diff --git a/.gitignore b/.gitignore index 3ff70b2..2ba5b92 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,3 @@ test_html/bind_test.bundle.js docs/ npm-debug.log bower_components - -milo.min.js -milo.min.js.map diff --git a/.jshintrc b/.jshintrc index 1570545..b628e79 100644 --- a/.jshintrc +++ b/.jshintrc @@ -3,4 +3,4 @@ "laxbreak": true, "browser": true, "node": true -} \ No newline at end of file +} diff --git a/lib/milo.js b/lib/milo.js index 0e527f8..9edd4c0 100644 --- a/lib/milo.js +++ b/lib/milo.js @@ -1,5 +1,6 @@ 'use strict'; +var core = require('milo-core'); var _ = require('mol-proto'); @@ -47,9 +48,11 @@ function milo(func) { * - [registry](./registry.js.html) - registries of fasets and components classes */ _.extend(milo, { + Messenger: core.Messenger, + Model: core.Model, + minder: core.minder, loader: require('./loader'), binder: require('./binder'), - minder: require('./minder'), mail: require('./services/mail'), window: require('./services/window'), config: require('./config'), @@ -58,8 +61,6 @@ _.extend(milo, { attributes: require('./attributes'), ComponentFacet: require('./components/c_facet'), Component: require('./components/c_class'), - Messenger: require('./messenger'), - Model: require('./model'), Command: require('./command'), registry: require('./registry'), milo_version: '0.1.4', diff --git a/lib/util/storage/index.js b/lib/util/storage/index.js index 859746f..7310062 100644 --- a/lib/util/storage/index.js +++ b/lib/util/storage/index.js @@ -10,6 +10,7 @@ var DOMStorageError = require('../error').createClass('DomStorageError') , check = require('../check') , Match = check.Match; +require('./model') module.exports = DOMStorage; diff --git a/lib/util/storage/model.js b/lib/util/storage/model.js new file mode 100644 index 0000000..ff667bb --- /dev/null +++ b/lib/util/storage/model.js @@ -0,0 +1,24 @@ +'use strict'; + +var Model = require('milo-core').Model + +Model.registerWithDOMStorage = Model$$registerWithDOMStorage; + + +function Model$$registerWithDOMStorage() { + var DOMStorage = require('./index'); + DOMStorage.registerDataType('Model', Model_domStorageSerializer, Model_domStorageParser); + DOMStorage.registerDataType('ModelPath', Model_domStorageSerializer, Model_domStorageParser, 'Model'); +} + + +function Model_domStorageSerializer(value) { + var data = value.get(); + return JSON.stringify(data); +} + + +function Model_domStorageParser(valueStr) { + var data = _.jsonParse(valueStr); + return new Model(data); +} diff --git a/milo.bundle.js b/milo.bundle.js index c02dd89..98ea807 100644 --- a/milo.bundle.js +++ b/milo.bundle.js @@ -29,7 +29,7 @@ _.extendProto(Facet, { init: function() {} }); -},{"mol-proto":117}],2:[function(require,module,exports){ +},{"mol-proto":150}],2:[function(require,module,exports){ 'use strict'; @@ -238,7 +238,7 @@ function FacetedObject$$createFacetedClass(name, facetsClasses, facetsConfig) { } }; -},{"../util/check":92,"../util/error":100,"./facet":1,"mol-proto":117}],3:[function(require,module,exports){ +},{"../util/check":90,"../util/error":98,"./facet":1,"mol-proto":150}],3:[function(require,module,exports){ 'use strict'; var _ = require('mol-proto') @@ -451,7 +451,7 @@ function Mixin$$useWith(hostClass, instanceKey, mixinMethods) { }, this); } -},{"../config":65,"../util/check":92,"../util/error":100,"mol-proto":117}],4:[function(require,module,exports){ +},{"../config":65,"../util/check":90,"../util/error":98,"mol-proto":150}],4:[function(require,module,exports){ 'use strict'; var _ = require('mol-proto') @@ -571,7 +571,7 @@ function setClass(FoundationClass) { _.defineProperty(this, 'FoundationClass', FoundationClass, _.ENUM); } -},{"../util/check":92,"../util/error":100,"mol-proto":117}],5:[function(require,module,exports){ +},{"../util/check":90,"../util/error":98,"mol-proto":150}],5:[function(require,module,exports){ 'use strict'; var Attribute = require('./a_class') @@ -721,7 +721,7 @@ function BindAttribute$$setInfo(el, componentClass, componentName, componentFace attr.decorate(); } -},{"../config":65,"../util/check":92,"../util/error":100,"./a_class":6,"mol-proto":117}],6:[function(require,module,exports){ +},{"../config":65,"../util/check":90,"../util/error":98,"./a_class":6,"mol-proto":150}],6:[function(require,module,exports){ 'use strict'; var _ = require('mol-proto') @@ -836,7 +836,7 @@ function Attribute$decorate() { this.set(this.render()); } -},{"../util/check":92,"../util/error":100,"mol-proto":117}],7:[function(require,module,exports){ +},{"../util/check":90,"../util/error":98,"mol-proto":150}],7:[function(require,module,exports){ 'use strict'; var Attribute = require('./a_class') @@ -923,7 +923,7 @@ function render() { return this.loadUrl; } -},{"../config":65,"../util/error":100,"./a_class":6,"mol-proto":117}],8:[function(require,module,exports){ +},{"../config":65,"../util/error":98,"./a_class":6,"mol-proto":150}],8:[function(require,module,exports){ 'use strict'; /** @@ -1103,7 +1103,7 @@ function createBinderScope(scopeEl, scopeObjectFactory, rootScope, bindRootEleme } } -},{"./attributes/a_bind":5,"./components/c_facets/cf_registry":31,"./components/c_info":32,"./components/c_registry":33,"./components/scope":41,"./services/mail":86,"./util/check":92,"./util/dom":96,"./util/error":100,"mol-proto":117}],10:[function(require,module,exports){ +},{"./attributes/a_bind":5,"./components/c_facets/cf_registry":31,"./components/c_info":32,"./components/c_registry":33,"./components/scope":41,"./services/mail":84,"./util/check":90,"./util/dom":94,"./util/error":98,"mol-proto":150}],10:[function(require,module,exports){ 'use strict'; // @@ -1277,7 +1277,7 @@ function ActionsHistory$getDescription() { }; } -},{"../util/logger":104,"mol-proto":117}],12:[function(require,module,exports){ +},{"../util/logger":102,"mol-proto":150}],12:[function(require,module,exports){ 'use strict'; var ClassRegistry = require('../abstract/registry') @@ -1493,7 +1493,7 @@ function Command$getDescription() { }; } -},{"../util/check":92,"../util/logger":104,"mol-proto":117}],14:[function(require,module,exports){ +},{"../util/check":90,"../util/logger":102,"mol-proto":150}],14:[function(require,module,exports){ 'use strict'; @@ -1567,7 +1567,7 @@ function Transaction$getDescription() { } } -},{"./actions_history":11,"mol-proto":117}],15:[function(require,module,exports){ +},{"./actions_history":11,"mol-proto":150}],15:[function(require,module,exports){ 'use strict'; @@ -1724,7 +1724,7 @@ function TransactionHistory$destroy() { delete this.transactions; } -},{"../messenger":67,"../util/logger":104,"./actions_history":11,"./transaction":14,"mol-proto":117}],16:[function(require,module,exports){ +},{"../messenger":67,"../util/logger":102,"./actions_history":11,"./transaction":14,"mol-proto":150}],16:[function(require,module,exports){ 'use strict'; @@ -2647,7 +2647,7 @@ function Component$isDestroyed() { return this._destroyed; } -},{"../abstract/faceted_object":2,"../attributes/a_bind":5,"../binder":9,"../config":65,"../messenger":67,"../util/check":92,"../util/component_name":93,"../util/dom":96,"../util/error":100,"../util/json_parse":103,"../util/logger":104,"../util/storage":108,"./c_facets/cf_registry":31,"./c_utils":34,"./scope":41,"mol-proto":117}],17:[function(require,module,exports){ +},{"../abstract/faceted_object":2,"../attributes/a_bind":5,"../binder":9,"../config":65,"../messenger":67,"../util/check":90,"../util/component_name":91,"../util/dom":94,"../util/error":98,"../util/json_parse":101,"../util/logger":102,"../util/storage":106,"./c_facets/cf_registry":31,"./c_utils":34,"./scope":41,"mol-proto":150}],17:[function(require,module,exports){ 'use strict'; /** @@ -2868,7 +2868,7 @@ function requiresFacet(facetName) { || facetRequire.indexOf(_.firstLowerCase(facetName)) >= 0); } -},{"../abstract/facet":1,"../messenger":67,"../util/error":100,"./c_utils":34,"mol-proto":117}],18:[function(require,module,exports){ +},{"../abstract/facet":1,"../messenger":67,"../util/error":98,"./c_utils":34,"mol-proto":150}],18:[function(require,module,exports){ 'use strict'; @@ -3057,7 +3057,7 @@ function Container$remove(comp) { this.owner.el.removeChild(comp.el); } -},{"../../binder":9,"../../util/dom":96,"../../util/logger":104,"../c_facet":17,"../scope":41,"./cf_registry":31,"mol-proto":117}],19:[function(require,module,exports){ +},{"../../binder":9,"../../util/dom":94,"../../util/logger":102,"../c_facet":17,"../scope":41,"./cf_registry":31,"mol-proto":150}],19:[function(require,module,exports){ 'use strict'; var Mixin = require('../../abstract/mixin') @@ -3716,7 +3716,7 @@ function Data$setState(state) { return this.set(state.state); } -},{"../../abstract/mixin":3,"../../messenger":67,"../../model/change_data":74,"../../model/m_path":78,"../../model/model_utils":79,"../../model/path_utils":81,"../../util/logger":104,"../c_facet":17,"../msg_api/data":36,"../msg_api/de_data":37,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":117}],20:[function(require,module,exports){ +},{"../../abstract/mixin":3,"../../messenger":67,"../../model/change_data":73,"../../model/m_path":76,"../../model/model_utils":77,"../../model/path_utils":79,"../../util/logger":102,"../c_facet":17,"../msg_api/data":36,"../msg_api/de_data":37,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],20:[function(require,module,exports){ 'use strict'; @@ -4054,7 +4054,7 @@ function hasTextAfterSelection() { return isText; } -},{"../../attributes/a_bind":5,"../../binder":9,"../../config":65,"../../util/check":92,"../../util/dom":96,"../../util/error":100,"../c_facet":17,"./cf_registry":31,"dot":116,"mol-proto":117}],21:[function(require,module,exports){ +},{"../../attributes/a_bind":5,"../../binder":9,"../../config":65,"../../util/check":90,"../../util/dom":94,"../../util/error":98,"../c_facet":17,"./cf_registry":31,"dot":115,"mol-proto":150}],21:[function(require,module,exports){ 'use strict'; // @@ -4271,7 +4271,7 @@ function _dragIsDisabled(event) { return false; } -},{"../../util/dragdrop":99,"../../util/logger":104,"../c_class":16,"../c_facet":17,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":117}],22:[function(require,module,exports){ +},{"../../util/dragdrop":97,"../../util/logger":102,"../c_class":16,"../c_facet":17,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],22:[function(require,module,exports){ 'use strict'; // @@ -4459,7 +4459,7 @@ function _isDropAllowed(dt, originalDropComponent) { // TODO test for other data types } -},{"../../util/dragdrop":99,"../../util/error":100,"../c_facet":17,"../msg_api/drop":38,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":117}],23:[function(require,module,exports){ +},{"../../util/dragdrop":97,"../../util/error":98,"../c_facet":17,"../msg_api/drop":38,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],23:[function(require,module,exports){ 'use strict'; var ComponentFacet = require('../c_facet') @@ -4518,7 +4518,7 @@ function Events$init() { _.defineProperty(this, MSG_SOURCE_KEY, domEventsSource); } -},{"../../messenger":67,"../c_facet":17,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":117}],24:[function(require,module,exports){ +},{"../../messenger":67,"../c_facet":17,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],24:[function(require,module,exports){ 'use strict'; @@ -4707,7 +4707,7 @@ function _makeWhenReadyFunc(isReadyFunc, event) { } } -},{"../../messenger":67,"../../services/de_constrs":84,"../c_facet":17,"../msg_src/frame":40,"./cf_registry":31,"mol-proto":117}],25:[function(require,module,exports){ +},{"../../messenger":67,"../../services/de_constrs":82,"../c_facet":17,"../msg_src/frame":40,"./cf_registry":31,"mol-proto":150}],25:[function(require,module,exports){ 'use strict'; @@ -4785,7 +4785,7 @@ function ItemFacet$extractItem() { this.list.extractItem(this.index); } -},{"../../model":76,"../../services/mail":86,"../c_facet":17,"./cf_registry":31,"mol-proto":117}],26:[function(require,module,exports){ +},{"../../model":74,"../../services/mail":84,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],26:[function(require,module,exports){ 'use strict'; var ComponentFacet = require('../c_facet') @@ -5217,7 +5217,7 @@ function List$destroy() { ComponentFacet.prototype.destroy.apply(this, arguments); } -},{"../../binder":9,"../../config":65,"../../services/mail":86,"../../util":102,"../c_class":16,"../c_facet":17,"./cf_registry":31,"dot":116,"mol-proto":117}],27:[function(require,module,exports){ +},{"../../binder":9,"../../config":65,"../../services/mail":84,"../../util":100,"../c_class":16,"../c_facet":17,"./cf_registry":31,"dot":115,"mol-proto":150}],27:[function(require,module,exports){ 'use strict'; var ComponentFacet = require('../c_facet') @@ -5293,7 +5293,7 @@ function ModelFacet$destroy() { ComponentFacet.prototype.destroy.apply(this, arguments); } -},{"../../abstract/mixin":3,"../../model":76,"../c_facet":17,"./cf_registry":31,"mol-proto":117}],28:[function(require,module,exports){ +},{"../../abstract/mixin":3,"../../model":74,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],28:[function(require,module,exports){ 'use strict'; var ComponentFacet = require('../c_facet') @@ -5334,7 +5334,7 @@ function Options$destroy() { ComponentFacet.prototype.destroy.apply(this, arguments); } -},{"../../model":76,"../c_facet":17,"./cf_registry":31,"mol-proto":117}],29:[function(require,module,exports){ +},{"../../model":74,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],29:[function(require,module,exports){ 'use strict'; // @@ -5442,7 +5442,7 @@ function Template$binder() { logger.error('TemplateFacet: Binder called without container facet.'); } -},{"../../binder":9,"../../util/check":92,"../../util/logger":104,"../c_facet":17,"./cf_registry":31,"mol-proto":117}],30:[function(require,module,exports){ +},{"../../binder":9,"../../util/check":90,"../../util/logger":102,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],30:[function(require,module,exports){ 'use strict'; var ComponentFacet = require('../c_facet') @@ -5545,7 +5545,7 @@ function Transfer$getComponentMeta() { }; } -},{"../c_facet":17,"./cf_registry":31,"mol-proto":117}],31:[function(require,module,exports){ +},{"../c_facet":17,"./cf_registry":31,"mol-proto":150}],31:[function(require,module,exports){ 'use strict'; var ClassRegistry = require('../../abstract/registry') @@ -5696,7 +5696,7 @@ function hasContainerFacet(ComponentClass, extraFacetsClasses) { } } -},{"../util/component_name":93,"../util/error":100,"../util/logger":104,"./c_facets/cf_registry":31,"./c_registry":33,"./scope":41,"mol-proto":117}],33:[function(require,module,exports){ +},{"../util/component_name":91,"../util/error":98,"../util/logger":102,"./c_facets/cf_registry":31,"./c_registry":33,"./scope":41,"mol-proto":150}],33:[function(require,module,exports){ 'use strict'; var ClassRegistry = require('../abstract/registry') @@ -5804,7 +5804,7 @@ function _getContainingComponent(el, returnCurrent, conditionFunc) { return _getContainingComponent(el.parentNode, true, conditionFunc); } -},{"../config":65,"../util/check":92}],35:[function(require,module,exports){ +},{"../config":65,"../util/check":90}],35:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -5902,7 +5902,7 @@ function createInternalData(sourceMessage, message, data) { return internalData; } -},{"../../messenger/m_api":68,"../../util/check":92,"./de_data":37,"mol-proto":117}],37:[function(require,module,exports){ +},{"../../messenger/m_api":68,"../../util/check":90,"./de_data":37,"mol-proto":150}],37:[function(require,module,exports){ 'use strict'; @@ -6046,7 +6046,7 @@ function inputChangeEvent(el) { : inputElementTypes.byDefault.event; } -},{"mol-proto":117}],38:[function(require,module,exports){ +},{"mol-proto":150}],38:[function(require,module,exports){ 'use strict'; @@ -6144,7 +6144,7 @@ function emitter() { return this.component.el; } -},{"../../messenger/m_source":70,"../../services/dom_source":85,"../../util/check":92,"../c_class":16,"mol-proto":117}],40:[function(require,module,exports){ +},{"../../messenger/m_source":70,"../../services/dom_source":83,"../../util/check":90,"../c_class":16,"mol-proto":150}],40:[function(require,module,exports){ 'use strict'; // ###component iframe source @@ -6220,7 +6220,7 @@ function handleEvent(event) { this.dispatchMessage(event.data.type, event); } -},{"../../messenger/m_source":70,"../../util/check":92,"../../util/error":100,"../../util/logger":104,"../c_class":16,"mol-proto":117}],41:[function(require,module,exports){ +},{"../../messenger/m_source":70,"../../util/check":90,"../../util/error":98,"../../util/logger":102,"../c_class":16,"mol-proto":150}],41:[function(require,module,exports){ 'use strict'; var _ = require('mol-proto') @@ -6486,7 +6486,7 @@ function Scope$$rename(obj, name, renameInScope) { obj.name = name; } -},{"../util/check":92,"../util/component_name":93,"../util/error":100,"../util/logger":104,"mol-proto":117}],42:[function(require,module,exports){ +},{"../util/check":90,"../util/component_name":91,"../util/error":98,"../util/logger":102,"mol-proto":150}],42:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -6612,7 +6612,7 @@ function onOptionsChange(msg, data) { }); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],44:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],44:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -6758,7 +6758,7 @@ function onAddItem(msg, data) { this.events.postMessage('milo_combolistadditem', data); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],45:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],45:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -6851,7 +6851,7 @@ function toISO8601Format(date) { function pad(n) { return n < 10 ? '0' + n : n; } } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],46:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],46:[function(require,module,exports){ 'use strict'; @@ -6970,7 +6970,7 @@ function MLFoldTree$renderTree (data) { } } -},{"../../util/count":94,"../c_class":16,"../c_registry":33,"dot":116}],48:[function(require,module,exports){ +},{"../../util/count":92,"../c_class":16,"../c_registry":33,"dot":115}],48:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7103,7 +7103,7 @@ function onModelChange(path, data) { dispatchChangeMessage.call(this); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],51:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],51:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7141,7 +7141,7 @@ function MLInput$setMaxLength(length) { this.el.setAttribute('maxlength', length); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],52:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],52:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7264,7 +7264,7 @@ function MLInputList_del() { function MLInputList_splice() { // ... arguments this.model.splice.apply(this.model, arguments); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],53:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],53:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7328,7 +7328,7 @@ function onChildrenBound() { this._connector = milo.minder(this.model, '<<<-', this.data).deferChangeMode('<<<->>>'); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],54:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],54:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7473,7 +7473,7 @@ function _sendChangeMessage() { -},{"../../util/dragdrop":99,"../c_class":16,"../c_registry":33,"mol-proto":117}],55:[function(require,module,exports){ +},{"../../util/dragdrop":97,"../c_class":16,"../c_registry":33,"mol-proto":150}],55:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7637,7 +7637,7 @@ function MLRadioGroup$destroy() { Component.prototype.destroy.apply(this, arguments); } -},{"../../util/count":94,"../c_class":16,"../c_registry":33,"mol-proto":117}],56:[function(require,module,exports){ +},{"../../util/count":92,"../c_class":16,"../c_registry":33,"mol-proto":150}],56:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -7696,7 +7696,7 @@ function onOptionsChange(path, data) { this.template.render({ selectOptions: this.model.get() }); } -},{"../c_class":16,"../c_registry":33,"mol-proto":117}],57:[function(require,module,exports){ +},{"../c_class":16,"../c_registry":33,"mol-proto":150}],57:[function(require,module,exports){ 'use strict'; /** @@ -8320,7 +8320,7 @@ function _setData() { this.setFilteredOptions(this._optionsData); } -},{"../../util/logger":104,"../c_class":16,"../c_registry":33,"dot":116,"mol-proto":117}],58:[function(require,module,exports){ +},{"../../util/logger":102,"../c_class":16,"../c_registry":33,"dot":115,"mol-proto":150}],58:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -8428,7 +8428,7 @@ function MLTextarea$destroy() { function MLTextarea$disable(disable) { this.el.disabled = disable; } -},{"../../util/logger":104,"../c_class":16,"../c_registry":33,"mol-proto":117}],60:[function(require,module,exports){ +},{"../../util/logger":102,"../c_class":16,"../c_registry":33,"mol-proto":150}],60:[function(require,module,exports){ 'use strict'; var Component = require('../c_class') @@ -8680,7 +8680,7 @@ function _toggleAlert(doShow) { this.el[doShow ? 'focus' : 'blur'](); } -},{"../../../util/check":92,"../../../util/component_name":93,"../../../util/logger":104,"../../c_class":16,"../../c_registry":33,"mol-proto":117}],63:[function(require,module,exports){ +},{"../../../util/check":90,"../../../util/component_name":91,"../../../util/logger":102,"../../c_class":16,"../../c_registry":33,"mol-proto":150}],63:[function(require,module,exports){ 'use strict'; var Component = require('../../c_class') @@ -9022,7 +9022,7 @@ function MLDialog$destroy() { Component.prototype.destroy.apply(this, arguments); } -},{"../../../util/check":92,"../../../util/component_name":93,"../../../util/logger":104,"../../c_class":16,"../../c_registry":33,"mol-proto":117}],64:[function(require,module,exports){ +},{"../../../util/check":90,"../../../util/component_name":91,"../../../util/logger":102,"../../c_class":16,"../../c_registry":33,"mol-proto":150}],64:[function(require,module,exports){ 'use strict'; var Component = require('../../c_class') @@ -9136,7 +9136,7 @@ function MLDropdown$toggleMenu(doShow) { : 'none'; } -},{"../../../util/dom_listeners":97,"../../../util/logger":104,"../../c_class":16,"../../c_registry":33,"mol-proto":117}],65:[function(require,module,exports){ +},{"../../../util/dom_listeners":95,"../../../util/logger":102,"../../c_class":16,"../../c_registry":33,"mol-proto":150}],65:[function(require,module,exports){ 'use strict'; @@ -9216,7 +9216,7 @@ config({ debug: false }); -},{"dot":116,"mol-proto":117}],66:[function(require,module,exports){ +},{"dot":115,"mol-proto":150}],66:[function(require,module,exports){ 'use strict'; @@ -9318,7 +9318,7 @@ function loadView(el, removeAttribute, callback) { }); } -},{"./attributes/a_load":7,"./config":65,"./services/mail":86,"./util/dom":96,"./util/error":100,"./util/logger":104,"./util/request":106}],67:[function(require,module,exports){ +},{"./attributes/a_load":7,"./config":65,"./services/mail":84,"./util/dom":94,"./util/error":98,"./util/logger":102,"./util/request":104}],67:[function(require,module,exports){ 'use strict'; var Mixin = require('../abstract/mixin') @@ -9985,7 +9985,7 @@ function getMessageSource() { return this._messageSource } -},{"../abstract/mixin":3,"../util/check":92,"../util/error":100,"./m_source":70,"mol-proto":117}],68:[function(require,module,exports){ +},{"../abstract/mixin":3,"../util/check":90,"../util/error":98,"./m_source":70,"mol-proto":150}],68:[function(require,module,exports){ 'use strict'; var _ = require('mol-proto') @@ -10178,7 +10178,7 @@ function filterSourceMessage(sourceMessage, message, internalData) { return true; } -},{"../util/logger":104,"mol-proto":117}],69:[function(require,module,exports){ +},{"../util/logger":102,"mol-proto":150}],69:[function(require,module,exports){ 'use strict'; var MessengerAPI = require('./m_api') @@ -10292,7 +10292,7 @@ function getInternalMessages(sourceMessage) { return internalMessages; } -},{"./m_api":68,"mol-proto":117}],70:[function(require,module,exports){ +},{"./m_api":68,"mol-proto":150}],70:[function(require,module,exports){ 'use strict'; var Mixin = require('../abstract/mixin') @@ -10464,7 +10464,7 @@ function postMessage(message, data) { this.messenger.postMessage(message, data); } -},{"../abstract/mixin":3,"../util/check":92,"../util/error":100,"../util/logger":104,"./m_api":68,"mol-proto":117}],71:[function(require,module,exports){ +},{"../abstract/mixin":3,"../util/check":90,"../util/error":98,"../util/logger":102,"./m_api":68,"mol-proto":150}],71:[function(require,module,exports){ 'use strict'; @@ -10533,9 +10533,10 @@ function MessengerMessageSource$postMessage(message, data) { this.messenger.postMessageSync(message, data); } -},{"../util/check":92,"./m_source":70,"mol-proto":117}],72:[function(require,module,exports){ +},{"../util/check":90,"./m_source":70,"mol-proto":150}],72:[function(require,module,exports){ 'use strict'; +var core = require('milo-core'); var _ = require('mol-proto'); @@ -10583,9 +10584,11 @@ function milo(func) { * - [registry](./registry.js.html) - registries of fasets and components classes */ _.extend(milo, { + Messenger: core.Messenger, + Model: core.Model, + minder: core.minder, loader: require('./loader'), binder: require('./binder'), - minder: require('./minder'), mail: require('./services/mail'), window: require('./services/window'), config: require('./config'), @@ -10594,8 +10597,6 @@ _.extend(milo, { attributes: require('./attributes'), ComponentFacet: require('./components/c_facet'), Component: require('./components/c_class'), - Messenger: require('./messenger'), - Model: require('./model'), Command: require('./command'), registry: require('./registry'), milo_version: '0.1.4', @@ -10622,227 +10623,7 @@ function destroy() { milo.util.destroy(); } -},{"./attributes":8,"./binder":9,"./classes":10,"./command":13,"./components/c_class":16,"./components/c_facet":17,"./config":65,"./loader":66,"./messenger":67,"./minder":73,"./model":76,"./registry":83,"./services/mail":86,"./services/window":89,"./use_components":90,"./use_facets":91,"./util":102,"./util/create_component_class":95,"mol-proto":117}],73:[function(require,module,exports){ -'use strict'; - -var Connector = require('./model/connector') - , Messenger = require('./messenger') - , _ = require('mol-proto') - , logger = require('./util/logger'); - - -module.exports = minder; - - -/** - * This function creates one or many Connector objects that - * create live reactive connection between objects implementing - * dataSource interface: - * Objects should emit messages when any part of their data changes, - * methods `on` and `off` should be implemented to subscribe/unsubscribe - * to change notification messages, methods `set` and `get` should be implemented to get/set data - * on path objects, pointing to particular parts of the object, method `path` - * should return path object for a given path string (see path utils for path string syntax). - * Both Model and Data facet are such data sources, they can be linked by Connector object. - * - * @param {Object} ds1 the first data source. Instead of the first data source an array can be passed with arrays of Connection objects parameters in each array element. - * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. - * @param {Object} ds2 the second data source - * @param {Object} options not implemented yet - */ -function minder(ds1, mode, ds2, options) { - if (Array.isArray(ds1)) { - var connDescriptions = ds1; - var connectors = connDescriptions.map(function(descr) { - return new Connector(descr[0], descr[1], descr[2], descr[3]); - }); - connectors.forEach(_addConnector); - return connectors; - } else { - var cnct = new Connector(ds1, mode, ds2, options); - _addConnector(cnct); - return cnct; - } -} - - -/** - * messenger of minder where it emits events related to all connectors - * @type {Messenger} - */ -var _messenger = new Messenger(minder, Messenger.defaultMethods); - - -var _connectors = [] - , _receivedMessages = [] - , _isPropagating = false; - - -_.extend(minder, { - getConnectors: minder_getConnectors, - getExpandedConnections: minder_getExpandedConnections, - isPropagating: minder_isPropagating, - whenPropagationCompleted: minder_whenPropagationCompleted, - destroyConnector: minder_destroyConnector, - destroy: minder_destroy -}); - - -function _addConnector(cnct) { - cnct.___minder_id = _connectors.push(cnct) - 1; - cnct.on(/.*/, onConnectorMessage); - minder.postMessage('added', { connector: cnct }); - minder.postMessage('turnedon', { connector: cnct }); -} - - -function onConnectorMessage(msg, data) { - var data = data ? _.clone(data) : {}; - _.extend(data, { - id: this.___minder_id, - connector: this - }); - minder.postMessage(msg, data); - if (! _receivedMessages.length && ! _isPropagating) { - _.defer(_idleCheck); - _isPropagating = true; - } - - _receivedMessages.push({ msg: msg, data: data }); -} - - -function _idleCheck() { - if (_receivedMessages.length) { - _receivedMessages.length = 0; - _.defer(_idleCheck); - minder.postMessage('propagationticked'); - } else { - _isPropagating = false; - minder.postMessage('propagationcompleted'); - } -} - - -function minder_isPropagating() { - return _isPropagating; -} - - -function minder_whenPropagationCompleted(callback) { - if (_isPropagating) - minder.once('propagationcompleted', executeCallback); - else - _.defer(executeCallback); - - function executeCallback() { - if (_isPropagating) - minder.once('propagationcompleted', executeCallback); - else - callback(); - } -} - - -function minder_getConnectors(onOff) { - if (typeof onOff == 'undefined') - return _connectors; - - return _connectors.filter(function(cnct) { - return cnct.isOn === onOff; - }); -} - - -function minder_destroyConnector(cnct) { - cnct.destroy(); - var index = _connectors.indexOf(cnct); - if (index >= 0) - delete _connectors[index]; - else - logger.warn('minder: connector destroyed that is not registered in minder'); -} - - -function minder_getExpandedConnections(onOff, searchStr) { - var connectors = minder.getConnectors(onOff); - var connections = connectors.map(function(cnct) { - var connection = { - leftSource: _getExpandedSource(cnct.ds1), - rightSource: _getExpandedSource(cnct.ds2), - mode: cnct.mode, - isOn: cnct.isOn - }; - - if (cnct.options) - connection.options = cnct.options; - - return connection; - }); - - if (searchStr) - connections = connections.filter(function(cnctn) { - return _sourceMatchesString(cnctn.leftSource, searchStr) - || _sourceMatchesString(cnctn.rightSource, searchStr); - }); - - return connections; -} - - -function _getExpandedSource(ds) { - var source = []; - if (typeof ds == 'function') { - if (ds._model && ds._accessPath) { - source.unshift(ds._accessPath); - ds = ds._model; - } - - source.unshift(ds); - ds = ds._hostObject; - } - - if (typeof ds == 'object') { - source.unshift(ds); - - if (ds.owner) - source.unshift(ds.owner); - } - - return source; -} - - -function _sourceMatchesString(source, matchStr) { - return source.some(function(srcNode) { - var className = srcNode.constructor && srcNode.constructor.name; - return _stringMatch(className, matchStr) - || _stringMatch(srcNode.name, matchStr) - || _stringMatch(srcNode, matchStr); - }); -} - - -function _stringMatch(str, substr) { - return str && typeof str == 'string' && str.indexOf(substr) >= 0; -} - - -function minder_destroy() { - _connectors.forEach(function(cnct) { - destroyDS(cnct.ds1); - destroyDS(cnct.ds2); - cnct.destroy(); - }); - _messenger.destroy(); - minder._destroyed = true; - - function destroyDS(ds) { - if (ds && !ds._destroyed) ds.destroy(); - } -} - -},{"./messenger":67,"./model/connector":75,"./util/logger":104,"mol-proto":117}],74:[function(require,module,exports){ +},{"./attributes":8,"./binder":9,"./classes":10,"./command":13,"./components/c_class":16,"./components/c_facet":17,"./config":65,"./loader":66,"./registry":81,"./services/mail":84,"./services/window":87,"./use_components":88,"./use_facets":89,"./util":100,"./util/create_component_class":93,"milo-core":124,"mol-proto":150}],73:[function(require,module,exports){ 'use strict'; @@ -11078,554 +10859,430 @@ function executeMethod(modelPath, data) { logger.error('unknown data change type'); } -},{"../components/c_facets/cf_registry":31,"../config":65,"../util/logger":104,"./path_utils":81,"mol-proto":117}],75:[function(require,module,exports){ +},{"../components/c_facets/cf_registry":31,"../config":65,"../util/logger":102,"./path_utils":79,"mol-proto":150}],74:[function(require,module,exports){ 'use strict'; -var ConnectorError = require('../util/error').Connector - , Messenger = require('../messenger') +var ModelPath = require('./m_path') + , synthesize = require('./synthesize') , pathUtils = require('./path_utils') + , changeDataHandler = require('./change_data') + , Messenger = require('../messenger') + , MessengerMessageSource = require('../messenger/msngr_source') + , ModelMsgAPI = require('./m_msg_api') + , ModelError = require('../util/error').Model + , Mixin = require('../abstract/mixin') , _ = require('mol-proto') - , logger = require('../util/logger'); - - -module.exports = Connector; + , check = require('../util/check') + , Match = check.Match + , logger = require('../util/logger') + , jsonParse = require('../util/json_parse'); -var modePattern = /^(\<*)\-+(\>*)$/; +module.exports = Model; /** - * Connector - * Class that creates connector object for data connection between - * two data-sources - * Data-sources should implement the following API: - * get() - get value from datasource or its path - * set(value) - set value to datasource or to its path - * on(path, subscriber) - subscription to data changes with "*" support - * off(path, subscriber) - * path(accessPath) - to return the object that gives reference to some part of datasource - * and complies with that api too. + * `milo.Model` + * Model class instantiates objects that allow deep data access with __safe getters__ that return undefined (rather than throwing exception) when properties/items of unexisting objects/arrays are requested and __safe setters__ that create object trees when properties/items of unexisting objects/arrays are set and also post messages to allow subscription on changes and enable data reactivity. + * Reactivity is implememnted via [Connector](./connector.js.html) that can be instantiated either directly or with more convenient interface of [milo.minder](../minder.js.html). At the moment model can be connected to [Data facet](../components/c_facets/Data.js.html) or to another model or [ModelPath](./m_path.js.html). + * Model constructor returns objects that are functions at the same time; when called they return ModelPath objects that allow get/set access to any point in model data. See [ModelData](#ModelData) below. * - * ####Events#### + * You can subscribe to model changes with `on` method by passing model access path in place of message, pattern or string with any number of stars to subscribe to a certain depth in model (e.g., `'***'` to subscribe to three levels). * - * - 'turnedon' - connector was turned on - * - 'turnedoff' - connector was turned off - * - 'changestarted' - change on connected datasource is started - * - 'changecompleted' - change on connected datasource is completed - * - 'destroyed' - connector was destroyed - * - * @param {Object} ds1 the first data source. - * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. - * @param {Object} ds2 the second data source - * @param {Object} options not implemented yet - * @return {Connector} when called with `new`, creates a Connector object. + * @constructor + * @param {Object|Array} data optional initial array data. If it is planned to connect model to view it is usually better to instantiate an empty Model (`var m = new Model`), connect it to [Component](../components/c_class.js.html)'s [Data facet](../components/c_facets/Data.js.html) (e.g., `milo.minder(m, '<<->>', c.data);`) and then set the model with `m.set(data)` - the view will be automatically updated. + * @param {Object} hostObject optional object that hosts model on one of its properties. Can be used when model itself is the context of the message subscriber and you need to travers to this object (although it is possible to set any context). Can also be used to proxy model's methods to the host like [Model facet](../components/c_facets/ModelFacet.js.html) is doing. + * @param {Object} options pass { reactive: false } to use model without messaging when it is not needed - it makes it much faster + * @return {Model} */ -function Connector(ds1, mode, ds2, options) { - setupMode.call(this, mode); - - _.extend(this, { - ds1: ds1, - ds2: ds2, - isOn: false, - _changesQueue1: [], - _changesQueue2: [], - _messenger: new Messenger(this, Messenger.defaultMethods) - }); - - if (options) { - this.options = options; - - var pathTranslation = options.pathTranslation; - if (pathTranslation) { - pathTranslation = _.clone(pathTranslation); - var patternTranslation = getPatternTranslations(pathTranslation); - _.extend(this, { - pathTranslation1: reverseTranslationRules(pathTranslation), - pathTranslation2: pathTranslation, - patternTranslation1: reversePatternTranslationRules(patternTranslation), - patternTranslation2: patternTranslation - }); - } +function Model(data, hostObject, options) { + // `model` will be returned by constructor instead of `this`. `model` + // (`modelPath` function) should return a ModelPath object with "synthesized" methods + // to get/set model properties, to subscribe to property changes, etc. + // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below. + var model = function modelPath(accessPath) { // , ... arguments that will be interpolated + return Model$path.apply(model, arguments); + }; + model.__proto__ = Model.prototype; - var dataTranslation = options.dataTranslation; - if (dataTranslation) { - _.extend(this, { - dataTranslation1: dataTranslation['<-'], - dataTranslation2: dataTranslation['->'] - }); - } + model._hostObject = hostObject; + model._options = options || {}; - var dataValidation = options.dataValidation; - if (dataValidation) { - _.extend(this, { - dataValidation1: dataValidation['<-'], - dataValidation2: dataValidation['->'] - }); - } + if (model._options.reactive !== false) { + model._prepareMessengers(); + // subscribe to "changedata" message to enable reactive connections + model.onSync('changedata', changeDataHandler); } - this.turnOn(); + if (data) model._data = data; + + return model; } +Model.prototype.__proto__ = Model.__proto__; -function setupMode(mode){ - var parsedMode = mode.match(modePattern); - if (! parsedMode) - modeParseError(); +/** + * ####Model instance methods#### + * + * - [path](#path) - returns ModelPath object that allows access to any point in Model + * - [get](#Model$get) - get model data + * - set - set model data, synthesized + * - splice - splice model data (as array or pseudo-array), synthesized + * - [len](./m_path.js.html#ModelPath$len) - returns length of array (or pseudo-array) in model in safe way, 0 if no length is set + * - [push](./m_path.js.html#ModelPath$push) - add items to the end of array (or pseudo-array) in model + * - [pop](./m_path.js.html#ModelPath$pop) - remove item from the end of array (or pseudo-array) in model + * - [unshift](./m_path.js.html#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in model + * - [shift](./m_path.js.html#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in model + * - [proxyMessenger](#proxyMessenger) - proxy model's Messenger methods to host object + * - [proxyMethods](#proxyMethods) - proxy model methods to host object + */ +_.extendProto(Model, { + path: Model$path, + get: Model$get, + proxyMessenger: proxyMessenger, // deprecated, should not be used + proxyMethods: proxyMethods, + _prepareMessengers: _prepareMessengers, + _getHostObject: _getHostObject, + destroy: Model$destroy +}); - var depth1 = parsedMode[1].length - , depth2 = parsedMode[2].length; +// set, del, splice are added to model +_.extendProto(Model, synthesize.modelMethods); - if (depth1 && depth2 && depth1 != depth2) - modeParseError(); - if (! depth1 && ! depth2) - modeParseError(); +/** + * - Path: ModelPath class as `milo.Model.Path` + * - [registerWithDOMStorage](#Model$$registerWithDOMStorage) + */ +_.extend(Model, { + Path: ModelPath, + registerWithDOMStorage: Model$$registerWithDOMStorage, + useWith: Model$$useWith +}); - _.extend(this, { - mode: mode, - depth1: depth1, - depth2: depth2, - }); - function modeParseError() { - throw new ConnectorError('invalid Connector mode: ' + mode); - } -} +/** + * Expose Messenger methods on Facet prototype + */ +var MESSENGER_PROPERTY = '_messenger'; +Messenger.useWith(Model, MESSENGER_PROPERTY, Messenger.defaultMethods); -_.extendProto(Connector, { - turnOn: Connector$turnOn, - turnOff: Connector$turnOff, - destroy: Connector$destroy, - changeMode: Connector$changeMode, - deferChangeMode: Connector$deferChangeMode +/** + * ModelPath methods added to Model prototype + */ +['len', 'push', 'pop', 'unshift', 'shift'].forEach(function(methodName) { + var method = ModelPath.prototype[methodName]; + _.defineProperty(Model.prototype, methodName, method); }); + /** - * Function change the mode of the connection + * Model instance method. + * Get model data. * - * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. - * @return {Object[String]} + * @return {Any} */ -function Connector$changeMode(mode) { - this.turnOff(); - setupMode.call(this, mode); - this.turnOn(); - return this; +function Model$get() { + return this._data; } /** - * Function change the mode of the connection + * Model instance method. + * Returns ModelPath object that implements the same API as model but allows access to any point inside model as defined by `accessPath`. + * See [ModelPath](./m_path.js.html) class for more information. * - * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. - * @return {Object[String]} + * @param {String} accessPath string that defines path to access model. + * Path string consists of parts to define either property access (`".name"` to access property name) or array item access (`"[1]"` to access item with index 1). + * Access path can contain as many parts as necessary (e.g. `".list[0].name"` to access property `name` in the first element of array stored in property `list`. + * @param {List} arguments additional arguments of this method can be used to create interpolated paths. + * E.g. `m.path("[$1].$2", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m("[" + id + "]." + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`. + * @return {ModelPath} */ -function Connector$deferChangeMode(mode) { - _.deferMethod(this, 'changeMode', mode); - return this; +function Model$path(accessPath) { // , ... arguments that will be interpolated + if (! accessPath) return this; + + // "null" is context to pass to ModelPath, first parameter of bind + // "this" (model) is added in front of all arguments + _.splice(arguments, 0, 0, null, this); + + // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ... + return new (Function.prototype.bind.apply(ModelPath, arguments)); } /** - * Function that reverses translation rules for paths of connected odata sources + * Model instance method. + * Proxy model's Messenger methods to host object. * - * @param {Object[String]} rules map of paths defining the translation rules - * @return {Object[String]} + * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used. */ -function reverseTranslationRules(rules) { - var reverseRules = {}; - _.eachKey(rules, function(path2_value, path1_key) { - reverseRules[path2_value] = path1_key; - }); - return reverseRules; +function proxyMessenger(modelHostObject) { + modelHostObject = modelHostObject || this._hostObject; + Mixin.prototype._createProxyMethods.call(this[MESSENGER_PROPERTY], Messenger.defaultMethods, modelHostObject); } -function getPatternTranslations(pathTranslation) { - var patternTranslation = []; - _.eachKey(pathTranslation, function(path2_value, path1_key) { - var starIndex1 = path1_key.indexOf('*') - , starIndex2 = path2_value.indexOf('*'); - if (starIndex1 >= 0 && starIndex2 >= 0) { // pattern translation - if (path1_key.slice(starIndex1) != path2_value.slice(starIndex2)) - _throwInvalidTranslation(path1_key, path2_value); - delete pathTranslation[path1_key]; - - patternTranslation.push({ - fromPattern: pathUtils.createRegexPath(path1_key), - fromStaticPath: _getStaticPath(path1_key, starIndex1), - toPattern: pathUtils.createRegexPath(path2_value), - toStaticPath: _getStaticPath(path2_value, starIndex2) - }); - } else if (starIndex1 >= 0 || starIndex2 >= 0) // pattern only on one side of translation - _throwInvalidTranslation(path1_key, path2_value); - }); - - return patternTranslation; +var modelMethodsToProxy = ['path', 'get', 'set', 'del', 'splice', 'len', 'push', 'pop', 'unshift', 'shift']; - function _throwInvalidTranslation(path1, path2) { - throw new ConnectorError('Invalid pattern translation: ' + path1 + ', ' + path2); - } +/** + * Expose model methods on + * See same method in Mixin class for parameters meaning + * + * @param {Function} hostClass + * @param {[type]} instanceKey + * @param {[type]} mixinMethods optional + */ +function Model$$useWith(hostClass, instanceKey, mixinMethods) { + mixinMethods = mixinMethods || modelMethodsToProxy; + Mixin.useWith.call(Model, hostClass, instanceKey, mixinMethods); +} - function _getStaticPath(path, starIndex) { - return path.replace(/[\.\[]?\*.*$/, ''); - } -} - - -function reversePatternTranslationRules(patternTranslation) { - return patternTranslation.map(function(pt) { - return { - fromPattern: pt.toPattern, - fromStaticPath: pt.toStaticPath, - toPattern: pt.fromPattern, - toStaticPath: pt.fromStaticPath - }; - }); +/** + * Model instance method. + * Proxy model methods to host object. + * + * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used. + */ +function proxyMethods(modelHostObject) { + modelHostObject = modelHostObject || this._hostObject; + Mixin.prototype._createProxyMethods.call(this, modelMethodsToProxy, modelHostObject); } /** - * turnOn - * Method of Connector that enables connection (if it was previously disabled) + * Model instance method. + * Create and connect internal and external model's messengers. + * External messenger's methods are proxied on the model and they allows "*" subscriptions. */ -function Connector$turnOn() { - if (this.isOn) - return logger.warn('data sources are already connected'); - - var subscriptionPath = this._subscriptionPath = - new Array(this.depth1 || this.depth2).join('*'); - - var subscriptionPattern = pathUtils.createRegexPath(subscriptionPath); - - var self = this; - if (this.depth1) - this._link1 = linkDataSource('_link2', this.ds2, this.ds1, this._changesQueue1, this.pathTranslation1, this.patternTranslation1, this.dataTranslation1, this.dataValidation1); - if (this.depth2) - this._link2 = linkDataSource('_link1', this.ds1, this.ds2, this._changesQueue2, this.pathTranslation2, this.patternTranslation2, this.dataTranslation2, this.dataValidation2); - - this.isOn = true; - this.postMessage('turnedon'); - - - function linkDataSource(reverseLink, fromDS, toDS, changesQueue, pathTranslation, patternTranslation, dataTranslation, dataValidation) { - fromDS.onSync('datachanges', onData); - return onData; - - function onData(message, batch) { - var sendData = { - changes: [], - transaction: batch.transaction - } - - batch.changes.forEach(function(change) { - var sourcePath = change.path - , targetPath = translatePath(sourcePath); - - if (typeof targetPath == 'undefined') return; - - var change = _.clone(change); - _.extend(change, { - source: fromDS, - path: targetPath - }); - - translateData(sourcePath, change); - validateData(sourcePath, change); - }); - - if (! changesQueue.length) - _.defer(postChangeData); - - changesQueue.push(sendData); - - - function translatePath(sourcePath) { - if (pathTranslation) { - var translatedPath = pathTranslation[sourcePath]; - if (translatedPath) return translatedPath; - if (!patternTranslation.length) return; - var pt = _.find(patternTranslation, function(pTranslation) { - return pTranslation.fromPattern.test(sourcePath); - }); - if (!pt) return; - var translatedPath = sourcePath.replace(pt.fromStaticPath, pt.toStaticPath); - } else if (! ((subscriptionPattern instanceof RegExp - && subscriptionPattern.test(sourcePath)) - || subscriptionPattern == sourcePath)) return; - - return translatedPath || sourcePath; - } - - - function translateData(sourcePath, change) { - if (dataTranslation) { - var translate = dataTranslation[sourcePath]; - if (translate && typeof translate == 'function') { - change.oldValue = translate(change.oldValue); - change.newValue = translate(change.newValue); - } - } - } - - - function validateData(sourcePath, change) { - propagateData(change); - - if (dataValidation) { - var validators = dataValidation[sourcePath] - , passedCount = 0 - , alreadyFailed = false; - - if (validators) - validators.forEach(callValidator); - } +function _prepareMessengers() { + // model will post all its changes on internal messenger + var internalMessenger = new Messenger(this, undefined, undefined); + // message source to connect internal messenger to external + var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger); - function callValidator(validator) { - validator(change.newValue, function(err, response) { - response.path = sourcePath; - if (! alreadyFailed && (err || response.valid) && ++passedCount == validators.length) { - fromDS.postMessage('validated', response); - } else if (! response.valid) { - alreadyFailed = true; - fromDS.postMessage('validated', response); - } - }); - } - } + // external messenger to which all model users will subscribe, + // that will allow "*" subscriptions and support "changedata" message api. + var externalMessenger = new Messenger(this, undefined, internalMessengerSource); + _.defineProperty(this, MESSENGER_PROPERTY, externalMessenger); + _.defineProperty(this, '_internalMessenger', internalMessenger); +} - function propagateData(change) { - sendData.changes.push(change); - } +function _getHostObject() { + return this._hostObject; +} - function postChangeData() { - // prevent endless loop of updates for 2-way connection - if (self[reverseLink]) var callback = subscriptionSwitch; - var transactions = mergeTransactions(changesQueue); - changesQueue.length = 0; - transactions.forEach(function(transaction) { - // send data change instruction as message - toDS.postMessageSync('changedata', { changes: transaction }, callback); - }); - } +function Model$$registerWithDOMStorage() { + var DOMStorage = require('../util/storage'); + DOMStorage.registerDataType('Model', Model_domStorageSerializer, Model_domStorageParser); + DOMStorage.registerDataType('ModelPath', Model_domStorageSerializer, Model_domStorageParser, 'Model'); +} - function subscriptionSwitch(err, changeFinished) { - if (err) return; - var onOff = changeFinished ? 'onSync' : 'off'; - toDS[onOff]('datachanges', self[reverseLink]); +function Model_domStorageSerializer(value) { + var data = value.get(); + return JSON.stringify(data); +} - var message = changeFinished ? 'changecompleted' : 'changestarted'; - self.postMessage(message, { source: fromDS, target: toDS }); - } +function Model_domStorageParser(valueStr) { + var data = jsonParse(valueStr); + return new Model(data); +} - function mergeTransactions(batches) { - var transactions = [] - , currentTransaction; - batches.forEach(function(batch) { - if (! batch.transaction) currentTransaction = undefined; - if (! batch.changes.length) return; +function Model$destroy() { + this[MESSENGER_PROPERTY].destroy(); + this._internalMessenger.destroy(); + this._destroyed = true; +} - if (batch.transaction) { - if (currentTransaction) - _.appendArray(currentTransaction, batch.changes); - else { - currentTransaction = _.clone(batch.changes); - transactions.push(currentTransaction); - } - } else - transactions.push(batch.changes); - }); +},{"../abstract/mixin":3,"../messenger":67,"../messenger/msngr_source":71,"../util/check":90,"../util/error":98,"../util/json_parse":101,"../util/logger":102,"../util/storage":106,"./change_data":73,"./m_msg_api":75,"./m_path":76,"./path_utils":79,"./synthesize":80,"mol-proto":150}],75:[function(require,module,exports){ +'use strict'; - return transactions; - } - } - } -} +var MessengerRegexpAPI = require('../messenger/m_api_rx') + , pathUtils = require('./path_utils') + , _ = require('mol-proto'); /** - * turnOff - * Method of Connector that disables connection (if it was previously enabled) + * Subclass of MessengerRegexpAPI that is used to translate messages of external messenger of Model to internal messenger of Model. */ -function Connector$turnOff() { - if (! this.isOn) - return logger.warn('data sources are already disconnected'); - - var self = this; - unlinkDataSource(this.ds1, '_link2', this.pathTranslation2); - unlinkDataSource(this.ds2, '_link1', this.pathTranslation1); +var ModelMsgAPI = _.createSubclass(MessengerRegexpAPI, 'ModelMsgAPI'); - this.isOn = false; - this.postMessage('turnedoff'); +module.exports = ModelMsgAPI; - function unlinkDataSource(fromDS, linkName, pathTranslation) { - if (self[linkName]) { - fromDS.off('datachanges', self[linkName]); - delete self[linkName]; - } - } -} +/** + * ####ModelMsgAPI instance methods#### + * + * - [translateToSourceMessage](#translateToSourceMessage) - translates subscription paths with "*"s to regex, leaving other strings untouched + */ +_.extendProto(ModelMsgAPI, { + translateToSourceMessage: translateToSourceMessage, +}); /** - * Destroys connector object by turning it off and removing references to connected sources + * ModelMsgAPI instance method + * Translates subscription paths with "*"s to regex, leaving other strings untouched. + * + * @param {String} accessPath relative access path to be translated + * @return {RegExp|String} */ -function Connector$destroy() { - this.turnOff(); - this.postMessage('destroyed'); - this._messenger.destroy(); - delete this.ds1; - delete this.ds2; - this._destroyed = true; +function translateToSourceMessage(accessPath) { + if (accessPath instanceof RegExp) return accessPath; + + return pathUtils.createRegexPath(accessPath); } -},{"../messenger":67,"../util/error":100,"../util/logger":104,"./path_utils":81,"mol-proto":117}],76:[function(require,module,exports){ +},{"../messenger/m_api_rx":69,"./path_utils":79,"mol-proto":150}],76:[function(require,module,exports){ 'use strict'; -var ModelPath = require('./m_path') - , synthesize = require('./synthesize') +var synthesize = require('./synthesize') , pathUtils = require('./path_utils') , changeDataHandler = require('./change_data') , Messenger = require('../messenger') + , ModelPathMsgAPI = require('./path_msg_api') , MessengerMessageSource = require('../messenger/msngr_source') - , ModelMsgAPI = require('./m_msg_api') - , ModelError = require('../util/error').Model - , Mixin = require('../abstract/mixin') , _ = require('mol-proto') , check = require('../util/check') - , Match = check.Match - , logger = require('../util/logger') - , jsonParse = require('../util/json_parse'); + , Match = check.Match; -module.exports = Model; +module.exports = ModelPath; /** - * `milo.Model` - * Model class instantiates objects that allow deep data access with __safe getters__ that return undefined (rather than throwing exception) when properties/items of unexisting objects/arrays are requested and __safe setters__ that create object trees when properties/items of unexisting objects/arrays are set and also post messages to allow subscription on changes and enable data reactivity. - * Reactivity is implememnted via [Connector](./connector.js.html) that can be instantiated either directly or with more convenient interface of [milo.minder](../minder.js.html). At the moment model can be connected to [Data facet](../components/c_facets/Data.js.html) or to another model or [ModelPath](./m_path.js.html). - * Model constructor returns objects that are functions at the same time; when called they return ModelPath objects that allow get/set access to any point in model data. See [ModelData](#ModelData) below. - * - * You can subscribe to model changes with `on` method by passing model access path in place of message, pattern or string with any number of stars to subscribe to a certain depth in model (e.g., `'***'` to subscribe to three levels). + * `milo.Model.Path` + * ModelPath object that allows access to any point inside [Model](./index.js.html) as defined by `accessPath` * * @constructor - * @param {Object|Array} data optional initial array data. If it is planned to connect model to view it is usually better to instantiate an empty Model (`var m = new Model`), connect it to [Component](../components/c_class.js.html)'s [Data facet](../components/c_facets/Data.js.html) (e.g., `milo.minder(m, '<<->>', c.data);`) and then set the model with `m.set(data)` - the view will be automatically updated. - * @param {Object} hostObject optional object that hosts model on one of its properties. Can be used when model itself is the context of the message subscriber and you need to travers to this object (although it is possible to set any context). Can also be used to proxy model's methods to the host like [Model facet](../components/c_facets/ModelFacet.js.html) is doing. - * @param {Object} options pass { reactive: false } to use model without messaging when it is not needed - it makes it much faster - * @return {Model} + * @param {Model} model Model instance that ModelPath gives access to. + * @param {String} accessPath string that defines path to access model. + * Path string consists of parts to define either property access (`".name"` to access property name) or array item access (`"[1]"` to access item with index 1). + * Access path can contain as many parts as necessary (e.g. `".list[0].name"` to access property `name` in the first element of array stored in property `list`. + * @param {List} arguments additional arguments of this method can be used to create interpolated paths. + * E.g. `m.path("[$1].$2", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m("[" + id + "]." + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`. + * @return {ModelPath} */ -function Model(data, hostObject, options) { - // `model` will be returned by constructor instead of `this`. `model` - // (`modelPath` function) should return a ModelPath object with "synthesized" methods +function ModelPath(model, path) { // ,... - additional arguments for interpolation + // check(model, Model); + check(path, String); + + // `modelPath` will be returned by constructor instead of `this`. `modelPath` + // (`modelPath_path` function) should also return a ModelPath object with "synthesized" methods // to get/set model properties, to subscribe to property changes, etc. // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below. - var model = function modelPath(accessPath) { // , ... arguments that will be interpolated - return Model$path.apply(model, arguments); + var modelPath = function modelPath_path(accessPath) { // , ... arguments that will be interpolated + return ModelPath$path.apply(modelPath, arguments); }; - model.__proto__ = Model.prototype; + modelPath.__proto__ = ModelPath.prototype; - model._hostObject = hostObject; - model._options = options || {}; - if (model._options.reactive !== false) { - model._prepareMessengers(); + _.defineProperties(modelPath, { + _model: model, + _path: path, + _args: _.slice(arguments, 1), // path will be the first element of this array + _options: model._options + }); + + // parse access path + var parsedPath = pathUtils.parseAccessPath(path); + + // compute access path string + _.defineProperty(modelPath, '_accessPath', interpolateAccessPath(parsedPath, modelPath._args)); + + if (modelPath._options.reactive !== false) { + // messenger fails on "*" subscriptions + modelPath._prepareMessenger(); // subscribe to "changedata" message to enable reactive connections - model.onSync('changedata', changeDataHandler); + modelPath.onSync('changedata', changeDataHandler); } - if (data) model._data = data; + // compiling getter and setter + var methods = synthesize(path, parsedPath); - return model; + // adding methods to model path + _.defineProperties(modelPath, methods); + + Object.freeze(modelPath); + + return modelPath; } -Model.prototype.__proto__ = Model.__proto__; +ModelPath.prototype.__proto__ = ModelPath.__proto__; /** - * ####Model instance methods#### + * Interpolates path elements to compute real path * - * - [path](#path) - returns ModelPath object that allows access to any point in Model - * - [get](#Model$get) - get model data - * - set - set model data, synthesized - * - splice - splice model data (as array or pseudo-array), synthesized - * - [len](./m_path.js.html#ModelPath$len) - returns length of array (or pseudo-array) in model in safe way, 0 if no length is set - * - [push](./m_path.js.html#ModelPath$push) - add items to the end of array (or pseudo-array) in model - * - [pop](./m_path.js.html#ModelPath$pop) - remove item from the end of array (or pseudo-array) in model - * - [unshift](./m_path.js.html#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in model - * - [shift](./m_path.js.html#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in model - * - [proxyMessenger](#proxyMessenger) - proxy model's Messenger methods to host object - * - [proxyMethods](#proxyMethods) - proxy model methods to host object + * @param {Array} parsedPath parsed path - array of path nodes + * @param {Array} args path interpolation arguments, args[0] is path itself + * @return {String} */ -_.extendProto(Model, { - path: Model$path, - get: Model$get, - proxyMessenger: proxyMessenger, // deprecated, should not be used - proxyMethods: proxyMethods, - _prepareMessengers: _prepareMessengers, - _getHostObject: _getHostObject, - destroy: Model$destroy -}); - -// set, del, splice are added to model -_.extendProto(Model, synthesize.modelMethods); +function interpolateAccessPath(parsedPath, args) { + return parsedPath.reduce(function(accessPathStr, currNode, index) { + var interpolate = currNode.interpolate; + return accessPathStr + + (interpolate + ? (currNode.syntax == 'array' + ? '[' + args[interpolate] + ']' + : '.' + args[interpolate]) + : currNode.property); + }, ''); +} /** - * - Path: ModelPath class as `milo.Model.Path` - * - [registerWithDOMStorage](#Model$$registerWithDOMStorage) + * ####ModelPath instance methods#### + * + * - [path](#ModelPath$path) - gives access to path inside ModelPath + * - get - synthesized + * - set - synthesized + * - splice - splice model data (as array or pseudo-array), synthesized + * - [len](#ModelPath$len) - returns length of array (or pseudo-array) in safe way, 0 if no length is set + * - [push](#ModelPath$push) - add items to the end of array (or pseudo-array) in ModelPath + * - [pop](#ModelPath$pop) - remove item from the end of array (or pseudo-array) in ModelPath + * - [unshift](#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in ModelPath + * - [shift](#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in ModelPath */ -_.extend(Model, { - Path: ModelPath, - registerWithDOMStorage: Model$$registerWithDOMStorage, - useWith: Model$$useWith +_.extendProto(ModelPath, { + path: ModelPath$path, + len: ModelPath$len, + push: ModelPath$push, + pop: ModelPath$pop, + unshift: ModelPath$unshift, + shift: ModelPath$shift, + _prepareMessenger: _prepareMessenger, + _getDefinition: _getDefinition, + destroy: ModelPath$destroy }); -/** - * Expose Messenger methods on Facet prototype - */ -var MESSENGER_PROPERTY = '_messenger'; -Messenger.useWith(Model, MESSENGER_PROPERTY, Messenger.defaultMethods); - - -/** - * ModelPath methods added to Model prototype - */ -['len', 'push', 'pop', 'unshift', 'shift'].forEach(function(methodName) { - var method = ModelPath.prototype[methodName]; - _.defineProperty(Model.prototype, methodName, method); -}); +_.extend(ModelPath, { + _createFromDefinition: _createFromDefinition +}) /** - * Model instance method. - * Get model data. - * - * @return {Any} + * Expose Messenger methods on Facet prototype */ -function Model$get() { - return this._data; -} +var MESSENGER_PROPERTY = '_messenger'; +Messenger.useWith(ModelPath, MESSENGER_PROPERTY, Messenger.defaultMethods); /** - * Model instance method. - * Returns ModelPath object that implements the same API as model but allows access to any point inside model as defined by `accessPath`. - * See [ModelPath](./m_path.js.html) class for more information. + * ModelPath instance method + * Gives access to path inside ModelPath. Method works similarly to [path method](#Model$path) of model, using relative paths. * * @param {String} accessPath string that defines path to access model. * Path string consists of parts to define either property access (`".name"` to access property name) or array item access (`"[1]"` to access item with index 1). @@ -11634,1209 +11291,919 @@ function Model$get() { * E.g. `m.path("[$1].$2", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m("[" + id + "]." + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`. * @return {ModelPath} */ -function Model$path(accessPath) { // , ... arguments that will be interpolated +function ModelPath$path(accessPath) { // , ... arguments that will be interpolated if (! accessPath) return this; - // "null" is context to pass to ModelPath, first parameter of bind - // "this" (model) is added in front of all arguments - _.splice(arguments, 0, 0, null, this); + var thisPathArgsCount = this._args.length - 1; + + if (thisPathArgsCount > 0) {// this path has interpolated arguments too + accessPath = accessPath.replace(/\$[1-9][0-9]*/g, function(str) { + return '$' + (+str.slice(1) + thisPathArgsCount); + }); + } + + var newPath = this._path + accessPath; + + // this._model is added in front of all arguments as the first parameter + // of ModelPath constructor + var args = [this._model, newPath] + .concat(this._args.slice(1)) // remove old path from _args, as it is 1 based + .concat(_.slice(arguments, 1)); // add new interpolation arguments // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ... - return new (Function.prototype.bind.apply(ModelPath, arguments)); + return _.newApply(ModelPath, args); } /** - * Model instance method. - * Proxy model's Messenger methods to host object. + * ModelPath and Model instance method + * Returns length property and sets it to 0 if it wasn't set. * - * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used. + * @return {Any} */ -function proxyMessenger(modelHostObject) { - modelHostObject = modelHostObject || this._hostObject; - Mixin.prototype._createProxyMethods.call(this[MESSENGER_PROPERTY], Messenger.defaultMethods, modelHostObject); +function ModelPath$len() { + return this.path('.length').get() || 0; } -var modelMethodsToProxy = ['path', 'get', 'set', 'del', 'splice', 'len', 'push', 'pop', 'unshift', 'shift']; - - /** - * Expose model methods on - * See same method in Mixin class for parameters meaning + * ModelPath and Model instance method + * Adds items to the end of array (or pseudo-array). Returns new length. * - * @param {Function} hostClass - * @param {[type]} instanceKey - * @param {[type]} mixinMethods optional + * @param {List} arguments list of items that will be added to array (pseudo array) + * @return {Integer} */ -function Model$$useWith(hostClass, instanceKey, mixinMethods) { - mixinMethods = mixinMethods || modelMethodsToProxy; - Mixin.useWith.call(Model, hostClass, instanceKey, mixinMethods); +function ModelPath$push() { // arguments + var length = this.len(); + var newLength = length + arguments.length; + + _.splice(arguments, 0, 0, length, 0); + this.splice.apply(this, arguments); + + return newLength; } /** - * Model instance method. - * Proxy model methods to host object. + * ModelPath and Model instance method + * Removes item from the end of array (or pseudo-array). Returns this item. * - * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used. + * @return {Any} */ -function proxyMethods(modelHostObject) { - modelHostObject = modelHostObject || this._hostObject; - Mixin.prototype._createProxyMethods.call(this, modelMethodsToProxy, modelHostObject); +function ModelPath$pop() { + return this.splice(this.len() - 1, 1)[0]; } /** - * Model instance method. - * Create and connect internal and external model's messengers. - * External messenger's methods are proxied on the model and they allows "*" subscriptions. + * ModelPath and Model instance method + * Inserts items to the beginning of the array. Returns new length. + * + * @param {List} arguments items to be inserted in the beginning of array + * @return {Integer} */ -function _prepareMessengers() { - // model will post all its changes on internal messenger - var internalMessenger = new Messenger(this, undefined, undefined); - - // message source to connect internal messenger to external - var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger); - - // external messenger to which all model users will subscribe, - // that will allow "*" subscriptions and support "changedata" message api. - var externalMessenger = new Messenger(this, undefined, internalMessengerSource); - - _.defineProperty(this, MESSENGER_PROPERTY, externalMessenger); - _.defineProperty(this, '_internalMessenger', internalMessenger); -} +function ModelPath$unshift() { // arguments + var length = this.len(); + length += arguments.length; + _.splice(arguments, 0, 0, 0, 0); + this.splice.apply(this, arguments); -function _getHostObject() { - return this._hostObject; + return length; } -function Model$$registerWithDOMStorage() { - var DOMStorage = require('../util/storage'); - DOMStorage.registerDataType('Model', Model_domStorageSerializer, Model_domStorageParser); - DOMStorage.registerDataType('ModelPath', Model_domStorageSerializer, Model_domStorageParser, 'Model'); +/** + * ModelPath and Model instance method + * Removes the item from the beginning of array (or pseudo-array). Returns this item. + * + * @return {Any} + */ +function ModelPath$shift() { // arguments + return this.splice(0, 1)[0]; } -function Model_domStorageSerializer(value) { - var data = value.get(); - return JSON.stringify(data); +/** + * ModelPath instance method + * Initializes ModelPath mesenger with Model's messenger as its source ([MessengerMessageSource](../messenger/msngr_source.js.html)) and [ModelPathMsgAPI](./path_msg_api.js.html) as [MessengerAPI](../messenger/m_api.js.html) + */ +function _prepareMessenger() { + var mPathAPI = new ModelPathMsgAPI(this._accessPath); + + // create MessengerMessageSource connected to Model's messenger + var modelMessageSource = new MessengerMessageSource(this, undefined, mPathAPI, this._model); + + // create messenger with model passed as hostObject (default message dispatch context) + // and without proxying methods (we don't want to proxy them to Model) + var mPathMessenger = new Messenger(this, undefined, modelMessageSource); + + // store messenger on ModelPath instance + _.defineProperty(this, MESSENGER_PROPERTY, mPathMessenger); } -function Model_domStorageParser(valueStr) { - var data = jsonParse(valueStr); - return new Model(data); +/** + * Returns the object allowing to recreate model path + * + * @return {Object} + */ +function _getDefinition() { + return { + model: this._model, + path: this._path, + args: this._args + }; } -function Model$destroy() { +/** + * Class method + * Creates modelPath object from definition created by _getDefinition + * + * @param {Object} definition + * @return {ModelPath} + */ +function _createFromDefinition(definition) { + check(definition, { + model: Function, // Model + path: String, + args: Array + }); + + var m = definition.model; + + return m.apply(m, definition.args); +} + + +function ModelPath$destroy() { this[MESSENGER_PROPERTY].destroy(); - this._internalMessenger.destroy(); - this._destroyed = true; } -},{"../abstract/mixin":3,"../messenger":67,"../messenger/msngr_source":71,"../util/check":92,"../util/error":100,"../util/json_parse":103,"../util/logger":104,"../util/storage":108,"./change_data":74,"./m_msg_api":77,"./m_path":78,"./path_utils":81,"./synthesize":82,"mol-proto":117}],77:[function(require,module,exports){ +},{"../messenger":67,"../messenger/msngr_source":71,"../util/check":90,"./change_data":73,"./path_msg_api":78,"./path_utils":79,"./synthesize":80,"mol-proto":150}],77:[function(require,module,exports){ 'use strict'; -var MessengerRegexpAPI = require('../messenger/m_api_rx') + +var modelUtils = { + normalizeSpliceIndex: normalizeSpliceIndex +}; + +module.exports = modelUtils; + + +function normalizeSpliceIndex(spliceIndex, length) { + return spliceIndex > length + ? length + : spliceIndex >= 0 + ? spliceIndex + : spliceIndex + length > 0 + ? spliceIndex + length + : 0; +} + +},{}],78:[function(require,module,exports){ +'use strict'; + +var MessengerAPI = require('../messenger/m_api') , pathUtils = require('./path_utils') + , logger = require('../util/logger') , _ = require('mol-proto'); /** - * Subclass of MessengerRegexpAPI that is used to translate messages of external messenger of Model to internal messenger of Model. + * Subclass of MessengerAPI that is used to translate messages of Messenger on ModelPath to Messenger on Model. */ -var ModelMsgAPI = _.createSubclass(MessengerRegexpAPI, 'ModelMsgAPI'); +var ModelPathMsgAPI = _.createSubclass(MessengerAPI, 'ModelPathMsgAPI'); -module.exports = ModelMsgAPI; +module.exports = ModelPathMsgAPI; /** - * ####ModelMsgAPI instance methods#### + * ####ModelPathMsgAPI instance methods#### * - * - [translateToSourceMessage](#translateToSourceMessage) - translates subscription paths with "*"s to regex, leaving other strings untouched + * - [init](#init) - initializes ModelPathMsgAPI + * - [translateToSourceMessage](#translateToSourceMessage) - translates relative access paths of ModelPath to full path of Model + * - [createInternalData](#createInternalData) - changes path in message on model to relative path and adds `fullPath` property to message data */ -_.extendProto(ModelMsgAPI, { +_.extendProto(ModelPathMsgAPI, { + init: init, translateToSourceMessage: translateToSourceMessage, + createInternalData: createInternalData, }); /** - * ModelMsgAPI instance method - * Translates subscription paths with "*"s to regex, leaving other strings untouched. + * ModelPathMsgAPI instance method + * Called by MessengerAPI constructor. * - * @param {String} accessPath relative access path to be translated - * @return {RegExp|String} + * @param {String} rootPath root path of model path */ -function translateToSourceMessage(accessPath) { - if (accessPath instanceof RegExp) return accessPath; - - return pathUtils.createRegexPath(accessPath); +function init(rootPath) { + MessengerAPI.prototype.init.apply(this, arguments); + this.rootPath = rootPath; } -},{"../messenger/m_api_rx":69,"./path_utils":81,"mol-proto":117}],78:[function(require,module,exports){ -'use strict'; - -var synthesize = require('./synthesize') - , pathUtils = require('./path_utils') - , changeDataHandler = require('./change_data') - , Messenger = require('../messenger') - , ModelPathMsgAPI = require('./path_msg_api') - , MessengerMessageSource = require('../messenger/msngr_source') - , _ = require('mol-proto') - , check = require('../util/check') - , Match = check.Match; - - -module.exports = ModelPath; +/** + * ModelPathMsgAPI instance method + * Translates relative access paths of ModelPath to full path of Model. + * + * @param {String} accessPath relative access path to be translated + * @return {String} + */ +function translateToSourceMessage(message) { + // TODO should prepend RegExes + // TODO should not prepend changedata too??? + if (message instanceof RegExp) + return message; + if (message == 'datachanges') + return message; + + return this.rootPath + message; +} /** - * `milo.Model.Path` - * ModelPath object that allows access to any point inside [Model](./index.js.html) as defined by `accessPath` + * ModelPathMsgAPI instance method + * Changes path in message on model to relative path and adds `fullPath` property to message data. * - * @constructor - * @param {Model} model Model instance that ModelPath gives access to. - * @param {String} accessPath string that defines path to access model. - * Path string consists of parts to define either property access (`".name"` to access property name) or array item access (`"[1]"` to access item with index 1). - * Access path can contain as many parts as necessary (e.g. `".list[0].name"` to access property `name` in the first element of array stored in property `list`. - * @param {List} arguments additional arguments of this method can be used to create interpolated paths. - * E.g. `m.path("[$1].$2", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m("[" + id + "]." + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`. - * @return {ModelPath} + * @param {String} sourceMessage full access path on Model + * @param {String} message relative access path on ModelPath + * @param {Object} sourceData data received from Model, will be translated as described to be dispatched to ModelPath + * @return {Object} */ -function ModelPath(model, path) { // ,... - additional arguments for interpolation - // check(model, Model); - check(path, String); - - // `modelPath` will be returned by constructor instead of `this`. `modelPath` - // (`modelPath_path` function) should also return a ModelPath object with "synthesized" methods - // to get/set model properties, to subscribe to property changes, etc. - // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below. - var modelPath = function modelPath_path(accessPath) { // , ... arguments that will be interpolated - return ModelPath$path.apply(modelPath, arguments); - }; - modelPath.__proto__ = ModelPath.prototype; +function createInternalData(sourceMessage, message, sourceData) { + // TODO return on changedata too??? + if (message == 'datachanges') { + var internalChanges = sourceData.changes + .map(truncateChangePath, this) + .filter(function(change) { return change; }); + var internalData = { + changes: internalChanges, + transaction: sourceData.transaction + }; + return internalData + } - _.defineProperties(modelPath, { - _model: model, - _path: path, - _args: _.slice(arguments, 1), // path will be the first element of this array - _options: model._options - }); + var internalData = truncateChangePath.call(this, sourceData); + return internalData; +} - // parse access path - var parsedPath = pathUtils.parseAccessPath(path); - // compute access path string - _.defineProperty(modelPath, '_accessPath', interpolateAccessPath(parsedPath, modelPath._args)); +function truncateChangePath(change) { + var fullPath = change.path + , path = _.unPrefix(fullPath, this.rootPath); - if (modelPath._options.reactive !== false) { - // messenger fails on "*" subscriptions - modelPath._prepareMessenger(); - // subscribe to "changedata" message to enable reactive connections - modelPath.onSync('changedata', changeDataHandler); + if (typeof path == 'string') { + var change = _.clone(change); + change.fullPath = fullPath; + change.path = path; + return change; } +} - // compiling getter and setter - var methods = synthesize(path, parsedPath); +},{"../messenger/m_api":68,"../util/logger":102,"./path_utils":79,"mol-proto":150}],79:[function(require,module,exports){ +'use strict'; - // adding methods to model path - _.defineProperties(modelPath, methods); +// +// ### model path utils - Object.freeze(modelPath); +var check = require('../util/check') + , Match = check.Match + , _ = require('mol-proto') + , ModelError = require('../util/error').Model; - return modelPath; -} +var pathUtils = { + parseAccessPath: parseAccessPath, + createRegexPath: createRegexPath, + getPathNodeKey: getPathNodeKey, + wrapMessengerMethods: wrapMessengerMethods +}; -ModelPath.prototype.__proto__ = ModelPath.__proto__; +module.exports = pathUtils; -/** - * Interpolates path elements to compute real path - * - * @param {Array} parsedPath parsed path - array of path nodes - * @param {Array} args path interpolation arguments, args[0] is path itself - * @return {String} - */ -function interpolateAccessPath(parsedPath, args) { - return parsedPath.reduce(function(accessPathStr, currNode, index) { - var interpolate = currNode.interpolate; - return accessPathStr + - (interpolate - ? (currNode.syntax == 'array' - ? '[' + args[interpolate] + ']' - : '.' + args[interpolate]) - : currNode.property); - }, ''); -} - - -/** - * ####ModelPath instance methods#### - * - * - [path](#ModelPath$path) - gives access to path inside ModelPath - * - get - synthesized - * - set - synthesized - * - splice - splice model data (as array or pseudo-array), synthesized - * - [len](#ModelPath$len) - returns length of array (or pseudo-array) in safe way, 0 if no length is set - * - [push](#ModelPath$push) - add items to the end of array (or pseudo-array) in ModelPath - * - [pop](#ModelPath$pop) - remove item from the end of array (or pseudo-array) in ModelPath - * - [unshift](#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in ModelPath - * - [shift](#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in ModelPath - */ -_.extendProto(ModelPath, { - path: ModelPath$path, - len: ModelPath$len, - push: ModelPath$push, - pop: ModelPath$pop, - unshift: ModelPath$unshift, - shift: ModelPath$shift, - _prepareMessenger: _prepareMessenger, - _getDefinition: _getDefinition, - destroy: ModelPath$destroy -}); - +var propertyPathSyntax = '\\.[A-Za-z_-][A-Za-z0-9_-]*' + , arrayPathSyntax = '\\[[0-9]+\\]' + , interpolationSyntax = '\\$[1-9][0-9]*' + , propertyInterpolateSyntax = '\\.' + interpolationSyntax + , arrayInterpolateSyntax = '\\[' + interpolationSyntax + '\\]' -_.extend(ModelPath, { - _createFromDefinition: _createFromDefinition -}) + , propertyStarSyntax = '\\.\\*' + , arrayStarSyntax = '\\[\\*\\]' + , starSyntax = '\\*' + , pathParseSyntax = [ + propertyPathSyntax, + arrayPathSyntax, + propertyInterpolateSyntax, + arrayInterpolateSyntax + ].join('|') + , pathParsePattern = new RegExp(pathParseSyntax, 'g') -/** - * Expose Messenger methods on Facet prototype - */ -var MESSENGER_PROPERTY = '_messenger'; -Messenger.useWith(ModelPath, MESSENGER_PROPERTY, Messenger.defaultMethods); + , patternPathParseSyntax = [ + pathParseSyntax, + propertyStarSyntax, + arrayStarSyntax, + starSyntax + ].join('|') + , patternPathParsePattern = new RegExp(patternPathParseSyntax, 'g') + //, targetPathParsePattern = /\.[A-Za-z][A-Za-z0-9_]*|\[[0-9]+\]|\.\$[1-9][0-9]*|\[\$[1-9][0-9]*\]|\$[1-9][0-9]/g + , pathNodeTypes = { + '.': { syntax: 'object', empty: '{}' }, + '[': { syntax: 'array', empty: '[]'}, + '*': { syntax: 'match', empty: '{}'}, + }; -/** - * ModelPath instance method - * Gives access to path inside ModelPath. Method works similarly to [path method](#Model$path) of model, using relative paths. - * - * @param {String} accessPath string that defines path to access model. - * Path string consists of parts to define either property access (`".name"` to access property name) or array item access (`"[1]"` to access item with index 1). - * Access path can contain as many parts as necessary (e.g. `".list[0].name"` to access property `name` in the first element of array stored in property `list`. - * @param {List} arguments additional arguments of this method can be used to create interpolated paths. - * E.g. `m.path("[$1].$2", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m("[" + id + "]." + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`. - * @return {ModelPath} - */ -function ModelPath$path(accessPath) { // , ... arguments that will be interpolated - if (! accessPath) return this; +function parseAccessPath(path, nodeParsePattern) { + nodeParsePattern = nodeParsePattern || pathParsePattern; - var thisPathArgsCount = this._args.length - 1; + var parsedPath = []; - if (thisPathArgsCount > 0) {// this path has interpolated arguments too - accessPath = accessPath.replace(/\$[1-9][0-9]*/g, function(str) { - return '$' + (+str.slice(1) + thisPathArgsCount); - }); - } + if (! path) + return parsedPath; - var newPath = this._path + accessPath; + var unparsed = path.replace(nodeParsePattern, function(nodeStr) { + var pathNode = { property: nodeStr }; + _.extend(pathNode, pathNodeTypes[nodeStr[0]]); + if (nodeStr[1] == '$') + pathNode.interpolate = getPathNodeKey(pathNode, true); - // this._model is added in front of all arguments as the first parameter - // of ModelPath constructor - var args = [this._model, newPath] - .concat(this._args.slice(1)) // remove old path from _args, as it is 1 based - .concat(_.slice(arguments, 1)); // add new interpolation arguments + parsedPath.push(pathNode); + return ''; + }); + if (unparsed) + throw new ModelError('incorrect model path: ' + path); - // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ... - return _.newApply(ModelPath, args); + return parsedPath; } -/** - * ModelPath and Model instance method - * Returns length property and sets it to 0 if it wasn't set. - * - * @return {Any} - */ -function ModelPath$len() { - return this.path('.length').get() || 0; -} +var nodeRegex = { + '.*': propertyPathSyntax, + '[*]': arrayPathSyntax +}; +nodeRegex['*'] = nodeRegex['.*'] + '|' + nodeRegex['[*]']; +function createRegexPath(path) { + check(path, Match.OneOf(String, RegExp)); -/** - * ModelPath and Model instance method - * Adds items to the end of array (or pseudo-array). Returns new length. - * - * @param {List} arguments list of items that will be added to array (pseudo array) - * @return {Integer} - */ -function ModelPath$push() { // arguments - var length = this.len(); - var newLength = length + arguments.length; + if (path instanceof RegExp || path.indexOf('*') == -1) + return path; - _.splice(arguments, 0, 0, length, 0); - this.splice.apply(this, arguments); + var parsedPath = pathUtils.parseAccessPath(path, patternPathParsePattern) + , regexStr = '^' + // , regexStrEnd = '' + , patternsStarted = false; - return newLength; -} + parsedPath.forEach(function(pathNode) { + var prop = pathNode.property + , regex = nodeRegex[prop]; + + if (regex) { + // regexStr += '(' + regex; + // regexStrEnd += '|)'; + regexStr += '(' + regex + '|)'; + // regexStrEnd += '|)'; + patternsStarted = true; + } else { + // if (patternsStarted) + // throw new ModelError('"*" path segment cannot be in the middle of the path: ' + path); + regexStr += prop.replace(/(\.|\[|\])/g, '\\$1'); // add slash in front of symbols that have special meaning in regex + } + }); + regexStr += /* regexStrEnd + */ '$'; -/** - * ModelPath and Model instance method - * Removes item from the end of array (or pseudo-array). Returns this item. - * - * @return {Any} - */ -function ModelPath$pop() { - return this.splice(this.len() - 1, 1)[0]; + try { + return new RegExp(regexStr); + } catch (e) { + throw new ModelError('can\'t construct regex for path pattern: ' + path); + } } -/** - * ModelPath and Model instance method - * Inserts items to the beginning of the array. Returns new length. - * - * @param {List} arguments items to be inserted in the beginning of array - * @return {Integer} - */ -function ModelPath$unshift() { // arguments - var length = this.len(); - length += arguments.length; +function getPathNodeKey(pathNode, interpolated) { + var prop = pathNode.property + , startIndex = interpolated ? 2 : 1; + return pathNode.syntax == 'array' + ? prop.slice(startIndex, prop.length - 1) + : prop.slice(startIndex); +} - _.splice(arguments, 0, 0, 0, 0); - this.splice.apply(this, arguments); - return length; +// TODO allow for multiple messages in a string +function wrapMessengerMethods(methodsNames) { + methodsNames = methodsNames || ['on', 'off']; + var wrappedMethods = _.mapToObject(methodsNames, function(methodName) { + var origMethod = this[methodName]; + // replacing message subsribe/unsubscribe/etc. to convert "*" message patterns to regexps + return function(path, subscriber) { + var regexPath = createRegexPath(path); + origMethod.call(this, regexPath, subscriber); + }; + }, this); + _.defineProperties(this, wrappedMethods); } +},{"../util/check":90,"../util/error":98,"mol-proto":150}],80:[function(require,module,exports){ +'use strict'; -/** - * ModelPath and Model instance method - * Removes the item from the beginning of array (or pseudo-array). Returns this item. - * - * @return {Any} - */ -function ModelPath$shift() { // arguments - return this.splice(0, 1)[0]; -} +var pathUtils = require('../path_utils') + , modelUtils = require('../model_utils') + , logger = require('../../util/logger') + , miloCount = require('../../util/count') + , fs = require('fs') + , doT = require('dot') + , _ = require('mol-proto') + , changeDataHandler = require('../change_data') + , getTransactionFlag = changeDataHandler.getTransactionFlag + , postTransactionFinished = changeDataHandler.postTransactionFinished; /** - * ModelPath instance method - * Initializes ModelPath mesenger with Model's messenger as its source ([MessengerMessageSource](../messenger/msngr_source.js.html)) and [ModelPathMsgAPI](./path_msg_api.js.html) as [MessengerAPI](../messenger/m_api.js.html) + * Templates to synthesize model getters and setters */ -function _prepareMessenger() { - var mPathAPI = new ModelPathMsgAPI(this._accessPath); +var templates = { + get: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\nmethod = function get() {\n var m = {{# def.modelAccessPrefix }};\n return m {{~ it.parsedPath :pathNode }}\n {{? pathNode.interpolate}}\n && (m = m[this._args[ {{= pathNode.interpolate }} ]])\n {{??}}\n && (m = m{{= pathNode.property }})\n {{?}} {{~}};\n};\n", + set: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n\n\n/**\n * Template that synthesizes setter for Model and for ModelPath\n */\nmethod = function set(value) {\n {{# def.initVars:'set' }}\n\n {{# def.createTree:'set' }}\n\n {{\n currNode = nextNode;\n currProp = currNode && currNode.property;\n }}\n\n {{ /* assign value to the last property */ }}\n {{? currProp }}\n wasDef = {{# def.wasDefined}};\n {{# def.changeAccessPath }}\n\n var old = m{{# def.currProp }};\n\n {{ /* clone value to prevent same reference in linked models */ }}\n m{{# def.currProp }} = cloneTree(value);\n {{?}}\n\n {{ /* add message related to the last property change */ }}\n if (this._options.reactive !== false) {\n if (! wasDef)\n {{# def.addMsg }} accessPath, type: 'added',\n newValue: value });\n else if (old != value)\n {{# def.addMsg }} accessPath, type: 'changed',\n oldValue: old, newValue: value });\n\n {{ /* add message related to changes in (sub)properties inside removed and assigned value */ }}\n if (! wasDef || old != value)\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, value); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n", + del: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_traverse_tree }}\n\nmethod = function del() {\n {{# def.initVars:'del' }}\n\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n if (! treeDoesNotExist && m && m.hasOwnProperty && {{# def.wasDefined}}) {\n var old = m{{# def.currProp }};\n delete m{{# def.currProp }};\n {{# def.changeAccessPath }}\n var didDelete = true;\n }\n {{??}}\n if (typeof m != 'undefined') {\n var old = m;\n {{# def.modelAccessPrefix }} = undefined;\n var didDelete = true;\n }\n {{?}}\n\n if (didDelete && this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'deleted', oldValue: old });\n\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, undefined); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n", + splice: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n{{# def.include_traverse_tree }}\n\nmethod = function splice(spliceIndex, spliceHowMany) { /* ,... - extra arguments to splice into array */\n {{# def.initVars:'splice' }}\n\n var argsLen = arguments.length;\n var addItems = argsLen > 2;\n\n if (addItems) {\n {{ /* only create model tree if items are inserted in array */ }}\n\n {{ /* if model is undefined it will be set to an empty array */ }} \n var value = [];\n {{# def.createTree:'splice' }}\n\n {{? nextNode }}\n {{\n var currNode = nextNode;\n var currProp = currNode.property;\n var emptyProp = '[]';\n }}\n\n {{# def.createTreeStep }}\n {{?}}\n\n } else if (spliceHowMany > 0) {\n {{ /* if items are not inserted, only traverse model tree if items are deleted from array */ }}\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n {{ /* extra brace closes 'else' in def.traverseTreeStep */ }}\n {{# def.traverseTreeStep }} }\n {{?}}\n }\n\n {{ /* splice items */ }}\n if (addItems || (! treeDoesNotExist && m\n && m.length > spliceIndex ) ) {\n var oldLength = m.length = m.length || 0;\n\n arguments[0] = spliceIndex = normalizeSpliceIndex(spliceIndex, m.length);\n\n {{ /* clone added arguments to prevent same references in linked models */ }}\n if (addItems)\n for (var i = 2; i < argsLen; i++)\n arguments[i] = cloneTree(arguments[i]);\n\n {{ /* actual splice call */ }}\n var removed = Array.prototype.splice.apply(m, arguments);\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'splice',\n index: spliceIndex, removed: removed, addedCount: addItems ? argsLen - 2 : 0,\n newValue: m });\n\n if (removed && removed.length)\n removed.forEach(function(item, index) {\n var itemPath = accessPath + '[' + (spliceIndex + index) + ']';\n {{# def.addMsg }} itemPath, type: 'removed', oldValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'removed', 'oldValue');\n });\n\n if (addItems)\n for (var i = 2; i < argsLen; i++) {\n var item = arguments[i];\n var itemPath = accessPath + '[' + (spliceIndex + i - 2) + ']';\n {{# def.addMsg }} itemPath, type: 'added', newValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'added', 'newValue');\n }\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n }\n\n return removed || [];\n}\n" +}; - // create MessengerMessageSource connected to Model's messenger - var modelMessageSource = new MessengerMessageSource(this, undefined, mPathAPI, this._model); +var include_defines = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts initialization code\n */\n {{## def.initVars:method:\n var m = {{# def.modelAccessPrefix }};\n var messages = [], messagesHash = {};\n var accessPath = '';\n var treeDoesNotExist;\n /* hack to prevent sending finished events to allow for propagation of batches without splitting them */\n var inChangeTransaction = getTransactionFlag( {{= method }} );\n #}}\n\n/**\n * Inserts the beginning of function call to add message to list\n */\n{{## def.addMsg: addChangeMessage(messages, messagesHash, { path: #}}\n\n/**\n * Inserts current property/index for both normal and interpolated properties/indexes\n */\n{{## def.currProp:{{? currNode.interpolate }}[this._args[ {{= currNode.interpolate }} ]]{{??}}{{= currProp }}{{?}} #}}\n\n/**\n * Inserts condition to test whether normal/interpolated property/index exists\n */\n{{## def.wasDefined: m.hasOwnProperty(\n {{? currNode.interpolate }}\n this._args[ {{= currNode.interpolate }} ]\n {{??}}\n '{{= it.getPathNodeKey(currNode) }}'\n {{?}}\n) #}}\n\n\n/**\n * Inserts code to update access path for current property\n * Because of the possibility of interpolated properties, it can't be calculated in template, it can only be calculated during accessor call.\n */\n{{## def.changeAccessPath:\n accessPath += {{? currNode.interpolate }}\n {{? currNode.syntax == 'array' }}\n '[' + this._args[ {{= currNode.interpolate }} ] + ']';\n {{??}}\n '.' + this._args[ {{= currNode.interpolate }} ];\n {{?}}\n {{??}}\n '{{= currProp }}';\n {{?}}\n#}}\n\n\n/**\n * Inserts code to post stored messages\n */\n{{## def.postMessages:\n if (messages.length) {\n {{# def.modelPostBatchCode }}('datachanges', {\n changes: messages,\n transaction: inChangeTransaction\n });\n\n messages.forEach(function(msg) {\n {{# def.modelPostMessageCode }}(msg.path, msg);\n }, this);\n }\n#}}\n" + , include_create_tree = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to create model tree as neccessary for `set` and `splice` accessors and to add messages to send list if the tree changes.\n */\n{{## def.createTree:method:\n var wasDef = true;\n var old = m;\n\n {{ var emptyProp = it.parsedPath[0] && it.parsedPath[0].empty; }}\n {{? emptyProp }}\n {{ /* create top level model if it was not previously defined */ }}\n if (! m) {\n m = {{# def.modelAccessPrefix }} = {{= emptyProp }};\n wasDef = false;\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} '', type: 'added',\n newValue: m });\n }\n }\n {{??}}\n {{? method == 'splice' }}\n if (! m) {\n {{?}}\n m = {{# def.modelAccessPrefix }} = cloneTree(value);\n wasDef = typeof old != 'undefined';\n {{? method == 'splice' }}\n }\n {{?}} \n {{?}}\n\n\n {{ /* create model tree if it doesn't exist */ }}\n {{ var modelDataProperty = '';\n var nextNode = it.parsedPath[0];\n var count = it.parsedPath.length - 1;\n\n for (var i = 0; i < count; i++) {\n var currNode = nextNode;\n var currProp = currNode.property;\n nextNode = it.parsedPath[i + 1];\n var emptyProp = nextNode && nextNode.empty;\n }}\n\n {{# def.createTreeStep }}\n\n {{ } /* for loop */ }}\n#}}\n\n\n/**\n * Inserts code to create one step in the model tree\n */\n{{## def.createTreeStep:\n {{# def.changeAccessPath }}\n\n if (! {{# def.wasDefined }}) { \n {{ /* property does not exist */ }}\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'added', \n newValue: m });\n }\n\n } else if (typeof m{{# def.currProp }} != 'object') {\n {{ /* property is not object */ }}\n var old = m{{# def.currProp }};\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'changed', \n oldValue: old, newValue: m });\n }\n\n } else {\n {{ /* property exists, just traverse down the model tree */ }}\n m = m{{# def.currProp }};\n }\n#}}\n" + , include_traverse_tree = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to traverse model tree for `delete` and `splice` accessors.\n */\n{{## def.traverseTree:\n {{ \n var count = it.parsedPath.length-1;\n\n for (var i = 0; i < count; i++) { \n var currNode = it.parsedPath[i];\n var currProp = currNode.property;\n }}\n {{# def.traverseTreeStep }}\n\n {{ } /* for loop */\n\n var i = count;\n while (i--) { /* closing braces for else's above */\n }}\n }\n {{ } /* while loop */ }}\n#}}\n\n\n/**\n * Inserts code to traverse one step in the model tree\n */\n{{## def.traverseTreeStep:\n if (! (m && m.hasOwnProperty && {{# def.wasDefined}} ) )\n treeDoesNotExist = true;\n else {\n m = m{{# def.currProp }};\n {{# def.changeAccessPath }}\n {{ /* brace from else is not closed on purpose - all braces are closed in while loop */ }}\n#}}\n"; - // create messenger with model passed as hostObject (default message dispatch context) - // and without proxying methods (we don't want to proxy them to Model) - var mPathMessenger = new Messenger(this, undefined, modelMessageSource); +var dotDef = { + include_defines: include_defines, + include_create_tree: include_create_tree, + include_traverse_tree: include_traverse_tree, + getPathNodeKey: pathUtils.getPathNodeKey, + modelAccessPrefix: 'this._model._data', + modelPostMessageCode: 'this._model._internalMessenger.postMessage', + modelPostBatchCode: 'this._model.postMessageSync', + internalMessenger: 'this._model._internalMessenger' +}; - // store messenger on ModelPath instance - _.defineProperty(this, MESSENGER_PROPERTY, mPathMessenger); -} +var modelDotDef = _(dotDef).clone().extend({ + modelAccessPrefix: 'this._data', + modelPostMessageCode: 'this._internalMessenger.postMessage', + modelPostBatchCode: 'this.postMessageSync', + internalMessenger: 'this._internalMessenger' +})._(); -/** - * Returns the object allowing to recreate model path - * - * @return {Object} - */ -function _getDefinition() { - return { - model: this._model, - path: this._path, - args: this._args - }; -} +var dotSettings = _.clone(doT.templateSettings); +dotSettings.strip = false; + +var synthesizers = _.mapKeys(templates, function(tmpl) { + return doT.template(tmpl, dotSettings, dotDef); +}); + + +var modelSynthesizers = _.mapToObject(['set', 'del', 'splice'], function(methodName) { + return doT.template(templates[methodName], dotSettings, modelDotDef); +}); /** - * Class method - * Creates modelPath object from definition created by _getDefinition + * Function that synthesizes accessor methods. + * Function is memoized so accessors are cached (up to 1000). * - * @param {Object} definition - * @return {ModelPath} + * @param {String} path Model/ModelPath access path + * @param {Array} parsedPath array of path nodes + * @return {Object[Function]} */ -function _createFromDefinition(definition) { - check(definition, { - model: Function, // Model - path: String, - args: Array +var synthesizePathMethods = _.memoize(_synthesizePathMethods, undefined, 1000); + +function _synthesizePathMethods(path, parsedPath) { + var methods = _.mapKeys(synthesizers, function(synthszr) { + return _synthesize(synthszr, path, parsedPath); }); + return methods; +} - var m = definition.model; - return m.apply(m, definition.args); -} +var normalizeSpliceIndex = modelUtils.normalizeSpliceIndex; // used in splice.dot.js -function ModelPath$destroy() { - this[MESSENGER_PROPERTY].destroy(); -} +function _synthesize(synthesizer, path, parsedPath) { + var method + , methodCode = synthesizer({ + parsedPath: parsedPath, + getPathNodeKey: pathUtils.getPathNodeKey + }); -},{"../messenger":67,"../messenger/msngr_source":71,"../util/check":92,"./change_data":74,"./path_msg_api":80,"./path_utils":81,"./synthesize":82,"mol-proto":117}],79:[function(require,module,exports){ -'use strict'; + try { + eval(methodCode); + } catch (e) { + throw ModelError('ModelPath method compilation error; path: ' + path + ', code: ' + methodCode); + } + return method; -var modelUtils = { - normalizeSpliceIndex: normalizeSpliceIndex -}; -module.exports = modelUtils; + // functions used by methods `set`, `delete` and `splice` (synthesized by template) + function addChangeMessage(messages, messagesHash, msg) { + messages.push(msg); + messagesHash[msg.path] = msg; + } + function addTreeChangesMessages(messages, messagesHash, rootPath, oldValue, newValue) { + var oldIsTree = valueIsTree(oldValue) + , newIsTree = valueIsTree(newValue); -function normalizeSpliceIndex(spliceIndex, length) { - return spliceIndex > length - ? length - : spliceIndex >= 0 - ? spliceIndex - : spliceIndex + length > 0 - ? spliceIndex + length - : 0; -} + if (newIsTree) + addMessages(messages, messagesHash, rootPath, newValue, 'added', 'newValue'); + + if (oldIsTree) + addMessages(messages, messagesHash, rootPath, oldValue, 'removed', 'oldValue'); + } -},{}],80:[function(require,module,exports){ -'use strict'; + function addMessages(messages, messagesHash, rootPath, obj, msgType, valueProp) { + _addMessages(rootPath, obj); -var MessengerAPI = require('../messenger/m_api') - , pathUtils = require('./path_utils') - , logger = require('../util/logger') - , _ = require('mol-proto'); + function _addMessages(rootPath, obj) { + if (Array.isArray(obj)) { + var pathSyntax = rootPath + '[$$]'; + obj.forEach(function(value, index) { + addMessage(value, index, pathSyntax); + }); + } else { + var pathSyntax = rootPath + '.$$'; + _.eachKey(obj, function(value, key) { + addMessage(value, key, pathSyntax); + }); + } + } -/** - * Subclass of MessengerAPI that is used to translate messages of Messenger on ModelPath to Messenger on Model. - */ -var ModelPathMsgAPI = _.createSubclass(MessengerAPI, 'ModelPathMsgAPI'); + function addMessage(value, key, pathSyntax) { + var path = pathSyntax.replace('$$', key) + , existingMsg = messagesHash[path]; -module.exports = ModelPathMsgAPI; + if (existingMsg) { + if (existingMsg.type == msgType) + logger.error('setter error: same message type posted on the same path'); + else { + existingMsg.type = 'changed'; + existingMsg[valueProp] = value; + } + } else { + var msg = { path: path, type: msgType }; + msg[valueProp] = value; + addChangeMessage(messages, messagesHash, msg); + } + if (valueIsTree(value)) + _addMessages(path, value); + } + } -/** - * ####ModelPathMsgAPI instance methods#### - * - * - [init](#init) - initializes ModelPathMsgAPI - * - [translateToSourceMessage](#translateToSourceMessage) - translates relative access paths of ModelPath to full path of Model - * - [createInternalData](#createInternalData) - changes path in message on model to relative path and adds `fullPath` property to message data - */ -_.extendProto(ModelPathMsgAPI, { - init: init, - translateToSourceMessage: translateToSourceMessage, - createInternalData: createInternalData, -}); + function cloneTree(value) { + return valueIsNormalObject(value) + ? _.deepClone(value) + : value; + } + function protectValue(value) { + return ! valueIsNormalObject(value) + ? value + : Array.isArray(value) + ? value.slice() + : Object.create(value); + } -/** - * ModelPathMsgAPI instance method - * Called by MessengerAPI constructor. - * - * @param {String} rootPath root path of model path - */ -function init(rootPath) { - MessengerAPI.prototype.init.apply(this, arguments); - this.rootPath = rootPath; + function valueIsTree(value) { + return valueIsNormalObject(value) + && Object.keys(value).length; + } + + function valueIsNormalObject(value) { + return value != null + && typeof value == "object" + && ! (value instanceof Date) + && ! (value instanceof RegExp); + } + + function addBatchIdsToMessage(msg, batchId, msgId) { + _.defineProperties(msg, { + __batch_id: batchId, + __msg_id: msgId + }); + } } + /** - * ModelPathMsgAPI instance method - * Translates relative access paths of ModelPath to full path of Model. + * Exports `synthesize` function with the following: * - * @param {String} accessPath relative access path to be translated - * @return {String} + * - .modelMethods.set - `set` method for Model + * - .modelMethods.del - `del` method for Model + * - .modelMethods.splice - `splice` method for Model */ -function translateToSourceMessage(message) { - // TODO should prepend RegExes - // TODO should not prepend changedata too??? - if (message instanceof RegExp) - return message; - if (message == 'datachanges') - return message; - - return this.rootPath + message; -} +module.exports = synthesizePathMethods; + +var modelMethods = _.mapKeys(modelSynthesizers, function(synthesizer) { + return _synthesize(synthesizer, '', []); +}); + +synthesizePathMethods.modelMethods = modelMethods; +},{"../../util/count":92,"../../util/logger":102,"../change_data":73,"../model_utils":77,"../path_utils":79,"dot":115,"fs":113,"mol-proto":150}],81:[function(require,module,exports){ +'use strict'; /** - * ModelPathMsgAPI instance method - * Changes path in message on model to relative path and adds `fullPath` property to message data. + * Registries of facets and of components * - * @param {String} sourceMessage full access path on Model - * @param {String} message relative access path on ModelPath - * @param {Object} sourceData data received from Model, will be translated as described to be dispatched to ModelPath - * @return {Object} + * - [facets](./components/c_facets/cf_registry.js.html) + * - [components](./components/c_registry.js.html) */ -function createInternalData(sourceMessage, message, sourceData) { - // TODO return on changedata too??? - if (message == 'datachanges') { - var internalChanges = sourceData.changes - .map(truncateChangePath, this) - .filter(function(change) { return change; }); - var internalData = { - changes: internalChanges, - transaction: sourceData.transaction - }; +var registry = module.exports = { + facets: require('./components/c_facets/cf_registry'), + components: require('./components/c_registry'), + commands: require('./command/cmd_registry') +}; - return internalData - } +},{"./command/cmd_registry":12,"./components/c_facets/cf_registry":31,"./components/c_registry":33}],82:[function(require,module,exports){ +'use strict'; - var internalData = truncateChangePath.call(this, sourceData); - return internalData; -} +// +// ###dom events constructors -function truncateChangePath(change) { - var fullPath = change.path - , path = _.unPrefix(fullPath, this.rootPath); - - if (typeof path == 'string') { - var change = _.clone(change); - change.fullPath = fullPath; - change.path = path; - return change; - } -} - -},{"../messenger/m_api":68,"../util/logger":104,"./path_utils":81,"mol-proto":117}],81:[function(require,module,exports){ -'use strict'; +var _ = require('mol-proto'); -// -// ### model path utils -var check = require('../util/check') - , Match = check.Match - , _ = require('mol-proto') - , ModelError = require('../util/error').Model; +// https://developer.mozilla.org/en-US/docs/Web/Reference/Events -var pathUtils = { - parseAccessPath: parseAccessPath, - createRegexPath: createRegexPath, - getPathNodeKey: getPathNodeKey, - wrapMessengerMethods: wrapMessengerMethods +var eventTypes = { + ClipboardEvent: ['copy', 'cut', 'paste', 'beforecopy', 'beforecut', 'beforepaste'], + Event: ['input', 'readystatechange'], + FocusEvent: ['focus', 'blur', 'focusin', 'focusout'], + KeyboardEvent: ['keydown', 'keypress', 'keyup'], + MouseEvent: ['click', 'contextmenu', 'dblclick', 'mousedown', 'mouseup', + 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', + 'show' /* context menu */], + TouchEvent: ['touchstart', 'touchend', 'touchmove', 'touchenter', 'touchleave', 'touchcancel'], }; -module.exports = pathUtils; - -var propertyPathSyntax = '\\.[A-Za-z_-][A-Za-z0-9_-]*' - , arrayPathSyntax = '\\[[0-9]+\\]' - , interpolationSyntax = '\\$[1-9][0-9]*' - , propertyInterpolateSyntax = '\\.' + interpolationSyntax - , arrayInterpolateSyntax = '\\[' + interpolationSyntax + '\\]' +// mock window and event constructors for testing +if (typeof window != 'undefined') + var global = window; +else { + global = {}; + _.eachKey(eventTypes, function(eTypes, eventConstructorName) { + var eventConstructor = _.makeFunction(eventConstructorName, 'type', 'properties', + 'this.type = type; _.extend(this, properties);'); + global[eventConstructorName] = eventConstructor; + }); +} - , propertyStarSyntax = '\\.\\*' - , arrayStarSyntax = '\\[\\*\\]' - , starSyntax = '\\*' - , pathParseSyntax = [ - propertyPathSyntax, - arrayPathSyntax, - propertyInterpolateSyntax, - arrayInterpolateSyntax - ].join('|') - , pathParsePattern = new RegExp(pathParseSyntax, 'g') +var domEventsConstructors = {}; - , patternPathParseSyntax = [ - pathParseSyntax, - propertyStarSyntax, - arrayStarSyntax, - starSyntax - ].join('|') - , patternPathParsePattern = new RegExp(patternPathParseSyntax, 'g') +_.eachKey(eventTypes, function(eTypes, eventConstructorName) { + eTypes.forEach(function(type) { + if (Object.hasOwnProperty(domEventsConstructors, type)) + throw new Error('duplicate event type ' + type); - //, targetPathParsePattern = /\.[A-Za-z][A-Za-z0-9_]*|\[[0-9]+\]|\.\$[1-9][0-9]*|\[\$[1-9][0-9]*\]|\$[1-9][0-9]/g - , pathNodeTypes = { - '.': { syntax: 'object', empty: '{}' }, - '[': { syntax: 'array', empty: '[]'}, - '*': { syntax: 'match', empty: '{}'}, - }; + domEventsConstructors[type] = global[eventConstructorName]; + }); +}); -function parseAccessPath(path, nodeParsePattern) { - nodeParsePattern = nodeParsePattern || pathParsePattern; - var parsedPath = []; +module.exports = domEventsConstructors; - if (! path) - return parsedPath; +},{"mol-proto":150}],83:[function(require,module,exports){ +'use strict'; - var unparsed = path.replace(nodeParsePattern, function(nodeStr) { - var pathNode = { property: nodeStr }; - _.extend(pathNode, pathNodeTypes[nodeStr[0]]); - if (nodeStr[1] == '$') - pathNode.interpolate = getPathNodeKey(pathNode, true); - parsedPath.push(pathNode); - return ''; - }); - if (unparsed) - throw new ModelError('incorrect model path: ' + path); +var MessageSource = require('../messenger/m_source') + , Component = require('../components/c_class') + , domEventsConstructors = require('./de_constrs') // TODO merge with DOMEventSource ?? + , _ = require('mol-proto') + , check = require('../util/check') + , Match = check.Match; - return parsedPath; -} +var DOMEmitterSource = _.createSubclass(MessageSource, 'DOMEmitterSource', true); -var nodeRegex = { - '.*': propertyPathSyntax, - '[*]': arrayPathSyntax -}; -nodeRegex['*'] = nodeRegex['.*'] + '|' + nodeRegex['[*]']; +_.extendProto(DOMEmitterSource, { + // implementing MessageSource interface + init: init, + destroy: DOMEmitterSource$destroy, + addSourceSubscriber: _.partial(sourceSubscriberMethod, 'addEventListener'), + removeSourceSubscriber: _.partial(sourceSubscriberMethod, 'removeEventListener'), + postMessage: DOMEmitterSource$postMessage, + trigger: trigger, -function createRegexPath(path) { - check(path, Match.OneOf(String, RegExp)); + // class specific methods + emitter: emitter, + handleEvent: handleEvent, // event dispatcher - as defined by Event DOM API +}); - if (path instanceof RegExp || path.indexOf('*') == -1) - return path; +module.exports = DOMEmitterSource; - var parsedPath = pathUtils.parseAccessPath(path, patternPathParsePattern) - , regexStr = '^' - // , regexStrEnd = '' - , patternsStarted = false; - parsedPath.forEach(function(pathNode) { - var prop = pathNode.property - , regex = nodeRegex[prop]; - - if (regex) { - // regexStr += '(' + regex; - // regexStrEnd += '|)'; - regexStr += '(' + regex + '|)'; - // regexStrEnd += '|)'; - patternsStarted = true; - } else { - // if (patternsStarted) - // throw new ModelError('"*" path segment cannot be in the middle of the path: ' + path); - regexStr += prop.replace(/(\.|\[|\])/g, '\\$1'); // add slash in front of symbols that have special meaning in regex - } - }); +var useCapturePattern = /__capture$/ + , useCapturePostfix = '__capture'; - regexStr += /* regexStrEnd + */ '$'; - try { - return new RegExp(regexStr); - } catch (e) { - throw new ModelError('can\'t construct regex for path pattern: ' + path); - } +// init DOM event source +function init(hostObject, proxyMethods, messengerAPIOrClass, eventEmitter) { + this.eventEmitter = eventEmitter; + MessageSource.prototype.init.apply(this, arguments); } -function getPathNodeKey(pathNode, interpolated) { - var prop = pathNode.property - , startIndex = interpolated ? 2 : 1; - return pathNode.syntax == 'array' - ? prop.slice(startIndex, prop.length - 1) - : prop.slice(startIndex); +function DOMEmitterSource$destroy() { + MessageSource.prototype.destroy.apply(this, arguments); + delete this.eventEmitter; } -// TODO allow for multiple messages in a string -function wrapMessengerMethods(methodsNames) { - methodsNames = methodsNames || ['on', 'off']; - var wrappedMethods = _.mapToObject(methodsNames, function(methodName) { - var origMethod = this[methodName]; - // replacing message subsribe/unsubscribe/etc. to convert "*" message patterns to regexps - return function(path, subscriber) { - var regexPath = createRegexPath(path); - origMethod.call(this, regexPath, subscriber); - }; - }, this); - _.defineProperties(this, wrappedMethods); +// get DOM element of component +function emitter() { + return this.eventEmitter; } -},{"../util/check":92,"../util/error":100,"mol-proto":117}],82:[function(require,module,exports){ -'use strict'; -var pathUtils = require('../path_utils') - , modelUtils = require('../model_utils') - , logger = require('../../util/logger') - , miloCount = require('../../util/count') - , fs = require('fs') - , doT = require('dot') - , _ = require('mol-proto') - , changeDataHandler = require('../change_data') - , getTransactionFlag = changeDataHandler.getTransactionFlag - , postTransactionFinished = changeDataHandler.postTransactionFinished; +function sourceSubscriberMethod(method, eventType) { + if (! (eventType && typeof eventType == 'string')) return; + var capture = useCapturePattern.test(eventType); + eventType = eventType.replace(useCapturePattern, ''); + this.emitter()[method](eventType, this, capture); +} -/** - * Templates to synthesize model getters and setters - */ -var templates = { - get: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\nmethod = function get() {\n var m = {{# def.modelAccessPrefix }};\n return m {{~ it.parsedPath :pathNode }}\n {{? pathNode.interpolate}}\n && (m = m[this._args[ {{= pathNode.interpolate }} ]])\n {{??}}\n && (m = m{{= pathNode.property }})\n {{?}} {{~}};\n};\n", - set: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n\n\n/**\n * Template that synthesizes setter for Model and for ModelPath\n */\nmethod = function set(value) {\n {{# def.initVars:'set' }}\n\n {{# def.createTree:'set' }}\n\n {{\n currNode = nextNode;\n currProp = currNode && currNode.property;\n }}\n\n {{ /* assign value to the last property */ }}\n {{? currProp }}\n wasDef = {{# def.wasDefined}};\n {{# def.changeAccessPath }}\n\n var old = m{{# def.currProp }};\n\n {{ /* clone value to prevent same reference in linked models */ }}\n m{{# def.currProp }} = cloneTree(value);\n {{?}}\n\n {{ /* add message related to the last property change */ }}\n if (this._options.reactive !== false) {\n if (! wasDef)\n {{# def.addMsg }} accessPath, type: 'added',\n newValue: value });\n else if (old != value)\n {{# def.addMsg }} accessPath, type: 'changed',\n oldValue: old, newValue: value });\n\n {{ /* add message related to changes in (sub)properties inside removed and assigned value */ }}\n if (! wasDef || old != value)\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, value); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n", - del: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_traverse_tree }}\n\nmethod = function del() {\n {{# def.initVars:'del' }}\n\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n if (! treeDoesNotExist && m && m.hasOwnProperty && {{# def.wasDefined}}) {\n var old = m{{# def.currProp }};\n delete m{{# def.currProp }};\n {{# def.changeAccessPath }}\n var didDelete = true;\n }\n {{??}}\n if (typeof m != 'undefined') {\n var old = m;\n {{# def.modelAccessPrefix }} = undefined;\n var didDelete = true;\n }\n {{?}}\n\n if (didDelete && this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'deleted', oldValue: old });\n\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, undefined); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n", - splice: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n{{# def.include_traverse_tree }}\n\nmethod = function splice(spliceIndex, spliceHowMany) { /* ,... - extra arguments to splice into array */\n {{# def.initVars:'splice' }}\n\n var argsLen = arguments.length;\n var addItems = argsLen > 2;\n\n if (addItems) {\n {{ /* only create model tree if items are inserted in array */ }}\n\n {{ /* if model is undefined it will be set to an empty array */ }} \n var value = [];\n {{# def.createTree:'splice' }}\n\n {{? nextNode }}\n {{\n var currNode = nextNode;\n var currProp = currNode.property;\n var emptyProp = '[]';\n }}\n\n {{# def.createTreeStep }}\n {{?}}\n\n } else if (spliceHowMany > 0) {\n {{ /* if items are not inserted, only traverse model tree if items are deleted from array */ }}\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n {{ /* extra brace closes 'else' in def.traverseTreeStep */ }}\n {{# def.traverseTreeStep }} }\n {{?}}\n }\n\n {{ /* splice items */ }}\n if (addItems || (! treeDoesNotExist && m\n && m.length > spliceIndex ) ) {\n var oldLength = m.length = m.length || 0;\n\n arguments[0] = spliceIndex = normalizeSpliceIndex(spliceIndex, m.length);\n\n {{ /* clone added arguments to prevent same references in linked models */ }}\n if (addItems)\n for (var i = 2; i < argsLen; i++)\n arguments[i] = cloneTree(arguments[i]);\n\n {{ /* actual splice call */ }}\n var removed = Array.prototype.splice.apply(m, arguments);\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'splice',\n index: spliceIndex, removed: removed, addedCount: addItems ? argsLen - 2 : 0,\n newValue: m });\n\n if (removed && removed.length)\n removed.forEach(function(item, index) {\n var itemPath = accessPath + '[' + (spliceIndex + index) + ']';\n {{# def.addMsg }} itemPath, type: 'removed', oldValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'removed', 'oldValue');\n });\n\n if (addItems)\n for (var i = 2; i < argsLen; i++) {\n var item = arguments[i];\n var itemPath = accessPath + '[' + (spliceIndex + i - 2) + ']';\n {{# def.addMsg }} itemPath, type: 'added', newValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'added', 'newValue');\n }\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n }\n\n return removed || [];\n}\n" -}; +// event dispatcher - as defined by Event DOM API +function handleEvent(event) { + var isCapturePhase; + if (typeof window != 'undefined') + isCapturePhase = event.eventPhase == window.Event.CAPTURING_PHASE; -var include_defines = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts initialization code\n */\n {{## def.initVars:method:\n var m = {{# def.modelAccessPrefix }};\n var messages = [], messagesHash = {};\n var accessPath = '';\n var treeDoesNotExist;\n /* hack to prevent sending finished events to allow for propagation of batches without splitting them */\n var inChangeTransaction = getTransactionFlag( {{= method }} );\n #}}\n\n/**\n * Inserts the beginning of function call to add message to list\n */\n{{## def.addMsg: addChangeMessage(messages, messagesHash, { path: #}}\n\n/**\n * Inserts current property/index for both normal and interpolated properties/indexes\n */\n{{## def.currProp:{{? currNode.interpolate }}[this._args[ {{= currNode.interpolate }} ]]{{??}}{{= currProp }}{{?}} #}}\n\n/**\n * Inserts condition to test whether normal/interpolated property/index exists\n */\n{{## def.wasDefined: m.hasOwnProperty(\n {{? currNode.interpolate }}\n this._args[ {{= currNode.interpolate }} ]\n {{??}}\n '{{= it.getPathNodeKey(currNode) }}'\n {{?}}\n) #}}\n\n\n/**\n * Inserts code to update access path for current property\n * Because of the possibility of interpolated properties, it can't be calculated in template, it can only be calculated during accessor call.\n */\n{{## def.changeAccessPath:\n accessPath += {{? currNode.interpolate }}\n {{? currNode.syntax == 'array' }}\n '[' + this._args[ {{= currNode.interpolate }} ] + ']';\n {{??}}\n '.' + this._args[ {{= currNode.interpolate }} ];\n {{?}}\n {{??}}\n '{{= currProp }}';\n {{?}}\n#}}\n\n\n/**\n * Inserts code to post stored messages\n */\n{{## def.postMessages:\n if (messages.length) {\n {{# def.modelPostBatchCode }}('datachanges', {\n changes: messages,\n transaction: inChangeTransaction\n });\n\n messages.forEach(function(msg) {\n {{# def.modelPostMessageCode }}(msg.path, msg);\n }, this);\n }\n#}}\n" - , include_create_tree = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to create model tree as neccessary for `set` and `splice` accessors and to add messages to send list if the tree changes.\n */\n{{## def.createTree:method:\n var wasDef = true;\n var old = m;\n\n {{ var emptyProp = it.parsedPath[0] && it.parsedPath[0].empty; }}\n {{? emptyProp }}\n {{ /* create top level model if it was not previously defined */ }}\n if (! m) {\n m = {{# def.modelAccessPrefix }} = {{= emptyProp }};\n wasDef = false;\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} '', type: 'added',\n newValue: m });\n }\n }\n {{??}}\n {{? method == 'splice' }}\n if (! m) {\n {{?}}\n m = {{# def.modelAccessPrefix }} = cloneTree(value);\n wasDef = typeof old != 'undefined';\n {{? method == 'splice' }}\n }\n {{?}} \n {{?}}\n\n\n {{ /* create model tree if it doesn't exist */ }}\n {{ var modelDataProperty = '';\n var nextNode = it.parsedPath[0];\n var count = it.parsedPath.length - 1;\n\n for (var i = 0; i < count; i++) {\n var currNode = nextNode;\n var currProp = currNode.property;\n nextNode = it.parsedPath[i + 1];\n var emptyProp = nextNode && nextNode.empty;\n }}\n\n {{# def.createTreeStep }}\n\n {{ } /* for loop */ }}\n#}}\n\n\n/**\n * Inserts code to create one step in the model tree\n */\n{{## def.createTreeStep:\n {{# def.changeAccessPath }}\n\n if (! {{# def.wasDefined }}) { \n {{ /* property does not exist */ }}\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'added', \n newValue: m });\n }\n\n } else if (typeof m{{# def.currProp }} != 'object') {\n {{ /* property is not object */ }}\n var old = m{{# def.currProp }};\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'changed', \n oldValue: old, newValue: m });\n }\n\n } else {\n {{ /* property exists, just traverse down the model tree */ }}\n m = m{{# def.currProp }};\n }\n#}}\n" - , include_traverse_tree = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to traverse model tree for `delete` and `splice` accessors.\n */\n{{## def.traverseTree:\n {{ \n var count = it.parsedPath.length-1;\n\n for (var i = 0; i < count; i++) { \n var currNode = it.parsedPath[i];\n var currProp = currNode.property;\n }}\n {{# def.traverseTreeStep }}\n\n {{ } /* for loop */\n\n var i = count;\n while (i--) { /* closing braces for else's above */\n }}\n }\n {{ } /* while loop */ }}\n#}}\n\n\n/**\n * Inserts code to traverse one step in the model tree\n */\n{{## def.traverseTreeStep:\n if (! (m && m.hasOwnProperty && {{# def.wasDefined}} ) )\n treeDoesNotExist = true;\n else {\n m = m{{# def.currProp }};\n {{# def.changeAccessPath }}\n {{ /* brace from else is not closed on purpose - all braces are closed in while loop */ }}\n#}}\n"; + if (isCapturePhase) + event += useCapturePostfix; -var dotDef = { - include_defines: include_defines, - include_create_tree: include_create_tree, - include_traverse_tree: include_traverse_tree, - getPathNodeKey: pathUtils.getPathNodeKey, - modelAccessPrefix: 'this._model._data', - modelPostMessageCode: 'this._model._internalMessenger.postMessage', - modelPostBatchCode: 'this._model.postMessageSync', - internalMessenger: 'this._model._internalMessenger' -}; + this.dispatchMessage(event.type, event); +} -var modelDotDef = _(dotDef).clone().extend({ - modelAccessPrefix: 'this._data', - modelPostMessageCode: 'this._internalMessenger.postMessage', - modelPostBatchCode: 'this.postMessageSync', - internalMessenger: 'this._internalMessenger' -})._(); +function DOMEmitterSource$postMessage(message, data) { + this.messenger.postMessageSync(message, data); +} -var dotSettings = _.clone(doT.templateSettings); -dotSettings.strip = false; -var synthesizers = _.mapKeys(templates, function(tmpl) { - return doT.template(tmpl, dotSettings, dotDef); -}); +function trigger(eventType, properties) { + check(eventType, String); + check(properties, Match.Optional(Object)); + eventType = eventType.replace(useCapturePattern, ''); + var EventConstructor = domEventsConstructors[eventType]; -var modelSynthesizers = _.mapToObject(['set', 'del', 'splice'], function(methodName) { - return doT.template(templates[methodName], dotSettings, modelDotDef); -}); - + if (typeof EventConstructor != 'function') + throw new Error('unsupported event type'); -/** - * Function that synthesizes accessor methods. - * Function is memoized so accessors are cached (up to 1000). - * - * @param {String} path Model/ModelPath access path - * @param {Array} parsedPath array of path nodes - * @return {Object[Function]} - */ -var synthesizePathMethods = _.memoize(_synthesizePathMethods, undefined, 1000); + // check if it is correct + if (typeof properties != 'undefined') + properties.type = eventType; -function _synthesizePathMethods(path, parsedPath) { - var methods = _.mapKeys(synthesizers, function(synthszr) { - return _synthesize(synthszr, path, parsedPath); - }); - return methods; + var domEvent = new EventConstructor(eventType, properties); + var notCancelled = this.emitter().dispatchEvent(domEvent); + return notCancelled; } +},{"../components/c_class":16,"../messenger/m_source":70,"../util/check":90,"./de_constrs":82,"mol-proto":150}],84:[function(require,module,exports){ +'use strict'; -var normalizeSpliceIndex = modelUtils.normalizeSpliceIndex; // used in splice.dot.js - +/** + * `milo.mail` + * It is an application level messenger that is an instance of Messenger class. + * + * At the moment, in addition to application messages that you define, you can subscribe to __domready__ message that is guaranteed to fire once, + * even if DOM was ready at the time of the subscription. + * + * Messaging between frames is available via milo.mail. See [Frame facet](../components/c_facets/Frame.js.html). + * + * See [Messenger](../messenger/index.js.html). + * +**/ -function _synthesize(synthesizer, path, parsedPath) { - var method - , methodCode = synthesizer({ - parsedPath: parsedPath, - getPathNodeKey: pathUtils.getPathNodeKey - }); - try { - eval(methodCode); - } catch (e) { - throw ModelError('ModelPath method compilation error; path: ' + path + ', code: ' + methodCode); - } +var Messenger = require('../../messenger') + , MailMsgAPI = require('./mail_api') + , MailMessageSource = require('./mail_source') + , _ = require('mol-proto'); - return method; +var miloMail = new Messenger; - // functions used by methods `set`, `delete` and `splice` (synthesized by template) - function addChangeMessage(messages, messagesHash, msg) { - messages.push(msg); - messagesHash[msg.path] = msg; - } +var mailMsgSource = new MailMessageSource(miloMail, { trigger: 'trigger' }, new MailMsgAPI); - function addTreeChangesMessages(messages, messagesHash, rootPath, oldValue, newValue) { - var oldIsTree = valueIsTree(oldValue) - , newIsTree = valueIsTree(newValue); +miloMail._setMessageSource(mailMsgSource); - if (newIsTree) - addMessages(messages, messagesHash, rootPath, newValue, 'added', 'newValue'); - - if (oldIsTree) - addMessages(messages, messagesHash, rootPath, oldValue, 'removed', 'oldValue'); - } - function addMessages(messages, messagesHash, rootPath, obj, msgType, valueProp) { - _addMessages(rootPath, obj); +module.exports = miloMail; +},{"../../messenger":67,"./mail_api":85,"./mail_source":86,"mol-proto":150}],85:[function(require,module,exports){ +'use strict'; - function _addMessages(rootPath, obj) { - if (Array.isArray(obj)) { - var pathSyntax = rootPath + '[$$]'; - obj.forEach(function(value, index) { - addMessage(value, index, pathSyntax); - }); - } else { - var pathSyntax = rootPath + '.$$'; - _.eachKey(obj, function(value, key) { - addMessage(value, key, pathSyntax); - }); - } - } +var MessengerAPI = require('../../messenger/m_api') + , _ = require('mol-proto') + , check = require('../../util/check') + , Match = check.Match; - function addMessage(value, key, pathSyntax) { - var path = pathSyntax.replace('$$', key) - , existingMsg = messagesHash[path]; - if (existingMsg) { - if (existingMsg.type == msgType) - logger.error('setter error: same message type posted on the same path'); - else { - existingMsg.type = 'changed'; - existingMsg[valueProp] = value; - } - } else { - var msg = { path: path, type: msgType }; - msg[valueProp] = value; - addChangeMessage(messages, messagesHash, msg); - } +var MailMsgAPI = _.createSubclass(MessengerAPI, 'MailMsgAPI', true); - if (valueIsTree(value)) - _addMessages(path, value); - } - } - function cloneTree(value) { - return valueIsNormalObject(value) - ? _.deepClone(value) - : value; - } +_.extendProto(MailMsgAPI, { + translateToSourceMessage: translateToSourceMessage, + filterSourceMessage: filterSourceMessage +}); - function protectValue(value) { - return ! valueIsNormalObject(value) - ? value - : Array.isArray(value) - ? value.slice() - : Object.create(value); - } +module.exports = MailMsgAPI; - function valueIsTree(value) { - return valueIsNormalObject(value) - && Object.keys(value).length; - } - function valueIsNormalObject(value) { - return value != null - && typeof value == "object" - && ! (value instanceof Date) - && ! (value instanceof RegExp); - } +// TODO: this function should return relevant DOM event dependent on element tag +// Can also implement beforedatachanged event to allow preventing the change +// translateToDomEvent +var windowMessageRegExp = /^message\:/ + , windowMessagePrefix = 'message:'; - function addBatchIdsToMessage(msg, batchId, msgId) { - _.defineProperties(msg, { - __batch_id: batchId, - __msg_id: msgId - }); - } +function translateToSourceMessage(message) { + if (message == 'domready') + return 'readystatechange'; + else if (windowMessageRegExp.test(message)) + return 'message'; } -/** - * Exports `synthesize` function with the following: - * - * - .modelMethods.set - `set` method for Model - * - .modelMethods.del - `del` method for Model - * - .modelMethods.splice - `splice` method for Model - */ -module.exports = synthesizePathMethods; - -var modelMethods = _.mapKeys(modelSynthesizers, function(synthesizer) { - return _synthesize(synthesizer, '', []); -}); - -synthesizePathMethods.modelMethods = modelMethods; +// filterDataMessage +function filterSourceMessage(sourceMessage, msgType, msgData) { + if (sourceMessage == 'readystatechange') { + //return document.readyState == 'interactive'; + // return false; + // _.defineProperty(this, '_domReadyFired', true, _.WRIT); + return true; + } else if (sourceMessage == 'message') + return windowMessagePrefix + msgData.data.type == msgType; +}; -},{"../../util/count":94,"../../util/logger":104,"../change_data":74,"../model_utils":79,"../path_utils":81,"dot":116,"fs":114,"mol-proto":117}],83:[function(require,module,exports){ +},{"../../messenger/m_api":68,"../../util/check":90,"mol-proto":150}],86:[function(require,module,exports){ 'use strict'; -/** - * Registries of facets and of components - * - * - [facets](./components/c_facets/cf_registry.js.html) - * - [components](./components/c_registry.js.html) - */ -var registry = module.exports = { - facets: require('./components/c_facets/cf_registry'), - components: require('./components/c_registry'), - commands: require('./command/cmd_registry') -}; +var MessageSource = require('../../messenger/m_source') + , domEventsConstructors = require('../de_constrs') + , MailMessageSourceError = require('../../util/error').MailMessageSource + , _ = require('mol-proto') + , check = require('../../util/check') + , Match = check.Match; -},{"./command/cmd_registry":12,"./components/c_facets/cf_registry":31,"./components/c_registry":33}],84:[function(require,module,exports){ -'use strict'; -// -// ###dom events constructors +var MailMessageSource = _.createSubclass(MessageSource, 'MailMessageSource', true); -var _ = require('mol-proto'); +_.extendProto(MailMessageSource, { + // implementing MessageSource interface + addSourceSubscriber: addSourceSubscriber, + removeSourceSubscriber: removeSourceSubscriber, + trigger: trigger, + // class specific methods + _windowSubscriberMethod: _windowSubscriberMethod, + handleEvent: handleEvent, // event dispatcher - as defined by Event DOM API +}); -// https://developer.mozilla.org/en-US/docs/Web/Reference/Events -var eventTypes = { - ClipboardEvent: ['copy', 'cut', 'paste', 'beforecopy', 'beforecut', 'beforepaste'], - Event: ['input', 'readystatechange'], - FocusEvent: ['focus', 'blur', 'focusin', 'focusout'], - KeyboardEvent: ['keydown', 'keypress', 'keyup'], - MouseEvent: ['click', 'contextmenu', 'dblclick', 'mousedown', 'mouseup', - 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', - 'show' /* context menu */], - TouchEvent: ['touchstart', 'touchend', 'touchmove', 'touchenter', 'touchleave', 'touchcancel'], -}; +module.exports = MailMessageSource; -// mock window and event constructors for testing -if (typeof window != 'undefined') - var global = window; -else { - global = {}; - _.eachKey(eventTypes, function(eTypes, eventConstructorName) { - var eventConstructor = _.makeFunction(eventConstructorName, 'type', 'properties', - 'this.type = type; _.extend(this, properties);'); - global[eventConstructorName] = eventConstructor; - }); +function addSourceSubscriber(sourceMessage) { + if (isReadyStateChange(sourceMessage)) { + if (document.readyState == 'loading') + document.addEventListener('readystatechange', this, false); + else { + var EventConstructor = domEventsConstructors.readystatechange; + var domEvent = new EventConstructor('readystatechange', { target: document }); + this.dispatchMessage('readystatechange', domEvent); + } + } else + this._windowSubscriberMethod('addEventListener', sourceMessage); } -var domEventsConstructors = {}; - -_.eachKey(eventTypes, function(eTypes, eventConstructorName) { - eTypes.forEach(function(type) { - if (Object.hasOwnProperty(domEventsConstructors, type)) - throw new Error('duplicate event type ' + type); - - domEventsConstructors[type] = global[eventConstructorName]; - }); -}); - - -module.exports = domEventsConstructors; - -},{"mol-proto":117}],85:[function(require,module,exports){ -'use strict'; - - -var MessageSource = require('../messenger/m_source') - , Component = require('../components/c_class') - , domEventsConstructors = require('./de_constrs') // TODO merge with DOMEventSource ?? - , _ = require('mol-proto') - , check = require('../util/check') - , Match = check.Match; - -var DOMEmitterSource = _.createSubclass(MessageSource, 'DOMEmitterSource', true); - - -_.extendProto(DOMEmitterSource, { - // implementing MessageSource interface - init: init, - destroy: DOMEmitterSource$destroy, - addSourceSubscriber: _.partial(sourceSubscriberMethod, 'addEventListener'), - removeSourceSubscriber: _.partial(sourceSubscriberMethod, 'removeEventListener'), - postMessage: DOMEmitterSource$postMessage, - trigger: trigger, - - // class specific methods - emitter: emitter, - handleEvent: handleEvent, // event dispatcher - as defined by Event DOM API -}); - -module.exports = DOMEmitterSource; - - -var useCapturePattern = /__capture$/ - , useCapturePostfix = '__capture'; - - -// init DOM event source -function init(hostObject, proxyMethods, messengerAPIOrClass, eventEmitter) { - this.eventEmitter = eventEmitter; - MessageSource.prototype.init.apply(this, arguments); -} - - -function DOMEmitterSource$destroy() { - MessageSource.prototype.destroy.apply(this, arguments); - delete this.eventEmitter; -} - - -// get DOM element of component -function emitter() { - return this.eventEmitter; -} - - -function sourceSubscriberMethod(method, eventType) { - if (! (eventType && typeof eventType == 'string')) return; - var capture = useCapturePattern.test(eventType); - eventType = eventType.replace(useCapturePattern, ''); - this.emitter()[method](eventType, this, capture); -} - - -// event dispatcher - as defined by Event DOM API -function handleEvent(event) { - var isCapturePhase; - if (typeof window != 'undefined') - isCapturePhase = event.eventPhase == window.Event.CAPTURING_PHASE; - - if (isCapturePhase) - event += useCapturePostfix; - - this.dispatchMessage(event.type, event); -} - - -function DOMEmitterSource$postMessage(message, data) { - this.messenger.postMessageSync(message, data); -} - - -function trigger(eventType, properties) { - check(eventType, String); - check(properties, Match.Optional(Object)); - - eventType = eventType.replace(useCapturePattern, ''); - var EventConstructor = domEventsConstructors[eventType]; - - if (typeof EventConstructor != 'function') - throw new Error('unsupported event type'); - - // check if it is correct - if (typeof properties != 'undefined') - properties.type = eventType; - - var domEvent = new EventConstructor(eventType, properties); - var notCancelled = this.emitter().dispatchEvent(domEvent); - return notCancelled; -} - -},{"../components/c_class":16,"../messenger/m_source":70,"../util/check":92,"./de_constrs":84,"mol-proto":117}],86:[function(require,module,exports){ -'use strict'; - -/** - * `milo.mail` - * It is an application level messenger that is an instance of Messenger class. - * - * At the moment, in addition to application messages that you define, you can subscribe to __domready__ message that is guaranteed to fire once, - * even if DOM was ready at the time of the subscription. - * - * Messaging between frames is available via milo.mail. See [Frame facet](../components/c_facets/Frame.js.html). - * - * See [Messenger](../messenger/index.js.html). - * -**/ - - -var Messenger = require('../../messenger') - , MailMsgAPI = require('./mail_api') - , MailMessageSource = require('./mail_source') - , _ = require('mol-proto'); - - -var miloMail = new Messenger; - -var mailMsgSource = new MailMessageSource(miloMail, { trigger: 'trigger' }, new MailMsgAPI); - -miloMail._setMessageSource(mailMsgSource); - - -module.exports = miloMail; - -},{"../../messenger":67,"./mail_api":87,"./mail_source":88,"mol-proto":117}],87:[function(require,module,exports){ -'use strict'; - -var MessengerAPI = require('../../messenger/m_api') - , _ = require('mol-proto') - , check = require('../../util/check') - , Match = check.Match; - - -var MailMsgAPI = _.createSubclass(MessengerAPI, 'MailMsgAPI', true); - - -_.extendProto(MailMsgAPI, { - translateToSourceMessage: translateToSourceMessage, - filterSourceMessage: filterSourceMessage -}); - -module.exports = MailMsgAPI; - - -// TODO: this function should return relevant DOM event dependent on element tag -// Can also implement beforedatachanged event to allow preventing the change -// translateToDomEvent -var windowMessageRegExp = /^message\:/ - , windowMessagePrefix = 'message:'; - -function translateToSourceMessage(message) { - if (message == 'domready') - return 'readystatechange'; - else if (windowMessageRegExp.test(message)) - return 'message'; -} - - -// filterDataMessage -function filterSourceMessage(sourceMessage, msgType, msgData) { - if (sourceMessage == 'readystatechange') { - //return document.readyState == 'interactive'; - // return false; - // _.defineProperty(this, '_domReadyFired', true, _.WRIT); - return true; - } else if (sourceMessage == 'message') - return windowMessagePrefix + msgData.data.type == msgType; -}; - -},{"../../messenger/m_api":68,"../../util/check":92,"mol-proto":117}],88:[function(require,module,exports){ -'use strict'; - -var MessageSource = require('../../messenger/m_source') - , domEventsConstructors = require('../de_constrs') - , MailMessageSourceError = require('../../util/error').MailMessageSource - , _ = require('mol-proto') - , check = require('../../util/check') - , Match = check.Match; - - -var MailMessageSource = _.createSubclass(MessageSource, 'MailMessageSource', true); - - -_.extendProto(MailMessageSource, { - // implementing MessageSource interface - addSourceSubscriber: addSourceSubscriber, - removeSourceSubscriber: removeSourceSubscriber, - trigger: trigger, - - // class specific methods - _windowSubscriberMethod: _windowSubscriberMethod, - handleEvent: handleEvent, // event dispatcher - as defined by Event DOM API -}); - - -module.exports = MailMessageSource; - - -function addSourceSubscriber(sourceMessage) { - if (isReadyStateChange(sourceMessage)) { - if (document.readyState == 'loading') - document.addEventListener('readystatechange', this, false); - else { - var EventConstructor = domEventsConstructors.readystatechange; - var domEvent = new EventConstructor('readystatechange', { target: document }); - this.dispatchMessage('readystatechange', domEvent); - } - } else - this._windowSubscriberMethod('addEventListener', sourceMessage); -} - - -function removeSourceSubscriber(sourceMessage) { - if (isReadyStateChange(sourceMessage)) - document.removeEventListener('readystatechange', this, false); - else - this._windowSubscriberMethod('removeEventListener', sourceMessage); -} +function removeSourceSubscriber(sourceMessage) { + if (isReadyStateChange(sourceMessage)) + document.removeEventListener('readystatechange', this, false); + else + this._windowSubscriberMethod('removeEventListener', sourceMessage); +} function isReadyStateChange(sourceMessage) { @@ -12867,7 +12234,7 @@ function trigger(msgType, data) { window.postMessage(data, '*') } -},{"../../messenger/m_source":70,"../../util/check":92,"../../util/error":100,"../de_constrs":84,"mol-proto":117}],89:[function(require,module,exports){ +},{"../../messenger/m_source":70,"../../util/check":90,"../../util/error":98,"../de_constrs":82,"mol-proto":150}],87:[function(require,module,exports){ 'use strict'; @@ -12892,7 +12259,7 @@ function windowService_isTop() { return window.top == window.self || window.__karma__; } -},{"../messenger":67,"./dom_source":85}],90:[function(require,module,exports){ +},{"../messenger":67,"./dom_source":83}],88:[function(require,module,exports){ 'use strict'; require('./components/classes/View'); @@ -12920,7 +12287,7 @@ require('./components/ui/FoldTree'); require('./components/ui/bootstrap/Dropdown'); // require('./components/ui/bootstrap/Dialog'); -},{"./components/classes/View":35,"./components/ui/Button":42,"./components/ui/Combo":43,"./components/ui/ComboList":44,"./components/ui/Date":45,"./components/ui/DropTarget":46,"./components/ui/FoldTree":47,"./components/ui/Group":48,"./components/ui/Hyperlink":49,"./components/ui/Image":50,"./components/ui/Input":51,"./components/ui/InputList":52,"./components/ui/List":53,"./components/ui/ListItem":54,"./components/ui/RadioGroup":55,"./components/ui/Select":56,"./components/ui/SuperCombo":57,"./components/ui/Text":58,"./components/ui/Textarea":59,"./components/ui/Time":60,"./components/ui/Wrapper":61,"./components/ui/bootstrap/Dropdown":64}],91:[function(require,module,exports){ +},{"./components/classes/View":35,"./components/ui/Button":42,"./components/ui/Combo":43,"./components/ui/ComboList":44,"./components/ui/Date":45,"./components/ui/DropTarget":46,"./components/ui/FoldTree":47,"./components/ui/Group":48,"./components/ui/Hyperlink":49,"./components/ui/Image":50,"./components/ui/Input":51,"./components/ui/InputList":52,"./components/ui/List":53,"./components/ui/ListItem":54,"./components/ui/RadioGroup":55,"./components/ui/Select":56,"./components/ui/SuperCombo":57,"./components/ui/Text":58,"./components/ui/Textarea":59,"./components/ui/Time":60,"./components/ui/Wrapper":61,"./components/ui/bootstrap/Dropdown":64}],89:[function(require,module,exports){ 'use strict'; require('./components/c_facets/Dom'); @@ -12937,7 +12304,7 @@ require('./components/c_facets/List'); require('./components/c_facets/Item'); require('./components/c_facets/Transfer'); -},{"./components/c_facets/Container":18,"./components/c_facets/Data":19,"./components/c_facets/Dom":20,"./components/c_facets/Drag":21,"./components/c_facets/Drop":22,"./components/c_facets/Events":23,"./components/c_facets/Frame":24,"./components/c_facets/Item":25,"./components/c_facets/List":26,"./components/c_facets/ModelFacet":27,"./components/c_facets/Options":28,"./components/c_facets/Template":29,"./components/c_facets/Transfer":30}],92:[function(require,module,exports){ +},{"./components/c_facets/Container":18,"./components/c_facets/Data":19,"./components/c_facets/Dom":20,"./components/c_facets/Drag":21,"./components/c_facets/Drop":22,"./components/c_facets/Events":23,"./components/c_facets/Frame":24,"./components/c_facets/Item":25,"./components/c_facets/List":26,"./components/c_facets/ModelFacet":27,"./components/c_facets/Options":28,"./components/c_facets/Template":29,"./components/c_facets/Transfer":30}],90:[function(require,module,exports){ 'use strict'; /** @@ -13313,7 +12680,7 @@ function _prependPath(key, base) { return key + base; }; -},{"../config":65,"mol-proto":117}],93:[function(require,module,exports){ +},{"../config":65,"mol-proto":150}],91:[function(require,module,exports){ 'use strict'; var count = require('./count') @@ -13328,7 +12695,7 @@ function componentName() { return prefix + count(); } -},{"../config":65,"./count":94}],94:[function(require,module,exports){ +},{"../config":65,"./count":92}],92:[function(require,module,exports){ 'use strict'; var timestamp = Date.now() @@ -13355,7 +12722,7 @@ uniqueCount.get = function() { module.exports = uniqueCount; -},{}],95:[function(require,module,exports){ +},{}],93:[function(require,module,exports){ 'use strict'; module.exports = createComponentClass; @@ -13391,7 +12758,7 @@ function createComponentClass(config) { return ComponentClass; } -},{}],96:[function(require,module,exports){ +},{}],94:[function(require,module,exports){ 'use strict'; @@ -14073,7 +13440,7 @@ function addDebugPoint(x, y) { setTimeout(function() {document.body.appendChild(dbEl);}, 200); } -},{"../config":65,"./logger":104,"mol-proto":117}],97:[function(require,module,exports){ +},{"../config":65,"./logger":102,"mol-proto":150}],95:[function(require,module,exports){ 'use strict'; @@ -14131,7 +13498,7 @@ function _removeListener(l) { l.target.removeEventListener(l.eventType, l.handler); } -},{"./check":92,"mol-proto":117}],98:[function(require,module,exports){ +},{"./check":90,"mol-proto":150}],96:[function(require,module,exports){ 'use strict'; @@ -14180,7 +13547,7 @@ function isReady() { return readyState == 'loading' ? false : readyState; } -},{"mol-proto":117}],99:[function(require,module,exports){ +},{"mol-proto":150}],97:[function(require,module,exports){ 'use strict'; var Component = require('../components/c_class') @@ -14445,7 +13812,7 @@ function DragDrop_destroy() { dragDropService.offAll(); } -},{"../components/c_class":16,"../config":65,"../messenger":67,"./json_parse":103,"base32":113,"mol-proto":117}],100:[function(require,module,exports){ +},{"../components/c_class":16,"../config":65,"../messenger":67,"./json_parse":101,"base32":112,"mol-proto":150}],98:[function(require,module,exports){ // // milo.utils.error // ----------- @@ -14488,7 +13855,7 @@ function error$toBeImplemented() { throw new error.AbstractClass('calling the method of an absctract class'); } -},{"mol-proto":117}],101:[function(require,module,exports){ +},{"mol-proto":150}],99:[function(require,module,exports){ 'use strict'; @@ -14692,7 +14059,7 @@ function _createNodesAndPathsFunc(func) { -},{"../attributes/a_bind":5,"../binder":9,"../components/c_class":16,"./check":92,"./dom":96,"./logger":104,"mol-proto":117}],102:[function(require,module,exports){ +},{"../attributes/a_bind":5,"../binder":9,"../components/c_class":16,"./check":90,"./dom":94,"./logger":102,"mol-proto":150}],100:[function(require,module,exports){ 'use strict'; /** @@ -14729,7 +14096,7 @@ function util_destroy() { util.dragDrop.destroy(); } -},{"../components/ui/bootstrap/Alert":62,"../components/ui/bootstrap/Dialog":63,"./check":92,"./component_name":93,"./count":94,"./dom":96,"./dom_listeners":97,"./domready":98,"./dragdrop":99,"./error":100,"./fragment":101,"./json_parse":103,"./logger":104,"./request":106,"./selection":107,"./storage":108,"./websocket":110,"dot":116}],103:[function(require,module,exports){ +},{"../components/ui/bootstrap/Alert":62,"../components/ui/bootstrap/Dialog":63,"./check":90,"./component_name":91,"./count":92,"./dom":94,"./dom_listeners":95,"./domready":96,"./dragdrop":97,"./error":98,"./fragment":99,"./json_parse":101,"./logger":102,"./request":104,"./selection":105,"./storage":106,"./websocket":109,"dot":115}],101:[function(require,module,exports){ 'use strict'; @@ -14749,7 +14116,7 @@ function jsonParse(str) { } catch (e) {} } -},{}],104:[function(require,module,exports){ +},{}],102:[function(require,module,exports){ 'use strict'; // @@ -14779,7 +14146,7 @@ var logger = new Logger({ level: 3 }); module.exports = logger; -},{"./logger_class":105}],105:[function(require,module,exports){ +},{"./logger_class":103}],103:[function(require,module,exports){ 'use strict'; // ### Logger Class @@ -14904,7 +14271,7 @@ levels.forEach(function (name) { module.exports = Logger; -},{"mol-proto":117}],106:[function(require,module,exports){ +},{"mol-proto":150}],104:[function(require,module,exports){ 'use strict'; // milo.utils.request @@ -15226,7 +14593,7 @@ function whenRequestsCompleted(callback, timeout) { _.defer(callback); } -},{"../config":65,"../messenger":67,"./count":94,"./logger":104,"mol-proto":117}],107:[function(require,module,exports){ +},{"../config":65,"../messenger":67,"./count":92,"./logger":102,"mol-proto":150}],105:[function(require,module,exports){ 'use strict'; @@ -15667,7 +15034,7 @@ function TextSelection$$getDirection(){ } -},{"../../components/c_class":16,"../dom":96,"../logger":104,"mol-proto":117}],108:[function(require,module,exports){ +},{"../../components/c_class":16,"../dom":94,"../logger":102,"mol-proto":150}],106:[function(require,module,exports){ 'use strict'; @@ -15680,6 +15047,7 @@ var DOMStorageError = require('../error').createClass('DomStorageError') , check = require('../check') , Match = check.Match; +require('./model') module.exports = DOMStorage; @@ -16082,7 +15450,33 @@ function DOMStorage$destroy() { this._destroyed = true; } -},{"../../config":65,"../../messenger":67,"../check":92,"../error":100,"../json_parse":103,"./msg_src":109,"mol-proto":117}],109:[function(require,module,exports){ +},{"../../config":65,"../../messenger":67,"../check":90,"../error":98,"../json_parse":101,"./model":107,"./msg_src":108,"mol-proto":150}],107:[function(require,module,exports){ +'use strict'; + +var Model = require('milo-core').Model + +Model.registerWithDOMStorage = Model$$registerWithDOMStorage; + + +function Model$$registerWithDOMStorage() { + var DOMStorage = require('./index'); + DOMStorage.registerDataType('Model', Model_domStorageSerializer, Model_domStorageParser); + DOMStorage.registerDataType('ModelPath', Model_domStorageSerializer, Model_domStorageParser, 'Model'); +} + + +function Model_domStorageSerializer(value) { + var data = value.get(); + return JSON.stringify(data); +} + + +function Model_domStorageParser(valueStr) { + var data = _.jsonParse(valueStr); + return new Model(data); +} + +},{"./index":106,"milo-core":124}],108:[function(require,module,exports){ 'use strict'; @@ -16151,7 +15545,7 @@ function handleEvent(event) { this.dispatchMessage(msgType, data); } -},{"../../config":65,"../../messenger/m_source":70,"../../util/count":94,"../../util/error":100,"mol-proto":117}],110:[function(require,module,exports){ +},{"../../config":65,"../../messenger/m_source":70,"../../util/count":92,"../../util/error":98,"mol-proto":150}],109:[function(require,module,exports){ 'use strict'; /** @@ -16174,7 +15568,7 @@ function websocket() { module.exports = websocket; -},{"../../messenger":67,"./msg_api":111,"./msg_src":112}],111:[function(require,module,exports){ +},{"../../messenger":67,"./msg_api":110,"./msg_src":111}],110:[function(require,module,exports){ 'use strict'; var MessengerAPI = require('../../messenger/m_api') @@ -16220,7 +15614,7 @@ function createInternalData(sourceMessage, message, event) { return internalData; } -},{"../../messenger/m_api":68,"../../util/check":92,"mol-proto":117}],112:[function(require,module,exports){ +},{"../../messenger/m_api":68,"../../util/check":90,"mol-proto":150}],111:[function(require,module,exports){ 'use strict'; @@ -16330,7 +15724,7 @@ function WSMessageSource$trigger (msg, data, callback) { } } -},{"../../config":65,"../../messenger/m_source":70,"../../util/check":92,"../../util/count":94,"../../util/logger":104,"mol-proto":117}],113:[function(require,module,exports){ +},{"../../config":65,"../../messenger/m_source":70,"../../util/check":90,"../../util/count":92,"../../util/logger":102,"mol-proto":150}],112:[function(require,module,exports){ ;(function(){ // This would be the place to edit if you want a different @@ -16527,13 +15921,13 @@ if (typeof module !== 'undefined' && module.exports) { } })(); -},{}],114:[function(require,module,exports){ +},{}],113:[function(require,module,exports){ // not implemented // The reason for having an empty file and not throwing is to allow // untraditional implementation of this module. -},{}],115:[function(require,module,exports){ +},{}],114:[function(require,module,exports){ // doT.js // 2011-2014, Laura Doktorova, https://github.com/olado/doT // Licensed under the MIT license. @@ -16675,7 +16069,7 @@ if (typeof module !== 'undefined' && module.exports) { }; }()); -},{}],116:[function(require,module,exports){ +},{}],115:[function(require,module,exports){ /* doT + auto-compilation of doT templates * * 2012, Laura Doktorova, https://github.com/olado/doT @@ -16820,7 +16214,2616 @@ InstallDots.prototype.compileAll = function() { return this.__rendermodule; }; -},{"./doT":115,"fs":114}],117:[function(require,module,exports){ +},{"./doT":114,"fs":113}],116:[function(require,module,exports){ +'use strict'; + +var _ = require('mol-proto') + , check = require('../util/check') + , Match = check.Match + , config = require('../config'); + + +module.exports = Mixin; + +/** + * `milo.classes.Mixin` - an abstract Mixin class. + * Can be subclassed using: + * ``` + * var MyMixin = _.createSubclass(milo.classes.Mixin, 'MyMixin'); + * ``` + * + * Mixin pattern is also used, but Mixin in milo is implemented as a separate object that is stored on the property of the host object and can create proxy methods on the host object if required. + * Classes [Messenger](../messenger/index.js.html) and [MessageSource](../messenger/m_source.js.html) are subclasses of Mixin abstract class. `this` in proxy methods refers to Mixin instance, the reference to the host object is `this._hostObject`. + * + * @param {Object} hostObject Optional object where a Mixin instance will be stored on. It is used to proxy methods and also to find the reference when it is needed for host object implementation. + * @param {Object} proxyMethods Optional map of proxy method names as keys and Mixin methods names as values, so proxied methods can be renamed to avoid name-space conflicts if two different Mixin instances with the same method names are put on the object + * @param {List} arguments all constructor arguments will be passed to init method of Mixin subclass together with hostObject and proxyMethods + * @return {Mixin} + */ +function Mixin(hostObject, proxyMethods) { // , other args - passed to init method + check(hostObject, Match.Optional(Match.OneOf(Object, Function))); + + // store hostObject + _.defineProperty(this, '_hostObject', hostObject); + + // proxy methods to hostObject + if (proxyMethods) + this._createProxyMethods(proxyMethods); + + // calling init if it is defined in the class + if (this.init) + this.init.apply(this, arguments); +} + + +/** + * ####Mixin instance methods#### + * These methods are called by constructor, they are not to be called from subclasses. + * + * - [_createProxyMethod](#_createProxyMethod) + * - [_createProxyMethods](#_createProxyMethods) + */ +_.extendProto(Mixin, { + _createProxyMethod: _createProxyMethod, // deprecated, should not be used + _createProxyMethods: _createProxyMethods // deprecated, should not be used +}); + + +/** + * ####Mixin class methods#### + * These method should be called in host class declaration. + * + * - [useWith](#Mixin$$useWith) + */ +_.extend(Mixin, { + useWith: Mixin$$useWith +}); + + +/** + * Creates a proxied method of Mixin subclass on host object. + * + * @param {String} mixinMethodName name of method in Mixin subclass + * @param {String} proxyMethodName name of created proxy method on host object + * @param {Object} hostObject Optional reference to the host object; if not specified the host object passed to constructor wil be used. It allows to use the same instance of Mixin on two host objects. + */ +function _createProxyMethod(proxyMethodName, mixinMethodName, hostObject) { + hostObject = hostObject || this._hostObject; + + // Mixin class does not allow shadowing methods that exist on the host object + if (hostObject[proxyMethodName]) + throw new Error('method ' + proxyMethodName + + ' already defined in host object'); + + var method = this[mixinMethodName] + check(method, Function); + + // Bind proxied Mixin's method to Mixin instance + var boundMethod = method.bind(this); + + _.defineProperty(hostObject, proxyMethodName, boundMethod, _.WRIT); +} + + +/** + * Creates proxied methods of Mixin subclass on host object. + * + * @param {Hash[String]|Array[String]} proxyMethods map of names of methods, key - proxy method name, value - mixin method name. Can be array. + * @param {Object} hostObject an optional reference to the host object; if not specified the host object passed to constructor wil be used. It allows to use the same instance of Mixin on two host objects. + */ +function _createProxyMethods(proxyMethods, hostObject) { + check(proxyMethods, Match.Optional(Match.OneOf([String], Match.ObjectHash(String)))); + + // creating and binding proxy methods on the host object + if (Array.isArray(proxyMethods)) + proxyMethods.forEach(function(methodName) { + // method called this way to allow using _createProxyMethods with objects + // that are not inheriting from Mixin + _createProxyMethod.call(this, methodName, methodName, hostObject); + }, this); + else + _.eachKey(proxyMethods, function(mixinMethodName, proxyMethodName) { + // method called this way to allow using _createProxyMethods with objects + // that are not inheriting from Mixin + _createProxyMethod.call(this, proxyMethodName, mixinMethodName, hostObject); + }, this); +} + + +/** + * Sets mixin instance property name on the host class + * Can be called only once + * + * @private + * @param {Function} this Mixin subclass (not instance) + * @param {Function} hostClass + * @param {String} instanceKey + */ +function Mixin_setInstanceKey(hostClass, method, instanceKey) { + check(hostClass, Function); + check(instanceKey, Match.IdentifierString); + + var prop = config.mixin.instancePropertiesMap + , instanceKeys = hostClass[prop] = hostClass[prop] || {}; + + if (instanceKeys[method.name]) + throw new Error('Mixin: instance property for method with name ' + + method.name + ' is already set'); + + instanceKeys[method.name] = instanceKey; +} + + +/** + * Adds method of Mixin subclass to host class prototype. + * + * @private + * @param {Function} this Mixin subclass (not instance) + * @param {String} mixinMethodName name of method in Mixin subclass + * @param {String} hostMethodName (optional) name of created proxy method on host object, same if not specified + * @param {Object} hostObject object class, must be specified as the last parameter (2nd or 3rd) + */ +function Mixin_addMethod(hostClass, instanceKey, mixinMethodName, hostMethodName) { + var method = this.prototype[mixinMethodName]; + check(method, Function); + + var wrappedMethod = _wrapMixinMethod.call(this, method); + + _.defineProperty(hostClass.prototype, hostMethodName, wrappedMethod, _.WRIT); + + Mixin_setInstanceKey(hostClass, method, instanceKey) +} + + +/** + * Returns method that will be exposed on the host class prototype + * + * @private + * @param {Function} this Mixin subclass (not instance) + * @return {Function} + */ +function _wrapMixinMethod(method) { + return function() { // ,... arguments + var mixinInstance = _getMixinInstance.call(this, method.name); + return method.apply(mixinInstance, arguments); + } +} + + +/** + * Returns the reference to the instance of mixin subclass. + * This method is used when methods are exposed on the host class prototype (using addMehtods) rather than on host instance. + * Subclasses should not use this methods - whenever subclass method is exposed on the prototype it will be wrapped to set correct context for the subclass method. + * + * @private + * @return {Object} + */ +function _getMixinInstance(methodName) { + if (this instanceof Mixin) return this; + var instanceKeys = this.constructor[config.mixin.instancePropertiesMap] + return this[instanceKeys[methodName]]; +} + + +/** + * Adds methods of Mixin subclass to host class prototype. + * + * @param {Function} this Mixin subclass (not instance) + * @param {Object} hostClass host object class; must be specified. + * @param {String} instanceKey the name of the property the host class instance will store mixin instance on + * @param {Hash[String]|Array[String]} mixinMethods map of names of methods, key - host method name, value - mixin method name. Can be array. + */ +function Mixin$$useWith(hostClass, instanceKey, mixinMethods) { + check(mixinMethods, Match.Optional(Match.OneOf([String], Match.ObjectHash(String)))); + + if (Array.isArray(mixinMethods)) + mixinMethods.forEach(function(methodName) { + Mixin_addMethod.call(this, hostClass, instanceKey, methodName, methodName); + }, this); + else + _.eachKey(mixinMethods, function(mixinMethodName, hostMethodName) { + Mixin_addMethod.call(this, hostClass, instanceKey, mixinMethodName, hostMethodName); + }, this); +} + +},{"../config":118,"../util/check":135,"mol-proto":141}],117:[function(require,module,exports){ +'use strict'; + +// +// milo.classes +// ----------- + +// This module contains foundation classes + +var classes = { + Mixin: require('./abstract/mixin'), + MessageSource: require('./messenger/m_source'), + MessengerMessageSource: require('./messenger/msngr_source'), + MessengerAPI: require('./messenger/m_api'), + MessengerRegexpAPI: require('./messenger/m_api_rx') +}; + +module.exports = classes; + +},{"./abstract/mixin":116,"./messenger/m_api":120,"./messenger/m_api_rx":121,"./messenger/m_source":122,"./messenger/msngr_source":123}],118:[function(require,module,exports){ +'use strict'; + + +var _ = require('mol-proto'); + + +module.exports = config; + +function config(options) { + _.deepExtend(config, options); +} + +config({ + mixin: { + instancePropertiesMap: '___mixin_instances' + }, + check: true, + debug: false +}); + +},{"mol-proto":141}],119:[function(require,module,exports){ +'use strict'; + +var Mixin = require('../abstract/mixin') + , MessageSource = require('./m_source') + , _ = require('mol-proto') + , check = require('../util/check') + , Match = check.Match; + + +/** + * `milo.Messenger` + * A generic Messenger class that is used for all kinds of messaging in milo. It is subclassed from [Mixin](../abstract/mixin.js.html) and it proxies its methods to the host object for convenience. + * All facets and components have messenger attached to them. Messenger class interoperates with [MessageSource](./m_source.js.html) class that connects the messenger to some external source of messages (e.g., DOM events) and [MessengerAPI](./m_api.js.html) class that allows to define higher level messages than messages that exist on the source. + * Messenger class is used internally in milo and can be used together with any objects/classes in the application. + * milo also defines a global messenger [milo.mail](../mail/index.js.html) that dispatches `domready` event and can be used for any application wide messaging. + * To initialize your app after DOM is ready use: + * ``` + * milo.mail.on('domready', function() { + * // application starts + * }); + * ``` + * or the following shorter form of the same: + * ``` + * milo(function() { + * // application starts + * }); + * ``` + */ +var Messenger = _.createSubclass(Mixin, 'Messenger'); + +var messagesSplitRegExp = Messenger.messagesSplitRegExp = /\s*(?:\,|\s)\s*/; + + +/** + * ####Messenger instance methods#### + * + * - [init](#init) + * - [on](#Messenger$on) (alias - onMessage, deprecated) + * - [off](#Messenger$off) (alias - offMessage, deprecated) + * - [onMessages](#onMessages) + * - [offMessages](#offMessages) + * - [once](#once) + * - [onceSync](#onceSync) + * - [postMessage](#postMessage) + * - [getSubscribers](#getSubscribers) + * + * "Private" methods + * + * - [_chooseSubscribersHash](#_chooseSubscribersHash) + * - [_registerSubscriber](#_registerSubscriber) + * - [_removeSubscriber](#_removeSubscriber) + * - [_removeAllSubscribers](#_removeAllSubscribers) + * - [_callPatternSubscribers](#_callPatternSubscribers) + * - [_callSubscribers](#_callSubscribers) + * - [_setMessageSource](#_setMessageSource) + * - [getMessageSource](#getMessageSource) + */ +_.extendProto(Messenger, { + init: init, // called by Mixin (superclass) + destroy: Messenger$destroy, + on: Messenger$on, + once: Messenger$once, + onceSync: Messenger$onceSync, + onSync: Messenger$onSync, + onAsync: Messenger$onAsync, + onMessage: Messenger$on, // deprecated + off: Messenger$off, + offMessage: Messenger$off, // deprecated + onMessages: onMessages, + offMessages: offMessages, + offAll: Messenger$offAll, + postMessage: postMessage, + postMessageSync: postMessageSync, + getSubscribers: getSubscribers, + getMessageSource: getMessageSource, + _chooseSubscribersHash: _chooseSubscribersHash, + _registerSubscriber: _registerSubscriber, + _removeSubscriber: _removeSubscriber, + _removeAllSubscribers: _removeAllSubscribers, + _callPatternSubscribers: _callPatternSubscribers, + _callSubscribers: _callSubscribers, + _callSubscriber: _callSubscriber, + _setMessageSource: _setMessageSource +}); + + +/** + * A default map of proxy methods used by ComponentFacet and Component classes to pass to Messenger when it is instantiated. + * This map is for convenience only, it is NOT used internally by Messenger, a host class should pass it for methods to be proxied this way. + */ +Messenger.defaultMethods = { + on: 'on', + onSync: 'onSync', + once: 'once', + onceSync: 'onceSync', + off: 'off', + onMessages: 'onMessages', + offMessages: 'offMessages', + postMessage: 'postMessage', + postMessageSync: 'postMessageSync', + getSubscribers: 'getSubscribers' +}; + + +module.exports = Messenger; + + +Messenger.subscriptions = []; + + +/** + * Messenger instance method + * Initializes Messenger. Method is called by Mixin class constructor. + * See [on](#Messenger$on) method, [Messenger](#Messenger) class above and [MessageSource](./m_source.js.html) class. + * + * @param {Object} hostObject Optional object that stores the messenger on one of its properties. It is used to proxy methods of messenger and also as a context for subscribers when they are called by the Messenger. See `on` method. + * @param {Object} proxyMethods Optional map of method names; key - proxy method name, value - messenger's method name. + * @param {MessageSource} messageSource Optional messageSource linked to the messenger. If messageSource is supplied, the reference to the messenger will stored on its 'messenger' property + */ +function init(hostObject, proxyMethods, messageSource) { + // hostObject and proxyMethods are used in Mixin and checked there + if (messageSource) + this._setMessageSource(messageSource); + + _initializeSubscribers.call(this); +} + + +function _initializeSubscribers() { + _.defineProperties(this, { + _messageSubscribers: {}, + _patternMessageSubscribers: {}, + }, _.CONF); +} + + +/** + * Destroys messenger. Maybe needs to unsubscribe all subscribers + */ +function Messenger$destroy() { + this.offAll(); + var messageSource = this.getMessageSource(); + if (messageSource) + messageSource.destroy(); +} + + +/** + * Messenger instance method. + * Registers a subscriber function for a certain message(s). + * This method returns `true` if the subscription was successful. It can be unsuccessful if the passed subscriber has already been subscribed to this message type - double subscription never happens and it is safe to subscribe again - no error or warning is thrown or logged. + * Subscriber is passed two parameters: `message` (string) and `data` (object). Data object is supplied when message is dispatched, Messenger itself adds nothing to it. For example, [events facet](../components/c_facets/Events.js.html) sends actual DOM event when it posts message. + * Usage: + * ``` + * // subscribes onMouseUpDown to two DOM events on component via events facet. + * myComp.events.on('mousedown mouseup', onMouseUpDown); + * function onMouseUpDown(eventType, event) { + * // ... + * } + * + * myComp.data.on(/.+/, function(msg, data) { + * logger.debug(msg, data); + * }); // subscribes anonymous function to all non-empty messages on data facet + * // it will not be possible to unsubscribe anonymous subscriber separately, + * // but myComp.data.off(/.+/) will unsubscribe it + * ``` + * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the first subscriber for a given message is added, so it can subscribe to the source. + * [Components](../components/c_class.js.html) and [facets](../components/c_facet.js.html) change this method name to `on` when they proxy it. + * See [postMessage](#postMessage). + * + * @param {String|Array[String]|RegExp} messages Message types that should envoke the subscriber. + * If string is passed, it can be a sigle message or multiple message types separated by whitespace with optional commas. + * If an array of strings is passed, each string is a message type to subscribe for. + * If a RegExp is passed, the subscriber will be envoked when the message dispatched on the messenger matches the pattern (or IS the RegExp with identical pattern). + * Pattern subscriber does NOT cause any subscription to MessageSource, it only captures messages that are already subscribed to with precise message types. + * @param {Function|Object} subscriber Message subscriber - a function that will be called when the message is dispatched on the messenger (usually via proxied postMessage method of host object). + * If hostObject was supplied to Messenger constructor, hostObject will be the context (the value of this) for the subscriber envocation. + * Subscriber can also be an object with properties `subscriber` (function) and `context` ("this" value when subscriber is called) + * @return {Boolean} + */ +function Messenger$on(messages, subscriber) { + return _Messenger_onWithOptions.call(this, messages, subscriber); +} + + +function Messenger$once(messages, subscriber) { + return _Messenger_onWithOptions.call(this, messages, subscriber, { dispatchTimes: 1 }); +} + +function Messenger$onceSync(messages, subscriber) { + return _Messenger_onWithOptions.call(this, messages, subscriber, { dispatchTimes: 1, sync: true }); +} + + +function Messenger$onSync(messages, subscriber) { + return _Messenger_onWithOptions.call(this, messages, subscriber, { sync: true }); +} + + +function Messenger$onAsync(messages, subscriber) { + return _Messenger_onWithOptions.call(this, messages, subscriber, { sync: false }); +} + + +function _Messenger_onWithOptions(messages, subscriber, options) { + check(messages, Match.OneOf(String, [String], RegExp)); + check(subscriber, Match.OneOf(Function, { + subscriber: Function, + context: Match.Any, + options: Match.Optional(Object), + })); + + if (typeof subscriber == 'function') { + subscriber = { + subscriber: subscriber, + context: this._hostObject, + }; + } + + if (options) { + subscriber.options = subscriber.options || {}; + _.extend(subscriber.options, options); + } + + return _Messenger_on.call(this, messages, subscriber); +} + + +function _Messenger_on(messages, subscriber) { + _.defineProperty(subscriber, '__messages', messages); + return _eachMessage.call(this, '_registerSubscriber', messages, subscriber); +} + + +function _eachMessage(methodName, messages, subscriber) { + if (typeof messages == 'string') + messages = messages.split(messagesSplitRegExp); + + var subscribersHash = this._chooseSubscribersHash(messages); + + if (messages instanceof RegExp) + return this[methodName](subscribersHash, messages, subscriber); + + else { + var changed = false; + + messages.forEach(function(message) { + var subscriptionChanged = this[methodName](subscribersHash, message, subscriber); + changed = changed || subscriptionChanged; + }, this); + + return changed; + } +} + + +/** + * "Private" Messenger instance method + * It is called by [on](#Messenger$on) to register subscriber for one message type. + * Returns `true` if this subscriber is not yet registered for this type of message. + * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the first subscriber for a given message is added. + * + * @private + * @param {Object} subscribersHash The map of subscribers determined by [on](#Messenger$on) based on Message type, can be `this._patternMessageSubscribers` or `this._messageSubscribers` + * @param {String} message Message type + * @param {Function|Object} subscriber Subscriber function to be added or object with properties `subscriber` (function) and `context` (value of "this" when subscriber is called) + * @return {Boolean} + */ +function _registerSubscriber(subscribersHash, message, subscriber) { + if (! (subscribersHash[message] && subscribersHash[message].length)) { + subscribersHash[message] = []; + if (message instanceof RegExp) + subscribersHash[message].pattern = message; + if (this._messageSource) + this._messageSource.onSubscriberAdded(message); + var noSubscribers = true; + } + + var msgSubscribers = subscribersHash[message]; + var notYetRegistered = noSubscribers || _indexOfSubscriber.call(this, msgSubscribers, subscriber) == -1; + + if (notYetRegistered) + msgSubscribers.push(subscriber); + + return notYetRegistered; +} + + +/** + * Finds subscriber index in the list + * + * @param {Array[Function|Object]} list list of subscribers + * @param {Function|Object} subscriber subscriber function or object with properties `subscriber` (function) and `context` ("this" object) + */ +function _indexOfSubscriber(list, subscriber) { + var self = this; + return _.findIndex(list, function(subscr){ + return subscriber.subscriber == subscr.subscriber + && subscriber.context == subscr.context + }); +} + + +/** + * Messenger instance method. + * Subscribes to multiple messages passed as map together with subscribers. + * Usage: + * ``` + * myComp.events.onMessages({ + * 'mousedown': onMouseDown, + * 'mouseup': onMouseUp + * }); + * function onMouseDown(eventType, event) {} + * function onMouseUp(eventType, event) {} + * ``` + * Returns map with the same keys (message types) and boolean values indicating whether particular subscriber was added. + * It is NOT possible to add pattern subscriber using this method, as although you can use RegExp as the key, JavaScript will automatically convert it to string. + * + * @param {Object[Function]} messageSubscribers Map of message subscribers to be added + * @return {Object[Boolean]} + */ +function onMessages(messageSubscribers) { + check(messageSubscribers, Match.ObjectHash(Match.OneOf(Function, { subscriber: Function, context: Match.Any }))); + + var notYetRegisteredMap = _.mapKeys(messageSubscribers, function(subscriber, messages) { + return this.on(messages, subscriber); + }, this); + + return notYetRegisteredMap; +} + + +/** + * Messenger instance method. + * Removes a subscriber for message(s). Removes all subscribers for the message if subscriber isn't passed. + * This method returns `true` if the subscriber was registered. No error or warning is thrown or logged if you remove subscriber that was not registered. + * [Components](../components/c_class.js.html) and [facets](../components/c_facet.js.html) change this method name to `off` when they proxy it. + * Usage: + * ``` + * // unsubscribes onMouseUpDown from two DOM events. + * myComp.events.off('mousedown mouseup', onMouseUpDown); + * ``` + * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the last subscriber for a given message is removed and there is no more subscribers for this message. + * + * @param {String|Array[String]|RegExp} messages Message types that a subscriber should be removed for. + * If string is passed, it can be a sigle message or multiple message types separated by whitespace with optional commas. + * If an array of strings is passed, each string is a message type to remove a subscriber for. + * If a RegExp is passed, the pattern subscriber will be removed. + * RegExp subscriber does NOT cause any subscription to MessageSource, it only captures messages that are already subscribed to with precise message types. + * @param {Function} subscriber Message subscriber - Optional function that will be removed from the list of subscribers for the message(s). If subscriber is not supplied, all subscribers will be removed from this message(s). + * @return {Boolean} + */ +function Messenger$off(messages, subscriber) { + check(messages, Match.OneOf(String, [String], RegExp)); + check(subscriber, Match.Optional(Match.OneOf(Function, { + subscriber: Function, + context: Match.Any, + options: Match.Optional(Object), + // __messages: Match.Optional(Match.OneOf(String, [String], RegExp)) + }))); + + return _Messenger_off.call(this, messages, subscriber); +} + + +function _Messenger_off(messages, subscriber) { + return _eachMessage.call(this, '_removeSubscriber', messages, subscriber); +} + + +/** + * "Private" Messenger instance method + * It is called by [off](#Messenger$off) to remove subscriber for one message type. + * Returns `true` if this subscriber was registered for this type of message. + * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the last subscriber for a given message is removed and there is no more subscribers for this message. + * + * @private + * @param {Object} subscribersHash The map of subscribers determined by [off](#Messenger$off) based on message type, can be `this._patternMessageSubscribers` or `this._messageSubscribers` + * @param {String} message Message type + * @param {Function} subscriber Subscriber function to be removed + * @return {Boolean} + */ +function _removeSubscriber(subscribersHash, message, subscriber) { + var msgSubscribers = subscribersHash[message]; + if (! msgSubscribers || ! msgSubscribers.length) + return false; // nothing removed + + if (subscriber) { + if (typeof subscriber == 'function') + subscriber = { subscriber: subscriber, context: this._hostObject }; + + var subscriberIndex = _indexOfSubscriber.call(this, msgSubscribers, subscriber); + if (subscriberIndex == -1) + return false; // nothing removed + msgSubscribers.splice(subscriberIndex, 1); + if (! msgSubscribers.length) + this._removeAllSubscribers(subscribersHash, message); + + } else + this._removeAllSubscribers(subscribersHash, message); + + return true; // subscriber(s) removed +} + + +/** + * "Private" Messenger instance method + * It is called by [_removeSubscriber](#_removeSubscriber) to remove all subscribers for one message type. + * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified that all message subscribers were removed so it can unsubscribe from the source. + * + * @private + * @param {Object} subscribersHash The map of subscribers determined by [off](#Messenger$off) based on message type, can be `this._patternMessageSubscribers` or `this._messageSubscribers` + * @param {String} message Message type + */ +function _removeAllSubscribers(subscribersHash, message) { + delete subscribersHash[message]; + if (this._messageSource && typeof message == 'string') + this._messageSource.onSubscriberRemoved(message); +} + + +/** + * Messenger instance method. + * Unsubscribes from multiple messages passed as map together with subscribers. + * Returns map with the same keys (message types) and boolean values indicating whether particular subscriber was removed. + * If a subscriber for one of the messages is not supplied, all subscribers for this message will be removed. + * Usage: + * ``` + * myComp.events.offMessages({ + * 'mousedown': onMouseDown, + * 'mouseup': onMouseUp, + * 'click': undefined // all subscribers to this message will be removed + * }); + * ``` + * It is NOT possible to remove pattern subscriber(s) using this method, as although you can use RegExp as the key, JavaScript will automatically convert it to string. + * + * @param {Object[Function]} messageSubscribers Map of message subscribers to be removed + * @return {Object[Boolean]} + */ +function offMessages(messageSubscribers) { + check(messageSubscribers, Match.ObjectHash(Match.Optional(Match.OneOf(Function, { subscriber: Function, context: Match.Any })))); + + var subscriberRemovedMap = _.mapKeys(messageSubscribers, function(subscriber, messages) { + return this.off(messages, subscriber); + }, this); + + return subscriberRemovedMap; +} + + +/** + * Unsubscribes all subscribers + */ +function Messenger$offAll() { + _offAllSubscribers.call(this, this._patternMessageSubscribers); + _offAllSubscribers.call(this, this._messageSubscribers); +} + + +function _offAllSubscribers(subscribersHash) { + _.eachKey(subscribersHash, function(subscribers, message) { + this._removeAllSubscribers(subscribersHash, message); + }, this); +} + + +// TODO - send event to messageSource + + +/** + * Messenger instance method. + * Dispatches the message calling all subscribers registered for this message and, if the message is a string, calling all pattern subscribers when message matches the pattern. + * Each subscriber is passed the same parameters that are passed to theis method. + * The context of the subscriber envocation is set to the host object (`this._hostObject`) that was passed to the messenger constructor. + * Subscribers are called in the next tick ("asynchronously") apart from those that were subscribed with `onSync` (or that have `options.sync == true`). + * + * @param {String|RegExp} message message to be dispatched + * If the message is a string, the subscribers registered with exactly this message will be called and also pattern subscribers registered with the pattern that matches the dispatched message. + * If the message is RegExp, only the subscribers registered with exactly this pattern will be called. + * @param {Any} data data that will be passed to the subscriber as the second parameter. Messenger does not modify this data in any way. + * @param {Function} callback optional callback to pass to subscriber + * @param {Boolean} _synchronous if true passed, subscribers will be envoked synchronously apart from those that have `options.sync == false`. This parameter should not be used, instead postMessageSync should be used. + */ +function postMessage(message, data, callback, _synchronous) { + check(message, Match.OneOf(String, RegExp)); + check(callback, Match.Optional(Function)); + + var subscribersHash = this._chooseSubscribersHash(message); + var msgSubscribers = subscribersHash[message]; + + this._callSubscribers(message, data, callback, msgSubscribers, _synchronous); + + if (typeof message == 'string') + this._callPatternSubscribers(message, data, callback, msgSubscribers, _synchronous); +} + + +/** + * Same as postMessage apart from envoking subscribers synchronously, apart from those subscribed with `onAsync` (or with `options.sync == false`). + * + * @param {String|RegExp} message + * @param {Any} data + * @param {Function} callback + */ +function postMessageSync(message, data, callback) { + this.postMessage(message, data, callback, true); +} + + +/** + * "Private" Messenger instance method + * Envokes pattern subscribers with the pattern that matches the message. + * The method is called by [postMessage](#postMessage) - see more information there. + * + * @private + * @param {String} message message to be dispatched. Pattern subscribers registered with the pattern that matches the dispatched message will be called. + * @param {Any} data data that will be passed to the subscriber as the second parameter. Messenger does not modify this data in any way. + * @param {Function} callback optional callback to pass to subscriber + * @param {Array[Function|Object]} calledMsgSubscribers array of subscribers already called, they won't be called again if they are among pattern subscribers. + */ +function _callPatternSubscribers(message, data, callback, calledMsgSubscribers, _synchronous) { + _.eachKey(this._patternMessageSubscribers, + function(patternSubscribers) { + var pattern = patternSubscribers.pattern; + if (pattern.test(message)) { + if (calledMsgSubscribers) { + var patternSubscribers = patternSubscribers.filter(function(subscriber) { + var index = _indexOfSubscriber.call(this, calledMsgSubscribers, subscriber); + return index == -1; + }); + } + this._callSubscribers(message, data, callback, patternSubscribers, _synchronous); + } + } + , this); +} + + +/** + * "Private" Messenger instance method + * Envokes subscribers from the passed list. + * The method is called by [postMessage](#postMessage) and [_callPatternSubscribers](#_callPatternSubscribers). + * + * @private + * @param {String} message message to be dispatched, passed to subscribers as the first parameter. + * @param {Any} data data that will be passed to the subscriber as the second parameter. Messenger does not modify this data in any way. + * @param {Array[Function|Object]} msgSubscribers the array of message subscribers to be called. Each subscriber is called with the host object (see Messenger constructor) as the context. + * @param {Function} callback optional callback to pass to subscriber + */ +function _callSubscribers(message, data, callback, msgSubscribers, _synchronous) { + if (msgSubscribers && msgSubscribers.length) { + // cloning is necessary as some of the subscribers + // can be unsubscribed during the dispatch + // so this array would change in the process + msgSubscribers = msgSubscribers.slice(); + + msgSubscribers.forEach(function(subscriber) { + this._callSubscriber(subscriber, message, data, callback, _synchronous); + }, this); + } +} + + +function _callSubscriber(subscriber, message, data, callback, _synchronous) { + var syncSubscriber = subscriber.options && subscriber.options.sync + , synchro = (_synchronous && syncSubscriber !== false) + || syncSubscriber; + + var dispatchTimes = subscriber.options && subscriber.options.dispatchTimes; + if (dispatchTimes) { + if (dispatchTimes <= 1) { + var messages = subscriber.__messages; + this.off(messages, subscriber); + } else if (dispatchTimes > 1) + subscriber.options.dispatchTimes--; + } + + if (synchro) + subscriber.subscriber.call(subscriber.context, message, data, callback); + else + _.deferMethod(subscriber.subscriber, 'call', subscriber.context, message, data, callback); +} + + +/** + * Messenger instance method. + * Returns the array of subscribers that would be called if the message were dispatched. + * If `includePatternSubscribers === false`, pattern subscribers with matching patters will not be included (by default they are included). + * If there are no subscribers to the message, `undefined` will be returned, not an empty array, so it is safe to use the result in boolean tests. + * + * @param {String|RegExp} message Message to get subscribers for. + * If the message is RegExp, only pattern subscribers registered with exactly this pattern will be returned. + * If the message is String, subscribers registered with the string messages and pattern subscribers registered with matching pattern will be returned (unless the second parameter is false). + * @param {Boolean} includePatternSubscribers Optional false to prevent inclusion of patter subscribers, by default they are included. + * @return {Array|undefined} + */ +function getSubscribers(message, includePatternSubscribers) { + check(message, Match.OneOf(String, RegExp)); + + var subscribersHash = this._chooseSubscribersHash(message); + var msgSubscribers = subscribersHash[message] + ? [].concat(subscribersHash[message]) + : []; + + // pattern subscribers are incuded by default + if (includePatternSubscribers !== false && typeof message == 'string') { + _.eachKey(this._patternMessageSubscribers, + function(patternSubscribers) { + var pattern = patternSubscribers.pattern; + if (patternSubscribers && patternSubscribers.length + && pattern.test(message)) + _.appendArray(msgSubscribers, patternSubscribers); + } + ); + } + + // return undefined if there are no subscribers + return msgSubscribers.length + ? msgSubscribers + : undefined; +} + + +/** + * "Private" Messenger instance method + * Returns the map of subscribers for a given message type. + * + * @private + * @param {String|RegExp} message Message to choose the map of subscribers for + * @return {Object[Function]} + */ +function _chooseSubscribersHash(message) { + return message instanceof RegExp + ? this._patternMessageSubscribers + : this._messageSubscribers; +} + + +/** + * Messenger instance method + * Sets [MessageSource](./m_source.js.html) for the messenger also setting the reference to the messenger in the MessageSource. + * MessageSource can be passed to message constructor; this method allows to set it at a later time. For example, the subclasses of [ComponentFacet](../components/c_facet.js.html) use this method to set different MessageSource'es in the messenger that is created by ComponentFacet. + * Currently the method is implemented in such way that it can be called only once - MessageSource cannot be changed after this method is called. + * + * @param {MessageSource} messageSource an instance of MessageSource class to attach to this messenger (and to have this messenger attached to it too) + */ +function _setMessageSource(messageSource) { + check(messageSource, MessageSource); + + _.defineProperty(this, '_messageSource', messageSource); + messageSource.messenger = this; +} + + +/** + * Messenger instance method + * Returns messenger MessageSource + * + * @return {MessageSource} + */ +function getMessageSource() { + return this._messageSource +} + +},{"../abstract/mixin":116,"../util/check":135,"./m_source":122,"mol-proto":141}],120:[function(require,module,exports){ +arguments[4][68][0].apply(exports,arguments) +},{"../util/logger":137,"mol-proto":141}],121:[function(require,module,exports){ +arguments[4][69][0].apply(exports,arguments) +},{"./m_api":120,"mol-proto":141}],122:[function(require,module,exports){ +'use strict'; + +var Mixin = require('../abstract/mixin') + , MessengerAPI = require('./m_api') + , logger = require('../util/logger') + , _ = require('mol-proto') + , check = require('../util/check') + , Match = check.Match; + + +/** + * `milo.classes.MessageSource` + * An abstract class (subclass of [Mixin](../abstract/mixin.js.html)) for connecting [Messenger](./index.js.html) to external sources of messages (like DOM events) and defining higher level messages. + * An instance of MessageSource can either be passed to Messenger constructor or later using `_setMessageSource` method of Messenger. Once set, MessageSource of Messenger cannot be changed. + */ +var MessageSource = _.createSubclass(Mixin, 'MessageSource', true); + +module.exports = MessageSource; + + +/** + * ####MessageSource instance methods#### + * + * - [init](#init) - initializes messageSource - called by Mixin superclass + * - [setMessenger](#setMessenger) - connects Messenger to MessageSource, is called from `init` or `_setMessageSource` methods of [Messenger](./index.js.html). + * - [onSubscriberAdded](#onSubscriberAdded) - called by Messenger to notify when the first subscriber for an internal message was added, so MessageSource can subscribe to source + * - [onSubscriberRemoved](#onSubscriberRemoved) - called by Messenger to notify when the last subscriber for an internal message was removed, so MessageSource can unsubscribe from source + * - [dispatchMessage](#dispatchMessage) - dispatches source message. MessageSource subclass should implement mechanism when on actual source message this method is called. + * + * Methods below should be implemented in subclass: + * + * - [trigger](#trigger) - triggers messages on the source (an optional method) + * - [addSourceSubscriber](#addSourceSubscriber) - adds listener/subscriber to external message + * - [removeSourceSubscriber](#removeSourceSubscriber) - removes listener/subscriber from external message + */ +_.extendProto(MessageSource, { + init: init, + destroy: MessageSource$destroy, + setMessenger: setMessenger, + onSubscriberAdded: onSubscriberAdded, + onSubscriberRemoved: onSubscriberRemoved, + dispatchMessage: dispatchMessage, + postMessage: postMessage, + _prepareMessengerAPI: _prepareMessengerAPI, + + // Methods below must be implemented in subclass + trigger: toBeImplemented, + addSourceSubscriber: toBeImplemented, + removeSourceSubscriber: toBeImplemented +}); + + +/** + * MessageSource instance method. + * Called by Mixin constructor. + * MessageSource constructor should be passed the same parameters as this method signature. + * If an instance of [MessengerAPI](./m_api.js.html) is passed as the third parameter, it extends MessageSource functionality to allow it to define new messages, to filter messages based on their data and to change message data. See [MessengerAPI](./m_api.js.html). + * + * @param {Object} hostObject Optional object that stores the MessageSource on one of its properties. It is used to proxy methods of MessageSource. + * @param {Object[String]} proxyMethods Optional map of method names; key - proxy method name, value - MessageSource's method name. + * @param {MessengerAPI} messengerAPI Optional instance of MessengerAPI. + */ +function init(hostObject, proxyMethods, messengerAPI) { + this._prepareMessengerAPI(messengerAPI); +} + + +/** + * Destroys message source + */ +function MessageSource$destroy() { + if (this.messengerAPI) + this.messengerAPI.destroy(); +} + + +/** + * MessageSource instance method. + * Sets reference to Messenger instance. + * + * @param {Messenger} messenger reference to Messenger instance linked to this MessageSource + */ +function setMessenger(messenger) { + _.defineProperty(this, 'messenger', messenger); +} + + +/** + * MessageSource instance method. + * Prepares [MessengerAPI](./m_api.js.html) passed to constructor by proxying its methods to itself or if MessengerAPI wasn't passed defines two methods to avoid checking their availability every time the message is dispatched. + * + * @private + * @param {MessengerAPI} messengerAPI Optional instance of MessengerAPI + */ +function _prepareMessengerAPI(messengerAPI) { + check(messengerAPI, Match.Optional(MessengerAPI)); + + if (! messengerAPI) + messengerAPI = new MessengerAPI; + + _.defineProperty(this, 'messengerAPI', messengerAPI); +} + + +/** + * MessageSource instance method. + * Subscribes to external source using `addSourceSubscriber` method that should be implemented in subclass. + * This method is called by [Messenger](./index.js.html) when the first subscriber to the `message` is added. + * Delegates to supplied or default [MessengerAPI](./m_api.js.html) for translation of `message` to `sourceMessage`. `MessageAPI.prototype.addInternalMessage` will return undefined if this `sourceMessage` was already subscribed to to prevent duplicate subscription. + * + * @param {String} message internal Messenger message that has to be subscribed to at the external source of messages. + */ +function onSubscriberAdded(message) { + var newSourceMessage = this.messengerAPI.addInternalMessage(message); + if (typeof newSourceMessage != 'undefined') + this.addSourceSubscriber(newSourceMessage); +} + + +/** + * MessageSource instance method. + * Unsubscribes from external source using `removeSourceSubscriber` method that should be implemented in subclass. + * This method is called by [Messenger](./index.js.html) when the last subscriber to the `message` is removed. + * Delegates to supplied or default [MessengerAPI](./m_api.js.html) for translation of `message` to `sourceMessage`. `MessageAPI.prototype.removeInternalMessage` will return undefined if this `sourceMessage` was not yet subscribed to to prevent unsubscription without previous subscription. + * + * @param {String} message internal Messenger message that has to be unsubscribed from at the external source of messages. + */ +function onSubscriberRemoved(message) { + var removedSourceMessage = this.messengerAPI.removeInternalMessage(message); + if (typeof removedSourceMessage != 'undefined') + this.removeSourceSubscriber(removedSourceMessage); +} + + +/** + * MessageSource instance method. + * Dispatches sourceMessage to Messenger. + * Mechanism that calls this method when the source message is received should be implemented by subclass (see [DOMEventsSource](../components/msg_src/dom_events.js.html) for example). + * Delegates to supplied or default [MessengerAPI](./m_api.js.html) to create internal message data (`createInternalData`) and to filter the message based on its data and/or message (`filterSourceMessage`). + * Base MessengerAPI class implements these two methods in a trivial way (`createInternalData` simply returns external data, `filterSourceMessage` returns `true`), they are meant to be implemented by subclass. + * + * @param {String} sourceMessage source message received from external source + * @param {Object} sourceData data received from external source + */ +function dispatchMessage(sourceMessage, sourceData) { + var api = this.messengerAPI + , internalMessages = api.getInternalMessages(sourceMessage); + + if (internalMessages) + internalMessages.forEach(function (message) { + var internalData = api.createInternalData(sourceMessage, message, sourceData); + + var shouldDispatch = api.filterSourceMessage(sourceMessage, message, internalData); + if (shouldDispatch) + this.postMessage(message, internalData); + + }, this); +} + + +/** + * Posts message on the messenger. This method is separated so specific message sources can make message dispatch synchronous by using `postMessageSync` + * + * @param {String} message + * @param {Object} data + */ +function postMessage(message, data) { + this.messenger.postMessage(message, data); +} + + +function toBeImplemented() { + throw new Error('calling the method of an absctract class'); +} + +},{"../abstract/mixin":116,"../util/check":135,"../util/logger":137,"./m_api":120,"mol-proto":141}],123:[function(require,module,exports){ +arguments[4][71][0].apply(exports,arguments) +},{"../util/check":135,"./m_source":122,"mol-proto":141}],124:[function(require,module,exports){ +'use strict'; + +var _ = require('mol-proto'); + + +/** + * ####Milo packages#### + * + * - [minder](./minder.js.html) - data reactivity, one or two way, shallow or deep, as you like it + * - [config](./config.js.html) - milo configuration + * - [util](./util/index.js.html) - logger, request, dom, check, error, etc. + * - [classes](./classes.js.html) - abstract and base classes + * - [Messenger](./messenger/index.js.html) - generic Messenger used in most other milo classes, can be mixed into app classes too. + * - [Model](./model/index.js.html) - Model class that emits messages on changes to any depth without timer based watching + */ +var milo = { + minder: require('./minder'), + config: require('./config'), + util: require('./util'), + classes: require('./classes'), + Messenger: require('./messenger'), + Model: require('./model'), + destroy: destroy +}; + + +// export for node/browserify +if (typeof module == 'object' && module.exports) + module.exports = milo; + +// global milo for browser +if (typeof window == 'object') + window.milo = milo; + + +function destroy() { + milo.minder.destroy(); +} + +},{"./classes":117,"./config":118,"./messenger":119,"./minder":125,"./model":128,"./util":136,"mol-proto":141}],125:[function(require,module,exports){ +'use strict'; + +var Connector = require('./model/connector') + , Messenger = require('./messenger') + , _ = require('mol-proto') + , logger = require('./util/logger'); + + +module.exports = minder; + + +/** + * This function creates one or many Connector objects that + * create live reactive connection between objects implementing + * dataSource interface: + * Objects should emit messages when any part of their data changes, + * methods `on` and `off` should be implemented to subscribe/unsubscribe + * to change notification messages, methods `set` and `get` should be implemented to get/set data + * on path objects, pointing to particular parts of the object, method `path` + * should return path object for a given path string (see path utils for path string syntax). + * Both Model and Data facet are such data sources, they can be linked by Connector object. + * + * @param {Object} ds1 the first data source. Instead of the first data source an array can be passed with arrays of Connection objects parameters in each array element. + * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. + * @param {Object} ds2 the second data source + * @param {Object} options not implemented yet + */ +function minder(ds1, mode, ds2, options) { + if (Array.isArray(ds1)) { + var connDescriptions = ds1; + var connectors = connDescriptions.map(function(descr) { + return new Connector(descr[0], descr[1], descr[2], descr[3]); + }); + connectors.forEach(_addConnector); + return connectors; + } else { + var cnct = new Connector(ds1, mode, ds2, options); + _addConnector(cnct); + return cnct; + } +} + + +/** + * messenger of minder where it emits events related to all connectors + * @type {Messenger} + */ +var _messenger = new Messenger(minder, Messenger.defaultMethods); + + +var _connectors = [] + , _receivedMessages = [] + , _isPropagating = false; + + +_.extend(minder, { + getConnectors: minder_getConnectors, + getExpandedConnections: minder_getExpandedConnections, + isPropagating: minder_isPropagating, + whenPropagationCompleted: minder_whenPropagationCompleted, + destroyConnector: minder_destroyConnector, + destroy: minder_destroy +}); + + +function _addConnector(cnct) { + cnct.___minder_id = _connectors.push(cnct) - 1; + cnct.on(/.*/, onConnectorMessage); + minder.postMessage('added', { connector: cnct }); + minder.postMessage('turnedon', { connector: cnct }); +} + + +function onConnectorMessage(msg, data) { + var data = data ? _.clone(data) : {}; + _.extend(data, { + id: this.___minder_id, + connector: this + }); + minder.postMessage(msg, data); + if (! _receivedMessages.length && ! _isPropagating) { + _.defer(_idleCheck); + _isPropagating = true; + } + + _receivedMessages.push({ msg: msg, data: data }); +} + + +function _idleCheck() { + if (_receivedMessages.length) { + _receivedMessages.length = 0; + _.defer(_idleCheck); + minder.postMessage('propagationticked'); + } else { + _isPropagating = false; + minder.postMessage('propagationcompleted'); + } +} + + +function minder_isPropagating() { + return _isPropagating; +} + + +function minder_whenPropagationCompleted(callback) { + if (_isPropagating) + minder.once('propagationcompleted', executeCallback); + else + _.defer(executeCallback); + + function executeCallback() { + if (_isPropagating) + minder.once('propagationcompleted', executeCallback); + else + callback(); + } +} + + +function minder_getConnectors(onOff) { + if (typeof onOff == 'undefined') + return _connectors; + + return _connectors.filter(function(cnct) { + return cnct.isOn === onOff; + }); +} + + +function minder_destroyConnector(cnct) { + cnct.destroy(); + var index = _connectors.indexOf(cnct); + if (index >= 0) + delete _connectors[index]; + else + logger.warn('minder: connector destroyed that is not registered in minder'); +} + + +function minder_getExpandedConnections(onOff, searchStr) { + var connectors = minder.getConnectors(onOff); + var connections = connectors.map(function(cnct) { + var connection = { + leftSource: _getExpandedSource(cnct.ds1), + rightSource: _getExpandedSource(cnct.ds2), + mode: cnct.mode, + isOn: cnct.isOn + }; + + if (cnct.options) + connection.options = cnct.options; + + return connection; + }); + + if (searchStr) + connections = connections.filter(function(cnctn) { + return _sourceMatchesString(cnctn.leftSource, searchStr) + || _sourceMatchesString(cnctn.rightSource, searchStr); + }); + + return connections; +} + + +function _getExpandedSource(ds) { + var source = []; + if (typeof ds == 'function') { + if (ds._model && ds._accessPath) { + source.unshift(ds._accessPath); + ds = ds._model; + } + + source.unshift(ds); + ds = ds._hostObject; + } + + if (typeof ds == 'object') { + source.unshift(ds); + + if (ds.owner) + source.unshift(ds.owner); + } + + return source; +} + + +function _sourceMatchesString(source, matchStr) { + return source.some(function(srcNode) { + var className = srcNode.constructor && srcNode.constructor.name; + return _stringMatch(className, matchStr) + || _stringMatch(srcNode.name, matchStr) + || _stringMatch(srcNode, matchStr); + }); +} + + +function _stringMatch(str, substr) { + return str && typeof str == 'string' && str.indexOf(substr) >= 0; +} + + +function minder_destroy() { + _connectors.forEach(function(cnct) { + destroyDS(cnct.ds1); + destroyDS(cnct.ds2); + cnct.destroy(); + }); + _messenger.destroy(); + minder._destroyed = true; + + function destroyDS(ds) { + if (ds && !ds._destroyed) ds.destroy(); + } +} + +},{"./messenger":119,"./model/connector":127,"./util/logger":137,"mol-proto":141}],126:[function(require,module,exports){ +'use strict'; + + +var logger = require('../util/logger') + , config = require('../config') + , pathUtils = require('./path_utils') + , _ = require('mol-proto'); + +/** + * Utility function to process "changedata" messages emitted by Connector object. + */ +module.exports = changeDataHandler; + + +_.extend(changeDataHandler, { + setTransactionFlag: setTransactionFlag, + getTransactionFlag: getTransactionFlag, + passTransactionFlag: passTransactionFlag, + postTransactionFinished: postTransactionFinished +}); + + +/** + * Change data uses hidden property on accessor methods to pass flag that the accessor is executed as a part of change transaction. + * Accessor methods are supposed to store this flag in a local variable and to clear it (because another accessor can be executed in or out of transaction) using `getTransactionFlag` + * + * @private + * @param {Function} func accessor method reference + * @param {Boolean} flag a flag to be set + */ +function setTransactionFlag(func, flag) { + _.defineProperty(func, '__inChangeTransaction', flag, _.CONF | _.WRIT); +} + + +/** + * Retrieves and clears transaction flag from accessor method + * + * @private + * @param {Function} func accessor method reference + * @return {Boolean} + */ +function getTransactionFlag(func) { + var inTransaction = func.__inChangeTransaction; + delete func.__inChangeTransaction; + return inTransaction; +} + + +function passTransactionFlag(fromFunc, toFunc) { + var inTransaction = getTransactionFlag(fromFunc); + setTransactionFlag(toFunc, inTransaction); + return inTransaction; +} + + +/** + * Posts message on this to indicate the end of transaction unless `inChangeTransaction` is `true`. + */ +function postTransactionFinished() { + this.postMessageSync('datachanges', { transaction: false, changes: [] }); +} + + +/** + * subscriber to "changedata" event emitted by [Connector](./connector.js.html) object to enable reactive connections + * Used by Data facet, Model and ModelPath. Can be used by any object that implements get/set/del/splice api and sets data deeply to the whole tree. + * Object should call `changeDataHandler.initialize.call(this)` in its constructor. + * TODO: optimize messages list to avoid setting duplicate values down the tree + * + * @param {String} msg should be "changedata" here + * @param {Object} data batch of data change desciption objects + * @param {Function} callback callback to call before and after the data is processed + */ +function changeDataHandler(message, data, callback) { + processChanges.call(this, data.changes, callback); +} + + +// map of message types to methods +var CHANGE_TYPE_TO_METHOD_MAP = { + 'added': 'set', + 'changed': 'set', + 'deleted': 'del', + 'removed': 'del' +}; + + +/** + * Processes queued "changedata" messages. + * Posts "changestarted" and "changecompleted" messages and calls callback + * + * @param {[Function]} callback optional callback that is called with `(null, false)` parameters before change processing starts and `(null, true)` after it's finished. + */ +function processChanges(transaction, callback) { + notify.call(this, callback, false); + processTransaction.call(this, + prepareTransaction( + validateTransaction(transaction))); + notify.call(this, callback, true); +} + + +function notify(callback, changeFinished) { + callback && callback(null, changeFinished); + this.postMessage(changeFinished ? 'changecompleted' : 'changestarted'); +} + + +/** + * Checks that all messages from the transaction come from the same source. + * Hack: reverses the transaction if it comes from the Data facet + * Returns the reference to the transaction (for chaining) + * + * @param {Array} transaction transaction of data changes + * @return {Array} + */ +function validateTransaction(transaction) { + var source = transaction[0].source + , sameSource = true; + + if (transaction.length > 1) { + for (var i = 1, len = transaction.length; i < len; i++) + if (transaction[i].source != source) { + logger.error('changedata: changes from different sources in the same transaction, sources:', transaction[i].source.name, source.name); + sameSource = false; + source = transaction[i].source; + } + } + + return transaction; +} + + +function prepareTransaction(transaction) { + var todo = [] + , pathsToSplice = [] + , pathsToChange = [] + , hadSplice + , exitLoop = {}; + + + try { transaction.forEach(checkChange); } + catch (e) { if (e != exitLoop) throw e; } + + return todo; + + + function checkChange(data) { + (data.type == 'splice' ? checkSplice : checkMethod)(data); + } + + + function checkSplice(data) { + var parsedPath = pathUtils.parseAccessPath(data.path); + var parentPathChanged = pathsToChange.some(function(parentPath) { + if (parsedPath.length < parentPath.length) return; + return _pathIsParentOf(parentPath, parsedPath); + }); + + if (parentPathChanged) return; + + todo.push(data); + + if (! config.debug) throw exitLoop; + pathsToSplice.push(parsedPath); + hadSplice = true; + } + + + function checkMethod(data) { + var parsedPath = pathUtils.parseAccessPath(data.path); + var parentPathSpliced = pathsToSplice && pathsToSplice.some(function(parentPath) { + if (parsedPath.length <= parentPath.length + || parsedPath[parentPath.length].syntax != 'array') return; + return _pathIsParentOf(parentPath, parsedPath); + }); + + if (parentPathSpliced) return; + if (hadSplice) logger.error('changedata: child change is executed after splice; probably data source did not emit message with data.type=="finished"'); + + var parentPathChanged = pathsToChange.some(function(parentPath) { + if (parsedPath.length <= parentPath.length) return; + return _pathIsParentOf(parentPath, parsedPath); + }); + + if (parentPathChanged) return; + + pathsToChange.push(parsedPath); + + todo.push(data); + } + + + function _pathIsParentOf(parentPath, childPath) { + return parentPath.every(function(pathNode, index) { + return pathNode.property == childPath[index].property; + }); + } +} + + +function processTransaction(transaction) { + transaction.forEach(processChange, this); + postTransactionFinished.call(this, false); + + function processChange(data) { + var modelPath = this.path(data.path, data.type != 'removed' && data.type != 'deleted'); + if (! modelPath) return; + (data.type == 'splice' ? executeSplice : executeMethod)(modelPath, data); + } +} + + +function executeSplice(modelPath, data) { + var index = data.index + , howMany = data.removed.length + , spliceArgs = [index, howMany]; + + spliceArgs = spliceArgs.concat(data.newValue.slice(index, index + data.addedCount)); + setTransactionFlag(modelPath.splice, true); + modelPath.splice.apply(modelPath, spliceArgs); +} + + +function executeMethod(modelPath, data) { + var methodName = CHANGE_TYPE_TO_METHOD_MAP[data.type]; + if (methodName) { + setTransactionFlag(modelPath[methodName], true); + modelPath[methodName](data.newValue); + } else + logger.error('unknown data change type'); +} + +},{"../config":118,"../util/logger":137,"./path_utils":133,"mol-proto":141}],127:[function(require,module,exports){ +'use strict'; + +var Messenger = require('../messenger') + , pathUtils = require('./path_utils') + , _ = require('mol-proto') + , logger = require('../util/logger'); + + +module.exports = Connector; + + +var modePattern = /^(\<*)\-+(\>*)$/; + + +/** + * Connector + * Class that creates connector object for data connection between + * two data-sources + * Data-sources should implement the following API: + * get() - get value from datasource or its path + * set(value) - set value to datasource or to its path + * on(path, subscriber) - subscription to data changes with "*" support + * off(path, subscriber) + * path(accessPath) - to return the object that gives reference to some part of datasource + * and complies with that api too. + * + * ####Events#### + * + * - 'turnedon' - connector was turned on + * - 'turnedoff' - connector was turned off + * - 'changestarted' - change on connected datasource is started + * - 'changecompleted' - change on connected datasource is completed + * - 'destroyed' - connector was destroyed + * + * @param {Object} ds1 the first data source. + * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. + * @param {Object} ds2 the second data source + * @param {Object} options not implemented yet + * @return {Connector} when called with `new`, creates a Connector object. + */ +function Connector(ds1, mode, ds2, options) { + setupMode.call(this, mode); + + _.extend(this, { + ds1: ds1, + ds2: ds2, + isOn: false, + _changesQueue1: [], + _changesQueue2: [], + _messenger: new Messenger(this, Messenger.defaultMethods) + }); + + if (options) { + this.options = options; + + var pathTranslation = options.pathTranslation; + if (pathTranslation) { + pathTranslation = _.clone(pathTranslation); + var patternTranslation = getPatternTranslations(pathTranslation); + _.extend(this, { + pathTranslation1: reverseTranslationRules(pathTranslation), + pathTranslation2: pathTranslation, + patternTranslation1: reversePatternTranslationRules(patternTranslation), + patternTranslation2: patternTranslation + }); + } + + var dataTranslation = options.dataTranslation; + if (dataTranslation) { + _.extend(this, { + dataTranslation1: dataTranslation['<-'], + dataTranslation2: dataTranslation['->'] + }); + } + + var dataValidation = options.dataValidation; + if (dataValidation) { + _.extend(this, { + dataValidation1: dataValidation['<-'], + dataValidation2: dataValidation['->'] + }); + } + } + + this.turnOn(); +} + + +function setupMode(mode){ + var parsedMode = mode.match(modePattern); + + if (! parsedMode) + modeParseError(); + + var depth1 = parsedMode[1].length + , depth2 = parsedMode[2].length; + + if (depth1 && depth2 && depth1 != depth2) + modeParseError(); + + if (! depth1 && ! depth2) + modeParseError(); + + _.extend(this, { + mode: mode, + depth1: depth1, + depth2: depth2, + }); + + function modeParseError() { + throw new Error('invalid Connector mode: ' + mode); + } +} + + +_.extendProto(Connector, { + turnOn: Connector$turnOn, + turnOff: Connector$turnOff, + destroy: Connector$destroy, + changeMode: Connector$changeMode, + deferChangeMode: Connector$deferChangeMode +}); + +/** + * Function change the mode of the connection + * + * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. + * @return {Object[String]} + */ +function Connector$changeMode(mode) { + this.turnOff(); + setupMode.call(this, mode); + this.turnOn(); + return this; +} + + +/** + * Function change the mode of the connection + * + * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc. + * @return {Object[String]} + */ +function Connector$deferChangeMode(mode) { + _.deferMethod(this, 'changeMode', mode); + return this; +} + + +/** + * Function that reverses translation rules for paths of connected odata sources + * + * @param {Object[String]} rules map of paths defining the translation rules + * @return {Object[String]} + */ +function reverseTranslationRules(rules) { + var reverseRules = {}; + _.eachKey(rules, function(path2_value, path1_key) { + reverseRules[path2_value] = path1_key; + }); + return reverseRules; +} + + +function getPatternTranslations(pathTranslation) { + var patternTranslation = []; + _.eachKey(pathTranslation, function(path2_value, path1_key) { + var starIndex1 = path1_key.indexOf('*') + , starIndex2 = path2_value.indexOf('*'); + if (starIndex1 >= 0 && starIndex2 >= 0) { // pattern translation + if (path1_key.slice(starIndex1) != path2_value.slice(starIndex2)) + _throwInvalidTranslation(path1_key, path2_value); + delete pathTranslation[path1_key]; + + patternTranslation.push({ + fromPattern: pathUtils.createRegexPath(path1_key), + fromStaticPath: _getStaticPath(path1_key, starIndex1), + toPattern: pathUtils.createRegexPath(path2_value), + toStaticPath: _getStaticPath(path2_value, starIndex2) + }); + } else if (starIndex1 >= 0 || starIndex2 >= 0) // pattern only on one side of translation + _throwInvalidTranslation(path1_key, path2_value); + }); + + return patternTranslation; + + + function _throwInvalidTranslation(path1, path2) { + throw new Error('Invalid pattern translation: ' + path1 + ', ' + path2); + } + + + function _getStaticPath(path, starIndex) { + return path.replace(/[\.\[]?\*.*$/, ''); + } +} + + +function reversePatternTranslationRules(patternTranslation) { + return patternTranslation.map(function(pt) { + return { + fromPattern: pt.toPattern, + fromStaticPath: pt.toStaticPath, + toPattern: pt.fromPattern, + toStaticPath: pt.fromStaticPath + }; + }); +} + + +/** + * turnOn + * Method of Connector that enables connection (if it was previously disabled) + */ +function Connector$turnOn() { + if (this.isOn) + return logger.warn('data sources are already connected'); + + var subscriptionPath = this._subscriptionPath = + new Array(this.depth1 || this.depth2).join('*'); + + var subscriptionPattern = pathUtils.createRegexPath(subscriptionPath); + + var self = this; + if (this.depth1) + this._link1 = linkDataSource('_link2', this.ds2, this.ds1, this._changesQueue1, this.pathTranslation1, this.patternTranslation1, this.dataTranslation1, this.dataValidation1); + if (this.depth2) + this._link2 = linkDataSource('_link1', this.ds1, this.ds2, this._changesQueue2, this.pathTranslation2, this.patternTranslation2, this.dataTranslation2, this.dataValidation2); + + this.isOn = true; + this.postMessage('turnedon'); + + + function linkDataSource(reverseLink, fromDS, toDS, changesQueue, pathTranslation, patternTranslation, dataTranslation, dataValidation) { + fromDS.onSync('datachanges', onData); + return onData; + + function onData(message, batch) { + var sendData = { + changes: [], + transaction: batch.transaction + } + + batch.changes.forEach(function(change) { + var sourcePath = change.path + , targetPath = translatePath(sourcePath); + + if (typeof targetPath == 'undefined') return; + + var change = _.clone(change); + _.extend(change, { + source: fromDS, + path: targetPath + }); + + translateData(sourcePath, change); + validateData(sourcePath, change); + }); + + if (! changesQueue.length) + _.defer(postChangeData); + + changesQueue.push(sendData); + + + function translatePath(sourcePath) { + if (pathTranslation) { + var translatedPath = pathTranslation[sourcePath]; + if (translatedPath) return translatedPath; + if (!patternTranslation.length) return; + var pt = _.find(patternTranslation, function(pTranslation) { + return pTranslation.fromPattern.test(sourcePath); + }); + if (!pt) return; + var translatedPath = sourcePath.replace(pt.fromStaticPath, pt.toStaticPath); + } else if (! ((subscriptionPattern instanceof RegExp + && subscriptionPattern.test(sourcePath)) + || subscriptionPattern == sourcePath)) return; + + return translatedPath || sourcePath; + } + + + function translateData(sourcePath, change) { + if (dataTranslation) { + var translate = dataTranslation[sourcePath]; + if (translate && typeof translate == 'function') { + change.oldValue = translate(change.oldValue); + change.newValue = translate(change.newValue); + } + } + } + + + function validateData(sourcePath, change) { + propagateData(change); + + if (dataValidation) { + var validators = dataValidation[sourcePath] + , passedCount = 0 + , alreadyFailed = false; + + if (validators) + validators.forEach(callValidator); + } + + + function callValidator(validator) { + validator(change.newValue, function(err, response) { + response.path = sourcePath; + if (! alreadyFailed && (err || response.valid) && ++passedCount == validators.length) { + fromDS.postMessage('validated', response); + } else if (! response.valid) { + alreadyFailed = true; + fromDS.postMessage('validated', response); + } + }); + } + } + + + function propagateData(change) { + sendData.changes.push(change); + } + + + function postChangeData() { + // prevent endless loop of updates for 2-way connection + if (self[reverseLink]) var callback = subscriptionSwitch; + + var transactions = mergeTransactions(changesQueue); + changesQueue.length = 0; + transactions.forEach(function(transaction) { + // send data change instruction as message + toDS.postMessageSync('changedata', { changes: transaction }, callback); + }); + } + + + function subscriptionSwitch(err, changeFinished) { + if (err) return; + var onOff = changeFinished ? 'onSync' : 'off'; + toDS[onOff]('datachanges', self[reverseLink]); + + var message = changeFinished ? 'changecompleted' : 'changestarted'; + self.postMessage(message, { source: fromDS, target: toDS }); + } + + + function mergeTransactions(batches) { + var transactions = [] + , currentTransaction; + + batches.forEach(function(batch) { + if (! batch.transaction) currentTransaction = undefined; + if (! batch.changes.length) return; + + if (batch.transaction) { + if (currentTransaction) + _.appendArray(currentTransaction, batch.changes); + else { + currentTransaction = _.clone(batch.changes); + transactions.push(currentTransaction); + } + } else + transactions.push(batch.changes); + }); + + return transactions; + } + } + } +} + + +/** + * turnOff + * Method of Connector that disables connection (if it was previously enabled) + */ +function Connector$turnOff() { + if (! this.isOn) + return logger.warn('data sources are already disconnected'); + + var self = this; + unlinkDataSource(this.ds1, '_link2', this.pathTranslation2); + unlinkDataSource(this.ds2, '_link1', this.pathTranslation1); + + this.isOn = false; + this.postMessage('turnedoff'); + + + function unlinkDataSource(fromDS, linkName, pathTranslation) { + if (self[linkName]) { + fromDS.off('datachanges', self[linkName]); + delete self[linkName]; + } + } +} + + +/** + * Destroys connector object by turning it off and removing references to connected sources + */ +function Connector$destroy() { + this.turnOff(); + this.postMessage('destroyed'); + this._messenger.destroy(); + delete this.ds1; + delete this.ds2; + this._destroyed = true; +} + +},{"../messenger":119,"../util/logger":137,"./path_utils":133,"mol-proto":141}],128:[function(require,module,exports){ +'use strict'; + +var ModelPath = require('./m_path') + , synthesize = require('./synthesize') + , pathUtils = require('./path_utils') + , changeDataHandler = require('./change_data') + , Messenger = require('../messenger') + , MessengerMessageSource = require('../messenger/msngr_source') + , ModelMsgAPI = require('./m_msg_api') + , Mixin = require('../abstract/mixin') + , _ = require('mol-proto') + , check = require('../util/check') + , Match = check.Match + , logger = require('../util/logger'); + + +module.exports = Model; + + +/** + * `milo.Model` + * Model class instantiates objects that allow deep data access with __safe getters__ that return undefined (rather than throwing exception) when properties/items of unexisting objects/arrays are requested and __safe setters__ that create object trees when properties/items of unexisting objects/arrays are set and also post messages to allow subscription on changes and enable data reactivity. + * Reactivity is implememnted via [Connector](./connector.js.html) that can be instantiated either directly or with more convenient interface of [milo.minder](../minder.js.html). At the moment model can be connected to [Data facet](../components/c_facets/Data.js.html) or to another model or [ModelPath](./m_path.js.html). + * Model constructor returns objects that are functions at the same time; when called they return ModelPath objects that allow get/set access to any point in model data. See [ModelData](#ModelData) below. + * + * You can subscribe to model changes with `on` method by passing model access path in place of message, pattern or string with any number of stars to subscribe to a certain depth in model (e.g., `'***'` to subscribe to three levels). + * + * @constructor + * @param {Object|Array} data optional initial array data. If it is planned to connect model to view it is usually better to instantiate an empty Model (`var m = new Model`), connect it to [Component](../components/c_class.js.html)'s [Data facet](../components/c_facets/Data.js.html) (e.g., `milo.minder(m, '<<->>', c.data);`) and then set the model with `m.set(data)` - the view will be automatically updated. + * @param {Object} hostObject optional object that hosts model on one of its properties. Can be used when model itself is the context of the message subscriber and you need to travers to this object (although it is possible to set any context). Can also be used to proxy model's methods to the host like [Model facet](../components/c_facets/ModelFacet.js.html) is doing. + * @param {Object} options pass { reactive: false } to use model without messaging when it is not needed - it makes it much faster + * @return {Model} + */ +function Model(data, hostObject, options) { + // `model` will be returned by constructor instead of `this`. `model` + // (`modelPath` function) should return a ModelPath object with "synthesized" methods + // to get/set model properties, to subscribe to property changes, etc. + // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below. + var model = function modelPath(accessPath) { // , ... arguments that will be interpolated + return Model$path.apply(model, arguments); + }; + model.__proto__ = Model.prototype; + + model._hostObject = hostObject; + model._options = options || {}; + + if (model._options.reactive !== false) { + model._prepareMessengers(); + // subscribe to "changedata" message to enable reactive connections + model.onSync('changedata', changeDataHandler); + } + + if (data) model._data = data; + + return model; +} + +Model.prototype.__proto__ = Model.__proto__; + + +/** + * ####Model instance methods#### + * + * - [path](#path) - returns ModelPath object that allows access to any point in Model + * - [get](#Model$get) - get model data + * - set - set model data, synthesized + * - splice - splice model data (as array or pseudo-array), synthesized + * - [len](./m_path.js.html#ModelPath$len) - returns length of array (or pseudo-array) in model in safe way, 0 if no length is set + * - [push](./m_path.js.html#ModelPath$push) - add items to the end of array (or pseudo-array) in model + * - [pop](./m_path.js.html#ModelPath$pop) - remove item from the end of array (or pseudo-array) in model + * - [unshift](./m_path.js.html#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in model + * - [shift](./m_path.js.html#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in model + * - [proxyMessenger](#proxyMessenger) - proxy model's Messenger methods to host object + * - [proxyMethods](#proxyMethods) - proxy model methods to host object + */ +_.extendProto(Model, { + path: Model$path, + get: Model$get, + proxyMessenger: proxyMessenger, // deprecated, should not be used + proxyMethods: proxyMethods, + _prepareMessengers: _prepareMessengers, + _getHostObject: _getHostObject, + destroy: Model$destroy +}); + +// set, del, splice are added to model +_.extendProto(Model, synthesize.modelMethods); + + +/** + * - Path: ModelPath class as `milo.Model.Path` + */ +_.extend(Model, { + Path: ModelPath, + useWith: Model$$useWith +}); + + +/** + * Expose Messenger methods on Facet prototype + */ +var MESSENGER_PROPERTY = '_messenger'; +Messenger.useWith(Model, MESSENGER_PROPERTY, Messenger.defaultMethods); + + +/** + * ModelPath methods added to Model prototype + */ +['len', 'push', 'pop', 'unshift', 'shift'].forEach(function(methodName) { + var method = ModelPath.prototype[methodName]; + _.defineProperty(Model.prototype, methodName, method); +}); + + +/** + * Model instance method. + * Get model data. + * + * @return {Any} + */ +function Model$get() { + return this._data; +} + + +/** + * Model instance method. + * Returns ModelPath object that implements the same API as model but allows access to any point inside model as defined by `accessPath`. + * See [ModelPath](./m_path.js.html) class for more information. + * + * @param {String} accessPath string that defines path to access model. + * Path string consists of parts to define either property access (`".name"` to access property name) or array item access (`"[1]"` to access item with index 1). + * Access path can contain as many parts as necessary (e.g. `".list[0].name"` to access property `name` in the first element of array stored in property `list`. + * @param {List} arguments additional arguments of this method can be used to create interpolated paths. + * E.g. `m.path("[$1].$2", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m("[" + id + "]." + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`. + * @return {ModelPath} + */ +function Model$path(accessPath) { // , ... arguments that will be interpolated + if (! accessPath) return this; + + // "null" is context to pass to ModelPath, first parameter of bind + // "this" (model) is added in front of all arguments + _.splice(arguments, 0, 0, null, this); + + // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ... + return new (Function.prototype.bind.apply(ModelPath, arguments)); +} + + +/** + * Model instance method. + * Proxy model's Messenger methods to host object. + * + * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used. + */ +function proxyMessenger(modelHostObject) { + modelHostObject = modelHostObject || this._hostObject; + Mixin.prototype._createProxyMethods.call(this[MESSENGER_PROPERTY], Messenger.defaultMethods, modelHostObject); +} + + +var modelMethodsToProxy = ['path', 'get', 'set', 'del', 'splice', 'len', 'push', 'pop', 'unshift', 'shift']; + + +/** + * Expose model methods on + * See same method in Mixin class for parameters meaning + * + * @param {Function} hostClass + * @param {[type]} instanceKey + * @param {[type]} mixinMethods optional + */ +function Model$$useWith(hostClass, instanceKey, mixinMethods) { + mixinMethods = mixinMethods || modelMethodsToProxy; + Mixin.useWith.call(Model, hostClass, instanceKey, mixinMethods); +} + + +/** + * Model instance method. + * Proxy model methods to host object. + * + * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used. + */ +function proxyMethods(modelHostObject) { + modelHostObject = modelHostObject || this._hostObject; + Mixin.prototype._createProxyMethods.call(this, modelMethodsToProxy, modelHostObject); +} + + +/** + * Model instance method. + * Create and connect internal and external model's messengers. + * External messenger's methods are proxied on the model and they allows "*" subscriptions. + */ +function _prepareMessengers() { + // model will post all its changes on internal messenger + var internalMessenger = new Messenger(this, undefined, undefined); + + // message source to connect internal messenger to external + var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger); + + // external messenger to which all model users will subscribe, + // that will allow "*" subscriptions and support "changedata" message api. + var externalMessenger = new Messenger(this, undefined, internalMessengerSource); + + _.defineProperty(this, MESSENGER_PROPERTY, externalMessenger); + _.defineProperty(this, '_internalMessenger', internalMessenger); +} + + +function _getHostObject() { + return this._hostObject; +} + + +function Model$destroy() { + this[MESSENGER_PROPERTY].destroy(); + this._internalMessenger.destroy(); + this._destroyed = true; +} + +},{"../abstract/mixin":116,"../messenger":119,"../messenger/msngr_source":123,"../util/check":135,"../util/logger":137,"./change_data":126,"./m_msg_api":129,"./m_path":130,"./path_utils":133,"./synthesize":134,"mol-proto":141}],129:[function(require,module,exports){ +arguments[4][75][0].apply(exports,arguments) +},{"../messenger/m_api_rx":121,"./path_utils":133,"mol-proto":141}],130:[function(require,module,exports){ +arguments[4][76][0].apply(exports,arguments) +},{"../messenger":119,"../messenger/msngr_source":123,"../util/check":135,"./change_data":126,"./path_msg_api":132,"./path_utils":133,"./synthesize":134,"mol-proto":141}],131:[function(require,module,exports){ +module.exports=require(77) +},{}],132:[function(require,module,exports){ +arguments[4][78][0].apply(exports,arguments) +},{"../messenger/m_api":120,"../util/logger":137,"./path_utils":133,"mol-proto":141}],133:[function(require,module,exports){ +'use strict'; + +// +// ### model path utils + +var check = require('../util/check') + , Match = check.Match + , _ = require('mol-proto'); + +var pathUtils = { + parseAccessPath: parseAccessPath, + createRegexPath: createRegexPath, + getPathNodeKey: getPathNodeKey, + wrapMessengerMethods: wrapMessengerMethods +}; + +module.exports = pathUtils; + + +var propertyPathSyntax = '\\.[A-Za-z_-][A-Za-z0-9_-]*' + , arrayPathSyntax = '\\[[0-9]+\\]' + , interpolationSyntax = '\\$[1-9][0-9]*' + , propertyInterpolateSyntax = '\\.' + interpolationSyntax + , arrayInterpolateSyntax = '\\[' + interpolationSyntax + '\\]' + + , propertyStarSyntax = '\\.\\*' + , arrayStarSyntax = '\\[\\*\\]' + , starSyntax = '\\*' + + , pathParseSyntax = [ + propertyPathSyntax, + arrayPathSyntax, + propertyInterpolateSyntax, + arrayInterpolateSyntax + ].join('|') + , pathParsePattern = new RegExp(pathParseSyntax, 'g') + + , patternPathParseSyntax = [ + pathParseSyntax, + propertyStarSyntax, + arrayStarSyntax, + starSyntax + ].join('|') + , patternPathParsePattern = new RegExp(patternPathParseSyntax, 'g') + + //, targetPathParsePattern = /\.[A-Za-z][A-Za-z0-9_]*|\[[0-9]+\]|\.\$[1-9][0-9]*|\[\$[1-9][0-9]*\]|\$[1-9][0-9]/g + , pathNodeTypes = { + '.': { syntax: 'object', empty: '{}' }, + '[': { syntax: 'array', empty: '[]'}, + '*': { syntax: 'match', empty: '{}'}, + }; + +function parseAccessPath(path, nodeParsePattern) { + nodeParsePattern = nodeParsePattern || pathParsePattern; + + var parsedPath = []; + + if (! path) + return parsedPath; + + var unparsed = path.replace(nodeParsePattern, function(nodeStr) { + var pathNode = { property: nodeStr }; + _.extend(pathNode, pathNodeTypes[nodeStr[0]]); + if (nodeStr[1] == '$') + pathNode.interpolate = getPathNodeKey(pathNode, true); + + parsedPath.push(pathNode); + return ''; + }); + if (unparsed) + throw new Error('incorrect model path: ' + path); + + return parsedPath; +} + + +var nodeRegex = { + '.*': propertyPathSyntax, + '[*]': arrayPathSyntax +}; +nodeRegex['*'] = nodeRegex['.*'] + '|' + nodeRegex['[*]']; + +function createRegexPath(path) { + check(path, Match.OneOf(String, RegExp)); + + if (path instanceof RegExp || path.indexOf('*') == -1) + return path; + + var parsedPath = pathUtils.parseAccessPath(path, patternPathParsePattern) + , regexStr = '^' + // , regexStrEnd = '' + , patternsStarted = false; + + parsedPath.forEach(function(pathNode) { + var prop = pathNode.property + , regex = nodeRegex[prop]; + + if (regex) { + // regexStr += '(' + regex; + // regexStrEnd += '|)'; + regexStr += '(' + regex + '|)'; + // regexStrEnd += '|)'; + patternsStarted = true; + } else { + // if (patternsStarted) + // throw new Error('"*" path segment cannot be in the middle of the path: ' + path); + regexStr += prop.replace(/(\.|\[|\])/g, '\\$1'); // add slash in front of symbols that have special meaning in regex + } + }); + + regexStr += /* regexStrEnd + */ '$'; + + try { + return new RegExp(regexStr); + } catch (e) { + throw new Error('can\'t construct regex for path pattern: ' + path); + } +} + + +function getPathNodeKey(pathNode, interpolated) { + var prop = pathNode.property + , startIndex = interpolated ? 2 : 1; + return pathNode.syntax == 'array' + ? prop.slice(startIndex, prop.length - 1) + : prop.slice(startIndex); +} + + +// TODO allow for multiple messages in a string +function wrapMessengerMethods(methodsNames) { + methodsNames = methodsNames || ['on', 'off']; + var wrappedMethods = _.mapToObject(methodsNames, function(methodName) { + var origMethod = this[methodName]; + // replacing message subsribe/unsubscribe/etc. to convert "*" message patterns to regexps + return function(path, subscriber) { + var regexPath = createRegexPath(path); + origMethod.call(this, regexPath, subscriber); + }; + }, this); + _.defineProperties(this, wrappedMethods); +} + +},{"../util/check":135,"mol-proto":141}],134:[function(require,module,exports){ +'use strict'; + +var pathUtils = require('../path_utils') + , modelUtils = require('../model_utils') + , logger = require('../../util/logger') + , fs = require('fs') + , doT = require('dot') + , _ = require('mol-proto') + , changeDataHandler = require('../change_data') + , getTransactionFlag = changeDataHandler.getTransactionFlag + , postTransactionFinished = changeDataHandler.postTransactionFinished; + + +/** + * Templates to synthesize model getters and setters + */ +var templates = { + get: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\nmethod = function get() {\n var m = {{# def.modelAccessPrefix }};\n return m {{~ it.parsedPath :pathNode }}\n {{? pathNode.interpolate}}\n && (m = m[this._args[ {{= pathNode.interpolate }} ]])\n {{??}}\n && (m = m{{= pathNode.property }})\n {{?}} {{~}};\n};\n", + set: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n\n\n/**\n * Template that synthesizes setter for Model and for ModelPath\n */\nmethod = function set(value) {\n {{# def.initVars:'set' }}\n\n {{# def.createTree:'set' }}\n\n {{\n currNode = nextNode;\n currProp = currNode && currNode.property;\n }}\n\n {{ /* assign value to the last property */ }}\n {{? currProp }}\n wasDef = {{# def.wasDefined}};\n {{# def.changeAccessPath }}\n\n var old = m{{# def.currProp }};\n\n {{ /* clone value to prevent same reference in linked models */ }}\n m{{# def.currProp }} = cloneTree(value);\n {{?}}\n\n {{ /* add message related to the last property change */ }}\n if (this._options.reactive !== false) {\n if (! wasDef)\n {{# def.addMsg }} accessPath, type: 'added',\n newValue: value });\n else if (old != value)\n {{# def.addMsg }} accessPath, type: 'changed',\n oldValue: old, newValue: value });\n\n {{ /* add message related to changes in (sub)properties inside removed and assigned value */ }}\n if (! wasDef || old != value)\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, value); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n", + del: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_traverse_tree }}\n\nmethod = function del() {\n {{# def.initVars:'del' }}\n\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n if (! treeDoesNotExist && m && m.hasOwnProperty && {{# def.wasDefined}}) {\n var old = m{{# def.currProp }};\n delete m{{# def.currProp }};\n {{# def.changeAccessPath }}\n var didDelete = true;\n }\n {{??}}\n if (typeof m != 'undefined') {\n var old = m;\n {{# def.modelAccessPrefix }} = undefined;\n var didDelete = true;\n }\n {{?}}\n\n if (didDelete && this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'deleted', oldValue: old });\n\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, undefined); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n", + splice: "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n{{# def.include_traverse_tree }}\n\nmethod = function splice(spliceIndex, spliceHowMany) { /* ,... - extra arguments to splice into array */\n {{# def.initVars:'splice' }}\n\n var argsLen = arguments.length;\n var addItems = argsLen > 2;\n\n if (addItems) {\n {{ /* only create model tree if items are inserted in array */ }}\n\n {{ /* if model is undefined it will be set to an empty array */ }} \n var value = [];\n {{# def.createTree:'splice' }}\n\n {{? nextNode }}\n {{\n var currNode = nextNode;\n var currProp = currNode.property;\n var emptyProp = '[]';\n }}\n\n {{# def.createTreeStep }}\n {{?}}\n\n } else if (spliceHowMany > 0) {\n {{ /* if items are not inserted, only traverse model tree if items are deleted from array */ }}\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n {{ /* extra brace closes 'else' in def.traverseTreeStep */ }}\n {{# def.traverseTreeStep }} }\n {{?}}\n }\n\n {{ /* splice items */ }}\n if (addItems || (! treeDoesNotExist && m\n && m.length > spliceIndex ) ) {\n var oldLength = m.length = m.length || 0;\n\n arguments[0] = spliceIndex = normalizeSpliceIndex(spliceIndex, m.length);\n\n {{ /* clone added arguments to prevent same references in linked models */ }}\n if (addItems)\n for (var i = 2; i < argsLen; i++)\n arguments[i] = cloneTree(arguments[i]);\n\n {{ /* actual splice call */ }}\n var removed = Array.prototype.splice.apply(m, arguments);\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'splice',\n index: spliceIndex, removed: removed, addedCount: addItems ? argsLen - 2 : 0,\n newValue: m });\n\n if (removed && removed.length)\n removed.forEach(function(item, index) {\n var itemPath = accessPath + '[' + (spliceIndex + index) + ']';\n {{# def.addMsg }} itemPath, type: 'removed', oldValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'removed', 'oldValue');\n });\n\n if (addItems)\n for (var i = 2; i < argsLen; i++) {\n var item = arguments[i];\n var itemPath = accessPath + '[' + (spliceIndex + i - 2) + ']';\n {{# def.addMsg }} itemPath, type: 'added', newValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'added', 'newValue');\n }\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n }\n\n return removed || [];\n}\n" +}; + +var include_defines = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts initialization code\n */\n {{## def.initVars:method:\n var m = {{# def.modelAccessPrefix }};\n var messages = [], messagesHash = {};\n var accessPath = '';\n var treeDoesNotExist;\n /* hack to prevent sending finished events to allow for propagation of batches without splitting them */\n var inChangeTransaction = getTransactionFlag( {{= method }} );\n #}}\n\n/**\n * Inserts the beginning of function call to add message to list\n */\n{{## def.addMsg: addChangeMessage(messages, messagesHash, { path: #}}\n\n/**\n * Inserts current property/index for both normal and interpolated properties/indexes\n */\n{{## def.currProp:{{? currNode.interpolate }}[this._args[ {{= currNode.interpolate }} ]]{{??}}{{= currProp }}{{?}} #}}\n\n/**\n * Inserts condition to test whether normal/interpolated property/index exists\n */\n{{## def.wasDefined: m.hasOwnProperty(\n {{? currNode.interpolate }}\n this._args[ {{= currNode.interpolate }} ]\n {{??}}\n '{{= it.getPathNodeKey(currNode) }}'\n {{?}}\n) #}}\n\n\n/**\n * Inserts code to update access path for current property\n * Because of the possibility of interpolated properties, it can't be calculated in template, it can only be calculated during accessor call.\n */\n{{## def.changeAccessPath:\n accessPath += {{? currNode.interpolate }}\n {{? currNode.syntax == 'array' }}\n '[' + this._args[ {{= currNode.interpolate }} ] + ']';\n {{??}}\n '.' + this._args[ {{= currNode.interpolate }} ];\n {{?}}\n {{??}}\n '{{= currProp }}';\n {{?}}\n#}}\n\n\n/**\n * Inserts code to post stored messages\n */\n{{## def.postMessages:\n if (messages.length) {\n {{# def.modelPostBatchCode }}('datachanges', {\n changes: messages,\n transaction: inChangeTransaction\n });\n\n messages.forEach(function(msg) {\n {{# def.modelPostMessageCode }}(msg.path, msg);\n }, this);\n }\n#}}\n" + , include_create_tree = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to create model tree as neccessary for `set` and `splice` accessors and to add messages to send list if the tree changes.\n */\n{{## def.createTree:method:\n var wasDef = true;\n var old = m;\n\n {{ var emptyProp = it.parsedPath[0] && it.parsedPath[0].empty; }}\n {{? emptyProp }}\n {{ /* create top level model if it was not previously defined */ }}\n if (! m) {\n m = {{# def.modelAccessPrefix }} = {{= emptyProp }};\n wasDef = false;\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} '', type: 'added',\n newValue: m });\n }\n }\n {{??}}\n {{? method == 'splice' }}\n if (! m) {\n {{?}}\n m = {{# def.modelAccessPrefix }} = cloneTree(value);\n wasDef = typeof old != 'undefined';\n {{? method == 'splice' }}\n }\n {{?}} \n {{?}}\n\n\n {{ /* create model tree if it doesn't exist */ }}\n {{ var modelDataProperty = '';\n var nextNode = it.parsedPath[0];\n var count = it.parsedPath.length - 1;\n\n for (var i = 0; i < count; i++) {\n var currNode = nextNode;\n var currProp = currNode.property;\n nextNode = it.parsedPath[i + 1];\n var emptyProp = nextNode && nextNode.empty;\n }}\n\n {{# def.createTreeStep }}\n\n {{ } /* for loop */ }}\n#}}\n\n\n/**\n * Inserts code to create one step in the model tree\n */\n{{## def.createTreeStep:\n {{# def.changeAccessPath }}\n\n if (! {{# def.wasDefined }}) { \n {{ /* property does not exist */ }}\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'added', \n newValue: m });\n }\n\n } else if (typeof m{{# def.currProp }} != 'object') {\n {{ /* property is not object */ }}\n var old = m{{# def.currProp }};\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'changed', \n oldValue: old, newValue: m });\n }\n\n } else {\n {{ /* property exists, just traverse down the model tree */ }}\n m = m{{# def.currProp }};\n }\n#}}\n" + , include_traverse_tree = "'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to traverse model tree for `delete` and `splice` accessors.\n */\n{{## def.traverseTree:\n {{ \n var count = it.parsedPath.length-1;\n\n for (var i = 0; i < count; i++) { \n var currNode = it.parsedPath[i];\n var currProp = currNode.property;\n }}\n {{# def.traverseTreeStep }}\n\n {{ } /* for loop */\n\n var i = count;\n while (i--) { /* closing braces for else's above */\n }}\n }\n {{ } /* while loop */ }}\n#}}\n\n\n/**\n * Inserts code to traverse one step in the model tree\n */\n{{## def.traverseTreeStep:\n if (! (m && m.hasOwnProperty && {{# def.wasDefined}} ) )\n treeDoesNotExist = true;\n else {\n m = m{{# def.currProp }};\n {{# def.changeAccessPath }}\n {{ /* brace from else is not closed on purpose - all braces are closed in while loop */ }}\n#}}\n"; + +var dotDef = { + include_defines: include_defines, + include_create_tree: include_create_tree, + include_traverse_tree: include_traverse_tree, + getPathNodeKey: pathUtils.getPathNodeKey, + modelAccessPrefix: 'this._model._data', + modelPostMessageCode: 'this._model._internalMessenger.postMessage', + modelPostBatchCode: 'this._model.postMessageSync', + internalMessenger: 'this._model._internalMessenger' +}; + +var modelDotDef = _(dotDef).clone().extend({ + modelAccessPrefix: 'this._data', + modelPostMessageCode: 'this._internalMessenger.postMessage', + modelPostBatchCode: 'this.postMessageSync', + internalMessenger: 'this._internalMessenger' +})._(); + + +var dotSettings = _.clone(doT.templateSettings); +dotSettings.strip = false; + +var synthesizers = _.mapKeys(templates, function(tmpl) { + return doT.template(tmpl, dotSettings, dotDef); +}); + + +var modelSynthesizers = _.mapToObject(['set', 'del', 'splice'], function(methodName) { + return doT.template(templates[methodName], dotSettings, modelDotDef); +}); + + +/** + * Function that synthesizes accessor methods. + * Function is memoized so accessors are cached (up to 1000). + * + * @param {String} path Model/ModelPath access path + * @param {Array} parsedPath array of path nodes + * @return {Object[Function]} + */ +var synthesizePathMethods = _.memoize(_synthesizePathMethods, undefined, 1000); + +function _synthesizePathMethods(path, parsedPath) { + var methods = _.mapKeys(synthesizers, function(synthszr) { + return _synthesize(synthszr, path, parsedPath); + }); + return methods; +} + + +var normalizeSpliceIndex = modelUtils.normalizeSpliceIndex; // used in splice.dot.js + + +function _synthesize(synthesizer, path, parsedPath) { + var method + , methodCode = synthesizer({ + parsedPath: parsedPath, + getPathNodeKey: pathUtils.getPathNodeKey + }); + + try { + eval(methodCode); + } catch (e) { + throw ModelError('ModelPath method compilation error; path: ' + path + ', code: ' + methodCode); + } + + return method; + + + // functions used by methods `set`, `delete` and `splice` (synthesized by template) + function addChangeMessage(messages, messagesHash, msg) { + messages.push(msg); + messagesHash[msg.path] = msg; + } + + function addTreeChangesMessages(messages, messagesHash, rootPath, oldValue, newValue) { + var oldIsTree = valueIsTree(oldValue) + , newIsTree = valueIsTree(newValue); + + if (newIsTree) + addMessages(messages, messagesHash, rootPath, newValue, 'added', 'newValue'); + + if (oldIsTree) + addMessages(messages, messagesHash, rootPath, oldValue, 'removed', 'oldValue'); + } + + function addMessages(messages, messagesHash, rootPath, obj, msgType, valueProp) { + _addMessages(rootPath, obj); + + + function _addMessages(rootPath, obj) { + if (Array.isArray(obj)) { + var pathSyntax = rootPath + '[$$]'; + obj.forEach(function(value, index) { + addMessage(value, index, pathSyntax); + }); + } else { + var pathSyntax = rootPath + '.$$'; + _.eachKey(obj, function(value, key) { + addMessage(value, key, pathSyntax); + }); + } + } + + function addMessage(value, key, pathSyntax) { + var path = pathSyntax.replace('$$', key) + , existingMsg = messagesHash[path]; + + if (existingMsg) { + if (existingMsg.type == msgType) + logger.error('setter error: same message type posted on the same path'); + else { + existingMsg.type = 'changed'; + existingMsg[valueProp] = value; + } + } else { + var msg = { path: path, type: msgType }; + msg[valueProp] = value; + addChangeMessage(messages, messagesHash, msg); + } + + if (valueIsTree(value)) + _addMessages(path, value); + } + } + + function cloneTree(value) { + return valueIsNormalObject(value) + ? _.deepClone(value) + : value; + } + + function protectValue(value) { + return ! valueIsNormalObject(value) + ? value + : Array.isArray(value) + ? value.slice() + : Object.create(value); + } + + function valueIsTree(value) { + return valueIsNormalObject(value) + && Object.keys(value).length; + } + + function valueIsNormalObject(value) { + return value != null + && typeof value == "object" + && ! (value instanceof Date) + && ! (value instanceof RegExp); + } + + function addBatchIdsToMessage(msg, batchId, msgId) { + _.defineProperties(msg, { + __batch_id: batchId, + __msg_id: msgId + }); + } +} + + +/** + * Exports `synthesize` function with the following: + * + * - .modelMethods.set - `set` method for Model + * - .modelMethods.del - `del` method for Model + * - .modelMethods.splice - `splice` method for Model + */ +module.exports = synthesizePathMethods; + +var modelMethods = _.mapKeys(modelSynthesizers, function(synthesizer) { + return _synthesize(synthesizer, '', []); +}); + +synthesizePathMethods.modelMethods = modelMethods; + +},{"../../util/logger":137,"../change_data":126,"../model_utils":131,"../path_utils":133,"dot":140,"fs":113,"mol-proto":141}],135:[function(require,module,exports){ +arguments[4][90][0].apply(exports,arguments) +},{"../config":118,"mol-proto":141}],136:[function(require,module,exports){ +'use strict'; + +/** + * `milo.util` + */ +var util = { + logger: require('./logger'), + check: require('./check'), +}; + +module.exports = util; + +},{"./check":135,"./logger":137}],137:[function(require,module,exports){ +arguments[4][102][0].apply(exports,arguments) +},{"./logger_class":138}],138:[function(require,module,exports){ +arguments[4][103][0].apply(exports,arguments) +},{"mol-proto":141}],139:[function(require,module,exports){ +module.exports=require(114) +},{}],140:[function(require,module,exports){ +module.exports=require(115) +},{"./doT":139,"fs":113}],141:[function(require,module,exports){ 'use strict'; var utils = require('./utils'); @@ -17029,7 +19032,7 @@ if (typeof module == 'object' && module.exports) // export for node/browserify module.exports = Proto; -},{"./proto_array":118,"./proto_function":119,"./proto_number":120,"./proto_object":121,"./proto_prototype":122,"./proto_string":123,"./proto_util":124,"./utils":125}],118:[function(require,module,exports){ +},{"./proto_array":142,"./proto_function":143,"./proto_number":144,"./proto_object":145,"./proto_prototype":146,"./proto_string":147,"./proto_util":148,"./utils":149}],142:[function(require,module,exports){ 'use strict'; var __ = require('./proto_object') @@ -17263,7 +19266,7 @@ function deepForEach(callback, thisArg) { } } -},{"./proto_object":121,"./utils":125}],119:[function(require,module,exports){ +},{"./proto_object":145,"./utils":149}],143:[function(require,module,exports){ 'use strict'; @@ -17656,7 +19659,7 @@ function not() { }; } -},{"./proto_util":124,"./utils":125}],120:[function(require,module,exports){ +},{"./proto_util":148,"./utils":149}],144:[function(require,module,exports){ 'use strict'; /** @@ -17677,7 +19680,7 @@ function isNumeric() { return !isNaN(parseFloat(this)) && isFinite(this); }; -},{}],121:[function(require,module,exports){ +},{}],145:[function(require,module,exports){ 'use strict'; @@ -18312,7 +20315,7 @@ function isNot(obj) { return !isEqual.call(this, obj); } -},{"./utils":125}],122:[function(require,module,exports){ +},{"./utils":149}],146:[function(require,module,exports){ 'use strict'; /** @@ -18443,7 +20446,7 @@ function newApply(args) { return new (Function.prototype.bind.apply(this, args)); } -},{"./proto_function":119,"./proto_object":121}],123:[function(require,module,exports){ +},{"./proto_function":143,"./proto_object":145}],147:[function(require,module,exports){ 'use strict'; @@ -18630,7 +20633,7 @@ function unPrefix(str) { return this.replace(str, ''); } -},{"./proto_object":121}],124:[function(require,module,exports){ +},{"./proto_object":145}],148:[function(require,module,exports){ 'use strict'; /** @@ -18762,7 +20765,7 @@ function compareProperty() { */ function noop() {} -},{}],125:[function(require,module,exports){ +},{}],149:[function(require,module,exports){ 'use strict'; var utils = module.exports = { @@ -18827,6 +20830,24 @@ function makeFindMethod(eachMethod, findWhat) { } } +},{}],150:[function(require,module,exports){ +arguments[4][141][0].apply(exports,arguments) +},{"./proto_array":151,"./proto_function":152,"./proto_number":153,"./proto_object":154,"./proto_prototype":155,"./proto_string":156,"./proto_util":157,"./utils":158}],151:[function(require,module,exports){ +arguments[4][142][0].apply(exports,arguments) +},{"./proto_object":154,"./utils":158}],152:[function(require,module,exports){ +module.exports=require(143) +},{"./proto_util":157,"./utils":158}],153:[function(require,module,exports){ +module.exports=require(144) +},{}],154:[function(require,module,exports){ +module.exports=require(145) +},{"./utils":158}],155:[function(require,module,exports){ +arguments[4][146][0].apply(exports,arguments) +},{"./proto_function":152,"./proto_object":154}],156:[function(require,module,exports){ +arguments[4][147][0].apply(exports,arguments) +},{"./proto_object":154}],157:[function(require,module,exports){ +module.exports=require(148) +},{}],158:[function(require,module,exports){ +module.exports=require(149) },{}]},{},[72]) -//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvYWJzdHJhY3QvZmFjZXQuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2Fic3RyYWN0L2ZhY2V0ZWRfb2JqZWN0LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9hYnN0cmFjdC9taXhpbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvYWJzdHJhY3QvcmVnaXN0cnkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2F0dHJpYnV0ZXMvYV9iaW5kLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9hdHRyaWJ1dGVzL2FfY2xhc3MuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2F0dHJpYnV0ZXMvYV9sb2FkLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9hdHRyaWJ1dGVzL2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9iaW5kZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NsYXNzZXMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbW1hbmQvYWN0aW9uc19oaXN0b3J5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21tYW5kL2NtZF9yZWdpc3RyeS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tbWFuZC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tbWFuZC90cmFuc2FjdGlvbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tbWFuZC90cmFuc2FjdGlvbl9oaXN0b3J5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfY2xhc3MuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9Db250YWluZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldHMvRGF0YS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9Eb20uanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldHMvRHJhZy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9Ecm9wLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL0V2ZW50cy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9GcmFtZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9JdGVtLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL0xpc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldHMvTW9kZWxGYWNldC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9PcHRpb25zLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL1RlbXBsYXRlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL1RyYW5zZmVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfaW5mby5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX3JlZ2lzdHJ5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfdXRpbHMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY2xhc3Nlcy9WaWV3LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL21zZ19hcGkvZGF0YS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9tc2dfYXBpL2RlX2RhdGEuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvbXNnX2FwaS9kcm9wLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL21zZ19zcmMvZG9tX2V2ZW50cy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9tc2dfc3JjL2ZyYW1lLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3Njb3BlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0J1dHRvbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9Db21iby5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9Db21ib0xpc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvRGF0ZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9Ecm9wVGFyZ2V0LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0ZvbGRUcmVlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0dyb3VwLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0h5cGVybGluay5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9JbWFnZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9JbnB1dC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9JbnB1dExpc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvTGlzdC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9MaXN0SXRlbS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9SYWRpb0dyb3VwLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL1NlbGVjdC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9TdXBlckNvbWJvLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL1RleHQuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvVGV4dGFyZWEuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvVGltZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9XcmFwcGVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL2Jvb3RzdHJhcC9BbGVydC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9ib290c3RyYXAvRGlhbG9nLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL2Jvb3RzdHJhcC9Ecm9wZG93bi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29uZmlnLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9sb2FkZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21lc3Nlbmdlci9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWVzc2VuZ2VyL21fYXBpLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tZXNzZW5nZXIvbV9hcGlfcnguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21lc3Nlbmdlci9tX3NvdXJjZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWVzc2VuZ2VyL21zbmdyX3NvdXJjZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWlsby5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWluZGVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tb2RlbC9jaGFuZ2VfZGF0YS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbW9kZWwvY29ubmVjdG9yLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tb2RlbC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbW9kZWwvbV9tc2dfYXBpLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tb2RlbC9tX3BhdGguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21vZGVsL21vZGVsX3V0aWxzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tb2RlbC9wYXRoX21zZ19hcGkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21vZGVsL3BhdGhfdXRpbHMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21vZGVsL3N5bnRoZXNpemUvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3JlZ2lzdHJ5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9zZXJ2aWNlcy9kZV9jb25zdHJzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9zZXJ2aWNlcy9kb21fc291cmNlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9zZXJ2aWNlcy9tYWlsL2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9zZXJ2aWNlcy9tYWlsL21haWxfYXBpLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9zZXJ2aWNlcy9tYWlsL21haWxfc291cmNlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9zZXJ2aWNlcy93aW5kb3cuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3VzZV9jb21wb25lbnRzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91c2VfZmFjZXRzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL2NoZWNrLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL2NvbXBvbmVudF9uYW1lLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL2NvdW50LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL2NyZWF0ZV9jb21wb25lbnRfY2xhc3MuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvZG9tLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL2RvbV9saXN0ZW5lcnMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvZG9tcmVhZHkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvZHJhZ2Ryb3AuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvZXJyb3IuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvZnJhZ21lbnQuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvanNvbl9wYXJzZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9sb2dnZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvbG9nZ2VyX2NsYXNzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL3JlcXVlc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvc2VsZWN0aW9uL2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL3N0b3JhZ2UvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvc3RvcmFnZS9tc2dfc3JjLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL3dlYnNvY2tldC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC93ZWJzb2NrZXQvbXNnX2FwaS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC93ZWJzb2NrZXQvbXNnX3NyYy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvYmFzZTMyL2xpYi9iYXNlMzIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9mcy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvZG90L2RvVC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvZG90L2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX2FycmF5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX2Z1bmN0aW9uLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX251bWJlci5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbW9sLXByb3RvL2xpYi9wcm90b19vYmplY3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG9fcHJvdG90eXBlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX3N0cmluZy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbW9sLXByb3RvL2xpYi9wcm90b191dGlsLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3V0aWxzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9NQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25OQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6NUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdk5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5YUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzltQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6cEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1WkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3puQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZhY2V0O1xuXG5cbi8qKlxuICogYG1pbG8uY2xhc3Nlcy5GYWNldGBcbiAqIEJhc2UgRmFjZXQgY2xhc3MgaXMgYW4gYW5jZXN0b3Igb2YgW0NvbXBvbmVudEZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXQuanMuaHRtbCkgY2xhc3MsIHRoZSBtYWluIGJ1aWxkaW5nIGJsb2NrIGluIG1pbG8uXG4gKiBcbiAqIEBwYXJhbSB7RmFjZXRlZE9iamVjdH0gb3duZXIgYW4gaW5zdGFuY2Ugb2YgRmFjZXRlZE9iamVjdCBzdWJjbGFzcyB0aGF0IHN0b3JlcyB0aGUgZmFjZXQgb24gaXRzIHByb3BlcnR5ICB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgYG5hbWVgIHByb3BlcnR5IG9mIGZhY2V0XG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIG9wdGlvbmFsIGZhY2V0IGNvbmZpZ3VyYXRpb24sIHVzZWQgaW4gc3ViY2xhc3Nlc1xuICovXG5mdW5jdGlvbiBGYWNldChvd25lciwgY29uZmlnKSB7XG4gICAgdGhpcy5uYW1lID0gXy5maXJzdExvd2VyQ2FzZSh0aGlzLmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgIHRoaXMub3duZXIgPSBvd25lcjtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICB0aGlzLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG4vKipcbiAqIGBpbml0YCBtZXRob2Qgb2Ygc3ViY2xhc3Mgd2lsbCBiZSBjYWxsZWQgYnkgRmFjZXQgY29uc3RydWN0b3IuXG4gKi9cbl8uZXh0ZW5kUHJvdG8oRmFjZXQsIHtcbiAgICBpbml0OiBmdW5jdGlvbigpIHt9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgRmFjZXQgPSByZXF1aXJlKCcuL2ZhY2V0JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2hcbiAgICAsIEZhY2V0RXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuRmFjZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gRmFjZXRlZE9iamVjdDtcblxuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuRmFjZXRlZE9iamVjdGBcbiAqIENvbXBvbmVudCBjbGFzcyBpcyBiYXNlZCBvbiBhbiBhYnN0cmFjdCBgYGBGYWNldGVkT2JqZWN0YGBgIGNsYXNzLiBUaGlzIGNsYXNzIGNhbiBiZSB1c2VkIGluIGFueSBzaXR1YXRpb24gd2hlcmUgb2JqZWN0cyBjYW4gYmUgcmVwcmVzZW50ZWQgdmlhIGNvbGxlY3Rpb24gb2YgZmFjZXRzIChhIGZhY2V0IGlzIGFuIG9iamVjdCBvZiBhIGNlcnRhaW4gY2xhc3MsIGl0IGhvbGRzIGl0cyBvd24gY29uZmlndXJhdGlvbiwgZGF0YSBhbmQgbWV0aG9kcykuXG4gKiBJbiBhIHdheSwgXCJmYWNldHMgcGF0dGVyblwiIGlzIGFuIGludmVyc2lvbiBvZiBcImFkYXB0ZXIgcGF0dGVyblwiIC0gd2hpbGUgdGhlIGxhdHRlciBhbGxvd3MgZmluZGluZyBhIGNsYXNzL21ldGhvZHMgdGhhdCBoYXMgc3BlY2lmaWMgZnVuY3Rpb25hbGl0eSwgZmFjZXRlZCBvYmplY3QgaXMgc2ltcGx5IGNvbnN0cnVjdGVkIHRvIGhhdmUgdGhlc2UgZnVuY3Rpb25hbGl0aWVzLlxuICogV2l0aCB0aGlzIGFyY2hpdGVjdHVyZSBpdCBpcyBwb3NzaWJsZSB0byBjcmVhdGUgYSB2aXJ0dWFsbHkgdW5saW1pdGVkIG51bWJlciBvZiBjb21wb25lbnQgY2xhc3NlcyB3aXRoIGEgdmVyeSBsaW1pdGVkIG51bWJlciBvZiBidWlsZGluZyBibG9ja3Mgd2l0aG91dCBoYXZpbmcgYW55IGhpZXJhcmNoeSBvZiBjbGFzc2VzIC0gYWxsIGNvbXBvbmVudHMgaW5oZXJpdCBkaXJlY3RseSBmcm9tIENvbXBvbmVudCBjbGFzcy5cbiAqXG4gKiBUaGlzIGNvbnN0cnVjdG9yIHNob3VsZCBiZSBjYWxsZWQgYnkgYWxsIHN1YmNsYXNzZXMgY29uc3RydWN0b3IgKGl0IHdpbGwgaGFwcGVuIGF1dG9tYXRpY2FsbHkgaWYgYSBzdWJjbGFzcyBpcyBjcmVhdGVkIHdpdGggYF8uY3JlYXRlU3ViY2xhc3NgKS5cbiAqXG4gKiBAcmV0dXJuIHtGYWNldGVkT2JqZWN0fVxuICovXG5mdW5jdGlvbiBGYWNldGVkT2JqZWN0KCkge1xuICAgIC8vIHRoaXMuZmFjZXRzQ29uZmlnIGFuZCB0aGlzLmZhY2V0c0NsYXNzZXMgd2VyZSBzdG9yZWQgb24gYSBzcGVjaWZpYyBjbGFzcyBwcm90b3R5cGVcbiAgICAvLyB3aGVuIHRoZSBjbGFzcyB3YXMgY3JlYXRlZCBieSBGYWNldGVkT2JqZWN0LmNyZWF0ZUZhY2V0ZWRDbGFzc1xuICAgIHZhciBmYWNldHNDb25maWcgPSB0aGlzLmZhY2V0c0NvbmZpZyB8fCB7fTtcblxuICAgIHZhciBmYWNldHNEZXNjcmlwdG9ycyA9IHt9XG4gICAgICAgICwgZmFjZXRzID0ge307XG5cbiAgICAvLyBGYWNldGVkT2JqZWN0IGNsYXNzIGl0c2VsZiBpcyBub3QgbWVhbnQgdG8gYmUgaW5zdGFudGlhdGVkIC0gaXQgaGFzIG5vIGZhY2V0c1xuICAgIC8vIEl0IG1heSBjaGFuZ2UsIGFzIGFkZGluZyBmYWNldHMgaXMgcG9zc2libGUgdG8gaW5zdGFuY2VzXG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IgPT0gRmFjZXRlZE9iamVjdCkgICAgICBcbiAgICAgICAgdGhyb3cgbmV3IEZhY2V0RXJyb3IoJ0ZhY2V0ZWRPYmplY3QgaXMgYW4gYWJzdHJhY3QgY2xhc3MsIGNhblxcJ3QgYmUgaW5zdGFudGlhdGVkJyk7XG5cbiAgICAvLyBpbnN0YW50aWF0ZSBjbGFzcyBmYWNldHNcbiAgICBpZiAodGhpcy5mYWNldHNDbGFzc2VzKVxuICAgICAgICBfLmVhY2hLZXkodGhpcy5mYWNldHNDbGFzc2VzLCBpbnN0YW50aWF0ZUZhY2V0LCB0aGlzLCB0cnVlKTtcblxuICAgIC8vIGFkZCBmYWNldHMgdG8gdGhlIGNsYXNzIGFzIHByb3BlcnRpZXMgdW5kZXIgdGhlaXIgb3duIG5hbWVcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLCBmYWNldHNEZXNjcmlwdG9ycyk7XG5cbiAgICAvLyBzdG9yZSBhbGwgZmFjZXRzIG9uIGBmYWNldHNgIHByb3BlcnR5IHNvIHRoYXQgdGhleSBjYW4gYmUgZW51bWVyYXRlZFxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ2ZhY2V0cycsIGZhY2V0cyk7ICAgXG5cbiAgICAvLyBjYWxsIGBpbml0YG1ldGhvZCBpZiBpdCBpcyBkZWZpbmVkIGluIHN1YmNsYXNzXG4gICAgaWYgKHRoaXMuaW5pdClcbiAgICAgICAgdGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvLyBpbnN0YW50aWF0ZSBmYWNldCB3aXRoIGEgZ2l2ZW4gY2xhc3MgKEZhY2V0Q2xhc3MpIGFuZCBuYW1lIChmYWNldE5hbWUpXG4gICAgZnVuY3Rpb24gaW5zdGFudGlhdGVGYWNldChGYWNldENsYXNzLCBmYWNldE5hbWUpIHtcbiAgICAgICAgLy8gZ2V0IGZhY2V0IGNvbmZpZ3VyYXRpb25cbiAgICAgICAgdmFyIGZjdENvbmZpZyA9IGZhY2V0c0NvbmZpZ1tmYWNldE5hbWVdO1xuXG4gICAgICAgIC8vIGluc3RhdGlhdGUgZmFjZXRzXG4gICAgICAgIGZhY2V0c1tmYWNldE5hbWVdID0gbmV3IEZhY2V0Q2xhc3ModGhpcywgZmN0Q29uZmlnKTtcblxuICAgICAgICAvLyBhZGQgZmFjZXQgdG8gcHJvcGVydHkgZGVzY3JpcHRvcnNcbiAgICAgICAgZmFjZXRzRGVzY3JpcHRvcnNbZmFjZXROYW1lXSA9IHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB2YWx1ZTogZmFjZXRzW2ZhY2V0TmFtZV1cbiAgICAgICAgfTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiAjIyMjRmFjZXRlZE9iamVjdCBjbGFzcyBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2NyZWF0ZUZhY2V0ZWRDbGFzc10oI0ZhY2V0ZWRPYmplY3QkJGNyZWF0ZUZhY2V0ZWRDbGFzcylcbiAqIC0gW2hhc0ZhY2V0XSgjRmFjZXRlZE9iamVjdCQkaGFzRmFjZXQpXG4gKi9cbl8uZXh0ZW5kKEZhY2V0ZWRPYmplY3QsIHtcbiAgICBjcmVhdGVGYWNldGVkQ2xhc3M6IEZhY2V0ZWRPYmplY3QkJGNyZWF0ZUZhY2V0ZWRDbGFzcyxcbiAgICBoYXNGYWNldDogRmFjZXRlZE9iamVjdCQkaGFzRmFjZXQsXG4gICAgZ2V0RmFjZXRDb25maWc6IEZhY2V0ZWRPYmplY3QkJGdldEZhY2V0Q29uZmlnXG59KTtcblxuXG4vKipcbiAqICMjIyNGYWNldGVkT2JqZWN0IGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbYWRkRmFjZXRdKCNGYWNldGVkT2JqZWN0JGFkZEZhY2V0KVxuICovXG5fLmV4dGVuZFByb3RvKEZhY2V0ZWRPYmplY3QsIHtcbiAgICBhZGRGYWNldDogRmFjZXRlZE9iamVjdCRhZGRGYWNldFxufSk7XG5cblxuLyoqXG4gKiBGYWNldGVkT2JqZWN0IGluc3RhbmNlIG1ldGhvZC5cbiAqIEFkZHMgYSBmYWNldCB0byB0aGUgaW5zdGFuY2Ugb2YgRmFjZXRlZE9iamVjdCBzdWJjbGFzcy5cbiAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgdGhlIGZhY2V0IHRoYXQgd2FzIGNyZWF0ZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gRmFjZXRDbGFzcyBmYWNldCBjbGFzcyBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtPYmplY3R9IGZhY2V0Q29uZmlnIG9wdGlvbmFsIGZhY2V0IGNvbmZpZ3VyYXRpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSBmYWNldE5hbWUgb3B0aW9uYWwgZmFjZXQgbmFtZSwgRmFjZXRDbGFzcy5uYW1lIHdpbGwgYmUgdXNlZCBpZiBmYWNldE5hbWUgaXMgbm90IHBhc3NlZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gdGhyb3dPbkVycm9ycyBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gZXJyb3JzIHdpbGwgb25seSBiZSBsb2dnZWQgdG8gY29uc29sZS4gVHJ1ZSBieSBkZWZhdWx0LlxuICogQHJldHVybiB7RmFjZXR9XG4gKi9cbmZ1bmN0aW9uIEZhY2V0ZWRPYmplY3QkYWRkRmFjZXQoRmFjZXRDbGFzcywgZmFjZXRDb25maWcsIGZhY2V0TmFtZSwgdGhyb3dPbkVycm9ycykge1xuICAgIGNoZWNrKEZhY2V0Q2xhc3MsIEZ1bmN0aW9uKTtcbiAgICBjaGVjayhmYWNldE5hbWUsIE1hdGNoLk9wdGlvbmFsKFN0cmluZykpO1xuXG4gICAgLy8gZmlyc3QgbGV0dGVyIG9mIGZhY2V0IG5hbWUgc2hvdWxkIGJlIGxvd2VyY2FzZVxuICAgIGZhY2V0TmFtZSA9IF8uZmlyc3RMb3dlckNhc2UoZmFjZXROYW1lIHx8IEZhY2V0Q2xhc3MubmFtZSk7XG5cbiAgICAvLyBnZXQgZmFjZXRzIGRlZmluZWQgaW4gY2xhc3NcbiAgICB2YXIgcHJvdG9GYWNldHMgPSB0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZS5mYWNldHNDbGFzc2VzO1xuXG4gICAgLy8gY2hlY2sgdGhhdCB0aGlzIGZhY2V0TmFtZSB3YXMgbm90IGFscmVhZHkgdXNlZCBpbiB0aGUgY2xhc3NcbiAgICBpZiAocHJvdG9GYWNldHMgJiYgcHJvdG9GYWNldHNbZmFjZXROYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IEZhY2V0RXJyb3IoJ2ZhY2V0ICcgKyBmYWNldE5hbWUgKyAnIGlzIGFscmVhZHkgcGFydCBvZiB0aGUgY2xhc3MgJyArIHRoaXMuY29uc3RydWN0b3IubmFtZSk7XG5cbiAgICAvLyBjaGVjayB0aGF0IHRoaXMgZmFjZU5hbWUgZG9lcyBub3QgYWxyZWFkeSBleGlzdCBvbiB0aGUgZmFjZXRlZCBvYmplY3RcbiAgICBpZiAodGhpc1tmYWNldE5hbWVdKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gJ2ZhY2V0ICcgKyBmYWNldE5hbWUgKyAnIGlzIGFscmVhZHkgcHJlc2VudCBpbiBvYmplY3QnO1xuICAgICAgICBpZiAodGhyb3dPbkVycm9ycyA9PT0gZmFsc2UpXG4gICAgICAgICAgICByZXR1cm4gbG9nZ2VyLmVycm9yKCdGYWNldGVkT2JqZWN0IGFkZEZhY2V0OiAnLCBtZXNzYWdlKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEZhY2V0RXJyb3IobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLy8gaW5zdGFudGlhdGUgdGhlIGZhY2V0XG4gICAgdmFyIG5ld0ZhY2V0ID0gdGhpcy5mYWNldHNbZmFjZXROYW1lXSA9IG5ldyBGYWNldENsYXNzKHRoaXMsIGZhY2V0Q29uZmlnKTtcblxuICAgIC8vIGFkZCBmYWNldCB0byBmYWNldGVkIG9iamVjdFxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgZmFjZXROYW1lLCBuZXdGYWNldCwgXy5FTlVNKTtcblxuICAgIHJldHVybiBuZXdGYWNldDtcbn1cblxuXG4vKipcbiAqIEZhY2V0ZWRPYmplY3QgY2xhc3MgbWV0aG9kXG4gKiBSZXR1cm5zIHJlZmVyZW5jZSB0byB0aGUgZmFjZXQgY2xhc3MgaWYgdGhlIGZhY2V0IHdpdGggYGZhY2V0TmFtZWAgaXMgcGFydCBvZiB0aGUgY2xhc3MsIGB1bmRlZmluZWRgIG90aGVyd2lzZS4gSWYgc3ViY2xhc3MgaXMgY3JlYXRlZCB1c2luZyBfLmNyZWF0ZVN1YmNsYXNzIChhcyBpdCBzaG91bGQgYmUpIGl0IHdpbGwgYWxzbyBoYXZlIHRoaXMgbWV0aG9kLlxuICogXG4gKiBAcGFyYW0ge1N1YmNsYXNzKEZhY2V0ZWRPYmplY3QpfSB0aGlzIHRoaXMgaW4gdGhpcyBtZXRob2QgcmVmZXJzIHRvIEZhY2V0ZWRPYmplY3QgKG9yIGl0cyBzdWJjbGFzcykgdGhhdCBjYWxscyB0aGlzIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IGZhY2V0TmFtZVxuICogQHJldHVybiB7U3ViY2xhc3MoRmFjZXQpfHVuZGVmaW5lZH0gXG4gKi9cbmZ1bmN0aW9uIEZhY2V0ZWRPYmplY3QkJGhhc0ZhY2V0KGZhY2V0TmFtZSkge1xuICAgIC8vIHRoaXMgcmVmZXJzIHRvIHRoZSBGYWNldGVkT2JqZWN0IGNsYXNzIChvciBzdWJjbGFzcyksIG5vdCBpbnN0YW5jZVxuICAgIHZhciBwcm90b0ZhY2V0cyA9IHRoaXMucHJvdG90eXBlLmZhY2V0c0NsYXNzZXM7XG4gICAgcmV0dXJuIHByb3RvRmFjZXRzICYmIHByb3RvRmFjZXRzW2ZhY2V0TmFtZV07XG59XG5cbi8qKlxuICogRmFjZXRlZE9iamVjdCBjbGFzcyBtZXRob2RcbiAqIFJldHVybiB0aGUgY29uZmlndXJhdGlvbiBvZiBhIGZhY2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gZmFjZXROYW1lIHRoZSBmYWNldCB3aGljaCBjb25maWcgc2hvdWxkIGJlIHJldHJpZXZlZFxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgY29uZmlndXJhdGlvbiBvYmplY3QgdGhhdCB3YXMgcGFzc2VkIHRvIHRoZSBmYWNldFxuICovXG5mdW5jdGlvbiBGYWNldGVkT2JqZWN0JCRnZXRGYWNldENvbmZpZyhmYWNldE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNGYWNldChmYWNldE5hbWUpID8gdGhpcy5wcm90b3R5cGUuZmFjZXRzQ29uZmlnW2ZhY2V0TmFtZV0gOiBudWxsO1xufVxuXG5cbi8qKlxuICogRmFjZXRlZE9iamVjdCBjbGFzcyBtZXRob2RcbiAqIENsYXNzIGZhY3RvcnkgdGhhdCBjcmVhdGVzIGNsYXNzZXMgKGNvbnN0cnVjdG9yIGZ1bmN0aW9ucykgZnJvbSB0aGUgbWFwcyBvZiBmYWNldHMgYW5kIHRoZWlyIGNvbmZpZ3VyYXRpb25zLlxuICogQ3JlYXRlZCBjbGFzcyB3aWxsIGJlIHN1YmNsYXNzIG9mIGBGYWNldGVkT2JqZWN0YC5cbiAqXG4gKiBAcGFyYW0ge1N1YmNsYXNzKEZhY2V0ZWRPYmplY3QpfSB0aGlzIHRoaXMgaW4gdGhpcyBtZXRob2QgcmVmZXJzIHRvIEZhY2V0ZWRPYmplY3QgKG9yIGl0cyBzdWJjbGFzcykgdGhhdCBjYWxscyB0aGlzIG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgY2xhc3MgbmFtZSAod2lsbCBiZSBmdW5jdGlvbiBuYW1lIG9mIGNsYXNzIGNvbnN0cnVjdG9yIGZ1bmN0aW9uKVxuICogQHBhcmFtIHtPYmplY3RbU3ViY2xhc3MoRmFjZXQpXX0gZmFjZXRzQ2xhc3NlcyBtYXAgb2YgY2xhc3NlcyBvZiBmYWNldHMgdGhhdCB3aWxsIGNvbnN0aXR1dGUgdGhlIGNyZWF0ZWQgY2xhc3NcbiAqIEBwYXJhbSB7T2JqZWN0W09iamVjdF19IGZhY2V0c0NvbmZpZyBtYXAgb2YgZmFjZXRzIGNvbmZpZ3VyYXRpb24sIHNob3VsZCBoYXZlIHRoZSBzYW1lIGtleXMgYXMgdGhlIG1hcCBvZiBjbGFzc2VzLiBTb21lIGZhY2V0cyBtYXkgbm90IGhhdmUgY29uZmlndXJhdGlvbiwgYnV0IHRoZSBjb25maWd1cmF0aW9uIGZvciBhIGZhY2V0IHRoYXQgaXMgbm90IGluY2x1ZGVkIGluIGZhY2V0c0NsYXNzZXMgd2lsbCB0aHJvdyBhbiBleGNlcHRpb25cbiAqIEByZXR1cm4ge1N1YmNsYXNzKEZhY2V0ZWRPYmplY3QpfVxuICovXG5mdW5jdGlvbiBGYWNldGVkT2JqZWN0JCRjcmVhdGVGYWNldGVkQ2xhc3MobmFtZSwgZmFjZXRzQ2xhc3NlcywgZmFjZXRzQ29uZmlnKSB7XG4gICAgY2hlY2sobmFtZSwgU3RyaW5nKTtcbiAgICBjaGVjayhmYWNldHNDbGFzc2VzLCBNYXRjaC5PcHRpb25hbChNYXRjaC5PYmplY3RIYXNoKE1hdGNoLlN1YmNsYXNzKEZhY2V0LCB0cnVlKSkpKTtcbiAgICBjaGVjayhmYWNldHNDb25maWcsIE1hdGNoLk9wdGlvbmFsKE9iamVjdCkpO1xuXG4gICAgLy8gdGhyb3cgZXhjZXB0aW9uIGlmIGNvbmZpZyBwYXNzZWQgZm9yIGZhY2V0IGZvciB3aGljaCB0aGVyZSBpcyBubyBjbGFzc1xuICAgIGlmIChmYWNldHNDb25maWcpXG4gICAgICAgIF8uZWFjaEtleShmYWNldHNDb25maWcsIGZ1bmN0aW9uKGZjdENvbmZpZywgZmN0TmFtZSkge1xuICAgICAgICAgICAgaWYgKCEgZmFjZXRzQ2xhc3Nlcy5oYXNPd25Qcm9wZXJ0eShmY3ROYW1lKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRmFjZXRFcnJvcignY29uZmlndXJhdGlvbiBmb3IgZmFjZXQgKCcgKyBmY3ROYW1lICsgJykgcGFzc2VkIHRoYXQgaXMgbm90IGluIGNsYXNzJyk7XG4gICAgICAgIH0pO1xuXG4gICAgLy8gY3JlYXRlIHN1YmNsYXNzIG9mIHRoZSBjdXJyZW50IGNsYXNzICh0aGlzIHJlZmVycyB0byB0aGUgY2xhc3MgdGhhdCBjYWxscyB0aGlzIG1ldGhvZClcbiAgICB2YXIgRmFjZXRlZENsYXNzID0gXy5jcmVhdGVTdWJjbGFzcyh0aGlzLCBuYW1lLCB0cnVlKTtcblxuICAgIC8vIGdldCBmYWNldHMgY2xhc3NlcyBhbmQgY29uZmlndXJhdGlvbnMgZnJvbSBwYXJlbnQgY2xhc3NcbiAgICBmYWNldHNDbGFzc2VzID0gYWRkSW5oZXJpdGVkRmFjZXRzKHRoaXMsIGZhY2V0c0NsYXNzZXMsICdmYWNldHNDbGFzc2VzJyk7XG4gICAgZmFjZXRzQ29uZmlnID0gYWRkSW5oZXJpdGVkRmFjZXRzKHRoaXMsIGZhY2V0c0NvbmZpZywgJ2ZhY2V0c0NvbmZpZycpO1xuXG4gICAgLy8gc3RvcmUgZmFjZXRzIGNsYXNzZXMgYW5kIGNvbmZpZ3VyYXRpb25zIG9mIGNsYXNzIHByb3RvdHlwZVxuICAgIF8uZXh0ZW5kUHJvdG8oRmFjZXRlZENsYXNzLCB7XG4gICAgICAgIGZhY2V0c0NsYXNzZXM6IGZhY2V0c0NsYXNzZXMsXG4gICAgICAgIGZhY2V0c0NvbmZpZzogZmFjZXRzQ29uZmlnXG4gICAgfSk7XG5cbiAgICByZXR1cm4gRmFjZXRlZENsYXNzO1xuXG5cbiAgICBmdW5jdGlvbiBhZGRJbmhlcml0ZWRGYWNldHMoc3VwZXJDbGFzcywgZmFjZXRzSW5mbywgZmFjZXRzSW5mb05hbWUpIHtcbiAgICAgICAgdmFyIGluaGVyaXRlZEZhY2V0c0luZm8gPSBzdXBlckNsYXNzLnByb3RvdHlwZVtmYWNldHNJbmZvTmFtZV07XG4gICAgICAgIGlmIChpbmhlcml0ZWRGYWNldHNJbmZvKVxuICAgICAgICAgICAgcmV0dXJuIF8oaW5oZXJpdGVkRmFjZXRzSW5mbylcbiAgICAgICAgICAgICAgICAgICAgLmNsb25lKClcbiAgICAgICAgICAgICAgICAgICAgLmV4dGVuZChmYWNldHNJbmZvIHx8IHt9KS5fKCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBmYWNldHNJbmZvO1xuICAgIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBNaXhpbkVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLk1peGluXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1peGluO1xuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuTWl4aW5gIC0gYW4gYWJzdHJhY3QgTWl4aW4gY2xhc3MuXG4gKiBDYW4gYmUgc3ViY2xhc3NlZCB1c2luZzpcbiAqIGBgYFxuICogdmFyIE15TWl4aW4gPSBfLmNyZWF0ZVN1YmNsYXNzKG1pbG8uY2xhc3Nlcy5NaXhpbiwgJ015TWl4aW4nKTtcbiAqIGBgYFxuICpcbiAqIE1peGluIHBhdHRlcm4gaXMgYWxzbyB1c2VkLCBidXQgTWl4aW4gaW4gbWlsbyBpcyBpbXBsZW1lbnRlZCBhcyBhIHNlcGFyYXRlIG9iamVjdCB0aGF0IGlzIHN0b3JlZCBvbiB0aGUgcHJvcGVydHkgb2YgdGhlIGhvc3Qgb2JqZWN0IGFuZCBjYW4gY3JlYXRlIHByb3h5IG1ldGhvZHMgb24gdGhlIGhvc3Qgb2JqZWN0IGlmIHJlcXVpcmVkLlxuICogQ2xhc3NlcyBbTWVzc2VuZ2VyXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCkgYW5kIFtNZXNzYWdlU291cmNlXSguLi9tZXNzZW5nZXIvbV9zb3VyY2UuanMuaHRtbCkgYXJlIHN1YmNsYXNzZXMgb2YgTWl4aW4gYWJzdHJhY3QgY2xhc3MuIGB0aGlzYCBpbiBwcm94eSBtZXRob2RzIHJlZmVycyB0byBNaXhpbiBpbnN0YW5jZSwgdGhlIHJlZmVyZW5jZSB0byB0aGUgaG9zdCBvYmplY3QgaXMgYHRoaXMuX2hvc3RPYmplY3RgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IE9wdGlvbmFsIG9iamVjdCB3aGVyZSBhIE1peGluIGluc3RhbmNlIHdpbGwgYmUgc3RvcmVkIG9uLiBJdCBpcyB1c2VkIHRvIHByb3h5IG1ldGhvZHMgYW5kIGFsc28gdG8gZmluZCB0aGUgcmVmZXJlbmNlIHdoZW4gaXQgaXMgbmVlZGVkIGZvciBob3N0IG9iamVjdCBpbXBsZW1lbnRhdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm94eU1ldGhvZHMgT3B0aW9uYWwgbWFwIG9mIHByb3h5IG1ldGhvZCBuYW1lcyBhcyBrZXlzIGFuZCBNaXhpbiBtZXRob2RzIG5hbWVzIGFzIHZhbHVlcywgc28gcHJveGllZCBtZXRob2RzIGNhbiBiZSByZW5hbWVkIHRvIGF2b2lkIG5hbWUtc3BhY2UgY29uZmxpY3RzIGlmIHR3byBkaWZmZXJlbnQgTWl4aW4gaW5zdGFuY2VzIHdpdGggdGhlIHNhbWUgbWV0aG9kIG5hbWVzIGFyZSBwdXQgb24gdGhlIG9iamVjdFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgYWxsIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBpbml0IG1ldGhvZCBvZiBNaXhpbiBzdWJjbGFzcyB0b2dldGhlciB3aXRoIGhvc3RPYmplY3QgYW5kIHByb3h5TWV0aG9kc1xuICogQHJldHVybiB7TWl4aW59XG4gKi9cbmZ1bmN0aW9uIE1peGluKGhvc3RPYmplY3QsIHByb3h5TWV0aG9kcykgeyAvLyAsIG90aGVyIGFyZ3MgLSBwYXNzZWQgdG8gaW5pdCBtZXRob2RcbiAgICBjaGVjayhob3N0T2JqZWN0LCBNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihPYmplY3QsIEZ1bmN0aW9uKSkpO1xuXG4gICAgLy8gc3RvcmUgaG9zdE9iamVjdFxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19ob3N0T2JqZWN0JywgaG9zdE9iamVjdCk7XG5cbiAgICAvLyBwcm94eSBtZXRob2RzIHRvIGhvc3RPYmplY3RcbiAgICBpZiAocHJveHlNZXRob2RzKVxuICAgICAgICB0aGlzLl9jcmVhdGVQcm94eU1ldGhvZHMocHJveHlNZXRob2RzKTtcblxuICAgIC8vIGNhbGxpbmcgaW5pdCBpZiBpdCBpcyBkZWZpbmVkIGluIHRoZSBjbGFzc1xuICAgIGlmICh0aGlzLmluaXQpXG4gICAgICAgIHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogIyMjI01peGluIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKiBUaGVzZSBtZXRob2RzIGFyZSBjYWxsZWQgYnkgY29uc3RydWN0b3IsIHRoZXkgYXJlIG5vdCB0byBiZSBjYWxsZWQgZnJvbSBzdWJjbGFzc2VzLlxuICpcbiAqIC0gW19jcmVhdGVQcm94eU1ldGhvZF0oI19jcmVhdGVQcm94eU1ldGhvZClcbiAqIC0gW19jcmVhdGVQcm94eU1ldGhvZHNdKCNfY3JlYXRlUHJveHlNZXRob2RzKVxuICovXG5fLmV4dGVuZFByb3RvKE1peGluLCB7XG4gICAgX2NyZWF0ZVByb3h5TWV0aG9kOiBfY3JlYXRlUHJveHlNZXRob2QsICAvLyBkZXByZWNhdGVkLCBzaG91bGQgbm90IGJlIHVzZWRcbiAgICBfY3JlYXRlUHJveHlNZXRob2RzOiBfY3JlYXRlUHJveHlNZXRob2RzICAvLyBkZXByZWNhdGVkLCBzaG91bGQgbm90IGJlIHVzZWRcbn0pO1xuXG5cbi8qKlxuICogIyMjI01peGluIGNsYXNzIG1ldGhvZHMjIyMjXG4gKiBUaGVzZSBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBpbiBob3N0IGNsYXNzIGRlY2xhcmF0aW9uLlxuICpcbiAqIC0gW3VzZVdpdGhdKCNNaXhpbiQkdXNlV2l0aClcbiAqL1xuXy5leHRlbmQoTWl4aW4sIHtcbiAgICB1c2VXaXRoOiBNaXhpbiQkdXNlV2l0aFxufSk7XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgcHJveGllZCBtZXRob2Qgb2YgTWl4aW4gc3ViY2xhc3Mgb24gaG9zdCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1peGluTWV0aG9kTmFtZSBuYW1lIG9mIG1ldGhvZCBpbiBNaXhpbiBzdWJjbGFzc1xuICogQHBhcmFtIHtTdHJpbmd9IHByb3h5TWV0aG9kTmFtZSBuYW1lIG9mIGNyZWF0ZWQgcHJveHkgbWV0aG9kIG9uIGhvc3Qgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBPcHRpb25hbCByZWZlcmVuY2UgdG8gdGhlIGhvc3Qgb2JqZWN0OyBpZiBub3Qgc3BlY2lmaWVkIHRoZSBob3N0IG9iamVjdCBwYXNzZWQgdG8gY29uc3RydWN0b3Igd2lsIGJlIHVzZWQuIEl0IGFsbG93cyB0byB1c2UgdGhlIHNhbWUgaW5zdGFuY2Ugb2YgTWl4aW4gb24gdHdvIGhvc3Qgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gX2NyZWF0ZVByb3h5TWV0aG9kKHByb3h5TWV0aG9kTmFtZSwgbWl4aW5NZXRob2ROYW1lLCBob3N0T2JqZWN0KSB7XG4gICAgaG9zdE9iamVjdCA9IGhvc3RPYmplY3QgfHwgdGhpcy5faG9zdE9iamVjdDtcblxuICAgIC8vIE1peGluIGNsYXNzIGRvZXMgbm90IGFsbG93IHNoYWRvd2luZyBtZXRob2RzIHRoYXQgZXhpc3Qgb24gdGhlIGhvc3Qgb2JqZWN0XG4gICAgaWYgKGhvc3RPYmplY3RbcHJveHlNZXRob2ROYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IE1peGluRXJyb3IoJ21ldGhvZCAnICsgcHJveHlNZXRob2ROYW1lICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgYWxyZWFkeSBkZWZpbmVkIGluIGhvc3Qgb2JqZWN0Jyk7XG5cbiAgICB2YXIgbWV0aG9kID0gdGhpc1ttaXhpbk1ldGhvZE5hbWVdXG4gICAgY2hlY2sobWV0aG9kLCBGdW5jdGlvbik7XG5cbiAgICAvLyBCaW5kIHByb3hpZWQgTWl4aW4ncyBtZXRob2QgdG8gTWl4aW4gaW5zdGFuY2VcbiAgICB2YXIgYm91bmRNZXRob2QgPSBtZXRob2QuYmluZCh0aGlzKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkoaG9zdE9iamVjdCwgcHJveHlNZXRob2ROYW1lLCBib3VuZE1ldGhvZCwgXy5XUklUKTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgcHJveGllZCBtZXRob2RzIG9mIE1peGluIHN1YmNsYXNzIG9uIGhvc3Qgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7SGFzaFtTdHJpbmddfEFycmF5W1N0cmluZ119IHByb3h5TWV0aG9kcyBtYXAgb2YgbmFtZXMgb2YgbWV0aG9kcywga2V5IC0gcHJveHkgbWV0aG9kIG5hbWUsIHZhbHVlIC0gbWl4aW4gbWV0aG9kIG5hbWUuIENhbiBiZSBhcnJheS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IGFuIG9wdGlvbmFsIHJlZmVyZW5jZSB0byB0aGUgaG9zdCBvYmplY3Q7IGlmIG5vdCBzcGVjaWZpZWQgdGhlIGhvc3Qgb2JqZWN0IHBhc3NlZCB0byBjb25zdHJ1Y3RvciB3aWwgYmUgdXNlZC4gSXQgYWxsb3dzIHRvIHVzZSB0aGUgc2FtZSBpbnN0YW5jZSBvZiBNaXhpbiBvbiB0d28gaG9zdCBvYmplY3RzLlxuICovXG5mdW5jdGlvbiBfY3JlYXRlUHJveHlNZXRob2RzKHByb3h5TWV0aG9kcywgaG9zdE9iamVjdCkge1xuICAgIGNoZWNrKHByb3h5TWV0aG9kcywgTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoW1N0cmluZ10sIE1hdGNoLk9iamVjdEhhc2goU3RyaW5nKSkpKTtcblxuICAgIC8vIGNyZWF0aW5nIGFuZCBiaW5kaW5nIHByb3h5IG1ldGhvZHMgb24gdGhlIGhvc3Qgb2JqZWN0XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocHJveHlNZXRob2RzKSlcbiAgICAgICAgcHJveHlNZXRob2RzLmZvckVhY2goZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgLy8gbWV0aG9kIGNhbGxlZCB0aGlzIHdheSB0byBhbGxvdyB1c2luZyBfY3JlYXRlUHJveHlNZXRob2RzIHdpdGggb2JqZWN0c1xuICAgICAgICAgICAgLy8gdGhhdCBhcmUgbm90IGluaGVyaXRpbmcgZnJvbSBNaXhpblxuICAgICAgICAgICAgX2NyZWF0ZVByb3h5TWV0aG9kLmNhbGwodGhpcywgbWV0aG9kTmFtZSwgbWV0aG9kTmFtZSwgaG9zdE9iamVjdCk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIGVsc2VcbiAgICAgICAgXy5lYWNoS2V5KHByb3h5TWV0aG9kcywgZnVuY3Rpb24obWl4aW5NZXRob2ROYW1lLCBwcm94eU1ldGhvZE5hbWUpIHtcbiAgICAgICAgICAgIC8vIG1ldGhvZCBjYWxsZWQgdGhpcyB3YXkgdG8gYWxsb3cgdXNpbmcgX2NyZWF0ZVByb3h5TWV0aG9kcyB3aXRoIG9iamVjdHNcbiAgICAgICAgICAgIC8vIHRoYXQgYXJlIG5vdCBpbmhlcml0aW5nIGZyb20gTWl4aW5cbiAgICAgICAgICAgIF9jcmVhdGVQcm94eU1ldGhvZC5jYWxsKHRoaXMsIHByb3h5TWV0aG9kTmFtZSwgbWl4aW5NZXRob2ROYW1lLCBob3N0T2JqZWN0KTtcbiAgICAgICAgfSwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBTZXRzIG1peGluIGluc3RhbmNlIHByb3BlcnR5IG5hbWUgb24gdGhlIGhvc3QgY2xhc3NcbiAqIENhbiBiZSBjYWxsZWQgb25seSBvbmNlXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXMgTWl4aW4gc3ViY2xhc3MgKG5vdCBpbnN0YW5jZSlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhvc3RDbGFzc1xuICogQHBhcmFtIHtTdHJpbmd9IGluc3RhbmNlS2V5XG4gKi9cbmZ1bmN0aW9uIE1peGluX3NldEluc3RhbmNlS2V5KGhvc3RDbGFzcywgbWV0aG9kLCBpbnN0YW5jZUtleSkge1xuICAgIGNoZWNrKGhvc3RDbGFzcywgRnVuY3Rpb24pO1xuICAgIGNoZWNrKGluc3RhbmNlS2V5LCBNYXRjaC5JZGVudGlmaWVyU3RyaW5nKTtcblxuICAgIHZhciBwcm9wID0gY29uZmlnLm1peGluLmluc3RhbmNlUHJvcGVydGllc01hcFxuICAgICAgICAsIGluc3RhbmNlS2V5cyA9IGhvc3RDbGFzc1twcm9wXSA9IGhvc3RDbGFzc1twcm9wXSB8fCB7fTtcblxuICAgIGlmIChpbnN0YW5jZUtleXNbbWV0aG9kLm5hbWVdKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01peGluOiBpbnN0YW5jZSBwcm9wZXJ0eSBmb3IgbWV0aG9kIHdpdGggbmFtZSAnXG4gICAgICAgICAgICArIG1ldGhvZC5uYW1lICsgJyBpcyBhbHJlYWR5IHNldCcpO1xuXG4gICAgaW5zdGFuY2VLZXlzW21ldGhvZC5uYW1lXSA9IGluc3RhbmNlS2V5O1xufVxuXG5cbi8qKlxuICogQWRkcyBtZXRob2Qgb2YgTWl4aW4gc3ViY2xhc3MgdG8gaG9zdCBjbGFzcyBwcm90b3R5cGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXMgTWl4aW4gc3ViY2xhc3MgKG5vdCBpbnN0YW5jZSlcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaXhpbk1ldGhvZE5hbWUgbmFtZSBvZiBtZXRob2QgaW4gTWl4aW4gc3ViY2xhc3NcbiAqIEBwYXJhbSB7U3RyaW5nfSBob3N0TWV0aG9kTmFtZSAob3B0aW9uYWwpIG5hbWUgb2YgY3JlYXRlZCBwcm94eSBtZXRob2Qgb24gaG9zdCBvYmplY3QsIHNhbWUgaWYgbm90IHNwZWNpZmllZFxuICogQHBhcmFtIHtPYmplY3R9IGhvc3RPYmplY3Qgb2JqZWN0IGNsYXNzLCBtdXN0IGJlIHNwZWNpZmllZCBhcyB0aGUgbGFzdCBwYXJhbWV0ZXIgKDJuZCBvciAzcmQpXG4gKi9cbmZ1bmN0aW9uIE1peGluX2FkZE1ldGhvZChob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtaXhpbk1ldGhvZE5hbWUsIGhvc3RNZXRob2ROYW1lKSB7XG4gICAgdmFyIG1ldGhvZCA9IHRoaXMucHJvdG90eXBlW21peGluTWV0aG9kTmFtZV07XG4gICAgY2hlY2sobWV0aG9kLCBGdW5jdGlvbik7XG5cbiAgICB2YXIgd3JhcHBlZE1ldGhvZCA9IF93cmFwTWl4aW5NZXRob2QuY2FsbCh0aGlzLCBtZXRob2QpO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0eShob3N0Q2xhc3MucHJvdG90eXBlLCBob3N0TWV0aG9kTmFtZSwgd3JhcHBlZE1ldGhvZCwgXy5XUklUKTtcblxuICAgIE1peGluX3NldEluc3RhbmNlS2V5KGhvc3RDbGFzcywgbWV0aG9kLCBpbnN0YW5jZUtleSlcbn1cblxuXG4vKipcbiAqIFJldHVybnMgbWV0aG9kIHRoYXQgd2lsbCBiZSBleHBvc2VkIG9uIHRoZSBob3N0IGNsYXNzIHByb3RvdHlwZVxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzIE1peGluIHN1YmNsYXNzIChub3QgaW5zdGFuY2UpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gX3dyYXBNaXhpbk1ldGhvZChtZXRob2QpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7IC8vICwuLi4gYXJndW1lbnRzXG4gICAgICAgIHZhciBtaXhpbkluc3RhbmNlID0gX2dldE1peGluSW5zdGFuY2UuY2FsbCh0aGlzLCBtZXRob2QubmFtZSk7XG4gICAgICAgIHJldHVybiBtZXRob2QuYXBwbHkobWl4aW5JbnN0YW5jZSwgYXJndW1lbnRzKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSByZWZlcmVuY2UgdG8gdGhlIGluc3RhbmNlIG9mIG1peGluIHN1YmNsYXNzLlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCB3aGVuIG1ldGhvZHMgYXJlIGV4cG9zZWQgb24gdGhlIGhvc3QgY2xhc3MgcHJvdG90eXBlICh1c2luZyBhZGRNZWh0b2RzKSByYXRoZXIgdGhhbiBvbiBob3N0IGluc3RhbmNlLlxuICogU3ViY2xhc3NlcyBzaG91bGQgbm90IHVzZSB0aGlzIG1ldGhvZHMgLSB3aGVuZXZlciBzdWJjbGFzcyBtZXRob2QgaXMgZXhwb3NlZCBvbiB0aGUgcHJvdG90eXBlIGl0IHdpbGwgYmUgd3JhcHBlZCB0byBzZXQgY29ycmVjdCBjb250ZXh0IGZvciB0aGUgc3ViY2xhc3MgbWV0aG9kLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIF9nZXRNaXhpbkluc3RhbmNlKG1ldGhvZE5hbWUpIHtcbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIE1peGluKSByZXR1cm4gdGhpcztcbiAgICB2YXIgaW5zdGFuY2VLZXlzID0gdGhpcy5jb25zdHJ1Y3Rvcltjb25maWcubWl4aW4uaW5zdGFuY2VQcm9wZXJ0aWVzTWFwXVxuICAgIHJldHVybiB0aGlzW2luc3RhbmNlS2V5c1ttZXRob2ROYW1lXV07XG59XG5cblxuLyoqXG4gKiBBZGRzIG1ldGhvZHMgb2YgTWl4aW4gc3ViY2xhc3MgdG8gaG9zdCBjbGFzcyBwcm90b3R5cGUuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gdGhpcyBNaXhpbiBzdWJjbGFzcyAobm90IGluc3RhbmNlKVxuICogQHBhcmFtIHtPYmplY3R9IGhvc3RDbGFzcyBob3N0IG9iamVjdCBjbGFzczsgbXVzdCBiZSBzcGVjaWZpZWQuXG4gKiBAcGFyYW0ge1N0cmluZ30gaW5zdGFuY2VLZXkgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRoZSBob3N0IGNsYXNzIGluc3RhbmNlIHdpbGwgc3RvcmUgbWl4aW4gaW5zdGFuY2Ugb25cbiAqIEBwYXJhbSB7SGFzaFtTdHJpbmddfEFycmF5W1N0cmluZ119IG1peGluTWV0aG9kcyBtYXAgb2YgbmFtZXMgb2YgbWV0aG9kcywga2V5IC0gaG9zdCBtZXRob2QgbmFtZSwgdmFsdWUgLSBtaXhpbiBtZXRob2QgbmFtZS4gQ2FuIGJlIGFycmF5LlxuICovXG5mdW5jdGlvbiBNaXhpbiQkdXNlV2l0aChob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtaXhpbk1ldGhvZHMpIHtcbiAgICBjaGVjayhtaXhpbk1ldGhvZHMsIE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKFtTdHJpbmddLCBNYXRjaC5PYmplY3RIYXNoKFN0cmluZykpKSk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShtaXhpbk1ldGhvZHMpKVxuICAgICAgICBtaXhpbk1ldGhvZHMuZm9yRWFjaChmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgICAgICAgICBNaXhpbl9hZGRNZXRob2QuY2FsbCh0aGlzLCBob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtZXRob2ROYW1lLCBtZXRob2ROYW1lKTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgZWxzZVxuICAgICAgICBfLmVhY2hLZXkobWl4aW5NZXRob2RzLCBmdW5jdGlvbihtaXhpbk1ldGhvZE5hbWUsIGhvc3RNZXRob2ROYW1lKSB7XG4gICAgICAgICAgICBNaXhpbl9hZGRNZXRob2QuY2FsbCh0aGlzLCBob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtaXhpbk1ldGhvZE5hbWUsIGhvc3RNZXRob2ROYW1lKTtcbiAgICAgICAgfSwgdGhpcyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIFJlZ2lzdHJ5RXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuUmVnaXN0cnlcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENsYXNzUmVnaXN0cnk7XG5cblxuLyoqXG4gKiBgbWlsby5jbGFzc2VzLkNsYXNzUmVnaXN0cnlgIC0gdGhlIHJlZ2lzdHJ5IG9mIGNsYXNzZXMgY2xhc3MuXG4gKiBDb21wb25lbnRzIGFuZCBGYWNldHMgcmVnaXN0ZXIgdGhlbXNlbHZlcyBpbiByZWdpc3RyaWVzLiBJdCBhbGxvd3MgdG8gYXZvaWQgcmVxdWlyaW5nIHRoZW0gZnJvbSBvbmUgbW9kdWxlIGFuZCBwcmV2ZW50cyBjaXJjdWxhciBkZXBlbmRlbmNpZXMgYmV0d2VlbiBtb2R1bGVzLlxuICogXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBGb3VuZGF0aW9uQ2xhc3MgQWxsIGNsYXNzZXMgdGhhdCBhcmUgcmVnaXN0ZXJlZCBpbiB0aGUgcmVnaXN0cnkgc2hvdWxkIGJlIHN1YmNsYXNzZXMgb2YgdGhlIEZvdW5kYXRpb25DbGFzc1xuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBDbGFzc1JlZ2lzdHJ5IChGb3VuZGF0aW9uQ2xhc3MpIHtcbiAgICBpZiAoRm91bmRhdGlvbkNsYXNzKVxuICAgICAgICB0aGlzLnNldENsYXNzKEZvdW5kYXRpb25DbGFzcyk7XG5cbiAgICB0aGlzLl9fcmVnaXN0ZXJlZENsYXNzZXMgPSB7fTtcbn1cblxuXG4vKipcbiAqICMjIyNDbGFzc1JlZ2lzdHJ5IGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbYWRkXSgjYWRkKVxuICogLSBbZ2V0XSgjZ2V0KVxuICogLSBbcmVtb3ZlXSgjcmVtb3ZlKVxuICogLSBbY2xlYW5dKCNjbGVhbilcbiAqIC0gW3NldENsYXNzXSgjc2V0Q2xhc3MpXG4gKi9cbl8uZXh0ZW5kUHJvdG8oQ2xhc3NSZWdpc3RyeSwge1xuICAgIGFkZDogYWRkLFxuICAgIGdldDogZ2V0LFxuICAgIHJlbW92ZTogcmVtb3ZlLFxuICAgIGNsZWFuOiBjbGVhbixcbiAgICBzZXRDbGFzczogc2V0Q2xhc3Ncbn0pO1xuXG5cbi8qKlxuICogQ2xhc3NSZWdpc3RyeSBpbnN0YW5jZSBtZXRob2QgdGhhdCByZWdpc3RlcnMgYSBjbGFzcyBpbiB0aGUgcmVnaXN0cnkuXG4gKiBUaGUgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGEgY2xhc3MgaXMgcmVnaXN0ZXJlZCB1bmRlciB0aGUgc2FtZSBuYW1lIGFzIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBjbGFzcy5cbiAqIFRoZSBtZXRob2QgYWxsb3dzIHJlZ2lzdGVyaW5nIHRoZSBzYW1lIGNsYXNzIHVuZGVyIGEgZGlmZmVyZW50IG5hbWUsIHNvIGNsYXNzIGFsaWFzZXMgY2FuIGJlIGNyZWF0ZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gYUNsYXNzIGNsYXNzIHRvIHJlZ2lzdGVyIGluIHRoZSByZWdpc3RyeS4gU2hvdWxkIGJlIHN1YmNsYXNzIG9mIGB0aGlzLkZvdW5kYXRpb25DbGFzc2AuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBPcHRpb25hbCBjbGFzcyBuYW1lLiBJZiBjbGFzcyBuYW1lIGlzIG5vdCBzcGVjaWZpZWQsIGl0IHdpbGwgYmUgdGFrZW4gZnJvbSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBuYW1lLiBDbGFzcyBuYW1lIHNob3VsZCBiZSBhIHZhbGlkIGlkZW50aWZpZXIgYW5kIGNhbm5vdCBiZSBhbiBlbXB0eSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGFkZChhQ2xhc3MsIG5hbWUpIHtcbiAgICBuYW1lID0gbmFtZSB8fCBhQ2xhc3MubmFtZTtcblxuICAgIGNoZWNrKG5hbWUsIE1hdGNoLklkZW50aWZpZXJTdHJpbmcsICdjbGFzcyBuYW1lIG11c3QgYmUgaWRlbnRpZmllciBzdHJpbmcnKTtcblxuICAgIGlmICh0aGlzLkZvdW5kYXRpb25DbGFzcykge1xuICAgICAgICBpZiAoYUNsYXNzICE9IHRoaXMuRm91bmRhdGlvbkNsYXNzKVxuICAgICAgICAgICAgY2hlY2soYUNsYXNzLCBNYXRjaC5TdWJjbGFzcyh0aGlzLkZvdW5kYXRpb25DbGFzcyksICdjbGFzcyBtdXN0IGJlIGEgc3ViKGNsYXNzKSBvZiBhIGZvdW5kYXRpb24gY2xhc3MnKTtcbiAgICB9IGVsc2VcbiAgICAgICAgdGhyb3cgbmV3IFJlZ2lzdHJ5RXJyb3IoJ2ZvdW5kYXRpb24gY2xhc3MgbXVzdCBiZSBzZXQgYmVmb3JlIGFkZGluZyBjbGFzc2VzIHRvIHJlZ2lzdHJ5Jyk7XG5cbiAgICBpZiAodGhpcy5fX3JlZ2lzdGVyZWRDbGFzc2VzW25hbWVdKVxuICAgICAgICB0aHJvdyBuZXcgUmVnaXN0cnlFcnJvcignY2xhc3MgXCInICsgbmFtZSArICdcIiBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQnKTtcblxuICAgIHRoaXMuX19yZWdpc3RlcmVkQ2xhc3Nlc1tuYW1lXSA9IGFDbGFzcztcbn07XG5cblxuLyoqXG4gKiBHZXRzIGNsYXNzIGZyb20gcmVnaXN0cnkgYnkgbmFtZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIENsYXNzIG5hbWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBnZXQobmFtZSkge1xuICAgIGNoZWNrKG5hbWUsIFN0cmluZywgJ2NsYXNzIG5hbWUgbXVzdCBiZSBzdHJpbmcnKTtcbiAgICByZXR1cm4gdGhpcy5fX3JlZ2lzdGVyZWRDbGFzc2VzW25hbWVdO1xufTtcblxuXG4vKipcbiAqIFJlbW92ZSBjbGFzcyBmcm9tIHJlZ2lzdHJ5IGJ5IGl0cyBuYW1lLlxuICogSWYgY2xhc3MgaXMgbm90IHJlZ2lzdGVyZWQsIHRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uLlxuICogXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gbmFtZU9yQ2xhc3MgQ2xhc3MgbmFtZS4gSWYgY2xhc3MgY29uc3RydWN0b3IgaXMgc3VwcGxpZWQsIGl0cyBuYW1lIHdpbGwgYmUgdXNlZC5cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlKG5hbWVPckNsYXNzKSB7XG4gICAgY2hlY2sobmFtZU9yQ2xhc3MsIE1hdGNoLk9uZU9mKFN0cmluZywgRnVuY3Rpb24pLCAnY2xhc3Mgb3IgbmFtZSBtdXN0IGJlIHN1cHBsaWVkJyk7XG5cbiAgICB2YXIgbmFtZSA9IHR5cGVvZiBuYW1lT3JDbGFzcyA9PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyBuYW1lT3JDbGFzc1xuICAgICAgICAgICAgICAgICAgICAgICAgOiBuYW1lT3JDbGFzcy5uYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgaWYgKCEgdGhpcy5fX3JlZ2lzdGVyZWRDbGFzc2VzW25hbWVdKVxuICAgICAgICB0aHJvdyBuZXcgUmVnaXN0cnlFcnJvcignY2xhc3MgaXMgbm90IHJlZ2lzdGVyZWQnKTtcblxuICAgIGRlbGV0ZSB0aGlzLl9fcmVnaXN0ZXJlZENsYXNzZXNbbmFtZV07XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlcyBhbGwgY2xhc3NlcyBmcm9tIHJlZ2lzdHJ5LlxuICovXG5mdW5jdGlvbiBjbGVhbigpIHtcbiAgICB0aGlzLl9fcmVnaXN0ZXJlZENsYXNzZXMgPSB7fTtcbn07XG5cblxuLyoqXG4gKiBTZXRzIGBGb3VuZGF0aW9uQ2xhc3NgIG9mIHRoZSByZWdpc3RyeS4gSXQgc2hvdWxkIGJlIHNldCBiZWZvcmUgYW55IGNsYXNzIGNhbiBiZSBhZGRlZC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBGb3VuZGF0aW9uQ2xhc3MgQW55IGNsYXNzIHRoYXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgcmVnaXN0cnkgc2hvdWxkIGJlIGEgc3ViY2xhc3Mgb2YgdGhpcyBjbGFzcy4gRm91bmRhdGlvbkNsYXNzIGl0c2VsZiBjYW4gYmUgYWRkZWQgdG8gdGhlIHJlZ2lzdHJ5IHRvby5cbiAqL1xuZnVuY3Rpb24gc2V0Q2xhc3MoRm91bmRhdGlvbkNsYXNzKSB7XG4gICAgY2hlY2soRm91bmRhdGlvbkNsYXNzLCBGdW5jdGlvbik7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnRm91bmRhdGlvbkNsYXNzJywgRm91bmRhdGlvbkNsYXNzLCBfLkVOVU0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQXR0cmlidXRlID0gcmVxdWlyZSgnLi9hX2NsYXNzJylcbiAgICAsIEF0dHJpYnV0ZUVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLkF0dHJpYnV0ZVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxudmFyIEFUVFJJQlVURV9SRUdFWFA9IC9eKFteXFw6XFxbXFxdXSopKD86XFxbKFteXFw6XFxbXFxdXSopXFxdKT9cXDo/KFteOl0qKSQvXG4gICAgLCBGQUNFVFNfU1BMSVRfUkVHRVhQID0gL1xccyooPzpcXCx8XFxzKVxccyovXG4gICAgLCBBVFRSSUJVVEVfVEVNUExBVEUgPSAnJWNvbXBDbGFzcyVjb21wRmFjZXRzOiVjb21wTmFtZSc7XG5cblxuLyoqXG4gKiBgbWlsby5hdHRyaWJ1dGVzLmJpbmRgXG4gKiBCaW5kQXR0cmlidXRlIGNsYXNzIHBhcnNlcy92YWxpZGF0ZXMvZXRjLiBhbiBhdHRyaWJ1dGUgdGhhdCBiaW5kcyBET00gZWxlbWVudHMgdG8gbWlsbyBjb21wb25lbnRzLlxuICogUG9zc2libGUgYXR0cmlidXRlIHZhbHVlcyBhcmU6XG4gKlxuICogLSBgOm15Vmlld2AgLSBvbmx5IGNvbXBvbmVudCBuYW1lXG4gKiAtIGBWaWV3Om15Vmlld2AgLSBjbGFzcyBhbmQgY29tcG9uZW50IG5hbWVcbiAqIC0gYFtFdmVudHMsIERhdGFdOm15Vmlld2AgLSBmYWNldHMgYW5kIGNvbXBvbmVudCBuYW1lXG4gKiAtIGBWaWV3W0V2ZW50c106bXlWaWV3YCAtIGNsYXNzLCBmYWNldChzKSBhbmQgY29tcG9uZW50IG5hbWVcbiAqXG4gKiBTZWUgW2JpbmRlcl0oLi4vYmluZGVyLmpzLmh0bWwpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICovXG52YXIgQmluZEF0dHJpYnV0ZSA9IF8uY3JlYXRlU3ViY2xhc3MoQXR0cmlidXRlLCAnQmluZEF0dHJpYnV0ZScsIHRydWUpO1xuXG5cbi8qKlxuICogIyMjI0JpbmRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFthdHRyTmFtZV0oI2F0dHJOYW1lKVxuICogLSBbcGFyc2VdKCNwYXJzZSlcbiAqIC0gW3ZhbGlkYXRlXSgjdmFsaWRhdGUpXG4gKiAtIFtyZW5kZXJdKCNyZW5kZXIpXG4gKi9cbl8uZXh0ZW5kUHJvdG8oQmluZEF0dHJpYnV0ZSwge1xuICAgIGF0dHJOYW1lOiBhdHRyTmFtZSxcbiAgICBwYXJzZTogcGFyc2UsXG4gICAgdmFsaWRhdGU6IHZhbGlkYXRlLFxuICAgIHJlbmRlcjogcmVuZGVyXG59KTtcblxuXG4vKipcbiAqIEJpbmRBdHRyaWJ1dGUgY2xhc3MgbWV0aG9kc1xuICpcbiAqIC0gW3NldEluZm9dKCNCaW5kQXR0cmlidXRlJCRzZXRJbmZvKVxuICovXG5fLmV4dGVuZChCaW5kQXR0cmlidXRlLCB7XG4gICAgc2V0SW5mbzogQmluZEF0dHJpYnV0ZSQkc2V0SW5mb1xufSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBCaW5kQXR0cmlidXRlO1xuXG5cbi8qKlxuICogQmluZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCByZXR1cm5zIGF0dHJpYnV0ZSBuYW1lLCBieSBkZWZhdWx0IC0gYCdtbC1iaW5kJ2AuXG4gKiBUbyBjb25maWd1cmUgYmluZCBhdHRyaWJ1dGUgbmFtZSB1c2U6XG4gKiBgYGBcbiAqIG1pbG8uY29uZmlnKHsgYXR0cnM6IHsgYmluZDogJ2NjLWJpbmQnIH0gfSk7IC8vIHdpbGwgc2V0IGJpbmQgYXR0cmlidXRlIHRvICdjYy1iaW5kJ1xuICogYGBgXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBhdHRyTmFtZSgpIHtcbiAgICByZXR1cm4gY29uZmlnLmF0dHJzLmJpbmQ7XG59XG5cblxuLyoqXG4gKiBCaW5kQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZCB0aGF0IHBhcnNlcyBiaW5kIGF0dHJpYnV0ZSBpZiBpdCBpcyBwcmVzZW50IG9uIHRoZSBlbGVtZW50LlxuICogSXQgZGVmaW5lcyBwcm9wZXJ0aWVzIGBjb21wQ2xhc3NgLCBgY29tcEZhY2V0c2AgYW5kIGBjb21wTmFtZWAgb24gQmluZEF0dHJpYnV0ZSBpbnN0YW5jZS5cbiAqIFJldHVybnMgdGhlIGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gKlxuICogQHJldHVybiB7QmluZEF0dHJpYnV0ZX1cbiAqL1xuIGZ1bmN0aW9uIHBhcnNlKCkge1xuICAgIGlmICghIHRoaXMubm9kZSkgcmV0dXJuO1xuXG4gICAgdmFyIHZhbHVlID0gdGhpcy5nZXQoKTtcblxuICAgIGlmICh2YWx1ZSlcbiAgICAgICAgdmFyIGJpbmRUbyA9IHZhbHVlLm1hdGNoKEFUVFJJQlVURV9SRUdFWFApO1xuXG4gICAgaWYgKCEgYmluZFRvKVxuICAgICAgICB0aHJvdyBuZXcgQXR0cmlidXRlRXJyb3IoJ2ludmFsaWQgYmluZCBhdHRyaWJ1dGUgJyArIHZhbHVlKTtcblxuICAgIHRoaXMuY29tcENsYXNzID0gYmluZFRvWzFdIHx8ICdDb21wb25lbnQnO1xuICAgIHRoaXMuY29tcEZhY2V0cyA9IChiaW5kVG9bMl0gJiYgYmluZFRvWzJdLnNwbGl0KEZBQ0VUU19TUExJVF9SRUdFWFApKSB8fCB1bmRlZmluZWQ7XG4gICAgdGhpcy5jb21wTmFtZSA9IGJpbmRUb1szXSB8fCB1bmRlZmluZWQ7IC8vIHVuZGVmaW5lZCBpcyBub3Qgc2FtZSBhcyAnJ1xuXG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBCaW5kQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZCB0aGF0IHZhbGlkYXRlcyBiaW5kIGF0dHJpYnV0ZSwgdGhyb3dzIGlmIGl0IGhhcyBhbiBpbnZhbGlkIHZhbHVlLlxuICogUmV0dXJucyB0aGUgaW5zdGFuY2UgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAqXG4gKiBAcmV0dXJuIHtCaW5kQXR0cmlidXRlfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZSgpIHtcbiAgICBjaGVjayh0aGlzLmNvbXBOYW1lLCBNYXRjaC5JZGVudGlmaWVyU3RyaW5nKTtcblxuICAgIGlmICghIHRoaXMuY29tcENsYXNzKVxuICAgICAgICB0aHJvdyBuZXcgQXR0cmlidXRlRXJyb3IoJ2VtcHR5IGNvbXBvbmVudCBjbGFzcyBuYW1lICcgKyB0aGlzLmNvbXBDbGFzcyk7XG5cbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEJpbmRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIHRoYXQgcmV0dXJucyB0aGUgYXR0cmlidXRlIHZhbHVlIGZvciBnaXZlbiB2YWx1ZXMgb2YgcHJvcGVydGllcyBgY29tcENsYXNzYCwgYGNvbXBOYW1lYCBhbmQgYGNvbXBGYWNldHNgLlxuICogSWYgYHRoaXMuY29tcE5hbWVgIGlzIG5vdCBzZXQgaXQgd2lsbCBiZSBnZW5lcmF0ZWQgYXV0b21hdGljYWxseS5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICB0aGlzLmNvbXBOYW1lID0gdGhpcy5jb21wTmFtZSB8fCBtaWxvLnV0aWwuY29tcG9uZW50TmFtZSgpO1xuICAgIHJldHVybiBBVFRSSUJVVEVfVEVNUExBVEVcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgnJWNvbXBDbGFzcycsIHRoaXMuY29tcENsYXNzIHx8ICcnKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKCclY29tcEZhY2V0cycsIHRoaXMuY29tcEZhY2V0cyAmJiB0aGlzLmNvbXBGYWNldHMubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJ1snICsgdGhpcy5jb21wRmFjZXRzLmpvaW4oJywgJykgKyAnXSdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJylcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgnJWNvbXBOYW1lJywgdGhpcy5jb21wTmFtZSk7XG59XG5cblxuLyoqXG4gKiBCaW5kQXR0cmlidXRlIGNsYXNzIG1ldGhvZFxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IGNvbXBvbmVudENsYXNzIG9wdGlvbmFsIGNsYXNzIG5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfSBjb21wb25lbnROYW1lIG9wdGlvbmFsXG4gKiBAcGFyYW0ge0FycmF5PFN0cmluZz59IGNvbXBvbmVudEZhY2V0cyBvcHRpb25hbCBleHRyYSBmYWNldCB0byBhZGQgdG8gdGhlIGNsYXNzXG4gKi9cbmZ1bmN0aW9uIEJpbmRBdHRyaWJ1dGUkJHNldEluZm8oZWwsIGNvbXBvbmVudENsYXNzLCBjb21wb25lbnROYW1lLCBjb21wb25lbnRGYWNldHMpIHtcbiAgICB2YXIgYXR0ciA9IG5ldyBCaW5kQXR0cmlidXRlKGVsKTtcbiAgICBfLmV4dGVuZChhdHRyLCB7XG4gICAgICAgIGNvbXBDbGFzczogY29tcG9uZW50Q2xhc3MsXG4gICAgICAgIGNvbXBOYW1lOiBjb21wb25lbnROYW1lLFxuICAgICAgICBjb21wRmFjZXRzOiBjb21wb25lbnRGYWNldHNcbiAgICB9KTtcbiAgICBhdHRyLmRlY29yYXRlKCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCB0b0JlSW1wbGVtZW50ZWQgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykudG9CZUltcGxlbWVudGVkO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gQXR0cmlidXRlO1xuXG5cbi8qKlxuICogQW4gYWJzY3RyYWN0IGNsYXNzIGZvciBwYXJzaW5nIGFuZCB2YWxpZGF0aW9uIG9mIGVsZW1lbnQgYXR0cmlidXRlcy5cbiAqIFN1YmNsYXNzZXMgc2hvdWxkIGRlZmluZSBtZXRob2RzIGBhdHRyTmFtZWAsIGBwYXJzZWAsIGB2YWxpZGF0ZWAgYW5kIGByZW5kZXJgLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgRE9NIGVsZW1lbnQgd2hlcmUgYXR0cmlidXRlIGlzIGF0dGFjaGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBPcHRpb25hbCBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUsIHVzdWFsbHkgc3VwcGxpZWQgYnkgc3ViY2xhc3MgdmlhIGBhdHRyTmFtZWAgbWV0aG9kXG4gKi9cbmZ1bmN0aW9uIEF0dHJpYnV0ZShlbCwgbmFtZSkge1xuICAgIHRoaXMubmFtZSA9IG5hbWUgfHwgdGhpcy5hdHRyTmFtZSgpO1xuICAgIHRoaXMuZWwgPSBlbDtcblxuICAgIC8vIGF0dHJpYnV0ZSBub2RlXG4gICAgdGhpcy5ub2RlID0gZWwuYXR0cmlidXRlc1t0aGlzLm5hbWVdO1xufVxuXG5cbl8uZXh0ZW5kKEF0dHJpYnV0ZSwge1xuICAgIHJlbW92ZTogQXR0cmlidXRlJCRyZW1vdmVcbn0pO1xuXG5cbi8qKlxuICogIyMjI0F0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2dldF0oI0F0dHJpYnV0ZSRnZXQpXG4gKiAtIFtzZXRdKCNBdHRyaWJ1dGUkc2V0KVxuICogLSBbZGVjb3JhdGVdKCNBdHRyaWJ1dGUkZGVjb3JhdGUpXG4gKlxuICogVGhlIGZvbGxvd2luZyBpbnN0YW5jZSBtZXRob2RzIHNob3VsZCBiZSBkZWZpbmVkIGJ5IHN1YmNsYXNzXG4gKlxuICogLSBhdHRyTmFtZSAtIHNob3VsZCByZXR1cm4gYXR0cmlidXRlIG5hbWVcbiAqIC0gcGFyc2UgLSBzaG91bGQgcGFyc2UgYXR0cmlidXRlIHZhbHVlXG4gKiAtIHZhbGlkYXRlIC0gc2hvdWxkIHZhbGlkYXRlIGF0dHJpYnV0ZSB2YWx1ZSwgdGhyb3dpbmcgZXhjZXB0aW9uIGlmIGl0IGlzIGluY29ycmVjdCBcbiAqIC0gcmVuZGVyIC0gc2hvdWxkIHJldHVybiBhdHRyaWJ1dGUgdmFsdWUgZm9yIGEgZ2l2ZW4gYXR0cmlidXRlIHN0YXRlIChvdGhlciBwcm9wZXJ0aWVzLCBhcyBkZWZpbmVkIGluIHN1YmNsYXNzKVxuICovXG5fLmV4dGVuZFByb3RvKEF0dHJpYnV0ZSwge1xuICAgIGdldDogQXR0cmlidXRlJGdldCxcbiAgICBzZXQ6IEF0dHJpYnV0ZSRzZXQsXG4gICAgcmVtb3ZlOiBBdHRyaWJ1dGUkcmVtb3ZlLFxuICAgIGRlY29yYXRlOiBBdHRyaWJ1dGUkZGVjb3JhdGUsXG5cbiAgICBkZXN0cm95OiBBdHRyaWJ1dGUkZGVzdHJveSxcblxuICAgIC8vIHNob3VsZCBiZSBkZWZpbmVkIGluIHN1YmNsYXNzXG4gICAgYXR0ck5hbWU6IHRvQmVJbXBsZW1lbnRlZCxcbiAgICBwYXJzZTogdG9CZUltcGxlbWVudGVkLFxuICAgIHZhbGlkYXRlOiB0b0JlSW1wbGVtZW50ZWQsXG4gICAgcmVuZGVyOiB0b0JlSW1wbGVtZW50ZWRcbn0pO1xuXG5cbmZ1bmN0aW9uIEF0dHJpYnV0ZSQkcmVtb3ZlKGVsLCBkZWVwKSB7XG4gICAgdmFyIG5hbWUgPSB0aGlzLnByb3RvdHlwZS5hdHRyTmFtZSgpO1xuICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcblxuICAgIGlmIChkZWVwKSB7XG4gICAgICAgIHZhciBzZWxlY3RvciA9ICdbJyArIG5hbWUgKyAnXSc7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IGVsLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICAgICAgICBfLmZvckVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkRWwpIHtcbiAgICAgICAgICAgIGNoaWxkRWwucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgICAgICB9KVxuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBBdHRyaWJ1dGUkcmVtb3ZlKCkge1xuICAgIGRlbGV0ZSB0aGlzLm5vZGU7XG59XG5cblxuZnVuY3Rpb24gQXR0cmlidXRlJGRlc3Ryb3koKSB7XG4gICAgZGVsZXRlIHRoaXMuZWw7XG4gICAgZGVsZXRlIHRoaXMubm9kZTtcbn1cblxuLyoqXG4gKiBBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGUgdmFsdWUgYXMgc3RyaW5nLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gQXR0cmlidXRlJGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5lbC5nZXRBdHRyaWJ1dGUodGhpcy5uYW1lKTtcbn1cblxuXG4vKipcbiAqIEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCBzZXRzIGF0dHJpYnV0ZSB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcbiAqL1xuZnVuY3Rpb24gQXR0cmlidXRlJHNldCh2YWx1ZSkge1xuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKHRoaXMubmFtZSwgdmFsdWUpO1xufVxuXG5cbi8qKlxuICogQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZCB0aGF0IGRlY29yYXRlcyBlbGVtZW50IHdpdGggaXRzIHJlbmRlcmVkIHZhbHVlLlxuICogVXNlcyBgcmVuZGVyYCBtZXRob2QgdGhhdCBzaG91bGQgYmUgZGVmaWVuZCBpbiBzdWJjbGFzcy5cbiAqL1xuZnVuY3Rpb24gQXR0cmlidXRlJGRlY29yYXRlKCkge1xuICAgIHRoaXMuc2V0KHRoaXMucmVuZGVyKCkpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQXR0cmlidXRlID0gcmVxdWlyZSgnLi9hX2NsYXNzJylcbiAgICAsIEF0dHJpYnV0ZUVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLkF0dHJpYnV0ZVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIGBtaWxvLmF0dHJpYnV0ZXMubG9hZGBcbiAqIExvYWRBdHRyaWJ1dGUgY2xhc3MgcGFyc2VzL3ZhbGlkYXRlcy9ldGMuIGFuIGF0dHJpYnV0ZSB0aGF0IGxvYWRzIHN1Yi12aWV3cyBpbnRvIHRoZSBwYWdlLlxuICogQXR0cmlidXRlIHZhbHVlIHNob3VsZCBiZSBVUkwgb2YgdGhlIGZpbGUgdG8gbG9hZCBzdWJ2aWV3IGZyb20uXG4gKiBTZWUgW2xvYWRlcl0oLi4vbG9hZGVyLmpzLmh0bWwpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICovXG52YXIgTG9hZEF0dHJpYnV0ZSA9IF8uY3JlYXRlU3ViY2xhc3MoQXR0cmlidXRlLCAnTG9hZEF0dHJpYnV0ZScsIHRydWUpO1xuXG5cbi8qKlxuICogIyMjI0xvYWRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFthdHRyTmFtZV0oI2F0dHJOYW1lKVxuICogLSBbcGFyc2VdKCNwYXJzZSlcbiAqIC0gW3ZhbGlkYXRlXSgjdmFsaWRhdGUpXG4gKiAtIFtyZW5kZXJdKCNyZW5kZXIpXG4gKi9cbl8uZXh0ZW5kUHJvdG8oTG9hZEF0dHJpYnV0ZSwge1xuICAgIGF0dHJOYW1lOiBhdHRyTmFtZSxcbiAgICBwYXJzZTogcGFyc2UsXG4gICAgdmFsaWRhdGU6IHZhbGlkYXRlLFxuICAgIHJlbmRlcjogcmVuZGVyXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBMb2FkQXR0cmlidXRlO1xuXG5cbi8qKlxuICogQmluZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCByZXR1cm5zIGF0dHJpYnV0ZSBuYW1lLCBieSBkZWZhdWx0IC0gYCdtbC1sb2FkJ2AuXG4gKiBUbyBjb25maWd1cmUgbG9hZCBhdHRyaWJ1dGUgbmFtZSB1c2U6XG4gKiBgYGBcbiAqIG1pbG8uY29uZmlnKHsgYXR0cnM6IHsgbG9hZDogJ2NjLWxvYWQnIH0gfSk7IC8vIHdpbGwgc2V0IGJpbmQgYXR0cmlidXRlIHRvICdjYy1sb2FkJ1xuICogYGBgXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBhdHRyTmFtZSgpIHtcbiAgICByZXR1cm4gY29uZmlnLmF0dHJzLmxvYWQ7XG59XG5cblxuLyoqXG4gKiBMb2FkQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZCB0aGF0IHBhcnNlcyBsb2FkIGF0dHJpYnV0ZSBpZiBpdCBpcyBwcmVzZW50IG9uIHRoZSBlbGVtZW50LlxuICogSXQgZGVmaW5lcyBwcm9wZXJ0eSBgbG9hZFVybGAgb24gTG9hZEF0dHJpYnV0ZSBpbnN0YW5jZS5cbiAqIFJldHVybnMgdGhlIGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gKlxuICogQHJldHVybiB7TG9hZEF0dHJpYnV0ZX1cbiAqL1xuZnVuY3Rpb24gcGFyc2UoKSB7XG4gICAgaWYgKCEgdGhpcy5ub2RlKSByZXR1cm47XG5cbiAgICB0aGlzLmxvYWRVcmwgPSB0aGlzLmdldCgpO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogTG9hZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCBzaG91bGQgdmFsaWRhdGUgbG9hZCBhdHRyaWJ1dGUgYW5kIHRocm93IGlmIGl0IGhhcyBhbiBpbnZhbGlkIHZhbHVlLlxuICogVE9ETyAtIGltcGxlbWVudCB1cmwgdmFsaWRhdGlvbi5cbiAqIFJldHVybnMgdGhlIGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gKlxuICogQHJldHVybiB7TG9hZEF0dHJpYnV0ZX1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gICAgLy8gVE9ETyB1cmwgdmFsaWRhdGlvblxuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogTG9hZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgLSByZXR1cm5zIFVSTFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgIHJldHVybiB0aGlzLmxvYWRVcmw7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU3ViY2xhc3NlcyBvZiBbQXR0cmlidXRlXSguL2FfY2xhc3MuanMuaHRtbCkgY2xhc3NcbiAqXG4gKiAtIFtCaW5kQXR0cmlidXRlXSguL2FfYmluZC5qcy5odG1sKVxuICogLSBbTG9hZEF0dHJpYnV0ZV0oLi9hX2xvYWQuanMuaHRtbClcbiAqL1xudmFyIGF0dHJpYnV0ZXMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBiaW5kOiByZXF1aXJlKCcuL2FfYmluZCcpLFxuICAgIGxvYWQ6IHJlcXVpcmUoJy4vYV9sb2FkJylcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBtaWxvTWFpbCA9IHJlcXVpcmUoJy4vc2VydmljZXMvbWFpbCcpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvY19yZWdpc3RyeScpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9jZl9yZWdpc3RyeScpXG4gICAgLCBDb21wb25lbnQgPSBjb21wb25lbnRzUmVnaXN0cnkuZ2V0KCdDb21wb25lbnQnKVxuICAgICwgQ29tcG9uZW50SW5mbyA9IHJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2luZm8nKVxuICAgICwgU2NvcGUgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvc2NvcGUnKVxuICAgICwgQmluZEF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4vYXR0cmlidXRlcy9hX2JpbmQnKVxuICAgICwgQmluZGVyRXJyb3IgPSByZXF1aXJlKCcuL3V0aWwvZXJyb3InKS5CaW5kZXJcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuL3V0aWwvY2hlY2snKVxuICAgICwgdXRpbERvbSA9IHJlcXVpcmUoJy4vdXRpbC9kb20nKVxuICAgICwgTWF0Y2ggPSAgY2hlY2suTWF0Y2g7XG5cblxuYmluZGVyLnNjYW4gPSBzY2FuO1xuYmluZGVyLmNyZWF0ZSA9IGNyZWF0ZTtcbmJpbmRlci50d29QYXNzID0gdHdvUGFzcztcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmRlcjtcblxuXG4vKipcbiAqIGBtaWxvLmJpbmRlcmBcbiAqXG4gKiBSZWN1cnNpdmVseSBzY2FucyB0aGUgZG9jdW1lbnQgdHJlZSBpbnNpZGUgYHNjb3BlRWxgIChkb2N1bWVudC5ib2R5IGJ5IGRlZmF1bHQpIGxvb2tpbmcgZm9yIF9fbWwtYmluZF9fIGF0dHJpYnV0ZSB0aGF0IHNob3VsZCBjb250YWluIHRoZSBjbGFzcywgYWRkaXRpb25hbCBmYWNldHMgYW5kIHRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnQgdGhhdCBzaG91bGQgYmUgY3JlYXRlZCBhbmQgYm91bmQgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogUG9zc2libGUgdmFsdWVzIG9mIF9fbWwtYmluZF9fIGF0dHJpYnV0ZTpcbiAqXG4gKiAtIGA6bXlWaWV3YCAtIG9ubHkgY29tcG9uZW50IG5hbWUuIEFuIGluc3RhbmNlIG9mIENvbXBvbmVudCBjbGFzcyB3aWxsIGJlIGNyZWF0ZWQgd2l0aG91dCBhbnkgZmFjZXRzLlxuICogLSBgVmlldzpteVZpZXdgIC0gY2xhc3MgYW5kIGNvbXBvbmVudCBuYW1lLiBBbiBpbnN0YW5jZSBvZiBWaWV3IGNsYXNzIHdpbGwgYmUgY3JlYXRlZC5cbiAqIC0gYFtFdmVudHMsIERhdGFdOm15Vmlld2AgLSBmYWNldHMgYW5kIGNvbXBvbmVudCBuYW1lLiBBbiBpbnN0YW5jZSBvZiBDb21wb25lbnQgY2xhc3Mgd2lsbCBiZSBjcmVhdGVkIHdpdGggdGhlIGFkZGl0aW9uIG9mIGZhY2V0cyBFdmVudHMgYW5kIERhdGEuXG4gKiAtIGBWaWV3W0V2ZW50cywgRGF0YV06bXlWaWV3YCAtIGNsYXNzLCBmYWNldChzKSBhbmQgY29tcG9uZW50IG5hbWUuIEFuIGluc3RhbmNlIG9mIFZpZXcgY2xhc3Mgd2lsbCBiZSBjcmVhdGVkIHdpdGggdGhlIGFkZGl0aW9uIG9mIGZhY2V0cyBFdmVudHMgYW5kIERhdGEuXG4gKlxuICogRnVuY3Rpb24gcmV0dXJucyBhbiBpbnN0YW5jZSBvZiBbYFNjb3BlYF0oLi9jb21wb25lbnRzL3Njb3BlLmpzLmh0bWwpIGNsYXNzIGNvbnRhaW5pbmcgYWxsIGNvbXBvbmVudHMgY3JlYXRlZCBhcyBhIHJlc3VsdCBvZiBzY2FubmluZyBET00uXG4gKlxuICogSWYgdGhlIGNvbXBvbmVudCBoYXMgW2BDb250YWluZXJgXSguL2NvbXBvbmVudHMvY19mYWNldHMvQ29udGFpbmVyLmpzKSBmYWNldCwgY2hpbGRyZW4gb2YgdGhpcyBlbGVtZW50IHdpbGwgYmUgc3RvcmVkIGluIHRoZSBgc2NvcGVgIG9iamVjdCwgYXZhaWxhYmxlIGFzIHNjb3BlIHByb3BlcnR5IG9uIHRoZSBDb250YWluZXIgZmFjZXQgb2YgdGhpcyBjb21wb25lbnQuIE5hbWVzIG9mIGNvbXBvbmVudHMgd2l0aGluIHRoZSBzY29wZSBzaG91bGQgYmUgdW5pcXVlLCBidXQgdGhleSBjYW4gYmUgdGhlIHNhbWUgYXMgdGhlIG5hbWVzIG9mIGNvbXBvbmVudHMgaW4gb3V0ZXIgc2NvcGUgKG9yIHNvbWUgb3RoZXIgc2NvcGUpLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gc2NvcGVFbCByb290IGVsZW1lbnQgaW5zaWRlIHdoaWNoIERPTSB3aWxsIGJlIHNjYW5uZWQgYW5kIGJvdW5kXG4gKiBAcGFyYW0ge1Njb3BlfSByb290U2NvcGUgT3B0aW9uYWwgUm9vdCBzY29wZSBvYmplY3Qgd2hlcmUgdG9wIGxldmVsIGNvbXBvbmVudHMgd2lsbCBiZSBzYXZlZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gYmluZFJvb3RFbGVtZW50IElmIHNldCB0byBmYWxzZSwgdGhlbiB0aGUgcm9vdCBlbGVtZW50IHdpbGwgbm90IGJlIGJvdW5kLiBUcnVlIGJ5IGRlZmF1bHQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHRocm93T25FcnJvcnMgSWYgc2V0IHRvIGZhbHNlLCB0aGVuIGVycm9ycyB3aWxsIG9ubHkgYmUgbG9nZ2VkIHRvIGNvbnNvbGUuIFRydWUgYnkgZGVmYXVsdC5cbiAqIEByZXR1cm4ge1Njb3BlfVxuICovXG5mdW5jdGlvbiBiaW5kZXIoc2NvcGVFbCwgcm9vdFNjb3BlLCBiaW5kUm9vdEVsZW1lbnQsIHRocm93T25FcnJvcnMpIHtcbiAgICByZXR1cm4gY3JlYXRlQmluZGVyU2NvcGUoc2NvcGVFbCwgZnVuY3Rpb24oc2NvcGUsIGVsLCBhdHRyLCB0aHJvd09uRXJyb3JzKSB7XG4gICAgICAgIHZhciBpbmZvID0gbmV3IENvbXBvbmVudEluZm8oc2NvcGUsIGVsLCBhdHRyLCB0aHJvd09uRXJyb3JzKTtcbiAgICAgICAgcmV0dXJuIENvbXBvbmVudC5jcmVhdGUoaW5mbywgdGhyb3dPbkVycm9ycyk7XG4gICAgfSwgcm9vdFNjb3BlLCBiaW5kUm9vdEVsZW1lbnQsIHRocm93T25FcnJvcnMpO1xufVxuXG5cbi8vIGJpbmQgaW4gdHdvIHBhc3Nlc1xuZnVuY3Rpb24gdHdvUGFzcyhzY29wZUVsLCByb290U2NvcGUsIGJpbmRSb290RWxlbWVudCwgdGhyb3dPbkVycm9ycykge1xuICAgIHZhciBzY2FuU2NvcGUgPSBiaW5kZXIuc2NhbihzY29wZUVsLCByb290U2NvcGUsIGJpbmRSb290RWxlbWVudCwgdGhyb3dPbkVycm9ycyk7XG4gICAgcmV0dXJuIGJpbmRlci5jcmVhdGUoc2NhblNjb3BlLCB1bmRlZmluZWQsIHRocm93T25FcnJvcnMpO1xufVxuXG5cbi8vIHNjYW4gRE9NIGZvciBCaW5kQXR0cmlidXRlXG5mdW5jdGlvbiBzY2FuKHNjb3BlRWwsIHJvb3RTY29wZSwgYmluZFJvb3RFbGVtZW50LCB0aHJvd09uRXJyb3JzKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJpbmRlclNjb3BlKHNjb3BlRWwsIGZ1bmN0aW9uKHNjb3BlLCBlbCwgYXR0ciwgdGhyb3dPbkVycm9ycykge1xuICAgICAgICByZXR1cm4gbmV3IENvbXBvbmVudEluZm8oc2NvcGUsIGVsLCBhdHRyLCB0aHJvd09uRXJyb3JzKTtcbiAgICB9LCByb290U2NvcGUsIGJpbmRSb290RWxlbWVudCwgdGhyb3dPbkVycm9ycyk7XG59XG5cblxuLy8gY3JlYXRlIGJvdW5kIGNvbXBvbmVudHNcbmZ1bmN0aW9uIGNyZWF0ZShzY2FuU2NvcGUsIGhvc3RPYmplY3QsIHRocm93T25FcnJvcnMpIHtcbiAgICB2YXIgc2NvcGUgPSBuZXcgU2NvcGUoc2NhblNjb3BlLl9yb290RWwsIGhvc3RPYmplY3QpXG4gICAgICAgICwgYWRkTWV0aG9kID0gdGhyb3dPbkVycm9ycyA9PT0gZmFsc2UgPyAnX3NhZmVBZGQnIDogJ19hZGQnO1xuXG4gICAgc2NhblNjb3BlLl9lYWNoKGZ1bmN0aW9uKGNvbXBJbmZvKSB7XG4gICAgICAgIC8vIHNldCBjb3JyZWN0IGNvbXBvbmVudCdzIHNjb3BlXG4gICAgICAgIHZhciBpbmZvID0gXy5jbG9uZShjb21wSW5mbylcbiAgICAgICAgaW5mby5zY29wZSA9IHNjb3BlO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBjb21wb25lbnRcbiAgICAgICAgdmFyIGFDb21wb25lbnQgPSBDb21wb25lbnQuY3JlYXRlKGluZm8sIHRocm93T25FcnJvcnMpO1xuXG4gICAgICAgIHNjb3BlW2FkZE1ldGhvZF0oYUNvbXBvbmVudCwgYUNvbXBvbmVudC5uYW1lKTtcbiAgICAgICAgaWYgKGFDb21wb25lbnQuY29udGFpbmVyKVxuICAgICAgICAgICAgYUNvbXBvbmVudC5jb250YWluZXIuc2NvcGUgPSBjcmVhdGUoY29tcEluZm8uY29udGFpbmVyLnNjb3BlLCBhQ29tcG9uZW50LmNvbnRhaW5lciwgdGhyb3dPbkVycm9ycyk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2NvcGU7XG59XG5cbi8qKlxuICogYGNyZWF0ZUJpbmRlclNjb3BlYFxuICogQHBhcmFtICB7RWxlbWVudH0gc2NvcGVFbCAgICAgICAgICAgICBzY29wZUVsIHJvb3QgZWxlbWVudCBpbnNpZGUgd2hpY2ggRE9NIHdpbGwgYmUgc2Nhbm5lZCBhbmQgYm91bmQgKGRvY3VtZW50LmJvZHkgYnkgZGVmYXVsdCkuXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gc2NvcGVPYmplY3RGYWN0b3J5IFNlZSBbYmluZGVyXSgjbWlsby5iaW5kZXIpXG4gKiBAcGFyYW0gIHtTY29wZX0gcm9vdFNjb3BlICAgICAgICAgICAgIE9wdGlvbmFsIFJvb3Qgc2NvcGUgb2JqZWN0IHdoZXJlIHRvcCBsZXZlbCBjb21wb25lbnRzIHdpbGwgYmUgc2F2ZWQuXG4gKiBAcGFyYW0gIHtCb29sZWFufSBiaW5kUm9vdEVsZW1lbnQgICAgIElmIHNldCB0byBmYWxzZSwgdGhlbiB0aGUgcm9vdCBlbGVtZW50IHdpbGwgbm90IGJlIGJvdW5kLiBUcnVlIGJ5IGRlZmF1bHQuXG4gKiBAcGFyYW0gIHtCb29sZWFufSB0aHJvd09uRXJyb3JzICAgICAgIElmIHNldCB0byBmYWxzZSwgdGhlbiBlcnJvcnMgd2lsbCBvbmx5IGJlIGxvZ2dlZCB0byBjb25zb2xlLiBUcnVlIGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJuIHtTY29wZX0gICAgICAgICAgICAgICAgICAgICAgIFtkZXNjcmlwdGlvbl1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmluZGVyU2NvcGUoc2NvcGVFbCwgc2NvcGVPYmplY3RGYWN0b3J5LCByb290U2NvcGUsIGJpbmRSb290RWxlbWVudCwgdGhyb3dPbkVycm9ycykge1xuICAgIHZhciBzY29wZUVsID0gc2NvcGVFbCB8fCBkb2N1bWVudC5ib2R5XG4gICAgICAgICwgc2NvcGUgPSByb290U2NvcGUgfHwgbmV3IFNjb3BlKHNjb3BlRWwpXG4gICAgICAgICwgYWRkTWV0aG9kID0gdGhyb3dPbkVycm9ycyA9PT0gZmFsc2UgPyAnX3NhZmVBZGQnIDogJ19hZGQnO1xuXG4gICAgY3JlYXRlU2NvcGVGb3JFbGVtZW50KHNjb3BlLCBzY29wZUVsLCBiaW5kUm9vdEVsZW1lbnQpO1xuXG4gICAgcmV0dXJuIHNjb3BlO1xuXG5cbiAgICBmdW5jdGlvbiBjcmVhdGVTY29wZUZvckVsZW1lbnQoc2NvcGUsIGVsLCBiaW5kUm9vdEVsZW1lbnQpIHtcbiAgICAgICAgLy8gZ2V0IGVsZW1lbnQncyBiaW5kaW5nIGF0dHJpYnV0ZSAobWwtYmluZCBieSBkZWZhdWx0KVxuICAgICAgICB2YXIgYXR0ciA9IG5ldyBCaW5kQXR0cmlidXRlKGVsKTtcblxuICAgICAgICAvLyBpZiBlbGVtZW50IGhhcyBiaW5kIGF0dHJpYnV0ZSBjcmF0ZSBzY29wZSBvYmplY3QgKENvbXBvbmVudCBvciBDb21wb25lbnRJbmZvKVxuICAgICAgICBpZiAoYXR0ci5ub2RlICYmIGJpbmRSb290RWxlbWVudCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHZhciBzY29wZWRPYmplY3QgPSBzY29wZU9iamVjdEZhY3Rvcnkoc2NvcGUsIGVsLCBhdHRyLCB0aHJvd09uRXJyb3JzKVxuICAgICAgICAgICAgICAgICwgaXNDb250YWluZXIgPSB0eXBlb2Ygc2NvcGVkT2JqZWN0ICE9ICd1bmRlZmluZWQnICYmIHNjb3BlZE9iamVjdC5jb250YWluZXI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGVyZSBhcmUgY2hpbGROb2RlcyBhZGQgY2hpbGRyZW4gdG8gbmV3IHNjb3BlIGlmIHRoaXMgZWxlbWVudCBoYXMgY29tcG9uZW50IHdpdGggQ29udGFpbmVyIGZhY2V0XG4gICAgICAgIC8vIG90aGVyd2lzZSBjcmVhdGUgYSBuZXcgc2NvcGVcbiAgICAgICAgaWYgKGVsLmNoaWxkTm9kZXMgJiYgZWwuY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChpc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHZhciBpbm5lclNjb3BlID0gbmV3IFNjb3BlKGVsKTtcbiAgICAgICAgICAgICAgICBzY29wZWRPYmplY3QuY29udGFpbmVyLnNjb3BlID0gaW5uZXJTY29wZTtcbiAgICAgICAgICAgICAgICBpbm5lclNjb3BlLl9ob3N0T2JqZWN0ID0gc2NvcGVkT2JqZWN0LmNvbnRhaW5lcjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY3JlYXRlU2NvcGVGb3JDaGlsZHJlbihlbCwgaXNDb250YWluZXIgPyBpbm5lclNjb3BlIDogc2NvcGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgc2NvcGUgd2Fzbid0IHByZXZpb3VzbHkgY3JlYXRlZCBvbiBjb250YWluZXIgZmFjZXQsIGNyZWF0ZSBlbXB0eSBzY29wZSBhbnl3YXlcbiAgICAgICAgaWYgKGlzQ29udGFpbmVyICYmICEgc2NvcGVkT2JqZWN0LmNvbnRhaW5lci5zY29wZSlcbiAgICAgICAgICAgIHNjb3BlZE9iamVjdC5jb250YWluZXIuc2NvcGUgPSBuZXcgU2NvcGUoZWwpO1xuXG5cbiAgICAgICAgLy8gVE9ETyBjb25kaXRpb24gYWZ0ZXIgJiYgaXMgYSBoYWNrLCBzaG91bGQgbm90IGJlIHVzZWQhXG4gICAgICAgIGlmIChzY29wZWRPYmplY3QpIC8vICYmICEgc2NvcGVbYXR0ci5jb21wTmFtZV0pXG4gICAgICAgICAgICBzY29wZVthZGRNZXRob2RdKHNjb3BlZE9iamVjdCwgYXR0ci5jb21wTmFtZSk7XG5cbiAgICAgICAgLy8gXy5kZWZlcihwb3N0Q2hpbGRyZW5Cb3VuZE1lc3NhZ2UsIGVsKTtcbiAgICAgICAgcG9zdENoaWxkcmVuQm91bmRNZXNzYWdlKGVsKTtcblxuICAgICAgICByZXR1cm4gc2NvcGVkT2JqZWN0O1xuXG5cbiAgICAgICAgZnVuY3Rpb24gcG9zdENoaWxkcmVuQm91bmRNZXNzYWdlKGVsKSB7XG4gICAgICAgICAgICB2YXIgZWxDb21wID0gQ29tcG9uZW50LmdldENvbXBvbmVudChlbCk7XG5cbiAgICAgICAgICAgIGlmIChlbENvbXApXG4gICAgICAgICAgICAgICAgZWxDb21wLnBvc3RNZXNzYWdlU3luYygnY2hpbGRyZW5ib3VuZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjcmVhdGVTY29wZUZvckNoaWxkcmVuKGNvbnRhaW5lckVsLCBzY29wZSkge1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSB1dGlsRG9tLmNoaWxkcmVuKGNvbnRhaW5lckVsKTtcblxuICAgICAgICBfLmZvckVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgICAgIGNyZWF0ZVNjb3BlRm9yRWxlbWVudChzY29wZSwgbm9kZSwgdHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2NvcGU7XG4gICAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwiY2xhc3Nlc1wiPjwvYT5cbi8vIG1pbG8uY2xhc3Nlc1xuLy8gLS0tLS0tLS0tLS1cblxuLy8gVGhpcyBtb2R1bGUgY29udGFpbnMgZm91bmRhdGlvbiBjbGFzc2VzIGFuZCBjbGFzcyByZWdpc3RyaWVzLlxuXG52YXIgY2xhc3NlcyA9IHtcbiAgICBGYWNldDogcmVxdWlyZSgnLi9hYnN0cmFjdC9mYWNldCcpLFxuICAgIEZhY2V0ZWRPYmplY3Q6IHJlcXVpcmUoJy4vYWJzdHJhY3QvZmFjZXRlZF9vYmplY3QnKSxcbiAgICBTY29wZTogcmVxdWlyZSgnLi9jb21wb25lbnRzL3Njb3BlJyksXG4gICAgQ2xhc3NSZWdpc3RyeTogcmVxdWlyZSgnLi9hYnN0cmFjdC9yZWdpc3RyeScpLFxuICAgIE1peGluOiByZXF1aXJlKCcuL2Fic3RyYWN0L21peGluJyksXG4gICAgTWVzc2FnZVNvdXJjZTogcmVxdWlyZSgnLi9tZXNzZW5nZXIvbV9zb3VyY2UnKSxcbiAgICBNZXNzZW5nZXJNZXNzYWdlU291cmNlOiByZXF1aXJlKCcuL21lc3Nlbmdlci9tc25ncl9zb3VyY2UnKSxcbiAgICBNZXNzZW5nZXJBUEk6IHJlcXVpcmUoJy4vbWVzc2VuZ2VyL21fYXBpJyksXG4gICAgRE9NRXZlbnRzU291cmNlOiByZXF1aXJlKCcuL2NvbXBvbmVudHMvbXNnX3NyYy9kb21fZXZlbnRzJyksXG4gICAgVHJhbnNhY3Rpb246IHJlcXVpcmUoJy4vY29tbWFuZC90cmFuc2FjdGlvbicpLFxuICAgIFRyYW5zYWN0aW9uSGlzdG9yeTogcmVxdWlyZSgnLi9jb21tYW5kL3RyYW5zYWN0aW9uX2hpc3RvcnknKVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFzc2VzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBBY3Rpb25zSGlzdG9yeTtcblxuXG4vKipcbiAqIFN0b3JlcyBsaXN0IG9mIGNvbW1hbmRzIG9yIHRyYW5zYWN0aW9uc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtOdW1iZXJ9IG1heExlbmd0aFxuICovXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeShtYXhMZW5ndGgpIHtcbiAgICB0aGlzLl9tYXhMZW5ndGggPSBtYXhMZW5ndGggfHwgSW5maW5pdHk7XG4gICAgdGhpcy5hY3Rpb25zID0gW107XG4gICAgdGhpcy5wb3NpdGlvbiA9IDA7XG59XG5cblxuXy5leHRlbmRQcm90byhBY3Rpb25zSGlzdG9yeSwge1xuICAgIHN0b3JlOiBBY3Rpb25zSGlzdG9yeSRzdG9yZSxcbiAgICBkZWxldGVMYXN0OiBBY3Rpb25zSGlzdG9yeSRkZWxldGVMYXN0LFxuICAgIHVuZG86IEFjdGlvbnNIaXN0b3J5JHVuZG8sXG4gICAgcmVkbzogQWN0aW9uc0hpc3RvcnkkcmVkbyxcbiAgICB1bmRvQWxsOiBBY3Rpb25zSGlzdG9yeSR1bmRvQWxsLFxuICAgIHJlZG9BbGw6IEFjdGlvbnNIaXN0b3J5JHJlZG9BbGwsXG4gICAgdW5kb0FsbEFzeW5jOiBBY3Rpb25zSGlzdG9yeSR1bmRvQWxsQXN5bmMsXG4gICAgcmVkb0FsbEFzeW5jOiBBY3Rpb25zSGlzdG9yeSRyZWRvQWxsQXN5bmMsXG4gICAgZWFjaDogQWN0aW9uc0hpc3RvcnkkZWFjaCxcbiAgICBlYWNoUmV2ZXJzZTogQWN0aW9uc0hpc3RvcnkkZWFjaFJldmVyc2UsXG4gICAgZ2V0TGFzdEFjdGlvbjogQWN0aW9uc0hpc3RvcnkkZ2V0TGFzdEFjdGlvbixcblxuICAgIGdldERlc2NyaXB0aW9uOiBBY3Rpb25zSGlzdG9yeSRnZXREZXNjcmlwdGlvblxufSk7XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3Rvcnkkc3RvcmUoY29tbWFuZCkge1xuICAgIF90cnVuY2F0ZVRvQ3VycmVudFBvc2l0aW9uLmNhbGwodGhpcyk7XG4gICAgdGhpcy5hY3Rpb25zLnB1c2goY29tbWFuZCk7XG5cbiAgICBpZiAodGhpcy5hY3Rpb25zLmxlbmd0aCA+IHRoaXMuX21heExlbmd0aCkge1xuICAgICAgICB2YXIgYWN0ID0gdGhpcy5hY3Rpb25zLnNoaWZ0KCk7XG4gICAgICAgIGFjdC5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgdGhpcy5wb3NpdGlvbiA9IHRoaXMuYWN0aW9ucy5sZW5ndGg7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24gLSAxXG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkZGVsZXRlTGFzdCgpIHtcbiAgICBpZiAoIXRoaXMuYWN0aW9ucy5sZW5ndGgpIHJldHVybjtcbiAgICB0aGlzLnBvc2l0aW9uLS07XG4gICAgdGhpcy5hY3Rpb25zLmxlbmd0aC0tO1xufVxuXG5cbmZ1bmN0aW9uIF90cnVuY2F0ZVRvQ3VycmVudFBvc2l0aW9uKCkge1xuICAgIGZvciAodmFyIGkgPSB0aGlzLnBvc2l0aW9uOyBpIDwgdGhpcy5hY3Rpb25zLmxlbmd0aDsgaSsrKVxuICAgICAgICB0aGlzLmFjdGlvbnNbaV0uZGVzdHJveSgpO1xuICAgIHRoaXMuYWN0aW9ucy5sZW5ndGggPSB0aGlzLnBvc2l0aW9uO1xufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JHVuZG8oY2IpIHtcbiAgICBpZiAodGhpcy5wb3NpdGlvbiA9PSAwKSByZXR1cm47IC8vIG5vdGhpbmcgdG8gdW5kb1xuICAgIHZhciBhY3QgPSB0aGlzLmFjdGlvbnNbLS10aGlzLnBvc2l0aW9uXTtcbiAgICBhY3QudW5kbyhjYik7XG4gICAgcmV0dXJuIGFjdDtcbn1cblxuXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeSRyZWRvKGNiKSB7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gPT0gdGhpcy5hY3Rpb25zLmxlbmd0aCkgcmV0dXJuOyAvLyBub3RoaW5nIHRvIHJlZG9cbiAgICB2YXIgYWN0ID0gdGhpcy5hY3Rpb25zW3RoaXMucG9zaXRpb24rK107XG4gICAgYWN0LnJlZG8oY2IpO1xuICAgIHJldHVybiBhY3Q7XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkdW5kb0FsbCgpIHtcbiAgICB3aGlsZSAodGhpcy5wb3NpdGlvbikgdGhpcy51bmRvKCk7XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkcmVkb0FsbCgpIHtcbiAgICB3aGlsZSAodGhpcy5wb3NpdGlvbiA8IHRoaXMuYWN0aW9ucy5sZW5ndGgpIHRoaXMucmVkbygpO1xufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JHVuZG9BbGxBc3luYyhjYikge1xuICAgIGlmICh0aGlzLnBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMudW5kbygpO1xuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbilcbiAgICAgICAgICAgIF8uZGVmZXJNZXRob2QodGhpcywgJ3VuZG9BbGxBc3luYycsIGNiKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgaWYgKGNiKSBfLmRlZmVyKGNiKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkcmVkb0FsbEFzeW5jKGNiKSB7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gPCB0aGlzLmFjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucmVkbygpO1xuICAgICAgICBpZiAodGhpcy5wb3NpdGlvbiA8IHRoaXMuYWN0aW9ucy5sZW5ndGgpIFxuICAgICAgICAgICAgXy5kZWZlck1ldGhvZCh0aGlzLCAncmVkb0FsbEFzeW5jJywgY2IpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBpZiAoY2IpIF8uZGVmZXIoY2IpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeSRlYWNoKGZ1bmNPck1ldGhvZCwgdGhpc0FyZykge1xuICAgIHZhciBmdW5jID0gdHlwZW9mIGZ1bmNPck1ldGhvZCA9PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgID8gZnVuY3Rpb24oYWN0KSB7IGFjdFtmdW5jT3JNZXRob2RdKCk7IH1cbiAgICAgICAgICAgICAgICA6IGZ1bmNPck1ldGhvZDtcblxuICAgIHRoaXMuYWN0aW9ucy5mb3JFYWNoKGZ1bmMsIHRoaXNBcmcgfHwgdGhpcyk7XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkZWFjaFJldmVyc2UoZnVuY09yTWV0aG9kLCB0aGlzQXJnKSB7XG4gICAgdGhpcy5hY3Rpb25zLnJldmVyc2UoKTtcbiAgICB0aGlzLmVhY2goZnVuY09yTWV0aG9kLCB0aGlzQXJnKTtcbiAgICB0aGlzLmFjdGlvbnMucmV2ZXJzZSgpO1xufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JGdldExhc3RBY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb24gJiYgdGhpcy5hY3Rpb25zW3RoaXMucG9zaXRpb24gLSAxXTtcbn1cblxuXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeSRnZXREZXNjcmlwdGlvbigpIHtcbiAgICB2YXIgYWN0aW9ucyA9IHRoaXMuYWN0aW9ucy5tYXAoZnVuY3Rpb24oYWN0KSB7XG4gICAgICAgIHJldHVybiBhY3QuZ2V0RGVzY3JpcHRpb24oKTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgICBhY3Rpb25zOiBhY3Rpb25zLFxuICAgICAgICBwb3NpdGlvbjogdGhpcy5wb3NpdGlvbixcbiAgICAgICAgbGVuZ3RoOiBhY3Rpb25zLmxlbmd0aFxuICAgIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzc1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vYWJzdHJhY3QvcmVnaXN0cnknKVxuICAgICwgQ29tbWFuZCA9IHJlcXVpcmUoJy4vaW5kZXgnKTtcblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5jb21wb25lbnRzYFxuICogQW4gaW5zdGFuY2Ugb2YgW0NsYXNzUmVnaXN0cnldKC4uL2Fic3RyYWN0L3JlZ2lzdHJ5LmpzLmh0bWwpIGNsYXNzIHRoYXQgaXMgdXNlZCBieSBtaWxvIHRvIHJlZ2lzdGVyIGFuZCBmaW5kIGNvbXBvbmVudHMuXG4gKi9cbnZhciBjb21tYW5kc1JlZ2lzdHJ5ID0gbmV3IENsYXNzUmVnaXN0cnkoQ29tbWFuZCk7XG5cbi8vIGFkZCBjb21tb24gYW5jZXN0b3IgdG8gYWxsIGNvbXBvbmVudHMgdG8gdGhlIHJlZ2lzdHJ5LlxuY29tbWFuZHNSZWdpc3RyeS5hZGQoQ29tbWFuZCk7XG5cbm1vZHVsZS5leHBvcnRzID0gY29tbWFuZHNSZWdpc3RyeTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKTtcblxuXG52YXIgVU5ET19DT01NQU5EID0gJ191bmRvQ29tbWFuZCc7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBDb21tYW5kO1xuXG5cbi8qKlxuICogQ29tbWFuZCBjbGFzcyB0byBpbXBsZW1lbnQgXCJjb21tYW5kIHBhdHRlcm5cIiAtIHBhY2thZ2luZyBsbCBpbmZvcm1hdGlvbiBuZWNlc3NhcnkgZm9yIGRlbGF5ZWQgbWV0aG9kIGV4ZWN1dGlvblxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBtZXRob2QgbmFtZSBvciBmdW5jdGlvbiB0byBiZSBleGVjdXRlZFxuICogQHBhcmFtIHtMaXN0fSAqYXJndW1lbnRzIHBhcmFtZXRlcnMgdG8gYmUgcGFzc2VkIHRvIG1ldGhvZCBvciBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBDb21tYW5kKGZ1bmMpIHsgLy8gLCAuLi4gYXJndW1lbnRzXG4gICAgdGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiBDb21tYW5kIGluc3RhbmNlIG1ldGhvZHNcbiAqIFxuICogLSBbaW5pdF0oI0NvbW1hbmQkZXhlY3V0ZSkgLSBpbml0aWFsaXplIGNvbW1hbmQsIHNob3VsZCBiZSBvdmVyd3JpdHRlbiBieSBzdWJjbGFzc2VzXG4gKiAtIFtleGVjdXRlXSgjQ29tbWFuZCRleGVjdXRlKSAtIGV4ZWN1dGUgY29tbWFuZFxuICogLSBbc2V0VW5kb10oI0NvbW1hbmQkc2V0VW5kbykgLSBzZXQgdW5kbyBjb21tYW5kIGZvciB0aGlzIGNvbW1hbmRcbiAqIC0gW2dldFVuZG9dKCNDb21tYW5kJGdldFVuZG8pIC0gZ2V0IHVuZG8gY29tbWFuZCBvZiB0aGlzIGNvbW1hbmRcbiAqIC0gW3NldEFyZ3VtZW50c10oI0NvbW1hbmQkc2V0QXJndW1lbnRzKSAtIHNldCBjb21tYW5kcyBhcmd1bWVudHNcbiAqIC0gW2FkZEFyZ3VtZW50c10oI0NvbW1hbmQkYWRkQXJndW1lbnRzKSAtIGFkZCBhcmd1bWVudHMgdG8gY29tbWFuZFxuICogLSBbZGVzdHJveV0oI0NvbW1hbmQkZGVzdHJveSlcbiAqL1xuXy5leHRlbmRQcm90byhDb21tYW5kLCB7XG4gICAgaW5pdDogQ29tbWFuZCRpbml0LFxuICAgIGV4ZWN1dGU6IENvbW1hbmQkZXhlY3V0ZSxcbiAgICBzZXRVbmRvOiBDb21tYW5kJHNldFVuZG8sXG4gICAgZ2V0VW5kbzogQ29tbWFuZCRnZXRVbmRvLFxuICAgIHVuZG86IENvbW1hbmQkdW5kbyxcbiAgICByZWRvOiBDb21tYW5kJGV4ZWN1dGUsIC8vIHNhbWUgZm9yIGNvbW1hbmQsIGRpZmZlcmVudCBmb3IgdHJhbnNhY3Rpb25cbiAgICBzZXRBcmd1bWVudHM6IENvbW1hbmQkc2V0QXJndW1lbnRzLFxuICAgIGFkZEFyZ3VtZW50czogQ29tbWFuZCRhZGRBcmd1bWVudHMsXG4gICAgZ2V0QXJndW1lbnRzOiBDb21tYW5kJGdldEFyZ3VtZW50cyxcbiAgICBjaGFuZ2VBcmd1bWVudHM6IENvbW1hbmQkY2hhbmdlQXJndW1lbnRzLFxuICAgIGRlc3Ryb3k6IENvbW1hbmQkZGVzdHJveSxcblxuICAgIHNldENvbW1lbnQ6IENvbW1hbmQkc2V0Q29tbWVudCxcbiAgICBnZXREZXNjcmlwdGlvbjogQ29tbWFuZCRnZXREZXNjcmlwdGlvblxufSk7XG5cblxuLyoqXG4gKiBDb21tYW5kIGNsYXNzIG1ldGhvZHNcbiAqXG4gKiAtIFtjcmVhdGVdKCNDb21tYW5kJCRjcmVhdGUpIC0gY29tbWFuZHMgZmFjdG9yeVxuICovXG5fLmV4dGVuZChDb21tYW5kLCB7XG4gICAgY3JlYXRlOiBDb21tYW5kJCRjcmVhdGUsXG4gICAgY3JlYXRlV2l0aFVuZG86IENvbW1hbmQkJGNyZWF0ZVdpdGhVbmRvXG59KTtcblxuXG5mdW5jdGlvbiBDb21tYW5kJGluaXQoZnVuYykgeyAvLyAsIC4uLiBhcmd1bWVudHNcbiAgICBjaGVjayhmdW5jLCBNYXRjaC5PcHRpb25hbChGdW5jdGlvbikpO1xuICAgIHRoaXMuZnVuYyA9IGZ1bmMgfHwgZnVuY3Rpb24oKXt9O1xuICAgIHRoaXMuYXJncyA9IF8uc2xpY2UoYXJndW1lbnRzLCAxKTsgICAgXG59XG5cblxuLyoqXG4gKiBFeGVjdXRlIGNvbW1hbmQgbWFraW5nIGNvbW1hbmQgb2JqZWN0IGF2YWlsYWJsZSB2aWEgZnVuY3Rpb24gcHJvcGVydHkuIFxuICovXG5mdW5jdGlvbiBDb21tYW5kJGV4ZWN1dGUoY2IpIHtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcy5mdW5jLmFwcGx5KHRoaXMsIHRoaXMuYXJncyk7XG4gICAgaWYgKGNiKSBfLmRlZmVyKGNiKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5cbi8qKlxuICogU2V0IHVuZG8gY29tbWFuZCBmb3IgdGhpcyBjb21tYW5kLiBUaGlzIGNvbW1hbmQgYmVjb21lcyB1bmRvIGNvbW1hbmQgZm9yIHVuZG8gY29tbWFuZCAoc28gdW5kbyBjb21tYW5kIGNhbiBjaGFuZ2UgdGhpcyBjb21tYW5kIGR1cmluZyBpdHMgZXhlY3V0aW9uKS5cbiAqIFxuICogQHBhcmFtIHtDb21tYW5kfSB1bmRvQ29tbWFuZFxuICovXG5mdW5jdGlvbiBDb21tYW5kJHNldFVuZG8odW5kb0NvbW1hbmQpIHtcbiAgICBpZiAodGhpc1tVTkRPX0NPTU1BTkRdKVxuICAgICAgICBsb2dnZXIud2FybignQ29tbWFuZCBzZXRVbmRvOiB1bmRvIGNvbW1hbmQgaXMgYWxyZWFkeSBzZXQnKTtcblxuICAgIHRoaXNbVU5ET19DT01NQU5EXSA9IHVuZG9Db21tYW5kO1xuICAgIHVuZG9Db21tYW5kW1VORE9fQ09NTUFORF0gPSB0aGlzO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB1bmRvIGNvbW1hbmQgb2YgYSBnaXZlbiBjb21tYW5kXG4gKlxuICogQHJldHVybiB7Q29tbWFuZH1cbiAqL1xuZnVuY3Rpb24gQ29tbWFuZCRnZXRVbmRvKCkge1xuICAgIHJldHVybiB0aGlzW1VORE9fQ09NTUFORF07XG59XG5cblxuLyoqXG4gKiBFeGVjdXRlcyB1bmRvIGNvbW1hbmQgb2YgY3VycmVudCBjb21tYW5kXG4gKi9cbmZ1bmN0aW9uIENvbW1hbmQkdW5kbyhjYikge1xuICAgIHZhciB1bmRvQ21kID0gdGhpcy5nZXRVbmRvKCk7XG4gICAgaWYgKCEgdW5kb0NtZCkgcmV0dXJuIGxvZ2dlci5lcnJvcignQ29tbWFuZCB1bmRvIGNhbGxlZCB3aXRob3V0IHVuZG8gY29tbWFuZCBwcmVzZW50Jyk7XG4gICAgdmFyIHJlc3VsdCA9IHVuZG9DbWQuZXhlY3V0ZSgpO1xuICAgIGlmIChjYikgXy5kZWZlcihjYik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vKipcbiAqIFNldCBjb21tYW5kJ3MgYXJndW1lbnRzLiBJZiBhcmd1bWVudHMgd2VyZSBzZXQgZHVyaW5nIGNvbW1hbmQncyBjcmVhdGlvbiwgdGhpcyBtZXRob2Qgd2lsbCBvdmVyd3JpdGUgYXJndW1lbnRzIGFuZCBsb2cgd2FybmluZy5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9ICphcmd1bWVudHNcbiAqL1xuZnVuY3Rpb24gQ29tbWFuZCRzZXRBcmd1bWVudHMoKSB7IC8vLCAuLi4gYXJndW1lbnRzXG4gICAgaWYgKHRoaXMuYXJncyAmJiB0aGlzLmFyZ3MubGVuZ3RoKVxuICAgICAgICBsb2dnZXIud2FybignQ29tbWFuZCBzZXRBcmd1bWVudHM6IGNvbW1hbmQgYXJndW1lbnRzIGFyZSBhbHJlYWR5IHNldCcpO1xuICAgIHRoaXMuYXJncyA9IF8udG9BcnJheShhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIENvbW1hbmQkZ2V0QXJndW1lbnRzKCkge1xuICAgIHJldHVybiB0aGlzLmFyZ3M7XG59XG5cblxuZnVuY3Rpb24gQ29tbWFuZCRjaGFuZ2VBcmd1bWVudHMoKSB7IC8vLCAuLi4gYXJndW1lbnRzXG4gICAgdGhpcy5hcmdzID0gXy50b0FycmF5KGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiBBZGQgKGFwcGVuZCkgYXJndW1lbnRzIHRvIGNvbW1hbmRcbiAqXG4gKiBAcGFyYW0ge0xpc3R9ICphcmd1bWVudHMgYXJndW1lbnRzIGxpc3QgdG8gYmUgYXBwZW5kZWQgdG8gY29tbWFuZFxuICovXG5mdW5jdGlvbiBDb21tYW5kJGFkZEFyZ3VtZW50cygpIHsgLy8sIC4uLiBhcmd1bWVudHNcbiAgICBpZiAoISB0aGlzLmFyZ3MpIHRoaXMuYXJncyA9IFtdO1xuICAgIF8uYXBwZW5kQXJyYXkodGhpcy5hcmdzLCBhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogQ29tbWFuZHMgZmFjdG9yeS4gTGlrZWx5IG90IGJlIG92ZXJyaWRkZW4gYnkgc3ViY2xhc3NlcyB0byBpbXBsZW1lbnQgY3VzdG9tIGxvZ2ljIG9mIGNvbW1hbmQgY29uc3RydWN0aW9uXG4gKiBcbiAqIEB0aGlzIHtGdW5jdGlvbn0gQ2xhc3Mgb2YgY29tbWFuZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBtZXRob2QgbmFtZSBvciBmdW5jdGlvbiB0byBiZSBleGVjdXRlZFxuICogQHBhcmFtIHtMaXN0fSAqYXJndW1lbnRzIHBhcmFtZXRlcnMgdG8gYmUgcGFzc2VkIHRvIG1ldGhvZCBvciBmdW5jdGlvblxuICogQHJldHVybiB7Q29tbWFuZH1cbiAqL1xuZnVuY3Rpb24gQ29tbWFuZCQkY3JlYXRlKGZ1bmMpIHsgLy8gLCAuLi4gYXJndW1lbnRzXG4gICAgcmV0dXJuIF8ubmV3QXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG5mdW5jdGlvbiBDb21tYW5kJCRjcmVhdGVXaXRoVW5kbygpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyZWF0ZVdpdGhVbmRvIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBieSBzdWJzY2xhc3MnKTtcbn1cblxuXG4vKipcbiAqIERlc3Ryb3kgY3VycmVudCBjb21tYW5kICh0byBwcmV2ZW50IHBvdGVudGlhbCBtZW1vcnkgbGVha3Mgd2hlbiBjb21tYW5kcyBwb2ludCB0byBET00gZWxlbWVudHMpXG4gKi9cbmZ1bmN0aW9uIENvbW1hbmQkZGVzdHJveSgpIHtcbiAgICBkZWxldGUgdGhpcy5mdW5jO1xuICAgIGRlbGV0ZSB0aGlzLmFyZ3M7XG4gICAgdmFyIHVuZG9DbWQgPSB0aGlzW1VORE9fQ09NTUFORF07XG4gICAgaWYgKHVuZG9DbWQpIHtcbiAgICAgICAgZGVsZXRlIHRoaXNbVU5ET19DT01NQU5EXVtVTkRPX0NPTU1BTkRdO1xuICAgICAgICBkZWxldGUgdGhpc1tVTkRPX0NPTU1BTkRdO1xuICAgICAgICB1bmRvQ21kLmRlc3Ryb3koKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gQ29tbWFuZCRzZXRDb21tZW50KGNvbW1lbnQpIHtcbiAgICB0aGlzLmNvbW1lbnQgPSBjb21tZW50O1xufVxuXG5cbmZ1bmN0aW9uIENvbW1hbmQkZ2V0RGVzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZnVuYzogdGhpcy5mdW5jLm5hbWUsXG4gICAgICAgIGNvbW1lbnQ6IHRoaXMuY29tbWVudFxuICAgIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIEFjdGlvbnNIaXN0b3J5ID0gcmVxdWlyZSgnLi9hY3Rpb25zX2hpc3RvcnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNhY3Rpb247XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24oKSB7XG4gICAgdGhpcy5jb21tYW5kcyA9IG5ldyBBY3Rpb25zSGlzdG9yeTtcbn1cblxuXG5fLmV4dGVuZFByb3RvKFRyYW5zYWN0aW9uLCB7XG4gICAgZXhlY3V0ZTogVHJhbnNhY3Rpb24kZXhlY3V0ZSxcbiAgICB1bmRvOiBUcmFuc2FjdGlvbiR1bmRvLFxuICAgIHJlZG86IFRyYW5zYWN0aW9uJHJlZG8sXG4gICAgZGVzdHJveTogVHJhbnNhY3Rpb24kZGVzdHJveSxcbiAgICBzdG9yZUNvbW1hbmQ6IFRyYW5zYWN0aW9uJHN0b3JlQ29tbWFuZCxcbiAgICBtZXJnZTogVHJhbnNhY3Rpb24kbWVyZ2UsXG5cbiAgICBzZXRDb21tZW50OiBUcmFuc2FjdGlvbiRzZXRDb21tZW50LFxuICAgIGdldERlc2NyaXB0aW9uOiBUcmFuc2FjdGlvbiRnZXREZXNjcmlwdGlvblxufSk7XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24kZXhlY3V0ZSgpIHtcbiAgICB0aGlzLmNvbW1hbmRzLmVhY2goJ2V4ZWN1dGUnKTtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbiR1bmRvKGNiKSB7XG4gICAgdGhpcy5jb21tYW5kcy51bmRvQWxsQXN5bmMoY2IpO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uJHJlZG8oY2IpIHtcbiAgICB0aGlzLmNvbW1hbmRzLnJlZG9BbGxBc3luYyhjYik7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24kZGVzdHJveSgpIHtcbiAgICB0aGlzLmNvbW1hbmRzLmVhY2goJ2Rlc3Ryb3knKTtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbiRzdG9yZUNvbW1hbmQoY29tbWFuZCkge1xuICAgIHRoaXMuY29tbWFuZHMuc3RvcmUoY29tbWFuZCk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24kbWVyZ2UodHJhbnNhY3Rpb24pIHtcbiAgICB0cmFuc2FjdGlvbi5jb21tYW5kcy5lYWNoKGZ1bmN0aW9uKGNtZCkge1xuICAgICAgICB0aGlzLmNvbW1hbmRzLnN0b3JlKGNtZCk7XG4gICAgfSwgdGhpcyk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24kc2V0Q29tbWVudChjb21tZW50KSB7XG4gICAgdGhpcy5jb21tZW50ID0gY29tbWVudFxufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uJGdldERlc2NyaXB0aW9uKCkge1xuICAgIHZhciBjb21tYW5kcyA9IHRoaXMuY29tbWFuZHMuZ2V0RGVzY3JpcHRpb24oKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBjb21tYW5kczogY29tbWFuZHMuYWN0aW9ucyxcbiAgICAgICAgY29tbWVudDogdGhpcy5jb21tZW50XG4gICAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBBY3Rpb25zSGlzdG9yeSA9IHJlcXVpcmUoJy4vYWN0aW9uc19oaXN0b3J5JylcbiAgICAsIFRyYW5zYWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc2FjdGlvbicpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNhY3Rpb25IaXN0b3J5O1xuXG5cbnZhciBTQ0hFRFVMRUQgPSAnX3NjaGVkdWxlZCc7XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5KG1heExlbmd0aCkge1xuICAgIHRoaXMudHJhbnNhY3Rpb25zID0gbmV3IEFjdGlvbnNIaXN0b3J5KG1heExlbmd0aCk7XG4gICAgdGhpcy5jdXJyZW50QmF0Y2ggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jdXJyZW50VHJhbnNhY3Rpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpc1tTQ0hFRFVMRURdID0gZmFsc2U7XG59XG5cblxuXy5leHRlbmRQcm90byhUcmFuc2FjdGlvbkhpc3RvcnksIHtcbiAgICBzdG9yZUNvbW1hbmQ6IFRyYW5zYWN0aW9uSGlzdG9yeSRzdG9yZUNvbW1hbmQsXG4gICAgZW5kVHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uSGlzdG9yeSRlbmRUcmFuc2FjdGlvbixcbiAgICBzdG9yZVRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbkhpc3Rvcnkkc3RvcmVUcmFuc2FjdGlvbixcbiAgICBkZWxldGVMYXN0VHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uSGlzdG9yeSRkZWxldGVMYXN0VHJhbnNhY3Rpb24sXG4gICAgdW5kbzogVHJhbnNhY3Rpb25IaXN0b3J5JHVuZG8sXG4gICAgcmVkbzogVHJhbnNhY3Rpb25IaXN0b3J5JHJlZG8sXG4gICAgaW5UcmFuc2FjdGlvbjogVHJhbnNhY3Rpb25IaXN0b3J5JGluVHJhbnNhY3Rpb24sXG5cbiAgICBnZXREZXNjcmlwdGlvbjogVHJhbnNhY3Rpb25IaXN0b3J5JGdldERlc2NyaXB0aW9uLFxuICAgIHVzZU1lc3NlbmdlcjogVHJhbnNhY3Rpb25IaXN0b3J5JHVzZU1lc3NlbmdlcixcbiAgICBkZXN0cm95OiBUcmFuc2FjdGlvbkhpc3RvcnkkZGVzdHJveVxufSk7XG5cblxuLyoqXG4gKiBTdG9yZXMgY29tbWFuZCBpbiB0aGUgaGlzdG9yeS4gXG4gKiBAcGFyYW0ge0NvbW1hbmR9IGNvbW1hbmQgICAgICAgICAgIFxuICogQHBhcmFtIHtCb29sZWFufSBhcHBlbmRUcmFuc2FjdGlvbiBJZiBgdHJ1ZWAsIGFwcGVuZHMgdG8gdGhlIGN1cnJlbnQgb3IgcHJldmlvdXMgdHJhbnNhY3Rpb24gaWYgdGhlcmUgaXMgbm8gY3VycmVudCB0cmFuc2FjdGlvbi5cbiAqL1xuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JHN0b3JlQ29tbWFuZChjb21tYW5kLCBhcHBlbmRUcmFuc2FjdGlvbikge1xuICAgIGlmIChhcHBlbmRUcmFuc2FjdGlvbiAmJiAhKHRoaXMuY3VycmVudFRyYW5zYWN0aW9uIHx8IHRoaXMuY3VycmVudEJhdGNoKSkge1xuICAgICAgICB2YXIgdHJhbnNhY3Rpb24gPSB0aGlzLnRyYW5zYWN0aW9ucy5nZXRMYXN0QWN0aW9uKCk7XG4gICAgICAgIHRyYW5zYWN0aW9uLnN0b3JlQ29tbWFuZChjb21tYW5kKTtcbiAgICAgICAgX3Bvc3RUcmFuc2FjdGlvbk1lc3NhZ2UuY2FsbCh0aGlzLCAnYXBwZW5kZWQnLCB0cmFuc2FjdGlvbik7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoISB0aGlzLmN1cnJlbnRCYXRjaCkgdGhpcy5jdXJyZW50QmF0Y2ggPSBuZXcgVHJhbnNhY3Rpb247XG4gICAgdGhpcy5jdXJyZW50QmF0Y2guc3RvcmVDb21tYW5kKGNvbW1hbmQpO1xuICAgIGlmICghIHRoaXNbU0NIRURVTEVEXSkge1xuICAgICAgICB0aGlzW1NDSEVEVUxFRF0gPSB0cnVlO1xuICAgICAgICBfLmRlZmVyTWV0aG9kKHRoaXMsIF9zdG9yZVRyYW5zYWN0aW9uKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JGRlbGV0ZUxhc3RUcmFuc2FjdGlvbigpIHtcbiAgICBpZiAodGhpcy5jdXJyZW50QmF0Y2ggfHwgdGhpcy5jdXJyZW50VHJhbnNhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50QmF0Y2ggPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uID0gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25zLmRlbGV0ZUxhc3QoKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gX3N0b3JlVHJhbnNhY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudEJhdGNoKSB7XG4gICAgICAgIF9hZGRCYXRjaFRvVHJhbnNhY3Rpb24uY2FsbCh0aGlzKTtcbiAgICAgICAgXy5kZWZlck1ldGhvZCh0aGlzLCBfc3RvcmVUcmFuc2FjdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgX3N0b3JlQ3VycmVudFRyYW5zYWN0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIHRoaXNbU0NIRURVTEVEXSA9IGZhbHNlO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbkhpc3RvcnkkZW5kVHJhbnNhY3Rpb24oKSB7XG4gICAgX2FkZEJhdGNoVG9UcmFuc2FjdGlvbi5jYWxsKHRoaXMpO1xuICAgIF9zdG9yZUN1cnJlbnRUcmFuc2FjdGlvbi5jYWxsKHRoaXMpO1xufVxuXG5cbmZ1bmN0aW9uIF9hZGRCYXRjaFRvVHJhbnNhY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudEJhdGNoKSB7XG4gICAgICAgIGlmICghIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uKSB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbjtcbiAgICAgICAgdGhpcy5jdXJyZW50VHJhbnNhY3Rpb24ubWVyZ2UodGhpcy5jdXJyZW50QmF0Y2gpO1xuICAgICAgICB0aGlzLmN1cnJlbnRCYXRjaCA9IHVuZGVmaW5lZDtcbiAgICB9IFxufVxuXG5cbmZ1bmN0aW9uIF9zdG9yZUN1cnJlbnRUcmFuc2FjdGlvbigpIHtcbiAgICBpZiAodGhpcy5jdXJyZW50VHJhbnNhY3Rpb24pIHtcbiAgICAgICAgdmFyIHQgPSB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbjtcbiAgICAgICAgdGhpcy50cmFuc2FjdGlvbnMuc3RvcmUodCk7XG4gICAgICAgIF9wb3N0VHJhbnNhY3Rpb25NZXNzYWdlLmNhbGwodGhpcywgJ3N0b3JlZCcsIHQpO1xuXG4gICAgICAgIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uID0gdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbkhpc3Rvcnkkc3RvcmVUcmFuc2FjdGlvbih0cmFuc2FjdGlvbikge1xuICAgIHRoaXMuZW5kVHJhbnNhY3Rpb24oKTtcblxuICAgIHRoaXMudHJhbnNhY3Rpb25zLnN0b3JlKHRyYW5zYWN0aW9uKTtcbiAgICBfcG9zdFRyYW5zYWN0aW9uTWVzc2FnZS5jYWxsKHRoaXMsICdzdG9yZWQnLCB0cmFuc2FjdGlvbik7XG59XG5cblxuZnVuY3Rpb24gX3Bvc3RUcmFuc2FjdGlvbk1lc3NhZ2UobXNnLCB0cmFuc2FjdGlvbikge1xuICAgIGlmICh0aGlzLl9tZXNzZW5nZXIpXG4gICAgICAgIHRoaXMuX21lc3Nlbmdlci5wb3N0TWVzc2FnZShtc2csIHsgdHJhbnNhY3Rpb246IHRyYW5zYWN0aW9uIH0pO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeSR1bmRvKGNiKSB7XG4gICAgdmFyIHQgPSB0aGlzLnRyYW5zYWN0aW9ucy51bmRvKGNiKTtcbiAgICBpZiAodCkgX3Bvc3RUcmFuc2FjdGlvbk1lc3NhZ2UuY2FsbCh0aGlzLCAndW5kb25lJywgdCk7XG4gICAgcmV0dXJuIHQ7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JHJlZG8oY2IpIHtcbiAgICB2YXIgdCA9IHRoaXMudHJhbnNhY3Rpb25zLnJlZG8oY2IpO1xuICAgIGlmICh0KSBfcG9zdFRyYW5zYWN0aW9uTWVzc2FnZS5jYWxsKHRoaXMsICdyZWRvbmUnLCB0KTtcbiAgICByZXR1cm4gdDtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbkhpc3RvcnkkaW5UcmFuc2FjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpc1tTQ0hFRFVMRURdO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeSRnZXREZXNjcmlwdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbnMuZ2V0RGVzY3JpcHRpb24oKTtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbkhpc3RvcnkkdXNlTWVzc2VuZ2VyKCkge1xuICAgIHJldHVybiB0aGlzLl9tZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMsIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JGRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuX21lc3NlbmdlcikgdGhpcy5fbWVzc2VuZ2VyLmRlc3Ryb3koKTtcbiAgICBkZWxldGUgdGhpcy50cmFuc2FjdGlvbnM7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIEZhY2V0ZWRPYmplY3QgPSByZXF1aXJlKCcuLi9hYnN0cmFjdC9mYWNldGVkX29iamVjdCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY19mYWNldHMvY2ZfcmVnaXN0cnknKVxuICAgICwgQ29tcG9uZW50RmFjZXQgPSBmYWNldHNSZWdpc3RyeS5nZXQoJ0NvbXBvbmVudEZhY2V0JylcbiAgICAsIGNvbXBvbmVudFV0aWxzID0gcmVxdWlyZSgnLi9jX3V0aWxzJylcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uL21lc3NlbmdlcicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxuICAgICwgbWlsb0NvbXBvbmVudE5hbWUgPSByZXF1aXJlKCcuLi91dGlsL2NvbXBvbmVudF9uYW1lJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGRvbVV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbC9kb20nKVxuICAgICwgQ29tcG9uZW50RXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuQ29tcG9uZW50XG4gICAgLCBCaW5kQXR0cmlidXRlID0gcmVxdWlyZSgnLi4vYXR0cmlidXRlcy9hX2JpbmQnKVxuICAgICwgU2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJylcbiAgICAsIERPTVN0b3JhZ2UgPSByZXF1aXJlKCcuLi91dGlsL3N0b3JhZ2UnKVxuICAgICwganNvblBhcnNlID0gcmVxdWlyZSgnLi4vdXRpbC9qc29uX3BhcnNlJyk7XG5cbnZhciBfbWFrZUNvbXBvbmVudENvbmRpdGlvbkZ1bmMgPSBjb21wb25lbnRVdGlscy5fbWFrZUNvbXBvbmVudENvbmRpdGlvbkZ1bmM7XG5cblxuLyoqXG4gKiBgbWlsby5Db21wb25lbnRgXG4gKiBCYXNlIENvbXBvbmVudCBjbGFzcy4gU3ViY2xhc3Mgb2YgW0ZhY2V0ZWRPYmplY3RdKC4uL2Fic3RyYWN0L2ZhY2V0ZWRfb2JqZWN0LmpzLmh0bWwpLCBidXQgbm9uZSBvZiB0aGlzIGNsYXNzIG1ldGhvZHMgc2hvdWxkIGJlIGRpcmVjdGx5IHVzZWQgd2l0aCBjb21wb25lbnQuXG4gKiBJdHMgY29uc3RydWN0b3IgcGFzc2VzIGl0cyBwYXJhbWV0ZXJzLCBpbmNsdWRpbmcgaXRzIFtzY29wZV0oLi9zY29wZS5qcy5odG1sKSwgRE9NIGVsZW1lbnQgYW5kIG5hbWUgdG8gW2Bpbml0YF0oI2luaXQpIG1ldGhvZC5cbiAqIFRoZSBjb25zdHJ1Y3RvciBvZiBDb21wb25lbnQgY2xhc3MgcmFyZWx5IG5lZWRzIHRvIGJlIHVzZWQgZGlyZWN0bHksIGFzIFttaWxvLmJpbmRlcl0oLi4vYmluZGVyLmpzLmh0bWwpIGNyZWF0ZXMgY29tcG9uZW50cyB3aGVuIGl0IHNjYW5zIERPTSB0cmVlLlxuICogW2BDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3NgXSgjY3JlYXRlQ29tcG9uZW50Q2xhc3MpIHNob3VsZCBiZSB1c2VkIHRvIGNyZWF0ZSBhIHN1YmNsYXNzIG9mIENvbXBvbmVudCBjbGFzcyB3aXRoIGNvbmZpZ3VyZWQgZmFjZXRzLlxuICpcbiAqXG4gKiAjIyMjQ29tcG9uZW50IGluc3RhbmNlIHByb3BlcnRpZXMjIyMjXG4gKlxuICogLSBlbCAtIERPTSBlbGVtZW50IHRoYXQgY29tcG9uZW50IGlzIGF0dGFjaGVkIHRvLiBJZiB0aGUgc2Vjb25kIGNvbXBvbmVudCBpcyBhdHRhY2hlZCB0byB0aGUgc2FtZSBET00gZWxlbWVudCwgdGhlIHdhcm5pbmcgd2lsbCBiZSBsb2dnZWQgdG8gY29uc29sZS4gVG8gZ2V0IGNvbXBvbmVudCByZWZlcmVuY2UgZnJvbSBET00gZWxlbWVudCB1c2UgW0NvbXBvbmVudC5nZXRDb21wb25lbnRdKC4vY191dGlscy5qcy5odG1sI2dldENvbXBvbmVudCkgY2xhc3MgbWV0aG9kLiBUbyBpbnNwZWN0IGNvbXBvbmVudCB2aWEgZWxlbWVudCBpbiBicm93c2VyIGNoZWNrIGBfX19taWxvX2NvbXBvbmVudGAgcHJvcGVydHkgb2YgZWxlbWVudCAocHJvcGVydHkgbmFtZSBiZSBjaGFuZ2VkIHVzaW5nIGBtaWxvLmNvbmZpZ2ApLlxuICogLSBzY29wZSAtIHBhcmVudCBzY29wZSBvYmplY3QsIGFuIGluc3RhbmNlIG9mIFtTY29wZV0oLi9zY29wZS5qcy5odG1sKSBjbGFzcy4gVG8gZ2V0IHBhcmVudCBjb21wb25lbnQgdXNlIFtnZXRTY29wZVBhcmVudF0oI0NvbXBvbmVudCRnZXRTY29wZVBhcmVudCkgaW5zdGFuY2UgbWV0aG9kIG9mIGNvbXBvbmVudC4gVGhlIGFjdHVhbCBwYXRoIHRvIGdldCBwYXJlbnQgb2YgY29ucG9uZW50IGlzIGBjb21wb25lbnQuc2NvcGUuX2hvc3RPYmplY3Qub3duZXJgLCB3aGVyZSBgX2hvc3RPYmplY3RgIHJlZmVycyB0byBbQ29udGFpbmVyXShjX2ZhY2V0cy9Db250YWluZXIuanMuaHRtbCkgZmFjZXQgb2YgcGFyZW50IGNvbXBvbmVudCBhbmQgYG93bmVyYCB0byB0aGUgcGFyZW50IGl0c2VsZi4gVGhlIGNoaWxkcmVuIG9mIGNvbXBvbmVudCBhcmUgYWNjZXNzaWJsZSB2aWEgdGhlIHNjb3BlIG9mIGl0cyBjb250YWluZXIgZmFjZXQ6IGBjb21wb25lbnQuY29udGFpbmVyLnNjb3BlYC4gVGhlIHNjb3BlIGhpZXJhcmNoeSBjYW4gYmUgdGhlIHNhbWUgb3IgZGlmZmVyZW50IGFzIHRoZSBET00gaGllcmFyY2h5IC0gRE9NIGNoaWxkcmVuIG9mIHRoZSBjb21wb25lbnQgd2lsbCBiZSBvbiB0aGUgc2FtZSBzY29wZSBhcyBjb21wb25lbnQgaWYgaXQgZG9lcyBub3QgaGF2ZSBgQ29udGFpbmVyYCBmYWNldCBhbmQgaW4gdGhlIHNjb3BlIG9mIGl0cyBDb250YWluZXIgZmFjZXQgaWYgaXQgaGFzIGl0LiBTZWUgW1Njb3BlXSguL3Njb3BlLmpzLmh0bWwpLlxuICogLSBuYW1lIC0gdGhlIG5hbWUgb2YgY29tcG9uZW50LCBzaG91bGQgYmUgdW5pcXVlIGZvciB0aGUgc2NvcGUgd2hlcmUgY29tcG9uZW50IGJlbG9uZ3MuIFRvIGZpbmQgY29tcG9uZW50IGluIHNjb3BlIHRoZSBjb21wb25lbnQncyBuYW1lIHNob3VsZCBiZSB1c2VkIGFzIHByb3BlcnR5IG9mIHNjb3BlIG9iamVjdC4gU2VlIFtTY29wZV0oLi9zY29wZS5qcy5odG1sKS5cbiAqIC0gZmFjZXRzIC0gbWFwIG9mIHJlZmVyZW5jZXMgb2YgYWxsIGNvbXBvbmVudCdzIGZhY2V0cyAoZmFjZXQgbmFtZXMgYXJlIGxvd2VyY2FzZSBpbiB0aGlzIG1hcCkuIEFsbCBmYWNldHMgY2FuIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGFzIHByb3BlcnRpZXMgb2YgY29tcG9uZW50LCB0aGlzIHByb3BlcnR5IGNhbiBiZSB1c2VkIHRvIGl0ZXJhdGUgZmFjZXRzIChpdCBpcyB1c2VkIGluIHRoaXMgd2F5IGluIFthbGxGYWNldHNdKCNDb21wb25lbnQkYWxsRmFjZXRzKSBjb21wb25lbnQncyBpbnN0YW5jZSBtZXRob2QgdGhhdCBhbGxvd3MgdG8gY2FsbCBtZXRob2Qgd2l0aCB0aGUgc2FtZSBuYW1lIG9uIGFsbCBmYWNldHMpLlxuICogLSBleHRyYUZhY2V0cyAtIGFuIGFycmF5IG9mIG5hbWVzIG9mIGZhY2V0cyB0aGF0IGFyZSBhZGRlZCB0byBjb21wb25lbnQgYW5kIGRvIG5vdCBmb3JtIHRoZSBwYXJ0IG9mIGNvbXBvbmVudCdzIGNsYXNzLlxuICogLSBfbWVzc2VuZ2VyIC0gdGhlIHJlZmVyZW5jZSB0byBjb21wb25lbnQncyBbbWVzc2VuZ2VyXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCkuIFJhcmVseSBuZWVkcyB0byBiZSB1c2VkIGRpcmVjdGx5IGFzIGFsbCBjb21tb25seSB1c2VkIG1ldGhvZHMgb2YgbWVzZW5nZXIgYXJlIGF2YWlsYWJsZSBkaXJlY3RseSBvbiBjb21wb25lbnQuXG4gKlxuICpcbiAqICMjIyNDb21wb25lbnQgZXZlbnRzIyMjI1xuICpcbiAqIC0gJ2NoaWxkcmVuYm91bmQnIC0gc3luY2hyb25vdXNseSBkaXNwYXRjaGVkIHdoZW4gY2hpbGRyZW4gb2YgRE9NIGVsZW1lbnQgd2hpY2ggY29tcG5lbnQgaXMgY29ubmVjdGVkIHRvIGFyZSBjb25uZWN0ZWQgdG8gY29tcG9uZW50cy4gVGhlIGV2ZW50IGlzIGRpc3BhdGNoZWQgd2hlbiBjb21wb25lbnQgaXMgY3JlYXRlZCB3aXRoIGBtaWxvLmJpbmRlcmAgKGFzIGlzIGFsbW9zdCBhbHdheXMgdGhlIGNhc2UsIGFzIGFsbCBDb21wb25lbnQgY2xhc3MgbWV0aG9kcyB0aGF0IGNyZWF0ZS9jb3B5IGNvbXBvbmVudHMgdXNlIGBtaWxvLmJpbmRlcmAgaW50ZXJuYWxseSAtIGNvbXBvbmVudCBjb25zdHJ1Y3RvciBhbmQgQ29tcG9uZW50LmNyZWF0ZSBtZXRob2RzIGFyZSBub3QgdXNlZCBpbiBmcmFtZXdvcmsgb3V0c2lkZSBvZiBgbWlsby5iaW5kZXJgIGFuZCByYXJlbHkgaWYgZXZlciBuZWVkIHRvIGJlIHVzZWQgaW4gYXBsaWNhdGlvbikuXG4gKiAtICdhZGRlZHRvc2NvcGUnIC0gc3luY2hyb25vdXNseSBkaXNwYXRjaGVkIHdoZW4gY29tcG9uZW50IGlzIGFkZGVkIHRvIHNjb3BlLlxuICogLSAnc3RhdGVyZWFkeScgLSBheW5jaHJvbm91c2x5IGRpc3BhdGNoZWQgd2hlbiBjb21wb25lbnQgKHRvZ2V0aGVyIHdpdGggaXRzIHNjb3BlIGNoaWxkcmVuKSBpcyBjcmVhdGVkIHdpdGggW0NvbXBvbmVudC5jcmVhdGVGcm9tU3RhdGVdKCNDb21wb25lbnQkJGNyZWF0ZUZyb21TdGF0ZSkgKG9yIGBjcmVhdGVGcm9tRGF0YVRyYW5zZmVyYCkgbWV0aG9kLiBDYW4gYmUgZGlzcGF0Y2hlZCBieSBhcHBsaWNhdGlvbiBpZiB0aGUgY29tcG9uZW50J3Mgc3RhdGUgaXMgc2V0IHdpdGggc29tZSBvdGhlciBtZWNoYW5pc20uIFRoaXMgZXZlbnQgaXMgbm90IHVzZWQgaW4gYG1pbG9gLCBpdCBjYW4gYmUgdXNlZCBpbiBhcHBsaWNhdGlvbiBpbiBwYXJ0aWN1bGFyIHN1YmNsYXNzZXMgb2YgY29tcG9uZW50LlxuICogLSAnZ2V0c3RhdGVzdGFydGVkJyAtIGVtaXR0ZWQgc3luY2hyb25vdXNseSBqdXN0IGJlZm9yZSBnZXRTdGF0ZSBleGVjdXRlcyBzbyBjb21wb25lbnRzIGFuZCBmYWNldHMgY2FuIGNsZWFuIHVwIHRoZWlyIHN0YXRlIGZvciBzZXJpYWxpemF0aW9uLiBcbiAqIC0gJ2dldHN0YXRlY29tcGxldGVkJyAtIGVtaXR0ZWQgYXN5bmNocm9ub3VzbHkgYWZ0ZXIgZ2V0U3RhdGUgZXhlY3V0ZXMgc28gY29tcG9uZW50cyBhbmQgZmFjZXRzIGNhbiByZXN0b3JlIHRoZWlyIHN0YXRlIGFmdGVyIHNlcmlhbGl6YXRpb24uXG4gKlxuICpcbiAqICMjIyNDb21wb25lbnQgXCJsaWZlY3ljbGVcIiMjIyNcbiAqXG4gKiAxLiBDb21wb25lbnQgY29uc3RydWN0b3IgaXMgY2FsbGVkLiBDb21wb25lbnQncyBjb25zdHJ1Y3RvciBzaW1wbHkgY2FsbHMgY29uc3RydWN0b3Igb2YgW0ZhY2V0ZWRPYmplY3RdKC4uL2Fic3RyYWN0L2ZhY2V0ZWRfb2JqZWN0LmpzLmh0bWwpIHRoYXQgaXMgYSBzdXBlcmNsYXNzIG9mIENvbXBvbmVudC4gU3ViY2xhc3NlcyBvZiBDb21wb25lbnQgc2hvdWxkIG5vdCBpbXBsZW1lbnQgdGhlaXIgb3duIGNvbnN0cnVjdG9yLCB0aGV5IGNhbiBvcHRpb25hbGx5IGltcGxlbWVudCBgaW5pdGAgbWV0aG9kLCBidXQgbW9zdCBjb21wb25lbnRzIGRvIG5vdCBuZWVkIHRvIGRvIGl0LlxuICogMi4gY29uc3RydWN0b3JzIGFuZCBgaW5pdGAgbWV0aG9kcyBvZiBhbGwgZmFjZXRzIGFyZSBjYWxsZWQgaW4gc2VxdWVuY2UuIFNhbWUgYXMgY29tcG9uZW50cywgZmFjZXQgZG8gbm90IGltcGxlbWVudCB0aGVpciBjb25zdHJ1Y3RvcnMsIHRoZXkgY2FuIG9wdGlvbmFsbHkgaW1wbGVtZW50IGBpbml0YCBhbmQgYHN0YXJ0YCBtZXRob2RzIChzZWUgYmVsb3cpLiBJbnNpZGUgYGluaXRgIG1ldGhvZCB0aGVyZSBzaG91bGQgYmUgb25seSBnZW5lcmFsIGluaXRpYWxpemF0aW9uIGNvZGUgd2l0aG91dCBhbnkgZGVwZW5kZW5jeSBvbiBjb21wb25lbnQgaXRzZWxmIChpdCBpcyBub3QgcmVhZHkgeWV0KSBhbmQgb3RoZXIgZmFjZXRzIChhcyB0aGVyZSBpcyBubyBzcGVjaWZpYyBmYWNldHMgY3JlYXRpb24gb3JkZXIpLiBJZiBmYWNldCBpbXBsZW1lbnRzIGBpbml0YCBtZXRob2QgaXQgTVVTVCBjYWxsIGluaGVyaXRlZCBpbml0IHdpdGggYENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cylgLlxuICogMy4gYGluaXRgIG1ldGhvZCBvZiBjb21wb25lbnQgaXMgY2FsbGVkLiBBdCB0aGlzIHBvaW50IGFsbCBmYWNldHMgYXJlIGNyZWF0ZWQgYnV0IGZhY2V0cyBzdGlsbCBjYW4gYmUgbm90IHJlYWR5IGFzIHRoZXkgY2FuIGhhdmUgaW5pdGlhbGl6YXRpb24gY29kZSBpbiBgc3RhcnRgIG1ldGhvZC4gSWYgY29tcG9uZW50IHN1YmNsYXNzIGltcGxlbWVudHMgYGluaXRgIG1ldGhvZCBpdCBNVVNUIGNhbGwgaW5oZXJpdGVkIG1ldGhvZCB3aXRoIGA8U3VwZXJjbGFzcz4ucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKWAsIHdoZXJlIDxTdXBlcmNsYXNzPiBpcyBDb21wb25lbnQgb3IgYW5vdGhlciBzdXBlcmNsYXNzIHRoZSBjb21wb25lbnQgaXMgYSBzdWJjbGFzcyBvZi5cbiAqIDQuIGBjaGVja2AgbWV0aG9kIG9mIGFsbCBmYWNldHMgaXMgY2FsbGVkLiBUaGlzIG1ldGhvZCBhZGRzIGZhY2V0cyB0aGF0IGFyZSBub3QgcGFydCBvZiB0aGUgY29tcG9uZW50IGRlY2xhcmF0aW9uIChiZWluZyBwYXJ0IG9mIHRoZSBjbGFzcyBvciBleHBsaWNpdGVseSBsaXN0ZWQgaW4gYmluZCBhdHRyaWJ1dGUpIGJ1dCBhcmUgcmVxdWlyZWQgYnkgZmFjZXRzIHRoYXQgdGhlIGNvbXBuZW50IGFscmVhZHkgaGFzLiBTdWJjbGFzc2VzIG9mIFtDb21wb25lbnRGYWNldF0oLi9jX2ZhY2V0LmpzLmh0bWwpIGRvIG5vdCBuZWVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZC5cbiAqIDUuIGBzdGFydGAgbWV0aG9kIG9mIGFsbCBmYWNldHMgaXMgY2FsbGVkLiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGltcGxlbWVudGVkIGJ5IENvbXBvbmVudEZhY2V0IHN1YmNsYXNzZXMgYW5kIGl0IGNhbiBoYXZlIGFueSBpbml0aWFsaXphdGlvbiBjb2RlIHRoYXQgZGVwZW5kcyBvbiBjb21wb25lbnQgb3Igb24gb3RoZXIgZmFjZXRzIHRoYXQgYXJlIHRoZSBkZXBlbmRlbmNpZXMgb2YgYSBmYWNldC4gSW5oZXJpdGVkIGBzdGFydGAgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgaW50IGhlIHNhbWUgd2F5IGFzIHdyaXR0ZW4gYWJvdmUuXG4gKiA2LiBgc3RhcnRgIG1ldGhvZCBvZiBjb21wb25lbnQgaXMgY2FsbGVkLiBUaGlzIGNvbXBvbmVudCBtZXRob2QgY2FuIGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzZXMgaWYgdGhleSBuZWVkIHRvIGhhdmUgc29tZSBpbml0aWFsaXphdGlvbiBjb2RlIHRoYXQgZGVwZW5kcyBvbiBzb21lIGZhY2V0cyBhbmQgcmVxdWlyZXMgdGhhdCB0aGVzZSBmYWNldHMgYXJlIGZ1bGx5IGluaWFsaXplZC4gT2Z0ZW4gc3VjaCBjb2RlIGFsc28gZGVwZW5kcyBvbiBjb21wb25lbnQncyBzY29wZSBjaGlsZHJlbiBhcyB3ZWxsIHNvIHRoaXMgY29kZSBzaG91bGQgYmUgaW5zaWRlIGAnY2hpbGRyZW5ib3VuZCdgIGV2ZW50IHN1YnNjcmliZXIuXG4gKiA3LiAnYWRkZWR0b3Njb3BlJyBldmVudCBpcyBkaXNwYXRjaGVkIHdoZW4gY29tcG9uZW50IGlzIGFkZGVkIHRvIGl0cyBwYXJlbnQncyBzY29wZSBvciB0byB0b3AgbGV2ZWwgc2NvcGUgY3JlYXRlZCBieSBgbWlsby5iaW5kZXJgLlxuICogOC4gY29tcG9uZW50J3MgY2hpbGRyZW4gYXJlIGNyZWF0ZWQgKHN0ZXBzIDEtNiBhYm92ZSBhcmUgZm9sbG93ZWQgZm9yIGVhY2ggY2hpbGQpLlxuICogOS4gJ2NoaWxkcmVuYm91bmQnIGV2ZW50IGlzIGRpc3BhdGNoZWQgd2hlbiBhbGwgY29tcG9uZW50J3MgY2hpbGRyZW4gYXJlIGNyZWF0ZWQgYW5kIGFkZGVkIHRvIHRoZWlyIHNjb3BlIChzZWUgZXZlbnQgZGVzY3JpcHRpb24gYmVsb3cpLlxuICogMTAuICdzdGF0ZXJlYWR5JyBldmVudCBpcyBkaXNwYXRjaGVkIGZvciBjb21wb25lbnQgYW5kIGFsbCBpdHMgY2hpbGRyZW4gd2hlbiBjb21wb25lbnQgaXMgY3JlYXRlIGZyb20gc3RhdGUgKHNlZSBldmVudCBkZXNjcmlwdGlvbiBiZWxvdykuXG4gKiAxMS4gYXQgdGhpcyBwb2ludCBjb21wb25lbnQgaXMgaW4gdGhlIFwiaW50ZXJhY3RpdmVcIiBzdGF0ZSB3aGVuIGl0IGFuZCBpdHMgZmFjZXRzIHdpbGwgb25seSByZXNwb25kIHRvIG1lc3NhZ2VzL2V2ZW50cyB0aGF0IHRoZXkgc3Vic2NyaWJlZCB0byBkdXJpbmcgaW5pdGlhbGl6YXRpb24uXG4gKlxuICpcbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIHNjb3BlIHRvIHdoaWNoIGNvbXBvbmVudCB3aWxsIGJlbG9uZy4gSXQgaXMgdXN1YWxseSBhIHRvcCBsZXZlbCBzY29wZSBvYmplY3QgcmV0dXJuZWQgYnkgYG1pbG8uYmluZGVyYCBvciBgc2NvcGVgIHByb3BlcnR5IG9mIENvbnRhaW5lciBmYWNldC5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBET00gZWxlbWVudCB0aGF0IGNvbXBvbmVudCBpcyBhdHRhY2hlZCB0b1xuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgY29tcG9uZW50IG5hbWUsIHNob3VsZCBiZSB1bmlxdWUgaW4gdGhlIHNjb3BlIG9mIGNvbXBvbmVudFxuICogQHBhcmFtIHtDb21wb25lbnRJbmZvfSBjb21wb25lbnRJbmZvIGluc3RhbmNlIG9mIENvbXBvbmVudEluZm8gY2xhc3MgdGhhdCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBjb3B5IG9mIGNvbXBvbmVudFxuICogIFRPRE8gdHJ5IHJlbW92aW5nIGl0XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbnZhciBDb21wb25lbnQgPSBfLmNyZWF0ZVN1YmNsYXNzKEZhY2V0ZWRPYmplY3QsICdDb21wb25lbnQnLCB0cnVlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDb21wb25lbnQ7XG5cbl9yZWdpc3RlcldpdGhEb21TdG9yYWdlKCdDb21wb25lbnQnKTtcblxuXG4vKipcbiAqICMjIyNDb21wb25lbnQgY2xhc3MgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtjcmVhdGVDb21wb25lbnRDbGFzc10oI0NvbXBvbmVudCQkY3JlYXRlQ29tcG9uZW50Q2xhc3MpXG4gKiAtIFtjcmVhdGVdKCNDb21wb25lbnQkJGNyZWF0ZSlcbiAqIC0gW2NvcHldKCNDb21wb25lbnQkJGNvcHkpXG4gKiAtIFtjcmVhdGVPbkVsZW1lbnRdKCNDb21wb25lbnQkJGNyZWF0ZU9uRWxlbWVudClcbiAqIC0gW2lzQ29tcG9uZW50XShjX3V0aWxzLmpzLmh0bWwjaXNDb21wb25lbnQpXG4gKiAtIFtnZXRDb21wb25lbnRdKGNfdXRpbHMuanMuaHRtbCNnZXRDb21wb25lbnQpXG4gKiAtIFtnZXRDb250YWluaW5nQ29tcG9uZW50XShjX3V0aWxzLmpzLmh0bWwjZ2V0Q29udGFpbmluZ0NvbXBvbmVudClcbiAqIC0gW2NyZWF0ZUZyb21TdGF0ZV0oI0NvbXBvbmVudCQkY3JlYXRlRnJvbVN0YXRlKVxuICogLSBbY3JlYXRlRnJvbURhdGFUcmFuc2Zlcl0oI0NvbXBvbmVudCQkY3JlYXRlRnJvbURhdGFUcmFuc2ZlcilcbiAqL1xuXy5leHRlbmQoQ29tcG9uZW50LCB7XG4gICAgY3JlYXRlQ29tcG9uZW50Q2xhc3M6IENvbXBvbmVudCQkY3JlYXRlQ29tcG9uZW50Q2xhc3MsXG4gICAgY3JlYXRlOiBDb21wb25lbnQkJGNyZWF0ZSxcbiAgICBjb3B5OiBDb21wb25lbnQkJGNvcHksXG4gICAgY3JlYXRlT25FbGVtZW50OiBDb21wb25lbnQkJGNyZWF0ZU9uRWxlbWVudCxcbiAgICBpc0NvbXBvbmVudDogY29tcG9uZW50VXRpbHMuaXNDb21wb25lbnQsXG4gICAgZ2V0Q29tcG9uZW50OiBjb21wb25lbnRVdGlscy5nZXRDb21wb25lbnQsXG4gICAgZ2V0Q29udGFpbmluZ0NvbXBvbmVudDogY29tcG9uZW50VXRpbHMuZ2V0Q29udGFpbmluZ0NvbXBvbmVudCxcbiAgICBjcmVhdGVGcm9tU3RhdGU6IENvbXBvbmVudCQkY3JlYXRlRnJvbVN0YXRlLFxuICAgIGNyZWF0ZUZyb21EYXRhVHJhbnNmZXI6IENvbXBvbmVudCQkY3JlYXRlRnJvbURhdGFUcmFuc2ZlclxufSk7XG5kZWxldGUgQ29tcG9uZW50LmNyZWF0ZUZhY2V0ZWRDbGFzcztcblxuXG4vKipcbiAqICMjIyNDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtpbml0XSgjQ29tcG9uZW50JGluaXQpXG4gKiAtIFtjcmVhdGVFbGVtZW50XSgjQ29tcG9uZW50JGNyZWF0ZUVsZW1lbnQpXG4gKiAtIFtoYXNGYWNldF0oI0NvbXBvbmVudCRoYXNGYWNldClcbiAqIC0gW2FkZEZhY2V0XSgjQ29tcG9uZW50JGFkZEZhY2V0KVxuICogLSBbYWxsRmFjZXRzXSgjQ29tcG9uZW50JGFsbEZhY2V0cylcbiAqIC0gW3JlbmFtZV0oI0NvbXBvbmVudCRyZW5hbWUpXG4gKiAtIFtyZW1vdmVdKCNDb21wb25lbnQkcmVtb3ZlKVxuICogLSBbZ2V0U3RhdGVdKCNDb21wb25lbnQkZ2V0U3RhdGUpXG4gKiAtIFtnZXRUcmFuc2ZlclN0YXRlXSgjQ29tcG9uZW50JGdldFRyYW5zZmVyU3RhdGUpXG4gKiAtIFtzZXRTdGF0ZV0oI0NvbXBvbmVudCRzZXRTdGF0ZSlcbiAqIC0gW2dldFNjb3BlUGFyZW50XSgjQ29tcG9uZW50JGdldFNjb3BlUGFyZW50KVxuICogLSBbZ2V0VG9wU2NvcGVQYXJlbnRdKCNDb21wb25lbnQkZ2V0VG9wU2NvcGVQYXJlbnQpXG4gKiAtIFtnZXRTY29wZVBhcmVudFdpdGhDbGFzc10oI0NvbXBvbmVudCRnZXRTY29wZVBhcmVudFdpdGhDbGFzcylcbiAqIC0gW2dldFRvcFNjb3BlUGFyZW50V2l0aENsYXNzXSgjQ29tcG9uZW50JGdldFRvcFNjb3BlUGFyZW50V2l0aENsYXNzKVxuICogLSBbd2Fsa1Njb3BlVHJlZV0oI0NvbXBvbmVudCR3YWxrU2NvcGVUcmVlKVxuICogLSBbYnJvYWRjYXN0XSgjQ29tcG9uZW50JGJyb2FkY2FzdClcbiAqIC0gW2Rlc3Ryb3ldKCNDb21wb25lbnQkZGVzdHJveSlcbiAqIC0gW2lzRGVzdHJveWVkXSgjQ29tcG9uZW50JGlzRGVzdHJveWVkKVxuICpcbiAqXG4gKiAjIyMjI1tNZXNzZW5nZXJdKC4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sKSBtZXRob2RzIGF2YWlsYWJsZSBvbiBjb21wb25lbnQjIyMjI1xuICpcbiAqIC0gW29uXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCNNZXNzZW5nZXIkb24pIC0gc2luZ2xlIHN1YnNjcmliZVxuICogLSBbb2ZmXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCNNZXNzZW5nZXIkb2ZmKSAtIHNpbmdsZSB1bnN1YnNjcmliZVxuICogLSBbb25NZXNzYWdlc10oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwjTWVzc2VuZ2VyJG9uTWVzc2FnZXMpIC0gbXVsdGlwbGUgc3Vic2NyaWJlXG4gKiAtIFtvZmZNZXNzYWdlc10oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwjTWVzc2VuZ2VyJG9mZk1lc3NhZ2VzKSAtIG11bHRpcGxlIHVuc3Vic2NyaWJlXG4gKiAtIFtwb3N0TWVzc2FnZV0oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwjTWVzc2VuZ2VyJHBvc3RNZXNzYWdlKSAtIHBvc3QgbWVzc2FnZSBvbiBjb21wb25lbnRcbiAqIC0gW2dldFN1YnNjcmliZXJzXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCNNZXNzZW5nZXIkZ2V0U3Vic2NyaWJlcnMpIC0gZ2V0IHN1YnNjcmliZXJzIGZvciBhIGdpdmVuIG1lc3NhZ2VcbiAqL1xuXy5leHRlbmRQcm90byhDb21wb25lbnQsIHtcbiAgICBpbml0OiBDb21wb25lbnQkaW5pdCxcbiAgICBzdGFydDogQ29tcG9uZW50JHN0YXJ0LFxuICAgIGNyZWF0ZUVsZW1lbnQ6IENvbXBvbmVudCRjcmVhdGVFbGVtZW50LFxuICAgIGhhc0ZhY2V0OiBDb21wb25lbnQkaGFzRmFjZXQsXG4gICAgYWRkRmFjZXQ6IENvbXBvbmVudCRhZGRGYWNldCxcbiAgICBhbGxGYWNldHM6IENvbXBvbmVudCRhbGxGYWNldHMsXG4gICAgcmVuYW1lOiBDb21wb25lbnQkcmVuYW1lLFxuICAgIHJlbW92ZTogQ29tcG9uZW50JHJlbW92ZSxcbiAgICBpbnNlcnRJbnRvOiBDb21wb25lbnQkaW5zZXJ0SW50byxcblxuICAgIGdldFN0YXRlOiBDb21wb25lbnQkZ2V0U3RhdGUsXG4gICAgZ2V0VHJhbnNmZXJTdGF0ZTogQ29tcG9uZW50JGdldFRyYW5zZmVyU3RhdGUsXG4gICAgX2dldFN0YXRlOiBDb21wb25lbnQkX2dldFN0YXRlLFxuICAgIHNldFN0YXRlOiBDb21wb25lbnQkc2V0U3RhdGUsXG4gICAgXG4gICAgZ2V0U2NvcGVQYXJlbnQ6IENvbXBvbmVudCRnZXRTY29wZVBhcmVudCxcbiAgICBnZXRUb3BTY29wZVBhcmVudDogQ29tcG9uZW50JGdldFRvcFNjb3BlUGFyZW50LFxuICAgIGdldFNjb3BlUGFyZW50V2l0aENsYXNzOiBDb21wb25lbnQkZ2V0U2NvcGVQYXJlbnRXaXRoQ2xhc3MsXG4gICAgZ2V0VG9wU2NvcGVQYXJlbnRXaXRoQ2xhc3M6IENvbXBvbmVudCRnZXRUb3BTY29wZVBhcmVudFdpdGhDbGFzcyxcblxuICAgIHNldFNjb3BlUGFyZW50RnJvbURPTTogQ29tcG9uZW50JHNldFNjb3BlUGFyZW50RnJvbURPTSxcblxuICAgIHdhbGtTY29wZVRyZWU6IENvbXBvbmVudCR3YWxrU2NvcGVUcmVlLFxuXG4gICAgdHJlZVBhdGhPZjogQ29tcG9uZW50JHRyZWVQYXRoT2YsXG4gICAgZ2V0Q29tcG9uZW50QXRUcmVlUGF0aDogQ29tcG9uZW50JGdldENvbXBvbmVudEF0VHJlZVBhdGgsXG4gICAgaW5zZXJ0QXRUcmVlUGF0aDogQ29tcG9uZW50JGluc2VydEF0VHJlZVBhdGgsXG5cbiAgICBicm9hZGNhc3Q6IENvbXBvbmVudCRicm9hZGNhc3QsXG4gICAgZGVzdHJveTogQ29tcG9uZW50JGRlc3Ryb3ksXG4gICAgaXNEZXN0cm95ZWQ6IENvbXBvbmVudCRpc0Rlc3Ryb3llZFxufSk7XG5cblxuLyoqXG4gKiBFeHBvc2UgTWVzc2VuZ2VyIG1ldGhvZHMgb24gQ29tcG9uZW50IHByb3RvdHlwZVxuICovXG52YXIgTUVTU0VOR0VSX1BST1BFUlRZID0gJ19tZXNzZW5nZXInO1xuTWVzc2VuZ2VyLnVzZVdpdGgoQ29tcG9uZW50LCBNRVNTRU5HRVJfUFJPUEVSVFksIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG5cblxudmFyIENPTVBPTkVOVF9EQVRBX1RZUEVfUFJFRklYID0gJ3gtYXBwbGljYXRpb24vbWlsby1jb21wb25lbnQnO1xudmFyIENPTVBPTkVOVF9EQVRBX1RZUEVfUkVHRVggPSAveC1hcHBsaWNhdGlvblxcL21pbG8tY29tcG9uZW50XFwvKFthLXpfJF1bMC05YS16XyRdKikoPzpcXC8oKSkvaTtcblxuLyoqXG4gKiBDb21wb25lbnQgY2xhc3MgbWV0aG9kXG4gKiBDcmVhdGVzIGEgc3ViY2xhc3Mgb2YgY29tcG9uZW50IGZyb20gdGhlIG1hcCBvZiBjb25maWd1cmVkIGZhY2V0cy5cbiAqIFRoaXMgbWV0aG9kIHdyYXBzIGFuZCByZXBsYWNlcyBbYGNyZWF0ZUZhY2V0ZWRDbGFzc2BdKC4uL2Fic3RyYWN0L2ZhY2V0ZWRfb2JqZWN0LmpzLmh0bWwjY3JlYXRlRmFjZXRlZENsYXNzKSBjbGFzcyBtZXRob2Qgb2YgRmFjZXRlZE9iamVjdC5cbiAqIFVubGlrZSBjcmVhdGVGYWNldGVkQ2xhc3MsIHRoaXMgbWV0aG9kIHRha2UgZmFjZXQgY2xhc3NlcyBmcm9tIHJlZ2lzdHJ5IGJ5IHRoZWlyIG5hbWUsIHNvIG9ubHkgbWFwIG9mIGZhY2V0cyBjb25maWd1cmF0aW9uIG5lZWRzIHRvIGJlIHBhc3NlZC4gQWxsIGZhY2V0cyBjbGFzc2VzIHNob3VsZCBiZSBzdWJjbGFzc2VzIG9mIFtDb21wb25lbnRGYWNldF0oLi9jX2ZhY2V0LmpzLmh0bWwpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgY2xhc3MgbmFtZVxuICogQHBhcmFtIHtPYmplY3RbT2JqZWN0XSB8IEFycmF5W1N0cmluZ119IGZhY2V0c0NvbmZpZyBtYXAgb2YgZmFjZXRzIGNvbmZpZ3VyYXRpb24uXG4gKiAgSWYgc29tZSBmYWNldCBkb2VzIG5vdCByZXF1aXJlIGNvbmZpZ3VyYXRpb24sIGB1bmRlZmluZWRgIHNob3VsZCBiZSBwYXNzZWQgYXMgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBmYWNldC5cbiAqICBJZiBubyBmYWNldCByZXF1aXJlcyBjb25maWd1cmF0aW9uLCB0aGUgYXJyYXkgb2YgZmFjZXRzIG5hbWVzIGNhbiBiZSBwYXNzZWQuXG4gKiBAcmV0dXJuIHtTdWJjbGFzcyhDb21wb25lbnQpfVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkJGNyZWF0ZUNvbXBvbmVudENsYXNzKG5hbWUsIGZhY2V0c0NvbmZpZykge1xuICAgIC8vIGNvbnZlcnQgYXJyYXkgb2YgZmFjZXQgbmFtZXMgdG8gbWFwIG9mIGVtcHR5IGZhY2V0cyBjb25maWd1cmF0aW9uc1xuICAgIGlmIChBcnJheS5pc0FycmF5KGZhY2V0c0NvbmZpZykpIHtcbiAgICAgICAgdmFyIGNvbmZpZ01hcCA9IHt9O1xuICAgICAgICBmYWNldHNDb25maWcuZm9yRWFjaChmdW5jdGlvbihmY3QpIHtcbiAgICAgICAgICAgIHZhciBmY3ROYW1lID0gXy5maXJzdExvd2VyQ2FzZShmY3QpO1xuICAgICAgICAgICAgY29uZmlnTWFwW2ZjdE5hbWVdID0ge307XG4gICAgICAgIH0pO1xuICAgICAgICBmYWNldHNDb25maWcgPSBjb25maWdNYXA7XG4gICAgfVxuXG4gICAgLy8gY29uc3RydWN0IG1hcCBvZiBmYWNldHMgY2xhc3NlcyBmcm9tIGZhY2V0UmVnaXN0cnlcbiAgICB2YXIgZmFjZXRzQ2xhc3NlcztcbiAgICBpZiAodHlwZW9mIGZhY2V0c0NvbmZpZyA9PSAnb2JqZWN0JyAmJiBfLmtleXMoZmFjZXRzQ29uZmlnKS5sZW5ndGgpIHtcbiAgICAgICAgZmFjZXRzQ2xhc3NlcyA9IHt9O1xuICAgICAgICBfLmVhY2hLZXkoZmFjZXRzQ29uZmlnLCBmdW5jdGlvbihmY3RDb25maWcsIGZjdCkge1xuICAgICAgICAgICAgdmFyIGZjdE5hbWUgPSBfLmZpcnN0TG93ZXJDYXNlKGZjdCk7XG4gICAgICAgICAgICB2YXIgZmN0Q2xhc3NOYW1lID0gXy5maXJzdFVwcGVyQ2FzZShmY3QpO1xuICAgICAgICAgICAgZmFjZXRzQ2xhc3Nlc1tmY3ROYW1lXSA9IGZhY2V0c1JlZ2lzdHJ5LmdldChmY3RDbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBjcmVhdGUgc3ViY2xhc3Mgb2YgQ29tcG9uZW50IHVzaW5nIG1ldGhvZCBvZiBGYWNldGVkT2JqZWN0XG4gICAgdmFyIENvbXBvbmVudENsYXNzID0gRmFjZXRlZE9iamVjdC5jcmVhdGVGYWNldGVkQ2xhc3MuY2FsbCh0aGlzLCBuYW1lLCBmYWNldHNDbGFzc2VzLCBmYWNldHNDb25maWcpO1xuICAgIFxuICAgIF9yZWdpc3RlcldpdGhEb21TdG9yYWdlKG5hbWUpO1xuXG4gICAgcmV0dXJuIENvbXBvbmVudENsYXNzO1xufVxuXG5cbmZ1bmN0aW9uIF9yZWdpc3RlcldpdGhEb21TdG9yYWdlKGNsYXNzTmFtZSkge1xuICAgIERPTVN0b3JhZ2UucmVnaXN0ZXJEYXRhVHlwZShjbGFzc05hbWUsIENvbXBvbmVudF9kb21TdG9yYWdlU2VyaWFsaXplciwgQ29tcG9uZW50X2RvbVN0b3JhZ2VQYXJzZXIpO1xufVxuXG5cbmZ1bmN0aW9uIENvbXBvbmVudF9kb21TdG9yYWdlU2VyaWFsaXplcihjb21wb25lbnQpIHtcbiAgICB2YXIgc3RhdGUgPSBjb21wb25lbnQuZ2V0U3RhdGUoKTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc3RhdGUpOyAgIFxufVxuXG5cbmZ1bmN0aW9uIENvbXBvbmVudF9kb21TdG9yYWdlUGFyc2VyKGNvbXBTdHIsIGNvbXBDbGFzc05hbWUpIHtcbiAgICB2YXIgc3RhdGUgPSBqc29uUGFyc2UoY29tcFN0cik7XG4gICAgaWYgKHN0YXRlKVxuICAgICAgICByZXR1cm4gQ29tcG9uZW50LmNyZWF0ZUZyb21TdGF0ZShzdGF0ZSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgY2xhc3MgbWV0aG9kXG4gKiBDcmVhdGVzIGNvbXBvbmVudCBmcm9tIFtDb21wb25lbnRJbmZvXSguL2NfaW5mby5qcy5odG1sKSAodXNlZCBieSBbbWlsby5iaW5kZXJdKC4uL2JpbmRlci5qcy5odG1sKSBhbmQgdG8gY29weSBjb21wb25lbnQpXG4gKiBDb21wb25lbnQgb2YgYW55IHJlZ2lzdGVyZWQgY2xhc3MgKHNlZSBbY29tcG9uZW50c1JlZ2lzdHJ5XSguL2NfcmVnaXN0cnkuanMuaHRtbCkpIHdpdGggYW55IGFkZGl0aW9uYWwgcmVnaXN0ZXJlZCBmYWNldHMgKHNlZSBbZmFjZXRzUmVnaXN0cnldKC4vY19mYWNldHMvY2ZfcmVnaXN0cnkuanMuaHRtbCkpIGNhbiBiZSBjcmVhdGVkIHVzaW5nIHRoaXMgbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB7Q29tcG9uZW50SW5mb30gaW5mb1xuICogQHBhcmFtIHtCb29sZWFufSB0aHJvd09uRXJyb3JzIElmIHNldCB0byBmYWxzZSwgdGhlbiBlcnJvcnMgd2lsbCBvbmx5IGJlIGxvZ2dlZCB0byBjb25zb2xlLiBUcnVlIGJ5IGRlZmF1bHQuXG4gQCBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCQkY3JlYXRlKGluZm8sIHRocm93T25FcnJvcnMpIHtcbiAgICB2YXIgQ29tcG9uZW50Q2xhc3MgPSBpbmZvLkNvbXBvbmVudENsYXNzO1xuXG4gICAgaWYgKHR5cGVvZiBDb21wb25lbnRDbGFzcyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gJ2NyZWF0ZTogY29tcG9uZW50IGNsYXNzIHNob3VsZCBiZSBmdW5jdGlvbiwgXCInICsgdHlwZW9mIENvbXBvbmVudENsYXNzICsgJ1wiIHBhc3NlZCc7IFxuICAgICAgICBpZiAodGhyb3dPbkVycm9ycyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignQ29tcG9uZW50JywgbWVzc2FnZSwgJzt1c2luZyBiYXNlIENvbXBvbmVudCBjbGFzcyBpbnN0ZWFkJyk7XG4gICAgICAgICAgICBDb21wb25lbnRDbGFzcyA9IENvbXBvbmVudDtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICB0aHJvdyBuZXcgQ29tcG9uZW50RXJyb3IobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgdmFyIGFDb21wb25lbnQgPSBuZXcgQ29tcG9uZW50Q2xhc3MoaW5mby5zY29wZSwgaW5mby5lbCwgaW5mby5uYW1lLCBpbmZvKTtcblxuICAgIGlmIChpbmZvLmV4dHJhRmFjZXRzQ2xhc3NlcylcbiAgICAgICAgXy5lYWNoS2V5KGluZm8uZXh0cmFGYWNldHNDbGFzc2VzLCBmdW5jdGlvbihGYWNldENsYXNzKSB7XG4gICAgICAgICAgICBpZiAoISBhQ29tcG9uZW50Lmhhc0ZhY2V0KEZhY2V0Q2xhc3MpKVxuICAgICAgICAgICAgICAgIGFDb21wb25lbnQuYWRkRmFjZXQoRmFjZXRDbGFzcywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRocm93T25FcnJvcnMpO1xuICAgICAgICB9KTtcblxuICAgIHJldHVybiBhQ29tcG9uZW50O1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGNsYXNzIG1ldGhvZFxuICogQ3JlYXRlIGEgY29weSBvZiBjb21wb25lbnQsIGluY2x1ZGluZyBhIGNvcHkgb2YgRE9NIGVsZW1lbnQuIFJldHVybnMgYSBjb3B5IG9mIGBjb21wb25lbnRgIChvZiB0aGUgc2FtZSBjbGFzcykgd2l0aCBuZXcgRE9NIGVsZW1lbnQgKG5vdCBpbnNlcnRlZCBpbnRvIHBhZ2UpLlxuICogQ29tcG9uZW50IGlzIGFkZGVkIHRvIHRoZSBzYW1lIHNjb3BlIGFzIHRoZSBvcmlnaW5hbCBjb21wb25lbnQuXG4gKlxuICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXBvbmVudCBhbiBpbnN0YW5jZSBvZiBDb21wb25lbnQgY2xhc3Mgb3Igc3ViY2xhc3NcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVlcENvcHkgb3B0aW9uYWwgYHRydWVgIHRvIG1ha2UgZGVlcCBjb3B5IG9mIERPTSBlbGVtZW50LCBvdGhlcndpc2Ugb25seSBlbGVtZW50IHdpdGhvdXQgY2hpbGRyZW4gaXMgY29waWVkXG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCQkY29weShjb21wb25lbnQsIGRlZXBDb3B5KSB7XG4gICAgY2hlY2soY29tcG9uZW50LCBDb21wb25lbnQpO1xuICAgIGNoZWNrKGRlZXBDb3B5LCBNYXRjaC5PcHRpb25hbChCb29sZWFuKSk7XG5cbiAgICBpZiAoZGVlcENvcHkgJiYgIWNvbXBvbmVudC5jb250YWluZXIpIFxuICAgICAgICB0aHJvdyBuZXcgQ29tcG9uZW50RXJyb3IoJ0Nhbm5vdCBkZWVwIGNvcHkgY29tcG9uZW50IHdpdGhvdXQgY29udGFpbmVyIGZhY2V0Jyk7XG5cbiAgICAvLyBjb3B5IERPTSBlbGVtZW50LCB1c2luZyBEb20gZmFjZXQgaWYgaXQgaXMgYXZhaWxhYmxlXG4gICAgdmFyIG5ld0VsID0gY29tcG9uZW50LmRvbSBcbiAgICAgICAgICAgICAgICAgICAgPyBjb21wb25lbnQuZG9tLmNvcHkoZGVlcENvcHkpXG4gICAgICAgICAgICAgICAgICAgIDogY29tcG9uZW50LmVsLmNsb25lTm9kZShkZWVwQ29weSk7XG5cbiAgICB2YXIgQ29tcG9uZW50Q2xhc3MgPSBjb21wb25lbnQuY29uc3RydWN0b3I7XG5cbiAgICAvLyBjcmVhdGUgY29tcG9uZW50IG9mIHRoZSBzYW1lIGNsYXNzIG9uIHRoZSBlbGVtZW50XG4gICAgdmFyIGFDb21wb25lbnQgPSBDb21wb25lbnRDbGFzcy5jcmVhdGVPbkVsZW1lbnQobmV3RWwsIHVuZGVmaW5lZCwgY29tcG9uZW50LnNjb3BlLCBjb21wb25lbnQuZXh0cmFGYWNldHMpO1xuICAgIHZhciBzdGF0ZSA9IGNvbXBvbmVudC5fZ2V0U3RhdGUoZGVlcENvcHkgfHwgZmFsc2UpO1xuICAgIGFDb21wb25lbnQuc2V0U3RhdGUoc3RhdGUpO1xuICAgIF8uZGVmZXJNZXRob2QoYUNvbXBvbmVudCwgJ2Jyb2FkY2FzdCcsICdzdGF0ZXJlYWR5Jyk7XG4gICAgcmV0dXJuIGFDb21wb25lbnQ7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgY2xhc3MgbWV0aG9kXG4gKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIGNvbXBvbmVudCBhdGFjaGVkIHRvIGVsZW1lbnQuIEFsbCBzdWJjbGFzc2VzIG9mIGNvbXBvbmVudCBpbmhlcml0IHRoaXMgbWV0aG9kLlxuICogUmV0dXJucyB0aGUgY29tcG9uZW50IG9mIHRoZSBjbGFzcyB0aGlzIG1ldGhvZCBpcyB1c2VkIHdpdGggKHRoZWNvbnRleHQgb2YgdGhlIG1ldGhvZCBjYWxsKS5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIG9wdGlvbmFsIGVsZW1lbnQgdG8gYXR0YWNoIGNvbXBvbmVudCB0by4gSWYgZWxlbWVudCBpcyBub3QgcGFzc2VkLCBpdCB3aWxsIGJlIGNyZWF0ZWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBpbm5lckhUTUwgb3B0aW9uYWwgaW5uZXIgaHRtbCB0byBpbnNlcnQgaW4gZWxlbWVudCBiZWZvcmUgYmluZGluZy5cbiAqIEBwYXJhbSB7U2NvcGV9IHJvb3RTY29wZSBvcHRpb25hbCBzY29wZSB0byBwdXQgY29tcG9uZW50IGluLiBJZiBub3QgcGFzc2VkLCBjb21wb25lbnQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUgc2NvcGUgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudC4gSWYgc3VjaCBzY29wZSBkb2VzIG5vdCBleGlzdCwgbmV3IHNjb3BlIHdpbGwgYmUgY3JlYXRlZC5cbiAqIEBwYXJhbSB7QXJyYXlbU3RyaW5nXX0gZXh0cmFGYWNldHMgbGlzdCBvZiBleHRyYSBmYWNldCB0byBhZGQgdG8gY29tcG9uZW50XG4gKiBAcmV0dXJuIHtTdWJjbGFzcyhDb21wb25lbnQpfVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkJGNyZWF0ZU9uRWxlbWVudChlbCwgaW5uZXJIVE1MLCByb290U2NvcGUsIGV4dHJhRmFjZXRzKSB7XG4gICAgY2hlY2soaW5uZXJIVE1MLCBNYXRjaC5PcHRpb25hbChTdHJpbmcpKTtcbiAgICBjaGVjayhyb290U2NvcGUsIE1hdGNoLk9wdGlvbmFsKFNjb3BlKSk7XG4gICAgY2hlY2soZXh0cmFGYWNldHMsIE1hdGNoLk9wdGlvbmFsKFtTdHJpbmddKSk7XG5cbiAgICAvLyBcInRoaXNcIiByZWZlcnMgdG8gdGhlIGNsYXNzIG9mIGNvbXBvbmVudCBoZXJlLCBhcyB0aGlzIGlzIGEgY2xhc3MgbWV0aG9kXG4gICAgaWYgKGVsICYmIGlubmVySFRNTCkgZWwuaW5uZXJIVE1MID0gaW5uZXJIVE1MO1xuICAgIGVsID0gZWwgfHwgX2NyZWF0ZUNvbXBvbmVudEVsZW1lbnQuY2FsbCh0aGlzLCBpbm5lckhUTUwpO1xuICAgIHJvb3RTY29wZSA9IHJvb3RTY29wZSB8fCBfZmluZE9yQ3JlYXRlQ29tcG9uZW50Um9vdFNjb3BlKGVsKTtcbiAgICB2YXIgYUNvbXBvbmVudCA9IF9hZGRBdHRyaWJ1dGVBbmRCaW5kQ29tcG9uZW50LmNhbGwodGhpcywgZWwsIHJvb3RTY29wZSwgZXh0cmFGYWNldHMpO1xuICAgIGFDb21wb25lbnQuYnJvYWRjYXN0KCdzdGF0ZXJlYWR5Jyk7XG4gICAgcmV0dXJuIGFDb21wb25lbnQ7XG59XG5cbmZ1bmN0aW9uIF9jcmVhdGVDb21wb25lbnRFbGVtZW50KGlubmVySFRNTCkge1xuICAgIC8vIFwidGhpc1wiIHJlZmVycyB0byB0aGUgY2xhc3Mgb2YgY29tcG9uZW50IGhlcmUsIGFzIHRoaXMgaXMgYSBjbGFzcyBtZXRob2RcbiAgICB2YXIgRG9tID0gZmFjZXRzUmVnaXN0cnkuZ2V0KCdEb20nKVxuICAgICAgICAsIGRvbUZhY2V0Q29uZmlnID0gdGhpcy5nZXRGYWNldENvbmZpZygnZG9tJylcbiAgICAgICAgLCB0ZW1wbGF0ZUZhY2V0Q29uZmlnID0gdGhpcy5nZXRGYWNldENvbmZpZygndGVtcGxhdGUnKVxuICAgICAgICAsIHRlbXBsYXRlID0gdGVtcGxhdGVGYWNldENvbmZpZyAmJiB0ZW1wbGF0ZUZhY2V0Q29uZmlnLnRlbXBsYXRlO1xuXG4gICAgdmFyIGVsQ29uZmlnID0ge1xuICAgICAgICBkb21Db25maWc6IGRvbUZhY2V0Q29uZmlnLFxuICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGUsXG4gICAgICAgIGNvbnRlbnQ6IGlubmVySFRNTFxuICAgIH07XG5cbiAgICByZXR1cm4gRG9tLmNyZWF0ZUVsZW1lbnQoZWxDb25maWcpO1xufVxuXG5mdW5jdGlvbiBfZmluZE9yQ3JlYXRlQ29tcG9uZW50Um9vdFNjb3BlKGVsKSB7XG4gICAgdmFyIHBhcmVudCA9IENvbXBvbmVudC5nZXRDb250YWluaW5nQ29tcG9uZW50KGVsLCBmYWxzZSwgJ0NvbnRhaW5lcicpO1xuICAgIHJldHVybiBwYXJlbnQgPyBwYXJlbnQuY29udGFpbmVyLnNjb3BlIDogbmV3IFNjb3BlKGVsKTtcbn1cblxuZnVuY3Rpb24gX2FkZEF0dHJpYnV0ZUFuZEJpbmRDb21wb25lbnQoZWwsIHJvb3RTY29wZSwgZXh0cmFGYWNldHMpIHtcbiAgICAvLyBhZGQgYmluZCBhdHRyaWJ1dGUgdG8gZWxlbWVudFxuICAgIHZhciBhdHRyID0gbmV3IEJpbmRBdHRyaWJ1dGUoZWwpO1xuICAgIC8vIFwidGhpc1wiIHJlZmVycyB0byB0aGUgY2xhc3Mgb2YgY29tcG9uZW50IGhlcmUsIGFzIHRoaXMgaXMgYSBjbGFzcyBtZXRob2RcbiAgICBhdHRyLmNvbXBDbGFzcyA9IHRoaXMubmFtZTtcbiAgICBhdHRyLmNvbXBGYWNldHMgPSBleHRyYUZhY2V0cztcbiAgICBhdHRyLmRlY29yYXRlKCk7XG5cbiAgICAvLyBzaG91bGQgYmUgcmVxdWlyZWQgaGVyZSB0byByZXNvbHZlIGNpcmN1bGFyIGRlcGVuZGVuY3lcbiAgICB2YXIgbWlsb0JpbmRlciA9IHJlcXVpcmUoJy4uL2JpbmRlcicpO1xuICAgIG1pbG9CaW5kZXIoZWwsIHJvb3RTY29wZSk7XG5cbiAgICByZXR1cm4gcm9vdFNjb3BlW2F0dHIuY29tcE5hbWVdO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBjbGFzcyBtZXRob2RcbiAqIENyZWF0ZXMgY29tcG9uZW50IGZyb20gY29tcG9uZW50IHN0YXRlLCB0aGF0IGluY2x1ZGVzIGluZm9ybWF0aW9uIGFib3V0IGl0cyBjbGFzcywgZXh0cmEgZmFjZXRzLCBmYWNldHMgZGF0YSBhbmQgYWxsIHNjb3BlIGNoaWxkcmVuLlxuICogVGhpcyBpcyB1c2VkIHRvIHNhdmUvbG9hZCwgY29weS9wYXN0ZSBhbmQgZHJhZy9kcm9wIGNvbXBvbmVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBzdGF0ZSBmcm9tIHdoaWNoIGNvbXBvbmVudCB3aWxsIGJlIGNyZWF0ZWRcbiAqIEBwYXJhbSB7U2NvcGV9IHJvb3RTY29wZSBzY29wZSB0byB3aGljaCBjb21wb25lbnQgd2lsbCBiZSBhZGRlZFxuICogQHBhcmFtIHtCb29sZWFufSBuZXdVbmlxdWVOYW1lIG9wdGlvbmFsIGB0cnVlYCB0byBjcmVhdGUgY29tcG9uZW50IHdpdGggdGhlIG5hbWUgZGlmZmVyZW50IGZyb20gdGhlIG9yaWdpbmFsIG9uZS4gYEZhbHNlYCBieSBkZWZhdWx0LlxuICogQHBhcmFtIHtCb29sZWFufSB0aHJvd09uRXJyb3JzIElmIHNldCB0byBmYWxzZSwgdGhlbiBlcnJvcnMgd2lsbCBvbmx5IGJlIGxvZ2dlZCB0byBjb25zb2xlLiBUcnVlIGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJuIHtDb21wb25lbnR9IGNvbXBvbmVudFxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkJGNyZWF0ZUZyb21TdGF0ZShzdGF0ZSwgcm9vdFNjb3BlLCBuZXdVbmlxdWVOYW1lLCB0aHJvd09uRXJyb3JzKSB7XG4gICAgY2hlY2soc3RhdGUsIE1hdGNoLk9iamVjdEluY2x1ZGluZyh7XG4gICAgICAgIGNvbXBOYW1lOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICBjb21wQ2xhc3M6IE1hdGNoLk9wdGlvbmFsKFN0cmluZyksXG4gICAgICAgIGV4dHJhRmFjZXRzOiBNYXRjaC5PcHRpb25hbChbU3RyaW5nXSksXG4gICAgICAgIGZhY2V0c1N0YXRlczogTWF0Y2guT3B0aW9uYWwoT2JqZWN0KSxcbiAgICAgICAgb3V0ZXJIVE1MOiBTdHJpbmdcbiAgICB9KSk7XG5cbiAgICB2YXIgbWlsb0JpbmRlciA9IHJlcXVpcmUoJy4uL2JpbmRlcicpO1xuXG4gICAgLy8gY3JlYXRlIHdyYXBwZXIgZWxlbWVudCBvcHRpb25hbGx5IHJlbmFtaW5nIGNvbXBvbmVudFxuICAgIHZhciB3cmFwRWwgPSBfY3JlYXRlQ29tcG9uZW50V3JhcEVsZW1lbnQoc3RhdGUsIG5ld1VuaXF1ZU5hbWUpO1xuXG4gICAgLy8gaW5zdGFudGlhdGUgYWxsIGNvbXBvbmVudHMgZnJvbSBIVE1MXG4gICAgdmFyIHNjb3BlID0gbWlsb0JpbmRlcih3cmFwRWwsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aHJvd09uRXJyb3JzKTtcblxuICAgIC8vIGFzIHRoZXJlIHNob3VsZCBvbmx5IGJlIG9uZSBjb21wb25lbnQsIGNhbGwgdG8gX2FueSB3aWxsIHJldHVybiBpdFxuICAgIHZhciBjb21wb25lbnQgPSBzY29wZS5fYW55KCk7XG5cbiAgICAvLyBzZXQgY29tcG9uZW50J3Mgc2NvcGVcbiAgICBpZiAocm9vdFNjb3BlKSB7XG4gICAgICAgIGNvbXBvbmVudC5zY29wZSA9IHJvb3RTY29wZTtcbiAgICAgICAgcm9vdFNjb3BlLl9hZGQoY29tcG9uZW50KTtcbiAgICB9XG5cbiAgICAvLyByZXN0b3JlIGNvbXBvbmVudCBzdGF0ZVxuICAgIGNvbXBvbmVudC5zZXRTdGF0ZShzdGF0ZSk7XG4gICAgXy5kZWZlck1ldGhvZChjb21wb25lbnQsICdicm9hZGNhc3QnLCAnc3RhdGVyZWFkeScpO1xuXG4gICAgcmV0dXJuIGNvbXBvbmVudDsgICBcbn1cblxuXG4vLyB1c2VkIGJ5IENvbXBvbmVudCQkY3JlYXRlRnJvbVN0YXRlXG5mdW5jdGlvbiBfY3JlYXRlQ29tcG9uZW50V3JhcEVsZW1lbnQoc3RhdGUsIG5ld1VuaXF1ZU5hbWUpIHtcbiAgICB2YXIgd3JhcEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgd3JhcEVsLmlubmVySFRNTCA9IHN0YXRlLm91dGVySFRNTDtcblxuICAgIHZhciBjaGlsZHJlbiA9IGRvbVV0aWxzLmNoaWxkcmVuKHdyYXBFbCk7XG4gICAgaWYgKGNoaWxkcmVuLmxlbmd0aCAhPSAxKVxuICAgICAgICB0aHJvdyBuZXcgQ29tcG9uZW50RXJyb3IoJ2Nhbm5vdCBjcmVhdGUgY29tcG9uZW50OiBpbmNvcnJlY3QgSFRNTCwgZWxlbWVudHMgbnVtYmVyOiAnICsgY2hpbGRyZW4ubGVuZ3RoICsgJyAoc2hvdWxkIGJlIDEpJyk7XG4gICAgdmFyIGNvbXBFbCA9IGNoaWxkcmVuWzBdO1xuICAgIHZhciBhdHRyID0gbmV3IEJpbmRBdHRyaWJ1dGUoY29tcEVsKTtcbiAgICBhdHRyLmNvbXBOYW1lID0gbmV3VW5pcXVlTmFtZSA/IG1pbG9Db21wb25lbnROYW1lKCkgOiBzdGF0ZS5jb21wTmFtZTtcbiAgICBhdHRyLmNvbXBDbGFzcyA9IHN0YXRlLmNvbXBDbGFzcztcbiAgICBhdHRyLmNvbXBGYWNldHMgPSBzdGF0ZS5leHRyYUZhY2V0cztcbiAgICBhdHRyLmRlY29yYXRlKCk7XG5cbiAgICByZXR1cm4gd3JhcEVsO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBjb21wb25lbnQgZnJvbSBhIERhdGFUcmFuc2ZlciBvYmplY3QgKGlmIHBvc3NpYmxlKVxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RhdGFUcmFuc2ZlclxuICogQHBhcmFtIHtEYXRhVHJhbnNmZXJ9IGRhdGFUcmFuc2ZlciBEYXRhIHRyYW5zZmVyXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCQkY3JlYXRlRnJvbURhdGFUcmFuc2ZlcihkYXRhVHJhbnNmZXIpIHtcbiAgICB2YXIgZGF0YVR5cGUgPSBfLmZpbmQoZGF0YVRyYW5zZmVyLnR5cGVzLCBmdW5jdGlvbiAodHlwZSkge1xuICAgICAgICByZXR1cm4gQ09NUE9ORU5UX0RBVEFfVFlQRV9SRUdFWC50ZXN0KHR5cGUpO1xuICAgIH0pO1xuICAgIGlmICghZGF0YVR5cGUpIHJldHVybjtcblxuICAgIHZhciBzdGF0ZSA9IF8uanNvblBhcnNlKGRhdGFUcmFuc2Zlci5nZXREYXRhKGRhdGFUeXBlKSk7XG4gICAgaWYgKCFzdGF0ZSkgcmV0dXJuO1xuXG4gICAgcmV0dXJuIENvbXBvbmVudC5jcmVhdGVGcm9tU3RhdGUoc3RhdGUsIHVuZGVmaW5lZCwgdHJ1ZSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogSW5pdGlhbGl6ZXMgY29tcG9uZW50LiBBdXRvbWF0aWNhbGx5IGNhbGxlZCBieSBpbmhlcml0ZWQgY29uc3RydWN0b3Igb2YgRmFjZXRlZE9iamVjdC5cbiAqIFN1YmNsYXNzZXMgc2hvdWxkIGNhbGwgaW5oZXJpdGVkIGluaXQgbWV0aG9kczpcbiAqIGBgYFxuICogQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIHNjb3BlIHRvIHdoaWNoIGNvbXBvbmVudCB3aWxsIGJlbG9uZy4gSXQgaXMgdXN1YWxseSBhIHRvcCBsZXZlbCBzY29wZSBvYmplY3QgcmV0dXJuZWQgYnkgYG1pbG8uYmluZGVyYCBvciBgc2NvcGVgIHByb3BlcnR5IG9mIENvbnRhaW5lciBmYWNldC5cbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBET00gZWxlbWVudCB0aGF0IGNvbXBvbmVudCBpcyBhdHRhY2hlZCB0b1xuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgY29tcG9uZW50IG5hbWUsIHNob3VsZCBiZSB1bmlxdWUgaW4gdGhlIHNjb3BlIG9mIGNvbXBvbmVudFxuICogQHBhcmFtIHtDb21wb25lbnRJbmZvfSBjb21wb25lbnRJbmZvIGluc3RhbmNlIG9mIENvbXBvbmVudEluZm8gY2xhc3MgdGhhdCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBjb3B5IG9mIGNvbXBvbmVudFxuICogIFRPRE8gdHJ5IHJlbW92aW5nIGl0XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRpbml0KHNjb3BlLCBlbGVtZW50LCBuYW1lLCBjb21wb25lbnRJbmZvKSB7XG4gICAgLy8gY3JlYXRlIERPTSBlbGVtZW50IGlmIGl0IHdhc24ndCBwYXNzZWQgdG8gQ29uc3RydWN0b3JcbiAgICB0aGlzLmVsID0gZWxlbWVudCB8fCB0aGlzLmNyZWF0ZUVsZW1lbnQoKTtcblxuICAgIC8vIHN0b3JlIHJlZmVyZW5jZSB0byBjb21wb25lbnQgb24gRE9NIGVsZW1lbnRcbiAgICBpZiAodGhpcy5lbCkge1xuICAgICAgICAvLyBjaGVjayB0aGF0IGVsZW1lbnQgZG9lcyBub3QgaGF2ZSBhIGNvbXBvbmVudCBhbHJlYWR5IGF0YWNoZWRcbiAgICAgICAgdmFyIGVsQ29tcCA9IHRoaXMuZWxbY29uZmlnLmNvbXBvbmVudFJlZl07XG4gICAgICAgIGlmIChlbENvbXApXG4gICAgICAgICAgICBsb2dnZXIud2FybignY29tcG9uZW50ICcgKyBuYW1lICsgJyBhdHRhY2hlZCB0byBlbGVtZW50IHRoYXQgYWxyZWFkeSBoYXMgY29tcG9uZW50ICcgKyBlbENvbXAubmFtZSk7XG5cbiAgICAgICAgdGhpcy5lbFtjb25maWcuY29tcG9uZW50UmVmXSA9IHRoaXM7XG4gICAgfVxuXG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgY29tcG9uZW50SW5mbzogY29tcG9uZW50SW5mbyxcbiAgICAgICAgZXh0cmFGYWNldHM6IFtdXG4gICAgfSwgXy5FTlVNKTtcblxuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuXG4gICAgLy8gY3JlYXRlIGNvbXBvbmVudCBtZXNzZW5nZXJcbiAgICB2YXIgbWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzKTtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsIE1FU1NFTkdFUl9QUk9QRVJUWSwgbWVzc2VuZ2VyKTtcblxuICAgIC8vIGNoZWNrIGFsbCBmYWNldHMgZGVwZW5kZW5jaWVzIChyZXF1aXJlZCBmYWNldHMpXG4gICAgdGhpcy5hbGxGYWNldHMoJ2NoZWNrJyk7XG5cbiAgICAvLyBzdGFydCBhbGwgZmFjZXRzXG4gICAgdGhpcy5hbGxGYWNldHMoJ3N0YXJ0Jyk7XG5cbiAgICAvLyBjYWxsIHN0YXJ0IG1ldGhvZCBpZiBpdCdzIGRlZmluZWQgaW4gc3ViY2xhc3NcbiAgICBpZiAodGhpcy5zdGFydCkgdGhpcy5zdGFydCgpO1xufVxuXG5cbi8qKlxuICogVGhpcyBpcyBhIHN0dWIgdG8gYXZvaWQgY29uZnVzaW9uIHdoZXRoZXIgdGhlIG1ldGhvZCBvZiBzdXBlcmNsYXNzIHNob3VsZCBiZSBjYWxsZWQgaW4gc3ViY2xhc3Nlc1xuICogVGhlIHN0YXJ0IG1ldGhvZCBvZiBzdWJjbGFzcyBpbnN0YW5jZSBpcyBjYWxsZWQgb25jZSBhbGwgdGhlIGZhY2V0cyBhcmUgY3JlYXRlZCwgaW5pdGlhbGl6ZWQgYW5kIHN0YXJ0ZWQgKHNlZSBhYm92ZSlcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JHN0YXJ0KCkge31cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2QuXG4gKiBJbml0aWFsaXplcyB0aGUgZWxlbWVudCB3aGljaCB0aGlzIGNvbXBvbmVudCBpcyBib3VuZCB0b1xuICpcbiAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuIGEgY29tcG9uZW50IGlzIGluc3RhbnRpYXRlZCBvdXRzaWRlIHRoZSBET00gYW5kXG4gKiB3aWxsIGdlbmVyYXRlIGEgbmV3IGVsZW1lbnQgZm9yIHRoZSBjb21wb25lbnQuXG4gKiBcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRjcmVhdGVFbGVtZW50KCkge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgIHJldHVybjtcblxuICAgIHRoaXMuZWwgPSB0aGlzLmRvbVxuICAgICAgICAgICAgICAgID8gdGhpcy5kb20uY3JlYXRlRWxlbWVudCgpXG4gICAgICAgICAgICAgICAgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdESVYnKTtcblxuICAgIHJldHVybiB0aGlzLmVsO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyB0cnVlIGlmIGNvbXBvbmVudCBoYXMgZmFjZXRcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gZmFjZXROYW1lT3JDbGFzc1xuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGhhc0ZhY2V0KGZhY2V0TmFtZU9yQ2xhc3MpIHtcbiAgICB2YXIgZmFjZXROYW1lID0gXy5maXJzdExvd2VyQ2FzZSh0eXBlb2YgZmFjZXROYW1lT3JDbGFzcyA9PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBmYWNldE5hbWVPckNsYXNzLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGZhY2V0TmFtZU9yQ2xhc3MpO1xuXG4gICAgdmFyIGZhY2V0ID0gdGhpc1tmYWNldE5hbWVdO1xuICAgIGlmICghIGZhY2V0IGluc3RhbmNlb2YgQ29tcG9uZW50RmFjZXQpXG4gICAgICAgIGxvZ2dlci53YXJuKCdleHBlY3RlZCBmYWNldCcsIGZhY2V0TmFtZSwgJ2J1dCB0aGlzIHByb3BlcnR5IG5hbWUgaXMgdXNlZCBmb3Igc29tZXRoaW5nIGVsc2UnKTtcblxuICAgIHJldHVybiAhISBmYWNldDtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2QuXG4gKiBBZGRzIGZhY2V0IHdpdGggZ2l2ZW4gbmFtZSBvciBjbGFzcyB0byB0aGUgaW5zdGFuY2Ugb2YgQ29tcG9uZW50IChvciBpdHMgc3ViY2xhc3MpLlxuICogXG4gKiBAcGFyYW0ge1N0cmluZ3xTdWJjbGFzcyhDb21wb25lbnQpfSBmYWNldE5hbWVPckNsYXNzIG5hbWUgb2YgZmFjZXQgY2xhc3Mgb3IgdGhlIGNsYXNzIGl0c2VsZi4gSWYgbmFtZSBpcyBwYXNzZWQsIHRoZSBjbGFzcyB3aWxsIGJlIHJldGlyZXZlZCBmcm9tIGZhY2V0c1JlZ2lzdHJ5XG4gKiBAcGFyYW0ge09iamVjdH0gZmFjZXRDb25maWcgb3B0aW9uYWwgZmFjZXQgY29uZmlndXJhdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IGZhY2V0TmFtZSBvcHRpb25hbCBmYWNldCBuYW1lLiBBbGxvd3MgdG8gYWRkIGZhY2V0IHVuZGVyIGEgbmFtZSBkaWZmZXJlbnQgZnJvbSB0aGUgY2xhc3MgbmFtZSBzdXBwbGllZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gdGhyb3dPbkVycm9ycyBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gZXJyb3JzIHdpbGwgb25seSBiZSBsb2dnZWQgdG8gY29uc29sZS4gVHJ1ZSBieSBkZWZhdWx0LlxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkYWRkRmFjZXQoZmFjZXROYW1lT3JDbGFzcywgZmFjZXRDb25maWcsIGZhY2V0TmFtZSwgdGhyb3dPbkVycm9ycykge1xuICAgIGNoZWNrKGZhY2V0TmFtZU9yQ2xhc3MsIE1hdGNoLk9uZU9mKFN0cmluZywgTWF0Y2guU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQpKSk7XG4gICAgY2hlY2soZmFjZXRDb25maWcsIE1hdGNoLk9wdGlvbmFsKE9iamVjdCkpO1xuICAgIGNoZWNrKGZhY2V0TmFtZSwgTWF0Y2guT3B0aW9uYWwoU3RyaW5nKSk7XG5cbiAgICB2YXIgRmFjZXRDbGFzcztcbiAgICAvLyBpZiBvbmx5IG5hbWUgcGFzc2VkLCByZXRyaWV2ZSBmYWNldCBjbGFzcyBmcm9tIHJlZ2lzdHJ5XG4gICAgaWYgKHR5cGVvZiBmYWNldE5hbWVPckNsYXNzID09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciBmYWNldENsYXNzTmFtZSA9IF8uZmlyc3RVcHBlckNhc2UoZmFjZXROYW1lT3JDbGFzcyk7XG4gICAgICAgIEZhY2V0Q2xhc3MgPSBmYWNldHNSZWdpc3RyeS5nZXQoZmFjZXRDbGFzc05hbWUpO1xuICAgIH0gZWxzZSBcbiAgICAgICAgRmFjZXRDbGFzcyA9IGZhY2V0TmFtZU9yQ2xhc3M7XG5cbiAgICBpZiAoIWZhY2V0TmFtZSlcbiAgICAgICAgZmFjZXROYW1lID0gXy5maXJzdExvd2VyQ2FzZShGYWNldENsYXNzLm5hbWUpO1xuXG4gICAgdGhpcy5leHRyYUZhY2V0cy5wdXNoKGZhY2V0TmFtZSk7XG5cbiAgICAvLyBhZGQgZmFjZXQgdXNpbmcgbWV0aG9kIG9mIEZhY2V0ZWRPYmplY3RcbiAgICB2YXIgbmV3RmFjZXQgPSBGYWNldGVkT2JqZWN0LnByb3RvdHlwZS5hZGRGYWNldC5jYWxsKHRoaXMsIEZhY2V0Q2xhc3MsIGZhY2V0Q29uZmlnLCBmYWNldE5hbWUsIHRocm93T25FcnJvcnMpO1xuXG4gICAgLy8gY2hlY2sgZGVwZW5lZGVuY2llcyBhbmQgc3RhcnQgZmFjZXRcbiAgICBpZiAobmV3RmFjZXQuY2hlY2spIG5ld0ZhY2V0LmNoZWNrKCk7XG4gICAgaWYgKG5ld0ZhY2V0LnN0YXJ0KSBuZXdGYWNldC5zdGFydCgpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZC5cbiAqIEVudm9rZSBnaXZlbiBtZXRob2Qgd2l0aCBvcHRpb25hbCBwYXJhbWV0ZXJzIG9uIGFsbCBmYWNldHMuXG4gKiBSZXR1cm5zIHRoZSBtYXAgb2YgdmFsdWVzIHJldHVybmVkIGJ5IGFsbCBmYWNldHMuIElmIHRoZSBmYWNldCBkb2Vzbid0IGhhdmUgdGhlIG1ldGhvZCBpdCBpcyBzaW1wbHkgbm90IGNhbGxlZCBhbmQgdGhlIHZhbHVlIGluIHRoZSBtYXAgd2lsbCBiZSB1bmRlZmluZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCBtZXRob2QgbmFtZSB0byBlbnZva2Ugb24gdGhlIGZhY2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRhbGxGYWNldHMobWV0aG9kKSB7IC8vICwuLi4gYXJndW1lbnRzXG4gICAgdmFyIGFyZ3MgPSBfLnNsaWNlKGFyZ3VtZW50cywgMSk7XG5cbiAgICByZXR1cm4gXy5tYXBLZXlzKHRoaXMuZmFjZXRzLCBmdW5jdGlvbihmYWNldCwgZmN0TmFtZSkge1xuICAgICAgICBpZiAoZmFjZXQgJiYgdHlwZW9mIGZhY2V0W21ldGhvZF0gPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgIHJldHVybiBmYWNldFttZXRob2RdLmFwcGx5KGZhY2V0LCBhcmdzKTtcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2QuXG4gKiBcbiAqIEBwYXJhbSB7W1N0cmluZ119IG5hbWUgb3B0aW9uYWwgbmV3IG5hbWUgb2YgY29tcG9uZW50LCBcbiAqIEBwYXJhbSB7W0Jvb2xlYW5dfSByZW5hbWVJblNjb3BlIG9wdGlvbmFsIGZhbHNlIHRvIG5vdCByZW5hbWUgQ29tcG9uZW50SW5mbyBvYmplY3QgaW4gaXRzIHNjb3BlLCB0cnVlIGJ5IGRlZmF1bHRcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JHJlbmFtZShuYW1lLCByZW5hbWVJblNjb3BlKSB7XG4gICAgbmFtZSA9IG5hbWUgfHwgbWlsb0NvbXBvbmVudE5hbWUoKTtcbiAgICB0aGlzLmNvbXBvbmVudEluZm8ucmVuYW1lKG5hbWUsIGZhbHNlKTtcbiAgICBTY29wZS5yZW5hbWUodGhpcywgbmFtZSwgcmVuYW1lSW5TY29wZSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogUmVtb3ZlcyBjb21wb25lbnQgZnJvbSBpdHMgc2NvcGUuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBwcmVzZXJ2ZVNjb3BlUHJvcGVydHkgdHJ1ZSBub3QgdG8gZGVsZXRlIHNjb3BlIHByb3BlcnR5IG9mIGNvbXBvbmVudFxuICogQHBhcmFtIHtCb29sZWFufSBxdWlldCBvcHRpb25hbCB0cnVlIHRvIHN1cHByZXNzIHRoZSB3YXJuaW5nIG1lc3NhZ2UgaWYgdGhlIGNvbXBvbmVudCBpcyBub3QgaW4gc2NvcGVcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JHJlbW92ZShwcmVzZXJ2ZVNjb3BlUHJvcGVydHksIHF1aWV0KSB7XG4gICAgaWYgKHRoaXMuc2NvcGUpIHtcbiAgICAgICAgdGhpcy5zY29wZS5fcmVtb3ZlKHRoaXMubmFtZSwgcXVpZXQpO1xuICAgICAgICBpZiAoISBwcmVzZXJ2ZVNjb3BlUHJvcGVydHkpXG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zY29wZTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogSW5zZXJ0cyB0aGUgY29tcG9uZW50IGludG8gdGhlIERPTSBhbmQgYXR0ZW1wdHMgdG8gYWRqdXN0IHRoZSBzY29wZSB0cmVlIGFjY29yZGluZ2x5LlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50RWwgICAgVGhlIGVsZW1lbnQgaW50byB3aGljaCB0aGUgY29tcG9uZW50IHNob3VsZCBiZSBpbnNlcnRlZC5cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHJlZmVyZW5jZUVsIChvcHRpb25hbCkgVGhlIHJlZmVyZW5jZSBlbGVtZW50IGl0IHNob3VsZCBiZSBpbnNlcnRlZCBiZWZvcmUuXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRpbnNlcnRJbnRvKHBhcmVudEVsLCByZWZlcmVuY2VFbCkge1xuICAgIHBhcmVudEVsLmluc2VydEJlZm9yZSh0aGlzLmVsLCByZWZlcmVuY2VFbCk7XG4gICAgdGhpcy5zZXRTY29wZVBhcmVudEZyb21ET00oKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHJpZXZlcyBhbGwgY29tcG9uZW50IHN0YXRlLCBpbmNsdWRpbmcgaW5mb3JtYXRpb24gYWJvdXQgaXRzIGNsYXNzLCBleHRyYSBmYWNldHMsIGZhY2V0cyBkYXRhIGFuZCBhbGwgc2NvcGUgY2hpbGRyZW4uXG4gKiBUaGlzIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gc2F2ZS9sb2FkLCBjb3B5L3Bhc3RlIGFuZCBkcmFnL2Ryb3AgY29tcG9uZW50IFxuICogUmV0dXJucyBjb21wb25lbnQgc3RhdGVcbiAqXG4gKiBAdGhpcyB7Q29tcG9uZW50fSBjb21wb25lbnQgd2hpY2ggc3RhdGUgd2lsbCBiZSBzYXZlZFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkZ2V0U3RhdGUoKSB7XG4gICAgdGhpcy5icm9hZGNhc3QoJ2dldHN0YXRlc3RhcnRlZCcsIHsgcm9vdENvbXBvbmVudDogdGhpcyB9LCB1bmRlZmluZWQsIHRydWUpO1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX2dldFN0YXRlKHRydWUpO1xuICAgIHN0YXRlLm91dGVySFRNTCA9IHRoaXMuZWwub3V0ZXJIVE1MO1xuICAgIF8uZGVmZXJNZXRob2QodGhpcywgJ2Jyb2FkY2FzdCcsICdnZXRzdGF0ZWNvbXBsZXRlZCcsIHsgcm9vdENvbXBvbmVudDogdGhpcyB9LCB1bmRlZmluZWQsIHRydWUpO1xuICAgIHJldHVybiBzdGF0ZTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHJpZXZlcyBhbGwgY29tcG9uZW50IHN0YXRlLCBpbmNsdWRpbmcgaW5mb3JtYXRpb24gYWJvdXQgaXRzIGNsYXNzLCBleHRyYSBmYWNldHMsIGZhY2V0cyBkYXRhIGFuZCBhbGwgc2NvcGUgY2hpbGRyZW4uXG4gKiBUaGlzIGluZm9ybWF0aW9uIGlzIHVzZWQgdG8gc2F2ZS9sb2FkLCBjb3B5L3Bhc3RlIGFuZCBkcmFnL2Ryb3AgY29tcG9uZW50IFxuICogSWYgY29tcG9uZW50IGhhcyBbVHJhbnNmZXJdKC4vY19mYWNldHMvVHJhbnNmZXIuanMuaHRtbCkgZmFjZXQgb24gaXQsIHRoaXMgbWV0aG9kIHJldHJpZXZlcyBzdGF0ZSBmcm9tIHRoaXMgZmFjZXRcbiAqIFJldHVybnMgY29tcG9uZW50IHN0YXRlXG4gKlxuICogQHRoaXMge0NvbXBvbmVudH0gY29tcG9uZW50IHdoaWNoIHN0YXRlIHdpbGwgYmUgc2F2ZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGNhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMuIFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkZ2V0VHJhbnNmZXJTdGF0ZShvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmZXJcbiAgICAgICAgICAgID8gdGhpcy50cmFuc2Zlci5nZXRTdGF0ZShvcHRpb25zKVxuICAgICAgICAgICAgOiB0aGlzLmdldFN0YXRlKG9wdGlvbnMpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgY29tcG9uZW50XG4gKiBVc2VkIGJ5IGNsYXNzIG1ldGhvZCBgQ29tcG9uZW50LmdldFN0YXRlYCBhbmQgYnkgW0NvbnRhaW5lcl0oLi9jX2ZhY2V0cy9Db250YWluZXIuanMuaHRtbCkgZmFjZXQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVlcFN0YXRlIGZhbHNlIHRvIGdldCBzaGFsbG93IHN0YXRlIGZyb20gYWxsIGZhY2V0cyAodHJ1ZSBieSBkZWZhdWx0KVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkX2dldFN0YXRlKGRlZXBTdGF0ZSl7XG5cbiAgICB2YXIgZmFjZXRzU3RhdGVzID0gdGhpcy5hbGxGYWNldHMoJ2dldFN0YXRlJywgZGVlcFN0YXRlID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZSk7XG4gICAgZmFjZXRzU3RhdGVzID0gXy5maWx0ZXJLZXlzKGZhY2V0c1N0YXRlcywgZnVuY3Rpb24oZmN0U3RhdGUpIHtcbiAgICAgICAgcmV0dXJuICEhIGZjdFN0YXRlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tcE5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgY29tcENsYXNzOiB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgIGV4dHJhRmFjZXRzOiB0aGlzLmV4dHJhRmFjZXRzLFxuICAgICAgICBmYWNldHNTdGF0ZXM6IGZhY2V0c1N0YXRlc1xuICAgIH07XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRoZSBzdGF0ZSBvZiBjb21wb25lbnQuXG4gKiBVc2VkIGJ5IGNsYXNzIG1ldGhvZCBgQ29tcG9uZW50LmNyZWF0ZUZyb21TdGF0ZWAgYW5kIGJ5IFtDb250YWluZXJdKC4vY19mYWNldHMvQ29udGFpbmVyLmpzLmh0bWwpIGZhY2V0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgc3RhdGUgdG8gc2V0IHRoZSBjb21wb25lbnRcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JHNldFN0YXRlKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlLmZhY2V0c1N0YXRlcylcbiAgICAgICAgXy5lYWNoS2V5KHN0YXRlLmZhY2V0c1N0YXRlcywgZnVuY3Rpb24oZmN0U3RhdGUsIGZjdE5hbWUpIHtcbiAgICAgICAgICAgIHZhciBmYWNldCA9IHRoaXNbZmN0TmFtZV07XG4gICAgICAgICAgICBpZiAoZmFjZXQgJiYgdHlwZW9mIGZhY2V0LnNldFN0YXRlID09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICAgICAgZmFjZXQuc2V0U3RhdGUoZmN0U3RhdGUpO1xuICAgICAgICB9LCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2QuXG4gKiBSZXR1cm5zIHRoZSBzY29wZSBwYXJlbnQgb2YgYSBjb21wb25lbnQuXG4gKiBJZiBgY29uZGl0aW9uT3JGYWNldGAgcGFyYW1ldGVyIGlzIG5vdCBzcGVjaWZpZWQsIGFuIGltbWVkaWF0ZSBwYXJlbnQgd2lsbCBiZSByZXR1cm5lZCwgb3RoZXJ3aXNlIHRoZSBjbG9zZXN0IGFuY2VzdG9yIHdpdGggYSBzcGVjaWZpZWQgZmFjZXQgb3IgcGFzc2luZyBjb25kaXRpb24gdGVzdC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gY29uZGl0aW9uT3JGYWNldCBvcHRpb25hbCBjb25kaXRpb24gdGhhdCBjb21wb25lbnQgc2hvdWxkIHBhc3MgKG9yIGZhY2V0IG5hbWUgaXQgc2hvdWxkIGNvbnRhaW4pXG4gKiBAcmV0dXJuIHtDb21wb25lbnR8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkZ2V0U2NvcGVQYXJlbnQoY29uZGl0aW9uT3JGYWNldCkge1xuICAgIHJldHVybiBfY2FsbEdldFNjb3BlUGFyZW50LmNhbGwodGhpcywgX2dldFNjb3BlUGFyZW50LCBjb25kaXRpb25PckZhY2V0KTtcbn1cblxuZnVuY3Rpb24gX2NhbGxHZXRTY29wZVBhcmVudChfZ2V0U2NvcGVQYXJlbnRGdW5jLCBjb25kaXRpb25PckZhY2V0KSB7XG4gICAgY2hlY2soY29uZGl0aW9uT3JGYWNldCwgTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoRnVuY3Rpb24sIFN0cmluZykpKTtcbiAgICB2YXIgY29uZGl0aW9uRnVuYyA9IGNvbXBvbmVudFV0aWxzLl9tYWtlQ29tcG9uZW50Q29uZGl0aW9uRnVuYyhjb25kaXRpb25PckZhY2V0KTtcbiAgICByZXR1cm4gX2dldFNjb3BlUGFyZW50RnVuYy5jYWxsKHRoaXMsIGNvbmRpdGlvbkZ1bmMpOyAgIFxufVxuXG5mdW5jdGlvbiBfZ2V0U2NvcGVQYXJlbnQoY29uZGl0aW9uRnVuYykge1xuICAgIHZhciBwYXJlbnQ7XG4gICAgdHJ5IHsgcGFyZW50ID0gdGhpcy5zY29wZS5faG9zdE9iamVjdC5vd25lcjsgfSBjYXRjaChlKSB7fVxuXG4gICAgLy8gV2hlcmUgdGhlcmUgaXMgbm8gcGFyZW50LCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHVuZGVmaW5lZFxuICAgIC8vIFRoZSBwYXJlbnQgY29tcG9uZW50IGlzIGNoZWNrZWQgcmVjdXJzaXZlbHlcbiAgICBpZiAocGFyZW50KSB7XG4gICAgICAgIGlmICghIGNvbmRpdGlvbkZ1bmMgfHwgY29uZGl0aW9uRnVuYyhwYXJlbnQpIClcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBfZ2V0U2NvcGVQYXJlbnQuY2FsbChwYXJlbnQsIGNvbmRpdGlvbkZ1bmMpO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgc2NvcGUgcGFyZW50IHdpdGggYSBnaXZlbiBjbGFzcywgd2l0aCBzYW1lIGNsYXNzIGlmIG5vdCBzcGVjaWZpZWRcbiAqXG4gKiBAcGFyYW0ge1tGdW5jdGlvbl19IENvbXBvbmVudENsYXNzIGNvbXBvbmVudCBjbGFzcyB0aGF0IHRoZSBwYXJlbnQgc2hvdWxkIGhhdmUsIHNhbWUgY2xhc3MgYnkgZGVmYXVsdFxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkZ2V0U2NvcGVQYXJlbnRXaXRoQ2xhc3MoQ29tcG9uZW50Q2xhc3MpIHtcbiAgICBDb21wb25lbnRDbGFzcyA9IENvbXBvbmVudENsYXNzIHx8IHRoaXMuY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIF9nZXRTY29wZVBhcmVudC5jYWxsKHRoaXMsIGZ1bmN0aW9uKGNvbXApIHtcbiAgICAgICAgcmV0dXJuIGNvbXAgaW5zdGFuY2VvZiBDb21wb25lbnRDbGFzcztcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2QuXG4gKiBSZXR1cm5zIHRoZSB0b3Btb3N0IHNjb3BlIHBhcmVudCBvZiBhIGNvbXBvbmVudC5cbiAqIElmIGBjb25kaXRpb25PckZhY2V0YCBwYXJhbWV0ZXIgaXMgbm90IHNwZWNpZmllZCwgdGhlIHRvcG1vc3Qgc2NvcGUgcGFyZW50IHdpbGwgYmUgcmV0dXJuZWQsIG90aGVyd2lzZSB0aGUgdG9wbW9zdCBhbmNlc3RvciB3aXRoIGEgc3BlY2lmaWVkIGZhY2V0IG9yIHBhc3NpbmcgY29uZGl0aW9uIHRlc3QuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGNvbmRpdGlvbk9yRmFjZXQgb3B0aW9uYWwgY29uZGl0aW9uIHRoYXQgY29tcG9uZW50IHNob3VsZCBwYXNzIChvciBmYWNldCBuYW1lIGl0IHNob3VsZCBjb250YWluKVxuICogQHJldHVybiB7Q29tcG9uZW50fHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGdldFRvcFNjb3BlUGFyZW50KGNvbmRpdGlvbk9yRmFjZXQpIHtcbiAgICByZXR1cm4gX2NhbGxHZXRTY29wZVBhcmVudC5jYWxsKHRoaXMsIF9nZXRUb3BTY29wZVBhcmVudCwgY29uZGl0aW9uT3JGYWNldCk7XG59XG5cbmZ1bmN0aW9uIF9nZXRUb3BTY29wZVBhcmVudChjb25kaXRpb25GdW5jKSB7XG4gICAgdmFyIHRvcFBhcmVudFxuICAgICAgICAsIHBhcmVudCA9IHRoaXM7XG4gICAgZG8ge1xuICAgICAgICBwYXJlbnQgPSBfZ2V0U2NvcGVQYXJlbnQuY2FsbChwYXJlbnQsIGNvbmRpdGlvbkZ1bmMpO1xuICAgICAgICBpZiAocGFyZW50KVxuICAgICAgICAgICAgdG9wUGFyZW50ID0gcGFyZW50O1xuICAgIH0gd2hpbGUgKHBhcmVudCk7XG5cbiAgICByZXR1cm4gdG9wUGFyZW50O1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBzY29wZSBwYXJlbnQgd2l0aCBhIGdpdmVuIGNsYXNzLCB3aXRoIHNhbWUgY2xhc3MgaWYgbm90IHNwZWNpZmllZFxuICpcbiAqIEBwYXJhbSB7W0Z1bmN0aW9uXX0gQ29tcG9uZW50Q2xhc3MgY29tcG9uZW50IGNsYXNzIHRoYXQgdGhlIHBhcmVudCBzaG91bGQgaGF2ZSwgc2FtZSBjbGFzcyBieSBkZWZhdWx0XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRnZXRUb3BTY29wZVBhcmVudFdpdGhDbGFzcyhDb21wb25lbnRDbGFzcykge1xuICAgIENvbXBvbmVudENsYXNzID0gQ29tcG9uZW50Q2xhc3MgfHwgdGhpcy5jb25zdHJ1Y3RvcjtcbiAgICByZXR1cm4gX2dldFRvcFNjb3BlUGFyZW50LmNhbGwodGhpcywgZnVuY3Rpb24oY29tcCkge1xuICAgICAgICByZXR1cm4gY29tcCBpbnN0YW5jZW9mIENvbXBvbmVudENsYXNzO1xuICAgIH0pO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogRmluZHMgc2NvcGUgcGFyZW50IG9mIGNvbXBvbmVudCB1c2luZyBET00gdHJlZSAodW5saWtlIGdldFNjb3BlUGFyZW50IHRoYXQgc2ltcGx5IGdvZXMgdXAgdGhlIHNjb3BlIHRyZWUpLlxuICogV2hpbGUgZ2V0U2NvcGVQYXJlbnQgaXMgZmFzdGVyIGl0IG1heSBmYWlsIGlmIHNjb3BlIGNoYWluIGlzIG5vdCBzZXR1cCB5ZXQgKGUuZy4sIHdoZW4gY29tcG9uZW50IGhhcyBiZWVuIGp1c3QgaW5zZXJ0ZWQpLlxuICogVGhlIHNjb3BlIHByb3BlcnR5IG9mIGNvbXBvbmVudCB3aWxsIGJlIGNoYW5nZWQgdG8gcG9pbnQgdG8gc2NvcGUgb2JqZWN0IG9mIGNvbnRhaW5lciBmYWNldCBvZiB0aGF0IHBhcmVudC5cbiAqIFJldHVybmVkIHNjb3BlIHBhcmVudCBvZiB0aGUgY29tcG9uZW50IHdpbGwgYmUgdW5kZWZpbmVkIChhcyB3ZWxsIGFzIGNvbXBvbmVudCdzIHNjb3BlIHByb3BlcnR5KSBpZiBubyBwYXJlbnQgaW4gdGhlIERPTSB0cmVlIGhhcyBjb250YWluZXIgZmFjZXQuXG4gKiBUT0RPIE1ldGhvZCB3aWxsIG5vdCBiaW5kIERPTSBjaGlsZHJlbiBjb3JyZWN0bHkgaWYgY29tcG9uZW50IGhhcyBubyBjb250YWluZXIgZmFjZXQuXG4gKlxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkc2V0U2NvcGVQYXJlbnRGcm9tRE9NKCkge1xuICAgIHZhciBwYXJlbnRFbCA9IHRoaXMuZWwucGFyZW50Tm9kZTtcblxuICAgIHZhciBwYXJlbnQsIGZvdW5kUGFyZW50O1xuICAgIHdoaWxlIChwYXJlbnRFbCAmJiAhIGZvdW5kUGFyZW50KSB7XG4gICAgICAgIHBhcmVudCA9IENvbXBvbmVudC5nZXRDb21wb25lbnQocGFyZW50RWwpO1xuICAgICAgICBmb3VuZFBhcmVudCA9IHBhcmVudCAmJiBwYXJlbnQuY29udGFpbmVyO1xuICAgICAgICBwYXJlbnRFbCA9IHBhcmVudEVsLnBhcmVudE5vZGU7XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmUoKTsgLy8gcmVtb3ZlIGNvbXBvbmVudCBmcm9tIGl0cyBjdXJyZW50IHNjb3BlIChpZiBpdCBpcyBkZWZpbmVkKVxuICAgIGlmIChmb3VuZFBhcmVudCkge1xuICAgICAgICB0aGlzLnJlbmFtZSh1bmRlZmluZWQsIGZhbHNlKTtcbiAgICAgICAgcGFyZW50LmNvbnRhaW5lci5zY29wZS5fYWRkKHRoaXMpO1xuICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgIH0gICAgICAgIFxufVxuXG5cbi8qKlxuICogV2Fsa3MgY29tcG9uZW50IHRyZWUsIGNhbGxpbmcgcHJvdmlkZWQgY2FsbGJhY2sgb24gZWFjaCBjb21wb25lbnRcbiAqXG4gKiBAcGFyYW0gY2FsbGJhY2tcbiAqIEBwYXJhbSB0aGlzQXJnXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCR3YWxrU2NvcGVUcmVlKGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzKTtcbiAgICBpZiAoIXRoaXMuY29udGFpbmVyKSByZXR1cm47XG4gICAgdGhpcy5jb250YWluZXIuc2NvcGUuX2VhY2goZnVuY3Rpb24oY29tcG9uZW50KSB7XG4gICAgICAgIGNvbXBvbmVudC53YWxrU2NvcGVUcmVlKGNhbGxiYWNrLCB0aGlzQXJnKTtcbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBDb21wb25lbnQkdHJlZVBhdGhPZihjb21wb25lbnQpIHtcbiAgICByZXR1cm4gZG9tVXRpbHMudHJlZVBhdGhPZih0aGlzLmVsLCBjb21wb25lbnQuZWwpO1xufVxuXG5cbmZ1bmN0aW9uIENvbXBvbmVudCRnZXRDb21wb25lbnRBdFRyZWVQYXRoKHRyZWVQYXRoLCBuZWFyZXN0KSB7XG4gICAgdmFyIG5vZGUgPSBkb21VdGlscy5nZXROb2RlQXRUcmVlUGF0aCh0aGlzLmVsLCB0cmVlUGF0aCwgbmVhcmVzdCk7XG4gICAgcmV0dXJuIENvbXBvbmVudC5nZXRDb21wb25lbnQobm9kZSk7XG59XG5cblxuZnVuY3Rpb24gQ29tcG9uZW50JGluc2VydEF0VHJlZVBhdGgodHJlZVBhdGgsIGNvbXBvbmVudCwgbmVhcmVzdCkge1xuICAgIHZhciB3YXNJbnNlcnRlZCA9IGRvbVV0aWxzLmluc2VydEF0VHJlZVBhdGgodGhpcy5lbCwgdHJlZVBhdGgsIGNvbXBvbmVudC5lbCk7XG4gICAgaWYgKHdhc0luc2VydGVkKSBjb21wb25lbnQuc2V0U2NvcGVQYXJlbnRGcm9tRE9NKCk7XG4gICAgcmV0dXJuIHdhc0luc2VydGVkO1xufVxuXG5cbi8qKlxuICogQnJvYWRjYXN0IG1lc3NhZ2UgdG8gY29tcG9uZW50IGFuZCB0byBhbGwgaXRzIHNjb3BlIGNoaWxkcmVuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBtc2cgbWVzc2FnZSB0byBiZSBzZW50XG4gKiBAcGFyYW0ge1tBbnldfSBkYXRhIG9wdGlvbmFsIG1lc3NhZ2UgZGF0YVxuICogQHBhcmFtIHtbRnVuY3Rpb25dfSBjYWxsYmFjayBvcHRpb25hbCBjYWxsYmFja1xuICogQHBhcmFtIHtbQm9vbGVhbl19IHN5bmNocm9ub3VzbHkgaWYgaXQgc2hvdWxkIHVzZSBwb3N0TWVzc2FnZVN5bmNcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGJyb2FkY2FzdChtc2csIGRhdGEsIGNhbGxiYWNrLCBzeW5jaHJvbm91c2x5KSB7XG4gICAgdmFyIHBvc3RNZXRob2QgPSBzeW5jaHJvbm91c2x5ID8gJ3Bvc3RNZXNzYWdlU3luYycgOiAncG9zdE1lc3NhZ2UnO1xuICAgIHRoaXMud2Fsa1Njb3BlVHJlZShmdW5jdGlvbihjb21wb25lbnQpIHtcbiAgICAgICAgY29tcG9uZW50W3Bvc3RNZXRob2RdKG1zZywgZGF0YSwgY2FsbGJhY2spO1xuICAgIH0pO1xufVxuXG5cbi8qKlxuICogRGVzdHJveSBjb21wb25lbnQ6IHJlbW92ZXMgY29tcG9uZW50IGZyb20gRE9NLCByZW1vdmVzIGl0IGZyb20gc2NvcGUsIGRlbGV0ZXMgYWxsIHJlZmVyZW5jZXMgdG8gRE9NIG5vZGVzIGFuZCB1bnN1YnNjcmliZXMgZnJvbSBhbGwgbWVzc2FnZXMgYm90aCBjb21wb25lbnQgYW5kIGFsbCBmYWNldHNcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGRlc3Ryb3kocXVpZXQpIHtcbiAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgIGlmICghcXVpZXQpIGxvZ2dlci53YXJuKCdDb21wb25lbnQgZGVzdHJveTogY29tcG9uZW50IGlzIGFscmVhZHkgZGVzdHJveWVkJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmUoZmFsc2UsIHF1aWV0KTtcbiAgICB0aGlzLmFsbEZhY2V0cygnZGVzdHJveScpO1xuICAgIHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXS5kZXN0cm95KCk7XG4gICAgaWYgKHRoaXMuZWwpIHtcbiAgICAgICAgZG9tVXRpbHMuZGV0YWNoQ29tcG9uZW50KHRoaXMuZWwpO1xuICAgICAgICBkb21VdGlscy5yZW1vdmVFbGVtZW50KHRoaXMuZWwpO1xuICAgICAgICBkZWxldGUgdGhpcy5lbDtcbiAgICB9XG4gICAgdGhpcy5jb21wb25lbnRJbmZvLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIGNvbXBvbmVudCB3YXMgZGVzdHJveWVkXG4gKlxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGlzRGVzdHJveWVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZXN0cm95ZWQ7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogYG1pbG8uQ29tcG9uZW50LkZhY2V0YFxuICpcbiAqIFRoZSBjbGFzcyBmb3QgdGhlIGZhY2V0IG9mIGNvbXBvbmVudC4gV2hlbiBhIGNvbXBvbmVudCBpcyBjcmVhdGVkLCBpdFxuICogY3JlYXRlcyBhbGwgaXRzIGZhY2V0cy5cbiAqXG4gKiBTZWUgRmFjZXRzIHNlY3Rpb24gb24gaW5mb3JtYXRpb24gYWJvdXQgYXZhaWxhYmxlIGZhY2V0cyBhbmQgb25cbiAqIGhvdyB0byBjcmVhdGUgbmV3IGZhY2V0cyBjbGFzc2VzLlxuICpcbiAqIC0gQ29tcG9uZW50IC0gYmFzaWMgY29tcHBvbmVudCBjbGFzc1xuICogLSBDb21wb25lbnRGYWNldCAtIGJhc2ljXG4gKi9cblxudmFyIEZhY2V0ID0gcmVxdWlyZSgnLi4vYWJzdHJhY3QvZmFjZXQnKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJylcbiAgICAsIEZhY2V0RXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuRmFjZXRcbiAgICAsIGNvbXBvbmVudFV0aWxzID0gcmVxdWlyZSgnLi9jX3V0aWxzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxudmFyIENvbXBvbmVudEZhY2V0ID0gXy5jcmVhdGVTdWJjbGFzcyhGYWNldCwgJ0NvbXBvbmVudEZhY2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50RmFjZXQ7XG5cblxuLyoqXG4gKiBwb3N0RG9tUGFyZW50XG4gKlxuICogSWYgZmFjZXQgaGFzIERPTSBwYXJlbnQgZmFjZXQgKHNlZSBgZG9tUGFyZW50YCBtZXRob2QpLCBwb3N0cyB0aGUgbWVzc2FnZSB0byB0aGlzIGZhY2V0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlVHlwZVxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2VEYXRhXG4gKi9cbnZhciBwb3N0RG9tUGFyZW50ID0gXy5wYXJ0aWFsKF9wb3N0UGFyZW50LCBkb21QYXJlbnQpO1xuXG4vKipcbiAqIHBvc3RTY29wZVBhcmVudFxuICpcbiAqIElmIGZhY2V0IGhhcyBzY29wZSBwYXJlbnQgZmFjZXQgKHNlZSBgc2NvcGVQYXJlbnRgIG1ldGhvZCksIHBvc3RzIHRoZSBtZXNzYWdlIHRvIHRoaXMgZmFjZXQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VUeXBlXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZURhdGFcbiAqL1xudmFyIHBvc3RTY29wZVBhcmVudCA9IF8ucGFydGlhbChfcG9zdFBhcmVudCwgc2NvcGVQYXJlbnQpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oQ29tcG9uZW50RmFjZXQsIHtcbiAgICBpbml0OiBDb21wb25lbnRGYWNldCRpbml0LFxuICAgIHN0YXJ0OiBDb21wb25lbnRGYWNldCRzdGFydCxcbiAgICBjaGVjazogQ29tcG9uZW50RmFjZXQkY2hlY2ssXG4gICAgZGVzdHJveTogQ29tcG9uZW50RmFjZXQkZGVzdHJveSxcbiAgICBvbkNvbmZpZ01lc3NhZ2VzOiBDb21wb25lbnRGYWNldCRvbkNvbmZpZ01lc3NhZ2VzLFxuICAgIGRvbVBhcmVudDogZG9tUGFyZW50LFxuICAgIHBvc3REb21QYXJlbnQ6IHBvc3REb21QYXJlbnQsXG4gICAgc2NvcGVQYXJlbnQ6IHNjb3BlUGFyZW50LFxuICAgIHBvc3RTY29wZVBhcmVudDogcG9zdFNjb3BlUGFyZW50LFxuICAgIGdldE1lc3NhZ2VTb3VyY2U6IGdldE1lc3NhZ2VTb3VyY2UsXG4gICAgZGlzcGF0Y2hTb3VyY2VNZXNzYWdlOiBkaXNwYXRjaFNvdXJjZU1lc3NhZ2UsXG4gICAgX2NyZWF0ZU1lc3NlbmdlcjogX2NyZWF0ZU1lc3NlbmdlcixcbiAgICBfc2V0TWVzc2FnZVNvdXJjZTogX3NldE1lc3NhZ2VTb3VyY2UsXG4gICAgX2NyZWF0ZU1lc3NhZ2VTb3VyY2U6IF9jcmVhdGVNZXNzYWdlU291cmNlLFxuICAgIF9jcmVhdGVNZXNzYWdlU291cmNlV2l0aEFQSTogX2NyZWF0ZU1lc3NhZ2VTb3VyY2VXaXRoQVBJXG59KTtcblxuXy5leHRlbmQoQ29tcG9uZW50RmFjZXQsIHtcbiAgICByZXF1aXJlc0ZhY2V0OiByZXF1aXJlc0ZhY2V0XG59KTtcblxuXG4vKipcbiAqIEV4cG9zZSBNZXNzZW5nZXIgbWV0aG9kcyBvbiBGYWNldCBwcm90b3R5cGVcbiAqL1xudmFyIE1FU1NFTkdFUl9QUk9QRVJUWSA9ICdfbWVzc2VuZ2VyJztcbk1lc3Nlbmdlci51c2VXaXRoKENvbXBvbmVudEZhY2V0LCBNRVNTRU5HRVJfUFJPUEVSVFksIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG5cblxuLy8gaW5pdENvbXBvbmVudEZhY2V0XG5mdW5jdGlvbiBDb21wb25lbnRGYWNldCRpbml0KCkge1xuICAgIHRoaXMuX2NyZWF0ZU1lc3NlbmdlcigpO1xufVxuXG5cbi8vIHNvbWUgc3ViY2xhc3NlcyAoZS5nLiBNb2RlbEZhY2V0KSBvdmVycnJpZGUgdGhpcyBtZXRob2QgYW5kIGRvIG5vdCBjcmVhdGUgdGhlaXIgb3duIG1lc3NlbmdlclxuZnVuY3Rpb24gX2NyZWF0ZU1lc3Nlbmdlcigpe1xuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgTUVTU0VOR0VSX1BST1BFUlRZLCBuZXcgTWVzc2VuZ2VyKHRoaXMpKTtcbn1cblxuXG4vLyBzdGFydENvbXBvbmVudEZhY2V0XG5mdW5jdGlvbiBDb21wb25lbnRGYWNldCRzdGFydCgpIHtcbiAgICBpZiAodGhpcy5jb25maWcubWVzc2FnZXMpXG4gICAgICAgIHRoaXMub25Db25maWdNZXNzYWdlcyh0aGlzLmNvbmZpZy5tZXNzYWdlcyk7XG59XG5cblxuZnVuY3Rpb24gQ29tcG9uZW50RmFjZXQkb25Db25maWdNZXNzYWdlcyhtZXNzYWdlU3Vic2NyaWJlcnMpIHtcbiAgICB2YXIgbm90WWV0UmVnaXN0ZXJlZE1hcCA9IF8ubWFwS2V5cyhtZXNzYWdlU3Vic2NyaWJlcnMsIGZ1bmN0aW9uKHN1YnNjcmliZXIsIG1lc3NhZ2VzKSB7XG4gICAgICAgIHZhciBzdWJzY3JpYmVyVHlwZSA9IHR5cGVvZiBzdWJzY3JpYmVyO1xuICAgICAgICBpZiAoc3Vic2NyaWJlclR5cGUgPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9uKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcblxuICAgICAgICBpZiAoc3Vic2NyaWJlclR5cGUgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHZhciBjb250ZXh0VHlwZSA9IHR5cGVvZiBzdWJzY3JpYmVyLmNvbnRleHQ7XG4gICAgICAgICAgICBpZiAoY29udGV4dFR5cGUgPT0gJ29iamVjdCcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMub24obWVzc2FnZXMsIHN1YnNjcmliZXIpO1xuXG4gICAgICAgICAgICBpZiAoY29udGV4dFR5cGUgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3Vic2NyaWJlci5jb250ZXh0ID09IHRoaXMubmFtZSB8fCBzdWJzY3JpYmVyLmNvbnRleHQgPT0gJ2ZhY2V0JylcbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXI6IHN1YnNjcmliZXIuc3Vic2NyaWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXNcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzdWJzY3JpYmVyLmNvbnRleHQgPT0gJ293bmVyJylcbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlciA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXI6IHN1YnNjcmliZXIuc3Vic2NyaWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMub3duZXJcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBGYWNldEVycm9yKCd1bmtub3duIHN1YnNjcmliZXIgY29udGV4dCBpbiBjb25maWd1cmF0aW9uOiAnICsgc3Vic2NyaWJlci5jb250ZXh0KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9uKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEZhY2V0RXJyb3IoJ3Vua25vd24gc3Vic2NyaWJlciBjb250ZXh0IHR5cGUgaW4gY29uZmlndXJhdGlvbjogJyArIGNvbnRleHRUeXBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBGYWNldEVycm9yKCd1bmtub3duIHN1YnNjcmliZXIgdHlwZSBpbiBjb25maWd1cmF0aW9uOiAnICsgc3Vic2NyaWJlclR5cGUpO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIG5vdFlldFJlZ2lzdGVyZWRNYXA7XG59XG5cblxuLy8gY2hlY2tEZXBlbmRlbmNpZXNcbmZ1bmN0aW9uIENvbXBvbmVudEZhY2V0JGNoZWNrKCkge1xuICAgIGlmICh0aGlzLnJlcXVpcmUpIHtcbiAgICAgICAgdGhpcy5yZXF1aXJlLmZvckVhY2goZnVuY3Rpb24ocmVxRmFjZXQpIHtcbiAgICAgICAgICAgIGlmICghIHRoaXMub3duZXIuaGFzRmFjZXQocmVxRmFjZXQpKVxuICAgICAgICAgICAgICAgIHRoaXMub3duZXIuYWRkRmFjZXQocmVxRmFjZXQpO1xuICAgICAgICB9LCB0aGlzKTtcbiAgICB9XG59XG5cblxuLy8gZGVzdHJveXMgZmFjZXRcbmZ1bmN0aW9uIENvbXBvbmVudEZhY2V0JGRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXSkgdGhpc1tNRVNTRU5HRVJfUFJPUEVSVFldLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xufVxuXG5cbi8qKlxuICogZG9tUGFyZW50XG4gKlxuICogQHJldHVybiB7Q29tcG9uZW50RmFjZXR9IHJlZmVyZW5jZSB0byB0aGUgZmFjZXQgb2YgdGhlIHNhbWUgY2xhc3Mgb2YgdGhlIGNsb3Nlc3QgcGFyZW50IERPTSBlbGVtZW50LCB0aGF0IGhhcyBhIGNvbXBvbmVudCB3aXRoIHRoZSBzYW1lIGZhY2V0IGNsYXNzIGF0dGFjaGVkIHRvIGl0LiBJZiBzdWNoIGVsZW1lbnQgZG9lc24ndCBleGlzdCBtZXRob2Qgd2lsbCByZXR1cm4gdW5kZWZpbmVkLlxuICovXG5mdW5jdGlvbiBkb21QYXJlbnQoKSB7XG4gICAgdmFyIHBhcmVudENvbXBvbmVudCA9IGNvbXBvbmVudFV0aWxzLmdldENvbnRhaW5pbmdDb21wb25lbnQodGhpcy5vd25lci5lbCwgZmFsc2UsIHRoaXMubmFtZSk7XG4gICAgcmV0dXJuIHBhcmVudENvbXBvbmVudCAmJiBwYXJlbnRDb21wb25lbnRbdGhpcy5uYW1lXTtcbn1cblxuXG4vKipcbiAqIHNjb3BlUGFyZW50XG4gKlxuICogQHJldHVybiB7Q29tcG9uZW50RmFjZXR9IHJlZmVyZW5jZSB0byB0aGUgZmFjZXQgb2YgdGhlIHNhbWUgY2xhc3MgYXMgYHRoaXNgIGZhY2V0IG9mIHRoZSBjbG9zZXN0IHNjb3BlIHBhcmVudCAoaS5lLiwgdGhlIGNvbXBvbmVudCB0aGF0IGhhcyB0aGUgc2NvcGUgb2YgdGhlIGN1cnJlbnQgY29tcG9uZW50IGluIGl0cyBjb250YWluZXIgZmFjZXQpLlxuICovXG5mdW5jdGlvbiBzY29wZVBhcmVudCgpIHtcbiAgICB2YXIgcGFyZW50Q29tcG9uZW50ID0gdGhpcy5vd25lci5nZXRTY29wZVBhcmVudCh0aGlzLm5hbWUpO1xuICAgIHJldHVybiBwYXJlbnRDb21wb25lbnQgJiYgcGFyZW50Q29tcG9uZW50W3RoaXMubmFtZV07XG59XG5cblxuZnVuY3Rpb24gX3Bvc3RQYXJlbnQoZ2V0UGFyZW50TWV0aG9kLCBtZXNzYWdlVHlwZSwgbWVzc2FnZURhdGEpIHtcbiAgICB2YXIgcGFyZW50RmFjZXQgPSBnZXRQYXJlbnRNZXRob2QuY2FsbCh0aGlzKTtcbiAgICBpZiAocGFyZW50RmFjZXQpXG4gICAgICAgIHBhcmVudEZhY2V0LnBvc3RNZXNzYWdlKG1lc3NhZ2VUeXBlLCBtZXNzYWdlRGF0YSk7XG59XG5cblxuZnVuY3Rpb24gX3NldE1lc3NhZ2VTb3VyY2UobWVzc2FnZVNvdXJjZSkge1xuICAgIHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXS5fc2V0TWVzc2FnZVNvdXJjZShtZXNzYWdlU291cmNlKTtcbn1cblxuXG5mdW5jdGlvbiBnZXRNZXNzYWdlU291cmNlKCkge1xuICAgIHJldHVybiB0aGlzW01FU1NFTkdFUl9QUk9QRVJUWV0uZ2V0TWVzc2FnZVNvdXJjZSgpO1xufVxuXG5cbmZ1bmN0aW9uIGRpc3BhdGNoU291cmNlTWVzc2FnZShtZXNzYWdlLCBkYXRhKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZVNvdXJjZSgpLmRpc3BhdGNoTWVzc2FnZShtZXNzYWdlLCBkYXRhKTtcbn1cblxuXG5mdW5jdGlvbiBfY3JlYXRlTWVzc2FnZVNvdXJjZShNZXNzYWdlU291cmNlQ2xhc3MsIG9wdGlvbnMpIHtcbiAgICB2YXIgbWVzc2FnZVNvdXJjZSA9IG5ldyBNZXNzYWdlU291cmNlQ2xhc3ModGhpcywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMub3duZXIsIG9wdGlvbnMpO1xuICAgIHRoaXMuX3NldE1lc3NhZ2VTb3VyY2UobWVzc2FnZVNvdXJjZSlcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19tZXNzYWdlU291cmNlJywgbWVzc2FnZVNvdXJjZSk7XG59XG5cblxuZnVuY3Rpb24gX2NyZWF0ZU1lc3NhZ2VTb3VyY2VXaXRoQVBJKE1lc3NhZ2VTb3VyY2VDbGFzcywgbWVzc2VuZ2VyQVBJT3JDbGFzcywgb3B0aW9ucykge1xuICAgIHZhciBtZXNzYWdlU291cmNlID0gbmV3IE1lc3NhZ2VTb3VyY2VDbGFzcyh0aGlzLCB1bmRlZmluZWQsIG1lc3NlbmdlckFQSU9yQ2xhc3MsIHRoaXMub3duZXIsIG9wdGlvbnMpO1xuICAgIHRoaXMuX3NldE1lc3NhZ2VTb3VyY2UobWVzc2FnZVNvdXJjZSlcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19tZXNzYWdlU291cmNlJywgbWVzc2FnZVNvdXJjZSk7XG59XG5cblxuZnVuY3Rpb24gcmVxdWlyZXNGYWNldChmYWNldE5hbWUpIHtcbiAgICAvLyAndGhpcycgcmVmZXJzIHRvIHRoZSBGYWNldCBDbGFzc1xuICAgIHZhciBmYWNldFJlcXVpcmUgPSB0aGlzLnByb3RvdHlwZS5yZXF1aXJlO1xuXG4gICAgcmV0dXJuIGZhY2V0UmVxdWlyZSAmJiAoZmFjZXRSZXF1aXJlLmluZGV4T2YoXy5maXJzdFVwcGVyQ2FzZShmYWNldE5hbWUpKSA+PSAwXG4gICAgICAgICAgICAgICAgICAgICAgICB8fCBmYWNldFJlcXVpcmUuaW5kZXhPZihfLmZpcnN0TG93ZXJDYXNlKGZhY2V0TmFtZSkpID49IDApO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgbWlsb0JpbmRlciA9IHJlcXVpcmUoJy4uLy4uL2JpbmRlcicpXG4gICAgLCBTY29wZSA9IHJlcXVpcmUoJy4uL3Njb3BlJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcbiAgICAsIGRvbVV0aWxzID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9kb20nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKTtcblxuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0NvbnRhaW5lcicpYFxuICogQSBzcGVjaWFsIGNvbXBvbmVudCBmYWNldCB0aGF0IG1ha2VzIGNvbXBvbmVudCBjcmVhdGUgaXRzIG93biBpbm5lciBzY29wZS5cbiAqIFdoZW4gW21pbG8uYmluZGVyXSguLi8uLi9iaW5kZXIuanMuaHRtbCkgYmluZHMgRE9NIHRyZWUgYW5kIGNyZWF0ZXMgY29tcG9uZW50cywgaWYgY29tcG9uZW50cyBhcmUgaW5zaWRlIGNvbXBvbmVudCBXSVRIIENvbnRhaW5lciBmYWNldCwgdGhleSBhcmUgcHV0IG9uIHRoZSBgc2NvcGVgIG9mIGl0IChjb21wb25lbnQuY29udGFpbmVyLnNjb3BlIC0gc2VlIFtTY29wZV0oLi4vc2NvcGUuanMuaHRtbCkpLCBvdGhlcndpc2UgdGhleSBhcmUgcHV0IG9uIHRoZSBzYW1lIHNjb3BlIGV2ZW4gdGhvdWdoIHRoZXkgbWF5IGJlIGRlZXBlciBpbiBET00gdHJlZS5cbiAqIEl0IGFsbG93cyBjcmVhdGluZyBuYW1lc3BhY2VzIGF2b2lkaW5nIGNvbXBvbmVudHMgbmFtZXMgY29uZmxpY3RzLCBhdCB0aGUgc2FtZSB0aW1lIGNyZWF0aW5nIG1vcmUgc2hhbGxvdyBjb21wb25lbnRzIHRyZWUgdGhhbiB0aGUgRE9NIHRyZWUuXG4gKiBUbyBjcmVhdGUgY29tcG9uZW50cyBmb3IgZWxlbWVudHMgaW5zaWRlIHRoZSBjdXJyZW50IGNvbXBvbmVudCB1c2U6XG4gKiBgYGBcbiAqIGNvbXBvbmVudC5jb250YWluZXIuYmluZGVyKCk7XG4gKiBgYGBcbiAqIFNlZSBbbWlsby5iaW5kZXJdKC4uLy4uL2JpbmRlci5qcy5odG1sKVxuICovXG52YXIgQ29udGFpbmVyID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0NvbnRhaW5lcicpO1xuXG5cbi8qKlxuICogIyMjI0NvbnRhaW5lciBmYWNldCBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2JpbmRlcl0oI0NvbnRhaW5lciRiaW5kZXIpIC0gY3JlYXRlIGNvbXBvbmVudHMgZnJvbSBET00gaW5zaWRlIHRoZSBjdXJyZW50IG9uZVxuICovXG5fLmV4dGVuZFByb3RvKENvbnRhaW5lciwge1xuICAgIHN0YXJ0OiBDb250YWluZXIkc3RhcnQsXG4gICAgcGF0aDogQ29udGFpbmVyJHBhdGgsXG4gICAgZ2V0U3RhdGU6IENvbnRhaW5lciRnZXRTdGF0ZSxcbiAgICBzZXRTdGF0ZTogQ29udGFpbmVyJHNldFN0YXRlLFxuICAgIGJpbmRlcjogQ29udGFpbmVyJGJpbmRlcixcbiAgICBkZXN0cm95OiBDb250YWluZXIkZGVzdHJveSxcbiAgICB1bndyYXA6IENvbnRhaW5lciR1bndyYXAsXG5cbiAgICBhcHBlbmQ6IENvbnRhaW5lciRhcHBlbmQsXG4gICAgaW5zZXJ0QmVmb3JlOiBDb250YWluZXIkaW5zZXJ0QmVmb3JlLFxuICAgIHJlbW92ZTogQ29udGFpbmVyJHJlbW92ZVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChDb250YWluZXIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENvbnRhaW5lcjtcblxuXG4vKipcbiAqIENvbnRhaW5lciBpbnN0YW5jZSBtZXRob2QuXG4gKiBTY2FucyBET00sIGNyZWF0ZXMgY29tcG9uZW50cyBhbmQgYWRkcyB0byBzY29wZSBjaGlsZHJlbiBvZiBjb21wb25lbnQgZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gQ29udGFpbmVyJGJpbmRlcigpIHtcbiAgICByZXR1cm4gbWlsb0JpbmRlcih0aGlzLm93bmVyLmVsLCB0aGlzLnNjb3BlLCBmYWxzZSk7XG59XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogU2V0dXAgZW1wdHkgc2NvcGUgb2JqZWN0IG9uIHN0YXJ0XG4gKi9cbmZ1bmN0aW9uIENvbnRhaW5lciRzdGFydCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuc3RhcnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLnNjb3BlID0gbmV3IFNjb3BlKHRoaXMub3duZXIuZWwsIHRoaXMpO1xufVxuXG5cbnZhciBhbGxvd2VkTmFtZVBhdHRlcm4gPSAvXltBLVphLXpdW0EtWmEtejAtOVxcX1xcJF0qJC87XG4vKipcbiAqIENvbnRhaW5lciBpbnN0YW5jZSBtZXRob2QuXG4gKiBTYWZlbHkgdHJhdmVyc2VzIGNvbXBvbmVudCBzY29wZVxuICogUmV0dXJucyBjb21wb25lbnQgaW4gc2NvcGUgZm9yIGEgZ2l2ZW4gcGF0aFxuICogSWYgcGF0aCBpcyBpbnZhbGlkIHRoZSBtZXRob2Qgd2lsbCB0aHJvdywgaWYgdGhlcmUgaXMgbm8gY29tcG9uZW50IGF0IGEgZ2l2ZW4gcGF0aCBvciBzb21lIG9mIHRoZSBjb21wb25lbnRzIGFsb25nIHRoZSBwYXRoIGRvZXMgbm90IGhhdmUgQ29udGFpbmVyIGZhY2V0IHRoZSBtZXRob2Qgd2lsbCByZXR1cm4gdW5kZWZpbmVkLCBcbiAqIFxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGggcGF0aCBvZiBjaGlsZCBjb21wb25lbnQgaW4gc2NvcGUsIGVhY2ggbmFtZSBzaG91bGQgYmUgcHJlZml4ZWQgd2l0aCAnLicsIGUuZy46ICcuY2hpbGQuc3ViY2hpbGQnXG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbmZ1bmN0aW9uIENvbnRhaW5lciRwYXRoKHBhdGgpIHtcbiAgICBwYXRoID0gcGF0aC5zcGxpdCgnLicpO1xuICAgIHZhciBsZW4gPSBwYXRoLmxlbmd0aDtcbiAgICBpZiAocGF0aFswXSB8fCBsZW4gPCAyKSB0aHJvd0ludmFsaWRQYXRoKCk7XG4gICAgdmFyIGNvbXAgPSB0aGlzLm93bmVyO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG5hbWUgPSBwYXRoW2ldO1xuICAgICAgICBpZiAoIWFsbG93ZWROYW1lUGF0dGVybi50ZXN0KG5hbWUpKSB0aHJvd0ludmFsaWRQYXRoKCk7XG4gICAgICAgIGlmICghY29tcC5jb250YWluZXIpIHJldHVybjtcbiAgICAgICAgY29tcCA9IGNvbXAuY29udGFpbmVyLnNjb3BlW25hbWVdO1xuICAgICAgICBpZiAoIWNvbXApIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIGNvbXA7XG5cbiAgICBmdW5jdGlvbiB0aHJvd0ludmFsaWRQYXRoKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhdGggJyArIHBhdGggKyAnIGlzIGludmFsaWQnKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBDYWxsZWQgYnkgYENvbXBvbmVudC5wcm90b3R5cGUuZ2V0U3RhdGVgIHRvIGdldCBmYWNldCdzIHN0YXRlXG4gKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiBjb21wb25lbnRzIGluIHRoZSBzY29wZVxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVlcENvcHkgdHJ1ZSBieSBkZWZhdWx0XG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIENvbnRhaW5lciRnZXRTdGF0ZShkZWVwQ29weSkge1xuICAgIHZhciBzdGF0ZSA9IHsgc2NvcGU6IHt9IH07XG4gICAgaWYgKGRlZXBDb3B5ICE9PSBmYWxzZSlcbiAgICAgICAgdGhpcy5zY29wZS5fZWFjaChmdW5jdGlvbihjb21wb25lbnQsIGNvbXBOYW1lKSB7XG4gICAgICAgICAgICBzdGF0ZS5zY29wZVtjb21wTmFtZV0gPSBjb21wb25lbnQuX2dldFN0YXRlKCk7XG4gICAgICAgIH0pO1xuICAgIHJldHVybiBzdGF0ZTtcbn1cblxuXG4vKipcbiAqIENvbnRhaW5lciBpbnN0YW5jZSBtZXRob2RcbiAqIENhbGxlZCBieSBgQ29tcG9uZW50LnByb3RvdHlwZS5zZXRTdGF0ZWAgdG8gc2V0IGZhY2V0J3Mgc3RhdGVcbiAqIFNldHMgdGhlIHN0YXRlIG9mIGNvbXBvbmVudHMgaW4gdGhlIHNjb3BlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgZGF0YSB0byBzZXQgb24gZmFjZXQncyBtb2RlbFxuICovXG5mdW5jdGlvbiBDb250YWluZXIkc2V0U3RhdGUoc3RhdGUpIHtcbiAgICBfLmVhY2hLZXkoc3RhdGUuc2NvcGUsIGZ1bmN0aW9uKGNvbXBEYXRhLCBjb21wTmFtZSkge1xuICAgICAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5zY29wZVtjb21wTmFtZV07XG4gICAgICAgIGlmIChjb21wb25lbnQpXG4gICAgICAgICAgICBjb21wb25lbnQuc2V0U3RhdGUoY29tcERhdGEpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBsb2dnZXIud2FybignY29tcG9uZW50IFwiJyArIGNvbXBOYW1lICsgJ1wiIGRvZXMgbm90IGV4aXN0IG9uIHNjb3BlJyk7XG4gICAgfSwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIENvbnRhaW5lciRkZXN0cm95KCkge1xuICAgIHRoaXMuc2NvcGUuX2VhY2goZnVuY3Rpb24oY29tcG9uZW50KSB7XG4gICAgICAgIGNvbXBvbmVudC5kZXN0cm95KCk7XG4gICAgfSk7XG4gICAgdGhpcy5zY29wZS5fZGV0YWNoRWxlbWVudCgpO1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBNb3ZlcyBhbGwgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBvd25lciBpbnRvIHRoZSBwYXJlbnQgc2NvcGVcbiAqIFxuICogQHBhcmFtIHtCb29sZWFufSByZW5hbWVDaGlsZHJlbiBwYXNzIGZhbHNlIHRvIG5vdCByZW5hbWUgc2NvcGUgY2hpbGRyZW4gKGRlZmF1bHQgaXMgdHJ1ZSlcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVzdHJveSBJZiBub3QgZmFsc2UsIHRoZSBjb21wb25lbnQgd2lsbCBiZSBkZXN0cm95ZWQgYXQgdGhlIGVuZCAoZGVmYXVsdCBpcyB0cnVlKS5cbiAqL1xuZnVuY3Rpb24gQ29udGFpbmVyJHVud3JhcChyZW5hbWVDaGlsZHJlbiwgZGVzdHJveSkge1xuICAgIGRvbVV0aWxzLnVud3JhcEVsZW1lbnQodGhpcy5vd25lci5lbCk7XG4gICAgdGhpcy5zY29wZSAmJiB0aGlzLnNjb3BlLl9lYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICBjaGlsZC5yZW1vdmUoKTtcbiAgICAgICAgaWYgKHJlbmFtZUNoaWxkcmVuICE9PSBmYWxzZSkgY2hpbGQucmVuYW1lKHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgICAgICB0aGlzLm93bmVyLnNjb3BlICYmIHRoaXMub3duZXIuc2NvcGUuX2FkZChjaGlsZCk7XG4gICAgfSwgdGhpcyk7XG4gICAgaWYgKGRlc3Ryb3kgIT09IGZhbHNlKSB0aGlzLm93bmVyLmRlc3Ryb3koKTtcbn1cblxuXG4vKipcbiAqIENvbnRhaW5lciBpbnN0YW5jZSBtZXRob2RcbiAqIEFwcGVuZCBjb21wb25lbnQgdG8gRE9NIGFuZCB0byBzY29wZVxuICogQHBhcmFtIHtDb21wb25lbnR9IGNvbXAgY29tcG9uZW50IHRoYXQgd2lsbCBiZSBhcHBlbmRlZFxuICovXG5mdW5jdGlvbiBDb250YWluZXIkYXBwZW5kKGNvbXApIHtcbiAgICB0aGlzLnNjb3BlLl9hZGQoY29tcCk7XG4gICAgdGhpcy5vd25lci5lbC5hcHBlbmRDaGlsZChjb21wLmVsKTtcbn1cblxuXG4vKipcbiAqIENvbnRhaW5lciBpbnN0YW5jZSBtZXRob2RcbiAqIEluc2VydCBjb21wb25lbnQgdG8gRE9NIGFuZCB0byBzY29wZSBiZWZvcmUgYW5vdGhlciBjb21wb25lbnRcbiAqIEBwYXJhbSB7Q29tcG9uZW50fSBjb21wIGNvbXBvbmVudCB0aGF0IHdpbGwgYmUgaW5zZXJ0ZWRcbiAqIEBwYXJhbSB7Q29tcG9uZW50fSBzaWJsaW5nIGNvbXBvbmVudCBiZWZvcmUgd2hpY2ggY29tcG9uZW50IHdpbGwgYmUgYXBwZW5kZWRcbiAqL1xuZnVuY3Rpb24gQ29udGFpbmVyJGluc2VydEJlZm9yZShjb21wLCBzaWJsaW5nKSB7XG4gICAgdGhpcy5zY29wZS5fYWRkKGNvbXApO1xuICAgIHRoaXMuZWwuaW5zZXJ0QmVmb3JlKGNvbXAuZWwsIHNpYmxpbmcgJiYgc2libGluZy5lbCk7XG59XG5cbmZ1bmN0aW9uIENvbnRhaW5lciRyZW1vdmUoY29tcCkge1xuICAgIHRoaXMuc2NvcGUuX3JlbW92ZShjb21wKTtcbiAgICB0aGlzLm93bmVyLmVsLnJlbW92ZUNoaWxkKGNvbXAuZWwpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTWl4aW4gPSByZXF1aXJlKCcuLi8uLi9hYnN0cmFjdC9taXhpbicpXG4gICAgLCBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcblxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyJylcbiAgICAsIERPTUV2ZW50c1NvdXJjZSA9IHJlcXVpcmUoJy4uL21zZ19zcmMvZG9tX2V2ZW50cycpXG4gICAgLCBEYXRhTXNnQVBJID0gcmVxdWlyZSgnLi4vbXNnX2FwaS9kYXRhJylcbiAgICAsIGdldEVsZW1lbnREYXRhQWNjZXNzID0gcmVxdWlyZSgnLi4vbXNnX2FwaS9kZV9kYXRhJylcbiAgICAsIHBhdGhVdGlscyA9IHJlcXVpcmUoJy4uLy4uL21vZGVsL3BhdGhfdXRpbHMnKVxuICAgICwgTW9kZWxQYXRoID0gcmVxdWlyZSgnLi4vLi4vbW9kZWwvbV9wYXRoJylcbiAgICAsIG1vZGVsVXRpbHMgPSByZXF1aXJlKCcuLi8uLi9tb2RlbC9tb2RlbF91dGlscycpXG4gICAgLCBjaGFuZ2VEYXRhSGFuZGxlciA9IHJlcXVpcmUoJy4uLy4uL21vZGVsL2NoYW5nZV9kYXRhJylcbiAgICAsIGdldFRyYW5zYWN0aW9uRmxhZyA9IGNoYW5nZURhdGFIYW5kbGVyLmdldFRyYW5zYWN0aW9uRmxhZ1xuICAgICwgc2V0VHJhbnNhY3Rpb25GbGFnID0gY2hhbmdlRGF0YUhhbmRsZXIuc2V0VHJhbnNhY3Rpb25GbGFnXG4gICAgLCBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZCA9IGNoYW5nZURhdGFIYW5kbGVyLnBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkXG5cbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKTtcblxuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0RhdGEnKWBcbiAqIEZhY2V0IHRvIGdpdmUgYWNjZXNzIHRvIERPTSBkYXRhXG4gKi9cbnZhciBEYXRhID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0RhdGEnKTtcblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kc1xuICpcbiAqIC0gW3N0YXJ0XSgjRGF0YSRzdGFydCkgLSBzdGFydCBEYXRhIGZhY2V0XG4gKiAtIFtnZXRdKCNEYXRhJGdldCkgLSBnZXQgRE9NIGRhdGEgZnJvbSBET00gdHJlZVxuICogLSBbc2V0XSgjRGF0YSRzZXQpIC0gc2V0IERPTSBkYXRhIHRvIERPTSB0cmVlXG4gKiAtIFtwYXRoXSgjRGF0YSRwYXRoKSAtIGdldCByZWZlcmVuY2UgdG8gRGF0YSBmYWNldCBieSBwYXRoXG4gKi9cbl8uZXh0ZW5kUHJvdG8oRGF0YSwge1xuICAgIHN0YXJ0OiBEYXRhJHN0YXJ0LFxuICAgIGdldFN0YXRlOiBEYXRhJGdldFN0YXRlLFxuICAgIHNldFN0YXRlOiBEYXRhJHNldFN0YXRlLFxuXG4gICAgZ2V0OiBEYXRhJGdldCxcbiAgICBzZXQ6IERhdGEkc2V0LFxuICAgIGRlbDogRGF0YSRkZWwsXG4gICAgc3BsaWNlOiBEYXRhJHNwbGljZSxcbiAgICBsZW46IERhdGEkbGVuLFxuICAgIHBhdGg6IERhdGEkcGF0aCxcbiAgICBnZXRQYXRoOiBEYXRhJGdldFBhdGgsXG4gICAgZ2V0S2V5OiBEYXRhJGdldEtleSxcblxuICAgIF9nZXQ6IERhdGEkX2dldCxcbiAgICBfc2V0OiBEYXRhJF9zZXQsXG4gICAgX2RlbDogRGF0YSRfZGVsLFxuICAgIF9zcGxpY2U6IERhdGEkX3NwbGljZSxcbiAgICBfbGVuOiBEYXRhJF9sZW4sXG5cbiAgICBfc2V0U2NhbGFyVmFsdWU6IERhdGEkX3NldFNjYWxhclZhbHVlLFxuICAgIF9nZXRTY2FsYXJWYWx1ZTogRGF0YSRfZ2V0U2NhbGFyVmFsdWUsXG4gICAgX2J1YmJsZVVwRGF0YUNoYW5nZTogRGF0YSRfYnViYmxlVXBEYXRhQ2hhbmdlLFxuICAgIF9xdWV1ZURhdGFDaGFuZ2U6IERhdGEkX3F1ZXVlRGF0YUNoYW5nZSxcbiAgICBfcG9zdERhdGFDaGFuZ2VzOiBEYXRhJF9wb3N0RGF0YUNoYW5nZXMsXG4gICAgX3ByZXBhcmVNZXNzYWdlU291cmNlOiBfcHJlcGFyZU1lc3NhZ2VTb3VyY2Vcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoRGF0YSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGF0YTtcblxuXG4vKipcbiAqIE1vZGVsUGF0aCBtZXRob2RzIGFkZGVkIHRvIERhdGEgcHJvdG90eXBlXG4gKi9cblsncHVzaCcsICdwb3AnLCAndW5zaGlmdCcsICdzaGlmdCddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBNb2RlbFBhdGgucHJvdG90eXBlW21ldGhvZE5hbWVdO1xuICAgIF8uZGVmaW5lUHJvcGVydHkoRGF0YS5wcm90b3R5cGUsIG1ldGhvZE5hbWUsIG1ldGhvZCk7XG59KTtcblxuXG5cbi8vIHRoZXNlIG1ldGhvZHMgd2lsbCBiZSB3cmFwcGVkIHRvIHN1cHBvcnQgXCIqXCIgcGF0dGVybiBzdWJzY3JpcHRpb25zXG52YXIgcHJveHlEYXRhU291cmNlTWV0aG9kcyA9IHtcbiAgICAgICAgLy8gdmFsdWU6ICd2YWx1ZScsXG4gICAgICAgIHRyaWdnZXI6ICd0cmlnZ2VyJ1xuICAgIH07XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU3RhcnRzIERhdGEgZmFjZXRcbiAqIENhbGxlZCBieSBjb21wb25lbnQgYWZ0ZXIgY29tcG9uZW50IGlzIGluaXRpYWxpemVkLlxuICovXG5mdW5jdGlvbiBEYXRhJHN0YXJ0KCkge1xuICAgIC8vIGNoYW5nZSBtZXNzZW5nZXIgbWV0aG9kcyB0byB3b3JrIHdpdGggXCIqXCIgc3Vic2NyaXB0aW9ucyAobGlrZSBNb2RlbCBjbGFzcylcbiAgICBwYXRoVXRpbHMud3JhcE1lc3Nlbmdlck1ldGhvZHMuY2FsbCh0aGlzKTtcblxuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5zdGFydC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLy8gZ2V0L3NldCBtZXRob2RzIHRvIHNldCBkYXRhIG9mIGVsZW1lbnRcbiAgICB0aGlzLmVsRGF0YSA9IGdldEVsZW1lbnREYXRhQWNjZXNzKHRoaXMub3duZXIuZWwpO1xuXG4gICAgdGhpcy5fZGF0YUNoYW5nZXNRdWV1ZSA9IFtdO1xuXG4gICAgdGhpcy5fcHJlcGFyZU1lc3NhZ2VTb3VyY2UoKTtcblxuICAgIC8vIHN0b3JlIGZhY2V0IGRhdGEgcGF0aFxuICAgIHRoaXMuX3BhdGggPSAnLicgKyB0aGlzLm93bmVyLm5hbWU7XG5cbiAgICAvLyBjdXJyZW50IHZhbHVlXG4gICAgdGhpcy5fdmFsdWUgPSB0aGlzLmdldCgpO1xuXG4gICAgLy8gcHJlcGFyZSBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgbWVzc2VuZ2Vyc1xuICAgIC8vIHRoaXMuX3ByZXBhcmVNZXNzZW5nZXJzKCk7XG5cbiAgICAvLyBzdWJzY3JpYmUgdG8gRE9NIGV2ZW50IGFuZCBhY2Nlc3NvcnMnIG1lc3NhZ2VzXG4gICAgdGhpcy5vblN5bmMoJycsIG9uT3duRGF0YUNoYW5nZSk7XG5cbiAgICAvLyBtZXNzYWdlIHRvIG1hcmsgdGhlIGVuZCBvZiBiYXRjaCBvbiB0aGUgY3VycmVudCBsZXZlbFxuICAgIHRoaXMub25TeW5jKCdkYXRhY2hhbmdlc2ZpbmlzaGVkJywgb25EYXRhQ2hhbmdlc0ZpbmlzaGVkKTtcblxuICAgIC8vIGNoYW5nZXMgaW4gc2NvcGUgY2hpbGRyZW4gd2l0aCBEYXRhIGZhY2V0XG4gICAgdGhpcy5vblN5bmMoJ2NoaWxkZGF0YScsIG9uQ2hpbGREYXRhKTtcblxuICAgIC8vIHRvIGVuYWJsZSByZWFjdGl2ZSBjb25uZWN0aW9uc1xuICAgIHRoaXMub25TeW5jKCdjaGFuZ2VkYXRhJywgY2hhbmdlRGF0YUhhbmRsZXIpO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIENyZWF0ZSBhbmQgY29ubmVjdCBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgbWVzc2VuZ2VycyBvZiBEYXRhIGZhY2V0LlxuICogRXh0ZXJuYWwgbWVzc2VuZ2VyJ3MgbWV0aG9kcyBhcmUgcHJveGllZCBvbiB0aGUgRGF0YSBmYWNldCBhbmQgdGhleSBhbGxvd3MgXCIqXCIgc3Vic2NyaXB0aW9ucy5cbiAqL1xuLy8gZnVuY3Rpb24gX3ByZXBhcmVNZXNzZW5nZXJzKCkge1xuICAgIC8vIERhdGEgZmFjZXQgd2lsbCBwb3N0IGFsbCBpdHMgY2hhbmdlcyBvbiBpbnRlcm5hbCBtZXNzZW5nZXJcbiAgICAvLyB2YXIgaW50ZXJuYWxNZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMpO1xuXG4gICAgLy8gbWVzc2FnZSBzb3VyY2UgdG8gY29ubmVjdCBpbnRlcm5hbCBtZXNzZW5nZXIgdG8gZXh0ZXJuYWxcbiAgICAvLyB2YXIgaW50ZXJuYWxNZXNzZW5nZXJTb3VyY2UgPSBuZXcgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSh0aGlzLCB1bmRlZmluZWQsIG5ldyBNb2RlbE1zZ0FQSSwgaW50ZXJuYWxNZXNzZW5nZXIpO1xuXG4gICAgLy8gZXh0ZXJuYWwgbWVzc2VuZ2VyIHRvIHdoaWNoIGFsbCBtb2RlbCB1c2VycyB3aWxsIHN1YnNjcmliZSxcbiAgICAvLyB0aGF0IHdpbGwgYWxsb3cgXCIqXCIgc3Vic2NyaXB0aW9ucyBhbmQgc3VwcG9ydCBcImNoYW5nZWRhdGFcIiBtZXNzYWdlIGFwaS5cbiAgICAvLyB2YXIgZXh0ZXJuYWxNZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMsIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcywgaW50ZXJuYWxNZXNzZW5nZXJTb3VyY2UpO1xuXG4vLyAgICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbi8vICAgICAgICAgX21lc3NlbmdlcjogZXh0ZXJuYWxNZXNzZW5nZXIsXG4vLyAgICAgICAgIF9pbnRlcm5hbE1lc3NlbmdlcjogaW50ZXJuYWxNZXNzZW5nZXJcbi8vICAgICB9KTtcbi8vIH1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplcyBET01FdmVudHNTb3VyY2UgYW5kIGNvbm5lY3RzIGl0IHRvIERhdGEgZmFjZXQgbWVzc2VuZ2VyXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gX3ByZXBhcmVNZXNzYWdlU291cmNlKCkge1xuICAgIHZhciBkYXRhQVBJID0gbmV3IERhdGFNc2dBUEkodGhpcy5vd25lcilcbiAgICAgICAgLCBkYXRhRXZlbnRzU291cmNlID0gbmV3IERPTUV2ZW50c1NvdXJjZSh0aGlzLCBwcm94eURhdGFTb3VyY2VNZXRob2RzLCBkYXRhQVBJLCB0aGlzLm93bmVyKTtcbiAgICB0aGlzLl9zZXRNZXNzYWdlU291cmNlKGRhdGFFdmVudHNTb3VyY2UpO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2RhdGFFdmVudHNTb3VyY2UnLCBkYXRhRXZlbnRzU291cmNlKTtcblxuICAgIC8vIG1ha2UgdmFsdWUgbWV0aG9kIG9mIERhdGFNc2dBUEkgYXZhaWxhYmxlIG9uIERhdGEgZmFjZXRcbiAgICAvLyB0aGlzIGlzIGEgcHJpdmF0ZSBtZXRob2QsIGdldCgpIHNob3VsZCBiZSB1c2VkIHRvIGdldCBkYXRhLlxuICAgIE1peGluLnByb3RvdHlwZS5fY3JlYXRlUHJveHlNZXRob2QuY2FsbChkYXRhQVBJLCAndmFsdWUnLCAndmFsdWUnLCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIFN1YnNjcmliZXIgdG8gZGF0YSBjaGFuZ2UgZXZlbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZ1R5cGUgaW4gdGhpcyBpbnN0YW5jZSB3aWxsIGJlICcnXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YSBkYXRhIGNoYW5nZSBpbmZvcm1hdGlvblxuICovXG5mdW5jdGlvbiBvbk93bkRhdGFDaGFuZ2UobXNnVHlwZSwgZGF0YSkge1xuICAgIHRoaXMuX2J1YmJsZVVwRGF0YUNoYW5nZShkYXRhKTtcbiAgICB0aGlzLl9xdWV1ZURhdGFDaGFuZ2UoZGF0YSk7XG4gICAgaWYgKGRhdGEucGF0aCA9PT0gJycpIHtcbiAgICAgICAgdmFyIGluVHJhbnNhY3Rpb24gPSBnZXRUcmFuc2FjdGlvbkZsYWcoZGF0YSk7XG4gICAgICAgIHRoaXMucG9zdE1lc3NhZ2UoJ2RhdGFjaGFuZ2VzZmluaXNoZWQnLCB7IHRyYW5zYWN0aW9uOiBpblRyYW5zYWN0aW9uIH0pO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZW5kcyBkYXRhIGBtZXNzYWdlYCB0byBET00gcGFyZW50XG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtc2dEYXRhIGRhdGEgY2hhbmdlIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gRGF0YSRfYnViYmxlVXBEYXRhQ2hhbmdlKG1zZ0RhdGEpIHtcbiAgICB2YXIgcGFyZW50RGF0YSA9IHRoaXMuc2NvcGVQYXJlbnQoKTtcblxuICAgIGlmIChwYXJlbnREYXRhKSB7XG4gICAgICAgIHZhciBwYXJlbnRNc2cgPSBfLmNsb25lKG1zZ0RhdGEpO1xuICAgICAgICBwYXJlbnRNc2cucGF0aCA9ICh0aGlzLl9wYXRoIHx8ICgnLicgKyB0aGlzLm93bmVyLm5hbWUpKSAgKyBwYXJlbnRNc2cucGF0aDtcbiAgICAgICAgcGFyZW50RGF0YS5wb3N0TWVzc2FnZSgnY2hpbGRkYXRhJywgcGFyZW50TXNnIHx8IG1zZ0RhdGEpO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBRdWV1ZXMgZGF0YSBtZXNzYWdlcyB0byBiZSBkaXNwYXRjaGVkIHRvIGNvbm5lY3RvclxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gY2hhbmdlIGRhdGEgY2hhbmdlIGRlc2NyaXB0aW9uXG4gKi9cbmZ1bmN0aW9uIERhdGEkX3F1ZXVlRGF0YUNoYW5nZShjaGFuZ2UpIHtcbiAgICB0aGlzLl9kYXRhQ2hhbmdlc1F1ZXVlLnB1c2goY2hhbmdlKTtcbn1cblxuXG4vKipcbiAqIFN1YnNjcmliZXIgdG8gZGF0YWNoYW5nZXNmaW5pc2hlZCBldmVudC5cbiAqIENhbGxzIHRoZSBtZXRob2QgdG8gcG9zdCBjaGFuZ2VzIGJhdGNoIGFuZCBidWJibGVzIHVwIHRoZSBtZXNzYWdlXG4gKlxuICogQHBhcmFtICB7W3R5cGVdfSBtc2cgIFtkZXNjcmlwdGlvbl1cbiAqIEBwYXJhbSAge1t0eXBlXX0gZGF0YSBbZGVzY3JpcHRpb25dXG4gKi9cbmZ1bmN0aW9uIG9uRGF0YUNoYW5nZXNGaW5pc2hlZChtc2csIGRhdGEpIHtcbiAgICB0aGlzLl9wb3N0RGF0YUNoYW5nZXMoZGF0YS5pblRyYW5zYWN0aW9uKTtcbiAgICB2YXIgcGFyZW50RGF0YSA9IHRoaXMuc2NvcGVQYXJlbnQoKTtcbiAgICBpZiAocGFyZW50RGF0YSkgcGFyZW50RGF0YS5wb3N0TWVzc2FnZSgnZGF0YWNoYW5nZXNmaW5pc2hlZCcsIGRhdGEpO1xufVxuXG5cbi8qKlxuICogRGlzcGF0Y2hlcyBhbGwgY2hhbmdlcyBjb2xsZWN0ZWQgaW4gdGhlIGJhdGNoXG4gKiBVc2VkIGZvciBkYXRhIHByb3BhZ2F0aW9uIC0gY29ubmVjdG9yIHN1YnNjcmliZXMgdG8gdGhpcyBtZXNzYWdlXG4gKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gRGF0YSRfcG9zdERhdGFDaGFuZ2VzKGluVHJhbnNhY3Rpb24pIHtcbiAgICB2YXIgcXVldWUgPSB0aGlzLl9kYXRhQ2hhbmdlc1F1ZXVlLnJldmVyc2UoKTtcbiAgICB0aGlzLnBvc3RNZXNzYWdlU3luYygnZGF0YWNoYW5nZXMnLCB7XG4gICAgICAgIGNoYW5nZXM6IHF1ZXVlLFxuICAgICAgICB0cmFuc2FjdGlvbjogaW5UcmFuc2FjdGlvblxuICAgIH0pO1xuICAgIHRoaXMuX2RhdGFDaGFuZ2VzUXVldWUgPSBbXTsgLy8gaXQgY2FuJ3QgYmUgLmxlbmd0aCA9IDAsIGFzIHRoZSBhY3R1YWwgYXJyYXkgbWF5IHN0aWxsIGJlIHVzZWRcbn1cblxuXG4vKipcbiAqIFN1YnNjcmliZXIgdG8gZGF0YSBjaGFuZ2UgZXZlbnQgaW4gY2hpbGQgRGF0YSBmYWNldFxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gbXNnVHlwZVxuICogQHBhcmFtIHtPYmVqY3R9IGRhdGEgZGF0YSBjaGFuZ2UgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gb25DaGlsZERhdGEobXNnVHlwZSwgZGF0YSkge1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoZGF0YS5wYXRoLCBkYXRhKTtcbiAgICB0aGlzLl9idWJibGVVcERhdGFDaGFuZ2UoZGF0YSk7XG4gICAgdGhpcy5fcXVldWVEYXRhQ2hhbmdlKGRhdGEpO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgZGF0YSBpbiBET00gaGllcmFyY2h5IHJlY3Vyc2l2ZWx5LlxuICogUmV0dXJucyB0aGUgb2JqZWN0IHdpdGggdGhlIGRhdGEgYWN0dWFsbHkgc2V0IChjYW4gYmUgZGlmZmVyZW50LCBpZiBjb21wb25lbnRzIG1hdGNoaW5nIHNvbWUgcHJvcGVydGllcyBhcmUgbWlzc2luZykuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfE51bWJlcn0gdmFsdWUgdmFsdWUgdG8gYmUgc2V0LiBJZiB0aGUgdmFsdWUgaWYgc2NhbGFyLCBpdCB3aWxsIGJlIHNldCBvbiBjb21wb25lbnQncyBlbGVtZW50LCBpZiB0aGUgdmFsdWUgaXMgb2JqZWN0IC0gb24gRE9NIHRyZWUgaW5zaWRlIGNvbXBvbmVudFxuICogQHJldHVybiB7T2JqZWN0fFN0cmluZ3xOdW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIERhdGEkc2V0KHZhbHVlKSB7XG4gICAgdmFyIGluVHJhbnNhY3Rpb24gPSBnZXRUcmFuc2FjdGlvbkZsYWcoRGF0YSRzZXQpO1xuXG4gICAgdmFyIGNvbXBvbmVudFNldHRlciA9IHRoaXMuY29uZmlnLnNldDtcbiAgICBpZiAodHlwZW9mIGNvbXBvbmVudFNldHRlciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjb21wb25lbnRTZXR0ZXIuY2FsbCh0aGlzLm93bmVyLCB2YWx1ZSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKHRoaXMuX3NldCwgaW5UcmFuc2FjdGlvbik7XG5cbiAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLl92YWx1ZVxuICAgICAgICAsIG5ld1ZhbHVlID0gdGhpcy5fc2V0KHZhbHVlKTtcblxuICAgIC8vIHRoaXMgbWVzc2FnZSB0cmlnZ2VycyBvbk93bkRhdGFDaGFuZ2UsIGFzIHdlbGwgYXMgYWN0dWFsbCBET00gY2hhbmdlXG4gICAgLy8gc28gdGhlIHBhcmVudCBnZXRzIG5vdGlmaWVkXG4gICAgdmFyIG1zZyA9IHsgcGF0aDogJycsIHR5cGU6ICdjaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbmV3VmFsdWUsIG9sZFZhbHVlOiBvbGRWYWx1ZSB9O1xuICAgIHNldFRyYW5zYWN0aW9uRmxhZyhtc2csIGluVHJhbnNhY3Rpb24pO1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoJycsIG1zZyk7XG5cbiAgICByZXR1cm4gbmV3VmFsdWU7XG59XG5cblxuZnVuY3Rpb24gRGF0YSRfc2V0KHZhbHVlKSB7XG4gICAgdmFyIGluVHJhbnNhY3Rpb24gPSBnZXRUcmFuc2FjdGlvbkZsYWcoRGF0YSRfc2V0KTtcblxuICAgIHZhciB2YWx1ZVNldDtcbiAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZVNldCA9IFtdO1xuXG4gICAgICAgICAgICB2YXIgbGlzdEZhY2V0ID0gdGhpcy5vd25lci5saXN0O1xuICAgICAgICAgICAgaWYgKGxpc3RGYWNldCl7XG4gICAgICAgICAgICAgICAgdmFyIGxpc3RMZW5ndGggPSBsaXN0RmFjZXQuY291bnQoKVxuICAgICAgICAgICAgICAgICAgICAsIG5ld0l0ZW1zQ291bnQgPSB2YWx1ZS5sZW5ndGggLSBsaXN0TGVuZ3RoO1xuICAgICAgICAgICAgICAgIGlmIChuZXdJdGVtc0NvdW50ID49IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdEZhY2V0Ll9hZGRJdGVtcyhuZXdJdGVtc0NvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgbGlzdEZhY2V0Ll91cGRhdGVEYXRhUGF0aHMobGlzdExlbmd0aCwgbGlzdEZhY2V0LmNvdW50KCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oY2hpbGRWYWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0Q2hpbGREYXRhLmNhbGwodGhpcywgdmFsdWVTZXQsIGNoaWxkVmFsdWUsIGluZGV4LCAnWyQkXScpO1xuICAgICAgICAgICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgICAgICAgICAgdmFyIGxpc3RDb3VudCA9IGxpc3RGYWNldC5jb3VudCgpXG4gICAgICAgICAgICAgICAgICAgICwgcmVtb3ZlQ291bnQgPSBsaXN0Q291bnQgLSB2YWx1ZS5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAocmVtb3ZlQ291bnQtLSA+IDApXG4gICAgICAgICAgICAgICAgICAgIGxpc3RGYWNldC5fcmVtb3ZlSXRlbSh2YWx1ZS5sZW5ndGgpO1xuICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0RhdGE6IHNldHRpbmcgYXJyYXkgZGF0YSB3aXRob3V0IExpc3QgZmFjZXQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlU2V0ID0ge307XG4gICAgICAgICAgICBfLmVhY2hLZXkodmFsdWUsIGZ1bmN0aW9uKGNoaWxkVmFsdWUsIGtleSkge1xuICAgICAgICAgICAgICAgIHNldENoaWxkRGF0YS5jYWxsKHRoaXMsIHZhbHVlU2V0LCBjaGlsZFZhbHVlLCBrZXksICcuJCQnKTtcbiAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB9XG4gICAgfSBlbHNlXG4gICAgICAgIHZhbHVlU2V0ID0gdGhpcy5fc2V0U2NhbGFyVmFsdWUodmFsdWUpO1xuXG4gICAgdGhpcy5fdmFsdWUgPSB2YWx1ZVNldDtcblxuICAgIHJldHVybiB2YWx1ZVNldDtcblxuXG4gICAgZnVuY3Rpb24gc2V0Q2hpbGREYXRhKHZhbHVlU2V0LCBjaGlsZFZhbHVlLCBrZXksIHBhdGhTeW50YXgpIHtcbiAgICAgICAgdmFyIGNoaWxkUGF0aCA9IHBhdGhTeW50YXgucmVwbGFjZSgnJCQnLCBrZXkpO1xuICAgICAgICB2YXIgY2hpbGREYXRhRmFjZXQgPSB0aGlzLnBhdGgoY2hpbGRQYXRoLCB0eXBlb2YgY2hpbGRWYWx1ZSAhPSAndW5kZWZpbmVkJyk7XG4gICAgICAgIGlmIChjaGlsZERhdGFGYWNldCkge1xuICAgICAgICAgICAgc2V0VHJhbnNhY3Rpb25GbGFnKGNoaWxkRGF0YUZhY2V0LnNldCwgaW5UcmFuc2FjdGlvbik7XG4gICAgICAgICAgICB2YWx1ZVNldFtrZXldID0gY2hpbGREYXRhRmFjZXQuc2V0KGNoaWxkVmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIERlbGV0ZXMgY29tcG9uZW50IGZyb20gdmlldyBhbmQgc2NvcGUsIG9ubHkgaW4gY2FzZSBpdCBoYXMgSXRlbSBmYWNldCBvbiBpdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfE51bWJlcn0gdmFsdWUgdmFsdWUgdG8gc2V0IHRvIERPTSBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIERhdGEkZGVsKCkge1xuICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKERhdGEkZGVsKTtcblxuICAgIHZhciBjb21wb25lbnREZWxldGUgPSB0aGlzLmNvbmZpZy5kZWw7XG4gICAgaWYgKHR5cGVvZiBjb21wb25lbnREZWxldGUgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gY29tcG9uZW50RGVsZXRlLmNhbGwodGhpcy5vd25lcik7XG4gICAgICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkLmNhbGwodGhpcywgaW5UcmFuc2FjdGlvbik7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIG9sZFZhbHVlID0gdGhpcy5fdmFsdWU7XG5cbiAgICBzZXRUcmFuc2FjdGlvbkZsYWcodGhpcy5fZGVsLCBpblRyYW5zYWN0aW9uKTtcbiAgICB0aGlzLl9kZWwoKTtcblxuICAgIC8vIHRoaXMgbWVzc2FnZSB0cmlnZ2VycyBvbk93bkRhdGFDaGFuZ2UsIGFzIHdlbGwgYXMgYWN0dWFsbCBET00gY2hhbmdlXG4gICAgLy8gc28gdGhlIHBhcmVudCBnZXRzIG5vdGlmaWVkXG4gICAgdmFyIG1zZyA9IHsgcGF0aDogJycsIHR5cGU6ICdkZWxldGVkJywgb2xkVmFsdWU6IG9sZFZhbHVlIH07XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKG1zZywgaW5UcmFuc2FjdGlvbik7XG4gICAgdGhpcy5wb3N0TWVzc2FnZSgnJywgbXNnKTtcbn1cblxuXG5mdW5jdGlvbiBEYXRhJF9kZWwoKSB7XG4gICAgdmFyIGluVHJhbnNhY3Rpb24gPSBnZXRUcmFuc2FjdGlvbkZsYWcoRGF0YSRfZGVsKTtcbiAgICBzZXRUcmFuc2FjdGlvbkZsYWcodGhpcy5fc2V0LCBpblRyYW5zYWN0aW9uKTtcbiAgICB0aGlzLl9zZXQoKTtcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHNjYWxhciB2YWx1ZSB0byBET00gZWxlbWVudFxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbHVlIHZhbHVlIHRvIHNldCB0byBET00gZWxlbWVudFxuICovXG5mdW5jdGlvbiBEYXRhJF9zZXRTY2FsYXJWYWx1ZSh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmVsRGF0YS5zZXQodGhpcy5vd25lci5lbCwgdmFsdWUpO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEdldCBzdHJ1Y3R1cmVkIGRhdGEgZnJvbSBET00gaGllcmFyY2h5IHJlY3Vyc2l2ZWx5XG4gKiBSZXR1cm5zIERPTSBkYXRhXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBkZWVwR2V0IHRydWUgYnkgZGVmYXVsdFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBEYXRhJGdldChkZWVwR2V0KSB7XG4gICAgdmFyIGNvbXBvbmVudEdldHRlciA9IHRoaXMuY29uZmlnLmdldDtcbiAgICBpZiAodHlwZW9mIGNvbXBvbmVudEdldHRlciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICByZXR1cm4gY29tcG9uZW50R2V0dGVyLmNhbGwodGhpcy5vd25lciwgZGVlcEdldCk7XG5cbiAgICByZXR1cm4gdGhpcy5fZ2V0KGRlZXBHZXQpO1xufVxuXG5mdW5jdGlvbiBEYXRhJF9nZXQoZGVlcEdldCkge1xuICAgIGlmIChkZWVwR2V0ID09PSBmYWxzZSkgLy8gYSBoYWNrIHRvIGVuYWJsZSBnZXR0aW5nIHNoYWxsb3cgc3RhdGVcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIGNvbXAgPSB0aGlzLm93bmVyXG4gICAgICAgICwgc2NvcGVEYXRhO1xuXG4gICAgaWYgKGNvbXAubGlzdCkge1xuICAgICAgICBzY29wZURhdGEgPSBbXTtcbiAgICAgICAgY29tcC5saXN0LmVhY2goZnVuY3Rpb24obGlzdEl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICBzY29wZURhdGFbaW5kZXhdID0gbGlzdEl0ZW0uZGF0YS5nZXQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKGNvbXAuY29udGFpbmVyKVxuICAgICAgICAgICAgY29tcC5jb250YWluZXIuc2NvcGUuX2VhY2goZnVuY3Rpb24oc2NvcGVJdGVtLCBuYW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEgY29tcC5saXN0LmNvbnRhaW5zKHNjb3BlSXRlbSkgJiYgc2NvcGVJdGVtLmRhdGEpXG4gICAgICAgICAgICAgICAgICAgIHNjb3BlRGF0YVtuYW1lXSA9IHNjb3BlSXRlbS5kYXRhLmdldCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChjb21wLmNvbnRhaW5lcikge1xuICAgICAgICBzY29wZURhdGEgPSB7fTtcbiAgICAgICAgY29tcC5jb250YWluZXIuc2NvcGUuX2VhY2goZnVuY3Rpb24oc2NvcGVJdGVtLCBuYW1lKSB7XG4gICAgICAgICAgICBpZiAoc2NvcGVJdGVtLmRhdGEpXG4gICAgICAgICAgICAgICAgc2NvcGVEYXRhW25hbWVdID0gc2NvcGVJdGVtLmRhdGEuZ2V0KCk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZVxuICAgICAgICBzY29wZURhdGEgPSB0aGlzLl9nZXRTY2FsYXJWYWx1ZSgpO1xuXG4gICAgdGhpcy5fdmFsdWUgPSBzY29wZURhdGE7XG5cbiAgICByZXR1cm4gc2NvcGVEYXRhO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEdldHMgc2NhbGFyIGRhdGEgZnJvbSBET00gZWxlbWVudFxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIERhdGEkX2dldFNjYWxhclZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLmVsRGF0YS5nZXQodGhpcy5vd25lci5lbCk7XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU3BsaWNlcyBMaXN0IGl0ZW1zLiBSZXF1aXJlcyBMaXN0IGZhY2V0IHRvIGJlIHByZXNlbnQgb24gY29tcG9uZW50LiBXb3JrcyBpbiB0aGUgc2FtZSB3YXkgYXMgYXJyYXkgc3BsaWNlLlxuICogUmV0dXJucyBkYXRhIHJldHJpZXZlZCBmcm9tIHJlbW92ZWQgaXRlbXNcbiAqXG4gKiBAcGFyYW0ge0ludGVnZXJ9IHNwbGljZUluZGV4IGluZGV4IHRvIGRlbGV0ZS9pbnNlcnQgYXRcbiAqIEBwYXJhbSB7SW50ZWdlcn0gc3BsaWNlSG93TWFueSBudW1iZXIgb2YgaXRlbXMgdG8gZGVsZXRlXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBvcHRpb25hbCBpdGVtcyB0byBpbnNlcnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBEYXRhJHNwbGljZShzcGxpY2VJbmRleCwgc3BsaWNlSG93TWFueSkgeyAvLywgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKERhdGEkc3BsaWNlKTtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgdmFyIGNvbXBvbmVudFNwbGljZSA9IHRoaXMuY29uZmlnLnNwbGljZTtcbiAgICBpZiAodHlwZW9mIGNvbXBvbmVudFNwbGljZSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJlc3VsdCA9IGNvbXBvbmVudFNwbGljZS5hcHBseSh0aGlzLm93bmVyLCBhcmd1bWVudHMpO1xuICAgICAgICBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZC5jYWxsKHRoaXMsIGluVHJhbnNhY3Rpb24pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHNldFRyYW5zYWN0aW9uRmxhZyh0aGlzLl9zcGxpY2UsIGluVHJhbnNhY3Rpb24pO1xuICAgIHJlc3VsdCA9IHRoaXMuX3NwbGljZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgaWYgKCFyZXN1bHQpIHJldHVybjtcblxuICAgIHZhciBtc2cgPSB7IHBhdGg6ICcnLCB0eXBlOiAnc3BsaWNlJyxcbiAgICAgICAgICAgICAgICBpbmRleDogcmVzdWx0LnNwbGljZUluZGV4LFxuICAgICAgICAgICAgICAgIHJlbW92ZWQ6IHJlc3VsdC5yZW1vdmVkLFxuICAgICAgICAgICAgICAgIGFkZGVkQ291bnQ6IHJlc3VsdC5hZGRlZENvdW50LFxuICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB0aGlzLl92YWx1ZSB9O1xuICAgIHNldFRyYW5zYWN0aW9uRmxhZyhtc2csIGluVHJhbnNhY3Rpb24pO1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoJycsIG1zZyk7XG5cbiAgICByZXR1cm4gcmVzdWx0LnJlbW92ZWQ7XG59XG5cblxuZnVuY3Rpb24gRGF0YSRfc3BsaWNlKHNwbGljZUluZGV4LCBzcGxpY2VIb3dNYW55KSB7IC8vLCAuLi4gYXJndW1lbnRzXG4gICAgdmFyIGluVHJhbnNhY3Rpb24gPSBnZXRUcmFuc2FjdGlvbkZsYWcoRGF0YSRfc3BsaWNlKTtcblxuICAgIHZhciBsaXN0RmFjZXQgPSB0aGlzLm93bmVyLmxpc3Q7XG4gICAgaWYgKCEgbGlzdEZhY2V0KVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ0RhdGE6IGNhbm5vdCB1c2Ugc3BsaWNlIG1ldGhvZCB3aXRob3V0IExpc3QgZmFjZXQnKTtcblxuICAgIHZhciByZW1vdmVkID0gW107XG5cbiAgICB2YXIgbGlzdExlbmd0aCA9IGxpc3RGYWNldC5jb3VudCgpO1xuICAgIGFyZ3VtZW50c1swXSA9IHNwbGljZUluZGV4ID1cbiAgICAgICAgbW9kZWxVdGlscy5ub3JtYWxpemVTcGxpY2VJbmRleChzcGxpY2VJbmRleCwgbGlzdExlbmd0aCk7XG5cbiAgICBpZiAoc3BsaWNlSG93TWFueSA+IDAgJiYgbGlzdExlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IHNwbGljZUluZGV4OyBpIDwgc3BsaWNlSW5kZXggKyBzcGxpY2VIb3dNYW55OyBpKyspIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gbGlzdEZhY2V0Lml0ZW0oc3BsaWNlSW5kZXgpO1xuICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbURhdGEgPSBpdGVtLmRhdGEuZ2V0KCk7XG4gICAgICAgICAgICAgICAgbGlzdEZhY2V0Ll9yZW1vdmVJdGVtKHNwbGljZUluZGV4KTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdEYXRhOiBubyBpdGVtIGZvciBpbmRleCcsIGkpO1xuXG4gICAgICAgICAgICByZW1vdmVkLnB1c2goaXRlbURhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGlzdEZhY2V0Ll91cGRhdGVEYXRhUGF0aHMoc3BsaWNlSW5kZXgsIGxpc3RGYWNldC5jb3VudCgpKTtcbiAgICB9XG5cbiAgICB2YXIgYWRkZWQgPSBbXTtcblxuICAgIHZhciBhcmdzTGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgICAsIGFkZEl0ZW1zID0gYXJnc0xlbiA+IDJcbiAgICAgICAgLCBhZGRlZENvdW50ID0gYXJnc0xlbiAtIDI7XG4gICAgaWYgKGFkZEl0ZW1zKSB7XG4gICAgICAgIGxpc3RGYWNldC5fYWRkSXRlbXMoYWRkZWRDb3VudCwgc3BsaWNlSW5kZXgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMiwgaiA9IHNwbGljZUluZGV4OyBpIDwgYXJnc0xlbjsgaSsrLCBqKyspIHtcbiAgICAgICAgICAgIHZhciBpdGVtID0gbGlzdEZhY2V0Lml0ZW0oaik7XG4gICAgICAgICAgICBpZiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZyhpdGVtLmRhdGEuc2V0LCBpblRyYW5zYWN0aW9uKTtcbiAgICAgICAgICAgICAgICB2YXIgaXRlbURhdGEgPSBpdGVtLmRhdGEuc2V0KGFyZ3VtZW50c1tpXSk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybignRGF0YTogbm8gaXRlbSBmb3IgaW5kZXgnLCBqKTtcblxuICAgICAgICAgICAgYWRkZWQucHVzaChpdGVtRGF0YSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjaGFuZ2UgcGF0aHMgb2YgaXRlbXMgdGhhdCB3ZXJlIGFkZGVkIGFuZCBpdGVtcyBhZnRlciB0aGVtXG4gICAgICAgIGxpc3RGYWNldC5fdXBkYXRlRGF0YVBhdGhzKHNwbGljZUluZGV4LCBsaXN0RmFjZXQuY291bnQoKSk7XG4gICAgfVxuXG4gICAgLy8gaWYgKEFycmF5LmlzQXJyYXkodGhpcy5fdmFsdWUpKSB7XG4gICAgLy8gICAgIF8ucHJlcGVuZEFycmF5KGFkZGVkLCBbc3BsaWNlSW5kZXgsIHNwbGljZUhvd01hbnldKTtcbiAgICAvLyAgICAgQXJyYXkucHJvdG90eXBlLnNwbGljZS5hcHBseSh0aGlzLl92YWx1ZSwgYWRkZWQpO1xuICAgIC8vIH0gZWxzZVxuICAgICAgICB0aGlzLl92YWx1ZSA9IHRoaXMuZ2V0KCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBzcGxpY2VJbmRleDogc3BsaWNlSW5kZXgsXG4gICAgICAgIHJlbW92ZWQ6IHJlbW92ZWQsXG4gICAgICAgIGFkZGVkQ291bnQ6IGFkZEl0ZW1zID8gYWRkZWRDb3VudCA6IDBcbiAgICB9O1xufVxuXG5cbmZ1bmN0aW9uIERhdGEkbGVuKCkge1xuICAgIHZhciBjb21wb25lbnRMZW4gPSB0aGlzLmNvbmZpZy5sZW47XG4gICAgaWYgKHR5cGVvZiBjb21wb25lbnRMZW4gPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudExlbi5jYWxsKHRoaXMub3duZXIpO1xuICAgIGVsc2VcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xlbigpO1xufVxuXG5cbmZ1bmN0aW9uIERhdGEkX2xlbigpIHtcbiAgICBpZiAodGhpcy5vd25lci5saXN0KSByZXR1cm4gdGhpcy5vd25lci5saXN0LmNvdW50KCk7XG4gICAgZWxzZSBsb2dnZXIuZXJyb3IoJ0RhdGE6IGxlbiBjYWxsZWQgd2l0aG91dCBsaXN0IGZhY2V0Jyk7XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBkYXRhIGZhY2V0IG9mIGEgY2hpbGQgY29tcG9uZW50IChieSBzY29wZXMpIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBhdGhcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2Nlc3NQYXRoIGRhdGEgYWNjZXNzIHBhdGhcbiAqL1xuZnVuY3Rpb24gRGF0YSRwYXRoKGFjY2Vzc1BhdGgsIGNyZWF0ZUl0ZW0pIHtcbiAgICAvLyBjcmVhdGVJdGVtID0gdHJ1ZTsgLy8gdGhpcyBoYWNrIHNlZW1zIHRvIGJlIG5vIGxvbmdlciBuZWVkZWQuLi5cblxuICAgIGlmICghIGFjY2Vzc1BhdGgpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgdmFyIHBhcnNlZFBhdGggPSBwYXRoVXRpbHMucGFyc2VBY2Nlc3NQYXRoKGFjY2Vzc1BhdGgpO1xuICAgIHZhciBjdXJyZW50Q29tcG9uZW50ID0gdGhpcy5vd25lcjtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYXJzZWRQYXRoLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBwYXRoTm9kZSA9IHBhcnNlZFBhdGhbaV1cbiAgICAgICAgICAgICwgbm9kZUtleSA9IHBhdGhVdGlscy5nZXRQYXRoTm9kZUtleShwYXRoTm9kZSk7XG4gICAgICAgIGlmIChwYXRoTm9kZS5zeW50YXggPT0gJ2FycmF5JyAmJiBjdXJyZW50Q29tcG9uZW50Lmxpc3QpIHtcbiAgICAgICAgICAgIHZhciBpdGVtQ29tcG9uZW50ID0gY3VycmVudENvbXBvbmVudC5saXN0Lml0ZW0obm9kZUtleSk7XG4gICAgICAgICAgICBpZiAoISBpdGVtQ29tcG9uZW50ICYmIGNyZWF0ZUl0ZW0gIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgaXRlbUNvbXBvbmVudCA9IGN1cnJlbnRDb21wb25lbnQubGlzdC5fYWRkSXRlbShub2RlS2V5KTtcbiAgICAgICAgICAgICAgICBpdGVtQ29tcG9uZW50LmRhdGEuX3BhdGggPSBwYXRoTm9kZS5wcm9wZXJ0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnJlbnRDb21wb25lbnQgPSBpdGVtQ29tcG9uZW50O1xuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRDb21wb25lbnQuY29udGFpbmVyKVxuICAgICAgICAgICAgY3VycmVudENvbXBvbmVudCA9IGN1cnJlbnRDb21wb25lbnQuY29udGFpbmVyLnNjb3BlW25vZGVLZXldO1xuXG4gICAgICAgIHZhciBjdXJyZW50RGF0YUZhY2V0ID0gY3VycmVudENvbXBvbmVudCAmJiBjdXJyZW50Q29tcG9uZW50LmRhdGE7XG4gICAgICAgIGlmICghIGN1cnJlbnREYXRhRmFjZXQpXG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudERhdGFGYWNldDtcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHBhdGggdG8gYWNjZXNzIHRoaXMgZGF0YSBmYWNldCBmcm9tIHBhcmVudCAodXNpbmcgcGF0aCBtZXRob2QpXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBEYXRhJGdldFBhdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhdGg7XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBrZXkgdG8gYWNjZXNzIHRoZSB2YWx1ZSByZWxhdGVkIHRvIHRoaXMgZGF0YSBmYWNldCBvbiB0aGUgdmFsdWUgcmVsYXRlZCB0byBwYXJlbnQgZGF0YSBmYWNldC5cbiAqIElmIGNvbXBvbmVudCBoYXMgTGlzdCBmYWNldCwgcmV0dXJucyBpbmRleFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ3xJbnRlZ2VyfVxuICovXG5mdW5jdGlvbiBEYXRhJGdldEtleSgpIHtcbiAgICB2YXIgcGF0aCA9IHRoaXMuX3BhdGg7XG4gICAgcmV0dXJuIHBhdGhbMF0gPT0gJ1snXG4gICAgICAgICAgICA/ICtwYXRoLnNsaWNlKDEsIC0xKSAvLyByZW1vdmUgXCJbXCIgYW5kIFwiXVwiXG4gICAgICAgICAgICA6IHBhdGguc2xpY2UoMSkgLy8gcmVtb3ZlIGxlYWRpbmcgXCIuXCJcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBDYWxsZWQgYnkgYENvbXBvbmVudC5wcm90b3R5cGUuZ2V0U3RhdGVgIHRvIGdldCBmYWNldCdzIHN0YXRlXG4gKiBSZXR1cm5zIERPTSBkYXRhXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBkZWVwU3RhdGUsIHRydWUgYnkgZGVmYXVsdFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBEYXRhJGdldFN0YXRlKGRlZXBTdGF0ZSkge1xuICAgIHJldHVybiB7IHN0YXRlOiB0aGlzLmdldChkZWVwU3RhdGUpIH07XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IGBDb21wb25lbnQucHJvdG90eXBlLnNldFN0YXRlYCB0byBzZXQgZmFjZXQncyBzdGF0ZVxuICogU2ltcGx5IHNldHMgbW9kZWwgZGF0YVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBkYXRhIHRvIHNldCBvbiBmYWNldCdzIG1vZGVsXG4gKi9cbmZ1bmN0aW9uIERhdGEkc2V0U3RhdGUoc3RhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5zZXQoc3RhdGUuc3RhdGUpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JykgXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBiaW5kZXIgPSByZXF1aXJlKCcuLi8uLi9iaW5kZXInKVxuICAgICwgQmluZEF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4uLy4uL2F0dHJpYnV0ZXMvYV9iaW5kJylcbiAgICAsIERvbUZhY2V0RXJyb3IgPSByZXF1aXJlKCcuLi8uLi91dGlsL2Vycm9yJykuRG9tRmFjZXRcbiAgICAsIGRvbVV0aWxzID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9kb20nKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnJylcbiAgICAsIGRvVCA9IHJlcXVpcmUoJ2RvdCcpO1xuXG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuZmFjZXRzLmdldCgnRG9tJylgXG4gKiBGYWNldCB3aXRoIGNvbXBvbmVudCByZWxhdGVkIGRvbSB1dGlsc1xuICovXG52YXIgRG9tID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0RvbScpO1xuXG5fLmV4dGVuZChEb20sIHtcbiAgICBjcmVhdGVFbGVtZW50OiBEb20kJGNyZWF0ZUVsZW1lbnRcbn0pO1xuXG5cbi8qKlxuICogRmFjZXQgY2xhc3MgbWV0aG9kXG4gKiBDcmVhdGVzIGFuIGVsZW1lbnQgZnJvbSBhIHBhc3NlZCBjb25maWd1YXRpb24gb2JqZWN0XG4gKiBcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcgd2l0aCB0aGUgcHJvcGVydGllcyBgZG9tQ29uZmlnYCwgYGNvbnRlbnRgLCBgdGVtcGxhdGVgXG4gKiBAcmV0dXJuIHtFbGVtZW50fSBhbiBodG1sIGVsZW1lbnQgXG4gKi9cbmZ1bmN0aW9uIERvbSQkY3JlYXRlRWxlbWVudChjb25maWcpIHtcbiAgICB2YXIgZG9tQ29uZmlnID0gY29uZmlnLmRvbUNvbmZpZyB8fCB7fVxuICAgICAgICAsIHRhZ05hbWUgPSBkb21Db25maWcudGFnTmFtZSB8fCAnZGl2J1xuICAgICAgICAsIG5ld0VsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKVxuICAgICAgICAsIGNvbnRlbnQgPSBjb25maWcuY29udGVudFxuICAgICAgICAsIHRlbXBsYXRlID0gY29uZmlnLnRlbXBsYXRlO1xuXG4gICAgLy8gVE9ETyBpdCB3aWxsIGJlIGNhbGxlZCBhZ2FpbiB3aGVuL2lmIGNvbXBvbmVudCBpcyBpbnN0YW50aWF0ZWRcbiAgICAvLyBTaG91bGQgYmUgc29tZXByb3BlcnR5IG9uIGVsZW1lbnQgdG8gaW5kaWNhdGUgaXQncyBiZWVuIGNhbGxlZD9cbiAgICBfYXBwbHlDb25maWdUb0VsZW1lbnQobmV3RWwsIGRvbUNvbmZpZyk7XG5cbiAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgaWYgKHRlbXBsYXRlKVxuICAgICAgICAgICAgbmV3RWwuaW5uZXJIVE1MID0gZG9ULnRlbXBsYXRlKHRlbXBsYXRlKSh7Y29udGVudDogY29udGVudH0pO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBuZXdFbC5pbm5lckhUTUwgPSBjb250ZW50O1xuICAgIH1cbiAgICByZXR1cm4gbmV3RWw7XG59XG5cblxuZnVuY3Rpb24gX2FwcGx5Q29uZmlnVG9FbGVtZW50KGVsLCBjb25maWcpIHtcbiAgICB2YXIgY3NzQ2xhc3NlcyA9IGNvbmZpZyAmJiBjb25maWcuY2xzXG4gICAgICAgICwgY29uZmlnQXR0cmlidXRlcyA9IGNvbmZpZyAmJiBjb25maWcuYXR0cmlidXRlcztcblxuICAgIGlmIChjb25maWdBdHRyaWJ1dGVzKVxuICAgICAgICBfLmVhY2hLZXkoY29uZmlnQXR0cmlidXRlcywgZnVuY3Rpb24oYXR0clZhbHVlLCBhdHRyTmFtZSkge1xuICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKGF0dHJOYW1lLCBhdHRyVmFsdWUpO1xuICAgICAgICB9KTtcblxuICAgIGlmIChjc3NDbGFzc2VzKVxuICAgICAgICBfYXR0YWNoQ3NzQ2xhc3NlcyhlbCwgJ2FkZCcsIGNzc0NsYXNzZXMpO1xufVxuXG5cbl8uZXh0ZW5kUHJvdG8oRG9tLCB7XG4gICAgc3RhcnQ6IHN0YXJ0LFxuXG4gICAgc2hvdzogc2hvdyxcbiAgICBoaWRlOiBoaWRlLFxuICAgIHRvZ2dsZTogdG9nZ2xlLFxuICAgIGRldGFjaDogZGV0YWNoLFxuICAgIHJlbW92ZTogcmVtb3ZlLFxuICAgIGFwcGVuZDogYXBwZW5kLFxuICAgIHByZXBlbmQ6IHByZXBlbmQsXG4gICAgYXBwZW5kQ2hpbGRyZW46IGFwcGVuZENoaWxkcmVuLFxuICAgIHByZXBlbmRDaGlsZHJlbjogcHJlcGVuZENoaWxkcmVuLFxuICAgIGluc2VydEFmdGVyOiBpbnNlcnRBZnRlcixcbiAgICBpbnNlcnRCZWZvcmU6IGluc2VydEJlZm9yZSxcbiAgICBhcHBlbmRUb1Njb3BlUGFyZW50OiBhcHBlbmRUb1Njb3BlUGFyZW50LFxuICAgIGNoaWxkcmVuOiBEb20kY2hpbGRyZW4sXG4gICAgc2V0U3R5bGU6IHNldFN0eWxlLFxuICAgIHNldFN0eWxlczogc2V0U3R5bGVzLFxuICAgIGNvcHk6IGNvcHksXG4gICAgY3JlYXRlRWxlbWVudDogY3JlYXRlRWxlbWVudCxcblxuICAgIGFkZENzc0NsYXNzZXM6IF8ucGFydGlhbChfbWFuYWdlQ3NzQ2xhc3NlcywgJ2FkZCcpLFxuICAgIHJlbW92ZUNzc0NsYXNzZXM6IF8ucGFydGlhbChfbWFuYWdlQ3NzQ2xhc3NlcywgJ3JlbW92ZScpLFxuICAgIHRvZ2dsZUNzc0NsYXNzZXM6IF8ucGFydGlhbChfbWFuYWdlQ3NzQ2xhc3NlcywgJ3RvZ2dsZScpLFxuXG4gICAgZmluZDogZmluZCxcbiAgICBoYXNUZXh0QmVmb3JlU2VsZWN0aW9uOiBoYXNUZXh0QmVmb3JlU2VsZWN0aW9uLFxuICAgIGhhc1RleHRBZnRlclNlbGVjdGlvbjogaGFzVGV4dEFmdGVyU2VsZWN0aW9uLFxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChEb20pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IERvbTtcblxuXG4vLyBzdGFydCBEb20gZmFjZXRcbmZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIHZhciBlbCA9IHRoaXMub3duZXIuZWw7XG4gICAgX2FwcGx5Q29uZmlnVG9FbGVtZW50KGVsLCB0aGlzLmNvbmZpZyk7XG4gICAgdmFyIGN1cnJlbnRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKVxuICAgIHRoaXMuX3Zpc2libGUgPSBjdXJyZW50U3R5bGUgJiYgY3VycmVudFN0eWxlLmRpc3BsYXkgIT0gJ25vbmUnO1xufVxuXG4vLyBzaG93IEhUTUwgZWxlbWVudCBvZiBjb21wb25lbnRcbmZ1bmN0aW9uIHNob3coKSB7XG4gICAgdGhpcy50b2dnbGUodHJ1ZSk7XG59XG5cbi8vIGhpZGUgSFRNTCBlbGVtZW50IG9mIGNvbXBvbmVudFxuZnVuY3Rpb24gaGlkZSgpIHtcbiAgICB0aGlzLnRvZ2dsZShmYWxzZSk7XG59XG5cbi8vIHNob3cvaGlkZVxuZnVuY3Rpb24gdG9nZ2xlKGRvU2hvdykge1xuICAgIGRvU2hvdyA9IHR5cGVvZiBkb1Nob3cgPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICA/ICEgdGhpcy5fdmlzaWJsZVxuICAgICAgICAgICAgICAgIDogISEgZG9TaG93O1xuXG4gICAgdGhpcy5fdmlzaWJsZSA9IGRvU2hvdztcbiAgICB2YXIgZWwgPSB0aGlzLm93bmVyLmVsO1xuXG4gICAgZWwuc3R5bGUuZGlzcGxheSA9IGRvU2hvdyA/ICdibG9jaycgOiAnbm9uZSc7XG5cbiAgICByZXR1cm4gZG9TaG93O1xufVxuXG5cbmZ1bmN0aW9uIF9tYW5hZ2VDc3NDbGFzc2VzKG1ldGhvZE5hbWUsIGNzc0NsYXNzZXMsIGVuZm9yY2UpIHtcbiAgICBfYXR0YWNoQ3NzQ2xhc3Nlcyh0aGlzLm93bmVyLmVsLCBtZXRob2ROYW1lLCBjc3NDbGFzc2VzLCBlbmZvcmNlKTtcbn1cblxuXG5mdW5jdGlvbiBfYXR0YWNoQ3NzQ2xhc3NlcyhlbCwgbWV0aG9kTmFtZSwgY3NzQ2xhc3NlcywgZW5mb3JjZSkge1xuICAgIHZhciBjbGFzc0xpc3QgPSBlbC5jbGFzc0xpc3RcbiAgICAgICAgLCBkb1RvZ2dsZSA9IG1ldGhvZE5hbWUgPT0gJ3RvZ2dsZSc7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjc3NDbGFzc2VzKSlcbiAgICAgICAgY3NzQ2xhc3Nlcy5mb3JFYWNoKGNhbGxNZXRob2QpO1xuICAgIGVsc2UgaWYgKHR5cGVvZiBjc3NDbGFzc2VzID09ICdzdHJpbmcnKVxuICAgICAgICBjYWxsTWV0aG9kKGNzc0NsYXNzZXMpO1xuICAgIGVsc2VcbiAgICAgICAgdGhyb3cgbmV3IERvbUZhY2V0RXJyb3IoJ3Vua25vd24gdHlwZSBvZiBDU1MgY2xhc3NlcyBwYXJhbWV0ZXInKTtcblxuICAgIGZ1bmN0aW9uIGNhbGxNZXRob2QoY3NzQ2xzKSB7XG4gICAgICAgIGRvVG9nZ2xlXG4gICAgICAgICAgICAvLyBPbmx5IHBhc3MgJ2VuZm9yY2UnIGlmIGEgdmFsdWUgaGFzIGJlZW4gcHJvdmlkZWQgKFRoZSAndG9nZ2xlJyBmdW5jdGlvbiBvZiB0aGUgY2xhc3NMaXN0IHdpbGwgdHJlYXQgdW5kZWZpbmVkID09PSBmYWxzZSByZXN1bHRpbmcgaW4gb25seSBhbGxvd2luZyBjbGFzc2VzIHRvIGJlIHJlbW92ZWQpXG4gICAgICAgICAgICA/IGVuZm9yY2UgPT09IHVuZGVmaW5lZCA/IGNsYXNzTGlzdFttZXRob2ROYW1lXShjc3NDbHMpIDogY2xhc3NMaXN0W21ldGhvZE5hbWVdKGNzc0NscywgZW5mb3JjZSlcbiAgICAgICAgICAgIDogY2xhc3NMaXN0W21ldGhvZE5hbWVdKGNzc0Nscyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIGRldGFjaCgpIHtcbiAgICBpZiAodGhpcy5vd25lci5lbCkgIFxuICAgICAgICBkb21VdGlscy5kZXRhY2hDb21wb25lbnQodGhpcy5vd25lci5lbCk7XG59XG5cblxuZnVuY3Rpb24gc2V0U3R5bGUocHJvcGVydHksIHZhbHVlKSB7XG4gICAgaWYgKCF0aGlzLm93bmVyLmVsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjYWxsIHNldFN0eWxlIG9uIG93bmVyIHdpdGggbm8gZWxlbWVudDogXCIgKyB0aGlzLm93bmVyLmNvbnN0cnVjdG9yLm5hbWUpO1xuICAgIH1cbiAgICB0aGlzLm93bmVyLmVsLnN0eWxlW3Byb3BlcnR5XSA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBzZXRTdHlsZXMocHJvcGVydGllcykge1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHByb3BlcnRpZXMpXG4gICAgICAgIHRoaXMub3duZXIuZWwuc3R5bGVbcHJvcGVydHldID0gcHJvcGVydGllc1twcm9wZXJ0eV07XG59XG5cblxuLy8gY3JlYXRlIGEgY29weSBvZiBET00gZWxlbWVudCB1c2luZyBmYWNldCBjb25maWcgaWYgc2V0XG5mdW5jdGlvbiBjb3B5KGlzRGVlcCkge1xuICAgIHJldHVybiB0aGlzLm93bmVyLmVsICYmIHRoaXMub3duZXIuZWwuY2xvbmVOb2RlKGlzRGVlcCk7XG59XG5cblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudCgpIHtcbiAgICB2YXIgbmV3RWwgPSBEb20uY3JlYXRlRWxlbWVudCh0aGlzLmNvbmZpZyk7XG4gICAgcmV0dXJuIG5ld0VsO1xufVxuXG5cbi8vIHJlbW92ZSBIVE1MIGVsZW1lbnQgb2YgY29tcG9uZW50XG5mdW5jdGlvbiByZW1vdmUoKSB7XG4gICAgZG9tVXRpbHMucmVtb3ZlRWxlbWVudCh0aGlzLm93bmVyLmVsKTtcbn1cblxuLy8gYXBwZW5kIGluc2lkZSBIVE1MIGVsZW1lbnQgb2YgY29tcG9uZW50XG5mdW5jdGlvbiBhcHBlbmQoZWwpIHtcbiAgICB0aGlzLm93bmVyLmVsLmFwcGVuZENoaWxkKGVsKTtcbn1cblxuLy8gcHJlcGVuZCBpbnNpZGUgSFRNTCBlbGVtZW50IG9mIGNvbXBvbmVudFxuZnVuY3Rpb24gcHJlcGVuZChlbCkge1xuICAgIHZhciB0aGlzRWwgPSB0aGlzLm93bmVyLmVsXG4gICAgICAgICwgZmlyc3RDaGlsZCA9IHRoaXNFbC5maXJzdENoaWxkO1xuICAgIGlmIChmaXJzdENoaWxkKVxuICAgICAgICB0aGlzRWwuaW5zZXJ0QmVmb3JlKGVsLCBmaXJzdENoaWxkKTtcbiAgICBlbHNlXG4gICAgICAgIHRoaXNFbC5hcHBlbmRDaGlsZChlbCk7XG59XG5cbi8vIGFwcGVuZHMgY2hpbGRyZW4gb2YgZWxlbWVudCBpbnNpZGUgdGhpcyBjb21wb25lbnQncyBlbGVtZW50XG5mdW5jdGlvbiBhcHBlbmRDaGlsZHJlbihlbCkge1xuICAgIHdoaWxlKGVsLmNoaWxkTm9kZXMubGVuZ3RoKVxuICAgICAgICB0aGlzLmFwcGVuZChlbC5jaGlsZE5vZGVzWzBdKTtcbn1cblxuLy8gcHJlcGVuZHMgY2hpbGRyZW4gb2YgZWxlbWVudCBpbnNpZGUgdGhpcyBjb21wb25lbnQncyBlbGVtZW50XG5mdW5jdGlvbiBwcmVwZW5kQ2hpbGRyZW4oZWwpIHtcbiAgICB3aGlsZShlbC5jaGlsZE5vZGVzLmxlbmd0aClcbiAgICAgICAgdGhpcy5wcmVwZW5kKGVsLmNoaWxkTm9kZXNbZWwuY2hpbGROb2Rlcy5sZW5ndGggLSAxXSk7XG59XG5cbmZ1bmN0aW9uIGluc2VydEFmdGVyKGVsKSB7XG4gICAgdmFyIHRoaXNFbCA9IHRoaXMub3duZXIuZWxcbiAgICAgICAgLCBwYXJlbnQgPSB0aGlzRWwucGFyZW50Tm9kZTsgICAgXG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShlbCwgdGhpc0VsLm5leHRTaWJsaW5nKTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0QmVmb3JlKGVsKSB7XG4gICAgdmFyIHRoaXNFbCA9IHRoaXMub3duZXIuZWxcbiAgICAgICAgLCBwYXJlbnQgPSB0aGlzRWwucGFyZW50Tm9kZTtcbiAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGVsLCB0aGlzRWwpO1xufVxuXG5cbi8vIGFwcGVuZHMgY29tcG9uZW50J3MgZWxlbWVudCB0byBzY29wZSBwYXJlbnQuIElmIGl0IHdhcyBhbHJlZHkgaW4gRE9NIGl0IHdpbGwgYmUgbW92ZWRcbmZ1bmN0aW9uIGFwcGVuZFRvU2NvcGVQYXJlbnQoKSB7XG4gICAgdmFyIHBhcmVudCA9IHRoaXMub3duZXIuZ2V0U2NvcGVQYXJlbnQoKTtcbiAgICBpZiAocGFyZW50KSBwYXJlbnQuZWwuYXBwZW5kQ2hpbGQodGhpcy5vd25lci5lbCk7XG59XG5cblxuLyoqXG4gKiBEb20gZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRoZSBsaXN0IG9mIGNoaWxkIGVsZW1lbnRzIG9mIHRoZSBjb21wb25lbnQgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge0FycmF5W0VsZW1lbnRdfVxuICovXG5mdW5jdGlvbiBEb20kY2hpbGRyZW4oKSB7XG4gICAgcmV0dXJuIGRvbVV0aWxzLmNoaWxkcmVuKHRoaXMub3duZXIuZWwpO1xufVxuXG5cbnZhciBmaW5kRGlyZWN0aW9ucyA9IHtcbiAgICAndXAnOiAncHJldmlvdXNOb2RlJyxcbiAgICAnZG93bic6ICduZXh0Tm9kZSdcbn07XG5cbi8vIEZpbmRzIGNvbXBvbmVudCBwYXNzaW5nIG9wdGlvbmFsIGl0ZXJhdG9yJ3MgdGVzdFxuLy8gaW4gdGhlIHNhbWUgc2NvcGUgYXMgdGhlIGN1cnJlbnQgY29tcG9uZW50ICh0aGlzKVxuLy8gYnkgdHJhdmVyc2luZyBET00gdHJlZSB1cHdhcmRzIChkaXJlY3Rpb24gPSBcInVwXCIpXG4vLyBvciBkb3dud2FyZHMgKGRpcmVjdGlvbiA9IFwiZG93blwiKVxuZnVuY3Rpb24gZmluZChkaXJlY3Rpb24sIGl0ZXJhdG9yKSB7XG4gICAgaWYgKCEgZmluZERpcmVjdGlvbnMuaGFzT3duUHJvcGVydHkoZGlyZWN0aW9uKSlcbiAgICAgICAgdGhyb3cgbmV3IERvbUZhY2V0RXJyb3IoJ2luY29ycmVjdCBmaW5kIGRpcmVjdGlvbjogJyArIGRpcmVjdGlvbik7XG5cbiAgICB2YXIgZWwgPSB0aGlzLm93bmVyLmVsXG4gICAgICAgICwgc2NvcGUgPSB0aGlzLm93bmVyLnNjb3BlXG4gICAgICAgICwgdHJlZVdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoc2NvcGUuX3Jvb3RFbCwgTm9kZUZpbHRlci5TSE9XX0VMRU1FTlQpO1xuXG4gICAgdHJlZVdhbGtlci5jdXJyZW50Tm9kZSA9IGVsO1xuICAgIHZhciBuZXh0Tm9kZSA9IHRyZWVXYWxrZXJbZmluZERpcmVjdGlvbnNbZGlyZWN0aW9uXV0oKVxuICAgICAgICAsIGNvbXBvbmVudHNOYW1lcyA9IE9iamVjdC5rZXlzKHNjb3BlKVxuICAgICAgICAsIGZvdW5kID0gZmFsc2U7XG5cbiAgICB3aGlsZSAobmV4dE5vZGUpIHtcbiAgICAgICAgdmFyIGF0dHIgPSBuZXcgQmluZEF0dHJpYnV0ZShuZXh0Tm9kZSk7XG4gICAgICAgIGlmIChhdHRyLm5vZGUpIHtcbiAgICAgICAgICAgIGF0dHIucGFyc2UoKS52YWxpZGF0ZSgpO1xuICAgICAgICAgICAgaWYgKHNjb3BlLmhhc093blByb3BlcnR5KGF0dHIuY29tcE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbXBvbmVudCA9IHNjb3BlW2F0dHIuY29tcE5hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghIGl0ZXJhdG9yIHx8IGl0ZXJhdG9yKGNvbXBvbmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdHJlZVdhbGtlci5jdXJyZW50Tm9kZSA9IG5leHROb2RlO1xuICAgICAgICBuZXh0Tm9kZSA9IHRyZWVXYWxrZXJbZmluZERpcmVjdGlvbnNbZGlyZWN0aW9uXV0oKTtcbiAgICB9XG5cbiAgICBpZiAoZm91bmQpIHJldHVybiBjb21wb25lbnQ7XG59XG5cblxuLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBlbGVtZW50IGhhcyB0ZXh0IGJlZm9yZSBzZWxlY3Rpb25cbmZ1bmN0aW9uIGhhc1RleHRCZWZvcmVTZWxlY3Rpb24oKSB7XG4gICAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoISBzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHJldHVybiB0cnVlO1xuICAgIFxuICAgIHZhciB0ZXh0ID0gc2VsZWN0aW9uLmZvY3VzTm9kZSAmJiBzZWxlY3Rpb24uZm9jdXNOb2RlLnRleHRDb250ZW50O1xuICAgIHZhciBzdGFydFBvcyA9IHRleHQgJiYgdGV4dC5jaGFyQXQoMCkgPT0gJyAnID8gMSA6IDA7XG4gICAgaWYgKHNlbGVjdGlvbi5hbmNob3JPZmZzZXQgIT0gc3RhcnRQb3MpIHJldHVybiB0cnVlO1xuXG4gICAgLy8gd2FsayB1cCB0aGUgRE9NIHRyZWUgdG8gY2hlY2sgaWYgdGhlcmUgYXJlIHRleHQgbm9kZXMgYmVmb3JlIGN1cnNvclxuICAgIHZhciB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcih0aGlzLm93bmVyLmVsLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gICAgdHJlZVdhbGtlci5jdXJyZW50Tm9kZSA9IHNlbGVjdGlvbi5hbmNob3JOb2RlO1xuICAgIHZhciBwcmV2Tm9kZSA9IHRyZWVXYWxrZXIucHJldmlvdXNOb2RlKCk7XG5cbiAgICB2YXIgaXNUZXh0ID0gcHJldk5vZGUgPyAhcHJldk5vZGUubm9kZVZhbHVlLnRyaW0oKSA9PSAnJyA6IGZhbHNlO1xuXG4gICAgcmV0dXJuIGlzVGV4dDtcbn1cblxuXG5mdW5jdGlvbiBoYXNUZXh0QWZ0ZXJTZWxlY3Rpb24oKSB7XG4gICAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoISBzZWxlY3Rpb24uaXNDb2xsYXBzZWQpIHJldHVybiB0cnVlO1xuXG4gICAgdmFyIHRleHQgPSBzZWxlY3Rpb24uZm9jdXNOb2RlICYmIHNlbGVjdGlvbi5mb2N1c05vZGUudGV4dENvbnRlbnQ7XG4gICAgdmFyIHN0YXJ0UG9zID0gdGV4dCAmJiB0ZXh0LmNoYXJBdCh0ZXh0Lmxlbmd0aC0xKSA9PSAnICcgPyBzZWxlY3Rpb24uYW5jaG9yTm9kZS5sZW5ndGgtMSA6IHNlbGVjdGlvbi5hbmNob3JOb2RlLmxlbmd0aDtcbiAgICBpZiAoc2VsZWN0aW9uLmFuY2hvck9mZnNldCA8IHN0YXJ0UG9zKSByZXR1cm4gdHJ1ZTtcblxuICAgIC8vIHdhbGsgdXAgdGhlIERPTSB0cmVlIHRvIGNoZWNrIGlmIHRoZXJlIGFyZSB0ZXh0IG5vZGVzIGFmdGVyIGN1cnNvclxuICAgIHZhciB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcih0aGlzLm93bmVyLmVsLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gICAgdHJlZVdhbGtlci5jdXJyZW50Tm9kZSA9IHNlbGVjdGlvbi5hbmNob3JOb2RlO1xuICAgIHZhciBuZXh0Tm9kZSA9IHRyZWVXYWxrZXIubmV4dE5vZGUoKTtcbiAgICBcbiAgICAvL1RvIGNhcHR1cmUgd2hlbiB0cmVld2Fsa2VyIGdpdmVzIHVzIGFuIGVtcHR5IHRleHQgbm9kZSAodW5rbm93biByZWFzb24pXG4gICAgdmFyIGlzVGV4dCA9IG5leHROb2RlID8gIW5leHROb2RlLm5vZGVWYWx1ZS50cmltKCkgPT0gJycgOiBmYWxzZTtcblxuICAgIHJldHVybiBpc1RleHQ7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIDxhIG5hbWU9XCJjb21wb25lbnRzLWZhY2V0cy1kcmFnXCI+PC9hPlxuLy8gIyMjZHJhZyBmYWNldFxuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBET01FdmVudHNTb3VyY2UgPSByZXF1aXJlKCcuLi9tc2dfc3JjL2RvbV9ldmVudHMnKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBEcmFnRHJvcCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZHJhZ2Ryb3AnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi91dGlsL2xvZ2dlcicpO1xuXG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuZmFjZXRzLmdldCgnRHJhZycpYFxuICogRmFjZXQgZm9yIGNvbXBvbmVudHMgdGhhdCBjYW4gYmUgZHJhZ2dlZFxuICogRHJhZyBmYWNldCBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyczpcbiAqXG4gKiAgLSBtZXRhOiBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzXG4gKiAgICAgIC0gcGFyYW1zOiBvYmplY3Qgb2Yga2V5LXZhbHVlIHBhaXJzIHRoYXQgd2lsbCBiZSBjb252ZXJ0ZWQgaW4gdXJsLWxpa2UgcXVlcnkgc3RyaW5nIGluIHRoZSBlbmQgb2YgZGF0YSB0eXBlIGZvciBtZXRhZGF0YSBkYXRhIHR5cGUgKG9yIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGlzIG9iamVjdCkuIFNlZSBjb25maWcuZHJhZ0Ryb3AuZGF0YVR5cGVzLmNvbXBvbmVudE1ldGFUZW1wbGF0ZVxuICogICAgICAgICAgYWxsIHZhbHVlcyB3aWxsIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UgYXMgZGF0YXR5cGUgY2Fubm90IHN0b3JlIHVwcGVyY2FzZSBsZXR0ZXJzLlxuICogICAgICAtIGRhdGE6IGRhdGEgdGhhdCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgYWJvdmUgbWV0YSBkYXRhIHR5cGUgKG9yIGZ1bmN0aW9uKVxuICogIC0gYWxsb3dlZEVmZmVjdHM6IHN0cmluZyAob3IgZnVuY3Rpb24pIGFzIHNwZWNpZmllZCBoZXJlOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0RyYWdEcm9wL0RyYWdfT3BlcmF0aW9ucyNkcmFnc3RhcnRcbiAqICAtIGRhdGFUeXBlczogbWFwIG9mIGFkZGl0aW9uYWwgZGF0YSB0eXBlcyB0aGUgY29tcG9uZW50IHdpbGwgc3VwcGx5IHRvIGRhdGEgdHJhbnNmZXIgb2JqZWN0LCBrZXkgaXMgZGF0YSB0eXBlLCB2YWx1ZSBpcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBpdCwgY29tcG9uZW50IHdpbGwgYmUgcGFzc2VkIGFzIHRoZSBjb250ZXh0IHRvIHRoaXMgZnVuY3Rpb25cbiAqXG4gKiBJZiBmdW5jdGlvbiBpcyBzcGVjaWZpZWQgaW4gYW55IHBhcmFtZXRlciBpdCB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBjb21wb25lbnQgYXMgdGhlIGNvbnRleHRcbiAqL1xudmFyIERyYWcgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnRHJhZycpO1xuXG5fLmV4dGVuZFByb3RvKERyYWcsIHtcbiAgICBpbml0OiBEcmFnJGluaXQsXG4gICAgc3RhcnQ6IERyYWckc3RhcnQsXG4gICAgc2V0SGFuZGxlOiBEcmFnJHNldEhhbmRsZVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChEcmFnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBEcmFnO1xuXG5cbmZ1bmN0aW9uIERyYWckaW5pdCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAgIFxuXG4gICAgdGhpcy5fY3JlYXRlTWVzc2FnZVNvdXJjZVdpdGhBUEkoRE9NRXZlbnRzU291cmNlKTtcbiAgICB0aGlzLl9kcmFnRGF0YSA9IHt9O1xuXG4gICAgdmFyIGRhdGFUeXBlSW5mbyA9IHRoaXMuY29uZmlnLl9kYXRhVHlwZUluZm8gfHwgJyc7XG4gICAgdGhpcy5fZGF0YVR5cGVJbmZvID0gdHlwZW9mIGRhdGFUeXBlSW5mbyA9PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBkYXRhVHlwZUluZm9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGZ1bmN0aW9uKCkgeyByZXR1cm4gZGF0YVR5cGVJbmZvOyB9O1xufVxuXG5cbi8qKlxuICogRHJhZyBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgdGhlIGRyYWcgaGFuZGxlIGVsZW1lbnQgb2YgY29tcG9uZW50LiBUaGlzIGVsZW1lbnQgaGFzIHRvIGJlIGRyYWdnZWQgZm9yIHRoZSBjb21wb25lbnQgdG8gYmUgZHJhZ2dlZC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGhhbmRsZUVsXG4gKi9cbmZ1bmN0aW9uIERyYWckc2V0SGFuZGxlKGhhbmRsZUVsKSB7XG4gICAgaWYgKCEgdGhpcy5vd25lci5lbC5jb250YWlucyhoYW5kbGVFbCkpXG4gICAgICAgIHJldHVybiBsb2dnZXIud2FybignZHJhZyBoYW5kbGUgc2hvdWxkIGJlIGluc2lkZSBlbGVtZW50IHRvIGJlIGRyYWdnZWQnKVxuICAgIHRoaXMuX2RyYWdIYW5kbGUgPSBoYW5kbGVFbDtcbn1cblxuXG5mdW5jdGlvbiBEcmFnJHN0YXJ0KCkge1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5zdGFydC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIF9hZGREcmFnQXR0cmlidXRlLmNhbGwodGhpcyk7XG5cbiAgICB0aGlzLm9uTWVzc2FnZXMoe1xuICAgICAgICAnbW91c2Vkb3duJzogb25Nb3VzZURvd24sXG4gICAgICAgICdtb3VzZWVudGVyIG1vdXNlbGVhdmUgbW91c2Vtb3ZlJzogb25Nb3VzZU1vdmVtZW50LFxuICAgICAgICAnZHJhZ3N0YXJ0Jzogb25EcmFnU3RhcnQsXG4gICAgICAgICdkcmFnJzogb25EcmFnZ2luZyxcbiAgICAgICAgJ2RyYWdlbmQnOiBvbkRyYWdFbmRcbiAgICB9KTtcblxuICAgIHRoaXMub3duZXIub25NZXNzYWdlcyh7XG4gICAgICAgICdnZXRzdGF0ZXN0YXJ0ZWQnOlxuICAgICAgICAgICAgeyBzdWJzY3JpYmVyOiBfcmVtb3ZlRHJhZ0F0dHJpYnV0ZSwgY29udGV4dDogdGhpcyB9LFxuICAgICAgICAnZ2V0c3RhdGVjb21wbGV0ZWQnOlxuICAgICAgICAgICAgeyBzdWJzY3JpYmVyOiBfYWRkRHJhZ0F0dHJpYnV0ZSwgY29udGV4dDogdGhpcyB9XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBBZGRzIGRyYWdnYWJsZSBhdHRyaWJ1dGUgdG8gY29tcG9uZW50J3MgZWxlbWVudFxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIF9hZGREcmFnQXR0cmlidXRlKCkge1xuICAgIGlmICh0aGlzLm93bmVyLmVsKVxuICAgICAgICB0aGlzLm93bmVyLmVsLnNldEF0dHJpYnV0ZSgnZHJhZ2dhYmxlJywgdHJ1ZSk7XG59XG5cblxuZnVuY3Rpb24gX3JlbW92ZURyYWdBdHRyaWJ1dGUoKSB7XG4gICAgaWYgKHRoaXMub3duZXIuZWwpXG4gICAgICAgIHRoaXMub3duZXIuZWwucmVtb3ZlQXR0cmlidXRlKCdkcmFnZ2FibGUnKTtcbn1cblxuXG5mdW5jdGlvbiBvbk1vdXNlRG93bihldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgdGhpcy5fX21vdXNlRG93blRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICBpZiAodGFyZ2V0SW5EcmFnSGFuZGxlLmNhbGwodGhpcykpIHtcbiAgICAgICAgd2luZG93LmdldFNlbGVjdGlvbigpLmVtcHR5KCk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBvbk1vdXNlTW92ZW1lbnQoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIHZhciBzaG91bGRCZURyYWdnYWJsZSA9IHRhcmdldEluRHJhZ0hhbmRsZS5jYWxsKHRoaXMpO1xuICAgIHRoaXMub3duZXIuZWwuc2V0QXR0cmlidXRlKCdkcmFnZ2FibGUnLCBzaG91bGRCZURyYWdnYWJsZSk7XG4gICAgaWYgKGRvY3VtZW50LmJvZHkuZ2V0QXR0cmlidXRlKCdkYXRhLWRyYWdFbmFibGVFdmVudCcpICE9ICdmYWxzZScpXG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xufVxuXG5cbmZ1bmN0aW9uIG9uRHJhZ1N0YXJ0KGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5jb25maWcub2ZmIHx8ICEgdGFyZ2V0SW5EcmFnSGFuZGxlLmNhbGwodGhpcykpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBvd25lciA9IHRoaXMub3duZXI7XG4gICAgdmFyIGR0ID0gbmV3IERyYWdEcm9wKGV2ZW50KTtcblxuICAgIHRoaXMuX2RyYWdEYXRhID0gZHQuc2V0Q29tcG9uZW50U3RhdGUob3duZXIpO1xuICAgIHNldE1ldGEuY2FsbCh0aGlzKTtcbiAgICBzZXRBZGRpdGlvbmFsRGF0YVR5cGVzLmNhbGwodGhpcyk7XG4gICAgX3NldEFsbG93ZWRFZmZlY3RzLmNhbGwodGhpcywgZHQpO1xuXG4gICAgRHJhZ0Ryb3Auc2VydmljZS5wb3N0TWVzc2FnZVN5bmMoJ2RyYWdkcm9wc3RhcnRlZCcsIHtcbiAgICAgICAgZXZlbnRUeXBlOiAnZHJhZ3N0YXJ0JyxcbiAgICAgICAgZHJhZ0Ryb3A6IGR0LFxuICAgICAgICBkcmFnRmFjZXQ6IHRoaXNcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIHNldE1ldGEoKSB7XG4gICAgICAgIHZhciBtZXRhQ29uZmlnID0gdGhpcy5jb25maWcubWV0YVxuICAgICAgICAgICAgLCBwYXJhbXNDb25maWcgPSBtZXRhQ29uZmlnICYmIG1ldGFDb25maWcucGFyYW1zXG4gICAgICAgICAgICAsIG1ldGFEYXRhQ29uZmlnID0gbWV0YUNvbmZpZyAmJiBtZXRhQ29uZmlnLmRhdGE7XG5cbiAgICAgICAgdmFyIHBhcmFtcyA9IF8ucmVzdWx0KHBhcmFtc0NvbmZpZywgb3duZXIpXG4gICAgICAgICAgICAsIGRhdGEgPSBfLnJlc3VsdChtZXRhRGF0YUNvbmZpZywgb3duZXIpO1xuXG4gICAgICAgIHRoaXMuX2RyYWdNZXRhRGF0YVR5cGUgPSBkdC5zZXRDb21wb25lbnRNZXRhKG93bmVyLCBwYXJhbXMsIGRhdGEpO1xuICAgICAgICB0aGlzLl9kcmFnTWV0YURhdGEgPSBkYXRhO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldEFkZGl0aW9uYWxEYXRhVHlwZXMoKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5kYXRhVHlwZXMpIHtcbiAgICAgICAgICAgIHRoaXMuX2RhdGFUeXBlc0RhdGEgPSBfLm1hcEtleXModGhpcy5jb25maWcuZGF0YVR5cGVzLCBmdW5jdGlvbiAoZ2V0RGF0YUZ1bmMsIGRhdGFUeXBlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBnZXREYXRhRnVuYy5jYWxsKHRoaXMub3duZXIsIGRhdGFUeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ29iamVjdCcpIGRhdGEgPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YSkgZHQuc2V0RGF0YShkYXRhVHlwZSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgICAgICB9LCB0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBvbkRyYWdnaW5nKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBpZiAoX2RyYWdJc0Rpc2FibGVkLmNhbGwodGhpcywgZXZlbnQpKSByZXR1cm47XG5cbiAgICB2YXIgZHQgPSBuZXcgRHJhZ0Ryb3AoZXZlbnQpO1xuICAgIGR0LnNldENvbXBvbmVudFN0YXRlKHRoaXMub3duZXIsIHRoaXMuX2RyYWdEYXRhKTtcbiAgICBkdC5zZXREYXRhKHRoaXMuX2RyYWdNZXRhRGF0YVR5cGUsIHRoaXMuX2RyYWdNZXRhRGF0YSk7XG4gICAgaWYgKHRoaXMuX2RhdGFUeXBlc0RhdGEpIHtcbiAgICAgICAgXy5lYWNoS2V5KHRoaXMuX2RhdGFUeXBlc0RhdGEsIGZ1bmN0aW9uKGRhdGEsIGRhdGFUeXBlKSB7XG4gICAgICAgICAgICBpZiAoZGF0YSkgZHQuc2V0RGF0YShkYXRhVHlwZSwgZGF0YSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9zZXRBbGxvd2VkRWZmZWN0cy5jYWxsKHRoaXMsIGR0KTtcbn1cblxuXG5mdW5jdGlvbiBvbkRyYWdFbmQoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIGlmIChfZHJhZ0lzRGlzYWJsZWQuY2FsbCh0aGlzLCBldmVudCkpIHJldHVybjtcblxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHZhciBkdCA9IG5ldyBEcmFnRHJvcChldmVudCk7XG4gICAgRHJhZ0Ryb3Auc2VydmljZS5wb3N0TWVzc2FnZVN5bmMoJ2NvbXBsZXRlZHJhZ2Ryb3AnLCB7XG4gICAgICAgIGV2ZW50VHlwZTogJ2RyYWdlbmQnLFxuICAgICAgICBkcmFnRHJvcDogZHQsXG4gICAgICAgIGRyYWdGYWNldDogdGhpc1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9zZXRBbGxvd2VkRWZmZWN0cyhEcmFnRHJvcCkge1xuICAgIHZhciBlZmZlY3RzID0gXy5yZXN1bHQodGhpcy5jb25maWcuYWxsb3dlZEVmZmVjdHMsIHRoaXMub3duZXIpO1xuICAgIERyYWdEcm9wLnNldEFsbG93ZWRFZmZlY3RzKGVmZmVjdHMpO1xufVxuXG5cbmZ1bmN0aW9uIHRhcmdldEluRHJhZ0hhbmRsZSgpIHtcbiAgICByZXR1cm4gISB0aGlzLl9kcmFnSGFuZGxlIHx8IHRoaXMuX2RyYWdIYW5kbGUuY29udGFpbnModGhpcy5fX21vdXNlRG93blRhcmdldCk7XG59XG5cblxuZnVuY3Rpb24gX2RyYWdJc0Rpc2FibGVkKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9mZikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwiY29tcG9uZW50cy1mYWNldHMtZHJvcFwiPjwvYT5cbi8vICMjI2Ryb3AgZmFjZXRcblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgRE9NRXZlbnRzU291cmNlID0gcmVxdWlyZSgnLi4vbXNnX3NyYy9kb21fZXZlbnRzJylcbiAgICAsIERyb3BNc2dBUEkgPSByZXF1aXJlKCcuLi9tc2dfYXBpL2Ryb3AnKVxuICAgICwgRHJhZ0Ryb3AgPSByZXF1aXJlKCcuLi8uLi91dGlsL2RyYWdkcm9wJylcbiAgICAsIERyb3BFcnJvciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZXJyb3InKS5Ecm9wXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIF9oYW5kbGVEcm9wRGVwZW5kZW5jeTtcblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5mYWNldHMuZ2V0KCdEcm9wJylgXG4gKiBGYWNldCBmb3IgY29tcG9uZW50cyB0aGF0IGNhbiBhY2NlcHQgZHJvcHNcbiAqIERyb3AgZmFjZXQgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnM6XG4gKlxuICogIC0gYWxsb3cgLSBhbiBvYmplY3QgdGhhdCB3aWxsIGRlZmluZSBhbGxvd2VkIGRhdGEgdHlwZXMgZHVyaW5nIGRyYWcgKGBkcmFnZW50ZXJgIGFuZCBgZHJhZ292ZXJgIGV2ZW50cykgd2l0aCB0aGVzZSBwcm9wZXJ0aWVzOlxuICogICAgICAtIGNvbXBvbmVudHM6IGB0cnVlYCBieSBkZWZhdWx0IChhbGwgY29tcG9uZW50cyB3aWxsIGJlIGFjY2VwdGVkKVxuICogICAgICAgICAgICAgICAgICAgICAgICBPUiBzdHJpbmcgd2l0aCBhbGxvd2VkIGNvbXBvbmVudCBjbGFzc1xuICogICAgICAgICAgICAgICAgICAgICAgICBPUiBsaXN0IG9mIGFsbG93ZWQgY29tcG9uZW50cyBjbGFzc2VzIChzdHJpbmdzKVxuICogICAgICAgICAgICAgICAgICAgICAgICBPUiBtYXAgd2l0aCBhbGxvd2VkIGNsYXNzZXMgaW4ga2V5cyBhbmQgYHRydWVgL3Rlc3QgZnVuY3Rpb25zIGluIHZhbHVlc1xuICogICAgICAgICAgICAgICAgICAgICAgICBPUiB0ZXN0IGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBwYXNzZWQgb2JqZWN0IGRlZmluZWQgYmVsb3dcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1IgYGZhbHNlYCB0byBOT1QgYWNjZXB0IGNvbXBvbmVudHNcbiAqICAgICAgLSBkYXRhVHlwZXM6ICBgZmFsc2VgIGJ5IGRlZmF1bHQgKG5vIG90aGVyIGRhdGEgdHlwZXMgd2lsbCBiZSBhY2NlcHRlZClcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1Igc3RyaW5nIHdpdGggYWxsb3dlZCBkYXRhIHR5cGVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1IgbGlzdCBvZiBhZGRpdGlvbmFsIGRhdGEgdHlwZXMgdGhhdCBhIGRyb3AgdGFyZ2V0IHdvdWxkIGFjY2VwdFxuICogICAgICAgICAgICAgICAgICAgICAgICBPUiB0ZXN0IGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBwYXNzZWQgRHJhZ0Ryb3Agb2JqZWN0XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIE9SIGB0cnVlYCB0byBhY2NlcHQgYWxsIGRhdGEgdHlwZXNcbiAqICAgICAgLSBjaGVja1BhcmVudDogYGZhbHNlYCBieSBkZWZhdWx0XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIE9SIGB0cnVlYCB3aWxsIGNhbGwgcGFyZW50IGNvbXBvbmVudCBkcm9wIGFsbG93IHRvIGNoZWNrIGlmIHBhcmVudCBjb21wb25lbnQgd2lsbCBhY2NlcHQgdGhlIGNvbXBvbmVudFxuICogICAgICBJZiB0ZXN0IGZ1bmN0aW9ucyBhcmUgdXNlZCwgdGhleSBzaG91bGQgcmV0dXJuIGJvb2xlYW4uIEVhY2ggdGVzdCBmdW5jdGlvbiBjYW4gYWxzbyBzZXQgZHJvcCBlZmZlY3QgYXMgZGVmaW5lZCBoZXJlOlxuICogICAgICBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRGF0YVRyYW5zZmVyI2Ryb3BFZmZlY3QuMjguMjlcbiAqICAgICAgU2V0dGluZyBkcm9wIGVmZmVjdCB0aGF0IGlzIG5vdCBhbGxvd2VkIGJ5IGRyYWdnZWQgb2JqZWN0IHdpbGwgcHJldmVudCBkcm9wLlxuICogICAgICBUZXN0IGZ1bmN0aW9ucyBmb3IgY29tcG9uZW50cyB3aWxsIGJlIHBhc3NlZCB0aGUgb3duZXIgb2YgRHJvcCBmYWNldCBhcyBjb250ZXh0LCB0aGUgb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBwb3NzaWJsZSBwcm9wZXJ0aWVzIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXI6XG4gKiAgICAgICAgICBjb21wQ2xhc3MgLSBuYW1lIG9mIGNvbXBvbmVudCBjbGFzcyBhcyBzdG9yZWQgaW4gcmVnaXN0cnlcbiAqICAgICAgICAgIGNvbXBOYW1lIC0gbmFtZSBvZiBjb21wb25lbnQgKGFsbCBsb3dlcmNhc2UpXG4gKiAgICAgICAgICBwYXJhbXMgLSBwYXJhbWV0ZXJzIGFzIGVuY29kZWQgaW4gZGF0YVR5cGUsIHBhc3NlZCB0byBgbWlsby51dGlsLmRyYWdEcm9wLnNldENvbXBvbmVudE1ldGFgIGJ5IERyYWcgZmFjZXRcbiAqICAgICAgICAgIG1ldGFEYXRhVHlwZSAtIGRhdGEgdHlwZSBvZiB0aGUgZGF0YSB0aGF0IGhhcyBjb21wQ2xhc3MsIGNvbXBOYW1lIGFuZCBwYXJhbXMgZW5jb2RlZFxuICpcbiAqICAgICAgLi4uIGFuZCBEcmFnRHJvcCBpbnN0YW5jZSBhcyB0aGUgc2Vjb25kIHBhcmFtZXRlclxuICpcbiAqICAgICAgVGVzdCBmdW5jdGlvbiBmb3Igb3RoZXIgZGF0YSB0eXBlcyB3aWxsIGJlIHBhc3NlZCB0aGUgb3duZXIgb2YgRHJvcCBmYWNldCBhcyBjb250ZXh0IGFuZCBEcmFnRHJvcCBpbnN0YW5jZSBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyXG4gKlxuICogIyMjI0V2ZW50cyMjIyNcbiAqXG4gKiBJbiBhZGRpdGlvbiB0byBjb25maWd1cmluZyBhbGxvd2VkIGNvbXBvbmVudHMgYW5kIGRhdGEgdHlwZXMsIGNvbXBvbmVudHMgY2xhc3NlcyBzaG91bGQgc3Vic2NyaWJlIHRvIGV2ZW50cy5cbiAqIEF0IHRoZSB2ZXJ5IGxlYXN0LCB0aGV5IHNob3VsZCBzdWJzY3JpYmUgdG8gYGRyb3BgIGV2ZW50LlxuICpcbiAqIERyb3AgZmFjZXQgZW1pdHMgZHJhZ2luL2RyYWdvdXQgbWVzc2FnZXMgdGhhdCBhcmUgZW1pdHRlZCB3aGVuZXZlciBhY3R1YWwgY29tcG9uZW50IGVsZW1lbnQgaXMgZW50ZXJlZCBvciBsZWZ0XG4gKiAod2hpY2ggaXMgZGlmZmVyZW50IGZyb20gZHJhZ2VudGVyIGFuZCBkcmFnbGVhdmUgbWVzc2FnZXMgdGhhdCBhcmUgZW1pdHRlZCB3aGVuZXZlciBhbnkgY2hpbGQgZWxlbWVudCBpcyBlbnRlcmVkIG9yIGxlZnQsIGFzIGxvbmcgYXMgZXZlbnQgYnViYmxlcyB1cClcbiAqIElmIGNoaWxkIGNvbXBvbmVudCBoYXMgZHJvcCBmYWNldCBhdHRhY2hlZCwgZHJhZ291dCB3aWxsIGJlIGVtaXR0ZWQgb24gdGhlIGN1cnJlbnQgY29tcG9uZW50IHdoZW4gdGhlIGNoaWxkIGlzIGVudGVyZWQuXG4gKlxuICogWW91IGNhbiBzZWUgdGhlIGRlbW9uc3RyYXRpb24gb2Ygd2hlbiBtZXNzYWdlcyBhcmUgZW1pdHRlZCBbaGVyZV0oaHR0cDovL2pzYmluLmNvbS9idXFvdi82KVxuICogXG4gKi9cbnZhciBEcm9wID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0Ryb3AnKTtcblxuXG5fLmV4dGVuZFByb3RvKERyb3AsIHtcbiAgICBpbml0OiBEcm9wJGluaXQsXG4gICAgc3RhcnQ6IERyb3Akc3RhcnRcbiAgICAvLyBfcmVhdHRhY2g6IF9yZWF0dGFjaEV2ZW50c09uRWxlbWVudENoYW5nZVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChEcm9wKTtcblxubW9kdWxlLmV4cG9ydHMgPSBEcm9wO1xuXG5cbmZ1bmN0aW9uIERyb3AkaW5pdCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMuX2NyZWF0ZU1lc3NhZ2VTb3VyY2VXaXRoQVBJKERPTUV2ZW50c1NvdXJjZSwgbmV3IERyb3BNc2dBUEkpO1xufVxuXG5cbmZ1bmN0aW9uIERyb3Akc3RhcnQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLnN0YXJ0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5vd25lci5lbC5jbGFzc0xpc3QuYWRkKCdjYy1tb2R1bGUtcmVsYXRpdmUnKTtcbiAgICB0aGlzLm9uTWVzc2FnZXMoe1xuICAgICAgICAnZHJhZ2VudGVyIGRyYWdvdmVyJzogb25EcmFnZ2luZyxcbiAgICAgICAgJ2Ryb3AnOiBvbkRyb3AsXG4gICAgICAgICdkcmFnZW50ZXIgZHJhZ292ZXIgZHJhZ2xlYXZlIGRyb3AgZHJhZ2luIGRyYWdvdXQnOiBwb3N0VG9TZXJ2aWNlXG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gb25EcmFnZ2luZyhldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgdmFyIGR0ID0gbmV3IERyYWdEcm9wKGV2ZW50KTtcblxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBpZiAoISBfaGFuZGxlRHJvcERlcGVuZGVuY3kuY2FsbCh0aGlzLCBkdCkpXG4gICAgICAgIGR0LnNldERyb3BFZmZlY3QoJ25vbmUnKTtcbn1cblxuXG5mdW5jdGlvbiBvbkRyb3AoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHZhciBkdCA9IG5ldyBEcmFnRHJvcChldmVudCk7XG4gICAgRHJhZ0Ryb3Auc2VydmljZS5wb3N0TWVzc2FnZVN5bmMoJ2RyYWdkcm9wY29tcGxldGVkJywge1xuICAgICAgICBldmVudFR5cGU6ICdkcm9wJyxcbiAgICAgICAgZHJhZ0Ryb3A6IGR0LFxuICAgICAgICBkcm9wRmFjZXQ6IHRoaXMsXG4gICAgICAgIGNvbXBvbmVudDogdGhpcy5vd25lclxuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIHBvc3RUb1NlcnZpY2UoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIERyYWdEcm9wLnNlcnZpY2UucG9zdE1lc3NhZ2VTeW5jKGV2ZW50VHlwZSwge1xuICAgICAgICBldmVudDogZXZlbnQsXG4gICAgICAgIGRyb3BGYWNldDogdGhpcyxcbiAgICAgICAgY29tcG9uZW50OiB0aGlzLm93bmVyXG4gICAgfSk7XG59XG5cblxuX2hhbmRsZURyb3BEZXBlbmRlbmN5ID0gXy50aHJvdHRsZShfaGFuZGxlRHJvcERlcGVuZGVuY3lOb3Rocm90dGxlLCA1MCk7XG5mdW5jdGlvbiBfaGFuZGxlRHJvcERlcGVuZGVuY3lOb3Rocm90dGxlKGR0LCBvcmlnaW5hbERyb3BDb21wb25lbnQpIHtcbiAgICB2YXIgYWxsb3cgPSB0aGlzLmNvbmZpZy5hbGxvd1xuICAgICAgICAsIHBhcmVudEFsbG93ZWQgPSB0cnVlO1xuXG4gICAgb3JpZ2luYWxEcm9wQ29tcG9uZW50ID0gb3JpZ2luYWxEcm9wQ29tcG9uZW50IHx8IHRoaXMub3duZXI7XG5cbiAgICBpZiAoYWxsb3cgJiYgYWxsb3cuY2hlY2tQYXJlbnQpIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMub3duZXIuZ2V0U2NvcGVQYXJlbnQoJ0Ryb3AnKTtcbiAgICAgICAgaWYgKHBhcmVudClcbiAgICAgICAgICAgIHBhcmVudEFsbG93ZWQgPSBfaGFuZGxlRHJvcERlcGVuZGVuY3lOb3Rocm90dGxlLmNhbGwocGFyZW50LmRyb3AsIGR0LCBvcmlnaW5hbERyb3BDb21wb25lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJlbnRBbGxvd2VkICYmIF9pc0Ryb3BBbGxvd2VkLmNhbGwodGhpcywgZHQsIG9yaWdpbmFsRHJvcENvbXBvbmVudCk7XG59XG5cblxuLyoqXG4gKiBDaGVja3MgaWYgZHJvcCBpcyBhbGxvd2VkIGJhc2VkIG9uIGZhY2V0IGNvbmZpZ3VyYXRpb24gKHNlZSBhYm92ZSlcbiAqIFxuICogQHBhcmFtIHtEcmFnRHJvcH0gZHRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIF9pc0Ryb3BBbGxvd2VkKGR0LCBvcmlnaW5hbERyb3BDb21wb25lbnQpIHtcbiAgICB2YXIgYWxsb3cgPSB0aGlzLmNvbmZpZy5hbGxvdztcblxuICAgIGlmIChkdC5pc0NvbXBvbmVudCgpKSB7XG4gICAgICAgIHZhciBhbGxvd0NvbXBzID0gYWxsb3cgJiYgYWxsb3cuY29tcG9uZW50c1xuICAgICAgICAgICAgLCBtZXRhID0gZHQuZ2V0Q29tcG9uZW50TWV0YSgpO1xuXG4gICAgICAgIHN3aXRjaCAodHlwZW9mIGFsbG93Q29tcHMpIHtcbiAgICAgICAgICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYWxsb3dDb21wcztcbiAgICAgICAgICAgIC8vIGNvbXBvbmVudCBjbGFzc1xuICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWV0YSAmJiBtZXRhLmNvbXBDbGFzcyA9PSBhbGxvd0NvbXBzO1xuICAgICAgICAgICAgLy8gdGVzdCBmdW5jdGlvblxuICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgICAgICAgIHJldHVybiBhbGxvd0NvbXBzLmNhbGwodGhpcy5vd25lciwgbWV0YSwgZHQsIG9yaWdpbmFsRHJvcENvbXBvbmVudCk7XG4gICAgICAgICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFsbG93Q29tcHMpKVxuICAgICAgICAgICAgICAgICAgICAvLyBsaXN0IG9mIGFsbG93ZWQgY2xhc3Nlc1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWxsb3dDb21wcy5pbmRleE9mKG1ldGEgJiYgbWV0YS5jb21wQ2xhc3MpID49IDA7XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG1hcCBvZiBjbGFzczogYm9vbGVhbnx0ZXN0IGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXN0ID0gYWxsb3dDb21wc1ttZXRhICYmIG1ldGEuY29tcENsYXNzXTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhIF8ucmVzdWx0KHRlc3QsIHRoaXMub3duZXIsIG1ldGEsIGR0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBEcm9wRXJyb3IoJ0luY29ycmVjdCBhbGxvd2VkIGNvbXBvbmVudHMgaW4gY29uZmlnJyk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgZGF0YVR5cGVzID0gYWxsb3cgJiYgYWxsb3cuZGF0YVR5cGVzXG4gICAgICAgIHN3aXRjaCAodHlwZW9mIGRhdGFUeXBlcykge1xuICAgICAgICAgICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICAgICAgICAgIHJldHVybiBkdC50eXBlcy5pbmRleE9mKGRhdGFUeXBlcykgPj0gMDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRPRE8gdGVzdCBmb3Igb3RoZXIgZGF0YSB0eXBlc1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXInKVxuICAgICwgRE9NRXZlbnRzU291cmNlID0gcmVxdWlyZSgnLi4vbXNnX3NyYy9kb21fZXZlbnRzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0V2ZW50cycpYFxuICogQ29tcG9uZW50IGZhY2V0IHRoYXQgbWFuYWdlcyBzdWJzY3JpcHRpb25zIHRvIERPTSBldmVudHMgdXNpbmcgW01lc3Nlbmdlcl0oLi4vLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpIHdpdGggW0RPTUV2ZW50c1NvdXJjZV0oLi4vbXNnX3NyYy9kb21fZXZlbnRzLmpzLmh0bWwpLlxuICogQWxsIHB1YmxpYyBtZXRob2RzIG9mIE1lc3NlbmdlciBhbmQgYHRyaWdnZXJgIG1ldGhvZCBvZiBbRE9NRXZlbnRzU291cmNlXSguLi9tc2dfc3JjL2RvbV9ldmVudHMuanMuaHRtbCkgYXJlIHByb3hpZWQgZGlyZWN0bHkgdG8gdGhpcyBmYWNldC5cbiAqIEZvciBleGFtcGxlLCB0byBzdWJzY3JpYmUgdG8gYGNsaWNrYCBldmVudCB1c2U6XG4gKiBgYGBcbiAqIGNvbXBvbmVudC5mcmFtZS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAqICAgICAvLyAuLi5cbiAqIH0pO1xuICogYGBgXG4gKiBTZWUgW01lc3Nlbmdlcl0oLi4vLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpXG4gKi9cbnZhciBFdmVudHMgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnRXZlbnRzJyk7XG5cblxuLyoqXG4gKiAjIyMjRXZlbnRzIGZhY2V0IGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI0V2ZW50cyRpbml0KSAtIGNhbGxlZCBieSBjb25zdHJ1Y3RvciBhdXRvbWF0aWNhbGx5XG4gKi9cbl8uZXh0ZW5kUHJvdG8oRXZlbnRzLCB7XG4gICAgaW5pdDogRXZlbnRzJGluaXRcbiAgICAvLyBfcmVhdHRhY2g6IF9yZWF0dGFjaEV2ZW50c09uRWxlbWVudENoYW5nZVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChFdmVudHMpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50cztcblxuXG4vKipcbiAqIEV4cG9zZSBET01FdmVudHNTb3VyY2UgdHJpZ2dlciBtZXRob2Qgb24gRXZlbnRzIHByb3RvdHlwZVxuICovXG52YXIgTVNHX1NPVVJDRV9LRVkgPSAnX2RvbUV2ZW50c1NvdXJjZSdcbkRPTUV2ZW50c1NvdXJjZS51c2VXaXRoKEV2ZW50cywgTVNHX1NPVVJDRV9LRVksIFsndHJpZ2dlciddKTtcblxuXG4vKipcbiAqIEV2ZW50cyBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWx6ZXMgZmFjZXQsIGNvbm5lY3RzIERPTUV2ZW50c1NvdXJjZSB0byBmYWNldCdzIG1lc3NlbmdlclxuICovXG5mdW5jdGlvbiBFdmVudHMkaW5pdCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgdmFyIGRvbUV2ZW50c1NvdXJjZSA9IG5ldyBET01FdmVudHNTb3VyY2UodGhpcywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMub3duZXIpO1xuICAgIHRoaXMuX3NldE1lc3NhZ2VTb3VyY2UoZG9tRXZlbnRzU291cmNlKTtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsIE1TR19TT1VSQ0VfS0VZLCBkb21FdmVudHNTb3VyY2UpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uLy4uL21lc3NlbmdlcicpXG4gICAgLCBGcmFtZU1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuLi9tc2dfc3JjL2ZyYW1lJylcbiAgICAsIGRvbUV2ZW50c0NvbnN0cnVjdG9ycyA9IHJlcXVpcmUoJy4uLy4uL3NlcnZpY2VzL2RlX2NvbnN0cnMnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuZmFjZXRzLmdldCgnRnJhbWUnKWBcbiAqIENvbXBvbmVudCBmYWNldCB0aGF0IHNpbXBsaWZpZXMgc2VuZGluZyB3aW5kb3cgbWVzc2FnZXMgdG8gaWZyYW1lIGFuZCBzdWJzY3JpYmluZyB0byBtZXNzYWdlcyBvbiBpbm5lciB3aW5kb3cgb2YgaWZyYW1lLlxuICogQWxsIHB1YmxpYyBtZXRob2RzIG9mIE1lc3NlbmdlciBhbmQgYHRyaWdnZXJgIG1ldGhvZCBvZiBbRnJhbWVNZXNzYWdlU291cmNlXSguLi9tc2dfc3JjL2ZyYW1lLmpzLmh0bWwpIGFyZSBwcm94aWVkIGRpcmVjdGx5IHRvIHRoaXMgZmFjZXQuXG4gKiBGb3IgZXhhbXBsZSwgdG8gc2VuZCBjdXN0b20gbWVzc2FnZSB0byBpZnJhbWUgd2luZG93IHVzZTpcbiAqIGBgYFxuICogaWZyYW1lQ29tcG9uZW50LmZyYW1lLnRyaWdnZXIoJ215bWVzc2FnZScsIG15RGF0YSk7XG4gKiBgYGBcbiAqIFRvIHN1YnNjcmliZSB0byB0aGlzIG1lc3NhZ2VzIGluc2lkZSBmcmFtZSB1c2UgKHdpdGggbWlsbyAtIHNlZSBbbWlsby5tYWlsXSguLi8uLi9tYWlsL2luZGV4LmpzLmh0bWwpKTpcbiAqIGBgYFxuICogbWlsby5tYWlsLm9uKCdtZXNzYWdlOm15bWVzc2FnZScsIGZ1bmN0aW9uKG1zZ1R5cGUsIG1zZ0RhdGEpIHtcbiAqICAgICAvLyBkYXRhIGlzIGluc2lkZSBvZiB3aW5kb3cgbWVzc2FnZSBkYXRhXG4gKiAgICAgLy8gbXNnVHlwZSA9PSAnbWVzc2FnZTpteW1lc3NhZ2UnXG4gKiAgICAgdmFyIG15RGF0YSA9IG1zZ0RhdGEuZGF0YTtcbiAqICAgICAvLyAuLi4gYXBwIGxvZ2ljIGhlcmVcbiAqIH0pO1xuICogYGBgXG4gKiBvciB3aXRob3V0IG1pbG86XG4gKiBgYGBcbiAqIHdpbmRvdy5hdHRhY2hFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24obWVzc2FnZSkge1xuICogICAgIHZhciBtc2dUeXBlID0gbWVzc2FnZS50eXBlOyAvLyBlLmcuLCAnbXltZXNzYWdlJ1xuICogICAgIHZhciBteURhdGEgPSBtZXNzYWdlLmRhdGE7XG4gKiAgICAgLy8gLi4uIG1lc3NhZ2Ugcm91dGluZyBhbmQgY29kZSBoZXJlXG4gKiB9KTtcbiAqIGBgYFxuICogTWlsbyBkb2VzIHJvdXRpbmcgYmFzZWQgb24gc2VudCBtZXNzYWdlIHR5cGUgYXV0b21hdGljYWxseS5cbiAqIFNlZSBbTWVzc2VuZ2VyXSguLi8uLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCkgYW5kIFttaWxvLm1haWxdKC4uLy4uL21haWwvaW5kZXguanMuaHRtbCkuXG4gKi9cbiB2YXIgRnJhbWUgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnRnJhbWUnKTtcblxuXG4vKipcbiAqIENhbGxzIHBhc3NlZCBmdW5jdGlvbiB3aGVuIGZyYW1lIERPTSBiZWNvbWVzIHJlYWR5LiBJZiBhbHJlYWR5IHJlYWR5IGNhbGxzIGltbWVkaWF0ZWx5XG4gKi9cbnZhciBGcmFtZSR3aGVuUmVhZHkgPSBfbWFrZVdoZW5SZWFkeUZ1bmMoRnJhbWUkaXNSZWFkeSwgJ2RvbXJlYWR5Jyk7XG5cbi8qKlxuICogQ2FsbHMgcGFzc2VkIGZ1bmN0aW9uIHdoZW4gZnJhbWUgbWlsbyBiZWNvbWVzIHJlYWR5LiBJZiBhbHJlYWR5IHJlYWR5IGNhbGxzIGltbWVkaWF0ZWx5XG4gKi9cbnZhciBGcmFtZSR3aGVuTWlsb1JlYWR5ID0gX21ha2VXaGVuUmVhZHlGdW5jKEZyYW1lJGlzTWlsb1JlYWR5LCAnbWVzc2FnZTptaWxvcmVhZHknKTtcblxuXG4vKipcbiAqICMjIyNFdmVudHMgZmFjZXQgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtpbml0XSgjRnJhbWUkaW5pdCkgLSBjYWxsZWQgYnkgY29uc3RydWN0b3IgYXV0b21hdGljYWxseVxuICovXG5fLmV4dGVuZFByb3RvKEZyYW1lLCB7XG4gICAgaW5pdDogRnJhbWUkaW5pdCxcbiAgICBzdGFydDogRnJhbWUkc3RhcnQsXG4gICAgZGVzdHJveTogRnJhbWUkZGVzdHJveSxcbiAgICBnZXRXaW5kb3c6IEZyYW1lJGdldFdpbmRvdyxcbiAgICBpc1JlYWR5OiBGcmFtZSRpc1JlYWR5LFxuICAgIHdoZW5SZWFkeTogRnJhbWUkd2hlblJlYWR5LFxuICAgIGlzTWlsb1JlYWR5OiBGcmFtZSRpc01pbG9SZWFkeSxcbiAgICB3aGVuTWlsb1JlYWR5OiBGcmFtZSR3aGVuTWlsb1JlYWR5LFxuICAgIG1pbG86IEZyYW1lJG1pbG9cbiAgICAvLyBfcmVhdHRhY2g6IF9yZWF0dGFjaEV2ZW50c09uRWxlbWVudENoYW5nZVxufSk7XG5cblxuZmFjZXRzUmVnaXN0cnkuYWRkKEZyYW1lKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGcmFtZTtcblxuXG4vKipcbiAqIEV4cG9zZSBGcmFtZU1lc3NhZ2VTb3VyY2UgdHJpZ2dlciBtZXRob2Qgb24gRXZlbnRzIHByb3RvdHlwZVxuICovXG52YXIgTVNHX1NPVVJDRV9LRVkgPSAnX21lc3NhZ2VTb3VyY2UnO1xuRnJhbWVNZXNzYWdlU291cmNlLnVzZVdpdGgoRnJhbWUsIE1TR19TT1VSQ0VfS0VZLCBbJ3RyaWdnZXInXSk7XG5cblxuLyoqXG4gKiBGcmFtZSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWx6ZXMgZmFjZXQsIGNvbm5lY3RzIEZyYW1lTWVzc2FnZVNvdXJjZSB0byBmYWNldCdzIG1lc3NlbmdlclxuICovXG5mdW5jdGlvbiBGcmFtZSRpbml0KCkge1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgXG4gICAgdmFyIG1lc3NhZ2VTb3VyY2UgPSBuZXcgRnJhbWVNZXNzYWdlU291cmNlKHRoaXMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aGlzLm93bmVyKTtcbiAgICB0aGlzLl9zZXRNZXNzYWdlU291cmNlKG1lc3NhZ2VTb3VyY2UpO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBNU0dfU09VUkNFX0tFWSwgbWVzc2FnZVNvdXJjZSk7XG59XG5cblxuLyoqXG4gKiBGcmFtZSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEVtaXRzIGZyYW1lbG9hZGVkIGV2ZW50IHdoZW4gcmVhZHkuXG4gKi9cbmZ1bmN0aW9uIEZyYW1lJHN0YXJ0KCkge1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5zdGFydC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBtaWxvKHBvc3REb21SZWFkeSk7XG5cbiAgICBmdW5jdGlvbiBwb3N0RG9tUmVhZHkoZXZlbnQpIHtcbiAgICAgICAgc2VsZi5wb3N0TWVzc2FnZSgnZG9tcmVhZHknLCBldmVudCk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIEZyYW1lJGRlc3Ryb3koKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG4vKipcbiAqIEZyYW1lIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0cmlldmVzIHRoZSBpbnRlcm5hbCB3aW5kb3cgb2YgdGhlIGZyYW1lIFxuICpcbiAqIEBwYXJhbSB7V2luZG93fVxuICovXG5mdW5jdGlvbiBGcmFtZSRnZXRXaW5kb3coKSB7XG4gICAgcmV0dXJuIHRoaXMub3duZXIuZWwuY29udGVudFdpbmRvdztcbn1cblxuXG4vKipcbiAqIEZyYW1lIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBkb2N1bWVudC5yZWFkeVN0YXRlIGlmIGZyYW1lIGRvdW1lbnQgc3RhdGUgaXMgJ2ludGVyYWN0aXZlJyBvciAnY29tcGxldGUnLCBmYWxzZSBvdGhlcndpc2VcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd8Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gRnJhbWUkaXNSZWFkeSgpIHtcbiAgICB2YXIgcmVhZHlTdGF0ZSA9IHRoaXMuZ2V0V2luZG93KCkuZG9jdW1lbnQucmVhZHlTdGF0ZTtcbiAgICByZXR1cm4gIHJlYWR5U3RhdGUgIT0gJ2xvYWRpbmcnID8gcmVhZHlTdGF0ZSA6IGZhbHNlO1xufVxuXG5cbi8qKlxuICogRnJhbWUgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRydWUgaWYgbWlsbyBpcyBsb2FkZWQgYW5kIGhhcyBmaW5pc2hlZCBpbml0aWFsaXppbmcgaW5zaWRlIHRoZSBmcmFtZVxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIEZyYW1lJGlzTWlsb1JlYWR5KCkge1xuICAgIHZhciBmcmFtZU1pbG8gPSB0aGlzLmdldFdpbmRvdygpLm1pbG87XG4gICAgcmV0dXJuIHRoaXMuaXNSZWFkeSgpICYmIGZyYW1lTWlsbyAmJiBmcmFtZU1pbG8ubWlsb192ZXJzaW9uO1xufVxuXG5cbi8qKlxuICogR2l2ZXMgYWNjZXNzIHRvIG1pbG8gaW4gdGhlIGZyYW1lIChhc3N1bWluZyBpdCBpcyBsb2FkZWQgdGhlcmUpXG4gKiBDYWxscyBmdW5jdGlvbiB3aGVuIGJvdGggbWlsbyBhbmQgRE9NIGFyZSByZWFkeSBpZiBmdW5jdGlvbiBpcyBwYXNzZWQuXG4gKiBSZXR1cm5zIHRoZSByZWZlcmVuY2UgdG8gbWlsbyBpbnNpZGUgdGhlIGZyYW1lIGlmIHRoZSB3aW5kb3cgaXMgYWxyZWFkeSBhdmFpbGFibGUuXG4gKiBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gbWlsbyBhbmQgRE9NIGFyZSByZWFkeSBpbiB0aGUgZnJhbWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSByZWZlcmVuY2UgdG8gbWlsbyBpbiB0aGUgZnJhbWUgXG4gKi9cbmZ1bmN0aW9uIEZyYW1lJG1pbG8oZnVuYykge1xuICAgIGlmICh0eXBlb2YgZnVuYyA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdGhpcy53aGVuTWlsb1JlYWR5KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgc2VsZi5nZXRXaW5kb3coKS5taWxvKGZ1bmMpXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgd2luID0gdGhpcy5nZXRXaW5kb3coKTtcbiAgICByZXR1cm4gd2luICYmIHdpbi5taWxvO1xufVxuXG5cbmZ1bmN0aW9uIF9tYWtlV2hlblJlYWR5RnVuYyhpc1JlYWR5RnVuYywgZXZlbnQpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gRnJhbWVfd2hlblJlYWR5RnVuYyhmdW5jKSB7IC8vICwgYXJndW1lbnRzXG4gICAgICAgIHZhciBzZWxmID0gdGhpc1xuICAgICAgICAgICAgLCBhcmdzID0gXy5zbGljZShhcmd1bWVudHMsIDEpO1xuICAgICAgICBpZiAoaXNSZWFkeUZ1bmMuY2FsbCh0aGlzKSlcbiAgICAgICAgICAgIGNhbGxGdW5jKCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRoaXMub24oZXZlbnQsIGNhbGxGdW5jKTtcblxuICAgICAgICBmdW5jdGlvbiBjYWxsRnVuYygpIHtcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgTW9kZWwgPSByZXF1aXJlKCcuLi8uLi9tb2RlbCcpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIG1pbG9NYWlsID0gcmVxdWlyZSgnLi4vLi4vc2VydmljZXMvbWFpbCcpO1xuXG5cbnZhciBJdGVtRmFjZXQgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnSXRlbScpO1xuXG5fLmV4dGVuZFByb3RvKEl0ZW1GYWNldCwge1xuICAgIGdldFN0YXRlOiBJdGVtRmFjZXQkZ2V0U3RhdGUsXG4gICAgc2V0U3RhdGU6IEl0ZW1GYWNldCRzZXRTdGF0ZSxcbiAgICBnZXRJbmRleDogSXRlbUZhY2V0JGdldEluZGV4LFxuICAgIHNldEluZGV4OiBJdGVtRmFjZXQkc2V0SW5kZXgsXG4gICAgcmVtb3ZlSXRlbTogSXRlbUZhY2V0JHJlbW92ZUl0ZW0sXG4gICAgZXh0cmFjdEl0ZW06IEl0ZW1GYWNldCRleHRyYWN0SXRlbSxcbiAgICByZXF1aXJlOiBbJ0NvbnRhaW5lcicsICdEb20nLCAnRGF0YSddXG59KTtcblxuZmFjZXRzUmVnaXN0cnkuYWRkKEl0ZW1GYWNldCk7XG5cbm1vZHVsZS5leHBvcnRzID0gSXRlbUZhY2V0O1xuXG5cbmZ1bmN0aW9uIEl0ZW1GYWNldCRnZXRTdGF0ZSgpIHtcbiAgICByZXR1cm4geyBzdGF0ZToge1xuICAgICAgICBpbmRleDogdGhpcy5nZXRJbmRleCgpXG4gICAgfX07XG59XG5cblxuZnVuY3Rpb24gSXRlbUZhY2V0JHNldFN0YXRlKHN0YXRlKSB7XG4gICAgdGhpcy5zZXRJbmRleChzdGF0ZS5zdGF0ZS5pbmRleCk7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBvd25lciBjb21wb25lbnQgaW4gaXQncyBwYXJlbnQgbGlzdCBjb21wb25lbnRcbiAqIEByZXR1cm4ge0ludGVnZXJ9IFRoZSBpbmRleFxuICovXG5mdW5jdGlvbiBJdGVtRmFjZXQkZ2V0SW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXg7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgdGhlIGluZGV4IG9mIHRoaXMgY29tcG9uZW50XG4gKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IFRoZSBpbmRleCB0byBiZSBzZXRcbiAqL1xuZnVuY3Rpb24gSXRlbUZhY2V0JHNldEluZGV4KGluZGV4KSB7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xufVxuXG5cbi8qKlxuICogSXRlbUZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmVtb3ZlcyBjb21wb25lbnQgZnJvbSB0aGUgbGlzdCwgY29tcG9uZW50IGdldHMgZGVzdHJveWVkXG4gKi9cbmZ1bmN0aW9uIEl0ZW1GYWNldCRyZW1vdmVJdGVtKCkge1xuICAgIC8vIHRoaXMubGlzdCBhbmQgdGhpcy5pbmRleCBhcmUgc2V0IGJ5IHRoZSBsaXN0IHdoZW4gdGhlIGl0ZW0gaXMgYWRkZWRcbiAgICB0aGlzLmxpc3QucmVtb3ZlSXRlbSh0aGlzLmluZGV4KTtcbn1cblxuXG4vKipcbiAqIEl0ZW1GYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJlbW92ZXMgY29tcG9uZW50IGZyb20gdGhlIGxpc3QsIGNvbXBvbmVudCBpcyBOT1QgZGVzdHJveWVkXG4gKi9cbmZ1bmN0aW9uIEl0ZW1GYWNldCRleHRyYWN0SXRlbSgpIHtcbiAgICB0aGlzLmxpc3QuZXh0cmFjdEl0ZW0odGhpcy5pbmRleCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBtaWxvTWFpbCA9IHJlcXVpcmUoJy4uLy4uL3NlcnZpY2VzL21haWwnKVxuICAgICwgbWlsb0JpbmRlciA9IHJlcXVpcmUoJy4uLy4uL2JpbmRlcicpXG4gICAgLCBtaWxvVXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKVxuICAgICwgTGlzdEVycm9yID0gbWlsb1V0aWwuZXJyb3IuTGlzdFxuICAgICwgbG9nZ2VyID0gbWlsb1V0aWwubG9nZ2VyXG4gICAgLCBkb1QgPSByZXF1aXJlKCdkb3QnKVxuICAgICwgY2hlY2sgPSBtaWxvVXRpbC5jaGVja1xuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgZG9tVXRpbHMgPSBtaWxvVXRpbC5kb21cbiAgICAsIG1pbG9Db25maWcgPSByZXF1aXJlKCcuLi8uLi9jb25maWcnKTtcblxuXG52YXIgTElTVF9TQU1QTEVfQ1NTX0NMQVNTID0gJ21sLWxpc3QtaXRlbS1zYW1wbGUnO1xuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0xpc3QnKWBcbiAqIEZhY2V0IGVuYWJsaW5nIGxpc3QgZnVuY3Rpb25hbGl0eVxuICovXG52YXIgTGlzdCA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdMaXN0Jyk7XG5cbl8uZXh0ZW5kUHJvdG8oTGlzdCwge1xuICAgIGluaXQ6IExpc3QkaW5pdCxcbiAgICBzdGFydDogTGlzdCRzdGFydCxcbiAgICBkZXN0cm95OiBMaXN0JGRlc3Ryb3ksXG5cbiAgICByZXF1aXJlOiBbJ0NvbnRhaW5lcicsICdEb20nLCAnRGF0YSddLFxuICAgIF9pdGVtUHJldmlvdXNDb21wb25lbnQ6IF9pdGVtUHJldmlvdXNDb21wb25lbnQsXG5cbiAgICBpdGVtOiBMaXN0JGl0ZW0sXG4gICAgY291bnQ6IExpc3QkY291bnQsXG4gICAgY29udGFpbnM6IExpc3QkY29udGFpbnMsXG4gICAgYWRkSXRlbTogTGlzdCRhZGRJdGVtLFxuICAgIGFkZEl0ZW1zOiBMaXN0JGFkZEl0ZW1zLFxuICAgIHJlcGxhY2VJdGVtOiBMaXN0JHJlcGxhY2VJdGVtLFxuICAgIHJlbW92ZUl0ZW06IExpc3QkcmVtb3ZlSXRlbSxcbiAgICBleHRyYWN0SXRlbTogTGlzdCRleHRyYWN0SXRlbSxcbiAgICBlYWNoOiBMaXN0JGVhY2gsXG4gICAgX3NldEl0ZW06IExpc3QkX3NldEl0ZW0sXG4gICAgX3JlbW92ZUl0ZW06IExpc3QkX3JlbW92ZUl0ZW0sXG4gICAgX2FkZEl0ZW06IExpc3QkX2FkZEl0ZW0sXG4gICAgX2FkZEl0ZW1zOiBMaXN0JF9hZGRJdGVtcyxcbiAgICBfY3JlYXRlQ2FjaGVUZW1wbGF0ZTogTGlzdCRfY3JlYXRlQ2FjaGVUZW1wbGF0ZSxcbiAgICBfdXBkYXRlRGF0YVBhdGhzOiBMaXN0JF91cGRhdGVEYXRhUGF0aHNcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoTGlzdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTGlzdDtcblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogSW5pdGlhbGl6ZWQgTGlzdCBmYWNldCBpbnN0YW5jZSBhbmQgc2V0cyB1cCBpdGVtIHByb3BlcnRpZXMuXG4gKi9cbmZ1bmN0aW9uIExpc3QkaW5pdCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgIF9saXN0SXRlbXM6IFtdLFxuICAgICAgICBfbGlzdEl0ZW1zSGFzaDoge31cbiAgICB9KTtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdpdGVtU2FtcGxlJywgbnVsbCwgXy5XUklUKTtcbn1cblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU3RhcnRzIHRoZSBMaXN0IGZhY2V0IGluc3RhbmNlLCBmaW5kcyBjaGlsZCB3aXRoIEl0ZW0gZmFjZXQuXG4gKi9cbmZ1bmN0aW9uIExpc3Qkc3RhcnQoKSB7XG4gICAgLy8gRmlyZWQgYnkgX19iaW5kZXJfXyB3aGVuIGFsbCBjaGlsZHJlbiBvZiBjb21wb25lbnQgYXJlIGJvdW5kXG4gICAgdGhpcy5vd25lci5vbignY2hpbGRyZW5ib3VuZCcsIG9uQ2hpbGRyZW5Cb3VuZCk7XG59XG5cblxuZnVuY3Rpb24gb25DaGlsZHJlbkJvdW5kKCkge1xuICAgIC8vIGdldCBpdGVtcyBhbHJlYWR5IGluIHRoZSBsaXN0XG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy5kb20uY2hpbGRyZW4oKVxuICAgICAgICAsIGl0ZW1zID0gdGhpcy5saXN0Ll9saXN0SXRlbXNcbiAgICAgICAgLCBpdGVtc0hhc2ggPSB0aGlzLmxpc3QuX2xpc3RJdGVtc0hhc2g7XG5cbiAgICBjaGlsZHJlbiAmJiBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkRWwpIHtcbiAgICAgICAgdmFyIGNvbXAgPSBDb21wb25lbnQuZ2V0Q29tcG9uZW50KGNoaWxkRWwpO1xuICAgICAgICBpZiAoY29tcCAmJiBjb21wLml0ZW0pIHtcbiAgICAgICAgICAgIGl0ZW1zLnB1c2goY29tcCk7XG4gICAgICAgICAgICBpdGVtc0hhc2hbY29tcC5uYW1lXSA9IGNvbXA7XG4gICAgICAgICAgICBjb21wLml0ZW0ubGlzdCA9IHRoaXMubGlzdDtcbiAgICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgaWYgKGl0ZW1zLmxlbmd0aCkge1xuICAgICAgICB2YXIgZm91bmRJdGVtID0gaXRlbXNbMF07XG4gICAgICAgIGl0ZW1zLnNwbGljZSgwLCAxKTtcbiAgICAgICAgZGVsZXRlIGl0ZW1zSGFzaFtmb3VuZEl0ZW0ubmFtZV07XG4gICAgICAgIGl0ZW1zLmZvckVhY2goZnVuY3Rpb24oaXRlbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIGl0ZW0uaXRlbS5zZXRJbmRleChpbmRleCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICAvLyBDb21wb25lbnQgbXVzdCBoYXZlIG9uZSBjaGlsZCB3aXRoIGFuIEl0ZW0gZmFjZXQgXG4gICAgaWYgKCEgZm91bmRJdGVtKSB0aHJvdyBuZXcgTGlzdEVycm9yKCdObyBjaGlsZCBjb21wb25lbnQgaGFzIEl0ZW0gZmFjZXQnKTtcblxuICAgIHRoaXMubGlzdC5pdGVtU2FtcGxlID0gZm91bmRJdGVtO1xuXG4gICAgLy8gQWZ0ZXIga2VlcGluZyBhIHJlZmVyZW5jZSB0byB0aGUgaXRlbSBzYW1wbGUsIGl0IG11c3QgYmUgaGlkZGVuIGFuZCByZW1vdmVkIGZyb20gc2NvcGVcbiAgICBmb3VuZEl0ZW0uZG9tLmhpZGUoKTtcbiAgICBmb3VuZEl0ZW0ucmVtb3ZlKHRydWUpO1xuICAgIGZvdW5kSXRlbS5kb20ucmVtb3ZlQ3NzQ2xhc3NlcyhMSVNUX1NBTVBMRV9DU1NfQ0xBU1MpO1xuXG4gICAgLy8gcmVtb3ZlIHJlZmVyZW5jZXMgdG8gY29tcG9uZW50cyBmcm9tIHNhbXBsZSBpdGVtXG4gICAgZm91bmRJdGVtLndhbGtTY29wZVRyZWUoZnVuY3Rpb24oY29tcCkge1xuICAgICAgICBkZWxldGUgY29tcC5lbFttaWxvQ29uZmlnLmNvbXBvbmVudFJlZl07XG4gICAgfSk7XG5cbiAgICB0aGlzLmxpc3QuX2NyZWF0ZUNhY2hlVGVtcGxhdGUoKTtcbn1cblxuXG5mdW5jdGlvbiBMaXN0JF9jcmVhdGVDYWNoZVRlbXBsYXRlKCkge1xuICAgIGlmICghdGhpcy5pdGVtU2FtcGxlKSByZXR1cm4gZmFsc2U7XG4gICAgXG4gICAgdmFyIGl0ZW1TYW1wbGUgPSB0aGlzLml0ZW1TYW1wbGU7XG5cbiAgICAvLyBjcmVhdGUgaXRlbSB0ZW1wbGF0ZSB0byBpbnNlcnQgbWFueSBpdGVtcyBhdCBvbmNlXG4gICAgdmFyIGl0ZW1FbENvcHkgPSBpdGVtU2FtcGxlLmVsLmNsb25lTm9kZSh0cnVlKTtcbiAgICB2YXIgYXR0ciA9IGl0ZW1TYW1wbGUuY29tcG9uZW50SW5mby5hdHRyO1xuICAgIHZhciBhdHRyQ29weSA9IF8uY2xvbmUoYXR0cik7XG4gICAgYXR0ci5jb21wTmFtZSA9ICd7ez0gaXQuY29tcG9uZW50TmFtZSgpIH19JztcbiAgICBhdHRyLmVsID0gaXRlbUVsQ29weTtcbiAgICBhdHRyLmRlY29yYXRlKCk7XG5cbiAgICB2YXIgaXRlbXNUZW1wbGF0ZVN0ciA9IFxuICAgICAgICAgICd7eyB2YXIgaSA9IGl0LmNvdW50OyB3aGlsZShpLS0pIHsgfX0nXG4gICAgICAgICsgaXRlbUVsQ29weS5vdXRlckhUTUxcbiAgICAgICAgKyAne3sgfSB9fSc7XG5cbiAgICB0aGlzLml0ZW1zVGVtcGxhdGUgPSBkb1QuY29tcGlsZShpdGVtc1RlbXBsYXRlU3RyKTtcbn1cblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0cmlldmUgYSBwYXJ0aWN1bGFyIGNoaWxkIGl0ZW0gYnkgaW5kZXhcbiAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBjaGlsZCBpdGVtIHRvIGdldC5cbiAqIEByZXR1cm4ge0NvbXBvbmVudH0gVGhlIGNvbXBvbmVudCBmb3VuZFxuICovXG5mdW5jdGlvbiBMaXN0JGl0ZW0oaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGlzdEl0ZW1zW2luZGV4XTtcbn1cblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogR2V0cyB0aGUgdG90YWwgbnVtYmVyIG9mIGNoaWxkIGl0ZW1zXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgdG90YWxcbiAqL1xuZnVuY3Rpb24gTGlzdCRjb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGlzdEl0ZW1zLmxlbmd0aDtcbn1cblxuXG5mdW5jdGlvbiBMaXN0JF9zZXRJdGVtKGluZGV4LCBjb21wb25lbnQpIHtcbiAgICB0aGlzLl9saXN0SXRlbXMuc3BsaWNlKGluZGV4LCAwLCBjb21wb25lbnQpO1xuICAgIHRoaXMuX2xpc3RJdGVtc0hhc2hbY29tcG9uZW50Lm5hbWVdID0gY29tcG9uZW50O1xuICAgIGNvbXBvbmVudC5pdGVtLmxpc3QgPSB0aGlzO1xuICAgIGNvbXBvbmVudC5pdGVtLnNldEluZGV4KCtpbmRleCk7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgdHJ1ZSBpZiBhIHBhcnRpY3VsYXIgY2hpbGQgaXRlbSBleGlzdHMgaW4gdGhlIGxpc3RcbiAqIEBwYXJhbSB7Q29tcG9uZW50fSBjb21wb25lbnQgVGhlIGNvbXBvbmVudCB0byBsb29rIGZvci5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIExpc3QkY29udGFpbnMoY29tcG9uZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RJdGVtc0hhc2hbY29tcG9uZW50Lm5hbWVdID09IGNvbXBvbmVudDtcbn1cblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQWRkcyBhIG5ldyBjaGlsZCBjb21wb25lbnQgYXQgYSBwYXJ0aWN1bGFyIGluZGV4IGFuZCByZXR1cm5zIHRoZSBuZXcgY29tcG9uZW50LlxuICogVGhpcyBtZXRob2QgdXNlcyBkYXRhIGZhY2V0LCBzbyBub3RpZmljYXRpb24gd2lsbCBiZSBlbWl0dGVkIG9uIGRhdGEgZmFjZXQuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IFRoZSBpbmRleCB0byBhZGQgYXRcbiAqIEByZXR1cm4ge0NvbXBvbmVudH0gVGhlIG5ld2x5IGNyZWF0ZWQgY29tcG9uZW50XG4gKi9cbmZ1bmN0aW9uIExpc3QkYWRkSXRlbShpbmRleCwgaXRlbURhdGEpIHtcbiAgICBpbmRleCA9IGluZGV4IHx8IHRoaXMuY291bnQoKTtcbiAgICB0aGlzLm93bmVyLmRhdGEuc3BsaWNlKGluZGV4LCAwLCBpdGVtRGF0YSB8fCB7fSk7XG4gICAgcmV0dXJuIHRoaXMuaXRlbShpbmRleCk7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEFkZHMgYSBuZXcgY2hpbGQgY29tcG9uZW50IGF0IGEgcGFydGljdWxhciBpbmRleCBhbmQgcmV0dXJucyB0aGUgbmV3IGNvbXBvbmVudFxuICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCBUaGUgaW5kZXggdG8gYWRkIGF0XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBuZXdseSBjcmVhdGVkIGNvbXBvbmVudFxuICovXG5mdW5jdGlvbiBMaXN0JF9hZGRJdGVtKGluZGV4KSB7XG4gICAgaW5kZXggPSBpbmRleCB8fCB0aGlzLmNvdW50KCk7XG4gICAgaWYgKHRoaXMuaXRlbShpbmRleCkpXG4gICAgICAgIHRocm93IExpc3RFcnJvcignYXR0ZW1wdCB0byBjcmVhdGUgaXRlbSB3aXRoIElEIG9mIGV4aXN0aW5nIGl0ZW0nKTtcblxuICAgIC8vIENvcHkgY29tcG9uZW50XG4gICAgdmFyIGNvbXBvbmVudCA9IENvbXBvbmVudC5jb3B5KHRoaXMuaXRlbVNhbXBsZSwgdHJ1ZSk7XG4gICAgdmFyIHByZXZDb21wb25lbnQgPSB0aGlzLl9pdGVtUHJldmlvdXNDb21wb25lbnQoaW5kZXgpO1xuXG4gICAgaWYgKCFwcmV2Q29tcG9uZW50LmVsLnBhcmVudE5vZGUpXG4gICAgICAgIHJldHVybiBsb2dnZXIud2FybignbGlzdCBpdGVtIHNhbXBsZSB3YXMgcmVtb3ZlZCBmcm9tIERPTSwgcHJvYmFibHkgY2F1c2VkIGJ5IHdyb25nIGRhdGEuIFJlc2V0IGxpc3QgZGF0YSB3aXRoIGFycmF5Jyk7XG5cbiAgICAvLyBBZGQgaXQgdG8gdGhlIERPTVxuICAgIHByZXZDb21wb25lbnQuZG9tLmluc2VydEFmdGVyKGNvbXBvbmVudC5lbCk7XG5cbiAgICAvLyBBZGQgdG8gbGlzdCBpdGVtc1xuICAgIHRoaXMuX3NldEl0ZW0oaW5kZXgsIGNvbXBvbmVudCk7XG5cbiAgICAvLyBTaG93IHRoZSBsaXN0IGl0ZW0gY29tcG9uZW50XG4gICAgY29tcG9uZW50LmVsLnN0eWxlLmRpc3BsYXkgPSAnJztcblxuICAgIF91cGRhdGVJdGVtc0luZGV4ZXMuY2FsbCh0aGlzLCBpbmRleCArIDEpO1xuXG4gICAgcmV0dXJuIGNvbXBvbmVudDtcbn1cblxuXG5mdW5jdGlvbiBfdXBkYXRlSXRlbXNJbmRleGVzKGZyb21JbmRleCwgdG9JbmRleCkge1xuICAgIGZyb21JbmRleCA9IGZyb21JbmRleCB8fCAwO1xuICAgIHRvSW5kZXggPSB0b0luZGV4IHx8IHRoaXMuY291bnQoKTtcbiAgICBmb3IgKHZhciBpID0gZnJvbUluZGV4OyBpIDwgdG9JbmRleDsgaSsrKSB7XG4gICAgICAgIHZhciBjb21wb25lbnQgPSB0aGlzLl9saXN0SXRlbXNbaV07XG4gICAgICAgIGlmIChjb21wb25lbnQpXG4gICAgICAgICAgICBjb21wb25lbnQuaXRlbS5zZXRJbmRleChpKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0xpc3Q6IG5vIGl0ZW0gYXQgcG9zaXRpb24nLCBpKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gTGlzdCRhZGRJdGVtcyhjb3VudCwgaW5kZXgpIHsgLy8gLC4uLiBpdGVtcyBkYXRhXG4gICAgdmFyIGl0ZW1zRGF0YSA9IF8uc2xpY2UoYXJndW1lbnRzLCAyKTtcbiAgICBpZiAoaXRlbXNEYXRhLmxlbmd0aCA8IGNvdW50KSBcbiAgICAgICAgaXRlbXNEYXRhLmNvbmNhdChfLnJlcGVhdChjb3VudCAtIGl0ZW1zRGF0YS5sZW5ndGgsIHt9KSk7XG4gICAgdmFyIHNwbGljZUFyZ3MgPSBbaW5kZXgsIDBdLmNvbmNhdChpdGVtc0RhdGEpO1xuICAgIHZhciBkYXRhRmFjZXQgPSB0aGlzLm93bmVyLmRhdGE7XG4gICAgZGF0YUZhY2V0LnNwbGljZS5hcHBseShkYXRhRmFjZXQsIHNwbGljZUFyZ3MpO1xufVxuXG5cbi8qKlxuICogTGlzdCBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEFkZHMgYSBnaXZlbiBudW1iZXIgb2YgaXRlbXMgdXNpbmcgdGVtcGxhdGUgcmVuZGVyaW5nIHJhdGhlciB0aGFuIGFkZGluZyBlbGVtZW50cyBvbmUgYnkgb25lXG4gKlxuICogQHBhcmFtIHtJbnRlZ2VyfSBjb3VudCBudW1iZXIgb2YgaXRlbXMgdG8gYWRkXG4gKiBAcGFyYW0ge1tJbnRlZ2VyXX0gaW5kZXggb3B0aW9uYWwgaW5kZXggb2YgaXRlbSBhZnRlciB3aGljaCB0byBhZGRcbiAqL1xuZnVuY3Rpb24gTGlzdCRfYWRkSXRlbXMoY291bnQsIGluZGV4KSB7XG4gICAgY2hlY2soY291bnQsIE1hdGNoLkludGVnZXIpO1xuICAgIGlmIChjb3VudCA8IDApXG4gICAgICAgIHRocm93IG5ldyBMaXN0RXJyb3IoJ2NhblxcJ3QgYWRkIG5lZ2F0aXZlIG51bWJlciBvZiBpdGVtcycpO1xuXG4gICAgaWYgKGNvdW50ID09IDApIHJldHVybjtcblxuICAgIHZhciBpdGVtc0hUTUwgPSB0aGlzLml0ZW1zVGVtcGxhdGUoe1xuICAgICAgICBjb21wb25lbnROYW1lOiBtaWxvVXRpbC5jb21wb25lbnROYW1lLFxuICAgICAgICBjb3VudDogY291bnRcbiAgICB9KTtcblxuICAgIHZhciB3cmFwRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB3cmFwRWwuaW5uZXJIVE1MID0gaXRlbXNIVE1MO1xuXG4gICAgbWlsb0JpbmRlcih3cmFwRWwsIHRoaXMub3duZXIuY29udGFpbmVyLnNjb3BlKTtcbiAgICB2YXIgY2hpbGRyZW4gPSBkb21VdGlscy5jaGlsZHJlbih3cmFwRWwpO1xuXG4gICAgaWYgKGNvdW50ICE9IGNoaWxkcmVuLmxlbmd0aClcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdudW1iZXIgb2YgaXRlbXMgYWRkZWQgaXMgZGlmZmVyZW50IGZyb20gcmVxdWVzdGVkJyk7XG5cbiAgICBpZiAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICAgIHZhciBsaXN0TGVuZ3RoID0gdGhpcy5jb3VudCgpO1xuICAgICAgICB2YXIgc3BsaWNlSW5kZXggPSBpbmRleCA8IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHR5cGVvZiBpbmRleCA9PSAndW5kZWZpbmVkJyB8fCBpbmRleCA+IGxpc3RMZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBsaXN0TGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogaW5kZXg7XG5cbiAgICAgICAgdmFyIHByZXZDb21wb25lbnQgPSBzcGxpY2VJbmRleCA9PSAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdGhpcy5pdGVtU2FtcGxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5fbGlzdEl0ZW1zW3NwbGljZUluZGV4IC0gMV07XG5cbiAgICAgICAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcbiAgICAgICAgICAgICwgbmV3Q29tcG9uZW50cyA9IFtdO1xuXG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24oZWwsIGkpIHtcbiAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBDb21wb25lbnQuZ2V0Q29tcG9uZW50KGVsKTtcbiAgICAgICAgICAgIGlmICghIGNvbXBvbmVudClcbiAgICAgICAgICAgICAgICByZXR1cm4gbG9nZ2VyLmVycm9yKCdMaXN0OiBlbGVtZW50IGluIG5ldyBpdGVtcyBpcyBub3QgYSBjb21wb25lbnQnKTtcbiAgICAgICAgICAgIG5ld0NvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xuICAgICAgICAgICAgdGhpcy5fc2V0SXRlbShzcGxpY2VJbmRleCsrLCBjb21wb25lbnQpO1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIF91cGRhdGVJdGVtc0luZGV4ZXMuY2FsbCh0aGlzLCBzcGxpY2VJbmRleCk7XG5cbiAgICAgICAgaWYgKCFwcmV2Q29tcG9uZW50LmVsLnBhcmVudE5vZGUpXG4gICAgICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ2xpc3QgaXRlbSBzYW1wbGUgd2FzIHJlbW92ZWQgZnJvbSBET00sIHByb2JhYmx5IGNhdXNlZCBieSB3cm9uZyBkYXRhLiBSZXNldCBsaXN0IGRhdGEgd2l0aCBhcnJheScpO1xuXG4gICAgICAgIC8vIEFkZCBpdCB0byB0aGUgRE9NXG4gICAgICAgIHByZXZDb21wb25lbnQuZG9tLmluc2VydEFmdGVyKGZyYWcpO1xuXG4gICAgICAgIF8uZGVmZXJNZXRob2QobmV3Q29tcG9uZW50cywgJ2ZvckVhY2gnLCBmdW5jdGlvbihjb21wKSB7XG4gICAgICAgICAgICBjb21wLmJyb2FkY2FzdCgnc3RhdGVyZWFkeScpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBMaXN0IGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGl0ZW0gdG8gcmVtb3ZlXG4gKiBAcmV0dXJuIHtBcnJheVtPYmplY3RdfSBUaGUgc3BsaWNlZCBkYXRhXG4gKi9cbmZ1bmN0aW9uIExpc3QkcmVtb3ZlSXRlbShpbmRleCkge1xuICAgIHJldHVybiB0aGlzLm93bmVyLmRhdGEuc3BsaWNlKGluZGV4LCAxKTtcbn1cblxuXG4vKipcbiAqIExpc3QgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgaXRlbSB0byBleHRyYWN0XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBleHRyYWN0ZWQgaXRlbVxuICovXG5mdW5jdGlvbiBMaXN0JGV4dHJhY3RJdGVtKGluZGV4KSB7XG4gICAgdmFyIGl0ZW1Db21wID0gdGhpcy5fcmVtb3ZlSXRlbShpbmRleCwgZmFsc2UpO1xuICAgIHRoaXMuX3VwZGF0ZURhdGFQYXRocyhpbmRleCwgdGhpcy5jb3VudCgpKTtcbiAgICByZXR1cm4gaXRlbUNvbXA7XG59XG5cblxuLyoqXG4gKiBMaXN0IGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmVtb3ZlcyBpdGVtLCByZXR1cm5zIHRoZSByZW1vdmVkIGl0ZW0gdGhhdCBpcyBkZXN0cm95ZWQgYnkgZGVmYXVsdC5cbiAqIFxuICogQHBhcmFtICB7TnVtYmVyfSBpbmRleCBpdGVtIGluZGV4XG4gKiBAcGFyYW0gIHtCb29sZWFufSBkb0Rlc3Ryb3lJdGVtIG9wdGlvbmFsIGZhbHNlIHRvIHByZXZlbnQgaXRlbSBkZXN0cnVjdGlvbiwgdHJ1ZSBieSBkZWZhdWx0XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbmZ1bmN0aW9uIExpc3QkX3JlbW92ZUl0ZW0oaW5kZXgsIGRvRGVzdHJveUl0ZW0pIHtcbiAgICB2YXIgY29tcCA9IHRoaXMuaXRlbShpbmRleCk7XG5cbiAgICBpZiAoISBjb21wKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ2F0dGVtcHQgdG8gcmVtb3ZlIGxpc3QgaXRlbSB3aXRoIGlkIHRoYXQgZG9lcyBub3QgZXhpc3QnKTtcblxuICAgIHRoaXMuX2xpc3RJdGVtc1tpbmRleF0gPSB1bmRlZmluZWQ7XG4gICAgZGVsZXRlIHRoaXMuX2xpc3RJdGVtc0hhc2hbY29tcC5uYW1lXTtcbiAgICBpZiAoZG9EZXN0cm95SXRlbSAhPT0gZmFsc2UpIGNvbXAuZGVzdHJveSgpO1xuICAgIGVsc2Uge1xuICAgICAgICBjb21wLnJlbW92ZSgpO1xuICAgICAgICBjb21wLmRvbS5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9saXN0SXRlbXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICBfdXBkYXRlSXRlbXNJbmRleGVzLmNhbGwodGhpcywgaW5kZXgpO1xuXG4gICAgcmV0dXJuIGNvbXA7XG59XG5cblxuZnVuY3Rpb24gTGlzdCRyZXBsYWNlSXRlbShpbmRleCwgbmV3SXRlbSl7XG4gICAgdmFyIG9sZEl0ZW0gPSB0aGlzLml0ZW0oaW5kZXgpO1xuICAgIG9sZEl0ZW0uZG9tLmluc2VydEFmdGVyKG5ld0l0ZW0uZWwpO1xuICAgIHRoaXMuX3JlbW92ZUl0ZW0oaW5kZXgpO1xuICAgIHRoaXMuX3NldEl0ZW0oaW5kZXgsIG5ld0l0ZW0pO1xufVxuXG5cbi8vIFJldHVybnMgdGhlIHByZXZpb3VzIGl0ZW0gY29tcG9uZW50IGdpdmVuIGFuIGluZGV4XG5mdW5jdGlvbiBfaXRlbVByZXZpb3VzQ29tcG9uZW50KGluZGV4KSB7XG4gICAgd2hpbGUgKGluZGV4ID49IDAgJiYgISB0aGlzLl9saXN0SXRlbXNbaW5kZXhdKVxuICAgICAgICBpbmRleC0tO1xuXG4gICAgcmV0dXJuIGluZGV4ID49IDBcbiAgICAgICAgICAgICAgICA/IHRoaXMuX2xpc3RJdGVtc1tpbmRleF1cbiAgICAgICAgICAgICAgICA6IHRoaXMuaXRlbVNhbXBsZTtcbn1cblxuXG4vLyB0b0luZGV4IGlzIG5vdCBpbmNsdWRlZFxuLy8gbm8gcmFuZ2UgY2hlY2tpbmcgaXMgbWFkZVxuZnVuY3Rpb24gTGlzdCRfdXBkYXRlRGF0YVBhdGhzKGZyb21JbmRleCwgdG9JbmRleCkge1xuICAgIGZvciAodmFyIGkgPSBmcm9tSW5kZXg7IGkgPCB0b0luZGV4OyBpKyspIHtcbiAgICAgICAgdmFyIGl0ZW0gPSB0aGlzLml0ZW0oaSk7XG4gICAgICAgIGlmIChpdGVtKVxuICAgICAgICAgICAgaXRlbS5kYXRhLl9wYXRoID0gJ1snICsgaSArICddJztcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0RhdGE6IG5vIGl0ZW0gZm9yIGluZGV4Jywgaik7XG4gICAgfVxufVxuXG5cbi8qKlxuICogRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTaW1pbGFyIHRvIGZvckVhY2ggbWV0aG9kIG9mIEFycmF5LCBpdGVyYXRlcyBlYWNoIG9mIHRoZSBjaGlsZCBpdGVtcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIEFuIGl0ZXJhdG9yIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBlYWNoIGNoaWxkIGl0ZW0uXG4gKiBAcGFyYW0ge1t0eXBlXX0gICB0aGlzQXJnICBDb250ZXh0IHRvIHNldCBgdGhpc2AuXG4gKi9cbmZ1bmN0aW9uIExpc3QkZWFjaChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIHRoaXMuX2xpc3RJdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgIGlmIChpdGVtKSBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBwYXNzZXMgaXRlbSwgaW5kZXggdG8gY2FsbGJhY2tcbiAgICAgICAgZWxzZSBsb2dnZXIud2FybignTGlzdCRlYWNoOiBpdGVtJywgaW5kZXgsICdpcyB1bmRlZmluZWQnKTtcbiAgICB9LCB0aGlzQXJnIHx8IHRoaXMpO1xufVxuXG5cbi8qKlxuICogRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBEZXN0cm95cyB0aGUgbGlzdFxuICovXG5mdW5jdGlvbiBMaXN0JGRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuaXRlbVNhbXBsZSkgdGhpcy5pdGVtU2FtcGxlLmRlc3Ryb3kodHJ1ZSk7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgTW9kZWwgPSByZXF1aXJlKCcuLi8uLi9tb2RlbCcpXG4gICAgLCBNaXhpbiA9IHJlcXVpcmUoJy4uLy4uL2Fic3RyYWN0L21peGluJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vLyBnZW5lcmljIGRyYWcgaGFuZGxlciwgc2hvdWxkIGJlIG92ZXJyaWRkZW5cbnZhciBNb2RlbEZhY2V0ID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ01vZGVsJyk7XG5cbl8uZXh0ZW5kUHJvdG8oTW9kZWxGYWNldCwge1xuICAgIGluaXQ6IE1vZGVsRmFjZXQkaW5pdCxcbiAgICBnZXRTdGF0ZTogTW9kZWxGYWNldCRnZXRTdGF0ZSxcbiAgICBzZXRTdGF0ZTogTW9kZWxGYWNldCRzZXRTdGF0ZSxcbiAgICBfY3JlYXRlTWVzc2VuZ2VyOiBNb2RlbEZhY2V0JF9jcmVhdGVNZXNzZW5nZXIsXG4gICAgZGVzdHJveTogTW9kZWxGYWNldCRkZXN0cm95XG59KTtcblxuZmFjZXRzUmVnaXN0cnkuYWRkKE1vZGVsRmFjZXQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsRmFjZXQ7XG5cblxuLyoqXG4gKiBFeHBvc2UgTW9kZWwgY2xhc3MgbWV0aG9kcyBvbiBNb2RlbEZhY2V0XG4gKi9cbk1vZGVsLnVzZVdpdGgoTW9kZWxGYWNldCwgJ20nKTtcblxuXG5mdW5jdGlvbiBNb2RlbEZhY2V0JGluaXQoKSB7XG4gICAgdGhpcy5tID0gbmV3IE1vZGVsKHRoaXMuY29uZmlnLmRhdGEsIHRoaXMpO1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgLy8gdGhpcy5tLnByb3h5TWV0aG9kcyh0aGlzKTsgLy8gQ3JlYXRlcyBtb2RlbCdzIG1ldGhvZHMgZGlyZWN0bHkgb24gZmFjZXRcbn1cblxuXG4vKipcbiAqIE1vZGVsRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBDYWxsZWQgYnkgYENvbXBvbmVudC5wcm90b3R5cGUuZ2V0U3RhdGVgIHRvIGdldCBmYWNldCdzIHN0YXRlXG4gKiBTaW1wbHkgcmV0dXJucyBtb2RlbCBkYXRhXG4gKlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBNb2RlbEZhY2V0JGdldFN0YXRlKCkge1xuICAgIHZhciBtb2RlbFZhbHVlID0gdGhpcy5tLmdldCgpO1xuICAgIGlmICh0eXBlb2YgbW9kZWxWYWx1ZSA9PSAnb2JqZWN0JylcbiAgICAgICAgbW9kZWxWYWx1ZSA9IF8uZGVlcENsb25lKG1vZGVsVmFsdWUpO1xuICAgIHJldHVybiB7IHN0YXRlOiBtb2RlbFZhbHVlIH07XG59XG5cblxuLyoqXG4gKiBNb2RlbEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IGBDb21wb25lbnQucHJvdG90eXBlLnNldFN0YXRlYCB0byBzZXQgZmFjZXQncyBzdGF0ZVxuICogU2ltcGx5IHNldHMgbW9kZWwgZGF0YVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZSBkYXRhIHRvIHNldCBvbiBmYWNldCdzIG1vZGVsXG4gKi9cbmZ1bmN0aW9uIE1vZGVsRmFjZXQkc2V0U3RhdGUoc3RhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5tLnNldChzdGF0ZS5zdGF0ZSk7XG59XG5cblxuZnVuY3Rpb24gTW9kZWxGYWNldCRfY3JlYXRlTWVzc2VuZ2VyKCkgeyAvLyBDYWxsZWQgYnkgaW5oZXJpdGVkIGluaXRcbiAgICB0aGlzLl9tZXNzZW5nZXIgPSB0aGlzLm0uX21lc3Nlbmdlcjtcbn1cblxuXG5mdW5jdGlvbiBNb2RlbEZhY2V0JGRlc3Ryb3koKSB7XG4gICAgdGhpcy5tLmRlc3Ryb3koKTtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBNb2RlbCA9IHJlcXVpcmUoJy4uLy4uL21vZGVsJylcblxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8vIGdlbmVyaWMgZHJhZyBoYW5kbGVyLCBzaG91bGQgYmUgb3ZlcnJpZGRlblxudmFyIE9wdGlvbnMgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnT3B0aW9ucycpO1xuXG5fLmV4dGVuZFByb3RvKE9wdGlvbnMsIHtcbiAgICBpbml0OiBPcHRpb25zJGluaXQsXG4gICAgZGVzdHJveTogT3B0aW9ucyRkZXN0cm95LFxuICAgIF9jcmVhdGVNZXNzZW5nZXI6IE9wdGlvbnMkX2NyZWF0ZU1lc3NlbmdlclxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChPcHRpb25zKTtcblxubW9kdWxlLmV4cG9ydHMgPSBPcHRpb25zO1xuXG5cbmZ1bmN0aW9uIE9wdGlvbnMkaW5pdCgpIHtcbiAgICB0aGlzLm0gPSBuZXcgTW9kZWwodGhpcy5jb25maWcub3B0aW9ucywgdGhpcyk7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLm0ucHJveHlNZXRob2RzKHRoaXMpOyAvLyBDcmVhdGVzIG1vZGVsJ3MgbWV0aG9kcyBkaXJlY3RseSBvbiBmYWNldFxufVxuXG5cbmZ1bmN0aW9uIE9wdGlvbnMkX2NyZWF0ZU1lc3NlbmdlcigpIHsgLy8gQ2FsbGVkIGJ5IGluaGVyaXRlZCBpbml0XG4gICAgdGhpcy5fbWVzc2VuZ2VyID0gdGhpcy5tLl9tZXNzZW5nZXI7XG59XG5cblxuZnVuY3Rpb24gT3B0aW9ucyRkZXN0cm95KCkge1xuICAgIHRoaXMubS5kZXN0cm95KCk7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gPGEgbmFtZT1cImNvbXBvbmVudHMtZmFjZXRzLXRlbXBsYXRlXCI+PC9hPlxuLy8gIyMjdGVtcGxhdGUgZmFjZXRcblxuLy8gc2ltcGxpZmllcyByZW5kZXJpbmcgb2YgY29tcG9uZW50IGVsZW1lbnQgZnJvbSB0ZW1wbGF0ZS5cbi8vICAgQW55IHRlbXBsYXRpbmcgZW5naW5nIGNhbiBiZSB1c2VkIHRoYXQgc3VwcG9ydHMgdGVtcGxhdGUgY29tcGlsYXRpb25cbi8vICAgKG9yIHlvdSBjYW4gbW9jayB0aGlzIGNvbXBpbGF0aW9uIGVhc2lseSBieSBjcmVhdGluZyBjbG9zdXJlIHN0b3Jpbmdcbi8vICAgdGVtcGxhdGUgc3RyaW5nIGluIGNhc2UgeW91ciBlbmdpbmUgZG9lc24ndCBzdXBwb3J0IGNvbXBpbGF0aW9uKS5cbi8vICAgQnkgZGVmYXVsdCBtaWxvIHVzZXMgW2RvVF0oKSwgdGhlIG1vc3QgdmVyc2F0aWxlLCBjb25zY2lzZSBhbmQgYXQgdGhlXG4vLyAgIHNhbWUgdGltZSB0aGUgZmFzdGVzdCB0ZW1wbGF0aW5nIGVuZ2luZS5cbi8vICAgSWYgeW91IHVzZSBtaWxvIGluIGJyb3dzZXIsIGl0IGlzIHRoZSBwYXJ0IG9mIG1pbG8gYnVuZGxlIGFuZCBhdmFpbGFibGVcbi8vICAgYXMgZ2xvYmFsIHZhcmlhYmxlIGBkb1RgLlxuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi91dGlsL2xvZ2dlcicpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBiaW5kZXIgPSByZXF1aXJlKCcuLi8uLi9iaW5kZXInKTtcblxuXG4vLyBkYXRhIG1vZGVsIGNvbm5lY3Rpb24gZmFjZXRcbnZhciBUZW1wbGF0ZSA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdUZW1wbGF0ZScpO1xuXG5fLmV4dGVuZFByb3RvKFRlbXBsYXRlLCB7XG4gICAgaW5pdDogVGVtcGxhdGUkaW5pdCxcbiAgICBzdGFydDogVGVtcGxhdGUkc3RhcnQsXG4gICAgc2V0OiBUZW1wbGF0ZSRzZXQsXG4gICAgZ2V0Q29tcGlsZWQ6IFRlbXBsYXRlJGdldENvbXBpbGVkLFxuICAgIHJlbmRlcjogVGVtcGxhdGUkcmVuZGVyLFxuICAgIGJpbmRlcjogVGVtcGxhdGUkYmluZGVyXG5cbiAgICAvLyBfcmVhdHRhY2g6IF9yZWF0dGFjaEV2ZW50c09uRWxlbWVudENoYW5nZVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChUZW1wbGF0ZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gVGVtcGxhdGU7XG5cblxuZnVuY3Rpb24gVGVtcGxhdGUkaW5pdCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLy8gdGVtcGxhdGVzIGFyZSBpbnRlcnBvbGF0ZWQgd2l0aCBkZWZhdWx0IChkb1QpIG9yIGNvbmZpZ3VyZWQgZW5naW5lICh0aGlzLmNvbmZpZy5jb21waWxlKVxuICAgIC8vIHVubGVzcyB0aGlzLmNvbmZpZy5pbnRlcnBvbGF0ZSBpcyBmYWxzZVxuICAgIHZhciBjb21waWxlID0gdGhpcy5jb25maWcuaW50ZXJwb2xhdGUgPT09IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy5jb25maWcuY29tcGlsZSB8fCBtaWxvLmNvbmZpZy50ZW1wbGF0ZS5jb21waWxlO1xuXG4gICAgdGhpcy5zZXQodGhpcy5jb25maWcudGVtcGxhdGUgfHwgJycsIGNvbXBpbGUsIHRoaXMuY29uZmlnLmNvbXBpbGVPcHRpb25zKTtcbn1cblxuXG5mdW5jdGlvbiBUZW1wbGF0ZSRzdGFydCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuc3RhcnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodGhpcy5jb25maWcuYXV0b1JlbmRlcikge1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICBpZiAodGhpcy5jb25maWcuYXV0b0JpbmRlcilcbiAgICAgICAgICAgIHRoaXMuYmluZGVyKCk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIFRlbXBsYXRlJGdldENvbXBpbGVkKCkge1xuICAgIHJldHVybiB0aGlzLl90ZW1wbGF0ZTtcbn1cblxuXG5mdW5jdGlvbiBUZW1wbGF0ZSRzZXQodGVtcGxhdGVTdHIsIGNvbXBpbGUsIGNvbXBpbGVPcHRpb25zKSB7XG4gICAgY2hlY2sodGVtcGxhdGVTdHIsIE1hdGNoLk9uZU9mKFN0cmluZywgRnVuY3Rpb24pKTtcbiAgICBjaGVjayhjb21waWxlLCBNYXRjaC5PcHRpb25hbChGdW5jdGlvbikpO1xuXG4gICAgaWYgKHR5cGVvZiB0ZW1wbGF0ZVN0ciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aGlzLl90ZW1wbGF0ZSA9IHRlbXBsYXRlU3RyO1xuICAgIGVsc2Uge1xuICAgICAgICB0aGlzLl90ZW1wbGF0ZVN0ciA9IHRlbXBsYXRlU3RyO1xuICAgICAgICBpZiAoY29tcGlsZSlcbiAgICAgICAgICAgIHRoaXMuX2NvbXBpbGUgPSBjb21waWxlO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb21waWxlID0gdGhpcy5fY29tcGlsZTtcblxuICAgICAgICBpZiAoY29tcGlsZSlcbiAgICAgICAgICAgIHRoaXMuX3RlbXBsYXRlID0gY29tcGlsZSh0ZW1wbGF0ZVN0ciwgY29tcGlsZU9wdGlvbnMpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbmZ1bmN0aW9uIFRlbXBsYXRlJHJlbmRlcihkYXRhKSB7IC8vIHdlIG5lZWQgZGF0YSBvbmx5IGlmIHVzZSB0ZW1wbGF0aW5nIGVuZ2luZVxuICAgIHRoaXMub3duZXIuZWwuaW5uZXJIVE1MID0gdGhpcy5fdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLl90ZW1wbGF0ZShkYXRhKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX3RlbXBsYXRlU3RyO1xuXG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuZnVuY3Rpb24gVGVtcGxhdGUkYmluZGVyKCkge1xuICAgIGlmICh0aGlzLm93bmVyLmNvbnRhaW5lcilcbiAgICAgICAgcmV0dXJuIHRoaXMub3duZXIuY29udGFpbmVyLmJpbmRlcigpO1xuICAgIGVsc2VcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdUZW1wbGF0ZUZhY2V0OiBCaW5kZXIgY2FsbGVkIHdpdGhvdXQgY29udGFpbmVyIGZhY2V0LicpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLyoqXG4gKiBUcmFuc2ZlciBmYWNldCBpcyBkZXNpZ25lZCBmb3IgY29tcG9uZW50cyB0byBiZSBhYmxlIHRvIHJlcHJlc2VudCBvdGhlciBjb21wb25lbnRzXG4gKiBJZiBhIFtDb21wb25lbnRdKC4uL2NfY2xhc3MuanMuaHRtbCkgaGFzIFRyYW5zZmVyIGZhY2V0LCB3aGVuIGBDb21wb25lbnQuZ2V0U3RhdGVgIGlzIGNhbGxlZCBmb3IgdGhpcyBjb21wb25ldCBpdCByZXR1cm5zIHByZXZpb3VzbHkgc2F2ZWQgZGF0YSwgcG9zc2libHkgZnJvbSBhbm90aGVyIGNvbXBvbmVudC5cbiAqIEZvciBleGFtcGxlLCBhIGxpc3Qgb2YgZG9jdW1lbnRzIGNhbiB1c2UgdGhpcyBmYWNldCBzbyB0aGF0IGVhY2ggaXRlbSBpbiB0aGUgbGlzdCBjYW4gc3RvcmUgYWN0dWFsIGRvY3VtZW50IGNvbXBvbmVudCBvbiBpdC5cbiAqL1xudmFyIFRyYW5zZmVyID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ1RyYW5zZmVyJyk7XG5cbl8uZXh0ZW5kUHJvdG8oVHJhbnNmZXIsIHtcbiAgICBpbml0OiBUcmFuc2ZlciRpbml0LFxuICAgIGdldFN0YXRlOiBUcmFuc2ZlciRnZXRTdGF0ZSxcbiAgICBzZXRTdGF0ZTogVHJhbnNmZXIkc2V0U3RhdGUsXG4gICAgc2V0QWN0aXZlU3RhdGU6IFRyYW5zZmVyJHNldEFjdGl2ZVN0YXRlLFxuICAgIHNldFN0YXRlV2l0aEtleTogVHJhbnNmZXIkc2V0U3RhdGVXaXRoS2V5LFxuICAgIGdldFN0YXRlV2l0aEtleTogVHJhbnNmZXIkZ2V0U3RhdGVXaXRoS2V5LFxuICAgIGdldENvbXBvbmVudE1ldGE6IFRyYW5zZmVyJGdldENvbXBvbmVudE1ldGFcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoVHJhbnNmZXIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zZmVyO1xuXG5cbmZ1bmN0aW9uIFRyYW5zZmVyJGluaXQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLl9hY3RpdmVTdGF0ZSA9ICcnO1xuICAgIHRoaXMuX2RlZmF1bHRLZXkgPSAnJztcbiAgICB0aGlzLl9zdGF0ZSA9IHt9O1xufVxuXG5cbi8qKlxuICogVHJhbnNmZXIgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRyYW5zZmVyIHN0YXRlIGZvciBjb21wb25lbnQuIENhbiBiZSBvYnRhaW5lZCBmcm9tIGFub3RoZXIgY29tcG9uZW50IGJ5IHVzaW5nIGBDb21wb25lbnQuZ2V0U3RhdGVgXG4gKlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBUcmFuc2ZlciRnZXRTdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVbdGhpcy5fYWN0aXZlU3RhdGVdIHx8IHRoaXMuX3N0YXRlW3RoaXMuX2RlZmF1bHRLZXldO1xufVxuXG5cbi8qKlxuICogVHJhbnNmZXIgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRyYW5zZmVyIHN0YXRlIGZvciBjb21wb25lbnQuIENhbiBiZSBvYnRhaW5lZCBmcm9tIGFub3RoZXIgY29tcG9uZW50IGJ5IHVzaW5nIGBDb21wb25lbnQuZ2V0U3RhdGVgXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlXG4gKi9cbmZ1bmN0aW9uIFRyYW5zZmVyJHNldFN0YXRlKHN0YXRlKSB7XG4gICAgdGhpcy5fc3RhdGVbJyddID0gc3RhdGU7XG4gICAgdGhpcy5zZXRBY3RpdmVTdGF0ZSgnJyk7XG59XG5cbi8qKlxuICogVHJhbnNmZXIgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRoZSBhY3RpdmUgc3RhdGUgKHVzZWQgYnkgZ2V0U3RhdGUpXG4gKiBAcGFyYW0ge1t0eXBlXX0ga2V5IFtkZXNjcmlwdGlvbl1cbiAqL1xuZnVuY3Rpb24gVHJhbnNmZXIkc2V0QWN0aXZlU3RhdGUoa2V5KSB7XG4gICAgdGhpcy5fYWN0aXZlU3RhdGUgPSBrZXk7XG59XG5cbi8qKlxuICogVHJhbnNmZXIgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRyYW5zZmVyIHN0YXRlIGZvciBjb21wb25lbnQgd2l0aG91dCBkZWZhdWx0IGtleS4gQ2FuIGJlIG9idGFpbmVkIGZyb20gYW5vdGhlciBjb21wb25lbnQgYnkgdXNpbmcgYENvbXBvbmVudC5nZXRTdGF0ZWBcbiAqIFdoZW4gdGhlIGFjdGl2ZSBzdGF0ZSBpcyBzZXQgdG8gdGhlIGV4cGVjdGVkIGtleVxuICogQHBhcmFtIHtbdHlwZV19IGtleSAgIFtkZXNjcmlwdGlvbl1cbiAqIEBwYXJhbSB7W3R5cGVdfSBzdGF0ZSBbZGVzY3JpcHRpb25dXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGlzRGVmYXVsdEtleSAoT3B0aW9uYWwpXG4gKi9cbmZ1bmN0aW9uIFRyYW5zZmVyJHNldFN0YXRlV2l0aEtleShrZXksIHN0YXRlLCBpc0RlZmF1bHRLZXkpIHtcbiAgICBpZiAoIWtleSkgdGhyb3cgbmV3IEVycm9yKCdUcmFuc2ZlciRzZXRTdGF0ZVdpdGhLZXk6IG5vIGtleScpO1xuXG4gICAgaWYgKGlzRGVmYXVsdEtleSlcbiAgICAgICAgdGhpcy5fZGVmYXVsdEtleSA9IGtleTtcbiAgICBlbHNlXG4gICAgICAgIHRoaXMuX2RlZmF1bHRLZXkgPSB0aGlzLl9kZWZhdWx0S2V5IHx8IGtleTtcblxuICAgIHRoaXMuX3N0YXRlW2tleV0gPSBzdGF0ZTtcbiAgICB0aGlzLnNldEFjdGl2ZVN0YXRlKGtleSk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNmZXIkZ2V0U3RhdGVXaXRoS2V5KGtleSkge1xuICAgIHJldHVybiB0eXBlb2Yga2V5ID09ICdzdHJpbmcnICYmIHRoaXMuX3N0YXRlW2tleV07XG59XG5cblxuZnVuY3Rpb24gVHJhbnNmZXIkZ2V0Q29tcG9uZW50TWV0YSgpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLmdldFN0YXRlKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tcE5hbWU6IHN0YXRlICYmIHN0YXRlLmNvbXBOYW1lLFxuICAgICAgICBjb21wQ2xhc3M6IHN0YXRlICYmIHN0YXRlLmNvbXBDbGFzc1xuICAgIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzc1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vLi4vYWJzdHJhY3QvcmVnaXN0cnknKVxuICAgICwgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0Jyk7XG5cblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5mYWNldHNgXG4gKiBDb21wb25lbnQgZmFjZXRzIHJlZ2lzdHJ5LiBBbiBpbnN0YW5jZSBvZiBbQ2xhc3NSZWdpc3RyeV0oLi4vLi4vYWJzdHJhY3QvcmVnaXN0cnkuanMuaHRtbCkgY2xhc3MgdGhhdCBpcyB1c2VkIGJ5IG1pbG8gdG8gcmVnaXN0ZXIgYW5kIGZpbmQgZmFjZXRzLlxuICovXG4gdmFyIGZhY2V0c1JlZ2lzdHJ5ID0gbmV3IENsYXNzUmVnaXN0cnkoQ29tcG9uZW50RmFjZXQpO1xuXG5cbi8vIEFkZHMgY29tbW9uIGFuY2VzdG9yIHRvIGFsbCBmYWNldHMgb2YgY29tcG9uZW50cyB0byB0aGUgcmVnaXN0cnkuXG5mYWNldHNSZWdpc3RyeS5hZGQoQ29tcG9uZW50RmFjZXQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZhY2V0c1JlZ2lzdHJ5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jX3JlZ2lzdHJ5JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jX2ZhY2V0cy9jZl9yZWdpc3RyeScpXG4gICAgLCBjb21wb25lbnROYW1lID0gcmVxdWlyZSgnLi4vdXRpbC9jb21wb25lbnRfbmFtZScpXG4gICAgLCBTY29wZSA9IHJlcXVpcmUoJy4vc2NvcGUnKVxuICAgICwgQmluZGVyRXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuQmluZGVyXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBDb21wb25lbnRJbmZvO1xuXG5cbi8qKlxuICogU2ltcGxlIGNsYXNzIHRvIGhvbGQgaW5mb3JtYXRpb24gYWxsb3dpbmcgdG8gY3JlYXRlL2NvcHkgY29tcG9uZW50IHVzaW5nIFtgQ29tcG9uZW50LmNyZWF0ZWBdKC4vY19jbGFzcy5qcy5odG1sI2NyZWF0ZSkgYW5kIFtgQ29tcG9uZW50LmNvcHlgXSguL2NfY2xhc3MuanMuaHRtbCNjb3B5KS5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7U2NvcGV9IHNjb3BlIHNjb3BlIG9iamVjdCB0aGUgY29tcG9uZW50IGJlbG9ncyB0bywgdXN1YWxseSBlaXRoZXIgdG9wIGxldmVsIHNjb3BlIHRoYXQgd2lsbCBiZSByZXR1cm5lZCBieSBbbWlsby5iaW5kZXJdKC4uL2JpbmRlci5qcy5odG1sKSBvciBgc2NvcGVgIHByb3BlcnR5IG9mIFtDb250YWluZXJdKC4vY19mYWNldHMvQ29udGFpbmVyLmpzLmh0bWwpIGZhY2V0IG9mIGNvbnRhaW5pbmcgY29tcG9uZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIERPTSBlbGVtZW50IHRoZSBjb21wb25lbnQgaXMgYXR0YWNoZWQgdG9cbiAqIEBwYXJhbSB7QmluZEF0dHJpYnV0ZX0gYXR0ciBCaW5kQXR0cmlidXRlIGluc3RhbmNlIHRoYXQgdGhlIGNvbXBvbmVudCB3YXMgY3JlYXRlZCB3aXRoXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHRocm93T25FcnJvcnMgSWYgc2V0IHRvIGZhbHNlLCB0aGVuIGVycm9ycyB3aWxsIG9ubHkgYmUgbG9nZ2VkIHRvIGNvbnNvbGUuIFRydWUgYnkgZGVmYXVsdC5cbiAqIEByZXR1cm4ge0NvbXBvbmVudEluZm99XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudEluZm8oc2NvcGUsIGVsLCBhdHRyLCB0aHJvd09uRXJyb3JzKSB7XG4gICAgYXR0ci5wYXJzZSgpLnZhbGlkYXRlKCk7XG5cbiAgICB0aGlzLnNjb3BlID0gc2NvcGU7XG4gICAgdGhpcy5lbCA9IGVsO1xuICAgIHRoaXMuYXR0ciA9IGF0dHI7XG4gICAgdGhpcy5uYW1lID0gYXR0ci5jb21wTmFtZTtcbiAgICB0aGlzLkNvbXBvbmVudENsYXNzID0gZ2V0Q29tcG9uZW50Q2xhc3MoYXR0ciwgdGhyb3dPbkVycm9ycyk7XG4gICAgdGhpcy5leHRyYUZhY2V0c0NsYXNzZXMgPSBnZXRDb21wb25lbnRFeHRyYUZhY2V0cyh0aGlzLkNvbXBvbmVudENsYXNzLCBhdHRyLCB0aHJvd09uRXJyb3JzKTtcblxuICAgIGlmICh0aGlzLkNvbXBvbmVudENsYXNzXG4gICAgICAgICAgICAmJiBoYXNDb250YWluZXJGYWNldCh0aGlzLkNvbXBvbmVudENsYXNzLCB0aGlzLmV4dHJhRmFjZXRzQ2xhc3NlcykpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXIgPSB7fTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiAjIyMjQ29tcG9uZW50SW5mbyBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICogXG4gKiAtIFtkZXN0cm95XSgjQ29tcG9uZW50SW5mbyRkZXN0cm95KVxuICogLSBbcmVuYW1lXSgjQ29tcG9uZW50SW5mbyRyZW5hbWUpXG4gKi9cbl8uZXh0ZW5kUHJvdG8oQ29tcG9uZW50SW5mbywge1xuICAgIGRlc3Ryb3k6IENvbXBvbmVudEluZm8kZGVzdHJveSxcbiAgICByZW5hbWU6IENvbXBvbmVudEluZm8kcmVuYW1lXG59KTtcblxuXG4vKipcbiAqIENvbXBvbmVudEluZm8gaW5zdGFuY2UgbWV0aG9kXG4gKiBEZXN0cm95cyBDb21wb25lbnRJbmZvIGJ5IHJlbW92aW5nIHRoZSByZWZlcmVuY2VzIHRvIERPTSBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudEluZm8kZGVzdHJveSgpIHtcbiAgICBkZWxldGUgdGhpcy5lbDtcbiAgICB0aGlzLmF0dHIuZGVzdHJveSgpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50SW5mbyBpbnN0YW5jZSBtZXRob2RcbiAqIFJlbmFtZXMgQ29tcG9uZW50SW5mbyBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge1tTdHJpbmddfSBuYW1lIG9wdGlvbmFsIG5ldyBjb21wb25lbnQgbmFtZSwgZ2VuZXJhdGVkIGZyb20gdGltZXN0YW1wIGJ5IGRlZmF1bHRcbiAqIEBwYXJhbSB7W0Jvb2xlYW5dfSByZW5hbWVJblNjb3BlIG9wdGlvbmFsIGZhbHNlIHRvIG5vdCByZW5hbWUgQ29tcG9uZW50SW5mbyBvYmplY3QgaW4gaXRzIHNjb3BlLCB0cnVlIGJ5IGRlZmF1bHRcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50SW5mbyRyZW5hbWUobmFtZSwgcmVuYW1lSW5TY29wZSkge1xuICAgIG5hbWUgPSBuYW1lIHx8IGNvbXBvbmVudE5hbWUoKTtcbiAgICBTY29wZS5yZW5hbWUodGhpcywgbmFtZSwgcmVuYW1lSW5TY29wZSk7XG4gICAgdGhpcy5hdHRyLmNvbXBOYW1lID0gbmFtZTtcbiAgICB0aGlzLmF0dHIuZGVjb3JhdGUoKTtcbn1cblxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnRDbGFzcyhhdHRyLCB0aHJvd09uRXJyb3JzKSB7XG4gICAgdmFyIENvbXBvbmVudENsYXNzID0gY29tcG9uZW50c1JlZ2lzdHJ5LmdldChhdHRyLmNvbXBDbGFzcyk7XG4gICAgaWYgKCEgQ29tcG9uZW50Q2xhc3MpXG4gICAgICAgIHJlcG9ydEJpbmRlckVycm9yKHRocm93T25FcnJvcnMsICdjbGFzcyAnICsgYXR0ci5jb21wQ2xhc3MgKyAnIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gICAgcmV0dXJuIENvbXBvbmVudENsYXNzO1xufVxuXG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudEV4dHJhRmFjZXRzKENvbXBvbmVudENsYXNzLCBhdHRyLCB0aHJvd09uRXJyb3JzKSB7XG4gICAgdmFyIGZhY2V0cyA9IGF0dHIuY29tcEZhY2V0c1xuICAgICAgICAsIGV4dHJhRmFjZXRzQ2xhc3NlcyA9IHt9O1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZmFjZXRzKSlcbiAgICAgICAgZmFjZXRzLmZvckVhY2goZnVuY3Rpb24oZmN0TmFtZSkge1xuICAgICAgICAgICAgZmN0TmFtZSA9IF8uZmlyc3RVcHBlckNhc2UoZmN0TmFtZSk7XG4gICAgICAgICAgICBpZiAoQ29tcG9uZW50Q2xhc3MuaGFzRmFjZXQoZmN0TmFtZSkpXG4gICAgICAgICAgICAgICAgcmVwb3J0QmluZGVyRXJyb3IodGhyb3dPbkVycm9ycywgJ2NsYXNzICcgKyBDb21wb25lbnRDbGFzcy5uYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJyBhbHJlYWR5IGhhcyBmYWNldCAnICsgZmN0TmFtZSk7XG4gICAgICAgICAgICBpZiAoZXh0cmFGYWNldHNDbGFzc2VzW2ZjdE5hbWVdKVxuICAgICAgICAgICAgICAgIHJlcG9ydEJpbmRlckVycm9yKHRocm93T25FcnJvcnMsICdjb21wb25lbnQgJyArIGF0dHIuY29tcE5hbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAnIGFscmVhZHkgaGFzIGZhY2V0ICcgKyBmY3ROYW1lKTtcbiAgICAgICAgICAgIHZhciBGYWNldENsYXNzID0gZmFjZXRzUmVnaXN0cnkuZ2V0KGZjdE5hbWUpO1xuICAgICAgICAgICAgZXh0cmFGYWNldHNDbGFzc2VzW2ZjdE5hbWVdID0gRmFjZXRDbGFzcztcbiAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gZXh0cmFGYWNldHNDbGFzc2VzO1xufVxuXG5cbmZ1bmN0aW9uIHJlcG9ydEJpbmRlckVycm9yKHRocm93T25FcnJvcnMsIG1lc3NhZ2UpIHtcbiAgICBpZiAodGhyb3dPbkVycm9ycyA9PT0gZmFsc2UpXG4gICAgICAgIGxvZ2dlci5lcnJvcignQ29tcG9uZW50SW5mbyBiaW5kZXIgZXJyb3I6JywgbWVzc2FnZSk7XG4gICAgZWxzZVxuICAgICAgICB0aHJvdyBuZXcgQmluZGVyRXJyb3IobWVzc2FnZSk7XG59O1xuXG5cbmZ1bmN0aW9uIGhhc0NvbnRhaW5lckZhY2V0KENvbXBvbmVudENsYXNzLCBleHRyYUZhY2V0c0NsYXNzZXMpIHtcbiAgICByZXR1cm4gKENvbXBvbmVudENsYXNzLmhhc0ZhY2V0KCdjb250YWluZXInKVxuICAgICAgICB8fCAnQ29udGFpbmVyJyBpbiBleHRyYUZhY2V0c0NsYXNzZXNcbiAgICAgICAgfHwgXy5zb21lS2V5KGV4dHJhRmFjZXRzQ2xhc3NlcywgZmFjZXRSZXF1aXJlc0NvbnRhaW5lcilcbiAgICAgICAgfHwgY2xhc3NIYXNGYWNldFRoYXRSZXF1aXJlc0NvbnRhaW5lcigpKTtcblxuICAgIGZ1bmN0aW9uIGNsYXNzSGFzRmFjZXRUaGF0UmVxdWlyZXNDb250YWluZXIoKSB7XG4gICAgICAgIHJldHVybiAoQ29tcG9uZW50Q2xhc3MucHJvdG90eXBlLmZhY2V0c0NsYXNzZXNcbiAgICAgICAgICAgICYmIF8uc29tZUtleShDb21wb25lbnRDbGFzcy5wcm90b3R5cGUuZmFjZXRzQ2xhc3NlcywgZmFjZXRSZXF1aXJlc0NvbnRhaW5lcikpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmFjZXRSZXF1aXJlc0NvbnRhaW5lcihGYWNldENsYXNzKSB7XG4gICAgICAgIHJldHVybiBGYWNldENsYXNzLnJlcXVpcmVzRmFjZXQoJ2NvbnRhaW5lcicpO1xuICAgIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENsYXNzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9hYnN0cmFjdC9yZWdpc3RyeScpXG4gICAgLCBDb21wb25lbnQgPSByZXF1aXJlKCcuL2NfY2xhc3MnKTtcblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5jb21wb25lbnRzYFxuICogQW4gaW5zdGFuY2Ugb2YgW0NsYXNzUmVnaXN0cnldKC4uL2Fic3RyYWN0L3JlZ2lzdHJ5LmpzLmh0bWwpIGNsYXNzIHRoYXQgaXMgdXNlZCBieSBtaWxvIHRvIHJlZ2lzdGVyIGFuZCBmaW5kIGNvbXBvbmVudHMuXG4gKi9cbnZhciBjb21wb25lbnRzUmVnaXN0cnkgPSBuZXcgQ2xhc3NSZWdpc3RyeShDb21wb25lbnQpO1xuXG4vLyBhZGQgY29tbW9uIGFuY2VzdG9yIHRvIGFsbCBjb21wb25lbnRzIHRvIHRoZSByZWdpc3RyeS5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoQ29tcG9uZW50KTtcblxubW9kdWxlLmV4cG9ydHMgPSBjb21wb25lbnRzUmVnaXN0cnk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxudmFyIGNvbXBvbmVudFV0aWxzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgaXNDb21wb25lbnQ6IGlzQ29tcG9uZW50LFxuICAgIGdldENvbXBvbmVudDogZ2V0Q29tcG9uZW50LFxuICAgIGdldENvbnRhaW5pbmdDb21wb25lbnQ6IGdldENvbnRhaW5pbmdDb21wb25lbnQsXG4gICAgX21ha2VDb21wb25lbnRDb25kaXRpb25GdW5jOiBfbWFrZUNvbXBvbmVudENvbmRpdGlvbkZ1bmNcbn07XG5cblxuLyoqXG4gKiBpc0NvbXBvbmVudFxuICpcbiAqIENoZWNrcyBpZiBlbGVtZW50IGhhcyBhIGNvbXBvbmVudCBhdHRhY2hlZCB0byBpdCBieVxuICogY2hlY2tpbmcgdGhlIHByZXNlbmNlIG9mIHByb3BlcnR5IGRpZmluZWQgaW4gbWlsby5jb25maWdcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIERPTSBlbGVtZW50XG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlLCBpZiBpdCBoYXMgbWlsbyBjb21wb25lbnQgYXR0YWNoZWQgdG8gaXRcbiAqL1xuZnVuY3Rpb24gaXNDb21wb25lbnQoZWwpIHtcbiAgICByZXR1cm4gZWwuaGFzT3duUHJvcGVydHkoY29uZmlnLmNvbXBvbmVudFJlZik7XG59XG5cblxuLyoqXG4gKiBnZXRDb21wb25lbnRcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIERPTSBlbGVtZW50XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9IGNvbXBvbmVudCBhdHRhY2hlZCB0byBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGdldENvbXBvbmVudChlbCkge1xuICAgIHJldHVybiBlbCAmJiBlbFtjb25maWcuY29tcG9uZW50UmVmXTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGNsb3Nlc3QgY29tcG9uZW50IHdoaWNoIGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgZWxlbWVudCxcbiAqIG9wdGlvbmFsbHksIG9ubHkgY29tcG9uZW50IHRoYXQgcGFzc2VzIGBjb25kaXRpb25gIHRlc3Qgb3IgY29udGFpbnMgc3BlY2lmaWVkIGZhY2V0XG4gKlxuICogVW5sZXNzIGByZXR1cm5DdXJyZW50YCBwYXJhbWV0ZXIgaXMgZmFsc2UsIHRoZSBmdW5jdGlvbiB3aWxsIHJldHVyblxuICogdGhlIGN1cnJlbnQgY29tcG9uZW50IG9mIHRoZSBlbGVtZW50ICh0cnVlIGJ5IGRlZmF1bHQpLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBET00gRWxlbWVudCBvciB0ZXh0IE5vZGVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcmV0dXJuQ3VycmVudCBvcHRpb25hbCBib29sZWFuIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGUgY29tcG9uZW50IG9mIHRoZSBlbGVtZW50IGNhbiBiZSByZXR1cm5lZC4gVHJ1ZSBieSBkZWZhdWx0LCBzaG91bGQgYmUgZmFsc2UgdG8gcmV0dXJuIG9ubHkgYW5jZXN0b3JzLlxuICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGNvbmRpdGlvbk9yRmFjZXQgb3B0aW9uYWwgY29uZGl0aW9uIHRoYXQgY29tcG9uZW50IHNob3VsZCBwYXNzIChvciBmYWNldCBuYW1lIGl0IHNob3VsZCBjb250YWluKVxuICogQHJldHVybiB7Q29tcG9uZW50fSBcbiAqL1xuZnVuY3Rpb24gZ2V0Q29udGFpbmluZ0NvbXBvbmVudChub2RlLCByZXR1cm5DdXJyZW50LCBjb25kaXRpb25PckZhY2V0KSB7XG4gICAgLy8gY2hlY2sobm9kZSwgTm9kZSk7IC0gY2FuJ3QgY2hlY2sgdGl5cGUgaGVyZSBhcyBpdCBpcyBtb3N0IGxpa2VseSBjb21pbmcgZnJvbSBhbm90aGVyIGZyYW1lXG4gICAgY2hlY2socmV0dXJuQ3VycmVudCwgTWF0Y2guT3B0aW9uYWwoQm9vbGVhbikpO1xuICAgIGNoZWNrKGNvbmRpdGlvbk9yRmFjZXQsIE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKEZ1bmN0aW9uLCBTdHJpbmcpKSk7XG5cbiAgICB2YXIgY29uZGl0aW9uRnVuYyA9IF9tYWtlQ29tcG9uZW50Q29uZGl0aW9uRnVuYyhjb25kaXRpb25PckZhY2V0KTtcblxuICAgIHJldHVybiBfZ2V0Q29udGFpbmluZ0NvbXBvbmVudChub2RlLCByZXR1cm5DdXJyZW50LCBjb25kaXRpb25GdW5jKTtcbn1cblxuXG5mdW5jdGlvbiBfbWFrZUNvbXBvbmVudENvbmRpdGlvbkZ1bmMoY29uZGl0aW9uT3JGYWNldCkge1xuICAgIGlmICh0eXBlb2YgY29uZGl0aW9uT3JGYWNldCA9PSAnZnVuY3Rpb24nKVxuICAgICAgICByZXR1cm4gY29uZGl0aW9uT3JGYWNldDtcbiAgICBlbHNlIGlmICh0eXBlb2YgY29uZGl0aW9uT3JGYWNldCA9PSAnc3RyaW5nJykge1xuICAgICAgICB2YXIgZmFjZXROYW1lID0gXy5maXJzdExvd2VyQ2FzZShjb25kaXRpb25PckZhY2V0KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChjb21wKSB7XG4gICAgICAgICAgIHJldHVybiBjb21wLmhhc0ZhY2V0KGZhY2V0TmFtZSk7XG4gICAgICAgIH07XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9nZXRDb250YWluaW5nQ29tcG9uZW50KGVsLCByZXR1cm5DdXJyZW50LCBjb25kaXRpb25GdW5jKSB7XG4gICAgLy8gV2hlcmUgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBhIGNvbXBvbmVudCBpdCBzaG91bGQgYmUgcmV0dXJuZWRcbiAgICAvLyBpZiByZXR1cm5DdXJyZW50IGlzIHRydWUgb3IgdW5kZWZpbmVkXG4gICAgaWYgKHJldHVybkN1cnJlbnQgIT09IGZhbHNlKSB7XG4gICAgICAgIHZhciBjb21wID0gZ2V0Q29tcG9uZW50KGVsKTtcbiAgICAgICAgaWYgKGNvbXAgJiYgKCEgY29uZGl0aW9uRnVuYyB8fCBjb25kaXRpb25GdW5jKGNvbXApKSlcbiAgICAgICAgICAgIHJldHVybiBjb21wO1xuICAgIH1cblxuICAgIC8vIFdoZXJlIHRoZXJlIGlzIG5vIHBhcmVudCBlbGVtZW50LCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHVuZGVmaW5lZFxuICAgIC8vIFRoZSBwYXJlbnQgZWxlbWVudCBpcyBjaGVja2VkIHJlY3Vyc2l2ZWx5XG4gICAgaWYgKGVsLnBhcmVudE5vZGUpXG4gICAgICAgIHJldHVybiBfZ2V0Q29udGFpbmluZ0NvbXBvbmVudChlbC5wYXJlbnROb2RlLCB0cnVlLCBjb25kaXRpb25GdW5jKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBWaWV3ID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdWaWV3JywgWydjb250YWluZXInXSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoVmlldyk7XG5cbm1vZHVsZS5leHBvcnRzID0gVmlldztcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgTWVzc2VuZ2VyQVBJID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyL21fYXBpJylcbiAgICAsIGdldEVsZW1lbnREYXRhQWNjZXNzID0gcmVxdWlyZSgnLi9kZV9kYXRhJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxuLy8gY2xhc3MgdG8gaGFuZGxlIHN1YnNjcmlidGlvbnMgdG8gY2hhbmdlcyBpbiBET00gZm9yIFVJIChtYXliZSBhbHNvIGNvbnRlbnQgZWRpdGFibGUpIGVsZW1lbnRzXG5cbi8qKlxuICogQSBjbGFzc1xuICovXG52YXIgRGF0YU1zZ0FQSSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2VuZ2VyQVBJLCAnRGF0YU1zZ0FQSScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oRGF0YU1zZ0FQSSwge1xuICAgIC8vIGltcGxlbWVudGluZyBNZXNzYWdlU291cmNlIGludGVyZmFjZVxuICAgIGluaXQ6IERhdGFNc2dBUEkkaW5pdCxcbiAgICB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2U6IHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZSxcbiAgICBmaWx0ZXJTb3VyY2VNZXNzYWdlOiBmaWx0ZXJTb3VyY2VNZXNzYWdlLFxuICAgIGNyZWF0ZUludGVybmFsRGF0YTogY3JlYXRlSW50ZXJuYWxEYXRhLFxuXG4gICAgLy8gY2xhc3Mgc3BlY2lmaWMgbWV0aG9kc1xuICAgIHZhbHVlOiBEYXRhTXNnQVBJJHZhbHVlXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhTXNnQVBJO1xuXG5cbmZ1bmN0aW9uIERhdGFNc2dBUEkkaW5pdChjb21wb25lbnQpIHtcbiAgICBNZXNzZW5nZXJBUEkucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHRoaXMuY29tcG9uZW50ID0gY29tcG9uZW50O1xuICAgIHRoaXMuZWxEYXRhID0gZ2V0RWxlbWVudERhdGFBY2Nlc3MoY29tcG9uZW50LmVsKTtcbn1cblxuXG4vLyBnZXREb21FbGVtZW50RGF0YVZhbHVlXG5mdW5jdGlvbiBEYXRhTXNnQVBJJHZhbHVlKCkgeyAvLyB2YWx1ZSBtZXRob2RcbiAgICB2YXIgY29tcG9uZW50R2V0dGVyID0gdGhpcy5jb21wb25lbnQuZGF0YS5jb25maWcuZ2V0O1xuICAgIHZhciBuZXdWYWx1ZSA9IHR5cGVvZiBjb21wb25lbnRHZXR0ZXIgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICA/IGNvbXBvbmVudEdldHRlci5jYWxsKHRoaXMuY29tcG9uZW50KVxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuZWxEYXRhLmdldCh0aGlzLmNvbXBvbmVudC5lbCk7XG5cbiAgICB0aGlzLmNvbXBvbmVudC5kYXRhLl92YWx1ZSA9IG5ld1ZhbHVlO1xuXG4gICAgcmV0dXJuIG5ld1ZhbHVlO1xufVxuXG5cbi8vIFRPRE86IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHJldHVybiByZWxldmFudCBET00gZXZlbnQgZGVwZW5kZW50IG9uIGVsZW1lbnQgdGFnXG4vLyBDYW4gYWxzbyBpbXBsZW1lbnQgYmVmb3JlZGF0YWNoYW5nZWQgZXZlbnQgdG8gYWxsb3cgcHJldmVudGluZyB0aGUgY2hhbmdlXG4vLyB0cmFuc2xhdGVUb0RvbUV2ZW50XG5mdW5jdGlvbiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHZhciBjb21wb25lbnRFdmVudCA9IHRoaXMuY29tcG9uZW50LmRhdGEuY29uZmlnLmV2ZW50O1xuICAgIHZhciBldmVudCA9IGNvbXBvbmVudEV2ZW50IHx8IHRoaXMuZWxEYXRhLmV2ZW50KHRoaXMuY29tcG9uZW50LmVsKTtcblxuICAgIGlmIChtZXNzYWdlID09ICcnICYmIGV2ZW50KVxuICAgICAgICByZXR1cm4gZXZlbnQ7ICAvLyB0aGlzLnRhZ0V2ZW50O1xufVxuXG5cbi8vIGZpbHRlckRhdGFNZXNzYWdlXG5mdW5jdGlvbiBmaWx0ZXJTb3VyY2VNZXNzYWdlKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIGRhdGEpIHtcbiAgICByZXR1cm4gZGF0YS5uZXdWYWx1ZSAhPSBkYXRhLm9sZFZhbHVlO1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZUludGVybmFsRGF0YShzb3VyY2VNZXNzYWdlLCBtZXNzYWdlLCBkYXRhKSB7XG4gICAgdmFyIG9sZFZhbHVlID0gdGhpcy5jb21wb25lbnQuZGF0YS5fdmFsdWVcbiAgICAgICAgLCBuZXdWYWx1ZSA9IHRoaXMudmFsdWUoKTtcblxuICAgIHZhciBpbnRlcm5hbERhdGEgPSB7IFxuICAgICAgICBwYXRoOiAnJyxcbiAgICAgICAgdHlwZTogJ2NoYW5nZWQnLFxuICAgICAgICBvbGRWYWx1ZTogb2xkVmFsdWUsXG4gICAgICAgIG5ld1ZhbHVlOiBuZXdWYWx1ZVxuICAgIH07XG4gICAgcmV0dXJuIGludGVybmFsRGF0YTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8qKlxuICogUmV0dXJucyBkYXRhIGFjY2VzcyBtZXRob2RzIGFuZCBldmVudHMgZm9yIGdpdmVuIERPTSBlbGVtZW50LlxuICogVXNlZCBieSBbRGF0YV0oLi4vY19mYWNldHMvRGF0YS5qcy5odG1sKSBmYWNldCBhbmQgYnkgW0RhdGFNc2dBUEldKC4vZGF0YS5qcy5odG1sKVxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xudmFyIGdldEVsZW1lbnREYXRhQWNjZXNzID0gZnVuY3Rpb24oZWwpIHtcbiAgICB2YXIgdGFnTmFtZSA9IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKVxuICAgICAgICAsIGVsRGF0YSA9IGRvbUVsZW1lbnRzRGF0YUFjY2Vzc1t0YWdOYW1lXTtcbiAgICByZXR1cm4gZWxEYXRhIHx8IGRvbUVsZW1lbnRzRGF0YUFjY2Vzcy5ieURlZmF1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RWxlbWVudERhdGFBY2Nlc3M7XG5cblxuLyoqXG4gKiBEYXRhIGFjY2VzcyBtZXRob2RzIGFuZCBldmVudHMgZm9yIERPTSBlbGVtZW50cy5cbiAqL1xudmFyIGRvbUVsZW1lbnRzRGF0YUFjY2VzcyA9IHtcbiAgICBieURlZmF1bHQ6IHtcbiAgICAgICAgcHJvcGVydHk6ICdpbm5lckhUTUwnLFxuICAgIH0sXG4gICAgJ2Rpdic6IHtcbiAgICAgICAgcHJvcGVydHk6ICdpbm5lckhUTUwnLCAvLyBoYWNrLCBzaG91bGQgYmUgaW5uZXJIVE1MPyB0byBtYWtlIHdvcmsgd2l0aCBFZGl0YWJsZSBmYWNldFxuICAgICAgICAvLyBldmVudDogJ2lucHV0J1xuICAgIH0sXG4gICAgJ3NwYW4nOiB7XG4gICAgICAgIHByb3BlcnR5OiAnaW5uZXJIVE1MJyxcbiAgICAgICAgZXZlbnQ6ICdpbnB1dCdcbiAgICB9LFxuICAgICdwJzoge1xuICAgICAgICBwcm9wZXJ0eTogJ2lubmVySFRNTCcsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfSxcbiAgICAnaW5wdXQnOiB7XG4gICAgICAgIHByb3BlcnR5OiBpbnB1dERhdGFQcm9wZXJ0eSxcbiAgICAgICAgZXZlbnQ6IGlucHV0Q2hhbmdlRXZlbnRcbiAgICB9LFxuICAgICd0ZXh0YXJlYSc6IHtcbiAgICAgICAgcHJvcGVydHk6ICd2YWx1ZScsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfSxcbiAgICAnc2VsZWN0Jzoge1xuICAgICAgICBwcm9wZXJ0eTogJ3ZhbHVlJyxcbiAgICAgICAgZXZlbnQ6ICdjaGFuZ2UnXG4gICAgfSxcbiAgICAnaW1nJzoge1xuICAgICAgICBwcm9wZXJ0eTogJ3NyYydcbiAgICB9LFxuICAgICdjYXB0aW9uJzoge1xuICAgICAgICBwcm9wZXJ0eTogJ2lubmVySFRNTCcsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfSxcbiAgICAndGhlYWQnOiB7XG4gICAgICAgIHByb3BlcnR5OiAnaW5uZXJIVE1MJyxcbiAgICAgICAgZXZlbnQ6ICdpbnB1dCdcbiAgICB9LFxuICAgICd0Ym9keSc6IHtcbiAgICAgICAgcHJvcGVydHk6ICdpbm5lckhUTUwnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH0sXG4gICAgJ3Rmb290Jzoge1xuICAgICAgICBwcm9wZXJ0eTogJ2lubmVySFRNTCcsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfVxufTtcblxuXG4vLyBjb252ZXJ0IHN0cmluZ3MgdG8gZnVuY3Rpb25zIGFuZCBjcmVhdGUgZ2V0c2V0IG1ldGhvZHNcbl8uZWFjaEtleShkb21FbGVtZW50c0RhdGFBY2Nlc3MsIGZ1bmN0aW9uKHRhZ0luZm8pIHtcbiAgICB2YXIgcHJvcGVydHkgPSB0YWdJbmZvLnByb3BlcnR5XG4gICAgICAgICwgZXZlbnQgPSB0YWdJbmZvLmV2ZW50O1xuICAgIGlmICh0eXBlb2YgcHJvcGVydHkgIT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGFnSW5mby5wcm9wZXJ0eSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gcHJvcGVydHk7IH07XG4gICAgdmFyIHByb3BGdW5jID0gdGFnSW5mby5wcm9wZXJ0eTtcbiAgICBpZiAodHlwZW9mIGV2ZW50ICE9ICdmdW5jdGlvbicpXG4gICAgICAgIHRhZ0luZm8uZXZlbnQgPSBmdW5jdGlvbigpIHsgcmV0dXJuIGV2ZW50OyB9O1xuICAgIGlmICghIHRhZ0luZm8uZ2V0KVxuICAgICAgICB0YWdJbmZvLmdldCA9IGZ1bmN0aW9uKGVsKSB7IHJldHVybiBlbFtwcm9wRnVuYyhlbCldOyB9XG4gICAgaWYgKCEgdGFnSW5mby5zZXQpXG4gICAgICAgIHRhZ0luZm8uc2V0ID0gZnVuY3Rpb24oZWwsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gKGVsW3Byb3BGdW5jKGVsKV0gPSB0eXBlb2YgdmFsdWUgPT0gJ3VuZGVmaW5lZCcgPyAnJyA6IHZhbHVlKTtcbiAgICAgICAgfVxufSk7XG5cblxuLyoqXG4gKiBUeXBlcyBvZiBpbnB1dCBlbGVtZW50c1xuICovXG52YXIgaW5wdXRFbGVtZW50VHlwZXMgPSB7XG4gICAgYnlEZWZhdWx0OiB7XG4gICAgICAgIHByb3BlcnR5OiAndmFsdWUnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH0sXG4gICAgJ2NoZWNrYm94Jzoge1xuICAgICAgICBwcm9wZXJ0eTogJ2NoZWNrZWQnLFxuICAgICAgICBldmVudDogJ2NoYW5nZSdcbiAgICB9LFxuICAgICdyYWRpbyc6IHtcbiAgICAgICAgcHJvcGVydHk6ICdjaGVja2VkJyxcbiAgICAgICAgZXZlbnQ6ICdjaGFuZ2UnXG4gICAgfSxcbiAgICAndGV4dCc6IHtcbiAgICAgICAgcHJvcGVydHk6ICd2YWx1ZScsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJuIHByb3BlcnR5IG9mIGlucHV0IGVsZW1lbnQgdG8gZ2V0L3NldCBpdHMgZGF0YVxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gaW5wdXREYXRhUHJvcGVydHkoZWwpIHtcbiAgICB2YXIgaW5wdXRUeXBlID0gaW5wdXRFbGVtZW50VHlwZXNbZWwudHlwZV07XG4gICAgcmV0dXJuIGlucHV0VHlwZVxuICAgICAgICAgICAgPyBpbnB1dFR5cGUucHJvcGVydHlcbiAgICAgICAgICAgIDogaW5wdXRFbGVtZW50VHlwZXMuYnlEZWZhdWx0LnByb3BlcnR5O1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBET00gZXZlbnQgdHlwZSB0byBsaXN0ZW4gdG8gdG8gcmVhY3QgdG8gaW5wdXQgZWxlbWVudCBjaGFuZ2VcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGlucHV0Q2hhbmdlRXZlbnQoZWwpIHtcbiAgICB2YXIgaW5wdXRUeXBlID0gaW5wdXRFbGVtZW50VHlwZXNbZWwudHlwZV07XG4gICAgcmV0dXJuIGlucHV0VHlwZVxuICAgICAgICAgICAgPyBpbnB1dFR5cGUuZXZlbnRcbiAgICAgICAgICAgIDogaW5wdXRFbGVtZW50VHlwZXMuYnlEZWZhdWx0LmV2ZW50O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBNZXNzZW5nZXJBUEkgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXIvbV9hcGknKVxuXG5cbnZhciBEcm9wTXNnQVBJID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzZW5nZXJBUEksICdEcm9wTXNnQVBJJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhEcm9wTXNnQVBJLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlOiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UsXG4gICAgZmlsdGVyU291cmNlTWVzc2FnZTogZmlsdGVyU291cmNlTWVzc2FnZSxcbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gRHJvcE1zZ0FQSTtcblxuXG52YXIgZHJvcEV2ZW50c01hcCA9IHtcbiAgICAnZHJhZ2luJzogJ2RyYWdlbnRlcicsXG4gICAgJ2RyYWdvdXQnOiAnZHJhZ2xlYXZlJ1xufTtcblxuXG5mdW5jdGlvbiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHJldHVybiBkcm9wRXZlbnRzTWFwLmhhc093blByb3BlcnR5KG1lc3NhZ2UpXG4gICAgICAgICAgICA/IGRyb3BFdmVudHNNYXBbbWVzc2FnZV1cbiAgICAgICAgICAgIDogbWVzc2FnZTtcbn1cblxuZnVuY3Rpb24gcmVzZXRGaWx0ZXJWYXJzKCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jdXJyZW50VGFyZ2V0O1xuICAgIGRlbGV0ZSB0aGlzLl9pbnNpZGU7XG59XG5cbmZ1bmN0aW9uIGZpbHRlclNvdXJjZU1lc3NhZ2Uoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgZGF0YSkgeyAvLyBkYXRhIGlzIERPTSBldmVudCBvYmplY3RcbiAgICB2YXIgb2sgPSB0cnVlO1xuXG4gICAgaWYgKHNvdXJjZU1lc3NhZ2UgPT0gJ2RyYWdlbnRlcicgJiYgbWVzc2FnZSA9PSAnZHJhZ2luJykge1xuICAgICAgICB0aGlzLl9jdXJyZW50VGFyZ2V0ID0gZGF0YS50YXJnZXQ7XG4gICAgICAgIG9rID0gIXRoaXMuX2luc2lkZTtcbiAgICAgICAgdGhpcy5faW5zaWRlID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHNvdXJjZU1lc3NhZ2UgPT0gJ2RyYWdsZWF2ZScgJiYgbWVzc2FnZSA9PSAnZHJhZ291dCcpIHtcbiAgICAgICAgb2sgPSB0aGlzLl9jdXJyZW50VGFyZ2V0ID09IGRhdGEudGFyZ2V0O1xuICAgICAgICBpZiAob2spIHJlc2V0RmlsdGVyVmFycy5jYWxsKHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoc291cmNlTWVzc2FnZSA9PSAnZHJvcCcpIHJlc2V0RmlsdGVyVmFycy5jYWxsKHRoaXMpO1xuXG4gICAgcmV0dXJuIG9rO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBET01FbWl0dGVyU291cmNlID0gcmVxdWlyZSgnLi4vLi4vc2VydmljZXMvZG9tX3NvdXJjZScpXG4gICAgLCBNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyL21fc291cmNlJylcbiAgICAsIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxudmFyIERPTUV2ZW50c1NvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoRE9NRW1pdHRlclNvdXJjZSwgJ0RPTUV2ZW50c1NvdXJjZScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oRE9NRXZlbnRzU291cmNlLCB7XG4gICAgaW5pdDogaW5pdCxcbiAgICBkZXN0cm95OiBET01FdmVudHNTb3VyY2UkZGVzdHJveSxcbiAgICBlbWl0dGVyOiBlbWl0dGVyXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBET01FdmVudHNTb3VyY2U7XG5cblxudmFyIHVzZUNhcHR1cmVQYXR0ZXJuID0gL19fY2FwdHVyZSQvXG4gICAgLCB1c2VDYXB0dXJlUG9zdGZpeCA9ICdfX2NhcHR1cmUnO1xuXG5cbi8vIGluaXQgRE9NIGV2ZW50IHNvdXJjZVxuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NlbmdlckFQSU9yQ2xhc3MsIGNvbXBvbmVudCkge1xuICAgIGNoZWNrKGNvbXBvbmVudCwgQ29tcG9uZW50KTtcbiAgICB0aGlzLmNvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgICBNZXNzYWdlU291cmNlLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gRE9NRXZlbnRzU291cmNlJGRlc3Ryb3koKSB7XG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGRlbGV0ZSB0aGlzLmNvbXBvbmVudDtcbn1cblxuXG4vLyBnZXQgRE9NIGVsZW1lbnQgb2YgY29tcG9uZW50XG5mdW5jdGlvbiBlbWl0dGVyKCkge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudC5lbDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gIyMjY29tcG9uZW50IGlmcmFtZSBzb3VyY2VcblxudmFyIE1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXIvbV9zb3VyY2UnKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi91dGlsL2xvZ2dlcicpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBGcmFtZU1lc3NhZ2VTb3VyY2VFcnJvciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZXJyb3InKS5GcmFtZU1lc3NhZ2VTb3VyY2U7XG5cbnZhciBGcmFtZU1lc3NhZ2VTb3VyY2UgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NhZ2VTb3VyY2UsICdGcmFtZU1lc3NhZ2VTb3VyY2UnLCB0cnVlKTtcblxuXG5fLmV4dGVuZFByb3RvKEZyYW1lTWVzc2FnZVNvdXJjZSwge1xuICAgIC8vIGltcGxlbWVudGluZyBNZXNzYWdlU291cmNlIGludGVyZmFjZVxuICAgIGluaXQ6IGluaXQsXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogYWRkU291cmNlU3Vic2NyaWJlcixcbiAgICByZW1vdmVTb3VyY2VTdWJzY3JpYmVyOiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyLFxuICAgIHRyaWdnZXI6IHRyaWdnZXIsXG5cbiAgICAvL2NsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICBmcmFtZVdpbmRvdzogZnJhbWVXaW5kb3csXG4gICAgaGFuZGxlRXZlbnQ6IGhhbmRsZUV2ZW50ICAvLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBGcmFtZU1lc3NhZ2VTb3VyY2U7XG5cblxuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NlbmdlckFQSU9yQ2xhc3MsIGNvbXBvbmVudCkge1xuICAgIGNoZWNrKGNvbXBvbmVudCwgQ29tcG9uZW50KTtcbiAgICB0aGlzLmNvbXBvbmVudCA9IGNvbXBvbmVudDtcblxuICAgIGlmIChjb21wb25lbnQuZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9ICdpZnJhbWUnKVxuICAgICAgICB0aHJvdyBuZXcgRnJhbWVNZXNzYWdlU291cmNlRXJyb3IoJ2NvbXBvbmVudCBmb3IgRnJhbWVNZXNzYWdlU291cmNlIGNhbiBvbmx5IGJlIGF0dGFjaGVkIHRvIGlmcmFtZSBlbGVtZW50Jyk7XG5cbiAgICBNZXNzYWdlU291cmNlLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gZnJhbWVXaW5kb3coKSB7XG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50LmVsLmNvbnRlbnRXaW5kb3c7XG59XG5cblxuLy8gYWRkSUZyYW1lTWVzc2FnZUxpc3RlbmVyXG5mdW5jdGlvbiBhZGRTb3VyY2VTdWJzY3JpYmVyKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICB2YXIgd2luID0gdGhpcy5mcmFtZVdpbmRvdygpO1xuICAgIGlmICh3aW4pIHdpbi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcywgZmFsc2UpO1xuICAgIGVsc2UgbG9nZ2VyLndhcm4oJ0ZyYW1lTWVzc2FnZVNvdXJjZTogZnJhbWUgd2luZG93IGlzIHVuZGVmaW5lZCcpO1xufVxuXG5cbi8vIHJlbW92ZUlGcmFtZU1lc3NhZ2VMaXN0ZW5lclxuZnVuY3Rpb24gcmVtb3ZlU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgdmFyIHdpbiA9IHRoaXMuZnJhbWVXaW5kb3coKTtcbiAgICBpZiAod2luKSB3aW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRoaXMsIGZhbHNlKTtcbiAgICBlbHNlIGxvZ2dlci53YXJuKCdGcmFtZU1lc3NhZ2VTb3VyY2U6IGZyYW1lIHdpbmRvdyBpcyB1bmRlZmluZWQnKTtcbn1cblxuXG5mdW5jdGlvbiB0cmlnZ2VyKG1zZ1R5cGUsIGRhdGEpIHtcbiAgICBkYXRhID0gZGF0YSB8fCB7fTtcbiAgICBkYXRhLnR5cGUgPSBtc2dUeXBlO1xuXG4gICAgdGhpcy5mcmFtZVdpbmRvdygpLnBvc3RNZXNzYWdlKGRhdGEsICcqJyk7XG59XG5cblxuLy8gVE9ETyBtYXliZSByZWZhY3RvciB0byBGcmFtZU1zZ0FQST9cbmZ1bmN0aW9uIGhhbmRsZUV2ZW50KGV2ZW50KSB7XG4gICAgdGhpcy5kaXNwYXRjaE1lc3NhZ2UoZXZlbnQuZGF0YS50eXBlLCBldmVudCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNvbXBvbmVudE5hbWUgPSByZXF1aXJlKCcuLi91dGlsL2NvbXBvbmVudF9uYW1lJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBTY29wZUVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLlNjb3BlXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpO1xuXG5cbi8qKlxuICogU2NvcGUgY2xhc3MuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RFbCB0aGUgcm9vdCBlbGVtZW50IG9mIHRoaXMgc2NvcGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IHRoZSBob3N0IFxuICogQHJldHVybiB7U2NvcGV9XG4gKi9cbmZ1bmN0aW9uIFNjb3BlKHJvb3RFbCwgaG9zdE9iamVjdCkge1xuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgIF9yb290RWw6IHJvb3RFbCxcbiAgICAgICAgX2hvc3RPYmplY3Q6IGhvc3RPYmplY3RcbiAgICB9LCBfLldSSVQpOyAvLyB3cml0YWJsZVxufTtcblxuXy5leHRlbmRQcm90byhTY29wZSwge1xuICAgIF9hZGQ6IFNjb3BlJF9hZGQsXG4gICAgX3NhZmVBZGQ6IFNjb3BlJF9zYWZlQWRkLFxuICAgIF9jb3B5OiBTY29wZSRfY29weSxcbiAgICBfZWFjaDogU2NvcGUkX2VhY2gsXG4gICAgX21vdmU6IFNjb3BlJF9tb3ZlLFxuICAgIF9tZXJnZTogU2NvcGUkX21lcmdlLFxuICAgIF9sZW5ndGg6IFNjb3BlJF9sZW5ndGgsXG4gICAgX2FueTogU2NvcGUkX2FueSxcbiAgICBfcmVtb3ZlOiBTY29wZSRfcmVtb3ZlLFxuICAgIF9jbGVhbjogU2NvcGUkX2NsZWFuLFxuICAgIF9kZXRhY2hFbGVtZW50OiBTY29wZSRfZGV0YWNoRWxlbWVudCxcbiAgICBfaGFzOiBTY29wZSRfaGFzLFxuICAgIF9maWx0ZXI6IFNjb3BlJF9maWx0ZXJcbn0pO1xuXG5cbl8uZXh0ZW5kKFNjb3BlLCB7XG4gICAgcmVuYW1lOiBTY29wZSQkcmVuYW1lXG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjb3BlO1xuXG5cbnZhciBhbGxvd2VkTmFtZVBhdHRlcm4gPSAvXltBLVphLXpdW0EtWmEtejAtOVxcX1xcJF0qJC87XG5cblxuLyoqXG4gKiBTY29wZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBBZGRzIG9iamVjdCB0byB0aGUgc2NvcGUsIHRocm93aW5nIGlmIG5hbWUgaXMgbm90IHVuaXF1ZVxuICogQHBhcmFtIHtDb21wb25lbnR8Q29tcG9uZW50SW5mb30gb2JqZWN0IGNvbXBvbmVudCBvciBjb21wb25lbnQgaW5mbyB0byBhZGQgdG8gdGhlIHNjb3BlXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgY29tcG9uZW50IHRvIGFkZFxuICovXG5mdW5jdGlvbiBTY29wZSRfYWRkKG9iamVjdCwgbmFtZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSA9PSAnc3RyaW5nJylcbiAgICAgICAgb2JqZWN0Lm5hbWUgPSBuYW1lO1xuICAgIGVsc2VcbiAgICAgICAgbmFtZSA9IG9iamVjdC5uYW1lO1xuICAgIFxuICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KG5hbWUpKVxuICAgICAgICB0aHJvdyBuZXcgU2NvcGVFcnJvcignZHVwbGljYXRlIG9iamVjdCBuYW1lOiAnICsgbmFtZSk7XG5cbiAgICBjaGVja05hbWUobmFtZSk7XG4gICAgX19hZGQuY2FsbCh0aGlzLCBvYmplY3QsIG5hbWUpO1xufVxuXG5cbi8qKlxuICogU2NvcGUgaW5zdGFuY2UgbWV0aG9kXG4gKiBBZGRzIG9iamVjdCB0byBzY29wZSByZW5hbWluZyBpdCBpZiBuYW1lIGlzIG5vdCB1bmlxdWVcbiAqIEBwYXJhbSB7Q29tcG9uZW50fENvbXBvbmVudEluZm99IG9iamVjdCBjb21wb25lbnQgb3IgY29tcG9uZW50IGluZm8gdG8gYWRkIHRvIHRoZSBzY29wZVxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIGNvbXBvbmVudCB0byBhZGRcbiAqL1xuZnVuY3Rpb24gU2NvcGUkX3NhZmVBZGQob2JqZWN0LCBuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lID09ICdzdHJpbmcnKVxuICAgICAgICBvYmplY3QubmFtZSA9IG5hbWU7XG4gICAgZWxzZVxuICAgICAgICBuYW1lID0gb2JqZWN0Lm5hbWU7XG5cbiAgICB2YXIgc2hvdWxkUmVuYW1lID0gdGhpcy5oYXNPd25Qcm9wZXJ0eShuYW1lKTtcbiAgICBpZiAoc2hvdWxkUmVuYW1lKVxuICAgICAgICBsb2dnZXIuZXJyb3IoJ1Njb3BlOiBkdXBsaWNhdGUgb2JqZWN0IG5hbWU6ICcgKyBuYW1lKTtcbiAgICBlbHNlIHtcbiAgICAgICAgc2hvdWxkUmVuYW1lID0gISBhbGxvd2VkTmFtZVBhdHRlcm4udGVzdChuYW1lKTtcbiAgICAgICAgaWYgKHNob3VsZFJlbmFtZSlcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignU2NvcGU6IG5hbWUgc2hvdWxkIHN0YXJ0IGZyb20gbGV0dGVyLCB0aGlzIG5hbWUgaXMgbm90IGFsbG93ZWQ6ICcgKyBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoc2hvdWxkUmVuYW1lKSB7XG4gICAgICAgIG5hbWUgPSBjb21wb25lbnROYW1lKCk7XG4gICAgICAgIG9iamVjdC5uYW1lID0gbmFtZTtcbiAgICB9XG5cbiAgICBfX2FkZC5jYWxsKHRoaXMsIG9iamVjdCwgbmFtZSk7XG59XG5cblxuZnVuY3Rpb24gX19hZGQob2JqZWN0LCBuYW1lKSB7XG4gICAgdGhpc1tuYW1lXSA9IG9iamVjdDtcbiAgICBvYmplY3Quc2NvcGUgPSB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBvYmplY3QucG9zdE1lc3NhZ2UgPT09ICdmdW5jdGlvbicpXG4gICAgICAgIG9iamVjdC5wb3N0TWVzc2FnZSgnYWRkZWR0b3Njb3BlJyk7IFxufVxuXG5cbi8qKlxuICogSW5zdGFuY2UgbWV0aG9kLlxuICogY29waWVzIGFsbCBvYmplY3RzIGZyb20gb25lIHNjb3BlIHRvIGFub3RoZXIsXG4gKiB0aHJvd2luZyBpZiBzb21lIG9iamVjdCBpcyBub3QgdW5pcXVlXG4gKiBAcGFyYW0ge1Njb3BlfSBhU2NvcGUgdGhlIHNjb3BlIHRvIGNvcHlcbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2NvcHkoYVNjb3BlKSB7XG4gICAgY2hlY2soYVNjb3BlLCBTY29wZSk7XG5cbiAgICBhU2NvcGUuX2VhY2goU2NvcGUkX2FkZCwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBJbnN0YW5jZSBtZXRob2QuXG4gKiBNb3ZlcyBhIGNvbXBvbmVudCBmcm9tIHRoaXMgc2NvcGUgdG8gYW5vdGhlciBzY29wZS5cbiAqIEBwYXJhbSB7Q29tcG9uZW50fSBjb21wb25lbnQgdGhlIGNvbXBvbmVudCB0byBiZSBtb3ZlZFxuICogQHBhcmFtIHtTY29wZX0gb3RoZXJTY29wZSB0aGUgc2NvcGUgdG8gY29weSB0aGUgY29tcG9uZW50IHRvXG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9tb3ZlKGNvbXBvbmVudCwgb3RoZXJTY29wZSkge1xuICAgIG90aGVyU2NvcGUuX2FkZChjb21wb25lbnQpO1xuICAgIHRoaXMuX3JlbW92ZShjb21wb25lbnQubmFtZSk7XG4gICAgY29tcG9uZW50LnNjb3BlID0gb3RoZXJTY29wZTtcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIE1lcmdlcyBvbmUgc2NvcGUgaW50byB0aGlzIHNjb3BlXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSB0aGUgc2NvcGUgdG8gYWJzb3JiXG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9tZXJnZShzY29wZSkge1xuICAgIHNjb3BlLl9lYWNoKGZ1bmN0aW9uIChjb21wKSB7XG4gICAgICAgIHRoaXMuX2FkZChjb21wLCBjb21wLm5hbWUpO1xuICAgICAgICBzY29wZS5fcmVtb3ZlKGNvbXAubmFtZSk7XG4gICAgfSwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBJbnN0YW5jZSBtZXRob2QuXG4gKiBFbnVtZXJhdGVzIGVhY2ggY29tcG9uZW50IGluIHRoZSBzY29wZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdGhlIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgZm9yIGVhY2ggY29tcG9uZW50XG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyB0aGUgY29udGV4dFxuICovXG5mdW5jdGlvbiBTY29wZSRfZWFjaChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIF8uZWFjaEtleSh0aGlzLCBjYWxsYmFjaywgdGhpc0FyZyB8fCB0aGlzLCB0cnVlKTsgLy8gZW51bWVyYXRlcyBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seVxufVxuXG5cbi8qKlxuICogSW5zdGFuY2UgbWV0aG9kLlxuICogUmV0dXJucyBhIGZpbHRlcmVkIGxpc3Qgb2YgY29tcG9uZW50cyBiYXNlZCBvbiBhIGNhbGxiYWNrXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0aGUgZnVuY3Rpb24gdG8gZXhlY3V0ZSBmb3IgZWFjaCBjb21wb25lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIHRoZSBjb250ZXh0XG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2ZpbHRlcihjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIHJldHVybiBfLmZpbHRlcktleXModGhpcywgY2FsbGJhY2ssIHRoaXNBcmcgfHwgdGhpcywgdHJ1ZSk7XG59XG5cblxuLyoqXG4gKiBDaGVja3MgdGhlIHZhbGlkaXR5IG9mIGEgbmFtZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRoZSBmdW5jdGlvbiB0byBleGVjdXRlIGZvciBlYWNoIGNvbXBvbmVudFxuICovXG5mdW5jdGlvbiBjaGVja05hbWUobmFtZSkge1xuICAgIGlmICghIGFsbG93ZWROYW1lUGF0dGVybi50ZXN0KG5hbWUpKVxuICAgICAgICB0aHJvdyBuZXcgU2NvcGVFcnJvcignbmFtZSBzaG91bGQgc3RhcnQgZnJvbSBsZXR0ZXIsIHRoaXMgbmFtZSBpcyBub3QgYWxsb3dlZDogJyArIG5hbWUpO1xufVxuXG5cbi8qKlxuICogSW5zdGFuY2UgbWV0aG9kLlxuICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhlIHNjb3BlXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9sZW5ndGgoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMpLmxlbmd0aDtcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgYSBjb21wb25lbnQgZnJvbSB0aGUgc2NvcGUuIEl0IG1heSBsb29rIGxpa2UgaXQgcmV0dXJucyB0aGUgZmlyc3QgY29tcG9uZW50XG4gKiBidXQgaW4gcmVhbGl0eSBnaXZlbiB0aGF0IHNjb3BlcyBhcmUgaGFzaGVzLCB0aGVyZSBpcyBubyBzdWNoIHRoaW5nLlxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBTY29wZSRfYW55KCkge1xuICAgIHZhciBrZXkgPSBPYmplY3Qua2V5cyh0aGlzKVswXTtcbiAgICByZXR1cm4ga2V5ICYmIHRoaXNba2V5XTtcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIFJlbW92ZXMgYSBjb21wb25lbnQgZnJvbSB0aGUgc2NvcGUgYnkgaXQncyBuYW1lLlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIGNvbXBvbmVudCB0byByZW1vdmVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcXVpZXQgb3B0aW9uYWwgdHJ1ZSB0byBzdXBwcmVzcyB0aGUgd2FybmluZyBtZXNzYWdlIGlmIHRoZSBjb21wb25lbnQgaXMgbm90IGluIHNjb3BlXG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9yZW1vdmUobmFtZSwgcXVpZXQpIHtcbiAgICBpZiAoISAobmFtZSBpbiB0aGlzKSkge1xuICAgICAgICBpZiAoIXF1aWV0KSBsb2dnZXIud2FybigncmVtb3Zpbmcgb2JqZWN0IHRoYXQgaXMgbm90IGluIHNjb3BlJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb2JqZWN0ID0gdGhpc1tuYW1lXTtcblxuICAgIGRlbGV0ZSB0aGlzW25hbWVdO1xuXG4gICAgaWYgKHR5cGVvZiBvYmplY3QucG9zdE1lc3NhZ2UgPT09ICdmdW5jdGlvbicpXG4gICAgICAgIG9iamVjdC5wb3N0TWVzc2FnZSgncmVtb3ZlZGZyb21zY29wZScpO1xufVxuXG5cbi8qKlxuICogSW5zdGFuY2UgbWV0aG9kLlxuICogUmVtb3ZlcyBhbGwgY29tcG9uZW50cyBmcm9tIHRoZSBzY29wZS5cbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2NsZWFuKCkge1xuICAgIHRoaXMuX2VhY2goZnVuY3Rpb24ob2JqZWN0LCBuYW1lKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzW25hbWVdLnNjb3BlO1xuICAgICAgICBkZWxldGUgdGhpc1tuYW1lXTtcbiAgICB9LCB0aGlzKTtcbn1cblxuZnVuY3Rpb24gU2NvcGUkX2RldGFjaEVsZW1lbnQoKSB7XG4gICAgdGhpcy5fcm9vdEVsID0gbnVsbDtcbn1cblxuXG4vKipcbiAqIENoZWNrcyBpZiBzY29wZSBoYXMgb2JqZWN0IGJ5IG9iamVjdCBuYW1lXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBTY29wZSRfaGFzKG9iamVjdCkge1xuICAgIHJldHVybiB0aGlzLmhhc093blByb3BlcnR5KG9iamVjdC5uYW1lKTtcbn1cblxuXG4vKipcbiAqIENoYW5nZSBvYmplY3QgbmFtZSwgcmVuYW1pbmcgaXQgaW4gc2NvcGUgdW5sZXNzIHJlbmFtZUluU2NvcGUgaXMgZmFsc2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5ldyBuYW1lXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJlbmFtZUluU2NvcGUgdHJ1ZSBieSBkZWZhdWx0XG4gKi9cbmZ1bmN0aW9uIFNjb3BlJCRyZW5hbWUob2JqLCBuYW1lLCByZW5hbWVJblNjb3BlKSB7XG4gICAgaWYgKG9iai5zY29wZSAmJiByZW5hbWVJblNjb3BlICE9PSBmYWxzZSkge1xuICAgICAgICBvYmouc2NvcGUuX3JlbW92ZShvYmoubmFtZSk7XG4gICAgICAgIG9iai5zY29wZS5fYWRkKG9iaiwgbmFtZSk7XG4gICAgfSBlbHNlXG4gICAgICAgIG9iai5uYW1lID0gbmFtZTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBNTEJ1dHRvbiA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxCdXR0b24nLCB7XG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLWJ1dHRvbidcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTEJ1dHRvbik7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxCdXR0b247XG5cbl8uZXh0ZW5kUHJvdG8oTUxCdXR0b24sIHtcbiAgICBkaXNhYmxlOiBNTEJ1dHRvbiRkaXNhYmxlLFxuICAgIGlzRGlzYWJsZWQ6IE1MQnV0dG9uJGlzRGlzYWJsZWRcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MQnV0dG9uJGRpc2FibGUoZGlzYWJsZSkge1xuICAgIHRoaXMuZWwuZGlzYWJsZWQgPSBkaXNhYmxlO1xufVxuXG5mdW5jdGlvbiBNTEJ1dHRvbiRpc0Rpc2FibGVkKCkge1xuICAgIHJldHVybiAhIXRoaXMuZWwuZGlzYWJsZWQ7XG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxudmFyIENPTUJPX0NIQU5HRV9NRVNTQUdFID0gJ21sY29tYm9jaGFuZ2UnO1xuXG52YXIgREFUQUxJU1RfVEVNUExBVEUgPSAne3t+IGl0LmNvbWJvT3B0aW9ucyA6b3B0aW9uIH19IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInt7PSBvcHRpb24ubGFiZWwgfX1cIj48L29wdGlvbj4gXFxcbiAgICAgICAgICAgICAgICAgICAgICAgICB7e359fSc7XG5cbnZhciBNTENvbWJvID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTENvbWJvJywge1xuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRhdGE6IHtcbiAgICAgICAgZ2V0OiBNTENvbWJvX2dldCxcbiAgICAgICAgc2V0OiBNTENvbWJvX3NldCxcbiAgICAgICAgZGVsOiBNTENvbWJvX2RlbCxcbiAgICAgICAgc3BsaWNlOiB1bmRlZmluZWQsXG4gICAgICAgIGV2ZW50OiBDT01CT19DSEFOR0VfTUVTU0FHRVxuICAgIH0sXG4gICAgbW9kZWw6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICcqKionOiB7IHN1YnNjcmliZXI6IG9uT3B0aW9uc0NoYW5nZSwgY29udGV4dDogJ293bmVyJyB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1kYXRhbGlzdCdcbiAgICB9LFxuICAgIGNvbnRhaW5lcjogdW5kZWZpbmVkXG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTENvbWJvKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTENvbWJvO1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxDb21ibywge1xuICAgIGluaXQ6IE1MQ29tYm8kaW5pdFxufSk7XG5cblxuZnVuY3Rpb24gTUxDb21ibyRpbml0KCkge1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMub24oJ2NoaWxkcmVuYm91bmQnLCBvbkNoaWxkcmVuQm91bmQpO1xufVxuXG5mdW5jdGlvbiBvbkNoaWxkcmVuQm91bmQoKSB7XG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgJ19jb21ib0lucHV0JzogdGhpcy5jb250YWluZXIuc2NvcGUuaW5wdXQsXG4gICAgICAgICdfY29tYm9MaXN0JzogdGhpcy5jb250YWluZXIuc2NvcGUuZGF0YWxpc3RcbiAgICB9KTtcblxuICAgIHRoaXMuX2NvbWJvTGlzdC50ZW1wbGF0ZS5zZXQoREFUQUxJU1RfVEVNUExBVEUpO1xuXG4gICAgdGhpcy5fY29tYm9JbnB1dC5kYXRhLm9uKCdpbnB1dCcsXG4gICAgICAgIHsgc3Vic2NyaWJlcjogZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlLCBjb250ZXh0OiB0aGlzIH0pO1xufVxuXG5mdW5jdGlvbiBNTENvbWJvX2dldCgpIHtcbiAgICBpZiAoISB0aGlzLl9jb21ib0lucHV0KSByZXR1cm47XG4gICAgcmV0dXJuIHRoaXMuX2NvbWJvSW5wdXQuZGF0YS5nZXQoKTtcbn1cblxuZnVuY3Rpb24gTUxDb21ib19zZXQodmFsdWUpIHtcbiAgICByZXR1cm4gY2hhbmdlQ29tYm9EYXRhLmNhbGwodGhpcywgJ3NldCcsIHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gTUxDb21ib19kZWwoKSB7XG4gICAgcmV0dXJuIGNoYW5nZUNvbWJvRGF0YS5jYWxsKHRoaXMsICdkZWwnLCB2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGNoYW5nZUNvbWJvRGF0YShtZXRob2QsIHZhbHVlKSB7XG4gICAgaWYgKCEgdGhpcy5fY29tYm9JbnB1dCkgcmV0dXJuO1xuICAgIHZhciByZXN1bHQgPSB0aGlzLl9jb21ib0lucHV0LmRhdGFbbWV0aG9kXSh2YWx1ZSk7XG4gICAgZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vLyBQb3N0IHRoZSBkYXRhIGNoYW5nZVxuZnVuY3Rpb24gZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlKCkge1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoQ09NQk9fQ0hBTkdFX01FU1NBR0UpO1xufVxuXG5mdW5jdGlvbiBvbk9wdGlvbnNDaGFuZ2UobXNnLCBkYXRhKSB7XG4gICAgdGhpcy5fY29tYm9MaXN0LnRlbXBsYXRlLnJlbmRlcih7XG4gICAgICAgIGNvbWJvT3B0aW9uczogdGhpcy5tb2RlbC5nZXQoKVxuICAgIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxudmFyIENPTUJPX0xJU1RfQ0hBTkdFX01FU1NBR0UgPSAnbWxjb21ib2xpc3RjaGFuZ2UnO1xuXG5cbnZhciBNTENvbWJvTGlzdCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxDb21ib0xpc3QnLCB7XG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLWNvbWJvLWxpc3QnXG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICAgIGdldDogTUxDb21ib0xpc3RfZ2V0LFxuICAgICAgICBzZXQ6IE1MQ29tYm9MaXN0X3NldCxcbiAgICAgICAgZGVsOiBNTENvbWJvTGlzdF9kZWwsXG4gICAgICAgIGV2ZW50OiBDT01CT19MSVNUX0NIQU5HRV9NRVNTQUdFXG4gICAgfSxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBtb2RlbDoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJyoqKic6IHsgc3Vic2NyaWJlcjogb25JdGVtc0NoYW5nZSwgY29udGV4dDogJ293bmVyJ31cbiAgICAgICAgfVxuICAgIH0sXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgICAgdGVtcGxhdGU6ICc8ZGl2IG1sLWJpbmQ9XCJNTFN1cGVyQ29tYm86Y29tYm9cIj48L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIk1MTGlzdDpsaXN0XCI+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBtbC1iaW5kPVwiTUxMaXN0SXRlbTppdGVtXCIgY2xhc3M9XCJsaXN0LWl0ZW1cIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gbWwtYmluZD1cIltkYXRhXTpsYWJlbFwiPjwvc3Bhbj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gbWwtYmluZD1cIltldmVudHNdOmRlbGV0ZUJ0blwiIGNsYXNzPVwiZ2x5cGhpY29uIGdseXBoaWNvbi1yZW1vdmVcIj48L3NwYW4+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICA8L2Rpdj4nXG4gICAgfVxufSk7XG5cblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTENvbWJvTGlzdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxDb21ib0xpc3Q7XG5cblxuXy5leHRlbmRQcm90byhNTENvbWJvTGlzdCwge1xuICAgIGluaXQ6IE1MQ29tYm9MaXN0JGluaXQsXG4gICAgc2V0T3B0aW9uczogTUxDb21ib0xpc3Qkc2V0T3B0aW9ucyxcbiAgICBzZXREYXRhVmFsaWRhdGlvbjogTUxDb21ib0xpc3Qkc2V0RGF0YVZhbGlkYXRpb24sXG4gICAgdG9nZ2xlQWRkQnV0dG9uOiBNTENvbWJvTGlzdCR0b2dnbGVBZGRCdXR0b24sXG4gICAgZGVzdHJveTogTUxDb21ib0xpc3QkZGVzdHJveSxcbiAgICBzZXRBZGRJdGVtUHJvbXB0OiBNTENvbWJvTGlzdCRzZXRBZGRJdGVtUHJvbXB0LFxuICAgIGNsZWFyQ29tYm9JbnB1dCA6IE1MQ29tYm9MaXN0JGNsZWFyQ29tYm9JbnB1dFxufSk7XG5cblxuZnVuY3Rpb24gTUxDb21ib0xpc3QkaW5pdCgpIHtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLl9kYXRhVmFsaWRhdGlvbiA9IGZ1bmN0aW9uICgpIHt9O1xuICAgIHRoaXMubW9kZWwuc2V0KFtdKTtcbiAgICB0aGlzLm9uY2UoJ2NoaWxkcmVuYm91bmQnLCBvbkNoaWxkcmVuQm91bmQpO1xufVxuXG5cbmZ1bmN0aW9uIE1MQ29tYm9MaXN0JHNldERhdGFWYWxpZGF0aW9uKGRhdGFWYWxpZGF0aW9uKSB7XG4gICAgaWYgKHR5cGVvZiBkYXRhVmFsaWRhdGlvbiA9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aGlzLl9kYXRhVmFsaWRhdGlvbiA9IGRhdGFWYWxpZGF0aW9uO1xufVxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdCRzZXRPcHRpb25zKGFycikge1xuICAgIHRoaXMuX2NvbWJvLnNldE9wdGlvbnMoYXJyKTtcbn1cblxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdCRjbGVhckNvbWJvSW5wdXQgKCkge1xuICAgIHRoaXMuX2NvbWJvLmNsZWFyQ29tYm9JbnB1dCgpO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEhpZGVzIGFkZCBidXR0b25cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hvd1xuICovXG5mdW5jdGlvbiBNTENvbWJvTGlzdCR0b2dnbGVBZGRCdXR0b24oc2hvdykge1xuICAgIHRoaXMuX2NvbWJvLnRvZ2dsZUFkZEJ1dHRvbihzaG93KTtcbn1cblxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdCRzZXRBZGRJdGVtUHJvbXB0KHByb21wdCkge1xuICAgdGhpcy5fY29tYm8uc2V0QWRkSXRlbVByb21wdChwcm9tcHQpO1xufVxuXG5cbmZ1bmN0aW9uIE1MQ29tYm9MaXN0JGRlc3Ryb3koKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5fY29ubmVjdG9yICYmIG1pbG8ubWluZGVyLmRlc3Ryb3lDb25uZWN0b3IodGhpcy5fY29ubmVjdG9yKTtcbiAgICB0aGlzLl9jb25uZWN0b3IgPSBudWxsO1xufVxuXG5cbmZ1bmN0aW9uIG9uQ2hpbGRyZW5Cb3VuZCgpIHtcbiAgICB0aGlzLnRlbXBsYXRlLnJlbmRlcigpLmJpbmRlcigpO1xuICAgIGNvbXBvbmVudFNldHVwLmNhbGwodGhpcyk7XG59XG5cbmZ1bmN0aW9uIGNvbXBvbmVudFNldHVwKCkge1xuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgICdfY29tYm8nOiB0aGlzLmNvbnRhaW5lci5zY29wZS5jb21ibyxcbiAgICAgICAgJ19saXN0JzogdGhpcy5jb250YWluZXIuc2NvcGUubGlzdFxuICAgIH0pO1xuXG4gICAgdGhpcy5fY29ubmVjdG9yID0gbWlsby5taW5kZXIodGhpcy5fbGlzdC5tb2RlbCwgJzw8PC0+Pj4nLCB0aGlzLm1vZGVsKTtcbiAgICB0aGlzLl9jb21iby5kYXRhLm9uKCcnLCB7IHN1YnNjcmliZXI6IG9uQ29tYm9DaGFuZ2UsIGNvbnRleHQ6IHRoaXMgfSk7XG4gICAgdGhpcy5fY29tYm8ub24oJ2FkZGl0ZW0nLCB7IHN1YnNjcmliZXI6IG9uQWRkSXRlbSwgY29udGV4dDogdGhpcyB9KTtcbn1cblxuZnVuY3Rpb24gb25Db21ib0NoYW5nZShtc2csIGRhdGEpIHtcbiAgICBpZiAoZGF0YS5uZXdWYWx1ZSAmJiB0aGlzLl9kYXRhVmFsaWRhdGlvbihtc2csIGRhdGEsIHRoaXMuX2xpc3QubW9kZWwuZ2V0KCkpKVxuICAgICAgICB0aGlzLl9saXN0Lm1vZGVsLnB1c2goZGF0YS5uZXdWYWx1ZSk7XG4gICAgdGhpcy5fY29tYm8uZGF0YS5kZWwoKTtcbiAgICAvLyBiZWNhdXNlIG9mIHN1cGVyY29tYm8gbGlzdGVuZXJzIG9mZiB5b3UgaGF2ZSB0byBzZXQgX3ZhbHVlIGV4cGxpY2l0bHlcbiAgICB0aGlzLl9jb21iby5kYXRhLl92YWx1ZSA9ICcnO1xufVxuXG5mdW5jdGlvbiBvbkl0ZW1zQ2hhbmdlKG1zZywgZGF0YSkge1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoQ09NQk9fTElTVF9DSEFOR0VfTUVTU0FHRSk7XG59XG5cbmZ1bmN0aW9uIE1MQ29tYm9MaXN0X2dldCgpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLm1vZGVsLmdldCgpO1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcgPyBfLmNsb25lKHZhbHVlKSA6IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdF9zZXQodmFsdWUpIHtcbiAgICB0aGlzLm1vZGVsLnNldCh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIE1MQ29tYm9MaXN0X2RlbCgpIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbC5zZXQoW10pO1xufVxuXG5cbmZ1bmN0aW9uIG9uQWRkSXRlbShtc2csIGRhdGEpIHtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKCdhZGRpdGVtJywgZGF0YSk7XG4gICAgdGhpcy5ldmVudHMucG9zdE1lc3NhZ2UoJ21pbG9fY29tYm9saXN0YWRkaXRlbScsIGRhdGEpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxudmFyIE1MRGF0ZSA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxEYXRlJywge1xuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRhdGE6IHtcbiAgICAgICAgZ2V0OiBNTERhdGVfZ2V0LFxuICAgICAgICBzZXQ6IE1MRGF0ZV9zZXQsXG4gICAgICAgIGRlbDogTUxEYXRlX2RlbCxcbiAgICB9LFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1kYXRlJ1xuICAgIH1cbn0pO1xuXG5fLmV4dGVuZFByb3RvKE1MRGF0ZSwge1xuICAgIGdldE1pbjogTUxEYXRlJGdldE1pbixcbiAgICBzZXRNaW46IE1MRGF0ZSRzZXRNaW4sXG4gICAgZ2V0TWF4OiBNTERhdGUkZ2V0TWF4LFxuICAgIHNldE1heDogTUxEYXRlJHNldE1heFxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxEYXRlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTERhdGU7XG5cblxuZnVuY3Rpb24gTUxEYXRlJGdldE1pbigpIHtcbiAgICByZXR1cm4gXy5kYXRlKHRoaXMuZWwubWluKTtcbn1cblxuXG5mdW5jdGlvbiBNTERhdGUkc2V0TWluKHZhbHVlKSB7XG4gICAgdmFyIGRhdGUgPSBfLnRvRGF0ZSh2YWx1ZSk7XG5cbiAgICB0aGlzLmVsLm1pbiA9IGRhdGUgPyB0b0lTTzg2MDFGb3JtYXQoZGF0ZSkgOiAnJztcbn1cblxuXG5mdW5jdGlvbiBNTERhdGUkZ2V0TWF4KCkge1xuICAgIHJldHVybiBfLmRhdGUodGhpcy5lbC5tYXgpO1xufVxuXG5cbmZ1bmN0aW9uIE1MRGF0ZSRzZXRNYXgodmFsdWUpIHtcbiAgICB2YXIgZGF0ZSA9IF8udG9EYXRlKHZhbHVlKTtcblxuICAgIHRoaXMuZWwubWF4ID0gZGF0ZSA/IHRvSVNPODYwMUZvcm1hdChkYXRlKSA6ICcnO1xufVxuXG5cbmZ1bmN0aW9uIE1MRGF0ZV9nZXQoKSB7XG4gICAgcmV0dXJuIF8udG9EYXRlKHRoaXMuZWwudmFsdWUpO1xufVxuXG5cbmZ1bmN0aW9uIE1MRGF0ZV9zZXQodmFsdWUpIHtcbiAgICB2YXIgZGF0ZSA9IF8udG9EYXRlKHZhbHVlKTtcblxuICAgIHRoaXMuZWwudmFsdWUgPSBkYXRlID8gdG9JU084NjAxRm9ybWF0KGRhdGUpIDogJyc7XG5cbiAgICBkaXNwYXRjaElucHV0TWVzc2FnZS5jYWxsKHRoaXMpO1xufVxuXG5mdW5jdGlvbiBNTERhdGVfZGVsKCkge1xuICAgIHRoaXMuZWwudmFsdWUgPSAnJztcblxuICAgIGRpc3BhdGNoSW5wdXRNZXNzYWdlLmNhbGwodGhpcyk7XG59XG5cblxuZnVuY3Rpb24gZGlzcGF0Y2hJbnB1dE1lc3NhZ2UoKSB7XG4gICAgdGhpcy5kYXRhLmRpc3BhdGNoU291cmNlTWVzc2FnZSgnaW5wdXQnKTsgLy8gRGlzcGF0Y2ggdGhlICdpbnB1dCcgKHVzdWFsbHkgZGlzcGF0Y2hlZCBieSB0aGUgdW5kZXJseWluZyA8aW5wdXQ+IGVsZW1lbnQpIGV2ZW50IHNvIHRoYXQgdGhlIGRhdGEgY2hhbmdlIGNhbiBiZSBsaXN0ZW5lZCB0b1xufVxuXG5cbmZ1bmN0aW9uIHRvSVNPODYwMUZvcm1hdChkYXRlKSB7XG4gICAgdmFyIGRhdGVBcnIgPSBbXG4gICAgICAgIGRhdGUuZ2V0RnVsbFllYXIoKSxcbiAgICAgICAgcGFkKGRhdGUuZ2V0TW9udGgoKSArIDEpLFxuICAgICAgICBwYWQoZGF0ZS5nZXREYXRlKCkpXG4gICAgXTtcblxuICAgIHZhciBkYXRlU3RyID0gZGF0ZUFyci5qb2luKCctJyk7XG5cbiAgICByZXR1cm4gZGF0ZVN0cjtcblxuICAgIGZ1bmN0aW9uIHBhZChuKSB7IHJldHVybiBuIDwgMTAgPyAnMCcgKyBuIDogbjsgfVxufSIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5Jyk7XG5cblxudmFyIE1MRHJvcFRhcmdldCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxEcm9wVGFyZ2V0JywgWydkcm9wJ10pO1xuXG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxEcm9wVGFyZ2V0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTERyb3BUYXJnZXQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBkb1QgPSByZXF1aXJlKCdkb3QnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIG1pbG9Db3VudCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY291bnQnKTtcblxudmFyIFRSRUVfVEVNUExBVEUgPSAnPHVsIGNsYXNzPVwibWwtdWktZm9sZHRyZWUtbGlzdFwiPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7e34gaXQuZGF0YS5pdGVtcyA6aXRlbTppbmRleCB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdmFyIGhhc1N1YlRyZWUgPSBpdGVtLml0ZW1zICYmIGl0ZW0uaXRlbXMubGVuZ3RoOyB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIHt7PyBoYXNTdWJUcmVlIH19Y2xhc3M9XCJtbC11aS1mb2xkdHJlZS0taGFzLW11bHRpcGxlXCJ7ez99fT5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWwtdWktZm9sZHRyZWUtaXRlbVwiPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez8gaGFzU3ViVHJlZSB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1sLXVpLWZvbGR0cmVlLWJ1dHRvblwiPjwvZGl2PlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez0gaXQuaXRlbVRlbXBsYXRlKHsgaXRlbTogaXRlbSwgaWQ6IGl0Lml0ZW1JRHNbaW5kZXhdIH0pIH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/IGhhc1N1YlRyZWUgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3s9IGl0LnRyZWVUZW1wbGF0ZShpdGVtKSB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7P319XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICB7e359fVxcXG4gICAgICAgICAgICAgICAgICAgIDwvdWw+JztcblxudmFyIERFRkFVTFRfQ09NUElMRURfSVRFTV9URU1QTEFURSA9IGRvVC5jb21waWxlKCdcXFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtbC11aS1mb2xkdHJlZS1sYWJlbFwiIGRhdGEtaXRlbS1pZD1cInt7PSBpdC5pZCB9fVwiPlxcXG4gICAgICAgICAgICAgICAge3s9IGl0Lml0ZW0ubGFiZWwgfX1cXFxuICAgICAgICAgICAgPC9zcGFuPicpXG4gICAgLCBDT01QSUxFRF9UUkVFX1RFTVBMQVRFID0gZG9ULmNvbXBpbGUoVFJFRV9URU1QTEFURSk7XG5cblxudmFyIE1MRm9sZFRyZWUgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MRm9sZFRyZWUnLCB7XG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZXZlbnRzOiB7XG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICAnY2xpY2sgZGJsY2xpY2snOiB7IHN1YnNjcmliZXI6IG9uSXRlbUV2ZW50LCBjb250ZXh0OiAnb3duZXInIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLWZvbGR0cmVlLW1haW4nXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxGb2xkVHJlZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxGb2xkVHJlZTtcblxuXy5leHRlbmRQcm90byhNTEZvbGRUcmVlLCB7XG4gICAgc2V0SXRlbVRlbXBsYXRlOiBNTEZvbGRUcmVlJHNldEl0ZW1UZW1wbGF0ZSxcbiAgICByZW5kZXJUcmVlOiBNTEZvbGRUcmVlJHJlbmRlclRyZWVcbn0pO1xuXG5mdW5jdGlvbiBmb2xkVW5mb2xkKGVsKSB7XG4gICAgZWwuY2xhc3NMaXN0LnRvZ2dsZSgnbWwtdWktZm9sZHRyZWUtLXVuZm9sZCcpO1xufVxuXG5mdW5jdGlvbiBpdGVtTWVzc2FnZShtc2csIGVsKSB7XG4gICAgdmFyIGlkID0gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWl0ZW0taWQnKVxuICAgICAgICAsIGl0ZW0gPSB0aGlzLl9pdGVtc01hcFtpZF07XG5cbiAgICB0aGlzLnBvc3RNZXNzYWdlKCdtbGZvbGR0cmVlXycgKyBtc2csIHtcbiAgICAgICAgaXRlbTogaXRlbSxcbiAgICAgICAgZWw6IGVsXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIG9uSXRlbUV2ZW50KG1zZywgZSkge1xuICAgIHZhciBlbCA9IGUudGFyZ2V0O1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoJ21sLXVpLWZvbGR0cmVlLWJ1dHRvbicpKVxuICAgICAgICBmb2xkVW5mb2xkKGVsLnBhcmVudE5vZGUucGFyZW50Tm9kZSk7XG4gICAgZWxzZSBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdtbC11aS1mb2xkdHJlZS1sYWJlbCcpKVxuICAgICAgICBpdGVtTWVzc2FnZS5jYWxsKHRoaXMsIG1zZywgZWwpO1xuICAgIGVsc2UgcmV0dXJuO1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG59XG5cbmZ1bmN0aW9uIE1MRm9sZFRyZWUkc2V0SXRlbVRlbXBsYXRlICh0ZW1wbGF0ZVN0cikge1xuICAgIHRoaXMuX2l0ZW1UZW1wbGF0ZSA9IGRvVC5jb21waWxlKHRlbXBsYXRlU3RyKTtcbn1cblxuZnVuY3Rpb24gTUxGb2xkVHJlZSRyZW5kZXJUcmVlIChkYXRhKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICAgIHNlbGYuX2l0ZW1zTWFwID0ge307XG4gICAgdGhpcy5lbC5pbm5lckhUTUwgPSBfcmVuZGVyVHJlZShkYXRhKTtcblxuICAgIGZ1bmN0aW9uIF9yZW5kZXJUcmVlIChkYXRhKSB7XG4gICAgICAgIGlmIChkYXRhLml0ZW1zKVxuICAgICAgICAgICAgdmFyIGl0ZW1zSURzID0gXy5tYXAoZGF0YS5pdGVtcywgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICAgICAgICAgIHZhciBpZCA9IG1pbG9Db3VudCgpO1xuICAgICAgICAgICAgICAgIHNlbGYuX2l0ZW1zTWFwW2lkXSA9IGl0ZW07XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlkOyBcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBDT01QSUxFRF9UUkVFX1RFTVBMQVRFKHtcbiAgICAgICAgICAgIGl0ZW1JRHM6IGl0ZW1zSURzLFxuICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgIGl0ZW1UZW1wbGF0ZTogc2VsZi5faXRlbVRlbXBsYXRlIHx8IERFRkFVTFRfQ09NUElMRURfSVRFTV9URU1QTEFURSxcbiAgICAgICAgICAgIHRyZWVUZW1wbGF0ZTogX3JlbmRlclRyZWVcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5Jyk7XG5cblxudmFyIE1MR3JvdXAgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MR3JvdXAnLCB7XG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1ncm91cCdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTEdyb3VwKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTEdyb3VwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5Jyk7XG5cblxudmFyIE1MSHlwZXJsaW5rID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTEh5cGVybGluaycsIHtcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLWh5cGVybGluaydcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTEh5cGVybGluayk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxIeXBlcmxpbms7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBJTUFHRV9DSEFOR0VfTUVTU0FHRSA9ICdtbGltYWdlY2hhbmdlJztcblxudmFyIE1MSW1hZ2UgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MSW1hZ2UnLCB7XG4gICAgZGF0YToge1xuICAgICAgICBzZXQ6IE1MSW1hZ2Vfc2V0LFxuICAgICAgICBnZXQ6IE1MSW1hZ2VfZ2V0LFxuICAgICAgICBkZWw6IE1MSW1hZ2VfZGVsLFxuICAgICAgICBzcGxpY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgZXZlbnQ6IElNQUdFX0NIQU5HRV9NRVNTQUdFXG4gICAgfSxcbiAgICBtb2RlbDoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJy5zcmMnOiB7IHN1YnNjcmliZXI6IG9uTW9kZWxDaGFuZ2UsIGNvbnRleHQ6ICdvd25lcicgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgdGFnTmFtZTogJ2ltZycsXG4gICAgICAgIGNsczogJ21sLXVpLWltYWdlJ1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MSW1hZ2UpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MSW1hZ2U7XG5cblxuXy5leHRlbmRQcm90byhNTEltYWdlLCB7XG4gICAgaW5pdDogTUxJbWFnZSRpbml0XG59KTtcblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWxpemUgcmFkaW8gZ3JvdXAgYW5kIHNldHVwXG4gKi9cbmZ1bmN0aW9uIE1MSW1hZ2UkaW5pdCgpIHtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG4vKipcbiAqIFNldHMgaW1hZ2UgdmFsdWVcbiAqIFJlcGxhY2VzIHRoZSBkYXRhIHNldCBvcGVyYXRpb24gdG8gZGVhbCB3aXRoIHJhZGlvIGJ1dHRvbnNcbiAqXG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYmUgc2V0XG4gKi9cbmZ1bmN0aW9uIE1MSW1hZ2Vfc2V0KHZhbHVlKSB7XG4gICAgdGhpcy5tb2RlbC5zZXQodmFsdWUpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuXG4vKipcbiAqIEdldHMgZ3JvdXAgdmFsdWVcbiAqIFJldHJpZXZlcyB0aGUgc2VsZWN0ZWQgdmFsdWUgb2YgdGhlIGdyb3VwXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBNTEltYWdlX2dldCgpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLm1vZGVsLmdldCgpO1xuICAgIHJldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcgPyBfLmNsb25lKHZhbHVlKSA6IHZhbHVlO1xufVxuXG5cbi8qKlxuICogRGVsZXRlZCBncm91cCB2YWx1ZVxuICogRGVsZXRlcyB0aGUgdmFsdWUgb2YgdGhlIGdyb3VwLCBzZXR0aW5nIGl0IHRvIGVtcHR5XG4gKi9cbmZ1bmN0aW9uIE1MSW1hZ2VfZGVsKCkge1xuICAgIHRoaXMubW9kZWwuZGVsKCk7XG59XG5cblxuLy8gUG9zdCB0aGUgZGF0YSBjaGFuZ2VcbmZ1bmN0aW9uIGRpc3BhdGNoQ2hhbmdlTWVzc2FnZSgpIHtcbiAgICB0aGlzLmRhdGEuZGlzcGF0Y2hTb3VyY2VNZXNzYWdlKElNQUdFX0NIQU5HRV9NRVNTQUdFKTtcbn1cblxuXG5mdW5jdGlvbiBvbk1vZGVsQ2hhbmdlKHBhdGgsIGRhdGEpIHtcbiAgICB0aGlzLmVsLnNyYyA9IGRhdGEubmV3VmFsdWU7XG4gICAgZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBNTElucHV0ID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTElucHV0Jywge1xuICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktaW5wdXQnXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxJbnB1dCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxJbnB1dDtcblxuXy5leHRlbmRQcm90byhNTElucHV0LCB7XG4gICAgZGlzYWJsZTogTUxJbnB1dCRkaXNhYmxlLFxuICAgIGlzRGlzYWJsZWQ6IE1MSW5wdXQkaXNEaXNhYmxlZCxcbiAgICBzZXRNYXhMZW5ndGg6IE1MSW5wdXQkc2V0TWF4TGVuZ3RoXG59KTtcblxuZnVuY3Rpb24gTUxJbnB1dCRkaXNhYmxlKGRpc2FibGUpIHtcbiAgICB0aGlzLmVsLmRpc2FibGVkID0gZGlzYWJsZTtcbn1cblxuZnVuY3Rpb24gTUxJbnB1dCRpc0Rpc2FibGVkKCkge1xuICAgIHJldHVybiAhIXRoaXMuZWwuZGlzYWJsZWQ7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXQkc2V0TWF4TGVuZ3RoKGxlbmd0aCkge1xuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKCdtYXhsZW5ndGgnLCBsZW5ndGgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxudmFyIElOUFVUX0xJU1RfQ0hBTkdFX01FU1NBR0UgPSAnbWxpbnB1dGxpc3RjaGFuZ2UnO1xuXG52YXIgYXN5bmNIYW5kbGVyID0gZnVuY3Rpb24gKHZhbHVlLCBjYWxsYmFjaykge2NhbGxiYWNrKHZhbHVlKTt9O1xuXG52YXIgTUxJbnB1dExpc3QgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MSW5wdXRMaXN0Jywge1xuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1pbnB1dC1saXN0J1xuICAgIH0sXG4gICAgZGF0YToge1xuICAgICAgICBnZXQ6IE1MSW5wdXRMaXN0X2dldCxcbiAgICAgICAgc2V0OiBNTElucHV0TGlzdF9zZXQsXG4gICAgICAgIGRlbDogTUxJbnB1dExpc3RfZGVsLFxuICAgICAgICBzcGxpY2U6IE1MSW5wdXRMaXN0X3NwbGljZSxcbiAgICAgICAgZXZlbnQ6IElOUFVUX0xJU1RfQ0hBTkdFX01FU1NBR0VcbiAgICB9LFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGNvbnRhaW5lcjogdW5kZWZpbmVkLFxuICAgIG1vZGVsOiB7XG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICAnKioqJzogeyBzdWJzY3JpYmVyOiBvbkl0ZW1zQ2hhbmdlLCBjb250ZXh0OiAnb3duZXInIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgICAgdGVtcGxhdGU6ICdcXFxuICAgICAgICAgICAgPGRpdiBtbC1iaW5kPVwiTUxMaXN0Omxpc3RcIj5cXFxuICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIk1MTGlzdEl0ZW06aXRlbVwiIGNsYXNzPVwibGlzdC1pdGVtXCI+XFxcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gbWwtYmluZD1cIltkYXRhXTpsYWJlbFwiPjwvc3Bhbj5cXFxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBtbC1iaW5kPVwiW2V2ZW50c106ZGVsZXRlQnRuXCIgY2xhc3M9XCJnbHlwaGljb24gZ2x5cGhpY29uLXJlbW92ZVwiPjwvc3Bhbj5cXFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcXG4gICAgICAgICAgICA8L2Rpdj5cXFxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgbWwtYmluZD1cIk1MSW5wdXQ6aW5wdXRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiPlxcXG4gICAgICAgICAgICA8YnV0dG9uIG1sLWJpbmQ9XCJNTEJ1dHRvbjpidXR0b25cIiBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiPlxcXG4gICAgICAgICAgICAgICAgQWRkXFxcbiAgICAgICAgICAgIDwvYnV0dG9uPidcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTElucHV0TGlzdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxJbnB1dExpc3Q7XG5cbl8uZXh0ZW5kUHJvdG8oTUxJbnB1dExpc3QsIHtcbiAgICBpbml0OiBNTElucHV0TGlzdCRpbml0LFxuICAgIHNldEFzeW5jOiBNTElucHV0TGlzdCRzZXRBc3luYyxcbiAgICBzZXRQbGFjZUhvbGRlcjogTUxJbnB1dExpc3Qkc2V0UGxhY2VIb2xkZXIsXG4gICAgZGVzdHJveTogTUxJbnB1dExpc3QkZGVzdHJveVxufSk7XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0JGluaXQoKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5vbmNlKCdjaGlsZHJlbmJvdW5kJywgb25DaGlsZHJlbkJvdW5kKTtcbiAgICB0aGlzLm1vZGVsLnNldChbXSk7XG59XG5cbmZ1bmN0aW9uIG9uQ2hpbGRyZW5Cb3VuZCgpIHtcbiAgICByZW5kZXIuY2FsbCh0aGlzKTtcbn1cblxuZnVuY3Rpb24gTUxJbnB1dExpc3Qkc2V0UGxhY2VIb2xkZXIocGxhY2VIb2xkZXIpIHtcbiAgICB0aGlzLl9pbnB1dC5lbC5zZXRBdHRyaWJ1dGUoJ3BsYWNlSG9sZGVyJywgcGxhY2VIb2xkZXIpO1xufVxuXG5mdW5jdGlvbiBNTElucHV0TGlzdCRzZXRBc3luYyhuZXdIYW5kbGVyKSB7XG4gICAgYXN5bmNIYW5kbGVyID0gbmV3SGFuZGxlciB8fCBhc3luY0hhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0JGRlc3Ryb3koKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5fY29ubmVjdG9yICYmIG1pbG8ubWluZGVyLmRlc3Ryb3lDb25uZWN0b3IodGhpcy5fY29ubmVjdG9yKTtcbiAgICB0aGlzLl9jb25uZWN0b3IgPSBudWxsO1xufVxuXG5mdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgdGhpcy50ZW1wbGF0ZS5yZW5kZXIoKS5iaW5kZXIoKTtcbiAgICBjb21wb25lbnRTZXR1cC5jYWxsKHRoaXMpO1xufVxuXG5mdW5jdGlvbiBjb21wb25lbnRTZXR1cCgpIHtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICAnX2lucHV0JzogdGhpcy5jb250YWluZXIuc2NvcGUuaW5wdXQsXG4gICAgICAgICdfYnV0dG9uJzogdGhpcy5jb250YWluZXIuc2NvcGUuYnV0dG9uLFxuICAgICAgICAnX2xpc3QnOiB0aGlzLmNvbnRhaW5lci5zY29wZS5saXN0XG4gICAgfSk7XG4gICAgdGhpcy5fY29ubmVjdG9yID0gbWlsby5taW5kZXIodGhpcy5fbGlzdC5tb2RlbCwgJzw8PC0+Pj4nLCB0aGlzLm1vZGVsKTtcbiAgICB0aGlzLl9idXR0b24uZXZlbnRzLm9uKCdjbGljaycsIHtzdWJzY3JpYmVyOiBvbkNsaWNrLCBjb250ZXh0OiB0aGlzIH0pOyAgIFxufVxuXG5mdW5jdGlvbiBvbkNsaWNrKG1zZykge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuX2lucHV0LmRhdGEuZ2V0KDApO1xuICAgIGlmICh0aGlzLl9pbnB1dC5kYXRhKVxuICAgICAgICBhc3luY0hhbmRsZXIodmFsdWUsIGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2xpc3QubW9kZWwucHVzaCh7IGxhYmVsOiBsYWJlbCwgdmFsdWU6IHZhbHVlIH0pO1xuICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgIHRoaXMuX2lucHV0LmRhdGEuZGVsKCk7XG59XG5cbmZ1bmN0aW9uIG9uSXRlbXNDaGFuZ2UobXNnLCBkYXRhKSB7XG4gICAgdGhpcy5kYXRhLmRpc3BhdGNoU291cmNlTWVzc2FnZShJTlBVVF9MSVNUX0NIQU5HRV9NRVNTQUdFKTtcbn1cblxuZnVuY3Rpb24gTUxJbnB1dExpc3RfZ2V0KCkge1xuICAgIHZhciBtb2RlbCA9IHRoaXMubW9kZWwuZ2V0KCk7XG4gICAgcmV0dXJuIG1vZGVsID8gXy5jbG9uZShtb2RlbCkgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0X3NldCh2YWx1ZSkge1xuICAgIHRoaXMubW9kZWwuc2V0KHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gTUxJbnB1dExpc3RfZGVsKCkge1xuICAgIHJldHVybiB0aGlzLm1vZGVsLnNldChbXSk7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0X3NwbGljZSgpIHsgLy8gLi4uIGFyZ3VtZW50c1xuICAgIHRoaXMubW9kZWwuc3BsaWNlLmFwcGx5KHRoaXMubW9kZWwsIGFyZ3VtZW50cyk7XG59IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxudmFyIExJU1RfQ0hBTkdFX01FU1NBR0UgPSAnbWxsaXN0Y2hhbmdlJ1xuICAgICwgREVMRVRFX0JVVFRPTl9OQU1FID0gJ2RlbGV0ZUJ0bic7XG5cblxudmFyIE1MTGlzdCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxMaXN0Jywge1xuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1saXN0J1xuICAgIH0sXG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIG1vZGVsOiB1bmRlZmluZWQsXG4gICAgbGlzdDogdW5kZWZpbmVkXG59KTtcblxuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MTGlzdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxMaXN0O1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxMaXN0LCB7XG4gICAgaW5pdDogTUxMaXN0JGluaXQsXG4gICAgZGVzdHJveTogTUxMaXN0JGRlc3Ryb3ksXG4gICAgcmVtb3ZlSXRlbTogTUxMaXN0JHJlbW92ZUl0ZW0sXG4gICAgbW92ZUl0ZW06IE1MTGlzdCRtb3ZlSXRlbVxufSk7XG5cblxuZnVuY3Rpb24gTUxMaXN0JGluaXQoKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5vbignY2hpbGRyZW5ib3VuZCcsIG9uQ2hpbGRyZW5Cb3VuZCk7XG59XG5cblxuZnVuY3Rpb24gTUxMaXN0JGRlc3Ryb3koKSB7XG4gICAgdGhpcy5fY29ubmVjdG9yICYmIG1pbG8ubWluZGVyLmRlc3Ryb3lDb25uZWN0b3IodGhpcy5fY29ubmVjdG9yKTtcbiAgICB0aGlzLl9jb25uZWN0b3IgPSBudWxsO1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdCRyZW1vdmVJdGVtKGluZGV4KXtcbiAgICB0aGlzLm1vZGVsLnNwbGljZShpbmRleCwgMSk7XG59XG5cblxuZnVuY3Rpb24gTUxMaXN0JG1vdmVJdGVtKGZyb20sIHRvKSB7XG4gICAgdmFyIHNwbGljZWREYXRhID0gdGhpcy5tb2RlbC5zcGxpY2UoZnJvbSwgMSk7XG4gICAgcmV0dXJuIHRoaXMubW9kZWwuc3BsaWNlKHRvLCAwLCBzcGxpY2VkRGF0YVswXSk7XG59XG5cblxuZnVuY3Rpb24gb25DaGlsZHJlbkJvdW5kKCkge1xuICAgIHRoaXMubW9kZWwuc2V0KFtdKTtcbiAgICB0aGlzLl9jb25uZWN0b3IgPSBtaWxvLm1pbmRlcih0aGlzLm1vZGVsLCAnPDw8LScsIHRoaXMuZGF0YSkuZGVmZXJDaGFuZ2VNb2RlKCc8PDwtPj4+Jyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIERyYWdEcm9wID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9kcmFnZHJvcCcpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG52YXIgTElTVElURU1fQ0hBTkdFX01FU1NBR0UgPSAnbWxsaXN0aXRlbWNoYW5nZSdcblxudmFyIE1MTGlzdEl0ZW0gPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MTGlzdEl0ZW0nLCB7XG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZG9tOiB1bmRlZmluZWQsXG4gICAgZHJhZzoge1xuICAgICAgICBtZXRhOiB7XG4gICAgICAgICAgICBwYXJhbXM6IGdldE1ldGFEYXRhXG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRyb3A6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICdkcmFnZW50ZXInOiB7IHN1YnNjcmliZXI6IG9uRHJhZ0hvdmVyLCBjb250ZXh0OiAnb3duZXInIH0sXG4gICAgICAgICAgICAnZHJhZ292ZXInOiB7IHN1YnNjcmliZXI6IG9uRHJhZ0hvdmVyLCBjb250ZXh0OiAnb3duZXInIH0sXG4gICAgICAgICAgICAnZHJhZ2xlYXZlJzogeyBzdWJzY3JpYmVyOiBvbkRyYWdPdXQsIGNvbnRleHQ6ICdvd25lcicgfSxcbiAgICAgICAgICAgICdkcm9wJzogeyBzdWJzY3JpYmVyOiBvbkl0ZW1Ecm9wLCBjb250ZXh0OiAnb3duZXInIH1cbiAgICAgICAgfSxcbiAgICAgICAgYWxsb3c6IHtcbiAgICAgICAgICAgIGNvbXBvbmVudHM6IGlzQ29tcG9uZW50QWxsb3dlZFxuICAgICAgICB9XG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICAgIGdldDogTUxMaXN0SXRlbV9nZXQsXG4gICAgICAgIHNldDogTUxMaXN0SXRlbV9zZXQsXG4gICAgICAgIGRlbDogTUxMaXN0SXRlbV9kZWwsXG4gICAgICAgIGV2ZW50OiBMSVNUSVRFTV9DSEFOR0VfTUVTU0FHRVxuICAgIH0sXG4gICAgbW9kZWw6IHVuZGVmaW5lZCxcbiAgICBpdGVtOiB1bmRlZmluZWRcbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MTGlzdEl0ZW0pO1xuXG52YXIgTUxMaXN0SXRlbSA9IG1vZHVsZS5leHBvcnRzID0gTUxMaXN0SXRlbTtcblxuXG5fLmV4dGVuZFByb3RvKE1MTGlzdEl0ZW0sIHtcbiAgICBpbml0OiBNTExpc3RJdGVtJGluaXQsXG4gICAgbW92ZUl0ZW06IE1MTGlzdEl0ZW0kbW92ZUl0ZW0sXG4gICAgcmVtb3ZlSXRlbTogTUxMaXN0SXRlbSRyZW1vdmVJdGVtLFxuICAgIGlzRHJvcEFsbG93ZWQ6IE1MTGlzdEl0ZW0kaXNEcm9wQWxsb3dlZFxufSk7XG5cblxuZnVuY3Rpb24gTUxMaXN0SXRlbSRpbml0KCkge1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMub24oJ2NoaWxkcmVuYm91bmQnLCBvbkNoaWxkcmVuQm91bmQpO1xufVxuXG5cbmZ1bmN0aW9uIG9uQ2hpbGRyZW5Cb3VuZCgpIHtcbiAgICB2YXIgZGVsZXRlQnRuID0gdGhpcy5jb250YWluZXIuc2NvcGUuZGVsZXRlQnRuO1xuICAgIGRlbGV0ZUJ0biAmJiBkZWxldGVCdG4uZXZlbnRzLm9uKCdjbGljaycsIHsgc3Vic2NyaWJlcjogdGhpcy5yZW1vdmVJdGVtLCBjb250ZXh0OiB0aGlzIH0pO1xufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdEl0ZW0kcmVtb3ZlSXRlbSgpIHtcbiAgICB0cnkgeyB2YXIgbGlzdE93bmVyID0gdGhpcy5pdGVtLmxpc3Qub3duZXI7IH0gY2F0Y2goZSkge31cbiAgICBsaXN0T3duZXIgJiYgbGlzdE93bmVyLnJlbW92ZUl0ZW0odGhpcy5pdGVtLmluZGV4KTtcbn1cblxuXG5mdW5jdGlvbiBNTExpc3RJdGVtJG1vdmVJdGVtKGluZGV4KSB7XG4gICAgdmFyIGxpc3RPd25lciA9IHRoaXMuaXRlbS5saXN0Lm93bmVyO1xuICAgIGxpc3RPd25lciAmJiBsaXN0T3duZXIubW92ZUl0ZW0odGhpcy5pdGVtLmluZGV4LCBpbmRleCk7XG59XG5cblxuZnVuY3Rpb24gTUxMaXN0SXRlbSRpc0Ryb3BBbGxvd2VkKG1ldGEsIGRyYWdEcm9wKXtcbiAgICByZXR1cm4gbWV0YS5wYXJhbXMgJiYgbWV0YS5wYXJhbXMuaW5kZXggJiYgbWV0YS5jb21wQ2xhc3MgPT0gJ01MTGlzdEl0ZW0nO1xufVxuXG5cbmZ1bmN0aW9uIGlzQ29tcG9uZW50QWxsb3dlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pc0Ryb3BBbGxvd2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gb25JdGVtRHJvcChldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgb25EcmFnT3V0LmNhbGwodGhpcyk7XG4gICAgdmFyIGR0ID0gbmV3IERyYWdEcm9wKGV2ZW50KTtcbiAgICB2YXIgbWV0YSA9IGR0LmdldENvbXBvbmVudE1ldGEoKTtcbiAgICB2YXIgc3RhdGUgPSBkdC5nZXRDb21wb25lbnRTdGF0ZSgpO1xuICAgIHZhciBsaXN0T3duZXIgPSB0aGlzLml0ZW0ubGlzdC5vd25lcjtcbiAgICB2YXIgaW5kZXggPSBtZXRhLnBhcmFtcyAmJiBtZXRhLnBhcmFtcy5pbmRleDtcblxuICAgIGxpc3RPd25lci5tb3ZlSXRlbSgraW5kZXgsIHRoaXMuaXRlbS5pbmRleCwgc3RhdGUpO1xufVxuXG5cbmZ1bmN0aW9uIG9uRHJhZ0hvdmVyKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICB0aGlzLmRvbS5hZGRDc3NDbGFzc2VzKCdtbC1kcmFnLW92ZXInKTtcbn1cblxuXG5mdW5jdGlvbiBvbkRyYWdPdXQoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIHRoaXMuZG9tLnJlbW92ZUNzc0NsYXNzZXMoJ21sLWRyYWctb3ZlcicpO1xufVxuXG5cbmZ1bmN0aW9uIGdldE1ldGFEYXRhKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGluZGV4OiB0aGlzLml0ZW0uaW5kZXhcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gTUxMaXN0SXRlbV9nZXQoKSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5tb2RlbC5nZXQoKTtcbiAgICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnID8gXy5jbG9uZSh2YWx1ZSkgOiB2YWx1ZTtcbn1cblxuXG5mdW5jdGlvbiBNTExpc3RJdGVtX3NldCh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpXG4gICAgICAgIHRoaXMuZGF0YS5fc2V0KHZhbHVlKTtcbiAgICB0aGlzLm1vZGVsLnNldCh2YWx1ZSk7XG4gICAgX3NlbmRDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdEl0ZW1fZGVsKCkge1xuICAgIHRoaXMuZGF0YS5fZGVsKCk7XG4gICAgdGhpcy5tb2RlbC5kZWwoKTtcbiAgICBfc2VuZENoYW5nZU1lc3NhZ2UuY2FsbCh0aGlzKTsgICAgXG59XG5cblxuZnVuY3Rpb24gX3NlbmRDaGFuZ2VNZXNzYWdlKCkge1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoTElTVElURU1fQ0hBTkdFX01FU1NBR0UpO1xufVxuXG5cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIG1pbG9Db3VudCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY291bnQnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBSQURJT19DSEFOR0VfTUVTU0FHRSA9ICdtbHJhZGlvZ3JvdXBjaGFuZ2UnXG4gICAgLCBFTEVNRU5UX05BTUVfUFJPUEVSVFkgPSAnX21sUmFkaW9Hcm91cEVsZW1lbnRJRCdcbiAgICAsIEVMRU1FTlRfTkFNRV9QUkVGSVggPSAnbWwtcmFkaW8tZ3JvdXAtJztcblxudmFyIE1MUmFkaW9Hcm91cCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxSYWRpb0dyb3VwJywge1xuICAgIGRhdGE6IHtcbiAgICAgICAgc2V0OiBNTFJhZGlvR3JvdXBfc2V0LFxuICAgICAgICBnZXQ6IE1MUmFkaW9Hcm91cF9nZXQsXG4gICAgICAgIGRlbDogTUxSYWRpb0dyb3VwX2RlbCxcbiAgICAgICAgc3BsaWNlOiB1bmRlZmluZWQsXG4gICAgICAgIGV2ZW50OiBSQURJT19DSEFOR0VfTUVTU0FHRVxuICAgIH0sXG4gICAgbW9kZWw6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICcqKionOiB7IHN1YnNjcmliZXI6IG9uT3B0aW9uc0NoYW5nZSwgY29udGV4dDogJ293bmVyJyB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGV2ZW50czoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJ2NsaWNrJzogeyBzdWJzY3JpYmVyOiBvbkdyb3VwQ2xpY2ssIGNvbnRleHQ6ICdvd25lcicgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktcmFkaW8tZ3JvdXAnXG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgICB0ZW1wbGF0ZTogJ3t7fiBpdC5yYWRpb09wdGlvbnMgOm9wdGlvbiB9fSBcXFxuICAgICAgICAgICAgICAgICAgICAgICAge3sjI2RlZi5lbElEOnt7PSBpdC5lbGVtZW50TmFtZSB9fS17ez0gb3B0aW9uLnZhbHVlIH19I319IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInt7PSBpdC5fcmVuZGVyT3B0aW9ucy5vcHRpb25Dc3NDbGFzcyB8fCBcIicgKyBFTEVNRU5UX05BTUVfUFJFRklYICsgJ29wdGlvblwiIH19XCI+IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPVwie3sjIGRlZi5lbElEIH19XCIgdHlwZT1cInJhZGlvXCIgdmFsdWU9XCJ7ez0gb3B0aW9uLnZhbHVlIH19XCIgbmFtZT1cInt7PSBpdC5lbGVtZW50TmFtZSB9fVwiPiBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJ7eyMgZGVmLmVsSUQgfX1cIj57ez0gb3B0aW9uLmxhYmVsIH19PC9sYWJlbD4gXFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj4gXFxcbiAgICAgICAgICAgICAgICAgICB7e359fSdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTFJhZGlvR3JvdXApO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MUmFkaW9Hcm91cDtcblxuXG5fLmV4dGVuZFByb3RvKE1MUmFkaW9Hcm91cCwge1xuICAgIGluaXQ6IE1MUmFkaW9Hcm91cCRpbml0LFxuICAgIGRlc3Ryb3k6IE1MUmFkaW9Hcm91cCRkZXN0cm95LFxuICAgIHNldFJlbmRlck9wdGlvbnM6IE1MUmFkaW9Hcm91cCRzZXRSZW5kZXJPcHRpb25zXG59KTtcblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWxpemUgcmFkaW8gZ3JvdXAgYW5kIHNldHVwXG4gKi9cbmZ1bmN0aW9uIE1MUmFkaW9Hcm91cCRpbml0KCkge1xuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19yYWRpb0xpc3QnLCBbXSwgXy5DT05GKTtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsIEVMRU1FTlRfTkFNRV9QUk9QRVJUWSwgRUxFTUVOVF9OQU1FX1BSRUZJWCArIG1pbG9Db3VudCgpKTtcbiAgICB0aGlzLl9yZW5kZXJPcHRpb25zID0ge307XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gTUxSYWRpb0dyb3VwJHNldFJlbmRlck9wdGlvbnMob3B0aW9ucykge1xuICAgIHRoaXMuX3JlbmRlck9wdGlvbnMgPSBvcHRpb25zO1xufVxuXG5cbi8qKlxuICogU2V0cyBncm91cCB2YWx1ZVxuICogUmVwbGFjZXMgdGhlIGRhdGEgc2V0IG9wZXJhdGlvbiB0byBkZWFsIHdpdGggcmFkaW8gYnV0dG9uc1xuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlIFRoZSB2YWx1ZSB0byBiZSBzZXRcbiAqL1xuZnVuY3Rpb24gTUxSYWRpb0dyb3VwX3NldCh2YWx1ZSkge1xuICAgIHZhciBvcHRpb25zID0gdGhpcy5fcmFkaW9MaXN0XG4gICAgICAgICwgc2V0UmVzdWx0O1xuICAgIGlmIChvcHRpb25zLmxlbmd0aCkge1xuICAgICAgICBvcHRpb25zLmZvckVhY2goZnVuY3Rpb24ocmFkaW8pIHtcbiAgICAgICAgICAgIHJhZGlvLmNoZWNrZWQgPSByYWRpby52YWx1ZSA9PSB2YWx1ZTtcbiAgICAgICAgICAgIGlmIChyYWRpby5jaGVja2VkKVxuICAgICAgICAgICAgICAgIHNldFJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBkaXNwYXRjaENoYW5nZU1lc3NhZ2UuY2FsbCh0aGlzKTtcblxuICAgICAgICByZXR1cm4gc2V0UmVzdWx0O1xuICAgIH1cbn1cblxuXG4vKipcbiAqIEdldHMgZ3JvdXAgdmFsdWVcbiAqIFJldHJpZXZlcyB0aGUgc2VsZWN0ZWQgdmFsdWUgb2YgdGhlIGdyb3VwXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBNTFJhZGlvR3JvdXBfZ2V0KCkge1xuICAgIHZhciBjaGVja2VkID0gXy5maW5kKHRoaXMuX3JhZGlvTGlzdCwgZnVuY3Rpb24ocmFkaW8pIHtcbiAgICAgICAgcmV0dXJuIHJhZGlvLmNoZWNrZWQ7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2hlY2tlZCAmJiBjaGVja2VkLnZhbHVlIHx8IHVuZGVmaW5lZDtcbn1cblxuXG4vKipcbiAqIERlbGV0ZWQgZ3JvdXAgdmFsdWVcbiAqIERlbGV0ZXMgdGhlIHZhbHVlIG9mIHRoZSBncm91cCwgc2V0dGluZyBpdCB0byBlbXB0eVxuICovXG5mdW5jdGlvbiBNTFJhZGlvR3JvdXBfZGVsKCkge1xuICAgIHZhciBvcHRpb25zID0gdGhpcy5fcmFkaW9MaXN0O1xuICAgIGlmIChvcHRpb25zLmxlbmd0aClcbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKHJhZGlvKSB7XG4gICAgICAgICAgICByYWRpby5jaGVja2VkID0gZmFsc2U7XG4gICAgICAgIH0pO1xuXG4gICAgZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuXG4vKipcbiAqIE1hbmFnZSByYWRpbyBjaGlsZHJlbiBjbGlja3NcbiAqL1xuZnVuY3Rpb24gb25Hcm91cENsaWNrKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudGFyZ2V0LnR5cGUgPT0gJ3JhZGlvJylcbiAgICAgICAgZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7XG59XG5cbi8vIFBvc3QgdGhlIGRhdGEgY2hhbmdlXG5mdW5jdGlvbiBkaXNwYXRjaENoYW5nZU1lc3NhZ2UoKSB7XG4gICAgdGhpcy5kYXRhLmRpc3BhdGNoU291cmNlTWVzc2FnZShSQURJT19DSEFOR0VfTUVTU0FHRSk7XG59XG5cblxuLy8gU2V0IHJhZGlvIGJ1dHRvbiBjaGlsZHJlbiBvbiBtb2RlbCBjaGFuZ2VcbmZ1bmN0aW9uIG9uT3B0aW9uc0NoYW5nZShwYXRoLCBkYXRhKSB7XG4gICAgdGhpcy50ZW1wbGF0ZS5yZW5kZXIoe1xuICAgICAgICByYWRpb09wdGlvbnM6IHRoaXMubW9kZWwuZ2V0KCksXG4gICAgICAgIGVsZW1lbnROYW1lOiB0aGlzW0VMRU1FTlRfTkFNRV9QUk9QRVJUWV0sXG4gICAgICAgIF9yZW5kZXJPcHRpb25zOiB0aGlzLl9yZW5kZXJPcHRpb25zXG4gICAgfSk7XG5cbiAgICB2YXIgcmFkaW9FbHMgPSB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ2lucHV0W3R5cGU9XCJyYWRpb1wiXScpXG4gICAgICAgICwgb3B0aW9ucyA9IF8udG9BcnJheShyYWRpb0Vscyk7XG5cbiAgICB0aGlzLl9yYWRpb0xpc3QubGVuZ3RoID0gMDtcbiAgICB0aGlzLl9yYWRpb0xpc3Quc3BsaWNlLmFwcGx5KHRoaXMuX3JhZGlvTGlzdCwgWzAsIDBdLmNvbmNhdChvcHRpb25zKSk7XG59XG5cblxuZnVuY3Rpb24gTUxSYWRpb0dyb3VwJGRlc3Ryb3koKSB7XG4gICAgZGVsZXRlIHRoaXMuX3JhZGlvTGlzdDtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxudmFyIE1MU2VsZWN0ID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTFNlbGVjdCcsIHtcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktc2VsZWN0J1xuICAgIH0sXG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIG1vZGVsOiB7XG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICAnKionOiB7IHN1YnNjcmliZXI6IG9uT3B0aW9uc0NoYW5nZSwgY29udGV4dDogJ293bmVyJyB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICAgIHRlbXBsYXRlOiAne3t+IGl0LnNlbGVjdE9wdGlvbnMgOm9wdGlvbiB9fSBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInt7PSBvcHRpb24udmFsdWUgfX1cIiB7ez8gb3B0aW9uLnNlbGVjdGVkIH19c2VsZWN0ZWR7ez99fT57ez0gb3B0aW9uLmxhYmVsIH19PC9vcHRpb24+IFxcXG4gICAgICAgICAgICAgICAgICAge3t+fX0nXG4gICAgfVxufSk7XG5cblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTFNlbGVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxTZWxlY3Q7XG5cblxuXy5leHRlbmRQcm90byhNTFNlbGVjdCwge1xuICAgIHNldE9wdGlvbnM6IE1MU2VsZWN0JHNldE9wdGlvbnMsXG4gICAgZGlzYWJsZTogTUxTZWxlY3QkZGlzYWJsZVxufSk7XG5cblxuZnVuY3Rpb24gTUxTZWxlY3Qkc2V0T3B0aW9ucyhvcHRpb25zKSB7XG4gICAgLy8gU2V0IG9wdGlvbnMgdGVtcG9yYXJpbHkgZGlzYWJsZXMgbW9kZWwgc3Vic2NyaXB0aW9ucyAoQXMgYSB3b3JrYXJvdW5kIGZvciBwZXJmb3JtYW5jZSBpc3N1ZXMgcmVsYXRpbmcgdG8gbW9kZWwgdXBkYXRlcyAvIHRlbXBsYXRlIHJlLXJlbmRlcmluZylcbiAgICB2YXIgbW9kZWxDaGFuZ2VMaXN0ZW5lciA9IHsgY29udGV4dDogdGhpcywgc3Vic2NyaWJlcjogb25PcHRpb25zQ2hhbmdlIH07XG5cbiAgICB0aGlzLm1vZGVsLm9mZignKionLCBtb2RlbENoYW5nZUxpc3RlbmVyKTtcbiAgICB0aGlzLm1vZGVsLnNldChvcHRpb25zKTtcbiAgICB0aGlzLm1vZGVsLm9uKCcqKicsIG1vZGVsQ2hhbmdlTGlzdGVuZXIpO1xuXG4gICAgb25PcHRpb25zQ2hhbmdlLmNhbGwodGhpcyk7XG59XG5cblxuZnVuY3Rpb24gTUxTZWxlY3QkZGlzYWJsZShkaXNhYmxlKSB7XG4gICAgdGhpcy5lbC5kaXNhYmxlZCA9IGRpc2FibGU7XG59XG5cblxuZnVuY3Rpb24gb25PcHRpb25zQ2hhbmdlKHBhdGgsIGRhdGEpIHtcbiAgICB0aGlzLnRlbXBsYXRlLnJlbmRlcih7IHNlbGVjdE9wdGlvbnM6IHRoaXMubW9kZWwuZ2V0KCkgfSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogTUxTdXBlckNvbWJvXG4gKiBBIGNvbWJvIHNlbGVjdCBsaXN0IHdpdGggaW50ZWxsaWdlbnQgc2Nyb2xsaW5nIG9mIHN1cGVyIGxhcmdlIGxpc3RzLlxuICovXG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBkb1QgPSByZXF1aXJlKCdkb3QnKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKTtcblxudmFyIENPTUJPX09QRU4gPSAnbWwtdWktc3VwZXJjb21iby1vcGVuJztcbnZhciBDT01CT19DSEFOR0VfTUVTU0FHRSA9ICdtbHN1cGVyY29tYm9jaGFuZ2UnO1xuXG52YXIgT1BUSU9OU19URU1QTEFURSA9ICd7e34gaXQuY29tYm9PcHRpb25zIDpvcHRpb246aW5kZXggfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYge3s/IG9wdGlvbi5zZWxlY3RlZH19Y2xhc3M9XCJzZWxlY3RlZFwiIHt7P319ZGF0YS12YWx1ZT1cInt7PSBpbmRleCB9fVwiPnt7PSBvcHRpb24ubGFiZWwgfX08L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAge3t+fX0nO1xuXG52YXIgTUFYX1JFTkRFUkVEID0gMTAwO1xudmFyIEJVRkZFUiA9IDI1O1xudmFyIERFRkFVTFRfRUxFTUVOVF9IRUlHSFQgPSAyMDtcblxudmFyIE1MU3VwZXJDb21ibyA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxTdXBlckNvbWJvJywge1xuICAgIGV2ZW50czoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJ21vdXNlbGVhdmUnOiB7c3Vic2NyaWJlcjogb25Nb3VzZUxlYXZlLCBjb250ZXh0OiAnb3duZXInfSxcbiAgICAgICAgICAgICdtb3VzZW92ZXInOiB7c3Vic2NyaWJlcjogb25Nb3VzZU92ZXIsIGNvbnRleHQ6ICdvd25lcid9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRhdGE6IHtcbiAgICAgICAgZ2V0OiBNTFN1cGVyQ29tYm9fZ2V0LFxuICAgICAgICBzZXQ6IE1MU3VwZXJDb21ib19zZXQsXG4gICAgICAgIGRlbDogTUxTdXBlckNvbWJvX2RlbCxcbiAgICAgICAgc3BsaWNlOiB1bmRlZmluZWQsXG4gICAgICAgIGV2ZW50OiBDT01CT19DSEFOR0VfTUVTU0FHRVxuICAgIH0sXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLXN1cGVyY29tYm8nXG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgICB0ZW1wbGF0ZTogJzxpbnB1dCBtbC1iaW5kPVwiW2RhdGEsIGV2ZW50c106aW5wdXRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBtbC11aS1pbnB1dFwiPlxcXG4gICAgICAgICAgICAgICAgICAgPGRpdiBtbC1iaW5kPVwiW2RvbV06YWRkSXRlbURpdlwiIGNsYXNzPVwibWwtdWktc3VwZXJjb21iby1hZGRcIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gbWwtYmluZD1cIjphZGRQcm9tcHRcIj48L3NwYW4+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWwtYmluZD1cIltldmVudHMsIGRvbV06YWRkQnRuXCIgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgbWwtdWktYnV0dG9uXCI+QWRkPC9idXR0b24+XFxcbiAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIltkb20sIGV2ZW50c106bGlzdFwiIGNsYXNzPVwibWwtdWktc3VwZXJjb21iby1kcm9wZG93blwiPlxcXG4gICAgICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIltkb21dOmJlZm9yZVwiPjwvZGl2PlxcXG4gICAgICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIlt0ZW1wbGF0ZSwgZG9tLCBldmVudHNdOm9wdGlvbnNcIiBjbGFzcz1cIm1sLXVpLXN1cGVyY29tYm8tb3B0aW9uc1wiPjwvZGl2PlxcXG4gICAgICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIltkb21dOmFmdGVyXCI+PC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICA8L2Rpdj4nXG4gICAgfSxcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZFxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxTdXBlckNvbWJvKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTFN1cGVyQ29tYm87XG5cbi8qKlxuICogUHVibGljIEFwaVxuICovXG5fLmV4dGVuZFByb3RvKE1MU3VwZXJDb21ibywge1xuICAgIGluaXQ6IE1MU3VwZXJDb21ibyRpbml0LFxuICAgIHNob3dPcHRpb25zOiBNTFN1cGVyQ29tYm8kc2hvd09wdGlvbnMsXG4gICAgaGlkZU9wdGlvbnM6IE1MU3VwZXJDb21ibyRoaWRlT3B0aW9ucyxcbiAgICB0b2dnbGVPcHRpb25zOiBNTFN1cGVyQ29tYm8kdG9nZ2xlT3B0aW9ucyxcbiAgICBzZXRPcHRpb25zOiBNTFN1cGVyQ29tYm8kc2V0T3B0aW9ucyxcbiAgICBpbml0T3B0aW9uc1VSTDogTUxTdXBlckNvbWJvJGluaXRPcHRpb25zVVJMLFxuICAgIHNldEZpbHRlcmVkT3B0aW9uczogTUxTdXBlckNvbWJvJHNldEZpbHRlcmVkT3B0aW9ucyxcbiAgICB1cGRhdGU6IE1MU3VwZXJDb21ibyR1cGRhdGUsXG4gICAgdG9nZ2xlQWRkQnV0dG9uOiBNTFN1cGVyQ29tYm8kdG9nZ2xlQWRkQnV0dG9uLFxuICAgIHNldEFkZEl0ZW1Qcm9tcHQ6IE1MU3VwZXJDb21ibyRzZXRBZGRJdGVtUHJvbXB0LFxuICAgIGNsZWFyQ29tYm9JbnB1dDogTUxTdXBlckNvbWJvX2RlbFxufSk7XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXNlIHRoZSBjb21wb25lbnQsIHdhaXQgZm9yIGNoaWxkcmVuYm91bmQsIHNldHVwIGVtcHR5IG9wdGlvbnMgYXJyYXlzLlxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm8kaW5pdCgpIHtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHRoaXMub25jZSgnY2hpbGRyZW5ib3VuZCcsIG9uQ2hpbGRyZW5Cb3VuZCk7XG5cbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfb3B0aW9uc0RhdGE6IFtdLFxuICAgICAgICBfZmlsdGVyZWRPcHRpb25zRGF0YTogW11cbiAgICB9LCBfLldSSVQpO1xufVxuXG4vKipcbiAqIEhhbmRsZXIgZm9yIGluaXQgY2hpbGRyZW5ib3VuZCBsaXN0ZW5lci4gUmVuZGVycyB0ZW1wbGF0ZS5cbiAqL1xuZnVuY3Rpb24gb25DaGlsZHJlbkJvdW5kKCkge1xuICAgIHRoaXMudGVtcGxhdGUucmVuZGVyKCkuYmluZGVyKCk7XG4gICAgY29tcG9uZW50U2V0dXAuY2FsbCh0aGlzKTtcbn1cblxuXG4vKipcbiAqIERlZmluZSBpbnN0YW5jZSBwcm9wZXJ0aWVzLCBnZXQgc3ViY29tcG9uZW50cywgY2FsbCBzZXR1cCBzdWItdGFza3NcbiAqL1xuZnVuY3Rpb24gY29tcG9uZW50U2V0dXAoKSB7XG4gICAgdmFyIHNjb3BlID0gdGhpcy5jb250YWluZXIuc2NvcGU7XG5cbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfY29tYm9JbnB1dDogc2NvcGUuaW5wdXQsXG4gICAgICAgIF9jb21ib0xpc3Q6IHNjb3BlLmxpc3QsXG4gICAgICAgIF9jb21ib09wdGlvbnM6IHNjb3BlLm9wdGlvbnMsXG4gICAgICAgIF9jb21ib0JlZm9yZTogc2NvcGUuYmVmb3JlLFxuICAgICAgICBfY29tYm9BZnRlcjogc2NvcGUuYWZ0ZXIsXG4gICAgICAgIF9jb21ib0FkZEl0ZW1EaXY6IHNjb3BlLmFkZEl0ZW1EaXYsXG4gICAgICAgIF9jb21ib0FkZFByb21wdDogc2NvcGUuYWRkUHJvbXB0LFxuICAgICAgICBfY29tYm9BZGRCdG46IHNjb3BlLmFkZEJ0bixcbiAgICAgICAgX29wdGlvblRlbXBsYXRlOiBkb1QuY29tcGlsZShPUFRJT05TX1RFTVBMQVRFKVxuICAgIH0pO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgX3N0YXJ0SW5kZXg6IDAsXG4gICAgICAgIF9lbmRJbmRleDogTUFYX1JFTkRFUkVELFxuICAgICAgICBfaGlkZGVuOiBmYWxzZSxcbiAgICAgICAgX2VsZW1lbnRIZWlnaHQ6IERFRkFVTFRfRUxFTUVOVF9IRUlHSFQsXG4gICAgICAgIF90b3RhbDogMCxcbiAgICAgICAgX29wdGlvbnNIZWlnaHQ6IDIwMCxcbiAgICAgICAgX2xhc3RTY3JvbGxQb3M6IDAsXG4gICAgICAgIF9jdXJyZW50VmFsdWU6IG51bGwsXG4gICAgICAgIF9zZWxlY3RlZDogbnVsbCxcbiAgICAgICAgX2lzQWRkQnV0dG9uU2hvd246IGZhbHNlXG4gICAgfSwgXy5XUklUKTtcblxuICAgIC8vIENvbXBvbmVudCBTZXR1cFxuICAgIHRoaXMuZG9tLnNldFN0eWxlcyh7IHBvc2l0aW9uOiAncmVsYXRpdmUnIH0pO1xuICAgIHNldHVwQ29tYm9MaXN0KHRoaXMuX2NvbWJvTGlzdCwgdGhpcy5fY29tYm9PcHRpb25zLCB0aGlzKTtcbiAgICBzZXR1cENvbWJvSW5wdXQodGhpcy5fY29tYm9JbnB1dCwgdGhpcyk7XG4gICAgc2V0dXBDb21ib0J0bih0aGlzLl9jb21ib0FkZEJ0biwgdGhpcyk7XG5cbiAgICB0aGlzLmV2ZW50cy5vbigna2V5ZG93bicsIHsgc3Vic2NyaWJlcjogY2hhbmdlU2VsZWN0ZWQsIGNvbnRleHQ6IHRoaXMgfSk7XG4gICAgLy90aGlzLmV2ZW50cy5vbignbW91c2VsZWF2ZScsIHsgc3Vic2NyaWJlcjogTUxTdXBlckNvbWJvJGhpZGVPcHRpb25zLCBjb250ZXh0OiB0aGlzIH0pO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFNob3dzIG9yIGhpZGVzIG9wdGlvbiBsaXN0LlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hvdyB0cnVlIHRvIHNob3csIGZhbHNlIHRvIGhpZGVcbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJHRvZ2dsZU9wdGlvbnMoc2hvdykge1xuICAgIHRoaXMuX2hpZGRlbiA9ICFzaG93O1xuICAgIHRoaXMuX2NvbWJvTGlzdC5kb20udG9nZ2xlKHNob3cpO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFNob3dzIG9wdGlvbnMgbGlzdFxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm8kc2hvd09wdGlvbnMoKSB7XG4gICAgdGhpcy5faGlkZGVuID0gZmFsc2U7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKENPTUJPX09QRU4pO1xuICAgIHRoaXMuX2NvbWJvTGlzdC5kb20udG9nZ2xlKHRydWUpO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEhpZGVzIG9wdGlvbnMgbGlzdFxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm8kaGlkZU9wdGlvbnMoKSB7XG4gICAgdGhpcy5faGlkZGVuID0gdHJ1ZTtcbiAgICB0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoQ09NQk9fT1BFTik7XG4gICAgdGhpcy5fY29tYm9MaXN0LmRvbS50b2dnbGUoZmFsc2UpO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEhpZGVzIGFkZCBidXR0b25cbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJHRvZ2dsZUFkZEJ1dHRvbihzaG93LCBvcHRpb25zKSB7XG4gICAgdGhpcy5fY29tYm9BZGRJdGVtRGl2LmRvbS50b2dnbGUoc2hvdyk7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5wcmVzZXJ2ZVN0YXRlKSB0aGlzLl9fc2hvd0FkZE9uQ2xpY2sgPSB0aGlzLl9pc0FkZEJ1dHRvblNob3duO1xuICAgIHRoaXMuX2lzQWRkQnV0dG9uU2hvd24gPSBzaG93O1xufVxuXG5cbmZ1bmN0aW9uIE1MU3VwZXJDb21ibyRzZXRBZGRJdGVtUHJvbXB0KHByb21wdCkge1xuICAgIHRoaXMuX2FkZEl0ZW1Qcm9tcHQgPSBwcm9tcHQ7XG4gICAgdGhpcy5fY29tYm9BZGRQcm9tcHQuZWwuaW5uZXJIVE1MID0gcHJvbXB0O1xuICAgIHRoaXMudG9nZ2xlQWRkQnV0dG9uKGZhbHNlKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgdGhlIG9wdGlvbnMgb2YgdGhlIGRyb3Bkb3duXG4gKlxuICogQHBhcmFtIHtBcnJheVtPYmplY3RdfSBhcnIgdGhlIG9wdGlvbnMgdG8gc2V0IHdpdGggbGFiZWwgYW5kIHZhbHVlIHBhaXJzLiBWYWx1ZSBjYW4gYmUgYW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm8kc2V0T3B0aW9ucyhhcnIpIHtcbiAgICB0aGlzLl9vcHRpb25zRGF0YSA9IGFycjtcbiAgICB0aGlzLnNldEZpbHRlcmVkT3B0aW9ucyhhcnIpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogSW5pdGlhbGlzZSB0aGUgcmVtb3RlIG9wdGlvbnMgb2YgdGhlIGRyb3Bkb3duXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gaW5pdGlhbGlzZS5cbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJGluaXRPcHRpb25zVVJMKG9wdGlvbnMpIHtcbiAgICB0aGlzLl9vcHRpb25zVVJMID0gb3B0aW9ucy51cmw7XG4gICAgdGhpcy5fZm9ybWF0T3B0aW9uc1VSTCA9IG9wdGlvbnMuZm9ybWF0T3B0aW9ucyB8fCBmdW5jdGlvbihlKXtyZXR1cm4gZTt9O1xufVxuXG5cbi8qKlxuICogUHJpdmF0ZSBtZXRob2RcbiAqIFNldHMgdGhlIG9wdGlvbnMgb2YgdGhlIGRyb3Bkb3duIGJhc2VkIG9uIGEgcmVxdWVzdFxuICovXG5mdW5jdGlvbiBfZ2V0T3B0aW9uc1VSTChjYikge1xuICAgIHZhciB1cmwgPSB0aGlzLl9vcHRpb25zVVJMLFxuICAgICAgICBxdWVyeVN0cmluZyA9IHRoaXMuX2NvbWJvSW5wdXQuZGF0YS5nZXQoKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgY2IgPSBjYiB8fCBfLm5vb3A7XG4gICAgbWlsby51dGlsLnJlcXVlc3QucG9zdCh1cmwsIHsgbmFtZTogcXVlcnlTdHJpbmcgfSwgZnVuY3Rpb24gKGVyciwgcmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IHNlYXJjaCBmb3IgXCInICsgcXVlcnlTdHJpbmcgKyAnXCInKTtcbiAgICAgICAgICAgIHJldHVybiBjYihuZXcgRXJyb3IoJ1JlcXVlc3QgZXJyb3InKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVzcG9uc2VEYXRhID0gXy5qc29uUGFyc2UocmVzcG9uc2UpO1xuICAgICAgICBpZiAocmVzcG9uc2VEYXRhKSBjYihudWxsLCByZXNwb25zZURhdGEpO1xuICAgICAgICBlbHNlIGNiKG5ldyBFcnJvcignRGF0YSBlcnJvcicpKTtcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgdGhlIGZpbHRlcmVkIG9wdGlvbnMsIHdoaWNoIGlzIGEgc3Vic2V0IG9mIG5vcm1hbCBvcHRpb25zXG4gKlxuICogQHBhcmFtIHtbdHlwZV19IGFyciBUaGUgb3B0aW9ucyB0byBzZXRcbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJHNldEZpbHRlcmVkT3B0aW9ucyhhcnIpIHtcbiAgICBpZiAoISBhcnIpIHJldHVybiBsb2dnZXIuZXJyb3IoJ3NldEZpbHRlcmVkT3B0aW9uczogcGFyYW1ldGVyIGlzIHVuZGVmaW5lZCcpO1xuICAgIHRoaXMuX2ZpbHRlcmVkT3B0aW9uc0RhdGEgPSBhcnI7XG4gICAgdGhpcy5fdG90YWwgPSBhcnIubGVuZ3RoO1xuICAgIHRoaXMudXBkYXRlKCk7XG59XG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogVXBkYXRlcyB0aGUgbGlzdC4gVGhpcyBpcyB1c2VkIG9uIHNjcm9sbCwgYW5kIG1ha2VzIHVzZSBvZiB0aGUgZmlsdGVyZWRPcHRpb25zIHRvXG4gKiBpbnRlbGxpZ2VudGx5IHNob3cgYSBzdWJzZXQgb2YgdGhlIGZpbHRlcmVkIGxpc3QgYXQgYSB0aW1lLlxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm8kdXBkYXRlKCkge1xuICAgIHZhciB3YXNIaWRkZW4gPSB0aGlzLl9oaWRkZW47XG5cbiAgICB2YXIgYXJyVG9TaG93ID0gdGhpcy5fZmlsdGVyZWRPcHRpb25zRGF0YS5zbGljZSh0aGlzLl9zdGFydEluZGV4LCB0aGlzLl9lbmRJbmRleCk7XG5cbiAgICB0aGlzLl9jb21ib09wdGlvbnMudGVtcGxhdGUucmVuZGVyKHtcbiAgICAgICAgY29tYm9PcHRpb25zOiBhcnJUb1Nob3dcbiAgICB9KTtcblxuICAgIHRoaXMuX2VsZW1lbnRIZWlnaHQgPSB0aGlzLl9lbGVtZW50SGVpZ2h0IHx8IERFRkFVTFRfRUxFTUVOVF9IRUlHSFQ7XG5cbiAgICBpZiAod2FzSGlkZGVuKVxuICAgICAgICB0aGlzLmhpZGVPcHRpb25zKCk7XG5cbiAgICB2YXIgYmVmb3JlSGVpZ2h0ID0gdGhpcy5fc3RhcnRJbmRleCAqIHRoaXMuX2VsZW1lbnRIZWlnaHQ7XG4gICAgdmFyIGFmdGVySGVpZ2h0ID0gKHRoaXMuX3RvdGFsIC0gdGhpcy5fZW5kSW5kZXgpICogdGhpcy5fZWxlbWVudEhlaWdodDtcbiAgICB0aGlzLl9jb21ib0JlZm9yZS5lbC5zdHlsZS5oZWlnaHQgPSBiZWZvcmVIZWlnaHQgKyAncHgnO1xuICAgIHRoaXMuX2NvbWJvQWZ0ZXIuZWwuc3R5bGUuaGVpZ2h0ID0gYWZ0ZXJIZWlnaHQgPiAwID8gYWZ0ZXJIZWlnaHQgKyAncHgnIDogJzBweCc7XG59XG5cbi8qKlxuICogU2V0dXAgdGhlIGNvbWJvIGxpc3RcbiAqXG4gKiBAcGFyYW0gIHtDb21wb25lbnR9IGxpc3RcbiAqIEBwYXJhbSAge0FycmF5fSBvcHRpb25zXG4gKiBAcGFyYW0gIHtDb21wb25lbnR9IHNlbGZcbiAqL1xuZnVuY3Rpb24gc2V0dXBDb21ib0xpc3QobGlzdCwgb3B0aW9ucywgc2VsZikge1xuICAgIHNlbGYudG9nZ2xlQWRkQnV0dG9uKGZhbHNlKTtcbiAgICBvcHRpb25zLnRlbXBsYXRlLnNldChPUFRJT05TX1RFTVBMQVRFKTtcblxuICAgIGxpc3QuZG9tLnNldFN0eWxlcyh7XG4gICAgICAgIG92ZXJmbG93OiAnc2Nyb2xsJyxcbiAgICAgICAgaGVpZ2h0OiBzZWxmLl9vcHRpb25zSGVpZ2h0ICsgJ3B4JyxcbiAgICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIHpJbmRleDogMTBcbiAgICAgICAgLy8gdG9wOiB5UG9zICsgJ3B4JyxcbiAgICAgICAgLy8gbGVmdDogeFBvcyArICdweCcsXG4gICAgfSk7XG5cbiAgICBzZWxmLmhpZGVPcHRpb25zKCk7XG4gICAgbGlzdC5ldmVudHMub25NZXNzYWdlcyh7XG4gICAgICAgICdjbGljayc6IHtzdWJzY3JpYmVyOiBvbkxpc3RDbGljaywgY29udGV4dDogc2VsZn0sXG4gICAgICAgICdzY3JvbGwnOiB7c3Vic2NyaWJlcjogb25MaXN0U2Nyb2xsLCBjb250ZXh0OiBzZWxmfVxuICAgIH0pO1xufVxuXG4vKipcbiAqIFNldHVwIHRoZSBpbnB1dCBjb21wb25lbnRcbiAqXG4gKiBAcGFyYW0gIHtDb21wb25lbnR9IGlucHV0XG4gKiBAcGFyYW0gIHtDb21wb25lbnR9IHNlbGZcbiAqL1xuZnVuY3Rpb24gc2V0dXBDb21ib0lucHV0KGlucHV0LCBzZWxmKSB7XG4gICAgaW5wdXQuZXZlbnRzLm9uY2UoJ2ZvY3VzJywgZnVuY3Rpb24oKXtcbiAgICAgICAgaW5wdXQuZGF0YS5vbignJywgeyBzdWJzY3JpYmVyOiBvbkRhdGFDaGFuZ2UsIGNvbnRleHQ6IHNlbGYgfSk7XG4gICAgICAgIGlucHV0LmV2ZW50cy5vbignY2xpY2snLCB7c3Vic2NyaWJlcjogb25JbnB1dENsaWNrLCBjb250ZXh0OiBzZWxmIH0pO1xuICAgICAgICBpbnB1dC5ldmVudHMub24oJ2tleWRvd24nLCB7c3Vic2NyaWJlcjogb25FbnRlcktleSwgY29udGV4dDogc2VsZiB9KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBTZXR1cCB0aGUgYnV0dG9uXG4gKiBAcGFyYW0gIHtDb21wb25lbnR9IGJ0blxuICogQHBhcmFtICB7Q29tcG9uZW50fSBzZWxmXG4gKi9cbmZ1bmN0aW9uIHNldHVwQ29tYm9CdG4oYnRuLCBzZWxmKSB7XG4gICAgYnRuLmV2ZW50cy5vbignY2xpY2snLCB7IHN1YnNjcmliZXI6IG9uQWRkQnRuLCBjb250ZXh0OiBzZWxmIH0pO1xufVxuXG5cbi8qKlxuICogQ3VzdG9tIGRhdGEgZmFjZXQgZ2V0IG1ldGhvZFxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm9fZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50VmFsdWU7XG59XG5cbi8qKlxuICogQ3VzdG9tIGRhdGEgZmFjZXQgc2V0IG1ldGhvZFxuICogQHBhcmFtIHtWYXJpYWJsZX0gb2JqXG4gKi9cbmZ1bmN0aW9uIE1MU3VwZXJDb21ib19zZXQob2JqKSB7XG4gICAgdGhpcy5fY3VycmVudFZhbHVlID0gb2JqO1xuICAgIHRoaXMuX2NvbWJvSW5wdXQuZGF0YS5zZXQob2JqICYmIG9iai5sYWJlbCk7XG4gICAgXy5kZWZlck1ldGhvZCh0aGlzLCAnaGlkZU9wdGlvbnMnKTtcbn1cblxuLyoqXG4gKiBDdXN0b20gZGF0YSBmYWNldCBkZWwgbWV0aG9kXG4gKi9cbmZ1bmN0aW9uIE1MU3VwZXJDb21ib19kZWwoKSB7XG4gICAgdGhpcy5fY3VycmVudFZhbHVlID0gbnVsbDtcbiAgICB0aGlzLl9jb21ib0lucHV0LmRhdGEuc2V0KCcnKTtcbn1cblxuXG4vKipcbiAqIElucHV0IGRhdGEgY2hhbmdlIGhhbmRsZXJcbiAqIFdoZW4gdGhlIGlucHV0IGRhdGEgY2hhbmdlcywgdGhpcyBtZXRob2QgZmlsdGVycyB0aGUgb3B0aW9uc0RhdGEsIGFuZCBzZXRzIHRoZSBmaXJzdCBlbGVtZW50XG4gKiB0byBiZSBzZWxlY3RlZC5cbiAqIEBwYXJhbSAge1N0cmluZ30gbXNnXG4gKiBAcGFyYW0gIHtPYmpleHR9IGRhdGFcbiAqL1xuZnVuY3Rpb24gb25EYXRhQ2hhbmdlKG1zZywgZGF0YSkge1xuICAgIHZhciB0ZXh0ID0gZGF0YS5uZXdWYWx1ZSAmJiBkYXRhLm5ld1ZhbHVlLnRyaW0oKTtcbiAgICBpZiAodGhpcy5fb3B0aW9uc1VSTCkge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIF9nZXRPcHRpb25zVVJMLmNhbGwodGhpcywgZnVuY3Rpb24oZXJyLCByZXNwb25zZURhdGEpe1xuICAgICAgICAgICAgaWYgKGVyciB8fCAhcmVzcG9uc2VEYXRhKSByZXR1cm47XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gcmVzcG9uc2VEYXRhLmRhdGEubWFwKHNlbGYuX2Zvcm1hdE9wdGlvbnNVUkwpO1xuICAgICAgICAgICAgICAgIHNlbGYuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBfdXBkYXRlT3B0aW9uc0FuZEFkZEJ1dHRvbi5jYWxsKHNlbGYsIHRleHQsIHNlbGYuX29wdGlvbnNEYXRhKTtcbiAgICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRGF0YSBlcnJvcicsIGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgZmlsdGVyZWREYXRhID0gX2ZpbHRlckRhdGEuY2FsbCh0aGlzLCB0ZXh0KTtcbiAgICAgICAgX3VwZGF0ZU9wdGlvbnNBbmRBZGRCdXR0b24uY2FsbCh0aGlzLCB0ZXh0LCBmaWx0ZXJlZERhdGEpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBfZmlsdGVyRGF0YSh0ZXh0KSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnNEYXRhLmZpbHRlcihmdW5jdGlvbihvcHRpb24pIHtcbiAgICAgICAgZGVsZXRlIG9wdGlvbi5zZWxlY3RlZDtcbiAgICAgICAgaWYgKG9wdGlvbi5sYWJlbCkge1xuICAgICAgICAgICAgdmFyIGxhYmVsID0gb3B0aW9uLmxhYmVsLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICByZXR1cm4gbGFiZWwudHJpbSgpLnRvTG93ZXJDYXNlKCkuaW5kZXhPZih0ZXh0LnRvTG93ZXJDYXNlKCkpID09IDA7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBfdXBkYXRlT3B0aW9uc0FuZEFkZEJ1dHRvbih0ZXh0LCBmaWx0ZXJlZEFycikge1xuICAgIGlmICghdGV4dCkge1xuICAgICAgICB0aGlzLnRvZ2dsZUFkZEJ1dHRvbihmYWxzZSwgeyBwcmVzZXJ2ZVN0YXRlOiB0cnVlIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmaWx0ZXJlZEFyci5sZW5ndGggJiYgXy5maW5kKGZpbHRlcmVkQXJyLCBpc0V4YWN0TWF0Y2gpKSB7XG4gICAgICAgICAgICB0aGlzLnRvZ2dsZUFkZEJ1dHRvbihmYWxzZSwgeyBwcmVzZXJ2ZVN0YXRlOiB0cnVlIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX2FkZEl0ZW1Qcm9tcHQpIHtcbiAgICAgICAgICAgIHRoaXMudG9nZ2xlQWRkQnV0dG9uKHRoaXMuX29wdGlvbnNEYXRhLmxlbmd0aCA+IDEgfHwgdGhpcy5fb3B0aW9uc1VSTCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsdGVyZWRBcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnNob3dPcHRpb25zKCk7XG4gICAgICAgICAgICBmaWx0ZXJlZEFyclswXS5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zZWxlY3RlZCA9IGZpbHRlcmVkQXJyWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oaWRlT3B0aW9ucygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zZXRGaWx0ZXJlZE9wdGlvbnMoZmlsdGVyZWRBcnIpO1xuICAgIHRoaXMuX2NvbWJvTGlzdC5lbC5zY3JvbGxUb3AgPSAwO1xuXG4gICAgZnVuY3Rpb24gaXNFeGFjdE1hdGNoKGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZW0ubGFiZWwudG9Mb3dlckNhc2UoKSA9PT0gdGV4dC50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBBIG1hcCBvZiBrZXlDb2RlcyB0byBkaXJlY3Rpb25zXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG52YXIgZGlyZWN0aW9uTWFwID0geyAnNDAnOiAxLCAnMzgnOiAtMSB9O1xuXG4vKipcbiAqIExpc3Qga2V5ZG93biBoYW5kbGVyXG4gKiBDaGFuZ2VzIHRoZSBzZWxlY3RlZCBsaXN0IGl0ZW0gYnkgZmluZGluZyB0aGUgYWRqYWNlbnQgaXRlbSBhbmQgc2V0dGluZyBpdCB0byBzZWxlY3RlZC5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5mdW5jdGlvbiBjaGFuZ2VTZWxlY3RlZCh0eXBlLCBldmVudCkge1xuICAgIC8vVE9ETyB0ZXN0IG1vY2hhXG4gICAgdmFyIGRpcmVjdGlvbiA9IGRpcmVjdGlvbk1hcFtldmVudC5rZXlDb2RlXTtcblxuICAgIGlmKGRpcmVjdGlvbilcbiAgICAgICAgX2NoYW5nZVNlbGVjdGVkLmNhbGwodGhpcywgZGlyZWN0aW9uKTtcbn1cblxuZnVuY3Rpb24gX2NoYW5nZVNlbGVjdGVkKGRpcmVjdGlvbikge1xuICAgIC8vIFRPRE86IHJlZmFjdG9yIGFuZCB0aWR5IHVwLCBsb29rcyBsaWtlIHNvbWUgY29kZSBkdXBsaWNhdGlvbi5cbiAgICB2YXIgc2VsZWN0ZWQgPSB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zZWxlY3RlZCcpWzBdXG4gICAgICAgICwgc2Nyb2xsUG9zID0gdGhpcy5fY29tYm9MaXN0LmVsLnNjcm9sbFRvcFxuICAgICAgICAsIHNlbGVjdGVkUG9zID0gc2VsZWN0ZWQgPyBzZWxlY3RlZC5vZmZzZXRUb3AgOiAwXG4gICAgICAgICwgcmVsYXRpdmVQb3MgPSBzZWxlY3RlZFBvcyAtIHNjcm9sbFBvcztcblxuICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICB2YXIgaW5kZXggPSBfZ2V0RGF0YVZhbHVlRnJvbUVsZW1lbnQuY2FsbCh0aGlzLCBzZWxlY3RlZClcbiAgICAgICAgICAgICwgdGhpc0l0ZW0gPSB0aGlzLl9maWx0ZXJlZE9wdGlvbnNEYXRhW2luZGV4XVxuICAgICAgICAgICAgLCBhZGpJdGVtID0gdGhpcy5fZmlsdGVyZWRPcHRpb25zRGF0YVtpbmRleCArIGRpcmVjdGlvbl07XG5cbiAgICAgICAgaWYgKGFkakl0ZW0pIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzSXRlbS5zZWxlY3RlZDtcbiAgICAgICAgICAgIGFkakl0ZW0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWQgPSBhZGpJdGVtO1xuICAgICAgICAgICAgdGhpcy51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLl9maWx0ZXJlZE9wdGlvbnNEYXRhWzBdKSB7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXJlZE9wdGlvbnNEYXRhWzBdLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocmVsYXRpdmVQb3MgPiB0aGlzLl9vcHRpb25zSGVpZ2h0IC0gdGhpcy5fZWxlbWVudEhlaWdodCoyICYmIGRpcmVjdGlvbiA9PT0gMSlcbiAgICAgICAgdGhpcy5fY29tYm9MaXN0LmVsLnNjcm9sbFRvcCArPSB0aGlzLl9lbGVtZW50SGVpZ2h0KmRpcmVjdGlvbio1O1xuXG4gICAgaWYgKHJlbGF0aXZlUG9zIDwgdGhpcy5fZWxlbWVudEhlaWdodCAmJiBkaXJlY3Rpb24gPT09IC0xKVxuICAgICAgICB0aGlzLl9jb21ib0xpc3QuZWwuc2Nyb2xsVG9wICs9IHRoaXMuX2VsZW1lbnRIZWlnaHQqZGlyZWN0aW9uKjU7XG59XG5cblxuLyoqXG4gKiBNb3VzZSBvdmVyIGhhbmRsZXJcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5mdW5jdGlvbiBvbk1vdXNlT3Zlcih0eXBlLCBldmVudCkge1xuICAgIHRoaXMuX21vdXNlSXNPdmVyID0gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIE1vdXNlIGxlYXZlIGhhbmRsZXJcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5mdW5jdGlvbiBvbk1vdXNlTGVhdmUodHlwZSwgZXZlbnQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fbW91c2VJc092ZXIgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5fbW91c2VPdXRUaW1lcikgY2xlYXJJbnRlcnZhbCh0aGlzLl9tb3VzZU91dFRpbWVyKTtcbiAgICB0aGlzLl9tb3VzZU91dFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgICBpZiAoIXNlbGYuX21vdXNlSXNPdmVyKVxuICAgICAgICAgICAgX29uTW91c2VMZWF2ZS5jYWxsKHNlbGYpO1xuICAgIH0sIDc1MCk7XG59XG5cbmZ1bmN0aW9uIF9vbk1vdXNlTGVhdmUoKSB7XG4gICAgdGhpcy5oaWRlT3B0aW9ucygpO1xuICAgIHRoaXMudG9nZ2xlQWRkQnV0dG9uKGZhbHNlLCB7IHByZXNlcnZlU3RhdGU6IHRydWUgfSk7XG59XG5cblxuLyoqXG4gKiBJbnB1dCBjbGljayBoYW5kbGVyXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gb25JbnB1dENsaWNrKHR5cGUsIGV2ZW50KSB7XG4gICAgdGhpcy5zaG93T3B0aW9ucygpO1xuICAgIGlmICh0aGlzLl9fc2hvd0FkZE9uQ2xpY2spIHRoaXMudG9nZ2xlQWRkQnV0dG9uKHRydWUpO1xufVxuXG5cbi8qKlxuICogRW50ZXIga2V5IGhhbmRsZXJcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5mdW5jdGlvbiBvbkVudGVyS2V5KHR5cGUsIGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmtleUNvZGUgPT0gMTMpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkKVxuICAgICAgICAgICAgX3NldERhdGEuY2FsbCh0aGlzKTtcbiAgICB9XG59XG5cbi8qKlxuICogQWRkIGJ1dHRvbiBoYW5kbGVyXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gb25BZGRCdG4gKHR5cGUsIGV2ZW50KSB7XG4gICAgdmFyIGRhdGEgPSB7IGxhYmVsOiB0aGlzLl9jb21ib0lucHV0LmVsLnZhbHVlIH07XG4gICAgdGhpcy5wb3N0TWVzc2FnZSgnYWRkaXRlbScsIGRhdGEpO1xuICAgIHRoaXMuZXZlbnRzLnBvc3RNZXNzYWdlKCdtaWxvX3N1cGVyY29tYm9hZGRpdGVtJywgZGF0YSk7XG4gICAgdGhpcy50b2dnbGVBZGRCdXR0b24oZmFsc2UsIHsgcHJlc2VydmVTdGF0ZTogdHJ1ZSB9KTtcblxufVxuXG4vKipcbiAqIExpc3QgY2xpY2sgaGFuZGxlclxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKi9cbmZ1bmN0aW9uIG9uTGlzdENsaWNrICh0eXBlLCBldmVudCkge1xuICAgIHZhciBpbmRleCA9IF9nZXREYXRhVmFsdWVGcm9tRWxlbWVudC5jYWxsKHRoaXMsIGV2ZW50LnRhcmdldCk7XG4gICAgdmFyIGRhdGEgPSB0aGlzLl9maWx0ZXJlZE9wdGlvbnNEYXRhW2luZGV4XTtcblxuICAgIHRoaXMuX3NlbGVjdGVkID0gZGF0YTtcbiAgICBfc2V0RGF0YS5jYWxsKHRoaXMpO1xuICAgIHRoaXMudXBkYXRlKCk7XG59XG5cblxuLyoqXG4gKiBMaXN0IHNjcm9sbCBoYW5kbGVyXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gb25MaXN0U2Nyb2xsICh0eXBlLCBldmVudCkge1xuICAgIHZhciBzY3JvbGxQb3MgPSBldmVudC50YXJnZXQuc2Nyb2xsVG9wXG4gICAgICAgICwgZGlyZWN0aW9uID0gc2Nyb2xsUG9zID4gdGhpcy5fbGFzdFNjcm9sbFBvcyA/ICdkb3duJyA6ICd1cCdcbiAgICAgICAgLCBmaXJzdENoaWxkID0gdGhpcy5fY29tYm9PcHRpb25zLmVsLmxhc3RFbGVtZW50Q2hpbGRcbiAgICAgICAgLCBsYXN0Q2hpbGQgPSB0aGlzLl9jb21ib09wdGlvbnMuZWwuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgICAgLCBsYXN0RWxQb3NpdGlvbiA9IGZpcnN0Q2hpbGQgPyBmaXJzdENoaWxkLm9mZnNldFRvcCA6IDBcbiAgICAgICAgLCBmaXJzdEVsUG9zaXRpb24gPSBsYXN0Q2hpbGQgPyBsYXN0Q2hpbGQub2Zmc2V0VG9wIDogMFxuICAgICAgICAsIGRpc3RGcm9tTGFzdEVsID0gbGFzdEVsUG9zaXRpb24gLSBzY3JvbGxQb3MgLSB0aGlzLl9vcHRpb25zSGVpZ2h0ICsgdGhpcy5fZWxlbWVudEhlaWdodFxuICAgICAgICAsIGRpc3RGcm9tRmlyc3RFbCA9IHNjcm9sbFBvcyAtIGZpcnN0RWxQb3NpdGlvblxuICAgICAgICAsIGVsc0Zyb21TdGFydCA9IE1hdGguZmxvb3IoZGlzdEZyb21GaXJzdEVsIC8gdGhpcy5fZWxlbWVudEhlaWdodClcbiAgICAgICAgLCBlbHNUb1RoZUVuZCA9IE1hdGguZmxvb3IoZGlzdEZyb21MYXN0RWwgLyB0aGlzLl9lbGVtZW50SGVpZ2h0KVxuICAgICAgICAsIHRvdGFsRWxlbWVudHNCZWZvcmUgPSBNYXRoLmZsb29yKHNjcm9sbFBvcyAvIHRoaXMuX2VsZW1lbnRIZWlnaHQpIC0gQlVGRkVSO1xuXG4gICAgaWYgKChkaXJlY3Rpb24gPT0gJ2Rvd24nICYmIGVsc1RvVGhlRW5kIDwgQlVGRkVSKVxuICAgICAgICB8fCAoZGlyZWN0aW9uID09ICd1cCcgJiYgZWxzRnJvbVN0YXJ0IDwgQlVGRkVSKSkge1xuICAgICAgICB0aGlzLl9zdGFydEluZGV4ID0gdG90YWxFbGVtZW50c0JlZm9yZSA+IDAgPyB0b3RhbEVsZW1lbnRzQmVmb3JlIDogMDtcbiAgICAgICAgdGhpcy5fZW5kSW5kZXggPSB0b3RhbEVsZW1lbnRzQmVmb3JlICsgTUFYX1JFTkRFUkVEO1xuICAgICAgICB0aGlzLl9lbGVtZW50SGVpZ2h0ID0gZmlyc3RDaGlsZC5zdHlsZS5oZWlnaHQ7XG4gICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgfVxuICAgIHRoaXMuX2xhc3RTY3JvbGxQb3MgPSBzY3JvbGxQb3M7XG59XG5cblxuLyoqXG4gKiBQcml2YXRlIG1ldGhvZFxuICogUmV0cmlldmVzIHRoZSBkYXRhLXZhbHVlIGF0dHJpYnV0ZSB2YWx1ZSBmcm9tIHRoZSBlbGVtZW50IGFuZCByZXR1cm5zIGl0IGFzIGFuIGluZGV4IG9mXG4gKiB0aGUgZmlsdGVyZWRPcHRpb25zXG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gZWxcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuZnVuY3Rpb24gX2dldERhdGFWYWx1ZUZyb21FbGVtZW50KGVsKSB7XG4gICAgcmV0dXJuIE51bWJlcihlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSkgKyB0aGlzLl9zdGFydEluZGV4O1xufVxuXG4vKipcbiAqIFByaXZhdGUgbWV0aG9kXG4gKiBTZXRzIHRoZSBkYXRhIG9mIHRoZSBTdXBlckNvbWJvLCB0YWtpbmcgY2FyZSB0byByZXNldCBzb21lIHRoaW5ncyBhbmQgdGVtcG9yYXJpbHlcbiAqIHVuc3Vic2NyaWJlIGRhdGEgbGlzdGVuZXJzLlxuICovXG5mdW5jdGlvbiBfc2V0RGF0YSgpIHtcbiAgICBkZWxldGUgdGhpcy5fc2VsZWN0ZWQuc2VsZWN0ZWQ7XG4gICAgdGhpcy5oaWRlT3B0aW9ucygpO1xuICAgIHRoaXMudG9nZ2xlQWRkQnV0dG9uKGZhbHNlKTtcbiAgICB0aGlzLl9jb21ib0lucHV0LmRhdGEub2ZmKCcnLCB7IHN1YnNjcmliZXI6IG9uRGF0YUNoYW5nZSwgY29udGV4dDogdGhpcyB9KTtcbiAgICAvL3N1cGVyY29tYm8gbGlzdGVuZXJzIG9mZlxuICAgIHRoaXMuZGF0YS5zZXQodGhpcy5fc2VsZWN0ZWQpO1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoQ09NQk9fQ0hBTkdFX01FU1NBR0UpO1xuICAgIHRoaXMuX2NvbWJvSW5wdXQuZGF0YS5vbignJywgeyBzdWJzY3JpYmVyOiBvbkRhdGFDaGFuZ2UsIGNvbnRleHQ6IHRoaXMgfSk7XG4gICAgLy9zdXBlcmNvbWJvIGxpc3RlbmVycyBvblxuICAgIHRoaXMuX3NlbGVjdGVkID0gbnVsbDtcbiAgICB0aGlzLnNldEZpbHRlcmVkT3B0aW9ucyh0aGlzLl9vcHRpb25zRGF0YSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKTtcblxuXG52YXIgTUxUZXh0ID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTFRleHQnLCB7XG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS10ZXh0J1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MVGV4dCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxUZXh0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKTtcblxuXG52YXIgTUxUZXh0YXJlYSA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxUZXh0YXJlYScsIHtcbiAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLXRleHRhcmVhJ1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MVGV4dGFyZWEpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MVGV4dGFyZWE7XG5cblxudmFyIFNBTVBMRV9BVVRPUkVTSVpFX1RFWFQgPSAnTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQsJztcblxuXG5fLmV4dGVuZFByb3RvKE1MVGV4dGFyZWEsIHtcbiAgICBzdGFydEF1dG9yZXNpemU6IE1MVGV4dGFyZWEkc3RhcnRBdXRvcmVzaXplLFxuICAgIHN0b3BBdXRvcmVzaXplOiBNTFRleHRhcmVhJHN0b3BBdXRvcmVzaXplLFxuICAgIGlzQXV0b3Jlc2l6ZWQ6IE1MVGV4dGFyZWEkaXNBdXRvcmVzaXplZCxcbiAgICBkaXNhYmxlOiBNTFRleHRhcmVhJGRpc2FibGVcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MVGV4dGFyZWEkc3RhcnRBdXRvcmVzaXplKG9wdGlvbnMpIHtcbiAgICBpZiAodGhpcy5fYXV0b3Jlc2l6ZSlcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdNTFRleHRhcmVhIHN0YXJ0QXV0b3Jlc2l6ZTogYXV0b3Jlc2l6ZSBpcyBhbHJlYWR5IG9uJyk7XG4gICAgdGhpcy5fYXV0b3Jlc2l6ZSA9IHRydWU7XG4gICAgdGhpcy5fYXV0b3Jlc2l6ZU9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgX2FkanVzdEFyZWFIZWlnaHQuY2FsbCh0aGlzKTtcbiAgICBfbWFuYWdlU3Vic2NyaXB0aW9ucy5jYWxsKHRoaXMsICdvbicpO1xufVxuXG5cbmZ1bmN0aW9uIF9tYW5hZ2VTdWJzY3JpcHRpb25zKG9uT2ZmKSB7XG4gICAgdGhpcy5ldmVudHNbb25PZmZdKCdjbGljaycsIHsgc3Vic2NyaWJlcjogX2FkanVzdEFyZWFIZWlnaHQsIGNvbnRleHQ6IHRoaXMgfSk7XG4gICAgdGhpcy5kYXRhW29uT2ZmXSgnJywgeyBzdWJzY3JpYmVyOiBfYWRqdXN0QXJlYUhlaWdodCwgY29udGV4dDogdGhpcyB9KTtcbn1cblxuXG5mdW5jdGlvbiBfYWRqdXN0QXJlYUhlaWdodCgpIHtcbiAgICB0aGlzLmVsLnN0eWxlLmhlaWdodCA9IDA7XG5cbiAgICB2YXIgbmV3SGVpZ2h0ID0gdGhpcy5lbC5zY3JvbGxIZWlnaHRcbiAgICAgICAgLCBtaW5IZWlnaHQgPSB0aGlzLl9hdXRvcmVzaXplT3B0aW9ucy5taW5IZWlnaHRcbiAgICAgICAgLCBtYXhIZWlnaHQgPSB0aGlzLl9hdXRvcmVzaXplT3B0aW9ucy5tYXhIZWlnaHQ7XG5cbiAgICBuZXdIZWlnaHQgPSBuZXdIZWlnaHQgPj0gbWF4SGVpZ2h0XG4gICAgICAgICAgICAgICAgPyBtYXhIZWlnaHRcbiAgICAgICAgICAgICAgICA6IG5ld0hlaWdodCA8PSBtaW5IZWlnaHRcbiAgICAgICAgICAgICAgICA/IG1pbkhlaWdodFxuICAgICAgICAgICAgICAgIDogbmV3SGVpZ2h0O1xuXG4gICAgdGhpcy5lbC5zdHlsZS5oZWlnaHQgPSBuZXdIZWlnaHQgKyAncHgnO1xufVxuXG5cbmZ1bmN0aW9uIE1MVGV4dGFyZWEkc3RvcEF1dG9yZXNpemUoKSB7XG4gICAgaWYgKCEgdGhpcy5fYXV0b3Jlc2l6ZSlcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdNTFRleHRhcmVhIHN0b3BBdXRvcmVzaXplOiBhdXRvcmVzaXplIGlzIG5vdCBvbicpO1xuICAgIHRoaXMuX2F1dG9yZXNpemUgPSBmYWxzZTtcbiAgICBfbWFuYWdlU3Vic2NyaXB0aW9ucy5jYWxsKHRoaXMsICdvZmYnKTtcbn1cblxuXG5mdW5jdGlvbiBNTFRleHRhcmVhJGlzQXV0b3Jlc2l6ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2F1dG9yZXNpemU7XG59XG5cblxuZnVuY3Rpb24gTUxUZXh0YXJlYSRkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9hdXRvcmVzaXplKVxuICAgICAgICB0aGlzLnN0b3BBdXRvcmVzaXplKCk7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmZ1bmN0aW9uIE1MVGV4dGFyZWEkZGlzYWJsZShkaXNhYmxlKSB7XG4gICAgdGhpcy5lbC5kaXNhYmxlZCA9IGRpc2FibGU7XG59IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5Jyk7XG5cblxudmFyIE1MVGltZSA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxUaW1lJywge1xuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRhdGE6IHtcbiAgICAgICAgZ2V0OiBNTFRpbWVfZ2V0LFxuICAgICAgICBzZXQ6IE1MVGltZV9zZXQsXG4gICAgICAgIGRlbDogTUxUaW1lX2RlbCxcbiAgICB9LFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS10aW1lJ1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MVGltZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxUaW1lO1xuXG5cbnZhciBUSU1FX1JFR0VYID0gL14oWzAtOV17MSwyfSkoPzpcXDp8XFwuKShbMC05XXsxLDJ9KSQvXG4gICAgLCBUSU1FX1RFTVBMQVRFID0gJ2hoOm1tJztcblxuZnVuY3Rpb24gTUxUaW1lX2dldCgpIHtcbiAgICB2YXIgdGltZVN0ciA9IHRoaXMuZWwudmFsdWU7XG4gICAgdmFyIG1hdGNoID0gdGltZVN0ci5tYXRjaChUSU1FX1JFR0VYKTtcbiAgICBpZiAoISBtYXRjaCkgcmV0dXJuO1xuICAgIHZhciBob3VycyA9IG1hdGNoWzFdXG4gICAgICAgICwgbWlucyA9IG1hdGNoWzJdO1xuICAgIGlmIChob3VycyA+IDIzIHx8IG1pbnMgPiA1OSkgcmV0dXJuO1xuICAgIHZhciB0aW1lID0gbmV3IERhdGUoMTk3MCwgMCwgMSwgaG91cnMsIG1pbnMpO1xuXG4gICAgcmV0dXJuIF8udG9EYXRlKHRpbWUpO1xufVxuXG5cbmZ1bmN0aW9uIE1MVGltZV9zZXQodmFsdWUpIHtcbiAgICB2YXIgdGltZSA9IF8udG9EYXRlKHZhbHVlKTtcbiAgICBpZiAoISB0aW1lKSB7XG4gICAgICAgIHRoaXMuZWwudmFsdWUgPSAnJztcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0aW1lU3RyID0gVElNRV9URU1QTEFURVxuICAgICAgICAgICAgLnJlcGxhY2UoJ2hoJywgcGFkKHRpbWUuZ2V0SG91cnMoKSkpXG4gICAgICAgICAgICAucmVwbGFjZSgnbW0nLCBwYWQodGltZS5nZXRNaW51dGVzKCkpKTtcblxuICAgIHRoaXMuZWwudmFsdWUgPSB0aW1lU3RyO1xuICAgIHJldHVybiB0aW1lU3RyO1xuXG4gICAgZnVuY3Rpb24gcGFkKG4pIHtyZXR1cm4gbiA8IDEwID8gJzAnICsgbiA6IG47IH1cbn1cblxuXG5mdW5jdGlvbiBNTFRpbWVfZGVsKCkge1xuICAgIHRoaXMuZWwudmFsdWUgPSAnJztcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBNTFdyYXBwZXIgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MV3JhcHBlcicsIHtcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLXdyYXBwZXInXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxXcmFwcGVyKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTFdyYXBwZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi8uLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uLy4uL2NfcmVnaXN0cnknKVxuICAgICwgY29tcG9uZW50TmFtZSA9IHJlcXVpcmUoJy4uLy4uLy4uL3V0aWwvY29tcG9uZW50X25hbWUnKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vLi4vdXRpbC9sb2dnZXInKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi8uLi8uLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2hcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG52YXIgQUxFUlRfQ1NTX0NMQVNTRVMgPSB7XG4gICAgc3VjY2VzczogJ2FsZXJ0LXN1Y2Nlc3MnLFxuICAgIHdhcm5pbmc6ICdhbGVydC13YXJuaW5nJyxcbiAgICBpbmZvOiAnYWxlcnQtaW5mbycsXG4gICAgZGFuZ2VyOiAnYWxlcnQtZGFuZ2VyJyxcbiAgICBmaXhlZDogJ2FsZXJ0LWZpeGVkJ1xufTtcblxuXG52YXIgTUxBbGVydCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxBbGVydCcsIHtcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiBbJ21sLWJzLWFsZXJ0JywgJ2FsZXJ0JywgJ2ZhZGUnXSxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgJ3JvbGUnOiAnYWxlcnQnLFxuICAgICAgICAgICAgJ2FyaWEtaGlkZGVuJzogJ3RydWUnXG4gICAgICAgIH1cbiAgICB9LFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICAgIHRlbXBsYXRlOiAnXFxcbiAgICAgICAgICAgIHt7PyBpdC5jbG9zZSB9fVxcXG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtbC1iaW5kPVwiW2V2ZW50c106Y2xvc2VCdG5cIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGRhdGEtZGlzbWlzcz1cImFsZXJ0XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+JnRpbWVzOzwvYnV0dG9uPlxcXG4gICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICB7ez0gaXQubWVzc2FnZX19J1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MQWxlcnQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MQWxlcnQ7XG5cblxuXy5leHRlbmQoTUxBbGVydCwge1xuICAgIGNyZWF0ZUFsZXJ0OiBNTEFsZXJ0JCRjcmVhdGVBbGVydCxcbiAgICBvcGVuQWxlcnQ6IE1MQWxlcnQkJG9wZW5BbGVydCxcbn0pO1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxBbGVydCwge1xuICAgIG9wZW5BbGVydDogTUxBbGVydCRvcGVuQWxlcnQsXG4gICAgY2xvc2VBbGVydDogTUxBbGVydCRjbG9zZUFsZXJ0XG59KTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBuZXcgYWxlcnQgaW5zdGFuY2UuIFRvIGNyZWF0ZSBhbmQgb3BlbiBhdCB0aGUgc2FtZSB0aW1lIHVzZSBbb3BlbkFsZXJ0XSgjTUxBbGVydCQkb3BlbkFsZXJ0KVxuICogYG9wdGlvbnNgIGlzIGFuIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgICAgIG1lc3NhZ2U6IHN0cmluZyBhbGVydCBtZXNzYWdlXG4gKiAgICAgIHR5cGU6ICAgIG9wdGlvbmFsIHN0cmluZyB0aGUgdHlwZSBvZiBhbGVydCBtZXNzYWdlLCBvbmUgb2Ygc3VjY2Vzcywgd2FybmluZywgaW5mbywgZGFuZ2VyLCBmaXhlZFxuICogICAgICAgICAgICAgICBkZWZhdWx0ICdpbmZvJ1xuICogICAgICBjbG9zZTogICBvcHRpb25hbCBmYWxzZSB0byBwcmV2ZW50IHVzZXIgZnJvbSBjbG9zaW5nXG4gKiAgICAgICAgICAgICAgIG9yIHRydWUgKGRlZmF1bHQpIHRvIGVuYWJsZSBjbG9zaW5nIGFuZCByZW5kZXIgYSBjbG9zZSBidXR0b25cbiAqICAgICAgdGltZW91dDogb3B0aW9uYWwgdGltZXIsIGluIG1pbGxpc2Vjb25kcyB0byBhdXRvbWF0aWNhbGx5IGNsb3NlIHRoZSBhbGVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGFsZXJ0IGNvbmZpZ3VyYXRpb25cbiAqL1xuZnVuY3Rpb24gTUxBbGVydCQkY3JlYXRlQWxlcnQob3B0aW9ucykge1xuICAgIGNoZWNrKG9wdGlvbnMsIHtcbiAgICAgICAgbWVzc2FnZTogU3RyaW5nLFxuICAgICAgICB0eXBlOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICBjbG9zZTogTWF0Y2guT3B0aW9uYWwoQm9vbGVhbiksXG4gICAgICAgIHRpbWVvdXQ6IE1hdGNoLk9wdGlvbmFsKE51bWJlcilcbiAgICB9KTtcblxuICAgIHZhciBhbGVydCA9IE1MQWxlcnQuY3JlYXRlT25FbGVtZW50KCk7XG5cbiAgICBvcHRpb25zID0gX3ByZXBhcmVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgdmFyIGFsZXJ0Q2xzID0gQUxFUlRfQ1NTX0NMQVNTRVNbb3B0aW9ucy50eXBlXTtcbiAgICBhbGVydC5kb20uYWRkQ3NzQ2xhc3NlcyhhbGVydENscyk7XG5cbiAgICBhbGVydC5fYWxlcnQgPSB7XG4gICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgICAgIHZpc2libGU6IGZhbHNlXG4gICAgfTtcblxuICAgIGFsZXJ0LnRlbXBsYXRlLnJlbmRlcihvcHRpb25zKS5iaW5kZXIoKTtcblxuICAgIHZhciBhbGVydFNjb3BlID0gYWxlcnQuY29udGFpbmVyLnNjb3BlO1xuXG4gICAgaWYgKG9wdGlvbnMuY2xvc2UpXG4gICAgICAgIGFsZXJ0U2NvcGUuY2xvc2VCdG4uZXZlbnRzLm9uKCdjbGljaycsXG4gICAgICAgICAgICB7IHN1YnNjcmliZXI6IF9vbkNsb3NlQnRuQ2xpY2ssIGNvbnRleHQ6IGFsZXJ0IH0pO1xuXG4gICAgaWYgKG9wdGlvbnMudGltZW91dClcbiAgICAgICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgICAgICAgaWYoYWxlcnQuX2FsZXJ0LnZpc2libGUpXG4gICAgICAgICAgICAgICAgYWxlcnQuY2xvc2VBbGVydCgpO1xuICAgICAgICB9LCBvcHRpb25zLnRpbWVvdXQpO1xuXG4gICAgcmV0dXJuIGFsZXJ0O1xufVxuXG5cbi8qKlxuICogQ3JlYXRlIGFuZCBzaG93IGFsZXJ0IHBvcHVwXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgb2JqZWN0IHdpdGggbWVzc2FnZSwgdHlwZSwgY2xvc2UgYW5kIHRpbWVvdXRcbiAqIEByZXR1cm4ge01MQWxlcnR9IHRoZSBhbGVydCBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBNTEFsZXJ0JCRvcGVuQWxlcnQob3B0aW9ucykge1xuICAgIHZhciBhbGVydCA9IE1MQWxlcnQuY3JlYXRlQWxlcnQob3B0aW9ucyk7XG4gICAgYWxlcnQub3BlbkFsZXJ0KCk7XG4gICAgcmV0dXJuIGFsZXJ0O1xufVxuXG5cbmZ1bmN0aW9uIF9vbkNsb3NlQnRuQ2xpY2sodHlwZSwgZXZlbnQpIHtcbiAgICB0aGlzLmNsb3NlQWxlcnQoKTtcbn1cblxuXG5mdW5jdGlvbiBfcHJlcGFyZU9wdGlvbnMob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBfLmNsb25lKG9wdGlvbnMpO1xuICAgIG9wdGlvbnMuY2xvc2UgPSB0eXBlb2Ygb3B0aW9ucy5jbG9zZSA9PSAndW5kZWZpbmVkJyB8fCBvcHRpb25zLmNsb3NlID09PSB0cnVlO1xuICAgIG9wdGlvbnMudGltZW91dCA9IE1hdGguZmxvb3Iob3B0aW9ucy50aW1lb3V0KTtcbiAgICBvcHRpb25zLnR5cGUgPSBvcHRpb25zLnR5cGUgfHwgJ2luZm8nO1xuXG4gICAgcmV0dXJuIG9wdGlvbnM7XG59XG5cblxuLyoqXG4gKiBPcGVuIHRoZSBhbGVydFxuICovXG5mdW5jdGlvbiBNTEFsZXJ0JG9wZW5BbGVydCgpIHtcbiAgICBfdG9nZ2xlQWxlcnQuY2FsbCh0aGlzLCB0cnVlKTtcbn1cblxuXG4vKipcbiAqIENsb3NlIHRoZSBhbGVydFxuICovXG5mdW5jdGlvbiBNTEFsZXJ0JGNsb3NlQWxlcnQoKSB7XG4gICAgX3RvZ2dsZUFsZXJ0LmNhbGwodGhpcywgZmFsc2UpO1xuICAgIHRoaXMuZGVzdHJveSgpO1xufVxuXG5cbmZ1bmN0aW9uIF90b2dnbGVBbGVydChkb1Nob3cpIHtcbiAgICBkb1Nob3cgPSB0eXBlb2YgZG9TaG93ID09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICAgICAgPyAhIHRoaXMuX2FsZXJ0LnZpc2libGVcbiAgICAgICAgICAgICAgICA6ICEhIGRvU2hvdztcblxuICAgIHZhciBhZGRSZW1vdmUgPSBkb1Nob3cgPyAnYWRkJyA6ICdyZW1vdmUnXG4gICAgICAgICwgYXBwZW5kUmVtb3ZlID0gZG9TaG93ID8gJ2FwcGVuZENoaWxkJyA6ICdyZW1vdmVDaGlsZCc7XG5cbiAgICB0aGlzLl9hbGVydC52aXNpYmxlID0gZG9TaG93O1xuXG4gICAgZG9jdW1lbnQuYm9keVthcHBlbmRSZW1vdmVdKHRoaXMuZWwpO1xuICAgIHRoaXMuZG9tLnRvZ2dsZShkb1Nob3cpO1xuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICFkb1Nob3cpO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0W2FkZFJlbW92ZV0oJ2luJyk7XG4gICAgdGhpcy5lbFtkb1Nob3cgPyAnZm9jdXMnIDogJ2JsdXInXSgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi8uLi9jX3JlZ2lzdHJ5JylcbiAgICAsIGNvbXBvbmVudE5hbWUgPSByZXF1aXJlKCcuLi8uLi8uLi91dGlsL2NvbXBvbmVudF9uYW1lJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uLy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxudmFyIERFRkFVTFRfQlVUVE9OUyA9IFsgeyB0eXBlOiAnZGVmYXVsdCcsIGxhYmVsOiAnT0snLCByZXN1bHQ6ICdPSycgfSBdO1xuXG52YXIgQ0xPU0VfT1BUSU9OUyA9IFsnYmFja2Ryb3AnLCAna2V5Ym9hcmQnLCAnYnV0dG9uJ107XG5cbnZhciBCVVRUT05fQ1NTX0NMQVNTRVMgPSB7IC8vIFRPRE8gLSB1c2UgaW4gdGVtcGxhdGVcbiAgICBkZWZhdWx0OiAnYnRuLWRlZmF1bHQnLFxuICAgIHByaW1hcnk6ICdidG4tcHJpbWFyeScsXG4gICAgc3VjY2VzczogJ2J0bi1zdWNjZXNzJyxcbiAgICBpbmZvOiAnYnRuLWluZm8nLFxuICAgIHdhcm5pbmc6ICdidG4td2FybmluZycsXG4gICAgZGFuZ2VyOiAnYnRuLWRhbmdlcicsXG4gICAgbGluazogJ2J0bi1saW5rJ1xufTtcblxuXG4vKipcbiAqIERpYWxvZyBjbGFzcyB0byBzaG93IGN1c3RvbSBkaWFsb2cgYm94ZXMgYmFzZWQgb24gY29uZmlndXJhdGlvbiAtIHNlZSBbY3JlYXRlRGlhbG9nXSgjTUxEaWFsb2ckJGNyZWF0ZURpYWxvZykgbWV0aG9kLlxuICogT25seSBvbmUgZGlhbG9nIGNhbiBiZSBvcGVuZWQgYXQgYSB0aW1lIC0gdHJ5aW5nIHRvIG9wZW4gYW5vdGhlciB3aWxsIGxvZyBlcnJvciB0byBjb25zb2xlLiBDdXJyZW50bHkgb3BlbmVkIGRpYWxvZyBjYW4gYmUgcmV0cmlldmVkIHVzaW5nIFtnZXRDdXJyZW50RGlhbG9nXSgjTUxEaWFsb2ckJGdldEN1cnJlbnREaWFsb2cpIGNsYXNzIG1ldGhvZC5cbiAqL1xudmFyIE1MRGlhbG9nID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTERpYWxvZycsIHtcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiBbJ21sLWJzLWRpYWxvZycsICdtb2RhbCcsICdmYWRlJ10sXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICdyb2xlJzogJ2RpYWxvZycsXG4gICAgICAgICAgICAnYXJpYS1oaWRkZW4nOiAndHJ1ZSdcbiAgICAgICAgfVxuICAgIH0sXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgICAgdGVtcGxhdGU6ICdcXFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWRpYWxvZ1wiPlxcXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cXFxuICAgICAgICAgICAgICAgICAgICB7ez8gaXQudGl0bGUgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/IGl0LmNsb3NlLmJ1dHRvbiB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gbWwtYmluZD1cIltldmVudHNdOmNsb3NlQnRuXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY2xvc2VcIj4mdGltZXM7PC9idXR0b24+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGg0IGNsYXNzPVwibW9kYWwtdGl0bGVcIj57ez0gaXQudGl0bGUgfX08L2g0PlxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgICAgIHt7PyBpdC5odG1sIHx8IGl0LnRleHQgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIiBtbC1iaW5kPVwiW2NvbnRhaW5lcl06ZGlhbG9nQm9keVwiPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/IGl0Lmh0bWwgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez0gaXQuaHRtbCB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/P319XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+e3s9IGl0LnRleHQgfX08L3A+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgICAgIHt7PyBpdC5idXR0b25zICYmIGl0LmJ1dHRvbnMubGVuZ3RoIH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7fiBpdC5idXR0b25zIDpidG4gfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4te3s9IGJ0bi50eXBlIH19e3s/IGJ0bi5jbHMgfX0ge3s9IGJ0bi5jbHMgfX17ez99fVwiXFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1sLWJpbmQ9XCJbZXZlbnRzXTp7ez0gYnRuLm5hbWUgfX1cIj57ez0gYnRuLmxhYmVsIH19PC9idXR0b24+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e359fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgIDwvZGl2PidcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTERpYWxvZyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxEaWFsb2c7XG5cblxuXy5leHRlbmQoTUxEaWFsb2csIHtcbiAgICBjcmVhdGVEaWFsb2c6IE1MRGlhbG9nJCRjcmVhdGVEaWFsb2csXG4gICAgb3BlbkRpYWxvZzogTUxEaWFsb2ckJG9wZW5EaWFsb2csXG4gICAgZ2V0T3BlbmVkRGlhbG9nOiBNTERpYWxvZyQkZ2V0T3BlbmVkRGlhbG9nXG59KTtcblxuXG5fLmV4dGVuZFByb3RvKE1MRGlhbG9nLCB7XG4gICAgb3BlbkRpYWxvZzogTUxEaWFsb2ckb3BlbkRpYWxvZyxcbiAgICBjbG9zZURpYWxvZzogTUxEaWFsb2ckY2xvc2VEaWFsb2csXG4gICAgZGVzdHJveTogTUxEaWFsb2ckZGVzdHJveVxufSk7XG5cblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGRpYWxvZyBpbnN0YW5jZS4gVG8gY3JlYXRlIGFuZCBvcGVuIGF0IHRoZSBzYW1lIHRpbWUgW29wZW5EaWFsb2ddKCNNTERpYWxvZyQkb3BlbkRpYWxvZylcbiAqIGBvcHRpb25zYCBpcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAgIHRpdGxlOiBvcHRpb25hbCBkaWFsb2cgdGl0bGVcbiAqICAgICBodG1sOiBvcHRpb25hbCBkaWFsb2cgdGV4dCBhcyBodG1sICh3aWxsIHRha2UgcHJlY2VkZW5jZSBvdmVyIHRleHQgaWYgYm90aCB0ZXh0IG5kIGh0bWwgYXJlIHBhc3NlZClcbiAqICAgICAgIG9yXG4gKiAgICAgdGV4dDogb3B0aW9uYWwgZGlhbG9nIHRleHRcbiAqICAgICBjbG9zZTogb3B0aW9uYWwgZmFsc2UgdG8gcHJldmVudCBiYWNrZHJvcCBhbmQgZXNjIGtleSBmcm9tIGNsb3NpbmcgdGhlIGRpYWxvZyBhbmQgcmVtb3ZpbmcgY2xvc2UgYnV0dG9uIGluIHRvcCByaWdodCBjb3JuZXJcbiAqICAgICAgICAgICAgb3IgdHJ1ZSAoZGVmYXVsdCkgdG8gZW5hYmxlIGFsbCBjbG9zZSBvcHRpb25zXG4gKiAgICAgICAgICAgIG9yIG9iamVjdCB3aXRoIHByb3BlcnRpZXNcbiAqICAgICAgICAgYmFja2Ryb3A6IGZhbHNlIG9yIHRydWUgKGRlZmF1bHQpLCBjbG9zZSBkaWFsb2cgd2hlbiBiYWNrZHJvcCBjbGlja2VkXG4gKiAgICAgICAgIGtleWJvYXJkOiBmYWxzZSBvciB0cnVlIChkZWZhdWx0KSwgY2xvc2UgZGlhbG9nIHdoZW4gZXNjIGtleSBpcyBwcmVzc2VkXG4gKiAgICAgICAgIGJ1dHRvbjogZmFsc2Ugb3IgdHJ1ZSAoZGVmYXVsdCksIHNob3cgY2xvc2UgYnV0dG9uIGluIHRoZSBoZWFkZXIgKHdvbid0IGJlIHNob3duIGlmIHRoZXJlIGlzIG5vIGhlYWRlciB3aGVuIHRpdGxlIGlzIG5vdCBwYXNzZWQpXG4gKiAgICAgYnV0dG9uczogb3B0aW9uYWwgYXJyYXkgb2YgYnV0dG9ucyBjb25maWd1cmF0aW9ucywgd2hlcmUgZWFjaCBidXR0b24gY29uZmlnIGlzIGFuIG9iamVjdFxuICogICAgICAgICBuYW1lOiAgIG9wdGlvbmFsIG5hbWUgb2YgY29tcG9uZW50LCBzaG91bGQgYmUgdW5pcXVlIGFuZCBzaG91bGQgbm90IGJlIGBjbG9zZUJ0bmAsIGlmIG5vdCBwYXNzZWQgYSB0aW1lc3RhbXAgYmFzZWQgbmFtZSB3aWxsIGJlIHVzZWRcbiAqICAgICAgICAgdHlwZTogICBidXR0b24gdHlwZSwgd2lsbCBkZXRlcm1pbmUgYnV0dG9uIENTUyBzdHlsZS4gUG9zc2libGUgdHlwZXMgYXJlOiBkZWZ1bHQsIHByaW1hcnksIHN1Y2Nlc3MsIGluZm8sIHdhcm5pbmcsIGRhbmdlciwgbGluayAobWFwIHRvIHJlbGF0ZWQgYm9vdHN0cmFwIGJ1dHRvbiBzdHlsZXMpXG4gKiAgICAgICAgIGxhYmVsOiAgYnV0dG9uIGxhYmVsXG4gKiAgICAgICAgIGNsb3NlOiAgb3B0aW9uYWwgZmFsc2UgdG8gcHJldmVudCB0aGlzIGJ1dHRvbiBmcm9tIGNsb3NpbmcgZGlhbG9nXG4gKiAgICAgICAgIHJlc3VsdDogc3RyaW5nIHdpdGggZGlhbG9nIGNsb3NlIHJlc3VsdCB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIGRpYWxvZyBzdWJzY3JpYmVyIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXJcbiAqICAgICAgICAgZGF0YTogICBhbnkgdmFsdWUvb2JqZWN0IG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSBkYXRhIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gZGlhbG9nIHN1YnNjcmliZXIgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIuXG4gKiAgICAgICAgICAgICAgICAgSWYgZnVuY3Rpb24gaXMgcGFzc2VkIGl0IHdpbGwgYmUgY2FsbGVkIHdpdGggZGlhbG9nIGFzIGNvbnRleHQgYW5kIGJ1dHRvbiBvcHRpb25zIGFzIHBhcmFtZXRlci5cbiAqXG4gKiAgICAgSWYgYHRpdGxlYCBpcyBub3QgcGFzc2VkLCBkaWFsb2cgd2lsbCBub3QgaGF2ZSB0aXRsZSBzZWN0aW9uICAgXG4gKiAgICAgSWYgbmVpdGhlciBgdGV4dGAgbm9yIGBodG1sYCBpcyBwYXNzZWQsIGRpYWxvZyB3aWxsIG5vdCBoYXZlIGJvZHkgc2VjdGlvbi5cbiAqICAgICBJZiBgYnV0dG9uc2AgYXJlIG5vdCBwYXNzZWQsIHRoZXJlIHdpbGwgb25seSBiZSBPSyBidXR0b24uXG4gKlxuICogV2hlbiBkaWFsb2cgaXMgY2xvc2VkLCB0aGUgc3Vic2NyaWJlciBpcyBjYWxsZWQgd2l0aCByZWF1bHQgYW5kIG9wdGlvbmFsIGRhdGEgYXMgZGVmaW5lZCBpbiBidXR0b25zIGNvbmZpZ3VyYXRpb25zLlxuICogSWYgYmFja2Ryb3AgaXMgY2xpY2tlZCBvciBFU0Mga2V5IGlzIHByZXNzZWQgdGhlIHJlc3VsdCB3aWxsIGJlICdkaXNtaXNzZWQnXG4gKiBJZiBjbG9zZSBidXR0b24gaW4gdGhlIHRvcCByaWdodCBjb3JuZXIgaXMgY2xpY2tlZCwgdGhlIHJlc3VsdCB3aWxsIGJlICdjbG9zZWQnIChkZWZhdWx0IHJlc3VsdClcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgZGlhbG9nIGNvbmZpZ3VyYXRpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGluaXRpYWxpemUgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGUgZGlhbG9nXG4gKi9cbmZ1bmN0aW9uIE1MRGlhbG9nJCRjcmVhdGVEaWFsb2cob3B0aW9ucywgaW5pdGlhbGl6ZSkge1xuICAgIGNoZWNrKG9wdGlvbnMsIHtcbiAgICAgICAgdGl0bGU6IE1hdGNoLk9wdGlvbmFsKFN0cmluZyksXG4gICAgICAgIGh0bWw6IE1hdGNoLk9wdGlvbmFsKFN0cmluZyksXG4gICAgICAgIHRleHQ6IE1hdGNoLk9wdGlvbmFsKFN0cmluZyksXG4gICAgICAgIGNsb3NlOiBNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihCb29sZWFuLCB7XG4gICAgICAgICAgICBiYWNrZHJvcDogTWF0Y2guT3B0aW9uYWwoQm9vbGVhbiksXG4gICAgICAgICAgICBrZXlib2FyZDogTWF0Y2guT3B0aW9uYWwoQm9vbGVhbiksXG4gICAgICAgICAgICBidXR0b246IE1hdGNoLk9wdGlvbmFsKEJvb2xlYW4pXG4gICAgICAgIH0pKSxcbiAgICAgICAgYnV0dG9uczogTWF0Y2guT3B0aW9uYWwoWyB7XG4gICAgICAgICAgICBuYW1lOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgICAgICAgbGFiZWw6IFN0cmluZyxcbiAgICAgICAgICAgIGNsb3NlOiBNYXRjaC5PcHRpb25hbChCb29sZWFuKSxcbiAgICAgICAgICAgIHJlc3VsdDogTWF0Y2guT3B0aW9uYWwoU3RyaW5nKSxcbiAgICAgICAgICAgIGRhdGE6IE1hdGNoLk9wdGlvbmFsKE1hdGNoLkFueSksXG4gICAgICAgICAgICBjbHM6IE1hdGNoLk9wdGlvbmFsKFN0cmluZylcbiAgICAgICAgfSBdKVxuICAgIH0pO1xuXG4gICAgdmFyIGRpYWxvZyA9IE1MRGlhbG9nLmNyZWF0ZU9uRWxlbWVudCgpO1xuXG4gICAgb3B0aW9ucyA9IF9wcmVwYXJlT3B0aW9ucyhvcHRpb25zKTtcbiAgICBkaWFsb2cuX2RpYWxvZyA9IHtcbiAgICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgICAgdmlzaWJsZTogZmFsc2VcbiAgICB9O1xuXG4gICAgZGlhbG9nLnRlbXBsYXRlXG4gICAgICAgIC5yZW5kZXIob3B0aW9ucylcbiAgICAgICAgLmJpbmRlcigpO1xuXG4gICAgdmFyIGRpYWxvZ1Njb3BlID0gZGlhbG9nLmNvbnRhaW5lci5zY29wZTtcblxuICAgIGlmIChvcHRpb25zLmNsb3NlLmJhY2tkcm9wKVxuICAgICAgICBkaWFsb2cuZXZlbnRzLm9uKCdjbGljaycsXG4gICAgICAgICAgICB7IHN1YnNjcmliZXI6IF9vbkJhY2tkcm9wQ2xpY2ssIGNvbnRleHQ6IGRpYWxvZyB9KTtcblxuICAgIGlmIChvcHRpb25zLnRpdGxlICYmIG9wdGlvbnMuY2xvc2UuYnV0dG9uKVxuICAgICAgICBkaWFsb2dTY29wZS5jbG9zZUJ0bi5ldmVudHMub24oJ2NsaWNrJyxcbiAgICAgICAgICAgIHsgc3Vic2NyaWJlcjogX29uQ2xvc2VCdG5DbGljaywgY29udGV4dDogZGlhbG9nIH0pO1xuXG4gICAgb3B0aW9ucy5idXR0b25zLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIHZhciBidXR0b25TdWJzY3JpYmVyID0ge1xuICAgICAgICAgICAgc3Vic2NyaWJlcjogXy5wYXJ0aWFsKF9kaWFsb2dCdXR0b25DbGljaywgYnRuKSxcbiAgICAgICAgICAgIGNvbnRleHQ6IGRpYWxvZ1xuICAgICAgICB9O1xuICAgICAgICBkaWFsb2dTY29wZVtidG4ubmFtZV0uZXZlbnRzLm9uKCdjbGljaycsIGJ1dHRvblN1YnNjcmliZXIpO1xuICAgIH0pO1xuXG4gICAgaWYgKGluaXRpYWxpemUpIGluaXRpYWxpemUoZGlhbG9nKTtcbiAgICByZXR1cm4gZGlhbG9nO1xufVxuXG5cbmZ1bmN0aW9uIF9kaWFsb2dCdXR0b25DbGljayhidXR0b24pIHtcbiAgICBpZiAoYnV0dG9uLmNsb3NlICE9PSBmYWxzZSlcbiAgICAgICAgX3RvZ2dsZURpYWxvZy5jYWxsKHRoaXMsIGZhbHNlKTtcblxuICAgIHZhciBkYXRhID0gXy5yZXN1bHQoYnV0dG9uLmRhdGEsIHRoaXMsIGJ1dHRvbik7XG4gICAgX2Rpc3BhdGNoUmVzdWx0LmNhbGwodGhpcywgYnV0dG9uLnJlc3VsdCwgZGF0YSk7XG59XG5cblxuZnVuY3Rpb24gX2Rpc3BhdGNoUmVzdWx0KHJlc3VsdCwgZGF0YSkge1xuICAgIHZhciBzdWJzY3JpYmVyID0gdGhpcy5fZGlhbG9nLnN1YnNjcmliZXI7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpYmVyID09ICdmdW5jdGlvbicpXG4gICAgICAgIHN1YnNjcmliZXIuY2FsbCh0aGlzLCByZXN1bHQsIGRhdGEpO1xuICAgIGVsc2VcbiAgICAgICAgc3Vic2NyaWJlci5zdWJzY3JpYmVyLmNhbGwoc3Vic2NyaWJlci5jb250ZXh0LCByZXN1bHQsIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIF9vbkJhY2tkcm9wQ2xpY2soZXZlbnRUeXBlLCBldmVudCkge1xuICAgIGlmIChldmVudC50YXJnZXQgPT0gdGhpcy5lbClcbiAgICAgICAgdGhpcy5jbG9zZURpYWxvZygnZGlzbWlzc2VkJyk7XG59XG5cblxuZnVuY3Rpb24gX29uQ2xvc2VCdG5DbGljaygpIHtcbiAgICB0aGlzLmNsb3NlRGlhbG9nKCdjbG9zZWQnKTtcbn1cblxuXG5mdW5jdGlvbiBfb25LZXlEb3duKGV2ZW50KSB7XG4gICAgaWYgKG9wZW5lZERpYWxvZ1xuICAgICAgICAgICAgJiYgb3BlbmVkRGlhbG9nLl9kaWFsb2cub3B0aW9ucy5jbG9zZS5rZXlib2FyZFxuICAgICAgICAgICAgJiYgZXZlbnQua2V5Q29kZSA9PSAyNykgLy8gZXNjIGtleVxuICAgICAgICBvcGVuZWREaWFsb2cuY2xvc2VEaWFsb2coJ2Rpc21pc3NlZCcpO1xufVxuXG5cbmZ1bmN0aW9uIF9wcmVwYXJlT3B0aW9ucyhvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IF8uY2xvbmUob3B0aW9ucyk7XG4gICAgb3B0aW9ucy5idXR0b25zID0gXy5jbG9uZShvcHRpb25zLmJ1dHRvbnMgfHwgREVGQVVMVF9CVVRUT05TKTtcbiAgICBvcHRpb25zLmJ1dHRvbnMuZm9yRWFjaChmdW5jdGlvbihidG4pIHtcbiAgICAgICAgYnRuLm5hbWUgPSBidG4ubmFtZSB8fCBjb21wb25lbnROYW1lKCk7XG4gICAgfSk7XG5cbiAgICBvcHRpb25zLmNsb3NlID0gdHlwZW9mIG9wdGlvbnMuY2xvc2UgPT0gJ3VuZGVmaW5lZCcgfHwgb3B0aW9ucy5jbG9zZSA9PT0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBfLm9iamVjdChDTE9TRV9PUFRJT05TLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2Ygb3B0aW9ucy5jbG9zZSA9PSAnb2JqZWN0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gXy5tYXBUb09iamVjdChDTE9TRV9PUFRJT05TLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihvcHQpIHsgcmV0dXJuIG9wdGlvbnMuY2xvc2Vbb3B0XSAhPT0gZmFsc2U7IH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfLm9iamVjdChDTE9TRV9PUFRJT05TLCBmYWxzZSk7XG5cbiAgICByZXR1cm4gb3B0aW9ucztcbn1cblxuXG4vKipcbiAqIENyZWF0ZSBhbmQgc2hvdyBkaWFsb2cgcG9wdXBcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgb2JqZWN0IHdpdGggdGl0bGUsIHRleHQgYW5kIGJ1dHRvbnMuIFNlZSBbY3JlYXRlRGlhbG9nXSgjTUxEaWFsb2ckJGNyZWF0ZURpYWxvZykgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdH0gc3Vic2NyaWJlciBvcHRpb25hbCBzdWJzY3JpYmVyIGZ1bmN0aW9uIG9yIG9iamVjdCB0aGF0IGlzIHBhc3NlZCByZXN1bHQgYW5kIG9wdGlvbmFsIGRhdGEuIFVubGVzcyBjb250ZXh0IGlzIGRlZmluZWQsIGRpYWxvZyB3aWxsIGJlIHRoZSBjb250ZXh0LlxuICovXG5mdW5jdGlvbiBNTERpYWxvZyQkb3BlbkRpYWxvZyhvcHRpb25zLCBzdWJzY3JpYmVyLCBpbml0aWFsaXplKSB7XG4gICAgdmFyIGRpYWxvZyA9IE1MRGlhbG9nLmNyZWF0ZURpYWxvZyhvcHRpb25zLCBpbml0aWFsaXplKTtcbiAgICBkaWFsb2cub3BlbkRpYWxvZyhzdWJzY3JpYmVyKTtcbiAgICByZXR1cm4gZGlhbG9nO1xufVxuXG5cblxuZnVuY3Rpb24gX3RvZ2dsZURpYWxvZyhkb1Nob3cpIHtcbiAgICBkb1Nob3cgPSB0eXBlb2YgZG9TaG93ID09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICAgICAgPyAhIHRoaXMuX2RpYWxvZy52aXNpYmxlXG4gICAgICAgICAgICAgICAgOiAhISBkb1Nob3c7XG5cbiAgICB2YXIgYWRkUmVtb3ZlID0gZG9TaG93ID8gJ2FkZCcgOiAncmVtb3ZlJ1xuICAgICAgICAsIGFwcGVuZFJlbW92ZSA9IGRvU2hvdyA/ICdhcHBlbmRDaGlsZCcgOiAncmVtb3ZlQ2hpbGQnO1xuXG4gICAgdGhpcy5fZGlhbG9nLnZpc2libGUgPSBkb1Nob3c7XG5cbiAgICBpZiAoZG9TaG93ICYmICEgZGlhbG9nc0luaXRpYWxpemVkKVxuICAgICAgICBfaW5pdGlhbGl6ZURpYWxvZ3MoKTtcblxuICAgIGRvY3VtZW50LmJvZHlbYXBwZW5kUmVtb3ZlXSh0aGlzLmVsKTtcbiAgICBpZiAoYmFja2Ryb3BFbClcbiAgICAgICAgZG9jdW1lbnQuYm9keVthcHBlbmRSZW1vdmVdKGJhY2tkcm9wRWwpO1xuICAgIHRoaXMuZG9tLnRvZ2dsZShkb1Nob3cpO1xuICAgIHRoaXMuZWwuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICFkb1Nob3cpO1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0W2FkZFJlbW92ZV0oJ21vZGFsLW9wZW4nKTtcbiAgICB0aGlzLmVsLmNsYXNzTGlzdFthZGRSZW1vdmVdKCdpbicpO1xuXG4gICAgb3BlbmVkRGlhbG9nID0gZG9TaG93ID8gdGhpcyA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLmVsW2RvU2hvdyA/ICdmb2N1cycgOiAnYmx1ciddKCk7XG59XG5cblxudmFyIGRpYWxvZ3NJbml0aWFsaXplZCwgYmFja2Ryb3BFbDtcblxuZnVuY3Rpb24gX2luaXRpYWxpemVEaWFsb2dzKCkge1xuICAgIGJhY2tkcm9wRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBiYWNrZHJvcEVsLmNsYXNzTmFtZSA9ICdtb2RhbC1iYWNrZHJvcCBmYWRlIGluJztcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgX29uS2V5RG93bik7XG4gICAgZGlhbG9nc0luaXRpYWxpemVkID0gdHJ1ZTtcbn1cblxuXG52YXIgb3BlbmVkRGlhbG9nO1xuXG4vKipcbiAqIE9wZW5zIGRpYWxvZyBpbnN0YW5jZS5cbiAqIFN1YnNjcmliZXIgb2JqZWN0IHNob3VsZCBoYXZlIHRoZSBzYW1lIGZvcm1hdCBhcyB0aGUgc3Vic2NyaWJlciBmb3IgdGhlIE1lc3NlbmdlciAoYWx0aG91Z2ggTWVzc2VuZ2VyIGlzIG5vdCB1c2VkKSAtIGVpdGhlciBmdW5jdGlvbiBvciBvYmplY3Qgd2l0aCBzdWJzY3JpYmVyIGFuZCBjb250ZXh0IHByb3BlcnRpZXMuXG4gKiBcbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBzdWJzY3JpYmVyIHN1YnNjcmliZXIgb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIE1MRGlhbG9nJG9wZW5EaWFsb2coc3Vic2NyaWJlcikge1xuICAgIGNoZWNrKHN1YnNjcmliZXIsIE1hdGNoLk9uZU9mKEZ1bmN0aW9uLCB7IHN1YnNjcmliZXI6IEZ1bmN0aW9uLCBjb250ZXh0OiBNYXRjaC5BbnkgfSkpO1xuXG4gICAgaWYgKG9wZW5lZERpYWxvZylcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdNTERpYWxvZyBvcGVuRGlhbG9nOiBjYW5cXCd0IG9wZW4gZGlhbG9nLCBhbm90aGVyIGRpYWxvZyBpcyBhbHJlYWR5IG9wZW4nKTtcblxuICAgIHRoaXMuX2RpYWxvZy5zdWJzY3JpYmVyID0gc3Vic2NyaWJlcjtcbiAgICBfdG9nZ2xlRGlhbG9nLmNhbGwodGhpcywgdHJ1ZSk7XG59XG5cblxuLyoqXG4gKiBDbG9zZXMgZGlhbG9nIGluc3RhbmNlLCBvcHRpb25hbGx5IHBhc3NpbmcgcmVzdWx0IGFuZCBkYXRhIHRvIGRpYWxvZyBzdWJzY3JpYmVyLlxuICogSWYgbm8gcmVzdWx0IGlzIHBhc3NlZCwgJ2Nsb3NlZCcgd2lsbCBiZSBwYXNzZWQgdG8gc3Vic2NyaWJlci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVzdWx0IGRpYWxvZyByZXN1bHQsIHBhc3NlZCBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyIHRvIHN1YmNzcmliZXJcbiAqIEBwYXJhbSB7QW55fSBkYXRhIG9wdGlvbmFsIGRpYWxvZyBkYXRhLCBwYXNzZWQgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgdG8gc3Vic2NyaWJlclxuICovXG5mdW5jdGlvbiBNTERpYWxvZyRjbG9zZURpYWxvZyhyZXN1bHQsIGRhdGEpIHtcbiAgICBpZiAoISBvcGVuZWREaWFsb2cpXG4gICAgICAgIHJldHVybiBsb2dnZXIud2FybignTUxEaWFsb2cgY2xvc2VEaWFsb2c6IGNhblxcJ3QgY2xvc2UgZGlhbG9nLCBubyBkaWFsb2cgb3BlbicpO1xuXG4gICAgcmVzdWx0ID0gcmVzdWx0IHx8ICdjbG9zZWQnO1xuXG4gICAgX3RvZ2dsZURpYWxvZy5jYWxsKHRoaXMsIGZhbHNlKTtcbiAgICBfZGlzcGF0Y2hSZXN1bHQuY2FsbCh0aGlzLCByZXN1bHQsIGRhdGEpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBjdXJyZW50bHkgb3BlbmVkIGRpYWxvZ1xuICpcbiAqIEByZXR1cm4ge01MRGlhbG9nfVxuICovXG5mdW5jdGlvbiBNTERpYWxvZyQkZ2V0T3BlbmVkRGlhbG9nKCkge1xuICAgIHJldHVybiBvcGVuZWREaWFsb2c7XG59XG5cblxuZnVuY3Rpb24gTUxEaWFsb2ckZGVzdHJveSgpIHtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgX29uS2V5RG93bik7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi8uLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uLy4uL2NfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi91dGlsL2xvZ2dlcicpXG4gICAgLCBET01MaXN0ZW5lcnMgPSByZXF1aXJlKCcuLi8uLi8uLi91dGlsL2RvbV9saXN0ZW5lcnMnKTtcblxuXG52YXIgVE9HR0xFX0NTU19DTEFTUyA9ICdkcm9wZG93bi10b2dnbGUnXG4gICAgLCBNRU5VX0NTU19DTEFTUyA9ICdkcm9wZG93bi1tZW51JztcblxuXG52YXIgTUxEcm9wZG93biA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxEcm9wZG93bicsIHtcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiBbJ21sLWJzLWRyb3Bkb3duJywgJ2Ryb3Bkb3duJ11cbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTERyb3Bkb3duKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTERyb3Bkb3duO1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxEcm9wZG93biwge1xuICAgIHN0YXJ0OiBNTERyb3Bkb3duJHN0YXJ0LFxuICAgIGRlc3Ryb3k6IE1MRHJvcGRvd24kZGVzdHJveSxcbiAgICB0b2dnbGVNZW51OiBNTERyb3Bkb3duJHRvZ2dsZU1lbnUsXG4gICAgc2hvd01lbnU6IE1MRHJvcGRvd24kc2hvd01lbnUsXG4gICAgaGlkZU1lbnU6IE1MRHJvcGRvd24kaGlkZU1lbnVcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MRHJvcGRvd24kc3RhcnQoKSB7XG4gICAgdmFyIHRvZ2dsZUVsID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKCcuJyArIFRPR0dMRV9DU1NfQ0xBU1MpXG4gICAgICAgICwgbWVudUVsID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKCcuJyArIE1FTlVfQ1NTX0NMQVNTKTtcblxuICAgIGlmICghICh0b2dnbGVFbCAmJiBtZW51RWwpKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLmVycm9yKCdNTERyb3Bkb3duOicsIFRPR0dMRV9DU1NfQ0xBU1MsICdvcicsIE1FTlVfQ1NTX0NMQVNTLCAnaXNuXFwndCBmb3VuZCcpO1xuXG4gICAgdmFyIGRvYyA9IHdpbmRvdy5kb2N1bWVudFxuICAgICAgICAsIGNsaWNrSGFuZGxlciA9IHRoaXMudG9nZ2xlTWVudS5iaW5kKHRoaXMsIHVuZGVmaW5lZCk7XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gbmV3IERPTUxpc3RlbmVycztcbiAgICB0aGlzLl9kcm9wZG93biA9IHtcbiAgICAgICAgbWVudTogbWVudUVsLFxuICAgICAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICAgICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgICB9O1xuICAgIHRoaXMuaGlkZU1lbnUoKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBsaXN0ZW5lcnMuYWRkKHRvZ2dsZUVsLCAnY2xpY2snLCBjbGlja0hhbmRsZXIpO1xuICAgIC8vbWF5YmUgb25seSBhZGQgdGhpcyBldmVudHMgaWYgaXMgb3Blbj9cbiAgICBsaXN0ZW5lcnMuYWRkKGRvYywgJ21vdXNlb3V0Jywgb25Eb2NPdXQpO1xuICAgIGxpc3RlbmVycy5hZGQoZG9jLCAnY2xpY2snLCBvbkNsaWNrKTtcblxuXG4gICAgZnVuY3Rpb24gb25Eb2NPdXQoZXZlbnQpIHtcbiAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldFxuICAgICAgICAgICAgLCByZWxhdGVkVGFyZ2V0ID0gZXZlbnQucmVsYXRlZFRhcmdldFxuICAgICAgICAgICAgLCBsaXN0ZW5lcnMgPSBzZWxmLl9kcm9wZG93bi5saXN0ZW5lcnM7XG5cbiAgICAgICAgaWYgKGlzSWZyYW1lKHRhcmdldCkpXG4gICAgICAgICAgICBsaXN0ZW5lcnMucmVtb3ZlKHRhcmdldC5jb250ZW50V2luZG93LmRvY3VtZW50LCAnY2xpY2snLCBvbkNsaWNrKTtcblxuICAgICAgICBpZiAoaXNJZnJhbWUocmVsYXRlZFRhcmdldCkpXG4gICAgICAgICAgICBsaXN0ZW5lcnMuYWRkKHJlbGF0ZWRUYXJnZXQuY29udGVudFdpbmRvdy5kb2N1bWVudCwgJ2NsaWNrJywgb25DbGljayk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25DbGljayhldmVudCkge1xuICAgICAgICBpZiAoIXNlbGYuZWwuY29udGFpbnMoZXZlbnQudGFyZ2V0KSlcbiAgICAgICAgICAgIHNlbGYuaGlkZU1lbnUoKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gaXNJZnJhbWUoZWwpIHtcbiAgICByZXR1cm4gZWwgJiYgZWwudGFnTmFtZSA9PSAnSUZSQU1FJztcbn1cblxuXG5mdW5jdGlvbiBNTERyb3Bkb3duJGRlc3Ryb3koKSB7XG4gICAgdGhpcy5fZHJvcGRvd24ubGlzdGVuZXJzLnJlbW92ZUFsbCgpO1xuICAgIGRlbGV0ZSB0aGlzLl9kcm9wZG93bjtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG5mdW5jdGlvbiBNTERyb3Bkb3duJHNob3dNZW51KCkge1xuICAgIHRoaXMudG9nZ2xlTWVudSh0cnVlKTtcbn1cblxuXG5mdW5jdGlvbiBNTERyb3Bkb3duJGhpZGVNZW51KCkge1xuICAgIHRoaXMudG9nZ2xlTWVudShmYWxzZSk7XG59XG5cblxuZnVuY3Rpb24gTUxEcm9wZG93biR0b2dnbGVNZW51KGRvU2hvdykge1xuICAgIGRvU2hvdyA9IHR5cGVvZiBkb1Nob3cgPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICA/ICEgdGhpcy5fZHJvcGRvd24udmlzaWJsZVxuICAgICAgICAgICAgICAgIDogISEgZG9TaG93O1xuXG4gICAgdGhpcy5fZHJvcGRvd24udmlzaWJsZSA9IGRvU2hvdztcblxuICAgIHZhciBtZW51ID0gdGhpcy5fZHJvcGRvd24ubWVudTtcbiAgICBtZW51LnN0eWxlLmRpc3BsYXkgPSBkb1Nob3dcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICdibG9jaydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICdub25lJztcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG4vLyA8YSBuYW1lPVwiY29uZmlnXCI+PC9hPlxuLy8gbWlsby5jb25maWdcbi8vIC0tLS0tLS0tLS0tXG5cbi8vIEl0IGlzIHRoZSBmdW5jdGlvbiB0aGF0IGFsbG93cyB0byBjaGFuZ2UgbWlsbyBjb25maWd1cmF0aW9ucyBhbmQgYWxzb1xuLy8gYWNjZXNzIHRoZW0gb24gY29uZmlnJ3MgcHJvcGVydGllcy5cblxuLy8gYGBgamF2YXNjcmlwdFxuLy8gbWlsby5jb25maWcoe1xuLy8gICAgIGF0dHJzOiB7XG4vLyAgICAgICAgIGJpbmQ6ICdtbC1iaW5kJyxcbi8vICAgICAgICAgbG9hZDogJ21sLWxvYWQnXG4vLyAgICAgfVxuLy8gfSk7XG4vLyBgYGBcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBkb1QgPSByZXF1aXJlKCdkb3QnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbmZpZztcblxuZnVuY3Rpb24gY29uZmlnKG9wdGlvbnMpIHtcbiAgICBfLmRlZXBFeHRlbmQoY29uZmlnLCBvcHRpb25zKTtcbn1cblxuY29uZmlnKHtcbiAgICBhdHRyczoge1xuICAgICAgICBiaW5kOiAnbWwtYmluZCcsXG4gICAgICAgIGxvYWQ6ICdtbC1sb2FkJ1xuICAgIH0sXG4gICAgY29tcG9uZW50UmVmOiAnX19fbWlsb19jb21wb25lbnQnLFxuICAgIGNvbXBvbmVudFByZWZpeDogJ21pbG9fJyxcbiAgICBtaXhpbjoge1xuICAgICAgICBpbnN0YW5jZVByb3BlcnRpZXNNYXA6ICdfX19taXhpbl9pbnN0YW5jZXMnXG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgICBjb21waWxlOiBkb1QuY29tcGlsZVxuICAgIH0sXG4gICAgZG9tU3RvcmFnZToge1xuICAgICAgICB0eXBlU3VmZml4OiAnOl9fX21pbG9fZGF0YV90eXBlJyxcbiAgICAgICAgcHJlZml4U2VwYXJhdG9yOiAnLycsXG4gICAgICAgIHJvb3Q6ICcnLFxuICAgICAgICBtZXNzYWdlS2V5OiAnX19fbWlsb19tZXNzYWdlLycsXG4gICAgICAgIG1lc3NhZ2VUaW1lc3RhbXA6ICdfX19taWxvX3RpbWVzdGFtcCcsXG4gICAgICAgIHF1b3RhRXhjZWVkZWQ6IHtcbiAgICAgICAgICAgIHRocm93RXJyb3I6IHRydWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBmYWxzZVxuICAgICAgICB9XG4gICAgfSxcbiAgICBkcmFnRHJvcDoge1xuICAgICAgICBkYXRhVHlwZXM6IHtcbiAgICAgICAgICAgIGNvbXBvbmVudDogJ3gtYXBwbGljYXRpb24vbWlsby9jb21wb25lbnQnLFxuICAgICAgICAgICAgY29tcG9uZW50TWV0YVRlbXBsYXRlOiAneC1hcHBsaWNhdGlvbi9taWxvL2NvbXBvbmVudC1tZXRhLyVjbGFzcy8lbmFtZS8lcGFyYW1zJyxcbiAgICAgICAgICAgIGNvbXBvbmVudE1ldGFSZWdleDogL154XFwtYXBwbGljYXRpb25cXC9taWxvXFwvY29tcG9uZW50XFwtbWV0YVxcLyhbYS16MC05XSspXFwvKFthLXowLTldKylcXC8oW2EtejAtOV0qKSQvLFxuICAgICAgICB9XG4gICAgfSxcbiAgICByZXF1ZXN0OiB7XG4gICAgICAgIGpzb25wVGltZW91dDogNjAwMDAsXG4gICAgICAgIGpzb25wQ2FsbGJhY2tQcmVmaXg6ICdfX19taWxvX2NhbGxiYWNrXycsXG4gICAgICAgIG9wdGlvbnNLZXk6ICdfX19taWxvX29wdGlvbnMnLFxuICAgICAgICBkZWZhdWx0czoge1xuICAgICAgICAgICAgdGltZW91dDogNjAwMDBcbiAgICAgICAgfVxuICAgIH0sXG4gICAgd2Vic29ja2V0OiB7XG4gICAgICAgIHJwYzoge1xuICAgICAgICAgICAgdGltZW91dDogMTUwMDAsXG4gICAgICAgICAgICByZXNwb25zZVByZWZpeDogJ3Jlc3BvbnNlXydcbiAgICAgICAgfVxuICAgIH0sXG4gICAgY2hlY2s6IHRydWUsXG4gICAgZGVidWc6IGZhbHNlXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbWlsb01haWwgPSByZXF1aXJlKCcuL3NlcnZpY2VzL21haWwnKVxuICAgICwgcmVxdWVzdCA9IHJlcXVpcmUoJy4vdXRpbC9yZXF1ZXN0JylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4vdXRpbC9sb2dnZXInKVxuICAgICwgdXRpbERvbSA9IHJlcXVpcmUoJy4vdXRpbC9kb20nKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKVxuICAgICwgTG9hZEF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4vYXR0cmlidXRlcy9hX2xvYWQnKVxuICAgICwgTG9hZGVyRXJyb3IgPSByZXF1aXJlKCcuL3V0aWwvZXJyb3InKS5Mb2FkZXI7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBsb2FkZXI7XG5cbi8qKlxuICogYG1pbG8ubG9hZGVyYFxuICogXG4gKiBSZWN1cnNpdmVseSBzY2FucyB0aGUgZG9jdW1lbnQgdHJlZSBpbnNpZGUgYHJvb3RFbGAgKGRvY3VtZW50LmJvZHkgYnkgZGVmYXVsdCkgbG9va2luZyBmb3IgX19tbC1sb2FkX18gQGF0dHJpYnV0ZS5cbiAqIE9uZSBsZXZlbCBsb2FkIGlzIGV4ZWN1dGVkLiBObyBhZGRpdGlvbmFsIGxvYWRlciBnZXQgY2FsbGVkIG9uIGluc2lkZSBfX21sLWxvYWRfXyBhdHRyaWJ1dGVzLiBcbiAqXG4gKiBQb3NzaWJsZSB1c2FnZXM6XG4gKiAtIG1pbG8ubG9hZGVyKFtteVJvb3RFbCxdW215UmVtb3ZlQXR0cmlidXRlLF1teUNhbGxiYWNrKVxuICogXG4gKiBAcGFyYW0gIHtFbGVtZW50fSAgcm9vdEVsICAgICAgICAgIFJvb3QgZWxlbWVudCBpbnNpZGUgd2hpY2ggRE9NIHdpbGwgYmUgc2Nhbm5lZCAoZG9jdW1lbnQuYm9keSBieSBkZWZhdWx0KS5cbiAqIEBwYXJhbSAge0Jvb2xlYW59ICByZW1vdmVBdHRyaWJ1dGUgSWYgc2V0IHRvIHRydWUsIHRoZW4gdGhlIF9fbWwtbG9hZF9fIGF0dHJpYnV0ZSB3aWxsIGJlIHJlbW92ZWQgb25jZSBsb2FkZXIgaGFzIGJlZW4gZXhlY3V0ZWQgKEZhbHNlIGJ5IGRlZmF1bHQpLlxuICogQHBhcmFtICB7RnVuY3Rpb259IGNhbGxiYWNrICAgICAgICBDYWxsYmFjayB0byBjYWxsIGFmdGVyIGFsbCBlbGVtZW50cyBnZXQgbG9hZGVkIChSZXF1aXJlZCkuXG4gKi9cbmZ1bmN0aW9uIGxvYWRlcihyb290RWwsIHJlbW92ZUF0dHJpYnV0ZSwgY2FsbGJhY2spIHtcbiAgICBtaWxvKGZ1bmN0aW9uKCkge1xuICAgICAgICBfbG9hZGVyKHJvb3RFbCwgcmVtb3ZlQXR0cmlidXRlLCBjYWxsYmFjayk7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gX2xvYWRlcihyb290RWwsIHJlbW92ZUF0dHJpYnV0ZSwgY2FsbGJhY2spIHtcbiAgICBpZiAodHlwZW9mIHJvb3RFbCA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNhbGxiYWNrID0gcm9vdEVsO1xuICAgICAgICByb290RWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJlbW92ZUF0dHJpYnV0ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcmVtb3ZlQXR0cmlidXRlID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY2FsbGJhY2sgPSByZW1vdmVBdHRyaWJ1dGU7XG4gICAgICAgIHJlbW92ZUF0dHJpYnV0ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIHJvb3RFbCA9IHJvb3RFbCB8fCBkb2N1bWVudC5ib2R5O1xuXG4gICAgbWlsb01haWwucG9zdE1lc3NhZ2UoJ2xvYWRlcicsIHsgc3RhdGU6ICdzdGFydGVkJyB9KTtcbiAgICBfbG9hZFZpZXdzSW5FbGVtZW50KHJvb3RFbCwgcmVtb3ZlQXR0cmlidXRlLCBmdW5jdGlvbih2aWV3cykge1xuICAgICAgICBtaWxvTWFpbC5wb3N0TWVzc2FnZSgnbG9hZGVyJywgeyBcbiAgICAgICAgICAgIHN0YXRlOiAnZmluaXNoZWQnLFxuICAgICAgICAgICAgdmlld3M6IHZpZXdzXG4gICAgICAgIH0pO1xuICAgICAgICBjYWxsYmFjayh2aWV3cyk7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gX2xvYWRWaWV3c0luRWxlbWVudChyb290RWwsIHJlbW92ZUF0dHJpYnV0ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgbG9hZEVsZW1lbnRzID0gcm9vdEVsLmdldEF0dHJpYnV0ZShjb25maWcuYXR0cnMubG9hZClcbiAgICAgICAgICAgICAgICAgICAgICAgID8gW3Jvb3RFbF1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogcm9vdEVsLnF1ZXJ5U2VsZWN0b3JBbGwoJ1snICsgY29uZmlnLmF0dHJzLmxvYWQgKyAnXScpO1xuXG4gICAgdmFyIHZpZXdzID0ge31cbiAgICAgICAgLCB0b3RhbENvdW50ID0gbG9hZEVsZW1lbnRzLmxlbmd0aFxuICAgICAgICAsIGxvYWRlZENvdW50ID0gMDtcblxuICAgIF8uZm9yRWFjaChsb2FkRWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICBsb2FkVmlldyhlbCwgcmVtb3ZlQXR0cmlidXRlLCBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICAgIHZpZXdzW2VsLmlkXSA9IGVyciB8fCBlbDtcbiAgICAgICAgICAgIGxvYWRlZENvdW50Kys7XG4gICAgICAgICAgICBpZiAobG9hZGVkQ291bnQgPT0gdG90YWxDb3VudClcbiAgICAgICAgICAgICAgICBjYWxsYmFjayh2aWV3cyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuXG5mdW5jdGlvbiBsb2FkVmlldyhlbCwgcmVtb3ZlQXR0cmlidXRlLCBjYWxsYmFjaykge1xuICAgIGlmICh1dGlsRG9tLmNoaWxkcmVuKGVsKS5sZW5ndGgpXG4gICAgICAgIHRocm93IG5ldyBMb2FkZXJFcnJvcignY2FuXFwndCBsb2FkIGh0bWwgaW50byBlbGVtZW50IHRoYXQgaXMgbm90IGVtcHR5Jyk7XG5cbiAgICB2YXIgYXR0ciA9IG5ldyBMb2FkQXR0cmlidXRlKGVsKTtcblxuICAgIGF0dHIucGFyc2UoKS52YWxpZGF0ZSgpO1xuXG4gICAgcmVxdWVzdC5nZXQoYXR0ci5sb2FkVXJsLCBmdW5jdGlvbihlcnIsIGh0bWwpIHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgZXJyLm1lc3NhZ2UgPSBlcnIubWVzc2FnZSB8fCAnY2FuXFwndCBsb2FkIGZpbGUgJyArIGF0dHIubG9hZFVybDtcbiAgICAgICAgICAgIC8vIGxvZ2dlci5lcnJvcihlcnIubWVzc2FnZSk7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZWwuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgaWYgKHJlbW92ZUF0dHJpYnV0ZSkgTG9hZEF0dHJpYnV0ZS5yZW1vdmUoZWwpO1xuICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICB9KTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1peGluID0gcmVxdWlyZSgnLi4vYWJzdHJhY3QvbWl4aW4nKVxuICAgIC8vICwgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4vbWVzc2FnZV9zb3VyY2UnKVxuICAgICwgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4vbV9zb3VyY2UnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgTWVzc2VuZ2VyRXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuTWVzc2VuZ2VyO1xuXG5cbi8qKlxuICogYG1pbG8uTWVzc2VuZ2VyYFxuICogQSBnZW5lcmljIE1lc3NlbmdlciBjbGFzcyB0aGF0IGlzIHVzZWQgZm9yIGFsbCBraW5kcyBvZiBtZXNzYWdpbmcgaW4gbWlsby4gSXQgaXMgc3ViY2xhc3NlZCBmcm9tIFtNaXhpbl0oLi4vYWJzdHJhY3QvbWl4aW4uanMuaHRtbCkgYW5kIGl0IHByb3hpZXMgaXRzIG1ldGhvZHMgdG8gdGhlIGhvc3Qgb2JqZWN0IGZvciBjb252ZW5pZW5jZS5cbiAqIEFsbCBmYWNldHMgYW5kIGNvbXBvbmVudHMgaGF2ZSBtZXNzZW5nZXIgYXR0YWNoZWQgdG8gdGhlbS4gTWVzc2VuZ2VyIGNsYXNzIGludGVyb3BlcmF0ZXMgd2l0aCBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBjbGFzcyB0aGF0IGNvbm5lY3RzIHRoZSBtZXNzZW5nZXIgdG8gc29tZSBleHRlcm5hbCBzb3VyY2Ugb2YgbWVzc2FnZXMgKGUuZy4sIERPTSBldmVudHMpIGFuZCBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpIGNsYXNzIHRoYXQgYWxsb3dzIHRvIGRlZmluZSBoaWdoZXIgbGV2ZWwgbWVzc2FnZXMgdGhhbiBtZXNzYWdlcyB0aGF0IGV4aXN0IG9uIHRoZSBzb3VyY2UuXG4gKiBNZXNzZW5nZXIgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IGluIG1pbG8gYW5kIGNhbiBiZSB1c2VkIHRvZ2V0aGVyIHdpdGggYW55IG9iamVjdHMvY2xhc3NlcyBpbiB0aGUgYXBwbGljYXRpb24uXG4gKiBtaWxvIGFsc28gZGVmaW5lcyBhIGdsb2JhbCBtZXNzZW5nZXIgW21pbG8ubWFpbF0oLi4vbWFpbC9pbmRleC5qcy5odG1sKSB0aGF0IGRpc3BhdGNoZXMgYGRvbXJlYWR5YCBldmVudCBhbmQgY2FuIGJlIHVzZWQgZm9yIGFueSBhcHBsaWNhdGlvbiB3aWRlIG1lc3NhZ2luZy5cbiAqIFRvIGluaXRpYWxpemUgeW91ciBhcHAgYWZ0ZXIgRE9NIGlzIHJlYWR5IHVzZTpcbiAqIGBgYFxuICogbWlsby5tYWlsLm9uKCdkb21yZWFkeScsIGZ1bmN0aW9uKCkge1xuICogICAgIC8vIGFwcGxpY2F0aW9uIHN0YXJ0c1xuICogfSk7XG4gKiBgYGBcbiAqIG9yIHRoZSBmb2xsb3dpbmcgc2hvcnRlciBmb3JtIG9mIHRoZSBzYW1lOlxuICogYGBgXG4gKiBtaWxvKGZ1bmN0aW9uKCkge1xuICogICAgIC8vIGFwcGxpY2F0aW9uIHN0YXJ0c1xuICogfSk7XG4gKiBgYGBcbiAqL1xudmFyIE1lc3NlbmdlciA9IF8uY3JlYXRlU3ViY2xhc3MoTWl4aW4sICdNZXNzZW5nZXInKTtcblxudmFyIG1lc3NhZ2VzU3BsaXRSZWdFeHAgPSBNZXNzZW5nZXIubWVzc2FnZXNTcGxpdFJlZ0V4cCA9IC9cXHMqKD86XFwsfFxccylcXHMqLztcblxuXG4vKipcbiAqICMjIyNNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtpbml0XSgjaW5pdClcbiAqIC0gW29uXSgjTWVzc2VuZ2VyJG9uKSAoYWxpYXMgLSBvbk1lc3NhZ2UsIGRlcHJlY2F0ZWQpXG4gKiAtIFtvZmZdKCNNZXNzZW5nZXIkb2ZmKSAoYWxpYXMgLSBvZmZNZXNzYWdlLCBkZXByZWNhdGVkKVxuICogLSBbb25NZXNzYWdlc10oI29uTWVzc2FnZXMpXG4gKiAtIFtvZmZNZXNzYWdlc10oI29mZk1lc3NhZ2VzKVxuICogLSBbb25jZV0oI29uY2UpXG4gKiAtIFtvbmNlU3luY10oI29uY2VTeW5jKVxuICogLSBbcG9zdE1lc3NhZ2VdKCNwb3N0TWVzc2FnZSlcbiAqIC0gW2dldFN1YnNjcmliZXJzXSgjZ2V0U3Vic2NyaWJlcnMpXG4gKlxuICogXCJQcml2YXRlXCIgbWV0aG9kc1xuICpcbiAqIC0gW19jaG9vc2VTdWJzY3JpYmVyc0hhc2hdKCNfY2hvb3NlU3Vic2NyaWJlcnNIYXNoKVxuICogLSBbX3JlZ2lzdGVyU3Vic2NyaWJlcl0oI19yZWdpc3RlclN1YnNjcmliZXIpXG4gKiAtIFtfcmVtb3ZlU3Vic2NyaWJlcl0oI19yZW1vdmVTdWJzY3JpYmVyKVxuICogLSBbX3JlbW92ZUFsbFN1YnNjcmliZXJzXSgjX3JlbW92ZUFsbFN1YnNjcmliZXJzKVxuICogLSBbX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnNdKCNfY2FsbFBhdHRlcm5TdWJzY3JpYmVycylcbiAqIC0gW19jYWxsU3Vic2NyaWJlcnNdKCNfY2FsbFN1YnNjcmliZXJzKVxuICogLSBbX3NldE1lc3NhZ2VTb3VyY2VdKCNfc2V0TWVzc2FnZVNvdXJjZSlcbiAqIC0gW2dldE1lc3NhZ2VTb3VyY2VdKCNnZXRNZXNzYWdlU291cmNlKVxuICovXG5fLmV4dGVuZFByb3RvKE1lc3Nlbmdlciwge1xuICAgIGluaXQ6IGluaXQsIC8vIGNhbGxlZCBieSBNaXhpbiAoc3VwZXJjbGFzcylcbiAgICBkZXN0cm95OiBNZXNzZW5nZXIkZGVzdHJveSxcbiAgICBvbjogTWVzc2VuZ2VyJG9uLFxuICAgIG9uY2U6IE1lc3NlbmdlciRvbmNlLFxuICAgIG9uY2VTeW5jOiBNZXNzZW5nZXIkb25jZVN5bmMsXG4gICAgb25TeW5jOiBNZXNzZW5nZXIkb25TeW5jLFxuICAgIG9uQXN5bmM6IE1lc3NlbmdlciRvbkFzeW5jLFxuICAgIG9uTWVzc2FnZTogTWVzc2VuZ2VyJG9uLCAvLyBkZXByZWNhdGVkXG4gICAgb2ZmOiBNZXNzZW5nZXIkb2ZmLFxuICAgIG9mZk1lc3NhZ2U6IE1lc3NlbmdlciRvZmYsIC8vIGRlcHJlY2F0ZWRcbiAgICBvbk1lc3NhZ2VzOiBvbk1lc3NhZ2VzLFxuICAgIG9mZk1lc3NhZ2VzOiBvZmZNZXNzYWdlcyxcbiAgICBvZmZBbGw6IE1lc3NlbmdlciRvZmZBbGwsXG4gICAgcG9zdE1lc3NhZ2U6IHBvc3RNZXNzYWdlLFxuICAgIHBvc3RNZXNzYWdlU3luYzogcG9zdE1lc3NhZ2VTeW5jLFxuICAgIGdldFN1YnNjcmliZXJzOiBnZXRTdWJzY3JpYmVycyxcbiAgICBnZXRNZXNzYWdlU291cmNlOiBnZXRNZXNzYWdlU291cmNlLFxuICAgIF9jaG9vc2VTdWJzY3JpYmVyc0hhc2g6IF9jaG9vc2VTdWJzY3JpYmVyc0hhc2gsXG4gICAgX3JlZ2lzdGVyU3Vic2NyaWJlcjogX3JlZ2lzdGVyU3Vic2NyaWJlcixcbiAgICBfcmVtb3ZlU3Vic2NyaWJlcjogX3JlbW92ZVN1YnNjcmliZXIsXG4gICAgX3JlbW92ZUFsbFN1YnNjcmliZXJzOiBfcmVtb3ZlQWxsU3Vic2NyaWJlcnMsXG4gICAgX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnM6IF9jYWxsUGF0dGVyblN1YnNjcmliZXJzLFxuICAgIF9jYWxsU3Vic2NyaWJlcnM6IF9jYWxsU3Vic2NyaWJlcnMsXG4gICAgX2NhbGxTdWJzY3JpYmVyOiBfY2FsbFN1YnNjcmliZXIsXG4gICAgX3NldE1lc3NhZ2VTb3VyY2U6IF9zZXRNZXNzYWdlU291cmNlXG59KTtcblxuXG4vKipcbiAqIEEgZGVmYXVsdCBtYXAgb2YgcHJveHkgbWV0aG9kcyB1c2VkIGJ5IENvbXBvbmVudEZhY2V0IGFuZCBDb21wb25lbnQgY2xhc3NlcyB0byBwYXNzIHRvIE1lc3NlbmdlciB3aGVuIGl0IGlzIGluc3RhbnRpYXRlZC5cbiAqIFRoaXMgbWFwIGlzIGZvciBjb252ZW5pZW5jZSBvbmx5LCBpdCBpcyBOT1QgdXNlZCBpbnRlcm5hbGx5IGJ5IE1lc3NlbmdlciwgYSBob3N0IGNsYXNzIHNob3VsZCBwYXNzIGl0IGZvciBtZXRob2RzIHRvIGJlIHByb3hpZWQgdGhpcyB3YXkuXG4gKi9cbk1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyA9IHtcbiAgICBvbjogJ29uJyxcbiAgICBvblN5bmM6ICdvblN5bmMnLFxuICAgIG9uY2U6ICdvbmNlJyxcbiAgICBvbmNlU3luYzogJ29uY2VTeW5jJyxcbiAgICBvZmY6ICdvZmYnLFxuICAgIG9uTWVzc2FnZXM6ICdvbk1lc3NhZ2VzJyxcbiAgICBvZmZNZXNzYWdlczogJ29mZk1lc3NhZ2VzJyxcbiAgICBwb3N0TWVzc2FnZTogJ3Bvc3RNZXNzYWdlJyxcbiAgICBwb3N0TWVzc2FnZVN5bmM6ICdwb3N0TWVzc2FnZVN5bmMnLFxuICAgIGdldFN1YnNjcmliZXJzOiAnZ2V0U3Vic2NyaWJlcnMnXG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWVzc2VuZ2VyO1xuXG5cbk1lc3Nlbmdlci5zdWJzY3JpcHRpb25zID0gW107XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplcyBNZXNzZW5nZXIuIE1ldGhvZCBpcyBjYWxsZWQgYnkgTWl4aW4gY2xhc3MgY29uc3RydWN0b3IuXG4gKiBTZWUgW29uXSgjTWVzc2VuZ2VyJG9uKSBtZXRob2QsIFtNZXNzZW5nZXJdKCNNZXNzZW5nZXIpIGNsYXNzIGFib3ZlIGFuZCBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBjbGFzcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBPcHRpb25hbCBvYmplY3QgdGhhdCBzdG9yZXMgdGhlIG1lc3NlbmdlciBvbiBvbmUgb2YgaXRzIHByb3BlcnRpZXMuIEl0IGlzIHVzZWQgdG8gcHJveHkgbWV0aG9kcyBvZiBtZXNzZW5nZXIgYW5kIGFsc28gYXMgYSBjb250ZXh0IGZvciBzdWJzY3JpYmVycyB3aGVuIHRoZXkgYXJlIGNhbGxlZCBieSB0aGUgTWVzc2VuZ2VyLiBTZWUgYG9uYCBtZXRob2QuXG4gKiBAcGFyYW0ge09iamVjdH0gcHJveHlNZXRob2RzIE9wdGlvbmFsIG1hcCBvZiBtZXRob2QgbmFtZXM7IGtleSAtIHByb3h5IG1ldGhvZCBuYW1lLCB2YWx1ZSAtIG1lc3NlbmdlcidzIG1ldGhvZCBuYW1lLlxuICogQHBhcmFtIHtNZXNzYWdlU291cmNlfSBtZXNzYWdlU291cmNlIE9wdGlvbmFsIG1lc3NhZ2VTb3VyY2UgbGlua2VkIHRvIHRoZSBtZXNzZW5nZXIuIElmIG1lc3NhZ2VTb3VyY2UgaXMgc3VwcGxpZWQsIHRoZSByZWZlcmVuY2UgdG8gdGhlIG1lc3NlbmdlciB3aWxsIHN0b3JlZCBvbiBpdHMgJ21lc3NlbmdlcicgcHJvcGVydHlcbiAqL1xuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NhZ2VTb3VyY2UpIHtcbiAgICAvLyBob3N0T2JqZWN0IGFuZCBwcm94eU1ldGhvZHMgYXJlIHVzZWQgaW4gTWl4aW4gYW5kIGNoZWNrZWQgdGhlcmVcbiAgICBpZiAobWVzc2FnZVNvdXJjZSlcbiAgICAgICAgdGhpcy5fc2V0TWVzc2FnZVNvdXJjZShtZXNzYWdlU291cmNlKTtcblxuICAgIF9pbml0aWFsaXplU3Vic2NyaWJlcnMuY2FsbCh0aGlzKTtcbn1cblxuXG5mdW5jdGlvbiBfaW5pdGlhbGl6ZVN1YnNjcmliZXJzKCkge1xuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgIF9tZXNzYWdlU3Vic2NyaWJlcnM6IHt9LFxuICAgICAgICBfcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVyczoge30sXG4gICAgfSwgXy5DT05GKTtcbn1cblxuXG4vKipcbiAqIERlc3Ryb3lzIG1lc3Nlbmdlci4gTWF5YmUgbmVlZHMgdG8gdW5zdWJzY3JpYmUgYWxsIHN1YnNjcmliZXJzXG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRkZXN0cm95KCkge1xuICAgIHRoaXMub2ZmQWxsKCk7XG4gICAgdmFyIG1lc3NhZ2VTb3VyY2UgPSB0aGlzLmdldE1lc3NhZ2VTb3VyY2UoKTtcbiAgICBpZiAobWVzc2FnZVNvdXJjZSlcbiAgICAgICAgbWVzc2FnZVNvdXJjZS5kZXN0cm95KCk7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogUmVnaXN0ZXJzIGEgc3Vic2NyaWJlciBmdW5jdGlvbiBmb3IgYSBjZXJ0YWluIG1lc3NhZ2UocykuXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB0cnVlYCBpZiB0aGUgc3Vic2NyaXB0aW9uIHdhcyBzdWNjZXNzZnVsLiBJdCBjYW4gYmUgdW5zdWNjZXNzZnVsIGlmIHRoZSBwYXNzZWQgc3Vic2NyaWJlciBoYXMgYWxyZWFkeSBiZWVuIHN1YnNjcmliZWQgdG8gdGhpcyBtZXNzYWdlIHR5cGUgLSBkb3VibGUgc3Vic2NyaXB0aW9uIG5ldmVyIGhhcHBlbnMgYW5kIGl0IGlzIHNhZmUgdG8gc3Vic2NyaWJlIGFnYWluIC0gbm8gZXJyb3Igb3Igd2FybmluZyBpcyB0aHJvd24gb3IgbG9nZ2VkLlxuICogU3Vic2NyaWJlciBpcyBwYXNzZWQgdHdvIHBhcmFtZXRlcnM6IGBtZXNzYWdlYCAoc3RyaW5nKSBhbmQgYGRhdGFgIChvYmplY3QpLiBEYXRhIG9iamVjdCBpcyBzdXBwbGllZCB3aGVuIG1lc3NhZ2UgaXMgZGlzcGF0Y2hlZCwgTWVzc2VuZ2VyIGl0c2VsZiBhZGRzIG5vdGhpbmcgdG8gaXQuIEZvciBleGFtcGxlLCBbZXZlbnRzIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL0V2ZW50cy5qcy5odG1sKSBzZW5kcyBhY3R1YWwgRE9NIGV2ZW50IHdoZW4gaXQgcG9zdHMgbWVzc2FnZS5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiAvLyBzdWJzY3JpYmVzIG9uTW91c2VVcERvd24gdG8gdHdvIERPTSBldmVudHMgb24gY29tcG9uZW50IHZpYSBldmVudHMgZmFjZXQuXG4gKiBteUNvbXAuZXZlbnRzLm9uKCdtb3VzZWRvd24gbW91c2V1cCcsIG9uTW91c2VVcERvd24pO1xuICogZnVuY3Rpb24gb25Nb3VzZVVwRG93bihldmVudFR5cGUsIGV2ZW50KSB7XG4gKiAgICAgLy8gLi4uXG4gKiB9XG4gKlxuICogbXlDb21wLmRhdGEub24oLy4rLywgZnVuY3Rpb24obXNnLCBkYXRhKSB7XG4gKiAgICAgbG9nZ2VyLmRlYnVnKG1zZywgZGF0YSk7XG4gKiB9KTsgLy8gc3Vic2NyaWJlcyBhbm9ueW1vdXMgZnVuY3Rpb24gdG8gYWxsIG5vbi1lbXB0eSBtZXNzYWdlcyBvbiBkYXRhIGZhY2V0XG4gKiAvLyBpdCB3aWxsIG5vdCBiZSBwb3NzaWJsZSB0byB1bnN1YnNjcmliZSBhbm9ueW1vdXMgc3Vic2NyaWJlciBzZXBhcmF0ZWx5LFxuICogLy8gYnV0IG15Q29tcC5kYXRhLm9mZigvLisvKSB3aWxsIHVuc3Vic2NyaWJlIGl0XG4gKiBgYGBcbiAqIElmIG1lc3NlbmdlciBoYXMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgYXR0YWNoZWQgdG8gaXQsIE1lc3NhZ2VTb3VyY2Ugd2lsbCBiZSBub3RpZmllZCB3aGVuIHRoZSBmaXJzdCBzdWJzY3JpYmVyIGZvciBhIGdpdmVuIG1lc3NhZ2UgaXMgYWRkZWQsIHNvIGl0IGNhbiBzdWJzY3JpYmUgdG8gdGhlIHNvdXJjZS5cbiAqIFtDb21wb25lbnRzXSguLi9jb21wb25lbnRzL2NfY2xhc3MuanMuaHRtbCkgYW5kIFtmYWNldHNdKC4uL2NvbXBvbmVudHMvY19mYWNldC5qcy5odG1sKSBjaGFuZ2UgdGhpcyBtZXRob2QgbmFtZSB0byBgb25gIHdoZW4gdGhleSBwcm94eSBpdC5cbiAqIFNlZSBbcG9zdE1lc3NhZ2VdKCNwb3N0TWVzc2FnZSkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXlbU3RyaW5nXXxSZWdFeHB9IG1lc3NhZ2VzIE1lc3NhZ2UgdHlwZXMgdGhhdCBzaG91bGQgZW52b2tlIHRoZSBzdWJzY3JpYmVyLlxuICogIElmIHN0cmluZyBpcyBwYXNzZWQsIGl0IGNhbiBiZSBhIHNpZ2xlIG1lc3NhZ2Ugb3IgbXVsdGlwbGUgbWVzc2FnZSB0eXBlcyBzZXBhcmF0ZWQgYnkgd2hpdGVzcGFjZSB3aXRoIG9wdGlvbmFsIGNvbW1hcy5cbiAqICBJZiBhbiBhcnJheSBvZiBzdHJpbmdzIGlzIHBhc3NlZCwgZWFjaCBzdHJpbmcgaXMgYSBtZXNzYWdlIHR5cGUgdG8gc3Vic2NyaWJlIGZvci5cbiAqICBJZiBhIFJlZ0V4cCBpcyBwYXNzZWQsIHRoZSBzdWJzY3JpYmVyIHdpbGwgYmUgZW52b2tlZCB3aGVuIHRoZSBtZXNzYWdlIGRpc3BhdGNoZWQgb24gdGhlIG1lc3NlbmdlciBtYXRjaGVzIHRoZSBwYXR0ZXJuIChvciBJUyB0aGUgUmVnRXhwIHdpdGggaWRlbnRpY2FsIHBhdHRlcm4pLlxuICogIFBhdHRlcm4gc3Vic2NyaWJlciBkb2VzIE5PVCBjYXVzZSBhbnkgc3Vic2NyaXB0aW9uIHRvIE1lc3NhZ2VTb3VyY2UsIGl0IG9ubHkgY2FwdHVyZXMgbWVzc2FnZXMgdGhhdCBhcmUgYWxyZWFkeSBzdWJzY3JpYmVkIHRvIHdpdGggcHJlY2lzZSBtZXNzYWdlIHR5cGVzLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IHN1YnNjcmliZXIgTWVzc2FnZSBzdWJzY3JpYmVyIC0gYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIG1lc3NhZ2UgaXMgZGlzcGF0Y2hlZCBvbiB0aGUgbWVzc2VuZ2VyICh1c3VhbGx5IHZpYSBwcm94aWVkIHBvc3RNZXNzYWdlIG1ldGhvZCBvZiBob3N0IG9iamVjdCkuXG4gKiAgSWYgaG9zdE9iamVjdCB3YXMgc3VwcGxpZWQgdG8gTWVzc2VuZ2VyIGNvbnN0cnVjdG9yLCBob3N0T2JqZWN0IHdpbGwgYmUgdGhlIGNvbnRleHQgKHRoZSB2YWx1ZSBvZiB0aGlzKSBmb3IgdGhlIHN1YnNjcmliZXIgZW52b2NhdGlvbi5cbiAqICBTdWJzY3JpYmVyIGNhbiBhbHNvIGJlIGFuIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgYHN1YnNjcmliZXJgIChmdW5jdGlvbikgYW5kIGBjb250ZXh0YCAoXCJ0aGlzXCIgdmFsdWUgd2hlbiBzdWJzY3JpYmVyIGlzIGNhbGxlZClcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRvbihtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMuY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG59XG5cblxuZnVuY3Rpb24gTWVzc2VuZ2VyJG9uY2UobWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICByZXR1cm4gX01lc3Nlbmdlcl9vbldpdGhPcHRpb25zLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIsIHsgZGlzcGF0Y2hUaW1lczogMSB9KTtcbn1cblxuZnVuY3Rpb24gTWVzc2VuZ2VyJG9uY2VTeW5jKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucy5jYWxsKHRoaXMsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyLCB7IGRpc3BhdGNoVGltZXM6IDEsIHN5bmM6IHRydWUgfSk7XG59XG5cblxuZnVuY3Rpb24gTWVzc2VuZ2VyJG9uU3luYyhtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMuY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlciwgeyBzeW5jOiB0cnVlIH0pO1xufVxuXG5cbmZ1bmN0aW9uIE1lc3NlbmdlciRvbkFzeW5jKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucy5jYWxsKHRoaXMsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyLCB7IHN5bmM6IGZhbHNlIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucyhtZXNzYWdlcywgc3Vic2NyaWJlciwgb3B0aW9ucykge1xuICAgIGNoZWNrKG1lc3NhZ2VzLCBNYXRjaC5PbmVPZihTdHJpbmcsIFtTdHJpbmddLCBSZWdFeHApKTtcbiAgICBjaGVjayhzdWJzY3JpYmVyLCBNYXRjaC5PbmVPZihGdW5jdGlvbiwge1xuICAgICAgICBzdWJzY3JpYmVyOiBGdW5jdGlvbixcbiAgICAgICAgY29udGV4dDogTWF0Y2guQW55LFxuICAgICAgICBvcHRpb25zOiBNYXRjaC5PcHRpb25hbChPYmplY3QpLFxuICAgIH0pKTtcblxuICAgIGlmICh0eXBlb2Ygc3Vic2NyaWJlciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHN1YnNjcmliZXIgPSB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyOiBzdWJzY3JpYmVyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5faG9zdE9iamVjdCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgICBzdWJzY3JpYmVyLm9wdGlvbnMgPSBzdWJzY3JpYmVyLm9wdGlvbnMgfHwge307XG4gICAgICAgIF8uZXh0ZW5kKHN1YnNjcmliZXIub3B0aW9ucywgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb24uY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG59XG5cblxuZnVuY3Rpb24gX01lc3Nlbmdlcl9vbihtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIF8uZGVmaW5lUHJvcGVydHkoc3Vic2NyaWJlciwgJ19fbWVzc2FnZXMnLCBtZXNzYWdlcyk7XG4gICAgcmV0dXJuIF9lYWNoTWVzc2FnZS5jYWxsKHRoaXMsICdfcmVnaXN0ZXJTdWJzY3JpYmVyJywgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xufVxuXG5cbmZ1bmN0aW9uIF9lYWNoTWVzc2FnZShtZXRob2ROYW1lLCBtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZXMgPT0gJ3N0cmluZycpXG4gICAgICAgIG1lc3NhZ2VzID0gbWVzc2FnZXMuc3BsaXQobWVzc2FnZXNTcGxpdFJlZ0V4cCk7XG5cbiAgICB2YXIgc3Vic2NyaWJlcnNIYXNoID0gdGhpcy5fY2hvb3NlU3Vic2NyaWJlcnNIYXNoKG1lc3NhZ2VzKTtcblxuICAgIGlmIChtZXNzYWdlcyBpbnN0YW5jZW9mIFJlZ0V4cClcbiAgICAgICAgcmV0dXJuIHRoaXNbbWV0aG9kTmFtZV0oc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG5cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGNoYW5nZWQgPSBmYWxzZTtcblxuICAgICAgICBtZXNzYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIHZhciBzdWJzY3JpcHRpb25DaGFuZ2VkID0gdGhpc1ttZXRob2ROYW1lXShzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UsIHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgY2hhbmdlZCA9IGNoYW5nZWQgfHwgc3Vic2NyaXB0aW9uQ2hhbmdlZDtcbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIGNoYW5nZWQ7XG4gICAgfVxufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogSXQgaXMgY2FsbGVkIGJ5IFtvbl0oI01lc3NlbmdlciRvbikgdG8gcmVnaXN0ZXIgc3Vic2NyaWJlciBmb3Igb25lIG1lc3NhZ2UgdHlwZS5cbiAqIFJldHVybnMgYHRydWVgIGlmIHRoaXMgc3Vic2NyaWJlciBpcyBub3QgeWV0IHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHlwZSBvZiBtZXNzYWdlLlxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGZpcnN0IHN1YnNjcmliZXIgZm9yIGEgZ2l2ZW4gbWVzc2FnZSBpcyBhZGRlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN1YnNjcmliZXJzSGFzaCBUaGUgbWFwIG9mIHN1YnNjcmliZXJzIGRldGVybWluZWQgYnkgW29uXSgjTWVzc2VuZ2VyJG9uKSBiYXNlZCBvbiBNZXNzYWdlIHR5cGUsIGNhbiBiZSBgdGhpcy5fcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVyc2Agb3IgYHRoaXMuX21lc3NhZ2VTdWJzY3JpYmVyc2BcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIE1lc3NhZ2UgdHlwZVxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IHN1YnNjcmliZXIgU3Vic2NyaWJlciBmdW5jdGlvbiB0byBiZSBhZGRlZCBvciBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIGBzdWJzY3JpYmVyYCAoZnVuY3Rpb24pIGFuZCBgY29udGV4dGAgKHZhbHVlIG9mIFwidGhpc1wiIHdoZW4gc3Vic2NyaWJlciBpcyBjYWxsZWQpXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBfcmVnaXN0ZXJTdWJzY3JpYmVyKHN1YnNjcmliZXJzSGFzaCwgbWVzc2FnZSwgc3Vic2NyaWJlcikge1xuICAgIGlmICghIChzdWJzY3JpYmVyc0hhc2hbbWVzc2FnZV0gJiYgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdLmxlbmd0aCkpIHtcbiAgICAgICAgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdID0gW107XG4gICAgICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgUmVnRXhwKVxuICAgICAgICAgICAgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdLnBhdHRlcm4gPSBtZXNzYWdlO1xuICAgICAgICBpZiAodGhpcy5fbWVzc2FnZVNvdXJjZSlcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VTb3VyY2Uub25TdWJzY3JpYmVyQWRkZWQobWVzc2FnZSk7XG4gICAgICAgIHZhciBub1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgbXNnU3Vic2NyaWJlcnMgPSBzdWJzY3JpYmVyc0hhc2hbbWVzc2FnZV07XG4gICAgdmFyIG5vdFlldFJlZ2lzdGVyZWQgPSBub1N1YnNjcmliZXJzIHx8IF9pbmRleE9mU3Vic2NyaWJlci5jYWxsKHRoaXMsIG1zZ1N1YnNjcmliZXJzLCBzdWJzY3JpYmVyKSA9PSAtMTtcblxuICAgIGlmIChub3RZZXRSZWdpc3RlcmVkKVxuICAgICAgICBtc2dTdWJzY3JpYmVycy5wdXNoKHN1YnNjcmliZXIpO1xuXG4gICAgcmV0dXJuIG5vdFlldFJlZ2lzdGVyZWQ7XG59XG5cblxuLyoqXG4gKiBGaW5kcyBzdWJzY3JpYmVyIGluZGV4IGluIHRoZSBsaXN0XG4gKlxuICogQHBhcmFtIHtBcnJheVtGdW5jdGlvbnxPYmplY3RdfSBsaXN0IGxpc3Qgb2Ygc3Vic2NyaWJlcnNcbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBzdWJzY3JpYmVyIHN1YnNjcmliZXIgZnVuY3Rpb24gb3Igb2JqZWN0IHdpdGggcHJvcGVydGllcyBgc3Vic2NyaWJlcmAgKGZ1bmN0aW9uKSBhbmQgYGNvbnRleHRgIChcInRoaXNcIiBvYmplY3QpXG4gKi9cbmZ1bmN0aW9uIF9pbmRleE9mU3Vic2NyaWJlcihsaXN0LCBzdWJzY3JpYmVyKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBfLmZpbmRJbmRleChsaXN0LCBmdW5jdGlvbihzdWJzY3Ipe1xuICAgICAgICByZXR1cm4gc3Vic2NyaWJlci5zdWJzY3JpYmVyID09IHN1YnNjci5zdWJzY3JpYmVyXG4gICAgICAgICAgICAgICAgJiYgc3Vic2NyaWJlci5jb250ZXh0ID09IHN1YnNjci5jb250ZXh0XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogU3Vic2NyaWJlcyB0byBtdWx0aXBsZSBtZXNzYWdlcyBwYXNzZWQgYXMgbWFwIHRvZ2V0aGVyIHdpdGggc3Vic2NyaWJlcnMuXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogbXlDb21wLmV2ZW50cy5vbk1lc3NhZ2VzKHtcbiAqICAgICAnbW91c2Vkb3duJzogb25Nb3VzZURvd24sXG4gKiAgICAgJ21vdXNldXAnOiBvbk1vdXNlVXBcbiAqIH0pO1xuICogZnVuY3Rpb24gb25Nb3VzZURvd24oZXZlbnRUeXBlLCBldmVudCkge31cbiAqIGZ1bmN0aW9uIG9uTW91c2VVcChldmVudFR5cGUsIGV2ZW50KSB7fVxuICogYGBgXG4gKiBSZXR1cm5zIG1hcCB3aXRoIHRoZSBzYW1lIGtleXMgKG1lc3NhZ2UgdHlwZXMpIGFuZCBib29sZWFuIHZhbHVlcyBpbmRpY2F0aW5nIHdoZXRoZXIgcGFydGljdWxhciBzdWJzY3JpYmVyIHdhcyBhZGRlZC5cbiAqIEl0IGlzIE5PVCBwb3NzaWJsZSB0byBhZGQgcGF0dGVybiBzdWJzY3JpYmVyIHVzaW5nIHRoaXMgbWV0aG9kLCBhcyBhbHRob3VnaCB5b3UgY2FuIHVzZSBSZWdFeHAgYXMgdGhlIGtleSwgSmF2YVNjcmlwdCB3aWxsIGF1dG9tYXRpY2FsbHkgY29udmVydCBpdCB0byBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtPYmplY3RbRnVuY3Rpb25dfSBtZXNzYWdlU3Vic2NyaWJlcnMgTWFwIG9mIG1lc3NhZ2Ugc3Vic2NyaWJlcnMgdG8gYmUgYWRkZWRcbiAqIEByZXR1cm4ge09iamVjdFtCb29sZWFuXX1cbiAqL1xuZnVuY3Rpb24gb25NZXNzYWdlcyhtZXNzYWdlU3Vic2NyaWJlcnMpIHtcbiAgICBjaGVjayhtZXNzYWdlU3Vic2NyaWJlcnMsIE1hdGNoLk9iamVjdEhhc2goTWF0Y2guT25lT2YoRnVuY3Rpb24sIHsgc3Vic2NyaWJlcjogRnVuY3Rpb24sIGNvbnRleHQ6IE1hdGNoLkFueSB9KSkpO1xuXG4gICAgdmFyIG5vdFlldFJlZ2lzdGVyZWRNYXAgPSBfLm1hcEtleXMobWVzc2FnZVN1YnNjcmliZXJzLCBmdW5jdGlvbihzdWJzY3JpYmVyLCBtZXNzYWdlcykge1xuICAgICAgICByZXR1cm4gdGhpcy5vbihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gbm90WWV0UmVnaXN0ZXJlZE1hcDtcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2QuXG4gKiBSZW1vdmVzIGEgc3Vic2NyaWJlciBmb3IgbWVzc2FnZShzKS4gUmVtb3ZlcyBhbGwgc3Vic2NyaWJlcnMgZm9yIHRoZSBtZXNzYWdlIGlmIHN1YnNjcmliZXIgaXNuJ3QgcGFzc2VkLlxuICogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1YnNjcmliZXIgd2FzIHJlZ2lzdGVyZWQuIE5vIGVycm9yIG9yIHdhcm5pbmcgaXMgdGhyb3duIG9yIGxvZ2dlZCBpZiB5b3UgcmVtb3ZlIHN1YnNjcmliZXIgdGhhdCB3YXMgbm90IHJlZ2lzdGVyZWQuXG4gKiBbQ29tcG9uZW50c10oLi4vY29tcG9uZW50cy9jX2NsYXNzLmpzLmh0bWwpIGFuZCBbZmFjZXRzXSguLi9jb21wb25lbnRzL2NfZmFjZXQuanMuaHRtbCkgY2hhbmdlIHRoaXMgbWV0aG9kIG5hbWUgdG8gYG9mZmAgd2hlbiB0aGV5IHByb3h5IGl0LlxuICogVXNhZ2U6XG4gKiBgYGBcbiAqIC8vIHVuc3Vic2NyaWJlcyBvbk1vdXNlVXBEb3duIGZyb20gdHdvIERPTSBldmVudHMuXG4gKiBteUNvbXAuZXZlbnRzLm9mZignbW91c2Vkb3duIG1vdXNldXAnLCBvbk1vdXNlVXBEb3duKTtcbiAqIGBgYFxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciBmb3IgYSBnaXZlbiBtZXNzYWdlIGlzIHJlbW92ZWQgYW5kIHRoZXJlIGlzIG5vIG1vcmUgc3Vic2NyaWJlcnMgZm9yIHRoaXMgbWVzc2FnZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xBcnJheVtTdHJpbmddfFJlZ0V4cH0gbWVzc2FnZXMgTWVzc2FnZSB0eXBlcyB0aGF0IGEgc3Vic2NyaWJlciBzaG91bGQgYmUgcmVtb3ZlZCBmb3IuXG4gKiAgSWYgc3RyaW5nIGlzIHBhc3NlZCwgaXQgY2FuIGJlIGEgc2lnbGUgbWVzc2FnZSBvciBtdWx0aXBsZSBtZXNzYWdlIHR5cGVzIHNlcGFyYXRlZCBieSB3aGl0ZXNwYWNlIHdpdGggb3B0aW9uYWwgY29tbWFzLlxuICogIElmIGFuIGFycmF5IG9mIHN0cmluZ3MgaXMgcGFzc2VkLCBlYWNoIHN0cmluZyBpcyBhIG1lc3NhZ2UgdHlwZSB0byByZW1vdmUgYSBzdWJzY3JpYmVyIGZvci5cbiAqICBJZiBhIFJlZ0V4cCBpcyBwYXNzZWQsIHRoZSBwYXR0ZXJuIHN1YnNjcmliZXIgd2lsbCBiZSByZW1vdmVkLlxuICogIFJlZ0V4cCBzdWJzY3JpYmVyIGRvZXMgTk9UIGNhdXNlIGFueSBzdWJzY3JpcHRpb24gdG8gTWVzc2FnZVNvdXJjZSwgaXQgb25seSBjYXB0dXJlcyBtZXNzYWdlcyB0aGF0IGFyZSBhbHJlYWR5IHN1YnNjcmliZWQgdG8gd2l0aCBwcmVjaXNlIG1lc3NhZ2UgdHlwZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdWJzY3JpYmVyIE1lc3NhZ2Ugc3Vic2NyaWJlciAtIE9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGxpc3Qgb2Ygc3Vic2NyaWJlcnMgZm9yIHRoZSBtZXNzYWdlKHMpLiBJZiBzdWJzY3JpYmVyIGlzIG5vdCBzdXBwbGllZCwgYWxsIHN1YnNjcmliZXJzIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoaXMgbWVzc2FnZShzKS5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRvZmYobWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICBjaGVjayhtZXNzYWdlcywgTWF0Y2guT25lT2YoU3RyaW5nLCBbU3RyaW5nXSwgUmVnRXhwKSk7XG4gICAgY2hlY2soc3Vic2NyaWJlciwgTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoRnVuY3Rpb24sIHtcbiAgICAgICAgc3Vic2NyaWJlcjogRnVuY3Rpb24sXG4gICAgICAgIGNvbnRleHQ6IE1hdGNoLkFueSxcbiAgICAgICAgb3B0aW9uczogTWF0Y2guT3B0aW9uYWwoT2JqZWN0KSxcbiAgICAgICAgLy8gX19tZXNzYWdlczogTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoU3RyaW5nLCBbU3RyaW5nXSwgUmVnRXhwKSlcbiAgICB9KSkpO1xuXG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb2ZmLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xufVxuXG5cbmZ1bmN0aW9uIF9NZXNzZW5nZXJfb2ZmKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9lYWNoTWVzc2FnZS5jYWxsKHRoaXMsICdfcmVtb3ZlU3Vic2NyaWJlcicsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIEl0IGlzIGNhbGxlZCBieSBbb2ZmXSgjTWVzc2VuZ2VyJG9mZikgdG8gcmVtb3ZlIHN1YnNjcmliZXIgZm9yIG9uZSBtZXNzYWdlIHR5cGUuXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGlzIHN1YnNjcmliZXIgd2FzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHlwZSBvZiBtZXNzYWdlLlxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciBmb3IgYSBnaXZlbiBtZXNzYWdlIGlzIHJlbW92ZWQgYW5kIHRoZXJlIGlzIG5vIG1vcmUgc3Vic2NyaWJlcnMgZm9yIHRoaXMgbWVzc2FnZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN1YnNjcmliZXJzSGFzaCBUaGUgbWFwIG9mIHN1YnNjcmliZXJzIGRldGVybWluZWQgYnkgW29mZl0oI01lc3NlbmdlciRvZmYpIGJhc2VkIG9uIG1lc3NhZ2UgdHlwZSwgY2FuIGJlIGB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzYCBvciBgdGhpcy5fbWVzc2FnZVN1YnNjcmliZXJzYFxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgTWVzc2FnZSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdWJzY3JpYmVyIFN1YnNjcmliZXIgZnVuY3Rpb24gdG8gYmUgcmVtb3ZlZFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gX3JlbW92ZVN1YnNjcmliZXIoc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlLCBzdWJzY3JpYmVyKSB7XG4gICAgdmFyIG1zZ1N1YnNjcmliZXJzID0gc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdO1xuICAgIGlmICghIG1zZ1N1YnNjcmliZXJzIHx8ICEgbXNnU3Vic2NyaWJlcnMubGVuZ3RoKVxuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdGhpbmcgcmVtb3ZlZFxuXG4gICAgaWYgKHN1YnNjcmliZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdWJzY3JpYmVyID09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICBzdWJzY3JpYmVyID0geyBzdWJzY3JpYmVyOiBzdWJzY3JpYmVyLCBjb250ZXh0OiB0aGlzLl9ob3N0T2JqZWN0IH07XG5cbiAgICAgICAgdmFyIHN1YnNjcmliZXJJbmRleCA9IF9pbmRleE9mU3Vic2NyaWJlci5jYWxsKHRoaXMsIG1zZ1N1YnNjcmliZXJzLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgaWYgKHN1YnNjcmliZXJJbmRleCA9PSAtMSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gbm90aGluZyByZW1vdmVkXG4gICAgICAgIG1zZ1N1YnNjcmliZXJzLnNwbGljZShzdWJzY3JpYmVySW5kZXgsIDEpO1xuICAgICAgICBpZiAoISBtc2dTdWJzY3JpYmVycy5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpO1xuXG4gICAgfSBlbHNlXG4gICAgICAgIHRoaXMuX3JlbW92ZUFsbFN1YnNjcmliZXJzKHN1YnNjcmliZXJzSGFzaCwgbWVzc2FnZSk7XG5cbiAgICByZXR1cm4gdHJ1ZTsgLy8gc3Vic2NyaWJlcihzKSByZW1vdmVkXG59XG5cblxuLyoqXG4gKiBcIlByaXZhdGVcIiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBJdCBpcyBjYWxsZWQgYnkgW19yZW1vdmVTdWJzY3JpYmVyXSgjX3JlbW92ZVN1YnNjcmliZXIpIHRvIHJlbW92ZSBhbGwgc3Vic2NyaWJlcnMgZm9yIG9uZSBtZXNzYWdlIHR5cGUuXG4gKiBJZiBtZXNzZW5nZXIgaGFzIFtNZXNzYWdlU291cmNlXSguL21fc291cmNlLmpzLmh0bWwpIGF0dGFjaGVkIHRvIGl0LCBNZXNzYWdlU291cmNlIHdpbGwgYmUgbm90aWZpZWQgdGhhdCBhbGwgbWVzc2FnZSBzdWJzY3JpYmVycyB3ZXJlIHJlbW92ZWQgc28gaXQgY2FuIHVuc3Vic2NyaWJlIGZyb20gdGhlIHNvdXJjZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN1YnNjcmliZXJzSGFzaCBUaGUgbWFwIG9mIHN1YnNjcmliZXJzIGRldGVybWluZWQgYnkgW29mZl0oI01lc3NlbmdlciRvZmYpIGJhc2VkIG9uIG1lc3NhZ2UgdHlwZSwgY2FuIGJlIGB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzYCBvciBgdGhpcy5fbWVzc2FnZVN1YnNjcmliZXJzYFxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgTWVzc2FnZSB0eXBlXG4gKi9cbmZ1bmN0aW9uIF9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpIHtcbiAgICBkZWxldGUgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdO1xuICAgIGlmICh0aGlzLl9tZXNzYWdlU291cmNlICYmIHR5cGVvZiBtZXNzYWdlID09ICdzdHJpbmcnKVxuICAgICAgICB0aGlzLl9tZXNzYWdlU291cmNlLm9uU3Vic2NyaWJlclJlbW92ZWQobWVzc2FnZSk7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogVW5zdWJzY3JpYmVzIGZyb20gbXVsdGlwbGUgbWVzc2FnZXMgcGFzc2VkIGFzIG1hcCB0b2dldGhlciB3aXRoIHN1YnNjcmliZXJzLlxuICogUmV0dXJucyBtYXAgd2l0aCB0aGUgc2FtZSBrZXlzIChtZXNzYWdlIHR5cGVzKSBhbmQgYm9vbGVhbiB2YWx1ZXMgaW5kaWNhdGluZyB3aGV0aGVyIHBhcnRpY3VsYXIgc3Vic2NyaWJlciB3YXMgcmVtb3ZlZC5cbiAqIElmIGEgc3Vic2NyaWJlciBmb3Igb25lIG9mIHRoZSBtZXNzYWdlcyBpcyBub3Qgc3VwcGxpZWQsIGFsbCBzdWJzY3JpYmVycyBmb3IgdGhpcyBtZXNzYWdlIHdpbGwgYmUgcmVtb3ZlZC5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiBteUNvbXAuZXZlbnRzLm9mZk1lc3NhZ2VzKHtcbiAqICAgICAnbW91c2Vkb3duJzogb25Nb3VzZURvd24sXG4gKiAgICAgJ21vdXNldXAnOiBvbk1vdXNlVXAsXG4gKiAgICAgJ2NsaWNrJzogdW5kZWZpbmVkIC8vIGFsbCBzdWJzY3JpYmVycyB0byB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSByZW1vdmVkXG4gKiB9KTtcbiAqIGBgYFxuICogSXQgaXMgTk9UIHBvc3NpYmxlIHRvIHJlbW92ZSBwYXR0ZXJuIHN1YnNjcmliZXIocykgdXNpbmcgdGhpcyBtZXRob2QsIGFzIGFsdGhvdWdoIHlvdSBjYW4gdXNlIFJlZ0V4cCBhcyB0aGUga2V5LCBKYXZhU2NyaXB0IHdpbGwgYXV0b21hdGljYWxseSBjb252ZXJ0IGl0IHRvIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdFtGdW5jdGlvbl19IG1lc3NhZ2VTdWJzY3JpYmVycyBNYXAgb2YgbWVzc2FnZSBzdWJzY3JpYmVycyB0byBiZSByZW1vdmVkXG4gKiBAcmV0dXJuIHtPYmplY3RbQm9vbGVhbl19XG4gKi9cbmZ1bmN0aW9uIG9mZk1lc3NhZ2VzKG1lc3NhZ2VTdWJzY3JpYmVycykge1xuICAgIGNoZWNrKG1lc3NhZ2VTdWJzY3JpYmVycywgTWF0Y2guT2JqZWN0SGFzaChNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihGdW5jdGlvbiwgeyBzdWJzY3JpYmVyOiBGdW5jdGlvbiwgY29udGV4dDogTWF0Y2guQW55IH0pKSkpO1xuXG4gICAgdmFyIHN1YnNjcmliZXJSZW1vdmVkTWFwID0gXy5tYXBLZXlzKG1lc3NhZ2VTdWJzY3JpYmVycywgZnVuY3Rpb24oc3Vic2NyaWJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub2ZmKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiBzdWJzY3JpYmVyUmVtb3ZlZE1hcDtcbn1cblxuXG4vKipcbiAqIFVuc3Vic2NyaWJlcyBhbGwgc3Vic2NyaWJlcnNcbiAqL1xuZnVuY3Rpb24gTWVzc2VuZ2VyJG9mZkFsbCgpIHtcbiAgICBfb2ZmQWxsU3Vic2NyaWJlcnMuY2FsbCh0aGlzLCB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzKTtcbiAgICBfb2ZmQWxsU3Vic2NyaWJlcnMuY2FsbCh0aGlzLCB0aGlzLl9tZXNzYWdlU3Vic2NyaWJlcnMpO1xufVxuXG5cbmZ1bmN0aW9uIF9vZmZBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gpIHtcbiAgICBfLmVhY2hLZXkoc3Vic2NyaWJlcnNIYXNoLCBmdW5jdGlvbihzdWJzY3JpYmVycywgbWVzc2FnZSkge1xuICAgICAgICB0aGlzLl9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbi8vIFRPRE8gLSBzZW5kIGV2ZW50IHRvIG1lc3NhZ2VTb3VyY2VcblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2QuXG4gKiBEaXNwYXRjaGVzIHRoZSBtZXNzYWdlIGNhbGxpbmcgYWxsIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgbWVzc2FnZSBhbmQsIGlmIHRoZSBtZXNzYWdlIGlzIGEgc3RyaW5nLCBjYWxsaW5nIGFsbCBwYXR0ZXJuIHN1YnNjcmliZXJzIHdoZW4gbWVzc2FnZSBtYXRjaGVzIHRoZSBwYXR0ZXJuLlxuICogRWFjaCBzdWJzY3JpYmVyIGlzIHBhc3NlZCB0aGUgc2FtZSBwYXJhbWV0ZXJzIHRoYXQgYXJlIHBhc3NlZCB0byB0aGVpcyBtZXRob2QuXG4gKiBUaGUgY29udGV4dCBvZiB0aGUgc3Vic2NyaWJlciBlbnZvY2F0aW9uIGlzIHNldCB0byB0aGUgaG9zdCBvYmplY3QgKGB0aGlzLl9ob3N0T2JqZWN0YCkgdGhhdCB3YXMgcGFzc2VkIHRvIHRoZSBtZXNzZW5nZXIgY29uc3RydWN0b3IuXG4gKiBTdWJzY3JpYmVycyBhcmUgY2FsbGVkIGluIHRoZSBuZXh0IHRpY2sgKFwiYXN5bmNocm9ub3VzbHlcIikgYXBhcnQgZnJvbSB0aG9zZSB0aGF0IHdlcmUgc3Vic2NyaWJlZCB3aXRoIGBvblN5bmNgIChvciB0aGF0IGhhdmUgYG9wdGlvbnMuc3luYyA9PSB0cnVlYCkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgZGlzcGF0Y2hlZFxuICogIElmIHRoZSBtZXNzYWdlIGlzIGEgc3RyaW5nLCB0aGUgc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIGV4YWN0bHkgdGhpcyBtZXNzYWdlIHdpbGwgYmUgY2FsbGVkIGFuZCBhbHNvIHBhdHRlcm4gc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBwYXR0ZXJuIHRoYXQgbWF0Y2hlcyB0aGUgZGlzcGF0Y2hlZCBtZXNzYWdlLlxuICogIElmIHRoZSBtZXNzYWdlIGlzIFJlZ0V4cCwgb25seSB0aGUgc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIGV4YWN0bHkgdGhpcyBwYXR0ZXJuIHdpbGwgYmUgY2FsbGVkLlxuICogQHBhcmFtIHtBbnl9IGRhdGEgZGF0YSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBzdWJzY3JpYmVyIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBNZXNzZW5nZXIgZG9lcyBub3QgbW9kaWZ5IHRoaXMgZGF0YSBpbiBhbnkgd2F5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdG8gcGFzcyB0byBzdWJzY3JpYmVyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IF9zeW5jaHJvbm91cyBpZiB0cnVlIHBhc3NlZCwgc3Vic2NyaWJlcnMgd2lsbCBiZSBlbnZva2VkIHN5bmNocm9ub3VzbHkgYXBhcnQgZnJvbSB0aG9zZSB0aGF0IGhhdmUgYG9wdGlvbnMuc3luYyA9PSBmYWxzZWAuIFRoaXMgcGFyYW1ldGVyIHNob3VsZCBub3QgYmUgdXNlZCwgaW5zdGVhZCBwb3N0TWVzc2FnZVN5bmMgc2hvdWxkIGJlIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBfc3luY2hyb25vdXMpIHtcbiAgICBjaGVjayhtZXNzYWdlLCBNYXRjaC5PbmVPZihTdHJpbmcsIFJlZ0V4cCkpO1xuICAgIGNoZWNrKGNhbGxiYWNrLCBNYXRjaC5PcHRpb25hbChGdW5jdGlvbikpO1xuXG4gICAgdmFyIHN1YnNjcmliZXJzSGFzaCA9IHRoaXMuX2Nob29zZVN1YnNjcmliZXJzSGFzaChtZXNzYWdlKTtcbiAgICB2YXIgbXNnU3Vic2NyaWJlcnMgPSBzdWJzY3JpYmVyc0hhc2hbbWVzc2FnZV07XG5cbiAgICB0aGlzLl9jYWxsU3Vic2NyaWJlcnMobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIG1zZ1N1YnNjcmliZXJzLCBfc3luY2hyb25vdXMpO1xuXG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09ICdzdHJpbmcnKVxuICAgICAgICB0aGlzLl9jYWxsUGF0dGVyblN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBtc2dTdWJzY3JpYmVycywgX3N5bmNocm9ub3VzKTtcbn1cblxuXG4vKipcbiAqIFNhbWUgYXMgcG9zdE1lc3NhZ2UgYXBhcnQgZnJvbSBlbnZva2luZyBzdWJzY3JpYmVycyBzeW5jaHJvbm91c2x5LCBhcGFydCBmcm9tIHRob3NlIHN1YnNjcmliZWQgd2l0aCBgb25Bc3luY2AgKG9yIHdpdGggYG9wdGlvbnMuc3luYyA9PSBmYWxzZWApLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbWVzc2FnZVxuICogQHBhcmFtIHtBbnl9IGRhdGFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKi9cbmZ1bmN0aW9uIHBvc3RNZXNzYWdlU3luYyhtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaykge1xuICAgIHRoaXMucG9zdE1lc3NhZ2UobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIHRydWUpO1xufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogRW52b2tlcyBwYXR0ZXJuIHN1YnNjcmliZXJzIHdpdGggdGhlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIHRoZSBtZXNzYWdlLlxuICogVGhlIG1ldGhvZCBpcyBjYWxsZWQgYnkgW3Bvc3RNZXNzYWdlXSgjcG9zdE1lc3NhZ2UpIC0gc2VlIG1vcmUgaW5mb3JtYXRpb24gdGhlcmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgZGlzcGF0Y2hlZC4gUGF0dGVybiBzdWJzY3JpYmVycyByZWdpc3RlcmVkIHdpdGggdGhlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIHRoZSBkaXNwYXRjaGVkIG1lc3NhZ2Ugd2lsbCBiZSBjYWxsZWQuXG4gKiBAcGFyYW0ge0FueX0gZGF0YSBkYXRhIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHN1YnNjcmliZXIgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIuIE1lc3NlbmdlciBkb2VzIG5vdCBtb2RpZnkgdGhpcyBkYXRhIGluIGFueSB3YXkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBvcHRpb25hbCBjYWxsYmFjayB0byBwYXNzIHRvIHN1YnNjcmliZXJcbiAqIEBwYXJhbSB7QXJyYXlbRnVuY3Rpb258T2JqZWN0XX0gY2FsbGVkTXNnU3Vic2NyaWJlcnMgYXJyYXkgb2Ygc3Vic2NyaWJlcnMgYWxyZWFkeSBjYWxsZWQsIHRoZXkgd29uJ3QgYmUgY2FsbGVkIGFnYWluIGlmIHRoZXkgYXJlIGFtb25nIHBhdHRlcm4gc3Vic2NyaWJlcnMuXG4gKi9cbmZ1bmN0aW9uIF9jYWxsUGF0dGVyblN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBjYWxsZWRNc2dTdWJzY3JpYmVycywgX3N5bmNocm9ub3VzKSB7XG4gICAgXy5lYWNoS2V5KHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnMsXG4gICAgICAgIGZ1bmN0aW9uKHBhdHRlcm5TdWJzY3JpYmVycykge1xuICAgICAgICAgICAgdmFyIHBhdHRlcm4gPSBwYXR0ZXJuU3Vic2NyaWJlcnMucGF0dGVybjtcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuLnRlc3QobWVzc2FnZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2FsbGVkTXNnU3Vic2NyaWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhdHRlcm5TdWJzY3JpYmVycyA9IHBhdHRlcm5TdWJzY3JpYmVycy5maWx0ZXIoZnVuY3Rpb24oc3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gX2luZGV4T2ZTdWJzY3JpYmVyLmNhbGwodGhpcywgY2FsbGVkTXNnU3Vic2NyaWJlcnMsIHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4ID09IC0xO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FsbFN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBwYXR0ZXJuU3Vic2NyaWJlcnMsIF9zeW5jaHJvbm91cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAsIHRoaXMpO1xufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogRW52b2tlcyBzdWJzY3JpYmVycyBmcm9tIHRoZSBwYXNzZWQgbGlzdC5cbiAqIFRoZSBtZXRob2QgaXMgY2FsbGVkIGJ5IFtwb3N0TWVzc2FnZV0oI3Bvc3RNZXNzYWdlKSBhbmQgW19jYWxsUGF0dGVyblN1YnNjcmliZXJzXSgjX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnMpLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIGRpc3BhdGNoZWQsIHBhc3NlZCB0byBzdWJzY3JpYmVycyBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyLlxuICogQHBhcmFtIHtBbnl9IGRhdGEgZGF0YSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBzdWJzY3JpYmVyIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBNZXNzZW5nZXIgZG9lcyBub3QgbW9kaWZ5IHRoaXMgZGF0YSBpbiBhbnkgd2F5LlxuICogQHBhcmFtIHtBcnJheVtGdW5jdGlvbnxPYmplY3RdfSBtc2dTdWJzY3JpYmVycyB0aGUgYXJyYXkgb2YgbWVzc2FnZSBzdWJzY3JpYmVycyB0byBiZSBjYWxsZWQuIEVhY2ggc3Vic2NyaWJlciBpcyBjYWxsZWQgd2l0aCB0aGUgaG9zdCBvYmplY3QgKHNlZSBNZXNzZW5nZXIgY29uc3RydWN0b3IpIGFzIHRoZSBjb250ZXh0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdG8gcGFzcyB0byBzdWJzY3JpYmVyXG4gKi9cbmZ1bmN0aW9uIF9jYWxsU3Vic2NyaWJlcnMobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIG1zZ1N1YnNjcmliZXJzLCBfc3luY2hyb25vdXMpIHtcbiAgICBpZiAobXNnU3Vic2NyaWJlcnMgJiYgbXNnU3Vic2NyaWJlcnMubGVuZ3RoKSB7XG4gICAgICAgIC8vIGNsb25pbmcgaXMgbmVjZXNzYXJ5IGFzIHNvbWUgb2YgdGhlIHN1YnNjcmliZXJzXG4gICAgICAgIC8vIGNhbiBiZSB1bnN1YnNjcmliZWQgZHVyaW5nIHRoZSBkaXNwYXRjaFxuICAgICAgICAvLyBzbyB0aGlzIGFycmF5IHdvdWxkIGNoYW5nZSBpbiB0aGUgcHJvY2Vzc1xuICAgICAgICBtc2dTdWJzY3JpYmVycyA9IG1zZ1N1YnNjcmliZXJzLnNsaWNlKCk7XG5cbiAgICAgICAgbXNnU3Vic2NyaWJlcnMuZm9yRWFjaChmdW5jdGlvbihzdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWxsU3Vic2NyaWJlcihzdWJzY3JpYmVyLCBtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgX3N5bmNocm9ub3VzKTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9jYWxsU3Vic2NyaWJlcihzdWJzY3JpYmVyLCBtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgX3N5bmNocm9ub3VzKSB7XG4gICAgdmFyIHN5bmNTdWJzY3JpYmVyID0gc3Vic2NyaWJlci5vcHRpb25zICYmIHN1YnNjcmliZXIub3B0aW9ucy5zeW5jXG4gICAgICAgICwgc3luY2hybyA9IChfc3luY2hyb25vdXMgJiYgc3luY1N1YnNjcmliZXIgIT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgfHwgc3luY1N1YnNjcmliZXI7XG5cbiAgICB2YXIgZGlzcGF0Y2hUaW1lcyA9IHN1YnNjcmliZXIub3B0aW9ucyAmJiBzdWJzY3JpYmVyLm9wdGlvbnMuZGlzcGF0Y2hUaW1lcztcbiAgICBpZiAoZGlzcGF0Y2hUaW1lcykge1xuICAgICAgICBpZiAoZGlzcGF0Y2hUaW1lcyA8PSAxKSB7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZXMgPSBzdWJzY3JpYmVyLl9fbWVzc2FnZXM7XG4gICAgICAgICAgICB0aGlzLm9mZihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlzcGF0Y2hUaW1lcyA+IDEpXG4gICAgICAgICAgICBzdWJzY3JpYmVyLm9wdGlvbnMuZGlzcGF0Y2hUaW1lcy0tO1xuICAgIH1cblxuICAgIGlmIChzeW5jaHJvKVxuICAgICAgICBzdWJzY3JpYmVyLnN1YnNjcmliZXIuY2FsbChzdWJzY3JpYmVyLmNvbnRleHQsIG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrKTtcbiAgICBlbHNlXG4gICAgICAgIF8uZGVmZXJNZXRob2Qoc3Vic2NyaWJlci5zdWJzY3JpYmVyLCAnY2FsbCcsIHN1YnNjcmliZXIuY29udGV4dCwgbWVzc2FnZSwgZGF0YSwgY2FsbGJhY2spO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgdGhlIGFycmF5IG9mIHN1YnNjcmliZXJzIHRoYXQgd291bGQgYmUgY2FsbGVkIGlmIHRoZSBtZXNzYWdlIHdlcmUgZGlzcGF0Y2hlZC5cbiAqIElmIGBpbmNsdWRlUGF0dGVyblN1YnNjcmliZXJzID09PSBmYWxzZWAsIHBhdHRlcm4gc3Vic2NyaWJlcnMgd2l0aCBtYXRjaGluZyBwYXR0ZXJzIHdpbGwgbm90IGJlIGluY2x1ZGVkIChieSBkZWZhdWx0IHRoZXkgYXJlIGluY2x1ZGVkKS5cbiAqIElmIHRoZXJlIGFyZSBubyBzdWJzY3JpYmVycyB0byB0aGUgbWVzc2FnZSwgYHVuZGVmaW5lZGAgd2lsbCBiZSByZXR1cm5lZCwgbm90IGFuIGVtcHR5IGFycmF5LCBzbyBpdCBpcyBzYWZlIHRvIHVzZSB0aGUgcmVzdWx0IGluIGJvb2xlYW4gdGVzdHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBtZXNzYWdlIE1lc3NhZ2UgdG8gZ2V0IHN1YnNjcmliZXJzIGZvci5cbiAqICBJZiB0aGUgbWVzc2FnZSBpcyBSZWdFeHAsIG9ubHkgcGF0dGVybiBzdWJzY3JpYmVycyByZWdpc3RlcmVkIHdpdGggZXhhY3RseSB0aGlzIHBhdHRlcm4gd2lsbCBiZSByZXR1cm5lZC5cbiAqICBJZiB0aGUgbWVzc2FnZSBpcyBTdHJpbmcsIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgc3RyaW5nIG1lc3NhZ2VzIGFuZCBwYXR0ZXJuIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCBtYXRjaGluZyBwYXR0ZXJuIHdpbGwgYmUgcmV0dXJuZWQgKHVubGVzcyB0aGUgc2Vjb25kIHBhcmFtZXRlciBpcyBmYWxzZSkuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGVQYXR0ZXJuU3Vic2NyaWJlcnMgT3B0aW9uYWwgZmFsc2UgdG8gcHJldmVudCBpbmNsdXNpb24gb2YgcGF0dGVyIHN1YnNjcmliZXJzLCBieSBkZWZhdWx0IHRoZXkgYXJlIGluY2x1ZGVkLlxuICogQHJldHVybiB7QXJyYXl8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBnZXRTdWJzY3JpYmVycyhtZXNzYWdlLCBpbmNsdWRlUGF0dGVyblN1YnNjcmliZXJzKSB7XG4gICAgY2hlY2sobWVzc2FnZSwgTWF0Y2guT25lT2YoU3RyaW5nLCBSZWdFeHApKTtcblxuICAgIHZhciBzdWJzY3JpYmVyc0hhc2ggPSB0aGlzLl9jaG9vc2VTdWJzY3JpYmVyc0hhc2gobWVzc2FnZSk7XG4gICAgdmFyIG1zZ1N1YnNjcmliZXJzID0gc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBbXS5jb25jYXQoc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogW107XG5cbiAgICAvLyBwYXR0ZXJuIHN1YnNjcmliZXJzIGFyZSBpbmN1ZGVkIGJ5IGRlZmF1bHRcbiAgICBpZiAoaW5jbHVkZVBhdHRlcm5TdWJzY3JpYmVycyAhPT0gZmFsc2UgJiYgdHlwZW9mIG1lc3NhZ2UgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgXy5lYWNoS2V5KHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnMsXG4gICAgICAgICAgICBmdW5jdGlvbihwYXR0ZXJuU3Vic2NyaWJlcnMpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGF0dGVybiA9IHBhdHRlcm5TdWJzY3JpYmVycy5wYXR0ZXJuO1xuICAgICAgICAgICAgICAgIGlmIChwYXR0ZXJuU3Vic2NyaWJlcnMgJiYgcGF0dGVyblN1YnNjcmliZXJzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgcGF0dGVybi50ZXN0KG1lc3NhZ2UpKVxuICAgICAgICAgICAgICAgICAgICBfLmFwcGVuZEFycmF5KG1zZ1N1YnNjcmliZXJzLCBwYXR0ZXJuU3Vic2NyaWJlcnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8vIHJldHVybiB1bmRlZmluZWQgaWYgdGhlcmUgYXJlIG5vIHN1YnNjcmliZXJzXG4gICAgcmV0dXJuIG1zZ1N1YnNjcmliZXJzLmxlbmd0aFxuICAgICAgICAgICAgICAgID8gbXNnU3Vic2NyaWJlcnNcbiAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgdGhlIG1hcCBvZiBzdWJzY3JpYmVycyBmb3IgYSBnaXZlbiBtZXNzYWdlIHR5cGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbWVzc2FnZSBNZXNzYWdlIHRvIGNob29zZSB0aGUgbWFwIG9mIHN1YnNjcmliZXJzIGZvclxuICogQHJldHVybiB7T2JqZWN0W0Z1bmN0aW9uXX1cbiAqL1xuZnVuY3Rpb24gX2Nob29zZVN1YnNjcmliZXJzSGFzaChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIG1lc3NhZ2UgaW5zdGFuY2VvZiBSZWdFeHBcbiAgICAgICAgICAgICAgICA/IHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnNcbiAgICAgICAgICAgICAgICA6IHRoaXMuX21lc3NhZ2VTdWJzY3JpYmVycztcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgZm9yIHRoZSBtZXNzZW5nZXIgYWxzbyBzZXR0aW5nIHRoZSByZWZlcmVuY2UgdG8gdGhlIG1lc3NlbmdlciBpbiB0aGUgTWVzc2FnZVNvdXJjZS5cbiAqIE1lc3NhZ2VTb3VyY2UgY2FuIGJlIHBhc3NlZCB0byBtZXNzYWdlIGNvbnN0cnVjdG9yOyB0aGlzIG1ldGhvZCBhbGxvd3MgdG8gc2V0IGl0IGF0IGEgbGF0ZXIgdGltZS4gRm9yIGV4YW1wbGUsIHRoZSBzdWJjbGFzc2VzIG9mIFtDb21wb25lbnRGYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0LmpzLmh0bWwpIHVzZSB0aGlzIG1ldGhvZCB0byBzZXQgZGlmZmVyZW50IE1lc3NhZ2VTb3VyY2UnZXMgaW4gdGhlIG1lc3NlbmdlciB0aGF0IGlzIGNyZWF0ZWQgYnkgQ29tcG9uZW50RmFjZXQuXG4gKiBDdXJyZW50bHkgdGhlIG1ldGhvZCBpcyBpbXBsZW1lbnRlZCBpbiBzdWNoIHdheSB0aGF0IGl0IGNhbiBiZSBjYWxsZWQgb25seSBvbmNlIC0gTWVzc2FnZVNvdXJjZSBjYW5ub3QgYmUgY2hhbmdlZCBhZnRlciB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuXG4gKlxuICogQHBhcmFtIHtNZXNzYWdlU291cmNlfSBtZXNzYWdlU291cmNlIGFuIGluc3RhbmNlIG9mIE1lc3NhZ2VTb3VyY2UgY2xhc3MgdG8gYXR0YWNoIHRvIHRoaXMgbWVzc2VuZ2VyIChhbmQgdG8gaGF2ZSB0aGlzIG1lc3NlbmdlciBhdHRhY2hlZCB0byBpdCB0b28pXG4gKi9cbmZ1bmN0aW9uIF9zZXRNZXNzYWdlU291cmNlKG1lc3NhZ2VTb3VyY2UpIHtcbiAgICBjaGVjayhtZXNzYWdlU291cmNlLCBNZXNzYWdlU291cmNlKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19tZXNzYWdlU291cmNlJywgbWVzc2FnZVNvdXJjZSk7XG4gICAgbWVzc2FnZVNvdXJjZS5tZXNzZW5nZXIgPSB0aGlzO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBtZXNzZW5nZXIgTWVzc2FnZVNvdXJjZVxuICpcbiAqIEByZXR1cm4ge01lc3NhZ2VTb3VyY2V9XG4gKi9cbmZ1bmN0aW9uIGdldE1lc3NhZ2VTb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX21lc3NhZ2VTb3VyY2Vcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1lc3NlbmdlckFQSTtcblxuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuTWVzc2VuZ2VyQVBJYFxuICogQmFzZSBjbGFzcywgc3ViY2xhc3NlcyBvZiB3aGljaCBjYW4gc3VwcGxlbWVudCB0aGUgZnVuY3Rpb25hbGl0eSBvZiBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBieSBpbXBsZW1lbnRpbmcgdGhyZWUgbWV0aG9kczpcbiAqXG4gKiAtIGB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2VgIHRvIHRyYW5zbGF0ZSBzb3VyY2UgbWVzc2FnZXMgKHJlY2lldmVkIGZyb20gZXh0ZXJuYWwgc291cmNlIHZpYSBgTWVzc2FnZVNPdXJjZWApIHRvIGludGVybmFsIG1lc3NhZ2VzICh0aGF0IGFyZSBkaXNwYXRjaGVkIG9uIE1lc3NlbmdlciksIGFsbG93aW5nIHRvIG1ha2UgaW50ZXJuYWwgbWVzc2FnZXMgbW9yZSBkZXRhaWxlZCB0aGFuIHNvdXJjZSBtZXNzYWdlcy4gRm9yIGV4YW1wbGUsIFtEYXRhIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL0RhdGEuanMuaHRtbCkgdXNlcyBbRGF0YU1zZ0FQSV0oLi4vY29tcG9uZW50cy9tc2dfYXBpL2RhdGEuanMuaHRtbCkgdG8gZGVmaW5lIHNldmVyYWwgaW50ZXJuYWwgbWVzc2FnZXMgcmVsYXRlZCB0byB0aGUgY2hhbmdlIG9mIHN0YXRlIGluIGNvbnRlbnRlZGl0YWJsZSBET00gZWxlbWVudC5cbiAqIC0gYGNyZWF0ZUludGVybmFsRGF0YWAgdG8gbW9kaWZ5IG1lc3NhZ2UgZGF0YSByZWNlaXZlZCBmcm9tIHNvdXJjZSB0byBzb21lIG1vcmUgbWVhbmluZ2Z1bCBvciBtb3JlIGRldGFpbGVkIG1lc3NhZ2UgZGF0YSB0aGF0IHdpbGwgYmUgZGlzcGF0Y2hlZCBvbiBNZXNzZW5nZXIuIEZvciBleGFtcGxlLCBbRGF0YSBmYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0cy9EYXRhLmpzLmh0bWwpIHVzZXMgW0RhdGFNc2dBUEldKC4uL2NvbXBvbmVudHMvbXNnX2FwaS9kYXRhLmpzLmh0bWwpIChzdWJjbGFzcyBvZiBNZXNzZW5nZXJBUEkpIHRvIHRyYW5zbGF0ZSBET00gbWVzc2FnZXMgdG8gZGF0YSBjaGFuZ2UgbWVzc2FnZXMuXG4gKiAtIGBmaWx0ZXJTb3VyY2VNZXNzYWdlYCB0byBlbmFibGUvZGlzYWJsZSBtZXNzYWdlIGRpc3BhdGNoIGJhc2VkIG9uIHNvbWUgY29uZGl0aW9ucyBpbiBkYXRhLlxuICpcbiAqIElmIGBNZXNzYWdlU291cmNlYCBjb25zdHJ1Y3RvciBpcyBub3QgcGFzc2VkIGFuIGluc3RhbmNlIG9mIHNvbWUgc3ViY2xhc3Mgb2YgYE1lc3NlbmdlckFQSWAsIGl0IGF1dG9tYXRpY2FsbHkgY3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBNZXNzZW5nZXJBUEkgdGhhdCBkZWZpbmVzIGFsbCAzIG9mIHRob3NlIG1ldGhvZHMgaW4gYSB0cml2aWFsIHdheS4gU2VlIHRoZXNlIG1ldGhvZHMgYmVsb3cgZm9yIHRoZWlyIHNpZ25hdHVyZXMuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAdGhpcyB7TWVzc2VuZ2VyQVBJfVxuICogQHJldHVybiB7TWVzc2VuZ2VyQVBJfVxuICovXG5mdW5jdGlvbiBNZXNzZW5nZXJBUEkoKSB7XG4gICAgaWYgKHRoaXMuaW5pdClcbiAgICAgICAgdGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiAjIyMjTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI2luaXQpIC0gaW5pdGlhbGl6ZXMgTWVzc2VuZ2VyQVBJXG4gKiAtIFthZGRJbnRlcm5hbE1lc3NhZ2VdKCNhZGRJbnRlcm5hbE1lc3NhZ2UpIC0gYWRkcyBpbnRlcm5hbCBtZXNzYWdlXG4gKiAtIFtyZW1vdmVJbnRlcm5hbE1lc3NhZ2VdKCNyZW1vdmVJbnRlcm5hbE1lc3NhZ2UpIC0gcmVtb3ZlcyBpbnRlcm5hbCBtZXNzYWdlXG4gKiAtIFtnZXRJbnRlcm5hbE1lc3NhZ2VzXSgjZ2V0SW50ZXJuYWxNZXNzYWdlcykgLSByZXR1cm5zIHRoZSBsaXN0IG9mIGludGVybmFsIG1lc3NhZ2VzIGZvciBnaXZlbiBzb3VyY2UgbWVzc2FnZVxuICpcbiAqIFRoZXNlIG1ldGhvZHMgc2hvdWxkIGJlIHJlZGVmaW5lZCBieSBzdWJjbGFzczpcbiAqXG4gKiAtIFt0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2VdKCN0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UpIC0gY29udmVydHMgaW50ZXJuYWwgbWVzc2FnZSB0eXBlIHRvIHNvdXJjZSAoZXh0ZXJuYWwpIG1lc3NhZ2UgdHlwZVxuICogLSBbY3JlYXRlSW50ZXJuYWxEYXRhXSgjY3JlYXRlSW50ZXJuYWxEYXRhKSAtIGNvbnZlcnRzIHNvdXJjZSBtZXNzYWdlIGRhdGEgcmVjZWl2ZWQgdmlhIE1lc3NhZ2VTb3VyY2UgdG8gaW50ZXJuYWwgbWVzc2FnZSBkYXRhXG4gKiAtIFtmaWx0ZXJTb3VyY2VNZXNzYWdlXSgjZmlsdGVyU291cmNlTWVzc2FnZSkgLSBmaWx0ZXJzIHNvdXJjZSBtZXNzYWdlIGJhc2VkIG9uIHRoZSBkYXRhIG9mIHRoZSBtZXNzYWdlIGFuZCB0aGUgY29ycmVzcG9uZGluZyBpbnRlcm5hbCBtZXNzYWdlIHRoYXQgaXMgYWJvdXQgdG8gYmUgc2VudCBvbiBNZXNzZW5nZXJcbiAqL1xuXy5leHRlbmRQcm90byhNZXNzZW5nZXJBUEksIHtcbiAgICBpbml0OiBpbml0LFxuICAgIGRlc3Ryb3k6IE1lc3NlbmdlckFQSSRkZXN0cm95LFxuICAgIGFkZEludGVybmFsTWVzc2FnZTogYWRkSW50ZXJuYWxNZXNzYWdlLFxuICAgIHJlbW92ZUludGVybmFsTWVzc2FnZTogcmVtb3ZlSW50ZXJuYWxNZXNzYWdlLFxuICAgIGdldEludGVybmFsTWVzc2FnZXM6IGdldEludGVybmFsTWVzc2FnZXMsXG5cbiAgICAvLyBzaG91bGQgYmUgcmVkZWZpbmVkIGJ5IHN1YmNsYXNzXG4gICAgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlOiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UsXG4gICAgY3JlYXRlSW50ZXJuYWxEYXRhOiBjcmVhdGVJbnRlcm5hbERhdGEsXG4gICAgZmlsdGVyU291cmNlTWVzc2FnZTogZmlsdGVyU291cmNlTWVzc2FnZVxufSk7XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBDYWxsZWQgYnkgTWVzc2VuZ2VyQVBJIGNvbnN0cnVjdG9yLiBTdWJjbGFzc2VzIHRoYXQgcmUtaW1wbGVtZW50IGBpbml0YCBtZXRob2Qgc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgdXNpbmc6IGBNZXNzZW5nZXJBUEkucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKWBcbiAqL1xuZnVuY3Rpb24gaW5pdCgpIHtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfaW50ZXJuYWxNZXNzYWdlcycsIHt9KTtcbn1cblxuXG4vKipcbiAqIERlc3Ryb3lzIG1lc3NlbmdlciBBUElcbiAqL1xuZnVuY3Rpb24gTWVzc2VuZ2VyQVBJJGRlc3Ryb3koKSB7XG5cbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlckFQSSBpbnN0YW5jZSBtZXRob2RcbiAqIFRyYW5zbGF0ZXMgaW50ZXJuYWwgYG1lc3NhZ2VgIHRvIHNvdXJjZSBtZXNzYWdlLCBhZGRzIGludGVybmFsIGBtZXNzYWdlYCB0byB0aGUgbGlzdCwgbWFraW5nIHN1cmUgdGhlIHNhbWUgYG1lc3NhZ2VgIHdhc24ndCBwYXNzZWQgYmVmb3JlIChpdCB3b3VsZCBpbmRpY2F0ZSBNZXNzZW5nZXIgZXJyb3IpLlxuICogUmV0dXJucyBzb3VyY2UgbWVzc2FnZSBpZiBpdCBpcyB1c2VkIGZpcnN0IHRpbWUgKHNvIHRoYXQgYE1lc3NhZ2VTb3VyY2VgIHN1YmNyaWJlcyB0byB0aGlzIHNvdXJjZSBtZXNzYWdlKSBvciBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBpbnRlcm5hbCBtZXNzYWdlIHRvIGJlIHRyYW5zbGF0ZWQgYW5kIGFkZGVkXG4gKiBAcmV0dXJuIHtTdHJpbmd8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBhZGRJbnRlcm5hbE1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHZhciBpbnRlcm5hbE1zZ3NcbiAgICAgICAgLCBzb3VyY2VNZXNzYWdlID0gdGhpcy50cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSk7XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZU1lc3NhZ2UgPT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcblxuICAgIGlmICh0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzLmhhc093blByb3BlcnR5KHNvdXJjZU1lc3NhZ2UpKSB7XG4gICAgICAgIGludGVybmFsTXNncyA9IHRoaXMuX2ludGVybmFsTWVzc2FnZXNbc291cmNlTWVzc2FnZV07XG4gICAgICAgIGlmIChpbnRlcm5hbE1zZ3MuaW5kZXhPZihtZXNzYWdlKSA9PSAtMSlcbiAgICAgICAgICAgIGludGVybmFsTXNncy5wdXNoKG1lc3NhZ2UpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBsb2dnZXIud2FybignRHVwbGljYXRlIGFkZEludGVybmFsTWVzc2FnZSBjYWxsIGZvciBpbnRlcm5hbCBtZXNzYWdlICcgKyBtZXNzYWdlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpbnRlcm5hbE1zZ3MgPSB0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdID0gW107XG4gICAgICAgIGludGVybmFsTXNncy5wdXNoKG1lc3NhZ2UpO1xuICAgICAgICByZXR1cm4gc291cmNlTWVzc2FnZTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZW1vdmVzIGludGVybmFsIGBtZXNzYWdlYCBmcm9tIHRoZSBsaXN0IGNvbm5lY3RlZCB0byBjb3JyZXNwb25kaW5nIHNvdXJjZSBtZXNzYWdlIChgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlYCBpcyB1c2VkIGZvciB0cmFuc2xhdGlvbikuXG4gKiBSZXR1cm5zIHNvdXJjZSBtZXNzYWdlLCBpZiB0aGUgbGFzdCBpbnRlcm5hbCBtZXNzYWdlIHdhcyByZW1vdmVkIChzbyB0aGF0IGBNZXNzYWdlU291cmNlYCBjYW4gdW5zdWJzY3JpYmUgZnJvbSB0aGlzIHNvdXJjZSBtZXNzYWdlKSwgb3IgYHVuZGVmaW5lZGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgaW50ZXJuYWwgbWVzc2FnZSB0byBiZSB0cmFuc2xhdGVkIGFuZCByZW1vdmVkXG4gKiBAcmV0dXJuIHtTdHJpbmd8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiByZW1vdmVJbnRlcm5hbE1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHZhciBzb3VyY2VNZXNzYWdlID0gdGhpcy50cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSk7XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZU1lc3NhZ2UgPT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcblxuICAgIHZhciBpbnRlcm5hbE1zZ3MgPSB0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdO1xuXG4gICAgaWYgKGludGVybmFsTXNncyAmJiBpbnRlcm5hbE1zZ3MubGVuZ3RoKSB7XG4gICAgICAgIHZhciBtZXNzYWdlSW5kZXggPSBpbnRlcm5hbE1zZ3MuaW5kZXhPZihtZXNzYWdlKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBpbnRlcm5hbE1zZ3Muc3BsaWNlKG1lc3NhZ2VJbmRleCwgMSk7XG4gICAgICAgICAgICBpZiAoaW50ZXJuYWxNc2dzLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2ludGVybmFsTWVzc2FnZXNbc291cmNlTWVzc2FnZV07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZU1lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgdW5leHBlY3RlZE5vdGlmaWNhdGlvbldhcm5pbmcoKTtcbiAgICB9IGVsc2VcbiAgICAgICAgdW5leHBlY3RlZE5vdGlmaWNhdGlvbldhcm5pbmcoKTtcblxuXG4gICAgZnVuY3Rpb24gdW5leHBlY3RlZE5vdGlmaWNhdGlvbldhcm5pbmcoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdub3RpZmljYXRpb24gcmVjZWl2ZWQ6IHVuLXN1YnNjcmliZSBmcm9tIGludGVybmFsIG1lc3NhZ2UgJyArIG1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICsgJyB3aXRob3V0IHByZXZpb3VzIHN1YnNjcmlwdGlvbiBub3RpZmljYXRpb24nKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBpbnRlcm5hbCBtZXNzYWdlcyB0aGF0IHdlcmUgdHJhbnNsYXRlZCB0byBnaXZlbiBgc291cmNlTWVzc2FnZWAuXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGJ5IGBNZXNzYWdlU291cmNlYCB0byBkaXNwYXRjaCBzb3VyY2UgbWVzc2FnZSBvbiB0aGUgYE1lc2VuZ2VyYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc291cmNlTWVzc2FnZSBzb3VyY2UgbWVzc2FnZVxuICogQHJldHVybiB7QXJyYXlbU3RyaW5nXX1cbiAqL1xuZnVuY3Rpb24gZ2V0SW50ZXJuYWxNZXNzYWdlcyhzb3VyY2VNZXNzYWdlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2ludGVybmFsTWVzc2FnZXNbc291cmNlTWVzc2FnZV07XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBTdWJjbGFzc2VzIHNob3VsZCByZS1pbXBsZW1lbnQgdGhpcyBtZXRob2QgdG8gZGVmaW5lIHRoZSBydWxlIGZvciB0cmFuc2xhdGlvbiBvZiBpbnRlcm5hbCBgbWVzc2FnZWAgdG8gc291cmNlIG1lc3NhZ2UuIFRoaXMgY2xhc3Mgc2ltcGx5IHJldHVybnMgdGhlIHNhbWUgYG1lc3NhZ2VgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIG1lc3NhZ2UgdG8gYmUgdHJhbnNsYXRlZFxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlXG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBTdWJjbGFzc2VzIHNob3VsZCByZS1pbXBsZW1lbnQgdGhpcyBtZXRob2QgdG8gZGVmaW5lIHRoZSBydWxlIGZvciB0cmFuc2xhdGlvbiBvZiBzb3VyY2UgbWVzc2FnZSBkYXRhIHRvIGludGVybmFsIG1lc3NhZ2UgZGF0YS4gVGhpcyBjbGFzcyBzaW1wbHkgcmV0dXJucyB0aGUgc2FtZSBgc291cmNlRGF0YWAuXG4gKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluIFtkaXNwYXRjaE1lc3NhZ2VdKC4vbV9zb3VyY2UuanMuaHRtbCNkaXNwYXRjaE1lc3NhZ2UpIG1ldGhvZCBvZiBgTWVzc2FnZVNvdXJjZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNvdXJjZU1lc3NhZ2Ugc291cmNlIG1lc3NhZ2UsIGNhbiBiZSB1c2VkIGluIHRyYW5zbGF0aW9uIHJ1bGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIG1lc3NhZ2UsIGNhbiBiZSB1c2VkIGluIHRyYW5zbGF0aW9uIHJ1bGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2VEYXRhIGRhdGEgcmVjZWl2ZWQgZnJvbSBzb3VyY2UgdGhhdCBoYXMgdG8gYmUgdHJhbnNsYXRlZCB0byBkYXRhIHRoYXQgd2lsbCBiZSBzZW50IHRvIGludGVybmFsIE1lc3NlbmdlciBzdWJzY3JpYmVyXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUludGVybmFsRGF0YShzb3VyY2VNZXNzYWdlLCBtZXNzYWdlLCBzb3VyY2VEYXRhKSB7XG4gICAgcmV0dXJuIHNvdXJjZURhdGE7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBTdWJjbGFzc2VzIHNob3VsZCByZS1pbXBsZW1lbnQgdGhpcyBtZXRob2QgdG8gZGVmaW5lIHRoZSBkaXNwYXRjaCBmaWx0ZXIgZm9yIGludGVybmFsIG1lc3NhZ2VzLiBUaGlzIG1ldGhvZCBzaG91bGQgcmV0dXJuIGB0cnVlYCB0byBhbGxvdyBhbmQgYGZhbHNlYCB0byBwcmV2ZW50IGludGVybmFsIG1lc3NhZ2UgZGlzcGF0Y2guIFRoaXMgY2xhc3MgYWx3YXlzIHJldHVybnMgYHRydWVgLlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiBbZGlzcGF0Y2hNZXNzYWdlXSguL21fc291cmNlLmpzLmh0bWwjZGlzcGF0Y2hNZXNzYWdlKSBtZXRob2Qgb2YgYE1lc3NhZ2VTb3VyY2VgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzb3VyY2VNZXNzYWdlIHNvdXJjZSBtZXNzYWdlLCBjYW4gYmUgdXNlZCBpbiBmaWx0ZXIgcnVsZVxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgaW50ZXJuYWwgbWVzc2FnZSwgY2FuIGJlIHVzZWQgaW4gZmlsdGVyIHJ1bGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBpbnRlcm5hbERhdGEgZGF0YSB0cmFuc2xhdGVkIGJ5IGBjcmVhdGVJbnRlcm5hbERhdGFgIG1ldGhvZCBmcm9tIHNvdXJjZSBkYXRhLCBjYW4gYmUgdXNlZCBpbiBmaWx0ZXIgcnVsZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gZmlsdGVyU291cmNlTWVzc2FnZShzb3VyY2VNZXNzYWdlLCBtZXNzYWdlLCBpbnRlcm5hbERhdGEpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1lc3NlbmdlckFQSSA9IHJlcXVpcmUoJy4vbV9hcGknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8qKlxuICogQSBnZW5lcmljIHN1YnNjbGFzcyBvZiBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpIHRoYXQgc3VwcG9ydHMgcGF0dGVybiBzdWJzY3JpcHRpb25zIHRvIHNvdXJjZS5cbiAqIENhbiBiZSB1c2VmdWwgaWYgdGhlIHNvdXJjZSBpcyBhbm90aGVyIE1lc3Nlbmdlci5cbiAqL1xuIHZhciBNZXNzZW5nZXJSZWdleHBBUEkgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NlbmdlckFQSSwgJ01lc3NlbmdlclJlZ2V4cEFQSScpO1xuXG4gbW9kdWxlLmV4cG9ydHMgPSBNZXNzZW5nZXJSZWdleHBBUEk7XG5cblxuXy5leHRlbmRQcm90byhNZXNzZW5nZXJSZWdleHBBUEksIHtcbiAgICBpbml0OiBpbml0LFxuICAgIGFkZEludGVybmFsTWVzc2FnZTogYWRkSW50ZXJuYWxNZXNzYWdlLFxuICAgIHJlbW92ZUludGVybmFsTWVzc2FnZTogcmVtb3ZlSW50ZXJuYWxNZXNzYWdlLFxuICAgIGdldEludGVybmFsTWVzc2FnZXM6IGdldEludGVybmFsTWVzc2FnZXNcbn0pO1xuXG5cbi8qKlxuICogTWVzc2VuZ2VyUmVnZXhwQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IE1lc3NlbmdlclJlZ2V4cEFQSSBjb25zdHJ1Y3Rvci5cbiAqL1xuZnVuY3Rpb24gaW5pdCgpIHtcbiAgICBNZXNzZW5nZXJBUEkucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfcGF0dGVybkludGVybmFsTWVzc2FnZXM6IHt9XG4gICAgfSk7XG4gICAgdGhpcy5fY2F0Y2hBbGxTdWJzY3JpYmVkID0gZmFsc2U7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJSZWdleHBBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBBdWdtZW50cyBNZXNzZW5nZXJBUEkgbWV0aG9kIGJ5IHN0b3JpbmcgcmVnZXhwXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgaW50ZXJuYWwgbWVzc2FnZSB0byBiZSB0cmFuc2xhdGVkIGFuZCBhZGRlZFxuICogQHJldHVybiB7U3RyaW5nfFJlZ0V4cHx1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIGFkZEludGVybmFsTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgdmFyIHNvdXJjZU1lc3NhZ2UgPSBNZXNzZW5nZXJBUEkucHJvdG90eXBlLmFkZEludGVybmFsTWVzc2FnZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIFxuICAgIC8vIHN0b3JlIHJlZ2V4cCBpdHNlbGYgaWYgc291cmNlTWVzc2FnZSBpcyByZWdleHBcbiAgICBpZiAoc291cmNlTWVzc2FnZSAmJiBzb3VyY2VNZXNzYWdlIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHRoaXMuX2ludGVybmFsTWVzc2FnZXNbc291cmNlTWVzc2FnZV0ucGF0dGVybiA9IHNvdXJjZU1lc3NhZ2U7XG4gICAgICAgIHRoaXMuX3BhdHRlcm5JbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdID0gdGhpcy5faW50ZXJuYWxNZXNzYWdlc1tzb3VyY2VNZXNzYWdlXTtcbiAgICAgICAgaWYgKHRoaXMuX2NhdGNoQWxsU3Vic2NyaWJlZCkgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5fY2F0Y2hBbGxTdWJzY3JpYmVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIC8uKi87XG4gICAgfVxuXG4gICAgcmV0dXJuIHNvdXJjZU1lc3NhZ2U7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJSZWdleHBBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBBdWdtZW50cyBNZXNzZW5nZXJBUEkgbWV0aG9kIGJ5IHJlbW92aW5nIHJlZ2V4cCBzdWJzY2lycHRpb25cbiAqIFxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgaW50ZXJuYWwgbWVzc2FnZSB0byBiZSB0cmFuc2xhdGVkIGFuZCBhZGRlZFxuICogQHJldHVybiB7U3RyaW5nfFJlZ0V4cHx1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUludGVybmFsTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgdmFyIHNvdXJjZU1lc3NhZ2UgPSBNZXNzZW5nZXJBUEkucHJvdG90eXBlLnJlbW92ZUludGVybmFsTWVzc2FnZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgaWYgKHNvdXJjZU1lc3NhZ2UgJiYgc291cmNlTWVzc2FnZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICBkZWxldGUgdGhpcy5fcGF0dGVybkludGVybmFsTWVzc2FnZXNbc291cmNlTWVzc2FnZV07XG4gICAgICAgIHZhciBub1BhdHRlcm5JbnRlcm5hbE1lc3NhZ2VzID0gISBPYmplY3Qua2V5cyh0aGlzLl9wYXR0ZXJuSW50ZXJuYWxNZXNzYWdlcykubGVuZ3RoO1xuICAgICAgICBpZiAobm9QYXR0ZXJuSW50ZXJuYWxNZXNzYWdlcykge1xuICAgICAgICAgICAgdGhpcy5fY2F0Y2hBbGxTdWJzY3JpYmVkID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gLy4qLztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzb3VyY2VNZXNzYWdlO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQXVnbWVudHMgTWVzc2VuZ2VyQVBJIG1ldGhvZCBieSByZXR1cm5pbmcgbWVzc2FnZXMgc3Vic2NyaWJlZCB3aXRoIHJlZ2V4cFxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBieSBgTWVzc2FnZVNvdXJjZWAgdG8gZGlzcGF0Y2ggc291cmNlIG1lc3NhZ2Ugb24gdGhlIGBNZXNlbmdlcmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBzb3VyY2VNZXNzYWdlIHNvdXJjZSBtZXNzYWdlXG4gKiBAcmV0dXJuIHtBcnJheVtTdHJpbmddfVxuICovXG5mdW5jdGlvbiBnZXRJbnRlcm5hbE1lc3NhZ2VzKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICB2YXIgaW50ZXJuYWxNZXNzYWdlcyA9IE1lc3NlbmdlckFQSS5wcm90b3R5cGUuZ2V0SW50ZXJuYWxNZXNzYWdlcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLy8gYWRkIGludGVybmFsIG1lc3NhZ2VzIGZvciByZWdleHAgc291cmNlIHN1YnNjcmlwdGlvbnNcbiAgICBpZiAodHlwZW9mIHNvdXJjZU1lc3NhZ2UgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgaW50ZXJuYWxNZXNzYWdlcyA9IGludGVybmFsTWVzc2FnZXMgfHwgW107XG4gICAgICAgIHZhciBpbnRlcm5hbE1lc3NhZ2VzSGFzaCA9IF8ub2JqZWN0KGludGVybmFsTWVzc2FnZXMsIHRydWUpO1xuXG4gICAgICAgIF8uZWFjaEtleSh0aGlzLl9wYXR0ZXJuSW50ZXJuYWxNZXNzYWdlcywgZnVuY3Rpb24ocGF0dGVybk1lc3NhZ2VzKSB7XG4gICAgICAgICAgICB2YXIgc291cmNlUGF0dGVybiA9IHBhdHRlcm5NZXNzYWdlcy5wYXR0ZXJuO1xuXG4gICAgICAgICAgICBpZiAoc291cmNlUGF0dGVybi50ZXN0KHNvdXJjZU1lc3NhZ2UpKVxuICAgICAgICAgICAgICAgIHBhdHRlcm5NZXNzYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGludGVybmFsTWVzc2FnZXNIYXNoW21lc3NhZ2VdKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIGludGVybmFsTWVzc2FnZXMucHVzaChtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxNZXNzYWdlc0hhc2hbbWVzc2FnZV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IFxuXG4gICAgcmV0dXJuIGludGVybmFsTWVzc2FnZXM7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNaXhpbiA9IHJlcXVpcmUoJy4uL2Fic3RyYWN0L21peGluJylcbiAgICAsIE1lc3NlbmdlckFQSSA9IHJlcXVpcmUoJy4vbV9hcGknKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKVxuICAgICwgdG9CZUltcGxlbWVudGVkID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLnRvQmVJbXBsZW1lbnRlZFxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuTWVzc2FnZVNvdXJjZWBcbiAqIEFuIGFic3RyYWN0IGNsYXNzIChzdWJjbGFzcyBvZiBbTWl4aW5dKC4uL2Fic3RyYWN0L21peGluLmpzLmh0bWwpKSBmb3IgY29ubmVjdGluZyBbTWVzc2VuZ2VyXSguL2luZGV4LmpzLmh0bWwpIHRvIGV4dGVybmFsIHNvdXJjZXMgb2YgbWVzc2FnZXMgKGxpa2UgRE9NIGV2ZW50cykgYW5kIGRlZmluaW5nIGhpZ2hlciBsZXZlbCBtZXNzYWdlcy5cbiAqIEFuIGluc3RhbmNlIG9mIE1lc3NhZ2VTb3VyY2UgY2FuIGVpdGhlciBiZSBwYXNzZWQgdG8gTWVzc2VuZ2VyIGNvbnN0cnVjdG9yIG9yIGxhdGVyIHVzaW5nIGBfc2V0TWVzc2FnZVNvdXJjZWAgbWV0aG9kIG9mIE1lc3Nlbmdlci4gT25jZSBzZXQsIE1lc3NhZ2VTb3VyY2Ugb2YgTWVzc2VuZ2VyIGNhbm5vdCBiZSBjaGFuZ2VkLlxuICovXG52YXIgTWVzc2FnZVNvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoTWl4aW4sICdNZXNzYWdlU291cmNlJywgdHJ1ZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTWVzc2FnZVNvdXJjZTtcblxuXG4vKipcbiAqICMjIyNNZXNzYWdlU291cmNlIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI2luaXQpIC0gaW5pdGlhbGl6ZXMgbWVzc2FnZVNvdXJjZSAtIGNhbGxlZCBieSBNaXhpbiBzdXBlcmNsYXNzXG4gKiAtIFtzZXRNZXNzZW5nZXJdKCNzZXRNZXNzZW5nZXIpIC0gY29ubmVjdHMgTWVzc2VuZ2VyIHRvIE1lc3NhZ2VTb3VyY2UsIGlzIGNhbGxlZCBmcm9tIGBpbml0YCBvciBgX3NldE1lc3NhZ2VTb3VyY2VgIG1ldGhvZHMgb2YgW01lc3Nlbmdlcl0oLi9pbmRleC5qcy5odG1sKS5cbiAqIC0gW29uU3Vic2NyaWJlckFkZGVkXSgjb25TdWJzY3JpYmVyQWRkZWQpIC0gY2FsbGVkIGJ5IE1lc3NlbmdlciB0byBub3RpZnkgd2hlbiB0aGUgZmlyc3Qgc3Vic2NyaWJlciBmb3IgYW4gaW50ZXJuYWwgbWVzc2FnZSB3YXMgYWRkZWQsIHNvIE1lc3NhZ2VTb3VyY2UgY2FuIHN1YnNjcmliZSB0byBzb3VyY2VcbiAqIC0gW29uU3Vic2NyaWJlclJlbW92ZWRdKCNvblN1YnNjcmliZXJSZW1vdmVkKSAtIGNhbGxlZCBieSBNZXNzZW5nZXIgdG8gbm90aWZ5IHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciBmb3IgYW4gaW50ZXJuYWwgbWVzc2FnZSB3YXMgcmVtb3ZlZCwgc28gTWVzc2FnZVNvdXJjZSBjYW4gdW5zdWJzY3JpYmUgZnJvbSBzb3VyY2VcbiAqIC0gW2Rpc3BhdGNoTWVzc2FnZV0oI2Rpc3BhdGNoTWVzc2FnZSkgLSBkaXNwYXRjaGVzIHNvdXJjZSBtZXNzYWdlLiBNZXNzYWdlU291cmNlIHN1YmNsYXNzIHNob3VsZCBpbXBsZW1lbnQgbWVjaGFuaXNtIHdoZW4gb24gYWN0dWFsIHNvdXJjZSBtZXNzYWdlIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC5cbiAqXG4gKiBNZXRob2RzIGJlbG93IHNob3VsZCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzczpcbiAqXG4gKiAtIFt0cmlnZ2VyXSgjdHJpZ2dlcikgLSB0cmlnZ2VycyBtZXNzYWdlcyBvbiB0aGUgc291cmNlIChhbiBvcHRpb25hbCBtZXRob2QpXG4gKiAtIFthZGRTb3VyY2VTdWJzY3JpYmVyXSgjYWRkU291cmNlU3Vic2NyaWJlcikgLSBhZGRzIGxpc3RlbmVyL3N1YnNjcmliZXIgdG8gZXh0ZXJuYWwgbWVzc2FnZVxuICogLSBbcmVtb3ZlU291cmNlU3Vic2NyaWJlcl0oI3JlbW92ZVNvdXJjZVN1YnNjcmliZXIpIC0gcmVtb3ZlcyBsaXN0ZW5lci9zdWJzY3JpYmVyIGZyb20gZXh0ZXJuYWwgbWVzc2FnZVxuICovXG5fLmV4dGVuZFByb3RvKE1lc3NhZ2VTb3VyY2UsIHtcbiAgICBpbml0OiBpbml0LFxuICAgIGRlc3Ryb3k6IE1lc3NhZ2VTb3VyY2UkZGVzdHJveSxcbiAgICBzZXRNZXNzZW5nZXI6IHNldE1lc3NlbmdlcixcbiAgICBvblN1YnNjcmliZXJBZGRlZDogb25TdWJzY3JpYmVyQWRkZWQsXG4gICAgb25TdWJzY3JpYmVyUmVtb3ZlZDogb25TdWJzY3JpYmVyUmVtb3ZlZCwgXG4gICAgZGlzcGF0Y2hNZXNzYWdlOiBkaXNwYXRjaE1lc3NhZ2UsXG4gICAgcG9zdE1lc3NhZ2U6IHBvc3RNZXNzYWdlLFxuICAgIF9wcmVwYXJlTWVzc2VuZ2VyQVBJOiBfcHJlcGFyZU1lc3NlbmdlckFQSSxcblxuICAgIC8vIE1ldGhvZHMgYmVsb3cgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzc1xuICAgIHRyaWdnZXI6IHRvQmVJbXBsZW1lbnRlZCxcbiAgICBhZGRTb3VyY2VTdWJzY3JpYmVyOiB0b0JlSW1wbGVtZW50ZWQsXG4gICAgcmVtb3ZlU291cmNlU3Vic2NyaWJlcjogdG9CZUltcGxlbWVudGVkXG59KTtcblxuXG4vKipcbiAqIE1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kLlxuICogQ2FsbGVkIGJ5IE1peGluIGNvbnN0cnVjdG9yLlxuICogTWVzc2FnZVNvdXJjZSBjb25zdHJ1Y3RvciBzaG91bGQgYmUgcGFzc2VkIHRoZSBzYW1lIHBhcmFtZXRlcnMgYXMgdGhpcyBtZXRob2Qgc2lnbmF0dXJlLlxuICogSWYgYW4gaW5zdGFuY2Ugb2YgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSBpcyBwYXNzZWQgYXMgdGhlIHRoaXJkIHBhcmFtZXRlciwgaXQgZXh0ZW5kcyBNZXNzYWdlU291cmNlIGZ1bmN0aW9uYWxpdHkgdG8gYWxsb3cgaXQgdG8gZGVmaW5lIG5ldyBtZXNzYWdlcywgdG8gZmlsdGVyIG1lc3NhZ2VzIGJhc2VkIG9uIHRoZWlyIGRhdGEgYW5kIHRvIGNoYW5nZSBtZXNzYWdlIGRhdGEuIFNlZSBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IE9wdGlvbmFsIG9iamVjdCB0aGF0IHN0b3JlcyB0aGUgTWVzc2FnZVNvdXJjZSBvbiBvbmUgb2YgaXRzIHByb3BlcnRpZXMuIEl0IGlzIHVzZWQgdG8gcHJveHkgbWV0aG9kcyBvZiBNZXNzYWdlU291cmNlLlxuICogQHBhcmFtIHtPYmplY3RbU3RyaW5nXX0gcHJveHlNZXRob2RzIE9wdGlvbmFsIG1hcCBvZiBtZXRob2QgbmFtZXM7IGtleSAtIHByb3h5IG1ldGhvZCBuYW1lLCB2YWx1ZSAtIE1lc3NhZ2VTb3VyY2UncyBtZXRob2QgbmFtZS5cbiAqIEBwYXJhbSB7TWVzc2VuZ2VyQVBJfSBtZXNzZW5nZXJBUEkgT3B0aW9uYWwgaW5zdGFuY2Ugb2YgTWVzc2VuZ2VyQVBJLlxuICovXG5mdW5jdGlvbiBpbml0KGhvc3RPYmplY3QsIHByb3h5TWV0aG9kcywgbWVzc2VuZ2VyQVBJKSB7XG4gICAgdGhpcy5fcHJlcGFyZU1lc3NlbmdlckFQSShtZXNzZW5nZXJBUEkpO1xufVxuXG5cbi8qKlxuICogRGVzdHJveXMgbWVzc2FnZSBzb3VyY2VcbiAqL1xuZnVuY3Rpb24gTWVzc2FnZVNvdXJjZSRkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLm1lc3NlbmdlckFQSSlcbiAgICAgICAgdGhpcy5tZXNzZW5nZXJBUEkuZGVzdHJveSgpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBTZXRzIHJlZmVyZW5jZSB0byBNZXNzZW5nZXIgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtNZXNzZW5nZXJ9IG1lc3NlbmdlciByZWZlcmVuY2UgdG8gTWVzc2VuZ2VyIGluc3RhbmNlIGxpbmtlZCB0byB0aGlzIE1lc3NhZ2VTb3VyY2VcbiAqL1xuZnVuY3Rpb24gc2V0TWVzc2VuZ2VyKG1lc3Nlbmdlcikge1xuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ21lc3NlbmdlcicsIG1lc3Nlbmdlcik7XG59XG5cblxuLyoqXG4gKiBNZXNzYWdlU291cmNlIGluc3RhbmNlIG1ldGhvZC5cbiAqIFByZXBhcmVzIFtNZXNzZW5nZXJBUEldKC4vbV9hcGkuanMuaHRtbCkgcGFzc2VkIHRvIGNvbnN0cnVjdG9yIGJ5IHByb3h5aW5nIGl0cyBtZXRob2RzIHRvIGl0c2VsZiBvciBpZiBNZXNzZW5nZXJBUEkgd2Fzbid0IHBhc3NlZCBkZWZpbmVzIHR3byBtZXRob2RzIHRvIGF2b2lkIGNoZWNraW5nIHRoZWlyIGF2YWlsYWJpbGl0eSBldmVyeSB0aW1lIHRoZSBtZXNzYWdlIGlzIGRpc3BhdGNoZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7TWVzc2VuZ2VyQVBJfSBtZXNzZW5nZXJBUEkgT3B0aW9uYWwgaW5zdGFuY2Ugb2YgTWVzc2VuZ2VyQVBJXG4gKi9cbmZ1bmN0aW9uIF9wcmVwYXJlTWVzc2VuZ2VyQVBJKG1lc3NlbmdlckFQSSkge1xuICAgIGNoZWNrKG1lc3NlbmdlckFQSSwgTWF0Y2guT3B0aW9uYWwoTWVzc2VuZ2VyQVBJKSk7XG5cbiAgICBpZiAoISBtZXNzZW5nZXJBUEkpXG4gICAgICAgIG1lc3NlbmdlckFQSSA9IG5ldyBNZXNzZW5nZXJBUEk7XG5cbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXNzZW5nZXJBUEknLCBtZXNzZW5nZXJBUEkpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBTdWJzY3JpYmVzIHRvIGV4dGVybmFsIHNvdXJjZSB1c2luZyBgYWRkU291cmNlU3Vic2NyaWJlcmAgbWV0aG9kIHRoYXQgc2hvdWxkIGJlIGltcGxlbWVudGVkIGluIHN1YmNsYXNzLlxuICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IFtNZXNzZW5nZXJdKC4vaW5kZXguanMuaHRtbCkgd2hlbiB0aGUgZmlyc3Qgc3Vic2NyaWJlciB0byB0aGUgYG1lc3NhZ2VgIGlzIGFkZGVkLlxuICogRGVsZWdhdGVzIHRvIHN1cHBsaWVkIG9yIGRlZmF1bHQgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSBmb3IgdHJhbnNsYXRpb24gb2YgYG1lc3NhZ2VgIHRvIGBzb3VyY2VNZXNzYWdlYC4gYE1lc3NhZ2VBUEkucHJvdG90eXBlLmFkZEludGVybmFsTWVzc2FnZWAgd2lsbCByZXR1cm4gdW5kZWZpbmVkIGlmIHRoaXMgYHNvdXJjZU1lc3NhZ2VgIHdhcyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gdG8gcHJldmVudCBkdXBsaWNhdGUgc3Vic2NyaXB0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIE1lc3NlbmdlciBtZXNzYWdlIHRoYXQgaGFzIHRvIGJlIHN1YnNjcmliZWQgdG8gYXQgdGhlIGV4dGVybmFsIHNvdXJjZSBvZiBtZXNzYWdlcy5cbiAqL1xuZnVuY3Rpb24gb25TdWJzY3JpYmVyQWRkZWQobWVzc2FnZSkge1xuICAgIHZhciBuZXdTb3VyY2VNZXNzYWdlID0gdGhpcy5tZXNzZW5nZXJBUEkuYWRkSW50ZXJuYWxNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIGlmICh0eXBlb2YgbmV3U291cmNlTWVzc2FnZSAhPSAndW5kZWZpbmVkJylcbiAgICAgICAgdGhpcy5hZGRTb3VyY2VTdWJzY3JpYmVyKG5ld1NvdXJjZU1lc3NhZ2UpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBVbnN1YnNjcmliZXMgZnJvbSBleHRlcm5hbCBzb3VyY2UgdXNpbmcgYHJlbW92ZVNvdXJjZVN1YnNjcmliZXJgIG1ldGhvZCB0aGF0IHNob3VsZCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzcy5cbiAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBbTWVzc2VuZ2VyXSguL2luZGV4LmpzLmh0bWwpIHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciB0byB0aGUgYG1lc3NhZ2VgIGlzIHJlbW92ZWQuXG4gKiBEZWxlZ2F0ZXMgdG8gc3VwcGxpZWQgb3IgZGVmYXVsdCBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpIGZvciB0cmFuc2xhdGlvbiBvZiBgbWVzc2FnZWAgdG8gYHNvdXJjZU1lc3NhZ2VgLiBgTWVzc2FnZUFQSS5wcm90b3R5cGUucmVtb3ZlSW50ZXJuYWxNZXNzYWdlYCB3aWxsIHJldHVybiB1bmRlZmluZWQgaWYgdGhpcyBgc291cmNlTWVzc2FnZWAgd2FzIG5vdCB5ZXQgc3Vic2NyaWJlZCB0byB0byBwcmV2ZW50IHVuc3Vic2NyaXB0aW9uIHdpdGhvdXQgcHJldmlvdXMgc3Vic2NyaXB0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIE1lc3NlbmdlciBtZXNzYWdlIHRoYXQgaGFzIHRvIGJlIHVuc3Vic2NyaWJlZCBmcm9tIGF0IHRoZSBleHRlcm5hbCBzb3VyY2Ugb2YgbWVzc2FnZXMuXG4gKi9cbmZ1bmN0aW9uIG9uU3Vic2NyaWJlclJlbW92ZWQobWVzc2FnZSkge1xuICAgIHZhciByZW1vdmVkU291cmNlTWVzc2FnZSA9IHRoaXMubWVzc2VuZ2VyQVBJLnJlbW92ZUludGVybmFsTWVzc2FnZShtZXNzYWdlKTtcbiAgICBpZiAodHlwZW9mIHJlbW92ZWRTb3VyY2VNZXNzYWdlICE9ICd1bmRlZmluZWQnKVxuICAgICAgICB0aGlzLnJlbW92ZVNvdXJjZVN1YnNjcmliZXIocmVtb3ZlZFNvdXJjZU1lc3NhZ2UpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBEaXNwYXRjaGVzIHNvdXJjZU1lc3NhZ2UgdG8gTWVzc2VuZ2VyLlxuICogTWVjaGFuaXNtIHRoYXQgY2FsbHMgdGhpcyBtZXRob2Qgd2hlbiB0aGUgc291cmNlIG1lc3NhZ2UgaXMgcmVjZWl2ZWQgc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzIChzZWUgW0RPTUV2ZW50c1NvdXJjZV0oLi4vY29tcG9uZW50cy9tc2dfc3JjL2RvbV9ldmVudHMuanMuaHRtbCkgZm9yIGV4YW1wbGUpLlxuICogRGVsZWdhdGVzIHRvIHN1cHBsaWVkIG9yIGRlZmF1bHQgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSB0byBjcmVhdGUgaW50ZXJuYWwgbWVzc2FnZSBkYXRhIChgY3JlYXRlSW50ZXJuYWxEYXRhYCkgYW5kIHRvIGZpbHRlciB0aGUgbWVzc2FnZSBiYXNlZCBvbiBpdHMgZGF0YSBhbmQvb3IgbWVzc2FnZSAoYGZpbHRlclNvdXJjZU1lc3NhZ2VgKS5cbiAqIEJhc2UgTWVzc2VuZ2VyQVBJIGNsYXNzIGltcGxlbWVudHMgdGhlc2UgdHdvIG1ldGhvZHMgaW4gYSB0cml2aWFsIHdheSAoYGNyZWF0ZUludGVybmFsRGF0YWAgc2ltcGx5IHJldHVybnMgZXh0ZXJuYWwgZGF0YSwgYGZpbHRlclNvdXJjZU1lc3NhZ2VgIHJldHVybnMgYHRydWVgKSwgdGhleSBhcmUgbWVhbnQgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNvdXJjZU1lc3NhZ2Ugc291cmNlIG1lc3NhZ2UgcmVjZWl2ZWQgZnJvbSBleHRlcm5hbCBzb3VyY2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2VEYXRhIGRhdGEgcmVjZWl2ZWQgZnJvbSBleHRlcm5hbCBzb3VyY2VcbiAqL1xuZnVuY3Rpb24gZGlzcGF0Y2hNZXNzYWdlKHNvdXJjZU1lc3NhZ2UsIHNvdXJjZURhdGEpIHtcbiAgICB2YXIgYXBpID0gdGhpcy5tZXNzZW5nZXJBUElcbiAgICAgICAgLCBpbnRlcm5hbE1lc3NhZ2VzID0gYXBpLmdldEludGVybmFsTWVzc2FnZXMoc291cmNlTWVzc2FnZSk7XG5cbiAgICBpZiAoaW50ZXJuYWxNZXNzYWdlcykgXG4gICAgICAgIGludGVybmFsTWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICAgICAgdmFyIGludGVybmFsRGF0YSA9IGFwaS5jcmVhdGVJbnRlcm5hbERhdGEoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgc291cmNlRGF0YSk7XG5cbiAgICAgICAgICAgIHZhciBzaG91bGREaXNwYXRjaCA9IGFwaS5maWx0ZXJTb3VyY2VNZXNzYWdlKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIGludGVybmFsRGF0YSk7XG4gICAgICAgICAgICBpZiAoc2hvdWxkRGlzcGF0Y2gpIFxuICAgICAgICAgICAgICAgIHRoaXMucG9zdE1lc3NhZ2UobWVzc2FnZSwgaW50ZXJuYWxEYXRhKTsgICAgICBcbiAgICAgICAgICAgIFxuICAgICAgICB9LCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIFBvc3RzIG1lc3NhZ2Ugb24gdGhlIG1lc3Nlbmdlci4gVGhpcyBtZXRob2QgaXMgc2VwYXJhdGVkIHNvIHNwZWNpZmljIG1lc3NhZ2Ugc291cmNlcyBjYW4gbWFrZSBtZXNzYWdlIGRpc3BhdGNoIHN5bmNocm9ub3VzIGJ5IHVzaW5nIGBwb3N0TWVzc2FnZVN5bmNgXG4gKiBcbiAqIEBwYXJhbSAge1N0cmluZ30gbWVzc2FnZVxuICogQHBhcmFtICB7T2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2UsIGRhdGEpIHtcbiAgICB0aGlzLm1lc3Nlbmdlci5wb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4vbV9zb3VyY2UnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKTtcblxuXG4vKipcbiAqIFN1YmNsYXNzIG9mIE1lc3NhZ2VTb3VyY2UgdGhhdCBhbGxvd3MgdG8gY29ubmVjdCBNZXNzZW5nZXIgdG8gYW5vdGhlciBNZXNzZW5nZXIgdXNpbmcgaXQgYXMgZXh0ZXJuYWwgc291cmNlLlxuICovXG52YXIgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2FnZVNvdXJjZSwgJ01lc3Nlbmdlck1lc3NhZ2VTb3VyY2UnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNZXNzZW5nZXJNZXNzYWdlU291cmNlO1xuXG5cbi8qKlxuICogIyMjI01lc3Nlbmdlck1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqL1xuXy5leHRlbmRQcm90byhNZXNzZW5nZXJNZXNzYWdlU291cmNlLCB7XG4gICAgaW5pdDogaW5pdCxcbiAgICBhZGRTb3VyY2VTdWJzY3JpYmVyOiBhZGRTb3VyY2VTdWJzY3JpYmVyLFxuICAgIHJlbW92ZVNvdXJjZVN1YnNjcmliZXI6IHJlbW92ZVNvdXJjZVN1YnNjcmliZXIsXG4gICAgcG9zdE1lc3NhZ2U6IE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UkcG9zdE1lc3NhZ2Vcbn0pO1xuXG4vKipcbiAqIEluaXRpYWxpemVzIE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2VcbiAqIERlZmluZXMgb25lIHBhcmFtZXRlciBpbiBhZGRpdGlvbiB0byBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBwYXJhbWV0ZXJzXG4gKlxuICogQHBhcmFtIHtNZXNzZW5nZXJ9IHNvdXJjZU1lc3NlbmdlciBtZXNzZW5nZXIgdGhpcyBtZXNzYWdlIHNvdXJjZSBjb25uZWN0cyB0b1xuICovXG5mdW5jdGlvbiBpbml0KGhvc3RPYmplY3QsIHByb3h5TWV0aG9kcywgbWVzc2VuZ2VyQVBJLCBzb3VyY2VNZXNzZW5nZXIpIHtcbiAgICBNZXNzYWdlU291cmNlLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5zb3VyY2VNZXNzZW5nZXIgPSBzb3VyY2VNZXNzZW5nZXI7XG59XG5cblxuLyoqXG4gKiBTdWJzY3JpYmVzIHRvIHNvdXJjZSBtZXNzYWdlLiBTZWUgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgZG9jcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xSZWdleH0gc291cmNlTWVzc2FnZSBzb3VyY2UgbWVzc2FnZSB0byBzdWJzY3JpYmUgdG9cbiAqL1xuZnVuY3Rpb24gYWRkU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgdGhpcy5zb3VyY2VNZXNzZW5nZXIub25TeW5jKHNvdXJjZU1lc3NhZ2UsIHsgY29udGV4dDogdGhpcywgc3Vic2NyaWJlcjogdGhpcy5kaXNwYXRjaE1lc3NhZ2UgfSk7XG59XG5cblxuLyoqXG4gKiBVbnN1YnNjcmliZXMgZnJvbSBzb3VyY2UgbWVzc2FnZS4gU2VlIFtNZXNzYWdlU291cmNlXSguL21fc291cmNlLmpzLmh0bWwpIGRvY3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnZXh9IHNvdXJjZU1lc3NhZ2Ugc291cmNlIG1lc3NhZ2UgdG8gdW5zdWJzY3JpYmUgZnJvbVxuICovXG5mdW5jdGlvbiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICB0aGlzLnNvdXJjZU1lc3Nlbmdlci5vZmYoc291cmNlTWVzc2FnZSwgeyBjb250ZXh0OiB0aGlzLCBzdWJzY3JpYmVyOiB0aGlzLmRpc3BhdGNoTWVzc2FnZSB9KTtcbn1cblxuXG4vKipcbiAqIE92ZXJyaWRlcyBkZWZhbHV0IG1lc3NhZ2Ugc291cmNlIHRvIGRpc3BhdGNoIG1lc3NhZ2VzIHN5bmNocm9ub3VzbHlcbiAqIFxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UkcG9zdE1lc3NhZ2UobWVzc2FnZSwgZGF0YSkge1xuICAgIHRoaXMubWVzc2VuZ2VyLnBvc3RNZXNzYWdlU3luYyhtZXNzYWdlLCBkYXRhKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vLyByZWdpc3RlciBpbmNsdWRlZCBmYWNldHNcbnJlcXVpcmUoJy4vdXNlX2ZhY2V0cycpO1xuXG4vLyByZWdpc3RlciBpbmNsdWRlZCBjb21wb25lbnRzXG5yZXF1aXJlKCcuL3VzZV9jb21wb25lbnRzJyk7XG5cblxuLyoqXG4gKiBgbWlsb2BcbiAqXG4gKiBBIG1pbmltYWxpc3QgYnJvd3NlciBmcmFtZXdvcmsgdGhhdCBiaW5kcyBET00gZWxlbWVudHMgdG8gSlMgY29tcG9uZW50cyBhbmQgY29tcG9uZW50cyB0byBtb2RlbHMuXG4gKlxuICogYG1pbG9gIGlzIGF2YWlsYWJsZSBhcyBnbG9iYWwgb2JqZWN0IGluIHRoZSBicm93c2VyLlxuICogQXQgdGhlIG1vbWVudCBpdCBpcyBub3QgcG9zc2lpYmxlIHRvIHJlcXVpcmUgaXQgd2l0aCBicm93c2VyaWZ5IHRvIGhhdmUgaXQgYnVuZGxlZCB3aXRoIHRoZSBhcHAgYmVjYXVzZSBvZiB0aGUgd2F5IFticmZzXShodHRwczovL2dpdGh1Yi5jb20vc3Vic3RhY2svYnJmcykgYnJvd3NlcmlmeSBwbHVnaW4gaXMgaW1wbGVtZW50ZWQuXG4gKiBJdCBpcyBwb3NzaWJsZSB0aG91Z2ggdG8gcmVxdWlyZSBgbWlsb2Agd2l0aCBub2RlIHRvIHVzZSB1bml2ZXJzYWwgcGFydHMgb2YgdGhlIGZyYW1ld29yayAoYWJzdHJhY3QgY2xhc3NlcywgTWVzc2VuZ2VyLCBNb2RlbCwgZXRjLik6XG4gKiBgYGBcbiAqIHZhciBtaWxvID0gcmVxdWlyZSgnbW9sLW1pbG8nKTtcbiAqIGBgYFxuICogXG4gKiBgbWlsb2AgaXRzZWxmIGlzIGEgZnVuY3Rpb24gdGhhdCBpbiB0aGUgYnJvd3NlciBjYW4gYmUgdXNlZCB0byBkZWxheSBleGVjdXRpb24gdW50aWwgRE9NIGlzIHJlYWR5LlxuICovXG5mdW5jdGlvbiBtaWxvKGZ1bmMpIHtcbiAgICBtaWxvLnV0aWwuZG9tUmVhZHkoZnVuYyk7XG59XG5cblxuLyoqXG4gKiAjIyMjTWlsbyBwYWNrYWdlcyMjIyNcbiAqXG4gKiAtIFtsb2FkZXJdKC4vbG9hZGVyLmpzLmh0bWwpIC0gbG9hZGluZyBzdWJ2aWV3cyBpbnRvIHBhZ2VcbiAqIC0gW2JpbmRlcl0oLi9iaW5kZXIuanMuaHRtbCkgLSBjb21wb25lbnRzIGluc3RhbnRpYXRpb24gYW5kIGJpbmRpbmcgb2YgRE9NIGVsZW1lbnRzIHRvIHRoZW1cbiAqIC0gW21pbmRlcl0oLi9taW5kZXIuanMuaHRtbCkgLSBkYXRhIHJlYWN0aXZpdHksIG9uZSBvciB0d28gd2F5LCBzaGFsbG93IG9yIGRlZXAsIGFzIHlvdSBsaWtlIGl0XG4gKiAtIFttYWlsXSguL21haWwvaW5kZXguanMuaHRtbCkgLSBhcHBsaWNhaXRvbiBsZXZlbCBtZXNzZW5nZXIsIGFsc28gY29ubmVjdHMgdG8gbWVzc2FnZXMgZnJvbSBvdGhlciB3aW5kb3dzIGRpc3BhdGNoZWQgd2l0aCBgd2luZG93LnBvc3RNZXNzYWdlYC5cbiAqIC0gW2NvbmZpZ10oLi9jb25maWcuanMuaHRtbCkgLSBtaWxvIGNvbmZpZ3VyYXRpb25cbiAqIC0gW3V0aWxdKC4vdXRpbC9pbmRleC5qcy5odG1sKSAtIGxvZ2dlciwgcmVxdWVzdCwgZG9tLCBjaGVjaywgZXJyb3IsIGV0Yy5cbiAqIC0gW2NsYXNzZXNdKC4vY2xhc3Nlcy5qcy5odG1sKSAtIGFic3RyYWN0IGFuZCBiYXNlIGNsYXNzZXNcbiAqIC0gW2F0dHJpYnV0ZXNdKC4vYXR0cmlidXRlcy9pbmRleC5qcy5odG1sKSAtIGNsYXNzZXMgdGhhdCB3cmFwIERPTSBlbGVtZW50cyBhdHRyaWJ1dGVzIHJlY29nbml6ZWQgYnkgbWlsb1xuICogLSBbQ29tcG9uZW50RmFjZXRdKC4vY29tcG9uZW50cy9jX2ZhY2V0LmpzLmh0bWwpIC0gYmFzZSBjbGFzcyBvZiBDb21wb25lbnQgZmFjZXRcbiAqIC0gW0NvbXBvbmVudF0oLi9jb21wb25lbnRzL2NfY2xhc3MuanMuaHRtbCkgLSBiYXNlIENvbXBvbmVudCBjbGFzc1xuICogLSBbTWVzc2VuZ2VyXSguL21lc3Nlbmdlci9pbmRleC5qcy5odG1sKSAtIGdlbmVyaWMgTWVzc2VuZ2VyIHVzZWQgaW4gbW9zdCBvdGhlciBtaWxvIGNsYXNzZXMsIGNhbiBiZSBtaXhlZCBpbnRvIGFwcCBjbGFzc2VzIHRvby5cbiAqIC0gW01vZGVsXSguL21vZGVsL2luZGV4LmpzLmh0bWwpIC0gTW9kZWwgY2xhc3MgdGhhdCBlbWl0cyBtZXNzYWdlcyBvbiBjaGFuZ2VzIHRvIGFueSBkZXB0aCB3aXRob3V0IHRpbWVyIGJhc2VkIHdhdGNoaW5nXG4gKiAtIFtyZWdpc3RyeV0oLi9yZWdpc3RyeS5qcy5odG1sKSAtIHJlZ2lzdHJpZXMgb2YgZmFzZXRzIGFuZCBjb21wb25lbnRzIGNsYXNzZXNcbiAqL1xuXy5leHRlbmQobWlsbywge1xuICAgIGxvYWRlcjogcmVxdWlyZSgnLi9sb2FkZXInKSxcbiAgICBiaW5kZXI6IHJlcXVpcmUoJy4vYmluZGVyJyksXG4gICAgbWluZGVyOiByZXF1aXJlKCcuL21pbmRlcicpLFxuICAgIG1haWw6IHJlcXVpcmUoJy4vc2VydmljZXMvbWFpbCcpLFxuICAgIHdpbmRvdzogcmVxdWlyZSgnLi9zZXJ2aWNlcy93aW5kb3cnKSxcbiAgICBjb25maWc6IHJlcXVpcmUoJy4vY29uZmlnJyksXG4gICAgdXRpbDogcmVxdWlyZSgnLi91dGlsJyksXG4gICAgY2xhc3NlczogcmVxdWlyZSgnLi9jbGFzc2VzJyksXG4gICAgYXR0cmlidXRlczogcmVxdWlyZSgnLi9hdHRyaWJ1dGVzJyksXG4gICAgQ29tcG9uZW50RmFjZXQ6IHJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0JyksXG4gICAgQ29tcG9uZW50OiByZXF1aXJlKCcuL2NvbXBvbmVudHMvY19jbGFzcycpLFxuICAgIE1lc3NlbmdlcjogcmVxdWlyZSgnLi9tZXNzZW5nZXInKSxcbiAgICBNb2RlbDogcmVxdWlyZSgnLi9tb2RlbCcpLFxuICAgIENvbW1hbmQ6IHJlcXVpcmUoJy4vY29tbWFuZCcpLFxuICAgIHJlZ2lzdHJ5OiByZXF1aXJlKCcuL3JlZ2lzdHJ5JyksXG4gICAgbWlsb192ZXJzaW9uOiAnMC4xLjQnLFxuICAgIGNyZWF0ZUNvbXBvbmVudENsYXNzOiByZXF1aXJlKCcuL3V0aWwvY3JlYXRlX2NvbXBvbmVudF9jbGFzcycpLFxuICAgIGRlc3Ryb3k6IGRlc3Ryb3lcbn0pO1xuXG5cbi8vIGV4cG9ydCBmb3Igbm9kZS9icm93c2VyaWZ5XG5pZiAodHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgICAgXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBtaWxvO1xuXG4vLyBnbG9iYWwgbWlsbyBmb3IgYnJvd3NlclxuaWYgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcpIHtcbiAgICB3aW5kb3cubWlsbyA9IG1pbG87XG4gICAgbWlsby5tYWlsLnRyaWdnZXIoJ21pbG9yZWFkeScpO1xufVxuXG5cbmZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgbWlsby5tYWlsLmRlc3Ryb3koKTtcbiAgICBtaWxvLndpbmRvdy5kZXN0cm95KCk7XG4gICAgbWlsby5taW5kZXIuZGVzdHJveSgpO1xuICAgIG1pbG8udXRpbC5kZXN0cm95KCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb25uZWN0b3IgPSByZXF1aXJlKCcuL21vZGVsL2Nvbm5lY3RvcicpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuL21lc3NlbmdlcicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4vdXRpbC9sb2dnZXInKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IG1pbmRlcjtcblxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBvbmUgb3IgbWFueSBDb25uZWN0b3Igb2JqZWN0cyB0aGF0XG4gKiBjcmVhdGUgbGl2ZSByZWFjdGl2ZSBjb25uZWN0aW9uIGJldHdlZW4gb2JqZWN0cyBpbXBsZW1lbnRpbmdcbiAqIGRhdGFTb3VyY2UgaW50ZXJmYWNlOlxuICogT2JqZWN0cyBzaG91bGQgZW1pdCBtZXNzYWdlcyB3aGVuIGFueSBwYXJ0IG9mIHRoZWlyIGRhdGEgY2hhbmdlcyxcbiAqIG1ldGhvZHMgYG9uYCBhbmQgYG9mZmAgc2hvdWxkIGJlIGltcGxlbWVudGVkIHRvIHN1YnNjcmliZS91bnN1YnNjcmliZVxuICogdG8gY2hhbmdlIG5vdGlmaWNhdGlvbiBtZXNzYWdlcywgbWV0aG9kcyBgc2V0YCBhbmQgYGdldGAgc2hvdWxkIGJlIGltcGxlbWVudGVkIHRvIGdldC9zZXQgZGF0YVxuICogb24gcGF0aCBvYmplY3RzLCBwb2ludGluZyB0byBwYXJ0aWN1bGFyIHBhcnRzIG9mIHRoZSBvYmplY3QsIG1ldGhvZCBgcGF0aGBcbiAqIHNob3VsZCByZXR1cm4gcGF0aCBvYmplY3QgZm9yIGEgZ2l2ZW4gcGF0aCBzdHJpbmcgKHNlZSBwYXRoIHV0aWxzIGZvciBwYXRoIHN0cmluZyBzeW50YXgpLlxuICogQm90aCBNb2RlbCBhbmQgRGF0YSBmYWNldCBhcmUgc3VjaCBkYXRhIHNvdXJjZXMsIHRoZXkgY2FuIGJlIGxpbmtlZCBieSBDb25uZWN0b3Igb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkczEgdGhlIGZpcnN0IGRhdGEgc291cmNlLiBJbnN0ZWFkIG9mIHRoZSBmaXJzdCBkYXRhIHNvdXJjZSBhbiBhcnJheSBjYW4gYmUgcGFzc2VkIHdpdGggYXJyYXlzIG9mIENvbm5lY3Rpb24gb2JqZWN0cyBwYXJhbWV0ZXJzIGluIGVhY2ggYXJyYXkgZWxlbWVudC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBtb2RlIHRoZSBjb25uZWN0aW9uIG1vZGUgdGhhdCBkZWZpbmVzIHRoZSBkaXJlY3Rpb24gYW5kIHRoZSBkZXB0aCBvZiBjb25uZWN0aW9uLiBQb3NzaWJsZSB2YWx1ZXMgYXJlICctPicsICc8PC0nLCAnPDw8LT4+PicsIGV0Yy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBkczIgdGhlIHNlY29uZCBkYXRhIHNvdXJjZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgbm90IGltcGxlbWVudGVkIHlldFxuICovXG5mdW5jdGlvbiBtaW5kZXIoZHMxLCBtb2RlLCBkczIsIG9wdGlvbnMpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShkczEpKSB7XG4gICAgICAgIHZhciBjb25uRGVzY3JpcHRpb25zID0gZHMxO1xuICAgICAgICB2YXIgY29ubmVjdG9ycyA9IGNvbm5EZXNjcmlwdGlvbnMubWFwKGZ1bmN0aW9uKGRlc2NyKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbm5lY3RvcihkZXNjclswXSwgZGVzY3JbMV0sIGRlc2NyWzJdLCBkZXNjclszXSk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25uZWN0b3JzLmZvckVhY2goX2FkZENvbm5lY3Rvcik7XG4gICAgICAgIHJldHVybiBjb25uZWN0b3JzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBjbmN0ID0gbmV3IENvbm5lY3RvcihkczEsIG1vZGUsIGRzMiwgb3B0aW9ucyk7XG4gICAgICAgIF9hZGRDb25uZWN0b3IoY25jdCk7XG4gICAgICAgIHJldHVybiBjbmN0O1xuICAgIH1cbn1cblxuXG4vKipcbiAqIG1lc3NlbmdlciBvZiBtaW5kZXIgd2hlcmUgaXQgZW1pdHMgZXZlbnRzIHJlbGF0ZWQgdG8gYWxsIGNvbm5lY3RvcnNcbiAqIEB0eXBlIHtNZXNzZW5nZXJ9XG4gKi9cbnZhciBfbWVzc2VuZ2VyID0gbmV3IE1lc3NlbmdlcihtaW5kZXIsIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG5cblxudmFyIF9jb25uZWN0b3JzID0gW11cbiAgICAsIF9yZWNlaXZlZE1lc3NhZ2VzID0gW11cbiAgICAsIF9pc1Byb3BhZ2F0aW5nID0gZmFsc2U7XG5cblxuXy5leHRlbmQobWluZGVyLCB7XG4gICAgZ2V0Q29ubmVjdG9yczogbWluZGVyX2dldENvbm5lY3RvcnMsXG4gICAgZ2V0RXhwYW5kZWRDb25uZWN0aW9uczogbWluZGVyX2dldEV4cGFuZGVkQ29ubmVjdGlvbnMsXG4gICAgaXNQcm9wYWdhdGluZzogbWluZGVyX2lzUHJvcGFnYXRpbmcsXG4gICAgd2hlblByb3BhZ2F0aW9uQ29tcGxldGVkOiBtaW5kZXJfd2hlblByb3BhZ2F0aW9uQ29tcGxldGVkLFxuICAgIGRlc3Ryb3lDb25uZWN0b3I6IG1pbmRlcl9kZXN0cm95Q29ubmVjdG9yLFxuICAgIGRlc3Ryb3k6IG1pbmRlcl9kZXN0cm95XG59KTtcblxuXG5mdW5jdGlvbiBfYWRkQ29ubmVjdG9yKGNuY3QpIHtcbiAgICBjbmN0Ll9fX21pbmRlcl9pZCA9IF9jb25uZWN0b3JzLnB1c2goY25jdCkgLSAxO1xuICAgIGNuY3Qub24oLy4qLywgb25Db25uZWN0b3JNZXNzYWdlKTtcbiAgICBtaW5kZXIucG9zdE1lc3NhZ2UoJ2FkZGVkJywgeyBjb25uZWN0b3I6IGNuY3QgfSk7XG4gICAgbWluZGVyLnBvc3RNZXNzYWdlKCd0dXJuZWRvbicsIHsgY29ubmVjdG9yOiBjbmN0IH0pO1xufVxuXG5cbmZ1bmN0aW9uIG9uQ29ubmVjdG9yTWVzc2FnZShtc2csIGRhdGEpIHtcbiAgICB2YXIgZGF0YSA9IGRhdGEgPyBfLmNsb25lKGRhdGEpIDoge307XG4gICAgXy5leHRlbmQoZGF0YSwge1xuICAgICAgICBpZDogdGhpcy5fX19taW5kZXJfaWQsXG4gICAgICAgIGNvbm5lY3RvcjogdGhpc1xuICAgIH0pO1xuICAgIG1pbmRlci5wb3N0TWVzc2FnZShtc2csIGRhdGEpO1xuICAgIGlmICghIF9yZWNlaXZlZE1lc3NhZ2VzLmxlbmd0aCAmJiAhIF9pc1Byb3BhZ2F0aW5nKSB7XG4gICAgICAgIF8uZGVmZXIoX2lkbGVDaGVjayk7XG4gICAgICAgIF9pc1Byb3BhZ2F0aW5nID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBfcmVjZWl2ZWRNZXNzYWdlcy5wdXNoKHsgbXNnOiBtc2csIGRhdGE6IGRhdGEgfSk7XG59XG5cblxuZnVuY3Rpb24gX2lkbGVDaGVjaygpIHtcbiAgICBpZiAoX3JlY2VpdmVkTWVzc2FnZXMubGVuZ3RoKSB7XG4gICAgICAgIF9yZWNlaXZlZE1lc3NhZ2VzLmxlbmd0aCA9IDA7XG4gICAgICAgIF8uZGVmZXIoX2lkbGVDaGVjayk7XG4gICAgICAgIG1pbmRlci5wb3N0TWVzc2FnZSgncHJvcGFnYXRpb250aWNrZWQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBfaXNQcm9wYWdhdGluZyA9IGZhbHNlO1xuICAgICAgICBtaW5kZXIucG9zdE1lc3NhZ2UoJ3Byb3BhZ2F0aW9uY29tcGxldGVkJyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIG1pbmRlcl9pc1Byb3BhZ2F0aW5nKCkge1xuICAgIHJldHVybiBfaXNQcm9wYWdhdGluZztcbn1cblxuXG5mdW5jdGlvbiBtaW5kZXJfd2hlblByb3BhZ2F0aW9uQ29tcGxldGVkKGNhbGxiYWNrKSB7XG4gICAgaWYgKF9pc1Byb3BhZ2F0aW5nKVxuICAgICAgICBtaW5kZXIub25jZSgncHJvcGFnYXRpb25jb21wbGV0ZWQnLCBleGVjdXRlQ2FsbGJhY2spO1xuICAgIGVsc2VcbiAgICAgICAgXy5kZWZlcihleGVjdXRlQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gZXhlY3V0ZUNhbGxiYWNrKCkge1xuICAgICAgICBpZiAoX2lzUHJvcGFnYXRpbmcpXG4gICAgICAgICAgICBtaW5kZXIub25jZSgncHJvcGFnYXRpb25jb21wbGV0ZWQnLCBleGVjdXRlQ2FsbGJhY2spO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBtaW5kZXJfZ2V0Q29ubmVjdG9ycyhvbk9mZikge1xuICAgIGlmICh0eXBlb2Ygb25PZmYgPT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgIHJldHVybiBfY29ubmVjdG9ycztcblxuICAgIHJldHVybiBfY29ubmVjdG9ycy5maWx0ZXIoZnVuY3Rpb24oY25jdCkge1xuICAgICAgICByZXR1cm4gY25jdC5pc09uID09PSBvbk9mZjtcbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBtaW5kZXJfZGVzdHJveUNvbm5lY3RvcihjbmN0KSB7XG4gICAgY25jdC5kZXN0cm95KCk7XG4gICAgdmFyIGluZGV4ID0gX2Nvbm5lY3RvcnMuaW5kZXhPZihjbmN0KTtcbiAgICBpZiAoaW5kZXggPj0gMClcbiAgICAgICAgZGVsZXRlIF9jb25uZWN0b3JzW2luZGV4XTtcbiAgICBlbHNlXG4gICAgICAgIGxvZ2dlci53YXJuKCdtaW5kZXI6IGNvbm5lY3RvciBkZXN0cm95ZWQgdGhhdCBpcyBub3QgcmVnaXN0ZXJlZCBpbiBtaW5kZXInKTtcbn1cblxuXG5mdW5jdGlvbiBtaW5kZXJfZ2V0RXhwYW5kZWRDb25uZWN0aW9ucyhvbk9mZiwgc2VhcmNoU3RyKSB7XG4gICAgdmFyIGNvbm5lY3RvcnMgPSBtaW5kZXIuZ2V0Q29ubmVjdG9ycyhvbk9mZik7XG4gICAgdmFyIGNvbm5lY3Rpb25zID0gIGNvbm5lY3RvcnMubWFwKGZ1bmN0aW9uKGNuY3QpIHtcbiAgICAgICAgdmFyIGNvbm5lY3Rpb24gPSB7XG4gICAgICAgICAgICBsZWZ0U291cmNlOiBfZ2V0RXhwYW5kZWRTb3VyY2UoY25jdC5kczEpLFxuICAgICAgICAgICAgcmlnaHRTb3VyY2U6IF9nZXRFeHBhbmRlZFNvdXJjZShjbmN0LmRzMiksXG4gICAgICAgICAgICBtb2RlOiBjbmN0Lm1vZGUsXG4gICAgICAgICAgICBpc09uOiBjbmN0LmlzT25cbiAgICAgICAgfTtcbiAgICAgICAgXG4gICAgICAgIGlmIChjbmN0Lm9wdGlvbnMpXG4gICAgICAgICAgICBjb25uZWN0aW9uLm9wdGlvbnMgPSBjbmN0Lm9wdGlvbnM7XG5cbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb247XG4gICAgfSk7XG5cbiAgICBpZiAoc2VhcmNoU3RyKVxuICAgICAgICBjb25uZWN0aW9ucyA9IGNvbm5lY3Rpb25zLmZpbHRlcihmdW5jdGlvbihjbmN0bikge1xuICAgICAgICAgICAgcmV0dXJuIF9zb3VyY2VNYXRjaGVzU3RyaW5nKGNuY3RuLmxlZnRTb3VyY2UsIHNlYXJjaFN0cilcbiAgICAgICAgICAgICAgICAgICAgfHwgX3NvdXJjZU1hdGNoZXNTdHJpbmcoY25jdG4ucmlnaHRTb3VyY2UsIHNlYXJjaFN0cik7XG4gICAgICAgIH0pO1xuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25zO1xufVxuXG5cbmZ1bmN0aW9uIF9nZXRFeHBhbmRlZFNvdXJjZShkcykge1xuICAgIHZhciBzb3VyY2UgPSBbXTtcbiAgICBpZiAodHlwZW9mIGRzID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaWYgKGRzLl9tb2RlbCAmJiBkcy5fYWNjZXNzUGF0aCkge1xuICAgICAgICAgICAgc291cmNlLnVuc2hpZnQoZHMuX2FjY2Vzc1BhdGgpO1xuICAgICAgICAgICAgZHMgPSBkcy5fbW9kZWw7XG4gICAgICAgIH1cblxuICAgICAgICBzb3VyY2UudW5zaGlmdChkcyk7XG4gICAgICAgIGRzID0gZHMuX2hvc3RPYmplY3Q7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkcyA9PSAnb2JqZWN0Jykge1xuICAgICAgICBzb3VyY2UudW5zaGlmdChkcyk7XG5cbiAgICAgICAgaWYgKGRzLm93bmVyKVxuICAgICAgICAgICAgc291cmNlLnVuc2hpZnQoZHMub3duZXIpO1xuICAgIH1cblxuICAgIHJldHVybiBzb3VyY2U7XG59XG5cblxuZnVuY3Rpb24gX3NvdXJjZU1hdGNoZXNTdHJpbmcoc291cmNlLCBtYXRjaFN0cikge1xuICAgIHJldHVybiBzb3VyY2Uuc29tZShmdW5jdGlvbihzcmNOb2RlKSB7XG4gICAgICAgIHZhciBjbGFzc05hbWUgPSBzcmNOb2RlLmNvbnN0cnVjdG9yICYmIHNyY05vZGUuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgcmV0dXJuIF9zdHJpbmdNYXRjaChjbGFzc05hbWUsIG1hdGNoU3RyKVxuICAgICAgICAgICAgICAgIHx8IF9zdHJpbmdNYXRjaChzcmNOb2RlLm5hbWUsIG1hdGNoU3RyKVxuICAgICAgICAgICAgICAgIHx8IF9zdHJpbmdNYXRjaChzcmNOb2RlLCBtYXRjaFN0cik7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gX3N0cmluZ01hdGNoKHN0ciwgc3Vic3RyKSB7XG4gICAgcmV0dXJuIHN0ciAmJiB0eXBlb2Ygc3RyID09ICdzdHJpbmcnICYmIHN0ci5pbmRleE9mKHN1YnN0cikgPj0gMDtcbn1cblxuXG5mdW5jdGlvbiBtaW5kZXJfZGVzdHJveSgpIHtcbiAgICBfY29ubmVjdG9ycy5mb3JFYWNoKGZ1bmN0aW9uKGNuY3QpIHtcbiAgICAgICAgZGVzdHJveURTKGNuY3QuZHMxKTtcbiAgICAgICAgZGVzdHJveURTKGNuY3QuZHMyKTtcbiAgICAgICAgY25jdC5kZXN0cm95KCk7XG4gICAgfSk7XG4gICAgX21lc3Nlbmdlci5kZXN0cm95KCk7XG4gICAgbWluZGVyLl9kZXN0cm95ZWQgPSB0cnVlO1xuXG4gICAgZnVuY3Rpb24gZGVzdHJveURTKGRzKSB7XG4gICAgICAgIGlmIChkcyAmJiAhZHMuX2Rlc3Ryb3llZCkgZHMuZGVzdHJveSgpO1xuICAgIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5JylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gcHJvY2VzcyBcImNoYW5nZWRhdGFcIiBtZXNzYWdlcyBlbWl0dGVkIGJ5IENvbm5lY3RvciBvYmplY3QuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gY2hhbmdlRGF0YUhhbmRsZXI7XG5cblxuXy5leHRlbmQoY2hhbmdlRGF0YUhhbmRsZXIsIHtcbiAgICBzZXRUcmFuc2FjdGlvbkZsYWc6IHNldFRyYW5zYWN0aW9uRmxhZyxcbiAgICBnZXRUcmFuc2FjdGlvbkZsYWc6IGdldFRyYW5zYWN0aW9uRmxhZyxcbiAgICBwYXNzVHJhbnNhY3Rpb25GbGFnOiBwYXNzVHJhbnNhY3Rpb25GbGFnLFxuICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkOiBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZFxufSk7XG5cblxuLyoqXG4gKiBDaGFuZ2UgZGF0YSB1c2VzIGhpZGRlbiBwcm9wZXJ0eSBvbiBhY2Nlc3NvciBtZXRob2RzIHRvIHBhc3MgZmxhZyB0aGF0IHRoZSBhY2Nlc3NvciBpcyBleGVjdXRlZCBhcyBhIHBhcnQgb2YgY2hhbmdlIHRyYW5zYWN0aW9uLlxuICogQWNjZXNzb3IgbWV0aG9kcyBhcmUgc3VwcG9zZWQgdG8gc3RvcmUgdGhpcyBmbGFnIGluIGEgbG9jYWwgdmFyaWFibGUgYW5kIHRvIGNsZWFyIGl0IChiZWNhdXNlIGFub3RoZXIgYWNjZXNzb3IgY2FuIGJlIGV4ZWN1dGVkIGluIG9yIG91dCBvZiB0cmFuc2FjdGlvbikgdXNpbmcgYGdldFRyYW5zYWN0aW9uRmxhZ2BcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBhY2Nlc3NvciBtZXRob2QgcmVmZXJlbmNlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGZsYWcgYSBmbGFnIHRvIGJlIHNldFxuICovXG5mdW5jdGlvbiBzZXRUcmFuc2FjdGlvbkZsYWcoZnVuYywgZmxhZykge1xuICAgIF8uZGVmaW5lUHJvcGVydHkoZnVuYywgJ19faW5DaGFuZ2VUcmFuc2FjdGlvbicsIGZsYWcsIF8uQ09ORiB8IF8uV1JJVCk7XG59XG5cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIGNsZWFycyB0cmFuc2FjdGlvbiBmbGFnIGZyb20gYWNjZXNzb3IgbWV0aG9kXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgYWNjZXNzb3IgbWV0aG9kIHJlZmVyZW5jZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25GbGFnKGZ1bmMpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGZ1bmMuX19pbkNoYW5nZVRyYW5zYWN0aW9uO1xuICAgIGRlbGV0ZSBmdW5jLl9faW5DaGFuZ2VUcmFuc2FjdGlvbjtcbiAgICByZXR1cm4gaW5UcmFuc2FjdGlvbjtcbn1cblxuXG5mdW5jdGlvbiBwYXNzVHJhbnNhY3Rpb25GbGFnKGZyb21GdW5jLCB0b0Z1bmMpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGdldFRyYW5zYWN0aW9uRmxhZyhmcm9tRnVuYyk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKHRvRnVuYywgaW5UcmFuc2FjdGlvbik7XG4gICAgcmV0dXJuIGluVHJhbnNhY3Rpb247XG59XG5cblxuLyoqXG4gKiBQb3N0cyBtZXNzYWdlIG9uIHRoaXMgdG8gaW5kaWNhdGUgdGhlIGVuZCBvZiB0cmFuc2FjdGlvbiB1bmxlc3MgYGluQ2hhbmdlVHJhbnNhY3Rpb25gIGlzIGB0cnVlYC5cbiAqL1xuZnVuY3Rpb24gcG9zdFRyYW5zYWN0aW9uRmluaXNoZWQoKSB7XG4gICAgdGhpcy5wb3N0TWVzc2FnZVN5bmMoJ2RhdGFjaGFuZ2VzJywgeyB0cmFuc2FjdGlvbjogZmFsc2UsIGNoYW5nZXM6IFtdIH0pO1xufVxuXG5cbi8qKlxuICogc3Vic2NyaWJlciB0byBcImNoYW5nZWRhdGFcIiBldmVudCBlbWl0dGVkIGJ5IFtDb25uZWN0b3JdKC4vY29ubmVjdG9yLmpzLmh0bWwpIG9iamVjdCB0byBlbmFibGUgcmVhY3RpdmUgY29ubmVjdGlvbnNcbiAqIFVzZWQgYnkgRGF0YSBmYWNldCwgTW9kZWwgYW5kIE1vZGVsUGF0aC4gQ2FuIGJlIHVzZWQgYnkgYW55IG9iamVjdCB0aGF0IGltcGxlbWVudHMgZ2V0L3NldC9kZWwvc3BsaWNlIGFwaSBhbmQgc2V0cyBkYXRhIGRlZXBseSB0byB0aGUgd2hvbGUgdHJlZS5cbiAqIE9iamVjdCBzaG91bGQgY2FsbCBgY2hhbmdlRGF0YUhhbmRsZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpYCBpbiBpdHMgY29uc3RydWN0b3IuXG4gKiBUT0RPOiBvcHRpbWl6ZSBtZXNzYWdlcyBsaXN0IHRvIGF2b2lkIHNldHRpbmcgZHVwbGljYXRlIHZhbHVlcyBkb3duIHRoZSB0cmVlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyBzaG91bGQgYmUgXCJjaGFuZ2VkYXRhXCIgaGVyZVxuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgYmF0Y2ggb2YgZGF0YSBjaGFuZ2UgZGVzY2lwdGlvbiBvYmplY3RzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsYmFjayB0byBjYWxsIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGRhdGEgaXMgcHJvY2Vzc2VkXG4gKi9cbmZ1bmN0aW9uIGNoYW5nZURhdGFIYW5kbGVyKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgcHJvY2Vzc0NoYW5nZXMuY2FsbCh0aGlzLCBkYXRhLmNoYW5nZXMsIGNhbGxiYWNrKTtcbn1cblxuXG4vLyBtYXAgb2YgbWVzc2FnZSB0eXBlcyB0byBtZXRob2RzXG52YXIgQ0hBTkdFX1RZUEVfVE9fTUVUSE9EX01BUCA9IHtcbiAgICAnYWRkZWQnOiAgICdzZXQnLFxuICAgICdjaGFuZ2VkJzogJ3NldCcsXG4gICAgJ2RlbGV0ZWQnOiAnZGVsJyxcbiAgICAncmVtb3ZlZCc6ICdkZWwnXG59O1xuXG5cbi8qKlxuICogUHJvY2Vzc2VzIHF1ZXVlZCBcImNoYW5nZWRhdGFcIiBtZXNzYWdlcy5cbiAqIFBvc3RzIFwiY2hhbmdlc3RhcnRlZFwiIGFuZCBcImNoYW5nZWNvbXBsZXRlZFwiIG1lc3NhZ2VzIGFuZCBjYWxscyBjYWxsYmFja1xuICpcbiAqIEBwYXJhbSB7W0Z1bmN0aW9uXX0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2l0aCBgKG51bGwsIGZhbHNlKWAgcGFyYW1ldGVycyBiZWZvcmUgY2hhbmdlIHByb2Nlc3Npbmcgc3RhcnRzIGFuZCBgKG51bGwsIHRydWUpYCBhZnRlciBpdCdzIGZpbmlzaGVkLlxuICovXG5mdW5jdGlvbiBwcm9jZXNzQ2hhbmdlcyh0cmFuc2FjdGlvbiwgY2FsbGJhY2spIHtcbiAgICBub3RpZnkuY2FsbCh0aGlzLCBjYWxsYmFjaywgZmFsc2UpO1xuICAgIHByb2Nlc3NUcmFuc2FjdGlvbi5jYWxsKHRoaXMsXG4gICAgICAgIHByZXBhcmVUcmFuc2FjdGlvbihcbiAgICAgICAgICAgIHZhbGlkYXRlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSk7XG4gICAgbm90aWZ5LmNhbGwodGhpcywgY2FsbGJhY2ssIHRydWUpO1xufVxuXG5cbmZ1bmN0aW9uIG5vdGlmeShjYWxsYmFjaywgY2hhbmdlRmluaXNoZWQpIHtcbiAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsLCBjaGFuZ2VGaW5pc2hlZCk7XG4gICAgdGhpcy5wb3N0TWVzc2FnZShjaGFuZ2VGaW5pc2hlZCA/ICdjaGFuZ2Vjb21wbGV0ZWQnIDogJ2NoYW5nZXN0YXJ0ZWQnKTtcbn1cblxuXG4vKipcbiAqIENoZWNrcyB0aGF0IGFsbCBtZXNzYWdlcyBmcm9tIHRoZSB0cmFuc2FjdGlvbiBjb21lIGZyb20gdGhlIHNhbWUgc291cmNlLlxuICogSGFjazogcmV2ZXJzZXMgdGhlIHRyYW5zYWN0aW9uIGlmIGl0IGNvbWVzIGZyb20gdGhlIERhdGEgZmFjZXRcbiAqIFJldHVybnMgdGhlIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNhY3Rpb24gKGZvciBjaGFpbmluZylcbiAqIFxuICogQHBhcmFtICB7QXJyYXl9IHRyYW5zYWN0aW9uIHRyYW5zYWN0aW9uIG9mIGRhdGEgY2hhbmdlc1xuICogQHJldHVybiB7QXJyYXl9IFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSB7XG4gICAgdmFyIHNvdXJjZSA9IHRyYW5zYWN0aW9uWzBdLnNvdXJjZVxuICAgICAgICAsIHNhbWVTb3VyY2UgPSB0cnVlO1xuXG4gICAgaWYgKHRyYW5zYWN0aW9uLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IHRyYW5zYWN0aW9uLmxlbmd0aDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgICAgaWYgKHRyYW5zYWN0aW9uW2ldLnNvdXJjZSAhPSBzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ2NoYW5nZWRhdGE6IGNoYW5nZXMgZnJvbSBkaWZmZXJlbnQgc291cmNlcyBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbiwgc291cmNlczonLCB0cmFuc2FjdGlvbltpXS5zb3VyY2UubmFtZSwgc291cmNlLm5hbWUpO1xuICAgICAgICAgICAgICAgIHNhbWVTb3VyY2UgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzb3VyY2UgPSB0cmFuc2FjdGlvbltpXS5zb3VyY2U7XG4gICAgICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uO1xufVxuXG5cbmZ1bmN0aW9uIHByZXBhcmVUcmFuc2FjdGlvbih0cmFuc2FjdGlvbikge1xuICAgIHZhciB0b2RvID0gW11cbiAgICAgICAgLCBwYXRoc1RvU3BsaWNlID0gW11cbiAgICAgICAgLCBwYXRoc1RvQ2hhbmdlID0gW11cbiAgICAgICAgLCBoYWRTcGxpY2VcbiAgICAgICAgLCBleGl0TG9vcCA9IHt9O1xuXG5cbiAgICB0cnkgeyB0cmFuc2FjdGlvbi5mb3JFYWNoKGNoZWNrQ2hhbmdlKTsgfVxuICAgIGNhdGNoIChlKSB7IGlmIChlICE9IGV4aXRMb29wKSB0aHJvdyBlOyB9XG5cbiAgICByZXR1cm4gdG9kbztcblxuXG4gICAgZnVuY3Rpb24gY2hlY2tDaGFuZ2UoZGF0YSkge1xuICAgICAgICAoZGF0YS50eXBlID09ICdzcGxpY2UnID8gY2hlY2tTcGxpY2UgOiBjaGVja01ldGhvZCkoZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjaGVja1NwbGljZShkYXRhKSB7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChkYXRhLnBhdGgpO1xuICAgICAgICB2YXIgcGFyZW50UGF0aENoYW5nZWQgPSBwYXRoc1RvQ2hhbmdlLnNvbWUoZnVuY3Rpb24ocGFyZW50UGF0aCkge1xuICAgICAgICAgICAgaWYgKHBhcnNlZFBhdGgubGVuZ3RoIDwgcGFyZW50UGF0aC5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJlbnRQYXRoQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgICAgIHRvZG8ucHVzaChkYXRhKTtcblxuICAgICAgICBpZiAoISBjb25maWcuZGVidWcpIHRocm93IGV4aXRMb29wO1xuICAgICAgICBwYXRoc1RvU3BsaWNlLnB1c2gocGFyc2VkUGF0aCk7XG4gICAgICAgIGhhZFNwbGljZSA9IHRydWU7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjaGVja01ldGhvZChkYXRhKSB7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChkYXRhLnBhdGgpO1xuICAgICAgICB2YXIgcGFyZW50UGF0aFNwbGljZWQgPSBwYXRoc1RvU3BsaWNlICYmIHBhdGhzVG9TcGxpY2Uuc29tZShmdW5jdGlvbihwYXJlbnRQYXRoKSB7XG4gICAgICAgICAgICBpZiAocGFyc2VkUGF0aC5sZW5ndGggPD0gcGFyZW50UGF0aC5sZW5ndGhcbiAgICAgICAgICAgICAgICB8fCBwYXJzZWRQYXRoW3BhcmVudFBhdGgubGVuZ3RoXS5zeW50YXggIT0gJ2FycmF5JykgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIF9wYXRoSXNQYXJlbnRPZihwYXJlbnRQYXRoLCBwYXJzZWRQYXRoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHBhcmVudFBhdGhTcGxpY2VkKSByZXR1cm47XG4gICAgICAgIGlmIChoYWRTcGxpY2UpIGxvZ2dlci5lcnJvcignY2hhbmdlZGF0YTogY2hpbGQgY2hhbmdlIGlzIGV4ZWN1dGVkIGFmdGVyIHNwbGljZTsgcHJvYmFibHkgZGF0YSBzb3VyY2UgZGlkIG5vdCBlbWl0IG1lc3NhZ2Ugd2l0aCBkYXRhLnR5cGU9PVwiZmluaXNoZWRcIicpO1xuXG4gICAgICAgIHZhciBwYXJlbnRQYXRoQ2hhbmdlZCA9IHBhdGhzVG9DaGFuZ2Uuc29tZShmdW5jdGlvbihwYXJlbnRQYXRoKSB7XG4gICAgICAgICAgICBpZiAocGFyc2VkUGF0aC5sZW5ndGggPD0gcGFyZW50UGF0aC5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJlbnRQYXRoQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgICAgIHBhdGhzVG9DaGFuZ2UucHVzaChwYXJzZWRQYXRoKTtcblxuICAgICAgICB0b2RvLnB1c2goZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgY2hpbGRQYXRoKSB7XG4gICAgICAgIHJldHVybiBwYXJlbnRQYXRoLmV2ZXJ5KGZ1bmN0aW9uKHBhdGhOb2RlLCBpbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhdGhOb2RlLnByb3BlcnR5ID09IGNoaWxkUGF0aFtpbmRleF0ucHJvcGVydHk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBwcm9jZXNzVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pIHtcbiAgICB0cmFuc2FjdGlvbi5mb3JFYWNoKHByb2Nlc3NDaGFuZ2UsIHRoaXMpO1xuICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkLmNhbGwodGhpcywgZmFsc2UpO1xuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc0NoYW5nZShkYXRhKSB7XG4gICAgICAgIHZhciBtb2RlbFBhdGggPSB0aGlzLnBhdGgoZGF0YS5wYXRoLCBkYXRhLnR5cGUgIT0gJ3JlbW92ZWQnICYmIGRhdGEudHlwZSAhPSAnZGVsZXRlZCcpO1xuICAgICAgICBpZiAoISBtb2RlbFBhdGgpIHJldHVybjtcbiAgICAgICAgKGRhdGEudHlwZSA9PSAnc3BsaWNlJyA/IGV4ZWN1dGVTcGxpY2UgOiBleGVjdXRlTWV0aG9kKShtb2RlbFBhdGgsIGRhdGEpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBleGVjdXRlU3BsaWNlKG1vZGVsUGF0aCwgZGF0YSkge1xuICAgIHZhciBpbmRleCA9IGRhdGEuaW5kZXhcbiAgICAgICAgLCBob3dNYW55ID0gZGF0YS5yZW1vdmVkLmxlbmd0aFxuICAgICAgICAsIHNwbGljZUFyZ3MgPSBbaW5kZXgsIGhvd01hbnldO1xuXG4gICAgc3BsaWNlQXJncyA9IHNwbGljZUFyZ3MuY29uY2F0KGRhdGEubmV3VmFsdWUuc2xpY2UoaW5kZXgsIGluZGV4ICsgZGF0YS5hZGRlZENvdW50KSk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKG1vZGVsUGF0aC5zcGxpY2UsIHRydWUpO1xuICAgIG1vZGVsUGF0aC5zcGxpY2UuYXBwbHkobW9kZWxQYXRoLCBzcGxpY2VBcmdzKTtcbn1cblxuXG5mdW5jdGlvbiBleGVjdXRlTWV0aG9kKG1vZGVsUGF0aCwgZGF0YSkge1xuICAgIHZhciBtZXRob2ROYW1lID0gQ0hBTkdFX1RZUEVfVE9fTUVUSE9EX01BUFtkYXRhLnR5cGVdO1xuICAgIGlmIChtZXRob2ROYW1lKSB7XG4gICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZyhtb2RlbFBhdGhbbWV0aG9kTmFtZV0sIHRydWUpO1xuICAgICAgICBtb2RlbFBhdGhbbWV0aG9kTmFtZV0oZGF0YS5uZXdWYWx1ZSk7XG4gICAgfSBlbHNlXG4gICAgICAgIGxvZ2dlci5lcnJvcigndW5rbm93biBkYXRhIGNoYW5nZSB0eXBlJyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb25uZWN0b3JFcnJvciA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS5Db25uZWN0b3JcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uL21lc3NlbmdlcicpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gQ29ubmVjdG9yO1xuXG5cbnZhciBtb2RlUGF0dGVybiA9IC9eKFxcPCopXFwtKyhcXD4qKSQvO1xuXG5cbi8qKlxuICogQ29ubmVjdG9yXG4gKiBDbGFzcyB0aGF0IGNyZWF0ZXMgY29ubmVjdG9yIG9iamVjdCBmb3IgZGF0YSBjb25uZWN0aW9uIGJldHdlZW5cbiAqIHR3byBkYXRhLXNvdXJjZXNcbiAqIERhdGEtc291cmNlcyBzaG91bGQgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgQVBJOlxuICogZ2V0KCkgLSBnZXQgdmFsdWUgZnJvbSBkYXRhc291cmNlIG9yIGl0cyBwYXRoXG4gKiBzZXQodmFsdWUpIC0gc2V0IHZhbHVlIHRvIGRhdGFzb3VyY2Ugb3IgdG8gaXRzIHBhdGhcbiAqIG9uKHBhdGgsIHN1YnNjcmliZXIpIC0gc3Vic2NyaXB0aW9uIHRvIGRhdGEgY2hhbmdlcyB3aXRoIFwiKlwiIHN1cHBvcnRcbiAqIG9mZihwYXRoLCBzdWJzY3JpYmVyKVxuICogcGF0aChhY2Nlc3NQYXRoKSAtIHRvIHJldHVybiB0aGUgb2JqZWN0IHRoYXQgZ2l2ZXMgcmVmZXJlbmNlIHRvIHNvbWUgcGFydCBvZiBkYXRhc291cmNlXG4gKiBhbmQgY29tcGxpZXMgd2l0aCB0aGF0IGFwaSB0b28uXG4gKlxuICogIyMjI0V2ZW50cyMjIyNcbiAqXG4gKiAtICd0dXJuZWRvbicgLSBjb25uZWN0b3Igd2FzIHR1cm5lZCBvblxuICogLSAndHVybmVkb2ZmJyAtIGNvbm5lY3RvciB3YXMgdHVybmVkIG9mZlxuICogLSAnY2hhbmdlc3RhcnRlZCcgLSBjaGFuZ2Ugb24gY29ubmVjdGVkIGRhdGFzb3VyY2UgaXMgc3RhcnRlZFxuICogLSAnY2hhbmdlY29tcGxldGVkJyAtIGNoYW5nZSBvbiBjb25uZWN0ZWQgZGF0YXNvdXJjZSBpcyBjb21wbGV0ZWRcbiAqIC0gJ2Rlc3Ryb3llZCcgLSBjb25uZWN0b3Igd2FzIGRlc3Ryb3llZFxuICogXG4gKiBAcGFyYW0ge09iamVjdH0gZHMxIHRoZSBmaXJzdCBkYXRhIHNvdXJjZS5cbiAqIEBwYXJhbSB7U3RyaW5nfSBtb2RlIHRoZSBjb25uZWN0aW9uIG1vZGUgdGhhdCBkZWZpbmVzIHRoZSBkaXJlY3Rpb24gYW5kIHRoZSBkZXB0aCBvZiBjb25uZWN0aW9uLiBQb3NzaWJsZSB2YWx1ZXMgYXJlICctPicsICc8PC0nLCAnPDw8LT4+PicsIGV0Yy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBkczIgdGhlIHNlY29uZCBkYXRhIHNvdXJjZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgbm90IGltcGxlbWVudGVkIHlldFxuICogQHJldHVybiB7Q29ubmVjdG9yfSB3aGVuIGNhbGxlZCB3aXRoIGBuZXdgLCBjcmVhdGVzIGEgQ29ubmVjdG9yIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gQ29ubmVjdG9yKGRzMSwgbW9kZSwgZHMyLCBvcHRpb25zKSB7XG4gICAgc2V0dXBNb2RlLmNhbGwodGhpcywgbW9kZSk7XG5cbiAgICBfLmV4dGVuZCh0aGlzLCB7XG4gICAgICAgIGRzMTogZHMxLFxuICAgICAgICBkczI6IGRzMixcbiAgICAgICAgaXNPbjogZmFsc2UsXG4gICAgICAgIF9jaGFuZ2VzUXVldWUxOiBbXSxcbiAgICAgICAgX2NoYW5nZXNRdWV1ZTI6IFtdLFxuICAgICAgICBfbWVzc2VuZ2VyOiBuZXcgTWVzc2VuZ2VyKHRoaXMsIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcylcbiAgICB9KTtcblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cbiAgICAgICAgdmFyIHBhdGhUcmFuc2xhdGlvbiA9IG9wdGlvbnMucGF0aFRyYW5zbGF0aW9uO1xuICAgICAgICBpZiAocGF0aFRyYW5zbGF0aW9uKSB7XG4gICAgICAgICAgICBwYXRoVHJhbnNsYXRpb24gPSBfLmNsb25lKHBhdGhUcmFuc2xhdGlvbik7XG4gICAgICAgICAgICB2YXIgcGF0dGVyblRyYW5zbGF0aW9uID0gZ2V0UGF0dGVyblRyYW5zbGF0aW9ucyhwYXRoVHJhbnNsYXRpb24pO1xuICAgICAgICAgICAgXy5leHRlbmQodGhpcywge1xuICAgICAgICAgICAgICAgIHBhdGhUcmFuc2xhdGlvbjE6IHJldmVyc2VUcmFuc2xhdGlvblJ1bGVzKHBhdGhUcmFuc2xhdGlvbiksXG4gICAgICAgICAgICAgICAgcGF0aFRyYW5zbGF0aW9uMjogcGF0aFRyYW5zbGF0aW9uLFxuICAgICAgICAgICAgICAgIHBhdHRlcm5UcmFuc2xhdGlvbjE6IHJldmVyc2VQYXR0ZXJuVHJhbnNsYXRpb25SdWxlcyhwYXR0ZXJuVHJhbnNsYXRpb24pLFxuICAgICAgICAgICAgICAgIHBhdHRlcm5UcmFuc2xhdGlvbjI6IHBhdHRlcm5UcmFuc2xhdGlvblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZGF0YVRyYW5zbGF0aW9uID0gb3B0aW9ucy5kYXRhVHJhbnNsYXRpb247XG4gICAgICAgIGlmIChkYXRhVHJhbnNsYXRpb24pIHtcbiAgICAgICAgICAgIF8uZXh0ZW5kKHRoaXMsIHtcbiAgICAgICAgICAgICAgICBkYXRhVHJhbnNsYXRpb24xOiBkYXRhVHJhbnNsYXRpb25bJzwtJ10sXG4gICAgICAgICAgICAgICAgZGF0YVRyYW5zbGF0aW9uMjogZGF0YVRyYW5zbGF0aW9uWyctPiddXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkYXRhVmFsaWRhdGlvbiA9IG9wdGlvbnMuZGF0YVZhbGlkYXRpb247XG4gICAgICAgIGlmIChkYXRhVmFsaWRhdGlvbikge1xuICAgICAgICAgICAgXy5leHRlbmQodGhpcywge1xuICAgICAgICAgICAgICAgIGRhdGFWYWxpZGF0aW9uMTogZGF0YVZhbGlkYXRpb25bJzwtJ10sXG4gICAgICAgICAgICAgICAgZGF0YVZhbGlkYXRpb24yOiBkYXRhVmFsaWRhdGlvblsnLT4nXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnR1cm5PbigpO1xufVxuXG5cbmZ1bmN0aW9uIHNldHVwTW9kZShtb2RlKXtcbiAgICB2YXIgcGFyc2VkTW9kZSA9IG1vZGUubWF0Y2gobW9kZVBhdHRlcm4pO1xuXG4gICAgaWYgKCEgcGFyc2VkTW9kZSlcbiAgICAgICAgbW9kZVBhcnNlRXJyb3IoKTtcblxuICAgIHZhciBkZXB0aDEgPSBwYXJzZWRNb2RlWzFdLmxlbmd0aFxuICAgICAgICAsIGRlcHRoMiA9IHBhcnNlZE1vZGVbMl0ubGVuZ3RoO1xuXG4gICAgaWYgKGRlcHRoMSAmJiBkZXB0aDIgJiYgZGVwdGgxICE9IGRlcHRoMilcbiAgICAgICAgbW9kZVBhcnNlRXJyb3IoKTtcblxuICAgIGlmICghIGRlcHRoMSAmJiAhIGRlcHRoMilcbiAgICAgICAgbW9kZVBhcnNlRXJyb3IoKTtcblxuICAgIF8uZXh0ZW5kKHRoaXMsIHtcbiAgICAgICAgbW9kZTogbW9kZSxcbiAgICAgICAgZGVwdGgxOiBkZXB0aDEsXG4gICAgICAgIGRlcHRoMjogZGVwdGgyLFxuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gbW9kZVBhcnNlRXJyb3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBDb25uZWN0b3JFcnJvcignaW52YWxpZCBDb25uZWN0b3IgbW9kZTogJyArIG1vZGUpO1xuICAgIH1cbn1cblxuXG5fLmV4dGVuZFByb3RvKENvbm5lY3Rvciwge1xuICAgIHR1cm5PbjogQ29ubmVjdG9yJHR1cm5PbixcbiAgICB0dXJuT2ZmOiBDb25uZWN0b3IkdHVybk9mZixcbiAgICBkZXN0cm95OiBDb25uZWN0b3IkZGVzdHJveSxcbiAgICBjaGFuZ2VNb2RlOiBDb25uZWN0b3IkY2hhbmdlTW9kZSxcbiAgICBkZWZlckNoYW5nZU1vZGU6IENvbm5lY3RvciRkZWZlckNoYW5nZU1vZGVcbn0pO1xuXG4vKipcbiAqIEZ1bmN0aW9uIGNoYW5nZSB0aGUgbW9kZSBvZiB0aGUgY29ubmVjdGlvblxuICpcbiAqIEBwYXJhbSBAcGFyYW0ge1N0cmluZ30gbW9kZSB0aGUgY29ubmVjdGlvbiBtb2RlIHRoYXQgZGVmaW5lcyB0aGUgZGlyZWN0aW9uIGFuZCB0aGUgZGVwdGggb2YgY29ubmVjdGlvbi4gUG9zc2libGUgdmFsdWVzIGFyZSAnLT4nLCAnPDwtJywgJzw8PC0+Pj4nLCBldGMuXG4gKiBAcmV0dXJuIHtPYmplY3RbU3RyaW5nXX1cbiAqL1xuZnVuY3Rpb24gQ29ubmVjdG9yJGNoYW5nZU1vZGUobW9kZSkge1xuICAgIHRoaXMudHVybk9mZigpO1xuICAgIHNldHVwTW9kZS5jYWxsKHRoaXMsIG1vZGUpO1xuICAgIHRoaXMudHVybk9uKCk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBGdW5jdGlvbiBjaGFuZ2UgdGhlIG1vZGUgb2YgdGhlIGNvbm5lY3Rpb25cbiAqXG4gKiBAcGFyYW0gQHBhcmFtIHtTdHJpbmd9IG1vZGUgdGhlIGNvbm5lY3Rpb24gbW9kZSB0aGF0IGRlZmluZXMgdGhlIGRpcmVjdGlvbiBhbmQgdGhlIGRlcHRoIG9mIGNvbm5lY3Rpb24uIFBvc3NpYmxlIHZhbHVlcyBhcmUgJy0+JywgJzw8LScsICc8PDwtPj4+JywgZXRjLlxuICogQHJldHVybiB7T2JqZWN0W1N0cmluZ119XG4gKi9cbmZ1bmN0aW9uIENvbm5lY3RvciRkZWZlckNoYW5nZU1vZGUobW9kZSkge1xuICAgIF8uZGVmZXJNZXRob2QodGhpcywgJ2NoYW5nZU1vZGUnLCBtb2RlKTtcbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgcmV2ZXJzZXMgdHJhbnNsYXRpb24gcnVsZXMgZm9yIHBhdGhzIG9mIGNvbm5lY3RlZCBvZGF0YSBzb3VyY2VzXG4gKlxuICogQHBhcmFtIHtPYmplY3RbU3RyaW5nXX0gcnVsZXMgbWFwIG9mIHBhdGhzIGRlZmluaW5nIHRoZSB0cmFuc2xhdGlvbiBydWxlc1xuICogQHJldHVybiB7T2JqZWN0W1N0cmluZ119XG4gKi9cbmZ1bmN0aW9uIHJldmVyc2VUcmFuc2xhdGlvblJ1bGVzKHJ1bGVzKSB7XG4gICAgdmFyIHJldmVyc2VSdWxlcyA9IHt9O1xuICAgIF8uZWFjaEtleShydWxlcywgZnVuY3Rpb24ocGF0aDJfdmFsdWUsIHBhdGgxX2tleSkge1xuICAgICAgICByZXZlcnNlUnVsZXNbcGF0aDJfdmFsdWVdID0gcGF0aDFfa2V5O1xuICAgIH0pO1xuICAgIHJldHVybiByZXZlcnNlUnVsZXM7XG59XG5cblxuZnVuY3Rpb24gZ2V0UGF0dGVyblRyYW5zbGF0aW9ucyhwYXRoVHJhbnNsYXRpb24pIHtcbiAgICB2YXIgcGF0dGVyblRyYW5zbGF0aW9uID0gW107XG4gICAgXy5lYWNoS2V5KHBhdGhUcmFuc2xhdGlvbiwgZnVuY3Rpb24ocGF0aDJfdmFsdWUsIHBhdGgxX2tleSkge1xuICAgICAgICB2YXIgc3RhckluZGV4MSA9IHBhdGgxX2tleS5pbmRleE9mKCcqJylcbiAgICAgICAgICAgICwgc3RhckluZGV4MiA9IHBhdGgyX3ZhbHVlLmluZGV4T2YoJyonKTtcbiAgICAgICAgaWYgKHN0YXJJbmRleDEgPj0gMCAmJiBzdGFySW5kZXgyID49IDApIHsgLy8gcGF0dGVybiB0cmFuc2xhdGlvblxuICAgICAgICAgICAgaWYgKHBhdGgxX2tleS5zbGljZShzdGFySW5kZXgxKSAhPSBwYXRoMl92YWx1ZS5zbGljZShzdGFySW5kZXgyKSlcbiAgICAgICAgICAgICAgICBfdGhyb3dJbnZhbGlkVHJhbnNsYXRpb24ocGF0aDFfa2V5LCBwYXRoMl92YWx1ZSk7XG4gICAgICAgICAgICBkZWxldGUgcGF0aFRyYW5zbGF0aW9uW3BhdGgxX2tleV07ICAgICAgICAgICAgXG5cbiAgICAgICAgICAgIHBhdHRlcm5UcmFuc2xhdGlvbi5wdXNoKHtcbiAgICAgICAgICAgICAgICBmcm9tUGF0dGVybjogcGF0aFV0aWxzLmNyZWF0ZVJlZ2V4UGF0aChwYXRoMV9rZXkpLFxuICAgICAgICAgICAgICAgIGZyb21TdGF0aWNQYXRoOiBfZ2V0U3RhdGljUGF0aChwYXRoMV9rZXksIHN0YXJJbmRleDEpLFxuICAgICAgICAgICAgICAgIHRvUGF0dGVybjogcGF0aFV0aWxzLmNyZWF0ZVJlZ2V4UGF0aChwYXRoMl92YWx1ZSksXG4gICAgICAgICAgICAgICAgdG9TdGF0aWNQYXRoOiBfZ2V0U3RhdGljUGF0aChwYXRoMl92YWx1ZSwgc3RhckluZGV4MilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXJJbmRleDEgPj0gMCB8fCBzdGFySW5kZXgyID49IDApIC8vIHBhdHRlcm4gb25seSBvbiBvbmUgc2lkZSBvZiB0cmFuc2xhdGlvblxuICAgICAgICAgICAgX3Rocm93SW52YWxpZFRyYW5zbGF0aW9uKHBhdGgxX2tleSwgcGF0aDJfdmFsdWUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHBhdHRlcm5UcmFuc2xhdGlvbjtcblxuXG4gICAgZnVuY3Rpb24gX3Rocm93SW52YWxpZFRyYW5zbGF0aW9uKHBhdGgxLCBwYXRoMikge1xuICAgICAgICB0aHJvdyBuZXcgQ29ubmVjdG9yRXJyb3IoJ0ludmFsaWQgcGF0dGVybiB0cmFuc2xhdGlvbjogJyArIHBhdGgxICsgJywgJyArIHBhdGgyKTtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIF9nZXRTdGF0aWNQYXRoKHBhdGgsIHN0YXJJbmRleCkge1xuICAgICAgICByZXR1cm4gcGF0aC5yZXBsYWNlKC9bXFwuXFxbXT9cXCouKiQvLCAnJyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIHJldmVyc2VQYXR0ZXJuVHJhbnNsYXRpb25SdWxlcyhwYXR0ZXJuVHJhbnNsYXRpb24pIHtcbiAgICByZXR1cm4gcGF0dGVyblRyYW5zbGF0aW9uLm1hcChmdW5jdGlvbihwdCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZnJvbVBhdHRlcm46IHB0LnRvUGF0dGVybixcbiAgICAgICAgICAgIGZyb21TdGF0aWNQYXRoOiBwdC50b1N0YXRpY1BhdGgsXG4gICAgICAgICAgICB0b1BhdHRlcm46IHB0LmZyb21QYXR0ZXJuLFxuICAgICAgICAgICAgdG9TdGF0aWNQYXRoOiBwdC5mcm9tU3RhdGljUGF0aFxuICAgICAgICB9O1xuICAgIH0pO1xufVxuXG5cbi8qKlxuICogdHVybk9uXG4gKiBNZXRob2Qgb2YgQ29ubmVjdG9yIHRoYXQgZW5hYmxlcyBjb25uZWN0aW9uIChpZiBpdCB3YXMgcHJldmlvdXNseSBkaXNhYmxlZClcbiAqL1xuZnVuY3Rpb24gQ29ubmVjdG9yJHR1cm5PbigpIHtcbiAgICBpZiAodGhpcy5pc09uKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ2RhdGEgc291cmNlcyBhcmUgYWxyZWFkeSBjb25uZWN0ZWQnKTtcblxuICAgIHZhciBzdWJzY3JpcHRpb25QYXRoID0gdGhpcy5fc3Vic2NyaXB0aW9uUGF0aCA9XG4gICAgICAgIG5ldyBBcnJheSh0aGlzLmRlcHRoMSB8fCB0aGlzLmRlcHRoMikuam9pbignKicpO1xuXG4gICAgdmFyIHN1YnNjcmlwdGlvblBhdHRlcm4gPSBwYXRoVXRpbHMuY3JlYXRlUmVnZXhQYXRoKHN1YnNjcmlwdGlvblBhdGgpO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICh0aGlzLmRlcHRoMSlcbiAgICAgICAgdGhpcy5fbGluazEgPSBsaW5rRGF0YVNvdXJjZSgnX2xpbmsyJywgdGhpcy5kczIsIHRoaXMuZHMxLCB0aGlzLl9jaGFuZ2VzUXVldWUxLCB0aGlzLnBhdGhUcmFuc2xhdGlvbjEsIHRoaXMucGF0dGVyblRyYW5zbGF0aW9uMSwgdGhpcy5kYXRhVHJhbnNsYXRpb24xLCB0aGlzLmRhdGFWYWxpZGF0aW9uMSk7XG4gICAgaWYgKHRoaXMuZGVwdGgyKVxuICAgICAgICB0aGlzLl9saW5rMiA9IGxpbmtEYXRhU291cmNlKCdfbGluazEnLCB0aGlzLmRzMSwgdGhpcy5kczIsIHRoaXMuX2NoYW5nZXNRdWV1ZTIsIHRoaXMucGF0aFRyYW5zbGF0aW9uMiwgdGhpcy5wYXR0ZXJuVHJhbnNsYXRpb24yLCB0aGlzLmRhdGFUcmFuc2xhdGlvbjIsIHRoaXMuZGF0YVZhbGlkYXRpb24yKTtcblxuICAgIHRoaXMuaXNPbiA9IHRydWU7XG4gICAgdGhpcy5wb3N0TWVzc2FnZSgndHVybmVkb24nKTtcblxuXG4gICAgZnVuY3Rpb24gbGlua0RhdGFTb3VyY2UocmV2ZXJzZUxpbmssIGZyb21EUywgdG9EUywgY2hhbmdlc1F1ZXVlLCBwYXRoVHJhbnNsYXRpb24sIHBhdHRlcm5UcmFuc2xhdGlvbiwgZGF0YVRyYW5zbGF0aW9uLCBkYXRhVmFsaWRhdGlvbikge1xuICAgICAgICBmcm9tRFMub25TeW5jKCdkYXRhY2hhbmdlcycsIG9uRGF0YSk7XG4gICAgICAgIHJldHVybiBvbkRhdGE7XG5cbiAgICAgICAgZnVuY3Rpb24gb25EYXRhKG1lc3NhZ2UsIGJhdGNoKSB7XG4gICAgICAgICAgICB2YXIgc2VuZERhdGEgPSB7XG4gICAgICAgICAgICAgICAgY2hhbmdlczogW10sXG4gICAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IGJhdGNoLnRyYW5zYWN0aW9uXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJhdGNoLmNoYW5nZXMuZm9yRWFjaChmdW5jdGlvbihjaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICB2YXIgc291cmNlUGF0aCA9IGNoYW5nZS5wYXRoXG4gICAgICAgICAgICAgICAgICAgICwgdGFyZ2V0UGF0aCA9IHRyYW5zbGF0ZVBhdGgoc291cmNlUGF0aCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldFBhdGggPT0gJ3VuZGVmaW5lZCcpIHJldHVybjtcblxuICAgICAgICAgICAgICAgIHZhciBjaGFuZ2UgPSBfLmNsb25lKGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgXy5leHRlbmQoY2hhbmdlLCB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogZnJvbURTLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiB0YXJnZXRQYXRoXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICB0cmFuc2xhdGVEYXRhKHNvdXJjZVBhdGgsIGNoYW5nZSk7XG4gICAgICAgICAgICAgICAgdmFsaWRhdGVEYXRhKHNvdXJjZVBhdGgsIGNoYW5nZSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKCEgY2hhbmdlc1F1ZXVlLmxlbmd0aClcbiAgICAgICAgICAgICAgICBfLmRlZmVyKHBvc3RDaGFuZ2VEYXRhKTtcblxuICAgICAgICAgICAgY2hhbmdlc1F1ZXVlLnB1c2goc2VuZERhdGEpO1xuXG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHRyYW5zbGF0ZVBhdGgoc291cmNlUGF0aCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXRoVHJhbnNsYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zbGF0ZWRQYXRoID0gcGF0aFRyYW5zbGF0aW9uW3NvdXJjZVBhdGhdO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNsYXRlZFBhdGgpIHJldHVybiB0cmFuc2xhdGVkUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXR0ZXJuVHJhbnNsYXRpb24ubGVuZ3RoKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIHZhciBwdCA9IF8uZmluZChwYXR0ZXJuVHJhbnNsYXRpb24sIGZ1bmN0aW9uKHBUcmFuc2xhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBUcmFuc2xhdGlvbi5mcm9tUGF0dGVybi50ZXN0KHNvdXJjZVBhdGgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwdCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNsYXRlZFBhdGggPSBzb3VyY2VQYXRoLnJlcGxhY2UocHQuZnJvbVN0YXRpY1BhdGgsIHB0LnRvU3RhdGljUGF0aCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICghICgoc3Vic2NyaXB0aW9uUGF0dGVybiBpbnN0YW5jZW9mIFJlZ0V4cFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc3Vic2NyaXB0aW9uUGF0dGVybi50ZXN0KHNvdXJjZVBhdGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgc3Vic2NyaXB0aW9uUGF0dGVybiA9PSBzb3VyY2VQYXRoKSkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zbGF0ZWRQYXRoIHx8IHNvdXJjZVBhdGg7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgZnVuY3Rpb24gdHJhbnNsYXRlRGF0YShzb3VyY2VQYXRoLCBjaGFuZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YVRyYW5zbGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGUgPSBkYXRhVHJhbnNsYXRpb25bc291cmNlUGF0aF07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0cmFuc2xhdGUgJiYgdHlwZW9mIHRyYW5zbGF0ZSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2Uub2xkVmFsdWUgPSB0cmFuc2xhdGUoY2hhbmdlLm9sZFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZS5uZXdWYWx1ZSA9IHRyYW5zbGF0ZShjaGFuZ2UubmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgXG4gICAgICAgICAgICBmdW5jdGlvbiB2YWxpZGF0ZURhdGEoc291cmNlUGF0aCwgY2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgcHJvcGFnYXRlRGF0YShjaGFuZ2UpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRhdGFWYWxpZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWxpZGF0b3JzID0gZGF0YVZhbGlkYXRpb25bc291cmNlUGF0aF1cbiAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzc2VkQ291bnQgPSAwXG4gICAgICAgICAgICAgICAgICAgICAgICAsIGFscmVhZHlGYWlsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsaWRhdG9ycylcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRvcnMuZm9yRWFjaChjYWxsVmFsaWRhdG9yKTsgICBcbiAgICAgICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNhbGxWYWxpZGF0b3IodmFsaWRhdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRvcihjaGFuZ2UubmV3VmFsdWUsIGZ1bmN0aW9uKGVyciwgcmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnBhdGggPSBzb3VyY2VQYXRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEgYWxyZWFkeUZhaWxlZCAmJiAoZXJyIHx8IHJlc3BvbnNlLnZhbGlkKSAmJiArK3Bhc3NlZENvdW50ID09IHZhbGlkYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbURTLnBvc3RNZXNzYWdlKCd2YWxpZGF0ZWQnLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEgcmVzcG9uc2UudmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHJlYWR5RmFpbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tRFMucG9zdE1lc3NhZ2UoJ3ZhbGlkYXRlZCcsIHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHByb3BhZ2F0ZURhdGEoY2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgc2VuZERhdGEuY2hhbmdlcy5wdXNoKGNoYW5nZSk7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgZnVuY3Rpb24gcG9zdENoYW5nZURhdGEoKSB7XG4gICAgICAgICAgICAgICAgLy8gcHJldmVudCBlbmRsZXNzIGxvb3Agb2YgdXBkYXRlcyBmb3IgMi13YXkgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGlmIChzZWxmW3JldmVyc2VMaW5rXSkgdmFyIGNhbGxiYWNrID0gc3Vic2NyaXB0aW9uU3dpdGNoO1xuXG4gICAgICAgICAgICAgICAgdmFyIHRyYW5zYWN0aW9ucyA9IG1lcmdlVHJhbnNhY3Rpb25zKGNoYW5nZXNRdWV1ZSk7XG4gICAgICAgICAgICAgICAgY2hhbmdlc1F1ZXVlLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zLmZvckVhY2goZnVuY3Rpb24odHJhbnNhY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2VuZCBkYXRhIGNoYW5nZSBpbnN0cnVjdGlvbiBhcyBtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIHRvRFMucG9zdE1lc3NhZ2VTeW5jKCdjaGFuZ2VkYXRhJywgeyBjaGFuZ2VzOiB0cmFuc2FjdGlvbiB9LCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgZnVuY3Rpb24gc3Vic2NyaXB0aW9uU3dpdGNoKGVyciwgY2hhbmdlRmluaXNoZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSByZXR1cm47XG4gICAgICAgICAgICAgICAgdmFyIG9uT2ZmID0gY2hhbmdlRmluaXNoZWQgPyAnb25TeW5jJyA6ICdvZmYnO1xuICAgICAgICAgICAgICAgIHRvRFNbb25PZmZdKCdkYXRhY2hhbmdlcycsIHNlbGZbcmV2ZXJzZUxpbmtdKTtcblxuICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gY2hhbmdlRmluaXNoZWQgPyAnY2hhbmdlY29tcGxldGVkJyA6ICdjaGFuZ2VzdGFydGVkJztcbiAgICAgICAgICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIHsgc291cmNlOiBmcm9tRFMsIHRhcmdldDogdG9EUyB9KTtcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICBmdW5jdGlvbiBtZXJnZVRyYW5zYWN0aW9ucyhiYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRyYW5zYWN0aW9ucyA9IFtdXG4gICAgICAgICAgICAgICAgICAgICwgY3VycmVudFRyYW5zYWN0aW9uO1xuXG4gICAgICAgICAgICAgICAgYmF0Y2hlcy5mb3JFYWNoKGZ1bmN0aW9uKGJhdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIGJhdGNoLnRyYW5zYWN0aW9uKSBjdXJyZW50VHJhbnNhY3Rpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIGJhdGNoLmNoYW5nZXMubGVuZ3RoKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGJhdGNoLnRyYW5zYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFRyYW5zYWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uYXBwZW5kQXJyYXkoY3VycmVudFRyYW5zYWN0aW9uLCBiYXRjaC5jaGFuZ2VzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRUcmFuc2FjdGlvbiA9IF8uY2xvbmUoYmF0Y2guY2hhbmdlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zLnB1c2goY3VycmVudFRyYW5zYWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbnMucHVzaChiYXRjaC5jaGFuZ2VzKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2FjdGlvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuLyoqXG4gKiB0dXJuT2ZmXG4gKiBNZXRob2Qgb2YgQ29ubmVjdG9yIHRoYXQgZGlzYWJsZXMgY29ubmVjdGlvbiAoaWYgaXQgd2FzIHByZXZpb3VzbHkgZW5hYmxlZClcbiAqL1xuZnVuY3Rpb24gQ29ubmVjdG9yJHR1cm5PZmYoKSB7XG4gICAgaWYgKCEgdGhpcy5pc09uKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ2RhdGEgc291cmNlcyBhcmUgYWxyZWFkeSBkaXNjb25uZWN0ZWQnKTtcblxuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB1bmxpbmtEYXRhU291cmNlKHRoaXMuZHMxLCAnX2xpbmsyJywgdGhpcy5wYXRoVHJhbnNsYXRpb24yKTtcbiAgICB1bmxpbmtEYXRhU291cmNlKHRoaXMuZHMyLCAnX2xpbmsxJywgdGhpcy5wYXRoVHJhbnNsYXRpb24xKTtcblxuICAgIHRoaXMuaXNPbiA9IGZhbHNlO1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoJ3R1cm5lZG9mZicpO1xuXG5cbiAgICBmdW5jdGlvbiB1bmxpbmtEYXRhU291cmNlKGZyb21EUywgbGlua05hbWUsIHBhdGhUcmFuc2xhdGlvbikge1xuICAgICAgICBpZiAoc2VsZltsaW5rTmFtZV0pIHtcbiAgICAgICAgICAgIGZyb21EUy5vZmYoJ2RhdGFjaGFuZ2VzJywgc2VsZltsaW5rTmFtZV0pO1xuICAgICAgICAgICAgZGVsZXRlIHNlbGZbbGlua05hbWVdO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5cbi8qKlxuICogRGVzdHJveXMgY29ubmVjdG9yIG9iamVjdCBieSB0dXJuaW5nIGl0IG9mZiBhbmQgcmVtb3ZpbmcgcmVmZXJlbmNlcyB0byBjb25uZWN0ZWQgc291cmNlc1xuICovXG5mdW5jdGlvbiBDb25uZWN0b3IkZGVzdHJveSgpIHtcbiAgICB0aGlzLnR1cm5PZmYoKTtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKCdkZXN0cm95ZWQnKTtcbiAgICB0aGlzLl9tZXNzZW5nZXIuZGVzdHJveSgpO1xuICAgIGRlbGV0ZSB0aGlzLmRzMTtcbiAgICBkZWxldGUgdGhpcy5kczI7XG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1vZGVsUGF0aCA9IHJlcXVpcmUoJy4vbV9wYXRoJylcbiAgICAsIHN5bnRoZXNpemUgPSByZXF1aXJlKCcuL3N5bnRoZXNpemUnKVxuICAgICwgcGF0aFV0aWxzID0gcmVxdWlyZSgnLi9wYXRoX3V0aWxzJylcbiAgICAsIGNoYW5nZURhdGFIYW5kbGVyID0gcmVxdWlyZSgnLi9jaGFuZ2VfZGF0YScpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4uL21lc3Nlbmdlci9tc25ncl9zb3VyY2UnKVxuICAgICwgTW9kZWxNc2dBUEkgPSByZXF1aXJlKCcuL21fbXNnX2FwaScpXG4gICAgLCBNb2RlbEVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLk1vZGVsXG4gICAgLCBNaXhpbiA9IHJlcXVpcmUoJy4uL2Fic3RyYWN0L21peGluJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2hcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGpzb25QYXJzZSA9IHJlcXVpcmUoJy4uL3V0aWwvanNvbl9wYXJzZScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTW9kZWw7XG5cblxuLyoqXG4gKiBgbWlsby5Nb2RlbGBcbiAqIE1vZGVsIGNsYXNzIGluc3RhbnRpYXRlcyBvYmplY3RzIHRoYXQgYWxsb3cgZGVlcCBkYXRhIGFjY2VzcyB3aXRoIF9fc2FmZSBnZXR0ZXJzX18gdGhhdCByZXR1cm4gdW5kZWZpbmVkIChyYXRoZXIgdGhhbiB0aHJvd2luZyBleGNlcHRpb24pIHdoZW4gcHJvcGVydGllcy9pdGVtcyBvZiB1bmV4aXN0aW5nIG9iamVjdHMvYXJyYXlzIGFyZSByZXF1ZXN0ZWQgYW5kIF9fc2FmZSBzZXR0ZXJzX18gdGhhdCBjcmVhdGUgb2JqZWN0IHRyZWVzIHdoZW4gcHJvcGVydGllcy9pdGVtcyBvZiB1bmV4aXN0aW5nIG9iamVjdHMvYXJyYXlzIGFyZSBzZXQgYW5kIGFsc28gcG9zdCBtZXNzYWdlcyB0byBhbGxvdyBzdWJzY3JpcHRpb24gb24gY2hhbmdlcyBhbmQgZW5hYmxlIGRhdGEgcmVhY3Rpdml0eS5cbiAqIFJlYWN0aXZpdHkgaXMgaW1wbGVtZW1udGVkIHZpYSBbQ29ubmVjdG9yXSguL2Nvbm5lY3Rvci5qcy5odG1sKSB0aGF0IGNhbiBiZSBpbnN0YW50aWF0ZWQgZWl0aGVyIGRpcmVjdGx5IG9yIHdpdGggbW9yZSBjb252ZW5pZW50IGludGVyZmFjZSBvZiBbbWlsby5taW5kZXJdKC4uL21pbmRlci5qcy5odG1sKS4gQXQgdGhlIG1vbWVudCBtb2RlbCBjYW4gYmUgY29ubmVjdGVkIHRvIFtEYXRhIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL0RhdGEuanMuaHRtbCkgb3IgdG8gYW5vdGhlciBtb2RlbCBvciBbTW9kZWxQYXRoXSguL21fcGF0aC5qcy5odG1sKS5cbiAqIE1vZGVsIGNvbnN0cnVjdG9yIHJldHVybnMgb2JqZWN0cyB0aGF0IGFyZSBmdW5jdGlvbnMgYXQgdGhlIHNhbWUgdGltZTsgd2hlbiBjYWxsZWQgdGhleSByZXR1cm4gTW9kZWxQYXRoIG9iamVjdHMgdGhhdCBhbGxvdyBnZXQvc2V0IGFjY2VzcyB0byBhbnkgcG9pbnQgaW4gbW9kZWwgZGF0YS4gU2VlIFtNb2RlbERhdGFdKCNNb2RlbERhdGEpIGJlbG93LlxuICpcbiAqIFlvdSBjYW4gc3Vic2NyaWJlIHRvIG1vZGVsIGNoYW5nZXMgd2l0aCBgb25gIG1ldGhvZCBieSBwYXNzaW5nIG1vZGVsIGFjY2VzcyBwYXRoIGluIHBsYWNlIG9mIG1lc3NhZ2UsIHBhdHRlcm4gb3Igc3RyaW5nIHdpdGggYW55IG51bWJlciBvZiBzdGFycyB0byBzdWJzY3JpYmUgdG8gYSBjZXJ0YWluIGRlcHRoIGluIG1vZGVsIChlLmcuLCBgJyoqKidgIHRvIHN1YnNjcmliZSB0byB0aHJlZSBsZXZlbHMpLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IGRhdGEgb3B0aW9uYWwgaW5pdGlhbCBhcnJheSBkYXRhLiBJZiBpdCBpcyBwbGFubmVkIHRvIGNvbm5lY3QgbW9kZWwgdG8gdmlldyBpdCBpcyB1c3VhbGx5IGJldHRlciB0byBpbnN0YW50aWF0ZSBhbiBlbXB0eSBNb2RlbCAoYHZhciBtID0gbmV3IE1vZGVsYCksIGNvbm5lY3QgaXQgdG8gW0NvbXBvbmVudF0oLi4vY29tcG9uZW50cy9jX2NsYXNzLmpzLmh0bWwpJ3MgW0RhdGEgZmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldHMvRGF0YS5qcy5odG1sKSAoZS5nLiwgYG1pbG8ubWluZGVyKG0sICc8PC0+PicsIGMuZGF0YSk7YCkgYW5kIHRoZW4gc2V0IHRoZSBtb2RlbCB3aXRoIGBtLnNldChkYXRhKWAgLSB0aGUgdmlldyB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXBkYXRlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IG9wdGlvbmFsIG9iamVjdCB0aGF0IGhvc3RzIG1vZGVsIG9uIG9uZSBvZiBpdHMgcHJvcGVydGllcy4gQ2FuIGJlIHVzZWQgd2hlbiBtb2RlbCBpdHNlbGYgaXMgdGhlIGNvbnRleHQgb2YgdGhlIG1lc3NhZ2Ugc3Vic2NyaWJlciBhbmQgeW91IG5lZWQgdG8gdHJhdmVycyB0byB0aGlzIG9iamVjdCAoYWx0aG91Z2ggaXQgaXMgcG9zc2libGUgdG8gc2V0IGFueSBjb250ZXh0KS4gQ2FuIGFsc28gYmUgdXNlZCB0byBwcm94eSBtb2RlbCdzIG1ldGhvZHMgdG8gdGhlIGhvc3QgbGlrZSBbTW9kZWwgZmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldHMvTW9kZWxGYWNldC5qcy5odG1sKSBpcyBkb2luZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHBhc3MgeyByZWFjdGl2ZTogZmFsc2UgfSB0byB1c2UgbW9kZWwgd2l0aG91dCBtZXNzYWdpbmcgd2hlbiBpdCBpcyBub3QgbmVlZGVkIC0gaXQgbWFrZXMgaXQgbXVjaCBmYXN0ZXJcbiAqIEByZXR1cm4ge01vZGVsfVxuICovXG5mdW5jdGlvbiBNb2RlbChkYXRhLCBob3N0T2JqZWN0LCBvcHRpb25zKSB7XG4gICAgLy8gYG1vZGVsYCB3aWxsIGJlIHJldHVybmVkIGJ5IGNvbnN0cnVjdG9yIGluc3RlYWQgb2YgYHRoaXNgLiBgbW9kZWxgXG4gICAgLy8gKGBtb2RlbFBhdGhgIGZ1bmN0aW9uKSBzaG91bGQgcmV0dXJuIGEgTW9kZWxQYXRoIG9iamVjdCB3aXRoIFwic3ludGhlc2l6ZWRcIiBtZXRob2RzXG4gICAgLy8gdG8gZ2V0L3NldCBtb2RlbCBwcm9wZXJ0aWVzLCB0byBzdWJzY3JpYmUgdG8gcHJvcGVydHkgY2hhbmdlcywgZXRjLlxuICAgIC8vIEFkZGl0aW9uYWwgYXJndW1lbnRzIG9mIG1vZGVsUGF0aCBjYW4gYmUgdXNlZCBpbiB0aGUgcGF0aCB1c2luZyBpbnRlcnBvbGF0aW9uIC0gc2VlIE1vZGVsUGF0aCBiZWxvdy5cbiAgICB2YXIgbW9kZWwgPSBmdW5jdGlvbiBtb2RlbFBhdGgoYWNjZXNzUGF0aCkgeyAvLyAsIC4uLiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGludGVycG9sYXRlZFxuICAgICAgICByZXR1cm4gTW9kZWwkcGF0aC5hcHBseShtb2RlbCwgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIG1vZGVsLl9fcHJvdG9fXyA9IE1vZGVsLnByb3RvdHlwZTtcblxuICAgIG1vZGVsLl9ob3N0T2JqZWN0ID0gaG9zdE9iamVjdDtcbiAgICBtb2RlbC5fb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAobW9kZWwuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XG4gICAgICAgIG1vZGVsLl9wcmVwYXJlTWVzc2VuZ2VycygpO1xuICAgICAgICAvLyBzdWJzY3JpYmUgdG8gXCJjaGFuZ2VkYXRhXCIgbWVzc2FnZSB0byBlbmFibGUgcmVhY3RpdmUgY29ubmVjdGlvbnNcbiAgICAgICAgbW9kZWwub25TeW5jKCdjaGFuZ2VkYXRhJywgY2hhbmdlRGF0YUhhbmRsZXIpO1xuICAgIH1cblxuICAgIGlmIChkYXRhKSBtb2RlbC5fZGF0YSA9IGRhdGE7XG5cbiAgICByZXR1cm4gbW9kZWw7XG59XG5cbk1vZGVsLnByb3RvdHlwZS5fX3Byb3RvX18gPSBNb2RlbC5fX3Byb3RvX187XG5cblxuLyoqXG4gKiAjIyMjTW9kZWwgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtwYXRoXSgjcGF0aCkgLSByZXR1cm5zIE1vZGVsUGF0aCBvYmplY3QgdGhhdCBhbGxvd3MgYWNjZXNzIHRvIGFueSBwb2ludCBpbiBNb2RlbFxuICogLSBbZ2V0XSgjTW9kZWwkZ2V0KSAtIGdldCBtb2RlbCBkYXRhXG4gKiAtIHNldCAtIHNldCBtb2RlbCBkYXRhLCBzeW50aGVzaXplZFxuICogLSBzcGxpY2UgLSBzcGxpY2UgbW9kZWwgZGF0YSAoYXMgYXJyYXkgb3IgcHNldWRvLWFycmF5KSwgc3ludGhlc2l6ZWRcbiAqIC0gW2xlbl0oLi9tX3BhdGguanMuaHRtbCNNb2RlbFBhdGgkbGVuKSAtIHJldHVybnMgbGVuZ3RoIG9mIGFycmF5IChvciBwc2V1ZG8tYXJyYXkpIGluIG1vZGVsIGluIHNhZmUgd2F5LCAwIGlmIG5vIGxlbmd0aCBpcyBzZXRcbiAqIC0gW3B1c2hdKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJHB1c2gpIC0gYWRkIGl0ZW1zIHRvIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gbW9kZWxcbiAqIC0gW3BvcF0oLi9tX3BhdGguanMuaHRtbCNNb2RlbFBhdGgkcG9wKSAtIHJlbW92ZSBpdGVtIGZyb20gdGhlIGVuZCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbFxuICogLSBbdW5zaGlmdF0oLi9tX3BhdGguanMuaHRtbCNNb2RlbFBhdGgkdW5zaGlmdCkgLSBhZGQgaXRlbXMgdG8gdGhlIGJlZ2lubmluZyBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbFxuICogLSBbc2hpZnRdKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJHNoaWZ0KSAtIHJlbW92ZSBpdGVtIGZyb20gdGhlIGJlZ2lubmluZyBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbFxuICogLSBbcHJveHlNZXNzZW5nZXJdKCNwcm94eU1lc3NlbmdlcikgLSBwcm94eSBtb2RlbCdzIE1lc3NlbmdlciBtZXRob2RzIHRvIGhvc3Qgb2JqZWN0XG4gKiAtIFtwcm94eU1ldGhvZHNdKCNwcm94eU1ldGhvZHMpIC0gcHJveHkgbW9kZWwgbWV0aG9kcyB0byBob3N0IG9iamVjdFxuICovXG5fLmV4dGVuZFByb3RvKE1vZGVsLCB7XG4gICAgcGF0aDogTW9kZWwkcGF0aCxcbiAgICBnZXQ6IE1vZGVsJGdldCxcbiAgICBwcm94eU1lc3NlbmdlcjogcHJveHlNZXNzZW5nZXIsIC8vIGRlcHJlY2F0ZWQsIHNob3VsZCBub3QgYmUgdXNlZFxuICAgIHByb3h5TWV0aG9kczogcHJveHlNZXRob2RzLFxuICAgIF9wcmVwYXJlTWVzc2VuZ2VyczogX3ByZXBhcmVNZXNzZW5nZXJzLFxuICAgIF9nZXRIb3N0T2JqZWN0OiBfZ2V0SG9zdE9iamVjdCxcbiAgICBkZXN0cm95OiBNb2RlbCRkZXN0cm95XG59KTtcblxuLy8gc2V0LCBkZWwsIHNwbGljZSBhcmUgYWRkZWQgdG8gbW9kZWxcbl8uZXh0ZW5kUHJvdG8oTW9kZWwsIHN5bnRoZXNpemUubW9kZWxNZXRob2RzKTtcblxuXG4vKipcbiAqIC0gUGF0aDogTW9kZWxQYXRoIGNsYXNzIGFzIGBtaWxvLk1vZGVsLlBhdGhgXG4gKiAtIFtyZWdpc3RlcldpdGhET01TdG9yYWdlXSgjTW9kZWwkJHJlZ2lzdGVyV2l0aERPTVN0b3JhZ2UpXG4gKi9cbl8uZXh0ZW5kKE1vZGVsLCB7XG4gICAgUGF0aDogTW9kZWxQYXRoLFxuICAgIHJlZ2lzdGVyV2l0aERPTVN0b3JhZ2U6IE1vZGVsJCRyZWdpc3RlcldpdGhET01TdG9yYWdlLFxuICAgIHVzZVdpdGg6IE1vZGVsJCR1c2VXaXRoXG59KTtcblxuXG4vKipcbiAqIEV4cG9zZSBNZXNzZW5nZXIgbWV0aG9kcyBvbiBGYWNldCBwcm90b3R5cGVcbiAqL1xudmFyIE1FU1NFTkdFUl9QUk9QRVJUWSA9ICdfbWVzc2VuZ2VyJztcbk1lc3Nlbmdlci51c2VXaXRoKE1vZGVsLCBNRVNTRU5HRVJfUFJPUEVSVFksIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggbWV0aG9kcyBhZGRlZCB0byBNb2RlbCBwcm90b3R5cGVcbiAqL1xuWydsZW4nLCAncHVzaCcsICdwb3AnLCAndW5zaGlmdCcsICdzaGlmdCddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBNb2RlbFBhdGgucHJvdG90eXBlW21ldGhvZE5hbWVdO1xuICAgIF8uZGVmaW5lUHJvcGVydHkoTW9kZWwucHJvdG90eXBlLCBtZXRob2ROYW1lLCBtZXRob2QpO1xufSk7XG5cblxuLyoqXG4gKiBNb2RlbCBpbnN0YW5jZSBtZXRob2QuXG4gKiBHZXQgbW9kZWwgZGF0YS5cbiAqXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIE1vZGVsJGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGF0YTtcbn1cblxuXG4vKipcbiAqIE1vZGVsIGluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgTW9kZWxQYXRoIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIHNhbWUgQVBJIGFzIG1vZGVsIGJ1dCBhbGxvd3MgYWNjZXNzIHRvIGFueSBwb2ludCBpbnNpZGUgbW9kZWwgYXMgZGVmaW5lZCBieSBgYWNjZXNzUGF0aGAuXG4gKiBTZWUgW01vZGVsUGF0aF0oLi9tX3BhdGguanMuaHRtbCkgY2xhc3MgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2Vzc1BhdGggc3RyaW5nIHRoYXQgZGVmaW5lcyBwYXRoIHRvIGFjY2VzcyBtb2RlbC5cbiAqICBQYXRoIHN0cmluZyBjb25zaXN0cyBvZiBwYXJ0cyB0byBkZWZpbmUgZWl0aGVyIHByb3BlcnR5IGFjY2VzcyAoYFwiLm5hbWVcImAgdG8gYWNjZXNzIHByb3BlcnR5IG5hbWUpIG9yIGFycmF5IGl0ZW0gYWNjZXNzIChgXCJbMV1cImAgdG8gYWNjZXNzIGl0ZW0gd2l0aCBpbmRleCAxKS5cbiAqICBBY2Nlc3MgcGF0aCBjYW4gY29udGFpbiBhcyBtYW55IHBhcnRzIGFzIG5lY2Vzc2FyeSAoZS5nLiBgXCIubGlzdFswXS5uYW1lXCJgIHRvIGFjY2VzcyBwcm9wZXJ0eSBgbmFtZWAgaW4gdGhlIGZpcnN0IGVsZW1lbnQgb2YgYXJyYXkgc3RvcmVkIGluIHByb3BlcnR5IGBsaXN0YC5cbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFkZGl0aW9uYWwgYXJndW1lbnRzIG9mIHRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBpbnRlcnBvbGF0ZWQgcGF0aHMuXG4gKiAgRS5nLiBgbS5wYXRoKFwiWyQxXS4kMlwiLCBpZCwgcHJvcClgIHJldHVybnMgTW9kZWxQYXRoIHRvIGFjY2VzcyBwcm9wZXJ0eSB3aXRoIG5hbWUgYHByb3BgIGluIGFycmF5IGl0ZW0gd2l0aCBpbmRleCBgaWRgLiBBbHRob3VnaCB0aGlzIE1vZGVsUGF0aCBvYmplY3Qgd2lsbCB3b3JrIGV4YWN0bHkgYXMgYG0oXCJbXCIgKyBpZCArIFwiXS5cIiArIHByb3ApYCwgdGhlIGludGVycG9sYXRlZCBpcyBtdWNoIG1vcmUgZWZmaWNpZW50IGFzIE1vZGVsUGF0aCB3aXRoIGludGVycG9sYXRpb24gd2lsbCBub3Qgc3ludGhlc2l6ZSBuZXcgZ2V0dGVycyBhbmQgc2V0dGVycywgd2hpbGUgTW9kZWxQYXRoIHdpdGggY29tcHV0ZWQgYWNjZXNzIHBhdGggd2lsbCBzeW50aGVzaXplIG5ldyBnZXR0ZXJzIGFuZCBzZXR0ZXJzIGZvciBlYWNoIHBhaXIgb2YgdmFsdWVzIG9mIGBpZGAgYW5kIGBwcm9wYC5cbiAqIEByZXR1cm4ge01vZGVsUGF0aH1cbiAqL1xuZnVuY3Rpb24gTW9kZWwkcGF0aChhY2Nlc3NQYXRoKSB7ICAvLyAsIC4uLiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGludGVycG9sYXRlZFxuICAgIGlmICghIGFjY2Vzc1BhdGgpIHJldHVybiB0aGlzO1xuXG4gICAgLy8gXCJudWxsXCIgaXMgY29udGV4dCB0byBwYXNzIHRvIE1vZGVsUGF0aCwgZmlyc3QgcGFyYW1ldGVyIG9mIGJpbmRcbiAgICAvLyBcInRoaXNcIiAobW9kZWwpIGlzIGFkZGVkIGluIGZyb250IG9mIGFsbCBhcmd1bWVudHNcbiAgICBfLnNwbGljZShhcmd1bWVudHMsIDAsIDAsIG51bGwsIHRoaXMpO1xuXG4gICAgLy8gY2FsbGluZyBNb2RlbFBhdGggY29uc3RydWN0b3Igd2l0aCBuZXcgYW5kIHRoZSBsaXN0IG9mIGFyZ3VtZW50czogdGhpcyAobW9kZWwpLCBhY2Nlc3NQYXRoLCAuLi5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShNb2RlbFBhdGgsIGFyZ3VtZW50cykpO1xufVxuXG5cbi8qKlxuICogTW9kZWwgaW5zdGFuY2UgbWV0aG9kLlxuICogUHJveHkgbW9kZWwncyBNZXNzZW5nZXIgbWV0aG9kcyB0byBob3N0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbW9kZWxIb3N0T2JqZWN0IG9wdGlvbmFsIGhvc3Qgb2JqZWN0LiBJZiBub3QgcGFzc2VkLCBob3N0T2JqZWN0IHBhc3NlZCB0byBNb2RlbCBjb25zdHJ1Y3RvciB3aWxsIGJlIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHByb3h5TWVzc2VuZ2VyKG1vZGVsSG9zdE9iamVjdCkge1xuICAgIG1vZGVsSG9zdE9iamVjdCA9IG1vZGVsSG9zdE9iamVjdCB8fCB0aGlzLl9ob3N0T2JqZWN0O1xuICAgIE1peGluLnByb3RvdHlwZS5fY3JlYXRlUHJveHlNZXRob2RzLmNhbGwodGhpc1tNRVNTRU5HRVJfUFJPUEVSVFldLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMsIG1vZGVsSG9zdE9iamVjdCk7XG59XG5cblxudmFyIG1vZGVsTWV0aG9kc1RvUHJveHkgPSBbJ3BhdGgnLCAnZ2V0JywgJ3NldCcsICdkZWwnLCAnc3BsaWNlJywgJ2xlbicsICdwdXNoJywgJ3BvcCcsICd1bnNoaWZ0JywgJ3NoaWZ0J107XG5cblxuLyoqXG4gKiBFeHBvc2UgbW9kZWwgbWV0aG9kcyBvblxuICogU2VlIHNhbWUgbWV0aG9kIGluIE1peGluIGNsYXNzIGZvciBwYXJhbWV0ZXJzIG1lYW5pbmdcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBob3N0Q2xhc3NcbiAqIEBwYXJhbSB7W3R5cGVdfSBpbnN0YW5jZUtleVxuICogQHBhcmFtIHtbdHlwZV19IG1peGluTWV0aG9kcyBvcHRpb25hbFxuICovXG5mdW5jdGlvbiBNb2RlbCQkdXNlV2l0aChob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtaXhpbk1ldGhvZHMpIHtcbiAgICBtaXhpbk1ldGhvZHMgPSBtaXhpbk1ldGhvZHMgfHwgbW9kZWxNZXRob2RzVG9Qcm94eTtcbiAgICBNaXhpbi51c2VXaXRoLmNhbGwoTW9kZWwsIGhvc3RDbGFzcywgaW5zdGFuY2VLZXksIG1peGluTWV0aG9kcyk7XG59XG5cblxuLyoqXG4gKiBNb2RlbCBpbnN0YW5jZSBtZXRob2QuXG4gKiBQcm94eSBtb2RlbCBtZXRob2RzIHRvIGhvc3Qgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBtb2RlbEhvc3RPYmplY3Qgb3B0aW9uYWwgaG9zdCBvYmplY3QuIElmIG5vdCBwYXNzZWQsIGhvc3RPYmplY3QgcGFzc2VkIHRvIE1vZGVsIGNvbnN0cnVjdG9yIHdpbGwgYmUgdXNlZC5cbiAqL1xuZnVuY3Rpb24gcHJveHlNZXRob2RzKG1vZGVsSG9zdE9iamVjdCkge1xuICAgIG1vZGVsSG9zdE9iamVjdCA9IG1vZGVsSG9zdE9iamVjdCB8fCB0aGlzLl9ob3N0T2JqZWN0O1xuICAgIE1peGluLnByb3RvdHlwZS5fY3JlYXRlUHJveHlNZXRob2RzLmNhbGwodGhpcywgbW9kZWxNZXRob2RzVG9Qcm94eSwgbW9kZWxIb3N0T2JqZWN0KTtcbn1cblxuXG4vKipcbiAqIE1vZGVsIGluc3RhbmNlIG1ldGhvZC5cbiAqIENyZWF0ZSBhbmQgY29ubmVjdCBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgbW9kZWwncyBtZXNzZW5nZXJzLlxuICogRXh0ZXJuYWwgbWVzc2VuZ2VyJ3MgbWV0aG9kcyBhcmUgcHJveGllZCBvbiB0aGUgbW9kZWwgYW5kIHRoZXkgYWxsb3dzIFwiKlwiIHN1YnNjcmlwdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIF9wcmVwYXJlTWVzc2VuZ2VycygpIHtcbiAgICAvLyBtb2RlbCB3aWxsIHBvc3QgYWxsIGl0cyBjaGFuZ2VzIG9uIGludGVybmFsIG1lc3NlbmdlclxuICAgIHZhciBpbnRlcm5hbE1lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXIodGhpcywgdW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuXG4gICAgLy8gbWVzc2FnZSBzb3VyY2UgdG8gY29ubmVjdCBpbnRlcm5hbCBtZXNzZW5nZXIgdG8gZXh0ZXJuYWxcbiAgICB2YXIgaW50ZXJuYWxNZXNzZW5nZXJTb3VyY2UgPSBuZXcgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSh0aGlzLCB1bmRlZmluZWQsIG5ldyBNb2RlbE1zZ0FQSSwgaW50ZXJuYWxNZXNzZW5nZXIpO1xuXG4gICAgLy8gZXh0ZXJuYWwgbWVzc2VuZ2VyIHRvIHdoaWNoIGFsbCBtb2RlbCB1c2VycyB3aWxsIHN1YnNjcmliZSxcbiAgICAvLyB0aGF0IHdpbGwgYWxsb3cgXCIqXCIgc3Vic2NyaXB0aW9ucyBhbmQgc3VwcG9ydCBcImNoYW5nZWRhdGFcIiBtZXNzYWdlIGFwaS5cbiAgICB2YXIgZXh0ZXJuYWxNZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMsIHVuZGVmaW5lZCwgaW50ZXJuYWxNZXNzZW5nZXJTb3VyY2UpO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBNRVNTRU5HRVJfUFJPUEVSVFksIGV4dGVybmFsTWVzc2VuZ2VyKTtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfaW50ZXJuYWxNZXNzZW5nZXInLCBpbnRlcm5hbE1lc3Nlbmdlcik7XG59XG5cblxuZnVuY3Rpb24gX2dldEhvc3RPYmplY3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hvc3RPYmplY3Q7XG59XG5cblxuZnVuY3Rpb24gTW9kZWwkJHJlZ2lzdGVyV2l0aERPTVN0b3JhZ2UoKSB7XG4gICAgdmFyIERPTVN0b3JhZ2UgPSByZXF1aXJlKCcuLi91dGlsL3N0b3JhZ2UnKTtcbiAgICBET01TdG9yYWdlLnJlZ2lzdGVyRGF0YVR5cGUoJ01vZGVsJywgTW9kZWxfZG9tU3RvcmFnZVNlcmlhbGl6ZXIsIE1vZGVsX2RvbVN0b3JhZ2VQYXJzZXIpO1xuICAgIERPTVN0b3JhZ2UucmVnaXN0ZXJEYXRhVHlwZSgnTW9kZWxQYXRoJywgTW9kZWxfZG9tU3RvcmFnZVNlcmlhbGl6ZXIsIE1vZGVsX2RvbVN0b3JhZ2VQYXJzZXIsICdNb2RlbCcpO1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsX2RvbVN0b3JhZ2VTZXJpYWxpemVyKHZhbHVlKSB7XG4gICAgdmFyIGRhdGEgPSB2YWx1ZS5nZXQoKTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG59XG5cblxuZnVuY3Rpb24gTW9kZWxfZG9tU3RvcmFnZVBhcnNlcih2YWx1ZVN0cikge1xuICAgIHZhciBkYXRhID0ganNvblBhcnNlKHZhbHVlU3RyKTtcbiAgICByZXR1cm4gbmV3IE1vZGVsKGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsJGRlc3Ryb3koKSB7XG4gICAgdGhpc1tNRVNTRU5HRVJfUFJPUEVSVFldLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9pbnRlcm5hbE1lc3Nlbmdlci5kZXN0cm95KCk7XG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1lc3NlbmdlclJlZ2V4cEFQSSA9IHJlcXVpcmUoJy4uL21lc3Nlbmdlci9tX2FwaV9yeCcpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8qKlxuICogU3ViY2xhc3Mgb2YgTWVzc2VuZ2VyUmVnZXhwQVBJIHRoYXQgaXMgdXNlZCB0byB0cmFuc2xhdGUgbWVzc2FnZXMgb2YgZXh0ZXJuYWwgbWVzc2VuZ2VyIG9mIE1vZGVsIHRvIGludGVybmFsIG1lc3NlbmdlciBvZiBNb2RlbC5cbiAqL1xudmFyIE1vZGVsTXNnQVBJID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzZW5nZXJSZWdleHBBUEksICdNb2RlbE1zZ0FQSScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsTXNnQVBJO1xuXG5cbi8qKlxuICogIyMjI01vZGVsTXNnQVBJIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlXSgjdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKSAtIHRyYW5zbGF0ZXMgc3Vic2NyaXB0aW9uIHBhdGhzIHdpdGggXCIqXCJzIHRvIHJlZ2V4LCBsZWF2aW5nIG90aGVyIHN0cmluZ3MgdW50b3VjaGVkXG4gKi9cbl8uZXh0ZW5kUHJvdG8oTW9kZWxNc2dBUEksIHtcbiAgICB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2U6IHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZSxcbn0pO1xuXG5cbi8qKlxuICogTW9kZWxNc2dBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBUcmFuc2xhdGVzIHN1YnNjcmlwdGlvbiBwYXRocyB3aXRoIFwiKlwicyB0byByZWdleCwgbGVhdmluZyBvdGhlciBzdHJpbmdzIHVudG91Y2hlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXNzUGF0aCByZWxhdGl2ZSBhY2Nlc3MgcGF0aCB0byBiZSB0cmFuc2xhdGVkXG4gKiBAcmV0dXJuIHtSZWdFeHB8U3RyaW5nfVxuICovXG5mdW5jdGlvbiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UoYWNjZXNzUGF0aCkge1xuICAgIGlmIChhY2Nlc3NQYXRoIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gYWNjZXNzUGF0aDtcblxuICAgIHJldHVybiBwYXRoVXRpbHMuY3JlYXRlUmVnZXhQYXRoKGFjY2Vzc1BhdGgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgc3ludGhlc2l6ZSA9IHJlcXVpcmUoJy4vc3ludGhlc2l6ZScpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgY2hhbmdlRGF0YUhhbmRsZXIgPSByZXF1aXJlKCcuL2NoYW5nZV9kYXRhJylcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uL21lc3NlbmdlcicpXG4gICAgLCBNb2RlbFBhdGhNc2dBUEkgPSByZXF1aXJlKCcuL3BhdGhfbXNnX2FwaScpXG4gICAgLCBNZXNzZW5nZXJNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyL21zbmdyX3NvdXJjZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTW9kZWxQYXRoO1xuXG5cbi8qKlxuICogYG1pbG8uTW9kZWwuUGF0aGBcbiAqIE1vZGVsUGF0aCBvYmplY3QgdGhhdCBhbGxvd3MgYWNjZXNzIHRvIGFueSBwb2ludCBpbnNpZGUgW01vZGVsXSguL2luZGV4LmpzLmh0bWwpIGFzIGRlZmluZWQgYnkgYGFjY2Vzc1BhdGhgXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge01vZGVsfSBtb2RlbCBNb2RlbCBpbnN0YW5jZSB0aGF0IE1vZGVsUGF0aCBnaXZlcyBhY2Nlc3MgdG8uXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXNzUGF0aCBzdHJpbmcgdGhhdCBkZWZpbmVzIHBhdGggdG8gYWNjZXNzIG1vZGVsLlxuICogIFBhdGggc3RyaW5nIGNvbnNpc3RzIG9mIHBhcnRzIHRvIGRlZmluZSBlaXRoZXIgcHJvcGVydHkgYWNjZXNzIChgXCIubmFtZVwiYCB0byBhY2Nlc3MgcHJvcGVydHkgbmFtZSkgb3IgYXJyYXkgaXRlbSBhY2Nlc3MgKGBcIlsxXVwiYCB0byBhY2Nlc3MgaXRlbSB3aXRoIGluZGV4IDEpLlxuICogIEFjY2VzcyBwYXRoIGNhbiBjb250YWluIGFzIG1hbnkgcGFydHMgYXMgbmVjZXNzYXJ5IChlLmcuIGBcIi5saXN0WzBdLm5hbWVcImAgdG8gYWNjZXNzIHByb3BlcnR5IGBuYW1lYCBpbiB0aGUgZmlyc3QgZWxlbWVudCBvZiBhcnJheSBzdG9yZWQgaW4gcHJvcGVydHkgYGxpc3RgLlxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgYWRkaXRpb25hbCBhcmd1bWVudHMgb2YgdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGludGVycG9sYXRlZCBwYXRocy5cbiAqICBFLmcuIGBtLnBhdGgoXCJbJDFdLiQyXCIsIGlkLCBwcm9wKWAgcmV0dXJucyBNb2RlbFBhdGggdG8gYWNjZXNzIHByb3BlcnR5IHdpdGggbmFtZSBgcHJvcGAgaW4gYXJyYXkgaXRlbSB3aXRoIGluZGV4IGBpZGAuIEFsdGhvdWdoIHRoaXMgTW9kZWxQYXRoIG9iamVjdCB3aWxsIHdvcmsgZXhhY3RseSBhcyBgbShcIltcIiArIGlkICsgXCJdLlwiICsgcHJvcClgLCB0aGUgaW50ZXJwb2xhdGVkIGlzIG11Y2ggbW9yZSBlZmZpY2llbnQgYXMgTW9kZWxQYXRoIHdpdGggaW50ZXJwb2xhdGlvbiB3aWxsIG5vdCBzeW50aGVzaXplIG5ldyBnZXR0ZXJzIGFuZCBzZXR0ZXJzLCB3aGlsZSBNb2RlbFBhdGggd2l0aCBjb21wdXRlZCBhY2Nlc3MgcGF0aCB3aWxsIHN5bnRoZXNpemUgbmV3IGdldHRlcnMgYW5kIHNldHRlcnMgZm9yIGVhY2ggcGFpciBvZiB2YWx1ZXMgb2YgYGlkYCBhbmQgYHByb3BgLlxuICogQHJldHVybiB7TW9kZWxQYXRofVxuICovXG5mdW5jdGlvbiBNb2RlbFBhdGgobW9kZWwsIHBhdGgpIHsgLy8gLC4uLiAtIGFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciBpbnRlcnBvbGF0aW9uXG4gICAgLy8gY2hlY2sobW9kZWwsIE1vZGVsKTtcbiAgICBjaGVjayhwYXRoLCBTdHJpbmcpO1xuXG4gICAgLy8gYG1vZGVsUGF0aGAgd2lsbCBiZSByZXR1cm5lZCBieSBjb25zdHJ1Y3RvciBpbnN0ZWFkIG9mIGB0aGlzYC4gYG1vZGVsUGF0aGBcbiAgICAvLyAoYG1vZGVsUGF0aF9wYXRoYCBmdW5jdGlvbikgc2hvdWxkIGFsc28gcmV0dXJuIGEgTW9kZWxQYXRoIG9iamVjdCB3aXRoIFwic3ludGhlc2l6ZWRcIiBtZXRob2RzXG4gICAgLy8gdG8gZ2V0L3NldCBtb2RlbCBwcm9wZXJ0aWVzLCB0byBzdWJzY3JpYmUgdG8gcHJvcGVydHkgY2hhbmdlcywgZXRjLlxuICAgIC8vIEFkZGl0aW9uYWwgYXJndW1lbnRzIG9mIG1vZGVsUGF0aCBjYW4gYmUgdXNlZCBpbiB0aGUgcGF0aCB1c2luZyBpbnRlcnBvbGF0aW9uIC0gc2VlIE1vZGVsUGF0aCBiZWxvdy5cbiAgICB2YXIgbW9kZWxQYXRoID0gZnVuY3Rpb24gbW9kZWxQYXRoX3BhdGgoYWNjZXNzUGF0aCkgeyAvLyAsIC4uLiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGludGVycG9sYXRlZFxuICAgICAgICByZXR1cm4gTW9kZWxQYXRoJHBhdGguYXBwbHkobW9kZWxQYXRoLCBhcmd1bWVudHMpO1xuICAgIH07XG4gICAgbW9kZWxQYXRoLl9fcHJvdG9fXyA9IE1vZGVsUGF0aC5wcm90b3R5cGU7XG5cblxuICAgIF8uZGVmaW5lUHJvcGVydGllcyhtb2RlbFBhdGgsIHtcbiAgICAgICAgX21vZGVsOiBtb2RlbCxcbiAgICAgICAgX3BhdGg6IHBhdGgsXG4gICAgICAgIF9hcmdzOiBfLnNsaWNlKGFyZ3VtZW50cywgMSksIC8vIHBhdGggd2lsbCBiZSB0aGUgZmlyc3QgZWxlbWVudCBvZiB0aGlzIGFycmF5XG4gICAgICAgIF9vcHRpb25zOiBtb2RlbC5fb3B0aW9uc1xuICAgIH0pO1xuXG4gICAgLy8gcGFyc2UgYWNjZXNzIHBhdGhcbiAgICB2YXIgcGFyc2VkUGF0aCA9IHBhdGhVdGlscy5wYXJzZUFjY2Vzc1BhdGgocGF0aCk7XG5cbiAgICAvLyBjb21wdXRlIGFjY2VzcyBwYXRoIHN0cmluZ1xuICAgIF8uZGVmaW5lUHJvcGVydHkobW9kZWxQYXRoLCAnX2FjY2Vzc1BhdGgnLCBpbnRlcnBvbGF0ZUFjY2Vzc1BhdGgocGFyc2VkUGF0aCwgbW9kZWxQYXRoLl9hcmdzKSk7XG5cbiAgICBpZiAobW9kZWxQYXRoLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xuICAgICAgICAvLyBtZXNzZW5nZXIgZmFpbHMgb24gXCIqXCIgc3Vic2NyaXB0aW9uc1xuICAgICAgICBtb2RlbFBhdGguX3ByZXBhcmVNZXNzZW5nZXIoKTtcbiAgICAgICAgLy8gc3Vic2NyaWJlIHRvIFwiY2hhbmdlZGF0YVwiIG1lc3NhZ2UgdG8gZW5hYmxlIHJlYWN0aXZlIGNvbm5lY3Rpb25zXG4gICAgICAgIG1vZGVsUGF0aC5vblN5bmMoJ2NoYW5nZWRhdGEnLCBjaGFuZ2VEYXRhSGFuZGxlcik7XG4gICAgfVxuXG4gICAgLy8gY29tcGlsaW5nIGdldHRlciBhbmQgc2V0dGVyXG4gICAgdmFyIG1ldGhvZHMgPSBzeW50aGVzaXplKHBhdGgsIHBhcnNlZFBhdGgpO1xuXG4gICAgLy8gYWRkaW5nIG1ldGhvZHMgdG8gbW9kZWwgcGF0aFxuICAgIF8uZGVmaW5lUHJvcGVydGllcyhtb2RlbFBhdGgsIG1ldGhvZHMpO1xuXG4gICAgT2JqZWN0LmZyZWV6ZShtb2RlbFBhdGgpO1xuXG4gICAgcmV0dXJuIG1vZGVsUGF0aDtcbn1cblxuTW9kZWxQYXRoLnByb3RvdHlwZS5fX3Byb3RvX18gPSBNb2RlbFBhdGguX19wcm90b19fO1xuXG5cbi8qKlxuICogSW50ZXJwb2xhdGVzIHBhdGggZWxlbWVudHMgdG8gY29tcHV0ZSByZWFsIHBhdGhcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYXJzZWRQYXRoIHBhcnNlZCBwYXRoIC0gYXJyYXkgb2YgcGF0aCBub2Rlc1xuICogQHBhcmFtIHtBcnJheX0gYXJncyBwYXRoIGludGVycG9sYXRpb24gYXJndW1lbnRzLCBhcmdzWzBdIGlzIHBhdGggaXRzZWxmXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGludGVycG9sYXRlQWNjZXNzUGF0aChwYXJzZWRQYXRoLCBhcmdzKSB7XG4gICAgcmV0dXJuIHBhcnNlZFBhdGgucmVkdWNlKGZ1bmN0aW9uKGFjY2Vzc1BhdGhTdHIsIGN1cnJOb2RlLCBpbmRleCkge1xuICAgICAgICB2YXIgaW50ZXJwb2xhdGUgPSBjdXJyTm9kZS5pbnRlcnBvbGF0ZTtcbiAgICAgICAgcmV0dXJuIGFjY2Vzc1BhdGhTdHIgK1xuICAgICAgICAgICAgICAgIChpbnRlcnBvbGF0ZVxuICAgICAgICAgICAgICAgICAgICA/IChjdXJyTm9kZS5zeW50YXggPT0gJ2FycmF5J1xuICAgICAgICAgICAgICAgICAgICAgICAgPyAnWycgKyBhcmdzW2ludGVycG9sYXRlXSArICddJ1xuICAgICAgICAgICAgICAgICAgICAgICAgOiAnLicgKyBhcmdzW2ludGVycG9sYXRlXSlcbiAgICAgICAgICAgICAgICAgICAgOiBjdXJyTm9kZS5wcm9wZXJ0eSk7XG4gICAgfSwgJycpO1xufVxuXG5cbi8qKlxuICogIyMjI01vZGVsUGF0aCBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW3BhdGhdKCNNb2RlbFBhdGgkcGF0aCkgLSBnaXZlcyBhY2Nlc3MgdG8gcGF0aCBpbnNpZGUgTW9kZWxQYXRoXG4gKiAtIGdldCAtIHN5bnRoZXNpemVkXG4gKiAtIHNldCAtIHN5bnRoZXNpemVkXG4gKiAtIHNwbGljZSAtIHNwbGljZSBtb2RlbCBkYXRhIChhcyBhcnJheSBvciBwc2V1ZG8tYXJyYXkpLCBzeW50aGVzaXplZFxuICogLSBbbGVuXSgjTW9kZWxQYXRoJGxlbikgLSByZXR1cm5zIGxlbmd0aCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBzYWZlIHdheSwgMCBpZiBubyBsZW5ndGggaXMgc2V0XG4gKiAtIFtwdXNoXSgjTW9kZWxQYXRoJHB1c2gpIC0gYWRkIGl0ZW1zIHRvIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gTW9kZWxQYXRoXG4gKiAtIFtwb3BdKCNNb2RlbFBhdGgkcG9wKSAtIHJlbW92ZSBpdGVtIGZyb20gdGhlIGVuZCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBNb2RlbFBhdGhcbiAqIC0gW3Vuc2hpZnRdKCNNb2RlbFBhdGgkdW5zaGlmdCkgLSBhZGQgaXRlbXMgdG8gdGhlIGJlZ2lubmluZyBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBNb2RlbFBhdGhcbiAqIC0gW3NoaWZ0XSgjTW9kZWxQYXRoJHNoaWZ0KSAtIHJlbW92ZSBpdGVtIGZyb20gdGhlIGJlZ2lubmluZyBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBNb2RlbFBhdGhcbiAqL1xuXy5leHRlbmRQcm90byhNb2RlbFBhdGgsIHtcbiAgICBwYXRoOiBNb2RlbFBhdGgkcGF0aCxcbiAgICBsZW46IE1vZGVsUGF0aCRsZW4sXG4gICAgcHVzaDogTW9kZWxQYXRoJHB1c2gsXG4gICAgcG9wOiBNb2RlbFBhdGgkcG9wLFxuICAgIHVuc2hpZnQ6IE1vZGVsUGF0aCR1bnNoaWZ0LFxuICAgIHNoaWZ0OiBNb2RlbFBhdGgkc2hpZnQsXG4gICAgX3ByZXBhcmVNZXNzZW5nZXI6IF9wcmVwYXJlTWVzc2VuZ2VyLFxuICAgIF9nZXREZWZpbml0aW9uOiBfZ2V0RGVmaW5pdGlvbixcbiAgICBkZXN0cm95OiBNb2RlbFBhdGgkZGVzdHJveVxufSk7XG5cblxuXy5leHRlbmQoTW9kZWxQYXRoLCB7XG4gICAgX2NyZWF0ZUZyb21EZWZpbml0aW9uOiBfY3JlYXRlRnJvbURlZmluaXRpb25cbn0pXG5cblxuLyoqXG4gKiBFeHBvc2UgTWVzc2VuZ2VyIG1ldGhvZHMgb24gRmFjZXQgcHJvdG90eXBlXG4gKi9cbnZhciBNRVNTRU5HRVJfUFJPUEVSVFkgPSAnX21lc3Nlbmdlcic7XG5NZXNzZW5nZXIudXNlV2l0aChNb2RlbFBhdGgsIE1FU1NFTkdFUl9QUk9QRVJUWSwgTWVzc2VuZ2VyLmRlZmF1bHRNZXRob2RzKTtcblxuXG4vKipcbiAqIE1vZGVsUGF0aCBpbnN0YW5jZSBtZXRob2RcbiAqIEdpdmVzIGFjY2VzcyB0byBwYXRoIGluc2lkZSBNb2RlbFBhdGguIE1ldGhvZCB3b3JrcyBzaW1pbGFybHkgdG8gW3BhdGggbWV0aG9kXSgjTW9kZWwkcGF0aCkgb2YgbW9kZWwsIHVzaW5nIHJlbGF0aXZlIHBhdGhzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2Nlc3NQYXRoIHN0cmluZyB0aGF0IGRlZmluZXMgcGF0aCB0byBhY2Nlc3MgbW9kZWwuXG4gKiAgUGF0aCBzdHJpbmcgY29uc2lzdHMgb2YgcGFydHMgdG8gZGVmaW5lIGVpdGhlciBwcm9wZXJ0eSBhY2Nlc3MgKGBcIi5uYW1lXCJgIHRvIGFjY2VzcyBwcm9wZXJ0eSBuYW1lKSBvciBhcnJheSBpdGVtIGFjY2VzcyAoYFwiWzFdXCJgIHRvIGFjY2VzcyBpdGVtIHdpdGggaW5kZXggMSkuXG4gKiAgQWNjZXNzIHBhdGggY2FuIGNvbnRhaW4gYXMgbWFueSBwYXJ0cyBhcyBuZWNlc3NhcnkgKGUuZy4gYFwiLmxpc3RbMF0ubmFtZVwiYCB0byBhY2Nlc3MgcHJvcGVydHkgYG5hbWVgIGluIHRoZSBmaXJzdCBlbGVtZW50IG9mIGFycmF5IHN0b3JlZCBpbiBwcm9wZXJ0eSBgbGlzdGAuXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBhZGRpdGlvbmFsIGFyZ3VtZW50cyBvZiB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgaW50ZXJwb2xhdGVkIHBhdGhzLlxuICogIEUuZy4gYG0ucGF0aChcIlskMV0uJDJcIiwgaWQsIHByb3ApYCByZXR1cm5zIE1vZGVsUGF0aCB0byBhY2Nlc3MgcHJvcGVydHkgd2l0aCBuYW1lIGBwcm9wYCBpbiBhcnJheSBpdGVtIHdpdGggaW5kZXggYGlkYC4gQWx0aG91Z2ggdGhpcyBNb2RlbFBhdGggb2JqZWN0IHdpbGwgd29yayBleGFjdGx5IGFzIGBtKFwiW1wiICsgaWQgKyBcIl0uXCIgKyBwcm9wKWAsIHRoZSBpbnRlcnBvbGF0ZWQgaXMgbXVjaCBtb3JlIGVmZmljaWVudCBhcyBNb2RlbFBhdGggd2l0aCBpbnRlcnBvbGF0aW9uIHdpbGwgbm90IHN5bnRoZXNpemUgbmV3IGdldHRlcnMgYW5kIHNldHRlcnMsIHdoaWxlIE1vZGVsUGF0aCB3aXRoIGNvbXB1dGVkIGFjY2VzcyBwYXRoIHdpbGwgc3ludGhlc2l6ZSBuZXcgZ2V0dGVycyBhbmQgc2V0dGVycyBmb3IgZWFjaCBwYWlyIG9mIHZhbHVlcyBvZiBgaWRgIGFuZCBgcHJvcGAuXG4gKiBAcmV0dXJuIHtNb2RlbFBhdGh9XG4gKi9cbmZ1bmN0aW9uIE1vZGVsUGF0aCRwYXRoKGFjY2Vzc1BhdGgpIHsgIC8vICwgLi4uIGFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgaW50ZXJwb2xhdGVkXG4gICAgaWYgKCEgYWNjZXNzUGF0aCkgcmV0dXJuIHRoaXM7XG5cbiAgICB2YXIgdGhpc1BhdGhBcmdzQ291bnQgPSB0aGlzLl9hcmdzLmxlbmd0aCAtIDE7XG5cbiAgICBpZiAodGhpc1BhdGhBcmdzQ291bnQgPiAwKSB7Ly8gdGhpcyBwYXRoIGhhcyBpbnRlcnBvbGF0ZWQgYXJndW1lbnRzIHRvb1xuICAgICAgICBhY2Nlc3NQYXRoID0gYWNjZXNzUGF0aC5yZXBsYWNlKC9cXCRbMS05XVswLTldKi9nLCBmdW5jdGlvbihzdHIpIHtcbiAgICAgICAgICAgIHJldHVybiAnJCcgKyAoK3N0ci5zbGljZSgxKSArIHRoaXNQYXRoQXJnc0NvdW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgdmFyIG5ld1BhdGggPSB0aGlzLl9wYXRoICsgYWNjZXNzUGF0aDtcblxuICAgIC8vIHRoaXMuX21vZGVsIGlzIGFkZGVkIGluIGZyb250IG9mIGFsbCBhcmd1bWVudHMgYXMgdGhlIGZpcnN0IHBhcmFtZXRlclxuICAgIC8vIG9mIE1vZGVsUGF0aCBjb25zdHJ1Y3RvclxuICAgIHZhciBhcmdzID0gW3RoaXMuX21vZGVsLCBuZXdQYXRoXVxuICAgICAgICAgICAgICAgIC5jb25jYXQodGhpcy5fYXJncy5zbGljZSgxKSkgLy8gcmVtb3ZlIG9sZCBwYXRoIGZyb20gX2FyZ3MsIGFzIGl0IGlzIDEgYmFzZWRcbiAgICAgICAgICAgICAgICAuY29uY2F0KF8uc2xpY2UoYXJndW1lbnRzLCAxKSk7IC8vIGFkZCBuZXcgaW50ZXJwb2xhdGlvbiBhcmd1bWVudHNcblxuICAgIC8vIGNhbGxpbmcgTW9kZWxQYXRoIGNvbnN0cnVjdG9yIHdpdGggbmV3IGFuZCB0aGUgbGlzdCBvZiBhcmd1bWVudHM6IHRoaXMgKG1vZGVsKSwgYWNjZXNzUGF0aCwgLi4uXG4gICAgcmV0dXJuIF8ubmV3QXBwbHkoTW9kZWxQYXRoLCBhcmdzKTtcbn1cblxuXG4vKipcbiAqIE1vZGVsUGF0aCBhbmQgTW9kZWwgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIGxlbmd0aCBwcm9wZXJ0eSBhbmQgc2V0cyBpdCB0byAwIGlmIGl0IHdhc24ndCBzZXQuXG4gKlxuICogQHJldHVybiB7QW55fVxuICovXG5mdW5jdGlvbiBNb2RlbFBhdGgkbGVuKCkge1xuICAgIHJldHVybiB0aGlzLnBhdGgoJy5sZW5ndGgnKS5nZXQoKSB8fCAwO1xufVxuXG5cbi8qKlxuICogTW9kZWxQYXRoIGFuZCBNb2RlbCBpbnN0YW5jZSBtZXRob2RcbiAqIEFkZHMgaXRlbXMgdG8gdGhlIGVuZCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KS4gUmV0dXJucyBuZXcgbGVuZ3RoLlxuICpcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGxpc3Qgb2YgaXRlbXMgdGhhdCB3aWxsIGJlIGFkZGVkIHRvIGFycmF5IChwc2V1ZG8gYXJyYXkpXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfVxuICovXG5mdW5jdGlvbiBNb2RlbFBhdGgkcHVzaCgpIHsgLy8gYXJndW1lbnRzXG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuKCk7XG4gICAgdmFyIG5ld0xlbmd0aCA9IGxlbmd0aCArIGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICBfLnNwbGljZShhcmd1bWVudHMsIDAsIDAsIGxlbmd0aCwgMCk7XG4gICAgdGhpcy5zcGxpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHJldHVybiBuZXdMZW5ndGg7XG59XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggYW5kIE1vZGVsIGluc3RhbmNlIG1ldGhvZFxuICogUmVtb3ZlcyBpdGVtIGZyb20gdGhlIGVuZCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KS4gUmV0dXJucyB0aGlzIGl0ZW0uXG4gKlxuICogQHJldHVybiB7QW55fVxuICovXG5mdW5jdGlvbiBNb2RlbFBhdGgkcG9wKCkge1xuICAgIHJldHVybiB0aGlzLnNwbGljZSh0aGlzLmxlbigpIC0gMSwgMSlbMF07XG59XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggYW5kIE1vZGVsIGluc3RhbmNlIG1ldGhvZFxuICogSW5zZXJ0cyBpdGVtcyB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBhcnJheS4gUmV0dXJucyBuZXcgbGVuZ3RoLlxuICpcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGl0ZW1zIHRvIGJlIGluc2VydGVkIGluIHRoZSBiZWdpbm5pbmcgb2YgYXJyYXlcbiAqIEByZXR1cm4ge0ludGVnZXJ9XG4gKi9cbmZ1bmN0aW9uIE1vZGVsUGF0aCR1bnNoaWZ0KCkgeyAvLyBhcmd1bWVudHNcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5sZW4oKTtcbiAgICBsZW5ndGggKz0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIF8uc3BsaWNlKGFyZ3VtZW50cywgMCwgMCwgMCwgMCk7XG4gICAgdGhpcy5zcGxpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHJldHVybiBsZW5ndGg7XG59XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggYW5kIE1vZGVsIGluc3RhbmNlIG1ldGhvZFxuICogUmVtb3ZlcyB0aGUgaXRlbSBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkuIFJldHVybnMgdGhpcyBpdGVtLlxuICpcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gTW9kZWxQYXRoJHNoaWZ0KCkgeyAvLyBhcmd1bWVudHNcbiAgICByZXR1cm4gdGhpcy5zcGxpY2UoMCwgMSlbMF07XG59XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplcyBNb2RlbFBhdGggbWVzZW5nZXIgd2l0aCBNb2RlbCdzIG1lc3NlbmdlciBhcyBpdHMgc291cmNlIChbTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZV0oLi4vbWVzc2VuZ2VyL21zbmdyX3NvdXJjZS5qcy5odG1sKSkgYW5kIFtNb2RlbFBhdGhNc2dBUEldKC4vcGF0aF9tc2dfYXBpLmpzLmh0bWwpIGFzIFtNZXNzZW5nZXJBUEldKC4uL21lc3Nlbmdlci9tX2FwaS5qcy5odG1sKVxuICovXG5mdW5jdGlvbiBfcHJlcGFyZU1lc3NlbmdlcigpIHtcbiAgICB2YXIgbVBhdGhBUEkgPSBuZXcgTW9kZWxQYXRoTXNnQVBJKHRoaXMuX2FjY2Vzc1BhdGgpO1xuXG4gICAgLy8gY3JlYXRlIE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UgY29ubmVjdGVkIHRvIE1vZGVsJ3MgbWVzc2VuZ2VyXG4gICAgdmFyIG1vZGVsTWVzc2FnZVNvdXJjZSA9IG5ldyBNZXNzZW5nZXJNZXNzYWdlU291cmNlKHRoaXMsIHVuZGVmaW5lZCwgbVBhdGhBUEksIHRoaXMuX21vZGVsKTtcblxuICAgIC8vIGNyZWF0ZSBtZXNzZW5nZXIgd2l0aCBtb2RlbCBwYXNzZWQgYXMgaG9zdE9iamVjdCAoZGVmYXVsdCBtZXNzYWdlIGRpc3BhdGNoIGNvbnRleHQpXG4gICAgLy8gYW5kIHdpdGhvdXQgcHJveHlpbmcgbWV0aG9kcyAod2UgZG9uJ3Qgd2FudCB0byBwcm94eSB0aGVtIHRvIE1vZGVsKVxuICAgIHZhciBtUGF0aE1lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXIodGhpcywgdW5kZWZpbmVkLCBtb2RlbE1lc3NhZ2VTb3VyY2UpO1xuXG4gICAgLy8gc3RvcmUgbWVzc2VuZ2VyIG9uIE1vZGVsUGF0aCBpbnN0YW5jZVxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgTUVTU0VOR0VSX1BST1BFUlRZLCBtUGF0aE1lc3Nlbmdlcik7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBvYmplY3QgYWxsb3dpbmcgdG8gcmVjcmVhdGUgbW9kZWwgcGF0aFxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gX2dldERlZmluaXRpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbW9kZWw6IHRoaXMuX21vZGVsLFxuICAgICAgICBwYXRoOiB0aGlzLl9wYXRoLFxuICAgICAgICBhcmdzOiB0aGlzLl9hcmdzXG4gICAgfTtcbn1cblxuXG4vKipcbiAqIENsYXNzIG1ldGhvZFxuICogQ3JlYXRlcyBtb2RlbFBhdGggb2JqZWN0IGZyb20gZGVmaW5pdGlvbiBjcmVhdGVkIGJ5IF9nZXREZWZpbml0aW9uXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBkZWZpbml0aW9uXG4gKiBAcmV0dXJuIHtNb2RlbFBhdGh9XG4gKi9cbmZ1bmN0aW9uIF9jcmVhdGVGcm9tRGVmaW5pdGlvbihkZWZpbml0aW9uKSB7XG4gICAgY2hlY2soZGVmaW5pdGlvbiwge1xuICAgICAgICBtb2RlbDogRnVuY3Rpb24sIC8vIE1vZGVsXG4gICAgICAgIHBhdGg6IFN0cmluZyxcbiAgICAgICAgYXJnczogQXJyYXlcbiAgICB9KTtcblxuICAgIHZhciBtID0gZGVmaW5pdGlvbi5tb2RlbDtcblxuICAgIHJldHVybiBtLmFwcGx5KG0sIGRlZmluaXRpb24uYXJncyk7XG59XG5cblxuZnVuY3Rpb24gTW9kZWxQYXRoJGRlc3Ryb3koKSB7XG4gICAgdGhpc1tNRVNTRU5HRVJfUFJPUEVSVFldLmRlc3Ryb3koKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbW9kZWxVdGlscyA9IHtcbiAgICBub3JtYWxpemVTcGxpY2VJbmRleDogbm9ybWFsaXplU3BsaWNlSW5kZXhcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbW9kZWxVdGlscztcblxuXG5mdW5jdGlvbiBub3JtYWxpemVTcGxpY2VJbmRleChzcGxpY2VJbmRleCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHNwbGljZUluZGV4ID4gbGVuZ3RoXG4gICAgICAgICAgICA/IGxlbmd0aFxuICAgICAgICAgICAgOiBzcGxpY2VJbmRleCA+PSAwXG4gICAgICAgICAgICAgICAgPyBzcGxpY2VJbmRleFxuICAgICAgICAgICAgICAgIDogc3BsaWNlSW5kZXggKyBsZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgICAgID8gc3BsaWNlSW5kZXggKyBsZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgOiAwO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTWVzc2VuZ2VyQVBJID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyL21fYXBpJylcbiAgICAsIHBhdGhVdGlscyA9IHJlcXVpcmUoJy4vcGF0aF91dGlscycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLyoqXG4gKiBTdWJjbGFzcyBvZiBNZXNzZW5nZXJBUEkgdGhhdCBpcyB1c2VkIHRvIHRyYW5zbGF0ZSBtZXNzYWdlcyBvZiBNZXNzZW5nZXIgb24gTW9kZWxQYXRoIHRvIE1lc3NlbmdlciBvbiBNb2RlbC5cbiAqL1xudmFyIE1vZGVsUGF0aE1zZ0FQSSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2VuZ2VyQVBJLCAnTW9kZWxQYXRoTXNnQVBJJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTW9kZWxQYXRoTXNnQVBJO1xuXG5cbi8qKlxuICogIyMjI01vZGVsUGF0aE1zZ0FQSSBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2luaXRdKCNpbml0KSAtIGluaXRpYWxpemVzIE1vZGVsUGF0aE1zZ0FQSVxuICogLSBbdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlXSgjdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKSAtIHRyYW5zbGF0ZXMgcmVsYXRpdmUgYWNjZXNzIHBhdGhzIG9mIE1vZGVsUGF0aCB0byBmdWxsIHBhdGggb2YgTW9kZWxcbiAqIC0gW2NyZWF0ZUludGVybmFsRGF0YV0oI2NyZWF0ZUludGVybmFsRGF0YSkgLSBjaGFuZ2VzIHBhdGggaW4gbWVzc2FnZSBvbiBtb2RlbCB0byByZWxhdGl2ZSBwYXRoIGFuZCBhZGRzIGBmdWxsUGF0aGAgcHJvcGVydHkgdG8gbWVzc2FnZSBkYXRhXG4gKi9cbl8uZXh0ZW5kUHJvdG8oTW9kZWxQYXRoTXNnQVBJLCB7XG4gICAgaW5pdDogaW5pdCxcbiAgICB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2U6IHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZSxcbiAgICBjcmVhdGVJbnRlcm5hbERhdGE6IGNyZWF0ZUludGVybmFsRGF0YSxcbn0pO1xuXG5cbi8qKlxuICogTW9kZWxQYXRoTXNnQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IE1lc3NlbmdlckFQSSBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcm9vdFBhdGggcm9vdCBwYXRoIG9mIG1vZGVsIHBhdGhcbiAqL1xuZnVuY3Rpb24gaW5pdChyb290UGF0aCkge1xuICAgIE1lc3NlbmdlckFQSS5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMucm9vdFBhdGggPSByb290UGF0aDtcbn1cblxuLyoqXG4gKiBNb2RlbFBhdGhNc2dBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBUcmFuc2xhdGVzIHJlbGF0aXZlIGFjY2VzcyBwYXRocyBvZiBNb2RlbFBhdGggdG8gZnVsbCBwYXRoIG9mIE1vZGVsLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2Nlc3NQYXRoIHJlbGF0aXZlIGFjY2VzcyBwYXRoIHRvIGJlIHRyYW5zbGF0ZWRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICAvLyBUT0RPIHNob3VsZCBwcmVwZW5kIFJlZ0V4ZXNcbiAgICAvLyBUT0RPIHNob3VsZCBub3QgcHJlcGVuZCBjaGFuZ2VkYXRhIHRvbz8/P1xuICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgUmVnRXhwKVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICBpZiAobWVzc2FnZSA9PSAnZGF0YWNoYW5nZXMnKVxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICBcbiAgICByZXR1cm4gdGhpcy5yb290UGF0aCArIG1lc3NhZ2U7XG59XG5cblxuLyoqXG4gKiBNb2RlbFBhdGhNc2dBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBDaGFuZ2VzIHBhdGggaW4gbWVzc2FnZSBvbiBtb2RlbCB0byByZWxhdGl2ZSBwYXRoIGFuZCBhZGRzIGBmdWxsUGF0aGAgcHJvcGVydHkgdG8gbWVzc2FnZSBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzb3VyY2VNZXNzYWdlIGZ1bGwgYWNjZXNzIHBhdGggb24gTW9kZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIHJlbGF0aXZlIGFjY2VzcyBwYXRoIG9uIE1vZGVsUGF0aFxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZURhdGEgZGF0YSByZWNlaXZlZCBmcm9tIE1vZGVsLCB3aWxsIGJlIHRyYW5zbGF0ZWQgYXMgZGVzY3JpYmVkIHRvIGJlIGRpc3BhdGNoZWQgdG8gTW9kZWxQYXRoXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUludGVybmFsRGF0YShzb3VyY2VNZXNzYWdlLCBtZXNzYWdlLCBzb3VyY2VEYXRhKSB7XG4gICAgLy8gVE9ETyByZXR1cm4gb24gY2hhbmdlZGF0YSB0b28/Pz9cbiAgICBpZiAobWVzc2FnZSA9PSAnZGF0YWNoYW5nZXMnKSB7XG4gICAgICAgIHZhciBpbnRlcm5hbENoYW5nZXMgPSBzb3VyY2VEYXRhLmNoYW5nZXNcbiAgICAgICAgICAgIC5tYXAodHJ1bmNhdGVDaGFuZ2VQYXRoLCB0aGlzKVxuICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbihjaGFuZ2UpIHsgcmV0dXJuIGNoYW5nZTsgfSk7XG4gICAgICAgIHZhciBpbnRlcm5hbERhdGEgPSB7XG4gICAgICAgICAgICBjaGFuZ2VzOiBpbnRlcm5hbENoYW5nZXMsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbjogc291cmNlRGF0YS50cmFuc2FjdGlvblxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBpbnRlcm5hbERhdGFcbiAgICB9XG5cbiAgICB2YXIgaW50ZXJuYWxEYXRhID0gdHJ1bmNhdGVDaGFuZ2VQYXRoLmNhbGwodGhpcywgc291cmNlRGF0YSk7XG4gICAgcmV0dXJuIGludGVybmFsRGF0YTtcbn1cblxuXG5mdW5jdGlvbiB0cnVuY2F0ZUNoYW5nZVBhdGgoY2hhbmdlKSB7XG4gICAgdmFyIGZ1bGxQYXRoID0gY2hhbmdlLnBhdGhcbiAgICAgICAgLCBwYXRoID0gXy51blByZWZpeChmdWxsUGF0aCwgdGhpcy5yb290UGF0aCk7XG5cbiAgICBpZiAodHlwZW9mIHBhdGggPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdmFyIGNoYW5nZSA9IF8uY2xvbmUoY2hhbmdlKTtcbiAgICAgICAgY2hhbmdlLmZ1bGxQYXRoID0gZnVsbFBhdGg7XG4gICAgICAgIGNoYW5nZS5wYXRoID0gcGF0aDtcbiAgICAgICAgcmV0dXJuIGNoYW5nZTtcbiAgICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIDxhIG5hbWU9XCJtb2RlbC1wYXRoXCI+PC9hPlxuLy8gIyMjIG1vZGVsIHBhdGggdXRpbHNcblxudmFyIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIE1vZGVsRXJyb3IgPSByZXF1aXJlKCcuLi91dGlsL2Vycm9yJykuTW9kZWw7XG5cbnZhciBwYXRoVXRpbHMgPSB7XG4gICAgcGFyc2VBY2Nlc3NQYXRoOiBwYXJzZUFjY2Vzc1BhdGgsXG4gICAgY3JlYXRlUmVnZXhQYXRoOiBjcmVhdGVSZWdleFBhdGgsXG4gICAgZ2V0UGF0aE5vZGVLZXk6IGdldFBhdGhOb2RlS2V5LFxuICAgIHdyYXBNZXNzZW5nZXJNZXRob2RzOiB3cmFwTWVzc2VuZ2VyTWV0aG9kc1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBwYXRoVXRpbHM7XG5cblxudmFyIHByb3BlcnR5UGF0aFN5bnRheCA9ICdcXFxcLltBLVphLXpfLV1bQS1aYS16MC05Xy1dKidcbiAgICAsIGFycmF5UGF0aFN5bnRheCA9ICdcXFxcW1swLTldK1xcXFxdJ1xuICAgICwgaW50ZXJwb2xhdGlvblN5bnRheCA9ICdcXFxcJFsxLTldWzAtOV0qJ1xuICAgICwgcHJvcGVydHlJbnRlcnBvbGF0ZVN5bnRheCA9ICdcXFxcLicgKyBpbnRlcnBvbGF0aW9uU3ludGF4XG4gICAgLCBhcnJheUludGVycG9sYXRlU3ludGF4ID0gJ1xcXFxbJyArIGludGVycG9sYXRpb25TeW50YXggKyAnXFxcXF0nXG5cbiAgICAsIHByb3BlcnR5U3RhclN5bnRheCA9ICdcXFxcLlxcXFwqJ1xuICAgICwgYXJyYXlTdGFyU3ludGF4ID0gJ1xcXFxbXFxcXCpcXFxcXSdcbiAgICAsIHN0YXJTeW50YXggPSAnXFxcXConXG5cbiAgICAsIHBhdGhQYXJzZVN5bnRheCA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVBhdGhTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlQYXRoU3ludGF4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5SW50ZXJwb2xhdGVTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYXlJbnRlcnBvbGF0ZVN5bnRheFxuICAgICAgICAgICAgICAgICAgICAgICAgXS5qb2luKCd8JylcbiAgICAsIHBhdGhQYXJzZVBhdHRlcm4gPSBuZXcgUmVnRXhwKHBhdGhQYXJzZVN5bnRheCwgJ2cnKVxuXG4gICAgLCBwYXR0ZXJuUGF0aFBhcnNlU3ludGF4ID0gIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGhQYXJzZVN5bnRheCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5U3RhclN5bnRheCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5U3RhclN5bnRheCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJTeW50YXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXS5qb2luKCd8JylcbiAgICAsIHBhdHRlcm5QYXRoUGFyc2VQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXR0ZXJuUGF0aFBhcnNlU3ludGF4LCAnZycpXG5cbiAgICAvLywgdGFyZ2V0UGF0aFBhcnNlUGF0dGVybiA9IC9cXC5bQS1aYS16XVtBLVphLXowLTlfXSp8XFxbWzAtOV0rXFxdfFxcLlxcJFsxLTldWzAtOV0qfFxcW1xcJFsxLTldWzAtOV0qXFxdfFxcJFsxLTldWzAtOV0vZ1xuICAgICwgcGF0aE5vZGVUeXBlcyA9IHtcbiAgICAgICAgJy4nOiB7IHN5bnRheDogJ29iamVjdCcsIGVtcHR5OiAne30nIH0sXG4gICAgICAgICdbJzogeyBzeW50YXg6ICdhcnJheScsIGVtcHR5OiAnW10nfSxcbiAgICAgICAgJyonOiB7IHN5bnRheDogJ21hdGNoJywgZW1wdHk6ICd7fSd9LFxuICAgIH07XG5cbmZ1bmN0aW9uIHBhcnNlQWNjZXNzUGF0aChwYXRoLCBub2RlUGFyc2VQYXR0ZXJuKSB7XG4gICAgbm9kZVBhcnNlUGF0dGVybiA9IG5vZGVQYXJzZVBhdHRlcm4gfHwgcGF0aFBhcnNlUGF0dGVybjtcblxuICAgIHZhciBwYXJzZWRQYXRoID0gW107XG5cbiAgICBpZiAoISBwYXRoKVxuICAgICAgICByZXR1cm4gcGFyc2VkUGF0aDtcblxuICAgIHZhciB1bnBhcnNlZCA9IHBhdGgucmVwbGFjZShub2RlUGFyc2VQYXR0ZXJuLCBmdW5jdGlvbihub2RlU3RyKSB7XG4gICAgICAgIHZhciBwYXRoTm9kZSA9IHsgcHJvcGVydHk6IG5vZGVTdHIgfTtcbiAgICAgICAgXy5leHRlbmQocGF0aE5vZGUsIHBhdGhOb2RlVHlwZXNbbm9kZVN0clswXV0pO1xuICAgICAgICBpZiAobm9kZVN0clsxXSA9PSAnJCcpXG4gICAgICAgICAgICBwYXRoTm9kZS5pbnRlcnBvbGF0ZSA9IGdldFBhdGhOb2RlS2V5KHBhdGhOb2RlLCB0cnVlKTtcblxuICAgICAgICBwYXJzZWRQYXRoLnB1c2gocGF0aE5vZGUpO1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfSk7XG4gICAgaWYgKHVucGFyc2VkKVxuICAgICAgICB0aHJvdyBuZXcgTW9kZWxFcnJvcignaW5jb3JyZWN0IG1vZGVsIHBhdGg6ICcgKyBwYXRoKTtcblxuICAgIHJldHVybiBwYXJzZWRQYXRoO1xufVxuXG5cbnZhciBub2RlUmVnZXggPSB7XG4gICAgJy4qJzogcHJvcGVydHlQYXRoU3ludGF4LFxuICAgICdbKl0nOiBhcnJheVBhdGhTeW50YXhcbn07XG5ub2RlUmVnZXhbJyonXSA9IG5vZGVSZWdleFsnLionXSArICd8JyArIG5vZGVSZWdleFsnWypdJ107XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlZ2V4UGF0aChwYXRoKSB7XG4gICAgY2hlY2socGF0aCwgTWF0Y2guT25lT2YoU3RyaW5nLCBSZWdFeHApKTtcblxuICAgIGlmIChwYXRoIGluc3RhbmNlb2YgUmVnRXhwIHx8IHBhdGguaW5kZXhPZignKicpID09IC0xKVxuICAgICAgICByZXR1cm4gcGF0aDtcblxuICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChwYXRoLCBwYXR0ZXJuUGF0aFBhcnNlUGF0dGVybilcbiAgICAgICAgLCByZWdleFN0ciA9ICdeJ1xuICAgICAgICAvLyAsIHJlZ2V4U3RyRW5kID0gJydcbiAgICAgICAgLCBwYXR0ZXJuc1N0YXJ0ZWQgPSBmYWxzZTtcblxuICAgIHBhcnNlZFBhdGguZm9yRWFjaChmdW5jdGlvbihwYXRoTm9kZSkge1xuICAgICAgICB2YXIgcHJvcCA9IHBhdGhOb2RlLnByb3BlcnR5XG4gICAgICAgICAgICAsIHJlZ2V4ID0gbm9kZVJlZ2V4W3Byb3BdO1xuICAgICAgICBcbiAgICAgICAgaWYgKHJlZ2V4KSB7XG4gICAgICAgICAgICAvLyByZWdleFN0ciArPSAnKCcgKyByZWdleDtcbiAgICAgICAgICAgIC8vIHJlZ2V4U3RyRW5kICs9ICd8KSc7XG4gICAgICAgICAgICByZWdleFN0ciArPSAnKCcgKyByZWdleCArICd8KSc7XG4gICAgICAgICAgICAvLyByZWdleFN0ckVuZCArPSAnfCknO1xuICAgICAgICAgICAgcGF0dGVybnNTdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGlmIChwYXR0ZXJuc1N0YXJ0ZWQpXG4gICAgICAgICAgICAvLyAgdGhyb3cgbmV3IE1vZGVsRXJyb3IoJ1wiKlwiIHBhdGggc2VnbWVudCBjYW5ub3QgYmUgaW4gdGhlIG1pZGRsZSBvZiB0aGUgcGF0aDogJyArIHBhdGgpO1xuICAgICAgICAgICAgcmVnZXhTdHIgKz0gcHJvcC5yZXBsYWNlKC8oXFwufFxcW3xcXF0pL2csICdcXFxcJDEnKTsgLy8gYWRkIHNsYXNoIGluIGZyb250IG9mIHN5bWJvbHMgdGhhdCBoYXZlIHNwZWNpYWwgbWVhbmluZyBpbiByZWdleFxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZWdleFN0ciArPSAvKiByZWdleFN0ckVuZCArICovICckJztcblxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4U3RyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBNb2RlbEVycm9yKCdjYW5cXCd0IGNvbnN0cnVjdCByZWdleCBmb3IgcGF0aCBwYXR0ZXJuOiAnICsgcGF0aCk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIGdldFBhdGhOb2RlS2V5KHBhdGhOb2RlLCBpbnRlcnBvbGF0ZWQpIHtcbiAgICB2YXIgcHJvcCA9IHBhdGhOb2RlLnByb3BlcnR5XG4gICAgICAgICwgc3RhcnRJbmRleCA9IGludGVycG9sYXRlZCA/IDIgOiAxO1xuICAgIHJldHVybiBwYXRoTm9kZS5zeW50YXggPT0gJ2FycmF5J1xuICAgICAgICA/IHByb3Auc2xpY2Uoc3RhcnRJbmRleCwgcHJvcC5sZW5ndGggLSAxKVxuICAgICAgICA6IHByb3Auc2xpY2Uoc3RhcnRJbmRleCk7XG59XG5cblxuLy8gVE9ETyBhbGxvdyBmb3IgbXVsdGlwbGUgbWVzc2FnZXMgaW4gYSBzdHJpbmdcbmZ1bmN0aW9uIHdyYXBNZXNzZW5nZXJNZXRob2RzKG1ldGhvZHNOYW1lcykge1xuICAgIG1ldGhvZHNOYW1lcyA9IG1ldGhvZHNOYW1lcyB8fCBbJ29uJywgJ29mZiddO1xuICAgIHZhciB3cmFwcGVkTWV0aG9kcyA9IF8ubWFwVG9PYmplY3QobWV0aG9kc05hbWVzLCBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgICAgIHZhciBvcmlnTWV0aG9kID0gdGhpc1ttZXRob2ROYW1lXTtcbiAgICAgICAgLy8gcmVwbGFjaW5nIG1lc3NhZ2Ugc3Vic3JpYmUvdW5zdWJzY3JpYmUvZXRjLiB0byBjb252ZXJ0IFwiKlwiIG1lc3NhZ2UgcGF0dGVybnMgdG8gcmVnZXhwc1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24ocGF0aCwgc3Vic2NyaWJlcikge1xuICAgICAgICAgICAgdmFyIHJlZ2V4UGF0aCA9IGNyZWF0ZVJlZ2V4UGF0aChwYXRoKTtcbiAgICAgICAgICAgIG9yaWdNZXRob2QuY2FsbCh0aGlzLCByZWdleFBhdGgsIHN1YnNjcmliZXIpO1xuICAgICAgICB9O1xuICAgIH0sIHRoaXMpO1xuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB3cmFwcGVkTWV0aG9kcyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBwYXRoVXRpbHMgPSByZXF1aXJlKCcuLi9wYXRoX3V0aWxzJylcbiAgICAsIG1vZGVsVXRpbHMgPSByZXF1aXJlKCcuLi9tb2RlbF91dGlscycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi91dGlsL2xvZ2dlcicpXG4gICAgLCBtaWxvQ291bnQgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NvdW50JylcbiAgICAsIGZzID0gcmVxdWlyZSgnZnMnKVxuICAgICwgZG9UID0gcmVxdWlyZSgnZG90JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hhbmdlRGF0YUhhbmRsZXIgPSByZXF1aXJlKCcuLi9jaGFuZ2VfZGF0YScpXG4gICAgLCBnZXRUcmFuc2FjdGlvbkZsYWcgPSBjaGFuZ2VEYXRhSGFuZGxlci5nZXRUcmFuc2FjdGlvbkZsYWdcbiAgICAsIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkID0gY2hhbmdlRGF0YUhhbmRsZXIucG9zdFRyYW5zYWN0aW9uRmluaXNoZWQ7XG5cblxuLyoqXG4gKiBUZW1wbGF0ZXMgdG8gc3ludGhlc2l6ZSBtb2RlbCBnZXR0ZXJzIGFuZCBzZXR0ZXJzXG4gKi9cbnZhciB0ZW1wbGF0ZXMgPSB7XG4gICAgZ2V0OiBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbm1ldGhvZCA9IGZ1bmN0aW9uIGdldCgpIHtcXG4gICAgdmFyIG0gPSB7eyMgZGVmLm1vZGVsQWNjZXNzUHJlZml4IH19O1xcbiAgICByZXR1cm4gbSB7e34gaXQucGFyc2VkUGF0aCA6cGF0aE5vZGUgfX1cXG4gICAgICAgIHt7PyBwYXRoTm9kZS5pbnRlcnBvbGF0ZX19XFxuICAgICAgICAgICAgJiYgKG0gPSBtW3RoaXMuX2FyZ3NbIHt7PSBwYXRoTm9kZS5pbnRlcnBvbGF0ZSB9fSBdXSlcXG4gICAgICAgIHt7Pz99fVxcbiAgICAgICAgICAgICYmIChtID0gbXt7PSBwYXRoTm9kZS5wcm9wZXJ0eSB9fSlcXG4gICAgICAgIHt7P319IHt7fn19O1xcbn07XFxuXCIsXG4gICAgc2V0OiBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbnt7IyBkZWYuaW5jbHVkZV9kZWZpbmVzIH19XFxue3sjIGRlZi5pbmNsdWRlX2NyZWF0ZV90cmVlIH19XFxuXFxuXFxuLyoqXFxuICogVGVtcGxhdGUgdGhhdCBzeW50aGVzaXplcyBzZXR0ZXIgZm9yIE1vZGVsIGFuZCBmb3IgTW9kZWxQYXRoXFxuICovXFxubWV0aG9kID0gZnVuY3Rpb24gc2V0KHZhbHVlKSB7XFxuICAgIHt7IyBkZWYuaW5pdFZhcnM6J3NldCcgfX1cXG5cXG4gICAge3sjIGRlZi5jcmVhdGVUcmVlOidzZXQnIH19XFxuXFxuICAgIHt7XFxuICAgICAgICBjdXJyTm9kZSA9IG5leHROb2RlO1xcbiAgICAgICAgY3VyclByb3AgPSBjdXJyTm9kZSAmJiBjdXJyTm9kZS5wcm9wZXJ0eTtcXG4gICAgfX1cXG5cXG4gICAge3sgLyogYXNzaWduIHZhbHVlIHRvIHRoZSBsYXN0IHByb3BlcnR5ICovIH19XFxuICAgIHt7PyBjdXJyUHJvcCB9fVxcbiAgICAgICAgd2FzRGVmID0ge3sjIGRlZi53YXNEZWZpbmVkfX07XFxuICAgICAgICB7eyMgZGVmLmNoYW5nZUFjY2Vzc1BhdGggfX1cXG5cXG4gICAgICAgIHZhciBvbGQgPSBte3sjIGRlZi5jdXJyUHJvcCB9fTtcXG5cXG4gICAgICAgIHt7IC8qIGNsb25lIHZhbHVlIHRvIHByZXZlbnQgc2FtZSByZWZlcmVuY2UgaW4gbGlua2VkIG1vZGVscyAqLyB9fVxcbiAgICAgICAgbXt7IyBkZWYuY3VyclByb3AgfX0gPSBjbG9uZVRyZWUodmFsdWUpO1xcbiAgICB7ez99fVxcblxcbiAgICB7eyAvKiBhZGQgbWVzc2FnZSByZWxhdGVkIHRvIHRoZSBsYXN0IHByb3BlcnR5IGNoYW5nZSAqLyB9fVxcbiAgICBpZiAodGhpcy5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcXG4gICAgICAgIGlmICghIHdhc0RlZilcXG4gICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBhY2Nlc3NQYXRoLCB0eXBlOiAnYWRkZWQnLFxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZTogdmFsdWUgfSk7XFxuICAgICAgICBlbHNlIGlmIChvbGQgIT0gdmFsdWUpXFxuICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gYWNjZXNzUGF0aCwgdHlwZTogJ2NoYW5nZWQnLFxcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZTogb2xkLCBuZXdWYWx1ZTogdmFsdWUgfSk7XFxuXFxuICAgICAgICB7eyAvKiBhZGQgbWVzc2FnZSByZWxhdGVkIHRvIGNoYW5nZXMgaW4gKHN1Yilwcm9wZXJ0aWVzIGluc2lkZSByZW1vdmVkIGFuZCBhc3NpZ25lZCB2YWx1ZSAqLyB9fVxcbiAgICAgICAgaWYgKCEgd2FzRGVmIHx8IG9sZCAhPSB2YWx1ZSlcXG4gICAgICAgICAgICBhZGRUcmVlQ2hhbmdlc01lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsXFxuICAgICAgICAgICAgICAgIGFjY2Vzc1BhdGgsIG9sZCwgdmFsdWUpOyAvKiBkZWZpbmVkIGluIHRoZSBmdW5jdGlvbiB0aGF0IHN5bnRoZXNpemVzIE1vZGVsUGF0aCBzZXR0ZXIgKi9cXG5cXG4gICAgICAgIHt7IC8qIHBvc3QgYWxsIHN0b3JlZCBtZXNzYWdlcyAqLyB9fVxcbiAgICAgICAge3sjIGRlZi5wb3N0TWVzc2FnZXMgfX1cXG4gICAgfVxcbn07XFxuXCIsXG4gICAgZGVsOiBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbnt7IyBkZWYuaW5jbHVkZV9kZWZpbmVzIH19XFxue3sjIGRlZi5pbmNsdWRlX3RyYXZlcnNlX3RyZWUgfX1cXG5cXG5tZXRob2QgPSBmdW5jdGlvbiBkZWwoKSB7XFxuICAgIHt7IyBkZWYuaW5pdFZhcnM6J2RlbCcgfX1cXG5cXG4gICAge3s/IGl0LnBhcnNlZFBhdGgubGVuZ3RoIH19XFxuICAgICAgICB7eyMgZGVmLnRyYXZlcnNlVHJlZSB9fVxcblxcbiAgICAgICAge3tcXG4gICAgICAgICAgICB2YXIgY3Vyck5vZGUgPSBpdC5wYXJzZWRQYXRoW2NvdW50XTtcXG4gICAgICAgICAgICB2YXIgY3VyclByb3AgPSBjdXJyTm9kZS5wcm9wZXJ0eTsgICAgICAgXFxuICAgICAgICB9fVxcblxcbiAgICAgICAgaWYgKCEgdHJlZURvZXNOb3RFeGlzdCAmJiBtICYmIG0uaGFzT3duUHJvcGVydHkgJiYge3sjIGRlZi53YXNEZWZpbmVkfX0pIHtcXG4gICAgICAgICAgICB2YXIgb2xkID0gbXt7IyBkZWYuY3VyclByb3AgfX07XFxuICAgICAgICAgICAgZGVsZXRlIG17eyMgZGVmLmN1cnJQcm9wIH19O1xcbiAgICAgICAgICAgIHt7IyBkZWYuY2hhbmdlQWNjZXNzUGF0aCB9fVxcbiAgICAgICAgICAgIHZhciBkaWREZWxldGUgPSB0cnVlO1xcbiAgICAgICAgfVxcbiAgICB7ez8/fX1cXG4gICAgICAgIGlmICh0eXBlb2YgbSAhPSAndW5kZWZpbmVkJykge1xcbiAgICAgICAgICAgIHZhciBvbGQgPSBtO1xcbiAgICAgICAgICAgIHt7IyBkZWYubW9kZWxBY2Nlc3NQcmVmaXggfX0gPSB1bmRlZmluZWQ7XFxuICAgICAgICAgICAgdmFyIGRpZERlbGV0ZSA9IHRydWU7XFxuICAgICAgICB9XFxuICAgIHt7P319XFxuXFxuICAgIGlmIChkaWREZWxldGUgJiYgdGhpcy5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcXG4gICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGFjY2Vzc1BhdGgsIHR5cGU6ICdkZWxldGVkJywgb2xkVmFsdWU6IG9sZCB9KTtcXG5cXG4gICAgICAgIGFkZFRyZWVDaGFuZ2VzTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCxcXG4gICAgICAgICAgICBhY2Nlc3NQYXRoLCBvbGQsIHVuZGVmaW5lZCk7IC8qIGRlZmluZWQgaW4gdGhlIGZ1bmN0aW9uIHRoYXQgc3ludGhlc2l6ZXMgTW9kZWxQYXRoIHNldHRlciAqL1xcblxcbiAgICAgICAge3sgLyogcG9zdCBhbGwgc3RvcmVkIG1lc3NhZ2VzICovIH19XFxuICAgICAgICB7eyMgZGVmLnBvc3RNZXNzYWdlcyB9fVxcbiAgICB9XFxufTtcXG5cIixcbiAgICBzcGxpY2U6IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxue3sjIGRlZi5pbmNsdWRlX2RlZmluZXMgfX1cXG57eyMgZGVmLmluY2x1ZGVfY3JlYXRlX3RyZWUgfX1cXG57eyMgZGVmLmluY2x1ZGVfdHJhdmVyc2VfdHJlZSB9fVxcblxcbm1ldGhvZCA9IGZ1bmN0aW9uIHNwbGljZShzcGxpY2VJbmRleCwgc3BsaWNlSG93TWFueSkgeyAvKiAsLi4uIC0gZXh0cmEgYXJndW1lbnRzIHRvIHNwbGljZSBpbnRvIGFycmF5ICovXFxuICAgIHt7IyBkZWYuaW5pdFZhcnM6J3NwbGljZScgfX1cXG5cXG4gICAgdmFyIGFyZ3NMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xcbiAgICB2YXIgYWRkSXRlbXMgPSBhcmdzTGVuID4gMjtcXG5cXG4gICAgaWYgKGFkZEl0ZW1zKSB7XFxuICAgICAgICB7eyAvKiBvbmx5IGNyZWF0ZSBtb2RlbCB0cmVlIGlmIGl0ZW1zIGFyZSBpbnNlcnRlZCBpbiBhcnJheSAqLyB9fVxcblxcbiAgICAgICAge3sgLyogaWYgbW9kZWwgaXMgdW5kZWZpbmVkIGl0IHdpbGwgYmUgc2V0IHRvIGFuIGVtcHR5IGFycmF5ICovIH19ICBcXG4gICAgICAgIHZhciB2YWx1ZSA9IFtdO1xcbiAgICAgICAge3sjIGRlZi5jcmVhdGVUcmVlOidzcGxpY2UnIH19XFxuXFxuICAgICAgICB7ez8gbmV4dE5vZGUgfX1cXG4gICAgICAgICAgICB7e1xcbiAgICAgICAgICAgICAgICB2YXIgY3Vyck5vZGUgPSBuZXh0Tm9kZTtcXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJQcm9wID0gY3Vyck5vZGUucHJvcGVydHk7XFxuICAgICAgICAgICAgICAgIHZhciBlbXB0eVByb3AgPSAnW10nO1xcbiAgICAgICAgICAgIH19XFxuXFxuICAgICAgICAgICAge3sjIGRlZi5jcmVhdGVUcmVlU3RlcCB9fVxcbiAgICAgICAge3s/fX1cXG5cXG4gICAgfSBlbHNlIGlmIChzcGxpY2VIb3dNYW55ID4gMCkge1xcbiAgICAgICAge3sgLyogaWYgaXRlbXMgYXJlIG5vdCBpbnNlcnRlZCwgb25seSB0cmF2ZXJzZSBtb2RlbCB0cmVlIGlmIGl0ZW1zIGFyZSBkZWxldGVkIGZyb20gYXJyYXkgKi8gfX1cXG4gICAgICAgIHt7PyBpdC5wYXJzZWRQYXRoLmxlbmd0aCB9fVxcbiAgICAgICAgICAgIHt7IyBkZWYudHJhdmVyc2VUcmVlIH19XFxuXFxuICAgICAgICAgICAge3tcXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJOb2RlID0gaXQucGFyc2VkUGF0aFtjb3VudF07XFxuICAgICAgICAgICAgICAgIHZhciBjdXJyUHJvcCA9IGN1cnJOb2RlLnByb3BlcnR5OyAgICAgICBcXG4gICAgICAgICAgICB9fVxcblxcbiAgICAgICAgICAgIHt7IC8qIGV4dHJhIGJyYWNlIGNsb3NlcyAnZWxzZScgaW4gZGVmLnRyYXZlcnNlVHJlZVN0ZXAgKi8gfX1cXG4gICAgICAgICAgICB7eyMgZGVmLnRyYXZlcnNlVHJlZVN0ZXAgfX0gfVxcbiAgICAgICAge3s/fX1cXG4gICAgfVxcblxcbiAgICB7eyAvKiBzcGxpY2UgaXRlbXMgKi8gfX1cXG4gICAgaWYgKGFkZEl0ZW1zIHx8ICghIHRyZWVEb2VzTm90RXhpc3QgJiYgbVxcbiAgICAgICAgICAgICYmIG0ubGVuZ3RoID4gc3BsaWNlSW5kZXggKSApIHtcXG4gICAgICAgIHZhciBvbGRMZW5ndGggPSBtLmxlbmd0aCA9IG0ubGVuZ3RoIHx8IDA7XFxuXFxuICAgICAgICBhcmd1bWVudHNbMF0gPSBzcGxpY2VJbmRleCA9IG5vcm1hbGl6ZVNwbGljZUluZGV4KHNwbGljZUluZGV4LCBtLmxlbmd0aCk7XFxuXFxuICAgICAgICB7eyAvKiBjbG9uZSBhZGRlZCBhcmd1bWVudHMgdG8gcHJldmVudCBzYW1lIHJlZmVyZW5jZXMgaW4gbGlua2VkIG1vZGVscyAqLyB9fVxcbiAgICAgICAgaWYgKGFkZEl0ZW1zKVxcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYXJnc0xlbjsgaSsrKVxcbiAgICAgICAgICAgICAgICBhcmd1bWVudHNbaV0gPSBjbG9uZVRyZWUoYXJndW1lbnRzW2ldKTtcXG5cXG4gICAgICAgIHt7IC8qIGFjdHVhbCBzcGxpY2UgY2FsbCAqLyB9fVxcbiAgICAgICAgdmFyIHJlbW92ZWQgPSBBcnJheS5wcm90b3R5cGUuc3BsaWNlLmFwcGx5KG0sIGFyZ3VtZW50cyk7XFxuXFxuICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcXG4gICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBhY2Nlc3NQYXRoLCB0eXBlOiAnc3BsaWNlJyxcXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiBzcGxpY2VJbmRleCwgcmVtb3ZlZDogcmVtb3ZlZCwgYWRkZWRDb3VudDogYWRkSXRlbXMgPyBhcmdzTGVuIC0gMiA6IDAsXFxuICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbSB9KTtcXG5cXG4gICAgICAgICAgICBpZiAocmVtb3ZlZCAmJiByZW1vdmVkLmxlbmd0aClcXG4gICAgICAgICAgICAgICAgcmVtb3ZlZC5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbVBhdGggPSBhY2Nlc3NQYXRoICsgJ1snICsgKHNwbGljZUluZGV4ICsgaW5kZXgpICsgJ10nO1xcbiAgICAgICAgICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gaXRlbVBhdGgsIHR5cGU6ICdyZW1vdmVkJywgb2xkVmFsdWU6IGl0ZW0gfSk7XFxuXFxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVJc1RyZWUoaXRlbSkpXFxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgaXRlbVBhdGgsIGl0ZW0sICdyZW1vdmVkJywgJ29sZFZhbHVlJyk7XFxuICAgICAgICAgICAgICAgIH0pO1xcblxcbiAgICAgICAgICAgIGlmIChhZGRJdGVtcylcXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCBhcmdzTGVuOyBpKyspIHtcXG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVtID0gYXJndW1lbnRzW2ldO1xcbiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW1QYXRoID0gYWNjZXNzUGF0aCArICdbJyArIChzcGxpY2VJbmRleCArIGkgLSAyKSArICddJztcXG4gICAgICAgICAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGl0ZW1QYXRoLCB0eXBlOiAnYWRkZWQnLCBuZXdWYWx1ZTogaXRlbSB9KTtcXG5cXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUlzVHJlZShpdGVtKSlcXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCBpdGVtUGF0aCwgaXRlbSwgJ2FkZGVkJywgJ25ld1ZhbHVlJyk7XFxuICAgICAgICAgICAgICAgIH1cXG5cXG4gICAgICAgICAgICB7eyAvKiBwb3N0IGFsbCBzdG9yZWQgbWVzc2FnZXMgKi8gfX1cXG4gICAgICAgICAgICB7eyMgZGVmLnBvc3RNZXNzYWdlcyB9fVxcbiAgICAgICAgfVxcbiAgICB9XFxuXFxuICAgIHJldHVybiByZW1vdmVkIHx8IFtdO1xcbn1cXG5cIlxufTtcblxudmFyIGluY2x1ZGVfZGVmaW5lcyA9IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBpbml0aWFsaXphdGlvbiBjb2RlXFxuICovXFxuIHt7IyMgZGVmLmluaXRWYXJzOm1ldGhvZDpcXG4gICAgdmFyIG0gPSB7eyMgZGVmLm1vZGVsQWNjZXNzUHJlZml4IH19O1xcbiAgICB2YXIgbWVzc2FnZXMgPSBbXSwgbWVzc2FnZXNIYXNoID0ge307XFxuICAgIHZhciBhY2Nlc3NQYXRoID0gJyc7XFxuICAgIHZhciB0cmVlRG9lc05vdEV4aXN0O1xcbiAgICAvKiBoYWNrIHRvIHByZXZlbnQgc2VuZGluZyBmaW5pc2hlZCBldmVudHMgdG8gYWxsb3cgZm9yIHByb3BhZ2F0aW9uIG9mIGJhdGNoZXMgd2l0aG91dCBzcGxpdHRpbmcgdGhlbSAqL1xcbiAgICB2YXIgaW5DaGFuZ2VUcmFuc2FjdGlvbiA9IGdldFRyYW5zYWN0aW9uRmxhZygge3s9IG1ldGhvZCB9fSApO1xcbiAjfX1cXG5cXG4vKipcXG4gKiBJbnNlcnRzIHRoZSBiZWdpbm5pbmcgb2YgZnVuY3Rpb24gY2FsbCB0byBhZGQgbWVzc2FnZSB0byBsaXN0XFxuICovXFxue3sjIyBkZWYuYWRkTXNnOiBhZGRDaGFuZ2VNZXNzYWdlKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIHsgcGF0aDogI319XFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjdXJyZW50IHByb3BlcnR5L2luZGV4IGZvciBib3RoIG5vcm1hbCBhbmQgaW50ZXJwb2xhdGVkIHByb3BlcnRpZXMvaW5kZXhlc1xcbiAqL1xcbnt7IyMgZGVmLmN1cnJQcm9wOnt7PyBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fVt0aGlzLl9hcmdzWyB7ez0gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX0gXV17ez8/fX17ez0gY3VyclByb3AgfX17ez99fSAjfX1cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvbmRpdGlvbiB0byB0ZXN0IHdoZXRoZXIgbm9ybWFsL2ludGVycG9sYXRlZCBwcm9wZXJ0eS9pbmRleCBleGlzdHNcXG4gKi9cXG57eyMjIGRlZi53YXNEZWZpbmVkOiBtLmhhc093blByb3BlcnR5KFxcbiAgICB7ez8gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX1cXG4gICAgICAgIHRoaXMuX2FyZ3NbIHt7PSBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fSBdXFxuICAgIHt7Pz99fVxcbiAgICAgICAgJ3t7PSBpdC5nZXRQYXRoTm9kZUtleShjdXJyTm9kZSkgfX0nXFxuICAgIHt7P319XFxuKSAjfX1cXG5cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvZGUgdG8gdXBkYXRlIGFjY2VzcyBwYXRoIGZvciBjdXJyZW50IHByb3BlcnR5XFxuICogQmVjYXVzZSBvZiB0aGUgcG9zc2liaWxpdHkgb2YgaW50ZXJwb2xhdGVkIHByb3BlcnRpZXMsIGl0IGNhbid0IGJlIGNhbGN1bGF0ZWQgaW4gdGVtcGxhdGUsIGl0IGNhbiBvbmx5IGJlIGNhbGN1bGF0ZWQgZHVyaW5nIGFjY2Vzc29yIGNhbGwuXFxuICovXFxue3sjIyBkZWYuY2hhbmdlQWNjZXNzUGF0aDpcXG4gICAgYWNjZXNzUGF0aCArPSB7ez8gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX1cXG4gICAgICAgIHt7PyBjdXJyTm9kZS5zeW50YXggPT0gJ2FycmF5JyB9fVxcbiAgICAgICAgICAgICdbJyArIHRoaXMuX2FyZ3NbIHt7PSBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fSBdICsgJ10nO1xcbiAgICAgICAge3s/P319XFxuICAgICAgICAgICAgJy4nICsgdGhpcy5fYXJnc1sge3s9IGN1cnJOb2RlLmludGVycG9sYXRlIH19IF07XFxuICAgICAgICB7ez99fVxcbiAgICB7ez8/fX1cXG4gICAgICAgICd7ez0gY3VyclByb3AgfX0nO1xcbiAgICB7ez99fVxcbiN9fVxcblxcblxcbi8qKlxcbiAqIEluc2VydHMgY29kZSB0byBwb3N0IHN0b3JlZCBtZXNzYWdlc1xcbiAqL1xcbnt7IyMgZGVmLnBvc3RNZXNzYWdlczpcXG4gICAgaWYgKG1lc3NhZ2VzLmxlbmd0aCkge1xcbiAgICAgICAge3sjIGRlZi5tb2RlbFBvc3RCYXRjaENvZGUgfX0oJ2RhdGFjaGFuZ2VzJywge1xcbiAgICAgICAgICAgIGNoYW5nZXM6IG1lc3NhZ2VzLFxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uOiBpbkNoYW5nZVRyYW5zYWN0aW9uXFxuICAgICAgICB9KTtcXG5cXG4gICAgICAgIG1lc3NhZ2VzLmZvckVhY2goZnVuY3Rpb24obXNnKSB7XFxuICAgICAgICAgICAge3sjIGRlZi5tb2RlbFBvc3RNZXNzYWdlQ29kZSB9fShtc2cucGF0aCwgbXNnKTtcXG4gICAgICAgIH0sIHRoaXMpO1xcbiAgICB9XFxuI319XFxuXCJcbiAgICAsIGluY2x1ZGVfY3JlYXRlX3RyZWUgPSBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbi8qKlxcbiAqIEluc2VydHMgY29kZSB0byBjcmVhdGUgbW9kZWwgdHJlZSBhcyBuZWNjZXNzYXJ5IGZvciBgc2V0YCBhbmQgYHNwbGljZWAgYWNjZXNzb3JzIGFuZCB0byBhZGQgbWVzc2FnZXMgdG8gc2VuZCBsaXN0IGlmIHRoZSB0cmVlIGNoYW5nZXMuXFxuICovXFxue3sjIyBkZWYuY3JlYXRlVHJlZTptZXRob2Q6XFxuICAgIHZhciB3YXNEZWYgPSB0cnVlO1xcbiAgICB2YXIgb2xkID0gbTtcXG5cXG4gICAge3sgdmFyIGVtcHR5UHJvcCA9IGl0LnBhcnNlZFBhdGhbMF0gJiYgaXQucGFyc2VkUGF0aFswXS5lbXB0eTsgfX1cXG4gICAge3s/IGVtcHR5UHJvcCB9fVxcbiAgICAgICAge3sgLyogY3JlYXRlIHRvcCBsZXZlbCBtb2RlbCBpZiBpdCB3YXMgbm90IHByZXZpb3VzbHkgZGVmaW5lZCAqLyB9fVxcbiAgICAgICAgaWYgKCEgbSkge1xcbiAgICAgICAgICAgIG0gPSB7eyMgZGVmLm1vZGVsQWNjZXNzUHJlZml4IH19ID0ge3s9IGVtcHR5UHJvcCB9fTtcXG4gICAgICAgICAgICB3YXNEZWYgPSBmYWxzZTtcXG5cXG4gICAgICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcXG4gICAgICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gJycsIHR5cGU6ICdhZGRlZCcsXFxuICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBtIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH1cXG4gICAge3s/P319XFxuICAgICAgICB7ez8gbWV0aG9kID09ICdzcGxpY2UnIH19XFxuICAgICAgICAgICAgaWYgKCEgbSkge1xcbiAgICAgICAge3s/fX1cXG4gICAgICAgICAgICAgICAgbSA9IHt7IyBkZWYubW9kZWxBY2Nlc3NQcmVmaXggfX0gPSBjbG9uZVRyZWUodmFsdWUpO1xcbiAgICAgICAgICAgICAgICB3YXNEZWYgPSB0eXBlb2Ygb2xkICE9ICd1bmRlZmluZWQnO1xcbiAgICAgICAge3s/IG1ldGhvZCA9PSAnc3BsaWNlJyB9fVxcbiAgICAgICAgICAgIH1cXG4gICAgICAgIHt7P319ICAgICAgIFxcbiAgICB7ez99fVxcblxcblxcbiAgICB7eyAvKiBjcmVhdGUgbW9kZWwgdHJlZSBpZiBpdCBkb2Vzbid0IGV4aXN0ICovIH19XFxuICAgIHt7ICB2YXIgbW9kZWxEYXRhUHJvcGVydHkgPSAnJztcXG4gICAgICAgIHZhciBuZXh0Tm9kZSA9IGl0LnBhcnNlZFBhdGhbMF07XFxuICAgICAgICB2YXIgY291bnQgPSBpdC5wYXJzZWRQYXRoLmxlbmd0aCAtIDE7XFxuXFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcXG4gICAgICAgICAgICB2YXIgY3Vyck5vZGUgPSBuZXh0Tm9kZTtcXG4gICAgICAgICAgICB2YXIgY3VyclByb3AgPSBjdXJyTm9kZS5wcm9wZXJ0eTtcXG4gICAgICAgICAgICBuZXh0Tm9kZSA9IGl0LnBhcnNlZFBhdGhbaSArIDFdO1xcbiAgICAgICAgICAgIHZhciBlbXB0eVByb3AgPSBuZXh0Tm9kZSAmJiBuZXh0Tm9kZS5lbXB0eTtcXG4gICAgfX1cXG5cXG4gICAgICAgIHt7IyBkZWYuY3JlYXRlVHJlZVN0ZXAgfX1cXG5cXG4gICAge3sgIH0gLyogZm9yIGxvb3AgKi8gfX1cXG4jfX1cXG5cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvZGUgdG8gY3JlYXRlIG9uZSBzdGVwIGluIHRoZSBtb2RlbCB0cmVlXFxuICovXFxue3sjIyBkZWYuY3JlYXRlVHJlZVN0ZXA6XFxuICAgIHt7IyBkZWYuY2hhbmdlQWNjZXNzUGF0aCB9fVxcblxcbiAgICBpZiAoISB7eyMgZGVmLndhc0RlZmluZWQgfX0pIHsgXFxuICAgICAgICB7eyAvKiBwcm9wZXJ0eSBkb2VzIG5vdCBleGlzdCAqLyB9fVxcbiAgICAgICAgbSA9IG17eyMgZGVmLmN1cnJQcm9wIH19ID0ge3s9IGVtcHR5UHJvcCB9fTtcXG5cXG4gICAgICAgIGlmICh0aGlzLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xcbiAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGFjY2Vzc1BhdGgsIHR5cGU6ICdhZGRlZCcsIFxcbiAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBtIH0pO1xcbiAgICAgICAgfVxcblxcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBte3sjIGRlZi5jdXJyUHJvcCB9fSAhPSAnb2JqZWN0Jykge1xcbiAgICAgICAge3sgLyogcHJvcGVydHkgaXMgbm90IG9iamVjdCAqLyB9fVxcbiAgICAgICAgdmFyIG9sZCA9IG17eyMgZGVmLmN1cnJQcm9wIH19O1xcbiAgICAgICAgbSA9IG17eyMgZGVmLmN1cnJQcm9wIH19ID0ge3s9IGVtcHR5UHJvcCB9fTtcXG5cXG4gICAgICAgIGlmICh0aGlzLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xcbiAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGFjY2Vzc1BhdGgsIHR5cGU6ICdjaGFuZ2VkJywgXFxuICAgICAgICAgICAgICAgICAgb2xkVmFsdWU6IG9sZCwgbmV3VmFsdWU6IG0gfSk7XFxuICAgICAgICB9XFxuXFxuICAgIH0gZWxzZSB7XFxuICAgICAgICB7eyAvKiBwcm9wZXJ0eSBleGlzdHMsIGp1c3QgdHJhdmVyc2UgZG93biB0aGUgbW9kZWwgdHJlZSAqLyB9fVxcbiAgICAgICAgbSA9IG17eyMgZGVmLmN1cnJQcm9wIH19O1xcbiAgICB9XFxuI319XFxuXCJcbiAgICAsIGluY2x1ZGVfdHJhdmVyc2VfdHJlZSA9IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb2RlIHRvIHRyYXZlcnNlIG1vZGVsIHRyZWUgZm9yIGBkZWxldGVgIGFuZCBgc3BsaWNlYCBhY2Nlc3NvcnMuXFxuICovXFxue3sjIyBkZWYudHJhdmVyc2VUcmVlOlxcbiAgICB7eyBcXG4gICAgICAgIHZhciBjb3VudCA9IGl0LnBhcnNlZFBhdGgubGVuZ3RoLTE7XFxuXFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsgXFxuICAgICAgICAgICAgdmFyIGN1cnJOb2RlID0gaXQucGFyc2VkUGF0aFtpXTtcXG4gICAgICAgICAgICB2YXIgY3VyclByb3AgPSBjdXJyTm9kZS5wcm9wZXJ0eTtcXG4gICAgfX1cXG4gICAgICAgICAgICB7eyMgZGVmLnRyYXZlcnNlVHJlZVN0ZXAgfX1cXG5cXG4gICAge3sgfSAvKiBmb3IgbG9vcCAqL1xcblxcbiAgICAgICAgdmFyIGkgPSBjb3VudDtcXG4gICAgICAgIHdoaWxlIChpLS0pIHsgLyogY2xvc2luZyBicmFjZXMgZm9yIGVsc2UncyBhYm92ZSAqL1xcbiAgICB9fVxcbiAgICAgICAgICAgIH1cXG4gICAge3sgfSAvKiB3aGlsZSBsb29wICovIH19XFxuI319XFxuXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb2RlIHRvIHRyYXZlcnNlIG9uZSBzdGVwIGluIHRoZSBtb2RlbCB0cmVlXFxuICovXFxue3sjIyBkZWYudHJhdmVyc2VUcmVlU3RlcDpcXG4gICAgaWYgKCEgKG0gJiYgbS5oYXNPd25Qcm9wZXJ0eSAmJiB7eyMgZGVmLndhc0RlZmluZWR9fSApIClcXG4gICAgICAgIHRyZWVEb2VzTm90RXhpc3QgPSB0cnVlO1xcbiAgICBlbHNlIHtcXG4gICAgICAgIG0gPSBte3sjIGRlZi5jdXJyUHJvcCB9fTtcXG4gICAgICAgIHt7IyBkZWYuY2hhbmdlQWNjZXNzUGF0aCB9fVxcbiAgICB7eyAvKiBicmFjZSBmcm9tIGVsc2UgaXMgbm90IGNsb3NlZCBvbiBwdXJwb3NlIC0gYWxsIGJyYWNlcyBhcmUgY2xvc2VkIGluIHdoaWxlIGxvb3AgKi8gfX1cXG4jfX1cXG5cIjtcblxudmFyIGRvdERlZiA9IHtcbiAgICBpbmNsdWRlX2RlZmluZXM6IGluY2x1ZGVfZGVmaW5lcyxcbiAgICBpbmNsdWRlX2NyZWF0ZV90cmVlOiBpbmNsdWRlX2NyZWF0ZV90cmVlLFxuICAgIGluY2x1ZGVfdHJhdmVyc2VfdHJlZTogaW5jbHVkZV90cmF2ZXJzZV90cmVlLFxuICAgIGdldFBhdGhOb2RlS2V5OiBwYXRoVXRpbHMuZ2V0UGF0aE5vZGVLZXksXG4gICAgbW9kZWxBY2Nlc3NQcmVmaXg6ICd0aGlzLl9tb2RlbC5fZGF0YScsXG4gICAgbW9kZWxQb3N0TWVzc2FnZUNvZGU6ICd0aGlzLl9tb2RlbC5faW50ZXJuYWxNZXNzZW5nZXIucG9zdE1lc3NhZ2UnLFxuICAgIG1vZGVsUG9zdEJhdGNoQ29kZTogJ3RoaXMuX21vZGVsLnBvc3RNZXNzYWdlU3luYycsXG4gICAgaW50ZXJuYWxNZXNzZW5nZXI6ICd0aGlzLl9tb2RlbC5faW50ZXJuYWxNZXNzZW5nZXInXG59O1xuXG52YXIgbW9kZWxEb3REZWYgPSBfKGRvdERlZikuY2xvbmUoKS5leHRlbmQoe1xuICAgIG1vZGVsQWNjZXNzUHJlZml4OiAndGhpcy5fZGF0YScsXG4gICAgbW9kZWxQb3N0TWVzc2FnZUNvZGU6ICd0aGlzLl9pbnRlcm5hbE1lc3Nlbmdlci5wb3N0TWVzc2FnZScsXG4gICAgbW9kZWxQb3N0QmF0Y2hDb2RlOiAndGhpcy5wb3N0TWVzc2FnZVN5bmMnLFxuICAgIGludGVybmFsTWVzc2VuZ2VyOiAndGhpcy5faW50ZXJuYWxNZXNzZW5nZXInXG59KS5fKCk7XG5cblxudmFyIGRvdFNldHRpbmdzID0gXy5jbG9uZShkb1QudGVtcGxhdGVTZXR0aW5ncyk7XG5kb3RTZXR0aW5ncy5zdHJpcCA9IGZhbHNlO1xuXG52YXIgc3ludGhlc2l6ZXJzID0gXy5tYXBLZXlzKHRlbXBsYXRlcywgZnVuY3Rpb24odG1wbCkge1xuICAgIHJldHVybiBkb1QudGVtcGxhdGUodG1wbCwgZG90U2V0dGluZ3MsIGRvdERlZik7IFxufSk7XG5cblxudmFyIG1vZGVsU3ludGhlc2l6ZXJzID0gXy5tYXBUb09iamVjdChbJ3NldCcsICdkZWwnLCAnc3BsaWNlJ10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICByZXR1cm4gZG9ULnRlbXBsYXRlKHRlbXBsYXRlc1ttZXRob2ROYW1lXSwgZG90U2V0dGluZ3MsIG1vZGVsRG90RGVmKTtcbn0pO1xuXG5cbi8qKlxuICogRnVuY3Rpb24gdGhhdCBzeW50aGVzaXplcyBhY2Nlc3NvciBtZXRob2RzLlxuICogRnVuY3Rpb24gaXMgbWVtb2l6ZWQgc28gYWNjZXNzb3JzIGFyZSBjYWNoZWQgKHVwIHRvIDEwMDApLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIE1vZGVsL01vZGVsUGF0aCBhY2Nlc3MgcGF0aFxuICogQHBhcmFtIHtBcnJheX0gcGFyc2VkUGF0aCBhcnJheSBvZiBwYXRoIG5vZGVzXG4gKiBAcmV0dXJuIHtPYmplY3RbRnVuY3Rpb25dfVxuICovXG52YXIgc3ludGhlc2l6ZVBhdGhNZXRob2RzID0gXy5tZW1vaXplKF9zeW50aGVzaXplUGF0aE1ldGhvZHMsIHVuZGVmaW5lZCwgMTAwMCk7XG5cbmZ1bmN0aW9uIF9zeW50aGVzaXplUGF0aE1ldGhvZHMocGF0aCwgcGFyc2VkUGF0aCkge1xuICAgIHZhciBtZXRob2RzID0gXy5tYXBLZXlzKHN5bnRoZXNpemVycywgZnVuY3Rpb24oc3ludGhzenIpIHtcbiAgICAgICAgcmV0dXJuIF9zeW50aGVzaXplKHN5bnRoc3pyLCBwYXRoLCBwYXJzZWRQYXRoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbWV0aG9kcztcbn1cblxuXG52YXIgbm9ybWFsaXplU3BsaWNlSW5kZXggPSBtb2RlbFV0aWxzLm5vcm1hbGl6ZVNwbGljZUluZGV4OyAvLyB1c2VkIGluIHNwbGljZS5kb3QuanNcblxuXG5mdW5jdGlvbiBfc3ludGhlc2l6ZShzeW50aGVzaXplciwgcGF0aCwgcGFyc2VkUGF0aCkge1xuICAgIHZhciBtZXRob2RcbiAgICAgICAgLCBtZXRob2RDb2RlID0gc3ludGhlc2l6ZXIoe1xuICAgICAgICAgICAgcGFyc2VkUGF0aDogcGFyc2VkUGF0aCxcbiAgICAgICAgICAgIGdldFBhdGhOb2RlS2V5OiBwYXRoVXRpbHMuZ2V0UGF0aE5vZGVLZXlcbiAgICAgICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgICBldmFsKG1ldGhvZENvZGUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgTW9kZWxFcnJvcignTW9kZWxQYXRoIG1ldGhvZCBjb21waWxhdGlvbiBlcnJvcjsgcGF0aDogJyArIHBhdGggKyAnLCBjb2RlOiAnICsgbWV0aG9kQ29kZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1ldGhvZDtcblxuXG4gICAgLy8gZnVuY3Rpb25zIHVzZWQgYnkgbWV0aG9kcyBgc2V0YCwgYGRlbGV0ZWAgYW5kIGBzcGxpY2VgIChzeW50aGVzaXplZCBieSB0ZW1wbGF0ZSlcbiAgICBmdW5jdGlvbiBhZGRDaGFuZ2VNZXNzYWdlKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIG1zZykge1xuICAgICAgICBtZXNzYWdlcy5wdXNoKG1zZyk7XG4gICAgICAgIG1lc3NhZ2VzSGFzaFttc2cucGF0aF0gPSBtc2c7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkVHJlZUNoYW5nZXNNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCByb290UGF0aCwgb2xkVmFsdWUsIG5ld1ZhbHVlKSB7XG4gICAgICAgIHZhciBvbGRJc1RyZWUgPSB2YWx1ZUlzVHJlZShvbGRWYWx1ZSlcbiAgICAgICAgICAgICwgbmV3SXNUcmVlID0gdmFsdWVJc1RyZWUobmV3VmFsdWUpO1xuXG4gICAgICAgIGlmIChuZXdJc1RyZWUpXG4gICAgICAgICAgICBhZGRNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCByb290UGF0aCwgbmV3VmFsdWUsICdhZGRlZCcsICduZXdWYWx1ZScpO1xuICAgICAgICBcbiAgICAgICAgaWYgKG9sZElzVHJlZSlcbiAgICAgICAgICAgIGFkZE1lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIHJvb3RQYXRoLCBvbGRWYWx1ZSwgJ3JlbW92ZWQnLCAnb2xkVmFsdWUnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCByb290UGF0aCwgb2JqLCBtc2dUeXBlLCB2YWx1ZVByb3ApIHtcbiAgICAgICAgX2FkZE1lc3NhZ2VzKHJvb3RQYXRoLCBvYmopO1xuXG5cbiAgICAgICAgZnVuY3Rpb24gX2FkZE1lc3NhZ2VzKHJvb3RQYXRoLCBvYmopIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aFN5bnRheCA9IHJvb3RQYXRoICsgJ1skJF0nO1xuICAgICAgICAgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICBhZGRNZXNzYWdlKHZhbHVlLCBpbmRleCwgcGF0aFN5bnRheCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBwYXRoU3ludGF4ID0gcm9vdFBhdGggKyAnLiQkJztcbiAgICAgICAgICAgICAgICBfLmVhY2hLZXkob2JqLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZE1lc3NhZ2UodmFsdWUsIGtleSwgcGF0aFN5bnRheCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBhZGRNZXNzYWdlKHZhbHVlLCBrZXksIHBhdGhTeW50YXgpIHtcbiAgICAgICAgICAgIHZhciBwYXRoID0gcGF0aFN5bnRheC5yZXBsYWNlKCckJCcsIGtleSlcbiAgICAgICAgICAgICAgICAsIGV4aXN0aW5nTXNnID0gbWVzc2FnZXNIYXNoW3BhdGhdO1xuXG4gICAgICAgICAgICBpZiAoZXhpc3RpbmdNc2cpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdNc2cudHlwZSA9PSBtc2dUeXBlKVxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ3NldHRlciBlcnJvcjogc2FtZSBtZXNzYWdlIHR5cGUgcG9zdGVkIG9uIHRoZSBzYW1lIHBhdGgnKTtcbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdNc2cudHlwZSA9ICdjaGFuZ2VkJztcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdNc2dbdmFsdWVQcm9wXSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIG1zZyA9IHsgcGF0aDogcGF0aCwgdHlwZTogbXNnVHlwZSB9O1xuICAgICAgICAgICAgICAgIG1zZ1t2YWx1ZVByb3BdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgYWRkQ2hhbmdlTWVzc2FnZShtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCBtc2cpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodmFsdWVJc1RyZWUodmFsdWUpKVxuICAgICAgICAgICAgICAgIF9hZGRNZXNzYWdlcyhwYXRoLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbG9uZVRyZWUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlSXNOb3JtYWxPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICAgPyBfLmRlZXBDbG9uZSh2YWx1ZSlcbiAgICAgICAgICAgICAgICA6IHZhbHVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByb3RlY3RWYWx1ZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gISB2YWx1ZUlzTm9ybWFsT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICAgICAgICA6IEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWUuc2xpY2UoKVxuICAgICAgICAgICAgICAgICAgICA6IE9iamVjdC5jcmVhdGUodmFsdWUpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlSXNUcmVlKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZUlzTm9ybWFsT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICAgICYmIE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsdWVJc05vcm1hbE9iamVjdCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbFxuICAgICAgICAgICAgICAgICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiXG4gICAgICAgICAgICAgICAgJiYgISAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKVxuICAgICAgICAgICAgICAgICYmICEgKHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRCYXRjaElkc1RvTWVzc2FnZShtc2csIGJhdGNoSWQsIG1zZ0lkKSB7XG4gICAgICAgIF8uZGVmaW5lUHJvcGVydGllcyhtc2csIHtcbiAgICAgICAgICAgIF9fYmF0Y2hfaWQ6IGJhdGNoSWQsXG4gICAgICAgICAgICBfX21zZ19pZDogbXNnSWRcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogRXhwb3J0cyBgc3ludGhlc2l6ZWAgZnVuY3Rpb24gd2l0aCB0aGUgZm9sbG93aW5nOlxuICpcbiAqIC0gLm1vZGVsTWV0aG9kcy5zZXQgLSBgc2V0YCBtZXRob2QgZm9yIE1vZGVsXG4gKiAtIC5tb2RlbE1ldGhvZHMuZGVsIC0gYGRlbGAgbWV0aG9kIGZvciBNb2RlbFxuICogLSAubW9kZWxNZXRob2RzLnNwbGljZSAtIGBzcGxpY2VgIG1ldGhvZCBmb3IgTW9kZWxcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBzeW50aGVzaXplUGF0aE1ldGhvZHM7XG5cbnZhciBtb2RlbE1ldGhvZHMgPSBfLm1hcEtleXMobW9kZWxTeW50aGVzaXplcnMsIGZ1bmN0aW9uKHN5bnRoZXNpemVyKSB7XG4gICAgcmV0dXJuIF9zeW50aGVzaXplKHN5bnRoZXNpemVyLCAnJywgW10pO1xufSk7XG5cbnN5bnRoZXNpemVQYXRoTWV0aG9kcy5tb2RlbE1ldGhvZHMgPSBtb2RlbE1ldGhvZHM7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogUmVnaXN0cmllcyBvZiBmYWNldHMgYW5kIG9mIGNvbXBvbmVudHNcbiAqXG4gKiAtIFtmYWNldHNdKC4vY29tcG9uZW50cy9jX2ZhY2V0cy9jZl9yZWdpc3RyeS5qcy5odG1sKVxuICogLSBbY29tcG9uZW50c10oLi9jb21wb25lbnRzL2NfcmVnaXN0cnkuanMuaHRtbClcbiAqL1xudmFyIHJlZ2lzdHJ5ID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZmFjZXRzOiByZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvY2ZfcmVnaXN0cnknKSxcbiAgICBjb21wb25lbnRzOiByZXF1aXJlKCcuL2NvbXBvbmVudHMvY19yZWdpc3RyeScpLFxuICAgIGNvbW1hbmRzOiByZXF1aXJlKCcuL2NvbW1hbmQvY21kX3JlZ2lzdHJ5Jylcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIDxhIG5hbWU9XCJjb21wb25lbnRzLWRvbS1jb25zdHJ1Y3RvcnNcIj48L2E+XG4vLyAjIyNkb20gZXZlbnRzIGNvbnN0cnVjdG9yc1xuXG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvUmVmZXJlbmNlL0V2ZW50c1xuXG52YXIgZXZlbnRUeXBlcyA9IHtcbiAgICBDbGlwYm9hcmRFdmVudDogWydjb3B5JywgJ2N1dCcsICdwYXN0ZScsICdiZWZvcmVjb3B5JywgJ2JlZm9yZWN1dCcsICdiZWZvcmVwYXN0ZSddLFxuICAgIEV2ZW50OiBbJ2lucHV0JywgJ3JlYWR5c3RhdGVjaGFuZ2UnXSxcbiAgICBGb2N1c0V2ZW50OiBbJ2ZvY3VzJywgJ2JsdXInLCAnZm9jdXNpbicsICdmb2N1c291dCddLFxuICAgIEtleWJvYXJkRXZlbnQ6IFsna2V5ZG93bicsICdrZXlwcmVzcycsICAna2V5dXAnXSxcbiAgICBNb3VzZUV2ZW50OiBbJ2NsaWNrJywgJ2NvbnRleHRtZW51JywgJ2RibGNsaWNrJywgJ21vdXNlZG93bicsICdtb3VzZXVwJyxcbiAgICAgICAgICAgICAgICAgJ21vdXNlZW50ZXInLCAnbW91c2VsZWF2ZScsICdtb3VzZW1vdmUnLCAnbW91c2VvdXQnLCAnbW91c2VvdmVyJyxcbiAgICAgICAgICAgICAgICAgJ3Nob3cnIC8qIGNvbnRleHQgbWVudSAqL10sXG4gICAgVG91Y2hFdmVudDogWyd0b3VjaHN0YXJ0JywgJ3RvdWNoZW5kJywgJ3RvdWNobW92ZScsICd0b3VjaGVudGVyJywgJ3RvdWNobGVhdmUnLCAndG91Y2hjYW5jZWwnXSxcbn07XG5cblxuLy8gbW9jayB3aW5kb3cgYW5kIGV2ZW50IGNvbnN0cnVjdG9ycyBmb3IgdGVzdGluZ1xuaWYgKHR5cGVvZiB3aW5kb3cgIT0gJ3VuZGVmaW5lZCcpXG4gICAgdmFyIGdsb2JhbCA9IHdpbmRvdztcbmVsc2Uge1xuICAgIGdsb2JhbCA9IHt9O1xuICAgIF8uZWFjaEtleShldmVudFR5cGVzLCBmdW5jdGlvbihlVHlwZXMsIGV2ZW50Q29uc3RydWN0b3JOYW1lKSB7XG4gICAgICAgIHZhciBldmVudENvbnN0cnVjdG9yID0gXy5tYWtlRnVuY3Rpb24oZXZlbnRDb25zdHJ1Y3Rvck5hbWUsICd0eXBlJywgJ3Byb3BlcnRpZXMnLFxuICAgICAgICAgICAgJ3RoaXMudHlwZSA9IHR5cGU7IF8uZXh0ZW5kKHRoaXMsIHByb3BlcnRpZXMpOycpO1xuICAgICAgICBnbG9iYWxbZXZlbnRDb25zdHJ1Y3Rvck5hbWVdID0gZXZlbnRDb25zdHJ1Y3RvcjtcbiAgICB9KTtcbn1cblxuXG52YXIgZG9tRXZlbnRzQ29uc3RydWN0b3JzID0ge307XG5cbl8uZWFjaEtleShldmVudFR5cGVzLCBmdW5jdGlvbihlVHlwZXMsIGV2ZW50Q29uc3RydWN0b3JOYW1lKSB7XG4gICAgZVR5cGVzLmZvckVhY2goZnVuY3Rpb24odHlwZSkge1xuICAgICAgICBpZiAoT2JqZWN0Lmhhc093blByb3BlcnR5KGRvbUV2ZW50c0NvbnN0cnVjdG9ycywgdHlwZSkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2R1cGxpY2F0ZSBldmVudCB0eXBlICcgKyB0eXBlKTtcblxuICAgICAgICBkb21FdmVudHNDb25zdHJ1Y3RvcnNbdHlwZV0gPSBnbG9iYWxbZXZlbnRDb25zdHJ1Y3Rvck5hbWVdO1xuICAgIH0pO1xufSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBkb21FdmVudHNDb25zdHJ1Y3RvcnM7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIE1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXIvbV9zb3VyY2UnKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9jX2NsYXNzJylcbiAgICAsIGRvbUV2ZW50c0NvbnN0cnVjdG9ycyA9IHJlcXVpcmUoJy4vZGVfY29uc3RycycpIC8vIFRPRE8gbWVyZ2Ugd2l0aCBET01FdmVudFNvdXJjZSA/P1xuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxudmFyIERPTUVtaXR0ZXJTb3VyY2UgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NhZ2VTb3VyY2UsICdET01FbWl0dGVyU291cmNlJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhET01FbWl0dGVyU291cmNlLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgaW5pdDogaW5pdCxcbiAgICBkZXN0cm95OiBET01FbWl0dGVyU291cmNlJGRlc3Ryb3ksXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogXy5wYXJ0aWFsKHNvdXJjZVN1YnNjcmliZXJNZXRob2QsICdhZGRFdmVudExpc3RlbmVyJyksXG4gICAgcmVtb3ZlU291cmNlU3Vic2NyaWJlcjogXy5wYXJ0aWFsKHNvdXJjZVN1YnNjcmliZXJNZXRob2QsICdyZW1vdmVFdmVudExpc3RlbmVyJyksXG4gICAgcG9zdE1lc3NhZ2U6IERPTUVtaXR0ZXJTb3VyY2UkcG9zdE1lc3NhZ2UsXG4gICAgdHJpZ2dlcjogdHJpZ2dlcixcblxuICAgIC8vIGNsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICBlbWl0dGVyOiBlbWl0dGVyLFxuICAgIGhhbmRsZUV2ZW50OiBoYW5kbGVFdmVudCwgIC8vIGV2ZW50IGRpc3BhdGNoZXIgLSBhcyBkZWZpbmVkIGJ5IEV2ZW50IERPTSBBUElcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IERPTUVtaXR0ZXJTb3VyY2U7XG5cblxudmFyIHVzZUNhcHR1cmVQYXR0ZXJuID0gL19fY2FwdHVyZSQvXG4gICAgLCB1c2VDYXB0dXJlUG9zdGZpeCA9ICdfX2NhcHR1cmUnO1xuXG5cbi8vIGluaXQgRE9NIGV2ZW50IHNvdXJjZVxuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NlbmdlckFQSU9yQ2xhc3MsIGV2ZW50RW1pdHRlcikge1xuICAgIHRoaXMuZXZlbnRFbWl0dGVyID0gZXZlbnRFbWl0dGVyO1xuICAgIE1lc3NhZ2VTb3VyY2UucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG5mdW5jdGlvbiBET01FbWl0dGVyU291cmNlJGRlc3Ryb3koKSB7XG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGRlbGV0ZSB0aGlzLmV2ZW50RW1pdHRlcjtcbn1cblxuXG4vLyBnZXQgRE9NIGVsZW1lbnQgb2YgY29tcG9uZW50XG5mdW5jdGlvbiBlbWl0dGVyKCkge1xuICAgIHJldHVybiB0aGlzLmV2ZW50RW1pdHRlcjtcbn1cblxuXG5mdW5jdGlvbiBzb3VyY2VTdWJzY3JpYmVyTWV0aG9kKG1ldGhvZCwgZXZlbnRUeXBlKSB7XG4gICAgaWYgKCEgKGV2ZW50VHlwZSAmJiB0eXBlb2YgZXZlbnRUeXBlID09ICdzdHJpbmcnKSkgcmV0dXJuO1xuICAgIHZhciBjYXB0dXJlID0gdXNlQ2FwdHVyZVBhdHRlcm4udGVzdChldmVudFR5cGUpO1xuICAgIGV2ZW50VHlwZSA9IGV2ZW50VHlwZS5yZXBsYWNlKHVzZUNhcHR1cmVQYXR0ZXJuLCAnJyk7XG4gICAgdGhpcy5lbWl0dGVyKClbbWV0aG9kXShldmVudFR5cGUsIHRoaXMsIGNhcHR1cmUpO1xufVxuXG5cbi8vIGV2ZW50IGRpc3BhdGNoZXIgLSBhcyBkZWZpbmVkIGJ5IEV2ZW50IERPTSBBUElcbmZ1bmN0aW9uIGhhbmRsZUV2ZW50KGV2ZW50KSB7XG4gICAgdmFyIGlzQ2FwdHVyZVBoYXNlO1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnKVxuICAgICAgICBpc0NhcHR1cmVQaGFzZSA9IGV2ZW50LmV2ZW50UGhhc2UgPT0gd2luZG93LkV2ZW50LkNBUFRVUklOR19QSEFTRTtcblxuICAgIGlmIChpc0NhcHR1cmVQaGFzZSlcbiAgICAgICAgZXZlbnQgKz0gdXNlQ2FwdHVyZVBvc3RmaXg7XG5cbiAgICB0aGlzLmRpc3BhdGNoTWVzc2FnZShldmVudC50eXBlLCBldmVudCk7XG59XG5cblxuZnVuY3Rpb24gRE9NRW1pdHRlclNvdXJjZSRwb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhKSB7XG4gICAgdGhpcy5tZXNzZW5nZXIucG9zdE1lc3NhZ2VTeW5jKG1lc3NhZ2UsIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIHRyaWdnZXIoZXZlbnRUeXBlLCBwcm9wZXJ0aWVzKSB7XG4gICAgY2hlY2soZXZlbnRUeXBlLCBTdHJpbmcpO1xuICAgIGNoZWNrKHByb3BlcnRpZXMsIE1hdGNoLk9wdGlvbmFsKE9iamVjdCkpO1xuXG4gICAgZXZlbnRUeXBlID0gZXZlbnRUeXBlLnJlcGxhY2UodXNlQ2FwdHVyZVBhdHRlcm4sICcnKTtcbiAgICB2YXIgRXZlbnRDb25zdHJ1Y3RvciA9IGRvbUV2ZW50c0NvbnN0cnVjdG9yc1tldmVudFR5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBFdmVudENvbnN0cnVjdG9yICE9ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgZXZlbnQgdHlwZScpO1xuXG4gICAgLy8gY2hlY2sgaWYgaXQgaXMgY29ycmVjdFxuICAgIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPSAndW5kZWZpbmVkJylcbiAgICAgICAgcHJvcGVydGllcy50eXBlID0gZXZlbnRUeXBlO1xuXG4gICAgdmFyIGRvbUV2ZW50ID0gbmV3IEV2ZW50Q29uc3RydWN0b3IoZXZlbnRUeXBlLCBwcm9wZXJ0aWVzKTtcbiAgICB2YXIgbm90Q2FuY2VsbGVkID0gdGhpcy5lbWl0dGVyKCkuZGlzcGF0Y2hFdmVudChkb21FdmVudCk7XG4gICAgcmV0dXJuIG5vdENhbmNlbGxlZDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBgbWlsby5tYWlsYFxuICogSXQgaXMgYW4gYXBwbGljYXRpb24gbGV2ZWwgbWVzc2VuZ2VyIHRoYXQgaXMgYW4gaW5zdGFuY2Ugb2YgTWVzc2VuZ2VyIGNsYXNzLlxuICpcbiAqIEF0IHRoZSBtb21lbnQsIGluIGFkZGl0aW9uIHRvIGFwcGxpY2F0aW9uIG1lc3NhZ2VzIHRoYXQgeW91IGRlZmluZSwgeW91IGNhbiBzdWJzY3JpYmUgdG8gX19kb21yZWFkeV9fIG1lc3NhZ2UgdGhhdCBpcyBndWFyYW50ZWVkIHRvIGZpcmUgb25jZSxcbiAqIGV2ZW4gaWYgRE9NIHdhcyByZWFkeSBhdCB0aGUgdGltZSBvZiB0aGUgc3Vic2NyaXB0aW9uLlxuICpcbiAqIE1lc3NhZ2luZyBiZXR3ZWVuIGZyYW1lcyBpcyBhdmFpbGFibGUgdmlhIG1pbG8ubWFpbC4gU2VlIFtGcmFtZSBmYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0cy9GcmFtZS5qcy5odG1sKS5cbiAqXG4gKiBTZWUgW01lc3Nlbmdlcl0oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpLlxuICogXG4qKi9cblxuXG52YXIgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyJylcbiAgICAsIE1haWxNc2dBUEkgPSByZXF1aXJlKCcuL21haWxfYXBpJylcbiAgICAsIE1haWxNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi9tYWlsX3NvdXJjZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxudmFyIG1pbG9NYWlsID0gbmV3IE1lc3NlbmdlcjtcblxudmFyIG1haWxNc2dTb3VyY2UgPSBuZXcgTWFpbE1lc3NhZ2VTb3VyY2UobWlsb01haWwsIHsgdHJpZ2dlcjogJ3RyaWdnZXInIH0sIG5ldyBNYWlsTXNnQVBJKTtcblxubWlsb01haWwuX3NldE1lc3NhZ2VTb3VyY2UobWFpbE1zZ1NvdXJjZSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBtaWxvTWFpbDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1lc3NlbmdlckFQSSA9IHJlcXVpcmUoJy4uLy4uL21lc3Nlbmdlci9tX2FwaScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbnZhciBNYWlsTXNnQVBJID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzZW5nZXJBUEksICdNYWlsTXNnQVBJJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhNYWlsTXNnQVBJLCB7XG4gICAgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlOiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UsXG4gICAgZmlsdGVyU291cmNlTWVzc2FnZTogZmlsdGVyU291cmNlTWVzc2FnZVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTWFpbE1zZ0FQSTtcblxuXG4vLyBUT0RPOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gcmVsZXZhbnQgRE9NIGV2ZW50IGRlcGVuZGVudCBvbiBlbGVtZW50IHRhZ1xuLy8gQ2FuIGFsc28gaW1wbGVtZW50IGJlZm9yZWRhdGFjaGFuZ2VkIGV2ZW50IHRvIGFsbG93IHByZXZlbnRpbmcgdGhlIGNoYW5nZVxuLy8gdHJhbnNsYXRlVG9Eb21FdmVudFxudmFyIHdpbmRvd01lc3NhZ2VSZWdFeHAgPSAvXm1lc3NhZ2VcXDovXG4gICAgLCB3aW5kb3dNZXNzYWdlUHJlZml4ID0gJ21lc3NhZ2U6JztcblxuZnVuY3Rpb24gdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICBpZiAobWVzc2FnZSA9PSAnZG9tcmVhZHknKVxuICAgICAgICByZXR1cm4gJ3JlYWR5c3RhdGVjaGFuZ2UnO1xuICAgIGVsc2UgaWYgKHdpbmRvd01lc3NhZ2VSZWdFeHAudGVzdChtZXNzYWdlKSlcbiAgICAgICAgcmV0dXJuICdtZXNzYWdlJztcbn1cblxuXG4vLyBmaWx0ZXJEYXRhTWVzc2FnZVxuZnVuY3Rpb24gZmlsdGVyU291cmNlTWVzc2FnZShzb3VyY2VNZXNzYWdlLCBtc2dUeXBlLCBtc2dEYXRhKSB7XG4gICAgaWYgKHNvdXJjZU1lc3NhZ2UgPT0gJ3JlYWR5c3RhdGVjaGFuZ2UnKSB7XG4gICAgICAgIC8vcmV0dXJuIGRvY3VtZW50LnJlYWR5U3RhdGUgPT0gJ2ludGVyYWN0aXZlJztcbiAgICAgICAgLy8gIHJldHVybiBmYWxzZTtcbiAgICAgICAgLy8gXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2RvbVJlYWR5RmlyZWQnLCB0cnVlLCBfLldSSVQpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHNvdXJjZU1lc3NhZ2UgPT0gJ21lc3NhZ2UnKVxuICAgICAgICByZXR1cm4gd2luZG93TWVzc2FnZVByZWZpeCArIG1zZ0RhdGEuZGF0YS50eXBlID09IG1zZ1R5cGU7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4uLy4uL21lc3Nlbmdlci9tX3NvdXJjZScpXG4gICAgLCBkb21FdmVudHNDb25zdHJ1Y3RvcnMgPSByZXF1aXJlKCcuLi9kZV9jb25zdHJzJylcbiAgICAsIE1haWxNZXNzYWdlU291cmNlRXJyb3IgPSByZXF1aXJlKCcuLi8uLi91dGlsL2Vycm9yJykuTWFpbE1lc3NhZ2VTb3VyY2VcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxudmFyIE1haWxNZXNzYWdlU291cmNlID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzYWdlU291cmNlLCAnTWFpbE1lc3NhZ2VTb3VyY2UnLCB0cnVlKTtcblxuXG5fLmV4dGVuZFByb3RvKE1haWxNZXNzYWdlU291cmNlLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogYWRkU291cmNlU3Vic2NyaWJlcixcbiAgICByZW1vdmVTb3VyY2VTdWJzY3JpYmVyOiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyLFxuICAgIHRyaWdnZXI6IHRyaWdnZXIsXG5cbiAgICAvLyBjbGFzcyBzcGVjaWZpYyBtZXRob2RzXG4gICAgX3dpbmRvd1N1YnNjcmliZXJNZXRob2Q6IF93aW5kb3dTdWJzY3JpYmVyTWV0aG9kLFxuICAgIGhhbmRsZUV2ZW50OiBoYW5kbGVFdmVudCwgIC8vIGV2ZW50IGRpc3BhdGNoZXIgLSBhcyBkZWZpbmVkIGJ5IEV2ZW50IERPTSBBUElcbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWFpbE1lc3NhZ2VTb3VyY2U7XG5cblxuZnVuY3Rpb24gYWRkU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgaWYgKGlzUmVhZHlTdGF0ZUNoYW5nZShzb3VyY2VNZXNzYWdlKSkge1xuICAgICAgICBpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PSAnbG9hZGluZycpXG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWFkeXN0YXRlY2hhbmdlJywgdGhpcywgZmFsc2UpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBFdmVudENvbnN0cnVjdG9yID0gZG9tRXZlbnRzQ29uc3RydWN0b3JzLnJlYWR5c3RhdGVjaGFuZ2U7XG4gICAgICAgICAgICB2YXIgZG9tRXZlbnQgPSBuZXcgRXZlbnRDb25zdHJ1Y3RvcigncmVhZHlzdGF0ZWNoYW5nZScsIHsgdGFyZ2V0OiBkb2N1bWVudCB9KTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hNZXNzYWdlKCdyZWFkeXN0YXRlY2hhbmdlJywgZG9tRXZlbnQpO1xuICAgICAgICB9XG4gICAgfSBlbHNlXG4gICAgICAgIHRoaXMuX3dpbmRvd1N1YnNjcmliZXJNZXRob2QoJ2FkZEV2ZW50TGlzdGVuZXInLCBzb3VyY2VNZXNzYWdlKTtcbn1cblxuXG5mdW5jdGlvbiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICBpZiAoaXNSZWFkeVN0YXRlQ2hhbmdlKHNvdXJjZU1lc3NhZ2UpKVxuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdyZWFkeXN0YXRlY2hhbmdlJywgdGhpcywgZmFsc2UpO1xuICAgIGVsc2UgXG4gICAgICAgIHRoaXMuX3dpbmRvd1N1YnNjcmliZXJNZXRob2QoJ3JlbW92ZUV2ZW50TGlzdGVuZXInLCBzb3VyY2VNZXNzYWdlKTtcbn1cblxuXG5mdW5jdGlvbiBpc1JlYWR5U3RhdGVDaGFuZ2Uoc291cmNlTWVzc2FnZSkge1xuICAgIHJldHVybiBzb3VyY2VNZXNzYWdlID09ICdyZWFkeXN0YXRlY2hhbmdlJyAmJiB0eXBlb2YgZG9jdW1lbnQgPT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIGlzV2luZG93TWVzc2FnZShzb3VyY2VNZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNvdXJjZU1lc3NhZ2UgPT0gJ21lc3NhZ2UnICYmIHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIF93aW5kb3dTdWJzY3JpYmVyTWV0aG9kKG1ldGhvZCwgc291cmNlTWVzc2FnZSkge1xuICAgIGlmIChpc1dpbmRvd01lc3NhZ2Uoc291cmNlTWVzc2FnZSkpXG4gICAgICAgIHdpbmRvd1ttZXRob2RdKCdtZXNzYWdlJywgdGhpcywgZmFsc2UpO1xufVxuXG5cbi8vIGV2ZW50IGRpc3BhdGNoZXIgLSBhcyBkZWZpbmVkIGJ5IEV2ZW50IERPTSBBUElcbmZ1bmN0aW9uIGhhbmRsZUV2ZW50KGV2ZW50KSB7XG4gICAgdGhpcy5kaXNwYXRjaE1lc3NhZ2UoZXZlbnQudHlwZSwgZXZlbnQpO1xufVxuXG5cbmZ1bmN0aW9uIHRyaWdnZXIobXNnVHlwZSwgZGF0YSkge1xuICAgIGRhdGEgPSBkYXRhIHx8IHt9O1xuICAgIGRhdGEudHlwZSA9ICdtZXNzYWdlOicgKyBtc2dUeXBlO1xuICAgIFxuICAgIGlmICh0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnKVxuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoZGF0YSwgJyonKVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgRE9NRW1pdHRlclNvdXJjZSA9IHJlcXVpcmUoJy4vZG9tX3NvdXJjZScpO1xuXG5cbnZhciB3aW5kb3dTZXJ2aWNlID0gbmV3IE1lc3NlbmdlcjtcbnZhciBkb21FbWl0dGVyU291cmNlID0gbmV3IERPTUVtaXR0ZXJTb3VyY2Uod2luZG93U2VydmljZSwgeyB0cmlnZ2VyOiAndHJpZ2dlcicgfSwgdW5kZWZpbmVkLCB3aW5kb3cpO1xud2luZG93U2VydmljZS5fc2V0TWVzc2FnZVNvdXJjZShkb21FbWl0dGVyU291cmNlKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHdpbmRvd1NlcnZpY2U7XG5cblxuXy5leHRlbmQod2luZG93U2VydmljZSwge1xuICAgIGlzVG9wOiB3aW5kb3dTZXJ2aWNlX2lzVG9wXG59KTtcblxuXG5mdW5jdGlvbiB3aW5kb3dTZXJ2aWNlX2lzVG9wKCkge1xuICAgIHJldHVybiB3aW5kb3cudG9wID09IHdpbmRvdy5zZWxmIHx8IHdpbmRvdy5fX2thcm1hX187XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jbGFzc2VzL1ZpZXcnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9Hcm91cCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL1dyYXBwZXInKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9UZXh0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvU2VsZWN0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvSW5wdXQnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9JbnB1dExpc3QnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9UZXh0YXJlYScpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL1JhZGlvR3JvdXAnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9CdXR0b24nKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9IeXBlcmxpbmsnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9MaXN0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvTGlzdEl0ZW0nKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9UaW1lJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvRGF0ZScpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0NvbWJvJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvU3VwZXJDb21ibycpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0NvbWJvTGlzdCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0ltYWdlJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvRHJvcFRhcmdldCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0ZvbGRUcmVlJyk7XG5cbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9ib290c3RyYXAvRHJvcGRvd24nKTtcbi8vIHJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9ib290c3RyYXAvRGlhbG9nJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9Eb20nKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9EYXRhJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvRnJhbWUnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9FdmVudHMnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9PcHRpb25zJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvVGVtcGxhdGUnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9Db250YWluZXInKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9Nb2RlbEZhY2V0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvRHJhZycpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL0Ryb3AnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9MaXN0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvSXRlbScpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL1RyYW5zZmVyJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogYG1pbG8udXRpbHMuY2hlY2tgXG4gKlxuICogQ2hlY2sgaXMgYSBtb2R1bGUgZm9yIHBhcmFtZXRlcnMgY2hlY2tpbmcgZXh0cmFjdGVkIGZyb20gW01ldGVvcl0oaHR0cDovL2RvY3MubWV0ZW9yLmNvbS8pIGZyYW1ld29yay5cbiAqXG4gKiBJdCBhbGxvd3MgdG8gYm90aCBkb2N1bWVudCBhbmQgdG8gY2hlY2sgcGFyYW1ldGVyIHR5cGVzIGluIHlvdXIgZnVuY3Rpb25cbiAqIG1ha2luZyBjb2RlIGJvdGggcmVhZGFibGUgYW5kIHN0YWJsZS5cbiAqXG4gKlxuICogIyMjIFVzYWdlXG4gKmBgYFxuICogdmFyIGNoZWNrID0gbWlsby5jaGVja1xuICogICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcbiAqXG4gKiBmdW5jdGlvbiBNeShuYW1lLCBvYmosIGNiKSB7XG4gKiAgICAgLy8gaWYgYW55IG9mIGNoZWNrcyBmYWlsIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duXG4gKiAgICAgY2hlY2sobmFtZSwgU3RyaW5nKTtcbiAqICAgICBjaGVjayhvYmosIE1hdGNoLk9iamVjdEluY2x1ZGluZyh7IG9wdGlvbnM6IE9iamVjdCB9KSk7XG4gKiAgICAgY2hlY2soY2IsIEZ1bmN0aW9uKTtcbiAqXG4gKiAgICAgLy8gLi4uIHlvdXIgY29kZVxuICogfVxuICpgYGBcbiAqIFNlZSBbTWV0ZW9yIGRvY3NdKGh0dHA6Ly9kb2NzLm1ldGVvci5jb20vI21hdGNoKSB0byBzZWUgaG93IGl0IHdvcmtzXG4gKlxuICpcbiAqICMjIyBQYXR0ZXJuc1xuICpcbiAqIEFsbCBwYXR0ZXJucyBhbmQgZnVuY3Rpb25zIGRlc2NyaWJlZCBpbiBNZXRlb3IgZG9jcyB3b3JrLlxuICpcbiAqIFVubGlrZSBpbiBNZXRlb3IsIE9iamVjdCBwYXR0ZXJuIG1hdGNoZXMgaW5zdGFuY2Ugb2YgYW55IGNsYXNzLFxuICogbm90IG9ubHkgcGxhaW4gb2JqZWN0LlxuICpcbiAqIEluIGFkZGl0aW9uIHRvIHBhdHRlcm5zIGRlc2NyaWJlZCBpbiBNZXRlb3IgZG9jcyB0aGUgZm9sbG93aW5nIHBhdHRlcm5zIGFyZSBpbXBsZW1lbnRlZFxuICpcbiAqICogTWF0Y2guX19PYmplY3RIYXNoX18oX3BhdHRlcm5fKVxuICpcbiAqICAgTWF0Y2hlcyBhbiBvYmplY3Qgd2hlcmUgYWxsIHByb3BlcnRpZXMgbWF0Y2ggYSBnaXZlbiBwYXR0ZXJuXG4gKlxuICogKiBNYXRjaC5fX1N1YmNsYXNzX18oX2NvbnN0cnVjdG9yXyBbLCBfbWF0Y2hUaGlzQ2xhc3NUb29fXSlcbiAqXG4gKiAgIE1hdGNoZXMgYSBjbGFzcyB0aGF0IGlzIGEgc3ViY2xhc3Mgb2YgYSBnaXZlbiBjbGFzcy4gSWYgdGhlIHNlY29uZCBwYXJhbWV0ZXJcbiAqICAgaXMgdHJ1ZSwgaXQgd2lsbCBhbHNvIG1hdGNoIHRoZSBjbGFzcyBpdHNlbGYuXG4gKlxuICogICBXaXRob3V0IHRoaXMgcGF0dGVybiB0byBjaGVjayBpZiBfTXlTdWJjbGFzc18gaXMgYSBzdWJjbGFzcyBvZiBfTXlDbGFzc19cbiAqICAgeW91IHdvdWxkIGhhdmUgdG8gdXNlXG4gKlxuICogICAgICAgY2hlY2soTXlTdWJjbGFzcywgTWF0Y2guV2hlcmUoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgcmV0dXJuIE15U3ViY2xhc3MucHJvdG90eXBlIGluc3RhbmNlb2YgTXlDbGFzcztcbiAqICAgICAgIH0pO1xuICpcbiAqXG4gKiBUaGluZ3Mgd2UgZXhwbGljaXRseSBkbyBOT1Qgc3VwcG9ydDpcbiAqICAgIC0gaGV0ZXJvZ2Vub3VzIGFycmF5c1xuKiovXG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG52YXIgY2hlY2sgPSBmdW5jdGlvbiAodmFsdWUsIHBhdHRlcm4pIHtcbiAgICBpZiAoY29uZmlnLmNoZWNrID09PSBmYWxzZSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgLy8gUmVjb3JkIHRoYXQgY2hlY2sgZ290IGNhbGxlZCwgaWYgc29tZWJvZHkgY2FyZWQuXG4gICAgdHJ5IHtcbiAgICAgICAgY2hlY2tTdWJ0cmVlKHZhbHVlLCBwYXR0ZXJuKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKChlcnIgaW5zdGFuY2VvZiBNYXRjaC5FcnJvcikgJiYgZXJyLnBhdGgpXG4gICAgICAgICAgICBlcnIubWVzc2FnZSArPSBcIiBpbiBmaWVsZCBcIiArIGVyci5wYXRoO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjaGVjaztcblxudmFyIE1hdGNoID0gY2hlY2suTWF0Y2ggPSB7XG4gICAgT3B0aW9uYWw6IGZ1bmN0aW9uIChwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiBuZXcgT3B0aW9uYWwocGF0dGVybik7XG4gICAgfSxcbiAgICBPbmVPZjogZnVuY3Rpb24gKC8qIGFyZ3VtZW50cyAqLykge1xuICAgICAgICByZXR1cm4gbmV3IE9uZU9mKGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBBbnk6IFsnX19hbnlfXyddLFxuICAgIFdoZXJlOiBmdW5jdGlvbiAoY29uZGl0aW9uKSB7XG4gICAgICAgIHJldHVybiBuZXcgV2hlcmUoY29uZGl0aW9uKTtcbiAgICB9LFxuICAgIE9iamVjdEluY2x1ZGluZzogZnVuY3Rpb24gKHBhdHRlcm4pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RJbmNsdWRpbmcocGF0dGVybik7XG4gICAgfSxcbiAgICAvLyBNYXRjaGVzIG9ubHkgc2lnbmVkIDMyLWJpdCBpbnRlZ2Vyc1xuICAgIEludGVnZXI6IFsnX19pbnRlZ2VyX18nXSxcblxuICAgIC8vIE1hdGNoZXMgc3RyaW5nIHRoYXQgaXMgYSB2YWxpZCBpZGVudGlmaWVyLCB3aWxsIG5vdCBhbGxvdyBqYXZhc2NyaXB0IHJlc2VydmVkIHdvcmRzXG4gICAgSWRlbnRpZmllclN0cmluZzogL15bYS16XyRdWzAtOWEtel8kXSokL2ksXG5cbiAgICAvLyBNYXRjaGVzIGhhc2ggKG9iamVjdCkgd2l0aCB2YWx1ZXMgbWF0Y2hpbmcgcGF0dGVyblxuICAgIE9iamVjdEhhc2g6IGZ1bmN0aW9uKHBhdHRlcm4pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RIYXNoKHBhdHRlcm4pO1xuICAgIH0sXG5cbiAgICBTdWJjbGFzczogZnVuY3Rpb24oU3VwZXJjbGFzcywgbWF0Y2hTdXBlcmNsYXNzVG9vKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3ViY2xhc3MoU3VwZXJjbGFzcywgbWF0Y2hTdXBlcmNsYXNzVG9vKTtcbiAgICB9LFxuXG4gICAgLy8gWFhYIG1hdGNoZXJzIHNob3VsZCBrbm93IGhvdyB0byBkZXNjcmliZSB0aGVtc2VsdmVzIGZvciBlcnJvcnNcbiAgICBFcnJvcjogVHlwZUVycm9yLFxuXG4gICAgLy8gTWV0ZW9yLm1ha2VFcnJvclR5cGUoXCJNYXRjaC5FcnJvclwiLCBmdW5jdGlvbiAobXNnKSB7XG4gICAgICAgIC8vIHRoaXMubWVzc2FnZSA9IFwiTWF0Y2ggZXJyb3I6IFwiICsgbXNnO1xuICAgICAgICAvLyBUaGUgcGF0aCBvZiB0aGUgdmFsdWUgdGhhdCBmYWlsZWQgdG8gbWF0Y2guIEluaXRpYWxseSBlbXB0eSwgdGhpcyBnZXRzXG4gICAgICAgIC8vIHBvcHVsYXRlZCBieSBjYXRjaGluZyBhbmQgcmV0aHJvd2luZyB0aGUgZXhjZXB0aW9uIGFzIGl0IGdvZXMgYmFjayB1cCB0aGVcbiAgICAgICAgLy8gc3RhY2suXG4gICAgICAgIC8vIEUuZy46IFwidmFsc1szXS5lbnRpdHkuY3JlYXRlZFwiXG4gICAgICAgIC8vIHRoaXMucGF0aCA9IFwiXCI7XG4gICAgICAgIC8vIElmIHRoaXMgZ2V0cyBzZW50IG92ZXIgRERQLCBkb24ndCBnaXZlIGZ1bGwgaW50ZXJuYWwgZGV0YWlscyBidXQgYXQgbGVhc3RcbiAgICAgICAgLy8gcHJvdmlkZSBzb21ldGhpbmcgYmV0dGVyIHRoYW4gNTAwIEludGVybmFsIHNlcnZlciBlcnJvci5cbiAgICAvLyAgICAgdGhpcy5zYW5pdGl6ZWRFcnJvciA9IG5ldyBNZXRlb3IuRXJyb3IoNDAwLCBcIk1hdGNoIGZhaWxlZFwiKTtcbiAgICAvLyB9KSxcblxuICAgIC8vIFRlc3RzIHRvIHNlZSBpZiB2YWx1ZSBtYXRjaGVzIHBhdHRlcm4uIFVubGlrZSBjaGVjaywgaXQgbWVyZWx5IHJldHVybnMgdHJ1ZVxuICAgIC8vIG9yIGZhbHNlICh1bmxlc3MgYW4gZXJyb3Igb3RoZXIgdGhhbiBNYXRjaC5FcnJvciB3YXMgdGhyb3duKS5cbiAgICB0ZXN0OiBmdW5jdGlvbiAodmFsdWUsIHBhdHRlcm4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNoZWNrU3VidHJlZSh2YWx1ZSwgcGF0dGVybik7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBNYXRjaC5FcnJvcilcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAvLyBSZXRocm93IG90aGVyIGVycm9ycy5cbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5mdW5jdGlvbiBPcHRpb25hbChwYXR0ZXJuKSB7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbn07XG5cbmZ1bmN0aW9uIE9uZU9mKGNob2ljZXMpIHtcbiAgICBpZiAoY2hvaWNlcy5sZW5ndGggPT0gMClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTXVzdCBwcm92aWRlIGF0IGxlYXN0IG9uZSBjaG9pY2UgdG8gTWF0Y2guT25lT2ZcIik7XG4gICAgdGhpcy5jaG9pY2VzID0gY2hvaWNlcztcbn07XG5cbmZ1bmN0aW9uIFdoZXJlKGNvbmRpdGlvbikge1xuICAgIHRoaXMuY29uZGl0aW9uID0gY29uZGl0aW9uO1xufTtcblxuZnVuY3Rpb24gT2JqZWN0SW5jbHVkaW5nKHBhdHRlcm4pIHtcbiAgICB0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuO1xufTtcblxuZnVuY3Rpb24gT2JqZWN0SGFzaChwYXR0ZXJuKSB7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbn07XG5cbmZ1bmN0aW9uIFN1YmNsYXNzKFN1cGVyY2xhc3MsIG1hdGNoU3VwZXJjbGFzc1Rvbykge1xuICAgIHRoaXMuU3VwZXJjbGFzcyA9IFN1cGVyY2xhc3M7XG4gICAgdGhpcy5tYXRjaFN1cGVyY2xhc3MgPSBtYXRjaFN1cGVyY2xhc3NUb287XG59O1xuXG52YXIgdHlwZW9mQ2hlY2tzID0gW1xuICAgIFtTdHJpbmcsIFwic3RyaW5nXCJdLFxuICAgIFtOdW1iZXIsIFwibnVtYmVyXCJdLFxuICAgIFtCb29sZWFuLCBcImJvb2xlYW5cIl0sXG4gICAgW0Z1bmN0aW9uLCBcImZ1bmN0aW9uXCJdLFxuICAgIC8vIFdoaWxlIHdlIGRvbid0IGFsbG93IHVuZGVmaW5lZCBpbiBKU09OLCB0aGlzIGlzIGdvb2QgZm9yIG9wdGlvbmFsXG4gICAgLy8gYXJndW1lbnRzIHdpdGggT25lT2YuXG4gICAgW3VuZGVmaW5lZCwgXCJ1bmRlZmluZWRcIl1cbl07XG5cbmZ1bmN0aW9uIGNoZWNrU3VidHJlZSh2YWx1ZSwgcGF0dGVybikge1xuICAgIC8vIE1hdGNoIGFueXRoaW5nIVxuICAgIGlmIChwYXR0ZXJuID09PSBNYXRjaC5BbnkpXG4gICAgICAgIHJldHVybjtcblxuICAgIC8vIEJhc2ljIGF0b21pYyB0eXBlcy5cbiAgICAvLyBEbyBub3QgbWF0Y2ggYm94ZWQgb2JqZWN0cyAoZS5nLiBTdHJpbmcsIEJvb2xlYW4pXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlb2ZDaGVja3MubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKHBhdHRlcm4gPT09IHR5cGVvZkNoZWNrc1tpXVswXSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gdHlwZW9mQ2hlY2tzW2ldWzFdKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIkV4cGVjdGVkIFwiICsgdHlwZW9mQ2hlY2tzW2ldWzFdICsgXCIsIGdvdCBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBhdHRlcm4gPT09IG51bGwpIHtcbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBudWxsLCBnb3QgXCIgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8vIE1hdGNoLkludGVnZXIgaXMgc3BlY2lhbCB0eXBlIGVuY29kZWQgd2l0aCBhcnJheVxuICAgIGlmIChwYXR0ZXJuID09PSBNYXRjaC5JbnRlZ2VyKSB7XG4gICAgICAgIC8vIFRoZXJlIGlzIG5vIGNvbnNpc3RlbnQgYW5kIHJlbGlhYmxlIHdheSB0byBjaGVjayBpZiB2YXJpYWJsZSBpcyBhIDY0LWJpdFxuICAgICAgICAvLyBpbnRlZ2VyLiBPbmUgb2YgdGhlIHBvcHVsYXIgc29sdXRpb25zIGlzIHRvIGdldCByZW1pbmRlciBvZiBkaXZpc2lvbiBieSAxXG4gICAgICAgIC8vIGJ1dCB0aGlzIG1ldGhvZCBmYWlscyBvbiByZWFsbHkgbGFyZ2UgZmxvYXRzIHdpdGggYmlnIHByZWNpc2lvbi5cbiAgICAgICAgLy8gRS5nLjogMS4zNDgxOTIzMDg0OTE4MjRlKzIzICUgMSA9PT0gMCBpbiBWOFxuICAgICAgICAvLyBCaXR3aXNlIG9wZXJhdG9ycyB3b3JrIGNvbnNpc3RhbnRseSBidXQgYWx3YXlzIGNhc3QgdmFyaWFibGUgdG8gMzItYml0XG4gICAgICAgIC8vIHNpZ25lZCBpbnRlZ2VyIGFjY29yZGluZyB0byBKYXZhU2NyaXB0IHNwZWNzLlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAodmFsdWUgfCAwKSA9PT0gdmFsdWUpXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKCdFeHBlY3RlZCBJbnRlZ2VyLCBnb3QgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICh2YWx1ZSBpbnN0YW5jZW9mIE9iamVjdCA/IEpTT04uc3RyaW5naWZ5KHZhbHVlKSA6IHZhbHVlKSk7XG4gICAgfVxuXG4gICAgaWYgKHBhdHRlcm4gPT09IE1hdGNoLklkZW50aWZpZXJTdHJpbmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgTWF0Y2guSWRlbnRpZmllclN0cmluZy50ZXN0KHZhbHVlKVxuICAgICAgICAgICAgICAgICYmIF9qc0tleXdvcmRzLmluZGV4T2Yoa2V5KSA9PSAtMSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKCdFeHBlY3RlZCBpZGVudGlmaWVyIHN0cmluZywgZ290ICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAodmFsdWUgaW5zdGFuY2VvZiBPYmplY3QgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgOiB2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8vIFwiT2JqZWN0XCIgaXMgc2hvcnRoYW5kIGZvciBNYXRjaC5PYmplY3RJbmNsdWRpbmcoe30pO1xuICAgIGlmIChwYXR0ZXJuID09PSBPYmplY3QpXG4gICAgICAgIHBhdHRlcm4gPSBNYXRjaC5PYmplY3RJbmNsdWRpbmcoe30pO1xuXG4gICAgLy8gQXJyYXkgKGNoZWNrZWQgQUZURVIgQW55LCB3aGljaCBpcyBpbXBsZW1lbnRlZCBhcyBhbiBBcnJheSkuXG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICBpZiAocGF0dGVybi5sZW5ndGggIT09IDEpXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkJhZCBwYXR0ZXJuOiBhcnJheXMgbXVzdCBoYXZlIG9uZSB0eXBlIGVsZW1lbnRcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShwYXR0ZXJuKSk7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIkV4cGVjdGVkIGFycmF5LCBnb3QgXCIgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbiAodmFsdWVFbGVtZW50LCBpbmRleCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjaGVja1N1YnRyZWUodmFsdWVFbGVtZW50LCBwYXR0ZXJuWzBdKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBNYXRjaC5FcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBlcnIucGF0aCA9IF9wcmVwZW5kUGF0aChpbmRleCwgZXJyLnBhdGgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQXJiaXRyYXJ5IHZhbGlkYXRpb24gY2hlY2tzLiBUaGUgY29uZGl0aW9uIGNhbiByZXR1cm4gZmFsc2Ugb3IgdGhyb3cgYVxuICAgIC8vIE1hdGNoLkVycm9yIChpZSwgaXQgY2FuIGludGVybmFsbHkgdXNlIGNoZWNrKCkpIHRvIGZhaWwuXG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBXaGVyZSkge1xuICAgICAgICBpZiAocGF0dGVybi5jb25kaXRpb24odmFsdWUpKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBYWFggdGhpcyBlcnJvciBpcyB0ZXJyaWJsZVxuICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJGYWlsZWQgTWF0Y2guV2hlcmUgdmFsaWRhdGlvblwiKTtcbiAgICB9XG5cblxuICAgIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgT3B0aW9uYWwpXG4gICAgICAgIHBhdHRlcm4gPSBNYXRjaC5PbmVPZih1bmRlZmluZWQsIHBhdHRlcm4ucGF0dGVybik7XG5cbiAgICBpZiAocGF0dGVybiBpbnN0YW5jZW9mIE9uZU9mKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0dGVybi5jaG9pY2VzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNoZWNrU3VidHJlZSh2YWx1ZSwgcGF0dGVybi5jaG9pY2VzW2ldKTtcbiAgICAgICAgICAgICAgICAvLyBObyBlcnJvcj8gWWF5LCByZXR1cm4uXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gT3RoZXIgZXJyb3JzIHNob3VsZCBiZSB0aHJvd24uIE1hdGNoIGVycm9ycyBqdXN0IG1lYW4gdHJ5IGFub3RoZXJcbiAgICAgICAgICAgICAgICAvLyBjaG9pY2UuXG4gICAgICAgICAgICAgICAgaWYgKCEoZXJyIGluc3RhbmNlb2YgTWF0Y2guRXJyb3IpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gWFhYIHRoaXMgZXJyb3IgaXMgdGVycmlibGVcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiRmFpbGVkIE1hdGNoLk9uZU9mIG9yIE1hdGNoLk9wdGlvbmFsIHZhbGlkYXRpb25cIik7XG4gICAgfVxuXG4gICAgLy8gQSBmdW5jdGlvbiB0aGF0IGlzbid0IHNvbWV0aGluZyB3ZSBzcGVjaWFsLWNhc2UgaXMgYXNzdW1lZCB0byBiZSBhXG4gICAgLy8gY29uc3RydWN0b3IuXG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBwYXR0ZXJuKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBYWFggd2hhdCBpZiAubmFtZSBpc24ndCBkZWZpbmVkXG4gICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIkV4cGVjdGVkIFwiICsgcGF0dGVybi5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgdW5rbm93bktleXNBbGxvd2VkID0gZmFsc2U7XG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBPYmplY3RJbmNsdWRpbmcpIHtcbiAgICAgICAgdW5rbm93bktleXNBbGxvd2VkID0gdHJ1ZTtcbiAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4ucGF0dGVybjtcbiAgICB9XG5cbiAgICBpZiAocGF0dGVybiBpbnN0YW5jZW9mIE9iamVjdEhhc2gpIHtcbiAgICAgICAgdmFyIGtleVBhdHRlcm4gPSBwYXR0ZXJuLnBhdHRlcm47XG4gICAgICAgIHZhciBlbXB0eUhhc2ggPSB0cnVlO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHtcbiAgICAgICAgICAgIGVtcHR5SGFzaCA9IGZhbHNlO1xuICAgICAgICAgICAgY2hlY2sodmFsdWVba2V5XSwga2V5UGF0dGVybik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVtcHR5SGFzaClcbiAgICAgICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIkV4cGVjdGVkIFwiICsgcGF0dGVybi5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgU3ViY2xhc3MpIHtcbiAgICAgICAgdmFyIFN1cGVyY2xhc3MgPSBwYXR0ZXJuLlN1cGVyY2xhc3M7XG4gICAgICAgIGlmIChwYXR0ZXJuLm1hdGNoU3VwZXJjbGFzcyAmJiB2YWx1ZSA9PSBTdXBlcmNsYXNzKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAoISAodmFsdWUucHJvdG90eXBlIGluc3RhbmNlb2YgU3VwZXJjbGFzcykpXG4gICAgICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBcIiArIHBhdHRlcm4uY29uc3RydWN0b3IubmFtZSArIFwiIG9mIFwiICsgU3VwZXJjbGFzcy5uYW1lKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcGF0dGVybiAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJCYWQgcGF0dGVybjogdW5rbm93biBwYXR0ZXJuIHR5cGVcIik7XG5cbiAgICAvLyBBbiBvYmplY3QsIHdpdGggcmVxdWlyZWQgYW5kIG9wdGlvbmFsIGtleXMuIE5vdGUgdGhhdCB0aGlzIGRvZXMgTk9UIGRvXG4gICAgLy8gc3RydWN0dXJhbCBtYXRjaGVzIGFnYWluc3Qgb2JqZWN0cyBvZiBzcGVjaWFsIHR5cGVzIHRoYXQgaGFwcGVuIHRvIG1hdGNoXG4gICAgLy8gdGhlIHBhdHRlcm46IHRoaXMgcmVhbGx5IG5lZWRzIHRvIGJlIGEgcGxhaW4gb2xkIHtPYmplY3R9IVxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKVxuICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBvYmplY3QsIGdvdCBcIiArIHR5cGVvZiB2YWx1ZSk7XG4gICAgaWYgKHZhbHVlID09PSBudWxsKVxuICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBvYmplY3QsIGdvdCBudWxsXCIpO1xuXG4gICAgdmFyIHJlcXVpcmVkUGF0dGVybnMgPSB7fTtcbiAgICB2YXIgb3B0aW9uYWxQYXR0ZXJucyA9IHt9O1xuXG4gICAgXy5lYWNoS2V5KHBhdHRlcm4sIGZ1bmN0aW9uKHN1YlBhdHRlcm4sIGtleSkge1xuICAgICAgICBpZiAocGF0dGVybltrZXldIGluc3RhbmNlb2YgT3B0aW9uYWwpXG4gICAgICAgICAgICBvcHRpb25hbFBhdHRlcm5zW2tleV0gPSBwYXR0ZXJuW2tleV0ucGF0dGVybjtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmVxdWlyZWRQYXR0ZXJuc1trZXldID0gcGF0dGVybltrZXldO1xuICAgIH0sIHRoaXMsIHRydWUpO1xuXG4gICAgXy5lYWNoS2V5KHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgICAgIHZhciBzdWJWYWx1ZSA9IHZhbHVlW2tleV07XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAocmVxdWlyZWRQYXR0ZXJucy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgY2hlY2tTdWJ0cmVlKHN1YlZhbHVlLCByZXF1aXJlZFBhdHRlcm5zW2tleV0pO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXF1aXJlZFBhdHRlcm5zW2tleV07XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbmFsUGF0dGVybnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGNoZWNrU3VidHJlZShzdWJWYWx1ZSwgb3B0aW9uYWxQYXR0ZXJuc1trZXldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1bmtub3duS2V5c0FsbG93ZWQpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIlVua25vd24ga2V5XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBNYXRjaC5FcnJvcilcbiAgICAgICAgICAgICAgICBlcnIucGF0aCA9IF9wcmVwZW5kUGF0aChrZXksIGVyci5wYXRoKTtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgIH0sIHRoaXMsIHRydWUpO1xuXG4gICAgXy5lYWNoS2V5KHJlcXVpcmVkUGF0dGVybnMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiTWlzc2luZyBrZXkgJ1wiICsga2V5ICsgXCInXCIpO1xuICAgIH0sIHRoaXMsIHRydWUpO1xufTtcblxuXG52YXIgX2pzS2V5d29yZHMgPSBbXCJkb1wiLCBcImlmXCIsIFwiaW5cIiwgXCJmb3JcIiwgXCJsZXRcIiwgXCJuZXdcIiwgXCJ0cnlcIiwgXCJ2YXJcIiwgXCJjYXNlXCIsXG4gICAgXCJlbHNlXCIsIFwiZW51bVwiLCBcImV2YWxcIiwgXCJmYWxzZVwiLCBcIm51bGxcIiwgXCJ0aGlzXCIsIFwidHJ1ZVwiLCBcInZvaWRcIiwgXCJ3aXRoXCIsXG4gICAgXCJicmVha1wiLCBcImNhdGNoXCIsIFwiY2xhc3NcIiwgXCJjb25zdFwiLCBcInN1cGVyXCIsIFwidGhyb3dcIiwgXCJ3aGlsZVwiLCBcInlpZWxkXCIsXG4gICAgXCJkZWxldGVcIiwgXCJleHBvcnRcIiwgXCJpbXBvcnRcIiwgXCJwdWJsaWNcIiwgXCJyZXR1cm5cIiwgXCJzdGF0aWNcIiwgXCJzd2l0Y2hcIixcbiAgICBcInR5cGVvZlwiLCBcImRlZmF1bHRcIiwgXCJleHRlbmRzXCIsIFwiZmluYWxseVwiLCBcInBhY2thZ2VcIiwgXCJwcml2YXRlXCIsIFwiY29udGludWVcIixcbiAgICBcImRlYnVnZ2VyXCIsIFwiZnVuY3Rpb25cIiwgXCJhcmd1bWVudHNcIiwgXCJpbnRlcmZhY2VcIiwgXCJwcm90ZWN0ZWRcIiwgXCJpbXBsZW1lbnRzXCIsXG4gICAgXCJpbnN0YW5jZW9mXCJdO1xuXG4vLyBBc3N1bWVzIHRoZSBiYXNlIG9mIHBhdGggaXMgYWxyZWFkeSBlc2NhcGVkIHByb3Blcmx5XG4vLyByZXR1cm5zIGtleSArIGJhc2VcbmZ1bmN0aW9uIF9wcmVwZW5kUGF0aChrZXksIGJhc2UpIHtcbiAgICBpZiAoKHR5cGVvZiBrZXkpID09PSBcIm51bWJlclwiIHx8IGtleS5tYXRjaCgvXlswLTldKyQvKSlcbiAgICAgICAga2V5ID0gXCJbXCIgKyBrZXkgKyBcIl1cIjtcbiAgICBlbHNlIGlmICgha2V5Lm1hdGNoKE1hdGNoLklkZW50aWZpZXJTdHJpbmcpIHx8IF9qc0tleXdvcmRzLmluZGV4T2Yoa2V5KSAhPSAtMSlcbiAgICAgICAga2V5ID0gSlNPTi5zdHJpbmdpZnkoW2tleV0pO1xuXG4gICAgaWYgKGJhc2UgJiYgYmFzZVswXSAhPT0gXCJbXCIpXG4gICAgICAgIHJldHVybiBrZXkgKyAnLicgKyBiYXNlO1xuICAgIHJldHVybiBrZXkgKyBiYXNlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvdW50ID0gcmVxdWlyZSgnLi9jb3VudCcpXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxuICAgICwgcHJlZml4ID0gY29uZmlnLmNvbXBvbmVudFByZWZpeDtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvbmVudE5hbWU7XG5cblxuZnVuY3Rpb24gY29tcG9uZW50TmFtZSgpIHtcbiAgICByZXR1cm4gcHJlZml4ICsgY291bnQoKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHRpbWVzdGFtcCA9IERhdGUubm93KClcbiAgICAsIGNvdW50ID0gJydcbiAgICAsIHVuaXF1ZUlEID0gJycgKyB0aW1lc3RhbXA7XG5cbmZ1bmN0aW9uIHVuaXF1ZUNvdW50KCkge1xuICAgIHZhciBuZXdUaW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIHVuaXF1ZUlEID0gJycgKyBuZXdUaW1lc3RhbXA7XG4gICAgaWYgKHRpbWVzdGFtcCA9PSBuZXdUaW1lc3RhbXApIHtcbiAgICAgICAgY291bnQgPSBjb3VudCA9PT0gJycgPyAwIDogY291bnQgKyAxO1xuICAgICAgICB1bmlxdWVJRCArPSAnXycgKyBjb3VudDtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aW1lc3RhbXAgPSBuZXdUaW1lc3RhbXA7XG4gICAgICAgIGNvdW50ID0gJyc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuaXF1ZUlEO1xufVxuXG51bmlxdWVDb3VudC5nZXQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdW5pcXVlSUQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdW5pcXVlQ291bnQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQ29tcG9uZW50Q2xhc3M7XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiB3aGljaCBjcmVhdGVzIGFuZCByZWdpc3RlcnMgbmV3IG1pbG8gY29tcG9uZW50LiAgVGhlIGNvbXBvbmVudCBjcmVhdGVkIHdpbGwgaGF2ZVxuICogYSByZWZlcmVuY2UgdG8gdGhlIHN1cGVyIGNsYXNzIHVzZWQgaW4gaXRzIGNyZWF0aW9uIChBY2Nlc3NhYmxlIHVzaW5nIDxDb21wb25lbnRDbGFzcz4uc3VwZXIpLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcuY2xhc3NOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIG5ldyBjb21wb25lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBbJ0NvbXBvbmVudCddIGNvbmZpZy5zdXBlckNsYXNzTmFtZSAtIFRoZSBuYW1lIG9mIGFuIGV4aXN0aW5nIGNvbXBvbmVudCB0byBiZSB1c2VkIGFzIHRoZSBuZXcgY29tcG9uZW50J3Mgc3VwZXIgY2xhc3NcbiAqIEBwYXJhbSB7b2JqZWN0PX0gY29uZmlnLmZhY2V0cyAtIEZhY2V0IGNvbmZpZ3VyYXRpb24gKEhhc2ggb2YgZmFjZXQgbmFtZSB7c3RyaW5nfSB0byBjb25maWcge29iamVjdH0pXG4gKiBAcGFyYW0ge29iamVjdD19IGNvbmZpZy5tZXRob2RzIC0gTWV0aG9kcyBvZiB0aGUgbmV3IGNvbXBvbmVudCAoSGFzaCBvZiBmdW5jdGlvbiBuYW1lIHtzdHJpbmd9IHRvIGZ1bmN0aW9uIHtmdW5jdGlvbn0pXG4gKiBAcGFyYW0ge29iamVjdD19IGNvbmZpZy5zdGF0aWNNZXRob2RzIC0gU3RhdGljIG1ldGhvZHMgb2YgdGhlIG5ldyBjb21wb25lbnQgKEhhc2ggb2YgZnVuY3Rpb24gbmFtZSB7c3RyaW5nfSB0byBmdW5jdGlvbiB7ZnVuY3Rpb259KVxuICovXG5mdW5jdGlvbiBjcmVhdGVDb21wb25lbnRDbGFzcyhjb25maWcpIHtcbiAgICB2YXIgY29tcG9uZW50UmVnaXN0cnkgPSBtaWxvLnJlZ2lzdHJ5LmNvbXBvbmVudHM7XG4gICAgdmFyIFN1cGVyQ2xhc3MgPSBjb21wb25lbnRSZWdpc3RyeS5nZXQoY29uZmlnLnN1cGVyQ2xhc3NOYW1lIHx8ICdDb21wb25lbnQnKTtcbiAgICB2YXIgQ29tcG9uZW50Q2xhc3MgPSBTdXBlckNsYXNzLmNyZWF0ZUNvbXBvbmVudENsYXNzKGNvbmZpZy5jbGFzc05hbWUsIGNvbmZpZy5mYWNldHMpO1xuXG4gICAgaWYoY29uZmlnLm1ldGhvZHMpIHtcbiAgICAgICAgXy5leHRlbmRQcm90byhDb21wb25lbnRDbGFzcywgY29uZmlnLm1ldGhvZHMpO1xuICAgIH1cblxuICAgIGlmKGNvbmZpZy5zdGF0aWNNZXRob2RzKSB7XG4gICAgICAgIGlmKGNvbmZpZy5zdGF0aWNNZXRob2RzLnN1cGVyICE9PSB1bmRlZmluZWQpIHRocm93ICdcXCdzdXBlclxcJyBpcyBhIHJlc2VydmVkIGtleXdvcmQnO1xuXG4gICAgICAgIF8uZXh0ZW5kKENvbXBvbmVudENsYXNzLCBjb25maWcuc3RhdGljTWV0aG9kcyk7XG4gICAgfVxuXG4gICAgQ29tcG9uZW50Q2xhc3Muc3VwZXIgPSBTdXBlckNsYXNzLnByb3RvdHlwZTtcbiAgICBcbiAgICBjb21wb25lbnRSZWdpc3RyeS5hZGQoQ29tcG9uZW50Q2xhc3MpO1xuXG4gICAgcmV0dXJuIENvbXBvbmVudENsYXNzO1xufSIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXInKTtcblxudmFyIGRvbVV0aWxzID0ge1xuICAgIGNoaWxkcmVuOiBjaGlsZHJlbixcbiAgICBmaWx0ZXJOb2RlTGlzdEJ5VHlwZTogZmlsdGVyTm9kZUxpc3RCeVR5cGUsXG4gICAgY29udGFpbmluZ0VsZW1lbnQ6IGNvbnRhaW5pbmdFbGVtZW50LFxuICAgIHNlbGVjdEVsZW1lbnRDb250ZW50czogc2VsZWN0RWxlbWVudENvbnRlbnRzLFxuICAgIHNlbGVjdEVsZW1lbnRUZXh0OiBzZWxlY3RFbGVtZW50VGV4dCxcbiAgICBnZXRFbGVtZW50T2Zmc2V0OiBnZXRFbGVtZW50T2Zmc2V0LFxuICAgIHNldENhcmV0UG9zaXRpb246IHNldENhcmV0UG9zaXRpb24sXG4gICAgZ2V0U2VsZWN0aW9uRGlyZWN0aW9uOiBnZXRTZWxlY3Rpb25EaXJlY3Rpb24sXG4gICAgc2V0U2VsZWN0aW9uOiBzZXRTZWxlY3Rpb24sXG4gICAgY2xlYXJTZWxlY3Rpb246IGNsZWFyU2VsZWN0aW9uLFxuICAgIHJlbW92ZUVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQsXG4gICAgdW53cmFwRWxlbWVudDogdW53cmFwRWxlbWVudCxcbiAgICB3cmFwSW5FbGVtZW50OiB3cmFwSW5FbGVtZW50LFxuICAgIGRldGFjaENvbXBvbmVudDogZGV0YWNoQ29tcG9uZW50LFxuICAgIGZpcnN0VGV4dE5vZGU6IGZpcnN0VGV4dE5vZGUsXG4gICAgbGFzdFRleHROb2RlOiBsYXN0VGV4dE5vZGUsXG4gICAgdHJpbU5vZGVSaWdodDogdHJpbU5vZGVSaWdodCxcbiAgICB0cmltTm9kZUxlZnQ6IHRyaW1Ob2RlTGVmdCxcbiAgICBzdHJpcEh0bWw6IHN0cmlwSHRtbCxcbiAgICBodG1sRW50aXRpZXM6IGh0bWxFbnRpdGllcyxcbiAgICB3YWxrVHJlZTogd2Fsa1RyZWUsXG4gICAgY3JlYXRlVHJlZVdhbGtlcjogY3JlYXRlVHJlZVdhbGtlcixcblxuICAgIHRyZWVQYXRoT2Y6IHRyZWVQYXRoT2YsXG4gICAgZ2V0Tm9kZUF0VHJlZVBhdGg6IGdldE5vZGVBdFRyZWVQYXRoLFxuICAgIGluc2VydEF0VHJlZVBhdGg6IGluc2VydEF0VHJlZVBhdGgsXG4gICAgaXNUcmVlUGF0aEJlZm9yZTogaXNUcmVlUGF0aEJlZm9yZSxcblxuICAgIGdldE5vZGVXaW5kb3c6IGdldE5vZGVXaW5kb3csXG5cbiAgICBnZXRDb21wb25lbnRzRnJvbVJhbmdlOiBnZXRDb21wb25lbnRzRnJvbVJhbmdlLFxuICAgIGRlbGV0ZVJhbmdlV2l0aENvbXBvbmVudHM6IGRlbGV0ZVJhbmdlV2l0aENvbXBvbmVudHMsXG4gICAgZm9yRWFjaE5vZGVzSW5SYW5nZTogZm9yRWFjaE5vZGVzSW5SYW5nZSxcbiAgICBhcmVSYW5nZXNFcXVhbDogYXJlUmFuZ2VzRXF1YWwsXG5cbiAgICBhZGREZWJ1Z1BvaW50OiBhZGREZWJ1Z1BvaW50XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbVV0aWxzO1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgbGlzdCBvZiBlbGVtZW50IGNoaWxkcmVuIG9mIERPTSBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCBlbGVtZW50IHRvIHJldHVybiB0aGUgY2hpbGRyZW4gb2YgKG9ubHkgRE9NIGVsZW1lbnRzKVxuICogQHJldHVybiB7QXJyYXlbRWxlbWVudF19XG4gKi9cbiBmdW5jdGlvbiBjaGlsZHJlbihlbCkge1xuICAgIHJldHVybiBmaWx0ZXJOb2RlTGlzdEJ5VHlwZShlbC5jaGlsZE5vZGVzLCBOb2RlLkVMRU1FTlRfTk9ERSk7XG4gfVxuXG5cbi8qKlxuICogRmlsdGVycyB0aGUgbGlzdCBvZiBub2RlcyBieSB0eXBlXG4gKlxuICogQHBhcmFtIHtOb2RlTGlzdH0gbm9kZUxpc3QgdGhlIGxpc3Qgb2Ygbm9kZXMsIGZvciBleGFtcGxlIGNoaWxkTm9kZXMgcHJvcGVydHkgb2YgRE9NIGVsZW1lbnRcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbm9kZVR5cGUgYW4gaW50ZWdlciBjb25zdGFudCBbZGVmaW5lZCBieSBET00gQVBJXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTm9kZS5ub2RlVHlwZSksIGUuZy4gYE5vZGUuRUxFTUVOVF9OT0RFYCBvciBgTm9kZS5URVhUX05PREVgXG4gKiBAcmV0dXJuIHtBcnJheVtOb2RlXX1cbiAqL1xuZnVuY3Rpb24gZmlsdGVyTm9kZUxpc3RCeVR5cGUobm9kZUxpc3QsIG5vZGVUeXBlKSB7XG4gICAgcmV0dXJuIF8uZmlsdGVyKG5vZGVMaXN0LCBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PSBub2RlVHlwZTtcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIEZpbmQgbmVhcmVzdCBwYXJlbnQgZWxlbWVudCBmb3Igbm9kZS5cbiAqIElmIG5vZGUgaXMgYW4gZWxlbWVudCwgaXQgd2lsbCBiZSByZXR1cm5lZC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqIEByZXR1cm4ge0VsZW1lbnR8bnVsbH1cbiAqL1xuZnVuY3Rpb24gY29udGFpbmluZ0VsZW1lbnQobm9kZSkge1xuICAgIHdoaWxlIChub2RlKSB7XG4gICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IE5vZGUuRUxFTUVOVF9OT0RFKVxuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5cbi8qKlxuICogU2VsZWN0cyBpbm5lciBjb250ZW50cyBvZiBET00gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgRE9NIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gc2VsZWN0RWxlbWVudENvbnRlbnRzKGVsKSB7XG4gICAgdmFyIGRvYyA9IGVsLm93bmVyRG9jdW1lbnQ7XG4gICAgaWYgKCEgZG9jKSByZXR1cm4gbG9nZ2VyLmVycm9yKCdzZWxlY3RFbGVtZW50Q29udGVudHM6IGVsZW1lbnQgaGFzIG5vIGRvY3VtZW50Jyk7XG4gICAgdmFyIHJhbmdlID0gZG9jLmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGVsKTtcbiAgICB2YXIgd2luID0gZ2V0Tm9kZVdpbmRvdyhlbClcbiAgICAgICAgLCBzZWwgPSB3aW4uZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG59XG5cblxuLyoqXG4gKiBTZWxlY3RzIHRleHQgaW5zaWRlIGVsZW1lbnRcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqL1xuZnVuY3Rpb24gc2VsZWN0RWxlbWVudFRleHQoZWwpIHtcbiAgICB2YXIgZnJvbU5vZGUgPSBmaXJzdFRleHROb2RlKGVsKVxuICAgICAgICAsIHRvTm9kZSA9IGxhc3RUZXh0Tm9kZShlbCk7XG5cbiAgICBpZiAoZnJvbU5vZGUgJiYgdG9Ob2RlKVxuICAgICAgICBzZXRTZWxlY3Rpb24oZnJvbU5vZGUsIDAsIHRvTm9kZSwgdG9Ob2RlLnRleHRDb250ZW50Lmxlbmd0aCk7XG59XG5cblxuLyoqXG4gKiBTZXRzIHRoZSBjYXJldCBwb3NpdGlvbiB0byB0aGUgcG9zaXRpb24gaW4gdGhlIG5vZGVcbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgRE9NIG5vZGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBwb3MgY2FyZXQgcG9zaXRpb25cbiAqL1xuZnVuY3Rpb24gc2V0Q2FyZXRQb3NpdGlvbihub2RlLCBwb3MpIHtcbiAgICB2YXIgZG9jID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIGlmICghIGRvYykgcmV0dXJuIGxvZ2dlci5lcnJvcignc2V0Q2FyZXRQb3NpdGlvbjogZWxlbWVudCBoYXMgbm8gZG9jdW1lbnQnKTtcbiAgICB2YXIgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChub2RlLCBwb3MpO1xuICAgIHZhciB3aW4gPSBnZXROb2RlV2luZG93KG5vZGUpXG4gICAgICAgICwgc2VsID0gd2luLmdldFNlbGVjdGlvbigpO1xuICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xufVxuXG4vKipcbiAqIGdldCB0aGUgZGlyZWN0aW9uIG9mIGEgc2VsZWN0aW9uXG4gKlxuICogMSBmb3J3YXJkLCAtMSBiYWNrd2FyZCwgMCBubyBkaXJlY3Rpb24sIHVuZGVmaW5lZCBvbmUgb2YgdGhlIG5vZGUgaXMgZGV0YWNoZWQgb3IgaW4gYSBkaWZmZXJlbnQgZnJhbWVcbiAqXG4gKiBAcGFyYW0ge3NlbH0gYSBzZWxlY3Rpb24gb2JqZWN0XG4gKiBAcmV0dXJuIHstMXwwfDF8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25EaXJlY3Rpb24oc2VsKXtcbiAgICByZXR1cm4gX2dldERpcmVjdGlvbihzZWwuYW5jaG9yTm9kZSwgc2VsLmFuY2hvck9mZnNldCwgc2VsLmZvY3VzTm9kZSwgc2VsLmZvY3VzT2Zmc2V0KTtcbn1cblxuZnVuY3Rpb24gX2dldERpcmVjdGlvbihmcm9tTm9kZSwgc3RhcnRPZmZzZXQsIHRvTm9kZSwgZW5kT2Zmc2V0KXtcbiAgICB2YXIgZG9jUG9zaXRpb24gPSBmcm9tTm9kZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbih0b05vZGUpO1xuICAgIGlmIChkb2NQb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HKXtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIGVsc2UgaWYgKGRvY1Bvc2l0aW9uICYgTm9kZS5ET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcpe1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGVsc2UgaWYgKGZyb21Ob2RlID09IHRvTm9kZSl7XG4gICAgICAgIGlmIChzdGFydE9mZnNldCA8IGVuZE9mZnNldCl7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGFydE9mZnNldCA+IGVuZE9mZnNldCl7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBTZWxlY3RzIGEgcmFuZ2UgaW4gYSBkb2N1bWVudFxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gZnJvbU5vZGUgRE9NIG5vZGUgdG8gc3RhcnQgc2VsZWN0aW9uIGluXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhcnRPZmZzZXRcbiAqIEBwYXJhbSB7Tm9kZX0gdG9Ob2RlIERPTSBub2RlIHRvIGVuZCBzZWxlY3Rpb24gaW5cbiAqIEBwYXJhbSB7TnVtYmVyfSBlbmRPZmZzZXRcbiAqL1xuZnVuY3Rpb24gc2V0U2VsZWN0aW9uKGZyb21Ob2RlLCBzdGFydE9mZnNldCwgdG9Ob2RlLCBlbmRPZmZzZXQpIHtcbiAgICB2YXIgZG9jID0gZnJvbU5vZGUub3duZXJEb2N1bWVudDtcbiAgICBpZiAoISBkb2MpIHJldHVybiBsb2dnZXIoJ3NldENhcmV0UG9zaXRpb246IGVsZW1lbnQgaGFzIG5vIGRvY3VtZW50Jyk7XG4gICAgdmFyIGJhY2t3YXJkID0gX2dldERpcmVjdGlvbihmcm9tTm9kZSwgc3RhcnRPZmZzZXQsIHRvTm9kZSwgZW5kT2Zmc2V0KSA9PSAtMTtcbiAgICB2YXIgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICB2YXIgY29udGFpbmVyLCBvcmlnaW5hbENvbnRlbnRFZGl0YWJsZTtcbiAgICAvLyBkb2VzIG5vdCB3b3JrIGluIG5vbiBjb250ZW50RWRpdGFibGUgaXRlbXNcblxuICAgIHZhciB3aW4gPSBnZXROb2RlV2luZG93KGZyb21Ob2RlKVxuICAgICAgICAsIHNlbCA9IHdpbi5nZXRTZWxlY3Rpb24oKTtcblxuXG4gICAgaWYgKGJhY2t3YXJkKXtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQodG9Ob2RlLCBlbmRPZmZzZXQpO1xuICAgICAgICByYW5nZS5zZXRFbmQoZnJvbU5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoZnJvbU5vZGUsIHN0YXJ0T2Zmc2V0KTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kKHRvTm9kZSwgZW5kT2Zmc2V0KTtcbiAgICB9XG5cbiAgICBjb250YWluZXIgPSByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lciA9PSBOb2RlLkVMRU1FTlRfTk9ERSA/XG4gICAgICAgIHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIDpcbiAgICAgICAgcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIucGFyZW50RWxlbWVudDtcblxuICAgIGlmICghY29udGFpbmVyLmlzQ29udGVudEVkaXRhYmxlKXtcbiAgICAgICAgb3JpZ2luYWxDb250ZW50RWRpdGFibGUgPSBjb250YWluZXIuY29udGVudEVkaXRhYmxlOyAvLyBmYWxzZSBvciBpbmhlcml0XG4gICAgICAgIGNvbnRhaW5lci5jb250ZW50RWRpdGFibGUgPSBcInRydWVcIjtcbiAgICB9XG5cbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcblxuICAgIGlmIChiYWNrd2FyZCl7XG4gICAgICAgIHNlbC5leHRlbmQodG9Ob2RlLCBlbmRPZmZzZXQpO1xuICAgIH1cblxuICAgIGlmIChvcmlnaW5hbENvbnRlbnRFZGl0YWJsZSl7XG4gICAgICAgIC8vIHJlc3RvcmluZyBjb250ZW50RWRpdGFibGVcbiAgICAgICAgY29udGFpbmVyLmNvbnRlbnRFZGl0YWJsZSA9IG9yaWdpbmFsQ29udGVudEVkaXRhYmxlO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDbGVhcnMgc2VsZWN0aW9uIGluIGEgZ2l2ZW4gd2luZG93XG4gKiBAcGFyYW0ge1dpbmRvd30gd2luXG4gKi9cbmZ1bmN0aW9uIGNsZWFyU2VsZWN0aW9uKHdpbikge1xuICAgIHdpbiA9IHdpbiB8fCB3aW5kb3c7XG4gICAgdmFyIHNlbCA9IHdpbi5nZXRTZWxlY3Rpb24oKTtcbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG59XG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIGFuIGVsZW1lbnQncyB0b3RhbCB0b3AgYW5kIGxlZnQgb2Zmc2V0IGZyb20gdGhlIGRvY3VtZW50IGVkZ2UuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCB0aGUgZWxlbWVudCBmb3Igd2hpY2ggcG9zaXRpb24gbmVlZHMgdG8gYmUgcmV0dXJuZWRcbiAqIEBwYXJhbSB7aW5jbHVkZUJvcmRlcn0gaWYgaXMgdG8gaW5jbHVkZSB0aGUgYm9yZGVyIHdpZHRoXG4gKiBAcmV0dXJuIHtPYmplY3R9IHZlY3RvciBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIHRvcE9mZnNldCBhbmQgbGVmdE9mZnNldFxuICovXG5mdW5jdGlvbiBnZXRFbGVtZW50T2Zmc2V0KGVsLCBpbmNsdWRlQm9yZGVyKSB7XG4gICAgdmFyIHlQb3MsIHhQb3M7XG5cbiAgICB5UG9zID0gZWwub2Zmc2V0VG9wO1xuICAgIHhQb3MgPSBlbC5vZmZzZXRMZWZ0O1xuICAgIGVsID0gZWwub2Zmc2V0UGFyZW50O1xuXG4gICAgd2hpbGUgKGVsKSB7XG4gICAgICAgIHlQb3MgKz0gZWwub2Zmc2V0VG9wICsgZ2V0Qm9yZGVyKGVsLCAnSGVpZ2h0JywgaW5jbHVkZUJvcmRlcik7XG4gICAgICAgIHhQb3MgKz0gZWwub2Zmc2V0TGVmdCArIGdldEJvcmRlcihlbCwgJ1dpZHRoJywgaW5jbHVkZUJvcmRlcik7XG4gICAgICAgIGVsID0gZWwub2Zmc2V0UGFyZW50O1xuICAgIH1cblxuICAgIHJldHVybiB7IHRvcE9mZnNldDogeVBvcywgbGVmdE9mZnNldDogeFBvcyB9O1xufVxuXG5cbmZ1bmN0aW9uIGdldEJvcmRlcihlbCwgdHlwZSwgaW5jbHVkZUJvcmRlcikge1xuICAgIGlmIChpbmNsdWRlQm9yZGVyKSB7XG4gICAgICAgIHZhciBzaWRlID0gKHR5cGUgPT0gJ0hlaWdodCcpID8gJ3RvcCcgOiAnbGVmdCcsXG4gICAgICAgICAgICBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCksXG4gICAgICAgICAgICBzaWRlVmFsdWUgPSBwYXJzZUludChzdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZSgnYm9yZGVyLScgKyBzaWRlICsgJy13aWR0aCcpLCAxMCk7XG5cbiAgICAgICAgaWYgKHNpZGVWYWx1ZSkgcmV0dXJuIHNpZGVWYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG5cblxuLyoqXG4gKiBSZW1vdmVzIGVsZW1lbnQgZnJvbSB0aGUgZG9jdW1lbnRcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIHRoZSBlbGVtZW50IHRvIGJlIHJlbW92ZWRcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlRWxlbWVudChlbCkge1xuICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnQpe1xuICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWwpO1xuICAgICAgICBwYXJlbnQubm9ybWFsaXplKCk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgY2hpbGQgdGV4dCBub2RlIG9mIGFuIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR8Tm9kZX0gbm9kZSB0aGUgbm9kZSB0byBiZSBzZWFyY2hlZCwgaWYgdGhlIG5vZGUgaXMgdGV4dCBub2RlIHdlIHJldHVybiB0aGUgbm9kZS5cbiAqIEByZXR1cm4ge1RleHROb2RlfVxuICovXG5mdW5jdGlvbiBmaXJzdFRleHROb2RlKG5vZGUpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSBOb2RlLlRFWFRfTk9ERSkgcmV0dXJuIG5vZGU7XG4gICAgdmFyIHRyZWVXYWxrZXIgPSBjcmVhdGVUcmVlV2Fsa2VyKG5vZGUsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgICByZXR1cm4gdHJlZVdhbGtlci5maXJzdENoaWxkKCk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBsYXN0IGNoaWxkIHRleHQgbm9kZSBvZiBhbiBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fE5vZGV9IG5vZGUgdGhlIG5vZGUgdG8gYmUgc2VhcmNoZWQsIGlmIHRoZSBub2RlIGlzIHRleHQgbm9kZSB3ZSByZXR1cm4gdGhlIG5vZGUuXG4gKiBAcmV0dXJuIHtUZXh0Tm9kZX1cbiAqL1xuZnVuY3Rpb24gbGFzdFRleHROb2RlKG5vZGUpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSBOb2RlLlRFWFRfTk9ERSkgcmV0dXJuIG5vZGU7XG4gICAgdmFyIHRyZWVXYWxrZXIgPSBjcmVhdGVUcmVlV2Fsa2VyKG5vZGUsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgICByZXR1cm4gdHJlZVdhbGtlci5sYXN0Q2hpbGQoKTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgZWxlbWVudCBmcm9tIHRoZSBkb2N1bWVudCBwdXR0aW5nIGl0cyBjaGlsZHJlbiBpbiBpdHMgcGxhY2VcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIHRoZSBlbGVtZW50IHRvIGJlIFwidW53cmFwcGVkXCJcbiAqL1xuZnVuY3Rpb24gdW53cmFwRWxlbWVudChlbCkge1xuICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xuXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICB2YXIgZnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgLy8gbXVzdCBiZSBjb3BpZWQgdG8gYXZvaWQgaXRlcmF0aW5nIGEgbXV0YXRpbmcgbGlzdCBvZiBjaGlsZE5vZGVzXG4gICAgICAgIHZhciBjaGlsZHJlbiA9IF8uc2xpY2UoZWwuY2hpbGROb2Rlcyk7XG4gICAgICAgIGNoaWxkcmVuLmZvckVhY2goZnJhZy5hcHBlbmRDaGlsZCwgZnJhZyk7XG4gICAgICAgIHBhcmVudC5yZXBsYWNlQ2hpbGQoZnJhZywgZWwpO1xuICAgICAgICBwYXJlbnQubm9ybWFsaXplKCk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogV3JhcHMgYW4gZWxlbWVudCBpbiBhbm90aGVyIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSB3cmFwSW50b0VsXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbFxuICovXG5mdW5jdGlvbiB3cmFwSW5FbGVtZW50KHdyYXBJbnRvRWwsIGVsKSB7XG4gICAgdmFyIHBhcmVudCA9IGVsLnBhcmVudE5vZGU7XG5cbiAgICBpZiAocGFyZW50KSB7XG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod3JhcEludG9FbCwgZWwpO1xuICAgICAgICB3cmFwSW50b0VsLmFwcGVuZENoaWxkKGVsKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBUcmltcyBhIHRleHQgbm9kZSBvZiB0cmFpbGluZyBzcGFjZXMsIGFuZCByZXR1cm5zIHRydWUgaWYgYSB0cmltIHdhcyBwZXJmb3JtZWQuXG4gKlxuICogQHBhcmFtICB7VGV4dE5vZGV9IG5vZGVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIHRyaW1Ob2RlUmlnaHQobm9kZSkge1xuICAgIHJldHVybiBfdHJpbU5vZGUobm9kZSwgJ3RyaW1SaWdodCcpO1xufVxuXG5cbi8qKlxuICogVHJpbXMgYSB0ZXh0IG5vZGUgb2YgbGVhZGluZyBzcGFjZXMsIGFuZCByZXR1cm5zIHRydWUgaWYgYSB0cmltIHdhcyBwZXJmb3JtZWQuXG4gKlxuICogQHBhcmFtICB7VGV4dE5vZGV9IG5vZGVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIHRyaW1Ob2RlTGVmdChub2RlKSB7XG4gICAgcmV0dXJuIF90cmltTm9kZShub2RlLCAndHJpbUxlZnQnKTtcbn1cblxuXG5mdW5jdGlvbiBfdHJpbU5vZGUobm9kZSwgbWV0aG9kTmFtZSkge1xuICAgIHZhciBsZW4gPSBub2RlLmxlbmd0aDtcbiAgICBub2RlLnRleHRDb250ZW50ID0gbm9kZS50ZXh0Q29udGVudFttZXRob2ROYW1lXSgpO1xuICAgIHJldHVybiBsZW4gIT09IG5vZGUubGVuZ3RoO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgcmVmZXJlbmNlIHRvIGNvbXBvbmVudCBmcm9tIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbFxuICovXG5mdW5jdGlvbiBkZXRhY2hDb21wb25lbnQoZWwpIHtcbiAgICBkZWxldGUgZWxbY29uZmlnLmNvbXBvbmVudFJlZl07XG59XG5cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGNvbnRlbnQgb2YgYSBodG1sIHN0cmluZ1xuICogQHBhcmFtICB7U3RyaW5nfSBzdHIgQW55IHN0cmluZ1xuICogQHJldHVybiB7U3RyaW5nfSByZXR1cm5zIHRoZSBzdHJpbmcgY2xlYW5lZCBvZiBhbnkgaHRtbCBjb250ZW50LlxuICovXG5mdW5jdGlvbiBzdHJpcEh0bWwoc3RyKSB7XG4gICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0RJVicpO1xuICAgIGRpdi5pbm5lckhUTUwgPSBzdHI7XG4gICAgcmV0dXJuIGRpdi50ZXh0Q29udGVudCB8fCAnJztcbn1cblxuXG4vKipcbiAqIENvbnZlbmllbmNlIHdyYXBwZXIgZm9yIG5hdGl2ZSBUcmVlV2Fsa2VyIHRoYXQgYXV0b21hdGljYWxseSB3YWxrcyB0aGUgdHJlZSBhbmQgY2FsbHMgYW4gaXRlcmF0b3IgZnVuY3Rpb24uXG4gKiBUaGlzIHdpbGwgbm90IGl0ZXJhdGUgdGhlIHJvb3QgZWxlbWVudC5cbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSByb290IFRoZSBjb250YWluaW5nIHJvb3QgZWxlbWVudCB0byBiZSB3YWxrZWQuIFdpbGwgbm90IGJlIGl0ZXJhdGVkLlxuICogQHBhcmFtICB7Tm9kZUZpbGVyfSBmaWx0ZXIgQSBOb2RlRmlsdGVyIGNvbnN0YW50LCBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vZG9jcy9XZWIvQVBJL1RyZWVXYWxrZXJcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBpdGVyYXRvciBBIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBlYWNoIG5vZGUuIFJldHVybmluZyAnZmFsc2UnIHdpbGwgYnJlYWsuXG4gKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHQgQW4gb3B0aW9uYWwgY29udGV4dCB0byBwYXNzZWQsIGRlZmF1bHRzIHRvIHJvb3QuXG4gKi9cbmZ1bmN0aW9uIHdhbGtUcmVlKHJvb3QsIGZpbHRlciwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgdHcgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHJvb3QsIGZpbHRlcik7XG4gICAgd2hpbGUodHcubmV4dE5vZGUoKSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gaXRlcmF0b3IuY2FsbChjb250ZXh0IHx8IHJvb3QsIHR3LmN1cnJlbnROb2RlKTtcbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpIGJyZWFrO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIFJldHVybnMgYXJyYXkgb2YgY2hpbGQgaW5kZXhlcyBvZiBlbGVtZW50IHBhdGggaW5zaWRlIHJvb3QgZWxlbWVudCBpbiBET00gdHJlZSB1c2luZyBicmVhZHRoIGZpcnN0IHRyZWUgdHJhdmVyc2FsLlxuICogUmV0dXJucyB1bmRlZmluZWQgaWYgdGhlIGVsZW1lbnQgaXMgbm90IGluc2lkZSByb290IGVsZW1lbnQsIDAgaWYgdGhlIHJvb3QgZWxlbWVudCBpdHNlbGYgaXMgcGFzc2VkLlxuICpcbiAqIEBwYXJhbSAge0VsZW1lbnR9IHJvb3RFbCBlbGVtZW50IHRvIHNlYXJjaFxuICogQHBhcmFtICB7RWxlbWVudH0gZWwgZWxlbWVudCB0byBmaW5kIHRoZSBpbmRleCBvZlxuICogQHJldHVybiB7QXJyYXlbTnVtYmVyXX1cbiAqL1xuZnVuY3Rpb24gdHJlZVBhdGhPZihyb290RWwsIGVsKSB7XG4gICAgaWYgKCEgKHJvb3RFbCAmJiByb290RWwuY29udGFpbnMoZWwpKSkgcmV0dXJuO1xuXG4gICAgdmFyIHRyZWVQYXRoID0gW11cbiAgICAgICAgLCBub2RlID0gcm9vdEVsO1xuXG4gICAgd2hpbGUgKG5vZGUgIT0gZWwpIHtcbiAgICAgICAgdmFyIG5vZGVJbmRleCA9IF8uZmluZEluZGV4KG5vZGUuY2hpbGROb2RlcywgY29udGFpbnNFbCk7XG4gICAgICAgIHRyZWVQYXRoLnB1c2gobm9kZUluZGV4KTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGROb2Rlc1tub2RlSW5kZXhdO1xuICAgIH1cblxuICAgIHJldHVybiB0cmVlUGF0aDtcblxuICAgIGZ1bmN0aW9uIGNvbnRhaW5zRWwoY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkLmNvbnRhaW5zKGVsKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGVsZW1lbnQgYXQgZ2l2ZW4gdHJlZSBwYXRoXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSByb290RWxcbiAqIEBwYXJhbSB7QXJyYXlbTnVtYmVyXX0gdHJlZVBhdGhcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gbmVhcmVzdCByZXR1cm4gbmVhcmVzdCBwb3NzaWJsZSBub2RlIGlmIGV4YWN0IG5vZGUgZG9lcyBub3QgZXhpc3RcbiAqIEByZXR1cm4ge05vZGV9XG4gKi9cbmZ1bmN0aW9uIGdldE5vZGVBdFRyZWVQYXRoKHJvb3RFbCwgdHJlZVBhdGgsIG5lYXJlc3QpIHtcbiAgICBpZiAoIXRyZWVQYXRoKSByZXR1cm47XG5cbiAgICB2YXIgbGVuID0gdHJlZVBhdGgubGVuZ3RoO1xuICAgIGlmIChsZW4gPT09IDApIHJldHVybiByb290RWw7XG5cbiAgICB2YXIgbm9kZSA9IHJvb3RFbDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gbm9kZS5jaGlsZE5vZGVzO1xuICAgICAgICBpZiAoISBjaGlsZHJlbikge1xuICAgICAgICAgICAgaWYgKCEgbmVhcmVzdCkgbm9kZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjaGlsZEluZGV4ID0gdHJlZVBhdGhbaV1cbiAgICAgICAgICAgICwgY2hpbGQgPSBjaGlsZHJlbltjaGlsZEluZGV4XTtcbiAgICAgICAgaWYgKCEgY2hpbGQpIHtcbiAgICAgICAgICAgIG5vZGUgPSBuZWFyZXN0XG4gICAgICAgICAgICAgICAgICAgID8gY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gY2hpbGQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGU7XG59XG5cblxuLyoqXG4gKiBJbnNlcnRzIGFuIGVsZW1lbnQgaW5zaWRlIHJvb3QgYXQgYSBnaXZlbiBwYXRoIGluIHRyZWUgKHRoYXQgaGFzIHRoZSBzYW1lIG1lYW5pbmcgYXMgdGhlIGluZGV4IHJldHVybmVkIGJ5IGB0cmVlUGF0aE9mYCBmdW5jdGlvbikuIElmIGVsZW1lbnQgaXMgYWxyZWFkeSBpbiB0aGUgcm9vdCdzIHRyZWUsIGl0IHdpbGwgYmUgcmVtb3ZlZCBmaXJzdCBhbmQgdGhlbiBtb3ZlZCB0byB0aGUgcGFzc2VkIHRyZWVJbmRleFxuICogSW5zZXJ0aW9uIGF0IGluZGV4IDAgaXMgbm90IHBvc3NpYmxlIGFuZCB3aWxsIHJldHVybiB1bmRlZmluZWQgYXMgaXQgd291bGQgbWVhbiByZXBsYWNpbmcgdGhlIHJvb3QgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHJvb3RFbCBlbGVtZW50IGludG8gd2hpY2ggdG8gaW5zZXJ0XG4gKiBAcGFyYW0ge051bWJlcn0gdHJlZUluZGV4IGluZGV4IGluIERPTSB0cmVlIGluc2lkZSByb290IGVsZW1lbnQgKHNlZSB0cmVlUGF0aE9mKVxuICogQHBhcmFtIHtFbGVtZW50fSBlbCBlbGVtZW50IHRvIGJlIGluc2VydGVkXG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHdhcyBzdWNjZXNzZnVsbHkgaW5zZXJ0ZWRcbiAqL1xuZnVuY3Rpb24gaW5zZXJ0QXRUcmVlUGF0aChyb290RWwsIHRyZWVQYXRoLCBlbCwgbmVhcmVzdCkge1xuICAgIHZhciB0b05vcm1hbGl6ZSA9IGVsLm5vZGVUeXBlID09IE5vZGUuVEVYVF9OT0RFO1xuICAgIGlmIChyb290RWwuY29udGFpbnMoZWwpKVxuICAgICAgICByZW1vdmVFbGVtZW50KGVsKTsgLy8gY2FuJ3QgdXNlIHJlbW92ZUNoaWxkIGFzIHJvb3RFbCBoZXJlIGlzIG5vdCBhbiBpbW1lZGlhdGUgcGFyZW50XG5cbiAgICBpZiAodHJlZVBhdGgubGVuZ3RoID09IDApIHJldHVybjtcblxuICAgIHZhciBwYXJlbnQgPSBnZXROb2RlQXRUcmVlUGF0aChyb290RWwsIHRyZWVQYXRoLnNsaWNlKDAsIC0xKSwgbmVhcmVzdClcbiAgICAgICAgLCBjaGlsZHJlbiA9IHBhcmVudC5jaGlsZE5vZGVzO1xuXG4gICAgaWYgKCEgY2hpbGRyZW4pIHtcbiAgICAgICAgaWYgKG5lYXJlc3QpIHtcbiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICAgICAgICAgICAgY2hpbGRyZW4gPSBwYXJlbnQuY2hpbGROb2RlcztcbiAgICAgICAgfSBlbHNlIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGRJbmRleCA9IHRyZWVQYXRoW3RyZWVQYXRoLmxlbmd0aCAtIDFdXG4gICAgICAgICwgY2hpbGQgPSBjaGlsZHJlbltjaGlsZEluZGV4XTtcblxuICAgIGlmIChjaGlsZCkge1xuICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGVsLCBjaGlsZCk7XG4gICAgICAgIGlmICh0b05vcm1hbGl6ZSkgcGFyZW50Lm5vcm1hbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiAoY2hpbGRJbmRleCA9PT0gMCB8fCBuZWFyZXN0KSkge1xuICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICBpZiAodG9Ob3JtYWxpemUpIHBhcmVudC5ub3JtYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY2hpbGQgPSBjaGlsZHJlbltjaGlsZEluZGV4IC0gMV07XG4gICAgICAgIGlmIChjaGlsZCB8fCBuZWFyZXN0KSB7XG4gICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICAgICAgaWYgKHRvTm9ybWFsaXplKSBwYXJlbnQubm9ybWFsaXplKCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG4vKipcbiAqIFJldHVybnMgYHRydWVgIGlmIHRoZSBmaXJzdCB0cmVlIHBhdGggcG9pbnRzIHRvIGEgbm9kZSB3aGljaCBpcyBiZWZvcmUgdGhlIG90aGVyIGluIHRoZSBkb2N1bWVudCBvcmRlci5cbiAqIEBwYXJhbSAge0FycmF5fSAgcGF0aDEgICBBIHRyZWVwYXRoIGFycmF5XG4gKiBAcGFyYW0gIHtBcnJheX0gIHBhdGgyICAgQSB0cmVlcGF0aCBhcnJheVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNUcmVlUGF0aEJlZm9yZShwYXRoMSwgcGF0aDIpIHtcbiAgICB2YXIgaSA9IDBcbiAgICAgICAgLCBpc0JlZm9yZTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocGF0aDEpICYmIEFycmF5LmlzQXJyYXkocGF0aDIpKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLmVycm9yKCdpc1RyZWVQYXRoQmVmb3JlOiBPbmUgb3IgYm90aCBwYXRocyBhcmUgbm90IHZhbGlkIHRyZWVwYXRoIGFycmF5cy4nKTtcblxuICAgIGZvciAoaTsgaSA8IHBhdGgxLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwYXRoMVtpXSA8IHBhdGgyW2ldKSB7XG4gICAgICAgICAgICBpc0JlZm9yZSA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmIChwYXRoMVtpXSA+IHBhdGgyW2ldKSB7XG4gICAgICAgICAgICBpc0JlZm9yZSA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGlzQmVmb3JlID09ICd1bmRlZmluZWQnKVxuICAgICAgICBpZiAocGF0aDEubGVuZ3RoIDwgcGF0aDIubGVuZ3RoKVxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ2lzVHJlZVBhdGhCZWZvcmU6IE9uZSBub2RlIGlzIGluc2lkZSBhbm90aGVyJyk7XG5cbiAgICByZXR1cm4gaXNCZWZvcmUgfHwgZmFsc2U7XG59XG5cblxuLyoqXG4gKiBDb252ZXJ0cyBub24gbGF0aW4gY2hhcmFjdGVycyB0byBIVE1MIGVudGl0eSBjb2Rlcy5cbiAqIEBwYXJhbSAge1N0cmluZ30gc3RyIHRoZSBzdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybiB7U3RyaW5nfSAgICAgdGhlIHN0cmluZyB3aXRoIGh0bWwgZW50aXRpZXNcbiAqL1xuZnVuY3Rpb24gaHRtbEVudGl0aWVzKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW1xcdTAwQTAtXFx1OTk5OTk8PlxcJl0vZ2ltLCBmdW5jdGlvbihpKSB7XG4gICAgICAgIHJldHVybiAnJiMnK2kuY2hhckNvZGVBdCgwKSsnOyc7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gY3JlYXRlVHJlZVdhbGtlcihlbCwgd2hhdFRvU2hvdykge1xuICAgIHdoYXRUb1Nob3cgPSB3aGF0VG9TaG93IHx8IChOb2RlRmlsdGVyLlNIT1dfVEVYVCB8IE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5UKTtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihlbCwgd2hhdFRvU2hvdyk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSByZWZlcmVuY2UgdG8gdGhlIHdpbmRvdyB0aGUgbm9kZSBpcyBpblxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHJldHVybiB7V2luZG93fVxuICovXG5mdW5jdGlvbiBnZXROb2RlV2luZG93KG5vZGUpIHtcbiAgICB2YXIgZG9jID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBkb2MgJiYgKGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93KTtcbn1cblxuXG5cbi8qKlxuICogZG8gc29tZXRoaW5nIGZvciBlYWNoIG5vZGVzIGNvbnRhaW5lZCBpbiBhIHJhbmdlXG4gKlxuICogQHBhcmFtIHtyYW5nZX0gYSByYW5nZVxuICogQHBhcmFtIHtjYn0gYSBmdW5jdGlvbiB0YWtpbmcgYSBub2RlIGFzIGFyZ3VtZW50XG5cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaE5vZGVzSW5SYW5nZShyYW5nZSwgY2Ipe1xuICAgIHZhciByYW5nZUNvbnRhaW5lciA9IHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyXG4gICAgICAgICwgZG9jID0gcmFuZ2VDb250YWluZXIub3duZXJEb2N1bWVudDtcblxuICAgIGZ1bmN0aW9uIGlzTm9kZUluc2lkZVJhbmdlKG5vZGUpe1xuICAgICAgICB2YXIgbm9kZVJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgdmFyIGlzSW5zaWRlID0gZmFsc2U7XG4gICAgICAgIG5vZGVSYW5nZS5zZWxlY3ROb2RlKG5vZGUpO1xuXG4gICAgICAgIGlmIChub2RlUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKHdpbmRvdy5SYW5nZS5TVEFSVF9UT19TVEFSVCwgcmFuZ2UpICE9IC0xXG4gICAgICAgICAgICAmJiBub2RlUmFuZ2UuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKHdpbmRvdy5SYW5nZS5FTkRfVE9fRU5ELCByYW5nZSkgIT0gMSl7XG4gICAgICAgICAgICBpc0luc2lkZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZVJhbmdlLmRldGFjaCgpO1xuICAgICAgICByZXR1cm4gaXNJbnNpZGU7XG4gICAgfVxuXG4gICAgdmFyIHRyZWVXYWxrZXIgPSBkb2MuY3JlYXRlVHJlZVdhbGtlcihyYW5nZUNvbnRhaW5lcixcbiAgICAgICAgICAgIE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5UIHwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuXG4gICAgdmFyIGN1cnJlbnROb2RlO1xuICAgIHdoaWxlIChjdXJyZW50Tm9kZSA9IHRyZWVXYWxrZXIubmV4dE5vZGUoKSl7IC8vIHNob3VsZCBiZSBhc3NpZ25tZW50XG4gICAgICAgIGlmIChpc05vZGVJbnNpZGVSYW5nZShjdXJyZW50Tm9kZSkpe1xuICAgICAgICAgICAgY2IoY3VycmVudE5vZGUpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIGdldCBhbGwgY29tcG9uZW50cyBjb250YWluZWQgaW4gYSByYW5nZVxuICpcbiAqIEBwYXJhbSB7cmFuZ2V9IGEgRE9NIHJhbmdlLlxuICovXG5mdW5jdGlvbiBnZXRDb21wb25lbnRzRnJvbVJhbmdlKHJhbmdlKSB7XG4gICAgdmFyIHdpbiA9IGdldE5vZGVXaW5kb3cocmFuZ2Uuc3RhcnRDb250YWluZXIpXG4gICAgICAgICwgQ29tcG9uZW50ID0gd2luLm1pbG8uQ29tcG9uZW50O1xuXG4gICAgdmFyIGNvbXBvbmVudHMgPSBbXTtcbiAgICBmb3JFYWNoTm9kZXNJblJhbmdlKHJhbmdlLCBmdW5jdGlvbiAobm9kZSl7XG4gICAgICAgIGlmIChub2RlLm5vZGVUeXBlICE9IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICAgICAgICB2YXIgY29tcCA9IENvbXBvbmVudC5nZXRDb21wb25lbnQobm9kZSk7XG4gICAgICAgICAgICBpZiAoY29tcClcbiAgICAgICAgICAgICAgICBjb21wb25lbnRzLnB1c2goY29tcCk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBjb21wb25lbnRzO1xufVxuXG4vKipcbiAqIGRlbGV0ZSBhIHJhbmdlXG4gKlxuICogQHBhcmFtIHtyYW5nZX0gZGVsZXRlIGEgRE9NIHJhbmdlIGFuZCBhbGwgdGhlIGNvbXBvbmVudHMgaW5zaWRlXG4gKi9cbmZ1bmN0aW9uIGRlbGV0ZVJhbmdlV2l0aENvbXBvbmVudHMocmFuZ2UpIHtcbiAgICB2YXIgY29tcG9uZW50cyA9IGdldENvbXBvbmVudHNGcm9tUmFuZ2UocmFuZ2UpO1xuXG4gICAgY29tcG9uZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGNvbXApIHtcbiAgICAgICAgY29tcC5kZXN0cm95KHRydWUpO1xuICAgIH0pO1xuXG4gICAgcmFuZ2UuZGVsZXRlQ29udGVudHMoKTtcbn1cblxuLyoqXG4gKiBjaGVjayBpZiB0d28gcmFuZ2VzIGFyZSBlcXVpdmFsZW50XG4gKlxuICogQHBhcmFtIHtyYW5nZX0gcmFuZ2UxXG4gKiBAcGFyYW0ge3JhbmdlfSByYW5nZTJcbiAqIEByZXR1cm4ge0Jvb2xlYW59IGFyZSB0aGUgdHdvIHJhbmdlcyBlcXVpdmFsZW50XG4gKi9cbmZ1bmN0aW9uIGFyZVJhbmdlc0VxdWFsKHJhbmdlMSwgcmFuZ2UyKXtcbiAgICByZXR1cm4gcmFuZ2UxLmNvbXBhcmVCb3VuZGFyeVBvaW50cyh3aW5kb3cuUmFuZ2UuU1RBUlRfVE9fU1RBUlQsIHJhbmdlMikgPT0gMCAmJiByYW5nZTEuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKHdpbmRvdy5SYW5nZS5FTkRfVE9fRU5ELCByYW5nZTIpID09IDA7XG59XG5cblxuLyoqXG4gKiBBZGRzIGEgc2luZ2xlIHBpeGVsIGRpdiB0byB0aGUgYm9keSBhdCBhIGdpdmVuIHggYW5kIHkgcG9zaXRpb24uIFVzZWZ1bCBmb3IgZGVidWdnaW5nIHBvc2l0aW9uIHNwZWNpZmljIGNvZGUuXG4gKiBAcGFyYW0ge051bWJlcn0geFxuICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAqL1xuZnVuY3Rpb24gYWRkRGVidWdQb2ludCh4LCB5KSB7XG4gICAgdmFyIGRiRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkYkVsLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCAnd2lkdGg6IDFweDsgaGVpZ2h0OiAxcHg7IHBvc2l0aW9uOmZpeGVkOyBsZWZ0OicreCsncHg7IHRvcDonK3krJ3B4OyBiYWNrZ3JvdW5kLWNvbG9yOnJlZDsgei1pbmRleDogMTAwJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRiRWwpO30sIDIwMCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuL2NoZWNrJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBET01MaXN0ZW5lcnM7XG5cblxuZnVuY3Rpb24gRE9NTGlzdGVuZXJzKCkge1xuICAgIHRoaXMubGlzdGVuZXJzID0gW107XG59XG5cblxuXy5leHRlbmRQcm90byhET01MaXN0ZW5lcnMsIHtcbiAgICBhZGQ6IERPTUxpc3RlbmVycyRhZGQsXG4gICAgcmVtb3ZlOiBET01MaXN0ZW5lcnMkcmVtb3ZlLFxuICAgIHJlbW92ZUFsbDogRE9NTGlzdGVuZXJzJHJlbW92ZUFsbFxufSk7XG5cblxuZnVuY3Rpb24gRE9NTGlzdGVuZXJzJGFkZCh0YXJnZXQsIGV2ZW50VHlwZSwgaGFuZGxlcikge1xuICAgIHRoaXMubGlzdGVuZXJzLnB1c2goe1xuICAgICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgICAgZXZlbnRUeXBlOiBldmVudFR5cGUsXG4gICAgICAgIGhhbmRsZXI6IGhhbmRsZXJcbiAgICB9KTtcbiAgICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGhhbmRsZXIpO1xufVxuXG5cbmZ1bmN0aW9uIERPTUxpc3RlbmVycyRyZW1vdmUodGFyZ2V0LCBldmVudFR5cGUsIGhhbmRsZXIpIHtcbiAgICB2YXIgbGlzdGVuZXIgPSB7XG4gICAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgICBldmVudFR5cGU6IGV2ZW50VHlwZSxcbiAgICAgICAgaGFuZGxlcjogaGFuZGxlclxuICAgIH07XG4gICAgdmFyIGlkeCA9IF8uZmluZEluZGV4KHRoaXMubGlzdGVuZXJzLCBfLnBhcnRpYWwoXy5pc0VxdWFsLCBsaXN0ZW5lcikpO1xuXG4gICAgaWYgKGlkeCA+IC0xKSB7XG4gICAgICAgIHRoaXMubGlzdGVuZXJzLnNwbGljZShpZHgsIDEpO1xuICAgICAgICBfcmVtb3ZlTGlzdGVuZXIobGlzdGVuZXIpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBET01MaXN0ZW5lcnMkcmVtb3ZlQWxsKCkge1xuICAgIHRoaXMubGlzdGVuZXJzLmZvckVhY2goX3JlbW92ZUxpc3RlbmVyKTtcbiAgICB0aGlzLmxpc3RlbmVycyA9IFtdO1xufVxuXG5cbmZ1bmN0aW9uIF9yZW1vdmVMaXN0ZW5lcihsKSB7XG4gICAgbC50YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihsLmV2ZW50VHlwZSwgbC5oYW5kbGVyKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZG9tUmVhZHk7XG5cblxudmFyIGRvbVJlYWR5RnVuY3MgPSBbXVxuICAgICwgZG9tUmVhZHlTdWJzY3JpYmVkID0gZmFsc2U7XG5cblxuZnVuY3Rpb24gZG9tUmVhZHkoZnVuYykgeyAvLyAsIGFyZ3VtZW50c1xuICAgIHZhciBzZWxmID0gdGhpc1xuICAgICAgICAsIGFyZ3MgPSBfLnNsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgaWYgKGlzUmVhZHkuY2FsbCh0aGlzKSlcbiAgICAgICAgY2FsbEZ1bmMoKTtcbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKCFkb21SZWFkeVN1YnNjcmliZWQpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3JlYWR5c3RhdGVjaGFuZ2UnLCBvbkRvbVJlYWR5KTtcbiAgICAgICAgICAgIGRvbVJlYWR5U3Vic2NyaWJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZG9tUmVhZHlGdW5jcy5wdXNoKGNhbGxGdW5jKTsgLy8gY2xvc3VyZSBpcyBhZGRlZCwgc28gZXZlcnkgdGltZSBkaWZmZXJlbnQgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWRcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxsRnVuYygpIHtcbiAgICAgICAgZnVuYy5hcHBseShzZWxmLCBhcmdzKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gb25Eb21SZWFkeSgpIHtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdyZWFkeXN0YXRlY2hhbmdlJywgb25Eb21SZWFkeSk7XG4gICAgZG9tUmVhZHlGdW5jcy5mb3JFYWNoKGZ1bmN0aW9uKGZ1bmMpIHsgZnVuYygpOyB9KTtcbn1cblxuXG5fLmV4dGVuZChkb21SZWFkeSwge1xuICAgIGlzUmVhZHk6IGlzUmVhZHlcbn0pO1xuXG5cbmZ1bmN0aW9uIGlzUmVhZHkoKSB7XG4gICAgdmFyIHJlYWR5U3RhdGUgPSBkb2N1bWVudC5yZWFkeVN0YXRlO1xuICAgIHJldHVybiByZWFkeVN0YXRlID09ICdsb2FkaW5nJyA/IGZhbHNlIDogcmVhZHlTdGF0ZTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvY19jbGFzcycpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgZHJhZ0Ryb3BDb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKS5kcmFnRHJvcFxuICAgICwgY29tcG9uZW50TWV0YVJlZ2V4ID0gZHJhZ0Ryb3BDb25maWcuZGF0YVR5cGVzLmNvbXBvbmVudE1ldGFSZWdleFxuICAgICwganNvblBhcnNlID0gcmVxdWlyZSgnLi9qc29uX3BhcnNlJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgYmFzZTMyID0gcmVxdWlyZSgnYmFzZTMyJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBEcmFnRHJvcDtcblxuXG4vKipcbiAqIFdyYXBwZXIgZm9yIGV2ZW50LmRhdGFUcmFuc2ZlciBvZiBkcmFnLWRyb3AgSFRNTCBBUElcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7ZXZlbnR9IERPTSBldmVudFxuICogQHJldHVybiB7RHJhZ0Ryb3B9XG4gKi9cbmZ1bmN0aW9uIERyYWdEcm9wKGV2ZW50KSB7XG4gICAgdGhpcy5ldmVudCA9IGV2ZW50O1xuICAgIHRoaXMuZGF0YVRyYW5zZmVyID0gZXZlbnQuZGF0YVRyYW5zZmVyO1xuICAgIHRoaXMudHlwZXMgPSBldmVudC5kYXRhVHJhbnNmZXIudHlwZXM7XG59XG5cbi8qKlxuICogVXNhZ2U6XG4gKiB2YXIgdGVzdERUID0gbmV3IERyYWdEcm9wKGV2ZW50KTtcbiAqIHRlc3REVC5zZXRDb21wb25lbnRNZXRhKG5ld0NvbXBvbmVudCwge3Rlc3Q6ICd0ZXN0JywgdGVzdDI6ICd0ZXN0Mid9KTtcbiAqIHRlc3REVC5nZXRDb21wb25lbnRNZXRhKCk7XG4gKi9cblxuXy5leHRlbmQoRHJhZ0Ryb3AsIHtcbiAgICBjb21wb25lbnREYXRhVHlwZTogRHJhZ0Ryb3AkJGNvbXBvbmVudERhdGFUeXBlXG59KTtcblxuXy5leHRlbmRQcm90byhEcmFnRHJvcCwge1xuICAgIGlzQ29tcG9uZW50OiBEcmFnRHJvcCRpc0NvbXBvbmVudCxcbiAgICBnZXRDb21wb25lbnRTdGF0ZTogRHJhZ0Ryb3AkZ2V0Q29tcG9uZW50U3RhdGUsXG4gICAgc2V0Q29tcG9uZW50U3RhdGU6IERyYWdEcm9wJHNldENvbXBvbmVudFN0YXRlLFxuICAgIGdldENvbXBvbmVudE1ldGE6IERyYWdEcm9wJGdldENvbXBvbmVudE1ldGEsXG4gICAgc2V0Q29tcG9uZW50TWV0YTogRHJhZ0Ryb3Akc2V0Q29tcG9uZW50TWV0YSxcbiAgICBnZXRBbGxvd2VkRWZmZWN0czogRHJhZ0Ryb3AkZ2V0QWxsb3dlZEVmZmVjdHMsXG4gICAgc2V0QWxsb3dlZEVmZmVjdHM6IERyYWdEcm9wJHNldEFsbG93ZWRFZmZlY3RzLFxuICAgIGdldERyb3BFZmZlY3Q6IERyYWdEcm9wJGdldERyb3BFZmZlY3QsXG4gICAgc2V0RHJvcEVmZmVjdDogRHJhZ0Ryb3Akc2V0RHJvcEVmZmVjdCxcbiAgICBpc0VmZmVjdEFsbG93ZWQ6IERyYWdEcm9wJGlzRWZmZWN0QWxsb3dlZCxcbiAgICBnZXREYXRhOiBEcmFnRHJvcCRnZXREYXRhLFxuICAgIHNldERhdGE6IERyYWdEcm9wJHNldERhdGEsXG4gICAgY2xlYXJEYXRhOiBEcmFnRHJvcCRjbGVhckRhdGFcbn0pO1xuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJCRjb21wb25lbnREYXRhVHlwZSgpIHtcbiAgICByZXR1cm4gZHJhZ0Ryb3BDb25maWcuZGF0YVR5cGVzLmNvbXBvbmVudDtcbn1cblxuXG5mdW5jdGlvbiBEcmFnRHJvcCRpc0NvbXBvbmVudCgpIHtcbiAgICByZXR1cm4gXy5pbmRleE9mKHRoaXMudHlwZXMsIERyYWdEcm9wLmNvbXBvbmVudERhdGFUeXBlKCkpID49IDA7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3AkZ2V0Q29tcG9uZW50U3RhdGUoKSB7XG4gICAgdmFyIGRhdGFUeXBlID0gRHJhZ0Ryb3AuY29tcG9uZW50RGF0YVR5cGUoKVxuICAgICAgICAsIHN0YXRlU3RyID0gdGhpcy5kYXRhVHJhbnNmZXIuZ2V0RGF0YShkYXRhVHlwZSlcbiAgICAgICAgLCBzdGF0ZSA9IGpzb25QYXJzZShzdGF0ZVN0cik7XG5cbiAgICByZXR1cm4gc3RhdGU7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3Akc2V0Q29tcG9uZW50U3RhdGUoY29tcG9uZW50LCBzdGF0ZVN0cil7XG4gICAgaWYgKCEgc3RhdGVTdHIpIHtcbiAgICAgICAgdmFyIHN0YXRlID0gY29tcG9uZW50LmdldFRyYW5zZmVyU3RhdGUoeyByZXF1ZXN0ZWRCeTogJ2RyYWcnIH0pO1xuICAgICAgICBzdGF0ZVN0ciA9IEpTT04uc3RyaW5naWZ5KHN0YXRlKTtcbiAgICB9XG4gICAgdmFyIGRhdGFUeXBlID0gRHJhZ0Ryb3AuY29tcG9uZW50RGF0YVR5cGUoKTtcblxuICAgIHN0YXRlU3RyICYmIHRoaXMuZGF0YVRyYW5zZmVyLnNldERhdGEoZGF0YVR5cGUsIHN0YXRlU3RyKTtcbiAgICB0aGlzLmRhdGFUcmFuc2Zlci5zZXREYXRhKCd0ZXh0L2h0bWwnLCBjb21wb25lbnQuZWwub3V0ZXJIVE1MKTtcbiAgICByZXR1cm4gc3RhdGVTdHI7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3Akc2V0Q29tcG9uZW50TWV0YShjb21wb25lbnQsIHBhcmFtcywgZGF0YSkge1xuICAgIHZhciBtZXRhID0gX2NvbXBvbmVudE1ldGEoY29tcG9uZW50KTtcblxuICAgIHZhciBwYXJhbXNTdHIgPSBfLnRvUXVlcnlTdHJpbmcocGFyYW1zKTtcbiAgICB2YXIgZGF0YVR5cGUgPSBkcmFnRHJvcENvbmZpZy5kYXRhVHlwZXMuY29tcG9uZW50TWV0YVRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCclY2xhc3MnLCBfZW5jb2RlKG1ldGEuY29tcENsYXNzIHx8ICcnKSlcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoJyVuYW1lJywgX2VuY29kZShtZXRhLmNvbXBOYW1lIHx8ICcnKSlcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoJyVwYXJhbXMnLCBfZW5jb2RlKHBhcmFtc1N0ciB8fCAnJykpO1xuXG4gICAgaWYgKGRhdGEgJiYgdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcpIGRhdGEgPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcblxuICAgIHRoaXMuZGF0YVRyYW5zZmVyLnNldERhdGEoZGF0YVR5cGUsIGRhdGEgfHwgJycpO1xuXG4gICAgcmV0dXJuIGRhdGFUeXBlO1xufVxuXG5cbmZ1bmN0aW9uIF9lbmNvZGUoc3RyKSB7XG4gICAgcmV0dXJuIGJhc2UzMi5lbmNvZGUoc3RyKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5cbmZ1bmN0aW9uIF9jb21wb25lbnRNZXRhKGNvbXBvbmVudCkge1xuICAgIHJldHVybiBjb21wb25lbnQudHJhbnNmZXJcbiAgICAgICAgICAgID8gY29tcG9uZW50LnRyYW5zZmVyLmdldENvbXBvbmVudE1ldGEoKVxuICAgICAgICAgICAgOiB7IFxuICAgICAgICAgICAgICAgIGNvbXBDbGFzczogY29tcG9uZW50LmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICAgICAgY29tcE5hbWU6IGNvbXBvbmVudC5uYW1lXG4gICAgICAgICAgICB9O1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJGdldENvbXBvbmVudE1ldGEoKSB7XG4gICAgdmFyIG1hdGNoO1xuICAgIHZhciBtZXRhRGF0YVR5cGUgPSBfLmZpbmQodGhpcy50eXBlcywgZnVuY3Rpb24gKGRUeXBlKSB7XG4gICAgICAgIG1hdGNoID0gZFR5cGUubWF0Y2goY29tcG9uZW50TWV0YVJlZ2V4KTtcbiAgICAgICAgcmV0dXJuICEhbWF0Y2g7XG4gICAgfSk7XG4gICAgaWYgKCFtZXRhRGF0YVR5cGUpIHJldHVybjtcblxuICAgIGZvciAodmFyIGk9MTsgaTw0OyBpKyspXG4gICAgICAgIG1hdGNoW2ldID0gYmFzZTMyLmRlY29kZShtYXRjaFtpXSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBjb21wQ2xhc3M6IG1hdGNoWzFdLFxuICAgICAgICBjb21wTmFtZTogbWF0Y2hbMl0sXG4gICAgICAgIHBhcmFtczogXy5mcm9tUXVlcnlTdHJpbmcobWF0Y2hbM10pLFxuICAgICAgICBtZXRhRGF0YVR5cGU6IG1ldGFEYXRhVHlwZSxcbiAgICAgICAgbWV0YURhdGE6IF8uanNvblBhcnNlKHRoaXMuZGF0YVRyYW5zZmVyLmdldERhdGEobWV0YURhdGFUeXBlKSkgXG4gICAgICAgICAgICAgICAgICAgID8gXy5qc29uUGFyc2UodGhpcy5kYXRhVHJhbnNmZXIuZ2V0RGF0YShtZXRhRGF0YVR5cGUpKSBcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmRhdGFUcmFuc2Zlci5nZXREYXRhKG1ldGFEYXRhVHlwZSlcbiAgICB9O1xufVxuXG5cbi8vIGFzIGRlZmluZWQgaGVyZTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9EcmFnRHJvcC9EcmFnX09wZXJhdGlvbnMjZHJhZ3N0YXJ0XG5mdW5jdGlvbiBEcmFnRHJvcCRnZXRBbGxvd2VkRWZmZWN0cygpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhVHJhbnNmZXIuZWZmZWN0QWxsb3dlZDtcbn1cblxuXG5mdW5jdGlvbiBEcmFnRHJvcCRzZXRBbGxvd2VkRWZmZWN0cyhlZmZlY3RzKSB7XG4gICAgdGhpcy5kYXRhVHJhbnNmZXIuZWZmZWN0QWxsb3dlZCA9IGVmZmVjdHM7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3AkZ2V0RHJvcEVmZmVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdDtcbn1cblxuXG5mdW5jdGlvbiBEcmFnRHJvcCRzZXREcm9wRWZmZWN0KGVmZmVjdCkge1xuICAgIHRoaXMuZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSBlZmZlY3Q7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3AkaXNFZmZlY3RBbGxvd2VkKGVmZmVjdCkge1xuICAgIHZhciBhbGxvd2VkRWZmZWN0cyA9IHRoaXMuZ2V0QWxsb3dlZEVmZmVjdHMoKVxuICAgICAgICAsIGlzQ29weSA9IGVmZmVjdCA9PSAnY29weSdcbiAgICAgICAgLCBpc01vdmUgPSBlZmZlY3QgPT0gJ21vdmUnXG4gICAgICAgICwgaXNMaW5rID0gZWZmZWN0ID09ICdsaW5rJ1xuICAgICAgICAsIGlzQWxsb3dlZCA9IGlzQ29weSB8fCBpc0xpbmsgfHwgaXNNb3ZlO1xuXG4gICAgc3dpdGNoIChhbGxvd2VkRWZmZWN0cykge1xuICAgICAgICBjYXNlICdjb3B5JzpcbiAgICAgICAgY2FzZSAnbW92ZSc6XG4gICAgICAgIGNhc2UgJ2xpbmsnOlxuICAgICAgICAgICAgcmV0dXJuIGFsbG93ZWRFZmZlY3RzID09IGVmZmVjdDtcbiAgICAgICAgY2FzZSAnY29weUxpbmsnOlxuICAgICAgICAgICAgcmV0dXJuIGlzQ29weSB8fCBpc0xpbms7XG4gICAgICAgIGNhc2UgJ2NvcHlNb3ZlJzpcbiAgICAgICAgICAgIHJldHVybiBpc0NvcHkgfHwgaXNNb3ZlO1xuICAgICAgICBjYXNlICdsaW5rTW92ZSc6XG4gICAgICAgICAgICByZXR1cm4gaXNMaW5rIHx8IGlzTW92ZTtcbiAgICAgICAgY2FzZSAnYWxsJzpcbiAgICAgICAgY2FzZSAndW5pbml0aWFsaXplZCc6XG4gICAgICAgICAgICByZXR1cm4gaXNBbGxvd2VkO1xuICAgICAgICBjYXNlICdub25lJzpcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3AkZ2V0RGF0YShkYXRhVHlwZSkge1xuICAgIHJldHVybiB0aGlzLmRhdGFUcmFuc2Zlci5nZXREYXRhKGRhdGFUeXBlKTtcbn1cblxuXG5mdW5jdGlvbiBEcmFnRHJvcCRzZXREYXRhKGRhdGFUeXBlLCBkYXRhU3RyKSB7XG4gICAgdGhpcy5kYXRhVHJhbnNmZXIuc2V0RGF0YShkYXRhVHlwZSwgZGF0YVN0cik7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3AkY2xlYXJEYXRhKGRhdGFUeXBlKSB7XG4gICAgdGhpcy5kYXRhVHJhbnNmZXIuY2xlYXJEYXRhKGRhdGFUeXBlKTtcbn1cblxuXG4vKipcbiAqIERyYWcgZHJvcCBzZXJ2aWNlIGNvbXBlbnNhdGluZyBmb3IgdGhlIGxhY2sgb2YgY29tbXVuaWNhdGlvbiBmcm9tIGRyb3AgdGFyZ2V0IHRvIGRyYWcgc291cmNlIGluIERPTSBBUElcbiAqL1xudmFyIGRyYWdEcm9wU2VydmljZSA9IG5ldyBNZXNzZW5nZXI7XG5cbnZhciBfY3VycmVudERyYWdEcm9wLCBfY3VycmVudERyYWdGYWNldDtcblxuXy5leHRlbmQoRHJhZ0Ryb3AsIHtcbiAgICBzZXJ2aWNlOiBkcmFnRHJvcFNlcnZpY2UsXG4gICAgZGVzdHJveTogRHJhZ0Ryb3BfZGVzdHJveVxufSk7XG5cblxuZHJhZ0Ryb3BTZXJ2aWNlLm9uTWVzc2FnZXMoe1xuICAgIC8vIGRhdGEgaXMgRHJhZ0Ryb3BEYXRhVHJhbnNmZXIgaW5zdGFuY2VcbiAgICAvLyBmaXJlZCBieSBEcmFnIGZhY2V0IG9uIFwiZHJhZ3N0YXJ0XCIgZXZlbnRcbiAgICAnZHJhZ2Ryb3BzdGFydGVkJzogb25EcmFnRHJvcFN0YXJ0ZWQsIFxuICAgIC8vIGRhdGEgaXMgb2JqZWN0IHdpdGggYXQgbGVhc3QgZHJvcEVmZmVjdCBwcm9wZXJ0eVxuICAgIC8vIGZpcmVkIGJ5IERyb3AgZmFjZXQgb24gXCJkcm9wXCIgZXZlbnRcbiAgICAnZHJhZ2Ryb3Bjb21wbGV0ZWQnOiBvbkRyYWdEcm9wQ29tcGxldGVkLCBcbiAgICAvLyBmaXJlZCBieSBEcmFnIGZhY2V0IG9uIFwiZHJhZ2VuZFwiIGV2ZW50IHRvIGNvbXBsZXRlIGRyYWdcbiAgICAvLyBpZiBkcm9wIGhhcHBlbmRlZCBpbiBhbm90aGVyIHdpbmRvdyBvciBpZiBpdCB3YXMgY2FuY2VsbGVkXG4gICAgJ2NvbXBsZXRlZHJhZ2Ryb3AnOiBvbkNvbXBsZXRlRHJhZ0Ryb3Bcbn0pO1xuXG5cbl8uZXh0ZW5kKGRyYWdEcm9wU2VydmljZSwge1xuICAgIGdldEN1cnJlbnREcmFnRHJvcDogZ2V0Q3VycmVudERyYWdEcm9wXG59KTtcblxuXG5mdW5jdGlvbiBvbkRyYWdEcm9wU3RhcnRlZChtc2csIGRhdGEpIHtcbiAgICBfY3VycmVudERyYWdEcm9wID0gZGF0YS5kcmFnRHJvcDtcbiAgICBfY3VycmVudERyYWdGYWNldCA9IGRhdGEuZHJhZ0ZhY2V0O1xufVxuXG5cbmZ1bmN0aW9uIG9uRHJhZ0Ryb3BDb21wbGV0ZWQobXNnLCBkYXRhKSB7XG4gICAgX2N1cnJlbnREcmFnRmFjZXQgJiYgX2N1cnJlbnREcmFnRmFjZXQucG9zdE1lc3NhZ2VTeW5jKCdkcmFnZHJvcGNvbXBsZXRlZCcsIGRhdGEpO1xuICAgIF9jdXJyZW50RHJhZ0Ryb3AgPSB1bmRlZmluZWQ7XG4gICAgX2N1cnJlbnREcmFnRmFjZXQgPSB1bmRlZmluZWQ7XG59XG5cblxuZnVuY3Rpb24gb25Db21wbGV0ZURyYWdEcm9wKG1zZywgZGF0YSkge1xuICAgIGlmIChfY3VycmVudERyYWdEcm9wKVxuICAgICAgICBkcmFnRHJvcFNlcnZpY2UucG9zdE1lc3NhZ2VTeW5jKCdkcmFnZHJvcGNvbXBsZXRlZCcsIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIGdldEN1cnJlbnREcmFnRHJvcCgpIHtcbiAgICByZXR1cm4gX2N1cnJlbnREcmFnRHJvcDtcbn1cblxuXG5mdW5jdGlvbiBEcmFnRHJvcF9kZXN0cm95KCkge1xuICAgIGRyYWdEcm9wU2VydmljZS5vZmZBbGwoKTtcbn1cbiIsIi8vIDxhIG5hbWU9XCJ1dGlscy1lcnJvclwiPjwvYT5cbi8vIG1pbG8udXRpbHMuZXJyb3Jcbi8vIC0tLS0tLS0tLS0tXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vLyBtb2R1bGUgZXhwb3J0cyBlcnJvciBjbGFzc2VzIGZvciBhbGwgbmFtZXMgZGVmaW5lZCBpbiB0aGlzIGFycmF5XG52YXIgZXJyb3JDbGFzc05hbWVzID0gWydBYnN0cmFjdENsYXNzJywgJ01peGluJywgJ01lc3NlbmdlcicsICdDb21wb25lbnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAnQXR0cmlidXRlJywgJ0JpbmRlcicsICdMb2FkZXInLCAnTWFpbE1lc3NhZ2VTb3VyY2UnLCAnRmFjZXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAnU2NvcGUnLCAnTW9kZWwnLCAnRG9tRmFjZXQnLCAnRWRpdGFibGVGYWNldCcsXG4gICAgICAgICAgICAgICAgICAgICAgICdMaXN0JywgJ0Nvbm5lY3RvcicsICdSZWdpc3RyeScsICdGcmFtZU1lc3NhZ2VTb3VyY2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAnRHJvcCcsICdBbmd1bGFyJywgJ1N0b3JhZ2VNZXNzYWdlU291cmNlJ107XG5cbnZhciBlcnJvciA9IHtcbiAgICB0b0JlSW1wbGVtZW50ZWQ6IGVycm9yJHRvQmVJbXBsZW1lbnRlZCxcbiAgICBjcmVhdGVDbGFzczogZXJyb3IkY3JlYXRlQ2xhc3Ncbn07XG5cbmVycm9yQ2xhc3NOYW1lcy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBlcnJvcltuYW1lXSA9IGVycm9yJGNyZWF0ZUNsYXNzKG5hbWUgKyAnRXJyb3InKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGVycm9yO1xuXG5cbmZ1bmN0aW9uIGVycm9yJGNyZWF0ZUNsYXNzKGVycm9yQ2xhc3NOYW1lKSB7XG4gICAgdmFyIEVycm9yQ2xhc3MgPSBfLm1ha2VGdW5jdGlvbihlcnJvckNsYXNzTmFtZSwgJ21lc3NhZ2UnLFxuICAgICAgICAgICAgJ3RoaXMubmFtZSA9IFwiJyArIGVycm9yQ2xhc3NOYW1lICsgJ1wiOyBcXFxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCBcIlRoZXJlIHdhcyBhbiAgZXJyb3JcIjsnKTtcbiAgICBfLm1ha2VTdWJjbGFzcyhFcnJvckNsYXNzLCBFcnJvcik7XG5cbiAgICByZXR1cm4gRXJyb3JDbGFzcztcbn1cblxuXG5mdW5jdGlvbiBlcnJvciR0b0JlSW1wbGVtZW50ZWQoKSB7XG4gICAgdGhyb3cgbmV3IGVycm9yLkFic3RyYWN0Q2xhc3MoJ2NhbGxpbmcgdGhlIG1ldGhvZCBvZiBhbiBhYnNjdHJhY3QgY2xhc3MnKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY29tcG9uZW50cy9jX2NsYXNzJylcbiAgICAsIEJpbmRBdHRyaWJ1dGUgPSByZXF1aXJlKCcuLi9hdHRyaWJ1dGVzL2FfYmluZCcpXG4gICAgLCBiaW5kZXIgPSByZXF1aXJlKCcuLi9iaW5kZXInKVxuICAgICwgZG9tVXRpbHMgPSByZXF1aXJlKCcuL2RvbScpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuL2xvZ2dlcicpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4vY2hlY2snKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBjcmVhdGVSYW5nZVBhdGhzID0gX2NyZWF0ZU5vZGVzQW5kUGF0aHNGdW5jKGRvbVV0aWxzLnRyZWVQYXRoT2YpO1xudmFyIGNyZWF0ZVJhbmdlTm9kZXMgPSBfY3JlYXRlTm9kZXNBbmRQYXRoc0Z1bmMoZG9tVXRpbHMuZ2V0Tm9kZUF0VHJlZVBhdGgpO1xuXG5cbnZhciBmcmFnbWVudFV0aWxzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZ2V0U3RhdGU6IGZyYWdtZW50X2dldFN0YXRlLFxuICAgIGdldFN0YXRlQXN5bmM6IGZyYWdtZW50X2dldFN0YXRlQXN5bmMsXG5cbiAgICBleHBhbmRSYW5nZVRvU2libGluZ3M6IGV4cGFuZFJhbmdlVG9TaWJsaW5ncyxcbiAgICBnZXRSYW5nZVNpYmxpbmdzOiBnZXRSYW5nZVNpYmxpbmdzLFxuICAgIGNyZWF0ZVJhbmdlRnJvbVNpYmxpbmdzOiBjcmVhdGVSYW5nZUZyb21TaWJsaW5ncyxcbiAgICBjcmVhdGVSYW5nZUZyb21Ob2RlczogY3JlYXRlUmFuZ2VGcm9tU2libGluZ3MsIC8vIGFsaWFzXG4gICAgY3JlYXRlUmFuZ2VQYXRoczogY3JlYXRlUmFuZ2VQYXRocyxcbiAgICBjcmVhdGVSYW5nZU5vZGVzOiBjcmVhdGVSYW5nZU5vZGVzXG59O1xuXG5cbi8qKlxuICogQ3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0aGUgc3RhdGUgb2Ygd3JhcHBlZCByYW5nZSB3aXRoIGNvbXBvbmVudHMsIGluY2x1ZGluZyBwYXJ0aWFsbHkgc2VsZWN0ZWQuIFRoZSByYW5nZSB3aWxsIGJlIGNsb25lZCBhbmQgd3JhcHBlZCBpbiBjb21wb25lbnQgd2l0aCBjb250YWluZXIgZmFjZXQgYmVmb3JlIGdldHRpbmcgaXRzIHN0YXRlLlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGxvZyBlcnJvciBhbmQgcmV0dXJuIHVuZGVmaW5lZCBpZiByYW5nZSBoYXMgbm8gY29tbW9uIGFuY2VzdG9yIHRoYXQgaGFzIGNvbXBvbmVudCB3aXRoIGNvbnRhaW5lciBmYWNldFxuICogXG4gKiBAcGFyYW0ge1JhbmdlfSByYW5nZSBET00gUmFuZ2UgaW5zdGFuY2VcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVuYW1lQ2hpbGRyZW4gb3B0aW9uYWwgcGFyYW1ldGVyLCBgdHJ1ZWAgdG8gcmVuYW1lIGZyYWdtZW50IGNoaWxkIGNvbXBvbmVudHNcbiAqIEBwYXJhbSB7U3RyaW5nfSB3cmFwcGVyQ2xhc3NOYW1lIG9wdGlvbmFsIHBhcmFtZXRlciB0byB3cmFwIGluIGEgY3VzdG9tIGNvbXBvbmVudCBjbGFzc1xuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBmcmFnbWVudF9nZXRTdGF0ZShyYW5nZSwgcmVuYW1lQ2hpbGRyZW4sIHdyYXBwZXJDbGFzc05hbWUpIHtcbiAgICB2YXIgcmFuZ2VDb250YWluZXIgPSBfZ2V0UmFuZ2VDb250YWluZXIocmFuZ2UpO1xuICAgIGlmICghIHJhbmdlQ29udGFpbmVyKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcignZnJhZ21lbnQuZ2V0U3RhdGU6IHJhbmdlIGhhcyBubyBjb21tb24gY29udGFpbmVyJyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZnJhZyA9IHJhbmdlLmNsb25lQ29udGVudHMoKVxuICAgICAgICAsIHdyYXBwZXIgPSBfd3JhcEZyYWdtZW50SW5Db250YWluZXIoZnJhZywgd3JhcHBlckNsYXNzTmFtZSk7XG5cbiAgICBfdHJhbnNmZXJTdGF0ZXMocmFuZ2VDb250YWluZXIsIHdyYXBwZXIpO1xuICAgIGlmIChyZW5hbWVDaGlsZHJlbikgX3JlbmFtZUNoaWxkcmVuKHdyYXBwZXIpO1xuICAgIHZhciB3cmFwcGVyU3RhdGUgPSB3cmFwcGVyLmdldFN0YXRlKCk7XG4gICAgXy5kZWZlck1ldGhvZCh3cmFwcGVyLCAnZGVzdHJveScpO1xuICAgIHJldHVybiB3cmFwcGVyU3RhdGU7XG59XG5cblxuLyoqXG4gKiBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIHRoZSBzdGF0ZSBvZiB3cmFwcGVkIHJhbmdlIHdpdGggY29tcG9uZW50cywgaW5jbHVkaW5nIHBhcnRpYWxseSBzZWxlY3RlZC4gVGhlIHJhbmdlIHdpbGwgYmUgY2xvbmVkIGFuZCB3cmFwcGVkIGluIGNvbXBvbmVudCB3aXRoIGNvbnRhaW5lciBmYWNldCBiZWZvcmUgZ2V0dGluZyBpdHMgc3RhdGUuXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHJlc3VsdCBhbmQgYW55IGVycm9yIHZpYSBjYWxsYmFjay5cbiAqIFxuICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgRE9NIFJhbmdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJlbmFtZUNoaWxkcmVuIG9wdGlvbmFsIHBhcmFtZXRlciwgYHRydWVgIHRvIHJlbmFtZSBmcmFnbWVudCBjaGlsZCBjb21wb25lbnRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBhbHdheXMgdGhlIGxhc3QgcGFyYW1ldGVyLCBvcHRpb25hbCBwYXJhbWV0ZXJzIGNhbiBiZSBkcm9wcGVkOyByZXN1bHQgaXMgcGFzc2VkIHZpYSBjYWxsYmFjayB3aXRoIGFueSBlcnJvciBhcyBmaXJzdCBwYXJhbWV0ZXJcbiAqL1xuZnVuY3Rpb24gZnJhZ21lbnRfZ2V0U3RhdGVBc3luYyhyYW5nZSwgcmVuYW1lQ2hpbGRyZW4sIGNhbGxiYWNrKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgdmFyIHJhbmdlQ29udGFpbmVyID0gX2dldFJhbmdlQ29udGFpbmVyKHJhbmdlKTtcbiAgICAgICAgaWYgKCEgcmFuZ2VDb250YWluZXIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBFcnJvcignZnJhZ21lbnQuZ2V0U3RhdGU6IHJhbmdlIGhhcyBubyBjb21tb24gY29udGFpbmVyJykpO1xuICAgICAgICAgICAgcmV0dXJuOyAvLyBkbyBOT1QgY29ubmVjdCByZXR1cm4gdG8gcHJldmlvdXMgY2FsbGJhY2ssIGdldFN0YXRlIHNob3VsZCByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHJlbmFtZUNoaWxkcmVuID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gcmVuYW1lQ2hpbGRyZW47XG4gICAgICAgICAgICByZW5hbWVDaGlsZHJlbiA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZyYWcgPSByYW5nZS5jbG9uZUNvbnRlbnRzKClcbiAgICAgICAgICAgICwgd3JhcHBlciA9IF93cmFwRnJhZ21lbnRJbkNvbnRhaW5lcihmcmFnKTtcblxuICAgICAgICBfdHJhbnNmZXJTdGF0ZXMocmFuZ2VDb250YWluZXIsIHdyYXBwZXIpO1xuICAgICAgICBfLmRlZmVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgd3JhcHBlci5icm9hZGNhc3QoJ3N0YXRlcmVhZHknKTtcbiAgICAgICAgICAgIF8uZGVmZXIoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmFtZUNoaWxkcmVuKSBfcmVuYW1lQ2hpbGRyZW4od3JhcHBlcik7XG4gICAgICAgICAgICAgICAgdmFyIHdyYXBwZXJTdGF0ZSA9IHdyYXBwZXIuZ2V0U3RhdGUoKTtcbiAgICAgICAgICAgICAgICB3cmFwcGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCB3cmFwcGVyU3RhdGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBfd3JhcEZyYWdtZW50SW5Db250YWluZXIoZnJhZywgd3JhcHBlckNsYXNzTmFtZSkge1xuICAgIHZhciB3cmFwRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAgICAsIGF0dHIgPSBuZXcgQmluZEF0dHJpYnV0ZSh3cmFwRWwpO1xuXG4gICAgXy5leHRlbmQoYXR0ciwge1xuICAgICAgICBjb21wQ2xhc3M6IHdyYXBwZXJDbGFzc05hbWUgfHwgJ0NvbXBvbmVudCcsXG4gICAgICAgIGNvbXBGYWNldHM6IHdyYXBwZXJDbGFzc05hbWUgPyBbXSA6IFsnY29udGFpbmVyJ10sXG4gICAgICAgIGNvbXBOYW1lOiAnd3JhcHBlcidcbiAgICB9KTtcblxuICAgIGF0dHIuZGVjb3JhdGUoKTtcblxuICAgIHdyYXBFbC5hcHBlbmRDaGlsZChmcmFnKTtcbiAgICB2YXIgc2NvcGUgPSBiaW5kZXIod3JhcEVsKTtcbiAgICByZXR1cm4gc2NvcGUud3JhcHBlcjtcbn1cblxuXG5mdW5jdGlvbiBfZ2V0UmFuZ2VDb250YWluZXIocmFuZ2UpIHtcbiAgICB2YXIgZWwgPSBkb21VdGlscy5jb250YWluaW5nRWxlbWVudChyYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lcik7XG4gICAgcmV0dXJuIENvbXBvbmVudC5nZXRDb250YWluaW5nQ29tcG9uZW50KGVsLCB0cnVlLCAnY29udGFpbmVyJyk7XG59XG5cblxuZnVuY3Rpb24gX3RyYW5zZmVyU3RhdGVzKGZyb21Db21wLCB0b0NvbXApIHtcbiAgICB2YXIgZnJvbVNjb3BlID0gZnJvbUNvbXAuY29udGFpbmVyLnNjb3BlO1xuICAgIHRvQ29tcC5jb250YWluZXIuc2NvcGUuX2VhY2goZnVuY3Rpb24odG9DaGlsZENvbXAsIG5hbWUpIHtcbiAgICAgICAgdmFyIGZyb21DaGlsZENvbXAgPSBmcm9tU2NvcGVbbmFtZV07XG4gICAgICAgIGlmICghIGZyb21DaGlsZENvbXApIHJldHVybiBsb2dnZXIuZXJyb3IoJ2ZyYWdtZW50LmdldFN0YXRlOiBjb25wb25lbnQnLCBuYW1lLCAnbm90IGZvdW5kIGluIHJhbmdlJyk7XG4gICAgICAgIHZhciBzdGF0ZSA9IGZyb21DaGlsZENvbXAuX2dldFN0YXRlKHRydWUpO1xuICAgICAgICB0b0NoaWxkQ29tcC5zZXRTdGF0ZShzdGF0ZSk7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gX3JlbmFtZUNoaWxkcmVuKGNvbXApIHtcbiAgICBjb21wLmNvbnRhaW5lci5zY29wZS5fZWFjaChmdW5jdGlvbihjaGlsZCkge1xuICAgICAgICBjaGlsZC5yZW5hbWUoKTtcbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBleHBhbmRSYW5nZVRvU2libGluZ3MocmFuZ2UpIHtcbiAgICB2YXIgc2libGluZ3MgPSBnZXRSYW5nZVNpYmxpbmdzKHJhbmdlKTtcbiAgICByYW5nZSA9IGNyZWF0ZVJhbmdlRnJvbVNpYmxpbmdzKHNpYmxpbmdzKTtcbiAgICByZXR1cm4gcmFuZ2U7XG59XG5cblxuZnVuY3Rpb24gY3JlYXRlUmFuZ2VGcm9tU2libGluZ3Mobm9kZXMpIHtcbiAgICB2YXIgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIGlmIChub2Rlcy5zaWJsaW5ncykge1xuICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShub2Rlcy5zdGFydCk7XG4gICAgICAgIHJhbmdlLnNldEVuZEFmdGVyKG5vZGVzLmVuZCk7XG4gICAgfSBlbHNlXG4gICAgICAgIHJhbmdlLnNlbGVjdE5vZGUobm9kZXMuc3RhcnQpO1xuICAgIHJldHVybiByYW5nZTtcbn1cblxuXG5mdW5jdGlvbiBnZXRSYW5nZVNpYmxpbmdzKHJhbmdlKSB7XG4gICAgdmFyIGNvbnRhaW5lck5vZGUgPSByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lclxuICAgICAgICAsIHN0YXJ0Tm9kZSA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgICAgICwgZW5kTm9kZSA9IHJhbmdlLmVuZENvbnRhaW5lcjtcblxuICAgIGlmIChzdGFydE5vZGUgPT0gZW5kTm9kZSkge1xuICAgICAgICBpZiAoc3RhcnROb2RlICE9IGNvbnRhaW5lck5vZGUpIGxvZ2dlci5lcnJvcignZGVsZXRlU2VsZWN0aW9uQ29tbWFuZCBsb2dpY2FsIGVycm9yOiBzdGFydD09ZW5kLCBidXQgY29udGFpbmVyIGlzIGRpZmZlcmVudCcpO1xuICAgICAgICByZXR1cm4geyBzaWJsaW5nczogZmFsc2UsIHN0YXJ0OiBzdGFydE5vZGUgfTtcbiAgICB9XG5cbiAgICBpZiAoc3RhcnROb2RlID09IGNvbnRhaW5lck5vZGUgfHwgZW5kTm9kZSA9PSBjb250YWluZXJOb2RlKVxuICAgICAgICByZXR1cm4geyBzaWJsaW5nczogZmFsc2UsIHN0YXJ0OiBjb250YWluZXJOb2RlIH07XG5cbiAgICB2YXIgc3RhcnRTaWJsaW5nID0gX2ZpbmRDb250YWluaW5nQ2hpbGQoY29udGFpbmVyTm9kZSwgc3RhcnROb2RlKTtcbiAgICB2YXIgZW5kU2libGluZyA9IF9maW5kQ29udGFpbmluZ0NoaWxkKGNvbnRhaW5lck5vZGUsIGVuZE5vZGUpO1xuXG4gICAgaWYgKHN0YXJ0U2libGluZyAmJiBlbmRTaWJsaW5nKSB7XG4gICAgICAgIGlmIChzdGFydFNpYmxpbmcgPT0gZW5kU2libGluZykge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdkZWxldGVTZWxlY3Rpb25Db21tYW5kIGxvZ2ljYWwgZXJyb3I6IHNhbWUgc2libGluZ3MnKTtcbiAgICAgICAgICAgIHJldHVybiB7IHNpYmxpbmdzOiBmYWxzZSwgc3RhcnQ6IHN0YXJ0U2libGluZyB9O1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgIHJldHVybiB7IHNpYmxpbmdzOiB0cnVlLCBzdGFydDogc3RhcnRTaWJsaW5nLCBlbmQ6IGVuZFNpYmxpbmcgfTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gX2ZpbmRDb250YWluaW5nQ2hpbGQoY29udGFpbmVyTm9kZSwgc2VsTm9kZSkge1xuICAgIHJldHVybiBfLmZpbmQoY29udGFpbmVyTm9kZS5jaGlsZE5vZGVzLCBmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHJldHVybiBub2RlLmNvbnRhaW5zKHNlbE5vZGUpO1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9jcmVhdGVOb2Rlc0FuZFBhdGhzRnVuYyhmdW5jKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHJvb3RFbCwgZnJvbU9iaikge1xuICAgICAgICB2YXIgdG9PYmogPSB7XG4gICAgICAgICAgICBzaWJsaW5nczogZnJvbU9iai5zaWJsaW5ncyxcbiAgICAgICAgICAgIHN0YXJ0OiBmdW5jKHJvb3RFbCwgZnJvbU9iai5zdGFydClcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRvT2JqLnNpYmxpbmdzKVxuICAgICAgICAgICAgdG9PYmouZW5kID0gZnVuYyhyb290RWwsIGZyb21PYmouZW5kKTtcbiAgICAgICAgcmV0dXJuIHRvT2JqO1xuICAgIH07XG59XG5cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBtaWxvLnV0aWxgXG4gKi9cbnZhciB1dGlsID0ge1xuICAgIGxvZ2dlcjogcmVxdWlyZSgnLi9sb2dnZXInKSxcbiAgICByZXF1ZXN0OiByZXF1aXJlKCcuL3JlcXVlc3QnKSxcbiAgICB3ZWJzb2NrZXQ6IHJlcXVpcmUoJy4vd2Vic29ja2V0JyksXG4gICAgY2hlY2s6IHJlcXVpcmUoJy4vY2hlY2snKSxcbiAgICBlcnJvcjogcmVxdWlyZSgnLi9lcnJvcicpLFxuICAgIGNvdW50OiByZXF1aXJlKCcuL2NvdW50JyksIC8vIGRlcHJlY2F0ZWRcbiAgICB1bmlxdWVJZDogcmVxdWlyZSgnLi9jb3VudCcpLFxuICAgIGNvbXBvbmVudE5hbWU6IHJlcXVpcmUoJy4vY29tcG9uZW50X25hbWUnKSxcbiAgICBkb206IHJlcXVpcmUoJy4vZG9tJyksXG4gICAgZG9tTGlzdGVuZXJzOiByZXF1aXJlKCcuL2RvbV9saXN0ZW5lcnMnKSxcbiAgICBzZWxlY3Rpb246IHJlcXVpcmUoJy4vc2VsZWN0aW9uJyksXG4gICAgZnJhZ21lbnQ6IHJlcXVpcmUoJy4vZnJhZ21lbnQnKSxcbiAgICBqc29uUGFyc2U6IHJlcXVpcmUoJy4vanNvbl9wYXJzZScpLFxuICAgIHN0b3JhZ2U6IHJlcXVpcmUoJy4vc3RvcmFnZScpLFxuICAgIGRvbVJlYWR5OiByZXF1aXJlKCcuL2RvbXJlYWR5JyksXG4gICAgZHJhZ0Ryb3A6IHJlcXVpcmUoJy4vZHJhZ2Ryb3AnKSxcbiAgICBkaWFsb2c6IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvdWkvYm9vdHN0cmFwL0RpYWxvZycpLFxuICAgIGFsZXJ0OiByZXF1aXJlKCcuLi9jb21wb25lbnRzL3VpL2Jvb3RzdHJhcC9BbGVydCcpLFxuICAgIGRvVDogcmVxdWlyZSgnZG90JyksXG4gICAgZGVzdHJveTogdXRpbF9kZXN0cm95XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHV0aWw7XG5cblxuZnVuY3Rpb24gdXRpbF9kZXN0cm95KCkge1xuICAgIHV0aWwucmVxdWVzdC5kZXN0cm95KCk7XG4gICAgdXRpbC5kcmFnRHJvcC5kZXN0cm95KCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBqc29uUGFyc2U7XG5cblxuLyoqXG4gKiBgbWlsby51dGlsLmpzb25QYXJzZWBcbiAqIFNhZmUgSlNPTi5wYXJzZSwgcmV0dXJucyB1bmRlZmluZWQgaWYgSlNPTi5wYXJzZSB0aHJvd3MgYW4gZXhjZXB0aW9uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0ciAtIEpTT04gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIG9iamVjdFxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24ganNvblBhcnNlKHN0cikge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHN0cik7XG4gICAgfSBjYXRjaCAoZSkge31cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gPGEgbmFtZT1cInV0aWxzLWxvZ2dlclwiPjwvYT5cbi8vIG1pbG8udXRpbHMubG9nZ2VyXG4vLyAtLS0tLS0tLS0tLVxuXG4vLyBBcHBsaWNhdGlvbiBsb2dnZXIgdGhhdCBoYXMgZXJyb3IsIHdhcm4sIGluZm8gYW5kIGRlYnVnXG4vLyBtZXRob2RzLCB0aGF0IGNhbiBiZSBzdXBwcmVzc2VkIGJ5IHNldHRpbmcgbG9nIGxldmVsLlxuXG4vLyBQcm9wZXJ0aWVzOlxuXG4vLyAtIGxldmVsXG5cbi8vICAgLSAwIC0gZXJyb3Jcbi8vICAgLSAxIC0gd2FyblxuLy8gICAtIDIgLSBpbmZvXG4vLyAgIC0gMyAtIGRlYnVnIChkZWZhdWx0KVxuXG4vLyAtIGVuYWJsZWRcblxuLy8gICB0cnVlIGJ5IGRlZmF1bHQuIFNldCB0byBmYWxzZSB0byBkaXNhYmxlIGFsbCBsb2dnaW5nIGluIGJyb3dzZXIgY29uc29sZS5cblxuXG52YXIgTG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXJfY2xhc3MnKTtcblxudmFyIGxvZ2dlciA9IG5ldyBMb2dnZXIoeyBsZXZlbDogMyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2dnZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vICMjIyBMb2dnZXIgQ2xhc3NcblxuLy8gUHJvcGVydGllczpcblxuLy8gLSBsZXZlbFxuXG4vLyAgIC0gMCAtIGVycm9yXG4vLyAgIC0gMSAtIHdhcm5cbi8vICAgLSAyIC0gaW5mb1xuLy8gICAtIDMgLSBkZWJ1ZyAoZGVmYXVsdClcblxuLy8gLSBlbmFibGVkXG5cbi8vICAgdHJ1ZSBieSBkZWZhdWx0LiBTZXQgdG8gZmFsc2UgdG8gZGlzYWJsZSBhbGwgbG9nZ2luZyBpbiBicm93c2VyIGNvbnNvbGUuXG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIExvZyBsZXZlbHMuXG4gKi9cblxudmFyIGxldmVscyA9IFtcbiAgICAnZXJyb3InLFxuICAgICd3YXJuJyxcbiAgICAnaW5mbycsXG4gICAgJ2RlYnVnJ1xuXTtcblxudmFyIG1heExldmVsTGVuZ3RoID0gTWF0aC5tYXguYXBwbHkoTWF0aCwgbGV2ZWxzLm1hcChmdW5jdGlvbihsZXZlbCkgeyByZXR1cm4gbGV2ZWwubGVuZ3RoOyB9KSk7XG5cbi8qKlxuICogQ29sb3JzIGZvciBsb2cgbGV2ZWxzLlxuICovXG5cbnZhciBjb2xvcnMgPSBbXG4gICAgMzEsXG4gICAgMzMsXG4gICAgMzYsXG4gICAgOTBcbl07XG5cbi8qKlxuICogUGFkcyB0aGUgbmljZSBvdXRwdXQgdG8gdGhlIGxvbmdlc3QgbG9nIGxldmVsLlxuICovXG5mdW5jdGlvbiBwYWQoc3RyKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggPCBtYXhMZXZlbExlbmd0aClcbiAgICAgICAgcmV0dXJuIHN0ciArIG5ldyBBcnJheShtYXhMZXZlbExlbmd0aCAtIHN0ci5sZW5ndGggKyAxKS5qb2luKCcgJyk7XG5cbiAgICByZXR1cm4gc3RyO1xufTtcblxuXG5mdW5jdGlvbiBjb2xvcmVkKHN0ciwgY29sb3IpIHtcbiAgICByZXR1cm4gJ1xceDFCWycgKyBjb2xvciArICdtJyArIHN0ciArICcgLVxceDFCWzM5bSc7XG59XG5cblxudmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBsZXZlbDogMyxcbiAgICB0aHJvd0xldmVsOiAtMSwgLy8gbmV2ZXIgdGhyb3dcbiAgICBlbmFibGVkOiB0cnVlLFxuICAgIGxvZ1ByZWZpeDogJydcbn1cblxuXG4vKipcbiAqIExvZ2dlciAoY29uc29sZSkuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xudmFyIExvZ2dlciA9IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgXy5leHRlbmQodGhpcywgREVGQVVMVF9PUFRJT05TKTtcbiAgICBfLmV4dGVuZCh0aGlzLCBvcHRzIHx8IHt9KTtcbn07XG5cblxuLyoqXG4gKiBMb2cgbWV0aG9kLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTG9nZ2VyLnByb3RvdHlwZS5sb2cgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgIHZhciBpbmRleCA9IGxldmVscy5pbmRleE9mKHR5cGUpO1xuXG4gICAgaWYgKCEgdGhpcy5lbmFibGVkIHx8IGluZGV4ID4gdGhpcy5sZXZlbClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICB2YXIgYXJncyA9IF8uc2xpY2UoYXJndW1lbnRzLCAxKTtcblxuICAgIGlmIChpbmRleCA8PSB0aGlzLnRocm93TGV2ZWwpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihbdGhpcy5sb2dQcmVmaXgsIHR5cGUgKyAnOiddLmNvbmNhdChhcmdzKS5qb2luKCcgJykpO1xuXG4gICAgY29uc29sZS5sb2cuYXBwbHkoXG4gICAgICAgICAgY29uc29sZVxuICAgICAgICAsIFsgdGhpcy5sb2dQcmVmaXhDb2xvclxuICAgICAgICAgICAgICA/ICcgICAnICsgY29sb3JlZCh0aGlzLmxvZ1ByZWZpeCwgdGhpcy5sb2dQcmVmaXhDb2xvcilcbiAgICAgICAgICAgICAgOiB0aGlzLmxvZ1ByZWZpeCxcbiAgICAgICAgICAgICh0aGlzLmNvbG9yc1xuICAgICAgICAgICAgICA/ICcgJyArIGNvbG9yZWQocGFkKHR5cGUpLCBjb2xvcnNbaW5kZXhdKVxuICAgICAgICAgICAgICA6IHR5cGUpICsgJzonXG4gICAgICAgICAgXS5jb25jYXQoYXJncylcbiAgICApO1xuXG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIG1ldGhvZHMuXG4gKi9cblxubGV2ZWxzLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBMb2dnZXIucHJvdG90eXBlW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmxvZy5hcHBseSh0aGlzLCBbbmFtZV0uY29uY2F0KF8udG9BcnJheShhcmd1bWVudHMpKSk7XG4gICAgfTtcbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTG9nZ2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBtaWxvLnV0aWxzLnJlcXVlc3Rcbi8vIC0tLS0tLS0tLS0tXG5cbi8vIENvbnZlbmllbmNlIGZ1bmN0aW9ucyB3cmFwcGluZyBYTUxIVFRQUmVxdWVzdCBmdW5jdGlvbmFsaXR5LlxuXG4vLyBgYGBcbi8vIHZhciByZXF1ZXN0ID0gbWlsby51dGlscy5yZXF1ZXN0XG4vLyAgICAgLCBvcHRzOiB7IG1ldGhvZDogJ0dFVCcgfTtcblxuLy8gcmVxdWVzdCh1cmwsIG9wdHMsIGZ1bmN0aW9uKGVyciwgZGF0YSkge1xuLy8gICAgIGxvZ2dlci5kZWJ1ZyhkYXRhKTtcbi8vIH0pO1xuXG4vLyByZXF1ZXN0LmdldCh1cmwsIGZ1bmN0aW9uKGVyciwgZGF0YSkge1xuLy8gICAgIGxvZ2dlci5kZWJ1ZyhkYXRhKTtcbi8vIH0pO1xuLy8gYGBgXG5cbi8vIE9ubHkgZ2VuZXJpYyByZXF1ZXN0IGFuZCBnZXQsIGpzb24sIHBvc3QgY29udmVuaWVuY2UgbWV0aG9kcyBhcmUgY3VycmVudGx5IGltcGxlbWVudGVkLlxuXG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNvdW50ID0gcmVxdWlyZSgnLi9jb3VudCcpXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXInKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWVzdDtcblxuXG52YXIgX3BlbmRpbmdSZXF1ZXN0cyA9IFtdO1xuXG52YXIgcHJvbWlzZVRoZW4gPSBjcmVhdGVQcm9taXNlT3ZlcnJpZGUoJ3RoZW4nKTtcbnZhciBwcm9taXNlQ2F0Y2ggPSBjcmVhdGVQcm9taXNlT3ZlcnJpZGUoJ2NhdGNoJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHdoaWNoIGlzIHVzZWQgdG8gb3ZlcnJpZGUgc3RhbmRhcmQgcHJvbWlzZSBiZWhhdmlvdXIgYW5kIGFsbG93IHByb21pc2UgaW5zdGFuY2VzIFxuICogY3JlYXRlZCB0byBtYWludGFpbiBhIHJlZmVyZW5jZSB0byB0aGUgcmVxdWVzdCBvYmplY3Qgbm8gbWF0dGVyIGlmIC50aGVuKCkgb3IgLmNhdGNoKCkgaXMgY2FsbGVkLlxuICovXG5mdW5jdGlvbiBjcmVhdGVQcm9taXNlT3ZlcnJpZGUoZnVuY3Rpb25OYW1lKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IFByb21pc2UucHJvdG90eXBlW2Z1bmN0aW9uTmFtZV0uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAga2VlcFJlcXVlc3RPYmplY3QocHJvbWlzZSwgdGhpcy5fcmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiByZXF1ZXN0KHVybCwgb3B0cywgY2FsbGJhY2spIHtcbiAgICBvcHRzLnVybCA9IHVybDtcbiAgICBvcHRzLmNvbnRlbnRUeXBlID0gb3B0cy5jb250ZW50VHlwZSB8fCAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PVVURi04JztcbiAgICBpZiAoX21lc3NlbmdlcikgcmVxdWVzdC5wb3N0TWVzc2FnZVN5bmMoJ3JlcXVlc3QnLCB7IG9wdGlvbnM6IG9wdHMgfSk7XG5cbiAgICB2YXIgcmVxID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgcmVxLm9wZW4ob3B0cy5tZXRob2QsIG9wdHMudXJsLCB0cnVlKTtcbiAgICByZXEuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgb3B0cy5jb250ZW50VHlwZSk7XG4gICAgc2V0UmVxdWVzdEhlYWRlcnMocmVxLCBvcHRzLmhlYWRlcnMpO1xuXG4gICAgcmVxLnRpbWVvdXQgPSBvcHRzLnRpbWVvdXQgfHwgY29uZmlnLnJlcXVlc3QuZGVmYXVsdHMudGltZW91dDtcbiAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlID0gcmVxLm9udGltZW91dCA9IHJlcS5vbmFib3J0ID0gb25SZWFkeTtcblxuICAgIHZhciB4UHJvbWlzZSA9IF9jcmVhdGVYUHJvbWlzZShyZXEpO1xuXG4gICAgcmVxLnNlbmQoSlNPTi5zdHJpbmdpZnkob3B0cy5kYXRhKSk7XG4gICAgcmVxW2NvbmZpZy5yZXF1ZXN0Lm9wdGlvbnNLZXldID0gb3B0cztcblxuICAgIF9wZW5kaW5nUmVxdWVzdHMucHVzaChyZXEpO1xuXG4gICAgcmV0dXJuIHhQcm9taXNlLnByb21pc2U7XG5cbiAgICBmdW5jdGlvbiBvblJlYWR5KGUpIHtcbiAgICAgICAgX29uUmVhZHkocmVxLCBjYWxsYmFjaywgeFByb21pc2UsIGUudHlwZSk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9jcmVhdGVYUHJvbWlzZShyZXF1ZXN0KSB7XG4gICAgdmFyIHJlc29sdmVQcm9taXNlLCByZWplY3RQcm9taXNlO1xuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgcmVqZWN0UHJvbWlzZSA9IHJlamVjdDtcbiAgICB9KTtcblxuICAgIGtlZXBSZXF1ZXN0T2JqZWN0KHByb21pc2UsIHJlcXVlc3QpO1xuICAgIHByb21pc2UuY2F0Y2goXy5ub29wKTsgLy8gU29tZXRpbWVzIGVycm9ycyBhcmUgaGFuZGxlZCB3aXRoaW4gY2FsbGJhY2tzLCBzbyB1bmNhdWdodCBwcm9taXNlIGVycm9yIG1lc3NhZ2Ugc2hvdWxkIGJlIHN1cHByZXNzZWQuXG5cbiAgICByZXR1cm4ge1xuICAgICAgICBwcm9taXNlOiBwcm9taXNlLFxuICAgICAgICByZXNvbHZlOiByZXNvbHZlUHJvbWlzZSxcbiAgICAgICAgcmVqZWN0OiByZWplY3RQcm9taXNlXG4gICAgfVxufVxuXG4vLyBFbnN1cmVzIHRoYXQgdGhlIHByb21pc2UgKGFuZCBhbnkgcHJvbWlzZXMgY3JlYXRlZCB3aGVuIGNhbGxpbmcgLnRoZW4vLmNhdGNoKSBoYXMgYSByZWZlcmVuY2UgdG8gdGhlIG9yaWdpbmFsIHJlcXVlc3Qgb2JqZWN0XG5mdW5jdGlvbiBrZWVwUmVxdWVzdE9iamVjdChwcm9taXNlLCByZXF1ZXN0KSB7XG4gICAgcHJvbWlzZS5fcmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgcHJvbWlzZS50aGVuID0gcHJvbWlzZVRoZW47XG4gICAgcHJvbWlzZS5jYXRjaCA9IHByb21pc2VDYXRjaDtcblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5cbmZ1bmN0aW9uIHNldFJlcXVlc3RIZWFkZXJzKHJlcSwgaGVhZGVycykge1xuICAgIGlmIChoZWFkZXJzKVxuICAgICAgICBfLmVhY2hLZXkoaGVhZGVycywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0pO1xufVxuXG5mdW5jdGlvbiBfb25SZWFkeShyZXEsIGNhbGxiYWNrLCB4UHJvbWlzZSwgZXZlbnRUeXBlKSB7XG4gICAgaWYgKHJlcS5yZWFkeVN0YXRlICE9IDQpIHJldHVybjtcbiAgICBpZiAoIXJlcS5zdGF0dXMgJiYgZXZlbnRUeXBlID09ICdyZWFkeXN0YXRlY2hhbmdlJykgcmV0dXJuO1xuXG4gICAgXy5zcGxpY2VJdGVtKF9wZW5kaW5nUmVxdWVzdHMsIHJlcSk7XG5cbiAgICB2YXIgZXJyb3I7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKCByZXEuc3RhdHVzID49IDIwMCAmJiByZXEuc3RhdHVzIDwgNDAwICkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSgnc3VjY2VzcycpO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKG51bGwsIHJlcS5yZXNwb25zZVRleHQsIHJlcSk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHsgZXJyb3IgPSBlOyB9XG4gICAgICAgICAgICB4UHJvbWlzZS5yZXNvbHZlKHJlcS5yZXNwb25zZVRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGVycm9yUmVhc29uID0gcmVxLnN0YXR1cyB8fCBldmVudFR5cGU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKCdlcnJvcicpO1xuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKCdlcnJvcicgKyBlcnJvclJlYXNvbik7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soZXJyb3JSZWFzb24sIHJlcS5yZXNwb25zZVRleHQsIHJlcSk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHsgZXJyb3IgPSBlOyB9XG4gICAgICAgICAgICB4UHJvbWlzZS5yZWplY3QoeyByZWFzb246IGVycm9yUmVhc29uLCByZXNwb25zZTogcmVxLnJlc3BvbnNlVGV4dCB9KTtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBlcnJvciA9IGVycm9yIHx8IGU7XG4gICAgfVxuXG4gICAgLy8gbm90IHJlbW92aW5nIHN1YnNjcmlwdGlvbiBjcmVhdGVzIG1lbW9yeSBsZWFrLCBkZWxldGluZyBwcm9wZXJ0eSB3b3VsZCBub3QgcmVtb3ZlIHN1YnNjcmlwdGlvblxuICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSByZXEub250aW1lb3V0ID0gcmVxLm9uYWJvcnQgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoIV9wZW5kaW5nUmVxdWVzdHMubGVuZ3RoKVxuICAgICAgICBwb3N0TWVzc2FnZSgncmVxdWVzdHNjb21wbGV0ZWQnKTtcblxuICAgIGlmIChlcnJvcikgdGhyb3cgbmV3IEVycm9yKCdFeGNlcHRpb246ICcgKyBlcnJvcik7XG5cbiAgICBmdW5jdGlvbiBwb3N0TWVzc2FnZShtc2cpIHtcbiAgICAgICAgaWYgKF9tZXNzZW5nZXIpIHJlcXVlc3QucG9zdE1lc3NhZ2UobXNnLFxuICAgICAgICAgICAgeyBzdGF0dXM6IHN0YXR1cywgcmVzcG9uc2U6IHJlcS5yZXNwb25zZVRleHQgfSk7XG4gICAgfVxufVxuXG5cbl8uZXh0ZW5kKHJlcXVlc3QsIHtcbiAgICBnZXQ6IHJlcXVlc3QkZ2V0LFxuICAgIHBvc3Q6IHJlcXVlc3QkcG9zdCxcbiAgICBqc29uOiByZXF1ZXN0JGpzb24sXG4gICAganNvbnA6IHJlcXVlc3QkanNvbnAsXG4gICAgZmlsZTogcmVxdWVzdCRmaWxlLFxuICAgIHVzZU1lc3NlbmdlcjogcmVxdWVzdCR1c2VNZXNzZW5nZXIsXG4gICAgZGVzdHJveTogcmVxdWVzdCRkZXN0cm95LFxuICAgIHdoZW5SZXF1ZXN0c0NvbXBsZXRlZDogd2hlblJlcXVlc3RzQ29tcGxldGVkXG59KTtcblxuXG52YXIgX21lc3NlbmdlcjtcblxuXG5mdW5jdGlvbiByZXF1ZXN0JHVzZU1lc3NlbmdlcigpIHtcbiAgICBfbWVzc2VuZ2VyID0gbmV3IE1lc3NlbmdlcihyZXF1ZXN0LCBbJ29uJywgJ29uY2UnLCAnb25TeW5jJywgJ29mZicsICdvbk1lc3NhZ2VzJywgJ29mZk1lc3NhZ2VzJywgJ3Bvc3RNZXNzYWdlJywgJ3Bvc3RNZXNzYWdlU3luYyddKTtcbn1cblxuXG5mdW5jdGlvbiByZXF1ZXN0JGdldCh1cmwsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHJlcXVlc3QodXJsLCB7IG1ldGhvZDogJ0dFVCcgfSwgY2FsbGJhY2spO1xufVxuXG5cbmZ1bmN0aW9uIHJlcXVlc3QkcG9zdCh1cmwsIGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHJlcXVlc3QodXJsLCB7IG1ldGhvZDogJ1BPU1QnLCBkYXRhOiBkYXRhIH0sIGNhbGxiYWNrKTtcbn1cblxuXG5mdW5jdGlvbiByZXF1ZXN0JGpzb24odXJsLCBjYWxsYmFjaykge1xuICAgIHZhciBwcm9taXNlID0gcmVxdWVzdCh1cmwsIHsgbWV0aG9kOiAnR0VUJyB9KTtcblxuICAgIHZhciBqc29uUHJvbWlzZSA9IHByb21pc2UudGhlbihKU09OLnBhcnNlKTtcblxuICAgIGlmIChjYWxsYmFjaylcbiAgICAgICAganNvblByb21pc2VcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24oZGF0YSkgeyBjYWxsYmFjayhudWxsLCBkYXRhKTsgfSlcbiAgICAgICAgLmNhdGNoKGZ1bmN0aW9uKGVyckRhdGEpIHsgY2FsbGJhY2soZXJyRGF0YS5yZWFzb24sIGVyckRhdGEucmVzcG9uc2UpOyB9KTtcblxuICAgIHJldHVybiBqc29uUHJvbWlzZTtcbn1cblxuXG52YXIganNvbnBPcHRpb25zID0geyBtZXRob2Q6ICdHRVQnLCBqc29ucDogdHJ1ZSB9O1xuZnVuY3Rpb24gcmVxdWVzdCRqc29ucCh1cmwsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpLFxuICAgICAgICB4UHJvbWlzZSA9IF9jcmVhdGVYUHJvbWlzZShzY3JpcHQpLFxuICAgICAgICBoZWFkID0gd2luZG93LmRvY3VtZW50LmhlYWQsXG4gICAgICAgIHVuaXF1ZUNhbGxiYWNrID0gY29uZmlnLnJlcXVlc3QuanNvbnBDYWxsYmFja1ByZWZpeCArIGNvdW50KCk7XG5cbiAgICB2YXIgb3B0cyA9IF8uZXh0ZW5kKHsgdXJsOiB1cmwgfSwganNvbnBPcHRpb25zKTtcbiAgICBpZiAoX21lc3NlbmdlcikgcmVxdWVzdC5wb3N0TWVzc2FnZVN5bmMoJ3JlcXVlc3QnLCB7IG9wdGlvbnM6IG9wdHMgfSk7XG5cbiAgICBpZiAoISBfLmlzRXF1YWwoXy5vbWl0S2V5cyhvcHRzLCAndXJsJyksIGpzb25wT3B0aW9ucykpXG4gICAgICAgIGxvZ2dlci53YXJuKCdJZ25vcmVkIG5vdCBhbGxvd2VkIHJlcXVlc3Qgb3B0aW9ucyBjaGFuZ2UgaW4gSlNPTlAgcmVxdWVzdCAtIG9ubHkgVVJMIGNhbiBiZSBjaGFuZ2VkJyk7XG5cbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ05vIEpTT05QIHJlc3BvbnNlIG9yIG5vIGNhbGxiYWNrIGluIHJlc3BvbnNlJyk7XG4gICAgICAgIF9vblJlc3VsdChlcnIpO1xuICAgIH0sIGNvbmZpZy5yZXF1ZXN0Lmpzb25wVGltZW91dCk7XG5cbiAgICB3aW5kb3dbdW5pcXVlQ2FsbGJhY2tdID0gXy5wYXJ0aWFsKF9vblJlc3VsdCwgbnVsbCk7XG5cbiAgICBfcGVuZGluZ1JlcXVlc3RzLnB1c2god2luZG93W3VuaXF1ZUNhbGxiYWNrXSk7XG5cbiAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnO1xuICAgIHNjcmlwdC5zcmMgPSBvcHRzLnVybCArIChvcHRzLnVybC5pbmRleE9mKCc/JykgPT0gLTEgPyAnPycgOiAnJicpICsgJ2NhbGxiYWNrPScgKyB1bmlxdWVDYWxsYmFjaztcblxuICAgIGhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcblxuICAgIHJldHVybiB4UHJvbWlzZS5wcm9taXNlO1xuXG5cbiAgICBmdW5jdGlvbiBfb25SZXN1bHQoZXJyLCByZXN1bHQpIHtcbiAgICAgICAgXy5zcGxpY2VJdGVtKF9wZW5kaW5nUmVxdWVzdHMsIHdpbmRvd1t1bmlxdWVDYWxsYmFja10pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcG9zdE1lc3NhZ2UoZXJyID8gJ2Vycm9yJyA6ICdzdWNjZXNzJywgZXJyLCByZXN1bHQpO1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignTm8gSlNPTlAgcmVzcG9uc2Ugb3IgdGltZW91dCcpO1xuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKCdlcnJvcmpzb25wdGltZW91dCcsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2goZSkgeyB2YXIgZXJyb3IgPSBlOyB9XG4gICAgICAgIGlmIChlcnIpIHhQcm9taXNlLnJlamVjdChlcnIpO1xuICAgICAgICBlbHNlIHhQcm9taXNlLnJlc29sdmUocmVzdWx0KTtcblxuICAgICAgICBjbGVhblVwKCk7XG4gICAgICAgIGlmICghX3BlbmRpbmdSZXF1ZXN0cy5sZW5ndGgpXG4gICAgICAgICAgICBwb3N0TWVzc2FnZSgncmVxdWVzdHNjb21wbGV0ZWQnKTtcblxuICAgICAgICBpZiAoZXJyb3IpIHRocm93IGVycm9yO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gY2xlYW5VcCgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICBoZWFkLnJlbW92ZUNoaWxkKHNjcmlwdCk7XG4gICAgICAgIGRlbGV0ZSB3aW5kb3dbdW5pcXVlQ2FsbGJhY2tdO1xuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gcG9zdE1lc3NhZ2UobXNnLCBzdGF0dXMsIHJlc3VsdCkge1xuICAgICAgICBpZiAoX21lc3NlbmdlcikgcmVxdWVzdC5wb3N0TWVzc2FnZShtc2csXG4gICAgICAgICAgICB7IHN0YXR1czogc3RhdHVzLCByZXNwb25zZTogcmVzdWx0IH0pO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiByZXF1ZXN0JGZpbGUob3B0cywgZmlsZURhdGEsIGNhbGxiYWNrLCBwcm9ncmVzcykge1xuICAgIGlmICh0eXBlb2Ygb3B0cyA9PSAnc3RyaW5nJylcbiAgICAgICAgb3B0cyA9IHsgbWV0aG9kOiAnUE9TVCcsIHVybDogb3B0cyB9O1xuXG4gICAgb3B0cy5tZXRob2QgPSBvcHRzLm1ldGhvZCB8fCAnUE9TVCc7XG4gICAgb3B0cy5maWxlID0gdHJ1ZTtcblxuICAgIGlmIChfbWVzc2VuZ2VyKSByZXF1ZXN0LnBvc3RNZXNzYWdlU3luYygncmVxdWVzdCcsIHsgb3B0aW9uczogb3B0cyB9KTtcblxuICAgIHZhciByZXEgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICBpZiAocHJvZ3Jlc3MpIHJlcS51cGxvYWQub25wcm9ncmVzcyA9IHByb2dyZXNzO1xuXG4gICAgcmVxLm9wZW4ob3B0cy5tZXRob2QsIG9wdHMudXJsLCB0cnVlKTtcbiAgICBzZXRSZXF1ZXN0SGVhZGVycyhyZXEsIG9wdHMuaGVhZGVycyk7XG5cbiAgICByZXEudGltZW91dCA9IG9wdHMudGltZW91dCB8fCBjb25maWcucmVxdWVzdC5kZWZhdWx0cy50aW1lb3V0O1xuICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSByZXEub250aW1lb3V0ID0gcmVxLm9uYWJvcnQgPSBvblJlYWR5O1xuXG4gICAgdmFyIHhQcm9taXNlID0gX2NyZWF0ZVhQcm9taXNlKHJlcSk7XG5cbiAgICBpZiAob3B0cy5iaW5hcnkpXG4gICAgICAgIHJlcS5zZW5kKGZpbGVEYXRhKTtcbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZScsIGZpbGVEYXRhKTtcbiAgICAgICAgcmVxLnNlbmQoZm9ybURhdGEpO1xuICAgIH1cblxuICAgIF9wZW5kaW5nUmVxdWVzdHMucHVzaChyZXEpO1xuXG4gICAgcmV0dXJuIHhQcm9taXNlLnByb21pc2U7XG5cbiAgICBmdW5jdGlvbiBvblJlYWR5KGUpIHtcbiAgICAgICAgaWYgKHByb2dyZXNzKSByZXEudXBsb2FkLm9ucHJvZ3Jlc3MgPSB1bmRlZmluZWQ7XG4gICAgICAgIF9vblJlYWR5KHJlcSwgY2FsbGJhY2ssIHhQcm9taXNlLCBlLnR5cGUpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiByZXF1ZXN0JGRlc3Ryb3koKSB7XG4gICAgaWYgKF9tZXNzZW5nZXIpIF9tZXNzZW5nZXIuZGVzdHJveSgpO1xuICAgIHJlcXVlc3QuX2Rlc3Ryb3llZCA9IHRydWU7XG59XG5cblxuZnVuY3Rpb24gd2hlblJlcXVlc3RzQ29tcGxldGVkKGNhbGxiYWNrLCB0aW1lb3V0KSB7XG4gICAgY2FsbGJhY2sgPSBfLm9uY2UoY2FsbGJhY2spO1xuICAgIGlmICh0aW1lb3V0KVxuICAgICAgICBfLmRlbGF5KGNhbGxiYWNrLCB0aW1lb3V0LCAndGltZW91dCcpO1xuXG4gICAgaWYgKF9wZW5kaW5nUmVxdWVzdHMubGVuZ3RoKVxuICAgICAgICBfbWVzc2VuZ2VyLm9uY2UoJ3JlcXVlc3RzY29tcGxldGVkJywgY2FsbGJhY2spO1xuICAgIGVsc2VcbiAgICAgICAgXy5kZWZlcihjYWxsYmFjayk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGRvbVV0aWxzID0gcmVxdWlyZSgnLi4vZG9tJylcbiAgICAsIGNvbnRhaW5pbmdFbGVtZW50ID0gZG9tVXRpbHMuY29udGFpbmluZ0VsZW1lbnRcbiAgICAsIHNldENhcmV0UG9zaXRpb24gPSBkb21VdGlscy5zZXRDYXJldFBvc2l0aW9uXG4gICAgLCBnZXRDb21wb25lbnRzRnJvbVJhbmdlID0gZG9tVXRpbHMuZ2V0Q29tcG9uZW50c0Zyb21SYW5nZVxuICAgICwgZGVsZXRlUmFuZ2VXaXRoQ29tcG9uZW50cyA9IGRvbVV0aWxzLmRlbGV0ZVJhbmdlV2l0aENvbXBvbmVudHNcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL2xvZ2dlcicpXG4gICAgLCBDb21wb25lbnQgPSByZXF1aXJlKCcuLi8uLi9jb21wb25lbnRzL2NfY2xhc3MnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRleHRTZWxlY3Rpb247XG5cblxuLyoqXG4gKiBUZXh0IHNlbGVjdGlvbiBjbGFzcy5cbiAqIFNlcnZlcyBhcyBhIGhlbHBlciB0byBtYW5hZ2UgY3VycmVudCBzZWxlY3Rpb25cbiAqIFRoZSBvYmplY3QgY2Fubm90IGJlIHJldXNlZCwgaWYgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzIHNvbWUgb2YgaXRzIHByb3BlcnRpZXMgbWF5IGNvbnRhaW4gaW5mb3JtYXRpb24gcmVsYXRlZCB0byBwcmV2aW91cyBzZWxlY3Rpb25cbiAqXG4gKiBAcGFyYW0ge1dpbmRvd30gd2luIHdpbmRvdyBpbiB3aGljaCB0ZXh0IHNlbGVjdGlvbiBpcyBwcm9jZXNzZWRcbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbih3aW4pIHtcbiAgICBpZiAoISB0aGlzIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbilcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKHdpbik7XG4gICAgdGhpcy53aW5kb3cgPSB3aW4gfHwgd2luZG93O1xuICAgIHRoaXMuaW5pdCgpO1xufVxuXG5cbi8qKlxuICogVGV4dFNlbGVjdGlvbiBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgc2VsZWN0aW9uIHN0YXJ0IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtFbGVtZW50fG51bGx9XG4gKi9cbnZhciBUZXh0U2VsZWN0aW9uJHN0YXJ0RWxlbWVudCA9IFxuICAgIF8ucGFydGlhbChfZ2V0RWxlbWVudCwgJ19zdGFydEVsZW1lbnQnLCAnc3RhcnRDb250YWluZXInKTtcblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNlbGVjdGlvbiBlbmQgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge0VsZW1lbnR8bnVsbH1cbiAqL1xudmFyIFRleHRTZWxlY3Rpb24kZW5kRWxlbWVudCA9IFxuICAgIF8ucGFydGlhbChfZ2V0RWxlbWVudCwgJ19lbmRFbGVtZW50JywgJ2VuZENvbnRhaW5lcicpO1xuXG5cbi8qKlxuICogVGV4dFNlbGVjdGlvbiBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgc2VsZWN0aW9uIGVuZCBlbGVtZW50XG4gKlxuICogQHJldHVybiB7RWxlbWVudHxudWxsfVxuICovXG52YXIgVGV4dFNlbGVjdGlvbiRjb250YWluaW5nRWxlbWVudCA9IFxuICAgIF8ucGFydGlhbChfZ2V0RWxlbWVudCwgJ19jb250YWluaW5nRWxlbWVudCcsICdjb21tb25BbmNlc3RvckNvbnRhaW5lcicpO1xuXG5cbi8qKlxuICogVGV4dFNlbGVjdGlvbiBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgc2VsZWN0aW9uIHN0YXJ0IENvbXBvbmVudFxuICpcbiAqIEByZXR1cm4ge0NvbXBvbmVudH1cbiAqL1xudmFyIFRleHRTZWxlY3Rpb24kc3RhcnRDb21wb25lbnQgPSBcbiAgICBfLnBhcnRpYWwoX2dldENvbXBvbmVudCwgJ19zdGFydENvbXBvbmVudCcsICdzdGFydEVsZW1lbnQnKTtcblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNlbGVjdGlvbiBlbmQgQ29tcG9uZW50XG4gKlxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG52YXIgVGV4dFNlbGVjdGlvbiRlbmRDb21wb25lbnQgPSBcbiAgICBfLnBhcnRpYWwoX2dldENvbXBvbmVudCwgJ19lbmRDb21wb25lbnQnLCAnZW5kRWxlbWVudCcpO1xuXG5cbi8qKlxuICogVGV4dFNlbGVjdGlvbiBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgc2VsZWN0aW9uIGVuZCBDb21wb25lbnRcbiAqXG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbnZhciBUZXh0U2VsZWN0aW9uJGNvbnRhaW5pbmdDb21wb25lbnQgPSBcbiAgICBfLnBhcnRpYWwoX2dldENvbXBvbmVudCwgJ19jb250YWluaW5nQ29tcG9uZW50JywgJ2NvbnRhaW5pbmdFbGVtZW50Jyk7XG5cblxuXy5leHRlbmRQcm90byhUZXh0U2VsZWN0aW9uLCB7XG4gICAgaW5pdDogVGV4dFNlbGVjdGlvbiRpbml0LFxuICAgIHRleHQ6IFRleHRTZWxlY3Rpb24kdGV4dCxcbiAgICB0ZXh0Tm9kZXM6IFRleHRTZWxlY3Rpb24kdGV4dE5vZGVzLFxuICAgIGNsZWFyOiBUZXh0U2VsZWN0aW9uJGNsZWFyLFxuXG4gICAgc3RhcnRFbGVtZW50OiBUZXh0U2VsZWN0aW9uJHN0YXJ0RWxlbWVudCxcbiAgICBlbmRFbGVtZW50OiBUZXh0U2VsZWN0aW9uJGVuZEVsZW1lbnQsXG4gICAgY29udGFpbmluZ0VsZW1lbnQ6IFRleHRTZWxlY3Rpb24kY29udGFpbmluZ0VsZW1lbnQsXG5cbiAgICBzdGFydENvbXBvbmVudDogVGV4dFNlbGVjdGlvbiRzdGFydENvbXBvbmVudCxcbiAgICBlbmRDb21wb25lbnQ6IFRleHRTZWxlY3Rpb24kZW5kQ29tcG9uZW50LFxuICAgIGNvbnRhaW5pbmdDb21wb25lbnQ6IFRleHRTZWxlY3Rpb24kY29udGFpbmluZ0NvbXBvbmVudCxcblxuICAgIGNvbnRhaW5lZENvbXBvbmVudHM6IFRleHRTZWxlY3Rpb24kY29udGFpbmVkQ29tcG9uZW50cyxcbiAgICBlYWNoQ29udGFpbmVkQ29tcG9uZW50OiBUZXh0U2VsZWN0aW9uJGVhY2hDb250YWluZWRDb21wb25lbnQsXG4gICAgZGVsOiBUZXh0U2VsZWN0aW9uJGRlbCxcbiAgICBfZ2V0UG9zdERlbGV0ZVNlbGVjdGlvblBvaW50OiBfZ2V0UG9zdERlbGV0ZVNlbGVjdGlvblBvaW50LFxuICAgIF9zZWxlY3RBZnRlckRlbGV0ZTogX3NlbGVjdEFmdGVyRGVsZXRlLFxuXG4gICAgZ2V0UmFuZ2U6IFRleHRTZWxlY3Rpb24kZ2V0UmFuZ2UsXG4gICAgZ2V0U3RhdGU6IFRleHRTZWxlY3Rpb24kZ2V0U3RhdGUsXG4gICAgZ2V0Tm9ybWFsaXplZFJhbmdlOiBUZXh0U2VsZWN0aW9uJCRnZXROb3JtYWxpemVkUmFuZ2UsXG4gICAgZ2V0RGlyZWN0aW9uOiBUZXh0U2VsZWN0aW9uJCRnZXREaXJlY3Rpb25cbn0pO1xuXG5cbl8uZXh0ZW5kKFRleHRTZWxlY3Rpb24sIHtcbiAgICBjcmVhdGVGcm9tUmFuZ2U6IFRleHRTZWxlY3Rpb24kJGNyZWF0ZUZyb21SYW5nZSxcbiAgICBjcmVhdGVGcm9tU3RhdGU6IFRleHRTZWxlY3Rpb24kJGNyZWF0ZUZyb21TdGF0ZSxcbiAgICBjcmVhdGVTdGF0ZU9iamVjdDogVGV4dFNlbGVjdGlvbiQkY3JlYXRlU3RhdGVPYmplY3Rcbn0pO1xuXG5cbi8qKlxuICogVGV4dFNlbGVjdGlvbiBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWxpemVzIFRleHRTZWxlY3Rpb24gZnJvbSB0aGUgY3VycmVudCBzZWxlY3Rpb25cbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiRpbml0KCkge1xuICAgIHRoaXMuc2VsZWN0aW9uID0gdGhpcy53aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uLnJhbmdlQ291bnQpXG4gICAgICAgIHRoaXMucmFuZ2UgPSB0aGlzLnNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIHRoaXMuaXNDb2xsYXBzZWQgPSB0aGlzLnNlbGVjdGlvbi5pc0NvbGxhcHNlZDtcbn1cblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXRyaWV2ZXMgYW5kIHJldHVybnMgc2VsZWN0aW9uIHRleHRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kdGV4dCgpIHtcbiAgICBpZiAoISB0aGlzLnJhbmdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgaWYgKCEgdGhpcy5fdGV4dClcbiAgICAgICAgdGhpcy5fdGV4dCA9IHRoaXMucmFuZ2UudG9TdHJpbmcoKTtcblxuICAgIHJldHVybiB0aGlzLl90ZXh0O1xufVxuXG5cbi8qKlxuICogVGV4dFNlbGVjdGlvbiBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHJpZXZlcyBhbmQgcmV0dXJucyBzZWxlY3Rpb24gdGV4dCBub2Rlc1xuICpcbiAqIEByZXR1cm4ge0FycmF5W05vZGVdfVxuICovXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJHRleHROb2RlcygpIHtcbiAgICBpZiAoISB0aGlzLnJhbmdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgaWYgKCEgdGhpcy5fdGV4dE5vZGVzKVxuICAgICAgICB0aGlzLl90ZXh0Tm9kZXMgPSBfZ2V0VGV4dE5vZGVzLmNhbGwodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMuX3RleHROb2Rlcztcbn1cblxuXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJGNsZWFyKCkge1xuICAgIHRoaXMuc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xufVxuXG5cbi8qKlxuICogUmV0cmlldmVzIHRleHQgYW5kIHRleHQgbm9kZXMgZnJvbSBzZWxlY3Rpb24gc2F2aW5nIHRoZW0gb24gcHJvcGVydGllcyBvZiBvYmplY3RcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtUZXh0U2VsZWN0aW9ufSB0aGlzXG4gKi9cbmZ1bmN0aW9uIF9nZXRUZXh0Tm9kZXMoKSB7XG4gICAgLy8gbGlzdCBvZiBzZWxlY3RlZCB0ZXh0IG5vZGVzXG4gICAgdmFyIHRleHROb2RlcyA9IFtdO1xuXG4gICAgaWYgKHRoaXMuaXNDb2xsYXBzZWQpXG4gICAgICAgIHJldHVybiB0ZXh0Tm9kZXM7XG5cbiAgICAvLyBjcmVhdGUgVHJlZVdhbGtlciB0byB0cmF2ZXJzZSB0aGUgdHJlZSB0byBzZWxlY3QgYWxsIHRleHQgbm9kZXNcbiAgICB2YXIgc2VsU3RhcnQgPSB0aGlzLnJhbmdlLnN0YXJ0Q29udGFpbmVyXG4gICAgICAgICwgc2VsRW5kID0gdGhpcy5yYW5nZS5lbmRDb250YWluZXJcbiAgICAgICAgLCByYW5nZUNvbnRhaW5lciA9IHRoaXMucmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7XG5cbiAgICB2YXIgdHJlZVdhbGtlciA9IHRoaXMud2luZG93LmRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIocmFuZ2VDb250YWluZXIsIE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcbiAgICB2YXIgbm9kZSA9IHRyZWVXYWxrZXIuY3VycmVudE5vZGUgPSBzZWxTdGFydDtcblxuICAgIC8vIHRyYXZlcnNlIERPTSB0cmVlIHRvIGNvbGxlY3QgYWxsIHNlbGVjdGVkIHRleHQgbm9kZXNcbiAgICB3aGlsZSAobm9kZSAmJiAoISBpbkVuZCB8fCBzZWxFbmQuY29udGFpbnMobm9kZSkpKSB7XG4gICAgICAgIHRleHROb2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgICB2YXIgaW5FbmQgPSBpbkVuZCB8fCBzZWxFbmQuY29udGFpbnMobm9kZSk7XG4gICAgICAgIG5vZGUgPSB0cmVlV2Fsa2VyLm5leHROb2RlKCk7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0Tm9kZXM7XG59XG5cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIHJldHVybnMgc3RhcnQvZW5kIGVsZW1lbnQgZnJvbSBzZWxlY3Rpb24gc2F2aW5nIHRoZW0gb24gcHJvcGVydGllcyBvZiBvYmplY3RcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtUZXh0U2VsZWN0aW9ufSB0aGlzXG4gKiBAcmV0dXJuIHtFbGVtZW50fG51bGx9XG4gKi9cbmZ1bmN0aW9uIF9nZXRFbGVtZW50KHRoaXNQcm9wTmFtZSwgcmFuZ2VQcm9wTmFtZSkge1xuICAgIGlmICghIHRoaXMucmFuZ2UpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBpZiAodHlwZW9mIHRoaXNbdGhpc1Byb3BOYW1lXSA9PSAndW5kZWZpbmVkJylcbiAgICAgICAgdGhpc1t0aGlzUHJvcE5hbWVdID0gY29udGFpbmluZ0VsZW1lbnQodGhpcy5yYW5nZVtyYW5nZVByb3BOYW1lXSk7XG4gICAgcmV0dXJuIHRoaXNbdGhpc1Byb3BOYW1lXTtcbn1cblxuXG4vKipcbiAqIFJldHJpZXZlcyBhbmQgcmV0dXJucyBzdGFydC9lbmQgY29tcG9uZW50IGZyb20gc2VsZWN0aW9uIHNhdmluZyB0aGVtIG9uIHByb3BlcnRpZXMgb2Ygb2JqZWN0XG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7VGV4dFNlbGVjdGlvbn0gdGhpc1xuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBfZ2V0Q29tcG9uZW50KHRoaXNQcm9wTmFtZSwgZWxNZXRob2ROYW1lKSB7XG4gICAgaWYgKCEgdGhpcy5yYW5nZSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGlmICh0eXBlb2YgdGhpc1t0aGlzUHJvcE5hbWVdID09ICd1bmRlZmluZWQnKVxuICAgICAgICB0aGlzW3RoaXNQcm9wTmFtZV0gPSBDb21wb25lbnQuZ2V0Q29udGFpbmluZ0NvbXBvbmVudCh0aGlzW2VsTWV0aG9kTmFtZV0oKSk7XG4gICAgcmV0dXJuIHRoaXNbdGhpc1Byb3BOYW1lXTtcbn1cblxuXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJGNvbnRhaW5lZENvbXBvbmVudHMoKSB7XG4gICAgaWYgKHRoaXMuX2NvbnRhaW5lZENvbXBvbmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzLl9jb250YWluZWRDb21wb25lbnRzO1xuXG4gICAgdmFyIGNvbXBvbmVudHMgPSB0aGlzLl9jb250YWluZWRDb21wb25lbnRzID0gW107XG5cbiAgICBpZiAodGhpcy5pc0NvbGxhcHNlZCB8fCAhIHRoaXMucmFuZ2UpIHJldHVybiBjb21wb25lbnRzO1xuXG4gICAgcmV0dXJuIGdldENvbXBvbmVudHNGcm9tUmFuZ2UodGhpcy5yYW5nZSk7XG59XG5cblxuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiRlYWNoQ29udGFpbmVkQ29tcG9uZW50KGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgaWYgKHRoaXMuaXNDb2xsYXBzZWQgfHwgISB0aGlzLnJhbmdlKSByZXR1cm47XG5cbiAgICB2YXIgY29tcG9uZW50cyA9IHRoaXMuY29udGFpbmVkQ29tcG9uZW50cygpO1xuXG4gICAgY29tcG9uZW50cy5mb3JFYWNoKGNhbGxiYWNrLCB0aGlzQXJnKTtcbn1cblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBEZWxldGVzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBhbmQgYWxsIGNvbXBvbmVudHMgaW4gaXRcbiAqIFxuICogQHBhcmFtIHtCb29sZWFufSBzZWxlY3RFbmRDb250YWluZXIgc2V0IHRvIHRydWUgaWYgdGhlIGVuZCBjb250YWluZXIgc2hvdWxkIGJlIHNlbGVjdGVkIGFmdGVyIGRlbGV0aW9uXG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kZGVsKHNlbGVjdEVuZENvbnRhaW5lcikge1xuICAgIGlmICh0aGlzLmlzQ29sbGFwc2VkIHx8ICEgdGhpcy5yYW5nZSkgcmV0dXJuO1xuXG4gICAgdmFyIHNlbFBvaW50ID0gdGhpcy5fZ2V0UG9zdERlbGV0ZVNlbGVjdGlvblBvaW50KHNlbGVjdEVuZENvbnRhaW5lcik7XG5cbiAgICBkZWxldGVSYW5nZVdpdGhDb21wb25lbnRzKHRoaXMucmFuZ2UpO1xuXG4gICAgdGhpcy5fc2VsZWN0QWZ0ZXJEZWxldGUoc2VsUG9pbnQpO1xuICAgIHNlbFBvaW50Lm5vZGUucGFyZW50Tm9kZS5ub3JtYWxpemUoKTtcbn1cblxuXG5mdW5jdGlvbiBfZ2V0UG9zdERlbGV0ZVNlbGVjdGlvblBvaW50KHNlbGVjdEVuZENvbnRhaW5lcikge1xuICAgIHZhciBzZWxOb2RlID0gdGhpcy5yYW5nZS5zdGFydENvbnRhaW5lcjtcbiAgICB2YXIgc2VsT2Zmc2V0ID0gdGhpcy5yYW5nZS5zdGFydE9mZnNldDtcbiAgICBpZiAoc2VsZWN0RW5kQ29udGFpbmVyICYmIHRoaXMucmFuZ2Uuc3RhcnRDb250YWluZXIgIT0gdGhpcy5yYW5nZS5lbmRDb250YWluZXIpIHtcbiAgICAgICAgc2VsTm9kZSA9IHRoaXMucmFuZ2UuZW5kQ29udGFpbmVyO1xuICAgICAgICBzZWxPZmZzZXQgPSAwO1xuICAgIH1cbiAgICByZXR1cm4geyBub2RlOiBzZWxOb2RlLCBvZmZzZXQ6IHNlbE9mZnNldCB9O1xufVxuXG5cbmZ1bmN0aW9uIF9zZWxlY3RBZnRlckRlbGV0ZShzZWxQb2ludCkge1xuICAgIHZhciBzZWxOb2RlID0gc2VsUG9pbnQubm9kZVxuICAgICAgICAsIHNlbE9mZnNldCA9IHNlbFBvaW50Lm9mZnNldDtcblxuICAgIGlmICghc2VsTm9kZSkgcmV0dXJuO1xuICAgIGlmIChzZWxOb2RlLm5vZGVUeXBlID09IE5vZGUuVEVYVF9OT0RFKVxuICAgICAgICBzZWxOb2RlLnRleHRDb250ZW50ID0gc2VsTm9kZS50ZXh0Q29udGVudC50cmltUmlnaHQoKTtcbiAgICBpZiAoIXNlbE5vZGUubm9kZVZhbHVlKVxuICAgICAgICBzZWxOb2RlLm5vZGVWYWx1ZSA9ICdcXHUwMEEwJzsgLy9ub24tYnJlYWtpbmcgc3BhY2UsIFxcdTIwMEIgZm9yIHplcm8gd2lkdGggc3BhY2U7XG5cbiAgICB2YXIgcG9zaXRpb24gPSBzZWxPZmZzZXQgPiBzZWxOb2RlLmxlbmd0aCA/IHNlbE5vZGUubGVuZ3RoIDogc2VsT2Zmc2V0O1xuICAgIHNldENhcmV0UG9zaXRpb24oc2VsTm9kZSwgcG9zaXRpb24pO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBzZWxlY3Rpb24gcmFuZ2VcbiAqXG4gKiBAcmV0dXJuIHtSYW5nZX1cbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiRnZXRSYW5nZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yYW5nZTtcbn1cblxuXG4vKipcbiAqIFN0b3JlcyBzZWxlY3Rpb24gd2luZG93LCBub2RlcyBhbmQgb2Zmc2V0cyBpbiBvYmplY3RcbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiRnZXRTdGF0ZShyb290RWwpIHtcbiAgICB2YXIgciA9IHRoaXMucmFuZ2U7XG4gICAgdmFyIGRvYyA9IHJvb3RFbC5vd25lckRvY3VtZW50XG4gICAgICAgICwgd2luID0gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3c7XG4gICAgaWYgKCFyKSByZXR1cm4geyB3aW5kb3c6IHdpbiB9O1xuICAgIHJldHVybiBUZXh0U2VsZWN0aW9uLmNyZWF0ZVN0YXRlT2JqZWN0KHJvb3RFbCwgci5zdGFydENvbnRhaW5lciwgci5zdGFydE9mZnNldCwgci5lbmRDb250YWluZXIsIHIuZW5kT2Zmc2V0KTtcbn1cblxuXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJCRjcmVhdGVTdGF0ZU9iamVjdChyb290RWwsIHN0YXJ0Q29udGFpbmVyLCBzdGFydE9mZnNldCwgZW5kQ29udGFpbmVyLCBlbmRPZmZzZXQpIHtcbiAgICBlbmRDb250YWluZXIgPSBlbmRDb250YWluZXIgfHwgc3RhcnRDb250YWluZXI7XG4gICAgZW5kT2Zmc2V0ID0gZW5kT2Zmc2V0IHx8IHN0YXJ0T2Zmc2V0O1xuICAgIHZhciBkb2MgPSByb290RWwub3duZXJEb2N1bWVudFxuICAgICAgICAsIHdpbiA9IGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93O1xuICAgIHJldHVybiB7XG4gICAgICAgIHdpbmRvdzogd2luLFxuICAgICAgICByb290RWw6IHJvb3RFbCxcbiAgICAgICAgc3RhcnQ6IF9nZXRTZWxlY3Rpb25Qb2ludFN0YXRlKHJvb3RFbCwgc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0KSxcbiAgICAgICAgZW5kOiBfZ2V0U2VsZWN0aW9uUG9pbnRTdGF0ZShyb290RWwsIGVuZENvbnRhaW5lciwgZW5kT2Zmc2V0KVxuICAgIH07XG59XG5cblxuZnVuY3Rpb24gX2dldFNlbGVjdGlvblBvaW50U3RhdGUocm9vdEVsLCBub2RlLCBvZmZzZXQpIHtcbiAgICB2YXIgdHJlZVBhdGggPSBkb21VdGlscy50cmVlUGF0aE9mKHJvb3RFbCwgbm9kZSk7XG4gICAgaWYgKCEgdHJlZVBhdGgpIGxvZ2dlci5lcnJvcignU2VsZWN0aW9uIHBvaW50IGlzIG91dHNpZGUgb2Ygcm9vdCBlbGVtZW50Jyk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHJlZVBhdGg6IHRyZWVQYXRoLFxuICAgICAgICBvZmZzZXQ6IG9mZnNldFxuICAgIH07XG59XG5cblxuLyoqXG4gKiBSZXN0b3JlcyBhY3R1YWwgc2VsZWN0aW9uIHRvIHRoZSBzdG9yZWQgcmFuZ2VcbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiQkY3JlYXRlRnJvbVN0YXRlKHN0YXRlKSB7XG4gICAgdmFyIGRvbVV0aWxzID0gc3RhdGUud2luZG93Lm1pbG8udXRpbC5kb207XG5cbiAgICBpZiAoc3RhdGUucm9vdEVsICYmIHN0YXRlLnN0YXJ0ICYmIHN0YXRlLmVuZCkge1xuICAgICAgICB2YXIgc3RhcnROb2RlID0gX3NlbGVjdGlvbk5vZGVGcm9tU3RhdGUoc3RhdGUucm9vdEVsLCBzdGF0ZS5zdGFydClcbiAgICAgICAgICAgICwgZW5kTm9kZSA9IF9zZWxlY3Rpb25Ob2RlRnJvbVN0YXRlKHN0YXRlLnJvb3RFbCwgc3RhdGUuZW5kKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZG9tVXRpbHMuc2V0U2VsZWN0aW9uKHN0YXJ0Tm9kZSwgc3RhdGUuc3RhcnQub2Zmc2V0LCBlbmROb2RlLCBzdGF0ZS5lbmQub2Zmc2V0KTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGV4dFNlbGVjdGlvbihzdGF0ZS53aW5kb3cpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignVGV4dCBzZWxlY3Rpb246IGNhblxcJ3QgY3JlYXRlIHNlbGVjdGlvbicsIGUsIGUubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBkb21VdGlscy5jbGVhclNlbGVjdGlvbihzdGF0ZS53aW5kb3cpO1xuICAgICAgICByZXR1cm4gbmV3IFRleHRTZWxlY3Rpb24oc3RhdGUud2luZG93KTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gX3NlbGVjdGlvbk5vZGVGcm9tU3RhdGUocm9vdEVsLCBwb2ludFN0YXRlKSB7XG4gICAgdmFyIG5vZGUgPSBkb21VdGlscy5nZXROb2RlQXRUcmVlUGF0aChyb290RWwsIHBvaW50U3RhdGUudHJlZVBhdGgpO1xuICAgIGlmICghIG5vZGUpIGxvZ2dlci5lcnJvcignVGV4dFNlbGVjdGlvbiBjcmVhdGVGcm9tU3RhdGU6IG5vIG5vZGUgYXQgdHJlZVBhdGgnKTtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgc2VsZWN0aW9uIGZyb20gcGFzc2VkIHJhbmdlXG4gKiBcbiAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGJhY2t3YXJkXG4gKlxuICogQHJldHVybiB7VGV4dFNlbGVjdGlvbn1cbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiQkY3JlYXRlRnJvbVJhbmdlKHJhbmdlLCBiYWNrd2FyZCkge1xuICAgIHZhciB3aW4gPSByYW5nZS5zdGFydENvbnRhaW5lci5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3XG4gICAgICAgICwgc2VsID0gd2luLmdldFNlbGVjdGlvbigpXG4gICAgICAgICwgZW5kUmFuZ2U7XG5cbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG5cbiAgICBpZiAoYmFja3dhcmQpe1xuICAgICAgICBlbmRSYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTtcbiAgICAgICAgZW5kUmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuXG4gICAgICAgIHNlbC5hZGRSYW5nZShlbmRSYW5nZSk7XG4gICAgICAgIHNlbC5leHRlbmQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0T2Zmc2V0KSAgICAgICAgXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgVGV4dFNlbGVjdGlvbih3aW4pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBub3JtYWxpemVkIGNvcHkgb2YgdGhlIHJhbmdlXG4gKiBJZiB5b3UgdHJpcGxlIGNsaWNrIGFuIGl0ZW0sIHRoZSBlbmQgb2YgdGhlIHJhbmdlIGlzIHBvc2l0aW9uZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgTkVYVCBub2RlLlxuICogdGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgcmFuZ2Ugd2l0aCB0aGUgZW5kIHBvc2l0aW9uZWQgYXQgdGhlIGVuZCBvZiB0aGUgbGFzdCB0ZXh0bm9kZSBjb250YWluZWQgXG4gKiBpbnNpZGUgYSBjb21wb25lbnQgd2l0aCB0aGUgXCJlZGl0YWJsZVwiIGZhY2V0XG4gKiBcbiAqIEByZXR1cm4ge3JhbmdlfVxuICovXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJCRnZXROb3JtYWxpemVkUmFuZ2UoKXtcbiAgICB2YXIgZG9jID0gdGhpcy5yYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lci5vd25lckRvY3VtZW50XG4gICAgICAgICwgdHcsIHByZXZpb3VzTm9kZVxuICAgICAgICAsIG5ld1JhbmdlID0gdGhpcy5yYW5nZS5jbG9uZVJhbmdlKCk7XG5cbiAgICBpZiAobmV3UmFuZ2UuZW5kQ29udGFpbmVyLm5vZGVUeXBlICE9PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICB0dyA9IGRvYy5jcmVhdGVUcmVlV2Fsa2VyKGRvYy5ib2R5LCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gICAgICAgIHR3LmN1cnJlbnROb2RlID0gbmV3UmFuZ2UuZW5kQ29udGFpbmVyO1xuICAgICAgICBwcmV2aW91c05vZGUgPSB0dy5wcmV2aW91c05vZGUoKTtcbiAgICAgICAgbmV3UmFuZ2Uuc2V0RW5kKHByZXZpb3VzTm9kZSwgcHJldmlvdXNOb2RlLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld1JhbmdlO1xufVxuXG4vKipcbiAqIGdldCB0aGUgZGlyZWN0aW9uIG9mIGEgc2VsZWN0aW9uXG4gKlxuICogMSBmb3J3YXJkLCAtMSBiYWNrd2FyZCwgMCBubyBkaXJlY3Rpb24sIHVuZGVmaW5lZCBvbmUgb2YgdGhlIG5vZGUgaXMgZGV0YWNoZWQgb3IgaW4gYSBkaWZmZXJlbnQgZnJhbWVcbiAqXG4gKiBAcmV0dXJuIHstMXwwfDF8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJCRnZXREaXJlY3Rpb24oKXtcbiAgICByZXR1cm4gZG9tVXRpbHMuZ2V0U2VsZWN0aW9uRGlyZWN0aW9uKHRoaXMuc2VsZWN0aW9uKTsgICAgXG59XG5cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgRE9NU3RvcmFnZUVycm9yID0gcmVxdWlyZSgnLi4vZXJyb3InKS5jcmVhdGVDbGFzcygnRG9tU3RvcmFnZUVycm9yJylcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uLy4uL21lc3NlbmdlcicpXG4gICAgLCBTdG9yYWdlTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4vbXNnX3NyYycpXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi8uLi9jb25maWcnKVxuICAgICwganNvblBhcnNlID0gcmVxdWlyZSgnLi4vanNvbl9wYXJzZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IERPTVN0b3JhZ2U7XG5cblxuLy8gc2hhcmVkIGtleXMgc3RvcmVkIGJ5IGFsbCBpbnN0YW5jZXMsIGluY2x1ZGUga2V5IHByZWZpeGVzXG52YXIgX3N0b3JlZEtleXMgPSB7XG4gICAgdHJ1ZToge30sIC8vIHNlc3Npb24gc3RvcmFnZVxuICAgIGZhbHNlOiB7fSAvLyBsb2NhbCBzdG9yYWdlXG59O1xuXG5cbi8qKlxuICogRE9NU3RvcmFnZSBjbGFzcyB0byBzaW1wbGlmeSBzdG9yYWdlIGFuZCByZXRyaWV2YWwgb2YgbXVsdGlwbGUgaXRlbXMgd2l0aCB0eXBlcyBwcmVzZXJ2YXRpb24gdG8gRE9NIHN0b3JhZ2UgKGxvY2FsU3RvcmFnZSBhbmQgc2Vzc2lvblN0b3JhZ2UpLlxuICogVHlwZXMgd2lsbCBiZSBzdG9yZWQgaW4gdGhlIGtleSBjcmVhdGVkIGZyb20gdmFsdWUga2V5cyB3aXRoIGFwcGVuZGVkIGBtaWxvLmNvbmZpZy5kb21TdG9yYWdlLnR5cGVTdWZmaXhgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVByZWZpeCBwcmVmaXggdGhhdCB3aWxsIGJlIGFkZGVkIHRvIGFsbCBrZXlzIGZvbGxvd2VkIGJ5IGBtaWxvLmNvbmZpZy5kb21TdG9yYWdlLnByZWZpeFNlcGFyYXRvcmAgKFwiL1wiIGJ5IGRlZmF1bHQpLlxuICogQHBhcmFtIHtCb29sZWFufSBzZXNzaW9uT25seSB0cnVlIHRvIHVzZSBzZXNzaW9uU3RvcmFnZS4gbG9jYWxTdG9yYWdlIHdpbGwgYmUgdXNlZCBieSBkZWZhdWx0LlxuICogQHBhcmFtIHtXaW5kb3d9IHdpbiB3aW5kb3cgdG8gd29yayBpblxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlKGtleVByZWZpeCwgc2Vzc2lvbk9ubHksIHdpbikge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgd2luID0gd2luIHx8IHdpbmRvdztcblxuICAgIGtleVByZWZpeCA9IGNvbmZpZy5kb21TdG9yYWdlLnJvb3QgK1xuICAgICAgICAgICAgICAgIChrZXlQcmVmaXhcbiAgICAgICAgICAgICAgICAgICAgPyBrZXlQcmVmaXggKyBjb25maWcuZG9tU3RvcmFnZS5wcmVmaXhTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgOiAnJyk7XG5cbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBrZXlQcmVmaXg6IGtleVByZWZpeCxcbiAgICAgICAgc2Vzc2lvbk9ubHk6ICEhIHNlc3Npb25Pbmx5LFxuICAgICAgICB3aW5kb3c6IHdpbixcbiAgICAgICAgX3N0b3JhZ2U6IHNlc3Npb25Pbmx5ID8gd2luLnNlc3Npb25TdG9yYWdlIDogd2luLmxvY2FsU3RvcmFnZSxcbiAgICAgICAgX3R5cGVTdWZmaXg6IGNvbmZpZy5kb21TdG9yYWdlLnR5cGVTdWZmaXgsXG4gICAgICAgIF9rZXlzOiB7fVxuICAgIH0sIF8uV1JJVCk7XG59XG5cblxuXy5leHRlbmRQcm90byhET01TdG9yYWdlLCB7XG4gICAgZ2V0OiBET01TdG9yYWdlJGdldCxcbiAgICBzZXQ6IERPTVN0b3JhZ2Ukc2V0LFxuICAgIHJlbW92ZTogRE9NU3RvcmFnZSRyZW1vdmUsXG4gICAgaGFzSXRlbTogRE9NU3RvcmFnZSRoYXNJdGVtLFxuICAgIGdldEl0ZW06IERPTVN0b3JhZ2UkZ2V0SXRlbSxcbiAgICBzZXRJdGVtOiBET01TdG9yYWdlJHNldEl0ZW0sXG4gICAgcmVtb3ZlSXRlbTogRE9NU3RvcmFnZSRyZW1vdmVJdGVtLFxuICAgIF9zdG9yYWdlS2V5OiBET01TdG9yYWdlJF9zdG9yYWdlS2V5LFxuICAgIF9kb21TdG9yYWdlS2V5OiBET01TdG9yYWdlJF9kb21TdG9yYWdlS2V5LFxuICAgIGdldEFsbEtleXM6IERPTVN0b3JhZ2UkZ2V0QWxsS2V5cyxcbiAgICBnZXRBbGxJdGVtczogRE9NU3RvcmFnZSRnZXRBbGxJdGVtcyxcbiAgICBjcmVhdGVNZXNzZW5nZXI6IERPTVN0b3JhZ2UkY3JlYXRlTWVzc2VuZ2VyLFxuICAgIGRlc3Ryb3k6IERPTVN0b3JhZ2UkZGVzdHJveVxufSk7XG5cblxuLyoqXG4gKiBFeHBvc2UgTWVzZW5nZXIgYW5kIE1lc3NhZ2VTb3VyY2UgbWV0aG9kcyBvbiBET01TdG9yYWdlXG4gKi9cbk1lc3Nlbmdlci51c2VXaXRoKERPTVN0b3JhZ2UsICdfbWVzc2VuZ2VyJywgTWVzc2VuZ2VyLmRlZmF1bHRNZXRob2RzKTtcblN0b3JhZ2VNZXNzYWdlU291cmNlLnVzZVdpdGgoRE9NU3RvcmFnZSwgJ19tZXNzYWdlU291cmNlJywgWyd0cmlnZ2VyJ10pO1xuXG5cbnZhciBfc2Vzc2lvblN0b3JhZ2UgPSBuZXcgRE9NU3RvcmFnZSgnJywgdHJ1ZSlcbiAgICAsIF9sb2NhbFN0b3JhZ2UgPSBuZXcgRE9NU3RvcmFnZSgnJywgZmFsc2UpO1xuXG52YXIgX2RvbVN0b3JhZ2UgPSB7XG4gICAgICAgIHRydWU6IF9zZXNzaW9uU3RvcmFnZSxcbiAgICAgICAgZmFsc2U6IF9sb2NhbFN0b3JhZ2VcbiAgICB9O1xuXG5fLmV4dGVuZChET01TdG9yYWdlLCB7XG4gICAgcmVnaXN0ZXJEYXRhVHlwZTogRE9NU3RvcmFnZSQkcmVnaXN0ZXJEYXRhVHlwZSxcbiAgICBsb2NhbDogX2xvY2FsU3RvcmFnZSxcbiAgICBzZXNzaW9uOiBfc2Vzc2lvblN0b3JhZ2UsXG4gICAgc3RvcmFnZTogX2RvbVN0b3JhZ2UsXG4gICAgX3N0b3JlZEtleXM6IF9zdG9yZWRLZXlzIC8vIGV4cG9zZWQgZm9yIHRlc3Rpbmdcbn0pO1xuXG5cbi8qKlxuICogU2V0cyBkYXRhIHRvIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBrZXlzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIHNpbmdsZSBvYmplY3QgY2FuIGJlIHBhc3NlZCBpbiB3aGljaCBjYXNlIGtleXMgd2lsbCBiZSB1c2VkIGFzIGtleXMgaW4gbG9jYWwgc3RvcmFnZS5cbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFsdGVybmF0aXZlbHkganVzdCB0aGUgbGlzdCBvZiBhcmd1bWVudHMgY2FuIGJlIHBhc3NlZCB3aGVyZSBhcmd1bWVudHMgY2FuIGJlIHNlcXVlbnRpYWxseSB1c2VkIGFzIGtleXMgYW5kIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRzZXQoZGF0YSkgeyAvLyBvciBhcmd1bWVudHNcbiAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ29iamVjdCcpXG4gICAgICAgIF8uZWFjaEtleShkYXRhLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICB0aGlzLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIGVsc2Uge1xuICAgICAgICB2YXIgYXJnc0xlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgIGlmIChhcmdzTGVuICUgMilcbiAgICAgICAgICAgIHRocm93IG5ldyBEb21TdG9yYWdlRXJyb3IoJ0RPTVN0b3JhZ2U6IHNldCBzaG91bGQgaGF2ZSBldmVuIG51bWJlciBvZiBhcmd1bWVudHMgb3Igb2JqZWN0Jyk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzTGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBhcmd1bWVudHNbaV1cbiAgICAgICAgICAgICAgICAsIHZhbHVlID0gYXJndW1lbnRzWysraV07XG5cbiAgICAgICAgICAgIHRoaXMuc2V0SXRlbShrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG4vKipcbiAqIEdldHMgZGF0YSBmcm9tIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBwYXNzZWQga2V5cywgYnV0IHJldHVybmVkIG9iamVjdCB3aWxsIGhhdmUga2V5cyB3aXRob3V0IHJvb3Qga2V5cy5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBrZXlzIGNhbiBiZSBwYXNzZWQgYXMgc3RyaW5ncyBvciBhcnJheXMgb2Ygc3RyaW5nc1xuICogQHJldHVybnMge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRnZXQoKSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBkYXRhID0ge307XG4gICAgXy5kZWVwRm9yRWFjaChhcmd1bWVudHMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBkYXRhW2tleV0gPSB0aGlzLmdldEl0ZW0oa2V5KTtcbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gZGF0YTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMga2V5cyBmcm9tIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBwYXNzZWQga2V5cy5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBrZXlzIGNhbiBiZSBwYXNzZWQgYXMgc3RyaW5ncyBvciBhcnJheXMgb2Ygc3RyaW5nc1xuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJHJlbW92ZSgpIHsgLy8sIC4uLiBhcmd1bWVudHNcbiAgICBfLmRlZXBGb3JFYWNoKGFyZ3VtZW50cywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHRoaXMucmVtb3ZlSXRlbShrZXkpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbi8qKlxuICogQ2hlY2sgZm9yIHByZXNlbmNlIG9mIHNpbmdsZSBpdGVtIGluIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBwYXNzZWQga2V5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkaGFzSXRlbShrZXkpIHtcbiAgICB2YXIgcEtleSA9IHRoaXMuX3N0b3JhZ2VLZXkoa2V5KTtcbiAgICByZXR1cm4gdGhpcy5fc3RvcmFnZS5nZXRJdGVtKHBLZXkpICE9IG51bGw7XG59XG5cblxuLyoqXG4gKiBHZXRzIHNpbmdsZSBpdGVtIGZyb20gRE9NIHN0b3JhZ2UgcHJlcGVuZGluZyBgdGhpcy5rZXlQcmVmaXhgIHRvIHBhc3NlZCBrZXkuXG4gKiBSZWFkcyB0eXBlIG9mIHRoZSBvcmlnaW5hbGx5IHN0b3JlZCB2YWx1ZSBmcm9tIGBrZXkgKyB0aGlzLl90eXBlU3VmZml4YCBhbmQgY29udmVydHMgZGF0YSB0byB0aGUgb3JpZ2luYWwgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkZ2V0SXRlbShrZXkpIHtcbiAgICB2YXIgcEtleSA9IHRoaXMuX3N0b3JhZ2VLZXkoa2V5KTtcbiAgICB2YXIgZGF0YVR5cGUgPSBfZ2V0S2V5RGF0YVR5cGUuY2FsbCh0aGlzLCBwS2V5KTtcbiAgICB2YXIgdmFsdWVTdHIgPSB0aGlzLl9zdG9yYWdlLmdldEl0ZW0ocEtleSk7XG4gICAgdmFyIHZhbHVlID0gX3BhcnNlRGF0YSh2YWx1ZVN0ciwgZGF0YVR5cGUpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuXG4vKipcbiAqIFNldHMgc2luZ2xlIGl0ZW0gdG8gRE9NIHN0b3JhZ2UgcHJlcGVuZGluZyBgdGhpcy5rZXlQcmVmaXhgIHRvIHBhc3NlZCBrZXkuXG4gKiBTdG9yZXMgdHlwZSBvZiB0aGUgc3RvcmVkIHZhbHVlIHRvIGBrZXkgKyB0aGlzLl90eXBlU3VmZml4YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2Ukc2V0SXRlbShrZXksIHZhbHVlKSB7XG4gICAgdmFyIHBLZXkgPSB0aGlzLl9zdG9yYWdlS2V5KGtleSk7XG4gICAgdmFyIGRhdGFUeXBlID0gX3NldEtleURhdGFUeXBlLmNhbGwodGhpcywgcEtleSwgdmFsdWUpO1xuICAgIHZhciB2YWx1ZVN0ciA9IF9zZXJpYWxpemVEYXRhKHZhbHVlLCBkYXRhVHlwZSk7XG4gICAgdHJ5IHtcbiAgICAgICAgdGhpcy5fc3RvcmFnZS5zZXRJdGVtKHBLZXksIHZhbHVlU3RyKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgaWYgKGUubmFtZSA9PSAnUXVvdGFFeGNlZWRlZEVycm9yJykge1xuICAgICAgICAgICAgdmFyIGNmZyA9IGNvbmZpZy5kb21TdG9yYWdlLnF1b3RhRXhjZWVkZWQ7XG4gICAgICAgICAgICBpZiAoY2ZnLm1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgbWlsby5tYWlsLnBvc3RNZXNzYWdlKCdxdW90YWV4Y2VlZGVkZXJyb3InLCB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoY2ZnLnRocm93RXJyb3IpXG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgIH1cbiAgICB0aGlzLl9rZXlzW2tleV0gPSB0cnVlO1xuICAgIF9kb21TdG9yYWdlW3RoaXMuc2Vzc2lvbk9ubHldLl9rZXlzW3BLZXldID0gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgc2luZ2xlIGl0ZW0gZnJvbSBET00gc3RvcmFnZSBwcmVwZW5kaW5nIGB0aGlzLmtleVByZWZpeGAgdG8gcGFzc2VkIGtleS5cbiAqIFR5cGUgb2YgdGhlIHN0b3JlZCB2YWx1ZSAoaW4gYGtleSArIHRoaXMuX3R5cGVTdWZmaXhgIGtleSkgaXMgYWxzbyByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRyZW1vdmVJdGVtKGtleSkge1xuICAgIHZhciBwS2V5ID0gdGhpcy5fc3RvcmFnZUtleShrZXkpO1xuICAgIHRoaXMuX3N0b3JhZ2UucmVtb3ZlSXRlbShwS2V5KTtcbiAgICBfcmVtb3ZlS2V5RGF0YVR5cGUuY2FsbCh0aGlzLCBwS2V5KVxuICAgIGRlbGV0ZSB0aGlzLl9rZXlzW2tleV07XG4gICAgZGVsZXRlIF9kb21TdG9yYWdlW3RoaXMuc2Vzc2lvbk9ubHldLl9rZXlzW3BLZXldO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgYXJyYXkgb2YgYWxsIGtleXMgc3RvcmVkIGJ5IHRoaXMgaW5zdGFuY2Ugb2YgRE9NU3RvcmFnZVxuICpcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJGdldEFsbEtleXMoKSB7XG4gICAgdmFyIHN0b3JlZEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLl9rZXlzKTtcbiAgICB2YXIga2V5c0luU3RvcmFnZSA9IHN0b3JlZEtleXMuZmlsdGVyKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAodGhpcy5oYXNJdGVtKGtleSkpIHJldHVybiB0cnVlO1xuICAgICAgICBlbHNlIGRlbGV0ZSB0aGlzLl9rZXlzW2tleV07XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIGtleXNJblN0b3JhZ2U7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXAgd2l0aCBhbGwga2V5cyBhbmQgdmFsdWVzIChkZXNlcmlhbGl6ZWQpIHN0b3JlZCB1c2luZyB0aGlzIGluc3RhbmNlIG9mIERPTVN0b3JhZ2VcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkZ2V0QWxsSXRlbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KHRoaXMuZ2V0QWxsS2V5cygpKTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgcHJlZml4ZWQga2V5IGZvciBET00gc3RvcmFnZSBmb3IgZ2l2ZW4gdW5wcmVmaXhlZCBrZXkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJF9zdG9yYWdlS2V5KGtleSkge1xuICAgIHJldHVybiB0aGlzLmtleVByZWZpeCArIGtleTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdW5wcmVmaXhlZCBrZXkgdG8gYmUgdXNlZCB3aXRoIHRoaXMgaW5zdGFuY2Ugb2YgRE9NU3RvcmFnZSBmaXIgZ2l2ZW4gYWN0dWFsIGtleSBpbiBzdG9yYWdlXG4gKiBJZiBrZXkgaGFzIGRpZmZlcmVudCBwcmVmaXggZnJvbSB0aGUga2V5UHJlZml4IHJldHVybnMgdW5kZWZpbmVkXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0b3JhZ2VLZXkgYWN0dWFsIGtleSBpbiBsb2NhbC9zZXNzaW9uIHN0b3JhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRfZG9tU3RvcmFnZUtleShzdG9yYWdlS2V5KSB7XG4gICAgaWYgKHN0b3JhZ2VLZXkuaW5kZXhPZih0aGlzLl90eXBlU3VmZml4KSA+PSAwKSByZXR1cm47XG4gICAgcmV0dXJuIF8udW5QcmVmaXgoc3RvcmFnZUtleSwgdGhpcy5rZXlQcmVmaXgpO1xufVxuXG5cbi8qKlxuICogR2V0cyBvcmlnaW5hbGx5IHN0b3JlZCBkYXRhIHR5cGUgZm9yIGdpdmVuIChwcmVmaXhlZCkgYGtleWAuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBwS2V5IHByZWZpeGVkIGtleSBvZiBzdG9yZWQgdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gX2dldEtleURhdGFUeXBlKHBLZXkpIHtcbiAgICBwS2V5ID0gX2RhdGFUeXBlS2V5LmNhbGwodGhpcywgcEtleSk7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2UuZ2V0SXRlbShwS2V5KTtcbn1cblxuXG4vKipcbiAqIFN0b3JlcyBkYXRhIHR5cGUgZm9yIGdpdmVuIChwcmVmaXhlZCkgYGtleWAgYW5kIGB2YWx1ZWAuXG4gKiBSZXR1cm5zIGRhdGEgdHlwZSBmb3IgYHZhbHVlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcEtleSBwcmVmaXhlZCBrZXkgb2Ygc3RvcmVkIHZhbHVlXG4gKiBAcGFyYW0ge0FueX0gdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gX3NldEtleURhdGFUeXBlKHBLZXksIHZhbHVlKSB7XG4gICAgdmFyIGRhdGFUeXBlID0gX2dldFZhbHVlVHlwZSh2YWx1ZSk7XG4gICAgcEtleSA9IF9kYXRhVHlwZUtleS5jYWxsKHRoaXMsIHBLZXkpO1xuICAgIHRoaXMuX3N0b3JhZ2Uuc2V0SXRlbShwS2V5LCBkYXRhVHlwZSk7XG4gICAgcmV0dXJuIGRhdGFUeXBlO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlcyBzdG9yZWQgZGF0YSB0eXBlIGZvciBnaXZlbiAocHJlZml4ZWQpIGBrZXlgLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gcEtleSBwcmVmaXhlZCBrZXkgb2Ygc3RvcmVkIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIF9yZW1vdmVLZXlEYXRhVHlwZShwS2V5KSB7XG4gICAgcEtleSA9IF9kYXRhVHlwZUtleS5jYWxsKHRoaXMsIHBLZXkpO1xuICAgIHRoaXMuX3N0b3JhZ2UucmVtb3ZlSXRlbShwS2V5KTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGtleSB0byBzdG9yZSBkYXRhIHR5cGUgZm9yIGdpdmVuIChwcmVmaXhlZCkgYGtleWAuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBwS2V5IHByZWZpeGVkIGtleSBvZiBzdG9yZWQgdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gX2RhdGFUeXBlS2V5KHBLZXkpIHtcbiAgICByZXR1cm4gcEtleSArIHRoaXMuX3R5cGVTdWZmaXg7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHR5cGUgb2YgdmFsdWUgYXMgc3RyaW5nLiBDbGFzcyBuYW1lIHJldHVybmVkIGZvciBvYmplY3RzICgnbnVsbCcgZm9yIG51bGwpLlxuICogQHBhcmFtICB7QW55fSB2YWx1ZVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBfZ2V0VmFsdWVUeXBlKHZhbHVlKSB7XG4gICAgdmFyIHZhbHVlVHlwZSA9IHR5cGVvZiB2YWx1ZVxuICAgICAgICAsIGNsYXNzTmFtZSA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLm5hbWVcbiAgICAgICAgLCBkYXRhVHlwZSA9IHZhbHVlc0RhdGFUeXBlc1tjbGFzc05hbWVdO1xuICAgIHJldHVybiBkYXRhVHlwZSB8fCAoXG4gICAgICAgICAgICB2YWx1ZVR5cGUgIT0gJ29iamVjdCdcbiAgICAgICAgICAgICAgICA/IHZhbHVlVHlwZVxuICAgICAgICAgICAgICAgIDogdmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/ICdudWxsJ1xuICAgICAgICAgICAgICAgICAgICA6IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUpO1xufVxudmFyIHZhbHVlc0RhdGFUeXBlcyA9IHtcbiAgICAvLyBjYW4gYmUgcmVnaXN0ZXJlZCB3aXRoIGByZWdpc3RlckRhdGFUeXBlYFxufVxuXG5cbi8qKlxuICogU2VyaWFsaXplcyB2YWx1ZSB0byBiZSBzdG9yZWQgaW4gRE9NIHN0b3JhZ2UuXG4gKlxuICogQHBhcmFtICB7QW55fSB2YWx1ZSB2YWx1ZSB0byBiZSBzZXJpYWxpemVkXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHZhbHVlVHlwZSBvcHRpb25hbCBkYXRhIHR5cGUgdG8gZGVmaW5lIHNlcmlhbGl6ZXIsIF9nZXRWYWx1ZVR5cGUgaXMgdXNlZCBpZiBub3QgcGFzc2VkLlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBfc2VyaWFsaXplRGF0YSh2YWx1ZSwgdmFsdWVUeXBlKSB7XG4gICAgdmFsdWVUeXBlID0gdmFsdWVUeXBlIHx8IF9nZXRWYWx1ZVR5cGUodmFsdWUpO1xuICAgIHZhciBzZXJpYWxpemVyID0gZGF0YVNlcmlhbGl6ZXJzW3ZhbHVlVHlwZV07XG4gICAgcmV0dXJuIHNlcmlhbGl6ZXJcbiAgICAgICAgICAgID8gc2VyaWFsaXplcih2YWx1ZSwgdmFsdWVUeXBlKVxuICAgICAgICAgICAgOiB2YWx1ZSAmJiB2YWx1ZS50b1N0cmluZyA9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSlcbiAgICAgICAgICAgICAgICA6ICcnICsgdmFsdWU7XG59XG52YXIgZGF0YVNlcmlhbGl6ZXJzID0ge1xuICAgICdBcnJheSc6IEpTT04uc3RyaW5naWZ5XG59XG5cblxuLyoqXG4gKiBQYXJzZXMgc3RyaW5nIHJldHJpZXZlZCBmcm9tIERPTSBzdG9yYWdlLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdmFsdWVTdHJcbiAqIEBwYXJhbSAge1N0cmluZ30gdmFsdWVUeXBlIGRhdGEgdHlwZSB0aGF0IGRlZmluZXMgcGFyc2VyLiBPcmlnaW5hbCBzcmluZyB3aWxsIGJlIHJldHVybmVkIGlmIHBhcnNlciBpcyBub3QgZGVmaW5lZC5cbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gX3BhcnNlRGF0YSh2YWx1ZVN0ciwgdmFsdWVUeXBlKSB7XG4gICAgdmFyIHBhcnNlciA9IGRhdGFQYXJzZXJzW3ZhbHVlVHlwZV07XG4gICAgcmV0dXJuIHBhcnNlclxuICAgICAgICAgICAgPyBwYXJzZXIodmFsdWVTdHIsIHZhbHVlVHlwZSlcbiAgICAgICAgICAgIDogdmFsdWVTdHI7XG59XG52YXIgZGF0YVBhcnNlcnMgPSB7XG4gICAgT2JqZWN0OiBqc29uUGFyc2UsXG4gICAgQXJyYXk6IGpzb25QYXJzZSxcbiAgICBEYXRlOiBmdW5jdGlvbih2YWxTdHIpIHsgcmV0dXJuIG5ldyBEYXRlKHZhbFN0cik7IH0sXG4gICAgYm9vbGVhbjogZnVuY3Rpb24odmFsU3RyKSB7IHJldHVybiB2YWxTdHIgPT0gJ3RydWUnOyB9LFxuICAgIG51bWJlcjogZnVuY3Rpb24odmFsU3RyKSB7IHJldHVybiBOdW1iZXIodmFsU3RyKTsgfSxcbiAgICBmdW5jdGlvbjogZnVuY3Rpb24odmFsU3RyKSB7IHJldHVybiBfLnRvRnVuY3Rpb24odmFsU3RyKTsgfSxcbiAgICBSZWdFeHA6IGZ1bmN0aW9uKHZhbFN0cikgeyByZXR1cm4gXy50b1JlZ0V4cCh2YWxTdHIpOyB9XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXJzIGRhdGEgdHlwZSB0byBiZSBzYXZlZCBpbiBET00gc3RvcmFnZS4gQ2xhc3MgbmFtZSBjYW4gYmUgdXNlZCBvciByZXN1bHQgb2YgYHR5cGVvZmAgb3BlcmF0b3IgZm9yIG5vbi1vYmplY3RzIHRvIG92ZXJyaWRlIGRlZmF1bHQgY29udmVyc2lvbnMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlVHlwZSBjbGFzcyAoY29uc3RydWN0b3IpIG5hbWUgb3IgdGhlIHN0cmluZyByZXR1cm5lZCBieSB0eXBlb2YuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXJpYWxpemVyIG9wdGlvbmFsIHNlcmlhbGl6ZXIgZm9yIHRoaXMgdHlwZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gcGFyc2VyIG9wdGlvbmFsIHBhcnNlciBmb3IgdGhpcyB0eXBlXG4gKiBAcGFyYW0ge1tTdHJpbmddfSBzdG9yZUFzRGF0YVR5cGUgb3B0aW9uYWwgbmFtZSBvZiBzdG9yZWQgZGF0YSB0eXBlIGlmIGRpZmZlcmVudCBmcm9tIHZhbHVlVHlwZVxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJCRyZWdpc3RlckRhdGFUeXBlKHZhbHVlVHlwZSwgc2VyaWFsaXplciwgcGFyc2VyLCBzdG9yZUFzRGF0YVR5cGUpIHtcbiAgICBpZiAoc2VyaWFsaXplcikgZGF0YVNlcmlhbGl6ZXJzW3ZhbHVlVHlwZV0gPSBzZXJpYWxpemVyO1xuICAgIGlmIChwYXJzZXIpIGRhdGFQYXJzZXJzW3ZhbHVlVHlwZV0gPSBwYXJzZXI7XG4gICAgdmFsdWVzRGF0YVR5cGVzW3ZhbHVlVHlwZV0gPSBzdG9yZUFzRGF0YVR5cGUgfHwgdmFsdWVUeXBlO1xufVxuXG5cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkY3JlYXRlTWVzc2VuZ2VyKCkge1xuICAgIHZhciBzdG9yYWdlTWVzc2FnZVNvdXJjZSA9IG5ldyBTdG9yYWdlTWVzc2FnZVNvdXJjZSh0aGlzKTtcbiAgICB2YXIgbWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzLCB1bmRlZmluZWQsIHN0b3JhZ2VNZXNzYWdlU291cmNlKTtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfbWVzc2VuZ2VyOiBtZXNzZW5nZXIsXG4gICAgICAgIF9tZXNzYWdlU291cmNlOiBzdG9yYWdlTWVzc2FnZVNvdXJjZVxuICAgIH0sIF8uV1JJVCk7XG59XG5cblxuZnVuY3Rpb24gRE9NU3RvcmFnZSRkZXN0cm95KCkge1xuICAgIHRoaXMuX3N0b3JhZ2UgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53aW5kb3cgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuX21lc3NlbmdlcikgdGhpcy5fbWVzc2VuZ2VyLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyL21fc291cmNlJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnJylcbiAgICAsIG1pbG9Db3VudCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY291bnQnKVxuICAgICwgU3RvcmFnZU1lc3NhZ2VTb3VyY2VFcnJvciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZXJyb3InKS5TdG9yYWdlTWVzc2FnZVNvdXJjZTtcblxudmFyIFN0b3JhZ2VNZXNzYWdlU291cmNlID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzYWdlU291cmNlLCAnU3RvcmFnZU1lc3NhZ2VTb3VyY2UnLCB0cnVlKTtcblxuXG5fLmV4dGVuZFByb3RvKFN0b3JhZ2VNZXNzYWdlU291cmNlLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgaW5pdDogaW5pdCxcbiAgICBhZGRTb3VyY2VTdWJzY3JpYmVyOiBTdG9yYWdlTWVzc2FnZVNvdXJjZSRhZGRTb3VyY2VTdWJzY3JpYmVyLFxuICAgIHJlbW92ZVNvdXJjZVN1YnNjcmliZXI6IFN0b3JhZ2VNZXNzYWdlU291cmNlJHJlbW92ZVNvdXJjZVN1YnNjcmliZXIsXG4gICAgcG9zdE1lc3NhZ2U6IFN0b3JhZ2VNZXNzYWdlU291cmNlJHBvc3RNZXNzYWdlLFxuICAgIHRyaWdnZXI6IFN0b3JhZ2VNZXNzYWdlU291cmNlJHRyaWdnZXIsXG5cbiAgICAvL2NsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICBoYW5kbGVFdmVudDogaGFuZGxlRXZlbnQgIC8vIGV2ZW50IGRpc3BhdGNoZXIgLSBhcyBkZWZpbmVkIGJ5IEV2ZW50IERPTSBBUElcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0b3JhZ2VNZXNzYWdlU291cmNlO1xuXG5cbmZ1bmN0aW9uIGluaXQoaG9zdE9iamVjdCwgcHJveHlNZXRob2RzLCBtZXNzZW5nZXJBUElPckNsYXNzKSB7XG4gICAgaWYgKGhvc3RPYmplY3QuY29uc3RydWN0b3IubmFtZSAhPSAnRE9NU3RvcmFnZScpXG4gICAgICAgIHRocm93IG5ldyBTdG9yYWdlTWVzc2FnZVNvdXJjZUVycm9yKCdob3N0T2JqZWN0IHNob3VsZCBiZSBhbiBpbnN0YW5jZSBvZiBET01TdG9yYWdlJyk7XG4gICAgdGhpcy5zdG9yYWdlID0gaG9zdE9iamVjdDtcbiAgICB0aGlzLm1lc3NhZ2VLZXkgPSBjb25maWcuZG9tU3RvcmFnZS5tZXNzYWdlS2V5O1xuICAgIHRoaXMud2luZG93ID0gaG9zdE9iamVjdC53aW5kb3c7XG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIFN0b3JhZ2VNZXNzYWdlU291cmNlJGFkZFNvdXJjZVN1YnNjcmliZXIoc291cmNlTWVzc2FnZSkge1xuICAgIHRoaXMud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3N0b3JhZ2UnLCB0aGlzLCBmYWxzZSk7XG59XG5cblxuZnVuY3Rpb24gU3RvcmFnZU1lc3NhZ2VTb3VyY2UkcmVtb3ZlU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgdGhpcy53aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RvcmFnZScsIHRoaXMsIGZhbHNlKTtcbn1cblxuXG5mdW5jdGlvbiBTdG9yYWdlTWVzc2FnZVNvdXJjZSRwb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhKSB7XG4gICAgdGhpcy5tZXNzZW5nZXIucG9zdE1lc3NhZ2VTeW5jKG1lc3NhZ2UsIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIFN0b3JhZ2VNZXNzYWdlU291cmNlJHRyaWdnZXIobXNnVHlwZSwgZGF0YSkge1xuICAgIHZhciBrZXkgPSB0aGlzLm1lc3NhZ2VLZXkgKyBtc2dUeXBlO1xuICAgIGRhdGEgPSBkYXRhIHx8IHt9O1xuICAgIGRhdGFbY29uZmlnLmRvbVN0b3JhZ2UubWVzc2FnZVRpbWVzdGFtcF0gPSBtaWxvQ291bnQoKTtcbiAgICBfLmRlZmVyTWV0aG9kKHRoaXMuc3RvcmFnZSwgJ3NldEl0ZW0nLCBrZXksIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIGhhbmRsZUV2ZW50KGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnN0b3JhZ2VBcmVhICE9IHRoaXMuc3RvcmFnZS5fc3RvcmFnZSkgcmV0dXJuO1xuICAgIHZhciBrZXkgPSB0aGlzLnN0b3JhZ2UuX2RvbVN0b3JhZ2VLZXkoZXZlbnQua2V5KTsgaWYgKCEga2V5KSByZXR1cm47XG4gICAgdmFyIG1zZ1R5cGUgPSBfLnVuUHJlZml4KGtleSwgdGhpcy5tZXNzYWdlS2V5KTsgaWYgKCEgbXNnVHlwZSkgcmV0dXJuO1xuICAgIHZhciBkYXRhID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oa2V5KTsgaWYgKCEgZGF0YSkgcmV0dXJuO1xuICAgIHRoaXMuZGlzcGF0Y2hNZXNzYWdlKG1zZ1R5cGUsIGRhdGEpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBtaWxvLnV0aWwud2Vic29ja2V0YCBcbioqL1xuXG5cbnZhciBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXInKVxuICAgICwgV1NNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi9tc2dfc3JjJylcbiAgICAsIFdTTXNnQVBJID0gcmVxdWlyZSgnLi9tc2dfYXBpJyk7XG5cblxuZnVuY3Rpb24gd2Vic29ja2V0KCkge1xuICAgIHZhciB3c01lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXI7XG4gICAgdmFyIHdzTXNnU291cmNlID0gbmV3IFdTTWVzc2FnZVNvdXJjZSh3c01lc3NlbmdlciwgeyBzZW5kOiAndHJpZ2dlcicsIGNvbm5lY3Q6ICdjb25uZWN0JyB9LCBuZXcgV1NNc2dBUEkpO1xuICAgIHdzTWVzc2VuZ2VyLl9zZXRNZXNzYWdlU291cmNlKHdzTXNnU291cmNlKTtcbiAgICByZXR1cm4gd3NNZXNzZW5nZXI7XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSB3ZWJzb2NrZXQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNZXNzZW5nZXJBUEkgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXIvbV9hcGknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG52YXIgV1NNc2dBUEkgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NlbmdlckFQSSwgJ1dTTXNnQVBJJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhXU01zZ0FQSSwge1xuICAgIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZTogdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlLFxuICAgIGZpbHRlclNvdXJjZU1lc3NhZ2U6IGZpbHRlclNvdXJjZU1lc3NhZ2UsXG4gICAgY3JlYXRlSW50ZXJuYWxEYXRhOiBjcmVhdGVJbnRlcm5hbERhdGFcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdTTXNnQVBJO1xuXG5cbnZhciBTT0NLRVRfTUVTU0FHRVMgPSBbJ29wZW4nLCAnY2xvc2UnLCAnZXJyb3InLCAnbWVzc2FnZSddO1xuXG5mdW5jdGlvbiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHJldHVybiBTT0NLRVRfTUVTU0FHRVMuaW5kZXhPZihtZXNzYWdlKSA+PSAwXG4gICAgICAgICAgICA/IG1lc3NhZ2VcbiAgICAgICAgICAgIDogJ21lc3NhZ2UnO1xufVxuXG5cbmZ1bmN0aW9uIGZpbHRlclNvdXJjZU1lc3NhZ2Uoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgbXNnRGF0YSkge1xuICAgIGlmIChTT0NLRVRfTUVTU0FHRVMuaW5kZXhPZihtZXNzYWdlKSA+PSAwKSByZXR1cm4gdHJ1ZTsgLy8gaW50ZXJuYWwgbWVzc2FnZSBpcyBvbmUgb2YgZXh0ZXJuYWwgbWVzc2FnZXNcbiAgICBpZiAoc291cmNlTWVzc2FnZSA9PSAnbWVzc2FnZScpIHtcbiAgICAgICAgdmFyIG1zZ1R5cGUgPSBtc2dEYXRhICYmIG1zZ0RhdGEudHlwZTtcbiAgICAgICAgcmV0dXJuIG1zZ1R5cGUgPT0gbWVzc2FnZTsgLy8gdHlwZSBlcXVhbHMgaW50ZXJuYWwgbWVzc2FnZVxuICAgIH1cbn07XG5cblxuZnVuY3Rpb24gY3JlYXRlSW50ZXJuYWxEYXRhKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIGV2ZW50KSB7XG4gICAgdmFyIGludGVybmFsRGF0YSA9IHNvdXJjZU1lc3NhZ2UgPT0gJ21lc3NhZ2UnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IF8uanNvblBhcnNlKGV2ZW50LmRhdGEpIHx8IGV2ZW50LmRhdGFcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZXZlbnQ7XG4gICAgcmV0dXJuIGludGVybmFsRGF0YTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4uLy4uL21lc3Nlbmdlci9tX3NvdXJjZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIHVuaXF1ZUlkID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jb3VudCcpXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi8uLi9jb25maWcnKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxudmFyIFdTTWVzc2FnZVNvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2FnZVNvdXJjZSwgJ1dTTWVzc2FnZVNvdXJjZScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oV1NNZXNzYWdlU291cmNlLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogYWRkU291cmNlU3Vic2NyaWJlcixcbiAgICByZW1vdmVTb3VyY2VTdWJzY3JpYmVyOiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyLFxuICAgIFxuICAgIC8vIGNsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICBoYW5kbGVFdmVudDogV1NNZXNzYWdlU291cmNlJGhhbmRsZUV2ZW50LFxuICAgIGNvbm5lY3Q6IFdTTWVzc2FnZVNvdXJjZSRjb25uZWN0LFxuICAgIHRyaWdnZXI6IFdTTWVzc2FnZVNvdXJjZSR0cmlnZ2VyXG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFdTTWVzc2FnZVNvdXJjZTtcblxuXG5mdW5jdGlvbiBXU01lc3NhZ2VTb3VyY2UkY29ubmVjdChvcHRpb25zKSB7XG4gICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgdmFyIGhvc3QgPSBvcHRpb25zLmhvc3QgfHwgd2luZG93LmxvY2F0aW9uLmhvc3QucmVwbGFjZSgvOi4qLywgJycpXG4gICAgICAgICwgcG9ydCA9IG9wdGlvbnMucG9ydCB8fCAnODA4MCc7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAodGhpcy5fd3MpIHtcbiAgICAgICAgLy8gVE9ETyBzaG91bGQgdW5zdWJzY3JpYmUgZGlmZmVyZW50bHlcbiAgICAgICAgdGhpcy5fd3Mub25vcGVuID0gdGhpcy53cy5vbm1lc3NhZ2UgPSB0aGlzLndzLm9uY2xvc2UgPSB0aGlzLndzLm9uZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3dzLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fd3MgPSBuZXcgV2ViU29ja2V0KCd3czovLycgKyBob3N0ICsgJzonICsgcG9ydCk7XG5cbiAgICAvLyBUT0RPIHJlY29ubmVjdFxufVxuXG5cblxuZnVuY3Rpb24gYWRkU291cmNlU3Vic2NyaWJlciAoc291cmNlTWVzc2FnZSkge1xuICAgIF93c1N1YnNjcmliZXJNZXRob2QuY2FsbCh0aGlzLCAnYWRkRXZlbnRMaXN0ZW5lcicsIHNvdXJjZU1lc3NhZ2UpO1xufVxuXG5cbmZ1bmN0aW9uIHJlbW92ZVNvdXJjZVN1YnNjcmliZXIgKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICBfd3NTdWJzY3JpYmVyTWV0aG9kLmNhbGwodGhpcywgJ3JlbW92ZUV2ZW50TGlzdGVuZXInLCBzb3VyY2VNZXNzYWdlKTtcbn1cblxuXG5mdW5jdGlvbiBfd3NTdWJzY3JpYmVyTWV0aG9kIChtZXRob2QsIHNvdXJjZU1lc3NhZ2UpIHsgICAgXG4gICAgaWYgKCF0aGlzLl93cykgcmV0dXJuIGxvZ2dlci5lcnJvcignd2Vic29ja2V0IGlzIG5vdCBjcmVhdGVkJyk7XG4gICAgdGhpcy5fd3NbbWV0aG9kXShzb3VyY2VNZXNzYWdlLCB0aGlzKTtcbn1cblxuXG4vLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG5mdW5jdGlvbiBXU01lc3NhZ2VTb3VyY2UkaGFuZGxlRXZlbnQgKGV2ZW50KSB7XG4gICAgdGhpcy5kaXNwYXRjaE1lc3NhZ2UoZXZlbnQudHlwZSwgZXZlbnQpO1xufVxuXG5cbmZ1bmN0aW9uIFdTTWVzc2FnZVNvdXJjZSR0cmlnZ2VyIChtc2csIGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCF0aGlzLl93cykgcmV0dXJuIGxvZ2dlci5lcnJvcignd2Vic29ja2V0IGlzIG5vdCBjcmVhdGVkJyk7XG5cbiAgICBkYXRhID0gZGF0YSB8fCB7fTtcbiAgICBkYXRhLnR5cGUgPSBtc2c7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgXG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIGRhdGEuY2FsbGJhY2tDb3JySWQgPSB1bmlxdWVJZCgpO1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSBfLmRlbGF5KG9uVGltZW91dCwgY29uZmlnLndlYnNvY2tldC5ycGMudGltZW91dCk7XG4gICAgICAgIHRvZ2dsZVJwY1N1YnNjcmlwdGlvbignb25jZScsIGRhdGEuY2FsbGJhY2tDb3JySWQpO1xuICAgIH0gICAgXG5cbiAgICB0aGlzLl93cy5zZW5kKEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcblxuXG4gICAgZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgICB0b2dnbGVScGNTdWJzY3JpcHRpb24oJ29mZicsIGRhdGEuY2FsbGJhY2tDb3JySWQpO1xuICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ3dlYnNvY2tldCBycGM6IHRpbWVvdXQnKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25SZXNwb25zZShtc2csIG1zZ0RhdGEpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgIGlmICh0eXBlb2YgbXNnRGF0YSA9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdmFyIGVyciA9IG1zZ0RhdGEuZXJyb3IgPyBuZXcgRXJyb3IobXNnRGF0YS5lcnJvcikgOiBudWxsO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBtc2dEYXRhLmRhdGEpXG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgY2FsbGJhY2sobmV3IEVycm9yKCd3ZWJzb2NrZXQgcnBjOiBpbnZhbGlkIHJlc3BvbnNlIGRhdGEnKSwgbXNnRGF0YSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9nZ2xlUnBjU3Vic2NyaXB0aW9uKG9uT2ZmLCBjb3JySWQpIHtcbiAgICAgICAgc2VsZi5tZXNzZW5nZXJbb25PZmZdKGNvbmZpZy53ZWJzb2NrZXQucnBjLnJlc3BvbnNlUHJlZml4ICsgY29ycklkLCBvblJlc3BvbnNlKTtcbiAgICB9XG59XG4iLCI7KGZ1bmN0aW9uKCl7XG5cbi8vIFRoaXMgd291bGQgYmUgdGhlIHBsYWNlIHRvIGVkaXQgaWYgeW91IHdhbnQgYSBkaWZmZXJlbnRcbi8vIEJhc2UzMiBpbXBsZW1lbnRhdGlvblxuXG52YXIgYWxwaGFiZXQgPSAnMDEyMzQ1Njc4OWFiY2RlZmdoamttbnBxcnR1dnd4eXonXG52YXIgYWxpYXMgPSB7IG86MCwgaToxLCBsOjEsIHM6NSB9XG5cbi8qKlxuICogQnVpbGQgYSBsb29rdXAgdGFibGUgYW5kIG1lbW9pemUgaXRcbiAqXG4gKiBSZXR1cm4gYW4gb2JqZWN0IHRoYXQgbWFwcyBhIGNoYXJhY3RlciB0byBpdHNcbiAqIGJ5dGUgdmFsdWUuXG4gKi9cblxudmFyIGxvb2t1cCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0YWJsZSA9IHt9XG4gICAgLy8gSW52ZXJ0ICdhbHBoYWJldCdcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFscGhhYmV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRhYmxlW2FscGhhYmV0W2ldXSA9IGlcbiAgICB9XG4gICAgLy8gU3BsaWNlIGluICdhbGlhcydcbiAgICBmb3IgKHZhciBrZXkgaW4gYWxpYXMpIHtcbiAgICAgICAgaWYgKCFhbGlhcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZVxuICAgICAgICB0YWJsZVtrZXldID0gdGFibGVbJycgKyBhbGlhc1trZXldXVxuICAgIH1cbiAgICBsb29rdXAgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRhYmxlIH1cbiAgICByZXR1cm4gdGFibGVcbn1cblxuLyoqXG4gKiBBIHN0cmVhbWluZyBlbmNvZGVyXG4gKlxuICogICAgIHZhciBlbmNvZGVyID0gbmV3IGJhc2UzMi5FbmNvZGVyKClcbiAqICAgICB2YXIgb3V0cHV0MSA9IGVuY29kZXIudXBkYXRlKGlucHV0MSlcbiAqICAgICB2YXIgb3V0cHV0MiA9IGVuY29kZXIudXBkYXRlKGlucHV0MilcbiAqICAgICB2YXIgbGFzdG91dHB1dCA9IGVuY29kZS51cGRhdGUobGFzdGlucHV0LCB0cnVlKVxuICovXG5cbmZ1bmN0aW9uIEVuY29kZXIoKSB7XG4gICAgdmFyIHNraXAgPSAwIC8vIGhvdyBtYW55IGJpdHMgd2Ugd2lsbCBza2lwIGZyb20gdGhlIGZpcnN0IGJ5dGVcbiAgICB2YXIgYml0cyA9IDAgLy8gNSBoaWdoIGJpdHMsIGNhcnJ5IGZyb20gb25lIGJ5dGUgdG8gdGhlIG5leHRcblxuICAgIHRoaXMub3V0cHV0ID0gJydcblxuICAgIC8vIFJlYWQgb25lIGJ5dGUgb2YgaW5wdXRcbiAgICAvLyBTaG91bGQgbm90IHJlYWxseSBiZSB1c2VkIGV4Y2VwdCBieSBcInVwZGF0ZVwiXG4gICAgdGhpcy5yZWFkQnl0ZSA9IGZ1bmN0aW9uKGJ5dGUpIHtcbiAgICAgICAgLy8gY29lcmNlIHRoZSBieXRlIHRvIGFuIGludFxuICAgICAgICBpZiAodHlwZW9mIGJ5dGUgPT0gJ3N0cmluZycpIGJ5dGUgPSBieXRlLmNoYXJDb2RlQXQoMClcblxuICAgICAgICBpZiAoc2tpcCA8IDApIHsgLy8gd2UgaGF2ZSBhIGNhcnJ5IGZyb20gdGhlIHByZXZpb3VzIGJ5dGVcbiAgICAgICAgICAgIGJpdHMgfD0gKGJ5dGUgPj4gKC1za2lwKSlcbiAgICAgICAgfSBlbHNlIHsgLy8gbm8gY2FycnlcbiAgICAgICAgICAgIGJpdHMgPSAoYnl0ZSA8PCBza2lwKSAmIDI0OFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNraXAgPiAzKSB7XG4gICAgICAgICAgICAvLyBub3QgZW5vdWdoIGRhdGEgdG8gcHJvZHVjZSBhIGNoYXJhY3RlciwgZ2V0IHVzIGFub3RoZXIgb25lXG4gICAgICAgICAgICBza2lwIC09IDhcbiAgICAgICAgICAgIHJldHVybiAxXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2tpcCA8IDQpIHtcbiAgICAgICAgICAgIC8vIHByb2R1Y2UgYSBjaGFyYWN0ZXJcbiAgICAgICAgICAgIHRoaXMub3V0cHV0ICs9IGFscGhhYmV0W2JpdHMgPj4gM11cbiAgICAgICAgICAgIHNraXAgKz0gNVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIDBcbiAgICB9XG5cbiAgICAvLyBGbHVzaCBhbnkgcmVtYWluaW5nIGJpdHMgbGVmdCBpbiB0aGUgc3RyZWFtXG4gICAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbihjaGVjaykge1xuICAgICAgICB2YXIgb3V0cHV0ID0gdGhpcy5vdXRwdXQgKyAoc2tpcCA8IDAgPyBhbHBoYWJldFtiaXRzID4+IDNdIDogJycpICsgKGNoZWNrID8gJyQnIDogJycpXG4gICAgICAgIHRoaXMub3V0cHV0ID0gJydcbiAgICAgICAgcmV0dXJuIG91dHB1dFxuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9jZXNzIGFkZGl0aW9uYWwgaW5wdXRcbiAqXG4gKiBpbnB1dDogc3RyaW5nIG9mIGJ5dGVzIHRvIGNvbnZlcnRcbiAqIGZsdXNoOiBib29sZWFuLCBzaG91bGQgd2UgZmx1c2ggYW55IHRyYWlsaW5nIGJpdHMgbGVmdFxuICogICAgICAgIGluIHRoZSBzdHJlYW1cbiAqIHJldHVybnM6IGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50aW5nICdpbnB1dCcgaW4gYmFzZTMyXG4gKi9cblxuRW5jb2Rlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24oaW5wdXQsIGZsdXNoKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7ICkge1xuICAgICAgICBpICs9IHRoaXMucmVhZEJ5dGUoaW5wdXRbaV0pXG4gICAgfVxuICAgIC8vIGNvbnN1bWUgYWxsIG91dHB1dFxuICAgIHZhciBvdXRwdXQgPSB0aGlzLm91dHB1dFxuICAgIHRoaXMub3V0cHV0ID0gJydcbiAgICBpZiAoZmx1c2gpIHtcbiAgICAgIG91dHB1dCArPSB0aGlzLmZpbmlzaCgpXG4gICAgfVxuICAgIHJldHVybiBvdXRwdXRcbn1cblxuLy8gRnVuY3Rpb25zIGFuYWxvZ291c2x5IHRvIEVuY29kZXJcblxuZnVuY3Rpb24gRGVjb2RlcigpIHtcbiAgICB2YXIgc2tpcCA9IDAgLy8gaG93IG1hbnkgYml0cyB3ZSBoYXZlIGZyb20gdGhlIHByZXZpb3VzIGNoYXJhY3RlclxuICAgIHZhciBieXRlID0gMCAvLyBjdXJyZW50IGJ5dGUgd2UncmUgcHJvZHVjaW5nXG5cbiAgICB0aGlzLm91dHB1dCA9ICcnXG5cbiAgICAvLyBDb25zdW1lIGEgY2hhcmFjdGVyIGZyb20gdGhlIHN0cmVhbSwgc3RvcmVcbiAgICAvLyB0aGUgb3V0cHV0IGluIHRoaXMub3V0cHV0LiBBcyBiZWZvcmUsIGJldHRlclxuICAgIC8vIHRvIHVzZSB1cGRhdGUoKS5cbiAgICB0aGlzLnJlYWRDaGFyID0gZnVuY3Rpb24oY2hhcikge1xuICAgICAgICBpZiAodHlwZW9mIGNoYXIgIT0gJ3N0cmluZycpe1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyID09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgY2hhciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjaGFyID0gY2hhci50b0xvd2VyQ2FzZSgpXG4gICAgICAgIHZhciB2YWwgPSBsb29rdXAoKVtjaGFyXVxuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgLy8gY2hhcmFjdGVyIGRvZXMgbm90IGV4aXN0IGluIG91ciBsb29rdXAgdGFibGVcbiAgICAgICAgICAgIHJldHVybiAvLyBza2lwIHNpbGVudGx5LiBBbiBhbHRlcm5hdGl2ZSB3b3VsZCBiZTpcbiAgICAgICAgICAgIC8vIHRocm93IEVycm9yKCdDb3VsZCBub3QgZmluZCBjaGFyYWN0ZXIgXCInICsgY2hhciArICdcIiBpbiBsb29rdXAgdGFibGUuJylcbiAgICAgICAgfVxuICAgICAgICB2YWwgPDw9IDMgLy8gbW92ZSB0byB0aGUgaGlnaCBiaXRzXG4gICAgICAgIGJ5dGUgfD0gdmFsID4+PiBza2lwXG4gICAgICAgIHNraXAgKz0gNVxuICAgICAgICBpZiAoc2tpcCA+PSA4KSB7XG4gICAgICAgICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBwcmVkdWNlIG91dHB1dFxuICAgICAgICAgICAgdGhpcy5vdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlKVxuICAgICAgICAgICAgc2tpcCAtPSA4XG4gICAgICAgICAgICBpZiAoc2tpcCA+IDApIGJ5dGUgPSAodmFsIDw8ICg1IC0gc2tpcCkpICYgMjU1XG4gICAgICAgICAgICBlbHNlIGJ5dGUgPSAwXG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIHRoaXMuZmluaXNoID0gZnVuY3Rpb24oY2hlY2spIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMub3V0cHV0ICsgKHNraXAgPCAwID8gYWxwaGFiZXRbYml0cyA+PiAzXSA6ICcnKSArIChjaGVjayA/ICckJyA6ICcnKVxuICAgICAgICB0aGlzLm91dHB1dCA9ICcnXG4gICAgICAgIHJldHVybiBvdXRwdXRcbiAgICB9XG59XG5cbkRlY29kZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGlucHV0LCBmbHVzaCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5yZWFkQ2hhcihpbnB1dFtpXSlcbiAgICB9XG4gICAgdmFyIG91dHB1dCA9IHRoaXMub3V0cHV0XG4gICAgdGhpcy5vdXRwdXQgPSAnJ1xuICAgIGlmIChmbHVzaCkge1xuICAgICAgb3V0cHV0ICs9IHRoaXMuZmluaXNoKClcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dFxufVxuXG4vKiogQ29udmVuaWVuY2UgZnVuY3Rpb25zXG4gKlxuICogVGhlc2UgYXJlIHRoZSBvbmVzIHRvIHVzZSBpZiB5b3UganVzdCBoYXZlIGEgc3RyaW5nIGFuZFxuICogd2FudCB0byBjb252ZXJ0IGl0IHdpdGhvdXQgZGVhbGluZyB3aXRoIHN0cmVhbXMgYW5kIHdoYXRub3QuXG4gKi9cblxuLy8gU3RyaW5nIG9mIGRhdGEgZ29lcyBpbiwgQmFzZTMyLWVuY29kZWQgc3RyaW5nIGNvbWVzIG91dC5cbmZ1bmN0aW9uIGVuY29kZShpbnB1dCkge1xuICB2YXIgZW5jb2RlciA9IG5ldyBFbmNvZGVyKClcbiAgdmFyIG91dHB1dCA9IGVuY29kZXIudXBkYXRlKGlucHV0LCB0cnVlKVxuICByZXR1cm4gb3V0cHV0XG59XG5cbi8vIEJhc2UzMi1lbmNvZGVkIHN0cmluZyBnb2VzIGluLCBkZWNvZGVkIGRhdGEgY29tZXMgb3V0LlxuZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG4gICAgdmFyIGRlY29kZXIgPSBuZXcgRGVjb2RlcigpXG4gICAgdmFyIG91dHB1dCA9IGRlY29kZXIudXBkYXRlKGlucHV0LCB0cnVlKVxuICAgIHJldHVybiBvdXRwdXRcbn1cblxudmFyIGJhc2UzMiA9IHtcbiAgICBEZWNvZGVyOiBEZWNvZGVyLFxuICAgIEVuY29kZXI6IEVuY29kZXIsXG4gICAgZW5jb2RlOiBlbmNvZGUsXG4gICAgZGVjb2RlOiBkZWNvZGVcbn1cblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gIC8vIHdlJ3JlIGluIGEgYnJvd3NlciAtIE9NRyFcbiAgd2luZG93LmJhc2UzMiA9IGJhc2UzMlxufVxuXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgLy8gbm9kZWpzL2Jyb3dzZXJpZnlcbiAgbW9kdWxlLmV4cG9ydHMgPSBiYXNlMzJcbn1cbn0pKCk7XG4iLCJcbi8vIG5vdCBpbXBsZW1lbnRlZFxuLy8gVGhlIHJlYXNvbiBmb3IgaGF2aW5nIGFuIGVtcHR5IGZpbGUgYW5kIG5vdCB0aHJvd2luZyBpcyB0byBhbGxvd1xuLy8gdW50cmFkaXRpb25hbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1vZHVsZS5cbiIsIi8vIGRvVC5qc1xuLy8gMjAxMS0yMDE0LCBMYXVyYSBEb2t0b3JvdmEsIGh0dHBzOi8vZ2l0aHViLmNvbS9vbGFkby9kb1Rcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cblxuKGZ1bmN0aW9uKCkge1xuXHRcInVzZSBzdHJpY3RcIjtcblxuXHR2YXIgZG9UID0ge1xuXHRcdHZlcnNpb246IFwiMS4wLjNcIixcblx0XHR0ZW1wbGF0ZVNldHRpbmdzOiB7XG5cdFx0XHRldmFsdWF0ZTogICAgL1xce1xceyhbXFxzXFxTXSs/KFxcfT8pKylcXH1cXH0vZyxcblx0XHRcdGludGVycG9sYXRlOiAvXFx7XFx7PShbXFxzXFxTXSs/KVxcfVxcfS9nLFxuXHRcdFx0ZW5jb2RlOiAgICAgIC9cXHtcXHshKFtcXHNcXFNdKz8pXFx9XFx9L2csXG5cdFx0XHR1c2U6ICAgICAgICAgL1xce1xceyMoW1xcc1xcU10rPylcXH1cXH0vZyxcblx0XHRcdHVzZVBhcmFtczogICAvKF58W15cXHckXSlkZWYoPzpcXC58XFxbW1xcJ1xcXCJdKShbXFx3JFxcLl0rKSg/OltcXCdcXFwiXVxcXSk/XFxzKlxcOlxccyooW1xcdyRcXC5dK3xcXFwiW15cXFwiXStcXFwifFxcJ1teXFwnXStcXCd8XFx7W15cXH1dK1xcfSkvZyxcblx0XHRcdGRlZmluZTogICAgICAvXFx7XFx7IyNcXHMqKFtcXHdcXC4kXSspXFxzKihcXDp8PSkoW1xcc1xcU10rPykjXFx9XFx9L2csXG5cdFx0XHRkZWZpbmVQYXJhbXM6L15cXHMqKFtcXHckXSspOihbXFxzXFxTXSspLyxcblx0XHRcdGNvbmRpdGlvbmFsOiAvXFx7XFx7XFw/KFxcPyk/XFxzKihbXFxzXFxTXSo/KVxccypcXH1cXH0vZyxcblx0XHRcdGl0ZXJhdGU6ICAgICAvXFx7XFx7flxccyooPzpcXH1cXH18KFtcXHNcXFNdKz8pXFxzKlxcOlxccyooW1xcdyRdKylcXHMqKD86XFw6XFxzKihbXFx3JF0rKSk/XFxzKlxcfVxcfSkvZyxcblx0XHRcdHZhcm5hbWU6XHRcIml0XCIsXG5cdFx0XHRzdHJpcDpcdFx0dHJ1ZSxcblx0XHRcdGFwcGVuZDpcdFx0dHJ1ZSxcblx0XHRcdHNlbGZjb250YWluZWQ6IGZhbHNlLFxuXHRcdFx0ZG9Ob3RTa2lwRW5jb2RlZDogZmFsc2Vcblx0XHR9LFxuXHRcdHRlbXBsYXRlOiB1bmRlZmluZWQsIC8vZm4sIGNvbXBpbGUgdGVtcGxhdGVcblx0XHRjb21waWxlOiAgdW5kZWZpbmVkICAvL2ZuLCBmb3IgZXhwcmVzc1xuXHR9LCBfZ2xvYmFscztcblxuXHRkb1QuZW5jb2RlSFRNTFNvdXJjZSA9IGZ1bmN0aW9uKGRvTm90U2tpcEVuY29kZWQpIHtcblx0XHR2YXIgZW5jb2RlSFRNTFJ1bGVzID0geyBcIiZcIjogXCImIzM4O1wiLCBcIjxcIjogXCImIzYwO1wiLCBcIj5cIjogXCImIzYyO1wiLCAnXCInOiBcIiYjMzQ7XCIsIFwiJ1wiOiBcIiYjMzk7XCIsIFwiL1wiOiBcIiYjNDc7XCIgfSxcblx0XHRcdG1hdGNoSFRNTCA9IGRvTm90U2tpcEVuY29kZWQgPyAvWyY8PlwiJ1xcL10vZyA6IC8mKD8hIz9cXHcrOyl8PHw+fFwifCd8XFwvL2c7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNvZGUpIHtcblx0XHRcdHJldHVybiBjb2RlID8gY29kZS50b1N0cmluZygpLnJlcGxhY2UobWF0Y2hIVE1MLCBmdW5jdGlvbihtKSB7cmV0dXJuIGVuY29kZUhUTUxSdWxlc1ttXSB8fCBtO30pIDogXCJcIjtcblx0XHR9O1xuXHR9O1xuXG5cdF9nbG9iYWxzID0gKGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzIHx8ICgwLGV2YWwpKFwidGhpc1wiKTsgfSgpKTtcblxuXHRpZiAodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZG9UO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0ZGVmaW5lKGZ1bmN0aW9uKCl7cmV0dXJuIGRvVDt9KTtcblx0fSBlbHNlIHtcblx0XHRfZ2xvYmFscy5kb1QgPSBkb1Q7XG5cdH1cblxuXHR2YXIgc3RhcnRlbmQgPSB7XG5cdFx0YXBwZW5kOiB7IHN0YXJ0OiBcIicrKFwiLCAgICAgIGVuZDogXCIpKydcIiwgICAgICBzdGFydGVuY29kZTogXCInK2VuY29kZUhUTUwoXCIgfSxcblx0XHRzcGxpdDogIHsgc3RhcnQ6IFwiJztvdXQrPShcIiwgZW5kOiBcIik7b3V0Kz0nXCIsIHN0YXJ0ZW5jb2RlOiBcIic7b3V0Kz1lbmNvZGVIVE1MKFwiIH1cblx0fSwgc2tpcCA9IC8kXi87XG5cblx0ZnVuY3Rpb24gcmVzb2x2ZURlZnMoYywgYmxvY2ssIGRlZikge1xuXHRcdHJldHVybiAoKHR5cGVvZiBibG9jayA9PT0gXCJzdHJpbmdcIikgPyBibG9jayA6IGJsb2NrLnRvU3RyaW5nKCkpXG5cdFx0LnJlcGxhY2UoYy5kZWZpbmUgfHwgc2tpcCwgZnVuY3Rpb24obSwgY29kZSwgYXNzaWduLCB2YWx1ZSkge1xuXHRcdFx0aWYgKGNvZGUuaW5kZXhPZihcImRlZi5cIikgPT09IDApIHtcblx0XHRcdFx0Y29kZSA9IGNvZGUuc3Vic3RyaW5nKDQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCEoY29kZSBpbiBkZWYpKSB7XG5cdFx0XHRcdGlmIChhc3NpZ24gPT09IFwiOlwiKSB7XG5cdFx0XHRcdFx0aWYgKGMuZGVmaW5lUGFyYW1zKSB2YWx1ZS5yZXBsYWNlKGMuZGVmaW5lUGFyYW1zLCBmdW5jdGlvbihtLCBwYXJhbSwgdikge1xuXHRcdFx0XHRcdFx0ZGVmW2NvZGVdID0ge2FyZzogcGFyYW0sIHRleHQ6IHZ9O1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGlmICghKGNvZGUgaW4gZGVmKSkgZGVmW2NvZGVdPSB2YWx1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRuZXcgRnVuY3Rpb24oXCJkZWZcIiwgXCJkZWZbJ1wiK2NvZGUrXCInXT1cIiArIHZhbHVlKShkZWYpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gXCJcIjtcblx0XHR9KVxuXHRcdC5yZXBsYWNlKGMudXNlIHx8IHNraXAsIGZ1bmN0aW9uKG0sIGNvZGUpIHtcblx0XHRcdGlmIChjLnVzZVBhcmFtcykgY29kZSA9IGNvZGUucmVwbGFjZShjLnVzZVBhcmFtcywgZnVuY3Rpb24obSwgcywgZCwgcGFyYW0pIHtcblx0XHRcdFx0aWYgKGRlZltkXSAmJiBkZWZbZF0uYXJnICYmIHBhcmFtKSB7XG5cdFx0XHRcdFx0dmFyIHJ3ID0gKGQrXCI6XCIrcGFyYW0pLnJlcGxhY2UoLyd8XFxcXC9nLCBcIl9cIik7XG5cdFx0XHRcdFx0ZGVmLl9fZXhwID0gZGVmLl9fZXhwIHx8IHt9O1xuXHRcdFx0XHRcdGRlZi5fX2V4cFtyd10gPSBkZWZbZF0udGV4dC5yZXBsYWNlKG5ldyBSZWdFeHAoXCIoXnxbXlxcXFx3JF0pXCIgKyBkZWZbZF0uYXJnICsgXCIoW15cXFxcdyRdKVwiLCBcImdcIiksIFwiJDFcIiArIHBhcmFtICsgXCIkMlwiKTtcblx0XHRcdFx0XHRyZXR1cm4gcyArIFwiZGVmLl9fZXhwWydcIitydytcIiddXCI7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0dmFyIHYgPSBuZXcgRnVuY3Rpb24oXCJkZWZcIiwgXCJyZXR1cm4gXCIgKyBjb2RlKShkZWYpO1xuXHRcdFx0cmV0dXJuIHYgPyByZXNvbHZlRGVmcyhjLCB2LCBkZWYpIDogdjtcblx0XHR9KTtcblx0fVxuXG5cdGZ1bmN0aW9uIHVuZXNjYXBlKGNvZGUpIHtcblx0XHRyZXR1cm4gY29kZS5yZXBsYWNlKC9cXFxcKCd8XFxcXCkvZywgXCIkMVwiKS5yZXBsYWNlKC9bXFxyXFx0XFxuXS9nLCBcIiBcIik7XG5cdH1cblxuXHRkb1QudGVtcGxhdGUgPSBmdW5jdGlvbih0bXBsLCBjLCBkZWYpIHtcblx0XHRjID0gYyB8fCBkb1QudGVtcGxhdGVTZXR0aW5ncztcblx0XHR2YXIgY3NlID0gYy5hcHBlbmQgPyBzdGFydGVuZC5hcHBlbmQgOiBzdGFydGVuZC5zcGxpdCwgbmVlZGh0bWxlbmNvZGUsIHNpZCA9IDAsIGluZHYsXG5cdFx0XHRzdHIgID0gKGMudXNlIHx8IGMuZGVmaW5lKSA/IHJlc29sdmVEZWZzKGMsIHRtcGwsIGRlZiB8fCB7fSkgOiB0bXBsO1xuXG5cdFx0c3RyID0gKFwidmFyIG91dD0nXCIgKyAoYy5zdHJpcCA/IHN0ci5yZXBsYWNlKC8oXnxcXHJ8XFxuKVxcdCogK3wgK1xcdCooXFxyfFxcbnwkKS9nLFwiIFwiKVxuXHRcdFx0XHRcdC5yZXBsYWNlKC9cXHJ8XFxufFxcdHxcXC9cXCpbXFxzXFxTXSo/XFwqXFwvL2csXCJcIik6IHN0cilcblx0XHRcdC5yZXBsYWNlKC8nfFxcXFwvZywgXCJcXFxcJCZcIilcblx0XHRcdC5yZXBsYWNlKGMuaW50ZXJwb2xhdGUgfHwgc2tpcCwgZnVuY3Rpb24obSwgY29kZSkge1xuXHRcdFx0XHRyZXR1cm4gY3NlLnN0YXJ0ICsgdW5lc2NhcGUoY29kZSkgKyBjc2UuZW5kO1xuXHRcdFx0fSlcblx0XHRcdC5yZXBsYWNlKGMuZW5jb2RlIHx8IHNraXAsIGZ1bmN0aW9uKG0sIGNvZGUpIHtcblx0XHRcdFx0bmVlZGh0bWxlbmNvZGUgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gY3NlLnN0YXJ0ZW5jb2RlICsgdW5lc2NhcGUoY29kZSkgKyBjc2UuZW5kO1xuXHRcdFx0fSlcblx0XHRcdC5yZXBsYWNlKGMuY29uZGl0aW9uYWwgfHwgc2tpcCwgZnVuY3Rpb24obSwgZWxzZWNhc2UsIGNvZGUpIHtcblx0XHRcdFx0cmV0dXJuIGVsc2VjYXNlID9cblx0XHRcdFx0XHQoY29kZSA/IFwiJzt9ZWxzZSBpZihcIiArIHVuZXNjYXBlKGNvZGUpICsgXCIpe291dCs9J1wiIDogXCInO31lbHNle291dCs9J1wiKSA6XG5cdFx0XHRcdFx0KGNvZGUgPyBcIic7aWYoXCIgKyB1bmVzY2FwZShjb2RlKSArIFwiKXtvdXQrPSdcIiA6IFwiJzt9b3V0Kz0nXCIpO1xuXHRcdFx0fSlcblx0XHRcdC5yZXBsYWNlKGMuaXRlcmF0ZSB8fCBza2lwLCBmdW5jdGlvbihtLCBpdGVyYXRlLCB2bmFtZSwgaW5hbWUpIHtcblx0XHRcdFx0aWYgKCFpdGVyYXRlKSByZXR1cm4gXCInO30gfSBvdXQrPSdcIjtcblx0XHRcdFx0c2lkKz0xOyBpbmR2PWluYW1lIHx8IFwiaVwiK3NpZDsgaXRlcmF0ZT11bmVzY2FwZShpdGVyYXRlKTtcblx0XHRcdFx0cmV0dXJuIFwiJzt2YXIgYXJyXCIrc2lkK1wiPVwiK2l0ZXJhdGUrXCI7aWYoYXJyXCIrc2lkK1wiKXt2YXIgXCIrdm5hbWUrXCIsXCIraW5kditcIj0tMSxsXCIrc2lkK1wiPWFyclwiK3NpZCtcIi5sZW5ndGgtMTt3aGlsZShcIitpbmR2K1wiPGxcIitzaWQrXCIpe1wiXG5cdFx0XHRcdFx0K3ZuYW1lK1wiPWFyclwiK3NpZCtcIltcIitpbmR2K1wiKz0xXTtvdXQrPSdcIjtcblx0XHRcdH0pXG5cdFx0XHQucmVwbGFjZShjLmV2YWx1YXRlIHx8IHNraXAsIGZ1bmN0aW9uKG0sIGNvZGUpIHtcblx0XHRcdFx0cmV0dXJuIFwiJztcIiArIHVuZXNjYXBlKGNvZGUpICsgXCJvdXQrPSdcIjtcblx0XHRcdH0pXG5cdFx0XHQrIFwiJztyZXR1cm4gb3V0O1wiKVxuXHRcdFx0LnJlcGxhY2UoL1xcbi9nLCBcIlxcXFxuXCIpLnJlcGxhY2UoL1xcdC9nLCAnXFxcXHQnKS5yZXBsYWNlKC9cXHIvZywgXCJcXFxcclwiKVxuXHRcdFx0LnJlcGxhY2UoLyhcXHN8O3xcXH18XnxcXHspb3V0XFwrPScnOy9nLCAnJDEnKS5yZXBsYWNlKC9cXCsnJy9nLCBcIlwiKTtcblx0XHRcdC8vLnJlcGxhY2UoLyhcXHN8O3xcXH18XnxcXHspb3V0XFwrPScnXFwrL2csJyQxb3V0Kz0nKTtcblxuXHRcdGlmIChuZWVkaHRtbGVuY29kZSkge1xuXHRcdFx0aWYgKCFjLnNlbGZjb250YWluZWQgJiYgX2dsb2JhbHMgJiYgIV9nbG9iYWxzLl9lbmNvZGVIVE1MKSBfZ2xvYmFscy5fZW5jb2RlSFRNTCA9IGRvVC5lbmNvZGVIVE1MU291cmNlKGMuZG9Ob3RTa2lwRW5jb2RlZCk7XG5cdFx0XHRzdHIgPSBcInZhciBlbmNvZGVIVE1MID0gdHlwZW9mIF9lbmNvZGVIVE1MICE9PSAndW5kZWZpbmVkJyA/IF9lbmNvZGVIVE1MIDogKFwiXG5cdFx0XHRcdCsgZG9ULmVuY29kZUhUTUxTb3VyY2UudG9TdHJpbmcoKSArIFwiKFwiICsgKGMuZG9Ob3RTa2lwRW5jb2RlZCB8fCAnJykgKyBcIikpO1wiXG5cdFx0XHRcdCsgc3RyO1xuXHRcdH1cblx0XHR0cnkge1xuXHRcdFx0cmV0dXJuIG5ldyBGdW5jdGlvbihjLnZhcm5hbWUsIHN0cik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0aWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiKSBjb25zb2xlLmxvZyhcIkNvdWxkIG5vdCBjcmVhdGUgYSB0ZW1wbGF0ZSBmdW5jdGlvbjogXCIgKyBzdHIpO1xuXHRcdFx0dGhyb3cgZTtcblx0XHR9XG5cdH07XG5cblx0ZG9ULmNvbXBpbGUgPSBmdW5jdGlvbih0bXBsLCBkZWYpIHtcblx0XHRyZXR1cm4gZG9ULnRlbXBsYXRlKHRtcGwsIG51bGwsIGRlZik7XG5cdH07XG59KCkpO1xuIiwiLyogZG9UICsgYXV0by1jb21waWxhdGlvbiBvZiBkb1QgdGVtcGxhdGVzXG4gKlxuICogMjAxMiwgTGF1cmEgRG9rdG9yb3ZhLCBodHRwczovL2dpdGh1Yi5jb20vb2xhZG8vZG9UXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqXG4gKiBDb21waWxlcyAuZGVmLCAuZG90LCAuanN0IGZpbGVzIGZvdW5kIHVuZGVyIHRoZSBzcGVjaWZpZWQgcGF0aC5cbiAqIEl0IGlnbm9yZXMgc3ViLWRpcmVjdG9yaWVzLlxuICogVGVtcGxhdGUgZmlsZXMgY2FuIGhhdmUgbXVsdGlwbGUgZXh0ZW5zaW9ucyBhdCB0aGUgc2FtZSB0aW1lLlxuICogRmlsZXMgd2l0aCAuZGVmIGV4dGVuc2lvbiBjYW4gYmUgaW5jbHVkZWQgaW4gb3RoZXIgZmlsZXMgdmlhIHt7I2RlZi5uYW1lfX1cbiAqIEZpbGVzIHdpdGggLmRvdCBleHRlbnNpb24gYXJlIGNvbXBpbGVkIGludG8gZnVuY3Rpb25zIHdpdGggdGhlIHNhbWUgbmFtZSBhbmRcbiAqIGNhbiBiZSBhY2Nlc3NlZCBhcyByZW5kZXJlci5maWxlbmFtZVxuICogRmlsZXMgd2l0aCAuanN0IGV4dGVuc2lvbiBhcmUgY29tcGlsZWQgaW50byAuanMgZmlsZXMuIFByb2R1Y2VkIC5qcyBmaWxlIGNhbiBiZVxuICogbG9hZGVkIGFzIGEgY29tbW9uSlMsIEFNRCBtb2R1bGUsIG9yIGp1c3QgaW5zdGFsbGVkIGludG8gYSBnbG9iYWwgdmFyaWFibGVcbiAqIChkZWZhdWx0IGlzIHNldCB0byB3aW5kb3cucmVuZGVyKS5cbiAqIEFsbCBpbmxpbmUgZGVmaW5lcyBkZWZpbmVkIGluIHRoZSAuanN0IGZpbGUgYXJlXG4gKiBjb21waWxlZCBpbnRvIHNlcGFyYXRlIGZ1bmN0aW9ucyBhbmQgYXJlIGF2YWlsYWJsZSB2aWEgX3JlbmRlci5maWxlbmFtZS5kZWZpbmVuYW1lXG4gKlxuICogQmFzaWMgdXNhZ2U6XG4gKiB2YXIgZG90cyA9IHJlcXVpcmUoXCJkb3RcIikucHJvY2Vzcyh7cGF0aDogXCIuL3ZpZXdzXCJ9KTtcbiAqIGRvdHMubXl0ZW1wbGF0ZSh7Zm9vOlwiaGVsbG8gd29ybGRcIn0pO1xuICpcbiAqIFRoZSBhYm92ZSBzbmlwcGV0IHdpbGw6XG4gKiAxLiBDb21waWxlIGFsbCB0ZW1wbGF0ZXMgaW4gdmlld3MgZm9sZGVyICguZG90LCAuZGVmLCAuanN0KVxuICogMi4gUGxhY2UgLmpzIGZpbGVzIGNvbXBpbGVkIGZyb20gLmpzdCB0ZW1wbGF0ZXMgaW50byB0aGUgc2FtZSBmb2xkZXIuXG4gKiAgICBUaGVzZSBmaWxlcyBjYW4gYmUgdXNlZCB3aXRoIHJlcXVpcmUsIGkuZS4gcmVxdWlyZShcIi4vdmlld3MvbXl0ZW1wbGF0ZVwiKS5cbiAqIDMuIFJldHVybiBhbiBvYmplY3Qgd2l0aCBmdW5jdGlvbnMgY29tcGlsZWQgZnJvbSAuZG90IHRlbXBsYXRlcyBhcyBpdHMgcHJvcGVydGllcy5cbiAqIDQuIFJlbmRlciBteXRlbXBsYXRlIHRlbXBsYXRlLlxuICovXG5cbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKSxcblx0ZG9UID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9kb1RcIik7XG5cbmRvVC5wcm9jZXNzID0gZnVuY3Rpb24ob3B0aW9ucykge1xuXHQvL3BhdGgsIGRlc3RpbmF0aW9uLCBnbG9iYWwsIHJlbmRlcm1vZHVsZSwgdGVtcGxhdGVTZXR0aW5nc1xuXHRyZXR1cm4gbmV3IEluc3RhbGxEb3RzKG9wdGlvbnMpLmNvbXBpbGVBbGwoKTtcbn07XG5cbmZ1bmN0aW9uIEluc3RhbGxEb3RzKG8pIHtcblx0dGhpcy5fX3BhdGggXHRcdD0gby5wYXRoIHx8IFwiLi9cIjtcblx0aWYgKHRoaXMuX19wYXRoW3RoaXMuX19wYXRoLmxlbmd0aC0xXSAhPT0gJy8nKSB0aGlzLl9fcGF0aCArPSAnLyc7XG5cdHRoaXMuX19kZXN0aW5hdGlvblx0PSBvLmRlc3RpbmF0aW9uIHx8IHRoaXMuX19wYXRoO1xuXHRpZiAodGhpcy5fX2Rlc3RpbmF0aW9uW3RoaXMuX19kZXN0aW5hdGlvbi5sZW5ndGgtMV0gIT09ICcvJykgdGhpcy5fX2Rlc3RpbmF0aW9uICs9ICcvJztcblx0dGhpcy5fX2dsb2JhbFx0XHQ9IG8uZ2xvYmFsIHx8IFwid2luZG93LnJlbmRlclwiO1xuXHR0aGlzLl9fcmVuZGVybW9kdWxlXHQ9IG8ucmVuZGVybW9kdWxlIHx8IHt9O1xuXHR0aGlzLl9fc2V0dGluZ3MgXHQ9IG8udGVtcGxhdGVTZXR0aW5ncyA/IGNvcHkoby50ZW1wbGF0ZVNldHRpbmdzLCBjb3B5KGRvVC50ZW1wbGF0ZVNldHRpbmdzKSkgOiB1bmRlZmluZWQ7XG5cdHRoaXMuX19pbmNsdWRlc1x0XHQ9IHt9O1xufVxuXG5JbnN0YWxsRG90cy5wcm90b3R5cGUuY29tcGlsZVRvRmlsZSA9IGZ1bmN0aW9uKHBhdGgsIHRlbXBsYXRlLCBkZWYpIHtcblx0ZGVmID0gZGVmIHx8IHt9O1xuXHR2YXIgbW9kdWxlbmFtZSA9IHBhdGguc3Vic3RyaW5nKHBhdGgubGFzdEluZGV4T2YoXCIvXCIpKzEsIHBhdGgubGFzdEluZGV4T2YoXCIuXCIpKVxuXHRcdCwgZGVmcyA9IGNvcHkodGhpcy5fX2luY2x1ZGVzLCBjb3B5KGRlZikpXG5cdFx0LCBzZXR0aW5ncyA9IHRoaXMuX19zZXR0aW5ncyB8fCBkb1QudGVtcGxhdGVTZXR0aW5nc1xuXHRcdCwgY29tcGlsZW9wdGlvbnMgPSBjb3B5KHNldHRpbmdzKVxuXHRcdCwgZGVmYXVsdGNvbXBpbGVkID0gZG9ULnRlbXBsYXRlKHRlbXBsYXRlLCBzZXR0aW5ncywgZGVmcylcblx0XHQsIGV4cG9ydHMgPSBbXVxuXHRcdCwgY29tcGlsZWQgPSBcIlwiXG5cdFx0LCBmbjtcblxuXHRmb3IgKHZhciBwcm9wZXJ0eSBpbiBkZWZzKSB7XG5cdFx0aWYgKGRlZnNbcHJvcGVydHldICE9PSBkZWZbcHJvcGVydHldICYmIGRlZnNbcHJvcGVydHldICE9PSB0aGlzLl9faW5jbHVkZXNbcHJvcGVydHldKSB7XG5cdFx0XHRmbiA9IHVuZGVmaW5lZDtcblx0XHRcdGlmICh0eXBlb2YgZGVmc1twcm9wZXJ0eV0gPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdGZuID0gZG9ULnRlbXBsYXRlKGRlZnNbcHJvcGVydHldLCBzZXR0aW5ncywgZGVmcyk7XG5cdFx0XHR9IGVsc2UgaWYgKHR5cGVvZiBkZWZzW3Byb3BlcnR5XSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRmbiA9IGRlZnNbcHJvcGVydHldO1xuXHRcdFx0fSBlbHNlIGlmIChkZWZzW3Byb3BlcnR5XS5hcmcpIHtcblx0XHRcdFx0Y29tcGlsZW9wdGlvbnMudmFybmFtZSA9IGRlZnNbcHJvcGVydHldLmFyZztcblx0XHRcdFx0Zm4gPSBkb1QudGVtcGxhdGUoZGVmc1twcm9wZXJ0eV0udGV4dCwgY29tcGlsZW9wdGlvbnMsIGRlZnMpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGZuKSB7XG5cdFx0XHRcdGNvbXBpbGVkICs9IGZuLnRvU3RyaW5nKCkucmVwbGFjZSgnYW5vbnltb3VzJywgcHJvcGVydHkpO1xuXHRcdFx0XHRleHBvcnRzLnB1c2gocHJvcGVydHkpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRjb21waWxlZCArPSBkZWZhdWx0Y29tcGlsZWQudG9TdHJpbmcoKS5yZXBsYWNlKCdhbm9ueW1vdXMnLCBtb2R1bGVuYW1lKTtcblx0ZnMud3JpdGVGaWxlU3luYyhwYXRoLCBcIihmdW5jdGlvbigpe1wiICsgY29tcGlsZWRcblx0XHQrIFwidmFyIGl0c2VsZj1cIiArIG1vZHVsZW5hbWUgKyBcIiwgX2VuY29kZUhUTUw9KFwiICsgZG9ULmVuY29kZUhUTUxTb3VyY2UudG9TdHJpbmcoKSArIFwiKFwiICsgKHNldHRpbmdzLmRvTm90U2tpcEVuY29kZWQgfHwgJycpICsgXCIpKTtcIlxuXHRcdCsgYWRkZXhwb3J0cyhleHBvcnRzKVxuXHRcdCsgXCJpZih0eXBlb2YgbW9kdWxlIT09J3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIG1vZHVsZS5leHBvcnRzPWl0c2VsZjtlbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT0nZnVuY3Rpb24nKWRlZmluZShmdW5jdGlvbigpe3JldHVybiBpdHNlbGY7fSk7ZWxzZSB7XCJcblx0XHQrIHRoaXMuX19nbG9iYWwgKyBcIj1cIiArIHRoaXMuX19nbG9iYWwgKyBcInx8e307XCIgKyB0aGlzLl9fZ2xvYmFsICsgXCJbJ1wiICsgbW9kdWxlbmFtZSArIFwiJ109aXRzZWxmO319KCkpO1wiKTtcbn07XG5cbmZ1bmN0aW9uIGFkZGV4cG9ydHMoZXhwb3J0cykge1xuXHRmb3IgKHZhciByZXQgPScnLCBpPTA7IGk8IGV4cG9ydHMubGVuZ3RoOyBpKyspIHtcblx0XHRyZXQgKz0gXCJpdHNlbGYuXCIgKyBleHBvcnRzW2ldKyBcIj1cIiArIGV4cG9ydHNbaV0rXCI7XCI7XG5cdH1cblx0cmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gY29weShvLCB0bykge1xuXHR0byA9IHRvIHx8IHt9O1xuXHRmb3IgKHZhciBwcm9wZXJ0eSBpbiBvKSB7XG5cdFx0dG9bcHJvcGVydHldID0gb1twcm9wZXJ0eV07XG5cdH1cblx0cmV0dXJuIHRvO1xufVxuXG5mdW5jdGlvbiByZWFkZGF0YShwYXRoKSB7XG5cdHZhciBkYXRhID0gZnMucmVhZEZpbGVTeW5jKHBhdGgpO1xuXHRpZiAoZGF0YSkgcmV0dXJuIGRhdGEudG9TdHJpbmcoKTtcblx0Y29uc29sZS5sb2coXCJwcm9ibGVtcyB3aXRoIFwiICsgcGF0aCk7XG59XG5cbkluc3RhbGxEb3RzLnByb3RvdHlwZS5jb21waWxlUGF0aCA9IGZ1bmN0aW9uKHBhdGgpIHtcblx0dmFyIGRhdGEgPSByZWFkZGF0YShwYXRoKTtcblx0aWYgKGRhdGEpIHtcblx0XHRyZXR1cm4gZG9ULnRlbXBsYXRlKGRhdGEsXG5cdFx0XHRcdFx0dGhpcy5fX3NldHRpbmdzIHx8IGRvVC50ZW1wbGF0ZVNldHRpbmdzLFxuXHRcdFx0XHRcdGNvcHkodGhpcy5fX2luY2x1ZGVzKSk7XG5cdH1cbn07XG5cbkluc3RhbGxEb3RzLnByb3RvdHlwZS5jb21waWxlQWxsID0gZnVuY3Rpb24oKSB7XG5cdGNvbnNvbGUubG9nKFwiQ29tcGlsaW5nIGFsbCBkb1QgdGVtcGxhdGVzLi4uXCIpO1xuXG5cdHZhciBkZWZGb2xkZXIgPSB0aGlzLl9fcGF0aCxcblx0XHRzb3VyY2VzID0gZnMucmVhZGRpclN5bmMoZGVmRm9sZGVyKSxcblx0XHRrLCBsLCBuYW1lO1xuXG5cdGZvciggayA9IDAsIGwgPSBzb3VyY2VzLmxlbmd0aDsgayA8IGw7IGsrKykge1xuXHRcdG5hbWUgPSBzb3VyY2VzW2tdO1xuXHRcdGlmICgvXFwuZGVmKFxcLmRvdHxcXC5qc3QpPyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiTG9hZGVkIGRlZiBcIiArIG5hbWUpO1xuXHRcdFx0dGhpcy5fX2luY2x1ZGVzW25hbWUuc3Vic3RyaW5nKDAsIG5hbWUuaW5kZXhPZignLicpKV0gPSByZWFkZGF0YShkZWZGb2xkZXIgKyBuYW1lKTtcblx0XHR9XG5cdH1cblxuXHRmb3IoIGsgPSAwLCBsID0gc291cmNlcy5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRuYW1lID0gc291cmNlc1trXTtcblx0XHRpZiAoL1xcLmRvdChcXC5kZWZ8XFwuanN0KT8kLy50ZXN0KG5hbWUpKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkNvbXBpbGluZyBcIiArIG5hbWUgKyBcIiB0byBmdW5jdGlvblwiKTtcblx0XHRcdHRoaXMuX19yZW5kZXJtb2R1bGVbbmFtZS5zdWJzdHJpbmcoMCwgbmFtZS5pbmRleE9mKCcuJykpXSA9IHRoaXMuY29tcGlsZVBhdGgoZGVmRm9sZGVyICsgbmFtZSk7XG5cdFx0fVxuXHRcdGlmICgvXFwuanN0KFxcLmRvdHxcXC5kZWYpPyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiQ29tcGlsaW5nIFwiICsgbmFtZSArIFwiIHRvIGZpbGVcIik7XG5cdFx0XHR0aGlzLmNvbXBpbGVUb0ZpbGUodGhpcy5fX2Rlc3RpbmF0aW9uICsgbmFtZS5zdWJzdHJpbmcoMCwgbmFtZS5pbmRleE9mKCcuJykpICsgJy5qcycsXG5cdFx0XHRcdFx0cmVhZGRhdGEoZGVmRm9sZGVyICsgbmFtZSkpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gdGhpcy5fX3JlbmRlcm1vZHVsZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuXG4vKipcbiAqIFtfX1Byb3RvdHlwZSBmdW5jdGlvbnNfX10ocHJvdG9fcHJvdG90eXBlLmpzLmh0bWwpXG4gKlxuICogLSBbZXh0ZW5kUHJvdG9dKHByb3RvX3Byb3RvdHlwZS5qcy5odG1sI2V4dGVuZFByb3RvKVxuICogLSBbY3JlYXRlU3ViY2xhc3NdKHByb3RvX3Byb3RvdHlwZS5qcy5odG1sI2NyZWF0ZVN1YmNsYXNzKVxuICogLSBbbWFrZVN1YmNsYXNzXShwcm90b19wcm90b3R5cGUuanMuaHRtbCNtYWtlU3ViY2xhc3MpXG4gKiAtIFtuZXdBcHBseV0ocHJvdG9fcHJvdG90eXBlLmpzLmh0bWwjbmV3QXBwbHkpXG4gKi9cbnZhciBwcm90b3R5cGVNZXRob2RzID0gcmVxdWlyZSgnLi9wcm90b19wcm90b3R5cGUnKTtcblxuXG4vKipcbiAqIFtfX09iamVjdCBmdW5jdGlvbnNfX10ocHJvdG9fb2JqZWN0LmpzLmh0bWwpXG4gKlxuICogLSBbZXh0ZW5kXShwcm90b19vYmplY3QuanMuaHRtbCNleHRlbmQpXG4gKiAtIFtjbG9uZV0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjY2xvbmUpXG4gKiAtIFtkZWZpbmVQcm9wZXJ0eV0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZGVmaW5lUHJvcGVydHkpXG4gKiAtIFtkZWZpbmVQcm9wZXJ0aWVzXShwcm90b19vYmplY3QuanMuaHRtbCNkZWZpbmVQcm9wZXJ0aWVzKVxuICogLSBbZGVlcEV4dGVuZF0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZGVlcEV4dGVuZClcbiAqIC0gW2RlZXBDbG9uZV0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZGVlcENsb25lKVxuICogLSBba2V5c10ocHJvdG9fb2JqZWN0LmpzLmh0bWwja2V5cylcbiAqIC0gW2FsbEtleXNdKHByb3RvX29iamVjdC5qcy5odG1sI2FsbEtleXMpXG4gKiAtIFt2YWx1ZXNdKHByb3RvX29iamVjdC5qcy5odG1sI3ZhbHVlcylcbiAqIC0gW2tleU9mXShwcm90b19vYmplY3QuanMuaHRtbCNrZXlPZilcbiAqIC0gW2FsbEtleXNPZl0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjYWxsS2V5c09mKVxuICogLSBbZWFjaEtleV0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZWFjaEtleSlcbiAqIC0gW21hcEtleXNdKHByb3RvX29iamVjdC5qcy5odG1sI21hcEtleXMpXG4gKiAtIFtyZWR1Y2VLZXlzXShwcm90b19vYmplY3QuanMuaHRtbCNyZWR1Y2VLZXlzKVxuICogLSBbZmlsdGVyS2V5c10ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZmlsdGVyS2V5cylcbiAqIC0gW3NvbWVLZXldKHByb3RvX29iamVjdC5qcy5odG1sI3NvbWVLZXkpXG4gKiAtIFtldmVyeUtleV0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZXZlcnlLZXkpXG4gKiAtIFtmaW5kVmFsdWVdKHByb3RvX29iamVjdC5qcy5odG1sI2ZpbmRWYWx1ZSlcbiAqIC0gW2ZpbmRLZXldKHByb3RvX29iamVjdC5qcy5odG1sI2ZpbmRLZXkpXG4gKiAtIFtwaWNrS2V5c10ocHJvdG9fb2JqZWN0LmpzLmh0bWwjcGlja0tleXMpXG4gKiAtIFtvbWl0S2V5c10ocHJvdG9fb2JqZWN0LmpzLmh0bWwjb21pdEtleXMpXG4gKiAtIFtpc0VxdWFsXShwcm90b19vYmplY3QuanMuaHRtbCNpc0VxdWFsKVxuICogLSBbaXNOb3RdKHByb3RvX29iamVjdC5qcy5odG1sI2lzTm90KVxuICovXG52YXIgb2JqZWN0TWV0aG9kcyA9IHJlcXVpcmUoJy4vcHJvdG9fb2JqZWN0Jyk7XG5cblxuLyoqXG4gKiBbX19BcnJheSBmdW5jdGlvbnNfX10ocHJvdG9fYXJyYXkuanMuaHRtbClcbiAqXG4gKiAtIFtmaW5kXShwcm90b19hcnJheS5qcy5odG1sI2ZpbmQpXG4gKiAtIFtmaW5kSW5kZXhdKHByb3RvX2FycmF5LmpzLmh0bWwjZmluZEluZGV4KVxuICogLSBbYXBwZW5kQXJyYXldKHByb3RvX2FycmF5LmpzLmh0bWwjYXBwZW5kQXJyYXkpXG4gKiAtIFtwcmVwZW5kQXJyYXldKHByb3RvX2FycmF5LmpzLmh0bWwjcHJlcGVuZEFycmF5KVxuICogLSBbc3BsaWNlSXRlbV0ocHJvdG9fYXJyYXkuanMuaHRtbCNzcGxpY2VJdGVtKVxuICogLSBbdG9BcnJheV0ocHJvdG9fYXJyYXkuanMuaHRtbCN0b0FycmF5KVxuICogLSBbb2JqZWN0XShwcm90b19hcnJheS5qcy5odG1sI29iamVjdClcbiAqIC0gW21hcFRvT2JqZWN0XShwcm90b19hcnJheS5qcy5odG1sI21hcFRvT2JqZWN0KVxuICogLSBbdW5pcXVlXShwcm90b19hcnJheS5qcy5odG1sI3VuaXF1ZSlcbiAqIC0gW2RlZXBGb3JFYWNoXShwcm90b19hcnJheS5qcy5odG1sI2RlZXBGb3JFYWNoKVxuICpcbiAqIEZ1bmN0aW9ucyB0aGF0IEFycmF5IFtpbXBsZW1lbnRzIG5hdGl2ZWx5XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9wcm90b3R5cGUjTWV0aG9kcykgYXJlIGFsc28gYWRkZWQgLSB0aGV5IGNhbiBiZSB1c2VkIHdpdGggYXJyYXktbGlrZSBvYmplY3RzIGFuZCBmb3IgY2hhaW5pbmcgKG5hdGl2ZSBmdW5jdGlvbnMgYXJlIGFsd2F5cyBjYWxsZWQpLlxuICovXG52YXIgYXJyYXlNZXRob2RzID0gcmVxdWlyZSgnLi9wcm90b19hcnJheScpO1xuXG5cbi8qKlxuICogW19fRnVuY3Rpb24gZnVuY3Rpb25zX19dKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwpXG4gKlxuICogLSBbbWFrZUZ1bmN0aW9uXShwcm90b19mdW5jdGlvbi5qcy5odG1sI21ha2VGdW5jdGlvbilcbiAqIC0gW3BhcnRpYWxdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjcGFydGlhbClcbiAqIC0gW3BhcnRpYWxSaWdodF0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNwYXJ0aWFsUmlnaHQpXG4gKiAtIFttZW1vaXplXShwcm90b19mdW5jdGlvbi5qcy5odG1sI21lbW9pemUpXG4gKiAtIFtkZWxheV0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNkZWxheSlcbiAqIC0gW2RlZmVyXShwcm90b19mdW5jdGlvbi5qcy5odG1sI2RlZmVyKVxuICogLSBbZGVsYXllZF0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNkZWxheWVkKVxuICogLSBbZGVmZXJyZWRdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjZGVmZXJyZWQpXG4gKiAtIFtkZWZlclRpY2tzXShwcm90b19mdW5jdGlvbi5qcy5odG1sI2RlZmVyVGlja3MpXG4gKiAtIFtkZWxheU1ldGhvZF0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNkZWxheU1ldGhvZClcbiAqIC0gW2RlZmVyTWV0aG9kXShwcm90b19mdW5jdGlvbi5qcy5odG1sI2RlZmVyTWV0aG9kKVxuICogLSBbZGVib3VuY2VdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjZGVib3VuY2UpXG4gKiAtIFt0aHJvdHRsZV0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCN0aHJvdHRsZSlcbiAqIC0gW29uY2VdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjb25jZSlcbiAqIC0gW3dhaXRGb3JdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjd2FpdEZvcilcbiovXG52YXIgZnVuY3Rpb25NZXRob2RzID0gcmVxdWlyZSgnLi9wcm90b19mdW5jdGlvbicpO1xuXG5cbi8qKlxuICogW19fU3RyaW5nIGZ1bmN0aW9uc19fXShwcm90b19zdHJpbmcuanMuaHRtbClcbiAqXG4gKiAtIFtmaXJzdFVwcGVyQ2FzZV0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjZmlyc3RVcHBlckNhc2UpXG4gKiAtIFtmaXJzdExvd2VyQ2FzZV0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjZmlyc3RMb3dlckNhc2UpXG4gKiAtIFt0b1JlZ0V4cF0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjdG9SZWdFeHApXG4gKiAtIFt0b0Z1bmN0aW9uXShwcm90b19zdHJpbmcuanMuaHRtbCN0b0Z1bmN0aW9uKVxuICogLSBbdG9EYXRlXShwcm90b19zdHJpbmcuanMuaHRtbCN0b0RhdGUpXG4gKiAtIFt0b1F1ZXJ5U3RyaW5nXShwcm90b19zdHJpbmcuanMuaHRtbCN0b1F1ZXJ5U3RyaW5nKVxuICogLSBbZnJvbVF1ZXJ5U3RyaW5nXShwcm90b19zdHJpbmcuanMuaHRtbCNmcm9tUXVlcnlTdHJpbmcpXG4gKiAtIFtqc29uUGFyc2VdKHByb3RvX3N0cmluZy5qcy5odG1sI2pzb25QYXJzZSlcbiAqIC0gW2hhc2hDb2RlXShwcm90b19zdHJpbmcuanMuaHRtbCNoYXNoQ29kZSlcbiAqIC0gW3VuUHJlZml4XShwcm90b19zdHJpbmcuanMuaHRtbCN1blByZWZpeClcbiAqL1xudmFyIHN0cmluZ01ldGhvZHMgPSByZXF1aXJlKCcuL3Byb3RvX3N0cmluZycpO1xuXG5cbi8qKlxuICogW19fTnVtYmVyIGZ1bmN0aW9uc19fXShwcm90b19udW1iZXIuanMuaHRtbClcbiAqXG4gKiAtIFtpc051bWVyaWNdKHByb3RvX251bWJlci5qcy5odG1sI2lzTnVtZXJpYylcbiAqL1xudmFyIG51bWJlck1ldGhvZHMgPSByZXF1aXJlKCcuL3Byb3RvX251bWJlcicpO1xuXG5cbi8qKlxuICogW19fVXRpbGl0eSBmdW5jdGlvbnNfX10ocHJvdG9fdXRpbC5qcy5odG1sKVxuICpcbiAqIC0gW3RpbWVzXShwcm90b191dGlsLmpzLmh0bWwjdGltZXMpXG4gKiAtIFtyZXBlYXRdKHByb3RvX3V0aWwuanMuaHRtbCNyZXBlYXQpXG4gKiAtIFt0YXBdKHByb3RvX3V0aWwuanMuaHRtbCN0YXApXG4gKiAtIFtyZXN1bHRdKHByb3RvX3V0aWwuanMuaHRtbCNyZXN1bHQpXG4gKiAtIFtpZGVudGl0eV0ocHJvdG9fdXRpbC5qcy5odG1sI2lkZW50aXR5KVxuICogLSBbcHJvcGVydHldKHByb3RvX3V0aWwuanMuaHRtbCNwcm9wZXJ0eSlcbiAqIC0gW2NvbXBhcmVQcm9wZXJ0eV0ocHJvdG9fdXRpbC5qcy5odG1sI2NvbXBhcmVQcm9wZXJ0eSlcbiAqIC0gW25vb3BdKHByb3RvX3V0aWwuanMuaHRtbCNub29wKVxuICovXG52YXIgdXRpbE1ldGhvZHMgPSByZXF1aXJlKCcuL3Byb3RvX3V0aWwnKTtcblxuXG4vKipcbiAqIENoYWluaW5nXG4gKiA9PT09PT09PVxuICpcbiAqIGBfYCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSB3cmFwcGVkIHZhbHVlIChvYmplY3QsIGZ1bmN0aW9uLCBhcnJheSwgZXRjLikgdG8gYWxsb3cgY2hhaW5pbmcgb2YgUHJvdG8gZnVuY3Rpb25zLlxuICogVG8gdW53cmFwLCBgX2AgbWV0aG9kIG9mIGEgd3JhcHBlZCB2YWx1ZSBzaG91bGQgYmUgdXNlZC5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiB2YXIgYXJyID0gXyh7IDA6IDMsIDE6IDQsIDI6IDUsIGxlbmd0aDogM30pXG4gKiAgICAgICAgICAgICAgLnRvQXJyYXkoKVxuICogICAgICAgICAgICAgIC5wcmVwZW5kQXJyYXkoWzEsIDJdKVxuICogICAgICAgICAgICAgIC5hcHBlbmRBcnJheShbNiwgNywgOF0pXG4gKiAgICAgICAgICAgICAgLl8oKTtcbiAqIGBgYFxuICogQSB3cmFwcGVkIG9iamVjdCBpcyBhbiBpbnN0YW5jZSBvZiBgX2AgKGBQcm90b2AgY2xhc3MpLlxuICpcbiAqIENoYWluaW5nIGlzIGltcGxlbWVudGVkIGZvciBkZXZlbG9wbWVudCBjb252ZW5pZW5jZSwgYnV0IGl0IGhhcyBwZXJmb3JtYW5jZSBvdmVyaGVhZCwgbm90IG9ubHkgdG8gd3JhcCBhbmQgdW53cmFwIHZhbHVlcyBidXQgaW4gZWFjaCBmdW5jdGlvbiBjYWxsLlxuICogQWx0aG91Z2ggYWxsIFByb3RvIGZ1bmN0aW9ucyBhcmUgaW1wbGVtZW50ZWQgYXMgbWV0aG9kcyBvcGVyYXRpbmcgb24gdGhpcyBhbmQgdGhlIG92ZXJoZWFkIHRvIHJlZGVmaW5lIHRoZW0gYXMgZnVuY3Rpb25zIGlzIHZlcnkgc21hbGwsIHRoZSBvdmVyaGVhZCB0byByZWRlZmluZSB0aGVtIGFzIG1ldGhvZHMgb2Ygd3JhcHBlZCB2YWx1ZSBpcyBzbGlnaHRseSBoaWdoZXIgLSBjaGFpbmluZyBpcyAxNS0yNSUgc2xvd2VyIHRoYW4gdXNpbmcgZnVuY3Rpb25zIChwcm9wZXJ0aWVzIG9mIF8gdGhhdCB0YWtlIHRoZSBmaXJzdCBwYXJhbWV0ZXIpLlxuICogSW4gY2FzZXMgd2hlbiBwZXJmb3JtYW5jZSBpcyBjcml0aWNhbCwgeW91IG1heSB3YW50IHRvIGF2b2lkIHVzaW5nIGNoYWluaW5nLlxuICpcbiAqIEBwYXJhbSB7QW55fSBzZWxmIEEgdmFsdWUgdG8gYmUgd3JhcHBlZFxuICogQHJldHVybiB7UHJvdG99XG4gKi9cbmZ1bmN0aW9uIFByb3RvKHNlbGYpIHtcbiAgICAvLyB3cmFwIHBhc3NlZCBwYXJhbWV0ZXIgaW4gXyBvYmplY3RcbiAgICB2YXIgd3JhcHBlZCA9IE9iamVjdC5jcmVhdGUoUHJvdG8ucHJvdG90eXBlKTtcbiAgICB3cmFwcGVkLnNlbGYgPSBzZWxmO1xuICAgIHJldHVybiB3cmFwcGVkO1xufTtcblxudmFyIF8gPSBQcm90bztcblxuXG4vLyBzdG9yZSByYXcgbWV0aG9kcyBmcm9tIGRpZmZlcmVudCBtb2R1bGVzIGluIF9fIG9iamVjdCAoZG91YmxlIFwiX1wiKVxudmFyIF9fID0ge307XG5cbm9iamVjdE1ldGhvZHMuZXh0ZW5kLmNhbGwoX18sIG9iamVjdE1ldGhvZHMpO1xuX18uZXh0ZW5kLmNhbGwoX18sIHByb3RvdHlwZU1ldGhvZHMpO1xuX18uZXh0ZW5kLmNhbGwoX18sIGFycmF5TWV0aG9kcyk7XG5fXy5leHRlbmQuY2FsbChfXywgc3RyaW5nTWV0aG9kcyk7XG5fXy5leHRlbmQuY2FsbChfXywgbnVtYmVyTWV0aG9kcyk7XG5fXy5leHRlbmQuY2FsbChfXywgZnVuY3Rpb25NZXRob2RzKTtcbl9fLmV4dGVuZC5jYWxsKF9fLCB1dGlsTWV0aG9kcyk7XG5cblxuLy8gYWRkIF9fIGFzIHByb3BlcnR5IG9mIFByb3RvLCBzbyB0aGV5IGNhbiBiZSB1c2VkIGFzIG1peGlucyBpbiBvdGhlciBjbGFzc2VzXG5fXy5kZWZpbmVQcm9wZXJ0eShQcm90bywgJ19fJywgX18pO1xuXG5cbi8vIGFkZCBfIG1ldGhvZCB0byB1bndyYXAgd3JhcHBlZCB2YWx1ZSAoUHJvdG8gaW5zdGFuY2UpXG5mdW5jdGlvbiB1bndyYXBQcm90bygpIHsgcmV0dXJuIHRoaXMuc2VsZjsgfVxuX18uZXh0ZW5kUHJvdG8uY2FsbChQcm90bywgeyBfOiB1bndyYXBQcm90byB9KTtcblxuLy8gYWRkIGNvbnN0YW50cyAoZnVuY3Rpb25zIHdpbGwgYmUgb3ZlcndyaXR0ZW4pXG5fXy5leHRlbmQuY2FsbChQcm90bywgb2JqZWN0TWV0aG9kcy5fY29uc3RhbnRzKTtcblxuLy8gYWRkIGZ1bmN0aW9ucyB0aGF0IHRha2UgZmlyc3QgcGFyYW1ldGVyIGluc3RlYWQgb2YgXCJ0aGlzXCIgdG8gUHJvdG9cbnZhciBwcm90b0Z1bmNzID0gX18ubWFwS2V5cy5jYWxsKF9fLCB1dGlscy5tYWtlUHJvdG9GdW5jdGlvbiwgdHJ1ZSk7XG5fXy5leHRlbmQuY2FsbChQcm90bywgcHJvdG9GdW5jcyk7XG5cbi8vIGFkZCBQcm90byB3cmFwcGVkIHZhbHVlIGluc3RhbmNlIG1ldGhvZHMgdG8gUHJvdG8gcHJvdG90eXBlXG52YXIgcHJvdG9JbnN0YW5jZU1ldGhvZHMgPSBfXy5tYXBLZXlzLmNhbGwoX18sIHV0aWxzLm1ha2VQcm90b0luc3RhbmNlTWV0aG9kLCB0cnVlKTtcbl9fLmV4dGVuZFByb3RvLmNhbGwoUHJvdG8sIHByb3RvSW5zdGFuY2VNZXRob2RzKTtcblxuXG4vKipcbiAqIEluIHdpbmRvd3MgZW52aXJvbm1lbnQsIGEgZ2xvYmFsIGBfYCB2YWx1ZSBpcyBwcmVzZXJ2ZWQgaW4gYF8udW5kZXJzY29yZWBcbiAqL1xuaWYgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcpIHtcbiAgICAvLyBwcmVzZXJ2ZSBleGlzdGluZyBfIG9iamVjdFxuICAgIGlmICh3aW5kb3cuXylcbiAgICAgICAgUHJvdG8udW5kZXJzY29yZSA9IHdpbmRvdy5fXG5cbiAgICAvLyBleHBvc2UgZ2xvYmFsIF8gYW5kIFByb3RvXG4gICAgd2luZG93Ll8gPSBQcm90bztcbn1cblxuaWYgKHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpXG4gICAgLy8gZXhwb3J0IGZvciBub2RlL2Jyb3dzZXJpZnlcbiAgICBtb2R1bGUuZXhwb3J0cyA9IFByb3RvO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgX18gPSByZXF1aXJlKCcuL3Byb3RvX29iamVjdCcpXG4gICAgLCB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuXG4vKipcbiAqIC0gW2ZpbmRdKCNmaW5kKVxuICogLSBbZmluZEluZGV4XSgjZmluZEluZGV4KVxuICogLSBbYXBwZW5kQXJyYXldKCNhcHBlbmRBcnJheSlcbiAqIC0gW3ByZXBlbmRBcnJheV0oI3ByZXBlbmRBcnJheSlcbiAqIC0gW3NwbGljZUl0ZW1dKCNzcGxpY2VJdGVtKVxuICogLSBbdG9BcnJheV0oI3RvQXJyYXkpXG4gKiAtIFtvYmplY3RdKCNvYmplY3QpXG4gKiAtIFttYXBUb09iamVjdF0oI21hcFRvT2JqZWN0KVxuICogLSBbdW5pcXVlXSgjdW5pcXVlKVxuICogLSBbZGVlcEZvckVhY2hdKCNkZWVwRm9yRWFjaClcbiAqXG4gKiBUaGVzZSBtZXRob2RzIGNhbiBiZSBbY2hhaW5lZF0ocHJvdG8uanMuaHRtbCNQcm90bykuXG4gKi9cbnZhciBhcnJheU1ldGhvZHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICAvLyBmaW5kOiBzZWUgYmVsb3dcbiAgICAvLyBmaW5kSW5kZXg6IHNlZSBiZWxvd1xuICAgIGFwcGVuZEFycmF5OiBhcHBlbmRBcnJheSxcbiAgICBwcmVwZW5kQXJyYXk6IHByZXBlbmRBcnJheSxcbiAgICB0b0FycmF5OiB0b0FycmF5LFxuICAgIG9iamVjdDogb2JqZWN0LFxuICAgIG1hcFRvT2JqZWN0OiBtYXBUb09iamVjdCxcbiAgICB1bmlxdWU6IHVuaXF1ZSxcbiAgICBkZWVwRm9yRWFjaDogZGVlcEZvckVhY2gsXG4gICAgc3BsaWNlSXRlbTogc3BsaWNlSXRlbVxufTtcblxuXG4vKipcbiAqIEZ1bmN0aW9ucyB0aGF0IEFycmF5IFtpbXBsZW1lbnRzIG5hdGl2ZWx5XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9wcm90b3R5cGUjTWV0aG9kcykgYXJlIGFsc28gaW5jbHVkZWQgZm9yIGNvbnZlbmllbmNlIC0gdGhleSBjYW4gYmUgdXNlZCB3aXRoIGFycmF5LWxpa2Ugb2JqZWN0cyBhbmQgZm9yIGNoYWluaW5nIChuYXRpdmUgZnVuY3Rpb25zIGFyZSBhbHdheXMgY2FsbGVkKS5cbiAqIFRoZXNlIG1ldGhvZHMgY2FuIGJlIFtjaGFpbmVkXShwcm90by5qcy5odG1sI1Byb3RvKSB0b28uXG4gKi9cbnZhciBuYXRpdmVBcnJheU1ldGhvZHNOYW1lcyA9IFsgJ2pvaW4nLCAncG9wJywgJ3B1c2gnLCAnY29uY2F0JyxcbiAgICAncmV2ZXJzZScsICdzaGlmdCcsICd1bnNoaWZ0JywgJ3NsaWNlJywgJ3NwbGljZScsXG4gICAgJ3NvcnQnLCAnZmlsdGVyJywgJ2ZvckVhY2gnLCAnc29tZScsICdldmVyeScsXG4gICAgJ21hcCcsICdpbmRleE9mJywgJ2xhc3RJbmRleE9mJywgJ3JlZHVjZScsICdyZWR1Y2VSaWdodCddO1xuXG52YXIgbmF0aXZlQXJyYXlNZXRob2RzID0gbWFwVG9PYmplY3QuY2FsbChuYXRpdmVBcnJheU1ldGhvZHNOYW1lcyxcbiAgICAgICAgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZVttZXRob2ROYW1lXTtcbiAgICAgICAgfSk7XG5cbl9fLmV4dGVuZC5jYWxsKGFycmF5TWV0aG9kcywgbmF0aXZlQXJyYXlNZXRob2RzKTtcblxuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIEVTNiBbQXJyYXkgX19maW5kX18gbWV0aG9kXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9maW5kKSAobmF0aXZlIG1ldGhvZCBpcyB1c2VkIGlmIGF2YWlsYWJsZSkuXG4gKiBSZXR1cm5zIGFycmF5IGVsZW1lbnQgdGhhdCBwYXNzZXMgY2FsbGJhY2sgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBzZWxmIGFycmF5IHRvIHNlYXJjaCBpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgc2hvdWxkIHJldHVybiBgdHJ1ZWAgZm9yIGl0ZW0gdG8gcGFzcyB0aGUgdGVzdCwgcGFzc2VkIGB2YWx1ZWAsIGBpbmRleGAgYW5kIGBzZWxmYCBhcyBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBvcHRpb25hbCBjb250ZXh0IChgdGhpc2ApIG9mIGNhbGxiYWNrIGNhbGxcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuYXJyYXlNZXRob2RzLmZpbmQgPSBBcnJheS5wcm90b3R5cGUuZmluZFxuICAgIHx8IHV0aWxzLm1ha2VGaW5kTWV0aG9kKGFycmF5TWV0aG9kcy5mb3JFYWNoLCAndmFsdWUnKTtcblxuXG4vKipcbiAqIEltcGxlbWVudGF0aW9uIG9mIEVTNiBbQXJyYXkgX19maW5kSW5kZXhfXyBtZXRob2RdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2ZpbmRJbmRleCkgKG5hdGl2ZSBtZXRob2QgaXMgdXNlZCBpZiBhdmFpbGFibGUpLlxuICogUmV0dXJucyB0aGUgaW5kZXggb2YgYXJyYXkgZWxlbWVudCB0aGF0IHBhc3NlcyBjYWxsYmFjayB0ZXN0LiBSZXR1cm5zIGAtMWAgaWYgbm90IGZvdW5kLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlbGYgYXJyYXkgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBzaG91bGQgcmV0dXJuIGB0cnVlYCBmb3IgaXRlbSB0byBwYXNzIHRoZSB0ZXN0LCBwYXNzZWQgYHZhbHVlYCwgYGluZGV4YCBhbmQgYHNlbGZgIGFzIHBhcmFtZXRlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIG9wdGlvbmFsIGNvbnRleHQgKGB0aGlzYCkgb2YgY2FsbGJhY2sgY2FsbFxuICogQHJldHVybiB7SW50ZWdlcn1cbiAqL1xuYXJyYXlNZXRob2RzLmZpbmRJbmRleCA9IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXhcbiAgICB8fCB1dGlscy5tYWtlRmluZE1ldGhvZChhcnJheU1ldGhvZHMuZm9yRWFjaCwgJ2luZGV4Jyk7XG5cblxuLyoqXG4gKiBBcHBlbmRzIGBhcnJheVRvQXBwZW5kYCB0byB0aGUgZW5kIG9mIGFycmF5IGBzZWxmYCBpbiBwbGFjZSAoY2FuIGJlIGFuIGluc3RhbmNlIG9mIEFycmF5IG9yIGFycmF5LWxpa2Ugb2JqZWN0KS5cbiAqIENoYW5nZXMgdGhlIHZhbHVlIG9mIGBzZWxmYCAoaXQgdXNlcyBgQXJyYXkucHJvdG90eXBlLnNwbGljZWApIGFuZCByZXR1cm5zIGBzZWxmYC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBzZWxmIEFuIGFycmF5IHRoYXQgd2lsbCBiZSBtb2RpZmllZFxuICogQHBhcmFtIHtBcnJheXxBcnJheS1saWtlfSBhcnJheVRvQXBwZW5kIEFuIGFycmF5IHRoYXQgd2lsbCBiZSBhcHBlbmRlZFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIGFwcGVuZEFycmF5KGFycmF5VG9BcHBlbmQpIHtcbiAgICBpZiAoISBhcnJheVRvQXBwZW5kLmxlbmd0aCkgcmV0dXJuIHRoaXM7XG4gICAgaWYgKCEgQXJyYXkuaXNBcnJheShhcnJheVRvQXBwZW5kKSlcbiAgICAgICAgYXJyYXlUb0FwcGVuZCA9IHRvQXJyYXkuY2FsbChhcnJheVRvQXBwZW5kKTtcbiAgICBcbiAgICB2YXIgYXJncyA9IFt0aGlzLmxlbmd0aCwgMF0uY29uY2F0KGFycmF5VG9BcHBlbmQpO1xuICAgIGFycmF5TWV0aG9kcy5zcGxpY2UuYXBwbHkodGhpcywgYXJncyk7XG5cbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIFByZXBlbmRzIGBhcnJheVRvUHJlcGVuZGAgdG8gdGhlIGJlZ2lubmlnIG9mIGFycmF5IGBzZWxmYCBpbiBwbGFjZSAoY2FuIGJlIGFuIGluc3RhbmNlIG9mIEFycmF5IG9yIGFycmF5LWxpa2Ugb2JqZWN0KS5cbiAqIENoYW5nZXMgdGhlIHZhbHVlIG9mIGBzZWxmYCAoaXQgdXNlcyBgQXJyYXkucHJvdG90eXBlLnNwbGljZWApIGFuZCByZXR1cm5zIGBzZWxmYC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBzZWxmIEFuIGFycmF5IHRoYXQgd2lsbCBiZSBtb2RpZmllZFxuICogQHBhcmFtIHtBcnJheXxBcnJheS1saWtlfSBhcnJheVRvQXBwZW5kIEFuIGFycmF5IHRoYXQgd2lsbCBiZSBwcmVwZW5kZWRcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBwcmVwZW5kQXJyYXkoYXJyYXlUb1ByZXBlbmQpIHtcbiAgICBpZiAoISBhcnJheVRvUHJlcGVuZC5sZW5ndGgpIHJldHVybiB0aGlzO1xuICAgIGlmICghIEFycmF5LmlzQXJyYXkoYXJyYXlUb1ByZXBlbmQpKVxuICAgICAgICBhcnJheVRvUHJlcGVuZCA9IHRvQXJyYXkuY2FsbChhcnJheVRvUHJlcGVuZCk7XG5cbiAgICB2YXIgYXJncyA9IFswLCAwXS5jb25jYXQoYXJyYXlUb1ByZXBlbmQpO1xuICAgIGFycmF5TWV0aG9kcy5zcGxpY2UuYXBwbHkodGhpcywgYXJncyk7XG5cbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgaXRlbSBmcm9tIGFycmF5IHRoYXQgaXMgZm91bmQgdXNpbmcgaW5kZXhPZiAoaS5lLiAnPT09JylcbiAqIE1vZGlmaWVzIG9yaWdpbmFsIGFycmF5IGFuZCByZXR1cm5zIHRoZSByZWZlcmVuY2UgdG8gaXQuXG4gKiBcbiAqIEBwYXJhbSB7QXJyYXl9IHNlbGYgQW4gYXJyYXkgdGhhdCB3aWxsIGJlIG1vZGlmaWVkXG4gKiBAcGFyYW0gIHtBbnl9IGl0ZW0gaXRlbSB0byBiZSByZW1vdmVkXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gc3BsaWNlSXRlbShpdGVtKSB7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5pbmRleE9mKGl0ZW0pO1xuICAgIGlmIChpbmRleCA+PSAwKSB0aGlzLnNwbGljZShpbmRleCwgMSk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIG5ldyBhcnJheSBjcmVhdGVkIGZyb20gYXJyYXktbGlrZSBvYmplY3QgKGUuZy4sIGBhcmd1bWVudHNgIHBzZXVkby1hcnJheSkuXG4gKlxuICogQHBhcmFtIHtBcnJheS1saWtlfSBzZWxmIE9iamVjdCB3aXRoIG51bWVyaWMgcHJvcGVydHkgbGVuZ3RoXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheSgpIHtcbiAgICByZXR1cm4gYXJyYXlNZXRob2RzLnNsaWNlLmNhbGwodGhpcyk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGFuIG9iamVjdCBjcmVhdGVkIGZyb20gdGhlIGFycmF5IG9mIGBrZXlzYCBhbmQgb3B0aW9uYWwgYXJyYXkgb2YgYHZhbHVlc2AuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gc2VsZiBBcnJheSBvZiBrZXlzXG4gKiBAcGFyYW0ge0FycmF5fGFueX0gdmFsdWVzIE9wdGlvbmFsIGFycmF5IG9mIHZhbHVlcyBvciB0aGUgdmFsdWUgdG8gYmUgYXNzaWduZWQgdG8gZWFjaCBwcm9wZXJ0eS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gb2JqZWN0KHZhbHVlcykge1xuICAgIHZhciBvYmogPSB7fVxuICAgICAgICAsIHZhbHVlc0lzQXJyYXkgPSBBcnJheS5pc0FycmF5KHZhbHVlcyk7XG4gICAgYXJyYXlNZXRob2RzLmZvckVhY2guY2FsbCh0aGlzLCBmdW5jdGlvbihrZXksIGluZGV4KSB7XG4gICAgICAgIG9ialtrZXldID0gdmFsdWVzSXNBcnJheSA/IHZhbHVlc1tpbmRleF0gOiB2YWx1ZXM7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gb2JqO1xufVxuXG5cbi8qKlxuICogTWFwcyBhcnJheSB0byBvYmplY3QuXG4gKiBBcnJheSBlbGVtZW50cyBiZWNvbWUga2V5cywgdmFsdWUgYXJlIHRha2VuIGZyb20gYGNhbGxiYWNrYC5cbiAqIFxuICogQHBhcmFtIHtBcnJheX0gc2VsZiBBbiBhcnJheSB3aGljaCB2YWx1ZXMgd2lsbCBiZWNvbWUga2V5cyBvZiB0aGUgcmVzdWx0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsYmFjayBpcyBwYXNzZWQgYHZhbHVlYCwgYGluZGV4YCBhbmQgYHNlbGZgIGFuZCBzaG91bGQgcmV0dXJuIHZhbHVlIHRoYXQgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0LlxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgQW4gb3B0aW9uYWwgY29udGV4dCBvZiBpdGVyYXRpb24gKHRoZSB2YWx1ZW9mIGB0aGlzYCksIHdpbGwgYmUgdW5kZWZpbmVkIGlmIHRoaXMgcGFyYW1ldGVyIGlzIG5vdCBwYXNzZWQuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIG1hcFRvT2JqZWN0KGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwodGhpcywgZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICAgIHJlc3VsdFt2YWx1ZV0gPSBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpbmRleCwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgYXJyYXkgd2l0aG91dCBkdXBsaWNhdGVzLiBEb2VzIG5vdCBtb2RpZnkgb3JpZ2luYWwgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gc2VsZiBvcmlnaW5hbCBhcnJheVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgY29tcGFyaXNvbiBmdW5jdGlvbiwgc2hvdWxkIHJldHVybiB0cnVlIGZvciBlcXVhbCBpdGVtcywgXCI9PT1cIiBpcyB1c2VkIGlmIG5vdCBwYXNzZWQuXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdW5pcXVlKGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpbHRlcmVkID0gW107XG4gICAgaWYgKCEgY2FsbGJhY2spXG4gICAgICAgIGl0ZW1JbmRleCA9IGl0ZW1JbmRleE9mO1xuXG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaXRlbUluZGV4KGl0ZW0pO1xuICAgICAgICBpZiAoaW5kZXggPT0gLTEpXG4gICAgICAgICAgICBmaWx0ZXJlZC5wdXNoKGl0ZW0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZpbHRlcmVkO1xuXG5cbiAgICBmdW5jdGlvbiBpdGVtSW5kZXgoaXRlbSkge1xuICAgICAgICByZXR1cm4gYXJyYXlNZXRob2RzLmZpbmRJbmRleC5jYWxsKGZpbHRlcmVkLCBmdW5jdGlvbihpdCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGl0ZW0sIGl0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXRlbUluZGV4T2YoaXRlbSkge1xuICAgICAgICByZXR1cm4gZmlsdGVyZWQuaW5kZXhPZihpdGVtKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBJdGVyYXRlcyBhcnJheSBhbmQgZWxlbWVudHMgdGhhdCBhcmUgYXJyYXlzIGNhbGxpbmcgY2FsbGJhY2sgd2l0aCBlYWNoIGVsZW1lbnQgdGhhdCBpcyBub3QgYW4gYXJyYXkuIENhbiBiZSB1c2VkIHRvIGl0ZXJhdGUgb3ZlciBhcmd1bWVudHMgbGlzdCB0byBhdm9pZCBjaGVja2luZyB3aGV0aGVyIGFycmF5IG9yIGxpc3Qgb2YgcGFyYW1ldGVycyBpcyBwYXNzZWQuXG4gKlxuICogQHBhcmFtIHtBcnJheXxBcnJheS1saWtlfSBzZWxmIGFycmF5IG9mIGVsZW1lbnRzIGFuZCBhcnJheXN0byBpdGVyYXRlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIGZvciBlYWNoIGl0ZW0gdGhhdCBpcyBub3QgYW4gYXJyYXkuIENhbGxiYWNrIGlzIHBhc3NlZCBpdGVtLCBpbmRleCBhbmQgb3JpZ2luYWwgYXJyYXkgYXMgcGFyYW1ldGVycy5cbiAqIEBwYXJhbSB7QW55fSB0aGlzQXJnIG9wdGlvbmFsIGNhbGxiYWNrIGVudm9jYXRpb24gY29udGV4dFxuICovXG5mdW5jdGlvbiBkZWVwRm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIHZhciBpbmRleCA9IDAsIGFyciA9IHRoaXM7XG4gICAgX2RlZXBGb3JFYWNoLmNhbGwodGhpcyk7XG5cbiAgICBmdW5jdGlvbiBfZGVlcEZvckVhY2goKSB7XG4gICAgICAgIGFycmF5TWV0aG9kcy5mb3JFYWNoLmNhbGwodGhpcywgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSlcbiAgICAgICAgICAgICAgICBfZGVlcEZvckVhY2guY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgrKywgYXJyKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBtYWtlUHJvdG9GdW5jdGlvbiA9IHJlcXVpcmUoJy4vdXRpbHMnKS5tYWtlUHJvdG9GdW5jdGlvblxuICAgICwgcmVwZWF0ID0gcmVxdWlyZSgnLi9wcm90b191dGlsJykucmVwZWF0O1xuXG5cbi8qKlxuICogLSBbbWFrZUZ1bmN0aW9uXSgjbWFrZUZ1bmN0aW9uKVxuICogLSBbcGFydGlhbF0oI3BhcnRpYWwpXG4gKiAtIFtwYXJ0aWFsUmlnaHRdKCNwYXJ0aWFsUmlnaHQpXG4gKiAtIFttZW1vaXplXSgjbWVtb2l6ZSlcbiAqIC0gW2RlbGF5XSgjZGVsYXkpXG4gKiAtIFtkZWZlcl0oI2RlZmVyKVxuICogLSBbZGVsYXllZF0oI2RlbGF5ZWQpXG4gKiAtIFtkZWZlcnJlZF0oI2RlZmVycmVkKVxuICogLSBbZGVmZXJUaWNrc10oI2RlZmVyVGlja3MpXG4gKiAtIFtkZWxheU1ldGhvZF0oI2RlbGF5TWV0aG9kKVxuICogLSBbZGVmZXJNZXRob2RdKCNkZWZlck1ldGhvZClcbiAqIC0gW2RlYm91bmNlXSgjZGVib3VuY2UpXG4gKiAtIFt0aHJvdHRsZV0oI3Rocm90dGxlKVxuICogLSBbb25jZV0oI29uY2UpXG4gKiAtIFt3YWl0Rm9yXSgjd2FpdEZvcilcbiAqIC0gW25vdF0oI25vdClcbiAqXG4gKiBUaGVzZSBtZXRob2RzIGNhbiBiZSBbY2hhaW5lZF0ocHJvdG8uanMuaHRtbCNQcm90bylcbiAqL1xudmFyIGZ1bmN0aW9uTWV0aG9kcyA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIG1ha2VGdW5jdGlvbjogbWFrZUZ1bmN0aW9uLFxuICAgIHBhcnRpYWw6IHBhcnRpYWwsXG4gICAgcGFydGlhbFJpZ2h0OiBwYXJ0aWFsUmlnaHQsXG4gICAgbWVtb2l6ZTogbWVtb2l6ZSxcbiAgICBkZWxheTogZGVsYXksXG4gICAgZGVmZXI6IGRlZmVyLFxuICAgIGRlbGF5ZWQ6IGRlbGF5ZWQsXG4gICAgZGVmZXJyZWQ6IGRlZmVycmVkLFxuICAgIGRlZmVyVGlja3M6IGRlZmVyVGlja3MsXG4gICAgZGVsYXlNZXRob2Q6IGRlbGF5TWV0aG9kLFxuICAgIGRlZmVyTWV0aG9kOiBkZWZlck1ldGhvZCxcbiAgICBkZWJvdW5jZTogZGVib3VuY2UsXG4gICAgdGhyb3R0bGU6IHRocm90dGxlLFxuICAgIG9uY2U6IG9uY2UsXG4gICAgd2FpdEZvcjogd2FpdEZvcixcbiAgICBub3Q6IG5vdFxufTtcblxuXG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cblxuLyoqXG4gKiBTaW1pbGFybHkgdG8gRnVuY3Rpb24gY29uc3RydWN0b3IgY3JlYXRlcyBhIGZ1bmN0aW9uIGZyb20gY29kZS5cbiAqIFVubGlrZSBGdW5jdGlvbiBjb25zdHJ1Y3RvciwgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIGEgZnVuY3Rpb24gbmFtZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5ldyBmdW5jdGlvbiBuYW1lXG4gKiBAcGFyYW0ge1N0cmluZ30gYXJnMSwgYXJnMiwgLi4uIHRoZSBuYW1lcyBvZiBmdW5jdGlvbiBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge1N0cmluZ30gZnVuY0JvZHkgZnVuY3Rpb24gYm9keVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIG1ha2VGdW5jdGlvbihhcmcxLCBhcmcyLCBmdW5jQm9keSkge1xuICAgIHZhciBuYW1lID0gdGhpc1xuICAgICAgICAsIGNvdW50ID0gYXJndW1lbnRzLmxlbmd0aCAtIDFcbiAgICAgICAgLCBmdW5jQm9keSA9IGFyZ3VtZW50c1tjb3VudF1cbiAgICAgICAgLCBmdW5jXG4gICAgICAgICwgY29kZSA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKylcbiAgICAgICAgY29kZSArPSAnLCAnICsgYXJndW1lbnRzW2ldO1xuICAgIGNvZGUgPSBbJ2Z1bmMgPSBmdW5jdGlvbiAnLCBuYW1lLCAnKCcsIGNvZGUuc2xpY2UoMiksICcpIHtcXG4nXG4gICAgICAgICAgICAgICAgLCBmdW5jQm9keSwgJ1xcbn0nXS5qb2luKCcnKTtcbiAgICBldmFsKGNvZGUpO1xuICAgIHJldHVybiBmdW5jO1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGFzIGEgcmVzdWx0IG9mIHBhcnRpYWwgZnVuY3Rpb24gYXBwbGljYXRpb24gd2l0aCB0aGUgcGFzc2VkIHBhcmFtZXRlcnMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBGdW5jdGlvbiB0byBiZSBhcHBsaWVkXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBBcmd1bWVudHMgYWZ0ZXIgc2VsZiB3aWxsIGJlIHByZXBlbmRlZCB0byB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gY2FsbCB3aGVuIHRoZSBwYXJ0aWFsIGZ1bmN0aW9uIGlzIGNhbGxlZC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBwYXJ0aWFsKCkgeyAvLyAsIC4uLiBhcmd1bWVudHNcbiAgICB2YXIgZnVuYyA9IHRoaXM7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICB9O1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGFzIGEgcmVzdWx0IG9mIHBhcnRpYWwgZnVuY3Rpb24gYXBwbGljYXRpb24gd2l0aCB0aGUgcGFzc2VkIHBhcmFtZXRlcnMsIGJ1dCBwYXJhbWV0ZXJzIGFyZSBhcHBlbmRlZCBvbiB0aGUgcmlnaHQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBGdW5jdGlvbiB0byBiZSBhcHBsaWVkXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBBcmd1bWVudHMgYWZ0ZXIgc2VsZiB3aWxsIGJlIGFwcGVuZGVkIG9uIHRoZSByaWdodCB0byB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gY2FsbCB3aGVuIHRoZSBwYXJ0aWFsIGZ1bmN0aW9uIGlzIGNhbGxlZC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBwYXJ0aWFsUmlnaHQoKSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBmdW5jID0gdGhpcztcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIHNsaWNlLmNhbGwoYXJndW1lbnRzKS5jb25jYXQoYXJncykpO1xuICAgIH07XG59XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgbWVtb2l6ZWQgdmVyc2lvbiBvZiB0aGUgZnVuY3Rpb24gdXNpbmcgc3VwcGxpZWQgaGFzaCBmdW5jdGlvbiBhcyBrZXkuIElmIHRoZSBoYXNoIGlzIG5vdCBzdXBwbGllZCwgdXNlcyBpdHMgZmlyc3QgcGFyYW1ldGVyIGFzIHRoZSBoYXNoLlxuICogXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGZ1bmN0aW9uIHRvIGJlIG1lbW9pemVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNoRnVuYyBvcHRpb25hbCBoYXNoIGZ1bmN0aW9uIHRoYXQgaXMgcGFzc2VkIGFsbCBmdW5jdGlvbiBhcmd1bWVudHMgYW5kIHNob3VsZCByZXR1cm4gY2FjaGUga2V5LlxuICogQHBhcmFtIHtJbnRlZ2VyfSBsaW1pdCBvcHRpb25hbCBtYXhpbXVtIG51bWJlciBvZiByZXN1bHRzIHRvIGJlIHN0b3JlZCBpbiB0aGUgY2FjaGUuIDEwMDAgYnkgZGVmYXVsdC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBtZW1vaXplZCBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBtZW1vaXplKGhhc2hGdW5jLCBsaW1pdCkge1xuICAgIHZhciBmdW5jID0gdGhpcztcbiAgICB2YXIgY2FjaGUgPSB7fSwga2V5c0xpc3QgPSBbXTtcbiAgICBsaW1pdCA9IGxpbWl0IHx8IDEwMDA7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBrZXkgPSBoYXNoRnVuYyA/IGhhc2hGdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBhcmd1bWVudHNbMF07XG4gICAgICAgIGlmIChjYWNoZS5oYXNPd25Qcm9wZXJ0eShrZXkpKVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlW2tleV07XG5cbiAgICAgICAgdmFyIHJlc3VsdCA9IGNhY2hlW2tleV0gPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGtleXNMaXN0LnB1c2goa2V5KTtcblxuICAgICAgICBpZiAoa2V5c0xpc3QubGVuZ3RoID4gbGltaXQpXG4gICAgICAgICAgICBkZWxldGUgY2FjaGVba2V5c0xpc3Quc2hpZnQoKV07XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xufVxuXG5cbi8qKlxuICogRGVsYXlzIGZ1bmN0aW9uIGV4ZWN1dGlvbiBieSBhIGdpdmVuIHRpbWUgaW4gbWlsbGlzZWNvbmRzLlxuICogVGhlIGNvbnRleHQgaW4gZnVuY3Rpb24gd2hlbiBpdCBpcyBleGVjdXRlZCBpcyBzZXQgdG8gYG51bGxgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gdGhhdCBleGVjdXRpb24gaGFzIHRvIGJlIGRlbGF5ZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3YWl0IGFwcHJveGltYXRlIGRhbGF5IHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBvcHRpb25hbCBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gZGVsYXkod2FpdCkgeyAvLyAsIGFyZ3VtZW50c1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBfZGVsYXkodGhpcywgd2FpdCwgYXJncyk7XG59XG4gXG5cbi8qKlxuICogRGVmZXJzIGZ1bmN0aW9uIGV4ZWN1dGlvbiAoZXhlY3V0ZXMgYXMgc29vbiBhcyBleGVjdXRpb24gbG9vcCBiZWNvbWVzIGZyZWUpXG4gKiBUaGUgY29udGV4dCBpbiBmdW5jdGlvbiB3aGVuIGl0IGlzIGV4ZWN1dGVkIGlzIHNldCB0byBgbnVsbGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBmdW5jdGlvbiB0aGF0IGV4ZWN1dGlvbiBoYXMgdG8gYmUgZGVsYXllZFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgb3B0aW9uYWwgYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIGRlZmVyKCkgeyAvLyAsIGFyZ3VtZW50c1xuICAgIHJldHVybiBfZGVsYXkodGhpcywgMSwgYXJndW1lbnRzKTtcbn1cblxuZnVuY3Rpb24gX2RlbGF5KGZ1bmMsIHdhaXQsIGFyZ3MsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gc2V0VGltZW91dChmdW5jLmFwcGx5LmJpbmQoZnVuYywgY29udGV4dCB8fCBudWxsLCBhcmdzKSwgd2FpdCk7XG59XG5cbi8qKlxuICogU2FtZSBhcyBfLmRlZmVyLCB0YWtlcyBmaXJzdCBhcmd1bWVudCBhcyB0aGUgZnVuY3Rpb24gdG8gYmUgZGVmZXJyZWRcbiAqL1xudmFyIGRlZmVyRnVuYyA9IG1ha2VQcm90b0Z1bmN0aW9uKGRlZmVyKTtcblxuLyoqXG4gKiBEZWZlcnMgZnVuY3Rpb24gZXhlY3V0aW9uIGZvciBgdGltZXNgIHRpY2tzIChleGVjdXRlcyBhZnRlciBleGVjdXRpb24gbG9vcCBiZWNvbWVzIGZyZWUgYHRpbWVzYCB0aW1lcylcbiAqIFRoZSBjb250ZXh0IGluIGZ1bmN0aW9uIHdoZW4gaXQgaXMgZXhlY3V0ZWQgaXMgc2V0IHRvIGBudWxsYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGZ1bmN0aW9uIHRoYXQgZXhlY3V0aW9uIGhhcyB0byBiZSBkZWxheWVkXG4gKiBAcGFyYW0ge0ludGVnZXJ9IHRpY2tzIG51bWJlciBvZiB0aW1lcyB0byBkZWZlciBleGVjdXRpb25cbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIG9wdGlvbmFsIGFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBkZWZlclRpY2tzKHRpY2tzKSB7IC8vICwgYXJndW1lbnRzXG4gICAgaWYgKHRpY2tzIDwgMikgcmV0dXJuIGRlZmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdmFyIGFyZ3MgPSByZXBlYXQuY2FsbChkZWZlckZ1bmMsIHRpY2tzIC0gMSk7XG4gICAgYXJncyA9IGFyZ3MuY29uY2F0KHRoaXMsIHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7IFxuICAgIHJldHVybiBkZWZlckZ1bmMuYXBwbHkobnVsbCwgYXJncyk7XG59XG5cblxuLyoqXG4gKiBXb3JrcyBsaWtlIF8uZGVsYXkgYnV0IGFsbG93cyB0byBkZWZlciBtZXRob2QgY2FsbCBvZiBgc2VsZmAgd2hpY2ggd2lsbCBiZSB0aGUgZmlyc3QgXy5kZWxheU1ldGhvZCBwYXJhbWV0ZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBvYmplY3QgdG8gZGVsYXkgbWV0aG9kIGNhbGwgb2ZcbiAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfSBmdW5jT3JNZXRob2ROYW1lIGZ1bmN0aW9uIG9yIG5hbWUgb2YgbWV0aG9kXG4gKiBAcGFyYW0ge051bWJlcn0gd2FpdCBhcHByb3hpbWF0ZSBkYWxheSB0aW1lIGluIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgYXJndW1lbnRzIHRvIHBhc3MgdG8gbWV0aG9kXG4gKi9cbmZ1bmN0aW9uIGRlbGF5TWV0aG9kKGZ1bmNPck1ldGhvZE5hbWUsIHdhaXQpIHsgLy8gLCAuLi4gYXJndW1lbnRzXG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIF9kZWxheU1ldGhvZCh0aGlzLCBmdW5jT3JNZXRob2ROYW1lLCB3YWl0LCBhcmdzKTtcbn1cblxuXG4vKipcbiAqIFdvcmtzIGxpa2UgXy5kZWZlciBidXQgYWxsb3dzIHRvIGRlZmVyIG1ldGhvZCBjYWxsIG9mIGBzZWxmYCB3aGljaCB3aWxsIGJlIHRoZSBmaXJzdCBfLmRlZmVyTWV0aG9kIHBhcmFtZXRlclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIG9iamVjdCB0byBkZWZlciBtZXRob2QgY2FsbCBvZlxuICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGZ1bmNPck1ldGhvZE5hbWUgZnVuY3Rpb24gb3IgbmFtZSBvZiBtZXRob2RcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFyZ3VtZW50cyB0byBwYXNzIHRvIG1ldGhvZFxuICovXG5mdW5jdGlvbiBkZWZlck1ldGhvZChmdW5jT3JNZXRob2ROYW1lKSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBfZGVsYXlNZXRob2QodGhpcywgZnVuY09yTWV0aG9kTmFtZSwgMSwgYXJncyk7XG59XG5cbmZ1bmN0aW9uIF9kZWxheU1ldGhvZChvYmplY3QsIGZ1bmNPck1ldGhvZE5hbWUsIHdhaXQsIGFyZ3MpIHtcbiAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSB0eXBlb2YgZnVuY09yTWV0aG9kTmFtZSA9PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICA/IG9iamVjdFtmdW5jT3JNZXRob2ROYW1lXVxuICAgICAgICAgICAgICAgICAgICA6IGZ1bmNPck1ldGhvZE5hbWU7XG4gICAgICAgIGZ1bmMuYXBwbHkob2JqZWN0LCBhcmdzKTtcbiAgICB9LCB3YWl0KTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgZnVuY3Rpb24gdGhhdCB3aWxsIGV4ZWN1dGUgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uIGB3YWl0YCBtcyBhZnRlciBpdCBoYXMgYmVlbiBjYWxsZWRcbiAqIFRoZSBjb250ZXh0IGluIGZ1bmN0aW9uIHdoZW4gaXQgaXMgZXhlY3V0ZWQgaXMgc2V0IHRvIGBudWxsYC5cbiAqIEFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIGFyZSBhcHBlbmRlZCB0byB0aGUgYXJndW1lbnRzIHBhc3NlZCB0byBkZWxheWVkLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gd2hpY2ggZXhlY3V0aW9uIGhhcyB0byBiZSBkZWZlcnJlZFxuICogQHBhcmFtIHtOdW1iZXJ9IHdhaXQgYXBwcm94aW1hdGUgZGFsYXkgdGltZSBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIG9wdGlvbmFsIGFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBmdW5jdGlvblxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIGRlbGF5ZWQod2FpdCkgeyAvLywgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBmdW5jID0gdGhpc1xuICAgICAgICAsIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyAvLyAuLi4gYXJndW1lbnRzXG4gICAgICAgIHZhciBwYXNzQXJncyA9IGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgICAgIHJldHVybiBfZGVsYXkoZnVuYywgd2FpdCwgcGFzc0FyZ3MsIHRoaXMpO1xuICAgIH07XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGZ1bmN0aW9uIHRoYXQgd2lsbCBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBvbiB0aGUgbmV4dCB0aWNrIG9uY2UgaXQgaGFzIGJlZW4gY2FsbGVkXG4gKiBUaGUgY29udGV4dCBpbiBmdW5jdGlvbiB3aGVuIGl0IGlzIGV4ZWN1dGVkIGlzIHNldCB0byBgbnVsbGAuXG4gKiBBcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbiBhcmUgYXBwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBwYXNzZWQgdG8gZGVmZXJyZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBmdW5jdGlvbiB3aGljaCBleGVjdXRpb24gaGFzIHRvIGJlIGRlZmVycmVkXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBvcHRpb25hbCBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBkZWZlcnJlZCgpIHsgLy8sIC4uLiBhcmd1bWVudHNcbiAgICB2YXIgZnVuYyA9IHRoaXNcbiAgICAgICAgLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgLy8gLi4uIGFyZ3VtZW50c1xuICAgICAgICB2YXIgcGFzc0FyZ3MgPSBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgICAgICByZXR1cm4gX2RlbGF5KGZ1bmMsIDEsIHBhc3NBcmdzLCB0aGlzKTtcbiAgICB9O1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBjYWxsIG9yaWdpbmFsIGZ1bmN0aW9uIG9uY2UgaXQgaGFzIG5vdCBiZWVuIGNhbGxlZCBmb3IgYSBzcGVjaWZpZWQgdGltZVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gdGhhdCBleGVjdXRpb24gaGFzIHRvIGJlIGRlbGF5ZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3YWl0IGFwcHJveGltYXRlIGRhbGF5IHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGltbWVkaWF0ZSB0cnVlIHRvIGludm9rZSBmdW5jaXRvbiBpbW1lZGlhdGVseSBhbmQgdGhlbiBpZ25vcmUgZm9sbG93aW5nIGNhbGxzIGZvciB3YWl0IG1pbGxpc2Vjb25kc1xuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlKHdhaXQsIGltbWVkaWF0ZSkge1xuICAgIHZhciBmdW5jID0gdGhpczsgLy8gZmlyc3QgcGFyYW1ldGVyIG9mIF8uZGVib3VuY2VcbiAgICB2YXIgdGltZW91dCwgYXJncywgY29udGV4dCwgdGltZXN0YW1wLCByZXN1bHQ7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBjb250ZXh0ID0gdGhpczsgLy8gc3RvcmUgb3JpZ2luYWwgY29udGV4dFxuICAgICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgICB2YXIgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhIHRpbWVvdXQ7XG4gICAgICAgIGlmICghIHRpbWVvdXQpXG4gICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCk7XG4gICAgICAgIGlmIChjYWxsTm93KVxuICAgICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcblxuICAgICAgICBmdW5jdGlvbiBsYXRlcigpIHtcbiAgICAgICAgICAgIHZhciBsYXN0ID0gRGF0ZS5ub3coKSAtIHRpbWVzdGFtcDtcbiAgICAgICAgICAgIGlmIChsYXN0IDwgd2FpdClcbiAgICAgICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCAtIGxhc3QpO1xuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKCEgaW1tZWRpYXRlKVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiwgdGhhdCwgd2hlbiBpbnZva2VkLCB3aWxsIG9ubHkgYmUgdHJpZ2dlcmVkIGF0IG1vc3Qgb25jZSBkdXJpbmcgYSBnaXZlbiB3aW5kb3cgb2YgdGltZS4gXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBmdW5jdGlvbiB0aGF0IGV4ZWN1dGlvbiBoYXMgdG8gYmUgZGVsYXllZFxuICogQHBhcmFtIHtOdW1iZXJ9IHdhaXQgYXBwcm94aW1hdGUgZGVsYXkgdGltZSBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGB7bGVhZGluZzogZmFsc2V9YCB0byBkaXNhYmxlIHRoZSBleGVjdXRpb24gb24gdGhlIGxlYWRpbmcgZWRnZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIHRocm90dGxlKHdhaXQsIG9wdGlvbnMpIHtcbiAgICB2YXIgZnVuYyA9IHRoaXM7IC8vIGZpcnN0IHBhcmFtZXRlciBvZiBfLnRocm90dGxlXG4gICAgdmFyIGNvbnRleHQsIGFyZ3MsIHJlc3VsdDtcbiAgICB2YXIgdGltZW91dCA9IG51bGw7XG4gICAgdmFyIHByZXZpb3VzID0gMDtcbiAgICBvcHRpb25zIHx8IChvcHRpb25zID0ge30pO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgaWYgKCFwcmV2aW91cyAmJiBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlKSBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgdmFyIHJlbWFpbmluZyA9IHdhaXQgLSAobm93IC0gcHJldmlvdXMpO1xuICAgICAgICBjb250ZXh0ID0gdGhpcztcbiAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgaWYgKHJlbWFpbmluZyA8PSAwKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgICAgIHByZXZpb3VzID0gbm93O1xuICAgICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgfSBlbHNlIGlmICghdGltZW91dCAmJiBvcHRpb25zLnRyYWlsaW5nICE9PSBmYWxzZSlcbiAgICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCByZW1haW5pbmcpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGxhdGVyKCkge1xuICAgICAgICBwcmV2aW91cyA9IG9wdGlvbnMubGVhZGluZyA9PT0gZmFsc2UgPyAwIDogRGF0ZS5ub3coKTtcbiAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogQ2FsbCBwYXNzZWQgZnVuY3Rpb24gb25seSBvbmNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gc2VsZlxuICovXG5mdW5jdGlvbiBvbmNlKCkge1xuICAgIHZhciBmdW5jID0gdGhpc1xuICAgICAgICAsIHJhbiA9IGZhbHNlXG4gICAgICAgICwgbWVtbztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChyYW4pIHJldHVybiBtZW1vO1xuICAgICAgICByYW4gPSB0cnVlO1xuICAgICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICBmdW5jID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIEV4ZWN1dGUgYSBmdW5jdGlvbiB3aGVuIHRoZSBjb25kaXRpb24gZnVuY3Rpb24gcmV0dXJucyBhIHRydXRoeSB2YWx1ZVxuICogaXQgcnVucyB0aGUgY29uZGl0aW9uIGZ1bmN0aW9uIGV2ZXJ5IGBjaGVja0ludGVydmFsYCBtaWxsaXNlY29uZHMgKGRlZmF1bHQgNTApXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBmdW5jdGlvbjogaWYgaXQgcmV0dXJucyB0cnVlIHRoZSBjYWxsYmFjayBpcyBleGVjdXRlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgcnVucyB3aGVuIHRoZSBjb25kaXRpb24gaXMgdHJ1ZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1heFRpbWVvdXQgdGltZW91dCBiZWZvcmUgZ2l2aW5nIHVwICh0aW1lIGluIG1pbGxpc2Vjb25kcylcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRpbWVkT3V0RnVuYyBhIGZ1bmN0aW9uIGNhbGxlZCBpZiB0aW1lb3V0IGlzIHJlYWNoZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSBjaGVja0ludGVydmFsIHRpbWUgaW50ZXJ2YWwgd2hlbiB5b3UgcnVuIHRoZSBjb25kaXRpb24gZnVuY3Rpb24gKHRpbWUgaW4gbWlsbGlzZWNvbmRzKSwgZGVmYXVsdCA1MCBtc1xuICovXG5mdW5jdGlvbiB3YWl0Rm9yKGNhbGxiYWNrLCBtYXhUaW1lb3V0LCB0aW1lZE91dEZ1bmMsIGNoZWNrSW50ZXJ2YWwpe1xuICAgIHZhciBzdGFydCA9IERhdGUubm93KCk7XG4gICAgdmFyIGNvbmRpdGlvbiA9IHRoaXM7XG4gICAgY2hlY2tJbnRlcnZhbCA9IGNoZWNrSW50ZXJ2YWwgfHwgNTA7XG4gICAgdmFyIGludGVydmFsID0gc2V0SW50ZXJ2YWwodGVzdENvbmRpdGlvbiwgY2hlY2tJbnRlcnZhbCk7XG5cbiAgICBmdW5jdGlvbiB0ZXN0Q29uZGl0aW9uKCkge1xuICAgICAgICBpZiAoY29uZGl0aW9uKCkpIGNhbGxiYWNrKCk7XG4gICAgICAgIGVsc2UgaWYgKERhdGUubm93KCkgLSBzdGFydCA+PSBtYXhUaW1lb3V0KVxuICAgICAgICAgICAgdGltZWRPdXRGdW5jICYmIHRpbWVkT3V0RnVuYygpO1xuICAgICAgICBlbHNlIHJldHVybjtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIHJldHVybnMgdGhlIGZ1bmN0aW9uIHRoYXQgbmVnYXRlcyAoISBvcGVyYXRvcikgdGhlIHJlc3VsdCBvZiB0aGUgb3JpZ2luYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gdG8gbmVnYXRlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gbm90KCkge1xuICAgIHZhciBmdW5jID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiAhZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogLSBbaXNOdW1lcmljXSgjaXNOdW1lcmljKVxuICovXG52YXIgbnVtYmVyTWV0aG9kcyA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGlzTnVtZXJpYzogaXNOdW1lcmljXG59O1xuXG5cbi8qKlxuICogRnVuY3Rpb24gdG8gdGVzdCBpZiBhIHZhbHVlIGlzIG51bWVyaWNcbiAqXG4gKiBAcGFyYW0ge0FueX0gc2VsZiB2YWx1ZSB0byBiZSB0ZXN0ZWRcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgaXQgaXMgYSBudW1lcmljIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGlzTnVtZXJpYygpIHtcbiAgICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQodGhpcykpICYmIGlzRmluaXRlKHRoaXMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cblxuLyoqXG4gKiAtIFtleHRlbmRdKCNleHRlbmQpXG4gKiAtIFtjbG9uZV0oI2Nsb25lKVxuICogLSBbZGVmaW5lUHJvcGVydHldKCNkZWZpbmVQcm9wZXJ0eSlcbiAqIC0gW2RlZmluZVByb3BlcnRpZXNdKCNkZWZpbmVQcm9wZXJ0aWVzKVxuICogLSBbZGVlcEV4dGVuZF0oI2RlZXBFeHRlbmQpXG4gKiAtIFtkZWVwQ2xvbmVdKCNkZWVwQ2xvbmUpXG4gKiAtIFtrZXlzXSgja2V5cylcbiAqIC0gW2FsbEtleXNdKCNhbGxLZXlzKVxuICogLSBbdmFsdWVzXSgjdmFsdWVzKVxuICogLSBba2V5T2ZdKCNrZXlPZilcbiAqIC0gW2FsbEtleXNPZl0oI2FsbEtleXNPZilcbiAqIC0gW2VhY2hLZXldKCNlYWNoS2V5KVxuICogLSBbbWFwS2V5c10oI21hcEtleXMpXG4gKiAtIFtyZWR1Y2VLZXlzXSgjcmVkdWNlS2V5cylcbiAqIC0gW2ZpbHRlcktleXNdKCNmaWx0ZXJLZXlzKVxuICogLSBbc29tZUtleV0oI3NvbWVLZXkpXG4gKiAtIFtldmVyeUtleV0oI2V2ZXJ5S2V5KVxuICogLSBbZmluZFZhbHVlXSgjZmluZFZhbHVlKVxuICogLSBbZmluZEtleV0oI2ZpbmRLZXkpXG4gKiAtIFtwaWNrS2V5c10oI3BpY2tLZXlzKVxuICogLSBbb21pdEtleXNdKCNvbWl0S2V5cylcbiAqIC0gW2lzRXF1YWxdKCNpc0VxdWFsKVxuICogLSBbaXNOb3RdKCNpc05vdClcbiAqXG4gKiBBbGwgdGhlc2UgbWV0aG9kcyBjYW4gYmUgW2NoYWluZWRdKHByb3RvLmpzLmh0bWwjUHJvdG8pXG4gKi9cbnZhciBvYmplY3RNZXRob2RzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZXh0ZW5kOiBleHRlbmQsXG4gICAgY2xvbmU6IGNsb25lLFxuICAgIGRlZmluZVByb3BlcnR5OiBkZWZpbmVQcm9wZXJ0eSxcbiAgICBkZWZpbmVQcm9wZXJ0aWVzOiBkZWZpbmVQcm9wZXJ0aWVzLFxuICAgIGRlZXBFeHRlbmQ6IGRlZXBFeHRlbmQsXG4gICAgZGVlcENsb25lOiBkZWVwQ2xvbmUsXG4gICAga2V5czoga2V5cyxcbiAgICBhbGxLZXlzOiBhbGxLZXlzLFxuICAgIHZhbHVlczogdmFsdWVzLFxuICAgIGtleU9mOiBrZXlPZixcbiAgICBhbGxLZXlzT2Y6IGFsbEtleXNPZixcbiAgICBlYWNoS2V5OiBlYWNoS2V5LFxuICAgIG1hcEtleXM6IG1hcEtleXMsXG4gICAgcmVkdWNlS2V5czogcmVkdWNlS2V5cyxcbiAgICBmaWx0ZXJLZXlzOiBmaWx0ZXJLZXlzLFxuICAgIHNvbWVLZXk6IHNvbWVLZXksXG4gICAgZXZlcnlLZXk6IGV2ZXJ5S2V5LFxuICAgIHBpY2tLZXlzOiBwaWNrS2V5cyxcbiAgICBvbWl0S2V5czogb21pdEtleXMsXG4gICAgaXNFcXVhbDogaXNFcXVhbCxcbiAgICBpc05vdDogaXNOb3Rcbn07XG5cblxuLyoqXG4gKiAjIyMjUHJvcGVydHkgZGVzY3JpcHRvciBjb25zdGFudHMjIyMjXG4gKiBUaGUgc3VtIG9mIHRoZXNlIGNvbnN0YW50cyBjYW4gYmUgdXNlZCBhcyBsYXN0IHBhcmFtZXRlciBvZiBkZWZpbmVQcm9wZXJ0eSBhbmQgZGVmaW5lUHJvcGVydGllcyB0byBkZXRlcm1pbmUgdHlwZXMgb2YgcHJvcGVydGllcy5cbiAqL1xudmFyIGNvbnN0YW50cyA9IHtcbiAgICBFTlVNRVJBQkxFOiAxLFxuICAgIEVOVU06IDEsXG4gICAgQ09ORklHVVJBQkxFOiAyLFxuICAgIENPTkY6IDIsXG4gICAgV1JJVEFCTEU6IDQsXG4gICAgV1JJVDogNFxufTtcblxuZGVmaW5lUHJvcGVydHkuY2FsbChvYmplY3RNZXRob2RzLCAnX2NvbnN0YW50cycsIGNvbnN0YW50cyk7XG5cblxuLyoqXG4gKiBBbmFsb2d1ZSBvZiBFUzYgW0FycmF5IF9fZmluZF9fIG1ldGhvZF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZmluZCkuXG4gKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBvYmplY3QgcHJvcGVydHkgdGhhdCBwYXNzZXMgY2FsbGJhY2sgdGVzdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBvYmplY3QgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBzaG91bGQgcmV0dXJuIGB0cnVlYCBmb3IgaXRlbSB0byBwYXNzIHRoZSB0ZXN0LCBwYXNzZWQgYHZhbHVlYCwgYGtleWAgYW5kIGBzZWxmYCBhcyBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBvcHRpb25hbCBjb250ZXh0IChgdGhpc2ApIG9mIGNhbGxiYWNrIGNhbGxcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgYHRydWVgIHRvIGl0ZXJhdGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbm9iamVjdE1ldGhvZHMuZmluZFZhbHVlID0gdXRpbHMubWFrZUZpbmRNZXRob2QoZWFjaEtleSwgJ3ZhbHVlJyk7XG5cblxuLyoqXG4gKiBBbmFsb2d1ZSBvZiBFUzYgW0FycmF5IF9fZmluZEluZGV4X18gbWV0aG9kXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9maW5kSW5kZXgpLlxuICogUmV0dXJucyB0aGUga2V5IG9mIG9iamVjdCBwcm9wZXJ0eSB0aGF0IHBhc3NlcyBjYWxsYmFjayB0ZXN0LiBSZXR1cm5zIGB1bmRlZmluZWRgIGlmIG5vdCBmb3VuZCAodW5saWtlIGBmaW5kSW5kZXhgLCB0aGF0IHJldHVybnMgLTEgaW4gdGhpcyBjYXNlKS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBvYmplY3QgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBzaG91bGQgcmV0dXJuIGB0cnVlYCBmb3IgaXRlbSB0byBwYXNzIHRoZSB0ZXN0LCBwYXNzZWQgYHZhbHVlYCwgYGtleWAgYW5kIGBzZWxmYCBhcyBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBvcHRpb25hbCBjb250ZXh0IChgdGhpc2ApIG9mIGNhbGxiYWNrIGNhbGxcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgYHRydWVgIHRvIGl0ZXJhdGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfVxuICovXG5vYmplY3RNZXRob2RzLmZpbmRLZXkgPSB1dGlscy5tYWtlRmluZE1ldGhvZChlYWNoS2V5LCAna2V5Jyk7XG5cblxuLyoqXG4gKiBFeHRlbmRzIG9iamVjdCBgc2VsZmAgd2l0aCB0aGUgcHJvcGVydGllcyBvZiB0aGUgb2JqZWN0IGBvYmpgIGNvcHlpbmcgYWxsIG93biBwcm9wZXJ0aWVzIChub3QgdGhvc2UgaW5oZXJpdGVkIHZpYSBwcm90b3R5cGUgY2hhaW4pLCBpbmNsdWRpbmcgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyAodW5sZXNzIGBvbmx5RW51bWVyYWJsZWAgaXMgdHJ1dGh5KS5cbiAqIENyZWF0ZWQgcHJvcGVydGllcyB3aWxsIGhhdmUgdGhlIHNhbWUgZGVzY3JpcHRvcnMgYXMgdGhlIHByb3BlcnRpcyBvZiBgb2JqYC5cbiAqIFJldHVybnMgYHNlbGZgIHRvIGFsbG93IGNoYWluaW5nIHdpdGggb3RoZXIgZnVuY3Rpb25zLlxuICogQ2FuIGJlIHVzZWQgd2l0aCBmdW5jdGlvbnMsIHRvIGNvcHkgY2xhc3MgbWV0aG9kcywgZS5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBiZSBleHRlbmRlZFxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBBbiBvYmplY3Qgd2hpY2ggcHJvcGVydGllcyB3aWxsIGJlIGNvcGllZCB0byBzZWxmXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIE9wdGlvbmFsIGZsYWcgdG8gcHJldmVudCBjb3B5aW5nIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMsIGBmYWxzZWAgYnkgZGVmYXVsdFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBleHRlbmQob2JqLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBkZXNjcmlwdG9ycyA9IHt9O1xuXG4gICAgZWFjaEtleS5jYWxsKG9iaiwgZnVuY3Rpb24odmFsdWUsIHByb3ApIHtcbiAgICAgICAgZGVzY3JpcHRvcnNbcHJvcF0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwgcHJvcCk7XG4gICAgfSwgdGhpcywgb25seUVudW1lcmFibGUpO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgZGVzY3JpcHRvcnMpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBNYWtlcyBhIHNoYWxsb3cgY2xvbmUgb2Ygb2JqZWN0IGBvYmpgIGNyZWF0aW5nIGFuIGluc3RhbmNlIG9mIHRoZSBzYW1lIGNsYXNzOyB0aGUgcHJvcGVydGllcyB3aWxsIGhhdmUgdGhlIHNhbWUgZGVzY3JpcHRvcnMuXG4gKiBUbyBjbG9uZSBhbiBhcnJheSB1c2VcbiAqIGBgYFxuICogdmFyIGNsb25lZEFycmF5ID0gW10uY29uY2F0KGFycik7XG4gKiBgYGBcbiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG5vdCBiZSB1c2VkIHRvIGNsb25lIGFuIGFycmF5LCBiZWNhdXNlIGl0IGlzIGluZWZmaWNpZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBiZSBjbG9uZWRcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gY2xvbmUoKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcykpIHJldHVybiB0aGlzLnNsaWNlKCk7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gbmV3IERhdGUodGhpcyk7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiBuZXcgUmVnRXhwKHRoaXMpO1xuICAgIHZhciBjbG9uZWRPYmplY3QgPSBPYmplY3QuY3JlYXRlKHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlKTtcbiAgICBleHRlbmQuY2FsbChjbG9uZWRPYmplY3QsIHRoaXMpO1xuICAgIHJldHVybiBjbG9uZWRPYmplY3Q7XG59XG5cblxuLyoqXG4gKiBTeW50YXggc3VnYXIgdG8gc2hvcnRlbiB1c2FnZSBvZiBgT2JqZWN0LmRlZmluZVByb3BlcnR5YC5cbiAqIFRoZSBzaW1wbGVzdCB1c2FnZSAodG8gYWRkIG5vbi1lbnVtZXJhYmxlLCBub24tY29uZmlndXJhYmxlLCBub24td3JpdGFibGUgcHJvcGVydHkpOlxuICogYGBgXG4gKiBfLmRlZmluZVByb3BlcnR5KG9iaiwgJ2tleScsIHZhbHVlKTtcbiAqIGBgYFxuICpcbiAqIFRvIGRlZmluZSBzb21lIG90aGVyIHByb3BlcnRpZXMgdXNlIHN1bSBvZiB0aGUgZmxhZ3MgYF8uRU5VTUVSQUJMRWAgKG9yIGBfLkVOVU1gKSwgYF8uQ09ORklHVVJBQkxFYCAob3IgYF8uQ09ORmApIGFuZCBgXy5XUklUQUJMRWAgKG9yIGBfLldSSVRgKTpcbiAqIGBgYFxuICogXy5kZWZpbmVQcm9wZXJ0eShvYmosICdrZXknLCB2YWx1ZSwgXy5FTlVNICsgXy5XUklUKTtcbiAqIGBgYFxuICogUmV0dXJucyBgc2VsZmAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHRvIGFkZCBhIHByb3BlcnR5IHRvXG4gKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlOYW1lIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0aGF0IHdpbGwgYmUgYWRkZWRcbiAqIEBwYXJhbSB7QW55fSB2YWx1ZSB0aGUgdmFsdWUgb2YgYWRkZWQgcHJvcGVydHlcbiAqIEBwYXJhbSB7SW50ZWdlcn0gZGVjcmlwdG9yRmxhZ3MgYml0IG1hc2sgb2YgcHJvcGVydHkgZGVzY3JpcHRvciBwcm9wZXJ0aWVzIGNvbXBvc2VkIGZyb20gYF8uRU5VTUVSQUJMRWAgKG9yIGBfLkVOVU1gKSwgYF8uQ09ORklHVVJBQkxFYCAob3IgYF8uQ09ORmApIGFuZCBgXy5XUklUQUJMRWAgKG9yIGBfLldSSVRgKVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShwcm9wZXJ0eU5hbWUsIHZhbHVlLCBkZWNyaXB0b3JGbGFncykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBwcm9wZXJ0eU5hbWUsXG4gICAgICAgIF9nZXREZXNjcmlwdG9yKHZhbHVlLCBkZWNyaXB0b3JGbGFncykpO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbmZ1bmN0aW9uIF9nZXREZXNjcmlwdG9yKHZhbHVlLCBkZWNyaXB0b3JGbGFncykge1xuICAgIHZhciBkZXNjcmlwdG9yID0geyB2YWx1ZTogdmFsdWUgfTtcbiAgICBpZiAoZGVjcmlwdG9yRmxhZ3MpXG4gICAgICAgIGV4dGVuZC5jYWxsKGRlc2NyaXB0b3IsIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6ICEhIChkZWNyaXB0b3JGbGFncyAmIGNvbnN0YW50cy5FTlVNRVJBQkxFKSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogISEgKGRlY3JpcHRvckZsYWdzICYgY29uc3RhbnRzLkNPTkZJR1VSQUJMRSksXG4gICAgICAgICAgICB3cml0YWJsZTogISEgKGRlY3JpcHRvckZsYWdzICYgY29uc3RhbnRzLldSSVRBQkxFKVxuICAgICAgICB9KTtcblxuICAgIHJldHVybiBkZXNjcmlwdG9yO1xufVxuXG5cbi8qKlxuICogU3ludGF4IHN1Z2FyIHRvIHNob3J0ZW4gdXNhZ2Ugb2YgYE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzYC5cbiAqIFRoZSBzaW1wbGVzdCB1c2FnZSAodG8gYWRkIG5vbi1lbnVtZXJhYmxlLCBub24tY29uZmlndXJhYmxlLCBub24td3JpdGFibGUgcHJvcGVydGllcyk6XG4gKiBgYGBcbiAqIF8uZGVmaW5lUHJvcGVydGllcyhvYmosIHtcbiAqICAgICBrZXkxOiB2YWx1ZTEsXG4gKiAgICAga2V5MjogdmFsdWUyXG4gKiB9KTtcbiAqIGBgYFxuICogVG8gZGVmaW5lIHNvbWUgb3RoZXIgcHJvcGVydGllcyB1c2Ugc3VtIG9mIHRoZSBmbGFncyBgXy5FTlVNRVJBQkxFYCAob3IgYF8uRU5VTWApLCBgXy5DT05GSUdVUkFCTEVgIChvciBgXy5DT05GYCkgYW5kIGBfLldSSVRBQkxFYCAob3IgYF8uV1JJVGApOlxuICogYGBgXG4gKiBfLmRlZmluZVByb3BlcnRpZXMob2JqLCB7XG4gKiAgICAga2V5MTogdmFsdWUxLFxuICogICAgIGtleTI6IHZhbHVlMlxuICogfSwgXy5FTlVNICsgXy5XUklUKTtcbiAqIGBgYFxuICogUmV0dXJucyBgc2VsZmAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHRvIGFkZCBhIHByb3BlcnR5IHRvXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydHlWYWx1ZXMgQSBtYXAgb2Yga2V5cyBhbmQgdmFsdWVzIG9mIHByb3BlcnRpZXMgdGhhdHdpbGwgYmUgYWRkZWQuIFRoZSBkZXNjcmlwdG9ycyBvZiBwcm9wZXJ0aWVzIHdpbGwgYmUgZGVmaW5lZCBieSB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGRlY3JpcHRvckZsYWdzIGJpdCBtYXNrIG9mIHByb3BlcnR5IGRlc2NyaXB0b3IgcHJvcGVydGllcyBjb21wb3NlZCBmcm9tIGBfLkVOVU1FUkFCTEVgIChvciBgXy5FTlVNYCksIGBfLkNPTkZJR1VSQUJMRWAgKG9yIGBfLkNPTkZgKSBhbmQgYF8uV1JJVEFCTEVgIChvciBgXy5XUklUYClcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhwcm9wZXJ0eVZhbHVlcywgZGVjcmlwdG9yRmxhZ3MpIHtcbiAgICB2YXIgZGVzY3JpcHRvcnMgPSBtYXBLZXlzLmNhbGwocHJvcGVydHlWYWx1ZXMsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBfZ2V0RGVzY3JpcHRvcih2YWx1ZSwgZGVjcmlwdG9yRmxhZ3MpO1xuICAgIH0sIHRydWUpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIGRlc2NyaXB0b3JzKTtcbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEV4dGVuZHMgb2JqZWN0IGBzZWxmYCB3aXRoIHByb3BlcnRpZXMgb2YgYG9iamAgdG8gYW55IGRlcHRoLCB3aXRob3V0IG92ZXJ3cnRpdGluZyBleGlzdGluZyBvYmplY3QgcHJvcGVydGllcyBvZiBgc2VsZmAgd2l0aCBvYmplY3QgcHJvcGVydGllcyBvZiBgb2JqYC5cbiAqIFNjYWxhciBwcm9wZXJ0aWVzIG9mIGBvYmpgIHdpbGwgb3ZlcndyaXRlIHByb3BlcnRpZXMgb2YgYHNlbGZgLiBTY2FsYXIgcG9ycGVydGllcyBvZiBgc2VsZmAgd2lsbCBhbHNvIGJlIG92ZXJ3cml0dGVuLlxuICogQ29ycmVjdGx5IHdvcmtzIHdpdGggcmVjdXJzaXZlIG9iamVjdHMuXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogdmFyIG9iaiA9IHtcbiAqICAgICBpbm5lcjoge1xuICogICAgICAgICBhOiAxXG4gKiAgICAgfVxuICogfTtcbiAqXG4gKiBfLmRlZXBFeHRlbmQob2JqLCB7XG4gKiAgICAgaW5uZXI6IHtcbiAqICAgICAgICAgYjogMlxuICogICAgIH1cbiAqIH0pO1xuICpcbiAqIGFzc2VydC5kZWVwRXF1YWwob2JqLCB7XG4gKiAgICAgaW5uZXI6IHtcbiAqICAgICAgICAgYTogMSxcbiAqICAgICAgICAgYjogMlxuICogICAgIH1cbiAqIH0pOyAvLyBhc3NlcnQgcGFzc2VzXG4gKiBgYGBcbiAqIFJldHVybnMgYHNlbGZgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBiZSBleHRlbmRlZFxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBBbiBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIHRvIGNvcHkgdG9cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgT3B0aW9uYWwgYHRydWVgIHRvIHVzZSBvbmx5IGVudW1lcmFibGUgcHJvcGVydGllc1xuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBkZWVwRXh0ZW5kKG9iaiwgb25seUVudW1lcmFibGUpIHtcbiAgICByZXR1cm4gX2V4dGVuZFRyZWUodGhpcywgb2JqLCBvbmx5RW51bWVyYWJsZSwgW10pO1xufVxuXG5cbmZ1bmN0aW9uIF9leHRlbmRUcmVlKHNlbGZOb2RlLCBvYmpOb2RlLCBvbmx5RW51bWVyYWJsZSwgb2JqVHJhdmVyc2VkKSB7XG4gICAgaWYgKG9ialRyYXZlcnNlZC5pbmRleE9mKG9iak5vZGUpID49IDApIHJldHVybjsgLy8gbm9kZSBhbHJlYWR5IHRyYXZlcnNlZCwgb2JqIGhhcyByZWN1cnNpb25cblxuICAgIC8vIHN0b3JlIG5vZGUgdG8gcmVjb2duaXNlIHJlY3Vyc2lvblxuICAgIG9ialRyYXZlcnNlZC5wdXNoKG9iak5vZGUpO1xuXG4gICAgdmFyIGxvb3AgPSBBcnJheS5pc0FycmF5KG9iak5vZGUpID8gQXJyYXkucHJvdG90eXBlLmZvckVhY2ggOiBlYWNoS2V5O1xuXG4gICAgbG9vcC5jYWxsKG9iak5vZGUsIGZ1bmN0aW9uKHZhbHVlLCBwcm9wKSB7XG4gICAgICAgIHZhciBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmpOb2RlLCBwcm9wKTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgJiYgISAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApICYmICEgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgIGlmICghIChzZWxmTm9kZS5oYXNPd25Qcm9wZXJ0eShwcm9wKVxuICAgICAgICAgICAgICAgICAgICAmJiB0eXBlb2Ygc2VsZk5vZGVbcHJvcF0gPT0gJ29iamVjdCcgJiYgc2VsZk5vZGVbcHJvcF0gIT0gbnVsbCkpXG4gICAgICAgICAgICAgICAgc2VsZk5vZGVbcHJvcF0gPSAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpID8gW10gOiB7fTtcbiAgICAgICAgICAgIF9leHRlbmRUcmVlKHNlbGZOb2RlW3Byb3BdLCB2YWx1ZSwgb25seUVudW1lcmFibGUsIG9ialRyYXZlcnNlZCk7XG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNlbGZOb2RlLCBwcm9wLCBkZXNjcmlwdG9yKTtcbiAgICB9LCB0aGlzLCBvbmx5RW51bWVyYWJsZSk7XG5cbiAgICByZXR1cm4gc2VsZk5vZGU7XG59XG5cblxuLyoqXG4gKiBDbG9uZXMgYWxsIG9iamVjdCB0cmVlLiBDbGFzcyBvZiBvcmlnaW5hbCBvYmplY3QgaXMgbm90IHByZXNlcnZlZC4gUmV0dXJucyBgc2VsZmBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3QgdG8gYmUgZXh0ZW5kZWRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgT3B0aW9uYWwgYHRydWVgIHRvIHVzZSBvbmx5IGVudW1lcmFibGUgcHJvcGVydGllc1xuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBkZWVwQ2xvbmUob25seUVudW1lcmFibGUpIHtcbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIERhdGUpIHJldHVybiBuZXcgRGF0ZSh0aGlzKTtcbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFJlZ0V4cCkgcmV0dXJuIG5ldyBSZWdFeHAodGhpcyk7XG4gICAgdmFyIGNsb25lZE9iamVjdCA9IEFycmF5LmlzQXJyYXkodGhpcykgPyBbXSA6IHt9O1xuICAgIGRlZXBFeHRlbmQuY2FsbChjbG9uZWRPYmplY3QsIHRoaXMsIG9ubHlFbnVtZXJhYmxlKTtcbiAgICByZXR1cm4gY2xvbmVkT2JqZWN0O1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBhcnJheSBvZiBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgdGhlIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIG9iamVjdCB0byByZXR1cm4ga2V5cyBvZlxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIGtleXMoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBhcnJheSBvZiB2YWx1ZXMgb2YgdGhlIG9iamVjdCdzIGtleXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBvYmplY3QgdG8gcmV0dXJuIHZhbHVlcyBmcm9tXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdmFsdWVzKG9ubHlFbnVtZXJhYmxlKSB7XG4gICAgdmFyIHByb3BlcnRpZXMgPSBvbmx5RW51bWVyYWJsZVxuICAgICAgICAgICAgICAgID8gT2JqZWN0LmtleXModGhpcylcbiAgICAgICAgICAgICAgICA6IGFsbEtleXMuY2FsbCh0aGlzKTtcblxuICAgIHJldHVybiBwcm9wZXJ0aWVzLm1hcChmdW5jdGlvbihwcm9wKSB7XG4gICAgICAgIHJldHVybiB0aGlzW3Byb3BdO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBhcnJheSBvZiBhbGwgcHJvcGVydHkgbmFtZXMgb2YgYW4gb2JqZWN0IGBzZWxmYCAoaW5jbHVkaW5nIG5vbi1lbnVtZXJiYWxlKS5cbiAqIFRvIGdldCBvbmx5IGVudW1lcmFibGUgcHJvcGVydGllcywgdXNlIGBPYmplY3Qua2V5cygpYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3QgdG8gZ2V0IGFsbCBwcm9wZXJ0aWVzIG9mLlxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbiBmdW5jdGlvbiBhbGxLZXlzKCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKTtcbiB9XG5cblxuLyoqXG4gKiBBbiBhbmFsb2d1ZSBvZiBgaW5kZXhPZmAgbWV0aG9kIG9mIEFycmF5IHByb3RvdHlwZS5cbiAqIFJldHVybnMgdGhlIGBrZXlgIG9mIGBzZWFyY2hFbGVtZW50YCBpbiB0aGUgb2JqZWN0IGBzZWxmYC5cbiAqIEFzIG9iamVjdCBrZXlzIGFyZSB1bnNvcnRlZCwgaWYgdGhlcmUgYXJlIHNldmVyYWwga2V5cyB0aGF0IGhvbGQgYHNlYXJjaEVsZW1lbnRgIGFueSBvZiB0aGVtIGNhbiBiZSByZXR1cm5lZC4gVXNlIGBhbGxLZXlzT2ZgIHRvIHJldHVybiBhbGwga2V5cy5cbiAqIEFsbCBvd24gcHJvcGVydGllcyBhcmUgc2VhcmNoZWQgKG5vdCB0aG9zZSBpbmhlcml0ZWQgdmlhIHByb3RvdHlwZSBjaGFpbiksIGluY2x1ZGluZyBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzICh1bmxlc3MgYG9ubHlFbnVtZXJhYmxlYCBpcyB0cnV0aHkpLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBzZWFyY2ggYSB2YWx1ZSBpblxuICogQHBhcmFtIHtBbnl9IHNlYXJjaEVsZW1lbnQgQW4gZWxlbWVudCB0aGF0IHdpbGwgYmUgc2VhcmNoZWQuIEFuIGV4YWN0IGVxdWFsaXR5IGlzIHRlc3RlZCwgc28gYDBgIGlzIG5vdCB0aGUgc2FtZSBhcyBgJzAnYC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgdHJ1ZSB0byBzZWFyY2ggYW1vbmcgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGtleU9mKHNlYXJjaEVsZW1lbnQsIG9ubHlFbnVtZXJhYmxlKSB7XG4gICAgdmFyIHByb3BlcnRpZXMgPSBvbmx5RW51bWVyYWJsZVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBPYmplY3Qua2V5cyh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBhbGxLZXlzLmNhbGwodGhpcyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BlcnRpZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIGlmIChzZWFyY2hFbGVtZW50ID09PSB0aGlzW3Byb3BlcnRpZXNbaV1dKVxuICAgICAgICAgICAgcmV0dXJuIHByb3BlcnRpZXNbaV07XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5cbi8qKlxuICogV29ya3Mgc2ltaWxhcmx5IHRvIHRoZSBwcmV2aW91cyBmdW5jdGlvbiwgYnV0IHJldHVybnMgdGhlIGFycmF5IG9mIGtleXMgaG9sZGluZyBgc2VhcmNoRWxlbWVudGAgYXMgdGhlaXIgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHRvIHNlYXJjaCBhIHZhbHVlIGluXG4gKiBAcGFyYW0ge0FueX0gc2VhcmNoRWxlbWVudCBBbiBlbGVtZW50IHRoYXQgd2lsbCBiZSBzZWFyY2hlZC4gQW4gZXhhY3QgZXF1YWxpdHkgaXMgdGVzdGVkLCBzbyBgMGAgaXMgbm90IHRoZSBzYW1lIGFzIGAnMCdgLlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBBbiBvcHRpb25hbCB0cnVlIHRvIHNlYXJjaCBhbW9uZyBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seS5cbiAqIEByZXR1cm4ge0FycmF5W1N0cmluZ119XG4gKi9cbmZ1bmN0aW9uIGFsbEtleXNPZihzZWFyY2hFbGVtZW50LCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gb25seUVudW1lcmFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gT2JqZWN0LmtleXModGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYWxsS2V5cy5jYWxsKHRoaXMpO1xuXG4gICAgdmFyIGtleXMgPSBwcm9wZXJ0aWVzLmZpbHRlcihmdW5jdGlvbihwcm9wKSB7XG4gICAgICAgIHJldHVybiBzZWFyY2hFbGVtZW50ID09PSB0aGlzW3Byb3BdO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIGtleXM7XG59XG5cblxuLyoqXG4gKiBBbiBhbmFsb2d1ZSBvZiBbZm9yRWFjaF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZm9yRWFjaCkgbWV0aG9kIG9mIEFycmF5IHByb3RvdHlwZS5cbiAqIEl0ZXJhdGVzIGFsbCBvd24gcHJvcGVydGllcyBvZiBgc2VsZmAgKG9yIG9ubHkgZW51bWVyYWJsZSBvd24gcHJvcGVydGllcyBpZiBgb25seUVudW1lcmFibGVgIGlzIHRydXRoeSkgY2FsbGluZyBjYWxsYmFjayBmb3IgZWFjaCBrZXkuXG4gKiBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQgd2l0aCBhcnJheXMsIGl0IHdpbGwgaW5jbHVkZSBgbGVuZ3RoYCBwcm9wZXJ0eSBpbiBpdGVyYXRpb24uXG4gKiBUbyBpdGVyYXRlIGFycmF5LWxpa2Ugb2JqZWN0cyAoZS5nLiwgYGFyZ3VtZW50c2AgcHNldWRvLWFycmF5KSB1c2U6XG4gKiBgYGBcbiAqIF8uZm9yRWFjaChhcmd1bWVudHMsIGNhbGxiYWNrLCB0aGlzQXJnKTtcbiAqIGBgYFxuICogRnVuY3Rpb24gcmV0dXJucyBgc2VsZmAgdG8gYWxsb3cgW2NoYWluaW5nXShwcm90by5qcy5odG1sKVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB3aGljaCBwcm9wZXJ0aWVzIHdpbGwgYmUgaXRlcmF0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIGlzIHBhc3NlZCBgdmFsdWVgLCBga2V5YCBhbmQgYHNlbGZgLCBpdHMgcmV0dXJuIHZhbHVlIGlzIG5vdCB1c2VkLlxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgQW4gb3B0aW9uYWwgY29udGV4dCBvZiBpdGVyYXRpb24gKHRoZSB2YWx1ZW9mIGB0aGlzYCksIHdpbGwgYmUgdW5kZWZpbmVkIGlmIHRoaXMgcGFyYW1ldGVyIGlzIG5vdCBwYXNzZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIGB0cnVlYCB0byBpdGVyYXRlIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICovXG5mdW5jdGlvbiBlYWNoS2V5KGNhbGxiYWNrLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gb25seUVudW1lcmFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gT2JqZWN0LmtleXModGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYWxsS2V5cy5jYWxsKHRoaXMpO1xuXG4gICAgcHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzW3Byb3BdLCBwcm9wLCB0aGlzKTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogQW4gYW5hbG9ndWUgb2YgW21hcF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvbWFwKSBtZXRob2Qgb2YgQXJyYXkgcHJvdG90eXBlLlxuICogUmV0dXJucyB0aGUgb2JqZWN0IHRoYXQgaXMgdGhlIHJlc3VsdCBvZiB0aGUgYXBwbGljYXRpb24gb2YgY2FsbGJhY2sgdG8gdmFsdWVzIGluIGFsbCBvd24gcHJvcGVydGllcyBvZiBgc2VsZmAgKG9yIG9ubHkgZW51bWVyYWJsZSBvd24gcHJvcGVydGllcyBpZiBgb25seUVudW1lcmFibGVgIGlzIHRydXRoeSkuXG4gKiBUaGUgcmV0dXJuZWQgb2JqZWN0IHdpbGwgYmUgdGhlIGluc3RhbmNlIG9mIHRoZSBzYW1lIGNsYXNzIGFzIGBzZWxmYC5cbiAqIFByb3BlcnR5IGRlc2NyaXB0b3JzIG9mIHRoZSByZXR1cm5lZCBvYmplY3Qgd2lsbCBoYXZlIHRoZSBzYW1lIGBlbnVtZXJhYmxlYCwgYGNvbmZpZ3VyYWJsZWAgYW5kIGB3cml0YWJsZWAgc2V0dGluZ3MgYXMgdGhlIHByb3BlcnRpZXMgb2YgYHNlbGZgLlxuICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkIHdpdGggYXJyYXlzLCBpdCB3aWxsIGluY2x1ZGUgYGxlbmd0aGAgcHJvcGVydHkgaW4gaXRlcmF0aW9uLlxuICogVG8gbWFwIGFycmF5LWxpa2Ugb2JqZWN0cyB1c2U6XG4gKiBgYGBcbiAqIHZhciByZXN1bHQgPSBfLm1hcChhcmd1bWVudHMsIGNhbGxiYWNrLCB0aGlzQXJnKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB3aGljaCBwcm9wZXJ0aWVzIHdpbGwgYmUgaXRlcmF0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIGlzIHBhc3NlZCBgdmFsdWVgLCBga2V5YCBhbmQgYHNlbGZgIGFuZCBzaG91bGQgcmV0dXJuIHZhbHVlIHRoYXQgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgbWFwLlxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgQW4gb3B0aW9uYWwgY29udGV4dCBvZiBpdGVyYXRpb24gKHRoZSB2YWx1ZW9mIGB0aGlzYCksIHdpbGwgYmUgdW5kZWZpbmVkIGlmIHRoaXMgcGFyYW1ldGVyIGlzIG5vdCBwYXNzZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIGB0cnVlYCB0byBpdGVyYXRlIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBtYXBLZXlzKGNhbGxiYWNrLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBkZXNjcmlwdG9ycyA9IHt9O1xuICAgIGVhY2hLZXkuY2FsbCh0aGlzLCBtYXBQcm9wZXJ0eSwgdGhpc0FyZywgb25seUVudW1lcmFibGUpO1xuICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlLCBkZXNjcmlwdG9ycyk7XG5cbiAgICBmdW5jdGlvbiBtYXBQcm9wZXJ0eSh2YWx1ZSwga2V5LCBzZWxmKSB7XG4gICAgICAgIGRlc2NyaXB0b3JzW2tleV0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNlbGYsIGtleSk7XG4gICAgICAgIGRlc2NyaXB0b3JzW2tleV0udmFsdWUgPSBjYWxsYmFjay5jYWxsKHRoaXMsIHZhbHVlLCBrZXksIHNlbGYpO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIEFuIGFuYWxvZ3VlIG9mIFtyZWR1Y2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L1JlZHVjZSkgbWV0aG9kIG9mIEFycmF5IHByb3RvdHlwZS5cbiAqIFRoaXMgbWV0aG9kIHJlZHVjZXMgdGhlIG9iamVjdCB0byBhIHNpbmdsZSB2YWx1ZS4gSXRlcmF0aW9uIG9yZGVyIGlzIGltcG9zc2libGUgdG8gY29udHJvbCB3aXRoIG9iamVjdC5cbiAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZCB3aXRoIGFycmF5cywgaXQgd2lsbCBpbmNsdWRlIGBsZW5ndGhgIHByb3BlcnR5IGluIGl0ZXJhdGlvbi5cbiAqIFRvIHJlZHVjZSBhcnJheS1saWtlIG9iamVjdHMgdXNlOlxuICogYGBgXG4gKiB2YXIgcmVzdWx0ID0gXy5yZWR1Y2UoYXJndW1lbnRzLCBjYWxsYmFjaywgaW5pdGlhbFZhbHVlLCB0aGlzQXJnKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB3aGljaCBwcm9wZXJ0aWVzIHdpbGwgYmUgaXRlcmF0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIGlzIHBhc3NlZCBgcHJldmlvdXNWYWx1ZWAsIGB2YWx1ZWAsIGBrZXlgIGFuZCBgc2VsZmAgYW5kIHNob3VsZCByZXR1cm4gdmFsdWUgdGhhdCB3aWxsIGJlIHVzZWQgYXMgdGhlIGBwcmV2aW91c1ZhbHVlYCBmb3IgdGhlIG5leHQgYGNhbGxiYWNrYCBjYWxsLlxuICogQHBhcmFtIHtBbnl9IGluaXRpYWxWYWx1ZSBUaGUgaW5pdGlhbCB2YWx1ZSBwYXNzZWQgdG8gY2FsbGJhY2sgYXMgdGhlIGZpcnN0IHBhcmFtZXRlciBvbiB0aGUgZmlyc3QgY2FsbC5cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIEFuIG9wdGlvbmFsIGNvbnRleHQgb2YgaXRlcmF0aW9uICh0aGUgdmFsdWVvZiBgdGhpc2ApLCB3aWxsIGJlIHVuZGVmaW5lZCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgcGFzc2VkLlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBBbiBvcHRpb25hbCBgdHJ1ZWAgdG8gaXRlcmF0ZSBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seS5cbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gcmVkdWNlS2V5cyhjYWxsYmFjaywgaW5pdGlhbFZhbHVlLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gb25seUVudW1lcmFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gT2JqZWN0LmtleXModGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYWxsS2V5cy5jYWxsKHRoaXMpO1xuXG4gICAgdmFyIG1lbW8gPSBpbml0aWFsVmFsdWU7XG5cbiAgICBwcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICBtZW1vID0gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCBtZW1vLCB0aGlzW3Byb3BdLCBwcm9wLCB0aGlzKTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiBtZW1vO1xufVxuXG5cbi8qKlxuICogQW4gYW5hbG9ndWUgb2YgW2ZpbHRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZmlsdGVyKSBtZXRob2Qgb2YgQXJyYXkgcHJvdG90eXBlLlxuICogUmV0dXJucyB0aGUgbmV3IG9iamVjdCB3aXRoIGtleXMgZm9yIHdoaWNoIGNhbGxiYWNrIHJldHVybnMgdHJ1ZS5cbiAqIFByb3BlcnR5IGRlc2NyaXB0b3JzIG9mIHRoZSByZXR1cm5lZCBvYmplY3Qgd2lsbCBoYXZlIHRoZSBzYW1lIGBlbnVtZXJhYmxlYCwgYGNvbmZpZ3VyYWJsZWAgYW5kIGB3cml0YWJsZWAgc2V0dGluZ3MgYXMgdGhlIHByb3BlcnRpZXMgb2YgYHNlbGZgLlxuICogVG8gZmlsdGVyIGFycmF5LWxpa2Ugb2JqZWN0cyB1c2U6XG4gKiBgYGBcbiAqIHZhciByZXN1bHQgPSBfLmZpbHRlcihhcmd1bWVudHMsIGNhbGxiYWNrLCB0aGlzQXJnKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB3aGljaCBwcm9wZXJ0aWVzIHdpbGwgYmUgaXRlcmF0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIGlzIHBhc3NlZCBgdmFsdWVgLCBga2V5YCBhbmQgYHNlbGZgLiBJZiBpdCByZXR1cm5zIHRydXRoeSB2YWx1ZSwgdGhlIGtleS92YWx1ZSB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSByZXN1bHRpbmcgb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgQW4gb3B0aW9uYWwgY29udGV4dCBvZiBpdGVyYXRpb24gKHRoZSB2YWx1ZW9mIGB0aGlzYCksIHdpbGwgYmUgdW5kZWZpbmVkIGlmIHRoaXMgcGFyYW1ldGVyIGlzIG5vdCBwYXNzZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIGB0cnVlYCB0byBpdGVyYXRlIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBmaWx0ZXJLZXlzKGNhbGxiYWNrLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBkZXNjcmlwdG9ycyA9IHt9O1xuICAgIGVhY2hLZXkuY2FsbCh0aGlzLCBmaWx0ZXJQcm9wZXJ0eSwgdGhpc0FyZywgb25seUVudW1lcmFibGUpO1xuICAgIHJldHVybiBPYmplY3QuY3JlYXRlKHRoaXMuY29uc3RydWN0b3IucHJvdG90eXBlLCBkZXNjcmlwdG9ycyk7O1xuXG4gICAgZnVuY3Rpb24gZmlsdGVyUHJvcGVydHkodmFsdWUsIGtleSwgc2VsZikge1xuICAgICAgICBpZiAoY2FsbGJhY2suY2FsbCh0aGlzLCB2YWx1ZSwga2V5LCBzZWxmKSlcbiAgICAgICAgICAgIGRlc2NyaXB0b3JzW2tleV0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHNlbGYsIGtleSk7XG4gICAgfVxufVxuXG5cbnZhciBfcGFzc2VkID0ge31cbiAgICAsIF9kaWROb3RQYXNzID0ge307XG5cbi8qKlxuICogQW4gYW5hbG9ndWUgb2YgW3NvbWVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L3NvbWUpIG1ldGhvZCBvZiBBcnJheSBwcm90b3R5cGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHdoaWNoIHByb3BlcnRpZXMgd2lsbCBiZSBpdGVyYXRlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2sgaXMgcGFzc2VkIGB2YWx1ZWAsIGBrZXlgIGFuZCBgc2VsZmAuIElmIGl0IHJldHVybnMgdHJ1dGh5IHZhbHVlLCB0aGUgZnVuY3Rpb24gaW1tZWFkaXRlbHkgcmV0dXJucyBgdHJ1ZWAuXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBBbiBvcHRpb25hbCBjb250ZXh0IG9mIGl0ZXJhdGlvbiAodGhlIHZhbHVlb2YgYHRoaXNgKSwgd2lsbCBiZSB1bmRlZmluZWQgaWYgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHBhc3NlZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgYHRydWVgIHRvIGl0ZXJhdGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBzb21lS2V5KGNhbGxiYWNrLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHRyeSB7XG4gICAgICAgIGVhY2hLZXkuY2FsbCh0aGlzLCB0ZXN0UHJvcGVydHksIHRoaXNBcmcsIG9ubHlFbnVtZXJhYmxlKTtcbiAgICB9IGNhdGNoICh0ZXN0KSB7XG4gICAgICAgIGlmICh0ZXN0ID09PSBfcGFzc2VkKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgZWxzZSB0aHJvdyB0ZXN0O1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBmdW5jdGlvbiB0ZXN0UHJvcGVydHkodmFsdWUsIGtleSwgc2VsZikge1xuICAgICAgICBpZiAoY2FsbGJhY2suY2FsbCh0aGlzLCB2YWx1ZSwga2V5LCBzZWxmKSlcbiAgICAgICAgICAgIHRocm93IF9wYXNzZWQ7XG4gICAgfVxufVxuXG5cbi8qKlxuICogQW4gYW5hbG9ndWUgb2YgW2V2ZXJ5XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9ldmVyeSkgbWV0aG9kIG9mIEFycmF5IHByb3RvdHlwZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3Qgd2hpY2ggcHJvcGVydGllcyB3aWxsIGJlIGl0ZXJhdGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsYmFjayBpcyBwYXNzZWQgYHZhbHVlYCwgYGtleWAgYW5kIGBzZWxmYC4gSWYgaXQgcmV0dXJucyBmYWxzeSB2YWx1ZSwgdGhlIGZ1bmN0aW9uIGltbWVhZGl0ZWx5IHJldHVybnMgYGZhbHNlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIEFuIG9wdGlvbmFsIGNvbnRleHQgb2YgaXRlcmF0aW9uICh0aGUgdmFsdWVvZiBgdGhpc2ApLCB3aWxsIGJlIHVuZGVmaW5lZCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgcGFzc2VkLlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBBbiBvcHRpb25hbCBgdHJ1ZWAgdG8gaXRlcmF0ZSBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seS5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGV2ZXJ5S2V5KGNhbGxiYWNrLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHRyeSB7XG4gICAgICAgIGVhY2hLZXkuY2FsbCh0aGlzLCB0ZXN0UHJvcGVydHksIHRoaXNBcmcsIG9ubHlFbnVtZXJhYmxlKTtcbiAgICB9IGNhdGNoICh0ZXN0KSB7XG4gICAgICAgIGlmICh0ZXN0ID09PSBfZGlkTm90UGFzcykgcmV0dXJuIGZhbHNlO1xuICAgICAgICBlbHNlIHRocm93IHRlc3Q7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuXG4gICAgZnVuY3Rpb24gdGVzdFByb3BlcnR5KHZhbHVlLCBrZXksIHNlbGYpIHtcbiAgICAgICAgaWYgKCEgY2FsbGJhY2suY2FsbCh0aGlzLCB2YWx1ZSwga2V5LCBzZWxmKSlcbiAgICAgICAgICAgIHRocm93IF9kaWROb3RQYXNzO1xuICAgIH1cbn1cblxuXG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZVxuICAgICwgY29uY2F0ID0gQXJyYXlQcm90by5jb25jYXQ7XG4vKipcbiAqIFJldHVybnMgb2JqZWN0IG9mIHRoZSBzYW1lIGNsYXNzIHdpdGggb25seSBzcGVjaWZpZWQga2V5cywgdGhhdCBhcmUgcGFzc2VkIGFzIHN0cmluZyBwYXJhbWV0ZXJzIG9yIGFycmF5KHMpIG9mIGtleXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgYW4gb2JqZWN0IHRvIHBpY2sga2V5cyBmcm9tXG4gKiBAcGFyYW0ge0xpc3RbU3RyaW5nfEFycmF5XX0gYXJndW1lbnRzIGxpc3Qgb2Yga2V5cyAob3IgYXJyYXkocykgb2Yga2V5cylcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gcGlja0tleXMoKSB7IC8vICwgLi4uIGtleXNcbiAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBhcmd1bWVudHMpXG4gICAgICAgICwgb2JqID0gT2JqZWN0LmNyZWF0ZSh0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gICAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShrZXkpKVxuICAgICAgICAgICAgb2JqW2tleV0gPSB0aGlzW2tleV07XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIG9iajtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgb2JqZWN0IG9mIHRoZSBzYW1lIGNsYXNzIHdpdGhvdXQgc3BlY2lmaWVkIGtleXMsIHRoYXQgYXJlIHBhc3NlZCBhcyBzdHJpbmcgcGFyYW1ldGVycyBvciBhcnJheShzKSBvZiBrZXlzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIGFuIG9iamVjdCB0byBvbWl0IGtleXMgaW5cbiAqIEBwYXJhbSB7TGlzdFtTdHJpbmd8QXJyYXldfSBhcmd1bWVudHMgbGlzdCBvZiBrZXlzIChvciBhcnJheShzKSBvZiBrZXlzKVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBvbWl0S2V5cygpIHsgLy8gLCAuLi4ga2V5c1xuICAgIHZhciBrZXlzID0gY29uY2F0LmFwcGx5KEFycmF5UHJvdG8sIGFyZ3VtZW50cylcbiAgICAgICAgLCBvYmogPSBjbG9uZS5jYWxsKHRoaXMpO1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpe1xuICAgICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIG9iajtcbn1cblxuXG4vKipcbiAqIFBlcmZvcm1zIGRlZXAgZXF1YWxpdHkgdGVzdCBvZiB0aGUgb2JqZWN0LiBEb2VzIG5vdCB3b3JrIHdpdGggcmVjdXJzaXZlIG9iamVjdHNcbiAqIEBwYXJhbSAge0FueX0gc2VsZiBvYmplY3QgdG8gY29tcGFyZVxuICogQHBhcmFtICB7QW55fSBvYmogb2JqZWN0IHRvIGNvbXBhcmVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzRXF1YWwob2JqKSB7XG4gICAgaWYgKHRoaXMgPT09IG9iaikgcmV0dXJuIHRoaXMgIT09IDAgfHwgMS90aGlzID09IDEvb2JqOyAvLyAwIGFuZCAtMCBhcmUgY29uc2lkZXJlZCBub3QgZXF1YWwsIGFsdGhvdWdoIDAgPT09IC0wIGlzIHRydWVcbiAgICBpZiAodGhpcyA9PSBudWxsIHx8IG9iaiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgdmFyIGNsYXNzTmFtZSA9IHRoaXMuY29uc3RydWN0b3IubmFtZTtcbiAgICBpZiAoY2xhc3NOYW1lICE9IG9iai5jb25zdHJ1Y3Rvci5uYW1lKSByZXR1cm4gZmFsc2U7XG4gICAgc3dpdGNoIChjbGFzc05hbWUpIHtcbiAgICAgICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgICAgICAgIHJldHVybiB0aGlzID09IFN0cmluZyhvYmopO1xuICAgICAgICBjYXNlICdOdW1iZXInOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMgIT0gK3RoaXMgPyBvYmogIT0gK29iaiA6ICh0aGlzID09IDAgPyAxL3RoaXMgPT0gMS9vYmogOiB0aGlzID09ICtvYmopO1xuICAgICAgICBjYXNlICdEYXRlJzpcbiAgICAgICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICAgICAgICByZXR1cm4gK3RoaXMgPT0gK29iajtcbiAgICAgICAgY2FzZSAnUmVnRXhwJzpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNvdXJjZSA9PSBvYmouc291cmNlXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMuZ2xvYmFsID09IG9iai5nbG9iYWxcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5tdWx0aWxpbmUgPT0gb2JqLm11bHRpbGluZVxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLmlnbm9yZUNhc2UgPT0gb2JqLmlnbm9yZUNhc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcyAhPSAnb2JqZWN0JyB8fCB0eXBlb2Ygb2JqICE9ICdvYmplY3QnKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzKSlcbiAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoID09IG9iai5sZW5ndGhcbiAgICAgICAgICAgICAgICAmJiB0aGlzLmV2ZXJ5KGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0VxdWFsLmNhbGwoaXRlbSwgb2JqW2luZGV4XSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBhbGxLZXlzLmNhbGwodGhpcykubGVuZ3RoID09IGFsbEtleXMuY2FsbChvYmopLmxlbmd0aFxuICAgICAgICAgICAgICAgICYmIGV2ZXJ5S2V5LmNhbGwodGhpcywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNFcXVhbC5jYWxsKHZhbHVlLCBvYmpba2V5XSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogVGhlIG9wcG9zaXRlIG9mIGlzRXF1YWxcbiAqIEBwYXJhbSAge0FueX0gc2VsZiBvYmplY3QgdG8gY29tcGFyZVxuICogQHBhcmFtICB7QW55fSBvYmogb2JqZWN0IHRvIGNvbXBhcmVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzTm90KG9iaikge1xuICAgIHJldHVybiAhaXNFcXVhbC5jYWxsKHRoaXMsIG9iaik7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogLSBbZXh0ZW5kUHJvdG9dKCNleHRlbmRQcm90bylcbiAqIC0gW2NyZWF0ZVN1YmNsYXNzXSgjY3JlYXRlU3ViY2xhc3MpXG4gKiAtIFttYWtlU3ViY2xhc3NdKCNtYWtlU3ViY2xhc3MpXG4gKiAtIFtuZXdBcHBseV0oI25ld0FwcGx5KVxuICpcbiAqIFRoZXNlIG1ldGhvZHMgY2FuIGJlIFtjaGFpbmVkXShwcm90by5qcy5odG1sI1Byb3RvKVxuICovXG52YXIgcHJvdG90eXBlTWV0aG9kcyA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGV4dGVuZFByb3RvOiBleHRlbmRQcm90byxcbiAgICBjcmVhdGVTdWJjbGFzczogY3JlYXRlU3ViY2xhc3MsXG4gICAgbWFrZVN1YmNsYXNzOiBtYWtlU3ViY2xhc3MsXG4gICAgbmV3QXBwbHk6IG5ld0FwcGx5XG59O1xuXG5cbnZhciBfXyA9IHJlcXVpcmUoJy4vcHJvdG9fb2JqZWN0Jyk7XG5cbl9fLmV4dGVuZC5jYWxsKF9fLCByZXF1aXJlKCcuL3Byb3RvX2Z1bmN0aW9uJykpO1xuXG5cbi8qKlxuICogQWRkcyBub24tZW51bWVyYWJsZSwgbm9uLWNvbmZpZ3VyYWJsZSBhbmQgbm9uLXdyaXRhYmxlIHByb3BlcnRpZXMgdG8gdGhlIHByb3RvdHlwZSBvZiBjb25zdHJ1Y3RvciBmdW5jdGlvbi5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiBmdW5jdGlvbiBNeUNsYXNzKCkge31cbiAqIF8uZXh0ZW5kUHJvdG8oTXlDbGFzcywge1xuICogICAgIG1ldGhvZDE6IGZ1bmN0aW9uKCkge30sXG4gKiAgICAgbWV0aG9kMjogZnVuY3Rpb24oKSB7fVxuICogfSk7XG4gKiBgYGBcbiAqIFRvIGV4dGVuZCBjbGFzcyB2aWEgb2JqZWN0OlxuICogYGBgXG4gKiBfLmV4dGVuZFByb3RvKG9iai5jb25zdHJ1Y3RvciwgbWV0aG9kcyk7XG4gKiBgYGBcbiAqIFJldHVybnMgcGFzc2VkIGNvbnN0cnVjdG9yLCBzbyBmdW5jdGlvbnMgXy5leHRlbmRQcm90bywgW18uZXh0ZW5kXShvYmplY3QuanMuaHRtbCNleHRlbmQpIGFuZCBfLm1ha2VTdWJjbGFzcyBjYW4gYmUgW2NoYWluZWRdKHByb3RvLmpzLmh0bWwpLiBcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGNvbnN0cnVjdG9yIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gbWV0aG9kcyBhIG1hcCBvZiBmdW5jdGlvbnMsIGtleXMgd2lsbCBiZSBpbnN0YW5jZSBtZXRob2RzIChwcm9wZXJ0aWVzIG9mIHRoZSBjb25zdHJ1Y3RvciBwcm90b3R5cGUpXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gZXh0ZW5kUHJvdG8obWV0aG9kcykge1xuICAgIHZhciBwcm9wRGVzY3JpcHRvcnMgPSB7fTtcblxuICAgIF9fLmVhY2hLZXkuY2FsbChtZXRob2RzLCBmdW5jdGlvbihtZXRob2QsIG5hbWUpIHtcbiAgICAgICAgcHJvcERlc2NyaXB0b3JzW25hbWVdID0ge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IG1ldGhvZFxuICAgICAgICB9O1xuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcy5wcm90b3R5cGUsIHByb3BEZXNjcmlwdG9ycyk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBNYWtlcyBhIHN1YmNsYXNzIG9mIGNsYXNzIGB0aGlzQ2xhc3NgLlxuICogVGhlIHJldHVybmVkIGZ1bmN0aW9uIHdpbGwgaGF2ZSBzcGVjaWZpZWQgYG5hbWVgIGlmIHN1cHBsaWVkLlxuICogVGhlIGNvbnN0cnVjdG9yIG9mIHN1cGVyY2xhc3Mgd2lsbCBiZSBjYWxsZWQgaW4gc3ViY2xhc3MgY29uc3RydWN0b3IgYnkgZGVmYXVsdCB1bmxlc3MgYGFwcGx5Q29uc3RydWN0b3IgPT09IGZhbHNlYCAobm90IGp1c3QgZmFsc3kpLlxuICogQ29waWVzIGB0aGlzQ2xhc3NgIGNsYXNzIG1ldGhvZHMgdG8gY3JlYXRlZCBzdWJjbGFzcy4gRm9yIHRoZW0gdG8gd29yayBjb3JyZWN0bHkgdGhleSBzaG91bGQgdXNlIGB0aGlzYCB0byByZWZlciB0byB0aGUgY2xhc3MgcmF0aGVyIHRoYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBuYW1lLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXNDbGFzcyBBIGNsYXNzIHRvIG1ha2Ugc3ViY2xhc3Mgb2ZcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIE9wdGlvbmFsIG5hbWUgb2Ygc3ViY2xhc3MgY29uc3RydWN0b3IgZnVuY3Rpb25cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gYXBwbHlDb25zdHJ1Y3RvciBPcHRpb25hbCBmYWxzZSB2YWx1ZSAobm90IGZhbHN5KSB0byBwcmV2ZW50IGNhbGwgb2YgaW5oZXJpdGVkIGNvbnN0cnVjdG9yIGluIHRoZSBjb25zdHJ1Y3RvciBvZiBzdWJjbGFzc1xuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVN1YmNsYXNzKG5hbWUsIGFwcGx5Q29uc3RydWN0b3IpIHtcbiAgICB2YXIgdGhpc0NsYXNzID0gdGhpcztcbiAgICB2YXIgc3ViY2xhc3M7XG5cbiAgICAvLyBuYW1lIGlzIG9wdGlvbmFsXG4gICAgbmFtZSA9IG5hbWUgfHwgJyc7XG5cbiAgICAvLyBhcHBseSBzdXBlcmNsYXNzIGNvbnN0cnVjdG9yXG4gICAgdmFyIGNvbnN0cnVjdG9yQ29kZSA9IGFwcGx5Q29uc3RydWN0b3IgPT09IGZhbHNlXG4gICAgICAgICAgICA/ICcnXG4gICAgICAgICAgICA6ICd0aGlzQ2xhc3MuYXBwbHkodGhpcywgYXJndW1lbnRzKTsnO1xuXG4gICAgZXZhbCgnc3ViY2xhc3MgPSBmdW5jdGlvbiAnICsgbmFtZSArICcoKXsgJyArIGNvbnN0cnVjdG9yQ29kZSArICcgfScpO1xuXG4gICAgbWFrZVN1YmNsYXNzLmNhbGwoc3ViY2xhc3MsIHRoaXNDbGFzcyk7XG5cbiAgICAvLyBjb3B5IGNsYXNzIG1ldGhvZHNcbiAgICAvLyAtIGZvciB0aGVtIHRvIHdvcmsgY29ycmVjdGx5IHRoZXkgc2hvdWxkIG5vdCBleHBsaWN0bHkgdXNlIHN1cGVyY2xhc3MgbmFtZVxuICAgIC8vIGFuZCB1c2UgXCJ0aGlzXCIgaW5zdGVhZFxuICAgIF9fLmRlZXBFeHRlbmQuY2FsbChzdWJjbGFzcywgdGhpc0NsYXNzLCB0cnVlKTtcblxuICAgIHJldHVybiBzdWJjbGFzcztcbn1cblxuXG4vKipcbiAqIFNldHMgdXAgcHJvdG90eXBlIGNoYWluIHRvIGNoYW5nZSBgdGhpc0NsYXNzYCAoYSBjb25zdHJ1Y3RvciBmdW5jdGlvbikgc28gdGhhdCBpdCBiZWNvbWVzIGEgc3ViY2xhc3Mgb2YgYFN1cGVyY2xhc3NgLlxuICogUmV0dXJucyBgdGhpc0NsYXNzYCBzbyBpdCBjYW4gYmUgW2NoYWluZWRdKHByb3RvLmpzLmh0bWwpIHdpdGggXy5leHRlbmRQcm90byBhbmQgW18uZXh0ZW5kXShvYmplY3QuanMuaHRtbCNleHRlbmQpLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXNDbGFzcyBBIGNsYXNzIHRoYXQgd2lsbCBiZWNvbWUgYSBzdWJjbGFzcyBvZiBTdXBlcmNsYXNzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBTdXBlcmNsYXNzIEEgY2xhc3MgdGhhdCB3aWxsIGJlY29tZSBhIHN1cGVyY2xhc3Mgb2YgdGhpc0NsYXNzXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gbWFrZVN1YmNsYXNzKFN1cGVyY2xhc3MpIHtcbiAgICAvLyBwcm90b3R5cGUgY2hhaW5cbiAgICB0aGlzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU3VwZXJjbGFzcy5wcm90b3R5cGUpO1xuICAgIFxuICAgIC8vIHN1YmNsYXNzIGlkZW50aXR5XG4gICAgZXh0ZW5kUHJvdG8uY2FsbCh0aGlzLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB0aGlzXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBDYWxscyBjb25zdHJ1Y3RvciBgdGhpc2Agd2l0aCBhcmd1bWVudHMgcGFzc2VkIGFzIGFycmF5XG4gKiBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXNDbGFzcyBBIGNsYXNzIGNvbnN0cnVjdG9yIHRoYXQgd2lsbCBiZSBjYWxsZWRcbiAqIEByZXR1cm4ge0FycmF5fEFycmF5LWxpa2V9IGFyZ3MgQXJyYXkgb2YgYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gbmV3QXBwbHkoYXJncykge1xuICAgIGlmICghIEFycmF5LmlzQXJyYXkoYXJncykpXG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzKTtcbiAgICAvLyBcIm51bGxcIiBpcyBjb250ZXh0IHRvIHBhc3MgdG8gY2xhc3MgY29uc3RydWN0b3IsIGZpcnN0IHBhcmFtZXRlciBvZiBiaW5kXG4gICAgdmFyIGFyZ3MgPSBbbnVsbF0uY29uY2F0KGFyZ3MpO1xuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KHRoaXMsIGFyZ3MpKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgX18gPSByZXF1aXJlKCcuL3Byb3RvX29iamVjdCcpO1xuXG5cbi8qKlxuICogLSBbZmlyc3RVcHBlckNhc2VdKCNmaXJzdFVwcGVyQ2FzZSlcbiAqIC0gW2ZpcnN0TG93ZXJDYXNlXSgjZmlyc3RMb3dlckNhc2UpXG4gKiAtIFt0b1JlZ0V4cF0oI3RvUmVnRXhwKVxuICogLSBbdG9GdW5jdGlvbl0oI3RvRnVuY3Rpb24pXG4gKiAtIFt0b0RhdGVdKCN0b0RhdGUpXG4gKiAtIFt0b1F1ZXJ5U3RyaW5nXSgjdG9RdWVyeVN0cmluZylcbiAqIC0gW2Zyb21RdWVyeVN0cmluZ10oI2Zyb21RdWVyeVN0cmluZylcbiAqIC0gW2pzb25QYXJzZV0oI2pzb25QYXJzZSlcbiAqIC0gW2hhc2hDb2RlXSgjaGFzaENvZGUpXG4gKiAtIFt1blByZWZpeF0oI3VuUHJlZml4KVxuICovXG4gdmFyIHN0cmluZ01ldGhvZHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBmaXJzdFVwcGVyQ2FzZTogZmlyc3RVcHBlckNhc2UsXG4gICAgZmlyc3RMb3dlckNhc2U6IGZpcnN0TG93ZXJDYXNlLFxuICAgIHRvUmVnRXhwOiB0b1JlZ0V4cCxcbiAgICB0b0Z1bmN0aW9uOiB0b0Z1bmN0aW9uLFxuICAgIHRvRGF0ZTogdG9EYXRlLFxuICAgIHRvUXVlcnlTdHJpbmc6IHRvUXVlcnlTdHJpbmcsXG4gICAgZnJvbVF1ZXJ5U3RyaW5nOiBmcm9tUXVlcnlTdHJpbmcsXG4gICAganNvblBhcnNlOiBqc29uUGFyc2UsXG4gICAgaGFzaENvZGU6IGhhc2hDb2RlLFxuICAgIHVuUHJlZml4OiB1blByZWZpeFxufTtcblxuXG4vKipcbiAqIFJldHVybnMgc3RyaW5nIHdpdGggdGhlIGZpcnN0IGNoYXJhY3RlciBjaGFuZ2VkIHRvIHVwcGVyIGNhc2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGYgQSBzdHJpbmcgdGhhdCB3aWxsIGhhdmUgaXRzIGZpcnN0IGNoYXJhY3RlciByZXBsYWNlZFxuICovXG5mdW5jdGlvbiBmaXJzdFVwcGVyQ2FzZSgpIHtcbiAgICByZXR1cm4gdGhpcyA/IHRoaXNbMF0udG9VcHBlckNhc2UoKSArIHRoaXMuc2xpY2UoMSkgOiB0aGlzO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBzdHJpbmcgd2l0aCB0aGUgZmlyc3QgY2hhcmFjdGVyIGNoYW5nZWQgdG8gbG93ZXIgY2FzZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZiBBIHN0cmluZyB0aGF0IHdpbGwgaGF2ZSBpdHMgZmlyc3QgY2hhcmFjdGVyIHJlcGxhY2VkXG4gKi9cbmZ1bmN0aW9uIGZpcnN0TG93ZXJDYXNlKCkge1xuICAgIHJldHVybiB0aGlzID8gdGhpc1swXS50b0xvd2VyQ2FzZSgpICsgdGhpcy5zbGljZSgxKSA6IHRoaXM7XG59XG5cblxuLyoqXG4gKiBDb252ZXJ0cyBzdHJpbmcgY3JlYXRlZCBieSBgdG9TdHJpbmdgIG1ldGhvZCBvZiBSZWdFeHAgYmFjayB0byBSZWdFeHBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZiBzdHJpbmcgY29udGFpbmluZyByZWd1bGFyIGV4cHJlc3Npb24gaW5jbHVkaW5nIGVuY2xvc2luZyBcIi9cIiBzeW1ib2xzIGFuZCBmbGFnc1xuICogQHJldHVybiB7UmVnRXhwfVxuICovXG5mdW5jdGlvbiB0b1JlZ0V4cCgpIHtcbiAgICB2YXIgcnggPSB0aGlzLm1hdGNoKHJlZ2V4cFN0cmluZ1BhdHRlcm4pO1xuICAgIGlmIChyeCkgcmV0dXJuIG5ldyBSZWdFeHAocnhbMV0sIHJ4WzJdKTtcbn1cbnZhciByZWdleHBTdHJpbmdQYXR0ZXJuID0gL15cXC8oLiopXFwvKFtnaW15XSopJC87XG5cblxuLyoqXG4gKiBDb252ZXJ0cyBzdHJpbmcgY3JlYXRlZCBieSBgdG9TdHJpbmdgIG1ldGhvZCBvZiBmdW5jdGlvbiBiYWNrIHRvIGZ1bmN0aW9uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGYgc3RyaW5nIGNvbnRhaW5pbmcgZnVsbCBmdW5jdGlvbiBjb2RlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gdG9GdW5jdGlvbigpIHtcbiAgICB2YXIgZnVuYztcbiAgICB2YXIgY29kZSA9ICdmdW5jID0gJyArIHRoaXMgKyAnOyc7XG4gICAgdHJ5IHtcbiAgICAgICAgZXZhbChjb2RlKTtcbiAgICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBDb252ZXJ0cyBzdHJpbmcgdG8gZGF0ZSBpbiBhIHNhZmUgd2F5IHNvIHRoYXQgdGhlIHJlc2l1bHQgaXMgdW5kZWZpbmVkIGlmIGRhdGUgaXMgaW52YWxpZFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfERhdGV9IHNlbGYgc3RyaW5nIG9yIGRhdGUgb2JqZWN0IHRvIGNvbnZlcnQgdG8gVkFMSUQgZGF0ZVxuICogQHJldHVybiB7W3R5cGVdfSBbZGVzY3JpcHRpb25dXG4gKi9cbmZ1bmN0aW9uIHRvRGF0ZSgpIHtcbiAgICBpZiAoISB0aGlzKSByZXR1cm47XG4gICAgdHJ5IHtcbiAgICAgICAgdmFyIGRhdGUgPSBuZXcgRGF0ZSh0aGlzKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIGlmIChkYXRlICYmIGRhdGUuZ2V0VGltZSAmJiAhaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKVxuICAgICAgICByZXR1cm4gZGF0ZTtcbn1cblxuXG4vKipcbiAqIENvbnZlcnQgcGFyYW1zIG9iamVjdCB0byBhIHVybCBzdHlsZSBxdWVyeSBzdHJpbmcgKHdpdGhvdXQgXCI/XCIpXG4gKiBcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIFRoZSBvYmplY3QgaGFzaCB0byBiZSBjb252ZXJ0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVuY29kZSBvcHRpb25hbCBmdW5jdGlvbiB1c2VkIHRvIGVuY29kZSBkYXRhLCBlbmNvZGVVUklDb21wb25lbnQgaXMgdXNlZCBpZiBub3Qgc3BlY2lmaWVkXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSByZXN1bHRpbmcgcXVlcnkgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHRvUXVlcnlTdHJpbmcoZW5jb2RlKSB7XG4gICAgdmFyIHFzID0gJydcbiAgICAgICAgLCBwYXJhbXMgPSB0aGlzIHx8IHt9XG4gICAgICAgICwgZW5jb2RlID0gZW5jb2RlIHx8IGVuY29kZVVSSUNvbXBvbmVudDtcblxuICAgIF9fLmVhY2hLZXkuY2FsbChwYXJhbXMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgcXMgKz0ga2V5ICsgJz0nICsgZW5jb2RlKHZhbHVlKSArICcmJztcbiAgICB9KTtcbiAgICBcbiAgICByZXR1cm4gcXMuc2xpY2UoMCwgLTEpO1xufVxuXG5cbi8qKlxuICogQ29udmVydCB1cmwgc3R5bGUgcXVlcnkgc3RyaW5nICh3aXRob3V0IFwiP1wiKSBpbnRvIG9iamVjdCBoYXNoXG4gKiBcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmIFRoZSBzdHJpbmcgdG8gYmUgY29udmVydGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkZWNvZGUgb3B0aW9uYWwgZGVjb2RlIGZ1bmN0aW9uLCBkZWNvZGVVUklDb21wb25lbnQgd2lsbCBiZSB1c2VkIGlmIG5vdCBzdXBwbGllZFxuICogQHJldHVybiB7T2JqZWN0fSBUaGUgcmVzdWx0aW5nIG9iamVjdCBoYXNoXG4gKi9cbmZ1bmN0aW9uIGZyb21RdWVyeVN0cmluZyhkZWNvZGUpIHtcbiAgICB2YXIgcGFpcnMgPSB0aGlzLnNwbGl0KCcmJylcbiAgICAgICAgLCByZXN1bHRzID0ge31cbiAgICAgICAgLCBkZWNvZGUgPSBkZWNvZGUgfHwgZGVjb2RlVVJJQ29tcG9uZW50O1xuXG4gICAgcGFpcnMuZm9yRWFjaChmdW5jdGlvbihwYWlyKSB7XG4gICAgICAgIHZhciBzcGxpdFBhaXIgPSBwYWlyLnNwbGl0KCc9Jyk7XG4gICAgICAgIGlmIChzcGxpdFBhaXIubGVuZ3RoIDwgMikgcmV0dXJuO1xuICAgICAgICB2YXIga2V5ID0gc3BsaXRQYWlyWzBdXG4gICAgICAgICAgICAsIHZhbHVlID0gZGVjb2RlKHNwbGl0UGFpclsxXSB8fCAnJyk7XG4gICAgICAgIGlmICgha2V5KSByZXR1cm47XG4gICAgICAgIHJlc3VsdHNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG59XG5cblxuLyoqXG4gKiBTYWZlIEpTT04ucGFyc2UsIHJldHVybnMgdW5kZWZpbmVkIGlmIEpTT04ucGFyc2UgdGhyb3dzIGFuIGV4Y2VwdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmIEpTT04gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIG9iamVjdFxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24ganNvblBhcnNlKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG59XG5cblxuLyoqXG4gKiBEYW4gQmVybnN0ZWluJ3MgYWxnb3J5dGhtIHRvIGNyZWF0ZSBoYXNoIGZyb20gc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGYgc3RyaW5nIHRvIGNvbnZlcnQgdG8gaGFzaFxuICogQHJldHVybiB7TnVtYmVyfVxuICovXG5mdW5jdGlvbiBoYXNoQ29kZSgpIHtcbiAgICB2YXIgaGFzaCA9IDUzODFcbiAgICAgICAgLCBzdHIgPSB0aGlzXG4gICAgICAgICwgbGVuID0gc3RyLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBjaGFyID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGhhc2ggPSAoKGhhc2ggPDwgNSkgKyBoYXNoKSArIGNoYXI7IC8qIGhhc2ggKiAzMyArIGMgKi9cbiAgICB9XG4gICAgcmV0dXJuIGhhc2g7XG59XG5cblxuLyoqXG4gKiBSZW1vdmVzIGdpdmVuIHByZWZpeCBmcm9tIHRoZSBzdHJpbmcuIElmIHN0cmluZyBkb2VzIG5vdCBiZWdpbiBmcm9tIHRoZSBwcmVmaXgsIHJldHVybnMgdW5kZWZpbmVkXG4gKiBcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHVuUHJlZml4KHN0cikge1xuICAgIGlmICh0aGlzLmluZGV4T2Yoc3RyKSA9PSAwKVxuICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlKHN0ciwgJycpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIC0gW3RpbWVzXSgjdGltZXMpXG4gKiAtIFtyZXBlYXRdKCNyZXBlYXQpXG4gKiAtIFt0YXBdKCN0YXApXG4gKiAtIFtyZXN1bHRdKCNyZXN1bHQpXG4gKiAtIFtpZGVudGl0eV0oI2lkZW50aXR5KVxuICogLSBbcHJvcGVydHldKCNwcm9wZXJ0eSlcbiAqIC0gW2NvbXBhcmVQcm9wZXJ0eV0oI2NvbXBhcmVQcm9wZXJ0eSlcbiAqIC0gW25vb3BdKCNub29wKVxuICovXG52YXIgdXRpbE1ldGhvZHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICB0aW1lczogdGltZXMsXG4gICAgcmVwZWF0OiByZXBlYXQsXG4gICAgdGFwOiB0YXAsXG4gICAgcmVzdWx0OiByZXN1bHQsXG4gICAgaWRlbnRpdHk6IGlkZW50aXR5LFxuICAgIHByb3BlcnR5OiBwcm9wZXJ0eSxcbiAgICBjb21wYXJlUHJvcGVydHk6IGNvbXBhcmVQcm9wZXJ0eSxcbiAgICBub29wOiBub29wXG59O1xuXG5cbi8qKlxuICogQ2FsbHMgYGNhbGxiYWNrYCBgc2VsZmAgdGltZXMgd2l0aCBgdGhpc0FyZ2AgYXMgY29udGV4dC4gQ2FsbGJhY2sgaXMgcGFzc2VkIGl0ZXJhdGlvbiBpbmRleCBmcm9tIDAgdG8gYHNlbGYtMWBcbiAqIFxuICogQHBhcmFtIHtJbnRlZ2VyfSBzZWxmXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHBhcmFtIHtBbnl9IHRoaXNBcmdcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiB0aW1lcyhjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIHZhciBhcnIgPSBBcnJheShNYXRoLm1heCgwLCB0aGlzKSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzOyBpKyspXG4gICAgICAgIGFycltpXSA9IGNhbGxiYWNrLmNhbGwodGhpc0FyZywgaSk7XG4gICAgcmV0dXJuIGFycjtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgYXJyYXkgd2l0aCB0aGUgZmlyc3QgYXJndW1lbnQgcmVwZWF0ZWQgYHRpbWVzYCB0aW1lc1xuICogQHBhcmFtICB7QW55fSBzZWxmXG4gKiBAcGFyYW0gIHtJbnRlZ2VyfSB0aW1lc1xuICogQHJldHVybiB7QXJyYXlbQW55XX1cbiAqL1xuZnVuY3Rpb24gcmVwZWF0KHRpbWVzKSB7XG4gICAgdmFyIGFyciA9IEFycmF5KE1hdGgubWF4KDAsIHRpbWVzKSk7O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGltZXM7IGkrKylcbiAgICAgICAgYXJyW2ldID0gdGhpcztcbiAgICByZXR1cm4gYXJyO1xufVxuXG5cbi8qKlxuICogRnVuY3Rpb24gdG8gdGFwIGludG8gY2hhaW5lZCBtZXRob2RzIGFuZCB0byBpbnNwZWN0IGludGVybWVkaWFyeSByZXN1bHRcbiAqXG4gKiBAcGFyYW0ge0FueX0gc2VsZiB2YWx1ZSB0aGF0J3MgcGFzc2VkIGJldHdlZW4gY2hhaW5lZCBtZXRob2RzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgdmFsdWUgKGJvdGggYXMgY29udGV4dCBhbmQgYXMgdGhlIGZpcnN0IHBhcmFtZXRlcilcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gdGFwKGZ1bmMpIHtcbiAgICBmdW5jLmNhbGwodGhpcywgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbi8qKlxuICogQ2FsbHMgZnVuY3Rpb24gYHNlbGZgIChmaXJzdCBwYXJhbWV0ZXIgb2YgXy5yZXN1bHQpIHdpdGggZ2l2ZW4gY29udGV4dCBhbmQgYXJndW1lbnRzXG4gKiBcbiAqIEBwYXJhbSB7RnVuY3Rpb258QW55fSBzZWxmXG4gKiBAcGFyYW0ge0FueX0gdGhpc0FyZyBjb250ZXh0XG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBleHRyYSBhcmd1bWVudHNcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gcmVzdWx0KHRoaXNBcmcpIHsgLy8sIGFyZ3VtZW50c1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gdHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgPyB0aGlzLmFwcGx5KHRoaXNBcmcsIGFyZ3MpXG4gICAgICAgICAgICA6IHRoaXM7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHNlbGYuIFVzZWZ1bCBmb3IgdXNpbmcgYXMgYW4gaXRlcmF0b3IgaWYgdGhlIGFjdHVhbCB2YWx1ZSBuZWVkcyB0byBiZSByZXR1cm5lZC4gVW5saWtlIGluIHVuZGVyc2NvcmUgYW5kIGxvZGFzaCwgdGhpcyBmdW5jdGlvbiBpcyBOT1QgdXNlZCBhcyBkZWZhdWx0IGl0ZXJhdG9yLlxuICpcbiAqIEBwYXJhbSB7QW55fSBzZWxmIFxuICogQHJldHVybiB7QW55fVxuICovXG5mdW5jdGlvbiBpZGVudGl0eSgpIHtcbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIFJldHVybnMgZnVuY3Rpb24gdGhhdCBwaWNrcyB0aGUgcHJvcGVydHkgZnJvbSB0aGUgb2JqZWN0XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGZcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eSgpIHtcbiAgICB2YXIga2V5ID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmpba2V5XTtcbiAgICB9O1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIGluIGFycmF5IHNvcnQgdG8gc29ydCBieSBhIGdpdmVuIHByb3BlcnR5XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGZcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBjb21wYXJlUHJvcGVydHkoKSB7XG4gICAgdmFyIGtleSA9IHRoaXM7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGFba2V5XSA8IGJba2V5XVxuICAgICAgICAgICAgPyAtMVxuICAgICAgICAgICAgOiBhW2tleV0gPiBiW2tleV1cbiAgICAgICAgICAgICAgICA/IDFcbiAgICAgICAgICAgICAgICA6IDA7XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgZG9lcyBub3RoaW5nXG4gKi9cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBtYWtlUHJvdG9JbnN0YW5jZU1ldGhvZDogbWFrZVByb3RvSW5zdGFuY2VNZXRob2QsXG4gICAgbWFrZVByb3RvRnVuY3Rpb246IG1ha2VQcm90b0Z1bmN0aW9uLFxuICAgIG1ha2VGaW5kTWV0aG9kOiBtYWtlRmluZE1ldGhvZFxufVxuXG5cbmZ1bmN0aW9uIG1ha2VQcm90b0luc3RhbmNlTWV0aG9kKG1ldGhvZCkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5zZWxmID0gbWV0aG9kLmFwcGx5KHRoaXMuc2VsZiwgYXJndW1lbnRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbn1cblxuXG5mdW5jdGlvbiBtYWtlUHJvdG9GdW5jdGlvbihtZXRob2QpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIHdoZW4gdGhlIG1ldGhvZCBpcyBleGVjdXRlZCwgdGhlIHZhbHVlIG9mIFwidGhpc1wiIHdpbGwgYmUgYXJndW1lbnRzWzBdLFxuICAgICAgICAvLyBvdGhlciBhcmd1bWVudHMgc3RhcnRpbmcgZnJvbSAjMSB3aWxsIHBhc3NlZCB0byBtZXRob2QgYXMgcGFyYW1ldGVycy5cbiAgICAgICAgcmV0dXJuIG1ldGhvZC5jYWxsLmFwcGx5KG1ldGhvZCwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuXG5cbnZhciBfZXJyb3IgPSBuZXcgRXJyb3I7XG5cbi8qKlxuICogUmV0dXJucyBgZmluZGAgb3IgYGZpbmRJbmRleGAgbWV0aG9kLCBkZXBlbmRpbmcgb24gcGFyYW1ldGVyXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaE1ldGhvZCAtIG1ldGhvZCB0byB1c2UgZm9yIGl0ZXJhdGlvbiAoZm9yRWFjaCBmb3IgYXJyYXkgb3IgZWFjaEtleSBmb3Igb2JqZWN0KVxuICogQHBhcmFtIHtTdHJpbmd9IGZpbmRXaGF0ICd2YWx1ZScgLSByZXR1cm5zIGZpbmQgbWV0aG9kIG9mIEFycmF5IChpbXBsZW1lbnRlZCBpbiBFUzYpIG9yIGZpbmRWYWx1ZSBtZXRob2Qgb2YgT2JqZWN0LCBhbnl0aGluZyBlbHNlID0gcmV0dXJucyBmaW5kSW5kZXgvZmluZEtleSBtZXRob2RzLlxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIG1ha2VGaW5kTWV0aG9kKGVhY2hNZXRob2QsIGZpbmRXaGF0KSB7XG4gICAgdmFyIGFyZ0luZGV4ID0gZmluZFdoYXQgPT0gJ3ZhbHVlJyA/IDAgOiAxO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGZpbmRWYWx1ZU9ySW5kZXgoY2FsbGJhY2ssIHRoaXNBcmcsIG9ubHlFbnVtZXJhYmxlKSB7XG4gICAgICAgIHZhciBjYXVnaHRFcnJvcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGVhY2hNZXRob2QuY2FsbCh0aGlzLCB0ZXN0SXRlbSwgdGhpc0FyZywgb25seUVudW1lcmFibGUpO1xuICAgICAgICB9IGNhdGNoIChmb3VuZCkge1xuICAgICAgICAgICAgaWYgKGZvdW5kID09PSBfZXJyb3IpIHRocm93IGNhdWdodEVycm9yO1xuICAgICAgICAgICAgZWxzZSByZXR1cm4gZm91bmQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgbG9va2luZyBmb3IgaW5kZXggYW5kIG5vdCBmb3VuZCwgcmV0dXJuIC0xXG4gICAgICAgIGlmIChhcmdJbmRleCAmJiBlYWNoTWV0aG9kID09IEFycmF5LnByb3RvdHlwZS5mb3JFYWNoKVxuICAgICAgICAgICAgcmV0dXJuIC0xOyBcblxuICAgICAgICBmdW5jdGlvbiB0ZXN0SXRlbSh2YWx1ZSwgaW5kZXgsIHNlbGYpIHtcbiAgICAgICAgICAgIHZhciB0ZXN0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0ZXN0ID0gY2FsbGJhY2suY2FsbCh0aGlzLCB2YWx1ZSwgaW5kZXgsIHNlbGYpO1xuICAgICAgICAgICAgfSBjYXRjaChlcnIpIHtcbiAgICAgICAgICAgICAgICBjYXVnaHRFcnJvciA9IGVycjtcbiAgICAgICAgICAgICAgICB0aHJvdyBfZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGVzdClcbiAgICAgICAgICAgICAgICB0aHJvdyBhcmd1bWVudHNbYXJnSW5kZXhdO1xuICAgICAgICB9XG4gICAgfVxufVxuIl19 +//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvYWJzdHJhY3QvZmFjZXQuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2Fic3RyYWN0L2ZhY2V0ZWRfb2JqZWN0LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9hYnN0cmFjdC9taXhpbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvYWJzdHJhY3QvcmVnaXN0cnkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2F0dHJpYnV0ZXMvYV9iaW5kLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9hdHRyaWJ1dGVzL2FfY2xhc3MuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2F0dHJpYnV0ZXMvYV9sb2FkLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9hdHRyaWJ1dGVzL2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9iaW5kZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NsYXNzZXMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbW1hbmQvYWN0aW9uc19oaXN0b3J5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21tYW5kL2NtZF9yZWdpc3RyeS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tbWFuZC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tbWFuZC90cmFuc2FjdGlvbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tbWFuZC90cmFuc2FjdGlvbl9oaXN0b3J5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfY2xhc3MuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9Db250YWluZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldHMvRGF0YS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9Eb20uanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldHMvRHJhZy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9Ecm9wLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL0V2ZW50cy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9GcmFtZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9JdGVtLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL0xpc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY19mYWNldHMvTW9kZWxGYWNldC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX2ZhY2V0cy9PcHRpb25zLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL1RlbXBsYXRlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL1RyYW5zZmVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfaW5mby5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9jX3JlZ2lzdHJ5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL2NfdXRpbHMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvY2xhc3Nlcy9WaWV3LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL21zZ19hcGkvZGF0YS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9tc2dfYXBpL2RlX2RhdGEuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvbXNnX2FwaS9kcm9wLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL21zZ19zcmMvZG9tX2V2ZW50cy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy9tc2dfc3JjL2ZyYW1lLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3Njb3BlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0J1dHRvbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9Db21iby5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9Db21ib0xpc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvRGF0ZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9Ecm9wVGFyZ2V0LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0ZvbGRUcmVlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0dyb3VwLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL0h5cGVybGluay5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9JbWFnZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9JbnB1dC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9JbnB1dExpc3QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvTGlzdC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9MaXN0SXRlbS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9SYWRpb0dyb3VwLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL1NlbGVjdC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9TdXBlckNvbWJvLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL1RleHQuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvVGV4dGFyZWEuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL2NvbXBvbmVudHMvdWkvVGltZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9XcmFwcGVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL2Jvb3RzdHJhcC9BbGVydC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29tcG9uZW50cy91aS9ib290c3RyYXAvRGlhbG9nLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9jb21wb25lbnRzL3VpL2Jvb3RzdHJhcC9Ecm9wZG93bi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvY29uZmlnLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9sb2FkZXIuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21lc3Nlbmdlci9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWVzc2VuZ2VyL21fYXBpLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tZXNzZW5nZXIvbV9hcGlfcnguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21lc3Nlbmdlci9tX3NvdXJjZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWVzc2VuZ2VyL21zbmdyX3NvdXJjZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbWlsby5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbW9kZWwvY2hhbmdlX2RhdGEuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21vZGVsL2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi9tb2RlbC9tX21zZ19hcGkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21vZGVsL21fcGF0aC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbW9kZWwvbW9kZWxfdXRpbHMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL21vZGVsL3BhdGhfbXNnX2FwaS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbW9kZWwvcGF0aF91dGlscy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvbW9kZWwvc3ludGhlc2l6ZS9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvcmVnaXN0cnkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3NlcnZpY2VzL2RlX2NvbnN0cnMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3NlcnZpY2VzL2RvbV9zb3VyY2UuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3NlcnZpY2VzL21haWwvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3NlcnZpY2VzL21haWwvbWFpbF9hcGkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3NlcnZpY2VzL21haWwvbWFpbF9zb3VyY2UuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3NlcnZpY2VzL3dpbmRvdy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXNlX2NvbXBvbmVudHMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3VzZV9mYWNldHMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvY2hlY2suanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvY29tcG9uZW50X25hbWUuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvY291bnQuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvY3JlYXRlX2NvbXBvbmVudF9jbGFzcy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9kb20uanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvZG9tX2xpc3RlbmVycy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9kb21yZWFkeS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9kcmFnZHJvcC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9lcnJvci5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9mcmFnbWVudC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9qc29uX3BhcnNlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL2xvZ2dlci5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9sb2dnZXJfY2xhc3MuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvcmVxdWVzdC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9zZWxlY3Rpb24vaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvc3RvcmFnZS9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC9zdG9yYWdlL21vZGVsLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL2xpYi91dGlsL3N0b3JhZ2UvbXNnX3NyYy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9saWIvdXRpbC93ZWJzb2NrZXQvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvd2Vic29ja2V0L21zZ19hcGkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbGliL3V0aWwvd2Vic29ja2V0L21zZ19zcmMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL2Jhc2UzMi9saWIvYmFzZTMyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vZnMuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL2RvdC9kb1QuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL2RvdC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9hYnN0cmFjdC9taXhpbi5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9jbGFzc2VzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL2NvbmZpZy5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9tZXNzZW5nZXIvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21pbG8tY29yZS9saWIvbWVzc2VuZ2VyL21fYXBpLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL21lc3Nlbmdlci9tX2FwaV9yeC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9tZXNzZW5nZXIvbV9zb3VyY2UuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21pbG8tY29yZS9saWIvbWVzc2VuZ2VyL21zbmdyX3NvdXJjZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9taWxvLWNvcmUuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21pbG8tY29yZS9saWIvbWluZGVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL21vZGVsL2NoYW5nZV9kYXRhLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL21vZGVsL2Nvbm5lY3Rvci5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9tb2RlbC9pbmRleC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9tb2RlbC9tX21zZ19hcGkuanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21pbG8tY29yZS9saWIvbW9kZWwvbV9wYXRoLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL21vZGVsL3BhdGhfbXNnX2FwaS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi9tb2RlbC9wYXRoX3V0aWxzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL21vZGVsL3N5bnRoZXNpemUvaW5kZXguanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21pbG8tY29yZS9saWIvdXRpbC9jaGVjay5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL2xpYi91dGlsL2luZGV4LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL3V0aWwvbG9nZ2VyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbGliL3V0aWwvbG9nZ2VyX2NsYXNzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG8uanMiLCIvVXNlcnMvZXZnZW55cG9iZXJlemtpbi9Xb3JrL0NDL21pbG8vbm9kZV9tb2R1bGVzL21pbG8tY29yZS9ub2RlX21vZHVsZXMvbW9sLXByb3RvL2xpYi9wcm90b19hcnJheS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX2Z1bmN0aW9uLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG9fbnVtYmVyLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG9fb2JqZWN0LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG9fcHJvdG90eXBlLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG9fc3RyaW5nLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9taWxvLWNvcmUvbm9kZV9tb2R1bGVzL21vbC1wcm90by9saWIvcHJvdG9fdXRpbC5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbWlsby1jb3JlL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3V0aWxzLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvLmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX2FycmF5LmpzIiwiL1VzZXJzL2V2Z2VueXBvYmVyZXpraW4vV29yay9DQy9taWxvL25vZGVfbW9kdWxlcy9tb2wtcHJvdG8vbGliL3Byb3RvX3Byb3RvdHlwZS5qcyIsIi9Vc2Vycy9ldmdlbnlwb2JlcmV6a2luL1dvcmsvQ0MvbWlsby9ub2RlX21vZHVsZXMvbW9sLXByb3RvL2xpYi9wcm90b19zdHJpbmcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbk5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3o1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlhQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOW1CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeHFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25NQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2cEJBOztBQ0FBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlLQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdOQTs7QUNBQTs7OztBQ0FBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMU1BOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTs7QUNBQTs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3puQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBOztBQ0FBOzs7Ozs7OztBQ0FBOztBQ0FBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBGYWNldDtcblxuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuRmFjZXRgXG4gKiBCYXNlIEZhY2V0IGNsYXNzIGlzIGFuIGFuY2VzdG9yIG9mIFtDb21wb25lbnRGYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0LmpzLmh0bWwpIGNsYXNzLCB0aGUgbWFpbiBidWlsZGluZyBibG9jayBpbiBtaWxvLlxuICogXG4gKiBAcGFyYW0ge0ZhY2V0ZWRPYmplY3R9IG93bmVyIGFuIGluc3RhbmNlIG9mIEZhY2V0ZWRPYmplY3Qgc3ViY2xhc3MgdGhhdCBzdG9yZXMgdGhlIGZhY2V0IG9uIGl0cyBwcm9wZXJ0eSAgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIGBuYW1lYCBwcm9wZXJ0eSBvZiBmYWNldFxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBvcHRpb25hbCBmYWNldCBjb25maWd1cmF0aW9uLCB1c2VkIGluIHN1YmNsYXNzZXNcbiAqL1xuZnVuY3Rpb24gRmFjZXQob3duZXIsIGNvbmZpZykge1xuICAgIHRoaXMubmFtZSA9IF8uZmlyc3RMb3dlckNhc2UodGhpcy5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICB0aGlzLm93bmVyID0gb3duZXI7XG4gICAgdGhpcy5jb25maWcgPSBjb25maWcgfHwge307XG4gICAgdGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiBgaW5pdGAgbWV0aG9kIG9mIHN1YmNsYXNzIHdpbGwgYmUgY2FsbGVkIGJ5IEZhY2V0IGNvbnN0cnVjdG9yLlxuICovXG5fLmV4dGVuZFByb3RvKEZhY2V0LCB7XG4gICAgaW5pdDogZnVuY3Rpb24oKSB7fVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIEZhY2V0ID0gcmVxdWlyZSgnLi9mYWNldCcpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBGYWNldEVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLkZhY2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZhY2V0ZWRPYmplY3Q7XG5cblxuLyoqXG4gKiBgbWlsby5jbGFzc2VzLkZhY2V0ZWRPYmplY3RgXG4gKiBDb21wb25lbnQgY2xhc3MgaXMgYmFzZWQgb24gYW4gYWJzdHJhY3QgYGBgRmFjZXRlZE9iamVjdGBgYCBjbGFzcy4gVGhpcyBjbGFzcyBjYW4gYmUgdXNlZCBpbiBhbnkgc2l0dWF0aW9uIHdoZXJlIG9iamVjdHMgY2FuIGJlIHJlcHJlc2VudGVkIHZpYSBjb2xsZWN0aW9uIG9mIGZhY2V0cyAoYSBmYWNldCBpcyBhbiBvYmplY3Qgb2YgYSBjZXJ0YWluIGNsYXNzLCBpdCBob2xkcyBpdHMgb3duIGNvbmZpZ3VyYXRpb24sIGRhdGEgYW5kIG1ldGhvZHMpLlxuICogSW4gYSB3YXksIFwiZmFjZXRzIHBhdHRlcm5cIiBpcyBhbiBpbnZlcnNpb24gb2YgXCJhZGFwdGVyIHBhdHRlcm5cIiAtIHdoaWxlIHRoZSBsYXR0ZXIgYWxsb3dzIGZpbmRpbmcgYSBjbGFzcy9tZXRob2RzIHRoYXQgaGFzIHNwZWNpZmljIGZ1bmN0aW9uYWxpdHksIGZhY2V0ZWQgb2JqZWN0IGlzIHNpbXBseSBjb25zdHJ1Y3RlZCB0byBoYXZlIHRoZXNlIGZ1bmN0aW9uYWxpdGllcy5cbiAqIFdpdGggdGhpcyBhcmNoaXRlY3R1cmUgaXQgaXMgcG9zc2libGUgdG8gY3JlYXRlIGEgdmlydHVhbGx5IHVubGltaXRlZCBudW1iZXIgb2YgY29tcG9uZW50IGNsYXNzZXMgd2l0aCBhIHZlcnkgbGltaXRlZCBudW1iZXIgb2YgYnVpbGRpbmcgYmxvY2tzIHdpdGhvdXQgaGF2aW5nIGFueSBoaWVyYXJjaHkgb2YgY2xhc3NlcyAtIGFsbCBjb21wb25lbnRzIGluaGVyaXQgZGlyZWN0bHkgZnJvbSBDb21wb25lbnQgY2xhc3MuXG4gKlxuICogVGhpcyBjb25zdHJ1Y3RvciBzaG91bGQgYmUgY2FsbGVkIGJ5IGFsbCBzdWJjbGFzc2VzIGNvbnN0cnVjdG9yIChpdCB3aWxsIGhhcHBlbiBhdXRvbWF0aWNhbGx5IGlmIGEgc3ViY2xhc3MgaXMgY3JlYXRlZCB3aXRoIGBfLmNyZWF0ZVN1YmNsYXNzYCkuXG4gKlxuICogQHJldHVybiB7RmFjZXRlZE9iamVjdH1cbiAqL1xuZnVuY3Rpb24gRmFjZXRlZE9iamVjdCgpIHtcbiAgICAvLyB0aGlzLmZhY2V0c0NvbmZpZyBhbmQgdGhpcy5mYWNldHNDbGFzc2VzIHdlcmUgc3RvcmVkIG9uIGEgc3BlY2lmaWMgY2xhc3MgcHJvdG90eXBlXG4gICAgLy8gd2hlbiB0aGUgY2xhc3Mgd2FzIGNyZWF0ZWQgYnkgRmFjZXRlZE9iamVjdC5jcmVhdGVGYWNldGVkQ2xhc3NcbiAgICB2YXIgZmFjZXRzQ29uZmlnID0gdGhpcy5mYWNldHNDb25maWcgfHwge307XG5cbiAgICB2YXIgZmFjZXRzRGVzY3JpcHRvcnMgPSB7fVxuICAgICAgICAsIGZhY2V0cyA9IHt9O1xuXG4gICAgLy8gRmFjZXRlZE9iamVjdCBjbGFzcyBpdHNlbGYgaXMgbm90IG1lYW50IHRvIGJlIGluc3RhbnRpYXRlZCAtIGl0IGhhcyBubyBmYWNldHNcbiAgICAvLyBJdCBtYXkgY2hhbmdlLCBhcyBhZGRpbmcgZmFjZXRzIGlzIHBvc3NpYmxlIHRvIGluc3RhbmNlc1xuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09IEZhY2V0ZWRPYmplY3QpICAgICAgXG4gICAgICAgIHRocm93IG5ldyBGYWNldEVycm9yKCdGYWNldGVkT2JqZWN0IGlzIGFuIGFic3RyYWN0IGNsYXNzLCBjYW5cXCd0IGJlIGluc3RhbnRpYXRlZCcpO1xuXG4gICAgLy8gaW5zdGFudGlhdGUgY2xhc3MgZmFjZXRzXG4gICAgaWYgKHRoaXMuZmFjZXRzQ2xhc3NlcylcbiAgICAgICAgXy5lYWNoS2V5KHRoaXMuZmFjZXRzQ2xhc3NlcywgaW5zdGFudGlhdGVGYWNldCwgdGhpcywgdHJ1ZSk7XG5cbiAgICAvLyBhZGQgZmFjZXRzIHRvIHRoZSBjbGFzcyBhcyBwcm9wZXJ0aWVzIHVuZGVyIHRoZWlyIG93biBuYW1lXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgZmFjZXRzRGVzY3JpcHRvcnMpO1xuXG4gICAgLy8gc3RvcmUgYWxsIGZhY2V0cyBvbiBgZmFjZXRzYCBwcm9wZXJ0eSBzbyB0aGF0IHRoZXkgY2FuIGJlIGVudW1lcmF0ZWRcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdmYWNldHMnLCBmYWNldHMpOyAgIFxuXG4gICAgLy8gY2FsbCBgaW5pdGBtZXRob2QgaWYgaXQgaXMgZGVmaW5lZCBpbiBzdWJjbGFzc1xuICAgIGlmICh0aGlzLmluaXQpXG4gICAgICAgIHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgLy8gaW5zdGFudGlhdGUgZmFjZXQgd2l0aCBhIGdpdmVuIGNsYXNzIChGYWNldENsYXNzKSBhbmQgbmFtZSAoZmFjZXROYW1lKVxuICAgIGZ1bmN0aW9uIGluc3RhbnRpYXRlRmFjZXQoRmFjZXRDbGFzcywgZmFjZXROYW1lKSB7XG4gICAgICAgIC8vIGdldCBmYWNldCBjb25maWd1cmF0aW9uXG4gICAgICAgIHZhciBmY3RDb25maWcgPSBmYWNldHNDb25maWdbZmFjZXROYW1lXTtcblxuICAgICAgICAvLyBpbnN0YXRpYXRlIGZhY2V0c1xuICAgICAgICBmYWNldHNbZmFjZXROYW1lXSA9IG5ldyBGYWNldENsYXNzKHRoaXMsIGZjdENvbmZpZyk7XG5cbiAgICAgICAgLy8gYWRkIGZhY2V0IHRvIHByb3BlcnR5IGRlc2NyaXB0b3JzXG4gICAgICAgIGZhY2V0c0Rlc2NyaXB0b3JzW2ZhY2V0TmFtZV0gPSB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IGZhY2V0c1tmYWNldE5hbWVdXG4gICAgICAgIH07XG4gICAgfVxufVxuXG5cbi8qKlxuICogIyMjI0ZhY2V0ZWRPYmplY3QgY2xhc3MgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtjcmVhdGVGYWNldGVkQ2xhc3NdKCNGYWNldGVkT2JqZWN0JCRjcmVhdGVGYWNldGVkQ2xhc3MpXG4gKiAtIFtoYXNGYWNldF0oI0ZhY2V0ZWRPYmplY3QkJGhhc0ZhY2V0KVxuICovXG5fLmV4dGVuZChGYWNldGVkT2JqZWN0LCB7XG4gICAgY3JlYXRlRmFjZXRlZENsYXNzOiBGYWNldGVkT2JqZWN0JCRjcmVhdGVGYWNldGVkQ2xhc3MsXG4gICAgaGFzRmFjZXQ6IEZhY2V0ZWRPYmplY3QkJGhhc0ZhY2V0LFxuICAgIGdldEZhY2V0Q29uZmlnOiBGYWNldGVkT2JqZWN0JCRnZXRGYWNldENvbmZpZ1xufSk7XG5cblxuLyoqXG4gKiAjIyMjRmFjZXRlZE9iamVjdCBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2FkZEZhY2V0XSgjRmFjZXRlZE9iamVjdCRhZGRGYWNldClcbiAqL1xuXy5leHRlbmRQcm90byhGYWNldGVkT2JqZWN0LCB7XG4gICAgYWRkRmFjZXQ6IEZhY2V0ZWRPYmplY3QkYWRkRmFjZXRcbn0pO1xuXG5cbi8qKlxuICogRmFjZXRlZE9iamVjdCBpbnN0YW5jZSBtZXRob2QuXG4gKiBBZGRzIGEgZmFjZXQgdG8gdGhlIGluc3RhbmNlIG9mIEZhY2V0ZWRPYmplY3Qgc3ViY2xhc3MuXG4gKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIHRoZSBmYWNldCB0aGF0IHdhcyBjcmVhdGVkLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEZhY2V0Q2xhc3MgZmFjZXQgY2xhc3MgY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7T2JqZWN0fSBmYWNldENvbmZpZyBvcHRpb25hbCBmYWNldCBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gZmFjZXROYW1lIG9wdGlvbmFsIGZhY2V0IG5hbWUsIEZhY2V0Q2xhc3MubmFtZSB3aWxsIGJlIHVzZWQgaWYgZmFjZXROYW1lIGlzIG5vdCBwYXNzZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHRocm93T25FcnJvcnMgSWYgc2V0IHRvIGZhbHNlLCB0aGVuIGVycm9ycyB3aWxsIG9ubHkgYmUgbG9nZ2VkIHRvIGNvbnNvbGUuIFRydWUgYnkgZGVmYXVsdC5cbiAqIEByZXR1cm4ge0ZhY2V0fVxuICovXG5mdW5jdGlvbiBGYWNldGVkT2JqZWN0JGFkZEZhY2V0KEZhY2V0Q2xhc3MsIGZhY2V0Q29uZmlnLCBmYWNldE5hbWUsIHRocm93T25FcnJvcnMpIHtcbiAgICBjaGVjayhGYWNldENsYXNzLCBGdW5jdGlvbik7XG4gICAgY2hlY2soZmFjZXROYW1lLCBNYXRjaC5PcHRpb25hbChTdHJpbmcpKTtcblxuICAgIC8vIGZpcnN0IGxldHRlciBvZiBmYWNldCBuYW1lIHNob3VsZCBiZSBsb3dlcmNhc2VcbiAgICBmYWNldE5hbWUgPSBfLmZpcnN0TG93ZXJDYXNlKGZhY2V0TmFtZSB8fCBGYWNldENsYXNzLm5hbWUpO1xuXG4gICAgLy8gZ2V0IGZhY2V0cyBkZWZpbmVkIGluIGNsYXNzXG4gICAgdmFyIHByb3RvRmFjZXRzID0gdGhpcy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuZmFjZXRzQ2xhc3NlcztcblxuICAgIC8vIGNoZWNrIHRoYXQgdGhpcyBmYWNldE5hbWUgd2FzIG5vdCBhbHJlYWR5IHVzZWQgaW4gdGhlIGNsYXNzXG4gICAgaWYgKHByb3RvRmFjZXRzICYmIHByb3RvRmFjZXRzW2ZhY2V0TmFtZV0pXG4gICAgICAgIHRocm93IG5ldyBGYWNldEVycm9yKCdmYWNldCAnICsgZmFjZXROYW1lICsgJyBpcyBhbHJlYWR5IHBhcnQgb2YgdGhlIGNsYXNzICcgKyB0aGlzLmNvbnN0cnVjdG9yLm5hbWUpO1xuXG4gICAgLy8gY2hlY2sgdGhhdCB0aGlzIGZhY2VOYW1lIGRvZXMgbm90IGFscmVhZHkgZXhpc3Qgb24gdGhlIGZhY2V0ZWQgb2JqZWN0XG4gICAgaWYgKHRoaXNbZmFjZXROYW1lXSkge1xuICAgICAgICB2YXIgbWVzc2FnZSA9ICdmYWNldCAnICsgZmFjZXROYW1lICsgJyBpcyBhbHJlYWR5IHByZXNlbnQgaW4gb2JqZWN0JztcbiAgICAgICAgaWYgKHRocm93T25FcnJvcnMgPT09IGZhbHNlKVxuICAgICAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcignRmFjZXRlZE9iamVjdCBhZGRGYWNldDogJywgbWVzc2FnZSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRocm93IG5ldyBGYWNldEVycm9yKG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIC8vIGluc3RhbnRpYXRlIHRoZSBmYWNldFxuICAgIHZhciBuZXdGYWNldCA9IHRoaXMuZmFjZXRzW2ZhY2V0TmFtZV0gPSBuZXcgRmFjZXRDbGFzcyh0aGlzLCBmYWNldENvbmZpZyk7XG5cbiAgICAvLyBhZGQgZmFjZXQgdG8gZmFjZXRlZCBvYmplY3RcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsIGZhY2V0TmFtZSwgbmV3RmFjZXQsIF8uRU5VTSk7XG5cbiAgICByZXR1cm4gbmV3RmFjZXQ7XG59XG5cblxuLyoqXG4gKiBGYWNldGVkT2JqZWN0IGNsYXNzIG1ldGhvZFxuICogUmV0dXJucyByZWZlcmVuY2UgdG8gdGhlIGZhY2V0IGNsYXNzIGlmIHRoZSBmYWNldCB3aXRoIGBmYWNldE5hbWVgIGlzIHBhcnQgb2YgdGhlIGNsYXNzLCBgdW5kZWZpbmVkYCBvdGhlcndpc2UuIElmIHN1YmNsYXNzIGlzIGNyZWF0ZWQgdXNpbmcgXy5jcmVhdGVTdWJjbGFzcyAoYXMgaXQgc2hvdWxkIGJlKSBpdCB3aWxsIGFsc28gaGF2ZSB0aGlzIG1ldGhvZC5cbiAqIFxuICogQHBhcmFtIHtTdWJjbGFzcyhGYWNldGVkT2JqZWN0KX0gdGhpcyB0aGlzIGluIHRoaXMgbWV0aG9kIHJlZmVycyB0byBGYWNldGVkT2JqZWN0IChvciBpdHMgc3ViY2xhc3MpIHRoYXQgY2FsbHMgdGhpcyBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBmYWNldE5hbWVcbiAqIEByZXR1cm4ge1N1YmNsYXNzKEZhY2V0KXx1bmRlZmluZWR9IFxuICovXG5mdW5jdGlvbiBGYWNldGVkT2JqZWN0JCRoYXNGYWNldChmYWNldE5hbWUpIHtcbiAgICAvLyB0aGlzIHJlZmVycyB0byB0aGUgRmFjZXRlZE9iamVjdCBjbGFzcyAob3Igc3ViY2xhc3MpLCBub3QgaW5zdGFuY2VcbiAgICB2YXIgcHJvdG9GYWNldHMgPSB0aGlzLnByb3RvdHlwZS5mYWNldHNDbGFzc2VzO1xuICAgIHJldHVybiBwcm90b0ZhY2V0cyAmJiBwcm90b0ZhY2V0c1tmYWNldE5hbWVdO1xufVxuXG4vKipcbiAqIEZhY2V0ZWRPYmplY3QgY2xhc3MgbWV0aG9kXG4gKiBSZXR1cm4gdGhlIGNvbmZpZ3VyYXRpb24gb2YgYSBmYWNldFxuICogQHBhcmFtIHtTdHJpbmd9IGZhY2V0TmFtZSB0aGUgZmFjZXQgd2hpY2ggY29uZmlnIHNob3VsZCBiZSByZXRyaWV2ZWRcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRoYXQgd2FzIHBhc3NlZCB0byB0aGUgZmFjZXRcbiAqL1xuZnVuY3Rpb24gRmFjZXRlZE9iamVjdCQkZ2V0RmFjZXRDb25maWcoZmFjZXROYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzRmFjZXQoZmFjZXROYW1lKSA/IHRoaXMucHJvdG90eXBlLmZhY2V0c0NvbmZpZ1tmYWNldE5hbWVdIDogbnVsbDtcbn1cblxuXG4vKipcbiAqIEZhY2V0ZWRPYmplY3QgY2xhc3MgbWV0aG9kXG4gKiBDbGFzcyBmYWN0b3J5IHRoYXQgY3JlYXRlcyBjbGFzc2VzIChjb25zdHJ1Y3RvciBmdW5jdGlvbnMpIGZyb20gdGhlIG1hcHMgb2YgZmFjZXRzIGFuZCB0aGVpciBjb25maWd1cmF0aW9ucy5cbiAqIENyZWF0ZWQgY2xhc3Mgd2lsbCBiZSBzdWJjbGFzcyBvZiBgRmFjZXRlZE9iamVjdGAuXG4gKlxuICogQHBhcmFtIHtTdWJjbGFzcyhGYWNldGVkT2JqZWN0KX0gdGhpcyB0aGlzIGluIHRoaXMgbWV0aG9kIHJlZmVycyB0byBGYWNldGVkT2JqZWN0IChvciBpdHMgc3ViY2xhc3MpIHRoYXQgY2FsbHMgdGhpcyBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIGNsYXNzIG5hbWUgKHdpbGwgYmUgZnVuY3Rpb24gbmFtZSBvZiBjbGFzcyBjb25zdHJ1Y3RvciBmdW5jdGlvbilcbiAqIEBwYXJhbSB7T2JqZWN0W1N1YmNsYXNzKEZhY2V0KV19IGZhY2V0c0NsYXNzZXMgbWFwIG9mIGNsYXNzZXMgb2YgZmFjZXRzIHRoYXQgd2lsbCBjb25zdGl0dXRlIHRoZSBjcmVhdGVkIGNsYXNzXG4gKiBAcGFyYW0ge09iamVjdFtPYmplY3RdfSBmYWNldHNDb25maWcgbWFwIG9mIGZhY2V0cyBjb25maWd1cmF0aW9uLCBzaG91bGQgaGF2ZSB0aGUgc2FtZSBrZXlzIGFzIHRoZSBtYXAgb2YgY2xhc3Nlcy4gU29tZSBmYWNldHMgbWF5IG5vdCBoYXZlIGNvbmZpZ3VyYXRpb24sIGJ1dCB0aGUgY29uZmlndXJhdGlvbiBmb3IgYSBmYWNldCB0aGF0IGlzIG5vdCBpbmNsdWRlZCBpbiBmYWNldHNDbGFzc2VzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uXG4gKiBAcmV0dXJuIHtTdWJjbGFzcyhGYWNldGVkT2JqZWN0KX1cbiAqL1xuZnVuY3Rpb24gRmFjZXRlZE9iamVjdCQkY3JlYXRlRmFjZXRlZENsYXNzKG5hbWUsIGZhY2V0c0NsYXNzZXMsIGZhY2V0c0NvbmZpZykge1xuICAgIGNoZWNrKG5hbWUsIFN0cmluZyk7XG4gICAgY2hlY2soZmFjZXRzQ2xhc3NlcywgTWF0Y2guT3B0aW9uYWwoTWF0Y2guT2JqZWN0SGFzaChNYXRjaC5TdWJjbGFzcyhGYWNldCwgdHJ1ZSkpKSk7XG4gICAgY2hlY2soZmFjZXRzQ29uZmlnLCBNYXRjaC5PcHRpb25hbChPYmplY3QpKTtcblxuICAgIC8vIHRocm93IGV4Y2VwdGlvbiBpZiBjb25maWcgcGFzc2VkIGZvciBmYWNldCBmb3Igd2hpY2ggdGhlcmUgaXMgbm8gY2xhc3NcbiAgICBpZiAoZmFjZXRzQ29uZmlnKVxuICAgICAgICBfLmVhY2hLZXkoZmFjZXRzQ29uZmlnLCBmdW5jdGlvbihmY3RDb25maWcsIGZjdE5hbWUpIHtcbiAgICAgICAgICAgIGlmICghIGZhY2V0c0NsYXNzZXMuaGFzT3duUHJvcGVydHkoZmN0TmFtZSkpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEZhY2V0RXJyb3IoJ2NvbmZpZ3VyYXRpb24gZm9yIGZhY2V0ICgnICsgZmN0TmFtZSArICcpIHBhc3NlZCB0aGF0IGlzIG5vdCBpbiBjbGFzcycpO1xuICAgICAgICB9KTtcblxuICAgIC8vIGNyZWF0ZSBzdWJjbGFzcyBvZiB0aGUgY3VycmVudCBjbGFzcyAodGhpcyByZWZlcnMgdG8gdGhlIGNsYXNzIHRoYXQgY2FsbHMgdGhpcyBtZXRob2QpXG4gICAgdmFyIEZhY2V0ZWRDbGFzcyA9IF8uY3JlYXRlU3ViY2xhc3ModGhpcywgbmFtZSwgdHJ1ZSk7XG5cbiAgICAvLyBnZXQgZmFjZXRzIGNsYXNzZXMgYW5kIGNvbmZpZ3VyYXRpb25zIGZyb20gcGFyZW50IGNsYXNzXG4gICAgZmFjZXRzQ2xhc3NlcyA9IGFkZEluaGVyaXRlZEZhY2V0cyh0aGlzLCBmYWNldHNDbGFzc2VzLCAnZmFjZXRzQ2xhc3NlcycpO1xuICAgIGZhY2V0c0NvbmZpZyA9IGFkZEluaGVyaXRlZEZhY2V0cyh0aGlzLCBmYWNldHNDb25maWcsICdmYWNldHNDb25maWcnKTtcblxuICAgIC8vIHN0b3JlIGZhY2V0cyBjbGFzc2VzIGFuZCBjb25maWd1cmF0aW9ucyBvZiBjbGFzcyBwcm90b3R5cGVcbiAgICBfLmV4dGVuZFByb3RvKEZhY2V0ZWRDbGFzcywge1xuICAgICAgICBmYWNldHNDbGFzc2VzOiBmYWNldHNDbGFzc2VzLFxuICAgICAgICBmYWNldHNDb25maWc6IGZhY2V0c0NvbmZpZ1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIEZhY2V0ZWRDbGFzcztcblxuXG4gICAgZnVuY3Rpb24gYWRkSW5oZXJpdGVkRmFjZXRzKHN1cGVyQ2xhc3MsIGZhY2V0c0luZm8sIGZhY2V0c0luZm9OYW1lKSB7XG4gICAgICAgIHZhciBpbmhlcml0ZWRGYWNldHNJbmZvID0gc3VwZXJDbGFzcy5wcm90b3R5cGVbZmFjZXRzSW5mb05hbWVdO1xuICAgICAgICBpZiAoaW5oZXJpdGVkRmFjZXRzSW5mbylcbiAgICAgICAgICAgIHJldHVybiBfKGluaGVyaXRlZEZhY2V0c0luZm8pXG4gICAgICAgICAgICAgICAgICAgIC5jbG9uZSgpXG4gICAgICAgICAgICAgICAgICAgIC5leHRlbmQoZmFjZXRzSW5mbyB8fCB7fSkuXygpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gZmFjZXRzSW5mbztcbiAgICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgTWl4aW5FcnJvciA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS5NaXhpblxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNaXhpbjtcblxuLyoqXG4gKiBgbWlsby5jbGFzc2VzLk1peGluYCAtIGFuIGFic3RyYWN0IE1peGluIGNsYXNzLlxuICogQ2FuIGJlIHN1YmNsYXNzZWQgdXNpbmc6XG4gKiBgYGBcbiAqIHZhciBNeU1peGluID0gXy5jcmVhdGVTdWJjbGFzcyhtaWxvLmNsYXNzZXMuTWl4aW4sICdNeU1peGluJyk7XG4gKiBgYGBcbiAqXG4gKiBNaXhpbiBwYXR0ZXJuIGlzIGFsc28gdXNlZCwgYnV0IE1peGluIGluIG1pbG8gaXMgaW1wbGVtZW50ZWQgYXMgYSBzZXBhcmF0ZSBvYmplY3QgdGhhdCBpcyBzdG9yZWQgb24gdGhlIHByb3BlcnR5IG9mIHRoZSBob3N0IG9iamVjdCBhbmQgY2FuIGNyZWF0ZSBwcm94eSBtZXRob2RzIG9uIHRoZSBob3N0IG9iamVjdCBpZiByZXF1aXJlZC5cbiAqIENsYXNzZXMgW01lc3Nlbmdlcl0oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpIGFuZCBbTWVzc2FnZVNvdXJjZV0oLi4vbWVzc2VuZ2VyL21fc291cmNlLmpzLmh0bWwpIGFyZSBzdWJjbGFzc2VzIG9mIE1peGluIGFic3RyYWN0IGNsYXNzLiBgdGhpc2AgaW4gcHJveHkgbWV0aG9kcyByZWZlcnMgdG8gTWl4aW4gaW5zdGFuY2UsIHRoZSByZWZlcmVuY2UgdG8gdGhlIGhvc3Qgb2JqZWN0IGlzIGB0aGlzLl9ob3N0T2JqZWN0YC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBPcHRpb25hbCBvYmplY3Qgd2hlcmUgYSBNaXhpbiBpbnN0YW5jZSB3aWxsIGJlIHN0b3JlZCBvbi4gSXQgaXMgdXNlZCB0byBwcm94eSBtZXRob2RzIGFuZCBhbHNvIHRvIGZpbmQgdGhlIHJlZmVyZW5jZSB3aGVuIGl0IGlzIG5lZWRlZCBmb3IgaG9zdCBvYmplY3QgaW1wbGVtZW50YXRpb24uXG4gKiBAcGFyYW0ge09iamVjdH0gcHJveHlNZXRob2RzIE9wdGlvbmFsIG1hcCBvZiBwcm94eSBtZXRob2QgbmFtZXMgYXMga2V5cyBhbmQgTWl4aW4gbWV0aG9kcyBuYW1lcyBhcyB2YWx1ZXMsIHNvIHByb3hpZWQgbWV0aG9kcyBjYW4gYmUgcmVuYW1lZCB0byBhdm9pZCBuYW1lLXNwYWNlIGNvbmZsaWN0cyBpZiB0d28gZGlmZmVyZW50IE1peGluIGluc3RhbmNlcyB3aXRoIHRoZSBzYW1lIG1ldGhvZCBuYW1lcyBhcmUgcHV0IG9uIHRoZSBvYmplY3RcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFsbCBjb25zdHJ1Y3RvciBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgdG8gaW5pdCBtZXRob2Qgb2YgTWl4aW4gc3ViY2xhc3MgdG9nZXRoZXIgd2l0aCBob3N0T2JqZWN0IGFuZCBwcm94eU1ldGhvZHNcbiAqIEByZXR1cm4ge01peGlufVxuICovXG5mdW5jdGlvbiBNaXhpbihob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMpIHsgLy8gLCBvdGhlciBhcmdzIC0gcGFzc2VkIHRvIGluaXQgbWV0aG9kXG4gICAgY2hlY2soaG9zdE9iamVjdCwgTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoT2JqZWN0LCBGdW5jdGlvbikpKTtcblxuICAgIC8vIHN0b3JlIGhvc3RPYmplY3RcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfaG9zdE9iamVjdCcsIGhvc3RPYmplY3QpO1xuXG4gICAgLy8gcHJveHkgbWV0aG9kcyB0byBob3N0T2JqZWN0XG4gICAgaWYgKHByb3h5TWV0aG9kcylcbiAgICAgICAgdGhpcy5fY3JlYXRlUHJveHlNZXRob2RzKHByb3h5TWV0aG9kcyk7XG5cbiAgICAvLyBjYWxsaW5nIGluaXQgaWYgaXQgaXMgZGVmaW5lZCBpbiB0aGUgY2xhc3NcbiAgICBpZiAodGhpcy5pbml0KVxuICAgICAgICB0aGlzLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG4vKipcbiAqICMjIyNNaXhpbiBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICogVGhlc2UgbWV0aG9kcyBhcmUgY2FsbGVkIGJ5IGNvbnN0cnVjdG9yLCB0aGV5IGFyZSBub3QgdG8gYmUgY2FsbGVkIGZyb20gc3ViY2xhc3Nlcy5cbiAqXG4gKiAtIFtfY3JlYXRlUHJveHlNZXRob2RdKCNfY3JlYXRlUHJveHlNZXRob2QpXG4gKiAtIFtfY3JlYXRlUHJveHlNZXRob2RzXSgjX2NyZWF0ZVByb3h5TWV0aG9kcylcbiAqL1xuXy5leHRlbmRQcm90byhNaXhpbiwge1xuICAgIF9jcmVhdGVQcm94eU1ldGhvZDogX2NyZWF0ZVByb3h5TWV0aG9kLCAgLy8gZGVwcmVjYXRlZCwgc2hvdWxkIG5vdCBiZSB1c2VkXG4gICAgX2NyZWF0ZVByb3h5TWV0aG9kczogX2NyZWF0ZVByb3h5TWV0aG9kcyAgLy8gZGVwcmVjYXRlZCwgc2hvdWxkIG5vdCBiZSB1c2VkXG59KTtcblxuXG4vKipcbiAqICMjIyNNaXhpbiBjbGFzcyBtZXRob2RzIyMjI1xuICogVGhlc2UgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgaW4gaG9zdCBjbGFzcyBkZWNsYXJhdGlvbi5cbiAqXG4gKiAtIFt1c2VXaXRoXSgjTWl4aW4kJHVzZVdpdGgpXG4gKi9cbl8uZXh0ZW5kKE1peGluLCB7XG4gICAgdXNlV2l0aDogTWl4aW4kJHVzZVdpdGhcbn0pO1xuXG5cbi8qKlxuICogQ3JlYXRlcyBhIHByb3hpZWQgbWV0aG9kIG9mIE1peGluIHN1YmNsYXNzIG9uIGhvc3Qgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaXhpbk1ldGhvZE5hbWUgbmFtZSBvZiBtZXRob2QgaW4gTWl4aW4gc3ViY2xhc3NcbiAqIEBwYXJhbSB7U3RyaW5nfSBwcm94eU1ldGhvZE5hbWUgbmFtZSBvZiBjcmVhdGVkIHByb3h5IG1ldGhvZCBvbiBob3N0IG9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IGhvc3RPYmplY3QgT3B0aW9uYWwgcmVmZXJlbmNlIHRvIHRoZSBob3N0IG9iamVjdDsgaWYgbm90IHNwZWNpZmllZCB0aGUgaG9zdCBvYmplY3QgcGFzc2VkIHRvIGNvbnN0cnVjdG9yIHdpbCBiZSB1c2VkLiBJdCBhbGxvd3MgdG8gdXNlIHRoZSBzYW1lIGluc3RhbmNlIG9mIE1peGluIG9uIHR3byBob3N0IG9iamVjdHMuXG4gKi9cbmZ1bmN0aW9uIF9jcmVhdGVQcm94eU1ldGhvZChwcm94eU1ldGhvZE5hbWUsIG1peGluTWV0aG9kTmFtZSwgaG9zdE9iamVjdCkge1xuICAgIGhvc3RPYmplY3QgPSBob3N0T2JqZWN0IHx8IHRoaXMuX2hvc3RPYmplY3Q7XG5cbiAgICAvLyBNaXhpbiBjbGFzcyBkb2VzIG5vdCBhbGxvdyBzaGFkb3dpbmcgbWV0aG9kcyB0aGF0IGV4aXN0IG9uIHRoZSBob3N0IG9iamVjdFxuICAgIGlmIChob3N0T2JqZWN0W3Byb3h5TWV0aG9kTmFtZV0pXG4gICAgICAgIHRocm93IG5ldyBNaXhpbkVycm9yKCdtZXRob2QgJyArIHByb3h5TWV0aG9kTmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIGFscmVhZHkgZGVmaW5lZCBpbiBob3N0IG9iamVjdCcpO1xuXG4gICAgdmFyIG1ldGhvZCA9IHRoaXNbbWl4aW5NZXRob2ROYW1lXVxuICAgIGNoZWNrKG1ldGhvZCwgRnVuY3Rpb24pO1xuXG4gICAgLy8gQmluZCBwcm94aWVkIE1peGluJ3MgbWV0aG9kIHRvIE1peGluIGluc3RhbmNlXG4gICAgdmFyIGJvdW5kTWV0aG9kID0gbWV0aG9kLmJpbmQodGhpcyk7XG5cbiAgICBfLmRlZmluZVByb3BlcnR5KGhvc3RPYmplY3QsIHByb3h5TWV0aG9kTmFtZSwgYm91bmRNZXRob2QsIF8uV1JJVCk7XG59XG5cblxuLyoqXG4gKiBDcmVhdGVzIHByb3hpZWQgbWV0aG9kcyBvZiBNaXhpbiBzdWJjbGFzcyBvbiBob3N0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge0hhc2hbU3RyaW5nXXxBcnJheVtTdHJpbmddfSBwcm94eU1ldGhvZHMgbWFwIG9mIG5hbWVzIG9mIG1ldGhvZHMsIGtleSAtIHByb3h5IG1ldGhvZCBuYW1lLCB2YWx1ZSAtIG1peGluIG1ldGhvZCBuYW1lLiBDYW4gYmUgYXJyYXkuXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBhbiBvcHRpb25hbCByZWZlcmVuY2UgdG8gdGhlIGhvc3Qgb2JqZWN0OyBpZiBub3Qgc3BlY2lmaWVkIHRoZSBob3N0IG9iamVjdCBwYXNzZWQgdG8gY29uc3RydWN0b3Igd2lsIGJlIHVzZWQuIEl0IGFsbG93cyB0byB1c2UgdGhlIHNhbWUgaW5zdGFuY2Ugb2YgTWl4aW4gb24gdHdvIGhvc3Qgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gX2NyZWF0ZVByb3h5TWV0aG9kcyhwcm94eU1ldGhvZHMsIGhvc3RPYmplY3QpIHtcbiAgICBjaGVjayhwcm94eU1ldGhvZHMsIE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKFtTdHJpbmddLCBNYXRjaC5PYmplY3RIYXNoKFN0cmluZykpKSk7XG5cbiAgICAvLyBjcmVhdGluZyBhbmQgYmluZGluZyBwcm94eSBtZXRob2RzIG9uIHRoZSBob3N0IG9iamVjdFxuICAgIGlmIChBcnJheS5pc0FycmF5KHByb3h5TWV0aG9kcykpXG4gICAgICAgIHByb3h5TWV0aG9kcy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgICAgIC8vIG1ldGhvZCBjYWxsZWQgdGhpcyB3YXkgdG8gYWxsb3cgdXNpbmcgX2NyZWF0ZVByb3h5TWV0aG9kcyB3aXRoIG9iamVjdHNcbiAgICAgICAgICAgIC8vIHRoYXQgYXJlIG5vdCBpbmhlcml0aW5nIGZyb20gTWl4aW5cbiAgICAgICAgICAgIF9jcmVhdGVQcm94eU1ldGhvZC5jYWxsKHRoaXMsIG1ldGhvZE5hbWUsIG1ldGhvZE5hbWUsIGhvc3RPYmplY3QpO1xuICAgICAgICB9LCB0aGlzKTtcbiAgICBlbHNlXG4gICAgICAgIF8uZWFjaEtleShwcm94eU1ldGhvZHMsIGZ1bmN0aW9uKG1peGluTWV0aG9kTmFtZSwgcHJveHlNZXRob2ROYW1lKSB7XG4gICAgICAgICAgICAvLyBtZXRob2QgY2FsbGVkIHRoaXMgd2F5IHRvIGFsbG93IHVzaW5nIF9jcmVhdGVQcm94eU1ldGhvZHMgd2l0aCBvYmplY3RzXG4gICAgICAgICAgICAvLyB0aGF0IGFyZSBub3QgaW5oZXJpdGluZyBmcm9tIE1peGluXG4gICAgICAgICAgICBfY3JlYXRlUHJveHlNZXRob2QuY2FsbCh0aGlzLCBwcm94eU1ldGhvZE5hbWUsIG1peGluTWV0aG9kTmFtZSwgaG9zdE9iamVjdCk7XG4gICAgICAgIH0sIHRoaXMpO1xufVxuXG5cbi8qKlxuICogU2V0cyBtaXhpbiBpbnN0YW5jZSBwcm9wZXJ0eSBuYW1lIG9uIHRoZSBob3N0IGNsYXNzXG4gKiBDYW4gYmUgY2FsbGVkIG9ubHkgb25jZVxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzIE1peGluIHN1YmNsYXNzIChub3QgaW5zdGFuY2UpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBob3N0Q2xhc3NcbiAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUtleVxuICovXG5mdW5jdGlvbiBNaXhpbl9zZXRJbnN0YW5jZUtleShob3N0Q2xhc3MsIG1ldGhvZCwgaW5zdGFuY2VLZXkpIHtcbiAgICBjaGVjayhob3N0Q2xhc3MsIEZ1bmN0aW9uKTtcbiAgICBjaGVjayhpbnN0YW5jZUtleSwgTWF0Y2guSWRlbnRpZmllclN0cmluZyk7XG5cbiAgICB2YXIgcHJvcCA9IGNvbmZpZy5taXhpbi5pbnN0YW5jZVByb3BlcnRpZXNNYXBcbiAgICAgICAgLCBpbnN0YW5jZUtleXMgPSBob3N0Q2xhc3NbcHJvcF0gPSBob3N0Q2xhc3NbcHJvcF0gfHwge307XG5cbiAgICBpZiAoaW5zdGFuY2VLZXlzW21ldGhvZC5uYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXhpbjogaW5zdGFuY2UgcHJvcGVydHkgZm9yIG1ldGhvZCB3aXRoIG5hbWUgJ1xuICAgICAgICAgICAgKyBtZXRob2QubmFtZSArICcgaXMgYWxyZWFkeSBzZXQnKTtcblxuICAgIGluc3RhbmNlS2V5c1ttZXRob2QubmFtZV0gPSBpbnN0YW5jZUtleTtcbn1cblxuXG4vKipcbiAqIEFkZHMgbWV0aG9kIG9mIE1peGluIHN1YmNsYXNzIHRvIGhvc3QgY2xhc3MgcHJvdG90eXBlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzIE1peGluIHN1YmNsYXNzIChub3QgaW5zdGFuY2UpXG4gKiBAcGFyYW0ge1N0cmluZ30gbWl4aW5NZXRob2ROYW1lIG5hbWUgb2YgbWV0aG9kIGluIE1peGluIHN1YmNsYXNzXG4gKiBAcGFyYW0ge1N0cmluZ30gaG9zdE1ldGhvZE5hbWUgKG9wdGlvbmFsKSBuYW1lIG9mIGNyZWF0ZWQgcHJveHkgbWV0aG9kIG9uIGhvc3Qgb2JqZWN0LCBzYW1lIGlmIG5vdCBzcGVjaWZpZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IG9iamVjdCBjbGFzcywgbXVzdCBiZSBzcGVjaWZpZWQgYXMgdGhlIGxhc3QgcGFyYW1ldGVyICgybmQgb3IgM3JkKVxuICovXG5mdW5jdGlvbiBNaXhpbl9hZGRNZXRob2QoaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2ROYW1lLCBob3N0TWV0aG9kTmFtZSkge1xuICAgIHZhciBtZXRob2QgPSB0aGlzLnByb3RvdHlwZVttaXhpbk1ldGhvZE5hbWVdO1xuICAgIGNoZWNrKG1ldGhvZCwgRnVuY3Rpb24pO1xuXG4gICAgdmFyIHdyYXBwZWRNZXRob2QgPSBfd3JhcE1peGluTWV0aG9kLmNhbGwodGhpcywgbWV0aG9kKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkoaG9zdENsYXNzLnByb3RvdHlwZSwgaG9zdE1ldGhvZE5hbWUsIHdyYXBwZWRNZXRob2QsIF8uV1JJVCk7XG5cbiAgICBNaXhpbl9zZXRJbnN0YW5jZUtleShob3N0Q2xhc3MsIG1ldGhvZCwgaW5zdGFuY2VLZXkpXG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIG1ldGhvZCB0aGF0IHdpbGwgYmUgZXhwb3NlZCBvbiB0aGUgaG9zdCBjbGFzcyBwcm90b3R5cGVcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gdGhpcyBNaXhpbiBzdWJjbGFzcyAobm90IGluc3RhbmNlKVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIF93cmFwTWl4aW5NZXRob2QobWV0aG9kKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyAvLyAsLi4uIGFyZ3VtZW50c1xuICAgICAgICB2YXIgbWl4aW5JbnN0YW5jZSA9IF9nZXRNaXhpbkluc3RhbmNlLmNhbGwodGhpcywgbWV0aG9kLm5hbWUpO1xuICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KG1peGluSW5zdGFuY2UsIGFyZ3VtZW50cyk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBpbnN0YW5jZSBvZiBtaXhpbiBzdWJjbGFzcy5cbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2hlbiBtZXRob2RzIGFyZSBleHBvc2VkIG9uIHRoZSBob3N0IGNsYXNzIHByb3RvdHlwZSAodXNpbmcgYWRkTWVodG9kcykgcmF0aGVyIHRoYW4gb24gaG9zdCBpbnN0YW5jZS5cbiAqIFN1YmNsYXNzZXMgc2hvdWxkIG5vdCB1c2UgdGhpcyBtZXRob2RzIC0gd2hlbmV2ZXIgc3ViY2xhc3MgbWV0aG9kIGlzIGV4cG9zZWQgb24gdGhlIHByb3RvdHlwZSBpdCB3aWxsIGJlIHdyYXBwZWQgdG8gc2V0IGNvcnJlY3QgY29udGV4dCBmb3IgdGhlIHN1YmNsYXNzIG1ldGhvZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBfZ2V0TWl4aW5JbnN0YW5jZShtZXRob2ROYW1lKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBNaXhpbikgcmV0dXJuIHRoaXM7XG4gICAgdmFyIGluc3RhbmNlS2V5cyA9IHRoaXMuY29uc3RydWN0b3JbY29uZmlnLm1peGluLmluc3RhbmNlUHJvcGVydGllc01hcF1cbiAgICByZXR1cm4gdGhpc1tpbnN0YW5jZUtleXNbbWV0aG9kTmFtZV1dO1xufVxuXG5cbi8qKlxuICogQWRkcyBtZXRob2RzIG9mIE1peGluIHN1YmNsYXNzIHRvIGhvc3QgY2xhc3MgcHJvdG90eXBlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXMgTWl4aW4gc3ViY2xhc3MgKG5vdCBpbnN0YW5jZSlcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0Q2xhc3MgaG9zdCBvYmplY3QgY2xhc3M7IG11c3QgYmUgc3BlY2lmaWVkLlxuICogQHBhcmFtIHtTdHJpbmd9IGluc3RhbmNlS2V5IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0aGUgaG9zdCBjbGFzcyBpbnN0YW5jZSB3aWxsIHN0b3JlIG1peGluIGluc3RhbmNlIG9uXG4gKiBAcGFyYW0ge0hhc2hbU3RyaW5nXXxBcnJheVtTdHJpbmddfSBtaXhpbk1ldGhvZHMgbWFwIG9mIG5hbWVzIG9mIG1ldGhvZHMsIGtleSAtIGhvc3QgbWV0aG9kIG5hbWUsIHZhbHVlIC0gbWl4aW4gbWV0aG9kIG5hbWUuIENhbiBiZSBhcnJheS5cbiAqL1xuZnVuY3Rpb24gTWl4aW4kJHVzZVdpdGgoaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2RzKSB7XG4gICAgY2hlY2sobWl4aW5NZXRob2RzLCBNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihbU3RyaW5nXSwgTWF0Y2guT2JqZWN0SGFzaChTdHJpbmcpKSkpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkobWl4aW5NZXRob2RzKSlcbiAgICAgICAgbWl4aW5NZXRob2RzLmZvckVhY2goZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgTWl4aW5fYWRkTWV0aG9kLmNhbGwodGhpcywgaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWV0aG9kTmFtZSwgbWV0aG9kTmFtZSk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIGVsc2VcbiAgICAgICAgXy5lYWNoS2V5KG1peGluTWV0aG9kcywgZnVuY3Rpb24obWl4aW5NZXRob2ROYW1lLCBob3N0TWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgTWl4aW5fYWRkTWV0aG9kLmNhbGwodGhpcywgaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2ROYW1lLCBob3N0TWV0aG9kTmFtZSk7XG4gICAgICAgIH0sIHRoaXMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBSZWdpc3RyeUVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLlJlZ2lzdHJ5XG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxubW9kdWxlLmV4cG9ydHMgPSBDbGFzc1JlZ2lzdHJ5O1xuXG5cbi8qKlxuICogYG1pbG8uY2xhc3Nlcy5DbGFzc1JlZ2lzdHJ5YCAtIHRoZSByZWdpc3RyeSBvZiBjbGFzc2VzIGNsYXNzLlxuICogQ29tcG9uZW50cyBhbmQgRmFjZXRzIHJlZ2lzdGVyIHRoZW1zZWx2ZXMgaW4gcmVnaXN0cmllcy4gSXQgYWxsb3dzIHRvIGF2b2lkIHJlcXVpcmluZyB0aGVtIGZyb20gb25lIG1vZHVsZSBhbmQgcHJldmVudHMgY2lyY3VsYXIgZGVwZW5kZW5jaWVzIGJldHdlZW4gbW9kdWxlcy5cbiAqIFxuICogQHBhcmFtIHtGdW5jdGlvbn0gRm91bmRhdGlvbkNsYXNzIEFsbCBjbGFzc2VzIHRoYXQgYXJlIHJlZ2lzdGVyZWQgaW4gdGhlIHJlZ2lzdHJ5IHNob3VsZCBiZSBzdWJjbGFzc2VzIG9mIHRoZSBGb3VuZGF0aW9uQ2xhc3NcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gQ2xhc3NSZWdpc3RyeSAoRm91bmRhdGlvbkNsYXNzKSB7XG4gICAgaWYgKEZvdW5kYXRpb25DbGFzcylcbiAgICAgICAgdGhpcy5zZXRDbGFzcyhGb3VuZGF0aW9uQ2xhc3MpO1xuXG4gICAgdGhpcy5fX3JlZ2lzdGVyZWRDbGFzc2VzID0ge307XG59XG5cblxuLyoqXG4gKiAjIyMjQ2xhc3NSZWdpc3RyeSBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2FkZF0oI2FkZClcbiAqIC0gW2dldF0oI2dldClcbiAqIC0gW3JlbW92ZV0oI3JlbW92ZSlcbiAqIC0gW2NsZWFuXSgjY2xlYW4pXG4gKiAtIFtzZXRDbGFzc10oI3NldENsYXNzKVxuICovXG5fLmV4dGVuZFByb3RvKENsYXNzUmVnaXN0cnksIHtcbiAgICBhZGQ6IGFkZCxcbiAgICBnZXQ6IGdldCxcbiAgICByZW1vdmU6IHJlbW92ZSxcbiAgICBjbGVhbjogY2xlYW4sXG4gICAgc2V0Q2xhc3M6IHNldENsYXNzXG59KTtcblxuXG4vKipcbiAqIENsYXNzUmVnaXN0cnkgaW5zdGFuY2UgbWV0aG9kIHRoYXQgcmVnaXN0ZXJzIGEgY2xhc3MgaW4gdGhlIHJlZ2lzdHJ5LlxuICogVGhlIG1ldGhvZCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhIGNsYXNzIGlzIHJlZ2lzdGVyZWQgdW5kZXIgdGhlIHNhbWUgbmFtZSBhcyBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgY2xhc3MuXG4gKiBUaGUgbWV0aG9kIGFsbG93cyByZWdpc3RlcmluZyB0aGUgc2FtZSBjbGFzcyB1bmRlciBhIGRpZmZlcmVudCBuYW1lLCBzbyBjbGFzcyBhbGlhc2VzIGNhbiBiZSBjcmVhdGVkLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFDbGFzcyBjbGFzcyB0byByZWdpc3RlciBpbiB0aGUgcmVnaXN0cnkuIFNob3VsZCBiZSBzdWJjbGFzcyBvZiBgdGhpcy5Gb3VuZGF0aW9uQ2xhc3NgLlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgT3B0aW9uYWwgY2xhc3MgbmFtZS4gSWYgY2xhc3MgbmFtZSBpcyBub3Qgc3BlY2lmaWVkLCBpdCB3aWxsIGJlIHRha2VuIGZyb20gY29uc3RydWN0b3IgZnVuY3Rpb24gbmFtZS4gQ2xhc3MgbmFtZSBzaG91bGQgYmUgYSB2YWxpZCBpZGVudGlmaWVyIGFuZCBjYW5ub3QgYmUgYW4gZW1wdHkgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBhZGQoYUNsYXNzLCBuYW1lKSB7XG4gICAgbmFtZSA9IG5hbWUgfHwgYUNsYXNzLm5hbWU7XG5cbiAgICBjaGVjayhuYW1lLCBNYXRjaC5JZGVudGlmaWVyU3RyaW5nLCAnY2xhc3MgbmFtZSBtdXN0IGJlIGlkZW50aWZpZXIgc3RyaW5nJyk7XG5cbiAgICBpZiAodGhpcy5Gb3VuZGF0aW9uQ2xhc3MpIHtcbiAgICAgICAgaWYgKGFDbGFzcyAhPSB0aGlzLkZvdW5kYXRpb25DbGFzcylcbiAgICAgICAgICAgIGNoZWNrKGFDbGFzcywgTWF0Y2guU3ViY2xhc3ModGhpcy5Gb3VuZGF0aW9uQ2xhc3MpLCAnY2xhc3MgbXVzdCBiZSBhIHN1YihjbGFzcykgb2YgYSBmb3VuZGF0aW9uIGNsYXNzJyk7XG4gICAgfSBlbHNlXG4gICAgICAgIHRocm93IG5ldyBSZWdpc3RyeUVycm9yKCdmb3VuZGF0aW9uIGNsYXNzIG11c3QgYmUgc2V0IGJlZm9yZSBhZGRpbmcgY2xhc3NlcyB0byByZWdpc3RyeScpO1xuXG4gICAgaWYgKHRoaXMuX19yZWdpc3RlcmVkQ2xhc3Nlc1tuYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZ2lzdHJ5RXJyb3IoJ2NsYXNzIFwiJyArIG5hbWUgKyAnXCIgaXMgYWxyZWFkeSByZWdpc3RlcmVkJyk7XG5cbiAgICB0aGlzLl9fcmVnaXN0ZXJlZENsYXNzZXNbbmFtZV0gPSBhQ2xhc3M7XG59O1xuXG5cbi8qKlxuICogR2V0cyBjbGFzcyBmcm9tIHJlZ2lzdHJ5IGJ5IG5hbWVcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBDbGFzcyBuYW1lXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gZ2V0KG5hbWUpIHtcbiAgICBjaGVjayhuYW1lLCBTdHJpbmcsICdjbGFzcyBuYW1lIG11c3QgYmUgc3RyaW5nJyk7XG4gICAgcmV0dXJuIHRoaXMuX19yZWdpc3RlcmVkQ2xhc3Nlc1tuYW1lXTtcbn07XG5cblxuLyoqXG4gKiBSZW1vdmUgY2xhc3MgZnJvbSByZWdpc3RyeSBieSBpdHMgbmFtZS5cbiAqIElmIGNsYXNzIGlzIG5vdCByZWdpc3RlcmVkLCB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi5cbiAqIFxuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IG5hbWVPckNsYXNzIENsYXNzIG5hbWUuIElmIGNsYXNzIGNvbnN0cnVjdG9yIGlzIHN1cHBsaWVkLCBpdHMgbmFtZSB3aWxsIGJlIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZShuYW1lT3JDbGFzcykge1xuICAgIGNoZWNrKG5hbWVPckNsYXNzLCBNYXRjaC5PbmVPZihTdHJpbmcsIEZ1bmN0aW9uKSwgJ2NsYXNzIG9yIG5hbWUgbXVzdCBiZSBzdXBwbGllZCcpO1xuXG4gICAgdmFyIG5hbWUgPSB0eXBlb2YgbmFtZU9yQ2xhc3MgPT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICAgICAgICAgID8gbmFtZU9yQ2xhc3NcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbmFtZU9yQ2xhc3MubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgIGlmICghIHRoaXMuX19yZWdpc3RlcmVkQ2xhc3Nlc1tuYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZ2lzdHJ5RXJyb3IoJ2NsYXNzIGlzIG5vdCByZWdpc3RlcmVkJyk7XG5cbiAgICBkZWxldGUgdGhpcy5fX3JlZ2lzdGVyZWRDbGFzc2VzW25hbWVdO1xufTtcblxuXG4vKipcbiAqIFJlbW92ZXMgYWxsIGNsYXNzZXMgZnJvbSByZWdpc3RyeS5cbiAqL1xuZnVuY3Rpb24gY2xlYW4oKSB7XG4gICAgdGhpcy5fX3JlZ2lzdGVyZWRDbGFzc2VzID0ge307XG59O1xuXG5cbi8qKlxuICogU2V0cyBgRm91bmRhdGlvbkNsYXNzYCBvZiB0aGUgcmVnaXN0cnkuIEl0IHNob3VsZCBiZSBzZXQgYmVmb3JlIGFueSBjbGFzcyBjYW4gYmUgYWRkZWQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gRm91bmRhdGlvbkNsYXNzIEFueSBjbGFzcyB0aGF0IHdpbGwgYmUgYWRkZWQgdG8gdGhlIHJlZ2lzdHJ5IHNob3VsZCBiZSBhIHN1YmNsYXNzIG9mIHRoaXMgY2xhc3MuIEZvdW5kYXRpb25DbGFzcyBpdHNlbGYgY2FuIGJlIGFkZGVkIHRvIHRoZSByZWdpc3RyeSB0b28uXG4gKi9cbmZ1bmN0aW9uIHNldENsYXNzKEZvdW5kYXRpb25DbGFzcykge1xuICAgIGNoZWNrKEZvdW5kYXRpb25DbGFzcywgRnVuY3Rpb24pO1xuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ0ZvdW5kYXRpb25DbGFzcycsIEZvdW5kYXRpb25DbGFzcywgXy5FTlVNKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4vYV9jbGFzcycpXG4gICAgLCBBdHRyaWJ1dGVFcnJvciA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS5BdHRyaWJ1dGVcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbnZhciBBVFRSSUJVVEVfUkVHRVhQPSAvXihbXlxcOlxcW1xcXV0qKSg/OlxcWyhbXlxcOlxcW1xcXV0qKVxcXSk/XFw6PyhbXjpdKikkL1xuICAgICwgRkFDRVRTX1NQTElUX1JFR0VYUCA9IC9cXHMqKD86XFwsfFxccylcXHMqL1xuICAgICwgQVRUUklCVVRFX1RFTVBMQVRFID0gJyVjb21wQ2xhc3MlY29tcEZhY2V0czolY29tcE5hbWUnO1xuXG5cbi8qKlxuICogYG1pbG8uYXR0cmlidXRlcy5iaW5kYFxuICogQmluZEF0dHJpYnV0ZSBjbGFzcyBwYXJzZXMvdmFsaWRhdGVzL2V0Yy4gYW4gYXR0cmlidXRlIHRoYXQgYmluZHMgRE9NIGVsZW1lbnRzIHRvIG1pbG8gY29tcG9uZW50cy5cbiAqIFBvc3NpYmxlIGF0dHJpYnV0ZSB2YWx1ZXMgYXJlOlxuICpcbiAqIC0gYDpteVZpZXdgIC0gb25seSBjb21wb25lbnQgbmFtZVxuICogLSBgVmlldzpteVZpZXdgIC0gY2xhc3MgYW5kIGNvbXBvbmVudCBuYW1lXG4gKiAtIGBbRXZlbnRzLCBEYXRhXTpteVZpZXdgIC0gZmFjZXRzIGFuZCBjb21wb25lbnQgbmFtZVxuICogLSBgVmlld1tFdmVudHNdOm15Vmlld2AgLSBjbGFzcywgZmFjZXQocykgYW5kIGNvbXBvbmVudCBuYW1lXG4gKlxuICogU2VlIFtiaW5kZXJdKC4uL2JpbmRlci5qcy5odG1sKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xudmFyIEJpbmRBdHRyaWJ1dGUgPSBfLmNyZWF0ZVN1YmNsYXNzKEF0dHJpYnV0ZSwgJ0JpbmRBdHRyaWJ1dGUnLCB0cnVlKTtcblxuXG4vKipcbiAqICMjIyNCaW5kQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbYXR0ck5hbWVdKCNhdHRyTmFtZSlcbiAqIC0gW3BhcnNlXSgjcGFyc2UpXG4gKiAtIFt2YWxpZGF0ZV0oI3ZhbGlkYXRlKVxuICogLSBbcmVuZGVyXSgjcmVuZGVyKVxuICovXG5fLmV4dGVuZFByb3RvKEJpbmRBdHRyaWJ1dGUsIHtcbiAgICBhdHRyTmFtZTogYXR0ck5hbWUsXG4gICAgcGFyc2U6IHBhcnNlLFxuICAgIHZhbGlkYXRlOiB2YWxpZGF0ZSxcbiAgICByZW5kZXI6IHJlbmRlclxufSk7XG5cblxuLyoqXG4gKiBCaW5kQXR0cmlidXRlIGNsYXNzIG1ldGhvZHNcbiAqXG4gKiAtIFtzZXRJbmZvXSgjQmluZEF0dHJpYnV0ZSQkc2V0SW5mbylcbiAqL1xuXy5leHRlbmQoQmluZEF0dHJpYnV0ZSwge1xuICAgIHNldEluZm86IEJpbmRBdHRyaWJ1dGUkJHNldEluZm9cbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gQmluZEF0dHJpYnV0ZTtcblxuXG4vKipcbiAqIEJpbmRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGUgbmFtZSwgYnkgZGVmYXVsdCAtIGAnbWwtYmluZCdgLlxuICogVG8gY29uZmlndXJlIGJpbmQgYXR0cmlidXRlIG5hbWUgdXNlOlxuICogYGBgXG4gKiBtaWxvLmNvbmZpZyh7IGF0dHJzOiB7IGJpbmQ6ICdjYy1iaW5kJyB9IH0pOyAvLyB3aWxsIHNldCBiaW5kIGF0dHJpYnV0ZSB0byAnY2MtYmluZCdcbiAqIGBgYFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gYXR0ck5hbWUoKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5hdHRycy5iaW5kO1xufVxuXG5cbi8qKlxuICogQmluZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCBwYXJzZXMgYmluZCBhdHRyaWJ1dGUgaWYgaXQgaXMgcHJlc2VudCBvbiB0aGUgZWxlbWVudC5cbiAqIEl0IGRlZmluZXMgcHJvcGVydGllcyBgY29tcENsYXNzYCwgYGNvbXBGYWNldHNgIGFuZCBgY29tcE5hbWVgIG9uIEJpbmRBdHRyaWJ1dGUgaW5zdGFuY2UuXG4gKiBSZXR1cm5zIHRoZSBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICpcbiAqIEByZXR1cm4ge0JpbmRBdHRyaWJ1dGV9XG4gKi9cbiBmdW5jdGlvbiBwYXJzZSgpIHtcbiAgICBpZiAoISB0aGlzLm5vZGUpIHJldHVybjtcblxuICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KCk7XG5cbiAgICBpZiAodmFsdWUpXG4gICAgICAgIHZhciBiaW5kVG8gPSB2YWx1ZS5tYXRjaChBVFRSSUJVVEVfUkVHRVhQKTtcblxuICAgIGlmICghIGJpbmRUbylcbiAgICAgICAgdGhyb3cgbmV3IEF0dHJpYnV0ZUVycm9yKCdpbnZhbGlkIGJpbmQgYXR0cmlidXRlICcgKyB2YWx1ZSk7XG5cbiAgICB0aGlzLmNvbXBDbGFzcyA9IGJpbmRUb1sxXSB8fCAnQ29tcG9uZW50JztcbiAgICB0aGlzLmNvbXBGYWNldHMgPSAoYmluZFRvWzJdICYmIGJpbmRUb1syXS5zcGxpdChGQUNFVFNfU1BMSVRfUkVHRVhQKSkgfHwgdW5kZWZpbmVkO1xuICAgIHRoaXMuY29tcE5hbWUgPSBiaW5kVG9bM10gfHwgdW5kZWZpbmVkOyAvLyB1bmRlZmluZWQgaXMgbm90IHNhbWUgYXMgJydcblxuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogQmluZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCB2YWxpZGF0ZXMgYmluZCBhdHRyaWJ1dGUsIHRocm93cyBpZiBpdCBoYXMgYW4gaW52YWxpZCB2YWx1ZS5cbiAqIFJldHVybnMgdGhlIGluc3RhbmNlIGZvciBtZXRob2QgY2hhaW5pbmcuXG4gKlxuICogQHJldHVybiB7QmluZEF0dHJpYnV0ZX1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGUoKSB7XG4gICAgY2hlY2sodGhpcy5jb21wTmFtZSwgTWF0Y2guSWRlbnRpZmllclN0cmluZyk7XG5cbiAgICBpZiAoISB0aGlzLmNvbXBDbGFzcylcbiAgICAgICAgdGhyb3cgbmV3IEF0dHJpYnV0ZUVycm9yKCdlbXB0eSBjb21wb25lbnQgY2xhc3MgbmFtZSAnICsgdGhpcy5jb21wQ2xhc3MpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBCaW5kQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZCB0aGF0IHJldHVybnMgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBmb3IgZ2l2ZW4gdmFsdWVzIG9mIHByb3BlcnRpZXMgYGNvbXBDbGFzc2AsIGBjb21wTmFtZWAgYW5kIGBjb21wRmFjZXRzYC5cbiAqIElmIGB0aGlzLmNvbXBOYW1lYCBpcyBub3Qgc2V0IGl0IHdpbGwgYmUgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgdGhpcy5jb21wTmFtZSA9IHRoaXMuY29tcE5hbWUgfHwgbWlsby51dGlsLmNvbXBvbmVudE5hbWUoKTtcbiAgICByZXR1cm4gQVRUUklCVVRFX1RFTVBMQVRFXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoJyVjb21wQ2xhc3MnLCB0aGlzLmNvbXBDbGFzcyB8fCAnJylcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgnJWNvbXBGYWNldHMnLCB0aGlzLmNvbXBGYWNldHMgJiYgdGhpcy5jb21wRmFjZXRzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICdbJyArIHRoaXMuY29tcEZhY2V0cy5qb2luKCcsICcpICsgJ10nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJycpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoJyVjb21wTmFtZScsIHRoaXMuY29tcE5hbWUpO1xufVxuXG5cbi8qKlxuICogQmluZEF0dHJpYnV0ZSBjbGFzcyBtZXRob2RcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBjb21wb25lbnRDbGFzcyBvcHRpb25hbCBjbGFzcyBuYW1lXG4gKiBAcGFyYW0ge1N0cmluZ30gY29tcG9uZW50TmFtZSBvcHRpb25hbFxuICogQHBhcmFtIHtBcnJheTxTdHJpbmc+fSBjb21wb25lbnRGYWNldHMgb3B0aW9uYWwgZXh0cmEgZmFjZXQgdG8gYWRkIHRvIHRoZSBjbGFzc1xuICovXG5mdW5jdGlvbiBCaW5kQXR0cmlidXRlJCRzZXRJbmZvKGVsLCBjb21wb25lbnRDbGFzcywgY29tcG9uZW50TmFtZSwgY29tcG9uZW50RmFjZXRzKSB7XG4gICAgdmFyIGF0dHIgPSBuZXcgQmluZEF0dHJpYnV0ZShlbCk7XG4gICAgXy5leHRlbmQoYXR0ciwge1xuICAgICAgICBjb21wQ2xhc3M6IGNvbXBvbmVudENsYXNzLFxuICAgICAgICBjb21wTmFtZTogY29tcG9uZW50TmFtZSxcbiAgICAgICAgY29tcEZhY2V0czogY29tcG9uZW50RmFjZXRzXG4gICAgfSk7XG4gICAgYXR0ci5kZWNvcmF0ZSgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgdG9CZUltcGxlbWVudGVkID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLnRvQmVJbXBsZW1lbnRlZDtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IEF0dHJpYnV0ZTtcblxuXG4vKipcbiAqIEFuIGFic2N0cmFjdCBjbGFzcyBmb3IgcGFyc2luZyBhbmQgdmFsaWRhdGlvbiBvZiBlbGVtZW50IGF0dHJpYnV0ZXMuXG4gKiBTdWJjbGFzc2VzIHNob3VsZCBkZWZpbmUgbWV0aG9kcyBgYXR0ck5hbWVgLCBgcGFyc2VgLCBgdmFsaWRhdGVgIGFuZCBgcmVuZGVyYC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIERPTSBlbGVtZW50IHdoZXJlIGF0dHJpYnV0ZSBpcyBhdHRhY2hlZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgT3B0aW9uYWwgbmFtZSBvZiB0aGUgYXR0cmlidXRlLCB1c3VhbGx5IHN1cHBsaWVkIGJ5IHN1YmNsYXNzIHZpYSBgYXR0ck5hbWVgIG1ldGhvZFxuICovXG5mdW5jdGlvbiBBdHRyaWJ1dGUoZWwsIG5hbWUpIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lIHx8IHRoaXMuYXR0ck5hbWUoKTtcbiAgICB0aGlzLmVsID0gZWw7XG5cbiAgICAvLyBhdHRyaWJ1dGUgbm9kZVxuICAgIHRoaXMubm9kZSA9IGVsLmF0dHJpYnV0ZXNbdGhpcy5uYW1lXTtcbn1cblxuXG5fLmV4dGVuZChBdHRyaWJ1dGUsIHtcbiAgICByZW1vdmU6IEF0dHJpYnV0ZSQkcmVtb3ZlXG59KTtcblxuXG4vKipcbiAqICMjIyNBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtnZXRdKCNBdHRyaWJ1dGUkZ2V0KVxuICogLSBbc2V0XSgjQXR0cmlidXRlJHNldClcbiAqIC0gW2RlY29yYXRlXSgjQXR0cmlidXRlJGRlY29yYXRlKVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgaW5zdGFuY2UgbWV0aG9kcyBzaG91bGQgYmUgZGVmaW5lZCBieSBzdWJjbGFzc1xuICpcbiAqIC0gYXR0ck5hbWUgLSBzaG91bGQgcmV0dXJuIGF0dHJpYnV0ZSBuYW1lXG4gKiAtIHBhcnNlIC0gc2hvdWxkIHBhcnNlIGF0dHJpYnV0ZSB2YWx1ZVxuICogLSB2YWxpZGF0ZSAtIHNob3VsZCB2YWxpZGF0ZSBhdHRyaWJ1dGUgdmFsdWUsIHRocm93aW5nIGV4Y2VwdGlvbiBpZiBpdCBpcyBpbmNvcnJlY3QgXG4gKiAtIHJlbmRlciAtIHNob3VsZCByZXR1cm4gYXR0cmlidXRlIHZhbHVlIGZvciBhIGdpdmVuIGF0dHJpYnV0ZSBzdGF0ZSAob3RoZXIgcHJvcGVydGllcywgYXMgZGVmaW5lZCBpbiBzdWJjbGFzcylcbiAqL1xuXy5leHRlbmRQcm90byhBdHRyaWJ1dGUsIHtcbiAgICBnZXQ6IEF0dHJpYnV0ZSRnZXQsXG4gICAgc2V0OiBBdHRyaWJ1dGUkc2V0LFxuICAgIHJlbW92ZTogQXR0cmlidXRlJHJlbW92ZSxcbiAgICBkZWNvcmF0ZTogQXR0cmlidXRlJGRlY29yYXRlLFxuXG4gICAgZGVzdHJveTogQXR0cmlidXRlJGRlc3Ryb3ksXG5cbiAgICAvLyBzaG91bGQgYmUgZGVmaW5lZCBpbiBzdWJjbGFzc1xuICAgIGF0dHJOYW1lOiB0b0JlSW1wbGVtZW50ZWQsXG4gICAgcGFyc2U6IHRvQmVJbXBsZW1lbnRlZCxcbiAgICB2YWxpZGF0ZTogdG9CZUltcGxlbWVudGVkLFxuICAgIHJlbmRlcjogdG9CZUltcGxlbWVudGVkXG59KTtcblxuXG5mdW5jdGlvbiBBdHRyaWJ1dGUkJHJlbW92ZShlbCwgZGVlcCkge1xuICAgIHZhciBuYW1lID0gdGhpcy5wcm90b3R5cGUuYXR0ck5hbWUoKTtcbiAgICBlbC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG5cbiAgICBpZiAoZGVlcCkge1xuICAgICAgICB2YXIgc2VsZWN0b3IgPSAnWycgKyBuYW1lICsgJ10nO1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSBlbC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgICAgICAgXy5mb3JFYWNoKGNoaWxkcmVuLCBmdW5jdGlvbihjaGlsZEVsKSB7XG4gICAgICAgICAgICBjaGlsZEVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgICAgfSlcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gQXR0cmlidXRlJHJlbW92ZSgpIHtcbiAgICBkZWxldGUgdGhpcy5ub2RlO1xufVxuXG5cbmZ1bmN0aW9uIEF0dHJpYnV0ZSRkZXN0cm95KCkge1xuICAgIGRlbGV0ZSB0aGlzLmVsO1xuICAgIGRlbGV0ZSB0aGlzLm5vZGU7XG59XG5cbi8qKlxuICogQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZCB0aGF0IHJldHVybnMgYXR0cmlidXRlIHZhbHVlIGFzIHN0cmluZy5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIEF0dHJpYnV0ZSRnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWwuZ2V0QXR0cmlidXRlKHRoaXMubmFtZSk7XG59XG5cblxuLyoqXG4gKiBBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIHRoYXQgc2V0cyBhdHRyaWJ1dGUgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIEF0dHJpYnV0ZSRzZXQodmFsdWUpIHtcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSh0aGlzLm5hbWUsIHZhbHVlKTtcbn1cblxuXG4vKipcbiAqIEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCBkZWNvcmF0ZXMgZWxlbWVudCB3aXRoIGl0cyByZW5kZXJlZCB2YWx1ZS5cbiAqIFVzZXMgYHJlbmRlcmAgbWV0aG9kIHRoYXQgc2hvdWxkIGJlIGRlZmllbmQgaW4gc3ViY2xhc3MuXG4gKi9cbmZ1bmN0aW9uIEF0dHJpYnV0ZSRkZWNvcmF0ZSgpIHtcbiAgICB0aGlzLnNldCh0aGlzLnJlbmRlcigpKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4vYV9jbGFzcycpXG4gICAgLCBBdHRyaWJ1dGVFcnJvciA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS5BdHRyaWJ1dGVcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLyoqXG4gKiBgbWlsby5hdHRyaWJ1dGVzLmxvYWRgXG4gKiBMb2FkQXR0cmlidXRlIGNsYXNzIHBhcnNlcy92YWxpZGF0ZXMvZXRjLiBhbiBhdHRyaWJ1dGUgdGhhdCBsb2FkcyBzdWItdmlld3MgaW50byB0aGUgcGFnZS5cbiAqIEF0dHJpYnV0ZSB2YWx1ZSBzaG91bGQgYmUgVVJMIG9mIHRoZSBmaWxlIHRvIGxvYWQgc3VidmlldyBmcm9tLlxuICogU2VlIFtsb2FkZXJdKC4uL2xvYWRlci5qcy5odG1sKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xudmFyIExvYWRBdHRyaWJ1dGUgPSBfLmNyZWF0ZVN1YmNsYXNzKEF0dHJpYnV0ZSwgJ0xvYWRBdHRyaWJ1dGUnLCB0cnVlKTtcblxuXG4vKipcbiAqICMjIyNMb2FkQXR0cmlidXRlIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbYXR0ck5hbWVdKCNhdHRyTmFtZSlcbiAqIC0gW3BhcnNlXSgjcGFyc2UpXG4gKiAtIFt2YWxpZGF0ZV0oI3ZhbGlkYXRlKVxuICogLSBbcmVuZGVyXSgjcmVuZGVyKVxuICovXG5fLmV4dGVuZFByb3RvKExvYWRBdHRyaWJ1dGUsIHtcbiAgICBhdHRyTmFtZTogYXR0ck5hbWUsXG4gICAgcGFyc2U6IHBhcnNlLFxuICAgIHZhbGlkYXRlOiB2YWxpZGF0ZSxcbiAgICByZW5kZXI6IHJlbmRlclxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTG9hZEF0dHJpYnV0ZTtcblxuXG4vKipcbiAqIEJpbmRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIHRoYXQgcmV0dXJucyBhdHRyaWJ1dGUgbmFtZSwgYnkgZGVmYXVsdCAtIGAnbWwtbG9hZCdgLlxuICogVG8gY29uZmlndXJlIGxvYWQgYXR0cmlidXRlIG5hbWUgdXNlOlxuICogYGBgXG4gKiBtaWxvLmNvbmZpZyh7IGF0dHJzOiB7IGxvYWQ6ICdjYy1sb2FkJyB9IH0pOyAvLyB3aWxsIHNldCBiaW5kIGF0dHJpYnV0ZSB0byAnY2MtbG9hZCdcbiAqIGBgYFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gYXR0ck5hbWUoKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5hdHRycy5sb2FkO1xufVxuXG5cbi8qKlxuICogTG9hZEF0dHJpYnV0ZSBpbnN0YW5jZSBtZXRob2QgdGhhdCBwYXJzZXMgbG9hZCBhdHRyaWJ1dGUgaWYgaXQgaXMgcHJlc2VudCBvbiB0aGUgZWxlbWVudC5cbiAqIEl0IGRlZmluZXMgcHJvcGVydHkgYGxvYWRVcmxgIG9uIExvYWRBdHRyaWJ1dGUgaW5zdGFuY2UuXG4gKiBSZXR1cm5zIHRoZSBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICpcbiAqIEByZXR1cm4ge0xvYWRBdHRyaWJ1dGV9XG4gKi9cbmZ1bmN0aW9uIHBhcnNlKCkge1xuICAgIGlmICghIHRoaXMubm9kZSkgcmV0dXJuO1xuXG4gICAgdGhpcy5sb2FkVXJsID0gdGhpcy5nZXQoKTtcbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIExvYWRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIHRoYXQgc2hvdWxkIHZhbGlkYXRlIGxvYWQgYXR0cmlidXRlIGFuZCB0aHJvdyBpZiBpdCBoYXMgYW4gaW52YWxpZCB2YWx1ZS5cbiAqIFRPRE8gLSBpbXBsZW1lbnQgdXJsIHZhbGlkYXRpb24uXG4gKiBSZXR1cm5zIHRoZSBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICpcbiAqIEByZXR1cm4ge0xvYWRBdHRyaWJ1dGV9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICAgIC8vIFRPRE8gdXJsIHZhbGlkYXRpb25cbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIExvYWRBdHRyaWJ1dGUgaW5zdGFuY2UgbWV0aG9kIC0gcmV0dXJucyBVUkxcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkVXJsO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFN1YmNsYXNzZXMgb2YgW0F0dHJpYnV0ZV0oLi9hX2NsYXNzLmpzLmh0bWwpIGNsYXNzXG4gKlxuICogLSBbQmluZEF0dHJpYnV0ZV0oLi9hX2JpbmQuanMuaHRtbClcbiAqIC0gW0xvYWRBdHRyaWJ1dGVdKC4vYV9sb2FkLmpzLmh0bWwpXG4gKi9cbnZhciBhdHRyaWJ1dGVzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgYmluZDogcmVxdWlyZSgnLi9hX2JpbmQnKSxcbiAgICBsb2FkOiByZXF1aXJlKCcuL2FfbG9hZCcpXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbWlsb01haWwgPSByZXF1aXJlKCcuL3NlcnZpY2VzL21haWwnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL2NfcmVnaXN0cnknKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvY2ZfcmVnaXN0cnknKVxuICAgICwgQ29tcG9uZW50ID0gY29tcG9uZW50c1JlZ2lzdHJ5LmdldCgnQ29tcG9uZW50JylcbiAgICAsIENvbXBvbmVudEluZm8gPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvY19pbmZvJylcbiAgICAsIFNjb3BlID0gcmVxdWlyZSgnLi9jb21wb25lbnRzL3Njb3BlJylcbiAgICAsIEJpbmRBdHRyaWJ1dGUgPSByZXF1aXJlKCcuL2F0dHJpYnV0ZXMvYV9iaW5kJylcbiAgICAsIEJpbmRlckVycm9yID0gcmVxdWlyZSgnLi91dGlsL2Vycm9yJykuQmluZGVyXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi91dGlsL2NoZWNrJylcbiAgICAsIHV0aWxEb20gPSByZXF1aXJlKCcuL3V0aWwvZG9tJylcbiAgICAsIE1hdGNoID0gIGNoZWNrLk1hdGNoO1xuXG5cbmJpbmRlci5zY2FuID0gc2NhbjtcbmJpbmRlci5jcmVhdGUgPSBjcmVhdGU7XG5iaW5kZXIudHdvUGFzcyA9IHR3b1Bhc3M7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBiaW5kZXI7XG5cblxuLyoqXG4gKiBgbWlsby5iaW5kZXJgXG4gKlxuICogUmVjdXJzaXZlbHkgc2NhbnMgdGhlIGRvY3VtZW50IHRyZWUgaW5zaWRlIGBzY29wZUVsYCAoZG9jdW1lbnQuYm9keSBieSBkZWZhdWx0KSBsb29raW5nIGZvciBfX21sLWJpbmRfXyBhdHRyaWJ1dGUgdGhhdCBzaG91bGQgY29udGFpbiB0aGUgY2xhc3MsIGFkZGl0aW9uYWwgZmFjZXRzIGFuZCB0aGUgbmFtZSBvZiB0aGUgY29tcG9uZW50IHRoYXQgc2hvdWxkIGJlIGNyZWF0ZWQgYW5kIGJvdW5kIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIFBvc3NpYmxlIHZhbHVlcyBvZiBfX21sLWJpbmRfXyBhdHRyaWJ1dGU6XG4gKlxuICogLSBgOm15Vmlld2AgLSBvbmx5IGNvbXBvbmVudCBuYW1lLiBBbiBpbnN0YW5jZSBvZiBDb21wb25lbnQgY2xhc3Mgd2lsbCBiZSBjcmVhdGVkIHdpdGhvdXQgYW55IGZhY2V0cy5cbiAqIC0gYFZpZXc6bXlWaWV3YCAtIGNsYXNzIGFuZCBjb21wb25lbnQgbmFtZS4gQW4gaW5zdGFuY2Ugb2YgVmlldyBjbGFzcyB3aWxsIGJlIGNyZWF0ZWQuXG4gKiAtIGBbRXZlbnRzLCBEYXRhXTpteVZpZXdgIC0gZmFjZXRzIGFuZCBjb21wb25lbnQgbmFtZS4gQW4gaW5zdGFuY2Ugb2YgQ29tcG9uZW50IGNsYXNzIHdpbGwgYmUgY3JlYXRlZCB3aXRoIHRoZSBhZGRpdGlvbiBvZiBmYWNldHMgRXZlbnRzIGFuZCBEYXRhLlxuICogLSBgVmlld1tFdmVudHMsIERhdGFdOm15Vmlld2AgLSBjbGFzcywgZmFjZXQocykgYW5kIGNvbXBvbmVudCBuYW1lLiBBbiBpbnN0YW5jZSBvZiBWaWV3IGNsYXNzIHdpbGwgYmUgY3JlYXRlZCB3aXRoIHRoZSBhZGRpdGlvbiBvZiBmYWNldHMgRXZlbnRzIGFuZCBEYXRhLlxuICpcbiAqIEZ1bmN0aW9uIHJldHVybnMgYW4gaW5zdGFuY2Ugb2YgW2BTY29wZWBdKC4vY29tcG9uZW50cy9zY29wZS5qcy5odG1sKSBjbGFzcyBjb250YWluaW5nIGFsbCBjb21wb25lbnRzIGNyZWF0ZWQgYXMgYSByZXN1bHQgb2Ygc2Nhbm5pbmcgRE9NLlxuICpcbiAqIElmIHRoZSBjb21wb25lbnQgaGFzIFtgQ29udGFpbmVyYF0oLi9jb21wb25lbnRzL2NfZmFjZXRzL0NvbnRhaW5lci5qcykgZmFjZXQsIGNoaWxkcmVuIG9mIHRoaXMgZWxlbWVudCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgYHNjb3BlYCBvYmplY3QsIGF2YWlsYWJsZSBhcyBzY29wZSBwcm9wZXJ0eSBvbiB0aGUgQ29udGFpbmVyIGZhY2V0IG9mIHRoaXMgY29tcG9uZW50LiBOYW1lcyBvZiBjb21wb25lbnRzIHdpdGhpbiB0aGUgc2NvcGUgc2hvdWxkIGJlIHVuaXF1ZSwgYnV0IHRoZXkgY2FuIGJlIHRoZSBzYW1lIGFzIHRoZSBuYW1lcyBvZiBjb21wb25lbnRzIGluIG91dGVyIHNjb3BlIChvciBzb21lIG90aGVyIHNjb3BlKS5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHNjb3BlRWwgcm9vdCBlbGVtZW50IGluc2lkZSB3aGljaCBET00gd2lsbCBiZSBzY2FubmVkIGFuZCBib3VuZFxuICogQHBhcmFtIHtTY29wZX0gcm9vdFNjb3BlIE9wdGlvbmFsIFJvb3Qgc2NvcGUgb2JqZWN0IHdoZXJlIHRvcCBsZXZlbCBjb21wb25lbnRzIHdpbGwgYmUgc2F2ZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGJpbmRSb290RWxlbWVudCBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gdGhlIHJvb3QgZWxlbWVudCB3aWxsIG5vdCBiZSBib3VuZC4gVHJ1ZSBieSBkZWZhdWx0LlxuICogQHBhcmFtIHtCb29sZWFufSB0aHJvd09uRXJyb3JzIElmIHNldCB0byBmYWxzZSwgdGhlbiBlcnJvcnMgd2lsbCBvbmx5IGJlIGxvZ2dlZCB0byBjb25zb2xlLiBUcnVlIGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJuIHtTY29wZX1cbiAqL1xuZnVuY3Rpb24gYmluZGVyKHNjb3BlRWwsIHJvb3RTY29wZSwgYmluZFJvb3RFbGVtZW50LCB0aHJvd09uRXJyb3JzKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJpbmRlclNjb3BlKHNjb3BlRWwsIGZ1bmN0aW9uKHNjb3BlLCBlbCwgYXR0ciwgdGhyb3dPbkVycm9ycykge1xuICAgICAgICB2YXIgaW5mbyA9IG5ldyBDb21wb25lbnRJbmZvKHNjb3BlLCBlbCwgYXR0ciwgdGhyb3dPbkVycm9ycyk7XG4gICAgICAgIHJldHVybiBDb21wb25lbnQuY3JlYXRlKGluZm8sIHRocm93T25FcnJvcnMpO1xuICAgIH0sIHJvb3RTY29wZSwgYmluZFJvb3RFbGVtZW50LCB0aHJvd09uRXJyb3JzKTtcbn1cblxuXG4vLyBiaW5kIGluIHR3byBwYXNzZXNcbmZ1bmN0aW9uIHR3b1Bhc3Moc2NvcGVFbCwgcm9vdFNjb3BlLCBiaW5kUm9vdEVsZW1lbnQsIHRocm93T25FcnJvcnMpIHtcbiAgICB2YXIgc2NhblNjb3BlID0gYmluZGVyLnNjYW4oc2NvcGVFbCwgcm9vdFNjb3BlLCBiaW5kUm9vdEVsZW1lbnQsIHRocm93T25FcnJvcnMpO1xuICAgIHJldHVybiBiaW5kZXIuY3JlYXRlKHNjYW5TY29wZSwgdW5kZWZpbmVkLCB0aHJvd09uRXJyb3JzKTtcbn1cblxuXG4vLyBzY2FuIERPTSBmb3IgQmluZEF0dHJpYnV0ZVxuZnVuY3Rpb24gc2NhbihzY29wZUVsLCByb290U2NvcGUsIGJpbmRSb290RWxlbWVudCwgdGhyb3dPbkVycm9ycykge1xuICAgIHJldHVybiBjcmVhdGVCaW5kZXJTY29wZShzY29wZUVsLCBmdW5jdGlvbihzY29wZSwgZWwsIGF0dHIsIHRocm93T25FcnJvcnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDb21wb25lbnRJbmZvKHNjb3BlLCBlbCwgYXR0ciwgdGhyb3dPbkVycm9ycyk7XG4gICAgfSwgcm9vdFNjb3BlLCBiaW5kUm9vdEVsZW1lbnQsIHRocm93T25FcnJvcnMpO1xufVxuXG5cbi8vIGNyZWF0ZSBib3VuZCBjb21wb25lbnRzXG5mdW5jdGlvbiBjcmVhdGUoc2NhblNjb3BlLCBob3N0T2JqZWN0LCB0aHJvd09uRXJyb3JzKSB7XG4gICAgdmFyIHNjb3BlID0gbmV3IFNjb3BlKHNjYW5TY29wZS5fcm9vdEVsLCBob3N0T2JqZWN0KVxuICAgICAgICAsIGFkZE1ldGhvZCA9IHRocm93T25FcnJvcnMgPT09IGZhbHNlID8gJ19zYWZlQWRkJyA6ICdfYWRkJztcblxuICAgIHNjYW5TY29wZS5fZWFjaChmdW5jdGlvbihjb21wSW5mbykge1xuICAgICAgICAvLyBzZXQgY29ycmVjdCBjb21wb25lbnQncyBzY29wZVxuICAgICAgICB2YXIgaW5mbyA9IF8uY2xvbmUoY29tcEluZm8pXG4gICAgICAgIGluZm8uc2NvcGUgPSBzY29wZTtcblxuICAgICAgICAvLyBjcmVhdGUgY29tcG9uZW50XG4gICAgICAgIHZhciBhQ29tcG9uZW50ID0gQ29tcG9uZW50LmNyZWF0ZShpbmZvLCB0aHJvd09uRXJyb3JzKTtcblxuICAgICAgICBzY29wZVthZGRNZXRob2RdKGFDb21wb25lbnQsIGFDb21wb25lbnQubmFtZSk7XG4gICAgICAgIGlmIChhQ29tcG9uZW50LmNvbnRhaW5lcilcbiAgICAgICAgICAgIGFDb21wb25lbnQuY29udGFpbmVyLnNjb3BlID0gY3JlYXRlKGNvbXBJbmZvLmNvbnRhaW5lci5zY29wZSwgYUNvbXBvbmVudC5jb250YWluZXIsIHRocm93T25FcnJvcnMpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNjb3BlO1xufVxuXG4vKipcbiAqIGBjcmVhdGVCaW5kZXJTY29wZWBcbiAqIEBwYXJhbSAge0VsZW1lbnR9IHNjb3BlRWwgICAgICAgICAgICAgc2NvcGVFbCByb290IGVsZW1lbnQgaW5zaWRlIHdoaWNoIERPTSB3aWxsIGJlIHNjYW5uZWQgYW5kIGJvdW5kIChkb2N1bWVudC5ib2R5IGJ5IGRlZmF1bHQpLlxuICogQHBhcmFtICB7RnVuY3Rpb259IHNjb3BlT2JqZWN0RmFjdG9yeSBTZWUgW2JpbmRlcl0oI21pbG8uYmluZGVyKVxuICogQHBhcmFtICB7U2NvcGV9IHJvb3RTY29wZSAgICAgICAgICAgICBPcHRpb25hbCBSb290IHNjb3BlIG9iamVjdCB3aGVyZSB0b3AgbGV2ZWwgY29tcG9uZW50cyB3aWxsIGJlIHNhdmVkLlxuICogQHBhcmFtICB7Qm9vbGVhbn0gYmluZFJvb3RFbGVtZW50ICAgICBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gdGhlIHJvb3QgZWxlbWVudCB3aWxsIG5vdCBiZSBib3VuZC4gVHJ1ZSBieSBkZWZhdWx0LlxuICogQHBhcmFtICB7Qm9vbGVhbn0gdGhyb3dPbkVycm9ycyAgICAgICBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gZXJyb3JzIHdpbGwgb25seSBiZSBsb2dnZWQgdG8gY29uc29sZS4gVHJ1ZSBieSBkZWZhdWx0LlxuICogQHJldHVybiB7U2NvcGV9ICAgICAgICAgICAgICAgICAgICAgICBbZGVzY3JpcHRpb25dXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRlclNjb3BlKHNjb3BlRWwsIHNjb3BlT2JqZWN0RmFjdG9yeSwgcm9vdFNjb3BlLCBiaW5kUm9vdEVsZW1lbnQsIHRocm93T25FcnJvcnMpIHtcbiAgICB2YXIgc2NvcGVFbCA9IHNjb3BlRWwgfHwgZG9jdW1lbnQuYm9keVxuICAgICAgICAsIHNjb3BlID0gcm9vdFNjb3BlIHx8IG5ldyBTY29wZShzY29wZUVsKVxuICAgICAgICAsIGFkZE1ldGhvZCA9IHRocm93T25FcnJvcnMgPT09IGZhbHNlID8gJ19zYWZlQWRkJyA6ICdfYWRkJztcblxuICAgIGNyZWF0ZVNjb3BlRm9yRWxlbWVudChzY29wZSwgc2NvcGVFbCwgYmluZFJvb3RFbGVtZW50KTtcblxuICAgIHJldHVybiBzY29wZTtcblxuXG4gICAgZnVuY3Rpb24gY3JlYXRlU2NvcGVGb3JFbGVtZW50KHNjb3BlLCBlbCwgYmluZFJvb3RFbGVtZW50KSB7XG4gICAgICAgIC8vIGdldCBlbGVtZW50J3MgYmluZGluZyBhdHRyaWJ1dGUgKG1sLWJpbmQgYnkgZGVmYXVsdClcbiAgICAgICAgdmFyIGF0dHIgPSBuZXcgQmluZEF0dHJpYnV0ZShlbCk7XG5cbiAgICAgICAgLy8gaWYgZWxlbWVudCBoYXMgYmluZCBhdHRyaWJ1dGUgY3JhdGUgc2NvcGUgb2JqZWN0IChDb21wb25lbnQgb3IgQ29tcG9uZW50SW5mbylcbiAgICAgICAgaWYgKGF0dHIubm9kZSAmJiBiaW5kUm9vdEVsZW1lbnQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB2YXIgc2NvcGVkT2JqZWN0ID0gc2NvcGVPYmplY3RGYWN0b3J5KHNjb3BlLCBlbCwgYXR0ciwgdGhyb3dPbkVycm9ycylcbiAgICAgICAgICAgICAgICAsIGlzQ29udGFpbmVyID0gdHlwZW9mIHNjb3BlZE9iamVjdCAhPSAndW5kZWZpbmVkJyAmJiBzY29wZWRPYmplY3QuY29udGFpbmVyO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGNoaWxkTm9kZXMgYWRkIGNoaWxkcmVuIHRvIG5ldyBzY29wZSBpZiB0aGlzIGVsZW1lbnQgaGFzIGNvbXBvbmVudCB3aXRoIENvbnRhaW5lciBmYWNldFxuICAgICAgICAvLyBvdGhlcndpc2UgY3JlYXRlIGEgbmV3IHNjb3BlXG4gICAgICAgIGlmIChlbC5jaGlsZE5vZGVzICYmIGVsLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaXNDb250YWluZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgaW5uZXJTY29wZSA9IG5ldyBTY29wZShlbCk7XG4gICAgICAgICAgICAgICAgc2NvcGVkT2JqZWN0LmNvbnRhaW5lci5zY29wZSA9IGlubmVyU2NvcGU7XG4gICAgICAgICAgICAgICAgaW5uZXJTY29wZS5faG9zdE9iamVjdCA9IHNjb3BlZE9iamVjdC5jb250YWluZXI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNyZWF0ZVNjb3BlRm9yQ2hpbGRyZW4oZWwsIGlzQ29udGFpbmVyID8gaW5uZXJTY29wZSA6IHNjb3BlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHNjb3BlIHdhc24ndCBwcmV2aW91c2x5IGNyZWF0ZWQgb24gY29udGFpbmVyIGZhY2V0LCBjcmVhdGUgZW1wdHkgc2NvcGUgYW55d2F5XG4gICAgICAgIGlmIChpc0NvbnRhaW5lciAmJiAhIHNjb3BlZE9iamVjdC5jb250YWluZXIuc2NvcGUpXG4gICAgICAgICAgICBzY29wZWRPYmplY3QuY29udGFpbmVyLnNjb3BlID0gbmV3IFNjb3BlKGVsKTtcblxuXG4gICAgICAgIC8vIFRPRE8gY29uZGl0aW9uIGFmdGVyICYmIGlzIGEgaGFjaywgc2hvdWxkIG5vdCBiZSB1c2VkIVxuICAgICAgICBpZiAoc2NvcGVkT2JqZWN0KSAvLyAmJiAhIHNjb3BlW2F0dHIuY29tcE5hbWVdKVxuICAgICAgICAgICAgc2NvcGVbYWRkTWV0aG9kXShzY29wZWRPYmplY3QsIGF0dHIuY29tcE5hbWUpO1xuXG4gICAgICAgIC8vIF8uZGVmZXIocG9zdENoaWxkcmVuQm91bmRNZXNzYWdlLCBlbCk7XG4gICAgICAgIHBvc3RDaGlsZHJlbkJvdW5kTWVzc2FnZShlbCk7XG5cbiAgICAgICAgcmV0dXJuIHNjb3BlZE9iamVjdDtcblxuXG4gICAgICAgIGZ1bmN0aW9uIHBvc3RDaGlsZHJlbkJvdW5kTWVzc2FnZShlbCkge1xuICAgICAgICAgICAgdmFyIGVsQ29tcCA9IENvbXBvbmVudC5nZXRDb21wb25lbnQoZWwpO1xuXG4gICAgICAgICAgICBpZiAoZWxDb21wKVxuICAgICAgICAgICAgICAgIGVsQ29tcC5wb3N0TWVzc2FnZVN5bmMoJ2NoaWxkcmVuYm91bmQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG4gICAgZnVuY3Rpb24gY3JlYXRlU2NvcGVGb3JDaGlsZHJlbihjb250YWluZXJFbCwgc2NvcGUpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gdXRpbERvbS5jaGlsZHJlbihjb250YWluZXJFbCk7XG5cbiAgICAgICAgXy5mb3JFYWNoKGNoaWxkcmVuLCBmdW5jdGlvbihub2RlKSB7XG4gICAgICAgICAgICBjcmVhdGVTY29wZUZvckVsZW1lbnQoc2NvcGUsIG5vZGUsIHRydWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHNjb3BlO1xuICAgIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gPGEgbmFtZT1cImNsYXNzZXNcIj48L2E+XG4vLyBtaWxvLmNsYXNzZXNcbi8vIC0tLS0tLS0tLS0tXG5cbi8vIFRoaXMgbW9kdWxlIGNvbnRhaW5zIGZvdW5kYXRpb24gY2xhc3NlcyBhbmQgY2xhc3MgcmVnaXN0cmllcy5cblxudmFyIGNsYXNzZXMgPSB7XG4gICAgRmFjZXQ6IHJlcXVpcmUoJy4vYWJzdHJhY3QvZmFjZXQnKSxcbiAgICBGYWNldGVkT2JqZWN0OiByZXF1aXJlKCcuL2Fic3RyYWN0L2ZhY2V0ZWRfb2JqZWN0JyksXG4gICAgU2NvcGU6IHJlcXVpcmUoJy4vY29tcG9uZW50cy9zY29wZScpLFxuICAgIENsYXNzUmVnaXN0cnk6IHJlcXVpcmUoJy4vYWJzdHJhY3QvcmVnaXN0cnknKSxcbiAgICBNaXhpbjogcmVxdWlyZSgnLi9hYnN0cmFjdC9taXhpbicpLFxuICAgIE1lc3NhZ2VTb3VyY2U6IHJlcXVpcmUoJy4vbWVzc2VuZ2VyL21fc291cmNlJyksXG4gICAgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZTogcmVxdWlyZSgnLi9tZXNzZW5nZXIvbXNuZ3Jfc291cmNlJyksXG4gICAgTWVzc2VuZ2VyQVBJOiByZXF1aXJlKCcuL21lc3Nlbmdlci9tX2FwaScpLFxuICAgIERPTUV2ZW50c1NvdXJjZTogcmVxdWlyZSgnLi9jb21wb25lbnRzL21zZ19zcmMvZG9tX2V2ZW50cycpLFxuICAgIFRyYW5zYWN0aW9uOiByZXF1aXJlKCcuL2NvbW1hbmQvdHJhbnNhY3Rpb24nKSxcbiAgICBUcmFuc2FjdGlvbkhpc3Rvcnk6IHJlcXVpcmUoJy4vY29tbWFuZC90cmFuc2FjdGlvbl9oaXN0b3J5Jylcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY2xhc3NlcztcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gQWN0aW9uc0hpc3Rvcnk7XG5cblxuLyoqXG4gKiBTdG9yZXMgbGlzdCBvZiBjb21tYW5kcyBvciB0cmFuc2FjdGlvbnNcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7TnVtYmVyfSBtYXhMZW5ndGhcbiAqL1xuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkobWF4TGVuZ3RoKSB7XG4gICAgdGhpcy5fbWF4TGVuZ3RoID0gbWF4TGVuZ3RoIHx8IEluZmluaXR5O1xuICAgIHRoaXMuYWN0aW9ucyA9IFtdO1xuICAgIHRoaXMucG9zaXRpb24gPSAwO1xufVxuXG5cbl8uZXh0ZW5kUHJvdG8oQWN0aW9uc0hpc3RvcnksIHtcbiAgICBzdG9yZTogQWN0aW9uc0hpc3Rvcnkkc3RvcmUsXG4gICAgZGVsZXRlTGFzdDogQWN0aW9uc0hpc3RvcnkkZGVsZXRlTGFzdCxcbiAgICB1bmRvOiBBY3Rpb25zSGlzdG9yeSR1bmRvLFxuICAgIHJlZG86IEFjdGlvbnNIaXN0b3J5JHJlZG8sXG4gICAgdW5kb0FsbDogQWN0aW9uc0hpc3RvcnkkdW5kb0FsbCxcbiAgICByZWRvQWxsOiBBY3Rpb25zSGlzdG9yeSRyZWRvQWxsLFxuICAgIHVuZG9BbGxBc3luYzogQWN0aW9uc0hpc3RvcnkkdW5kb0FsbEFzeW5jLFxuICAgIHJlZG9BbGxBc3luYzogQWN0aW9uc0hpc3RvcnkkcmVkb0FsbEFzeW5jLFxuICAgIGVhY2g6IEFjdGlvbnNIaXN0b3J5JGVhY2gsXG4gICAgZWFjaFJldmVyc2U6IEFjdGlvbnNIaXN0b3J5JGVhY2hSZXZlcnNlLFxuICAgIGdldExhc3RBY3Rpb246IEFjdGlvbnNIaXN0b3J5JGdldExhc3RBY3Rpb24sXG5cbiAgICBnZXREZXNjcmlwdGlvbjogQWN0aW9uc0hpc3RvcnkkZ2V0RGVzY3JpcHRpb25cbn0pO1xuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JHN0b3JlKGNvbW1hbmQpIHtcbiAgICBfdHJ1bmNhdGVUb0N1cnJlbnRQb3NpdGlvbi5jYWxsKHRoaXMpO1xuICAgIHRoaXMuYWN0aW9ucy5wdXNoKGNvbW1hbmQpO1xuXG4gICAgaWYgKHRoaXMuYWN0aW9ucy5sZW5ndGggPiB0aGlzLl9tYXhMZW5ndGgpIHtcbiAgICAgICAgdmFyIGFjdCA9IHRoaXMuYWN0aW9ucy5zaGlmdCgpO1xuICAgICAgICBhY3QuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIHRoaXMucG9zaXRpb24gPSB0aGlzLmFjdGlvbnMubGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uIC0gMVxufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JGRlbGV0ZUxhc3QoKSB7XG4gICAgaWYgKCF0aGlzLmFjdGlvbnMubGVuZ3RoKSByZXR1cm47XG4gICAgdGhpcy5wb3NpdGlvbi0tO1xuICAgIHRoaXMuYWN0aW9ucy5sZW5ndGgtLTtcbn1cblxuXG5mdW5jdGlvbiBfdHJ1bmNhdGVUb0N1cnJlbnRQb3NpdGlvbigpIHtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5wb3NpdGlvbjsgaSA8IHRoaXMuYWN0aW9ucy5sZW5ndGg7IGkrKylcbiAgICAgICAgdGhpcy5hY3Rpb25zW2ldLmRlc3Ryb3koKTtcbiAgICB0aGlzLmFjdGlvbnMubGVuZ3RoID0gdGhpcy5wb3NpdGlvbjtcbn1cblxuXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeSR1bmRvKGNiKSB7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gPT0gMCkgcmV0dXJuOyAvLyBub3RoaW5nIHRvIHVuZG9cbiAgICB2YXIgYWN0ID0gdGhpcy5hY3Rpb25zWy0tdGhpcy5wb3NpdGlvbl07XG4gICAgYWN0LnVuZG8oY2IpO1xuICAgIHJldHVybiBhY3Q7XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkcmVkbyhjYikge1xuICAgIGlmICh0aGlzLnBvc2l0aW9uID09IHRoaXMuYWN0aW9ucy5sZW5ndGgpIHJldHVybjsgLy8gbm90aGluZyB0byByZWRvXG4gICAgdmFyIGFjdCA9IHRoaXMuYWN0aW9uc1t0aGlzLnBvc2l0aW9uKytdO1xuICAgIGFjdC5yZWRvKGNiKTtcbiAgICByZXR1cm4gYWN0O1xufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JHVuZG9BbGwoKSB7XG4gICAgd2hpbGUgKHRoaXMucG9zaXRpb24pIHRoaXMudW5kbygpO1xufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JHJlZG9BbGwoKSB7XG4gICAgd2hpbGUgKHRoaXMucG9zaXRpb24gPCB0aGlzLmFjdGlvbnMubGVuZ3RoKSB0aGlzLnJlZG8oKTtcbn1cblxuXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeSR1bmRvQWxsQXN5bmMoY2IpIHtcbiAgICBpZiAodGhpcy5wb3NpdGlvbikge1xuICAgICAgICB0aGlzLnVuZG8oKTtcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb24pXG4gICAgICAgICAgICBfLmRlZmVyTWV0aG9kKHRoaXMsICd1bmRvQWxsQXN5bmMnLCBjYik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGlmIChjYikgXy5kZWZlcihjYik7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JHJlZG9BbGxBc3luYyhjYikge1xuICAgIGlmICh0aGlzLnBvc2l0aW9uIDwgdGhpcy5hY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnJlZG8oKTtcbiAgICAgICAgaWYgKHRoaXMucG9zaXRpb24gPCB0aGlzLmFjdGlvbnMubGVuZ3RoKSBcbiAgICAgICAgICAgIF8uZGVmZXJNZXRob2QodGhpcywgJ3JlZG9BbGxBc3luYycsIGNiKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgaWYgKGNiKSBfLmRlZmVyKGNiKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkZWFjaChmdW5jT3JNZXRob2QsIHRoaXNBcmcpIHtcbiAgICB2YXIgZnVuYyA9IHR5cGVvZiBmdW5jT3JNZXRob2QgPT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICA/IGZ1bmN0aW9uKGFjdCkgeyBhY3RbZnVuY09yTWV0aG9kXSgpOyB9XG4gICAgICAgICAgICAgICAgOiBmdW5jT3JNZXRob2Q7XG5cbiAgICB0aGlzLmFjdGlvbnMuZm9yRWFjaChmdW5jLCB0aGlzQXJnIHx8IHRoaXMpO1xufVxuXG5cbmZ1bmN0aW9uIEFjdGlvbnNIaXN0b3J5JGVhY2hSZXZlcnNlKGZ1bmNPck1ldGhvZCwgdGhpc0FyZykge1xuICAgIHRoaXMuYWN0aW9ucy5yZXZlcnNlKCk7XG4gICAgdGhpcy5lYWNoKGZ1bmNPck1ldGhvZCwgdGhpc0FyZyk7XG4gICAgdGhpcy5hY3Rpb25zLnJldmVyc2UoKTtcbn1cblxuXG5mdW5jdGlvbiBBY3Rpb25zSGlzdG9yeSRnZXRMYXN0QWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uICYmIHRoaXMuYWN0aW9uc1t0aGlzLnBvc2l0aW9uIC0gMV07XG59XG5cblxuZnVuY3Rpb24gQWN0aW9uc0hpc3RvcnkkZ2V0RGVzY3JpcHRpb24oKSB7XG4gICAgdmFyIGFjdGlvbnMgPSB0aGlzLmFjdGlvbnMubWFwKGZ1bmN0aW9uKGFjdCkge1xuICAgICAgICByZXR1cm4gYWN0LmdldERlc2NyaXB0aW9uKCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWN0aW9uczogYWN0aW9ucyxcbiAgICAgICAgcG9zaXRpb246IHRoaXMucG9zaXRpb24sXG4gICAgICAgIGxlbmd0aDogYWN0aW9ucy5sZW5ndGhcbiAgICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3NSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2Fic3RyYWN0L3JlZ2lzdHJ5JylcbiAgICAsIENvbW1hbmQgPSByZXF1aXJlKCcuL2luZGV4Jyk7XG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuY29tcG9uZW50c2BcbiAqIEFuIGluc3RhbmNlIG9mIFtDbGFzc1JlZ2lzdHJ5XSguLi9hYnN0cmFjdC9yZWdpc3RyeS5qcy5odG1sKSBjbGFzcyB0aGF0IGlzIHVzZWQgYnkgbWlsbyB0byByZWdpc3RlciBhbmQgZmluZCBjb21wb25lbnRzLlxuICovXG52YXIgY29tbWFuZHNSZWdpc3RyeSA9IG5ldyBDbGFzc1JlZ2lzdHJ5KENvbW1hbmQpO1xuXG4vLyBhZGQgY29tbW9uIGFuY2VzdG9yIHRvIGFsbCBjb21wb25lbnRzIHRvIHRoZSByZWdpc3RyeS5cbmNvbW1hbmRzUmVnaXN0cnkuYWRkKENvbW1hbmQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbW1hbmRzUmVnaXN0cnk7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2hcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJyk7XG5cblxudmFyIFVORE9fQ09NTUFORCA9ICdfdW5kb0NvbW1hbmQnO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gQ29tbWFuZDtcblxuXG4vKipcbiAqIENvbW1hbmQgY2xhc3MgdG8gaW1wbGVtZW50IFwiY29tbWFuZCBwYXR0ZXJuXCIgLSBwYWNrYWdpbmcgbGwgaW5mb3JtYXRpb24gbmVjZXNzYXJ5IGZvciBkZWxheWVkIG1ldGhvZCBleGVjdXRpb25cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgbWV0aG9kIG5hbWUgb3IgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWRcbiAqIEBwYXJhbSB7TGlzdH0gKmFyZ3VtZW50cyBwYXJhbWV0ZXJzIHRvIGJlIHBhc3NlZCB0byBtZXRob2Qgb3IgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gQ29tbWFuZChmdW5jKSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogQ29tbWFuZCBpbnN0YW5jZSBtZXRob2RzXG4gKiBcbiAqIC0gW2luaXRdKCNDb21tYW5kJGV4ZWN1dGUpIC0gaW5pdGlhbGl6ZSBjb21tYW5kLCBzaG91bGQgYmUgb3ZlcndyaXR0ZW4gYnkgc3ViY2xhc3Nlc1xuICogLSBbZXhlY3V0ZV0oI0NvbW1hbmQkZXhlY3V0ZSkgLSBleGVjdXRlIGNvbW1hbmRcbiAqIC0gW3NldFVuZG9dKCNDb21tYW5kJHNldFVuZG8pIC0gc2V0IHVuZG8gY29tbWFuZCBmb3IgdGhpcyBjb21tYW5kXG4gKiAtIFtnZXRVbmRvXSgjQ29tbWFuZCRnZXRVbmRvKSAtIGdldCB1bmRvIGNvbW1hbmQgb2YgdGhpcyBjb21tYW5kXG4gKiAtIFtzZXRBcmd1bWVudHNdKCNDb21tYW5kJHNldEFyZ3VtZW50cykgLSBzZXQgY29tbWFuZHMgYXJndW1lbnRzXG4gKiAtIFthZGRBcmd1bWVudHNdKCNDb21tYW5kJGFkZEFyZ3VtZW50cykgLSBhZGQgYXJndW1lbnRzIHRvIGNvbW1hbmRcbiAqIC0gW2Rlc3Ryb3ldKCNDb21tYW5kJGRlc3Ryb3kpXG4gKi9cbl8uZXh0ZW5kUHJvdG8oQ29tbWFuZCwge1xuICAgIGluaXQ6IENvbW1hbmQkaW5pdCxcbiAgICBleGVjdXRlOiBDb21tYW5kJGV4ZWN1dGUsXG4gICAgc2V0VW5kbzogQ29tbWFuZCRzZXRVbmRvLFxuICAgIGdldFVuZG86IENvbW1hbmQkZ2V0VW5kbyxcbiAgICB1bmRvOiBDb21tYW5kJHVuZG8sXG4gICAgcmVkbzogQ29tbWFuZCRleGVjdXRlLCAvLyBzYW1lIGZvciBjb21tYW5kLCBkaWZmZXJlbnQgZm9yIHRyYW5zYWN0aW9uXG4gICAgc2V0QXJndW1lbnRzOiBDb21tYW5kJHNldEFyZ3VtZW50cyxcbiAgICBhZGRBcmd1bWVudHM6IENvbW1hbmQkYWRkQXJndW1lbnRzLFxuICAgIGdldEFyZ3VtZW50czogQ29tbWFuZCRnZXRBcmd1bWVudHMsXG4gICAgY2hhbmdlQXJndW1lbnRzOiBDb21tYW5kJGNoYW5nZUFyZ3VtZW50cyxcbiAgICBkZXN0cm95OiBDb21tYW5kJGRlc3Ryb3ksXG5cbiAgICBzZXRDb21tZW50OiBDb21tYW5kJHNldENvbW1lbnQsXG4gICAgZ2V0RGVzY3JpcHRpb246IENvbW1hbmQkZ2V0RGVzY3JpcHRpb25cbn0pO1xuXG5cbi8qKlxuICogQ29tbWFuZCBjbGFzcyBtZXRob2RzXG4gKlxuICogLSBbY3JlYXRlXSgjQ29tbWFuZCQkY3JlYXRlKSAtIGNvbW1hbmRzIGZhY3RvcnlcbiAqL1xuXy5leHRlbmQoQ29tbWFuZCwge1xuICAgIGNyZWF0ZTogQ29tbWFuZCQkY3JlYXRlLFxuICAgIGNyZWF0ZVdpdGhVbmRvOiBDb21tYW5kJCRjcmVhdGVXaXRoVW5kb1xufSk7XG5cblxuZnVuY3Rpb24gQ29tbWFuZCRpbml0KGZ1bmMpIHsgLy8gLCAuLi4gYXJndW1lbnRzXG4gICAgY2hlY2soZnVuYywgTWF0Y2guT3B0aW9uYWwoRnVuY3Rpb24pKTtcbiAgICB0aGlzLmZ1bmMgPSBmdW5jIHx8IGZ1bmN0aW9uKCl7fTtcbiAgICB0aGlzLmFyZ3MgPSBfLnNsaWNlKGFyZ3VtZW50cywgMSk7ICAgIFxufVxuXG5cbi8qKlxuICogRXhlY3V0ZSBjb21tYW5kIG1ha2luZyBjb21tYW5kIG9iamVjdCBhdmFpbGFibGUgdmlhIGZ1bmN0aW9uIHByb3BlcnR5LiBcbiAqL1xuZnVuY3Rpb24gQ29tbWFuZCRleGVjdXRlKGNiKSB7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuZnVuYy5hcHBseSh0aGlzLCB0aGlzLmFyZ3MpO1xuICAgIGlmIChjYikgXy5kZWZlcihjYik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG4vKipcbiAqIFNldCB1bmRvIGNvbW1hbmQgZm9yIHRoaXMgY29tbWFuZC4gVGhpcyBjb21tYW5kIGJlY29tZXMgdW5kbyBjb21tYW5kIGZvciB1bmRvIGNvbW1hbmQgKHNvIHVuZG8gY29tbWFuZCBjYW4gY2hhbmdlIHRoaXMgY29tbWFuZCBkdXJpbmcgaXRzIGV4ZWN1dGlvbikuXG4gKiBcbiAqIEBwYXJhbSB7Q29tbWFuZH0gdW5kb0NvbW1hbmRcbiAqL1xuZnVuY3Rpb24gQ29tbWFuZCRzZXRVbmRvKHVuZG9Db21tYW5kKSB7XG4gICAgaWYgKHRoaXNbVU5ET19DT01NQU5EXSlcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0NvbW1hbmQgc2V0VW5kbzogdW5kbyBjb21tYW5kIGlzIGFscmVhZHkgc2V0Jyk7XG5cbiAgICB0aGlzW1VORE9fQ09NTUFORF0gPSB1bmRvQ29tbWFuZDtcbiAgICB1bmRvQ29tbWFuZFtVTkRPX0NPTU1BTkRdID0gdGhpcztcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdW5kbyBjb21tYW5kIG9mIGEgZ2l2ZW4gY29tbWFuZFxuICpcbiAqIEByZXR1cm4ge0NvbW1hbmR9XG4gKi9cbmZ1bmN0aW9uIENvbW1hbmQkZ2V0VW5kbygpIHtcbiAgICByZXR1cm4gdGhpc1tVTkRPX0NPTU1BTkRdO1xufVxuXG5cbi8qKlxuICogRXhlY3V0ZXMgdW5kbyBjb21tYW5kIG9mIGN1cnJlbnQgY29tbWFuZFxuICovXG5mdW5jdGlvbiBDb21tYW5kJHVuZG8oY2IpIHtcbiAgICB2YXIgdW5kb0NtZCA9IHRoaXMuZ2V0VW5kbygpO1xuICAgIGlmICghIHVuZG9DbWQpIHJldHVybiBsb2dnZXIuZXJyb3IoJ0NvbW1hbmQgdW5kbyBjYWxsZWQgd2l0aG91dCB1bmRvIGNvbW1hbmQgcHJlc2VudCcpO1xuICAgIHZhciByZXN1bHQgPSB1bmRvQ21kLmV4ZWN1dGUoKTtcbiAgICBpZiAoY2IpIF8uZGVmZXIoY2IpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cblxuLyoqXG4gKiBTZXQgY29tbWFuZCdzIGFyZ3VtZW50cy4gSWYgYXJndW1lbnRzIHdlcmUgc2V0IGR1cmluZyBjb21tYW5kJ3MgY3JlYXRpb24sIHRoaXMgbWV0aG9kIHdpbGwgb3ZlcndyaXRlIGFyZ3VtZW50cyBhbmQgbG9nIHdhcm5pbmcuXG4gKlxuICogQHBhcmFtIHtMaXN0fSAqYXJndW1lbnRzXG4gKi9cbmZ1bmN0aW9uIENvbW1hbmQkc2V0QXJndW1lbnRzKCkgeyAvLywgLi4uIGFyZ3VtZW50c1xuICAgIGlmICh0aGlzLmFyZ3MgJiYgdGhpcy5hcmdzLmxlbmd0aClcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0NvbW1hbmQgc2V0QXJndW1lbnRzOiBjb21tYW5kIGFyZ3VtZW50cyBhcmUgYWxyZWFkeSBzZXQnKTtcbiAgICB0aGlzLmFyZ3MgPSBfLnRvQXJyYXkoYXJndW1lbnRzKTtcbn1cblxuXG5mdW5jdGlvbiBDb21tYW5kJGdldEFyZ3VtZW50cygpIHtcbiAgICByZXR1cm4gdGhpcy5hcmdzO1xufVxuXG5cbmZ1bmN0aW9uIENvbW1hbmQkY2hhbmdlQXJndW1lbnRzKCkgeyAvLywgLi4uIGFyZ3VtZW50c1xuICAgIHRoaXMuYXJncyA9IF8udG9BcnJheShhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogQWRkIChhcHBlbmQpIGFyZ3VtZW50cyB0byBjb21tYW5kXG4gKlxuICogQHBhcmFtIHtMaXN0fSAqYXJndW1lbnRzIGFyZ3VtZW50cyBsaXN0IHRvIGJlIGFwcGVuZGVkIHRvIGNvbW1hbmRcbiAqL1xuZnVuY3Rpb24gQ29tbWFuZCRhZGRBcmd1bWVudHMoKSB7IC8vLCAuLi4gYXJndW1lbnRzXG4gICAgaWYgKCEgdGhpcy5hcmdzKSB0aGlzLmFyZ3MgPSBbXTtcbiAgICBfLmFwcGVuZEFycmF5KHRoaXMuYXJncywgYXJndW1lbnRzKTtcbn1cblxuXG4vKipcbiAqIENvbW1hbmRzIGZhY3RvcnkuIExpa2VseSBvdCBiZSBvdmVycmlkZGVuIGJ5IHN1YmNsYXNzZXMgdG8gaW1wbGVtZW50IGN1c3RvbSBsb2dpYyBvZiBjb21tYW5kIGNvbnN0cnVjdGlvblxuICogXG4gKiBAdGhpcyB7RnVuY3Rpb259IENsYXNzIG9mIGNvbW1hbmRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgbWV0aG9kIG5hbWUgb3IgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWRcbiAqIEBwYXJhbSB7TGlzdH0gKmFyZ3VtZW50cyBwYXJhbWV0ZXJzIHRvIGJlIHBhc3NlZCB0byBtZXRob2Qgb3IgZnVuY3Rpb25cbiAqIEByZXR1cm4ge0NvbW1hbmR9XG4gKi9cbmZ1bmN0aW9uIENvbW1hbmQkJGNyZWF0ZShmdW5jKSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHJldHVybiBfLm5ld0FwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gQ29tbWFuZCQkY3JlYXRlV2l0aFVuZG8oKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVXaXRoVW5kbyBzaG91bGQgYmUgaW1wbGVtZW50ZWQgYnkgc3Vic2NsYXNzJyk7XG59XG5cblxuLyoqXG4gKiBEZXN0cm95IGN1cnJlbnQgY29tbWFuZCAodG8gcHJldmVudCBwb3RlbnRpYWwgbWVtb3J5IGxlYWtzIHdoZW4gY29tbWFuZHMgcG9pbnQgdG8gRE9NIGVsZW1lbnRzKVxuICovXG5mdW5jdGlvbiBDb21tYW5kJGRlc3Ryb3koKSB7XG4gICAgZGVsZXRlIHRoaXMuZnVuYztcbiAgICBkZWxldGUgdGhpcy5hcmdzO1xuICAgIHZhciB1bmRvQ21kID0gdGhpc1tVTkRPX0NPTU1BTkRdO1xuICAgIGlmICh1bmRvQ21kKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzW1VORE9fQ09NTUFORF1bVU5ET19DT01NQU5EXTtcbiAgICAgICAgZGVsZXRlIHRoaXNbVU5ET19DT01NQU5EXTtcbiAgICAgICAgdW5kb0NtZC5kZXN0cm95KCk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIENvbW1hbmQkc2V0Q29tbWVudChjb21tZW50KSB7XG4gICAgdGhpcy5jb21tZW50ID0gY29tbWVudDtcbn1cblxuXG5mdW5jdGlvbiBDb21tYW5kJGdldERlc2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGZ1bmM6IHRoaXMuZnVuYy5uYW1lLFxuICAgICAgICBjb21tZW50OiB0aGlzLmNvbW1lbnRcbiAgICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBBY3Rpb25zSGlzdG9yeSA9IHJlcXVpcmUoJy4vYWN0aW9uc19oaXN0b3J5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zYWN0aW9uO1xuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uKCkge1xuICAgIHRoaXMuY29tbWFuZHMgPSBuZXcgQWN0aW9uc0hpc3Rvcnk7XG59XG5cblxuXy5leHRlbmRQcm90byhUcmFuc2FjdGlvbiwge1xuICAgIGV4ZWN1dGU6IFRyYW5zYWN0aW9uJGV4ZWN1dGUsXG4gICAgdW5kbzogVHJhbnNhY3Rpb24kdW5kbyxcbiAgICByZWRvOiBUcmFuc2FjdGlvbiRyZWRvLFxuICAgIGRlc3Ryb3k6IFRyYW5zYWN0aW9uJGRlc3Ryb3ksXG4gICAgc3RvcmVDb21tYW5kOiBUcmFuc2FjdGlvbiRzdG9yZUNvbW1hbmQsXG4gICAgbWVyZ2U6IFRyYW5zYWN0aW9uJG1lcmdlLFxuXG4gICAgc2V0Q29tbWVudDogVHJhbnNhY3Rpb24kc2V0Q29tbWVudCxcbiAgICBnZXREZXNjcmlwdGlvbjogVHJhbnNhY3Rpb24kZ2V0RGVzY3JpcHRpb25cbn0pO1xuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uJGV4ZWN1dGUoKSB7XG4gICAgdGhpcy5jb21tYW5kcy5lYWNoKCdleGVjdXRlJyk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24kdW5kbyhjYikge1xuICAgIHRoaXMuY29tbWFuZHMudW5kb0FsbEFzeW5jKGNiKTtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbiRyZWRvKGNiKSB7XG4gICAgdGhpcy5jb21tYW5kcy5yZWRvQWxsQXN5bmMoY2IpO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uJGRlc3Ryb3koKSB7XG4gICAgdGhpcy5jb21tYW5kcy5lYWNoKCdkZXN0cm95Jyk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb24kc3RvcmVDb21tYW5kKGNvbW1hbmQpIHtcbiAgICB0aGlzLmNvbW1hbmRzLnN0b3JlKGNvbW1hbmQpO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uJG1lcmdlKHRyYW5zYWN0aW9uKSB7XG4gICAgdHJhbnNhY3Rpb24uY29tbWFuZHMuZWFjaChmdW5jdGlvbihjbWQpIHtcbiAgICAgICAgdGhpcy5jb21tYW5kcy5zdG9yZShjbWQpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uJHNldENvbW1lbnQoY29tbWVudCkge1xuICAgIHRoaXMuY29tbWVudCA9IGNvbW1lbnRcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbiRnZXREZXNjcmlwdGlvbigpIHtcbiAgICB2YXIgY29tbWFuZHMgPSB0aGlzLmNvbW1hbmRzLmdldERlc2NyaXB0aW9uKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tbWFuZHM6IGNvbW1hbmRzLmFjdGlvbnMsXG4gICAgICAgIGNvbW1lbnQ6IHRoaXMuY29tbWVudFxuICAgIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgQWN0aW9uc0hpc3RvcnkgPSByZXF1aXJlKCcuL2FjdGlvbnNfaGlzdG9yeScpXG4gICAgLCBUcmFuc2FjdGlvbiA9IHJlcXVpcmUoJy4vdHJhbnNhY3Rpb24nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zYWN0aW9uSGlzdG9yeTtcblxuXG52YXIgU0NIRURVTEVEID0gJ19zY2hlZHVsZWQnO1xuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeShtYXhMZW5ndGgpIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9ucyA9IG5ldyBBY3Rpb25zSGlzdG9yeShtYXhMZW5ndGgpO1xuICAgIHRoaXMuY3VycmVudEJhdGNoID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXNbU0NIRURVTEVEXSA9IGZhbHNlO1xufVxuXG5cbl8uZXh0ZW5kUHJvdG8oVHJhbnNhY3Rpb25IaXN0b3J5LCB7XG4gICAgc3RvcmVDb21tYW5kOiBUcmFuc2FjdGlvbkhpc3Rvcnkkc3RvcmVDb21tYW5kLFxuICAgIGVuZFRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbkhpc3RvcnkkZW5kVHJhbnNhY3Rpb24sXG4gICAgc3RvcmVUcmFuc2FjdGlvbjogVHJhbnNhY3Rpb25IaXN0b3J5JHN0b3JlVHJhbnNhY3Rpb24sXG4gICAgZGVsZXRlTGFzdFRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbkhpc3RvcnkkZGVsZXRlTGFzdFRyYW5zYWN0aW9uLFxuICAgIHVuZG86IFRyYW5zYWN0aW9uSGlzdG9yeSR1bmRvLFxuICAgIHJlZG86IFRyYW5zYWN0aW9uSGlzdG9yeSRyZWRvLFxuICAgIGluVHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uSGlzdG9yeSRpblRyYW5zYWN0aW9uLFxuXG4gICAgZ2V0RGVzY3JpcHRpb246IFRyYW5zYWN0aW9uSGlzdG9yeSRnZXREZXNjcmlwdGlvbixcbiAgICB1c2VNZXNzZW5nZXI6IFRyYW5zYWN0aW9uSGlzdG9yeSR1c2VNZXNzZW5nZXIsXG4gICAgZGVzdHJveTogVHJhbnNhY3Rpb25IaXN0b3J5JGRlc3Ryb3lcbn0pO1xuXG5cbi8qKlxuICogU3RvcmVzIGNvbW1hbmQgaW4gdGhlIGhpc3RvcnkuIFxuICogQHBhcmFtIHtDb21tYW5kfSBjb21tYW5kICAgICAgICAgICBcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gYXBwZW5kVHJhbnNhY3Rpb24gSWYgYHRydWVgLCBhcHBlbmRzIHRvIHRoZSBjdXJyZW50IG9yIHByZXZpb3VzIHRyYW5zYWN0aW9uIGlmIHRoZXJlIGlzIG5vIGN1cnJlbnQgdHJhbnNhY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeSRzdG9yZUNvbW1hbmQoY29tbWFuZCwgYXBwZW5kVHJhbnNhY3Rpb24pIHtcbiAgICBpZiAoYXBwZW5kVHJhbnNhY3Rpb24gJiYgISh0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbiB8fCB0aGlzLmN1cnJlbnRCYXRjaCkpIHtcbiAgICAgICAgdmFyIHRyYW5zYWN0aW9uID0gdGhpcy50cmFuc2FjdGlvbnMuZ2V0TGFzdEFjdGlvbigpO1xuICAgICAgICB0cmFuc2FjdGlvbi5zdG9yZUNvbW1hbmQoY29tbWFuZCk7XG4gICAgICAgIF9wb3N0VHJhbnNhY3Rpb25NZXNzYWdlLmNhbGwodGhpcywgJ2FwcGVuZGVkJywgdHJhbnNhY3Rpb24pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCEgdGhpcy5jdXJyZW50QmF0Y2gpIHRoaXMuY3VycmVudEJhdGNoID0gbmV3IFRyYW5zYWN0aW9uO1xuICAgIHRoaXMuY3VycmVudEJhdGNoLnN0b3JlQ29tbWFuZChjb21tYW5kKTtcbiAgICBpZiAoISB0aGlzW1NDSEVEVUxFRF0pIHtcbiAgICAgICAgdGhpc1tTQ0hFRFVMRURdID0gdHJ1ZTtcbiAgICAgICAgXy5kZWZlck1ldGhvZCh0aGlzLCBfc3RvcmVUcmFuc2FjdGlvbik7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeSRkZWxldGVMYXN0VHJhbnNhY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudEJhdGNoIHx8IHRoaXMuY3VycmVudFRyYW5zYWN0aW9uKSB7XG4gICAgICAgIHRoaXMuY3VycmVudEJhdGNoID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9ucy5kZWxldGVMYXN0KCk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9zdG9yZVRyYW5zYWN0aW9uKCkge1xuICAgIGlmICh0aGlzLmN1cnJlbnRCYXRjaCkge1xuICAgICAgICBfYWRkQmF0Y2hUb1RyYW5zYWN0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgIF8uZGVmZXJNZXRob2QodGhpcywgX3N0b3JlVHJhbnNhY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIF9zdG9yZUN1cnJlbnRUcmFuc2FjdGlvbi5jYWxsKHRoaXMpO1xuICAgICAgICB0aGlzW1NDSEVEVUxFRF0gPSBmYWxzZTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JGVuZFRyYW5zYWN0aW9uKCkge1xuICAgIF9hZGRCYXRjaFRvVHJhbnNhY3Rpb24uY2FsbCh0aGlzKTtcbiAgICBfc3RvcmVDdXJyZW50VHJhbnNhY3Rpb24uY2FsbCh0aGlzKTtcbn1cblxuXG5mdW5jdGlvbiBfYWRkQmF0Y2hUb1RyYW5zYWN0aW9uKCkge1xuICAgIGlmICh0aGlzLmN1cnJlbnRCYXRjaCkge1xuICAgICAgICBpZiAoISB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbikgdGhpcy5jdXJyZW50VHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb247XG4gICAgICAgIHRoaXMuY3VycmVudFRyYW5zYWN0aW9uLm1lcmdlKHRoaXMuY3VycmVudEJhdGNoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50QmF0Y2ggPSB1bmRlZmluZWQ7XG4gICAgfSBcbn1cblxuXG5mdW5jdGlvbiBfc3RvcmVDdXJyZW50VHJhbnNhY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudFRyYW5zYWN0aW9uKSB7XG4gICAgICAgIHZhciB0ID0gdGhpcy5jdXJyZW50VHJhbnNhY3Rpb247XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb25zLnN0b3JlKHQpO1xuICAgICAgICBfcG9zdFRyYW5zYWN0aW9uTWVzc2FnZS5jYWxsKHRoaXMsICdzdG9yZWQnLCB0KTtcblxuICAgICAgICB0aGlzLmN1cnJlbnRUcmFuc2FjdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JHN0b3JlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pIHtcbiAgICB0aGlzLmVuZFRyYW5zYWN0aW9uKCk7XG5cbiAgICB0aGlzLnRyYW5zYWN0aW9ucy5zdG9yZSh0cmFuc2FjdGlvbik7XG4gICAgX3Bvc3RUcmFuc2FjdGlvbk1lc3NhZ2UuY2FsbCh0aGlzLCAnc3RvcmVkJywgdHJhbnNhY3Rpb24pO1xufVxuXG5cbmZ1bmN0aW9uIF9wb3N0VHJhbnNhY3Rpb25NZXNzYWdlKG1zZywgdHJhbnNhY3Rpb24pIHtcbiAgICBpZiAodGhpcy5fbWVzc2VuZ2VyKVxuICAgICAgICB0aGlzLl9tZXNzZW5nZXIucG9zdE1lc3NhZ2UobXNnLCB7IHRyYW5zYWN0aW9uOiB0cmFuc2FjdGlvbiB9KTtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbkhpc3RvcnkkdW5kbyhjYikge1xuICAgIHZhciB0ID0gdGhpcy50cmFuc2FjdGlvbnMudW5kbyhjYik7XG4gICAgaWYgKHQpIF9wb3N0VHJhbnNhY3Rpb25NZXNzYWdlLmNhbGwodGhpcywgJ3VuZG9uZScsIHQpO1xuICAgIHJldHVybiB0O1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeSRyZWRvKGNiKSB7XG4gICAgdmFyIHQgPSB0aGlzLnRyYW5zYWN0aW9ucy5yZWRvKGNiKTtcbiAgICBpZiAodCkgX3Bvc3RUcmFuc2FjdGlvbk1lc3NhZ2UuY2FsbCh0aGlzLCAncmVkb25lJywgdCk7XG4gICAgcmV0dXJuIHQ7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JGluVHJhbnNhY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXNbU0NIRURVTEVEXTtcbn1cblxuXG5mdW5jdGlvbiBUcmFuc2FjdGlvbkhpc3RvcnkkZ2V0RGVzY3JpcHRpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb25zLmdldERlc2NyaXB0aW9uKCk7XG59XG5cblxuZnVuY3Rpb24gVHJhbnNhY3Rpb25IaXN0b3J5JHVzZU1lc3NlbmdlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fbWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMpO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zYWN0aW9uSGlzdG9yeSRkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9tZXNzZW5nZXIpIHRoaXMuX21lc3Nlbmdlci5kZXN0cm95KCk7XG4gICAgZGVsZXRlIHRoaXMudHJhbnNhY3Rpb25zO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBGYWNldGVkT2JqZWN0ID0gcmVxdWlyZSgnLi4vYWJzdHJhY3QvZmFjZXRlZF9vYmplY3QnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5JylcbiAgICAsIENvbXBvbmVudEZhY2V0ID0gZmFjZXRzUmVnaXN0cnkuZ2V0KCdDb21wb25lbnRGYWNldCcpXG4gICAgLCBjb21wb25lbnRVdGlscyA9IHJlcXVpcmUoJy4vY191dGlscycpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIG1pbG9Db21wb25lbnROYW1lID0gcmVxdWlyZSgnLi4vdXRpbC9jb21wb25lbnRfbmFtZScpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpXG4gICAgLCBkb21VdGlscyA9IHJlcXVpcmUoJy4uL3V0aWwvZG9tJylcbiAgICAsIENvbXBvbmVudEVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLkNvbXBvbmVudFxuICAgICwgQmluZEF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4uL2F0dHJpYnV0ZXMvYV9iaW5kJylcbiAgICAsIFNjb3BlID0gcmVxdWlyZSgnLi9zY29wZScpXG4gICAgLCBET01TdG9yYWdlID0gcmVxdWlyZSgnLi4vdXRpbC9zdG9yYWdlJylcbiAgICAsIGpzb25QYXJzZSA9IHJlcXVpcmUoJy4uL3V0aWwvanNvbl9wYXJzZScpO1xuXG52YXIgX21ha2VDb21wb25lbnRDb25kaXRpb25GdW5jID0gY29tcG9uZW50VXRpbHMuX21ha2VDb21wb25lbnRDb25kaXRpb25GdW5jO1xuXG5cbi8qKlxuICogYG1pbG8uQ29tcG9uZW50YFxuICogQmFzZSBDb21wb25lbnQgY2xhc3MuIFN1YmNsYXNzIG9mIFtGYWNldGVkT2JqZWN0XSguLi9hYnN0cmFjdC9mYWNldGVkX29iamVjdC5qcy5odG1sKSwgYnV0IG5vbmUgb2YgdGhpcyBjbGFzcyBtZXRob2RzIHNob3VsZCBiZSBkaXJlY3RseSB1c2VkIHdpdGggY29tcG9uZW50LlxuICogSXRzIGNvbnN0cnVjdG9yIHBhc3NlcyBpdHMgcGFyYW1ldGVycywgaW5jbHVkaW5nIGl0cyBbc2NvcGVdKC4vc2NvcGUuanMuaHRtbCksIERPTSBlbGVtZW50IGFuZCBuYW1lIHRvIFtgaW5pdGBdKCNpbml0KSBtZXRob2QuXG4gKiBUaGUgY29uc3RydWN0b3Igb2YgQ29tcG9uZW50IGNsYXNzIHJhcmVseSBuZWVkcyB0byBiZSB1c2VkIGRpcmVjdGx5LCBhcyBbbWlsby5iaW5kZXJdKC4uL2JpbmRlci5qcy5odG1sKSBjcmVhdGVzIGNvbXBvbmVudHMgd2hlbiBpdCBzY2FucyBET00gdHJlZS5cbiAqIFtgQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzYF0oI2NyZWF0ZUNvbXBvbmVudENsYXNzKSBzaG91bGQgYmUgdXNlZCB0byBjcmVhdGUgYSBzdWJjbGFzcyBvZiBDb21wb25lbnQgY2xhc3Mgd2l0aCBjb25maWd1cmVkIGZhY2V0cy5cbiAqXG4gKlxuICogIyMjI0NvbXBvbmVudCBpbnN0YW5jZSBwcm9wZXJ0aWVzIyMjI1xuICpcbiAqIC0gZWwgLSBET00gZWxlbWVudCB0aGF0IGNvbXBvbmVudCBpcyBhdHRhY2hlZCB0by4gSWYgdGhlIHNlY29uZCBjb21wb25lbnQgaXMgYXR0YWNoZWQgdG8gdGhlIHNhbWUgRE9NIGVsZW1lbnQsIHRoZSB3YXJuaW5nIHdpbGwgYmUgbG9nZ2VkIHRvIGNvbnNvbGUuIFRvIGdldCBjb21wb25lbnQgcmVmZXJlbmNlIGZyb20gRE9NIGVsZW1lbnQgdXNlIFtDb21wb25lbnQuZ2V0Q29tcG9uZW50XSguL2NfdXRpbHMuanMuaHRtbCNnZXRDb21wb25lbnQpIGNsYXNzIG1ldGhvZC4gVG8gaW5zcGVjdCBjb21wb25lbnQgdmlhIGVsZW1lbnQgaW4gYnJvd3NlciBjaGVjayBgX19fbWlsb19jb21wb25lbnRgIHByb3BlcnR5IG9mIGVsZW1lbnQgKHByb3BlcnR5IG5hbWUgYmUgY2hhbmdlZCB1c2luZyBgbWlsby5jb25maWdgKS5cbiAqIC0gc2NvcGUgLSBwYXJlbnQgc2NvcGUgb2JqZWN0LCBhbiBpbnN0YW5jZSBvZiBbU2NvcGVdKC4vc2NvcGUuanMuaHRtbCkgY2xhc3MuIFRvIGdldCBwYXJlbnQgY29tcG9uZW50IHVzZSBbZ2V0U2NvcGVQYXJlbnRdKCNDb21wb25lbnQkZ2V0U2NvcGVQYXJlbnQpIGluc3RhbmNlIG1ldGhvZCBvZiBjb21wb25lbnQuIFRoZSBhY3R1YWwgcGF0aCB0byBnZXQgcGFyZW50IG9mIGNvbnBvbmVudCBpcyBgY29tcG9uZW50LnNjb3BlLl9ob3N0T2JqZWN0Lm93bmVyYCwgd2hlcmUgYF9ob3N0T2JqZWN0YCByZWZlcnMgdG8gW0NvbnRhaW5lcl0oY19mYWNldHMvQ29udGFpbmVyLmpzLmh0bWwpIGZhY2V0IG9mIHBhcmVudCBjb21wb25lbnQgYW5kIGBvd25lcmAgdG8gdGhlIHBhcmVudCBpdHNlbGYuIFRoZSBjaGlsZHJlbiBvZiBjb21wb25lbnQgYXJlIGFjY2Vzc2libGUgdmlhIHRoZSBzY29wZSBvZiBpdHMgY29udGFpbmVyIGZhY2V0OiBgY29tcG9uZW50LmNvbnRhaW5lci5zY29wZWAuIFRoZSBzY29wZSBoaWVyYXJjaHkgY2FuIGJlIHRoZSBzYW1lIG9yIGRpZmZlcmVudCBhcyB0aGUgRE9NIGhpZXJhcmNoeSAtIERPTSBjaGlsZHJlbiBvZiB0aGUgY29tcG9uZW50IHdpbGwgYmUgb24gdGhlIHNhbWUgc2NvcGUgYXMgY29tcG9uZW50IGlmIGl0IGRvZXMgbm90IGhhdmUgYENvbnRhaW5lcmAgZmFjZXQgYW5kIGluIHRoZSBzY29wZSBvZiBpdHMgQ29udGFpbmVyIGZhY2V0IGlmIGl0IGhhcyBpdC4gU2VlIFtTY29wZV0oLi9zY29wZS5qcy5odG1sKS5cbiAqIC0gbmFtZSAtIHRoZSBuYW1lIG9mIGNvbXBvbmVudCwgc2hvdWxkIGJlIHVuaXF1ZSBmb3IgdGhlIHNjb3BlIHdoZXJlIGNvbXBvbmVudCBiZWxvbmdzLiBUbyBmaW5kIGNvbXBvbmVudCBpbiBzY29wZSB0aGUgY29tcG9uZW50J3MgbmFtZSBzaG91bGQgYmUgdXNlZCBhcyBwcm9wZXJ0eSBvZiBzY29wZSBvYmplY3QuIFNlZSBbU2NvcGVdKC4vc2NvcGUuanMuaHRtbCkuXG4gKiAtIGZhY2V0cyAtIG1hcCBvZiByZWZlcmVuY2VzIG9mIGFsbCBjb21wb25lbnQncyBmYWNldHMgKGZhY2V0IG5hbWVzIGFyZSBsb3dlcmNhc2UgaW4gdGhpcyBtYXApLiBBbGwgZmFjZXRzIGNhbiBiZSBhY2Nlc3NlZCBkaXJlY3RseSBhcyBwcm9wZXJ0aWVzIG9mIGNvbXBvbmVudCwgdGhpcyBwcm9wZXJ0eSBjYW4gYmUgdXNlZCB0byBpdGVyYXRlIGZhY2V0cyAoaXQgaXMgdXNlZCBpbiB0aGlzIHdheSBpbiBbYWxsRmFjZXRzXSgjQ29tcG9uZW50JGFsbEZhY2V0cykgY29tcG9uZW50J3MgaW5zdGFuY2UgbWV0aG9kIHRoYXQgYWxsb3dzIHRvIGNhbGwgbWV0aG9kIHdpdGggdGhlIHNhbWUgbmFtZSBvbiBhbGwgZmFjZXRzKS5cbiAqIC0gZXh0cmFGYWNldHMgLSBhbiBhcnJheSBvZiBuYW1lcyBvZiBmYWNldHMgdGhhdCBhcmUgYWRkZWQgdG8gY29tcG9uZW50IGFuZCBkbyBub3QgZm9ybSB0aGUgcGFydCBvZiBjb21wb25lbnQncyBjbGFzcy5cbiAqIC0gX21lc3NlbmdlciAtIHRoZSByZWZlcmVuY2UgdG8gY29tcG9uZW50J3MgW21lc3Nlbmdlcl0oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpLiBSYXJlbHkgbmVlZHMgdG8gYmUgdXNlZCBkaXJlY3RseSBhcyBhbGwgY29tbW9ubHkgdXNlZCBtZXRob2RzIG9mIG1lc2VuZ2VyIGFyZSBhdmFpbGFibGUgZGlyZWN0bHkgb24gY29tcG9uZW50LlxuICpcbiAqXG4gKiAjIyMjQ29tcG9uZW50IGV2ZW50cyMjIyNcbiAqXG4gKiAtICdjaGlsZHJlbmJvdW5kJyAtIHN5bmNocm9ub3VzbHkgZGlzcGF0Y2hlZCB3aGVuIGNoaWxkcmVuIG9mIERPTSBlbGVtZW50IHdoaWNoIGNvbXBuZW50IGlzIGNvbm5lY3RlZCB0byBhcmUgY29ubmVjdGVkIHRvIGNvbXBvbmVudHMuIFRoZSBldmVudCBpcyBkaXNwYXRjaGVkIHdoZW4gY29tcG9uZW50IGlzIGNyZWF0ZWQgd2l0aCBgbWlsby5iaW5kZXJgIChhcyBpcyBhbG1vc3QgYWx3YXlzIHRoZSBjYXNlLCBhcyBhbGwgQ29tcG9uZW50IGNsYXNzIG1ldGhvZHMgdGhhdCBjcmVhdGUvY29weSBjb21wb25lbnRzIHVzZSBgbWlsby5iaW5kZXJgIGludGVybmFsbHkgLSBjb21wb25lbnQgY29uc3RydWN0b3IgYW5kIENvbXBvbmVudC5jcmVhdGUgbWV0aG9kcyBhcmUgbm90IHVzZWQgaW4gZnJhbWV3b3JrIG91dHNpZGUgb2YgYG1pbG8uYmluZGVyYCBhbmQgcmFyZWx5IGlmIGV2ZXIgbmVlZCB0byBiZSB1c2VkIGluIGFwbGljYXRpb24pLlxuICogLSAnYWRkZWR0b3Njb3BlJyAtIHN5bmNocm9ub3VzbHkgZGlzcGF0Y2hlZCB3aGVuIGNvbXBvbmVudCBpcyBhZGRlZCB0byBzY29wZS5cbiAqIC0gJ3N0YXRlcmVhZHknIC0gYXluY2hyb25vdXNseSBkaXNwYXRjaGVkIHdoZW4gY29tcG9uZW50ICh0b2dldGhlciB3aXRoIGl0cyBzY29wZSBjaGlsZHJlbikgaXMgY3JlYXRlZCB3aXRoIFtDb21wb25lbnQuY3JlYXRlRnJvbVN0YXRlXSgjQ29tcG9uZW50JCRjcmVhdGVGcm9tU3RhdGUpIChvciBgY3JlYXRlRnJvbURhdGFUcmFuc2ZlcmApIG1ldGhvZC4gQ2FuIGJlIGRpc3BhdGNoZWQgYnkgYXBwbGljYXRpb24gaWYgdGhlIGNvbXBvbmVudCdzIHN0YXRlIGlzIHNldCB3aXRoIHNvbWUgb3RoZXIgbWVjaGFuaXNtLiBUaGlzIGV2ZW50IGlzIG5vdCB1c2VkIGluIGBtaWxvYCwgaXQgY2FuIGJlIHVzZWQgaW4gYXBwbGljYXRpb24gaW4gcGFydGljdWxhciBzdWJjbGFzc2VzIG9mIGNvbXBvbmVudC5cbiAqIC0gJ2dldHN0YXRlc3RhcnRlZCcgLSBlbWl0dGVkIHN5bmNocm9ub3VzbHkganVzdCBiZWZvcmUgZ2V0U3RhdGUgZXhlY3V0ZXMgc28gY29tcG9uZW50cyBhbmQgZmFjZXRzIGNhbiBjbGVhbiB1cCB0aGVpciBzdGF0ZSBmb3Igc2VyaWFsaXphdGlvbi4gXG4gKiAtICdnZXRzdGF0ZWNvbXBsZXRlZCcgLSBlbWl0dGVkIGFzeW5jaHJvbm91c2x5IGFmdGVyIGdldFN0YXRlIGV4ZWN1dGVzIHNvIGNvbXBvbmVudHMgYW5kIGZhY2V0cyBjYW4gcmVzdG9yZSB0aGVpciBzdGF0ZSBhZnRlciBzZXJpYWxpemF0aW9uLlxuICpcbiAqXG4gKiAjIyMjQ29tcG9uZW50IFwibGlmZWN5Y2xlXCIjIyMjXG4gKlxuICogMS4gQ29tcG9uZW50IGNvbnN0cnVjdG9yIGlzIGNhbGxlZC4gQ29tcG9uZW50J3MgY29uc3RydWN0b3Igc2ltcGx5IGNhbGxzIGNvbnN0cnVjdG9yIG9mIFtGYWNldGVkT2JqZWN0XSguLi9hYnN0cmFjdC9mYWNldGVkX29iamVjdC5qcy5odG1sKSB0aGF0IGlzIGEgc3VwZXJjbGFzcyBvZiBDb21wb25lbnQuIFN1YmNsYXNzZXMgb2YgQ29tcG9uZW50IHNob3VsZCBub3QgaW1wbGVtZW50IHRoZWlyIG93biBjb25zdHJ1Y3RvciwgdGhleSBjYW4gb3B0aW9uYWxseSBpbXBsZW1lbnQgYGluaXRgIG1ldGhvZCwgYnV0IG1vc3QgY29tcG9uZW50cyBkbyBub3QgbmVlZCB0byBkbyBpdC5cbiAqIDIuIGNvbnN0cnVjdG9ycyBhbmQgYGluaXRgIG1ldGhvZHMgb2YgYWxsIGZhY2V0cyBhcmUgY2FsbGVkIGluIHNlcXVlbmNlLiBTYW1lIGFzIGNvbXBvbmVudHMsIGZhY2V0IGRvIG5vdCBpbXBsZW1lbnQgdGhlaXIgY29uc3RydWN0b3JzLCB0aGV5IGNhbiBvcHRpb25hbGx5IGltcGxlbWVudCBgaW5pdGAgYW5kIGBzdGFydGAgbWV0aG9kcyAoc2VlIGJlbG93KS4gSW5zaWRlIGBpbml0YCBtZXRob2QgdGhlcmUgc2hvdWxkIGJlIG9ubHkgZ2VuZXJhbCBpbml0aWFsaXphdGlvbiBjb2RlIHdpdGhvdXQgYW55IGRlcGVuZGVuY3kgb24gY29tcG9uZW50IGl0c2VsZiAoaXQgaXMgbm90IHJlYWR5IHlldCkgYW5kIG90aGVyIGZhY2V0cyAoYXMgdGhlcmUgaXMgbm8gc3BlY2lmaWMgZmFjZXRzIGNyZWF0aW9uIG9yZGVyKS4gSWYgZmFjZXQgaW1wbGVtZW50cyBgaW5pdGAgbWV0aG9kIGl0IE1VU1QgY2FsbCBpbmhlcml0ZWQgaW5pdCB3aXRoIGBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpYC5cbiAqIDMuIGBpbml0YCBtZXRob2Qgb2YgY29tcG9uZW50IGlzIGNhbGxlZC4gQXQgdGhpcyBwb2ludCBhbGwgZmFjZXRzIGFyZSBjcmVhdGVkIGJ1dCBmYWNldHMgc3RpbGwgY2FuIGJlIG5vdCByZWFkeSBhcyB0aGV5IGNhbiBoYXZlIGluaXRpYWxpemF0aW9uIGNvZGUgaW4gYHN0YXJ0YCBtZXRob2QuIElmIGNvbXBvbmVudCBzdWJjbGFzcyBpbXBsZW1lbnRzIGBpbml0YCBtZXRob2QgaXQgTVVTVCBjYWxsIGluaGVyaXRlZCBtZXRob2Qgd2l0aCBgPFN1cGVyY2xhc3M+LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cylgLCB3aGVyZSA8U3VwZXJjbGFzcz4gaXMgQ29tcG9uZW50IG9yIGFub3RoZXIgc3VwZXJjbGFzcyB0aGUgY29tcG9uZW50IGlzIGEgc3ViY2xhc3Mgb2YuXG4gKiA0LiBgY2hlY2tgIG1ldGhvZCBvZiBhbGwgZmFjZXRzIGlzIGNhbGxlZC4gVGhpcyBtZXRob2QgYWRkcyBmYWNldHMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIGNvbXBvbmVudCBkZWNsYXJhdGlvbiAoYmVpbmcgcGFydCBvZiB0aGUgY2xhc3Mgb3IgZXhwbGljaXRlbHkgbGlzdGVkIGluIGJpbmQgYXR0cmlidXRlKSBidXQgYXJlIHJlcXVpcmVkIGJ5IGZhY2V0cyB0aGF0IHRoZSBjb21wbmVudCBhbHJlYWR5IGhhcy4gU3ViY2xhc3NlcyBvZiBbQ29tcG9uZW50RmFjZXRdKC4vY19mYWNldC5qcy5odG1sKSBkbyBub3QgbmVlZCB0byBpbXBsZW1lbnQgdGhpcyBtZXRob2QuXG4gKiA1LiBgc3RhcnRgIG1ldGhvZCBvZiBhbGwgZmFjZXRzIGlzIGNhbGxlZC4gVGhpcyBtZXRob2QgaXMgdXN1YWxseSBpbXBsZW1lbnRlZCBieSBDb21wb25lbnRGYWNldCBzdWJjbGFzc2VzIGFuZCBpdCBjYW4gaGF2ZSBhbnkgaW5pdGlhbGl6YXRpb24gY29kZSB0aGF0IGRlcGVuZHMgb24gY29tcG9uZW50IG9yIG9uIG90aGVyIGZhY2V0cyB0aGF0IGFyZSB0aGUgZGVwZW5kZW5jaWVzIG9mIGEgZmFjZXQuIEluaGVyaXRlZCBgc3RhcnRgIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIGludCBoZSBzYW1lIHdheSBhcyB3cml0dGVuIGFib3ZlLlxuICogNi4gYHN0YXJ0YCBtZXRob2Qgb2YgY29tcG9uZW50IGlzIGNhbGxlZC4gVGhpcyBjb21wb25lbnQgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzc2VzIGlmIHRoZXkgbmVlZCB0byBoYXZlIHNvbWUgaW5pdGlhbGl6YXRpb24gY29kZSB0aGF0IGRlcGVuZHMgb24gc29tZSBmYWNldHMgYW5kIHJlcXVpcmVzIHRoYXQgdGhlc2UgZmFjZXRzIGFyZSBmdWxseSBpbmlhbGl6ZWQuIE9mdGVuIHN1Y2ggY29kZSBhbHNvIGRlcGVuZHMgb24gY29tcG9uZW50J3Mgc2NvcGUgY2hpbGRyZW4gYXMgd2VsbCBzbyB0aGlzIGNvZGUgc2hvdWxkIGJlIGluc2lkZSBgJ2NoaWxkcmVuYm91bmQnYCBldmVudCBzdWJzY3JpYmVyLlxuICogNy4gJ2FkZGVkdG9zY29wZScgZXZlbnQgaXMgZGlzcGF0Y2hlZCB3aGVuIGNvbXBvbmVudCBpcyBhZGRlZCB0byBpdHMgcGFyZW50J3Mgc2NvcGUgb3IgdG8gdG9wIGxldmVsIHNjb3BlIGNyZWF0ZWQgYnkgYG1pbG8uYmluZGVyYC5cbiAqIDguIGNvbXBvbmVudCdzIGNoaWxkcmVuIGFyZSBjcmVhdGVkIChzdGVwcyAxLTYgYWJvdmUgYXJlIGZvbGxvd2VkIGZvciBlYWNoIGNoaWxkKS5cbiAqIDkuICdjaGlsZHJlbmJvdW5kJyBldmVudCBpcyBkaXNwYXRjaGVkIHdoZW4gYWxsIGNvbXBvbmVudCdzIGNoaWxkcmVuIGFyZSBjcmVhdGVkIGFuZCBhZGRlZCB0byB0aGVpciBzY29wZSAoc2VlIGV2ZW50IGRlc2NyaXB0aW9uIGJlbG93KS5cbiAqIDEwLiAnc3RhdGVyZWFkeScgZXZlbnQgaXMgZGlzcGF0Y2hlZCBmb3IgY29tcG9uZW50IGFuZCBhbGwgaXRzIGNoaWxkcmVuIHdoZW4gY29tcG9uZW50IGlzIGNyZWF0ZSBmcm9tIHN0YXRlIChzZWUgZXZlbnQgZGVzY3JpcHRpb24gYmVsb3cpLlxuICogMTEuIGF0IHRoaXMgcG9pbnQgY29tcG9uZW50IGlzIGluIHRoZSBcImludGVyYWN0aXZlXCIgc3RhdGUgd2hlbiBpdCBhbmQgaXRzIGZhY2V0cyB3aWxsIG9ubHkgcmVzcG9uZCB0byBtZXNzYWdlcy9ldmVudHMgdGhhdCB0aGV5IHN1YnNjcmliZWQgdG8gZHVyaW5nIGluaXRpYWxpemF0aW9uLlxuICpcbiAqXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSBzY29wZSB0byB3aGljaCBjb21wb25lbnQgd2lsbCBiZWxvbmcuIEl0IGlzIHVzdWFsbHkgYSB0b3AgbGV2ZWwgc2NvcGUgb2JqZWN0IHJldHVybmVkIGJ5IGBtaWxvLmJpbmRlcmAgb3IgYHNjb3BlYCBwcm9wZXJ0eSBvZiBDb250YWluZXIgZmFjZXQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgRE9NIGVsZW1lbnQgdGhhdCBjb21wb25lbnQgaXMgYXR0YWNoZWQgdG9cbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIGNvbXBvbmVudCBuYW1lLCBzaG91bGQgYmUgdW5pcXVlIGluIHRoZSBzY29wZSBvZiBjb21wb25lbnRcbiAqIEBwYXJhbSB7Q29tcG9uZW50SW5mb30gY29tcG9uZW50SW5mbyBpbnN0YW5jZSBvZiBDb21wb25lbnRJbmZvIGNsYXNzIHRoYXQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgY29weSBvZiBjb21wb25lbnRcbiAqICBUT0RPIHRyeSByZW1vdmluZyBpdFxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG52YXIgQ29tcG9uZW50ID0gXy5jcmVhdGVTdWJjbGFzcyhGYWNldGVkT2JqZWN0LCAnQ29tcG9uZW50JywgdHJ1ZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50O1xuXG5fcmVnaXN0ZXJXaXRoRG9tU3RvcmFnZSgnQ29tcG9uZW50Jyk7XG5cblxuLyoqXG4gKiAjIyMjQ29tcG9uZW50IGNsYXNzIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbY3JlYXRlQ29tcG9uZW50Q2xhc3NdKCNDb21wb25lbnQkJGNyZWF0ZUNvbXBvbmVudENsYXNzKVxuICogLSBbY3JlYXRlXSgjQ29tcG9uZW50JCRjcmVhdGUpXG4gKiAtIFtjb3B5XSgjQ29tcG9uZW50JCRjb3B5KVxuICogLSBbY3JlYXRlT25FbGVtZW50XSgjQ29tcG9uZW50JCRjcmVhdGVPbkVsZW1lbnQpXG4gKiAtIFtpc0NvbXBvbmVudF0oY191dGlscy5qcy5odG1sI2lzQ29tcG9uZW50KVxuICogLSBbZ2V0Q29tcG9uZW50XShjX3V0aWxzLmpzLmh0bWwjZ2V0Q29tcG9uZW50KVxuICogLSBbZ2V0Q29udGFpbmluZ0NvbXBvbmVudF0oY191dGlscy5qcy5odG1sI2dldENvbnRhaW5pbmdDb21wb25lbnQpXG4gKiAtIFtjcmVhdGVGcm9tU3RhdGVdKCNDb21wb25lbnQkJGNyZWF0ZUZyb21TdGF0ZSlcbiAqIC0gW2NyZWF0ZUZyb21EYXRhVHJhbnNmZXJdKCNDb21wb25lbnQkJGNyZWF0ZUZyb21EYXRhVHJhbnNmZXIpXG4gKi9cbl8uZXh0ZW5kKENvbXBvbmVudCwge1xuICAgIGNyZWF0ZUNvbXBvbmVudENsYXNzOiBDb21wb25lbnQkJGNyZWF0ZUNvbXBvbmVudENsYXNzLFxuICAgIGNyZWF0ZTogQ29tcG9uZW50JCRjcmVhdGUsXG4gICAgY29weTogQ29tcG9uZW50JCRjb3B5LFxuICAgIGNyZWF0ZU9uRWxlbWVudDogQ29tcG9uZW50JCRjcmVhdGVPbkVsZW1lbnQsXG4gICAgaXNDb21wb25lbnQ6IGNvbXBvbmVudFV0aWxzLmlzQ29tcG9uZW50LFxuICAgIGdldENvbXBvbmVudDogY29tcG9uZW50VXRpbHMuZ2V0Q29tcG9uZW50LFxuICAgIGdldENvbnRhaW5pbmdDb21wb25lbnQ6IGNvbXBvbmVudFV0aWxzLmdldENvbnRhaW5pbmdDb21wb25lbnQsXG4gICAgY3JlYXRlRnJvbVN0YXRlOiBDb21wb25lbnQkJGNyZWF0ZUZyb21TdGF0ZSxcbiAgICBjcmVhdGVGcm9tRGF0YVRyYW5zZmVyOiBDb21wb25lbnQkJGNyZWF0ZUZyb21EYXRhVHJhbnNmZXJcbn0pO1xuZGVsZXRlIENvbXBvbmVudC5jcmVhdGVGYWNldGVkQ2xhc3M7XG5cblxuLyoqXG4gKiAjIyMjQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI0NvbXBvbmVudCRpbml0KVxuICogLSBbY3JlYXRlRWxlbWVudF0oI0NvbXBvbmVudCRjcmVhdGVFbGVtZW50KVxuICogLSBbaGFzRmFjZXRdKCNDb21wb25lbnQkaGFzRmFjZXQpXG4gKiAtIFthZGRGYWNldF0oI0NvbXBvbmVudCRhZGRGYWNldClcbiAqIC0gW2FsbEZhY2V0c10oI0NvbXBvbmVudCRhbGxGYWNldHMpXG4gKiAtIFtyZW5hbWVdKCNDb21wb25lbnQkcmVuYW1lKVxuICogLSBbcmVtb3ZlXSgjQ29tcG9uZW50JHJlbW92ZSlcbiAqIC0gW2dldFN0YXRlXSgjQ29tcG9uZW50JGdldFN0YXRlKVxuICogLSBbZ2V0VHJhbnNmZXJTdGF0ZV0oI0NvbXBvbmVudCRnZXRUcmFuc2ZlclN0YXRlKVxuICogLSBbc2V0U3RhdGVdKCNDb21wb25lbnQkc2V0U3RhdGUpXG4gKiAtIFtnZXRTY29wZVBhcmVudF0oI0NvbXBvbmVudCRnZXRTY29wZVBhcmVudClcbiAqIC0gW2dldFRvcFNjb3BlUGFyZW50XSgjQ29tcG9uZW50JGdldFRvcFNjb3BlUGFyZW50KVxuICogLSBbZ2V0U2NvcGVQYXJlbnRXaXRoQ2xhc3NdKCNDb21wb25lbnQkZ2V0U2NvcGVQYXJlbnRXaXRoQ2xhc3MpXG4gKiAtIFtnZXRUb3BTY29wZVBhcmVudFdpdGhDbGFzc10oI0NvbXBvbmVudCRnZXRUb3BTY29wZVBhcmVudFdpdGhDbGFzcylcbiAqIC0gW3dhbGtTY29wZVRyZWVdKCNDb21wb25lbnQkd2Fsa1Njb3BlVHJlZSlcbiAqIC0gW2Jyb2FkY2FzdF0oI0NvbXBvbmVudCRicm9hZGNhc3QpXG4gKiAtIFtkZXN0cm95XSgjQ29tcG9uZW50JGRlc3Ryb3kpXG4gKiAtIFtpc0Rlc3Ryb3llZF0oI0NvbXBvbmVudCRpc0Rlc3Ryb3llZClcbiAqXG4gKlxuICogIyMjIyNbTWVzc2VuZ2VyXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCkgbWV0aG9kcyBhdmFpbGFibGUgb24gY29tcG9uZW50IyMjIyNcbiAqXG4gKiAtIFtvbl0oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwjTWVzc2VuZ2VyJG9uKSAtIHNpbmdsZSBzdWJzY3JpYmVcbiAqIC0gW29mZl0oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwjTWVzc2VuZ2VyJG9mZikgLSBzaW5nbGUgdW5zdWJzY3JpYmVcbiAqIC0gW29uTWVzc2FnZXNdKC4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sI01lc3NlbmdlciRvbk1lc3NhZ2VzKSAtIG11bHRpcGxlIHN1YnNjcmliZVxuICogLSBbb2ZmTWVzc2FnZXNdKC4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sI01lc3NlbmdlciRvZmZNZXNzYWdlcykgLSBtdWx0aXBsZSB1bnN1YnNjcmliZVxuICogLSBbcG9zdE1lc3NhZ2VdKC4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sI01lc3NlbmdlciRwb3N0TWVzc2FnZSkgLSBwb3N0IG1lc3NhZ2Ugb24gY29tcG9uZW50XG4gKiAtIFtnZXRTdWJzY3JpYmVyc10oLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwjTWVzc2VuZ2VyJGdldFN1YnNjcmliZXJzKSAtIGdldCBzdWJzY3JpYmVycyBmb3IgYSBnaXZlbiBtZXNzYWdlXG4gKi9cbl8uZXh0ZW5kUHJvdG8oQ29tcG9uZW50LCB7XG4gICAgaW5pdDogQ29tcG9uZW50JGluaXQsXG4gICAgc3RhcnQ6IENvbXBvbmVudCRzdGFydCxcbiAgICBjcmVhdGVFbGVtZW50OiBDb21wb25lbnQkY3JlYXRlRWxlbWVudCxcbiAgICBoYXNGYWNldDogQ29tcG9uZW50JGhhc0ZhY2V0LFxuICAgIGFkZEZhY2V0OiBDb21wb25lbnQkYWRkRmFjZXQsXG4gICAgYWxsRmFjZXRzOiBDb21wb25lbnQkYWxsRmFjZXRzLFxuICAgIHJlbmFtZTogQ29tcG9uZW50JHJlbmFtZSxcbiAgICByZW1vdmU6IENvbXBvbmVudCRyZW1vdmUsXG4gICAgaW5zZXJ0SW50bzogQ29tcG9uZW50JGluc2VydEludG8sXG5cbiAgICBnZXRTdGF0ZTogQ29tcG9uZW50JGdldFN0YXRlLFxuICAgIGdldFRyYW5zZmVyU3RhdGU6IENvbXBvbmVudCRnZXRUcmFuc2ZlclN0YXRlLFxuICAgIF9nZXRTdGF0ZTogQ29tcG9uZW50JF9nZXRTdGF0ZSxcbiAgICBzZXRTdGF0ZTogQ29tcG9uZW50JHNldFN0YXRlLFxuICAgIFxuICAgIGdldFNjb3BlUGFyZW50OiBDb21wb25lbnQkZ2V0U2NvcGVQYXJlbnQsXG4gICAgZ2V0VG9wU2NvcGVQYXJlbnQ6IENvbXBvbmVudCRnZXRUb3BTY29wZVBhcmVudCxcbiAgICBnZXRTY29wZVBhcmVudFdpdGhDbGFzczogQ29tcG9uZW50JGdldFNjb3BlUGFyZW50V2l0aENsYXNzLFxuICAgIGdldFRvcFNjb3BlUGFyZW50V2l0aENsYXNzOiBDb21wb25lbnQkZ2V0VG9wU2NvcGVQYXJlbnRXaXRoQ2xhc3MsXG5cbiAgICBzZXRTY29wZVBhcmVudEZyb21ET006IENvbXBvbmVudCRzZXRTY29wZVBhcmVudEZyb21ET00sXG5cbiAgICB3YWxrU2NvcGVUcmVlOiBDb21wb25lbnQkd2Fsa1Njb3BlVHJlZSxcblxuICAgIHRyZWVQYXRoT2Y6IENvbXBvbmVudCR0cmVlUGF0aE9mLFxuICAgIGdldENvbXBvbmVudEF0VHJlZVBhdGg6IENvbXBvbmVudCRnZXRDb21wb25lbnRBdFRyZWVQYXRoLFxuICAgIGluc2VydEF0VHJlZVBhdGg6IENvbXBvbmVudCRpbnNlcnRBdFRyZWVQYXRoLFxuXG4gICAgYnJvYWRjYXN0OiBDb21wb25lbnQkYnJvYWRjYXN0LFxuICAgIGRlc3Ryb3k6IENvbXBvbmVudCRkZXN0cm95LFxuICAgIGlzRGVzdHJveWVkOiBDb21wb25lbnQkaXNEZXN0cm95ZWRcbn0pO1xuXG5cbi8qKlxuICogRXhwb3NlIE1lc3NlbmdlciBtZXRob2RzIG9uIENvbXBvbmVudCBwcm90b3R5cGVcbiAqL1xudmFyIE1FU1NFTkdFUl9QUk9QRVJUWSA9ICdfbWVzc2VuZ2VyJztcbk1lc3Nlbmdlci51c2VXaXRoKENvbXBvbmVudCwgTUVTU0VOR0VSX1BST1BFUlRZLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMpO1xuXG5cbnZhciBDT01QT05FTlRfREFUQV9UWVBFX1BSRUZJWCA9ICd4LWFwcGxpY2F0aW9uL21pbG8tY29tcG9uZW50JztcbnZhciBDT01QT05FTlRfREFUQV9UWVBFX1JFR0VYID0gL3gtYXBwbGljYXRpb25cXC9taWxvLWNvbXBvbmVudFxcLyhbYS16XyRdWzAtOWEtel8kXSopKD86XFwvKCkpL2k7XG5cbi8qKlxuICogQ29tcG9uZW50IGNsYXNzIG1ldGhvZFxuICogQ3JlYXRlcyBhIHN1YmNsYXNzIG9mIGNvbXBvbmVudCBmcm9tIHRoZSBtYXAgb2YgY29uZmlndXJlZCBmYWNldHMuXG4gKiBUaGlzIG1ldGhvZCB3cmFwcyBhbmQgcmVwbGFjZXMgW2BjcmVhdGVGYWNldGVkQ2xhc3NgXSguLi9hYnN0cmFjdC9mYWNldGVkX29iamVjdC5qcy5odG1sI2NyZWF0ZUZhY2V0ZWRDbGFzcykgY2xhc3MgbWV0aG9kIG9mIEZhY2V0ZWRPYmplY3QuXG4gKiBVbmxpa2UgY3JlYXRlRmFjZXRlZENsYXNzLCB0aGlzIG1ldGhvZCB0YWtlIGZhY2V0IGNsYXNzZXMgZnJvbSByZWdpc3RyeSBieSB0aGVpciBuYW1lLCBzbyBvbmx5IG1hcCBvZiBmYWNldHMgY29uZmlndXJhdGlvbiBuZWVkcyB0byBiZSBwYXNzZWQuIEFsbCBmYWNldHMgY2xhc3NlcyBzaG91bGQgYmUgc3ViY2xhc3NlcyBvZiBbQ29tcG9uZW50RmFjZXRdKC4vY19mYWNldC5qcy5odG1sKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIGNsYXNzIG5hbWVcbiAqIEBwYXJhbSB7T2JqZWN0W09iamVjdF0gfCBBcnJheVtTdHJpbmddfSBmYWNldHNDb25maWcgbWFwIG9mIGZhY2V0cyBjb25maWd1cmF0aW9uLlxuICogIElmIHNvbWUgZmFjZXQgZG9lcyBub3QgcmVxdWlyZSBjb25maWd1cmF0aW9uLCBgdW5kZWZpbmVkYCBzaG91bGQgYmUgcGFzc2VkIGFzIHRoZSBjb25maWd1cmF0aW9uIGZvciB0aGUgZmFjZXQuXG4gKiAgSWYgbm8gZmFjZXQgcmVxdWlyZXMgY29uZmlndXJhdGlvbiwgdGhlIGFycmF5IG9mIGZhY2V0cyBuYW1lcyBjYW4gYmUgcGFzc2VkLlxuICogQHJldHVybiB7U3ViY2xhc3MoQ29tcG9uZW50KX1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JCRjcmVhdGVDb21wb25lbnRDbGFzcyhuYW1lLCBmYWNldHNDb25maWcpIHtcbiAgICAvLyBjb252ZXJ0IGFycmF5IG9mIGZhY2V0IG5hbWVzIHRvIG1hcCBvZiBlbXB0eSBmYWNldHMgY29uZmlndXJhdGlvbnNcbiAgICBpZiAoQXJyYXkuaXNBcnJheShmYWNldHNDb25maWcpKSB7XG4gICAgICAgIHZhciBjb25maWdNYXAgPSB7fTtcbiAgICAgICAgZmFjZXRzQ29uZmlnLmZvckVhY2goZnVuY3Rpb24oZmN0KSB7XG4gICAgICAgICAgICB2YXIgZmN0TmFtZSA9IF8uZmlyc3RMb3dlckNhc2UoZmN0KTtcbiAgICAgICAgICAgIGNvbmZpZ01hcFtmY3ROYW1lXSA9IHt9O1xuICAgICAgICB9KTtcbiAgICAgICAgZmFjZXRzQ29uZmlnID0gY29uZmlnTWFwO1xuICAgIH1cblxuICAgIC8vIGNvbnN0cnVjdCBtYXAgb2YgZmFjZXRzIGNsYXNzZXMgZnJvbSBmYWNldFJlZ2lzdHJ5XG4gICAgdmFyIGZhY2V0c0NsYXNzZXM7XG4gICAgaWYgKHR5cGVvZiBmYWNldHNDb25maWcgPT0gJ29iamVjdCcgJiYgXy5rZXlzKGZhY2V0c0NvbmZpZykubGVuZ3RoKSB7XG4gICAgICAgIGZhY2V0c0NsYXNzZXMgPSB7fTtcbiAgICAgICAgXy5lYWNoS2V5KGZhY2V0c0NvbmZpZywgZnVuY3Rpb24oZmN0Q29uZmlnLCBmY3QpIHtcbiAgICAgICAgICAgIHZhciBmY3ROYW1lID0gXy5maXJzdExvd2VyQ2FzZShmY3QpO1xuICAgICAgICAgICAgdmFyIGZjdENsYXNzTmFtZSA9IF8uZmlyc3RVcHBlckNhc2UoZmN0KTtcbiAgICAgICAgICAgIGZhY2V0c0NsYXNzZXNbZmN0TmFtZV0gPSBmYWNldHNSZWdpc3RyeS5nZXQoZmN0Q2xhc3NOYW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIHN1YmNsYXNzIG9mIENvbXBvbmVudCB1c2luZyBtZXRob2Qgb2YgRmFjZXRlZE9iamVjdFxuICAgIHZhciBDb21wb25lbnRDbGFzcyA9IEZhY2V0ZWRPYmplY3QuY3JlYXRlRmFjZXRlZENsYXNzLmNhbGwodGhpcywgbmFtZSwgZmFjZXRzQ2xhc3NlcywgZmFjZXRzQ29uZmlnKTtcbiAgICBcbiAgICBfcmVnaXN0ZXJXaXRoRG9tU3RvcmFnZShuYW1lKTtcblxuICAgIHJldHVybiBDb21wb25lbnRDbGFzcztcbn1cblxuXG5mdW5jdGlvbiBfcmVnaXN0ZXJXaXRoRG9tU3RvcmFnZShjbGFzc05hbWUpIHtcbiAgICBET01TdG9yYWdlLnJlZ2lzdGVyRGF0YVR5cGUoY2xhc3NOYW1lLCBDb21wb25lbnRfZG9tU3RvcmFnZVNlcmlhbGl6ZXIsIENvbXBvbmVudF9kb21TdG9yYWdlUGFyc2VyKTtcbn1cblxuXG5mdW5jdGlvbiBDb21wb25lbnRfZG9tU3RvcmFnZVNlcmlhbGl6ZXIoY29tcG9uZW50KSB7XG4gICAgdmFyIHN0YXRlID0gY29tcG9uZW50LmdldFN0YXRlKCk7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHN0YXRlKTsgICBcbn1cblxuXG5mdW5jdGlvbiBDb21wb25lbnRfZG9tU3RvcmFnZVBhcnNlcihjb21wU3RyLCBjb21wQ2xhc3NOYW1lKSB7XG4gICAgdmFyIHN0YXRlID0ganNvblBhcnNlKGNvbXBTdHIpO1xuICAgIGlmIChzdGF0ZSlcbiAgICAgICAgcmV0dXJuIENvbXBvbmVudC5jcmVhdGVGcm9tU3RhdGUoc3RhdGUpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGNsYXNzIG1ldGhvZFxuICogQ3JlYXRlcyBjb21wb25lbnQgZnJvbSBbQ29tcG9uZW50SW5mb10oLi9jX2luZm8uanMuaHRtbCkgKHVzZWQgYnkgW21pbG8uYmluZGVyXSguLi9iaW5kZXIuanMuaHRtbCkgYW5kIHRvIGNvcHkgY29tcG9uZW50KVxuICogQ29tcG9uZW50IG9mIGFueSByZWdpc3RlcmVkIGNsYXNzIChzZWUgW2NvbXBvbmVudHNSZWdpc3RyeV0oLi9jX3JlZ2lzdHJ5LmpzLmh0bWwpKSB3aXRoIGFueSBhZGRpdGlvbmFsIHJlZ2lzdGVyZWQgZmFjZXRzIChzZWUgW2ZhY2V0c1JlZ2lzdHJ5XSguL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5LmpzLmh0bWwpKSBjYW4gYmUgY3JlYXRlZCB1c2luZyB0aGlzIG1ldGhvZC5cbiAqXG4gKiBAcGFyYW0ge0NvbXBvbmVudEluZm99IGluZm9cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gdGhyb3dPbkVycm9ycyBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gZXJyb3JzIHdpbGwgb25seSBiZSBsb2dnZWQgdG8gY29uc29sZS4gVHJ1ZSBieSBkZWZhdWx0LlxuIEAgQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkJGNyZWF0ZShpbmZvLCB0aHJvd09uRXJyb3JzKSB7XG4gICAgdmFyIENvbXBvbmVudENsYXNzID0gaW5mby5Db21wb25lbnRDbGFzcztcblxuICAgIGlmICh0eXBlb2YgQ29tcG9uZW50Q2xhc3MgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgbWVzc2FnZSA9ICdjcmVhdGU6IGNvbXBvbmVudCBjbGFzcyBzaG91bGQgYmUgZnVuY3Rpb24sIFwiJyArIHR5cGVvZiBDb21wb25lbnRDbGFzcyArICdcIiBwYXNzZWQnOyBcbiAgICAgICAgaWYgKHRocm93T25FcnJvcnMgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0NvbXBvbmVudCcsIG1lc3NhZ2UsICc7dXNpbmcgYmFzZSBDb21wb25lbnQgY2xhc3MgaW5zdGVhZCcpO1xuICAgICAgICAgICAgQ29tcG9uZW50Q2xhc3MgPSBDb21wb25lbnQ7XG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IENvbXBvbmVudEVycm9yKG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHZhciBhQ29tcG9uZW50ID0gbmV3IENvbXBvbmVudENsYXNzKGluZm8uc2NvcGUsIGluZm8uZWwsIGluZm8ubmFtZSwgaW5mbyk7XG5cbiAgICBpZiAoaW5mby5leHRyYUZhY2V0c0NsYXNzZXMpXG4gICAgICAgIF8uZWFjaEtleShpbmZvLmV4dHJhRmFjZXRzQ2xhc3NlcywgZnVuY3Rpb24oRmFjZXRDbGFzcykge1xuICAgICAgICAgICAgaWYgKCEgYUNvbXBvbmVudC5oYXNGYWNldChGYWNldENsYXNzKSlcbiAgICAgICAgICAgICAgICBhQ29tcG9uZW50LmFkZEZhY2V0KEZhY2V0Q2xhc3MsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aHJvd09uRXJyb3JzKTtcbiAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gYUNvbXBvbmVudDtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBjbGFzcyBtZXRob2RcbiAqIENyZWF0ZSBhIGNvcHkgb2YgY29tcG9uZW50LCBpbmNsdWRpbmcgYSBjb3B5IG9mIERPTSBlbGVtZW50LiBSZXR1cm5zIGEgY29weSBvZiBgY29tcG9uZW50YCAob2YgdGhlIHNhbWUgY2xhc3MpIHdpdGggbmV3IERPTSBlbGVtZW50IChub3QgaW5zZXJ0ZWQgaW50byBwYWdlKS5cbiAqIENvbXBvbmVudCBpcyBhZGRlZCB0byB0aGUgc2FtZSBzY29wZSBhcyB0aGUgb3JpZ2luYWwgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7Q29tcG9uZW50fSBjb21wb25lbnQgYW4gaW5zdGFuY2Ugb2YgQ29tcG9uZW50IGNsYXNzIG9yIHN1YmNsYXNzXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRlZXBDb3B5IG9wdGlvbmFsIGB0cnVlYCB0byBtYWtlIGRlZXAgY29weSBvZiBET00gZWxlbWVudCwgb3RoZXJ3aXNlIG9ubHkgZWxlbWVudCB3aXRob3V0IGNoaWxkcmVuIGlzIGNvcGllZFxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkJGNvcHkoY29tcG9uZW50LCBkZWVwQ29weSkge1xuICAgIGNoZWNrKGNvbXBvbmVudCwgQ29tcG9uZW50KTtcbiAgICBjaGVjayhkZWVwQ29weSwgTWF0Y2guT3B0aW9uYWwoQm9vbGVhbikpO1xuXG4gICAgaWYgKGRlZXBDb3B5ICYmICFjb21wb25lbnQuY29udGFpbmVyKSBcbiAgICAgICAgdGhyb3cgbmV3IENvbXBvbmVudEVycm9yKCdDYW5ub3QgZGVlcCBjb3B5IGNvbXBvbmVudCB3aXRob3V0IGNvbnRhaW5lciBmYWNldCcpO1xuXG4gICAgLy8gY29weSBET00gZWxlbWVudCwgdXNpbmcgRG9tIGZhY2V0IGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHZhciBuZXdFbCA9IGNvbXBvbmVudC5kb20gXG4gICAgICAgICAgICAgICAgICAgID8gY29tcG9uZW50LmRvbS5jb3B5KGRlZXBDb3B5KVxuICAgICAgICAgICAgICAgICAgICA6IGNvbXBvbmVudC5lbC5jbG9uZU5vZGUoZGVlcENvcHkpO1xuXG4gICAgdmFyIENvbXBvbmVudENsYXNzID0gY29tcG9uZW50LmNvbnN0cnVjdG9yO1xuXG4gICAgLy8gY3JlYXRlIGNvbXBvbmVudCBvZiB0aGUgc2FtZSBjbGFzcyBvbiB0aGUgZWxlbWVudFxuICAgIHZhciBhQ29tcG9uZW50ID0gQ29tcG9uZW50Q2xhc3MuY3JlYXRlT25FbGVtZW50KG5ld0VsLCB1bmRlZmluZWQsIGNvbXBvbmVudC5zY29wZSwgY29tcG9uZW50LmV4dHJhRmFjZXRzKTtcbiAgICB2YXIgc3RhdGUgPSBjb21wb25lbnQuX2dldFN0YXRlKGRlZXBDb3B5IHx8IGZhbHNlKTtcbiAgICBhQ29tcG9uZW50LnNldFN0YXRlKHN0YXRlKTtcbiAgICBfLmRlZmVyTWV0aG9kKGFDb21wb25lbnQsICdicm9hZGNhc3QnLCAnc3RhdGVyZWFkeScpO1xuICAgIHJldHVybiBhQ29tcG9uZW50O1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGNsYXNzIG1ldGhvZFxuICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBjb21wb25lbnQgYXRhY2hlZCB0byBlbGVtZW50LiBBbGwgc3ViY2xhc3NlcyBvZiBjb21wb25lbnQgaW5oZXJpdCB0aGlzIG1ldGhvZC5cbiAqIFJldHVybnMgdGhlIGNvbXBvbmVudCBvZiB0aGUgY2xhc3MgdGhpcyBtZXRob2QgaXMgdXNlZCB3aXRoICh0aGVjb250ZXh0IG9mIHRoZSBtZXRob2QgY2FsbCkuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCBvcHRpb25hbCBlbGVtZW50IHRvIGF0dGFjaCBjb21wb25lbnQgdG8uIElmIGVsZW1lbnQgaXMgbm90IHBhc3NlZCwgaXQgd2lsbCBiZSBjcmVhdGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gaW5uZXJIVE1MIG9wdGlvbmFsIGlubmVyIGh0bWwgdG8gaW5zZXJ0IGluIGVsZW1lbnQgYmVmb3JlIGJpbmRpbmcuXG4gKiBAcGFyYW0ge1Njb3BlfSByb290U2NvcGUgb3B0aW9uYWwgc2NvcGUgdG8gcHV0IGNvbXBvbmVudCBpbi4gSWYgbm90IHBhc3NlZCwgY29tcG9uZW50IHdpbGwgYmUgYXR0YWNoZWQgdG8gdGhlIHNjb3BlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnQuIElmIHN1Y2ggc2NvcGUgZG9lcyBub3QgZXhpc3QsIG5ldyBzY29wZSB3aWxsIGJlIGNyZWF0ZWQuXG4gKiBAcGFyYW0ge0FycmF5W1N0cmluZ119IGV4dHJhRmFjZXRzIGxpc3Qgb2YgZXh0cmEgZmFjZXQgdG8gYWRkIHRvIGNvbXBvbmVudFxuICogQHJldHVybiB7U3ViY2xhc3MoQ29tcG9uZW50KX1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JCRjcmVhdGVPbkVsZW1lbnQoZWwsIGlubmVySFRNTCwgcm9vdFNjb3BlLCBleHRyYUZhY2V0cykge1xuICAgIGNoZWNrKGlubmVySFRNTCwgTWF0Y2guT3B0aW9uYWwoU3RyaW5nKSk7XG4gICAgY2hlY2socm9vdFNjb3BlLCBNYXRjaC5PcHRpb25hbChTY29wZSkpO1xuICAgIGNoZWNrKGV4dHJhRmFjZXRzLCBNYXRjaC5PcHRpb25hbChbU3RyaW5nXSkpO1xuXG4gICAgLy8gXCJ0aGlzXCIgcmVmZXJzIHRvIHRoZSBjbGFzcyBvZiBjb21wb25lbnQgaGVyZSwgYXMgdGhpcyBpcyBhIGNsYXNzIG1ldGhvZFxuICAgIGlmIChlbCAmJiBpbm5lckhUTUwpIGVsLmlubmVySFRNTCA9IGlubmVySFRNTDtcbiAgICBlbCA9IGVsIHx8IF9jcmVhdGVDb21wb25lbnRFbGVtZW50LmNhbGwodGhpcywgaW5uZXJIVE1MKTtcbiAgICByb290U2NvcGUgPSByb290U2NvcGUgfHwgX2ZpbmRPckNyZWF0ZUNvbXBvbmVudFJvb3RTY29wZShlbCk7XG4gICAgdmFyIGFDb21wb25lbnQgPSBfYWRkQXR0cmlidXRlQW5kQmluZENvbXBvbmVudC5jYWxsKHRoaXMsIGVsLCByb290U2NvcGUsIGV4dHJhRmFjZXRzKTtcbiAgICBhQ29tcG9uZW50LmJyb2FkY2FzdCgnc3RhdGVyZWFkeScpO1xuICAgIHJldHVybiBhQ29tcG9uZW50O1xufVxuXG5mdW5jdGlvbiBfY3JlYXRlQ29tcG9uZW50RWxlbWVudChpbm5lckhUTUwpIHtcbiAgICAvLyBcInRoaXNcIiByZWZlcnMgdG8gdGhlIGNsYXNzIG9mIGNvbXBvbmVudCBoZXJlLCBhcyB0aGlzIGlzIGEgY2xhc3MgbWV0aG9kXG4gICAgdmFyIERvbSA9IGZhY2V0c1JlZ2lzdHJ5LmdldCgnRG9tJylcbiAgICAgICAgLCBkb21GYWNldENvbmZpZyA9IHRoaXMuZ2V0RmFjZXRDb25maWcoJ2RvbScpXG4gICAgICAgICwgdGVtcGxhdGVGYWNldENvbmZpZyA9IHRoaXMuZ2V0RmFjZXRDb25maWcoJ3RlbXBsYXRlJylcbiAgICAgICAgLCB0ZW1wbGF0ZSA9IHRlbXBsYXRlRmFjZXRDb25maWcgJiYgdGVtcGxhdGVGYWNldENvbmZpZy50ZW1wbGF0ZTtcblxuICAgIHZhciBlbENvbmZpZyA9IHtcbiAgICAgICAgZG9tQ29uZmlnOiBkb21GYWNldENvbmZpZyxcbiAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlLFxuICAgICAgICBjb250ZW50OiBpbm5lckhUTUxcbiAgICB9O1xuXG4gICAgcmV0dXJuIERvbS5jcmVhdGVFbGVtZW50KGVsQ29uZmlnKTtcbn1cblxuZnVuY3Rpb24gX2ZpbmRPckNyZWF0ZUNvbXBvbmVudFJvb3RTY29wZShlbCkge1xuICAgIHZhciBwYXJlbnQgPSBDb21wb25lbnQuZ2V0Q29udGFpbmluZ0NvbXBvbmVudChlbCwgZmFsc2UsICdDb250YWluZXInKTtcbiAgICByZXR1cm4gcGFyZW50ID8gcGFyZW50LmNvbnRhaW5lci5zY29wZSA6IG5ldyBTY29wZShlbCk7XG59XG5cbmZ1bmN0aW9uIF9hZGRBdHRyaWJ1dGVBbmRCaW5kQ29tcG9uZW50KGVsLCByb290U2NvcGUsIGV4dHJhRmFjZXRzKSB7XG4gICAgLy8gYWRkIGJpbmQgYXR0cmlidXRlIHRvIGVsZW1lbnRcbiAgICB2YXIgYXR0ciA9IG5ldyBCaW5kQXR0cmlidXRlKGVsKTtcbiAgICAvLyBcInRoaXNcIiByZWZlcnMgdG8gdGhlIGNsYXNzIG9mIGNvbXBvbmVudCBoZXJlLCBhcyB0aGlzIGlzIGEgY2xhc3MgbWV0aG9kXG4gICAgYXR0ci5jb21wQ2xhc3MgPSB0aGlzLm5hbWU7XG4gICAgYXR0ci5jb21wRmFjZXRzID0gZXh0cmFGYWNldHM7XG4gICAgYXR0ci5kZWNvcmF0ZSgpO1xuXG4gICAgLy8gc2hvdWxkIGJlIHJlcXVpcmVkIGhlcmUgdG8gcmVzb2x2ZSBjaXJjdWxhciBkZXBlbmRlbmN5XG4gICAgdmFyIG1pbG9CaW5kZXIgPSByZXF1aXJlKCcuLi9iaW5kZXInKTtcbiAgICBtaWxvQmluZGVyKGVsLCByb290U2NvcGUpO1xuXG4gICAgcmV0dXJuIHJvb3RTY29wZVthdHRyLmNvbXBOYW1lXTtcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgY2xhc3MgbWV0aG9kXG4gKiBDcmVhdGVzIGNvbXBvbmVudCBmcm9tIGNvbXBvbmVudCBzdGF0ZSwgdGhhdCBpbmNsdWRlcyBpbmZvcm1hdGlvbiBhYm91dCBpdHMgY2xhc3MsIGV4dHJhIGZhY2V0cywgZmFjZXRzIGRhdGEgYW5kIGFsbCBzY29wZSBjaGlsZHJlbi5cbiAqIFRoaXMgaXMgdXNlZCB0byBzYXZlL2xvYWQsIGNvcHkvcGFzdGUgYW5kIGRyYWcvZHJvcCBjb21wb25lbnRcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgc3RhdGUgZnJvbSB3aGljaCBjb21wb25lbnQgd2lsbCBiZSBjcmVhdGVkXG4gKiBAcGFyYW0ge1Njb3BlfSByb290U2NvcGUgc2NvcGUgdG8gd2hpY2ggY29tcG9uZW50IHdpbGwgYmUgYWRkZWRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gbmV3VW5pcXVlTmFtZSBvcHRpb25hbCBgdHJ1ZWAgdG8gY3JlYXRlIGNvbXBvbmVudCB3aXRoIHRoZSBuYW1lIGRpZmZlcmVudCBmcm9tIHRoZSBvcmlnaW5hbCBvbmUuIGBGYWxzZWAgYnkgZGVmYXVsdC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gdGhyb3dPbkVycm9ycyBJZiBzZXQgdG8gZmFsc2UsIHRoZW4gZXJyb3JzIHdpbGwgb25seSBiZSBsb2dnZWQgdG8gY29uc29sZS4gVHJ1ZSBieSBkZWZhdWx0LlxuICogQHJldHVybiB7Q29tcG9uZW50fSBjb21wb25lbnRcbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JCRjcmVhdGVGcm9tU3RhdGUoc3RhdGUsIHJvb3RTY29wZSwgbmV3VW5pcXVlTmFtZSwgdGhyb3dPbkVycm9ycykge1xuICAgIGNoZWNrKHN0YXRlLCBNYXRjaC5PYmplY3RJbmNsdWRpbmcoe1xuICAgICAgICBjb21wTmFtZTogTWF0Y2guT3B0aW9uYWwoU3RyaW5nKSxcbiAgICAgICAgY29tcENsYXNzOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICBleHRyYUZhY2V0czogTWF0Y2guT3B0aW9uYWwoW1N0cmluZ10pLFxuICAgICAgICBmYWNldHNTdGF0ZXM6IE1hdGNoLk9wdGlvbmFsKE9iamVjdCksXG4gICAgICAgIG91dGVySFRNTDogU3RyaW5nXG4gICAgfSkpO1xuXG4gICAgdmFyIG1pbG9CaW5kZXIgPSByZXF1aXJlKCcuLi9iaW5kZXInKTtcblxuICAgIC8vIGNyZWF0ZSB3cmFwcGVyIGVsZW1lbnQgb3B0aW9uYWxseSByZW5hbWluZyBjb21wb25lbnRcbiAgICB2YXIgd3JhcEVsID0gX2NyZWF0ZUNvbXBvbmVudFdyYXBFbGVtZW50KHN0YXRlLCBuZXdVbmlxdWVOYW1lKTtcblxuICAgIC8vIGluc3RhbnRpYXRlIGFsbCBjb21wb25lbnRzIGZyb20gSFRNTFxuICAgIHZhciBzY29wZSA9IG1pbG9CaW5kZXIod3JhcEVsLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhyb3dPbkVycm9ycyk7XG5cbiAgICAvLyBhcyB0aGVyZSBzaG91bGQgb25seSBiZSBvbmUgY29tcG9uZW50LCBjYWxsIHRvIF9hbnkgd2lsbCByZXR1cm4gaXRcbiAgICB2YXIgY29tcG9uZW50ID0gc2NvcGUuX2FueSgpO1xuXG4gICAgLy8gc2V0IGNvbXBvbmVudCdzIHNjb3BlXG4gICAgaWYgKHJvb3RTY29wZSkge1xuICAgICAgICBjb21wb25lbnQuc2NvcGUgPSByb290U2NvcGU7XG4gICAgICAgIHJvb3RTY29wZS5fYWRkKGNvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgLy8gcmVzdG9yZSBjb21wb25lbnQgc3RhdGVcbiAgICBjb21wb25lbnQuc2V0U3RhdGUoc3RhdGUpO1xuICAgIF8uZGVmZXJNZXRob2QoY29tcG9uZW50LCAnYnJvYWRjYXN0JywgJ3N0YXRlcmVhZHknKTtcblxuICAgIHJldHVybiBjb21wb25lbnQ7ICAgXG59XG5cblxuLy8gdXNlZCBieSBDb21wb25lbnQkJGNyZWF0ZUZyb21TdGF0ZVxuZnVuY3Rpb24gX2NyZWF0ZUNvbXBvbmVudFdyYXBFbGVtZW50KHN0YXRlLCBuZXdVbmlxdWVOYW1lKSB7XG4gICAgdmFyIHdyYXBFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHdyYXBFbC5pbm5lckhUTUwgPSBzdGF0ZS5vdXRlckhUTUw7XG5cbiAgICB2YXIgY2hpbGRyZW4gPSBkb21VdGlscy5jaGlsZHJlbih3cmFwRWwpO1xuICAgIGlmIChjaGlsZHJlbi5sZW5ndGggIT0gMSlcbiAgICAgICAgdGhyb3cgbmV3IENvbXBvbmVudEVycm9yKCdjYW5ub3QgY3JlYXRlIGNvbXBvbmVudDogaW5jb3JyZWN0IEhUTUwsIGVsZW1lbnRzIG51bWJlcjogJyArIGNoaWxkcmVuLmxlbmd0aCArICcgKHNob3VsZCBiZSAxKScpO1xuICAgIHZhciBjb21wRWwgPSBjaGlsZHJlblswXTtcbiAgICB2YXIgYXR0ciA9IG5ldyBCaW5kQXR0cmlidXRlKGNvbXBFbCk7XG4gICAgYXR0ci5jb21wTmFtZSA9IG5ld1VuaXF1ZU5hbWUgPyBtaWxvQ29tcG9uZW50TmFtZSgpIDogc3RhdGUuY29tcE5hbWU7XG4gICAgYXR0ci5jb21wQ2xhc3MgPSBzdGF0ZS5jb21wQ2xhc3M7XG4gICAgYXR0ci5jb21wRmFjZXRzID0gc3RhdGUuZXh0cmFGYWNldHM7XG4gICAgYXR0ci5kZWNvcmF0ZSgpO1xuXG4gICAgcmV0dXJuIHdyYXBFbDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgY29tcG9uZW50IGZyb20gYSBEYXRhVHJhbnNmZXIgb2JqZWN0IChpZiBwb3NzaWJsZSlcbiAqXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9EYXRhVHJhbnNmZXJcbiAqIEBwYXJhbSB7RGF0YVRyYW5zZmVyfSBkYXRhVHJhbnNmZXIgRGF0YSB0cmFuc2ZlclxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkJGNyZWF0ZUZyb21EYXRhVHJhbnNmZXIoZGF0YVRyYW5zZmVyKSB7XG4gICAgdmFyIGRhdGFUeXBlID0gXy5maW5kKGRhdGFUcmFuc2Zlci50eXBlcywgZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIENPTVBPTkVOVF9EQVRBX1RZUEVfUkVHRVgudGVzdCh0eXBlKTtcbiAgICB9KTtcbiAgICBpZiAoIWRhdGFUeXBlKSByZXR1cm47XG5cbiAgICB2YXIgc3RhdGUgPSBfLmpzb25QYXJzZShkYXRhVHJhbnNmZXIuZ2V0RGF0YShkYXRhVHlwZSkpO1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcblxuICAgIHJldHVybiBDb21wb25lbnQuY3JlYXRlRnJvbVN0YXRlKHN0YXRlLCB1bmRlZmluZWQsIHRydWUpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZC5cbiAqIEluaXRpYWxpemVzIGNvbXBvbmVudC4gQXV0b21hdGljYWxseSBjYWxsZWQgYnkgaW5oZXJpdGVkIGNvbnN0cnVjdG9yIG9mIEZhY2V0ZWRPYmplY3QuXG4gKiBTdWJjbGFzc2VzIHNob3VsZCBjYWxsIGluaGVyaXRlZCBpbml0IG1ldGhvZHM6XG4gKiBgYGBcbiAqIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSBzY29wZSB0byB3aGljaCBjb21wb25lbnQgd2lsbCBiZWxvbmcuIEl0IGlzIHVzdWFsbHkgYSB0b3AgbGV2ZWwgc2NvcGUgb2JqZWN0IHJldHVybmVkIGJ5IGBtaWxvLmJpbmRlcmAgb3IgYHNjb3BlYCBwcm9wZXJ0eSBvZiBDb250YWluZXIgZmFjZXQuXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgRE9NIGVsZW1lbnQgdGhhdCBjb21wb25lbnQgaXMgYXR0YWNoZWQgdG9cbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIGNvbXBvbmVudCBuYW1lLCBzaG91bGQgYmUgdW5pcXVlIGluIHRoZSBzY29wZSBvZiBjb21wb25lbnRcbiAqIEBwYXJhbSB7Q29tcG9uZW50SW5mb30gY29tcG9uZW50SW5mbyBpbnN0YW5jZSBvZiBDb21wb25lbnRJbmZvIGNsYXNzIHRoYXQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgY29weSBvZiBjb21wb25lbnRcbiAqICBUT0RPIHRyeSByZW1vdmluZyBpdFxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkaW5pdChzY29wZSwgZWxlbWVudCwgbmFtZSwgY29tcG9uZW50SW5mbykge1xuICAgIC8vIGNyZWF0ZSBET00gZWxlbWVudCBpZiBpdCB3YXNuJ3QgcGFzc2VkIHRvIENvbnN0cnVjdG9yXG4gICAgdGhpcy5lbCA9IGVsZW1lbnQgfHwgdGhpcy5jcmVhdGVFbGVtZW50KCk7XG5cbiAgICAvLyBzdG9yZSByZWZlcmVuY2UgdG8gY29tcG9uZW50IG9uIERPTSBlbGVtZW50XG4gICAgaWYgKHRoaXMuZWwpIHtcbiAgICAgICAgLy8gY2hlY2sgdGhhdCBlbGVtZW50IGRvZXMgbm90IGhhdmUgYSBjb21wb25lbnQgYWxyZWFkeSBhdGFjaGVkXG4gICAgICAgIHZhciBlbENvbXAgPSB0aGlzLmVsW2NvbmZpZy5jb21wb25lbnRSZWZdO1xuICAgICAgICBpZiAoZWxDb21wKVxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ2NvbXBvbmVudCAnICsgbmFtZSArICcgYXR0YWNoZWQgdG8gZWxlbWVudCB0aGF0IGFscmVhZHkgaGFzIGNvbXBvbmVudCAnICsgZWxDb21wLm5hbWUpO1xuXG4gICAgICAgIHRoaXMuZWxbY29uZmlnLmNvbXBvbmVudFJlZl0gPSB0aGlzO1xuICAgIH1cblxuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgIGNvbXBvbmVudEluZm86IGNvbXBvbmVudEluZm8sXG4gICAgICAgIGV4dHJhRmFjZXRzOiBbXVxuICAgIH0sIF8uRU5VTSk7XG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcblxuICAgIC8vIGNyZWF0ZSBjb21wb25lbnQgbWVzc2VuZ2VyXG4gICAgdmFyIG1lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXIodGhpcyk7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBNRVNTRU5HRVJfUFJPUEVSVFksIG1lc3Nlbmdlcik7XG5cbiAgICAvLyBjaGVjayBhbGwgZmFjZXRzIGRlcGVuZGVuY2llcyAocmVxdWlyZWQgZmFjZXRzKVxuICAgIHRoaXMuYWxsRmFjZXRzKCdjaGVjaycpO1xuXG4gICAgLy8gc3RhcnQgYWxsIGZhY2V0c1xuICAgIHRoaXMuYWxsRmFjZXRzKCdzdGFydCcpO1xuXG4gICAgLy8gY2FsbCBzdGFydCBtZXRob2QgaWYgaXQncyBkZWZpbmVkIGluIHN1YmNsYXNzXG4gICAgaWYgKHRoaXMuc3RhcnQpIHRoaXMuc3RhcnQoKTtcbn1cblxuXG4vKipcbiAqIFRoaXMgaXMgYSBzdHViIHRvIGF2b2lkIGNvbmZ1c2lvbiB3aGV0aGVyIHRoZSBtZXRob2Qgb2Ygc3VwZXJjbGFzcyBzaG91bGQgYmUgY2FsbGVkIGluIHN1YmNsYXNzZXNcbiAqIFRoZSBzdGFydCBtZXRob2Qgb2Ygc3ViY2xhc3MgaW5zdGFuY2UgaXMgY2FsbGVkIG9uY2UgYWxsIHRoZSBmYWNldHMgYXJlIGNyZWF0ZWQsIGluaXRpYWxpemVkIGFuZCBzdGFydGVkIChzZWUgYWJvdmUpXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRzdGFydCgpIHt9XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogSW5pdGlhbGl6ZXMgdGhlIGVsZW1lbnQgd2hpY2ggdGhpcyBjb21wb25lbnQgaXMgYm91bmQgdG9cbiAqXG4gKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBhIGNvbXBvbmVudCBpcyBpbnN0YW50aWF0ZWQgb3V0c2lkZSB0aGUgRE9NIGFuZFxuICogd2lsbCBnZW5lcmF0ZSBhIG5ldyBlbGVtZW50IGZvciB0aGUgY29tcG9uZW50LlxuICogXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkY3JlYXRlRWxlbWVudCgpIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09ICd1bmRlZmluZWQnKVxuICAgICAgICByZXR1cm47XG5cbiAgICB0aGlzLmVsID0gdGhpcy5kb21cbiAgICAgICAgICAgICAgICA/IHRoaXMuZG9tLmNyZWF0ZUVsZW1lbnQoKVxuICAgICAgICAgICAgICAgIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnRElWJyk7XG5cbiAgICByZXR1cm4gdGhpcy5lbDtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgdHJ1ZSBpZiBjb21wb25lbnQgaGFzIGZhY2V0XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGZhY2V0TmFtZU9yQ2xhc3NcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRoYXNGYWNldChmYWNldE5hbWVPckNsYXNzKSB7XG4gICAgdmFyIGZhY2V0TmFtZSA9IF8uZmlyc3RMb3dlckNhc2UodHlwZW9mIGZhY2V0TmFtZU9yQ2xhc3MgPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZmFjZXROYW1lT3JDbGFzcy5uYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmYWNldE5hbWVPckNsYXNzKTtcblxuICAgIHZhciBmYWNldCA9IHRoaXNbZmFjZXROYW1lXTtcbiAgICBpZiAoISBmYWNldCBpbnN0YW5jZW9mIENvbXBvbmVudEZhY2V0KVxuICAgICAgICBsb2dnZXIud2FybignZXhwZWN0ZWQgZmFjZXQnLCBmYWNldE5hbWUsICdidXQgdGhpcyBwcm9wZXJ0eSBuYW1lIGlzIHVzZWQgZm9yIHNvbWV0aGluZyBlbHNlJyk7XG5cbiAgICByZXR1cm4gISEgZmFjZXQ7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogQWRkcyBmYWNldCB3aXRoIGdpdmVuIG5hbWUgb3IgY2xhc3MgdG8gdGhlIGluc3RhbmNlIG9mIENvbXBvbmVudCAob3IgaXRzIHN1YmNsYXNzKS5cbiAqIFxuICogQHBhcmFtIHtTdHJpbmd8U3ViY2xhc3MoQ29tcG9uZW50KX0gZmFjZXROYW1lT3JDbGFzcyBuYW1lIG9mIGZhY2V0IGNsYXNzIG9yIHRoZSBjbGFzcyBpdHNlbGYuIElmIG5hbWUgaXMgcGFzc2VkLCB0aGUgY2xhc3Mgd2lsbCBiZSByZXRpcmV2ZWQgZnJvbSBmYWNldHNSZWdpc3RyeVxuICogQHBhcmFtIHtPYmplY3R9IGZhY2V0Q29uZmlnIG9wdGlvbmFsIGZhY2V0IGNvbmZpZ3VyYXRpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSBmYWNldE5hbWUgb3B0aW9uYWwgZmFjZXQgbmFtZS4gQWxsb3dzIHRvIGFkZCBmYWNldCB1bmRlciBhIG5hbWUgZGlmZmVyZW50IGZyb20gdGhlIGNsYXNzIG5hbWUgc3VwcGxpZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHRocm93T25FcnJvcnMgSWYgc2V0IHRvIGZhbHNlLCB0aGVuIGVycm9ycyB3aWxsIG9ubHkgYmUgbG9nZ2VkIHRvIGNvbnNvbGUuIFRydWUgYnkgZGVmYXVsdC5cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGFkZEZhY2V0KGZhY2V0TmFtZU9yQ2xhc3MsIGZhY2V0Q29uZmlnLCBmYWNldE5hbWUsIHRocm93T25FcnJvcnMpIHtcbiAgICBjaGVjayhmYWNldE5hbWVPckNsYXNzLCBNYXRjaC5PbmVPZihTdHJpbmcsIE1hdGNoLlN1YmNsYXNzKENvbXBvbmVudEZhY2V0KSkpO1xuICAgIGNoZWNrKGZhY2V0Q29uZmlnLCBNYXRjaC5PcHRpb25hbChPYmplY3QpKTtcbiAgICBjaGVjayhmYWNldE5hbWUsIE1hdGNoLk9wdGlvbmFsKFN0cmluZykpO1xuXG4gICAgdmFyIEZhY2V0Q2xhc3M7XG4gICAgLy8gaWYgb25seSBuYW1lIHBhc3NlZCwgcmV0cmlldmUgZmFjZXQgY2xhc3MgZnJvbSByZWdpc3RyeVxuICAgIGlmICh0eXBlb2YgZmFjZXROYW1lT3JDbGFzcyA9PSAnc3RyaW5nJykge1xuICAgICAgICB2YXIgZmFjZXRDbGFzc05hbWUgPSBfLmZpcnN0VXBwZXJDYXNlKGZhY2V0TmFtZU9yQ2xhc3MpO1xuICAgICAgICBGYWNldENsYXNzID0gZmFjZXRzUmVnaXN0cnkuZ2V0KGZhY2V0Q2xhc3NOYW1lKTtcbiAgICB9IGVsc2UgXG4gICAgICAgIEZhY2V0Q2xhc3MgPSBmYWNldE5hbWVPckNsYXNzO1xuXG4gICAgaWYgKCFmYWNldE5hbWUpXG4gICAgICAgIGZhY2V0TmFtZSA9IF8uZmlyc3RMb3dlckNhc2UoRmFjZXRDbGFzcy5uYW1lKTtcblxuICAgIHRoaXMuZXh0cmFGYWNldHMucHVzaChmYWNldE5hbWUpO1xuXG4gICAgLy8gYWRkIGZhY2V0IHVzaW5nIG1ldGhvZCBvZiBGYWNldGVkT2JqZWN0XG4gICAgdmFyIG5ld0ZhY2V0ID0gRmFjZXRlZE9iamVjdC5wcm90b3R5cGUuYWRkRmFjZXQuY2FsbCh0aGlzLCBGYWNldENsYXNzLCBmYWNldENvbmZpZywgZmFjZXROYW1lLCB0aHJvd09uRXJyb3JzKTtcblxuICAgIC8vIGNoZWNrIGRlcGVuZWRlbmNpZXMgYW5kIHN0YXJ0IGZhY2V0XG4gICAgaWYgKG5ld0ZhY2V0LmNoZWNrKSBuZXdGYWNldC5jaGVjaygpO1xuICAgIGlmIChuZXdGYWNldC5zdGFydCkgbmV3RmFjZXQuc3RhcnQoKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2QuXG4gKiBFbnZva2UgZ2l2ZW4gbWV0aG9kIHdpdGggb3B0aW9uYWwgcGFyYW1ldGVycyBvbiBhbGwgZmFjZXRzLlxuICogUmV0dXJucyB0aGUgbWFwIG9mIHZhbHVlcyByZXR1cm5lZCBieSBhbGwgZmFjZXRzLiBJZiB0aGUgZmFjZXQgZG9lc24ndCBoYXZlIHRoZSBtZXRob2QgaXQgaXMgc2ltcGx5IG5vdCBjYWxsZWQgYW5kIHRoZSB2YWx1ZSBpbiB0aGUgbWFwIHdpbGwgYmUgdW5kZWZpbmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgbWV0aG9kIG5hbWUgdG8gZW52b2tlIG9uIHRoZSBmYWNldFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkYWxsRmFjZXRzKG1ldGhvZCkgeyAvLyAsLi4uIGFyZ3VtZW50c1xuICAgIHZhciBhcmdzID0gXy5zbGljZShhcmd1bWVudHMsIDEpO1xuXG4gICAgcmV0dXJuIF8ubWFwS2V5cyh0aGlzLmZhY2V0cywgZnVuY3Rpb24oZmFjZXQsIGZjdE5hbWUpIHtcbiAgICAgICAgaWYgKGZhY2V0ICYmIHR5cGVvZiBmYWNldFttZXRob2RdID09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICByZXR1cm4gZmFjZXRbbWV0aG9kXS5hcHBseShmYWNldCwgYXJncyk7XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogXG4gKiBAcGFyYW0ge1tTdHJpbmddfSBuYW1lIG9wdGlvbmFsIG5ldyBuYW1lIG9mIGNvbXBvbmVudCwgXG4gKiBAcGFyYW0ge1tCb29sZWFuXX0gcmVuYW1lSW5TY29wZSBvcHRpb25hbCBmYWxzZSB0byBub3QgcmVuYW1lIENvbXBvbmVudEluZm8gb2JqZWN0IGluIGl0cyBzY29wZSwgdHJ1ZSBieSBkZWZhdWx0XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRyZW5hbWUobmFtZSwgcmVuYW1lSW5TY29wZSkge1xuICAgIG5hbWUgPSBuYW1lIHx8IG1pbG9Db21wb25lbnROYW1lKCk7XG4gICAgdGhpcy5jb21wb25lbnRJbmZvLnJlbmFtZShuYW1lLCBmYWxzZSk7XG4gICAgU2NvcGUucmVuYW1lKHRoaXMsIG5hbWUsIHJlbmFtZUluU2NvcGUpO1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZC5cbiAqIFJlbW92ZXMgY29tcG9uZW50IGZyb20gaXRzIHNjb3BlLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcHJlc2VydmVTY29wZVByb3BlcnR5IHRydWUgbm90IHRvIGRlbGV0ZSBzY29wZSBwcm9wZXJ0eSBvZiBjb21wb25lbnRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcXVpZXQgb3B0aW9uYWwgdHJ1ZSB0byBzdXBwcmVzcyB0aGUgd2FybmluZyBtZXNzYWdlIGlmIHRoZSBjb21wb25lbnQgaXMgbm90IGluIHNjb3BlXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRyZW1vdmUocHJlc2VydmVTY29wZVByb3BlcnR5LCBxdWlldCkge1xuICAgIGlmICh0aGlzLnNjb3BlKSB7XG4gICAgICAgIHRoaXMuc2NvcGUuX3JlbW92ZSh0aGlzLm5hbWUsIHF1aWV0KTtcbiAgICAgICAgaWYgKCEgcHJlc2VydmVTY29wZVByb3BlcnR5KVxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc2NvcGU7XG4gICAgfVxufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZC5cbiAqIEluc2VydHMgdGhlIGNvbXBvbmVudCBpbnRvIHRoZSBET00gYW5kIGF0dGVtcHRzIHRvIGFkanVzdCB0aGUgc2NvcGUgdHJlZSBhY2NvcmRpbmdseS5cbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudEVsICAgIFRoZSBlbGVtZW50IGludG8gd2hpY2ggdGhlIGNvbXBvbmVudCBzaG91bGQgYmUgaW5zZXJ0ZWQuXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSByZWZlcmVuY2VFbCAob3B0aW9uYWwpIFRoZSByZWZlcmVuY2UgZWxlbWVudCBpdCBzaG91bGQgYmUgaW5zZXJ0ZWQgYmVmb3JlLlxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkaW5zZXJ0SW50byhwYXJlbnRFbCwgcmVmZXJlbmNlRWwpIHtcbiAgICBwYXJlbnRFbC5pbnNlcnRCZWZvcmUodGhpcy5lbCwgcmVmZXJlbmNlRWwpO1xuICAgIHRoaXMuc2V0U2NvcGVQYXJlbnRGcm9tRE9NKCk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXRyaWV2ZXMgYWxsIGNvbXBvbmVudCBzdGF0ZSwgaW5jbHVkaW5nIGluZm9ybWF0aW9uIGFib3V0IGl0cyBjbGFzcywgZXh0cmEgZmFjZXRzLCBmYWNldHMgZGF0YSBhbmQgYWxsIHNjb3BlIGNoaWxkcmVuLlxuICogVGhpcyBpbmZvcm1hdGlvbiBpcyB1c2VkIHRvIHNhdmUvbG9hZCwgY29weS9wYXN0ZSBhbmQgZHJhZy9kcm9wIGNvbXBvbmVudCBcbiAqIFJldHVybnMgY29tcG9uZW50IHN0YXRlXG4gKlxuICogQHRoaXMge0NvbXBvbmVudH0gY29tcG9uZW50IHdoaWNoIHN0YXRlIHdpbGwgYmUgc2F2ZWRcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGdldFN0YXRlKCkge1xuICAgIHRoaXMuYnJvYWRjYXN0KCdnZXRzdGF0ZXN0YXJ0ZWQnLCB7IHJvb3RDb21wb25lbnQ6IHRoaXMgfSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9nZXRTdGF0ZSh0cnVlKTtcbiAgICBzdGF0ZS5vdXRlckhUTUwgPSB0aGlzLmVsLm91dGVySFRNTDtcbiAgICBfLmRlZmVyTWV0aG9kKHRoaXMsICdicm9hZGNhc3QnLCAnZ2V0c3RhdGVjb21wbGV0ZWQnLCB7IHJvb3RDb21wb25lbnQ6IHRoaXMgfSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICByZXR1cm4gc3RhdGU7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXRyaWV2ZXMgYWxsIGNvbXBvbmVudCBzdGF0ZSwgaW5jbHVkaW5nIGluZm9ybWF0aW9uIGFib3V0IGl0cyBjbGFzcywgZXh0cmEgZmFjZXRzLCBmYWNldHMgZGF0YSBhbmQgYWxsIHNjb3BlIGNoaWxkcmVuLlxuICogVGhpcyBpbmZvcm1hdGlvbiBpcyB1c2VkIHRvIHNhdmUvbG9hZCwgY29weS9wYXN0ZSBhbmQgZHJhZy9kcm9wIGNvbXBvbmVudCBcbiAqIElmIGNvbXBvbmVudCBoYXMgW1RyYW5zZmVyXSguL2NfZmFjZXRzL1RyYW5zZmVyLmpzLmh0bWwpIGZhY2V0IG9uIGl0LCB0aGlzIG1ldGhvZCByZXRyaWV2ZXMgc3RhdGUgZnJvbSB0aGlzIGZhY2V0XG4gKiBSZXR1cm5zIGNvbXBvbmVudCBzdGF0ZVxuICpcbiAqIEB0aGlzIHtDb21wb25lbnR9IGNvbXBvbmVudCB3aGljaCBzdGF0ZSB3aWxsIGJlIHNhdmVkXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBjYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzLiBcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGdldFRyYW5zZmVyU3RhdGUob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnRyYW5zZmVyXG4gICAgICAgICAgICA/IHRoaXMudHJhbnNmZXIuZ2V0U3RhdGUob3B0aW9ucylcbiAgICAgICAgICAgIDogdGhpcy5nZXRTdGF0ZShvcHRpb25zKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIGNvbXBvbmVudFxuICogVXNlZCBieSBjbGFzcyBtZXRob2QgYENvbXBvbmVudC5nZXRTdGF0ZWAgYW5kIGJ5IFtDb250YWluZXJdKC4vY19mYWNldHMvQ29udGFpbmVyLmpzLmh0bWwpIGZhY2V0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRlZXBTdGF0ZSBmYWxzZSB0byBnZXQgc2hhbGxvdyBzdGF0ZSBmcm9tIGFsbCBmYWNldHMgKHRydWUgYnkgZGVmYXVsdClcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JF9nZXRTdGF0ZShkZWVwU3RhdGUpe1xuXG4gICAgdmFyIGZhY2V0c1N0YXRlcyA9IHRoaXMuYWxsRmFjZXRzKCdnZXRTdGF0ZScsIGRlZXBTdGF0ZSA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWUpO1xuICAgIGZhY2V0c1N0YXRlcyA9IF8uZmlsdGVyS2V5cyhmYWNldHNTdGF0ZXMsIGZ1bmN0aW9uKGZjdFN0YXRlKSB7XG4gICAgICAgIHJldHVybiAhISBmY3RTdGF0ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGNvbXBOYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIGNvbXBDbGFzczogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICBleHRyYUZhY2V0czogdGhpcy5leHRyYUZhY2V0cyxcbiAgICAgICAgZmFjZXRzU3RhdGVzOiBmYWNldHNTdGF0ZXNcbiAgICB9O1xufVxuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogU2V0cyB0aGUgc3RhdGUgb2YgY29tcG9uZW50LlxuICogVXNlZCBieSBjbGFzcyBtZXRob2QgYENvbXBvbmVudC5jcmVhdGVGcm9tU3RhdGVgIGFuZCBieSBbQ29udGFpbmVyXSguL2NfZmFjZXRzL0NvbnRhaW5lci5qcy5odG1sKSBmYWNldC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN0YXRlIHN0YXRlIHRvIHNldCB0aGUgY29tcG9uZW50XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRzZXRTdGF0ZShzdGF0ZSkge1xuICAgIGlmIChzdGF0ZS5mYWNldHNTdGF0ZXMpXG4gICAgICAgIF8uZWFjaEtleShzdGF0ZS5mYWNldHNTdGF0ZXMsIGZ1bmN0aW9uKGZjdFN0YXRlLCBmY3ROYW1lKSB7XG4gICAgICAgICAgICB2YXIgZmFjZXQgPSB0aGlzW2ZjdE5hbWVdO1xuICAgICAgICAgICAgaWYgKGZhY2V0ICYmIHR5cGVvZiBmYWNldC5zZXRTdGF0ZSA9PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgICAgIGZhY2V0LnNldFN0YXRlKGZjdFN0YXRlKTtcbiAgICAgICAgfSwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogUmV0dXJucyB0aGUgc2NvcGUgcGFyZW50IG9mIGEgY29tcG9uZW50LlxuICogSWYgYGNvbmRpdGlvbk9yRmFjZXRgIHBhcmFtZXRlciBpcyBub3Qgc3BlY2lmaWVkLCBhbiBpbW1lZGlhdGUgcGFyZW50IHdpbGwgYmUgcmV0dXJuZWQsIG90aGVyd2lzZSB0aGUgY2xvc2VzdCBhbmNlc3RvciB3aXRoIGEgc3BlY2lmaWVkIGZhY2V0IG9yIHBhc3NpbmcgY29uZGl0aW9uIHRlc3QuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGNvbmRpdGlvbk9yRmFjZXQgb3B0aW9uYWwgY29uZGl0aW9uIHRoYXQgY29tcG9uZW50IHNob3VsZCBwYXNzIChvciBmYWNldCBuYW1lIGl0IHNob3VsZCBjb250YWluKVxuICogQHJldHVybiB7Q29tcG9uZW50fHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGdldFNjb3BlUGFyZW50KGNvbmRpdGlvbk9yRmFjZXQpIHtcbiAgICByZXR1cm4gX2NhbGxHZXRTY29wZVBhcmVudC5jYWxsKHRoaXMsIF9nZXRTY29wZVBhcmVudCwgY29uZGl0aW9uT3JGYWNldCk7XG59XG5cbmZ1bmN0aW9uIF9jYWxsR2V0U2NvcGVQYXJlbnQoX2dldFNjb3BlUGFyZW50RnVuYywgY29uZGl0aW9uT3JGYWNldCkge1xuICAgIGNoZWNrKGNvbmRpdGlvbk9yRmFjZXQsIE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKEZ1bmN0aW9uLCBTdHJpbmcpKSk7XG4gICAgdmFyIGNvbmRpdGlvbkZ1bmMgPSBjb21wb25lbnRVdGlscy5fbWFrZUNvbXBvbmVudENvbmRpdGlvbkZ1bmMoY29uZGl0aW9uT3JGYWNldCk7XG4gICAgcmV0dXJuIF9nZXRTY29wZVBhcmVudEZ1bmMuY2FsbCh0aGlzLCBjb25kaXRpb25GdW5jKTsgICBcbn1cblxuZnVuY3Rpb24gX2dldFNjb3BlUGFyZW50KGNvbmRpdGlvbkZ1bmMpIHtcbiAgICB2YXIgcGFyZW50O1xuICAgIHRyeSB7IHBhcmVudCA9IHRoaXMuc2NvcGUuX2hvc3RPYmplY3Qub3duZXI7IH0gY2F0Y2goZSkge31cblxuICAgIC8vIFdoZXJlIHRoZXJlIGlzIG5vIHBhcmVudCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB1bmRlZmluZWRcbiAgICAvLyBUaGUgcGFyZW50IGNvbXBvbmVudCBpcyBjaGVja2VkIHJlY3Vyc2l2ZWx5XG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICBpZiAoISBjb25kaXRpb25GdW5jIHx8IGNvbmRpdGlvbkZ1bmMocGFyZW50KSApXG4gICAgICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gX2dldFNjb3BlUGFyZW50LmNhbGwocGFyZW50LCBjb25kaXRpb25GdW5jKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNjb3BlIHBhcmVudCB3aXRoIGEgZ2l2ZW4gY2xhc3MsIHdpdGggc2FtZSBjbGFzcyBpZiBub3Qgc3BlY2lmaWVkXG4gKlxuICogQHBhcmFtIHtbRnVuY3Rpb25dfSBDb21wb25lbnRDbGFzcyBjb21wb25lbnQgY2xhc3MgdGhhdCB0aGUgcGFyZW50IHNob3VsZCBoYXZlLCBzYW1lIGNsYXNzIGJ5IGRlZmF1bHRcbiAqIEByZXR1cm4ge0NvbXBvbmVudH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JGdldFNjb3BlUGFyZW50V2l0aENsYXNzKENvbXBvbmVudENsYXNzKSB7XG4gICAgQ29tcG9uZW50Q2xhc3MgPSBDb21wb25lbnRDbGFzcyB8fCB0aGlzLmNvbnN0cnVjdG9yO1xuICAgIHJldHVybiBfZ2V0U2NvcGVQYXJlbnQuY2FsbCh0aGlzLCBmdW5jdGlvbihjb21wKSB7XG4gICAgICAgIHJldHVybiBjb21wIGluc3RhbmNlb2YgQ29tcG9uZW50Q2xhc3M7XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kLlxuICogUmV0dXJucyB0aGUgdG9wbW9zdCBzY29wZSBwYXJlbnQgb2YgYSBjb21wb25lbnQuXG4gKiBJZiBgY29uZGl0aW9uT3JGYWNldGAgcGFyYW1ldGVyIGlzIG5vdCBzcGVjaWZpZWQsIHRoZSB0b3Btb3N0IHNjb3BlIHBhcmVudCB3aWxsIGJlIHJldHVybmVkLCBvdGhlcndpc2UgdGhlIHRvcG1vc3QgYW5jZXN0b3Igd2l0aCBhIHNwZWNpZmllZCBmYWNldCBvciBwYXNzaW5nIGNvbmRpdGlvbiB0ZXN0LlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfSBjb25kaXRpb25PckZhY2V0IG9wdGlvbmFsIGNvbmRpdGlvbiB0aGF0IGNvbXBvbmVudCBzaG91bGQgcGFzcyAob3IgZmFjZXQgbmFtZSBpdCBzaG91bGQgY29udGFpbilcbiAqIEByZXR1cm4ge0NvbXBvbmVudHx1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRnZXRUb3BTY29wZVBhcmVudChjb25kaXRpb25PckZhY2V0KSB7XG4gICAgcmV0dXJuIF9jYWxsR2V0U2NvcGVQYXJlbnQuY2FsbCh0aGlzLCBfZ2V0VG9wU2NvcGVQYXJlbnQsIGNvbmRpdGlvbk9yRmFjZXQpO1xufVxuXG5mdW5jdGlvbiBfZ2V0VG9wU2NvcGVQYXJlbnQoY29uZGl0aW9uRnVuYykge1xuICAgIHZhciB0b3BQYXJlbnRcbiAgICAgICAgLCBwYXJlbnQgPSB0aGlzO1xuICAgIGRvIHtcbiAgICAgICAgcGFyZW50ID0gX2dldFNjb3BlUGFyZW50LmNhbGwocGFyZW50LCBjb25kaXRpb25GdW5jKTtcbiAgICAgICAgaWYgKHBhcmVudClcbiAgICAgICAgICAgIHRvcFBhcmVudCA9IHBhcmVudDtcbiAgICB9IHdoaWxlIChwYXJlbnQpO1xuXG4gICAgcmV0dXJuIHRvcFBhcmVudDtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgc2NvcGUgcGFyZW50IHdpdGggYSBnaXZlbiBjbGFzcywgd2l0aCBzYW1lIGNsYXNzIGlmIG5vdCBzcGVjaWZpZWRcbiAqXG4gKiBAcGFyYW0ge1tGdW5jdGlvbl19IENvbXBvbmVudENsYXNzIGNvbXBvbmVudCBjbGFzcyB0aGF0IHRoZSBwYXJlbnQgc2hvdWxkIGhhdmUsIHNhbWUgY2xhc3MgYnkgZGVmYXVsdFxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBDb21wb25lbnQkZ2V0VG9wU2NvcGVQYXJlbnRXaXRoQ2xhc3MoQ29tcG9uZW50Q2xhc3MpIHtcbiAgICBDb21wb25lbnRDbGFzcyA9IENvbXBvbmVudENsYXNzIHx8IHRoaXMuY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIF9nZXRUb3BTY29wZVBhcmVudC5jYWxsKHRoaXMsIGZ1bmN0aW9uKGNvbXApIHtcbiAgICAgICAgcmV0dXJuIGNvbXAgaW5zdGFuY2VvZiBDb21wb25lbnRDbGFzcztcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEZpbmRzIHNjb3BlIHBhcmVudCBvZiBjb21wb25lbnQgdXNpbmcgRE9NIHRyZWUgKHVubGlrZSBnZXRTY29wZVBhcmVudCB0aGF0IHNpbXBseSBnb2VzIHVwIHRoZSBzY29wZSB0cmVlKS5cbiAqIFdoaWxlIGdldFNjb3BlUGFyZW50IGlzIGZhc3RlciBpdCBtYXkgZmFpbCBpZiBzY29wZSBjaGFpbiBpcyBub3Qgc2V0dXAgeWV0IChlLmcuLCB3aGVuIGNvbXBvbmVudCBoYXMgYmVlbiBqdXN0IGluc2VydGVkKS5cbiAqIFRoZSBzY29wZSBwcm9wZXJ0eSBvZiBjb21wb25lbnQgd2lsbCBiZSBjaGFuZ2VkIHRvIHBvaW50IHRvIHNjb3BlIG9iamVjdCBvZiBjb250YWluZXIgZmFjZXQgb2YgdGhhdCBwYXJlbnQuXG4gKiBSZXR1cm5lZCBzY29wZSBwYXJlbnQgb2YgdGhlIGNvbXBvbmVudCB3aWxsIGJlIHVuZGVmaW5lZCAoYXMgd2VsbCBhcyBjb21wb25lbnQncyBzY29wZSBwcm9wZXJ0eSkgaWYgbm8gcGFyZW50IGluIHRoZSBET00gdHJlZSBoYXMgY29udGFpbmVyIGZhY2V0LlxuICogVE9ETyBNZXRob2Qgd2lsbCBub3QgYmluZCBET00gY2hpbGRyZW4gY29ycmVjdGx5IGlmIGNvbXBvbmVudCBoYXMgbm8gY29udGFpbmVyIGZhY2V0LlxuICpcbiAqIEByZXR1cm4ge0NvbXBvbmVudH1cbiAqL1xuZnVuY3Rpb24gQ29tcG9uZW50JHNldFNjb3BlUGFyZW50RnJvbURPTSgpIHtcbiAgICB2YXIgcGFyZW50RWwgPSB0aGlzLmVsLnBhcmVudE5vZGU7XG5cbiAgICB2YXIgcGFyZW50LCBmb3VuZFBhcmVudDtcbiAgICB3aGlsZSAocGFyZW50RWwgJiYgISBmb3VuZFBhcmVudCkge1xuICAgICAgICBwYXJlbnQgPSBDb21wb25lbnQuZ2V0Q29tcG9uZW50KHBhcmVudEVsKTtcbiAgICAgICAgZm91bmRQYXJlbnQgPSBwYXJlbnQgJiYgcGFyZW50LmNvbnRhaW5lcjtcbiAgICAgICAgcGFyZW50RWwgPSBwYXJlbnRFbC5wYXJlbnROb2RlO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlKCk7IC8vIHJlbW92ZSBjb21wb25lbnQgZnJvbSBpdHMgY3VycmVudCBzY29wZSAoaWYgaXQgaXMgZGVmaW5lZClcbiAgICBpZiAoZm91bmRQYXJlbnQpIHtcbiAgICAgICAgdGhpcy5yZW5hbWUodW5kZWZpbmVkLCBmYWxzZSk7XG4gICAgICAgIHBhcmVudC5jb250YWluZXIuc2NvcGUuX2FkZCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICB9ICAgICAgICBcbn1cblxuXG4vKipcbiAqIFdhbGtzIGNvbXBvbmVudCB0cmVlLCBjYWxsaW5nIHByb3ZpZGVkIGNhbGxiYWNrIG9uIGVhY2ggY29tcG9uZW50XG4gKlxuICogQHBhcmFtIGNhbGxiYWNrXG4gKiBAcGFyYW0gdGhpc0FyZ1xuICovXG5mdW5jdGlvbiBDb21wb25lbnQkd2Fsa1Njb3BlVHJlZShjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdGhpcyk7XG4gICAgaWYgKCF0aGlzLmNvbnRhaW5lcikgcmV0dXJuO1xuICAgIHRoaXMuY29udGFpbmVyLnNjb3BlLl9lYWNoKGZ1bmN0aW9uKGNvbXBvbmVudCkge1xuICAgICAgICBjb21wb25lbnQud2Fsa1Njb3BlVHJlZShjYWxsYmFjaywgdGhpc0FyZyk7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gQ29tcG9uZW50JHRyZWVQYXRoT2YoY29tcG9uZW50KSB7XG4gICAgcmV0dXJuIGRvbVV0aWxzLnRyZWVQYXRoT2YodGhpcy5lbCwgY29tcG9uZW50LmVsKTtcbn1cblxuXG5mdW5jdGlvbiBDb21wb25lbnQkZ2V0Q29tcG9uZW50QXRUcmVlUGF0aCh0cmVlUGF0aCwgbmVhcmVzdCkge1xuICAgIHZhciBub2RlID0gZG9tVXRpbHMuZ2V0Tm9kZUF0VHJlZVBhdGgodGhpcy5lbCwgdHJlZVBhdGgsIG5lYXJlc3QpO1xuICAgIHJldHVybiBDb21wb25lbnQuZ2V0Q29tcG9uZW50KG5vZGUpO1xufVxuXG5cbmZ1bmN0aW9uIENvbXBvbmVudCRpbnNlcnRBdFRyZWVQYXRoKHRyZWVQYXRoLCBjb21wb25lbnQsIG5lYXJlc3QpIHtcbiAgICB2YXIgd2FzSW5zZXJ0ZWQgPSBkb21VdGlscy5pbnNlcnRBdFRyZWVQYXRoKHRoaXMuZWwsIHRyZWVQYXRoLCBjb21wb25lbnQuZWwpO1xuICAgIGlmICh3YXNJbnNlcnRlZCkgY29tcG9uZW50LnNldFNjb3BlUGFyZW50RnJvbURPTSgpO1xuICAgIHJldHVybiB3YXNJbnNlcnRlZDtcbn1cblxuXG4vKipcbiAqIEJyb2FkY2FzdCBtZXNzYWdlIHRvIGNvbXBvbmVudCBhbmQgdG8gYWxsIGl0cyBzY29wZSBjaGlsZHJlblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbXNnIG1lc3NhZ2UgdG8gYmUgc2VudFxuICogQHBhcmFtIHtbQW55XX0gZGF0YSBvcHRpb25hbCBtZXNzYWdlIGRhdGFcbiAqIEBwYXJhbSB7W0Z1bmN0aW9uXX0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2tcbiAqIEBwYXJhbSB7W0Jvb2xlYW5dfSBzeW5jaHJvbm91c2x5IGlmIGl0IHNob3VsZCB1c2UgcG9zdE1lc3NhZ2VTeW5jXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRicm9hZGNhc3QobXNnLCBkYXRhLCBjYWxsYmFjaywgc3luY2hyb25vdXNseSkge1xuICAgIHZhciBwb3N0TWV0aG9kID0gc3luY2hyb25vdXNseSA/ICdwb3N0TWVzc2FnZVN5bmMnIDogJ3Bvc3RNZXNzYWdlJztcbiAgICB0aGlzLndhbGtTY29wZVRyZWUoZnVuY3Rpb24oY29tcG9uZW50KSB7XG4gICAgICAgIGNvbXBvbmVudFtwb3N0TWV0aG9kXShtc2csIGRhdGEsIGNhbGxiYWNrKTtcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIERlc3Ryb3kgY29tcG9uZW50OiByZW1vdmVzIGNvbXBvbmVudCBmcm9tIERPTSwgcmVtb3ZlcyBpdCBmcm9tIHNjb3BlLCBkZWxldGVzIGFsbCByZWZlcmVuY2VzIHRvIERPTSBub2RlcyBhbmQgdW5zdWJzY3JpYmVzIGZyb20gYWxsIG1lc3NhZ2VzIGJvdGggY29tcG9uZW50IGFuZCBhbGwgZmFjZXRzXG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRkZXN0cm95KHF1aWV0KSB7XG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3llZCkge1xuICAgICAgICBpZiAoIXF1aWV0KSBsb2dnZXIud2FybignQ29tcG9uZW50IGRlc3Ryb3k6IGNvbXBvbmVudCBpcyBhbHJlYWR5IGRlc3Ryb3llZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlKGZhbHNlLCBxdWlldCk7XG4gICAgdGhpcy5hbGxGYWNldHMoJ2Rlc3Ryb3knKTtcbiAgICB0aGlzW01FU1NFTkdFUl9QUk9QRVJUWV0uZGVzdHJveSgpO1xuICAgIGlmICh0aGlzLmVsKSB7XG4gICAgICAgIGRvbVV0aWxzLmRldGFjaENvbXBvbmVudCh0aGlzLmVsKTtcbiAgICAgICAgZG9tVXRpbHMucmVtb3ZlRWxlbWVudCh0aGlzLmVsKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuZWw7XG4gICAgfVxuICAgIHRoaXMuY29tcG9uZW50SW5mby5kZXN0cm95KCk7XG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBjb21wb25lbnQgd2FzIGRlc3Ryb3llZFxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudCRpc0Rlc3Ryb3llZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVzdHJveWVkO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBtaWxvLkNvbXBvbmVudC5GYWNldGBcbiAqXG4gKiBUaGUgY2xhc3MgZm90IHRoZSBmYWNldCBvZiBjb21wb25lbnQuIFdoZW4gYSBjb21wb25lbnQgaXMgY3JlYXRlZCwgaXRcbiAqIGNyZWF0ZXMgYWxsIGl0cyBmYWNldHMuXG4gKlxuICogU2VlIEZhY2V0cyBzZWN0aW9uIG9uIGluZm9ybWF0aW9uIGFib3V0IGF2YWlsYWJsZSBmYWNldHMgYW5kIG9uXG4gKiBob3cgdG8gY3JlYXRlIG5ldyBmYWNldHMgY2xhc3Nlcy5cbiAqXG4gKiAtIENvbXBvbmVudCAtIGJhc2ljIGNvbXBwb25lbnQgY2xhc3NcbiAqIC0gQ29tcG9uZW50RmFjZXQgLSBiYXNpY1xuICovXG5cbnZhciBGYWNldCA9IHJlcXVpcmUoJy4uL2Fic3RyYWN0L2ZhY2V0JylcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uL21lc3NlbmdlcicpXG4gICAgLCBGYWNldEVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLkZhY2V0XG4gICAgLCBjb21wb25lbnRVdGlscyA9IHJlcXVpcmUoJy4vY191dGlscycpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cbnZhciBDb21wb25lbnRGYWNldCA9IF8uY3JlYXRlU3ViY2xhc3MoRmFjZXQsICdDb21wb25lbnRGYWNldCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBvbmVudEZhY2V0O1xuXG5cbi8qKlxuICogcG9zdERvbVBhcmVudFxuICpcbiAqIElmIGZhY2V0IGhhcyBET00gcGFyZW50IGZhY2V0IChzZWUgYGRvbVBhcmVudGAgbWV0aG9kKSwgcG9zdHMgdGhlIG1lc3NhZ2UgdG8gdGhpcyBmYWNldC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVR5cGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtZXNzYWdlRGF0YVxuICovXG52YXIgcG9zdERvbVBhcmVudCA9IF8ucGFydGlhbChfcG9zdFBhcmVudCwgZG9tUGFyZW50KTtcblxuLyoqXG4gKiBwb3N0U2NvcGVQYXJlbnRcbiAqXG4gKiBJZiBmYWNldCBoYXMgc2NvcGUgcGFyZW50IGZhY2V0IChzZWUgYHNjb3BlUGFyZW50YCBtZXRob2QpLCBwb3N0cyB0aGUgbWVzc2FnZSB0byB0aGlzIGZhY2V0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlVHlwZVxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2VEYXRhXG4gKi9cbnZhciBwb3N0U2NvcGVQYXJlbnQgPSBfLnBhcnRpYWwoX3Bvc3RQYXJlbnQsIHNjb3BlUGFyZW50KTtcblxuXG5fLmV4dGVuZFByb3RvKENvbXBvbmVudEZhY2V0LCB7XG4gICAgaW5pdDogQ29tcG9uZW50RmFjZXQkaW5pdCxcbiAgICBzdGFydDogQ29tcG9uZW50RmFjZXQkc3RhcnQsXG4gICAgY2hlY2s6IENvbXBvbmVudEZhY2V0JGNoZWNrLFxuICAgIGRlc3Ryb3k6IENvbXBvbmVudEZhY2V0JGRlc3Ryb3ksXG4gICAgb25Db25maWdNZXNzYWdlczogQ29tcG9uZW50RmFjZXQkb25Db25maWdNZXNzYWdlcyxcbiAgICBkb21QYXJlbnQ6IGRvbVBhcmVudCxcbiAgICBwb3N0RG9tUGFyZW50OiBwb3N0RG9tUGFyZW50LFxuICAgIHNjb3BlUGFyZW50OiBzY29wZVBhcmVudCxcbiAgICBwb3N0U2NvcGVQYXJlbnQ6IHBvc3RTY29wZVBhcmVudCxcbiAgICBnZXRNZXNzYWdlU291cmNlOiBnZXRNZXNzYWdlU291cmNlLFxuICAgIGRpc3BhdGNoU291cmNlTWVzc2FnZTogZGlzcGF0Y2hTb3VyY2VNZXNzYWdlLFxuICAgIF9jcmVhdGVNZXNzZW5nZXI6IF9jcmVhdGVNZXNzZW5nZXIsXG4gICAgX3NldE1lc3NhZ2VTb3VyY2U6IF9zZXRNZXNzYWdlU291cmNlLFxuICAgIF9jcmVhdGVNZXNzYWdlU291cmNlOiBfY3JlYXRlTWVzc2FnZVNvdXJjZSxcbiAgICBfY3JlYXRlTWVzc2FnZVNvdXJjZVdpdGhBUEk6IF9jcmVhdGVNZXNzYWdlU291cmNlV2l0aEFQSVxufSk7XG5cbl8uZXh0ZW5kKENvbXBvbmVudEZhY2V0LCB7XG4gICAgcmVxdWlyZXNGYWNldDogcmVxdWlyZXNGYWNldFxufSk7XG5cblxuLyoqXG4gKiBFeHBvc2UgTWVzc2VuZ2VyIG1ldGhvZHMgb24gRmFjZXQgcHJvdG90eXBlXG4gKi9cbnZhciBNRVNTRU5HRVJfUFJPUEVSVFkgPSAnX21lc3Nlbmdlcic7XG5NZXNzZW5nZXIudXNlV2l0aChDb21wb25lbnRGYWNldCwgTUVTU0VOR0VSX1BST1BFUlRZLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMpO1xuXG5cbi8vIGluaXRDb21wb25lbnRGYWNldFxuZnVuY3Rpb24gQ29tcG9uZW50RmFjZXQkaW5pdCgpIHtcbiAgICB0aGlzLl9jcmVhdGVNZXNzZW5nZXIoKTtcbn1cblxuXG4vLyBzb21lIHN1YmNsYXNzZXMgKGUuZy4gTW9kZWxGYWNldCkgb3ZlcnJyaWRlIHRoaXMgbWV0aG9kIGFuZCBkbyBub3QgY3JlYXRlIHRoZWlyIG93biBtZXNzZW5nZXJcbmZ1bmN0aW9uIF9jcmVhdGVNZXNzZW5nZXIoKXtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsIE1FU1NFTkdFUl9QUk9QRVJUWSwgbmV3IE1lc3Nlbmdlcih0aGlzKSk7XG59XG5cblxuLy8gc3RhcnRDb21wb25lbnRGYWNldFxuZnVuY3Rpb24gQ29tcG9uZW50RmFjZXQkc3RhcnQoKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm1lc3NhZ2VzKVxuICAgICAgICB0aGlzLm9uQ29uZmlnTWVzc2FnZXModGhpcy5jb25maWcubWVzc2FnZXMpO1xufVxuXG5cbmZ1bmN0aW9uIENvbXBvbmVudEZhY2V0JG9uQ29uZmlnTWVzc2FnZXMobWVzc2FnZVN1YnNjcmliZXJzKSB7XG4gICAgdmFyIG5vdFlldFJlZ2lzdGVyZWRNYXAgPSBfLm1hcEtleXMobWVzc2FnZVN1YnNjcmliZXJzLCBmdW5jdGlvbihzdWJzY3JpYmVyLCBtZXNzYWdlcykge1xuICAgICAgICB2YXIgc3Vic2NyaWJlclR5cGUgPSB0eXBlb2Ygc3Vic2NyaWJlcjtcbiAgICAgICAgaWYgKHN1YnNjcmliZXJUeXBlID09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vbihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG5cbiAgICAgICAgaWYgKHN1YnNjcmliZXJUeXBlID09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB2YXIgY29udGV4dFR5cGUgPSB0eXBlb2Ygc3Vic2NyaWJlci5jb250ZXh0O1xuICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09ICdvYmplY3QnKVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9uKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcblxuICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN1YnNjcmliZXIuY29udGV4dCA9PSB0aGlzLm5hbWUgfHwgc3Vic2NyaWJlci5jb250ZXh0ID09ICdmYWNldCcpXG4gICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyOiBzdWJzY3JpYmVyLnN1YnNjcmliZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoc3Vic2NyaWJlci5jb250ZXh0ID09ICdvd25lcicpXG4gICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyOiBzdWJzY3JpYmVyLnN1YnNjcmliZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLm93bmVyXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRmFjZXRFcnJvcigndW5rbm93biBzdWJzY3JpYmVyIGNvbnRleHQgaW4gY29uZmlndXJhdGlvbjogJyArIHN1YnNjcmliZXIuY29udGV4dCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vbihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRocm93IG5ldyBGYWNldEVycm9yKCd1bmtub3duIHN1YnNjcmliZXIgY29udGV4dCB0eXBlIGluIGNvbmZpZ3VyYXRpb246ICcgKyBjb250ZXh0VHlwZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgRmFjZXRFcnJvcigndW5rbm93biBzdWJzY3JpYmVyIHR5cGUgaW4gY29uZmlndXJhdGlvbjogJyArIHN1YnNjcmliZXJUeXBlKTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiBub3RZZXRSZWdpc3RlcmVkTWFwO1xufVxuXG5cbi8vIGNoZWNrRGVwZW5kZW5jaWVzXG5mdW5jdGlvbiBDb21wb25lbnRGYWNldCRjaGVjaygpIHtcbiAgICBpZiAodGhpcy5yZXF1aXJlKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZS5mb3JFYWNoKGZ1bmN0aW9uKHJlcUZhY2V0KSB7XG4gICAgICAgICAgICBpZiAoISB0aGlzLm93bmVyLmhhc0ZhY2V0KHJlcUZhY2V0KSlcbiAgICAgICAgICAgICAgICB0aGlzLm93bmVyLmFkZEZhY2V0KHJlcUZhY2V0KTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgfVxufVxuXG5cbi8vIGRlc3Ryb3lzIGZhY2V0XG5mdW5jdGlvbiBDb21wb25lbnRGYWNldCRkZXN0cm95KCkge1xuICAgIGlmICh0aGlzW01FU1NFTkdFUl9QUk9QRVJUWV0pIHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXS5kZXN0cm95KCk7XG4gICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIGRvbVBhcmVudFxuICpcbiAqIEByZXR1cm4ge0NvbXBvbmVudEZhY2V0fSByZWZlcmVuY2UgdG8gdGhlIGZhY2V0IG9mIHRoZSBzYW1lIGNsYXNzIG9mIHRoZSBjbG9zZXN0IHBhcmVudCBET00gZWxlbWVudCwgdGhhdCBoYXMgYSBjb21wb25lbnQgd2l0aCB0aGUgc2FtZSBmYWNldCBjbGFzcyBhdHRhY2hlZCB0byBpdC4gSWYgc3VjaCBlbGVtZW50IGRvZXNuJ3QgZXhpc3QgbWV0aG9kIHdpbGwgcmV0dXJuIHVuZGVmaW5lZC5cbiAqL1xuZnVuY3Rpb24gZG9tUGFyZW50KCkge1xuICAgIHZhciBwYXJlbnRDb21wb25lbnQgPSBjb21wb25lbnRVdGlscy5nZXRDb250YWluaW5nQ29tcG9uZW50KHRoaXMub3duZXIuZWwsIGZhbHNlLCB0aGlzLm5hbWUpO1xuICAgIHJldHVybiBwYXJlbnRDb21wb25lbnQgJiYgcGFyZW50Q29tcG9uZW50W3RoaXMubmFtZV07XG59XG5cblxuLyoqXG4gKiBzY29wZVBhcmVudFxuICpcbiAqIEByZXR1cm4ge0NvbXBvbmVudEZhY2V0fSByZWZlcmVuY2UgdG8gdGhlIGZhY2V0IG9mIHRoZSBzYW1lIGNsYXNzIGFzIGB0aGlzYCBmYWNldCBvZiB0aGUgY2xvc2VzdCBzY29wZSBwYXJlbnQgKGkuZS4sIHRoZSBjb21wb25lbnQgdGhhdCBoYXMgdGhlIHNjb3BlIG9mIHRoZSBjdXJyZW50IGNvbXBvbmVudCBpbiBpdHMgY29udGFpbmVyIGZhY2V0KS5cbiAqL1xuZnVuY3Rpb24gc2NvcGVQYXJlbnQoKSB7XG4gICAgdmFyIHBhcmVudENvbXBvbmVudCA9IHRoaXMub3duZXIuZ2V0U2NvcGVQYXJlbnQodGhpcy5uYW1lKTtcbiAgICByZXR1cm4gcGFyZW50Q29tcG9uZW50ICYmIHBhcmVudENvbXBvbmVudFt0aGlzLm5hbWVdO1xufVxuXG5cbmZ1bmN0aW9uIF9wb3N0UGFyZW50KGdldFBhcmVudE1ldGhvZCwgbWVzc2FnZVR5cGUsIG1lc3NhZ2VEYXRhKSB7XG4gICAgdmFyIHBhcmVudEZhY2V0ID0gZ2V0UGFyZW50TWV0aG9kLmNhbGwodGhpcyk7XG4gICAgaWYgKHBhcmVudEZhY2V0KVxuICAgICAgICBwYXJlbnRGYWNldC5wb3N0TWVzc2FnZShtZXNzYWdlVHlwZSwgbWVzc2FnZURhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIF9zZXRNZXNzYWdlU291cmNlKG1lc3NhZ2VTb3VyY2UpIHtcbiAgICB0aGlzW01FU1NFTkdFUl9QUk9QRVJUWV0uX3NldE1lc3NhZ2VTb3VyY2UobWVzc2FnZVNvdXJjZSk7XG59XG5cblxuZnVuY3Rpb24gZ2V0TWVzc2FnZVNvdXJjZSgpIHtcbiAgICByZXR1cm4gdGhpc1tNRVNTRU5HRVJfUFJPUEVSVFldLmdldE1lc3NhZ2VTb3VyY2UoKTtcbn1cblxuXG5mdW5jdGlvbiBkaXNwYXRjaFNvdXJjZU1lc3NhZ2UobWVzc2FnZSwgZGF0YSkge1xuICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2VTb3VyY2UoKS5kaXNwYXRjaE1lc3NhZ2UobWVzc2FnZSwgZGF0YSk7XG59XG5cblxuZnVuY3Rpb24gX2NyZWF0ZU1lc3NhZ2VTb3VyY2UoTWVzc2FnZVNvdXJjZUNsYXNzLCBvcHRpb25zKSB7XG4gICAgdmFyIG1lc3NhZ2VTb3VyY2UgPSBuZXcgTWVzc2FnZVNvdXJjZUNsYXNzKHRoaXMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aGlzLm93bmVyLCBvcHRpb25zKTtcbiAgICB0aGlzLl9zZXRNZXNzYWdlU291cmNlKG1lc3NhZ2VTb3VyY2UpXG5cbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfbWVzc2FnZVNvdXJjZScsIG1lc3NhZ2VTb3VyY2UpO1xufVxuXG5cbmZ1bmN0aW9uIF9jcmVhdGVNZXNzYWdlU291cmNlV2l0aEFQSShNZXNzYWdlU291cmNlQ2xhc3MsIG1lc3NlbmdlckFQSU9yQ2xhc3MsIG9wdGlvbnMpIHtcbiAgICB2YXIgbWVzc2FnZVNvdXJjZSA9IG5ldyBNZXNzYWdlU291cmNlQ2xhc3ModGhpcywgdW5kZWZpbmVkLCBtZXNzZW5nZXJBUElPckNsYXNzLCB0aGlzLm93bmVyLCBvcHRpb25zKTtcbiAgICB0aGlzLl9zZXRNZXNzYWdlU291cmNlKG1lc3NhZ2VTb3VyY2UpXG5cbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfbWVzc2FnZVNvdXJjZScsIG1lc3NhZ2VTb3VyY2UpO1xufVxuXG5cbmZ1bmN0aW9uIHJlcXVpcmVzRmFjZXQoZmFjZXROYW1lKSB7XG4gICAgLy8gJ3RoaXMnIHJlZmVycyB0byB0aGUgRmFjZXQgQ2xhc3NcbiAgICB2YXIgZmFjZXRSZXF1aXJlID0gdGhpcy5wcm90b3R5cGUucmVxdWlyZTtcblxuICAgIHJldHVybiBmYWNldFJlcXVpcmUgJiYgKGZhY2V0UmVxdWlyZS5pbmRleE9mKF8uZmlyc3RVcHBlckNhc2UoZmFjZXROYW1lKSkgPj0gMFxuICAgICAgICAgICAgICAgICAgICAgICAgfHwgZmFjZXRSZXF1aXJlLmluZGV4T2YoXy5maXJzdExvd2VyQ2FzZShmYWNldE5hbWUpKSA+PSAwKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIG1pbG9CaW5kZXIgPSByZXF1aXJlKCcuLi8uLi9iaW5kZXInKVxuICAgICwgU2NvcGUgPSByZXF1aXJlKCcuLi9zY29wZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBkb21VdGlscyA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZG9tJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvbG9nZ2VyJyk7XG5cblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5mYWNldHMuZ2V0KCdDb250YWluZXInKWBcbiAqIEEgc3BlY2lhbCBjb21wb25lbnQgZmFjZXQgdGhhdCBtYWtlcyBjb21wb25lbnQgY3JlYXRlIGl0cyBvd24gaW5uZXIgc2NvcGUuXG4gKiBXaGVuIFttaWxvLmJpbmRlcl0oLi4vLi4vYmluZGVyLmpzLmh0bWwpIGJpbmRzIERPTSB0cmVlIGFuZCBjcmVhdGVzIGNvbXBvbmVudHMsIGlmIGNvbXBvbmVudHMgYXJlIGluc2lkZSBjb21wb25lbnQgV0lUSCBDb250YWluZXIgZmFjZXQsIHRoZXkgYXJlIHB1dCBvbiB0aGUgYHNjb3BlYCBvZiBpdCAoY29tcG9uZW50LmNvbnRhaW5lci5zY29wZSAtIHNlZSBbU2NvcGVdKC4uL3Njb3BlLmpzLmh0bWwpKSwgb3RoZXJ3aXNlIHRoZXkgYXJlIHB1dCBvbiB0aGUgc2FtZSBzY29wZSBldmVuIHRob3VnaCB0aGV5IG1heSBiZSBkZWVwZXIgaW4gRE9NIHRyZWUuXG4gKiBJdCBhbGxvd3MgY3JlYXRpbmcgbmFtZXNwYWNlcyBhdm9pZGluZyBjb21wb25lbnRzIG5hbWVzIGNvbmZsaWN0cywgYXQgdGhlIHNhbWUgdGltZSBjcmVhdGluZyBtb3JlIHNoYWxsb3cgY29tcG9uZW50cyB0cmVlIHRoYW4gdGhlIERPTSB0cmVlLlxuICogVG8gY3JlYXRlIGNvbXBvbmVudHMgZm9yIGVsZW1lbnRzIGluc2lkZSB0aGUgY3VycmVudCBjb21wb25lbnQgdXNlOlxuICogYGBgXG4gKiBjb21wb25lbnQuY29udGFpbmVyLmJpbmRlcigpO1xuICogYGBgXG4gKiBTZWUgW21pbG8uYmluZGVyXSguLi8uLi9iaW5kZXIuanMuaHRtbClcbiAqL1xudmFyIENvbnRhaW5lciA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdDb250YWluZXInKTtcblxuXG4vKipcbiAqICMjIyNDb250YWluZXIgZmFjZXQgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtiaW5kZXJdKCNDb250YWluZXIkYmluZGVyKSAtIGNyZWF0ZSBjb21wb25lbnRzIGZyb20gRE9NIGluc2lkZSB0aGUgY3VycmVudCBvbmVcbiAqL1xuXy5leHRlbmRQcm90byhDb250YWluZXIsIHtcbiAgICBzdGFydDogQ29udGFpbmVyJHN0YXJ0LFxuICAgIHBhdGg6IENvbnRhaW5lciRwYXRoLFxuICAgIGdldFN0YXRlOiBDb250YWluZXIkZ2V0U3RhdGUsXG4gICAgc2V0U3RhdGU6IENvbnRhaW5lciRzZXRTdGF0ZSxcbiAgICBiaW5kZXI6IENvbnRhaW5lciRiaW5kZXIsXG4gICAgZGVzdHJveTogQ29udGFpbmVyJGRlc3Ryb3ksXG4gICAgdW53cmFwOiBDb250YWluZXIkdW53cmFwLFxuXG4gICAgYXBwZW5kOiBDb250YWluZXIkYXBwZW5kLFxuICAgIGluc2VydEJlZm9yZTogQ29udGFpbmVyJGluc2VydEJlZm9yZSxcbiAgICByZW1vdmU6IENvbnRhaW5lciRyZW1vdmVcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoQ29udGFpbmVyKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDb250YWluZXI7XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogU2NhbnMgRE9NLCBjcmVhdGVzIGNvbXBvbmVudHMgYW5kIGFkZHMgdG8gc2NvcGUgY2hpbGRyZW4gb2YgY29tcG9uZW50IGVsZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIENvbnRhaW5lciRiaW5kZXIoKSB7XG4gICAgcmV0dXJuIG1pbG9CaW5kZXIodGhpcy5vd25lci5lbCwgdGhpcy5zY29wZSwgZmFsc2UpO1xufVxuXG5cbi8qKlxuICogQ29udGFpbmVyIGluc3RhbmNlIG1ldGhvZC5cbiAqIFNldHVwIGVtcHR5IHNjb3BlIG9iamVjdCBvbiBzdGFydFxuICovXG5mdW5jdGlvbiBDb250YWluZXIkc3RhcnQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLnN0YXJ0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5zY29wZSA9IG5ldyBTY29wZSh0aGlzLm93bmVyLmVsLCB0aGlzKTtcbn1cblxuXG52YXIgYWxsb3dlZE5hbWVQYXR0ZXJuID0gL15bQS1aYS16XVtBLVphLXowLTlcXF9cXCRdKiQvO1xuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogU2FmZWx5IHRyYXZlcnNlcyBjb21wb25lbnQgc2NvcGVcbiAqIFJldHVybnMgY29tcG9uZW50IGluIHNjb3BlIGZvciBhIGdpdmVuIHBhdGhcbiAqIElmIHBhdGggaXMgaW52YWxpZCB0aGUgbWV0aG9kIHdpbGwgdGhyb3csIGlmIHRoZXJlIGlzIG5vIGNvbXBvbmVudCBhdCBhIGdpdmVuIHBhdGggb3Igc29tZSBvZiB0aGUgY29tcG9uZW50cyBhbG9uZyB0aGUgcGF0aCBkb2VzIG5vdCBoYXZlIENvbnRhaW5lciBmYWNldCB0aGUgbWV0aG9kIHdpbGwgcmV0dXJuIHVuZGVmaW5lZCwgXG4gKiBcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIHBhdGggb2YgY2hpbGQgY29tcG9uZW50IGluIHNjb3BlLCBlYWNoIG5hbWUgc2hvdWxkIGJlIHByZWZpeGVkIHdpdGggJy4nLCBlLmcuOiAnLmNoaWxkLnN1YmNoaWxkJ1xuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBDb250YWluZXIkcGF0aChwYXRoKSB7XG4gICAgcGF0aCA9IHBhdGguc3BsaXQoJy4nKTtcbiAgICB2YXIgbGVuID0gcGF0aC5sZW5ndGg7XG4gICAgaWYgKHBhdGhbMF0gfHwgbGVuIDwgMikgdGhyb3dJbnZhbGlkUGF0aCgpO1xuICAgIHZhciBjb21wID0gdGhpcy5vd25lcjtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBuYW1lID0gcGF0aFtpXTtcbiAgICAgICAgaWYgKCFhbGxvd2VkTmFtZVBhdHRlcm4udGVzdChuYW1lKSkgdGhyb3dJbnZhbGlkUGF0aCgpO1xuICAgICAgICBpZiAoIWNvbXAuY29udGFpbmVyKSByZXR1cm47XG4gICAgICAgIGNvbXAgPSBjb21wLmNvbnRhaW5lci5zY29wZVtuYW1lXTtcbiAgICAgICAgaWYgKCFjb21wKSByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBjb21wO1xuXG4gICAgZnVuY3Rpb24gdGhyb3dJbnZhbGlkUGF0aCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwYXRoICcgKyBwYXRoICsgJyBpcyBpbnZhbGlkJyk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogQ29udGFpbmVyIGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IGBDb21wb25lbnQucHJvdG90eXBlLmdldFN0YXRlYCB0byBnZXQgZmFjZXQncyBzdGF0ZVxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgY29tcG9uZW50cyBpbiB0aGUgc2NvcGVcbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRlZXBDb3B5IHRydWUgYnkgZGVmYXVsdFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBDb250YWluZXIkZ2V0U3RhdGUoZGVlcENvcHkpIHtcbiAgICB2YXIgc3RhdGUgPSB7IHNjb3BlOiB7fSB9O1xuICAgIGlmIChkZWVwQ29weSAhPT0gZmFsc2UpXG4gICAgICAgIHRoaXMuc2NvcGUuX2VhY2goZnVuY3Rpb24oY29tcG9uZW50LCBjb21wTmFtZSkge1xuICAgICAgICAgICAgc3RhdGUuc2NvcGVbY29tcE5hbWVdID0gY29tcG9uZW50Ll9nZXRTdGF0ZSgpO1xuICAgICAgICB9KTtcbiAgICByZXR1cm4gc3RhdGU7XG59XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBDYWxsZWQgYnkgYENvbXBvbmVudC5wcm90b3R5cGUuc2V0U3RhdGVgIHRvIHNldCBmYWNldCdzIHN0YXRlXG4gKiBTZXRzIHRoZSBzdGF0ZSBvZiBjb21wb25lbnRzIGluIHRoZSBzY29wZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIGRhdGEgdG8gc2V0IG9uIGZhY2V0J3MgbW9kZWxcbiAqL1xuZnVuY3Rpb24gQ29udGFpbmVyJHNldFN0YXRlKHN0YXRlKSB7XG4gICAgXy5lYWNoS2V5KHN0YXRlLnNjb3BlLCBmdW5jdGlvbihjb21wRGF0YSwgY29tcE5hbWUpIHtcbiAgICAgICAgdmFyIGNvbXBvbmVudCA9IHRoaXMuc2NvcGVbY29tcE5hbWVdO1xuICAgICAgICBpZiAoY29tcG9uZW50KVxuICAgICAgICAgICAgY29tcG9uZW50LnNldFN0YXRlKGNvbXBEYXRhKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ2NvbXBvbmVudCBcIicgKyBjb21wTmFtZSArICdcIiBkb2VzIG5vdCBleGlzdCBvbiBzY29wZScpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5mdW5jdGlvbiBDb250YWluZXIkZGVzdHJveSgpIHtcbiAgICB0aGlzLnNjb3BlLl9lYWNoKGZ1bmN0aW9uKGNvbXBvbmVudCkge1xuICAgICAgICBjb21wb25lbnQuZGVzdHJveSgpO1xuICAgIH0pO1xuICAgIHRoaXMuc2NvcGUuX2RldGFjaEVsZW1lbnQoKTtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogQ29udGFpbmVyIGluc3RhbmNlIG1ldGhvZFxuICogTW92ZXMgYWxsIG9mIHRoZSBjb250ZW50cyBvZiB0aGUgb3duZXIgaW50byB0aGUgcGFyZW50IHNjb3BlXG4gKiBcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVuYW1lQ2hpbGRyZW4gcGFzcyBmYWxzZSB0byBub3QgcmVuYW1lIHNjb3BlIGNoaWxkcmVuIChkZWZhdWx0IGlzIHRydWUpXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRlc3Ryb3kgSWYgbm90IGZhbHNlLCB0aGUgY29tcG9uZW50IHdpbGwgYmUgZGVzdHJveWVkIGF0IHRoZSBlbmQgKGRlZmF1bHQgaXMgdHJ1ZSkuXG4gKi9cbmZ1bmN0aW9uIENvbnRhaW5lciR1bndyYXAocmVuYW1lQ2hpbGRyZW4sIGRlc3Ryb3kpIHtcbiAgICBkb21VdGlscy51bndyYXBFbGVtZW50KHRoaXMub3duZXIuZWwpO1xuICAgIHRoaXMuc2NvcGUgJiYgdGhpcy5zY29wZS5fZWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgY2hpbGQucmVtb3ZlKCk7XG4gICAgICAgIGlmIChyZW5hbWVDaGlsZHJlbiAhPT0gZmFsc2UpIGNoaWxkLnJlbmFtZSh1bmRlZmluZWQsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5vd25lci5zY29wZSAmJiB0aGlzLm93bmVyLnNjb3BlLl9hZGQoY2hpbGQpO1xuICAgIH0sIHRoaXMpO1xuICAgIGlmIChkZXN0cm95ICE9PSBmYWxzZSkgdGhpcy5vd25lci5kZXN0cm95KCk7XG59XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBBcHBlbmQgY29tcG9uZW50IHRvIERPTSBhbmQgdG8gc2NvcGVcbiAqIEBwYXJhbSB7Q29tcG9uZW50fSBjb21wIGNvbXBvbmVudCB0aGF0IHdpbGwgYmUgYXBwZW5kZWRcbiAqL1xuZnVuY3Rpb24gQ29udGFpbmVyJGFwcGVuZChjb21wKSB7XG4gICAgdGhpcy5zY29wZS5fYWRkKGNvbXApO1xuICAgIHRoaXMub3duZXIuZWwuYXBwZW5kQ2hpbGQoY29tcC5lbCk7XG59XG5cblxuLyoqXG4gKiBDb250YWluZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbnNlcnQgY29tcG9uZW50IHRvIERPTSBhbmQgdG8gc2NvcGUgYmVmb3JlIGFub3RoZXIgY29tcG9uZW50XG4gKiBAcGFyYW0ge0NvbXBvbmVudH0gY29tcCBjb21wb25lbnQgdGhhdCB3aWxsIGJlIGluc2VydGVkXG4gKiBAcGFyYW0ge0NvbXBvbmVudH0gc2libGluZyBjb21wb25lbnQgYmVmb3JlIHdoaWNoIGNvbXBvbmVudCB3aWxsIGJlIGFwcGVuZGVkXG4gKi9cbmZ1bmN0aW9uIENvbnRhaW5lciRpbnNlcnRCZWZvcmUoY29tcCwgc2libGluZykge1xuICAgIHRoaXMuc2NvcGUuX2FkZChjb21wKTtcbiAgICB0aGlzLmVsLmluc2VydEJlZm9yZShjb21wLmVsLCBzaWJsaW5nICYmIHNpYmxpbmcuZWwpO1xufVxuXG5mdW5jdGlvbiBDb250YWluZXIkcmVtb3ZlKGNvbXApIHtcbiAgICB0aGlzLnNjb3BlLl9yZW1vdmUoY29tcCk7XG4gICAgdGhpcy5vd25lci5lbC5yZW1vdmVDaGlsZChjb21wLmVsKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1peGluID0gcmVxdWlyZSgnLi4vLi4vYWJzdHJhY3QvbWl4aW4nKVxuICAgICwgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG5cbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uLy4uL21lc3NlbmdlcicpXG4gICAgLCBET01FdmVudHNTb3VyY2UgPSByZXF1aXJlKCcuLi9tc2dfc3JjL2RvbV9ldmVudHMnKVxuICAgICwgRGF0YU1zZ0FQSSA9IHJlcXVpcmUoJy4uL21zZ19hcGkvZGF0YScpXG4gICAgLCBnZXRFbGVtZW50RGF0YUFjY2VzcyA9IHJlcXVpcmUoJy4uL21zZ19hcGkvZGVfZGF0YScpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuLi8uLi9tb2RlbC9wYXRoX3V0aWxzJylcbiAgICAsIE1vZGVsUGF0aCA9IHJlcXVpcmUoJy4uLy4uL21vZGVsL21fcGF0aCcpXG4gICAgLCBtb2RlbFV0aWxzID0gcmVxdWlyZSgnLi4vLi4vbW9kZWwvbW9kZWxfdXRpbHMnKVxuICAgICwgY2hhbmdlRGF0YUhhbmRsZXIgPSByZXF1aXJlKCcuLi8uLi9tb2RlbC9jaGFuZ2VfZGF0YScpXG4gICAgLCBnZXRUcmFuc2FjdGlvbkZsYWcgPSBjaGFuZ2VEYXRhSGFuZGxlci5nZXRUcmFuc2FjdGlvbkZsYWdcbiAgICAsIHNldFRyYW5zYWN0aW9uRmxhZyA9IGNoYW5nZURhdGFIYW5kbGVyLnNldFRyYW5zYWN0aW9uRmxhZ1xuICAgICwgcG9zdFRyYW5zYWN0aW9uRmluaXNoZWQgPSBjaGFuZ2VEYXRhSGFuZGxlci5wb3N0VHJhbnNhY3Rpb25GaW5pc2hlZFxuXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvbG9nZ2VyJyk7XG5cblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5mYWNldHMuZ2V0KCdEYXRhJylgXG4gKiBGYWNldCB0byBnaXZlIGFjY2VzcyB0byBET00gZGF0YVxuICovXG52YXIgRGF0YSA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdEYXRhJyk7XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZHNcbiAqXG4gKiAtIFtzdGFydF0oI0RhdGEkc3RhcnQpIC0gc3RhcnQgRGF0YSBmYWNldFxuICogLSBbZ2V0XSgjRGF0YSRnZXQpIC0gZ2V0IERPTSBkYXRhIGZyb20gRE9NIHRyZWVcbiAqIC0gW3NldF0oI0RhdGEkc2V0KSAtIHNldCBET00gZGF0YSB0byBET00gdHJlZVxuICogLSBbcGF0aF0oI0RhdGEkcGF0aCkgLSBnZXQgcmVmZXJlbmNlIHRvIERhdGEgZmFjZXQgYnkgcGF0aFxuICovXG5fLmV4dGVuZFByb3RvKERhdGEsIHtcbiAgICBzdGFydDogRGF0YSRzdGFydCxcbiAgICBnZXRTdGF0ZTogRGF0YSRnZXRTdGF0ZSxcbiAgICBzZXRTdGF0ZTogRGF0YSRzZXRTdGF0ZSxcblxuICAgIGdldDogRGF0YSRnZXQsXG4gICAgc2V0OiBEYXRhJHNldCxcbiAgICBkZWw6IERhdGEkZGVsLFxuICAgIHNwbGljZTogRGF0YSRzcGxpY2UsXG4gICAgbGVuOiBEYXRhJGxlbixcbiAgICBwYXRoOiBEYXRhJHBhdGgsXG4gICAgZ2V0UGF0aDogRGF0YSRnZXRQYXRoLFxuICAgIGdldEtleTogRGF0YSRnZXRLZXksXG5cbiAgICBfZ2V0OiBEYXRhJF9nZXQsXG4gICAgX3NldDogRGF0YSRfc2V0LFxuICAgIF9kZWw6IERhdGEkX2RlbCxcbiAgICBfc3BsaWNlOiBEYXRhJF9zcGxpY2UsXG4gICAgX2xlbjogRGF0YSRfbGVuLFxuXG4gICAgX3NldFNjYWxhclZhbHVlOiBEYXRhJF9zZXRTY2FsYXJWYWx1ZSxcbiAgICBfZ2V0U2NhbGFyVmFsdWU6IERhdGEkX2dldFNjYWxhclZhbHVlLFxuICAgIF9idWJibGVVcERhdGFDaGFuZ2U6IERhdGEkX2J1YmJsZVVwRGF0YUNoYW5nZSxcbiAgICBfcXVldWVEYXRhQ2hhbmdlOiBEYXRhJF9xdWV1ZURhdGFDaGFuZ2UsXG4gICAgX3Bvc3REYXRhQ2hhbmdlczogRGF0YSRfcG9zdERhdGFDaGFuZ2VzLFxuICAgIF9wcmVwYXJlTWVzc2FnZVNvdXJjZTogX3ByZXBhcmVNZXNzYWdlU291cmNlXG59KTtcblxuZmFjZXRzUmVnaXN0cnkuYWRkKERhdGEpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IERhdGE7XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggbWV0aG9kcyBhZGRlZCB0byBEYXRhIHByb3RvdHlwZVxuICovXG5bJ3B1c2gnLCAncG9wJywgJ3Vuc2hpZnQnLCAnc2hpZnQnXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICB2YXIgbWV0aG9kID0gTW9kZWxQYXRoLnByb3RvdHlwZVttZXRob2ROYW1lXTtcbiAgICBfLmRlZmluZVByb3BlcnR5KERhdGEucHJvdG90eXBlLCBtZXRob2ROYW1lLCBtZXRob2QpO1xufSk7XG5cblxuXG4vLyB0aGVzZSBtZXRob2RzIHdpbGwgYmUgd3JhcHBlZCB0byBzdXBwb3J0IFwiKlwiIHBhdHRlcm4gc3Vic2NyaXB0aW9uc1xudmFyIHByb3h5RGF0YVNvdXJjZU1ldGhvZHMgPSB7XG4gICAgICAgIC8vIHZhbHVlOiAndmFsdWUnLFxuICAgICAgICB0cmlnZ2VyOiAndHJpZ2dlcidcbiAgICB9O1xuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFN0YXJ0cyBEYXRhIGZhY2V0XG4gKiBDYWxsZWQgYnkgY29tcG9uZW50IGFmdGVyIGNvbXBvbmVudCBpcyBpbml0aWFsaXplZC5cbiAqL1xuZnVuY3Rpb24gRGF0YSRzdGFydCgpIHtcbiAgICAvLyBjaGFuZ2UgbWVzc2VuZ2VyIG1ldGhvZHMgdG8gd29yayB3aXRoIFwiKlwiIHN1YnNjcmlwdGlvbnMgKGxpa2UgTW9kZWwgY2xhc3MpXG4gICAgcGF0aFV0aWxzLndyYXBNZXNzZW5nZXJNZXRob2RzLmNhbGwodGhpcyk7XG5cbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuc3RhcnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIGdldC9zZXQgbWV0aG9kcyB0byBzZXQgZGF0YSBvZiBlbGVtZW50XG4gICAgdGhpcy5lbERhdGEgPSBnZXRFbGVtZW50RGF0YUFjY2Vzcyh0aGlzLm93bmVyLmVsKTtcblxuICAgIHRoaXMuX2RhdGFDaGFuZ2VzUXVldWUgPSBbXTtcblxuICAgIHRoaXMuX3ByZXBhcmVNZXNzYWdlU291cmNlKCk7XG5cbiAgICAvLyBzdG9yZSBmYWNldCBkYXRhIHBhdGhcbiAgICB0aGlzLl9wYXRoID0gJy4nICsgdGhpcy5vd25lci5uYW1lO1xuXG4gICAgLy8gY3VycmVudCB2YWx1ZVxuICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5nZXQoKTtcblxuICAgIC8vIHByZXBhcmUgaW50ZXJuYWwgYW5kIGV4dGVybmFsIG1lc3NlbmdlcnNcbiAgICAvLyB0aGlzLl9wcmVwYXJlTWVzc2VuZ2VycygpO1xuXG4gICAgLy8gc3Vic2NyaWJlIHRvIERPTSBldmVudCBhbmQgYWNjZXNzb3JzJyBtZXNzYWdlc1xuICAgIHRoaXMub25TeW5jKCcnLCBvbk93bkRhdGFDaGFuZ2UpO1xuXG4gICAgLy8gbWVzc2FnZSB0byBtYXJrIHRoZSBlbmQgb2YgYmF0Y2ggb24gdGhlIGN1cnJlbnQgbGV2ZWxcbiAgICB0aGlzLm9uU3luYygnZGF0YWNoYW5nZXNmaW5pc2hlZCcsIG9uRGF0YUNoYW5nZXNGaW5pc2hlZCk7XG5cbiAgICAvLyBjaGFuZ2VzIGluIHNjb3BlIGNoaWxkcmVuIHdpdGggRGF0YSBmYWNldFxuICAgIHRoaXMub25TeW5jKCdjaGlsZGRhdGEnLCBvbkNoaWxkRGF0YSk7XG5cbiAgICAvLyB0byBlbmFibGUgcmVhY3RpdmUgY29ubmVjdGlvbnNcbiAgICB0aGlzLm9uU3luYygnY2hhbmdlZGF0YScsIGNoYW5nZURhdGFIYW5kbGVyKTtcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBDcmVhdGUgYW5kIGNvbm5lY3QgaW50ZXJuYWwgYW5kIGV4dGVybmFsIG1lc3NlbmdlcnMgb2YgRGF0YSBmYWNldC5cbiAqIEV4dGVybmFsIG1lc3NlbmdlcidzIG1ldGhvZHMgYXJlIHByb3hpZWQgb24gdGhlIERhdGEgZmFjZXQgYW5kIHRoZXkgYWxsb3dzIFwiKlwiIHN1YnNjcmlwdGlvbnMuXG4gKi9cbi8vIGZ1bmN0aW9uIF9wcmVwYXJlTWVzc2VuZ2VycygpIHtcbiAgICAvLyBEYXRhIGZhY2V0IHdpbGwgcG9zdCBhbGwgaXRzIGNoYW5nZXMgb24gaW50ZXJuYWwgbWVzc2VuZ2VyXG4gICAgLy8gdmFyIGludGVybmFsTWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzKTtcblxuICAgIC8vIG1lc3NhZ2Ugc291cmNlIHRvIGNvbm5lY3QgaW50ZXJuYWwgbWVzc2VuZ2VyIHRvIGV4dGVybmFsXG4gICAgLy8gdmFyIGludGVybmFsTWVzc2VuZ2VyU291cmNlID0gbmV3IE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UodGhpcywgdW5kZWZpbmVkLCBuZXcgTW9kZWxNc2dBUEksIGludGVybmFsTWVzc2VuZ2VyKTtcblxuICAgIC8vIGV4dGVybmFsIG1lc3NlbmdlciB0byB3aGljaCBhbGwgbW9kZWwgdXNlcnMgd2lsbCBzdWJzY3JpYmUsXG4gICAgLy8gdGhhdCB3aWxsIGFsbG93IFwiKlwiIHN1YnNjcmlwdGlvbnMgYW5kIHN1cHBvcnQgXCJjaGFuZ2VkYXRhXCIgbWVzc2FnZSBhcGkuXG4gICAgLy8gdmFyIGV4dGVybmFsTWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMsIGludGVybmFsTWVzc2VuZ2VyU291cmNlKTtcblxuLy8gICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4vLyAgICAgICAgIF9tZXNzZW5nZXI6IGV4dGVybmFsTWVzc2VuZ2VyLFxuLy8gICAgICAgICBfaW50ZXJuYWxNZXNzZW5nZXI6IGludGVybmFsTWVzc2VuZ2VyXG4vLyAgICAgfSk7XG4vLyB9XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogSW5pdGlhbGl6ZXMgRE9NRXZlbnRzU291cmNlIGFuZCBjb25uZWN0cyBpdCB0byBEYXRhIGZhY2V0IG1lc3NlbmdlclxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIF9wcmVwYXJlTWVzc2FnZVNvdXJjZSgpIHtcbiAgICB2YXIgZGF0YUFQSSA9IG5ldyBEYXRhTXNnQVBJKHRoaXMub3duZXIpXG4gICAgICAgICwgZGF0YUV2ZW50c1NvdXJjZSA9IG5ldyBET01FdmVudHNTb3VyY2UodGhpcywgcHJveHlEYXRhU291cmNlTWV0aG9kcywgZGF0YUFQSSwgdGhpcy5vd25lcik7XG4gICAgdGhpcy5fc2V0TWVzc2FnZVNvdXJjZShkYXRhRXZlbnRzU291cmNlKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19kYXRhRXZlbnRzU291cmNlJywgZGF0YUV2ZW50c1NvdXJjZSk7XG5cbiAgICAvLyBtYWtlIHZhbHVlIG1ldGhvZCBvZiBEYXRhTXNnQVBJIGF2YWlsYWJsZSBvbiBEYXRhIGZhY2V0XG4gICAgLy8gdGhpcyBpcyBhIHByaXZhdGUgbWV0aG9kLCBnZXQoKSBzaG91bGQgYmUgdXNlZCB0byBnZXQgZGF0YS5cbiAgICBNaXhpbi5wcm90b3R5cGUuX2NyZWF0ZVByb3h5TWV0aG9kLmNhbGwoZGF0YUFQSSwgJ3ZhbHVlJywgJ3ZhbHVlJywgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBTdWJzY3JpYmVyIHRvIGRhdGEgY2hhbmdlIGV2ZW50XG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2dUeXBlIGluIHRoaXMgaW5zdGFuY2Ugd2lsbCBiZSAnJ1xuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgZGF0YSBjaGFuZ2UgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gb25Pd25EYXRhQ2hhbmdlKG1zZ1R5cGUsIGRhdGEpIHtcbiAgICB0aGlzLl9idWJibGVVcERhdGFDaGFuZ2UoZGF0YSk7XG4gICAgdGhpcy5fcXVldWVEYXRhQ2hhbmdlKGRhdGEpO1xuICAgIGlmIChkYXRhLnBhdGggPT09ICcnKSB7XG4gICAgICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKGRhdGEpO1xuICAgICAgICB0aGlzLnBvc3RNZXNzYWdlKCdkYXRhY2hhbmdlc2ZpbmlzaGVkJywgeyB0cmFuc2FjdGlvbjogaW5UcmFuc2FjdGlvbiB9KTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU2VuZHMgZGF0YSBgbWVzc2FnZWAgdG8gRE9NIHBhcmVudFxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gbXNnRGF0YSBkYXRhIGNoYW5nZSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIERhdGEkX2J1YmJsZVVwRGF0YUNoYW5nZShtc2dEYXRhKSB7XG4gICAgdmFyIHBhcmVudERhdGEgPSB0aGlzLnNjb3BlUGFyZW50KCk7XG5cbiAgICBpZiAocGFyZW50RGF0YSkge1xuICAgICAgICB2YXIgcGFyZW50TXNnID0gXy5jbG9uZShtc2dEYXRhKTtcbiAgICAgICAgcGFyZW50TXNnLnBhdGggPSAodGhpcy5fcGF0aCB8fCAoJy4nICsgdGhpcy5vd25lci5uYW1lKSkgICsgcGFyZW50TXNnLnBhdGg7XG4gICAgICAgIHBhcmVudERhdGEucG9zdE1lc3NhZ2UoJ2NoaWxkZGF0YScsIHBhcmVudE1zZyB8fCBtc2dEYXRhKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUXVldWVzIGRhdGEgbWVzc2FnZXMgdG8gYmUgZGlzcGF0Y2hlZCB0byBjb25uZWN0b3JcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGNoYW5nZSBkYXRhIGNoYW5nZSBkZXNjcmlwdGlvblxuICovXG5mdW5jdGlvbiBEYXRhJF9xdWV1ZURhdGFDaGFuZ2UoY2hhbmdlKSB7XG4gICAgdGhpcy5fZGF0YUNoYW5nZXNRdWV1ZS5wdXNoKGNoYW5nZSk7XG59XG5cblxuLyoqXG4gKiBTdWJzY3JpYmVyIHRvIGRhdGFjaGFuZ2VzZmluaXNoZWQgZXZlbnQuXG4gKiBDYWxscyB0aGUgbWV0aG9kIHRvIHBvc3QgY2hhbmdlcyBiYXRjaCBhbmQgYnViYmxlcyB1cCB0aGUgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSAge1t0eXBlXX0gbXNnICBbZGVzY3JpcHRpb25dXG4gKiBAcGFyYW0gIHtbdHlwZV19IGRhdGEgW2Rlc2NyaXB0aW9uXVxuICovXG5mdW5jdGlvbiBvbkRhdGFDaGFuZ2VzRmluaXNoZWQobXNnLCBkYXRhKSB7XG4gICAgdGhpcy5fcG9zdERhdGFDaGFuZ2VzKGRhdGEuaW5UcmFuc2FjdGlvbik7XG4gICAgdmFyIHBhcmVudERhdGEgPSB0aGlzLnNjb3BlUGFyZW50KCk7XG4gICAgaWYgKHBhcmVudERhdGEpIHBhcmVudERhdGEucG9zdE1lc3NhZ2UoJ2RhdGFjaGFuZ2VzZmluaXNoZWQnLCBkYXRhKTtcbn1cblxuXG4vKipcbiAqIERpc3BhdGNoZXMgYWxsIGNoYW5nZXMgY29sbGVjdGVkIGluIHRoZSBiYXRjaFxuICogVXNlZCBmb3IgZGF0YSBwcm9wYWdhdGlvbiAtIGNvbm5lY3RvciBzdWJzY3JpYmVzIHRvIHRoaXMgbWVzc2FnZVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIERhdGEkX3Bvc3REYXRhQ2hhbmdlcyhpblRyYW5zYWN0aW9uKSB7XG4gICAgdmFyIHF1ZXVlID0gdGhpcy5fZGF0YUNoYW5nZXNRdWV1ZS5yZXZlcnNlKCk7XG4gICAgdGhpcy5wb3N0TWVzc2FnZVN5bmMoJ2RhdGFjaGFuZ2VzJywge1xuICAgICAgICBjaGFuZ2VzOiBxdWV1ZSxcbiAgICAgICAgdHJhbnNhY3Rpb246IGluVHJhbnNhY3Rpb25cbiAgICB9KTtcbiAgICB0aGlzLl9kYXRhQ2hhbmdlc1F1ZXVlID0gW107IC8vIGl0IGNhbid0IGJlIC5sZW5ndGggPSAwLCBhcyB0aGUgYWN0dWFsIGFycmF5IG1heSBzdGlsbCBiZSB1c2VkXG59XG5cblxuLyoqXG4gKiBTdWJzY3JpYmVyIHRvIGRhdGEgY2hhbmdlIGV2ZW50IGluIGNoaWxkIERhdGEgZmFjZXRcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZ1R5cGVcbiAqIEBwYXJhbSB7T2JlamN0fSBkYXRhIGRhdGEgY2hhbmdlIGluZm9ybWF0aW9uXG4gKi9cbmZ1bmN0aW9uIG9uQ2hpbGREYXRhKG1zZ1R5cGUsIGRhdGEpIHtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKGRhdGEucGF0aCwgZGF0YSk7XG4gICAgdGhpcy5fYnViYmxlVXBEYXRhQ2hhbmdlKGRhdGEpO1xuICAgIHRoaXMuX3F1ZXVlRGF0YUNoYW5nZShkYXRhKTtcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIGRhdGEgaW4gRE9NIGhpZXJhcmNoeSByZWN1cnNpdmVseS5cbiAqIFJldHVybnMgdGhlIG9iamVjdCB3aXRoIHRoZSBkYXRhIGFjdHVhbGx5IHNldCAoY2FuIGJlIGRpZmZlcmVudCwgaWYgY29tcG9uZW50cyBtYXRjaGluZyBzb21lIHByb3BlcnRpZXMgYXJlIG1pc3NpbmcpLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ3xOdW1iZXJ9IHZhbHVlIHZhbHVlIHRvIGJlIHNldC4gSWYgdGhlIHZhbHVlIGlmIHNjYWxhciwgaXQgd2lsbCBiZSBzZXQgb24gY29tcG9uZW50J3MgZWxlbWVudCwgaWYgdGhlIHZhbHVlIGlzIG9iamVjdCAtIG9uIERPTSB0cmVlIGluc2lkZSBjb21wb25lbnRcbiAqIEByZXR1cm4ge09iamVjdHxTdHJpbmd8TnVtYmVyfVxuICovXG5mdW5jdGlvbiBEYXRhJHNldCh2YWx1ZSkge1xuICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKERhdGEkc2V0KTtcblxuICAgIHZhciBjb21wb25lbnRTZXR0ZXIgPSB0aGlzLmNvbmZpZy5zZXQ7XG4gICAgaWYgKHR5cGVvZiBjb21wb25lbnRTZXR0ZXIgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gY29tcG9uZW50U2V0dGVyLmNhbGwodGhpcy5vd25lciwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHNldFRyYW5zYWN0aW9uRmxhZyh0aGlzLl9zZXQsIGluVHJhbnNhY3Rpb24pO1xuXG4gICAgdmFyIG9sZFZhbHVlID0gdGhpcy5fdmFsdWVcbiAgICAgICAgLCBuZXdWYWx1ZSA9IHRoaXMuX3NldCh2YWx1ZSk7XG5cbiAgICAvLyB0aGlzIG1lc3NhZ2UgdHJpZ2dlcnMgb25Pd25EYXRhQ2hhbmdlLCBhcyB3ZWxsIGFzIGFjdHVhbGwgRE9NIGNoYW5nZVxuICAgIC8vIHNvIHRoZSBwYXJlbnQgZ2V0cyBub3RpZmllZFxuICAgIHZhciBtc2cgPSB7IHBhdGg6ICcnLCB0eXBlOiAnY2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgbmV3VmFsdWU6IG5ld1ZhbHVlLCBvbGRWYWx1ZTogb2xkVmFsdWUgfTtcbiAgICBzZXRUcmFuc2FjdGlvbkZsYWcobXNnLCBpblRyYW5zYWN0aW9uKTtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKCcnLCBtc2cpO1xuXG4gICAgcmV0dXJuIG5ld1ZhbHVlO1xufVxuXG5cbmZ1bmN0aW9uIERhdGEkX3NldCh2YWx1ZSkge1xuICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKERhdGEkX3NldCk7XG5cbiAgICB2YXIgdmFsdWVTZXQ7XG4gICAgaWYgKHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgdmFsdWVTZXQgPSBbXTtcblxuICAgICAgICAgICAgdmFyIGxpc3RGYWNldCA9IHRoaXMub3duZXIubGlzdDtcbiAgICAgICAgICAgIGlmIChsaXN0RmFjZXQpe1xuICAgICAgICAgICAgICAgIHZhciBsaXN0TGVuZ3RoID0gbGlzdEZhY2V0LmNvdW50KClcbiAgICAgICAgICAgICAgICAgICAgLCBuZXdJdGVtc0NvdW50ID0gdmFsdWUubGVuZ3RoIC0gbGlzdExlbmd0aDtcbiAgICAgICAgICAgICAgICBpZiAobmV3SXRlbXNDb3VudCA+PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RGYWNldC5fYWRkSXRlbXMobmV3SXRlbXNDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RGYWNldC5fdXBkYXRlRGF0YVBhdGhzKGxpc3RMZW5ndGgsIGxpc3RGYWNldC5jb3VudCgpKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkVmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHNldENoaWxkRGF0YS5jYWxsKHRoaXMsIHZhbHVlU2V0LCBjaGlsZFZhbHVlLCBpbmRleCwgJ1skJF0nKTtcbiAgICAgICAgICAgICAgICB9LCB0aGlzKTtcblxuICAgICAgICAgICAgICAgIHZhciBsaXN0Q291bnQgPSBsaXN0RmFjZXQuY291bnQoKVxuICAgICAgICAgICAgICAgICAgICAsIHJlbW92ZUNvdW50ID0gbGlzdENvdW50IC0gdmFsdWUubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgd2hpbGUgKHJlbW92ZUNvdW50LS0gPiAwKVxuICAgICAgICAgICAgICAgICAgICBsaXN0RmFjZXQuX3JlbW92ZUl0ZW0odmFsdWUubGVuZ3RoKTtcbiAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdEYXRhOiBzZXR0aW5nIGFycmF5IGRhdGEgd2l0aG91dCBMaXN0IGZhY2V0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZVNldCA9IHt9O1xuICAgICAgICAgICAgXy5lYWNoS2V5KHZhbHVlLCBmdW5jdGlvbihjaGlsZFZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgICAgICBzZXRDaGlsZERhdGEuY2FsbCh0aGlzLCB2YWx1ZVNldCwgY2hpbGRWYWx1ZSwga2V5LCAnLiQkJyk7XG4gICAgICAgICAgICB9LCB0aGlzKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZVxuICAgICAgICB2YWx1ZVNldCA9IHRoaXMuX3NldFNjYWxhclZhbHVlKHZhbHVlKTtcblxuICAgIHRoaXMuX3ZhbHVlID0gdmFsdWVTZXQ7XG5cbiAgICByZXR1cm4gdmFsdWVTZXQ7XG5cblxuICAgIGZ1bmN0aW9uIHNldENoaWxkRGF0YSh2YWx1ZVNldCwgY2hpbGRWYWx1ZSwga2V5LCBwYXRoU3ludGF4KSB7XG4gICAgICAgIHZhciBjaGlsZFBhdGggPSBwYXRoU3ludGF4LnJlcGxhY2UoJyQkJywga2V5KTtcbiAgICAgICAgdmFyIGNoaWxkRGF0YUZhY2V0ID0gdGhpcy5wYXRoKGNoaWxkUGF0aCwgdHlwZW9mIGNoaWxkVmFsdWUgIT0gJ3VuZGVmaW5lZCcpO1xuICAgICAgICBpZiAoY2hpbGREYXRhRmFjZXQpIHtcbiAgICAgICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZyhjaGlsZERhdGFGYWNldC5zZXQsIGluVHJhbnNhY3Rpb24pO1xuICAgICAgICAgICAgdmFsdWVTZXRba2V5XSA9IGNoaWxkRGF0YUZhY2V0LnNldChjaGlsZFZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBEZWxldGVzIGNvbXBvbmVudCBmcm9tIHZpZXcgYW5kIHNjb3BlLCBvbmx5IGluIGNhc2UgaXQgaGFzIEl0ZW0gZmFjZXQgb24gaXRcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbHVlIHZhbHVlIHRvIHNldCB0byBET00gZWxlbWVudFxuICovXG5mdW5jdGlvbiBEYXRhJGRlbCgpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGdldFRyYW5zYWN0aW9uRmxhZyhEYXRhJGRlbCk7XG5cbiAgICB2YXIgY29tcG9uZW50RGVsZXRlID0gdGhpcy5jb25maWcuZGVsO1xuICAgIGlmICh0eXBlb2YgY29tcG9uZW50RGVsZXRlID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGNvbXBvbmVudERlbGV0ZS5jYWxsKHRoaXMub3duZXIpO1xuICAgICAgICBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZC5jYWxsKHRoaXMsIGluVHJhbnNhY3Rpb24pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHZhciBvbGRWYWx1ZSA9IHRoaXMuX3ZhbHVlO1xuXG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKHRoaXMuX2RlbCwgaW5UcmFuc2FjdGlvbik7XG4gICAgdGhpcy5fZGVsKCk7XG5cbiAgICAvLyB0aGlzIG1lc3NhZ2UgdHJpZ2dlcnMgb25Pd25EYXRhQ2hhbmdlLCBhcyB3ZWxsIGFzIGFjdHVhbGwgRE9NIGNoYW5nZVxuICAgIC8vIHNvIHRoZSBwYXJlbnQgZ2V0cyBub3RpZmllZFxuICAgIHZhciBtc2cgPSB7IHBhdGg6ICcnLCB0eXBlOiAnZGVsZXRlZCcsIG9sZFZhbHVlOiBvbGRWYWx1ZSB9O1xuICAgIHNldFRyYW5zYWN0aW9uRmxhZyhtc2csIGluVHJhbnNhY3Rpb24pO1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoJycsIG1zZyk7XG59XG5cblxuZnVuY3Rpb24gRGF0YSRfZGVsKCkge1xuICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKERhdGEkX2RlbCk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKHRoaXMuX3NldCwgaW5UcmFuc2FjdGlvbik7XG4gICAgdGhpcy5fc2V0KCk7XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU2V0cyBzY2FsYXIgdmFsdWUgdG8gRE9NIGVsZW1lbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWx1ZSB2YWx1ZSB0byBzZXQgdG8gRE9NIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gRGF0YSRfc2V0U2NhbGFyVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5lbERhdGEuc2V0KHRoaXMub3duZXIuZWwsIHZhbHVlKTtcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBHZXQgc3RydWN0dXJlZCBkYXRhIGZyb20gRE9NIGhpZXJhcmNoeSByZWN1cnNpdmVseVxuICogUmV0dXJucyBET00gZGF0YVxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVlcEdldCB0cnVlIGJ5IGRlZmF1bHRcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gRGF0YSRnZXQoZGVlcEdldCkge1xuICAgIHZhciBjb21wb25lbnRHZXR0ZXIgPSB0aGlzLmNvbmZpZy5nZXQ7XG4gICAgaWYgKHR5cGVvZiBjb21wb25lbnRHZXR0ZXIgPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudEdldHRlci5jYWxsKHRoaXMub3duZXIsIGRlZXBHZXQpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2dldChkZWVwR2V0KTtcbn1cblxuZnVuY3Rpb24gRGF0YSRfZ2V0KGRlZXBHZXQpIHtcbiAgICBpZiAoZGVlcEdldCA9PT0gZmFsc2UpIC8vIGEgaGFjayB0byBlbmFibGUgZ2V0dGluZyBzaGFsbG93IHN0YXRlXG4gICAgICAgIHJldHVybjtcblxuICAgIHZhciBjb21wID0gdGhpcy5vd25lclxuICAgICAgICAsIHNjb3BlRGF0YTtcblxuICAgIGlmIChjb21wLmxpc3QpIHtcbiAgICAgICAgc2NvcGVEYXRhID0gW107XG4gICAgICAgIGNvbXAubGlzdC5lYWNoKGZ1bmN0aW9uKGxpc3RJdGVtLCBpbmRleCkge1xuICAgICAgICAgICAgc2NvcGVEYXRhW2luZGV4XSA9IGxpc3RJdGVtLmRhdGEuZ2V0KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChjb21wLmNvbnRhaW5lcilcbiAgICAgICAgICAgIGNvbXAuY29udGFpbmVyLnNjb3BlLl9lYWNoKGZ1bmN0aW9uKHNjb3BlSXRlbSwgbmFtZSkge1xuICAgICAgICAgICAgICAgIGlmICghIGNvbXAubGlzdC5jb250YWlucyhzY29wZUl0ZW0pICYmIHNjb3BlSXRlbS5kYXRhKVxuICAgICAgICAgICAgICAgICAgICBzY29wZURhdGFbbmFtZV0gPSBzY29wZUl0ZW0uZGF0YS5nZXQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoY29tcC5jb250YWluZXIpIHtcbiAgICAgICAgc2NvcGVEYXRhID0ge307XG4gICAgICAgIGNvbXAuY29udGFpbmVyLnNjb3BlLl9lYWNoKGZ1bmN0aW9uKHNjb3BlSXRlbSwgbmFtZSkge1xuICAgICAgICAgICAgaWYgKHNjb3BlSXRlbS5kYXRhKVxuICAgICAgICAgICAgICAgIHNjb3BlRGF0YVtuYW1lXSA9IHNjb3BlSXRlbS5kYXRhLmdldCgpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2VcbiAgICAgICAgc2NvcGVEYXRhID0gdGhpcy5fZ2V0U2NhbGFyVmFsdWUoKTtcblxuICAgIHRoaXMuX3ZhbHVlID0gc2NvcGVEYXRhO1xuXG4gICAgcmV0dXJuIHNjb3BlRGF0YTtcbn1cblxuXG4vKipcbiAqIERhdGEgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBHZXRzIHNjYWxhciBkYXRhIGZyb20gRE9NIGVsZW1lbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBEYXRhJF9nZXRTY2FsYXJWYWx1ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5lbERhdGEuZ2V0KHRoaXMub3duZXIuZWwpO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFNwbGljZXMgTGlzdCBpdGVtcy4gUmVxdWlyZXMgTGlzdCBmYWNldCB0byBiZSBwcmVzZW50IG9uIGNvbXBvbmVudC4gV29ya3MgaW4gdGhlIHNhbWUgd2F5IGFzIGFycmF5IHNwbGljZS5cbiAqIFJldHVybnMgZGF0YSByZXRyaWV2ZWQgZnJvbSByZW1vdmVkIGl0ZW1zXG4gKlxuICogQHBhcmFtIHtJbnRlZ2VyfSBzcGxpY2VJbmRleCBpbmRleCB0byBkZWxldGUvaW5zZXJ0IGF0XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHNwbGljZUhvd01hbnkgbnVtYmVyIG9mIGl0ZW1zIHRvIGRlbGV0ZVxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgb3B0aW9uYWwgaXRlbXMgdG8gaW5zZXJ0XG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gRGF0YSRzcGxpY2Uoc3BsaWNlSW5kZXgsIHNwbGljZUhvd01hbnkpIHsgLy8sIC4uLiBhcmd1bWVudHNcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGdldFRyYW5zYWN0aW9uRmxhZyhEYXRhJHNwbGljZSk7XG4gICAgdmFyIHJlc3VsdDtcblxuICAgIHZhciBjb21wb25lbnRTcGxpY2UgPSB0aGlzLmNvbmZpZy5zcGxpY2U7XG4gICAgaWYgKHR5cGVvZiBjb21wb25lbnRTcGxpY2UgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXN1bHQgPSBjb21wb25lbnRTcGxpY2UuYXBwbHkodGhpcy5vd25lciwgYXJndW1lbnRzKTtcbiAgICAgICAgcG9zdFRyYW5zYWN0aW9uRmluaXNoZWQuY2FsbCh0aGlzLCBpblRyYW5zYWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBzZXRUcmFuc2FjdGlvbkZsYWcodGhpcy5fc3BsaWNlLCBpblRyYW5zYWN0aW9uKTtcbiAgICByZXN1bHQgPSB0aGlzLl9zcGxpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIGlmICghcmVzdWx0KSByZXR1cm47XG5cbiAgICB2YXIgbXNnID0geyBwYXRoOiAnJywgdHlwZTogJ3NwbGljZScsXG4gICAgICAgICAgICAgICAgaW5kZXg6IHJlc3VsdC5zcGxpY2VJbmRleCxcbiAgICAgICAgICAgICAgICByZW1vdmVkOiByZXN1bHQucmVtb3ZlZCxcbiAgICAgICAgICAgICAgICBhZGRlZENvdW50OiByZXN1bHQuYWRkZWRDb3VudCxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZTogdGhpcy5fdmFsdWUgfTtcbiAgICBzZXRUcmFuc2FjdGlvbkZsYWcobXNnLCBpblRyYW5zYWN0aW9uKTtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKCcnLCBtc2cpO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5yZW1vdmVkO1xufVxuXG5cbmZ1bmN0aW9uIERhdGEkX3NwbGljZShzcGxpY2VJbmRleCwgc3BsaWNlSG93TWFueSkgeyAvLywgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBpblRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKERhdGEkX3NwbGljZSk7XG5cbiAgICB2YXIgbGlzdEZhY2V0ID0gdGhpcy5vd25lci5saXN0O1xuICAgIGlmICghIGxpc3RGYWNldClcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdEYXRhOiBjYW5ub3QgdXNlIHNwbGljZSBtZXRob2Qgd2l0aG91dCBMaXN0IGZhY2V0Jyk7XG5cbiAgICB2YXIgcmVtb3ZlZCA9IFtdO1xuXG4gICAgdmFyIGxpc3RMZW5ndGggPSBsaXN0RmFjZXQuY291bnQoKTtcbiAgICBhcmd1bWVudHNbMF0gPSBzcGxpY2VJbmRleCA9XG4gICAgICAgIG1vZGVsVXRpbHMubm9ybWFsaXplU3BsaWNlSW5kZXgoc3BsaWNlSW5kZXgsIGxpc3RMZW5ndGgpO1xuXG4gICAgaWYgKHNwbGljZUhvd01hbnkgPiAwICYmIGxpc3RMZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSBzcGxpY2VJbmRleDsgaSA8IHNwbGljZUluZGV4ICsgc3BsaWNlSG93TWFueTsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IGxpc3RGYWNldC5pdGVtKHNwbGljZUluZGV4KTtcbiAgICAgICAgICAgIGlmIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW1EYXRhID0gaXRlbS5kYXRhLmdldCgpO1xuICAgICAgICAgICAgICAgIGxpc3RGYWNldC5fcmVtb3ZlSXRlbShzcGxpY2VJbmRleCk7XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybignRGF0YTogbm8gaXRlbSBmb3IgaW5kZXgnLCBpKTtcblxuICAgICAgICAgICAgcmVtb3ZlZC5wdXNoKGl0ZW1EYXRhKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxpc3RGYWNldC5fdXBkYXRlRGF0YVBhdGhzKHNwbGljZUluZGV4LCBsaXN0RmFjZXQuY291bnQoKSk7XG4gICAgfVxuXG4gICAgdmFyIGFkZGVkID0gW107XG5cbiAgICB2YXIgYXJnc0xlbiA9IGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgICAgLCBhZGRJdGVtcyA9IGFyZ3NMZW4gPiAyXG4gICAgICAgICwgYWRkZWRDb3VudCA9IGFyZ3NMZW4gLSAyO1xuICAgIGlmIChhZGRJdGVtcykge1xuICAgICAgICBsaXN0RmFjZXQuX2FkZEl0ZW1zKGFkZGVkQ291bnQsIHNwbGljZUluZGV4KTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDIsIGogPSBzcGxpY2VJbmRleDsgaSA8IGFyZ3NMZW47IGkrKywgaisrKSB7XG4gICAgICAgICAgICB2YXIgaXRlbSA9IGxpc3RGYWNldC5pdGVtKGopO1xuICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBzZXRUcmFuc2FjdGlvbkZsYWcoaXRlbS5kYXRhLnNldCwgaW5UcmFuc2FjdGlvbik7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZW1EYXRhID0gaXRlbS5kYXRhLnNldChhcmd1bWVudHNbaV0pO1xuICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0RhdGE6IG5vIGl0ZW0gZm9yIGluZGV4Jywgaik7XG5cbiAgICAgICAgICAgIGFkZGVkLnB1c2goaXRlbURhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hhbmdlIHBhdGhzIG9mIGl0ZW1zIHRoYXQgd2VyZSBhZGRlZCBhbmQgaXRlbXMgYWZ0ZXIgdGhlbVxuICAgICAgICBsaXN0RmFjZXQuX3VwZGF0ZURhdGFQYXRocyhzcGxpY2VJbmRleCwgbGlzdEZhY2V0LmNvdW50KCkpO1xuICAgIH1cblxuICAgIC8vIGlmIChBcnJheS5pc0FycmF5KHRoaXMuX3ZhbHVlKSkge1xuICAgIC8vICAgICBfLnByZXBlbmRBcnJheShhZGRlZCwgW3NwbGljZUluZGV4LCBzcGxpY2VIb3dNYW55XSk7XG4gICAgLy8gICAgIEFycmF5LnByb3RvdHlwZS5zcGxpY2UuYXBwbHkodGhpcy5fdmFsdWUsIGFkZGVkKTtcbiAgICAvLyB9IGVsc2VcbiAgICAgICAgdGhpcy5fdmFsdWUgPSB0aGlzLmdldCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3BsaWNlSW5kZXg6IHNwbGljZUluZGV4LFxuICAgICAgICByZW1vdmVkOiByZW1vdmVkLFxuICAgICAgICBhZGRlZENvdW50OiBhZGRJdGVtcyA/IGFkZGVkQ291bnQgOiAwXG4gICAgfTtcbn1cblxuXG5mdW5jdGlvbiBEYXRhJGxlbigpIHtcbiAgICB2YXIgY29tcG9uZW50TGVuID0gdGhpcy5jb25maWcubGVuO1xuICAgIGlmICh0eXBlb2YgY29tcG9uZW50TGVuID09ICdmdW5jdGlvbicpXG4gICAgICAgIHJldHVybiBjb21wb25lbnRMZW4uY2FsbCh0aGlzLm93bmVyKTtcbiAgICBlbHNlXG4gICAgICAgIHJldHVybiB0aGlzLl9sZW4oKTtcbn1cblxuXG5mdW5jdGlvbiBEYXRhJF9sZW4oKSB7XG4gICAgaWYgKHRoaXMub3duZXIubGlzdCkgcmV0dXJuIHRoaXMub3duZXIubGlzdC5jb3VudCgpO1xuICAgIGVsc2UgbG9nZ2VyLmVycm9yKCdEYXRhOiBsZW4gY2FsbGVkIHdpdGhvdXQgbGlzdCBmYWNldCcpO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgZGF0YSBmYWNldCBvZiBhIGNoaWxkIGNvbXBvbmVudCAoYnkgc2NvcGVzKSBjb3JyZXNwb25kaW5nIHRvIHRoZSBwYXRoXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXNzUGF0aCBkYXRhIGFjY2VzcyBwYXRoXG4gKi9cbmZ1bmN0aW9uIERhdGEkcGF0aChhY2Nlc3NQYXRoLCBjcmVhdGVJdGVtKSB7XG4gICAgLy8gY3JlYXRlSXRlbSA9IHRydWU7IC8vIHRoaXMgaGFjayBzZWVtcyB0byBiZSBubyBsb25nZXIgbmVlZGVkLi4uXG5cbiAgICBpZiAoISBhY2Nlc3NQYXRoKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChhY2Nlc3NQYXRoKTtcbiAgICB2YXIgY3VycmVudENvbXBvbmVudCA9IHRoaXMub3duZXI7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcGFyc2VkUGF0aC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgcGF0aE5vZGUgPSBwYXJzZWRQYXRoW2ldXG4gICAgICAgICAgICAsIG5vZGVLZXkgPSBwYXRoVXRpbHMuZ2V0UGF0aE5vZGVLZXkocGF0aE5vZGUpO1xuICAgICAgICBpZiAocGF0aE5vZGUuc3ludGF4ID09ICdhcnJheScgJiYgY3VycmVudENvbXBvbmVudC5saXN0KSB7XG4gICAgICAgICAgICB2YXIgaXRlbUNvbXBvbmVudCA9IGN1cnJlbnRDb21wb25lbnQubGlzdC5pdGVtKG5vZGVLZXkpO1xuICAgICAgICAgICAgaWYgKCEgaXRlbUNvbXBvbmVudCAmJiBjcmVhdGVJdGVtICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGl0ZW1Db21wb25lbnQgPSBjdXJyZW50Q29tcG9uZW50Lmxpc3QuX2FkZEl0ZW0obm9kZUtleSk7XG4gICAgICAgICAgICAgICAgaXRlbUNvbXBvbmVudC5kYXRhLl9wYXRoID0gcGF0aE5vZGUucHJvcGVydHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50Q29tcG9uZW50ID0gaXRlbUNvbXBvbmVudDtcbiAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Q29tcG9uZW50LmNvbnRhaW5lcilcbiAgICAgICAgICAgIGN1cnJlbnRDb21wb25lbnQgPSBjdXJyZW50Q29tcG9uZW50LmNvbnRhaW5lci5zY29wZVtub2RlS2V5XTtcblxuICAgICAgICB2YXIgY3VycmVudERhdGFGYWNldCA9IGN1cnJlbnRDb21wb25lbnQgJiYgY3VycmVudENvbXBvbmVudC5kYXRhO1xuICAgICAgICBpZiAoISBjdXJyZW50RGF0YUZhY2V0KVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnREYXRhRmFjZXQ7XG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBwYXRoIHRvIGFjY2VzcyB0aGlzIGRhdGEgZmFjZXQgZnJvbSBwYXJlbnQgKHVzaW5nIHBhdGggbWV0aG9kKVxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gRGF0YSRnZXRQYXRoKCkge1xuICAgIHJldHVybiB0aGlzLl9wYXRoO1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMga2V5IHRvIGFjY2VzcyB0aGUgdmFsdWUgcmVsYXRlZCB0byB0aGlzIGRhdGEgZmFjZXQgb24gdGhlIHZhbHVlIHJlbGF0ZWQgdG8gcGFyZW50IGRhdGEgZmFjZXQuXG4gKiBJZiBjb21wb25lbnQgaGFzIExpc3QgZmFjZXQsIHJldHVybnMgaW5kZXhcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd8SW50ZWdlcn1cbiAqL1xuZnVuY3Rpb24gRGF0YSRnZXRLZXkoKSB7XG4gICAgdmFyIHBhdGggPSB0aGlzLl9wYXRoO1xuICAgIHJldHVybiBwYXRoWzBdID09ICdbJ1xuICAgICAgICAgICAgPyArcGF0aC5zbGljZSgxLCAtMSkgLy8gcmVtb3ZlIFwiW1wiIGFuZCBcIl1cIlxuICAgICAgICAgICAgOiBwYXRoLnNsaWNlKDEpIC8vIHJlbW92ZSBsZWFkaW5nIFwiLlwiXG59XG5cblxuLyoqXG4gKiBEYXRhIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IGBDb21wb25lbnQucHJvdG90eXBlLmdldFN0YXRlYCB0byBnZXQgZmFjZXQncyBzdGF0ZVxuICogUmV0dXJucyBET00gZGF0YVxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVlcFN0YXRlLCB0cnVlIGJ5IGRlZmF1bHRcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gRGF0YSRnZXRTdGF0ZShkZWVwU3RhdGUpIHtcbiAgICByZXR1cm4geyBzdGF0ZTogdGhpcy5nZXQoZGVlcFN0YXRlKSB9O1xufVxuXG5cbi8qKlxuICogRGF0YSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIENhbGxlZCBieSBgQ29tcG9uZW50LnByb3RvdHlwZS5zZXRTdGF0ZWAgdG8gc2V0IGZhY2V0J3Mgc3RhdGVcbiAqIFNpbXBseSBzZXRzIG1vZGVsIGRhdGFcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgZGF0YSB0byBzZXQgb24gZmFjZXQncyBtb2RlbFxuICovXG5mdW5jdGlvbiBEYXRhJHNldFN0YXRlKHN0YXRlKSB7XG4gICAgcmV0dXJuIHRoaXMuc2V0KHN0YXRlLnN0YXRlKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpIFxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgYmluZGVyID0gcmVxdWlyZSgnLi4vLi4vYmluZGVyJylcbiAgICAsIEJpbmRBdHRyaWJ1dGUgPSByZXF1aXJlKCcuLi8uLi9hdHRyaWJ1dGVzL2FfYmluZCcpXG4gICAgLCBEb21GYWNldEVycm9yID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9lcnJvcicpLkRvbUZhY2V0XG4gICAgLCBkb21VdGlscyA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZG9tJylcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZycpXG4gICAgLCBkb1QgPSByZXF1aXJlKCdkb3QnKTtcblxuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0RvbScpYFxuICogRmFjZXQgd2l0aCBjb21wb25lbnQgcmVsYXRlZCBkb20gdXRpbHNcbiAqL1xudmFyIERvbSA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdEb20nKTtcblxuXy5leHRlbmQoRG9tLCB7XG4gICAgY3JlYXRlRWxlbWVudDogRG9tJCRjcmVhdGVFbGVtZW50XG59KTtcblxuXG4vKipcbiAqIEZhY2V0IGNsYXNzIG1ldGhvZFxuICogQ3JlYXRlcyBhbiBlbGVtZW50IGZyb20gYSBwYXNzZWQgY29uZmlndWF0aW9uIG9iamVjdFxuICogXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIHdpdGggdGhlIHByb3BlcnRpZXMgYGRvbUNvbmZpZ2AsIGBjb250ZW50YCwgYHRlbXBsYXRlYFxuICogQHJldHVybiB7RWxlbWVudH0gYW4gaHRtbCBlbGVtZW50IFxuICovXG5mdW5jdGlvbiBEb20kJGNyZWF0ZUVsZW1lbnQoY29uZmlnKSB7XG4gICAgdmFyIGRvbUNvbmZpZyA9IGNvbmZpZy5kb21Db25maWcgfHwge31cbiAgICAgICAgLCB0YWdOYW1lID0gZG9tQ29uZmlnLnRhZ05hbWUgfHwgJ2RpdidcbiAgICAgICAgLCBuZXdFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSlcbiAgICAgICAgLCBjb250ZW50ID0gY29uZmlnLmNvbnRlbnRcbiAgICAgICAgLCB0ZW1wbGF0ZSA9IGNvbmZpZy50ZW1wbGF0ZTtcblxuICAgIC8vIFRPRE8gaXQgd2lsbCBiZSBjYWxsZWQgYWdhaW4gd2hlbi9pZiBjb21wb25lbnQgaXMgaW5zdGFudGlhdGVkXG4gICAgLy8gU2hvdWxkIGJlIHNvbWVwcm9wZXJ0eSBvbiBlbGVtZW50IHRvIGluZGljYXRlIGl0J3MgYmVlbiBjYWxsZWQ/XG4gICAgX2FwcGx5Q29uZmlnVG9FbGVtZW50KG5ld0VsLCBkb21Db25maWcpO1xuXG4gICAgaWYgKHR5cGVvZiBjb250ZW50ID09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICh0ZW1wbGF0ZSlcbiAgICAgICAgICAgIG5ld0VsLmlubmVySFRNTCA9IGRvVC50ZW1wbGF0ZSh0ZW1wbGF0ZSkoe2NvbnRlbnQ6IGNvbnRlbnR9KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbmV3RWwuaW5uZXJIVE1MID0gY29udGVudDtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0VsO1xufVxuXG5cbmZ1bmN0aW9uIF9hcHBseUNvbmZpZ1RvRWxlbWVudChlbCwgY29uZmlnKSB7XG4gICAgdmFyIGNzc0NsYXNzZXMgPSBjb25maWcgJiYgY29uZmlnLmNsc1xuICAgICAgICAsIGNvbmZpZ0F0dHJpYnV0ZXMgPSBjb25maWcgJiYgY29uZmlnLmF0dHJpYnV0ZXM7XG5cbiAgICBpZiAoY29uZmlnQXR0cmlidXRlcylcbiAgICAgICAgXy5lYWNoS2V5KGNvbmZpZ0F0dHJpYnV0ZXMsIGZ1bmN0aW9uKGF0dHJWYWx1ZSwgYXR0ck5hbWUpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICBpZiAoY3NzQ2xhc3NlcylcbiAgICAgICAgX2F0dGFjaENzc0NsYXNzZXMoZWwsICdhZGQnLCBjc3NDbGFzc2VzKTtcbn1cblxuXG5fLmV4dGVuZFByb3RvKERvbSwge1xuICAgIHN0YXJ0OiBzdGFydCxcblxuICAgIHNob3c6IHNob3csXG4gICAgaGlkZTogaGlkZSxcbiAgICB0b2dnbGU6IHRvZ2dsZSxcbiAgICBkZXRhY2g6IGRldGFjaCxcbiAgICByZW1vdmU6IHJlbW92ZSxcbiAgICBhcHBlbmQ6IGFwcGVuZCxcbiAgICBwcmVwZW5kOiBwcmVwZW5kLFxuICAgIGFwcGVuZENoaWxkcmVuOiBhcHBlbmRDaGlsZHJlbixcbiAgICBwcmVwZW5kQ2hpbGRyZW46IHByZXBlbmRDaGlsZHJlbixcbiAgICBpbnNlcnRBZnRlcjogaW5zZXJ0QWZ0ZXIsXG4gICAgaW5zZXJ0QmVmb3JlOiBpbnNlcnRCZWZvcmUsXG4gICAgYXBwZW5kVG9TY29wZVBhcmVudDogYXBwZW5kVG9TY29wZVBhcmVudCxcbiAgICBjaGlsZHJlbjogRG9tJGNoaWxkcmVuLFxuICAgIHNldFN0eWxlOiBzZXRTdHlsZSxcbiAgICBzZXRTdHlsZXM6IHNldFN0eWxlcyxcbiAgICBjb3B5OiBjb3B5LFxuICAgIGNyZWF0ZUVsZW1lbnQ6IGNyZWF0ZUVsZW1lbnQsXG5cbiAgICBhZGRDc3NDbGFzc2VzOiBfLnBhcnRpYWwoX21hbmFnZUNzc0NsYXNzZXMsICdhZGQnKSxcbiAgICByZW1vdmVDc3NDbGFzc2VzOiBfLnBhcnRpYWwoX21hbmFnZUNzc0NsYXNzZXMsICdyZW1vdmUnKSxcbiAgICB0b2dnbGVDc3NDbGFzc2VzOiBfLnBhcnRpYWwoX21hbmFnZUNzc0NsYXNzZXMsICd0b2dnbGUnKSxcblxuICAgIGZpbmQ6IGZpbmQsXG4gICAgaGFzVGV4dEJlZm9yZVNlbGVjdGlvbjogaGFzVGV4dEJlZm9yZVNlbGVjdGlvbixcbiAgICBoYXNUZXh0QWZ0ZXJTZWxlY3Rpb246IGhhc1RleHRBZnRlclNlbGVjdGlvbixcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoRG9tKTtcblxubW9kdWxlLmV4cG9ydHMgPSBEb207XG5cblxuLy8gc3RhcnQgRG9tIGZhY2V0XG5mdW5jdGlvbiBzdGFydCgpIHtcbiAgICB2YXIgZWwgPSB0aGlzLm93bmVyLmVsO1xuICAgIF9hcHBseUNvbmZpZ1RvRWxlbWVudChlbCwgdGhpcy5jb25maWcpO1xuICAgIHZhciBjdXJyZW50U3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbClcbiAgICB0aGlzLl92aXNpYmxlID0gY3VycmVudFN0eWxlICYmIGN1cnJlbnRTdHlsZS5kaXNwbGF5ICE9ICdub25lJztcbn1cblxuLy8gc2hvdyBIVE1MIGVsZW1lbnQgb2YgY29tcG9uZW50XG5mdW5jdGlvbiBzaG93KCkge1xuICAgIHRoaXMudG9nZ2xlKHRydWUpO1xufVxuXG4vLyBoaWRlIEhUTUwgZWxlbWVudCBvZiBjb21wb25lbnRcbmZ1bmN0aW9uIGhpZGUoKSB7XG4gICAgdGhpcy50b2dnbGUoZmFsc2UpO1xufVxuXG4vLyBzaG93L2hpZGVcbmZ1bmN0aW9uIHRvZ2dsZShkb1Nob3cpIHtcbiAgICBkb1Nob3cgPSB0eXBlb2YgZG9TaG93ID09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICAgICAgPyAhIHRoaXMuX3Zpc2libGVcbiAgICAgICAgICAgICAgICA6ICEhIGRvU2hvdztcblxuICAgIHRoaXMuX3Zpc2libGUgPSBkb1Nob3c7XG4gICAgdmFyIGVsID0gdGhpcy5vd25lci5lbDtcblxuICAgIGVsLnN0eWxlLmRpc3BsYXkgPSBkb1Nob3cgPyAnYmxvY2snIDogJ25vbmUnO1xuXG4gICAgcmV0dXJuIGRvU2hvdztcbn1cblxuXG5mdW5jdGlvbiBfbWFuYWdlQ3NzQ2xhc3NlcyhtZXRob2ROYW1lLCBjc3NDbGFzc2VzLCBlbmZvcmNlKSB7XG4gICAgX2F0dGFjaENzc0NsYXNzZXModGhpcy5vd25lci5lbCwgbWV0aG9kTmFtZSwgY3NzQ2xhc3NlcywgZW5mb3JjZSk7XG59XG5cblxuZnVuY3Rpb24gX2F0dGFjaENzc0NsYXNzZXMoZWwsIG1ldGhvZE5hbWUsIGNzc0NsYXNzZXMsIGVuZm9yY2UpIHtcbiAgICB2YXIgY2xhc3NMaXN0ID0gZWwuY2xhc3NMaXN0XG4gICAgICAgICwgZG9Ub2dnbGUgPSBtZXRob2ROYW1lID09ICd0b2dnbGUnO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY3NzQ2xhc3NlcykpXG4gICAgICAgIGNzc0NsYXNzZXMuZm9yRWFjaChjYWxsTWV0aG9kKTtcbiAgICBlbHNlIGlmICh0eXBlb2YgY3NzQ2xhc3NlcyA9PSAnc3RyaW5nJylcbiAgICAgICAgY2FsbE1ldGhvZChjc3NDbGFzc2VzKTtcbiAgICBlbHNlXG4gICAgICAgIHRocm93IG5ldyBEb21GYWNldEVycm9yKCd1bmtub3duIHR5cGUgb2YgQ1NTIGNsYXNzZXMgcGFyYW1ldGVyJyk7XG5cbiAgICBmdW5jdGlvbiBjYWxsTWV0aG9kKGNzc0Nscykge1xuICAgICAgICBkb1RvZ2dsZVxuICAgICAgICAgICAgLy8gT25seSBwYXNzICdlbmZvcmNlJyBpZiBhIHZhbHVlIGhhcyBiZWVuIHByb3ZpZGVkIChUaGUgJ3RvZ2dsZScgZnVuY3Rpb24gb2YgdGhlIGNsYXNzTGlzdCB3aWxsIHRyZWF0IHVuZGVmaW5lZCA9PT0gZmFsc2UgcmVzdWx0aW5nIGluIG9ubHkgYWxsb3dpbmcgY2xhc3NlcyB0byBiZSByZW1vdmVkKVxuICAgICAgICAgICAgPyBlbmZvcmNlID09PSB1bmRlZmluZWQgPyBjbGFzc0xpc3RbbWV0aG9kTmFtZV0oY3NzQ2xzKSA6IGNsYXNzTGlzdFttZXRob2ROYW1lXShjc3NDbHMsIGVuZm9yY2UpXG4gICAgICAgICAgICA6IGNsYXNzTGlzdFttZXRob2ROYW1lXShjc3NDbHMpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBkZXRhY2goKSB7XG4gICAgaWYgKHRoaXMub3duZXIuZWwpICBcbiAgICAgICAgZG9tVXRpbHMuZGV0YWNoQ29tcG9uZW50KHRoaXMub3duZXIuZWwpO1xufVxuXG5cbmZ1bmN0aW9uIHNldFN0eWxlKHByb3BlcnR5LCB2YWx1ZSkge1xuICAgIGlmICghdGhpcy5vd25lci5lbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgY2FsbCBzZXRTdHlsZSBvbiBvd25lciB3aXRoIG5vIGVsZW1lbnQ6IFwiICsgdGhpcy5vd25lci5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICB9XG4gICAgdGhpcy5vd25lci5lbC5zdHlsZVtwcm9wZXJ0eV0gPSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gc2V0U3R5bGVzKHByb3BlcnRpZXMpIHtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBwcm9wZXJ0aWVzKVxuICAgICAgICB0aGlzLm93bmVyLmVsLnN0eWxlW3Byb3BlcnR5XSA9IHByb3BlcnRpZXNbcHJvcGVydHldO1xufVxuXG5cbi8vIGNyZWF0ZSBhIGNvcHkgb2YgRE9NIGVsZW1lbnQgdXNpbmcgZmFjZXQgY29uZmlnIGlmIHNldFxuZnVuY3Rpb24gY29weShpc0RlZXApIHtcbiAgICByZXR1cm4gdGhpcy5vd25lci5lbCAmJiB0aGlzLm93bmVyLmVsLmNsb25lTm9kZShpc0RlZXApO1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQoKSB7XG4gICAgdmFyIG5ld0VsID0gRG9tLmNyZWF0ZUVsZW1lbnQodGhpcy5jb25maWcpO1xuICAgIHJldHVybiBuZXdFbDtcbn1cblxuXG4vLyByZW1vdmUgSFRNTCBlbGVtZW50IG9mIGNvbXBvbmVudFxuZnVuY3Rpb24gcmVtb3ZlKCkge1xuICAgIGRvbVV0aWxzLnJlbW92ZUVsZW1lbnQodGhpcy5vd25lci5lbCk7XG59XG5cbi8vIGFwcGVuZCBpbnNpZGUgSFRNTCBlbGVtZW50IG9mIGNvbXBvbmVudFxuZnVuY3Rpb24gYXBwZW5kKGVsKSB7XG4gICAgdGhpcy5vd25lci5lbC5hcHBlbmRDaGlsZChlbCk7XG59XG5cbi8vIHByZXBlbmQgaW5zaWRlIEhUTUwgZWxlbWVudCBvZiBjb21wb25lbnRcbmZ1bmN0aW9uIHByZXBlbmQoZWwpIHtcbiAgICB2YXIgdGhpc0VsID0gdGhpcy5vd25lci5lbFxuICAgICAgICAsIGZpcnN0Q2hpbGQgPSB0aGlzRWwuZmlyc3RDaGlsZDtcbiAgICBpZiAoZmlyc3RDaGlsZClcbiAgICAgICAgdGhpc0VsLmluc2VydEJlZm9yZShlbCwgZmlyc3RDaGlsZCk7XG4gICAgZWxzZVxuICAgICAgICB0aGlzRWwuYXBwZW5kQ2hpbGQoZWwpO1xufVxuXG4vLyBhcHBlbmRzIGNoaWxkcmVuIG9mIGVsZW1lbnQgaW5zaWRlIHRoaXMgY29tcG9uZW50J3MgZWxlbWVudFxuZnVuY3Rpb24gYXBwZW5kQ2hpbGRyZW4oZWwpIHtcbiAgICB3aGlsZShlbC5jaGlsZE5vZGVzLmxlbmd0aClcbiAgICAgICAgdGhpcy5hcHBlbmQoZWwuY2hpbGROb2Rlc1swXSk7XG59XG5cbi8vIHByZXBlbmRzIGNoaWxkcmVuIG9mIGVsZW1lbnQgaW5zaWRlIHRoaXMgY29tcG9uZW50J3MgZWxlbWVudFxuZnVuY3Rpb24gcHJlcGVuZENoaWxkcmVuKGVsKSB7XG4gICAgd2hpbGUoZWwuY2hpbGROb2Rlcy5sZW5ndGgpXG4gICAgICAgIHRoaXMucHJlcGVuZChlbC5jaGlsZE5vZGVzW2VsLmNoaWxkTm9kZXMubGVuZ3RoIC0gMV0pO1xufVxuXG5mdW5jdGlvbiBpbnNlcnRBZnRlcihlbCkge1xuICAgIHZhciB0aGlzRWwgPSB0aGlzLm93bmVyLmVsXG4gICAgICAgICwgcGFyZW50ID0gdGhpc0VsLnBhcmVudE5vZGU7ICAgIFxuICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZWwsIHRoaXNFbC5uZXh0U2libGluZyk7XG59XG5cbmZ1bmN0aW9uIGluc2VydEJlZm9yZShlbCkge1xuICAgIHZhciB0aGlzRWwgPSB0aGlzLm93bmVyLmVsXG4gICAgICAgICwgcGFyZW50ID0gdGhpc0VsLnBhcmVudE5vZGU7XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShlbCwgdGhpc0VsKTtcbn1cblxuXG4vLyBhcHBlbmRzIGNvbXBvbmVudCdzIGVsZW1lbnQgdG8gc2NvcGUgcGFyZW50LiBJZiBpdCB3YXMgYWxyZWR5IGluIERPTSBpdCB3aWxsIGJlIG1vdmVkXG5mdW5jdGlvbiBhcHBlbmRUb1Njb3BlUGFyZW50KCkge1xuICAgIHZhciBwYXJlbnQgPSB0aGlzLm93bmVyLmdldFNjb3BlUGFyZW50KCk7XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LmVsLmFwcGVuZENoaWxkKHRoaXMub3duZXIuZWwpO1xufVxuXG5cbi8qKlxuICogRG9tIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyB0aGUgbGlzdCBvZiBjaGlsZCBlbGVtZW50cyBvZiB0aGUgY29tcG9uZW50IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheVtFbGVtZW50XX1cbiAqL1xuZnVuY3Rpb24gRG9tJGNoaWxkcmVuKCkge1xuICAgIHJldHVybiBkb21VdGlscy5jaGlsZHJlbih0aGlzLm93bmVyLmVsKTtcbn1cblxuXG52YXIgZmluZERpcmVjdGlvbnMgPSB7XG4gICAgJ3VwJzogJ3ByZXZpb3VzTm9kZScsXG4gICAgJ2Rvd24nOiAnbmV4dE5vZGUnXG59O1xuXG4vLyBGaW5kcyBjb21wb25lbnQgcGFzc2luZyBvcHRpb25hbCBpdGVyYXRvcidzIHRlc3Rcbi8vIGluIHRoZSBzYW1lIHNjb3BlIGFzIHRoZSBjdXJyZW50IGNvbXBvbmVudCAodGhpcylcbi8vIGJ5IHRyYXZlcnNpbmcgRE9NIHRyZWUgdXB3YXJkcyAoZGlyZWN0aW9uID0gXCJ1cFwiKVxuLy8gb3IgZG93bndhcmRzIChkaXJlY3Rpb24gPSBcImRvd25cIilcbmZ1bmN0aW9uIGZpbmQoZGlyZWN0aW9uLCBpdGVyYXRvcikge1xuICAgIGlmICghIGZpbmREaXJlY3Rpb25zLmhhc093blByb3BlcnR5KGRpcmVjdGlvbikpXG4gICAgICAgIHRocm93IG5ldyBEb21GYWNldEVycm9yKCdpbmNvcnJlY3QgZmluZCBkaXJlY3Rpb246ICcgKyBkaXJlY3Rpb24pO1xuXG4gICAgdmFyIGVsID0gdGhpcy5vd25lci5lbFxuICAgICAgICAsIHNjb3BlID0gdGhpcy5vd25lci5zY29wZVxuICAgICAgICAsIHRyZWVXYWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHNjb3BlLl9yb290RWwsIE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5UKTtcblxuICAgIHRyZWVXYWxrZXIuY3VycmVudE5vZGUgPSBlbDtcbiAgICB2YXIgbmV4dE5vZGUgPSB0cmVlV2Fsa2VyW2ZpbmREaXJlY3Rpb25zW2RpcmVjdGlvbl1dKClcbiAgICAgICAgLCBjb21wb25lbnRzTmFtZXMgPSBPYmplY3Qua2V5cyhzY29wZSlcbiAgICAgICAgLCBmb3VuZCA9IGZhbHNlO1xuXG4gICAgd2hpbGUgKG5leHROb2RlKSB7XG4gICAgICAgIHZhciBhdHRyID0gbmV3IEJpbmRBdHRyaWJ1dGUobmV4dE5vZGUpO1xuICAgICAgICBpZiAoYXR0ci5ub2RlKSB7XG4gICAgICAgICAgICBhdHRyLnBhcnNlKCkudmFsaWRhdGUoKTtcbiAgICAgICAgICAgIGlmIChzY29wZS5oYXNPd25Qcm9wZXJ0eShhdHRyLmNvbXBOYW1lKSkge1xuICAgICAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBzY29wZVthdHRyLmNvbXBOYW1lXTtcbiAgICAgICAgICAgICAgICBpZiAoISBpdGVyYXRvciB8fCBpdGVyYXRvcihjb21wb25lbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRyZWVXYWxrZXIuY3VycmVudE5vZGUgPSBuZXh0Tm9kZTtcbiAgICAgICAgbmV4dE5vZGUgPSB0cmVlV2Fsa2VyW2ZpbmREaXJlY3Rpb25zW2RpcmVjdGlvbl1dKCk7XG4gICAgfVxuXG4gICAgaWYgKGZvdW5kKSByZXR1cm4gY29tcG9uZW50O1xufVxuXG5cbi8vIHJldHVybnMgdHJ1ZSBpZiB0aGUgZWxlbWVudCBoYXMgdGV4dCBiZWZvcmUgc2VsZWN0aW9uXG5mdW5jdGlvbiBoYXNUZXh0QmVmb3JlU2VsZWN0aW9uKCkge1xuICAgIHZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCEgc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSByZXR1cm4gdHJ1ZTtcbiAgICBcbiAgICB2YXIgdGV4dCA9IHNlbGVjdGlvbi5mb2N1c05vZGUgJiYgc2VsZWN0aW9uLmZvY3VzTm9kZS50ZXh0Q29udGVudDtcbiAgICB2YXIgc3RhcnRQb3MgPSB0ZXh0ICYmIHRleHQuY2hhckF0KDApID09ICcgJyA/IDEgOiAwO1xuICAgIGlmIChzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0ICE9IHN0YXJ0UG9zKSByZXR1cm4gdHJ1ZTtcblxuICAgIC8vIHdhbGsgdXAgdGhlIERPTSB0cmVlIHRvIGNoZWNrIGlmIHRoZXJlIGFyZSB0ZXh0IG5vZGVzIGJlZm9yZSBjdXJzb3JcbiAgICB2YXIgdHJlZVdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIodGhpcy5vd25lci5lbCwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICAgIHRyZWVXYWxrZXIuY3VycmVudE5vZGUgPSBzZWxlY3Rpb24uYW5jaG9yTm9kZTtcbiAgICB2YXIgcHJldk5vZGUgPSB0cmVlV2Fsa2VyLnByZXZpb3VzTm9kZSgpO1xuXG4gICAgdmFyIGlzVGV4dCA9IHByZXZOb2RlID8gIXByZXZOb2RlLm5vZGVWYWx1ZS50cmltKCkgPT0gJycgOiBmYWxzZTtcblxuICAgIHJldHVybiBpc1RleHQ7XG59XG5cblxuZnVuY3Rpb24gaGFzVGV4dEFmdGVyU2VsZWN0aW9uKCkge1xuICAgIHZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCEgc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSByZXR1cm4gdHJ1ZTtcblxuICAgIHZhciB0ZXh0ID0gc2VsZWN0aW9uLmZvY3VzTm9kZSAmJiBzZWxlY3Rpb24uZm9jdXNOb2RlLnRleHRDb250ZW50O1xuICAgIHZhciBzdGFydFBvcyA9IHRleHQgJiYgdGV4dC5jaGFyQXQodGV4dC5sZW5ndGgtMSkgPT0gJyAnID8gc2VsZWN0aW9uLmFuY2hvck5vZGUubGVuZ3RoLTEgOiBzZWxlY3Rpb24uYW5jaG9yTm9kZS5sZW5ndGg7XG4gICAgaWYgKHNlbGVjdGlvbi5hbmNob3JPZmZzZXQgPCBzdGFydFBvcykgcmV0dXJuIHRydWU7XG5cbiAgICAvLyB3YWxrIHVwIHRoZSBET00gdHJlZSB0byBjaGVjayBpZiB0aGVyZSBhcmUgdGV4dCBub2RlcyBhZnRlciBjdXJzb3JcbiAgICB2YXIgdHJlZVdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIodGhpcy5vd25lci5lbCwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICAgIHRyZWVXYWxrZXIuY3VycmVudE5vZGUgPSBzZWxlY3Rpb24uYW5jaG9yTm9kZTtcbiAgICB2YXIgbmV4dE5vZGUgPSB0cmVlV2Fsa2VyLm5leHROb2RlKCk7XG4gICAgXG4gICAgLy9UbyBjYXB0dXJlIHdoZW4gdHJlZXdhbGtlciBnaXZlcyB1cyBhbiBlbXB0eSB0ZXh0IG5vZGUgKHVua25vd24gcmVhc29uKVxuICAgIHZhciBpc1RleHQgPSBuZXh0Tm9kZSA/ICFuZXh0Tm9kZS5ub2RlVmFsdWUudHJpbSgpID09ICcnIDogZmFsc2U7XG5cbiAgICByZXR1cm4gaXNUZXh0O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwiY29tcG9uZW50cy1mYWNldHMtZHJhZ1wiPjwvYT5cbi8vICMjI2RyYWcgZmFjZXRcblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgRE9NRXZlbnRzU291cmNlID0gcmVxdWlyZSgnLi4vbXNnX3NyYy9kb21fZXZlbnRzJylcbiAgICAsIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgRHJhZ0Ryb3AgPSByZXF1aXJlKCcuLi8uLi91dGlsL2RyYWdkcm9wJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKTtcblxuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0RyYWcnKWBcbiAqIEZhY2V0IGZvciBjb21wb25lbnRzIHRoYXQgY2FuIGJlIGRyYWdnZWRcbiAqIERyYWcgZmFjZXQgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnM6XG4gKlxuICogIC0gbWV0YTogb2JqZWN0IHdpdGggcHJvcGVydGllc1xuICogICAgICAtIHBhcmFtczogb2JqZWN0IG9mIGtleS12YWx1ZSBwYWlycyB0aGF0IHdpbGwgYmUgY29udmVydGVkIGluIHVybC1saWtlIHF1ZXJ5IHN0cmluZyBpbiB0aGUgZW5kIG9mIGRhdGEgdHlwZSBmb3IgbWV0YWRhdGEgZGF0YSB0eXBlIChvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhpcyBvYmplY3QpLiBTZWUgY29uZmlnLmRyYWdEcm9wLmRhdGFUeXBlcy5jb21wb25lbnRNZXRhVGVtcGxhdGVcbiAqICAgICAgICAgIGFsbCB2YWx1ZXMgd2lsbCBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlIGFzIGRhdGF0eXBlIGNhbm5vdCBzdG9yZSB1cHBlcmNhc2UgbGV0dGVycy5cbiAqICAgICAgLSBkYXRhOiBkYXRhIHRoYXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlIGFib3ZlIG1ldGEgZGF0YSB0eXBlIChvciBmdW5jdGlvbilcbiAqICAtIGFsbG93ZWRFZmZlY3RzOiBzdHJpbmcgKG9yIGZ1bmN0aW9uKSBhcyBzcGVjaWZpZWQgaGVyZTogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9EcmFnRHJvcC9EcmFnX09wZXJhdGlvbnMjZHJhZ3N0YXJ0XG4gKiAgLSBkYXRhVHlwZXM6IG1hcCBvZiBhZGRpdGlvbmFsIGRhdGEgdHlwZXMgdGhlIGNvbXBvbmVudCB3aWxsIHN1cHBseSB0byBkYXRhIHRyYW5zZmVyIG9iamVjdCwga2V5IGlzIGRhdGEgdHlwZSwgdmFsdWUgaXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgaXQsIGNvbXBvbmVudCB3aWxsIGJlIHBhc3NlZCBhcyB0aGUgY29udGV4dCB0byB0aGlzIGZ1bmN0aW9uXG4gKlxuICogSWYgZnVuY3Rpb24gaXMgc3BlY2lmaWVkIGluIGFueSBwYXJhbWV0ZXIgaXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgY29tcG9uZW50IGFzIHRoZSBjb250ZXh0XG4gKi9cbnZhciBEcmFnID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0RyYWcnKTtcblxuXy5leHRlbmRQcm90byhEcmFnLCB7XG4gICAgaW5pdDogRHJhZyRpbml0LFxuICAgIHN0YXJ0OiBEcmFnJHN0YXJ0LFxuICAgIHNldEhhbmRsZTogRHJhZyRzZXRIYW5kbGVcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoRHJhZyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRHJhZztcblxuXG5mdW5jdGlvbiBEcmFnJGluaXQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgICBcblxuICAgIHRoaXMuX2NyZWF0ZU1lc3NhZ2VTb3VyY2VXaXRoQVBJKERPTUV2ZW50c1NvdXJjZSk7XG4gICAgdGhpcy5fZHJhZ0RhdGEgPSB7fTtcblxuICAgIHZhciBkYXRhVHlwZUluZm8gPSB0aGlzLmNvbmZpZy5fZGF0YVR5cGVJbmZvIHx8ICcnO1xuICAgIHRoaXMuX2RhdGFUeXBlSW5mbyA9IHR5cGVvZiBkYXRhVHlwZUluZm8gPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZGF0YVR5cGVJbmZvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmdW5jdGlvbigpIHsgcmV0dXJuIGRhdGFUeXBlSW5mbzsgfTtcbn1cblxuXG4vKipcbiAqIERyYWcgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRoZSBkcmFnIGhhbmRsZSBlbGVtZW50IG9mIGNvbXBvbmVudC4gVGhpcyBlbGVtZW50IGhhcyB0byBiZSBkcmFnZ2VkIGZvciB0aGUgY29tcG9uZW50IHRvIGJlIGRyYWdnZWQuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBoYW5kbGVFbFxuICovXG5mdW5jdGlvbiBEcmFnJHNldEhhbmRsZShoYW5kbGVFbCkge1xuICAgIGlmICghIHRoaXMub3duZXIuZWwuY29udGFpbnMoaGFuZGxlRWwpKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ2RyYWcgaGFuZGxlIHNob3VsZCBiZSBpbnNpZGUgZWxlbWVudCB0byBiZSBkcmFnZ2VkJylcbiAgICB0aGlzLl9kcmFnSGFuZGxlID0gaGFuZGxlRWw7XG59XG5cblxuZnVuY3Rpb24gRHJhZyRzdGFydCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuc3RhcnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBfYWRkRHJhZ0F0dHJpYnV0ZS5jYWxsKHRoaXMpO1xuXG4gICAgdGhpcy5vbk1lc3NhZ2VzKHtcbiAgICAgICAgJ21vdXNlZG93bic6IG9uTW91c2VEb3duLFxuICAgICAgICAnbW91c2VlbnRlciBtb3VzZWxlYXZlIG1vdXNlbW92ZSc6IG9uTW91c2VNb3ZlbWVudCxcbiAgICAgICAgJ2RyYWdzdGFydCc6IG9uRHJhZ1N0YXJ0LFxuICAgICAgICAnZHJhZyc6IG9uRHJhZ2dpbmcsXG4gICAgICAgICdkcmFnZW5kJzogb25EcmFnRW5kXG4gICAgfSk7XG5cbiAgICB0aGlzLm93bmVyLm9uTWVzc2FnZXMoe1xuICAgICAgICAnZ2V0c3RhdGVzdGFydGVkJzpcbiAgICAgICAgICAgIHsgc3Vic2NyaWJlcjogX3JlbW92ZURyYWdBdHRyaWJ1dGUsIGNvbnRleHQ6IHRoaXMgfSxcbiAgICAgICAgJ2dldHN0YXRlY29tcGxldGVkJzpcbiAgICAgICAgICAgIHsgc3Vic2NyaWJlcjogX2FkZERyYWdBdHRyaWJ1dGUsIGNvbnRleHQ6IHRoaXMgfVxuICAgIH0pO1xufVxuXG5cbi8qKlxuICogQWRkcyBkcmFnZ2FibGUgYXR0cmlidXRlIHRvIGNvbXBvbmVudCdzIGVsZW1lbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBfYWRkRHJhZ0F0dHJpYnV0ZSgpIHtcbiAgICBpZiAodGhpcy5vd25lci5lbClcbiAgICAgICAgdGhpcy5vd25lci5lbC5zZXRBdHRyaWJ1dGUoJ2RyYWdnYWJsZScsIHRydWUpO1xufVxuXG5cbmZ1bmN0aW9uIF9yZW1vdmVEcmFnQXR0cmlidXRlKCkge1xuICAgIGlmICh0aGlzLm93bmVyLmVsKVxuICAgICAgICB0aGlzLm93bmVyLmVsLnJlbW92ZUF0dHJpYnV0ZSgnZHJhZ2dhYmxlJyk7XG59XG5cblxuZnVuY3Rpb24gb25Nb3VzZURvd24oZXZlbnRUeXBlLCBldmVudCkge1xuICAgIHRoaXMuX19tb3VzZURvd25UYXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgaWYgKHRhcmdldEluRHJhZ0hhbmRsZS5jYWxsKHRoaXMpKSB7XG4gICAgICAgIHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5lbXB0eSgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gb25Nb3VzZU1vdmVtZW50KGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICB2YXIgc2hvdWxkQmVEcmFnZ2FibGUgPSB0YXJnZXRJbkRyYWdIYW5kbGUuY2FsbCh0aGlzKTtcbiAgICB0aGlzLm93bmVyLmVsLnNldEF0dHJpYnV0ZSgnZHJhZ2dhYmxlJywgc2hvdWxkQmVEcmFnZ2FibGUpO1xuICAgIGlmIChkb2N1bWVudC5ib2R5LmdldEF0dHJpYnV0ZSgnZGF0YS1kcmFnRW5hYmxlRXZlbnQnKSAhPSAnZmFsc2UnKVxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbn1cblxuXG5mdW5jdGlvbiBvbkRyYWdTdGFydChldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9mZiB8fCAhIHRhcmdldEluRHJhZ0hhbmRsZS5jYWxsKHRoaXMpKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb3duZXIgPSB0aGlzLm93bmVyO1xuICAgIHZhciBkdCA9IG5ldyBEcmFnRHJvcChldmVudCk7XG5cbiAgICB0aGlzLl9kcmFnRGF0YSA9IGR0LnNldENvbXBvbmVudFN0YXRlKG93bmVyKTtcbiAgICBzZXRNZXRhLmNhbGwodGhpcyk7XG4gICAgc2V0QWRkaXRpb25hbERhdGFUeXBlcy5jYWxsKHRoaXMpO1xuICAgIF9zZXRBbGxvd2VkRWZmZWN0cy5jYWxsKHRoaXMsIGR0KTtcblxuICAgIERyYWdEcm9wLnNlcnZpY2UucG9zdE1lc3NhZ2VTeW5jKCdkcmFnZHJvcHN0YXJ0ZWQnLCB7XG4gICAgICAgIGV2ZW50VHlwZTogJ2RyYWdzdGFydCcsXG4gICAgICAgIGRyYWdEcm9wOiBkdCxcbiAgICAgICAgZHJhZ0ZhY2V0OiB0aGlzXG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBzZXRNZXRhKCkge1xuICAgICAgICB2YXIgbWV0YUNvbmZpZyA9IHRoaXMuY29uZmlnLm1ldGFcbiAgICAgICAgICAgICwgcGFyYW1zQ29uZmlnID0gbWV0YUNvbmZpZyAmJiBtZXRhQ29uZmlnLnBhcmFtc1xuICAgICAgICAgICAgLCBtZXRhRGF0YUNvbmZpZyA9IG1ldGFDb25maWcgJiYgbWV0YUNvbmZpZy5kYXRhO1xuXG4gICAgICAgIHZhciBwYXJhbXMgPSBfLnJlc3VsdChwYXJhbXNDb25maWcsIG93bmVyKVxuICAgICAgICAgICAgLCBkYXRhID0gXy5yZXN1bHQobWV0YURhdGFDb25maWcsIG93bmVyKTtcblxuICAgICAgICB0aGlzLl9kcmFnTWV0YURhdGFUeXBlID0gZHQuc2V0Q29tcG9uZW50TWV0YShvd25lciwgcGFyYW1zLCBkYXRhKTtcbiAgICAgICAgdGhpcy5fZHJhZ01ldGFEYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZXRBZGRpdGlvbmFsRGF0YVR5cGVzKCkge1xuICAgICAgICBpZiAodGhpcy5jb25maWcuZGF0YVR5cGVzKSB7XG4gICAgICAgICAgICB0aGlzLl9kYXRhVHlwZXNEYXRhID0gXy5tYXBLZXlzKHRoaXMuY29uZmlnLmRhdGFUeXBlcywgZnVuY3Rpb24gKGdldERhdGFGdW5jLCBkYXRhVHlwZSkge1xuICAgICAgICAgICAgICAgIHZhciBkYXRhID0gZ2V0RGF0YUZ1bmMuY2FsbCh0aGlzLm93bmVyLCBkYXRhVHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBkYXRhID09ICdvYmplY3QnKSBkYXRhID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEpIGR0LnNldERhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuZnVuY3Rpb24gb25EcmFnZ2luZyhldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgaWYgKF9kcmFnSXNEaXNhYmxlZC5jYWxsKHRoaXMsIGV2ZW50KSkgcmV0dXJuO1xuXG4gICAgdmFyIGR0ID0gbmV3IERyYWdEcm9wKGV2ZW50KTtcbiAgICBkdC5zZXRDb21wb25lbnRTdGF0ZSh0aGlzLm93bmVyLCB0aGlzLl9kcmFnRGF0YSk7XG4gICAgZHQuc2V0RGF0YSh0aGlzLl9kcmFnTWV0YURhdGFUeXBlLCB0aGlzLl9kcmFnTWV0YURhdGEpO1xuICAgIGlmICh0aGlzLl9kYXRhVHlwZXNEYXRhKSB7XG4gICAgICAgIF8uZWFjaEtleSh0aGlzLl9kYXRhVHlwZXNEYXRhLCBmdW5jdGlvbihkYXRhLCBkYXRhVHlwZSkge1xuICAgICAgICAgICAgaWYgKGRhdGEpIGR0LnNldERhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfc2V0QWxsb3dlZEVmZmVjdHMuY2FsbCh0aGlzLCBkdCk7XG59XG5cblxuZnVuY3Rpb24gb25EcmFnRW5kKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBpZiAoX2RyYWdJc0Rpc2FibGVkLmNhbGwodGhpcywgZXZlbnQpKSByZXR1cm47XG5cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB2YXIgZHQgPSBuZXcgRHJhZ0Ryb3AoZXZlbnQpO1xuICAgIERyYWdEcm9wLnNlcnZpY2UucG9zdE1lc3NhZ2VTeW5jKCdjb21wbGV0ZWRyYWdkcm9wJywge1xuICAgICAgICBldmVudFR5cGU6ICdkcmFnZW5kJyxcbiAgICAgICAgZHJhZ0Ryb3A6IGR0LFxuICAgICAgICBkcmFnRmFjZXQ6IHRoaXNcbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBfc2V0QWxsb3dlZEVmZmVjdHMoRHJhZ0Ryb3ApIHtcbiAgICB2YXIgZWZmZWN0cyA9IF8ucmVzdWx0KHRoaXMuY29uZmlnLmFsbG93ZWRFZmZlY3RzLCB0aGlzLm93bmVyKTtcbiAgICBEcmFnRHJvcC5zZXRBbGxvd2VkRWZmZWN0cyhlZmZlY3RzKTtcbn1cblxuXG5mdW5jdGlvbiB0YXJnZXRJbkRyYWdIYW5kbGUoKSB7XG4gICAgcmV0dXJuICEgdGhpcy5fZHJhZ0hhbmRsZSB8fCB0aGlzLl9kcmFnSGFuZGxlLmNvbnRhaW5zKHRoaXMuX19tb3VzZURvd25UYXJnZXQpO1xufVxuXG5cbmZ1bmN0aW9uIF9kcmFnSXNEaXNhYmxlZChldmVudCkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5vZmYpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gPGEgbmFtZT1cImNvbXBvbmVudHMtZmFjZXRzLWRyb3BcIj48L2E+XG4vLyAjIyNkcm9wIGZhY2V0XG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcbiAgICAsIERPTUV2ZW50c1NvdXJjZSA9IHJlcXVpcmUoJy4uL21zZ19zcmMvZG9tX2V2ZW50cycpXG4gICAgLCBEcm9wTXNnQVBJID0gcmVxdWlyZSgnLi4vbXNnX2FwaS9kcm9wJylcbiAgICAsIERyYWdEcm9wID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9kcmFnZHJvcCcpXG4gICAgLCBEcm9wRXJyb3IgPSByZXF1aXJlKCcuLi8uLi91dGlsL2Vycm9yJykuRHJvcFxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBfaGFuZGxlRHJvcERlcGVuZGVuY3k7XG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuZmFjZXRzLmdldCgnRHJvcCcpYFxuICogRmFjZXQgZm9yIGNvbXBvbmVudHMgdGhhdCBjYW4gYWNjZXB0IGRyb3BzXG4gKiBEcm9wIGZhY2V0IHN1cHBvcnRzIHRoZSBmb2xsb3dpbmcgY29uZmlndXJhdGlvbiBwYXJhbWV0ZXJzOlxuICpcbiAqICAtIGFsbG93IC0gYW4gb2JqZWN0IHRoYXQgd2lsbCBkZWZpbmUgYWxsb3dlZCBkYXRhIHR5cGVzIGR1cmluZyBkcmFnIChgZHJhZ2VudGVyYCBhbmQgYGRyYWdvdmVyYCBldmVudHMpIHdpdGggdGhlc2UgcHJvcGVydGllczpcbiAqICAgICAgLSBjb21wb25lbnRzOiBgdHJ1ZWAgYnkgZGVmYXVsdCAoYWxsIGNvbXBvbmVudHMgd2lsbCBiZSBhY2NlcHRlZClcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1Igc3RyaW5nIHdpdGggYWxsb3dlZCBjb21wb25lbnQgY2xhc3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1IgbGlzdCBvZiBhbGxvd2VkIGNvbXBvbmVudHMgY2xhc3NlcyAoc3RyaW5ncylcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1IgbWFwIHdpdGggYWxsb3dlZCBjbGFzc2VzIGluIGtleXMgYW5kIGB0cnVlYC90ZXN0IGZ1bmN0aW9ucyBpbiB2YWx1ZXNcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1IgdGVzdCBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgcGFzc2VkIG9iamVjdCBkZWZpbmVkIGJlbG93XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIE9SIGBmYWxzZWAgdG8gTk9UIGFjY2VwdCBjb21wb25lbnRzXG4gKiAgICAgIC0gZGF0YVR5cGVzOiAgYGZhbHNlYCBieSBkZWZhdWx0IChubyBvdGhlciBkYXRhIHR5cGVzIHdpbGwgYmUgYWNjZXB0ZWQpXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIE9SIHN0cmluZyB3aXRoIGFsbG93ZWQgZGF0YSB0eXBlXG4gKiAgICAgICAgICAgICAgICAgICAgICAgIE9SIGxpc3Qgb2YgYWRkaXRpb25hbCBkYXRhIHR5cGVzIHRoYXQgYSBkcm9wIHRhcmdldCB3b3VsZCBhY2NlcHRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgT1IgdGVzdCBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgcGFzc2VkIERyYWdEcm9wIG9iamVjdFxuICogICAgICAgICAgICAgICAgICAgICAgICBPUiBgdHJ1ZWAgdG8gYWNjZXB0IGFsbCBkYXRhIHR5cGVzXG4gKiAgICAgIC0gY2hlY2tQYXJlbnQ6IGBmYWxzZWAgYnkgZGVmYXVsdFxuICogICAgICAgICAgICAgICAgICAgICAgICBPUiBgdHJ1ZWAgd2lsbCBjYWxsIHBhcmVudCBjb21wb25lbnQgZHJvcCBhbGxvdyB0byBjaGVjayBpZiBwYXJlbnQgY29tcG9uZW50IHdpbGwgYWNjZXB0IHRoZSBjb21wb25lbnRcbiAqICAgICAgSWYgdGVzdCBmdW5jdGlvbnMgYXJlIHVzZWQsIHRoZXkgc2hvdWxkIHJldHVybiBib29sZWFuLiBFYWNoIHRlc3QgZnVuY3Rpb24gY2FuIGFsc28gc2V0IGRyb3AgZWZmZWN0IGFzIGRlZmluZWQgaGVyZTpcbiAqICAgICAgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0RhdGFUcmFuc2ZlciNkcm9wRWZmZWN0LjI4LjI5XG4gKiAgICAgIFNldHRpbmcgZHJvcCBlZmZlY3QgdGhhdCBpcyBub3QgYWxsb3dlZCBieSBkcmFnZ2VkIG9iamVjdCB3aWxsIHByZXZlbnQgZHJvcC5cbiAqICAgICAgVGVzdCBmdW5jdGlvbnMgZm9yIGNvbXBvbmVudHMgd2lsbCBiZSBwYXNzZWQgdGhlIG93bmVyIG9mIERyb3AgZmFjZXQgYXMgY29udGV4dCwgdGhlIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcG9zc2libGUgcHJvcGVydGllcyBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyOlxuICogICAgICAgICAgY29tcENsYXNzIC0gbmFtZSBvZiBjb21wb25lbnQgY2xhc3MgYXMgc3RvcmVkIGluIHJlZ2lzdHJ5XG4gKiAgICAgICAgICBjb21wTmFtZSAtIG5hbWUgb2YgY29tcG9uZW50IChhbGwgbG93ZXJjYXNlKVxuICogICAgICAgICAgcGFyYW1zIC0gcGFyYW1ldGVycyBhcyBlbmNvZGVkIGluIGRhdGFUeXBlLCBwYXNzZWQgdG8gYG1pbG8udXRpbC5kcmFnRHJvcC5zZXRDb21wb25lbnRNZXRhYCBieSBEcmFnIGZhY2V0XG4gKiAgICAgICAgICBtZXRhRGF0YVR5cGUgLSBkYXRhIHR5cGUgb2YgdGhlIGRhdGEgdGhhdCBoYXMgY29tcENsYXNzLCBjb21wTmFtZSBhbmQgcGFyYW1zIGVuY29kZWRcbiAqXG4gKiAgICAgIC4uLiBhbmQgRHJhZ0Ryb3AgaW5zdGFuY2UgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXJcbiAqXG4gKiAgICAgIFRlc3QgZnVuY3Rpb24gZm9yIG90aGVyIGRhdGEgdHlwZXMgd2lsbCBiZSBwYXNzZWQgdGhlIG93bmVyIG9mIERyb3AgZmFjZXQgYXMgY29udGV4dCBhbmQgRHJhZ0Ryb3AgaW5zdGFuY2UgYXMgdGhlIGZpcnN0IHBhcmFtZXRlclxuICpcbiAqICMjIyNFdmVudHMjIyMjXG4gKlxuICogSW4gYWRkaXRpb24gdG8gY29uZmlndXJpbmcgYWxsb3dlZCBjb21wb25lbnRzIGFuZCBkYXRhIHR5cGVzLCBjb21wb25lbnRzIGNsYXNzZXMgc2hvdWxkIHN1YnNjcmliZSB0byBldmVudHMuXG4gKiBBdCB0aGUgdmVyeSBsZWFzdCwgdGhleSBzaG91bGQgc3Vic2NyaWJlIHRvIGBkcm9wYCBldmVudC5cbiAqXG4gKiBEcm9wIGZhY2V0IGVtaXRzIGRyYWdpbi9kcmFnb3V0IG1lc3NhZ2VzIHRoYXQgYXJlIGVtaXR0ZWQgd2hlbmV2ZXIgYWN0dWFsIGNvbXBvbmVudCBlbGVtZW50IGlzIGVudGVyZWQgb3IgbGVmdFxuICogKHdoaWNoIGlzIGRpZmZlcmVudCBmcm9tIGRyYWdlbnRlciBhbmQgZHJhZ2xlYXZlIG1lc3NhZ2VzIHRoYXQgYXJlIGVtaXR0ZWQgd2hlbmV2ZXIgYW55IGNoaWxkIGVsZW1lbnQgaXMgZW50ZXJlZCBvciBsZWZ0LCBhcyBsb25nIGFzIGV2ZW50IGJ1YmJsZXMgdXApXG4gKiBJZiBjaGlsZCBjb21wb25lbnQgaGFzIGRyb3AgZmFjZXQgYXR0YWNoZWQsIGRyYWdvdXQgd2lsbCBiZSBlbWl0dGVkIG9uIHRoZSBjdXJyZW50IGNvbXBvbmVudCB3aGVuIHRoZSBjaGlsZCBpcyBlbnRlcmVkLlxuICpcbiAqIFlvdSBjYW4gc2VlIHRoZSBkZW1vbnN0cmF0aW9uIG9mIHdoZW4gbWVzc2FnZXMgYXJlIGVtaXR0ZWQgW2hlcmVdKGh0dHA6Ly9qc2Jpbi5jb20vYnVxb3YvNilcbiAqIFxuICovXG52YXIgRHJvcCA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdEcm9wJyk7XG5cblxuXy5leHRlbmRQcm90byhEcm9wLCB7XG4gICAgaW5pdDogRHJvcCRpbml0LFxuICAgIHN0YXJ0OiBEcm9wJHN0YXJ0XG4gICAgLy8gX3JlYXR0YWNoOiBfcmVhdHRhY2hFdmVudHNPbkVsZW1lbnRDaGFuZ2Vcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoRHJvcCk7XG5cbm1vZHVsZS5leHBvcnRzID0gRHJvcDtcblxuXG5mdW5jdGlvbiBEcm9wJGluaXQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLl9jcmVhdGVNZXNzYWdlU291cmNlV2l0aEFQSShET01FdmVudHNTb3VyY2UsIG5ldyBEcm9wTXNnQVBJKTtcbn1cblxuXG5mdW5jdGlvbiBEcm9wJHN0YXJ0KCkge1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5zdGFydC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMub3duZXIuZWwuY2xhc3NMaXN0LmFkZCgnY2MtbW9kdWxlLXJlbGF0aXZlJyk7XG4gICAgdGhpcy5vbk1lc3NhZ2VzKHtcbiAgICAgICAgJ2RyYWdlbnRlciBkcmFnb3Zlcic6IG9uRHJhZ2dpbmcsXG4gICAgICAgICdkcm9wJzogb25Ecm9wLFxuICAgICAgICAnZHJhZ2VudGVyIGRyYWdvdmVyIGRyYWdsZWF2ZSBkcm9wIGRyYWdpbiBkcmFnb3V0JzogcG9zdFRvU2VydmljZVxuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIG9uRHJhZ2dpbmcoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIHZhciBkdCA9IG5ldyBEcmFnRHJvcChldmVudCk7XG5cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKCEgX2hhbmRsZURyb3BEZXBlbmRlbmN5LmNhbGwodGhpcywgZHQpKVxuICAgICAgICBkdC5zZXREcm9wRWZmZWN0KCdub25lJyk7XG59XG5cblxuZnVuY3Rpb24gb25Ecm9wKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB2YXIgZHQgPSBuZXcgRHJhZ0Ryb3AoZXZlbnQpO1xuICAgIERyYWdEcm9wLnNlcnZpY2UucG9zdE1lc3NhZ2VTeW5jKCdkcmFnZHJvcGNvbXBsZXRlZCcsIHtcbiAgICAgICAgZXZlbnRUeXBlOiAnZHJvcCcsXG4gICAgICAgIGRyYWdEcm9wOiBkdCxcbiAgICAgICAgZHJvcEZhY2V0OiB0aGlzLFxuICAgICAgICBjb21wb25lbnQ6IHRoaXMub3duZXJcbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBwb3N0VG9TZXJ2aWNlKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBEcmFnRHJvcC5zZXJ2aWNlLnBvc3RNZXNzYWdlU3luYyhldmVudFR5cGUsIHtcbiAgICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgICBkcm9wRmFjZXQ6IHRoaXMsXG4gICAgICAgIGNvbXBvbmVudDogdGhpcy5vd25lclxuICAgIH0pO1xufVxuXG5cbl9oYW5kbGVEcm9wRGVwZW5kZW5jeSA9IF8udGhyb3R0bGUoX2hhbmRsZURyb3BEZXBlbmRlbmN5Tm90aHJvdHRsZSwgNTApO1xuZnVuY3Rpb24gX2hhbmRsZURyb3BEZXBlbmRlbmN5Tm90aHJvdHRsZShkdCwgb3JpZ2luYWxEcm9wQ29tcG9uZW50KSB7XG4gICAgdmFyIGFsbG93ID0gdGhpcy5jb25maWcuYWxsb3dcbiAgICAgICAgLCBwYXJlbnRBbGxvd2VkID0gdHJ1ZTtcblxuICAgIG9yaWdpbmFsRHJvcENvbXBvbmVudCA9IG9yaWdpbmFsRHJvcENvbXBvbmVudCB8fCB0aGlzLm93bmVyO1xuXG4gICAgaWYgKGFsbG93ICYmIGFsbG93LmNoZWNrUGFyZW50KSB7XG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzLm93bmVyLmdldFNjb3BlUGFyZW50KCdEcm9wJyk7XG4gICAgICAgIGlmIChwYXJlbnQpXG4gICAgICAgICAgICBwYXJlbnRBbGxvd2VkID0gX2hhbmRsZURyb3BEZXBlbmRlbmN5Tm90aHJvdHRsZS5jYWxsKHBhcmVudC5kcm9wLCBkdCwgb3JpZ2luYWxEcm9wQ29tcG9uZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyZW50QWxsb3dlZCAmJiBfaXNEcm9wQWxsb3dlZC5jYWxsKHRoaXMsIGR0LCBvcmlnaW5hbERyb3BDb21wb25lbnQpO1xufVxuXG5cbi8qKlxuICogQ2hlY2tzIGlmIGRyb3AgaXMgYWxsb3dlZCBiYXNlZCBvbiBmYWNldCBjb25maWd1cmF0aW9uIChzZWUgYWJvdmUpXG4gKiBcbiAqIEBwYXJhbSB7RHJhZ0Ryb3B9IGR0XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBfaXNEcm9wQWxsb3dlZChkdCwgb3JpZ2luYWxEcm9wQ29tcG9uZW50KSB7XG4gICAgdmFyIGFsbG93ID0gdGhpcy5jb25maWcuYWxsb3c7XG5cbiAgICBpZiAoZHQuaXNDb21wb25lbnQoKSkge1xuICAgICAgICB2YXIgYWxsb3dDb21wcyA9IGFsbG93ICYmIGFsbG93LmNvbXBvbmVudHNcbiAgICAgICAgICAgICwgbWV0YSA9IGR0LmdldENvbXBvbmVudE1ldGEoKTtcblxuICAgICAgICBzd2l0Y2ggKHR5cGVvZiBhbGxvd0NvbXBzKSB7XG4gICAgICAgICAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFsbG93Q29tcHM7XG4gICAgICAgICAgICAvLyBjb21wb25lbnQgY2xhc3NcbiAgICAgICAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1ldGEgJiYgbWV0YS5jb21wQ2xhc3MgPT0gYWxsb3dDb21wcztcbiAgICAgICAgICAgIC8vIHRlc3QgZnVuY3Rpb25cbiAgICAgICAgICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYWxsb3dDb21wcy5jYWxsKHRoaXMub3duZXIsIG1ldGEsIGR0LCBvcmlnaW5hbERyb3BDb21wb25lbnQpO1xuICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhbGxvd0NvbXBzKSlcbiAgICAgICAgICAgICAgICAgICAgLy8gbGlzdCBvZiBhbGxvd2VkIGNsYXNzZXNcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFsbG93Q29tcHMuaW5kZXhPZihtZXRhICYmIG1ldGEuY29tcENsYXNzKSA+PSAwO1xuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBtYXAgb2YgY2xhc3M6IGJvb2xlYW58dGVzdCBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICB2YXIgdGVzdCA9IGFsbG93Q29tcHNbbWV0YSAmJiBtZXRhLmNvbXBDbGFzc107XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAhISBfLnJlc3VsdCh0ZXN0LCB0aGlzLm93bmVyLCBtZXRhLCBkdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRHJvcEVycm9yKCdJbmNvcnJlY3QgYWxsb3dlZCBjb21wb25lbnRzIGluIGNvbmZpZycpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGRhdGFUeXBlcyA9IGFsbG93ICYmIGFsbG93LmRhdGFUeXBlc1xuICAgICAgICBzd2l0Y2ggKHR5cGVvZiBkYXRhVHlwZXMpIHtcbiAgICAgICAgICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gZHQudHlwZXMuaW5kZXhPZihkYXRhVHlwZXMpID49IDA7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUT0RPIHRlc3QgZm9yIG90aGVyIGRhdGEgdHlwZXNcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyJylcbiAgICAsIERPTUV2ZW50c1NvdXJjZSA9IHJlcXVpcmUoJy4uL21zZ19zcmMvZG9tX2V2ZW50cycpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5mYWNldHMuZ2V0KCdFdmVudHMnKWBcbiAqIENvbXBvbmVudCBmYWNldCB0aGF0IG1hbmFnZXMgc3Vic2NyaXB0aW9ucyB0byBET00gZXZlbnRzIHVzaW5nIFtNZXNzZW5nZXJdKC4uLy4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sKSB3aXRoIFtET01FdmVudHNTb3VyY2VdKC4uL21zZ19zcmMvZG9tX2V2ZW50cy5qcy5odG1sKS5cbiAqIEFsbCBwdWJsaWMgbWV0aG9kcyBvZiBNZXNzZW5nZXIgYW5kIGB0cmlnZ2VyYCBtZXRob2Qgb2YgW0RPTUV2ZW50c1NvdXJjZV0oLi4vbXNnX3NyYy9kb21fZXZlbnRzLmpzLmh0bWwpIGFyZSBwcm94aWVkIGRpcmVjdGx5IHRvIHRoaXMgZmFjZXQuXG4gKiBGb3IgZXhhbXBsZSwgdG8gc3Vic2NyaWJlIHRvIGBjbGlja2AgZXZlbnQgdXNlOlxuICogYGBgXG4gKiBjb21wb25lbnQuZnJhbWUub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gKiAgICAgLy8gLi4uXG4gKiB9KTtcbiAqIGBgYFxuICogU2VlIFtNZXNzZW5nZXJdKC4uLy4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sKVxuICovXG52YXIgRXZlbnRzID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0V2ZW50cycpO1xuXG5cbi8qKlxuICogIyMjI0V2ZW50cyBmYWNldCBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2luaXRdKCNFdmVudHMkaW5pdCkgLSBjYWxsZWQgYnkgY29uc3RydWN0b3IgYXV0b21hdGljYWxseVxuICovXG5fLmV4dGVuZFByb3RvKEV2ZW50cywge1xuICAgIGluaXQ6IEV2ZW50cyRpbml0XG4gICAgLy8gX3JlYXR0YWNoOiBfcmVhdHRhY2hFdmVudHNPbkVsZW1lbnRDaGFuZ2Vcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoRXZlbnRzKTtcblxubW9kdWxlLmV4cG9ydHMgPSBFdmVudHM7XG5cblxuLyoqXG4gKiBFeHBvc2UgRE9NRXZlbnRzU291cmNlIHRyaWdnZXIgbWV0aG9kIG9uIEV2ZW50cyBwcm90b3R5cGVcbiAqL1xudmFyIE1TR19TT1VSQ0VfS0VZID0gJ19kb21FdmVudHNTb3VyY2UnXG5ET01FdmVudHNTb3VyY2UudXNlV2l0aChFdmVudHMsIE1TR19TT1VSQ0VfS0VZLCBbJ3RyaWdnZXInXSk7XG5cblxuLyoqXG4gKiBFdmVudHMgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsemVzIGZhY2V0LCBjb25uZWN0cyBET01FdmVudHNTb3VyY2UgdG8gZmFjZXQncyBtZXNzZW5nZXJcbiAqL1xuZnVuY3Rpb24gRXZlbnRzJGluaXQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHZhciBkb21FdmVudHNTb3VyY2UgPSBuZXcgRE9NRXZlbnRzU291cmNlKHRoaXMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0aGlzLm93bmVyKTtcbiAgICB0aGlzLl9zZXRNZXNzYWdlU291cmNlKGRvbUV2ZW50c1NvdXJjZSk7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBNU0dfU09VUkNFX0tFWSwgZG9tRXZlbnRzU291cmNlKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIGZhY2V0c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi9jZl9yZWdpc3RyeScpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXInKVxuICAgICwgRnJhbWVNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vbXNnX3NyYy9mcmFtZScpXG4gICAgLCBkb21FdmVudHNDb25zdHJ1Y3RvcnMgPSByZXF1aXJlKCcuLi8uLi9zZXJ2aWNlcy9kZV9jb25zdHJzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIGBtaWxvLnJlZ2lzdHJ5LmZhY2V0cy5nZXQoJ0ZyYW1lJylgXG4gKiBDb21wb25lbnQgZmFjZXQgdGhhdCBzaW1wbGlmaWVzIHNlbmRpbmcgd2luZG93IG1lc3NhZ2VzIHRvIGlmcmFtZSBhbmQgc3Vic2NyaWJpbmcgdG8gbWVzc2FnZXMgb24gaW5uZXIgd2luZG93IG9mIGlmcmFtZS5cbiAqIEFsbCBwdWJsaWMgbWV0aG9kcyBvZiBNZXNzZW5nZXIgYW5kIGB0cmlnZ2VyYCBtZXRob2Qgb2YgW0ZyYW1lTWVzc2FnZVNvdXJjZV0oLi4vbXNnX3NyYy9mcmFtZS5qcy5odG1sKSBhcmUgcHJveGllZCBkaXJlY3RseSB0byB0aGlzIGZhY2V0LlxuICogRm9yIGV4YW1wbGUsIHRvIHNlbmQgY3VzdG9tIG1lc3NhZ2UgdG8gaWZyYW1lIHdpbmRvdyB1c2U6XG4gKiBgYGBcbiAqIGlmcmFtZUNvbXBvbmVudC5mcmFtZS50cmlnZ2VyKCdteW1lc3NhZ2UnLCBteURhdGEpO1xuICogYGBgXG4gKiBUbyBzdWJzY3JpYmUgdG8gdGhpcyBtZXNzYWdlcyBpbnNpZGUgZnJhbWUgdXNlICh3aXRoIG1pbG8gLSBzZWUgW21pbG8ubWFpbF0oLi4vLi4vbWFpbC9pbmRleC5qcy5odG1sKSk6XG4gKiBgYGBcbiAqIG1pbG8ubWFpbC5vbignbWVzc2FnZTpteW1lc3NhZ2UnLCBmdW5jdGlvbihtc2dUeXBlLCBtc2dEYXRhKSB7XG4gKiAgICAgLy8gZGF0YSBpcyBpbnNpZGUgb2Ygd2luZG93IG1lc3NhZ2UgZGF0YVxuICogICAgIC8vIG1zZ1R5cGUgPT0gJ21lc3NhZ2U6bXltZXNzYWdlJ1xuICogICAgIHZhciBteURhdGEgPSBtc2dEYXRhLmRhdGE7XG4gKiAgICAgLy8gLi4uIGFwcCBsb2dpYyBoZXJlXG4gKiB9KTtcbiAqIGBgYFxuICogb3Igd2l0aG91dCBtaWxvOlxuICogYGBgXG4gKiB3aW5kb3cuYXR0YWNoRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAqICAgICB2YXIgbXNnVHlwZSA9IG1lc3NhZ2UudHlwZTsgLy8gZS5nLiwgJ215bWVzc2FnZSdcbiAqICAgICB2YXIgbXlEYXRhID0gbWVzc2FnZS5kYXRhO1xuICogICAgIC8vIC4uLiBtZXNzYWdlIHJvdXRpbmcgYW5kIGNvZGUgaGVyZVxuICogfSk7XG4gKiBgYGBcbiAqIE1pbG8gZG9lcyByb3V0aW5nIGJhc2VkIG9uIHNlbnQgbWVzc2FnZSB0eXBlIGF1dG9tYXRpY2FsbHkuXG4gKiBTZWUgW01lc3Nlbmdlcl0oLi4vLi4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpIGFuZCBbbWlsby5tYWlsXSguLi8uLi9tYWlsL2luZGV4LmpzLmh0bWwpLlxuICovXG4gdmFyIEZyYW1lID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0ZyYW1lJyk7XG5cblxuLyoqXG4gKiBDYWxscyBwYXNzZWQgZnVuY3Rpb24gd2hlbiBmcmFtZSBET00gYmVjb21lcyByZWFkeS4gSWYgYWxyZWFkeSByZWFkeSBjYWxscyBpbW1lZGlhdGVseVxuICovXG52YXIgRnJhbWUkd2hlblJlYWR5ID0gX21ha2VXaGVuUmVhZHlGdW5jKEZyYW1lJGlzUmVhZHksICdkb21yZWFkeScpO1xuXG4vKipcbiAqIENhbGxzIHBhc3NlZCBmdW5jdGlvbiB3aGVuIGZyYW1lIG1pbG8gYmVjb21lcyByZWFkeS4gSWYgYWxyZWFkeSByZWFkeSBjYWxscyBpbW1lZGlhdGVseVxuICovXG52YXIgRnJhbWUkd2hlbk1pbG9SZWFkeSA9IF9tYWtlV2hlblJlYWR5RnVuYyhGcmFtZSRpc01pbG9SZWFkeSwgJ21lc3NhZ2U6bWlsb3JlYWR5Jyk7XG5cblxuLyoqXG4gKiAjIyMjRXZlbnRzIGZhY2V0IGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI0ZyYW1lJGluaXQpIC0gY2FsbGVkIGJ5IGNvbnN0cnVjdG9yIGF1dG9tYXRpY2FsbHlcbiAqL1xuXy5leHRlbmRQcm90byhGcmFtZSwge1xuICAgIGluaXQ6IEZyYW1lJGluaXQsXG4gICAgc3RhcnQ6IEZyYW1lJHN0YXJ0LFxuICAgIGRlc3Ryb3k6IEZyYW1lJGRlc3Ryb3ksXG4gICAgZ2V0V2luZG93OiBGcmFtZSRnZXRXaW5kb3csXG4gICAgaXNSZWFkeTogRnJhbWUkaXNSZWFkeSxcbiAgICB3aGVuUmVhZHk6IEZyYW1lJHdoZW5SZWFkeSxcbiAgICBpc01pbG9SZWFkeTogRnJhbWUkaXNNaWxvUmVhZHksXG4gICAgd2hlbk1pbG9SZWFkeTogRnJhbWUkd2hlbk1pbG9SZWFkeSxcbiAgICBtaWxvOiBGcmFtZSRtaWxvXG4gICAgLy8gX3JlYXR0YWNoOiBfcmVhdHRhY2hFdmVudHNPbkVsZW1lbnRDaGFuZ2Vcbn0pO1xuXG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChGcmFtZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRnJhbWU7XG5cblxuLyoqXG4gKiBFeHBvc2UgRnJhbWVNZXNzYWdlU291cmNlIHRyaWdnZXIgbWV0aG9kIG9uIEV2ZW50cyBwcm90b3R5cGVcbiAqL1xudmFyIE1TR19TT1VSQ0VfS0VZID0gJ19tZXNzYWdlU291cmNlJztcbkZyYW1lTWVzc2FnZVNvdXJjZS51c2VXaXRoKEZyYW1lLCBNU0dfU09VUkNFX0tFWSwgWyd0cmlnZ2VyJ10pO1xuXG5cbi8qKlxuICogRnJhbWUgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsemVzIGZhY2V0LCBjb25uZWN0cyBGcmFtZU1lc3NhZ2VTb3VyY2UgdG8gZmFjZXQncyBtZXNzZW5nZXJcbiAqL1xuZnVuY3Rpb24gRnJhbWUkaW5pdCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIFxuICAgIHZhciBtZXNzYWdlU291cmNlID0gbmV3IEZyYW1lTWVzc2FnZVNvdXJjZSh0aGlzLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcy5vd25lcik7XG4gICAgdGhpcy5fc2V0TWVzc2FnZVNvdXJjZShtZXNzYWdlU291cmNlKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgTVNHX1NPVVJDRV9LRVksIG1lc3NhZ2VTb3VyY2UpO1xufVxuXG5cbi8qKlxuICogRnJhbWUgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBFbWl0cyBmcmFtZWxvYWRlZCBldmVudCB3aGVuIHJlYWR5LlxuICovXG5mdW5jdGlvbiBGcmFtZSRzdGFydCgpIHtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuc3RhcnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgbWlsbyhwb3N0RG9tUmVhZHkpO1xuXG4gICAgZnVuY3Rpb24gcG9zdERvbVJlYWR5KGV2ZW50KSB7XG4gICAgICAgIHNlbGYucG9zdE1lc3NhZ2UoJ2RvbXJlYWR5JywgZXZlbnQpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBGcmFtZSRkZXN0cm95KCkge1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiBGcmFtZSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHJpZXZlcyB0aGUgaW50ZXJuYWwgd2luZG93IG9mIHRoZSBmcmFtZSBcbiAqXG4gKiBAcGFyYW0ge1dpbmRvd31cbiAqL1xuZnVuY3Rpb24gRnJhbWUkZ2V0V2luZG93KCkge1xuICAgIHJldHVybiB0aGlzLm93bmVyLmVsLmNvbnRlbnRXaW5kb3c7XG59XG5cblxuLyoqXG4gKiBGcmFtZSBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgZG9jdW1lbnQucmVhZHlTdGF0ZSBpZiBmcmFtZSBkb3VtZW50IHN0YXRlIGlzICdpbnRlcmFjdGl2ZScgb3IgJ2NvbXBsZXRlJywgZmFsc2Ugb3RoZXJ3aXNlXG4gKlxuICogQHJldHVybiB7U3RyaW5nfEJvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIEZyYW1lJGlzUmVhZHkoKSB7XG4gICAgdmFyIHJlYWR5U3RhdGUgPSB0aGlzLmdldFdpbmRvdygpLmRvY3VtZW50LnJlYWR5U3RhdGU7XG4gICAgcmV0dXJuICByZWFkeVN0YXRlICE9ICdsb2FkaW5nJyA/IHJlYWR5U3RhdGUgOiBmYWxzZTtcbn1cblxuXG4vKipcbiAqIEZyYW1lIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyB0cnVlIGlmIG1pbG8gaXMgbG9hZGVkIGFuZCBoYXMgZmluaXNoZWQgaW5pdGlhbGl6aW5nIGluc2lkZSB0aGUgZnJhbWVcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBGcmFtZSRpc01pbG9SZWFkeSgpIHtcbiAgICB2YXIgZnJhbWVNaWxvID0gdGhpcy5nZXRXaW5kb3coKS5taWxvO1xuICAgIHJldHVybiB0aGlzLmlzUmVhZHkoKSAmJiBmcmFtZU1pbG8gJiYgZnJhbWVNaWxvLm1pbG9fdmVyc2lvbjtcbn1cblxuXG4vKipcbiAqIEdpdmVzIGFjY2VzcyB0byBtaWxvIGluIHRoZSBmcmFtZSAoYXNzdW1pbmcgaXQgaXMgbG9hZGVkIHRoZXJlKVxuICogQ2FsbHMgZnVuY3Rpb24gd2hlbiBib3RoIG1pbG8gYW5kIERPTSBhcmUgcmVhZHkgaWYgZnVuY3Rpb24gaXMgcGFzc2VkLlxuICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIG1pbG8gaW5zaWRlIHRoZSBmcmFtZSBpZiB0aGUgd2luZG93IGlzIGFscmVhZHkgYXZhaWxhYmxlLlxuICogXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIG1pbG8gYW5kIERPTSBhcmUgcmVhZHkgaW4gdGhlIGZyYW1lXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gcmVmZXJlbmNlIHRvIG1pbG8gaW4gdGhlIGZyYW1lIFxuICovXG5mdW5jdGlvbiBGcmFtZSRtaWxvKGZ1bmMpIHtcbiAgICBpZiAodHlwZW9mIGZ1bmMgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMud2hlbk1pbG9SZWFkeShmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHNlbGYuZ2V0V2luZG93KCkubWlsbyhmdW5jKVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdmFyIHdpbiA9IHRoaXMuZ2V0V2luZG93KCk7XG4gICAgcmV0dXJuIHdpbiAmJiB3aW4ubWlsbztcbn1cblxuXG5mdW5jdGlvbiBfbWFrZVdoZW5SZWFkeUZ1bmMoaXNSZWFkeUZ1bmMsIGV2ZW50KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIEZyYW1lX3doZW5SZWFkeUZ1bmMoZnVuYykgeyAvLyAsIGFyZ3VtZW50c1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICAgICAgICAgICwgYXJncyA9IF8uc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgaWYgKGlzUmVhZHlGdW5jLmNhbGwodGhpcykpXG4gICAgICAgICAgICBjYWxsRnVuYygpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLm9uKGV2ZW50LCBjYWxsRnVuYyk7XG5cbiAgICAgICAgZnVuY3Rpb24gY2FsbEZ1bmMoKSB7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcbiAgICAsIE1vZGVsID0gcmVxdWlyZSgnLi4vLi4vbW9kZWwnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBtaWxvTWFpbCA9IHJlcXVpcmUoJy4uLy4uL3NlcnZpY2VzL21haWwnKTtcblxuXG52YXIgSXRlbUZhY2V0ID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ0l0ZW0nKTtcblxuXy5leHRlbmRQcm90byhJdGVtRmFjZXQsIHtcbiAgICBnZXRTdGF0ZTogSXRlbUZhY2V0JGdldFN0YXRlLFxuICAgIHNldFN0YXRlOiBJdGVtRmFjZXQkc2V0U3RhdGUsXG4gICAgZ2V0SW5kZXg6IEl0ZW1GYWNldCRnZXRJbmRleCxcbiAgICBzZXRJbmRleDogSXRlbUZhY2V0JHNldEluZGV4LFxuICAgIHJlbW92ZUl0ZW06IEl0ZW1GYWNldCRyZW1vdmVJdGVtLFxuICAgIGV4dHJhY3RJdGVtOiBJdGVtRmFjZXQkZXh0cmFjdEl0ZW0sXG4gICAgcmVxdWlyZTogWydDb250YWluZXInLCAnRG9tJywgJ0RhdGEnXVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChJdGVtRmFjZXQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEl0ZW1GYWNldDtcblxuXG5mdW5jdGlvbiBJdGVtRmFjZXQkZ2V0U3RhdGUoKSB7XG4gICAgcmV0dXJuIHsgc3RhdGU6IHtcbiAgICAgICAgaW5kZXg6IHRoaXMuZ2V0SW5kZXgoKVxuICAgIH19O1xufVxuXG5cbmZ1bmN0aW9uIEl0ZW1GYWNldCRzZXRTdGF0ZShzdGF0ZSkge1xuICAgIHRoaXMuc2V0SW5kZXgoc3RhdGUuc3RhdGUuaW5kZXgpO1xufVxuXG5cbi8qKlxuICogRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgb3duZXIgY29tcG9uZW50IGluIGl0J3MgcGFyZW50IGxpc3QgY29tcG9uZW50XG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgaW5kZXhcbiAqL1xuZnVuY3Rpb24gSXRlbUZhY2V0JGdldEluZGV4KCkge1xuICAgIHJldHVybiB0aGlzLmluZGV4O1xufVxuXG5cbi8qKlxuICogRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRoZSBpbmRleCBvZiB0aGlzIGNvbXBvbmVudFxuICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCBUaGUgaW5kZXggdG8gYmUgc2V0XG4gKi9cbmZ1bmN0aW9uIEl0ZW1GYWNldCRzZXRJbmRleChpbmRleCkge1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbn1cblxuXG4vKipcbiAqIEl0ZW1GYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJlbW92ZXMgY29tcG9uZW50IGZyb20gdGhlIGxpc3QsIGNvbXBvbmVudCBnZXRzIGRlc3Ryb3llZFxuICovXG5mdW5jdGlvbiBJdGVtRmFjZXQkcmVtb3ZlSXRlbSgpIHtcbiAgICAvLyB0aGlzLmxpc3QgYW5kIHRoaXMuaW5kZXggYXJlIHNldCBieSB0aGUgbGlzdCB3aGVuIHRoZSBpdGVtIGlzIGFkZGVkXG4gICAgdGhpcy5saXN0LnJlbW92ZUl0ZW0odGhpcy5pbmRleCk7XG59XG5cblxuLyoqXG4gKiBJdGVtRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZW1vdmVzIGNvbXBvbmVudCBmcm9tIHRoZSBsaXN0LCBjb21wb25lbnQgaXMgTk9UIGRlc3Ryb3llZFxuICovXG5mdW5jdGlvbiBJdGVtRmFjZXQkZXh0cmFjdEl0ZW0oKSB7XG4gICAgdGhpcy5saXN0LmV4dHJhY3RJdGVtKHRoaXMuaW5kZXgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50RmFjZXQgPSByZXF1aXJlKCcuLi9jX2ZhY2V0JylcbiAgICAsIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbWlsb01haWwgPSByZXF1aXJlKCcuLi8uLi9zZXJ2aWNlcy9tYWlsJylcbiAgICAsIG1pbG9CaW5kZXIgPSByZXF1aXJlKCcuLi8uLi9iaW5kZXInKVxuICAgICwgbWlsb1V0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJylcbiAgICAsIExpc3RFcnJvciA9IG1pbG9VdGlsLmVycm9yLkxpc3RcbiAgICAsIGxvZ2dlciA9IG1pbG9VdGlsLmxvZ2dlclxuICAgICwgZG9UID0gcmVxdWlyZSgnZG90JylcbiAgICAsIGNoZWNrID0gbWlsb1V0aWwuY2hlY2tcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2hcbiAgICAsIGRvbVV0aWxzID0gbWlsb1V0aWwuZG9tXG4gICAgLCBtaWxvQ29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnJyk7XG5cblxudmFyIExJU1RfU0FNUExFX0NTU19DTEFTUyA9ICdtbC1saXN0LWl0ZW0tc2FtcGxlJztcblxuLyoqXG4gKiBgbWlsby5yZWdpc3RyeS5mYWNldHMuZ2V0KCdMaXN0JylgXG4gKiBGYWNldCBlbmFibGluZyBsaXN0IGZ1bmN0aW9uYWxpdHlcbiAqL1xudmFyIExpc3QgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnTGlzdCcpO1xuXG5fLmV4dGVuZFByb3RvKExpc3QsIHtcbiAgICBpbml0OiBMaXN0JGluaXQsXG4gICAgc3RhcnQ6IExpc3Qkc3RhcnQsXG4gICAgZGVzdHJveTogTGlzdCRkZXN0cm95LFxuXG4gICAgcmVxdWlyZTogWydDb250YWluZXInLCAnRG9tJywgJ0RhdGEnXSxcbiAgICBfaXRlbVByZXZpb3VzQ29tcG9uZW50OiBfaXRlbVByZXZpb3VzQ29tcG9uZW50LFxuXG4gICAgaXRlbTogTGlzdCRpdGVtLFxuICAgIGNvdW50OiBMaXN0JGNvdW50LFxuICAgIGNvbnRhaW5zOiBMaXN0JGNvbnRhaW5zLFxuICAgIGFkZEl0ZW06IExpc3QkYWRkSXRlbSxcbiAgICBhZGRJdGVtczogTGlzdCRhZGRJdGVtcyxcbiAgICByZXBsYWNlSXRlbTogTGlzdCRyZXBsYWNlSXRlbSxcbiAgICByZW1vdmVJdGVtOiBMaXN0JHJlbW92ZUl0ZW0sXG4gICAgZXh0cmFjdEl0ZW06IExpc3QkZXh0cmFjdEl0ZW0sXG4gICAgZWFjaDogTGlzdCRlYWNoLFxuICAgIF9zZXRJdGVtOiBMaXN0JF9zZXRJdGVtLFxuICAgIF9yZW1vdmVJdGVtOiBMaXN0JF9yZW1vdmVJdGVtLFxuICAgIF9hZGRJdGVtOiBMaXN0JF9hZGRJdGVtLFxuICAgIF9hZGRJdGVtczogTGlzdCRfYWRkSXRlbXMsXG4gICAgX2NyZWF0ZUNhY2hlVGVtcGxhdGU6IExpc3QkX2NyZWF0ZUNhY2hlVGVtcGxhdGUsXG4gICAgX3VwZGF0ZURhdGFQYXRoczogTGlzdCRfdXBkYXRlRGF0YVBhdGhzXG59KTtcblxuZmFjZXRzUmVnaXN0cnkuYWRkKExpc3QpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExpc3Q7XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWxpemVkIExpc3QgZmFjZXQgaW5zdGFuY2UgYW5kIHNldHMgdXAgaXRlbSBwcm9wZXJ0aWVzLlxuICovXG5mdW5jdGlvbiBMaXN0JGluaXQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfbGlzdEl0ZW1zOiBbXSxcbiAgICAgICAgX2xpc3RJdGVtc0hhc2g6IHt9XG4gICAgfSk7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnaXRlbVNhbXBsZScsIG51bGwsIF8uV1JJVCk7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFN0YXJ0cyB0aGUgTGlzdCBmYWNldCBpbnN0YW5jZSwgZmluZHMgY2hpbGQgd2l0aCBJdGVtIGZhY2V0LlxuICovXG5mdW5jdGlvbiBMaXN0JHN0YXJ0KCkge1xuICAgIC8vIEZpcmVkIGJ5IF9fYmluZGVyX18gd2hlbiBhbGwgY2hpbGRyZW4gb2YgY29tcG9uZW50IGFyZSBib3VuZFxuICAgIHRoaXMub3duZXIub24oJ2NoaWxkcmVuYm91bmQnLCBvbkNoaWxkcmVuQm91bmQpO1xufVxuXG5cbmZ1bmN0aW9uIG9uQ2hpbGRyZW5Cb3VuZCgpIHtcbiAgICAvLyBnZXQgaXRlbXMgYWxyZWFkeSBpbiB0aGUgbGlzdFxuICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZG9tLmNoaWxkcmVuKClcbiAgICAgICAgLCBpdGVtcyA9IHRoaXMubGlzdC5fbGlzdEl0ZW1zXG4gICAgICAgICwgaXRlbXNIYXNoID0gdGhpcy5saXN0Ll9saXN0SXRlbXNIYXNoO1xuXG4gICAgY2hpbGRyZW4gJiYgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbihjaGlsZEVsKSB7XG4gICAgICAgIHZhciBjb21wID0gQ29tcG9uZW50LmdldENvbXBvbmVudChjaGlsZEVsKTtcbiAgICAgICAgaWYgKGNvbXAgJiYgY29tcC5pdGVtKSB7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKGNvbXApO1xuICAgICAgICAgICAgaXRlbXNIYXNoW2NvbXAubmFtZV0gPSBjb21wO1xuICAgICAgICAgICAgY29tcC5pdGVtLmxpc3QgPSB0aGlzLmxpc3Q7XG4gICAgICAgIH1cbiAgICB9LCB0aGlzKTtcblxuICAgIGlmIChpdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGZvdW5kSXRlbSA9IGl0ZW1zWzBdO1xuICAgICAgICBpdGVtcy5zcGxpY2UoMCwgMSk7XG4gICAgICAgIGRlbGV0ZSBpdGVtc0hhc2hbZm91bmRJdGVtLm5hbWVdO1xuICAgICAgICBpdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICBpdGVtLml0ZW0uc2V0SW5kZXgoaW5kZXgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ29tcG9uZW50IG11c3QgaGF2ZSBvbmUgY2hpbGQgd2l0aCBhbiBJdGVtIGZhY2V0IFxuICAgIGlmICghIGZvdW5kSXRlbSkgdGhyb3cgbmV3IExpc3RFcnJvcignTm8gY2hpbGQgY29tcG9uZW50IGhhcyBJdGVtIGZhY2V0Jyk7XG5cbiAgICB0aGlzLmxpc3QuaXRlbVNhbXBsZSA9IGZvdW5kSXRlbTtcblxuICAgIC8vIEFmdGVyIGtlZXBpbmcgYSByZWZlcmVuY2UgdG8gdGhlIGl0ZW0gc2FtcGxlLCBpdCBtdXN0IGJlIGhpZGRlbiBhbmQgcmVtb3ZlZCBmcm9tIHNjb3BlXG4gICAgZm91bmRJdGVtLmRvbS5oaWRlKCk7XG4gICAgZm91bmRJdGVtLnJlbW92ZSh0cnVlKTtcbiAgICBmb3VuZEl0ZW0uZG9tLnJlbW92ZUNzc0NsYXNzZXMoTElTVF9TQU1QTEVfQ1NTX0NMQVNTKTtcblxuICAgIC8vIHJlbW92ZSByZWZlcmVuY2VzIHRvIGNvbXBvbmVudHMgZnJvbSBzYW1wbGUgaXRlbVxuICAgIGZvdW5kSXRlbS53YWxrU2NvcGVUcmVlKGZ1bmN0aW9uKGNvbXApIHtcbiAgICAgICAgZGVsZXRlIGNvbXAuZWxbbWlsb0NvbmZpZy5jb21wb25lbnRSZWZdO1xuICAgIH0pO1xuXG4gICAgdGhpcy5saXN0Ll9jcmVhdGVDYWNoZVRlbXBsYXRlKCk7XG59XG5cblxuZnVuY3Rpb24gTGlzdCRfY3JlYXRlQ2FjaGVUZW1wbGF0ZSgpIHtcbiAgICBpZiAoIXRoaXMuaXRlbVNhbXBsZSkgcmV0dXJuIGZhbHNlO1xuICAgIFxuICAgIHZhciBpdGVtU2FtcGxlID0gdGhpcy5pdGVtU2FtcGxlO1xuXG4gICAgLy8gY3JlYXRlIGl0ZW0gdGVtcGxhdGUgdG8gaW5zZXJ0IG1hbnkgaXRlbXMgYXQgb25jZVxuICAgIHZhciBpdGVtRWxDb3B5ID0gaXRlbVNhbXBsZS5lbC5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgdmFyIGF0dHIgPSBpdGVtU2FtcGxlLmNvbXBvbmVudEluZm8uYXR0cjtcbiAgICB2YXIgYXR0ckNvcHkgPSBfLmNsb25lKGF0dHIpO1xuICAgIGF0dHIuY29tcE5hbWUgPSAne3s9IGl0LmNvbXBvbmVudE5hbWUoKSB9fSc7XG4gICAgYXR0ci5lbCA9IGl0ZW1FbENvcHk7XG4gICAgYXR0ci5kZWNvcmF0ZSgpO1xuXG4gICAgdmFyIGl0ZW1zVGVtcGxhdGVTdHIgPSBcbiAgICAgICAgICAne3sgdmFyIGkgPSBpdC5jb3VudDsgd2hpbGUoaS0tKSB7IH19J1xuICAgICAgICArIGl0ZW1FbENvcHkub3V0ZXJIVE1MXG4gICAgICAgICsgJ3t7IH0gfX0nO1xuXG4gICAgdGhpcy5pdGVtc1RlbXBsYXRlID0gZG9ULmNvbXBpbGUoaXRlbXNUZW1wbGF0ZVN0cik7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHJpZXZlIGEgcGFydGljdWxhciBjaGlsZCBpdGVtIGJ5IGluZGV4XG4gKiBAcGFyYW0ge0ludGVnZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgY2hpbGQgaXRlbSB0byBnZXQuXG4gKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBjb21wb25lbnQgZm91bmRcbiAqL1xuZnVuY3Rpb24gTGlzdCRpdGVtKGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RJdGVtc1tpbmRleF07XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEdldHMgdGhlIHRvdGFsIG51bWJlciBvZiBjaGlsZCBpdGVtc1xuICogQHJldHVybiB7SW50ZWdlcn0gVGhlIHRvdGFsXG4gKi9cbmZ1bmN0aW9uIExpc3QkY291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RJdGVtcy5sZW5ndGg7XG59XG5cblxuZnVuY3Rpb24gTGlzdCRfc2V0SXRlbShpbmRleCwgY29tcG9uZW50KSB7XG4gICAgdGhpcy5fbGlzdEl0ZW1zLnNwbGljZShpbmRleCwgMCwgY29tcG9uZW50KTtcbiAgICB0aGlzLl9saXN0SXRlbXNIYXNoW2NvbXBvbmVudC5uYW1lXSA9IGNvbXBvbmVudDtcbiAgICBjb21wb25lbnQuaXRlbS5saXN0ID0gdGhpcztcbiAgICBjb21wb25lbnQuaXRlbS5zZXRJbmRleCgraW5kZXgpO1xufVxuXG5cbi8qKlxuICogRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRydWUgaWYgYSBwYXJ0aWN1bGFyIGNoaWxkIGl0ZW0gZXhpc3RzIGluIHRoZSBsaXN0XG4gKiBAcGFyYW0ge0NvbXBvbmVudH0gY29tcG9uZW50IFRoZSBjb21wb25lbnQgdG8gbG9vayBmb3IuXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBMaXN0JGNvbnRhaW5zKGNvbXBvbmVudCkge1xuICAgIHJldHVybiB0aGlzLl9saXN0SXRlbXNIYXNoW2NvbXBvbmVudC5uYW1lXSA9PSBjb21wb25lbnQ7XG59XG5cblxuLyoqXG4gKiBGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEFkZHMgYSBuZXcgY2hpbGQgY29tcG9uZW50IGF0IGEgcGFydGljdWxhciBpbmRleCBhbmQgcmV0dXJucyB0aGUgbmV3IGNvbXBvbmVudC5cbiAqIFRoaXMgbWV0aG9kIHVzZXMgZGF0YSBmYWNldCwgc28gbm90aWZpY2F0aW9uIHdpbGwgYmUgZW1pdHRlZCBvbiBkYXRhIGZhY2V0LlxuICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCBUaGUgaW5kZXggdG8gYWRkIGF0XG4gKiBAcmV0dXJuIHtDb21wb25lbnR9IFRoZSBuZXdseSBjcmVhdGVkIGNvbXBvbmVudFxuICovXG5mdW5jdGlvbiBMaXN0JGFkZEl0ZW0oaW5kZXgsIGl0ZW1EYXRhKSB7XG4gICAgaW5kZXggPSBpbmRleCB8fCB0aGlzLmNvdW50KCk7XG4gICAgdGhpcy5vd25lci5kYXRhLnNwbGljZShpbmRleCwgMCwgaXRlbURhdGEgfHwge30pO1xuICAgIHJldHVybiB0aGlzLml0ZW0oaW5kZXgpO1xufVxuXG5cbi8qKlxuICogRmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBBZGRzIGEgbmV3IGNoaWxkIGNvbXBvbmVudCBhdCBhIHBhcnRpY3VsYXIgaW5kZXggYW5kIHJldHVybnMgdGhlIG5ldyBjb21wb25lbnRcbiAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggVGhlIGluZGV4IHRvIGFkZCBhdFxuICogQHJldHVybiB7Q29tcG9uZW50fSBUaGUgbmV3bHkgY3JlYXRlZCBjb21wb25lbnRcbiAqL1xuZnVuY3Rpb24gTGlzdCRfYWRkSXRlbShpbmRleCkge1xuICAgIGluZGV4ID0gaW5kZXggfHwgdGhpcy5jb3VudCgpO1xuICAgIGlmICh0aGlzLml0ZW0oaW5kZXgpKVxuICAgICAgICB0aHJvdyBMaXN0RXJyb3IoJ2F0dGVtcHQgdG8gY3JlYXRlIGl0ZW0gd2l0aCBJRCBvZiBleGlzdGluZyBpdGVtJyk7XG5cbiAgICAvLyBDb3B5IGNvbXBvbmVudFxuICAgIHZhciBjb21wb25lbnQgPSBDb21wb25lbnQuY29weSh0aGlzLml0ZW1TYW1wbGUsIHRydWUpO1xuICAgIHZhciBwcmV2Q29tcG9uZW50ID0gdGhpcy5faXRlbVByZXZpb3VzQ29tcG9uZW50KGluZGV4KTtcblxuICAgIGlmICghcHJldkNvbXBvbmVudC5lbC5wYXJlbnROb2RlKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ2xpc3QgaXRlbSBzYW1wbGUgd2FzIHJlbW92ZWQgZnJvbSBET00sIHByb2JhYmx5IGNhdXNlZCBieSB3cm9uZyBkYXRhLiBSZXNldCBsaXN0IGRhdGEgd2l0aCBhcnJheScpO1xuXG4gICAgLy8gQWRkIGl0IHRvIHRoZSBET01cbiAgICBwcmV2Q29tcG9uZW50LmRvbS5pbnNlcnRBZnRlcihjb21wb25lbnQuZWwpO1xuXG4gICAgLy8gQWRkIHRvIGxpc3QgaXRlbXNcbiAgICB0aGlzLl9zZXRJdGVtKGluZGV4LCBjb21wb25lbnQpO1xuXG4gICAgLy8gU2hvdyB0aGUgbGlzdCBpdGVtIGNvbXBvbmVudFxuICAgIGNvbXBvbmVudC5lbC5zdHlsZS5kaXNwbGF5ID0gJyc7XG5cbiAgICBfdXBkYXRlSXRlbXNJbmRleGVzLmNhbGwodGhpcywgaW5kZXggKyAxKTtcblxuICAgIHJldHVybiBjb21wb25lbnQ7XG59XG5cblxuZnVuY3Rpb24gX3VwZGF0ZUl0ZW1zSW5kZXhlcyhmcm9tSW5kZXgsIHRvSW5kZXgpIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggfHwgMDtcbiAgICB0b0luZGV4ID0gdG9JbmRleCB8fCB0aGlzLmNvdW50KCk7XG4gICAgZm9yICh2YXIgaSA9IGZyb21JbmRleDsgaSA8IHRvSW5kZXg7IGkrKykge1xuICAgICAgICB2YXIgY29tcG9uZW50ID0gdGhpcy5fbGlzdEl0ZW1zW2ldO1xuICAgICAgICBpZiAoY29tcG9uZW50KVxuICAgICAgICAgICAgY29tcG9uZW50Lml0ZW0uc2V0SW5kZXgoaSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdMaXN0OiBubyBpdGVtIGF0IHBvc2l0aW9uJywgaSk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIExpc3QkYWRkSXRlbXMoY291bnQsIGluZGV4KSB7IC8vICwuLi4gaXRlbXMgZGF0YVxuICAgIHZhciBpdGVtc0RhdGEgPSBfLnNsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgaWYgKGl0ZW1zRGF0YS5sZW5ndGggPCBjb3VudCkgXG4gICAgICAgIGl0ZW1zRGF0YS5jb25jYXQoXy5yZXBlYXQoY291bnQgLSBpdGVtc0RhdGEubGVuZ3RoLCB7fSkpO1xuICAgIHZhciBzcGxpY2VBcmdzID0gW2luZGV4LCAwXS5jb25jYXQoaXRlbXNEYXRhKTtcbiAgICB2YXIgZGF0YUZhY2V0ID0gdGhpcy5vd25lci5kYXRhO1xuICAgIGRhdGFGYWNldC5zcGxpY2UuYXBwbHkoZGF0YUZhY2V0LCBzcGxpY2VBcmdzKTtcbn1cblxuXG4vKipcbiAqIExpc3QgZmFjZXQgaW5zdGFuY2UgbWV0aG9kXG4gKiBBZGRzIGEgZ2l2ZW4gbnVtYmVyIG9mIGl0ZW1zIHVzaW5nIHRlbXBsYXRlIHJlbmRlcmluZyByYXRoZXIgdGhhbiBhZGRpbmcgZWxlbWVudHMgb25lIGJ5IG9uZVxuICpcbiAqIEBwYXJhbSB7SW50ZWdlcn0gY291bnQgbnVtYmVyIG9mIGl0ZW1zIHRvIGFkZFxuICogQHBhcmFtIHtbSW50ZWdlcl19IGluZGV4IG9wdGlvbmFsIGluZGV4IG9mIGl0ZW0gYWZ0ZXIgd2hpY2ggdG8gYWRkXG4gKi9cbmZ1bmN0aW9uIExpc3QkX2FkZEl0ZW1zKGNvdW50LCBpbmRleCkge1xuICAgIGNoZWNrKGNvdW50LCBNYXRjaC5JbnRlZ2VyKTtcbiAgICBpZiAoY291bnQgPCAwKVxuICAgICAgICB0aHJvdyBuZXcgTGlzdEVycm9yKCdjYW5cXCd0IGFkZCBuZWdhdGl2ZSBudW1iZXIgb2YgaXRlbXMnKTtcblxuICAgIGlmIChjb3VudCA9PSAwKSByZXR1cm47XG5cbiAgICB2YXIgaXRlbXNIVE1MID0gdGhpcy5pdGVtc1RlbXBsYXRlKHtcbiAgICAgICAgY29tcG9uZW50TmFtZTogbWlsb1V0aWwuY29tcG9uZW50TmFtZSxcbiAgICAgICAgY291bnQ6IGNvdW50XG4gICAgfSk7XG5cbiAgICB2YXIgd3JhcEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgd3JhcEVsLmlubmVySFRNTCA9IGl0ZW1zSFRNTDtcblxuICAgIG1pbG9CaW5kZXIod3JhcEVsLCB0aGlzLm93bmVyLmNvbnRhaW5lci5zY29wZSk7XG4gICAgdmFyIGNoaWxkcmVuID0gZG9tVXRpbHMuY2hpbGRyZW4od3JhcEVsKTtcblxuICAgIGlmIChjb3VudCAhPSBjaGlsZHJlbi5sZW5ndGgpXG4gICAgICAgIGxvZ2dlci5lcnJvcignbnVtYmVyIG9mIGl0ZW1zIGFkZGVkIGlzIGRpZmZlcmVudCBmcm9tIHJlcXVlc3RlZCcpO1xuXG4gICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICB2YXIgbGlzdExlbmd0aCA9IHRoaXMuY291bnQoKTtcbiAgICAgICAgdmFyIHNwbGljZUluZGV4ID0gaW5kZXggPCAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgaW5kZXggPT0gJ3VuZGVmaW5lZCcgfHwgaW5kZXggPiBsaXN0TGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gbGlzdExlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGluZGV4O1xuXG4gICAgICAgIHZhciBwcmV2Q29tcG9uZW50ID0gc3BsaWNlSW5kZXggPT0gMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuaXRlbVNhbXBsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX2xpc3RJdGVtc1tzcGxpY2VJbmRleCAtIDFdO1xuXG4gICAgICAgIHZhciBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gICAgICAgICAgICAsIG5ld0NvbXBvbmVudHMgPSBbXTtcblxuICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGVsLCBpKSB7XG4gICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gQ29tcG9uZW50LmdldENvbXBvbmVudChlbCk7XG4gICAgICAgICAgICBpZiAoISBjb21wb25lbnQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcignTGlzdDogZWxlbWVudCBpbiBuZXcgaXRlbXMgaXMgbm90IGEgY29tcG9uZW50Jyk7XG4gICAgICAgICAgICBuZXdDb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcbiAgICAgICAgICAgIHRoaXMuX3NldEl0ZW0oc3BsaWNlSW5kZXgrKywgY29tcG9uZW50KTtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgICB9LCB0aGlzKTtcblxuICAgICAgICBfdXBkYXRlSXRlbXNJbmRleGVzLmNhbGwodGhpcywgc3BsaWNlSW5kZXgpO1xuXG4gICAgICAgIGlmICghcHJldkNvbXBvbmVudC5lbC5wYXJlbnROb2RlKVxuICAgICAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdsaXN0IGl0ZW0gc2FtcGxlIHdhcyByZW1vdmVkIGZyb20gRE9NLCBwcm9iYWJseSBjYXVzZWQgYnkgd3JvbmcgZGF0YS4gUmVzZXQgbGlzdCBkYXRhIHdpdGggYXJyYXknKTtcblxuICAgICAgICAvLyBBZGQgaXQgdG8gdGhlIERPTVxuICAgICAgICBwcmV2Q29tcG9uZW50LmRvbS5pbnNlcnRBZnRlcihmcmFnKTtcblxuICAgICAgICBfLmRlZmVyTWV0aG9kKG5ld0NvbXBvbmVudHMsICdmb3JFYWNoJywgZnVuY3Rpb24oY29tcCkge1xuICAgICAgICAgICAgY29tcC5icm9hZGNhc3QoJ3N0YXRlcmVhZHknKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogTGlzdCBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBpdGVtIHRvIHJlbW92ZVxuICogQHJldHVybiB7QXJyYXlbT2JqZWN0XX0gVGhlIHNwbGljZWQgZGF0YVxuICovXG5mdW5jdGlvbiBMaXN0JHJlbW92ZUl0ZW0oaW5kZXgpIHtcbiAgICByZXR1cm4gdGhpcy5vd25lci5kYXRhLnNwbGljZShpbmRleCwgMSk7XG59XG5cblxuLyoqXG4gKiBMaXN0IGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGl0ZW0gdG8gZXh0cmFjdFxuICogQHJldHVybiB7Q29tcG9uZW50fSBUaGUgZXh0cmFjdGVkIGl0ZW1cbiAqL1xuZnVuY3Rpb24gTGlzdCRleHRyYWN0SXRlbShpbmRleCkge1xuICAgIHZhciBpdGVtQ29tcCA9IHRoaXMuX3JlbW92ZUl0ZW0oaW5kZXgsIGZhbHNlKTtcbiAgICB0aGlzLl91cGRhdGVEYXRhUGF0aHMoaW5kZXgsIHRoaXMuY291bnQoKSk7XG4gICAgcmV0dXJuIGl0ZW1Db21wO1xufVxuXG5cbi8qKlxuICogTGlzdCBmYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIFJlbW92ZXMgaXRlbSwgcmV0dXJucyB0aGUgcmVtb3ZlZCBpdGVtIHRoYXQgaXMgZGVzdHJveWVkIGJ5IGRlZmF1bHQuXG4gKiBcbiAqIEBwYXJhbSAge051bWJlcn0gaW5kZXggaXRlbSBpbmRleFxuICogQHBhcmFtICB7Qm9vbGVhbn0gZG9EZXN0cm95SXRlbSBvcHRpb25hbCBmYWxzZSB0byBwcmV2ZW50IGl0ZW0gZGVzdHJ1Y3Rpb24sIHRydWUgYnkgZGVmYXVsdFxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG5mdW5jdGlvbiBMaXN0JF9yZW1vdmVJdGVtKGluZGV4LCBkb0Rlc3Ryb3lJdGVtKSB7XG4gICAgdmFyIGNvbXAgPSB0aGlzLml0ZW0oaW5kZXgpO1xuXG4gICAgaWYgKCEgY29tcClcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdhdHRlbXB0IHRvIHJlbW92ZSBsaXN0IGl0ZW0gd2l0aCBpZCB0aGF0IGRvZXMgbm90IGV4aXN0Jyk7XG5cbiAgICB0aGlzLl9saXN0SXRlbXNbaW5kZXhdID0gdW5kZWZpbmVkO1xuICAgIGRlbGV0ZSB0aGlzLl9saXN0SXRlbXNIYXNoW2NvbXAubmFtZV07XG4gICAgaWYgKGRvRGVzdHJveUl0ZW0gIT09IGZhbHNlKSBjb21wLmRlc3Ryb3koKTtcbiAgICBlbHNlIHtcbiAgICAgICAgY29tcC5yZW1vdmUoKTtcbiAgICAgICAgY29tcC5kb20ucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fbGlzdEl0ZW1zLnNwbGljZShpbmRleCwgMSk7XG4gICAgX3VwZGF0ZUl0ZW1zSW5kZXhlcy5jYWxsKHRoaXMsIGluZGV4KTtcblxuICAgIHJldHVybiBjb21wO1xufVxuXG5cbmZ1bmN0aW9uIExpc3QkcmVwbGFjZUl0ZW0oaW5kZXgsIG5ld0l0ZW0pe1xuICAgIHZhciBvbGRJdGVtID0gdGhpcy5pdGVtKGluZGV4KTtcbiAgICBvbGRJdGVtLmRvbS5pbnNlcnRBZnRlcihuZXdJdGVtLmVsKTtcbiAgICB0aGlzLl9yZW1vdmVJdGVtKGluZGV4KTtcbiAgICB0aGlzLl9zZXRJdGVtKGluZGV4LCBuZXdJdGVtKTtcbn1cblxuXG4vLyBSZXR1cm5zIHRoZSBwcmV2aW91cyBpdGVtIGNvbXBvbmVudCBnaXZlbiBhbiBpbmRleFxuZnVuY3Rpb24gX2l0ZW1QcmV2aW91c0NvbXBvbmVudChpbmRleCkge1xuICAgIHdoaWxlIChpbmRleCA+PSAwICYmICEgdGhpcy5fbGlzdEl0ZW1zW2luZGV4XSlcbiAgICAgICAgaW5kZXgtLTtcblxuICAgIHJldHVybiBpbmRleCA+PSAwXG4gICAgICAgICAgICAgICAgPyB0aGlzLl9saXN0SXRlbXNbaW5kZXhdXG4gICAgICAgICAgICAgICAgOiB0aGlzLml0ZW1TYW1wbGU7XG59XG5cblxuLy8gdG9JbmRleCBpcyBub3QgaW5jbHVkZWRcbi8vIG5vIHJhbmdlIGNoZWNraW5nIGlzIG1hZGVcbmZ1bmN0aW9uIExpc3QkX3VwZGF0ZURhdGFQYXRocyhmcm9tSW5kZXgsIHRvSW5kZXgpIHtcbiAgICBmb3IgKHZhciBpID0gZnJvbUluZGV4OyBpIDwgdG9JbmRleDsgaSsrKSB7XG4gICAgICAgIHZhciBpdGVtID0gdGhpcy5pdGVtKGkpO1xuICAgICAgICBpZiAoaXRlbSlcbiAgICAgICAgICAgIGl0ZW0uZGF0YS5fcGF0aCA9ICdbJyArIGkgKyAnXSc7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdEYXRhOiBubyBpdGVtIGZvciBpbmRleCcsIGopO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU2ltaWxhciB0byBmb3JFYWNoIG1ldGhvZCBvZiBBcnJheSwgaXRlcmF0ZXMgZWFjaCBvZiB0aGUgY2hpbGQgaXRlbXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBBbiBpdGVyYXRvciBmdW5jdGlvbiB0byBiZSBjYWxsZWQgb24gZWFjaCBjaGlsZCBpdGVtLlxuICogQHBhcmFtIHtbdHlwZV19ICAgdGhpc0FyZyAgQ29udGV4dCB0byBzZXQgYHRoaXNgLlxuICovXG5mdW5jdGlvbiBMaXN0JGVhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICB0aGlzLl9saXN0SXRlbXMuZm9yRWFjaChmdW5jdGlvbihpdGVtLCBpbmRleCkge1xuICAgICAgICBpZiAoaXRlbSkgY2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gcGFzc2VzIGl0ZW0sIGluZGV4IHRvIGNhbGxiYWNrXG4gICAgICAgIGVsc2UgbG9nZ2VyLndhcm4oJ0xpc3QkZWFjaDogaXRlbScsIGluZGV4LCAnaXMgdW5kZWZpbmVkJyk7XG4gICAgfSwgdGhpc0FyZyB8fCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogRGVzdHJveXMgdGhlIGxpc3RcbiAqL1xuZnVuY3Rpb24gTGlzdCRkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLml0ZW1TYW1wbGUpIHRoaXMuaXRlbVNhbXBsZS5kZXN0cm95KHRydWUpO1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnRGYWNldCA9IHJlcXVpcmUoJy4uL2NfZmFjZXQnKVxuICAgICwgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuL2NmX3JlZ2lzdHJ5JylcbiAgICAsIE1vZGVsID0gcmVxdWlyZSgnLi4vLi4vbW9kZWwnKVxuICAgICwgTWl4aW4gPSByZXF1aXJlKCcuLi8uLi9hYnN0cmFjdC9taXhpbicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLy8gZ2VuZXJpYyBkcmFnIGhhbmRsZXIsIHNob3VsZCBiZSBvdmVycmlkZGVuXG52YXIgTW9kZWxGYWNldCA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdNb2RlbCcpO1xuXG5fLmV4dGVuZFByb3RvKE1vZGVsRmFjZXQsIHtcbiAgICBpbml0OiBNb2RlbEZhY2V0JGluaXQsXG4gICAgZ2V0U3RhdGU6IE1vZGVsRmFjZXQkZ2V0U3RhdGUsXG4gICAgc2V0U3RhdGU6IE1vZGVsRmFjZXQkc2V0U3RhdGUsXG4gICAgX2NyZWF0ZU1lc3NlbmdlcjogTW9kZWxGYWNldCRfY3JlYXRlTWVzc2VuZ2VyLFxuICAgIGRlc3Ryb3k6IE1vZGVsRmFjZXQkZGVzdHJveVxufSk7XG5cbmZhY2V0c1JlZ2lzdHJ5LmFkZChNb2RlbEZhY2V0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBNb2RlbEZhY2V0O1xuXG5cbi8qKlxuICogRXhwb3NlIE1vZGVsIGNsYXNzIG1ldGhvZHMgb24gTW9kZWxGYWNldFxuICovXG5Nb2RlbC51c2VXaXRoKE1vZGVsRmFjZXQsICdtJyk7XG5cblxuZnVuY3Rpb24gTW9kZWxGYWNldCRpbml0KCkge1xuICAgIHRoaXMubSA9IG5ldyBNb2RlbCh0aGlzLmNvbmZpZy5kYXRhLCB0aGlzKTtcbiAgICBDb21wb25lbnRGYWNldC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIC8vIHRoaXMubS5wcm94eU1ldGhvZHModGhpcyk7IC8vIENyZWF0ZXMgbW9kZWwncyBtZXRob2RzIGRpcmVjdGx5IG9uIGZhY2V0XG59XG5cblxuLyoqXG4gKiBNb2RlbEZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IGBDb21wb25lbnQucHJvdG90eXBlLmdldFN0YXRlYCB0byBnZXQgZmFjZXQncyBzdGF0ZVxuICogU2ltcGx5IHJldHVybnMgbW9kZWwgZGF0YVxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gTW9kZWxGYWNldCRnZXRTdGF0ZSgpIHtcbiAgICB2YXIgbW9kZWxWYWx1ZSA9IHRoaXMubS5nZXQoKTtcbiAgICBpZiAodHlwZW9mIG1vZGVsVmFsdWUgPT0gJ29iamVjdCcpXG4gICAgICAgIG1vZGVsVmFsdWUgPSBfLmRlZXBDbG9uZShtb2RlbFZhbHVlKTtcbiAgICByZXR1cm4geyBzdGF0ZTogbW9kZWxWYWx1ZSB9O1xufVxuXG5cbi8qKlxuICogTW9kZWxGYWNldCBpbnN0YW5jZSBtZXRob2RcbiAqIENhbGxlZCBieSBgQ29tcG9uZW50LnByb3RvdHlwZS5zZXRTdGF0ZWAgdG8gc2V0IGZhY2V0J3Mgc3RhdGVcbiAqIFNpbXBseSBzZXRzIG1vZGVsIGRhdGFcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc3RhdGUgZGF0YSB0byBzZXQgb24gZmFjZXQncyBtb2RlbFxuICovXG5mdW5jdGlvbiBNb2RlbEZhY2V0JHNldFN0YXRlKHN0YXRlKSB7XG4gICAgcmV0dXJuIHRoaXMubS5zZXQoc3RhdGUuc3RhdGUpO1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsRmFjZXQkX2NyZWF0ZU1lc3NlbmdlcigpIHsgLy8gQ2FsbGVkIGJ5IGluaGVyaXRlZCBpbml0XG4gICAgdGhpcy5fbWVzc2VuZ2VyID0gdGhpcy5tLl9tZXNzZW5nZXI7XG59XG5cblxuZnVuY3Rpb24gTW9kZWxGYWNldCRkZXN0cm95KCkge1xuICAgIHRoaXMubS5kZXN0cm95KCk7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgTW9kZWwgPSByZXF1aXJlKCcuLi8uLi9tb2RlbCcpXG5cbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vLyBnZW5lcmljIGRyYWcgaGFuZGxlciwgc2hvdWxkIGJlIG92ZXJyaWRkZW5cbnZhciBPcHRpb25zID0gXy5jcmVhdGVTdWJjbGFzcyhDb21wb25lbnRGYWNldCwgJ09wdGlvbnMnKTtcblxuXy5leHRlbmRQcm90byhPcHRpb25zLCB7XG4gICAgaW5pdDogT3B0aW9ucyRpbml0LFxuICAgIGRlc3Ryb3k6IE9wdGlvbnMkZGVzdHJveSxcbiAgICBfY3JlYXRlTWVzc2VuZ2VyOiBPcHRpb25zJF9jcmVhdGVNZXNzZW5nZXJcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoT3B0aW9ucyk7XG5cbm1vZHVsZS5leHBvcnRzID0gT3B0aW9ucztcblxuXG5mdW5jdGlvbiBPcHRpb25zJGluaXQoKSB7XG4gICAgdGhpcy5tID0gbmV3IE1vZGVsKHRoaXMuY29uZmlnLm9wdGlvbnMsIHRoaXMpO1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5tLnByb3h5TWV0aG9kcyh0aGlzKTsgLy8gQ3JlYXRlcyBtb2RlbCdzIG1ldGhvZHMgZGlyZWN0bHkgb24gZmFjZXRcbn1cblxuXG5mdW5jdGlvbiBPcHRpb25zJF9jcmVhdGVNZXNzZW5nZXIoKSB7IC8vIENhbGxlZCBieSBpbmhlcml0ZWQgaW5pdFxuICAgIHRoaXMuX21lc3NlbmdlciA9IHRoaXMubS5fbWVzc2VuZ2VyO1xufVxuXG5cbmZ1bmN0aW9uIE9wdGlvbnMkZGVzdHJveSgpIHtcbiAgICB0aGlzLm0uZGVzdHJveSgpO1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIDxhIG5hbWU9XCJjb21wb25lbnRzLWZhY2V0cy10ZW1wbGF0ZVwiPjwvYT5cbi8vICMjI3RlbXBsYXRlIGZhY2V0XG5cbi8vIHNpbXBsaWZpZXMgcmVuZGVyaW5nIG9mIGNvbXBvbmVudCBlbGVtZW50IGZyb20gdGVtcGxhdGUuXG4vLyAgIEFueSB0ZW1wbGF0aW5nIGVuZ2luZyBjYW4gYmUgdXNlZCB0aGF0IHN1cHBvcnRzIHRlbXBsYXRlIGNvbXBpbGF0aW9uXG4vLyAgIChvciB5b3UgY2FuIG1vY2sgdGhpcyBjb21waWxhdGlvbiBlYXNpbHkgYnkgY3JlYXRpbmcgY2xvc3VyZSBzdG9yaW5nXG4vLyAgIHRlbXBsYXRlIHN0cmluZyBpbiBjYXNlIHlvdXIgZW5naW5lIGRvZXNuJ3Qgc3VwcG9ydCBjb21waWxhdGlvbikuXG4vLyAgIEJ5IGRlZmF1bHQgbWlsbyB1c2VzIFtkb1RdKCksIHRoZSBtb3N0IHZlcnNhdGlsZSwgY29uc2Npc2UgYW5kIGF0IHRoZVxuLy8gICBzYW1lIHRpbWUgdGhlIGZhc3Rlc3QgdGVtcGxhdGluZyBlbmdpbmUuXG4vLyAgIElmIHlvdSB1c2UgbWlsbyBpbiBicm93c2VyLCBpdCBpcyB0aGUgcGFydCBvZiBtaWxvIGJ1bmRsZSBhbmQgYXZhaWxhYmxlXG4vLyAgIGFzIGdsb2JhbCB2YXJpYWJsZSBgZG9UYC5cblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgYmluZGVyID0gcmVxdWlyZSgnLi4vLi4vYmluZGVyJyk7XG5cblxuLy8gZGF0YSBtb2RlbCBjb25uZWN0aW9uIGZhY2V0XG52YXIgVGVtcGxhdGUgPSBfLmNyZWF0ZVN1YmNsYXNzKENvbXBvbmVudEZhY2V0LCAnVGVtcGxhdGUnKTtcblxuXy5leHRlbmRQcm90byhUZW1wbGF0ZSwge1xuICAgIGluaXQ6IFRlbXBsYXRlJGluaXQsXG4gICAgc3RhcnQ6IFRlbXBsYXRlJHN0YXJ0LFxuICAgIHNldDogVGVtcGxhdGUkc2V0LFxuICAgIGdldENvbXBpbGVkOiBUZW1wbGF0ZSRnZXRDb21waWxlZCxcbiAgICByZW5kZXI6IFRlbXBsYXRlJHJlbmRlcixcbiAgICBiaW5kZXI6IFRlbXBsYXRlJGJpbmRlclxuXG4gICAgLy8gX3JlYXR0YWNoOiBfcmVhdHRhY2hFdmVudHNPbkVsZW1lbnRDaGFuZ2Vcbn0pO1xuXG5mYWNldHNSZWdpc3RyeS5hZGQoVGVtcGxhdGUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRlbXBsYXRlO1xuXG5cbmZ1bmN0aW9uIFRlbXBsYXRlJGluaXQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIHRlbXBsYXRlcyBhcmUgaW50ZXJwb2xhdGVkIHdpdGggZGVmYXVsdCAoZG9UKSBvciBjb25maWd1cmVkIGVuZ2luZSAodGhpcy5jb25maWcuY29tcGlsZSlcbiAgICAvLyB1bmxlc3MgdGhpcy5jb25maWcuaW50ZXJwb2xhdGUgaXMgZmFsc2VcbiAgICB2YXIgY29tcGlsZSA9IHRoaXMuY29uZmlnLmludGVycG9sYXRlID09PSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuY29uZmlnLmNvbXBpbGUgfHwgbWlsby5jb25maWcudGVtcGxhdGUuY29tcGlsZTtcblxuICAgIHRoaXMuc2V0KHRoaXMuY29uZmlnLnRlbXBsYXRlIHx8ICcnLCBjb21waWxlLCB0aGlzLmNvbmZpZy5jb21waWxlT3B0aW9ucyk7XG59XG5cblxuZnVuY3Rpb24gVGVtcGxhdGUkc3RhcnQoKSB7XG4gICAgQ29tcG9uZW50RmFjZXQucHJvdG90eXBlLnN0YXJ0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHRoaXMuY29uZmlnLmF1dG9SZW5kZXIpIHtcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLmF1dG9CaW5kZXIpXG4gICAgICAgICAgICB0aGlzLmJpbmRlcigpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBUZW1wbGF0ZSRnZXRDb21waWxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGVtcGxhdGU7XG59XG5cblxuZnVuY3Rpb24gVGVtcGxhdGUkc2V0KHRlbXBsYXRlU3RyLCBjb21waWxlLCBjb21waWxlT3B0aW9ucykge1xuICAgIGNoZWNrKHRlbXBsYXRlU3RyLCBNYXRjaC5PbmVPZihTdHJpbmcsIEZ1bmN0aW9uKSk7XG4gICAgY2hlY2soY29tcGlsZSwgTWF0Y2guT3B0aW9uYWwoRnVuY3Rpb24pKTtcblxuICAgIGlmICh0eXBlb2YgdGVtcGxhdGVTdHIgPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhpcy5fdGVtcGxhdGUgPSB0ZW1wbGF0ZVN0cjtcbiAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5fdGVtcGxhdGVTdHIgPSB0ZW1wbGF0ZVN0cjtcbiAgICAgICAgaWYgKGNvbXBpbGUpXG4gICAgICAgICAgICB0aGlzLl9jb21waWxlID0gY29tcGlsZTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29tcGlsZSA9IHRoaXMuX2NvbXBpbGU7XG5cbiAgICAgICAgaWYgKGNvbXBpbGUpXG4gICAgICAgICAgICB0aGlzLl90ZW1wbGF0ZSA9IGNvbXBpbGUodGVtcGxhdGVTdHIsIGNvbXBpbGVPcHRpb25zKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG5mdW5jdGlvbiBUZW1wbGF0ZSRyZW5kZXIoZGF0YSkgeyAvLyB3ZSBuZWVkIGRhdGEgb25seSBpZiB1c2UgdGVtcGxhdGluZyBlbmdpbmVcbiAgICB0aGlzLm93bmVyLmVsLmlubmVySFRNTCA9IHRoaXMuX3RlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdGhpcy5fdGVtcGxhdGUoZGF0YSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0aGlzLl90ZW1wbGF0ZVN0cjtcblxuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbmZ1bmN0aW9uIFRlbXBsYXRlJGJpbmRlcigpIHtcbiAgICBpZiAodGhpcy5vd25lci5jb250YWluZXIpXG4gICAgICAgIHJldHVybiB0aGlzLm93bmVyLmNvbnRhaW5lci5iaW5kZXIoKTtcbiAgICBlbHNlXG4gICAgICAgIGxvZ2dlci5lcnJvcignVGVtcGxhdGVGYWNldDogQmluZGVyIGNhbGxlZCB3aXRob3V0IGNvbnRhaW5lciBmYWNldC4nKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY2ZfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8qKlxuICogVHJhbnNmZXIgZmFjZXQgaXMgZGVzaWduZWQgZm9yIGNvbXBvbmVudHMgdG8gYmUgYWJsZSB0byByZXByZXNlbnQgb3RoZXIgY29tcG9uZW50c1xuICogSWYgYSBbQ29tcG9uZW50XSguLi9jX2NsYXNzLmpzLmh0bWwpIGhhcyBUcmFuc2ZlciBmYWNldCwgd2hlbiBgQ29tcG9uZW50LmdldFN0YXRlYCBpcyBjYWxsZWQgZm9yIHRoaXMgY29tcG9uZXQgaXQgcmV0dXJucyBwcmV2aW91c2x5IHNhdmVkIGRhdGEsIHBvc3NpYmx5IGZyb20gYW5vdGhlciBjb21wb25lbnQuXG4gKiBGb3IgZXhhbXBsZSwgYSBsaXN0IG9mIGRvY3VtZW50cyBjYW4gdXNlIHRoaXMgZmFjZXQgc28gdGhhdCBlYWNoIGl0ZW0gaW4gdGhlIGxpc3QgY2FuIHN0b3JlIGFjdHVhbCBkb2N1bWVudCBjb21wb25lbnQgb24gaXQuXG4gKi9cbnZhciBUcmFuc2ZlciA9IF8uY3JlYXRlU3ViY2xhc3MoQ29tcG9uZW50RmFjZXQsICdUcmFuc2ZlcicpO1xuXG5fLmV4dGVuZFByb3RvKFRyYW5zZmVyLCB7XG4gICAgaW5pdDogVHJhbnNmZXIkaW5pdCxcbiAgICBnZXRTdGF0ZTogVHJhbnNmZXIkZ2V0U3RhdGUsXG4gICAgc2V0U3RhdGU6IFRyYW5zZmVyJHNldFN0YXRlLFxuICAgIHNldEFjdGl2ZVN0YXRlOiBUcmFuc2ZlciRzZXRBY3RpdmVTdGF0ZSxcbiAgICBzZXRTdGF0ZVdpdGhLZXk6IFRyYW5zZmVyJHNldFN0YXRlV2l0aEtleSxcbiAgICBnZXRTdGF0ZVdpdGhLZXk6IFRyYW5zZmVyJGdldFN0YXRlV2l0aEtleSxcbiAgICBnZXRDb21wb25lbnRNZXRhOiBUcmFuc2ZlciRnZXRDb21wb25lbnRNZXRhXG59KTtcblxuZmFjZXRzUmVnaXN0cnkuYWRkKFRyYW5zZmVyKTtcblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2ZlcjtcblxuXG5mdW5jdGlvbiBUcmFuc2ZlciRpbml0KCkge1xuICAgIENvbXBvbmVudEZhY2V0LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5fYWN0aXZlU3RhdGUgPSAnJztcbiAgICB0aGlzLl9kZWZhdWx0S2V5ID0gJyc7XG4gICAgdGhpcy5fc3RhdGUgPSB7fTtcbn1cblxuXG4vKipcbiAqIFRyYW5zZmVyIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyB0cmFuc2ZlciBzdGF0ZSBmb3IgY29tcG9uZW50LiBDYW4gYmUgb2J0YWluZWQgZnJvbSBhbm90aGVyIGNvbXBvbmVudCBieSB1c2luZyBgQ29tcG9uZW50LmdldFN0YXRlYFxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gVHJhbnNmZXIkZ2V0U3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlW3RoaXMuX2FjdGl2ZVN0YXRlXSB8fCB0aGlzLl9zdGF0ZVt0aGlzLl9kZWZhdWx0S2V5XTtcbn1cblxuXG4vKipcbiAqIFRyYW5zZmVyIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU2V0cyB0cmFuc2ZlciBzdGF0ZSBmb3IgY29tcG9uZW50LiBDYW4gYmUgb2J0YWluZWQgZnJvbSBhbm90aGVyIGNvbXBvbmVudCBieSB1c2luZyBgQ29tcG9uZW50LmdldFN0YXRlYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZVxuICovXG5mdW5jdGlvbiBUcmFuc2ZlciRzZXRTdGF0ZShzdGF0ZSkge1xuICAgIHRoaXMuX3N0YXRlWycnXSA9IHN0YXRlO1xuICAgIHRoaXMuc2V0QWN0aXZlU3RhdGUoJycpO1xufVxuXG4vKipcbiAqIFRyYW5zZmVyIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU2V0cyB0aGUgYWN0aXZlIHN0YXRlICh1c2VkIGJ5IGdldFN0YXRlKVxuICogQHBhcmFtIHtbdHlwZV19IGtleSBbZGVzY3JpcHRpb25dXG4gKi9cbmZ1bmN0aW9uIFRyYW5zZmVyJHNldEFjdGl2ZVN0YXRlKGtleSkge1xuICAgIHRoaXMuX2FjdGl2ZVN0YXRlID0ga2V5O1xufVxuXG4vKipcbiAqIFRyYW5zZmVyIGZhY2V0IGluc3RhbmNlIG1ldGhvZFxuICogU2V0cyB0cmFuc2ZlciBzdGF0ZSBmb3IgY29tcG9uZW50IHdpdGhvdXQgZGVmYXVsdCBrZXkuIENhbiBiZSBvYnRhaW5lZCBmcm9tIGFub3RoZXIgY29tcG9uZW50IGJ5IHVzaW5nIGBDb21wb25lbnQuZ2V0U3RhdGVgXG4gKiBXaGVuIHRoZSBhY3RpdmUgc3RhdGUgaXMgc2V0IHRvIHRoZSBleHBlY3RlZCBrZXlcbiAqIEBwYXJhbSB7W3R5cGVdfSBrZXkgICBbZGVzY3JpcHRpb25dXG4gKiBAcGFyYW0ge1t0eXBlXX0gc3RhdGUgW2Rlc2NyaXB0aW9uXVxuICogQHBhcmFtIHtCb29sZWFufSBpc0RlZmF1bHRLZXkgKE9wdGlvbmFsKVxuICovXG5mdW5jdGlvbiBUcmFuc2ZlciRzZXRTdGF0ZVdpdGhLZXkoa2V5LCBzdGF0ZSwgaXNEZWZhdWx0S2V5KSB7XG4gICAgaWYgKCFrZXkpIHRocm93IG5ldyBFcnJvcignVHJhbnNmZXIkc2V0U3RhdGVXaXRoS2V5OiBubyBrZXknKTtcblxuICAgIGlmIChpc0RlZmF1bHRLZXkpXG4gICAgICAgIHRoaXMuX2RlZmF1bHRLZXkgPSBrZXk7XG4gICAgZWxzZVxuICAgICAgICB0aGlzLl9kZWZhdWx0S2V5ID0gdGhpcy5fZGVmYXVsdEtleSB8fCBrZXk7XG5cbiAgICB0aGlzLl9zdGF0ZVtrZXldID0gc3RhdGU7XG4gICAgdGhpcy5zZXRBY3RpdmVTdGF0ZShrZXkpO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zZmVyJGdldFN0YXRlV2l0aEtleShrZXkpIHtcbiAgICByZXR1cm4gdHlwZW9mIGtleSA9PSAnc3RyaW5nJyAmJiB0aGlzLl9zdGF0ZVtrZXldO1xufVxuXG5cbmZ1bmN0aW9uIFRyYW5zZmVyJGdldENvbXBvbmVudE1ldGEoKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5nZXRTdGF0ZSgpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbXBOYW1lOiBzdGF0ZSAmJiBzdGF0ZS5jb21wTmFtZSxcbiAgICAgICAgY29tcENsYXNzOiBzdGF0ZSAmJiBzdGF0ZS5jb21wQ2xhc3NcbiAgICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ2xhc3NSZWdpc3RyeSA9IHJlcXVpcmUoJy4uLy4uL2Fic3RyYWN0L3JlZ2lzdHJ5JylcbiAgICAsIENvbXBvbmVudEZhY2V0ID0gcmVxdWlyZSgnLi4vY19mYWNldCcpO1xuXG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuZmFjZXRzYFxuICogQ29tcG9uZW50IGZhY2V0cyByZWdpc3RyeS4gQW4gaW5zdGFuY2Ugb2YgW0NsYXNzUmVnaXN0cnldKC4uLy4uL2Fic3RyYWN0L3JlZ2lzdHJ5LmpzLmh0bWwpIGNsYXNzIHRoYXQgaXMgdXNlZCBieSBtaWxvIHRvIHJlZ2lzdGVyIGFuZCBmaW5kIGZhY2V0cy5cbiAqL1xuIHZhciBmYWNldHNSZWdpc3RyeSA9IG5ldyBDbGFzc1JlZ2lzdHJ5KENvbXBvbmVudEZhY2V0KTtcblxuXG4vLyBBZGRzIGNvbW1vbiBhbmNlc3RvciB0byBhbGwgZmFjZXRzIG9mIGNvbXBvbmVudHMgdG8gdGhlIHJlZ2lzdHJ5LlxuZmFjZXRzUmVnaXN0cnkuYWRkKENvbXBvbmVudEZhY2V0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmYWNldHNSZWdpc3RyeTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY19yZWdpc3RyeScpXG4gICAgLCBmYWNldHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4vY19mYWNldHMvY2ZfcmVnaXN0cnknKVxuICAgICwgY29tcG9uZW50TmFtZSA9IHJlcXVpcmUoJy4uL3V0aWwvY29tcG9uZW50X25hbWUnKVxuICAgICwgU2NvcGUgPSByZXF1aXJlKCcuL3Njb3BlJylcbiAgICAsIEJpbmRlckVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLkJpbmRlclxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gQ29tcG9uZW50SW5mbztcblxuXG4vKipcbiAqIFNpbXBsZSBjbGFzcyB0byBob2xkIGluZm9ybWF0aW9uIGFsbG93aW5nIHRvIGNyZWF0ZS9jb3B5IGNvbXBvbmVudCB1c2luZyBbYENvbXBvbmVudC5jcmVhdGVgXSguL2NfY2xhc3MuanMuaHRtbCNjcmVhdGUpIGFuZCBbYENvbXBvbmVudC5jb3B5YF0oLi9jX2NsYXNzLmpzLmh0bWwjY29weSkuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1Njb3BlfSBzY29wZSBzY29wZSBvYmplY3QgdGhlIGNvbXBvbmVudCBiZWxvZ3MgdG8sIHVzdWFsbHkgZWl0aGVyIHRvcCBsZXZlbCBzY29wZSB0aGF0IHdpbGwgYmUgcmV0dXJuZWQgYnkgW21pbG8uYmluZGVyXSguLi9iaW5kZXIuanMuaHRtbCkgb3IgYHNjb3BlYCBwcm9wZXJ0eSBvZiBbQ29udGFpbmVyXSguL2NfZmFjZXRzL0NvbnRhaW5lci5qcy5odG1sKSBmYWNldCBvZiBjb250YWluaW5nIGNvbXBvbmVudFxuICogQHBhcmFtIHtFbGVtZW50fSBlbCBET00gZWxlbWVudCB0aGUgY29tcG9uZW50IGlzIGF0dGFjaGVkIHRvXG4gKiBAcGFyYW0ge0JpbmRBdHRyaWJ1dGV9IGF0dHIgQmluZEF0dHJpYnV0ZSBpbnN0YW5jZSB0aGF0IHRoZSBjb21wb25lbnQgd2FzIGNyZWF0ZWQgd2l0aFxuICogQHBhcmFtIHtCb29sZWFufSB0aHJvd09uRXJyb3JzIElmIHNldCB0byBmYWxzZSwgdGhlbiBlcnJvcnMgd2lsbCBvbmx5IGJlIGxvZ2dlZCB0byBjb25zb2xlLiBUcnVlIGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJuIHtDb21wb25lbnRJbmZvfVxuICovXG5mdW5jdGlvbiBDb21wb25lbnRJbmZvKHNjb3BlLCBlbCwgYXR0ciwgdGhyb3dPbkVycm9ycykge1xuICAgIGF0dHIucGFyc2UoKS52YWxpZGF0ZSgpO1xuXG4gICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICAgIHRoaXMuZWwgPSBlbDtcbiAgICB0aGlzLmF0dHIgPSBhdHRyO1xuICAgIHRoaXMubmFtZSA9IGF0dHIuY29tcE5hbWU7XG4gICAgdGhpcy5Db21wb25lbnRDbGFzcyA9IGdldENvbXBvbmVudENsYXNzKGF0dHIsIHRocm93T25FcnJvcnMpO1xuICAgIHRoaXMuZXh0cmFGYWNldHNDbGFzc2VzID0gZ2V0Q29tcG9uZW50RXh0cmFGYWNldHModGhpcy5Db21wb25lbnRDbGFzcywgYXR0ciwgdGhyb3dPbkVycm9ycyk7XG5cbiAgICBpZiAodGhpcy5Db21wb25lbnRDbGFzc1xuICAgICAgICAgICAgJiYgaGFzQ29udGFpbmVyRmFjZXQodGhpcy5Db21wb25lbnRDbGFzcywgdGhpcy5leHRyYUZhY2V0c0NsYXNzZXMpKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyID0ge307XG4gICAgfVxufVxuXG5cbi8qKlxuICogIyMjI0NvbXBvbmVudEluZm8gaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqIFxuICogLSBbZGVzdHJveV0oI0NvbXBvbmVudEluZm8kZGVzdHJveSlcbiAqIC0gW3JlbmFtZV0oI0NvbXBvbmVudEluZm8kcmVuYW1lKVxuICovXG5fLmV4dGVuZFByb3RvKENvbXBvbmVudEluZm8sIHtcbiAgICBkZXN0cm95OiBDb21wb25lbnRJbmZvJGRlc3Ryb3ksXG4gICAgcmVuYW1lOiBDb21wb25lbnRJbmZvJHJlbmFtZVxufSk7XG5cblxuLyoqXG4gKiBDb21wb25lbnRJbmZvIGluc3RhbmNlIG1ldGhvZFxuICogRGVzdHJveXMgQ29tcG9uZW50SW5mbyBieSByZW1vdmluZyB0aGUgcmVmZXJlbmNlcyB0byBET00gZWxlbWVudFxuICovXG5mdW5jdGlvbiBDb21wb25lbnRJbmZvJGRlc3Ryb3koKSB7XG4gICAgZGVsZXRlIHRoaXMuZWw7XG4gICAgdGhpcy5hdHRyLmRlc3Ryb3koKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudEluZm8gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZW5hbWVzIENvbXBvbmVudEluZm8gb2JqZWN0XG4gKlxuICogQHBhcmFtIHtbU3RyaW5nXX0gbmFtZSBvcHRpb25hbCBuZXcgY29tcG9uZW50IG5hbWUsIGdlbmVyYXRlZCBmcm9tIHRpbWVzdGFtcCBieSBkZWZhdWx0XG4gKiBAcGFyYW0ge1tCb29sZWFuXX0gcmVuYW1lSW5TY29wZSBvcHRpb25hbCBmYWxzZSB0byBub3QgcmVuYW1lIENvbXBvbmVudEluZm8gb2JqZWN0IGluIGl0cyBzY29wZSwgdHJ1ZSBieSBkZWZhdWx0XG4gKi9cbmZ1bmN0aW9uIENvbXBvbmVudEluZm8kcmVuYW1lKG5hbWUsIHJlbmFtZUluU2NvcGUpIHtcbiAgICBuYW1lID0gbmFtZSB8fCBjb21wb25lbnROYW1lKCk7XG4gICAgU2NvcGUucmVuYW1lKHRoaXMsIG5hbWUsIHJlbmFtZUluU2NvcGUpO1xuICAgIHRoaXMuYXR0ci5jb21wTmFtZSA9IG5hbWU7XG4gICAgdGhpcy5hdHRyLmRlY29yYXRlKCk7XG59XG5cblxuZnVuY3Rpb24gZ2V0Q29tcG9uZW50Q2xhc3MoYXR0ciwgdGhyb3dPbkVycm9ycykge1xuICAgIHZhciBDb21wb25lbnRDbGFzcyA9IGNvbXBvbmVudHNSZWdpc3RyeS5nZXQoYXR0ci5jb21wQ2xhc3MpO1xuICAgIGlmICghIENvbXBvbmVudENsYXNzKVxuICAgICAgICByZXBvcnRCaW5kZXJFcnJvcih0aHJvd09uRXJyb3JzLCAnY2xhc3MgJyArIGF0dHIuY29tcENsYXNzICsgJyBpcyBub3QgcmVnaXN0ZXJlZCcpO1xuICAgIHJldHVybiBDb21wb25lbnRDbGFzcztcbn1cblxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnRFeHRyYUZhY2V0cyhDb21wb25lbnRDbGFzcywgYXR0ciwgdGhyb3dPbkVycm9ycykge1xuICAgIHZhciBmYWNldHMgPSBhdHRyLmNvbXBGYWNldHNcbiAgICAgICAgLCBleHRyYUZhY2V0c0NsYXNzZXMgPSB7fTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KGZhY2V0cykpXG4gICAgICAgIGZhY2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGZjdE5hbWUpIHtcbiAgICAgICAgICAgIGZjdE5hbWUgPSBfLmZpcnN0VXBwZXJDYXNlKGZjdE5hbWUpO1xuICAgICAgICAgICAgaWYgKENvbXBvbmVudENsYXNzLmhhc0ZhY2V0KGZjdE5hbWUpKVxuICAgICAgICAgICAgICAgIHJlcG9ydEJpbmRlckVycm9yKHRocm93T25FcnJvcnMsICdjbGFzcyAnICsgQ29tcG9uZW50Q2xhc3MubmFtZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICcgYWxyZWFkeSBoYXMgZmFjZXQgJyArIGZjdE5hbWUpO1xuICAgICAgICAgICAgaWYgKGV4dHJhRmFjZXRzQ2xhc3Nlc1tmY3ROYW1lXSlcbiAgICAgICAgICAgICAgICByZXBvcnRCaW5kZXJFcnJvcih0aHJvd09uRXJyb3JzLCAnY29tcG9uZW50ICcgKyBhdHRyLmNvbXBOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgJyBhbHJlYWR5IGhhcyBmYWNldCAnICsgZmN0TmFtZSk7XG4gICAgICAgICAgICB2YXIgRmFjZXRDbGFzcyA9IGZhY2V0c1JlZ2lzdHJ5LmdldChmY3ROYW1lKTtcbiAgICAgICAgICAgIGV4dHJhRmFjZXRzQ2xhc3Nlc1tmY3ROYW1lXSA9IEZhY2V0Q2xhc3M7XG4gICAgICAgIH0pO1xuXG4gICAgcmV0dXJuIGV4dHJhRmFjZXRzQ2xhc3Nlcztcbn1cblxuXG5mdW5jdGlvbiByZXBvcnRCaW5kZXJFcnJvcih0aHJvd09uRXJyb3JzLCBtZXNzYWdlKSB7XG4gICAgaWYgKHRocm93T25FcnJvcnMgPT09IGZhbHNlKVxuICAgICAgICBsb2dnZXIuZXJyb3IoJ0NvbXBvbmVudEluZm8gYmluZGVyIGVycm9yOicsIG1lc3NhZ2UpO1xuICAgIGVsc2VcbiAgICAgICAgdGhyb3cgbmV3IEJpbmRlckVycm9yKG1lc3NhZ2UpO1xufTtcblxuXG5mdW5jdGlvbiBoYXNDb250YWluZXJGYWNldChDb21wb25lbnRDbGFzcywgZXh0cmFGYWNldHNDbGFzc2VzKSB7XG4gICAgcmV0dXJuIChDb21wb25lbnRDbGFzcy5oYXNGYWNldCgnY29udGFpbmVyJylcbiAgICAgICAgfHwgJ0NvbnRhaW5lcicgaW4gZXh0cmFGYWNldHNDbGFzc2VzXG4gICAgICAgIHx8IF8uc29tZUtleShleHRyYUZhY2V0c0NsYXNzZXMsIGZhY2V0UmVxdWlyZXNDb250YWluZXIpXG4gICAgICAgIHx8IGNsYXNzSGFzRmFjZXRUaGF0UmVxdWlyZXNDb250YWluZXIoKSk7XG5cbiAgICBmdW5jdGlvbiBjbGFzc0hhc0ZhY2V0VGhhdFJlcXVpcmVzQ29udGFpbmVyKCkge1xuICAgICAgICByZXR1cm4gKENvbXBvbmVudENsYXNzLnByb3RvdHlwZS5mYWNldHNDbGFzc2VzXG4gICAgICAgICAgICAmJiBfLnNvbWVLZXkoQ29tcG9uZW50Q2xhc3MucHJvdG90eXBlLmZhY2V0c0NsYXNzZXMsIGZhY2V0UmVxdWlyZXNDb250YWluZXIpKVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZhY2V0UmVxdWlyZXNDb250YWluZXIoRmFjZXRDbGFzcykge1xuICAgICAgICByZXR1cm4gRmFjZXRDbGFzcy5yZXF1aXJlc0ZhY2V0KCdjb250YWluZXInKTtcbiAgICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDbGFzc1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vYWJzdHJhY3QvcmVnaXN0cnknKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi9jX2NsYXNzJyk7XG5cbi8qKlxuICogYG1pbG8ucmVnaXN0cnkuY29tcG9uZW50c2BcbiAqIEFuIGluc3RhbmNlIG9mIFtDbGFzc1JlZ2lzdHJ5XSguLi9hYnN0cmFjdC9yZWdpc3RyeS5qcy5odG1sKSBjbGFzcyB0aGF0IGlzIHVzZWQgYnkgbWlsbyB0byByZWdpc3RlciBhbmQgZmluZCBjb21wb25lbnRzLlxuICovXG52YXIgY29tcG9uZW50c1JlZ2lzdHJ5ID0gbmV3IENsYXNzUmVnaXN0cnkoQ29tcG9uZW50KTtcblxuLy8gYWRkIGNvbW1vbiBhbmNlc3RvciB0byBhbGwgY29tcG9uZW50cyB0byB0aGUgcmVnaXN0cnkuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKENvbXBvbmVudCk7XG5cbm1vZHVsZS5leHBvcnRzID0gY29tcG9uZW50c1JlZ2lzdHJ5O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbnZhciBjb21wb25lbnRVdGlscyA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGlzQ29tcG9uZW50OiBpc0NvbXBvbmVudCxcbiAgICBnZXRDb21wb25lbnQ6IGdldENvbXBvbmVudCxcbiAgICBnZXRDb250YWluaW5nQ29tcG9uZW50OiBnZXRDb250YWluaW5nQ29tcG9uZW50LFxuICAgIF9tYWtlQ29tcG9uZW50Q29uZGl0aW9uRnVuYzogX21ha2VDb21wb25lbnRDb25kaXRpb25GdW5jXG59O1xuXG5cbi8qKlxuICogaXNDb21wb25lbnRcbiAqXG4gKiBDaGVja3MgaWYgZWxlbWVudCBoYXMgYSBjb21wb25lbnQgYXR0YWNoZWQgdG8gaXQgYnlcbiAqIGNoZWNraW5nIHRoZSBwcmVzZW5jZSBvZiBwcm9wZXJ0eSBkaWZpbmVkIGluIG1pbG8uY29uZmlnXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCBET00gZWxlbWVudFxuICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSwgaWYgaXQgaGFzIG1pbG8gY29tcG9uZW50IGF0dGFjaGVkIHRvIGl0XG4gKi9cbmZ1bmN0aW9uIGlzQ29tcG9uZW50KGVsKSB7XG4gICAgcmV0dXJuIGVsLmhhc093blByb3BlcnR5KGNvbmZpZy5jb21wb25lbnRSZWYpO1xufVxuXG5cbi8qKlxuICogZ2V0Q29tcG9uZW50XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCBET00gZWxlbWVudFxuICogQHJldHVybiB7Q29tcG9uZW50fSBjb21wb25lbnQgYXR0YWNoZWQgdG8gZWxlbWVudFxuICovXG5mdW5jdGlvbiBnZXRDb21wb25lbnQoZWwpIHtcbiAgICByZXR1cm4gZWwgJiYgZWxbY29uZmlnLmNvbXBvbmVudFJlZl07XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjbG9zZXN0IGNvbXBvbmVudCB3aGljaCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGVsZW1lbnQsXG4gKiBvcHRpb25hbGx5LCBvbmx5IGNvbXBvbmVudCB0aGF0IHBhc3NlcyBgY29uZGl0aW9uYCB0ZXN0IG9yIGNvbnRhaW5zIHNwZWNpZmllZCBmYWNldFxuICpcbiAqIFVubGVzcyBgcmV0dXJuQ3VycmVudGAgcGFyYW1ldGVyIGlzIGZhbHNlLCB0aGUgZnVuY3Rpb24gd2lsbCByZXR1cm5cbiAqIHRoZSBjdXJyZW50IGNvbXBvbmVudCBvZiB0aGUgZWxlbWVudCAodHJ1ZSBieSBkZWZhdWx0KS5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgRE9NIEVsZW1lbnQgb3IgdGV4dCBOb2RlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJldHVybkN1cnJlbnQgb3B0aW9uYWwgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbXBvbmVudCBvZiB0aGUgZWxlbWVudCBjYW4gYmUgcmV0dXJuZWQuIFRydWUgYnkgZGVmYXVsdCwgc2hvdWxkIGJlIGZhbHNlIHRvIHJldHVybiBvbmx5IGFuY2VzdG9ycy5cbiAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfSBjb25kaXRpb25PckZhY2V0IG9wdGlvbmFsIGNvbmRpdGlvbiB0aGF0IGNvbXBvbmVudCBzaG91bGQgcGFzcyAob3IgZmFjZXQgbmFtZSBpdCBzaG91bGQgY29udGFpbilcbiAqIEByZXR1cm4ge0NvbXBvbmVudH0gXG4gKi9cbmZ1bmN0aW9uIGdldENvbnRhaW5pbmdDb21wb25lbnQobm9kZSwgcmV0dXJuQ3VycmVudCwgY29uZGl0aW9uT3JGYWNldCkge1xuICAgIC8vIGNoZWNrKG5vZGUsIE5vZGUpOyAtIGNhbid0IGNoZWNrIHRpeXBlIGhlcmUgYXMgaXQgaXMgbW9zdCBsaWtlbHkgY29taW5nIGZyb20gYW5vdGhlciBmcmFtZVxuICAgIGNoZWNrKHJldHVybkN1cnJlbnQsIE1hdGNoLk9wdGlvbmFsKEJvb2xlYW4pKTtcbiAgICBjaGVjayhjb25kaXRpb25PckZhY2V0LCBNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihGdW5jdGlvbiwgU3RyaW5nKSkpO1xuXG4gICAgdmFyIGNvbmRpdGlvbkZ1bmMgPSBfbWFrZUNvbXBvbmVudENvbmRpdGlvbkZ1bmMoY29uZGl0aW9uT3JGYWNldCk7XG5cbiAgICByZXR1cm4gX2dldENvbnRhaW5pbmdDb21wb25lbnQobm9kZSwgcmV0dXJuQ3VycmVudCwgY29uZGl0aW9uRnVuYyk7XG59XG5cblxuZnVuY3Rpb24gX21ha2VDb21wb25lbnRDb25kaXRpb25GdW5jKGNvbmRpdGlvbk9yRmFjZXQpIHtcbiAgICBpZiAodHlwZW9mIGNvbmRpdGlvbk9yRmFjZXQgPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNvbmRpdGlvbk9yRmFjZXQ7XG4gICAgZWxzZSBpZiAodHlwZW9mIGNvbmRpdGlvbk9yRmFjZXQgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdmFyIGZhY2V0TmFtZSA9IF8uZmlyc3RMb3dlckNhc2UoY29uZGl0aW9uT3JGYWNldCk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoY29tcCkge1xuICAgICAgICAgICByZXR1cm4gY29tcC5oYXNGYWNldChmYWNldE5hbWUpO1xuICAgICAgICB9O1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBfZ2V0Q29udGFpbmluZ0NvbXBvbmVudChlbCwgcmV0dXJuQ3VycmVudCwgY29uZGl0aW9uRnVuYykge1xuICAgIC8vIFdoZXJlIHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgYSBjb21wb25lbnQgaXQgc2hvdWxkIGJlIHJldHVybmVkXG4gICAgLy8gaWYgcmV0dXJuQ3VycmVudCBpcyB0cnVlIG9yIHVuZGVmaW5lZFxuICAgIGlmIChyZXR1cm5DdXJyZW50ICE9PSBmYWxzZSkge1xuICAgICAgICB2YXIgY29tcCA9IGdldENvbXBvbmVudChlbCk7XG4gICAgICAgIGlmIChjb21wICYmICghIGNvbmRpdGlvbkZ1bmMgfHwgY29uZGl0aW9uRnVuYyhjb21wKSkpXG4gICAgICAgICAgICByZXR1cm4gY29tcDtcbiAgICB9XG5cbiAgICAvLyBXaGVyZSB0aGVyZSBpcyBubyBwYXJlbnQgZWxlbWVudCwgdGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiB1bmRlZmluZWRcbiAgICAvLyBUaGUgcGFyZW50IGVsZW1lbnQgaXMgY2hlY2tlZCByZWN1cnNpdmVseVxuICAgIGlmIChlbC5wYXJlbnROb2RlKVxuICAgICAgICByZXR1cm4gX2dldENvbnRhaW5pbmdDb21wb25lbnQoZWwucGFyZW50Tm9kZSwgdHJ1ZSwgY29uZGl0aW9uRnVuYyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKTtcblxuXG52YXIgVmlldyA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnVmlldycsIFsnY29udGFpbmVyJ10pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKFZpZXcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZpZXc7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIE1lc3NlbmdlckFQSSA9IHJlcXVpcmUoJy4uLy4uL21lc3Nlbmdlci9tX2FwaScpXG4gICAgLCBnZXRFbGVtZW50RGF0YUFjY2VzcyA9IHJlcXVpcmUoJy4vZGVfZGF0YScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbi8vIGNsYXNzIHRvIGhhbmRsZSBzdWJzY3JpYnRpb25zIHRvIGNoYW5nZXMgaW4gRE9NIGZvciBVSSAobWF5YmUgYWxzbyBjb250ZW50IGVkaXRhYmxlKSBlbGVtZW50c1xuXG4vKipcbiAqIEEgY2xhc3NcbiAqL1xudmFyIERhdGFNc2dBUEkgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NlbmdlckFQSSwgJ0RhdGFNc2dBUEknLCB0cnVlKTtcblxuXG5fLmV4dGVuZFByb3RvKERhdGFNc2dBUEksIHtcbiAgICAvLyBpbXBsZW1lbnRpbmcgTWVzc2FnZVNvdXJjZSBpbnRlcmZhY2VcbiAgICBpbml0OiBEYXRhTXNnQVBJJGluaXQsXG4gICAgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlOiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UsXG4gICAgZmlsdGVyU291cmNlTWVzc2FnZTogZmlsdGVyU291cmNlTWVzc2FnZSxcbiAgICBjcmVhdGVJbnRlcm5hbERhdGE6IGNyZWF0ZUludGVybmFsRGF0YSxcblxuICAgIC8vIGNsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICB2YWx1ZTogRGF0YU1zZ0FQSSR2YWx1ZVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGF0YU1zZ0FQSTtcblxuXG5mdW5jdGlvbiBEYXRhTXNnQVBJJGluaXQoY29tcG9uZW50KSB7XG4gICAgTWVzc2VuZ2VyQVBJLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICB0aGlzLmNvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgICB0aGlzLmVsRGF0YSA9IGdldEVsZW1lbnREYXRhQWNjZXNzKGNvbXBvbmVudC5lbCk7XG59XG5cblxuLy8gZ2V0RG9tRWxlbWVudERhdGFWYWx1ZVxuZnVuY3Rpb24gRGF0YU1zZ0FQSSR2YWx1ZSgpIHsgLy8gdmFsdWUgbWV0aG9kXG4gICAgdmFyIGNvbXBvbmVudEdldHRlciA9IHRoaXMuY29tcG9uZW50LmRhdGEuY29uZmlnLmdldDtcbiAgICB2YXIgbmV3VmFsdWUgPSB0eXBlb2YgY29tcG9uZW50R2V0dGVyID09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgPyBjb21wb25lbnRHZXR0ZXIuY2FsbCh0aGlzLmNvbXBvbmVudClcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmVsRGF0YS5nZXQodGhpcy5jb21wb25lbnQuZWwpO1xuXG4gICAgdGhpcy5jb21wb25lbnQuZGF0YS5fdmFsdWUgPSBuZXdWYWx1ZTtcblxuICAgIHJldHVybiBuZXdWYWx1ZTtcbn1cblxuXG4vLyBUT0RPOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gcmVsZXZhbnQgRE9NIGV2ZW50IGRlcGVuZGVudCBvbiBlbGVtZW50IHRhZ1xuLy8gQ2FuIGFsc28gaW1wbGVtZW50IGJlZm9yZWRhdGFjaGFuZ2VkIGV2ZW50IHRvIGFsbG93IHByZXZlbnRpbmcgdGhlIGNoYW5nZVxuLy8gdHJhbnNsYXRlVG9Eb21FdmVudFxuZnVuY3Rpb24gdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICB2YXIgY29tcG9uZW50RXZlbnQgPSB0aGlzLmNvbXBvbmVudC5kYXRhLmNvbmZpZy5ldmVudDtcbiAgICB2YXIgZXZlbnQgPSBjb21wb25lbnRFdmVudCB8fCB0aGlzLmVsRGF0YS5ldmVudCh0aGlzLmNvbXBvbmVudC5lbCk7XG5cbiAgICBpZiAobWVzc2FnZSA9PSAnJyAmJiBldmVudClcbiAgICAgICAgcmV0dXJuIGV2ZW50OyAgLy8gdGhpcy50YWdFdmVudDtcbn1cblxuXG4vLyBmaWx0ZXJEYXRhTWVzc2FnZVxuZnVuY3Rpb24gZmlsdGVyU291cmNlTWVzc2FnZShzb3VyY2VNZXNzYWdlLCBtZXNzYWdlLCBkYXRhKSB7XG4gICAgcmV0dXJuIGRhdGEubmV3VmFsdWUgIT0gZGF0YS5vbGRWYWx1ZTtcbn1cblxuXG5mdW5jdGlvbiBjcmVhdGVJbnRlcm5hbERhdGEoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgZGF0YSkge1xuICAgIHZhciBvbGRWYWx1ZSA9IHRoaXMuY29tcG9uZW50LmRhdGEuX3ZhbHVlXG4gICAgICAgICwgbmV3VmFsdWUgPSB0aGlzLnZhbHVlKCk7XG5cbiAgICB2YXIgaW50ZXJuYWxEYXRhID0geyBcbiAgICAgICAgcGF0aDogJycsXG4gICAgICAgIHR5cGU6ICdjaGFuZ2VkJyxcbiAgICAgICAgb2xkVmFsdWU6IG9sZFZhbHVlLFxuICAgICAgICBuZXdWYWx1ZTogbmV3VmFsdWVcbiAgICB9O1xuICAgIHJldHVybiBpbnRlcm5hbERhdGE7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIFJldHVybnMgZGF0YSBhY2Nlc3MgbWV0aG9kcyBhbmQgZXZlbnRzIGZvciBnaXZlbiBET00gZWxlbWVudC5cbiAqIFVzZWQgYnkgW0RhdGFdKC4uL2NfZmFjZXRzL0RhdGEuanMuaHRtbCkgZmFjZXQgYW5kIGJ5IFtEYXRhTXNnQVBJXSguL2RhdGEuanMuaHRtbClcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbnZhciBnZXRFbGVtZW50RGF0YUFjY2VzcyA9IGZ1bmN0aW9uKGVsKSB7XG4gICAgdmFyIHRhZ05hbWUgPSBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgICAgLCBlbERhdGEgPSBkb21FbGVtZW50c0RhdGFBY2Nlc3NbdGFnTmFtZV07XG4gICAgcmV0dXJuIGVsRGF0YSB8fCBkb21FbGVtZW50c0RhdGFBY2Nlc3MuYnlEZWZhdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEVsZW1lbnREYXRhQWNjZXNzO1xuXG5cbi8qKlxuICogRGF0YSBhY2Nlc3MgbWV0aG9kcyBhbmQgZXZlbnRzIGZvciBET00gZWxlbWVudHMuXG4gKi9cbnZhciBkb21FbGVtZW50c0RhdGFBY2Nlc3MgPSB7XG4gICAgYnlEZWZhdWx0OiB7XG4gICAgICAgIHByb3BlcnR5OiAnaW5uZXJIVE1MJyxcbiAgICB9LFxuICAgICdkaXYnOiB7XG4gICAgICAgIHByb3BlcnR5OiAnaW5uZXJIVE1MJywgLy8gaGFjaywgc2hvdWxkIGJlIGlubmVySFRNTD8gdG8gbWFrZSB3b3JrIHdpdGggRWRpdGFibGUgZmFjZXRcbiAgICAgICAgLy8gZXZlbnQ6ICdpbnB1dCdcbiAgICB9LFxuICAgICdzcGFuJzoge1xuICAgICAgICBwcm9wZXJ0eTogJ2lubmVySFRNTCcsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfSxcbiAgICAncCc6IHtcbiAgICAgICAgcHJvcGVydHk6ICdpbm5lckhUTUwnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH0sXG4gICAgJ2lucHV0Jzoge1xuICAgICAgICBwcm9wZXJ0eTogaW5wdXREYXRhUHJvcGVydHksXG4gICAgICAgIGV2ZW50OiBpbnB1dENoYW5nZUV2ZW50XG4gICAgfSxcbiAgICAndGV4dGFyZWEnOiB7XG4gICAgICAgIHByb3BlcnR5OiAndmFsdWUnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH0sXG4gICAgJ3NlbGVjdCc6IHtcbiAgICAgICAgcHJvcGVydHk6ICd2YWx1ZScsXG4gICAgICAgIGV2ZW50OiAnY2hhbmdlJ1xuICAgIH0sXG4gICAgJ2ltZyc6IHtcbiAgICAgICAgcHJvcGVydHk6ICdzcmMnXG4gICAgfSxcbiAgICAnY2FwdGlvbic6IHtcbiAgICAgICAgcHJvcGVydHk6ICdpbm5lckhUTUwnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH0sXG4gICAgJ3RoZWFkJzoge1xuICAgICAgICBwcm9wZXJ0eTogJ2lubmVySFRNTCcsXG4gICAgICAgIGV2ZW50OiAnaW5wdXQnXG4gICAgfSxcbiAgICAndGJvZHknOiB7XG4gICAgICAgIHByb3BlcnR5OiAnaW5uZXJIVE1MJyxcbiAgICAgICAgZXZlbnQ6ICdpbnB1dCdcbiAgICB9LFxuICAgICd0Zm9vdCc6IHtcbiAgICAgICAgcHJvcGVydHk6ICdpbm5lckhUTUwnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH1cbn07XG5cblxuLy8gY29udmVydCBzdHJpbmdzIHRvIGZ1bmN0aW9ucyBhbmQgY3JlYXRlIGdldHNldCBtZXRob2RzXG5fLmVhY2hLZXkoZG9tRWxlbWVudHNEYXRhQWNjZXNzLCBmdW5jdGlvbih0YWdJbmZvKSB7XG4gICAgdmFyIHByb3BlcnR5ID0gdGFnSW5mby5wcm9wZXJ0eVxuICAgICAgICAsIGV2ZW50ID0gdGFnSW5mby5ldmVudDtcbiAgICBpZiAodHlwZW9mIHByb3BlcnR5ICE9ICdmdW5jdGlvbicpXG4gICAgICAgIHRhZ0luZm8ucHJvcGVydHkgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHByb3BlcnR5OyB9O1xuICAgIHZhciBwcm9wRnVuYyA9IHRhZ0luZm8ucHJvcGVydHk7XG4gICAgaWYgKHR5cGVvZiBldmVudCAhPSAnZnVuY3Rpb24nKVxuICAgICAgICB0YWdJbmZvLmV2ZW50ID0gZnVuY3Rpb24oKSB7IHJldHVybiBldmVudDsgfTtcbiAgICBpZiAoISB0YWdJbmZvLmdldClcbiAgICAgICAgdGFnSW5mby5nZXQgPSBmdW5jdGlvbihlbCkgeyByZXR1cm4gZWxbcHJvcEZ1bmMoZWwpXTsgfVxuICAgIGlmICghIHRhZ0luZm8uc2V0KVxuICAgICAgICB0YWdJbmZvLnNldCA9IGZ1bmN0aW9uKGVsLCB2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIChlbFtwcm9wRnVuYyhlbCldID0gdHlwZW9mIHZhbHVlID09ICd1bmRlZmluZWQnID8gJycgOiB2YWx1ZSk7XG4gICAgICAgIH1cbn0pO1xuXG5cbi8qKlxuICogVHlwZXMgb2YgaW5wdXQgZWxlbWVudHNcbiAqL1xudmFyIGlucHV0RWxlbWVudFR5cGVzID0ge1xuICAgIGJ5RGVmYXVsdDoge1xuICAgICAgICBwcm9wZXJ0eTogJ3ZhbHVlJyxcbiAgICAgICAgZXZlbnQ6ICdpbnB1dCdcbiAgICB9LFxuICAgICdjaGVja2JveCc6IHtcbiAgICAgICAgcHJvcGVydHk6ICdjaGVja2VkJyxcbiAgICAgICAgZXZlbnQ6ICdjaGFuZ2UnXG4gICAgfSxcbiAgICAncmFkaW8nOiB7XG4gICAgICAgIHByb3BlcnR5OiAnY2hlY2tlZCcsXG4gICAgICAgIGV2ZW50OiAnY2hhbmdlJ1xuICAgIH0sXG4gICAgJ3RleHQnOiB7XG4gICAgICAgIHByb3BlcnR5OiAndmFsdWUnLFxuICAgICAgICBldmVudDogJ2lucHV0J1xuICAgIH1cbn1cblxuXG4vKipcbiAqIFJldHVybiBwcm9wZXJ0eSBvZiBpbnB1dCBlbGVtZW50IHRvIGdldC9zZXQgaXRzIGRhdGFcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGlucHV0RGF0YVByb3BlcnR5KGVsKSB7XG4gICAgdmFyIGlucHV0VHlwZSA9IGlucHV0RWxlbWVudFR5cGVzW2VsLnR5cGVdO1xuICAgIHJldHVybiBpbnB1dFR5cGVcbiAgICAgICAgICAgID8gaW5wdXRUeXBlLnByb3BlcnR5XG4gICAgICAgICAgICA6IGlucHV0RWxlbWVudFR5cGVzLmJ5RGVmYXVsdC5wcm9wZXJ0eTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgRE9NIGV2ZW50IHR5cGUgdG8gbGlzdGVuIHRvIHRvIHJlYWN0IHRvIGlucHV0IGVsZW1lbnQgY2hhbmdlXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBpbnB1dENoYW5nZUV2ZW50KGVsKSB7XG4gICAgdmFyIGlucHV0VHlwZSA9IGlucHV0RWxlbWVudFR5cGVzW2VsLnR5cGVdO1xuICAgIHJldHVybiBpbnB1dFR5cGVcbiAgICAgICAgICAgID8gaW5wdXRUeXBlLmV2ZW50XG4gICAgICAgICAgICA6IGlucHV0RWxlbWVudFR5cGVzLmJ5RGVmYXVsdC5ldmVudDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgTWVzc2VuZ2VyQVBJID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyL21fYXBpJylcblxuXG52YXIgRHJvcE1zZ0FQSSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2VuZ2VyQVBJLCAnRHJvcE1zZ0FQSScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oRHJvcE1zZ0FQSSwge1xuICAgIC8vIGltcGxlbWVudGluZyBNZXNzYWdlU291cmNlIGludGVyZmFjZVxuICAgIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZTogdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlLFxuICAgIGZpbHRlclNvdXJjZU1lc3NhZ2U6IGZpbHRlclNvdXJjZU1lc3NhZ2UsXG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IERyb3BNc2dBUEk7XG5cblxudmFyIGRyb3BFdmVudHNNYXAgPSB7XG4gICAgJ2RyYWdpbic6ICdkcmFnZW50ZXInLFxuICAgICdkcmFnb3V0JzogJ2RyYWdsZWF2ZSdcbn07XG5cblxuZnVuY3Rpb24gdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZHJvcEV2ZW50c01hcC5oYXNPd25Qcm9wZXJ0eShtZXNzYWdlKVxuICAgICAgICAgICAgPyBkcm9wRXZlbnRzTWFwW21lc3NhZ2VdXG4gICAgICAgICAgICA6IG1lc3NhZ2U7XG59XG5cbmZ1bmN0aW9uIHJlc2V0RmlsdGVyVmFycygpIHtcbiAgICBkZWxldGUgdGhpcy5fY3VycmVudFRhcmdldDtcbiAgICBkZWxldGUgdGhpcy5faW5zaWRlO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJTb3VyY2VNZXNzYWdlKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIGRhdGEpIHsgLy8gZGF0YSBpcyBET00gZXZlbnQgb2JqZWN0XG4gICAgdmFyIG9rID0gdHJ1ZTtcblxuICAgIGlmIChzb3VyY2VNZXNzYWdlID09ICdkcmFnZW50ZXInICYmIG1lc3NhZ2UgPT0gJ2RyYWdpbicpIHtcbiAgICAgICAgdGhpcy5fY3VycmVudFRhcmdldCA9IGRhdGEudGFyZ2V0O1xuICAgICAgICBvayA9ICF0aGlzLl9pbnNpZGU7XG4gICAgICAgIHRoaXMuX2luc2lkZSA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChzb3VyY2VNZXNzYWdlID09ICdkcmFnbGVhdmUnICYmIG1lc3NhZ2UgPT0gJ2RyYWdvdXQnKSB7XG4gICAgICAgIG9rID0gdGhpcy5fY3VycmVudFRhcmdldCA9PSBkYXRhLnRhcmdldDtcbiAgICAgICAgaWYgKG9rKSByZXNldEZpbHRlclZhcnMuY2FsbCh0aGlzKTtcbiAgICB9IGVsc2UgaWYgKHNvdXJjZU1lc3NhZ2UgPT0gJ2Ryb3AnKSByZXNldEZpbHRlclZhcnMuY2FsbCh0aGlzKTtcblxuICAgIHJldHVybiBvaztcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgRE9NRW1pdHRlclNvdXJjZSA9IHJlcXVpcmUoJy4uLy4uL3NlcnZpY2VzL2RvbV9zb3VyY2UnKVxuICAgICwgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4uLy4uL21lc3Nlbmdlci9tX3NvdXJjZScpXG4gICAgLCBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cbnZhciBET01FdmVudHNTb3VyY2UgPSBfLmNyZWF0ZVN1YmNsYXNzKERPTUVtaXR0ZXJTb3VyY2UsICdET01FdmVudHNTb3VyY2UnLCB0cnVlKTtcblxuXG5fLmV4dGVuZFByb3RvKERPTUV2ZW50c1NvdXJjZSwge1xuICAgIGluaXQ6IGluaXQsXG4gICAgZGVzdHJveTogRE9NRXZlbnRzU291cmNlJGRlc3Ryb3ksXG4gICAgZW1pdHRlcjogZW1pdHRlclxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRE9NRXZlbnRzU291cmNlO1xuXG5cbnZhciB1c2VDYXB0dXJlUGF0dGVybiA9IC9fX2NhcHR1cmUkL1xuICAgICwgdXNlQ2FwdHVyZVBvc3RmaXggPSAnX19jYXB0dXJlJztcblxuXG4vLyBpbml0IERPTSBldmVudCBzb3VyY2VcbmZ1bmN0aW9uIGluaXQoaG9zdE9iamVjdCwgcHJveHlNZXRob2RzLCBtZXNzZW5nZXJBUElPckNsYXNzLCBjb21wb25lbnQpIHtcbiAgICBjaGVjayhjb21wb25lbnQsIENvbXBvbmVudCk7XG4gICAgdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnQ7XG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIERPTUV2ZW50c1NvdXJjZSRkZXN0cm95KCkge1xuICAgIE1lc3NhZ2VTb3VyY2UucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBkZWxldGUgdGhpcy5jb21wb25lbnQ7XG59XG5cblxuLy8gZ2V0IERPTSBlbGVtZW50IG9mIGNvbXBvbmVudFxuZnVuY3Rpb24gZW1pdHRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5jb21wb25lbnQuZWw7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vICMjI2NvbXBvbmVudCBpZnJhbWUgc291cmNlXG5cbnZhciBNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyL21fc291cmNlJylcbiAgICAsIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgRnJhbWVNZXNzYWdlU291cmNlRXJyb3IgPSByZXF1aXJlKCcuLi8uLi91dGlsL2Vycm9yJykuRnJhbWVNZXNzYWdlU291cmNlO1xuXG52YXIgRnJhbWVNZXNzYWdlU291cmNlID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzYWdlU291cmNlLCAnRnJhbWVNZXNzYWdlU291cmNlJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhGcmFtZU1lc3NhZ2VTb3VyY2UsIHtcbiAgICAvLyBpbXBsZW1lbnRpbmcgTWVzc2FnZVNvdXJjZSBpbnRlcmZhY2VcbiAgICBpbml0OiBpbml0LFxuICAgIGFkZFNvdXJjZVN1YnNjcmliZXI6IGFkZFNvdXJjZVN1YnNjcmliZXIsXG4gICAgcmVtb3ZlU291cmNlU3Vic2NyaWJlcjogcmVtb3ZlU291cmNlU3Vic2NyaWJlcixcbiAgICB0cmlnZ2VyOiB0cmlnZ2VyLFxuXG4gICAgLy9jbGFzcyBzcGVjaWZpYyBtZXRob2RzXG4gICAgZnJhbWVXaW5kb3c6IGZyYW1lV2luZG93LFxuICAgIGhhbmRsZUV2ZW50OiBoYW5kbGVFdmVudCAgLy8gZXZlbnQgZGlzcGF0Y2hlciAtIGFzIGRlZmluZWQgYnkgRXZlbnQgRE9NIEFQSVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gRnJhbWVNZXNzYWdlU291cmNlO1xuXG5cbmZ1bmN0aW9uIGluaXQoaG9zdE9iamVjdCwgcHJveHlNZXRob2RzLCBtZXNzZW5nZXJBUElPckNsYXNzLCBjb21wb25lbnQpIHtcbiAgICBjaGVjayhjb21wb25lbnQsIENvbXBvbmVudCk7XG4gICAgdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnQ7XG5cbiAgICBpZiAoY29tcG9uZW50LmVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSAhPSAnaWZyYW1lJylcbiAgICAgICAgdGhyb3cgbmV3IEZyYW1lTWVzc2FnZVNvdXJjZUVycm9yKCdjb21wb25lbnQgZm9yIEZyYW1lTWVzc2FnZVNvdXJjZSBjYW4gb25seSBiZSBhdHRhY2hlZCB0byBpZnJhbWUgZWxlbWVudCcpO1xuXG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIGZyYW1lV2luZG93KCkge1xuICAgIHJldHVybiB0aGlzLmNvbXBvbmVudC5lbC5jb250ZW50V2luZG93O1xufVxuXG5cbi8vIGFkZElGcmFtZU1lc3NhZ2VMaXN0ZW5lclxuZnVuY3Rpb24gYWRkU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgdmFyIHdpbiA9IHRoaXMuZnJhbWVXaW5kb3coKTtcbiAgICBpZiAod2luKSB3aW4uYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRoaXMsIGZhbHNlKTtcbiAgICBlbHNlIGxvZ2dlci53YXJuKCdGcmFtZU1lc3NhZ2VTb3VyY2U6IGZyYW1lIHdpbmRvdyBpcyB1bmRlZmluZWQnKTtcbn1cblxuXG4vLyByZW1vdmVJRnJhbWVNZXNzYWdlTGlzdGVuZXJcbmZ1bmN0aW9uIHJlbW92ZVNvdXJjZVN1YnNjcmliZXIoc291cmNlTWVzc2FnZSkge1xuICAgIHZhciB3aW4gPSB0aGlzLmZyYW1lV2luZG93KCk7XG4gICAgaWYgKHdpbikgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLCBmYWxzZSk7XG4gICAgZWxzZSBsb2dnZXIud2FybignRnJhbWVNZXNzYWdlU291cmNlOiBmcmFtZSB3aW5kb3cgaXMgdW5kZWZpbmVkJyk7XG59XG5cblxuZnVuY3Rpb24gdHJpZ2dlcihtc2dUeXBlLCBkYXRhKSB7XG4gICAgZGF0YSA9IGRhdGEgfHwge307XG4gICAgZGF0YS50eXBlID0gbXNnVHlwZTtcblxuICAgIHRoaXMuZnJhbWVXaW5kb3coKS5wb3N0TWVzc2FnZShkYXRhLCAnKicpO1xufVxuXG5cbi8vIFRPRE8gbWF5YmUgcmVmYWN0b3IgdG8gRnJhbWVNc2dBUEk/XG5mdW5jdGlvbiBoYW5kbGVFdmVudChldmVudCkge1xuICAgIHRoaXMuZGlzcGF0Y2hNZXNzYWdlKGV2ZW50LmRhdGEudHlwZSwgZXZlbnQpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjb21wb25lbnROYW1lID0gcmVxdWlyZSgnLi4vdXRpbC9jb21wb25lbnRfbmFtZScpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgU2NvcGVFcnJvciA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS5TY29wZVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKTtcblxuXG4vKipcbiAqIFNjb3BlIGNsYXNzLlxuICogQHBhcmFtIHtFbGVtZW50fSByb290RWwgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGlzIHNjb3BlXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCB0aGUgaG9zdCBcbiAqIEByZXR1cm4ge1Njb3BlfVxuICovXG5mdW5jdGlvbiBTY29wZShyb290RWwsIGhvc3RPYmplY3QpIHtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfcm9vdEVsOiByb290RWwsXG4gICAgICAgIF9ob3N0T2JqZWN0OiBob3N0T2JqZWN0XG4gICAgfSwgXy5XUklUKTsgLy8gd3JpdGFibGVcbn07XG5cbl8uZXh0ZW5kUHJvdG8oU2NvcGUsIHtcbiAgICBfYWRkOiBTY29wZSRfYWRkLFxuICAgIF9zYWZlQWRkOiBTY29wZSRfc2FmZUFkZCxcbiAgICBfY29weTogU2NvcGUkX2NvcHksXG4gICAgX2VhY2g6IFNjb3BlJF9lYWNoLFxuICAgIF9tb3ZlOiBTY29wZSRfbW92ZSxcbiAgICBfbWVyZ2U6IFNjb3BlJF9tZXJnZSxcbiAgICBfbGVuZ3RoOiBTY29wZSRfbGVuZ3RoLFxuICAgIF9hbnk6IFNjb3BlJF9hbnksXG4gICAgX3JlbW92ZTogU2NvcGUkX3JlbW92ZSxcbiAgICBfY2xlYW46IFNjb3BlJF9jbGVhbixcbiAgICBfZGV0YWNoRWxlbWVudDogU2NvcGUkX2RldGFjaEVsZW1lbnQsXG4gICAgX2hhczogU2NvcGUkX2hhcyxcbiAgICBfZmlsdGVyOiBTY29wZSRfZmlsdGVyXG59KTtcblxuXG5fLmV4dGVuZChTY29wZSwge1xuICAgIHJlbmFtZTogU2NvcGUkJHJlbmFtZVxufSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBTY29wZTtcblxuXG52YXIgYWxsb3dlZE5hbWVQYXR0ZXJuID0gL15bQS1aYS16XVtBLVphLXowLTlcXF9cXCRdKiQvO1xuXG5cbi8qKlxuICogU2NvcGUgaW5zdGFuY2UgbWV0aG9kLlxuICogQWRkcyBvYmplY3QgdG8gdGhlIHNjb3BlLCB0aHJvd2luZyBpZiBuYW1lIGlzIG5vdCB1bmlxdWVcbiAqIEBwYXJhbSB7Q29tcG9uZW50fENvbXBvbmVudEluZm99IG9iamVjdCBjb21wb25lbnQgb3IgY29tcG9uZW50IGluZm8gdG8gYWRkIHRvIHRoZSBzY29wZVxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIGNvbXBvbmVudCB0byBhZGRcbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2FkZChvYmplY3QsIG5hbWUpIHtcbiAgICBpZiAodHlwZW9mIG5hbWUgPT0gJ3N0cmluZycpXG4gICAgICAgIG9iamVjdC5uYW1lID0gbmFtZTtcbiAgICBlbHNlXG4gICAgICAgIG5hbWUgPSBvYmplY3QubmFtZTtcbiAgICBcbiAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSlcbiAgICAgICAgdGhyb3cgbmV3IFNjb3BlRXJyb3IoJ2R1cGxpY2F0ZSBvYmplY3QgbmFtZTogJyArIG5hbWUpO1xuXG4gICAgY2hlY2tOYW1lKG5hbWUpO1xuICAgIF9fYWRkLmNhbGwodGhpcywgb2JqZWN0LCBuYW1lKTtcbn1cblxuXG4vKipcbiAqIFNjb3BlIGluc3RhbmNlIG1ldGhvZFxuICogQWRkcyBvYmplY3QgdG8gc2NvcGUgcmVuYW1pbmcgaXQgaWYgbmFtZSBpcyBub3QgdW5pcXVlXG4gKiBAcGFyYW0ge0NvbXBvbmVudHxDb21wb25lbnRJbmZvfSBvYmplY3QgY29tcG9uZW50IG9yIGNvbXBvbmVudCBpbmZvIHRvIGFkZCB0byB0aGUgc2NvcGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnQgdG8gYWRkXG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9zYWZlQWRkKG9iamVjdCwgbmFtZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSA9PSAnc3RyaW5nJylcbiAgICAgICAgb2JqZWN0Lm5hbWUgPSBuYW1lO1xuICAgIGVsc2VcbiAgICAgICAgbmFtZSA9IG9iamVjdC5uYW1lO1xuXG4gICAgdmFyIHNob3VsZFJlbmFtZSA9IHRoaXMuaGFzT3duUHJvcGVydHkobmFtZSk7XG4gICAgaWYgKHNob3VsZFJlbmFtZSlcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdTY29wZTogZHVwbGljYXRlIG9iamVjdCBuYW1lOiAnICsgbmFtZSk7XG4gICAgZWxzZSB7XG4gICAgICAgIHNob3VsZFJlbmFtZSA9ICEgYWxsb3dlZE5hbWVQYXR0ZXJuLnRlc3QobmFtZSk7XG4gICAgICAgIGlmIChzaG91bGRSZW5hbWUpXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1Njb3BlOiBuYW1lIHNob3VsZCBzdGFydCBmcm9tIGxldHRlciwgdGhpcyBuYW1lIGlzIG5vdCBhbGxvd2VkOiAnICsgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFJlbmFtZSkge1xuICAgICAgICBuYW1lID0gY29tcG9uZW50TmFtZSgpO1xuICAgICAgICBvYmplY3QubmFtZSA9IG5hbWU7XG4gICAgfVxuXG4gICAgX19hZGQuY2FsbCh0aGlzLCBvYmplY3QsIG5hbWUpO1xufVxuXG5cbmZ1bmN0aW9uIF9fYWRkKG9iamVjdCwgbmFtZSkge1xuICAgIHRoaXNbbmFtZV0gPSBvYmplY3Q7XG4gICAgb2JqZWN0LnNjb3BlID0gdGhpcztcblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0LnBvc3RNZXNzYWdlID09PSAnZnVuY3Rpb24nKVxuICAgICAgICBvYmplY3QucG9zdE1lc3NhZ2UoJ2FkZGVkdG9zY29wZScpOyBcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIGNvcGllcyBhbGwgb2JqZWN0cyBmcm9tIG9uZSBzY29wZSB0byBhbm90aGVyLFxuICogdGhyb3dpbmcgaWYgc29tZSBvYmplY3QgaXMgbm90IHVuaXF1ZVxuICogQHBhcmFtIHtTY29wZX0gYVNjb3BlIHRoZSBzY29wZSB0byBjb3B5XG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9jb3B5KGFTY29wZSkge1xuICAgIGNoZWNrKGFTY29wZSwgU2NvcGUpO1xuXG4gICAgYVNjb3BlLl9lYWNoKFNjb3BlJF9hZGQsIHRoaXMpO1xufVxuXG5cbi8qKlxuICogSW5zdGFuY2UgbWV0aG9kLlxuICogTW92ZXMgYSBjb21wb25lbnQgZnJvbSB0aGlzIHNjb3BlIHRvIGFub3RoZXIgc2NvcGUuXG4gKiBAcGFyYW0ge0NvbXBvbmVudH0gY29tcG9uZW50IHRoZSBjb21wb25lbnQgdG8gYmUgbW92ZWRcbiAqIEBwYXJhbSB7U2NvcGV9IG90aGVyU2NvcGUgdGhlIHNjb3BlIHRvIGNvcHkgdGhlIGNvbXBvbmVudCB0b1xuICovXG5mdW5jdGlvbiBTY29wZSRfbW92ZShjb21wb25lbnQsIG90aGVyU2NvcGUpIHtcbiAgICBvdGhlclNjb3BlLl9hZGQoY29tcG9uZW50KTtcbiAgICB0aGlzLl9yZW1vdmUoY29tcG9uZW50Lm5hbWUpO1xuICAgIGNvbXBvbmVudC5zY29wZSA9IG90aGVyU2NvcGU7XG59XG5cblxuLyoqXG4gKiBJbnN0YW5jZSBtZXRob2QuXG4gKiBNZXJnZXMgb25lIHNjb3BlIGludG8gdGhpcyBzY29wZVxuICogQHBhcmFtIHtTY29wZX0gc2NvcGUgdGhlIHNjb3BlIHRvIGFic29yYlxuICovXG5mdW5jdGlvbiBTY29wZSRfbWVyZ2Uoc2NvcGUpIHtcbiAgICBzY29wZS5fZWFjaChmdW5jdGlvbiAoY29tcCkge1xuICAgICAgICB0aGlzLl9hZGQoY29tcCwgY29tcC5uYW1lKTtcbiAgICAgICAgc2NvcGUuX3JlbW92ZShjb21wLm5hbWUpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbi8qKlxuICogSW5zdGFuY2UgbWV0aG9kLlxuICogRW51bWVyYXRlcyBlYWNoIGNvbXBvbmVudCBpbiB0aGUgc2NvcGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRoZSBmdW5jdGlvbiB0byBleGVjdXRlIGZvciBlYWNoIGNvbXBvbmVudFxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgdGhlIGNvbnRleHRcbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2VhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICBfLmVhY2hLZXkodGhpcywgY2FsbGJhY2ssIHRoaXNBcmcgfHwgdGhpcywgdHJ1ZSk7IC8vIGVudW1lcmF0ZXMgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHlcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgYSBmaWx0ZXJlZCBsaXN0IG9mIGNvbXBvbmVudHMgYmFzZWQgb24gYSBjYWxsYmFja1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdGhlIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgZm9yIGVhY2ggY29tcG9uZW50XG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyB0aGUgY29udGV4dFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9maWx0ZXIoY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICByZXR1cm4gXy5maWx0ZXJLZXlzKHRoaXMsIGNhbGxiYWNrLCB0aGlzQXJnIHx8IHRoaXMsIHRydWUpO1xufVxuXG5cbi8qKlxuICogQ2hlY2tzIHRoZSB2YWxpZGl0eSBvZiBhIG5hbWUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0aGUgZnVuY3Rpb24gdG8gZXhlY3V0ZSBmb3IgZWFjaCBjb21wb25lbnRcbiAqL1xuZnVuY3Rpb24gY2hlY2tOYW1lKG5hbWUpIHtcbiAgICBpZiAoISBhbGxvd2VkTmFtZVBhdHRlcm4udGVzdChuYW1lKSlcbiAgICAgICAgdGhyb3cgbmV3IFNjb3BlRXJyb3IoJ25hbWUgc2hvdWxkIHN0YXJ0IGZyb20gbGV0dGVyLCB0aGlzIG5hbWUgaXMgbm90IGFsbG93ZWQ6ICcgKyBuYW1lKTtcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBvYmplY3RzIGluIHRoZSBzY29wZVxuICogQHJldHVybiB7TnVtYmVyfVxuICovXG5mdW5jdGlvbiBTY29wZSRfbGVuZ3RoKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzKS5sZW5ndGg7XG59XG5cblxuLyoqXG4gKiBJbnN0YW5jZSBtZXRob2QuXG4gKiBSZXR1cm5zIGEgY29tcG9uZW50IGZyb20gdGhlIHNjb3BlLiBJdCBtYXkgbG9vayBsaWtlIGl0IHJldHVybnMgdGhlIGZpcnN0IGNvbXBvbmVudFxuICogYnV0IGluIHJlYWxpdHkgZ2l2ZW4gdGhhdCBzY29wZXMgYXJlIGhhc2hlcywgdGhlcmUgaXMgbm8gc3VjaCB0aGluZy5cbiAqIEByZXR1cm4ge0NvbXBvbmVudH1cbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2FueSgpIHtcbiAgICB2YXIga2V5ID0gT2JqZWN0LmtleXModGhpcylbMF07XG4gICAgcmV0dXJuIGtleSAmJiB0aGlzW2tleV07XG59XG5cblxuLyoqXG4gKiBJbnN0YW5jZSBtZXRob2QuXG4gKiBSZW1vdmVzIGEgY29tcG9uZW50IGZyb20gdGhlIHNjb3BlIGJ5IGl0J3MgbmFtZS5cbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBjb21wb25lbnQgdG8gcmVtb3ZlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHF1aWV0IG9wdGlvbmFsIHRydWUgdG8gc3VwcHJlc3MgdGhlIHdhcm5pbmcgbWVzc2FnZSBpZiB0aGUgY29tcG9uZW50IGlzIG5vdCBpbiBzY29wZVxuICovXG5mdW5jdGlvbiBTY29wZSRfcmVtb3ZlKG5hbWUsIHF1aWV0KSB7XG4gICAgaWYgKCEgKG5hbWUgaW4gdGhpcykpIHtcbiAgICAgICAgaWYgKCFxdWlldCkgbG9nZ2VyLndhcm4oJ3JlbW92aW5nIG9iamVjdCB0aGF0IGlzIG5vdCBpbiBzY29wZScpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG9iamVjdCA9IHRoaXNbbmFtZV07XG5cbiAgICBkZWxldGUgdGhpc1tuYW1lXTtcblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0LnBvc3RNZXNzYWdlID09PSAnZnVuY3Rpb24nKVxuICAgICAgICBvYmplY3QucG9zdE1lc3NhZ2UoJ3JlbW92ZWRmcm9tc2NvcGUnKTtcbn1cblxuXG4vKipcbiAqIEluc3RhbmNlIG1ldGhvZC5cbiAqIFJlbW92ZXMgYWxsIGNvbXBvbmVudHMgZnJvbSB0aGUgc2NvcGUuXG4gKi9cbmZ1bmN0aW9uIFNjb3BlJF9jbGVhbigpIHtcbiAgICB0aGlzLl9lYWNoKGZ1bmN0aW9uKG9iamVjdCwgbmFtZSkge1xuICAgICAgICBkZWxldGUgdGhpc1tuYW1lXS5zY29wZTtcbiAgICAgICAgZGVsZXRlIHRoaXNbbmFtZV07XG4gICAgfSwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIFNjb3BlJF9kZXRhY2hFbGVtZW50KCkge1xuICAgIHRoaXMuX3Jvb3RFbCA9IG51bGw7XG59XG5cblxuLyoqXG4gKiBDaGVja3MgaWYgc2NvcGUgaGFzIG9iamVjdCBieSBvYmplY3QgbmFtZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gU2NvcGUkX2hhcyhvYmplY3QpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNPd25Qcm9wZXJ0eShvYmplY3QubmFtZSk7XG59XG5cblxuLyoqXG4gKiBDaGFuZ2Ugb2JqZWN0IG5hbWUsIHJlbmFtaW5nIGl0IGluIHNjb3BlIHVubGVzcyByZW5hbWVJblNjb3BlIGlzIGZhbHNlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBuZXcgbmFtZVxuICogQHBhcmFtIHtCb29sZWFufSByZW5hbWVJblNjb3BlIHRydWUgYnkgZGVmYXVsdFxuICovXG5mdW5jdGlvbiBTY29wZSQkcmVuYW1lKG9iaiwgbmFtZSwgcmVuYW1lSW5TY29wZSkge1xuICAgIGlmIChvYmouc2NvcGUgJiYgcmVuYW1lSW5TY29wZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgb2JqLnNjb3BlLl9yZW1vdmUob2JqLm5hbWUpO1xuICAgICAgICBvYmouc2NvcGUuX2FkZChvYmosIG5hbWUpO1xuICAgIH0gZWxzZVxuICAgICAgICBvYmoubmFtZSA9IG5hbWU7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKTtcblxuXG52YXIgTUxCdXR0b24gPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MQnV0dG9uJywge1xuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1idXR0b24nXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxCdXR0b24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MQnV0dG9uO1xuXG5fLmV4dGVuZFByb3RvKE1MQnV0dG9uLCB7XG4gICAgZGlzYWJsZTogTUxCdXR0b24kZGlzYWJsZSxcbiAgICBpc0Rpc2FibGVkOiBNTEJ1dHRvbiRpc0Rpc2FibGVkXG59KTtcblxuXG5mdW5jdGlvbiBNTEJ1dHRvbiRkaXNhYmxlKGRpc2FibGUpIHtcbiAgICB0aGlzLmVsLmRpc2FibGVkID0gZGlzYWJsZTtcbn1cblxuZnVuY3Rpb24gTUxCdXR0b24kaXNEaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gISF0aGlzLmVsLmRpc2FibGVkO1xufVxuXG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBDT01CT19DSEFOR0VfTUVTU0FHRSA9ICdtbGNvbWJvY2hhbmdlJztcblxudmFyIERBVEFMSVNUX1RFTVBMQVRFID0gJ3t7fiBpdC5jb21ib09wdGlvbnMgOm9wdGlvbiB9fSBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ7ez0gb3B0aW9uLmxhYmVsIH19XCI+PC9vcHRpb24+IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICAge3t+fX0nO1xuXG52YXIgTUxDb21ibyA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxDb21ibycsIHtcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkYXRhOiB7XG4gICAgICAgIGdldDogTUxDb21ib19nZXQsXG4gICAgICAgIHNldDogTUxDb21ib19zZXQsXG4gICAgICAgIGRlbDogTUxDb21ib19kZWwsXG4gICAgICAgIHNwbGljZTogdW5kZWZpbmVkLFxuICAgICAgICBldmVudDogQ09NQk9fQ0hBTkdFX01FU1NBR0VcbiAgICB9LFxuICAgIG1vZGVsOiB7XG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICAnKioqJzogeyBzdWJzY3JpYmVyOiBvbk9wdGlvbnNDaGFuZ2UsIGNvbnRleHQ6ICdvd25lcicgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktZGF0YWxpc3QnXG4gICAgfSxcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZFxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxDb21ibyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxDb21ibztcblxuXG5fLmV4dGVuZFByb3RvKE1MQ29tYm8sIHtcbiAgICBpbml0OiBNTENvbWJvJGluaXRcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MQ29tYm8kaW5pdCgpIHtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLm9uKCdjaGlsZHJlbmJvdW5kJywgb25DaGlsZHJlbkJvdW5kKTtcbn1cblxuZnVuY3Rpb24gb25DaGlsZHJlbkJvdW5kKCkge1xuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgICdfY29tYm9JbnB1dCc6IHRoaXMuY29udGFpbmVyLnNjb3BlLmlucHV0LFxuICAgICAgICAnX2NvbWJvTGlzdCc6IHRoaXMuY29udGFpbmVyLnNjb3BlLmRhdGFsaXN0XG4gICAgfSk7XG5cbiAgICB0aGlzLl9jb21ib0xpc3QudGVtcGxhdGUuc2V0KERBVEFMSVNUX1RFTVBMQVRFKTtcblxuICAgIHRoaXMuX2NvbWJvSW5wdXQuZGF0YS5vbignaW5wdXQnLFxuICAgICAgICB7IHN1YnNjcmliZXI6IGRpc3BhdGNoQ2hhbmdlTWVzc2FnZSwgY29udGV4dDogdGhpcyB9KTtcbn1cblxuZnVuY3Rpb24gTUxDb21ib19nZXQoKSB7XG4gICAgaWYgKCEgdGhpcy5fY29tYm9JbnB1dCkgcmV0dXJuO1xuICAgIHJldHVybiB0aGlzLl9jb21ib0lucHV0LmRhdGEuZ2V0KCk7XG59XG5cbmZ1bmN0aW9uIE1MQ29tYm9fc2V0KHZhbHVlKSB7XG4gICAgcmV0dXJuIGNoYW5nZUNvbWJvRGF0YS5jYWxsKHRoaXMsICdzZXQnLCB2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIE1MQ29tYm9fZGVsKCkge1xuICAgIHJldHVybiBjaGFuZ2VDb21ib0RhdGEuY2FsbCh0aGlzLCAnZGVsJywgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBjaGFuZ2VDb21ib0RhdGEobWV0aG9kLCB2YWx1ZSkge1xuICAgIGlmICghIHRoaXMuX2NvbWJvSW5wdXQpIHJldHVybjtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcy5fY29tYm9JbnB1dC5kYXRhW21ldGhvZF0odmFsdWUpO1xuICAgIGRpc3BhdGNoQ2hhbmdlTWVzc2FnZS5jYWxsKHRoaXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cblxuLy8gUG9zdCB0aGUgZGF0YSBjaGFuZ2VcbmZ1bmN0aW9uIGRpc3BhdGNoQ2hhbmdlTWVzc2FnZSgpIHtcbiAgICB0aGlzLmRhdGEuZGlzcGF0Y2hTb3VyY2VNZXNzYWdlKENPTUJPX0NIQU5HRV9NRVNTQUdFKTtcbn1cblxuZnVuY3Rpb24gb25PcHRpb25zQ2hhbmdlKG1zZywgZGF0YSkge1xuICAgIHRoaXMuX2NvbWJvTGlzdC50ZW1wbGF0ZS5yZW5kZXIoe1xuICAgICAgICBjb21ib09wdGlvbnM6IHRoaXMubW9kZWwuZ2V0KClcbiAgICB9KTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cbnZhciBDT01CT19MSVNUX0NIQU5HRV9NRVNTQUdFID0gJ21sY29tYm9saXN0Y2hhbmdlJztcblxuXG52YXIgTUxDb21ib0xpc3QgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MQ29tYm9MaXN0Jywge1xuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1jb21iby1saXN0J1xuICAgIH0sXG4gICAgZGF0YToge1xuICAgICAgICBnZXQ6IE1MQ29tYm9MaXN0X2dldCxcbiAgICAgICAgc2V0OiBNTENvbWJvTGlzdF9zZXQsXG4gICAgICAgIGRlbDogTUxDb21ib0xpc3RfZGVsLFxuICAgICAgICBldmVudDogQ09NQk9fTElTVF9DSEFOR0VfTUVTU0FHRVxuICAgIH0sXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgbW9kZWw6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICcqKionOiB7IHN1YnNjcmliZXI6IG9uSXRlbXNDaGFuZ2UsIGNvbnRleHQ6ICdvd25lcid9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICAgIHRlbXBsYXRlOiAnPGRpdiBtbC1iaW5kPVwiTUxTdXBlckNvbWJvOmNvbWJvXCI+PC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICA8ZGl2IG1sLWJpbmQ9XCJNTExpc3Q6bGlzdFwiPlxcXG4gICAgICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIk1MTGlzdEl0ZW06aXRlbVwiIGNsYXNzPVwibGlzdC1pdGVtXCI+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIG1sLWJpbmQ9XCJbZGF0YV06bGFiZWxcIj48L3NwYW4+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIG1sLWJpbmQ9XCJbZXZlbnRzXTpkZWxldGVCdG5cIiBjbGFzcz1cImdseXBoaWNvbiBnbHlwaGljb24tcmVtb3ZlXCI+PC9zcGFuPlxcXG4gICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcXG4gICAgICAgICAgICAgICAgICAgPC9kaXY+J1xuICAgIH1cbn0pO1xuXG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxDb21ib0xpc3QpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MQ29tYm9MaXN0O1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxDb21ib0xpc3QsIHtcbiAgICBpbml0OiBNTENvbWJvTGlzdCRpbml0LFxuICAgIHNldE9wdGlvbnM6IE1MQ29tYm9MaXN0JHNldE9wdGlvbnMsXG4gICAgc2V0RGF0YVZhbGlkYXRpb246IE1MQ29tYm9MaXN0JHNldERhdGFWYWxpZGF0aW9uLFxuICAgIHRvZ2dsZUFkZEJ1dHRvbjogTUxDb21ib0xpc3QkdG9nZ2xlQWRkQnV0dG9uLFxuICAgIGRlc3Ryb3k6IE1MQ29tYm9MaXN0JGRlc3Ryb3ksXG4gICAgc2V0QWRkSXRlbVByb21wdDogTUxDb21ib0xpc3Qkc2V0QWRkSXRlbVByb21wdCxcbiAgICBjbGVhckNvbWJvSW5wdXQgOiBNTENvbWJvTGlzdCRjbGVhckNvbWJvSW5wdXRcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MQ29tYm9MaXN0JGluaXQoKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy5fZGF0YVZhbGlkYXRpb24gPSBmdW5jdGlvbiAoKSB7fTtcbiAgICB0aGlzLm1vZGVsLnNldChbXSk7XG4gICAgdGhpcy5vbmNlKCdjaGlsZHJlbmJvdW5kJywgb25DaGlsZHJlbkJvdW5kKTtcbn1cblxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdCRzZXREYXRhVmFsaWRhdGlvbihkYXRhVmFsaWRhdGlvbikge1xuICAgIGlmICh0eXBlb2YgZGF0YVZhbGlkYXRpb24gPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhpcy5fZGF0YVZhbGlkYXRpb24gPSBkYXRhVmFsaWRhdGlvbjtcbn1cblxuZnVuY3Rpb24gTUxDb21ib0xpc3Qkc2V0T3B0aW9ucyhhcnIpIHtcbiAgICB0aGlzLl9jb21iby5zZXRPcHRpb25zKGFycik7XG59XG5cblxuZnVuY3Rpb24gTUxDb21ib0xpc3QkY2xlYXJDb21ib0lucHV0ICgpIHtcbiAgICB0aGlzLl9jb21iby5jbGVhckNvbWJvSW5wdXQoKTtcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBIaWRlcyBhZGQgYnV0dG9uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHNob3dcbiAqL1xuZnVuY3Rpb24gTUxDb21ib0xpc3QkdG9nZ2xlQWRkQnV0dG9uKHNob3cpIHtcbiAgICB0aGlzLl9jb21iby50b2dnbGVBZGRCdXR0b24oc2hvdyk7XG59XG5cblxuZnVuY3Rpb24gTUxDb21ib0xpc3Qkc2V0QWRkSXRlbVByb21wdChwcm9tcHQpIHtcbiAgIHRoaXMuX2NvbWJvLnNldEFkZEl0ZW1Qcm9tcHQocHJvbXB0KTtcbn1cblxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdCRkZXN0cm95KCkge1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMuX2Nvbm5lY3RvciAmJiBtaWxvLm1pbmRlci5kZXN0cm95Q29ubmVjdG9yKHRoaXMuX2Nvbm5lY3Rvcik7XG4gICAgdGhpcy5fY29ubmVjdG9yID0gbnVsbDtcbn1cblxuXG5mdW5jdGlvbiBvbkNoaWxkcmVuQm91bmQoKSB7XG4gICAgdGhpcy50ZW1wbGF0ZS5yZW5kZXIoKS5iaW5kZXIoKTtcbiAgICBjb21wb25lbnRTZXR1cC5jYWxsKHRoaXMpO1xufVxuXG5mdW5jdGlvbiBjb21wb25lbnRTZXR1cCgpIHtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICAnX2NvbWJvJzogdGhpcy5jb250YWluZXIuc2NvcGUuY29tYm8sXG4gICAgICAgICdfbGlzdCc6IHRoaXMuY29udGFpbmVyLnNjb3BlLmxpc3RcbiAgICB9KTtcblxuICAgIHRoaXMuX2Nvbm5lY3RvciA9IG1pbG8ubWluZGVyKHRoaXMuX2xpc3QubW9kZWwsICc8PDwtPj4+JywgdGhpcy5tb2RlbCk7XG4gICAgdGhpcy5fY29tYm8uZGF0YS5vbignJywgeyBzdWJzY3JpYmVyOiBvbkNvbWJvQ2hhbmdlLCBjb250ZXh0OiB0aGlzIH0pO1xuICAgIHRoaXMuX2NvbWJvLm9uKCdhZGRpdGVtJywgeyBzdWJzY3JpYmVyOiBvbkFkZEl0ZW0sIGNvbnRleHQ6IHRoaXMgfSk7XG59XG5cbmZ1bmN0aW9uIG9uQ29tYm9DaGFuZ2UobXNnLCBkYXRhKSB7XG4gICAgaWYgKGRhdGEubmV3VmFsdWUgJiYgdGhpcy5fZGF0YVZhbGlkYXRpb24obXNnLCBkYXRhLCB0aGlzLl9saXN0Lm1vZGVsLmdldCgpKSlcbiAgICAgICAgdGhpcy5fbGlzdC5tb2RlbC5wdXNoKGRhdGEubmV3VmFsdWUpO1xuICAgIHRoaXMuX2NvbWJvLmRhdGEuZGVsKCk7XG4gICAgLy8gYmVjYXVzZSBvZiBzdXBlcmNvbWJvIGxpc3RlbmVycyBvZmYgeW91IGhhdmUgdG8gc2V0IF92YWx1ZSBleHBsaWNpdGx5XG4gICAgdGhpcy5fY29tYm8uZGF0YS5fdmFsdWUgPSAnJztcbn1cblxuZnVuY3Rpb24gb25JdGVtc0NoYW5nZShtc2csIGRhdGEpIHtcbiAgICB0aGlzLmRhdGEuZGlzcGF0Y2hTb3VyY2VNZXNzYWdlKENPTUJPX0xJU1RfQ0hBTkdFX01FU1NBR0UpO1xufVxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdF9nZXQoKSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5tb2RlbC5nZXQoKTtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdvYmplY3QnID8gXy5jbG9uZSh2YWx1ZSkgOiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gTUxDb21ib0xpc3Rfc2V0KHZhbHVlKSB7XG4gICAgdGhpcy5tb2RlbC5zZXQodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBNTENvbWJvTGlzdF9kZWwoKSB7XG4gICAgcmV0dXJuIHRoaXMubW9kZWwuc2V0KFtdKTtcbn1cblxuXG5mdW5jdGlvbiBvbkFkZEl0ZW0obXNnLCBkYXRhKSB7XG4gICAgdGhpcy5wb3N0TWVzc2FnZSgnYWRkaXRlbScsIGRhdGEpO1xuICAgIHRoaXMuZXZlbnRzLnBvc3RNZXNzYWdlKCdtaWxvX2NvbWJvbGlzdGFkZGl0ZW0nLCBkYXRhKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cbnZhciBNTERhdGUgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MRGF0ZScsIHtcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkYXRhOiB7XG4gICAgICAgIGdldDogTUxEYXRlX2dldCxcbiAgICAgICAgc2V0OiBNTERhdGVfc2V0LFxuICAgICAgICBkZWw6IE1MRGF0ZV9kZWwsXG4gICAgfSxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktZGF0ZSdcbiAgICB9XG59KTtcblxuXy5leHRlbmRQcm90byhNTERhdGUsIHtcbiAgICBnZXRNaW46IE1MRGF0ZSRnZXRNaW4sXG4gICAgc2V0TWluOiBNTERhdGUkc2V0TWluLFxuICAgIGdldE1heDogTUxEYXRlJGdldE1heCxcbiAgICBzZXRNYXg6IE1MRGF0ZSRzZXRNYXhcbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MRGF0ZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxEYXRlO1xuXG5cbmZ1bmN0aW9uIE1MRGF0ZSRnZXRNaW4oKSB7XG4gICAgcmV0dXJuIF8uZGF0ZSh0aGlzLmVsLm1pbik7XG59XG5cblxuZnVuY3Rpb24gTUxEYXRlJHNldE1pbih2YWx1ZSkge1xuICAgIHZhciBkYXRlID0gXy50b0RhdGUodmFsdWUpO1xuXG4gICAgdGhpcy5lbC5taW4gPSBkYXRlID8gdG9JU084NjAxRm9ybWF0KGRhdGUpIDogJyc7XG59XG5cblxuZnVuY3Rpb24gTUxEYXRlJGdldE1heCgpIHtcbiAgICByZXR1cm4gXy5kYXRlKHRoaXMuZWwubWF4KTtcbn1cblxuXG5mdW5jdGlvbiBNTERhdGUkc2V0TWF4KHZhbHVlKSB7XG4gICAgdmFyIGRhdGUgPSBfLnRvRGF0ZSh2YWx1ZSk7XG5cbiAgICB0aGlzLmVsLm1heCA9IGRhdGUgPyB0b0lTTzg2MDFGb3JtYXQoZGF0ZSkgOiAnJztcbn1cblxuXG5mdW5jdGlvbiBNTERhdGVfZ2V0KCkge1xuICAgIHJldHVybiBfLnRvRGF0ZSh0aGlzLmVsLnZhbHVlKTtcbn1cblxuXG5mdW5jdGlvbiBNTERhdGVfc2V0KHZhbHVlKSB7XG4gICAgdmFyIGRhdGUgPSBfLnRvRGF0ZSh2YWx1ZSk7XG5cbiAgICB0aGlzLmVsLnZhbHVlID0gZGF0ZSA/IHRvSVNPODYwMUZvcm1hdChkYXRlKSA6ICcnO1xuXG4gICAgZGlzcGF0Y2hJbnB1dE1lc3NhZ2UuY2FsbCh0aGlzKTtcbn1cblxuZnVuY3Rpb24gTUxEYXRlX2RlbCgpIHtcbiAgICB0aGlzLmVsLnZhbHVlID0gJyc7XG5cbiAgICBkaXNwYXRjaElucHV0TWVzc2FnZS5jYWxsKHRoaXMpO1xufVxuXG5cbmZ1bmN0aW9uIGRpc3BhdGNoSW5wdXRNZXNzYWdlKCkge1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoJ2lucHV0Jyk7IC8vIERpc3BhdGNoIHRoZSAnaW5wdXQnICh1c3VhbGx5IGRpc3BhdGNoZWQgYnkgdGhlIHVuZGVybHlpbmcgPGlucHV0PiBlbGVtZW50KSBldmVudCBzbyB0aGF0IHRoZSBkYXRhIGNoYW5nZSBjYW4gYmUgbGlzdGVuZWQgdG9cbn1cblxuXG5mdW5jdGlvbiB0b0lTTzg2MDFGb3JtYXQoZGF0ZSkge1xuICAgIHZhciBkYXRlQXJyID0gW1xuICAgICAgICBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgIHBhZChkYXRlLmdldE1vbnRoKCkgKyAxKSxcbiAgICAgICAgcGFkKGRhdGUuZ2V0RGF0ZSgpKVxuICAgIF07XG5cbiAgICB2YXIgZGF0ZVN0ciA9IGRhdGVBcnIuam9pbignLScpO1xuXG4gICAgcmV0dXJuIGRhdGVTdHI7XG5cbiAgICBmdW5jdGlvbiBwYWQobikgeyByZXR1cm4gbiA8IDEwID8gJzAnICsgbiA6IG47IH1cbn0iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBNTERyb3BUYXJnZXQgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MRHJvcFRhcmdldCcsIFsnZHJvcCddKTtcblxuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MRHJvcFRhcmdldCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxEcm9wVGFyZ2V0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9UID0gcmVxdWlyZSgnZG90JylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBtaWxvQ291bnQgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NvdW50Jyk7XG5cbnZhciBUUkVFX1RFTVBMQVRFID0gJzx1bCBjbGFzcz1cIm1sLXVpLWZvbGR0cmVlLWxpc3RcIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAge3t+IGl0LmRhdGEuaXRlbXMgOml0ZW06aW5kZXggfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHZhciBoYXNTdWJUcmVlID0gaXRlbS5pdGVtcyAmJiBpdGVtLml0ZW1zLmxlbmd0aDsgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSB7ez8gaGFzU3ViVHJlZSB9fWNsYXNzPVwibWwtdWktZm9sZHRyZWUtLWhhcy1tdWx0aXBsZVwie3s/fX0+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1sLXVpLWZvbGR0cmVlLWl0ZW1cIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/IGhhc1N1YlRyZWUgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtbC11aS1mb2xkdHJlZS1idXR0b25cIj48L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3s9IGl0Lml0ZW1UZW1wbGF0ZSh7IGl0ZW06IGl0ZW0sIGlkOiBpdC5pdGVtSURzW2luZGV4XSB9KSB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7PyBoYXNTdWJUcmVlIH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7PSBpdC50cmVlVGVtcGxhdGUoaXRlbSkgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7ez99fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cXFxuICAgICAgICAgICAgICAgICAgICAgICAge3t+fX1cXFxuICAgICAgICAgICAgICAgICAgICA8L3VsPic7XG5cbnZhciBERUZBVUxUX0NPTVBJTEVEX0lURU1fVEVNUExBVEUgPSBkb1QuY29tcGlsZSgnXFxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWwtdWktZm9sZHRyZWUtbGFiZWxcIiBkYXRhLWl0ZW0taWQ9XCJ7ez0gaXQuaWQgfX1cIj5cXFxuICAgICAgICAgICAgICAgIHt7PSBpdC5pdGVtLmxhYmVsIH19XFxcbiAgICAgICAgICAgIDwvc3Bhbj4nKVxuICAgICwgQ09NUElMRURfVFJFRV9URU1QTEFURSA9IGRvVC5jb21waWxlKFRSRUVfVEVNUExBVEUpO1xuXG5cbnZhciBNTEZvbGRUcmVlID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTEZvbGRUcmVlJywge1xuICAgIGNvbnRhaW5lcjogdW5kZWZpbmVkLFxuICAgIGV2ZW50czoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJ2NsaWNrIGRibGNsaWNrJzogeyBzdWJzY3JpYmVyOiBvbkl0ZW1FdmVudCwgY29udGV4dDogJ293bmVyJyB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1mb2xkdHJlZS1tYWluJ1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MRm9sZFRyZWUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MRm9sZFRyZWU7XG5cbl8uZXh0ZW5kUHJvdG8oTUxGb2xkVHJlZSwge1xuICAgIHNldEl0ZW1UZW1wbGF0ZTogTUxGb2xkVHJlZSRzZXRJdGVtVGVtcGxhdGUsXG4gICAgcmVuZGVyVHJlZTogTUxGb2xkVHJlZSRyZW5kZXJUcmVlXG59KTtcblxuZnVuY3Rpb24gZm9sZFVuZm9sZChlbCkge1xuICAgIGVsLmNsYXNzTGlzdC50b2dnbGUoJ21sLXVpLWZvbGR0cmVlLS11bmZvbGQnKTtcbn1cblxuZnVuY3Rpb24gaXRlbU1lc3NhZ2UobXNnLCBlbCkge1xuICAgIHZhciBpZCA9IGVsLmdldEF0dHJpYnV0ZSgnZGF0YS1pdGVtLWlkJylcbiAgICAgICAgLCBpdGVtID0gdGhpcy5faXRlbXNNYXBbaWRdO1xuXG4gICAgdGhpcy5wb3N0TWVzc2FnZSgnbWxmb2xkdHJlZV8nICsgbXNnLCB7XG4gICAgICAgIGl0ZW06IGl0ZW0sXG4gICAgICAgIGVsOiBlbFxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBvbkl0ZW1FdmVudChtc2csIGUpIHtcbiAgICB2YXIgZWwgPSBlLnRhcmdldDtcbiAgICBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdtbC11aS1mb2xkdHJlZS1idXR0b24nKSlcbiAgICAgICAgZm9sZFVuZm9sZChlbC5wYXJlbnROb2RlLnBhcmVudE5vZGUpO1xuICAgIGVsc2UgaWYgKGVsLmNsYXNzTGlzdC5jb250YWlucygnbWwtdWktZm9sZHRyZWUtbGFiZWwnKSlcbiAgICAgICAgaXRlbU1lc3NhZ2UuY2FsbCh0aGlzLCBtc2csIGVsKTtcbiAgICBlbHNlIHJldHVybjtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xufVxuXG5mdW5jdGlvbiBNTEZvbGRUcmVlJHNldEl0ZW1UZW1wbGF0ZSAodGVtcGxhdGVTdHIpIHtcbiAgICB0aGlzLl9pdGVtVGVtcGxhdGUgPSBkb1QuY29tcGlsZSh0ZW1wbGF0ZVN0cik7XG59XG5cbmZ1bmN0aW9uIE1MRm9sZFRyZWUkcmVuZGVyVHJlZSAoZGF0YSkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICBzZWxmLl9pdGVtc01hcCA9IHt9O1xuICAgIHRoaXMuZWwuaW5uZXJIVE1MID0gX3JlbmRlclRyZWUoZGF0YSk7XG5cbiAgICBmdW5jdGlvbiBfcmVuZGVyVHJlZSAoZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5pdGVtcylcbiAgICAgICAgICAgIHZhciBpdGVtc0lEcyA9IF8ubWFwKGRhdGEuaXRlbXMsIGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICB2YXIgaWQgPSBtaWxvQ291bnQoKTtcbiAgICAgICAgICAgICAgICBzZWxmLl9pdGVtc01hcFtpZF0gPSBpdGVtO1xuICAgICAgICAgICAgICAgIHJldHVybiBpZDsgXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gQ09NUElMRURfVFJFRV9URU1QTEFURSh7XG4gICAgICAgICAgICBpdGVtSURzOiBpdGVtc0lEcyxcbiAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICBpdGVtVGVtcGxhdGU6IHNlbGYuX2l0ZW1UZW1wbGF0ZSB8fCBERUZBVUxUX0NPTVBJTEVEX0lURU1fVEVNUExBVEUsXG4gICAgICAgICAgICB0cmVlVGVtcGxhdGU6IF9yZW5kZXJUcmVlXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBNTEdyb3VwID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTEdyb3VwJywge1xuICAgIGNvbnRhaW5lcjogdW5kZWZpbmVkLFxuICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktZ3JvdXAnXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxHcm91cCk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxHcm91cDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBNTEh5cGVybGluayA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxIeXBlcmxpbmsnLCB7XG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1oeXBlcmxpbmsnXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxIeXBlcmxpbmspO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MSHlwZXJsaW5rO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG52YXIgSU1BR0VfQ0hBTkdFX01FU1NBR0UgPSAnbWxpbWFnZWNoYW5nZSc7XG5cbnZhciBNTEltYWdlID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTEltYWdlJywge1xuICAgIGRhdGE6IHtcbiAgICAgICAgc2V0OiBNTEltYWdlX3NldCxcbiAgICAgICAgZ2V0OiBNTEltYWdlX2dldCxcbiAgICAgICAgZGVsOiBNTEltYWdlX2RlbCxcbiAgICAgICAgc3BsaWNlOiB1bmRlZmluZWQsXG4gICAgICAgIGV2ZW50OiBJTUFHRV9DSEFOR0VfTUVTU0FHRVxuICAgIH0sXG4gICAgbW9kZWw6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICcuc3JjJzogeyBzdWJzY3JpYmVyOiBvbk1vZGVsQ2hhbmdlLCBjb250ZXh0OiAnb3duZXInIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIHRhZ05hbWU6ICdpbWcnLFxuICAgICAgICBjbHM6ICdtbC11aS1pbWFnZSdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTEltYWdlKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTEltYWdlO1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxJbWFnZSwge1xuICAgIGluaXQ6IE1MSW1hZ2UkaW5pdFxufSk7XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplIHJhZGlvIGdyb3VwIGFuZCBzZXR1cFxuICovXG5mdW5jdGlvbiBNTEltYWdlJGluaXQoKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuLyoqXG4gKiBTZXRzIGltYWdlIHZhbHVlXG4gKiBSZXBsYWNlcyB0aGUgZGF0YSBzZXQgb3BlcmF0aW9uIHRvIGRlYWwgd2l0aCByYWRpbyBidXR0b25zXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgVGhlIHZhbHVlIHRvIGJlIHNldFxuICovXG5mdW5jdGlvbiBNTEltYWdlX3NldCh2YWx1ZSkge1xuICAgIHRoaXMubW9kZWwuc2V0KHZhbHVlKTtcbiAgICByZXR1cm4gdmFsdWU7XG59XG5cblxuLyoqXG4gKiBHZXRzIGdyb3VwIHZhbHVlXG4gKiBSZXRyaWV2ZXMgdGhlIHNlbGVjdGVkIHZhbHVlIG9mIHRoZSBncm91cFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gTUxJbWFnZV9nZXQoKSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5tb2RlbC5nZXQoKTtcbiAgICByZXR1cm4gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnID8gXy5jbG9uZSh2YWx1ZSkgOiB2YWx1ZTtcbn1cblxuXG4vKipcbiAqIERlbGV0ZWQgZ3JvdXAgdmFsdWVcbiAqIERlbGV0ZXMgdGhlIHZhbHVlIG9mIHRoZSBncm91cCwgc2V0dGluZyBpdCB0byBlbXB0eVxuICovXG5mdW5jdGlvbiBNTEltYWdlX2RlbCgpIHtcbiAgICB0aGlzLm1vZGVsLmRlbCgpO1xufVxuXG5cbi8vIFBvc3QgdGhlIGRhdGEgY2hhbmdlXG5mdW5jdGlvbiBkaXNwYXRjaENoYW5nZU1lc3NhZ2UoKSB7XG4gICAgdGhpcy5kYXRhLmRpc3BhdGNoU291cmNlTWVzc2FnZShJTUFHRV9DSEFOR0VfTUVTU0FHRSk7XG59XG5cblxuZnVuY3Rpb24gb25Nb2RlbENoYW5nZShwYXRoLCBkYXRhKSB7XG4gICAgdGhpcy5lbC5zcmMgPSBkYXRhLm5ld1ZhbHVlO1xuICAgIGRpc3BhdGNoQ2hhbmdlTWVzc2FnZS5jYWxsKHRoaXMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG52YXIgTUxJbnB1dCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxJbnB1dCcsIHtcbiAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLWlucHV0J1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MSW5wdXQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MSW5wdXQ7XG5cbl8uZXh0ZW5kUHJvdG8oTUxJbnB1dCwge1xuICAgIGRpc2FibGU6IE1MSW5wdXQkZGlzYWJsZSxcbiAgICBpc0Rpc2FibGVkOiBNTElucHV0JGlzRGlzYWJsZWQsXG4gICAgc2V0TWF4TGVuZ3RoOiBNTElucHV0JHNldE1heExlbmd0aFxufSk7XG5cbmZ1bmN0aW9uIE1MSW5wdXQkZGlzYWJsZShkaXNhYmxlKSB7XG4gICAgdGhpcy5lbC5kaXNhYmxlZCA9IGRpc2FibGU7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXQkaXNEaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gISF0aGlzLmVsLmRpc2FibGVkO1xufVxuXG5mdW5jdGlvbiBNTElucHV0JHNldE1heExlbmd0aChsZW5ndGgpIHtcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnbWF4bGVuZ3RoJywgbGVuZ3RoKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cbnZhciBJTlBVVF9MSVNUX0NIQU5HRV9NRVNTQUdFID0gJ21saW5wdXRsaXN0Y2hhbmdlJztcblxudmFyIGFzeW5jSGFuZGxlciA9IGZ1bmN0aW9uICh2YWx1ZSwgY2FsbGJhY2spIHtjYWxsYmFjayh2YWx1ZSk7fTtcblxudmFyIE1MSW5wdXRMaXN0ID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTElucHV0TGlzdCcsIHtcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktaW5wdXQtbGlzdCdcbiAgICB9LFxuICAgIGRhdGE6IHtcbiAgICAgICAgZ2V0OiBNTElucHV0TGlzdF9nZXQsXG4gICAgICAgIHNldDogTUxJbnB1dExpc3Rfc2V0LFxuICAgICAgICBkZWw6IE1MSW5wdXRMaXN0X2RlbCxcbiAgICAgICAgc3BsaWNlOiBNTElucHV0TGlzdF9zcGxpY2UsXG4gICAgICAgIGV2ZW50OiBJTlBVVF9MSVNUX0NIQU5HRV9NRVNTQUdFXG4gICAgfSxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBjb250YWluZXI6IHVuZGVmaW5lZCxcbiAgICBtb2RlbDoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJyoqKic6IHsgc3Vic2NyaWJlcjogb25JdGVtc0NoYW5nZSwgY29udGV4dDogJ293bmVyJyB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICAgIHRlbXBsYXRlOiAnXFxcbiAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIk1MTGlzdDpsaXN0XCI+XFxcbiAgICAgICAgICAgICAgICA8ZGl2IG1sLWJpbmQ9XCJNTExpc3RJdGVtOml0ZW1cIiBjbGFzcz1cImxpc3QtaXRlbVwiPlxcXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIG1sLWJpbmQ9XCJbZGF0YV06bGFiZWxcIj48L3NwYW4+XFxcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gbWwtYmluZD1cIltldmVudHNdOmRlbGV0ZUJ0blwiIGNsYXNzPVwiZ2x5cGhpY29uIGdseXBoaWNvbi1yZW1vdmVcIj48L3NwYW4+XFxcbiAgICAgICAgICAgICAgICA8L2Rpdj5cXFxuICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIG1sLWJpbmQ9XCJNTElucHV0OmlucHV0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cXFxuICAgICAgICAgICAgPGJ1dHRvbiBtbC1iaW5kPVwiTUxCdXR0b246YnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHRcIj5cXFxuICAgICAgICAgICAgICAgIEFkZFxcXG4gICAgICAgICAgICA8L2J1dHRvbj4nXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxJbnB1dExpc3QpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MSW5wdXRMaXN0O1xuXG5fLmV4dGVuZFByb3RvKE1MSW5wdXRMaXN0LCB7XG4gICAgaW5pdDogTUxJbnB1dExpc3QkaW5pdCxcbiAgICBzZXRBc3luYzogTUxJbnB1dExpc3Qkc2V0QXN5bmMsXG4gICAgc2V0UGxhY2VIb2xkZXI6IE1MSW5wdXRMaXN0JHNldFBsYWNlSG9sZGVyLFxuICAgIGRlc3Ryb3k6IE1MSW5wdXRMaXN0JGRlc3Ryb3lcbn0pO1xuXG5mdW5jdGlvbiBNTElucHV0TGlzdCRpbml0KCkge1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMub25jZSgnY2hpbGRyZW5ib3VuZCcsIG9uQ2hpbGRyZW5Cb3VuZCk7XG4gICAgdGhpcy5tb2RlbC5zZXQoW10pO1xufVxuXG5mdW5jdGlvbiBvbkNoaWxkcmVuQm91bmQoKSB7XG4gICAgcmVuZGVyLmNhbGwodGhpcyk7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0JHNldFBsYWNlSG9sZGVyKHBsYWNlSG9sZGVyKSB7XG4gICAgdGhpcy5faW5wdXQuZWwuc2V0QXR0cmlidXRlKCdwbGFjZUhvbGRlcicsIHBsYWNlSG9sZGVyKTtcbn1cblxuZnVuY3Rpb24gTUxJbnB1dExpc3Qkc2V0QXN5bmMobmV3SGFuZGxlcikge1xuICAgIGFzeW5jSGFuZGxlciA9IG5ld0hhbmRsZXIgfHwgYXN5bmNIYW5kbGVyO1xufVxuXG5mdW5jdGlvbiBNTElucHV0TGlzdCRkZXN0cm95KCkge1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMuX2Nvbm5lY3RvciAmJiBtaWxvLm1pbmRlci5kZXN0cm95Q29ubmVjdG9yKHRoaXMuX2Nvbm5lY3Rvcik7XG4gICAgdGhpcy5fY29ubmVjdG9yID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgIHRoaXMudGVtcGxhdGUucmVuZGVyKCkuYmluZGVyKCk7XG4gICAgY29tcG9uZW50U2V0dXAuY2FsbCh0aGlzKTtcbn1cblxuZnVuY3Rpb24gY29tcG9uZW50U2V0dXAoKSB7XG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgJ19pbnB1dCc6IHRoaXMuY29udGFpbmVyLnNjb3BlLmlucHV0LFxuICAgICAgICAnX2J1dHRvbic6IHRoaXMuY29udGFpbmVyLnNjb3BlLmJ1dHRvbixcbiAgICAgICAgJ19saXN0JzogdGhpcy5jb250YWluZXIuc2NvcGUubGlzdFxuICAgIH0pO1xuICAgIHRoaXMuX2Nvbm5lY3RvciA9IG1pbG8ubWluZGVyKHRoaXMuX2xpc3QubW9kZWwsICc8PDwtPj4+JywgdGhpcy5tb2RlbCk7XG4gICAgdGhpcy5fYnV0dG9uLmV2ZW50cy5vbignY2xpY2snLCB7c3Vic2NyaWJlcjogb25DbGljaywgY29udGV4dDogdGhpcyB9KTsgICBcbn1cblxuZnVuY3Rpb24gb25DbGljayhtc2cpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLl9pbnB1dC5kYXRhLmdldCgwKTtcbiAgICBpZiAodGhpcy5faW5wdXQuZGF0YSlcbiAgICAgICAgYXN5bmNIYW5kbGVyKHZhbHVlLCBmdW5jdGlvbiAobGFiZWwsIHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9saXN0Lm1vZGVsLnB1c2goeyBsYWJlbDogbGFiZWwsIHZhbHVlOiB2YWx1ZSB9KTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLl9pbnB1dC5kYXRhLmRlbCgpO1xufVxuXG5mdW5jdGlvbiBvbkl0ZW1zQ2hhbmdlKG1zZywgZGF0YSkge1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoSU5QVVRfTElTVF9DSEFOR0VfTUVTU0FHRSk7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0X2dldCgpIHtcbiAgICB2YXIgbW9kZWwgPSB0aGlzLm1vZGVsLmdldCgpO1xuICAgIHJldHVybiBtb2RlbCA/IF8uY2xvbmUobW9kZWwpIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBNTElucHV0TGlzdF9zZXQodmFsdWUpIHtcbiAgICB0aGlzLm1vZGVsLnNldCh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIE1MSW5wdXRMaXN0X2RlbCgpIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbC5zZXQoW10pO1xufVxuXG5mdW5jdGlvbiBNTElucHV0TGlzdF9zcGxpY2UoKSB7IC8vIC4uLiBhcmd1bWVudHNcbiAgICB0aGlzLm1vZGVsLnNwbGljZS5hcHBseSh0aGlzLm1vZGVsLCBhcmd1bWVudHMpO1xufSIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cbnZhciBMSVNUX0NIQU5HRV9NRVNTQUdFID0gJ21sbGlzdGNoYW5nZSdcbiAgICAsIERFTEVURV9CVVRUT05fTkFNRSA9ICdkZWxldGVCdG4nO1xuXG5cbnZhciBNTExpc3QgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MTGlzdCcsIHtcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktbGlzdCdcbiAgICB9LFxuICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBtb2RlbDogdW5kZWZpbmVkLFxuICAgIGxpc3Q6IHVuZGVmaW5lZFxufSk7XG5cblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTExpc3QpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MTGlzdDtcblxuXG5fLmV4dGVuZFByb3RvKE1MTGlzdCwge1xuICAgIGluaXQ6IE1MTGlzdCRpbml0LFxuICAgIGRlc3Ryb3k6IE1MTGlzdCRkZXN0cm95LFxuICAgIHJlbW92ZUl0ZW06IE1MTGlzdCRyZW1vdmVJdGVtLFxuICAgIG1vdmVJdGVtOiBNTExpc3QkbW92ZUl0ZW1cbn0pO1xuXG5cbmZ1bmN0aW9uIE1MTGlzdCRpbml0KCkge1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMub24oJ2NoaWxkcmVuYm91bmQnLCBvbkNoaWxkcmVuQm91bmQpO1xufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdCRkZXN0cm95KCkge1xuICAgIHRoaXMuX2Nvbm5lY3RvciAmJiBtaWxvLm1pbmRlci5kZXN0cm95Q29ubmVjdG9yKHRoaXMuX2Nvbm5lY3Rvcik7XG4gICAgdGhpcy5fY29ubmVjdG9yID0gbnVsbDtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuXG5mdW5jdGlvbiBNTExpc3QkcmVtb3ZlSXRlbShpbmRleCl7XG4gICAgdGhpcy5tb2RlbC5zcGxpY2UoaW5kZXgsIDEpO1xufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdCRtb3ZlSXRlbShmcm9tLCB0bykge1xuICAgIHZhciBzcGxpY2VkRGF0YSA9IHRoaXMubW9kZWwuc3BsaWNlKGZyb20sIDEpO1xuICAgIHJldHVybiB0aGlzLm1vZGVsLnNwbGljZSh0bywgMCwgc3BsaWNlZERhdGFbMF0pO1xufVxuXG5cbmZ1bmN0aW9uIG9uQ2hpbGRyZW5Cb3VuZCgpIHtcbiAgICB0aGlzLm1vZGVsLnNldChbXSk7XG4gICAgdGhpcy5fY29ubmVjdG9yID0gbWlsby5taW5kZXIodGhpcy5tb2RlbCwgJzw8PC0nLCB0aGlzLmRhdGEpLmRlZmVyQ2hhbmdlTW9kZSgnPDw8LT4+PicpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBEcmFnRHJvcCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZHJhZ2Ryb3AnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxudmFyIExJU1RJVEVNX0NIQU5HRV9NRVNTQUdFID0gJ21sbGlzdGl0ZW1jaGFuZ2UnXG5cbnZhciBNTExpc3RJdGVtID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTExpc3RJdGVtJywge1xuICAgIGNvbnRhaW5lcjogdW5kZWZpbmVkLFxuICAgIGRvbTogdW5kZWZpbmVkLFxuICAgIGRyYWc6IHtcbiAgICAgICAgbWV0YToge1xuICAgICAgICAgICAgcGFyYW1zOiBnZXRNZXRhRGF0YVxuICAgICAgICB9XG4gICAgfSxcbiAgICBkcm9wOiB7XG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICAnZHJhZ2VudGVyJzogeyBzdWJzY3JpYmVyOiBvbkRyYWdIb3ZlciwgY29udGV4dDogJ293bmVyJyB9LFxuICAgICAgICAgICAgJ2RyYWdvdmVyJzogeyBzdWJzY3JpYmVyOiBvbkRyYWdIb3ZlciwgY29udGV4dDogJ293bmVyJyB9LFxuICAgICAgICAgICAgJ2RyYWdsZWF2ZSc6IHsgc3Vic2NyaWJlcjogb25EcmFnT3V0LCBjb250ZXh0OiAnb3duZXInIH0sXG4gICAgICAgICAgICAnZHJvcCc6IHsgc3Vic2NyaWJlcjogb25JdGVtRHJvcCwgY29udGV4dDogJ293bmVyJyB9XG4gICAgICAgIH0sXG4gICAgICAgIGFsbG93OiB7XG4gICAgICAgICAgICBjb21wb25lbnRzOiBpc0NvbXBvbmVudEFsbG93ZWRcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZGF0YToge1xuICAgICAgICBnZXQ6IE1MTGlzdEl0ZW1fZ2V0LFxuICAgICAgICBzZXQ6IE1MTGlzdEl0ZW1fc2V0LFxuICAgICAgICBkZWw6IE1MTGlzdEl0ZW1fZGVsLFxuICAgICAgICBldmVudDogTElTVElURU1fQ0hBTkdFX01FU1NBR0VcbiAgICB9LFxuICAgIG1vZGVsOiB1bmRlZmluZWQsXG4gICAgaXRlbTogdW5kZWZpbmVkXG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTExpc3RJdGVtKTtcblxudmFyIE1MTGlzdEl0ZW0gPSBtb2R1bGUuZXhwb3J0cyA9IE1MTGlzdEl0ZW07XG5cblxuXy5leHRlbmRQcm90byhNTExpc3RJdGVtLCB7XG4gICAgaW5pdDogTUxMaXN0SXRlbSRpbml0LFxuICAgIG1vdmVJdGVtOiBNTExpc3RJdGVtJG1vdmVJdGVtLFxuICAgIHJlbW92ZUl0ZW06IE1MTGlzdEl0ZW0kcmVtb3ZlSXRlbSxcbiAgICBpc0Ryb3BBbGxvd2VkOiBNTExpc3RJdGVtJGlzRHJvcEFsbG93ZWRcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MTGlzdEl0ZW0kaW5pdCgpIHtcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLm9uKCdjaGlsZHJlbmJvdW5kJywgb25DaGlsZHJlbkJvdW5kKTtcbn1cblxuXG5mdW5jdGlvbiBvbkNoaWxkcmVuQm91bmQoKSB7XG4gICAgdmFyIGRlbGV0ZUJ0biA9IHRoaXMuY29udGFpbmVyLnNjb3BlLmRlbGV0ZUJ0bjtcbiAgICBkZWxldGVCdG4gJiYgZGVsZXRlQnRuLmV2ZW50cy5vbignY2xpY2snLCB7IHN1YnNjcmliZXI6IHRoaXMucmVtb3ZlSXRlbSwgY29udGV4dDogdGhpcyB9KTtcbn1cblxuXG5mdW5jdGlvbiBNTExpc3RJdGVtJHJlbW92ZUl0ZW0oKSB7XG4gICAgdHJ5IHsgdmFyIGxpc3RPd25lciA9IHRoaXMuaXRlbS5saXN0Lm93bmVyOyB9IGNhdGNoKGUpIHt9XG4gICAgbGlzdE93bmVyICYmIGxpc3RPd25lci5yZW1vdmVJdGVtKHRoaXMuaXRlbS5pbmRleCk7XG59XG5cblxuZnVuY3Rpb24gTUxMaXN0SXRlbSRtb3ZlSXRlbShpbmRleCkge1xuICAgIHZhciBsaXN0T3duZXIgPSB0aGlzLml0ZW0ubGlzdC5vd25lcjtcbiAgICBsaXN0T3duZXIgJiYgbGlzdE93bmVyLm1vdmVJdGVtKHRoaXMuaXRlbS5pbmRleCwgaW5kZXgpO1xufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdEl0ZW0kaXNEcm9wQWxsb3dlZChtZXRhLCBkcmFnRHJvcCl7XG4gICAgcmV0dXJuIG1ldGEucGFyYW1zICYmIG1ldGEucGFyYW1zLmluZGV4ICYmIG1ldGEuY29tcENsYXNzID09ICdNTExpc3RJdGVtJztcbn1cblxuXG5mdW5jdGlvbiBpc0NvbXBvbmVudEFsbG93ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNEcm9wQWxsb3dlZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIG9uSXRlbURyb3AoZXZlbnRUeXBlLCBldmVudCkge1xuICAgIG9uRHJhZ091dC5jYWxsKHRoaXMpO1xuICAgIHZhciBkdCA9IG5ldyBEcmFnRHJvcChldmVudCk7XG4gICAgdmFyIG1ldGEgPSBkdC5nZXRDb21wb25lbnRNZXRhKCk7XG4gICAgdmFyIHN0YXRlID0gZHQuZ2V0Q29tcG9uZW50U3RhdGUoKTtcbiAgICB2YXIgbGlzdE93bmVyID0gdGhpcy5pdGVtLmxpc3Qub3duZXI7XG4gICAgdmFyIGluZGV4ID0gbWV0YS5wYXJhbXMgJiYgbWV0YS5wYXJhbXMuaW5kZXg7XG5cbiAgICBsaXN0T3duZXIubW92ZUl0ZW0oK2luZGV4LCB0aGlzLml0ZW0uaW5kZXgsIHN0YXRlKTtcbn1cblxuXG5mdW5jdGlvbiBvbkRyYWdIb3ZlcihldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgdGhpcy5kb20uYWRkQ3NzQ2xhc3NlcygnbWwtZHJhZy1vdmVyJyk7XG59XG5cblxuZnVuY3Rpb24gb25EcmFnT3V0KGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICB0aGlzLmRvbS5yZW1vdmVDc3NDbGFzc2VzKCdtbC1kcmFnLW92ZXInKTtcbn1cblxuXG5mdW5jdGlvbiBnZXRNZXRhRGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBpbmRleDogdGhpcy5pdGVtLmluZGV4XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIE1MTGlzdEl0ZW1fZ2V0KCkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWwuZ2V0KCk7XG4gICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyA/IF8uY2xvbmUodmFsdWUpIDogdmFsdWU7XG59XG5cblxuZnVuY3Rpb24gTUxMaXN0SXRlbV9zZXQodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKVxuICAgICAgICB0aGlzLmRhdGEuX3NldCh2YWx1ZSk7XG4gICAgdGhpcy5tb2RlbC5zZXQodmFsdWUpO1xuICAgIF9zZW5kQ2hhbmdlTWVzc2FnZS5jYWxsKHRoaXMpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuXG5mdW5jdGlvbiBNTExpc3RJdGVtX2RlbCgpIHtcbiAgICB0aGlzLmRhdGEuX2RlbCgpO1xuICAgIHRoaXMubW9kZWwuZGVsKCk7XG4gICAgX3NlbmRDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7ICAgIFxufVxuXG5cbmZ1bmN0aW9uIF9zZW5kQ2hhbmdlTWVzc2FnZSgpIHtcbiAgICB0aGlzLmRhdGEuZGlzcGF0Y2hTb3VyY2VNZXNzYWdlKExJU1RJVEVNX0NIQU5HRV9NRVNTQUdFKTtcbn1cblxuXG5cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBtaWxvQ291bnQgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NvdW50JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG52YXIgUkFESU9fQ0hBTkdFX01FU1NBR0UgPSAnbWxyYWRpb2dyb3VwY2hhbmdlJ1xuICAgICwgRUxFTUVOVF9OQU1FX1BST1BFUlRZID0gJ19tbFJhZGlvR3JvdXBFbGVtZW50SUQnXG4gICAgLCBFTEVNRU5UX05BTUVfUFJFRklYID0gJ21sLXJhZGlvLWdyb3VwLSc7XG5cbnZhciBNTFJhZGlvR3JvdXAgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MUmFkaW9Hcm91cCcsIHtcbiAgICBkYXRhOiB7XG4gICAgICAgIHNldDogTUxSYWRpb0dyb3VwX3NldCxcbiAgICAgICAgZ2V0OiBNTFJhZGlvR3JvdXBfZ2V0LFxuICAgICAgICBkZWw6IE1MUmFkaW9Hcm91cF9kZWwsXG4gICAgICAgIHNwbGljZTogdW5kZWZpbmVkLFxuICAgICAgICBldmVudDogUkFESU9fQ0hBTkdFX01FU1NBR0VcbiAgICB9LFxuICAgIG1vZGVsOiB7XG4gICAgICAgIG1lc3NhZ2VzOiB7XG4gICAgICAgICAgICAnKioqJzogeyBzdWJzY3JpYmVyOiBvbk9wdGlvbnNDaGFuZ2UsIGNvbnRleHQ6ICdvd25lcicgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBldmVudHM6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICdjbGljayc6IHsgc3Vic2NyaWJlcjogb25Hcm91cENsaWNrLCBjb250ZXh0OiAnb3duZXInIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLXJhZGlvLWdyb3VwJ1xuICAgIH0sXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgICAgdGVtcGxhdGU6ICd7e34gaXQucmFkaW9PcHRpb25zIDpvcHRpb24gfX0gXFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IyNkZWYuZWxJRDp7ez0gaXQuZWxlbWVudE5hbWUgfX0te3s9IG9wdGlvbi52YWx1ZSB9fSN9fSBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ7ez0gaXQuX3JlbmRlck9wdGlvbnMub3B0aW9uQ3NzQ2xhc3MgfHwgXCInICsgRUxFTUVOVF9OQU1FX1BSRUZJWCArICdvcHRpb25cIiB9fVwiPiBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cInt7IyBkZWYuZWxJRCB9fVwiIHR5cGU9XCJyYWRpb1wiIHZhbHVlPVwie3s9IG9wdGlvbi52YWx1ZSB9fVwiIG5hbWU9XCJ7ez0gaXQuZWxlbWVudE5hbWUgfX1cIj4gXFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwie3sjIGRlZi5lbElEIH19XCI+e3s9IG9wdGlvbi5sYWJlbCB9fTwvbGFiZWw+IFxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+IFxcXG4gICAgICAgICAgICAgICAgICAge3t+fX0nXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxSYWRpb0dyb3VwKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTFJhZGlvR3JvdXA7XG5cblxuXy5leHRlbmRQcm90byhNTFJhZGlvR3JvdXAsIHtcbiAgICBpbml0OiBNTFJhZGlvR3JvdXAkaW5pdCxcbiAgICBkZXN0cm95OiBNTFJhZGlvR3JvdXAkZGVzdHJveSxcbiAgICBzZXRSZW5kZXJPcHRpb25zOiBNTFJhZGlvR3JvdXAkc2V0UmVuZGVyT3B0aW9uc1xufSk7XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplIHJhZGlvIGdyb3VwIGFuZCBzZXR1cFxuICovXG5mdW5jdGlvbiBNTFJhZGlvR3JvdXAkaW5pdCgpIHtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfcmFkaW9MaXN0JywgW10sIF8uQ09ORik7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBFTEVNRU5UX05BTUVfUFJPUEVSVFksIEVMRU1FTlRfTkFNRV9QUkVGSVggKyBtaWxvQ291bnQoKSk7XG4gICAgdGhpcy5fcmVuZGVyT3B0aW9ucyA9IHt9O1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIE1MUmFkaW9Hcm91cCRzZXRSZW5kZXJPcHRpb25zKG9wdGlvbnMpIHtcbiAgICB0aGlzLl9yZW5kZXJPcHRpb25zID0gb3B0aW9ucztcbn1cblxuXG4vKipcbiAqIFNldHMgZ3JvdXAgdmFsdWVcbiAqIFJlcGxhY2VzIHRoZSBkYXRhIHNldCBvcGVyYXRpb24gdG8gZGVhbCB3aXRoIHJhZGlvIGJ1dHRvbnNcbiAqXG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYmUgc2V0XG4gKi9cbmZ1bmN0aW9uIE1MUmFkaW9Hcm91cF9zZXQodmFsdWUpIHtcbiAgICB2YXIgb3B0aW9ucyA9IHRoaXMuX3JhZGlvTGlzdFxuICAgICAgICAsIHNldFJlc3VsdDtcbiAgICBpZiAob3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKHJhZGlvKSB7XG4gICAgICAgICAgICByYWRpby5jaGVja2VkID0gcmFkaW8udmFsdWUgPT0gdmFsdWU7XG4gICAgICAgICAgICBpZiAocmFkaW8uY2hlY2tlZClcbiAgICAgICAgICAgICAgICBzZXRSZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlLmNhbGwodGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHNldFJlc3VsdDtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBHZXRzIGdyb3VwIHZhbHVlXG4gKiBSZXRyaWV2ZXMgdGhlIHNlbGVjdGVkIHZhbHVlIG9mIHRoZSBncm91cFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gTUxSYWRpb0dyb3VwX2dldCgpIHtcbiAgICB2YXIgY2hlY2tlZCA9IF8uZmluZCh0aGlzLl9yYWRpb0xpc3QsIGZ1bmN0aW9uKHJhZGlvKSB7XG4gICAgICAgIHJldHVybiByYWRpby5jaGVja2VkO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNoZWNrZWQgJiYgY2hlY2tlZC52YWx1ZSB8fCB1bmRlZmluZWQ7XG59XG5cblxuLyoqXG4gKiBEZWxldGVkIGdyb3VwIHZhbHVlXG4gKiBEZWxldGVzIHRoZSB2YWx1ZSBvZiB0aGUgZ3JvdXAsIHNldHRpbmcgaXQgdG8gZW1wdHlcbiAqL1xuZnVuY3Rpb24gTUxSYWRpb0dyb3VwX2RlbCgpIHtcbiAgICB2YXIgb3B0aW9ucyA9IHRoaXMuX3JhZGlvTGlzdDtcbiAgICBpZiAob3B0aW9ucy5sZW5ndGgpXG4gICAgICAgIG9wdGlvbnMuZm9yRWFjaChmdW5jdGlvbihyYWRpbykge1xuICAgICAgICAgICAgcmFkaW8uY2hlY2tlZCA9IGZhbHNlO1xuICAgICAgICB9KTtcblxuICAgIGRpc3BhdGNoQ2hhbmdlTWVzc2FnZS5jYWxsKHRoaXMpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cblxuLyoqXG4gKiBNYW5hZ2UgcmFkaW8gY2hpbGRyZW4gY2xpY2tzXG4gKi9cbmZ1bmN0aW9uIG9uR3JvdXBDbGljayhldmVudFR5cGUsIGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnRhcmdldC50eXBlID09ICdyYWRpbycpXG4gICAgICAgIGRpc3BhdGNoQ2hhbmdlTWVzc2FnZS5jYWxsKHRoaXMpO1xufVxuXG4vLyBQb3N0IHRoZSBkYXRhIGNoYW5nZVxuZnVuY3Rpb24gZGlzcGF0Y2hDaGFuZ2VNZXNzYWdlKCkge1xuICAgIHRoaXMuZGF0YS5kaXNwYXRjaFNvdXJjZU1lc3NhZ2UoUkFESU9fQ0hBTkdFX01FU1NBR0UpO1xufVxuXG5cbi8vIFNldCByYWRpbyBidXR0b24gY2hpbGRyZW4gb24gbW9kZWwgY2hhbmdlXG5mdW5jdGlvbiBvbk9wdGlvbnNDaGFuZ2UocGF0aCwgZGF0YSkge1xuICAgIHRoaXMudGVtcGxhdGUucmVuZGVyKHtcbiAgICAgICAgcmFkaW9PcHRpb25zOiB0aGlzLm1vZGVsLmdldCgpLFxuICAgICAgICBlbGVtZW50TmFtZTogdGhpc1tFTEVNRU5UX05BTUVfUFJPUEVSVFldLFxuICAgICAgICBfcmVuZGVyT3B0aW9uczogdGhpcy5fcmVuZGVyT3B0aW9uc1xuICAgIH0pO1xuXG4gICAgdmFyIHJhZGlvRWxzID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKCdpbnB1dFt0eXBlPVwicmFkaW9cIl0nKVxuICAgICAgICAsIG9wdGlvbnMgPSBfLnRvQXJyYXkocmFkaW9FbHMpO1xuXG4gICAgdGhpcy5fcmFkaW9MaXN0Lmxlbmd0aCA9IDA7XG4gICAgdGhpcy5fcmFkaW9MaXN0LnNwbGljZS5hcHBseSh0aGlzLl9yYWRpb0xpc3QsIFswLCAwXS5jb25jYXQob3B0aW9ucykpO1xufVxuXG5cbmZ1bmN0aW9uIE1MUmFkaW9Hcm91cCRkZXN0cm95KCkge1xuICAgIGRlbGV0ZSB0aGlzLl9yYWRpb0xpc3Q7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBNTFNlbGVjdCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxTZWxlY3QnLCB7XG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogJ21sLXVpLXNlbGVjdCdcbiAgICB9LFxuICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBtb2RlbDoge1xuICAgICAgICBtZXNzYWdlczoge1xuICAgICAgICAgICAgJyoqJzogeyBzdWJzY3JpYmVyOiBvbk9wdGlvbnNDaGFuZ2UsIGNvbnRleHQ6ICdvd25lcicgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgICB0ZW1wbGF0ZTogJ3t7fiBpdC5zZWxlY3RPcHRpb25zIDpvcHRpb24gfX0gXFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ7ez0gb3B0aW9uLnZhbHVlIH19XCIge3s/IG9wdGlvbi5zZWxlY3RlZCB9fXNlbGVjdGVke3s/fX0+e3s9IG9wdGlvbi5sYWJlbCB9fTwvb3B0aW9uPiBcXFxuICAgICAgICAgICAgICAgICAgIHt7fn19J1xuICAgIH1cbn0pO1xuXG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxTZWxlY3QpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MU2VsZWN0O1xuXG5cbl8uZXh0ZW5kUHJvdG8oTUxTZWxlY3QsIHtcbiAgICBzZXRPcHRpb25zOiBNTFNlbGVjdCRzZXRPcHRpb25zLFxuICAgIGRpc2FibGU6IE1MU2VsZWN0JGRpc2FibGVcbn0pO1xuXG5cbmZ1bmN0aW9uIE1MU2VsZWN0JHNldE9wdGlvbnMob3B0aW9ucykge1xuICAgIC8vIFNldCBvcHRpb25zIHRlbXBvcmFyaWx5IGRpc2FibGVzIG1vZGVsIHN1YnNjcmlwdGlvbnMgKEFzIGEgd29ya2Fyb3VuZCBmb3IgcGVyZm9ybWFuY2UgaXNzdWVzIHJlbGF0aW5nIHRvIG1vZGVsIHVwZGF0ZXMgLyB0ZW1wbGF0ZSByZS1yZW5kZXJpbmcpXG4gICAgdmFyIG1vZGVsQ2hhbmdlTGlzdGVuZXIgPSB7IGNvbnRleHQ6IHRoaXMsIHN1YnNjcmliZXI6IG9uT3B0aW9uc0NoYW5nZSB9O1xuXG4gICAgdGhpcy5tb2RlbC5vZmYoJyoqJywgbW9kZWxDaGFuZ2VMaXN0ZW5lcik7XG4gICAgdGhpcy5tb2RlbC5zZXQob3B0aW9ucyk7XG4gICAgdGhpcy5tb2RlbC5vbignKionLCBtb2RlbENoYW5nZUxpc3RlbmVyKTtcblxuICAgIG9uT3B0aW9uc0NoYW5nZS5jYWxsKHRoaXMpO1xufVxuXG5cbmZ1bmN0aW9uIE1MU2VsZWN0JGRpc2FibGUoZGlzYWJsZSkge1xuICAgIHRoaXMuZWwuZGlzYWJsZWQgPSBkaXNhYmxlO1xufVxuXG5cbmZ1bmN0aW9uIG9uT3B0aW9uc0NoYW5nZShwYXRoLCBkYXRhKSB7XG4gICAgdGhpcy50ZW1wbGF0ZS5yZW5kZXIoeyBzZWxlY3RPcHRpb25zOiB0aGlzLm1vZGVsLmdldCgpIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIE1MU3VwZXJDb21ib1xuICogQSBjb21ibyBzZWxlY3QgbGlzdCB3aXRoIGludGVsbGlnZW50IHNjcm9sbGluZyBvZiBzdXBlciBsYXJnZSBsaXN0cy5cbiAqL1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgZG9UID0gcmVxdWlyZSgnZG90JylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvbG9nZ2VyJyk7XG5cbnZhciBDT01CT19PUEVOID0gJ21sLXVpLXN1cGVyY29tYm8tb3Blbic7XG52YXIgQ09NQk9fQ0hBTkdFX01FU1NBR0UgPSAnbWxzdXBlcmNvbWJvY2hhbmdlJztcblxudmFyIE9QVElPTlNfVEVNUExBVEUgPSAne3t+IGl0LmNvbWJvT3B0aW9ucyA6b3B0aW9uOmluZGV4IH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHt7PyBvcHRpb24uc2VsZWN0ZWR9fWNsYXNzPVwic2VsZWN0ZWRcIiB7ez99fWRhdGEtdmFsdWU9XCJ7ez0gaW5kZXggfX1cIj57ez0gb3B0aW9uLmxhYmVsIH19PC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7fn19JztcblxudmFyIE1BWF9SRU5ERVJFRCA9IDEwMDtcbnZhciBCVUZGRVIgPSAyNTtcbnZhciBERUZBVUxUX0VMRU1FTlRfSEVJR0hUID0gMjA7XG5cbnZhciBNTFN1cGVyQ29tYm8gPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MU3VwZXJDb21ibycsIHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgICAgICdtb3VzZWxlYXZlJzoge3N1YnNjcmliZXI6IG9uTW91c2VMZWF2ZSwgY29udGV4dDogJ293bmVyJ30sXG4gICAgICAgICAgICAnbW91c2VvdmVyJzoge3N1YnNjcmliZXI6IG9uTW91c2VPdmVyLCBjb250ZXh0OiAnb3duZXInfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBkYXRhOiB7XG4gICAgICAgIGdldDogTUxTdXBlckNvbWJvX2dldCxcbiAgICAgICAgc2V0OiBNTFN1cGVyQ29tYm9fc2V0LFxuICAgICAgICBkZWw6IE1MU3VwZXJDb21ib19kZWwsXG4gICAgICAgIHNwbGljZTogdW5kZWZpbmVkLFxuICAgICAgICBldmVudDogQ09NQk9fQ0hBTkdFX01FU1NBR0VcbiAgICB9LFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS1zdXBlcmNvbWJvJ1xuICAgIH0sXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgICAgdGVtcGxhdGU6ICc8aW5wdXQgbWwtYmluZD1cIltkYXRhLCBldmVudHNdOmlucHV0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgbWwtdWktaW5wdXRcIj5cXFxuICAgICAgICAgICAgICAgICAgIDxkaXYgbWwtYmluZD1cIltkb21dOmFkZEl0ZW1EaXZcIiBjbGFzcz1cIm1sLXVpLXN1cGVyY29tYm8tYWRkXCI+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIG1sLWJpbmQ9XCI6YWRkUHJvbXB0XCI+PC9zcGFuPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1sLWJpbmQ9XCJbZXZlbnRzLCBkb21dOmFkZEJ0blwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IG1sLXVpLWJ1dHRvblwiPkFkZDwvYnV0dG9uPlxcXG4gICAgICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICA8ZGl2IG1sLWJpbmQ9XCJbZG9tLCBldmVudHNdOmxpc3RcIiBjbGFzcz1cIm1sLXVpLXN1cGVyY29tYm8tZHJvcGRvd25cIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IG1sLWJpbmQ9XCJbZG9tXTpiZWZvcmVcIj48L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IG1sLWJpbmQ9XCJbdGVtcGxhdGUsIGRvbSwgZXZlbnRzXTpvcHRpb25zXCIgY2xhc3M9XCJtbC11aS1zdXBlcmNvbWJvLW9wdGlvbnNcIj48L2Rpdj5cXFxuICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IG1sLWJpbmQ9XCJbZG9tXTphZnRlclwiPjwvZGl2PlxcXG4gICAgICAgICAgICAgICAgICAgPC9kaXY+J1xuICAgIH0sXG4gICAgY29udGFpbmVyOiB1bmRlZmluZWRcbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MU3VwZXJDb21ibyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxTdXBlckNvbWJvO1xuXG4vKipcbiAqIFB1YmxpYyBBcGlcbiAqL1xuXy5leHRlbmRQcm90byhNTFN1cGVyQ29tYm8sIHtcbiAgICBpbml0OiBNTFN1cGVyQ29tYm8kaW5pdCxcbiAgICBzaG93T3B0aW9uczogTUxTdXBlckNvbWJvJHNob3dPcHRpb25zLFxuICAgIGhpZGVPcHRpb25zOiBNTFN1cGVyQ29tYm8kaGlkZU9wdGlvbnMsXG4gICAgdG9nZ2xlT3B0aW9uczogTUxTdXBlckNvbWJvJHRvZ2dsZU9wdGlvbnMsXG4gICAgc2V0T3B0aW9uczogTUxTdXBlckNvbWJvJHNldE9wdGlvbnMsXG4gICAgaW5pdE9wdGlvbnNVUkw6IE1MU3VwZXJDb21ibyRpbml0T3B0aW9uc1VSTCxcbiAgICBzZXRGaWx0ZXJlZE9wdGlvbnM6IE1MU3VwZXJDb21ibyRzZXRGaWx0ZXJlZE9wdGlvbnMsXG4gICAgdXBkYXRlOiBNTFN1cGVyQ29tYm8kdXBkYXRlLFxuICAgIHRvZ2dsZUFkZEJ1dHRvbjogTUxTdXBlckNvbWJvJHRvZ2dsZUFkZEJ1dHRvbixcbiAgICBzZXRBZGRJdGVtUHJvbXB0OiBNTFN1cGVyQ29tYm8kc2V0QWRkSXRlbVByb21wdCxcbiAgICBjbGVhckNvbWJvSW5wdXQ6IE1MU3VwZXJDb21ib19kZWxcbn0pO1xuXG5cbi8qKlxuICogQ29tcG9uZW50IGluc3RhbmNlIG1ldGhvZFxuICogSW5pdGlhbGlzZSB0aGUgY29tcG9uZW50LCB3YWl0IGZvciBjaGlsZHJlbmJvdW5kLCBzZXR1cCBlbXB0eSBvcHRpb25zIGFycmF5cy5cbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJGluaXQoKSB7XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICB0aGlzLm9uY2UoJ2NoaWxkcmVuYm91bmQnLCBvbkNoaWxkcmVuQm91bmQpO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgX29wdGlvbnNEYXRhOiBbXSxcbiAgICAgICAgX2ZpbHRlcmVkT3B0aW9uc0RhdGE6IFtdXG4gICAgfSwgXy5XUklUKTtcbn1cblxuLyoqXG4gKiBIYW5kbGVyIGZvciBpbml0IGNoaWxkcmVuYm91bmQgbGlzdGVuZXIuIFJlbmRlcnMgdGVtcGxhdGUuXG4gKi9cbmZ1bmN0aW9uIG9uQ2hpbGRyZW5Cb3VuZCgpIHtcbiAgICB0aGlzLnRlbXBsYXRlLnJlbmRlcigpLmJpbmRlcigpO1xuICAgIGNvbXBvbmVudFNldHVwLmNhbGwodGhpcyk7XG59XG5cblxuLyoqXG4gKiBEZWZpbmUgaW5zdGFuY2UgcHJvcGVydGllcywgZ2V0IHN1YmNvbXBvbmVudHMsIGNhbGwgc2V0dXAgc3ViLXRhc2tzXG4gKi9cbmZ1bmN0aW9uIGNvbXBvbmVudFNldHVwKCkge1xuICAgIHZhciBzY29wZSA9IHRoaXMuY29udGFpbmVyLnNjb3BlO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgX2NvbWJvSW5wdXQ6IHNjb3BlLmlucHV0LFxuICAgICAgICBfY29tYm9MaXN0OiBzY29wZS5saXN0LFxuICAgICAgICBfY29tYm9PcHRpb25zOiBzY29wZS5vcHRpb25zLFxuICAgICAgICBfY29tYm9CZWZvcmU6IHNjb3BlLmJlZm9yZSxcbiAgICAgICAgX2NvbWJvQWZ0ZXI6IHNjb3BlLmFmdGVyLFxuICAgICAgICBfY29tYm9BZGRJdGVtRGl2OiBzY29wZS5hZGRJdGVtRGl2LFxuICAgICAgICBfY29tYm9BZGRQcm9tcHQ6IHNjb3BlLmFkZFByb21wdCxcbiAgICAgICAgX2NvbWJvQWRkQnRuOiBzY29wZS5hZGRCdG4sXG4gICAgICAgIF9vcHRpb25UZW1wbGF0ZTogZG9ULmNvbXBpbGUoT1BUSU9OU19URU1QTEFURSlcbiAgICB9KTtcblxuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgIF9zdGFydEluZGV4OiAwLFxuICAgICAgICBfZW5kSW5kZXg6IE1BWF9SRU5ERVJFRCxcbiAgICAgICAgX2hpZGRlbjogZmFsc2UsXG4gICAgICAgIF9lbGVtZW50SGVpZ2h0OiBERUZBVUxUX0VMRU1FTlRfSEVJR0hULFxuICAgICAgICBfdG90YWw6IDAsXG4gICAgICAgIF9vcHRpb25zSGVpZ2h0OiAyMDAsXG4gICAgICAgIF9sYXN0U2Nyb2xsUG9zOiAwLFxuICAgICAgICBfY3VycmVudFZhbHVlOiBudWxsLFxuICAgICAgICBfc2VsZWN0ZWQ6IG51bGwsXG4gICAgICAgIF9pc0FkZEJ1dHRvblNob3duOiBmYWxzZVxuICAgIH0sIF8uV1JJVCk7XG5cbiAgICAvLyBDb21wb25lbnQgU2V0dXBcbiAgICB0aGlzLmRvbS5zZXRTdHlsZXMoeyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9KTtcbiAgICBzZXR1cENvbWJvTGlzdCh0aGlzLl9jb21ib0xpc3QsIHRoaXMuX2NvbWJvT3B0aW9ucywgdGhpcyk7XG4gICAgc2V0dXBDb21ib0lucHV0KHRoaXMuX2NvbWJvSW5wdXQsIHRoaXMpO1xuICAgIHNldHVwQ29tYm9CdG4odGhpcy5fY29tYm9BZGRCdG4sIHRoaXMpO1xuXG4gICAgdGhpcy5ldmVudHMub24oJ2tleWRvd24nLCB7IHN1YnNjcmliZXI6IGNoYW5nZVNlbGVjdGVkLCBjb250ZXh0OiB0aGlzIH0pO1xuICAgIC8vdGhpcy5ldmVudHMub24oJ21vdXNlbGVhdmUnLCB7IHN1YnNjcmliZXI6IE1MU3VwZXJDb21ibyRoaWRlT3B0aW9ucywgY29udGV4dDogdGhpcyB9KTtcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTaG93cyBvciBoaWRlcyBvcHRpb24gbGlzdC5cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHNob3cgdHJ1ZSB0byBzaG93LCBmYWxzZSB0byBoaWRlXG4gKi9cbmZ1bmN0aW9uIE1MU3VwZXJDb21ibyR0b2dnbGVPcHRpb25zKHNob3cpIHtcbiAgICB0aGlzLl9oaWRkZW4gPSAhc2hvdztcbiAgICB0aGlzLl9jb21ib0xpc3QuZG9tLnRvZ2dsZShzaG93KTtcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTaG93cyBvcHRpb25zIGxpc3RcbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJHNob3dPcHRpb25zKCkge1xuICAgIHRoaXMuX2hpZGRlbiA9IGZhbHNlO1xuICAgIHRoaXMuZWwuY2xhc3NMaXN0LmFkZChDT01CT19PUEVOKTtcbiAgICB0aGlzLl9jb21ib0xpc3QuZG9tLnRvZ2dsZSh0cnVlKTtcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBIaWRlcyBvcHRpb25zIGxpc3RcbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJGhpZGVPcHRpb25zKCkge1xuICAgIHRoaXMuX2hpZGRlbiA9IHRydWU7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKENPTUJPX09QRU4pO1xuICAgIHRoaXMuX2NvbWJvTGlzdC5kb20udG9nZ2xlKGZhbHNlKTtcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBIaWRlcyBhZGQgYnV0dG9uXG4gKi9cbmZ1bmN0aW9uIE1MU3VwZXJDb21ibyR0b2dnbGVBZGRCdXR0b24oc2hvdywgb3B0aW9ucykge1xuICAgIHRoaXMuX2NvbWJvQWRkSXRlbURpdi5kb20udG9nZ2xlKHNob3cpO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMucHJlc2VydmVTdGF0ZSkgdGhpcy5fX3Nob3dBZGRPbkNsaWNrID0gdGhpcy5faXNBZGRCdXR0b25TaG93bjtcbiAgICB0aGlzLl9pc0FkZEJ1dHRvblNob3duID0gc2hvdztcbn1cblxuXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm8kc2V0QWRkSXRlbVByb21wdChwcm9tcHQpIHtcbiAgICB0aGlzLl9hZGRJdGVtUHJvbXB0ID0gcHJvbXB0O1xuICAgIHRoaXMuX2NvbWJvQWRkUHJvbXB0LmVsLmlubmVySFRNTCA9IHByb21wdDtcbiAgICB0aGlzLnRvZ2dsZUFkZEJ1dHRvbihmYWxzZSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRoZSBvcHRpb25zIG9mIHRoZSBkcm9wZG93blxuICpcbiAqIEBwYXJhbSB7QXJyYXlbT2JqZWN0XX0gYXJyIHRoZSBvcHRpb25zIHRvIHNldCB3aXRoIGxhYmVsIGFuZCB2YWx1ZSBwYWlycy4gVmFsdWUgY2FuIGJlIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJHNldE9wdGlvbnMoYXJyKSB7XG4gICAgdGhpcy5fb3B0aW9uc0RhdGEgPSBhcnI7XG4gICAgdGhpcy5zZXRGaWx0ZXJlZE9wdGlvbnMoYXJyKTtcbn1cblxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIEluaXRpYWxpc2UgdGhlIHJlbW90ZSBvcHRpb25zIG9mIHRoZSBkcm9wZG93blxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIGluaXRpYWxpc2UuXG4gKi9cbmZ1bmN0aW9uIE1MU3VwZXJDb21ibyRpbml0T3B0aW9uc1VSTChvcHRpb25zKSB7XG4gICAgdGhpcy5fb3B0aW9uc1VSTCA9IG9wdGlvbnMudXJsO1xuICAgIHRoaXMuX2Zvcm1hdE9wdGlvbnNVUkwgPSBvcHRpb25zLmZvcm1hdE9wdGlvbnMgfHwgZnVuY3Rpb24oZSl7cmV0dXJuIGU7fTtcbn1cblxuXG4vKipcbiAqIFByaXZhdGUgbWV0aG9kXG4gKiBTZXRzIHRoZSBvcHRpb25zIG9mIHRoZSBkcm9wZG93biBiYXNlZCBvbiBhIHJlcXVlc3RcbiAqL1xuZnVuY3Rpb24gX2dldE9wdGlvbnNVUkwoY2IpIHtcbiAgICB2YXIgdXJsID0gdGhpcy5fb3B0aW9uc1VSTCxcbiAgICAgICAgcXVlcnlTdHJpbmcgPSB0aGlzLl9jb21ib0lucHV0LmRhdGEuZ2V0KCk7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGNiID0gY2IgfHwgXy5ub29wO1xuICAgIG1pbG8udXRpbC5yZXF1ZXN0LnBvc3QodXJsLCB7IG5hbWU6IHF1ZXJ5U3RyaW5nIH0sIGZ1bmN0aW9uIChlcnIsIHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignQ2FuIG5vdCBzZWFyY2ggZm9yIFwiJyArIHF1ZXJ5U3RyaW5nICsgJ1wiJyk7XG4gICAgICAgICAgICByZXR1cm4gY2IobmV3IEVycm9yKCdSZXF1ZXN0IGVycm9yJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IF8uanNvblBhcnNlKHJlc3BvbnNlKTtcbiAgICAgICAgaWYgKHJlc3BvbnNlRGF0YSkgY2IobnVsbCwgcmVzcG9uc2VEYXRhKTtcbiAgICAgICAgZWxzZSBjYihuZXcgRXJyb3IoJ0RhdGEgZXJyb3InKSk7XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBDb21wb25lbnQgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIHRoZSBmaWx0ZXJlZCBvcHRpb25zLCB3aGljaCBpcyBhIHN1YnNldCBvZiBub3JtYWwgb3B0aW9uc1xuICpcbiAqIEBwYXJhbSB7W3R5cGVdfSBhcnIgVGhlIG9wdGlvbnMgdG8gc2V0XG4gKi9cbmZ1bmN0aW9uIE1MU3VwZXJDb21ibyRzZXRGaWx0ZXJlZE9wdGlvbnMoYXJyKSB7XG4gICAgaWYgKCEgYXJyKSByZXR1cm4gbG9nZ2VyLmVycm9yKCdzZXRGaWx0ZXJlZE9wdGlvbnM6IHBhcmFtZXRlciBpcyB1bmRlZmluZWQnKTtcbiAgICB0aGlzLl9maWx0ZXJlZE9wdGlvbnNEYXRhID0gYXJyO1xuICAgIHRoaXMuX3RvdGFsID0gYXJyLmxlbmd0aDtcbiAgICB0aGlzLnVwZGF0ZSgpO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCBpbnN0YW5jZSBtZXRob2RcbiAqIFVwZGF0ZXMgdGhlIGxpc3QuIFRoaXMgaXMgdXNlZCBvbiBzY3JvbGwsIGFuZCBtYWtlcyB1c2Ugb2YgdGhlIGZpbHRlcmVkT3B0aW9ucyB0b1xuICogaW50ZWxsaWdlbnRseSBzaG93IGEgc3Vic2V0IG9mIHRoZSBmaWx0ZXJlZCBsaXN0IGF0IGEgdGltZS5cbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvJHVwZGF0ZSgpIHtcbiAgICB2YXIgd2FzSGlkZGVuID0gdGhpcy5faGlkZGVuO1xuXG4gICAgdmFyIGFyclRvU2hvdyA9IHRoaXMuX2ZpbHRlcmVkT3B0aW9uc0RhdGEuc2xpY2UodGhpcy5fc3RhcnRJbmRleCwgdGhpcy5fZW5kSW5kZXgpO1xuXG4gICAgdGhpcy5fY29tYm9PcHRpb25zLnRlbXBsYXRlLnJlbmRlcih7XG4gICAgICAgIGNvbWJvT3B0aW9uczogYXJyVG9TaG93XG4gICAgfSk7XG5cbiAgICB0aGlzLl9lbGVtZW50SGVpZ2h0ID0gdGhpcy5fZWxlbWVudEhlaWdodCB8fCBERUZBVUxUX0VMRU1FTlRfSEVJR0hUO1xuXG4gICAgaWYgKHdhc0hpZGRlbilcbiAgICAgICAgdGhpcy5oaWRlT3B0aW9ucygpO1xuXG4gICAgdmFyIGJlZm9yZUhlaWdodCA9IHRoaXMuX3N0YXJ0SW5kZXggKiB0aGlzLl9lbGVtZW50SGVpZ2h0O1xuICAgIHZhciBhZnRlckhlaWdodCA9ICh0aGlzLl90b3RhbCAtIHRoaXMuX2VuZEluZGV4KSAqIHRoaXMuX2VsZW1lbnRIZWlnaHQ7XG4gICAgdGhpcy5fY29tYm9CZWZvcmUuZWwuc3R5bGUuaGVpZ2h0ID0gYmVmb3JlSGVpZ2h0ICsgJ3B4JztcbiAgICB0aGlzLl9jb21ib0FmdGVyLmVsLnN0eWxlLmhlaWdodCA9IGFmdGVySGVpZ2h0ID4gMCA/IGFmdGVySGVpZ2h0ICsgJ3B4JyA6ICcwcHgnO1xufVxuXG4vKipcbiAqIFNldHVwIHRoZSBjb21ibyBsaXN0XG4gKlxuICogQHBhcmFtICB7Q29tcG9uZW50fSBsaXN0XG4gKiBAcGFyYW0gIHtBcnJheX0gb3B0aW9uc1xuICogQHBhcmFtICB7Q29tcG9uZW50fSBzZWxmXG4gKi9cbmZ1bmN0aW9uIHNldHVwQ29tYm9MaXN0KGxpc3QsIG9wdGlvbnMsIHNlbGYpIHtcbiAgICBzZWxmLnRvZ2dsZUFkZEJ1dHRvbihmYWxzZSk7XG4gICAgb3B0aW9ucy50ZW1wbGF0ZS5zZXQoT1BUSU9OU19URU1QTEFURSk7XG5cbiAgICBsaXN0LmRvbS5zZXRTdHlsZXMoe1xuICAgICAgICBvdmVyZmxvdzogJ3Njcm9sbCcsXG4gICAgICAgIGhlaWdodDogc2VsZi5fb3B0aW9uc0hlaWdodCArICdweCcsXG4gICAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICB6SW5kZXg6IDEwXG4gICAgICAgIC8vIHRvcDogeVBvcyArICdweCcsXG4gICAgICAgIC8vIGxlZnQ6IHhQb3MgKyAncHgnLFxuICAgIH0pO1xuXG4gICAgc2VsZi5oaWRlT3B0aW9ucygpO1xuICAgIGxpc3QuZXZlbnRzLm9uTWVzc2FnZXMoe1xuICAgICAgICAnY2xpY2snOiB7c3Vic2NyaWJlcjogb25MaXN0Q2xpY2ssIGNvbnRleHQ6IHNlbGZ9LFxuICAgICAgICAnc2Nyb2xsJzoge3N1YnNjcmliZXI6IG9uTGlzdFNjcm9sbCwgY29udGV4dDogc2VsZn1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBTZXR1cCB0aGUgaW5wdXQgY29tcG9uZW50XG4gKlxuICogQHBhcmFtICB7Q29tcG9uZW50fSBpbnB1dFxuICogQHBhcmFtICB7Q29tcG9uZW50fSBzZWxmXG4gKi9cbmZ1bmN0aW9uIHNldHVwQ29tYm9JbnB1dChpbnB1dCwgc2VsZikge1xuICAgIGlucHV0LmV2ZW50cy5vbmNlKCdmb2N1cycsIGZ1bmN0aW9uKCl7XG4gICAgICAgIGlucHV0LmRhdGEub24oJycsIHsgc3Vic2NyaWJlcjogb25EYXRhQ2hhbmdlLCBjb250ZXh0OiBzZWxmIH0pO1xuICAgICAgICBpbnB1dC5ldmVudHMub24oJ2NsaWNrJywge3N1YnNjcmliZXI6IG9uSW5wdXRDbGljaywgY29udGV4dDogc2VsZiB9KTtcbiAgICAgICAgaW5wdXQuZXZlbnRzLm9uKCdrZXlkb3duJywge3N1YnNjcmliZXI6IG9uRW50ZXJLZXksIGNvbnRleHQ6IHNlbGYgfSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogU2V0dXAgdGhlIGJ1dHRvblxuICogQHBhcmFtICB7Q29tcG9uZW50fSBidG5cbiAqIEBwYXJhbSAge0NvbXBvbmVudH0gc2VsZlxuICovXG5mdW5jdGlvbiBzZXR1cENvbWJvQnRuKGJ0biwgc2VsZikge1xuICAgIGJ0bi5ldmVudHMub24oJ2NsaWNrJywgeyBzdWJzY3JpYmVyOiBvbkFkZEJ0biwgY29udGV4dDogc2VsZiB9KTtcbn1cblxuXG4vKipcbiAqIEN1c3RvbSBkYXRhIGZhY2V0IGdldCBtZXRob2RcbiAqL1xuZnVuY3Rpb24gTUxTdXBlckNvbWJvX2dldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFZhbHVlO1xufVxuXG4vKipcbiAqIEN1c3RvbSBkYXRhIGZhY2V0IHNldCBtZXRob2RcbiAqIEBwYXJhbSB7VmFyaWFibGV9IG9ialxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm9fc2V0KG9iaikge1xuICAgIHRoaXMuX2N1cnJlbnRWYWx1ZSA9IG9iajtcbiAgICB0aGlzLl9jb21ib0lucHV0LmRhdGEuc2V0KG9iaiAmJiBvYmoubGFiZWwpO1xuICAgIF8uZGVmZXJNZXRob2QodGhpcywgJ2hpZGVPcHRpb25zJyk7XG59XG5cbi8qKlxuICogQ3VzdG9tIGRhdGEgZmFjZXQgZGVsIG1ldGhvZFxuICovXG5mdW5jdGlvbiBNTFN1cGVyQ29tYm9fZGVsKCkge1xuICAgIHRoaXMuX2N1cnJlbnRWYWx1ZSA9IG51bGw7XG4gICAgdGhpcy5fY29tYm9JbnB1dC5kYXRhLnNldCgnJyk7XG59XG5cblxuLyoqXG4gKiBJbnB1dCBkYXRhIGNoYW5nZSBoYW5kbGVyXG4gKiBXaGVuIHRoZSBpbnB1dCBkYXRhIGNoYW5nZXMsIHRoaXMgbWV0aG9kIGZpbHRlcnMgdGhlIG9wdGlvbnNEYXRhLCBhbmQgc2V0cyB0aGUgZmlyc3QgZWxlbWVudFxuICogdG8gYmUgc2VsZWN0ZWQuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1zZ1xuICogQHBhcmFtICB7T2JqZXh0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIG9uRGF0YUNoYW5nZShtc2csIGRhdGEpIHtcbiAgICB2YXIgdGV4dCA9IGRhdGEubmV3VmFsdWUgJiYgZGF0YS5uZXdWYWx1ZS50cmltKCk7XG4gICAgaWYgKHRoaXMuX29wdGlvbnNVUkwpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICBfZ2V0T3B0aW9uc1VSTC5jYWxsKHRoaXMsIGZ1bmN0aW9uKGVyciwgcmVzcG9uc2VEYXRhKXtcbiAgICAgICAgICAgIGlmIChlcnIgfHwgIXJlc3BvbnNlRGF0YSkgcmV0dXJuO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHJlc3BvbnNlRGF0YS5kYXRhLm1hcChzZWxmLl9mb3JtYXRPcHRpb25zVVJMKTtcbiAgICAgICAgICAgICAgICBzZWxmLnNldE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgX3VwZGF0ZU9wdGlvbnNBbmRBZGRCdXR0b24uY2FsbChzZWxmLCB0ZXh0LCBzZWxmLl9vcHRpb25zRGF0YSk7XG4gICAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0RhdGEgZXJyb3InLCBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGZpbHRlcmVkRGF0YSA9IF9maWx0ZXJEYXRhLmNhbGwodGhpcywgdGV4dCk7XG4gICAgICAgIF91cGRhdGVPcHRpb25zQW5kQWRkQnV0dG9uLmNhbGwodGhpcywgdGV4dCwgZmlsdGVyZWREYXRhKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gX2ZpbHRlckRhdGEodGV4dCkge1xuICAgIHJldHVybiB0aGlzLl9vcHRpb25zRGF0YS5maWx0ZXIoZnVuY3Rpb24ob3B0aW9uKSB7XG4gICAgICAgIGRlbGV0ZSBvcHRpb24uc2VsZWN0ZWQ7XG4gICAgICAgIGlmIChvcHRpb24ubGFiZWwpIHtcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IG9wdGlvbi5sYWJlbC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgcmV0dXJuIGxhYmVsLnRyaW0oKS50b0xvd2VyQ2FzZSgpLmluZGV4T2YodGV4dC50b0xvd2VyQ2FzZSgpKSA9PSAwO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gX3VwZGF0ZU9wdGlvbnNBbmRBZGRCdXR0b24odGV4dCwgZmlsdGVyZWRBcnIpIHtcbiAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgdGhpcy50b2dnbGVBZGRCdXR0b24oZmFsc2UsIHsgcHJlc2VydmVTdGF0ZTogdHJ1ZSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmlsdGVyZWRBcnIubGVuZ3RoICYmIF8uZmluZChmaWx0ZXJlZEFyciwgaXNFeGFjdE1hdGNoKSkge1xuICAgICAgICAgICAgdGhpcy50b2dnbGVBZGRCdXR0b24oZmFsc2UsIHsgcHJlc2VydmVTdGF0ZTogdHJ1ZSB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9hZGRJdGVtUHJvbXB0KSB7XG4gICAgICAgICAgICB0aGlzLnRvZ2dsZUFkZEJ1dHRvbih0aGlzLl9vcHRpb25zRGF0YS5sZW5ndGggPiAxIHx8IHRoaXMuX29wdGlvbnNVUkwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZpbHRlcmVkQXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5zaG93T3B0aW9ucygpO1xuICAgICAgICAgICAgZmlsdGVyZWRBcnJbMF0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWQgPSBmaWx0ZXJlZEFyclswXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGlkZU9wdGlvbnMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2V0RmlsdGVyZWRPcHRpb25zKGZpbHRlcmVkQXJyKTtcbiAgICB0aGlzLl9jb21ib0xpc3QuZWwuc2Nyb2xsVG9wID0gMDtcblxuICAgIGZ1bmN0aW9uIGlzRXhhY3RNYXRjaChpdGVtKSB7XG4gICAgICAgIHJldHVybiBpdGVtLmxhYmVsLnRvTG93ZXJDYXNlKCkgPT09IHRleHQudG9Mb3dlckNhc2UoKTtcbiAgICB9XG59XG5cbi8qKlxuICogQSBtYXAgb2Yga2V5Q29kZXMgdG8gZGlyZWN0aW9uc1xuICogQHR5cGUge09iamVjdH1cbiAqL1xudmFyIGRpcmVjdGlvbk1hcCA9IHsgJzQwJzogMSwgJzM4JzogLTEgfTtcblxuLyoqXG4gKiBMaXN0IGtleWRvd24gaGFuZGxlclxuICogQ2hhbmdlcyB0aGUgc2VsZWN0ZWQgbGlzdCBpdGVtIGJ5IGZpbmRpbmcgdGhlIGFkamFjZW50IGl0ZW0gYW5kIHNldHRpbmcgaXQgdG8gc2VsZWN0ZWQuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gY2hhbmdlU2VsZWN0ZWQodHlwZSwgZXZlbnQpIHtcbiAgICAvL1RPRE8gdGVzdCBtb2NoYVxuICAgIHZhciBkaXJlY3Rpb24gPSBkaXJlY3Rpb25NYXBbZXZlbnQua2V5Q29kZV07XG5cbiAgICBpZihkaXJlY3Rpb24pXG4gICAgICAgIF9jaGFuZ2VTZWxlY3RlZC5jYWxsKHRoaXMsIGRpcmVjdGlvbik7XG59XG5cbmZ1bmN0aW9uIF9jaGFuZ2VTZWxlY3RlZChkaXJlY3Rpb24pIHtcbiAgICAvLyBUT0RPOiByZWZhY3RvciBhbmQgdGlkeSB1cCwgbG9va3MgbGlrZSBzb21lIGNvZGUgZHVwbGljYXRpb24uXG4gICAgdmFyIHNlbGVjdGVkID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKCcuc2VsZWN0ZWQnKVswXVxuICAgICAgICAsIHNjcm9sbFBvcyA9IHRoaXMuX2NvbWJvTGlzdC5lbC5zY3JvbGxUb3BcbiAgICAgICAgLCBzZWxlY3RlZFBvcyA9IHNlbGVjdGVkID8gc2VsZWN0ZWQub2Zmc2V0VG9wIDogMFxuICAgICAgICAsIHJlbGF0aXZlUG9zID0gc2VsZWN0ZWRQb3MgLSBzY3JvbGxQb3M7XG5cbiAgICBpZiAoc2VsZWN0ZWQpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gX2dldERhdGFWYWx1ZUZyb21FbGVtZW50LmNhbGwodGhpcywgc2VsZWN0ZWQpXG4gICAgICAgICAgICAsIHRoaXNJdGVtID0gdGhpcy5fZmlsdGVyZWRPcHRpb25zRGF0YVtpbmRleF1cbiAgICAgICAgICAgICwgYWRqSXRlbSA9IHRoaXMuX2ZpbHRlcmVkT3B0aW9uc0RhdGFbaW5kZXggKyBkaXJlY3Rpb25dO1xuXG4gICAgICAgIGlmIChhZGpJdGVtKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpc0l0ZW0uc2VsZWN0ZWQ7XG4gICAgICAgICAgICBhZGpJdGVtLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3NlbGVjdGVkID0gYWRqSXRlbTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodGhpcy5fZmlsdGVyZWRPcHRpb25zRGF0YVswXSkge1xuICAgICAgICAgICAgdGhpcy5fZmlsdGVyZWRPcHRpb25zRGF0YVswXS5zZWxlY3RlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlbGF0aXZlUG9zID4gdGhpcy5fb3B0aW9uc0hlaWdodCAtIHRoaXMuX2VsZW1lbnRIZWlnaHQqMiAmJiBkaXJlY3Rpb24gPT09IDEpXG4gICAgICAgIHRoaXMuX2NvbWJvTGlzdC5lbC5zY3JvbGxUb3AgKz0gdGhpcy5fZWxlbWVudEhlaWdodCpkaXJlY3Rpb24qNTtcblxuICAgIGlmIChyZWxhdGl2ZVBvcyA8IHRoaXMuX2VsZW1lbnRIZWlnaHQgJiYgZGlyZWN0aW9uID09PSAtMSlcbiAgICAgICAgdGhpcy5fY29tYm9MaXN0LmVsLnNjcm9sbFRvcCArPSB0aGlzLl9lbGVtZW50SGVpZ2h0KmRpcmVjdGlvbio1O1xufVxuXG5cbi8qKlxuICogTW91c2Ugb3ZlciBoYW5kbGVyXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gb25Nb3VzZU92ZXIodHlwZSwgZXZlbnQpIHtcbiAgICB0aGlzLl9tb3VzZUlzT3ZlciA9IHRydWU7XG59XG5cblxuLyoqXG4gKiBNb3VzZSBsZWF2ZSBoYW5kbGVyXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gb25Nb3VzZUxlYXZlKHR5cGUsIGV2ZW50KSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuX21vdXNlSXNPdmVyID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuX21vdXNlT3V0VGltZXIpIGNsZWFySW50ZXJ2YWwodGhpcy5fbW91c2VPdXRUaW1lcik7XG4gICAgdGhpcy5fbW91c2VPdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgICAgaWYgKCFzZWxmLl9tb3VzZUlzT3ZlcilcbiAgICAgICAgICAgIF9vbk1vdXNlTGVhdmUuY2FsbChzZWxmKTtcbiAgICB9LCA3NTApO1xufVxuXG5mdW5jdGlvbiBfb25Nb3VzZUxlYXZlKCkge1xuICAgIHRoaXMuaGlkZU9wdGlvbnMoKTtcbiAgICB0aGlzLnRvZ2dsZUFkZEJ1dHRvbihmYWxzZSwgeyBwcmVzZXJ2ZVN0YXRlOiB0cnVlIH0pO1xufVxuXG5cbi8qKlxuICogSW5wdXQgY2xpY2sgaGFuZGxlclxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKi9cbmZ1bmN0aW9uIG9uSW5wdXRDbGljayh0eXBlLCBldmVudCkge1xuICAgIHRoaXMuc2hvd09wdGlvbnMoKTtcbiAgICBpZiAodGhpcy5fX3Nob3dBZGRPbkNsaWNrKSB0aGlzLnRvZ2dsZUFkZEJ1dHRvbih0cnVlKTtcbn1cblxuXG4vKipcbiAqIEVudGVyIGtleSBoYW5kbGVyXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqL1xuZnVuY3Rpb24gb25FbnRlcktleSh0eXBlLCBldmVudCkge1xuICAgIGlmIChldmVudC5rZXlDb2RlID09IDEzKSB7XG4gICAgICAgIGlmICh0aGlzLl9zZWxlY3RlZClcbiAgICAgICAgICAgIF9zZXREYXRhLmNhbGwodGhpcyk7XG4gICAgfVxufVxuXG4vKipcbiAqIEFkZCBidXR0b24gaGFuZGxlclxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKi9cbmZ1bmN0aW9uIG9uQWRkQnRuICh0eXBlLCBldmVudCkge1xuICAgIHZhciBkYXRhID0geyBsYWJlbDogdGhpcy5fY29tYm9JbnB1dC5lbC52YWx1ZSB9O1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoJ2FkZGl0ZW0nLCBkYXRhKTtcbiAgICB0aGlzLmV2ZW50cy5wb3N0TWVzc2FnZSgnbWlsb19zdXBlcmNvbWJvYWRkaXRlbScsIGRhdGEpO1xuICAgIHRoaXMudG9nZ2xlQWRkQnV0dG9uKGZhbHNlLCB7IHByZXNlcnZlU3RhdGU6IHRydWUgfSk7XG5cbn1cblxuLyoqXG4gKiBMaXN0IGNsaWNrIGhhbmRsZXJcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5mdW5jdGlvbiBvbkxpc3RDbGljayAodHlwZSwgZXZlbnQpIHtcbiAgICB2YXIgaW5kZXggPSBfZ2V0RGF0YVZhbHVlRnJvbUVsZW1lbnQuY2FsbCh0aGlzLCBldmVudC50YXJnZXQpO1xuICAgIHZhciBkYXRhID0gdGhpcy5fZmlsdGVyZWRPcHRpb25zRGF0YVtpbmRleF07XG5cbiAgICB0aGlzLl9zZWxlY3RlZCA9IGRhdGE7XG4gICAgX3NldERhdGEuY2FsbCh0aGlzKTtcbiAgICB0aGlzLnVwZGF0ZSgpO1xufVxuXG5cbi8qKlxuICogTGlzdCBzY3JvbGwgaGFuZGxlclxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKi9cbmZ1bmN0aW9uIG9uTGlzdFNjcm9sbCAodHlwZSwgZXZlbnQpIHtcbiAgICB2YXIgc2Nyb2xsUG9zID0gZXZlbnQudGFyZ2V0LnNjcm9sbFRvcFxuICAgICAgICAsIGRpcmVjdGlvbiA9IHNjcm9sbFBvcyA+IHRoaXMuX2xhc3RTY3JvbGxQb3MgPyAnZG93bicgOiAndXAnXG4gICAgICAgICwgZmlyc3RDaGlsZCA9IHRoaXMuX2NvbWJvT3B0aW9ucy5lbC5sYXN0RWxlbWVudENoaWxkXG4gICAgICAgICwgbGFzdENoaWxkID0gdGhpcy5fY29tYm9PcHRpb25zLmVsLmZpcnN0RWxlbWVudENoaWxkXG4gICAgICAgICwgbGFzdEVsUG9zaXRpb24gPSBmaXJzdENoaWxkID8gZmlyc3RDaGlsZC5vZmZzZXRUb3AgOiAwXG4gICAgICAgICwgZmlyc3RFbFBvc2l0aW9uID0gbGFzdENoaWxkID8gbGFzdENoaWxkLm9mZnNldFRvcCA6IDBcbiAgICAgICAgLCBkaXN0RnJvbUxhc3RFbCA9IGxhc3RFbFBvc2l0aW9uIC0gc2Nyb2xsUG9zIC0gdGhpcy5fb3B0aW9uc0hlaWdodCArIHRoaXMuX2VsZW1lbnRIZWlnaHRcbiAgICAgICAgLCBkaXN0RnJvbUZpcnN0RWwgPSBzY3JvbGxQb3MgLSBmaXJzdEVsUG9zaXRpb25cbiAgICAgICAgLCBlbHNGcm9tU3RhcnQgPSBNYXRoLmZsb29yKGRpc3RGcm9tRmlyc3RFbCAvIHRoaXMuX2VsZW1lbnRIZWlnaHQpXG4gICAgICAgICwgZWxzVG9UaGVFbmQgPSBNYXRoLmZsb29yKGRpc3RGcm9tTGFzdEVsIC8gdGhpcy5fZWxlbWVudEhlaWdodClcbiAgICAgICAgLCB0b3RhbEVsZW1lbnRzQmVmb3JlID0gTWF0aC5mbG9vcihzY3JvbGxQb3MgLyB0aGlzLl9lbGVtZW50SGVpZ2h0KSAtIEJVRkZFUjtcblxuICAgIGlmICgoZGlyZWN0aW9uID09ICdkb3duJyAmJiBlbHNUb1RoZUVuZCA8IEJVRkZFUilcbiAgICAgICAgfHwgKGRpcmVjdGlvbiA9PSAndXAnICYmIGVsc0Zyb21TdGFydCA8IEJVRkZFUikpIHtcbiAgICAgICAgdGhpcy5fc3RhcnRJbmRleCA9IHRvdGFsRWxlbWVudHNCZWZvcmUgPiAwID8gdG90YWxFbGVtZW50c0JlZm9yZSA6IDA7XG4gICAgICAgIHRoaXMuX2VuZEluZGV4ID0gdG90YWxFbGVtZW50c0JlZm9yZSArIE1BWF9SRU5ERVJFRDtcbiAgICAgICAgdGhpcy5fZWxlbWVudEhlaWdodCA9IGZpcnN0Q2hpbGQuc3R5bGUuaGVpZ2h0O1xuICAgICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgIH1cbiAgICB0aGlzLl9sYXN0U2Nyb2xsUG9zID0gc2Nyb2xsUG9zO1xufVxuXG5cbi8qKlxuICogUHJpdmF0ZSBtZXRob2RcbiAqIFJldHJpZXZlcyB0aGUgZGF0YS12YWx1ZSBhdHRyaWJ1dGUgdmFsdWUgZnJvbSB0aGUgZWxlbWVudCBhbmQgcmV0dXJucyBpdCBhcyBhbiBpbmRleCBvZlxuICogdGhlIGZpbHRlcmVkT3B0aW9uc1xuICpcbiAqIEBwYXJhbSAge0VsZW1lbnR9IGVsXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIF9nZXREYXRhVmFsdWVGcm9tRWxlbWVudChlbCkge1xuICAgIHJldHVybiBOdW1iZXIoZWwuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJykpICsgdGhpcy5fc3RhcnRJbmRleDtcbn1cblxuLyoqXG4gKiBQcml2YXRlIG1ldGhvZFxuICogU2V0cyB0aGUgZGF0YSBvZiB0aGUgU3VwZXJDb21ibywgdGFraW5nIGNhcmUgdG8gcmVzZXQgc29tZSB0aGluZ3MgYW5kIHRlbXBvcmFyaWx5XG4gKiB1bnN1YnNjcmliZSBkYXRhIGxpc3RlbmVycy5cbiAqL1xuZnVuY3Rpb24gX3NldERhdGEoKSB7XG4gICAgZGVsZXRlIHRoaXMuX3NlbGVjdGVkLnNlbGVjdGVkO1xuICAgIHRoaXMuaGlkZU9wdGlvbnMoKTtcbiAgICB0aGlzLnRvZ2dsZUFkZEJ1dHRvbihmYWxzZSk7XG4gICAgdGhpcy5fY29tYm9JbnB1dC5kYXRhLm9mZignJywgeyBzdWJzY3JpYmVyOiBvbkRhdGFDaGFuZ2UsIGNvbnRleHQ6IHRoaXMgfSk7XG4gICAgLy9zdXBlcmNvbWJvIGxpc3RlbmVycyBvZmZcbiAgICB0aGlzLmRhdGEuc2V0KHRoaXMuX3NlbGVjdGVkKTtcbiAgICB0aGlzLmRhdGEuZGlzcGF0Y2hTb3VyY2VNZXNzYWdlKENPTUJPX0NIQU5HRV9NRVNTQUdFKTtcbiAgICB0aGlzLl9jb21ib0lucHV0LmRhdGEub24oJycsIHsgc3Vic2NyaWJlcjogb25EYXRhQ2hhbmdlLCBjb250ZXh0OiB0aGlzIH0pO1xuICAgIC8vc3VwZXJjb21ibyBsaXN0ZW5lcnMgb25cbiAgICB0aGlzLl9zZWxlY3RlZCA9IG51bGw7XG4gICAgdGhpcy5zZXRGaWx0ZXJlZE9wdGlvbnModGhpcy5fb3B0aW9uc0RhdGEpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jX3JlZ2lzdHJ5Jyk7XG5cblxudmFyIE1MVGV4dCA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxUZXh0Jywge1xuICAgIGRhdGE6IHVuZGVmaW5lZCxcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktdGV4dCdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTFRleHQpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MVGV4dDtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvbG9nZ2VyJyk7XG5cblxudmFyIE1MVGV4dGFyZWEgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MVGV4dGFyZWEnLCB7XG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS10ZXh0YXJlYSdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTFRleHRhcmVhKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTFRleHRhcmVhO1xuXG5cbnZhciBTQU1QTEVfQVVUT1JFU0laRV9URVhUID0gJ0xvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ZXIgYWRpcGlzY2luZyBlbGl0LCc7XG5cblxuXy5leHRlbmRQcm90byhNTFRleHRhcmVhLCB7XG4gICAgc3RhcnRBdXRvcmVzaXplOiBNTFRleHRhcmVhJHN0YXJ0QXV0b3Jlc2l6ZSxcbiAgICBzdG9wQXV0b3Jlc2l6ZTogTUxUZXh0YXJlYSRzdG9wQXV0b3Jlc2l6ZSxcbiAgICBpc0F1dG9yZXNpemVkOiBNTFRleHRhcmVhJGlzQXV0b3Jlc2l6ZWQsXG4gICAgZGlzYWJsZTogTUxUZXh0YXJlYSRkaXNhYmxlXG59KTtcblxuXG5mdW5jdGlvbiBNTFRleHRhcmVhJHN0YXJ0QXV0b3Jlc2l6ZShvcHRpb25zKSB7XG4gICAgaWYgKHRoaXMuX2F1dG9yZXNpemUpXG4gICAgICAgIHJldHVybiBsb2dnZXIud2FybignTUxUZXh0YXJlYSBzdGFydEF1dG9yZXNpemU6IGF1dG9yZXNpemUgaXMgYWxyZWFkeSBvbicpO1xuICAgIHRoaXMuX2F1dG9yZXNpemUgPSB0cnVlO1xuICAgIHRoaXMuX2F1dG9yZXNpemVPcHRpb25zID0gb3B0aW9ucztcblxuICAgIF9hZGp1c3RBcmVhSGVpZ2h0LmNhbGwodGhpcyk7XG4gICAgX21hbmFnZVN1YnNjcmlwdGlvbnMuY2FsbCh0aGlzLCAnb24nKTtcbn1cblxuXG5mdW5jdGlvbiBfbWFuYWdlU3Vic2NyaXB0aW9ucyhvbk9mZikge1xuICAgIHRoaXMuZXZlbnRzW29uT2ZmXSgnY2xpY2snLCB7IHN1YnNjcmliZXI6IF9hZGp1c3RBcmVhSGVpZ2h0LCBjb250ZXh0OiB0aGlzIH0pO1xuICAgIHRoaXMuZGF0YVtvbk9mZl0oJycsIHsgc3Vic2NyaWJlcjogX2FkanVzdEFyZWFIZWlnaHQsIGNvbnRleHQ6IHRoaXMgfSk7XG59XG5cblxuZnVuY3Rpb24gX2FkanVzdEFyZWFIZWlnaHQoKSB7XG4gICAgdGhpcy5lbC5zdHlsZS5oZWlnaHQgPSAwO1xuXG4gICAgdmFyIG5ld0hlaWdodCA9IHRoaXMuZWwuc2Nyb2xsSGVpZ2h0XG4gICAgICAgICwgbWluSGVpZ2h0ID0gdGhpcy5fYXV0b3Jlc2l6ZU9wdGlvbnMubWluSGVpZ2h0XG4gICAgICAgICwgbWF4SGVpZ2h0ID0gdGhpcy5fYXV0b3Jlc2l6ZU9wdGlvbnMubWF4SGVpZ2h0O1xuXG4gICAgbmV3SGVpZ2h0ID0gbmV3SGVpZ2h0ID49IG1heEhlaWdodFxuICAgICAgICAgICAgICAgID8gbWF4SGVpZ2h0XG4gICAgICAgICAgICAgICAgOiBuZXdIZWlnaHQgPD0gbWluSGVpZ2h0XG4gICAgICAgICAgICAgICAgPyBtaW5IZWlnaHRcbiAgICAgICAgICAgICAgICA6IG5ld0hlaWdodDtcblxuICAgIHRoaXMuZWwuc3R5bGUuaGVpZ2h0ID0gbmV3SGVpZ2h0ICsgJ3B4Jztcbn1cblxuXG5mdW5jdGlvbiBNTFRleHRhcmVhJHN0b3BBdXRvcmVzaXplKCkge1xuICAgIGlmICghIHRoaXMuX2F1dG9yZXNpemUpXG4gICAgICAgIHJldHVybiBsb2dnZXIud2FybignTUxUZXh0YXJlYSBzdG9wQXV0b3Jlc2l6ZTogYXV0b3Jlc2l6ZSBpcyBub3Qgb24nKTtcbiAgICB0aGlzLl9hdXRvcmVzaXplID0gZmFsc2U7XG4gICAgX21hbmFnZVN1YnNjcmlwdGlvbnMuY2FsbCh0aGlzLCAnb2ZmJyk7XG59XG5cblxuZnVuY3Rpb24gTUxUZXh0YXJlYSRpc0F1dG9yZXNpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl9hdXRvcmVzaXplO1xufVxuXG5cbmZ1bmN0aW9uIE1MVGV4dGFyZWEkZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fYXV0b3Jlc2l6ZSlcbiAgICAgICAgdGhpcy5zdG9wQXV0b3Jlc2l6ZSgpO1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5mdW5jdGlvbiBNTFRleHRhcmVhJGRpc2FibGUoZGlzYWJsZSkge1xuICAgIHRoaXMuZWwuZGlzYWJsZWQgPSBkaXNhYmxlO1xufSIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vY19yZWdpc3RyeScpO1xuXG5cbnZhciBNTFRpbWUgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MVGltZScsIHtcbiAgICBldmVudHM6IHVuZGVmaW5lZCxcbiAgICBkYXRhOiB7XG4gICAgICAgIGdldDogTUxUaW1lX2dldCxcbiAgICAgICAgc2V0OiBNTFRpbWVfc2V0LFxuICAgICAgICBkZWw6IE1MVGltZV9kZWwsXG4gICAgfSxcbiAgICBkb206IHtcbiAgICAgICAgY2xzOiAnbWwtdWktdGltZSdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTFRpbWUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MVGltZTtcblxuXG52YXIgVElNRV9SRUdFWCA9IC9eKFswLTldezEsMn0pKD86XFw6fFxcLikoWzAtOV17MSwyfSkkL1xuICAgICwgVElNRV9URU1QTEFURSA9ICdoaDptbSc7XG5cbmZ1bmN0aW9uIE1MVGltZV9nZXQoKSB7XG4gICAgdmFyIHRpbWVTdHIgPSB0aGlzLmVsLnZhbHVlO1xuICAgIHZhciBtYXRjaCA9IHRpbWVTdHIubWF0Y2goVElNRV9SRUdFWCk7XG4gICAgaWYgKCEgbWF0Y2gpIHJldHVybjtcbiAgICB2YXIgaG91cnMgPSBtYXRjaFsxXVxuICAgICAgICAsIG1pbnMgPSBtYXRjaFsyXTtcbiAgICBpZiAoaG91cnMgPiAyMyB8fCBtaW5zID4gNTkpIHJldHVybjtcbiAgICB2YXIgdGltZSA9IG5ldyBEYXRlKDE5NzAsIDAsIDEsIGhvdXJzLCBtaW5zKTtcblxuICAgIHJldHVybiBfLnRvRGF0ZSh0aW1lKTtcbn1cblxuXG5mdW5jdGlvbiBNTFRpbWVfc2V0KHZhbHVlKSB7XG4gICAgdmFyIHRpbWUgPSBfLnRvRGF0ZSh2YWx1ZSk7XG4gICAgaWYgKCEgdGltZSkge1xuICAgICAgICB0aGlzLmVsLnZhbHVlID0gJyc7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgdGltZVN0ciA9IFRJTUVfVEVNUExBVEVcbiAgICAgICAgICAgIC5yZXBsYWNlKCdoaCcsIHBhZCh0aW1lLmdldEhvdXJzKCkpKVxuICAgICAgICAgICAgLnJlcGxhY2UoJ21tJywgcGFkKHRpbWUuZ2V0TWludXRlcygpKSk7XG5cbiAgICB0aGlzLmVsLnZhbHVlID0gdGltZVN0cjtcbiAgICByZXR1cm4gdGltZVN0cjtcblxuICAgIGZ1bmN0aW9uIHBhZChuKSB7cmV0dXJuIG4gPCAxMCA/ICcwJyArIG4gOiBuOyB9XG59XG5cblxuZnVuY3Rpb24gTUxUaW1lX2RlbCgpIHtcbiAgICB0aGlzLmVsLnZhbHVlID0gJyc7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jX2NsYXNzJylcbiAgICAsIGNvbXBvbmVudHNSZWdpc3RyeSA9IHJlcXVpcmUoJy4uL2NfcmVnaXN0cnknKTtcblxuXG52YXIgTUxXcmFwcGVyID0gQ29tcG9uZW50LmNyZWF0ZUNvbXBvbmVudENsYXNzKCdNTFdyYXBwZXInLCB7XG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZGF0YTogdW5kZWZpbmVkLFxuICAgIGV2ZW50czogdW5kZWZpbmVkLFxuICAgIGRvbToge1xuICAgICAgICBjbHM6ICdtbC11aS13cmFwcGVyJ1xuICAgIH1cbn0pO1xuXG5jb21wb25lbnRzUmVnaXN0cnkuYWRkKE1MV3JhcHBlcik7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxXcmFwcGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi8uLi9jX3JlZ2lzdHJ5JylcbiAgICAsIGNvbXBvbmVudE5hbWUgPSByZXF1aXJlKCcuLi8uLi8uLi91dGlsL2NvbXBvbmVudF9uYW1lJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uLy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxudmFyIEFMRVJUX0NTU19DTEFTU0VTID0ge1xuICAgIHN1Y2Nlc3M6ICdhbGVydC1zdWNjZXNzJyxcbiAgICB3YXJuaW5nOiAnYWxlcnQtd2FybmluZycsXG4gICAgaW5mbzogJ2FsZXJ0LWluZm8nLFxuICAgIGRhbmdlcjogJ2FsZXJ0LWRhbmdlcicsXG4gICAgZml4ZWQ6ICdhbGVydC1maXhlZCdcbn07XG5cblxudmFyIE1MQWxlcnQgPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MQWxlcnQnLCB7XG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogWydtbC1icy1hbGVydCcsICdhbGVydCcsICdmYWRlJ10sXG4gICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgICAgICdyb2xlJzogJ2FsZXJ0JyxcbiAgICAgICAgICAgICdhcmlhLWhpZGRlbic6ICd0cnVlJ1xuICAgICAgICB9XG4gICAgfSxcbiAgICB0ZW1wbGF0ZToge1xuICAgICAgICB0ZW1wbGF0ZTogJ1xcXG4gICAgICAgICAgICB7ez8gaXQuY2xvc2UgfX1cXFxuICAgICAgICAgICAgICAgIDxidXR0b24gbWwtYmluZD1cIltldmVudHNdOmNsb3NlQnRuXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY2xvc2VcIiBkYXRhLWRpc21pc3M9XCJhbGVydFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZ0aW1lczs8L2J1dHRvbj5cXFxuICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAge3s9IGl0Lm1lc3NhZ2V9fSdcbiAgICB9XG59KTtcblxuY29tcG9uZW50c1JlZ2lzdHJ5LmFkZChNTEFsZXJ0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBNTEFsZXJ0O1xuXG5cbl8uZXh0ZW5kKE1MQWxlcnQsIHtcbiAgICBjcmVhdGVBbGVydDogTUxBbGVydCQkY3JlYXRlQWxlcnQsXG4gICAgb3BlbkFsZXJ0OiBNTEFsZXJ0JCRvcGVuQWxlcnQsXG59KTtcblxuXG5fLmV4dGVuZFByb3RvKE1MQWxlcnQsIHtcbiAgICBvcGVuQWxlcnQ6IE1MQWxlcnQkb3BlbkFsZXJ0LFxuICAgIGNsb3NlQWxlcnQ6IE1MQWxlcnQkY2xvc2VBbGVydFxufSk7XG5cblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgbmV3IGFsZXJ0IGluc3RhbmNlLiBUbyBjcmVhdGUgYW5kIG9wZW4gYXQgdGhlIHNhbWUgdGltZSB1c2UgW29wZW5BbGVydF0oI01MQWxlcnQkJG9wZW5BbGVydClcbiAqIGBvcHRpb25zYCBpcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAgICBtZXNzYWdlOiBzdHJpbmcgYWxlcnQgbWVzc2FnZVxuICogICAgICB0eXBlOiAgICBvcHRpb25hbCBzdHJpbmcgdGhlIHR5cGUgb2YgYWxlcnQgbWVzc2FnZSwgb25lIG9mIHN1Y2Nlc3MsIHdhcm5pbmcsIGluZm8sIGRhbmdlciwgZml4ZWRcbiAqICAgICAgICAgICAgICAgZGVmYXVsdCAnaW5mbydcbiAqICAgICAgY2xvc2U6ICAgb3B0aW9uYWwgZmFsc2UgdG8gcHJldmVudCB1c2VyIGZyb20gY2xvc2luZ1xuICogICAgICAgICAgICAgICBvciB0cnVlIChkZWZhdWx0KSB0byBlbmFibGUgY2xvc2luZyBhbmQgcmVuZGVyIGEgY2xvc2UgYnV0dG9uXG4gKiAgICAgIHRpbWVvdXQ6IG9wdGlvbmFsIHRpbWVyLCBpbiBtaWxsaXNlY29uZHMgdG8gYXV0b21hdGljYWxseSBjbG9zZSB0aGUgYWxlcnRcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBhbGVydCBjb25maWd1cmF0aW9uXG4gKi9cbmZ1bmN0aW9uIE1MQWxlcnQkJGNyZWF0ZUFsZXJ0KG9wdGlvbnMpIHtcbiAgICBjaGVjayhvcHRpb25zLCB7XG4gICAgICAgIG1lc3NhZ2U6IFN0cmluZyxcbiAgICAgICAgdHlwZTogTWF0Y2guT3B0aW9uYWwoU3RyaW5nKSxcbiAgICAgICAgY2xvc2U6IE1hdGNoLk9wdGlvbmFsKEJvb2xlYW4pLFxuICAgICAgICB0aW1lb3V0OiBNYXRjaC5PcHRpb25hbChOdW1iZXIpXG4gICAgfSk7XG5cbiAgICB2YXIgYWxlcnQgPSBNTEFsZXJ0LmNyZWF0ZU9uRWxlbWVudCgpO1xuXG4gICAgb3B0aW9ucyA9IF9wcmVwYXJlT3B0aW9ucyhvcHRpb25zKTtcblxuICAgIHZhciBhbGVydENscyA9IEFMRVJUX0NTU19DTEFTU0VTW29wdGlvbnMudHlwZV07XG4gICAgYWxlcnQuZG9tLmFkZENzc0NsYXNzZXMoYWxlcnRDbHMpO1xuXG4gICAgYWxlcnQuX2FsZXJ0ID0ge1xuICAgICAgICBvcHRpb25zOiBvcHRpb25zLFxuICAgICAgICB2aXNpYmxlOiBmYWxzZVxuICAgIH07XG5cbiAgICBhbGVydC50ZW1wbGF0ZS5yZW5kZXIob3B0aW9ucykuYmluZGVyKCk7XG5cbiAgICB2YXIgYWxlcnRTY29wZSA9IGFsZXJ0LmNvbnRhaW5lci5zY29wZTtcblxuICAgIGlmIChvcHRpb25zLmNsb3NlKVxuICAgICAgICBhbGVydFNjb3BlLmNsb3NlQnRuLmV2ZW50cy5vbignY2xpY2snLFxuICAgICAgICAgICAgeyBzdWJzY3JpYmVyOiBfb25DbG9zZUJ0bkNsaWNrLCBjb250ZXh0OiBhbGVydCB9KTtcblxuICAgIGlmIChvcHRpb25zLnRpbWVvdXQpXG4gICAgICAgIHZhciB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIGlmKGFsZXJ0Ll9hbGVydC52aXNpYmxlKVxuICAgICAgICAgICAgICAgIGFsZXJ0LmNsb3NlQWxlcnQoKTtcbiAgICAgICAgfSwgb3B0aW9ucy50aW1lb3V0KTtcblxuICAgIHJldHVybiBhbGVydDtcbn1cblxuXG4vKipcbiAqIENyZWF0ZSBhbmQgc2hvdyBhbGVydCBwb3B1cFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIG9iamVjdCB3aXRoIG1lc3NhZ2UsIHR5cGUsIGNsb3NlIGFuZCB0aW1lb3V0XG4gKiBAcmV0dXJuIHtNTEFsZXJ0fSB0aGUgYWxlcnQgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gTUxBbGVydCQkb3BlbkFsZXJ0KG9wdGlvbnMpIHtcbiAgICB2YXIgYWxlcnQgPSBNTEFsZXJ0LmNyZWF0ZUFsZXJ0KG9wdGlvbnMpO1xuICAgIGFsZXJ0Lm9wZW5BbGVydCgpO1xuICAgIHJldHVybiBhbGVydDtcbn1cblxuXG5mdW5jdGlvbiBfb25DbG9zZUJ0bkNsaWNrKHR5cGUsIGV2ZW50KSB7XG4gICAgdGhpcy5jbG9zZUFsZXJ0KCk7XG59XG5cblxuZnVuY3Rpb24gX3ByZXBhcmVPcHRpb25zKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gXy5jbG9uZShvcHRpb25zKTtcbiAgICBvcHRpb25zLmNsb3NlID0gdHlwZW9mIG9wdGlvbnMuY2xvc2UgPT0gJ3VuZGVmaW5lZCcgfHwgb3B0aW9ucy5jbG9zZSA9PT0gdHJ1ZTtcbiAgICBvcHRpb25zLnRpbWVvdXQgPSBNYXRoLmZsb29yKG9wdGlvbnMudGltZW91dCk7XG4gICAgb3B0aW9ucy50eXBlID0gb3B0aW9ucy50eXBlIHx8ICdpbmZvJztcblxuICAgIHJldHVybiBvcHRpb25zO1xufVxuXG5cbi8qKlxuICogT3BlbiB0aGUgYWxlcnRcbiAqL1xuZnVuY3Rpb24gTUxBbGVydCRvcGVuQWxlcnQoKSB7XG4gICAgX3RvZ2dsZUFsZXJ0LmNhbGwodGhpcywgdHJ1ZSk7XG59XG5cblxuLyoqXG4gKiBDbG9zZSB0aGUgYWxlcnRcbiAqL1xuZnVuY3Rpb24gTUxBbGVydCRjbG9zZUFsZXJ0KCkge1xuICAgIF90b2dnbGVBbGVydC5jYWxsKHRoaXMsIGZhbHNlKTtcbiAgICB0aGlzLmRlc3Ryb3koKTtcbn1cblxuXG5mdW5jdGlvbiBfdG9nZ2xlQWxlcnQoZG9TaG93KSB7XG4gICAgZG9TaG93ID0gdHlwZW9mIGRvU2hvdyA9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgID8gISB0aGlzLl9hbGVydC52aXNpYmxlXG4gICAgICAgICAgICAgICAgOiAhISBkb1Nob3c7XG5cbiAgICB2YXIgYWRkUmVtb3ZlID0gZG9TaG93ID8gJ2FkZCcgOiAncmVtb3ZlJ1xuICAgICAgICAsIGFwcGVuZFJlbW92ZSA9IGRvU2hvdyA/ICdhcHBlbmRDaGlsZCcgOiAncmVtb3ZlQ2hpbGQnO1xuXG4gICAgdGhpcy5fYWxlcnQudmlzaWJsZSA9IGRvU2hvdztcblxuICAgIGRvY3VtZW50LmJvZHlbYXBwZW5kUmVtb3ZlXSh0aGlzLmVsKTtcbiAgICB0aGlzLmRvbS50b2dnbGUoZG9TaG93KTtcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAhZG9TaG93KTtcbiAgICB0aGlzLmVsLmNsYXNzTGlzdFthZGRSZW1vdmVdKCdpbicpO1xuICAgIHRoaXMuZWxbZG9TaG93ID8gJ2ZvY3VzJyA6ICdibHVyJ10oKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uLy4uL2NfY2xhc3MnKVxuICAgICwgY29tcG9uZW50c1JlZ2lzdHJ5ID0gcmVxdWlyZSgnLi4vLi4vY19yZWdpc3RyeScpXG4gICAgLCBjb21wb25lbnROYW1lID0gcmVxdWlyZSgnLi4vLi4vLi4vdXRpbC9jb21wb25lbnRfbmFtZScpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi91dGlsL2xvZ2dlcicpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBERUZBVUxUX0JVVFRPTlMgPSBbIHsgdHlwZTogJ2RlZmF1bHQnLCBsYWJlbDogJ09LJywgcmVzdWx0OiAnT0snIH0gXTtcblxudmFyIENMT1NFX09QVElPTlMgPSBbJ2JhY2tkcm9wJywgJ2tleWJvYXJkJywgJ2J1dHRvbiddO1xuXG52YXIgQlVUVE9OX0NTU19DTEFTU0VTID0geyAvLyBUT0RPIC0gdXNlIGluIHRlbXBsYXRlXG4gICAgZGVmYXVsdDogJ2J0bi1kZWZhdWx0JyxcbiAgICBwcmltYXJ5OiAnYnRuLXByaW1hcnknLFxuICAgIHN1Y2Nlc3M6ICdidG4tc3VjY2VzcycsXG4gICAgaW5mbzogJ2J0bi1pbmZvJyxcbiAgICB3YXJuaW5nOiAnYnRuLXdhcm5pbmcnLFxuICAgIGRhbmdlcjogJ2J0bi1kYW5nZXInLFxuICAgIGxpbms6ICdidG4tbGluaydcbn07XG5cblxuLyoqXG4gKiBEaWFsb2cgY2xhc3MgdG8gc2hvdyBjdXN0b20gZGlhbG9nIGJveGVzIGJhc2VkIG9uIGNvbmZpZ3VyYXRpb24gLSBzZWUgW2NyZWF0ZURpYWxvZ10oI01MRGlhbG9nJCRjcmVhdGVEaWFsb2cpIG1ldGhvZC5cbiAqIE9ubHkgb25lIGRpYWxvZyBjYW4gYmUgb3BlbmVkIGF0IGEgdGltZSAtIHRyeWluZyB0byBvcGVuIGFub3RoZXIgd2lsbCBsb2cgZXJyb3IgdG8gY29uc29sZS4gQ3VycmVudGx5IG9wZW5lZCBkaWFsb2cgY2FuIGJlIHJldHJpZXZlZCB1c2luZyBbZ2V0Q3VycmVudERpYWxvZ10oI01MRGlhbG9nJCRnZXRDdXJyZW50RGlhbG9nKSBjbGFzcyBtZXRob2QuXG4gKi9cbnZhciBNTERpYWxvZyA9IENvbXBvbmVudC5jcmVhdGVDb21wb25lbnRDbGFzcygnTUxEaWFsb2cnLCB7XG4gICAgY29udGFpbmVyOiB1bmRlZmluZWQsXG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogWydtbC1icy1kaWFsb2cnLCAnbW9kYWwnLCAnZmFkZSddLFxuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICAncm9sZSc6ICdkaWFsb2cnLFxuICAgICAgICAgICAgJ2FyaWEtaGlkZGVuJzogJ3RydWUnXG4gICAgICAgIH1cbiAgICB9LFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICAgIHRlbXBsYXRlOiAnXFxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1kaWFsb2dcIj5cXFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XFxcbiAgICAgICAgICAgICAgICAgICAge3s/IGl0LnRpdGxlIH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7PyBpdC5jbG9zZS5idXR0b24gfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIG1sLWJpbmQ9XCJbZXZlbnRzXTpjbG9zZUJ0blwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCI+JnRpbWVzOzwvYnV0dG9uPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1vZGFsLXRpdGxlXCI+e3s9IGl0LnRpdGxlIH19PC9oND5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAgICAgICAgICB7ez8gaXQuaHRtbCB8fCBpdC50ZXh0IH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCIgbWwtYmluZD1cIltjb250YWluZXJdOmRpYWxvZ0JvZHlcIj5cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7PyBpdC5odG1sIH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3s9IGl0Lmh0bWwgfX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Pz99fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPnt7PSBpdC50ZXh0IH19PC9wPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAgICAgICAgICB7ez8gaXQuYnV0dG9ucyAmJiBpdC5idXR0b25zLmxlbmd0aCB9fVxcXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e34gaXQuYnV0dG9ucyA6YnRuIH19XFxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXt7PSBidG4udHlwZSB9fXt7PyBidG4uY2xzIH19IHt7PSBidG4uY2xzIH19e3s/fX1cIlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbC1iaW5kPVwiW2V2ZW50c106e3s9IGJ0bi5uYW1lIH19XCI+e3s9IGJ0bi5sYWJlbCB9fTwvYnV0dG9uPlxcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3t+fX1cXFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XFxcbiAgICAgICAgICAgICAgICAgICAge3s/fX1cXFxuICAgICAgICAgICAgICAgIDwvZGl2PlxcXG4gICAgICAgICAgICA8L2Rpdj4nXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxEaWFsb2cpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1MRGlhbG9nO1xuXG5cbl8uZXh0ZW5kKE1MRGlhbG9nLCB7XG4gICAgY3JlYXRlRGlhbG9nOiBNTERpYWxvZyQkY3JlYXRlRGlhbG9nLFxuICAgIG9wZW5EaWFsb2c6IE1MRGlhbG9nJCRvcGVuRGlhbG9nLFxuICAgIGdldE9wZW5lZERpYWxvZzogTUxEaWFsb2ckJGdldE9wZW5lZERpYWxvZ1xufSk7XG5cblxuXy5leHRlbmRQcm90byhNTERpYWxvZywge1xuICAgIG9wZW5EaWFsb2c6IE1MRGlhbG9nJG9wZW5EaWFsb2csXG4gICAgY2xvc2VEaWFsb2c6IE1MRGlhbG9nJGNsb3NlRGlhbG9nLFxuICAgIGRlc3Ryb3k6IE1MRGlhbG9nJGRlc3Ryb3lcbn0pO1xuXG5cbi8qKlxuICogQ3JlYXRlcyBhbmQgcmV0dXJucyBkaWFsb2cgaW5zdGFuY2UuIFRvIGNyZWF0ZSBhbmQgb3BlbiBhdCB0aGUgc2FtZSB0aW1lIFtvcGVuRGlhbG9nXSgjTUxEaWFsb2ckJG9wZW5EaWFsb2cpXG4gKiBgb3B0aW9uc2AgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICAgICB0aXRsZTogb3B0aW9uYWwgZGlhbG9nIHRpdGxlXG4gKiAgICAgaHRtbDogb3B0aW9uYWwgZGlhbG9nIHRleHQgYXMgaHRtbCAod2lsbCB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0ZXh0IGlmIGJvdGggdGV4dCBuZCBodG1sIGFyZSBwYXNzZWQpXG4gKiAgICAgICBvclxuICogICAgIHRleHQ6IG9wdGlvbmFsIGRpYWxvZyB0ZXh0XG4gKiAgICAgY2xvc2U6IG9wdGlvbmFsIGZhbHNlIHRvIHByZXZlbnQgYmFja2Ryb3AgYW5kIGVzYyBrZXkgZnJvbSBjbG9zaW5nIHRoZSBkaWFsb2cgYW5kIHJlbW92aW5nIGNsb3NlIGJ1dHRvbiBpbiB0b3AgcmlnaHQgY29ybmVyXG4gKiAgICAgICAgICAgIG9yIHRydWUgKGRlZmF1bHQpIHRvIGVuYWJsZSBhbGwgY2xvc2Ugb3B0aW9uc1xuICogICAgICAgICAgICBvciBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzXG4gKiAgICAgICAgIGJhY2tkcm9wOiBmYWxzZSBvciB0cnVlIChkZWZhdWx0KSwgY2xvc2UgZGlhbG9nIHdoZW4gYmFja2Ryb3AgY2xpY2tlZFxuICogICAgICAgICBrZXlib2FyZDogZmFsc2Ugb3IgdHJ1ZSAoZGVmYXVsdCksIGNsb3NlIGRpYWxvZyB3aGVuIGVzYyBrZXkgaXMgcHJlc3NlZFxuICogICAgICAgICBidXR0b246IGZhbHNlIG9yIHRydWUgKGRlZmF1bHQpLCBzaG93IGNsb3NlIGJ1dHRvbiBpbiB0aGUgaGVhZGVyICh3b24ndCBiZSBzaG93biBpZiB0aGVyZSBpcyBubyBoZWFkZXIgd2hlbiB0aXRsZSBpcyBub3QgcGFzc2VkKVxuICogICAgIGJ1dHRvbnM6IG9wdGlvbmFsIGFycmF5IG9mIGJ1dHRvbnMgY29uZmlndXJhdGlvbnMsIHdoZXJlIGVhY2ggYnV0dG9uIGNvbmZpZyBpcyBhbiBvYmplY3RcbiAqICAgICAgICAgbmFtZTogICBvcHRpb25hbCBuYW1lIG9mIGNvbXBvbmVudCwgc2hvdWxkIGJlIHVuaXF1ZSBhbmQgc2hvdWxkIG5vdCBiZSBgY2xvc2VCdG5gLCBpZiBub3QgcGFzc2VkIGEgdGltZXN0YW1wIGJhc2VkIG5hbWUgd2lsbCBiZSB1c2VkXG4gKiAgICAgICAgIHR5cGU6ICAgYnV0dG9uIHR5cGUsIHdpbGwgZGV0ZXJtaW5lIGJ1dHRvbiBDU1Mgc3R5bGUuIFBvc3NpYmxlIHR5cGVzIGFyZTogZGVmdWx0LCBwcmltYXJ5LCBzdWNjZXNzLCBpbmZvLCB3YXJuaW5nLCBkYW5nZXIsIGxpbmsgKG1hcCB0byByZWxhdGVkIGJvb3RzdHJhcCBidXR0b24gc3R5bGVzKVxuICogICAgICAgICBsYWJlbDogIGJ1dHRvbiBsYWJlbFxuICogICAgICAgICBjbG9zZTogIG9wdGlvbmFsIGZhbHNlIHRvIHByZXZlbnQgdGhpcyBidXR0b24gZnJvbSBjbG9zaW5nIGRpYWxvZ1xuICogICAgICAgICByZXN1bHQ6IHN0cmluZyB3aXRoIGRpYWxvZyBjbG9zZSByZXN1bHQgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byBkaWFsb2cgc3Vic2NyaWJlciBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyXG4gKiAgICAgICAgIGRhdGE6ICAgYW55IHZhbHVlL29iamVjdCBvciBmdW5jdGlvbiB0byBjcmVhdGUgZGF0YSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIGRpYWxvZyBzdWJzY3JpYmVyIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLlxuICogICAgICAgICAgICAgICAgIElmIGZ1bmN0aW9uIGlzIHBhc3NlZCBpdCB3aWxsIGJlIGNhbGxlZCB3aXRoIGRpYWxvZyBhcyBjb250ZXh0IGFuZCBidXR0b24gb3B0aW9ucyBhcyBwYXJhbWV0ZXIuXG4gKlxuICogICAgIElmIGB0aXRsZWAgaXMgbm90IHBhc3NlZCwgZGlhbG9nIHdpbGwgbm90IGhhdmUgdGl0bGUgc2VjdGlvbiAgIFxuICogICAgIElmIG5laXRoZXIgYHRleHRgIG5vciBgaHRtbGAgaXMgcGFzc2VkLCBkaWFsb2cgd2lsbCBub3QgaGF2ZSBib2R5IHNlY3Rpb24uXG4gKiAgICAgSWYgYGJ1dHRvbnNgIGFyZSBub3QgcGFzc2VkLCB0aGVyZSB3aWxsIG9ubHkgYmUgT0sgYnV0dG9uLlxuICpcbiAqIFdoZW4gZGlhbG9nIGlzIGNsb3NlZCwgdGhlIHN1YnNjcmliZXIgaXMgY2FsbGVkIHdpdGggcmVhdWx0IGFuZCBvcHRpb25hbCBkYXRhIGFzIGRlZmluZWQgaW4gYnV0dG9ucyBjb25maWd1cmF0aW9ucy5cbiAqIElmIGJhY2tkcm9wIGlzIGNsaWNrZWQgb3IgRVNDIGtleSBpcyBwcmVzc2VkIHRoZSByZXN1bHQgd2lsbCBiZSAnZGlzbWlzc2VkJ1xuICogSWYgY2xvc2UgYnV0dG9uIGluIHRoZSB0b3AgcmlnaHQgY29ybmVyIGlzIGNsaWNrZWQsIHRoZSByZXN1bHQgd2lsbCBiZSAnY2xvc2VkJyAoZGVmYXVsdCByZXN1bHQpXG4gKiBcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGRpYWxvZyBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbml0aWFsaXplIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhlIGRpYWxvZ1xuICovXG5mdW5jdGlvbiBNTERpYWxvZyQkY3JlYXRlRGlhbG9nKG9wdGlvbnMsIGluaXRpYWxpemUpIHtcbiAgICBjaGVjayhvcHRpb25zLCB7XG4gICAgICAgIHRpdGxlOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICBodG1sOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICB0ZXh0OiBNYXRjaC5PcHRpb25hbChTdHJpbmcpLFxuICAgICAgICBjbG9zZTogTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoQm9vbGVhbiwge1xuICAgICAgICAgICAgYmFja2Ryb3A6IE1hdGNoLk9wdGlvbmFsKEJvb2xlYW4pLFxuICAgICAgICAgICAga2V5Ym9hcmQ6IE1hdGNoLk9wdGlvbmFsKEJvb2xlYW4pLFxuICAgICAgICAgICAgYnV0dG9uOiBNYXRjaC5PcHRpb25hbChCb29sZWFuKVxuICAgICAgICB9KSksXG4gICAgICAgIGJ1dHRvbnM6IE1hdGNoLk9wdGlvbmFsKFsge1xuICAgICAgICAgICAgbmFtZTogTWF0Y2guT3B0aW9uYWwoU3RyaW5nKSxcbiAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcbiAgICAgICAgICAgIGxhYmVsOiBTdHJpbmcsXG4gICAgICAgICAgICBjbG9zZTogTWF0Y2guT3B0aW9uYWwoQm9vbGVhbiksXG4gICAgICAgICAgICByZXN1bHQ6IE1hdGNoLk9wdGlvbmFsKFN0cmluZyksXG4gICAgICAgICAgICBkYXRhOiBNYXRjaC5PcHRpb25hbChNYXRjaC5BbnkpLFxuICAgICAgICAgICAgY2xzOiBNYXRjaC5PcHRpb25hbChTdHJpbmcpXG4gICAgICAgIH0gXSlcbiAgICB9KTtcblxuICAgIHZhciBkaWFsb2cgPSBNTERpYWxvZy5jcmVhdGVPbkVsZW1lbnQoKTtcblxuICAgIG9wdGlvbnMgPSBfcHJlcGFyZU9wdGlvbnMob3B0aW9ucyk7XG4gICAgZGlhbG9nLl9kaWFsb2cgPSB7XG4gICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsXG4gICAgICAgIHZpc2libGU6IGZhbHNlXG4gICAgfTtcblxuICAgIGRpYWxvZy50ZW1wbGF0ZVxuICAgICAgICAucmVuZGVyKG9wdGlvbnMpXG4gICAgICAgIC5iaW5kZXIoKTtcblxuICAgIHZhciBkaWFsb2dTY29wZSA9IGRpYWxvZy5jb250YWluZXIuc2NvcGU7XG5cbiAgICBpZiAob3B0aW9ucy5jbG9zZS5iYWNrZHJvcClcbiAgICAgICAgZGlhbG9nLmV2ZW50cy5vbignY2xpY2snLFxuICAgICAgICAgICAgeyBzdWJzY3JpYmVyOiBfb25CYWNrZHJvcENsaWNrLCBjb250ZXh0OiBkaWFsb2cgfSk7XG5cbiAgICBpZiAob3B0aW9ucy50aXRsZSAmJiBvcHRpb25zLmNsb3NlLmJ1dHRvbilcbiAgICAgICAgZGlhbG9nU2NvcGUuY2xvc2VCdG4uZXZlbnRzLm9uKCdjbGljaycsXG4gICAgICAgICAgICB7IHN1YnNjcmliZXI6IF9vbkNsb3NlQnRuQ2xpY2ssIGNvbnRleHQ6IGRpYWxvZyB9KTtcblxuICAgIG9wdGlvbnMuYnV0dG9ucy5mb3JFYWNoKGZ1bmN0aW9uKGJ0bikge1xuICAgICAgICB2YXIgYnV0dG9uU3Vic2NyaWJlciA9IHtcbiAgICAgICAgICAgIHN1YnNjcmliZXI6IF8ucGFydGlhbChfZGlhbG9nQnV0dG9uQ2xpY2ssIGJ0biksXG4gICAgICAgICAgICBjb250ZXh0OiBkaWFsb2dcbiAgICAgICAgfTtcbiAgICAgICAgZGlhbG9nU2NvcGVbYnRuLm5hbWVdLmV2ZW50cy5vbignY2xpY2snLCBidXR0b25TdWJzY3JpYmVyKTtcbiAgICB9KTtcblxuICAgIGlmIChpbml0aWFsaXplKSBpbml0aWFsaXplKGRpYWxvZyk7XG4gICAgcmV0dXJuIGRpYWxvZztcbn1cblxuXG5mdW5jdGlvbiBfZGlhbG9nQnV0dG9uQ2xpY2soYnV0dG9uKSB7XG4gICAgaWYgKGJ1dHRvbi5jbG9zZSAhPT0gZmFsc2UpXG4gICAgICAgIF90b2dnbGVEaWFsb2cuY2FsbCh0aGlzLCBmYWxzZSk7XG5cbiAgICB2YXIgZGF0YSA9IF8ucmVzdWx0KGJ1dHRvbi5kYXRhLCB0aGlzLCBidXR0b24pO1xuICAgIF9kaXNwYXRjaFJlc3VsdC5jYWxsKHRoaXMsIGJ1dHRvbi5yZXN1bHQsIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIF9kaXNwYXRjaFJlc3VsdChyZXN1bHQsIGRhdGEpIHtcbiAgICB2YXIgc3Vic2NyaWJlciA9IHRoaXMuX2RpYWxvZy5zdWJzY3JpYmVyO1xuICAgIGlmICh0eXBlb2Ygc3Vic2NyaWJlciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICBzdWJzY3JpYmVyLmNhbGwodGhpcywgcmVzdWx0LCBkYXRhKTtcbiAgICBlbHNlXG4gICAgICAgIHN1YnNjcmliZXIuc3Vic2NyaWJlci5jYWxsKHN1YnNjcmliZXIuY29udGV4dCwgcmVzdWx0LCBkYXRhKTtcbn1cblxuXG5mdW5jdGlvbiBfb25CYWNrZHJvcENsaWNrKGV2ZW50VHlwZSwgZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudGFyZ2V0ID09IHRoaXMuZWwpXG4gICAgICAgIHRoaXMuY2xvc2VEaWFsb2coJ2Rpc21pc3NlZCcpO1xufVxuXG5cbmZ1bmN0aW9uIF9vbkNsb3NlQnRuQ2xpY2soKSB7XG4gICAgdGhpcy5jbG9zZURpYWxvZygnY2xvc2VkJyk7XG59XG5cblxuZnVuY3Rpb24gX29uS2V5RG93bihldmVudCkge1xuICAgIGlmIChvcGVuZWREaWFsb2dcbiAgICAgICAgICAgICYmIG9wZW5lZERpYWxvZy5fZGlhbG9nLm9wdGlvbnMuY2xvc2Uua2V5Ym9hcmRcbiAgICAgICAgICAgICYmIGV2ZW50LmtleUNvZGUgPT0gMjcpIC8vIGVzYyBrZXlcbiAgICAgICAgb3BlbmVkRGlhbG9nLmNsb3NlRGlhbG9nKCdkaXNtaXNzZWQnKTtcbn1cblxuXG5mdW5jdGlvbiBfcHJlcGFyZU9wdGlvbnMob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBfLmNsb25lKG9wdGlvbnMpO1xuICAgIG9wdGlvbnMuYnV0dG9ucyA9IF8uY2xvbmUob3B0aW9ucy5idXR0b25zIHx8IERFRkFVTFRfQlVUVE9OUyk7XG4gICAgb3B0aW9ucy5idXR0b25zLmZvckVhY2goZnVuY3Rpb24oYnRuKSB7XG4gICAgICAgIGJ0bi5uYW1lID0gYnRuLm5hbWUgfHwgY29tcG9uZW50TmFtZSgpO1xuICAgIH0pO1xuXG4gICAgb3B0aW9ucy5jbG9zZSA9IHR5cGVvZiBvcHRpb25zLmNsb3NlID09ICd1bmRlZmluZWQnIHx8IG9wdGlvbnMuY2xvc2UgPT09IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gXy5vYmplY3QoQ0xPU0VfT1BUSU9OUywgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIG9wdGlvbnMuY2xvc2UgPT0gJ29iamVjdCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF8ubWFwVG9PYmplY3QoQ0xPU0VfT1BUSU9OUyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24ob3B0KSB7IHJldHVybiBvcHRpb25zLmNsb3NlW29wdF0gIT09IGZhbHNlOyB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogXy5vYmplY3QoQ0xPU0VfT1BUSU9OUywgZmFsc2UpO1xuXG4gICAgcmV0dXJuIG9wdGlvbnM7XG59XG5cblxuLyoqXG4gKiBDcmVhdGUgYW5kIHNob3cgZGlhbG9nIHBvcHVwXG4gKiBcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIG9iamVjdCB3aXRoIHRpdGxlLCB0ZXh0IGFuZCBidXR0b25zLiBTZWUgW2NyZWF0ZURpYWxvZ10oI01MRGlhbG9nJCRjcmVhdGVEaWFsb2cpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IHN1YnNjcmliZXIgb3B0aW9uYWwgc3Vic2NyaWJlciBmdW5jdGlvbiBvciBvYmplY3QgdGhhdCBpcyBwYXNzZWQgcmVzdWx0IGFuZCBvcHRpb25hbCBkYXRhLiBVbmxlc3MgY29udGV4dCBpcyBkZWZpbmVkLCBkaWFsb2cgd2lsbCBiZSB0aGUgY29udGV4dC5cbiAqL1xuZnVuY3Rpb24gTUxEaWFsb2ckJG9wZW5EaWFsb2cob3B0aW9ucywgc3Vic2NyaWJlciwgaW5pdGlhbGl6ZSkge1xuICAgIHZhciBkaWFsb2cgPSBNTERpYWxvZy5jcmVhdGVEaWFsb2cob3B0aW9ucywgaW5pdGlhbGl6ZSk7XG4gICAgZGlhbG9nLm9wZW5EaWFsb2coc3Vic2NyaWJlcik7XG4gICAgcmV0dXJuIGRpYWxvZztcbn1cblxuXG5cbmZ1bmN0aW9uIF90b2dnbGVEaWFsb2coZG9TaG93KSB7XG4gICAgZG9TaG93ID0gdHlwZW9mIGRvU2hvdyA9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgID8gISB0aGlzLl9kaWFsb2cudmlzaWJsZVxuICAgICAgICAgICAgICAgIDogISEgZG9TaG93O1xuXG4gICAgdmFyIGFkZFJlbW92ZSA9IGRvU2hvdyA/ICdhZGQnIDogJ3JlbW92ZSdcbiAgICAgICAgLCBhcHBlbmRSZW1vdmUgPSBkb1Nob3cgPyAnYXBwZW5kQ2hpbGQnIDogJ3JlbW92ZUNoaWxkJztcblxuICAgIHRoaXMuX2RpYWxvZy52aXNpYmxlID0gZG9TaG93O1xuXG4gICAgaWYgKGRvU2hvdyAmJiAhIGRpYWxvZ3NJbml0aWFsaXplZClcbiAgICAgICAgX2luaXRpYWxpemVEaWFsb2dzKCk7XG5cbiAgICBkb2N1bWVudC5ib2R5W2FwcGVuZFJlbW92ZV0odGhpcy5lbCk7XG4gICAgaWYgKGJhY2tkcm9wRWwpXG4gICAgICAgIGRvY3VtZW50LmJvZHlbYXBwZW5kUmVtb3ZlXShiYWNrZHJvcEVsKTtcbiAgICB0aGlzLmRvbS50b2dnbGUoZG9TaG93KTtcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAhZG9TaG93KTtcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdFthZGRSZW1vdmVdKCdtb2RhbC1vcGVuJyk7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3RbYWRkUmVtb3ZlXSgnaW4nKTtcblxuICAgIG9wZW5lZERpYWxvZyA9IGRvU2hvdyA/IHRoaXMgOiB1bmRlZmluZWQ7XG4gICAgdGhpcy5lbFtkb1Nob3cgPyAnZm9jdXMnIDogJ2JsdXInXSgpO1xufVxuXG5cbnZhciBkaWFsb2dzSW5pdGlhbGl6ZWQsIGJhY2tkcm9wRWw7XG5cbmZ1bmN0aW9uIF9pbml0aWFsaXplRGlhbG9ncygpIHtcbiAgICBiYWNrZHJvcEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgYmFja2Ryb3BFbC5jbGFzc05hbWUgPSAnbW9kYWwtYmFja2Ryb3AgZmFkZSBpbic7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIF9vbktleURvd24pO1xuICAgIGRpYWxvZ3NJbml0aWFsaXplZCA9IHRydWU7XG59XG5cblxudmFyIG9wZW5lZERpYWxvZztcblxuLyoqXG4gKiBPcGVucyBkaWFsb2cgaW5zdGFuY2UuXG4gKiBTdWJzY3JpYmVyIG9iamVjdCBzaG91bGQgaGF2ZSB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIHN1YnNjcmliZXIgZm9yIHRoZSBNZXNzZW5nZXIgKGFsdGhvdWdoIE1lc3NlbmdlciBpcyBub3QgdXNlZCkgLSBlaXRoZXIgZnVuY3Rpb24gb3Igb2JqZWN0IHdpdGggc3Vic2NyaWJlciBhbmQgY29udGV4dCBwcm9wZXJ0aWVzLlxuICogXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdH0gc3Vic2NyaWJlciBzdWJzY3JpYmVyIG9iamVjdFxuICovXG5mdW5jdGlvbiBNTERpYWxvZyRvcGVuRGlhbG9nKHN1YnNjcmliZXIpIHtcbiAgICBjaGVjayhzdWJzY3JpYmVyLCBNYXRjaC5PbmVPZihGdW5jdGlvbiwgeyBzdWJzY3JpYmVyOiBGdW5jdGlvbiwgY29udGV4dDogTWF0Y2guQW55IH0pKTtcblxuICAgIGlmIChvcGVuZWREaWFsb2cpXG4gICAgICAgIHJldHVybiBsb2dnZXIud2FybignTUxEaWFsb2cgb3BlbkRpYWxvZzogY2FuXFwndCBvcGVuIGRpYWxvZywgYW5vdGhlciBkaWFsb2cgaXMgYWxyZWFkeSBvcGVuJyk7XG5cbiAgICB0aGlzLl9kaWFsb2cuc3Vic2NyaWJlciA9IHN1YnNjcmliZXI7XG4gICAgX3RvZ2dsZURpYWxvZy5jYWxsKHRoaXMsIHRydWUpO1xufVxuXG5cbi8qKlxuICogQ2xvc2VzIGRpYWxvZyBpbnN0YW5jZSwgb3B0aW9uYWxseSBwYXNzaW5nIHJlc3VsdCBhbmQgZGF0YSB0byBkaWFsb2cgc3Vic2NyaWJlci5cbiAqIElmIG5vIHJlc3VsdCBpcyBwYXNzZWQsICdjbG9zZWQnIHdpbGwgYmUgcGFzc2VkIHRvIHN1YnNjcmliZXIuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlc3VsdCBkaWFsb2cgcmVzdWx0LCBwYXNzZWQgYXMgdGhlIGZpcnN0IHBhcmFtZXRlciB0byBzdWJjc3JpYmVyXG4gKiBAcGFyYW0ge0FueX0gZGF0YSBvcHRpb25hbCBkaWFsb2cgZGF0YSwgcGFzc2VkIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyIHRvIHN1YnNjcmliZXJcbiAqL1xuZnVuY3Rpb24gTUxEaWFsb2ckY2xvc2VEaWFsb2cocmVzdWx0LCBkYXRhKSB7XG4gICAgaWYgKCEgb3BlbmVkRGlhbG9nKVxuICAgICAgICByZXR1cm4gbG9nZ2VyLndhcm4oJ01MRGlhbG9nIGNsb3NlRGlhbG9nOiBjYW5cXCd0IGNsb3NlIGRpYWxvZywgbm8gZGlhbG9nIG9wZW4nKTtcblxuICAgIHJlc3VsdCA9IHJlc3VsdCB8fCAnY2xvc2VkJztcblxuICAgIF90b2dnbGVEaWFsb2cuY2FsbCh0aGlzLCBmYWxzZSk7XG4gICAgX2Rpc3BhdGNoUmVzdWx0LmNhbGwodGhpcywgcmVzdWx0LCBkYXRhKTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgY3VycmVudGx5IG9wZW5lZCBkaWFsb2dcbiAqXG4gKiBAcmV0dXJuIHtNTERpYWxvZ31cbiAqL1xuZnVuY3Rpb24gTUxEaWFsb2ckJGdldE9wZW5lZERpYWxvZygpIHtcbiAgICByZXR1cm4gb3BlbmVkRGlhbG9nO1xufVxuXG5cbmZ1bmN0aW9uIE1MRGlhbG9nJGRlc3Ryb3koKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIF9vbktleURvd24pO1xuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vLi4vY19jbGFzcycpXG4gICAgLCBjb21wb25lbnRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi8uLi9jX3JlZ2lzdHJ5JylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vLi4vdXRpbC9sb2dnZXInKVxuICAgICwgRE9NTGlzdGVuZXJzID0gcmVxdWlyZSgnLi4vLi4vLi4vdXRpbC9kb21fbGlzdGVuZXJzJyk7XG5cblxudmFyIFRPR0dMRV9DU1NfQ0xBU1MgPSAnZHJvcGRvd24tdG9nZ2xlJ1xuICAgICwgTUVOVV9DU1NfQ0xBU1MgPSAnZHJvcGRvd24tbWVudSc7XG5cblxudmFyIE1MRHJvcGRvd24gPSBDb21wb25lbnQuY3JlYXRlQ29tcG9uZW50Q2xhc3MoJ01MRHJvcGRvd24nLCB7XG4gICAgZXZlbnRzOiB1bmRlZmluZWQsXG4gICAgZG9tOiB7XG4gICAgICAgIGNsczogWydtbC1icy1kcm9wZG93bicsICdkcm9wZG93biddXG4gICAgfVxufSk7XG5cbmNvbXBvbmVudHNSZWdpc3RyeS5hZGQoTUxEcm9wZG93bik7XG5cbm1vZHVsZS5leHBvcnRzID0gTUxEcm9wZG93bjtcblxuXG5fLmV4dGVuZFByb3RvKE1MRHJvcGRvd24sIHtcbiAgICBzdGFydDogTUxEcm9wZG93biRzdGFydCxcbiAgICBkZXN0cm95OiBNTERyb3Bkb3duJGRlc3Ryb3ksXG4gICAgdG9nZ2xlTWVudTogTUxEcm9wZG93biR0b2dnbGVNZW51LFxuICAgIHNob3dNZW51OiBNTERyb3Bkb3duJHNob3dNZW51LFxuICAgIGhpZGVNZW51OiBNTERyb3Bkb3duJGhpZGVNZW51XG59KTtcblxuXG5mdW5jdGlvbiBNTERyb3Bkb3duJHN0YXJ0KCkge1xuICAgIHZhciB0b2dnbGVFbCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLicgKyBUT0dHTEVfQ1NTX0NMQVNTKVxuICAgICAgICAsIG1lbnVFbCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLicgKyBNRU5VX0NTU19DTEFTUyk7XG5cbiAgICBpZiAoISAodG9nZ2xlRWwgJiYgbWVudUVsKSlcbiAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcignTUxEcm9wZG93bjonLCBUT0dHTEVfQ1NTX0NMQVNTLCAnb3InLCBNRU5VX0NTU19DTEFTUywgJ2lzblxcJ3QgZm91bmQnKTtcblxuICAgIHZhciBkb2MgPSB3aW5kb3cuZG9jdW1lbnRcbiAgICAgICAgLCBjbGlja0hhbmRsZXIgPSB0aGlzLnRvZ2dsZU1lbnUuYmluZCh0aGlzLCB1bmRlZmluZWQpO1xuXG4gICAgdmFyIGxpc3RlbmVycyA9IG5ldyBET01MaXN0ZW5lcnM7XG4gICAgdGhpcy5fZHJvcGRvd24gPSB7XG4gICAgICAgIG1lbnU6IG1lbnVFbCxcbiAgICAgICAgdmlzaWJsZTogZmFsc2UsXG4gICAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgfTtcbiAgICB0aGlzLmhpZGVNZW51KCk7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgbGlzdGVuZXJzLmFkZCh0b2dnbGVFbCwgJ2NsaWNrJywgY2xpY2tIYW5kbGVyKTtcbiAgICAvL21heWJlIG9ubHkgYWRkIHRoaXMgZXZlbnRzIGlmIGlzIG9wZW4/XG4gICAgbGlzdGVuZXJzLmFkZChkb2MsICdtb3VzZW91dCcsIG9uRG9jT3V0KTtcbiAgICBsaXN0ZW5lcnMuYWRkKGRvYywgJ2NsaWNrJywgb25DbGljayk7XG5cblxuICAgIGZ1bmN0aW9uIG9uRG9jT3V0KGV2ZW50KSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSBldmVudC50YXJnZXRcbiAgICAgICAgICAgICwgcmVsYXRlZFRhcmdldCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXRcbiAgICAgICAgICAgICwgbGlzdGVuZXJzID0gc2VsZi5fZHJvcGRvd24ubGlzdGVuZXJzO1xuXG4gICAgICAgIGlmIChpc0lmcmFtZSh0YXJnZXQpKVxuICAgICAgICAgICAgbGlzdGVuZXJzLnJlbW92ZSh0YXJnZXQuY29udGVudFdpbmRvdy5kb2N1bWVudCwgJ2NsaWNrJywgb25DbGljayk7XG5cbiAgICAgICAgaWYgKGlzSWZyYW1lKHJlbGF0ZWRUYXJnZXQpKVxuICAgICAgICAgICAgbGlzdGVuZXJzLmFkZChyZWxhdGVkVGFyZ2V0LmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQsICdjbGljaycsIG9uQ2xpY2spO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uQ2xpY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFzZWxmLmVsLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpXG4gICAgICAgICAgICBzZWxmLmhpZGVNZW51KCk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIGlzSWZyYW1lKGVsKSB7XG4gICAgcmV0dXJuIGVsICYmIGVsLnRhZ05hbWUgPT0gJ0lGUkFNRSc7XG59XG5cblxuZnVuY3Rpb24gTUxEcm9wZG93biRkZXN0cm95KCkge1xuICAgIHRoaXMuX2Ryb3Bkb3duLmxpc3RlbmVycy5yZW1vdmVBbGwoKTtcbiAgICBkZWxldGUgdGhpcy5fZHJvcGRvd247XG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gTUxEcm9wZG93biRzaG93TWVudSgpIHtcbiAgICB0aGlzLnRvZ2dsZU1lbnUodHJ1ZSk7XG59XG5cblxuZnVuY3Rpb24gTUxEcm9wZG93biRoaWRlTWVudSgpIHtcbiAgICB0aGlzLnRvZ2dsZU1lbnUoZmFsc2UpO1xufVxuXG5cbmZ1bmN0aW9uIE1MRHJvcGRvd24kdG9nZ2xlTWVudShkb1Nob3cpIHtcbiAgICBkb1Nob3cgPSB0eXBlb2YgZG9TaG93ID09ICd1bmRlZmluZWQnXG4gICAgICAgICAgICAgICAgPyAhIHRoaXMuX2Ryb3Bkb3duLnZpc2libGVcbiAgICAgICAgICAgICAgICA6ICEhIGRvU2hvdztcblxuICAgIHRoaXMuX2Ryb3Bkb3duLnZpc2libGUgPSBkb1Nob3c7XG5cbiAgICB2YXIgbWVudSA9IHRoaXMuX2Ryb3Bkb3duLm1lbnU7XG4gICAgbWVudS5zdHlsZS5kaXNwbGF5ID0gZG9TaG93XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAnYmxvY2snXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnbm9uZSc7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxuLy8gPGEgbmFtZT1cImNvbmZpZ1wiPjwvYT5cbi8vIG1pbG8uY29uZmlnXG4vLyAtLS0tLS0tLS0tLVxuXG4vLyBJdCBpcyB0aGUgZnVuY3Rpb24gdGhhdCBhbGxvd3MgdG8gY2hhbmdlIG1pbG8gY29uZmlndXJhdGlvbnMgYW5kIGFsc29cbi8vIGFjY2VzcyB0aGVtIG9uIGNvbmZpZydzIHByb3BlcnRpZXMuXG5cbi8vIGBgYGphdmFzY3JpcHRcbi8vIG1pbG8uY29uZmlnKHtcbi8vICAgICBhdHRyczoge1xuLy8gICAgICAgICBiaW5kOiAnbWwtYmluZCcsXG4vLyAgICAgICAgIGxvYWQ6ICdtbC1sb2FkJ1xuLy8gICAgIH1cbi8vIH0pO1xuLy8gYGBgXG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgZG9UID0gcmVxdWlyZSgnZG90Jyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBjb25maWc7XG5cbmZ1bmN0aW9uIGNvbmZpZyhvcHRpb25zKSB7XG4gICAgXy5kZWVwRXh0ZW5kKGNvbmZpZywgb3B0aW9ucyk7XG59XG5cbmNvbmZpZyh7XG4gICAgYXR0cnM6IHtcbiAgICAgICAgYmluZDogJ21sLWJpbmQnLFxuICAgICAgICBsb2FkOiAnbWwtbG9hZCdcbiAgICB9LFxuICAgIGNvbXBvbmVudFJlZjogJ19fX21pbG9fY29tcG9uZW50JyxcbiAgICBjb21wb25lbnRQcmVmaXg6ICdtaWxvXycsXG4gICAgbWl4aW46IHtcbiAgICAgICAgaW5zdGFuY2VQcm9wZXJ0aWVzTWFwOiAnX19fbWl4aW5faW5zdGFuY2VzJ1xuICAgIH0sXG4gICAgdGVtcGxhdGU6IHtcbiAgICAgICAgY29tcGlsZTogZG9ULmNvbXBpbGVcbiAgICB9LFxuICAgIGRvbVN0b3JhZ2U6IHtcbiAgICAgICAgdHlwZVN1ZmZpeDogJzpfX19taWxvX2RhdGFfdHlwZScsXG4gICAgICAgIHByZWZpeFNlcGFyYXRvcjogJy8nLFxuICAgICAgICByb290OiAnJyxcbiAgICAgICAgbWVzc2FnZUtleTogJ19fX21pbG9fbWVzc2FnZS8nLFxuICAgICAgICBtZXNzYWdlVGltZXN0YW1wOiAnX19fbWlsb190aW1lc3RhbXAnLFxuICAgICAgICBxdW90YUV4Y2VlZGVkOiB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yOiB0cnVlLFxuICAgICAgICAgICAgbWVzc2FnZTogZmFsc2VcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZHJhZ0Ryb3A6IHtcbiAgICAgICAgZGF0YVR5cGVzOiB7XG4gICAgICAgICAgICBjb21wb25lbnQ6ICd4LWFwcGxpY2F0aW9uL21pbG8vY29tcG9uZW50JyxcbiAgICAgICAgICAgIGNvbXBvbmVudE1ldGFUZW1wbGF0ZTogJ3gtYXBwbGljYXRpb24vbWlsby9jb21wb25lbnQtbWV0YS8lY2xhc3MvJW5hbWUvJXBhcmFtcycsXG4gICAgICAgICAgICBjb21wb25lbnRNZXRhUmVnZXg6IC9eeFxcLWFwcGxpY2F0aW9uXFwvbWlsb1xcL2NvbXBvbmVudFxcLW1ldGFcXC8oW2EtejAtOV0rKVxcLyhbYS16MC05XSspXFwvKFthLXowLTldKikkLyxcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVxdWVzdDoge1xuICAgICAgICBqc29ucFRpbWVvdXQ6IDYwMDAwLFxuICAgICAgICBqc29ucENhbGxiYWNrUHJlZml4OiAnX19fbWlsb19jYWxsYmFja18nLFxuICAgICAgICBvcHRpb25zS2V5OiAnX19fbWlsb19vcHRpb25zJyxcbiAgICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgICAgIHRpbWVvdXQ6IDYwMDAwXG4gICAgICAgIH1cbiAgICB9LFxuICAgIHdlYnNvY2tldDoge1xuICAgICAgICBycGM6IHtcbiAgICAgICAgICAgIHRpbWVvdXQ6IDE1MDAwLFxuICAgICAgICAgICAgcmVzcG9uc2VQcmVmaXg6ICdyZXNwb25zZV8nXG4gICAgICAgIH1cbiAgICB9LFxuICAgIGNoZWNrOiB0cnVlLFxuICAgIGRlYnVnOiBmYWxzZVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIG1pbG9NYWlsID0gcmVxdWlyZSgnLi9zZXJ2aWNlcy9tYWlsJylcbiAgICAsIHJlcXVlc3QgPSByZXF1aXJlKCcuL3V0aWwvcmVxdWVzdCcpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuL3V0aWwvbG9nZ2VyJylcbiAgICAsIHV0aWxEb20gPSByZXF1aXJlKCcuL3V0aWwvZG9tJylcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJylcbiAgICAsIExvYWRBdHRyaWJ1dGUgPSByZXF1aXJlKCcuL2F0dHJpYnV0ZXMvYV9sb2FkJylcbiAgICAsIExvYWRlckVycm9yID0gcmVxdWlyZSgnLi91dGlsL2Vycm9yJykuTG9hZGVyO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbG9hZGVyO1xuXG4vKipcbiAqIGBtaWxvLmxvYWRlcmBcbiAqIFxuICogUmVjdXJzaXZlbHkgc2NhbnMgdGhlIGRvY3VtZW50IHRyZWUgaW5zaWRlIGByb290RWxgIChkb2N1bWVudC5ib2R5IGJ5IGRlZmF1bHQpIGxvb2tpbmcgZm9yIF9fbWwtbG9hZF9fIEBhdHRyaWJ1dGUuXG4gKiBPbmUgbGV2ZWwgbG9hZCBpcyBleGVjdXRlZC4gTm8gYWRkaXRpb25hbCBsb2FkZXIgZ2V0IGNhbGxlZCBvbiBpbnNpZGUgX19tbC1sb2FkX18gYXR0cmlidXRlcy4gXG4gKlxuICogUG9zc2libGUgdXNhZ2VzOlxuICogLSBtaWxvLmxvYWRlcihbbXlSb290RWwsXVtteVJlbW92ZUF0dHJpYnV0ZSxdbXlDYWxsYmFjaylcbiAqIFxuICogQHBhcmFtICB7RWxlbWVudH0gIHJvb3RFbCAgICAgICAgICBSb290IGVsZW1lbnQgaW5zaWRlIHdoaWNoIERPTSB3aWxsIGJlIHNjYW5uZWQgKGRvY3VtZW50LmJvZHkgYnkgZGVmYXVsdCkuXG4gKiBAcGFyYW0gIHtCb29sZWFufSAgcmVtb3ZlQXR0cmlidXRlIElmIHNldCB0byB0cnVlLCB0aGVuIHRoZSBfX21sLWxvYWRfXyBhdHRyaWJ1dGUgd2lsbCBiZSByZW1vdmVkIG9uY2UgbG9hZGVyIGhhcyBiZWVuIGV4ZWN1dGVkIChGYWxzZSBieSBkZWZhdWx0KS5cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFjayAgICAgICAgQ2FsbGJhY2sgdG8gY2FsbCBhZnRlciBhbGwgZWxlbWVudHMgZ2V0IGxvYWRlZCAoUmVxdWlyZWQpLlxuICovXG5mdW5jdGlvbiBsb2FkZXIocm9vdEVsLCByZW1vdmVBdHRyaWJ1dGUsIGNhbGxiYWNrKSB7XG4gICAgbWlsbyhmdW5jdGlvbigpIHtcbiAgICAgICAgX2xvYWRlcihyb290RWwsIHJlbW92ZUF0dHJpYnV0ZSwgY2FsbGJhY2spO1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9sb2FkZXIocm9vdEVsLCByZW1vdmVBdHRyaWJ1dGUsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiByb290RWwgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjYWxsYmFjayA9IHJvb3RFbDtcbiAgICAgICAgcm9vdEVsID0gdW5kZWZpbmVkO1xuICAgICAgICByZW1vdmVBdHRyaWJ1dGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlbW92ZUF0dHJpYnV0ZSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNhbGxiYWNrID0gcmVtb3ZlQXR0cmlidXRlO1xuICAgICAgICByZW1vdmVBdHRyaWJ1dGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICByb290RWwgPSByb290RWwgfHwgZG9jdW1lbnQuYm9keTtcblxuICAgIG1pbG9NYWlsLnBvc3RNZXNzYWdlKCdsb2FkZXInLCB7IHN0YXRlOiAnc3RhcnRlZCcgfSk7XG4gICAgX2xvYWRWaWV3c0luRWxlbWVudChyb290RWwsIHJlbW92ZUF0dHJpYnV0ZSwgZnVuY3Rpb24odmlld3MpIHtcbiAgICAgICAgbWlsb01haWwucG9zdE1lc3NhZ2UoJ2xvYWRlcicsIHsgXG4gICAgICAgICAgICBzdGF0ZTogJ2ZpbmlzaGVkJyxcbiAgICAgICAgICAgIHZpZXdzOiB2aWV3c1xuICAgICAgICB9KTtcbiAgICAgICAgY2FsbGJhY2sodmlld3MpO1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9sb2FkVmlld3NJbkVsZW1lbnQocm9vdEVsLCByZW1vdmVBdHRyaWJ1dGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGxvYWRFbGVtZW50cyA9IHJvb3RFbC5nZXRBdHRyaWJ1dGUoY29uZmlnLmF0dHJzLmxvYWQpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFtyb290RWxdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHJvb3RFbC5xdWVyeVNlbGVjdG9yQWxsKCdbJyArIGNvbmZpZy5hdHRycy5sb2FkICsgJ10nKTtcblxuICAgIHZhciB2aWV3cyA9IHt9XG4gICAgICAgICwgdG90YWxDb3VudCA9IGxvYWRFbGVtZW50cy5sZW5ndGhcbiAgICAgICAgLCBsb2FkZWRDb3VudCA9IDA7XG5cbiAgICBfLmZvckVhY2gobG9hZEVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgbG9hZFZpZXcoZWwsIHJlbW92ZUF0dHJpYnV0ZSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICB2aWV3c1tlbC5pZF0gPSBlcnIgfHwgZWw7XG4gICAgICAgICAgICBsb2FkZWRDb3VudCsrO1xuICAgICAgICAgICAgaWYgKGxvYWRlZENvdW50ID09IHRvdGFsQ291bnQpXG4gICAgICAgICAgICAgICAgY2FsbGJhY2sodmlld3MpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn07XG5cblxuZnVuY3Rpb24gbG9hZFZpZXcoZWwsIHJlbW92ZUF0dHJpYnV0ZSwgY2FsbGJhY2spIHtcbiAgICBpZiAodXRpbERvbS5jaGlsZHJlbihlbCkubGVuZ3RoKVxuICAgICAgICB0aHJvdyBuZXcgTG9hZGVyRXJyb3IoJ2NhblxcJ3QgbG9hZCBodG1sIGludG8gZWxlbWVudCB0aGF0IGlzIG5vdCBlbXB0eScpO1xuXG4gICAgdmFyIGF0dHIgPSBuZXcgTG9hZEF0dHJpYnV0ZShlbCk7XG5cbiAgICBhdHRyLnBhcnNlKCkudmFsaWRhdGUoKTtcblxuICAgIHJlcXVlc3QuZ2V0KGF0dHIubG9hZFVybCwgZnVuY3Rpb24oZXJyLCBodG1sKSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGVyci5tZXNzYWdlID0gZXJyLm1lc3NhZ2UgfHwgJ2NhblxcJ3QgbG9hZCBmaWxlICcgKyBhdHRyLmxvYWRVcmw7XG4gICAgICAgICAgICAvLyBsb2dnZXIuZXJyb3IoZXJyLm1lc3NhZ2UpO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIGlmIChyZW1vdmVBdHRyaWJ1dGUpIExvYWRBdHRyaWJ1dGUucmVtb3ZlKGVsKTtcbiAgICAgICAgY2FsbGJhY2sobnVsbCk7XG4gICAgfSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNaXhpbiA9IHJlcXVpcmUoJy4uL2Fic3RyYWN0L21peGluJylcbiAgICAvLyAsIE1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuL21lc3NhZ2Vfc291cmNlJylcbiAgICAsIE1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuL21fc291cmNlJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2hcbiAgICAsIE1lc3NlbmdlckVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLk1lc3NlbmdlcjtcblxuXG4vKipcbiAqIGBtaWxvLk1lc3NlbmdlcmBcbiAqIEEgZ2VuZXJpYyBNZXNzZW5nZXIgY2xhc3MgdGhhdCBpcyB1c2VkIGZvciBhbGwga2luZHMgb2YgbWVzc2FnaW5nIGluIG1pbG8uIEl0IGlzIHN1YmNsYXNzZWQgZnJvbSBbTWl4aW5dKC4uL2Fic3RyYWN0L21peGluLmpzLmh0bWwpIGFuZCBpdCBwcm94aWVzIGl0cyBtZXRob2RzIHRvIHRoZSBob3N0IG9iamVjdCBmb3IgY29udmVuaWVuY2UuXG4gKiBBbGwgZmFjZXRzIGFuZCBjb21wb25lbnRzIGhhdmUgbWVzc2VuZ2VyIGF0dGFjaGVkIHRvIHRoZW0uIE1lc3NlbmdlciBjbGFzcyBpbnRlcm9wZXJhdGVzIHdpdGggW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgY2xhc3MgdGhhdCBjb25uZWN0cyB0aGUgbWVzc2VuZ2VyIHRvIHNvbWUgZXh0ZXJuYWwgc291cmNlIG9mIG1lc3NhZ2VzIChlLmcuLCBET00gZXZlbnRzKSBhbmQgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSBjbGFzcyB0aGF0IGFsbG93cyB0byBkZWZpbmUgaGlnaGVyIGxldmVsIG1lc3NhZ2VzIHRoYW4gbWVzc2FnZXMgdGhhdCBleGlzdCBvbiB0aGUgc291cmNlLlxuICogTWVzc2VuZ2VyIGNsYXNzIGlzIHVzZWQgaW50ZXJuYWxseSBpbiBtaWxvIGFuZCBjYW4gYmUgdXNlZCB0b2dldGhlciB3aXRoIGFueSBvYmplY3RzL2NsYXNzZXMgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICogbWlsbyBhbHNvIGRlZmluZXMgYSBnbG9iYWwgbWVzc2VuZ2VyIFttaWxvLm1haWxdKC4uL21haWwvaW5kZXguanMuaHRtbCkgdGhhdCBkaXNwYXRjaGVzIGBkb21yZWFkeWAgZXZlbnQgYW5kIGNhbiBiZSB1c2VkIGZvciBhbnkgYXBwbGljYXRpb24gd2lkZSBtZXNzYWdpbmcuXG4gKiBUbyBpbml0aWFsaXplIHlvdXIgYXBwIGFmdGVyIERPTSBpcyByZWFkeSB1c2U6XG4gKiBgYGBcbiAqIG1pbG8ubWFpbC5vbignZG9tcmVhZHknLCBmdW5jdGlvbigpIHtcbiAqICAgICAvLyBhcHBsaWNhdGlvbiBzdGFydHNcbiAqIH0pO1xuICogYGBgXG4gKiBvciB0aGUgZm9sbG93aW5nIHNob3J0ZXIgZm9ybSBvZiB0aGUgc2FtZTpcbiAqIGBgYFxuICogbWlsbyhmdW5jdGlvbigpIHtcbiAqICAgICAvLyBhcHBsaWNhdGlvbiBzdGFydHNcbiAqIH0pO1xuICogYGBgXG4gKi9cbnZhciBNZXNzZW5nZXIgPSBfLmNyZWF0ZVN1YmNsYXNzKE1peGluLCAnTWVzc2VuZ2VyJyk7XG5cbnZhciBtZXNzYWdlc1NwbGl0UmVnRXhwID0gTWVzc2VuZ2VyLm1lc3NhZ2VzU3BsaXRSZWdFeHAgPSAvXFxzKig/OlxcLHxcXHMpXFxzKi87XG5cblxuLyoqXG4gKiAjIyMjTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI2luaXQpXG4gKiAtIFtvbl0oI01lc3NlbmdlciRvbikgKGFsaWFzIC0gb25NZXNzYWdlLCBkZXByZWNhdGVkKVxuICogLSBbb2ZmXSgjTWVzc2VuZ2VyJG9mZikgKGFsaWFzIC0gb2ZmTWVzc2FnZSwgZGVwcmVjYXRlZClcbiAqIC0gW29uTWVzc2FnZXNdKCNvbk1lc3NhZ2VzKVxuICogLSBbb2ZmTWVzc2FnZXNdKCNvZmZNZXNzYWdlcylcbiAqIC0gW29uY2VdKCNvbmNlKVxuICogLSBbb25jZVN5bmNdKCNvbmNlU3luYylcbiAqIC0gW3Bvc3RNZXNzYWdlXSgjcG9zdE1lc3NhZ2UpXG4gKiAtIFtnZXRTdWJzY3JpYmVyc10oI2dldFN1YnNjcmliZXJzKVxuICpcbiAqIFwiUHJpdmF0ZVwiIG1ldGhvZHNcbiAqXG4gKiAtIFtfY2hvb3NlU3Vic2NyaWJlcnNIYXNoXSgjX2Nob29zZVN1YnNjcmliZXJzSGFzaClcbiAqIC0gW19yZWdpc3RlclN1YnNjcmliZXJdKCNfcmVnaXN0ZXJTdWJzY3JpYmVyKVxuICogLSBbX3JlbW92ZVN1YnNjcmliZXJdKCNfcmVtb3ZlU3Vic2NyaWJlcilcbiAqIC0gW19yZW1vdmVBbGxTdWJzY3JpYmVyc10oI19yZW1vdmVBbGxTdWJzY3JpYmVycylcbiAqIC0gW19jYWxsUGF0dGVyblN1YnNjcmliZXJzXSgjX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnMpXG4gKiAtIFtfY2FsbFN1YnNjcmliZXJzXSgjX2NhbGxTdWJzY3JpYmVycylcbiAqIC0gW19zZXRNZXNzYWdlU291cmNlXSgjX3NldE1lc3NhZ2VTb3VyY2UpXG4gKiAtIFtnZXRNZXNzYWdlU291cmNlXSgjZ2V0TWVzc2FnZVNvdXJjZSlcbiAqL1xuXy5leHRlbmRQcm90byhNZXNzZW5nZXIsIHtcbiAgICBpbml0OiBpbml0LCAvLyBjYWxsZWQgYnkgTWl4aW4gKHN1cGVyY2xhc3MpXG4gICAgZGVzdHJveTogTWVzc2VuZ2VyJGRlc3Ryb3ksXG4gICAgb246IE1lc3NlbmdlciRvbixcbiAgICBvbmNlOiBNZXNzZW5nZXIkb25jZSxcbiAgICBvbmNlU3luYzogTWVzc2VuZ2VyJG9uY2VTeW5jLFxuICAgIG9uU3luYzogTWVzc2VuZ2VyJG9uU3luYyxcbiAgICBvbkFzeW5jOiBNZXNzZW5nZXIkb25Bc3luYyxcbiAgICBvbk1lc3NhZ2U6IE1lc3NlbmdlciRvbiwgLy8gZGVwcmVjYXRlZFxuICAgIG9mZjogTWVzc2VuZ2VyJG9mZixcbiAgICBvZmZNZXNzYWdlOiBNZXNzZW5nZXIkb2ZmLCAvLyBkZXByZWNhdGVkXG4gICAgb25NZXNzYWdlczogb25NZXNzYWdlcyxcbiAgICBvZmZNZXNzYWdlczogb2ZmTWVzc2FnZXMsXG4gICAgb2ZmQWxsOiBNZXNzZW5nZXIkb2ZmQWxsLFxuICAgIHBvc3RNZXNzYWdlOiBwb3N0TWVzc2FnZSxcbiAgICBwb3N0TWVzc2FnZVN5bmM6IHBvc3RNZXNzYWdlU3luYyxcbiAgICBnZXRTdWJzY3JpYmVyczogZ2V0U3Vic2NyaWJlcnMsXG4gICAgZ2V0TWVzc2FnZVNvdXJjZTogZ2V0TWVzc2FnZVNvdXJjZSxcbiAgICBfY2hvb3NlU3Vic2NyaWJlcnNIYXNoOiBfY2hvb3NlU3Vic2NyaWJlcnNIYXNoLFxuICAgIF9yZWdpc3RlclN1YnNjcmliZXI6IF9yZWdpc3RlclN1YnNjcmliZXIsXG4gICAgX3JlbW92ZVN1YnNjcmliZXI6IF9yZW1vdmVTdWJzY3JpYmVyLFxuICAgIF9yZW1vdmVBbGxTdWJzY3JpYmVyczogX3JlbW92ZUFsbFN1YnNjcmliZXJzLFxuICAgIF9jYWxsUGF0dGVyblN1YnNjcmliZXJzOiBfY2FsbFBhdHRlcm5TdWJzY3JpYmVycyxcbiAgICBfY2FsbFN1YnNjcmliZXJzOiBfY2FsbFN1YnNjcmliZXJzLFxuICAgIF9jYWxsU3Vic2NyaWJlcjogX2NhbGxTdWJzY3JpYmVyLFxuICAgIF9zZXRNZXNzYWdlU291cmNlOiBfc2V0TWVzc2FnZVNvdXJjZVxufSk7XG5cblxuLyoqXG4gKiBBIGRlZmF1bHQgbWFwIG9mIHByb3h5IG1ldGhvZHMgdXNlZCBieSBDb21wb25lbnRGYWNldCBhbmQgQ29tcG9uZW50IGNsYXNzZXMgdG8gcGFzcyB0byBNZXNzZW5nZXIgd2hlbiBpdCBpcyBpbnN0YW50aWF0ZWQuXG4gKiBUaGlzIG1hcCBpcyBmb3IgY29udmVuaWVuY2Ugb25seSwgaXQgaXMgTk9UIHVzZWQgaW50ZXJuYWxseSBieSBNZXNzZW5nZXIsIGEgaG9zdCBjbGFzcyBzaG91bGQgcGFzcyBpdCBmb3IgbWV0aG9kcyB0byBiZSBwcm94aWVkIHRoaXMgd2F5LlxuICovXG5NZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMgPSB7XG4gICAgb246ICdvbicsXG4gICAgb25TeW5jOiAnb25TeW5jJyxcbiAgICBvbmNlOiAnb25jZScsXG4gICAgb25jZVN5bmM6ICdvbmNlU3luYycsXG4gICAgb2ZmOiAnb2ZmJyxcbiAgICBvbk1lc3NhZ2VzOiAnb25NZXNzYWdlcycsXG4gICAgb2ZmTWVzc2FnZXM6ICdvZmZNZXNzYWdlcycsXG4gICAgcG9zdE1lc3NhZ2U6ICdwb3N0TWVzc2FnZScsXG4gICAgcG9zdE1lc3NhZ2VTeW5jOiAncG9zdE1lc3NhZ2VTeW5jJyxcbiAgICBnZXRTdWJzY3JpYmVyczogJ2dldFN1YnNjcmliZXJzJ1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1lc3NlbmdlcjtcblxuXG5NZXNzZW5nZXIuc3Vic2NyaXB0aW9ucyA9IFtdO1xuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogSW5pdGlhbGl6ZXMgTWVzc2VuZ2VyLiBNZXRob2QgaXMgY2FsbGVkIGJ5IE1peGluIGNsYXNzIGNvbnN0cnVjdG9yLlxuICogU2VlIFtvbl0oI01lc3NlbmdlciRvbikgbWV0aG9kLCBbTWVzc2VuZ2VyXSgjTWVzc2VuZ2VyKSBjbGFzcyBhYm92ZSBhbmQgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgY2xhc3MuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGhvc3RPYmplY3QgT3B0aW9uYWwgb2JqZWN0IHRoYXQgc3RvcmVzIHRoZSBtZXNzZW5nZXIgb24gb25lIG9mIGl0cyBwcm9wZXJ0aWVzLiBJdCBpcyB1c2VkIHRvIHByb3h5IG1ldGhvZHMgb2YgbWVzc2VuZ2VyIGFuZCBhbHNvIGFzIGEgY29udGV4dCBmb3Igc3Vic2NyaWJlcnMgd2hlbiB0aGV5IGFyZSBjYWxsZWQgYnkgdGhlIE1lc3Nlbmdlci4gU2VlIGBvbmAgbWV0aG9kLlxuICogQHBhcmFtIHtPYmplY3R9IHByb3h5TWV0aG9kcyBPcHRpb25hbCBtYXAgb2YgbWV0aG9kIG5hbWVzOyBrZXkgLSBwcm94eSBtZXRob2QgbmFtZSwgdmFsdWUgLSBtZXNzZW5nZXIncyBtZXRob2QgbmFtZS5cbiAqIEBwYXJhbSB7TWVzc2FnZVNvdXJjZX0gbWVzc2FnZVNvdXJjZSBPcHRpb25hbCBtZXNzYWdlU291cmNlIGxpbmtlZCB0byB0aGUgbWVzc2VuZ2VyLiBJZiBtZXNzYWdlU291cmNlIGlzIHN1cHBsaWVkLCB0aGUgcmVmZXJlbmNlIHRvIHRoZSBtZXNzZW5nZXIgd2lsbCBzdG9yZWQgb24gaXRzICdtZXNzZW5nZXInIHByb3BlcnR5XG4gKi9cbmZ1bmN0aW9uIGluaXQoaG9zdE9iamVjdCwgcHJveHlNZXRob2RzLCBtZXNzYWdlU291cmNlKSB7XG4gICAgLy8gaG9zdE9iamVjdCBhbmQgcHJveHlNZXRob2RzIGFyZSB1c2VkIGluIE1peGluIGFuZCBjaGVja2VkIHRoZXJlXG4gICAgaWYgKG1lc3NhZ2VTb3VyY2UpXG4gICAgICAgIHRoaXMuX3NldE1lc3NhZ2VTb3VyY2UobWVzc2FnZVNvdXJjZSk7XG5cbiAgICBfaW5pdGlhbGl6ZVN1YnNjcmliZXJzLmNhbGwodGhpcyk7XG59XG5cblxuZnVuY3Rpb24gX2luaXRpYWxpemVTdWJzY3JpYmVycygpIHtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfbWVzc2FnZVN1YnNjcmliZXJzOiB7fSxcbiAgICAgICAgX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnM6IHt9LFxuICAgIH0sIF8uQ09ORik7XG59XG5cblxuLyoqXG4gKiBEZXN0cm95cyBtZXNzZW5nZXIuIE1heWJlIG5lZWRzIHRvIHVuc3Vic2NyaWJlIGFsbCBzdWJzY3JpYmVyc1xuICovXG5mdW5jdGlvbiBNZXNzZW5nZXIkZGVzdHJveSgpIHtcbiAgICB0aGlzLm9mZkFsbCgpO1xuICAgIHZhciBtZXNzYWdlU291cmNlID0gdGhpcy5nZXRNZXNzYWdlU291cmNlKCk7XG4gICAgaWYgKG1lc3NhZ2VTb3VyY2UpXG4gICAgICAgIG1lc3NhZ2VTb3VyY2UuZGVzdHJveSgpO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZC5cbiAqIFJlZ2lzdGVycyBhIHN1YnNjcmliZXIgZnVuY3Rpb24gZm9yIGEgY2VydGFpbiBtZXNzYWdlKHMpLlxuICogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1YnNjcmlwdGlvbiB3YXMgc3VjY2Vzc2Z1bC4gSXQgY2FuIGJlIHVuc3VjY2Vzc2Z1bCBpZiB0aGUgcGFzc2VkIHN1YnNjcmliZXIgaGFzIGFscmVhZHkgYmVlbiBzdWJzY3JpYmVkIHRvIHRoaXMgbWVzc2FnZSB0eXBlIC0gZG91YmxlIHN1YnNjcmlwdGlvbiBuZXZlciBoYXBwZW5zIGFuZCBpdCBpcyBzYWZlIHRvIHN1YnNjcmliZSBhZ2FpbiAtIG5vIGVycm9yIG9yIHdhcm5pbmcgaXMgdGhyb3duIG9yIGxvZ2dlZC5cbiAqIFN1YnNjcmliZXIgaXMgcGFzc2VkIHR3byBwYXJhbWV0ZXJzOiBgbWVzc2FnZWAgKHN0cmluZykgYW5kIGBkYXRhYCAob2JqZWN0KS4gRGF0YSBvYmplY3QgaXMgc3VwcGxpZWQgd2hlbiBtZXNzYWdlIGlzIGRpc3BhdGNoZWQsIE1lc3NlbmdlciBpdHNlbGYgYWRkcyBub3RoaW5nIHRvIGl0LiBGb3IgZXhhbXBsZSwgW2V2ZW50cyBmYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0cy9FdmVudHMuanMuaHRtbCkgc2VuZHMgYWN0dWFsIERPTSBldmVudCB3aGVuIGl0IHBvc3RzIG1lc3NhZ2UuXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogLy8gc3Vic2NyaWJlcyBvbk1vdXNlVXBEb3duIHRvIHR3byBET00gZXZlbnRzIG9uIGNvbXBvbmVudCB2aWEgZXZlbnRzIGZhY2V0LlxuICogbXlDb21wLmV2ZW50cy5vbignbW91c2Vkb3duIG1vdXNldXAnLCBvbk1vdXNlVXBEb3duKTtcbiAqIGZ1bmN0aW9uIG9uTW91c2VVcERvd24oZXZlbnRUeXBlLCBldmVudCkge1xuICogICAgIC8vIC4uLlxuICogfVxuICpcbiAqIG15Q29tcC5kYXRhLm9uKC8uKy8sIGZ1bmN0aW9uKG1zZywgZGF0YSkge1xuICogICAgIGxvZ2dlci5kZWJ1Zyhtc2csIGRhdGEpO1xuICogfSk7IC8vIHN1YnNjcmliZXMgYW5vbnltb3VzIGZ1bmN0aW9uIHRvIGFsbCBub24tZW1wdHkgbWVzc2FnZXMgb24gZGF0YSBmYWNldFxuICogLy8gaXQgd2lsbCBub3QgYmUgcG9zc2libGUgdG8gdW5zdWJzY3JpYmUgYW5vbnltb3VzIHN1YnNjcmliZXIgc2VwYXJhdGVseSxcbiAqIC8vIGJ1dCBteUNvbXAuZGF0YS5vZmYoLy4rLykgd2lsbCB1bnN1YnNjcmliZSBpdFxuICogYGBgXG4gKiBJZiBtZXNzZW5nZXIgaGFzIFtNZXNzYWdlU291cmNlXSguL21fc291cmNlLmpzLmh0bWwpIGF0dGFjaGVkIHRvIGl0LCBNZXNzYWdlU291cmNlIHdpbGwgYmUgbm90aWZpZWQgd2hlbiB0aGUgZmlyc3Qgc3Vic2NyaWJlciBmb3IgYSBnaXZlbiBtZXNzYWdlIGlzIGFkZGVkLCBzbyBpdCBjYW4gc3Vic2NyaWJlIHRvIHRoZSBzb3VyY2UuXG4gKiBbQ29tcG9uZW50c10oLi4vY29tcG9uZW50cy9jX2NsYXNzLmpzLmh0bWwpIGFuZCBbZmFjZXRzXSguLi9jb21wb25lbnRzL2NfZmFjZXQuanMuaHRtbCkgY2hhbmdlIHRoaXMgbWV0aG9kIG5hbWUgdG8gYG9uYCB3aGVuIHRoZXkgcHJveHkgaXQuXG4gKiBTZWUgW3Bvc3RNZXNzYWdlXSgjcG9zdE1lc3NhZ2UpLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5W1N0cmluZ118UmVnRXhwfSBtZXNzYWdlcyBNZXNzYWdlIHR5cGVzIHRoYXQgc2hvdWxkIGVudm9rZSB0aGUgc3Vic2NyaWJlci5cbiAqICBJZiBzdHJpbmcgaXMgcGFzc2VkLCBpdCBjYW4gYmUgYSBzaWdsZSBtZXNzYWdlIG9yIG11bHRpcGxlIG1lc3NhZ2UgdHlwZXMgc2VwYXJhdGVkIGJ5IHdoaXRlc3BhY2Ugd2l0aCBvcHRpb25hbCBjb21tYXMuXG4gKiAgSWYgYW4gYXJyYXkgb2Ygc3RyaW5ncyBpcyBwYXNzZWQsIGVhY2ggc3RyaW5nIGlzIGEgbWVzc2FnZSB0eXBlIHRvIHN1YnNjcmliZSBmb3IuXG4gKiAgSWYgYSBSZWdFeHAgaXMgcGFzc2VkLCB0aGUgc3Vic2NyaWJlciB3aWxsIGJlIGVudm9rZWQgd2hlbiB0aGUgbWVzc2FnZSBkaXNwYXRjaGVkIG9uIHRoZSBtZXNzZW5nZXIgbWF0Y2hlcyB0aGUgcGF0dGVybiAob3IgSVMgdGhlIFJlZ0V4cCB3aXRoIGlkZW50aWNhbCBwYXR0ZXJuKS5cbiAqICBQYXR0ZXJuIHN1YnNjcmliZXIgZG9lcyBOT1QgY2F1c2UgYW55IHN1YnNjcmlwdGlvbiB0byBNZXNzYWdlU291cmNlLCBpdCBvbmx5IGNhcHR1cmVzIG1lc3NhZ2VzIHRoYXQgYXJlIGFscmVhZHkgc3Vic2NyaWJlZCB0byB3aXRoIHByZWNpc2UgbWVzc2FnZSB0eXBlcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBzdWJzY3JpYmVyIE1lc3NhZ2Ugc3Vic2NyaWJlciAtIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBtZXNzYWdlIGlzIGRpc3BhdGNoZWQgb24gdGhlIG1lc3NlbmdlciAodXN1YWxseSB2aWEgcHJveGllZCBwb3N0TWVzc2FnZSBtZXRob2Qgb2YgaG9zdCBvYmplY3QpLlxuICogIElmIGhvc3RPYmplY3Qgd2FzIHN1cHBsaWVkIHRvIE1lc3NlbmdlciBjb25zdHJ1Y3RvciwgaG9zdE9iamVjdCB3aWxsIGJlIHRoZSBjb250ZXh0ICh0aGUgdmFsdWUgb2YgdGhpcykgZm9yIHRoZSBzdWJzY3JpYmVyIGVudm9jYXRpb24uXG4gKiAgU3Vic2NyaWJlciBjYW4gYWxzbyBiZSBhbiBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIGBzdWJzY3JpYmVyYCAoZnVuY3Rpb24pIGFuZCBgY29udGV4dGAgKFwidGhpc1wiIHZhbHVlIHdoZW4gc3Vic2NyaWJlciBpcyBjYWxsZWQpXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBNZXNzZW5nZXIkb24obWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICByZXR1cm4gX01lc3Nlbmdlcl9vbldpdGhPcHRpb25zLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xufVxuXG5cbmZ1bmN0aW9uIE1lc3NlbmdlciRvbmNlKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucy5jYWxsKHRoaXMsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyLCB7IGRpc3BhdGNoVGltZXM6IDEgfSk7XG59XG5cbmZ1bmN0aW9uIE1lc3NlbmdlciRvbmNlU3luYyhtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMuY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlciwgeyBkaXNwYXRjaFRpbWVzOiAxLCBzeW5jOiB0cnVlIH0pO1xufVxuXG5cbmZ1bmN0aW9uIE1lc3NlbmdlciRvblN5bmMobWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICByZXR1cm4gX01lc3Nlbmdlcl9vbldpdGhPcHRpb25zLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIsIHsgc3luYzogdHJ1ZSB9KTtcbn1cblxuXG5mdW5jdGlvbiBNZXNzZW5nZXIkb25Bc3luYyhtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMuY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlciwgeyBzeW5jOiBmYWxzZSB9KTtcbn1cblxuXG5mdW5jdGlvbiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMobWVzc2FnZXMsIHN1YnNjcmliZXIsIG9wdGlvbnMpIHtcbiAgICBjaGVjayhtZXNzYWdlcywgTWF0Y2guT25lT2YoU3RyaW5nLCBbU3RyaW5nXSwgUmVnRXhwKSk7XG4gICAgY2hlY2soc3Vic2NyaWJlciwgTWF0Y2guT25lT2YoRnVuY3Rpb24sIHtcbiAgICAgICAgc3Vic2NyaWJlcjogRnVuY3Rpb24sXG4gICAgICAgIGNvbnRleHQ6IE1hdGNoLkFueSxcbiAgICAgICAgb3B0aW9uczogTWF0Y2guT3B0aW9uYWwoT2JqZWN0KSxcbiAgICB9KSk7XG5cbiAgICBpZiAodHlwZW9mIHN1YnNjcmliZXIgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBzdWJzY3JpYmVyID0ge1xuICAgICAgICAgICAgc3Vic2NyaWJlcjogc3Vic2NyaWJlcixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuX2hvc3RPYmplY3QsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgc3Vic2NyaWJlci5vcHRpb25zID0gc3Vic2NyaWJlci5vcHRpb25zIHx8IHt9O1xuICAgICAgICBfLmV4dGVuZChzdWJzY3JpYmVyLm9wdGlvbnMsIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xufVxuXG5cbmZ1bmN0aW9uIF9NZXNzZW5nZXJfb24obWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICBfLmRlZmluZVByb3BlcnR5KHN1YnNjcmliZXIsICdfX21lc3NhZ2VzJywgbWVzc2FnZXMpO1xuICAgIHJldHVybiBfZWFjaE1lc3NhZ2UuY2FsbCh0aGlzLCAnX3JlZ2lzdGVyU3Vic2NyaWJlcicsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbn1cblxuXG5mdW5jdGlvbiBfZWFjaE1lc3NhZ2UobWV0aG9kTmFtZSwgbWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2VzID09ICdzdHJpbmcnKVxuICAgICAgICBtZXNzYWdlcyA9IG1lc3NhZ2VzLnNwbGl0KG1lc3NhZ2VzU3BsaXRSZWdFeHApO1xuXG4gICAgdmFyIHN1YnNjcmliZXJzSGFzaCA9IHRoaXMuX2Nob29zZVN1YnNjcmliZXJzSGFzaChtZXNzYWdlcyk7XG5cbiAgICBpZiAobWVzc2FnZXMgaW5zdGFuY2VvZiBSZWdFeHApXG4gICAgICAgIHJldHVybiB0aGlzW21ldGhvZE5hbWVdKHN1YnNjcmliZXJzSGFzaCwgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xuXG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBjaGFuZ2VkID0gZmFsc2U7XG5cbiAgICAgICAgbWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICAgICAgICB2YXIgc3Vic2NyaXB0aW9uQ2hhbmdlZCA9IHRoaXNbbWV0aG9kTmFtZV0oc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgICAgIGNoYW5nZWQgPSBjaGFuZ2VkIHx8IHN1YnNjcmlwdGlvbkNoYW5nZWQ7XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIHJldHVybiBjaGFuZ2VkO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIEl0IGlzIGNhbGxlZCBieSBbb25dKCNNZXNzZW5nZXIkb24pIHRvIHJlZ2lzdGVyIHN1YnNjcmliZXIgZm9yIG9uZSBtZXNzYWdlIHR5cGUuXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGlzIHN1YnNjcmliZXIgaXMgbm90IHlldCByZWdpc3RlcmVkIGZvciB0aGlzIHR5cGUgb2YgbWVzc2FnZS5cbiAqIElmIG1lc3NlbmdlciBoYXMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgYXR0YWNoZWQgdG8gaXQsIE1lc3NhZ2VTb3VyY2Ugd2lsbCBiZSBub3RpZmllZCB3aGVuIHRoZSBmaXJzdCBzdWJzY3JpYmVyIGZvciBhIGdpdmVuIG1lc3NhZ2UgaXMgYWRkZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdWJzY3JpYmVyc0hhc2ggVGhlIG1hcCBvZiBzdWJzY3JpYmVycyBkZXRlcm1pbmVkIGJ5IFtvbl0oI01lc3NlbmdlciRvbikgYmFzZWQgb24gTWVzc2FnZSB0eXBlLCBjYW4gYmUgYHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnNgIG9yIGB0aGlzLl9tZXNzYWdlU3Vic2NyaWJlcnNgXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBNZXNzYWdlIHR5cGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBzdWJzY3JpYmVyIFN1YnNjcmliZXIgZnVuY3Rpb24gdG8gYmUgYWRkZWQgb3Igb2JqZWN0IHdpdGggcHJvcGVydGllcyBgc3Vic2NyaWJlcmAgKGZ1bmN0aW9uKSBhbmQgYGNvbnRleHRgICh2YWx1ZSBvZiBcInRoaXNcIiB3aGVuIHN1YnNjcmliZXIgaXMgY2FsbGVkKVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gX3JlZ2lzdGVyU3Vic2NyaWJlcihzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UsIHN1YnNjcmliZXIpIHtcbiAgICBpZiAoISAoc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdICYmIHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXS5sZW5ndGgpKSB7XG4gICAgICAgIHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXSA9IFtdO1xuICAgICAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFJlZ0V4cClcbiAgICAgICAgICAgIHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXS5wYXR0ZXJuID0gbWVzc2FnZTtcbiAgICAgICAgaWYgKHRoaXMuX21lc3NhZ2VTb3VyY2UpXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlU291cmNlLm9uU3Vic2NyaWJlckFkZGVkKG1lc3NhZ2UpO1xuICAgICAgICB2YXIgbm9TdWJzY3JpYmVycyA9IHRydWU7XG4gICAgfVxuXG4gICAgdmFyIG1zZ1N1YnNjcmliZXJzID0gc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdO1xuICAgIHZhciBub3RZZXRSZWdpc3RlcmVkID0gbm9TdWJzY3JpYmVycyB8fCBfaW5kZXhPZlN1YnNjcmliZXIuY2FsbCh0aGlzLCBtc2dTdWJzY3JpYmVycywgc3Vic2NyaWJlcikgPT0gLTE7XG5cbiAgICBpZiAobm90WWV0UmVnaXN0ZXJlZClcbiAgICAgICAgbXNnU3Vic2NyaWJlcnMucHVzaChzdWJzY3JpYmVyKTtcblxuICAgIHJldHVybiBub3RZZXRSZWdpc3RlcmVkO1xufVxuXG5cbi8qKlxuICogRmluZHMgc3Vic2NyaWJlciBpbmRleCBpbiB0aGUgbGlzdFxuICpcbiAqIEBwYXJhbSB7QXJyYXlbRnVuY3Rpb258T2JqZWN0XX0gbGlzdCBsaXN0IG9mIHN1YnNjcmliZXJzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdH0gc3Vic2NyaWJlciBzdWJzY3JpYmVyIGZ1bmN0aW9uIG9yIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgYHN1YnNjcmliZXJgIChmdW5jdGlvbikgYW5kIGBjb250ZXh0YCAoXCJ0aGlzXCIgb2JqZWN0KVxuICovXG5mdW5jdGlvbiBfaW5kZXhPZlN1YnNjcmliZXIobGlzdCwgc3Vic2NyaWJlcikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gXy5maW5kSW5kZXgobGlzdCwgZnVuY3Rpb24oc3Vic2NyKXtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmliZXIuc3Vic2NyaWJlciA9PSBzdWJzY3Iuc3Vic2NyaWJlclxuICAgICAgICAgICAgICAgICYmIHN1YnNjcmliZXIuY29udGV4dCA9PSBzdWJzY3IuY29udGV4dFxuICAgIH0pO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZC5cbiAqIFN1YnNjcmliZXMgdG8gbXVsdGlwbGUgbWVzc2FnZXMgcGFzc2VkIGFzIG1hcCB0b2dldGhlciB3aXRoIHN1YnNjcmliZXJzLlxuICogVXNhZ2U6XG4gKiBgYGBcbiAqIG15Q29tcC5ldmVudHMub25NZXNzYWdlcyh7XG4gKiAgICAgJ21vdXNlZG93bic6IG9uTW91c2VEb3duLFxuICogICAgICdtb3VzZXVwJzogb25Nb3VzZVVwXG4gKiB9KTtcbiAqIGZ1bmN0aW9uIG9uTW91c2VEb3duKGV2ZW50VHlwZSwgZXZlbnQpIHt9XG4gKiBmdW5jdGlvbiBvbk1vdXNlVXAoZXZlbnRUeXBlLCBldmVudCkge31cbiAqIGBgYFxuICogUmV0dXJucyBtYXAgd2l0aCB0aGUgc2FtZSBrZXlzIChtZXNzYWdlIHR5cGVzKSBhbmQgYm9vbGVhbiB2YWx1ZXMgaW5kaWNhdGluZyB3aGV0aGVyIHBhcnRpY3VsYXIgc3Vic2NyaWJlciB3YXMgYWRkZWQuXG4gKiBJdCBpcyBOT1QgcG9zc2libGUgdG8gYWRkIHBhdHRlcm4gc3Vic2NyaWJlciB1c2luZyB0aGlzIG1ldGhvZCwgYXMgYWx0aG91Z2ggeW91IGNhbiB1c2UgUmVnRXhwIGFzIHRoZSBrZXksIEphdmFTY3JpcHQgd2lsbCBhdXRvbWF0aWNhbGx5IGNvbnZlcnQgaXQgdG8gc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0W0Z1bmN0aW9uXX0gbWVzc2FnZVN1YnNjcmliZXJzIE1hcCBvZiBtZXNzYWdlIHN1YnNjcmliZXJzIHRvIGJlIGFkZGVkXG4gKiBAcmV0dXJuIHtPYmplY3RbQm9vbGVhbl19XG4gKi9cbmZ1bmN0aW9uIG9uTWVzc2FnZXMobWVzc2FnZVN1YnNjcmliZXJzKSB7XG4gICAgY2hlY2sobWVzc2FnZVN1YnNjcmliZXJzLCBNYXRjaC5PYmplY3RIYXNoKE1hdGNoLk9uZU9mKEZ1bmN0aW9uLCB7IHN1YnNjcmliZXI6IEZ1bmN0aW9uLCBjb250ZXh0OiBNYXRjaC5BbnkgfSkpKTtcblxuICAgIHZhciBub3RZZXRSZWdpc3RlcmVkTWFwID0gXy5tYXBLZXlzKG1lc3NhZ2VTdWJzY3JpYmVycywgZnVuY3Rpb24oc3Vic2NyaWJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub24obWVzc2FnZXMsIHN1YnNjcmliZXIpO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIG5vdFlldFJlZ2lzdGVyZWRNYXA7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogUmVtb3ZlcyBhIHN1YnNjcmliZXIgZm9yIG1lc3NhZ2UocykuIFJlbW92ZXMgYWxsIHN1YnNjcmliZXJzIGZvciB0aGUgbWVzc2FnZSBpZiBzdWJzY3JpYmVyIGlzbid0IHBhc3NlZC5cbiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYHRydWVgIGlmIHRoZSBzdWJzY3JpYmVyIHdhcyByZWdpc3RlcmVkLiBObyBlcnJvciBvciB3YXJuaW5nIGlzIHRocm93biBvciBsb2dnZWQgaWYgeW91IHJlbW92ZSBzdWJzY3JpYmVyIHRoYXQgd2FzIG5vdCByZWdpc3RlcmVkLlxuICogW0NvbXBvbmVudHNdKC4uL2NvbXBvbmVudHMvY19jbGFzcy5qcy5odG1sKSBhbmQgW2ZhY2V0c10oLi4vY29tcG9uZW50cy9jX2ZhY2V0LmpzLmh0bWwpIGNoYW5nZSB0aGlzIG1ldGhvZCBuYW1lIHRvIGBvZmZgIHdoZW4gdGhleSBwcm94eSBpdC5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiAvLyB1bnN1YnNjcmliZXMgb25Nb3VzZVVwRG93biBmcm9tIHR3byBET00gZXZlbnRzLlxuICogbXlDb21wLmV2ZW50cy5vZmYoJ21vdXNlZG93biBtb3VzZXVwJywgb25Nb3VzZVVwRG93bik7XG4gKiBgYGBcbiAqIElmIG1lc3NlbmdlciBoYXMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgYXR0YWNoZWQgdG8gaXQsIE1lc3NhZ2VTb3VyY2Ugd2lsbCBiZSBub3RpZmllZCB3aGVuIHRoZSBsYXN0IHN1YnNjcmliZXIgZm9yIGEgZ2l2ZW4gbWVzc2FnZSBpcyByZW1vdmVkIGFuZCB0aGVyZSBpcyBubyBtb3JlIHN1YnNjcmliZXJzIGZvciB0aGlzIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXlbU3RyaW5nXXxSZWdFeHB9IG1lc3NhZ2VzIE1lc3NhZ2UgdHlwZXMgdGhhdCBhIHN1YnNjcmliZXIgc2hvdWxkIGJlIHJlbW92ZWQgZm9yLlxuICogIElmIHN0cmluZyBpcyBwYXNzZWQsIGl0IGNhbiBiZSBhIHNpZ2xlIG1lc3NhZ2Ugb3IgbXVsdGlwbGUgbWVzc2FnZSB0eXBlcyBzZXBhcmF0ZWQgYnkgd2hpdGVzcGFjZSB3aXRoIG9wdGlvbmFsIGNvbW1hcy5cbiAqICBJZiBhbiBhcnJheSBvZiBzdHJpbmdzIGlzIHBhc3NlZCwgZWFjaCBzdHJpbmcgaXMgYSBtZXNzYWdlIHR5cGUgdG8gcmVtb3ZlIGEgc3Vic2NyaWJlciBmb3IuXG4gKiAgSWYgYSBSZWdFeHAgaXMgcGFzc2VkLCB0aGUgcGF0dGVybiBzdWJzY3JpYmVyIHdpbGwgYmUgcmVtb3ZlZC5cbiAqICBSZWdFeHAgc3Vic2NyaWJlciBkb2VzIE5PVCBjYXVzZSBhbnkgc3Vic2NyaXB0aW9uIHRvIE1lc3NhZ2VTb3VyY2UsIGl0IG9ubHkgY2FwdHVyZXMgbWVzc2FnZXMgdGhhdCBhcmUgYWxyZWFkeSBzdWJzY3JpYmVkIHRvIHdpdGggcHJlY2lzZSBtZXNzYWdlIHR5cGVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3Vic2NyaWJlciBNZXNzYWdlIHN1YnNjcmliZXIgLSBPcHRpb25hbCBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBsaXN0IG9mIHN1YnNjcmliZXJzIGZvciB0aGUgbWVzc2FnZShzKS4gSWYgc3Vic2NyaWJlciBpcyBub3Qgc3VwcGxpZWQsIGFsbCBzdWJzY3JpYmVycyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGlzIG1lc3NhZ2UocykuXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBNZXNzZW5nZXIkb2ZmKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgY2hlY2sobWVzc2FnZXMsIE1hdGNoLk9uZU9mKFN0cmluZywgW1N0cmluZ10sIFJlZ0V4cCkpO1xuICAgIGNoZWNrKHN1YnNjcmliZXIsIE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKEZ1bmN0aW9uLCB7XG4gICAgICAgIHN1YnNjcmliZXI6IEZ1bmN0aW9uLFxuICAgICAgICBjb250ZXh0OiBNYXRjaC5BbnksXG4gICAgICAgIG9wdGlvbnM6IE1hdGNoLk9wdGlvbmFsKE9iamVjdCksXG4gICAgICAgIC8vIF9fbWVzc2FnZXM6IE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKFN0cmluZywgW1N0cmluZ10sIFJlZ0V4cCkpXG4gICAgfSkpKTtcblxuICAgIHJldHVybiBfTWVzc2VuZ2VyX29mZi5jYWxsKHRoaXMsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbn1cblxuXG5mdW5jdGlvbiBfTWVzc2VuZ2VyX29mZihtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfZWFjaE1lc3NhZ2UuY2FsbCh0aGlzLCAnX3JlbW92ZVN1YnNjcmliZXInLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG59XG5cblxuLyoqXG4gKiBcIlByaXZhdGVcIiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBJdCBpcyBjYWxsZWQgYnkgW29mZl0oI01lc3NlbmdlciRvZmYpIHRvIHJlbW92ZSBzdWJzY3JpYmVyIGZvciBvbmUgbWVzc2FnZSB0eXBlLlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhpcyBzdWJzY3JpYmVyIHdhcyByZWdpc3RlcmVkIGZvciB0aGlzIHR5cGUgb2YgbWVzc2FnZS5cbiAqIElmIG1lc3NlbmdlciBoYXMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgYXR0YWNoZWQgdG8gaXQsIE1lc3NhZ2VTb3VyY2Ugd2lsbCBiZSBub3RpZmllZCB3aGVuIHRoZSBsYXN0IHN1YnNjcmliZXIgZm9yIGEgZ2l2ZW4gbWVzc2FnZSBpcyByZW1vdmVkIGFuZCB0aGVyZSBpcyBubyBtb3JlIHN1YnNjcmliZXJzIGZvciB0aGlzIG1lc3NhZ2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdWJzY3JpYmVyc0hhc2ggVGhlIG1hcCBvZiBzdWJzY3JpYmVycyBkZXRlcm1pbmVkIGJ5IFtvZmZdKCNNZXNzZW5nZXIkb2ZmKSBiYXNlZCBvbiBtZXNzYWdlIHR5cGUsIGNhbiBiZSBgdGhpcy5fcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVyc2Agb3IgYHRoaXMuX21lc3NhZ2VTdWJzY3JpYmVyc2BcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIE1lc3NhZ2UgdHlwZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3Vic2NyaWJlciBTdWJzY3JpYmVyIGZ1bmN0aW9uIHRvIGJlIHJlbW92ZWRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIF9yZW1vdmVTdWJzY3JpYmVyKHN1YnNjcmliZXJzSGFzaCwgbWVzc2FnZSwgc3Vic2NyaWJlcikge1xuICAgIHZhciBtc2dTdWJzY3JpYmVycyA9IHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXTtcbiAgICBpZiAoISBtc2dTdWJzY3JpYmVycyB8fCAhIG1zZ1N1YnNjcmliZXJzLmxlbmd0aClcbiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBub3RoaW5nIHJlbW92ZWRcblxuICAgIGlmIChzdWJzY3JpYmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc3Vic2NyaWJlciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgc3Vic2NyaWJlciA9IHsgc3Vic2NyaWJlcjogc3Vic2NyaWJlciwgY29udGV4dDogdGhpcy5faG9zdE9iamVjdCB9O1xuXG4gICAgICAgIHZhciBzdWJzY3JpYmVySW5kZXggPSBfaW5kZXhPZlN1YnNjcmliZXIuY2FsbCh0aGlzLCBtc2dTdWJzY3JpYmVycywgc3Vic2NyaWJlcik7XG4gICAgICAgIGlmIChzdWJzY3JpYmVySW5kZXggPT0gLTEpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdGhpbmcgcmVtb3ZlZFxuICAgICAgICBtc2dTdWJzY3JpYmVycy5zcGxpY2Uoc3Vic2NyaWJlckluZGV4LCAxKTtcbiAgICAgICAgaWYgKCEgbXNnU3Vic2NyaWJlcnMubGVuZ3RoKVxuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlQWxsU3Vic2NyaWJlcnMoc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlKTtcblxuICAgIH0gZWxzZVxuICAgICAgICB0aGlzLl9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpO1xuXG4gICAgcmV0dXJuIHRydWU7IC8vIHN1YnNjcmliZXIocykgcmVtb3ZlZFxufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogSXQgaXMgY2FsbGVkIGJ5IFtfcmVtb3ZlU3Vic2NyaWJlcl0oI19yZW1vdmVTdWJzY3JpYmVyKSB0byByZW1vdmUgYWxsIHN1YnNjcmliZXJzIGZvciBvbmUgbWVzc2FnZSB0eXBlLlxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHRoYXQgYWxsIG1lc3NhZ2Ugc3Vic2NyaWJlcnMgd2VyZSByZW1vdmVkIHNvIGl0IGNhbiB1bnN1YnNjcmliZSBmcm9tIHRoZSBzb3VyY2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdWJzY3JpYmVyc0hhc2ggVGhlIG1hcCBvZiBzdWJzY3JpYmVycyBkZXRlcm1pbmVkIGJ5IFtvZmZdKCNNZXNzZW5nZXIkb2ZmKSBiYXNlZCBvbiBtZXNzYWdlIHR5cGUsIGNhbiBiZSBgdGhpcy5fcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVyc2Agb3IgYHRoaXMuX21lc3NhZ2VTdWJzY3JpYmVyc2BcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIE1lc3NhZ2UgdHlwZVxuICovXG5mdW5jdGlvbiBfcmVtb3ZlQWxsU3Vic2NyaWJlcnMoc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlKSB7XG4gICAgZGVsZXRlIHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXTtcbiAgICBpZiAodGhpcy5fbWVzc2FnZVNvdXJjZSAmJiB0eXBlb2YgbWVzc2FnZSA9PSAnc3RyaW5nJylcbiAgICAgICAgdGhpcy5fbWVzc2FnZVNvdXJjZS5vblN1YnNjcmliZXJSZW1vdmVkKG1lc3NhZ2UpO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZC5cbiAqIFVuc3Vic2NyaWJlcyBmcm9tIG11bHRpcGxlIG1lc3NhZ2VzIHBhc3NlZCBhcyBtYXAgdG9nZXRoZXIgd2l0aCBzdWJzY3JpYmVycy5cbiAqIFJldHVybnMgbWFwIHdpdGggdGhlIHNhbWUga2V5cyAobWVzc2FnZSB0eXBlcykgYW5kIGJvb2xlYW4gdmFsdWVzIGluZGljYXRpbmcgd2hldGhlciBwYXJ0aWN1bGFyIHN1YnNjcmliZXIgd2FzIHJlbW92ZWQuXG4gKiBJZiBhIHN1YnNjcmliZXIgZm9yIG9uZSBvZiB0aGUgbWVzc2FnZXMgaXMgbm90IHN1cHBsaWVkLCBhbGwgc3Vic2NyaWJlcnMgZm9yIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHJlbW92ZWQuXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogbXlDb21wLmV2ZW50cy5vZmZNZXNzYWdlcyh7XG4gKiAgICAgJ21vdXNlZG93bic6IG9uTW91c2VEb3duLFxuICogICAgICdtb3VzZXVwJzogb25Nb3VzZVVwLFxuICogICAgICdjbGljayc6IHVuZGVmaW5lZCAvLyBhbGwgc3Vic2NyaWJlcnMgdG8gdGhpcyBtZXNzYWdlIHdpbGwgYmUgcmVtb3ZlZFxuICogfSk7XG4gKiBgYGBcbiAqIEl0IGlzIE5PVCBwb3NzaWJsZSB0byByZW1vdmUgcGF0dGVybiBzdWJzY3JpYmVyKHMpIHVzaW5nIHRoaXMgbWV0aG9kLCBhcyBhbHRob3VnaCB5b3UgY2FuIHVzZSBSZWdFeHAgYXMgdGhlIGtleSwgSmF2YVNjcmlwdCB3aWxsIGF1dG9tYXRpY2FsbHkgY29udmVydCBpdCB0byBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtPYmplY3RbRnVuY3Rpb25dfSBtZXNzYWdlU3Vic2NyaWJlcnMgTWFwIG9mIG1lc3NhZ2Ugc3Vic2NyaWJlcnMgdG8gYmUgcmVtb3ZlZFxuICogQHJldHVybiB7T2JqZWN0W0Jvb2xlYW5dfVxuICovXG5mdW5jdGlvbiBvZmZNZXNzYWdlcyhtZXNzYWdlU3Vic2NyaWJlcnMpIHtcbiAgICBjaGVjayhtZXNzYWdlU3Vic2NyaWJlcnMsIE1hdGNoLk9iamVjdEhhc2goTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoRnVuY3Rpb24sIHsgc3Vic2NyaWJlcjogRnVuY3Rpb24sIGNvbnRleHQ6IE1hdGNoLkFueSB9KSkpKTtcblxuICAgIHZhciBzdWJzY3JpYmVyUmVtb3ZlZE1hcCA9IF8ubWFwS2V5cyhtZXNzYWdlU3Vic2NyaWJlcnMsIGZ1bmN0aW9uKHN1YnNjcmliZXIsIG1lc3NhZ2VzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9mZihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gc3Vic2NyaWJlclJlbW92ZWRNYXA7XG59XG5cblxuLyoqXG4gKiBVbnN1YnNjcmliZXMgYWxsIHN1YnNjcmliZXJzXG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRvZmZBbGwoKSB7XG4gICAgX29mZkFsbFN1YnNjcmliZXJzLmNhbGwodGhpcywgdGhpcy5fcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVycyk7XG4gICAgX29mZkFsbFN1YnNjcmliZXJzLmNhbGwodGhpcywgdGhpcy5fbWVzc2FnZVN1YnNjcmliZXJzKTtcbn1cblxuXG5mdW5jdGlvbiBfb2ZmQWxsU3Vic2NyaWJlcnMoc3Vic2NyaWJlcnNIYXNoKSB7XG4gICAgXy5lYWNoS2V5KHN1YnNjcmliZXJzSGFzaCwgZnVuY3Rpb24oc3Vic2NyaWJlcnMsIG1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy5fcmVtb3ZlQWxsU3Vic2NyaWJlcnMoc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlKTtcbiAgICB9LCB0aGlzKTtcbn1cblxuXG4vLyBUT0RPIC0gc2VuZCBldmVudCB0byBtZXNzYWdlU291cmNlXG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogRGlzcGF0Y2hlcyB0aGUgbWVzc2FnZSBjYWxsaW5nIGFsbCBzdWJzY3JpYmVycyByZWdpc3RlcmVkIGZvciB0aGlzIG1lc3NhZ2UgYW5kLCBpZiB0aGUgbWVzc2FnZSBpcyBhIHN0cmluZywgY2FsbGluZyBhbGwgcGF0dGVybiBzdWJzY3JpYmVycyB3aGVuIG1lc3NhZ2UgbWF0Y2hlcyB0aGUgcGF0dGVybi5cbiAqIEVhY2ggc3Vic2NyaWJlciBpcyBwYXNzZWQgdGhlIHNhbWUgcGFyYW1ldGVycyB0aGF0IGFyZSBwYXNzZWQgdG8gdGhlaXMgbWV0aG9kLlxuICogVGhlIGNvbnRleHQgb2YgdGhlIHN1YnNjcmliZXIgZW52b2NhdGlvbiBpcyBzZXQgdG8gdGhlIGhvc3Qgb2JqZWN0IChgdGhpcy5faG9zdE9iamVjdGApIHRoYXQgd2FzIHBhc3NlZCB0byB0aGUgbWVzc2VuZ2VyIGNvbnN0cnVjdG9yLlxuICogU3Vic2NyaWJlcnMgYXJlIGNhbGxlZCBpbiB0aGUgbmV4dCB0aWNrIChcImFzeW5jaHJvbm91c2x5XCIpIGFwYXJ0IGZyb20gdGhvc2UgdGhhdCB3ZXJlIHN1YnNjcmliZWQgd2l0aCBgb25TeW5jYCAob3IgdGhhdCBoYXZlIGBvcHRpb25zLnN5bmMgPT0gdHJ1ZWApLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIGRpc3BhdGNoZWRcbiAqICBJZiB0aGUgbWVzc2FnZSBpcyBhIHN0cmluZywgdGhlIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCBleGFjdGx5IHRoaXMgbWVzc2FnZSB3aWxsIGJlIGNhbGxlZCBhbmQgYWxzbyBwYXR0ZXJuIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgcGF0dGVybiB0aGF0IG1hdGNoZXMgdGhlIGRpc3BhdGNoZWQgbWVzc2FnZS5cbiAqICBJZiB0aGUgbWVzc2FnZSBpcyBSZWdFeHAsIG9ubHkgdGhlIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCBleGFjdGx5IHRoaXMgcGF0dGVybiB3aWxsIGJlIGNhbGxlZC5cbiAqIEBwYXJhbSB7QW55fSBkYXRhIGRhdGEgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgc3Vic2NyaWJlciBhcyB0aGUgc2Vjb25kIHBhcmFtZXRlci4gTWVzc2VuZ2VyIGRvZXMgbm90IG1vZGlmeSB0aGlzIGRhdGEgaW4gYW55IHdheS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIG9wdGlvbmFsIGNhbGxiYWNrIHRvIHBhc3MgdG8gc3Vic2NyaWJlclxuICogQHBhcmFtIHtCb29sZWFufSBfc3luY2hyb25vdXMgaWYgdHJ1ZSBwYXNzZWQsIHN1YnNjcmliZXJzIHdpbGwgYmUgZW52b2tlZCBzeW5jaHJvbm91c2x5IGFwYXJ0IGZyb20gdGhvc2UgdGhhdCBoYXZlIGBvcHRpb25zLnN5bmMgPT0gZmFsc2VgLiBUaGlzIHBhcmFtZXRlciBzaG91bGQgbm90IGJlIHVzZWQsIGluc3RlYWQgcG9zdE1lc3NhZ2VTeW5jIHNob3VsZCBiZSB1c2VkLlxuICovXG5mdW5jdGlvbiBwb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgX3N5bmNocm9ub3VzKSB7XG4gICAgY2hlY2sobWVzc2FnZSwgTWF0Y2guT25lT2YoU3RyaW5nLCBSZWdFeHApKTtcbiAgICBjaGVjayhjYWxsYmFjaywgTWF0Y2guT3B0aW9uYWwoRnVuY3Rpb24pKTtcblxuICAgIHZhciBzdWJzY3JpYmVyc0hhc2ggPSB0aGlzLl9jaG9vc2VTdWJzY3JpYmVyc0hhc2gobWVzc2FnZSk7XG4gICAgdmFyIG1zZ1N1YnNjcmliZXJzID0gc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdO1xuXG4gICAgdGhpcy5fY2FsbFN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBtc2dTdWJzY3JpYmVycywgX3N5bmNocm9ub3VzKTtcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PSAnc3RyaW5nJylcbiAgICAgICAgdGhpcy5fY2FsbFBhdHRlcm5TdWJzY3JpYmVycyhtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgbXNnU3Vic2NyaWJlcnMsIF9zeW5jaHJvbm91cyk7XG59XG5cblxuLyoqXG4gKiBTYW1lIGFzIHBvc3RNZXNzYWdlIGFwYXJ0IGZyb20gZW52b2tpbmcgc3Vic2NyaWJlcnMgc3luY2hyb25vdXNseSwgYXBhcnQgZnJvbSB0aG9zZSBzdWJzY3JpYmVkIHdpdGggYG9uQXN5bmNgIChvciB3aXRoIGBvcHRpb25zLnN5bmMgPT0gZmFsc2VgKS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IG1lc3NhZ2VcbiAqIEBwYXJhbSB7QW55fSBkYXRhXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICovXG5mdW5jdGlvbiBwb3N0TWVzc2FnZVN5bmMobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCB0cnVlKTtcbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIEVudm9rZXMgcGF0dGVybiBzdWJzY3JpYmVycyB3aXRoIHRoZSBwYXR0ZXJuIHRoYXQgbWF0Y2hlcyB0aGUgbWVzc2FnZS5cbiAqIFRoZSBtZXRob2QgaXMgY2FsbGVkIGJ5IFtwb3N0TWVzc2FnZV0oI3Bvc3RNZXNzYWdlKSAtIHNlZSBtb3JlIGluZm9ybWF0aW9uIHRoZXJlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIGRpc3BhdGNoZWQuIFBhdHRlcm4gc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBwYXR0ZXJuIHRoYXQgbWF0Y2hlcyB0aGUgZGlzcGF0Y2hlZCBtZXNzYWdlIHdpbGwgYmUgY2FsbGVkLlxuICogQHBhcmFtIHtBbnl9IGRhdGEgZGF0YSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBzdWJzY3JpYmVyIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBNZXNzZW5nZXIgZG9lcyBub3QgbW9kaWZ5IHRoaXMgZGF0YSBpbiBhbnkgd2F5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdG8gcGFzcyB0byBzdWJzY3JpYmVyXG4gKiBAcGFyYW0ge0FycmF5W0Z1bmN0aW9ufE9iamVjdF19IGNhbGxlZE1zZ1N1YnNjcmliZXJzIGFycmF5IG9mIHN1YnNjcmliZXJzIGFscmVhZHkgY2FsbGVkLCB0aGV5IHdvbid0IGJlIGNhbGxlZCBhZ2FpbiBpZiB0aGV5IGFyZSBhbW9uZyBwYXR0ZXJuIHN1YnNjcmliZXJzLlxuICovXG5mdW5jdGlvbiBfY2FsbFBhdHRlcm5TdWJzY3JpYmVycyhtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgY2FsbGVkTXNnU3Vic2NyaWJlcnMsIF9zeW5jaHJvbm91cykge1xuICAgIF8uZWFjaEtleSh0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzLFxuICAgICAgICBmdW5jdGlvbihwYXR0ZXJuU3Vic2NyaWJlcnMpIHtcbiAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gcGF0dGVyblN1YnNjcmliZXJzLnBhdHRlcm47XG4gICAgICAgICAgICBpZiAocGF0dGVybi50ZXN0KG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNhbGxlZE1zZ1N1YnNjcmliZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXR0ZXJuU3Vic2NyaWJlcnMgPSBwYXR0ZXJuU3Vic2NyaWJlcnMuZmlsdGVyKGZ1bmN0aW9uKHN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IF9pbmRleE9mU3Vic2NyaWJlci5jYWxsKHRoaXMsIGNhbGxlZE1zZ1N1YnNjcmliZXJzLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbmRleCA9PSAtMTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxTdWJzY3JpYmVycyhtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgcGF0dGVyblN1YnNjcmliZXJzLCBfc3luY2hyb25vdXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgLCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIEVudm9rZXMgc3Vic2NyaWJlcnMgZnJvbSB0aGUgcGFzc2VkIGxpc3QuXG4gKiBUaGUgbWV0aG9kIGlzIGNhbGxlZCBieSBbcG9zdE1lc3NhZ2VdKCNwb3N0TWVzc2FnZSkgYW5kIFtfY2FsbFBhdHRlcm5TdWJzY3JpYmVyc10oI19jYWxsUGF0dGVyblN1YnNjcmliZXJzKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgbWVzc2FnZSB0byBiZSBkaXNwYXRjaGVkLCBwYXNzZWQgdG8gc3Vic2NyaWJlcnMgYXMgdGhlIGZpcnN0IHBhcmFtZXRlci5cbiAqIEBwYXJhbSB7QW55fSBkYXRhIGRhdGEgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgc3Vic2NyaWJlciBhcyB0aGUgc2Vjb25kIHBhcmFtZXRlci4gTWVzc2VuZ2VyIGRvZXMgbm90IG1vZGlmeSB0aGlzIGRhdGEgaW4gYW55IHdheS5cbiAqIEBwYXJhbSB7QXJyYXlbRnVuY3Rpb258T2JqZWN0XX0gbXNnU3Vic2NyaWJlcnMgdGhlIGFycmF5IG9mIG1lc3NhZ2Ugc3Vic2NyaWJlcnMgdG8gYmUgY2FsbGVkLiBFYWNoIHN1YnNjcmliZXIgaXMgY2FsbGVkIHdpdGggdGhlIGhvc3Qgb2JqZWN0IChzZWUgTWVzc2VuZ2VyIGNvbnN0cnVjdG9yKSBhcyB0aGUgY29udGV4dC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIG9wdGlvbmFsIGNhbGxiYWNrIHRvIHBhc3MgdG8gc3Vic2NyaWJlclxuICovXG5mdW5jdGlvbiBfY2FsbFN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBtc2dTdWJzY3JpYmVycywgX3N5bmNocm9ub3VzKSB7XG4gICAgaWYgKG1zZ1N1YnNjcmliZXJzICYmIG1zZ1N1YnNjcmliZXJzLmxlbmd0aCkge1xuICAgICAgICAvLyBjbG9uaW5nIGlzIG5lY2Vzc2FyeSBhcyBzb21lIG9mIHRoZSBzdWJzY3JpYmVyc1xuICAgICAgICAvLyBjYW4gYmUgdW5zdWJzY3JpYmVkIGR1cmluZyB0aGUgZGlzcGF0Y2hcbiAgICAgICAgLy8gc28gdGhpcyBhcnJheSB3b3VsZCBjaGFuZ2UgaW4gdGhlIHByb2Nlc3NcbiAgICAgICAgbXNnU3Vic2NyaWJlcnMgPSBtc2dTdWJzY3JpYmVycy5zbGljZSgpO1xuXG4gICAgICAgIG1zZ1N1YnNjcmliZXJzLmZvckVhY2goZnVuY3Rpb24oc3Vic2NyaWJlcikge1xuICAgICAgICAgICAgdGhpcy5fY2FsbFN1YnNjcmliZXIoc3Vic2NyaWJlciwgbWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIF9zeW5jaHJvbm91cyk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBfY2FsbFN1YnNjcmliZXIoc3Vic2NyaWJlciwgbWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIF9zeW5jaHJvbm91cykge1xuICAgIHZhciBzeW5jU3Vic2NyaWJlciA9IHN1YnNjcmliZXIub3B0aW9ucyAmJiBzdWJzY3JpYmVyLm9wdGlvbnMuc3luY1xuICAgICAgICAsIHN5bmNocm8gPSAoX3N5bmNocm9ub3VzICYmIHN5bmNTdWJzY3JpYmVyICE9PSBmYWxzZSlcbiAgICAgICAgICAgICAgICAgIHx8IHN5bmNTdWJzY3JpYmVyO1xuXG4gICAgdmFyIGRpc3BhdGNoVGltZXMgPSBzdWJzY3JpYmVyLm9wdGlvbnMgJiYgc3Vic2NyaWJlci5vcHRpb25zLmRpc3BhdGNoVGltZXM7XG4gICAgaWYgKGRpc3BhdGNoVGltZXMpIHtcbiAgICAgICAgaWYgKGRpc3BhdGNoVGltZXMgPD0gMSkge1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2VzID0gc3Vic2NyaWJlci5fX21lc3NhZ2VzO1xuICAgICAgICAgICAgdGhpcy5vZmYobWVzc2FnZXMsIHN1YnNjcmliZXIpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpc3BhdGNoVGltZXMgPiAxKVxuICAgICAgICAgICAgc3Vic2NyaWJlci5vcHRpb25zLmRpc3BhdGNoVGltZXMtLTtcbiAgICB9XG5cbiAgICBpZiAoc3luY2hybylcbiAgICAgICAgc3Vic2NyaWJlci5zdWJzY3JpYmVyLmNhbGwoc3Vic2NyaWJlci5jb250ZXh0LCBtZXNzYWdlLCBkYXRhLCBjYWxsYmFjayk7XG4gICAgZWxzZVxuICAgICAgICBfLmRlZmVyTWV0aG9kKHN1YnNjcmliZXIuc3Vic2NyaWJlciwgJ2NhbGwnLCBzdWJzY3JpYmVyLmNvbnRleHQsIG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrKTtcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2QuXG4gKiBSZXR1cm5zIHRoZSBhcnJheSBvZiBzdWJzY3JpYmVycyB0aGF0IHdvdWxkIGJlIGNhbGxlZCBpZiB0aGUgbWVzc2FnZSB3ZXJlIGRpc3BhdGNoZWQuXG4gKiBJZiBgaW5jbHVkZVBhdHRlcm5TdWJzY3JpYmVycyA9PT0gZmFsc2VgLCBwYXR0ZXJuIHN1YnNjcmliZXJzIHdpdGggbWF0Y2hpbmcgcGF0dGVycyB3aWxsIG5vdCBiZSBpbmNsdWRlZCAoYnkgZGVmYXVsdCB0aGV5IGFyZSBpbmNsdWRlZCkuXG4gKiBJZiB0aGVyZSBhcmUgbm8gc3Vic2NyaWJlcnMgdG8gdGhlIG1lc3NhZ2UsIGB1bmRlZmluZWRgIHdpbGwgYmUgcmV0dXJuZWQsIG5vdCBhbiBlbXB0eSBhcnJheSwgc28gaXQgaXMgc2FmZSB0byB1c2UgdGhlIHJlc3VsdCBpbiBib29sZWFuIHRlc3RzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbWVzc2FnZSBNZXNzYWdlIHRvIGdldCBzdWJzY3JpYmVycyBmb3IuXG4gKiAgSWYgdGhlIG1lc3NhZ2UgaXMgUmVnRXhwLCBvbmx5IHBhdHRlcm4gc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIGV4YWN0bHkgdGhpcyBwYXR0ZXJuIHdpbGwgYmUgcmV0dXJuZWQuXG4gKiAgSWYgdGhlIG1lc3NhZ2UgaXMgU3RyaW5nLCBzdWJzY3JpYmVycyByZWdpc3RlcmVkIHdpdGggdGhlIHN0cmluZyBtZXNzYWdlcyBhbmQgcGF0dGVybiBzdWJzY3JpYmVycyByZWdpc3RlcmVkIHdpdGggbWF0Y2hpbmcgcGF0dGVybiB3aWxsIGJlIHJldHVybmVkICh1bmxlc3MgdGhlIHNlY29uZCBwYXJhbWV0ZXIgaXMgZmFsc2UpLlxuICogQHBhcmFtIHtCb29sZWFufSBpbmNsdWRlUGF0dGVyblN1YnNjcmliZXJzIE9wdGlvbmFsIGZhbHNlIHRvIHByZXZlbnQgaW5jbHVzaW9uIG9mIHBhdHRlciBzdWJzY3JpYmVycywgYnkgZGVmYXVsdCB0aGV5IGFyZSBpbmNsdWRlZC5cbiAqIEByZXR1cm4ge0FycmF5fHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gZ2V0U3Vic2NyaWJlcnMobWVzc2FnZSwgaW5jbHVkZVBhdHRlcm5TdWJzY3JpYmVycykge1xuICAgIGNoZWNrKG1lc3NhZ2UsIE1hdGNoLk9uZU9mKFN0cmluZywgUmVnRXhwKSk7XG5cbiAgICB2YXIgc3Vic2NyaWJlcnNIYXNoID0gdGhpcy5fY2hvb3NlU3Vic2NyaWJlcnNIYXNoKG1lc3NhZ2UpO1xuICAgIHZhciBtc2dTdWJzY3JpYmVycyA9IHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gW10uY29uY2F0KHN1YnNjcmliZXJzSGFzaFttZXNzYWdlXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFtdO1xuXG4gICAgLy8gcGF0dGVybiBzdWJzY3JpYmVycyBhcmUgaW5jdWRlZCBieSBkZWZhdWx0XG4gICAgaWYgKGluY2x1ZGVQYXR0ZXJuU3Vic2NyaWJlcnMgIT09IGZhbHNlICYmIHR5cGVvZiBtZXNzYWdlID09ICdzdHJpbmcnKSB7XG4gICAgICAgIF8uZWFjaEtleSh0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzLFxuICAgICAgICAgICAgZnVuY3Rpb24ocGF0dGVyblN1YnNjcmliZXJzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBhdHRlcm4gPSBwYXR0ZXJuU3Vic2NyaWJlcnMucGF0dGVybjtcbiAgICAgICAgICAgICAgICBpZiAocGF0dGVyblN1YnNjcmliZXJzICYmIHBhdHRlcm5TdWJzY3JpYmVycy5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIHBhdHRlcm4udGVzdChtZXNzYWdlKSlcbiAgICAgICAgICAgICAgICAgICAgXy5hcHBlbmRBcnJheShtc2dTdWJzY3JpYmVycywgcGF0dGVyblN1YnNjcmliZXJzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gdW5kZWZpbmVkIGlmIHRoZXJlIGFyZSBubyBzdWJzY3JpYmVyc1xuICAgIHJldHVybiBtc2dTdWJzY3JpYmVycy5sZW5ndGhcbiAgICAgICAgICAgICAgICA/IG1zZ1N1YnNjcmliZXJzXG4gICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG59XG5cblxuLyoqXG4gKiBcIlByaXZhdGVcIiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHRoZSBtYXAgb2Ygc3Vic2NyaWJlcnMgZm9yIGEgZ2l2ZW4gbWVzc2FnZSB0eXBlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IG1lc3NhZ2UgTWVzc2FnZSB0byBjaG9vc2UgdGhlIG1hcCBvZiBzdWJzY3JpYmVycyBmb3JcbiAqIEByZXR1cm4ge09iamVjdFtGdW5jdGlvbl19XG4gKi9cbmZ1bmN0aW9uIF9jaG9vc2VTdWJzY3JpYmVyc0hhc2gobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlIGluc3RhbmNlb2YgUmVnRXhwXG4gICAgICAgICAgICAgICAgPyB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzXG4gICAgICAgICAgICAgICAgOiB0aGlzLl9tZXNzYWdlU3Vic2NyaWJlcnM7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBTZXRzIFtNZXNzYWdlU291cmNlXSguL21fc291cmNlLmpzLmh0bWwpIGZvciB0aGUgbWVzc2VuZ2VyIGFsc28gc2V0dGluZyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBtZXNzZW5nZXIgaW4gdGhlIE1lc3NhZ2VTb3VyY2UuXG4gKiBNZXNzYWdlU291cmNlIGNhbiBiZSBwYXNzZWQgdG8gbWVzc2FnZSBjb25zdHJ1Y3RvcjsgdGhpcyBtZXRob2QgYWxsb3dzIHRvIHNldCBpdCBhdCBhIGxhdGVyIHRpbWUuIEZvciBleGFtcGxlLCB0aGUgc3ViY2xhc3NlcyBvZiBbQ29tcG9uZW50RmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldC5qcy5odG1sKSB1c2UgdGhpcyBtZXRob2QgdG8gc2V0IGRpZmZlcmVudCBNZXNzYWdlU291cmNlJ2VzIGluIHRoZSBtZXNzZW5nZXIgdGhhdCBpcyBjcmVhdGVkIGJ5IENvbXBvbmVudEZhY2V0LlxuICogQ3VycmVudGx5IHRoZSBtZXRob2QgaXMgaW1wbGVtZW50ZWQgaW4gc3VjaCB3YXkgdGhhdCBpdCBjYW4gYmUgY2FsbGVkIG9ubHkgb25jZSAtIE1lc3NhZ2VTb3VyY2UgY2Fubm90IGJlIGNoYW5nZWQgYWZ0ZXIgdGhpcyBtZXRob2QgaXMgY2FsbGVkLlxuICpcbiAqIEBwYXJhbSB7TWVzc2FnZVNvdXJjZX0gbWVzc2FnZVNvdXJjZSBhbiBpbnN0YW5jZSBvZiBNZXNzYWdlU291cmNlIGNsYXNzIHRvIGF0dGFjaCB0byB0aGlzIG1lc3NlbmdlciAoYW5kIHRvIGhhdmUgdGhpcyBtZXNzZW5nZXIgYXR0YWNoZWQgdG8gaXQgdG9vKVxuICovXG5mdW5jdGlvbiBfc2V0TWVzc2FnZVNvdXJjZShtZXNzYWdlU291cmNlKSB7XG4gICAgY2hlY2sobWVzc2FnZVNvdXJjZSwgTWVzc2FnZVNvdXJjZSk7XG5cbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfbWVzc2FnZVNvdXJjZScsIG1lc3NhZ2VTb3VyY2UpO1xuICAgIG1lc3NhZ2VTb3VyY2UubWVzc2VuZ2VyID0gdGhpcztcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgbWVzc2VuZ2VyIE1lc3NhZ2VTb3VyY2VcbiAqXG4gKiBAcmV0dXJuIHtNZXNzYWdlU291cmNlfVxuICovXG5mdW5jdGlvbiBnZXRNZXNzYWdlU291cmNlKCkge1xuICAgIHJldHVybiB0aGlzLl9tZXNzYWdlU291cmNlXG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNZXNzZW5nZXJBUEk7XG5cblxuLyoqXG4gKiBgbWlsby5jbGFzc2VzLk1lc3NlbmdlckFQSWBcbiAqIEJhc2UgY2xhc3MsIHN1YmNsYXNzZXMgb2Ygd2hpY2ggY2FuIHN1cHBsZW1lbnQgdGhlIGZ1bmN0aW9uYWxpdHkgb2YgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgYnkgaW1wbGVtZW50aW5nIHRocmVlIG1ldGhvZHM6XG4gKlxuICogLSBgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlYCB0byB0cmFuc2xhdGUgc291cmNlIG1lc3NhZ2VzIChyZWNpZXZlZCBmcm9tIGV4dGVybmFsIHNvdXJjZSB2aWEgYE1lc3NhZ2VTT3VyY2VgKSB0byBpbnRlcm5hbCBtZXNzYWdlcyAodGhhdCBhcmUgZGlzcGF0Y2hlZCBvbiBNZXNzZW5nZXIpLCBhbGxvd2luZyB0byBtYWtlIGludGVybmFsIG1lc3NhZ2VzIG1vcmUgZGV0YWlsZWQgdGhhbiBzb3VyY2UgbWVzc2FnZXMuIEZvciBleGFtcGxlLCBbRGF0YSBmYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0cy9EYXRhLmpzLmh0bWwpIHVzZXMgW0RhdGFNc2dBUEldKC4uL2NvbXBvbmVudHMvbXNnX2FwaS9kYXRhLmpzLmh0bWwpIHRvIGRlZmluZSBzZXZlcmFsIGludGVybmFsIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gdGhlIGNoYW5nZSBvZiBzdGF0ZSBpbiBjb250ZW50ZWRpdGFibGUgRE9NIGVsZW1lbnQuXG4gKiAtIGBjcmVhdGVJbnRlcm5hbERhdGFgIHRvIG1vZGlmeSBtZXNzYWdlIGRhdGEgcmVjZWl2ZWQgZnJvbSBzb3VyY2UgdG8gc29tZSBtb3JlIG1lYW5pbmdmdWwgb3IgbW9yZSBkZXRhaWxlZCBtZXNzYWdlIGRhdGEgdGhhdCB3aWxsIGJlIGRpc3BhdGNoZWQgb24gTWVzc2VuZ2VyLiBGb3IgZXhhbXBsZSwgW0RhdGEgZmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldHMvRGF0YS5qcy5odG1sKSB1c2VzIFtEYXRhTXNnQVBJXSguLi9jb21wb25lbnRzL21zZ19hcGkvZGF0YS5qcy5odG1sKSAoc3ViY2xhc3Mgb2YgTWVzc2VuZ2VyQVBJKSB0byB0cmFuc2xhdGUgRE9NIG1lc3NhZ2VzIHRvIGRhdGEgY2hhbmdlIG1lc3NhZ2VzLlxuICogLSBgZmlsdGVyU291cmNlTWVzc2FnZWAgdG8gZW5hYmxlL2Rpc2FibGUgbWVzc2FnZSBkaXNwYXRjaCBiYXNlZCBvbiBzb21lIGNvbmRpdGlvbnMgaW4gZGF0YS5cbiAqXG4gKiBJZiBgTWVzc2FnZVNvdXJjZWAgY29uc3RydWN0b3IgaXMgbm90IHBhc3NlZCBhbiBpbnN0YW5jZSBvZiBzb21lIHN1YmNsYXNzIG9mIGBNZXNzZW5nZXJBUElgLCBpdCBhdXRvbWF0aWNhbGx5IGNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgTWVzc2VuZ2VyQVBJIHRoYXQgZGVmaW5lcyBhbGwgMyBvZiB0aG9zZSBtZXRob2RzIGluIGEgdHJpdmlhbCB3YXkuIFNlZSB0aGVzZSBtZXRob2RzIGJlbG93IGZvciB0aGVpciBzaWduYXR1cmVzLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHRoaXMge01lc3NlbmdlckFQSX1cbiAqIEByZXR1cm4ge01lc3NlbmdlckFQSX1cbiAqL1xuZnVuY3Rpb24gTWVzc2VuZ2VyQVBJKCkge1xuICAgIGlmICh0aGlzLmluaXQpXG4gICAgICAgIHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogIyMjI01lc3NlbmdlckFQSSBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2luaXRdKCNpbml0KSAtIGluaXRpYWxpemVzIE1lc3NlbmdlckFQSVxuICogLSBbYWRkSW50ZXJuYWxNZXNzYWdlXSgjYWRkSW50ZXJuYWxNZXNzYWdlKSAtIGFkZHMgaW50ZXJuYWwgbWVzc2FnZVxuICogLSBbcmVtb3ZlSW50ZXJuYWxNZXNzYWdlXSgjcmVtb3ZlSW50ZXJuYWxNZXNzYWdlKSAtIHJlbW92ZXMgaW50ZXJuYWwgbWVzc2FnZVxuICogLSBbZ2V0SW50ZXJuYWxNZXNzYWdlc10oI2dldEludGVybmFsTWVzc2FnZXMpIC0gcmV0dXJucyB0aGUgbGlzdCBvZiBpbnRlcm5hbCBtZXNzYWdlcyBmb3IgZ2l2ZW4gc291cmNlIG1lc3NhZ2VcbiAqXG4gKiBUaGVzZSBtZXRob2RzIHNob3VsZCBiZSByZWRlZmluZWQgYnkgc3ViY2xhc3M6XG4gKlxuICogLSBbdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlXSgjdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKSAtIGNvbnZlcnRzIGludGVybmFsIG1lc3NhZ2UgdHlwZSB0byBzb3VyY2UgKGV4dGVybmFsKSBtZXNzYWdlIHR5cGVcbiAqIC0gW2NyZWF0ZUludGVybmFsRGF0YV0oI2NyZWF0ZUludGVybmFsRGF0YSkgLSBjb252ZXJ0cyBzb3VyY2UgbWVzc2FnZSBkYXRhIHJlY2VpdmVkIHZpYSBNZXNzYWdlU291cmNlIHRvIGludGVybmFsIG1lc3NhZ2UgZGF0YVxuICogLSBbZmlsdGVyU291cmNlTWVzc2FnZV0oI2ZpbHRlclNvdXJjZU1lc3NhZ2UpIC0gZmlsdGVycyBzb3VyY2UgbWVzc2FnZSBiYXNlZCBvbiB0aGUgZGF0YSBvZiB0aGUgbWVzc2FnZSBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgaW50ZXJuYWwgbWVzc2FnZSB0aGF0IGlzIGFib3V0IHRvIGJlIHNlbnQgb24gTWVzc2VuZ2VyXG4gKi9cbl8uZXh0ZW5kUHJvdG8oTWVzc2VuZ2VyQVBJLCB7XG4gICAgaW5pdDogaW5pdCxcbiAgICBkZXN0cm95OiBNZXNzZW5nZXJBUEkkZGVzdHJveSxcbiAgICBhZGRJbnRlcm5hbE1lc3NhZ2U6IGFkZEludGVybmFsTWVzc2FnZSxcbiAgICByZW1vdmVJbnRlcm5hbE1lc3NhZ2U6IHJlbW92ZUludGVybmFsTWVzc2FnZSxcbiAgICBnZXRJbnRlcm5hbE1lc3NhZ2VzOiBnZXRJbnRlcm5hbE1lc3NhZ2VzLFxuXG4gICAgLy8gc2hvdWxkIGJlIHJlZGVmaW5lZCBieSBzdWJjbGFzc1xuICAgIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZTogdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlLFxuICAgIGNyZWF0ZUludGVybmFsRGF0YTogY3JlYXRlSW50ZXJuYWxEYXRhLFxuICAgIGZpbHRlclNvdXJjZU1lc3NhZ2U6IGZpbHRlclNvdXJjZU1lc3NhZ2Vcbn0pO1xuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQ2FsbGVkIGJ5IE1lc3NlbmdlckFQSSBjb25zdHJ1Y3Rvci4gU3ViY2xhc3NlcyB0aGF0IHJlLWltcGxlbWVudCBgaW5pdGAgbWV0aG9kIHNob3VsZCBjYWxsIHRoaXMgbWV0aG9kIHVzaW5nOiBgTWVzc2VuZ2VyQVBJLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cylgXG4gKi9cbmZ1bmN0aW9uIGluaXQoKSB7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2ludGVybmFsTWVzc2FnZXMnLCB7fSk7XG59XG5cblxuLyoqXG4gKiBEZXN0cm95cyBtZXNzZW5nZXIgQVBJXG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlckFQSSRkZXN0cm95KCkge1xuXG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXJBUEkgaW5zdGFuY2UgbWV0aG9kXG4gKiBUcmFuc2xhdGVzIGludGVybmFsIGBtZXNzYWdlYCB0byBzb3VyY2UgbWVzc2FnZSwgYWRkcyBpbnRlcm5hbCBgbWVzc2FnZWAgdG8gdGhlIGxpc3QsIG1ha2luZyBzdXJlIHRoZSBzYW1lIGBtZXNzYWdlYCB3YXNuJ3QgcGFzc2VkIGJlZm9yZSAoaXQgd291bGQgaW5kaWNhdGUgTWVzc2VuZ2VyIGVycm9yKS5cbiAqIFJldHVybnMgc291cmNlIG1lc3NhZ2UgaWYgaXQgaXMgdXNlZCBmaXJzdCB0aW1lIChzbyB0aGF0IGBNZXNzYWdlU291cmNlYCBzdWJjcmliZXMgdG8gdGhpcyBzb3VyY2UgbWVzc2FnZSkgb3IgYHVuZGVmaW5lZGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgaW50ZXJuYWwgbWVzc2FnZSB0byBiZSB0cmFuc2xhdGVkIGFuZCBhZGRlZFxuICogQHJldHVybiB7U3RyaW5nfHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gYWRkSW50ZXJuYWxNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICB2YXIgaW50ZXJuYWxNc2dzXG4gICAgICAgICwgc291cmNlTWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpO1xuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2VNZXNzYWdlID09ICd1bmRlZmluZWQnKSByZXR1cm47XG5cbiAgICBpZiAodGhpcy5faW50ZXJuYWxNZXNzYWdlcy5oYXNPd25Qcm9wZXJ0eShzb3VyY2VNZXNzYWdlKSkge1xuICAgICAgICBpbnRlcm5hbE1zZ3MgPSB0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdO1xuICAgICAgICBpZiAoaW50ZXJuYWxNc2dzLmluZGV4T2YobWVzc2FnZSkgPT0gLTEpXG4gICAgICAgICAgICBpbnRlcm5hbE1zZ3MucHVzaChtZXNzYWdlKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0R1cGxpY2F0ZSBhZGRJbnRlcm5hbE1lc3NhZ2UgY2FsbCBmb3IgaW50ZXJuYWwgbWVzc2FnZSAnICsgbWVzc2FnZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaW50ZXJuYWxNc2dzID0gdGhpcy5faW50ZXJuYWxNZXNzYWdlc1tzb3VyY2VNZXNzYWdlXSA9IFtdO1xuICAgICAgICBpbnRlcm5hbE1zZ3MucHVzaChtZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuIHNvdXJjZU1lc3NhZ2U7XG4gICAgfVxufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogUmVtb3ZlcyBpbnRlcm5hbCBgbWVzc2FnZWAgZnJvbSB0aGUgbGlzdCBjb25uZWN0ZWQgdG8gY29ycmVzcG9uZGluZyBzb3VyY2UgbWVzc2FnZSAoYHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZWAgaXMgdXNlZCBmb3IgdHJhbnNsYXRpb24pLlxuICogUmV0dXJucyBzb3VyY2UgbWVzc2FnZSwgaWYgdGhlIGxhc3QgaW50ZXJuYWwgbWVzc2FnZSB3YXMgcmVtb3ZlZCAoc28gdGhhdCBgTWVzc2FnZVNvdXJjZWAgY2FuIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBzb3VyY2UgbWVzc2FnZSksIG9yIGB1bmRlZmluZWRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIG1lc3NhZ2UgdG8gYmUgdHJhbnNsYXRlZCBhbmQgcmVtb3ZlZFxuICogQHJldHVybiB7U3RyaW5nfHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlSW50ZXJuYWxNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICB2YXIgc291cmNlTWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpO1xuXG4gICAgaWYgKHR5cGVvZiBzb3VyY2VNZXNzYWdlID09ICd1bmRlZmluZWQnKSByZXR1cm47XG5cbiAgICB2YXIgaW50ZXJuYWxNc2dzID0gdGhpcy5faW50ZXJuYWxNZXNzYWdlc1tzb3VyY2VNZXNzYWdlXTtcblxuICAgIGlmIChpbnRlcm5hbE1zZ3MgJiYgaW50ZXJuYWxNc2dzLmxlbmd0aCkge1xuICAgICAgICB2YXIgbWVzc2FnZUluZGV4ID0gaW50ZXJuYWxNc2dzLmluZGV4T2YobWVzc2FnZSk7XG4gICAgICAgIGlmIChtZXNzYWdlSW5kZXggPj0gMCkge1xuICAgICAgICAgICAgaW50ZXJuYWxNc2dzLnNwbGljZShtZXNzYWdlSW5kZXgsIDEpO1xuICAgICAgICAgICAgaWYgKGludGVybmFsTXNncy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdO1xuICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2VNZXNzYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgIHVuZXhwZWN0ZWROb3RpZmljYXRpb25XYXJuaW5nKCk7XG4gICAgfSBlbHNlXG4gICAgICAgIHVuZXhwZWN0ZWROb3RpZmljYXRpb25XYXJuaW5nKCk7XG5cblxuICAgIGZ1bmN0aW9uIHVuZXhwZWN0ZWROb3RpZmljYXRpb25XYXJuaW5nKCkge1xuICAgICAgICBsb2dnZXIud2Fybignbm90aWZpY2F0aW9uIHJlY2VpdmVkOiB1bi1zdWJzY3JpYmUgZnJvbSBpbnRlcm5hbCBtZXNzYWdlICcgKyBtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICArICcgd2l0aG91dCBwcmV2aW91cyBzdWJzY3JpcHRpb24gbm90aWZpY2F0aW9uJyk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyB0aGUgYXJyYXkgb2YgaW50ZXJuYWwgbWVzc2FnZXMgdGhhdCB3ZXJlIHRyYW5zbGF0ZWQgdG8gZ2l2ZW4gYHNvdXJjZU1lc3NhZ2VgLlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBieSBgTWVzc2FnZVNvdXJjZWAgdG8gZGlzcGF0Y2ggc291cmNlIG1lc3NhZ2Ugb24gdGhlIGBNZXNlbmdlcmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNvdXJjZU1lc3NhZ2Ugc291cmNlIG1lc3NhZ2VcbiAqIEByZXR1cm4ge0FycmF5W1N0cmluZ119XG4gKi9cbmZ1bmN0aW9uIGdldEludGVybmFsTWVzc2FnZXMoc291cmNlTWVzc2FnZSkge1xuICAgIHJldHVybiB0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogU3ViY2xhc3NlcyBzaG91bGQgcmUtaW1wbGVtZW50IHRoaXMgbWV0aG9kIHRvIGRlZmluZSB0aGUgcnVsZSBmb3IgdHJhbnNsYXRpb24gb2YgaW50ZXJuYWwgYG1lc3NhZ2VgIHRvIHNvdXJjZSBtZXNzYWdlLiBUaGlzIGNsYXNzIHNpbXBseSByZXR1cm5zIHRoZSBzYW1lIGBtZXNzYWdlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBpbnRlcm5hbCBtZXNzYWdlIHRvIGJlIHRyYW5zbGF0ZWRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbWVzc2FnZVxufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogU3ViY2xhc3NlcyBzaG91bGQgcmUtaW1wbGVtZW50IHRoaXMgbWV0aG9kIHRvIGRlZmluZSB0aGUgcnVsZSBmb3IgdHJhbnNsYXRpb24gb2Ygc291cmNlIG1lc3NhZ2UgZGF0YSB0byBpbnRlcm5hbCBtZXNzYWdlIGRhdGEuIFRoaXMgY2xhc3Mgc2ltcGx5IHJldHVybnMgdGhlIHNhbWUgYHNvdXJjZURhdGFgLlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBpbiBbZGlzcGF0Y2hNZXNzYWdlXSguL21fc291cmNlLmpzLmh0bWwjZGlzcGF0Y2hNZXNzYWdlKSBtZXRob2Qgb2YgYE1lc3NhZ2VTb3VyY2VgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzb3VyY2VNZXNzYWdlIHNvdXJjZSBtZXNzYWdlLCBjYW4gYmUgdXNlZCBpbiB0cmFuc2xhdGlvbiBydWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBpbnRlcm5hbCBtZXNzYWdlLCBjYW4gYmUgdXNlZCBpbiB0cmFuc2xhdGlvbiBydWxlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlRGF0YSBkYXRhIHJlY2VpdmVkIGZyb20gc291cmNlIHRoYXQgaGFzIHRvIGJlIHRyYW5zbGF0ZWQgdG8gZGF0YSB0aGF0IHdpbGwgYmUgc2VudCB0byBpbnRlcm5hbCBNZXNzZW5nZXIgc3Vic2NyaWJlclxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBjcmVhdGVJbnRlcm5hbERhdGEoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgc291cmNlRGF0YSkge1xuICAgIHJldHVybiBzb3VyY2VEYXRhO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyQVBJIGluc3RhbmNlIG1ldGhvZFxuICogU3ViY2xhc3NlcyBzaG91bGQgcmUtaW1wbGVtZW50IHRoaXMgbWV0aG9kIHRvIGRlZmluZSB0aGUgZGlzcGF0Y2ggZmlsdGVyIGZvciBpbnRlcm5hbCBtZXNzYWdlcy4gVGhpcyBtZXRob2Qgc2hvdWxkIHJldHVybiBgdHJ1ZWAgdG8gYWxsb3cgYW5kIGBmYWxzZWAgdG8gcHJldmVudCBpbnRlcm5hbCBtZXNzYWdlIGRpc3BhdGNoLiBUaGlzIGNsYXNzIGFsd2F5cyByZXR1cm5zIGB0cnVlYC5cbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW4gW2Rpc3BhdGNoTWVzc2FnZV0oLi9tX3NvdXJjZS5qcy5odG1sI2Rpc3BhdGNoTWVzc2FnZSkgbWV0aG9kIG9mIGBNZXNzYWdlU291cmNlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc291cmNlTWVzc2FnZSBzb3VyY2UgbWVzc2FnZSwgY2FuIGJlIHVzZWQgaW4gZmlsdGVyIHJ1bGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIG1lc3NhZ2UsIGNhbiBiZSB1c2VkIGluIGZpbHRlciBydWxlXG4gKiBAcGFyYW0ge09iamVjdH0gaW50ZXJuYWxEYXRhIGRhdGEgdHJhbnNsYXRlZCBieSBgY3JlYXRlSW50ZXJuYWxEYXRhYCBtZXRob2QgZnJvbSBzb3VyY2UgZGF0YSwgY2FuIGJlIHVzZWQgaW4gZmlsdGVyIHJ1bGVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGZpbHRlclNvdXJjZU1lc3NhZ2Uoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgaW50ZXJuYWxEYXRhKSB7XG4gICAgcmV0dXJuIHRydWU7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNZXNzZW5nZXJBUEkgPSByZXF1aXJlKCcuL21fYXBpJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIEEgZ2VuZXJpYyBzdWJzY2xhc3Mgb2YgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSB0aGF0IHN1cHBvcnRzIHBhdHRlcm4gc3Vic2NyaXB0aW9ucyB0byBzb3VyY2UuXG4gKiBDYW4gYmUgdXNlZnVsIGlmIHRoZSBzb3VyY2UgaXMgYW5vdGhlciBNZXNzZW5nZXIuXG4gKi9cbiB2YXIgTWVzc2VuZ2VyUmVnZXhwQVBJID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzZW5nZXJBUEksICdNZXNzZW5nZXJSZWdleHBBUEknKTtcblxuIG1vZHVsZS5leHBvcnRzID0gTWVzc2VuZ2VyUmVnZXhwQVBJO1xuXG5cbl8uZXh0ZW5kUHJvdG8oTWVzc2VuZ2VyUmVnZXhwQVBJLCB7XG4gICAgaW5pdDogaW5pdCxcbiAgICBhZGRJbnRlcm5hbE1lc3NhZ2U6IGFkZEludGVybmFsTWVzc2FnZSxcbiAgICByZW1vdmVJbnRlcm5hbE1lc3NhZ2U6IHJlbW92ZUludGVybmFsTWVzc2FnZSxcbiAgICBnZXRJbnRlcm5hbE1lc3NhZ2VzOiBnZXRJbnRlcm5hbE1lc3NhZ2VzXG59KTtcblxuXG4vKipcbiAqIE1lc3NlbmdlclJlZ2V4cEFQSSBpbnN0YW5jZSBtZXRob2RcbiAqIENhbGxlZCBieSBNZXNzZW5nZXJSZWdleHBBUEkgY29uc3RydWN0b3IuXG4gKi9cbmZ1bmN0aW9uIGluaXQoKSB7XG4gICAgTWVzc2VuZ2VyQVBJLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgXy5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHtcbiAgICAgICAgX3BhdHRlcm5JbnRlcm5hbE1lc3NhZ2VzOiB7fVxuICAgIH0pO1xuICAgIHRoaXMuX2NhdGNoQWxsU3Vic2NyaWJlZCA9IGZhbHNlO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyUmVnZXhwQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQXVnbWVudHMgTWVzc2VuZ2VyQVBJIG1ldGhvZCBieSBzdG9yaW5nIHJlZ2V4cFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIG1lc3NhZ2UgdG8gYmUgdHJhbnNsYXRlZCBhbmQgYWRkZWRcbiAqIEByZXR1cm4ge1N0cmluZ3xSZWdFeHB8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBhZGRJbnRlcm5hbE1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHZhciBzb3VyY2VNZXNzYWdlID0gTWVzc2VuZ2VyQVBJLnByb3RvdHlwZS5hZGRJbnRlcm5hbE1lc3NhZ2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBcbiAgICAvLyBzdG9yZSByZWdleHAgaXRzZWxmIGlmIHNvdXJjZU1lc3NhZ2UgaXMgcmVnZXhwXG4gICAgaWYgKHNvdXJjZU1lc3NhZ2UgJiYgc291cmNlTWVzc2FnZSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICB0aGlzLl9pbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdLnBhdHRlcm4gPSBzb3VyY2VNZXNzYWdlO1xuICAgICAgICB0aGlzLl9wYXR0ZXJuSW50ZXJuYWxNZXNzYWdlc1tzb3VyY2VNZXNzYWdlXSA9IHRoaXMuX2ludGVybmFsTWVzc2FnZXNbc291cmNlTWVzc2FnZV07XG4gICAgICAgIGlmICh0aGlzLl9jYXRjaEFsbFN1YnNjcmliZWQpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMuX2NhdGNoQWxsU3Vic2NyaWJlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiAvLiovO1xuICAgIH1cblxuICAgIHJldHVybiBzb3VyY2VNZXNzYWdlO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyUmVnZXhwQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQXVnbWVudHMgTWVzc2VuZ2VyQVBJIG1ldGhvZCBieSByZW1vdmluZyByZWdleHAgc3Vic2NpcnB0aW9uXG4gKiBcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIG1lc3NhZ2UgdG8gYmUgdHJhbnNsYXRlZCBhbmQgYWRkZWRcbiAqIEByZXR1cm4ge1N0cmluZ3xSZWdFeHB8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiByZW1vdmVJbnRlcm5hbE1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHZhciBzb3VyY2VNZXNzYWdlID0gTWVzc2VuZ2VyQVBJLnByb3RvdHlwZS5yZW1vdmVJbnRlcm5hbE1lc3NhZ2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIGlmIChzb3VyY2VNZXNzYWdlICYmIHNvdXJjZU1lc3NhZ2UgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuX3BhdHRlcm5JbnRlcm5hbE1lc3NhZ2VzW3NvdXJjZU1lc3NhZ2VdO1xuICAgICAgICB2YXIgbm9QYXR0ZXJuSW50ZXJuYWxNZXNzYWdlcyA9ICEgT2JqZWN0LmtleXModGhpcy5fcGF0dGVybkludGVybmFsTWVzc2FnZXMpLmxlbmd0aDtcbiAgICAgICAgaWYgKG5vUGF0dGVybkludGVybmFsTWVzc2FnZXMpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhdGNoQWxsU3Vic2NyaWJlZCA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIC8uKi87XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlTWVzc2FnZTtcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlckFQSSBpbnN0YW5jZSBtZXRob2RcbiAqIEF1Z21lbnRzIE1lc3NlbmdlckFQSSBtZXRob2QgYnkgcmV0dXJuaW5nIG1lc3NhZ2VzIHN1YnNjcmliZWQgd2l0aCByZWdleHBcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgYnkgYE1lc3NhZ2VTb3VyY2VgIHRvIGRpc3BhdGNoIHNvdXJjZSBtZXNzYWdlIG9uIHRoZSBgTWVzZW5nZXJgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gc291cmNlTWVzc2FnZSBzb3VyY2UgbWVzc2FnZVxuICogQHJldHVybiB7QXJyYXlbU3RyaW5nXX1cbiAqL1xuZnVuY3Rpb24gZ2V0SW50ZXJuYWxNZXNzYWdlcyhzb3VyY2VNZXNzYWdlKSB7XG4gICAgdmFyIGludGVybmFsTWVzc2FnZXMgPSBNZXNzZW5nZXJBUEkucHJvdG90eXBlLmdldEludGVybmFsTWVzc2FnZXMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIC8vIGFkZCBpbnRlcm5hbCBtZXNzYWdlcyBmb3IgcmVnZXhwIHNvdXJjZSBzdWJzY3JpcHRpb25zXG4gICAgaWYgKHR5cGVvZiBzb3VyY2VNZXNzYWdlID09ICdzdHJpbmcnKSB7XG4gICAgICAgIGludGVybmFsTWVzc2FnZXMgPSBpbnRlcm5hbE1lc3NhZ2VzIHx8IFtdO1xuICAgICAgICB2YXIgaW50ZXJuYWxNZXNzYWdlc0hhc2ggPSBfLm9iamVjdChpbnRlcm5hbE1lc3NhZ2VzLCB0cnVlKTtcblxuICAgICAgICBfLmVhY2hLZXkodGhpcy5fcGF0dGVybkludGVybmFsTWVzc2FnZXMsIGZ1bmN0aW9uKHBhdHRlcm5NZXNzYWdlcykge1xuICAgICAgICAgICAgdmFyIHNvdXJjZVBhdHRlcm4gPSBwYXR0ZXJuTWVzc2FnZXMucGF0dGVybjtcblxuICAgICAgICAgICAgaWYgKHNvdXJjZVBhdHRlcm4udGVzdChzb3VyY2VNZXNzYWdlKSlcbiAgICAgICAgICAgICAgICBwYXR0ZXJuTWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnRlcm5hbE1lc3NhZ2VzSGFzaFttZXNzYWdlXSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbE1lc3NhZ2VzLnB1c2gobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIGludGVybmFsTWVzc2FnZXNIYXNoW21lc3NhZ2VdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSBcblxuICAgIHJldHVybiBpbnRlcm5hbE1lc3NhZ2VzO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTWl4aW4gPSByZXF1aXJlKCcuLi9hYnN0cmFjdC9taXhpbicpXG4gICAgLCBNZXNzZW5nZXJBUEkgPSByZXF1aXJlKCcuL21fYXBpJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIHRvQmVJbXBsZW1lbnRlZCA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS50b0JlSW1wbGVtZW50ZWRcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxuLyoqXG4gKiBgbWlsby5jbGFzc2VzLk1lc3NhZ2VTb3VyY2VgXG4gKiBBbiBhYnN0cmFjdCBjbGFzcyAoc3ViY2xhc3Mgb2YgW01peGluXSguLi9hYnN0cmFjdC9taXhpbi5qcy5odG1sKSkgZm9yIGNvbm5lY3RpbmcgW01lc3Nlbmdlcl0oLi9pbmRleC5qcy5odG1sKSB0byBleHRlcm5hbCBzb3VyY2VzIG9mIG1lc3NhZ2VzIChsaWtlIERPTSBldmVudHMpIGFuZCBkZWZpbmluZyBoaWdoZXIgbGV2ZWwgbWVzc2FnZXMuXG4gKiBBbiBpbnN0YW5jZSBvZiBNZXNzYWdlU291cmNlIGNhbiBlaXRoZXIgYmUgcGFzc2VkIHRvIE1lc3NlbmdlciBjb25zdHJ1Y3RvciBvciBsYXRlciB1c2luZyBgX3NldE1lc3NhZ2VTb3VyY2VgIG1ldGhvZCBvZiBNZXNzZW5nZXIuIE9uY2Ugc2V0LCBNZXNzYWdlU291cmNlIG9mIE1lc3NlbmdlciBjYW5ub3QgYmUgY2hhbmdlZC5cbiAqL1xudmFyIE1lc3NhZ2VTb3VyY2UgPSBfLmNyZWF0ZVN1YmNsYXNzKE1peGluLCAnTWVzc2FnZVNvdXJjZScsIHRydWUpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1lc3NhZ2VTb3VyY2U7XG5cblxuLyoqXG4gKiAjIyMjTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW2luaXRdKCNpbml0KSAtIGluaXRpYWxpemVzIG1lc3NhZ2VTb3VyY2UgLSBjYWxsZWQgYnkgTWl4aW4gc3VwZXJjbGFzc1xuICogLSBbc2V0TWVzc2VuZ2VyXSgjc2V0TWVzc2VuZ2VyKSAtIGNvbm5lY3RzIE1lc3NlbmdlciB0byBNZXNzYWdlU291cmNlLCBpcyBjYWxsZWQgZnJvbSBgaW5pdGAgb3IgYF9zZXRNZXNzYWdlU291cmNlYCBtZXRob2RzIG9mIFtNZXNzZW5nZXJdKC4vaW5kZXguanMuaHRtbCkuXG4gKiAtIFtvblN1YnNjcmliZXJBZGRlZF0oI29uU3Vic2NyaWJlckFkZGVkKSAtIGNhbGxlZCBieSBNZXNzZW5nZXIgdG8gbm90aWZ5IHdoZW4gdGhlIGZpcnN0IHN1YnNjcmliZXIgZm9yIGFuIGludGVybmFsIG1lc3NhZ2Ugd2FzIGFkZGVkLCBzbyBNZXNzYWdlU291cmNlIGNhbiBzdWJzY3JpYmUgdG8gc291cmNlXG4gKiAtIFtvblN1YnNjcmliZXJSZW1vdmVkXSgjb25TdWJzY3JpYmVyUmVtb3ZlZCkgLSBjYWxsZWQgYnkgTWVzc2VuZ2VyIHRvIG5vdGlmeSB3aGVuIHRoZSBsYXN0IHN1YnNjcmliZXIgZm9yIGFuIGludGVybmFsIG1lc3NhZ2Ugd2FzIHJlbW92ZWQsIHNvIE1lc3NhZ2VTb3VyY2UgY2FuIHVuc3Vic2NyaWJlIGZyb20gc291cmNlXG4gKiAtIFtkaXNwYXRjaE1lc3NhZ2VdKCNkaXNwYXRjaE1lc3NhZ2UpIC0gZGlzcGF0Y2hlcyBzb3VyY2UgbWVzc2FnZS4gTWVzc2FnZVNvdXJjZSBzdWJjbGFzcyBzaG91bGQgaW1wbGVtZW50IG1lY2hhbmlzbSB3aGVuIG9uIGFjdHVhbCBzb3VyY2UgbWVzc2FnZSB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuXG4gKlxuICogTWV0aG9kcyBiZWxvdyBzaG91bGQgYmUgaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3M6XG4gKlxuICogLSBbdHJpZ2dlcl0oI3RyaWdnZXIpIC0gdHJpZ2dlcnMgbWVzc2FnZXMgb24gdGhlIHNvdXJjZSAoYW4gb3B0aW9uYWwgbWV0aG9kKVxuICogLSBbYWRkU291cmNlU3Vic2NyaWJlcl0oI2FkZFNvdXJjZVN1YnNjcmliZXIpIC0gYWRkcyBsaXN0ZW5lci9zdWJzY3JpYmVyIHRvIGV4dGVybmFsIG1lc3NhZ2VcbiAqIC0gW3JlbW92ZVNvdXJjZVN1YnNjcmliZXJdKCNyZW1vdmVTb3VyY2VTdWJzY3JpYmVyKSAtIHJlbW92ZXMgbGlzdGVuZXIvc3Vic2NyaWJlciBmcm9tIGV4dGVybmFsIG1lc3NhZ2VcbiAqL1xuXy5leHRlbmRQcm90byhNZXNzYWdlU291cmNlLCB7XG4gICAgaW5pdDogaW5pdCxcbiAgICBkZXN0cm95OiBNZXNzYWdlU291cmNlJGRlc3Ryb3ksXG4gICAgc2V0TWVzc2VuZ2VyOiBzZXRNZXNzZW5nZXIsXG4gICAgb25TdWJzY3JpYmVyQWRkZWQ6IG9uU3Vic2NyaWJlckFkZGVkLFxuICAgIG9uU3Vic2NyaWJlclJlbW92ZWQ6IG9uU3Vic2NyaWJlclJlbW92ZWQsIFxuICAgIGRpc3BhdGNoTWVzc2FnZTogZGlzcGF0Y2hNZXNzYWdlLFxuICAgIHBvc3RNZXNzYWdlOiBwb3N0TWVzc2FnZSxcbiAgICBfcHJlcGFyZU1lc3NlbmdlckFQSTogX3ByZXBhcmVNZXNzZW5nZXJBUEksXG5cbiAgICAvLyBNZXRob2RzIGJlbG93IG11c3QgYmUgaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3NcbiAgICB0cmlnZ2VyOiB0b0JlSW1wbGVtZW50ZWQsXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogdG9CZUltcGxlbWVudGVkLFxuICAgIHJlbW92ZVNvdXJjZVN1YnNjcmliZXI6IHRvQmVJbXBsZW1lbnRlZFxufSk7XG5cblxuLyoqXG4gKiBNZXNzYWdlU291cmNlIGluc3RhbmNlIG1ldGhvZC5cbiAqIENhbGxlZCBieSBNaXhpbiBjb25zdHJ1Y3Rvci5cbiAqIE1lc3NhZ2VTb3VyY2UgY29uc3RydWN0b3Igc2hvdWxkIGJlIHBhc3NlZCB0aGUgc2FtZSBwYXJhbWV0ZXJzIGFzIHRoaXMgbWV0aG9kIHNpZ25hdHVyZS5cbiAqIElmIGFuIGluc3RhbmNlIG9mIFtNZXNzZW5nZXJBUEldKC4vbV9hcGkuanMuaHRtbCkgaXMgcGFzc2VkIGFzIHRoZSB0aGlyZCBwYXJhbWV0ZXIsIGl0IGV4dGVuZHMgTWVzc2FnZVNvdXJjZSBmdW5jdGlvbmFsaXR5IHRvIGFsbG93IGl0IHRvIGRlZmluZSBuZXcgbWVzc2FnZXMsIHRvIGZpbHRlciBtZXNzYWdlcyBiYXNlZCBvbiB0aGVpciBkYXRhIGFuZCB0byBjaGFuZ2UgbWVzc2FnZSBkYXRhLiBTZWUgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBPcHRpb25hbCBvYmplY3QgdGhhdCBzdG9yZXMgdGhlIE1lc3NhZ2VTb3VyY2Ugb24gb25lIG9mIGl0cyBwcm9wZXJ0aWVzLiBJdCBpcyB1c2VkIHRvIHByb3h5IG1ldGhvZHMgb2YgTWVzc2FnZVNvdXJjZS5cbiAqIEBwYXJhbSB7T2JqZWN0W1N0cmluZ119IHByb3h5TWV0aG9kcyBPcHRpb25hbCBtYXAgb2YgbWV0aG9kIG5hbWVzOyBrZXkgLSBwcm94eSBtZXRob2QgbmFtZSwgdmFsdWUgLSBNZXNzYWdlU291cmNlJ3MgbWV0aG9kIG5hbWUuXG4gKiBAcGFyYW0ge01lc3NlbmdlckFQSX0gbWVzc2VuZ2VyQVBJIE9wdGlvbmFsIGluc3RhbmNlIG9mIE1lc3NlbmdlckFQSS5cbiAqL1xuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NlbmdlckFQSSkge1xuICAgIHRoaXMuX3ByZXBhcmVNZXNzZW5nZXJBUEkobWVzc2VuZ2VyQVBJKTtcbn1cblxuXG4vKipcbiAqIERlc3Ryb3lzIG1lc3NhZ2Ugc291cmNlXG4gKi9cbmZ1bmN0aW9uIE1lc3NhZ2VTb3VyY2UkZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5tZXNzZW5nZXJBUEkpXG4gICAgICAgIHRoaXMubWVzc2VuZ2VyQVBJLmRlc3Ryb3koKTtcbn1cblxuXG4vKipcbiAqIE1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kLlxuICogU2V0cyByZWZlcmVuY2UgdG8gTWVzc2VuZ2VyIGluc3RhbmNlLlxuICpcbiAqIEBwYXJhbSB7TWVzc2VuZ2VyfSBtZXNzZW5nZXIgcmVmZXJlbmNlIHRvIE1lc3NlbmdlciBpbnN0YW5jZSBsaW5rZWQgdG8gdGhpcyBNZXNzYWdlU291cmNlXG4gKi9cbmZ1bmN0aW9uIHNldE1lc3NlbmdlcihtZXNzZW5nZXIpIHtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXNzZW5nZXInLCBtZXNzZW5nZXIpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBQcmVwYXJlcyBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpIHBhc3NlZCB0byBjb25zdHJ1Y3RvciBieSBwcm94eWluZyBpdHMgbWV0aG9kcyB0byBpdHNlbGYgb3IgaWYgTWVzc2VuZ2VyQVBJIHdhc24ndCBwYXNzZWQgZGVmaW5lcyB0d28gbWV0aG9kcyB0byBhdm9pZCBjaGVja2luZyB0aGVpciBhdmFpbGFiaWxpdHkgZXZlcnkgdGltZSB0aGUgbWVzc2FnZSBpcyBkaXNwYXRjaGVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge01lc3NlbmdlckFQSX0gbWVzc2VuZ2VyQVBJIE9wdGlvbmFsIGluc3RhbmNlIG9mIE1lc3NlbmdlckFQSVxuICovXG5mdW5jdGlvbiBfcHJlcGFyZU1lc3NlbmdlckFQSShtZXNzZW5nZXJBUEkpIHtcbiAgICBjaGVjayhtZXNzZW5nZXJBUEksIE1hdGNoLk9wdGlvbmFsKE1lc3NlbmdlckFQSSkpO1xuXG4gICAgaWYgKCEgbWVzc2VuZ2VyQVBJKVxuICAgICAgICBtZXNzZW5nZXJBUEkgPSBuZXcgTWVzc2VuZ2VyQVBJO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWVzc2VuZ2VyQVBJJywgbWVzc2VuZ2VyQVBJKTtcbn1cblxuXG4vKipcbiAqIE1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kLlxuICogU3Vic2NyaWJlcyB0byBleHRlcm5hbCBzb3VyY2UgdXNpbmcgYGFkZFNvdXJjZVN1YnNjcmliZXJgIG1ldGhvZCB0aGF0IHNob3VsZCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzcy5cbiAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBbTWVzc2VuZ2VyXSguL2luZGV4LmpzLmh0bWwpIHdoZW4gdGhlIGZpcnN0IHN1YnNjcmliZXIgdG8gdGhlIGBtZXNzYWdlYCBpcyBhZGRlZC5cbiAqIERlbGVnYXRlcyB0byBzdXBwbGllZCBvciBkZWZhdWx0IFtNZXNzZW5nZXJBUEldKC4vbV9hcGkuanMuaHRtbCkgZm9yIHRyYW5zbGF0aW9uIG9mIGBtZXNzYWdlYCB0byBgc291cmNlTWVzc2FnZWAuIGBNZXNzYWdlQVBJLnByb3RvdHlwZS5hZGRJbnRlcm5hbE1lc3NhZ2VgIHdpbGwgcmV0dXJuIHVuZGVmaW5lZCBpZiB0aGlzIGBzb3VyY2VNZXNzYWdlYCB3YXMgYWxyZWFkeSBzdWJzY3JpYmVkIHRvIHRvIHByZXZlbnQgZHVwbGljYXRlIHN1YnNjcmlwdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBpbnRlcm5hbCBNZXNzZW5nZXIgbWVzc2FnZSB0aGF0IGhhcyB0byBiZSBzdWJzY3JpYmVkIHRvIGF0IHRoZSBleHRlcm5hbCBzb3VyY2Ugb2YgbWVzc2FnZXMuXG4gKi9cbmZ1bmN0aW9uIG9uU3Vic2NyaWJlckFkZGVkKG1lc3NhZ2UpIHtcbiAgICB2YXIgbmV3U291cmNlTWVzc2FnZSA9IHRoaXMubWVzc2VuZ2VyQVBJLmFkZEludGVybmFsTWVzc2FnZShtZXNzYWdlKTtcbiAgICBpZiAodHlwZW9mIG5ld1NvdXJjZU1lc3NhZ2UgIT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgIHRoaXMuYWRkU291cmNlU3Vic2NyaWJlcihuZXdTb3VyY2VNZXNzYWdlKTtcbn1cblxuXG4vKipcbiAqIE1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kLlxuICogVW5zdWJzY3JpYmVzIGZyb20gZXh0ZXJuYWwgc291cmNlIHVzaW5nIGByZW1vdmVTb3VyY2VTdWJzY3JpYmVyYCBtZXRob2QgdGhhdCBzaG91bGQgYmUgaW1wbGVtZW50ZWQgaW4gc3ViY2xhc3MuXG4gKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgW01lc3Nlbmdlcl0oLi9pbmRleC5qcy5odG1sKSB3aGVuIHRoZSBsYXN0IHN1YnNjcmliZXIgdG8gdGhlIGBtZXNzYWdlYCBpcyByZW1vdmVkLlxuICogRGVsZWdhdGVzIHRvIHN1cHBsaWVkIG9yIGRlZmF1bHQgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSBmb3IgdHJhbnNsYXRpb24gb2YgYG1lc3NhZ2VgIHRvIGBzb3VyY2VNZXNzYWdlYC4gYE1lc3NhZ2VBUEkucHJvdG90eXBlLnJlbW92ZUludGVybmFsTWVzc2FnZWAgd2lsbCByZXR1cm4gdW5kZWZpbmVkIGlmIHRoaXMgYHNvdXJjZU1lc3NhZ2VgIHdhcyBub3QgeWV0IHN1YnNjcmliZWQgdG8gdG8gcHJldmVudCB1bnN1YnNjcmlwdGlvbiB3aXRob3V0IHByZXZpb3VzIHN1YnNjcmlwdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBpbnRlcm5hbCBNZXNzZW5nZXIgbWVzc2FnZSB0aGF0IGhhcyB0byBiZSB1bnN1YnNjcmliZWQgZnJvbSBhdCB0aGUgZXh0ZXJuYWwgc291cmNlIG9mIG1lc3NhZ2VzLlxuICovXG5mdW5jdGlvbiBvblN1YnNjcmliZXJSZW1vdmVkKG1lc3NhZ2UpIHtcbiAgICB2YXIgcmVtb3ZlZFNvdXJjZU1lc3NhZ2UgPSB0aGlzLm1lc3NlbmdlckFQSS5yZW1vdmVJbnRlcm5hbE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgaWYgKHR5cGVvZiByZW1vdmVkU291cmNlTWVzc2FnZSAhPSAndW5kZWZpbmVkJylcbiAgICAgICAgdGhpcy5yZW1vdmVTb3VyY2VTdWJzY3JpYmVyKHJlbW92ZWRTb3VyY2VNZXNzYWdlKTtcbn1cblxuXG4vKipcbiAqIE1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kLlxuICogRGlzcGF0Y2hlcyBzb3VyY2VNZXNzYWdlIHRvIE1lc3Nlbmdlci5cbiAqIE1lY2hhbmlzbSB0aGF0IGNhbGxzIHRoaXMgbWV0aG9kIHdoZW4gdGhlIHNvdXJjZSBtZXNzYWdlIGlzIHJlY2VpdmVkIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcyAoc2VlIFtET01FdmVudHNTb3VyY2VdKC4uL2NvbXBvbmVudHMvbXNnX3NyYy9kb21fZXZlbnRzLmpzLmh0bWwpIGZvciBleGFtcGxlKS5cbiAqIERlbGVnYXRlcyB0byBzdXBwbGllZCBvciBkZWZhdWx0IFtNZXNzZW5nZXJBUEldKC4vbV9hcGkuanMuaHRtbCkgdG8gY3JlYXRlIGludGVybmFsIG1lc3NhZ2UgZGF0YSAoYGNyZWF0ZUludGVybmFsRGF0YWApIGFuZCB0byBmaWx0ZXIgdGhlIG1lc3NhZ2UgYmFzZWQgb24gaXRzIGRhdGEgYW5kL29yIG1lc3NhZ2UgKGBmaWx0ZXJTb3VyY2VNZXNzYWdlYCkuXG4gKiBCYXNlIE1lc3NlbmdlckFQSSBjbGFzcyBpbXBsZW1lbnRzIHRoZXNlIHR3byBtZXRob2RzIGluIGEgdHJpdmlhbCB3YXkgKGBjcmVhdGVJbnRlcm5hbERhdGFgIHNpbXBseSByZXR1cm5zIGV4dGVybmFsIGRhdGEsIGBmaWx0ZXJTb3VyY2VNZXNzYWdlYCByZXR1cm5zIGB0cnVlYCksIHRoZXkgYXJlIG1lYW50IHRvIGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzb3VyY2VNZXNzYWdlIHNvdXJjZSBtZXNzYWdlIHJlY2VpdmVkIGZyb20gZXh0ZXJuYWwgc291cmNlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlRGF0YSBkYXRhIHJlY2VpdmVkIGZyb20gZXh0ZXJuYWwgc291cmNlXG4gKi9cbmZ1bmN0aW9uIGRpc3BhdGNoTWVzc2FnZShzb3VyY2VNZXNzYWdlLCBzb3VyY2VEYXRhKSB7XG4gICAgdmFyIGFwaSA9IHRoaXMubWVzc2VuZ2VyQVBJXG4gICAgICAgICwgaW50ZXJuYWxNZXNzYWdlcyA9IGFwaS5nZXRJbnRlcm5hbE1lc3NhZ2VzKHNvdXJjZU1lc3NhZ2UpO1xuXG4gICAgaWYgKGludGVybmFsTWVzc2FnZXMpIFxuICAgICAgICBpbnRlcm5hbE1lc3NhZ2VzLmZvckVhY2goZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIHZhciBpbnRlcm5hbERhdGEgPSBhcGkuY3JlYXRlSW50ZXJuYWxEYXRhKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIHNvdXJjZURhdGEpO1xuXG4gICAgICAgICAgICB2YXIgc2hvdWxkRGlzcGF0Y2ggPSBhcGkuZmlsdGVyU291cmNlTWVzc2FnZShzb3VyY2VNZXNzYWdlLCBtZXNzYWdlLCBpbnRlcm5hbERhdGEpO1xuICAgICAgICAgICAgaWYgKHNob3VsZERpc3BhdGNoKSBcbiAgICAgICAgICAgICAgICB0aGlzLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIGludGVybmFsRGF0YSk7ICAgICAgXG4gICAgICAgICAgICBcbiAgICAgICAgfSwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBQb3N0cyBtZXNzYWdlIG9uIHRoZSBtZXNzZW5nZXIuIFRoaXMgbWV0aG9kIGlzIHNlcGFyYXRlZCBzbyBzcGVjaWZpYyBtZXNzYWdlIHNvdXJjZXMgY2FuIG1ha2UgbWVzc2FnZSBkaXNwYXRjaCBzeW5jaHJvbm91cyBieSB1c2luZyBgcG9zdE1lc3NhZ2VTeW5jYFxuICogXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1lc3NhZ2VcbiAqIEBwYXJhbSAge09iamVjdH0gZGF0YVxuICovXG5mdW5jdGlvbiBwb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhKSB7XG4gICAgdGhpcy5tZXNzZW5nZXIucG9zdE1lc3NhZ2UobWVzc2FnZSwgZGF0YSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIE1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuL21fc291cmNlJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJyk7XG5cblxuLyoqXG4gKiBTdWJjbGFzcyBvZiBNZXNzYWdlU291cmNlIHRoYXQgYWxsb3dzIHRvIGNvbm5lY3QgTWVzc2VuZ2VyIHRvIGFub3RoZXIgTWVzc2VuZ2VyIHVzaW5nIGl0IGFzIGV4dGVybmFsIHNvdXJjZS5cbiAqL1xudmFyIE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NhZ2VTb3VyY2UsICdNZXNzZW5nZXJNZXNzYWdlU291cmNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZTtcblxuXG4vKipcbiAqICMjIyNNZXNzZW5nZXJNZXNzYWdlU291cmNlIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKi9cbl8uZXh0ZW5kUHJvdG8oTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSwge1xuICAgIGluaXQ6IGluaXQsXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogYWRkU291cmNlU3Vic2NyaWJlcixcbiAgICByZW1vdmVTb3VyY2VTdWJzY3JpYmVyOiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyLFxuICAgIHBvc3RNZXNzYWdlOiBNZXNzZW5nZXJNZXNzYWdlU291cmNlJHBvc3RNZXNzYWdlXG59KTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBNZXNzZW5nZXJNZXNzYWdlU291cmNlXG4gKiBEZWZpbmVzIG9uZSBwYXJhbWV0ZXIgaW4gYWRkaXRpb24gdG8gW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgcGFyYW1ldGVyc1xuICpcbiAqIEBwYXJhbSB7TWVzc2VuZ2VyfSBzb3VyY2VNZXNzZW5nZXIgbWVzc2VuZ2VyIHRoaXMgbWVzc2FnZSBzb3VyY2UgY29ubmVjdHMgdG9cbiAqL1xuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NlbmdlckFQSSwgc291cmNlTWVzc2VuZ2VyKSB7XG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHRoaXMuc291cmNlTWVzc2VuZ2VyID0gc291cmNlTWVzc2VuZ2VyO1xufVxuXG5cbi8qKlxuICogU3Vic2NyaWJlcyB0byBzb3VyY2UgbWVzc2FnZS4gU2VlIFtNZXNzYWdlU291cmNlXSguL21fc291cmNlLmpzLmh0bWwpIGRvY3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnZXh9IHNvdXJjZU1lc3NhZ2Ugc291cmNlIG1lc3NhZ2UgdG8gc3Vic2NyaWJlIHRvXG4gKi9cbmZ1bmN0aW9uIGFkZFNvdXJjZVN1YnNjcmliZXIoc291cmNlTWVzc2FnZSkge1xuICAgIHRoaXMuc291cmNlTWVzc2VuZ2VyLm9uU3luYyhzb3VyY2VNZXNzYWdlLCB7IGNvbnRleHQ6IHRoaXMsIHN1YnNjcmliZXI6IHRoaXMuZGlzcGF0Y2hNZXNzYWdlIH0pO1xufVxuXG5cbi8qKlxuICogVW5zdWJzY3JpYmVzIGZyb20gc291cmNlIG1lc3NhZ2UuIFNlZSBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBkb2NzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ2V4fSBzb3VyY2VNZXNzYWdlIHNvdXJjZSBtZXNzYWdlIHRvIHVuc3Vic2NyaWJlIGZyb21cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgdGhpcy5zb3VyY2VNZXNzZW5nZXIub2ZmKHNvdXJjZU1lc3NhZ2UsIHsgY29udGV4dDogdGhpcywgc3Vic2NyaWJlcjogdGhpcy5kaXNwYXRjaE1lc3NhZ2UgfSk7XG59XG5cblxuLyoqXG4gKiBPdmVycmlkZXMgZGVmYWx1dCBtZXNzYWdlIHNvdXJjZSB0byBkaXNwYXRjaCBtZXNzYWdlcyBzeW5jaHJvbm91c2x5XG4gKiBcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICovXG5mdW5jdGlvbiBNZXNzZW5nZXJNZXNzYWdlU291cmNlJHBvc3RNZXNzYWdlKG1lc3NhZ2UsIGRhdGEpIHtcbiAgICB0aGlzLm1lc3Nlbmdlci5wb3N0TWVzc2FnZVN5bmMobWVzc2FnZSwgZGF0YSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjb3JlID0gcmVxdWlyZSgnbWlsby1jb3JlJyk7XG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8vIHJlZ2lzdGVyIGluY2x1ZGVkIGZhY2V0c1xucmVxdWlyZSgnLi91c2VfZmFjZXRzJyk7XG5cbi8vIHJlZ2lzdGVyIGluY2x1ZGVkIGNvbXBvbmVudHNcbnJlcXVpcmUoJy4vdXNlX2NvbXBvbmVudHMnKTtcblxuXG4vKipcbiAqIGBtaWxvYFxuICpcbiAqIEEgbWluaW1hbGlzdCBicm93c2VyIGZyYW1ld29yayB0aGF0IGJpbmRzIERPTSBlbGVtZW50cyB0byBKUyBjb21wb25lbnRzIGFuZCBjb21wb25lbnRzIHRvIG1vZGVscy5cbiAqXG4gKiBgbWlsb2AgaXMgYXZhaWxhYmxlIGFzIGdsb2JhbCBvYmplY3QgaW4gdGhlIGJyb3dzZXIuXG4gKiBBdCB0aGUgbW9tZW50IGl0IGlzIG5vdCBwb3NzaWlibGUgdG8gcmVxdWlyZSBpdCB3aXRoIGJyb3dzZXJpZnkgdG8gaGF2ZSBpdCBidW5kbGVkIHdpdGggdGhlIGFwcCBiZWNhdXNlIG9mIHRoZSB3YXkgW2JyZnNdKGh0dHBzOi8vZ2l0aHViLmNvbS9zdWJzdGFjay9icmZzKSBicm93c2VyaWZ5IHBsdWdpbiBpcyBpbXBsZW1lbnRlZC5cbiAqIEl0IGlzIHBvc3NpYmxlIHRob3VnaCB0byByZXF1aXJlIGBtaWxvYCB3aXRoIG5vZGUgdG8gdXNlIHVuaXZlcnNhbCBwYXJ0cyBvZiB0aGUgZnJhbWV3b3JrIChhYnN0cmFjdCBjbGFzc2VzLCBNZXNzZW5nZXIsIE1vZGVsLCBldGMuKTpcbiAqIGBgYFxuICogdmFyIG1pbG8gPSByZXF1aXJlKCdtb2wtbWlsbycpO1xuICogYGBgXG4gKiBcbiAqIGBtaWxvYCBpdHNlbGYgaXMgYSBmdW5jdGlvbiB0aGF0IGluIHRoZSBicm93c2VyIGNhbiBiZSB1c2VkIHRvIGRlbGF5IGV4ZWN1dGlvbiB1bnRpbCBET00gaXMgcmVhZHkuXG4gKi9cbmZ1bmN0aW9uIG1pbG8oZnVuYykge1xuICAgIG1pbG8udXRpbC5kb21SZWFkeShmdW5jKTtcbn1cblxuXG4vKipcbiAqICMjIyNNaWxvIHBhY2thZ2VzIyMjI1xuICpcbiAqIC0gW2xvYWRlcl0oLi9sb2FkZXIuanMuaHRtbCkgLSBsb2FkaW5nIHN1YnZpZXdzIGludG8gcGFnZVxuICogLSBbYmluZGVyXSguL2JpbmRlci5qcy5odG1sKSAtIGNvbXBvbmVudHMgaW5zdGFudGlhdGlvbiBhbmQgYmluZGluZyBvZiBET00gZWxlbWVudHMgdG8gdGhlbVxuICogLSBbbWluZGVyXSguL21pbmRlci5qcy5odG1sKSAtIGRhdGEgcmVhY3Rpdml0eSwgb25lIG9yIHR3byB3YXksIHNoYWxsb3cgb3IgZGVlcCwgYXMgeW91IGxpa2UgaXRcbiAqIC0gW21haWxdKC4vbWFpbC9pbmRleC5qcy5odG1sKSAtIGFwcGxpY2FpdG9uIGxldmVsIG1lc3NlbmdlciwgYWxzbyBjb25uZWN0cyB0byBtZXNzYWdlcyBmcm9tIG90aGVyIHdpbmRvd3MgZGlzcGF0Y2hlZCB3aXRoIGB3aW5kb3cucG9zdE1lc3NhZ2VgLlxuICogLSBbY29uZmlnXSguL2NvbmZpZy5qcy5odG1sKSAtIG1pbG8gY29uZmlndXJhdGlvblxuICogLSBbdXRpbF0oLi91dGlsL2luZGV4LmpzLmh0bWwpIC0gbG9nZ2VyLCByZXF1ZXN0LCBkb20sIGNoZWNrLCBlcnJvciwgZXRjLlxuICogLSBbY2xhc3Nlc10oLi9jbGFzc2VzLmpzLmh0bWwpIC0gYWJzdHJhY3QgYW5kIGJhc2UgY2xhc3Nlc1xuICogLSBbYXR0cmlidXRlc10oLi9hdHRyaWJ1dGVzL2luZGV4LmpzLmh0bWwpIC0gY2xhc3NlcyB0aGF0IHdyYXAgRE9NIGVsZW1lbnRzIGF0dHJpYnV0ZXMgcmVjb2duaXplZCBieSBtaWxvXG4gKiAtIFtDb21wb25lbnRGYWNldF0oLi9jb21wb25lbnRzL2NfZmFjZXQuanMuaHRtbCkgLSBiYXNlIGNsYXNzIG9mIENvbXBvbmVudCBmYWNldFxuICogLSBbQ29tcG9uZW50XSguL2NvbXBvbmVudHMvY19jbGFzcy5qcy5odG1sKSAtIGJhc2UgQ29tcG9uZW50IGNsYXNzXG4gKiAtIFtNZXNzZW5nZXJdKC4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpIC0gZ2VuZXJpYyBNZXNzZW5nZXIgdXNlZCBpbiBtb3N0IG90aGVyIG1pbG8gY2xhc3NlcywgY2FuIGJlIG1peGVkIGludG8gYXBwIGNsYXNzZXMgdG9vLlxuICogLSBbTW9kZWxdKC4vbW9kZWwvaW5kZXguanMuaHRtbCkgLSBNb2RlbCBjbGFzcyB0aGF0IGVtaXRzIG1lc3NhZ2VzIG9uIGNoYW5nZXMgdG8gYW55IGRlcHRoIHdpdGhvdXQgdGltZXIgYmFzZWQgd2F0Y2hpbmdcbiAqIC0gW3JlZ2lzdHJ5XSguL3JlZ2lzdHJ5LmpzLmh0bWwpIC0gcmVnaXN0cmllcyBvZiBmYXNldHMgYW5kIGNvbXBvbmVudHMgY2xhc3Nlc1xuICovXG5fLmV4dGVuZChtaWxvLCB7XG4gICAgTWVzc2VuZ2VyOiBjb3JlLk1lc3NlbmdlcixcbiAgICBNb2RlbDogY29yZS5Nb2RlbCxcbiAgICBtaW5kZXI6IGNvcmUubWluZGVyLFxuICAgIGxvYWRlcjogcmVxdWlyZSgnLi9sb2FkZXInKSxcbiAgICBiaW5kZXI6IHJlcXVpcmUoJy4vYmluZGVyJyksXG4gICAgbWFpbDogcmVxdWlyZSgnLi9zZXJ2aWNlcy9tYWlsJyksXG4gICAgd2luZG93OiByZXF1aXJlKCcuL3NlcnZpY2VzL3dpbmRvdycpLFxuICAgIGNvbmZpZzogcmVxdWlyZSgnLi9jb25maWcnKSxcbiAgICB1dGlsOiByZXF1aXJlKCcuL3V0aWwnKSxcbiAgICBjbGFzc2VzOiByZXF1aXJlKCcuL2NsYXNzZXMnKSxcbiAgICBhdHRyaWJ1dGVzOiByZXF1aXJlKCcuL2F0dHJpYnV0ZXMnKSxcbiAgICBDb21wb25lbnRGYWNldDogcmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXQnKSxcbiAgICBDb21wb25lbnQ6IHJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2NsYXNzJyksXG4gICAgQ29tbWFuZDogcmVxdWlyZSgnLi9jb21tYW5kJyksXG4gICAgcmVnaXN0cnk6IHJlcXVpcmUoJy4vcmVnaXN0cnknKSxcbiAgICBtaWxvX3ZlcnNpb246ICcwLjEuNCcsXG4gICAgY3JlYXRlQ29tcG9uZW50Q2xhc3M6IHJlcXVpcmUoJy4vdXRpbC9jcmVhdGVfY29tcG9uZW50X2NsYXNzJyksXG4gICAgZGVzdHJveTogZGVzdHJveVxufSk7XG5cblxuLy8gZXhwb3J0IGZvciBub2RlL2Jyb3dzZXJpZnlcbmlmICh0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSAgICBcbiAgICBtb2R1bGUuZXhwb3J0cyA9IG1pbG87XG5cbi8vIGdsb2JhbCBtaWxvIGZvciBicm93c2VyXG5pZiAodHlwZW9mIHdpbmRvdyA9PSAnb2JqZWN0Jykge1xuICAgIHdpbmRvdy5taWxvID0gbWlsbztcbiAgICBtaWxvLm1haWwudHJpZ2dlcignbWlsb3JlYWR5Jyk7XG59XG5cblxuZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICBtaWxvLm1haWwuZGVzdHJveSgpO1xuICAgIG1pbG8ud2luZG93LmRlc3Ryb3koKTtcbiAgICBtaWxvLm1pbmRlci5kZXN0cm95KCk7XG4gICAgbWlsby51dGlsLmRlc3Ryb3koKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgZmFjZXRzUmVnaXN0cnkgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5JylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gcHJvY2VzcyBcImNoYW5nZWRhdGFcIiBtZXNzYWdlcyBlbWl0dGVkIGJ5IENvbm5lY3RvciBvYmplY3QuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gY2hhbmdlRGF0YUhhbmRsZXI7XG5cblxuXy5leHRlbmQoY2hhbmdlRGF0YUhhbmRsZXIsIHtcbiAgICBzZXRUcmFuc2FjdGlvbkZsYWc6IHNldFRyYW5zYWN0aW9uRmxhZyxcbiAgICBnZXRUcmFuc2FjdGlvbkZsYWc6IGdldFRyYW5zYWN0aW9uRmxhZyxcbiAgICBwYXNzVHJhbnNhY3Rpb25GbGFnOiBwYXNzVHJhbnNhY3Rpb25GbGFnLFxuICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkOiBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZFxufSk7XG5cblxuLyoqXG4gKiBDaGFuZ2UgZGF0YSB1c2VzIGhpZGRlbiBwcm9wZXJ0eSBvbiBhY2Nlc3NvciBtZXRob2RzIHRvIHBhc3MgZmxhZyB0aGF0IHRoZSBhY2Nlc3NvciBpcyBleGVjdXRlZCBhcyBhIHBhcnQgb2YgY2hhbmdlIHRyYW5zYWN0aW9uLlxuICogQWNjZXNzb3IgbWV0aG9kcyBhcmUgc3VwcG9zZWQgdG8gc3RvcmUgdGhpcyBmbGFnIGluIGEgbG9jYWwgdmFyaWFibGUgYW5kIHRvIGNsZWFyIGl0IChiZWNhdXNlIGFub3RoZXIgYWNjZXNzb3IgY2FuIGJlIGV4ZWN1dGVkIGluIG9yIG91dCBvZiB0cmFuc2FjdGlvbikgdXNpbmcgYGdldFRyYW5zYWN0aW9uRmxhZ2BcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBhY2Nlc3NvciBtZXRob2QgcmVmZXJlbmNlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGZsYWcgYSBmbGFnIHRvIGJlIHNldFxuICovXG5mdW5jdGlvbiBzZXRUcmFuc2FjdGlvbkZsYWcoZnVuYywgZmxhZykge1xuICAgIF8uZGVmaW5lUHJvcGVydHkoZnVuYywgJ19faW5DaGFuZ2VUcmFuc2FjdGlvbicsIGZsYWcsIF8uQ09ORiB8IF8uV1JJVCk7XG59XG5cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIGNsZWFycyB0cmFuc2FjdGlvbiBmbGFnIGZyb20gYWNjZXNzb3IgbWV0aG9kXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgYWNjZXNzb3IgbWV0aG9kIHJlZmVyZW5jZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25GbGFnKGZ1bmMpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGZ1bmMuX19pbkNoYW5nZVRyYW5zYWN0aW9uO1xuICAgIGRlbGV0ZSBmdW5jLl9faW5DaGFuZ2VUcmFuc2FjdGlvbjtcbiAgICByZXR1cm4gaW5UcmFuc2FjdGlvbjtcbn1cblxuXG5mdW5jdGlvbiBwYXNzVHJhbnNhY3Rpb25GbGFnKGZyb21GdW5jLCB0b0Z1bmMpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGdldFRyYW5zYWN0aW9uRmxhZyhmcm9tRnVuYyk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKHRvRnVuYywgaW5UcmFuc2FjdGlvbik7XG4gICAgcmV0dXJuIGluVHJhbnNhY3Rpb247XG59XG5cblxuLyoqXG4gKiBQb3N0cyBtZXNzYWdlIG9uIHRoaXMgdG8gaW5kaWNhdGUgdGhlIGVuZCBvZiB0cmFuc2FjdGlvbiB1bmxlc3MgYGluQ2hhbmdlVHJhbnNhY3Rpb25gIGlzIGB0cnVlYC5cbiAqL1xuZnVuY3Rpb24gcG9zdFRyYW5zYWN0aW9uRmluaXNoZWQoKSB7XG4gICAgdGhpcy5wb3N0TWVzc2FnZVN5bmMoJ2RhdGFjaGFuZ2VzJywgeyB0cmFuc2FjdGlvbjogZmFsc2UsIGNoYW5nZXM6IFtdIH0pO1xufVxuXG5cbi8qKlxuICogc3Vic2NyaWJlciB0byBcImNoYW5nZWRhdGFcIiBldmVudCBlbWl0dGVkIGJ5IFtDb25uZWN0b3JdKC4vY29ubmVjdG9yLmpzLmh0bWwpIG9iamVjdCB0byBlbmFibGUgcmVhY3RpdmUgY29ubmVjdGlvbnNcbiAqIFVzZWQgYnkgRGF0YSBmYWNldCwgTW9kZWwgYW5kIE1vZGVsUGF0aC4gQ2FuIGJlIHVzZWQgYnkgYW55IG9iamVjdCB0aGF0IGltcGxlbWVudHMgZ2V0L3NldC9kZWwvc3BsaWNlIGFwaSBhbmQgc2V0cyBkYXRhIGRlZXBseSB0byB0aGUgd2hvbGUgdHJlZS5cbiAqIE9iamVjdCBzaG91bGQgY2FsbCBgY2hhbmdlRGF0YUhhbmRsZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpYCBpbiBpdHMgY29uc3RydWN0b3IuXG4gKiBUT0RPOiBvcHRpbWl6ZSBtZXNzYWdlcyBsaXN0IHRvIGF2b2lkIHNldHRpbmcgZHVwbGljYXRlIHZhbHVlcyBkb3duIHRoZSB0cmVlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyBzaG91bGQgYmUgXCJjaGFuZ2VkYXRhXCIgaGVyZVxuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgYmF0Y2ggb2YgZGF0YSBjaGFuZ2UgZGVzY2lwdGlvbiBvYmplY3RzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsYmFjayB0byBjYWxsIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGRhdGEgaXMgcHJvY2Vzc2VkXG4gKi9cbmZ1bmN0aW9uIGNoYW5nZURhdGFIYW5kbGVyKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgcHJvY2Vzc0NoYW5nZXMuY2FsbCh0aGlzLCBkYXRhLmNoYW5nZXMsIGNhbGxiYWNrKTtcbn1cblxuXG4vLyBtYXAgb2YgbWVzc2FnZSB0eXBlcyB0byBtZXRob2RzXG52YXIgQ0hBTkdFX1RZUEVfVE9fTUVUSE9EX01BUCA9IHtcbiAgICAnYWRkZWQnOiAgICdzZXQnLFxuICAgICdjaGFuZ2VkJzogJ3NldCcsXG4gICAgJ2RlbGV0ZWQnOiAnZGVsJyxcbiAgICAncmVtb3ZlZCc6ICdkZWwnXG59O1xuXG5cbi8qKlxuICogUHJvY2Vzc2VzIHF1ZXVlZCBcImNoYW5nZWRhdGFcIiBtZXNzYWdlcy5cbiAqIFBvc3RzIFwiY2hhbmdlc3RhcnRlZFwiIGFuZCBcImNoYW5nZWNvbXBsZXRlZFwiIG1lc3NhZ2VzIGFuZCBjYWxscyBjYWxsYmFja1xuICpcbiAqIEBwYXJhbSB7W0Z1bmN0aW9uXX0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2l0aCBgKG51bGwsIGZhbHNlKWAgcGFyYW1ldGVycyBiZWZvcmUgY2hhbmdlIHByb2Nlc3Npbmcgc3RhcnRzIGFuZCBgKG51bGwsIHRydWUpYCBhZnRlciBpdCdzIGZpbmlzaGVkLlxuICovXG5mdW5jdGlvbiBwcm9jZXNzQ2hhbmdlcyh0cmFuc2FjdGlvbiwgY2FsbGJhY2spIHtcbiAgICBub3RpZnkuY2FsbCh0aGlzLCBjYWxsYmFjaywgZmFsc2UpO1xuICAgIHByb2Nlc3NUcmFuc2FjdGlvbi5jYWxsKHRoaXMsXG4gICAgICAgIHByZXBhcmVUcmFuc2FjdGlvbihcbiAgICAgICAgICAgIHZhbGlkYXRlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSk7XG4gICAgbm90aWZ5LmNhbGwodGhpcywgY2FsbGJhY2ssIHRydWUpO1xufVxuXG5cbmZ1bmN0aW9uIG5vdGlmeShjYWxsYmFjaywgY2hhbmdlRmluaXNoZWQpIHtcbiAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsLCBjaGFuZ2VGaW5pc2hlZCk7XG4gICAgdGhpcy5wb3N0TWVzc2FnZShjaGFuZ2VGaW5pc2hlZCA/ICdjaGFuZ2Vjb21wbGV0ZWQnIDogJ2NoYW5nZXN0YXJ0ZWQnKTtcbn1cblxuXG4vKipcbiAqIENoZWNrcyB0aGF0IGFsbCBtZXNzYWdlcyBmcm9tIHRoZSB0cmFuc2FjdGlvbiBjb21lIGZyb20gdGhlIHNhbWUgc291cmNlLlxuICogSGFjazogcmV2ZXJzZXMgdGhlIHRyYW5zYWN0aW9uIGlmIGl0IGNvbWVzIGZyb20gdGhlIERhdGEgZmFjZXRcbiAqIFJldHVybnMgdGhlIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNhY3Rpb24gKGZvciBjaGFpbmluZylcbiAqIFxuICogQHBhcmFtICB7QXJyYXl9IHRyYW5zYWN0aW9uIHRyYW5zYWN0aW9uIG9mIGRhdGEgY2hhbmdlc1xuICogQHJldHVybiB7QXJyYXl9IFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSB7XG4gICAgdmFyIHNvdXJjZSA9IHRyYW5zYWN0aW9uWzBdLnNvdXJjZVxuICAgICAgICAsIHNhbWVTb3VyY2UgPSB0cnVlO1xuXG4gICAgaWYgKHRyYW5zYWN0aW9uLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IHRyYW5zYWN0aW9uLmxlbmd0aDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgICAgaWYgKHRyYW5zYWN0aW9uW2ldLnNvdXJjZSAhPSBzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ2NoYW5nZWRhdGE6IGNoYW5nZXMgZnJvbSBkaWZmZXJlbnQgc291cmNlcyBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbiwgc291cmNlczonLCB0cmFuc2FjdGlvbltpXS5zb3VyY2UubmFtZSwgc291cmNlLm5hbWUpO1xuICAgICAgICAgICAgICAgIHNhbWVTb3VyY2UgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzb3VyY2UgPSB0cmFuc2FjdGlvbltpXS5zb3VyY2U7XG4gICAgICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uO1xufVxuXG5cbmZ1bmN0aW9uIHByZXBhcmVUcmFuc2FjdGlvbih0cmFuc2FjdGlvbikge1xuICAgIHZhciB0b2RvID0gW11cbiAgICAgICAgLCBwYXRoc1RvU3BsaWNlID0gW11cbiAgICAgICAgLCBwYXRoc1RvQ2hhbmdlID0gW11cbiAgICAgICAgLCBoYWRTcGxpY2VcbiAgICAgICAgLCBleGl0TG9vcCA9IHt9O1xuXG5cbiAgICB0cnkgeyB0cmFuc2FjdGlvbi5mb3JFYWNoKGNoZWNrQ2hhbmdlKTsgfVxuICAgIGNhdGNoIChlKSB7IGlmIChlICE9IGV4aXRMb29wKSB0aHJvdyBlOyB9XG5cbiAgICByZXR1cm4gdG9kbztcblxuXG4gICAgZnVuY3Rpb24gY2hlY2tDaGFuZ2UoZGF0YSkge1xuICAgICAgICAoZGF0YS50eXBlID09ICdzcGxpY2UnID8gY2hlY2tTcGxpY2UgOiBjaGVja01ldGhvZCkoZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjaGVja1NwbGljZShkYXRhKSB7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChkYXRhLnBhdGgpO1xuICAgICAgICB2YXIgcGFyZW50UGF0aENoYW5nZWQgPSBwYXRoc1RvQ2hhbmdlLnNvbWUoZnVuY3Rpb24ocGFyZW50UGF0aCkge1xuICAgICAgICAgICAgaWYgKHBhcnNlZFBhdGgubGVuZ3RoIDwgcGFyZW50UGF0aC5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJlbnRQYXRoQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgICAgIHRvZG8ucHVzaChkYXRhKTtcblxuICAgICAgICBpZiAoISBjb25maWcuZGVidWcpIHRocm93IGV4aXRMb29wO1xuICAgICAgICBwYXRoc1RvU3BsaWNlLnB1c2gocGFyc2VkUGF0aCk7XG4gICAgICAgIGhhZFNwbGljZSA9IHRydWU7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjaGVja01ldGhvZChkYXRhKSB7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChkYXRhLnBhdGgpO1xuICAgICAgICB2YXIgcGFyZW50UGF0aFNwbGljZWQgPSBwYXRoc1RvU3BsaWNlICYmIHBhdGhzVG9TcGxpY2Uuc29tZShmdW5jdGlvbihwYXJlbnRQYXRoKSB7XG4gICAgICAgICAgICBpZiAocGFyc2VkUGF0aC5sZW5ndGggPD0gcGFyZW50UGF0aC5sZW5ndGhcbiAgICAgICAgICAgICAgICB8fCBwYXJzZWRQYXRoW3BhcmVudFBhdGgubGVuZ3RoXS5zeW50YXggIT0gJ2FycmF5JykgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIF9wYXRoSXNQYXJlbnRPZihwYXJlbnRQYXRoLCBwYXJzZWRQYXRoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHBhcmVudFBhdGhTcGxpY2VkKSByZXR1cm47XG4gICAgICAgIGlmIChoYWRTcGxpY2UpIGxvZ2dlci5lcnJvcignY2hhbmdlZGF0YTogY2hpbGQgY2hhbmdlIGlzIGV4ZWN1dGVkIGFmdGVyIHNwbGljZTsgcHJvYmFibHkgZGF0YSBzb3VyY2UgZGlkIG5vdCBlbWl0IG1lc3NhZ2Ugd2l0aCBkYXRhLnR5cGU9PVwiZmluaXNoZWRcIicpO1xuXG4gICAgICAgIHZhciBwYXJlbnRQYXRoQ2hhbmdlZCA9IHBhdGhzVG9DaGFuZ2Uuc29tZShmdW5jdGlvbihwYXJlbnRQYXRoKSB7XG4gICAgICAgICAgICBpZiAocGFyc2VkUGF0aC5sZW5ndGggPD0gcGFyZW50UGF0aC5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJlbnRQYXRoQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgICAgIHBhdGhzVG9DaGFuZ2UucHVzaChwYXJzZWRQYXRoKTtcblxuICAgICAgICB0b2RvLnB1c2goZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgY2hpbGRQYXRoKSB7XG4gICAgICAgIHJldHVybiBwYXJlbnRQYXRoLmV2ZXJ5KGZ1bmN0aW9uKHBhdGhOb2RlLCBpbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhdGhOb2RlLnByb3BlcnR5ID09IGNoaWxkUGF0aFtpbmRleF0ucHJvcGVydHk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBwcm9jZXNzVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pIHtcbiAgICB0cmFuc2FjdGlvbi5mb3JFYWNoKHByb2Nlc3NDaGFuZ2UsIHRoaXMpO1xuICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkLmNhbGwodGhpcywgZmFsc2UpO1xuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc0NoYW5nZShkYXRhKSB7XG4gICAgICAgIHZhciBtb2RlbFBhdGggPSB0aGlzLnBhdGgoZGF0YS5wYXRoLCBkYXRhLnR5cGUgIT0gJ3JlbW92ZWQnICYmIGRhdGEudHlwZSAhPSAnZGVsZXRlZCcpO1xuICAgICAgICBpZiAoISBtb2RlbFBhdGgpIHJldHVybjtcbiAgICAgICAgKGRhdGEudHlwZSA9PSAnc3BsaWNlJyA/IGV4ZWN1dGVTcGxpY2UgOiBleGVjdXRlTWV0aG9kKShtb2RlbFBhdGgsIGRhdGEpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBleGVjdXRlU3BsaWNlKG1vZGVsUGF0aCwgZGF0YSkge1xuICAgIHZhciBpbmRleCA9IGRhdGEuaW5kZXhcbiAgICAgICAgLCBob3dNYW55ID0gZGF0YS5yZW1vdmVkLmxlbmd0aFxuICAgICAgICAsIHNwbGljZUFyZ3MgPSBbaW5kZXgsIGhvd01hbnldO1xuXG4gICAgc3BsaWNlQXJncyA9IHNwbGljZUFyZ3MuY29uY2F0KGRhdGEubmV3VmFsdWUuc2xpY2UoaW5kZXgsIGluZGV4ICsgZGF0YS5hZGRlZENvdW50KSk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKG1vZGVsUGF0aC5zcGxpY2UsIHRydWUpO1xuICAgIG1vZGVsUGF0aC5zcGxpY2UuYXBwbHkobW9kZWxQYXRoLCBzcGxpY2VBcmdzKTtcbn1cblxuXG5mdW5jdGlvbiBleGVjdXRlTWV0aG9kKG1vZGVsUGF0aCwgZGF0YSkge1xuICAgIHZhciBtZXRob2ROYW1lID0gQ0hBTkdFX1RZUEVfVE9fTUVUSE9EX01BUFtkYXRhLnR5cGVdO1xuICAgIGlmIChtZXRob2ROYW1lKSB7XG4gICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZyhtb2RlbFBhdGhbbWV0aG9kTmFtZV0sIHRydWUpO1xuICAgICAgICBtb2RlbFBhdGhbbWV0aG9kTmFtZV0oZGF0YS5uZXdWYWx1ZSk7XG4gICAgfSBlbHNlXG4gICAgICAgIGxvZ2dlci5lcnJvcigndW5rbm93biBkYXRhIGNoYW5nZSB0eXBlJyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNb2RlbFBhdGggPSByZXF1aXJlKCcuL21fcGF0aCcpXG4gICAgLCBzeW50aGVzaXplID0gcmVxdWlyZSgnLi9zeW50aGVzaXplJylcbiAgICAsIHBhdGhVdGlscyA9IHJlcXVpcmUoJy4vcGF0aF91dGlscycpXG4gICAgLCBjaGFuZ2VEYXRhSGFuZGxlciA9IHJlcXVpcmUoJy4vY2hhbmdlX2RhdGEnKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJylcbiAgICAsIE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXIvbXNuZ3Jfc291cmNlJylcbiAgICAsIE1vZGVsTXNnQVBJID0gcmVxdWlyZSgnLi9tX21zZ19hcGknKVxuICAgICwgTW9kZWxFcnJvciA9IHJlcXVpcmUoJy4uL3V0aWwvZXJyb3InKS5Nb2RlbFxuICAgICwgTWl4aW4gPSByZXF1aXJlKCcuLi9hYnN0cmFjdC9taXhpbicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpXG4gICAgLCBqc29uUGFyc2UgPSByZXF1aXJlKCcuLi91dGlsL2pzb25fcGFyc2UnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsO1xuXG5cbi8qKlxuICogYG1pbG8uTW9kZWxgXG4gKiBNb2RlbCBjbGFzcyBpbnN0YW50aWF0ZXMgb2JqZWN0cyB0aGF0IGFsbG93IGRlZXAgZGF0YSBhY2Nlc3Mgd2l0aCBfX3NhZmUgZ2V0dGVyc19fIHRoYXQgcmV0dXJuIHVuZGVmaW5lZCAocmF0aGVyIHRoYW4gdGhyb3dpbmcgZXhjZXB0aW9uKSB3aGVuIHByb3BlcnRpZXMvaXRlbXMgb2YgdW5leGlzdGluZyBvYmplY3RzL2FycmF5cyBhcmUgcmVxdWVzdGVkIGFuZCBfX3NhZmUgc2V0dGVyc19fIHRoYXQgY3JlYXRlIG9iamVjdCB0cmVlcyB3aGVuIHByb3BlcnRpZXMvaXRlbXMgb2YgdW5leGlzdGluZyBvYmplY3RzL2FycmF5cyBhcmUgc2V0IGFuZCBhbHNvIHBvc3QgbWVzc2FnZXMgdG8gYWxsb3cgc3Vic2NyaXB0aW9uIG9uIGNoYW5nZXMgYW5kIGVuYWJsZSBkYXRhIHJlYWN0aXZpdHkuXG4gKiBSZWFjdGl2aXR5IGlzIGltcGxlbWVtbnRlZCB2aWEgW0Nvbm5lY3Rvcl0oLi9jb25uZWN0b3IuanMuaHRtbCkgdGhhdCBjYW4gYmUgaW5zdGFudGlhdGVkIGVpdGhlciBkaXJlY3RseSBvciB3aXRoIG1vcmUgY29udmVuaWVudCBpbnRlcmZhY2Ugb2YgW21pbG8ubWluZGVyXSguLi9taW5kZXIuanMuaHRtbCkuIEF0IHRoZSBtb21lbnQgbW9kZWwgY2FuIGJlIGNvbm5lY3RlZCB0byBbRGF0YSBmYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0cy9EYXRhLmpzLmh0bWwpIG9yIHRvIGFub3RoZXIgbW9kZWwgb3IgW01vZGVsUGF0aF0oLi9tX3BhdGguanMuaHRtbCkuXG4gKiBNb2RlbCBjb25zdHJ1Y3RvciByZXR1cm5zIG9iamVjdHMgdGhhdCBhcmUgZnVuY3Rpb25zIGF0IHRoZSBzYW1lIHRpbWU7IHdoZW4gY2FsbGVkIHRoZXkgcmV0dXJuIE1vZGVsUGF0aCBvYmplY3RzIHRoYXQgYWxsb3cgZ2V0L3NldCBhY2Nlc3MgdG8gYW55IHBvaW50IGluIG1vZGVsIGRhdGEuIFNlZSBbTW9kZWxEYXRhXSgjTW9kZWxEYXRhKSBiZWxvdy5cbiAqXG4gKiBZb3UgY2FuIHN1YnNjcmliZSB0byBtb2RlbCBjaGFuZ2VzIHdpdGggYG9uYCBtZXRob2QgYnkgcGFzc2luZyBtb2RlbCBhY2Nlc3MgcGF0aCBpbiBwbGFjZSBvZiBtZXNzYWdlLCBwYXR0ZXJuIG9yIHN0cmluZyB3aXRoIGFueSBudW1iZXIgb2Ygc3RhcnMgdG8gc3Vic2NyaWJlIHRvIGEgY2VydGFpbiBkZXB0aCBpbiBtb2RlbCAoZS5nLiwgYCcqKionYCB0byBzdWJzY3JpYmUgdG8gdGhyZWUgbGV2ZWxzKS5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBkYXRhIG9wdGlvbmFsIGluaXRpYWwgYXJyYXkgZGF0YS4gSWYgaXQgaXMgcGxhbm5lZCB0byBjb25uZWN0IG1vZGVsIHRvIHZpZXcgaXQgaXMgdXN1YWxseSBiZXR0ZXIgdG8gaW5zdGFudGlhdGUgYW4gZW1wdHkgTW9kZWwgKGB2YXIgbSA9IG5ldyBNb2RlbGApLCBjb25uZWN0IGl0IHRvIFtDb21wb25lbnRdKC4uL2NvbXBvbmVudHMvY19jbGFzcy5qcy5odG1sKSdzIFtEYXRhIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL0RhdGEuanMuaHRtbCkgKGUuZy4sIGBtaWxvLm1pbmRlcihtLCAnPDwtPj4nLCBjLmRhdGEpO2ApIGFuZCB0aGVuIHNldCB0aGUgbW9kZWwgd2l0aCBgbS5zZXQoZGF0YSlgIC0gdGhlIHZpZXcgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBvcHRpb25hbCBvYmplY3QgdGhhdCBob3N0cyBtb2RlbCBvbiBvbmUgb2YgaXRzIHByb3BlcnRpZXMuIENhbiBiZSB1c2VkIHdoZW4gbW9kZWwgaXRzZWxmIGlzIHRoZSBjb250ZXh0IG9mIHRoZSBtZXNzYWdlIHN1YnNjcmliZXIgYW5kIHlvdSBuZWVkIHRvIHRyYXZlcnMgdG8gdGhpcyBvYmplY3QgKGFsdGhvdWdoIGl0IGlzIHBvc3NpYmxlIHRvIHNldCBhbnkgY29udGV4dCkuIENhbiBhbHNvIGJlIHVzZWQgdG8gcHJveHkgbW9kZWwncyBtZXRob2RzIHRvIHRoZSBob3N0IGxpa2UgW01vZGVsIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL01vZGVsRmFjZXQuanMuaHRtbCkgaXMgZG9pbmcuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBwYXNzIHsgcmVhY3RpdmU6IGZhbHNlIH0gdG8gdXNlIG1vZGVsIHdpdGhvdXQgbWVzc2FnaW5nIHdoZW4gaXQgaXMgbm90IG5lZWRlZCAtIGl0IG1ha2VzIGl0IG11Y2ggZmFzdGVyXG4gKiBAcmV0dXJuIHtNb2RlbH1cbiAqL1xuZnVuY3Rpb24gTW9kZWwoZGF0YSwgaG9zdE9iamVjdCwgb3B0aW9ucykge1xuICAgIC8vIGBtb2RlbGAgd2lsbCBiZSByZXR1cm5lZCBieSBjb25zdHJ1Y3RvciBpbnN0ZWFkIG9mIGB0aGlzYC4gYG1vZGVsYFxuICAgIC8vIChgbW9kZWxQYXRoYCBmdW5jdGlvbikgc2hvdWxkIHJldHVybiBhIE1vZGVsUGF0aCBvYmplY3Qgd2l0aCBcInN5bnRoZXNpemVkXCIgbWV0aG9kc1xuICAgIC8vIHRvIGdldC9zZXQgbW9kZWwgcHJvcGVydGllcywgdG8gc3Vic2NyaWJlIHRvIHByb3BlcnR5IGNoYW5nZXMsIGV0Yy5cbiAgICAvLyBBZGRpdGlvbmFsIGFyZ3VtZW50cyBvZiBtb2RlbFBhdGggY2FuIGJlIHVzZWQgaW4gdGhlIHBhdGggdXNpbmcgaW50ZXJwb2xhdGlvbiAtIHNlZSBNb2RlbFBhdGggYmVsb3cuXG4gICAgdmFyIG1vZGVsID0gZnVuY3Rpb24gbW9kZWxQYXRoKGFjY2Vzc1BhdGgpIHsgLy8gLCAuLi4gYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBpbnRlcnBvbGF0ZWRcbiAgICAgICAgcmV0dXJuIE1vZGVsJHBhdGguYXBwbHkobW9kZWwsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgICBtb2RlbC5fX3Byb3RvX18gPSBNb2RlbC5wcm90b3R5cGU7XG5cbiAgICBtb2RlbC5faG9zdE9iamVjdCA9IGhvc3RPYmplY3Q7XG4gICAgbW9kZWwuX29wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgaWYgKG1vZGVsLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xuICAgICAgICBtb2RlbC5fcHJlcGFyZU1lc3NlbmdlcnMoKTtcbiAgICAgICAgLy8gc3Vic2NyaWJlIHRvIFwiY2hhbmdlZGF0YVwiIG1lc3NhZ2UgdG8gZW5hYmxlIHJlYWN0aXZlIGNvbm5lY3Rpb25zXG4gICAgICAgIG1vZGVsLm9uU3luYygnY2hhbmdlZGF0YScsIGNoYW5nZURhdGFIYW5kbGVyKTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YSkgbW9kZWwuX2RhdGEgPSBkYXRhO1xuXG4gICAgcmV0dXJuIG1vZGVsO1xufVxuXG5Nb2RlbC5wcm90b3R5cGUuX19wcm90b19fID0gTW9kZWwuX19wcm90b19fO1xuXG5cbi8qKlxuICogIyMjI01vZGVsIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbcGF0aF0oI3BhdGgpIC0gcmV0dXJucyBNb2RlbFBhdGggb2JqZWN0IHRoYXQgYWxsb3dzIGFjY2VzcyB0byBhbnkgcG9pbnQgaW4gTW9kZWxcbiAqIC0gW2dldF0oI01vZGVsJGdldCkgLSBnZXQgbW9kZWwgZGF0YVxuICogLSBzZXQgLSBzZXQgbW9kZWwgZGF0YSwgc3ludGhlc2l6ZWRcbiAqIC0gc3BsaWNlIC0gc3BsaWNlIG1vZGVsIGRhdGEgKGFzIGFycmF5IG9yIHBzZXVkby1hcnJheSksIHN5bnRoZXNpemVkXG4gKiAtIFtsZW5dKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJGxlbikgLSByZXR1cm5zIGxlbmd0aCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbCBpbiBzYWZlIHdheSwgMCBpZiBubyBsZW5ndGggaXMgc2V0XG4gKiAtIFtwdXNoXSguL21fcGF0aC5qcy5odG1sI01vZGVsUGF0aCRwdXNoKSAtIGFkZCBpdGVtcyB0byB0aGUgZW5kIG9mIGFycmF5IChvciBwc2V1ZG8tYXJyYXkpIGluIG1vZGVsXG4gKiAtIFtwb3BdKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJHBvcCkgLSByZW1vdmUgaXRlbSBmcm9tIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gbW9kZWxcbiAqIC0gW3Vuc2hpZnRdKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJHVuc2hpZnQpIC0gYWRkIGl0ZW1zIHRvIHRoZSBiZWdpbm5pbmcgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gbW9kZWxcbiAqIC0gW3NoaWZ0XSguL21fcGF0aC5qcy5odG1sI01vZGVsUGF0aCRzaGlmdCkgLSByZW1vdmUgaXRlbSBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gbW9kZWxcbiAqIC0gW3Byb3h5TWVzc2VuZ2VyXSgjcHJveHlNZXNzZW5nZXIpIC0gcHJveHkgbW9kZWwncyBNZXNzZW5nZXIgbWV0aG9kcyB0byBob3N0IG9iamVjdFxuICogLSBbcHJveHlNZXRob2RzXSgjcHJveHlNZXRob2RzKSAtIHByb3h5IG1vZGVsIG1ldGhvZHMgdG8gaG9zdCBvYmplY3RcbiAqL1xuXy5leHRlbmRQcm90byhNb2RlbCwge1xuICAgIHBhdGg6IE1vZGVsJHBhdGgsXG4gICAgZ2V0OiBNb2RlbCRnZXQsXG4gICAgcHJveHlNZXNzZW5nZXI6IHByb3h5TWVzc2VuZ2VyLCAvLyBkZXByZWNhdGVkLCBzaG91bGQgbm90IGJlIHVzZWRcbiAgICBwcm94eU1ldGhvZHM6IHByb3h5TWV0aG9kcyxcbiAgICBfcHJlcGFyZU1lc3NlbmdlcnM6IF9wcmVwYXJlTWVzc2VuZ2VycyxcbiAgICBfZ2V0SG9zdE9iamVjdDogX2dldEhvc3RPYmplY3QsXG4gICAgZGVzdHJveTogTW9kZWwkZGVzdHJveVxufSk7XG5cbi8vIHNldCwgZGVsLCBzcGxpY2UgYXJlIGFkZGVkIHRvIG1vZGVsXG5fLmV4dGVuZFByb3RvKE1vZGVsLCBzeW50aGVzaXplLm1vZGVsTWV0aG9kcyk7XG5cblxuLyoqXG4gKiAtIFBhdGg6IE1vZGVsUGF0aCBjbGFzcyBhcyBgbWlsby5Nb2RlbC5QYXRoYFxuICogLSBbcmVnaXN0ZXJXaXRoRE9NU3RvcmFnZV0oI01vZGVsJCRyZWdpc3RlcldpdGhET01TdG9yYWdlKVxuICovXG5fLmV4dGVuZChNb2RlbCwge1xuICAgIFBhdGg6IE1vZGVsUGF0aCxcbiAgICByZWdpc3RlcldpdGhET01TdG9yYWdlOiBNb2RlbCQkcmVnaXN0ZXJXaXRoRE9NU3RvcmFnZSxcbiAgICB1c2VXaXRoOiBNb2RlbCQkdXNlV2l0aFxufSk7XG5cblxuLyoqXG4gKiBFeHBvc2UgTWVzc2VuZ2VyIG1ldGhvZHMgb24gRmFjZXQgcHJvdG90eXBlXG4gKi9cbnZhciBNRVNTRU5HRVJfUFJPUEVSVFkgPSAnX21lc3Nlbmdlcic7XG5NZXNzZW5nZXIudXNlV2l0aChNb2RlbCwgTUVTU0VOR0VSX1BST1BFUlRZLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMpO1xuXG5cbi8qKlxuICogTW9kZWxQYXRoIG1ldGhvZHMgYWRkZWQgdG8gTW9kZWwgcHJvdG90eXBlXG4gKi9cblsnbGVuJywgJ3B1c2gnLCAncG9wJywgJ3Vuc2hpZnQnLCAnc2hpZnQnXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICB2YXIgbWV0aG9kID0gTW9kZWxQYXRoLnByb3RvdHlwZVttZXRob2ROYW1lXTtcbiAgICBfLmRlZmluZVByb3BlcnR5KE1vZGVsLnByb3RvdHlwZSwgbWV0aG9kTmFtZSwgbWV0aG9kKTtcbn0pO1xuXG5cbi8qKlxuICogTW9kZWwgaW5zdGFuY2UgbWV0aG9kLlxuICogR2V0IG1vZGVsIGRhdGEuXG4gKlxuICogQHJldHVybiB7QW55fVxuICovXG5mdW5jdGlvbiBNb2RlbCRnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGE7XG59XG5cblxuLyoqXG4gKiBNb2RlbCBpbnN0YW5jZSBtZXRob2QuXG4gKiBSZXR1cm5zIE1vZGVsUGF0aCBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHRoZSBzYW1lIEFQSSBhcyBtb2RlbCBidXQgYWxsb3dzIGFjY2VzcyB0byBhbnkgcG9pbnQgaW5zaWRlIG1vZGVsIGFzIGRlZmluZWQgYnkgYGFjY2Vzc1BhdGhgLlxuICogU2VlIFtNb2RlbFBhdGhdKC4vbV9wYXRoLmpzLmh0bWwpIGNsYXNzIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY2Nlc3NQYXRoIHN0cmluZyB0aGF0IGRlZmluZXMgcGF0aCB0byBhY2Nlc3MgbW9kZWwuXG4gKiAgUGF0aCBzdHJpbmcgY29uc2lzdHMgb2YgcGFydHMgdG8gZGVmaW5lIGVpdGhlciBwcm9wZXJ0eSBhY2Nlc3MgKGBcIi5uYW1lXCJgIHRvIGFjY2VzcyBwcm9wZXJ0eSBuYW1lKSBvciBhcnJheSBpdGVtIGFjY2VzcyAoYFwiWzFdXCJgIHRvIGFjY2VzcyBpdGVtIHdpdGggaW5kZXggMSkuXG4gKiAgQWNjZXNzIHBhdGggY2FuIGNvbnRhaW4gYXMgbWFueSBwYXJ0cyBhcyBuZWNlc3NhcnkgKGUuZy4gYFwiLmxpc3RbMF0ubmFtZVwiYCB0byBhY2Nlc3MgcHJvcGVydHkgYG5hbWVgIGluIHRoZSBmaXJzdCBlbGVtZW50IG9mIGFycmF5IHN0b3JlZCBpbiBwcm9wZXJ0eSBgbGlzdGAuXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBhZGRpdGlvbmFsIGFyZ3VtZW50cyBvZiB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgaW50ZXJwb2xhdGVkIHBhdGhzLlxuICogIEUuZy4gYG0ucGF0aChcIlskMV0uJDJcIiwgaWQsIHByb3ApYCByZXR1cm5zIE1vZGVsUGF0aCB0byBhY2Nlc3MgcHJvcGVydHkgd2l0aCBuYW1lIGBwcm9wYCBpbiBhcnJheSBpdGVtIHdpdGggaW5kZXggYGlkYC4gQWx0aG91Z2ggdGhpcyBNb2RlbFBhdGggb2JqZWN0IHdpbGwgd29yayBleGFjdGx5IGFzIGBtKFwiW1wiICsgaWQgKyBcIl0uXCIgKyBwcm9wKWAsIHRoZSBpbnRlcnBvbGF0ZWQgaXMgbXVjaCBtb3JlIGVmZmljaWVudCBhcyBNb2RlbFBhdGggd2l0aCBpbnRlcnBvbGF0aW9uIHdpbGwgbm90IHN5bnRoZXNpemUgbmV3IGdldHRlcnMgYW5kIHNldHRlcnMsIHdoaWxlIE1vZGVsUGF0aCB3aXRoIGNvbXB1dGVkIGFjY2VzcyBwYXRoIHdpbGwgc3ludGhlc2l6ZSBuZXcgZ2V0dGVycyBhbmQgc2V0dGVycyBmb3IgZWFjaCBwYWlyIG9mIHZhbHVlcyBvZiBgaWRgIGFuZCBgcHJvcGAuXG4gKiBAcmV0dXJuIHtNb2RlbFBhdGh9XG4gKi9cbmZ1bmN0aW9uIE1vZGVsJHBhdGgoYWNjZXNzUGF0aCkgeyAgLy8gLCAuLi4gYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBpbnRlcnBvbGF0ZWRcbiAgICBpZiAoISBhY2Nlc3NQYXRoKSByZXR1cm4gdGhpcztcblxuICAgIC8vIFwibnVsbFwiIGlzIGNvbnRleHQgdG8gcGFzcyB0byBNb2RlbFBhdGgsIGZpcnN0IHBhcmFtZXRlciBvZiBiaW5kXG4gICAgLy8gXCJ0aGlzXCIgKG1vZGVsKSBpcyBhZGRlZCBpbiBmcm9udCBvZiBhbGwgYXJndW1lbnRzXG4gICAgXy5zcGxpY2UoYXJndW1lbnRzLCAwLCAwLCBudWxsLCB0aGlzKTtcblxuICAgIC8vIGNhbGxpbmcgTW9kZWxQYXRoIGNvbnN0cnVjdG9yIHdpdGggbmV3IGFuZCB0aGUgbGlzdCBvZiBhcmd1bWVudHM6IHRoaXMgKG1vZGVsKSwgYWNjZXNzUGF0aCwgLi4uXG4gICAgcmV0dXJuIG5ldyAoRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuYXBwbHkoTW9kZWxQYXRoLCBhcmd1bWVudHMpKTtcbn1cblxuXG4vKipcbiAqIE1vZGVsIGluc3RhbmNlIG1ldGhvZC5cbiAqIFByb3h5IG1vZGVsJ3MgTWVzc2VuZ2VyIG1ldGhvZHMgdG8gaG9zdCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1vZGVsSG9zdE9iamVjdCBvcHRpb25hbCBob3N0IG9iamVjdC4gSWYgbm90IHBhc3NlZCwgaG9zdE9iamVjdCBwYXNzZWQgdG8gTW9kZWwgY29uc3RydWN0b3Igd2lsbCBiZSB1c2VkLlxuICovXG5mdW5jdGlvbiBwcm94eU1lc3Nlbmdlcihtb2RlbEhvc3RPYmplY3QpIHtcbiAgICBtb2RlbEhvc3RPYmplY3QgPSBtb2RlbEhvc3RPYmplY3QgfHwgdGhpcy5faG9zdE9iamVjdDtcbiAgICBNaXhpbi5wcm90b3R5cGUuX2NyZWF0ZVByb3h5TWV0aG9kcy5jYWxsKHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXSwgTWVzc2VuZ2VyLmRlZmF1bHRNZXRob2RzLCBtb2RlbEhvc3RPYmplY3QpO1xufVxuXG5cbnZhciBtb2RlbE1ldGhvZHNUb1Byb3h5ID0gWydwYXRoJywgJ2dldCcsICdzZXQnLCAnZGVsJywgJ3NwbGljZScsICdsZW4nLCAncHVzaCcsICdwb3AnLCAndW5zaGlmdCcsICdzaGlmdCddO1xuXG5cbi8qKlxuICogRXhwb3NlIG1vZGVsIG1ldGhvZHMgb25cbiAqIFNlZSBzYW1lIG1ldGhvZCBpbiBNaXhpbiBjbGFzcyBmb3IgcGFyYW1ldGVycyBtZWFuaW5nXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaG9zdENsYXNzXG4gKiBAcGFyYW0ge1t0eXBlXX0gaW5zdGFuY2VLZXlcbiAqIEBwYXJhbSB7W3R5cGVdfSBtaXhpbk1ldGhvZHMgb3B0aW9uYWxcbiAqL1xuZnVuY3Rpb24gTW9kZWwkJHVzZVdpdGgoaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2RzKSB7XG4gICAgbWl4aW5NZXRob2RzID0gbWl4aW5NZXRob2RzIHx8IG1vZGVsTWV0aG9kc1RvUHJveHk7XG4gICAgTWl4aW4udXNlV2l0aC5jYWxsKE1vZGVsLCBob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtaXhpbk1ldGhvZHMpO1xufVxuXG5cbi8qKlxuICogTW9kZWwgaW5zdGFuY2UgbWV0aG9kLlxuICogUHJveHkgbW9kZWwgbWV0aG9kcyB0byBob3N0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbW9kZWxIb3N0T2JqZWN0IG9wdGlvbmFsIGhvc3Qgb2JqZWN0LiBJZiBub3QgcGFzc2VkLCBob3N0T2JqZWN0IHBhc3NlZCB0byBNb2RlbCBjb25zdHJ1Y3RvciB3aWxsIGJlIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHByb3h5TWV0aG9kcyhtb2RlbEhvc3RPYmplY3QpIHtcbiAgICBtb2RlbEhvc3RPYmplY3QgPSBtb2RlbEhvc3RPYmplY3QgfHwgdGhpcy5faG9zdE9iamVjdDtcbiAgICBNaXhpbi5wcm90b3R5cGUuX2NyZWF0ZVByb3h5TWV0aG9kcy5jYWxsKHRoaXMsIG1vZGVsTWV0aG9kc1RvUHJveHksIG1vZGVsSG9zdE9iamVjdCk7XG59XG5cblxuLyoqXG4gKiBNb2RlbCBpbnN0YW5jZSBtZXRob2QuXG4gKiBDcmVhdGUgYW5kIGNvbm5lY3QgaW50ZXJuYWwgYW5kIGV4dGVybmFsIG1vZGVsJ3MgbWVzc2VuZ2Vycy5cbiAqIEV4dGVybmFsIG1lc3NlbmdlcidzIG1ldGhvZHMgYXJlIHByb3hpZWQgb24gdGhlIG1vZGVsIGFuZCB0aGV5IGFsbG93cyBcIipcIiBzdWJzY3JpcHRpb25zLlxuICovXG5mdW5jdGlvbiBfcHJlcGFyZU1lc3NlbmdlcnMoKSB7XG4gICAgLy8gbW9kZWwgd2lsbCBwb3N0IGFsbCBpdHMgY2hhbmdlcyBvbiBpbnRlcm5hbCBtZXNzZW5nZXJcbiAgICB2YXIgaW50ZXJuYWxNZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKTtcblxuICAgIC8vIG1lc3NhZ2Ugc291cmNlIHRvIGNvbm5lY3QgaW50ZXJuYWwgbWVzc2VuZ2VyIHRvIGV4dGVybmFsXG4gICAgdmFyIGludGVybmFsTWVzc2VuZ2VyU291cmNlID0gbmV3IE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UodGhpcywgdW5kZWZpbmVkLCBuZXcgTW9kZWxNc2dBUEksIGludGVybmFsTWVzc2VuZ2VyKTtcblxuICAgIC8vIGV4dGVybmFsIG1lc3NlbmdlciB0byB3aGljaCBhbGwgbW9kZWwgdXNlcnMgd2lsbCBzdWJzY3JpYmUsXG4gICAgLy8gdGhhdCB3aWxsIGFsbG93IFwiKlwiIHN1YnNjcmlwdGlvbnMgYW5kIHN1cHBvcnQgXCJjaGFuZ2VkYXRhXCIgbWVzc2FnZSBhcGkuXG4gICAgdmFyIGV4dGVybmFsTWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzLCB1bmRlZmluZWQsIGludGVybmFsTWVzc2VuZ2VyU291cmNlKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgTUVTU0VOR0VSX1BST1BFUlRZLCBleHRlcm5hbE1lc3Nlbmdlcik7XG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnX2ludGVybmFsTWVzc2VuZ2VyJywgaW50ZXJuYWxNZXNzZW5nZXIpO1xufVxuXG5cbmZ1bmN0aW9uIF9nZXRIb3N0T2JqZWN0KCkge1xuICAgIHJldHVybiB0aGlzLl9ob3N0T2JqZWN0O1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsJCRyZWdpc3RlcldpdGhET01TdG9yYWdlKCkge1xuICAgIHZhciBET01TdG9yYWdlID0gcmVxdWlyZSgnLi4vdXRpbC9zdG9yYWdlJyk7XG4gICAgRE9NU3RvcmFnZS5yZWdpc3RlckRhdGFUeXBlKCdNb2RlbCcsIE1vZGVsX2RvbVN0b3JhZ2VTZXJpYWxpemVyLCBNb2RlbF9kb21TdG9yYWdlUGFyc2VyKTtcbiAgICBET01TdG9yYWdlLnJlZ2lzdGVyRGF0YVR5cGUoJ01vZGVsUGF0aCcsIE1vZGVsX2RvbVN0b3JhZ2VTZXJpYWxpemVyLCBNb2RlbF9kb21TdG9yYWdlUGFyc2VyLCAnTW9kZWwnKTtcbn1cblxuXG5mdW5jdGlvbiBNb2RlbF9kb21TdG9yYWdlU2VyaWFsaXplcih2YWx1ZSkge1xuICAgIHZhciBkYXRhID0gdmFsdWUuZ2V0KCk7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsX2RvbVN0b3JhZ2VQYXJzZXIodmFsdWVTdHIpIHtcbiAgICB2YXIgZGF0YSA9IGpzb25QYXJzZSh2YWx1ZVN0cik7XG4gICAgcmV0dXJuIG5ldyBNb2RlbChkYXRhKTtcbn1cblxuXG5mdW5jdGlvbiBNb2RlbCRkZXN0cm95KCkge1xuICAgIHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXS5kZXN0cm95KCk7XG4gICAgdGhpcy5faW50ZXJuYWxNZXNzZW5nZXIuZGVzdHJveSgpO1xuICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNZXNzZW5nZXJSZWdleHBBUEkgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXIvbV9hcGlfcngnKVxuICAgICwgcGF0aFV0aWxzID0gcmVxdWlyZSgnLi9wYXRoX3V0aWxzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqIFN1YmNsYXNzIG9mIE1lc3NlbmdlclJlZ2V4cEFQSSB0aGF0IGlzIHVzZWQgdG8gdHJhbnNsYXRlIG1lc3NhZ2VzIG9mIGV4dGVybmFsIG1lc3NlbmdlciBvZiBNb2RlbCB0byBpbnRlcm5hbCBtZXNzZW5nZXIgb2YgTW9kZWwuXG4gKi9cbnZhciBNb2RlbE1zZ0FQSSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2VuZ2VyUmVnZXhwQVBJLCAnTW9kZWxNc2dBUEknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNb2RlbE1zZ0FQSTtcblxuXG4vKipcbiAqICMjIyNNb2RlbE1zZ0FQSSBpbnN0YW5jZSBtZXRob2RzIyMjI1xuICpcbiAqIC0gW3RyYW5zbGF0ZVRvU291cmNlTWVzc2FnZV0oI3RyYW5zbGF0ZVRvU291cmNlTWVzc2FnZSkgLSB0cmFuc2xhdGVzIHN1YnNjcmlwdGlvbiBwYXRocyB3aXRoIFwiKlwicyB0byByZWdleCwgbGVhdmluZyBvdGhlciBzdHJpbmdzIHVudG91Y2hlZFxuICovXG5fLmV4dGVuZFByb3RvKE1vZGVsTXNnQVBJLCB7XG4gICAgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlOiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UsXG59KTtcblxuXG4vKipcbiAqIE1vZGVsTXNnQVBJIGluc3RhbmNlIG1ldGhvZFxuICogVHJhbnNsYXRlcyBzdWJzY3JpcHRpb24gcGF0aHMgd2l0aCBcIipcInMgdG8gcmVnZXgsIGxlYXZpbmcgb3RoZXIgc3RyaW5ncyB1bnRvdWNoZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2Vzc1BhdGggcmVsYXRpdmUgYWNjZXNzIHBhdGggdG8gYmUgdHJhbnNsYXRlZFxuICogQHJldHVybiB7UmVnRXhwfFN0cmluZ31cbiAqL1xuZnVuY3Rpb24gdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlKGFjY2Vzc1BhdGgpIHtcbiAgICBpZiAoYWNjZXNzUGF0aCBpbnN0YW5jZW9mIFJlZ0V4cCkgcmV0dXJuIGFjY2Vzc1BhdGg7XG5cbiAgICByZXR1cm4gcGF0aFV0aWxzLmNyZWF0ZVJlZ2V4UGF0aChhY2Nlc3NQYXRoKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHN5bnRoZXNpemUgPSByZXF1aXJlKCcuL3N5bnRoZXNpemUnKVxuICAgICwgcGF0aFV0aWxzID0gcmVxdWlyZSgnLi9wYXRoX3V0aWxzJylcbiAgICAsIGNoYW5nZURhdGFIYW5kbGVyID0gcmVxdWlyZSgnLi9jaGFuZ2VfZGF0YScpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgTW9kZWxQYXRoTXNnQVBJID0gcmVxdWlyZSgnLi9wYXRoX21zZ19hcGknKVxuICAgICwgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4uL21lc3Nlbmdlci9tc25ncl9zb3VyY2UnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsUGF0aDtcblxuXG4vKipcbiAqIGBtaWxvLk1vZGVsLlBhdGhgXG4gKiBNb2RlbFBhdGggb2JqZWN0IHRoYXQgYWxsb3dzIGFjY2VzcyB0byBhbnkgcG9pbnQgaW5zaWRlIFtNb2RlbF0oLi9pbmRleC5qcy5odG1sKSBhcyBkZWZpbmVkIGJ5IGBhY2Nlc3NQYXRoYFxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtNb2RlbH0gbW9kZWwgTW9kZWwgaW5zdGFuY2UgdGhhdCBNb2RlbFBhdGggZ2l2ZXMgYWNjZXNzIHRvLlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2Vzc1BhdGggc3RyaW5nIHRoYXQgZGVmaW5lcyBwYXRoIHRvIGFjY2VzcyBtb2RlbC5cbiAqICBQYXRoIHN0cmluZyBjb25zaXN0cyBvZiBwYXJ0cyB0byBkZWZpbmUgZWl0aGVyIHByb3BlcnR5IGFjY2VzcyAoYFwiLm5hbWVcImAgdG8gYWNjZXNzIHByb3BlcnR5IG5hbWUpIG9yIGFycmF5IGl0ZW0gYWNjZXNzIChgXCJbMV1cImAgdG8gYWNjZXNzIGl0ZW0gd2l0aCBpbmRleCAxKS5cbiAqICBBY2Nlc3MgcGF0aCBjYW4gY29udGFpbiBhcyBtYW55IHBhcnRzIGFzIG5lY2Vzc2FyeSAoZS5nLiBgXCIubGlzdFswXS5uYW1lXCJgIHRvIGFjY2VzcyBwcm9wZXJ0eSBgbmFtZWAgaW4gdGhlIGZpcnN0IGVsZW1lbnQgb2YgYXJyYXkgc3RvcmVkIGluIHByb3BlcnR5IGBsaXN0YC5cbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFkZGl0aW9uYWwgYXJndW1lbnRzIG9mIHRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBpbnRlcnBvbGF0ZWQgcGF0aHMuXG4gKiAgRS5nLiBgbS5wYXRoKFwiWyQxXS4kMlwiLCBpZCwgcHJvcClgIHJldHVybnMgTW9kZWxQYXRoIHRvIGFjY2VzcyBwcm9wZXJ0eSB3aXRoIG5hbWUgYHByb3BgIGluIGFycmF5IGl0ZW0gd2l0aCBpbmRleCBgaWRgLiBBbHRob3VnaCB0aGlzIE1vZGVsUGF0aCBvYmplY3Qgd2lsbCB3b3JrIGV4YWN0bHkgYXMgYG0oXCJbXCIgKyBpZCArIFwiXS5cIiArIHByb3ApYCwgdGhlIGludGVycG9sYXRlZCBpcyBtdWNoIG1vcmUgZWZmaWNpZW50IGFzIE1vZGVsUGF0aCB3aXRoIGludGVycG9sYXRpb24gd2lsbCBub3Qgc3ludGhlc2l6ZSBuZXcgZ2V0dGVycyBhbmQgc2V0dGVycywgd2hpbGUgTW9kZWxQYXRoIHdpdGggY29tcHV0ZWQgYWNjZXNzIHBhdGggd2lsbCBzeW50aGVzaXplIG5ldyBnZXR0ZXJzIGFuZCBzZXR0ZXJzIGZvciBlYWNoIHBhaXIgb2YgdmFsdWVzIG9mIGBpZGAgYW5kIGBwcm9wYC5cbiAqIEByZXR1cm4ge01vZGVsUGF0aH1cbiAqL1xuZnVuY3Rpb24gTW9kZWxQYXRoKG1vZGVsLCBwYXRoKSB7IC8vICwuLi4gLSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgaW50ZXJwb2xhdGlvblxuICAgIC8vIGNoZWNrKG1vZGVsLCBNb2RlbCk7XG4gICAgY2hlY2socGF0aCwgU3RyaW5nKTtcblxuICAgIC8vIGBtb2RlbFBhdGhgIHdpbGwgYmUgcmV0dXJuZWQgYnkgY29uc3RydWN0b3IgaW5zdGVhZCBvZiBgdGhpc2AuIGBtb2RlbFBhdGhgXG4gICAgLy8gKGBtb2RlbFBhdGhfcGF0aGAgZnVuY3Rpb24pIHNob3VsZCBhbHNvIHJldHVybiBhIE1vZGVsUGF0aCBvYmplY3Qgd2l0aCBcInN5bnRoZXNpemVkXCIgbWV0aG9kc1xuICAgIC8vIHRvIGdldC9zZXQgbW9kZWwgcHJvcGVydGllcywgdG8gc3Vic2NyaWJlIHRvIHByb3BlcnR5IGNoYW5nZXMsIGV0Yy5cbiAgICAvLyBBZGRpdGlvbmFsIGFyZ3VtZW50cyBvZiBtb2RlbFBhdGggY2FuIGJlIHVzZWQgaW4gdGhlIHBhdGggdXNpbmcgaW50ZXJwb2xhdGlvbiAtIHNlZSBNb2RlbFBhdGggYmVsb3cuXG4gICAgdmFyIG1vZGVsUGF0aCA9IGZ1bmN0aW9uIG1vZGVsUGF0aF9wYXRoKGFjY2Vzc1BhdGgpIHsgLy8gLCAuLi4gYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBpbnRlcnBvbGF0ZWRcbiAgICAgICAgcmV0dXJuIE1vZGVsUGF0aCRwYXRoLmFwcGx5KG1vZGVsUGF0aCwgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIG1vZGVsUGF0aC5fX3Byb3RvX18gPSBNb2RlbFBhdGgucHJvdG90eXBlO1xuXG5cbiAgICBfLmRlZmluZVByb3BlcnRpZXMobW9kZWxQYXRoLCB7XG4gICAgICAgIF9tb2RlbDogbW9kZWwsXG4gICAgICAgIF9wYXRoOiBwYXRoLFxuICAgICAgICBfYXJnczogXy5zbGljZShhcmd1bWVudHMsIDEpLCAvLyBwYXRoIHdpbGwgYmUgdGhlIGZpcnN0IGVsZW1lbnQgb2YgdGhpcyBhcnJheVxuICAgICAgICBfb3B0aW9uczogbW9kZWwuX29wdGlvbnNcbiAgICB9KTtcblxuICAgIC8vIHBhcnNlIGFjY2VzcyBwYXRoXG4gICAgdmFyIHBhcnNlZFBhdGggPSBwYXRoVXRpbHMucGFyc2VBY2Nlc3NQYXRoKHBhdGgpO1xuXG4gICAgLy8gY29tcHV0ZSBhY2Nlc3MgcGF0aCBzdHJpbmdcbiAgICBfLmRlZmluZVByb3BlcnR5KG1vZGVsUGF0aCwgJ19hY2Nlc3NQYXRoJywgaW50ZXJwb2xhdGVBY2Nlc3NQYXRoKHBhcnNlZFBhdGgsIG1vZGVsUGF0aC5fYXJncykpO1xuXG4gICAgaWYgKG1vZGVsUGF0aC5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgLy8gbWVzc2VuZ2VyIGZhaWxzIG9uIFwiKlwiIHN1YnNjcmlwdGlvbnNcbiAgICAgICAgbW9kZWxQYXRoLl9wcmVwYXJlTWVzc2VuZ2VyKCk7XG4gICAgICAgIC8vIHN1YnNjcmliZSB0byBcImNoYW5nZWRhdGFcIiBtZXNzYWdlIHRvIGVuYWJsZSByZWFjdGl2ZSBjb25uZWN0aW9uc1xuICAgICAgICBtb2RlbFBhdGgub25TeW5jKCdjaGFuZ2VkYXRhJywgY2hhbmdlRGF0YUhhbmRsZXIpO1xuICAgIH1cblxuICAgIC8vIGNvbXBpbGluZyBnZXR0ZXIgYW5kIHNldHRlclxuICAgIHZhciBtZXRob2RzID0gc3ludGhlc2l6ZShwYXRoLCBwYXJzZWRQYXRoKTtcblxuICAgIC8vIGFkZGluZyBtZXRob2RzIHRvIG1vZGVsIHBhdGhcbiAgICBfLmRlZmluZVByb3BlcnRpZXMobW9kZWxQYXRoLCBtZXRob2RzKTtcblxuICAgIE9iamVjdC5mcmVlemUobW9kZWxQYXRoKTtcblxuICAgIHJldHVybiBtb2RlbFBhdGg7XG59XG5cbk1vZGVsUGF0aC5wcm90b3R5cGUuX19wcm90b19fID0gTW9kZWxQYXRoLl9fcHJvdG9fXztcblxuXG4vKipcbiAqIEludGVycG9sYXRlcyBwYXRoIGVsZW1lbnRzIHRvIGNvbXB1dGUgcmVhbCBwYXRoXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFyc2VkUGF0aCBwYXJzZWQgcGF0aCAtIGFycmF5IG9mIHBhdGggbm9kZXNcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgcGF0aCBpbnRlcnBvbGF0aW9uIGFyZ3VtZW50cywgYXJnc1swXSBpcyBwYXRoIGl0c2VsZlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZUFjY2Vzc1BhdGgocGFyc2VkUGF0aCwgYXJncykge1xuICAgIHJldHVybiBwYXJzZWRQYXRoLnJlZHVjZShmdW5jdGlvbihhY2Nlc3NQYXRoU3RyLCBjdXJyTm9kZSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGludGVycG9sYXRlID0gY3Vyck5vZGUuaW50ZXJwb2xhdGU7XG4gICAgICAgIHJldHVybiBhY2Nlc3NQYXRoU3RyICtcbiAgICAgICAgICAgICAgICAoaW50ZXJwb2xhdGVcbiAgICAgICAgICAgICAgICAgICAgPyAoY3Vyck5vZGUuc3ludGF4ID09ICdhcnJheSdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gJ1snICsgYXJnc1tpbnRlcnBvbGF0ZV0gKyAnXSdcbiAgICAgICAgICAgICAgICAgICAgICAgIDogJy4nICsgYXJnc1tpbnRlcnBvbGF0ZV0pXG4gICAgICAgICAgICAgICAgICAgIDogY3Vyck5vZGUucHJvcGVydHkpO1xuICAgIH0sICcnKTtcbn1cblxuXG4vKipcbiAqICMjIyNNb2RlbFBhdGggaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtwYXRoXSgjTW9kZWxQYXRoJHBhdGgpIC0gZ2l2ZXMgYWNjZXNzIHRvIHBhdGggaW5zaWRlIE1vZGVsUGF0aFxuICogLSBnZXQgLSBzeW50aGVzaXplZFxuICogLSBzZXQgLSBzeW50aGVzaXplZFxuICogLSBzcGxpY2UgLSBzcGxpY2UgbW9kZWwgZGF0YSAoYXMgYXJyYXkgb3IgcHNldWRvLWFycmF5KSwgc3ludGhlc2l6ZWRcbiAqIC0gW2xlbl0oI01vZGVsUGF0aCRsZW4pIC0gcmV0dXJucyBsZW5ndGggb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gc2FmZSB3YXksIDAgaWYgbm8gbGVuZ3RoIGlzIHNldFxuICogLSBbcHVzaF0oI01vZGVsUGF0aCRwdXNoKSAtIGFkZCBpdGVtcyB0byB0aGUgZW5kIG9mIGFycmF5IChvciBwc2V1ZG8tYXJyYXkpIGluIE1vZGVsUGF0aFxuICogLSBbcG9wXSgjTW9kZWxQYXRoJHBvcCkgLSByZW1vdmUgaXRlbSBmcm9tIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gTW9kZWxQYXRoXG4gKiAtIFt1bnNoaWZ0XSgjTW9kZWxQYXRoJHVuc2hpZnQpIC0gYWRkIGl0ZW1zIHRvIHRoZSBiZWdpbm5pbmcgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gTW9kZWxQYXRoXG4gKiAtIFtzaGlmdF0oI01vZGVsUGF0aCRzaGlmdCkgLSByZW1vdmUgaXRlbSBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gTW9kZWxQYXRoXG4gKi9cbl8uZXh0ZW5kUHJvdG8oTW9kZWxQYXRoLCB7XG4gICAgcGF0aDogTW9kZWxQYXRoJHBhdGgsXG4gICAgbGVuOiBNb2RlbFBhdGgkbGVuLFxuICAgIHB1c2g6IE1vZGVsUGF0aCRwdXNoLFxuICAgIHBvcDogTW9kZWxQYXRoJHBvcCxcbiAgICB1bnNoaWZ0OiBNb2RlbFBhdGgkdW5zaGlmdCxcbiAgICBzaGlmdDogTW9kZWxQYXRoJHNoaWZ0LFxuICAgIF9wcmVwYXJlTWVzc2VuZ2VyOiBfcHJlcGFyZU1lc3NlbmdlcixcbiAgICBfZ2V0RGVmaW5pdGlvbjogX2dldERlZmluaXRpb24sXG4gICAgZGVzdHJveTogTW9kZWxQYXRoJGRlc3Ryb3lcbn0pO1xuXG5cbl8uZXh0ZW5kKE1vZGVsUGF0aCwge1xuICAgIF9jcmVhdGVGcm9tRGVmaW5pdGlvbjogX2NyZWF0ZUZyb21EZWZpbml0aW9uXG59KVxuXG5cbi8qKlxuICogRXhwb3NlIE1lc3NlbmdlciBtZXRob2RzIG9uIEZhY2V0IHByb3RvdHlwZVxuICovXG52YXIgTUVTU0VOR0VSX1BST1BFUlRZID0gJ19tZXNzZW5nZXInO1xuTWVzc2VuZ2VyLnVzZVdpdGgoTW9kZWxQYXRoLCBNRVNTRU5HRVJfUFJPUEVSVFksIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggaW5zdGFuY2UgbWV0aG9kXG4gKiBHaXZlcyBhY2Nlc3MgdG8gcGF0aCBpbnNpZGUgTW9kZWxQYXRoLiBNZXRob2Qgd29ya3Mgc2ltaWxhcmx5IHRvIFtwYXRoIG1ldGhvZF0oI01vZGVsJHBhdGgpIG9mIG1vZGVsLCB1c2luZyByZWxhdGl2ZSBwYXRocy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXNzUGF0aCBzdHJpbmcgdGhhdCBkZWZpbmVzIHBhdGggdG8gYWNjZXNzIG1vZGVsLlxuICogIFBhdGggc3RyaW5nIGNvbnNpc3RzIG9mIHBhcnRzIHRvIGRlZmluZSBlaXRoZXIgcHJvcGVydHkgYWNjZXNzIChgXCIubmFtZVwiYCB0byBhY2Nlc3MgcHJvcGVydHkgbmFtZSkgb3IgYXJyYXkgaXRlbSBhY2Nlc3MgKGBcIlsxXVwiYCB0byBhY2Nlc3MgaXRlbSB3aXRoIGluZGV4IDEpLlxuICogIEFjY2VzcyBwYXRoIGNhbiBjb250YWluIGFzIG1hbnkgcGFydHMgYXMgbmVjZXNzYXJ5IChlLmcuIGBcIi5saXN0WzBdLm5hbWVcImAgdG8gYWNjZXNzIHByb3BlcnR5IGBuYW1lYCBpbiB0aGUgZmlyc3QgZWxlbWVudCBvZiBhcnJheSBzdG9yZWQgaW4gcHJvcGVydHkgYGxpc3RgLlxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgYWRkaXRpb25hbCBhcmd1bWVudHMgb2YgdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGludGVycG9sYXRlZCBwYXRocy5cbiAqICBFLmcuIGBtLnBhdGgoXCJbJDFdLiQyXCIsIGlkLCBwcm9wKWAgcmV0dXJucyBNb2RlbFBhdGggdG8gYWNjZXNzIHByb3BlcnR5IHdpdGggbmFtZSBgcHJvcGAgaW4gYXJyYXkgaXRlbSB3aXRoIGluZGV4IGBpZGAuIEFsdGhvdWdoIHRoaXMgTW9kZWxQYXRoIG9iamVjdCB3aWxsIHdvcmsgZXhhY3RseSBhcyBgbShcIltcIiArIGlkICsgXCJdLlwiICsgcHJvcClgLCB0aGUgaW50ZXJwb2xhdGVkIGlzIG11Y2ggbW9yZSBlZmZpY2llbnQgYXMgTW9kZWxQYXRoIHdpdGggaW50ZXJwb2xhdGlvbiB3aWxsIG5vdCBzeW50aGVzaXplIG5ldyBnZXR0ZXJzIGFuZCBzZXR0ZXJzLCB3aGlsZSBNb2RlbFBhdGggd2l0aCBjb21wdXRlZCBhY2Nlc3MgcGF0aCB3aWxsIHN5bnRoZXNpemUgbmV3IGdldHRlcnMgYW5kIHNldHRlcnMgZm9yIGVhY2ggcGFpciBvZiB2YWx1ZXMgb2YgYGlkYCBhbmQgYHByb3BgLlxuICogQHJldHVybiB7TW9kZWxQYXRofVxuICovXG5mdW5jdGlvbiBNb2RlbFBhdGgkcGF0aChhY2Nlc3NQYXRoKSB7ICAvLyAsIC4uLiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGludGVycG9sYXRlZFxuICAgIGlmICghIGFjY2Vzc1BhdGgpIHJldHVybiB0aGlzO1xuXG4gICAgdmFyIHRoaXNQYXRoQXJnc0NvdW50ID0gdGhpcy5fYXJncy5sZW5ndGggLSAxO1xuXG4gICAgaWYgKHRoaXNQYXRoQXJnc0NvdW50ID4gMCkgey8vIHRoaXMgcGF0aCBoYXMgaW50ZXJwb2xhdGVkIGFyZ3VtZW50cyB0b29cbiAgICAgICAgYWNjZXNzUGF0aCA9IGFjY2Vzc1BhdGgucmVwbGFjZSgvXFwkWzEtOV1bMC05XSovZywgZnVuY3Rpb24oc3RyKSB7XG4gICAgICAgICAgICByZXR1cm4gJyQnICsgKCtzdHIuc2xpY2UoMSkgKyB0aGlzUGF0aEFyZ3NDb3VudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBuZXdQYXRoID0gdGhpcy5fcGF0aCArIGFjY2Vzc1BhdGg7XG5cbiAgICAvLyB0aGlzLl9tb2RlbCBpcyBhZGRlZCBpbiBmcm9udCBvZiBhbGwgYXJndW1lbnRzIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXJcbiAgICAvLyBvZiBNb2RlbFBhdGggY29uc3RydWN0b3JcbiAgICB2YXIgYXJncyA9IFt0aGlzLl9tb2RlbCwgbmV3UGF0aF1cbiAgICAgICAgICAgICAgICAuY29uY2F0KHRoaXMuX2FyZ3Muc2xpY2UoMSkpIC8vIHJlbW92ZSBvbGQgcGF0aCBmcm9tIF9hcmdzLCBhcyBpdCBpcyAxIGJhc2VkXG4gICAgICAgICAgICAgICAgLmNvbmNhdChfLnNsaWNlKGFyZ3VtZW50cywgMSkpOyAvLyBhZGQgbmV3IGludGVycG9sYXRpb24gYXJndW1lbnRzXG5cbiAgICAvLyBjYWxsaW5nIE1vZGVsUGF0aCBjb25zdHJ1Y3RvciB3aXRoIG5ldyBhbmQgdGhlIGxpc3Qgb2YgYXJndW1lbnRzOiB0aGlzIChtb2RlbCksIGFjY2Vzc1BhdGgsIC4uLlxuICAgIHJldHVybiBfLm5ld0FwcGx5KE1vZGVsUGF0aCwgYXJncyk7XG59XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggYW5kIE1vZGVsIGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBsZW5ndGggcHJvcGVydHkgYW5kIHNldHMgaXQgdG8gMCBpZiBpdCB3YXNuJ3Qgc2V0LlxuICpcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gTW9kZWxQYXRoJGxlbigpIHtcbiAgICByZXR1cm4gdGhpcy5wYXRoKCcubGVuZ3RoJykuZ2V0KCkgfHwgMDtcbn1cblxuXG4vKipcbiAqIE1vZGVsUGF0aCBhbmQgTW9kZWwgaW5zdGFuY2UgbWV0aG9kXG4gKiBBZGRzIGl0ZW1zIHRvIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkuIFJldHVybnMgbmV3IGxlbmd0aC5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBsaXN0IG9mIGl0ZW1zIHRoYXQgd2lsbCBiZSBhZGRlZCB0byBhcnJheSAocHNldWRvIGFycmF5KVxuICogQHJldHVybiB7SW50ZWdlcn1cbiAqL1xuZnVuY3Rpb24gTW9kZWxQYXRoJHB1c2goKSB7IC8vIGFyZ3VtZW50c1xuICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbigpO1xuICAgIHZhciBuZXdMZW5ndGggPSBsZW5ndGggKyBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgXy5zcGxpY2UoYXJndW1lbnRzLCAwLCAwLCBsZW5ndGgsIDApO1xuICAgIHRoaXMuc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICByZXR1cm4gbmV3TGVuZ3RoO1xufVxuXG5cbi8qKlxuICogTW9kZWxQYXRoIGFuZCBNb2RlbCBpbnN0YW5jZSBtZXRob2RcbiAqIFJlbW92ZXMgaXRlbSBmcm9tIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkuIFJldHVybnMgdGhpcyBpdGVtLlxuICpcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gTW9kZWxQYXRoJHBvcCgpIHtcbiAgICByZXR1cm4gdGhpcy5zcGxpY2UodGhpcy5sZW4oKSAtIDEsIDEpWzBdO1xufVxuXG5cbi8qKlxuICogTW9kZWxQYXRoIGFuZCBNb2RlbCBpbnN0YW5jZSBtZXRob2RcbiAqIEluc2VydHMgaXRlbXMgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgYXJyYXkuIFJldHVybnMgbmV3IGxlbmd0aC5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBpdGVtcyB0byBiZSBpbnNlcnRlZCBpbiB0aGUgYmVnaW5uaW5nIG9mIGFycmF5XG4gKiBAcmV0dXJuIHtJbnRlZ2VyfVxuICovXG5mdW5jdGlvbiBNb2RlbFBhdGgkdW5zaGlmdCgpIHsgLy8gYXJndW1lbnRzXG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuKCk7XG4gICAgbGVuZ3RoICs9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICBfLnNwbGljZShhcmd1bWVudHMsIDAsIDAsIDAsIDApO1xuICAgIHRoaXMuc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICByZXR1cm4gbGVuZ3RoO1xufVxuXG5cbi8qKlxuICogTW9kZWxQYXRoIGFuZCBNb2RlbCBpbnN0YW5jZSBtZXRob2RcbiAqIFJlbW92ZXMgdGhlIGl0ZW0gZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGFycmF5IChvciBwc2V1ZG8tYXJyYXkpLiBSZXR1cm5zIHRoaXMgaXRlbS5cbiAqXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIE1vZGVsUGF0aCRzaGlmdCgpIHsgLy8gYXJndW1lbnRzXG4gICAgcmV0dXJuIHRoaXMuc3BsaWNlKDAsIDEpWzBdO1xufVxuXG5cbi8qKlxuICogTW9kZWxQYXRoIGluc3RhbmNlIG1ldGhvZFxuICogSW5pdGlhbGl6ZXMgTW9kZWxQYXRoIG1lc2VuZ2VyIHdpdGggTW9kZWwncyBtZXNzZW5nZXIgYXMgaXRzIHNvdXJjZSAoW01lc3Nlbmdlck1lc3NhZ2VTb3VyY2VdKC4uL21lc3Nlbmdlci9tc25ncl9zb3VyY2UuanMuaHRtbCkpIGFuZCBbTW9kZWxQYXRoTXNnQVBJXSguL3BhdGhfbXNnX2FwaS5qcy5odG1sKSBhcyBbTWVzc2VuZ2VyQVBJXSguLi9tZXNzZW5nZXIvbV9hcGkuanMuaHRtbClcbiAqL1xuZnVuY3Rpb24gX3ByZXBhcmVNZXNzZW5nZXIoKSB7XG4gICAgdmFyIG1QYXRoQVBJID0gbmV3IE1vZGVsUGF0aE1zZ0FQSSh0aGlzLl9hY2Nlc3NQYXRoKTtcblxuICAgIC8vIGNyZWF0ZSBNZXNzZW5nZXJNZXNzYWdlU291cmNlIGNvbm5lY3RlZCB0byBNb2RlbCdzIG1lc3NlbmdlclxuICAgIHZhciBtb2RlbE1lc3NhZ2VTb3VyY2UgPSBuZXcgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSh0aGlzLCB1bmRlZmluZWQsIG1QYXRoQVBJLCB0aGlzLl9tb2RlbCk7XG5cbiAgICAvLyBjcmVhdGUgbWVzc2VuZ2VyIHdpdGggbW9kZWwgcGFzc2VkIGFzIGhvc3RPYmplY3QgKGRlZmF1bHQgbWVzc2FnZSBkaXNwYXRjaCBjb250ZXh0KVxuICAgIC8vIGFuZCB3aXRob3V0IHByb3h5aW5nIG1ldGhvZHMgKHdlIGRvbid0IHdhbnQgdG8gcHJveHkgdGhlbSB0byBNb2RlbClcbiAgICB2YXIgbVBhdGhNZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMsIHVuZGVmaW5lZCwgbW9kZWxNZXNzYWdlU291cmNlKTtcblxuICAgIC8vIHN0b3JlIG1lc3NlbmdlciBvbiBNb2RlbFBhdGggaW5zdGFuY2VcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsIE1FU1NFTkdFUl9QUk9QRVJUWSwgbVBhdGhNZXNzZW5nZXIpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgb2JqZWN0IGFsbG93aW5nIHRvIHJlY3JlYXRlIG1vZGVsIHBhdGhcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIF9nZXREZWZpbml0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIG1vZGVsOiB0aGlzLl9tb2RlbCxcbiAgICAgICAgcGF0aDogdGhpcy5fcGF0aCxcbiAgICAgICAgYXJnczogdGhpcy5fYXJnc1xuICAgIH07XG59XG5cblxuLyoqXG4gKiBDbGFzcyBtZXRob2RcbiAqIENyZWF0ZXMgbW9kZWxQYXRoIG9iamVjdCBmcm9tIGRlZmluaXRpb24gY3JlYXRlZCBieSBfZ2V0RGVmaW5pdGlvblxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gZGVmaW5pdGlvblxuICogQHJldHVybiB7TW9kZWxQYXRofVxuICovXG5mdW5jdGlvbiBfY3JlYXRlRnJvbURlZmluaXRpb24oZGVmaW5pdGlvbikge1xuICAgIGNoZWNrKGRlZmluaXRpb24sIHtcbiAgICAgICAgbW9kZWw6IEZ1bmN0aW9uLCAvLyBNb2RlbFxuICAgICAgICBwYXRoOiBTdHJpbmcsXG4gICAgICAgIGFyZ3M6IEFycmF5XG4gICAgfSk7XG5cbiAgICB2YXIgbSA9IGRlZmluaXRpb24ubW9kZWw7XG5cbiAgICByZXR1cm4gbS5hcHBseShtLCBkZWZpbml0aW9uLmFyZ3MpO1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsUGF0aCRkZXN0cm95KCkge1xuICAgIHRoaXNbTUVTU0VOR0VSX1BST1BFUlRZXS5kZXN0cm95KCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIG1vZGVsVXRpbHMgPSB7XG4gICAgbm9ybWFsaXplU3BsaWNlSW5kZXg6IG5vcm1hbGl6ZVNwbGljZUluZGV4XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG1vZGVsVXRpbHM7XG5cblxuZnVuY3Rpb24gbm9ybWFsaXplU3BsaWNlSW5kZXgoc3BsaWNlSW5kZXgsIGxlbmd0aCkge1xuICAgIHJldHVybiBzcGxpY2VJbmRleCA+IGxlbmd0aFxuICAgICAgICAgICAgPyBsZW5ndGhcbiAgICAgICAgICAgIDogc3BsaWNlSW5kZXggPj0gMFxuICAgICAgICAgICAgICAgID8gc3BsaWNlSW5kZXhcbiAgICAgICAgICAgICAgICA6IHNwbGljZUluZGV4ICsgbGVuZ3RoID4gMFxuICAgICAgICAgICAgICAgICAgICA/IHNwbGljZUluZGV4ICsgbGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgIDogMDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1lc3NlbmdlckFQSSA9IHJlcXVpcmUoJy4uL21lc3Nlbmdlci9tX2FwaScpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8qKlxuICogU3ViY2xhc3Mgb2YgTWVzc2VuZ2VyQVBJIHRoYXQgaXMgdXNlZCB0byB0cmFuc2xhdGUgbWVzc2FnZXMgb2YgTWVzc2VuZ2VyIG9uIE1vZGVsUGF0aCB0byBNZXNzZW5nZXIgb24gTW9kZWwuXG4gKi9cbnZhciBNb2RlbFBhdGhNc2dBUEkgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NlbmdlckFQSSwgJ01vZGVsUGF0aE1zZ0FQSScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVsUGF0aE1zZ0FQSTtcblxuXG4vKipcbiAqICMjIyNNb2RlbFBhdGhNc2dBUEkgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtpbml0XSgjaW5pdCkgLSBpbml0aWFsaXplcyBNb2RlbFBhdGhNc2dBUElcbiAqIC0gW3RyYW5zbGF0ZVRvU291cmNlTWVzc2FnZV0oI3RyYW5zbGF0ZVRvU291cmNlTWVzc2FnZSkgLSB0cmFuc2xhdGVzIHJlbGF0aXZlIGFjY2VzcyBwYXRocyBvZiBNb2RlbFBhdGggdG8gZnVsbCBwYXRoIG9mIE1vZGVsXG4gKiAtIFtjcmVhdGVJbnRlcm5hbERhdGFdKCNjcmVhdGVJbnRlcm5hbERhdGEpIC0gY2hhbmdlcyBwYXRoIGluIG1lc3NhZ2Ugb24gbW9kZWwgdG8gcmVsYXRpdmUgcGF0aCBhbmQgYWRkcyBgZnVsbFBhdGhgIHByb3BlcnR5IHRvIG1lc3NhZ2UgZGF0YVxuICovXG5fLmV4dGVuZFByb3RvKE1vZGVsUGF0aE1zZ0FQSSwge1xuICAgIGluaXQ6IGluaXQsXG4gICAgdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlOiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UsXG4gICAgY3JlYXRlSW50ZXJuYWxEYXRhOiBjcmVhdGVJbnRlcm5hbERhdGEsXG59KTtcblxuXG4vKipcbiAqIE1vZGVsUGF0aE1zZ0FQSSBpbnN0YW5jZSBtZXRob2RcbiAqIENhbGxlZCBieSBNZXNzZW5nZXJBUEkgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJvb3RQYXRoIHJvb3QgcGF0aCBvZiBtb2RlbCBwYXRoXG4gKi9cbmZ1bmN0aW9uIGluaXQocm9vdFBhdGgpIHtcbiAgICBNZXNzZW5nZXJBUEkucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLnJvb3RQYXRoID0gcm9vdFBhdGg7XG59XG5cbi8qKlxuICogTW9kZWxQYXRoTXNnQVBJIGluc3RhbmNlIG1ldGhvZFxuICogVHJhbnNsYXRlcyByZWxhdGl2ZSBhY2Nlc3MgcGF0aHMgb2YgTW9kZWxQYXRoIHRvIGZ1bGwgcGF0aCBvZiBNb2RlbC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWNjZXNzUGF0aCByZWxhdGl2ZSBhY2Nlc3MgcGF0aCB0byBiZSB0cmFuc2xhdGVkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgLy8gVE9ETyBzaG91bGQgcHJlcGVuZCBSZWdFeGVzXG4gICAgLy8gVE9ETyBzaG91bGQgbm90IHByZXBlbmQgY2hhbmdlZGF0YSB0b28/Pz9cbiAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFJlZ0V4cClcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgaWYgKG1lc3NhZ2UgPT0gJ2RhdGFjaGFuZ2VzJylcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgXG4gICAgcmV0dXJuIHRoaXMucm9vdFBhdGggKyBtZXNzYWdlO1xufVxuXG5cbi8qKlxuICogTW9kZWxQYXRoTXNnQVBJIGluc3RhbmNlIG1ldGhvZFxuICogQ2hhbmdlcyBwYXRoIGluIG1lc3NhZ2Ugb24gbW9kZWwgdG8gcmVsYXRpdmUgcGF0aCBhbmQgYWRkcyBgZnVsbFBhdGhgIHByb3BlcnR5IHRvIG1lc3NhZ2UgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc291cmNlTWVzc2FnZSBmdWxsIGFjY2VzcyBwYXRoIG9uIE1vZGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSByZWxhdGl2ZSBhY2Nlc3MgcGF0aCBvbiBNb2RlbFBhdGhcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2VEYXRhIGRhdGEgcmVjZWl2ZWQgZnJvbSBNb2RlbCwgd2lsbCBiZSB0cmFuc2xhdGVkIGFzIGRlc2NyaWJlZCB0byBiZSBkaXNwYXRjaGVkIHRvIE1vZGVsUGF0aFxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBjcmVhdGVJbnRlcm5hbERhdGEoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgc291cmNlRGF0YSkge1xuICAgIC8vIFRPRE8gcmV0dXJuIG9uIGNoYW5nZWRhdGEgdG9vPz8/XG4gICAgaWYgKG1lc3NhZ2UgPT0gJ2RhdGFjaGFuZ2VzJykge1xuICAgICAgICB2YXIgaW50ZXJuYWxDaGFuZ2VzID0gc291cmNlRGF0YS5jaGFuZ2VzXG4gICAgICAgICAgICAubWFwKHRydW5jYXRlQ2hhbmdlUGF0aCwgdGhpcylcbiAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24oY2hhbmdlKSB7IHJldHVybiBjaGFuZ2U7IH0pO1xuICAgICAgICB2YXIgaW50ZXJuYWxEYXRhID0ge1xuICAgICAgICAgICAgY2hhbmdlczogaW50ZXJuYWxDaGFuZ2VzLFxuICAgICAgICAgICAgdHJhbnNhY3Rpb246IHNvdXJjZURhdGEudHJhbnNhY3Rpb25cbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gaW50ZXJuYWxEYXRhXG4gICAgfVxuXG4gICAgdmFyIGludGVybmFsRGF0YSA9IHRydW5jYXRlQ2hhbmdlUGF0aC5jYWxsKHRoaXMsIHNvdXJjZURhdGEpO1xuICAgIHJldHVybiBpbnRlcm5hbERhdGE7XG59XG5cblxuZnVuY3Rpb24gdHJ1bmNhdGVDaGFuZ2VQYXRoKGNoYW5nZSkge1xuICAgIHZhciBmdWxsUGF0aCA9IGNoYW5nZS5wYXRoXG4gICAgICAgICwgcGF0aCA9IF8udW5QcmVmaXgoZnVsbFBhdGgsIHRoaXMucm9vdFBhdGgpO1xuXG4gICAgaWYgKHR5cGVvZiBwYXRoID09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciBjaGFuZ2UgPSBfLmNsb25lKGNoYW5nZSk7XG4gICAgICAgIGNoYW5nZS5mdWxsUGF0aCA9IGZ1bGxQYXRoO1xuICAgICAgICBjaGFuZ2UucGF0aCA9IHBhdGg7XG4gICAgICAgIHJldHVybiBjaGFuZ2U7XG4gICAgfVxufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwibW9kZWwtcGF0aFwiPjwvYT5cbi8vICMjIyBtb2RlbCBwYXRoIHV0aWxzXG5cbnZhciBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBNb2RlbEVycm9yID0gcmVxdWlyZSgnLi4vdXRpbC9lcnJvcicpLk1vZGVsO1xuXG52YXIgcGF0aFV0aWxzID0ge1xuICAgIHBhcnNlQWNjZXNzUGF0aDogcGFyc2VBY2Nlc3NQYXRoLFxuICAgIGNyZWF0ZVJlZ2V4UGF0aDogY3JlYXRlUmVnZXhQYXRoLFxuICAgIGdldFBhdGhOb2RlS2V5OiBnZXRQYXRoTm9kZUtleSxcbiAgICB3cmFwTWVzc2VuZ2VyTWV0aG9kczogd3JhcE1lc3Nlbmdlck1ldGhvZHNcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gcGF0aFV0aWxzO1xuXG5cbnZhciBwcm9wZXJ0eVBhdGhTeW50YXggPSAnXFxcXC5bQS1aYS16Xy1dW0EtWmEtejAtOV8tXSonXG4gICAgLCBhcnJheVBhdGhTeW50YXggPSAnXFxcXFtbMC05XStcXFxcXSdcbiAgICAsIGludGVycG9sYXRpb25TeW50YXggPSAnXFxcXCRbMS05XVswLTldKidcbiAgICAsIHByb3BlcnR5SW50ZXJwb2xhdGVTeW50YXggPSAnXFxcXC4nICsgaW50ZXJwb2xhdGlvblN5bnRheFxuICAgICwgYXJyYXlJbnRlcnBvbGF0ZVN5bnRheCA9ICdcXFxcWycgKyBpbnRlcnBvbGF0aW9uU3ludGF4ICsgJ1xcXFxdJ1xuXG4gICAgLCBwcm9wZXJ0eVN0YXJTeW50YXggPSAnXFxcXC5cXFxcKidcbiAgICAsIGFycmF5U3RhclN5bnRheCA9ICdcXFxcW1xcXFwqXFxcXF0nXG4gICAgLCBzdGFyU3ludGF4ID0gJ1xcXFwqJ1xuXG4gICAgLCBwYXRoUGFyc2VTeW50YXggPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlQYXRoU3ludGF4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5UGF0aFN5bnRheCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUludGVycG9sYXRlU3ludGF4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5SW50ZXJwb2xhdGVTeW50YXhcbiAgICAgICAgICAgICAgICAgICAgICAgIF0uam9pbignfCcpXG4gICAgLCBwYXRoUGFyc2VQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXRoUGFyc2VTeW50YXgsICdnJylcblxuICAgICwgcGF0dGVyblBhdGhQYXJzZVN5bnRheCA9ICBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoUGFyc2VTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVN0YXJTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVN0YXJTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFyU3ludGF4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0uam9pbignfCcpXG4gICAgLCBwYXR0ZXJuUGF0aFBhcnNlUGF0dGVybiA9IG5ldyBSZWdFeHAocGF0dGVyblBhdGhQYXJzZVN5bnRheCwgJ2cnKVxuXG4gICAgLy8sIHRhcmdldFBhdGhQYXJzZVBhdHRlcm4gPSAvXFwuW0EtWmEtel1bQS1aYS16MC05X10qfFxcW1swLTldK1xcXXxcXC5cXCRbMS05XVswLTldKnxcXFtcXCRbMS05XVswLTldKlxcXXxcXCRbMS05XVswLTldL2dcbiAgICAsIHBhdGhOb2RlVHlwZXMgPSB7XG4gICAgICAgICcuJzogeyBzeW50YXg6ICdvYmplY3QnLCBlbXB0eTogJ3t9JyB9LFxuICAgICAgICAnWyc6IHsgc3ludGF4OiAnYXJyYXknLCBlbXB0eTogJ1tdJ30sXG4gICAgICAgICcqJzogeyBzeW50YXg6ICdtYXRjaCcsIGVtcHR5OiAne30nfSxcbiAgICB9O1xuXG5mdW5jdGlvbiBwYXJzZUFjY2Vzc1BhdGgocGF0aCwgbm9kZVBhcnNlUGF0dGVybikge1xuICAgIG5vZGVQYXJzZVBhdHRlcm4gPSBub2RlUGFyc2VQYXR0ZXJuIHx8IHBhdGhQYXJzZVBhdHRlcm47XG5cbiAgICB2YXIgcGFyc2VkUGF0aCA9IFtdO1xuXG4gICAgaWYgKCEgcGF0aClcbiAgICAgICAgcmV0dXJuIHBhcnNlZFBhdGg7XG5cbiAgICB2YXIgdW5wYXJzZWQgPSBwYXRoLnJlcGxhY2Uobm9kZVBhcnNlUGF0dGVybiwgZnVuY3Rpb24obm9kZVN0cikge1xuICAgICAgICB2YXIgcGF0aE5vZGUgPSB7IHByb3BlcnR5OiBub2RlU3RyIH07XG4gICAgICAgIF8uZXh0ZW5kKHBhdGhOb2RlLCBwYXRoTm9kZVR5cGVzW25vZGVTdHJbMF1dKTtcbiAgICAgICAgaWYgKG5vZGVTdHJbMV0gPT0gJyQnKVxuICAgICAgICAgICAgcGF0aE5vZGUuaW50ZXJwb2xhdGUgPSBnZXRQYXRoTm9kZUtleShwYXRoTm9kZSwgdHJ1ZSk7XG5cbiAgICAgICAgcGFyc2VkUGF0aC5wdXNoKHBhdGhOb2RlKTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH0pO1xuICAgIGlmICh1bnBhcnNlZClcbiAgICAgICAgdGhyb3cgbmV3IE1vZGVsRXJyb3IoJ2luY29ycmVjdCBtb2RlbCBwYXRoOiAnICsgcGF0aCk7XG5cbiAgICByZXR1cm4gcGFyc2VkUGF0aDtcbn1cblxuXG52YXIgbm9kZVJlZ2V4ID0ge1xuICAgICcuKic6IHByb3BlcnR5UGF0aFN5bnRheCxcbiAgICAnWypdJzogYXJyYXlQYXRoU3ludGF4XG59O1xubm9kZVJlZ2V4WycqJ10gPSBub2RlUmVnZXhbJy4qJ10gKyAnfCcgKyBub2RlUmVnZXhbJ1sqXSddO1xuXG5mdW5jdGlvbiBjcmVhdGVSZWdleFBhdGgocGF0aCkge1xuICAgIGNoZWNrKHBhdGgsIE1hdGNoLk9uZU9mKFN0cmluZywgUmVnRXhwKSk7XG5cbiAgICBpZiAocGF0aCBpbnN0YW5jZW9mIFJlZ0V4cCB8fCBwYXRoLmluZGV4T2YoJyonKSA9PSAtMSlcbiAgICAgICAgcmV0dXJuIHBhdGg7XG5cbiAgICB2YXIgcGFyc2VkUGF0aCA9IHBhdGhVdGlscy5wYXJzZUFjY2Vzc1BhdGgocGF0aCwgcGF0dGVyblBhdGhQYXJzZVBhdHRlcm4pXG4gICAgICAgICwgcmVnZXhTdHIgPSAnXidcbiAgICAgICAgLy8gLCByZWdleFN0ckVuZCA9ICcnXG4gICAgICAgICwgcGF0dGVybnNTdGFydGVkID0gZmFsc2U7XG5cbiAgICBwYXJzZWRQYXRoLmZvckVhY2goZnVuY3Rpb24ocGF0aE5vZGUpIHtcbiAgICAgICAgdmFyIHByb3AgPSBwYXRoTm9kZS5wcm9wZXJ0eVxuICAgICAgICAgICAgLCByZWdleCA9IG5vZGVSZWdleFtwcm9wXTtcbiAgICAgICAgXG4gICAgICAgIGlmIChyZWdleCkge1xuICAgICAgICAgICAgLy8gcmVnZXhTdHIgKz0gJygnICsgcmVnZXg7XG4gICAgICAgICAgICAvLyByZWdleFN0ckVuZCArPSAnfCknO1xuICAgICAgICAgICAgcmVnZXhTdHIgKz0gJygnICsgcmVnZXggKyAnfCknO1xuICAgICAgICAgICAgLy8gcmVnZXhTdHJFbmQgKz0gJ3wpJztcbiAgICAgICAgICAgIHBhdHRlcm5zU3RhcnRlZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBpZiAocGF0dGVybnNTdGFydGVkKVxuICAgICAgICAgICAgLy8gIHRocm93IG5ldyBNb2RlbEVycm9yKCdcIipcIiBwYXRoIHNlZ21lbnQgY2Fubm90IGJlIGluIHRoZSBtaWRkbGUgb2YgdGhlIHBhdGg6ICcgKyBwYXRoKTtcbiAgICAgICAgICAgIHJlZ2V4U3RyICs9IHByb3AucmVwbGFjZSgvKFxcLnxcXFt8XFxdKS9nLCAnXFxcXCQxJyk7IC8vIGFkZCBzbGFzaCBpbiBmcm9udCBvZiBzeW1ib2xzIHRoYXQgaGF2ZSBzcGVjaWFsIG1lYW5pbmcgaW4gcmVnZXhcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmVnZXhTdHIgKz0gLyogcmVnZXhTdHJFbmQgKyAqLyAnJCc7XG5cbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChyZWdleFN0cik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBuZXcgTW9kZWxFcnJvcignY2FuXFwndCBjb25zdHJ1Y3QgcmVnZXggZm9yIHBhdGggcGF0dGVybjogJyArIHBhdGgpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBnZXRQYXRoTm9kZUtleShwYXRoTm9kZSwgaW50ZXJwb2xhdGVkKSB7XG4gICAgdmFyIHByb3AgPSBwYXRoTm9kZS5wcm9wZXJ0eVxuICAgICAgICAsIHN0YXJ0SW5kZXggPSBpbnRlcnBvbGF0ZWQgPyAyIDogMTtcbiAgICByZXR1cm4gcGF0aE5vZGUuc3ludGF4ID09ICdhcnJheSdcbiAgICAgICAgPyBwcm9wLnNsaWNlKHN0YXJ0SW5kZXgsIHByb3AubGVuZ3RoIC0gMSlcbiAgICAgICAgOiBwcm9wLnNsaWNlKHN0YXJ0SW5kZXgpO1xufVxuXG5cbi8vIFRPRE8gYWxsb3cgZm9yIG11bHRpcGxlIG1lc3NhZ2VzIGluIGEgc3RyaW5nXG5mdW5jdGlvbiB3cmFwTWVzc2VuZ2VyTWV0aG9kcyhtZXRob2RzTmFtZXMpIHtcbiAgICBtZXRob2RzTmFtZXMgPSBtZXRob2RzTmFtZXMgfHwgWydvbicsICdvZmYnXTtcbiAgICB2YXIgd3JhcHBlZE1ldGhvZHMgPSBfLm1hcFRvT2JqZWN0KG1ldGhvZHNOYW1lcywgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgb3JpZ01ldGhvZCA9IHRoaXNbbWV0aG9kTmFtZV07XG4gICAgICAgIC8vIHJlcGxhY2luZyBtZXNzYWdlIHN1YnNyaWJlL3Vuc3Vic2NyaWJlL2V0Yy4gdG8gY29udmVydCBcIipcIiBtZXNzYWdlIHBhdHRlcm5zIHRvIHJlZ2V4cHNcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBhdGgsIHN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgIHZhciByZWdleFBhdGggPSBjcmVhdGVSZWdleFBhdGgocGF0aCk7XG4gICAgICAgICAgICBvcmlnTWV0aG9kLmNhbGwodGhpcywgcmVnZXhQYXRoLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgfTtcbiAgICB9LCB0aGlzKTtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywgd3JhcHBlZE1ldGhvZHMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcGF0aFV0aWxzID0gcmVxdWlyZSgnLi4vcGF0aF91dGlscycpXG4gICAgLCBtb2RlbFV0aWxzID0gcmVxdWlyZSgnLi4vbW9kZWxfdXRpbHMnKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKVxuICAgICwgbWlsb0NvdW50ID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jb3VudCcpXG4gICAgLCBmcyA9IHJlcXVpcmUoJ2ZzJylcbiAgICAsIGRvVCA9IHJlcXVpcmUoJ2RvdCcpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoYW5nZURhdGFIYW5kbGVyID0gcmVxdWlyZSgnLi4vY2hhbmdlX2RhdGEnKVxuICAgICwgZ2V0VHJhbnNhY3Rpb25GbGFnID0gY2hhbmdlRGF0YUhhbmRsZXIuZ2V0VHJhbnNhY3Rpb25GbGFnXG4gICAgLCBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZCA9IGNoYW5nZURhdGFIYW5kbGVyLnBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkO1xuXG5cbi8qKlxuICogVGVtcGxhdGVzIHRvIHN5bnRoZXNpemUgbW9kZWwgZ2V0dGVycyBhbmQgc2V0dGVyc1xuICovXG52YXIgdGVtcGxhdGVzID0ge1xuICAgIGdldDogXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG5tZXRob2QgPSBmdW5jdGlvbiBnZXQoKSB7XFxuICAgIHZhciBtID0ge3sjIGRlZi5tb2RlbEFjY2Vzc1ByZWZpeCB9fTtcXG4gICAgcmV0dXJuIG0ge3t+IGl0LnBhcnNlZFBhdGggOnBhdGhOb2RlIH19XFxuICAgICAgICB7ez8gcGF0aE5vZGUuaW50ZXJwb2xhdGV9fVxcbiAgICAgICAgICAgICYmIChtID0gbVt0aGlzLl9hcmdzWyB7ez0gcGF0aE5vZGUuaW50ZXJwb2xhdGUgfX0gXV0pXFxuICAgICAgICB7ez8/fX1cXG4gICAgICAgICAgICAmJiAobSA9IG17ez0gcGF0aE5vZGUucHJvcGVydHkgfX0pXFxuICAgICAgICB7ez99fSB7e359fTtcXG59O1xcblwiLFxuICAgIHNldDogXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG57eyMgZGVmLmluY2x1ZGVfZGVmaW5lcyB9fVxcbnt7IyBkZWYuaW5jbHVkZV9jcmVhdGVfdHJlZSB9fVxcblxcblxcbi8qKlxcbiAqIFRlbXBsYXRlIHRoYXQgc3ludGhlc2l6ZXMgc2V0dGVyIGZvciBNb2RlbCBhbmQgZm9yIE1vZGVsUGF0aFxcbiAqL1xcbm1ldGhvZCA9IGZ1bmN0aW9uIHNldCh2YWx1ZSkge1xcbiAgICB7eyMgZGVmLmluaXRWYXJzOidzZXQnIH19XFxuXFxuICAgIHt7IyBkZWYuY3JlYXRlVHJlZTonc2V0JyB9fVxcblxcbiAgICB7e1xcbiAgICAgICAgY3Vyck5vZGUgPSBuZXh0Tm9kZTtcXG4gICAgICAgIGN1cnJQcm9wID0gY3Vyck5vZGUgJiYgY3Vyck5vZGUucHJvcGVydHk7XFxuICAgIH19XFxuXFxuICAgIHt7IC8qIGFzc2lnbiB2YWx1ZSB0byB0aGUgbGFzdCBwcm9wZXJ0eSAqLyB9fVxcbiAgICB7ez8gY3VyclByb3AgfX1cXG4gICAgICAgIHdhc0RlZiA9IHt7IyBkZWYud2FzRGVmaW5lZH19O1xcbiAgICAgICAge3sjIGRlZi5jaGFuZ2VBY2Nlc3NQYXRoIH19XFxuXFxuICAgICAgICB2YXIgb2xkID0gbXt7IyBkZWYuY3VyclByb3AgfX07XFxuXFxuICAgICAgICB7eyAvKiBjbG9uZSB2YWx1ZSB0byBwcmV2ZW50IHNhbWUgcmVmZXJlbmNlIGluIGxpbmtlZCBtb2RlbHMgKi8gfX1cXG4gICAgICAgIG17eyMgZGVmLmN1cnJQcm9wIH19ID0gY2xvbmVUcmVlKHZhbHVlKTtcXG4gICAge3s/fX1cXG5cXG4gICAge3sgLyogYWRkIG1lc3NhZ2UgcmVsYXRlZCB0byB0aGUgbGFzdCBwcm9wZXJ0eSBjaGFuZ2UgKi8gfX1cXG4gICAgaWYgKHRoaXMuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XFxuICAgICAgICBpZiAoISB3YXNEZWYpXFxuICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gYWNjZXNzUGF0aCwgdHlwZTogJ2FkZGVkJyxcXG4gICAgICAgICAgICAgICAgbmV3VmFsdWU6IHZhbHVlIH0pO1xcbiAgICAgICAgZWxzZSBpZiAob2xkICE9IHZhbHVlKVxcbiAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGFjY2Vzc1BhdGgsIHR5cGU6ICdjaGFuZ2VkJyxcXG4gICAgICAgICAgICAgICAgb2xkVmFsdWU6IG9sZCwgbmV3VmFsdWU6IHZhbHVlIH0pO1xcblxcbiAgICAgICAge3sgLyogYWRkIG1lc3NhZ2UgcmVsYXRlZCB0byBjaGFuZ2VzIGluIChzdWIpcHJvcGVydGllcyBpbnNpZGUgcmVtb3ZlZCBhbmQgYXNzaWduZWQgdmFsdWUgKi8gfX1cXG4gICAgICAgIGlmICghIHdhc0RlZiB8fCBvbGQgIT0gdmFsdWUpXFxuICAgICAgICAgICAgYWRkVHJlZUNoYW5nZXNNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLFxcbiAgICAgICAgICAgICAgICBhY2Nlc3NQYXRoLCBvbGQsIHZhbHVlKTsgLyogZGVmaW5lZCBpbiB0aGUgZnVuY3Rpb24gdGhhdCBzeW50aGVzaXplcyBNb2RlbFBhdGggc2V0dGVyICovXFxuXFxuICAgICAgICB7eyAvKiBwb3N0IGFsbCBzdG9yZWQgbWVzc2FnZXMgKi8gfX1cXG4gICAgICAgIHt7IyBkZWYucG9zdE1lc3NhZ2VzIH19XFxuICAgIH1cXG59O1xcblwiLFxuICAgIGRlbDogXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG57eyMgZGVmLmluY2x1ZGVfZGVmaW5lcyB9fVxcbnt7IyBkZWYuaW5jbHVkZV90cmF2ZXJzZV90cmVlIH19XFxuXFxubWV0aG9kID0gZnVuY3Rpb24gZGVsKCkge1xcbiAgICB7eyMgZGVmLmluaXRWYXJzOidkZWwnIH19XFxuXFxuICAgIHt7PyBpdC5wYXJzZWRQYXRoLmxlbmd0aCB9fVxcbiAgICAgICAge3sjIGRlZi50cmF2ZXJzZVRyZWUgfX1cXG5cXG4gICAgICAgIHt7XFxuICAgICAgICAgICAgdmFyIGN1cnJOb2RlID0gaXQucGFyc2VkUGF0aFtjb3VudF07XFxuICAgICAgICAgICAgdmFyIGN1cnJQcm9wID0gY3Vyck5vZGUucHJvcGVydHk7ICAgICAgIFxcbiAgICAgICAgfX1cXG5cXG4gICAgICAgIGlmICghIHRyZWVEb2VzTm90RXhpc3QgJiYgbSAmJiBtLmhhc093blByb3BlcnR5ICYmIHt7IyBkZWYud2FzRGVmaW5lZH19KSB7XFxuICAgICAgICAgICAgdmFyIG9sZCA9IG17eyMgZGVmLmN1cnJQcm9wIH19O1xcbiAgICAgICAgICAgIGRlbGV0ZSBte3sjIGRlZi5jdXJyUHJvcCB9fTtcXG4gICAgICAgICAgICB7eyMgZGVmLmNoYW5nZUFjY2Vzc1BhdGggfX1cXG4gICAgICAgICAgICB2YXIgZGlkRGVsZXRlID0gdHJ1ZTtcXG4gICAgICAgIH1cXG4gICAge3s/P319XFxuICAgICAgICBpZiAodHlwZW9mIG0gIT0gJ3VuZGVmaW5lZCcpIHtcXG4gICAgICAgICAgICB2YXIgb2xkID0gbTtcXG4gICAgICAgICAgICB7eyMgZGVmLm1vZGVsQWNjZXNzUHJlZml4IH19ID0gdW5kZWZpbmVkO1xcbiAgICAgICAgICAgIHZhciBkaWREZWxldGUgPSB0cnVlO1xcbiAgICAgICAgfVxcbiAgICB7ez99fVxcblxcbiAgICBpZiAoZGlkRGVsZXRlICYmIHRoaXMuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XFxuICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBhY2Nlc3NQYXRoLCB0eXBlOiAnZGVsZXRlZCcsIG9sZFZhbHVlOiBvbGQgfSk7XFxuXFxuICAgICAgICBhZGRUcmVlQ2hhbmdlc01lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsXFxuICAgICAgICAgICAgYWNjZXNzUGF0aCwgb2xkLCB1bmRlZmluZWQpOyAvKiBkZWZpbmVkIGluIHRoZSBmdW5jdGlvbiB0aGF0IHN5bnRoZXNpemVzIE1vZGVsUGF0aCBzZXR0ZXIgKi9cXG5cXG4gICAgICAgIHt7IC8qIHBvc3QgYWxsIHN0b3JlZCBtZXNzYWdlcyAqLyB9fVxcbiAgICAgICAge3sjIGRlZi5wb3N0TWVzc2FnZXMgfX1cXG4gICAgfVxcbn07XFxuXCIsXG4gICAgc3BsaWNlOiBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbnt7IyBkZWYuaW5jbHVkZV9kZWZpbmVzIH19XFxue3sjIGRlZi5pbmNsdWRlX2NyZWF0ZV90cmVlIH19XFxue3sjIGRlZi5pbmNsdWRlX3RyYXZlcnNlX3RyZWUgfX1cXG5cXG5tZXRob2QgPSBmdW5jdGlvbiBzcGxpY2Uoc3BsaWNlSW5kZXgsIHNwbGljZUhvd01hbnkpIHsgLyogLC4uLiAtIGV4dHJhIGFyZ3VtZW50cyB0byBzcGxpY2UgaW50byBhcnJheSAqL1xcbiAgICB7eyMgZGVmLmluaXRWYXJzOidzcGxpY2UnIH19XFxuXFxuICAgIHZhciBhcmdzTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcXG4gICAgdmFyIGFkZEl0ZW1zID0gYXJnc0xlbiA+IDI7XFxuXFxuICAgIGlmIChhZGRJdGVtcykge1xcbiAgICAgICAge3sgLyogb25seSBjcmVhdGUgbW9kZWwgdHJlZSBpZiBpdGVtcyBhcmUgaW5zZXJ0ZWQgaW4gYXJyYXkgKi8gfX1cXG5cXG4gICAgICAgIHt7IC8qIGlmIG1vZGVsIGlzIHVuZGVmaW5lZCBpdCB3aWxsIGJlIHNldCB0byBhbiBlbXB0eSBhcnJheSAqLyB9fSAgXFxuICAgICAgICB2YXIgdmFsdWUgPSBbXTtcXG4gICAgICAgIHt7IyBkZWYuY3JlYXRlVHJlZTonc3BsaWNlJyB9fVxcblxcbiAgICAgICAge3s/IG5leHROb2RlIH19XFxuICAgICAgICAgICAge3tcXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJOb2RlID0gbmV4dE5vZGU7XFxuICAgICAgICAgICAgICAgIHZhciBjdXJyUHJvcCA9IGN1cnJOb2RlLnByb3BlcnR5O1xcbiAgICAgICAgICAgICAgICB2YXIgZW1wdHlQcm9wID0gJ1tdJztcXG4gICAgICAgICAgICB9fVxcblxcbiAgICAgICAgICAgIHt7IyBkZWYuY3JlYXRlVHJlZVN0ZXAgfX1cXG4gICAgICAgIHt7P319XFxuXFxuICAgIH0gZWxzZSBpZiAoc3BsaWNlSG93TWFueSA+IDApIHtcXG4gICAgICAgIHt7IC8qIGlmIGl0ZW1zIGFyZSBub3QgaW5zZXJ0ZWQsIG9ubHkgdHJhdmVyc2UgbW9kZWwgdHJlZSBpZiBpdGVtcyBhcmUgZGVsZXRlZCBmcm9tIGFycmF5ICovIH19XFxuICAgICAgICB7ez8gaXQucGFyc2VkUGF0aC5sZW5ndGggfX1cXG4gICAgICAgICAgICB7eyMgZGVmLnRyYXZlcnNlVHJlZSB9fVxcblxcbiAgICAgICAgICAgIHt7XFxuICAgICAgICAgICAgICAgIHZhciBjdXJyTm9kZSA9IGl0LnBhcnNlZFBhdGhbY291bnRdO1xcbiAgICAgICAgICAgICAgICB2YXIgY3VyclByb3AgPSBjdXJyTm9kZS5wcm9wZXJ0eTsgICAgICAgXFxuICAgICAgICAgICAgfX1cXG5cXG4gICAgICAgICAgICB7eyAvKiBleHRyYSBicmFjZSBjbG9zZXMgJ2Vsc2UnIGluIGRlZi50cmF2ZXJzZVRyZWVTdGVwICovIH19XFxuICAgICAgICAgICAge3sjIGRlZi50cmF2ZXJzZVRyZWVTdGVwIH19IH1cXG4gICAgICAgIHt7P319XFxuICAgIH1cXG5cXG4gICAge3sgLyogc3BsaWNlIGl0ZW1zICovIH19XFxuICAgIGlmIChhZGRJdGVtcyB8fCAoISB0cmVlRG9lc05vdEV4aXN0ICYmIG1cXG4gICAgICAgICAgICAmJiBtLmxlbmd0aCA+IHNwbGljZUluZGV4ICkgKSB7XFxuICAgICAgICB2YXIgb2xkTGVuZ3RoID0gbS5sZW5ndGggPSBtLmxlbmd0aCB8fCAwO1xcblxcbiAgICAgICAgYXJndW1lbnRzWzBdID0gc3BsaWNlSW5kZXggPSBub3JtYWxpemVTcGxpY2VJbmRleChzcGxpY2VJbmRleCwgbS5sZW5ndGgpO1xcblxcbiAgICAgICAge3sgLyogY2xvbmUgYWRkZWQgYXJndW1lbnRzIHRvIHByZXZlbnQgc2FtZSByZWZlcmVuY2VzIGluIGxpbmtlZCBtb2RlbHMgKi8gfX1cXG4gICAgICAgIGlmIChhZGRJdGVtcylcXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGFyZ3NMZW47IGkrKylcXG4gICAgICAgICAgICAgICAgYXJndW1lbnRzW2ldID0gY2xvbmVUcmVlKGFyZ3VtZW50c1tpXSk7XFxuXFxuICAgICAgICB7eyAvKiBhY3R1YWwgc3BsaWNlIGNhbGwgKi8gfX1cXG4gICAgICAgIHZhciByZW1vdmVkID0gQXJyYXkucHJvdG90eXBlLnNwbGljZS5hcHBseShtLCBhcmd1bWVudHMpO1xcblxcbiAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XFxuICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gYWNjZXNzUGF0aCwgdHlwZTogJ3NwbGljZScsXFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogc3BsaWNlSW5kZXgsIHJlbW92ZWQ6IHJlbW92ZWQsIGFkZGVkQ291bnQ6IGFkZEl0ZW1zID8gYXJnc0xlbiAtIDIgOiAwLFxcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IG0gfSk7XFxuXFxuICAgICAgICAgICAgaWYgKHJlbW92ZWQgJiYgcmVtb3ZlZC5sZW5ndGgpXFxuICAgICAgICAgICAgICAgIHJlbW92ZWQuZm9yRWFjaChmdW5jdGlvbihpdGVtLCBpbmRleCkge1xcbiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW1QYXRoID0gYWNjZXNzUGF0aCArICdbJyArIChzcGxpY2VJbmRleCArIGluZGV4KSArICddJztcXG4gICAgICAgICAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGl0ZW1QYXRoLCB0eXBlOiAncmVtb3ZlZCcsIG9sZFZhbHVlOiBpdGVtIH0pO1xcblxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlSXNUcmVlKGl0ZW0pKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE1lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIGl0ZW1QYXRoLCBpdGVtLCAncmVtb3ZlZCcsICdvbGRWYWx1ZScpO1xcbiAgICAgICAgICAgICAgICB9KTtcXG5cXG4gICAgICAgICAgICBpZiAoYWRkSXRlbXMpXFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYXJnc0xlbjsgaSsrKSB7XFxuICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IGFyZ3VtZW50c1tpXTtcXG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVtUGF0aCA9IGFjY2Vzc1BhdGggKyAnWycgKyAoc3BsaWNlSW5kZXggKyBpIC0gMikgKyAnXSc7XFxuICAgICAgICAgICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBpdGVtUGF0aCwgdHlwZTogJ2FkZGVkJywgbmV3VmFsdWU6IGl0ZW0gfSk7XFxuXFxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVJc1RyZWUoaXRlbSkpXFxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgaXRlbVBhdGgsIGl0ZW0sICdhZGRlZCcsICduZXdWYWx1ZScpO1xcbiAgICAgICAgICAgICAgICB9XFxuXFxuICAgICAgICAgICAge3sgLyogcG9zdCBhbGwgc3RvcmVkIG1lc3NhZ2VzICovIH19XFxuICAgICAgICAgICAge3sjIGRlZi5wb3N0TWVzc2FnZXMgfX1cXG4gICAgICAgIH1cXG4gICAgfVxcblxcbiAgICByZXR1cm4gcmVtb3ZlZCB8fCBbXTtcXG59XFxuXCJcbn07XG5cbnZhciBpbmNsdWRlX2RlZmluZXMgPSBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbi8qKlxcbiAqIEluc2VydHMgaW5pdGlhbGl6YXRpb24gY29kZVxcbiAqL1xcbiB7eyMjIGRlZi5pbml0VmFyczptZXRob2Q6XFxuICAgIHZhciBtID0ge3sjIGRlZi5tb2RlbEFjY2Vzc1ByZWZpeCB9fTtcXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIG1lc3NhZ2VzSGFzaCA9IHt9O1xcbiAgICB2YXIgYWNjZXNzUGF0aCA9ICcnO1xcbiAgICB2YXIgdHJlZURvZXNOb3RFeGlzdDtcXG4gICAgLyogaGFjayB0byBwcmV2ZW50IHNlbmRpbmcgZmluaXNoZWQgZXZlbnRzIHRvIGFsbG93IGZvciBwcm9wYWdhdGlvbiBvZiBiYXRjaGVzIHdpdGhvdXQgc3BsaXR0aW5nIHRoZW0gKi9cXG4gICAgdmFyIGluQ2hhbmdlVHJhbnNhY3Rpb24gPSBnZXRUcmFuc2FjdGlvbkZsYWcoIHt7PSBtZXRob2QgfX0gKTtcXG4gI319XFxuXFxuLyoqXFxuICogSW5zZXJ0cyB0aGUgYmVnaW5uaW5nIG9mIGZ1bmN0aW9uIGNhbGwgdG8gYWRkIG1lc3NhZ2UgdG8gbGlzdFxcbiAqL1xcbnt7IyMgZGVmLmFkZE1zZzogYWRkQ2hhbmdlTWVzc2FnZShtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCB7IHBhdGg6ICN9fVxcblxcbi8qKlxcbiAqIEluc2VydHMgY3VycmVudCBwcm9wZXJ0eS9pbmRleCBmb3IgYm90aCBub3JtYWwgYW5kIGludGVycG9sYXRlZCBwcm9wZXJ0aWVzL2luZGV4ZXNcXG4gKi9cXG57eyMjIGRlZi5jdXJyUHJvcDp7ez8gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX1bdGhpcy5fYXJnc1sge3s9IGN1cnJOb2RlLmludGVycG9sYXRlIH19IF1de3s/P319e3s9IGN1cnJQcm9wIH19e3s/fX0gI319XFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb25kaXRpb24gdG8gdGVzdCB3aGV0aGVyIG5vcm1hbC9pbnRlcnBvbGF0ZWQgcHJvcGVydHkvaW5kZXggZXhpc3RzXFxuICovXFxue3sjIyBkZWYud2FzRGVmaW5lZDogbS5oYXNPd25Qcm9wZXJ0eShcXG4gICAge3s/IGN1cnJOb2RlLmludGVycG9sYXRlIH19XFxuICAgICAgICB0aGlzLl9hcmdzWyB7ez0gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX0gXVxcbiAgICB7ez8/fX1cXG4gICAgICAgICd7ez0gaXQuZ2V0UGF0aE5vZGVLZXkoY3Vyck5vZGUpIH19J1xcbiAgICB7ez99fVxcbikgI319XFxuXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb2RlIHRvIHVwZGF0ZSBhY2Nlc3MgcGF0aCBmb3IgY3VycmVudCBwcm9wZXJ0eVxcbiAqIEJlY2F1c2Ugb2YgdGhlIHBvc3NpYmlsaXR5IG9mIGludGVycG9sYXRlZCBwcm9wZXJ0aWVzLCBpdCBjYW4ndCBiZSBjYWxjdWxhdGVkIGluIHRlbXBsYXRlLCBpdCBjYW4gb25seSBiZSBjYWxjdWxhdGVkIGR1cmluZyBhY2Nlc3NvciBjYWxsLlxcbiAqL1xcbnt7IyMgZGVmLmNoYW5nZUFjY2Vzc1BhdGg6XFxuICAgIGFjY2Vzc1BhdGggKz0ge3s/IGN1cnJOb2RlLmludGVycG9sYXRlIH19XFxuICAgICAgICB7ez8gY3Vyck5vZGUuc3ludGF4ID09ICdhcnJheScgfX1cXG4gICAgICAgICAgICAnWycgKyB0aGlzLl9hcmdzWyB7ez0gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX0gXSArICddJztcXG4gICAgICAgIHt7Pz99fVxcbiAgICAgICAgICAgICcuJyArIHRoaXMuX2FyZ3NbIHt7PSBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fSBdO1xcbiAgICAgICAge3s/fX1cXG4gICAge3s/P319XFxuICAgICAgICAne3s9IGN1cnJQcm9wIH19JztcXG4gICAge3s/fX1cXG4jfX1cXG5cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvZGUgdG8gcG9zdCBzdG9yZWQgbWVzc2FnZXNcXG4gKi9cXG57eyMjIGRlZi5wb3N0TWVzc2FnZXM6XFxuICAgIGlmIChtZXNzYWdlcy5sZW5ndGgpIHtcXG4gICAgICAgIHt7IyBkZWYubW9kZWxQb3N0QmF0Y2hDb2RlIH19KCdkYXRhY2hhbmdlcycsIHtcXG4gICAgICAgICAgICBjaGFuZ2VzOiBtZXNzYWdlcyxcXG4gICAgICAgICAgICB0cmFuc2FjdGlvbjogaW5DaGFuZ2VUcmFuc2FjdGlvblxcbiAgICAgICAgfSk7XFxuXFxuICAgICAgICBtZXNzYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKG1zZykge1xcbiAgICAgICAgICAgIHt7IyBkZWYubW9kZWxQb3N0TWVzc2FnZUNvZGUgfX0obXNnLnBhdGgsIG1zZyk7XFxuICAgICAgICB9LCB0aGlzKTtcXG4gICAgfVxcbiN9fVxcblwiXG4gICAgLCBpbmNsdWRlX2NyZWF0ZV90cmVlID0gXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvZGUgdG8gY3JlYXRlIG1vZGVsIHRyZWUgYXMgbmVjY2Vzc2FyeSBmb3IgYHNldGAgYW5kIGBzcGxpY2VgIGFjY2Vzc29ycyBhbmQgdG8gYWRkIG1lc3NhZ2VzIHRvIHNlbmQgbGlzdCBpZiB0aGUgdHJlZSBjaGFuZ2VzLlxcbiAqL1xcbnt7IyMgZGVmLmNyZWF0ZVRyZWU6bWV0aG9kOlxcbiAgICB2YXIgd2FzRGVmID0gdHJ1ZTtcXG4gICAgdmFyIG9sZCA9IG07XFxuXFxuICAgIHt7IHZhciBlbXB0eVByb3AgPSBpdC5wYXJzZWRQYXRoWzBdICYmIGl0LnBhcnNlZFBhdGhbMF0uZW1wdHk7IH19XFxuICAgIHt7PyBlbXB0eVByb3AgfX1cXG4gICAgICAgIHt7IC8qIGNyZWF0ZSB0b3AgbGV2ZWwgbW9kZWwgaWYgaXQgd2FzIG5vdCBwcmV2aW91c2x5IGRlZmluZWQgKi8gfX1cXG4gICAgICAgIGlmICghIG0pIHtcXG4gICAgICAgICAgICBtID0ge3sjIGRlZi5tb2RlbEFjY2Vzc1ByZWZpeCB9fSA9IHt7PSBlbXB0eVByb3AgfX07XFxuICAgICAgICAgICAgd2FzRGVmID0gZmFsc2U7XFxuXFxuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XFxuICAgICAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19ICcnLCB0eXBlOiAnYWRkZWQnLFxcbiAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbSB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgIHt7Pz99fVxcbiAgICAgICAge3s/IG1ldGhvZCA9PSAnc3BsaWNlJyB9fVxcbiAgICAgICAgICAgIGlmICghIG0pIHtcXG4gICAgICAgIHt7P319XFxuICAgICAgICAgICAgICAgIG0gPSB7eyMgZGVmLm1vZGVsQWNjZXNzUHJlZml4IH19ID0gY2xvbmVUcmVlKHZhbHVlKTtcXG4gICAgICAgICAgICAgICAgd2FzRGVmID0gdHlwZW9mIG9sZCAhPSAndW5kZWZpbmVkJztcXG4gICAgICAgIHt7PyBtZXRob2QgPT0gJ3NwbGljZScgfX1cXG4gICAgICAgICAgICB9XFxuICAgICAgICB7ez99fSAgICAgICBcXG4gICAge3s/fX1cXG5cXG5cXG4gICAge3sgLyogY3JlYXRlIG1vZGVsIHRyZWUgaWYgaXQgZG9lc24ndCBleGlzdCAqLyB9fVxcbiAgICB7eyAgdmFyIG1vZGVsRGF0YVByb3BlcnR5ID0gJyc7XFxuICAgICAgICB2YXIgbmV4dE5vZGUgPSBpdC5wYXJzZWRQYXRoWzBdO1xcbiAgICAgICAgdmFyIGNvdW50ID0gaXQucGFyc2VkUGF0aC5sZW5ndGggLSAxO1xcblxcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XFxuICAgICAgICAgICAgdmFyIGN1cnJOb2RlID0gbmV4dE5vZGU7XFxuICAgICAgICAgICAgdmFyIGN1cnJQcm9wID0gY3Vyck5vZGUucHJvcGVydHk7XFxuICAgICAgICAgICAgbmV4dE5vZGUgPSBpdC5wYXJzZWRQYXRoW2kgKyAxXTtcXG4gICAgICAgICAgICB2YXIgZW1wdHlQcm9wID0gbmV4dE5vZGUgJiYgbmV4dE5vZGUuZW1wdHk7XFxuICAgIH19XFxuXFxuICAgICAgICB7eyMgZGVmLmNyZWF0ZVRyZWVTdGVwIH19XFxuXFxuICAgIHt7ICB9IC8qIGZvciBsb29wICovIH19XFxuI319XFxuXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb2RlIHRvIGNyZWF0ZSBvbmUgc3RlcCBpbiB0aGUgbW9kZWwgdHJlZVxcbiAqL1xcbnt7IyMgZGVmLmNyZWF0ZVRyZWVTdGVwOlxcbiAgICB7eyMgZGVmLmNoYW5nZUFjY2Vzc1BhdGggfX1cXG5cXG4gICAgaWYgKCEge3sjIGRlZi53YXNEZWZpbmVkIH19KSB7IFxcbiAgICAgICAge3sgLyogcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgKi8gfX1cXG4gICAgICAgIG0gPSBte3sjIGRlZi5jdXJyUHJvcCB9fSA9IHt7PSBlbXB0eVByb3AgfX07XFxuXFxuICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcXG4gICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBhY2Nlc3NQYXRoLCB0eXBlOiAnYWRkZWQnLCBcXG4gICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbSB9KTtcXG4gICAgICAgIH1cXG5cXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbXt7IyBkZWYuY3VyclByb3AgfX0gIT0gJ29iamVjdCcpIHtcXG4gICAgICAgIHt7IC8qIHByb3BlcnR5IGlzIG5vdCBvYmplY3QgKi8gfX1cXG4gICAgICAgIHZhciBvbGQgPSBte3sjIGRlZi5jdXJyUHJvcCB9fTtcXG4gICAgICAgIG0gPSBte3sjIGRlZi5jdXJyUHJvcCB9fSA9IHt7PSBlbXB0eVByb3AgfX07XFxuXFxuICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5yZWFjdGl2ZSAhPT0gZmFsc2UpIHtcXG4gICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBhY2Nlc3NQYXRoLCB0eXBlOiAnY2hhbmdlZCcsIFxcbiAgICAgICAgICAgICAgICAgIG9sZFZhbHVlOiBvbGQsIG5ld1ZhbHVlOiBtIH0pO1xcbiAgICAgICAgfVxcblxcbiAgICB9IGVsc2Uge1xcbiAgICAgICAge3sgLyogcHJvcGVydHkgZXhpc3RzLCBqdXN0IHRyYXZlcnNlIGRvd24gdGhlIG1vZGVsIHRyZWUgKi8gfX1cXG4gICAgICAgIG0gPSBte3sjIGRlZi5jdXJyUHJvcCB9fTtcXG4gICAgfVxcbiN9fVxcblwiXG4gICAgLCBpbmNsdWRlX3RyYXZlcnNlX3RyZWUgPSBcIid1c2Ugc3RyaWN0JztcXG4vKiBPbmx5IHVzZSB0aGlzIHN0eWxlIG9mIGNvbW1lbnRzLCBub3QgXFxcIi8vXFxcIiAqL1xcblxcbi8qKlxcbiAqIEluc2VydHMgY29kZSB0byB0cmF2ZXJzZSBtb2RlbCB0cmVlIGZvciBgZGVsZXRlYCBhbmQgYHNwbGljZWAgYWNjZXNzb3JzLlxcbiAqL1xcbnt7IyMgZGVmLnRyYXZlcnNlVHJlZTpcXG4gICAge3sgXFxuICAgICAgICB2YXIgY291bnQgPSBpdC5wYXJzZWRQYXRoLmxlbmd0aC0xO1xcblxcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7IFxcbiAgICAgICAgICAgIHZhciBjdXJyTm9kZSA9IGl0LnBhcnNlZFBhdGhbaV07XFxuICAgICAgICAgICAgdmFyIGN1cnJQcm9wID0gY3Vyck5vZGUucHJvcGVydHk7XFxuICAgIH19XFxuICAgICAgICAgICAge3sjIGRlZi50cmF2ZXJzZVRyZWVTdGVwIH19XFxuXFxuICAgIHt7IH0gLyogZm9yIGxvb3AgKi9cXG5cXG4gICAgICAgIHZhciBpID0gY291bnQ7XFxuICAgICAgICB3aGlsZSAoaS0tKSB7IC8qIGNsb3NpbmcgYnJhY2VzIGZvciBlbHNlJ3MgYWJvdmUgKi9cXG4gICAgfX1cXG4gICAgICAgICAgICB9XFxuICAgIHt7IH0gLyogd2hpbGUgbG9vcCAqLyB9fVxcbiN9fVxcblxcblxcbi8qKlxcbiAqIEluc2VydHMgY29kZSB0byB0cmF2ZXJzZSBvbmUgc3RlcCBpbiB0aGUgbW9kZWwgdHJlZVxcbiAqL1xcbnt7IyMgZGVmLnRyYXZlcnNlVHJlZVN0ZXA6XFxuICAgIGlmICghIChtICYmIG0uaGFzT3duUHJvcGVydHkgJiYge3sjIGRlZi53YXNEZWZpbmVkfX0gKSApXFxuICAgICAgICB0cmVlRG9lc05vdEV4aXN0ID0gdHJ1ZTtcXG4gICAgZWxzZSB7XFxuICAgICAgICBtID0gbXt7IyBkZWYuY3VyclByb3AgfX07XFxuICAgICAgICB7eyMgZGVmLmNoYW5nZUFjY2Vzc1BhdGggfX1cXG4gICAge3sgLyogYnJhY2UgZnJvbSBlbHNlIGlzIG5vdCBjbG9zZWQgb24gcHVycG9zZSAtIGFsbCBicmFjZXMgYXJlIGNsb3NlZCBpbiB3aGlsZSBsb29wICovIH19XFxuI319XFxuXCI7XG5cbnZhciBkb3REZWYgPSB7XG4gICAgaW5jbHVkZV9kZWZpbmVzOiBpbmNsdWRlX2RlZmluZXMsXG4gICAgaW5jbHVkZV9jcmVhdGVfdHJlZTogaW5jbHVkZV9jcmVhdGVfdHJlZSxcbiAgICBpbmNsdWRlX3RyYXZlcnNlX3RyZWU6IGluY2x1ZGVfdHJhdmVyc2VfdHJlZSxcbiAgICBnZXRQYXRoTm9kZUtleTogcGF0aFV0aWxzLmdldFBhdGhOb2RlS2V5LFxuICAgIG1vZGVsQWNjZXNzUHJlZml4OiAndGhpcy5fbW9kZWwuX2RhdGEnLFxuICAgIG1vZGVsUG9zdE1lc3NhZ2VDb2RlOiAndGhpcy5fbW9kZWwuX2ludGVybmFsTWVzc2VuZ2VyLnBvc3RNZXNzYWdlJyxcbiAgICBtb2RlbFBvc3RCYXRjaENvZGU6ICd0aGlzLl9tb2RlbC5wb3N0TWVzc2FnZVN5bmMnLFxuICAgIGludGVybmFsTWVzc2VuZ2VyOiAndGhpcy5fbW9kZWwuX2ludGVybmFsTWVzc2VuZ2VyJ1xufTtcblxudmFyIG1vZGVsRG90RGVmID0gXyhkb3REZWYpLmNsb25lKCkuZXh0ZW5kKHtcbiAgICBtb2RlbEFjY2Vzc1ByZWZpeDogJ3RoaXMuX2RhdGEnLFxuICAgIG1vZGVsUG9zdE1lc3NhZ2VDb2RlOiAndGhpcy5faW50ZXJuYWxNZXNzZW5nZXIucG9zdE1lc3NhZ2UnLFxuICAgIG1vZGVsUG9zdEJhdGNoQ29kZTogJ3RoaXMucG9zdE1lc3NhZ2VTeW5jJyxcbiAgICBpbnRlcm5hbE1lc3NlbmdlcjogJ3RoaXMuX2ludGVybmFsTWVzc2VuZ2VyJ1xufSkuXygpO1xuXG5cbnZhciBkb3RTZXR0aW5ncyA9IF8uY2xvbmUoZG9ULnRlbXBsYXRlU2V0dGluZ3MpO1xuZG90U2V0dGluZ3Muc3RyaXAgPSBmYWxzZTtcblxudmFyIHN5bnRoZXNpemVycyA9IF8ubWFwS2V5cyh0ZW1wbGF0ZXMsIGZ1bmN0aW9uKHRtcGwpIHtcbiAgICByZXR1cm4gZG9ULnRlbXBsYXRlKHRtcGwsIGRvdFNldHRpbmdzLCBkb3REZWYpOyBcbn0pO1xuXG5cbnZhciBtb2RlbFN5bnRoZXNpemVycyA9IF8ubWFwVG9PYmplY3QoWydzZXQnLCAnZGVsJywgJ3NwbGljZSddLCBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgcmV0dXJuIGRvVC50ZW1wbGF0ZSh0ZW1wbGF0ZXNbbWV0aG9kTmFtZV0sIGRvdFNldHRpbmdzLCBtb2RlbERvdERlZik7XG59KTtcblxuXG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgc3ludGhlc2l6ZXMgYWNjZXNzb3IgbWV0aG9kcy5cbiAqIEZ1bmN0aW9uIGlzIG1lbW9pemVkIHNvIGFjY2Vzc29ycyBhcmUgY2FjaGVkICh1cCB0byAxMDAwKS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aCBNb2RlbC9Nb2RlbFBhdGggYWNjZXNzIHBhdGhcbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnNlZFBhdGggYXJyYXkgb2YgcGF0aCBub2Rlc1xuICogQHJldHVybiB7T2JqZWN0W0Z1bmN0aW9uXX1cbiAqL1xudmFyIHN5bnRoZXNpemVQYXRoTWV0aG9kcyA9IF8ubWVtb2l6ZShfc3ludGhlc2l6ZVBhdGhNZXRob2RzLCB1bmRlZmluZWQsIDEwMDApO1xuXG5mdW5jdGlvbiBfc3ludGhlc2l6ZVBhdGhNZXRob2RzKHBhdGgsIHBhcnNlZFBhdGgpIHtcbiAgICB2YXIgbWV0aG9kcyA9IF8ubWFwS2V5cyhzeW50aGVzaXplcnMsIGZ1bmN0aW9uKHN5bnRoc3pyKSB7XG4gICAgICAgIHJldHVybiBfc3ludGhlc2l6ZShzeW50aHN6ciwgcGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG1ldGhvZHM7XG59XG5cblxudmFyIG5vcm1hbGl6ZVNwbGljZUluZGV4ID0gbW9kZWxVdGlscy5ub3JtYWxpemVTcGxpY2VJbmRleDsgLy8gdXNlZCBpbiBzcGxpY2UuZG90LmpzXG5cblxuZnVuY3Rpb24gX3N5bnRoZXNpemUoc3ludGhlc2l6ZXIsIHBhdGgsIHBhcnNlZFBhdGgpIHtcbiAgICB2YXIgbWV0aG9kXG4gICAgICAgICwgbWV0aG9kQ29kZSA9IHN5bnRoZXNpemVyKHtcbiAgICAgICAgICAgIHBhcnNlZFBhdGg6IHBhcnNlZFBhdGgsXG4gICAgICAgICAgICBnZXRQYXRoTm9kZUtleTogcGF0aFV0aWxzLmdldFBhdGhOb2RlS2V5XG4gICAgICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgZXZhbChtZXRob2RDb2RlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IE1vZGVsRXJyb3IoJ01vZGVsUGF0aCBtZXRob2QgY29tcGlsYXRpb24gZXJyb3I7IHBhdGg6ICcgKyBwYXRoICsgJywgY29kZTogJyArIG1ldGhvZENvZGUpO1xuICAgIH1cblxuICAgIHJldHVybiBtZXRob2Q7XG5cblxuICAgIC8vIGZ1bmN0aW9ucyB1c2VkIGJ5IG1ldGhvZHMgYHNldGAsIGBkZWxldGVgIGFuZCBgc3BsaWNlYCAoc3ludGhlc2l6ZWQgYnkgdGVtcGxhdGUpXG4gICAgZnVuY3Rpb24gYWRkQ2hhbmdlTWVzc2FnZShtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCBtc2cpIHtcbiAgICAgICAgbWVzc2FnZXMucHVzaChtc2cpO1xuICAgICAgICBtZXNzYWdlc0hhc2hbbXNnLnBhdGhdID0gbXNnO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFRyZWVDaGFuZ2VzTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgcm9vdFBhdGgsIG9sZFZhbHVlLCBuZXdWYWx1ZSkge1xuICAgICAgICB2YXIgb2xkSXNUcmVlID0gdmFsdWVJc1RyZWUob2xkVmFsdWUpXG4gICAgICAgICAgICAsIG5ld0lzVHJlZSA9IHZhbHVlSXNUcmVlKG5ld1ZhbHVlKTtcblxuICAgICAgICBpZiAobmV3SXNUcmVlKVxuICAgICAgICAgICAgYWRkTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgcm9vdFBhdGgsIG5ld1ZhbHVlLCAnYWRkZWQnLCAnbmV3VmFsdWUnKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChvbGRJc1RyZWUpXG4gICAgICAgICAgICBhZGRNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCByb290UGF0aCwgb2xkVmFsdWUsICdyZW1vdmVkJywgJ29sZFZhbHVlJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgcm9vdFBhdGgsIG9iaiwgbXNnVHlwZSwgdmFsdWVQcm9wKSB7XG4gICAgICAgIF9hZGRNZXNzYWdlcyhyb290UGF0aCwgb2JqKTtcblxuXG4gICAgICAgIGZ1bmN0aW9uIF9hZGRNZXNzYWdlcyhyb290UGF0aCwgb2JqKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBhdGhTeW50YXggPSByb290UGF0aCArICdbJCRdJztcbiAgICAgICAgICAgICAgICBvYmouZm9yRWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkTWVzc2FnZSh2YWx1ZSwgaW5kZXgsIHBhdGhTeW50YXgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aFN5bnRheCA9IHJvb3RQYXRoICsgJy4kJCc7XG4gICAgICAgICAgICAgICAgXy5lYWNoS2V5KG9iaiwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgICAgICAgICAgICAgICBhZGRNZXNzYWdlKHZhbHVlLCBrZXksIHBhdGhTeW50YXgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gYWRkTWVzc2FnZSh2YWx1ZSwga2V5LCBwYXRoU3ludGF4KSB7XG4gICAgICAgICAgICB2YXIgcGF0aCA9IHBhdGhTeW50YXgucmVwbGFjZSgnJCQnLCBrZXkpXG4gICAgICAgICAgICAgICAgLCBleGlzdGluZ01zZyA9IG1lc3NhZ2VzSGFzaFtwYXRoXTtcblxuICAgICAgICAgICAgaWYgKGV4aXN0aW5nTXNnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nTXNnLnR5cGUgPT0gbXNnVHlwZSlcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdzZXR0ZXIgZXJyb3I6IHNhbWUgbWVzc2FnZSB0eXBlIHBvc3RlZCBvbiB0aGUgc2FtZSBwYXRoJyk7XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nTXNnLnR5cGUgPSAnY2hhbmdlZCc7XG4gICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nTXNnW3ZhbHVlUHJvcF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBtc2cgPSB7IHBhdGg6IHBhdGgsIHR5cGU6IG1zZ1R5cGUgfTtcbiAgICAgICAgICAgICAgICBtc2dbdmFsdWVQcm9wXSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGFkZENoYW5nZU1lc3NhZ2UobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgbXNnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHZhbHVlSXNUcmVlKHZhbHVlKSlcbiAgICAgICAgICAgICAgICBfYWRkTWVzc2FnZXMocGF0aCwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xvbmVUcmVlKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZUlzTm9ybWFsT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICAgID8gXy5kZWVwQ2xvbmUodmFsdWUpXG4gICAgICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcm90ZWN0VmFsdWUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuICEgdmFsdWVJc05vcm1hbE9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgICA/IHZhbHVlXG4gICAgICAgICAgICAgICAgOiBBcnJheS5pc0FycmF5KHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICA/IHZhbHVlLnNsaWNlKClcbiAgICAgICAgICAgICAgICAgICAgOiBPYmplY3QuY3JlYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB2YWx1ZUlzVHJlZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWVJc05vcm1hbE9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgICAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbHVlSXNOb3JtYWxPYmplY3QodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGxcbiAgICAgICAgICAgICAgICAmJiB0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIlxuICAgICAgICAgICAgICAgICYmICEgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSlcbiAgICAgICAgICAgICAgICAmJiAhICh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkQmF0Y2hJZHNUb01lc3NhZ2UobXNnLCBiYXRjaElkLCBtc2dJZCkge1xuICAgICAgICBfLmRlZmluZVByb3BlcnRpZXMobXNnLCB7XG4gICAgICAgICAgICBfX2JhdGNoX2lkOiBiYXRjaElkLFxuICAgICAgICAgICAgX19tc2dfaWQ6IG1zZ0lkXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIEV4cG9ydHMgYHN5bnRoZXNpemVgIGZ1bmN0aW9uIHdpdGggdGhlIGZvbGxvd2luZzpcbiAqXG4gKiAtIC5tb2RlbE1ldGhvZHMuc2V0IC0gYHNldGAgbWV0aG9kIGZvciBNb2RlbFxuICogLSAubW9kZWxNZXRob2RzLmRlbCAtIGBkZWxgIG1ldGhvZCBmb3IgTW9kZWxcbiAqIC0gLm1vZGVsTWV0aG9kcy5zcGxpY2UgLSBgc3BsaWNlYCBtZXRob2QgZm9yIE1vZGVsXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gc3ludGhlc2l6ZVBhdGhNZXRob2RzO1xuXG52YXIgbW9kZWxNZXRob2RzID0gXy5tYXBLZXlzKG1vZGVsU3ludGhlc2l6ZXJzLCBmdW5jdGlvbihzeW50aGVzaXplcikge1xuICAgIHJldHVybiBfc3ludGhlc2l6ZShzeW50aGVzaXplciwgJycsIFtdKTtcbn0pO1xuXG5zeW50aGVzaXplUGF0aE1ldGhvZHMubW9kZWxNZXRob2RzID0gbW9kZWxNZXRob2RzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFJlZ2lzdHJpZXMgb2YgZmFjZXRzIGFuZCBvZiBjb21wb25lbnRzXG4gKlxuICogLSBbZmFjZXRzXSguL2NvbXBvbmVudHMvY19mYWNldHMvY2ZfcmVnaXN0cnkuanMuaHRtbClcbiAqIC0gW2NvbXBvbmVudHNdKC4vY29tcG9uZW50cy9jX3JlZ2lzdHJ5LmpzLmh0bWwpXG4gKi9cbnZhciByZWdpc3RyeSA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGZhY2V0czogcmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL2NmX3JlZ2lzdHJ5JyksXG4gICAgY29tcG9uZW50czogcmVxdWlyZSgnLi9jb21wb25lbnRzL2NfcmVnaXN0cnknKSxcbiAgICBjb21tYW5kczogcmVxdWlyZSgnLi9jb21tYW5kL2NtZF9yZWdpc3RyeScpXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwiY29tcG9uZW50cy1kb20tY29uc3RydWN0b3JzXCI+PC9hPlxuLy8gIyMjZG9tIGV2ZW50cyBjb25zdHJ1Y3RvcnNcblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL1JlZmVyZW5jZS9FdmVudHNcblxudmFyIGV2ZW50VHlwZXMgPSB7XG4gICAgQ2xpcGJvYXJkRXZlbnQ6IFsnY29weScsICdjdXQnLCAncGFzdGUnLCAnYmVmb3JlY29weScsICdiZWZvcmVjdXQnLCAnYmVmb3JlcGFzdGUnXSxcbiAgICBFdmVudDogWydpbnB1dCcsICdyZWFkeXN0YXRlY2hhbmdlJ10sXG4gICAgRm9jdXNFdmVudDogWydmb2N1cycsICdibHVyJywgJ2ZvY3VzaW4nLCAnZm9jdXNvdXQnXSxcbiAgICBLZXlib2FyZEV2ZW50OiBbJ2tleWRvd24nLCAna2V5cHJlc3MnLCAgJ2tleXVwJ10sXG4gICAgTW91c2VFdmVudDogWydjbGljaycsICdjb250ZXh0bWVudScsICdkYmxjbGljaycsICdtb3VzZWRvd24nLCAnbW91c2V1cCcsXG4gICAgICAgICAgICAgICAgICdtb3VzZWVudGVyJywgJ21vdXNlbGVhdmUnLCAnbW91c2Vtb3ZlJywgJ21vdXNlb3V0JywgJ21vdXNlb3ZlcicsXG4gICAgICAgICAgICAgICAgICdzaG93JyAvKiBjb250ZXh0IG1lbnUgKi9dLFxuICAgIFRvdWNoRXZlbnQ6IFsndG91Y2hzdGFydCcsICd0b3VjaGVuZCcsICd0b3VjaG1vdmUnLCAndG91Y2hlbnRlcicsICd0b3VjaGxlYXZlJywgJ3RvdWNoY2FuY2VsJ10sXG59O1xuXG5cbi8vIG1vY2sgd2luZG93IGFuZCBldmVudCBjb25zdHJ1Y3RvcnMgZm9yIHRlc3RpbmdcbmlmICh0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnKVxuICAgIHZhciBnbG9iYWwgPSB3aW5kb3c7XG5lbHNlIHtcbiAgICBnbG9iYWwgPSB7fTtcbiAgICBfLmVhY2hLZXkoZXZlbnRUeXBlcywgZnVuY3Rpb24oZVR5cGVzLCBldmVudENvbnN0cnVjdG9yTmFtZSkge1xuICAgICAgICB2YXIgZXZlbnRDb25zdHJ1Y3RvciA9IF8ubWFrZUZ1bmN0aW9uKGV2ZW50Q29uc3RydWN0b3JOYW1lLCAndHlwZScsICdwcm9wZXJ0aWVzJyxcbiAgICAgICAgICAgICd0aGlzLnR5cGUgPSB0eXBlOyBfLmV4dGVuZCh0aGlzLCBwcm9wZXJ0aWVzKTsnKTtcbiAgICAgICAgZ2xvYmFsW2V2ZW50Q29uc3RydWN0b3JOYW1lXSA9IGV2ZW50Q29uc3RydWN0b3I7XG4gICAgfSk7XG59XG5cblxudmFyIGRvbUV2ZW50c0NvbnN0cnVjdG9ycyA9IHt9O1xuXG5fLmVhY2hLZXkoZXZlbnRUeXBlcywgZnVuY3Rpb24oZVR5cGVzLCBldmVudENvbnN0cnVjdG9yTmFtZSkge1xuICAgIGVUeXBlcy5mb3JFYWNoKGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eShkb21FdmVudHNDb25zdHJ1Y3RvcnMsIHR5cGUpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkdXBsaWNhdGUgZXZlbnQgdHlwZSAnICsgdHlwZSk7XG5cbiAgICAgICAgZG9tRXZlbnRzQ29uc3RydWN0b3JzW3R5cGVdID0gZ2xvYmFsW2V2ZW50Q29uc3RydWN0b3JOYW1lXTtcbiAgICB9KTtcbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZG9tRXZlbnRzQ29uc3RydWN0b3JzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyL21fc291cmNlJylcbiAgICAsIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvY19jbGFzcycpXG4gICAgLCBkb21FdmVudHNDb25zdHJ1Y3RvcnMgPSByZXF1aXJlKCcuL2RlX2NvbnN0cnMnKSAvLyBUT0RPIG1lcmdlIHdpdGggRE9NRXZlbnRTb3VyY2UgPz9cbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cbnZhciBET01FbWl0dGVyU291cmNlID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzYWdlU291cmNlLCAnRE9NRW1pdHRlclNvdXJjZScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oRE9NRW1pdHRlclNvdXJjZSwge1xuICAgIC8vIGltcGxlbWVudGluZyBNZXNzYWdlU291cmNlIGludGVyZmFjZVxuICAgIGluaXQ6IGluaXQsXG4gICAgZGVzdHJveTogRE9NRW1pdHRlclNvdXJjZSRkZXN0cm95LFxuICAgIGFkZFNvdXJjZVN1YnNjcmliZXI6IF8ucGFydGlhbChzb3VyY2VTdWJzY3JpYmVyTWV0aG9kLCAnYWRkRXZlbnRMaXN0ZW5lcicpLFxuICAgIHJlbW92ZVNvdXJjZVN1YnNjcmliZXI6IF8ucGFydGlhbChzb3VyY2VTdWJzY3JpYmVyTWV0aG9kLCAncmVtb3ZlRXZlbnRMaXN0ZW5lcicpLFxuICAgIHBvc3RNZXNzYWdlOiBET01FbWl0dGVyU291cmNlJHBvc3RNZXNzYWdlLFxuICAgIHRyaWdnZXI6IHRyaWdnZXIsXG5cbiAgICAvLyBjbGFzcyBzcGVjaWZpYyBtZXRob2RzXG4gICAgZW1pdHRlcjogZW1pdHRlcixcbiAgICBoYW5kbGVFdmVudDogaGFuZGxlRXZlbnQsICAvLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBET01FbWl0dGVyU291cmNlO1xuXG5cbnZhciB1c2VDYXB0dXJlUGF0dGVybiA9IC9fX2NhcHR1cmUkL1xuICAgICwgdXNlQ2FwdHVyZVBvc3RmaXggPSAnX19jYXB0dXJlJztcblxuXG4vLyBpbml0IERPTSBldmVudCBzb3VyY2VcbmZ1bmN0aW9uIGluaXQoaG9zdE9iamVjdCwgcHJveHlNZXRob2RzLCBtZXNzZW5nZXJBUElPckNsYXNzLCBldmVudEVtaXR0ZXIpIHtcbiAgICB0aGlzLmV2ZW50RW1pdHRlciA9IGV2ZW50RW1pdHRlcjtcbiAgICBNZXNzYWdlU291cmNlLnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cblxuZnVuY3Rpb24gRE9NRW1pdHRlclNvdXJjZSRkZXN0cm95KCkge1xuICAgIE1lc3NhZ2VTb3VyY2UucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBkZWxldGUgdGhpcy5ldmVudEVtaXR0ZXI7XG59XG5cblxuLy8gZ2V0IERPTSBlbGVtZW50IG9mIGNvbXBvbmVudFxuZnVuY3Rpb24gZW1pdHRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5ldmVudEVtaXR0ZXI7XG59XG5cblxuZnVuY3Rpb24gc291cmNlU3Vic2NyaWJlck1ldGhvZChtZXRob2QsIGV2ZW50VHlwZSkge1xuICAgIGlmICghIChldmVudFR5cGUgJiYgdHlwZW9mIGV2ZW50VHlwZSA9PSAnc3RyaW5nJykpIHJldHVybjtcbiAgICB2YXIgY2FwdHVyZSA9IHVzZUNhcHR1cmVQYXR0ZXJuLnRlc3QoZXZlbnRUeXBlKTtcbiAgICBldmVudFR5cGUgPSBldmVudFR5cGUucmVwbGFjZSh1c2VDYXB0dXJlUGF0dGVybiwgJycpO1xuICAgIHRoaXMuZW1pdHRlcigpW21ldGhvZF0oZXZlbnRUeXBlLCB0aGlzLCBjYXB0dXJlKTtcbn1cblxuXG4vLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG5mdW5jdGlvbiBoYW5kbGVFdmVudChldmVudCkge1xuICAgIHZhciBpc0NhcHR1cmVQaGFzZTtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJylcbiAgICAgICAgaXNDYXB0dXJlUGhhc2UgPSBldmVudC5ldmVudFBoYXNlID09IHdpbmRvdy5FdmVudC5DQVBUVVJJTkdfUEhBU0U7XG5cbiAgICBpZiAoaXNDYXB0dXJlUGhhc2UpXG4gICAgICAgIGV2ZW50ICs9IHVzZUNhcHR1cmVQb3N0Zml4O1xuXG4gICAgdGhpcy5kaXNwYXRjaE1lc3NhZ2UoZXZlbnQudHlwZSwgZXZlbnQpO1xufVxuXG5cbmZ1bmN0aW9uIERPTUVtaXR0ZXJTb3VyY2UkcG9zdE1lc3NhZ2UobWVzc2FnZSwgZGF0YSkge1xuICAgIHRoaXMubWVzc2VuZ2VyLnBvc3RNZXNzYWdlU3luYyhtZXNzYWdlLCBkYXRhKTtcbn1cblxuXG5mdW5jdGlvbiB0cmlnZ2VyKGV2ZW50VHlwZSwgcHJvcGVydGllcykge1xuICAgIGNoZWNrKGV2ZW50VHlwZSwgU3RyaW5nKTtcbiAgICBjaGVjayhwcm9wZXJ0aWVzLCBNYXRjaC5PcHRpb25hbChPYmplY3QpKTtcblxuICAgIGV2ZW50VHlwZSA9IGV2ZW50VHlwZS5yZXBsYWNlKHVzZUNhcHR1cmVQYXR0ZXJuLCAnJyk7XG4gICAgdmFyIEV2ZW50Q29uc3RydWN0b3IgPSBkb21FdmVudHNDb25zdHJ1Y3RvcnNbZXZlbnRUeXBlXTtcblxuICAgIGlmICh0eXBlb2YgRXZlbnRDb25zdHJ1Y3RvciAhPSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIGV2ZW50IHR5cGUnKTtcblxuICAgIC8vIGNoZWNrIGlmIGl0IGlzIGNvcnJlY3RcbiAgICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgIHByb3BlcnRpZXMudHlwZSA9IGV2ZW50VHlwZTtcblxuICAgIHZhciBkb21FdmVudCA9IG5ldyBFdmVudENvbnN0cnVjdG9yKGV2ZW50VHlwZSwgcHJvcGVydGllcyk7XG4gICAgdmFyIG5vdENhbmNlbGxlZCA9IHRoaXMuZW1pdHRlcigpLmRpc3BhdGNoRXZlbnQoZG9tRXZlbnQpO1xuICAgIHJldHVybiBub3RDYW5jZWxsZWQ7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogYG1pbG8ubWFpbGBcbiAqIEl0IGlzIGFuIGFwcGxpY2F0aW9uIGxldmVsIG1lc3NlbmdlciB0aGF0IGlzIGFuIGluc3RhbmNlIG9mIE1lc3NlbmdlciBjbGFzcy5cbiAqXG4gKiBBdCB0aGUgbW9tZW50LCBpbiBhZGRpdGlvbiB0byBhcHBsaWNhdGlvbiBtZXNzYWdlcyB0aGF0IHlvdSBkZWZpbmUsIHlvdSBjYW4gc3Vic2NyaWJlIHRvIF9fZG9tcmVhZHlfXyBtZXNzYWdlIHRoYXQgaXMgZ3VhcmFudGVlZCB0byBmaXJlIG9uY2UsXG4gKiBldmVuIGlmIERPTSB3YXMgcmVhZHkgYXQgdGhlIHRpbWUgb2YgdGhlIHN1YnNjcmlwdGlvbi5cbiAqXG4gKiBNZXNzYWdpbmcgYmV0d2VlbiBmcmFtZXMgaXMgYXZhaWxhYmxlIHZpYSBtaWxvLm1haWwuIFNlZSBbRnJhbWUgZmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldHMvRnJhbWUuanMuaHRtbCkuXG4gKlxuICogU2VlIFtNZXNzZW5nZXJdKC4uL21lc3Nlbmdlci9pbmRleC5qcy5odG1sKS5cbiAqIFxuKiovXG5cblxudmFyIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uLy4uL21lc3NlbmdlcicpXG4gICAgLCBNYWlsTXNnQVBJID0gcmVxdWlyZSgnLi9tYWlsX2FwaScpXG4gICAgLCBNYWlsTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4vbWFpbF9zb3VyY2UnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG5cbnZhciBtaWxvTWFpbCA9IG5ldyBNZXNzZW5nZXI7XG5cbnZhciBtYWlsTXNnU291cmNlID0gbmV3IE1haWxNZXNzYWdlU291cmNlKG1pbG9NYWlsLCB7IHRyaWdnZXI6ICd0cmlnZ2VyJyB9LCBuZXcgTWFpbE1zZ0FQSSk7XG5cbm1pbG9NYWlsLl9zZXRNZXNzYWdlU291cmNlKG1haWxNc2dTb3VyY2UpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbWlsb01haWw7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNZXNzZW5nZXJBUEkgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXIvbV9hcGknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG52YXIgTWFpbE1zZ0FQSSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2VuZ2VyQVBJLCAnTWFpbE1zZ0FQSScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oTWFpbE1zZ0FQSSwge1xuICAgIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZTogdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlLFxuICAgIGZpbHRlclNvdXJjZU1lc3NhZ2U6IGZpbHRlclNvdXJjZU1lc3NhZ2Vcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1haWxNc2dBUEk7XG5cblxuLy8gVE9ETzogdGhpcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHJlbGV2YW50IERPTSBldmVudCBkZXBlbmRlbnQgb24gZWxlbWVudCB0YWdcbi8vIENhbiBhbHNvIGltcGxlbWVudCBiZWZvcmVkYXRhY2hhbmdlZCBldmVudCB0byBhbGxvdyBwcmV2ZW50aW5nIHRoZSBjaGFuZ2Vcbi8vIHRyYW5zbGF0ZVRvRG9tRXZlbnRcbnZhciB3aW5kb3dNZXNzYWdlUmVnRXhwID0gL15tZXNzYWdlXFw6L1xuICAgICwgd2luZG93TWVzc2FnZVByZWZpeCA9ICdtZXNzYWdlOic7XG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgaWYgKG1lc3NhZ2UgPT0gJ2RvbXJlYWR5JylcbiAgICAgICAgcmV0dXJuICdyZWFkeXN0YXRlY2hhbmdlJztcbiAgICBlbHNlIGlmICh3aW5kb3dNZXNzYWdlUmVnRXhwLnRlc3QobWVzc2FnZSkpXG4gICAgICAgIHJldHVybiAnbWVzc2FnZSc7XG59XG5cblxuLy8gZmlsdGVyRGF0YU1lc3NhZ2VcbmZ1bmN0aW9uIGZpbHRlclNvdXJjZU1lc3NhZ2Uoc291cmNlTWVzc2FnZSwgbXNnVHlwZSwgbXNnRGF0YSkge1xuICAgIGlmIChzb3VyY2VNZXNzYWdlID09ICdyZWFkeXN0YXRlY2hhbmdlJykge1xuICAgICAgICAvL3JldHVybiBkb2N1bWVudC5yZWFkeVN0YXRlID09ICdpbnRlcmFjdGl2ZSc7XG4gICAgICAgIC8vICByZXR1cm4gZmFsc2U7XG4gICAgICAgIC8vIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19kb21SZWFkeUZpcmVkJywgdHJ1ZSwgXy5XUklUKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmIChzb3VyY2VNZXNzYWdlID09ICdtZXNzYWdlJylcbiAgICAgICAgcmV0dXJuIHdpbmRvd01lc3NhZ2VQcmVmaXggKyBtc2dEYXRhLmRhdGEudHlwZSA9PSBtc2dUeXBlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIE1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXIvbV9zb3VyY2UnKVxuICAgICwgZG9tRXZlbnRzQ29uc3RydWN0b3JzID0gcmVxdWlyZSgnLi4vZGVfY29uc3RycycpXG4gICAgLCBNYWlsTWVzc2FnZVNvdXJjZUVycm9yID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9lcnJvcicpLk1haWxNZXNzYWdlU291cmNlXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbnZhciBNYWlsTWVzc2FnZVNvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2FnZVNvdXJjZSwgJ01haWxNZXNzYWdlU291cmNlJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhNYWlsTWVzc2FnZVNvdXJjZSwge1xuICAgIC8vIGltcGxlbWVudGluZyBNZXNzYWdlU291cmNlIGludGVyZmFjZVxuICAgIGFkZFNvdXJjZVN1YnNjcmliZXI6IGFkZFNvdXJjZVN1YnNjcmliZXIsXG4gICAgcmVtb3ZlU291cmNlU3Vic2NyaWJlcjogcmVtb3ZlU291cmNlU3Vic2NyaWJlcixcbiAgICB0cmlnZ2VyOiB0cmlnZ2VyLFxuXG4gICAgLy8gY2xhc3Mgc3BlY2lmaWMgbWV0aG9kc1xuICAgIF93aW5kb3dTdWJzY3JpYmVyTWV0aG9kOiBfd2luZG93U3Vic2NyaWJlck1ldGhvZCxcbiAgICBoYW5kbGVFdmVudDogaGFuZGxlRXZlbnQsICAvLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1haWxNZXNzYWdlU291cmNlO1xuXG5cbmZ1bmN0aW9uIGFkZFNvdXJjZVN1YnNjcmliZXIoc291cmNlTWVzc2FnZSkge1xuICAgIGlmIChpc1JlYWR5U3RhdGVDaGFuZ2Uoc291cmNlTWVzc2FnZSkpIHtcbiAgICAgICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT0gJ2xvYWRpbmcnKVxuICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncmVhZHlzdGF0ZWNoYW5nZScsIHRoaXMsIGZhbHNlKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgRXZlbnRDb25zdHJ1Y3RvciA9IGRvbUV2ZW50c0NvbnN0cnVjdG9ycy5yZWFkeXN0YXRlY2hhbmdlO1xuICAgICAgICAgICAgdmFyIGRvbUV2ZW50ID0gbmV3IEV2ZW50Q29uc3RydWN0b3IoJ3JlYWR5c3RhdGVjaGFuZ2UnLCB7IHRhcmdldDogZG9jdW1lbnQgfSk7XG4gICAgICAgICAgICB0aGlzLmRpc3BhdGNoTWVzc2FnZSgncmVhZHlzdGF0ZWNoYW5nZScsIGRvbUV2ZW50KTtcbiAgICAgICAgfVxuICAgIH0gZWxzZVxuICAgICAgICB0aGlzLl93aW5kb3dTdWJzY3JpYmVyTWV0aG9kKCdhZGRFdmVudExpc3RlbmVyJywgc291cmNlTWVzc2FnZSk7XG59XG5cblxuZnVuY3Rpb24gcmVtb3ZlU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgaWYgKGlzUmVhZHlTdGF0ZUNoYW5nZShzb3VyY2VNZXNzYWdlKSlcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVhZHlzdGF0ZWNoYW5nZScsIHRoaXMsIGZhbHNlKTtcbiAgICBlbHNlIFxuICAgICAgICB0aGlzLl93aW5kb3dTdWJzY3JpYmVyTWV0aG9kKCdyZW1vdmVFdmVudExpc3RlbmVyJywgc291cmNlTWVzc2FnZSk7XG59XG5cblxuZnVuY3Rpb24gaXNSZWFkeVN0YXRlQ2hhbmdlKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICByZXR1cm4gc291cmNlTWVzc2FnZSA9PSAncmVhZHlzdGF0ZWNoYW5nZScgJiYgdHlwZW9mIGRvY3VtZW50ID09ICdvYmplY3QnO1xufVxuXG5mdW5jdGlvbiBpc1dpbmRvd01lc3NhZ2Uoc291cmNlTWVzc2FnZSkge1xuICAgIHJldHVybiBzb3VyY2VNZXNzYWdlID09ICdtZXNzYWdlJyAmJiB0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnO1xufVxuXG5mdW5jdGlvbiBfd2luZG93U3Vic2NyaWJlck1ldGhvZChtZXRob2QsIHNvdXJjZU1lc3NhZ2UpIHtcbiAgICBpZiAoaXNXaW5kb3dNZXNzYWdlKHNvdXJjZU1lc3NhZ2UpKVxuICAgICAgICB3aW5kb3dbbWV0aG9kXSgnbWVzc2FnZScsIHRoaXMsIGZhbHNlKTtcbn1cblxuXG4vLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG5mdW5jdGlvbiBoYW5kbGVFdmVudChldmVudCkge1xuICAgIHRoaXMuZGlzcGF0Y2hNZXNzYWdlKGV2ZW50LnR5cGUsIGV2ZW50KTtcbn1cblxuXG5mdW5jdGlvbiB0cmlnZ2VyKG1zZ1R5cGUsIGRhdGEpIHtcbiAgICBkYXRhID0gZGF0YSB8fCB7fTtcbiAgICBkYXRhLnR5cGUgPSAnbWVzc2FnZTonICsgbXNnVHlwZTtcbiAgICBcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAnb2JqZWN0JylcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKGRhdGEsICcqJylcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJylcbiAgICAsIERPTUVtaXR0ZXJTb3VyY2UgPSByZXF1aXJlKCcuL2RvbV9zb3VyY2UnKTtcblxuXG52YXIgd2luZG93U2VydmljZSA9IG5ldyBNZXNzZW5nZXI7XG52YXIgZG9tRW1pdHRlclNvdXJjZSA9IG5ldyBET01FbWl0dGVyU291cmNlKHdpbmRvd1NlcnZpY2UsIHsgdHJpZ2dlcjogJ3RyaWdnZXInIH0sIHVuZGVmaW5lZCwgd2luZG93KTtcbndpbmRvd1NlcnZpY2UuX3NldE1lc3NhZ2VTb3VyY2UoZG9tRW1pdHRlclNvdXJjZSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB3aW5kb3dTZXJ2aWNlO1xuXG5cbl8uZXh0ZW5kKHdpbmRvd1NlcnZpY2UsIHtcbiAgICBpc1RvcDogd2luZG93U2VydmljZV9pc1RvcFxufSk7XG5cblxuZnVuY3Rpb24gd2luZG93U2VydmljZV9pc1RvcCgpIHtcbiAgICByZXR1cm4gd2luZG93LnRvcCA9PSB3aW5kb3cuc2VsZiB8fCB3aW5kb3cuX19rYXJtYV9fO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY2xhc3Nlcy9WaWV3Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvR3JvdXAnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9XcmFwcGVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvVGV4dCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL1NlbGVjdCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0lucHV0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvSW5wdXRMaXN0Jyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvVGV4dGFyZWEnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9SYWRpb0dyb3VwJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvQnV0dG9uJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvSHlwZXJsaW5rJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvTGlzdCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0xpc3RJdGVtJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvVGltZScpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0RhdGUnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9Db21ibycpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL1N1cGVyQ29tYm8nKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9Db21ib0xpc3QnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9JbWFnZScpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL3VpL0Ryb3BUYXJnZXQnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy91aS9Gb2xkVHJlZScpO1xuXG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvYm9vdHN0cmFwL0Ryb3Bkb3duJyk7XG4vLyByZXF1aXJlKCcuL2NvbXBvbmVudHMvdWkvYm9vdHN0cmFwL0RpYWxvZycpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvRG9tJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvRGF0YScpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL0ZyYW1lJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvRXZlbnRzJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvT3B0aW9ucycpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL1RlbXBsYXRlJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvQ29udGFpbmVyJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvTW9kZWxGYWNldCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL0RyYWcnKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9Ecm9wJyk7XG5yZXF1aXJlKCcuL2NvbXBvbmVudHMvY19mYWNldHMvTGlzdCcpO1xucmVxdWlyZSgnLi9jb21wb25lbnRzL2NfZmFjZXRzL0l0ZW0nKTtcbnJlcXVpcmUoJy4vY29tcG9uZW50cy9jX2ZhY2V0cy9UcmFuc2ZlcicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBtaWxvLnV0aWxzLmNoZWNrYFxuICpcbiAqIENoZWNrIGlzIGEgbW9kdWxlIGZvciBwYXJhbWV0ZXJzIGNoZWNraW5nIGV4dHJhY3RlZCBmcm9tIFtNZXRlb3JdKGh0dHA6Ly9kb2NzLm1ldGVvci5jb20vKSBmcmFtZXdvcmsuXG4gKlxuICogSXQgYWxsb3dzIHRvIGJvdGggZG9jdW1lbnQgYW5kIHRvIGNoZWNrIHBhcmFtZXRlciB0eXBlcyBpbiB5b3VyIGZ1bmN0aW9uXG4gKiBtYWtpbmcgY29kZSBib3RoIHJlYWRhYmxlIGFuZCBzdGFibGUuXG4gKlxuICpcbiAqICMjIyBVc2FnZVxuICpgYGBcbiAqIHZhciBjaGVjayA9IG1pbG8uY2hlY2tcbiAqICAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG4gKlxuICogZnVuY3Rpb24gTXkobmFtZSwgb2JqLCBjYikge1xuICogICAgIC8vIGlmIGFueSBvZiBjaGVja3MgZmFpbCBhbiBlcnJvciB3aWxsIGJlIHRocm93blxuICogICAgIGNoZWNrKG5hbWUsIFN0cmluZyk7XG4gKiAgICAgY2hlY2sob2JqLCBNYXRjaC5PYmplY3RJbmNsdWRpbmcoeyBvcHRpb25zOiBPYmplY3QgfSkpO1xuICogICAgIGNoZWNrKGNiLCBGdW5jdGlvbik7XG4gKlxuICogICAgIC8vIC4uLiB5b3VyIGNvZGVcbiAqIH1cbiAqYGBgXG4gKiBTZWUgW01ldGVvciBkb2NzXShodHRwOi8vZG9jcy5tZXRlb3IuY29tLyNtYXRjaCkgdG8gc2VlIGhvdyBpdCB3b3Jrc1xuICpcbiAqXG4gKiAjIyMgUGF0dGVybnNcbiAqXG4gKiBBbGwgcGF0dGVybnMgYW5kIGZ1bmN0aW9ucyBkZXNjcmliZWQgaW4gTWV0ZW9yIGRvY3Mgd29yay5cbiAqXG4gKiBVbmxpa2UgaW4gTWV0ZW9yLCBPYmplY3QgcGF0dGVybiBtYXRjaGVzIGluc3RhbmNlIG9mIGFueSBjbGFzcyxcbiAqIG5vdCBvbmx5IHBsYWluIG9iamVjdC5cbiAqXG4gKiBJbiBhZGRpdGlvbiB0byBwYXR0ZXJucyBkZXNjcmliZWQgaW4gTWV0ZW9yIGRvY3MgdGhlIGZvbGxvd2luZyBwYXR0ZXJucyBhcmUgaW1wbGVtZW50ZWRcbiAqXG4gKiAqIE1hdGNoLl9fT2JqZWN0SGFzaF9fKF9wYXR0ZXJuXylcbiAqXG4gKiAgIE1hdGNoZXMgYW4gb2JqZWN0IHdoZXJlIGFsbCBwcm9wZXJ0aWVzIG1hdGNoIGEgZ2l2ZW4gcGF0dGVyblxuICpcbiAqICogTWF0Y2guX19TdWJjbGFzc19fKF9jb25zdHJ1Y3Rvcl8gWywgX21hdGNoVGhpc0NsYXNzVG9vX10pXG4gKlxuICogICBNYXRjaGVzIGEgY2xhc3MgdGhhdCBpcyBhIHN1YmNsYXNzIG9mIGEgZ2l2ZW4gY2xhc3MuIElmIHRoZSBzZWNvbmQgcGFyYW1ldGVyXG4gKiAgIGlzIHRydWUsIGl0IHdpbGwgYWxzbyBtYXRjaCB0aGUgY2xhc3MgaXRzZWxmLlxuICpcbiAqICAgV2l0aG91dCB0aGlzIHBhdHRlcm4gdG8gY2hlY2sgaWYgX015U3ViY2xhc3NfIGlzIGEgc3ViY2xhc3Mgb2YgX015Q2xhc3NfXG4gKiAgIHlvdSB3b3VsZCBoYXZlIHRvIHVzZVxuICpcbiAqICAgICAgIGNoZWNrKE15U3ViY2xhc3MsIE1hdGNoLldoZXJlKGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgIHJldHVybiBNeVN1YmNsYXNzLnByb3RvdHlwZSBpbnN0YW5jZW9mIE15Q2xhc3M7XG4gKiAgICAgICB9KTtcbiAqXG4gKlxuICogVGhpbmdzIHdlIGV4cGxpY2l0bHkgZG8gTk9UIHN1cHBvcnQ6XG4gKiAgICAtIGhldGVyb2dlbm91cyBhcnJheXNcbioqL1xuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxudmFyIGNoZWNrID0gZnVuY3Rpb24gKHZhbHVlLCBwYXR0ZXJuKSB7XG4gICAgaWYgKGNvbmZpZy5jaGVjayA9PT0gZmFsc2UpXG4gICAgICAgIHJldHVybjtcblxuICAgIC8vIFJlY29yZCB0aGF0IGNoZWNrIGdvdCBjYWxsZWQsIGlmIHNvbWVib2R5IGNhcmVkLlxuICAgIHRyeSB7XG4gICAgICAgIGNoZWNrU3VidHJlZSh2YWx1ZSwgcGF0dGVybik7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmICgoZXJyIGluc3RhbmNlb2YgTWF0Y2guRXJyb3IpICYmIGVyci5wYXRoKVxuICAgICAgICAgICAgZXJyLm1lc3NhZ2UgKz0gXCIgaW4gZmllbGQgXCIgKyBlcnIucGF0aDtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY2hlY2s7XG5cbnZhciBNYXRjaCA9IGNoZWNrLk1hdGNoID0ge1xuICAgIE9wdGlvbmFsOiBmdW5jdGlvbiAocGF0dGVybikge1xuICAgICAgICByZXR1cm4gbmV3IE9wdGlvbmFsKHBhdHRlcm4pO1xuICAgIH0sXG4gICAgT25lT2Y6IGZ1bmN0aW9uICgvKiBhcmd1bWVudHMgKi8pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPbmVPZihhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgQW55OiBbJ19fYW55X18nXSxcbiAgICBXaGVyZTogZnVuY3Rpb24gKGNvbmRpdGlvbikge1xuICAgICAgICByZXR1cm4gbmV3IFdoZXJlKGNvbmRpdGlvbik7XG4gICAgfSxcbiAgICBPYmplY3RJbmNsdWRpbmc6IGZ1bmN0aW9uIChwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiBuZXcgT2JqZWN0SW5jbHVkaW5nKHBhdHRlcm4pO1xuICAgIH0sXG4gICAgLy8gTWF0Y2hlcyBvbmx5IHNpZ25lZCAzMi1iaXQgaW50ZWdlcnNcbiAgICBJbnRlZ2VyOiBbJ19faW50ZWdlcl9fJ10sXG5cbiAgICAvLyBNYXRjaGVzIHN0cmluZyB0aGF0IGlzIGEgdmFsaWQgaWRlbnRpZmllciwgd2lsbCBub3QgYWxsb3cgamF2YXNjcmlwdCByZXNlcnZlZCB3b3Jkc1xuICAgIElkZW50aWZpZXJTdHJpbmc6IC9eW2Etel8kXVswLTlhLXpfJF0qJC9pLFxuXG4gICAgLy8gTWF0Y2hlcyBoYXNoIChvYmplY3QpIHdpdGggdmFsdWVzIG1hdGNoaW5nIHBhdHRlcm5cbiAgICBPYmplY3RIYXNoOiBmdW5jdGlvbihwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiBuZXcgT2JqZWN0SGFzaChwYXR0ZXJuKTtcbiAgICB9LFxuXG4gICAgU3ViY2xhc3M6IGZ1bmN0aW9uKFN1cGVyY2xhc3MsIG1hdGNoU3VwZXJjbGFzc1Rvbykge1xuICAgICAgICByZXR1cm4gbmV3IFN1YmNsYXNzKFN1cGVyY2xhc3MsIG1hdGNoU3VwZXJjbGFzc1Rvbyk7XG4gICAgfSxcblxuICAgIC8vIFhYWCBtYXRjaGVycyBzaG91bGQga25vdyBob3cgdG8gZGVzY3JpYmUgdGhlbXNlbHZlcyBmb3IgZXJyb3JzXG4gICAgRXJyb3I6IFR5cGVFcnJvcixcblxuICAgIC8vIE1ldGVvci5tYWtlRXJyb3JUeXBlKFwiTWF0Y2guRXJyb3JcIiwgZnVuY3Rpb24gKG1zZykge1xuICAgICAgICAvLyB0aGlzLm1lc3NhZ2UgPSBcIk1hdGNoIGVycm9yOiBcIiArIG1zZztcbiAgICAgICAgLy8gVGhlIHBhdGggb2YgdGhlIHZhbHVlIHRoYXQgZmFpbGVkIHRvIG1hdGNoLiBJbml0aWFsbHkgZW1wdHksIHRoaXMgZ2V0c1xuICAgICAgICAvLyBwb3B1bGF0ZWQgYnkgY2F0Y2hpbmcgYW5kIHJldGhyb3dpbmcgdGhlIGV4Y2VwdGlvbiBhcyBpdCBnb2VzIGJhY2sgdXAgdGhlXG4gICAgICAgIC8vIHN0YWNrLlxuICAgICAgICAvLyBFLmcuOiBcInZhbHNbM10uZW50aXR5LmNyZWF0ZWRcIlxuICAgICAgICAvLyB0aGlzLnBhdGggPSBcIlwiO1xuICAgICAgICAvLyBJZiB0aGlzIGdldHMgc2VudCBvdmVyIEREUCwgZG9uJ3QgZ2l2ZSBmdWxsIGludGVybmFsIGRldGFpbHMgYnV0IGF0IGxlYXN0XG4gICAgICAgIC8vIHByb3ZpZGUgc29tZXRoaW5nIGJldHRlciB0aGFuIDUwMCBJbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuXG4gICAgLy8gICAgIHRoaXMuc2FuaXRpemVkRXJyb3IgPSBuZXcgTWV0ZW9yLkVycm9yKDQwMCwgXCJNYXRjaCBmYWlsZWRcIik7XG4gICAgLy8gfSksXG5cbiAgICAvLyBUZXN0cyB0byBzZWUgaWYgdmFsdWUgbWF0Y2hlcyBwYXR0ZXJuLiBVbmxpa2UgY2hlY2ssIGl0IG1lcmVseSByZXR1cm5zIHRydWVcbiAgICAvLyBvciBmYWxzZSAodW5sZXNzIGFuIGVycm9yIG90aGVyIHRoYW4gTWF0Y2guRXJyb3Igd2FzIHRocm93bikuXG4gICAgdGVzdDogZnVuY3Rpb24gKHZhbHVlLCBwYXR0ZXJuKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjaGVja1N1YnRyZWUodmFsdWUsIHBhdHRlcm4pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgTWF0Y2guRXJyb3IpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgLy8gUmV0aHJvdyBvdGhlciBlcnJvcnMuXG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuZnVuY3Rpb24gT3B0aW9uYWwocGF0dGVybikge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47XG59O1xuXG5mdW5jdGlvbiBPbmVPZihjaG9pY2VzKSB7XG4gICAgaWYgKGNob2ljZXMubGVuZ3RoID09IDApXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk11c3QgcHJvdmlkZSBhdCBsZWFzdCBvbmUgY2hvaWNlIHRvIE1hdGNoLk9uZU9mXCIpO1xuICAgIHRoaXMuY2hvaWNlcyA9IGNob2ljZXM7XG59O1xuXG5mdW5jdGlvbiBXaGVyZShjb25kaXRpb24pIHtcbiAgICB0aGlzLmNvbmRpdGlvbiA9IGNvbmRpdGlvbjtcbn07XG5cbmZ1bmN0aW9uIE9iamVjdEluY2x1ZGluZyhwYXR0ZXJuKSB7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbn07XG5cbmZ1bmN0aW9uIE9iamVjdEhhc2gocGF0dGVybikge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47XG59O1xuXG5mdW5jdGlvbiBTdWJjbGFzcyhTdXBlcmNsYXNzLCBtYXRjaFN1cGVyY2xhc3NUb28pIHtcbiAgICB0aGlzLlN1cGVyY2xhc3MgPSBTdXBlcmNsYXNzO1xuICAgIHRoaXMubWF0Y2hTdXBlcmNsYXNzID0gbWF0Y2hTdXBlcmNsYXNzVG9vO1xufTtcblxudmFyIHR5cGVvZkNoZWNrcyA9IFtcbiAgICBbU3RyaW5nLCBcInN0cmluZ1wiXSxcbiAgICBbTnVtYmVyLCBcIm51bWJlclwiXSxcbiAgICBbQm9vbGVhbiwgXCJib29sZWFuXCJdLFxuICAgIFtGdW5jdGlvbiwgXCJmdW5jdGlvblwiXSxcbiAgICAvLyBXaGlsZSB3ZSBkb24ndCBhbGxvdyB1bmRlZmluZWQgaW4gSlNPTiwgdGhpcyBpcyBnb29kIGZvciBvcHRpb25hbFxuICAgIC8vIGFyZ3VtZW50cyB3aXRoIE9uZU9mLlxuICAgIFt1bmRlZmluZWQsIFwidW5kZWZpbmVkXCJdXG5dO1xuXG5mdW5jdGlvbiBjaGVja1N1YnRyZWUodmFsdWUsIHBhdHRlcm4pIHtcbiAgICAvLyBNYXRjaCBhbnl0aGluZyFcbiAgICBpZiAocGF0dGVybiA9PT0gTWF0Y2guQW55KVxuICAgICAgICByZXR1cm47XG5cbiAgICAvLyBCYXNpYyBhdG9taWMgdHlwZXMuXG4gICAgLy8gRG8gbm90IG1hdGNoIGJveGVkIG9iamVjdHMgKGUuZy4gU3RyaW5nLCBCb29sZWFuKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHlwZW9mQ2hlY2tzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChwYXR0ZXJuID09PSB0eXBlb2ZDaGVja3NbaV1bMF0pIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IHR5cGVvZkNoZWNrc1tpXVsxXSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBcIiArIHR5cGVvZkNoZWNrc1tpXVsxXSArIFwiLCBnb3QgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChwYXR0ZXJuID09PSBudWxsKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiRXhwZWN0ZWQgbnVsbCwgZ290IFwiICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvLyBNYXRjaC5JbnRlZ2VyIGlzIHNwZWNpYWwgdHlwZSBlbmNvZGVkIHdpdGggYXJyYXlcbiAgICBpZiAocGF0dGVybiA9PT0gTWF0Y2guSW50ZWdlcikge1xuICAgICAgICAvLyBUaGVyZSBpcyBubyBjb25zaXN0ZW50IGFuZCByZWxpYWJsZSB3YXkgdG8gY2hlY2sgaWYgdmFyaWFibGUgaXMgYSA2NC1iaXRcbiAgICAgICAgLy8gaW50ZWdlci4gT25lIG9mIHRoZSBwb3B1bGFyIHNvbHV0aW9ucyBpcyB0byBnZXQgcmVtaW5kZXIgb2YgZGl2aXNpb24gYnkgMVxuICAgICAgICAvLyBidXQgdGhpcyBtZXRob2QgZmFpbHMgb24gcmVhbGx5IGxhcmdlIGZsb2F0cyB3aXRoIGJpZyBwcmVjaXNpb24uXG4gICAgICAgIC8vIEUuZy46IDEuMzQ4MTkyMzA4NDkxODI0ZSsyMyAlIDEgPT09IDAgaW4gVjhcbiAgICAgICAgLy8gQml0d2lzZSBvcGVyYXRvcnMgd29yayBjb25zaXN0YW50bHkgYnV0IGFsd2F5cyBjYXN0IHZhcmlhYmxlIHRvIDMyLWJpdFxuICAgICAgICAvLyBzaWduZWQgaW50ZWdlciBhY2NvcmRpbmcgdG8gSmF2YVNjcmlwdCBzcGVjcy5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgKHZhbHVlIHwgMCkgPT09IHZhbHVlKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcignRXhwZWN0ZWQgSW50ZWdlciwgZ290ICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAodmFsdWUgaW5zdGFuY2VvZiBPYmplY3QgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgOiB2YWx1ZSkpO1xuICAgIH1cblxuICAgIGlmIChwYXR0ZXJuID09PSBNYXRjaC5JZGVudGlmaWVyU3RyaW5nKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIE1hdGNoLklkZW50aWZpZXJTdHJpbmcudGVzdCh2YWx1ZSlcbiAgICAgICAgICAgICAgICAmJiBfanNLZXl3b3Jkcy5pbmRleE9mKGtleSkgPT0gLTEpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcignRXhwZWN0ZWQgaWRlbnRpZmllciBzdHJpbmcsIGdvdCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ID8gSlNPTi5zdHJpbmdpZnkodmFsdWUpIDogdmFsdWUpKTtcbiAgICB9XG5cbiAgICAvLyBcIk9iamVjdFwiIGlzIHNob3J0aGFuZCBmb3IgTWF0Y2guT2JqZWN0SW5jbHVkaW5nKHt9KTtcbiAgICBpZiAocGF0dGVybiA9PT0gT2JqZWN0KVxuICAgICAgICBwYXR0ZXJuID0gTWF0Y2guT2JqZWN0SW5jbHVkaW5nKHt9KTtcblxuICAgIC8vIEFycmF5IChjaGVja2VkIEFGVEVSIEFueSwgd2hpY2ggaXMgaW1wbGVtZW50ZWQgYXMgYW4gQXJyYXkpLlxuICAgIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgaWYgKHBhdHRlcm4ubGVuZ3RoICE9PSAxKVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJCYWQgcGF0dGVybjogYXJyYXlzIG11c3QgaGF2ZSBvbmUgdHlwZSBlbGVtZW50XCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocGF0dGVybikpO1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBhcnJheSwgZ290IFwiICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlRWxlbWVudCwgaW5kZXgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY2hlY2tTdWJ0cmVlKHZhbHVlRWxlbWVudCwgcGF0dGVyblswXSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgTWF0Y2guRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyLnBhdGggPSBfcHJlcGVuZFBhdGgoaW5kZXgsIGVyci5wYXRoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEFyYml0cmFyeSB2YWxpZGF0aW9uIGNoZWNrcy4gVGhlIGNvbmRpdGlvbiBjYW4gcmV0dXJuIGZhbHNlIG9yIHRocm93IGFcbiAgICAvLyBNYXRjaC5FcnJvciAoaWUsIGl0IGNhbiBpbnRlcm5hbGx5IHVzZSBjaGVjaygpKSB0byBmYWlsLlxuICAgIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgV2hlcmUpIHtcbiAgICAgICAgaWYgKHBhdHRlcm4uY29uZGl0aW9uKHZhbHVlKSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gWFhYIHRoaXMgZXJyb3IgaXMgdGVycmlibGVcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiRmFpbGVkIE1hdGNoLldoZXJlIHZhbGlkYXRpb25cIik7XG4gICAgfVxuXG5cbiAgICBpZiAocGF0dGVybiBpbnN0YW5jZW9mIE9wdGlvbmFsKVxuICAgICAgICBwYXR0ZXJuID0gTWF0Y2guT25lT2YodW5kZWZpbmVkLCBwYXR0ZXJuLnBhdHRlcm4pO1xuXG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBPbmVPZikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdHRlcm4uY2hvaWNlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjaGVja1N1YnRyZWUodmFsdWUsIHBhdHRlcm4uY2hvaWNlc1tpXSk7XG4gICAgICAgICAgICAgICAgLy8gTm8gZXJyb3I/IFlheSwgcmV0dXJuLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIE90aGVyIGVycm9ycyBzaG91bGQgYmUgdGhyb3duLiBNYXRjaCBlcnJvcnMganVzdCBtZWFuIHRyeSBhbm90aGVyXG4gICAgICAgICAgICAgICAgLy8gY2hvaWNlLlxuICAgICAgICAgICAgICAgIGlmICghKGVyciBpbnN0YW5jZW9mIE1hdGNoLkVycm9yKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFhYWCB0aGlzIGVycm9yIGlzIHRlcnJpYmxlXG4gICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIkZhaWxlZCBNYXRjaC5PbmVPZiBvciBNYXRjaC5PcHRpb25hbCB2YWxpZGF0aW9uXCIpO1xuICAgIH1cblxuICAgIC8vIEEgZnVuY3Rpb24gdGhhdCBpc24ndCBzb21ldGhpbmcgd2Ugc3BlY2lhbC1jYXNlIGlzIGFzc3VtZWQgdG8gYmUgYVxuICAgIC8vIGNvbnN0cnVjdG9yLlxuICAgIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgcGF0dGVybilcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gWFhYIHdoYXQgaWYgLm5hbWUgaXNuJ3QgZGVmaW5lZFxuICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBcIiArIHBhdHRlcm4uY29uc3RydWN0b3IubmFtZSk7XG4gICAgfVxuXG4gICAgdmFyIHVua25vd25LZXlzQWxsb3dlZCA9IGZhbHNlO1xuICAgIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgT2JqZWN0SW5jbHVkaW5nKSB7XG4gICAgICAgIHVua25vd25LZXlzQWxsb3dlZCA9IHRydWU7XG4gICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnBhdHRlcm47XG4gICAgfVxuXG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBPYmplY3RIYXNoKSB7XG4gICAgICAgIHZhciBrZXlQYXR0ZXJuID0gcGF0dGVybi5wYXR0ZXJuO1xuICAgICAgICB2YXIgZW1wdHlIYXNoID0gdHJ1ZTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIHZhbHVlKSB7XG4gICAgICAgICAgICBlbXB0eUhhc2ggPSBmYWxzZTtcbiAgICAgICAgICAgIGNoZWNrKHZhbHVlW2tleV0sIGtleVBhdHRlcm4pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbXB0eUhhc2gpXG4gICAgICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJFeHBlY3RlZCBcIiArIHBhdHRlcm4uY29uc3RydWN0b3IubmFtZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGF0dGVybiBpbnN0YW5jZW9mIFN1YmNsYXNzKSB7XG4gICAgICAgIHZhciBTdXBlcmNsYXNzID0gcGF0dGVybi5TdXBlcmNsYXNzO1xuICAgICAgICBpZiAocGF0dGVybi5tYXRjaFN1cGVyY2xhc3MgJiYgdmFsdWUgPT0gU3VwZXJjbGFzcylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKCEgKHZhbHVlLnByb3RvdHlwZSBpbnN0YW5jZW9mIFN1cGVyY2xhc3MpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiRXhwZWN0ZWQgXCIgKyBwYXR0ZXJuLmNvbnN0cnVjdG9yLm5hbWUgKyBcIiBvZiBcIiArIFN1cGVyY2xhc3MubmFtZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHBhdHRlcm4gIT09IFwib2JqZWN0XCIpXG4gICAgICAgIHRocm93IEVycm9yKFwiQmFkIHBhdHRlcm46IHVua25vd24gcGF0dGVybiB0eXBlXCIpO1xuXG4gICAgLy8gQW4gb2JqZWN0LCB3aXRoIHJlcXVpcmVkIGFuZCBvcHRpb25hbCBrZXlzLiBOb3RlIHRoYXQgdGhpcyBkb2VzIE5PVCBkb1xuICAgIC8vIHN0cnVjdHVyYWwgbWF0Y2hlcyBhZ2FpbnN0IG9iamVjdHMgb2Ygc3BlY2lhbCB0eXBlcyB0aGF0IGhhcHBlbiB0byBtYXRjaFxuICAgIC8vIHRoZSBwYXR0ZXJuOiB0aGlzIHJlYWxseSBuZWVkcyB0byBiZSBhIHBsYWluIG9sZCB7T2JqZWN0fSFcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JylcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiRXhwZWN0ZWQgb2JqZWN0LCBnb3QgXCIgKyB0eXBlb2YgdmFsdWUpO1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbClcbiAgICAgICAgdGhyb3cgbmV3IE1hdGNoLkVycm9yKFwiRXhwZWN0ZWQgb2JqZWN0LCBnb3QgbnVsbFwiKTtcblxuICAgIHZhciByZXF1aXJlZFBhdHRlcm5zID0ge307XG4gICAgdmFyIG9wdGlvbmFsUGF0dGVybnMgPSB7fTtcblxuICAgIF8uZWFjaEtleShwYXR0ZXJuLCBmdW5jdGlvbihzdWJQYXR0ZXJuLCBrZXkpIHtcbiAgICAgICAgaWYgKHBhdHRlcm5ba2V5XSBpbnN0YW5jZW9mIE9wdGlvbmFsKVxuICAgICAgICAgICAgb3B0aW9uYWxQYXR0ZXJuc1trZXldID0gcGF0dGVybltrZXldLnBhdHRlcm47XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlcXVpcmVkUGF0dGVybnNba2V5XSA9IHBhdHRlcm5ba2V5XTtcbiAgICB9LCB0aGlzLCB0cnVlKTtcblxuICAgIF8uZWFjaEtleSh2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgICB2YXIgc3ViVmFsdWUgPSB2YWx1ZVtrZXldO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHJlcXVpcmVkUGF0dGVybnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGNoZWNrU3VidHJlZShzdWJWYWx1ZSwgcmVxdWlyZWRQYXR0ZXJuc1trZXldKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgcmVxdWlyZWRQYXR0ZXJuc1trZXldO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvcHRpb25hbFBhdHRlcm5zLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBjaGVja1N1YnRyZWUoc3ViVmFsdWUsIG9wdGlvbmFsUGF0dGVybnNba2V5XSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghdW5rbm93bktleXNBbGxvd2VkKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWF0Y2guRXJyb3IoXCJVbmtub3duIGtleVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgTWF0Y2guRXJyb3IpXG4gICAgICAgICAgICAgICAgZXJyLnBhdGggPSBfcHJlcGVuZFBhdGgoa2V5LCBlcnIucGF0aCk7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICB9LCB0aGlzLCB0cnVlKTtcblxuICAgIF8uZWFjaEtleShyZXF1aXJlZFBhdHRlcm5zLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICAgIHRocm93IG5ldyBNYXRjaC5FcnJvcihcIk1pc3Npbmcga2V5ICdcIiArIGtleSArIFwiJ1wiKTtcbiAgICB9LCB0aGlzLCB0cnVlKTtcbn07XG5cblxudmFyIF9qc0tleXdvcmRzID0gW1wiZG9cIiwgXCJpZlwiLCBcImluXCIsIFwiZm9yXCIsIFwibGV0XCIsIFwibmV3XCIsIFwidHJ5XCIsIFwidmFyXCIsIFwiY2FzZVwiLFxuICAgIFwiZWxzZVwiLCBcImVudW1cIiwgXCJldmFsXCIsIFwiZmFsc2VcIiwgXCJudWxsXCIsIFwidGhpc1wiLCBcInRydWVcIiwgXCJ2b2lkXCIsIFwid2l0aFwiLFxuICAgIFwiYnJlYWtcIiwgXCJjYXRjaFwiLCBcImNsYXNzXCIsIFwiY29uc3RcIiwgXCJzdXBlclwiLCBcInRocm93XCIsIFwid2hpbGVcIiwgXCJ5aWVsZFwiLFxuICAgIFwiZGVsZXRlXCIsIFwiZXhwb3J0XCIsIFwiaW1wb3J0XCIsIFwicHVibGljXCIsIFwicmV0dXJuXCIsIFwic3RhdGljXCIsIFwic3dpdGNoXCIsXG4gICAgXCJ0eXBlb2ZcIiwgXCJkZWZhdWx0XCIsIFwiZXh0ZW5kc1wiLCBcImZpbmFsbHlcIiwgXCJwYWNrYWdlXCIsIFwicHJpdmF0ZVwiLCBcImNvbnRpbnVlXCIsXG4gICAgXCJkZWJ1Z2dlclwiLCBcImZ1bmN0aW9uXCIsIFwiYXJndW1lbnRzXCIsIFwiaW50ZXJmYWNlXCIsIFwicHJvdGVjdGVkXCIsIFwiaW1wbGVtZW50c1wiLFxuICAgIFwiaW5zdGFuY2VvZlwiXTtcblxuLy8gQXNzdW1lcyB0aGUgYmFzZSBvZiBwYXRoIGlzIGFscmVhZHkgZXNjYXBlZCBwcm9wZXJseVxuLy8gcmV0dXJucyBrZXkgKyBiYXNlXG5mdW5jdGlvbiBfcHJlcGVuZFBhdGgoa2V5LCBiYXNlKSB7XG4gICAgaWYgKCh0eXBlb2Yga2V5KSA9PT0gXCJudW1iZXJcIiB8fCBrZXkubWF0Y2goL15bMC05XSskLykpXG4gICAgICAgIGtleSA9IFwiW1wiICsga2V5ICsgXCJdXCI7XG4gICAgZWxzZSBpZiAoIWtleS5tYXRjaChNYXRjaC5JZGVudGlmaWVyU3RyaW5nKSB8fCBfanNLZXl3b3Jkcy5pbmRleE9mKGtleSkgIT0gLTEpXG4gICAgICAgIGtleSA9IEpTT04uc3RyaW5naWZ5KFtrZXldKTtcblxuICAgIGlmIChiYXNlICYmIGJhc2VbMF0gIT09IFwiW1wiKVxuICAgICAgICByZXR1cm4ga2V5ICsgJy4nICsgYmFzZTtcbiAgICByZXR1cm4ga2V5ICsgYmFzZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjb3VudCA9IHJlcXVpcmUoJy4vY291bnQnKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIHByZWZpeCA9IGNvbmZpZy5jb21wb25lbnRQcmVmaXg7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBjb21wb25lbnROYW1lO1xuXG5cbmZ1bmN0aW9uIGNvbXBvbmVudE5hbWUoKSB7XG4gICAgcmV0dXJuIHByZWZpeCArIGNvdW50KCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB0aW1lc3RhbXAgPSBEYXRlLm5vdygpXG4gICAgLCBjb3VudCA9ICcnXG4gICAgLCB1bmlxdWVJRCA9ICcnICsgdGltZXN0YW1wO1xuXG5mdW5jdGlvbiB1bmlxdWVDb3VudCgpIHtcbiAgICB2YXIgbmV3VGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICB1bmlxdWVJRCA9ICcnICsgbmV3VGltZXN0YW1wO1xuICAgIGlmICh0aW1lc3RhbXAgPT0gbmV3VGltZXN0YW1wKSB7XG4gICAgICAgIGNvdW50ID0gY291bnQgPT09ICcnID8gMCA6IGNvdW50ICsgMTtcbiAgICAgICAgdW5pcXVlSUQgKz0gJ18nICsgY291bnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGltZXN0YW1wID0gbmV3VGltZXN0YW1wO1xuICAgICAgICBjb3VudCA9ICcnO1xuICAgIH1cblxuICAgIHJldHVybiB1bmlxdWVJRDtcbn1cblxudW5pcXVlQ291bnQuZ2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHVuaXF1ZUlEO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHVuaXF1ZUNvdW50O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUNvbXBvbmVudENsYXNzO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gd2hpY2ggY3JlYXRlcyBhbmQgcmVnaXN0ZXJzIG5ldyBtaWxvIGNvbXBvbmVudC4gIFRoZSBjb21wb25lbnQgY3JlYXRlZCB3aWxsIGhhdmVcbiAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzdXBlciBjbGFzcyB1c2VkIGluIGl0cyBjcmVhdGlvbiAoQWNjZXNzYWJsZSB1c2luZyA8Q29tcG9uZW50Q2xhc3M+LnN1cGVyKS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29uZmlnLmNsYXNzTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBuZXcgY29tcG9uZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gWydDb21wb25lbnQnXSBjb25maWcuc3VwZXJDbGFzc05hbWUgLSBUaGUgbmFtZSBvZiBhbiBleGlzdGluZyBjb21wb25lbnQgdG8gYmUgdXNlZCBhcyB0aGUgbmV3IGNvbXBvbmVudCdzIHN1cGVyIGNsYXNzXG4gKiBAcGFyYW0ge29iamVjdD19IGNvbmZpZy5mYWNldHMgLSBGYWNldCBjb25maWd1cmF0aW9uIChIYXNoIG9mIGZhY2V0IG5hbWUge3N0cmluZ30gdG8gY29uZmlnIHtvYmplY3R9KVxuICogQHBhcmFtIHtvYmplY3Q9fSBjb25maWcubWV0aG9kcyAtIE1ldGhvZHMgb2YgdGhlIG5ldyBjb21wb25lbnQgKEhhc2ggb2YgZnVuY3Rpb24gbmFtZSB7c3RyaW5nfSB0byBmdW5jdGlvbiB7ZnVuY3Rpb259KVxuICogQHBhcmFtIHtvYmplY3Q9fSBjb25maWcuc3RhdGljTWV0aG9kcyAtIFN0YXRpYyBtZXRob2RzIG9mIHRoZSBuZXcgY29tcG9uZW50IChIYXNoIG9mIGZ1bmN0aW9uIG5hbWUge3N0cmluZ30gdG8gZnVuY3Rpb24ge2Z1bmN0aW9ufSlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50Q2xhc3MoY29uZmlnKSB7XG4gICAgdmFyIGNvbXBvbmVudFJlZ2lzdHJ5ID0gbWlsby5yZWdpc3RyeS5jb21wb25lbnRzO1xuICAgIHZhciBTdXBlckNsYXNzID0gY29tcG9uZW50UmVnaXN0cnkuZ2V0KGNvbmZpZy5zdXBlckNsYXNzTmFtZSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgdmFyIENvbXBvbmVudENsYXNzID0gU3VwZXJDbGFzcy5jcmVhdGVDb21wb25lbnRDbGFzcyhjb25maWcuY2xhc3NOYW1lLCBjb25maWcuZmFjZXRzKTtcblxuICAgIGlmKGNvbmZpZy5tZXRob2RzKSB7XG4gICAgICAgIF8uZXh0ZW5kUHJvdG8oQ29tcG9uZW50Q2xhc3MsIGNvbmZpZy5tZXRob2RzKTtcbiAgICB9XG5cbiAgICBpZihjb25maWcuc3RhdGljTWV0aG9kcykge1xuICAgICAgICBpZihjb25maWcuc3RhdGljTWV0aG9kcy5zdXBlciAhPT0gdW5kZWZpbmVkKSB0aHJvdyAnXFwnc3VwZXJcXCcgaXMgYSByZXNlcnZlZCBrZXl3b3JkJztcblxuICAgICAgICBfLmV4dGVuZChDb21wb25lbnRDbGFzcywgY29uZmlnLnN0YXRpY01ldGhvZHMpO1xuICAgIH1cblxuICAgIENvbXBvbmVudENsYXNzLnN1cGVyID0gU3VwZXJDbGFzcy5wcm90b3R5cGU7XG4gICAgXG4gICAgY29tcG9uZW50UmVnaXN0cnkuYWRkKENvbXBvbmVudENsYXNzKTtcblxuICAgIHJldHVybiBDb21wb25lbnRDbGFzcztcbn0iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4vbG9nZ2VyJyk7XG5cbnZhciBkb21VdGlscyA9IHtcbiAgICBjaGlsZHJlbjogY2hpbGRyZW4sXG4gICAgZmlsdGVyTm9kZUxpc3RCeVR5cGU6IGZpbHRlck5vZGVMaXN0QnlUeXBlLFxuICAgIGNvbnRhaW5pbmdFbGVtZW50OiBjb250YWluaW5nRWxlbWVudCxcbiAgICBzZWxlY3RFbGVtZW50Q29udGVudHM6IHNlbGVjdEVsZW1lbnRDb250ZW50cyxcbiAgICBzZWxlY3RFbGVtZW50VGV4dDogc2VsZWN0RWxlbWVudFRleHQsXG4gICAgZ2V0RWxlbWVudE9mZnNldDogZ2V0RWxlbWVudE9mZnNldCxcbiAgICBzZXRDYXJldFBvc2l0aW9uOiBzZXRDYXJldFBvc2l0aW9uLFxuICAgIGdldFNlbGVjdGlvbkRpcmVjdGlvbjogZ2V0U2VsZWN0aW9uRGlyZWN0aW9uLFxuICAgIHNldFNlbGVjdGlvbjogc2V0U2VsZWN0aW9uLFxuICAgIGNsZWFyU2VsZWN0aW9uOiBjbGVhclNlbGVjdGlvbixcbiAgICByZW1vdmVFbGVtZW50OiByZW1vdmVFbGVtZW50LFxuICAgIHVud3JhcEVsZW1lbnQ6IHVud3JhcEVsZW1lbnQsXG4gICAgd3JhcEluRWxlbWVudDogd3JhcEluRWxlbWVudCxcbiAgICBkZXRhY2hDb21wb25lbnQ6IGRldGFjaENvbXBvbmVudCxcbiAgICBmaXJzdFRleHROb2RlOiBmaXJzdFRleHROb2RlLFxuICAgIGxhc3RUZXh0Tm9kZTogbGFzdFRleHROb2RlLFxuICAgIHRyaW1Ob2RlUmlnaHQ6IHRyaW1Ob2RlUmlnaHQsXG4gICAgdHJpbU5vZGVMZWZ0OiB0cmltTm9kZUxlZnQsXG4gICAgc3RyaXBIdG1sOiBzdHJpcEh0bWwsXG4gICAgaHRtbEVudGl0aWVzOiBodG1sRW50aXRpZXMsXG4gICAgd2Fsa1RyZWU6IHdhbGtUcmVlLFxuICAgIGNyZWF0ZVRyZWVXYWxrZXI6IGNyZWF0ZVRyZWVXYWxrZXIsXG5cbiAgICB0cmVlUGF0aE9mOiB0cmVlUGF0aE9mLFxuICAgIGdldE5vZGVBdFRyZWVQYXRoOiBnZXROb2RlQXRUcmVlUGF0aCxcbiAgICBpbnNlcnRBdFRyZWVQYXRoOiBpbnNlcnRBdFRyZWVQYXRoLFxuICAgIGlzVHJlZVBhdGhCZWZvcmU6IGlzVHJlZVBhdGhCZWZvcmUsXG5cbiAgICBnZXROb2RlV2luZG93OiBnZXROb2RlV2luZG93LFxuXG4gICAgZ2V0Q29tcG9uZW50c0Zyb21SYW5nZTogZ2V0Q29tcG9uZW50c0Zyb21SYW5nZSxcbiAgICBkZWxldGVSYW5nZVdpdGhDb21wb25lbnRzOiBkZWxldGVSYW5nZVdpdGhDb21wb25lbnRzLFxuICAgIGZvckVhY2hOb2Rlc0luUmFuZ2U6IGZvckVhY2hOb2Rlc0luUmFuZ2UsXG4gICAgYXJlUmFuZ2VzRXF1YWw6IGFyZVJhbmdlc0VxdWFsLFxuXG4gICAgYWRkRGVidWdQb2ludDogYWRkRGVidWdQb2ludFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBkb21VdGlscztcblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGxpc3Qgb2YgZWxlbWVudCBjaGlsZHJlbiBvZiBET00gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgZWxlbWVudCB0byByZXR1cm4gdGhlIGNoaWxkcmVuIG9mIChvbmx5IERPTSBlbGVtZW50cylcbiAqIEByZXR1cm4ge0FycmF5W0VsZW1lbnRdfVxuICovXG4gZnVuY3Rpb24gY2hpbGRyZW4oZWwpIHtcbiAgICByZXR1cm4gZmlsdGVyTm9kZUxpc3RCeVR5cGUoZWwuY2hpbGROb2RlcywgTm9kZS5FTEVNRU5UX05PREUpO1xuIH1cblxuXG4vKipcbiAqIEZpbHRlcnMgdGhlIGxpc3Qgb2Ygbm9kZXMgYnkgdHlwZVxuICpcbiAqIEBwYXJhbSB7Tm9kZUxpc3R9IG5vZGVMaXN0IHRoZSBsaXN0IG9mIG5vZGVzLCBmb3IgZXhhbXBsZSBjaGlsZE5vZGVzIHByb3BlcnR5IG9mIERPTSBlbGVtZW50XG4gKiBAcGFyYW0ge0ludGVnZXJ9IG5vZGVUeXBlIGFuIGludGVnZXIgY29uc3RhbnQgW2RlZmluZWQgYnkgRE9NIEFQSV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL05vZGUubm9kZVR5cGUpLCBlLmcuIGBOb2RlLkVMRU1FTlRfTk9ERWAgb3IgYE5vZGUuVEVYVF9OT0RFYFxuICogQHJldHVybiB7QXJyYXlbTm9kZV19XG4gKi9cbmZ1bmN0aW9uIGZpbHRlck5vZGVMaXN0QnlUeXBlKG5vZGVMaXN0LCBub2RlVHlwZSkge1xuICAgIHJldHVybiBfLmZpbHRlcihub2RlTGlzdCwgZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5vZGUubm9kZVR5cGUgPT0gbm9kZVR5cGU7XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBGaW5kIG5lYXJlc3QgcGFyZW50IGVsZW1lbnQgZm9yIG5vZGUuXG4gKiBJZiBub2RlIGlzIGFuIGVsZW1lbnQsIGl0IHdpbGwgYmUgcmV0dXJuZWQuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcmV0dXJuIHtFbGVtZW50fG51bGx9XG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5pbmdFbGVtZW50KG5vZGUpIHtcbiAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSBOb2RlLkVMRU1FTlRfTk9ERSlcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuXG4vKipcbiAqIFNlbGVjdHMgaW5uZXIgY29udGVudHMgb2YgRE9NIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsIERPTSBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIHNlbGVjdEVsZW1lbnRDb250ZW50cyhlbCkge1xuICAgIHZhciBkb2MgPSBlbC5vd25lckRvY3VtZW50O1xuICAgIGlmICghIGRvYykgcmV0dXJuIGxvZ2dlci5lcnJvcignc2VsZWN0RWxlbWVudENvbnRlbnRzOiBlbGVtZW50IGhhcyBubyBkb2N1bWVudCcpO1xuICAgIHZhciByYW5nZSA9IGRvYy5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhlbCk7XG4gICAgdmFyIHdpbiA9IGdldE5vZGVXaW5kb3coZWwpXG4gICAgICAgICwgc2VsID0gd2luLmdldFNlbGVjdGlvbigpO1xuICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xufVxuXG5cbi8qKlxuICogU2VsZWN0cyB0ZXh0IGluc2lkZSBlbGVtZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKi9cbmZ1bmN0aW9uIHNlbGVjdEVsZW1lbnRUZXh0KGVsKSB7XG4gICAgdmFyIGZyb21Ob2RlID0gZmlyc3RUZXh0Tm9kZShlbClcbiAgICAgICAgLCB0b05vZGUgPSBsYXN0VGV4dE5vZGUoZWwpO1xuXG4gICAgaWYgKGZyb21Ob2RlICYmIHRvTm9kZSlcbiAgICAgICAgc2V0U2VsZWN0aW9uKGZyb21Ob2RlLCAwLCB0b05vZGUsIHRvTm9kZS50ZXh0Q29udGVudC5sZW5ndGgpO1xufVxuXG5cbi8qKlxuICogU2V0cyB0aGUgY2FyZXQgcG9zaXRpb24gdG8gdGhlIHBvc2l0aW9uIGluIHRoZSBub2RlXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIERPTSBub2RlXG4gKiBAcGFyYW0ge051bWJlcn0gcG9zIGNhcmV0IHBvc2l0aW9uXG4gKi9cbmZ1bmN0aW9uIHNldENhcmV0UG9zaXRpb24obm9kZSwgcG9zKSB7XG4gICAgdmFyIGRvYyA9IG5vZGUub3duZXJEb2N1bWVudDtcbiAgICBpZiAoISBkb2MpIHJldHVybiBsb2dnZXIuZXJyb3IoJ3NldENhcmV0UG9zaXRpb246IGVsZW1lbnQgaGFzIG5vIGRvY3VtZW50Jyk7XG4gICAgdmFyIHJhbmdlID0gZG9jLmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQobm9kZSwgcG9zKTtcbiAgICB2YXIgd2luID0gZ2V0Tm9kZVdpbmRvdyhub2RlKVxuICAgICAgICAsIHNlbCA9IHdpbi5nZXRTZWxlY3Rpb24oKTtcbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcbn1cblxuLyoqXG4gKiBnZXQgdGhlIGRpcmVjdGlvbiBvZiBhIHNlbGVjdGlvblxuICpcbiAqIDEgZm9yd2FyZCwgLTEgYmFja3dhcmQsIDAgbm8gZGlyZWN0aW9uLCB1bmRlZmluZWQgb25lIG9mIHRoZSBub2RlIGlzIGRldGFjaGVkIG9yIGluIGEgZGlmZmVyZW50IGZyYW1lXG4gKlxuICogQHBhcmFtIHtzZWx9IGEgc2VsZWN0aW9uIG9iamVjdFxuICogQHJldHVybiB7LTF8MHwxfHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uRGlyZWN0aW9uKHNlbCl7XG4gICAgcmV0dXJuIF9nZXREaXJlY3Rpb24oc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQsIHNlbC5mb2N1c05vZGUsIHNlbC5mb2N1c09mZnNldCk7XG59XG5cbmZ1bmN0aW9uIF9nZXREaXJlY3Rpb24oZnJvbU5vZGUsIHN0YXJ0T2Zmc2V0LCB0b05vZGUsIGVuZE9mZnNldCl7XG4gICAgdmFyIGRvY1Bvc2l0aW9uID0gZnJvbU5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24odG9Ob2RlKTtcbiAgICBpZiAoZG9jUG9zaXRpb24gJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORyl7XG4gICAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICBlbHNlIGlmIChkb2NQb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fUFJFQ0VESU5HKXtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICBlbHNlIGlmIChmcm9tTm9kZSA9PSB0b05vZGUpe1xuICAgICAgICBpZiAoc3RhcnRPZmZzZXQgPCBlbmRPZmZzZXQpe1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhcnRPZmZzZXQgPiBlbmRPZmZzZXQpe1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogU2VsZWN0cyBhIHJhbmdlIGluIGEgZG9jdW1lbnRcbiAqXG4gKiBAcGFyYW0ge05vZGV9IGZyb21Ob2RlIERPTSBub2RlIHRvIHN0YXJ0IHNlbGVjdGlvbiBpblxuICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0T2Zmc2V0XG4gKiBAcGFyYW0ge05vZGV9IHRvTm9kZSBET00gbm9kZSB0byBlbmQgc2VsZWN0aW9uIGluXG4gKiBAcGFyYW0ge051bWJlcn0gZW5kT2Zmc2V0XG4gKi9cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbihmcm9tTm9kZSwgc3RhcnRPZmZzZXQsIHRvTm9kZSwgZW5kT2Zmc2V0KSB7XG4gICAgdmFyIGRvYyA9IGZyb21Ob2RlLm93bmVyRG9jdW1lbnQ7XG4gICAgaWYgKCEgZG9jKSByZXR1cm4gbG9nZ2VyKCdzZXRDYXJldFBvc2l0aW9uOiBlbGVtZW50IGhhcyBubyBkb2N1bWVudCcpO1xuICAgIHZhciBiYWNrd2FyZCA9IF9nZXREaXJlY3Rpb24oZnJvbU5vZGUsIHN0YXJ0T2Zmc2V0LCB0b05vZGUsIGVuZE9mZnNldCkgPT0gLTE7XG4gICAgdmFyIHJhbmdlID0gZG9jLmNyZWF0ZVJhbmdlKCk7XG4gICAgdmFyIGNvbnRhaW5lciwgb3JpZ2luYWxDb250ZW50RWRpdGFibGU7XG4gICAgLy8gZG9lcyBub3Qgd29yayBpbiBub24gY29udGVudEVkaXRhYmxlIGl0ZW1zXG5cbiAgICB2YXIgd2luID0gZ2V0Tm9kZVdpbmRvdyhmcm9tTm9kZSlcbiAgICAgICAgLCBzZWwgPSB3aW4uZ2V0U2VsZWN0aW9uKCk7XG5cblxuICAgIGlmIChiYWNrd2FyZCl7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0KHRvTm9kZSwgZW5kT2Zmc2V0KTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kKGZyb21Ob2RlLCBzdGFydE9mZnNldCk7XG4gICAgICAgIHJhbmdlLmNvbGxhcHNlKGZhbHNlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0KGZyb21Ob2RlLCBzdGFydE9mZnNldCk7XG4gICAgICAgIHJhbmdlLnNldEVuZCh0b05vZGUsIGVuZE9mZnNldCk7XG4gICAgfVxuXG4gICAgY29udGFpbmVyID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPT0gTm9kZS5FTEVNRU5UX05PREUgP1xuICAgICAgICByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lciA6XG4gICAgICAgIHJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyLnBhcmVudEVsZW1lbnQ7XG5cbiAgICBpZiAoIWNvbnRhaW5lci5pc0NvbnRlbnRFZGl0YWJsZSl7XG4gICAgICAgIG9yaWdpbmFsQ29udGVudEVkaXRhYmxlID0gY29udGFpbmVyLmNvbnRlbnRFZGl0YWJsZTsgLy8gZmFsc2Ugb3IgaW5oZXJpdFxuICAgICAgICBjb250YWluZXIuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG4gICAgfVxuXG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG5cbiAgICBpZiAoYmFja3dhcmQpe1xuICAgICAgICBzZWwuZXh0ZW5kKHRvTm9kZSwgZW5kT2Zmc2V0KTtcbiAgICB9XG5cbiAgICBpZiAob3JpZ2luYWxDb250ZW50RWRpdGFibGUpe1xuICAgICAgICAvLyByZXN0b3JpbmcgY29udGVudEVkaXRhYmxlXG4gICAgICAgIGNvbnRhaW5lci5jb250ZW50RWRpdGFibGUgPSBvcmlnaW5hbENvbnRlbnRFZGl0YWJsZTtcbiAgICB9XG59XG5cbi8qKlxuICogQ2xlYXJzIHNlbGVjdGlvbiBpbiBhIGdpdmVuIHdpbmRvd1xuICogQHBhcmFtIHtXaW5kb3d9IHdpblxuICovXG5mdW5jdGlvbiBjbGVhclNlbGVjdGlvbih3aW4pIHtcbiAgICB3aW4gPSB3aW4gfHwgd2luZG93O1xuICAgIHZhciBzZWwgPSB3aW4uZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xufVxuXG5cbi8qKlxuICogQ2FsY3VsYXRlcyBhbiBlbGVtZW50J3MgdG90YWwgdG9wIGFuZCBsZWZ0IG9mZnNldCBmcm9tIHRoZSBkb2N1bWVudCBlZGdlLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgdGhlIGVsZW1lbnQgZm9yIHdoaWNoIHBvc2l0aW9uIG5lZWRzIHRvIGJlIHJldHVybmVkXG4gKiBAcGFyYW0ge2luY2x1ZGVCb3JkZXJ9IGlmIGlzIHRvIGluY2x1ZGUgdGhlIGJvcmRlciB3aWR0aFxuICogQHJldHVybiB7T2JqZWN0fSB2ZWN0b3Igb2JqZWN0IHdpdGggcHJvcGVydGllcyB0b3BPZmZzZXQgYW5kIGxlZnRPZmZzZXRcbiAqL1xuZnVuY3Rpb24gZ2V0RWxlbWVudE9mZnNldChlbCwgaW5jbHVkZUJvcmRlcikge1xuICAgIHZhciB5UG9zLCB4UG9zO1xuXG4gICAgeVBvcyA9IGVsLm9mZnNldFRvcDtcbiAgICB4UG9zID0gZWwub2Zmc2V0TGVmdDtcbiAgICBlbCA9IGVsLm9mZnNldFBhcmVudDtcblxuICAgIHdoaWxlIChlbCkge1xuICAgICAgICB5UG9zICs9IGVsLm9mZnNldFRvcCArIGdldEJvcmRlcihlbCwgJ0hlaWdodCcsIGluY2x1ZGVCb3JkZXIpO1xuICAgICAgICB4UG9zICs9IGVsLm9mZnNldExlZnQgKyBnZXRCb3JkZXIoZWwsICdXaWR0aCcsIGluY2x1ZGVCb3JkZXIpO1xuICAgICAgICBlbCA9IGVsLm9mZnNldFBhcmVudDtcbiAgICB9XG5cbiAgICByZXR1cm4geyB0b3BPZmZzZXQ6IHlQb3MsIGxlZnRPZmZzZXQ6IHhQb3MgfTtcbn1cblxuXG5mdW5jdGlvbiBnZXRCb3JkZXIoZWwsIHR5cGUsIGluY2x1ZGVCb3JkZXIpIHtcbiAgICBpZiAoaW5jbHVkZUJvcmRlcikge1xuICAgICAgICB2YXIgc2lkZSA9ICh0eXBlID09ICdIZWlnaHQnKSA/ICd0b3AnIDogJ2xlZnQnLFxuICAgICAgICAgICAgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpLFxuICAgICAgICAgICAgc2lkZVZhbHVlID0gcGFyc2VJbnQoc3R5bGVzLmdldFByb3BlcnR5VmFsdWUoJ2JvcmRlci0nICsgc2lkZSArICctd2lkdGgnKSwgMTApO1xuXG4gICAgICAgIGlmIChzaWRlVmFsdWUpIHJldHVybiBzaWRlVmFsdWU7XG4gICAgfVxuICAgIHJldHVybiAwO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlcyBlbGVtZW50IGZyb20gdGhlIGRvY3VtZW50XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCB0aGUgZWxlbWVudCB0byBiZSByZW1vdmVkXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQoZWwpIHtcbiAgICB2YXIgcGFyZW50ID0gZWwucGFyZW50Tm9kZTtcbiAgICBpZiAocGFyZW50KXtcbiAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKGVsKTtcbiAgICAgICAgcGFyZW50Lm5vcm1hbGl6ZSgpO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IGNoaWxkIHRleHQgbm9kZSBvZiBhbiBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fE5vZGV9IG5vZGUgdGhlIG5vZGUgdG8gYmUgc2VhcmNoZWQsIGlmIHRoZSBub2RlIGlzIHRleHQgbm9kZSB3ZSByZXR1cm4gdGhlIG5vZGUuXG4gKiBAcmV0dXJuIHtUZXh0Tm9kZX1cbiAqL1xuZnVuY3Rpb24gZmlyc3RUZXh0Tm9kZShub2RlKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gTm9kZS5URVhUX05PREUpIHJldHVybiBub2RlO1xuICAgIHZhciB0cmVlV2Fsa2VyID0gY3JlYXRlVHJlZVdhbGtlcihub2RlLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gICAgcmV0dXJuIHRyZWVXYWxrZXIuZmlyc3RDaGlsZCgpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgbGFzdCBjaGlsZCB0ZXh0IG5vZGUgb2YgYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudHxOb2RlfSBub2RlIHRoZSBub2RlIHRvIGJlIHNlYXJjaGVkLCBpZiB0aGUgbm9kZSBpcyB0ZXh0IG5vZGUgd2UgcmV0dXJuIHRoZSBub2RlLlxuICogQHJldHVybiB7VGV4dE5vZGV9XG4gKi9cbmZ1bmN0aW9uIGxhc3RUZXh0Tm9kZShub2RlKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gTm9kZS5URVhUX05PREUpIHJldHVybiBub2RlO1xuICAgIHZhciB0cmVlV2Fsa2VyID0gY3JlYXRlVHJlZVdhbGtlcihub2RlLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gICAgcmV0dXJuIHRyZWVXYWxrZXIubGFzdENoaWxkKCk7XG59XG5cblxuLyoqXG4gKiBSZW1vdmVzIGVsZW1lbnQgZnJvbSB0aGUgZG9jdW1lbnQgcHV0dGluZyBpdHMgY2hpbGRyZW4gaW4gaXRzIHBsYWNlXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbCB0aGUgZWxlbWVudCB0byBiZSBcInVud3JhcHBlZFwiXG4gKi9cbmZ1bmN0aW9uIHVud3JhcEVsZW1lbnQoZWwpIHtcbiAgICB2YXIgcGFyZW50ID0gZWwucGFyZW50Tm9kZTtcblxuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgIC8vIG11c3QgYmUgY29waWVkIHRvIGF2b2lkIGl0ZXJhdGluZyBhIG11dGF0aW5nIGxpc3Qgb2YgY2hpbGROb2Rlc1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSBfLnNsaWNlKGVsLmNoaWxkTm9kZXMpO1xuICAgICAgICBjaGlsZHJlbi5mb3JFYWNoKGZyYWcuYXBwZW5kQ2hpbGQsIGZyYWcpO1xuICAgICAgICBwYXJlbnQucmVwbGFjZUNoaWxkKGZyYWcsIGVsKTtcbiAgICAgICAgcGFyZW50Lm5vcm1hbGl6ZSgpO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIFdyYXBzIGFuIGVsZW1lbnQgaW4gYW5vdGhlciBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gd3JhcEludG9FbFxuICogQHBhcmFtICB7RWxlbWVudH0gZWxcbiAqL1xuZnVuY3Rpb24gd3JhcEluRWxlbWVudCh3cmFwSW50b0VsLCBlbCkge1xuICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xuXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHdyYXBJbnRvRWwsIGVsKTtcbiAgICAgICAgd3JhcEludG9FbC5hcHBlbmRDaGlsZChlbCk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogVHJpbXMgYSB0ZXh0IG5vZGUgb2YgdHJhaWxpbmcgc3BhY2VzLCBhbmQgcmV0dXJucyB0cnVlIGlmIGEgdHJpbSB3YXMgcGVyZm9ybWVkLlxuICpcbiAqIEBwYXJhbSAge1RleHROb2RlfSBub2RlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiB0cmltTm9kZVJpZ2h0KG5vZGUpIHtcbiAgICByZXR1cm4gX3RyaW1Ob2RlKG5vZGUsICd0cmltUmlnaHQnKTtcbn1cblxuXG4vKipcbiAqIFRyaW1zIGEgdGV4dCBub2RlIG9mIGxlYWRpbmcgc3BhY2VzLCBhbmQgcmV0dXJucyB0cnVlIGlmIGEgdHJpbSB3YXMgcGVyZm9ybWVkLlxuICpcbiAqIEBwYXJhbSAge1RleHROb2RlfSBub2RlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiB0cmltTm9kZUxlZnQobm9kZSkge1xuICAgIHJldHVybiBfdHJpbU5vZGUobm9kZSwgJ3RyaW1MZWZ0Jyk7XG59XG5cblxuZnVuY3Rpb24gX3RyaW1Ob2RlKG5vZGUsIG1ldGhvZE5hbWUpIHtcbiAgICB2YXIgbGVuID0gbm9kZS5sZW5ndGg7XG4gICAgbm9kZS50ZXh0Q29udGVudCA9IG5vZGUudGV4dENvbnRlbnRbbWV0aG9kTmFtZV0oKTtcbiAgICByZXR1cm4gbGVuICE9PSBub2RlLmxlbmd0aDtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHJlZmVyZW5jZSB0byBjb21wb25lbnQgZnJvbSBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gZWxcbiAqL1xuZnVuY3Rpb24gZGV0YWNoQ29tcG9uZW50KGVsKSB7XG4gICAgZGVsZXRlIGVsW2NvbmZpZy5jb21wb25lbnRSZWZdO1xufVxuXG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBjb250ZW50IG9mIGEgaHRtbCBzdHJpbmdcbiAqIEBwYXJhbSAge1N0cmluZ30gc3RyIEFueSBzdHJpbmdcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgc3RyaW5nIGNsZWFuZWQgb2YgYW55IGh0bWwgY29udGVudC5cbiAqL1xuZnVuY3Rpb24gc3RyaXBIdG1sKHN0cikge1xuICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdESVYnKTtcbiAgICBkaXYuaW5uZXJIVE1MID0gc3RyO1xuICAgIHJldHVybiBkaXYudGV4dENvbnRlbnQgfHwgJyc7XG59XG5cblxuLyoqXG4gKiBDb252ZW5pZW5jZSB3cmFwcGVyIGZvciBuYXRpdmUgVHJlZVdhbGtlciB0aGF0IGF1dG9tYXRpY2FsbHkgd2Fsa3MgdGhlIHRyZWUgYW5kIGNhbGxzIGFuIGl0ZXJhdG9yIGZ1bmN0aW9uLlxuICogVGhpcyB3aWxsIG5vdCBpdGVyYXRlIHRoZSByb290IGVsZW1lbnQuXG4gKiBAcGFyYW0gIHtIVE1MRWxlbWVudH0gcm9vdCBUaGUgY29udGFpbmluZyByb290IGVsZW1lbnQgdG8gYmUgd2Fsa2VkLiBXaWxsIG5vdCBiZSBpdGVyYXRlZC5cbiAqIEBwYXJhbSAge05vZGVGaWxlcn0gZmlsdGVyIEEgTm9kZUZpbHRlciBjb25zdGFudCwgc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL2RvY3MvV2ViL0FQSS9UcmVlV2Fsa2VyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gaXRlcmF0b3IgQSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgb24gZWFjaCBub2RlLiBSZXR1cm5pbmcgJ2ZhbHNlJyB3aWxsIGJyZWFrLlxuICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0IEFuIG9wdGlvbmFsIGNvbnRleHQgdG8gcGFzc2VkLCBkZWZhdWx0cyB0byByb290LlxuICovXG5mdW5jdGlvbiB3YWxrVHJlZShyb290LCBmaWx0ZXIsIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIHR3ID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihyb290LCBmaWx0ZXIpO1xuICAgIHdoaWxlKHR3Lm5leHROb2RlKCkpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCB8fCByb290LCB0dy5jdXJyZW50Tm9kZSk7XG4gICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKSBicmVhaztcbiAgICB9XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGFycmF5IG9mIGNoaWxkIGluZGV4ZXMgb2YgZWxlbWVudCBwYXRoIGluc2lkZSByb290IGVsZW1lbnQgaW4gRE9NIHRyZWUgdXNpbmcgYnJlYWR0aCBmaXJzdCB0cmVlIHRyYXZlcnNhbC5cbiAqIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZSBlbGVtZW50IGlzIG5vdCBpbnNpZGUgcm9vdCBlbGVtZW50LCAwIGlmIHRoZSByb290IGVsZW1lbnQgaXRzZWxmIGlzIHBhc3NlZC5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSByb290RWwgZWxlbWVudCB0byBzZWFyY2hcbiAqIEBwYXJhbSAge0VsZW1lbnR9IGVsIGVsZW1lbnQgdG8gZmluZCB0aGUgaW5kZXggb2ZcbiAqIEByZXR1cm4ge0FycmF5W051bWJlcl19XG4gKi9cbmZ1bmN0aW9uIHRyZWVQYXRoT2Yocm9vdEVsLCBlbCkge1xuICAgIGlmICghIChyb290RWwgJiYgcm9vdEVsLmNvbnRhaW5zKGVsKSkpIHJldHVybjtcblxuICAgIHZhciB0cmVlUGF0aCA9IFtdXG4gICAgICAgICwgbm9kZSA9IHJvb3RFbDtcblxuICAgIHdoaWxlIChub2RlICE9IGVsKSB7XG4gICAgICAgIHZhciBub2RlSW5kZXggPSBfLmZpbmRJbmRleChub2RlLmNoaWxkTm9kZXMsIGNvbnRhaW5zRWwpO1xuICAgICAgICB0cmVlUGF0aC5wdXNoKG5vZGVJbmRleCk7XG4gICAgICAgIG5vZGUgPSBub2RlLmNoaWxkTm9kZXNbbm9kZUluZGV4XTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJlZVBhdGg7XG5cbiAgICBmdW5jdGlvbiBjb250YWluc0VsKGNoaWxkKSB7XG4gICAgICAgIHJldHVybiBjaGlsZC5jb250YWlucyhlbCk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJucyBlbGVtZW50IGF0IGdpdmVuIHRyZWUgcGF0aFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gcm9vdEVsXG4gKiBAcGFyYW0ge0FycmF5W051bWJlcl19IHRyZWVQYXRoXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG5lYXJlc3QgcmV0dXJuIG5lYXJlc3QgcG9zc2libGUgbm9kZSBpZiBleGFjdCBub2RlIGRvZXMgbm90IGV4aXN0XG4gKiBAcmV0dXJuIHtOb2RlfVxuICovXG5mdW5jdGlvbiBnZXROb2RlQXRUcmVlUGF0aChyb290RWwsIHRyZWVQYXRoLCBuZWFyZXN0KSB7XG4gICAgaWYgKCF0cmVlUGF0aCkgcmV0dXJuO1xuXG4gICAgdmFyIGxlbiA9IHRyZWVQYXRoLmxlbmd0aDtcbiAgICBpZiAobGVuID09PSAwKSByZXR1cm4gcm9vdEVsO1xuXG4gICAgdmFyIG5vZGUgPSByb290RWw7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IG5vZGUuY2hpbGROb2RlcztcbiAgICAgICAgaWYgKCEgY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGlmICghIG5lYXJlc3QpIG5vZGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2hpbGRJbmRleCA9IHRyZWVQYXRoW2ldXG4gICAgICAgICAgICAsIGNoaWxkID0gY2hpbGRyZW5bY2hpbGRJbmRleF07XG4gICAgICAgIGlmICghIGNoaWxkKSB7XG4gICAgICAgICAgICBub2RlID0gbmVhcmVzdFxuICAgICAgICAgICAgICAgICAgICA/IGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZSA9IGNoaWxkO1xuICAgIH1cblxuICAgIHJldHVybiBub2RlO1xufVxuXG5cbi8qKlxuICogSW5zZXJ0cyBhbiBlbGVtZW50IGluc2lkZSByb290IGF0IGEgZ2l2ZW4gcGF0aCBpbiB0cmVlICh0aGF0IGhhcyB0aGUgc2FtZSBtZWFuaW5nIGFzIHRoZSBpbmRleCByZXR1cm5lZCBieSBgdHJlZVBhdGhPZmAgZnVuY3Rpb24pLiBJZiBlbGVtZW50IGlzIGFscmVhZHkgaW4gdGhlIHJvb3QncyB0cmVlLCBpdCB3aWxsIGJlIHJlbW92ZWQgZmlyc3QgYW5kIHRoZW4gbW92ZWQgdG8gdGhlIHBhc3NlZCB0cmVlSW5kZXhcbiAqIEluc2VydGlvbiBhdCBpbmRleCAwIGlzIG5vdCBwb3NzaWJsZSBhbmQgd2lsbCByZXR1cm4gdW5kZWZpbmVkIGFzIGl0IHdvdWxkIG1lYW4gcmVwbGFjaW5nIHRoZSByb290IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSByb290RWwgZWxlbWVudCBpbnRvIHdoaWNoIHRvIGluc2VydFxuICogQHBhcmFtIHtOdW1iZXJ9IHRyZWVJbmRleCBpbmRleCBpbiBET00gdHJlZSBpbnNpZGUgcm9vdCBlbGVtZW50IChzZWUgdHJlZVBhdGhPZilcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgZWxlbWVudCB0byBiZSBpbnNlcnRlZFxuICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiB3YXMgc3VjY2Vzc2Z1bGx5IGluc2VydGVkXG4gKi9cbmZ1bmN0aW9uIGluc2VydEF0VHJlZVBhdGgocm9vdEVsLCB0cmVlUGF0aCwgZWwsIG5lYXJlc3QpIHtcbiAgICB2YXIgdG9Ob3JtYWxpemUgPSBlbC5ub2RlVHlwZSA9PSBOb2RlLlRFWFRfTk9ERTtcbiAgICBpZiAocm9vdEVsLmNvbnRhaW5zKGVsKSlcbiAgICAgICAgcmVtb3ZlRWxlbWVudChlbCk7IC8vIGNhbid0IHVzZSByZW1vdmVDaGlsZCBhcyByb290RWwgaGVyZSBpcyBub3QgYW4gaW1tZWRpYXRlIHBhcmVudFxuXG4gICAgaWYgKHRyZWVQYXRoLmxlbmd0aCA9PSAwKSByZXR1cm47XG5cbiAgICB2YXIgcGFyZW50ID0gZ2V0Tm9kZUF0VHJlZVBhdGgocm9vdEVsLCB0cmVlUGF0aC5zbGljZSgwLCAtMSksIG5lYXJlc3QpXG4gICAgICAgICwgY2hpbGRyZW4gPSBwYXJlbnQuY2hpbGROb2RlcztcblxuICAgIGlmICghIGNoaWxkcmVuKSB7XG4gICAgICAgIGlmIChuZWFyZXN0KSB7XG4gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIGNoaWxkcmVuID0gcGFyZW50LmNoaWxkTm9kZXM7XG4gICAgICAgIH0gZWxzZSByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkSW5kZXggPSB0cmVlUGF0aFt0cmVlUGF0aC5sZW5ndGggLSAxXVxuICAgICAgICAsIGNoaWxkID0gY2hpbGRyZW5bY2hpbGRJbmRleF07XG5cbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShlbCwgY2hpbGQpO1xuICAgICAgICBpZiAodG9Ob3JtYWxpemUpIHBhcmVudC5ub3JtYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmIChjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgKGNoaWxkSW5kZXggPT09IDAgfHwgbmVhcmVzdCkpIHtcbiAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgaWYgKHRvTm9ybWFsaXplKSBwYXJlbnQubm9ybWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNoaWxkID0gY2hpbGRyZW5bY2hpbGRJbmRleCAtIDFdO1xuICAgICAgICBpZiAoY2hpbGQgfHwgbmVhcmVzdCkge1xuICAgICAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgICAgIGlmICh0b05vcm1hbGl6ZSkgcGFyZW50Lm5vcm1hbGl6ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZmlyc3QgdHJlZSBwYXRoIHBvaW50cyB0byBhIG5vZGUgd2hpY2ggaXMgYmVmb3JlIHRoZSBvdGhlciBpbiB0aGUgZG9jdW1lbnQgb3JkZXIuXG4gKiBAcGFyYW0gIHtBcnJheX0gIHBhdGgxICAgQSB0cmVlcGF0aCBhcnJheVxuICogQHBhcmFtICB7QXJyYXl9ICBwYXRoMiAgIEEgdHJlZXBhdGggYXJyYXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzVHJlZVBhdGhCZWZvcmUocGF0aDEsIHBhdGgyKSB7XG4gICAgdmFyIGkgPSAwXG4gICAgICAgICwgaXNCZWZvcmU7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHBhdGgxKSAmJiBBcnJheS5pc0FycmF5KHBhdGgyKSlcbiAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcignaXNUcmVlUGF0aEJlZm9yZTogT25lIG9yIGJvdGggcGF0aHMgYXJlIG5vdCB2YWxpZCB0cmVlcGF0aCBhcnJheXMuJyk7XG5cbiAgICBmb3IgKGk7IGkgPCBwYXRoMS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aDFbaV0gPCBwYXRoMltpXSkge1xuICAgICAgICAgICAgaXNCZWZvcmUgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSBpZiAocGF0aDFbaV0gPiBwYXRoMltpXSkge1xuICAgICAgICAgICAgaXNCZWZvcmUgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpc0JlZm9yZSA9PSAndW5kZWZpbmVkJylcbiAgICAgICAgaWYgKHBhdGgxLmxlbmd0aCA8IHBhdGgyLmxlbmd0aClcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdpc1RyZWVQYXRoQmVmb3JlOiBPbmUgbm9kZSBpcyBpbnNpZGUgYW5vdGhlcicpO1xuXG4gICAgcmV0dXJuIGlzQmVmb3JlIHx8IGZhbHNlO1xufVxuXG5cbi8qKlxuICogQ29udmVydHMgbm9uIGxhdGluIGNoYXJhY3RlcnMgdG8gSFRNTCBlbnRpdHkgY29kZXMuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHN0ciB0aGUgc3RyaW5nIHRvIGNvbnZlcnRcbiAqIEByZXR1cm4ge1N0cmluZ30gICAgIHRoZSBzdHJpbmcgd2l0aCBodG1sIGVudGl0aWVzXG4gKi9cbmZ1bmN0aW9uIGh0bWxFbnRpdGllcyhzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL1tcXHUwMEEwLVxcdTk5OTk5PD5cXCZdL2dpbSwgZnVuY3Rpb24oaSkge1xuICAgICAgICByZXR1cm4gJyYjJytpLmNoYXJDb2RlQXQoMCkrJzsnO1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZVRyZWVXYWxrZXIoZWwsIHdoYXRUb1Nob3cpIHtcbiAgICB3aGF0VG9TaG93ID0gd2hhdFRvU2hvdyB8fCAoTm9kZUZpbHRlci5TSE9XX1RFWFQgfCBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCk7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoZWwsIHdoYXRUb1Nob3cpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIHRoZSB3aW5kb3cgdGhlIG5vZGUgaXMgaW5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqIEByZXR1cm4ge1dpbmRvd31cbiAqL1xuZnVuY3Rpb24gZ2V0Tm9kZVdpbmRvdyhub2RlKSB7XG4gICAgdmFyIGRvYyA9IG5vZGUub3duZXJEb2N1bWVudDtcbiAgICByZXR1cm4gZG9jICYmIChkb2MuZGVmYXVsdFZpZXcgfHwgZG9jLnBhcmVudFdpbmRvdyk7XG59XG5cblxuXG4vKipcbiAqIGRvIHNvbWV0aGluZyBmb3IgZWFjaCBub2RlcyBjb250YWluZWQgaW4gYSByYW5nZVxuICpcbiAqIEBwYXJhbSB7cmFuZ2V9IGEgcmFuZ2VcbiAqIEBwYXJhbSB7Y2J9IGEgZnVuY3Rpb24gdGFraW5nIGEgbm9kZSBhcyBhcmd1bWVudFxuXG4gKi9cbmZ1bmN0aW9uIGZvckVhY2hOb2Rlc0luUmFuZ2UocmFuZ2UsIGNiKXtcbiAgICB2YXIgcmFuZ2VDb250YWluZXIgPSByYW5nZS5jb21tb25BbmNlc3RvckNvbnRhaW5lclxuICAgICAgICAsIGRvYyA9IHJhbmdlQ29udGFpbmVyLm93bmVyRG9jdW1lbnQ7XG5cbiAgICBmdW5jdGlvbiBpc05vZGVJbnNpZGVSYW5nZShub2RlKXtcbiAgICAgICAgdmFyIG5vZGVSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgIHZhciBpc0luc2lkZSA9IGZhbHNlO1xuICAgICAgICBub2RlUmFuZ2Uuc2VsZWN0Tm9kZShub2RlKTtcblxuICAgICAgICBpZiAobm9kZVJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyh3aW5kb3cuUmFuZ2UuU1RBUlRfVE9fU1RBUlQsIHJhbmdlKSAhPSAtMVxuICAgICAgICAgICAgJiYgbm9kZVJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyh3aW5kb3cuUmFuZ2UuRU5EX1RPX0VORCwgcmFuZ2UpICE9IDEpe1xuICAgICAgICAgICAgaXNJbnNpZGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIG5vZGVSYW5nZS5kZXRhY2goKTtcbiAgICAgICAgcmV0dXJuIGlzSW5zaWRlO1xuICAgIH1cblxuICAgIHZhciB0cmVlV2Fsa2VyID0gZG9jLmNyZWF0ZVRyZWVXYWxrZXIocmFuZ2VDb250YWluZXIsXG4gICAgICAgICAgICBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCB8IE5vZGVGaWx0ZXIuU0hPV19URVhUKTtcblxuICAgIHZhciBjdXJyZW50Tm9kZTtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgPSB0cmVlV2Fsa2VyLm5leHROb2RlKCkpeyAvLyBzaG91bGQgYmUgYXNzaWdubWVudFxuICAgICAgICBpZiAoaXNOb2RlSW5zaWRlUmFuZ2UoY3VycmVudE5vZGUpKXtcbiAgICAgICAgICAgIGNiKGN1cnJlbnROb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBnZXQgYWxsIGNvbXBvbmVudHMgY29udGFpbmVkIGluIGEgcmFuZ2VcbiAqXG4gKiBAcGFyYW0ge3JhbmdlfSBhIERPTSByYW5nZS5cbiAqL1xuZnVuY3Rpb24gZ2V0Q29tcG9uZW50c0Zyb21SYW5nZShyYW5nZSkge1xuICAgIHZhciB3aW4gPSBnZXROb2RlV2luZG93KHJhbmdlLnN0YXJ0Q29udGFpbmVyKVxuICAgICAgICAsIENvbXBvbmVudCA9IHdpbi5taWxvLkNvbXBvbmVudDtcblxuICAgIHZhciBjb21wb25lbnRzID0gW107XG4gICAgZm9yRWFjaE5vZGVzSW5SYW5nZShyYW5nZSwgZnVuY3Rpb24gKG5vZGUpe1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAgICAgdmFyIGNvbXAgPSBDb21wb25lbnQuZ2V0Q29tcG9uZW50KG5vZGUpO1xuICAgICAgICAgICAgaWYgKGNvbXApXG4gICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKGNvbXApO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY29tcG9uZW50cztcbn1cblxuLyoqXG4gKiBkZWxldGUgYSByYW5nZVxuICpcbiAqIEBwYXJhbSB7cmFuZ2V9IGRlbGV0ZSBhIERPTSByYW5nZSBhbmQgYWxsIHRoZSBjb21wb25lbnRzIGluc2lkZVxuICovXG5mdW5jdGlvbiBkZWxldGVSYW5nZVdpdGhDb21wb25lbnRzKHJhbmdlKSB7XG4gICAgdmFyIGNvbXBvbmVudHMgPSBnZXRDb21wb25lbnRzRnJvbVJhbmdlKHJhbmdlKTtcblxuICAgIGNvbXBvbmVudHMuZm9yRWFjaChmdW5jdGlvbihjb21wKSB7XG4gICAgICAgIGNvbXAuZGVzdHJveSh0cnVlKTtcbiAgICB9KTtcblxuICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG59XG5cbi8qKlxuICogY2hlY2sgaWYgdHdvIHJhbmdlcyBhcmUgZXF1aXZhbGVudFxuICpcbiAqIEBwYXJhbSB7cmFuZ2V9IHJhbmdlMVxuICogQHBhcmFtIHtyYW5nZX0gcmFuZ2UyXG4gKiBAcmV0dXJuIHtCb29sZWFufSBhcmUgdGhlIHR3byByYW5nZXMgZXF1aXZhbGVudFxuICovXG5mdW5jdGlvbiBhcmVSYW5nZXNFcXVhbChyYW5nZTEsIHJhbmdlMil7XG4gICAgcmV0dXJuIHJhbmdlMS5jb21wYXJlQm91bmRhcnlQb2ludHMod2luZG93LlJhbmdlLlNUQVJUX1RPX1NUQVJULCByYW5nZTIpID09IDAgJiYgcmFuZ2UxLmNvbXBhcmVCb3VuZGFyeVBvaW50cyh3aW5kb3cuUmFuZ2UuRU5EX1RPX0VORCwgcmFuZ2UyKSA9PSAwO1xufVxuXG5cbi8qKlxuICogQWRkcyBhIHNpbmdsZSBwaXhlbCBkaXYgdG8gdGhlIGJvZHkgYXQgYSBnaXZlbiB4IGFuZCB5IHBvc2l0aW9uLiBVc2VmdWwgZm9yIGRlYnVnZ2luZyBwb3NpdGlvbiBzcGVjaWZpYyBjb2RlLlxuICogQHBhcmFtIHtOdW1iZXJ9IHhcbiAqIEBwYXJhbSB7TnVtYmVyfSB5XG4gKi9cbmZ1bmN0aW9uIGFkZERlYnVnUG9pbnQoeCwgeSkge1xuICAgIHZhciBkYkVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGJFbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJ3dpZHRoOiAxcHg7IGhlaWdodDogMXB4OyBwb3NpdGlvbjpmaXhlZDsgbGVmdDonK3grJ3B4OyB0b3A6Jyt5KydweDsgYmFja2dyb3VuZC1jb2xvcjpyZWQ7IHotaW5kZXg6IDEwMCcpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkYkVsKTt9LCAyMDApO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi9jaGVjaycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gRE9NTGlzdGVuZXJzO1xuXG5cbmZ1bmN0aW9uIERPTUxpc3RlbmVycygpIHtcbiAgICB0aGlzLmxpc3RlbmVycyA9IFtdO1xufVxuXG5cbl8uZXh0ZW5kUHJvdG8oRE9NTGlzdGVuZXJzLCB7XG4gICAgYWRkOiBET01MaXN0ZW5lcnMkYWRkLFxuICAgIHJlbW92ZTogRE9NTGlzdGVuZXJzJHJlbW92ZSxcbiAgICByZW1vdmVBbGw6IERPTUxpc3RlbmVycyRyZW1vdmVBbGxcbn0pO1xuXG5cbmZ1bmN0aW9uIERPTUxpc3RlbmVycyRhZGQodGFyZ2V0LCBldmVudFR5cGUsIGhhbmRsZXIpIHtcbiAgICB0aGlzLmxpc3RlbmVycy5wdXNoKHtcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICAgIGV2ZW50VHlwZTogZXZlbnRUeXBlLFxuICAgICAgICBoYW5kbGVyOiBoYW5kbGVyXG4gICAgfSk7XG4gICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBoYW5kbGVyKTtcbn1cblxuXG5mdW5jdGlvbiBET01MaXN0ZW5lcnMkcmVtb3ZlKHRhcmdldCwgZXZlbnRUeXBlLCBoYW5kbGVyKSB7XG4gICAgdmFyIGxpc3RlbmVyID0ge1xuICAgICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgICAgZXZlbnRUeXBlOiBldmVudFR5cGUsXG4gICAgICAgIGhhbmRsZXI6IGhhbmRsZXJcbiAgICB9O1xuICAgIHZhciBpZHggPSBfLmZpbmRJbmRleCh0aGlzLmxpc3RlbmVycywgXy5wYXJ0aWFsKF8uaXNFcXVhbCwgbGlzdGVuZXIpKTtcblxuICAgIGlmIChpZHggPiAtMSkge1xuICAgICAgICB0aGlzLmxpc3RlbmVycy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgX3JlbW92ZUxpc3RlbmVyKGxpc3RlbmVyKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gRE9NTGlzdGVuZXJzJHJlbW92ZUFsbCgpIHtcbiAgICB0aGlzLmxpc3RlbmVycy5mb3JFYWNoKF9yZW1vdmVMaXN0ZW5lcik7XG4gICAgdGhpcy5saXN0ZW5lcnMgPSBbXTtcbn1cblxuXG5mdW5jdGlvbiBfcmVtb3ZlTGlzdGVuZXIobCkge1xuICAgIGwudGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIobC5ldmVudFR5cGUsIGwuaGFuZGxlcik7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbVJlYWR5O1xuXG5cbnZhciBkb21SZWFkeUZ1bmNzID0gW11cbiAgICAsIGRvbVJlYWR5U3Vic2NyaWJlZCA9IGZhbHNlO1xuXG5cbmZ1bmN0aW9uIGRvbVJlYWR5KGZ1bmMpIHsgLy8gLCBhcmd1bWVudHNcbiAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICAgICAgLCBhcmdzID0gXy5zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIGlmIChpc1JlYWR5LmNhbGwodGhpcykpXG4gICAgICAgIGNhbGxGdW5jKCk7XG4gICAgZWxzZSB7XG4gICAgICAgIGlmICghZG9tUmVhZHlTdWJzY3JpYmVkKSB7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWFkeXN0YXRlY2hhbmdlJywgb25Eb21SZWFkeSk7XG4gICAgICAgICAgICBkb21SZWFkeVN1YnNjcmliZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGRvbVJlYWR5RnVuY3MucHVzaChjYWxsRnVuYyk7IC8vIGNsb3N1cmUgaXMgYWRkZWQsIHNvIGV2ZXJ5IHRpbWUgZGlmZmVyZW50IGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FsbEZ1bmMoKSB7XG4gICAgICAgIGZ1bmMuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIG9uRG9tUmVhZHkoKSB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVhZHlzdGF0ZWNoYW5nZScsIG9uRG9tUmVhZHkpO1xuICAgIGRvbVJlYWR5RnVuY3MuZm9yRWFjaChmdW5jdGlvbihmdW5jKSB7IGZ1bmMoKTsgfSk7XG59XG5cblxuXy5leHRlbmQoZG9tUmVhZHksIHtcbiAgICBpc1JlYWR5OiBpc1JlYWR5XG59KTtcblxuXG5mdW5jdGlvbiBpc1JlYWR5KCkge1xuICAgIHZhciByZWFkeVN0YXRlID0gZG9jdW1lbnQucmVhZHlTdGF0ZTtcbiAgICByZXR1cm4gcmVhZHlTdGF0ZSA9PSAnbG9hZGluZycgPyBmYWxzZSA6IHJlYWR5U3RhdGU7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBDb21wb25lbnQgPSByZXF1aXJlKCcuLi9jb21wb25lbnRzL2NfY2xhc3MnKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJylcbiAgICAsIGRyYWdEcm9wQ29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJykuZHJhZ0Ryb3BcbiAgICAsIGNvbXBvbmVudE1ldGFSZWdleCA9IGRyYWdEcm9wQ29uZmlnLmRhdGFUeXBlcy5jb21wb25lbnRNZXRhUmVnZXhcbiAgICAsIGpzb25QYXJzZSA9IHJlcXVpcmUoJy4vanNvbl9wYXJzZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGJhc2UzMiA9IHJlcXVpcmUoJ2Jhc2UzMicpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gRHJhZ0Ryb3A7XG5cblxuLyoqXG4gKiBXcmFwcGVyIGZvciBldmVudC5kYXRhVHJhbnNmZXIgb2YgZHJhZy1kcm9wIEhUTUwgQVBJXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2V2ZW50fSBET00gZXZlbnRcbiAqIEByZXR1cm4ge0RyYWdEcm9wfVxuICovXG5mdW5jdGlvbiBEcmFnRHJvcChldmVudCkge1xuICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICB0aGlzLmRhdGFUcmFuc2ZlciA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICB0aGlzLnR5cGVzID0gZXZlbnQuZGF0YVRyYW5zZmVyLnR5cGVzO1xufVxuXG4vKipcbiAqIFVzYWdlOlxuICogdmFyIHRlc3REVCA9IG5ldyBEcmFnRHJvcChldmVudCk7XG4gKiB0ZXN0RFQuc2V0Q29tcG9uZW50TWV0YShuZXdDb21wb25lbnQsIHt0ZXN0OiAndGVzdCcsIHRlc3QyOiAndGVzdDInfSk7XG4gKiB0ZXN0RFQuZ2V0Q29tcG9uZW50TWV0YSgpO1xuICovXG5cbl8uZXh0ZW5kKERyYWdEcm9wLCB7XG4gICAgY29tcG9uZW50RGF0YVR5cGU6IERyYWdEcm9wJCRjb21wb25lbnREYXRhVHlwZVxufSk7XG5cbl8uZXh0ZW5kUHJvdG8oRHJhZ0Ryb3AsIHtcbiAgICBpc0NvbXBvbmVudDogRHJhZ0Ryb3AkaXNDb21wb25lbnQsXG4gICAgZ2V0Q29tcG9uZW50U3RhdGU6IERyYWdEcm9wJGdldENvbXBvbmVudFN0YXRlLFxuICAgIHNldENvbXBvbmVudFN0YXRlOiBEcmFnRHJvcCRzZXRDb21wb25lbnRTdGF0ZSxcbiAgICBnZXRDb21wb25lbnRNZXRhOiBEcmFnRHJvcCRnZXRDb21wb25lbnRNZXRhLFxuICAgIHNldENvbXBvbmVudE1ldGE6IERyYWdEcm9wJHNldENvbXBvbmVudE1ldGEsXG4gICAgZ2V0QWxsb3dlZEVmZmVjdHM6IERyYWdEcm9wJGdldEFsbG93ZWRFZmZlY3RzLFxuICAgIHNldEFsbG93ZWRFZmZlY3RzOiBEcmFnRHJvcCRzZXRBbGxvd2VkRWZmZWN0cyxcbiAgICBnZXREcm9wRWZmZWN0OiBEcmFnRHJvcCRnZXREcm9wRWZmZWN0LFxuICAgIHNldERyb3BFZmZlY3Q6IERyYWdEcm9wJHNldERyb3BFZmZlY3QsXG4gICAgaXNFZmZlY3RBbGxvd2VkOiBEcmFnRHJvcCRpc0VmZmVjdEFsbG93ZWQsXG4gICAgZ2V0RGF0YTogRHJhZ0Ryb3AkZ2V0RGF0YSxcbiAgICBzZXREYXRhOiBEcmFnRHJvcCRzZXREYXRhLFxuICAgIGNsZWFyRGF0YTogRHJhZ0Ryb3AkY2xlYXJEYXRhXG59KTtcblxuXG5mdW5jdGlvbiBEcmFnRHJvcCQkY29tcG9uZW50RGF0YVR5cGUoKSB7XG4gICAgcmV0dXJuIGRyYWdEcm9wQ29uZmlnLmRhdGFUeXBlcy5jb21wb25lbnQ7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3AkaXNDb21wb25lbnQoKSB7XG4gICAgcmV0dXJuIF8uaW5kZXhPZih0aGlzLnR5cGVzLCBEcmFnRHJvcC5jb21wb25lbnREYXRhVHlwZSgpKSA+PSAwO1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJGdldENvbXBvbmVudFN0YXRlKCkge1xuICAgIHZhciBkYXRhVHlwZSA9IERyYWdEcm9wLmNvbXBvbmVudERhdGFUeXBlKClcbiAgICAgICAgLCBzdGF0ZVN0ciA9IHRoaXMuZGF0YVRyYW5zZmVyLmdldERhdGEoZGF0YVR5cGUpXG4gICAgICAgICwgc3RhdGUgPSBqc29uUGFyc2Uoc3RhdGVTdHIpO1xuXG4gICAgcmV0dXJuIHN0YXRlO1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJHNldENvbXBvbmVudFN0YXRlKGNvbXBvbmVudCwgc3RhdGVTdHIpe1xuICAgIGlmICghIHN0YXRlU3RyKSB7XG4gICAgICAgIHZhciBzdGF0ZSA9IGNvbXBvbmVudC5nZXRUcmFuc2ZlclN0YXRlKHsgcmVxdWVzdGVkQnk6ICdkcmFnJyB9KTtcbiAgICAgICAgc3RhdGVTdHIgPSBKU09OLnN0cmluZ2lmeShzdGF0ZSk7XG4gICAgfVxuICAgIHZhciBkYXRhVHlwZSA9IERyYWdEcm9wLmNvbXBvbmVudERhdGFUeXBlKCk7XG5cbiAgICBzdGF0ZVN0ciAmJiB0aGlzLmRhdGFUcmFuc2Zlci5zZXREYXRhKGRhdGFUeXBlLCBzdGF0ZVN0cik7XG4gICAgdGhpcy5kYXRhVHJhbnNmZXIuc2V0RGF0YSgndGV4dC9odG1sJywgY29tcG9uZW50LmVsLm91dGVySFRNTCk7XG4gICAgcmV0dXJuIHN0YXRlU3RyO1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJHNldENvbXBvbmVudE1ldGEoY29tcG9uZW50LCBwYXJhbXMsIGRhdGEpIHtcbiAgICB2YXIgbWV0YSA9IF9jb21wb25lbnRNZXRhKGNvbXBvbmVudCk7XG5cbiAgICB2YXIgcGFyYW1zU3RyID0gXy50b1F1ZXJ5U3RyaW5nKHBhcmFtcyk7XG4gICAgdmFyIGRhdGFUeXBlID0gZHJhZ0Ryb3BDb25maWcuZGF0YVR5cGVzLmNvbXBvbmVudE1ldGFUZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgnJWNsYXNzJywgX2VuY29kZShtZXRhLmNvbXBDbGFzcyB8fCAnJykpXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCclbmFtZScsIF9lbmNvZGUobWV0YS5jb21wTmFtZSB8fCAnJykpXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCclcGFyYW1zJywgX2VuY29kZShwYXJhbXNTdHIgfHwgJycpKTtcblxuICAgIGlmIChkYXRhICYmIHR5cGVvZiBkYXRhID09ICdvYmplY3QnKSBkYXRhID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG5cbiAgICB0aGlzLmRhdGFUcmFuc2Zlci5zZXREYXRhKGRhdGFUeXBlLCBkYXRhIHx8ICcnKTtcblxuICAgIHJldHVybiBkYXRhVHlwZTtcbn1cblxuXG5mdW5jdGlvbiBfZW5jb2RlKHN0cikge1xuICAgIHJldHVybiBiYXNlMzIuZW5jb2RlKHN0cikudG9Mb3dlckNhc2UoKTtcbn1cblxuXG5mdW5jdGlvbiBfY29tcG9uZW50TWV0YShjb21wb25lbnQpIHtcbiAgICByZXR1cm4gY29tcG9uZW50LnRyYW5zZmVyXG4gICAgICAgICAgICA/IGNvbXBvbmVudC50cmFuc2Zlci5nZXRDb21wb25lbnRNZXRhKClcbiAgICAgICAgICAgIDogeyBcbiAgICAgICAgICAgICAgICBjb21wQ2xhc3M6IGNvbXBvbmVudC5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICAgICAgICAgIGNvbXBOYW1lOiBjb21wb25lbnQubmFtZVxuICAgICAgICAgICAgfTtcbn1cblxuXG5mdW5jdGlvbiBEcmFnRHJvcCRnZXRDb21wb25lbnRNZXRhKCkge1xuICAgIHZhciBtYXRjaDtcbiAgICB2YXIgbWV0YURhdGFUeXBlID0gXy5maW5kKHRoaXMudHlwZXMsIGZ1bmN0aW9uIChkVHlwZSkge1xuICAgICAgICBtYXRjaCA9IGRUeXBlLm1hdGNoKGNvbXBvbmVudE1ldGFSZWdleCk7XG4gICAgICAgIHJldHVybiAhIW1hdGNoO1xuICAgIH0pO1xuICAgIGlmICghbWV0YURhdGFUeXBlKSByZXR1cm47XG5cbiAgICBmb3IgKHZhciBpPTE7IGk8NDsgaSsrKVxuICAgICAgICBtYXRjaFtpXSA9IGJhc2UzMi5kZWNvZGUobWF0Y2hbaV0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tcENsYXNzOiBtYXRjaFsxXSxcbiAgICAgICAgY29tcE5hbWU6IG1hdGNoWzJdLFxuICAgICAgICBwYXJhbXM6IF8uZnJvbVF1ZXJ5U3RyaW5nKG1hdGNoWzNdKSxcbiAgICAgICAgbWV0YURhdGFUeXBlOiBtZXRhRGF0YVR5cGUsXG4gICAgICAgIG1ldGFEYXRhOiBfLmpzb25QYXJzZSh0aGlzLmRhdGFUcmFuc2Zlci5nZXREYXRhKG1ldGFEYXRhVHlwZSkpIFxuICAgICAgICAgICAgICAgICAgICA/IF8uanNvblBhcnNlKHRoaXMuZGF0YVRyYW5zZmVyLmdldERhdGEobWV0YURhdGFUeXBlKSkgXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy5kYXRhVHJhbnNmZXIuZ2V0RGF0YShtZXRhRGF0YVR5cGUpXG4gICAgfTtcbn1cblxuXG4vLyBhcyBkZWZpbmVkIGhlcmU6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvRHJhZ0Ryb3AvRHJhZ19PcGVyYXRpb25zI2RyYWdzdGFydFxuZnVuY3Rpb24gRHJhZ0Ryb3AkZ2V0QWxsb3dlZEVmZmVjdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVRyYW5zZmVyLmVmZmVjdEFsbG93ZWQ7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3Akc2V0QWxsb3dlZEVmZmVjdHMoZWZmZWN0cykge1xuICAgIHRoaXMuZGF0YVRyYW5zZmVyLmVmZmVjdEFsbG93ZWQgPSBlZmZlY3RzO1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJGdldERyb3BFZmZlY3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3Q7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3Akc2V0RHJvcEVmZmVjdChlZmZlY3QpIHtcbiAgICB0aGlzLmRhdGFUcmFuc2Zlci5kcm9wRWZmZWN0ID0gZWZmZWN0O1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJGlzRWZmZWN0QWxsb3dlZChlZmZlY3QpIHtcbiAgICB2YXIgYWxsb3dlZEVmZmVjdHMgPSB0aGlzLmdldEFsbG93ZWRFZmZlY3RzKClcbiAgICAgICAgLCBpc0NvcHkgPSBlZmZlY3QgPT0gJ2NvcHknXG4gICAgICAgICwgaXNNb3ZlID0gZWZmZWN0ID09ICdtb3ZlJ1xuICAgICAgICAsIGlzTGluayA9IGVmZmVjdCA9PSAnbGluaydcbiAgICAgICAgLCBpc0FsbG93ZWQgPSBpc0NvcHkgfHwgaXNMaW5rIHx8IGlzTW92ZTtcblxuICAgIHN3aXRjaCAoYWxsb3dlZEVmZmVjdHMpIHtcbiAgICAgICAgY2FzZSAnY29weSc6XG4gICAgICAgIGNhc2UgJ21vdmUnOlxuICAgICAgICBjYXNlICdsaW5rJzpcbiAgICAgICAgICAgIHJldHVybiBhbGxvd2VkRWZmZWN0cyA9PSBlZmZlY3Q7XG4gICAgICAgIGNhc2UgJ2NvcHlMaW5rJzpcbiAgICAgICAgICAgIHJldHVybiBpc0NvcHkgfHwgaXNMaW5rO1xuICAgICAgICBjYXNlICdjb3B5TW92ZSc6XG4gICAgICAgICAgICByZXR1cm4gaXNDb3B5IHx8IGlzTW92ZTtcbiAgICAgICAgY2FzZSAnbGlua01vdmUnOlxuICAgICAgICAgICAgcmV0dXJuIGlzTGluayB8fCBpc01vdmU7XG4gICAgICAgIGNhc2UgJ2FsbCc6XG4gICAgICAgIGNhc2UgJ3VuaW5pdGlhbGl6ZWQnOlxuICAgICAgICAgICAgcmV0dXJuIGlzQWxsb3dlZDtcbiAgICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJGdldERhdGEoZGF0YVR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhVHJhbnNmZXIuZ2V0RGF0YShkYXRhVHlwZSk7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3Akc2V0RGF0YShkYXRhVHlwZSwgZGF0YVN0cikge1xuICAgIHRoaXMuZGF0YVRyYW5zZmVyLnNldERhdGEoZGF0YVR5cGUsIGRhdGFTdHIpO1xufVxuXG5cbmZ1bmN0aW9uIERyYWdEcm9wJGNsZWFyRGF0YShkYXRhVHlwZSkge1xuICAgIHRoaXMuZGF0YVRyYW5zZmVyLmNsZWFyRGF0YShkYXRhVHlwZSk7XG59XG5cblxuLyoqXG4gKiBEcmFnIGRyb3Agc2VydmljZSBjb21wZW5zYXRpbmcgZm9yIHRoZSBsYWNrIG9mIGNvbW11bmljYXRpb24gZnJvbSBkcm9wIHRhcmdldCB0byBkcmFnIHNvdXJjZSBpbiBET00gQVBJXG4gKi9cbnZhciBkcmFnRHJvcFNlcnZpY2UgPSBuZXcgTWVzc2VuZ2VyO1xuXG52YXIgX2N1cnJlbnREcmFnRHJvcCwgX2N1cnJlbnREcmFnRmFjZXQ7XG5cbl8uZXh0ZW5kKERyYWdEcm9wLCB7XG4gICAgc2VydmljZTogZHJhZ0Ryb3BTZXJ2aWNlLFxuICAgIGRlc3Ryb3k6IERyYWdEcm9wX2Rlc3Ryb3lcbn0pO1xuXG5cbmRyYWdEcm9wU2VydmljZS5vbk1lc3NhZ2VzKHtcbiAgICAvLyBkYXRhIGlzIERyYWdEcm9wRGF0YVRyYW5zZmVyIGluc3RhbmNlXG4gICAgLy8gZmlyZWQgYnkgRHJhZyBmYWNldCBvbiBcImRyYWdzdGFydFwiIGV2ZW50XG4gICAgJ2RyYWdkcm9wc3RhcnRlZCc6IG9uRHJhZ0Ryb3BTdGFydGVkLCBcbiAgICAvLyBkYXRhIGlzIG9iamVjdCB3aXRoIGF0IGxlYXN0IGRyb3BFZmZlY3QgcHJvcGVydHlcbiAgICAvLyBmaXJlZCBieSBEcm9wIGZhY2V0IG9uIFwiZHJvcFwiIGV2ZW50XG4gICAgJ2RyYWdkcm9wY29tcGxldGVkJzogb25EcmFnRHJvcENvbXBsZXRlZCwgXG4gICAgLy8gZmlyZWQgYnkgRHJhZyBmYWNldCBvbiBcImRyYWdlbmRcIiBldmVudCB0byBjb21wbGV0ZSBkcmFnXG4gICAgLy8gaWYgZHJvcCBoYXBwZW5kZWQgaW4gYW5vdGhlciB3aW5kb3cgb3IgaWYgaXQgd2FzIGNhbmNlbGxlZFxuICAgICdjb21wbGV0ZWRyYWdkcm9wJzogb25Db21wbGV0ZURyYWdEcm9wXG59KTtcblxuXG5fLmV4dGVuZChkcmFnRHJvcFNlcnZpY2UsIHtcbiAgICBnZXRDdXJyZW50RHJhZ0Ryb3A6IGdldEN1cnJlbnREcmFnRHJvcFxufSk7XG5cblxuZnVuY3Rpb24gb25EcmFnRHJvcFN0YXJ0ZWQobXNnLCBkYXRhKSB7XG4gICAgX2N1cnJlbnREcmFnRHJvcCA9IGRhdGEuZHJhZ0Ryb3A7XG4gICAgX2N1cnJlbnREcmFnRmFjZXQgPSBkYXRhLmRyYWdGYWNldDtcbn1cblxuXG5mdW5jdGlvbiBvbkRyYWdEcm9wQ29tcGxldGVkKG1zZywgZGF0YSkge1xuICAgIF9jdXJyZW50RHJhZ0ZhY2V0ICYmIF9jdXJyZW50RHJhZ0ZhY2V0LnBvc3RNZXNzYWdlU3luYygnZHJhZ2Ryb3Bjb21wbGV0ZWQnLCBkYXRhKTtcbiAgICBfY3VycmVudERyYWdEcm9wID0gdW5kZWZpbmVkO1xuICAgIF9jdXJyZW50RHJhZ0ZhY2V0ID0gdW5kZWZpbmVkO1xufVxuXG5cbmZ1bmN0aW9uIG9uQ29tcGxldGVEcmFnRHJvcChtc2csIGRhdGEpIHtcbiAgICBpZiAoX2N1cnJlbnREcmFnRHJvcClcbiAgICAgICAgZHJhZ0Ryb3BTZXJ2aWNlLnBvc3RNZXNzYWdlU3luYygnZHJhZ2Ryb3Bjb21wbGV0ZWQnLCBkYXRhKTtcbn1cblxuXG5mdW5jdGlvbiBnZXRDdXJyZW50RHJhZ0Ryb3AoKSB7XG4gICAgcmV0dXJuIF9jdXJyZW50RHJhZ0Ryb3A7XG59XG5cblxuZnVuY3Rpb24gRHJhZ0Ryb3BfZGVzdHJveSgpIHtcbiAgICBkcmFnRHJvcFNlcnZpY2Uub2ZmQWxsKCk7XG59XG4iLCIvLyA8YSBuYW1lPVwidXRpbHMtZXJyb3JcIj48L2E+XG4vLyBtaWxvLnV0aWxzLmVycm9yXG4vLyAtLS0tLS0tLS0tLVxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLy8gbW9kdWxlIGV4cG9ydHMgZXJyb3IgY2xhc3NlcyBmb3IgYWxsIG5hbWVzIGRlZmluZWQgaW4gdGhpcyBhcnJheVxudmFyIGVycm9yQ2xhc3NOYW1lcyA9IFsnQWJzdHJhY3RDbGFzcycsICdNaXhpbicsICdNZXNzZW5nZXInLCAnQ29tcG9uZW50JyxcbiAgICAgICAgICAgICAgICAgICAgICAgJ0F0dHJpYnV0ZScsICdCaW5kZXInLCAnTG9hZGVyJywgJ01haWxNZXNzYWdlU291cmNlJywgJ0ZhY2V0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgJ1Njb3BlJywgJ01vZGVsJywgJ0RvbUZhY2V0JywgJ0VkaXRhYmxlRmFjZXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAnTGlzdCcsICdDb25uZWN0b3InLCAnUmVnaXN0cnknLCAnRnJhbWVNZXNzYWdlU291cmNlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgJ0Ryb3AnLCAnQW5ndWxhcicsICdTdG9yYWdlTWVzc2FnZVNvdXJjZSddO1xuXG52YXIgZXJyb3IgPSB7XG4gICAgdG9CZUltcGxlbWVudGVkOiBlcnJvciR0b0JlSW1wbGVtZW50ZWQsXG4gICAgY3JlYXRlQ2xhc3M6IGVycm9yJGNyZWF0ZUNsYXNzXG59O1xuXG5lcnJvckNsYXNzTmFtZXMuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgZXJyb3JbbmFtZV0gPSBlcnJvciRjcmVhdGVDbGFzcyhuYW1lICsgJ0Vycm9yJyk7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBlcnJvcjtcblxuXG5mdW5jdGlvbiBlcnJvciRjcmVhdGVDbGFzcyhlcnJvckNsYXNzTmFtZSkge1xuICAgIHZhciBFcnJvckNsYXNzID0gXy5tYWtlRnVuY3Rpb24oZXJyb3JDbGFzc05hbWUsICdtZXNzYWdlJyxcbiAgICAgICAgICAgICd0aGlzLm5hbWUgPSBcIicgKyBlcnJvckNsYXNzTmFtZSArICdcIjsgXFxcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgXCJUaGVyZSB3YXMgYW4gIGVycm9yXCI7Jyk7XG4gICAgXy5tYWtlU3ViY2xhc3MoRXJyb3JDbGFzcywgRXJyb3IpO1xuXG4gICAgcmV0dXJuIEVycm9yQ2xhc3M7XG59XG5cblxuZnVuY3Rpb24gZXJyb3IkdG9CZUltcGxlbWVudGVkKCkge1xuICAgIHRocm93IG5ldyBlcnJvci5BYnN0cmFjdENsYXNzKCdjYWxsaW5nIHRoZSBtZXRob2Qgb2YgYW4gYWJzY3RyYWN0IGNsYXNzJyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIENvbXBvbmVudCA9IHJlcXVpcmUoJy4uL2NvbXBvbmVudHMvY19jbGFzcycpXG4gICAgLCBCaW5kQXR0cmlidXRlID0gcmVxdWlyZSgnLi4vYXR0cmlidXRlcy9hX2JpbmQnKVxuICAgICwgYmluZGVyID0gcmVxdWlyZSgnLi4vYmluZGVyJylcbiAgICAsIGRvbVV0aWxzID0gcmVxdWlyZSgnLi9kb20nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi9sb2dnZXInKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuL2NoZWNrJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG52YXIgY3JlYXRlUmFuZ2VQYXRocyA9IF9jcmVhdGVOb2Rlc0FuZFBhdGhzRnVuYyhkb21VdGlscy50cmVlUGF0aE9mKTtcbnZhciBjcmVhdGVSYW5nZU5vZGVzID0gX2NyZWF0ZU5vZGVzQW5kUGF0aHNGdW5jKGRvbVV0aWxzLmdldE5vZGVBdFRyZWVQYXRoKTtcblxuXG52YXIgZnJhZ21lbnRVdGlscyA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGdldFN0YXRlOiBmcmFnbWVudF9nZXRTdGF0ZSxcbiAgICBnZXRTdGF0ZUFzeW5jOiBmcmFnbWVudF9nZXRTdGF0ZUFzeW5jLFxuXG4gICAgZXhwYW5kUmFuZ2VUb1NpYmxpbmdzOiBleHBhbmRSYW5nZVRvU2libGluZ3MsXG4gICAgZ2V0UmFuZ2VTaWJsaW5nczogZ2V0UmFuZ2VTaWJsaW5ncyxcbiAgICBjcmVhdGVSYW5nZUZyb21TaWJsaW5nczogY3JlYXRlUmFuZ2VGcm9tU2libGluZ3MsXG4gICAgY3JlYXRlUmFuZ2VGcm9tTm9kZXM6IGNyZWF0ZVJhbmdlRnJvbVNpYmxpbmdzLCAvLyBhbGlhc1xuICAgIGNyZWF0ZVJhbmdlUGF0aHM6IGNyZWF0ZVJhbmdlUGF0aHMsXG4gICAgY3JlYXRlUmFuZ2VOb2RlczogY3JlYXRlUmFuZ2VOb2Rlc1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlIHN0YXRlIG9mIHdyYXBwZWQgcmFuZ2Ugd2l0aCBjb21wb25lbnRzLCBpbmNsdWRpbmcgcGFydGlhbGx5IHNlbGVjdGVkLiBUaGUgcmFuZ2Ugd2lsbCBiZSBjbG9uZWQgYW5kIHdyYXBwZWQgaW4gY29tcG9uZW50IHdpdGggY29udGFpbmVyIGZhY2V0IGJlZm9yZSBnZXR0aW5nIGl0cyBzdGF0ZS5cbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBsb2cgZXJyb3IgYW5kIHJldHVybiB1bmRlZmluZWQgaWYgcmFuZ2UgaGFzIG5vIGNvbW1vbiBhbmNlc3RvciB0aGF0IGhhcyBjb21wb25lbnQgd2l0aCBjb250YWluZXIgZmFjZXRcbiAqIFxuICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgRE9NIFJhbmdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHJlbmFtZUNoaWxkcmVuIG9wdGlvbmFsIHBhcmFtZXRlciwgYHRydWVgIHRvIHJlbmFtZSBmcmFnbWVudCBjaGlsZCBjb21wb25lbnRzXG4gKiBAcGFyYW0ge1N0cmluZ30gd3JhcHBlckNsYXNzTmFtZSBvcHRpb25hbCBwYXJhbWV0ZXIgdG8gd3JhcCBpbiBhIGN1c3RvbSBjb21wb25lbnQgY2xhc3NcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZnJhZ21lbnRfZ2V0U3RhdGUocmFuZ2UsIHJlbmFtZUNoaWxkcmVuLCB3cmFwcGVyQ2xhc3NOYW1lKSB7XG4gICAgdmFyIHJhbmdlQ29udGFpbmVyID0gX2dldFJhbmdlQ29udGFpbmVyKHJhbmdlKTtcbiAgICBpZiAoISByYW5nZUNvbnRhaW5lcikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ2ZyYWdtZW50LmdldFN0YXRlOiByYW5nZSBoYXMgbm8gY29tbW9uIGNvbnRhaW5lcicpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGZyYWcgPSByYW5nZS5jbG9uZUNvbnRlbnRzKClcbiAgICAgICAgLCB3cmFwcGVyID0gX3dyYXBGcmFnbWVudEluQ29udGFpbmVyKGZyYWcsIHdyYXBwZXJDbGFzc05hbWUpO1xuXG4gICAgX3RyYW5zZmVyU3RhdGVzKHJhbmdlQ29udGFpbmVyLCB3cmFwcGVyKTtcbiAgICBpZiAocmVuYW1lQ2hpbGRyZW4pIF9yZW5hbWVDaGlsZHJlbih3cmFwcGVyKTtcbiAgICB2YXIgd3JhcHBlclN0YXRlID0gd3JhcHBlci5nZXRTdGF0ZSgpO1xuICAgIF8uZGVmZXJNZXRob2Qod3JhcHBlciwgJ2Rlc3Ryb3knKTtcbiAgICByZXR1cm4gd3JhcHBlclN0YXRlO1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0aGUgc3RhdGUgb2Ygd3JhcHBlZCByYW5nZSB3aXRoIGNvbXBvbmVudHMsIGluY2x1ZGluZyBwYXJ0aWFsbHkgc2VsZWN0ZWQuIFRoZSByYW5nZSB3aWxsIGJlIGNsb25lZCBhbmQgd3JhcHBlZCBpbiBjb21wb25lbnQgd2l0aCBjb250YWluZXIgZmFjZXQgYmVmb3JlIGdldHRpbmcgaXRzIHN0YXRlLlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIHJldHVybiByZXN1bHQgYW5kIGFueSBlcnJvciB2aWEgY2FsbGJhY2suXG4gKiBcbiAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIERPTSBSYW5nZSBpbnN0YW5jZVxuICogQHBhcmFtIHtCb29sZWFufSByZW5hbWVDaGlsZHJlbiBvcHRpb25hbCBwYXJhbWV0ZXIsIGB0cnVlYCB0byByZW5hbWUgZnJhZ21lbnQgY2hpbGQgY29tcG9uZW50c1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgYWx3YXlzIHRoZSBsYXN0IHBhcmFtZXRlciwgb3B0aW9uYWwgcGFyYW1ldGVycyBjYW4gYmUgZHJvcHBlZDsgcmVzdWx0IGlzIHBhc3NlZCB2aWEgY2FsbGJhY2sgd2l0aCBhbnkgZXJyb3IgYXMgZmlyc3QgcGFyYW1ldGVyXG4gKi9cbmZ1bmN0aW9uIGZyYWdtZW50X2dldFN0YXRlQXN5bmMocmFuZ2UsIHJlbmFtZUNoaWxkcmVuLCBjYWxsYmFjaykge1xuICAgIHRyeSB7XG4gICAgICAgIHZhciByYW5nZUNvbnRhaW5lciA9IF9nZXRSYW5nZUNvbnRhaW5lcihyYW5nZSk7XG4gICAgICAgIGlmICghIHJhbmdlQ29udGFpbmVyKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ2ZyYWdtZW50LmdldFN0YXRlOiByYW5nZSBoYXMgbm8gY29tbW9uIGNvbnRhaW5lcicpKTtcbiAgICAgICAgICAgIHJldHVybjsgLy8gZG8gTk9UIGNvbm5lY3QgcmV0dXJuIHRvIHByZXZpb3VzIGNhbGxiYWNrLCBnZXRTdGF0ZSBzaG91bGQgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiByZW5hbWVDaGlsZHJlbiA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWxsYmFjayA9IHJlbmFtZUNoaWxkcmVuO1xuICAgICAgICAgICAgcmVuYW1lQ2hpbGRyZW4gPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBmcmFnID0gcmFuZ2UuY2xvbmVDb250ZW50cygpXG4gICAgICAgICAgICAsIHdyYXBwZXIgPSBfd3JhcEZyYWdtZW50SW5Db250YWluZXIoZnJhZyk7XG5cbiAgICAgICAgX3RyYW5zZmVyU3RhdGVzKHJhbmdlQ29udGFpbmVyLCB3cmFwcGVyKTtcbiAgICAgICAgXy5kZWZlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHdyYXBwZXIuYnJvYWRjYXN0KCdzdGF0ZXJlYWR5Jyk7XG4gICAgICAgICAgICBfLmRlZmVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIGlmIChyZW5hbWVDaGlsZHJlbikgX3JlbmFtZUNoaWxkcmVuKHdyYXBwZXIpO1xuICAgICAgICAgICAgICAgIHZhciB3cmFwcGVyU3RhdGUgPSB3cmFwcGVyLmdldFN0YXRlKCk7XG4gICAgICAgICAgICAgICAgd3JhcHBlci5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgd3JhcHBlclN0YXRlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gX3dyYXBGcmFnbWVudEluQ29udGFpbmVyKGZyYWcsIHdyYXBwZXJDbGFzc05hbWUpIHtcbiAgICB2YXIgd3JhcEVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgLCBhdHRyID0gbmV3IEJpbmRBdHRyaWJ1dGUod3JhcEVsKTtcblxuICAgIF8uZXh0ZW5kKGF0dHIsIHtcbiAgICAgICAgY29tcENsYXNzOiB3cmFwcGVyQ2xhc3NOYW1lIHx8ICdDb21wb25lbnQnLFxuICAgICAgICBjb21wRmFjZXRzOiB3cmFwcGVyQ2xhc3NOYW1lID8gW10gOiBbJ2NvbnRhaW5lciddLFxuICAgICAgICBjb21wTmFtZTogJ3dyYXBwZXInXG4gICAgfSk7XG5cbiAgICBhdHRyLmRlY29yYXRlKCk7XG5cbiAgICB3cmFwRWwuYXBwZW5kQ2hpbGQoZnJhZyk7XG4gICAgdmFyIHNjb3BlID0gYmluZGVyKHdyYXBFbCk7XG4gICAgcmV0dXJuIHNjb3BlLndyYXBwZXI7XG59XG5cblxuZnVuY3Rpb24gX2dldFJhbmdlQ29udGFpbmVyKHJhbmdlKSB7XG4gICAgdmFyIGVsID0gZG9tVXRpbHMuY29udGFpbmluZ0VsZW1lbnQocmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIpO1xuICAgIHJldHVybiBDb21wb25lbnQuZ2V0Q29udGFpbmluZ0NvbXBvbmVudChlbCwgdHJ1ZSwgJ2NvbnRhaW5lcicpO1xufVxuXG5cbmZ1bmN0aW9uIF90cmFuc2ZlclN0YXRlcyhmcm9tQ29tcCwgdG9Db21wKSB7XG4gICAgdmFyIGZyb21TY29wZSA9IGZyb21Db21wLmNvbnRhaW5lci5zY29wZTtcbiAgICB0b0NvbXAuY29udGFpbmVyLnNjb3BlLl9lYWNoKGZ1bmN0aW9uKHRvQ2hpbGRDb21wLCBuYW1lKSB7XG4gICAgICAgIHZhciBmcm9tQ2hpbGRDb21wID0gZnJvbVNjb3BlW25hbWVdO1xuICAgICAgICBpZiAoISBmcm9tQ2hpbGRDb21wKSByZXR1cm4gbG9nZ2VyLmVycm9yKCdmcmFnbWVudC5nZXRTdGF0ZTogY29ucG9uZW50JywgbmFtZSwgJ25vdCBmb3VuZCBpbiByYW5nZScpO1xuICAgICAgICB2YXIgc3RhdGUgPSBmcm9tQ2hpbGRDb21wLl9nZXRTdGF0ZSh0cnVlKTtcbiAgICAgICAgdG9DaGlsZENvbXAuc2V0U3RhdGUoc3RhdGUpO1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9yZW5hbWVDaGlsZHJlbihjb21wKSB7XG4gICAgY29tcC5jb250YWluZXIuc2NvcGUuX2VhY2goZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgICAgY2hpbGQucmVuYW1lKCk7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gZXhwYW5kUmFuZ2VUb1NpYmxpbmdzKHJhbmdlKSB7XG4gICAgdmFyIHNpYmxpbmdzID0gZ2V0UmFuZ2VTaWJsaW5ncyhyYW5nZSk7XG4gICAgcmFuZ2UgPSBjcmVhdGVSYW5nZUZyb21TaWJsaW5ncyhzaWJsaW5ncyk7XG4gICAgcmV0dXJuIHJhbmdlO1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZVJhbmdlRnJvbVNpYmxpbmdzKG5vZGVzKSB7XG4gICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICBpZiAobm9kZXMuc2libGluZ3MpIHtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnRCZWZvcmUobm9kZXMuc3RhcnQpO1xuICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihub2Rlcy5lbmQpO1xuICAgIH0gZWxzZVxuICAgICAgICByYW5nZS5zZWxlY3ROb2RlKG5vZGVzLnN0YXJ0KTtcbiAgICByZXR1cm4gcmFuZ2U7XG59XG5cblxuZnVuY3Rpb24gZ2V0UmFuZ2VTaWJsaW5ncyhyYW5nZSkge1xuICAgIHZhciBjb250YWluZXJOb2RlID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXJcbiAgICAgICAgLCBzdGFydE5vZGUgPSByYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgICAsIGVuZE5vZGUgPSByYW5nZS5lbmRDb250YWluZXI7XG5cbiAgICBpZiAoc3RhcnROb2RlID09IGVuZE5vZGUpIHtcbiAgICAgICAgaWYgKHN0YXJ0Tm9kZSAhPSBjb250YWluZXJOb2RlKSBsb2dnZXIuZXJyb3IoJ2RlbGV0ZVNlbGVjdGlvbkNvbW1hbmQgbG9naWNhbCBlcnJvcjogc3RhcnQ9PWVuZCwgYnV0IGNvbnRhaW5lciBpcyBkaWZmZXJlbnQnKTtcbiAgICAgICAgcmV0dXJuIHsgc2libGluZ3M6IGZhbHNlLCBzdGFydDogc3RhcnROb2RlIH07XG4gICAgfVxuXG4gICAgaWYgKHN0YXJ0Tm9kZSA9PSBjb250YWluZXJOb2RlIHx8IGVuZE5vZGUgPT0gY29udGFpbmVyTm9kZSlcbiAgICAgICAgcmV0dXJuIHsgc2libGluZ3M6IGZhbHNlLCBzdGFydDogY29udGFpbmVyTm9kZSB9O1xuXG4gICAgdmFyIHN0YXJ0U2libGluZyA9IF9maW5kQ29udGFpbmluZ0NoaWxkKGNvbnRhaW5lck5vZGUsIHN0YXJ0Tm9kZSk7XG4gICAgdmFyIGVuZFNpYmxpbmcgPSBfZmluZENvbnRhaW5pbmdDaGlsZChjb250YWluZXJOb2RlLCBlbmROb2RlKTtcblxuICAgIGlmIChzdGFydFNpYmxpbmcgJiYgZW5kU2libGluZykge1xuICAgICAgICBpZiAoc3RhcnRTaWJsaW5nID09IGVuZFNpYmxpbmcpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignZGVsZXRlU2VsZWN0aW9uQ29tbWFuZCBsb2dpY2FsIGVycm9yOiBzYW1lIHNpYmxpbmdzJyk7XG4gICAgICAgICAgICByZXR1cm4geyBzaWJsaW5nczogZmFsc2UsIHN0YXJ0OiBzdGFydFNpYmxpbmcgfTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICByZXR1cm4geyBzaWJsaW5nczogdHJ1ZSwgc3RhcnQ6IHN0YXJ0U2libGluZywgZW5kOiBlbmRTaWJsaW5nIH07XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9maW5kQ29udGFpbmluZ0NoaWxkKGNvbnRhaW5lck5vZGUsIHNlbE5vZGUpIHtcbiAgICByZXR1cm4gXy5maW5kKGNvbnRhaW5lck5vZGUuY2hpbGROb2RlcywgZnVuY3Rpb24obm9kZSkge1xuICAgICAgICByZXR1cm4gbm9kZS5jb250YWlucyhzZWxOb2RlKTtcbiAgICB9KTtcbn1cblxuXG5mdW5jdGlvbiBfY3JlYXRlTm9kZXNBbmRQYXRoc0Z1bmMoZnVuYykge1xuICAgIHJldHVybiBmdW5jdGlvbihyb290RWwsIGZyb21PYmopIHtcbiAgICAgICAgdmFyIHRvT2JqID0ge1xuICAgICAgICAgICAgc2libGluZ3M6IGZyb21PYmouc2libGluZ3MsXG4gICAgICAgICAgICBzdGFydDogZnVuYyhyb290RWwsIGZyb21PYmouc3RhcnQpXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0b09iai5zaWJsaW5ncylcbiAgICAgICAgICAgIHRvT2JqLmVuZCA9IGZ1bmMocm9vdEVsLCBmcm9tT2JqLmVuZCk7XG4gICAgICAgIHJldHVybiB0b09iajtcbiAgICB9O1xufVxuXG5cbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBgbWlsby51dGlsYFxuICovXG52YXIgdXRpbCA9IHtcbiAgICBsb2dnZXI6IHJlcXVpcmUoJy4vbG9nZ2VyJyksXG4gICAgcmVxdWVzdDogcmVxdWlyZSgnLi9yZXF1ZXN0JyksXG4gICAgd2Vic29ja2V0OiByZXF1aXJlKCcuL3dlYnNvY2tldCcpLFxuICAgIGNoZWNrOiByZXF1aXJlKCcuL2NoZWNrJyksXG4gICAgZXJyb3I6IHJlcXVpcmUoJy4vZXJyb3InKSxcbiAgICBjb3VudDogcmVxdWlyZSgnLi9jb3VudCcpLCAvLyBkZXByZWNhdGVkXG4gICAgdW5pcXVlSWQ6IHJlcXVpcmUoJy4vY291bnQnKSxcbiAgICBjb21wb25lbnROYW1lOiByZXF1aXJlKCcuL2NvbXBvbmVudF9uYW1lJyksXG4gICAgZG9tOiByZXF1aXJlKCcuL2RvbScpLFxuICAgIGRvbUxpc3RlbmVyczogcmVxdWlyZSgnLi9kb21fbGlzdGVuZXJzJyksXG4gICAgc2VsZWN0aW9uOiByZXF1aXJlKCcuL3NlbGVjdGlvbicpLFxuICAgIGZyYWdtZW50OiByZXF1aXJlKCcuL2ZyYWdtZW50JyksXG4gICAganNvblBhcnNlOiByZXF1aXJlKCcuL2pzb25fcGFyc2UnKSxcbiAgICBzdG9yYWdlOiByZXF1aXJlKCcuL3N0b3JhZ2UnKSxcbiAgICBkb21SZWFkeTogcmVxdWlyZSgnLi9kb21yZWFkeScpLFxuICAgIGRyYWdEcm9wOiByZXF1aXJlKCcuL2RyYWdkcm9wJyksXG4gICAgZGlhbG9nOiByZXF1aXJlKCcuLi9jb21wb25lbnRzL3VpL2Jvb3RzdHJhcC9EaWFsb2cnKSxcbiAgICBhbGVydDogcmVxdWlyZSgnLi4vY29tcG9uZW50cy91aS9ib290c3RyYXAvQWxlcnQnKSxcbiAgICBkb1Q6IHJlcXVpcmUoJ2RvdCcpLFxuICAgIGRlc3Ryb3k6IHV0aWxfZGVzdHJveVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dGlsO1xuXG5cbmZ1bmN0aW9uIHV0aWxfZGVzdHJveSgpIHtcbiAgICB1dGlsLnJlcXVlc3QuZGVzdHJveSgpO1xuICAgIHV0aWwuZHJhZ0Ryb3AuZGVzdHJveSgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbm1vZHVsZS5leHBvcnRzID0ganNvblBhcnNlO1xuXG5cbi8qKlxuICogYG1pbG8udXRpbC5qc29uUGFyc2VgXG4gKiBTYWZlIEpTT04ucGFyc2UsIHJldHVybnMgdW5kZWZpbmVkIGlmIEpTT04ucGFyc2UgdGhyb3dzIGFuIGV4Y2VwdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgLSBKU09OIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBvYmplY3RcbiAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIGpzb25QYXJzZShzdHIpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShzdHIpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIDxhIG5hbWU9XCJ1dGlscy1sb2dnZXJcIj48L2E+XG4vLyBtaWxvLnV0aWxzLmxvZ2dlclxuLy8gLS0tLS0tLS0tLS1cblxuLy8gQXBwbGljYXRpb24gbG9nZ2VyIHRoYXQgaGFzIGVycm9yLCB3YXJuLCBpbmZvIGFuZCBkZWJ1Z1xuLy8gbWV0aG9kcywgdGhhdCBjYW4gYmUgc3VwcHJlc3NlZCBieSBzZXR0aW5nIGxvZyBsZXZlbC5cblxuLy8gUHJvcGVydGllczpcblxuLy8gLSBsZXZlbFxuXG4vLyAgIC0gMCAtIGVycm9yXG4vLyAgIC0gMSAtIHdhcm5cbi8vICAgLSAyIC0gaW5mb1xuLy8gICAtIDMgLSBkZWJ1ZyAoZGVmYXVsdClcblxuLy8gLSBlbmFibGVkXG5cbi8vICAgdHJ1ZSBieSBkZWZhdWx0LiBTZXQgdG8gZmFsc2UgdG8gZGlzYWJsZSBhbGwgbG9nZ2luZyBpbiBicm93c2VyIGNvbnNvbGUuXG5cblxudmFyIExvZ2dlciA9IHJlcXVpcmUoJy4vbG9nZ2VyX2NsYXNzJyk7XG5cbnZhciBsb2dnZXIgPSBuZXcgTG9nZ2VyKHsgbGV2ZWw6IDMgfSk7XG5cbm1vZHVsZS5leHBvcnRzID0gbG9nZ2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAjIyMgTG9nZ2VyIENsYXNzXG5cbi8vIFByb3BlcnRpZXM6XG5cbi8vIC0gbGV2ZWxcblxuLy8gICAtIDAgLSBlcnJvclxuLy8gICAtIDEgLSB3YXJuXG4vLyAgIC0gMiAtIGluZm9cbi8vICAgLSAzIC0gZGVidWcgKGRlZmF1bHQpXG5cbi8vIC0gZW5hYmxlZFxuXG4vLyAgIHRydWUgYnkgZGVmYXVsdC4gU2V0IHRvIGZhbHNlIHRvIGRpc2FibGUgYWxsIGxvZ2dpbmcgaW4gYnJvd3NlciBjb25zb2xlLlxuXG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJyk7XG5cblxuLyoqXG4gKiBMb2cgbGV2ZWxzLlxuICovXG5cbnZhciBsZXZlbHMgPSBbXG4gICAgJ2Vycm9yJyxcbiAgICAnd2FybicsXG4gICAgJ2luZm8nLFxuICAgICdkZWJ1Zydcbl07XG5cbnZhciBtYXhMZXZlbExlbmd0aCA9IE1hdGgubWF4LmFwcGx5KE1hdGgsIGxldmVscy5tYXAoZnVuY3Rpb24obGV2ZWwpIHsgcmV0dXJuIGxldmVsLmxlbmd0aDsgfSkpO1xuXG4vKipcbiAqIENvbG9ycyBmb3IgbG9nIGxldmVscy5cbiAqL1xuXG52YXIgY29sb3JzID0gW1xuICAgIDMxLFxuICAgIDMzLFxuICAgIDM2LFxuICAgIDkwXG5dO1xuXG4vKipcbiAqIFBhZHMgdGhlIG5pY2Ugb3V0cHV0IHRvIHRoZSBsb25nZXN0IGxvZyBsZXZlbC5cbiAqL1xuZnVuY3Rpb24gcGFkKHN0cikge1xuICAgIGlmIChzdHIubGVuZ3RoIDwgbWF4TGV2ZWxMZW5ndGgpXG4gICAgICAgIHJldHVybiBzdHIgKyBuZXcgQXJyYXkobWF4TGV2ZWxMZW5ndGggLSBzdHIubGVuZ3RoICsgMSkuam9pbignICcpO1xuXG4gICAgcmV0dXJuIHN0cjtcbn07XG5cblxuZnVuY3Rpb24gY29sb3JlZChzdHIsIGNvbG9yKSB7XG4gICAgcmV0dXJuICdcXHgxQlsnICsgY29sb3IgKyAnbScgKyBzdHIgKyAnIC1cXHgxQlszOW0nO1xufVxuXG5cbnZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbGV2ZWw6IDMsXG4gICAgdGhyb3dMZXZlbDogLTEsIC8vIG5ldmVyIHRocm93XG4gICAgZW5hYmxlZDogdHJ1ZSxcbiAgICBsb2dQcmVmaXg6ICcnXG59XG5cblxuLyoqXG4gKiBMb2dnZXIgKGNvbnNvbGUpLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cbnZhciBMb2dnZXIgPSBmdW5jdGlvbiAob3B0cykge1xuICAgIF8uZXh0ZW5kKHRoaXMsIERFRkFVTFRfT1BUSU9OUyk7XG4gICAgXy5leHRlbmQodGhpcywgb3B0cyB8fCB7fSk7XG59O1xuXG5cbi8qKlxuICogTG9nIG1ldGhvZC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxvZ2dlci5wcm90b3R5cGUubG9nID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICB2YXIgaW5kZXggPSBsZXZlbHMuaW5kZXhPZih0eXBlKTtcblxuICAgIGlmICghIHRoaXMuZW5hYmxlZCB8fCBpbmRleCA+IHRoaXMubGV2ZWwpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgdmFyIGFyZ3MgPSBfLnNsaWNlKGFyZ3VtZW50cywgMSk7XG5cbiAgICBpZiAoaW5kZXggPD0gdGhpcy50aHJvd0xldmVsKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoW3RoaXMubG9nUHJlZml4LCB0eXBlICsgJzonXS5jb25jYXQoYXJncykuam9pbignICcpKTtcblxuICAgIGNvbnNvbGUubG9nLmFwcGx5KFxuICAgICAgICAgIGNvbnNvbGVcbiAgICAgICAgLCBbIHRoaXMubG9nUHJlZml4Q29sb3JcbiAgICAgICAgICAgICAgPyAnICAgJyArIGNvbG9yZWQodGhpcy5sb2dQcmVmaXgsIHRoaXMubG9nUHJlZml4Q29sb3IpXG4gICAgICAgICAgICAgIDogdGhpcy5sb2dQcmVmaXgsXG4gICAgICAgICAgICAodGhpcy5jb2xvcnNcbiAgICAgICAgICAgICAgPyAnICcgKyBjb2xvcmVkKHBhZCh0eXBlKSwgY29sb3JzW2luZGV4XSlcbiAgICAgICAgICAgICAgOiB0eXBlKSArICc6J1xuICAgICAgICAgIF0uY29uY2F0KGFyZ3MpXG4gICAgKTtcblxuICAgIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZSBtZXRob2RzLlxuICovXG5cbmxldmVscy5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgTG9nZ2VyLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5sb2cuYXBwbHkodGhpcywgW25hbWVdLmNvbmNhdChfLnRvQXJyYXkoYXJndW1lbnRzKSkpO1xuICAgIH07XG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IExvZ2dlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gbWlsby51dGlscy5yZXF1ZXN0XG4vLyAtLS0tLS0tLS0tLVxuXG4vLyBDb252ZW5pZW5jZSBmdW5jdGlvbnMgd3JhcHBpbmcgWE1MSFRUUFJlcXVlc3QgZnVuY3Rpb25hbGl0eS5cblxuLy8gYGBgXG4vLyB2YXIgcmVxdWVzdCA9IG1pbG8udXRpbHMucmVxdWVzdFxuLy8gICAgICwgb3B0czogeyBtZXRob2Q6ICdHRVQnIH07XG5cbi8vIHJlcXVlc3QodXJsLCBvcHRzLCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbi8vICAgICBsb2dnZXIuZGVidWcoZGF0YSk7XG4vLyB9KTtcblxuLy8gcmVxdWVzdC5nZXQodXJsLCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbi8vICAgICBsb2dnZXIuZGVidWcoZGF0YSk7XG4vLyB9KTtcbi8vIGBgYFxuXG4vLyBPbmx5IGdlbmVyaWMgcmVxdWVzdCBhbmQgZ2V0LCBqc29uLCBwb3N0IGNvbnZlbmllbmNlIG1ldGhvZHMgYXJlIGN1cnJlbnRseSBpbXBsZW1lbnRlZC5cblxuXG52YXIgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjb3VudCA9IHJlcXVpcmUoJy4vY291bnQnKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4vbG9nZ2VyJylcbiAgICAsIE1lc3NlbmdlciA9IHJlcXVpcmUoJy4uL21lc3NlbmdlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3Q7XG5cblxudmFyIF9wZW5kaW5nUmVxdWVzdHMgPSBbXTtcblxudmFyIHByb21pc2VUaGVuID0gY3JlYXRlUHJvbWlzZU92ZXJyaWRlKCd0aGVuJyk7XG52YXIgcHJvbWlzZUNhdGNoID0gY3JlYXRlUHJvbWlzZU92ZXJyaWRlKCdjYXRjaCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB3aGljaCBpcyB1c2VkIHRvIG92ZXJyaWRlIHN0YW5kYXJkIHByb21pc2UgYmVoYXZpb3VyIGFuZCBhbGxvdyBwcm9taXNlIGluc3RhbmNlcyBcbiAqIGNyZWF0ZWQgdG8gbWFpbnRhaW4gYSByZWZlcmVuY2UgdG8gdGhlIHJlcXVlc3Qgb2JqZWN0IG5vIG1hdHRlciBpZiAudGhlbigpIG9yIC5jYXRjaCgpIGlzIGNhbGxlZC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUHJvbWlzZU92ZXJyaWRlKGZ1bmN0aW9uTmFtZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHByb21pc2UgPSBQcm9taXNlLnByb3RvdHlwZVtmdW5jdGlvbk5hbWVdLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGtlZXBSZXF1ZXN0T2JqZWN0KHByb21pc2UsIHRoaXMuX3JlcXVlc3QpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gcmVxdWVzdCh1cmwsIG9wdHMsIGNhbGxiYWNrKSB7XG4gICAgb3B0cy51cmwgPSB1cmw7XG4gICAgb3B0cy5jb250ZW50VHlwZSA9IG9wdHMuY29udGVudFR5cGUgfHwgJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD1VVEYtOCc7XG4gICAgaWYgKF9tZXNzZW5nZXIpIHJlcXVlc3QucG9zdE1lc3NhZ2VTeW5jKCdyZXF1ZXN0JywgeyBvcHRpb25zOiBvcHRzIH0pO1xuXG4gICAgdmFyIHJlcSA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIHJlcS5vcGVuKG9wdHMubWV0aG9kLCBvcHRzLnVybCwgdHJ1ZSk7XG4gICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsIG9wdHMuY29udGVudFR5cGUpO1xuICAgIHNldFJlcXVlc3RIZWFkZXJzKHJlcSwgb3B0cy5oZWFkZXJzKTtcblxuICAgIHJlcS50aW1lb3V0ID0gb3B0cy50aW1lb3V0IHx8IGNvbmZpZy5yZXF1ZXN0LmRlZmF1bHRzLnRpbWVvdXQ7XG4gICAgcmVxLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHJlcS5vbnRpbWVvdXQgPSByZXEub25hYm9ydCA9IG9uUmVhZHk7XG5cbiAgICB2YXIgeFByb21pc2UgPSBfY3JlYXRlWFByb21pc2UocmVxKTtcblxuICAgIHJlcS5zZW5kKEpTT04uc3RyaW5naWZ5KG9wdHMuZGF0YSkpO1xuICAgIHJlcVtjb25maWcucmVxdWVzdC5vcHRpb25zS2V5XSA9IG9wdHM7XG5cbiAgICBfcGVuZGluZ1JlcXVlc3RzLnB1c2gocmVxKTtcblxuICAgIHJldHVybiB4UHJvbWlzZS5wcm9taXNlO1xuXG4gICAgZnVuY3Rpb24gb25SZWFkeShlKSB7XG4gICAgICAgIF9vblJlYWR5KHJlcSwgY2FsbGJhY2ssIHhQcm9taXNlLCBlLnR5cGUpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBfY3JlYXRlWFByb21pc2UocmVxdWVzdCkge1xuICAgIHZhciByZXNvbHZlUHJvbWlzZSwgcmVqZWN0UHJvbWlzZTtcbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgfSk7XG5cbiAgICBrZWVwUmVxdWVzdE9iamVjdChwcm9taXNlLCByZXF1ZXN0KTtcbiAgICBwcm9taXNlLmNhdGNoKF8ubm9vcCk7IC8vIFNvbWV0aW1lcyBlcnJvcnMgYXJlIGhhbmRsZWQgd2l0aGluIGNhbGxiYWNrcywgc28gdW5jYXVnaHQgcHJvbWlzZSBlcnJvciBtZXNzYWdlIHNob3VsZCBiZSBzdXBwcmVzc2VkLlxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgcHJvbWlzZTogcHJvbWlzZSxcbiAgICAgICAgcmVzb2x2ZTogcmVzb2x2ZVByb21pc2UsXG4gICAgICAgIHJlamVjdDogcmVqZWN0UHJvbWlzZVxuICAgIH1cbn1cblxuLy8gRW5zdXJlcyB0aGF0IHRoZSBwcm9taXNlIChhbmQgYW55IHByb21pc2VzIGNyZWF0ZWQgd2hlbiBjYWxsaW5nIC50aGVuLy5jYXRjaCkgaGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBvcmlnaW5hbCByZXF1ZXN0IG9iamVjdFxuZnVuY3Rpb24ga2VlcFJlcXVlc3RPYmplY3QocHJvbWlzZSwgcmVxdWVzdCkge1xuICAgIHByb21pc2UuX3JlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHByb21pc2UudGhlbiA9IHByb21pc2VUaGVuO1xuICAgIHByb21pc2UuY2F0Y2ggPSBwcm9taXNlQ2F0Y2g7XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuXG5mdW5jdGlvbiBzZXRSZXF1ZXN0SGVhZGVycyhyZXEsIGhlYWRlcnMpIHtcbiAgICBpZiAoaGVhZGVycylcbiAgICAgICAgXy5lYWNoS2V5KGhlYWRlcnMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsdWUpO1xuICAgICAgICB9KTtcbn1cblxuZnVuY3Rpb24gX29uUmVhZHkocmVxLCBjYWxsYmFjaywgeFByb21pc2UsIGV2ZW50VHlwZSkge1xuICAgIGlmIChyZXEucmVhZHlTdGF0ZSAhPSA0KSByZXR1cm47XG4gICAgaWYgKCFyZXEuc3RhdHVzICYmIGV2ZW50VHlwZSA9PSAncmVhZHlzdGF0ZWNoYW5nZScpIHJldHVybjtcblxuICAgIF8uc3BsaWNlSXRlbShfcGVuZGluZ1JlcXVlc3RzLCByZXEpO1xuXG4gICAgdmFyIGVycm9yO1xuICAgIHRyeSB7XG4gICAgICAgIGlmICggcmVxLnN0YXR1cyA+PSAyMDAgJiYgcmVxLnN0YXR1cyA8IDQwMCApIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoJ3N1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsLCByZXEucmVzcG9uc2VUZXh0LCByZXEpO1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7IGVycm9yID0gZTsgfVxuICAgICAgICAgICAgeFByb21pc2UucmVzb2x2ZShyZXEucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBlcnJvclJlYXNvbiA9IHJlcS5zdGF0dXMgfHwgZXZlbnRUeXBlO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSgnZXJyb3InKTtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSgnZXJyb3InICsgZXJyb3JSZWFzb24pO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKGVycm9yUmVhc29uLCByZXEucmVzcG9uc2VUZXh0LCByZXEpO1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7IGVycm9yID0gZTsgfVxuICAgICAgICAgICAgeFByb21pc2UucmVqZWN0KHsgcmVhc29uOiBlcnJvclJlYXNvbiwgcmVzcG9uc2U6IHJlcS5yZXNwb25zZVRleHQgfSk7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgZXJyb3IgPSBlcnJvciB8fCBlO1xuICAgIH1cblxuICAgIC8vIG5vdCByZW1vdmluZyBzdWJzY3JpcHRpb24gY3JlYXRlcyBtZW1vcnkgbGVhaywgZGVsZXRpbmcgcHJvcGVydHkgd291bGQgbm90IHJlbW92ZSBzdWJzY3JpcHRpb25cbiAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlID0gcmVxLm9udGltZW91dCA9IHJlcS5vbmFib3J0ID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFfcGVuZGluZ1JlcXVlc3RzLmxlbmd0aClcbiAgICAgICAgcG9zdE1lc3NhZ2UoJ3JlcXVlc3RzY29tcGxldGVkJyk7XG5cbiAgICBpZiAoZXJyb3IpIHRocm93IG5ldyBFcnJvcignRXhjZXB0aW9uOiAnICsgZXJyb3IpO1xuXG4gICAgZnVuY3Rpb24gcG9zdE1lc3NhZ2UobXNnKSB7XG4gICAgICAgIGlmIChfbWVzc2VuZ2VyKSByZXF1ZXN0LnBvc3RNZXNzYWdlKG1zZyxcbiAgICAgICAgICAgIHsgc3RhdHVzOiBzdGF0dXMsIHJlc3BvbnNlOiByZXEucmVzcG9uc2VUZXh0IH0pO1xuICAgIH1cbn1cblxuXG5fLmV4dGVuZChyZXF1ZXN0LCB7XG4gICAgZ2V0OiByZXF1ZXN0JGdldCxcbiAgICBwb3N0OiByZXF1ZXN0JHBvc3QsXG4gICAganNvbjogcmVxdWVzdCRqc29uLFxuICAgIGpzb25wOiByZXF1ZXN0JGpzb25wLFxuICAgIGZpbGU6IHJlcXVlc3QkZmlsZSxcbiAgICB1c2VNZXNzZW5nZXI6IHJlcXVlc3QkdXNlTWVzc2VuZ2VyLFxuICAgIGRlc3Ryb3k6IHJlcXVlc3QkZGVzdHJveSxcbiAgICB3aGVuUmVxdWVzdHNDb21wbGV0ZWQ6IHdoZW5SZXF1ZXN0c0NvbXBsZXRlZFxufSk7XG5cblxudmFyIF9tZXNzZW5nZXI7XG5cblxuZnVuY3Rpb24gcmVxdWVzdCR1c2VNZXNzZW5nZXIoKSB7XG4gICAgX21lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXIocmVxdWVzdCwgWydvbicsICdvbmNlJywgJ29uU3luYycsICdvZmYnLCAnb25NZXNzYWdlcycsICdvZmZNZXNzYWdlcycsICdwb3N0TWVzc2FnZScsICdwb3N0TWVzc2FnZVN5bmMnXSk7XG59XG5cblxuZnVuY3Rpb24gcmVxdWVzdCRnZXQodXJsLCBjYWxsYmFjaykge1xuICAgIHJldHVybiByZXF1ZXN0KHVybCwgeyBtZXRob2Q6ICdHRVQnIH0sIGNhbGxiYWNrKTtcbn1cblxuXG5mdW5jdGlvbiByZXF1ZXN0JHBvc3QodXJsLCBkYXRhLCBjYWxsYmFjaykge1xuICAgIHJldHVybiByZXF1ZXN0KHVybCwgeyBtZXRob2Q6ICdQT1NUJywgZGF0YTogZGF0YSB9LCBjYWxsYmFjayk7XG59XG5cblxuZnVuY3Rpb24gcmVxdWVzdCRqc29uKHVybCwgY2FsbGJhY2spIHtcbiAgICB2YXIgcHJvbWlzZSA9IHJlcXVlc3QodXJsLCB7IG1ldGhvZDogJ0dFVCcgfSk7XG5cbiAgICB2YXIganNvblByb21pc2UgPSBwcm9taXNlLnRoZW4oSlNPTi5wYXJzZSk7XG5cbiAgICBpZiAoY2FsbGJhY2spXG4gICAgICAgIGpzb25Qcm9taXNlXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uKGRhdGEpIHsgY2FsbGJhY2sobnVsbCwgZGF0YSk7IH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbihlcnJEYXRhKSB7IGNhbGxiYWNrKGVyckRhdGEucmVhc29uLCBlcnJEYXRhLnJlc3BvbnNlKTsgfSk7XG5cbiAgICByZXR1cm4ganNvblByb21pc2U7XG59XG5cblxudmFyIGpzb25wT3B0aW9ucyA9IHsgbWV0aG9kOiAnR0VUJywganNvbnA6IHRydWUgfTtcbmZ1bmN0aW9uIHJlcXVlc3QkanNvbnAodXJsLCBjYWxsYmFjaykge1xuICAgIHZhciBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSxcbiAgICAgICAgeFByb21pc2UgPSBfY3JlYXRlWFByb21pc2Uoc2NyaXB0KSxcbiAgICAgICAgaGVhZCA9IHdpbmRvdy5kb2N1bWVudC5oZWFkLFxuICAgICAgICB1bmlxdWVDYWxsYmFjayA9IGNvbmZpZy5yZXF1ZXN0Lmpzb25wQ2FsbGJhY2tQcmVmaXggKyBjb3VudCgpO1xuXG4gICAgdmFyIG9wdHMgPSBfLmV4dGVuZCh7IHVybDogdXJsIH0sIGpzb25wT3B0aW9ucyk7XG4gICAgaWYgKF9tZXNzZW5nZXIpIHJlcXVlc3QucG9zdE1lc3NhZ2VTeW5jKCdyZXF1ZXN0JywgeyBvcHRpb25zOiBvcHRzIH0pO1xuXG4gICAgaWYgKCEgXy5pc0VxdWFsKF8ub21pdEtleXMob3B0cywgJ3VybCcpLCBqc29ucE9wdGlvbnMpKVxuICAgICAgICBsb2dnZXIud2FybignSWdub3JlZCBub3QgYWxsb3dlZCByZXF1ZXN0IG9wdGlvbnMgY2hhbmdlIGluIEpTT05QIHJlcXVlc3QgLSBvbmx5IFVSTCBjYW4gYmUgY2hhbmdlZCcpO1xuXG4gICAgdmFyIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdObyBKU09OUCByZXNwb25zZSBvciBubyBjYWxsYmFjayBpbiByZXNwb25zZScpO1xuICAgICAgICBfb25SZXN1bHQoZXJyKTtcbiAgICB9LCBjb25maWcucmVxdWVzdC5qc29ucFRpbWVvdXQpO1xuXG4gICAgd2luZG93W3VuaXF1ZUNhbGxiYWNrXSA9IF8ucGFydGlhbChfb25SZXN1bHQsIG51bGwpO1xuXG4gICAgX3BlbmRpbmdSZXF1ZXN0cy5wdXNoKHdpbmRvd1t1bmlxdWVDYWxsYmFja10pO1xuXG4gICAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0JztcbiAgICBzY3JpcHQuc3JjID0gb3B0cy51cmwgKyAob3B0cy51cmwuaW5kZXhPZignPycpID09IC0xID8gJz8nIDogJyYnKSArICdjYWxsYmFjaz0nICsgdW5pcXVlQ2FsbGJhY2s7XG5cbiAgICBoZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG5cbiAgICByZXR1cm4geFByb21pc2UucHJvbWlzZTtcblxuXG4gICAgZnVuY3Rpb24gX29uUmVzdWx0KGVyciwgcmVzdWx0KSB7XG4gICAgICAgIF8uc3BsaWNlSXRlbShfcGVuZGluZ1JlcXVlc3RzLCB3aW5kb3dbdW5pcXVlQ2FsbGJhY2tdKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBvc3RNZXNzYWdlKGVyciA/ICdlcnJvcicgOiAnc3VjY2VzcycsIGVyciwgcmVzdWx0KTtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ05vIEpTT05QIHJlc3BvbnNlIG9yIHRpbWVvdXQnKTtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSgnZXJyb3Jqc29ucHRpbWVvdXQnLCBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soZXJyLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoKGUpIHsgdmFyIGVycm9yID0gZTsgfVxuICAgICAgICBpZiAoZXJyKSB4UHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgZWxzZSB4UHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG5cbiAgICAgICAgY2xlYW5VcCgpO1xuICAgICAgICBpZiAoIV9wZW5kaW5nUmVxdWVzdHMubGVuZ3RoKVxuICAgICAgICAgICAgcG9zdE1lc3NhZ2UoJ3JlcXVlc3RzY29tcGxldGVkJyk7XG5cbiAgICAgICAgaWYgKGVycm9yKSB0aHJvdyBlcnJvcjtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIGNsZWFuVXAoKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpO1xuICAgICAgICBkZWxldGUgd2luZG93W3VuaXF1ZUNhbGxiYWNrXTtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1zZywgc3RhdHVzLCByZXN1bHQpIHtcbiAgICAgICAgaWYgKF9tZXNzZW5nZXIpIHJlcXVlc3QucG9zdE1lc3NhZ2UobXNnLFxuICAgICAgICAgICAgeyBzdGF0dXM6IHN0YXR1cywgcmVzcG9uc2U6IHJlc3VsdCB9KTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gcmVxdWVzdCRmaWxlKG9wdHMsIGZpbGVEYXRhLCBjYWxsYmFjaywgcHJvZ3Jlc3MpIHtcbiAgICBpZiAodHlwZW9mIG9wdHMgPT0gJ3N0cmluZycpXG4gICAgICAgIG9wdHMgPSB7IG1ldGhvZDogJ1BPU1QnLCB1cmw6IG9wdHMgfTtcblxuICAgIG9wdHMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ1BPU1QnO1xuICAgIG9wdHMuZmlsZSA9IHRydWU7XG5cbiAgICBpZiAoX21lc3NlbmdlcikgcmVxdWVzdC5wb3N0TWVzc2FnZVN5bmMoJ3JlcXVlc3QnLCB7IG9wdGlvbnM6IG9wdHMgfSk7XG5cbiAgICB2YXIgcmVxID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgaWYgKHByb2dyZXNzKSByZXEudXBsb2FkLm9ucHJvZ3Jlc3MgPSBwcm9ncmVzcztcblxuICAgIHJlcS5vcGVuKG9wdHMubWV0aG9kLCBvcHRzLnVybCwgdHJ1ZSk7XG4gICAgc2V0UmVxdWVzdEhlYWRlcnMocmVxLCBvcHRzLmhlYWRlcnMpO1xuXG4gICAgcmVxLnRpbWVvdXQgPSBvcHRzLnRpbWVvdXQgfHwgY29uZmlnLnJlcXVlc3QuZGVmYXVsdHMudGltZW91dDtcbiAgICByZXEub25yZWFkeXN0YXRlY2hhbmdlID0gcmVxLm9udGltZW91dCA9IHJlcS5vbmFib3J0ID0gb25SZWFkeTtcblxuICAgIHZhciB4UHJvbWlzZSA9IF9jcmVhdGVYUHJvbWlzZShyZXEpO1xuXG4gICAgaWYgKG9wdHMuYmluYXJ5KVxuICAgICAgICByZXEuc2VuZChmaWxlRGF0YSk7XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlRGF0YSk7XG4gICAgICAgIHJlcS5zZW5kKGZvcm1EYXRhKTtcbiAgICB9XG5cbiAgICBfcGVuZGluZ1JlcXVlc3RzLnB1c2gocmVxKTtcblxuICAgIHJldHVybiB4UHJvbWlzZS5wcm9taXNlO1xuXG4gICAgZnVuY3Rpb24gb25SZWFkeShlKSB7XG4gICAgICAgIGlmIChwcm9ncmVzcykgcmVxLnVwbG9hZC5vbnByb2dyZXNzID0gdW5kZWZpbmVkO1xuICAgICAgICBfb25SZWFkeShyZXEsIGNhbGxiYWNrLCB4UHJvbWlzZSwgZS50eXBlKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gcmVxdWVzdCRkZXN0cm95KCkge1xuICAgIGlmIChfbWVzc2VuZ2VyKSBfbWVzc2VuZ2VyLmRlc3Ryb3koKTtcbiAgICByZXF1ZXN0Ll9kZXN0cm95ZWQgPSB0cnVlO1xufVxuXG5cbmZ1bmN0aW9uIHdoZW5SZXF1ZXN0c0NvbXBsZXRlZChjYWxsYmFjaywgdGltZW91dCkge1xuICAgIGNhbGxiYWNrID0gXy5vbmNlKGNhbGxiYWNrKTtcbiAgICBpZiAodGltZW91dClcbiAgICAgICAgXy5kZWxheShjYWxsYmFjaywgdGltZW91dCwgJ3RpbWVvdXQnKTtcblxuICAgIGlmIChfcGVuZGluZ1JlcXVlc3RzLmxlbmd0aClcbiAgICAgICAgX21lc3Nlbmdlci5vbmNlKCdyZXF1ZXN0c2NvbXBsZXRlZCcsIGNhbGxiYWNrKTtcbiAgICBlbHNlXG4gICAgICAgIF8uZGVmZXIoY2FsbGJhY2spO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBkb21VdGlscyA9IHJlcXVpcmUoJy4uL2RvbScpXG4gICAgLCBjb250YWluaW5nRWxlbWVudCA9IGRvbVV0aWxzLmNvbnRhaW5pbmdFbGVtZW50XG4gICAgLCBzZXRDYXJldFBvc2l0aW9uID0gZG9tVXRpbHMuc2V0Q2FyZXRQb3NpdGlvblxuICAgICwgZ2V0Q29tcG9uZW50c0Zyb21SYW5nZSA9IGRvbVV0aWxzLmdldENvbXBvbmVudHNGcm9tUmFuZ2VcbiAgICAsIGRlbGV0ZVJhbmdlV2l0aENvbXBvbmVudHMgPSBkb21VdGlscy5kZWxldGVSYW5nZVdpdGhDb21wb25lbnRzXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi9sb2dnZXInKVxuICAgICwgQ29tcG9uZW50ID0gcmVxdWlyZSgnLi4vLi4vY29tcG9uZW50cy9jX2NsYXNzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBUZXh0U2VsZWN0aW9uO1xuXG5cbi8qKlxuICogVGV4dCBzZWxlY3Rpb24gY2xhc3MuXG4gKiBTZXJ2ZXMgYXMgYSBoZWxwZXIgdG8gbWFuYWdlIGN1cnJlbnQgc2VsZWN0aW9uXG4gKiBUaGUgb2JqZWN0IGNhbm5vdCBiZSByZXVzZWQsIGlmIHRoZSBzZWxlY3Rpb24gY2hhbmdlcyBzb21lIG9mIGl0cyBwcm9wZXJ0aWVzIG1heSBjb250YWluIGluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gcHJldmlvdXMgc2VsZWN0aW9uXG4gKlxuICogQHBhcmFtIHtXaW5kb3d9IHdpbiB3aW5kb3cgaW4gd2hpY2ggdGV4dCBzZWxlY3Rpb24gaXMgcHJvY2Vzc2VkXG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24od2luKSB7XG4gICAgaWYgKCEgdGhpcyBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24pXG4gICAgICAgIHJldHVybiBuZXcgVGV4dFNlbGVjdGlvbih3aW4pO1xuICAgIHRoaXMud2luZG93ID0gd2luIHx8IHdpbmRvdztcbiAgICB0aGlzLmluaXQoKTtcbn1cblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNlbGVjdGlvbiBzdGFydCBlbGVtZW50XG4gKlxuICogQHJldHVybiB7RWxlbWVudHxudWxsfVxuICovXG52YXIgVGV4dFNlbGVjdGlvbiRzdGFydEVsZW1lbnQgPSBcbiAgICBfLnBhcnRpYWwoX2dldEVsZW1lbnQsICdfc3RhcnRFbGVtZW50JywgJ3N0YXJ0Q29udGFpbmVyJyk7XG5cblxuLyoqXG4gKiBUZXh0U2VsZWN0aW9uIGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBzZWxlY3Rpb24gZW5kIGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtFbGVtZW50fG51bGx9XG4gKi9cbnZhciBUZXh0U2VsZWN0aW9uJGVuZEVsZW1lbnQgPSBcbiAgICBfLnBhcnRpYWwoX2dldEVsZW1lbnQsICdfZW5kRWxlbWVudCcsICdlbmRDb250YWluZXInKTtcblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNlbGVjdGlvbiBlbmQgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge0VsZW1lbnR8bnVsbH1cbiAqL1xudmFyIFRleHRTZWxlY3Rpb24kY29udGFpbmluZ0VsZW1lbnQgPSBcbiAgICBfLnBhcnRpYWwoX2dldEVsZW1lbnQsICdfY29udGFpbmluZ0VsZW1lbnQnLCAnY29tbW9uQW5jZXN0b3JDb250YWluZXInKTtcblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNlbGVjdGlvbiBzdGFydCBDb21wb25lbnRcbiAqXG4gKiBAcmV0dXJuIHtDb21wb25lbnR9XG4gKi9cbnZhciBUZXh0U2VsZWN0aW9uJHN0YXJ0Q29tcG9uZW50ID0gXG4gICAgXy5wYXJ0aWFsKF9nZXRDb21wb25lbnQsICdfc3RhcnRDb21wb25lbnQnLCAnc3RhcnRFbGVtZW50Jyk7XG5cblxuLyoqXG4gKiBUZXh0U2VsZWN0aW9uIGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBzZWxlY3Rpb24gZW5kIENvbXBvbmVudFxuICpcbiAqIEByZXR1cm4ge0NvbXBvbmVudH1cbiAqL1xudmFyIFRleHRTZWxlY3Rpb24kZW5kQ29tcG9uZW50ID0gXG4gICAgXy5wYXJ0aWFsKF9nZXRDb21wb25lbnQsICdfZW5kQ29tcG9uZW50JywgJ2VuZEVsZW1lbnQnKTtcblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXR1cm5zIHNlbGVjdGlvbiBlbmQgQ29tcG9uZW50XG4gKlxuICogQHJldHVybiB7Q29tcG9uZW50fVxuICovXG52YXIgVGV4dFNlbGVjdGlvbiRjb250YWluaW5nQ29tcG9uZW50ID0gXG4gICAgXy5wYXJ0aWFsKF9nZXRDb21wb25lbnQsICdfY29udGFpbmluZ0NvbXBvbmVudCcsICdjb250YWluaW5nRWxlbWVudCcpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oVGV4dFNlbGVjdGlvbiwge1xuICAgIGluaXQ6IFRleHRTZWxlY3Rpb24kaW5pdCxcbiAgICB0ZXh0OiBUZXh0U2VsZWN0aW9uJHRleHQsXG4gICAgdGV4dE5vZGVzOiBUZXh0U2VsZWN0aW9uJHRleHROb2RlcyxcbiAgICBjbGVhcjogVGV4dFNlbGVjdGlvbiRjbGVhcixcblxuICAgIHN0YXJ0RWxlbWVudDogVGV4dFNlbGVjdGlvbiRzdGFydEVsZW1lbnQsXG4gICAgZW5kRWxlbWVudDogVGV4dFNlbGVjdGlvbiRlbmRFbGVtZW50LFxuICAgIGNvbnRhaW5pbmdFbGVtZW50OiBUZXh0U2VsZWN0aW9uJGNvbnRhaW5pbmdFbGVtZW50LFxuXG4gICAgc3RhcnRDb21wb25lbnQ6IFRleHRTZWxlY3Rpb24kc3RhcnRDb21wb25lbnQsXG4gICAgZW5kQ29tcG9uZW50OiBUZXh0U2VsZWN0aW9uJGVuZENvbXBvbmVudCxcbiAgICBjb250YWluaW5nQ29tcG9uZW50OiBUZXh0U2VsZWN0aW9uJGNvbnRhaW5pbmdDb21wb25lbnQsXG5cbiAgICBjb250YWluZWRDb21wb25lbnRzOiBUZXh0U2VsZWN0aW9uJGNvbnRhaW5lZENvbXBvbmVudHMsXG4gICAgZWFjaENvbnRhaW5lZENvbXBvbmVudDogVGV4dFNlbGVjdGlvbiRlYWNoQ29udGFpbmVkQ29tcG9uZW50LFxuICAgIGRlbDogVGV4dFNlbGVjdGlvbiRkZWwsXG4gICAgX2dldFBvc3REZWxldGVTZWxlY3Rpb25Qb2ludDogX2dldFBvc3REZWxldGVTZWxlY3Rpb25Qb2ludCxcbiAgICBfc2VsZWN0QWZ0ZXJEZWxldGU6IF9zZWxlY3RBZnRlckRlbGV0ZSxcblxuICAgIGdldFJhbmdlOiBUZXh0U2VsZWN0aW9uJGdldFJhbmdlLFxuICAgIGdldFN0YXRlOiBUZXh0U2VsZWN0aW9uJGdldFN0YXRlLFxuICAgIGdldE5vcm1hbGl6ZWRSYW5nZTogVGV4dFNlbGVjdGlvbiQkZ2V0Tm9ybWFsaXplZFJhbmdlLFxuICAgIGdldERpcmVjdGlvbjogVGV4dFNlbGVjdGlvbiQkZ2V0RGlyZWN0aW9uXG59KTtcblxuXG5fLmV4dGVuZChUZXh0U2VsZWN0aW9uLCB7XG4gICAgY3JlYXRlRnJvbVJhbmdlOiBUZXh0U2VsZWN0aW9uJCRjcmVhdGVGcm9tUmFuZ2UsXG4gICAgY3JlYXRlRnJvbVN0YXRlOiBUZXh0U2VsZWN0aW9uJCRjcmVhdGVGcm9tU3RhdGUsXG4gICAgY3JlYXRlU3RhdGVPYmplY3Q6IFRleHRTZWxlY3Rpb24kJGNyZWF0ZVN0YXRlT2JqZWN0XG59KTtcblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplcyBUZXh0U2VsZWN0aW9uIGZyb20gdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kaW5pdCgpIHtcbiAgICB0aGlzLnNlbGVjdGlvbiA9IHRoaXMud2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICh0aGlzLnNlbGVjdGlvbi5yYW5nZUNvdW50KVxuICAgICAgICB0aGlzLnJhbmdlID0gdGhpcy5zZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcbiAgICB0aGlzLmlzQ29sbGFwc2VkID0gdGhpcy5zZWxlY3Rpb24uaXNDb2xsYXBzZWQ7XG59XG5cblxuLyoqXG4gKiBUZXh0U2VsZWN0aW9uIGluc3RhbmNlIG1ldGhvZFxuICogUmV0cmlldmVzIGFuZCByZXR1cm5zIHNlbGVjdGlvbiB0ZXh0XG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJHRleHQoKSB7XG4gICAgaWYgKCEgdGhpcy5yYW5nZSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGlmICghIHRoaXMuX3RleHQpXG4gICAgICAgIHRoaXMuX3RleHQgPSB0aGlzLnJhbmdlLnRvU3RyaW5nKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fdGV4dDtcbn1cblxuXG4vKipcbiAqIFRleHRTZWxlY3Rpb24gaW5zdGFuY2UgbWV0aG9kXG4gKiBSZXRyaWV2ZXMgYW5kIHJldHVybnMgc2VsZWN0aW9uIHRleHQgbm9kZXNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheVtOb2RlXX1cbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiR0ZXh0Tm9kZXMoKSB7XG4gICAgaWYgKCEgdGhpcy5yYW5nZSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGlmICghIHRoaXMuX3RleHROb2RlcylcbiAgICAgICAgdGhpcy5fdGV4dE5vZGVzID0gX2dldFRleHROb2Rlcy5jYWxsKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLl90ZXh0Tm9kZXM7XG59XG5cblxuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiRjbGVhcigpIHtcbiAgICB0aGlzLnNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbn1cblxuXG4vKipcbiAqIFJldHJpZXZlcyB0ZXh0IGFuZCB0ZXh0IG5vZGVzIGZyb20gc2VsZWN0aW9uIHNhdmluZyB0aGVtIG9uIHByb3BlcnRpZXMgb2Ygb2JqZWN0XG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7VGV4dFNlbGVjdGlvbn0gdGhpc1xuICovXG5mdW5jdGlvbiBfZ2V0VGV4dE5vZGVzKCkge1xuICAgIC8vIGxpc3Qgb2Ygc2VsZWN0ZWQgdGV4dCBub2Rlc1xuICAgIHZhciB0ZXh0Tm9kZXMgPSBbXTtcblxuICAgIGlmICh0aGlzLmlzQ29sbGFwc2VkKVxuICAgICAgICByZXR1cm4gdGV4dE5vZGVzO1xuXG4gICAgLy8gY3JlYXRlIFRyZWVXYWxrZXIgdG8gdHJhdmVyc2UgdGhlIHRyZWUgdG8gc2VsZWN0IGFsbCB0ZXh0IG5vZGVzXG4gICAgdmFyIHNlbFN0YXJ0ID0gdGhpcy5yYW5nZS5zdGFydENvbnRhaW5lclxuICAgICAgICAsIHNlbEVuZCA9IHRoaXMucmFuZ2UuZW5kQ29udGFpbmVyXG4gICAgICAgICwgcmFuZ2VDb250YWluZXIgPSB0aGlzLnJhbmdlLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xuXG4gICAgdmFyIHRyZWVXYWxrZXIgPSB0aGlzLndpbmRvdy5kb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHJhbmdlQ29udGFpbmVyLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCk7XG4gICAgdmFyIG5vZGUgPSB0cmVlV2Fsa2VyLmN1cnJlbnROb2RlID0gc2VsU3RhcnQ7XG5cbiAgICAvLyB0cmF2ZXJzZSBET00gdHJlZSB0byBjb2xsZWN0IGFsbCBzZWxlY3RlZCB0ZXh0IG5vZGVzXG4gICAgd2hpbGUgKG5vZGUgJiYgKCEgaW5FbmQgfHwgc2VsRW5kLmNvbnRhaW5zKG5vZGUpKSkge1xuICAgICAgICB0ZXh0Tm9kZXMucHVzaChub2RlKTtcbiAgICAgICAgdmFyIGluRW5kID0gaW5FbmQgfHwgc2VsRW5kLmNvbnRhaW5zKG5vZGUpO1xuICAgICAgICBub2RlID0gdHJlZVdhbGtlci5uZXh0Tm9kZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGV4dE5vZGVzO1xufVxuXG5cbi8qKlxuICogUmV0cmlldmVzIGFuZCByZXR1cm5zIHN0YXJ0L2VuZCBlbGVtZW50IGZyb20gc2VsZWN0aW9uIHNhdmluZyB0aGVtIG9uIHByb3BlcnRpZXMgb2Ygb2JqZWN0XG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7VGV4dFNlbGVjdGlvbn0gdGhpc1xuICogQHJldHVybiB7RWxlbWVudHxudWxsfVxuICovXG5mdW5jdGlvbiBfZ2V0RWxlbWVudCh0aGlzUHJvcE5hbWUsIHJhbmdlUHJvcE5hbWUpIHtcbiAgICBpZiAoISB0aGlzLnJhbmdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzW3RoaXNQcm9wTmFtZV0gPT0gJ3VuZGVmaW5lZCcpXG4gICAgICAgIHRoaXNbdGhpc1Byb3BOYW1lXSA9IGNvbnRhaW5pbmdFbGVtZW50KHRoaXMucmFuZ2VbcmFuZ2VQcm9wTmFtZV0pO1xuICAgIHJldHVybiB0aGlzW3RoaXNQcm9wTmFtZV07XG59XG5cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIHJldHVybnMgc3RhcnQvZW5kIGNvbXBvbmVudCBmcm9tIHNlbGVjdGlvbiBzYXZpbmcgdGhlbSBvbiBwcm9wZXJ0aWVzIG9mIG9iamVjdFxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1RleHRTZWxlY3Rpb259IHRoaXNcbiAqIEByZXR1cm4ge0NvbXBvbmVudH1cbiAqL1xuZnVuY3Rpb24gX2dldENvbXBvbmVudCh0aGlzUHJvcE5hbWUsIGVsTWV0aG9kTmFtZSkge1xuICAgIGlmICghIHRoaXMucmFuZ2UpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBpZiAodHlwZW9mIHRoaXNbdGhpc1Byb3BOYW1lXSA9PSAndW5kZWZpbmVkJylcbiAgICAgICAgdGhpc1t0aGlzUHJvcE5hbWVdID0gQ29tcG9uZW50LmdldENvbnRhaW5pbmdDb21wb25lbnQodGhpc1tlbE1ldGhvZE5hbWVdKCkpO1xuICAgIHJldHVybiB0aGlzW3RoaXNQcm9wTmFtZV07XG59XG5cblxuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiRjb250YWluZWRDb21wb25lbnRzKCkge1xuICAgIGlmICh0aGlzLl9jb250YWluZWRDb21wb25lbnRzKVxuICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVkQ29tcG9uZW50cztcblxuICAgIHZhciBjb21wb25lbnRzID0gdGhpcy5fY29udGFpbmVkQ29tcG9uZW50cyA9IFtdO1xuXG4gICAgaWYgKHRoaXMuaXNDb2xsYXBzZWQgfHwgISB0aGlzLnJhbmdlKSByZXR1cm4gY29tcG9uZW50cztcblxuICAgIHJldHVybiBnZXRDb21wb25lbnRzRnJvbVJhbmdlKHRoaXMucmFuZ2UpO1xufVxuXG5cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kZWFjaENvbnRhaW5lZENvbXBvbmVudChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIGlmICh0aGlzLmlzQ29sbGFwc2VkIHx8ICEgdGhpcy5yYW5nZSkgcmV0dXJuO1xuXG4gICAgdmFyIGNvbXBvbmVudHMgPSB0aGlzLmNvbnRhaW5lZENvbXBvbmVudHMoKTtcblxuICAgIGNvbXBvbmVudHMuZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZyk7XG59XG5cblxuLyoqXG4gKiBUZXh0U2VsZWN0aW9uIGluc3RhbmNlIG1ldGhvZFxuICogRGVsZXRlcyB0aGUgY3VycmVudCBzZWxlY3Rpb24gYW5kIGFsbCBjb21wb25lbnRzIGluIGl0XG4gKiBcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2VsZWN0RW5kQ29udGFpbmVyIHNldCB0byB0cnVlIGlmIHRoZSBlbmQgY29udGFpbmVyIHNob3VsZCBiZSBzZWxlY3RlZCBhZnRlciBkZWxldGlvblxuICovXG5mdW5jdGlvbiBUZXh0U2VsZWN0aW9uJGRlbChzZWxlY3RFbmRDb250YWluZXIpIHtcbiAgICBpZiAodGhpcy5pc0NvbGxhcHNlZCB8fCAhIHRoaXMucmFuZ2UpIHJldHVybjtcblxuICAgIHZhciBzZWxQb2ludCA9IHRoaXMuX2dldFBvc3REZWxldGVTZWxlY3Rpb25Qb2ludChzZWxlY3RFbmRDb250YWluZXIpO1xuXG4gICAgZGVsZXRlUmFuZ2VXaXRoQ29tcG9uZW50cyh0aGlzLnJhbmdlKTtcblxuICAgIHRoaXMuX3NlbGVjdEFmdGVyRGVsZXRlKHNlbFBvaW50KTtcbiAgICBzZWxQb2ludC5ub2RlLnBhcmVudE5vZGUubm9ybWFsaXplKCk7XG59XG5cblxuZnVuY3Rpb24gX2dldFBvc3REZWxldGVTZWxlY3Rpb25Qb2ludChzZWxlY3RFbmRDb250YWluZXIpIHtcbiAgICB2YXIgc2VsTm9kZSA9IHRoaXMucmFuZ2Uuc3RhcnRDb250YWluZXI7XG4gICAgdmFyIHNlbE9mZnNldCA9IHRoaXMucmFuZ2Uuc3RhcnRPZmZzZXQ7XG4gICAgaWYgKHNlbGVjdEVuZENvbnRhaW5lciAmJiB0aGlzLnJhbmdlLnN0YXJ0Q29udGFpbmVyICE9IHRoaXMucmFuZ2UuZW5kQ29udGFpbmVyKSB7XG4gICAgICAgIHNlbE5vZGUgPSB0aGlzLnJhbmdlLmVuZENvbnRhaW5lcjtcbiAgICAgICAgc2VsT2Zmc2V0ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHsgbm9kZTogc2VsTm9kZSwgb2Zmc2V0OiBzZWxPZmZzZXQgfTtcbn1cblxuXG5mdW5jdGlvbiBfc2VsZWN0QWZ0ZXJEZWxldGUoc2VsUG9pbnQpIHtcbiAgICB2YXIgc2VsTm9kZSA9IHNlbFBvaW50Lm5vZGVcbiAgICAgICAgLCBzZWxPZmZzZXQgPSBzZWxQb2ludC5vZmZzZXQ7XG5cbiAgICBpZiAoIXNlbE5vZGUpIHJldHVybjtcbiAgICBpZiAoc2VsTm9kZS5ub2RlVHlwZSA9PSBOb2RlLlRFWFRfTk9ERSlcbiAgICAgICAgc2VsTm9kZS50ZXh0Q29udGVudCA9IHNlbE5vZGUudGV4dENvbnRlbnQudHJpbVJpZ2h0KCk7XG4gICAgaWYgKCFzZWxOb2RlLm5vZGVWYWx1ZSlcbiAgICAgICAgc2VsTm9kZS5ub2RlVmFsdWUgPSAnXFx1MDBBMCc7IC8vbm9uLWJyZWFraW5nIHNwYWNlLCBcXHUyMDBCIGZvciB6ZXJvIHdpZHRoIHNwYWNlO1xuXG4gICAgdmFyIHBvc2l0aW9uID0gc2VsT2Zmc2V0ID4gc2VsTm9kZS5sZW5ndGggPyBzZWxOb2RlLmxlbmd0aCA6IHNlbE9mZnNldDtcbiAgICBzZXRDYXJldFBvc2l0aW9uKHNlbE5vZGUsIHBvc2l0aW9uKTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgc2VsZWN0aW9uIHJhbmdlXG4gKlxuICogQHJldHVybiB7UmFuZ2V9XG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kZ2V0UmFuZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMucmFuZ2U7XG59XG5cblxuLyoqXG4gKiBTdG9yZXMgc2VsZWN0aW9uIHdpbmRvdywgbm9kZXMgYW5kIG9mZnNldHMgaW4gb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kZ2V0U3RhdGUocm9vdEVsKSB7XG4gICAgdmFyIHIgPSB0aGlzLnJhbmdlO1xuICAgIHZhciBkb2MgPSByb290RWwub3duZXJEb2N1bWVudFxuICAgICAgICAsIHdpbiA9IGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93O1xuICAgIGlmICghcikgcmV0dXJuIHsgd2luZG93OiB3aW4gfTtcbiAgICByZXR1cm4gVGV4dFNlbGVjdGlvbi5jcmVhdGVTdGF0ZU9iamVjdChyb290RWwsIHIuc3RhcnRDb250YWluZXIsIHIuc3RhcnRPZmZzZXQsIHIuZW5kQ29udGFpbmVyLCByLmVuZE9mZnNldCk7XG59XG5cblxuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiQkY3JlYXRlU3RhdGVPYmplY3Qocm9vdEVsLCBzdGFydENvbnRhaW5lciwgc3RhcnRPZmZzZXQsIGVuZENvbnRhaW5lciwgZW5kT2Zmc2V0KSB7XG4gICAgZW5kQ29udGFpbmVyID0gZW5kQ29udGFpbmVyIHx8IHN0YXJ0Q29udGFpbmVyO1xuICAgIGVuZE9mZnNldCA9IGVuZE9mZnNldCB8fCBzdGFydE9mZnNldDtcbiAgICB2YXIgZG9jID0gcm9vdEVsLm93bmVyRG9jdW1lbnRcbiAgICAgICAgLCB3aW4gPSBkb2MuZGVmYXVsdFZpZXcgfHwgZG9jLnBhcmVudFdpbmRvdztcbiAgICByZXR1cm4ge1xuICAgICAgICB3aW5kb3c6IHdpbixcbiAgICAgICAgcm9vdEVsOiByb290RWwsXG4gICAgICAgIHN0YXJ0OiBfZ2V0U2VsZWN0aW9uUG9pbnRTdGF0ZShyb290RWwsIHN0YXJ0Q29udGFpbmVyLCBzdGFydE9mZnNldCksXG4gICAgICAgIGVuZDogX2dldFNlbGVjdGlvblBvaW50U3RhdGUocm9vdEVsLCBlbmRDb250YWluZXIsIGVuZE9mZnNldClcbiAgICB9O1xufVxuXG5cbmZ1bmN0aW9uIF9nZXRTZWxlY3Rpb25Qb2ludFN0YXRlKHJvb3RFbCwgbm9kZSwgb2Zmc2V0KSB7XG4gICAgdmFyIHRyZWVQYXRoID0gZG9tVXRpbHMudHJlZVBhdGhPZihyb290RWwsIG5vZGUpO1xuICAgIGlmICghIHRyZWVQYXRoKSBsb2dnZXIuZXJyb3IoJ1NlbGVjdGlvbiBwb2ludCBpcyBvdXRzaWRlIG9mIHJvb3QgZWxlbWVudCcpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHRyZWVQYXRoOiB0cmVlUGF0aCxcbiAgICAgICAgb2Zmc2V0OiBvZmZzZXRcbiAgICB9O1xufVxuXG5cbi8qKlxuICogUmVzdG9yZXMgYWN0dWFsIHNlbGVjdGlvbiB0byB0aGUgc3RvcmVkIHJhbmdlXG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kJGNyZWF0ZUZyb21TdGF0ZShzdGF0ZSkge1xuICAgIHZhciBkb21VdGlscyA9IHN0YXRlLndpbmRvdy5taWxvLnV0aWwuZG9tO1xuXG4gICAgaWYgKHN0YXRlLnJvb3RFbCAmJiBzdGF0ZS5zdGFydCAmJiBzdGF0ZS5lbmQpIHtcbiAgICAgICAgdmFyIHN0YXJ0Tm9kZSA9IF9zZWxlY3Rpb25Ob2RlRnJvbVN0YXRlKHN0YXRlLnJvb3RFbCwgc3RhdGUuc3RhcnQpXG4gICAgICAgICAgICAsIGVuZE5vZGUgPSBfc2VsZWN0aW9uTm9kZUZyb21TdGF0ZShzdGF0ZS5yb290RWwsIHN0YXRlLmVuZCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRvbVV0aWxzLnNldFNlbGVjdGlvbihzdGFydE5vZGUsIHN0YXRlLnN0YXJ0Lm9mZnNldCwgZW5kTm9kZSwgc3RhdGUuZW5kLm9mZnNldCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRleHRTZWxlY3Rpb24oc3RhdGUud2luZG93KTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1RleHQgc2VsZWN0aW9uOiBjYW5cXCd0IGNyZWF0ZSBzZWxlY3Rpb24nLCBlLCBlLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZG9tVXRpbHMuY2xlYXJTZWxlY3Rpb24oc3RhdGUud2luZG93KTtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKHN0YXRlLndpbmRvdyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9zZWxlY3Rpb25Ob2RlRnJvbVN0YXRlKHJvb3RFbCwgcG9pbnRTdGF0ZSkge1xuICAgIHZhciBub2RlID0gZG9tVXRpbHMuZ2V0Tm9kZUF0VHJlZVBhdGgocm9vdEVsLCBwb2ludFN0YXRlLnRyZWVQYXRoKTtcbiAgICBpZiAoISBub2RlKSBsb2dnZXIuZXJyb3IoJ1RleHRTZWxlY3Rpb24gY3JlYXRlRnJvbVN0YXRlOiBubyBub2RlIGF0IHRyZWVQYXRoJyk7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cblxuLyoqXG4gKiBDcmVhdGVzIHNlbGVjdGlvbiBmcm9tIHBhc3NlZCByYW5nZVxuICogXG4gKiBAcGFyYW0ge1JhbmdlfSByYW5nZVxuICogQHBhcmFtIHtCb29sZWFufSBiYWNrd2FyZFxuICpcbiAqIEByZXR1cm4ge1RleHRTZWxlY3Rpb259XG4gKi9cbmZ1bmN0aW9uIFRleHRTZWxlY3Rpb24kJGNyZWF0ZUZyb21SYW5nZShyYW5nZSwgYmFja3dhcmQpIHtcbiAgICB2YXIgd2luID0gcmFuZ2Uuc3RhcnRDb250YWluZXIub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlld1xuICAgICAgICAsIHNlbCA9IHdpbi5nZXRTZWxlY3Rpb24oKVxuICAgICAgICAsIGVuZFJhbmdlO1xuXG4gICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuXG4gICAgaWYgKGJhY2t3YXJkKXtcbiAgICAgICAgZW5kUmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG4gICAgICAgIGVuZFJhbmdlLmNvbGxhcHNlKGZhbHNlKTtcblxuICAgICAgICBzZWwuYWRkUmFuZ2UoZW5kUmFuZ2UpO1xuICAgICAgICBzZWwuZXh0ZW5kKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkgICAgICAgIFxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFRleHRTZWxlY3Rpb24od2luKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbm9ybWFsaXplZCBjb3B5IG9mIHRoZSByYW5nZVxuICogSWYgeW91IHRyaXBsZSBjbGljayBhbiBpdGVtLCB0aGUgZW5kIG9mIHRoZSByYW5nZSBpcyBwb3NpdGlvbmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIE5FWFQgbm9kZS5cbiAqIHRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIHJhbmdlIHdpdGggdGhlIGVuZCBwb3NpdGlvbmVkIGF0IHRoZSBlbmQgb2YgdGhlIGxhc3QgdGV4dG5vZGUgY29udGFpbmVkIFxuICogaW5zaWRlIGEgY29tcG9uZW50IHdpdGggdGhlIFwiZWRpdGFibGVcIiBmYWNldFxuICogXG4gKiBAcmV0dXJuIHtyYW5nZX1cbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiQkZ2V0Tm9ybWFsaXplZFJhbmdlKCl7XG4gICAgdmFyIGRvYyA9IHRoaXMucmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIub3duZXJEb2N1bWVudFxuICAgICAgICAsIHR3LCBwcmV2aW91c05vZGVcbiAgICAgICAgLCBuZXdSYW5nZSA9IHRoaXMucmFuZ2UuY2xvbmVSYW5nZSgpO1xuXG4gICAgaWYgKG5ld1JhbmdlLmVuZENvbnRhaW5lci5ub2RlVHlwZSAhPT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgICAgdHcgPSBkb2MuY3JlYXRlVHJlZVdhbGtlcihkb2MuYm9keSwgTm9kZUZpbHRlci5TSE9XX1RFWFQpO1xuICAgICAgICB0dy5jdXJyZW50Tm9kZSA9IG5ld1JhbmdlLmVuZENvbnRhaW5lcjtcbiAgICAgICAgcHJldmlvdXNOb2RlID0gdHcucHJldmlvdXNOb2RlKCk7XG4gICAgICAgIG5ld1JhbmdlLnNldEVuZChwcmV2aW91c05vZGUsIHByZXZpb3VzTm9kZS5sZW5ndGgpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdSYW5nZTtcbn1cblxuLyoqXG4gKiBnZXQgdGhlIGRpcmVjdGlvbiBvZiBhIHNlbGVjdGlvblxuICpcbiAqIDEgZm9yd2FyZCwgLTEgYmFja3dhcmQsIDAgbm8gZGlyZWN0aW9uLCB1bmRlZmluZWQgb25lIG9mIHRoZSBub2RlIGlzIGRldGFjaGVkIG9yIGluIGEgZGlmZmVyZW50IGZyYW1lXG4gKlxuICogQHJldHVybiB7LTF8MHwxfHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gVGV4dFNlbGVjdGlvbiQkZ2V0RGlyZWN0aW9uKCl7XG4gICAgcmV0dXJuIGRvbVV0aWxzLmdldFNlbGVjdGlvbkRpcmVjdGlvbih0aGlzLnNlbGVjdGlvbik7ICAgIFxufVxuXG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIERPTVN0b3JhZ2VFcnJvciA9IHJlcXVpcmUoJy4uL2Vycm9yJykuY3JlYXRlQ2xhc3MoJ0RvbVN0b3JhZ2VFcnJvcicpXG4gICAgLCBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXInKVxuICAgICwgU3RvcmFnZU1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuL21zZ19zcmMnKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnJylcbiAgICAsIGpzb25QYXJzZSA9IHJlcXVpcmUoJy4uL2pzb25fcGFyc2UnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cbnJlcXVpcmUoJy4vbW9kZWwnKVxuXG5tb2R1bGUuZXhwb3J0cyA9IERPTVN0b3JhZ2U7XG5cblxuLy8gc2hhcmVkIGtleXMgc3RvcmVkIGJ5IGFsbCBpbnN0YW5jZXMsIGluY2x1ZGUga2V5IHByZWZpeGVzXG52YXIgX3N0b3JlZEtleXMgPSB7XG4gICAgdHJ1ZToge30sIC8vIHNlc3Npb24gc3RvcmFnZVxuICAgIGZhbHNlOiB7fSAvLyBsb2NhbCBzdG9yYWdlXG59O1xuXG5cbi8qKlxuICogRE9NU3RvcmFnZSBjbGFzcyB0byBzaW1wbGlmeSBzdG9yYWdlIGFuZCByZXRyaWV2YWwgb2YgbXVsdGlwbGUgaXRlbXMgd2l0aCB0eXBlcyBwcmVzZXJ2YXRpb24gdG8gRE9NIHN0b3JhZ2UgKGxvY2FsU3RvcmFnZSBhbmQgc2Vzc2lvblN0b3JhZ2UpLlxuICogVHlwZXMgd2lsbCBiZSBzdG9yZWQgaW4gdGhlIGtleSBjcmVhdGVkIGZyb20gdmFsdWUga2V5cyB3aXRoIGFwcGVuZGVkIGBtaWxvLmNvbmZpZy5kb21TdG9yYWdlLnR5cGVTdWZmaXhgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVByZWZpeCBwcmVmaXggdGhhdCB3aWxsIGJlIGFkZGVkIHRvIGFsbCBrZXlzIGZvbGxvd2VkIGJ5IGBtaWxvLmNvbmZpZy5kb21TdG9yYWdlLnByZWZpeFNlcGFyYXRvcmAgKFwiL1wiIGJ5IGRlZmF1bHQpLlxuICogQHBhcmFtIHtCb29sZWFufSBzZXNzaW9uT25seSB0cnVlIHRvIHVzZSBzZXNzaW9uU3RvcmFnZS4gbG9jYWxTdG9yYWdlIHdpbGwgYmUgdXNlZCBieSBkZWZhdWx0LlxuICogQHBhcmFtIHtXaW5kb3d9IHdpbiB3aW5kb3cgdG8gd29yayBpblxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlKGtleVByZWZpeCwgc2Vzc2lvbk9ubHksIHdpbikge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09ICd1bmRlZmluZWQnKSByZXR1cm47XG4gICAgd2luID0gd2luIHx8IHdpbmRvdztcblxuICAgIGtleVByZWZpeCA9IGNvbmZpZy5kb21TdG9yYWdlLnJvb3QgK1xuICAgICAgICAgICAgICAgIChrZXlQcmVmaXhcbiAgICAgICAgICAgICAgICAgICAgPyBrZXlQcmVmaXggKyBjb25maWcuZG9tU3RvcmFnZS5wcmVmaXhTZXBhcmF0b3JcbiAgICAgICAgICAgICAgICAgICAgOiAnJyk7XG5cbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBrZXlQcmVmaXg6IGtleVByZWZpeCxcbiAgICAgICAgc2Vzc2lvbk9ubHk6ICEhIHNlc3Npb25Pbmx5LFxuICAgICAgICB3aW5kb3c6IHdpbixcbiAgICAgICAgX3N0b3JhZ2U6IHNlc3Npb25Pbmx5ID8gd2luLnNlc3Npb25TdG9yYWdlIDogd2luLmxvY2FsU3RvcmFnZSxcbiAgICAgICAgX3R5cGVTdWZmaXg6IGNvbmZpZy5kb21TdG9yYWdlLnR5cGVTdWZmaXgsXG4gICAgICAgIF9rZXlzOiB7fVxuICAgIH0sIF8uV1JJVCk7XG59XG5cblxuXy5leHRlbmRQcm90byhET01TdG9yYWdlLCB7XG4gICAgZ2V0OiBET01TdG9yYWdlJGdldCxcbiAgICBzZXQ6IERPTVN0b3JhZ2Ukc2V0LFxuICAgIHJlbW92ZTogRE9NU3RvcmFnZSRyZW1vdmUsXG4gICAgaGFzSXRlbTogRE9NU3RvcmFnZSRoYXNJdGVtLFxuICAgIGdldEl0ZW06IERPTVN0b3JhZ2UkZ2V0SXRlbSxcbiAgICBzZXRJdGVtOiBET01TdG9yYWdlJHNldEl0ZW0sXG4gICAgcmVtb3ZlSXRlbTogRE9NU3RvcmFnZSRyZW1vdmVJdGVtLFxuICAgIF9zdG9yYWdlS2V5OiBET01TdG9yYWdlJF9zdG9yYWdlS2V5LFxuICAgIF9kb21TdG9yYWdlS2V5OiBET01TdG9yYWdlJF9kb21TdG9yYWdlS2V5LFxuICAgIGdldEFsbEtleXM6IERPTVN0b3JhZ2UkZ2V0QWxsS2V5cyxcbiAgICBnZXRBbGxJdGVtczogRE9NU3RvcmFnZSRnZXRBbGxJdGVtcyxcbiAgICBjcmVhdGVNZXNzZW5nZXI6IERPTVN0b3JhZ2UkY3JlYXRlTWVzc2VuZ2VyLFxuICAgIGRlc3Ryb3k6IERPTVN0b3JhZ2UkZGVzdHJveVxufSk7XG5cblxuLyoqXG4gKiBFeHBvc2UgTWVzZW5nZXIgYW5kIE1lc3NhZ2VTb3VyY2UgbWV0aG9kcyBvbiBET01TdG9yYWdlXG4gKi9cbk1lc3Nlbmdlci51c2VXaXRoKERPTVN0b3JhZ2UsICdfbWVzc2VuZ2VyJywgTWVzc2VuZ2VyLmRlZmF1bHRNZXRob2RzKTtcblN0b3JhZ2VNZXNzYWdlU291cmNlLnVzZVdpdGgoRE9NU3RvcmFnZSwgJ19tZXNzYWdlU291cmNlJywgWyd0cmlnZ2VyJ10pO1xuXG5cbnZhciBfc2Vzc2lvblN0b3JhZ2UgPSBuZXcgRE9NU3RvcmFnZSgnJywgdHJ1ZSlcbiAgICAsIF9sb2NhbFN0b3JhZ2UgPSBuZXcgRE9NU3RvcmFnZSgnJywgZmFsc2UpO1xuXG52YXIgX2RvbVN0b3JhZ2UgPSB7XG4gICAgICAgIHRydWU6IF9zZXNzaW9uU3RvcmFnZSxcbiAgICAgICAgZmFsc2U6IF9sb2NhbFN0b3JhZ2VcbiAgICB9O1xuXG5fLmV4dGVuZChET01TdG9yYWdlLCB7XG4gICAgcmVnaXN0ZXJEYXRhVHlwZTogRE9NU3RvcmFnZSQkcmVnaXN0ZXJEYXRhVHlwZSxcbiAgICBsb2NhbDogX2xvY2FsU3RvcmFnZSxcbiAgICBzZXNzaW9uOiBfc2Vzc2lvblN0b3JhZ2UsXG4gICAgc3RvcmFnZTogX2RvbVN0b3JhZ2UsXG4gICAgX3N0b3JlZEtleXM6IF9zdG9yZWRLZXlzIC8vIGV4cG9zZWQgZm9yIHRlc3Rpbmdcbn0pO1xuXG5cbi8qKlxuICogU2V0cyBkYXRhIHRvIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBrZXlzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIHNpbmdsZSBvYmplY3QgY2FuIGJlIHBhc3NlZCBpbiB3aGljaCBjYXNlIGtleXMgd2lsbCBiZSB1c2VkIGFzIGtleXMgaW4gbG9jYWwgc3RvcmFnZS5cbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFsdGVybmF0aXZlbHkganVzdCB0aGUgbGlzdCBvZiBhcmd1bWVudHMgY2FuIGJlIHBhc3NlZCB3aGVyZSBhcmd1bWVudHMgY2FuIGJlIHNlcXVlbnRpYWxseSB1c2VkIGFzIGtleXMgYW5kIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRzZXQoZGF0YSkgeyAvLyBvciBhcmd1bWVudHNcbiAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ29iamVjdCcpXG4gICAgICAgIF8uZWFjaEtleShkYXRhLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICB0aGlzLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIGVsc2Uge1xuICAgICAgICB2YXIgYXJnc0xlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgIGlmIChhcmdzTGVuICUgMilcbiAgICAgICAgICAgIHRocm93IG5ldyBEb21TdG9yYWdlRXJyb3IoJ0RPTVN0b3JhZ2U6IHNldCBzaG91bGQgaGF2ZSBldmVuIG51bWJlciBvZiBhcmd1bWVudHMgb3Igb2JqZWN0Jyk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzTGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBhcmd1bWVudHNbaV1cbiAgICAgICAgICAgICAgICAsIHZhbHVlID0gYXJndW1lbnRzWysraV07XG5cbiAgICAgICAgICAgIHRoaXMuc2V0SXRlbShrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG4vKipcbiAqIEdldHMgZGF0YSBmcm9tIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBwYXNzZWQga2V5cywgYnV0IHJldHVybmVkIG9iamVjdCB3aWxsIGhhdmUga2V5cyB3aXRob3V0IHJvb3Qga2V5cy5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBrZXlzIGNhbiBiZSBwYXNzZWQgYXMgc3RyaW5ncyBvciBhcnJheXMgb2Ygc3RyaW5nc1xuICogQHJldHVybnMge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRnZXQoKSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBkYXRhID0ge307XG4gICAgXy5kZWVwRm9yRWFjaChhcmd1bWVudHMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBkYXRhW2tleV0gPSB0aGlzLmdldEl0ZW0oa2V5KTtcbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gZGF0YTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMga2V5cyBmcm9tIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBwYXNzZWQga2V5cy5cbiAqXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBrZXlzIGNhbiBiZSBwYXNzZWQgYXMgc3RyaW5ncyBvciBhcnJheXMgb2Ygc3RyaW5nc1xuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJHJlbW92ZSgpIHsgLy8sIC4uLiBhcmd1bWVudHNcbiAgICBfLmRlZXBGb3JFYWNoKGFyZ3VtZW50cywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHRoaXMucmVtb3ZlSXRlbShrZXkpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbi8qKlxuICogQ2hlY2sgZm9yIHByZXNlbmNlIG9mIHNpbmdsZSBpdGVtIGluIERPTSBzdG9yYWdlLiBgdGhpcy5rZXlQcmVmaXhgIGlzIHByZXBlbmRlZCB0byBwYXNzZWQga2V5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkaGFzSXRlbShrZXkpIHtcbiAgICB2YXIgcEtleSA9IHRoaXMuX3N0b3JhZ2VLZXkoa2V5KTtcbiAgICByZXR1cm4gdGhpcy5fc3RvcmFnZS5nZXRJdGVtKHBLZXkpICE9IG51bGw7XG59XG5cblxuLyoqXG4gKiBHZXRzIHNpbmdsZSBpdGVtIGZyb20gRE9NIHN0b3JhZ2UgcHJlcGVuZGluZyBgdGhpcy5rZXlQcmVmaXhgIHRvIHBhc3NlZCBrZXkuXG4gKiBSZWFkcyB0eXBlIG9mIHRoZSBvcmlnaW5hbGx5IHN0b3JlZCB2YWx1ZSBmcm9tIGBrZXkgKyB0aGlzLl90eXBlU3VmZml4YCBhbmQgY29udmVydHMgZGF0YSB0byB0aGUgb3JpZ2luYWwgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkZ2V0SXRlbShrZXkpIHtcbiAgICB2YXIgcEtleSA9IHRoaXMuX3N0b3JhZ2VLZXkoa2V5KTtcbiAgICB2YXIgZGF0YVR5cGUgPSBfZ2V0S2V5RGF0YVR5cGUuY2FsbCh0aGlzLCBwS2V5KTtcbiAgICB2YXIgdmFsdWVTdHIgPSB0aGlzLl9zdG9yYWdlLmdldEl0ZW0ocEtleSk7XG4gICAgdmFyIHZhbHVlID0gX3BhcnNlRGF0YSh2YWx1ZVN0ciwgZGF0YVR5cGUpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuXG4vKipcbiAqIFNldHMgc2luZ2xlIGl0ZW0gdG8gRE9NIHN0b3JhZ2UgcHJlcGVuZGluZyBgdGhpcy5rZXlQcmVmaXhgIHRvIHBhc3NlZCBrZXkuXG4gKiBTdG9yZXMgdHlwZSBvZiB0aGUgc3RvcmVkIHZhbHVlIHRvIGBrZXkgKyB0aGlzLl90eXBlU3VmZml4YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2Ukc2V0SXRlbShrZXksIHZhbHVlKSB7XG4gICAgdmFyIHBLZXkgPSB0aGlzLl9zdG9yYWdlS2V5KGtleSk7XG4gICAgdmFyIGRhdGFUeXBlID0gX3NldEtleURhdGFUeXBlLmNhbGwodGhpcywgcEtleSwgdmFsdWUpO1xuICAgIHZhciB2YWx1ZVN0ciA9IF9zZXJpYWxpemVEYXRhKHZhbHVlLCBkYXRhVHlwZSk7XG4gICAgdHJ5IHtcbiAgICAgICAgdGhpcy5fc3RvcmFnZS5zZXRJdGVtKHBLZXksIHZhbHVlU3RyKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgaWYgKGUubmFtZSA9PSAnUXVvdGFFeGNlZWRlZEVycm9yJykge1xuICAgICAgICAgICAgdmFyIGNmZyA9IGNvbmZpZy5kb21TdG9yYWdlLnF1b3RhRXhjZWVkZWQ7XG4gICAgICAgICAgICBpZiAoY2ZnLm1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgbWlsby5tYWlsLnBvc3RNZXNzYWdlKCdxdW90YWV4Y2VlZGVkZXJyb3InLCB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoY2ZnLnRocm93RXJyb3IpXG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgIH1cbiAgICB0aGlzLl9rZXlzW2tleV0gPSB0cnVlO1xuICAgIF9kb21TdG9yYWdlW3RoaXMuc2Vzc2lvbk9ubHldLl9rZXlzW3BLZXldID0gdHJ1ZTtcbn1cblxuXG4vKipcbiAqIFJlbW92ZXMgc2luZ2xlIGl0ZW0gZnJvbSBET00gc3RvcmFnZSBwcmVwZW5kaW5nIGB0aGlzLmtleVByZWZpeGAgdG8gcGFzc2VkIGtleS5cbiAqIFR5cGUgb2YgdGhlIHN0b3JlZCB2YWx1ZSAoaW4gYGtleSArIHRoaXMuX3R5cGVTdWZmaXhgIGtleSkgaXMgYWxzbyByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRyZW1vdmVJdGVtKGtleSkge1xuICAgIHZhciBwS2V5ID0gdGhpcy5fc3RvcmFnZUtleShrZXkpO1xuICAgIHRoaXMuX3N0b3JhZ2UucmVtb3ZlSXRlbShwS2V5KTtcbiAgICBfcmVtb3ZlS2V5RGF0YVR5cGUuY2FsbCh0aGlzLCBwS2V5KVxuICAgIGRlbGV0ZSB0aGlzLl9rZXlzW2tleV07XG4gICAgZGVsZXRlIF9kb21TdG9yYWdlW3RoaXMuc2Vzc2lvbk9ubHldLl9rZXlzW3BLZXldO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgYXJyYXkgb2YgYWxsIGtleXMgc3RvcmVkIGJ5IHRoaXMgaW5zdGFuY2Ugb2YgRE9NU3RvcmFnZVxuICpcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJGdldEFsbEtleXMoKSB7XG4gICAgdmFyIHN0b3JlZEtleXMgPSBPYmplY3Qua2V5cyh0aGlzLl9rZXlzKTtcbiAgICB2YXIga2V5c0luU3RvcmFnZSA9IHN0b3JlZEtleXMuZmlsdGVyKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAodGhpcy5oYXNJdGVtKGtleSkpIHJldHVybiB0cnVlO1xuICAgICAgICBlbHNlIGRlbGV0ZSB0aGlzLl9rZXlzW2tleV07XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIGtleXNJblN0b3JhZ2U7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXAgd2l0aCBhbGwga2V5cyBhbmQgdmFsdWVzIChkZXNlcmlhbGl6ZWQpIHN0b3JlZCB1c2luZyB0aGlzIGluc3RhbmNlIG9mIERPTVN0b3JhZ2VcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkZ2V0QWxsSXRlbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KHRoaXMuZ2V0QWxsS2V5cygpKTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgcHJlZml4ZWQga2V5IGZvciBET00gc3RvcmFnZSBmb3IgZ2l2ZW4gdW5wcmVmaXhlZCBrZXkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJF9zdG9yYWdlS2V5KGtleSkge1xuICAgIHJldHVybiB0aGlzLmtleVByZWZpeCArIGtleTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdW5wcmVmaXhlZCBrZXkgdG8gYmUgdXNlZCB3aXRoIHRoaXMgaW5zdGFuY2Ugb2YgRE9NU3RvcmFnZSBmaXIgZ2l2ZW4gYWN0dWFsIGtleSBpbiBzdG9yYWdlXG4gKiBJZiBrZXkgaGFzIGRpZmZlcmVudCBwcmVmaXggZnJvbSB0aGUga2V5UHJlZml4IHJldHVybnMgdW5kZWZpbmVkXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0b3JhZ2VLZXkgYWN0dWFsIGtleSBpbiBsb2NhbC9zZXNzaW9uIHN0b3JhZ2VcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gRE9NU3RvcmFnZSRfZG9tU3RvcmFnZUtleShzdG9yYWdlS2V5KSB7XG4gICAgaWYgKHN0b3JhZ2VLZXkuaW5kZXhPZih0aGlzLl90eXBlU3VmZml4KSA+PSAwKSByZXR1cm47XG4gICAgcmV0dXJuIF8udW5QcmVmaXgoc3RvcmFnZUtleSwgdGhpcy5rZXlQcmVmaXgpO1xufVxuXG5cbi8qKlxuICogR2V0cyBvcmlnaW5hbGx5IHN0b3JlZCBkYXRhIHR5cGUgZm9yIGdpdmVuIChwcmVmaXhlZCkgYGtleWAuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBwS2V5IHByZWZpeGVkIGtleSBvZiBzdG9yZWQgdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gX2dldEtleURhdGFUeXBlKHBLZXkpIHtcbiAgICBwS2V5ID0gX2RhdGFUeXBlS2V5LmNhbGwodGhpcywgcEtleSk7XG4gICAgcmV0dXJuIHRoaXMuX3N0b3JhZ2UuZ2V0SXRlbShwS2V5KTtcbn1cblxuXG4vKipcbiAqIFN0b3JlcyBkYXRhIHR5cGUgZm9yIGdpdmVuIChwcmVmaXhlZCkgYGtleWAgYW5kIGB2YWx1ZWAuXG4gKiBSZXR1cm5zIGRhdGEgdHlwZSBmb3IgYHZhbHVlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcEtleSBwcmVmaXhlZCBrZXkgb2Ygc3RvcmVkIHZhbHVlXG4gKiBAcGFyYW0ge0FueX0gdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gX3NldEtleURhdGFUeXBlKHBLZXksIHZhbHVlKSB7XG4gICAgdmFyIGRhdGFUeXBlID0gX2dldFZhbHVlVHlwZSh2YWx1ZSk7XG4gICAgcEtleSA9IF9kYXRhVHlwZUtleS5jYWxsKHRoaXMsIHBLZXkpO1xuICAgIHRoaXMuX3N0b3JhZ2Uuc2V0SXRlbShwS2V5LCBkYXRhVHlwZSk7XG4gICAgcmV0dXJuIGRhdGFUeXBlO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlcyBzdG9yZWQgZGF0YSB0eXBlIGZvciBnaXZlbiAocHJlZml4ZWQpIGBrZXlgLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gcEtleSBwcmVmaXhlZCBrZXkgb2Ygc3RvcmVkIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIF9yZW1vdmVLZXlEYXRhVHlwZShwS2V5KSB7XG4gICAgcEtleSA9IF9kYXRhVHlwZUtleS5jYWxsKHRoaXMsIHBLZXkpO1xuICAgIHRoaXMuX3N0b3JhZ2UucmVtb3ZlSXRlbShwS2V5KTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGtleSB0byBzdG9yZSBkYXRhIHR5cGUgZm9yIGdpdmVuIChwcmVmaXhlZCkgYGtleWAuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSBwS2V5IHByZWZpeGVkIGtleSBvZiBzdG9yZWQgdmFsdWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuZnVuY3Rpb24gX2RhdGFUeXBlS2V5KHBLZXkpIHtcbiAgICByZXR1cm4gcEtleSArIHRoaXMuX3R5cGVTdWZmaXg7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHR5cGUgb2YgdmFsdWUgYXMgc3RyaW5nLiBDbGFzcyBuYW1lIHJldHVybmVkIGZvciBvYmplY3RzICgnbnVsbCcgZm9yIG51bGwpLlxuICogQHBhcmFtICB7QW55fSB2YWx1ZVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBfZ2V0VmFsdWVUeXBlKHZhbHVlKSB7XG4gICAgdmFyIHZhbHVlVHlwZSA9IHR5cGVvZiB2YWx1ZVxuICAgICAgICAsIGNsYXNzTmFtZSA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLm5hbWVcbiAgICAgICAgLCBkYXRhVHlwZSA9IHZhbHVlc0RhdGFUeXBlc1tjbGFzc05hbWVdO1xuICAgIHJldHVybiBkYXRhVHlwZSB8fCAoXG4gICAgICAgICAgICB2YWx1ZVR5cGUgIT0gJ29iamVjdCdcbiAgICAgICAgICAgICAgICA/IHZhbHVlVHlwZVxuICAgICAgICAgICAgICAgIDogdmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgICAgICAgICA/ICdudWxsJ1xuICAgICAgICAgICAgICAgICAgICA6IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUpO1xufVxudmFyIHZhbHVlc0RhdGFUeXBlcyA9IHtcbiAgICAvLyBjYW4gYmUgcmVnaXN0ZXJlZCB3aXRoIGByZWdpc3RlckRhdGFUeXBlYFxufVxuXG5cbi8qKlxuICogU2VyaWFsaXplcyB2YWx1ZSB0byBiZSBzdG9yZWQgaW4gRE9NIHN0b3JhZ2UuXG4gKlxuICogQHBhcmFtICB7QW55fSB2YWx1ZSB2YWx1ZSB0byBiZSBzZXJpYWxpemVkXG4gKiBAcGFyYW0gIHtTdHJpbmd9IHZhbHVlVHlwZSBvcHRpb25hbCBkYXRhIHR5cGUgdG8gZGVmaW5lIHNlcmlhbGl6ZXIsIF9nZXRWYWx1ZVR5cGUgaXMgdXNlZCBpZiBub3QgcGFzc2VkLlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBfc2VyaWFsaXplRGF0YSh2YWx1ZSwgdmFsdWVUeXBlKSB7XG4gICAgdmFsdWVUeXBlID0gdmFsdWVUeXBlIHx8IF9nZXRWYWx1ZVR5cGUodmFsdWUpO1xuICAgIHZhciBzZXJpYWxpemVyID0gZGF0YVNlcmlhbGl6ZXJzW3ZhbHVlVHlwZV07XG4gICAgcmV0dXJuIHNlcmlhbGl6ZXJcbiAgICAgICAgICAgID8gc2VyaWFsaXplcih2YWx1ZSwgdmFsdWVUeXBlKVxuICAgICAgICAgICAgOiB2YWx1ZSAmJiB2YWx1ZS50b1N0cmluZyA9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgICAgICAgICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSlcbiAgICAgICAgICAgICAgICA6ICcnICsgdmFsdWU7XG59XG52YXIgZGF0YVNlcmlhbGl6ZXJzID0ge1xuICAgICdBcnJheSc6IEpTT04uc3RyaW5naWZ5XG59XG5cblxuLyoqXG4gKiBQYXJzZXMgc3RyaW5nIHJldHJpZXZlZCBmcm9tIERPTSBzdG9yYWdlLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdmFsdWVTdHJcbiAqIEBwYXJhbSAge1N0cmluZ30gdmFsdWVUeXBlIGRhdGEgdHlwZSB0aGF0IGRlZmluZXMgcGFyc2VyLiBPcmlnaW5hbCBzcmluZyB3aWxsIGJlIHJldHVybmVkIGlmIHBhcnNlciBpcyBub3QgZGVmaW5lZC5cbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gX3BhcnNlRGF0YSh2YWx1ZVN0ciwgdmFsdWVUeXBlKSB7XG4gICAgdmFyIHBhcnNlciA9IGRhdGFQYXJzZXJzW3ZhbHVlVHlwZV07XG4gICAgcmV0dXJuIHBhcnNlclxuICAgICAgICAgICAgPyBwYXJzZXIodmFsdWVTdHIsIHZhbHVlVHlwZSlcbiAgICAgICAgICAgIDogdmFsdWVTdHI7XG59XG52YXIgZGF0YVBhcnNlcnMgPSB7XG4gICAgT2JqZWN0OiBqc29uUGFyc2UsXG4gICAgQXJyYXk6IGpzb25QYXJzZSxcbiAgICBEYXRlOiBmdW5jdGlvbih2YWxTdHIpIHsgcmV0dXJuIG5ldyBEYXRlKHZhbFN0cik7IH0sXG4gICAgYm9vbGVhbjogZnVuY3Rpb24odmFsU3RyKSB7IHJldHVybiB2YWxTdHIgPT0gJ3RydWUnOyB9LFxuICAgIG51bWJlcjogZnVuY3Rpb24odmFsU3RyKSB7IHJldHVybiBOdW1iZXIodmFsU3RyKTsgfSxcbiAgICBmdW5jdGlvbjogZnVuY3Rpb24odmFsU3RyKSB7IHJldHVybiBfLnRvRnVuY3Rpb24odmFsU3RyKTsgfSxcbiAgICBSZWdFeHA6IGZ1bmN0aW9uKHZhbFN0cikgeyByZXR1cm4gXy50b1JlZ0V4cCh2YWxTdHIpOyB9XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXJzIGRhdGEgdHlwZSB0byBiZSBzYXZlZCBpbiBET00gc3RvcmFnZS4gQ2xhc3MgbmFtZSBjYW4gYmUgdXNlZCBvciByZXN1bHQgb2YgYHR5cGVvZmAgb3BlcmF0b3IgZm9yIG5vbi1vYmplY3RzIHRvIG92ZXJyaWRlIGRlZmF1bHQgY29udmVyc2lvbnMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlVHlwZSBjbGFzcyAoY29uc3RydWN0b3IpIG5hbWUgb3IgdGhlIHN0cmluZyByZXR1cm5lZCBieSB0eXBlb2YuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXJpYWxpemVyIG9wdGlvbmFsIHNlcmlhbGl6ZXIgZm9yIHRoaXMgdHlwZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gcGFyc2VyIG9wdGlvbmFsIHBhcnNlciBmb3IgdGhpcyB0eXBlXG4gKiBAcGFyYW0ge1tTdHJpbmddfSBzdG9yZUFzRGF0YVR5cGUgb3B0aW9uYWwgbmFtZSBvZiBzdG9yZWQgZGF0YSB0eXBlIGlmIGRpZmZlcmVudCBmcm9tIHZhbHVlVHlwZVxuICovXG5mdW5jdGlvbiBET01TdG9yYWdlJCRyZWdpc3RlckRhdGFUeXBlKHZhbHVlVHlwZSwgc2VyaWFsaXplciwgcGFyc2VyLCBzdG9yZUFzRGF0YVR5cGUpIHtcbiAgICBpZiAoc2VyaWFsaXplcikgZGF0YVNlcmlhbGl6ZXJzW3ZhbHVlVHlwZV0gPSBzZXJpYWxpemVyO1xuICAgIGlmIChwYXJzZXIpIGRhdGFQYXJzZXJzW3ZhbHVlVHlwZV0gPSBwYXJzZXI7XG4gICAgdmFsdWVzRGF0YVR5cGVzW3ZhbHVlVHlwZV0gPSBzdG9yZUFzRGF0YVR5cGUgfHwgdmFsdWVUeXBlO1xufVxuXG5cbmZ1bmN0aW9uIERPTVN0b3JhZ2UkY3JlYXRlTWVzc2VuZ2VyKCkge1xuICAgIHZhciBzdG9yYWdlTWVzc2FnZVNvdXJjZSA9IG5ldyBTdG9yYWdlTWVzc2FnZVNvdXJjZSh0aGlzKTtcbiAgICB2YXIgbWVzc2VuZ2VyID0gbmV3IE1lc3Nlbmdlcih0aGlzLCB1bmRlZmluZWQsIHN0b3JhZ2VNZXNzYWdlU291cmNlKTtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywge1xuICAgICAgICBfbWVzc2VuZ2VyOiBtZXNzZW5nZXIsXG4gICAgICAgIF9tZXNzYWdlU291cmNlOiBzdG9yYWdlTWVzc2FnZVNvdXJjZVxuICAgIH0sIF8uV1JJVCk7XG59XG5cblxuZnVuY3Rpb24gRE9NU3RvcmFnZSRkZXN0cm95KCkge1xuICAgIHRoaXMuX3N0b3JhZ2UgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53aW5kb3cgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuX21lc3NlbmdlcikgdGhpcy5fbWVzc2VuZ2VyLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTW9kZWwgPSByZXF1aXJlKCdtaWxvLWNvcmUnKS5Nb2RlbFxuXG5Nb2RlbC5yZWdpc3RlcldpdGhET01TdG9yYWdlID0gTW9kZWwkJHJlZ2lzdGVyV2l0aERPTVN0b3JhZ2U7XG5cblxuZnVuY3Rpb24gTW9kZWwkJHJlZ2lzdGVyV2l0aERPTVN0b3JhZ2UoKSB7XG4gICAgdmFyIERPTVN0b3JhZ2UgPSByZXF1aXJlKCcuL2luZGV4Jyk7XG4gICAgRE9NU3RvcmFnZS5yZWdpc3RlckRhdGFUeXBlKCdNb2RlbCcsIE1vZGVsX2RvbVN0b3JhZ2VTZXJpYWxpemVyLCBNb2RlbF9kb21TdG9yYWdlUGFyc2VyKTtcbiAgICBET01TdG9yYWdlLnJlZ2lzdGVyRGF0YVR5cGUoJ01vZGVsUGF0aCcsIE1vZGVsX2RvbVN0b3JhZ2VTZXJpYWxpemVyLCBNb2RlbF9kb21TdG9yYWdlUGFyc2VyLCAnTW9kZWwnKTtcbn1cblxuXG5mdW5jdGlvbiBNb2RlbF9kb21TdG9yYWdlU2VyaWFsaXplcih2YWx1ZSkge1xuICAgIHZhciBkYXRhID0gdmFsdWUuZ2V0KCk7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIE1vZGVsX2RvbVN0b3JhZ2VQYXJzZXIodmFsdWVTdHIpIHtcbiAgICB2YXIgZGF0YSA9IF8uanNvblBhcnNlKHZhbHVlU3RyKTtcbiAgICByZXR1cm4gbmV3IE1vZGVsKGRhdGEpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi4vLi4vbWVzc2VuZ2VyL21fc291cmNlJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgY29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnJylcbiAgICAsIG1pbG9Db3VudCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY291bnQnKVxuICAgICwgU3RvcmFnZU1lc3NhZ2VTb3VyY2VFcnJvciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvZXJyb3InKS5TdG9yYWdlTWVzc2FnZVNvdXJjZTtcblxudmFyIFN0b3JhZ2VNZXNzYWdlU291cmNlID0gXy5jcmVhdGVTdWJjbGFzcyhNZXNzYWdlU291cmNlLCAnU3RvcmFnZU1lc3NhZ2VTb3VyY2UnLCB0cnVlKTtcblxuXG5fLmV4dGVuZFByb3RvKFN0b3JhZ2VNZXNzYWdlU291cmNlLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgaW5pdDogaW5pdCxcbiAgICBhZGRTb3VyY2VTdWJzY3JpYmVyOiBTdG9yYWdlTWVzc2FnZVNvdXJjZSRhZGRTb3VyY2VTdWJzY3JpYmVyLFxuICAgIHJlbW92ZVNvdXJjZVN1YnNjcmliZXI6IFN0b3JhZ2VNZXNzYWdlU291cmNlJHJlbW92ZVNvdXJjZVN1YnNjcmliZXIsXG4gICAgcG9zdE1lc3NhZ2U6IFN0b3JhZ2VNZXNzYWdlU291cmNlJHBvc3RNZXNzYWdlLFxuICAgIHRyaWdnZXI6IFN0b3JhZ2VNZXNzYWdlU291cmNlJHRyaWdnZXIsXG5cbiAgICAvL2NsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICBoYW5kbGVFdmVudDogaGFuZGxlRXZlbnQgIC8vIGV2ZW50IGRpc3BhdGNoZXIgLSBhcyBkZWZpbmVkIGJ5IEV2ZW50IERPTSBBUElcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0b3JhZ2VNZXNzYWdlU291cmNlO1xuXG5cbmZ1bmN0aW9uIGluaXQoaG9zdE9iamVjdCwgcHJveHlNZXRob2RzLCBtZXNzZW5nZXJBUElPckNsYXNzKSB7XG4gICAgaWYgKGhvc3RPYmplY3QuY29uc3RydWN0b3IubmFtZSAhPSAnRE9NU3RvcmFnZScpXG4gICAgICAgIHRocm93IG5ldyBTdG9yYWdlTWVzc2FnZVNvdXJjZUVycm9yKCdob3N0T2JqZWN0IHNob3VsZCBiZSBhbiBpbnN0YW5jZSBvZiBET01TdG9yYWdlJyk7XG4gICAgdGhpcy5zdG9yYWdlID0gaG9zdE9iamVjdDtcbiAgICB0aGlzLm1lc3NhZ2VLZXkgPSBjb25maWcuZG9tU3RvcmFnZS5tZXNzYWdlS2V5O1xuICAgIHRoaXMud2luZG93ID0gaG9zdE9iamVjdC53aW5kb3c7XG4gICAgTWVzc2FnZVNvdXJjZS5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbmZ1bmN0aW9uIFN0b3JhZ2VNZXNzYWdlU291cmNlJGFkZFNvdXJjZVN1YnNjcmliZXIoc291cmNlTWVzc2FnZSkge1xuICAgIHRoaXMud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3N0b3JhZ2UnLCB0aGlzLCBmYWxzZSk7XG59XG5cblxuZnVuY3Rpb24gU3RvcmFnZU1lc3NhZ2VTb3VyY2UkcmVtb3ZlU291cmNlU3Vic2NyaWJlcihzb3VyY2VNZXNzYWdlKSB7XG4gICAgdGhpcy53aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RvcmFnZScsIHRoaXMsIGZhbHNlKTtcbn1cblxuXG5mdW5jdGlvbiBTdG9yYWdlTWVzc2FnZVNvdXJjZSRwb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhKSB7XG4gICAgdGhpcy5tZXNzZW5nZXIucG9zdE1lc3NhZ2VTeW5jKG1lc3NhZ2UsIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIFN0b3JhZ2VNZXNzYWdlU291cmNlJHRyaWdnZXIobXNnVHlwZSwgZGF0YSkge1xuICAgIHZhciBrZXkgPSB0aGlzLm1lc3NhZ2VLZXkgKyBtc2dUeXBlO1xuICAgIGRhdGEgPSBkYXRhIHx8IHt9O1xuICAgIGRhdGFbY29uZmlnLmRvbVN0b3JhZ2UubWVzc2FnZVRpbWVzdGFtcF0gPSBtaWxvQ291bnQoKTtcbiAgICBfLmRlZmVyTWV0aG9kKHRoaXMuc3RvcmFnZSwgJ3NldEl0ZW0nLCBrZXksIGRhdGEpO1xufVxuXG5cbmZ1bmN0aW9uIGhhbmRsZUV2ZW50KGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnN0b3JhZ2VBcmVhICE9IHRoaXMuc3RvcmFnZS5fc3RvcmFnZSkgcmV0dXJuO1xuICAgIHZhciBrZXkgPSB0aGlzLnN0b3JhZ2UuX2RvbVN0b3JhZ2VLZXkoZXZlbnQua2V5KTsgaWYgKCEga2V5KSByZXR1cm47XG4gICAgdmFyIG1zZ1R5cGUgPSBfLnVuUHJlZml4KGtleSwgdGhpcy5tZXNzYWdlS2V5KTsgaWYgKCEgbXNnVHlwZSkgcmV0dXJuO1xuICAgIHZhciBkYXRhID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oa2V5KTsgaWYgKCEgZGF0YSkgcmV0dXJuO1xuICAgIHRoaXMuZGlzcGF0Y2hNZXNzYWdlKG1zZ1R5cGUsIGRhdGEpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBtaWxvLnV0aWwud2Vic29ja2V0YCBcbioqL1xuXG5cbnZhciBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXInKVxuICAgICwgV1NNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi9tc2dfc3JjJylcbiAgICAsIFdTTXNnQVBJID0gcmVxdWlyZSgnLi9tc2dfYXBpJyk7XG5cblxuZnVuY3Rpb24gd2Vic29ja2V0KCkge1xuICAgIHZhciB3c01lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXI7XG4gICAgdmFyIHdzTXNnU291cmNlID0gbmV3IFdTTWVzc2FnZVNvdXJjZSh3c01lc3NlbmdlciwgeyBzZW5kOiAndHJpZ2dlcicsIGNvbm5lY3Q6ICdjb25uZWN0JyB9LCBuZXcgV1NNc2dBUEkpO1xuICAgIHdzTWVzc2VuZ2VyLl9zZXRNZXNzYWdlU291cmNlKHdzTXNnU291cmNlKTtcbiAgICByZXR1cm4gd3NNZXNzZW5nZXI7XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSB3ZWJzb2NrZXQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNZXNzZW5nZXJBUEkgPSByZXF1aXJlKCcuLi8uLi9tZXNzZW5nZXIvbV9hcGknKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG52YXIgV1NNc2dBUEkgPSBfLmNyZWF0ZVN1YmNsYXNzKE1lc3NlbmdlckFQSSwgJ1dTTXNnQVBJJywgdHJ1ZSk7XG5cblxuXy5leHRlbmRQcm90byhXU01zZ0FQSSwge1xuICAgIHRyYW5zbGF0ZVRvU291cmNlTWVzc2FnZTogdHJhbnNsYXRlVG9Tb3VyY2VNZXNzYWdlLFxuICAgIGZpbHRlclNvdXJjZU1lc3NhZ2U6IGZpbHRlclNvdXJjZU1lc3NhZ2UsXG4gICAgY3JlYXRlSW50ZXJuYWxEYXRhOiBjcmVhdGVJbnRlcm5hbERhdGFcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdTTXNnQVBJO1xuXG5cbnZhciBTT0NLRVRfTUVTU0FHRVMgPSBbJ29wZW4nLCAnY2xvc2UnLCAnZXJyb3InLCAnbWVzc2FnZSddO1xuXG5mdW5jdGlvbiB0cmFuc2xhdGVUb1NvdXJjZU1lc3NhZ2UobWVzc2FnZSkge1xuICAgIHJldHVybiBTT0NLRVRfTUVTU0FHRVMuaW5kZXhPZihtZXNzYWdlKSA+PSAwXG4gICAgICAgICAgICA/IG1lc3NhZ2VcbiAgICAgICAgICAgIDogJ21lc3NhZ2UnO1xufVxuXG5cbmZ1bmN0aW9uIGZpbHRlclNvdXJjZU1lc3NhZ2Uoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgbXNnRGF0YSkge1xuICAgIGlmIChTT0NLRVRfTUVTU0FHRVMuaW5kZXhPZihtZXNzYWdlKSA+PSAwKSByZXR1cm4gdHJ1ZTsgLy8gaW50ZXJuYWwgbWVzc2FnZSBpcyBvbmUgb2YgZXh0ZXJuYWwgbWVzc2FnZXNcbiAgICBpZiAoc291cmNlTWVzc2FnZSA9PSAnbWVzc2FnZScpIHtcbiAgICAgICAgdmFyIG1zZ1R5cGUgPSBtc2dEYXRhICYmIG1zZ0RhdGEudHlwZTtcbiAgICAgICAgcmV0dXJuIG1zZ1R5cGUgPT0gbWVzc2FnZTsgLy8gdHlwZSBlcXVhbHMgaW50ZXJuYWwgbWVzc2FnZVxuICAgIH1cbn07XG5cblxuZnVuY3Rpb24gY3JlYXRlSW50ZXJuYWxEYXRhKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIGV2ZW50KSB7XG4gICAgdmFyIGludGVybmFsRGF0YSA9IHNvdXJjZU1lc3NhZ2UgPT0gJ21lc3NhZ2UnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IF8uanNvblBhcnNlKGV2ZW50LmRhdGEpIHx8IGV2ZW50LmRhdGFcbiAgICAgICAgICAgICAgICAgICAgICAgIDogZXZlbnQ7XG4gICAgcmV0dXJuIGludGVybmFsRGF0YTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgTWVzc2FnZVNvdXJjZSA9IHJlcXVpcmUoJy4uLy4uL21lc3Nlbmdlci9tX3NvdXJjZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIHVuaXF1ZUlkID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9jb3VudCcpXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi8uLi9jb25maWcnKVxuICAgICwgY2hlY2sgPSByZXF1aXJlKCcuLi8uLi91dGlsL2NoZWNrJylcbiAgICAsIE1hdGNoID0gY2hlY2suTWF0Y2g7XG5cblxudmFyIFdTTWVzc2FnZVNvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoTWVzc2FnZVNvdXJjZSwgJ1dTTWVzc2FnZVNvdXJjZScsIHRydWUpO1xuXG5cbl8uZXh0ZW5kUHJvdG8oV1NNZXNzYWdlU291cmNlLCB7XG4gICAgLy8gaW1wbGVtZW50aW5nIE1lc3NhZ2VTb3VyY2UgaW50ZXJmYWNlXG4gICAgYWRkU291cmNlU3Vic2NyaWJlcjogYWRkU291cmNlU3Vic2NyaWJlcixcbiAgICByZW1vdmVTb3VyY2VTdWJzY3JpYmVyOiByZW1vdmVTb3VyY2VTdWJzY3JpYmVyLFxuICAgIFxuICAgIC8vIGNsYXNzIHNwZWNpZmljIG1ldGhvZHNcbiAgICBoYW5kbGVFdmVudDogV1NNZXNzYWdlU291cmNlJGhhbmRsZUV2ZW50LFxuICAgIGNvbm5lY3Q6IFdTTWVzc2FnZVNvdXJjZSRjb25uZWN0LFxuICAgIHRyaWdnZXI6IFdTTWVzc2FnZVNvdXJjZSR0cmlnZ2VyXG59KTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFdTTWVzc2FnZVNvdXJjZTtcblxuXG5mdW5jdGlvbiBXU01lc3NhZ2VTb3VyY2UkY29ubmVjdChvcHRpb25zKSB7XG4gICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgdmFyIGhvc3QgPSBvcHRpb25zLmhvc3QgfHwgd2luZG93LmxvY2F0aW9uLmhvc3QucmVwbGFjZSgvOi4qLywgJycpXG4gICAgICAgICwgcG9ydCA9IG9wdGlvbnMucG9ydCB8fCAnODA4MCc7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAodGhpcy5fd3MpIHtcbiAgICAgICAgLy8gVE9ETyBzaG91bGQgdW5zdWJzY3JpYmUgZGlmZmVyZW50bHlcbiAgICAgICAgdGhpcy5fd3Mub25vcGVuID0gdGhpcy53cy5vbm1lc3NhZ2UgPSB0aGlzLndzLm9uY2xvc2UgPSB0aGlzLndzLm9uZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX3dzLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fd3MgPSBuZXcgV2ViU29ja2V0KCd3czovLycgKyBob3N0ICsgJzonICsgcG9ydCk7XG5cbiAgICAvLyBUT0RPIHJlY29ubmVjdFxufVxuXG5cblxuZnVuY3Rpb24gYWRkU291cmNlU3Vic2NyaWJlciAoc291cmNlTWVzc2FnZSkge1xuICAgIF93c1N1YnNjcmliZXJNZXRob2QuY2FsbCh0aGlzLCAnYWRkRXZlbnRMaXN0ZW5lcicsIHNvdXJjZU1lc3NhZ2UpO1xufVxuXG5cbmZ1bmN0aW9uIHJlbW92ZVNvdXJjZVN1YnNjcmliZXIgKHNvdXJjZU1lc3NhZ2UpIHtcbiAgICBfd3NTdWJzY3JpYmVyTWV0aG9kLmNhbGwodGhpcywgJ3JlbW92ZUV2ZW50TGlzdGVuZXInLCBzb3VyY2VNZXNzYWdlKTtcbn1cblxuXG5mdW5jdGlvbiBfd3NTdWJzY3JpYmVyTWV0aG9kIChtZXRob2QsIHNvdXJjZU1lc3NhZ2UpIHsgICAgXG4gICAgaWYgKCF0aGlzLl93cykgcmV0dXJuIGxvZ2dlci5lcnJvcignd2Vic29ja2V0IGlzIG5vdCBjcmVhdGVkJyk7XG4gICAgdGhpcy5fd3NbbWV0aG9kXShzb3VyY2VNZXNzYWdlLCB0aGlzKTtcbn1cblxuXG4vLyBldmVudCBkaXNwYXRjaGVyIC0gYXMgZGVmaW5lZCBieSBFdmVudCBET00gQVBJXG5mdW5jdGlvbiBXU01lc3NhZ2VTb3VyY2UkaGFuZGxlRXZlbnQgKGV2ZW50KSB7XG4gICAgdGhpcy5kaXNwYXRjaE1lc3NhZ2UoZXZlbnQudHlwZSwgZXZlbnQpO1xufVxuXG5cbmZ1bmN0aW9uIFdTTWVzc2FnZVNvdXJjZSR0cmlnZ2VyIChtc2csIGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCF0aGlzLl93cykgcmV0dXJuIGxvZ2dlci5lcnJvcignd2Vic29ja2V0IGlzIG5vdCBjcmVhdGVkJyk7XG5cbiAgICBkYXRhID0gZGF0YSB8fCB7fTtcbiAgICBkYXRhLnR5cGUgPSBtc2c7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgXG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIGRhdGEuY2FsbGJhY2tDb3JySWQgPSB1bmlxdWVJZCgpO1xuICAgICAgICB2YXIgaW50ZXJ2YWwgPSBfLmRlbGF5KG9uVGltZW91dCwgY29uZmlnLndlYnNvY2tldC5ycGMudGltZW91dCk7XG4gICAgICAgIHRvZ2dsZVJwY1N1YnNjcmlwdGlvbignb25jZScsIGRhdGEuY2FsbGJhY2tDb3JySWQpO1xuICAgIH0gICAgXG5cbiAgICB0aGlzLl93cy5zZW5kKEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcblxuXG4gICAgZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgICB0b2dnbGVScGNTdWJzY3JpcHRpb24oJ29mZicsIGRhdGEuY2FsbGJhY2tDb3JySWQpO1xuICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ3dlYnNvY2tldCBycGM6IHRpbWVvdXQnKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25SZXNwb25zZShtc2csIG1zZ0RhdGEpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgIGlmICh0eXBlb2YgbXNnRGF0YSA9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdmFyIGVyciA9IG1zZ0RhdGEuZXJyb3IgPyBuZXcgRXJyb3IobXNnRGF0YS5lcnJvcikgOiBudWxsO1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBtc2dEYXRhLmRhdGEpXG4gICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgY2FsbGJhY2sobmV3IEVycm9yKCd3ZWJzb2NrZXQgcnBjOiBpbnZhbGlkIHJlc3BvbnNlIGRhdGEnKSwgbXNnRGF0YSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9nZ2xlUnBjU3Vic2NyaXB0aW9uKG9uT2ZmLCBjb3JySWQpIHtcbiAgICAgICAgc2VsZi5tZXNzZW5nZXJbb25PZmZdKGNvbmZpZy53ZWJzb2NrZXQucnBjLnJlc3BvbnNlUHJlZml4ICsgY29ycklkLCBvblJlc3BvbnNlKTtcbiAgICB9XG59XG4iLCI7KGZ1bmN0aW9uKCl7XG5cbi8vIFRoaXMgd291bGQgYmUgdGhlIHBsYWNlIHRvIGVkaXQgaWYgeW91IHdhbnQgYSBkaWZmZXJlbnRcbi8vIEJhc2UzMiBpbXBsZW1lbnRhdGlvblxuXG52YXIgYWxwaGFiZXQgPSAnMDEyMzQ1Njc4OWFiY2RlZmdoamttbnBxcnR1dnd4eXonXG52YXIgYWxpYXMgPSB7IG86MCwgaToxLCBsOjEsIHM6NSB9XG5cbi8qKlxuICogQnVpbGQgYSBsb29rdXAgdGFibGUgYW5kIG1lbW9pemUgaXRcbiAqXG4gKiBSZXR1cm4gYW4gb2JqZWN0IHRoYXQgbWFwcyBhIGNoYXJhY3RlciB0byBpdHNcbiAqIGJ5dGUgdmFsdWUuXG4gKi9cblxudmFyIGxvb2t1cCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciB0YWJsZSA9IHt9XG4gICAgLy8gSW52ZXJ0ICdhbHBoYWJldCdcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFscGhhYmV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRhYmxlW2FscGhhYmV0W2ldXSA9IGlcbiAgICB9XG4gICAgLy8gU3BsaWNlIGluICdhbGlhcydcbiAgICBmb3IgKHZhciBrZXkgaW4gYWxpYXMpIHtcbiAgICAgICAgaWYgKCFhbGlhcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZVxuICAgICAgICB0YWJsZVtrZXldID0gdGFibGVbJycgKyBhbGlhc1trZXldXVxuICAgIH1cbiAgICBsb29rdXAgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRhYmxlIH1cbiAgICByZXR1cm4gdGFibGVcbn1cblxuLyoqXG4gKiBBIHN0cmVhbWluZyBlbmNvZGVyXG4gKlxuICogICAgIHZhciBlbmNvZGVyID0gbmV3IGJhc2UzMi5FbmNvZGVyKClcbiAqICAgICB2YXIgb3V0cHV0MSA9IGVuY29kZXIudXBkYXRlKGlucHV0MSlcbiAqICAgICB2YXIgb3V0cHV0MiA9IGVuY29kZXIudXBkYXRlKGlucHV0MilcbiAqICAgICB2YXIgbGFzdG91dHB1dCA9IGVuY29kZS51cGRhdGUobGFzdGlucHV0LCB0cnVlKVxuICovXG5cbmZ1bmN0aW9uIEVuY29kZXIoKSB7XG4gICAgdmFyIHNraXAgPSAwIC8vIGhvdyBtYW55IGJpdHMgd2Ugd2lsbCBza2lwIGZyb20gdGhlIGZpcnN0IGJ5dGVcbiAgICB2YXIgYml0cyA9IDAgLy8gNSBoaWdoIGJpdHMsIGNhcnJ5IGZyb20gb25lIGJ5dGUgdG8gdGhlIG5leHRcblxuICAgIHRoaXMub3V0cHV0ID0gJydcblxuICAgIC8vIFJlYWQgb25lIGJ5dGUgb2YgaW5wdXRcbiAgICAvLyBTaG91bGQgbm90IHJlYWxseSBiZSB1c2VkIGV4Y2VwdCBieSBcInVwZGF0ZVwiXG4gICAgdGhpcy5yZWFkQnl0ZSA9IGZ1bmN0aW9uKGJ5dGUpIHtcbiAgICAgICAgLy8gY29lcmNlIHRoZSBieXRlIHRvIGFuIGludFxuICAgICAgICBpZiAodHlwZW9mIGJ5dGUgPT0gJ3N0cmluZycpIGJ5dGUgPSBieXRlLmNoYXJDb2RlQXQoMClcblxuICAgICAgICBpZiAoc2tpcCA8IDApIHsgLy8gd2UgaGF2ZSBhIGNhcnJ5IGZyb20gdGhlIHByZXZpb3VzIGJ5dGVcbiAgICAgICAgICAgIGJpdHMgfD0gKGJ5dGUgPj4gKC1za2lwKSlcbiAgICAgICAgfSBlbHNlIHsgLy8gbm8gY2FycnlcbiAgICAgICAgICAgIGJpdHMgPSAoYnl0ZSA8PCBza2lwKSAmIDI0OFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNraXAgPiAzKSB7XG4gICAgICAgICAgICAvLyBub3QgZW5vdWdoIGRhdGEgdG8gcHJvZHVjZSBhIGNoYXJhY3RlciwgZ2V0IHVzIGFub3RoZXIgb25lXG4gICAgICAgICAgICBza2lwIC09IDhcbiAgICAgICAgICAgIHJldHVybiAxXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2tpcCA8IDQpIHtcbiAgICAgICAgICAgIC8vIHByb2R1Y2UgYSBjaGFyYWN0ZXJcbiAgICAgICAgICAgIHRoaXMub3V0cHV0ICs9IGFscGhhYmV0W2JpdHMgPj4gM11cbiAgICAgICAgICAgIHNraXAgKz0gNVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIDBcbiAgICB9XG5cbiAgICAvLyBGbHVzaCBhbnkgcmVtYWluaW5nIGJpdHMgbGVmdCBpbiB0aGUgc3RyZWFtXG4gICAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbihjaGVjaykge1xuICAgICAgICB2YXIgb3V0cHV0ID0gdGhpcy5vdXRwdXQgKyAoc2tpcCA8IDAgPyBhbHBoYWJldFtiaXRzID4+IDNdIDogJycpICsgKGNoZWNrID8gJyQnIDogJycpXG4gICAgICAgIHRoaXMub3V0cHV0ID0gJydcbiAgICAgICAgcmV0dXJuIG91dHB1dFxuICAgIH1cbn1cblxuLyoqXG4gKiBQcm9jZXNzIGFkZGl0aW9uYWwgaW5wdXRcbiAqXG4gKiBpbnB1dDogc3RyaW5nIG9mIGJ5dGVzIHRvIGNvbnZlcnRcbiAqIGZsdXNoOiBib29sZWFuLCBzaG91bGQgd2UgZmx1c2ggYW55IHRyYWlsaW5nIGJpdHMgbGVmdFxuICogICAgICAgIGluIHRoZSBzdHJlYW1cbiAqIHJldHVybnM6IGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgcmVwcmVzZW50aW5nICdpbnB1dCcgaW4gYmFzZTMyXG4gKi9cblxuRW5jb2Rlci5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24oaW5wdXQsIGZsdXNoKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7ICkge1xuICAgICAgICBpICs9IHRoaXMucmVhZEJ5dGUoaW5wdXRbaV0pXG4gICAgfVxuICAgIC8vIGNvbnN1bWUgYWxsIG91dHB1dFxuICAgIHZhciBvdXRwdXQgPSB0aGlzLm91dHB1dFxuICAgIHRoaXMub3V0cHV0ID0gJydcbiAgICBpZiAoZmx1c2gpIHtcbiAgICAgIG91dHB1dCArPSB0aGlzLmZpbmlzaCgpXG4gICAgfVxuICAgIHJldHVybiBvdXRwdXRcbn1cblxuLy8gRnVuY3Rpb25zIGFuYWxvZ291c2x5IHRvIEVuY29kZXJcblxuZnVuY3Rpb24gRGVjb2RlcigpIHtcbiAgICB2YXIgc2tpcCA9IDAgLy8gaG93IG1hbnkgYml0cyB3ZSBoYXZlIGZyb20gdGhlIHByZXZpb3VzIGNoYXJhY3RlclxuICAgIHZhciBieXRlID0gMCAvLyBjdXJyZW50IGJ5dGUgd2UncmUgcHJvZHVjaW5nXG5cbiAgICB0aGlzLm91dHB1dCA9ICcnXG5cbiAgICAvLyBDb25zdW1lIGEgY2hhcmFjdGVyIGZyb20gdGhlIHN0cmVhbSwgc3RvcmVcbiAgICAvLyB0aGUgb3V0cHV0IGluIHRoaXMub3V0cHV0LiBBcyBiZWZvcmUsIGJldHRlclxuICAgIC8vIHRvIHVzZSB1cGRhdGUoKS5cbiAgICB0aGlzLnJlYWRDaGFyID0gZnVuY3Rpb24oY2hhcikge1xuICAgICAgICBpZiAodHlwZW9mIGNoYXIgIT0gJ3N0cmluZycpe1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjaGFyID09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgY2hhciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjaGFyID0gY2hhci50b0xvd2VyQ2FzZSgpXG4gICAgICAgIHZhciB2YWwgPSBsb29rdXAoKVtjaGFyXVxuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgLy8gY2hhcmFjdGVyIGRvZXMgbm90IGV4aXN0IGluIG91ciBsb29rdXAgdGFibGVcbiAgICAgICAgICAgIHJldHVybiAvLyBza2lwIHNpbGVudGx5LiBBbiBhbHRlcm5hdGl2ZSB3b3VsZCBiZTpcbiAgICAgICAgICAgIC8vIHRocm93IEVycm9yKCdDb3VsZCBub3QgZmluZCBjaGFyYWN0ZXIgXCInICsgY2hhciArICdcIiBpbiBsb29rdXAgdGFibGUuJylcbiAgICAgICAgfVxuICAgICAgICB2YWwgPDw9IDMgLy8gbW92ZSB0byB0aGUgaGlnaCBiaXRzXG4gICAgICAgIGJ5dGUgfD0gdmFsID4+PiBza2lwXG4gICAgICAgIHNraXAgKz0gNVxuICAgICAgICBpZiAoc2tpcCA+PSA4KSB7XG4gICAgICAgICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBwcmVkdWNlIG91dHB1dFxuICAgICAgICAgICAgdGhpcy5vdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlKVxuICAgICAgICAgICAgc2tpcCAtPSA4XG4gICAgICAgICAgICBpZiAoc2tpcCA+IDApIGJ5dGUgPSAodmFsIDw8ICg1IC0gc2tpcCkpICYgMjU1XG4gICAgICAgICAgICBlbHNlIGJ5dGUgPSAwXG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIHRoaXMuZmluaXNoID0gZnVuY3Rpb24oY2hlY2spIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMub3V0cHV0ICsgKHNraXAgPCAwID8gYWxwaGFiZXRbYml0cyA+PiAzXSA6ICcnKSArIChjaGVjayA/ICckJyA6ICcnKVxuICAgICAgICB0aGlzLm91dHB1dCA9ICcnXG4gICAgICAgIHJldHVybiBvdXRwdXRcbiAgICB9XG59XG5cbkRlY29kZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGlucHV0LCBmbHVzaCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5yZWFkQ2hhcihpbnB1dFtpXSlcbiAgICB9XG4gICAgdmFyIG91dHB1dCA9IHRoaXMub3V0cHV0XG4gICAgdGhpcy5vdXRwdXQgPSAnJ1xuICAgIGlmIChmbHVzaCkge1xuICAgICAgb3V0cHV0ICs9IHRoaXMuZmluaXNoKClcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dFxufVxuXG4vKiogQ29udmVuaWVuY2UgZnVuY3Rpb25zXG4gKlxuICogVGhlc2UgYXJlIHRoZSBvbmVzIHRvIHVzZSBpZiB5b3UganVzdCBoYXZlIGEgc3RyaW5nIGFuZFxuICogd2FudCB0byBjb252ZXJ0IGl0IHdpdGhvdXQgZGVhbGluZyB3aXRoIHN0cmVhbXMgYW5kIHdoYXRub3QuXG4gKi9cblxuLy8gU3RyaW5nIG9mIGRhdGEgZ29lcyBpbiwgQmFzZTMyLWVuY29kZWQgc3RyaW5nIGNvbWVzIG91dC5cbmZ1bmN0aW9uIGVuY29kZShpbnB1dCkge1xuICB2YXIgZW5jb2RlciA9IG5ldyBFbmNvZGVyKClcbiAgdmFyIG91dHB1dCA9IGVuY29kZXIudXBkYXRlKGlucHV0LCB0cnVlKVxuICByZXR1cm4gb3V0cHV0XG59XG5cbi8vIEJhc2UzMi1lbmNvZGVkIHN0cmluZyBnb2VzIGluLCBkZWNvZGVkIGRhdGEgY29tZXMgb3V0LlxuZnVuY3Rpb24gZGVjb2RlKGlucHV0KSB7XG4gICAgdmFyIGRlY29kZXIgPSBuZXcgRGVjb2RlcigpXG4gICAgdmFyIG91dHB1dCA9IGRlY29kZXIudXBkYXRlKGlucHV0LCB0cnVlKVxuICAgIHJldHVybiBvdXRwdXRcbn1cblxudmFyIGJhc2UzMiA9IHtcbiAgICBEZWNvZGVyOiBEZWNvZGVyLFxuICAgIEVuY29kZXI6IEVuY29kZXIsXG4gICAgZW5jb2RlOiBlbmNvZGUsXG4gICAgZGVjb2RlOiBkZWNvZGVcbn1cblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gIC8vIHdlJ3JlIGluIGEgYnJvd3NlciAtIE9NRyFcbiAgd2luZG93LmJhc2UzMiA9IGJhc2UzMlxufVxuXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgLy8gbm9kZWpzL2Jyb3dzZXJpZnlcbiAgbW9kdWxlLmV4cG9ydHMgPSBiYXNlMzJcbn1cbn0pKCk7XG4iLCJcbi8vIG5vdCBpbXBsZW1lbnRlZFxuLy8gVGhlIHJlYXNvbiBmb3IgaGF2aW5nIGFuIGVtcHR5IGZpbGUgYW5kIG5vdCB0aHJvd2luZyBpcyB0byBhbGxvd1xuLy8gdW50cmFkaXRpb25hbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1vZHVsZS5cbiIsIi8vIGRvVC5qc1xuLy8gMjAxMS0yMDE0LCBMYXVyYSBEb2t0b3JvdmEsIGh0dHBzOi8vZ2l0aHViLmNvbS9vbGFkby9kb1Rcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cblxuKGZ1bmN0aW9uKCkge1xuXHRcInVzZSBzdHJpY3RcIjtcblxuXHR2YXIgZG9UID0ge1xuXHRcdHZlcnNpb246IFwiMS4wLjNcIixcblx0XHR0ZW1wbGF0ZVNldHRpbmdzOiB7XG5cdFx0XHRldmFsdWF0ZTogICAgL1xce1xceyhbXFxzXFxTXSs/KFxcfT8pKylcXH1cXH0vZyxcblx0XHRcdGludGVycG9sYXRlOiAvXFx7XFx7PShbXFxzXFxTXSs/KVxcfVxcfS9nLFxuXHRcdFx0ZW5jb2RlOiAgICAgIC9cXHtcXHshKFtcXHNcXFNdKz8pXFx9XFx9L2csXG5cdFx0XHR1c2U6ICAgICAgICAgL1xce1xceyMoW1xcc1xcU10rPylcXH1cXH0vZyxcblx0XHRcdHVzZVBhcmFtczogICAvKF58W15cXHckXSlkZWYoPzpcXC58XFxbW1xcJ1xcXCJdKShbXFx3JFxcLl0rKSg/OltcXCdcXFwiXVxcXSk/XFxzKlxcOlxccyooW1xcdyRcXC5dK3xcXFwiW15cXFwiXStcXFwifFxcJ1teXFwnXStcXCd8XFx7W15cXH1dK1xcfSkvZyxcblx0XHRcdGRlZmluZTogICAgICAvXFx7XFx7IyNcXHMqKFtcXHdcXC4kXSspXFxzKihcXDp8PSkoW1xcc1xcU10rPykjXFx9XFx9L2csXG5cdFx0XHRkZWZpbmVQYXJhbXM6L15cXHMqKFtcXHckXSspOihbXFxzXFxTXSspLyxcblx0XHRcdGNvbmRpdGlvbmFsOiAvXFx7XFx7XFw/KFxcPyk/XFxzKihbXFxzXFxTXSo/KVxccypcXH1cXH0vZyxcblx0XHRcdGl0ZXJhdGU6ICAgICAvXFx7XFx7flxccyooPzpcXH1cXH18KFtcXHNcXFNdKz8pXFxzKlxcOlxccyooW1xcdyRdKylcXHMqKD86XFw6XFxzKihbXFx3JF0rKSk/XFxzKlxcfVxcfSkvZyxcblx0XHRcdHZhcm5hbWU6XHRcIml0XCIsXG5cdFx0XHRzdHJpcDpcdFx0dHJ1ZSxcblx0XHRcdGFwcGVuZDpcdFx0dHJ1ZSxcblx0XHRcdHNlbGZjb250YWluZWQ6IGZhbHNlLFxuXHRcdFx0ZG9Ob3RTa2lwRW5jb2RlZDogZmFsc2Vcblx0XHR9LFxuXHRcdHRlbXBsYXRlOiB1bmRlZmluZWQsIC8vZm4sIGNvbXBpbGUgdGVtcGxhdGVcblx0XHRjb21waWxlOiAgdW5kZWZpbmVkICAvL2ZuLCBmb3IgZXhwcmVzc1xuXHR9LCBfZ2xvYmFscztcblxuXHRkb1QuZW5jb2RlSFRNTFNvdXJjZSA9IGZ1bmN0aW9uKGRvTm90U2tpcEVuY29kZWQpIHtcblx0XHR2YXIgZW5jb2RlSFRNTFJ1bGVzID0geyBcIiZcIjogXCImIzM4O1wiLCBcIjxcIjogXCImIzYwO1wiLCBcIj5cIjogXCImIzYyO1wiLCAnXCInOiBcIiYjMzQ7XCIsIFwiJ1wiOiBcIiYjMzk7XCIsIFwiL1wiOiBcIiYjNDc7XCIgfSxcblx0XHRcdG1hdGNoSFRNTCA9IGRvTm90U2tpcEVuY29kZWQgPyAvWyY8PlwiJ1xcL10vZyA6IC8mKD8hIz9cXHcrOyl8PHw+fFwifCd8XFwvL2c7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKGNvZGUpIHtcblx0XHRcdHJldHVybiBjb2RlID8gY29kZS50b1N0cmluZygpLnJlcGxhY2UobWF0Y2hIVE1MLCBmdW5jdGlvbihtKSB7cmV0dXJuIGVuY29kZUhUTUxSdWxlc1ttXSB8fCBtO30pIDogXCJcIjtcblx0XHR9O1xuXHR9O1xuXG5cdF9nbG9iYWxzID0gKGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzIHx8ICgwLGV2YWwpKFwidGhpc1wiKTsgfSgpKTtcblxuXHRpZiAodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZG9UO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0ZGVmaW5lKGZ1bmN0aW9uKCl7cmV0dXJuIGRvVDt9KTtcblx0fSBlbHNlIHtcblx0XHRfZ2xvYmFscy5kb1QgPSBkb1Q7XG5cdH1cblxuXHR2YXIgc3RhcnRlbmQgPSB7XG5cdFx0YXBwZW5kOiB7IHN0YXJ0OiBcIicrKFwiLCAgICAgIGVuZDogXCIpKydcIiwgICAgICBzdGFydGVuY29kZTogXCInK2VuY29kZUhUTUwoXCIgfSxcblx0XHRzcGxpdDogIHsgc3RhcnQ6IFwiJztvdXQrPShcIiwgZW5kOiBcIik7b3V0Kz0nXCIsIHN0YXJ0ZW5jb2RlOiBcIic7b3V0Kz1lbmNvZGVIVE1MKFwiIH1cblx0fSwgc2tpcCA9IC8kXi87XG5cblx0ZnVuY3Rpb24gcmVzb2x2ZURlZnMoYywgYmxvY2ssIGRlZikge1xuXHRcdHJldHVybiAoKHR5cGVvZiBibG9jayA9PT0gXCJzdHJpbmdcIikgPyBibG9jayA6IGJsb2NrLnRvU3RyaW5nKCkpXG5cdFx0LnJlcGxhY2UoYy5kZWZpbmUgfHwgc2tpcCwgZnVuY3Rpb24obSwgY29kZSwgYXNzaWduLCB2YWx1ZSkge1xuXHRcdFx0aWYgKGNvZGUuaW5kZXhPZihcImRlZi5cIikgPT09IDApIHtcblx0XHRcdFx0Y29kZSA9IGNvZGUuc3Vic3RyaW5nKDQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCEoY29kZSBpbiBkZWYpKSB7XG5cdFx0XHRcdGlmIChhc3NpZ24gPT09IFwiOlwiKSB7XG5cdFx0XHRcdFx0aWYgKGMuZGVmaW5lUGFyYW1zKSB2YWx1ZS5yZXBsYWNlKGMuZGVmaW5lUGFyYW1zLCBmdW5jdGlvbihtLCBwYXJhbSwgdikge1xuXHRcdFx0XHRcdFx0ZGVmW2NvZGVdID0ge2FyZzogcGFyYW0sIHRleHQ6IHZ9O1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGlmICghKGNvZGUgaW4gZGVmKSkgZGVmW2NvZGVdPSB2YWx1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRuZXcgRnVuY3Rpb24oXCJkZWZcIiwgXCJkZWZbJ1wiK2NvZGUrXCInXT1cIiArIHZhbHVlKShkZWYpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gXCJcIjtcblx0XHR9KVxuXHRcdC5yZXBsYWNlKGMudXNlIHx8IHNraXAsIGZ1bmN0aW9uKG0sIGNvZGUpIHtcblx0XHRcdGlmIChjLnVzZVBhcmFtcykgY29kZSA9IGNvZGUucmVwbGFjZShjLnVzZVBhcmFtcywgZnVuY3Rpb24obSwgcywgZCwgcGFyYW0pIHtcblx0XHRcdFx0aWYgKGRlZltkXSAmJiBkZWZbZF0uYXJnICYmIHBhcmFtKSB7XG5cdFx0XHRcdFx0dmFyIHJ3ID0gKGQrXCI6XCIrcGFyYW0pLnJlcGxhY2UoLyd8XFxcXC9nLCBcIl9cIik7XG5cdFx0XHRcdFx0ZGVmLl9fZXhwID0gZGVmLl9fZXhwIHx8IHt9O1xuXHRcdFx0XHRcdGRlZi5fX2V4cFtyd10gPSBkZWZbZF0udGV4dC5yZXBsYWNlKG5ldyBSZWdFeHAoXCIoXnxbXlxcXFx3JF0pXCIgKyBkZWZbZF0uYXJnICsgXCIoW15cXFxcdyRdKVwiLCBcImdcIiksIFwiJDFcIiArIHBhcmFtICsgXCIkMlwiKTtcblx0XHRcdFx0XHRyZXR1cm4gcyArIFwiZGVmLl9fZXhwWydcIitydytcIiddXCI7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0dmFyIHYgPSBuZXcgRnVuY3Rpb24oXCJkZWZcIiwgXCJyZXR1cm4gXCIgKyBjb2RlKShkZWYpO1xuXHRcdFx0cmV0dXJuIHYgPyByZXNvbHZlRGVmcyhjLCB2LCBkZWYpIDogdjtcblx0XHR9KTtcblx0fVxuXG5cdGZ1bmN0aW9uIHVuZXNjYXBlKGNvZGUpIHtcblx0XHRyZXR1cm4gY29kZS5yZXBsYWNlKC9cXFxcKCd8XFxcXCkvZywgXCIkMVwiKS5yZXBsYWNlKC9bXFxyXFx0XFxuXS9nLCBcIiBcIik7XG5cdH1cblxuXHRkb1QudGVtcGxhdGUgPSBmdW5jdGlvbih0bXBsLCBjLCBkZWYpIHtcblx0XHRjID0gYyB8fCBkb1QudGVtcGxhdGVTZXR0aW5ncztcblx0XHR2YXIgY3NlID0gYy5hcHBlbmQgPyBzdGFydGVuZC5hcHBlbmQgOiBzdGFydGVuZC5zcGxpdCwgbmVlZGh0bWxlbmNvZGUsIHNpZCA9IDAsIGluZHYsXG5cdFx0XHRzdHIgID0gKGMudXNlIHx8IGMuZGVmaW5lKSA/IHJlc29sdmVEZWZzKGMsIHRtcGwsIGRlZiB8fCB7fSkgOiB0bXBsO1xuXG5cdFx0c3RyID0gKFwidmFyIG91dD0nXCIgKyAoYy5zdHJpcCA/IHN0ci5yZXBsYWNlKC8oXnxcXHJ8XFxuKVxcdCogK3wgK1xcdCooXFxyfFxcbnwkKS9nLFwiIFwiKVxuXHRcdFx0XHRcdC5yZXBsYWNlKC9cXHJ8XFxufFxcdHxcXC9cXCpbXFxzXFxTXSo/XFwqXFwvL2csXCJcIik6IHN0cilcblx0XHRcdC5yZXBsYWNlKC8nfFxcXFwvZywgXCJcXFxcJCZcIilcblx0XHRcdC5yZXBsYWNlKGMuaW50ZXJwb2xhdGUgfHwgc2tpcCwgZnVuY3Rpb24obSwgY29kZSkge1xuXHRcdFx0XHRyZXR1cm4gY3NlLnN0YXJ0ICsgdW5lc2NhcGUoY29kZSkgKyBjc2UuZW5kO1xuXHRcdFx0fSlcblx0XHRcdC5yZXBsYWNlKGMuZW5jb2RlIHx8IHNraXAsIGZ1bmN0aW9uKG0sIGNvZGUpIHtcblx0XHRcdFx0bmVlZGh0bWxlbmNvZGUgPSB0cnVlO1xuXHRcdFx0XHRyZXR1cm4gY3NlLnN0YXJ0ZW5jb2RlICsgdW5lc2NhcGUoY29kZSkgKyBjc2UuZW5kO1xuXHRcdFx0fSlcblx0XHRcdC5yZXBsYWNlKGMuY29uZGl0aW9uYWwgfHwgc2tpcCwgZnVuY3Rpb24obSwgZWxzZWNhc2UsIGNvZGUpIHtcblx0XHRcdFx0cmV0dXJuIGVsc2VjYXNlID9cblx0XHRcdFx0XHQoY29kZSA/IFwiJzt9ZWxzZSBpZihcIiArIHVuZXNjYXBlKGNvZGUpICsgXCIpe291dCs9J1wiIDogXCInO31lbHNle291dCs9J1wiKSA6XG5cdFx0XHRcdFx0KGNvZGUgPyBcIic7aWYoXCIgKyB1bmVzY2FwZShjb2RlKSArIFwiKXtvdXQrPSdcIiA6IFwiJzt9b3V0Kz0nXCIpO1xuXHRcdFx0fSlcblx0XHRcdC5yZXBsYWNlKGMuaXRlcmF0ZSB8fCBza2lwLCBmdW5jdGlvbihtLCBpdGVyYXRlLCB2bmFtZSwgaW5hbWUpIHtcblx0XHRcdFx0aWYgKCFpdGVyYXRlKSByZXR1cm4gXCInO30gfSBvdXQrPSdcIjtcblx0XHRcdFx0c2lkKz0xOyBpbmR2PWluYW1lIHx8IFwiaVwiK3NpZDsgaXRlcmF0ZT11bmVzY2FwZShpdGVyYXRlKTtcblx0XHRcdFx0cmV0dXJuIFwiJzt2YXIgYXJyXCIrc2lkK1wiPVwiK2l0ZXJhdGUrXCI7aWYoYXJyXCIrc2lkK1wiKXt2YXIgXCIrdm5hbWUrXCIsXCIraW5kditcIj0tMSxsXCIrc2lkK1wiPWFyclwiK3NpZCtcIi5sZW5ndGgtMTt3aGlsZShcIitpbmR2K1wiPGxcIitzaWQrXCIpe1wiXG5cdFx0XHRcdFx0K3ZuYW1lK1wiPWFyclwiK3NpZCtcIltcIitpbmR2K1wiKz0xXTtvdXQrPSdcIjtcblx0XHRcdH0pXG5cdFx0XHQucmVwbGFjZShjLmV2YWx1YXRlIHx8IHNraXAsIGZ1bmN0aW9uKG0sIGNvZGUpIHtcblx0XHRcdFx0cmV0dXJuIFwiJztcIiArIHVuZXNjYXBlKGNvZGUpICsgXCJvdXQrPSdcIjtcblx0XHRcdH0pXG5cdFx0XHQrIFwiJztyZXR1cm4gb3V0O1wiKVxuXHRcdFx0LnJlcGxhY2UoL1xcbi9nLCBcIlxcXFxuXCIpLnJlcGxhY2UoL1xcdC9nLCAnXFxcXHQnKS5yZXBsYWNlKC9cXHIvZywgXCJcXFxcclwiKVxuXHRcdFx0LnJlcGxhY2UoLyhcXHN8O3xcXH18XnxcXHspb3V0XFwrPScnOy9nLCAnJDEnKS5yZXBsYWNlKC9cXCsnJy9nLCBcIlwiKTtcblx0XHRcdC8vLnJlcGxhY2UoLyhcXHN8O3xcXH18XnxcXHspb3V0XFwrPScnXFwrL2csJyQxb3V0Kz0nKTtcblxuXHRcdGlmIChuZWVkaHRtbGVuY29kZSkge1xuXHRcdFx0aWYgKCFjLnNlbGZjb250YWluZWQgJiYgX2dsb2JhbHMgJiYgIV9nbG9iYWxzLl9lbmNvZGVIVE1MKSBfZ2xvYmFscy5fZW5jb2RlSFRNTCA9IGRvVC5lbmNvZGVIVE1MU291cmNlKGMuZG9Ob3RTa2lwRW5jb2RlZCk7XG5cdFx0XHRzdHIgPSBcInZhciBlbmNvZGVIVE1MID0gdHlwZW9mIF9lbmNvZGVIVE1MICE9PSAndW5kZWZpbmVkJyA/IF9lbmNvZGVIVE1MIDogKFwiXG5cdFx0XHRcdCsgZG9ULmVuY29kZUhUTUxTb3VyY2UudG9TdHJpbmcoKSArIFwiKFwiICsgKGMuZG9Ob3RTa2lwRW5jb2RlZCB8fCAnJykgKyBcIikpO1wiXG5cdFx0XHRcdCsgc3RyO1xuXHRcdH1cblx0XHR0cnkge1xuXHRcdFx0cmV0dXJuIG5ldyBGdW5jdGlvbihjLnZhcm5hbWUsIHN0cik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0aWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiKSBjb25zb2xlLmxvZyhcIkNvdWxkIG5vdCBjcmVhdGUgYSB0ZW1wbGF0ZSBmdW5jdGlvbjogXCIgKyBzdHIpO1xuXHRcdFx0dGhyb3cgZTtcblx0XHR9XG5cdH07XG5cblx0ZG9ULmNvbXBpbGUgPSBmdW5jdGlvbih0bXBsLCBkZWYpIHtcblx0XHRyZXR1cm4gZG9ULnRlbXBsYXRlKHRtcGwsIG51bGwsIGRlZik7XG5cdH07XG59KCkpO1xuIiwiLyogZG9UICsgYXV0by1jb21waWxhdGlvbiBvZiBkb1QgdGVtcGxhdGVzXG4gKlxuICogMjAxMiwgTGF1cmEgRG9rdG9yb3ZhLCBodHRwczovL2dpdGh1Yi5jb20vb2xhZG8vZG9UXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqXG4gKiBDb21waWxlcyAuZGVmLCAuZG90LCAuanN0IGZpbGVzIGZvdW5kIHVuZGVyIHRoZSBzcGVjaWZpZWQgcGF0aC5cbiAqIEl0IGlnbm9yZXMgc3ViLWRpcmVjdG9yaWVzLlxuICogVGVtcGxhdGUgZmlsZXMgY2FuIGhhdmUgbXVsdGlwbGUgZXh0ZW5zaW9ucyBhdCB0aGUgc2FtZSB0aW1lLlxuICogRmlsZXMgd2l0aCAuZGVmIGV4dGVuc2lvbiBjYW4gYmUgaW5jbHVkZWQgaW4gb3RoZXIgZmlsZXMgdmlhIHt7I2RlZi5uYW1lfX1cbiAqIEZpbGVzIHdpdGggLmRvdCBleHRlbnNpb24gYXJlIGNvbXBpbGVkIGludG8gZnVuY3Rpb25zIHdpdGggdGhlIHNhbWUgbmFtZSBhbmRcbiAqIGNhbiBiZSBhY2Nlc3NlZCBhcyByZW5kZXJlci5maWxlbmFtZVxuICogRmlsZXMgd2l0aCAuanN0IGV4dGVuc2lvbiBhcmUgY29tcGlsZWQgaW50byAuanMgZmlsZXMuIFByb2R1Y2VkIC5qcyBmaWxlIGNhbiBiZVxuICogbG9hZGVkIGFzIGEgY29tbW9uSlMsIEFNRCBtb2R1bGUsIG9yIGp1c3QgaW5zdGFsbGVkIGludG8gYSBnbG9iYWwgdmFyaWFibGVcbiAqIChkZWZhdWx0IGlzIHNldCB0byB3aW5kb3cucmVuZGVyKS5cbiAqIEFsbCBpbmxpbmUgZGVmaW5lcyBkZWZpbmVkIGluIHRoZSAuanN0IGZpbGUgYXJlXG4gKiBjb21waWxlZCBpbnRvIHNlcGFyYXRlIGZ1bmN0aW9ucyBhbmQgYXJlIGF2YWlsYWJsZSB2aWEgX3JlbmRlci5maWxlbmFtZS5kZWZpbmVuYW1lXG4gKlxuICogQmFzaWMgdXNhZ2U6XG4gKiB2YXIgZG90cyA9IHJlcXVpcmUoXCJkb3RcIikucHJvY2Vzcyh7cGF0aDogXCIuL3ZpZXdzXCJ9KTtcbiAqIGRvdHMubXl0ZW1wbGF0ZSh7Zm9vOlwiaGVsbG8gd29ybGRcIn0pO1xuICpcbiAqIFRoZSBhYm92ZSBzbmlwcGV0IHdpbGw6XG4gKiAxLiBDb21waWxlIGFsbCB0ZW1wbGF0ZXMgaW4gdmlld3MgZm9sZGVyICguZG90LCAuZGVmLCAuanN0KVxuICogMi4gUGxhY2UgLmpzIGZpbGVzIGNvbXBpbGVkIGZyb20gLmpzdCB0ZW1wbGF0ZXMgaW50byB0aGUgc2FtZSBmb2xkZXIuXG4gKiAgICBUaGVzZSBmaWxlcyBjYW4gYmUgdXNlZCB3aXRoIHJlcXVpcmUsIGkuZS4gcmVxdWlyZShcIi4vdmlld3MvbXl0ZW1wbGF0ZVwiKS5cbiAqIDMuIFJldHVybiBhbiBvYmplY3Qgd2l0aCBmdW5jdGlvbnMgY29tcGlsZWQgZnJvbSAuZG90IHRlbXBsYXRlcyBhcyBpdHMgcHJvcGVydGllcy5cbiAqIDQuIFJlbmRlciBteXRlbXBsYXRlIHRlbXBsYXRlLlxuICovXG5cbnZhciBmcyA9IHJlcXVpcmUoXCJmc1wiKSxcblx0ZG9UID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9kb1RcIik7XG5cbmRvVC5wcm9jZXNzID0gZnVuY3Rpb24ob3B0aW9ucykge1xuXHQvL3BhdGgsIGRlc3RpbmF0aW9uLCBnbG9iYWwsIHJlbmRlcm1vZHVsZSwgdGVtcGxhdGVTZXR0aW5nc1xuXHRyZXR1cm4gbmV3IEluc3RhbGxEb3RzKG9wdGlvbnMpLmNvbXBpbGVBbGwoKTtcbn07XG5cbmZ1bmN0aW9uIEluc3RhbGxEb3RzKG8pIHtcblx0dGhpcy5fX3BhdGggXHRcdD0gby5wYXRoIHx8IFwiLi9cIjtcblx0aWYgKHRoaXMuX19wYXRoW3RoaXMuX19wYXRoLmxlbmd0aC0xXSAhPT0gJy8nKSB0aGlzLl9fcGF0aCArPSAnLyc7XG5cdHRoaXMuX19kZXN0aW5hdGlvblx0PSBvLmRlc3RpbmF0aW9uIHx8IHRoaXMuX19wYXRoO1xuXHRpZiAodGhpcy5fX2Rlc3RpbmF0aW9uW3RoaXMuX19kZXN0aW5hdGlvbi5sZW5ndGgtMV0gIT09ICcvJykgdGhpcy5fX2Rlc3RpbmF0aW9uICs9ICcvJztcblx0dGhpcy5fX2dsb2JhbFx0XHQ9IG8uZ2xvYmFsIHx8IFwid2luZG93LnJlbmRlclwiO1xuXHR0aGlzLl9fcmVuZGVybW9kdWxlXHQ9IG8ucmVuZGVybW9kdWxlIHx8IHt9O1xuXHR0aGlzLl9fc2V0dGluZ3MgXHQ9IG8udGVtcGxhdGVTZXR0aW5ncyA/IGNvcHkoby50ZW1wbGF0ZVNldHRpbmdzLCBjb3B5KGRvVC50ZW1wbGF0ZVNldHRpbmdzKSkgOiB1bmRlZmluZWQ7XG5cdHRoaXMuX19pbmNsdWRlc1x0XHQ9IHt9O1xufVxuXG5JbnN0YWxsRG90cy5wcm90b3R5cGUuY29tcGlsZVRvRmlsZSA9IGZ1bmN0aW9uKHBhdGgsIHRlbXBsYXRlLCBkZWYpIHtcblx0ZGVmID0gZGVmIHx8IHt9O1xuXHR2YXIgbW9kdWxlbmFtZSA9IHBhdGguc3Vic3RyaW5nKHBhdGgubGFzdEluZGV4T2YoXCIvXCIpKzEsIHBhdGgubGFzdEluZGV4T2YoXCIuXCIpKVxuXHRcdCwgZGVmcyA9IGNvcHkodGhpcy5fX2luY2x1ZGVzLCBjb3B5KGRlZikpXG5cdFx0LCBzZXR0aW5ncyA9IHRoaXMuX19zZXR0aW5ncyB8fCBkb1QudGVtcGxhdGVTZXR0aW5nc1xuXHRcdCwgY29tcGlsZW9wdGlvbnMgPSBjb3B5KHNldHRpbmdzKVxuXHRcdCwgZGVmYXVsdGNvbXBpbGVkID0gZG9ULnRlbXBsYXRlKHRlbXBsYXRlLCBzZXR0aW5ncywgZGVmcylcblx0XHQsIGV4cG9ydHMgPSBbXVxuXHRcdCwgY29tcGlsZWQgPSBcIlwiXG5cdFx0LCBmbjtcblxuXHRmb3IgKHZhciBwcm9wZXJ0eSBpbiBkZWZzKSB7XG5cdFx0aWYgKGRlZnNbcHJvcGVydHldICE9PSBkZWZbcHJvcGVydHldICYmIGRlZnNbcHJvcGVydHldICE9PSB0aGlzLl9faW5jbHVkZXNbcHJvcGVydHldKSB7XG5cdFx0XHRmbiA9IHVuZGVmaW5lZDtcblx0XHRcdGlmICh0eXBlb2YgZGVmc1twcm9wZXJ0eV0gPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdGZuID0gZG9ULnRlbXBsYXRlKGRlZnNbcHJvcGVydHldLCBzZXR0aW5ncywgZGVmcyk7XG5cdFx0XHR9IGVsc2UgaWYgKHR5cGVvZiBkZWZzW3Byb3BlcnR5XSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRmbiA9IGRlZnNbcHJvcGVydHldO1xuXHRcdFx0fSBlbHNlIGlmIChkZWZzW3Byb3BlcnR5XS5hcmcpIHtcblx0XHRcdFx0Y29tcGlsZW9wdGlvbnMudmFybmFtZSA9IGRlZnNbcHJvcGVydHldLmFyZztcblx0XHRcdFx0Zm4gPSBkb1QudGVtcGxhdGUoZGVmc1twcm9wZXJ0eV0udGV4dCwgY29tcGlsZW9wdGlvbnMsIGRlZnMpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGZuKSB7XG5cdFx0XHRcdGNvbXBpbGVkICs9IGZuLnRvU3RyaW5nKCkucmVwbGFjZSgnYW5vbnltb3VzJywgcHJvcGVydHkpO1xuXHRcdFx0XHRleHBvcnRzLnB1c2gocHJvcGVydHkpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRjb21waWxlZCArPSBkZWZhdWx0Y29tcGlsZWQudG9TdHJpbmcoKS5yZXBsYWNlKCdhbm9ueW1vdXMnLCBtb2R1bGVuYW1lKTtcblx0ZnMud3JpdGVGaWxlU3luYyhwYXRoLCBcIihmdW5jdGlvbigpe1wiICsgY29tcGlsZWRcblx0XHQrIFwidmFyIGl0c2VsZj1cIiArIG1vZHVsZW5hbWUgKyBcIiwgX2VuY29kZUhUTUw9KFwiICsgZG9ULmVuY29kZUhUTUxTb3VyY2UudG9TdHJpbmcoKSArIFwiKFwiICsgKHNldHRpbmdzLmRvTm90U2tpcEVuY29kZWQgfHwgJycpICsgXCIpKTtcIlxuXHRcdCsgYWRkZXhwb3J0cyhleHBvcnRzKVxuXHRcdCsgXCJpZih0eXBlb2YgbW9kdWxlIT09J3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIG1vZHVsZS5leHBvcnRzPWl0c2VsZjtlbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT0nZnVuY3Rpb24nKWRlZmluZShmdW5jdGlvbigpe3JldHVybiBpdHNlbGY7fSk7ZWxzZSB7XCJcblx0XHQrIHRoaXMuX19nbG9iYWwgKyBcIj1cIiArIHRoaXMuX19nbG9iYWwgKyBcInx8e307XCIgKyB0aGlzLl9fZ2xvYmFsICsgXCJbJ1wiICsgbW9kdWxlbmFtZSArIFwiJ109aXRzZWxmO319KCkpO1wiKTtcbn07XG5cbmZ1bmN0aW9uIGFkZGV4cG9ydHMoZXhwb3J0cykge1xuXHRmb3IgKHZhciByZXQgPScnLCBpPTA7IGk8IGV4cG9ydHMubGVuZ3RoOyBpKyspIHtcblx0XHRyZXQgKz0gXCJpdHNlbGYuXCIgKyBleHBvcnRzW2ldKyBcIj1cIiArIGV4cG9ydHNbaV0rXCI7XCI7XG5cdH1cblx0cmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gY29weShvLCB0bykge1xuXHR0byA9IHRvIHx8IHt9O1xuXHRmb3IgKHZhciBwcm9wZXJ0eSBpbiBvKSB7XG5cdFx0dG9bcHJvcGVydHldID0gb1twcm9wZXJ0eV07XG5cdH1cblx0cmV0dXJuIHRvO1xufVxuXG5mdW5jdGlvbiByZWFkZGF0YShwYXRoKSB7XG5cdHZhciBkYXRhID0gZnMucmVhZEZpbGVTeW5jKHBhdGgpO1xuXHRpZiAoZGF0YSkgcmV0dXJuIGRhdGEudG9TdHJpbmcoKTtcblx0Y29uc29sZS5sb2coXCJwcm9ibGVtcyB3aXRoIFwiICsgcGF0aCk7XG59XG5cbkluc3RhbGxEb3RzLnByb3RvdHlwZS5jb21waWxlUGF0aCA9IGZ1bmN0aW9uKHBhdGgpIHtcblx0dmFyIGRhdGEgPSByZWFkZGF0YShwYXRoKTtcblx0aWYgKGRhdGEpIHtcblx0XHRyZXR1cm4gZG9ULnRlbXBsYXRlKGRhdGEsXG5cdFx0XHRcdFx0dGhpcy5fX3NldHRpbmdzIHx8IGRvVC50ZW1wbGF0ZVNldHRpbmdzLFxuXHRcdFx0XHRcdGNvcHkodGhpcy5fX2luY2x1ZGVzKSk7XG5cdH1cbn07XG5cbkluc3RhbGxEb3RzLnByb3RvdHlwZS5jb21waWxlQWxsID0gZnVuY3Rpb24oKSB7XG5cdGNvbnNvbGUubG9nKFwiQ29tcGlsaW5nIGFsbCBkb1QgdGVtcGxhdGVzLi4uXCIpO1xuXG5cdHZhciBkZWZGb2xkZXIgPSB0aGlzLl9fcGF0aCxcblx0XHRzb3VyY2VzID0gZnMucmVhZGRpclN5bmMoZGVmRm9sZGVyKSxcblx0XHRrLCBsLCBuYW1lO1xuXG5cdGZvciggayA9IDAsIGwgPSBzb3VyY2VzLmxlbmd0aDsgayA8IGw7IGsrKykge1xuXHRcdG5hbWUgPSBzb3VyY2VzW2tdO1xuXHRcdGlmICgvXFwuZGVmKFxcLmRvdHxcXC5qc3QpPyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiTG9hZGVkIGRlZiBcIiArIG5hbWUpO1xuXHRcdFx0dGhpcy5fX2luY2x1ZGVzW25hbWUuc3Vic3RyaW5nKDAsIG5hbWUuaW5kZXhPZignLicpKV0gPSByZWFkZGF0YShkZWZGb2xkZXIgKyBuYW1lKTtcblx0XHR9XG5cdH1cblxuXHRmb3IoIGsgPSAwLCBsID0gc291cmNlcy5sZW5ndGg7IGsgPCBsOyBrKyspIHtcblx0XHRuYW1lID0gc291cmNlc1trXTtcblx0XHRpZiAoL1xcLmRvdChcXC5kZWZ8XFwuanN0KT8kLy50ZXN0KG5hbWUpKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkNvbXBpbGluZyBcIiArIG5hbWUgKyBcIiB0byBmdW5jdGlvblwiKTtcblx0XHRcdHRoaXMuX19yZW5kZXJtb2R1bGVbbmFtZS5zdWJzdHJpbmcoMCwgbmFtZS5pbmRleE9mKCcuJykpXSA9IHRoaXMuY29tcGlsZVBhdGgoZGVmRm9sZGVyICsgbmFtZSk7XG5cdFx0fVxuXHRcdGlmICgvXFwuanN0KFxcLmRvdHxcXC5kZWYpPyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiQ29tcGlsaW5nIFwiICsgbmFtZSArIFwiIHRvIGZpbGVcIik7XG5cdFx0XHR0aGlzLmNvbXBpbGVUb0ZpbGUodGhpcy5fX2Rlc3RpbmF0aW9uICsgbmFtZS5zdWJzdHJpbmcoMCwgbmFtZS5pbmRleE9mKCcuJykpICsgJy5qcycsXG5cdFx0XHRcdFx0cmVhZGRhdGEoZGVmRm9sZGVyICsgbmFtZSkpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gdGhpcy5fX3JlbmRlcm1vZHVsZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBjb25maWcgPSByZXF1aXJlKCcuLi9jb25maWcnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IE1peGluO1xuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuTWl4aW5gIC0gYW4gYWJzdHJhY3QgTWl4aW4gY2xhc3MuXG4gKiBDYW4gYmUgc3ViY2xhc3NlZCB1c2luZzpcbiAqIGBgYFxuICogdmFyIE15TWl4aW4gPSBfLmNyZWF0ZVN1YmNsYXNzKG1pbG8uY2xhc3Nlcy5NaXhpbiwgJ015TWl4aW4nKTtcbiAqIGBgYFxuICpcbiAqIE1peGluIHBhdHRlcm4gaXMgYWxzbyB1c2VkLCBidXQgTWl4aW4gaW4gbWlsbyBpcyBpbXBsZW1lbnRlZCBhcyBhIHNlcGFyYXRlIG9iamVjdCB0aGF0IGlzIHN0b3JlZCBvbiB0aGUgcHJvcGVydHkgb2YgdGhlIGhvc3Qgb2JqZWN0IGFuZCBjYW4gY3JlYXRlIHByb3h5IG1ldGhvZHMgb24gdGhlIGhvc3Qgb2JqZWN0IGlmIHJlcXVpcmVkLlxuICogQ2xhc3NlcyBbTWVzc2VuZ2VyXSguLi9tZXNzZW5nZXIvaW5kZXguanMuaHRtbCkgYW5kIFtNZXNzYWdlU291cmNlXSguLi9tZXNzZW5nZXIvbV9zb3VyY2UuanMuaHRtbCkgYXJlIHN1YmNsYXNzZXMgb2YgTWl4aW4gYWJzdHJhY3QgY2xhc3MuIGB0aGlzYCBpbiBwcm94eSBtZXRob2RzIHJlZmVycyB0byBNaXhpbiBpbnN0YW5jZSwgdGhlIHJlZmVyZW5jZSB0byB0aGUgaG9zdCBvYmplY3QgaXMgYHRoaXMuX2hvc3RPYmplY3RgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IE9wdGlvbmFsIG9iamVjdCB3aGVyZSBhIE1peGluIGluc3RhbmNlIHdpbGwgYmUgc3RvcmVkIG9uLiBJdCBpcyB1c2VkIHRvIHByb3h5IG1ldGhvZHMgYW5kIGFsc28gdG8gZmluZCB0aGUgcmVmZXJlbmNlIHdoZW4gaXQgaXMgbmVlZGVkIGZvciBob3N0IG9iamVjdCBpbXBsZW1lbnRhdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm94eU1ldGhvZHMgT3B0aW9uYWwgbWFwIG9mIHByb3h5IG1ldGhvZCBuYW1lcyBhcyBrZXlzIGFuZCBNaXhpbiBtZXRob2RzIG5hbWVzIGFzIHZhbHVlcywgc28gcHJveGllZCBtZXRob2RzIGNhbiBiZSByZW5hbWVkIHRvIGF2b2lkIG5hbWUtc3BhY2UgY29uZmxpY3RzIGlmIHR3byBkaWZmZXJlbnQgTWl4aW4gaW5zdGFuY2VzIHdpdGggdGhlIHNhbWUgbWV0aG9kIG5hbWVzIGFyZSBwdXQgb24gdGhlIG9iamVjdFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgYWxsIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCB0byBpbml0IG1ldGhvZCBvZiBNaXhpbiBzdWJjbGFzcyB0b2dldGhlciB3aXRoIGhvc3RPYmplY3QgYW5kIHByb3h5TWV0aG9kc1xuICogQHJldHVybiB7TWl4aW59XG4gKi9cbmZ1bmN0aW9uIE1peGluKGhvc3RPYmplY3QsIHByb3h5TWV0aG9kcykgeyAvLyAsIG90aGVyIGFyZ3MgLSBwYXNzZWQgdG8gaW5pdCBtZXRob2RcbiAgICBjaGVjayhob3N0T2JqZWN0LCBNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihPYmplY3QsIEZ1bmN0aW9uKSkpO1xuXG4gICAgLy8gc3RvcmUgaG9zdE9iamVjdFxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19ob3N0T2JqZWN0JywgaG9zdE9iamVjdCk7XG5cbiAgICAvLyBwcm94eSBtZXRob2RzIHRvIGhvc3RPYmplY3RcbiAgICBpZiAocHJveHlNZXRob2RzKVxuICAgICAgICB0aGlzLl9jcmVhdGVQcm94eU1ldGhvZHMocHJveHlNZXRob2RzKTtcblxuICAgIC8vIGNhbGxpbmcgaW5pdCBpZiBpdCBpcyBkZWZpbmVkIGluIHRoZSBjbGFzc1xuICAgIGlmICh0aGlzLmluaXQpXG4gICAgICAgIHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5cbi8qKlxuICogIyMjI01peGluIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKiBUaGVzZSBtZXRob2RzIGFyZSBjYWxsZWQgYnkgY29uc3RydWN0b3IsIHRoZXkgYXJlIG5vdCB0byBiZSBjYWxsZWQgZnJvbSBzdWJjbGFzc2VzLlxuICpcbiAqIC0gW19jcmVhdGVQcm94eU1ldGhvZF0oI19jcmVhdGVQcm94eU1ldGhvZClcbiAqIC0gW19jcmVhdGVQcm94eU1ldGhvZHNdKCNfY3JlYXRlUHJveHlNZXRob2RzKVxuICovXG5fLmV4dGVuZFByb3RvKE1peGluLCB7XG4gICAgX2NyZWF0ZVByb3h5TWV0aG9kOiBfY3JlYXRlUHJveHlNZXRob2QsICAvLyBkZXByZWNhdGVkLCBzaG91bGQgbm90IGJlIHVzZWRcbiAgICBfY3JlYXRlUHJveHlNZXRob2RzOiBfY3JlYXRlUHJveHlNZXRob2RzICAvLyBkZXByZWNhdGVkLCBzaG91bGQgbm90IGJlIHVzZWRcbn0pO1xuXG5cbi8qKlxuICogIyMjI01peGluIGNsYXNzIG1ldGhvZHMjIyMjXG4gKiBUaGVzZSBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBpbiBob3N0IGNsYXNzIGRlY2xhcmF0aW9uLlxuICpcbiAqIC0gW3VzZVdpdGhdKCNNaXhpbiQkdXNlV2l0aClcbiAqL1xuXy5leHRlbmQoTWl4aW4sIHtcbiAgICB1c2VXaXRoOiBNaXhpbiQkdXNlV2l0aFxufSk7XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgcHJveGllZCBtZXRob2Qgb2YgTWl4aW4gc3ViY2xhc3Mgb24gaG9zdCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1peGluTWV0aG9kTmFtZSBuYW1lIG9mIG1ldGhvZCBpbiBNaXhpbiBzdWJjbGFzc1xuICogQHBhcmFtIHtTdHJpbmd9IHByb3h5TWV0aG9kTmFtZSBuYW1lIG9mIGNyZWF0ZWQgcHJveHkgbWV0aG9kIG9uIGhvc3Qgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBPcHRpb25hbCByZWZlcmVuY2UgdG8gdGhlIGhvc3Qgb2JqZWN0OyBpZiBub3Qgc3BlY2lmaWVkIHRoZSBob3N0IG9iamVjdCBwYXNzZWQgdG8gY29uc3RydWN0b3Igd2lsIGJlIHVzZWQuIEl0IGFsbG93cyB0byB1c2UgdGhlIHNhbWUgaW5zdGFuY2Ugb2YgTWl4aW4gb24gdHdvIGhvc3Qgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gX2NyZWF0ZVByb3h5TWV0aG9kKHByb3h5TWV0aG9kTmFtZSwgbWl4aW5NZXRob2ROYW1lLCBob3N0T2JqZWN0KSB7XG4gICAgaG9zdE9iamVjdCA9IGhvc3RPYmplY3QgfHwgdGhpcy5faG9zdE9iamVjdDtcblxuICAgIC8vIE1peGluIGNsYXNzIGRvZXMgbm90IGFsbG93IHNoYWRvd2luZyBtZXRob2RzIHRoYXQgZXhpc3Qgb24gdGhlIGhvc3Qgb2JqZWN0XG4gICAgaWYgKGhvc3RPYmplY3RbcHJveHlNZXRob2ROYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtZXRob2QgJyArIHByb3h5TWV0aG9kTmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAnIGFscmVhZHkgZGVmaW5lZCBpbiBob3N0IG9iamVjdCcpO1xuXG4gICAgdmFyIG1ldGhvZCA9IHRoaXNbbWl4aW5NZXRob2ROYW1lXVxuICAgIGNoZWNrKG1ldGhvZCwgRnVuY3Rpb24pO1xuXG4gICAgLy8gQmluZCBwcm94aWVkIE1peGluJ3MgbWV0aG9kIHRvIE1peGluIGluc3RhbmNlXG4gICAgdmFyIGJvdW5kTWV0aG9kID0gbWV0aG9kLmJpbmQodGhpcyk7XG5cbiAgICBfLmRlZmluZVByb3BlcnR5KGhvc3RPYmplY3QsIHByb3h5TWV0aG9kTmFtZSwgYm91bmRNZXRob2QsIF8uV1JJVCk7XG59XG5cblxuLyoqXG4gKiBDcmVhdGVzIHByb3hpZWQgbWV0aG9kcyBvZiBNaXhpbiBzdWJjbGFzcyBvbiBob3N0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge0hhc2hbU3RyaW5nXXxBcnJheVtTdHJpbmddfSBwcm94eU1ldGhvZHMgbWFwIG9mIG5hbWVzIG9mIG1ldGhvZHMsIGtleSAtIHByb3h5IG1ldGhvZCBuYW1lLCB2YWx1ZSAtIG1peGluIG1ldGhvZCBuYW1lLiBDYW4gYmUgYXJyYXkuXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBhbiBvcHRpb25hbCByZWZlcmVuY2UgdG8gdGhlIGhvc3Qgb2JqZWN0OyBpZiBub3Qgc3BlY2lmaWVkIHRoZSBob3N0IG9iamVjdCBwYXNzZWQgdG8gY29uc3RydWN0b3Igd2lsIGJlIHVzZWQuIEl0IGFsbG93cyB0byB1c2UgdGhlIHNhbWUgaW5zdGFuY2Ugb2YgTWl4aW4gb24gdHdvIGhvc3Qgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gX2NyZWF0ZVByb3h5TWV0aG9kcyhwcm94eU1ldGhvZHMsIGhvc3RPYmplY3QpIHtcbiAgICBjaGVjayhwcm94eU1ldGhvZHMsIE1hdGNoLk9wdGlvbmFsKE1hdGNoLk9uZU9mKFtTdHJpbmddLCBNYXRjaC5PYmplY3RIYXNoKFN0cmluZykpKSk7XG5cbiAgICAvLyBjcmVhdGluZyBhbmQgYmluZGluZyBwcm94eSBtZXRob2RzIG9uIHRoZSBob3N0IG9iamVjdFxuICAgIGlmIChBcnJheS5pc0FycmF5KHByb3h5TWV0aG9kcykpXG4gICAgICAgIHByb3h5TWV0aG9kcy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgICAgIC8vIG1ldGhvZCBjYWxsZWQgdGhpcyB3YXkgdG8gYWxsb3cgdXNpbmcgX2NyZWF0ZVByb3h5TWV0aG9kcyB3aXRoIG9iamVjdHNcbiAgICAgICAgICAgIC8vIHRoYXQgYXJlIG5vdCBpbmhlcml0aW5nIGZyb20gTWl4aW5cbiAgICAgICAgICAgIF9jcmVhdGVQcm94eU1ldGhvZC5jYWxsKHRoaXMsIG1ldGhvZE5hbWUsIG1ldGhvZE5hbWUsIGhvc3RPYmplY3QpO1xuICAgICAgICB9LCB0aGlzKTtcbiAgICBlbHNlXG4gICAgICAgIF8uZWFjaEtleShwcm94eU1ldGhvZHMsIGZ1bmN0aW9uKG1peGluTWV0aG9kTmFtZSwgcHJveHlNZXRob2ROYW1lKSB7XG4gICAgICAgICAgICAvLyBtZXRob2QgY2FsbGVkIHRoaXMgd2F5IHRvIGFsbG93IHVzaW5nIF9jcmVhdGVQcm94eU1ldGhvZHMgd2l0aCBvYmplY3RzXG4gICAgICAgICAgICAvLyB0aGF0IGFyZSBub3QgaW5oZXJpdGluZyBmcm9tIE1peGluXG4gICAgICAgICAgICBfY3JlYXRlUHJveHlNZXRob2QuY2FsbCh0aGlzLCBwcm94eU1ldGhvZE5hbWUsIG1peGluTWV0aG9kTmFtZSwgaG9zdE9iamVjdCk7XG4gICAgICAgIH0sIHRoaXMpO1xufVxuXG5cbi8qKlxuICogU2V0cyBtaXhpbiBpbnN0YW5jZSBwcm9wZXJ0eSBuYW1lIG9uIHRoZSBob3N0IGNsYXNzXG4gKiBDYW4gYmUgY2FsbGVkIG9ubHkgb25jZVxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzIE1peGluIHN1YmNsYXNzIChub3QgaW5zdGFuY2UpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBob3N0Q2xhc3NcbiAqIEBwYXJhbSB7U3RyaW5nfSBpbnN0YW5jZUtleVxuICovXG5mdW5jdGlvbiBNaXhpbl9zZXRJbnN0YW5jZUtleShob3N0Q2xhc3MsIG1ldGhvZCwgaW5zdGFuY2VLZXkpIHtcbiAgICBjaGVjayhob3N0Q2xhc3MsIEZ1bmN0aW9uKTtcbiAgICBjaGVjayhpbnN0YW5jZUtleSwgTWF0Y2guSWRlbnRpZmllclN0cmluZyk7XG5cbiAgICB2YXIgcHJvcCA9IGNvbmZpZy5taXhpbi5pbnN0YW5jZVByb3BlcnRpZXNNYXBcbiAgICAgICAgLCBpbnN0YW5jZUtleXMgPSBob3N0Q2xhc3NbcHJvcF0gPSBob3N0Q2xhc3NbcHJvcF0gfHwge307XG5cbiAgICBpZiAoaW5zdGFuY2VLZXlzW21ldGhvZC5uYW1lXSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXhpbjogaW5zdGFuY2UgcHJvcGVydHkgZm9yIG1ldGhvZCB3aXRoIG5hbWUgJ1xuICAgICAgICAgICAgKyBtZXRob2QubmFtZSArICcgaXMgYWxyZWFkeSBzZXQnKTtcblxuICAgIGluc3RhbmNlS2V5c1ttZXRob2QubmFtZV0gPSBpbnN0YW5jZUtleTtcbn1cblxuXG4vKipcbiAqIEFkZHMgbWV0aG9kIG9mIE1peGluIHN1YmNsYXNzIHRvIGhvc3QgY2xhc3MgcHJvdG90eXBlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzIE1peGluIHN1YmNsYXNzIChub3QgaW5zdGFuY2UpXG4gKiBAcGFyYW0ge1N0cmluZ30gbWl4aW5NZXRob2ROYW1lIG5hbWUgb2YgbWV0aG9kIGluIE1peGluIHN1YmNsYXNzXG4gKiBAcGFyYW0ge1N0cmluZ30gaG9zdE1ldGhvZE5hbWUgKG9wdGlvbmFsKSBuYW1lIG9mIGNyZWF0ZWQgcHJveHkgbWV0aG9kIG9uIGhvc3Qgb2JqZWN0LCBzYW1lIGlmIG5vdCBzcGVjaWZpZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IG9iamVjdCBjbGFzcywgbXVzdCBiZSBzcGVjaWZpZWQgYXMgdGhlIGxhc3QgcGFyYW1ldGVyICgybmQgb3IgM3JkKVxuICovXG5mdW5jdGlvbiBNaXhpbl9hZGRNZXRob2QoaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2ROYW1lLCBob3N0TWV0aG9kTmFtZSkge1xuICAgIHZhciBtZXRob2QgPSB0aGlzLnByb3RvdHlwZVttaXhpbk1ldGhvZE5hbWVdO1xuICAgIGNoZWNrKG1ldGhvZCwgRnVuY3Rpb24pO1xuXG4gICAgdmFyIHdyYXBwZWRNZXRob2QgPSBfd3JhcE1peGluTWV0aG9kLmNhbGwodGhpcywgbWV0aG9kKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkoaG9zdENsYXNzLnByb3RvdHlwZSwgaG9zdE1ldGhvZE5hbWUsIHdyYXBwZWRNZXRob2QsIF8uV1JJVCk7XG5cbiAgICBNaXhpbl9zZXRJbnN0YW5jZUtleShob3N0Q2xhc3MsIG1ldGhvZCwgaW5zdGFuY2VLZXkpXG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIG1ldGhvZCB0aGF0IHdpbGwgYmUgZXhwb3NlZCBvbiB0aGUgaG9zdCBjbGFzcyBwcm90b3R5cGVcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gdGhpcyBNaXhpbiBzdWJjbGFzcyAobm90IGluc3RhbmNlKVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIF93cmFwTWl4aW5NZXRob2QobWV0aG9kKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyAvLyAsLi4uIGFyZ3VtZW50c1xuICAgICAgICB2YXIgbWl4aW5JbnN0YW5jZSA9IF9nZXRNaXhpbkluc3RhbmNlLmNhbGwodGhpcywgbWV0aG9kLm5hbWUpO1xuICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KG1peGluSW5zdGFuY2UsIGFyZ3VtZW50cyk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIHRoZSBpbnN0YW5jZSBvZiBtaXhpbiBzdWJjbGFzcy5cbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2hlbiBtZXRob2RzIGFyZSBleHBvc2VkIG9uIHRoZSBob3N0IGNsYXNzIHByb3RvdHlwZSAodXNpbmcgYWRkTWVodG9kcykgcmF0aGVyIHRoYW4gb24gaG9zdCBpbnN0YW5jZS5cbiAqIFN1YmNsYXNzZXMgc2hvdWxkIG5vdCB1c2UgdGhpcyBtZXRob2RzIC0gd2hlbmV2ZXIgc3ViY2xhc3MgbWV0aG9kIGlzIGV4cG9zZWQgb24gdGhlIHByb3RvdHlwZSBpdCB3aWxsIGJlIHdyYXBwZWQgdG8gc2V0IGNvcnJlY3QgY29udGV4dCBmb3IgdGhlIHN1YmNsYXNzIG1ldGhvZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBfZ2V0TWl4aW5JbnN0YW5jZShtZXRob2ROYW1lKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBNaXhpbikgcmV0dXJuIHRoaXM7XG4gICAgdmFyIGluc3RhbmNlS2V5cyA9IHRoaXMuY29uc3RydWN0b3JbY29uZmlnLm1peGluLmluc3RhbmNlUHJvcGVydGllc01hcF1cbiAgICByZXR1cm4gdGhpc1tpbnN0YW5jZUtleXNbbWV0aG9kTmFtZV1dO1xufVxuXG5cbi8qKlxuICogQWRkcyBtZXRob2RzIG9mIE1peGluIHN1YmNsYXNzIHRvIGhvc3QgY2xhc3MgcHJvdG90eXBlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRoaXMgTWl4aW4gc3ViY2xhc3MgKG5vdCBpbnN0YW5jZSlcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0Q2xhc3MgaG9zdCBvYmplY3QgY2xhc3M7IG11c3QgYmUgc3BlY2lmaWVkLlxuICogQHBhcmFtIHtTdHJpbmd9IGluc3RhbmNlS2V5IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0aGUgaG9zdCBjbGFzcyBpbnN0YW5jZSB3aWxsIHN0b3JlIG1peGluIGluc3RhbmNlIG9uXG4gKiBAcGFyYW0ge0hhc2hbU3RyaW5nXXxBcnJheVtTdHJpbmddfSBtaXhpbk1ldGhvZHMgbWFwIG9mIG5hbWVzIG9mIG1ldGhvZHMsIGtleSAtIGhvc3QgbWV0aG9kIG5hbWUsIHZhbHVlIC0gbWl4aW4gbWV0aG9kIG5hbWUuIENhbiBiZSBhcnJheS5cbiAqL1xuZnVuY3Rpb24gTWl4aW4kJHVzZVdpdGgoaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2RzKSB7XG4gICAgY2hlY2sobWl4aW5NZXRob2RzLCBNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihbU3RyaW5nXSwgTWF0Y2guT2JqZWN0SGFzaChTdHJpbmcpKSkpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkobWl4aW5NZXRob2RzKSlcbiAgICAgICAgbWl4aW5NZXRob2RzLmZvckVhY2goZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgTWl4aW5fYWRkTWV0aG9kLmNhbGwodGhpcywgaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWV0aG9kTmFtZSwgbWV0aG9kTmFtZSk7XG4gICAgICAgIH0sIHRoaXMpO1xuICAgIGVsc2VcbiAgICAgICAgXy5lYWNoS2V5KG1peGluTWV0aG9kcywgZnVuY3Rpb24obWl4aW5NZXRob2ROYW1lLCBob3N0TWV0aG9kTmFtZSkge1xuICAgICAgICAgICAgTWl4aW5fYWRkTWV0aG9kLmNhbGwodGhpcywgaG9zdENsYXNzLCBpbnN0YW5jZUtleSwgbWl4aW5NZXRob2ROYW1lLCBob3N0TWV0aG9kTmFtZSk7XG4gICAgICAgIH0sIHRoaXMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwiY2xhc3Nlc1wiPjwvYT5cbi8vIG1pbG8uY2xhc3Nlc1xuLy8gLS0tLS0tLS0tLS1cblxuLy8gVGhpcyBtb2R1bGUgY29udGFpbnMgZm91bmRhdGlvbiBjbGFzc2VzXG5cbnZhciBjbGFzc2VzID0ge1xuICAgIE1peGluOiByZXF1aXJlKCcuL2Fic3RyYWN0L21peGluJyksXG4gICAgTWVzc2FnZVNvdXJjZTogcmVxdWlyZSgnLi9tZXNzZW5nZXIvbV9zb3VyY2UnKSxcbiAgICBNZXNzZW5nZXJNZXNzYWdlU291cmNlOiByZXF1aXJlKCcuL21lc3Nlbmdlci9tc25ncl9zb3VyY2UnKSxcbiAgICBNZXNzZW5nZXJBUEk6IHJlcXVpcmUoJy4vbWVzc2VuZ2VyL21fYXBpJyksXG4gICAgTWVzc2VuZ2VyUmVnZXhwQVBJOiByZXF1aXJlKCcuL21lc3Nlbmdlci9tX2FwaV9yeCcpXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzZXM7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbmZpZztcblxuZnVuY3Rpb24gY29uZmlnKG9wdGlvbnMpIHtcbiAgICBfLmRlZXBFeHRlbmQoY29uZmlnLCBvcHRpb25zKTtcbn1cblxuY29uZmlnKHtcbiAgICBtaXhpbjoge1xuICAgICAgICBpbnN0YW5jZVByb3BlcnRpZXNNYXA6ICdfX19taXhpbl9pbnN0YW5jZXMnXG4gICAgfSxcbiAgICBjaGVjazogdHJ1ZSxcbiAgICBkZWJ1ZzogZmFsc2Vcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgTWl4aW4gPSByZXF1aXJlKCcuLi9hYnN0cmFjdC9taXhpbicpXG4gICAgLCBNZXNzYWdlU291cmNlID0gcmVxdWlyZSgnLi9tX3NvdXJjZScpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoO1xuXG5cbi8qKlxuICogYG1pbG8uTWVzc2VuZ2VyYFxuICogQSBnZW5lcmljIE1lc3NlbmdlciBjbGFzcyB0aGF0IGlzIHVzZWQgZm9yIGFsbCBraW5kcyBvZiBtZXNzYWdpbmcgaW4gbWlsby4gSXQgaXMgc3ViY2xhc3NlZCBmcm9tIFtNaXhpbl0oLi4vYWJzdHJhY3QvbWl4aW4uanMuaHRtbCkgYW5kIGl0IHByb3hpZXMgaXRzIG1ldGhvZHMgdG8gdGhlIGhvc3Qgb2JqZWN0IGZvciBjb252ZW5pZW5jZS5cbiAqIEFsbCBmYWNldHMgYW5kIGNvbXBvbmVudHMgaGF2ZSBtZXNzZW5nZXIgYXR0YWNoZWQgdG8gdGhlbS4gTWVzc2VuZ2VyIGNsYXNzIGludGVyb3BlcmF0ZXMgd2l0aCBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBjbGFzcyB0aGF0IGNvbm5lY3RzIHRoZSBtZXNzZW5nZXIgdG8gc29tZSBleHRlcm5hbCBzb3VyY2Ugb2YgbWVzc2FnZXMgKGUuZy4sIERPTSBldmVudHMpIGFuZCBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpIGNsYXNzIHRoYXQgYWxsb3dzIHRvIGRlZmluZSBoaWdoZXIgbGV2ZWwgbWVzc2FnZXMgdGhhbiBtZXNzYWdlcyB0aGF0IGV4aXN0IG9uIHRoZSBzb3VyY2UuXG4gKiBNZXNzZW5nZXIgY2xhc3MgaXMgdXNlZCBpbnRlcm5hbGx5IGluIG1pbG8gYW5kIGNhbiBiZSB1c2VkIHRvZ2V0aGVyIHdpdGggYW55IG9iamVjdHMvY2xhc3NlcyBpbiB0aGUgYXBwbGljYXRpb24uXG4gKiBtaWxvIGFsc28gZGVmaW5lcyBhIGdsb2JhbCBtZXNzZW5nZXIgW21pbG8ubWFpbF0oLi4vbWFpbC9pbmRleC5qcy5odG1sKSB0aGF0IGRpc3BhdGNoZXMgYGRvbXJlYWR5YCBldmVudCBhbmQgY2FuIGJlIHVzZWQgZm9yIGFueSBhcHBsaWNhdGlvbiB3aWRlIG1lc3NhZ2luZy5cbiAqIFRvIGluaXRpYWxpemUgeW91ciBhcHAgYWZ0ZXIgRE9NIGlzIHJlYWR5IHVzZTpcbiAqIGBgYFxuICogbWlsby5tYWlsLm9uKCdkb21yZWFkeScsIGZ1bmN0aW9uKCkge1xuICogICAgIC8vIGFwcGxpY2F0aW9uIHN0YXJ0c1xuICogfSk7XG4gKiBgYGBcbiAqIG9yIHRoZSBmb2xsb3dpbmcgc2hvcnRlciBmb3JtIG9mIHRoZSBzYW1lOlxuICogYGBgXG4gKiBtaWxvKGZ1bmN0aW9uKCkge1xuICogICAgIC8vIGFwcGxpY2F0aW9uIHN0YXJ0c1xuICogfSk7XG4gKiBgYGBcbiAqL1xudmFyIE1lc3NlbmdlciA9IF8uY3JlYXRlU3ViY2xhc3MoTWl4aW4sICdNZXNzZW5nZXInKTtcblxudmFyIG1lc3NhZ2VzU3BsaXRSZWdFeHAgPSBNZXNzZW5nZXIubWVzc2FnZXNTcGxpdFJlZ0V4cCA9IC9cXHMqKD86XFwsfFxccylcXHMqLztcblxuXG4vKipcbiAqICMjIyNNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtpbml0XSgjaW5pdClcbiAqIC0gW29uXSgjTWVzc2VuZ2VyJG9uKSAoYWxpYXMgLSBvbk1lc3NhZ2UsIGRlcHJlY2F0ZWQpXG4gKiAtIFtvZmZdKCNNZXNzZW5nZXIkb2ZmKSAoYWxpYXMgLSBvZmZNZXNzYWdlLCBkZXByZWNhdGVkKVxuICogLSBbb25NZXNzYWdlc10oI29uTWVzc2FnZXMpXG4gKiAtIFtvZmZNZXNzYWdlc10oI29mZk1lc3NhZ2VzKVxuICogLSBbb25jZV0oI29uY2UpXG4gKiAtIFtvbmNlU3luY10oI29uY2VTeW5jKVxuICogLSBbcG9zdE1lc3NhZ2VdKCNwb3N0TWVzc2FnZSlcbiAqIC0gW2dldFN1YnNjcmliZXJzXSgjZ2V0U3Vic2NyaWJlcnMpXG4gKlxuICogXCJQcml2YXRlXCIgbWV0aG9kc1xuICpcbiAqIC0gW19jaG9vc2VTdWJzY3JpYmVyc0hhc2hdKCNfY2hvb3NlU3Vic2NyaWJlcnNIYXNoKVxuICogLSBbX3JlZ2lzdGVyU3Vic2NyaWJlcl0oI19yZWdpc3RlclN1YnNjcmliZXIpXG4gKiAtIFtfcmVtb3ZlU3Vic2NyaWJlcl0oI19yZW1vdmVTdWJzY3JpYmVyKVxuICogLSBbX3JlbW92ZUFsbFN1YnNjcmliZXJzXSgjX3JlbW92ZUFsbFN1YnNjcmliZXJzKVxuICogLSBbX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnNdKCNfY2FsbFBhdHRlcm5TdWJzY3JpYmVycylcbiAqIC0gW19jYWxsU3Vic2NyaWJlcnNdKCNfY2FsbFN1YnNjcmliZXJzKVxuICogLSBbX3NldE1lc3NhZ2VTb3VyY2VdKCNfc2V0TWVzc2FnZVNvdXJjZSlcbiAqIC0gW2dldE1lc3NhZ2VTb3VyY2VdKCNnZXRNZXNzYWdlU291cmNlKVxuICovXG5fLmV4dGVuZFByb3RvKE1lc3Nlbmdlciwge1xuICAgIGluaXQ6IGluaXQsIC8vIGNhbGxlZCBieSBNaXhpbiAoc3VwZXJjbGFzcylcbiAgICBkZXN0cm95OiBNZXNzZW5nZXIkZGVzdHJveSxcbiAgICBvbjogTWVzc2VuZ2VyJG9uLFxuICAgIG9uY2U6IE1lc3NlbmdlciRvbmNlLFxuICAgIG9uY2VTeW5jOiBNZXNzZW5nZXIkb25jZVN5bmMsXG4gICAgb25TeW5jOiBNZXNzZW5nZXIkb25TeW5jLFxuICAgIG9uQXN5bmM6IE1lc3NlbmdlciRvbkFzeW5jLFxuICAgIG9uTWVzc2FnZTogTWVzc2VuZ2VyJG9uLCAvLyBkZXByZWNhdGVkXG4gICAgb2ZmOiBNZXNzZW5nZXIkb2ZmLFxuICAgIG9mZk1lc3NhZ2U6IE1lc3NlbmdlciRvZmYsIC8vIGRlcHJlY2F0ZWRcbiAgICBvbk1lc3NhZ2VzOiBvbk1lc3NhZ2VzLFxuICAgIG9mZk1lc3NhZ2VzOiBvZmZNZXNzYWdlcyxcbiAgICBvZmZBbGw6IE1lc3NlbmdlciRvZmZBbGwsXG4gICAgcG9zdE1lc3NhZ2U6IHBvc3RNZXNzYWdlLFxuICAgIHBvc3RNZXNzYWdlU3luYzogcG9zdE1lc3NhZ2VTeW5jLFxuICAgIGdldFN1YnNjcmliZXJzOiBnZXRTdWJzY3JpYmVycyxcbiAgICBnZXRNZXNzYWdlU291cmNlOiBnZXRNZXNzYWdlU291cmNlLFxuICAgIF9jaG9vc2VTdWJzY3JpYmVyc0hhc2g6IF9jaG9vc2VTdWJzY3JpYmVyc0hhc2gsXG4gICAgX3JlZ2lzdGVyU3Vic2NyaWJlcjogX3JlZ2lzdGVyU3Vic2NyaWJlcixcbiAgICBfcmVtb3ZlU3Vic2NyaWJlcjogX3JlbW92ZVN1YnNjcmliZXIsXG4gICAgX3JlbW92ZUFsbFN1YnNjcmliZXJzOiBfcmVtb3ZlQWxsU3Vic2NyaWJlcnMsXG4gICAgX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnM6IF9jYWxsUGF0dGVyblN1YnNjcmliZXJzLFxuICAgIF9jYWxsU3Vic2NyaWJlcnM6IF9jYWxsU3Vic2NyaWJlcnMsXG4gICAgX2NhbGxTdWJzY3JpYmVyOiBfY2FsbFN1YnNjcmliZXIsXG4gICAgX3NldE1lc3NhZ2VTb3VyY2U6IF9zZXRNZXNzYWdlU291cmNlXG59KTtcblxuXG4vKipcbiAqIEEgZGVmYXVsdCBtYXAgb2YgcHJveHkgbWV0aG9kcyB1c2VkIGJ5IENvbXBvbmVudEZhY2V0IGFuZCBDb21wb25lbnQgY2xhc3NlcyB0byBwYXNzIHRvIE1lc3NlbmdlciB3aGVuIGl0IGlzIGluc3RhbnRpYXRlZC5cbiAqIFRoaXMgbWFwIGlzIGZvciBjb252ZW5pZW5jZSBvbmx5LCBpdCBpcyBOT1QgdXNlZCBpbnRlcm5hbGx5IGJ5IE1lc3NlbmdlciwgYSBob3N0IGNsYXNzIHNob3VsZCBwYXNzIGl0IGZvciBtZXRob2RzIHRvIGJlIHByb3hpZWQgdGhpcyB3YXkuXG4gKi9cbk1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyA9IHtcbiAgICBvbjogJ29uJyxcbiAgICBvblN5bmM6ICdvblN5bmMnLFxuICAgIG9uY2U6ICdvbmNlJyxcbiAgICBvbmNlU3luYzogJ29uY2VTeW5jJyxcbiAgICBvZmY6ICdvZmYnLFxuICAgIG9uTWVzc2FnZXM6ICdvbk1lc3NhZ2VzJyxcbiAgICBvZmZNZXNzYWdlczogJ29mZk1lc3NhZ2VzJyxcbiAgICBwb3N0TWVzc2FnZTogJ3Bvc3RNZXNzYWdlJyxcbiAgICBwb3N0TWVzc2FnZVN5bmM6ICdwb3N0TWVzc2FnZVN5bmMnLFxuICAgIGdldFN1YnNjcmliZXJzOiAnZ2V0U3Vic2NyaWJlcnMnXG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTWVzc2VuZ2VyO1xuXG5cbk1lc3Nlbmdlci5zdWJzY3JpcHRpb25zID0gW107XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBJbml0aWFsaXplcyBNZXNzZW5nZXIuIE1ldGhvZCBpcyBjYWxsZWQgYnkgTWl4aW4gY2xhc3MgY29uc3RydWN0b3IuXG4gKiBTZWUgW29uXSgjTWVzc2VuZ2VyJG9uKSBtZXRob2QsIFtNZXNzZW5nZXJdKCNNZXNzZW5nZXIpIGNsYXNzIGFib3ZlIGFuZCBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBjbGFzcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gaG9zdE9iamVjdCBPcHRpb25hbCBvYmplY3QgdGhhdCBzdG9yZXMgdGhlIG1lc3NlbmdlciBvbiBvbmUgb2YgaXRzIHByb3BlcnRpZXMuIEl0IGlzIHVzZWQgdG8gcHJveHkgbWV0aG9kcyBvZiBtZXNzZW5nZXIgYW5kIGFsc28gYXMgYSBjb250ZXh0IGZvciBzdWJzY3JpYmVycyB3aGVuIHRoZXkgYXJlIGNhbGxlZCBieSB0aGUgTWVzc2VuZ2VyLiBTZWUgYG9uYCBtZXRob2QuXG4gKiBAcGFyYW0ge09iamVjdH0gcHJveHlNZXRob2RzIE9wdGlvbmFsIG1hcCBvZiBtZXRob2QgbmFtZXM7IGtleSAtIHByb3h5IG1ldGhvZCBuYW1lLCB2YWx1ZSAtIG1lc3NlbmdlcidzIG1ldGhvZCBuYW1lLlxuICogQHBhcmFtIHtNZXNzYWdlU291cmNlfSBtZXNzYWdlU291cmNlIE9wdGlvbmFsIG1lc3NhZ2VTb3VyY2UgbGlua2VkIHRvIHRoZSBtZXNzZW5nZXIuIElmIG1lc3NhZ2VTb3VyY2UgaXMgc3VwcGxpZWQsIHRoZSByZWZlcmVuY2UgdG8gdGhlIG1lc3NlbmdlciB3aWxsIHN0b3JlZCBvbiBpdHMgJ21lc3NlbmdlcicgcHJvcGVydHlcbiAqL1xuZnVuY3Rpb24gaW5pdChob3N0T2JqZWN0LCBwcm94eU1ldGhvZHMsIG1lc3NhZ2VTb3VyY2UpIHtcbiAgICAvLyBob3N0T2JqZWN0IGFuZCBwcm94eU1ldGhvZHMgYXJlIHVzZWQgaW4gTWl4aW4gYW5kIGNoZWNrZWQgdGhlcmVcbiAgICBpZiAobWVzc2FnZVNvdXJjZSlcbiAgICAgICAgdGhpcy5fc2V0TWVzc2FnZVNvdXJjZShtZXNzYWdlU291cmNlKTtcblxuICAgIF9pbml0aWFsaXplU3Vic2NyaWJlcnMuY2FsbCh0aGlzKTtcbn1cblxuXG5mdW5jdGlvbiBfaW5pdGlhbGl6ZVN1YnNjcmliZXJzKCkge1xuICAgIF8uZGVmaW5lUHJvcGVydGllcyh0aGlzLCB7XG4gICAgICAgIF9tZXNzYWdlU3Vic2NyaWJlcnM6IHt9LFxuICAgICAgICBfcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVyczoge30sXG4gICAgfSwgXy5DT05GKTtcbn1cblxuXG4vKipcbiAqIERlc3Ryb3lzIG1lc3Nlbmdlci4gTWF5YmUgbmVlZHMgdG8gdW5zdWJzY3JpYmUgYWxsIHN1YnNjcmliZXJzXG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRkZXN0cm95KCkge1xuICAgIHRoaXMub2ZmQWxsKCk7XG4gICAgdmFyIG1lc3NhZ2VTb3VyY2UgPSB0aGlzLmdldE1lc3NhZ2VTb3VyY2UoKTtcbiAgICBpZiAobWVzc2FnZVNvdXJjZSlcbiAgICAgICAgbWVzc2FnZVNvdXJjZS5kZXN0cm95KCk7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogUmVnaXN0ZXJzIGEgc3Vic2NyaWJlciBmdW5jdGlvbiBmb3IgYSBjZXJ0YWluIG1lc3NhZ2UocykuXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB0cnVlYCBpZiB0aGUgc3Vic2NyaXB0aW9uIHdhcyBzdWNjZXNzZnVsLiBJdCBjYW4gYmUgdW5zdWNjZXNzZnVsIGlmIHRoZSBwYXNzZWQgc3Vic2NyaWJlciBoYXMgYWxyZWFkeSBiZWVuIHN1YnNjcmliZWQgdG8gdGhpcyBtZXNzYWdlIHR5cGUgLSBkb3VibGUgc3Vic2NyaXB0aW9uIG5ldmVyIGhhcHBlbnMgYW5kIGl0IGlzIHNhZmUgdG8gc3Vic2NyaWJlIGFnYWluIC0gbm8gZXJyb3Igb3Igd2FybmluZyBpcyB0aHJvd24gb3IgbG9nZ2VkLlxuICogU3Vic2NyaWJlciBpcyBwYXNzZWQgdHdvIHBhcmFtZXRlcnM6IGBtZXNzYWdlYCAoc3RyaW5nKSBhbmQgYGRhdGFgIChvYmplY3QpLiBEYXRhIG9iamVjdCBpcyBzdXBwbGllZCB3aGVuIG1lc3NhZ2UgaXMgZGlzcGF0Y2hlZCwgTWVzc2VuZ2VyIGl0c2VsZiBhZGRzIG5vdGhpbmcgdG8gaXQuIEZvciBleGFtcGxlLCBbZXZlbnRzIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL0V2ZW50cy5qcy5odG1sKSBzZW5kcyBhY3R1YWwgRE9NIGV2ZW50IHdoZW4gaXQgcG9zdHMgbWVzc2FnZS5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiAvLyBzdWJzY3JpYmVzIG9uTW91c2VVcERvd24gdG8gdHdvIERPTSBldmVudHMgb24gY29tcG9uZW50IHZpYSBldmVudHMgZmFjZXQuXG4gKiBteUNvbXAuZXZlbnRzLm9uKCdtb3VzZWRvd24gbW91c2V1cCcsIG9uTW91c2VVcERvd24pO1xuICogZnVuY3Rpb24gb25Nb3VzZVVwRG93bihldmVudFR5cGUsIGV2ZW50KSB7XG4gKiAgICAgLy8gLi4uXG4gKiB9XG4gKlxuICogbXlDb21wLmRhdGEub24oLy4rLywgZnVuY3Rpb24obXNnLCBkYXRhKSB7XG4gKiAgICAgbG9nZ2VyLmRlYnVnKG1zZywgZGF0YSk7XG4gKiB9KTsgLy8gc3Vic2NyaWJlcyBhbm9ueW1vdXMgZnVuY3Rpb24gdG8gYWxsIG5vbi1lbXB0eSBtZXNzYWdlcyBvbiBkYXRhIGZhY2V0XG4gKiAvLyBpdCB3aWxsIG5vdCBiZSBwb3NzaWJsZSB0byB1bnN1YnNjcmliZSBhbm9ueW1vdXMgc3Vic2NyaWJlciBzZXBhcmF0ZWx5LFxuICogLy8gYnV0IG15Q29tcC5kYXRhLm9mZigvLisvKSB3aWxsIHVuc3Vic2NyaWJlIGl0XG4gKiBgYGBcbiAqIElmIG1lc3NlbmdlciBoYXMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgYXR0YWNoZWQgdG8gaXQsIE1lc3NhZ2VTb3VyY2Ugd2lsbCBiZSBub3RpZmllZCB3aGVuIHRoZSBmaXJzdCBzdWJzY3JpYmVyIGZvciBhIGdpdmVuIG1lc3NhZ2UgaXMgYWRkZWQsIHNvIGl0IGNhbiBzdWJzY3JpYmUgdG8gdGhlIHNvdXJjZS5cbiAqIFtDb21wb25lbnRzXSguLi9jb21wb25lbnRzL2NfY2xhc3MuanMuaHRtbCkgYW5kIFtmYWNldHNdKC4uL2NvbXBvbmVudHMvY19mYWNldC5qcy5odG1sKSBjaGFuZ2UgdGhpcyBtZXRob2QgbmFtZSB0byBgb25gIHdoZW4gdGhleSBwcm94eSBpdC5cbiAqIFNlZSBbcG9zdE1lc3NhZ2VdKCNwb3N0TWVzc2FnZSkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXlbU3RyaW5nXXxSZWdFeHB9IG1lc3NhZ2VzIE1lc3NhZ2UgdHlwZXMgdGhhdCBzaG91bGQgZW52b2tlIHRoZSBzdWJzY3JpYmVyLlxuICogIElmIHN0cmluZyBpcyBwYXNzZWQsIGl0IGNhbiBiZSBhIHNpZ2xlIG1lc3NhZ2Ugb3IgbXVsdGlwbGUgbWVzc2FnZSB0eXBlcyBzZXBhcmF0ZWQgYnkgd2hpdGVzcGFjZSB3aXRoIG9wdGlvbmFsIGNvbW1hcy5cbiAqICBJZiBhbiBhcnJheSBvZiBzdHJpbmdzIGlzIHBhc3NlZCwgZWFjaCBzdHJpbmcgaXMgYSBtZXNzYWdlIHR5cGUgdG8gc3Vic2NyaWJlIGZvci5cbiAqICBJZiBhIFJlZ0V4cCBpcyBwYXNzZWQsIHRoZSBzdWJzY3JpYmVyIHdpbGwgYmUgZW52b2tlZCB3aGVuIHRoZSBtZXNzYWdlIGRpc3BhdGNoZWQgb24gdGhlIG1lc3NlbmdlciBtYXRjaGVzIHRoZSBwYXR0ZXJuIChvciBJUyB0aGUgUmVnRXhwIHdpdGggaWRlbnRpY2FsIHBhdHRlcm4pLlxuICogIFBhdHRlcm4gc3Vic2NyaWJlciBkb2VzIE5PVCBjYXVzZSBhbnkgc3Vic2NyaXB0aW9uIHRvIE1lc3NhZ2VTb3VyY2UsIGl0IG9ubHkgY2FwdHVyZXMgbWVzc2FnZXMgdGhhdCBhcmUgYWxyZWFkeSBzdWJzY3JpYmVkIHRvIHdpdGggcHJlY2lzZSBtZXNzYWdlIHR5cGVzLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IHN1YnNjcmliZXIgTWVzc2FnZSBzdWJzY3JpYmVyIC0gYSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIG1lc3NhZ2UgaXMgZGlzcGF0Y2hlZCBvbiB0aGUgbWVzc2VuZ2VyICh1c3VhbGx5IHZpYSBwcm94aWVkIHBvc3RNZXNzYWdlIG1ldGhvZCBvZiBob3N0IG9iamVjdCkuXG4gKiAgSWYgaG9zdE9iamVjdCB3YXMgc3VwcGxpZWQgdG8gTWVzc2VuZ2VyIGNvbnN0cnVjdG9yLCBob3N0T2JqZWN0IHdpbGwgYmUgdGhlIGNvbnRleHQgKHRoZSB2YWx1ZSBvZiB0aGlzKSBmb3IgdGhlIHN1YnNjcmliZXIgZW52b2NhdGlvbi5cbiAqICBTdWJzY3JpYmVyIGNhbiBhbHNvIGJlIGFuIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgYHN1YnNjcmliZXJgIChmdW5jdGlvbikgYW5kIGBjb250ZXh0YCAoXCJ0aGlzXCIgdmFsdWUgd2hlbiBzdWJzY3JpYmVyIGlzIGNhbGxlZClcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRvbihtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMuY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG59XG5cblxuZnVuY3Rpb24gTWVzc2VuZ2VyJG9uY2UobWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICByZXR1cm4gX01lc3Nlbmdlcl9vbldpdGhPcHRpb25zLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIsIHsgZGlzcGF0Y2hUaW1lczogMSB9KTtcbn1cblxuZnVuY3Rpb24gTWVzc2VuZ2VyJG9uY2VTeW5jKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucy5jYWxsKHRoaXMsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyLCB7IGRpc3BhdGNoVGltZXM6IDEsIHN5bmM6IHRydWUgfSk7XG59XG5cblxuZnVuY3Rpb24gTWVzc2VuZ2VyJG9uU3luYyhtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIHJldHVybiBfTWVzc2VuZ2VyX29uV2l0aE9wdGlvbnMuY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlciwgeyBzeW5jOiB0cnVlIH0pO1xufVxuXG5cbmZ1bmN0aW9uIE1lc3NlbmdlciRvbkFzeW5jKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucy5jYWxsKHRoaXMsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyLCB7IHN5bmM6IGZhbHNlIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9NZXNzZW5nZXJfb25XaXRoT3B0aW9ucyhtZXNzYWdlcywgc3Vic2NyaWJlciwgb3B0aW9ucykge1xuICAgIGNoZWNrKG1lc3NhZ2VzLCBNYXRjaC5PbmVPZihTdHJpbmcsIFtTdHJpbmddLCBSZWdFeHApKTtcbiAgICBjaGVjayhzdWJzY3JpYmVyLCBNYXRjaC5PbmVPZihGdW5jdGlvbiwge1xuICAgICAgICBzdWJzY3JpYmVyOiBGdW5jdGlvbixcbiAgICAgICAgY29udGV4dDogTWF0Y2guQW55LFxuICAgICAgICBvcHRpb25zOiBNYXRjaC5PcHRpb25hbChPYmplY3QpLFxuICAgIH0pKTtcblxuICAgIGlmICh0eXBlb2Ygc3Vic2NyaWJlciA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHN1YnNjcmliZXIgPSB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyOiBzdWJzY3JpYmVyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5faG9zdE9iamVjdCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgICBzdWJzY3JpYmVyLm9wdGlvbnMgPSBzdWJzY3JpYmVyLm9wdGlvbnMgfHwge307XG4gICAgICAgIF8uZXh0ZW5kKHN1YnNjcmliZXIub3B0aW9ucywgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb24uY2FsbCh0aGlzLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG59XG5cblxuZnVuY3Rpb24gX01lc3Nlbmdlcl9vbihtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIF8uZGVmaW5lUHJvcGVydHkoc3Vic2NyaWJlciwgJ19fbWVzc2FnZXMnLCBtZXNzYWdlcyk7XG4gICAgcmV0dXJuIF9lYWNoTWVzc2FnZS5jYWxsKHRoaXMsICdfcmVnaXN0ZXJTdWJzY3JpYmVyJywgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xufVxuXG5cbmZ1bmN0aW9uIF9lYWNoTWVzc2FnZShtZXRob2ROYW1lLCBtZXNzYWdlcywgc3Vic2NyaWJlcikge1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZXMgPT0gJ3N0cmluZycpXG4gICAgICAgIG1lc3NhZ2VzID0gbWVzc2FnZXMuc3BsaXQobWVzc2FnZXNTcGxpdFJlZ0V4cCk7XG5cbiAgICB2YXIgc3Vic2NyaWJlcnNIYXNoID0gdGhpcy5fY2hvb3NlU3Vic2NyaWJlcnNIYXNoKG1lc3NhZ2VzKTtcblxuICAgIGlmIChtZXNzYWdlcyBpbnN0YW5jZW9mIFJlZ0V4cClcbiAgICAgICAgcmV0dXJuIHRoaXNbbWV0aG9kTmFtZV0oc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlcywgc3Vic2NyaWJlcik7XG5cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGNoYW5nZWQgPSBmYWxzZTtcblxuICAgICAgICBtZXNzYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIHZhciBzdWJzY3JpcHRpb25DaGFuZ2VkID0gdGhpc1ttZXRob2ROYW1lXShzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UsIHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgY2hhbmdlZCA9IGNoYW5nZWQgfHwgc3Vic2NyaXB0aW9uQ2hhbmdlZDtcbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIGNoYW5nZWQ7XG4gICAgfVxufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogSXQgaXMgY2FsbGVkIGJ5IFtvbl0oI01lc3NlbmdlciRvbikgdG8gcmVnaXN0ZXIgc3Vic2NyaWJlciBmb3Igb25lIG1lc3NhZ2UgdHlwZS5cbiAqIFJldHVybnMgYHRydWVgIGlmIHRoaXMgc3Vic2NyaWJlciBpcyBub3QgeWV0IHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHlwZSBvZiBtZXNzYWdlLlxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGZpcnN0IHN1YnNjcmliZXIgZm9yIGEgZ2l2ZW4gbWVzc2FnZSBpcyBhZGRlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN1YnNjcmliZXJzSGFzaCBUaGUgbWFwIG9mIHN1YnNjcmliZXJzIGRldGVybWluZWQgYnkgW29uXSgjTWVzc2VuZ2VyJG9uKSBiYXNlZCBvbiBNZXNzYWdlIHR5cGUsIGNhbiBiZSBgdGhpcy5fcGF0dGVybk1lc3NhZ2VTdWJzY3JpYmVyc2Agb3IgYHRoaXMuX21lc3NhZ2VTdWJzY3JpYmVyc2BcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIE1lc3NhZ2UgdHlwZVxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IHN1YnNjcmliZXIgU3Vic2NyaWJlciBmdW5jdGlvbiB0byBiZSBhZGRlZCBvciBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIGBzdWJzY3JpYmVyYCAoZnVuY3Rpb24pIGFuZCBgY29udGV4dGAgKHZhbHVlIG9mIFwidGhpc1wiIHdoZW4gc3Vic2NyaWJlciBpcyBjYWxsZWQpXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBfcmVnaXN0ZXJTdWJzY3JpYmVyKHN1YnNjcmliZXJzSGFzaCwgbWVzc2FnZSwgc3Vic2NyaWJlcikge1xuICAgIGlmICghIChzdWJzY3JpYmVyc0hhc2hbbWVzc2FnZV0gJiYgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdLmxlbmd0aCkpIHtcbiAgICAgICAgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdID0gW107XG4gICAgICAgIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgUmVnRXhwKVxuICAgICAgICAgICAgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdLnBhdHRlcm4gPSBtZXNzYWdlO1xuICAgICAgICBpZiAodGhpcy5fbWVzc2FnZVNvdXJjZSlcbiAgICAgICAgICAgIHRoaXMuX21lc3NhZ2VTb3VyY2Uub25TdWJzY3JpYmVyQWRkZWQobWVzc2FnZSk7XG4gICAgICAgIHZhciBub1N1YnNjcmliZXJzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgbXNnU3Vic2NyaWJlcnMgPSBzdWJzY3JpYmVyc0hhc2hbbWVzc2FnZV07XG4gICAgdmFyIG5vdFlldFJlZ2lzdGVyZWQgPSBub1N1YnNjcmliZXJzIHx8IF9pbmRleE9mU3Vic2NyaWJlci5jYWxsKHRoaXMsIG1zZ1N1YnNjcmliZXJzLCBzdWJzY3JpYmVyKSA9PSAtMTtcblxuICAgIGlmIChub3RZZXRSZWdpc3RlcmVkKVxuICAgICAgICBtc2dTdWJzY3JpYmVycy5wdXNoKHN1YnNjcmliZXIpO1xuXG4gICAgcmV0dXJuIG5vdFlldFJlZ2lzdGVyZWQ7XG59XG5cblxuLyoqXG4gKiBGaW5kcyBzdWJzY3JpYmVyIGluZGV4IGluIHRoZSBsaXN0XG4gKlxuICogQHBhcmFtIHtBcnJheVtGdW5jdGlvbnxPYmplY3RdfSBsaXN0IGxpc3Qgb2Ygc3Vic2NyaWJlcnNcbiAqIEBwYXJhbSB7RnVuY3Rpb258T2JqZWN0fSBzdWJzY3JpYmVyIHN1YnNjcmliZXIgZnVuY3Rpb24gb3Igb2JqZWN0IHdpdGggcHJvcGVydGllcyBgc3Vic2NyaWJlcmAgKGZ1bmN0aW9uKSBhbmQgYGNvbnRleHRgIChcInRoaXNcIiBvYmplY3QpXG4gKi9cbmZ1bmN0aW9uIF9pbmRleE9mU3Vic2NyaWJlcihsaXN0LCBzdWJzY3JpYmVyKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBfLmZpbmRJbmRleChsaXN0LCBmdW5jdGlvbihzdWJzY3Ipe1xuICAgICAgICByZXR1cm4gc3Vic2NyaWJlci5zdWJzY3JpYmVyID09IHN1YnNjci5zdWJzY3JpYmVyXG4gICAgICAgICAgICAgICAgJiYgc3Vic2NyaWJlci5jb250ZXh0ID09IHN1YnNjci5jb250ZXh0XG4gICAgfSk7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogU3Vic2NyaWJlcyB0byBtdWx0aXBsZSBtZXNzYWdlcyBwYXNzZWQgYXMgbWFwIHRvZ2V0aGVyIHdpdGggc3Vic2NyaWJlcnMuXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogbXlDb21wLmV2ZW50cy5vbk1lc3NhZ2VzKHtcbiAqICAgICAnbW91c2Vkb3duJzogb25Nb3VzZURvd24sXG4gKiAgICAgJ21vdXNldXAnOiBvbk1vdXNlVXBcbiAqIH0pO1xuICogZnVuY3Rpb24gb25Nb3VzZURvd24oZXZlbnRUeXBlLCBldmVudCkge31cbiAqIGZ1bmN0aW9uIG9uTW91c2VVcChldmVudFR5cGUsIGV2ZW50KSB7fVxuICogYGBgXG4gKiBSZXR1cm5zIG1hcCB3aXRoIHRoZSBzYW1lIGtleXMgKG1lc3NhZ2UgdHlwZXMpIGFuZCBib29sZWFuIHZhbHVlcyBpbmRpY2F0aW5nIHdoZXRoZXIgcGFydGljdWxhciBzdWJzY3JpYmVyIHdhcyBhZGRlZC5cbiAqIEl0IGlzIE5PVCBwb3NzaWJsZSB0byBhZGQgcGF0dGVybiBzdWJzY3JpYmVyIHVzaW5nIHRoaXMgbWV0aG9kLCBhcyBhbHRob3VnaCB5b3UgY2FuIHVzZSBSZWdFeHAgYXMgdGhlIGtleSwgSmF2YVNjcmlwdCB3aWxsIGF1dG9tYXRpY2FsbHkgY29udmVydCBpdCB0byBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtPYmplY3RbRnVuY3Rpb25dfSBtZXNzYWdlU3Vic2NyaWJlcnMgTWFwIG9mIG1lc3NhZ2Ugc3Vic2NyaWJlcnMgdG8gYmUgYWRkZWRcbiAqIEByZXR1cm4ge09iamVjdFtCb29sZWFuXX1cbiAqL1xuZnVuY3Rpb24gb25NZXNzYWdlcyhtZXNzYWdlU3Vic2NyaWJlcnMpIHtcbiAgICBjaGVjayhtZXNzYWdlU3Vic2NyaWJlcnMsIE1hdGNoLk9iamVjdEhhc2goTWF0Y2guT25lT2YoRnVuY3Rpb24sIHsgc3Vic2NyaWJlcjogRnVuY3Rpb24sIGNvbnRleHQ6IE1hdGNoLkFueSB9KSkpO1xuXG4gICAgdmFyIG5vdFlldFJlZ2lzdGVyZWRNYXAgPSBfLm1hcEtleXMobWVzc2FnZVN1YnNjcmliZXJzLCBmdW5jdGlvbihzdWJzY3JpYmVyLCBtZXNzYWdlcykge1xuICAgICAgICByZXR1cm4gdGhpcy5vbihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gbm90WWV0UmVnaXN0ZXJlZE1hcDtcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2QuXG4gKiBSZW1vdmVzIGEgc3Vic2NyaWJlciBmb3IgbWVzc2FnZShzKS4gUmVtb3ZlcyBhbGwgc3Vic2NyaWJlcnMgZm9yIHRoZSBtZXNzYWdlIGlmIHN1YnNjcmliZXIgaXNuJ3QgcGFzc2VkLlxuICogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHN1YnNjcmliZXIgd2FzIHJlZ2lzdGVyZWQuIE5vIGVycm9yIG9yIHdhcm5pbmcgaXMgdGhyb3duIG9yIGxvZ2dlZCBpZiB5b3UgcmVtb3ZlIHN1YnNjcmliZXIgdGhhdCB3YXMgbm90IHJlZ2lzdGVyZWQuXG4gKiBbQ29tcG9uZW50c10oLi4vY29tcG9uZW50cy9jX2NsYXNzLmpzLmh0bWwpIGFuZCBbZmFjZXRzXSguLi9jb21wb25lbnRzL2NfZmFjZXQuanMuaHRtbCkgY2hhbmdlIHRoaXMgbWV0aG9kIG5hbWUgdG8gYG9mZmAgd2hlbiB0aGV5IHByb3h5IGl0LlxuICogVXNhZ2U6XG4gKiBgYGBcbiAqIC8vIHVuc3Vic2NyaWJlcyBvbk1vdXNlVXBEb3duIGZyb20gdHdvIERPTSBldmVudHMuXG4gKiBteUNvbXAuZXZlbnRzLm9mZignbW91c2Vkb3duIG1vdXNldXAnLCBvbk1vdXNlVXBEb3duKTtcbiAqIGBgYFxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciBmb3IgYSBnaXZlbiBtZXNzYWdlIGlzIHJlbW92ZWQgYW5kIHRoZXJlIGlzIG5vIG1vcmUgc3Vic2NyaWJlcnMgZm9yIHRoaXMgbWVzc2FnZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xBcnJheVtTdHJpbmddfFJlZ0V4cH0gbWVzc2FnZXMgTWVzc2FnZSB0eXBlcyB0aGF0IGEgc3Vic2NyaWJlciBzaG91bGQgYmUgcmVtb3ZlZCBmb3IuXG4gKiAgSWYgc3RyaW5nIGlzIHBhc3NlZCwgaXQgY2FuIGJlIGEgc2lnbGUgbWVzc2FnZSBvciBtdWx0aXBsZSBtZXNzYWdlIHR5cGVzIHNlcGFyYXRlZCBieSB3aGl0ZXNwYWNlIHdpdGggb3B0aW9uYWwgY29tbWFzLlxuICogIElmIGFuIGFycmF5IG9mIHN0cmluZ3MgaXMgcGFzc2VkLCBlYWNoIHN0cmluZyBpcyBhIG1lc3NhZ2UgdHlwZSB0byByZW1vdmUgYSBzdWJzY3JpYmVyIGZvci5cbiAqICBJZiBhIFJlZ0V4cCBpcyBwYXNzZWQsIHRoZSBwYXR0ZXJuIHN1YnNjcmliZXIgd2lsbCBiZSByZW1vdmVkLlxuICogIFJlZ0V4cCBzdWJzY3JpYmVyIGRvZXMgTk9UIGNhdXNlIGFueSBzdWJzY3JpcHRpb24gdG8gTWVzc2FnZVNvdXJjZSwgaXQgb25seSBjYXB0dXJlcyBtZXNzYWdlcyB0aGF0IGFyZSBhbHJlYWR5IHN1YnNjcmliZWQgdG8gd2l0aCBwcmVjaXNlIG1lc3NhZ2UgdHlwZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdWJzY3JpYmVyIE1lc3NhZ2Ugc3Vic2NyaWJlciAtIE9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIGxpc3Qgb2Ygc3Vic2NyaWJlcnMgZm9yIHRoZSBtZXNzYWdlKHMpLiBJZiBzdWJzY3JpYmVyIGlzIG5vdCBzdXBwbGllZCwgYWxsIHN1YnNjcmliZXJzIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoaXMgbWVzc2FnZShzKS5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIE1lc3NlbmdlciRvZmYobWVzc2FnZXMsIHN1YnNjcmliZXIpIHtcbiAgICBjaGVjayhtZXNzYWdlcywgTWF0Y2guT25lT2YoU3RyaW5nLCBbU3RyaW5nXSwgUmVnRXhwKSk7XG4gICAgY2hlY2soc3Vic2NyaWJlciwgTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoRnVuY3Rpb24sIHtcbiAgICAgICAgc3Vic2NyaWJlcjogRnVuY3Rpb24sXG4gICAgICAgIGNvbnRleHQ6IE1hdGNoLkFueSxcbiAgICAgICAgb3B0aW9uczogTWF0Y2guT3B0aW9uYWwoT2JqZWN0KSxcbiAgICAgICAgLy8gX19tZXNzYWdlczogTWF0Y2guT3B0aW9uYWwoTWF0Y2guT25lT2YoU3RyaW5nLCBbU3RyaW5nXSwgUmVnRXhwKSlcbiAgICB9KSkpO1xuXG4gICAgcmV0dXJuIF9NZXNzZW5nZXJfb2ZmLmNhbGwodGhpcywgbWVzc2FnZXMsIHN1YnNjcmliZXIpO1xufVxuXG5cbmZ1bmN0aW9uIF9NZXNzZW5nZXJfb2ZmKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKSB7XG4gICAgcmV0dXJuIF9lYWNoTWVzc2FnZS5jYWxsKHRoaXMsICdfcmVtb3ZlU3Vic2NyaWJlcicsIG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIEl0IGlzIGNhbGxlZCBieSBbb2ZmXSgjTWVzc2VuZ2VyJG9mZikgdG8gcmVtb3ZlIHN1YnNjcmliZXIgZm9yIG9uZSBtZXNzYWdlIHR5cGUuXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGlzIHN1YnNjcmliZXIgd2FzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHlwZSBvZiBtZXNzYWdlLlxuICogSWYgbWVzc2VuZ2VyIGhhcyBbTWVzc2FnZVNvdXJjZV0oLi9tX3NvdXJjZS5qcy5odG1sKSBhdHRhY2hlZCB0byBpdCwgTWVzc2FnZVNvdXJjZSB3aWxsIGJlIG5vdGlmaWVkIHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciBmb3IgYSBnaXZlbiBtZXNzYWdlIGlzIHJlbW92ZWQgYW5kIHRoZXJlIGlzIG5vIG1vcmUgc3Vic2NyaWJlcnMgZm9yIHRoaXMgbWVzc2FnZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN1YnNjcmliZXJzSGFzaCBUaGUgbWFwIG9mIHN1YnNjcmliZXJzIGRldGVybWluZWQgYnkgW29mZl0oI01lc3NlbmdlciRvZmYpIGJhc2VkIG9uIG1lc3NhZ2UgdHlwZSwgY2FuIGJlIGB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzYCBvciBgdGhpcy5fbWVzc2FnZVN1YnNjcmliZXJzYFxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgTWVzc2FnZSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdWJzY3JpYmVyIFN1YnNjcmliZXIgZnVuY3Rpb24gdG8gYmUgcmVtb3ZlZFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gX3JlbW92ZVN1YnNjcmliZXIoc3Vic2NyaWJlcnNIYXNoLCBtZXNzYWdlLCBzdWJzY3JpYmVyKSB7XG4gICAgdmFyIG1zZ1N1YnNjcmliZXJzID0gc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdO1xuICAgIGlmICghIG1zZ1N1YnNjcmliZXJzIHx8ICEgbXNnU3Vic2NyaWJlcnMubGVuZ3RoKVxuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdGhpbmcgcmVtb3ZlZFxuXG4gICAgaWYgKHN1YnNjcmliZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzdWJzY3JpYmVyID09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICBzdWJzY3JpYmVyID0geyBzdWJzY3JpYmVyOiBzdWJzY3JpYmVyLCBjb250ZXh0OiB0aGlzLl9ob3N0T2JqZWN0IH07XG5cbiAgICAgICAgdmFyIHN1YnNjcmliZXJJbmRleCA9IF9pbmRleE9mU3Vic2NyaWJlci5jYWxsKHRoaXMsIG1zZ1N1YnNjcmliZXJzLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgaWYgKHN1YnNjcmliZXJJbmRleCA9PSAtMSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gbm90aGluZyByZW1vdmVkXG4gICAgICAgIG1zZ1N1YnNjcmliZXJzLnNwbGljZShzdWJzY3JpYmVySW5kZXgsIDEpO1xuICAgICAgICBpZiAoISBtc2dTdWJzY3JpYmVycy5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpO1xuXG4gICAgfSBlbHNlXG4gICAgICAgIHRoaXMuX3JlbW92ZUFsbFN1YnNjcmliZXJzKHN1YnNjcmliZXJzSGFzaCwgbWVzc2FnZSk7XG5cbiAgICByZXR1cm4gdHJ1ZTsgLy8gc3Vic2NyaWJlcihzKSByZW1vdmVkXG59XG5cblxuLyoqXG4gKiBcIlByaXZhdGVcIiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kXG4gKiBJdCBpcyBjYWxsZWQgYnkgW19yZW1vdmVTdWJzY3JpYmVyXSgjX3JlbW92ZVN1YnNjcmliZXIpIHRvIHJlbW92ZSBhbGwgc3Vic2NyaWJlcnMgZm9yIG9uZSBtZXNzYWdlIHR5cGUuXG4gKiBJZiBtZXNzZW5nZXIgaGFzIFtNZXNzYWdlU291cmNlXSguL21fc291cmNlLmpzLmh0bWwpIGF0dGFjaGVkIHRvIGl0LCBNZXNzYWdlU291cmNlIHdpbGwgYmUgbm90aWZpZWQgdGhhdCBhbGwgbWVzc2FnZSBzdWJzY3JpYmVycyB3ZXJlIHJlbW92ZWQgc28gaXQgY2FuIHVuc3Vic2NyaWJlIGZyb20gdGhlIHNvdXJjZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN1YnNjcmliZXJzSGFzaCBUaGUgbWFwIG9mIHN1YnNjcmliZXJzIGRldGVybWluZWQgYnkgW29mZl0oI01lc3NlbmdlciRvZmYpIGJhc2VkIG9uIG1lc3NhZ2UgdHlwZSwgY2FuIGJlIGB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzYCBvciBgdGhpcy5fbWVzc2FnZVN1YnNjcmliZXJzYFxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgTWVzc2FnZSB0eXBlXG4gKi9cbmZ1bmN0aW9uIF9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpIHtcbiAgICBkZWxldGUgc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdO1xuICAgIGlmICh0aGlzLl9tZXNzYWdlU291cmNlICYmIHR5cGVvZiBtZXNzYWdlID09ICdzdHJpbmcnKVxuICAgICAgICB0aGlzLl9tZXNzYWdlU291cmNlLm9uU3Vic2NyaWJlclJlbW92ZWQobWVzc2FnZSk7XG59XG5cblxuLyoqXG4gKiBNZXNzZW5nZXIgaW5zdGFuY2UgbWV0aG9kLlxuICogVW5zdWJzY3JpYmVzIGZyb20gbXVsdGlwbGUgbWVzc2FnZXMgcGFzc2VkIGFzIG1hcCB0b2dldGhlciB3aXRoIHN1YnNjcmliZXJzLlxuICogUmV0dXJucyBtYXAgd2l0aCB0aGUgc2FtZSBrZXlzIChtZXNzYWdlIHR5cGVzKSBhbmQgYm9vbGVhbiB2YWx1ZXMgaW5kaWNhdGluZyB3aGV0aGVyIHBhcnRpY3VsYXIgc3Vic2NyaWJlciB3YXMgcmVtb3ZlZC5cbiAqIElmIGEgc3Vic2NyaWJlciBmb3Igb25lIG9mIHRoZSBtZXNzYWdlcyBpcyBub3Qgc3VwcGxpZWQsIGFsbCBzdWJzY3JpYmVycyBmb3IgdGhpcyBtZXNzYWdlIHdpbGwgYmUgcmVtb3ZlZC5cbiAqIFVzYWdlOlxuICogYGBgXG4gKiBteUNvbXAuZXZlbnRzLm9mZk1lc3NhZ2VzKHtcbiAqICAgICAnbW91c2Vkb3duJzogb25Nb3VzZURvd24sXG4gKiAgICAgJ21vdXNldXAnOiBvbk1vdXNlVXAsXG4gKiAgICAgJ2NsaWNrJzogdW5kZWZpbmVkIC8vIGFsbCBzdWJzY3JpYmVycyB0byB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSByZW1vdmVkXG4gKiB9KTtcbiAqIGBgYFxuICogSXQgaXMgTk9UIHBvc3NpYmxlIHRvIHJlbW92ZSBwYXR0ZXJuIHN1YnNjcmliZXIocykgdXNpbmcgdGhpcyBtZXRob2QsIGFzIGFsdGhvdWdoIHlvdSBjYW4gdXNlIFJlZ0V4cCBhcyB0aGUga2V5LCBKYXZhU2NyaXB0IHdpbGwgYXV0b21hdGljYWxseSBjb252ZXJ0IGl0IHRvIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdFtGdW5jdGlvbl19IG1lc3NhZ2VTdWJzY3JpYmVycyBNYXAgb2YgbWVzc2FnZSBzdWJzY3JpYmVycyB0byBiZSByZW1vdmVkXG4gKiBAcmV0dXJuIHtPYmplY3RbQm9vbGVhbl19XG4gKi9cbmZ1bmN0aW9uIG9mZk1lc3NhZ2VzKG1lc3NhZ2VTdWJzY3JpYmVycykge1xuICAgIGNoZWNrKG1lc3NhZ2VTdWJzY3JpYmVycywgTWF0Y2guT2JqZWN0SGFzaChNYXRjaC5PcHRpb25hbChNYXRjaC5PbmVPZihGdW5jdGlvbiwgeyBzdWJzY3JpYmVyOiBGdW5jdGlvbiwgY29udGV4dDogTWF0Y2guQW55IH0pKSkpO1xuXG4gICAgdmFyIHN1YnNjcmliZXJSZW1vdmVkTWFwID0gXy5tYXBLZXlzKG1lc3NhZ2VTdWJzY3JpYmVycywgZnVuY3Rpb24oc3Vic2NyaWJlciwgbWVzc2FnZXMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub2ZmKG1lc3NhZ2VzLCBzdWJzY3JpYmVyKTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiBzdWJzY3JpYmVyUmVtb3ZlZE1hcDtcbn1cblxuXG4vKipcbiAqIFVuc3Vic2NyaWJlcyBhbGwgc3Vic2NyaWJlcnNcbiAqL1xuZnVuY3Rpb24gTWVzc2VuZ2VyJG9mZkFsbCgpIHtcbiAgICBfb2ZmQWxsU3Vic2NyaWJlcnMuY2FsbCh0aGlzLCB0aGlzLl9wYXR0ZXJuTWVzc2FnZVN1YnNjcmliZXJzKTtcbiAgICBfb2ZmQWxsU3Vic2NyaWJlcnMuY2FsbCh0aGlzLCB0aGlzLl9tZXNzYWdlU3Vic2NyaWJlcnMpO1xufVxuXG5cbmZ1bmN0aW9uIF9vZmZBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gpIHtcbiAgICBfLmVhY2hLZXkoc3Vic2NyaWJlcnNIYXNoLCBmdW5jdGlvbihzdWJzY3JpYmVycywgbWVzc2FnZSkge1xuICAgICAgICB0aGlzLl9yZW1vdmVBbGxTdWJzY3JpYmVycyhzdWJzY3JpYmVyc0hhc2gsIG1lc3NhZ2UpO1xuICAgIH0sIHRoaXMpO1xufVxuXG5cbi8vIFRPRE8gLSBzZW5kIGV2ZW50IHRvIG1lc3NhZ2VTb3VyY2VcblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2QuXG4gKiBEaXNwYXRjaGVzIHRoZSBtZXNzYWdlIGNhbGxpbmcgYWxsIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgbWVzc2FnZSBhbmQsIGlmIHRoZSBtZXNzYWdlIGlzIGEgc3RyaW5nLCBjYWxsaW5nIGFsbCBwYXR0ZXJuIHN1YnNjcmliZXJzIHdoZW4gbWVzc2FnZSBtYXRjaGVzIHRoZSBwYXR0ZXJuLlxuICogRWFjaCBzdWJzY3JpYmVyIGlzIHBhc3NlZCB0aGUgc2FtZSBwYXJhbWV0ZXJzIHRoYXQgYXJlIHBhc3NlZCB0byB0aGVpcyBtZXRob2QuXG4gKiBUaGUgY29udGV4dCBvZiB0aGUgc3Vic2NyaWJlciBlbnZvY2F0aW9uIGlzIHNldCB0byB0aGUgaG9zdCBvYmplY3QgKGB0aGlzLl9ob3N0T2JqZWN0YCkgdGhhdCB3YXMgcGFzc2VkIHRvIHRoZSBtZXNzZW5nZXIgY29uc3RydWN0b3IuXG4gKiBTdWJzY3JpYmVycyBhcmUgY2FsbGVkIGluIHRoZSBuZXh0IHRpY2sgKFwiYXN5bmNocm9ub3VzbHlcIikgYXBhcnQgZnJvbSB0aG9zZSB0aGF0IHdlcmUgc3Vic2NyaWJlZCB3aXRoIGBvblN5bmNgIChvciB0aGF0IGhhdmUgYG9wdGlvbnMuc3luYyA9PSB0cnVlYCkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgZGlzcGF0Y2hlZFxuICogIElmIHRoZSBtZXNzYWdlIGlzIGEgc3RyaW5nLCB0aGUgc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIGV4YWN0bHkgdGhpcyBtZXNzYWdlIHdpbGwgYmUgY2FsbGVkIGFuZCBhbHNvIHBhdHRlcm4gc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIHRoZSBwYXR0ZXJuIHRoYXQgbWF0Y2hlcyB0aGUgZGlzcGF0Y2hlZCBtZXNzYWdlLlxuICogIElmIHRoZSBtZXNzYWdlIGlzIFJlZ0V4cCwgb25seSB0aGUgc3Vic2NyaWJlcnMgcmVnaXN0ZXJlZCB3aXRoIGV4YWN0bHkgdGhpcyBwYXR0ZXJuIHdpbGwgYmUgY2FsbGVkLlxuICogQHBhcmFtIHtBbnl9IGRhdGEgZGF0YSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBzdWJzY3JpYmVyIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBNZXNzZW5nZXIgZG9lcyBub3QgbW9kaWZ5IHRoaXMgZGF0YSBpbiBhbnkgd2F5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdG8gcGFzcyB0byBzdWJzY3JpYmVyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IF9zeW5jaHJvbm91cyBpZiB0cnVlIHBhc3NlZCwgc3Vic2NyaWJlcnMgd2lsbCBiZSBlbnZva2VkIHN5bmNocm9ub3VzbHkgYXBhcnQgZnJvbSB0aG9zZSB0aGF0IGhhdmUgYG9wdGlvbnMuc3luYyA9PSBmYWxzZWAuIFRoaXMgcGFyYW1ldGVyIHNob3VsZCBub3QgYmUgdXNlZCwgaW5zdGVhZCBwb3N0TWVzc2FnZVN5bmMgc2hvdWxkIGJlIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBfc3luY2hyb25vdXMpIHtcbiAgICBjaGVjayhtZXNzYWdlLCBNYXRjaC5PbmVPZihTdHJpbmcsIFJlZ0V4cCkpO1xuICAgIGNoZWNrKGNhbGxiYWNrLCBNYXRjaC5PcHRpb25hbChGdW5jdGlvbikpO1xuXG4gICAgdmFyIHN1YnNjcmliZXJzSGFzaCA9IHRoaXMuX2Nob29zZVN1YnNjcmliZXJzSGFzaChtZXNzYWdlKTtcbiAgICB2YXIgbXNnU3Vic2NyaWJlcnMgPSBzdWJzY3JpYmVyc0hhc2hbbWVzc2FnZV07XG5cbiAgICB0aGlzLl9jYWxsU3Vic2NyaWJlcnMobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIG1zZ1N1YnNjcmliZXJzLCBfc3luY2hyb25vdXMpO1xuXG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09ICdzdHJpbmcnKVxuICAgICAgICB0aGlzLl9jYWxsUGF0dGVyblN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBtc2dTdWJzY3JpYmVycywgX3N5bmNocm9ub3VzKTtcbn1cblxuXG4vKipcbiAqIFNhbWUgYXMgcG9zdE1lc3NhZ2UgYXBhcnQgZnJvbSBlbnZva2luZyBzdWJzY3JpYmVycyBzeW5jaHJvbm91c2x5LCBhcGFydCBmcm9tIHRob3NlIHN1YnNjcmliZWQgd2l0aCBgb25Bc3luY2AgKG9yIHdpdGggYG9wdGlvbnMuc3luYyA9PSBmYWxzZWApLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbWVzc2FnZVxuICogQHBhcmFtIHtBbnl9IGRhdGFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKi9cbmZ1bmN0aW9uIHBvc3RNZXNzYWdlU3luYyhtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaykge1xuICAgIHRoaXMucG9zdE1lc3NhZ2UobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIHRydWUpO1xufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogRW52b2tlcyBwYXR0ZXJuIHN1YnNjcmliZXJzIHdpdGggdGhlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIHRoZSBtZXNzYWdlLlxuICogVGhlIG1ldGhvZCBpcyBjYWxsZWQgYnkgW3Bvc3RNZXNzYWdlXSgjcG9zdE1lc3NhZ2UpIC0gc2VlIG1vcmUgaW5mb3JtYXRpb24gdGhlcmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgZGlzcGF0Y2hlZC4gUGF0dGVybiBzdWJzY3JpYmVycyByZWdpc3RlcmVkIHdpdGggdGhlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIHRoZSBkaXNwYXRjaGVkIG1lc3NhZ2Ugd2lsbCBiZSBjYWxsZWQuXG4gKiBAcGFyYW0ge0FueX0gZGF0YSBkYXRhIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHN1YnNjcmliZXIgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIuIE1lc3NlbmdlciBkb2VzIG5vdCBtb2RpZnkgdGhpcyBkYXRhIGluIGFueSB3YXkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBvcHRpb25hbCBjYWxsYmFjayB0byBwYXNzIHRvIHN1YnNjcmliZXJcbiAqIEBwYXJhbSB7QXJyYXlbRnVuY3Rpb258T2JqZWN0XX0gY2FsbGVkTXNnU3Vic2NyaWJlcnMgYXJyYXkgb2Ygc3Vic2NyaWJlcnMgYWxyZWFkeSBjYWxsZWQsIHRoZXkgd29uJ3QgYmUgY2FsbGVkIGFnYWluIGlmIHRoZXkgYXJlIGFtb25nIHBhdHRlcm4gc3Vic2NyaWJlcnMuXG4gKi9cbmZ1bmN0aW9uIF9jYWxsUGF0dGVyblN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBjYWxsZWRNc2dTdWJzY3JpYmVycywgX3N5bmNocm9ub3VzKSB7XG4gICAgXy5lYWNoS2V5KHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnMsXG4gICAgICAgIGZ1bmN0aW9uKHBhdHRlcm5TdWJzY3JpYmVycykge1xuICAgICAgICAgICAgdmFyIHBhdHRlcm4gPSBwYXR0ZXJuU3Vic2NyaWJlcnMucGF0dGVybjtcbiAgICAgICAgICAgIGlmIChwYXR0ZXJuLnRlc3QobWVzc2FnZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2FsbGVkTXNnU3Vic2NyaWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhdHRlcm5TdWJzY3JpYmVycyA9IHBhdHRlcm5TdWJzY3JpYmVycy5maWx0ZXIoZnVuY3Rpb24oc3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gX2luZGV4T2ZTdWJzY3JpYmVyLmNhbGwodGhpcywgY2FsbGVkTXNnU3Vic2NyaWJlcnMsIHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4ID09IC0xO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fY2FsbFN1YnNjcmliZXJzKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrLCBwYXR0ZXJuU3Vic2NyaWJlcnMsIF9zeW5jaHJvbm91cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAsIHRoaXMpO1xufVxuXG5cbi8qKlxuICogXCJQcml2YXRlXCIgTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogRW52b2tlcyBzdWJzY3JpYmVycyBmcm9tIHRoZSBwYXNzZWQgbGlzdC5cbiAqIFRoZSBtZXRob2QgaXMgY2FsbGVkIGJ5IFtwb3N0TWVzc2FnZV0oI3Bvc3RNZXNzYWdlKSBhbmQgW19jYWxsUGF0dGVyblN1YnNjcmliZXJzXSgjX2NhbGxQYXR0ZXJuU3Vic2NyaWJlcnMpLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBtZXNzYWdlIHRvIGJlIGRpc3BhdGNoZWQsIHBhc3NlZCB0byBzdWJzY3JpYmVycyBhcyB0aGUgZmlyc3QgcGFyYW1ldGVyLlxuICogQHBhcmFtIHtBbnl9IGRhdGEgZGF0YSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBzdWJzY3JpYmVyIGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBNZXNzZW5nZXIgZG9lcyBub3QgbW9kaWZ5IHRoaXMgZGF0YSBpbiBhbnkgd2F5LlxuICogQHBhcmFtIHtBcnJheVtGdW5jdGlvbnxPYmplY3RdfSBtc2dTdWJzY3JpYmVycyB0aGUgYXJyYXkgb2YgbWVzc2FnZSBzdWJzY3JpYmVycyB0byBiZSBjYWxsZWQuIEVhY2ggc3Vic2NyaWJlciBpcyBjYWxsZWQgd2l0aCB0aGUgaG9zdCBvYmplY3QgKHNlZSBNZXNzZW5nZXIgY29uc3RydWN0b3IpIGFzIHRoZSBjb250ZXh0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdG8gcGFzcyB0byBzdWJzY3JpYmVyXG4gKi9cbmZ1bmN0aW9uIF9jYWxsU3Vic2NyaWJlcnMobWVzc2FnZSwgZGF0YSwgY2FsbGJhY2ssIG1zZ1N1YnNjcmliZXJzLCBfc3luY2hyb25vdXMpIHtcbiAgICBpZiAobXNnU3Vic2NyaWJlcnMgJiYgbXNnU3Vic2NyaWJlcnMubGVuZ3RoKSB7XG4gICAgICAgIC8vIGNsb25pbmcgaXMgbmVjZXNzYXJ5IGFzIHNvbWUgb2YgdGhlIHN1YnNjcmliZXJzXG4gICAgICAgIC8vIGNhbiBiZSB1bnN1YnNjcmliZWQgZHVyaW5nIHRoZSBkaXNwYXRjaFxuICAgICAgICAvLyBzbyB0aGlzIGFycmF5IHdvdWxkIGNoYW5nZSBpbiB0aGUgcHJvY2Vzc1xuICAgICAgICBtc2dTdWJzY3JpYmVycyA9IG1zZ1N1YnNjcmliZXJzLnNsaWNlKCk7XG5cbiAgICAgICAgbXNnU3Vic2NyaWJlcnMuZm9yRWFjaChmdW5jdGlvbihzdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9jYWxsU3Vic2NyaWJlcihzdWJzY3JpYmVyLCBtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgX3N5bmNocm9ub3VzKTtcbiAgICAgICAgfSwgdGhpcyk7XG4gICAgfVxufVxuXG5cbmZ1bmN0aW9uIF9jYWxsU3Vic2NyaWJlcihzdWJzY3JpYmVyLCBtZXNzYWdlLCBkYXRhLCBjYWxsYmFjaywgX3N5bmNocm9ub3VzKSB7XG4gICAgdmFyIHN5bmNTdWJzY3JpYmVyID0gc3Vic2NyaWJlci5vcHRpb25zICYmIHN1YnNjcmliZXIub3B0aW9ucy5zeW5jXG4gICAgICAgICwgc3luY2hybyA9IChfc3luY2hyb25vdXMgJiYgc3luY1N1YnNjcmliZXIgIT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgfHwgc3luY1N1YnNjcmliZXI7XG5cbiAgICB2YXIgZGlzcGF0Y2hUaW1lcyA9IHN1YnNjcmliZXIub3B0aW9ucyAmJiBzdWJzY3JpYmVyLm9wdGlvbnMuZGlzcGF0Y2hUaW1lcztcbiAgICBpZiAoZGlzcGF0Y2hUaW1lcykge1xuICAgICAgICBpZiAoZGlzcGF0Y2hUaW1lcyA8PSAxKSB7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZXMgPSBzdWJzY3JpYmVyLl9fbWVzc2FnZXM7XG4gICAgICAgICAgICB0aGlzLm9mZihtZXNzYWdlcywgc3Vic2NyaWJlcik7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlzcGF0Y2hUaW1lcyA+IDEpXG4gICAgICAgICAgICBzdWJzY3JpYmVyLm9wdGlvbnMuZGlzcGF0Y2hUaW1lcy0tO1xuICAgIH1cblxuICAgIGlmIChzeW5jaHJvKVxuICAgICAgICBzdWJzY3JpYmVyLnN1YnNjcmliZXIuY2FsbChzdWJzY3JpYmVyLmNvbnRleHQsIG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrKTtcbiAgICBlbHNlXG4gICAgICAgIF8uZGVmZXJNZXRob2Qoc3Vic2NyaWJlci5zdWJzY3JpYmVyLCAnY2FsbCcsIHN1YnNjcmliZXIuY29udGV4dCwgbWVzc2FnZSwgZGF0YSwgY2FsbGJhY2spO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgdGhlIGFycmF5IG9mIHN1YnNjcmliZXJzIHRoYXQgd291bGQgYmUgY2FsbGVkIGlmIHRoZSBtZXNzYWdlIHdlcmUgZGlzcGF0Y2hlZC5cbiAqIElmIGBpbmNsdWRlUGF0dGVyblN1YnNjcmliZXJzID09PSBmYWxzZWAsIHBhdHRlcm4gc3Vic2NyaWJlcnMgd2l0aCBtYXRjaGluZyBwYXR0ZXJzIHdpbGwgbm90IGJlIGluY2x1ZGVkIChieSBkZWZhdWx0IHRoZXkgYXJlIGluY2x1ZGVkKS5cbiAqIElmIHRoZXJlIGFyZSBubyBzdWJzY3JpYmVycyB0byB0aGUgbWVzc2FnZSwgYHVuZGVmaW5lZGAgd2lsbCBiZSByZXR1cm5lZCwgbm90IGFuIGVtcHR5IGFycmF5LCBzbyBpdCBpcyBzYWZlIHRvIHVzZSB0aGUgcmVzdWx0IGluIGJvb2xlYW4gdGVzdHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBtZXNzYWdlIE1lc3NhZ2UgdG8gZ2V0IHN1YnNjcmliZXJzIGZvci5cbiAqICBJZiB0aGUgbWVzc2FnZSBpcyBSZWdFeHAsIG9ubHkgcGF0dGVybiBzdWJzY3JpYmVycyByZWdpc3RlcmVkIHdpdGggZXhhY3RseSB0aGlzIHBhdHRlcm4gd2lsbCBiZSByZXR1cm5lZC5cbiAqICBJZiB0aGUgbWVzc2FnZSBpcyBTdHJpbmcsIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgc3RyaW5nIG1lc3NhZ2VzIGFuZCBwYXR0ZXJuIHN1YnNjcmliZXJzIHJlZ2lzdGVyZWQgd2l0aCBtYXRjaGluZyBwYXR0ZXJuIHdpbGwgYmUgcmV0dXJuZWQgKHVubGVzcyB0aGUgc2Vjb25kIHBhcmFtZXRlciBpcyBmYWxzZSkuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGVQYXR0ZXJuU3Vic2NyaWJlcnMgT3B0aW9uYWwgZmFsc2UgdG8gcHJldmVudCBpbmNsdXNpb24gb2YgcGF0dGVyIHN1YnNjcmliZXJzLCBieSBkZWZhdWx0IHRoZXkgYXJlIGluY2x1ZGVkLlxuICogQHJldHVybiB7QXJyYXl8dW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBnZXRTdWJzY3JpYmVycyhtZXNzYWdlLCBpbmNsdWRlUGF0dGVyblN1YnNjcmliZXJzKSB7XG4gICAgY2hlY2sobWVzc2FnZSwgTWF0Y2guT25lT2YoU3RyaW5nLCBSZWdFeHApKTtcblxuICAgIHZhciBzdWJzY3JpYmVyc0hhc2ggPSB0aGlzLl9jaG9vc2VTdWJzY3JpYmVyc0hhc2gobWVzc2FnZSk7XG4gICAgdmFyIG1zZ1N1YnNjcmliZXJzID0gc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBbXS5jb25jYXQoc3Vic2NyaWJlcnNIYXNoW21lc3NhZ2VdKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogW107XG5cbiAgICAvLyBwYXR0ZXJuIHN1YnNjcmliZXJzIGFyZSBpbmN1ZGVkIGJ5IGRlZmF1bHRcbiAgICBpZiAoaW5jbHVkZVBhdHRlcm5TdWJzY3JpYmVycyAhPT0gZmFsc2UgJiYgdHlwZW9mIG1lc3NhZ2UgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgXy5lYWNoS2V5KHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnMsXG4gICAgICAgICAgICBmdW5jdGlvbihwYXR0ZXJuU3Vic2NyaWJlcnMpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGF0dGVybiA9IHBhdHRlcm5TdWJzY3JpYmVycy5wYXR0ZXJuO1xuICAgICAgICAgICAgICAgIGlmIChwYXR0ZXJuU3Vic2NyaWJlcnMgJiYgcGF0dGVyblN1YnNjcmliZXJzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgcGF0dGVybi50ZXN0KG1lc3NhZ2UpKVxuICAgICAgICAgICAgICAgICAgICBfLmFwcGVuZEFycmF5KG1zZ1N1YnNjcmliZXJzLCBwYXR0ZXJuU3Vic2NyaWJlcnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8vIHJldHVybiB1bmRlZmluZWQgaWYgdGhlcmUgYXJlIG5vIHN1YnNjcmliZXJzXG4gICAgcmV0dXJuIG1zZ1N1YnNjcmliZXJzLmxlbmd0aFxuICAgICAgICAgICAgICAgID8gbXNnU3Vic2NyaWJlcnNcbiAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcbn1cblxuXG4vKipcbiAqIFwiUHJpdmF0ZVwiIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIFJldHVybnMgdGhlIG1hcCBvZiBzdWJzY3JpYmVycyBmb3IgYSBnaXZlbiBtZXNzYWdlIHR5cGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gbWVzc2FnZSBNZXNzYWdlIHRvIGNob29zZSB0aGUgbWFwIG9mIHN1YnNjcmliZXJzIGZvclxuICogQHJldHVybiB7T2JqZWN0W0Z1bmN0aW9uXX1cbiAqL1xuZnVuY3Rpb24gX2Nob29zZVN1YnNjcmliZXJzSGFzaChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIG1lc3NhZ2UgaW5zdGFuY2VvZiBSZWdFeHBcbiAgICAgICAgICAgICAgICA/IHRoaXMuX3BhdHRlcm5NZXNzYWdlU3Vic2NyaWJlcnNcbiAgICAgICAgICAgICAgICA6IHRoaXMuX21lc3NhZ2VTdWJzY3JpYmVycztcbn1cblxuXG4vKipcbiAqIE1lc3NlbmdlciBpbnN0YW5jZSBtZXRob2RcbiAqIFNldHMgW01lc3NhZ2VTb3VyY2VdKC4vbV9zb3VyY2UuanMuaHRtbCkgZm9yIHRoZSBtZXNzZW5nZXIgYWxzbyBzZXR0aW5nIHRoZSByZWZlcmVuY2UgdG8gdGhlIG1lc3NlbmdlciBpbiB0aGUgTWVzc2FnZVNvdXJjZS5cbiAqIE1lc3NhZ2VTb3VyY2UgY2FuIGJlIHBhc3NlZCB0byBtZXNzYWdlIGNvbnN0cnVjdG9yOyB0aGlzIG1ldGhvZCBhbGxvd3MgdG8gc2V0IGl0IGF0IGEgbGF0ZXIgdGltZS4gRm9yIGV4YW1wbGUsIHRoZSBzdWJjbGFzc2VzIG9mIFtDb21wb25lbnRGYWNldF0oLi4vY29tcG9uZW50cy9jX2ZhY2V0LmpzLmh0bWwpIHVzZSB0aGlzIG1ldGhvZCB0byBzZXQgZGlmZmVyZW50IE1lc3NhZ2VTb3VyY2UnZXMgaW4gdGhlIG1lc3NlbmdlciB0aGF0IGlzIGNyZWF0ZWQgYnkgQ29tcG9uZW50RmFjZXQuXG4gKiBDdXJyZW50bHkgdGhlIG1ldGhvZCBpcyBpbXBsZW1lbnRlZCBpbiBzdWNoIHdheSB0aGF0IGl0IGNhbiBiZSBjYWxsZWQgb25seSBvbmNlIC0gTWVzc2FnZVNvdXJjZSBjYW5ub3QgYmUgY2hhbmdlZCBhZnRlciB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuXG4gKlxuICogQHBhcmFtIHtNZXNzYWdlU291cmNlfSBtZXNzYWdlU291cmNlIGFuIGluc3RhbmNlIG9mIE1lc3NhZ2VTb3VyY2UgY2xhc3MgdG8gYXR0YWNoIHRvIHRoaXMgbWVzc2VuZ2VyIChhbmQgdG8gaGF2ZSB0aGlzIG1lc3NlbmdlciBhdHRhY2hlZCB0byBpdCB0b28pXG4gKi9cbmZ1bmN0aW9uIF9zZXRNZXNzYWdlU291cmNlKG1lc3NhZ2VTb3VyY2UpIHtcbiAgICBjaGVjayhtZXNzYWdlU291cmNlLCBNZXNzYWdlU291cmNlKTtcblxuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ19tZXNzYWdlU291cmNlJywgbWVzc2FnZVNvdXJjZSk7XG4gICAgbWVzc2FnZVNvdXJjZS5tZXNzZW5nZXIgPSB0aGlzO1xufVxuXG5cbi8qKlxuICogTWVzc2VuZ2VyIGluc3RhbmNlIG1ldGhvZFxuICogUmV0dXJucyBtZXNzZW5nZXIgTWVzc2FnZVNvdXJjZVxuICpcbiAqIEByZXR1cm4ge01lc3NhZ2VTb3VyY2V9XG4gKi9cbmZ1bmN0aW9uIGdldE1lc3NhZ2VTb3VyY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX21lc3NhZ2VTb3VyY2Vcbn1cbiIsImFyZ3VtZW50c1s0XVs2OF1bMF0uYXBwbHkoZXhwb3J0cyxhcmd1bWVudHMpIiwiYXJndW1lbnRzWzRdWzY5XVswXS5hcHBseShleHBvcnRzLGFyZ3VtZW50cykiLCIndXNlIHN0cmljdCc7XG5cbnZhciBNaXhpbiA9IHJlcXVpcmUoJy4uL2Fic3RyYWN0L21peGluJylcbiAgICAsIE1lc3NlbmdlckFQSSA9IHJlcXVpcmUoJy4vbV9hcGknKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaDtcblxuXG4vKipcbiAqIGBtaWxvLmNsYXNzZXMuTWVzc2FnZVNvdXJjZWBcbiAqIEFuIGFic3RyYWN0IGNsYXNzIChzdWJjbGFzcyBvZiBbTWl4aW5dKC4uL2Fic3RyYWN0L21peGluLmpzLmh0bWwpKSBmb3IgY29ubmVjdGluZyBbTWVzc2VuZ2VyXSguL2luZGV4LmpzLmh0bWwpIHRvIGV4dGVybmFsIHNvdXJjZXMgb2YgbWVzc2FnZXMgKGxpa2UgRE9NIGV2ZW50cykgYW5kIGRlZmluaW5nIGhpZ2hlciBsZXZlbCBtZXNzYWdlcy5cbiAqIEFuIGluc3RhbmNlIG9mIE1lc3NhZ2VTb3VyY2UgY2FuIGVpdGhlciBiZSBwYXNzZWQgdG8gTWVzc2VuZ2VyIGNvbnN0cnVjdG9yIG9yIGxhdGVyIHVzaW5nIGBfc2V0TWVzc2FnZVNvdXJjZWAgbWV0aG9kIG9mIE1lc3Nlbmdlci4gT25jZSBzZXQsIE1lc3NhZ2VTb3VyY2Ugb2YgTWVzc2VuZ2VyIGNhbm5vdCBiZSBjaGFuZ2VkLlxuICovXG52YXIgTWVzc2FnZVNvdXJjZSA9IF8uY3JlYXRlU3ViY2xhc3MoTWl4aW4sICdNZXNzYWdlU291cmNlJywgdHJ1ZSk7XG5cbm1vZHVsZS5leHBvcnRzID0gTWVzc2FnZVNvdXJjZTtcblxuXG4vKipcbiAqICMjIyNNZXNzYWdlU291cmNlIGluc3RhbmNlIG1ldGhvZHMjIyMjXG4gKlxuICogLSBbaW5pdF0oI2luaXQpIC0gaW5pdGlhbGl6ZXMgbWVzc2FnZVNvdXJjZSAtIGNhbGxlZCBieSBNaXhpbiBzdXBlcmNsYXNzXG4gKiAtIFtzZXRNZXNzZW5nZXJdKCNzZXRNZXNzZW5nZXIpIC0gY29ubmVjdHMgTWVzc2VuZ2VyIHRvIE1lc3NhZ2VTb3VyY2UsIGlzIGNhbGxlZCBmcm9tIGBpbml0YCBvciBgX3NldE1lc3NhZ2VTb3VyY2VgIG1ldGhvZHMgb2YgW01lc3Nlbmdlcl0oLi9pbmRleC5qcy5odG1sKS5cbiAqIC0gW29uU3Vic2NyaWJlckFkZGVkXSgjb25TdWJzY3JpYmVyQWRkZWQpIC0gY2FsbGVkIGJ5IE1lc3NlbmdlciB0byBub3RpZnkgd2hlbiB0aGUgZmlyc3Qgc3Vic2NyaWJlciBmb3IgYW4gaW50ZXJuYWwgbWVzc2FnZSB3YXMgYWRkZWQsIHNvIE1lc3NhZ2VTb3VyY2UgY2FuIHN1YnNjcmliZSB0byBzb3VyY2VcbiAqIC0gW29uU3Vic2NyaWJlclJlbW92ZWRdKCNvblN1YnNjcmliZXJSZW1vdmVkKSAtIGNhbGxlZCBieSBNZXNzZW5nZXIgdG8gbm90aWZ5IHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciBmb3IgYW4gaW50ZXJuYWwgbWVzc2FnZSB3YXMgcmVtb3ZlZCwgc28gTWVzc2FnZVNvdXJjZSBjYW4gdW5zdWJzY3JpYmUgZnJvbSBzb3VyY2VcbiAqIC0gW2Rpc3BhdGNoTWVzc2FnZV0oI2Rpc3BhdGNoTWVzc2FnZSkgLSBkaXNwYXRjaGVzIHNvdXJjZSBtZXNzYWdlLiBNZXNzYWdlU291cmNlIHN1YmNsYXNzIHNob3VsZCBpbXBsZW1lbnQgbWVjaGFuaXNtIHdoZW4gb24gYWN0dWFsIHNvdXJjZSBtZXNzYWdlIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC5cbiAqXG4gKiBNZXRob2RzIGJlbG93IHNob3VsZCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzczpcbiAqXG4gKiAtIFt0cmlnZ2VyXSgjdHJpZ2dlcikgLSB0cmlnZ2VycyBtZXNzYWdlcyBvbiB0aGUgc291cmNlIChhbiBvcHRpb25hbCBtZXRob2QpXG4gKiAtIFthZGRTb3VyY2VTdWJzY3JpYmVyXSgjYWRkU291cmNlU3Vic2NyaWJlcikgLSBhZGRzIGxpc3RlbmVyL3N1YnNjcmliZXIgdG8gZXh0ZXJuYWwgbWVzc2FnZVxuICogLSBbcmVtb3ZlU291cmNlU3Vic2NyaWJlcl0oI3JlbW92ZVNvdXJjZVN1YnNjcmliZXIpIC0gcmVtb3ZlcyBsaXN0ZW5lci9zdWJzY3JpYmVyIGZyb20gZXh0ZXJuYWwgbWVzc2FnZVxuICovXG5fLmV4dGVuZFByb3RvKE1lc3NhZ2VTb3VyY2UsIHtcbiAgICBpbml0OiBpbml0LFxuICAgIGRlc3Ryb3k6IE1lc3NhZ2VTb3VyY2UkZGVzdHJveSxcbiAgICBzZXRNZXNzZW5nZXI6IHNldE1lc3NlbmdlcixcbiAgICBvblN1YnNjcmliZXJBZGRlZDogb25TdWJzY3JpYmVyQWRkZWQsXG4gICAgb25TdWJzY3JpYmVyUmVtb3ZlZDogb25TdWJzY3JpYmVyUmVtb3ZlZCwgXG4gICAgZGlzcGF0Y2hNZXNzYWdlOiBkaXNwYXRjaE1lc3NhZ2UsXG4gICAgcG9zdE1lc3NhZ2U6IHBvc3RNZXNzYWdlLFxuICAgIF9wcmVwYXJlTWVzc2VuZ2VyQVBJOiBfcHJlcGFyZU1lc3NlbmdlckFQSSxcblxuICAgIC8vIE1ldGhvZHMgYmVsb3cgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzc1xuICAgIHRyaWdnZXI6IHRvQmVJbXBsZW1lbnRlZCxcbiAgICBhZGRTb3VyY2VTdWJzY3JpYmVyOiB0b0JlSW1wbGVtZW50ZWQsXG4gICAgcmVtb3ZlU291cmNlU3Vic2NyaWJlcjogdG9CZUltcGxlbWVudGVkXG59KTtcblxuXG4vKipcbiAqIE1lc3NhZ2VTb3VyY2UgaW5zdGFuY2UgbWV0aG9kLlxuICogQ2FsbGVkIGJ5IE1peGluIGNvbnN0cnVjdG9yLlxuICogTWVzc2FnZVNvdXJjZSBjb25zdHJ1Y3RvciBzaG91bGQgYmUgcGFzc2VkIHRoZSBzYW1lIHBhcmFtZXRlcnMgYXMgdGhpcyBtZXRob2Qgc2lnbmF0dXJlLlxuICogSWYgYW4gaW5zdGFuY2Ugb2YgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSBpcyBwYXNzZWQgYXMgdGhlIHRoaXJkIHBhcmFtZXRlciwgaXQgZXh0ZW5kcyBNZXNzYWdlU291cmNlIGZ1bmN0aW9uYWxpdHkgdG8gYWxsb3cgaXQgdG8gZGVmaW5lIG5ldyBtZXNzYWdlcywgdG8gZmlsdGVyIG1lc3NhZ2VzIGJhc2VkIG9uIHRoZWlyIGRhdGEgYW5kIHRvIGNoYW5nZSBtZXNzYWdlIGRhdGEuIFNlZSBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IE9wdGlvbmFsIG9iamVjdCB0aGF0IHN0b3JlcyB0aGUgTWVzc2FnZVNvdXJjZSBvbiBvbmUgb2YgaXRzIHByb3BlcnRpZXMuIEl0IGlzIHVzZWQgdG8gcHJveHkgbWV0aG9kcyBvZiBNZXNzYWdlU291cmNlLlxuICogQHBhcmFtIHtPYmplY3RbU3RyaW5nXX0gcHJveHlNZXRob2RzIE9wdGlvbmFsIG1hcCBvZiBtZXRob2QgbmFtZXM7IGtleSAtIHByb3h5IG1ldGhvZCBuYW1lLCB2YWx1ZSAtIE1lc3NhZ2VTb3VyY2UncyBtZXRob2QgbmFtZS5cbiAqIEBwYXJhbSB7TWVzc2VuZ2VyQVBJfSBtZXNzZW5nZXJBUEkgT3B0aW9uYWwgaW5zdGFuY2Ugb2YgTWVzc2VuZ2VyQVBJLlxuICovXG5mdW5jdGlvbiBpbml0KGhvc3RPYmplY3QsIHByb3h5TWV0aG9kcywgbWVzc2VuZ2VyQVBJKSB7XG4gICAgdGhpcy5fcHJlcGFyZU1lc3NlbmdlckFQSShtZXNzZW5nZXJBUEkpO1xufVxuXG5cbi8qKlxuICogRGVzdHJveXMgbWVzc2FnZSBzb3VyY2VcbiAqL1xuZnVuY3Rpb24gTWVzc2FnZVNvdXJjZSRkZXN0cm95KCkge1xuICAgIGlmICh0aGlzLm1lc3NlbmdlckFQSSlcbiAgICAgICAgdGhpcy5tZXNzZW5nZXJBUEkuZGVzdHJveSgpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBTZXRzIHJlZmVyZW5jZSB0byBNZXNzZW5nZXIgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtNZXNzZW5nZXJ9IG1lc3NlbmdlciByZWZlcmVuY2UgdG8gTWVzc2VuZ2VyIGluc3RhbmNlIGxpbmtlZCB0byB0aGlzIE1lc3NhZ2VTb3VyY2VcbiAqL1xuZnVuY3Rpb24gc2V0TWVzc2VuZ2VyKG1lc3Nlbmdlcikge1xuICAgIF8uZGVmaW5lUHJvcGVydHkodGhpcywgJ21lc3NlbmdlcicsIG1lc3Nlbmdlcik7XG59XG5cblxuLyoqXG4gKiBNZXNzYWdlU291cmNlIGluc3RhbmNlIG1ldGhvZC5cbiAqIFByZXBhcmVzIFtNZXNzZW5nZXJBUEldKC4vbV9hcGkuanMuaHRtbCkgcGFzc2VkIHRvIGNvbnN0cnVjdG9yIGJ5IHByb3h5aW5nIGl0cyBtZXRob2RzIHRvIGl0c2VsZiBvciBpZiBNZXNzZW5nZXJBUEkgd2Fzbid0IHBhc3NlZCBkZWZpbmVzIHR3byBtZXRob2RzIHRvIGF2b2lkIGNoZWNraW5nIHRoZWlyIGF2YWlsYWJpbGl0eSBldmVyeSB0aW1lIHRoZSBtZXNzYWdlIGlzIGRpc3BhdGNoZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7TWVzc2VuZ2VyQVBJfSBtZXNzZW5nZXJBUEkgT3B0aW9uYWwgaW5zdGFuY2Ugb2YgTWVzc2VuZ2VyQVBJXG4gKi9cbmZ1bmN0aW9uIF9wcmVwYXJlTWVzc2VuZ2VyQVBJKG1lc3NlbmdlckFQSSkge1xuICAgIGNoZWNrKG1lc3NlbmdlckFQSSwgTWF0Y2guT3B0aW9uYWwoTWVzc2VuZ2VyQVBJKSk7XG5cbiAgICBpZiAoISBtZXNzZW5nZXJBUEkpXG4gICAgICAgIG1lc3NlbmdlckFQSSA9IG5ldyBNZXNzZW5nZXJBUEk7XG5cbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdtZXNzZW5nZXJBUEknLCBtZXNzZW5nZXJBUEkpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBTdWJzY3JpYmVzIHRvIGV4dGVybmFsIHNvdXJjZSB1c2luZyBgYWRkU291cmNlU3Vic2NyaWJlcmAgbWV0aG9kIHRoYXQgc2hvdWxkIGJlIGltcGxlbWVudGVkIGluIHN1YmNsYXNzLlxuICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IFtNZXNzZW5nZXJdKC4vaW5kZXguanMuaHRtbCkgd2hlbiB0aGUgZmlyc3Qgc3Vic2NyaWJlciB0byB0aGUgYG1lc3NhZ2VgIGlzIGFkZGVkLlxuICogRGVsZWdhdGVzIHRvIHN1cHBsaWVkIG9yIGRlZmF1bHQgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSBmb3IgdHJhbnNsYXRpb24gb2YgYG1lc3NhZ2VgIHRvIGBzb3VyY2VNZXNzYWdlYC4gYE1lc3NhZ2VBUEkucHJvdG90eXBlLmFkZEludGVybmFsTWVzc2FnZWAgd2lsbCByZXR1cm4gdW5kZWZpbmVkIGlmIHRoaXMgYHNvdXJjZU1lc3NhZ2VgIHdhcyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gdG8gcHJldmVudCBkdXBsaWNhdGUgc3Vic2NyaXB0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIE1lc3NlbmdlciBtZXNzYWdlIHRoYXQgaGFzIHRvIGJlIHN1YnNjcmliZWQgdG8gYXQgdGhlIGV4dGVybmFsIHNvdXJjZSBvZiBtZXNzYWdlcy5cbiAqL1xuZnVuY3Rpb24gb25TdWJzY3JpYmVyQWRkZWQobWVzc2FnZSkge1xuICAgIHZhciBuZXdTb3VyY2VNZXNzYWdlID0gdGhpcy5tZXNzZW5nZXJBUEkuYWRkSW50ZXJuYWxNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIGlmICh0eXBlb2YgbmV3U291cmNlTWVzc2FnZSAhPSAndW5kZWZpbmVkJylcbiAgICAgICAgdGhpcy5hZGRTb3VyY2VTdWJzY3JpYmVyKG5ld1NvdXJjZU1lc3NhZ2UpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBVbnN1YnNjcmliZXMgZnJvbSBleHRlcm5hbCBzb3VyY2UgdXNpbmcgYHJlbW92ZVNvdXJjZVN1YnNjcmliZXJgIG1ldGhvZCB0aGF0IHNob3VsZCBiZSBpbXBsZW1lbnRlZCBpbiBzdWJjbGFzcy5cbiAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBbTWVzc2VuZ2VyXSguL2luZGV4LmpzLmh0bWwpIHdoZW4gdGhlIGxhc3Qgc3Vic2NyaWJlciB0byB0aGUgYG1lc3NhZ2VgIGlzIHJlbW92ZWQuXG4gKiBEZWxlZ2F0ZXMgdG8gc3VwcGxpZWQgb3IgZGVmYXVsdCBbTWVzc2VuZ2VyQVBJXSguL21fYXBpLmpzLmh0bWwpIGZvciB0cmFuc2xhdGlvbiBvZiBgbWVzc2FnZWAgdG8gYHNvdXJjZU1lc3NhZ2VgLiBgTWVzc2FnZUFQSS5wcm90b3R5cGUucmVtb3ZlSW50ZXJuYWxNZXNzYWdlYCB3aWxsIHJldHVybiB1bmRlZmluZWQgaWYgdGhpcyBgc291cmNlTWVzc2FnZWAgd2FzIG5vdCB5ZXQgc3Vic2NyaWJlZCB0byB0byBwcmV2ZW50IHVuc3Vic2NyaXB0aW9uIHdpdGhvdXQgcHJldmlvdXMgc3Vic2NyaXB0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGludGVybmFsIE1lc3NlbmdlciBtZXNzYWdlIHRoYXQgaGFzIHRvIGJlIHVuc3Vic2NyaWJlZCBmcm9tIGF0IHRoZSBleHRlcm5hbCBzb3VyY2Ugb2YgbWVzc2FnZXMuXG4gKi9cbmZ1bmN0aW9uIG9uU3Vic2NyaWJlclJlbW92ZWQobWVzc2FnZSkge1xuICAgIHZhciByZW1vdmVkU291cmNlTWVzc2FnZSA9IHRoaXMubWVzc2VuZ2VyQVBJLnJlbW92ZUludGVybmFsTWVzc2FnZShtZXNzYWdlKTtcbiAgICBpZiAodHlwZW9mIHJlbW92ZWRTb3VyY2VNZXNzYWdlICE9ICd1bmRlZmluZWQnKVxuICAgICAgICB0aGlzLnJlbW92ZVNvdXJjZVN1YnNjcmliZXIocmVtb3ZlZFNvdXJjZU1lc3NhZ2UpO1xufVxuXG5cbi8qKlxuICogTWVzc2FnZVNvdXJjZSBpbnN0YW5jZSBtZXRob2QuXG4gKiBEaXNwYXRjaGVzIHNvdXJjZU1lc3NhZ2UgdG8gTWVzc2VuZ2VyLlxuICogTWVjaGFuaXNtIHRoYXQgY2FsbHMgdGhpcyBtZXRob2Qgd2hlbiB0aGUgc291cmNlIG1lc3NhZ2UgaXMgcmVjZWl2ZWQgc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzIChzZWUgW0RPTUV2ZW50c1NvdXJjZV0oLi4vY29tcG9uZW50cy9tc2dfc3JjL2RvbV9ldmVudHMuanMuaHRtbCkgZm9yIGV4YW1wbGUpLlxuICogRGVsZWdhdGVzIHRvIHN1cHBsaWVkIG9yIGRlZmF1bHQgW01lc3NlbmdlckFQSV0oLi9tX2FwaS5qcy5odG1sKSB0byBjcmVhdGUgaW50ZXJuYWwgbWVzc2FnZSBkYXRhIChgY3JlYXRlSW50ZXJuYWxEYXRhYCkgYW5kIHRvIGZpbHRlciB0aGUgbWVzc2FnZSBiYXNlZCBvbiBpdHMgZGF0YSBhbmQvb3IgbWVzc2FnZSAoYGZpbHRlclNvdXJjZU1lc3NhZ2VgKS5cbiAqIEJhc2UgTWVzc2VuZ2VyQVBJIGNsYXNzIGltcGxlbWVudHMgdGhlc2UgdHdvIG1ldGhvZHMgaW4gYSB0cml2aWFsIHdheSAoYGNyZWF0ZUludGVybmFsRGF0YWAgc2ltcGx5IHJldHVybnMgZXh0ZXJuYWwgZGF0YSwgYGZpbHRlclNvdXJjZU1lc3NhZ2VgIHJldHVybnMgYHRydWVgKSwgdGhleSBhcmUgbWVhbnQgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNvdXJjZU1lc3NhZ2Ugc291cmNlIG1lc3NhZ2UgcmVjZWl2ZWQgZnJvbSBleHRlcm5hbCBzb3VyY2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2VEYXRhIGRhdGEgcmVjZWl2ZWQgZnJvbSBleHRlcm5hbCBzb3VyY2VcbiAqL1xuZnVuY3Rpb24gZGlzcGF0Y2hNZXNzYWdlKHNvdXJjZU1lc3NhZ2UsIHNvdXJjZURhdGEpIHtcbiAgICB2YXIgYXBpID0gdGhpcy5tZXNzZW5nZXJBUElcbiAgICAgICAgLCBpbnRlcm5hbE1lc3NhZ2VzID0gYXBpLmdldEludGVybmFsTWVzc2FnZXMoc291cmNlTWVzc2FnZSk7XG5cbiAgICBpZiAoaW50ZXJuYWxNZXNzYWdlcykgXG4gICAgICAgIGludGVybmFsTWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICAgICAgdmFyIGludGVybmFsRGF0YSA9IGFwaS5jcmVhdGVJbnRlcm5hbERhdGEoc291cmNlTWVzc2FnZSwgbWVzc2FnZSwgc291cmNlRGF0YSk7XG5cbiAgICAgICAgICAgIHZhciBzaG91bGREaXNwYXRjaCA9IGFwaS5maWx0ZXJTb3VyY2VNZXNzYWdlKHNvdXJjZU1lc3NhZ2UsIG1lc3NhZ2UsIGludGVybmFsRGF0YSk7XG4gICAgICAgICAgICBpZiAoc2hvdWxkRGlzcGF0Y2gpIFxuICAgICAgICAgICAgICAgIHRoaXMucG9zdE1lc3NhZ2UobWVzc2FnZSwgaW50ZXJuYWxEYXRhKTsgICAgICBcbiAgICAgICAgICAgIFxuICAgICAgICB9LCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIFBvc3RzIG1lc3NhZ2Ugb24gdGhlIG1lc3Nlbmdlci4gVGhpcyBtZXRob2QgaXMgc2VwYXJhdGVkIHNvIHNwZWNpZmljIG1lc3NhZ2Ugc291cmNlcyBjYW4gbWFrZSBtZXNzYWdlIGRpc3BhdGNoIHN5bmNocm9ub3VzIGJ5IHVzaW5nIGBwb3N0TWVzc2FnZVN5bmNgXG4gKiBcbiAqIEBwYXJhbSAge1N0cmluZ30gbWVzc2FnZVxuICogQHBhcmFtICB7T2JqZWN0fSBkYXRhXG4gKi9cbmZ1bmN0aW9uIHBvc3RNZXNzYWdlKG1lc3NhZ2UsIGRhdGEpIHtcbiAgICB0aGlzLm1lc3Nlbmdlci5wb3N0TWVzc2FnZShtZXNzYWdlLCBkYXRhKTtcbn1cblxuXG5mdW5jdGlvbiB0b0JlSW1wbGVtZW50ZWQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYWxsaW5nIHRoZSBtZXRob2Qgb2YgYW4gYWJzY3RyYWN0IGNsYXNzJyk7XG59XG4iLCJhcmd1bWVudHNbNF1bNzFdWzBdLmFwcGx5KGV4cG9ydHMsYXJndW1lbnRzKSIsIid1c2Ugc3RyaWN0JztcblxudmFyIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKTtcblxuXG4vKipcbiAqICMjIyNNaWxvIHBhY2thZ2VzIyMjI1xuICpcbiAqIC0gW21pbmRlcl0oLi9taW5kZXIuanMuaHRtbCkgLSBkYXRhIHJlYWN0aXZpdHksIG9uZSBvciB0d28gd2F5LCBzaGFsbG93IG9yIGRlZXAsIGFzIHlvdSBsaWtlIGl0XG4gKiAtIFtjb25maWddKC4vY29uZmlnLmpzLmh0bWwpIC0gbWlsbyBjb25maWd1cmF0aW9uXG4gKiAtIFt1dGlsXSguL3V0aWwvaW5kZXguanMuaHRtbCkgLSBsb2dnZXIsIHJlcXVlc3QsIGRvbSwgY2hlY2ssIGVycm9yLCBldGMuXG4gKiAtIFtjbGFzc2VzXSguL2NsYXNzZXMuanMuaHRtbCkgLSBhYnN0cmFjdCBhbmQgYmFzZSBjbGFzc2VzXG4gKiAtIFtNZXNzZW5nZXJdKC4vbWVzc2VuZ2VyL2luZGV4LmpzLmh0bWwpIC0gZ2VuZXJpYyBNZXNzZW5nZXIgdXNlZCBpbiBtb3N0IG90aGVyIG1pbG8gY2xhc3NlcywgY2FuIGJlIG1peGVkIGludG8gYXBwIGNsYXNzZXMgdG9vLlxuICogLSBbTW9kZWxdKC4vbW9kZWwvaW5kZXguanMuaHRtbCkgLSBNb2RlbCBjbGFzcyB0aGF0IGVtaXRzIG1lc3NhZ2VzIG9uIGNoYW5nZXMgdG8gYW55IGRlcHRoIHdpdGhvdXQgdGltZXIgYmFzZWQgd2F0Y2hpbmdcbiAqL1xudmFyIG1pbG8gPSB7XG4gICAgbWluZGVyOiByZXF1aXJlKCcuL21pbmRlcicpLFxuICAgIGNvbmZpZzogcmVxdWlyZSgnLi9jb25maWcnKSxcbiAgICB1dGlsOiByZXF1aXJlKCcuL3V0aWwnKSxcbiAgICBjbGFzc2VzOiByZXF1aXJlKCcuL2NsYXNzZXMnKSxcbiAgICBNZXNzZW5nZXI6IHJlcXVpcmUoJy4vbWVzc2VuZ2VyJyksXG4gICAgTW9kZWw6IHJlcXVpcmUoJy4vbW9kZWwnKSxcbiAgICBkZXN0cm95OiBkZXN0cm95XG59O1xuXG5cbi8vIGV4cG9ydCBmb3Igbm9kZS9icm93c2VyaWZ5XG5pZiAodHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgICAgXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBtaWxvO1xuXG4vLyBnbG9iYWwgbWlsbyBmb3IgYnJvd3NlclxuaWYgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcpXG4gICAgd2luZG93Lm1pbG8gPSBtaWxvO1xuXG5cbmZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgbWlsby5taW5kZXIuZGVzdHJveSgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQ29ubmVjdG9yID0gcmVxdWlyZSgnLi9tb2RlbC9jb25uZWN0b3InKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi9tZXNzZW5nZXInKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuL3V0aWwvbG9nZ2VyJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBtaW5kZXI7XG5cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgb25lIG9yIG1hbnkgQ29ubmVjdG9yIG9iamVjdHMgdGhhdFxuICogY3JlYXRlIGxpdmUgcmVhY3RpdmUgY29ubmVjdGlvbiBiZXR3ZWVuIG9iamVjdHMgaW1wbGVtZW50aW5nXG4gKiBkYXRhU291cmNlIGludGVyZmFjZTpcbiAqIE9iamVjdHMgc2hvdWxkIGVtaXQgbWVzc2FnZXMgd2hlbiBhbnkgcGFydCBvZiB0aGVpciBkYXRhIGNoYW5nZXMsXG4gKiBtZXRob2RzIGBvbmAgYW5kIGBvZmZgIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB0byBzdWJzY3JpYmUvdW5zdWJzY3JpYmVcbiAqIHRvIGNoYW5nZSBub3RpZmljYXRpb24gbWVzc2FnZXMsIG1ldGhvZHMgYHNldGAgYW5kIGBnZXRgIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB0byBnZXQvc2V0IGRhdGFcbiAqIG9uIHBhdGggb2JqZWN0cywgcG9pbnRpbmcgdG8gcGFydGljdWxhciBwYXJ0cyBvZiB0aGUgb2JqZWN0LCBtZXRob2QgYHBhdGhgXG4gKiBzaG91bGQgcmV0dXJuIHBhdGggb2JqZWN0IGZvciBhIGdpdmVuIHBhdGggc3RyaW5nIChzZWUgcGF0aCB1dGlscyBmb3IgcGF0aCBzdHJpbmcgc3ludGF4KS5cbiAqIEJvdGggTW9kZWwgYW5kIERhdGEgZmFjZXQgYXJlIHN1Y2ggZGF0YSBzb3VyY2VzLCB0aGV5IGNhbiBiZSBsaW5rZWQgYnkgQ29ubmVjdG9yIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZHMxIHRoZSBmaXJzdCBkYXRhIHNvdXJjZS4gSW5zdGVhZCBvZiB0aGUgZmlyc3QgZGF0YSBzb3VyY2UgYW4gYXJyYXkgY2FuIGJlIHBhc3NlZCB3aXRoIGFycmF5cyBvZiBDb25uZWN0aW9uIG9iamVjdHMgcGFyYW1ldGVycyBpbiBlYWNoIGFycmF5IGVsZW1lbnQuXG4gKiBAcGFyYW0ge1N0cmluZ30gbW9kZSB0aGUgY29ubmVjdGlvbiBtb2RlIHRoYXQgZGVmaW5lcyB0aGUgZGlyZWN0aW9uIGFuZCB0aGUgZGVwdGggb2YgY29ubmVjdGlvbi4gUG9zc2libGUgdmFsdWVzIGFyZSAnLT4nLCAnPDwtJywgJzw8PC0+Pj4nLCBldGMuXG4gKiBAcGFyYW0ge09iamVjdH0gZHMyIHRoZSBzZWNvbmQgZGF0YSBzb3VyY2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiAqL1xuZnVuY3Rpb24gbWluZGVyKGRzMSwgbW9kZSwgZHMyLCBvcHRpb25zKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZHMxKSkge1xuICAgICAgICB2YXIgY29ubkRlc2NyaXB0aW9ucyA9IGRzMTtcbiAgICAgICAgdmFyIGNvbm5lY3RvcnMgPSBjb25uRGVzY3JpcHRpb25zLm1hcChmdW5jdGlvbihkZXNjcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb25uZWN0b3IoZGVzY3JbMF0sIGRlc2NyWzFdLCBkZXNjclsyXSwgZGVzY3JbM10pO1xuICAgICAgICB9KTtcbiAgICAgICAgY29ubmVjdG9ycy5mb3JFYWNoKF9hZGRDb25uZWN0b3IpO1xuICAgICAgICByZXR1cm4gY29ubmVjdG9ycztcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgY25jdCA9IG5ldyBDb25uZWN0b3IoZHMxLCBtb2RlLCBkczIsIG9wdGlvbnMpO1xuICAgICAgICBfYWRkQ29ubmVjdG9yKGNuY3QpO1xuICAgICAgICByZXR1cm4gY25jdDtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBtZXNzZW5nZXIgb2YgbWluZGVyIHdoZXJlIGl0IGVtaXRzIGV2ZW50cyByZWxhdGVkIHRvIGFsbCBjb25uZWN0b3JzXG4gKiBAdHlwZSB7TWVzc2VuZ2VyfVxuICovXG52YXIgX21lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXIobWluZGVyLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMpO1xuXG5cbnZhciBfY29ubmVjdG9ycyA9IFtdXG4gICAgLCBfcmVjZWl2ZWRNZXNzYWdlcyA9IFtdXG4gICAgLCBfaXNQcm9wYWdhdGluZyA9IGZhbHNlO1xuXG5cbl8uZXh0ZW5kKG1pbmRlciwge1xuICAgIGdldENvbm5lY3RvcnM6IG1pbmRlcl9nZXRDb25uZWN0b3JzLFxuICAgIGdldEV4cGFuZGVkQ29ubmVjdGlvbnM6IG1pbmRlcl9nZXRFeHBhbmRlZENvbm5lY3Rpb25zLFxuICAgIGlzUHJvcGFnYXRpbmc6IG1pbmRlcl9pc1Byb3BhZ2F0aW5nLFxuICAgIHdoZW5Qcm9wYWdhdGlvbkNvbXBsZXRlZDogbWluZGVyX3doZW5Qcm9wYWdhdGlvbkNvbXBsZXRlZCxcbiAgICBkZXN0cm95Q29ubmVjdG9yOiBtaW5kZXJfZGVzdHJveUNvbm5lY3RvcixcbiAgICBkZXN0cm95OiBtaW5kZXJfZGVzdHJveVxufSk7XG5cblxuZnVuY3Rpb24gX2FkZENvbm5lY3RvcihjbmN0KSB7XG4gICAgY25jdC5fX19taW5kZXJfaWQgPSBfY29ubmVjdG9ycy5wdXNoKGNuY3QpIC0gMTtcbiAgICBjbmN0Lm9uKC8uKi8sIG9uQ29ubmVjdG9yTWVzc2FnZSk7XG4gICAgbWluZGVyLnBvc3RNZXNzYWdlKCdhZGRlZCcsIHsgY29ubmVjdG9yOiBjbmN0IH0pO1xuICAgIG1pbmRlci5wb3N0TWVzc2FnZSgndHVybmVkb24nLCB7IGNvbm5lY3RvcjogY25jdCB9KTtcbn1cblxuXG5mdW5jdGlvbiBvbkNvbm5lY3Rvck1lc3NhZ2UobXNnLCBkYXRhKSB7XG4gICAgdmFyIGRhdGEgPSBkYXRhID8gXy5jbG9uZShkYXRhKSA6IHt9O1xuICAgIF8uZXh0ZW5kKGRhdGEsIHtcbiAgICAgICAgaWQ6IHRoaXMuX19fbWluZGVyX2lkLFxuICAgICAgICBjb25uZWN0b3I6IHRoaXNcbiAgICB9KTtcbiAgICBtaW5kZXIucG9zdE1lc3NhZ2UobXNnLCBkYXRhKTtcbiAgICBpZiAoISBfcmVjZWl2ZWRNZXNzYWdlcy5sZW5ndGggJiYgISBfaXNQcm9wYWdhdGluZykge1xuICAgICAgICBfLmRlZmVyKF9pZGxlQ2hlY2spO1xuICAgICAgICBfaXNQcm9wYWdhdGluZyA9IHRydWU7XG4gICAgfVxuXG4gICAgX3JlY2VpdmVkTWVzc2FnZXMucHVzaCh7IG1zZzogbXNnLCBkYXRhOiBkYXRhIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9pZGxlQ2hlY2soKSB7XG4gICAgaWYgKF9yZWNlaXZlZE1lc3NhZ2VzLmxlbmd0aCkge1xuICAgICAgICBfcmVjZWl2ZWRNZXNzYWdlcy5sZW5ndGggPSAwO1xuICAgICAgICBfLmRlZmVyKF9pZGxlQ2hlY2spO1xuICAgICAgICBtaW5kZXIucG9zdE1lc3NhZ2UoJ3Byb3BhZ2F0aW9udGlja2VkJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgX2lzUHJvcGFnYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgbWluZGVyLnBvc3RNZXNzYWdlKCdwcm9wYWdhdGlvbmNvbXBsZXRlZCcpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBtaW5kZXJfaXNQcm9wYWdhdGluZygpIHtcbiAgICByZXR1cm4gX2lzUHJvcGFnYXRpbmc7XG59XG5cblxuZnVuY3Rpb24gbWluZGVyX3doZW5Qcm9wYWdhdGlvbkNvbXBsZXRlZChjYWxsYmFjaykge1xuICAgIGlmIChfaXNQcm9wYWdhdGluZylcbiAgICAgICAgbWluZGVyLm9uY2UoJ3Byb3BhZ2F0aW9uY29tcGxldGVkJywgZXhlY3V0ZUNhbGxiYWNrKTtcbiAgICBlbHNlXG4gICAgICAgIF8uZGVmZXIoZXhlY3V0ZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIGV4ZWN1dGVDYWxsYmFjaygpIHtcbiAgICAgICAgaWYgKF9pc1Byb3BhZ2F0aW5nKVxuICAgICAgICAgICAgbWluZGVyLm9uY2UoJ3Byb3BhZ2F0aW9uY29tcGxldGVkJywgZXhlY3V0ZUNhbGxiYWNrKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9XG59XG5cblxuZnVuY3Rpb24gbWluZGVyX2dldENvbm5lY3RvcnMob25PZmYpIHtcbiAgICBpZiAodHlwZW9mIG9uT2ZmID09ICd1bmRlZmluZWQnKVxuICAgICAgICByZXR1cm4gX2Nvbm5lY3RvcnM7XG5cbiAgICByZXR1cm4gX2Nvbm5lY3RvcnMuZmlsdGVyKGZ1bmN0aW9uKGNuY3QpIHtcbiAgICAgICAgcmV0dXJuIGNuY3QuaXNPbiA9PT0gb25PZmY7XG4gICAgfSk7XG59XG5cblxuZnVuY3Rpb24gbWluZGVyX2Rlc3Ryb3lDb25uZWN0b3IoY25jdCkge1xuICAgIGNuY3QuZGVzdHJveSgpO1xuICAgIHZhciBpbmRleCA9IF9jb25uZWN0b3JzLmluZGV4T2YoY25jdCk7XG4gICAgaWYgKGluZGV4ID49IDApXG4gICAgICAgIGRlbGV0ZSBfY29ubmVjdG9yc1tpbmRleF07XG4gICAgZWxzZVxuICAgICAgICBsb2dnZXIud2FybignbWluZGVyOiBjb25uZWN0b3IgZGVzdHJveWVkIHRoYXQgaXMgbm90IHJlZ2lzdGVyZWQgaW4gbWluZGVyJyk7XG59XG5cblxuZnVuY3Rpb24gbWluZGVyX2dldEV4cGFuZGVkQ29ubmVjdGlvbnMob25PZmYsIHNlYXJjaFN0cikge1xuICAgIHZhciBjb25uZWN0b3JzID0gbWluZGVyLmdldENvbm5lY3RvcnMob25PZmYpO1xuICAgIHZhciBjb25uZWN0aW9ucyA9ICBjb25uZWN0b3JzLm1hcChmdW5jdGlvbihjbmN0KSB7XG4gICAgICAgIHZhciBjb25uZWN0aW9uID0ge1xuICAgICAgICAgICAgbGVmdFNvdXJjZTogX2dldEV4cGFuZGVkU291cmNlKGNuY3QuZHMxKSxcbiAgICAgICAgICAgIHJpZ2h0U291cmNlOiBfZ2V0RXhwYW5kZWRTb3VyY2UoY25jdC5kczIpLFxuICAgICAgICAgICAgbW9kZTogY25jdC5tb2RlLFxuICAgICAgICAgICAgaXNPbjogY25jdC5pc09uXG4gICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICBpZiAoY25jdC5vcHRpb25zKVxuICAgICAgICAgICAgY29ubmVjdGlvbi5vcHRpb25zID0gY25jdC5vcHRpb25zO1xuXG4gICAgICAgIHJldHVybiBjb25uZWN0aW9uO1xuICAgIH0pO1xuXG4gICAgaWYgKHNlYXJjaFN0cilcbiAgICAgICAgY29ubmVjdGlvbnMgPSBjb25uZWN0aW9ucy5maWx0ZXIoZnVuY3Rpb24oY25jdG4pIHtcbiAgICAgICAgICAgIHJldHVybiBfc291cmNlTWF0Y2hlc1N0cmluZyhjbmN0bi5sZWZ0U291cmNlLCBzZWFyY2hTdHIpXG4gICAgICAgICAgICAgICAgICAgIHx8IF9zb3VyY2VNYXRjaGVzU3RyaW5nKGNuY3RuLnJpZ2h0U291cmNlLCBzZWFyY2hTdHIpO1xuICAgICAgICB9KTtcblxuICAgIHJldHVybiBjb25uZWN0aW9ucztcbn1cblxuXG5mdW5jdGlvbiBfZ2V0RXhwYW5kZWRTb3VyY2UoZHMpIHtcbiAgICB2YXIgc291cmNlID0gW107XG4gICAgaWYgKHR5cGVvZiBkcyA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGlmIChkcy5fbW9kZWwgJiYgZHMuX2FjY2Vzc1BhdGgpIHtcbiAgICAgICAgICAgIHNvdXJjZS51bnNoaWZ0KGRzLl9hY2Nlc3NQYXRoKTtcbiAgICAgICAgICAgIGRzID0gZHMuX21vZGVsO1xuICAgICAgICB9XG5cbiAgICAgICAgc291cmNlLnVuc2hpZnQoZHMpO1xuICAgICAgICBkcyA9IGRzLl9ob3N0T2JqZWN0O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZHMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgc291cmNlLnVuc2hpZnQoZHMpO1xuXG4gICAgICAgIGlmIChkcy5vd25lcilcbiAgICAgICAgICAgIHNvdXJjZS51bnNoaWZ0KGRzLm93bmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlO1xufVxuXG5cbmZ1bmN0aW9uIF9zb3VyY2VNYXRjaGVzU3RyaW5nKHNvdXJjZSwgbWF0Y2hTdHIpIHtcbiAgICByZXR1cm4gc291cmNlLnNvbWUoZnVuY3Rpb24oc3JjTm9kZSkge1xuICAgICAgICB2YXIgY2xhc3NOYW1lID0gc3JjTm9kZS5jb25zdHJ1Y3RvciAmJiBzcmNOb2RlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIHJldHVybiBfc3RyaW5nTWF0Y2goY2xhc3NOYW1lLCBtYXRjaFN0cilcbiAgICAgICAgICAgICAgICB8fCBfc3RyaW5nTWF0Y2goc3JjTm9kZS5uYW1lLCBtYXRjaFN0cilcbiAgICAgICAgICAgICAgICB8fCBfc3RyaW5nTWF0Y2goc3JjTm9kZSwgbWF0Y2hTdHIpO1xuICAgIH0pO1xufVxuXG5cbmZ1bmN0aW9uIF9zdHJpbmdNYXRjaChzdHIsIHN1YnN0cikge1xuICAgIHJldHVybiBzdHIgJiYgdHlwZW9mIHN0ciA9PSAnc3RyaW5nJyAmJiBzdHIuaW5kZXhPZihzdWJzdHIpID49IDA7XG59XG5cblxuZnVuY3Rpb24gbWluZGVyX2Rlc3Ryb3koKSB7XG4gICAgX2Nvbm5lY3RvcnMuZm9yRWFjaChmdW5jdGlvbihjbmN0KSB7XG4gICAgICAgIGRlc3Ryb3lEUyhjbmN0LmRzMSk7XG4gICAgICAgIGRlc3Ryb3lEUyhjbmN0LmRzMik7XG4gICAgICAgIGNuY3QuZGVzdHJveSgpO1xuICAgIH0pO1xuICAgIF9tZXNzZW5nZXIuZGVzdHJveSgpO1xuICAgIG1pbmRlci5fZGVzdHJveWVkID0gdHJ1ZTtcblxuICAgIGZ1bmN0aW9uIGRlc3Ryb3lEUyhkcykge1xuICAgICAgICBpZiAoZHMgJiYgIWRzLl9kZXN0cm95ZWQpIGRzLmRlc3Ryb3koKTtcbiAgICB9XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGxvZ2dlciA9IHJlcXVpcmUoJy4uL3V0aWwvbG9nZ2VyJylcbiAgICAsIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpXG4gICAgLCBwYXRoVXRpbHMgPSByZXF1aXJlKCcuL3BhdGhfdXRpbHMnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gcHJvY2VzcyBcImNoYW5nZWRhdGFcIiBtZXNzYWdlcyBlbWl0dGVkIGJ5IENvbm5lY3RvciBvYmplY3QuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gY2hhbmdlRGF0YUhhbmRsZXI7XG5cblxuXy5leHRlbmQoY2hhbmdlRGF0YUhhbmRsZXIsIHtcbiAgICBzZXRUcmFuc2FjdGlvbkZsYWc6IHNldFRyYW5zYWN0aW9uRmxhZyxcbiAgICBnZXRUcmFuc2FjdGlvbkZsYWc6IGdldFRyYW5zYWN0aW9uRmxhZyxcbiAgICBwYXNzVHJhbnNhY3Rpb25GbGFnOiBwYXNzVHJhbnNhY3Rpb25GbGFnLFxuICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkOiBwb3N0VHJhbnNhY3Rpb25GaW5pc2hlZFxufSk7XG5cblxuLyoqXG4gKiBDaGFuZ2UgZGF0YSB1c2VzIGhpZGRlbiBwcm9wZXJ0eSBvbiBhY2Nlc3NvciBtZXRob2RzIHRvIHBhc3MgZmxhZyB0aGF0IHRoZSBhY2Nlc3NvciBpcyBleGVjdXRlZCBhcyBhIHBhcnQgb2YgY2hhbmdlIHRyYW5zYWN0aW9uLlxuICogQWNjZXNzb3IgbWV0aG9kcyBhcmUgc3VwcG9zZWQgdG8gc3RvcmUgdGhpcyBmbGFnIGluIGEgbG9jYWwgdmFyaWFibGUgYW5kIHRvIGNsZWFyIGl0IChiZWNhdXNlIGFub3RoZXIgYWNjZXNzb3IgY2FuIGJlIGV4ZWN1dGVkIGluIG9yIG91dCBvZiB0cmFuc2FjdGlvbikgdXNpbmcgYGdldFRyYW5zYWN0aW9uRmxhZ2BcbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBhY2Nlc3NvciBtZXRob2QgcmVmZXJlbmNlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGZsYWcgYSBmbGFnIHRvIGJlIHNldFxuICovXG5mdW5jdGlvbiBzZXRUcmFuc2FjdGlvbkZsYWcoZnVuYywgZmxhZykge1xuICAgIF8uZGVmaW5lUHJvcGVydHkoZnVuYywgJ19faW5DaGFuZ2VUcmFuc2FjdGlvbicsIGZsYWcsIF8uQ09ORiB8IF8uV1JJVCk7XG59XG5cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW5kIGNsZWFycyB0cmFuc2FjdGlvbiBmbGFnIGZyb20gYWNjZXNzb3IgbWV0aG9kXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgYWNjZXNzb3IgbWV0aG9kIHJlZmVyZW5jZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25GbGFnKGZ1bmMpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGZ1bmMuX19pbkNoYW5nZVRyYW5zYWN0aW9uO1xuICAgIGRlbGV0ZSBmdW5jLl9faW5DaGFuZ2VUcmFuc2FjdGlvbjtcbiAgICByZXR1cm4gaW5UcmFuc2FjdGlvbjtcbn1cblxuXG5mdW5jdGlvbiBwYXNzVHJhbnNhY3Rpb25GbGFnKGZyb21GdW5jLCB0b0Z1bmMpIHtcbiAgICB2YXIgaW5UcmFuc2FjdGlvbiA9IGdldFRyYW5zYWN0aW9uRmxhZyhmcm9tRnVuYyk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKHRvRnVuYywgaW5UcmFuc2FjdGlvbik7XG4gICAgcmV0dXJuIGluVHJhbnNhY3Rpb247XG59XG5cblxuLyoqXG4gKiBQb3N0cyBtZXNzYWdlIG9uIHRoaXMgdG8gaW5kaWNhdGUgdGhlIGVuZCBvZiB0cmFuc2FjdGlvbiB1bmxlc3MgYGluQ2hhbmdlVHJhbnNhY3Rpb25gIGlzIGB0cnVlYC5cbiAqL1xuZnVuY3Rpb24gcG9zdFRyYW5zYWN0aW9uRmluaXNoZWQoKSB7XG4gICAgdGhpcy5wb3N0TWVzc2FnZVN5bmMoJ2RhdGFjaGFuZ2VzJywgeyB0cmFuc2FjdGlvbjogZmFsc2UsIGNoYW5nZXM6IFtdIH0pO1xufVxuXG5cbi8qKlxuICogc3Vic2NyaWJlciB0byBcImNoYW5nZWRhdGFcIiBldmVudCBlbWl0dGVkIGJ5IFtDb25uZWN0b3JdKC4vY29ubmVjdG9yLmpzLmh0bWwpIG9iamVjdCB0byBlbmFibGUgcmVhY3RpdmUgY29ubmVjdGlvbnNcbiAqIFVzZWQgYnkgRGF0YSBmYWNldCwgTW9kZWwgYW5kIE1vZGVsUGF0aC4gQ2FuIGJlIHVzZWQgYnkgYW55IG9iamVjdCB0aGF0IGltcGxlbWVudHMgZ2V0L3NldC9kZWwvc3BsaWNlIGFwaSBhbmQgc2V0cyBkYXRhIGRlZXBseSB0byB0aGUgd2hvbGUgdHJlZS5cbiAqIE9iamVjdCBzaG91bGQgY2FsbCBgY2hhbmdlRGF0YUhhbmRsZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpYCBpbiBpdHMgY29uc3RydWN0b3IuXG4gKiBUT0RPOiBvcHRpbWl6ZSBtZXNzYWdlcyBsaXN0IHRvIGF2b2lkIHNldHRpbmcgZHVwbGljYXRlIHZhbHVlcyBkb3duIHRoZSB0cmVlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyBzaG91bGQgYmUgXCJjaGFuZ2VkYXRhXCIgaGVyZVxuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgYmF0Y2ggb2YgZGF0YSBjaGFuZ2UgZGVzY2lwdGlvbiBvYmplY3RzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsYmFjayB0byBjYWxsIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIGRhdGEgaXMgcHJvY2Vzc2VkXG4gKi9cbmZ1bmN0aW9uIGNoYW5nZURhdGFIYW5kbGVyKG1lc3NhZ2UsIGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgcHJvY2Vzc0NoYW5nZXMuY2FsbCh0aGlzLCBkYXRhLmNoYW5nZXMsIGNhbGxiYWNrKTtcbn1cblxuXG4vLyBtYXAgb2YgbWVzc2FnZSB0eXBlcyB0byBtZXRob2RzXG52YXIgQ0hBTkdFX1RZUEVfVE9fTUVUSE9EX01BUCA9IHtcbiAgICAnYWRkZWQnOiAgICdzZXQnLFxuICAgICdjaGFuZ2VkJzogJ3NldCcsXG4gICAgJ2RlbGV0ZWQnOiAnZGVsJyxcbiAgICAncmVtb3ZlZCc6ICdkZWwnXG59O1xuXG5cbi8qKlxuICogUHJvY2Vzc2VzIHF1ZXVlZCBcImNoYW5nZWRhdGFcIiBtZXNzYWdlcy5cbiAqIFBvc3RzIFwiY2hhbmdlc3RhcnRlZFwiIGFuZCBcImNoYW5nZWNvbXBsZXRlZFwiIG1lc3NhZ2VzIGFuZCBjYWxscyBjYWxsYmFja1xuICpcbiAqIEBwYXJhbSB7W0Z1bmN0aW9uXX0gY2FsbGJhY2sgb3B0aW9uYWwgY2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2l0aCBgKG51bGwsIGZhbHNlKWAgcGFyYW1ldGVycyBiZWZvcmUgY2hhbmdlIHByb2Nlc3Npbmcgc3RhcnRzIGFuZCBgKG51bGwsIHRydWUpYCBhZnRlciBpdCdzIGZpbmlzaGVkLlxuICovXG5mdW5jdGlvbiBwcm9jZXNzQ2hhbmdlcyh0cmFuc2FjdGlvbiwgY2FsbGJhY2spIHtcbiAgICBub3RpZnkuY2FsbCh0aGlzLCBjYWxsYmFjaywgZmFsc2UpO1xuICAgIHByb2Nlc3NUcmFuc2FjdGlvbi5jYWxsKHRoaXMsXG4gICAgICAgIHByZXBhcmVUcmFuc2FjdGlvbihcbiAgICAgICAgICAgIHZhbGlkYXRlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSk7XG4gICAgbm90aWZ5LmNhbGwodGhpcywgY2FsbGJhY2ssIHRydWUpO1xufVxuXG5cbmZ1bmN0aW9uIG5vdGlmeShjYWxsYmFjaywgY2hhbmdlRmluaXNoZWQpIHtcbiAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsLCBjaGFuZ2VGaW5pc2hlZCk7XG4gICAgdGhpcy5wb3N0TWVzc2FnZShjaGFuZ2VGaW5pc2hlZCA/ICdjaGFuZ2Vjb21wbGV0ZWQnIDogJ2NoYW5nZXN0YXJ0ZWQnKTtcbn1cblxuXG4vKipcbiAqIENoZWNrcyB0aGF0IGFsbCBtZXNzYWdlcyBmcm9tIHRoZSB0cmFuc2FjdGlvbiBjb21lIGZyb20gdGhlIHNhbWUgc291cmNlLlxuICogSGFjazogcmV2ZXJzZXMgdGhlIHRyYW5zYWN0aW9uIGlmIGl0IGNvbWVzIGZyb20gdGhlIERhdGEgZmFjZXRcbiAqIFJldHVybnMgdGhlIHJlZmVyZW5jZSB0byB0aGUgdHJhbnNhY3Rpb24gKGZvciBjaGFpbmluZylcbiAqIFxuICogQHBhcmFtICB7QXJyYXl9IHRyYW5zYWN0aW9uIHRyYW5zYWN0aW9uIG9mIGRhdGEgY2hhbmdlc1xuICogQHJldHVybiB7QXJyYXl9IFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSB7XG4gICAgdmFyIHNvdXJjZSA9IHRyYW5zYWN0aW9uWzBdLnNvdXJjZVxuICAgICAgICAsIHNhbWVTb3VyY2UgPSB0cnVlO1xuXG4gICAgaWYgKHRyYW5zYWN0aW9uLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IHRyYW5zYWN0aW9uLmxlbmd0aDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgICAgaWYgKHRyYW5zYWN0aW9uW2ldLnNvdXJjZSAhPSBzb3VyY2UpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ2NoYW5nZWRhdGE6IGNoYW5nZXMgZnJvbSBkaWZmZXJlbnQgc291cmNlcyBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbiwgc291cmNlczonLCB0cmFuc2FjdGlvbltpXS5zb3VyY2UubmFtZSwgc291cmNlLm5hbWUpO1xuICAgICAgICAgICAgICAgIHNhbWVTb3VyY2UgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzb3VyY2UgPSB0cmFuc2FjdGlvbltpXS5zb3VyY2U7XG4gICAgICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uO1xufVxuXG5cbmZ1bmN0aW9uIHByZXBhcmVUcmFuc2FjdGlvbih0cmFuc2FjdGlvbikge1xuICAgIHZhciB0b2RvID0gW11cbiAgICAgICAgLCBwYXRoc1RvU3BsaWNlID0gW11cbiAgICAgICAgLCBwYXRoc1RvQ2hhbmdlID0gW11cbiAgICAgICAgLCBoYWRTcGxpY2VcbiAgICAgICAgLCBleGl0TG9vcCA9IHt9O1xuXG5cbiAgICB0cnkgeyB0cmFuc2FjdGlvbi5mb3JFYWNoKGNoZWNrQ2hhbmdlKTsgfVxuICAgIGNhdGNoIChlKSB7IGlmIChlICE9IGV4aXRMb29wKSB0aHJvdyBlOyB9XG5cbiAgICByZXR1cm4gdG9kbztcblxuXG4gICAgZnVuY3Rpb24gY2hlY2tDaGFuZ2UoZGF0YSkge1xuICAgICAgICAoZGF0YS50eXBlID09ICdzcGxpY2UnID8gY2hlY2tTcGxpY2UgOiBjaGVja01ldGhvZCkoZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjaGVja1NwbGljZShkYXRhKSB7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChkYXRhLnBhdGgpO1xuICAgICAgICB2YXIgcGFyZW50UGF0aENoYW5nZWQgPSBwYXRoc1RvQ2hhbmdlLnNvbWUoZnVuY3Rpb24ocGFyZW50UGF0aCkge1xuICAgICAgICAgICAgaWYgKHBhcnNlZFBhdGgubGVuZ3RoIDwgcGFyZW50UGF0aC5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJlbnRQYXRoQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgICAgIHRvZG8ucHVzaChkYXRhKTtcblxuICAgICAgICBpZiAoISBjb25maWcuZGVidWcpIHRocm93IGV4aXRMb29wO1xuICAgICAgICBwYXRoc1RvU3BsaWNlLnB1c2gocGFyc2VkUGF0aCk7XG4gICAgICAgIGhhZFNwbGljZSA9IHRydWU7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBjaGVja01ldGhvZChkYXRhKSB7XG4gICAgICAgIHZhciBwYXJzZWRQYXRoID0gcGF0aFV0aWxzLnBhcnNlQWNjZXNzUGF0aChkYXRhLnBhdGgpO1xuICAgICAgICB2YXIgcGFyZW50UGF0aFNwbGljZWQgPSBwYXRoc1RvU3BsaWNlICYmIHBhdGhzVG9TcGxpY2Uuc29tZShmdW5jdGlvbihwYXJlbnRQYXRoKSB7XG4gICAgICAgICAgICBpZiAocGFyc2VkUGF0aC5sZW5ndGggPD0gcGFyZW50UGF0aC5sZW5ndGhcbiAgICAgICAgICAgICAgICB8fCBwYXJzZWRQYXRoW3BhcmVudFBhdGgubGVuZ3RoXS5zeW50YXggIT0gJ2FycmF5JykgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIF9wYXRoSXNQYXJlbnRPZihwYXJlbnRQYXRoLCBwYXJzZWRQYXRoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHBhcmVudFBhdGhTcGxpY2VkKSByZXR1cm47XG4gICAgICAgIGlmIChoYWRTcGxpY2UpIGxvZ2dlci5lcnJvcignY2hhbmdlZGF0YTogY2hpbGQgY2hhbmdlIGlzIGV4ZWN1dGVkIGFmdGVyIHNwbGljZTsgcHJvYmFibHkgZGF0YSBzb3VyY2UgZGlkIG5vdCBlbWl0IG1lc3NhZ2Ugd2l0aCBkYXRhLnR5cGU9PVwiZmluaXNoZWRcIicpO1xuXG4gICAgICAgIHZhciBwYXJlbnRQYXRoQ2hhbmdlZCA9IHBhdGhzVG9DaGFuZ2Uuc29tZShmdW5jdGlvbihwYXJlbnRQYXRoKSB7XG4gICAgICAgICAgICBpZiAocGFyc2VkUGF0aC5sZW5ndGggPD0gcGFyZW50UGF0aC5sZW5ndGgpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgcGFyc2VkUGF0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwYXJlbnRQYXRoQ2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgICAgIHBhdGhzVG9DaGFuZ2UucHVzaChwYXJzZWRQYXRoKTtcblxuICAgICAgICB0b2RvLnB1c2goZGF0YSk7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBfcGF0aElzUGFyZW50T2YocGFyZW50UGF0aCwgY2hpbGRQYXRoKSB7XG4gICAgICAgIHJldHVybiBwYXJlbnRQYXRoLmV2ZXJ5KGZ1bmN0aW9uKHBhdGhOb2RlLCBpbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhdGhOb2RlLnByb3BlcnR5ID09IGNoaWxkUGF0aFtpbmRleF0ucHJvcGVydHk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBwcm9jZXNzVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pIHtcbiAgICB0cmFuc2FjdGlvbi5mb3JFYWNoKHByb2Nlc3NDaGFuZ2UsIHRoaXMpO1xuICAgIHBvc3RUcmFuc2FjdGlvbkZpbmlzaGVkLmNhbGwodGhpcywgZmFsc2UpO1xuXG4gICAgZnVuY3Rpb24gcHJvY2Vzc0NoYW5nZShkYXRhKSB7XG4gICAgICAgIHZhciBtb2RlbFBhdGggPSB0aGlzLnBhdGgoZGF0YS5wYXRoLCBkYXRhLnR5cGUgIT0gJ3JlbW92ZWQnICYmIGRhdGEudHlwZSAhPSAnZGVsZXRlZCcpO1xuICAgICAgICBpZiAoISBtb2RlbFBhdGgpIHJldHVybjtcbiAgICAgICAgKGRhdGEudHlwZSA9PSAnc3BsaWNlJyA/IGV4ZWN1dGVTcGxpY2UgOiBleGVjdXRlTWV0aG9kKShtb2RlbFBhdGgsIGRhdGEpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBleGVjdXRlU3BsaWNlKG1vZGVsUGF0aCwgZGF0YSkge1xuICAgIHZhciBpbmRleCA9IGRhdGEuaW5kZXhcbiAgICAgICAgLCBob3dNYW55ID0gZGF0YS5yZW1vdmVkLmxlbmd0aFxuICAgICAgICAsIHNwbGljZUFyZ3MgPSBbaW5kZXgsIGhvd01hbnldO1xuXG4gICAgc3BsaWNlQXJncyA9IHNwbGljZUFyZ3MuY29uY2F0KGRhdGEubmV3VmFsdWUuc2xpY2UoaW5kZXgsIGluZGV4ICsgZGF0YS5hZGRlZENvdW50KSk7XG4gICAgc2V0VHJhbnNhY3Rpb25GbGFnKG1vZGVsUGF0aC5zcGxpY2UsIHRydWUpO1xuICAgIG1vZGVsUGF0aC5zcGxpY2UuYXBwbHkobW9kZWxQYXRoLCBzcGxpY2VBcmdzKTtcbn1cblxuXG5mdW5jdGlvbiBleGVjdXRlTWV0aG9kKG1vZGVsUGF0aCwgZGF0YSkge1xuICAgIHZhciBtZXRob2ROYW1lID0gQ0hBTkdFX1RZUEVfVE9fTUVUSE9EX01BUFtkYXRhLnR5cGVdO1xuICAgIGlmIChtZXRob2ROYW1lKSB7XG4gICAgICAgIHNldFRyYW5zYWN0aW9uRmxhZyhtb2RlbFBhdGhbbWV0aG9kTmFtZV0sIHRydWUpO1xuICAgICAgICBtb2RlbFBhdGhbbWV0aG9kTmFtZV0oZGF0YS5uZXdWYWx1ZSk7XG4gICAgfSBlbHNlXG4gICAgICAgIGxvZ2dlci5lcnJvcigndW5rbm93biBkYXRhIGNoYW5nZSB0eXBlJyk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNZXNzZW5nZXIgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXInKVxuICAgICwgcGF0aFV0aWxzID0gcmVxdWlyZSgnLi9wYXRoX3V0aWxzJylcbiAgICAsIF8gPSByZXF1aXJlKCdtb2wtcHJvdG8nKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vdXRpbC9sb2dnZXInKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbm5lY3RvcjtcblxuXG52YXIgbW9kZVBhdHRlcm4gPSAvXihcXDwqKVxcLSsoXFw+KikkLztcblxuXG4vKipcbiAqIENvbm5lY3RvclxuICogQ2xhc3MgdGhhdCBjcmVhdGVzIGNvbm5lY3RvciBvYmplY3QgZm9yIGRhdGEgY29ubmVjdGlvbiBiZXR3ZWVuXG4gKiB0d28gZGF0YS1zb3VyY2VzXG4gKiBEYXRhLXNvdXJjZXMgc2hvdWxkIGltcGxlbWVudCB0aGUgZm9sbG93aW5nIEFQSTpcbiAqIGdldCgpIC0gZ2V0IHZhbHVlIGZyb20gZGF0YXNvdXJjZSBvciBpdHMgcGF0aFxuICogc2V0KHZhbHVlKSAtIHNldCB2YWx1ZSB0byBkYXRhc291cmNlIG9yIHRvIGl0cyBwYXRoXG4gKiBvbihwYXRoLCBzdWJzY3JpYmVyKSAtIHN1YnNjcmlwdGlvbiB0byBkYXRhIGNoYW5nZXMgd2l0aCBcIipcIiBzdXBwb3J0XG4gKiBvZmYocGF0aCwgc3Vic2NyaWJlcilcbiAqIHBhdGgoYWNjZXNzUGF0aCkgLSB0byByZXR1cm4gdGhlIG9iamVjdCB0aGF0IGdpdmVzIHJlZmVyZW5jZSB0byBzb21lIHBhcnQgb2YgZGF0YXNvdXJjZVxuICogYW5kIGNvbXBsaWVzIHdpdGggdGhhdCBhcGkgdG9vLlxuICpcbiAqICMjIyNFdmVudHMjIyMjXG4gKlxuICogLSAndHVybmVkb24nIC0gY29ubmVjdG9yIHdhcyB0dXJuZWQgb25cbiAqIC0gJ3R1cm5lZG9mZicgLSBjb25uZWN0b3Igd2FzIHR1cm5lZCBvZmZcbiAqIC0gJ2NoYW5nZXN0YXJ0ZWQnIC0gY2hhbmdlIG9uIGNvbm5lY3RlZCBkYXRhc291cmNlIGlzIHN0YXJ0ZWRcbiAqIC0gJ2NoYW5nZWNvbXBsZXRlZCcgLSBjaGFuZ2Ugb24gY29ubmVjdGVkIGRhdGFzb3VyY2UgaXMgY29tcGxldGVkXG4gKiAtICdkZXN0cm95ZWQnIC0gY29ubmVjdG9yIHdhcyBkZXN0cm95ZWRcbiAqIFxuICogQHBhcmFtIHtPYmplY3R9IGRzMSB0aGUgZmlyc3QgZGF0YSBzb3VyY2UuXG4gKiBAcGFyYW0ge1N0cmluZ30gbW9kZSB0aGUgY29ubmVjdGlvbiBtb2RlIHRoYXQgZGVmaW5lcyB0aGUgZGlyZWN0aW9uIGFuZCB0aGUgZGVwdGggb2YgY29ubmVjdGlvbi4gUG9zc2libGUgdmFsdWVzIGFyZSAnLT4nLCAnPDwtJywgJzw8PC0+Pj4nLCBldGMuXG4gKiBAcGFyYW0ge09iamVjdH0gZHMyIHRoZSBzZWNvbmQgZGF0YSBzb3VyY2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiAqIEByZXR1cm4ge0Nvbm5lY3Rvcn0gd2hlbiBjYWxsZWQgd2l0aCBgbmV3YCwgY3JlYXRlcyBhIENvbm5lY3RvciBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIENvbm5lY3RvcihkczEsIG1vZGUsIGRzMiwgb3B0aW9ucykge1xuICAgIHNldHVwTW9kZS5jYWxsKHRoaXMsIG1vZGUpO1xuXG4gICAgXy5leHRlbmQodGhpcywge1xuICAgICAgICBkczE6IGRzMSxcbiAgICAgICAgZHMyOiBkczIsXG4gICAgICAgIGlzT246IGZhbHNlLFxuICAgICAgICBfY2hhbmdlc1F1ZXVlMTogW10sXG4gICAgICAgIF9jaGFuZ2VzUXVldWUyOiBbXSxcbiAgICAgICAgX21lc3NlbmdlcjogbmV3IE1lc3Nlbmdlcih0aGlzLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMpXG4gICAgfSk7XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgICAgIHZhciBwYXRoVHJhbnNsYXRpb24gPSBvcHRpb25zLnBhdGhUcmFuc2xhdGlvbjtcbiAgICAgICAgaWYgKHBhdGhUcmFuc2xhdGlvbikge1xuICAgICAgICAgICAgcGF0aFRyYW5zbGF0aW9uID0gXy5jbG9uZShwYXRoVHJhbnNsYXRpb24pO1xuICAgICAgICAgICAgdmFyIHBhdHRlcm5UcmFuc2xhdGlvbiA9IGdldFBhdHRlcm5UcmFuc2xhdGlvbnMocGF0aFRyYW5zbGF0aW9uKTtcbiAgICAgICAgICAgIF8uZXh0ZW5kKHRoaXMsIHtcbiAgICAgICAgICAgICAgICBwYXRoVHJhbnNsYXRpb24xOiByZXZlcnNlVHJhbnNsYXRpb25SdWxlcyhwYXRoVHJhbnNsYXRpb24pLFxuICAgICAgICAgICAgICAgIHBhdGhUcmFuc2xhdGlvbjI6IHBhdGhUcmFuc2xhdGlvbixcbiAgICAgICAgICAgICAgICBwYXR0ZXJuVHJhbnNsYXRpb24xOiByZXZlcnNlUGF0dGVyblRyYW5zbGF0aW9uUnVsZXMocGF0dGVyblRyYW5zbGF0aW9uKSxcbiAgICAgICAgICAgICAgICBwYXR0ZXJuVHJhbnNsYXRpb24yOiBwYXR0ZXJuVHJhbnNsYXRpb25cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRhdGFUcmFuc2xhdGlvbiA9IG9wdGlvbnMuZGF0YVRyYW5zbGF0aW9uO1xuICAgICAgICBpZiAoZGF0YVRyYW5zbGF0aW9uKSB7XG4gICAgICAgICAgICBfLmV4dGVuZCh0aGlzLCB7XG4gICAgICAgICAgICAgICAgZGF0YVRyYW5zbGF0aW9uMTogZGF0YVRyYW5zbGF0aW9uWyc8LSddLFxuICAgICAgICAgICAgICAgIGRhdGFUcmFuc2xhdGlvbjI6IGRhdGFUcmFuc2xhdGlvblsnLT4nXVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZGF0YVZhbGlkYXRpb24gPSBvcHRpb25zLmRhdGFWYWxpZGF0aW9uO1xuICAgICAgICBpZiAoZGF0YVZhbGlkYXRpb24pIHtcbiAgICAgICAgICAgIF8uZXh0ZW5kKHRoaXMsIHtcbiAgICAgICAgICAgICAgICBkYXRhVmFsaWRhdGlvbjE6IGRhdGFWYWxpZGF0aW9uWyc8LSddLFxuICAgICAgICAgICAgICAgIGRhdGFWYWxpZGF0aW9uMjogZGF0YVZhbGlkYXRpb25bJy0+J11cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy50dXJuT24oKTtcbn1cblxuXG5mdW5jdGlvbiBzZXR1cE1vZGUobW9kZSl7XG4gICAgdmFyIHBhcnNlZE1vZGUgPSBtb2RlLm1hdGNoKG1vZGVQYXR0ZXJuKTtcblxuICAgIGlmICghIHBhcnNlZE1vZGUpXG4gICAgICAgIG1vZGVQYXJzZUVycm9yKCk7XG5cbiAgICB2YXIgZGVwdGgxID0gcGFyc2VkTW9kZVsxXS5sZW5ndGhcbiAgICAgICAgLCBkZXB0aDIgPSBwYXJzZWRNb2RlWzJdLmxlbmd0aDtcblxuICAgIGlmIChkZXB0aDEgJiYgZGVwdGgyICYmIGRlcHRoMSAhPSBkZXB0aDIpXG4gICAgICAgIG1vZGVQYXJzZUVycm9yKCk7XG5cbiAgICBpZiAoISBkZXB0aDEgJiYgISBkZXB0aDIpXG4gICAgICAgIG1vZGVQYXJzZUVycm9yKCk7XG5cbiAgICBfLmV4dGVuZCh0aGlzLCB7XG4gICAgICAgIG1vZGU6IG1vZGUsXG4gICAgICAgIGRlcHRoMTogZGVwdGgxLFxuICAgICAgICBkZXB0aDI6IGRlcHRoMixcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIG1vZGVQYXJzZUVycm9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgQ29ubmVjdG9yIG1vZGU6ICcgKyBtb2RlKTtcbiAgICB9XG59XG5cblxuXy5leHRlbmRQcm90byhDb25uZWN0b3IsIHtcbiAgICB0dXJuT246IENvbm5lY3RvciR0dXJuT24sXG4gICAgdHVybk9mZjogQ29ubmVjdG9yJHR1cm5PZmYsXG4gICAgZGVzdHJveTogQ29ubmVjdG9yJGRlc3Ryb3ksXG4gICAgY2hhbmdlTW9kZTogQ29ubmVjdG9yJGNoYW5nZU1vZGUsXG4gICAgZGVmZXJDaGFuZ2VNb2RlOiBDb25uZWN0b3IkZGVmZXJDaGFuZ2VNb2RlXG59KTtcblxuLyoqXG4gKiBGdW5jdGlvbiBjaGFuZ2UgdGhlIG1vZGUgb2YgdGhlIGNvbm5lY3Rpb25cbiAqXG4gKiBAcGFyYW0gQHBhcmFtIHtTdHJpbmd9IG1vZGUgdGhlIGNvbm5lY3Rpb24gbW9kZSB0aGF0IGRlZmluZXMgdGhlIGRpcmVjdGlvbiBhbmQgdGhlIGRlcHRoIG9mIGNvbm5lY3Rpb24uIFBvc3NpYmxlIHZhbHVlcyBhcmUgJy0+JywgJzw8LScsICc8PDwtPj4+JywgZXRjLlxuICogQHJldHVybiB7T2JqZWN0W1N0cmluZ119XG4gKi9cbmZ1bmN0aW9uIENvbm5lY3RvciRjaGFuZ2VNb2RlKG1vZGUpIHtcbiAgICB0aGlzLnR1cm5PZmYoKTtcbiAgICBzZXR1cE1vZGUuY2FsbCh0aGlzLCBtb2RlKTtcbiAgICB0aGlzLnR1cm5PbigpO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogRnVuY3Rpb24gY2hhbmdlIHRoZSBtb2RlIG9mIHRoZSBjb25uZWN0aW9uXG4gKlxuICogQHBhcmFtIEBwYXJhbSB7U3RyaW5nfSBtb2RlIHRoZSBjb25uZWN0aW9uIG1vZGUgdGhhdCBkZWZpbmVzIHRoZSBkaXJlY3Rpb24gYW5kIHRoZSBkZXB0aCBvZiBjb25uZWN0aW9uLiBQb3NzaWJsZSB2YWx1ZXMgYXJlICctPicsICc8PC0nLCAnPDw8LT4+PicsIGV0Yy5cbiAqIEByZXR1cm4ge09iamVjdFtTdHJpbmddfVxuICovXG5mdW5jdGlvbiBDb25uZWN0b3IkZGVmZXJDaGFuZ2VNb2RlKG1vZGUpIHtcbiAgICBfLmRlZmVyTWV0aG9kKHRoaXMsICdjaGFuZ2VNb2RlJywgbW9kZSk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IHJldmVyc2VzIHRyYW5zbGF0aW9uIHJ1bGVzIGZvciBwYXRocyBvZiBjb25uZWN0ZWQgb2RhdGEgc291cmNlc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0W1N0cmluZ119IHJ1bGVzIG1hcCBvZiBwYXRocyBkZWZpbmluZyB0aGUgdHJhbnNsYXRpb24gcnVsZXNcbiAqIEByZXR1cm4ge09iamVjdFtTdHJpbmddfVxuICovXG5mdW5jdGlvbiByZXZlcnNlVHJhbnNsYXRpb25SdWxlcyhydWxlcykge1xuICAgIHZhciByZXZlcnNlUnVsZXMgPSB7fTtcbiAgICBfLmVhY2hLZXkocnVsZXMsIGZ1bmN0aW9uKHBhdGgyX3ZhbHVlLCBwYXRoMV9rZXkpIHtcbiAgICAgICAgcmV2ZXJzZVJ1bGVzW3BhdGgyX3ZhbHVlXSA9IHBhdGgxX2tleTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmV2ZXJzZVJ1bGVzO1xufVxuXG5cbmZ1bmN0aW9uIGdldFBhdHRlcm5UcmFuc2xhdGlvbnMocGF0aFRyYW5zbGF0aW9uKSB7XG4gICAgdmFyIHBhdHRlcm5UcmFuc2xhdGlvbiA9IFtdO1xuICAgIF8uZWFjaEtleShwYXRoVHJhbnNsYXRpb24sIGZ1bmN0aW9uKHBhdGgyX3ZhbHVlLCBwYXRoMV9rZXkpIHtcbiAgICAgICAgdmFyIHN0YXJJbmRleDEgPSBwYXRoMV9rZXkuaW5kZXhPZignKicpXG4gICAgICAgICAgICAsIHN0YXJJbmRleDIgPSBwYXRoMl92YWx1ZS5pbmRleE9mKCcqJyk7XG4gICAgICAgIGlmIChzdGFySW5kZXgxID49IDAgJiYgc3RhckluZGV4MiA+PSAwKSB7IC8vIHBhdHRlcm4gdHJhbnNsYXRpb25cbiAgICAgICAgICAgIGlmIChwYXRoMV9rZXkuc2xpY2Uoc3RhckluZGV4MSkgIT0gcGF0aDJfdmFsdWUuc2xpY2Uoc3RhckluZGV4MikpXG4gICAgICAgICAgICAgICAgX3Rocm93SW52YWxpZFRyYW5zbGF0aW9uKHBhdGgxX2tleSwgcGF0aDJfdmFsdWUpO1xuICAgICAgICAgICAgZGVsZXRlIHBhdGhUcmFuc2xhdGlvbltwYXRoMV9rZXldOyAgICAgICAgICAgIFxuXG4gICAgICAgICAgICBwYXR0ZXJuVHJhbnNsYXRpb24ucHVzaCh7XG4gICAgICAgICAgICAgICAgZnJvbVBhdHRlcm46IHBhdGhVdGlscy5jcmVhdGVSZWdleFBhdGgocGF0aDFfa2V5KSxcbiAgICAgICAgICAgICAgICBmcm9tU3RhdGljUGF0aDogX2dldFN0YXRpY1BhdGgocGF0aDFfa2V5LCBzdGFySW5kZXgxKSxcbiAgICAgICAgICAgICAgICB0b1BhdHRlcm46IHBhdGhVdGlscy5jcmVhdGVSZWdleFBhdGgocGF0aDJfdmFsdWUpLFxuICAgICAgICAgICAgICAgIHRvU3RhdGljUGF0aDogX2dldFN0YXRpY1BhdGgocGF0aDJfdmFsdWUsIHN0YXJJbmRleDIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGFySW5kZXgxID49IDAgfHwgc3RhckluZGV4MiA+PSAwKSAvLyBwYXR0ZXJuIG9ubHkgb24gb25lIHNpZGUgb2YgdHJhbnNsYXRpb25cbiAgICAgICAgICAgIF90aHJvd0ludmFsaWRUcmFuc2xhdGlvbihwYXRoMV9rZXksIHBhdGgyX3ZhbHVlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXR0ZXJuVHJhbnNsYXRpb247XG5cblxuICAgIGZ1bmN0aW9uIF90aHJvd0ludmFsaWRUcmFuc2xhdGlvbihwYXRoMSwgcGF0aDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBhdHRlcm4gdHJhbnNsYXRpb246ICcgKyBwYXRoMSArICcsICcgKyBwYXRoMik7XG4gICAgfVxuXG5cbiAgICBmdW5jdGlvbiBfZ2V0U3RhdGljUGF0aChwYXRoLCBzdGFySW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvW1xcLlxcW10/XFwqLiokLywgJycpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiByZXZlcnNlUGF0dGVyblRyYW5zbGF0aW9uUnVsZXMocGF0dGVyblRyYW5zbGF0aW9uKSB7XG4gICAgcmV0dXJuIHBhdHRlcm5UcmFuc2xhdGlvbi5tYXAoZnVuY3Rpb24ocHQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZyb21QYXR0ZXJuOiBwdC50b1BhdHRlcm4sXG4gICAgICAgICAgICBmcm9tU3RhdGljUGF0aDogcHQudG9TdGF0aWNQYXRoLFxuICAgICAgICAgICAgdG9QYXR0ZXJuOiBwdC5mcm9tUGF0dGVybixcbiAgICAgICAgICAgIHRvU3RhdGljUGF0aDogcHQuZnJvbVN0YXRpY1BhdGhcbiAgICAgICAgfTtcbiAgICB9KTtcbn1cblxuXG4vKipcbiAqIHR1cm5PblxuICogTWV0aG9kIG9mIENvbm5lY3RvciB0aGF0IGVuYWJsZXMgY29ubmVjdGlvbiAoaWYgaXQgd2FzIHByZXZpb3VzbHkgZGlzYWJsZWQpXG4gKi9cbmZ1bmN0aW9uIENvbm5lY3RvciR0dXJuT24oKSB7XG4gICAgaWYgKHRoaXMuaXNPbilcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdkYXRhIHNvdXJjZXMgYXJlIGFscmVhZHkgY29ubmVjdGVkJyk7XG5cbiAgICB2YXIgc3Vic2NyaXB0aW9uUGF0aCA9IHRoaXMuX3N1YnNjcmlwdGlvblBhdGggPVxuICAgICAgICBuZXcgQXJyYXkodGhpcy5kZXB0aDEgfHwgdGhpcy5kZXB0aDIpLmpvaW4oJyonKTtcblxuICAgIHZhciBzdWJzY3JpcHRpb25QYXR0ZXJuID0gcGF0aFV0aWxzLmNyZWF0ZVJlZ2V4UGF0aChzdWJzY3JpcHRpb25QYXRoKTtcblxuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBpZiAodGhpcy5kZXB0aDEpXG4gICAgICAgIHRoaXMuX2xpbmsxID0gbGlua0RhdGFTb3VyY2UoJ19saW5rMicsIHRoaXMuZHMyLCB0aGlzLmRzMSwgdGhpcy5fY2hhbmdlc1F1ZXVlMSwgdGhpcy5wYXRoVHJhbnNsYXRpb24xLCB0aGlzLnBhdHRlcm5UcmFuc2xhdGlvbjEsIHRoaXMuZGF0YVRyYW5zbGF0aW9uMSwgdGhpcy5kYXRhVmFsaWRhdGlvbjEpO1xuICAgIGlmICh0aGlzLmRlcHRoMilcbiAgICAgICAgdGhpcy5fbGluazIgPSBsaW5rRGF0YVNvdXJjZSgnX2xpbmsxJywgdGhpcy5kczEsIHRoaXMuZHMyLCB0aGlzLl9jaGFuZ2VzUXVldWUyLCB0aGlzLnBhdGhUcmFuc2xhdGlvbjIsIHRoaXMucGF0dGVyblRyYW5zbGF0aW9uMiwgdGhpcy5kYXRhVHJhbnNsYXRpb24yLCB0aGlzLmRhdGFWYWxpZGF0aW9uMik7XG5cbiAgICB0aGlzLmlzT24gPSB0cnVlO1xuICAgIHRoaXMucG9zdE1lc3NhZ2UoJ3R1cm5lZG9uJyk7XG5cblxuICAgIGZ1bmN0aW9uIGxpbmtEYXRhU291cmNlKHJldmVyc2VMaW5rLCBmcm9tRFMsIHRvRFMsIGNoYW5nZXNRdWV1ZSwgcGF0aFRyYW5zbGF0aW9uLCBwYXR0ZXJuVHJhbnNsYXRpb24sIGRhdGFUcmFuc2xhdGlvbiwgZGF0YVZhbGlkYXRpb24pIHtcbiAgICAgICAgZnJvbURTLm9uU3luYygnZGF0YWNoYW5nZXMnLCBvbkRhdGEpO1xuICAgICAgICByZXR1cm4gb25EYXRhO1xuXG4gICAgICAgIGZ1bmN0aW9uIG9uRGF0YShtZXNzYWdlLCBiYXRjaCkge1xuICAgICAgICAgICAgdmFyIHNlbmREYXRhID0ge1xuICAgICAgICAgICAgICAgIGNoYW5nZXM6IFtdLFxuICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uOiBiYXRjaC50cmFuc2FjdGlvblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBiYXRjaC5jaGFuZ2VzLmZvckVhY2goZnVuY3Rpb24oY2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNvdXJjZVBhdGggPSBjaGFuZ2UucGF0aFxuICAgICAgICAgICAgICAgICAgICAsIHRhcmdldFBhdGggPSB0cmFuc2xhdGVQYXRoKHNvdXJjZVBhdGgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRQYXRoID09ICd1bmRlZmluZWQnKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICB2YXIgY2hhbmdlID0gXy5jbG9uZShjaGFuZ2UpO1xuICAgICAgICAgICAgICAgIF8uZXh0ZW5kKGNoYW5nZSwge1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IGZyb21EUyxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogdGFyZ2V0UGF0aFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlRGF0YShzb3VyY2VQYXRoLCBjaGFuZ2UpO1xuICAgICAgICAgICAgICAgIHZhbGlkYXRlRGF0YShzb3VyY2VQYXRoLCBjaGFuZ2UpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICghIGNoYW5nZXNRdWV1ZS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgXy5kZWZlcihwb3N0Q2hhbmdlRGF0YSk7XG5cbiAgICAgICAgICAgIGNoYW5nZXNRdWV1ZS5wdXNoKHNlbmREYXRhKTtcblxuXG4gICAgICAgICAgICBmdW5jdGlvbiB0cmFuc2xhdGVQYXRoKHNvdXJjZVBhdGgpIHtcbiAgICAgICAgICAgICAgICBpZiAocGF0aFRyYW5zbGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGVkUGF0aCA9IHBhdGhUcmFuc2xhdGlvbltzb3VyY2VQYXRoXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyYW5zbGF0ZWRQYXRoKSByZXR1cm4gdHJhbnNsYXRlZFBhdGg7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcGF0dGVyblRyYW5zbGF0aW9uLmxlbmd0aCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcHQgPSBfLmZpbmQocGF0dGVyblRyYW5zbGF0aW9uLCBmdW5jdGlvbihwVHJhbnNsYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwVHJhbnNsYXRpb24uZnJvbVBhdHRlcm4udGVzdChzb3VyY2VQYXRoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcHQpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zbGF0ZWRQYXRoID0gc291cmNlUGF0aC5yZXBsYWNlKHB0LmZyb21TdGF0aWNQYXRoLCBwdC50b1N0YXRpY1BhdGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISAoKHN1YnNjcmlwdGlvblBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHN1YnNjcmlwdGlvblBhdHRlcm4udGVzdChzb3VyY2VQYXRoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHN1YnNjcmlwdGlvblBhdHRlcm4gPT0gc291cmNlUGF0aCkpIHJldHVybjtcblxuICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2xhdGVkUGF0aCB8fCBzb3VyY2VQYXRoO1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHRyYW5zbGF0ZURhdGEoc291cmNlUGF0aCwgY2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGFUcmFuc2xhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNsYXRlID0gZGF0YVRyYW5zbGF0aW9uW3NvdXJjZVBhdGhdO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJhbnNsYXRlICYmIHR5cGVvZiB0cmFuc2xhdGUgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlLm9sZFZhbHVlID0gdHJhbnNsYXRlKGNoYW5nZS5vbGRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2UubmV3VmFsdWUgPSB0cmFuc2xhdGUoY2hhbmdlLm5ld1ZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgIFxuICAgICAgICAgICAgZnVuY3Rpb24gdmFsaWRhdGVEYXRhKHNvdXJjZVBhdGgsIGNoYW5nZSkge1xuICAgICAgICAgICAgICAgIHByb3BhZ2F0ZURhdGEoY2hhbmdlKTtcblxuICAgICAgICAgICAgICAgIGlmIChkYXRhVmFsaWRhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdG9ycyA9IGRhdGFWYWxpZGF0aW9uW3NvdXJjZVBhdGhdXG4gICAgICAgICAgICAgICAgICAgICAgICAsIHBhc3NlZENvdW50ID0gMFxuICAgICAgICAgICAgICAgICAgICAgICAgLCBhbHJlYWR5RmFpbGVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbGlkYXRvcnMpXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0b3JzLmZvckVhY2goY2FsbFZhbGlkYXRvcik7ICAgXG4gICAgICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjYWxsVmFsaWRhdG9yKHZhbGlkYXRvcikge1xuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0b3IoY2hhbmdlLm5ld1ZhbHVlLCBmdW5jdGlvbihlcnIsIHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5wYXRoID0gc291cmNlUGF0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIGFscmVhZHlGYWlsZWQgJiYgKGVyciB8fCByZXNwb25zZS52YWxpZCkgJiYgKytwYXNzZWRDb3VudCA9PSB2YWxpZGF0b3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21EUy5wb3N0TWVzc2FnZSgndmFsaWRhdGVkJywgcmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIHJlc3BvbnNlLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxyZWFkeUZhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbURTLnBvc3RNZXNzYWdlKCd2YWxpZGF0ZWQnLCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICBmdW5jdGlvbiBwcm9wYWdhdGVEYXRhKGNoYW5nZSkge1xuICAgICAgICAgICAgICAgIHNlbmREYXRhLmNoYW5nZXMucHVzaChjaGFuZ2UpO1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHBvc3RDaGFuZ2VEYXRhKCkge1xuICAgICAgICAgICAgICAgIC8vIHByZXZlbnQgZW5kbGVzcyBsb29wIG9mIHVwZGF0ZXMgZm9yIDItd2F5IGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICBpZiAoc2VsZltyZXZlcnNlTGlua10pIHZhciBjYWxsYmFjayA9IHN1YnNjcmlwdGlvblN3aXRjaDtcblxuICAgICAgICAgICAgICAgIHZhciB0cmFuc2FjdGlvbnMgPSBtZXJnZVRyYW5zYWN0aW9ucyhjaGFuZ2VzUXVldWUpO1xuICAgICAgICAgICAgICAgIGNoYW5nZXNRdWV1ZS5sZW5ndGggPSAwO1xuICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKHRyYW5zYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNlbmQgZGF0YSBjaGFuZ2UgaW5zdHJ1Y3Rpb24gYXMgbWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICB0b0RTLnBvc3RNZXNzYWdlU3luYygnY2hhbmdlZGF0YScsIHsgY2hhbmdlczogdHJhbnNhY3Rpb24gfSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHN1YnNjcmlwdGlvblN3aXRjaChlcnIsIGNoYW5nZUZpbmlzaGVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHZhciBvbk9mZiA9IGNoYW5nZUZpbmlzaGVkID8gJ29uU3luYycgOiAnb2ZmJztcbiAgICAgICAgICAgICAgICB0b0RTW29uT2ZmXSgnZGF0YWNoYW5nZXMnLCBzZWxmW3JldmVyc2VMaW5rXSk7XG5cbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZSA9IGNoYW5nZUZpbmlzaGVkID8gJ2NoYW5nZWNvbXBsZXRlZCcgOiAnY2hhbmdlc3RhcnRlZCc7XG4gICAgICAgICAgICAgICAgc2VsZi5wb3N0TWVzc2FnZShtZXNzYWdlLCB7IHNvdXJjZTogZnJvbURTLCB0YXJnZXQ6IHRvRFMgfSk7XG4gICAgICAgICAgICB9XG5cblxuICAgICAgICAgICAgZnVuY3Rpb24gbWVyZ2VUcmFuc2FjdGlvbnMoYmF0Y2hlcykge1xuICAgICAgICAgICAgICAgIHZhciB0cmFuc2FjdGlvbnMgPSBbXVxuICAgICAgICAgICAgICAgICAgICAsIGN1cnJlbnRUcmFuc2FjdGlvbjtcblxuICAgICAgICAgICAgICAgIGJhdGNoZXMuZm9yRWFjaChmdW5jdGlvbihiYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBiYXRjaC50cmFuc2FjdGlvbikgY3VycmVudFRyYW5zYWN0aW9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICBpZiAoISBiYXRjaC5jaGFuZ2VzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChiYXRjaC50cmFuc2FjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRUcmFuc2FjdGlvbilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmFwcGVuZEFycmF5KGN1cnJlbnRUcmFuc2FjdGlvbiwgYmF0Y2guY2hhbmdlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VHJhbnNhY3Rpb24gPSBfLmNsb25lKGJhdGNoLmNoYW5nZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9ucy5wdXNoKGN1cnJlbnRUcmFuc2FjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25zLnB1c2goYmF0Y2guY2hhbmdlcyk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb25zO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5cbi8qKlxuICogdHVybk9mZlxuICogTWV0aG9kIG9mIENvbm5lY3RvciB0aGF0IGRpc2FibGVzIGNvbm5lY3Rpb24gKGlmIGl0IHdhcyBwcmV2aW91c2x5IGVuYWJsZWQpXG4gKi9cbmZ1bmN0aW9uIENvbm5lY3RvciR0dXJuT2ZmKCkge1xuICAgIGlmICghIHRoaXMuaXNPbilcbiAgICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdkYXRhIHNvdXJjZXMgYXJlIGFscmVhZHkgZGlzY29ubmVjdGVkJyk7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdW5saW5rRGF0YVNvdXJjZSh0aGlzLmRzMSwgJ19saW5rMicsIHRoaXMucGF0aFRyYW5zbGF0aW9uMik7XG4gICAgdW5saW5rRGF0YVNvdXJjZSh0aGlzLmRzMiwgJ19saW5rMScsIHRoaXMucGF0aFRyYW5zbGF0aW9uMSk7XG5cbiAgICB0aGlzLmlzT24gPSBmYWxzZTtcbiAgICB0aGlzLnBvc3RNZXNzYWdlKCd0dXJuZWRvZmYnKTtcblxuXG4gICAgZnVuY3Rpb24gdW5saW5rRGF0YVNvdXJjZShmcm9tRFMsIGxpbmtOYW1lLCBwYXRoVHJhbnNsYXRpb24pIHtcbiAgICAgICAgaWYgKHNlbGZbbGlua05hbWVdKSB7XG4gICAgICAgICAgICBmcm9tRFMub2ZmKCdkYXRhY2hhbmdlcycsIHNlbGZbbGlua05hbWVdKTtcbiAgICAgICAgICAgIGRlbGV0ZSBzZWxmW2xpbmtOYW1lXTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuXG4vKipcbiAqIERlc3Ryb3lzIGNvbm5lY3RvciBvYmplY3QgYnkgdHVybmluZyBpdCBvZmYgYW5kIHJlbW92aW5nIHJlZmVyZW5jZXMgdG8gY29ubmVjdGVkIHNvdXJjZXNcbiAqL1xuZnVuY3Rpb24gQ29ubmVjdG9yJGRlc3Ryb3koKSB7XG4gICAgdGhpcy50dXJuT2ZmKCk7XG4gICAgdGhpcy5wb3N0TWVzc2FnZSgnZGVzdHJveWVkJyk7XG4gICAgdGhpcy5fbWVzc2VuZ2VyLmRlc3Ryb3koKTtcbiAgICBkZWxldGUgdGhpcy5kczE7XG4gICAgZGVsZXRlIHRoaXMuZHMyO1xuICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBNb2RlbFBhdGggPSByZXF1aXJlKCcuL21fcGF0aCcpXG4gICAgLCBzeW50aGVzaXplID0gcmVxdWlyZSgnLi9zeW50aGVzaXplJylcbiAgICAsIHBhdGhVdGlscyA9IHJlcXVpcmUoJy4vcGF0aF91dGlscycpXG4gICAgLCBjaGFuZ2VEYXRhSGFuZGxlciA9IHJlcXVpcmUoJy4vY2hhbmdlX2RhdGEnKVxuICAgICwgTWVzc2VuZ2VyID0gcmVxdWlyZSgnLi4vbWVzc2VuZ2VyJylcbiAgICAsIE1lc3Nlbmdlck1lc3NhZ2VTb3VyY2UgPSByZXF1aXJlKCcuLi9tZXNzZW5nZXIvbXNuZ3Jfc291cmNlJylcbiAgICAsIE1vZGVsTXNnQVBJID0gcmVxdWlyZSgnLi9tX21zZ19hcGknKVxuICAgICwgTWl4aW4gPSByZXF1aXJlKCcuLi9hYnN0cmFjdC9taXhpbicpXG4gICAgLCBfID0gcmVxdWlyZSgnbW9sLXByb3RvJylcbiAgICAsIGNoZWNrID0gcmVxdWlyZSgnLi4vdXRpbC9jaGVjaycpXG4gICAgLCBNYXRjaCA9IGNoZWNrLk1hdGNoXG4gICAgLCBsb2dnZXIgPSByZXF1aXJlKCcuLi91dGlsL2xvZ2dlcicpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTW9kZWw7XG5cblxuLyoqXG4gKiBgbWlsby5Nb2RlbGBcbiAqIE1vZGVsIGNsYXNzIGluc3RhbnRpYXRlcyBvYmplY3RzIHRoYXQgYWxsb3cgZGVlcCBkYXRhIGFjY2VzcyB3aXRoIF9fc2FmZSBnZXR0ZXJzX18gdGhhdCByZXR1cm4gdW5kZWZpbmVkIChyYXRoZXIgdGhhbiB0aHJvd2luZyBleGNlcHRpb24pIHdoZW4gcHJvcGVydGllcy9pdGVtcyBvZiB1bmV4aXN0aW5nIG9iamVjdHMvYXJyYXlzIGFyZSByZXF1ZXN0ZWQgYW5kIF9fc2FmZSBzZXR0ZXJzX18gdGhhdCBjcmVhdGUgb2JqZWN0IHRyZWVzIHdoZW4gcHJvcGVydGllcy9pdGVtcyBvZiB1bmV4aXN0aW5nIG9iamVjdHMvYXJyYXlzIGFyZSBzZXQgYW5kIGFsc28gcG9zdCBtZXNzYWdlcyB0byBhbGxvdyBzdWJzY3JpcHRpb24gb24gY2hhbmdlcyBhbmQgZW5hYmxlIGRhdGEgcmVhY3Rpdml0eS5cbiAqIFJlYWN0aXZpdHkgaXMgaW1wbGVtZW1udGVkIHZpYSBbQ29ubmVjdG9yXSguL2Nvbm5lY3Rvci5qcy5odG1sKSB0aGF0IGNhbiBiZSBpbnN0YW50aWF0ZWQgZWl0aGVyIGRpcmVjdGx5IG9yIHdpdGggbW9yZSBjb252ZW5pZW50IGludGVyZmFjZSBvZiBbbWlsby5taW5kZXJdKC4uL21pbmRlci5qcy5odG1sKS4gQXQgdGhlIG1vbWVudCBtb2RlbCBjYW4gYmUgY29ubmVjdGVkIHRvIFtEYXRhIGZhY2V0XSguLi9jb21wb25lbnRzL2NfZmFjZXRzL0RhdGEuanMuaHRtbCkgb3IgdG8gYW5vdGhlciBtb2RlbCBvciBbTW9kZWxQYXRoXSguL21fcGF0aC5qcy5odG1sKS5cbiAqIE1vZGVsIGNvbnN0cnVjdG9yIHJldHVybnMgb2JqZWN0cyB0aGF0IGFyZSBmdW5jdGlvbnMgYXQgdGhlIHNhbWUgdGltZTsgd2hlbiBjYWxsZWQgdGhleSByZXR1cm4gTW9kZWxQYXRoIG9iamVjdHMgdGhhdCBhbGxvdyBnZXQvc2V0IGFjY2VzcyB0byBhbnkgcG9pbnQgaW4gbW9kZWwgZGF0YS4gU2VlIFtNb2RlbERhdGFdKCNNb2RlbERhdGEpIGJlbG93LlxuICpcbiAqIFlvdSBjYW4gc3Vic2NyaWJlIHRvIG1vZGVsIGNoYW5nZXMgd2l0aCBgb25gIG1ldGhvZCBieSBwYXNzaW5nIG1vZGVsIGFjY2VzcyBwYXRoIGluIHBsYWNlIG9mIG1lc3NhZ2UsIHBhdHRlcm4gb3Igc3RyaW5nIHdpdGggYW55IG51bWJlciBvZiBzdGFycyB0byBzdWJzY3JpYmUgdG8gYSBjZXJ0YWluIGRlcHRoIGluIG1vZGVsIChlLmcuLCBgJyoqKidgIHRvIHN1YnNjcmliZSB0byB0aHJlZSBsZXZlbHMpLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IGRhdGEgb3B0aW9uYWwgaW5pdGlhbCBhcnJheSBkYXRhLiBJZiBpdCBpcyBwbGFubmVkIHRvIGNvbm5lY3QgbW9kZWwgdG8gdmlldyBpdCBpcyB1c3VhbGx5IGJldHRlciB0byBpbnN0YW50aWF0ZSBhbiBlbXB0eSBNb2RlbCAoYHZhciBtID0gbmV3IE1vZGVsYCksIGNvbm5lY3QgaXQgdG8gW0NvbXBvbmVudF0oLi4vY29tcG9uZW50cy9jX2NsYXNzLmpzLmh0bWwpJ3MgW0RhdGEgZmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldHMvRGF0YS5qcy5odG1sKSAoZS5nLiwgYG1pbG8ubWluZGVyKG0sICc8PC0+PicsIGMuZGF0YSk7YCkgYW5kIHRoZW4gc2V0IHRoZSBtb2RlbCB3aXRoIGBtLnNldChkYXRhKWAgLSB0aGUgdmlldyB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXBkYXRlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBob3N0T2JqZWN0IG9wdGlvbmFsIG9iamVjdCB0aGF0IGhvc3RzIG1vZGVsIG9uIG9uZSBvZiBpdHMgcHJvcGVydGllcy4gQ2FuIGJlIHVzZWQgd2hlbiBtb2RlbCBpdHNlbGYgaXMgdGhlIGNvbnRleHQgb2YgdGhlIG1lc3NhZ2Ugc3Vic2NyaWJlciBhbmQgeW91IG5lZWQgdG8gdHJhdmVycyB0byB0aGlzIG9iamVjdCAoYWx0aG91Z2ggaXQgaXMgcG9zc2libGUgdG8gc2V0IGFueSBjb250ZXh0KS4gQ2FuIGFsc28gYmUgdXNlZCB0byBwcm94eSBtb2RlbCdzIG1ldGhvZHMgdG8gdGhlIGhvc3QgbGlrZSBbTW9kZWwgZmFjZXRdKC4uL2NvbXBvbmVudHMvY19mYWNldHMvTW9kZWxGYWNldC5qcy5odG1sKSBpcyBkb2luZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIHBhc3MgeyByZWFjdGl2ZTogZmFsc2UgfSB0byB1c2UgbW9kZWwgd2l0aG91dCBtZXNzYWdpbmcgd2hlbiBpdCBpcyBub3QgbmVlZGVkIC0gaXQgbWFrZXMgaXQgbXVjaCBmYXN0ZXJcbiAqIEByZXR1cm4ge01vZGVsfVxuICovXG5mdW5jdGlvbiBNb2RlbChkYXRhLCBob3N0T2JqZWN0LCBvcHRpb25zKSB7XG4gICAgLy8gYG1vZGVsYCB3aWxsIGJlIHJldHVybmVkIGJ5IGNvbnN0cnVjdG9yIGluc3RlYWQgb2YgYHRoaXNgLiBgbW9kZWxgXG4gICAgLy8gKGBtb2RlbFBhdGhgIGZ1bmN0aW9uKSBzaG91bGQgcmV0dXJuIGEgTW9kZWxQYXRoIG9iamVjdCB3aXRoIFwic3ludGhlc2l6ZWRcIiBtZXRob2RzXG4gICAgLy8gdG8gZ2V0L3NldCBtb2RlbCBwcm9wZXJ0aWVzLCB0byBzdWJzY3JpYmUgdG8gcHJvcGVydHkgY2hhbmdlcywgZXRjLlxuICAgIC8vIEFkZGl0aW9uYWwgYXJndW1lbnRzIG9mIG1vZGVsUGF0aCBjYW4gYmUgdXNlZCBpbiB0aGUgcGF0aCB1c2luZyBpbnRlcnBvbGF0aW9uIC0gc2VlIE1vZGVsUGF0aCBiZWxvdy5cbiAgICB2YXIgbW9kZWwgPSBmdW5jdGlvbiBtb2RlbFBhdGgoYWNjZXNzUGF0aCkgeyAvLyAsIC4uLiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGludGVycG9sYXRlZFxuICAgICAgICByZXR1cm4gTW9kZWwkcGF0aC5hcHBseShtb2RlbCwgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIG1vZGVsLl9fcHJvdG9fXyA9IE1vZGVsLnByb3RvdHlwZTtcblxuICAgIG1vZGVsLl9ob3N0T2JqZWN0ID0gaG9zdE9iamVjdDtcbiAgICBtb2RlbC5fb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBpZiAobW9kZWwuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XG4gICAgICAgIG1vZGVsLl9wcmVwYXJlTWVzc2VuZ2VycygpO1xuICAgICAgICAvLyBzdWJzY3JpYmUgdG8gXCJjaGFuZ2VkYXRhXCIgbWVzc2FnZSB0byBlbmFibGUgcmVhY3RpdmUgY29ubmVjdGlvbnNcbiAgICAgICAgbW9kZWwub25TeW5jKCdjaGFuZ2VkYXRhJywgY2hhbmdlRGF0YUhhbmRsZXIpO1xuICAgIH1cblxuICAgIGlmIChkYXRhKSBtb2RlbC5fZGF0YSA9IGRhdGE7XG5cbiAgICByZXR1cm4gbW9kZWw7XG59XG5cbk1vZGVsLnByb3RvdHlwZS5fX3Byb3RvX18gPSBNb2RlbC5fX3Byb3RvX187XG5cblxuLyoqXG4gKiAjIyMjTW9kZWwgaW5zdGFuY2UgbWV0aG9kcyMjIyNcbiAqXG4gKiAtIFtwYXRoXSgjcGF0aCkgLSByZXR1cm5zIE1vZGVsUGF0aCBvYmplY3QgdGhhdCBhbGxvd3MgYWNjZXNzIHRvIGFueSBwb2ludCBpbiBNb2RlbFxuICogLSBbZ2V0XSgjTW9kZWwkZ2V0KSAtIGdldCBtb2RlbCBkYXRhXG4gKiAtIHNldCAtIHNldCBtb2RlbCBkYXRhLCBzeW50aGVzaXplZFxuICogLSBzcGxpY2UgLSBzcGxpY2UgbW9kZWwgZGF0YSAoYXMgYXJyYXkgb3IgcHNldWRvLWFycmF5KSwgc3ludGhlc2l6ZWRcbiAqIC0gW2xlbl0oLi9tX3BhdGguanMuaHRtbCNNb2RlbFBhdGgkbGVuKSAtIHJldHVybnMgbGVuZ3RoIG9mIGFycmF5IChvciBwc2V1ZG8tYXJyYXkpIGluIG1vZGVsIGluIHNhZmUgd2F5LCAwIGlmIG5vIGxlbmd0aCBpcyBzZXRcbiAqIC0gW3B1c2hdKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJHB1c2gpIC0gYWRkIGl0ZW1zIHRvIHRoZSBlbmQgb2YgYXJyYXkgKG9yIHBzZXVkby1hcnJheSkgaW4gbW9kZWxcbiAqIC0gW3BvcF0oLi9tX3BhdGguanMuaHRtbCNNb2RlbFBhdGgkcG9wKSAtIHJlbW92ZSBpdGVtIGZyb20gdGhlIGVuZCBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbFxuICogLSBbdW5zaGlmdF0oLi9tX3BhdGguanMuaHRtbCNNb2RlbFBhdGgkdW5zaGlmdCkgLSBhZGQgaXRlbXMgdG8gdGhlIGJlZ2lubmluZyBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbFxuICogLSBbc2hpZnRdKC4vbV9wYXRoLmpzLmh0bWwjTW9kZWxQYXRoJHNoaWZ0KSAtIHJlbW92ZSBpdGVtIGZyb20gdGhlIGJlZ2lubmluZyBvZiBhcnJheSAob3IgcHNldWRvLWFycmF5KSBpbiBtb2RlbFxuICogLSBbcHJveHlNZXNzZW5nZXJdKCNwcm94eU1lc3NlbmdlcikgLSBwcm94eSBtb2RlbCdzIE1lc3NlbmdlciBtZXRob2RzIHRvIGhvc3Qgb2JqZWN0XG4gKiAtIFtwcm94eU1ldGhvZHNdKCNwcm94eU1ldGhvZHMpIC0gcHJveHkgbW9kZWwgbWV0aG9kcyB0byBob3N0IG9iamVjdFxuICovXG5fLmV4dGVuZFByb3RvKE1vZGVsLCB7XG4gICAgcGF0aDogTW9kZWwkcGF0aCxcbiAgICBnZXQ6IE1vZGVsJGdldCxcbiAgICBwcm94eU1lc3NlbmdlcjogcHJveHlNZXNzZW5nZXIsIC8vIGRlcHJlY2F0ZWQsIHNob3VsZCBub3QgYmUgdXNlZFxuICAgIHByb3h5TWV0aG9kczogcHJveHlNZXRob2RzLFxuICAgIF9wcmVwYXJlTWVzc2VuZ2VyczogX3ByZXBhcmVNZXNzZW5nZXJzLFxuICAgIF9nZXRIb3N0T2JqZWN0OiBfZ2V0SG9zdE9iamVjdCxcbiAgICBkZXN0cm95OiBNb2RlbCRkZXN0cm95XG59KTtcblxuLy8gc2V0LCBkZWwsIHNwbGljZSBhcmUgYWRkZWQgdG8gbW9kZWxcbl8uZXh0ZW5kUHJvdG8oTW9kZWwsIHN5bnRoZXNpemUubW9kZWxNZXRob2RzKTtcblxuXG4vKipcbiAqIC0gUGF0aDogTW9kZWxQYXRoIGNsYXNzIGFzIGBtaWxvLk1vZGVsLlBhdGhgXG4gKi9cbl8uZXh0ZW5kKE1vZGVsLCB7XG4gICAgUGF0aDogTW9kZWxQYXRoLFxuICAgIHVzZVdpdGg6IE1vZGVsJCR1c2VXaXRoXG59KTtcblxuXG4vKipcbiAqIEV4cG9zZSBNZXNzZW5nZXIgbWV0aG9kcyBvbiBGYWNldCBwcm90b3R5cGVcbiAqL1xudmFyIE1FU1NFTkdFUl9QUk9QRVJUWSA9ICdfbWVzc2VuZ2VyJztcbk1lc3Nlbmdlci51c2VXaXRoKE1vZGVsLCBNRVNTRU5HRVJfUFJPUEVSVFksIE1lc3Nlbmdlci5kZWZhdWx0TWV0aG9kcyk7XG5cblxuLyoqXG4gKiBNb2RlbFBhdGggbWV0aG9kcyBhZGRlZCB0byBNb2RlbCBwcm90b3R5cGVcbiAqL1xuWydsZW4nLCAncHVzaCcsICdwb3AnLCAndW5zaGlmdCcsICdzaGlmdCddLmZvckVhY2goZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgIHZhciBtZXRob2QgPSBNb2RlbFBhdGgucHJvdG90eXBlW21ldGhvZE5hbWVdO1xuICAgIF8uZGVmaW5lUHJvcGVydHkoTW9kZWwucHJvdG90eXBlLCBtZXRob2ROYW1lLCBtZXRob2QpO1xufSk7XG5cblxuLyoqXG4gKiBNb2RlbCBpbnN0YW5jZSBtZXRob2QuXG4gKiBHZXQgbW9kZWwgZGF0YS5cbiAqXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIE1vZGVsJGdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGF0YTtcbn1cblxuXG4vKipcbiAqIE1vZGVsIGluc3RhbmNlIG1ldGhvZC5cbiAqIFJldHVybnMgTW9kZWxQYXRoIG9iamVjdCB0aGF0IGltcGxlbWVudHMgdGhlIHNhbWUgQVBJIGFzIG1vZGVsIGJ1dCBhbGxvd3MgYWNjZXNzIHRvIGFueSBwb2ludCBpbnNpZGUgbW9kZWwgYXMgZGVmaW5lZCBieSBgYWNjZXNzUGF0aGAuXG4gKiBTZWUgW01vZGVsUGF0aF0oLi9tX3BhdGguanMuaHRtbCkgY2xhc3MgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2Vzc1BhdGggc3RyaW5nIHRoYXQgZGVmaW5lcyBwYXRoIHRvIGFjY2VzcyBtb2RlbC5cbiAqICBQYXRoIHN0cmluZyBjb25zaXN0cyBvZiBwYXJ0cyB0byBkZWZpbmUgZWl0aGVyIHByb3BlcnR5IGFjY2VzcyAoYFwiLm5hbWVcImAgdG8gYWNjZXNzIHByb3BlcnR5IG5hbWUpIG9yIGFycmF5IGl0ZW0gYWNjZXNzIChgXCJbMV1cImAgdG8gYWNjZXNzIGl0ZW0gd2l0aCBpbmRleCAxKS5cbiAqICBBY2Nlc3MgcGF0aCBjYW4gY29udGFpbiBhcyBtYW55IHBhcnRzIGFzIG5lY2Vzc2FyeSAoZS5nLiBgXCIubGlzdFswXS5uYW1lXCJgIHRvIGFjY2VzcyBwcm9wZXJ0eSBgbmFtZWAgaW4gdGhlIGZpcnN0IGVsZW1lbnQgb2YgYXJyYXkgc3RvcmVkIGluIHByb3BlcnR5IGBsaXN0YC5cbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFkZGl0aW9uYWwgYXJndW1lbnRzIG9mIHRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBpbnRlcnBvbGF0ZWQgcGF0aHMuXG4gKiAgRS5nLiBgbS5wYXRoKFwiWyQxXS4kMlwiLCBpZCwgcHJvcClgIHJldHVybnMgTW9kZWxQYXRoIHRvIGFjY2VzcyBwcm9wZXJ0eSB3aXRoIG5hbWUgYHByb3BgIGluIGFycmF5IGl0ZW0gd2l0aCBpbmRleCBgaWRgLiBBbHRob3VnaCB0aGlzIE1vZGVsUGF0aCBvYmplY3Qgd2lsbCB3b3JrIGV4YWN0bHkgYXMgYG0oXCJbXCIgKyBpZCArIFwiXS5cIiArIHByb3ApYCwgdGhlIGludGVycG9sYXRlZCBpcyBtdWNoIG1vcmUgZWZmaWNpZW50IGFzIE1vZGVsUGF0aCB3aXRoIGludGVycG9sYXRpb24gd2lsbCBub3Qgc3ludGhlc2l6ZSBuZXcgZ2V0dGVycyBhbmQgc2V0dGVycywgd2hpbGUgTW9kZWxQYXRoIHdpdGggY29tcHV0ZWQgYWNjZXNzIHBhdGggd2lsbCBzeW50aGVzaXplIG5ldyBnZXR0ZXJzIGFuZCBzZXR0ZXJzIGZvciBlYWNoIHBhaXIgb2YgdmFsdWVzIG9mIGBpZGAgYW5kIGBwcm9wYC5cbiAqIEByZXR1cm4ge01vZGVsUGF0aH1cbiAqL1xuZnVuY3Rpb24gTW9kZWwkcGF0aChhY2Nlc3NQYXRoKSB7ICAvLyAsIC4uLiBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIGludGVycG9sYXRlZFxuICAgIGlmICghIGFjY2Vzc1BhdGgpIHJldHVybiB0aGlzO1xuXG4gICAgLy8gXCJudWxsXCIgaXMgY29udGV4dCB0byBwYXNzIHRvIE1vZGVsUGF0aCwgZmlyc3QgcGFyYW1ldGVyIG9mIGJpbmRcbiAgICAvLyBcInRoaXNcIiAobW9kZWwpIGlzIGFkZGVkIGluIGZyb250IG9mIGFsbCBhcmd1bWVudHNcbiAgICBfLnNwbGljZShhcmd1bWVudHMsIDAsIDAsIG51bGwsIHRoaXMpO1xuXG4gICAgLy8gY2FsbGluZyBNb2RlbFBhdGggY29uc3RydWN0b3Igd2l0aCBuZXcgYW5kIHRoZSBsaXN0IG9mIGFyZ3VtZW50czogdGhpcyAobW9kZWwpLCBhY2Nlc3NQYXRoLCAuLi5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShNb2RlbFBhdGgsIGFyZ3VtZW50cykpO1xufVxuXG5cbi8qKlxuICogTW9kZWwgaW5zdGFuY2UgbWV0aG9kLlxuICogUHJveHkgbW9kZWwncyBNZXNzZW5nZXIgbWV0aG9kcyB0byBob3N0IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbW9kZWxIb3N0T2JqZWN0IG9wdGlvbmFsIGhvc3Qgb2JqZWN0LiBJZiBub3QgcGFzc2VkLCBob3N0T2JqZWN0IHBhc3NlZCB0byBNb2RlbCBjb25zdHJ1Y3RvciB3aWxsIGJlIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHByb3h5TWVzc2VuZ2VyKG1vZGVsSG9zdE9iamVjdCkge1xuICAgIG1vZGVsSG9zdE9iamVjdCA9IG1vZGVsSG9zdE9iamVjdCB8fCB0aGlzLl9ob3N0T2JqZWN0O1xuICAgIE1peGluLnByb3RvdHlwZS5fY3JlYXRlUHJveHlNZXRob2RzLmNhbGwodGhpc1tNRVNTRU5HRVJfUFJPUEVSVFldLCBNZXNzZW5nZXIuZGVmYXVsdE1ldGhvZHMsIG1vZGVsSG9zdE9iamVjdCk7XG59XG5cblxudmFyIG1vZGVsTWV0aG9kc1RvUHJveHkgPSBbJ3BhdGgnLCAnZ2V0JywgJ3NldCcsICdkZWwnLCAnc3BsaWNlJywgJ2xlbicsICdwdXNoJywgJ3BvcCcsICd1bnNoaWZ0JywgJ3NoaWZ0J107XG5cblxuLyoqXG4gKiBFeHBvc2UgbW9kZWwgbWV0aG9kcyBvblxuICogU2VlIHNhbWUgbWV0aG9kIGluIE1peGluIGNsYXNzIGZvciBwYXJhbWV0ZXJzIG1lYW5pbmdcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBob3N0Q2xhc3NcbiAqIEBwYXJhbSB7W3R5cGVdfSBpbnN0YW5jZUtleVxuICogQHBhcmFtIHtbdHlwZV19IG1peGluTWV0aG9kcyBvcHRpb25hbFxuICovXG5mdW5jdGlvbiBNb2RlbCQkdXNlV2l0aChob3N0Q2xhc3MsIGluc3RhbmNlS2V5LCBtaXhpbk1ldGhvZHMpIHtcbiAgICBtaXhpbk1ldGhvZHMgPSBtaXhpbk1ldGhvZHMgfHwgbW9kZWxNZXRob2RzVG9Qcm94eTtcbiAgICBNaXhpbi51c2VXaXRoLmNhbGwoTW9kZWwsIGhvc3RDbGFzcywgaW5zdGFuY2VLZXksIG1peGluTWV0aG9kcyk7XG59XG5cblxuLyoqXG4gKiBNb2RlbCBpbnN0YW5jZSBtZXRob2QuXG4gKiBQcm94eSBtb2RlbCBtZXRob2RzIHRvIGhvc3Qgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBtb2RlbEhvc3RPYmplY3Qgb3B0aW9uYWwgaG9zdCBvYmplY3QuIElmIG5vdCBwYXNzZWQsIGhvc3RPYmplY3QgcGFzc2VkIHRvIE1vZGVsIGNvbnN0cnVjdG9yIHdpbGwgYmUgdXNlZC5cbiAqL1xuZnVuY3Rpb24gcHJveHlNZXRob2RzKG1vZGVsSG9zdE9iamVjdCkge1xuICAgIG1vZGVsSG9zdE9iamVjdCA9IG1vZGVsSG9zdE9iamVjdCB8fCB0aGlzLl9ob3N0T2JqZWN0O1xuICAgIE1peGluLnByb3RvdHlwZS5fY3JlYXRlUHJveHlNZXRob2RzLmNhbGwodGhpcywgbW9kZWxNZXRob2RzVG9Qcm94eSwgbW9kZWxIb3N0T2JqZWN0KTtcbn1cblxuXG4vKipcbiAqIE1vZGVsIGluc3RhbmNlIG1ldGhvZC5cbiAqIENyZWF0ZSBhbmQgY29ubmVjdCBpbnRlcm5hbCBhbmQgZXh0ZXJuYWwgbW9kZWwncyBtZXNzZW5nZXJzLlxuICogRXh0ZXJuYWwgbWVzc2VuZ2VyJ3MgbWV0aG9kcyBhcmUgcHJveGllZCBvbiB0aGUgbW9kZWwgYW5kIHRoZXkgYWxsb3dzIFwiKlwiIHN1YnNjcmlwdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIF9wcmVwYXJlTWVzc2VuZ2VycygpIHtcbiAgICAvLyBtb2RlbCB3aWxsIHBvc3QgYWxsIGl0cyBjaGFuZ2VzIG9uIGludGVybmFsIG1lc3NlbmdlclxuICAgIHZhciBpbnRlcm5hbE1lc3NlbmdlciA9IG5ldyBNZXNzZW5nZXIodGhpcywgdW5kZWZpbmVkLCB1bmRlZmluZWQpO1xuXG4gICAgLy8gbWVzc2FnZSBzb3VyY2UgdG8gY29ubmVjdCBpbnRlcm5hbCBtZXNzZW5nZXIgdG8gZXh0ZXJuYWxcbiAgICB2YXIgaW50ZXJuYWxNZXNzZW5nZXJTb3VyY2UgPSBuZXcgTWVzc2VuZ2VyTWVzc2FnZVNvdXJjZSh0aGlzLCB1bmRlZmluZWQsIG5ldyBNb2RlbE1zZ0FQSSwgaW50ZXJuYWxNZXNzZW5nZXIpO1xuXG4gICAgLy8gZXh0ZXJuYWwgbWVzc2VuZ2VyIHRvIHdoaWNoIGFsbCBtb2RlbCB1c2VycyB3aWxsIHN1YnNjcmliZSxcbiAgICAvLyB0aGF0IHdpbGwgYWxsb3cgXCIqXCIgc3Vic2NyaXB0aW9ucyBhbmQgc3VwcG9ydCBcImNoYW5nZWRhdGFcIiBtZXNzYWdlIGFwaS5cbiAgICB2YXIgZXh0ZXJuYWxNZXNzZW5nZXIgPSBuZXcgTWVzc2VuZ2VyKHRoaXMsIHVuZGVmaW5lZCwgaW50ZXJuYWxNZXNzZW5nZXJTb3VyY2UpO1xuXG4gICAgXy5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBNRVNTRU5HRVJfUFJPUEVSVFksIGV4dGVybmFsTWVzc2VuZ2VyKTtcbiAgICBfLmRlZmluZVByb3BlcnR5KHRoaXMsICdfaW50ZXJuYWxNZXNzZW5nZXInLCBpbnRlcm5hbE1lc3Nlbmdlcik7XG59XG5cblxuZnVuY3Rpb24gX2dldEhvc3RPYmplY3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hvc3RPYmplY3Q7XG59XG5cblxuZnVuY3Rpb24gTW9kZWwkZGVzdHJveSgpIHtcbiAgICB0aGlzW01FU1NFTkdFUl9QUk9QRVJUWV0uZGVzdHJveSgpO1xuICAgIHRoaXMuX2ludGVybmFsTWVzc2VuZ2VyLmRlc3Ryb3koKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xufVxuIiwiYXJndW1lbnRzWzRdWzc1XVswXS5hcHBseShleHBvcnRzLGFyZ3VtZW50cykiLCJhcmd1bWVudHNbNF1bNzZdWzBdLmFwcGx5KGV4cG9ydHMsYXJndW1lbnRzKSIsImFyZ3VtZW50c1s0XVs3OF1bMF0uYXBwbHkoZXhwb3J0cyxhcmd1bWVudHMpIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyA8YSBuYW1lPVwibW9kZWwtcGF0aFwiPjwvYT5cbi8vICMjIyBtb2RlbCBwYXRoIHV0aWxzXG5cbnZhciBjaGVjayA9IHJlcXVpcmUoJy4uL3V0aWwvY2hlY2snKVxuICAgICwgTWF0Y2ggPSBjaGVjay5NYXRjaFxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpO1xuXG52YXIgcGF0aFV0aWxzID0ge1xuICAgIHBhcnNlQWNjZXNzUGF0aDogcGFyc2VBY2Nlc3NQYXRoLFxuICAgIGNyZWF0ZVJlZ2V4UGF0aDogY3JlYXRlUmVnZXhQYXRoLFxuICAgIGdldFBhdGhOb2RlS2V5OiBnZXRQYXRoTm9kZUtleSxcbiAgICB3cmFwTWVzc2VuZ2VyTWV0aG9kczogd3JhcE1lc3Nlbmdlck1ldGhvZHNcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gcGF0aFV0aWxzO1xuXG5cbnZhciBwcm9wZXJ0eVBhdGhTeW50YXggPSAnXFxcXC5bQS1aYS16Xy1dW0EtWmEtejAtOV8tXSonXG4gICAgLCBhcnJheVBhdGhTeW50YXggPSAnXFxcXFtbMC05XStcXFxcXSdcbiAgICAsIGludGVycG9sYXRpb25TeW50YXggPSAnXFxcXCRbMS05XVswLTldKidcbiAgICAsIHByb3BlcnR5SW50ZXJwb2xhdGVTeW50YXggPSAnXFxcXC4nICsgaW50ZXJwb2xhdGlvblN5bnRheFxuICAgICwgYXJyYXlJbnRlcnBvbGF0ZVN5bnRheCA9ICdcXFxcWycgKyBpbnRlcnBvbGF0aW9uU3ludGF4ICsgJ1xcXFxdJ1xuXG4gICAgLCBwcm9wZXJ0eVN0YXJTeW50YXggPSAnXFxcXC5cXFxcKidcbiAgICAsIGFycmF5U3RhclN5bnRheCA9ICdcXFxcW1xcXFwqXFxcXF0nXG4gICAgLCBzdGFyU3ludGF4ID0gJ1xcXFwqJ1xuXG4gICAgLCBwYXRoUGFyc2VTeW50YXggPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHlQYXRoU3ludGF4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5UGF0aFN5bnRheCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eUludGVycG9sYXRlU3ludGF4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5SW50ZXJwb2xhdGVTeW50YXhcbiAgICAgICAgICAgICAgICAgICAgICAgIF0uam9pbignfCcpXG4gICAgLCBwYXRoUGFyc2VQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXRoUGFyc2VTeW50YXgsICdnJylcblxuICAgICwgcGF0dGVyblBhdGhQYXJzZVN5bnRheCA9ICBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoUGFyc2VTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eVN0YXJTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJheVN0YXJTeW50YXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFyU3ludGF4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0uam9pbignfCcpXG4gICAgLCBwYXR0ZXJuUGF0aFBhcnNlUGF0dGVybiA9IG5ldyBSZWdFeHAocGF0dGVyblBhdGhQYXJzZVN5bnRheCwgJ2cnKVxuXG4gICAgLy8sIHRhcmdldFBhdGhQYXJzZVBhdHRlcm4gPSAvXFwuW0EtWmEtel1bQS1aYS16MC05X10qfFxcW1swLTldK1xcXXxcXC5cXCRbMS05XVswLTldKnxcXFtcXCRbMS05XVswLTldKlxcXXxcXCRbMS05XVswLTldL2dcbiAgICAsIHBhdGhOb2RlVHlwZXMgPSB7XG4gICAgICAgICcuJzogeyBzeW50YXg6ICdvYmplY3QnLCBlbXB0eTogJ3t9JyB9LFxuICAgICAgICAnWyc6IHsgc3ludGF4OiAnYXJyYXknLCBlbXB0eTogJ1tdJ30sXG4gICAgICAgICcqJzogeyBzeW50YXg6ICdtYXRjaCcsIGVtcHR5OiAne30nfSxcbiAgICB9O1xuXG5mdW5jdGlvbiBwYXJzZUFjY2Vzc1BhdGgocGF0aCwgbm9kZVBhcnNlUGF0dGVybikge1xuICAgIG5vZGVQYXJzZVBhdHRlcm4gPSBub2RlUGFyc2VQYXR0ZXJuIHx8IHBhdGhQYXJzZVBhdHRlcm47XG5cbiAgICB2YXIgcGFyc2VkUGF0aCA9IFtdO1xuXG4gICAgaWYgKCEgcGF0aClcbiAgICAgICAgcmV0dXJuIHBhcnNlZFBhdGg7XG5cbiAgICB2YXIgdW5wYXJzZWQgPSBwYXRoLnJlcGxhY2Uobm9kZVBhcnNlUGF0dGVybiwgZnVuY3Rpb24obm9kZVN0cikge1xuICAgICAgICB2YXIgcGF0aE5vZGUgPSB7IHByb3BlcnR5OiBub2RlU3RyIH07XG4gICAgICAgIF8uZXh0ZW5kKHBhdGhOb2RlLCBwYXRoTm9kZVR5cGVzW25vZGVTdHJbMF1dKTtcbiAgICAgICAgaWYgKG5vZGVTdHJbMV0gPT0gJyQnKVxuICAgICAgICAgICAgcGF0aE5vZGUuaW50ZXJwb2xhdGUgPSBnZXRQYXRoTm9kZUtleShwYXRoTm9kZSwgdHJ1ZSk7XG5cbiAgICAgICAgcGFyc2VkUGF0aC5wdXNoKHBhdGhOb2RlKTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH0pO1xuICAgIGlmICh1bnBhcnNlZClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbmNvcnJlY3QgbW9kZWwgcGF0aDogJyArIHBhdGgpO1xuXG4gICAgcmV0dXJuIHBhcnNlZFBhdGg7XG59XG5cblxudmFyIG5vZGVSZWdleCA9IHtcbiAgICAnLionOiBwcm9wZXJ0eVBhdGhTeW50YXgsXG4gICAgJ1sqXSc6IGFycmF5UGF0aFN5bnRheFxufTtcbm5vZGVSZWdleFsnKiddID0gbm9kZVJlZ2V4WycuKiddICsgJ3wnICsgbm9kZVJlZ2V4WydbKl0nXTtcblxuZnVuY3Rpb24gY3JlYXRlUmVnZXhQYXRoKHBhdGgpIHtcbiAgICBjaGVjayhwYXRoLCBNYXRjaC5PbmVPZihTdHJpbmcsIFJlZ0V4cCkpO1xuXG4gICAgaWYgKHBhdGggaW5zdGFuY2VvZiBSZWdFeHAgfHwgcGF0aC5pbmRleE9mKCcqJykgPT0gLTEpXG4gICAgICAgIHJldHVybiBwYXRoO1xuXG4gICAgdmFyIHBhcnNlZFBhdGggPSBwYXRoVXRpbHMucGFyc2VBY2Nlc3NQYXRoKHBhdGgsIHBhdHRlcm5QYXRoUGFyc2VQYXR0ZXJuKVxuICAgICAgICAsIHJlZ2V4U3RyID0gJ14nXG4gICAgICAgIC8vICwgcmVnZXhTdHJFbmQgPSAnJ1xuICAgICAgICAsIHBhdHRlcm5zU3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgcGFyc2VkUGF0aC5mb3JFYWNoKGZ1bmN0aW9uKHBhdGhOb2RlKSB7XG4gICAgICAgIHZhciBwcm9wID0gcGF0aE5vZGUucHJvcGVydHlcbiAgICAgICAgICAgICwgcmVnZXggPSBub2RlUmVnZXhbcHJvcF07XG4gICAgICAgIFxuICAgICAgICBpZiAocmVnZXgpIHtcbiAgICAgICAgICAgIC8vIHJlZ2V4U3RyICs9ICcoJyArIHJlZ2V4O1xuICAgICAgICAgICAgLy8gcmVnZXhTdHJFbmQgKz0gJ3wpJztcbiAgICAgICAgICAgIHJlZ2V4U3RyICs9ICcoJyArIHJlZ2V4ICsgJ3wpJztcbiAgICAgICAgICAgIC8vIHJlZ2V4U3RyRW5kICs9ICd8KSc7XG4gICAgICAgICAgICBwYXR0ZXJuc1N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaWYgKHBhdHRlcm5zU3RhcnRlZClcbiAgICAgICAgICAgIC8vICB0aHJvdyBuZXcgRXJyb3IoJ1wiKlwiIHBhdGggc2VnbWVudCBjYW5ub3QgYmUgaW4gdGhlIG1pZGRsZSBvZiB0aGUgcGF0aDogJyArIHBhdGgpO1xuICAgICAgICAgICAgcmVnZXhTdHIgKz0gcHJvcC5yZXBsYWNlKC8oXFwufFxcW3xcXF0pL2csICdcXFxcJDEnKTsgLy8gYWRkIHNsYXNoIGluIGZyb250IG9mIHN5bWJvbHMgdGhhdCBoYXZlIHNwZWNpYWwgbWVhbmluZyBpbiByZWdleFxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICByZWdleFN0ciArPSAvKiByZWdleFN0ckVuZCArICovICckJztcblxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4U3RyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2FuXFwndCBjb25zdHJ1Y3QgcmVnZXggZm9yIHBhdGggcGF0dGVybjogJyArIHBhdGgpO1xuICAgIH1cbn1cblxuXG5mdW5jdGlvbiBnZXRQYXRoTm9kZUtleShwYXRoTm9kZSwgaW50ZXJwb2xhdGVkKSB7XG4gICAgdmFyIHByb3AgPSBwYXRoTm9kZS5wcm9wZXJ0eVxuICAgICAgICAsIHN0YXJ0SW5kZXggPSBpbnRlcnBvbGF0ZWQgPyAyIDogMTtcbiAgICByZXR1cm4gcGF0aE5vZGUuc3ludGF4ID09ICdhcnJheSdcbiAgICAgICAgPyBwcm9wLnNsaWNlKHN0YXJ0SW5kZXgsIHByb3AubGVuZ3RoIC0gMSlcbiAgICAgICAgOiBwcm9wLnNsaWNlKHN0YXJ0SW5kZXgpO1xufVxuXG5cbi8vIFRPRE8gYWxsb3cgZm9yIG11bHRpcGxlIG1lc3NhZ2VzIGluIGEgc3RyaW5nXG5mdW5jdGlvbiB3cmFwTWVzc2VuZ2VyTWV0aG9kcyhtZXRob2RzTmFtZXMpIHtcbiAgICBtZXRob2RzTmFtZXMgPSBtZXRob2RzTmFtZXMgfHwgWydvbicsICdvZmYnXTtcbiAgICB2YXIgd3JhcHBlZE1ldGhvZHMgPSBfLm1hcFRvT2JqZWN0KG1ldGhvZHNOYW1lcywgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgb3JpZ01ldGhvZCA9IHRoaXNbbWV0aG9kTmFtZV07XG4gICAgICAgIC8vIHJlcGxhY2luZyBtZXNzYWdlIHN1YnNyaWJlL3Vuc3Vic2NyaWJlL2V0Yy4gdG8gY29udmVydCBcIipcIiBtZXNzYWdlIHBhdHRlcm5zIHRvIHJlZ2V4cHNcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBhdGgsIHN1YnNjcmliZXIpIHtcbiAgICAgICAgICAgIHZhciByZWdleFBhdGggPSBjcmVhdGVSZWdleFBhdGgocGF0aCk7XG4gICAgICAgICAgICBvcmlnTWV0aG9kLmNhbGwodGhpcywgcmVnZXhQYXRoLCBzdWJzY3JpYmVyKTtcbiAgICAgICAgfTtcbiAgICB9LCB0aGlzKTtcbiAgICBfLmRlZmluZVByb3BlcnRpZXModGhpcywgd3JhcHBlZE1ldGhvZHMpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcGF0aFV0aWxzID0gcmVxdWlyZSgnLi4vcGF0aF91dGlscycpXG4gICAgLCBtb2RlbFV0aWxzID0gcmVxdWlyZSgnLi4vbW9kZWxfdXRpbHMnKVxuICAgICwgbG9nZ2VyID0gcmVxdWlyZSgnLi4vLi4vdXRpbC9sb2dnZXInKVxuICAgICwgZnMgPSByZXF1aXJlKCdmcycpXG4gICAgLCBkb1QgPSByZXF1aXJlKCdkb3QnKVxuICAgICwgXyA9IHJlcXVpcmUoJ21vbC1wcm90bycpXG4gICAgLCBjaGFuZ2VEYXRhSGFuZGxlciA9IHJlcXVpcmUoJy4uL2NoYW5nZV9kYXRhJylcbiAgICAsIGdldFRyYW5zYWN0aW9uRmxhZyA9IGNoYW5nZURhdGFIYW5kbGVyLmdldFRyYW5zYWN0aW9uRmxhZ1xuICAgICwgcG9zdFRyYW5zYWN0aW9uRmluaXNoZWQgPSBjaGFuZ2VEYXRhSGFuZGxlci5wb3N0VHJhbnNhY3Rpb25GaW5pc2hlZDtcblxuXG4vKipcbiAqIFRlbXBsYXRlcyB0byBzeW50aGVzaXplIG1vZGVsIGdldHRlcnMgYW5kIHNldHRlcnNcbiAqL1xudmFyIHRlbXBsYXRlcyA9IHtcbiAgICBnZXQ6IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxubWV0aG9kID0gZnVuY3Rpb24gZ2V0KCkge1xcbiAgICB2YXIgbSA9IHt7IyBkZWYubW9kZWxBY2Nlc3NQcmVmaXggfX07XFxuICAgIHJldHVybiBtIHt7fiBpdC5wYXJzZWRQYXRoIDpwYXRoTm9kZSB9fVxcbiAgICAgICAge3s/IHBhdGhOb2RlLmludGVycG9sYXRlfX1cXG4gICAgICAgICAgICAmJiAobSA9IG1bdGhpcy5fYXJnc1sge3s9IHBhdGhOb2RlLmludGVycG9sYXRlIH19IF1dKVxcbiAgICAgICAge3s/P319XFxuICAgICAgICAgICAgJiYgKG0gPSBte3s9IHBhdGhOb2RlLnByb3BlcnR5IH19KVxcbiAgICAgICAge3s/fX0ge3t+fX07XFxufTtcXG5cIixcbiAgICBzZXQ6IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxue3sjIGRlZi5pbmNsdWRlX2RlZmluZXMgfX1cXG57eyMgZGVmLmluY2x1ZGVfY3JlYXRlX3RyZWUgfX1cXG5cXG5cXG4vKipcXG4gKiBUZW1wbGF0ZSB0aGF0IHN5bnRoZXNpemVzIHNldHRlciBmb3IgTW9kZWwgYW5kIGZvciBNb2RlbFBhdGhcXG4gKi9cXG5tZXRob2QgPSBmdW5jdGlvbiBzZXQodmFsdWUpIHtcXG4gICAge3sjIGRlZi5pbml0VmFyczonc2V0JyB9fVxcblxcbiAgICB7eyMgZGVmLmNyZWF0ZVRyZWU6J3NldCcgfX1cXG5cXG4gICAge3tcXG4gICAgICAgIGN1cnJOb2RlID0gbmV4dE5vZGU7XFxuICAgICAgICBjdXJyUHJvcCA9IGN1cnJOb2RlICYmIGN1cnJOb2RlLnByb3BlcnR5O1xcbiAgICB9fVxcblxcbiAgICB7eyAvKiBhc3NpZ24gdmFsdWUgdG8gdGhlIGxhc3QgcHJvcGVydHkgKi8gfX1cXG4gICAge3s/IGN1cnJQcm9wIH19XFxuICAgICAgICB3YXNEZWYgPSB7eyMgZGVmLndhc0RlZmluZWR9fTtcXG4gICAgICAgIHt7IyBkZWYuY2hhbmdlQWNjZXNzUGF0aCB9fVxcblxcbiAgICAgICAgdmFyIG9sZCA9IG17eyMgZGVmLmN1cnJQcm9wIH19O1xcblxcbiAgICAgICAge3sgLyogY2xvbmUgdmFsdWUgdG8gcHJldmVudCBzYW1lIHJlZmVyZW5jZSBpbiBsaW5rZWQgbW9kZWxzICovIH19XFxuICAgICAgICBte3sjIGRlZi5jdXJyUHJvcCB9fSA9IGNsb25lVHJlZSh2YWx1ZSk7XFxuICAgIHt7P319XFxuXFxuICAgIHt7IC8qIGFkZCBtZXNzYWdlIHJlbGF0ZWQgdG8gdGhlIGxhc3QgcHJvcGVydHkgY2hhbmdlICovIH19XFxuICAgIGlmICh0aGlzLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xcbiAgICAgICAgaWYgKCEgd2FzRGVmKVxcbiAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGFjY2Vzc1BhdGgsIHR5cGU6ICdhZGRlZCcsXFxuICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiB2YWx1ZSB9KTtcXG4gICAgICAgIGVsc2UgaWYgKG9sZCAhPSB2YWx1ZSlcXG4gICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBhY2Nlc3NQYXRoLCB0eXBlOiAnY2hhbmdlZCcsXFxuICAgICAgICAgICAgICAgIG9sZFZhbHVlOiBvbGQsIG5ld1ZhbHVlOiB2YWx1ZSB9KTtcXG5cXG4gICAgICAgIHt7IC8qIGFkZCBtZXNzYWdlIHJlbGF0ZWQgdG8gY2hhbmdlcyBpbiAoc3ViKXByb3BlcnRpZXMgaW5zaWRlIHJlbW92ZWQgYW5kIGFzc2lnbmVkIHZhbHVlICovIH19XFxuICAgICAgICBpZiAoISB3YXNEZWYgfHwgb2xkICE9IHZhbHVlKVxcbiAgICAgICAgICAgIGFkZFRyZWVDaGFuZ2VzTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCxcXG4gICAgICAgICAgICAgICAgYWNjZXNzUGF0aCwgb2xkLCB2YWx1ZSk7IC8qIGRlZmluZWQgaW4gdGhlIGZ1bmN0aW9uIHRoYXQgc3ludGhlc2l6ZXMgTW9kZWxQYXRoIHNldHRlciAqL1xcblxcbiAgICAgICAge3sgLyogcG9zdCBhbGwgc3RvcmVkIG1lc3NhZ2VzICovIH19XFxuICAgICAgICB7eyMgZGVmLnBvc3RNZXNzYWdlcyB9fVxcbiAgICB9XFxufTtcXG5cIixcbiAgICBkZWw6IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxue3sjIGRlZi5pbmNsdWRlX2RlZmluZXMgfX1cXG57eyMgZGVmLmluY2x1ZGVfdHJhdmVyc2VfdHJlZSB9fVxcblxcbm1ldGhvZCA9IGZ1bmN0aW9uIGRlbCgpIHtcXG4gICAge3sjIGRlZi5pbml0VmFyczonZGVsJyB9fVxcblxcbiAgICB7ez8gaXQucGFyc2VkUGF0aC5sZW5ndGggfX1cXG4gICAgICAgIHt7IyBkZWYudHJhdmVyc2VUcmVlIH19XFxuXFxuICAgICAgICB7e1xcbiAgICAgICAgICAgIHZhciBjdXJyTm9kZSA9IGl0LnBhcnNlZFBhdGhbY291bnRdO1xcbiAgICAgICAgICAgIHZhciBjdXJyUHJvcCA9IGN1cnJOb2RlLnByb3BlcnR5OyAgICAgICBcXG4gICAgICAgIH19XFxuXFxuICAgICAgICBpZiAoISB0cmVlRG9lc05vdEV4aXN0ICYmIG0gJiYgbS5oYXNPd25Qcm9wZXJ0eSAmJiB7eyMgZGVmLndhc0RlZmluZWR9fSkge1xcbiAgICAgICAgICAgIHZhciBvbGQgPSBte3sjIGRlZi5jdXJyUHJvcCB9fTtcXG4gICAgICAgICAgICBkZWxldGUgbXt7IyBkZWYuY3VyclByb3AgfX07XFxuICAgICAgICAgICAge3sjIGRlZi5jaGFuZ2VBY2Nlc3NQYXRoIH19XFxuICAgICAgICAgICAgdmFyIGRpZERlbGV0ZSA9IHRydWU7XFxuICAgICAgICB9XFxuICAgIHt7Pz99fVxcbiAgICAgICAgaWYgKHR5cGVvZiBtICE9ICd1bmRlZmluZWQnKSB7XFxuICAgICAgICAgICAgdmFyIG9sZCA9IG07XFxuICAgICAgICAgICAge3sjIGRlZi5tb2RlbEFjY2Vzc1ByZWZpeCB9fSA9IHVuZGVmaW5lZDtcXG4gICAgICAgICAgICB2YXIgZGlkRGVsZXRlID0gdHJ1ZTtcXG4gICAgICAgIH1cXG4gICAge3s/fX1cXG5cXG4gICAgaWYgKGRpZERlbGV0ZSAmJiB0aGlzLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xcbiAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gYWNjZXNzUGF0aCwgdHlwZTogJ2RlbGV0ZWQnLCBvbGRWYWx1ZTogb2xkIH0pO1xcblxcbiAgICAgICAgYWRkVHJlZUNoYW5nZXNNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLFxcbiAgICAgICAgICAgIGFjY2Vzc1BhdGgsIG9sZCwgdW5kZWZpbmVkKTsgLyogZGVmaW5lZCBpbiB0aGUgZnVuY3Rpb24gdGhhdCBzeW50aGVzaXplcyBNb2RlbFBhdGggc2V0dGVyICovXFxuXFxuICAgICAgICB7eyAvKiBwb3N0IGFsbCBzdG9yZWQgbWVzc2FnZXMgKi8gfX1cXG4gICAgICAgIHt7IyBkZWYucG9zdE1lc3NhZ2VzIH19XFxuICAgIH1cXG59O1xcblwiLFxuICAgIHNwbGljZTogXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG57eyMgZGVmLmluY2x1ZGVfZGVmaW5lcyB9fVxcbnt7IyBkZWYuaW5jbHVkZV9jcmVhdGVfdHJlZSB9fVxcbnt7IyBkZWYuaW5jbHVkZV90cmF2ZXJzZV90cmVlIH19XFxuXFxubWV0aG9kID0gZnVuY3Rpb24gc3BsaWNlKHNwbGljZUluZGV4LCBzcGxpY2VIb3dNYW55KSB7IC8qICwuLi4gLSBleHRyYSBhcmd1bWVudHMgdG8gc3BsaWNlIGludG8gYXJyYXkgKi9cXG4gICAge3sjIGRlZi5pbml0VmFyczonc3BsaWNlJyB9fVxcblxcbiAgICB2YXIgYXJnc0xlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XFxuICAgIHZhciBhZGRJdGVtcyA9IGFyZ3NMZW4gPiAyO1xcblxcbiAgICBpZiAoYWRkSXRlbXMpIHtcXG4gICAgICAgIHt7IC8qIG9ubHkgY3JlYXRlIG1vZGVsIHRyZWUgaWYgaXRlbXMgYXJlIGluc2VydGVkIGluIGFycmF5ICovIH19XFxuXFxuICAgICAgICB7eyAvKiBpZiBtb2RlbCBpcyB1bmRlZmluZWQgaXQgd2lsbCBiZSBzZXQgdG8gYW4gZW1wdHkgYXJyYXkgKi8gfX0gIFxcbiAgICAgICAgdmFyIHZhbHVlID0gW107XFxuICAgICAgICB7eyMgZGVmLmNyZWF0ZVRyZWU6J3NwbGljZScgfX1cXG5cXG4gICAgICAgIHt7PyBuZXh0Tm9kZSB9fVxcbiAgICAgICAgICAgIHt7XFxuICAgICAgICAgICAgICAgIHZhciBjdXJyTm9kZSA9IG5leHROb2RlO1xcbiAgICAgICAgICAgICAgICB2YXIgY3VyclByb3AgPSBjdXJyTm9kZS5wcm9wZXJ0eTtcXG4gICAgICAgICAgICAgICAgdmFyIGVtcHR5UHJvcCA9ICdbXSc7XFxuICAgICAgICAgICAgfX1cXG5cXG4gICAgICAgICAgICB7eyMgZGVmLmNyZWF0ZVRyZWVTdGVwIH19XFxuICAgICAgICB7ez99fVxcblxcbiAgICB9IGVsc2UgaWYgKHNwbGljZUhvd01hbnkgPiAwKSB7XFxuICAgICAgICB7eyAvKiBpZiBpdGVtcyBhcmUgbm90IGluc2VydGVkLCBvbmx5IHRyYXZlcnNlIG1vZGVsIHRyZWUgaWYgaXRlbXMgYXJlIGRlbGV0ZWQgZnJvbSBhcnJheSAqLyB9fVxcbiAgICAgICAge3s/IGl0LnBhcnNlZFBhdGgubGVuZ3RoIH19XFxuICAgICAgICAgICAge3sjIGRlZi50cmF2ZXJzZVRyZWUgfX1cXG5cXG4gICAgICAgICAgICB7e1xcbiAgICAgICAgICAgICAgICB2YXIgY3Vyck5vZGUgPSBpdC5wYXJzZWRQYXRoW2NvdW50XTtcXG4gICAgICAgICAgICAgICAgdmFyIGN1cnJQcm9wID0gY3Vyck5vZGUucHJvcGVydHk7ICAgICAgIFxcbiAgICAgICAgICAgIH19XFxuXFxuICAgICAgICAgICAge3sgLyogZXh0cmEgYnJhY2UgY2xvc2VzICdlbHNlJyBpbiBkZWYudHJhdmVyc2VUcmVlU3RlcCAqLyB9fVxcbiAgICAgICAgICAgIHt7IyBkZWYudHJhdmVyc2VUcmVlU3RlcCB9fSB9XFxuICAgICAgICB7ez99fVxcbiAgICB9XFxuXFxuICAgIHt7IC8qIHNwbGljZSBpdGVtcyAqLyB9fVxcbiAgICBpZiAoYWRkSXRlbXMgfHwgKCEgdHJlZURvZXNOb3RFeGlzdCAmJiBtXFxuICAgICAgICAgICAgJiYgbS5sZW5ndGggPiBzcGxpY2VJbmRleCApICkge1xcbiAgICAgICAgdmFyIG9sZExlbmd0aCA9IG0ubGVuZ3RoID0gbS5sZW5ndGggfHwgMDtcXG5cXG4gICAgICAgIGFyZ3VtZW50c1swXSA9IHNwbGljZUluZGV4ID0gbm9ybWFsaXplU3BsaWNlSW5kZXgoc3BsaWNlSW5kZXgsIG0ubGVuZ3RoKTtcXG5cXG4gICAgICAgIHt7IC8qIGNsb25lIGFkZGVkIGFyZ3VtZW50cyB0byBwcmV2ZW50IHNhbWUgcmVmZXJlbmNlcyBpbiBsaW5rZWQgbW9kZWxzICovIH19XFxuICAgICAgICBpZiAoYWRkSXRlbXMpXFxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCBhcmdzTGVuOyBpKyspXFxuICAgICAgICAgICAgICAgIGFyZ3VtZW50c1tpXSA9IGNsb25lVHJlZShhcmd1bWVudHNbaV0pO1xcblxcbiAgICAgICAge3sgLyogYWN0dWFsIHNwbGljZSBjYWxsICovIH19XFxuICAgICAgICB2YXIgcmVtb3ZlZCA9IEFycmF5LnByb3RvdHlwZS5zcGxpY2UuYXBwbHkobSwgYXJndW1lbnRzKTtcXG5cXG4gICAgICAgIGlmICh0aGlzLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xcbiAgICAgICAgICAgIHt7IyBkZWYuYWRkTXNnIH19IGFjY2Vzc1BhdGgsIHR5cGU6ICdzcGxpY2UnLFxcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHNwbGljZUluZGV4LCByZW1vdmVkOiByZW1vdmVkLCBhZGRlZENvdW50OiBhZGRJdGVtcyA/IGFyZ3NMZW4gLSAyIDogMCxcXG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBtIH0pO1xcblxcbiAgICAgICAgICAgIGlmIChyZW1vdmVkICYmIHJlbW92ZWQubGVuZ3RoKVxcbiAgICAgICAgICAgICAgICByZW1vdmVkLmZvckVhY2goZnVuY3Rpb24oaXRlbSwgaW5kZXgpIHtcXG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVtUGF0aCA9IGFjY2Vzc1BhdGggKyAnWycgKyAoc3BsaWNlSW5kZXggKyBpbmRleCkgKyAnXSc7XFxuICAgICAgICAgICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSBpdGVtUGF0aCwgdHlwZTogJ3JlbW92ZWQnLCBvbGRWYWx1ZTogaXRlbSB9KTtcXG5cXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUlzVHJlZShpdGVtKSlcXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRNZXNzYWdlcyhtZXNzYWdlcywgbWVzc2FnZXNIYXNoLCBpdGVtUGF0aCwgaXRlbSwgJ3JlbW92ZWQnLCAnb2xkVmFsdWUnKTtcXG4gICAgICAgICAgICAgICAgfSk7XFxuXFxuICAgICAgICAgICAgaWYgKGFkZEl0ZW1zKVxcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMjsgaSA8IGFyZ3NMZW47IGkrKykge1xcbiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSBhcmd1bWVudHNbaV07XFxuICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbVBhdGggPSBhY2Nlc3NQYXRoICsgJ1snICsgKHNwbGljZUluZGV4ICsgaSAtIDIpICsgJ10nO1xcbiAgICAgICAgICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gaXRlbVBhdGgsIHR5cGU6ICdhZGRlZCcsIG5ld1ZhbHVlOiBpdGVtIH0pO1xcblxcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlSXNUcmVlKGl0ZW0pKVxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE1lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIGl0ZW1QYXRoLCBpdGVtLCAnYWRkZWQnLCAnbmV3VmFsdWUnKTtcXG4gICAgICAgICAgICAgICAgfVxcblxcbiAgICAgICAgICAgIHt7IC8qIHBvc3QgYWxsIHN0b3JlZCBtZXNzYWdlcyAqLyB9fVxcbiAgICAgICAgICAgIHt7IyBkZWYucG9zdE1lc3NhZ2VzIH19XFxuICAgICAgICB9XFxuICAgIH1cXG5cXG4gICAgcmV0dXJuIHJlbW92ZWQgfHwgW107XFxufVxcblwiXG59O1xuXG52YXIgaW5jbHVkZV9kZWZpbmVzID0gXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGluaXRpYWxpemF0aW9uIGNvZGVcXG4gKi9cXG4ge3sjIyBkZWYuaW5pdFZhcnM6bWV0aG9kOlxcbiAgICB2YXIgbSA9IHt7IyBkZWYubW9kZWxBY2Nlc3NQcmVmaXggfX07XFxuICAgIHZhciBtZXNzYWdlcyA9IFtdLCBtZXNzYWdlc0hhc2ggPSB7fTtcXG4gICAgdmFyIGFjY2Vzc1BhdGggPSAnJztcXG4gICAgdmFyIHRyZWVEb2VzTm90RXhpc3Q7XFxuICAgIC8qIGhhY2sgdG8gcHJldmVudCBzZW5kaW5nIGZpbmlzaGVkIGV2ZW50cyB0byBhbGxvdyBmb3IgcHJvcGFnYXRpb24gb2YgYmF0Y2hlcyB3aXRob3V0IHNwbGl0dGluZyB0aGVtICovXFxuICAgIHZhciBpbkNoYW5nZVRyYW5zYWN0aW9uID0gZ2V0VHJhbnNhY3Rpb25GbGFnKCB7ez0gbWV0aG9kIH19ICk7XFxuICN9fVxcblxcbi8qKlxcbiAqIEluc2VydHMgdGhlIGJlZ2lubmluZyBvZiBmdW5jdGlvbiBjYWxsIHRvIGFkZCBtZXNzYWdlIHRvIGxpc3RcXG4gKi9cXG57eyMjIGRlZi5hZGRNc2c6IGFkZENoYW5nZU1lc3NhZ2UobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgeyBwYXRoOiAjfX1cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGN1cnJlbnQgcHJvcGVydHkvaW5kZXggZm9yIGJvdGggbm9ybWFsIGFuZCBpbnRlcnBvbGF0ZWQgcHJvcGVydGllcy9pbmRleGVzXFxuICovXFxue3sjIyBkZWYuY3VyclByb3A6e3s/IGN1cnJOb2RlLmludGVycG9sYXRlIH19W3RoaXMuX2FyZ3NbIHt7PSBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fSBdXXt7Pz99fXt7PSBjdXJyUHJvcCB9fXt7P319ICN9fVxcblxcbi8qKlxcbiAqIEluc2VydHMgY29uZGl0aW9uIHRvIHRlc3Qgd2hldGhlciBub3JtYWwvaW50ZXJwb2xhdGVkIHByb3BlcnR5L2luZGV4IGV4aXN0c1xcbiAqL1xcbnt7IyMgZGVmLndhc0RlZmluZWQ6IG0uaGFzT3duUHJvcGVydHkoXFxuICAgIHt7PyBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fVxcbiAgICAgICAgdGhpcy5fYXJnc1sge3s9IGN1cnJOb2RlLmludGVycG9sYXRlIH19IF1cXG4gICAge3s/P319XFxuICAgICAgICAne3s9IGl0LmdldFBhdGhOb2RlS2V5KGN1cnJOb2RlKSB9fSdcXG4gICAge3s/fX1cXG4pICN9fVxcblxcblxcbi8qKlxcbiAqIEluc2VydHMgY29kZSB0byB1cGRhdGUgYWNjZXNzIHBhdGggZm9yIGN1cnJlbnQgcHJvcGVydHlcXG4gKiBCZWNhdXNlIG9mIHRoZSBwb3NzaWJpbGl0eSBvZiBpbnRlcnBvbGF0ZWQgcHJvcGVydGllcywgaXQgY2FuJ3QgYmUgY2FsY3VsYXRlZCBpbiB0ZW1wbGF0ZSwgaXQgY2FuIG9ubHkgYmUgY2FsY3VsYXRlZCBkdXJpbmcgYWNjZXNzb3IgY2FsbC5cXG4gKi9cXG57eyMjIGRlZi5jaGFuZ2VBY2Nlc3NQYXRoOlxcbiAgICBhY2Nlc3NQYXRoICs9IHt7PyBjdXJyTm9kZS5pbnRlcnBvbGF0ZSB9fVxcbiAgICAgICAge3s/IGN1cnJOb2RlLnN5bnRheCA9PSAnYXJyYXknIH19XFxuICAgICAgICAgICAgJ1snICsgdGhpcy5fYXJnc1sge3s9IGN1cnJOb2RlLmludGVycG9sYXRlIH19IF0gKyAnXSc7XFxuICAgICAgICB7ez8/fX1cXG4gICAgICAgICAgICAnLicgKyB0aGlzLl9hcmdzWyB7ez0gY3Vyck5vZGUuaW50ZXJwb2xhdGUgfX0gXTtcXG4gICAgICAgIHt7P319XFxuICAgIHt7Pz99fVxcbiAgICAgICAgJ3t7PSBjdXJyUHJvcCB9fSc7XFxuICAgIHt7P319XFxuI319XFxuXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb2RlIHRvIHBvc3Qgc3RvcmVkIG1lc3NhZ2VzXFxuICovXFxue3sjIyBkZWYucG9zdE1lc3NhZ2VzOlxcbiAgICBpZiAobWVzc2FnZXMubGVuZ3RoKSB7XFxuICAgICAgICB7eyMgZGVmLm1vZGVsUG9zdEJhdGNoQ29kZSB9fSgnZGF0YWNoYW5nZXMnLCB7XFxuICAgICAgICAgICAgY2hhbmdlczogbWVzc2FnZXMsXFxuICAgICAgICAgICAgdHJhbnNhY3Rpb246IGluQ2hhbmdlVHJhbnNhY3Rpb25cXG4gICAgICAgIH0pO1xcblxcbiAgICAgICAgbWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbihtc2cpIHtcXG4gICAgICAgICAgICB7eyMgZGVmLm1vZGVsUG9zdE1lc3NhZ2VDb2RlIH19KG1zZy5wYXRoLCBtc2cpO1xcbiAgICAgICAgfSwgdGhpcyk7XFxuICAgIH1cXG4jfX1cXG5cIlxuICAgICwgaW5jbHVkZV9jcmVhdGVfdHJlZSA9IFwiJ3VzZSBzdHJpY3QnO1xcbi8qIE9ubHkgdXNlIHRoaXMgc3R5bGUgb2YgY29tbWVudHMsIG5vdCBcXFwiLy9cXFwiICovXFxuXFxuLyoqXFxuICogSW5zZXJ0cyBjb2RlIHRvIGNyZWF0ZSBtb2RlbCB0cmVlIGFzIG5lY2Nlc3NhcnkgZm9yIGBzZXRgIGFuZCBgc3BsaWNlYCBhY2Nlc3NvcnMgYW5kIHRvIGFkZCBtZXNzYWdlcyB0byBzZW5kIGxpc3QgaWYgdGhlIHRyZWUgY2hhbmdlcy5cXG4gKi9cXG57eyMjIGRlZi5jcmVhdGVUcmVlOm1ldGhvZDpcXG4gICAgdmFyIHdhc0RlZiA9IHRydWU7XFxuICAgIHZhciBvbGQgPSBtO1xcblxcbiAgICB7eyB2YXIgZW1wdHlQcm9wID0gaXQucGFyc2VkUGF0aFswXSAmJiBpdC5wYXJzZWRQYXRoWzBdLmVtcHR5OyB9fVxcbiAgICB7ez8gZW1wdHlQcm9wIH19XFxuICAgICAgICB7eyAvKiBjcmVhdGUgdG9wIGxldmVsIG1vZGVsIGlmIGl0IHdhcyBub3QgcHJldmlvdXNseSBkZWZpbmVkICovIH19XFxuICAgICAgICBpZiAoISBtKSB7XFxuICAgICAgICAgICAgbSA9IHt7IyBkZWYubW9kZWxBY2Nlc3NQcmVmaXggfX0gPSB7ez0gZW1wdHlQcm9wIH19O1xcbiAgICAgICAgICAgIHdhc0RlZiA9IGZhbHNlO1xcblxcbiAgICAgICAgICAgIGlmICh0aGlzLl9vcHRpb25zLnJlYWN0aXZlICE9PSBmYWxzZSkge1xcbiAgICAgICAgICAgICAgICB7eyMgZGVmLmFkZE1zZyB9fSAnJywgdHlwZTogJ2FkZGVkJyxcXG4gICAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IG0gfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgfVxcbiAgICB7ez8/fX1cXG4gICAgICAgIHt7PyBtZXRob2QgPT0gJ3NwbGljZScgfX1cXG4gICAgICAgICAgICBpZiAoISBtKSB7XFxuICAgICAgICB7ez99fVxcbiAgICAgICAgICAgICAgICBtID0ge3sjIGRlZi5tb2RlbEFjY2Vzc1ByZWZpeCB9fSA9IGNsb25lVHJlZSh2YWx1ZSk7XFxuICAgICAgICAgICAgICAgIHdhc0RlZiA9IHR5cGVvZiBvbGQgIT0gJ3VuZGVmaW5lZCc7XFxuICAgICAgICB7ez8gbWV0aG9kID09ICdzcGxpY2UnIH19XFxuICAgICAgICAgICAgfVxcbiAgICAgICAge3s/fX0gICAgICAgXFxuICAgIHt7P319XFxuXFxuXFxuICAgIHt7IC8qIGNyZWF0ZSBtb2RlbCB0cmVlIGlmIGl0IGRvZXNuJ3QgZXhpc3QgKi8gfX1cXG4gICAge3sgIHZhciBtb2RlbERhdGFQcm9wZXJ0eSA9ICcnO1xcbiAgICAgICAgdmFyIG5leHROb2RlID0gaXQucGFyc2VkUGF0aFswXTtcXG4gICAgICAgIHZhciBjb3VudCA9IGl0LnBhcnNlZFBhdGgubGVuZ3RoIC0gMTtcXG5cXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xcbiAgICAgICAgICAgIHZhciBjdXJyTm9kZSA9IG5leHROb2RlO1xcbiAgICAgICAgICAgIHZhciBjdXJyUHJvcCA9IGN1cnJOb2RlLnByb3BlcnR5O1xcbiAgICAgICAgICAgIG5leHROb2RlID0gaXQucGFyc2VkUGF0aFtpICsgMV07XFxuICAgICAgICAgICAgdmFyIGVtcHR5UHJvcCA9IG5leHROb2RlICYmIG5leHROb2RlLmVtcHR5O1xcbiAgICB9fVxcblxcbiAgICAgICAge3sjIGRlZi5jcmVhdGVUcmVlU3RlcCB9fVxcblxcbiAgICB7eyAgfSAvKiBmb3IgbG9vcCAqLyB9fVxcbiN9fVxcblxcblxcbi8qKlxcbiAqIEluc2VydHMgY29kZSB0byBjcmVhdGUgb25lIHN0ZXAgaW4gdGhlIG1vZGVsIHRyZWVcXG4gKi9cXG57eyMjIGRlZi5jcmVhdGVUcmVlU3RlcDpcXG4gICAge3sjIGRlZi5jaGFuZ2VBY2Nlc3NQYXRoIH19XFxuXFxuICAgIGlmICghIHt7IyBkZWYud2FzRGVmaW5lZCB9fSkgeyBcXG4gICAgICAgIHt7IC8qIHByb3BlcnR5IGRvZXMgbm90IGV4aXN0ICovIH19XFxuICAgICAgICBtID0gbXt7IyBkZWYuY3VyclByb3AgfX0gPSB7ez0gZW1wdHlQcm9wIH19O1xcblxcbiAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XFxuICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gYWNjZXNzUGF0aCwgdHlwZTogJ2FkZGVkJywgXFxuICAgICAgICAgICAgICAgICAgbmV3VmFsdWU6IG0gfSk7XFxuICAgICAgICB9XFxuXFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIG17eyMgZGVmLmN1cnJQcm9wIH19ICE9ICdvYmplY3QnKSB7XFxuICAgICAgICB7eyAvKiBwcm9wZXJ0eSBpcyBub3Qgb2JqZWN0ICovIH19XFxuICAgICAgICB2YXIgb2xkID0gbXt7IyBkZWYuY3VyclByb3AgfX07XFxuICAgICAgICBtID0gbXt7IyBkZWYuY3VyclByb3AgfX0gPSB7ez0gZW1wdHlQcm9wIH19O1xcblxcbiAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMucmVhY3RpdmUgIT09IGZhbHNlKSB7XFxuICAgICAgICAgICAge3sjIGRlZi5hZGRNc2cgfX0gYWNjZXNzUGF0aCwgdHlwZTogJ2NoYW5nZWQnLCBcXG4gICAgICAgICAgICAgICAgICBvbGRWYWx1ZTogb2xkLCBuZXdWYWx1ZTogbSB9KTtcXG4gICAgICAgIH1cXG5cXG4gICAgfSBlbHNlIHtcXG4gICAgICAgIHt7IC8qIHByb3BlcnR5IGV4aXN0cywganVzdCB0cmF2ZXJzZSBkb3duIHRoZSBtb2RlbCB0cmVlICovIH19XFxuICAgICAgICBtID0gbXt7IyBkZWYuY3VyclByb3AgfX07XFxuICAgIH1cXG4jfX1cXG5cIlxuICAgICwgaW5jbHVkZV90cmF2ZXJzZV90cmVlID0gXCIndXNlIHN0cmljdCc7XFxuLyogT25seSB1c2UgdGhpcyBzdHlsZSBvZiBjb21tZW50cywgbm90IFxcXCIvL1xcXCIgKi9cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvZGUgdG8gdHJhdmVyc2UgbW9kZWwgdHJlZSBmb3IgYGRlbGV0ZWAgYW5kIGBzcGxpY2VgIGFjY2Vzc29ycy5cXG4gKi9cXG57eyMjIGRlZi50cmF2ZXJzZVRyZWU6XFxuICAgIHt7IFxcbiAgICAgICAgdmFyIGNvdW50ID0gaXQucGFyc2VkUGF0aC5sZW5ndGgtMTtcXG5cXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykgeyBcXG4gICAgICAgICAgICB2YXIgY3Vyck5vZGUgPSBpdC5wYXJzZWRQYXRoW2ldO1xcbiAgICAgICAgICAgIHZhciBjdXJyUHJvcCA9IGN1cnJOb2RlLnByb3BlcnR5O1xcbiAgICB9fVxcbiAgICAgICAgICAgIHt7IyBkZWYudHJhdmVyc2VUcmVlU3RlcCB9fVxcblxcbiAgICB7eyB9IC8qIGZvciBsb29wICovXFxuXFxuICAgICAgICB2YXIgaSA9IGNvdW50O1xcbiAgICAgICAgd2hpbGUgKGktLSkgeyAvKiBjbG9zaW5nIGJyYWNlcyBmb3IgZWxzZSdzIGFib3ZlICovXFxuICAgIH19XFxuICAgICAgICAgICAgfVxcbiAgICB7eyB9IC8qIHdoaWxlIGxvb3AgKi8gfX1cXG4jfX1cXG5cXG5cXG4vKipcXG4gKiBJbnNlcnRzIGNvZGUgdG8gdHJhdmVyc2Ugb25lIHN0ZXAgaW4gdGhlIG1vZGVsIHRyZWVcXG4gKi9cXG57eyMjIGRlZi50cmF2ZXJzZVRyZWVTdGVwOlxcbiAgICBpZiAoISAobSAmJiBtLmhhc093blByb3BlcnR5ICYmIHt7IyBkZWYud2FzRGVmaW5lZH19ICkgKVxcbiAgICAgICAgdHJlZURvZXNOb3RFeGlzdCA9IHRydWU7XFxuICAgIGVsc2Uge1xcbiAgICAgICAgbSA9IG17eyMgZGVmLmN1cnJQcm9wIH19O1xcbiAgICAgICAge3sjIGRlZi5jaGFuZ2VBY2Nlc3NQYXRoIH19XFxuICAgIHt7IC8qIGJyYWNlIGZyb20gZWxzZSBpcyBub3QgY2xvc2VkIG9uIHB1cnBvc2UgLSBhbGwgYnJhY2VzIGFyZSBjbG9zZWQgaW4gd2hpbGUgbG9vcCAqLyB9fVxcbiN9fVxcblwiO1xuXG52YXIgZG90RGVmID0ge1xuICAgIGluY2x1ZGVfZGVmaW5lczogaW5jbHVkZV9kZWZpbmVzLFxuICAgIGluY2x1ZGVfY3JlYXRlX3RyZWU6IGluY2x1ZGVfY3JlYXRlX3RyZWUsXG4gICAgaW5jbHVkZV90cmF2ZXJzZV90cmVlOiBpbmNsdWRlX3RyYXZlcnNlX3RyZWUsXG4gICAgZ2V0UGF0aE5vZGVLZXk6IHBhdGhVdGlscy5nZXRQYXRoTm9kZUtleSxcbiAgICBtb2RlbEFjY2Vzc1ByZWZpeDogJ3RoaXMuX21vZGVsLl9kYXRhJyxcbiAgICBtb2RlbFBvc3RNZXNzYWdlQ29kZTogJ3RoaXMuX21vZGVsLl9pbnRlcm5hbE1lc3Nlbmdlci5wb3N0TWVzc2FnZScsXG4gICAgbW9kZWxQb3N0QmF0Y2hDb2RlOiAndGhpcy5fbW9kZWwucG9zdE1lc3NhZ2VTeW5jJyxcbiAgICBpbnRlcm5hbE1lc3NlbmdlcjogJ3RoaXMuX21vZGVsLl9pbnRlcm5hbE1lc3Nlbmdlcidcbn07XG5cbnZhciBtb2RlbERvdERlZiA9IF8oZG90RGVmKS5jbG9uZSgpLmV4dGVuZCh7XG4gICAgbW9kZWxBY2Nlc3NQcmVmaXg6ICd0aGlzLl9kYXRhJyxcbiAgICBtb2RlbFBvc3RNZXNzYWdlQ29kZTogJ3RoaXMuX2ludGVybmFsTWVzc2VuZ2VyLnBvc3RNZXNzYWdlJyxcbiAgICBtb2RlbFBvc3RCYXRjaENvZGU6ICd0aGlzLnBvc3RNZXNzYWdlU3luYycsXG4gICAgaW50ZXJuYWxNZXNzZW5nZXI6ICd0aGlzLl9pbnRlcm5hbE1lc3Nlbmdlcidcbn0pLl8oKTtcblxuXG52YXIgZG90U2V0dGluZ3MgPSBfLmNsb25lKGRvVC50ZW1wbGF0ZVNldHRpbmdzKTtcbmRvdFNldHRpbmdzLnN0cmlwID0gZmFsc2U7XG5cbnZhciBzeW50aGVzaXplcnMgPSBfLm1hcEtleXModGVtcGxhdGVzLCBmdW5jdGlvbih0bXBsKSB7XG4gICAgcmV0dXJuIGRvVC50ZW1wbGF0ZSh0bXBsLCBkb3RTZXR0aW5ncywgZG90RGVmKTsgXG59KTtcblxuXG52YXIgbW9kZWxTeW50aGVzaXplcnMgPSBfLm1hcFRvT2JqZWN0KFsnc2V0JywgJ2RlbCcsICdzcGxpY2UnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgIHJldHVybiBkb1QudGVtcGxhdGUodGVtcGxhdGVzW21ldGhvZE5hbWVdLCBkb3RTZXR0aW5ncywgbW9kZWxEb3REZWYpO1xufSk7XG5cblxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IHN5bnRoZXNpemVzIGFjY2Vzc29yIG1ldGhvZHMuXG4gKiBGdW5jdGlvbiBpcyBtZW1vaXplZCBzbyBhY2Nlc3NvcnMgYXJlIGNhY2hlZCAodXAgdG8gMTAwMCkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGggTW9kZWwvTW9kZWxQYXRoIGFjY2VzcyBwYXRoXG4gKiBAcGFyYW0ge0FycmF5fSBwYXJzZWRQYXRoIGFycmF5IG9mIHBhdGggbm9kZXNcbiAqIEByZXR1cm4ge09iamVjdFtGdW5jdGlvbl19XG4gKi9cbnZhciBzeW50aGVzaXplUGF0aE1ldGhvZHMgPSBfLm1lbW9pemUoX3N5bnRoZXNpemVQYXRoTWV0aG9kcywgdW5kZWZpbmVkLCAxMDAwKTtcblxuZnVuY3Rpb24gX3N5bnRoZXNpemVQYXRoTWV0aG9kcyhwYXRoLCBwYXJzZWRQYXRoKSB7XG4gICAgdmFyIG1ldGhvZHMgPSBfLm1hcEtleXMoc3ludGhlc2l6ZXJzLCBmdW5jdGlvbihzeW50aHN6cikge1xuICAgICAgICByZXR1cm4gX3N5bnRoZXNpemUoc3ludGhzenIsIHBhdGgsIHBhcnNlZFBhdGgpO1xuICAgIH0pO1xuICAgIHJldHVybiBtZXRob2RzO1xufVxuXG5cbnZhciBub3JtYWxpemVTcGxpY2VJbmRleCA9IG1vZGVsVXRpbHMubm9ybWFsaXplU3BsaWNlSW5kZXg7IC8vIHVzZWQgaW4gc3BsaWNlLmRvdC5qc1xuXG5cbmZ1bmN0aW9uIF9zeW50aGVzaXplKHN5bnRoZXNpemVyLCBwYXRoLCBwYXJzZWRQYXRoKSB7XG4gICAgdmFyIG1ldGhvZFxuICAgICAgICAsIG1ldGhvZENvZGUgPSBzeW50aGVzaXplcih7XG4gICAgICAgICAgICBwYXJzZWRQYXRoOiBwYXJzZWRQYXRoLFxuICAgICAgICAgICAgZ2V0UGF0aE5vZGVLZXk6IHBhdGhVdGlscy5nZXRQYXRoTm9kZUtleVxuICAgICAgICB9KTtcblxuICAgIHRyeSB7XG4gICAgICAgIGV2YWwobWV0aG9kQ29kZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBNb2RlbEVycm9yKCdNb2RlbFBhdGggbWV0aG9kIGNvbXBpbGF0aW9uIGVycm9yOyBwYXRoOiAnICsgcGF0aCArICcsIGNvZGU6ICcgKyBtZXRob2RDb2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWV0aG9kO1xuXG5cbiAgICAvLyBmdW5jdGlvbnMgdXNlZCBieSBtZXRob2RzIGBzZXRgLCBgZGVsZXRlYCBhbmQgYHNwbGljZWAgKHN5bnRoZXNpemVkIGJ5IHRlbXBsYXRlKVxuICAgIGZ1bmN0aW9uIGFkZENoYW5nZU1lc3NhZ2UobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgbXNnKSB7XG4gICAgICAgIG1lc3NhZ2VzLnB1c2gobXNnKTtcbiAgICAgICAgbWVzc2FnZXNIYXNoW21zZy5wYXRoXSA9IG1zZztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRUcmVlQ2hhbmdlc01lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIHJvb3RQYXRoLCBvbGRWYWx1ZSwgbmV3VmFsdWUpIHtcbiAgICAgICAgdmFyIG9sZElzVHJlZSA9IHZhbHVlSXNUcmVlKG9sZFZhbHVlKVxuICAgICAgICAgICAgLCBuZXdJc1RyZWUgPSB2YWx1ZUlzVHJlZShuZXdWYWx1ZSk7XG5cbiAgICAgICAgaWYgKG5ld0lzVHJlZSlcbiAgICAgICAgICAgIGFkZE1lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIHJvb3RQYXRoLCBuZXdWYWx1ZSwgJ2FkZGVkJywgJ25ld1ZhbHVlJyk7XG4gICAgICAgIFxuICAgICAgICBpZiAob2xkSXNUcmVlKVxuICAgICAgICAgICAgYWRkTWVzc2FnZXMobWVzc2FnZXMsIG1lc3NhZ2VzSGFzaCwgcm9vdFBhdGgsIG9sZFZhbHVlLCAncmVtb3ZlZCcsICdvbGRWYWx1ZScpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZE1lc3NhZ2VzKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIHJvb3RQYXRoLCBvYmosIG1zZ1R5cGUsIHZhbHVlUHJvcCkge1xuICAgICAgICBfYWRkTWVzc2FnZXMocm9vdFBhdGgsIG9iaik7XG5cblxuICAgICAgICBmdW5jdGlvbiBfYWRkTWVzc2FnZXMocm9vdFBhdGgsIG9iaikge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgICAgIHZhciBwYXRoU3ludGF4ID0gcm9vdFBhdGggKyAnWyQkXSc7XG4gICAgICAgICAgICAgICAgb2JqLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZE1lc3NhZ2UodmFsdWUsIGluZGV4LCBwYXRoU3ludGF4KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHBhdGhTeW50YXggPSByb290UGF0aCArICcuJCQnO1xuICAgICAgICAgICAgICAgIF8uZWFjaEtleShvYmosIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkTWVzc2FnZSh2YWx1ZSwga2V5LCBwYXRoU3ludGF4KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGFkZE1lc3NhZ2UodmFsdWUsIGtleSwgcGF0aFN5bnRheCkge1xuICAgICAgICAgICAgdmFyIHBhdGggPSBwYXRoU3ludGF4LnJlcGxhY2UoJyQkJywga2V5KVxuICAgICAgICAgICAgICAgICwgZXhpc3RpbmdNc2cgPSBtZXNzYWdlc0hhc2hbcGF0aF07XG5cbiAgICAgICAgICAgIGlmIChleGlzdGluZ01zZykge1xuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ01zZy50eXBlID09IG1zZ1R5cGUpXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignc2V0dGVyIGVycm9yOiBzYW1lIG1lc3NhZ2UgdHlwZSBwb3N0ZWQgb24gdGhlIHNhbWUgcGF0aCcpO1xuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleGlzdGluZ01zZy50eXBlID0gJ2NoYW5nZWQnO1xuICAgICAgICAgICAgICAgICAgICBleGlzdGluZ01zZ1t2YWx1ZVByb3BdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgbXNnID0geyBwYXRoOiBwYXRoLCB0eXBlOiBtc2dUeXBlIH07XG4gICAgICAgICAgICAgICAgbXNnW3ZhbHVlUHJvcF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBhZGRDaGFuZ2VNZXNzYWdlKG1lc3NhZ2VzLCBtZXNzYWdlc0hhc2gsIG1zZyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZUlzVHJlZSh2YWx1ZSkpXG4gICAgICAgICAgICAgICAgX2FkZE1lc3NhZ2VzKHBhdGgsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lVHJlZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWVJc05vcm1hbE9iamVjdCh2YWx1ZSlcbiAgICAgICAgICAgICAgICA/IF8uZGVlcENsb25lKHZhbHVlKVxuICAgICAgICAgICAgICAgIDogdmFsdWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcHJvdGVjdFZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiAhIHZhbHVlSXNOb3JtYWxPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICAgPyB2YWx1ZVxuICAgICAgICAgICAgICAgIDogQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZS5zbGljZSgpXG4gICAgICAgICAgICAgICAgICAgIDogT2JqZWN0LmNyZWF0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsdWVJc1RyZWUodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlSXNOb3JtYWxPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICAgJiYgT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB2YWx1ZUlzTm9ybWFsT2JqZWN0KHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsXG4gICAgICAgICAgICAgICAgJiYgdHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCJcbiAgICAgICAgICAgICAgICAmJiAhICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpXG4gICAgICAgICAgICAgICAgJiYgISAodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZEJhdGNoSWRzVG9NZXNzYWdlKG1zZywgYmF0Y2hJZCwgbXNnSWQpIHtcbiAgICAgICAgXy5kZWZpbmVQcm9wZXJ0aWVzKG1zZywge1xuICAgICAgICAgICAgX19iYXRjaF9pZDogYmF0Y2hJZCxcbiAgICAgICAgICAgIF9fbXNnX2lkOiBtc2dJZFxuICAgICAgICB9KTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBFeHBvcnRzIGBzeW50aGVzaXplYCBmdW5jdGlvbiB3aXRoIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogLSAubW9kZWxNZXRob2RzLnNldCAtIGBzZXRgIG1ldGhvZCBmb3IgTW9kZWxcbiAqIC0gLm1vZGVsTWV0aG9kcy5kZWwgLSBgZGVsYCBtZXRob2QgZm9yIE1vZGVsXG4gKiAtIC5tb2RlbE1ldGhvZHMuc3BsaWNlIC0gYHNwbGljZWAgbWV0aG9kIGZvciBNb2RlbFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IHN5bnRoZXNpemVQYXRoTWV0aG9kcztcblxudmFyIG1vZGVsTWV0aG9kcyA9IF8ubWFwS2V5cyhtb2RlbFN5bnRoZXNpemVycywgZnVuY3Rpb24oc3ludGhlc2l6ZXIpIHtcbiAgICByZXR1cm4gX3N5bnRoZXNpemUoc3ludGhlc2l6ZXIsICcnLCBbXSk7XG59KTtcblxuc3ludGhlc2l6ZVBhdGhNZXRob2RzLm1vZGVsTWV0aG9kcyA9IG1vZGVsTWV0aG9kcztcbiIsImFyZ3VtZW50c1s0XVs5MF1bMF0uYXBwbHkoZXhwb3J0cyxhcmd1bWVudHMpIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIGBtaWxvLnV0aWxgXG4gKi9cbnZhciB1dGlsID0ge1xuICAgIGxvZ2dlcjogcmVxdWlyZSgnLi9sb2dnZXInKSxcbiAgICBjaGVjazogcmVxdWlyZSgnLi9jaGVjaycpLFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB1dGlsO1xuIiwiYXJndW1lbnRzWzRdWzEwMl1bMF0uYXBwbHkoZXhwb3J0cyxhcmd1bWVudHMpIiwiYXJndW1lbnRzWzRdWzEwM11bMF0uYXBwbHkoZXhwb3J0cyxhcmd1bWVudHMpIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cblxuLyoqXG4gKiBbX19Qcm90b3R5cGUgZnVuY3Rpb25zX19dKHByb3RvX3Byb3RvdHlwZS5qcy5odG1sKVxuICpcbiAqIC0gW2V4dGVuZFByb3RvXShwcm90b19wcm90b3R5cGUuanMuaHRtbCNleHRlbmRQcm90bylcbiAqIC0gW2NyZWF0ZVN1YmNsYXNzXShwcm90b19wcm90b3R5cGUuanMuaHRtbCNjcmVhdGVTdWJjbGFzcylcbiAqIC0gW21ha2VTdWJjbGFzc10ocHJvdG9fcHJvdG90eXBlLmpzLmh0bWwjbWFrZVN1YmNsYXNzKVxuICogLSBbbmV3QXBwbHldKHByb3RvX3Byb3RvdHlwZS5qcy5odG1sI25ld0FwcGx5KVxuICovXG52YXIgcHJvdG90eXBlTWV0aG9kcyA9IHJlcXVpcmUoJy4vcHJvdG9fcHJvdG90eXBlJyk7XG5cblxuLyoqXG4gKiBbX19PYmplY3QgZnVuY3Rpb25zX19dKHByb3RvX29iamVjdC5qcy5odG1sKVxuICpcbiAqIC0gW2V4dGVuZF0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZXh0ZW5kKVxuICogLSBbY2xvbmVdKHByb3RvX29iamVjdC5qcy5odG1sI2Nsb25lKVxuICogLSBbZGVmaW5lUHJvcGVydHldKHByb3RvX29iamVjdC5qcy5odG1sI2RlZmluZVByb3BlcnR5KVxuICogLSBbZGVmaW5lUHJvcGVydGllc10ocHJvdG9fb2JqZWN0LmpzLmh0bWwjZGVmaW5lUHJvcGVydGllcylcbiAqIC0gW2RlZXBFeHRlbmRdKHByb3RvX29iamVjdC5qcy5odG1sI2RlZXBFeHRlbmQpXG4gKiAtIFtkZWVwQ2xvbmVdKHByb3RvX29iamVjdC5qcy5odG1sI2RlZXBDbG9uZSlcbiAqIC0gW2tleXNdKHByb3RvX29iamVjdC5qcy5odG1sI2tleXMpXG4gKiAtIFthbGxLZXlzXShwcm90b19vYmplY3QuanMuaHRtbCNhbGxLZXlzKVxuICogLSBbdmFsdWVzXShwcm90b19vYmplY3QuanMuaHRtbCN2YWx1ZXMpXG4gKiAtIFtrZXlPZl0ocHJvdG9fb2JqZWN0LmpzLmh0bWwja2V5T2YpXG4gKiAtIFthbGxLZXlzT2ZdKHByb3RvX29iamVjdC5qcy5odG1sI2FsbEtleXNPZilcbiAqIC0gW2VhY2hLZXldKHByb3RvX29iamVjdC5qcy5odG1sI2VhY2hLZXkpXG4gKiAtIFttYXBLZXlzXShwcm90b19vYmplY3QuanMuaHRtbCNtYXBLZXlzKVxuICogLSBbcmVkdWNlS2V5c10ocHJvdG9fb2JqZWN0LmpzLmh0bWwjcmVkdWNlS2V5cylcbiAqIC0gW2ZpbHRlcktleXNdKHByb3RvX29iamVjdC5qcy5odG1sI2ZpbHRlcktleXMpXG4gKiAtIFtzb21lS2V5XShwcm90b19vYmplY3QuanMuaHRtbCNzb21lS2V5KVxuICogLSBbZXZlcnlLZXldKHByb3RvX29iamVjdC5qcy5odG1sI2V2ZXJ5S2V5KVxuICogLSBbZmluZFZhbHVlXShwcm90b19vYmplY3QuanMuaHRtbCNmaW5kVmFsdWUpXG4gKiAtIFtmaW5kS2V5XShwcm90b19vYmplY3QuanMuaHRtbCNmaW5kS2V5KVxuICogLSBbcGlja0tleXNdKHByb3RvX29iamVjdC5qcy5odG1sI3BpY2tLZXlzKVxuICogLSBbb21pdEtleXNdKHByb3RvX29iamVjdC5qcy5odG1sI29taXRLZXlzKVxuICogLSBbaXNFcXVhbF0ocHJvdG9fb2JqZWN0LmpzLmh0bWwjaXNFcXVhbClcbiAqIC0gW2lzTm90XShwcm90b19vYmplY3QuanMuaHRtbCNpc05vdClcbiAqL1xudmFyIG9iamVjdE1ldGhvZHMgPSByZXF1aXJlKCcuL3Byb3RvX29iamVjdCcpO1xuXG5cbi8qKlxuICogW19fQXJyYXkgZnVuY3Rpb25zX19dKHByb3RvX2FycmF5LmpzLmh0bWwpXG4gKlxuICogLSBbZmluZF0ocHJvdG9fYXJyYXkuanMuaHRtbCNmaW5kKVxuICogLSBbZmluZEluZGV4XShwcm90b19hcnJheS5qcy5odG1sI2ZpbmRJbmRleClcbiAqIC0gW2FwcGVuZEFycmF5XShwcm90b19hcnJheS5qcy5odG1sI2FwcGVuZEFycmF5KVxuICogLSBbcHJlcGVuZEFycmF5XShwcm90b19hcnJheS5qcy5odG1sI3ByZXBlbmRBcnJheSlcbiAqIC0gW3NwbGljZUl0ZW1dKHByb3RvX2FycmF5LmpzLmh0bWwjc3BsaWNlSXRlbSlcbiAqIC0gW3RvQXJyYXldKHByb3RvX2FycmF5LmpzLmh0bWwjdG9BcnJheSlcbiAqIC0gW29iamVjdF0ocHJvdG9fYXJyYXkuanMuaHRtbCNvYmplY3QpXG4gKiAtIFttYXBUb09iamVjdF0ocHJvdG9fYXJyYXkuanMuaHRtbCNtYXBUb09iamVjdClcbiAqIC0gW3VuaXF1ZV0ocHJvdG9fYXJyYXkuanMuaHRtbCN1bmlxdWUpXG4gKiAtIFtkZWVwRm9yRWFjaF0ocHJvdG9fYXJyYXkuanMuaHRtbCNkZWVwRm9yRWFjaClcbiAqXG4gKiBGdW5jdGlvbnMgdGhhdCBBcnJheSBbaW1wbGVtZW50cyBuYXRpdmVseV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvcHJvdG90eXBlI01ldGhvZHMpIGFyZSBhbHNvIGFkZGVkIC0gdGhleSBjYW4gYmUgdXNlZCB3aXRoIGFycmF5LWxpa2Ugb2JqZWN0cyBhbmQgZm9yIGNoYWluaW5nIChuYXRpdmUgZnVuY3Rpb25zIGFyZSBhbHdheXMgY2FsbGVkKS5cbiAqL1xudmFyIGFycmF5TWV0aG9kcyA9IHJlcXVpcmUoJy4vcHJvdG9fYXJyYXknKTtcblxuXG4vKipcbiAqIFtfX0Z1bmN0aW9uIGZ1bmN0aW9uc19fXShwcm90b19mdW5jdGlvbi5qcy5odG1sKVxuICpcbiAqIC0gW21ha2VGdW5jdGlvbl0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNtYWtlRnVuY3Rpb24pXG4gKiAtIFtwYXJ0aWFsXShwcm90b19mdW5jdGlvbi5qcy5odG1sI3BhcnRpYWwpXG4gKiAtIFtwYXJ0aWFsUmlnaHRdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjcGFydGlhbFJpZ2h0KVxuICogLSBbbWVtb2l6ZV0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNtZW1vaXplKVxuICogLSBbZGVsYXldKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjZGVsYXkpXG4gKiAtIFtkZWZlcl0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNkZWZlcilcbiAqIC0gW2RlbGF5ZWRdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjZGVsYXllZClcbiAqIC0gW2RlZmVycmVkXShwcm90b19mdW5jdGlvbi5qcy5odG1sI2RlZmVycmVkKVxuICogLSBbZGVmZXJUaWNrc10ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNkZWZlclRpY2tzKVxuICogLSBbZGVsYXlNZXRob2RdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjZGVsYXlNZXRob2QpXG4gKiAtIFtkZWZlck1ldGhvZF0ocHJvdG9fZnVuY3Rpb24uanMuaHRtbCNkZWZlck1ldGhvZClcbiAqIC0gW2RlYm91bmNlXShwcm90b19mdW5jdGlvbi5qcy5odG1sI2RlYm91bmNlKVxuICogLSBbdGhyb3R0bGVdKHByb3RvX2Z1bmN0aW9uLmpzLmh0bWwjdGhyb3R0bGUpXG4gKiAtIFtvbmNlXShwcm90b19mdW5jdGlvbi5qcy5odG1sI29uY2UpXG4gKiAtIFt3YWl0Rm9yXShwcm90b19mdW5jdGlvbi5qcy5odG1sI3dhaXRGb3IpXG4qL1xudmFyIGZ1bmN0aW9uTWV0aG9kcyA9IHJlcXVpcmUoJy4vcHJvdG9fZnVuY3Rpb24nKTtcblxuXG4vKipcbiAqIFtfX1N0cmluZyBmdW5jdGlvbnNfX10ocHJvdG9fc3RyaW5nLmpzLmh0bWwpXG4gKlxuICogLSBbZmlyc3RVcHBlckNhc2VdKHByb3RvX3N0cmluZy5qcy5odG1sI2ZpcnN0VXBwZXJDYXNlKVxuICogLSBbZmlyc3RMb3dlckNhc2VdKHByb3RvX3N0cmluZy5qcy5odG1sI2ZpcnN0TG93ZXJDYXNlKVxuICogLSBbdG9SZWdFeHBdKHByb3RvX3N0cmluZy5qcy5odG1sI3RvUmVnRXhwKVxuICogLSBbdG9GdW5jdGlvbl0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjdG9GdW5jdGlvbilcbiAqIC0gW3RvRGF0ZV0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjdG9EYXRlKVxuICogLSBbdG9RdWVyeVN0cmluZ10ocHJvdG9fc3RyaW5nLmpzLmh0bWwjdG9RdWVyeVN0cmluZylcbiAqIC0gW2Zyb21RdWVyeVN0cmluZ10ocHJvdG9fc3RyaW5nLmpzLmh0bWwjZnJvbVF1ZXJ5U3RyaW5nKVxuICogLSBbanNvblBhcnNlXShwcm90b19zdHJpbmcuanMuaHRtbCNqc29uUGFyc2UpXG4gKiAtIFtoYXNoQ29kZV0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjaGFzaENvZGUpXG4gKiAtIFt1blByZWZpeF0ocHJvdG9fc3RyaW5nLmpzLmh0bWwjdW5QcmVmaXgpXG4gKi9cbnZhciBzdHJpbmdNZXRob2RzID0gcmVxdWlyZSgnLi9wcm90b19zdHJpbmcnKTtcblxuXG4vKipcbiAqIFtfX051bWJlciBmdW5jdGlvbnNfX10ocHJvdG9fbnVtYmVyLmpzLmh0bWwpXG4gKlxuICogLSBbaXNOdW1lcmljXShwcm90b19udW1iZXIuanMuaHRtbCNpc051bWVyaWMpXG4gKi9cbnZhciBudW1iZXJNZXRob2RzID0gcmVxdWlyZSgnLi9wcm90b19udW1iZXInKTtcblxuXG4vKipcbiAqIFtfX1V0aWxpdHkgZnVuY3Rpb25zX19dKHByb3RvX3V0aWwuanMuaHRtbClcbiAqXG4gKiAtIFt0aW1lc10ocHJvdG9fdXRpbC5qcy5odG1sI3RpbWVzKVxuICogLSBbcmVwZWF0XShwcm90b191dGlsLmpzLmh0bWwjcmVwZWF0KVxuICogLSBbdGFwXShwcm90b191dGlsLmpzLmh0bWwjdGFwKVxuICogLSBbcmVzdWx0XShwcm90b191dGlsLmpzLmh0bWwjcmVzdWx0KVxuICogLSBbaWRlbnRpdHldKHByb3RvX3V0aWwuanMuaHRtbCNpZGVudGl0eSlcbiAqIC0gW3Byb3BlcnR5XShwcm90b191dGlsLmpzLmh0bWwjcHJvcGVydHkpXG4gKiAtIFtjb21wYXJlUHJvcGVydHldKHByb3RvX3V0aWwuanMuaHRtbCNjb21wYXJlUHJvcGVydHkpXG4gKiAtIFtub29wXShwcm90b191dGlsLmpzLmh0bWwjbm9vcClcbiAqL1xudmFyIHV0aWxNZXRob2RzID0gcmVxdWlyZSgnLi9wcm90b191dGlsJyk7XG5cblxuLyoqXG4gKiBDaGFpbmluZ1xuICogPT09PT09PT1cbiAqXG4gKiBgX2AgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgd3JhcHBlZCB2YWx1ZSAob2JqZWN0LCBmdW5jdGlvbiwgYXJyYXksIGV0Yy4pIHRvIGFsbG93IGNoYWluaW5nIG9mIFByb3RvIGZ1bmN0aW9ucy5cbiAqIFRvIHVud3JhcCwgYF9gIG1ldGhvZCBvZiBhIHdyYXBwZWQgdmFsdWUgc2hvdWxkIGJlIHVzZWQuXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogdmFyIGFyciA9IF8oeyAwOiAzLCAxOiA0LCAyOiA1LCBsZW5ndGg6IDN9KVxuICogICAgICAgICAgICAgIC50b0FycmF5KClcbiAqICAgICAgICAgICAgICAucHJlcGVuZEFycmF5KFsxLCAyXSlcbiAqICAgICAgICAgICAgICAuYXBwZW5kQXJyYXkoWzYsIDcsIDhdKVxuICogICAgICAgICAgICAgIC5fKCk7XG4gKiBgYGBcbiAqIEEgd3JhcHBlZCBvYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgYF9gIChgUHJvdG9gIGNsYXNzKS5cbiAqXG4gKiBDaGFpbmluZyBpcyBpbXBsZW1lbnRlZCBmb3IgZGV2ZWxvcG1lbnQgY29udmVuaWVuY2UsIGJ1dCBpdCBoYXMgcGVyZm9ybWFuY2Ugb3ZlcmhlYWQsIG5vdCBvbmx5IHRvIHdyYXAgYW5kIHVud3JhcCB2YWx1ZXMgYnV0IGluIGVhY2ggZnVuY3Rpb24gY2FsbC5cbiAqIEFsdGhvdWdoIGFsbCBQcm90byBmdW5jdGlvbnMgYXJlIGltcGxlbWVudGVkIGFzIG1ldGhvZHMgb3BlcmF0aW5nIG9uIHRoaXMgYW5kIHRoZSBvdmVyaGVhZCB0byByZWRlZmluZSB0aGVtIGFzIGZ1bmN0aW9ucyBpcyB2ZXJ5IHNtYWxsLCB0aGUgb3ZlcmhlYWQgdG8gcmVkZWZpbmUgdGhlbSBhcyBtZXRob2RzIG9mIHdyYXBwZWQgdmFsdWUgaXMgc2xpZ2h0bHkgaGlnaGVyIC0gY2hhaW5pbmcgaXMgMTUtMjUlIHNsb3dlciB0aGFuIHVzaW5nIGZ1bmN0aW9ucyAocHJvcGVydGllcyBvZiBfIHRoYXQgdGFrZSB0aGUgZmlyc3QgcGFyYW1ldGVyKS5cbiAqIEluIGNhc2VzIHdoZW4gcGVyZm9ybWFuY2UgaXMgY3JpdGljYWwsIHlvdSBtYXkgd2FudCB0byBhdm9pZCB1c2luZyBjaGFpbmluZy5cbiAqXG4gKiBAcGFyYW0ge0FueX0gc2VsZiBBIHZhbHVlIHRvIGJlIHdyYXBwZWRcbiAqIEByZXR1cm4ge1Byb3RvfVxuICovXG5mdW5jdGlvbiBQcm90byhzZWxmKSB7XG4gICAgLy8gd3JhcCBwYXNzZWQgcGFyYW1ldGVyIGluIF8gb2JqZWN0XG4gICAgdmFyIHdyYXBwZWQgPSBPYmplY3QuY3JlYXRlKFByb3RvLnByb3RvdHlwZSk7XG4gICAgd3JhcHBlZC5zZWxmID0gc2VsZjtcbiAgICByZXR1cm4gd3JhcHBlZDtcbn07XG5cbnZhciBfID0gUHJvdG87XG5cblxuLy8gc3RvcmUgcmF3IG1ldGhvZHMgZnJvbSBkaWZmZXJlbnQgbW9kdWxlcyBpbiBfXyBvYmplY3QgKGRvdWJsZSBcIl9cIilcbnZhciBfXyA9IHt9O1xuXG5vYmplY3RNZXRob2RzLmV4dGVuZC5jYWxsKF9fLCBvYmplY3RNZXRob2RzKTtcbl9fLmV4dGVuZC5jYWxsKF9fLCBwcm90b3R5cGVNZXRob2RzKTtcbl9fLmV4dGVuZC5jYWxsKF9fLCBhcnJheU1ldGhvZHMpO1xuX18uZXh0ZW5kLmNhbGwoX18sIHN0cmluZ01ldGhvZHMpO1xuX18uZXh0ZW5kLmNhbGwoX18sIG51bWJlck1ldGhvZHMpO1xuX18uZXh0ZW5kLmNhbGwoX18sIGZ1bmN0aW9uTWV0aG9kcyk7XG5fXy5leHRlbmQuY2FsbChfXywgdXRpbE1ldGhvZHMpO1xuXG5cbi8vIGFkZCBfXyBhcyBwcm9wZXJ0eSBvZiBQcm90bywgc28gdGhleSBjYW4gYmUgdXNlZCBhcyBtaXhpbnMgaW4gb3RoZXIgY2xhc3Nlc1xuX18uZGVmaW5lUHJvcGVydHkoUHJvdG8sICdfXycsIF9fKTtcblxuXG4vLyBhZGQgXyBtZXRob2QgdG8gdW53cmFwIHdyYXBwZWQgdmFsdWUgKFByb3RvIGluc3RhbmNlKVxuZnVuY3Rpb24gdW53cmFwUHJvdG8oKSB7IHJldHVybiB0aGlzLnNlbGY7IH1cbl9fLmV4dGVuZFByb3RvLmNhbGwoUHJvdG8sIHsgXzogdW53cmFwUHJvdG8gfSk7XG5cbi8vIGFkZCBjb25zdGFudHMgKGZ1bmN0aW9ucyB3aWxsIGJlIG92ZXJ3cml0dGVuKVxuX18uZXh0ZW5kLmNhbGwoUHJvdG8sIG9iamVjdE1ldGhvZHMuX2NvbnN0YW50cyk7XG5cbi8vIGFkZCBmdW5jdGlvbnMgdGhhdCB0YWtlIGZpcnN0IHBhcmFtZXRlciBpbnN0ZWFkIG9mIFwidGhpc1wiIHRvIFByb3RvXG52YXIgcHJvdG9GdW5jcyA9IF9fLm1hcEtleXMuY2FsbChfXywgdXRpbHMubWFrZVByb3RvRnVuY3Rpb24sIHRydWUpO1xuX18uZXh0ZW5kLmNhbGwoUHJvdG8sIHByb3RvRnVuY3MpO1xuXG4vLyBhZGQgUHJvdG8gd3JhcHBlZCB2YWx1ZSBpbnN0YW5jZSBtZXRob2RzIHRvIFByb3RvIHByb3RvdHlwZVxudmFyIHByb3RvSW5zdGFuY2VNZXRob2RzID0gX18ubWFwS2V5cy5jYWxsKF9fLCB1dGlscy5tYWtlUHJvdG9JbnN0YW5jZU1ldGhvZCwgdHJ1ZSk7XG5fXy5leHRlbmRQcm90by5jYWxsKFByb3RvLCBwcm90b0luc3RhbmNlTWV0aG9kcyk7XG5cblxuLyoqXG4gKiBJbiB3aW5kb3dzIGVudmlyb25tZW50LCBhIGdsb2JhbCBgX2AgdmFsdWUgaXMgcHJlc2VydmVkIGluIGBfLnVuZGVyc2NvcmVgXG4gKi9cbmlmICh0eXBlb2Ygd2luZG93ID09ICdvYmplY3QnKSB7XG4gICAgLy8gcHJlc2VydmUgZXhpc3RpbmcgXyBvYmplY3RcbiAgICBpZiAod2luZG93Ll8pXG4gICAgICAgIFByb3RvLnVuZGVyc2NvcmUgPSB3aW5kb3cuX1xuXG4gICAgLy8gZXhwb3NlIGdsb2JhbCBfIGFuZCBQcm90b1xuICAgIHdpbmRvdy5fID0gUHJvdG87XG59XG5cbmlmICh0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKVxuICAgIC8vIGV4cG9ydCBmb3Igbm9kZS9icm93c2VyaWZ5XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBQcm90bztcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9fID0gcmVxdWlyZSgnLi9wcm90b19vYmplY3QnKVxuICAgICwgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG5cblxuLyoqXG4gKiAtIFtmaW5kXSgjZmluZClcbiAqIC0gW2ZpbmRJbmRleF0oI2ZpbmRJbmRleClcbiAqIC0gW2FwcGVuZEFycmF5XSgjYXBwZW5kQXJyYXkpXG4gKiAtIFtwcmVwZW5kQXJyYXldKCNwcmVwZW5kQXJyYXkpXG4gKiAtIFtzcGxpY2VJdGVtXSgjc3BsaWNlSXRlbSlcbiAqIC0gW3RvQXJyYXldKCN0b0FycmF5KVxuICogLSBbb2JqZWN0XSgjb2JqZWN0KVxuICogLSBbbWFwVG9PYmplY3RdKCNtYXBUb09iamVjdClcbiAqIC0gW3VuaXF1ZV0oI3VuaXF1ZSlcbiAqIC0gW2RlZXBGb3JFYWNoXSgjZGVlcEZvckVhY2gpXG4gKlxuICogVGhlc2UgbWV0aG9kcyBjYW4gYmUgW2NoYWluZWRdKHByb3RvLmpzLmh0bWwjUHJvdG8pLlxuICovXG52YXIgYXJyYXlNZXRob2RzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgLy8gZmluZDogc2VlIGJlbG93XG4gICAgLy8gZmluZEluZGV4OiBzZWUgYmVsb3dcbiAgICBhcHBlbmRBcnJheTogYXBwZW5kQXJyYXksXG4gICAgcHJlcGVuZEFycmF5OiBwcmVwZW5kQXJyYXksXG4gICAgdG9BcnJheTogdG9BcnJheSxcbiAgICBvYmplY3Q6IG9iamVjdCxcbiAgICBtYXBUb09iamVjdDogbWFwVG9PYmplY3QsXG4gICAgdW5pcXVlOiB1bmlxdWUsXG4gICAgZGVlcEZvckVhY2g6IGRlZXBGb3JFYWNoLFxuICAgIHNwbGljZUl0ZW06IHNwbGljZUl0ZW1cbn07XG5cblxuLyoqXG4gKiBGdW5jdGlvbnMgdGhhdCBBcnJheSBbaW1wbGVtZW50cyBuYXRpdmVseV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvcHJvdG90eXBlI01ldGhvZHMpIGFyZSBhbHNvIGluY2x1ZGVkIGZvciBjb252ZW5pZW5jZSAtIHRoZXkgY2FuIGJlIHVzZWQgd2l0aCBhcnJheS1saWtlIG9iamVjdHMgYW5kIGZvciBjaGFpbmluZyAobmF0aXZlIGZ1bmN0aW9ucyBhcmUgYWx3YXlzIGNhbGxlZCkuXG4gKiBUaGVzZSBtZXRob2RzIGNhbiBiZSBbY2hhaW5lZF0ocHJvdG8uanMuaHRtbCNQcm90bykgdG9vLlxuICovXG52YXIgbmF0aXZlQXJyYXlNZXRob2RzTmFtZXMgPSBbICdqb2luJywgJ3BvcCcsICdwdXNoJywgJ2NvbmNhdCcsXG4gICAgJ3JldmVyc2UnLCAnc2hpZnQnLCAndW5zaGlmdCcsICdzbGljZScsICdzcGxpY2UnLFxuICAgICdzb3J0JywgJ2ZpbHRlcicsICdmb3JFYWNoJywgJ3NvbWUnLCAnZXZlcnknLFxuICAgICdtYXAnLCAnaW5kZXhPZicsICdsYXN0SW5kZXhPZicsICdyZWR1Y2UnLCAncmVkdWNlUmlnaHQnXTtcblxudmFyIG5hdGl2ZUFycmF5TWV0aG9kcyA9IG1hcFRvT2JqZWN0LmNhbGwobmF0aXZlQXJyYXlNZXRob2RzTmFtZXMsXG4gICAgICAgIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGVbbWV0aG9kTmFtZV07XG4gICAgICAgIH0pO1xuXG5fXy5leHRlbmQuY2FsbChhcnJheU1ldGhvZHMsIG5hdGl2ZUFycmF5TWV0aG9kcyk7XG5cblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBFUzYgW0FycmF5IF9fZmluZF9fIG1ldGhvZF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZmluZCkgKG5hdGl2ZSBtZXRob2QgaXMgdXNlZCBpZiBhdmFpbGFibGUpLlxuICogUmV0dXJucyBhcnJheSBlbGVtZW50IHRoYXQgcGFzc2VzIGNhbGxiYWNrIHRlc3QuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gc2VsZiBhcnJheSB0byBzZWFyY2ggaW5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHNob3VsZCByZXR1cm4gYHRydWVgIGZvciBpdGVtIHRvIHBhc3MgdGhlIHRlc3QsIHBhc3NlZCBgdmFsdWVgLCBgaW5kZXhgIGFuZCBgc2VsZmAgYXMgcGFyYW1ldGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgb3B0aW9uYWwgY29udGV4dCAoYHRoaXNgKSBvZiBjYWxsYmFjayBjYWxsXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmFycmF5TWV0aG9kcy5maW5kID0gQXJyYXkucHJvdG90eXBlLmZpbmRcbiAgICB8fCB1dGlscy5tYWtlRmluZE1ldGhvZChhcnJheU1ldGhvZHMuZm9yRWFjaCwgJ3ZhbHVlJyk7XG5cblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBFUzYgW0FycmF5IF9fZmluZEluZGV4X18gbWV0aG9kXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9maW5kSW5kZXgpIChuYXRpdmUgbWV0aG9kIGlzIHVzZWQgaWYgYXZhaWxhYmxlKS5cbiAqIFJldHVybnMgdGhlIGluZGV4IG9mIGFycmF5IGVsZW1lbnQgdGhhdCBwYXNzZXMgY2FsbGJhY2sgdGVzdC4gUmV0dXJucyBgLTFgIGlmIG5vdCBmb3VuZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBzZWxmIGFycmF5IHRvIHNlYXJjaCBpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgc2hvdWxkIHJldHVybiBgdHJ1ZWAgZm9yIGl0ZW0gdG8gcGFzcyB0aGUgdGVzdCwgcGFzc2VkIGB2YWx1ZWAsIGBpbmRleGAgYW5kIGBzZWxmYCBhcyBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBvcHRpb25hbCBjb250ZXh0IChgdGhpc2ApIG9mIGNhbGxiYWNrIGNhbGxcbiAqIEByZXR1cm4ge0ludGVnZXJ9XG4gKi9cbmFycmF5TWV0aG9kcy5maW5kSW5kZXggPSBBcnJheS5wcm90b3R5cGUuZmluZEluZGV4XG4gICAgfHwgdXRpbHMubWFrZUZpbmRNZXRob2QoYXJyYXlNZXRob2RzLmZvckVhY2gsICdpbmRleCcpO1xuXG5cbi8qKlxuICogQXBwZW5kcyBgYXJyYXlUb0FwcGVuZGAgdG8gdGhlIGVuZCBvZiBhcnJheSBgc2VsZmAgaW4gcGxhY2UgKGNhbiBiZSBhbiBpbnN0YW5jZSBvZiBBcnJheSBvciBhcnJheS1saWtlIG9iamVjdCkuXG4gKiBDaGFuZ2VzIHRoZSB2YWx1ZSBvZiBgc2VsZmAgKGl0IHVzZXMgYEFycmF5LnByb3RvdHlwZS5zcGxpY2VgKSBhbmQgcmV0dXJucyBgc2VsZmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gc2VsZiBBbiBhcnJheSB0aGF0IHdpbGwgYmUgbW9kaWZpZWRcbiAqIEBwYXJhbSB7QXJyYXl8QXJyYXktbGlrZX0gYXJyYXlUb0FwcGVuZCBBbiBhcnJheSB0aGF0IHdpbGwgYmUgYXBwZW5kZWRcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBhcHBlbmRBcnJheShhcnJheVRvQXBwZW5kKSB7XG4gICAgaWYgKCEgYXJyYXlUb0FwcGVuZC5sZW5ndGgpIHJldHVybiB0aGlzO1xuICAgIGlmICghIEFycmF5LmlzQXJyYXkoYXJyYXlUb0FwcGVuZCkpXG4gICAgICAgIGFycmF5VG9BcHBlbmQgPSB0b0FycmF5LmNhbGwoYXJyYXlUb0FwcGVuZCk7XG4gICAgXG4gICAgdmFyIGFyZ3MgPSBbdGhpcy5sZW5ndGgsIDBdLmNvbmNhdChhcnJheVRvQXBwZW5kKTtcbiAgICBhcnJheU1ldGhvZHMuc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBQcmVwZW5kcyBgYXJyYXlUb1ByZXBlbmRgIHRvIHRoZSBiZWdpbm5pZyBvZiBhcnJheSBgc2VsZmAgaW4gcGxhY2UgKGNhbiBiZSBhbiBpbnN0YW5jZSBvZiBBcnJheSBvciBhcnJheS1saWtlIG9iamVjdCkuXG4gKiBDaGFuZ2VzIHRoZSB2YWx1ZSBvZiBgc2VsZmAgKGl0IHVzZXMgYEFycmF5LnByb3RvdHlwZS5zcGxpY2VgKSBhbmQgcmV0dXJucyBgc2VsZmAuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gc2VsZiBBbiBhcnJheSB0aGF0IHdpbGwgYmUgbW9kaWZpZWRcbiAqIEBwYXJhbSB7QXJyYXl8QXJyYXktbGlrZX0gYXJyYXlUb0FwcGVuZCBBbiBhcnJheSB0aGF0IHdpbGwgYmUgcHJlcGVuZGVkXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gcHJlcGVuZEFycmF5KGFycmF5VG9QcmVwZW5kKSB7XG4gICAgaWYgKCEgYXJyYXlUb1ByZXBlbmQubGVuZ3RoKSByZXR1cm4gdGhpcztcbiAgICBpZiAoISBBcnJheS5pc0FycmF5KGFycmF5VG9QcmVwZW5kKSlcbiAgICAgICAgYXJyYXlUb1ByZXBlbmQgPSB0b0FycmF5LmNhbGwoYXJyYXlUb1ByZXBlbmQpO1xuXG4gICAgdmFyIGFyZ3MgPSBbMCwgMF0uY29uY2F0KGFycmF5VG9QcmVwZW5kKTtcbiAgICBhcnJheU1ldGhvZHMuc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBSZW1vdmVzIGl0ZW0gZnJvbSBhcnJheSB0aGF0IGlzIGZvdW5kIHVzaW5nIGluZGV4T2YgKGkuZS4gJz09PScpXG4gKiBNb2RpZmllcyBvcmlnaW5hbCBhcnJheSBhbmQgcmV0dXJucyB0aGUgcmVmZXJlbmNlIHRvIGl0LlxuICogXG4gKiBAcGFyYW0ge0FycmF5fSBzZWxmIEFuIGFycmF5IHRoYXQgd2lsbCBiZSBtb2RpZmllZFxuICogQHBhcmFtICB7QW55fSBpdGVtIGl0ZW0gdG8gYmUgcmVtb3ZlZFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHNwbGljZUl0ZW0oaXRlbSkge1xuICAgIHZhciBpbmRleCA9IHRoaXMuaW5kZXhPZihpdGVtKTtcbiAgICBpZiAoaW5kZXggPj0gMCkgdGhpcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBuZXcgYXJyYXkgY3JlYXRlZCBmcm9tIGFycmF5LWxpa2Ugb2JqZWN0IChlLmcuLCBgYXJndW1lbnRzYCBwc2V1ZG8tYXJyYXkpLlxuICpcbiAqIEBwYXJhbSB7QXJyYXktbGlrZX0gc2VsZiBPYmplY3Qgd2l0aCBudW1lcmljIHByb3BlcnR5IGxlbmd0aFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHRvQXJyYXkoKSB7XG4gICAgcmV0dXJuIGFycmF5TWV0aG9kcy5zbGljZS5jYWxsKHRoaXMpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBhbiBvYmplY3QgY3JlYXRlZCBmcm9tIHRoZSBhcnJheSBvZiBga2V5c2AgYW5kIG9wdGlvbmFsIGFycmF5IG9mIGB2YWx1ZXNgLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlbGYgQXJyYXkgb2Yga2V5c1xuICogQHBhcmFtIHtBcnJheXxhbnl9IHZhbHVlcyBPcHRpb25hbCBhcnJheSBvZiB2YWx1ZXMgb3IgdGhlIHZhbHVlIHRvIGJlIGFzc2lnbmVkIHRvIGVhY2ggcHJvcGVydHkuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIG9iamVjdCh2YWx1ZXMpIHtcbiAgICB2YXIgb2JqID0ge31cbiAgICAgICAgLCB2YWx1ZXNJc0FycmF5ID0gQXJyYXkuaXNBcnJheSh2YWx1ZXMpO1xuICAgIGFycmF5TWV0aG9kcy5mb3JFYWNoLmNhbGwodGhpcywgZnVuY3Rpb24oa2V5LCBpbmRleCkge1xuICAgICAgICBvYmpba2V5XSA9IHZhbHVlc0lzQXJyYXkgPyB2YWx1ZXNbaW5kZXhdIDogdmFsdWVzO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG9iajtcbn1cblxuXG4vKipcbiAqIE1hcHMgYXJyYXkgdG8gb2JqZWN0LlxuICogQXJyYXkgZWxlbWVudHMgYmVjb21lIGtleXMsIHZhbHVlIGFyZSB0YWtlbiBmcm9tIGBjYWxsYmFja2AuXG4gKiBcbiAqIEBwYXJhbSB7QXJyYXl9IHNlbGYgQW4gYXJyYXkgd2hpY2ggdmFsdWVzIHdpbGwgYmVjb21lIGtleXMgb2YgdGhlIHJlc3VsdFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2sgaXMgcGFzc2VkIGB2YWx1ZWAsIGBpbmRleGAgYW5kIGBzZWxmYCBhbmQgc2hvdWxkIHJldHVybiB2YWx1ZSB0aGF0IHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIEFuIG9wdGlvbmFsIGNvbnRleHQgb2YgaXRlcmF0aW9uICh0aGUgdmFsdWVvZiBgdGhpc2ApLCB3aWxsIGJlIHVuZGVmaW5lZCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgcGFzc2VkLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBtYXBUb09iamVjdChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHRoaXMsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgICByZXN1bHRbdmFsdWVdID0gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIHRoaXMpO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGFycmF5IHdpdGhvdXQgZHVwbGljYXRlcy4gRG9lcyBub3QgbW9kaWZ5IG9yaWdpbmFsIGFycmF5LlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlbGYgb3JpZ2luYWwgYXJyYXlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGNvbXBhcmlzb24gZnVuY3Rpb24sIHNob3VsZCByZXR1cm4gdHJ1ZSBmb3IgZXF1YWwgaXRlbXMsIFwiPT09XCIgaXMgdXNlZCBpZiBub3QgcGFzc2VkLlxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHVuaXF1ZShjYWxsYmFjaykge1xuICAgIHZhciBmaWx0ZXJlZCA9IFtdO1xuICAgIGlmICghIGNhbGxiYWNrKVxuICAgICAgICBpdGVtSW5kZXggPSBpdGVtSW5kZXhPZjtcblxuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGl0ZW1JbmRleChpdGVtKTtcbiAgICAgICAgaWYgKGluZGV4ID09IC0xKVxuICAgICAgICAgICAgZmlsdGVyZWQucHVzaChpdGVtKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBmaWx0ZXJlZDtcblxuXG4gICAgZnVuY3Rpb24gaXRlbUluZGV4KGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TWV0aG9kcy5maW5kSW5kZXguY2FsbChmaWx0ZXJlZCwgZnVuY3Rpb24oaXQpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhpdGVtLCBpdCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGl0ZW1JbmRleE9mKGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGZpbHRlcmVkLmluZGV4T2YoaXRlbSk7XG4gICAgfVxufVxuXG5cbi8qKlxuICogSXRlcmF0ZXMgYXJyYXkgYW5kIGVsZW1lbnRzIHRoYXQgYXJlIGFycmF5cyBjYWxsaW5nIGNhbGxiYWNrIHdpdGggZWFjaCBlbGVtZW50IHRoYXQgaXMgbm90IGFuIGFycmF5LiBDYW4gYmUgdXNlZCB0byBpdGVyYXRlIG92ZXIgYXJndW1lbnRzIGxpc3QgdG8gYXZvaWQgY2hlY2tpbmcgd2hldGhlciBhcnJheSBvciBsaXN0IG9mIHBhcmFtZXRlcnMgaXMgcGFzc2VkLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl8QXJyYXktbGlrZX0gc2VsZiBhcnJheSBvZiBlbGVtZW50cyBhbmQgYXJyYXlzdG8gaXRlcmF0ZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGNhbGxlZCBmb3IgZWFjaCBpdGVtIHRoYXQgaXMgbm90IGFuIGFycmF5LiBDYWxsYmFjayBpcyBwYXNzZWQgaXRlbSwgaW5kZXggYW5kIG9yaWdpbmFsIGFycmF5IGFzIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge0FueX0gdGhpc0FyZyBvcHRpb25hbCBjYWxsYmFjayBlbnZvY2F0aW9uIGNvbnRleHRcbiAqL1xuZnVuY3Rpb24gZGVlcEZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICB2YXIgaW5kZXggPSAwLCBhcnIgPSB0aGlzO1xuICAgIF9kZWVwRm9yRWFjaC5jYWxsKHRoaXMpO1xuXG4gICAgZnVuY3Rpb24gX2RlZXBGb3JFYWNoKCkge1xuICAgICAgICBhcnJheU1ldGhvZHMuZm9yRWFjaC5jYWxsKHRoaXMsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpXG4gICAgICAgICAgICAgICAgX2RlZXBGb3JFYWNoLmNhbGwodmFsdWUpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWUsIGluZGV4KyssIGFycik7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbWFrZVByb3RvRnVuY3Rpb24gPSByZXF1aXJlKCcuL3V0aWxzJykubWFrZVByb3RvRnVuY3Rpb25cbiAgICAsIHJlcGVhdCA9IHJlcXVpcmUoJy4vcHJvdG9fdXRpbCcpLnJlcGVhdDtcblxuXG4vKipcbiAqIC0gW21ha2VGdW5jdGlvbl0oI21ha2VGdW5jdGlvbilcbiAqIC0gW3BhcnRpYWxdKCNwYXJ0aWFsKVxuICogLSBbcGFydGlhbFJpZ2h0XSgjcGFydGlhbFJpZ2h0KVxuICogLSBbbWVtb2l6ZV0oI21lbW9pemUpXG4gKiAtIFtkZWxheV0oI2RlbGF5KVxuICogLSBbZGVmZXJdKCNkZWZlcilcbiAqIC0gW2RlbGF5ZWRdKCNkZWxheWVkKVxuICogLSBbZGVmZXJyZWRdKCNkZWZlcnJlZClcbiAqIC0gW2RlZmVyVGlja3NdKCNkZWZlclRpY2tzKVxuICogLSBbZGVsYXlNZXRob2RdKCNkZWxheU1ldGhvZClcbiAqIC0gW2RlZmVyTWV0aG9kXSgjZGVmZXJNZXRob2QpXG4gKiAtIFtkZWJvdW5jZV0oI2RlYm91bmNlKVxuICogLSBbdGhyb3R0bGVdKCN0aHJvdHRsZSlcbiAqIC0gW29uY2VdKCNvbmNlKVxuICogLSBbd2FpdEZvcl0oI3dhaXRGb3IpXG4gKiAtIFtub3RdKCNub3QpXG4gKlxuICogVGhlc2UgbWV0aG9kcyBjYW4gYmUgW2NoYWluZWRdKHByb3RvLmpzLmh0bWwjUHJvdG8pXG4gKi9cbnZhciBmdW5jdGlvbk1ldGhvZHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBtYWtlRnVuY3Rpb246IG1ha2VGdW5jdGlvbixcbiAgICBwYXJ0aWFsOiBwYXJ0aWFsLFxuICAgIHBhcnRpYWxSaWdodDogcGFydGlhbFJpZ2h0LFxuICAgIG1lbW9pemU6IG1lbW9pemUsXG4gICAgZGVsYXk6IGRlbGF5LFxuICAgIGRlZmVyOiBkZWZlcixcbiAgICBkZWxheWVkOiBkZWxheWVkLFxuICAgIGRlZmVycmVkOiBkZWZlcnJlZCxcbiAgICBkZWZlclRpY2tzOiBkZWZlclRpY2tzLFxuICAgIGRlbGF5TWV0aG9kOiBkZWxheU1ldGhvZCxcbiAgICBkZWZlck1ldGhvZDogZGVmZXJNZXRob2QsXG4gICAgZGVib3VuY2U6IGRlYm91bmNlLFxuICAgIHRocm90dGxlOiB0aHJvdHRsZSxcbiAgICBvbmNlOiBvbmNlLFxuICAgIHdhaXRGb3I6IHdhaXRGb3IsXG4gICAgbm90OiBub3Rcbn07XG5cblxudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG5cbi8qKlxuICogU2ltaWxhcmx5IHRvIEZ1bmN0aW9uIGNvbnN0cnVjdG9yIGNyZWF0ZXMgYSBmdW5jdGlvbiBmcm9tIGNvZGUuXG4gKiBVbmxpa2UgRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhIGZ1bmN0aW9uIG5hbWVcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBuZXcgZnVuY3Rpb24gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd9IGFyZzEsIGFyZzIsIC4uLiB0aGUgbmFtZXMgb2YgZnVuY3Rpb24gcGFyYW1ldGVyc1xuICogQHBhcmFtIHtTdHJpbmd9IGZ1bmNCb2R5IGZ1bmN0aW9uIGJvZHlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBtYWtlRnVuY3Rpb24oYXJnMSwgYXJnMiwgZnVuY0JvZHkpIHtcbiAgICB2YXIgbmFtZSA9IHRoaXNcbiAgICAgICAgLCBjb3VudCA9IGFyZ3VtZW50cy5sZW5ndGggLSAxXG4gICAgICAgICwgZnVuY0JvZHkgPSBhcmd1bWVudHNbY291bnRdXG4gICAgICAgICwgZnVuY1xuICAgICAgICAsIGNvZGUgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspXG4gICAgICAgIGNvZGUgKz0gJywgJyArIGFyZ3VtZW50c1tpXTtcbiAgICBjb2RlID0gWydmdW5jID0gZnVuY3Rpb24gJywgbmFtZSwgJygnLCBjb2RlLnNsaWNlKDIpLCAnKSB7XFxuJ1xuICAgICAgICAgICAgICAgICwgZnVuY0JvZHksICdcXG59J10uam9pbignJyk7XG4gICAgZXZhbChjb2RlKTtcbiAgICByZXR1cm4gZnVuYztcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBhcyBhIHJlc3VsdCBvZiBwYXJ0aWFsIGZ1bmN0aW9uIGFwcGxpY2F0aW9uIHdpdGggdGhlIHBhc3NlZCBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgRnVuY3Rpb24gdG8gYmUgYXBwbGllZFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgQXJndW1lbnRzIGFmdGVyIHNlbGYgd2lsbCBiZSBwcmVwZW5kZWQgdG8gdGhlIG9yaWdpbmFsIGZ1bmN0aW9uIGNhbGwgd2hlbiB0aGUgcGFydGlhbCBmdW5jdGlvbiBpcyBjYWxsZWQuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gcGFydGlhbCgpIHsgLy8gLCAuLi4gYXJndW1lbnRzXG4gICAgdmFyIGZ1bmMgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBhcyBhIHJlc3VsdCBvZiBwYXJ0aWFsIGZ1bmN0aW9uIGFwcGxpY2F0aW9uIHdpdGggdGhlIHBhc3NlZCBwYXJhbWV0ZXJzLCBidXQgcGFyYW1ldGVycyBhcmUgYXBwZW5kZWQgb24gdGhlIHJpZ2h0LlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgRnVuY3Rpb24gdG8gYmUgYXBwbGllZFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgQXJndW1lbnRzIGFmdGVyIHNlbGYgd2lsbCBiZSBhcHBlbmRlZCBvbiB0aGUgcmlnaHQgdG8gdGhlIG9yaWdpbmFsIGZ1bmN0aW9uIGNhbGwgd2hlbiB0aGUgcGFydGlhbCBmdW5jdGlvbiBpcyBjYWxsZWQuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gcGFydGlhbFJpZ2h0KCkgeyAvLyAsIC4uLiBhcmd1bWVudHNcbiAgICB2YXIgZnVuYyA9IHRoaXM7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBzbGljZS5jYWxsKGFyZ3VtZW50cykuY29uY2F0KGFyZ3MpKTtcbiAgICB9O1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhIG1lbW9pemVkIHZlcnNpb24gb2YgdGhlIGZ1bmN0aW9uIHVzaW5nIHN1cHBsaWVkIGhhc2ggZnVuY3Rpb24gYXMga2V5LiBJZiB0aGUgaGFzaCBpcyBub3Qgc3VwcGxpZWQsIHVzZXMgaXRzIGZpcnN0IHBhcmFtZXRlciBhcyB0aGUgaGFzaC5cbiAqIFxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBmdW5jdGlvbiB0byBiZSBtZW1vaXplZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFzaEZ1bmMgb3B0aW9uYWwgaGFzaCBmdW5jdGlvbiB0aGF0IGlzIHBhc3NlZCBhbGwgZnVuY3Rpb24gYXJndW1lbnRzIGFuZCBzaG91bGQgcmV0dXJuIGNhY2hlIGtleS5cbiAqIEBwYXJhbSB7SW50ZWdlcn0gbGltaXQgb3B0aW9uYWwgbWF4aW11bSBudW1iZXIgb2YgcmVzdWx0cyB0byBiZSBzdG9yZWQgaW4gdGhlIGNhY2hlLiAxMDAwIGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gbWVtb2l6ZWQgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gbWVtb2l6ZShoYXNoRnVuYywgbGltaXQpIHtcbiAgICB2YXIgZnVuYyA9IHRoaXM7XG4gICAgdmFyIGNhY2hlID0ge30sIGtleXNMaXN0ID0gW107XG4gICAgbGltaXQgPSBsaW1pdCB8fCAxMDAwO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIga2V5ID0gaGFzaEZ1bmMgPyBoYXNoRnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogYXJndW1lbnRzWzBdO1xuICAgICAgICBpZiAoY2FjaGUuaGFzT3duUHJvcGVydHkoa2V5KSlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZVtrZXldO1xuXG4gICAgICAgIHZhciByZXN1bHQgPSBjYWNoZVtrZXldID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICBrZXlzTGlzdC5wdXNoKGtleSk7XG5cbiAgICAgICAgaWYgKGtleXNMaXN0Lmxlbmd0aCA+IGxpbWl0KVxuICAgICAgICAgICAgZGVsZXRlIGNhY2hlW2tleXNMaXN0LnNoaWZ0KCldO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIERlbGF5cyBmdW5jdGlvbiBleGVjdXRpb24gYnkgYSBnaXZlbiB0aW1lIGluIG1pbGxpc2Vjb25kcy5cbiAqIFRoZSBjb250ZXh0IGluIGZ1bmN0aW9uIHdoZW4gaXQgaXMgZXhlY3V0ZWQgaXMgc2V0IHRvIGBudWxsYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGZ1bmN0aW9uIHRoYXQgZXhlY3V0aW9uIGhhcyB0byBiZSBkZWxheWVkXG4gKiBAcGFyYW0ge051bWJlcn0gd2FpdCBhcHByb3hpbWF0ZSBkYWxheSB0aW1lIGluIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgb3B0aW9uYWwgYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIGRlbGF5KHdhaXQpIHsgLy8gLCBhcmd1bWVudHNcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gX2RlbGF5KHRoaXMsIHdhaXQsIGFyZ3MpO1xufVxuIFxuXG4vKipcbiAqIERlZmVycyBmdW5jdGlvbiBleGVjdXRpb24gKGV4ZWN1dGVzIGFzIHNvb24gYXMgZXhlY3V0aW9uIGxvb3AgYmVjb21lcyBmcmVlKVxuICogVGhlIGNvbnRleHQgaW4gZnVuY3Rpb24gd2hlbiBpdCBpcyBleGVjdXRlZCBpcyBzZXQgdG8gYG51bGxgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gdGhhdCBleGVjdXRpb24gaGFzIHRvIGJlIGRlbGF5ZWRcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIG9wdGlvbmFsIGFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBkZWZlcigpIHsgLy8gLCBhcmd1bWVudHNcbiAgICByZXR1cm4gX2RlbGF5KHRoaXMsIDEsIGFyZ3VtZW50cyk7XG59XG5cbmZ1bmN0aW9uIF9kZWxheShmdW5jLCB3YWl0LCBhcmdzLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuYy5hcHBseS5iaW5kKGZ1bmMsIGNvbnRleHQgfHwgbnVsbCwgYXJncyksIHdhaXQpO1xufVxuXG4vKipcbiAqIFNhbWUgYXMgXy5kZWZlciwgdGFrZXMgZmlyc3QgYXJndW1lbnQgYXMgdGhlIGZ1bmN0aW9uIHRvIGJlIGRlZmVycmVkXG4gKi9cbnZhciBkZWZlckZ1bmMgPSBtYWtlUHJvdG9GdW5jdGlvbihkZWZlcik7XG5cbi8qKlxuICogRGVmZXJzIGZ1bmN0aW9uIGV4ZWN1dGlvbiBmb3IgYHRpbWVzYCB0aWNrcyAoZXhlY3V0ZXMgYWZ0ZXIgZXhlY3V0aW9uIGxvb3AgYmVjb21lcyBmcmVlIGB0aW1lc2AgdGltZXMpXG4gKiBUaGUgY29udGV4dCBpbiBmdW5jdGlvbiB3aGVuIGl0IGlzIGV4ZWN1dGVkIGlzIHNldCB0byBgbnVsbGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBmdW5jdGlvbiB0aGF0IGV4ZWN1dGlvbiBoYXMgdG8gYmUgZGVsYXllZFxuICogQHBhcmFtIHtJbnRlZ2VyfSB0aWNrcyBudW1iZXIgb2YgdGltZXMgdG8gZGVmZXIgZXhlY3V0aW9uXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBvcHRpb25hbCBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gZGVmZXJUaWNrcyh0aWNrcykgeyAvLyAsIGFyZ3VtZW50c1xuICAgIGlmICh0aWNrcyA8IDIpIHJldHVybiBkZWZlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHZhciBhcmdzID0gcmVwZWF0LmNhbGwoZGVmZXJGdW5jLCB0aWNrcyAtIDEpO1xuICAgIGFyZ3MgPSBhcmdzLmNvbmNhdCh0aGlzLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpOyBcbiAgICByZXR1cm4gZGVmZXJGdW5jLmFwcGx5KG51bGwsIGFyZ3MpO1xufVxuXG5cbi8qKlxuICogV29ya3MgbGlrZSBfLmRlbGF5IGJ1dCBhbGxvd3MgdG8gZGVmZXIgbWV0aG9kIGNhbGwgb2YgYHNlbGZgIHdoaWNoIHdpbGwgYmUgdGhlIGZpcnN0IF8uZGVsYXlNZXRob2QgcGFyYW1ldGVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgb2JqZWN0IHRvIGRlbGF5IG1ldGhvZCBjYWxsIG9mXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gZnVuY09yTWV0aG9kTmFtZSBmdW5jdGlvbiBvciBuYW1lIG9mIG1ldGhvZFxuICogQHBhcmFtIHtOdW1iZXJ9IHdhaXQgYXBwcm94aW1hdGUgZGFsYXkgdGltZSBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSB7TGlzdH0gYXJndW1lbnRzIGFyZ3VtZW50cyB0byBwYXNzIHRvIG1ldGhvZFxuICovXG5mdW5jdGlvbiBkZWxheU1ldGhvZChmdW5jT3JNZXRob2ROYW1lLCB3YWl0KSB7IC8vICwgLi4uIGFyZ3VtZW50c1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgIHJldHVybiBfZGVsYXlNZXRob2QodGhpcywgZnVuY09yTWV0aG9kTmFtZSwgd2FpdCwgYXJncyk7XG59XG5cblxuLyoqXG4gKiBXb3JrcyBsaWtlIF8uZGVmZXIgYnV0IGFsbG93cyB0byBkZWZlciBtZXRob2QgY2FsbCBvZiBgc2VsZmAgd2hpY2ggd2lsbCBiZSB0aGUgZmlyc3QgXy5kZWZlck1ldGhvZCBwYXJhbWV0ZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBvYmplY3QgdG8gZGVmZXIgbWV0aG9kIGNhbGwgb2ZcbiAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfSBmdW5jT3JNZXRob2ROYW1lIGZ1bmN0aW9uIG9yIG5hbWUgb2YgbWV0aG9kXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBhcmd1bWVudHMgdG8gcGFzcyB0byBtZXRob2RcbiAqL1xuZnVuY3Rpb24gZGVmZXJNZXRob2QoZnVuY09yTWV0aG9kTmFtZSkgeyAvLyAsIC4uLiBhcmd1bWVudHNcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gX2RlbGF5TWV0aG9kKHRoaXMsIGZ1bmNPck1ldGhvZE5hbWUsIDEsIGFyZ3MpO1xufVxuXG5mdW5jdGlvbiBfZGVsYXlNZXRob2Qob2JqZWN0LCBmdW5jT3JNZXRob2ROYW1lLCB3YWl0LCBhcmdzKSB7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBmdW5jID0gdHlwZW9mIGZ1bmNPck1ldGhvZE5hbWUgPT0gJ3N0cmluZydcbiAgICAgICAgICAgICAgICAgICAgPyBvYmplY3RbZnVuY09yTWV0aG9kTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgOiBmdW5jT3JNZXRob2ROYW1lO1xuICAgICAgICBmdW5jLmFwcGx5KG9iamVjdCwgYXJncyk7XG4gICAgfSwgd2FpdCk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGZ1bmN0aW9uIHRoYXQgd2lsbCBleGVjdXRlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBgd2FpdGAgbXMgYWZ0ZXIgaXQgaGFzIGJlZW4gY2FsbGVkXG4gKiBUaGUgY29udGV4dCBpbiBmdW5jdGlvbiB3aGVuIGl0IGlzIGV4ZWN1dGVkIGlzIHNldCB0byBgbnVsbGAuXG4gKiBBcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbiBhcmUgYXBwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBwYXNzZWQgdG8gZGVsYXllZC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGZ1bmN0aW9uIHdoaWNoIGV4ZWN1dGlvbiBoYXMgdG8gYmUgZGVmZXJyZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3YWl0IGFwcHJveGltYXRlIGRhbGF5IHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0ge0xpc3R9IGFyZ3VtZW50cyBvcHRpb25hbCBhcmd1bWVudHMgdGhhdCB3aWxsIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb25cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBkZWxheWVkKHdhaXQpIHsgLy8sIC4uLiBhcmd1bWVudHNcbiAgICB2YXIgZnVuYyA9IHRoaXNcbiAgICAgICAgLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgLy8gLi4uIGFyZ3VtZW50c1xuICAgICAgICB2YXIgcGFzc0FyZ3MgPSBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgICAgICByZXR1cm4gX2RlbGF5KGZ1bmMsIHdhaXQsIHBhc3NBcmdzLCB0aGlzKTtcbiAgICB9O1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBmdW5jdGlvbiB0aGF0IHdpbGwgZXhlY3V0ZSB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gb24gdGhlIG5leHQgdGljayBvbmNlIGl0IGhhcyBiZWVuIGNhbGxlZFxuICogVGhlIGNvbnRleHQgaW4gZnVuY3Rpb24gd2hlbiBpdCBpcyBleGVjdXRlZCBpcyBzZXQgdG8gYG51bGxgLlxuICogQXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gYXJlIGFwcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgcGFzc2VkIHRvIGRlZmVycmVkLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gd2hpY2ggZXhlY3V0aW9uIGhhcyB0byBiZSBkZWZlcnJlZFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgb3B0aW9uYWwgYXJndW1lbnRzIHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gZGVmZXJyZWQoKSB7IC8vLCAuLi4gYXJndW1lbnRzXG4gICAgdmFyIGZ1bmMgPSB0aGlzXG4gICAgICAgICwgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7IC8vIC4uLiBhcmd1bWVudHNcbiAgICAgICAgdmFyIHBhc3NBcmdzID0gYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKTtcbiAgICAgICAgcmV0dXJuIF9kZWxheShmdW5jLCAxLCBwYXNzQXJncywgdGhpcyk7XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgY2FsbCBvcmlnaW5hbCBmdW5jdGlvbiBvbmNlIGl0IGhhcyBub3QgYmVlbiBjYWxsZWQgZm9yIGEgc3BlY2lmaWVkIHRpbWVcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGZ1bmN0aW9uIHRoYXQgZXhlY3V0aW9uIGhhcyB0byBiZSBkZWxheWVkXG4gKiBAcGFyYW0ge051bWJlcn0gd2FpdCBhcHByb3hpbWF0ZSBkYWxheSB0aW1lIGluIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtCb29sZWFufSBpbW1lZGlhdGUgdHJ1ZSB0byBpbnZva2UgZnVuY2l0b24gaW1tZWRpYXRlbHkgYW5kIHRoZW4gaWdub3JlIGZvbGxvd2luZyBjYWxscyBmb3Igd2FpdCBtaWxsaXNlY29uZHNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBkZWJvdW5jZSh3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICB2YXIgZnVuYyA9IHRoaXM7IC8vIGZpcnN0IHBhcmFtZXRlciBvZiBfLmRlYm91bmNlXG4gICAgdmFyIHRpbWVvdXQsIGFyZ3MsIGNvbnRleHQsIHRpbWVzdGFtcCwgcmVzdWx0O1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgY29udGV4dCA9IHRoaXM7IC8vIHN0b3JlIG9yaWdpbmFsIGNvbnRleHRcbiAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdmFyIGNhbGxOb3cgPSBpbW1lZGlhdGUgJiYgISB0aW1lb3V0O1xuICAgICAgICBpZiAoISB0aW1lb3V0KVxuICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICAgICAgICBpZiAoY2FsbE5vdylcbiAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAgICAgZnVuY3Rpb24gbGF0ZXIoKSB7XG4gICAgICAgICAgICB2YXIgbGFzdCA9IERhdGUubm93KCkgLSB0aW1lc3RhbXA7XG4gICAgICAgICAgICBpZiAobGFzdCA8IHdhaXQpXG4gICAgICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQgLSBsYXN0KTtcbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmICghIGltbWVkaWF0ZSlcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIHdoZW4gaW52b2tlZCwgd2lsbCBvbmx5IGJlIHRyaWdnZXJlZCBhdCBtb3N0IG9uY2UgZHVyaW5nIGEgZ2l2ZW4gd2luZG93IG9mIHRpbWUuIFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb24gdGhhdCBleGVjdXRpb24gaGFzIHRvIGJlIGRlbGF5ZWRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3YWl0IGFwcHJveGltYXRlIGRlbGF5IHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBge2xlYWRpbmc6IGZhbHNlfWAgdG8gZGlzYWJsZSB0aGUgZXhlY3V0aW9uIG9uIHRoZSBsZWFkaW5nIGVkZ2VcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiB0aHJvdHRsZSh3YWl0LCBvcHRpb25zKSB7XG4gICAgdmFyIGZ1bmMgPSB0aGlzOyAvLyBmaXJzdCBwYXJhbWV0ZXIgb2YgXy50aHJvdHRsZVxuICAgIHZhciBjb250ZXh0LCBhcmdzLCByZXN1bHQ7XG4gICAgdmFyIHRpbWVvdXQgPSBudWxsO1xuICAgIHZhciBwcmV2aW91cyA9IDA7XG4gICAgb3B0aW9ucyB8fCAob3B0aW9ucyA9IHt9KTtcblxuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGlmICghcHJldmlvdXMgJiYgb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSkgcHJldmlvdXMgPSBub3c7XG4gICAgICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdyAtIHByZXZpb3VzKTtcbiAgICAgICAgY29udGV4dCA9IHRoaXM7XG4gICAgICAgIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGlmIChyZW1haW5pbmcgPD0gMCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXRpbWVvdXQgJiYgb3B0aW9ucy50cmFpbGluZyAhPT0gZmFsc2UpXG4gICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBsYXRlcigpIHtcbiAgICAgICAgcHJldmlvdXMgPSBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlID8gMCA6IERhdGUubm93KCk7XG4gICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIENhbGwgcGFzc2VkIGZ1bmN0aW9uIG9ubHkgb25jZVxuICogQHJldHVybiB7RnVuY3Rpb259IHNlbGZcbiAqL1xuZnVuY3Rpb24gb25jZSgpIHtcbiAgICB2YXIgZnVuYyA9IHRoaXNcbiAgICAgICAgLCByYW4gPSBmYWxzZVxuICAgICAgICAsIG1lbW87XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAocmFuKSByZXR1cm4gbWVtbztcbiAgICAgICAgcmFuID0gdHJ1ZTtcbiAgICAgICAgbWVtbyA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgZnVuYyA9IG51bGw7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgIH07XG59XG5cblxuLyoqXG4gKiBFeGVjdXRlIGEgZnVuY3Rpb24gd2hlbiB0aGUgY29uZGl0aW9uIGZ1bmN0aW9uIHJldHVybnMgYSB0cnV0aHkgdmFsdWVcbiAqIGl0IHJ1bnMgdGhlIGNvbmRpdGlvbiBmdW5jdGlvbiBldmVyeSBgY2hlY2tJbnRlcnZhbGAgbWlsbGlzZWNvbmRzIChkZWZhdWx0IDUwKVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGYgZnVuY3Rpb246IGlmIGl0IHJldHVybnMgdHJ1ZSB0aGUgY2FsbGJhY2sgaXMgZXhlY3V0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHJ1bnMgd2hlbiB0aGUgY29uZGl0aW9uIGlzIHRydWVcbiAqIEBwYXJhbSB7TnVtYmVyfSBtYXhUaW1lb3V0IHRpbWVvdXQgYmVmb3JlIGdpdmluZyB1cCAodGltZSBpbiBtaWxsaXNlY29uZHMpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aW1lZE91dEZ1bmMgYSBmdW5jdGlvbiBjYWxsZWQgaWYgdGltZW91dCBpcyByZWFjaGVkXG4gKiBAcGFyYW0ge051bWJlcn0gY2hlY2tJbnRlcnZhbCB0aW1lIGludGVydmFsIHdoZW4geW91IHJ1biB0aGUgY29uZGl0aW9uIGZ1bmN0aW9uICh0aW1lIGluIG1pbGxpc2Vjb25kcyksIGRlZmF1bHQgNTAgbXNcbiAqL1xuZnVuY3Rpb24gd2FpdEZvcihjYWxsYmFjaywgbWF4VGltZW91dCwgdGltZWRPdXRGdW5jLCBjaGVja0ludGVydmFsKXtcbiAgICB2YXIgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHZhciBjb25kaXRpb24gPSB0aGlzO1xuICAgIGNoZWNrSW50ZXJ2YWwgPSBjaGVja0ludGVydmFsIHx8IDUwO1xuICAgIHZhciBpbnRlcnZhbCA9IHNldEludGVydmFsKHRlc3RDb25kaXRpb24sIGNoZWNrSW50ZXJ2YWwpO1xuXG4gICAgZnVuY3Rpb24gdGVzdENvbmRpdGlvbigpIHtcbiAgICAgICAgaWYgKGNvbmRpdGlvbigpKSBjYWxsYmFjaygpO1xuICAgICAgICBlbHNlIGlmIChEYXRlLm5vdygpIC0gc3RhcnQgPj0gbWF4VGltZW91dClcbiAgICAgICAgICAgIHRpbWVkT3V0RnVuYyAmJiB0aW1lZE91dEZ1bmMoKTtcbiAgICAgICAgZWxzZSByZXR1cm47XG4gICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgIH07XG59XG5cblxuLyoqXG4gKiByZXR1cm5zIHRoZSBmdW5jdGlvbiB0aGF0IG5lZ2F0ZXMgKCEgb3BlcmF0b3IpIHRoZSByZXN1bHQgb2YgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxmIGZ1bmN0aW9uIHRvIG5lZ2F0ZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIG5vdCgpIHtcbiAgICB2YXIgZnVuYyA9IHRoaXM7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gIWZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIC0gW2lzTnVtZXJpY10oI2lzTnVtZXJpYylcbiAqL1xudmFyIG51bWJlck1ldGhvZHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBpc051bWVyaWM6IGlzTnVtZXJpY1xufTtcblxuXG4vKipcbiAqIEZ1bmN0aW9uIHRvIHRlc3QgaWYgYSB2YWx1ZSBpcyBudW1lcmljXG4gKlxuICogQHBhcmFtIHtBbnl9IHNlbGYgdmFsdWUgdG8gYmUgdGVzdGVkXG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIGl0IGlzIGEgbnVtZXJpYyB2YWx1ZVxuICovXG5mdW5jdGlvbiBpc051bWVyaWMoKSB7XG4gICAgcmV0dXJuICFpc05hTihwYXJzZUZsb2F0KHRoaXMpKSAmJiBpc0Zpbml0ZSh0aGlzKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xuXG5cbi8qKlxuICogLSBbZXh0ZW5kXSgjZXh0ZW5kKVxuICogLSBbY2xvbmVdKCNjbG9uZSlcbiAqIC0gW2RlZmluZVByb3BlcnR5XSgjZGVmaW5lUHJvcGVydHkpXG4gKiAtIFtkZWZpbmVQcm9wZXJ0aWVzXSgjZGVmaW5lUHJvcGVydGllcylcbiAqIC0gW2RlZXBFeHRlbmRdKCNkZWVwRXh0ZW5kKVxuICogLSBbZGVlcENsb25lXSgjZGVlcENsb25lKVxuICogLSBba2V5c10oI2tleXMpXG4gKiAtIFthbGxLZXlzXSgjYWxsS2V5cylcbiAqIC0gW3ZhbHVlc10oI3ZhbHVlcylcbiAqIC0gW2tleU9mXSgja2V5T2YpXG4gKiAtIFthbGxLZXlzT2ZdKCNhbGxLZXlzT2YpXG4gKiAtIFtlYWNoS2V5XSgjZWFjaEtleSlcbiAqIC0gW21hcEtleXNdKCNtYXBLZXlzKVxuICogLSBbcmVkdWNlS2V5c10oI3JlZHVjZUtleXMpXG4gKiAtIFtmaWx0ZXJLZXlzXSgjZmlsdGVyS2V5cylcbiAqIC0gW3NvbWVLZXldKCNzb21lS2V5KVxuICogLSBbZXZlcnlLZXldKCNldmVyeUtleSlcbiAqIC0gW2ZpbmRWYWx1ZV0oI2ZpbmRWYWx1ZSlcbiAqIC0gW2ZpbmRLZXldKCNmaW5kS2V5KVxuICogLSBbcGlja0tleXNdKCNwaWNrS2V5cylcbiAqIC0gW29taXRLZXlzXSgjb21pdEtleXMpXG4gKiAtIFtpc0VxdWFsXSgjaXNFcXVhbClcbiAqIC0gW2lzTm90XSgjaXNOb3QpXG4gKlxuICogQWxsIHRoZXNlIG1ldGhvZHMgY2FuIGJlIFtjaGFpbmVkXShwcm90by5qcy5odG1sI1Byb3RvKVxuICovXG52YXIgb2JqZWN0TWV0aG9kcyA9IG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGV4dGVuZDogZXh0ZW5kLFxuICAgIGNsb25lOiBjbG9uZSxcbiAgICBkZWZpbmVQcm9wZXJ0eTogZGVmaW5lUHJvcGVydHksXG4gICAgZGVmaW5lUHJvcGVydGllczogZGVmaW5lUHJvcGVydGllcyxcbiAgICBkZWVwRXh0ZW5kOiBkZWVwRXh0ZW5kLFxuICAgIGRlZXBDbG9uZTogZGVlcENsb25lLFxuICAgIGtleXM6IGtleXMsXG4gICAgYWxsS2V5czogYWxsS2V5cyxcbiAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICBrZXlPZjoga2V5T2YsXG4gICAgYWxsS2V5c09mOiBhbGxLZXlzT2YsXG4gICAgZWFjaEtleTogZWFjaEtleSxcbiAgICBtYXBLZXlzOiBtYXBLZXlzLFxuICAgIHJlZHVjZUtleXM6IHJlZHVjZUtleXMsXG4gICAgZmlsdGVyS2V5czogZmlsdGVyS2V5cyxcbiAgICBzb21lS2V5OiBzb21lS2V5LFxuICAgIGV2ZXJ5S2V5OiBldmVyeUtleSxcbiAgICBwaWNrS2V5czogcGlja0tleXMsXG4gICAgb21pdEtleXM6IG9taXRLZXlzLFxuICAgIGlzRXF1YWw6IGlzRXF1YWwsXG4gICAgaXNOb3Q6IGlzTm90XG59O1xuXG5cbi8qKlxuICogIyMjI1Byb3BlcnR5IGRlc2NyaXB0b3IgY29uc3RhbnRzIyMjI1xuICogVGhlIHN1bSBvZiB0aGVzZSBjb25zdGFudHMgY2FuIGJlIHVzZWQgYXMgbGFzdCBwYXJhbWV0ZXIgb2YgZGVmaW5lUHJvcGVydHkgYW5kIGRlZmluZVByb3BlcnRpZXMgdG8gZGV0ZXJtaW5lIHR5cGVzIG9mIHByb3BlcnRpZXMuXG4gKi9cbnZhciBjb25zdGFudHMgPSB7XG4gICAgRU5VTUVSQUJMRTogMSxcbiAgICBFTlVNOiAxLFxuICAgIENPTkZJR1VSQUJMRTogMixcbiAgICBDT05GOiAyLFxuICAgIFdSSVRBQkxFOiA0LFxuICAgIFdSSVQ6IDRcbn07XG5cbmRlZmluZVByb3BlcnR5LmNhbGwob2JqZWN0TWV0aG9kcywgJ19jb25zdGFudHMnLCBjb25zdGFudHMpO1xuXG5cbi8qKlxuICogQW5hbG9ndWUgb2YgRVM2IFtBcnJheSBfX2ZpbmRfXyBtZXRob2RdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2ZpbmQpLlxuICogUmV0dXJucyB0aGUgdmFsdWUgb2Ygb2JqZWN0IHByb3BlcnR5IHRoYXQgcGFzc2VzIGNhbGxiYWNrIHRlc3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgb2JqZWN0IHRvIHNlYXJjaCBpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgc2hvdWxkIHJldHVybiBgdHJ1ZWAgZm9yIGl0ZW0gdG8gcGFzcyB0aGUgdGVzdCwgcGFzc2VkIGB2YWx1ZWAsIGBrZXlgIGFuZCBgc2VsZmAgYXMgcGFyYW1ldGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgb3B0aW9uYWwgY29udGV4dCAoYHRoaXNgKSBvZiBjYWxsYmFjayBjYWxsXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIGB0cnVlYCB0byBpdGVyYXRlIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICogQHJldHVybiB7QW55fVxuICovXG5vYmplY3RNZXRob2RzLmZpbmRWYWx1ZSA9IHV0aWxzLm1ha2VGaW5kTWV0aG9kKGVhY2hLZXksICd2YWx1ZScpO1xuXG5cbi8qKlxuICogQW5hbG9ndWUgb2YgRVM2IFtBcnJheSBfX2ZpbmRJbmRleF9fIG1ldGhvZF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZmluZEluZGV4KS5cbiAqIFJldHVybnMgdGhlIGtleSBvZiBvYmplY3QgcHJvcGVydHkgdGhhdCBwYXNzZXMgY2FsbGJhY2sgdGVzdC4gUmV0dXJucyBgdW5kZWZpbmVkYCBpZiBub3QgZm91bmQgKHVubGlrZSBgZmluZEluZGV4YCwgdGhhdCByZXR1cm5zIC0xIGluIHRoaXMgY2FzZSkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgb2JqZWN0IHRvIHNlYXJjaCBpblxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgc2hvdWxkIHJldHVybiBgdHJ1ZWAgZm9yIGl0ZW0gdG8gcGFzcyB0aGUgdGVzdCwgcGFzc2VkIGB2YWx1ZWAsIGBrZXlgIGFuZCBgc2VsZmAgYXMgcGFyYW1ldGVyc1xuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgb3B0aW9uYWwgY29udGV4dCAoYHRoaXNgKSBvZiBjYWxsYmFjayBjYWxsXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIGB0cnVlYCB0byBpdGVyYXRlIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICogQHJldHVybiB7SW50ZWdlcn1cbiAqL1xub2JqZWN0TWV0aG9kcy5maW5kS2V5ID0gdXRpbHMubWFrZUZpbmRNZXRob2QoZWFjaEtleSwgJ2tleScpO1xuXG5cbi8qKlxuICogRXh0ZW5kcyBvYmplY3QgYHNlbGZgIHdpdGggdGhlIHByb3BlcnRpZXMgb2YgdGhlIG9iamVjdCBgb2JqYCBjb3B5aW5nIGFsbCBvd24gcHJvcGVydGllcyAobm90IHRob3NlIGluaGVyaXRlZCB2aWEgcHJvdG90eXBlIGNoYWluKSwgaW5jbHVkaW5nIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgKHVubGVzcyBgb25seUVudW1lcmFibGVgIGlzIHRydXRoeSkuXG4gKiBDcmVhdGVkIHByb3BlcnRpZXMgd2lsbCBoYXZlIHRoZSBzYW1lIGRlc2NyaXB0b3JzIGFzIHRoZSBwcm9wZXJ0aXMgb2YgYG9iamAuXG4gKiBSZXR1cm5zIGBzZWxmYCB0byBhbGxvdyBjaGFpbmluZyB3aXRoIG90aGVyIGZ1bmN0aW9ucy5cbiAqIENhbiBiZSB1c2VkIHdpdGggZnVuY3Rpb25zLCB0byBjb3B5IGNsYXNzIG1ldGhvZHMsIGUuZy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3QgdG8gYmUgZXh0ZW5kZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogQW4gb2JqZWN0IHdoaWNoIHByb3BlcnRpZXMgd2lsbCBiZSBjb3BpZWQgdG8gc2VsZlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBPcHRpb25hbCBmbGFnIHRvIHByZXZlbnQgY29weWluZyBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzLCBgZmFsc2VgIGJ5IGRlZmF1bHRcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZXh0ZW5kKG9iaiwgb25seUVudW1lcmFibGUpIHtcbiAgICB2YXIgZGVzY3JpcHRvcnMgPSB7fTtcblxuICAgIGVhY2hLZXkuY2FsbChvYmosIGZ1bmN0aW9uKHZhbHVlLCBwcm9wKSB7XG4gICAgICAgIGRlc2NyaXB0b3JzW3Byb3BdID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIHByb3ApO1xuICAgIH0sIHRoaXMsIG9ubHlFbnVtZXJhYmxlKTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIGRlc2NyaXB0b3JzKTtcblxuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogTWFrZXMgYSBzaGFsbG93IGNsb25lIG9mIG9iamVjdCBgb2JqYCBjcmVhdGluZyBhbiBpbnN0YW5jZSBvZiB0aGUgc2FtZSBjbGFzczsgdGhlIHByb3BlcnRpZXMgd2lsbCBoYXZlIHRoZSBzYW1lIGRlc2NyaXB0b3JzLlxuICogVG8gY2xvbmUgYW4gYXJyYXkgdXNlXG4gKiBgYGBcbiAqIHZhciBjbG9uZWRBcnJheSA9IFtdLmNvbmNhdChhcnIpO1xuICogYGBgXG4gKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBub3QgYmUgdXNlZCB0byBjbG9uZSBhbiBhcnJheSwgYmVjYXVzZSBpdCBpcyBpbmVmZmljaWVudC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3QgdG8gYmUgY2xvbmVkXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGNsb25lKCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMpKSByZXR1cm4gdGhpcy5zbGljZSgpO1xuICAgIGlmICh0aGlzIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIG5ldyBEYXRlKHRoaXMpO1xuICAgIGlmICh0aGlzIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gbmV3IFJlZ0V4cCh0aGlzKTtcbiAgICB2YXIgY2xvbmVkT2JqZWN0ID0gT2JqZWN0LmNyZWF0ZSh0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gICAgZXh0ZW5kLmNhbGwoY2xvbmVkT2JqZWN0LCB0aGlzKTtcbiAgICByZXR1cm4gY2xvbmVkT2JqZWN0O1xufVxuXG5cbi8qKlxuICogU3ludGF4IHN1Z2FyIHRvIHNob3J0ZW4gdXNhZ2Ugb2YgYE9iamVjdC5kZWZpbmVQcm9wZXJ0eWAuXG4gKiBUaGUgc2ltcGxlc3QgdXNhZ2UgKHRvIGFkZCBub24tZW51bWVyYWJsZSwgbm9uLWNvbmZpZ3VyYWJsZSwgbm9uLXdyaXRhYmxlIHByb3BlcnR5KTpcbiAqIGBgYFxuICogXy5kZWZpbmVQcm9wZXJ0eShvYmosICdrZXknLCB2YWx1ZSk7XG4gKiBgYGBcbiAqXG4gKiBUbyBkZWZpbmUgc29tZSBvdGhlciBwcm9wZXJ0aWVzIHVzZSBzdW0gb2YgdGhlIGZsYWdzIGBfLkVOVU1FUkFCTEVgIChvciBgXy5FTlVNYCksIGBfLkNPTkZJR1VSQUJMRWAgKG9yIGBfLkNPTkZgKSBhbmQgYF8uV1JJVEFCTEVgIChvciBgXy5XUklUYCk6XG4gKiBgYGBcbiAqIF8uZGVmaW5lUHJvcGVydHkob2JqLCAna2V5JywgdmFsdWUsIF8uRU5VTSArIF8uV1JJVCk7XG4gKiBgYGBcbiAqIFJldHVybnMgYHNlbGZgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBhZGQgYSBwcm9wZXJ0eSB0b1xuICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5TmFtZSB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdGhhdCB3aWxsIGJlIGFkZGVkXG4gKiBAcGFyYW0ge0FueX0gdmFsdWUgdGhlIHZhbHVlIG9mIGFkZGVkIHByb3BlcnR5XG4gKiBAcGFyYW0ge0ludGVnZXJ9IGRlY3JpcHRvckZsYWdzIGJpdCBtYXNrIG9mIHByb3BlcnR5IGRlc2NyaXB0b3IgcHJvcGVydGllcyBjb21wb3NlZCBmcm9tIGBfLkVOVU1FUkFCTEVgIChvciBgXy5FTlVNYCksIGBfLkNPTkZJR1VSQUJMRWAgKG9yIGBfLkNPTkZgKSBhbmQgYF8uV1JJVEFCTEVgIChvciBgXy5XUklUYClcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkocHJvcGVydHlOYW1lLCB2YWx1ZSwgZGVjcmlwdG9yRmxhZ3MpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgcHJvcGVydHlOYW1lLFxuICAgICAgICBfZ2V0RGVzY3JpcHRvcih2YWx1ZSwgZGVjcmlwdG9yRmxhZ3MpKTtcbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG5mdW5jdGlvbiBfZ2V0RGVzY3JpcHRvcih2YWx1ZSwgZGVjcmlwdG9yRmxhZ3MpIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHsgdmFsdWU6IHZhbHVlIH07XG4gICAgaWYgKGRlY3JpcHRvckZsYWdzKVxuICAgICAgICBleHRlbmQuY2FsbChkZXNjcmlwdG9yLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiAhISAoZGVjcmlwdG9yRmxhZ3MgJiBjb25zdGFudHMuRU5VTUVSQUJMRSksXG4gICAgICAgICAgICBjb25maWd1cmFibGU6ICEhIChkZWNyaXB0b3JGbGFncyAmIGNvbnN0YW50cy5DT05GSUdVUkFCTEUpLFxuICAgICAgICAgICAgd3JpdGFibGU6ICEhIChkZWNyaXB0b3JGbGFncyAmIGNvbnN0YW50cy5XUklUQUJMRSlcbiAgICAgICAgfSk7XG5cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbn1cblxuXG4vKipcbiAqIFN5bnRheCBzdWdhciB0byBzaG9ydGVuIHVzYWdlIG9mIGBPYmplY3QuZGVmaW5lUHJvcGVydGllc2AuXG4gKiBUaGUgc2ltcGxlc3QgdXNhZ2UgKHRvIGFkZCBub24tZW51bWVyYWJsZSwgbm9uLWNvbmZpZ3VyYWJsZSwgbm9uLXdyaXRhYmxlIHByb3BlcnRpZXMpOlxuICogYGBgXG4gKiBfLmRlZmluZVByb3BlcnRpZXMob2JqLCB7XG4gKiAgICAga2V5MTogdmFsdWUxLFxuICogICAgIGtleTI6IHZhbHVlMlxuICogfSk7XG4gKiBgYGBcbiAqIFRvIGRlZmluZSBzb21lIG90aGVyIHByb3BlcnRpZXMgdXNlIHN1bSBvZiB0aGUgZmxhZ3MgYF8uRU5VTUVSQUJMRWAgKG9yIGBfLkVOVU1gKSwgYF8uQ09ORklHVVJBQkxFYCAob3IgYF8uQ09ORmApIGFuZCBgXy5XUklUQUJMRWAgKG9yIGBfLldSSVRgKTpcbiAqIGBgYFxuICogXy5kZWZpbmVQcm9wZXJ0aWVzKG9iaiwge1xuICogICAgIGtleTE6IHZhbHVlMSxcbiAqICAgICBrZXkyOiB2YWx1ZTJcbiAqIH0sIF8uRU5VTSArIF8uV1JJVCk7XG4gKiBgYGBcbiAqIFJldHVybnMgYHNlbGZgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBhZGQgYSBwcm9wZXJ0eSB0b1xuICogQHBhcmFtIHtPYmplY3R9IHByb3BlcnR5VmFsdWVzIEEgbWFwIG9mIGtleXMgYW5kIHZhbHVlcyBvZiBwcm9wZXJ0aWVzIHRoYXR3aWxsIGJlIGFkZGVkLiBUaGUgZGVzY3JpcHRvcnMgb2YgcHJvcGVydGllcyB3aWxsIGJlIGRlZmluZWQgYnkgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzLlxuICogQHBhcmFtIHtJbnRlZ2VyfSBkZWNyaXB0b3JGbGFncyBiaXQgbWFzayBvZiBwcm9wZXJ0eSBkZXNjcmlwdG9yIHByb3BlcnRpZXMgY29tcG9zZWQgZnJvbSBgXy5FTlVNRVJBQkxFYCAob3IgYF8uRU5VTWApLCBgXy5DT05GSUdVUkFCTEVgIChvciBgXy5DT05GYCkgYW5kIGBfLldSSVRBQkxFYCAob3IgYF8uV1JJVGApXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMocHJvcGVydHlWYWx1ZXMsIGRlY3JpcHRvckZsYWdzKSB7XG4gICAgdmFyIGRlc2NyaXB0b3JzID0gbWFwS2V5cy5jYWxsKHByb3BlcnR5VmFsdWVzLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gX2dldERlc2NyaXB0b3IodmFsdWUsIGRlY3JpcHRvckZsYWdzKTtcbiAgICB9LCB0cnVlKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0aGlzLCBkZXNjcmlwdG9ycyk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBFeHRlbmRzIG9iamVjdCBgc2VsZmAgd2l0aCBwcm9wZXJ0aWVzIG9mIGBvYmpgIHRvIGFueSBkZXB0aCwgd2l0aG91dCBvdmVyd3J0aXRpbmcgZXhpc3Rpbmcgb2JqZWN0IHByb3BlcnRpZXMgb2YgYHNlbGZgIHdpdGggb2JqZWN0IHByb3BlcnRpZXMgb2YgYG9iamAuXG4gKiBTY2FsYXIgcHJvcGVydGllcyBvZiBgb2JqYCB3aWxsIG92ZXJ3cml0ZSBwcm9wZXJ0aWVzIG9mIGBzZWxmYC4gU2NhbGFyIHBvcnBlcnRpZXMgb2YgYHNlbGZgIHdpbGwgYWxzbyBiZSBvdmVyd3JpdHRlbi5cbiAqIENvcnJlY3RseSB3b3JrcyB3aXRoIHJlY3Vyc2l2ZSBvYmplY3RzLlxuICogVXNhZ2U6XG4gKiBgYGBcbiAqIHZhciBvYmogPSB7XG4gKiAgICAgaW5uZXI6IHtcbiAqICAgICAgICAgYTogMVxuICogICAgIH1cbiAqIH07XG4gKlxuICogXy5kZWVwRXh0ZW5kKG9iaiwge1xuICogICAgIGlubmVyOiB7XG4gKiAgICAgICAgIGI6IDJcbiAqICAgICB9XG4gKiB9KTtcbiAqXG4gKiBhc3NlcnQuZGVlcEVxdWFsKG9iaiwge1xuICogICAgIGlubmVyOiB7XG4gKiAgICAgICAgIGE6IDEsXG4gKiAgICAgICAgIGI6IDJcbiAqICAgICB9XG4gKiB9KTsgLy8gYXNzZXJ0IHBhc3Nlc1xuICogYGBgXG4gKiBSZXR1cm5zIGBzZWxmYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3QgdG8gYmUgZXh0ZW5kZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogQW4gb2JqZWN0IHdpdGggcHJvcGVydGllcyB0byBjb3B5IHRvXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIE9wdGlvbmFsIGB0cnVlYCB0byB1c2Ugb25seSBlbnVtZXJhYmxlIHByb3BlcnRpZXNcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZGVlcEV4dGVuZChvYmosIG9ubHlFbnVtZXJhYmxlKSB7XG4gICAgcmV0dXJuIF9leHRlbmRUcmVlKHRoaXMsIG9iaiwgb25seUVudW1lcmFibGUsIFtdKTtcbn1cblxuXG5mdW5jdGlvbiBfZXh0ZW5kVHJlZShzZWxmTm9kZSwgb2JqTm9kZSwgb25seUVudW1lcmFibGUsIG9ialRyYXZlcnNlZCkge1xuICAgIGlmIChvYmpUcmF2ZXJzZWQuaW5kZXhPZihvYmpOb2RlKSA+PSAwKSByZXR1cm47IC8vIG5vZGUgYWxyZWFkeSB0cmF2ZXJzZWQsIG9iaiBoYXMgcmVjdXJzaW9uXG5cbiAgICAvLyBzdG9yZSBub2RlIHRvIHJlY29nbmlzZSByZWN1cnNpb25cbiAgICBvYmpUcmF2ZXJzZWQucHVzaChvYmpOb2RlKTtcblxuICAgIHZhciBsb29wID0gQXJyYXkuaXNBcnJheShvYmpOb2RlKSA/IEFycmF5LnByb3RvdHlwZS5mb3JFYWNoIDogZWFjaEtleTtcblxuICAgIGxvb3AuY2FsbChvYmpOb2RlLCBmdW5jdGlvbih2YWx1ZSwgcHJvcCkge1xuICAgICAgICB2YXIgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqTm9kZSwgcHJvcCk7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcgJiYgdmFsdWUgIT0gbnVsbFxuICAgICAgICAgICAgICAgICYmICEgKHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwKSAmJiAhICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICBpZiAoISAoc2VsZk5vZGUuaGFzT3duUHJvcGVydHkocHJvcClcbiAgICAgICAgICAgICAgICAgICAgJiYgdHlwZW9mIHNlbGZOb2RlW3Byb3BdID09ICdvYmplY3QnICYmIHNlbGZOb2RlW3Byb3BdICE9IG51bGwpKVxuICAgICAgICAgICAgICAgIHNlbGZOb2RlW3Byb3BdID0gKEFycmF5LmlzQXJyYXkodmFsdWUpKSA/IFtdIDoge307XG4gICAgICAgICAgICBfZXh0ZW5kVHJlZShzZWxmTm9kZVtwcm9wXSwgdmFsdWUsIG9ubHlFbnVtZXJhYmxlLCBvYmpUcmF2ZXJzZWQpO1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmTm9kZSwgcHJvcCwgZGVzY3JpcHRvcik7XG4gICAgfSwgdGhpcywgb25seUVudW1lcmFibGUpO1xuXG4gICAgcmV0dXJuIHNlbGZOb2RlO1xufVxuXG5cbi8qKlxuICogQ2xvbmVzIGFsbCBvYmplY3QgdHJlZS4gQ2xhc3Mgb2Ygb3JpZ2luYWwgb2JqZWN0IGlzIG5vdCBwcmVzZXJ2ZWQuIFJldHVybnMgYHNlbGZgXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHRvIGJlIGV4dGVuZGVkXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIE9wdGlvbmFsIGB0cnVlYCB0byB1c2Ugb25seSBlbnVtZXJhYmxlIHByb3BlcnRpZXNcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZGVlcENsb25lKG9ubHlFbnVtZXJhYmxlKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gbmV3IERhdGUodGhpcyk7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiBuZXcgUmVnRXhwKHRoaXMpO1xuICAgIHZhciBjbG9uZWRPYmplY3QgPSBBcnJheS5pc0FycmF5KHRoaXMpID8gW10gOiB7fTtcbiAgICBkZWVwRXh0ZW5kLmNhbGwoY2xvbmVkT2JqZWN0LCB0aGlzLCBvbmx5RW51bWVyYWJsZSk7XG4gICAgcmV0dXJuIGNsb25lZE9iamVjdDtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgYXJyYXkgb2YgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIHRoZSBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBvYmplY3QgdG8gcmV0dXJuIGtleXMgb2ZcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5mdW5jdGlvbiBrZXlzKCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzKTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgYXJyYXkgb2YgdmFsdWVzIG9mIHRoZSBvYmplY3QncyBrZXlzXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgb2JqZWN0IHRvIHJldHVybiB2YWx1ZXMgZnJvbVxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gb25seUVudW1lcmFibGVcbiAgICAgICAgICAgICAgICA/IE9iamVjdC5rZXlzKHRoaXMpXG4gICAgICAgICAgICAgICAgOiBhbGxLZXlzLmNhbGwodGhpcyk7XG5cbiAgICByZXR1cm4gcHJvcGVydGllcy5tYXAoZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICByZXR1cm4gdGhpc1twcm9wXTtcbiAgICB9LCB0aGlzKTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgYXJyYXkgb2YgYWxsIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCBgc2VsZmAgKGluY2x1ZGluZyBub24tZW51bWVyYmFsZSkuXG4gKiBUbyBnZXQgb25seSBlbnVtZXJhYmxlIHByb3BlcnRpZXMsIHVzZSBgT2JqZWN0LmtleXMoKWAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHRvIGdldCBhbGwgcHJvcGVydGllcyBvZi5cbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG4gZnVuY3Rpb24gYWxsS2V5cygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcyk7XG4gfVxuXG5cbi8qKlxuICogQW4gYW5hbG9ndWUgb2YgYGluZGV4T2ZgIG1ldGhvZCBvZiBBcnJheSBwcm90b3R5cGUuXG4gKiBSZXR1cm5zIHRoZSBga2V5YCBvZiBgc2VhcmNoRWxlbWVudGAgaW4gdGhlIG9iamVjdCBgc2VsZmAuXG4gKiBBcyBvYmplY3Qga2V5cyBhcmUgdW5zb3J0ZWQsIGlmIHRoZXJlIGFyZSBzZXZlcmFsIGtleXMgdGhhdCBob2xkIGBzZWFyY2hFbGVtZW50YCBhbnkgb2YgdGhlbSBjYW4gYmUgcmV0dXJuZWQuIFVzZSBgYWxsS2V5c09mYCB0byByZXR1cm4gYWxsIGtleXMuXG4gKiBBbGwgb3duIHByb3BlcnRpZXMgYXJlIHNlYXJjaGVkIChub3QgdGhvc2UgaW5oZXJpdGVkIHZpYSBwcm90b3R5cGUgY2hhaW4pLCBpbmNsdWRpbmcgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyAodW5sZXNzIGBvbmx5RW51bWVyYWJsZWAgaXMgdHJ1dGh5KS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3QgdG8gc2VhcmNoIGEgdmFsdWUgaW5cbiAqIEBwYXJhbSB7QW55fSBzZWFyY2hFbGVtZW50IEFuIGVsZW1lbnQgdGhhdCB3aWxsIGJlIHNlYXJjaGVkLiBBbiBleGFjdCBlcXVhbGl0eSBpcyB0ZXN0ZWQsIHNvIGAwYCBpcyBub3QgdGhlIHNhbWUgYXMgYCcwJ2AuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIHRydWUgdG8gc2VhcmNoIGFtb25nIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBrZXlPZihzZWFyY2hFbGVtZW50LCBvbmx5RW51bWVyYWJsZSkge1xuICAgIHZhciBwcm9wZXJ0aWVzID0gb25seUVudW1lcmFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gT2JqZWN0LmtleXModGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYWxsS2V5cy5jYWxsKHRoaXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wZXJ0aWVzLmxlbmd0aDsgaSsrKVxuICAgICAgICBpZiAoc2VhcmNoRWxlbWVudCA9PT0gdGhpc1twcm9wZXJ0aWVzW2ldXSlcbiAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0aWVzW2ldO1xuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuXG4vKipcbiAqIFdvcmtzIHNpbWlsYXJseSB0byB0aGUgcHJldmlvdXMgZnVuY3Rpb24sIGJ1dCByZXR1cm5zIHRoZSBhcnJheSBvZiBrZXlzIGhvbGRpbmcgYHNlYXJjaEVsZW1lbnRgIGFzIHRoZWlyIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB0byBzZWFyY2ggYSB2YWx1ZSBpblxuICogQHBhcmFtIHtBbnl9IHNlYXJjaEVsZW1lbnQgQW4gZWxlbWVudCB0aGF0IHdpbGwgYmUgc2VhcmNoZWQuIEFuIGV4YWN0IGVxdWFsaXR5IGlzIHRlc3RlZCwgc28gYDBgIGlzIG5vdCB0aGUgc2FtZSBhcyBgJzAnYC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgdHJ1ZSB0byBzZWFyY2ggYW1vbmcgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtBcnJheVtTdHJpbmddfVxuICovXG5mdW5jdGlvbiBhbGxLZXlzT2Yoc2VhcmNoRWxlbWVudCwgb25seUVudW1lcmFibGUpIHtcbiAgICB2YXIgcHJvcGVydGllcyA9IG9ubHlFbnVtZXJhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IE9iamVjdC5rZXlzKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGFsbEtleXMuY2FsbCh0aGlzKTtcblxuICAgIHZhciBrZXlzID0gcHJvcGVydGllcy5maWx0ZXIoZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICByZXR1cm4gc2VhcmNoRWxlbWVudCA9PT0gdGhpc1twcm9wXTtcbiAgICB9LCB0aGlzKTtcblxuICAgIHJldHVybiBrZXlzO1xufVxuXG5cbi8qKlxuICogQW4gYW5hbG9ndWUgb2YgW2ZvckVhY2hdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2ZvckVhY2gpIG1ldGhvZCBvZiBBcnJheSBwcm90b3R5cGUuXG4gKiBJdGVyYXRlcyBhbGwgb3duIHByb3BlcnRpZXMgb2YgYHNlbGZgIChvciBvbmx5IGVudW1lcmFibGUgb3duIHByb3BlcnRpZXMgaWYgYG9ubHlFbnVtZXJhYmxlYCBpcyB0cnV0aHkpIGNhbGxpbmcgY2FsbGJhY2sgZm9yIGVhY2gga2V5LlxuICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkIHdpdGggYXJyYXlzLCBpdCB3aWxsIGluY2x1ZGUgYGxlbmd0aGAgcHJvcGVydHkgaW4gaXRlcmF0aW9uLlxuICogVG8gaXRlcmF0ZSBhcnJheS1saWtlIG9iamVjdHMgKGUuZy4sIGBhcmd1bWVudHNgIHBzZXVkby1hcnJheSkgdXNlOlxuICogYGBgXG4gKiBfLmZvckVhY2goYXJndW1lbnRzLCBjYWxsYmFjaywgdGhpc0FyZyk7XG4gKiBgYGBcbiAqIEZ1bmN0aW9uIHJldHVybnMgYHNlbGZgIHRvIGFsbG93IFtjaGFpbmluZ10ocHJvdG8uanMuaHRtbClcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3Qgd2hpY2ggcHJvcGVydGllcyB3aWxsIGJlIGl0ZXJhdGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsYmFjayBpcyBwYXNzZWQgYHZhbHVlYCwgYGtleWAgYW5kIGBzZWxmYCwgaXRzIHJldHVybiB2YWx1ZSBpcyBub3QgdXNlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIEFuIG9wdGlvbmFsIGNvbnRleHQgb2YgaXRlcmF0aW9uICh0aGUgdmFsdWVvZiBgdGhpc2ApLCB3aWxsIGJlIHVuZGVmaW5lZCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgcGFzc2VkLlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBBbiBvcHRpb25hbCBgdHJ1ZWAgdG8gaXRlcmF0ZSBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seS5cbiAqL1xuZnVuY3Rpb24gZWFjaEtleShjYWxsYmFjaywgdGhpc0FyZywgb25seUVudW1lcmFibGUpIHtcbiAgICB2YXIgcHJvcGVydGllcyA9IG9ubHlFbnVtZXJhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IE9iamVjdC5rZXlzKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGFsbEtleXMuY2FsbCh0aGlzKTtcblxuICAgIHByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XG4gICAgICAgIGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdGhpc1twcm9wXSwgcHJvcCwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEFuIGFuYWxvZ3VlIG9mIFttYXBdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L21hcCkgbWV0aG9kIG9mIEFycmF5IHByb3RvdHlwZS5cbiAqIFJldHVybnMgdGhlIG9iamVjdCB0aGF0IGlzIHRoZSByZXN1bHQgb2YgdGhlIGFwcGxpY2F0aW9uIG9mIGNhbGxiYWNrIHRvIHZhbHVlcyBpbiBhbGwgb3duIHByb3BlcnRpZXMgb2YgYHNlbGZgIChvciBvbmx5IGVudW1lcmFibGUgb3duIHByb3BlcnRpZXMgaWYgYG9ubHlFbnVtZXJhYmxlYCBpcyB0cnV0aHkpLlxuICogVGhlIHJldHVybmVkIG9iamVjdCB3aWxsIGJlIHRoZSBpbnN0YW5jZSBvZiB0aGUgc2FtZSBjbGFzcyBhcyBgc2VsZmAuXG4gKiBQcm9wZXJ0eSBkZXNjcmlwdG9ycyBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0IHdpbGwgaGF2ZSB0aGUgc2FtZSBgZW51bWVyYWJsZWAsIGBjb25maWd1cmFibGVgIGFuZCBgd3JpdGFibGVgIHNldHRpbmdzIGFzIHRoZSBwcm9wZXJ0aWVzIG9mIGBzZWxmYC5cbiAqIFRoaXMgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZCB3aXRoIGFycmF5cywgaXQgd2lsbCBpbmNsdWRlIGBsZW5ndGhgIHByb3BlcnR5IGluIGl0ZXJhdGlvbi5cbiAqIFRvIG1hcCBhcnJheS1saWtlIG9iamVjdHMgdXNlOlxuICogYGBgXG4gKiB2YXIgcmVzdWx0ID0gXy5tYXAoYXJndW1lbnRzLCBjYWxsYmFjaywgdGhpc0FyZyk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3Qgd2hpY2ggcHJvcGVydGllcyB3aWxsIGJlIGl0ZXJhdGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsYmFjayBpcyBwYXNzZWQgYHZhbHVlYCwgYGtleWAgYW5kIGBzZWxmYCBhbmQgc2hvdWxkIHJldHVybiB2YWx1ZSB0aGF0IHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG1hcC5cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIEFuIG9wdGlvbmFsIGNvbnRleHQgb2YgaXRlcmF0aW9uICh0aGUgdmFsdWVvZiBgdGhpc2ApLCB3aWxsIGJlIHVuZGVmaW5lZCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgcGFzc2VkLlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBBbiBvcHRpb25hbCBgdHJ1ZWAgdG8gaXRlcmF0ZSBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gbWFwS2V5cyhjYWxsYmFjaywgdGhpc0FyZywgb25seUVudW1lcmFibGUpIHtcbiAgICB2YXIgZGVzY3JpcHRvcnMgPSB7fTtcbiAgICBlYWNoS2V5LmNhbGwodGhpcywgbWFwUHJvcGVydHksIHRoaXNBcmcsIG9ubHlFbnVtZXJhYmxlKTtcbiAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZSh0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgZGVzY3JpcHRvcnMpO1xuXG4gICAgZnVuY3Rpb24gbWFwUHJvcGVydHkodmFsdWUsIGtleSwgc2VsZikge1xuICAgICAgICBkZXNjcmlwdG9yc1trZXldID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzZWxmLCBrZXkpO1xuICAgICAgICBkZXNjcmlwdG9yc1trZXldLnZhbHVlID0gY2FsbGJhY2suY2FsbCh0aGlzLCB2YWx1ZSwga2V5LCBzZWxmKTtcbiAgICB9XG59XG5cblxuLyoqXG4gKiBBbiBhbmFsb2d1ZSBvZiBbcmVkdWNlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9SZWR1Y2UpIG1ldGhvZCBvZiBBcnJheSBwcm90b3R5cGUuXG4gKiBUaGlzIG1ldGhvZCByZWR1Y2VzIHRoZSBvYmplY3QgdG8gYSBzaW5nbGUgdmFsdWUuIEl0ZXJhdGlvbiBvcmRlciBpcyBpbXBvc3NpYmxlIHRvIGNvbnRyb2wgd2l0aCBvYmplY3QuXG4gKiBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQgd2l0aCBhcnJheXMsIGl0IHdpbGwgaW5jbHVkZSBgbGVuZ3RoYCBwcm9wZXJ0eSBpbiBpdGVyYXRpb24uXG4gKiBUbyByZWR1Y2UgYXJyYXktbGlrZSBvYmplY3RzIHVzZTpcbiAqIGBgYFxuICogdmFyIHJlc3VsdCA9IF8ucmVkdWNlKGFyZ3VtZW50cywgY2FsbGJhY2ssIGluaXRpYWxWYWx1ZSwgdGhpc0FyZyk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3Qgd2hpY2ggcHJvcGVydGllcyB3aWxsIGJlIGl0ZXJhdGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsYmFjayBpcyBwYXNzZWQgYHByZXZpb3VzVmFsdWVgLCBgdmFsdWVgLCBga2V5YCBhbmQgYHNlbGZgIGFuZCBzaG91bGQgcmV0dXJuIHZhbHVlIHRoYXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBgcHJldmlvdXNWYWx1ZWAgZm9yIHRoZSBuZXh0IGBjYWxsYmFja2AgY2FsbC5cbiAqIEBwYXJhbSB7QW55fSBpbml0aWFsVmFsdWUgVGhlIGluaXRpYWwgdmFsdWUgcGFzc2VkIHRvIGNhbGxiYWNrIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIgb24gdGhlIGZpcnN0IGNhbGwuXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBBbiBvcHRpb25hbCBjb250ZXh0IG9mIGl0ZXJhdGlvbiAodGhlIHZhbHVlb2YgYHRoaXNgKSwgd2lsbCBiZSB1bmRlZmluZWQgaWYgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHBhc3NlZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgYHRydWVgIHRvIGl0ZXJhdGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIHJlZHVjZUtleXMoY2FsbGJhY2ssIGluaXRpYWxWYWx1ZSwgdGhpc0FyZywgb25seUVudW1lcmFibGUpIHtcbiAgICB2YXIgcHJvcGVydGllcyA9IG9ubHlFbnVtZXJhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICA/IE9iamVjdC5rZXlzKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGFsbEtleXMuY2FsbCh0aGlzKTtcblxuICAgIHZhciBtZW1vID0gaW5pdGlhbFZhbHVlO1xuXG4gICAgcHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcbiAgICAgICAgbWVtbyA9IGNhbGxiYWNrLmNhbGwodGhpc0FyZywgbWVtbywgdGhpc1twcm9wXSwgcHJvcCwgdGhpcyk7XG4gICAgfSwgdGhpcyk7XG5cbiAgICByZXR1cm4gbWVtbztcbn1cblxuXG4vKipcbiAqIEFuIGFuYWxvZ3VlIG9mIFtmaWx0ZXJdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2ZpbHRlcikgbWV0aG9kIG9mIEFycmF5IHByb3RvdHlwZS5cbiAqIFJldHVybnMgdGhlIG5ldyBvYmplY3Qgd2l0aCBrZXlzIGZvciB3aGljaCBjYWxsYmFjayByZXR1cm5zIHRydWUuXG4gKiBQcm9wZXJ0eSBkZXNjcmlwdG9ycyBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0IHdpbGwgaGF2ZSB0aGUgc2FtZSBgZW51bWVyYWJsZWAsIGBjb25maWd1cmFibGVgIGFuZCBgd3JpdGFibGVgIHNldHRpbmdzIGFzIHRoZSBwcm9wZXJ0aWVzIG9mIGBzZWxmYC5cbiAqIFRvIGZpbHRlciBhcnJheS1saWtlIG9iamVjdHMgdXNlOlxuICogYGBgXG4gKiB2YXIgcmVzdWx0ID0gXy5maWx0ZXIoYXJndW1lbnRzLCBjYWxsYmFjaywgdGhpc0FyZyk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBBbiBvYmplY3Qgd2hpY2ggcHJvcGVydGllcyB3aWxsIGJlIGl0ZXJhdGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsYmFjayBpcyBwYXNzZWQgYHZhbHVlYCwgYGtleWAgYW5kIGBzZWxmYC4gSWYgaXQgcmV0dXJucyB0cnV0aHkgdmFsdWUsIHRoZSBrZXkvdmFsdWUgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0aW5nIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGlzQXJnIEFuIG9wdGlvbmFsIGNvbnRleHQgb2YgaXRlcmF0aW9uICh0aGUgdmFsdWVvZiBgdGhpc2ApLCB3aWxsIGJlIHVuZGVmaW5lZCBpZiB0aGlzIHBhcmFtZXRlciBpcyBub3QgcGFzc2VkLlxuICogQHBhcmFtIHtCb29sZWFufSBvbmx5RW51bWVyYWJsZSBBbiBvcHRpb25hbCBgdHJ1ZWAgdG8gaXRlcmF0ZSBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb25seS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZmlsdGVyS2V5cyhjYWxsYmFjaywgdGhpc0FyZywgb25seUVudW1lcmFibGUpIHtcbiAgICB2YXIgZGVzY3JpcHRvcnMgPSB7fTtcbiAgICBlYWNoS2V5LmNhbGwodGhpcywgZmlsdGVyUHJvcGVydHksIHRoaXNBcmcsIG9ubHlFbnVtZXJhYmxlKTtcbiAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZSh0aGlzLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgZGVzY3JpcHRvcnMpOztcblxuICAgIGZ1bmN0aW9uIGZpbHRlclByb3BlcnR5KHZhbHVlLCBrZXksIHNlbGYpIHtcbiAgICAgICAgaWYgKGNhbGxiYWNrLmNhbGwodGhpcywgdmFsdWUsIGtleSwgc2VsZikpXG4gICAgICAgICAgICBkZXNjcmlwdG9yc1trZXldID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzZWxmLCBrZXkpO1xuICAgIH1cbn1cblxuXG52YXIgX3Bhc3NlZCA9IHt9XG4gICAgLCBfZGlkTm90UGFzcyA9IHt9O1xuXG4vKipcbiAqIEFuIGFuYWxvZ3VlIG9mIFtzb21lXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9zb21lKSBtZXRob2Qgb2YgQXJyYXkgcHJvdG90eXBlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIEFuIG9iamVjdCB3aGljaCBwcm9wZXJ0aWVzIHdpbGwgYmUgaXRlcmF0ZWRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIGlzIHBhc3NlZCBgdmFsdWVgLCBga2V5YCBhbmQgYHNlbGZgLiBJZiBpdCByZXR1cm5zIHRydXRoeSB2YWx1ZSwgdGhlIGZ1bmN0aW9uIGltbWVhZGl0ZWx5IHJldHVybnMgYHRydWVgLlxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgQW4gb3B0aW9uYWwgY29udGV4dCBvZiBpdGVyYXRpb24gKHRoZSB2YWx1ZW9mIGB0aGlzYCksIHdpbGwgYmUgdW5kZWZpbmVkIGlmIHRoaXMgcGFyYW1ldGVyIGlzIG5vdCBwYXNzZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9ubHlFbnVtZXJhYmxlIEFuIG9wdGlvbmFsIGB0cnVlYCB0byBpdGVyYXRlIGVudW1lcmFibGUgcHJvcGVydGllcyBvbmx5LlxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gc29tZUtleShjYWxsYmFjaywgdGhpc0FyZywgb25seUVudW1lcmFibGUpIHtcbiAgICB0cnkge1xuICAgICAgICBlYWNoS2V5LmNhbGwodGhpcywgdGVzdFByb3BlcnR5LCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSk7XG4gICAgfSBjYXRjaCAodGVzdCkge1xuICAgICAgICBpZiAodGVzdCA9PT0gX3Bhc3NlZCkgcmV0dXJuIHRydWU7XG4gICAgICAgIGVsc2UgdGhyb3cgdGVzdDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gdGVzdFByb3BlcnR5KHZhbHVlLCBrZXksIHNlbGYpIHtcbiAgICAgICAgaWYgKGNhbGxiYWNrLmNhbGwodGhpcywgdmFsdWUsIGtleSwgc2VsZikpXG4gICAgICAgICAgICB0aHJvdyBfcGFzc2VkO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIEFuIGFuYWxvZ3VlIG9mIFtldmVyeV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZXZlcnkpIG1ldGhvZCBvZiBBcnJheSBwcm90b3R5cGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlbGYgQW4gb2JqZWN0IHdoaWNoIHByb3BlcnRpZXMgd2lsbCBiZSBpdGVyYXRlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGJhY2sgaXMgcGFzc2VkIGB2YWx1ZWAsIGBrZXlgIGFuZCBgc2VsZmAuIElmIGl0IHJldHVybnMgZmFsc3kgdmFsdWUsIHRoZSBmdW5jdGlvbiBpbW1lYWRpdGVseSByZXR1cm5zIGBmYWxzZWAuXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBBbiBvcHRpb25hbCBjb250ZXh0IG9mIGl0ZXJhdGlvbiAodGhlIHZhbHVlb2YgYHRoaXNgKSwgd2lsbCBiZSB1bmRlZmluZWQgaWYgdGhpcyBwYXJhbWV0ZXIgaXMgbm90IHBhc3NlZC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gb25seUVudW1lcmFibGUgQW4gb3B0aW9uYWwgYHRydWVgIHRvIGl0ZXJhdGUgZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9ubHkuXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBldmVyeUtleShjYWxsYmFjaywgdGhpc0FyZywgb25seUVudW1lcmFibGUpIHtcbiAgICB0cnkge1xuICAgICAgICBlYWNoS2V5LmNhbGwodGhpcywgdGVzdFByb3BlcnR5LCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSk7XG4gICAgfSBjYXRjaCAodGVzdCkge1xuICAgICAgICBpZiAodGVzdCA9PT0gX2RpZE5vdFBhc3MpIHJldHVybiBmYWxzZTtcbiAgICAgICAgZWxzZSB0aHJvdyB0ZXN0O1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGZ1bmN0aW9uIHRlc3RQcm9wZXJ0eSh2YWx1ZSwga2V5LCBzZWxmKSB7XG4gICAgICAgIGlmICghIGNhbGxiYWNrLmNhbGwodGhpcywgdmFsdWUsIGtleSwgc2VsZikpXG4gICAgICAgICAgICB0aHJvdyBfZGlkTm90UGFzcztcbiAgICB9XG59XG5cblxudmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGVcbiAgICAsIGNvbmNhdCA9IEFycmF5UHJvdG8uY29uY2F0O1xuLyoqXG4gKiBSZXR1cm5zIG9iamVjdCBvZiB0aGUgc2FtZSBjbGFzcyB3aXRoIG9ubHkgc3BlY2lmaWVkIGtleXMsIHRoYXQgYXJlIHBhc3NlZCBhcyBzdHJpbmcgcGFyYW1ldGVycyBvciBhcnJheShzKSBvZiBrZXlzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZWxmIGFuIG9iamVjdCB0byBwaWNrIGtleXMgZnJvbVxuICogQHBhcmFtIHtMaXN0W1N0cmluZ3xBcnJheV19IGFyZ3VtZW50cyBsaXN0IG9mIGtleXMgKG9yIGFycmF5KHMpIG9mIGtleXMpXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIHBpY2tLZXlzKCkgeyAvLyAsIC4uLiBrZXlzXG4gICAgdmFyIGtleXMgPSBjb25jYXQuYXBwbHkoQXJyYXlQcm90bywgYXJndW1lbnRzKVxuICAgICAgICAsIG9iaiA9IE9iamVjdC5jcmVhdGUodGhpcy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUpO1xuICAgIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoa2V5KSlcbiAgICAgICAgICAgIG9ialtrZXldID0gdGhpc1trZXldO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBvYmo7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIG9iamVjdCBvZiB0aGUgc2FtZSBjbGFzcyB3aXRob3V0IHNwZWNpZmllZCBrZXlzLCB0aGF0IGFyZSBwYXNzZWQgYXMgc3RyaW5nIHBhcmFtZXRlcnMgb3IgYXJyYXkocykgb2Yga2V5cy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBhbiBvYmplY3QgdG8gb21pdCBrZXlzIGluXG4gKiBAcGFyYW0ge0xpc3RbU3RyaW5nfEFycmF5XX0gYXJndW1lbnRzIGxpc3Qgb2Yga2V5cyAob3IgYXJyYXkocykgb2Yga2V5cylcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gb21pdEtleXMoKSB7IC8vICwgLi4uIGtleXNcbiAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBhcmd1bWVudHMpXG4gICAgICAgICwgb2JqID0gY2xvbmUuY2FsbCh0aGlzKTtcbiAgICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KXtcbiAgICAgICAgZGVsZXRlIG9ialtrZXldO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBvYmo7XG59XG5cblxuLyoqXG4gKiBQZXJmb3JtcyBkZWVwIGVxdWFsaXR5IHRlc3Qgb2YgdGhlIG9iamVjdC4gRG9lcyBub3Qgd29yayB3aXRoIHJlY3Vyc2l2ZSBvYmplY3RzXG4gKiBAcGFyYW0gIHtBbnl9IHNlbGYgb2JqZWN0IHRvIGNvbXBhcmVcbiAqIEBwYXJhbSAge0FueX0gb2JqIG9iamVjdCB0byBjb21wYXJlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBpc0VxdWFsKG9iaikge1xuICAgIGlmICh0aGlzID09PSBvYmopIHJldHVybiB0aGlzICE9PSAwIHx8IDEvdGhpcyA9PSAxL29iajsgLy8gMCBhbmQgLTAgYXJlIGNvbnNpZGVyZWQgbm90IGVxdWFsLCBhbHRob3VnaCAwID09PSAtMCBpcyB0cnVlXG4gICAgaWYgKHRoaXMgPT0gbnVsbCB8fCBvYmogPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIHZhciBjbGFzc05hbWUgPSB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgaWYgKGNsYXNzTmFtZSAhPSBvYmouY29uc3RydWN0b3IubmFtZSkgcmV0dXJuIGZhbHNlO1xuICAgIHN3aXRjaCAoY2xhc3NOYW1lKSB7XG4gICAgICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICAgICAgICByZXR1cm4gdGhpcyA9PSBTdHJpbmcob2JqKTtcbiAgICAgICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgICAgICAgIHJldHVybiB0aGlzICE9ICt0aGlzID8gb2JqICE9ICtvYmogOiAodGhpcyA9PSAwID8gMS90aGlzID09IDEvb2JqIDogdGhpcyA9PSArb2JqKTtcbiAgICAgICAgY2FzZSAnRGF0ZSc6XG4gICAgICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgICAgICAgcmV0dXJuICt0aGlzID09ICtvYmo7XG4gICAgICAgIGNhc2UgJ1JlZ0V4cCc6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zb3VyY2UgPT0gb2JqLnNvdXJjZVxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLmdsb2JhbCA9PSBvYmouZ2xvYmFsXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMubXVsdGlsaW5lID09IG9iai5tdWx0aWxpbmVcbiAgICAgICAgICAgICAgICAgICAgJiYgdGhpcy5pZ25vcmVDYXNlID09IG9iai5pZ25vcmVDYXNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMgIT0gJ29iamVjdCcgfHwgdHlwZW9mIG9iaiAhPSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcykpXG4gICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA9PSBvYmoubGVuZ3RoXG4gICAgICAgICAgICAgICAgJiYgdGhpcy5ldmVyeShmdW5jdGlvbihpdGVtLCBpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNFcXVhbC5jYWxsKGl0ZW0sIG9ialtpbmRleF0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYWxsS2V5cy5jYWxsKHRoaXMpLmxlbmd0aCA9PSBhbGxLZXlzLmNhbGwob2JqKS5sZW5ndGhcbiAgICAgICAgICAgICAgICAmJiBldmVyeUtleS5jYWxsKHRoaXMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzRXF1YWwuY2FsbCh2YWx1ZSwgb2JqW2tleV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgIH1cbn1cblxuXG4vKipcbiAqIFRoZSBvcHBvc2l0ZSBvZiBpc0VxdWFsXG4gKiBAcGFyYW0gIHtBbnl9IHNlbGYgb2JqZWN0IHRvIGNvbXBhcmVcbiAqIEBwYXJhbSAge0FueX0gb2JqIG9iamVjdCB0byBjb21wYXJlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBpc05vdChvYmopIHtcbiAgICByZXR1cm4gIWlzRXF1YWwuY2FsbCh0aGlzLCBvYmopO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIC0gW2V4dGVuZFByb3RvXSgjZXh0ZW5kUHJvdG8pXG4gKiAtIFtjcmVhdGVTdWJjbGFzc10oI2NyZWF0ZVN1YmNsYXNzKVxuICogLSBbbWFrZVN1YmNsYXNzXSgjbWFrZVN1YmNsYXNzKVxuICogLSBbbmV3QXBwbHldKCNuZXdBcHBseSlcbiAqXG4gKiBUaGVzZSBtZXRob2RzIGNhbiBiZSBbY2hhaW5lZF0ocHJvdG8uanMuaHRtbCNQcm90bylcbiAqL1xudmFyIHByb3RvdHlwZU1ldGhvZHMgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBleHRlbmRQcm90bzogZXh0ZW5kUHJvdG8sXG4gICAgY3JlYXRlU3ViY2xhc3M6IGNyZWF0ZVN1YmNsYXNzLFxuICAgIG1ha2VTdWJjbGFzczogbWFrZVN1YmNsYXNzLFxuICAgIG5ld0FwcGx5OiBuZXdBcHBseVxufTtcblxuXG52YXIgX18gPSByZXF1aXJlKCcuL3Byb3RvX29iamVjdCcpO1xuXG5fXy5leHRlbmQuY2FsbChfXywgcmVxdWlyZSgnLi9wcm90b19mdW5jdGlvbicpKTtcblxuXG4vKipcbiAqIEFkZHMgbm9uLWVudW1lcmFibGUsIG5vbi1jb25maWd1cmFibGUgYW5kIG5vbi13cml0YWJsZSBwcm9wZXJ0aWVzIHRvIHRoZSBwcm90b3R5cGUgb2YgY29uc3RydWN0b3IgZnVuY3Rpb24uXG4gKiBVc2FnZTpcbiAqIGBgYFxuICogZnVuY3Rpb24gTXlDbGFzcygpIHt9XG4gKiBfLmV4dGVuZFByb3RvKE15Q2xhc3MsIHtcbiAqICAgICBtZXRob2QxOiBmdW5jdGlvbigpIHt9LFxuICogICAgIG1ldGhvZDI6IGZ1bmN0aW9uKCkge31cbiAqIH0pO1xuICogYGBgXG4gKiBUbyBleHRlbmQgY2xhc3MgdmlhIG9iamVjdDpcbiAqIGBgYFxuICogXy5leHRlbmRQcm90byhvYmouY29uc3RydWN0b3IsIG1ldGhvZHMpO1xuICogYGBgXG4gKiBSZXR1cm5zIHBhc3NlZCBjb25zdHJ1Y3Rvciwgc28gZnVuY3Rpb25zIF8uZXh0ZW5kUHJvdG8sIFtfLmV4dGVuZF0ob2JqZWN0LmpzLmh0bWwjZXh0ZW5kKSBhbmQgXy5tYWtlU3ViY2xhc3MgY2FuIGJlIFtjaGFpbmVkXShwcm90by5qcy5odG1sKS4gXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZiBjb25zdHJ1Y3RvciBmdW5jdGlvblxuICogQHBhcmFtIHtPYmplY3R9IG1ldGhvZHMgYSBtYXAgb2YgZnVuY3Rpb25zLCBrZXlzIHdpbGwgYmUgaW5zdGFuY2UgbWV0aG9kcyAocHJvcGVydGllcyBvZiB0aGUgY29uc3RydWN0b3IgcHJvdG90eXBlKVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIGV4dGVuZFByb3RvKG1ldGhvZHMpIHtcbiAgICB2YXIgcHJvcERlc2NyaXB0b3JzID0ge307XG5cbiAgICBfXy5lYWNoS2V5LmNhbGwobWV0aG9kcywgZnVuY3Rpb24obWV0aG9kLCBuYW1lKSB7XG4gICAgICAgIHByb3BEZXNjcmlwdG9yc1tuYW1lXSA9IHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBtZXRob2RcbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMucHJvdG90eXBlLCBwcm9wRGVzY3JpcHRvcnMpO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogTWFrZXMgYSBzdWJjbGFzcyBvZiBjbGFzcyBgdGhpc0NsYXNzYC5cbiAqIFRoZSByZXR1cm5lZCBmdW5jdGlvbiB3aWxsIGhhdmUgc3BlY2lmaWVkIGBuYW1lYCBpZiBzdXBwbGllZC5cbiAqIFRoZSBjb25zdHJ1Y3RvciBvZiBzdXBlcmNsYXNzIHdpbGwgYmUgY2FsbGVkIGluIHN1YmNsYXNzIGNvbnN0cnVjdG9yIGJ5IGRlZmF1bHQgdW5sZXNzIGBhcHBseUNvbnN0cnVjdG9yID09PSBmYWxzZWAgKG5vdCBqdXN0IGZhbHN5KS5cbiAqIENvcGllcyBgdGhpc0NsYXNzYCBjbGFzcyBtZXRob2RzIHRvIGNyZWF0ZWQgc3ViY2xhc3MuIEZvciB0aGVtIHRvIHdvcmsgY29ycmVjdGx5IHRoZXkgc2hvdWxkIHVzZSBgdGhpc2AgdG8gcmVmZXIgdG8gdGhlIGNsYXNzIHJhdGhlciB0aGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgbmFtZS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzQ2xhc3MgQSBjbGFzcyB0byBtYWtlIHN1YmNsYXNzIG9mXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBPcHRpb25hbCBuYW1lIG9mIHN1YmNsYXNzIGNvbnN0cnVjdG9yIGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGFwcGx5Q29uc3RydWN0b3IgT3B0aW9uYWwgZmFsc2UgdmFsdWUgKG5vdCBmYWxzeSkgdG8gcHJldmVudCBjYWxsIG9mIGluaGVyaXRlZCBjb25zdHJ1Y3RvciBpbiB0aGUgY29uc3RydWN0b3Igb2Ygc3ViY2xhc3NcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBjcmVhdGVTdWJjbGFzcyhuYW1lLCBhcHBseUNvbnN0cnVjdG9yKSB7XG4gICAgdmFyIHRoaXNDbGFzcyA9IHRoaXM7XG4gICAgdmFyIHN1YmNsYXNzO1xuXG4gICAgLy8gbmFtZSBpcyBvcHRpb25hbFxuICAgIG5hbWUgPSBuYW1lIHx8ICcnO1xuXG4gICAgLy8gYXBwbHkgc3VwZXJjbGFzcyBjb25zdHJ1Y3RvclxuICAgIHZhciBjb25zdHJ1Y3RvckNvZGUgPSBhcHBseUNvbnN0cnVjdG9yID09PSBmYWxzZVxuICAgICAgICAgICAgPyAnJ1xuICAgICAgICAgICAgOiAndGhpc0NsYXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7JztcblxuICAgIGV2YWwoJ3N1YmNsYXNzID0gZnVuY3Rpb24gJyArIG5hbWUgKyAnKCl7ICcgKyBjb25zdHJ1Y3RvckNvZGUgKyAnIH0nKTtcblxuICAgIG1ha2VTdWJjbGFzcy5jYWxsKHN1YmNsYXNzLCB0aGlzQ2xhc3MpO1xuXG4gICAgLy8gY29weSBjbGFzcyBtZXRob2RzXG4gICAgLy8gLSBmb3IgdGhlbSB0byB3b3JrIGNvcnJlY3RseSB0aGV5IHNob3VsZCBub3QgZXhwbGljdGx5IHVzZSBzdXBlcmNsYXNzIG5hbWVcbiAgICAvLyBhbmQgdXNlIFwidGhpc1wiIGluc3RlYWRcbiAgICBfXy5kZWVwRXh0ZW5kLmNhbGwoc3ViY2xhc3MsIHRoaXNDbGFzcywgdHJ1ZSk7XG5cbiAgICByZXR1cm4gc3ViY2xhc3M7XG59XG5cblxuLyoqXG4gKiBTZXRzIHVwIHByb3RvdHlwZSBjaGFpbiB0byBjaGFuZ2UgYHRoaXNDbGFzc2AgKGEgY29uc3RydWN0b3IgZnVuY3Rpb24pIHNvIHRoYXQgaXQgYmVjb21lcyBhIHN1YmNsYXNzIG9mIGBTdXBlcmNsYXNzYC5cbiAqIFJldHVybnMgYHRoaXNDbGFzc2Agc28gaXQgY2FuIGJlIFtjaGFpbmVkXShwcm90by5qcy5odG1sKSB3aXRoIF8uZXh0ZW5kUHJvdG8gYW5kIFtfLmV4dGVuZF0ob2JqZWN0LmpzLmh0bWwjZXh0ZW5kKS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzQ2xhc3MgQSBjbGFzcyB0aGF0IHdpbGwgYmVjb21lIGEgc3ViY2xhc3Mgb2YgU3VwZXJjbGFzc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gU3VwZXJjbGFzcyBBIGNsYXNzIHRoYXQgd2lsbCBiZWNvbWUgYSBzdXBlcmNsYXNzIG9mIHRoaXNDbGFzc1xuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIG1ha2VTdWJjbGFzcyhTdXBlcmNsYXNzKSB7XG4gICAgLy8gcHJvdG90eXBlIGNoYWluXG4gICAgdGhpcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN1cGVyY2xhc3MucHJvdG90eXBlKTtcbiAgICBcbiAgICAvLyBzdWJjbGFzcyBpZGVudGl0eVxuICAgIGV4dGVuZFByb3RvLmNhbGwodGhpcywge1xuICAgICAgICBjb25zdHJ1Y3RvcjogdGhpc1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xufVxuXG5cbi8qKlxuICogQ2FsbHMgY29uc3RydWN0b3IgYHRoaXNgIHdpdGggYXJndW1lbnRzIHBhc3NlZCBhcyBhcnJheVxuICogXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aGlzQ2xhc3MgQSBjbGFzcyBjb25zdHJ1Y3RvciB0aGF0IHdpbGwgYmUgY2FsbGVkXG4gKiBAcmV0dXJuIHtBcnJheXxBcnJheS1saWtlfSBhcmdzIEFycmF5IG9mIGFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIG5ld0FwcGx5KGFyZ3MpIHtcbiAgICBpZiAoISBBcnJheS5pc0FycmF5KGFyZ3MpKVxuICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncyk7XG4gICAgLy8gXCJudWxsXCIgaXMgY29udGV4dCB0byBwYXNzIHRvIGNsYXNzIGNvbnN0cnVjdG9yLCBmaXJzdCBwYXJhbWV0ZXIgb2YgYmluZFxuICAgIHZhciBhcmdzID0gW251bGxdLmNvbmNhdChhcmdzKTtcbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseSh0aGlzLCBhcmdzKSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIF9fID0gcmVxdWlyZSgnLi9wcm90b19vYmplY3QnKTtcblxuXG4vKipcbiAqIC0gW2ZpcnN0VXBwZXJDYXNlXSgjZmlyc3RVcHBlckNhc2UpXG4gKiAtIFtmaXJzdExvd2VyQ2FzZV0oI2ZpcnN0TG93ZXJDYXNlKVxuICogLSBbdG9SZWdFeHBdKCN0b1JlZ0V4cClcbiAqIC0gW3RvRnVuY3Rpb25dKCN0b0Z1bmN0aW9uKVxuICogLSBbdG9EYXRlXSgjdG9EYXRlKVxuICogLSBbdG9RdWVyeVN0cmluZ10oI3RvUXVlcnlTdHJpbmcpXG4gKiAtIFtmcm9tUXVlcnlTdHJpbmddKCNmcm9tUXVlcnlTdHJpbmcpXG4gKiAtIFtqc29uUGFyc2VdKCNqc29uUGFyc2UpXG4gKiAtIFtoYXNoQ29kZV0oI2hhc2hDb2RlKVxuICogLSBbdW5QcmVmaXhdKCN1blByZWZpeClcbiAqL1xuIHZhciBzdHJpbmdNZXRob2RzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZmlyc3RVcHBlckNhc2U6IGZpcnN0VXBwZXJDYXNlLFxuICAgIGZpcnN0TG93ZXJDYXNlOiBmaXJzdExvd2VyQ2FzZSxcbiAgICB0b1JlZ0V4cDogdG9SZWdFeHAsXG4gICAgdG9GdW5jdGlvbjogdG9GdW5jdGlvbixcbiAgICB0b0RhdGU6IHRvRGF0ZSxcbiAgICB0b1F1ZXJ5U3RyaW5nOiB0b1F1ZXJ5U3RyaW5nLFxuICAgIGZyb21RdWVyeVN0cmluZzogZnJvbVF1ZXJ5U3RyaW5nLFxuICAgIGpzb25QYXJzZToganNvblBhcnNlLFxuICAgIGhhc2hDb2RlOiBoYXNoQ29kZSxcbiAgICB1blByZWZpeDogdW5QcmVmaXhcbn07XG5cblxuLyoqXG4gKiBSZXR1cm5zIHN0cmluZyB3aXRoIHRoZSBmaXJzdCBjaGFyYWN0ZXIgY2hhbmdlZCB0byB1cHBlciBjYXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmIEEgc3RyaW5nIHRoYXQgd2lsbCBoYXZlIGl0cyBmaXJzdCBjaGFyYWN0ZXIgcmVwbGFjZWRcbiAqL1xuZnVuY3Rpb24gZmlyc3RVcHBlckNhc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMgPyB0aGlzWzBdLnRvVXBwZXJDYXNlKCkgKyB0aGlzLnNsaWNlKDEpIDogdGhpcztcbn1cblxuXG4vKipcbiAqIFJldHVybnMgc3RyaW5nIHdpdGggdGhlIGZpcnN0IGNoYXJhY3RlciBjaGFuZ2VkIHRvIGxvd2VyIGNhc2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGYgQSBzdHJpbmcgdGhhdCB3aWxsIGhhdmUgaXRzIGZpcnN0IGNoYXJhY3RlciByZXBsYWNlZFxuICovXG5mdW5jdGlvbiBmaXJzdExvd2VyQ2FzZSgpIHtcbiAgICByZXR1cm4gdGhpcyA/IHRoaXNbMF0udG9Mb3dlckNhc2UoKSArIHRoaXMuc2xpY2UoMSkgOiB0aGlzO1xufVxuXG5cbi8qKlxuICogQ29udmVydHMgc3RyaW5nIGNyZWF0ZWQgYnkgYHRvU3RyaW5nYCBtZXRob2Qgb2YgUmVnRXhwIGJhY2sgdG8gUmVnRXhwXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGYgc3RyaW5nIGNvbnRhaW5pbmcgcmVndWxhciBleHByZXNzaW9uIGluY2x1ZGluZyBlbmNsb3NpbmcgXCIvXCIgc3ltYm9scyBhbmQgZmxhZ3NcbiAqIEByZXR1cm4ge1JlZ0V4cH1cbiAqL1xuZnVuY3Rpb24gdG9SZWdFeHAoKSB7XG4gICAgdmFyIHJ4ID0gdGhpcy5tYXRjaChyZWdleHBTdHJpbmdQYXR0ZXJuKTtcbiAgICBpZiAocngpIHJldHVybiBuZXcgUmVnRXhwKHJ4WzFdLCByeFsyXSk7XG59XG52YXIgcmVnZXhwU3RyaW5nUGF0dGVybiA9IC9eXFwvKC4qKVxcLyhbZ2lteV0qKSQvO1xuXG5cbi8qKlxuICogQ29udmVydHMgc3RyaW5nIGNyZWF0ZWQgYnkgYHRvU3RyaW5nYCBtZXRob2Qgb2YgZnVuY3Rpb24gYmFjayB0byBmdW5jdGlvblxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmIHN0cmluZyBjb250YWluaW5nIGZ1bGwgZnVuY3Rpb24gY29kZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIHRvRnVuY3Rpb24oKSB7XG4gICAgdmFyIGZ1bmM7XG4gICAgdmFyIGNvZGUgPSAnZnVuYyA9ICcgKyB0aGlzICsgJzsnO1xuICAgIHRyeSB7XG4gICAgICAgIGV2YWwoY29kZSk7XG4gICAgICAgIHJldHVybiBmdW5jO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxufVxuXG5cbi8qKlxuICogQ29udmVydHMgc3RyaW5nIHRvIGRhdGUgaW4gYSBzYWZlIHdheSBzbyB0aGF0IHRoZSByZXNpdWx0IGlzIHVuZGVmaW5lZCBpZiBkYXRlIGlzIGludmFsaWRcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xEYXRlfSBzZWxmIHN0cmluZyBvciBkYXRlIG9iamVjdCB0byBjb252ZXJ0IHRvIFZBTElEIGRhdGVcbiAqIEByZXR1cm4ge1t0eXBlXX0gW2Rlc2NyaXB0aW9uXVxuICovXG5mdW5jdGlvbiB0b0RhdGUoKSB7XG4gICAgaWYgKCEgdGhpcykgcmV0dXJuO1xuICAgIHRyeSB7XG4gICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUodGhpcyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICBpZiAoZGF0ZSAmJiBkYXRlLmdldFRpbWUgJiYgIWlzTmFOKGRhdGUuZ2V0VGltZSgpKSlcbiAgICAgICAgcmV0dXJuIGRhdGU7XG59XG5cblxuLyoqXG4gKiBDb252ZXJ0IHBhcmFtcyBvYmplY3QgdG8gYSB1cmwgc3R5bGUgcXVlcnkgc3RyaW5nICh3aXRob3V0IFwiP1wiKVxuICogXG4gKiBAcGFyYW0ge09iamVjdH0gc2VsZiBUaGUgb2JqZWN0IGhhc2ggdG8gYmUgY29udmVydGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlbmNvZGUgb3B0aW9uYWwgZnVuY3Rpb24gdXNlZCB0byBlbmNvZGUgZGF0YSwgZW5jb2RlVVJJQ29tcG9uZW50IGlzIHVzZWQgaWYgbm90IHNwZWNpZmllZFxuICogQHJldHVybiB7U3RyaW5nfSB0aGUgcmVzdWx0aW5nIHF1ZXJ5IHN0cmluZ1xuICovXG5mdW5jdGlvbiB0b1F1ZXJ5U3RyaW5nKGVuY29kZSkge1xuICAgIHZhciBxcyA9ICcnXG4gICAgICAgICwgcGFyYW1zID0gdGhpcyB8fCB7fVxuICAgICAgICAsIGVuY29kZSA9IGVuY29kZSB8fCBlbmNvZGVVUklDb21wb25lbnQ7XG5cbiAgICBfXy5lYWNoS2V5LmNhbGwocGFyYW1zLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICAgIHFzICs9IGtleSArICc9JyArIGVuY29kZSh2YWx1ZSkgKyAnJic7XG4gICAgfSk7XG4gICAgXG4gICAgcmV0dXJuIHFzLnNsaWNlKDAsIC0xKTtcbn1cblxuXG4vKipcbiAqIENvbnZlcnQgdXJsIHN0eWxlIHF1ZXJ5IHN0cmluZyAod2l0aG91dCBcIj9cIikgaW50byBvYmplY3QgaGFzaFxuICogXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZiBUaGUgc3RyaW5nIHRvIGJlIGNvbnZlcnRlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZGVjb2RlIG9wdGlvbmFsIGRlY29kZSBmdW5jdGlvbiwgZGVjb2RlVVJJQ29tcG9uZW50IHdpbGwgYmUgdXNlZCBpZiBub3Qgc3VwcGxpZWRcbiAqIEByZXR1cm4ge09iamVjdH0gVGhlIHJlc3VsdGluZyBvYmplY3QgaGFzaFxuICovXG5mdW5jdGlvbiBmcm9tUXVlcnlTdHJpbmcoZGVjb2RlKSB7XG4gICAgdmFyIHBhaXJzID0gdGhpcy5zcGxpdCgnJicpXG4gICAgICAgICwgcmVzdWx0cyA9IHt9XG4gICAgICAgICwgZGVjb2RlID0gZGVjb2RlIHx8IGRlY29kZVVSSUNvbXBvbmVudDtcblxuICAgIHBhaXJzLmZvckVhY2goZnVuY3Rpb24ocGFpcikge1xuICAgICAgICB2YXIgc3BsaXRQYWlyID0gcGFpci5zcGxpdCgnPScpO1xuICAgICAgICBpZiAoc3BsaXRQYWlyLmxlbmd0aCA8IDIpIHJldHVybjtcbiAgICAgICAgdmFyIGtleSA9IHNwbGl0UGFpclswXVxuICAgICAgICAgICAgLCB2YWx1ZSA9IGRlY29kZShzcGxpdFBhaXJbMV0gfHwgJycpO1xuICAgICAgICBpZiAoIWtleSkgcmV0dXJuO1xuICAgICAgICByZXN1bHRzW2tleV0gPSB2YWx1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHRzO1xufVxuXG5cbi8qKlxuICogU2FmZSBKU09OLnBhcnNlLCByZXR1cm5zIHVuZGVmaW5lZCBpZiBKU09OLnBhcnNlIHRocm93cyBhbiBleGNlcHRpb25cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZiBKU09OIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBvYmplY3RcbiAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIGpzb25QYXJzZSgpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh0aGlzKTtcbiAgICB9IGNhdGNoIChlKSB7fVxufVxuXG5cbi8qKlxuICogRGFuIEJlcm5zdGVpbidzIGFsZ29yeXRobSB0byBjcmVhdGUgaGFzaCBmcm9tIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmIHN0cmluZyB0byBjb252ZXJ0IHRvIGhhc2hcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuZnVuY3Rpb24gaGFzaENvZGUoKSB7XG4gICAgdmFyIGhhc2ggPSA1MzgxXG4gICAgICAgICwgc3RyID0gdGhpc1xuICAgICAgICAsIGxlbiA9IHN0ci5sZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgY2hhciA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuICAgICAgICBoYXNoID0gKChoYXNoIDw8IDUpICsgaGFzaCkgKyBjaGFyOyAvKiBoYXNoICogMzMgKyBjICovXG4gICAgfVxuICAgIHJldHVybiBoYXNoO1xufVxuXG5cbi8qKlxuICogUmVtb3ZlcyBnaXZlbiBwcmVmaXggZnJvbSB0aGUgc3RyaW5nLiBJZiBzdHJpbmcgZG9lcyBub3QgYmVnaW4gZnJvbSB0aGUgcHJlZml4LCByZXR1cm5zIHVuZGVmaW5lZFxuICogXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiB1blByZWZpeChzdHIpIHtcbiAgICBpZiAodGhpcy5pbmRleE9mKHN0cikgPT0gMClcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZShzdHIsICcnKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiAtIFt0aW1lc10oI3RpbWVzKVxuICogLSBbcmVwZWF0XSgjcmVwZWF0KVxuICogLSBbdGFwXSgjdGFwKVxuICogLSBbcmVzdWx0XSgjcmVzdWx0KVxuICogLSBbaWRlbnRpdHldKCNpZGVudGl0eSlcbiAqIC0gW3Byb3BlcnR5XSgjcHJvcGVydHkpXG4gKiAtIFtjb21wYXJlUHJvcGVydHldKCNjb21wYXJlUHJvcGVydHkpXG4gKiAtIFtub29wXSgjbm9vcClcbiAqL1xudmFyIHV0aWxNZXRob2RzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgdGltZXM6IHRpbWVzLFxuICAgIHJlcGVhdDogcmVwZWF0LFxuICAgIHRhcDogdGFwLFxuICAgIHJlc3VsdDogcmVzdWx0LFxuICAgIGlkZW50aXR5OiBpZGVudGl0eSxcbiAgICBwcm9wZXJ0eTogcHJvcGVydHksXG4gICAgY29tcGFyZVByb3BlcnR5OiBjb21wYXJlUHJvcGVydHksXG4gICAgbm9vcDogbm9vcFxufTtcblxuXG4vKipcbiAqIENhbGxzIGBjYWxsYmFja2AgYHNlbGZgIHRpbWVzIHdpdGggYHRoaXNBcmdgIGFzIGNvbnRleHQuIENhbGxiYWNrIGlzIHBhc3NlZCBpdGVyYXRpb24gaW5kZXggZnJvbSAwIHRvIGBzZWxmLTFgXG4gKiBcbiAqIEBwYXJhbSB7SW50ZWdlcn0gc2VsZlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7QW55fSB0aGlzQXJnXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdGltZXMoY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICB2YXIgYXJyID0gQXJyYXkoTWF0aC5tYXgoMCwgdGhpcykpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpczsgaSsrKVxuICAgICAgICBhcnJbaV0gPSBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIGkpO1xuICAgIHJldHVybiBhcnI7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGFycmF5IHdpdGggdGhlIGZpcnN0IGFyZ3VtZW50IHJlcGVhdGVkIGB0aW1lc2AgdGltZXNcbiAqIEBwYXJhbSAge0FueX0gc2VsZlxuICogQHBhcmFtICB7SW50ZWdlcn0gdGltZXNcbiAqIEByZXR1cm4ge0FycmF5W0FueV19XG4gKi9cbmZ1bmN0aW9uIHJlcGVhdCh0aW1lcykge1xuICAgIHZhciBhcnIgPSBBcnJheShNYXRoLm1heCgwLCB0aW1lcykpOztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRpbWVzOyBpKyspXG4gICAgICAgIGFycltpXSA9IHRoaXM7XG4gICAgcmV0dXJuIGFycjtcbn1cblxuXG4vKipcbiAqIEZ1bmN0aW9uIHRvIHRhcCBpbnRvIGNoYWluZWQgbWV0aG9kcyBhbmQgdG8gaW5zcGVjdCBpbnRlcm1lZGlhcnkgcmVzdWx0XG4gKlxuICogQHBhcmFtIHtBbnl9IHNlbGYgdmFsdWUgdGhhdCdzIHBhc3NlZCBiZXR3ZWVuIGNoYWluZWQgbWV0aG9kc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIHdpdGggdGhlIHZhbHVlIChib3RoIGFzIGNvbnRleHQgYW5kIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIpXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIHRhcChmdW5jKSB7XG4gICAgZnVuYy5jYWxsKHRoaXMsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xufTtcblxuXG4vKipcbiAqIENhbGxzIGZ1bmN0aW9uIGBzZWxmYCAoZmlyc3QgcGFyYW1ldGVyIG9mIF8ucmVzdWx0KSB3aXRoIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuICogXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufEFueX0gc2VsZlxuICogQHBhcmFtIHtBbnl9IHRoaXNBcmcgY29udGV4dFxuICogQHBhcmFtIHtMaXN0fSBhcmd1bWVudHMgZXh0cmEgYXJndW1lbnRzXG4gKiBAcmV0dXJuIHtBbnl9XG4gKi9cbmZ1bmN0aW9uIHJlc3VsdCh0aGlzQXJnKSB7IC8vLCBhcmd1bWVudHNcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbidcbiAgICAgICAgICAgID8gdGhpcy5hcHBseSh0aGlzQXJnLCBhcmdzKVxuICAgICAgICAgICAgOiB0aGlzO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyBzZWxmLiBVc2VmdWwgZm9yIHVzaW5nIGFzIGFuIGl0ZXJhdG9yIGlmIHRoZSBhY3R1YWwgdmFsdWUgbmVlZHMgdG8gYmUgcmV0dXJuZWQuIFVubGlrZSBpbiB1bmRlcnNjb3JlIGFuZCBsb2Rhc2gsIHRoaXMgZnVuY3Rpb24gaXMgTk9UIHVzZWQgYXMgZGVmYXVsdCBpdGVyYXRvci5cbiAqXG4gKiBAcGFyYW0ge0FueX0gc2VsZiBcbiAqIEByZXR1cm4ge0FueX1cbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGZ1bmN0aW9uIHRoYXQgcGlja3MgdGhlIHByb3BlcnR5IGZyb20gdGhlIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gcHJvcGVydHkoKSB7XG4gICAgdmFyIGtleSA9IHRoaXM7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqW2tleV07XG4gICAgfTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCBpbiBhcnJheSBzb3J0IHRvIHNvcnQgYnkgYSBnaXZlbiBwcm9wZXJ0eVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxmXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gY29tcGFyZVByb3BlcnR5KCkge1xuICAgIHZhciBrZXkgPSB0aGlzO1xuICAgIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgIHJldHVybiBhW2tleV0gPCBiW2tleV1cbiAgICAgICAgICAgID8gLTFcbiAgICAgICAgICAgIDogYVtrZXldID4gYltrZXldXG4gICAgICAgICAgICAgICAgPyAxXG4gICAgICAgICAgICAgICAgOiAwO1xuICAgIH07XG59XG5cblxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IGRvZXMgbm90aGluZ1xuICovXG5mdW5jdGlvbiBub29wKCkge31cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgbWFrZVByb3RvSW5zdGFuY2VNZXRob2Q6IG1ha2VQcm90b0luc3RhbmNlTWV0aG9kLFxuICAgIG1ha2VQcm90b0Z1bmN0aW9uOiBtYWtlUHJvdG9GdW5jdGlvbixcbiAgICBtYWtlRmluZE1ldGhvZDogbWFrZUZpbmRNZXRob2Rcbn1cblxuXG5mdW5jdGlvbiBtYWtlUHJvdG9JbnN0YW5jZU1ldGhvZChtZXRob2QpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc2VsZiA9IG1ldGhvZC5hcHBseSh0aGlzLnNlbGYsIGFyZ3VtZW50cyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG59XG5cblxuZnVuY3Rpb24gbWFrZVByb3RvRnVuY3Rpb24obWV0aG9kKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAvLyB3aGVuIHRoZSBtZXRob2QgaXMgZXhlY3V0ZWQsIHRoZSB2YWx1ZSBvZiBcInRoaXNcIiB3aWxsIGJlIGFyZ3VtZW50c1swXSxcbiAgICAgICAgLy8gb3RoZXIgYXJndW1lbnRzIHN0YXJ0aW5nIGZyb20gIzEgd2lsbCBwYXNzZWQgdG8gbWV0aG9kIGFzIHBhcmFtZXRlcnMuXG4gICAgICAgIHJldHVybiBtZXRob2QuY2FsbC5hcHBseShtZXRob2QsIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuXG52YXIgX2Vycm9yID0gbmV3IEVycm9yO1xuXG4vKipcbiAqIFJldHVybnMgYGZpbmRgIG9yIGBmaW5kSW5kZXhgIG1ldGhvZCwgZGVwZW5kaW5nIG9uIHBhcmFtZXRlclxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hNZXRob2QgLSBtZXRob2QgdG8gdXNlIGZvciBpdGVyYXRpb24gKGZvckVhY2ggZm9yIGFycmF5IG9yIGVhY2hLZXkgZm9yIG9iamVjdClcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaW5kV2hhdCAndmFsdWUnIC0gcmV0dXJucyBmaW5kIG1ldGhvZCBvZiBBcnJheSAoaW1wbGVtZW50ZWQgaW4gRVM2KSBvciBmaW5kVmFsdWUgbWV0aG9kIG9mIE9iamVjdCwgYW55dGhpbmcgZWxzZSA9IHJldHVybnMgZmluZEluZGV4L2ZpbmRLZXkgbWV0aG9kcy5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBtYWtlRmluZE1ldGhvZChlYWNoTWV0aG9kLCBmaW5kV2hhdCkge1xuICAgIHZhciBhcmdJbmRleCA9IGZpbmRXaGF0ID09ICd2YWx1ZScgPyAwIDogMTtcblxuICAgIHJldHVybiBmdW5jdGlvbiBmaW5kVmFsdWVPckluZGV4KGNhbGxiYWNrLCB0aGlzQXJnLCBvbmx5RW51bWVyYWJsZSkge1xuICAgICAgICB2YXIgY2F1Z2h0RXJyb3I7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBlYWNoTWV0aG9kLmNhbGwodGhpcywgdGVzdEl0ZW0sIHRoaXNBcmcsIG9ubHlFbnVtZXJhYmxlKTtcbiAgICAgICAgfSBjYXRjaCAoZm91bmQpIHtcbiAgICAgICAgICAgIGlmIChmb3VuZCA9PT0gX2Vycm9yKSB0aHJvdyBjYXVnaHRFcnJvcjtcbiAgICAgICAgICAgIGVsc2UgcmV0dXJuIGZvdW5kO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGxvb2tpbmcgZm9yIGluZGV4IGFuZCBub3QgZm91bmQsIHJldHVybiAtMVxuICAgICAgICBpZiAoYXJnSW5kZXggJiYgZWFjaE1ldGhvZCA9PSBBcnJheS5wcm90b3R5cGUuZm9yRWFjaClcbiAgICAgICAgICAgIHJldHVybiAtMTsgXG5cbiAgICAgICAgZnVuY3Rpb24gdGVzdEl0ZW0odmFsdWUsIGluZGV4LCBzZWxmKSB7XG4gICAgICAgICAgICB2YXIgdGVzdDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGVzdCA9IGNhbGxiYWNrLmNhbGwodGhpcywgdmFsdWUsIGluZGV4LCBzZWxmKTtcbiAgICAgICAgICAgIH0gY2F0Y2goZXJyKSB7XG4gICAgICAgICAgICAgICAgY2F1Z2h0RXJyb3IgPSBlcnI7XG4gICAgICAgICAgICAgICAgdGhyb3cgX2Vycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRlc3QpXG4gICAgICAgICAgICAgICAgdGhyb3cgYXJndW1lbnRzW2FyZ0luZGV4XTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImFyZ3VtZW50c1s0XVsxNDFdWzBdLmFwcGx5KGV4cG9ydHMsYXJndW1lbnRzKSIsImFyZ3VtZW50c1s0XVsxNDJdWzBdLmFwcGx5KGV4cG9ydHMsYXJndW1lbnRzKSIsImFyZ3VtZW50c1s0XVsxNDZdWzBdLmFwcGx5KGV4cG9ydHMsYXJndW1lbnRzKSIsImFyZ3VtZW50c1s0XVsxNDddWzBdLmFwcGx5KGV4cG9ydHMsYXJndW1lbnRzKSJdfQ== ; \ No newline at end of file diff --git a/milo.bundle.map b/milo.bundle.map index fcfec0a..765d7fd 100644 --- a/milo.bundle.map +++ b/milo.bundle.map @@ -1,134 +1,159 @@ { "version": 3, "sources": [ - "/home/fozz/Projects/cc/milo/lib/abstract/facet.js", - "/home/fozz/Projects/cc/milo/lib/abstract/faceted_object.js", - "/home/fozz/Projects/cc/milo/lib/abstract/mixin.js", - "/home/fozz/Projects/cc/milo/lib/abstract/registry.js", - "/home/fozz/Projects/cc/milo/lib/attributes/a_bind.js", - "/home/fozz/Projects/cc/milo/lib/attributes/a_class.js", - "/home/fozz/Projects/cc/milo/lib/attributes/a_load.js", - "/home/fozz/Projects/cc/milo/lib/attributes/index.js", - "/home/fozz/Projects/cc/milo/lib/binder.js", - "/home/fozz/Projects/cc/milo/lib/classes.js", - "/home/fozz/Projects/cc/milo/lib/command/actions_history.js", - "/home/fozz/Projects/cc/milo/lib/command/cmd_registry.js", - "/home/fozz/Projects/cc/milo/lib/command/index.js", - "/home/fozz/Projects/cc/milo/lib/command/transaction.js", - "/home/fozz/Projects/cc/milo/lib/command/transaction_history.js", - "/home/fozz/Projects/cc/milo/lib/components/c_class.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facet.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Container.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Data.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Dom.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Drag.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Drop.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Events.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Frame.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Item.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/List.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/ModelFacet.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Options.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Template.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/Transfer.js", - "/home/fozz/Projects/cc/milo/lib/components/c_facets/cf_registry.js", - "/home/fozz/Projects/cc/milo/lib/components/c_info.js", - "/home/fozz/Projects/cc/milo/lib/components/c_registry.js", - "/home/fozz/Projects/cc/milo/lib/components/c_utils.js", - "/home/fozz/Projects/cc/milo/lib/components/classes/View.js", - "/home/fozz/Projects/cc/milo/lib/components/msg_api/data.js", - "/home/fozz/Projects/cc/milo/lib/components/msg_api/de_data.js", - "/home/fozz/Projects/cc/milo/lib/components/msg_api/drop.js", - "/home/fozz/Projects/cc/milo/lib/components/msg_src/dom_events.js", - "/home/fozz/Projects/cc/milo/lib/components/msg_src/frame.js", - "/home/fozz/Projects/cc/milo/lib/components/scope.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Button.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Combo.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/ComboList.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Date.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/DropTarget.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/FoldTree.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Group.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Hyperlink.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Image.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Input.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/InputList.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/List.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/ListItem.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/RadioGroup.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Select.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/SuperCombo.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Text.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Textarea.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Time.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/Wrapper.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/bootstrap/Alert.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/bootstrap/Dialog.js", - "/home/fozz/Projects/cc/milo/lib/components/ui/bootstrap/Dropdown.js", - "/home/fozz/Projects/cc/milo/lib/config.js", - "/home/fozz/Projects/cc/milo/lib/loader.js", - "/home/fozz/Projects/cc/milo/lib/messenger/index.js", - "/home/fozz/Projects/cc/milo/lib/messenger/m_api.js", - "/home/fozz/Projects/cc/milo/lib/messenger/m_api_rx.js", - "/home/fozz/Projects/cc/milo/lib/messenger/m_source.js", - "/home/fozz/Projects/cc/milo/lib/messenger/msngr_source.js", - "/home/fozz/Projects/cc/milo/lib/milo.js", - "/home/fozz/Projects/cc/milo/lib/minder.js", - "/home/fozz/Projects/cc/milo/lib/model/change_data.js", - "/home/fozz/Projects/cc/milo/lib/model/connector.js", - "/home/fozz/Projects/cc/milo/lib/model/index.js", - "/home/fozz/Projects/cc/milo/lib/model/m_msg_api.js", - "/home/fozz/Projects/cc/milo/lib/model/m_path.js", - "/home/fozz/Projects/cc/milo/lib/model/model_utils.js", - "/home/fozz/Projects/cc/milo/lib/model/path_msg_api.js", - "/home/fozz/Projects/cc/milo/lib/model/path_utils.js", - "/home/fozz/Projects/cc/milo/lib/model/synthesize/index.js", - "/home/fozz/Projects/cc/milo/lib/registry.js", - "/home/fozz/Projects/cc/milo/lib/services/de_constrs.js", - "/home/fozz/Projects/cc/milo/lib/services/dom_source.js", - "/home/fozz/Projects/cc/milo/lib/services/mail/index.js", - "/home/fozz/Projects/cc/milo/lib/services/mail/mail_api.js", - "/home/fozz/Projects/cc/milo/lib/services/mail/mail_source.js", - "/home/fozz/Projects/cc/milo/lib/services/window.js", - "/home/fozz/Projects/cc/milo/lib/use_components.js", - "/home/fozz/Projects/cc/milo/lib/use_facets.js", - "/home/fozz/Projects/cc/milo/lib/util/check.js", - "/home/fozz/Projects/cc/milo/lib/util/component_name.js", - "/home/fozz/Projects/cc/milo/lib/util/count.js", - "/home/fozz/Projects/cc/milo/lib/util/create_component_class.js", - "/home/fozz/Projects/cc/milo/lib/util/dom.js", - "/home/fozz/Projects/cc/milo/lib/util/dom_listeners.js", - "/home/fozz/Projects/cc/milo/lib/util/domready.js", - "/home/fozz/Projects/cc/milo/lib/util/dragdrop.js", - "/home/fozz/Projects/cc/milo/lib/util/error.js", - "/home/fozz/Projects/cc/milo/lib/util/fragment.js", - "/home/fozz/Projects/cc/milo/lib/util/index.js", - "/home/fozz/Projects/cc/milo/lib/util/json_parse.js", - "/home/fozz/Projects/cc/milo/lib/util/logger.js", - "/home/fozz/Projects/cc/milo/lib/util/logger_class.js", - "/home/fozz/Projects/cc/milo/lib/util/request.js", - "/home/fozz/Projects/cc/milo/lib/util/selection/index.js", - "/home/fozz/Projects/cc/milo/lib/util/storage/index.js", - "/home/fozz/Projects/cc/milo/lib/util/storage/msg_src.js", - "/home/fozz/Projects/cc/milo/lib/util/websocket/index.js", - "/home/fozz/Projects/cc/milo/lib/util/websocket/msg_api.js", - "/home/fozz/Projects/cc/milo/lib/util/websocket/msg_src.js", - "/home/fozz/Projects/cc/milo/node_modules/base32/lib/base32.js", - "/home/fozz/Projects/cc/milo/node_modules/browserify/node_modules/browser-builtins/builtin/fs.js", - "/home/fozz/Projects/cc/milo/node_modules/dot/doT.js", - "/home/fozz/Projects/cc/milo/node_modules/dot/index.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_array.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_function.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_number.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_object.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_prototype.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_string.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/proto_util.js", - "/home/fozz/Projects/cc/milo/node_modules/mol-proto/lib/utils.js" + "/Users/evgenypoberezkin/Work/CC/milo/lib/abstract/facet.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/abstract/faceted_object.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/abstract/mixin.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/abstract/registry.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/attributes/a_bind.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/attributes/a_class.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/attributes/a_load.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/attributes/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/binder.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/classes.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/command/actions_history.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/command/cmd_registry.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/command/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/command/transaction.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/command/transaction_history.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_class.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facet.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Container.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Data.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Dom.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Drag.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Drop.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Events.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Frame.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Item.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/List.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/ModelFacet.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Options.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Template.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/Transfer.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_facets/cf_registry.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_info.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_registry.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/c_utils.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/classes/View.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/msg_api/data.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/msg_api/de_data.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/msg_api/drop.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/msg_src/dom_events.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/msg_src/frame.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/scope.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Button.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Combo.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/ComboList.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Date.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/DropTarget.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/FoldTree.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Group.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Hyperlink.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Image.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Input.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/InputList.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/List.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/ListItem.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/RadioGroup.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Select.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/SuperCombo.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Text.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Textarea.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Time.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/Wrapper.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/bootstrap/Alert.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/bootstrap/Dialog.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/components/ui/bootstrap/Dropdown.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/config.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/loader.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/messenger/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/messenger/m_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/messenger/m_api_rx.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/messenger/m_source.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/messenger/msngr_source.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/milo.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/change_data.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/m_msg_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/m_path.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/model_utils.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/path_msg_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/path_utils.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/model/synthesize/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/registry.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/services/de_constrs.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/services/dom_source.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/services/mail/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/services/mail/mail_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/services/mail/mail_source.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/services/window.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/use_components.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/use_facets.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/check.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/component_name.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/count.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/create_component_class.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/dom.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/dom_listeners.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/domready.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/dragdrop.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/error.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/fragment.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/json_parse.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/logger.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/logger_class.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/request.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/selection/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/storage/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/storage/model.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/storage/msg_src.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/websocket/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/websocket/msg_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/lib/util/websocket/msg_src.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/base32/lib/base32.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/browserify/node_modules/browser-builtins/builtin/fs.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/dot/doT.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/dot/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/abstract/mixin.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/classes.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/config.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/messenger/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/messenger/m_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/messenger/m_api_rx.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/messenger/m_source.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/messenger/msngr_source.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/milo-core.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/minder.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/change_data.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/connector.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/m_msg_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/m_path.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/path_msg_api.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/path_utils.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/model/synthesize/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/util/check.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/util/index.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/util/logger.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/lib/util/logger_class.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_array.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_function.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_number.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_object.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_prototype.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_string.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/proto_util.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/milo-core/node_modules/mol-proto/lib/utils.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/mol-proto/lib/proto.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/mol-proto/lib/proto_array.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/mol-proto/lib/proto_prototype.js", + "/Users/evgenypoberezkin/Work/CC/milo/node_modules/mol-proto/lib/proto_string.js" ], "names": [], - "mappings": ";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACz5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9aA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9mBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnMA;AACA;AACA;AACA;AACA;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACznBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", + "mappings": ";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACz5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9aA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9mBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxqBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnMA;AACA;AACA;AACA;AACA;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvpBA;;ACAA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9KA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7NA;;ACAA;;;;ACAA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1MA;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;;ACAA;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACznBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/DA;;ACAA;;;;;;;;ACAA;;ACAA", "file": "generated.js", "sourceRoot": "", "sourcesContent": [ @@ -150,7 +175,7 @@ "'use strict';\n\n\nvar FacetedObject = require('../abstract/faceted_object')\n , facetsRegistry = require('./c_facets/cf_registry')\n , ComponentFacet = facetsRegistry.get('ComponentFacet')\n , componentUtils = require('./c_utils')\n , Messenger = require('../messenger')\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match\n , config = require('../config')\n , miloComponentName = require('../util/component_name')\n , logger = require('../util/logger')\n , domUtils = require('../util/dom')\n , ComponentError = require('../util/error').Component\n , BindAttribute = require('../attributes/a_bind')\n , Scope = require('./scope')\n , DOMStorage = require('../util/storage')\n , jsonParse = require('../util/json_parse');\n\nvar _makeComponentConditionFunc = componentUtils._makeComponentConditionFunc;\n\n\n/**\n * `milo.Component`\n * Base Component class. Subclass of [FacetedObject](../abstract/faceted_object.js.html), but none of this class methods should be directly used with component.\n * Its constructor passes its parameters, including its [scope](./scope.js.html), DOM element and name to [`init`](#init) method.\n * The constructor of Component class rarely needs to be used directly, as [milo.binder](../binder.js.html) creates components when it scans DOM tree.\n * [`Component.createComponentClass`](#createComponentClass) should be used to create a subclass of Component class with configured facets.\n *\n *\n * ####Component instance properties####\n *\n * - el - DOM element that component is attached to. If the second component is attached to the same DOM element, the warning will be logged to console. To get component reference from DOM element use [Component.getComponent](./c_utils.js.html#getComponent) class method. To inspect component via element in browser check `___milo_component` property of element (property name be changed using `milo.config`).\n * - scope - parent scope object, an instance of [Scope](./scope.js.html) class. To get parent component use [getScopeParent](#Component$getScopeParent) instance method of component. The actual path to get parent of conponent is `component.scope._hostObject.owner`, where `_hostObject` refers to [Container](c_facets/Container.js.html) facet of parent component and `owner` to the parent itself. The children of component are accessible via the scope of its container facet: `component.container.scope`. The scope hierarchy can be the same or different as the DOM hierarchy - DOM children of the component will be on the same scope as component if it does not have `Container` facet and in the scope of its Container facet if it has it. See [Scope](./scope.js.html).\n * - name - the name of component, should be unique for the scope where component belongs. To find component in scope the component's name should be used as property of scope object. See [Scope](./scope.js.html).\n * - facets - map of references of all component's facets (facet names are lowercase in this map). All facets can be accessed directly as properties of component, this property can be used to iterate facets (it is used in this way in [allFacets](#Component$allFacets) component's instance method that allows to call method with the same name on all facets).\n * - extraFacets - an array of names of facets that are added to component and do not form the part of component's class.\n * - _messenger - the reference to component's [messenger](../messenger/index.js.html). Rarely needs to be used directly as all commonly used methods of mesenger are available directly on component.\n *\n *\n * ####Component events####\n *\n * - 'childrenbound' - synchronously dispatched when children of DOM element which compnent is connected to are connected to components. The event is dispatched when component is created with `milo.binder` (as is almost always the case, as all Component class methods that create/copy components use `milo.binder` internally - component constructor and Component.create methods are not used in framework outside of `milo.binder` and rarely if ever need to be used in aplication).\n * - 'addedtoscope' - synchronously dispatched when component is added to scope.\n * - 'stateready' - aynchronously dispatched when component (together with its scope children) is created with [Component.createFromState](#Component$$createFromState) (or `createFromDataTransfer`) method. Can be dispatched by application if the component's state is set with some other mechanism. This event is not used in `milo`, it can be used in application in particular subclasses of component.\n * - 'getstatestarted' - emitted synchronously just before getState executes so components and facets can clean up their state for serialization. \n * - 'getstatecompleted' - emitted asynchronously after getState executes so components and facets can restore their state after serialization.\n *\n *\n * ####Component \"lifecycle\"####\n *\n * 1. Component constructor is called. Component's constructor simply calls constructor of [FacetedObject](../abstract/faceted_object.js.html) that is a superclass of Component. Subclasses of Component should not implement their own constructor, they can optionally implement `init` method, but most components do not need to do it.\n * 2. constructors and `init` methods of all facets are called in sequence. Same as components, facet do not implement their constructors, they can optionally implement `init` and `start` methods (see below). Inside `init` method there should be only general initialization code without any dependency on component itself (it is not ready yet) and other facets (as there is no specific facets creation order). If facet implements `init` method it MUST call inherited init with `ComponentFacet.prototype.init.apply(this, arguments)`.\n * 3. `init` method of component is called. At this point all facets are created but facets still can be not ready as they can have initialization code in `start` method. If component subclass implements `init` method it MUST call inherited method with `.prototype.init.apply(this, arguments)`, where is Component or another superclass the component is a subclass of.\n * 4. `check` method of all facets is called. This method adds facets that are not part of the component declaration (being part of the class or explicitely listed in bind attribute) but are required by facets that the compnent already has. Subclasses of [ComponentFacet](./c_facet.js.html) do not need to implement this method.\n * 5. `start` method of all facets is called. This method is usually implemented by ComponentFacet subclasses and it can have any initialization code that depends on component or on other facets that are the dependencies of a facet. Inherited `start` method should be called int he same way as written above.\n * 6. `start` method of component is called. This component method can be implemented by subclasses if they need to have some initialization code that depends on some facets and requires that these facets are fully inialized. Often such code also depends on component's scope children as well so this code should be inside `'childrenbound'` event subscriber.\n * 7. 'addedtoscope' event is dispatched when component is added to its parent's scope or to top level scope created by `milo.binder`.\n * 8. component's children are created (steps 1-6 above are followed for each child).\n * 9. 'childrenbound' event is dispatched when all component's children are created and added to their scope (see event description below).\n * 10. 'stateready' event is dispatched for component and all its children when component is create from state (see event description below).\n * 11. at this point component is in the \"interactive\" state when it and its facets will only respond to messages/events that they subscribed to during initialization.\n *\n *\n * @param {Scope} scope scope to which component will belong. It is usually a top level scope object returned by `milo.binder` or `scope` property of Container facet.\n * @param {Element} element DOM element that component is attached to\n * @param {String} name component name, should be unique in the scope of component\n * @param {ComponentInfo} componentInfo instance of ComponentInfo class that can be used to create a copy of component\n * TODO try removing it\n * @return {Component}\n */\nvar Component = _.createSubclass(FacetedObject, 'Component', true);\n\nmodule.exports = Component;\n\n_registerWithDomStorage('Component');\n\n\n/**\n * ####Component class methods####\n *\n * - [createComponentClass](#Component$$createComponentClass)\n * - [create](#Component$$create)\n * - [copy](#Component$$copy)\n * - [createOnElement](#Component$$createOnElement)\n * - [isComponent](c_utils.js.html#isComponent)\n * - [getComponent](c_utils.js.html#getComponent)\n * - [getContainingComponent](c_utils.js.html#getContainingComponent)\n * - [createFromState](#Component$$createFromState)\n * - [createFromDataTransfer](#Component$$createFromDataTransfer)\n */\n_.extend(Component, {\n createComponentClass: Component$$createComponentClass,\n create: Component$$create,\n copy: Component$$copy,\n createOnElement: Component$$createOnElement,\n isComponent: componentUtils.isComponent,\n getComponent: componentUtils.getComponent,\n getContainingComponent: componentUtils.getContainingComponent,\n createFromState: Component$$createFromState,\n createFromDataTransfer: Component$$createFromDataTransfer\n});\ndelete Component.createFacetedClass;\n\n\n/**\n * ####Component instance methods####\n *\n * - [init](#Component$init)\n * - [createElement](#Component$createElement)\n * - [hasFacet](#Component$hasFacet)\n * - [addFacet](#Component$addFacet)\n * - [allFacets](#Component$allFacets)\n * - [rename](#Component$rename)\n * - [remove](#Component$remove)\n * - [getState](#Component$getState)\n * - [getTransferState](#Component$getTransferState)\n * - [setState](#Component$setState)\n * - [getScopeParent](#Component$getScopeParent)\n * - [getTopScopeParent](#Component$getTopScopeParent)\n * - [getScopeParentWithClass](#Component$getScopeParentWithClass)\n * - [getTopScopeParentWithClass](#Component$getTopScopeParentWithClass)\n * - [walkScopeTree](#Component$walkScopeTree)\n * - [broadcast](#Component$broadcast)\n * - [destroy](#Component$destroy)\n * - [isDestroyed](#Component$isDestroyed)\n *\n *\n * #####[Messenger](../messenger/index.js.html) methods available on component#####\n *\n * - [on](../messenger/index.js.html#Messenger$on) - single subscribe\n * - [off](../messenger/index.js.html#Messenger$off) - single unsubscribe\n * - [onMessages](../messenger/index.js.html#Messenger$onMessages) - multiple subscribe\n * - [offMessages](../messenger/index.js.html#Messenger$offMessages) - multiple unsubscribe\n * - [postMessage](../messenger/index.js.html#Messenger$postMessage) - post message on component\n * - [getSubscribers](../messenger/index.js.html#Messenger$getSubscribers) - get subscribers for a given message\n */\n_.extendProto(Component, {\n init: Component$init,\n start: Component$start,\n createElement: Component$createElement,\n hasFacet: Component$hasFacet,\n addFacet: Component$addFacet,\n allFacets: Component$allFacets,\n rename: Component$rename,\n remove: Component$remove,\n insertInto: Component$insertInto,\n\n getState: Component$getState,\n getTransferState: Component$getTransferState,\n _getState: Component$_getState,\n setState: Component$setState,\n \n getScopeParent: Component$getScopeParent,\n getTopScopeParent: Component$getTopScopeParent,\n getScopeParentWithClass: Component$getScopeParentWithClass,\n getTopScopeParentWithClass: Component$getTopScopeParentWithClass,\n\n setScopeParentFromDOM: Component$setScopeParentFromDOM,\n\n walkScopeTree: Component$walkScopeTree,\n\n treePathOf: Component$treePathOf,\n getComponentAtTreePath: Component$getComponentAtTreePath,\n insertAtTreePath: Component$insertAtTreePath,\n\n broadcast: Component$broadcast,\n destroy: Component$destroy,\n isDestroyed: Component$isDestroyed\n});\n\n\n/**\n * Expose Messenger methods on Component prototype\n */\nvar MESSENGER_PROPERTY = '_messenger';\nMessenger.useWith(Component, MESSENGER_PROPERTY, Messenger.defaultMethods);\n\n\nvar COMPONENT_DATA_TYPE_PREFIX = 'x-application/milo-component';\nvar COMPONENT_DATA_TYPE_REGEX = /x-application\\/milo-component\\/([a-z_$][0-9a-z_$]*)(?:\\/())/i;\n\n/**\n * Component class method\n * Creates a subclass of component from the map of configured facets.\n * This method wraps and replaces [`createFacetedClass`](../abstract/faceted_object.js.html#createFacetedClass) class method of FacetedObject.\n * Unlike createFacetedClass, this method take facet classes from registry by their name, so only map of facets configuration needs to be passed. All facets classes should be subclasses of [ComponentFacet](./c_facet.js.html)\n *\n * @param {String} name class name\n * @param {Object[Object] | Array[String]} facetsConfig map of facets configuration.\n * If some facet does not require configuration, `undefined` should be passed as the configuration for the facet.\n * If no facet requires configuration, the array of facets names can be passed.\n * @return {Subclass(Component)}\n */\nfunction Component$$createComponentClass(name, facetsConfig) {\n // convert array of facet names to map of empty facets configurations\n if (Array.isArray(facetsConfig)) {\n var configMap = {};\n facetsConfig.forEach(function(fct) {\n var fctName = _.firstLowerCase(fct);\n configMap[fctName] = {};\n });\n facetsConfig = configMap;\n }\n\n // construct map of facets classes from facetRegistry\n var facetsClasses;\n if (typeof facetsConfig == 'object' && _.keys(facetsConfig).length) {\n facetsClasses = {};\n _.eachKey(facetsConfig, function(fctConfig, fct) {\n var fctName = _.firstLowerCase(fct);\n var fctClassName = _.firstUpperCase(fct);\n facetsClasses[fctName] = facetsRegistry.get(fctClassName);\n });\n }\n\n // create subclass of Component using method of FacetedObject\n var ComponentClass = FacetedObject.createFacetedClass.call(this, name, facetsClasses, facetsConfig);\n \n _registerWithDomStorage(name);\n\n return ComponentClass;\n}\n\n\nfunction _registerWithDomStorage(className) {\n DOMStorage.registerDataType(className, Component_domStorageSerializer, Component_domStorageParser);\n}\n\n\nfunction Component_domStorageSerializer(component) {\n var state = component.getState();\n return JSON.stringify(state); \n}\n\n\nfunction Component_domStorageParser(compStr, compClassName) {\n var state = jsonParse(compStr);\n if (state)\n return Component.createFromState(state);\n}\n\n\n/**\n * Component class method\n * Creates component from [ComponentInfo](./c_info.js.html) (used by [milo.binder](../binder.js.html) and to copy component)\n * Component of any registered class (see [componentsRegistry](./c_registry.js.html)) with any additional registered facets (see [facetsRegistry](./c_facets/cf_registry.js.html)) can be created using this method.\n *\n * @param {ComponentInfo} info\n * @param {Boolean} throwOnErrors If set to false, then errors will only be logged to console. True by default.\n @ @return {Component}\n */\nfunction Component$$create(info, throwOnErrors) {\n var ComponentClass = info.ComponentClass;\n\n if (typeof ComponentClass != 'function') {\n var message = 'create: component class should be function, \"' + typeof ComponentClass + '\" passed'; \n if (throwOnErrors === false) {\n logger.error('Component', message, ';using base Component class instead');\n ComponentClass = Component;\n } else\n throw new ComponentError(message);\n }\n\n var aComponent = new ComponentClass(info.scope, info.el, info.name, info);\n\n if (info.extraFacetsClasses)\n _.eachKey(info.extraFacetsClasses, function(FacetClass) {\n if (! aComponent.hasFacet(FacetClass))\n aComponent.addFacet(FacetClass, undefined, undefined, throwOnErrors);\n });\n\n return aComponent;\n}\n\n\n/**\n * Component class method\n * Create a copy of component, including a copy of DOM element. Returns a copy of `component` (of the same class) with new DOM element (not inserted into page).\n * Component is added to the same scope as the original component.\n *\n * @param {Component} component an instance of Component class or subclass\n * @param {Boolean} deepCopy optional `true` to make deep copy of DOM element, otherwise only element without children is copied\n * @return {Component}\n */\nfunction Component$$copy(component, deepCopy) {\n check(component, Component);\n check(deepCopy, Match.Optional(Boolean));\n\n if (deepCopy && !component.container) \n throw new ComponentError('Cannot deep copy component without container facet');\n\n // copy DOM element, using Dom facet if it is available\n var newEl = component.dom \n ? component.dom.copy(deepCopy)\n : component.el.cloneNode(deepCopy);\n\n var ComponentClass = component.constructor;\n\n // create component of the same class on the element\n var aComponent = ComponentClass.createOnElement(newEl, undefined, component.scope, component.extraFacets);\n var state = component._getState(deepCopy || false);\n aComponent.setState(state);\n _.deferMethod(aComponent, 'broadcast', 'stateready');\n return aComponent;\n}\n\n\n/**\n * Component class method\n * Creates an instance of component atached to element. All subclasses of component inherit this method.\n * Returns the component of the class this method is used with (thecontext of the method call).\n *\n * @param {Element} el optional element to attach component to. If element is not passed, it will be created\n * @param {String} innerHTML optional inner html to insert in element before binding.\n * @param {Scope} rootScope optional scope to put component in. If not passed, component will be attached to the scope that contains the element. If such scope does not exist, new scope will be created.\n * @param {Array[String]} extraFacets list of extra facet to add to component\n * @return {Subclass(Component)}\n */\nfunction Component$$createOnElement(el, innerHTML, rootScope, extraFacets) {\n check(innerHTML, Match.Optional(String));\n check(rootScope, Match.Optional(Scope));\n check(extraFacets, Match.Optional([String]));\n\n // \"this\" refers to the class of component here, as this is a class method\n if (el && innerHTML) el.innerHTML = innerHTML;\n el = el || _createComponentElement.call(this, innerHTML);\n rootScope = rootScope || _findOrCreateComponentRootScope(el);\n var aComponent = _addAttributeAndBindComponent.call(this, el, rootScope, extraFacets);\n aComponent.broadcast('stateready');\n return aComponent;\n}\n\nfunction _createComponentElement(innerHTML) {\n // \"this\" refers to the class of component here, as this is a class method\n var Dom = facetsRegistry.get('Dom')\n , domFacetConfig = this.getFacetConfig('dom')\n , templateFacetConfig = this.getFacetConfig('template')\n , template = templateFacetConfig && templateFacetConfig.template;\n\n var elConfig = {\n domConfig: domFacetConfig,\n template: template,\n content: innerHTML\n };\n\n return Dom.createElement(elConfig);\n}\n\nfunction _findOrCreateComponentRootScope(el) {\n var parent = Component.getContainingComponent(el, false, 'Container');\n return parent ? parent.container.scope : new Scope(el);\n}\n\nfunction _addAttributeAndBindComponent(el, rootScope, extraFacets) {\n // add bind attribute to element\n var attr = new BindAttribute(el);\n // \"this\" refers to the class of component here, as this is a class method\n attr.compClass = this.name;\n attr.compFacets = extraFacets;\n attr.decorate();\n\n // should be required here to resolve circular dependency\n var miloBinder = require('../binder');\n miloBinder(el, rootScope);\n\n return rootScope[attr.compName];\n}\n\n/**\n * Component class method\n * Creates component from component state, that includes information about its class, extra facets, facets data and all scope children.\n * This is used to save/load, copy/paste and drag/drop component\n *\n * @param {Object} state state from which component will be created\n * @param {Scope} rootScope scope to which component will be added\n * @param {Boolean} newUniqueName optional `true` to create component with the name different from the original one. `False` by default.\n * @param {Boolean} throwOnErrors If set to false, then errors will only be logged to console. True by default.\n * @return {Component} component\n */\nfunction Component$$createFromState(state, rootScope, newUniqueName, throwOnErrors) {\n check(state, Match.ObjectIncluding({\n compName: Match.Optional(String),\n compClass: Match.Optional(String),\n extraFacets: Match.Optional([String]),\n facetsStates: Match.Optional(Object),\n outerHTML: String\n }));\n\n var miloBinder = require('../binder');\n\n // create wrapper element optionally renaming component\n var wrapEl = _createComponentWrapElement(state, newUniqueName);\n\n // instantiate all components from HTML\n var scope = miloBinder(wrapEl, undefined, undefined, throwOnErrors);\n\n // as there should only be one component, call to _any will return it\n var component = scope._any();\n\n // set component's scope\n if (rootScope) {\n component.scope = rootScope;\n rootScope._add(component);\n }\n\n // restore component state\n component.setState(state);\n _.deferMethod(component, 'broadcast', 'stateready');\n\n return component; \n}\n\n\n// used by Component$$createFromState\nfunction _createComponentWrapElement(state, newUniqueName) {\n var wrapEl = document.createElement('div');\n wrapEl.innerHTML = state.outerHTML;\n\n var children = domUtils.children(wrapEl);\n if (children.length != 1)\n throw new ComponentError('cannot create component: incorrect HTML, elements number: ' + children.length + ' (should be 1)');\n var compEl = children[0];\n var attr = new BindAttribute(compEl);\n attr.compName = newUniqueName ? miloComponentName() : state.compName;\n attr.compClass = state.compClass;\n attr.compFacets = state.extraFacets;\n attr.decorate();\n\n return wrapEl;\n}\n\n/**\n * Creates a component from a DataTransfer object (if possible)\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer\n * @param {DataTransfer} dataTransfer Data transfer\n */\nfunction Component$$createFromDataTransfer(dataTransfer) {\n var dataType = _.find(dataTransfer.types, function (type) {\n return COMPONENT_DATA_TYPE_REGEX.test(type);\n });\n if (!dataType) return;\n\n var state = _.jsonParse(dataTransfer.getData(dataType));\n if (!state) return;\n\n return Component.createFromState(state, undefined, true);\n}\n\n\n/**\n * Component instance method.\n * Initializes component. Automatically called by inherited constructor of FacetedObject.\n * Subclasses should call inherited init methods:\n * ```\n * Component.prototype.init.apply(this, arguments)\n * ```\n *\n * @param {Scope} scope scope to which component will belong. It is usually a top level scope object returned by `milo.binder` or `scope` property of Container facet.\n * @param {Element} element DOM element that component is attached to\n * @param {String} name component name, should be unique in the scope of component\n * @param {ComponentInfo} componentInfo instance of ComponentInfo class that can be used to create a copy of component\n * TODO try removing it\n */\nfunction Component$init(scope, element, name, componentInfo) {\n // create DOM element if it wasn't passed to Constructor\n this.el = element || this.createElement();\n\n // store reference to component on DOM element\n if (this.el) {\n // check that element does not have a component already atached\n var elComp = this.el[config.componentRef];\n if (elComp)\n logger.warn('component ' + name + ' attached to element that already has component ' + elComp.name);\n\n this.el[config.componentRef] = this;\n }\n\n _.defineProperties(this, {\n componentInfo: componentInfo,\n extraFacets: []\n }, _.ENUM);\n\n this.name = name;\n this.scope = scope;\n\n // create component messenger\n var messenger = new Messenger(this);\n _.defineProperty(this, MESSENGER_PROPERTY, messenger);\n\n // check all facets dependencies (required facets)\n this.allFacets('check');\n\n // start all facets\n this.allFacets('start');\n\n // call start method if it's defined in subclass\n if (this.start) this.start();\n}\n\n\n/**\n * This is a stub to avoid confusion whether the method of superclass should be called in subclasses\n * The start method of subclass instance is called once all the facets are created, initialized and started (see above)\n */\nfunction Component$start() {}\n\n\n/**\n * Component instance method.\n * Initializes the element which this component is bound to\n *\n * This method is called when a component is instantiated outside the DOM and\n * will generate a new element for the component.\n * \n * @return {Element}\n */\nfunction Component$createElement() {\n if (typeof document == 'undefined')\n return;\n\n this.el = this.dom\n ? this.dom.createElement()\n : document.createElement('DIV');\n\n return this.el;\n}\n\n\n/**\n * Component instance method\n * Returns true if component has facet\n *\n * @param {Function|String} facetNameOrClass\n * @return {Boolean}\n */\nfunction Component$hasFacet(facetNameOrClass) {\n var facetName = _.firstLowerCase(typeof facetNameOrClass == 'function'\n ? facetNameOrClass.name\n : facetNameOrClass);\n\n var facet = this[facetName];\n if (! facet instanceof ComponentFacet)\n logger.warn('expected facet', facetName, 'but this property name is used for something else');\n\n return !! facet;\n}\n\n\n/**\n * Component instance method.\n * Adds facet with given name or class to the instance of Component (or its subclass).\n * \n * @param {String|Subclass(Component)} facetNameOrClass name of facet class or the class itself. If name is passed, the class will be retireved from facetsRegistry\n * @param {Object} facetConfig optional facet configuration\n * @param {String} facetName optional facet name. Allows to add facet under a name different from the class name supplied.\n * @param {Boolean} throwOnErrors If set to false, then errors will only be logged to console. True by default.\n */\nfunction Component$addFacet(facetNameOrClass, facetConfig, facetName, throwOnErrors) {\n check(facetNameOrClass, Match.OneOf(String, Match.Subclass(ComponentFacet)));\n check(facetConfig, Match.Optional(Object));\n check(facetName, Match.Optional(String));\n\n var FacetClass;\n // if only name passed, retrieve facet class from registry\n if (typeof facetNameOrClass == 'string') {\n var facetClassName = _.firstUpperCase(facetNameOrClass);\n FacetClass = facetsRegistry.get(facetClassName);\n } else \n FacetClass = facetNameOrClass;\n\n if (!facetName)\n facetName = _.firstLowerCase(FacetClass.name);\n\n this.extraFacets.push(facetName);\n\n // add facet using method of FacetedObject\n var newFacet = FacetedObject.prototype.addFacet.call(this, FacetClass, facetConfig, facetName, throwOnErrors);\n\n // check depenedencies and start facet\n if (newFacet.check) newFacet.check();\n if (newFacet.start) newFacet.start();\n}\n\n\n/**\n * Component instance method.\n * Envoke given method with optional parameters on all facets.\n * Returns the map of values returned by all facets. If the facet doesn't have the method it is simply not called and the value in the map will be undefined.\n *\n * @param {String} method method name to envoke on the facet\n * @return {Object}\n */\nfunction Component$allFacets(method) { // ,... arguments\n var args = _.slice(arguments, 1);\n\n return _.mapKeys(this.facets, function(facet, fctName) {\n if (facet && typeof facet[method] == 'function')\n return facet[method].apply(facet, args);\n });\n}\n\n\n/**\n * Component instance method.\n * \n * @param {[String]} name optional new name of component, \n * @param {[Boolean]} renameInScope optional false to not rename ComponentInfo object in its scope, true by default\n */\nfunction Component$rename(name, renameInScope) {\n name = name || miloComponentName();\n this.componentInfo.rename(name, false);\n Scope.rename(this, name, renameInScope);\n}\n\n\n/**\n * Component instance method.\n * Removes component from its scope.\n *\n * @param {Boolean} preserveScopeProperty true not to delete scope property of component\n * @param {Boolean} quiet optional true to suppress the warning message if the component is not in scope\n */\nfunction Component$remove(preserveScopeProperty, quiet) {\n if (this.scope) {\n this.scope._remove(this.name, quiet);\n if (! preserveScopeProperty)\n delete this.scope;\n }\n}\n\n\n/**\n * Component instance method.\n * Inserts the component into the DOM and attempts to adjust the scope tree accordingly.\n * @param {HTMLElement} parentEl The element into which the component should be inserted.\n * @param {HTMLElement} referenceEl (optional) The reference element it should be inserted before.\n */\nfunction Component$insertInto(parentEl, referenceEl) {\n parentEl.insertBefore(this.el, referenceEl);\n this.setScopeParentFromDOM();\n}\n\n\n/**\n * Component instance method\n * Retrieves all component state, including information about its class, extra facets, facets data and all scope children.\n * This information is used to save/load, copy/paste and drag/drop component \n * Returns component state\n *\n * @this {Component} component which state will be saved\n * @return {Object}\n */\nfunction Component$getState() {\n this.broadcast('getstatestarted', { rootComponent: this }, undefined, true);\n var state = this._getState(true);\n state.outerHTML = this.el.outerHTML;\n _.deferMethod(this, 'broadcast', 'getstatecompleted', { rootComponent: this }, undefined, true);\n return state;\n}\n\n\n/**\n * Component instance method\n * Retrieves all component state, including information about its class, extra facets, facets data and all scope children.\n * This information is used to save/load, copy/paste and drag/drop component \n * If component has [Transfer](./c_facets/Transfer.js.html) facet on it, this method retrieves state from this facet\n * Returns component state\n *\n * @this {Component} component which state will be saved\n * @param {Object} options can be used by subclasses. \n * @return {Object}\n */\nfunction Component$getTransferState(options) {\n return this.transfer\n ? this.transfer.getState(options)\n : this.getState(options);\n}\n\n\n/**\n * Component instance method\n * Returns the state of component\n * Used by class method `Component.getState` and by [Container](./c_facets/Container.js.html) facet.\n *\n * @private\n * @param {Boolean} deepState false to get shallow state from all facets (true by default)\n * @return {Object}\n */\nfunction Component$_getState(deepState){\n\n var facetsStates = this.allFacets('getState', deepState === false ? false : true);\n facetsStates = _.filterKeys(facetsStates, function(fctState) {\n return !! fctState;\n });\n\n return {\n compName: this.name,\n compClass: this.constructor.name,\n extraFacets: this.extraFacets,\n facetsStates: facetsStates\n };\n}\n\n\n/**\n * Component instance method\n * Sets the state of component.\n * Used by class method `Component.createFromState` and by [Container](./c_facets/Container.js.html) facet.\n *\n * @private\n * @param {Object} state state to set the component\n */\nfunction Component$setState(state) {\n if (state.facetsStates)\n _.eachKey(state.facetsStates, function(fctState, fctName) {\n var facet = this[fctName];\n if (facet && typeof facet.setState == 'function')\n facet.setState(fctState);\n }, this);\n}\n\n\n/**\n * Component instance method.\n * Returns the scope parent of a component.\n * If `conditionOrFacet` parameter is not specified, an immediate parent will be returned, otherwise the closest ancestor with a specified facet or passing condition test.\n *\n * @param {Function|String} conditionOrFacet optional condition that component should pass (or facet name it should contain)\n * @return {Component|undefined}\n */\nfunction Component$getScopeParent(conditionOrFacet) {\n return _callGetScopeParent.call(this, _getScopeParent, conditionOrFacet);\n}\n\nfunction _callGetScopeParent(_getScopeParentFunc, conditionOrFacet) {\n check(conditionOrFacet, Match.Optional(Match.OneOf(Function, String)));\n var conditionFunc = componentUtils._makeComponentConditionFunc(conditionOrFacet);\n return _getScopeParentFunc.call(this, conditionFunc); \n}\n\nfunction _getScopeParent(conditionFunc) {\n var parent;\n try { parent = this.scope._hostObject.owner; } catch(e) {}\n\n // Where there is no parent, this function will return undefined\n // The parent component is checked recursively\n if (parent) {\n if (! conditionFunc || conditionFunc(parent) )\n return parent;\n else\n return _getScopeParent.call(parent, conditionFunc);\n }\n}\n\n\n/**\n * Component instance method\n * Returns scope parent with a given class, with same class if not specified\n *\n * @param {[Function]} ComponentClass component class that the parent should have, same class by default\n * @return {Component}\n */\nfunction Component$getScopeParentWithClass(ComponentClass) {\n ComponentClass = ComponentClass || this.constructor;\n return _getScopeParent.call(this, function(comp) {\n return comp instanceof ComponentClass;\n });\n}\n\n\n/**\n * Component instance method.\n * Returns the topmost scope parent of a component.\n * If `conditionOrFacet` parameter is not specified, the topmost scope parent will be returned, otherwise the topmost ancestor with a specified facet or passing condition test.\n *\n * @param {Function|String} conditionOrFacet optional condition that component should pass (or facet name it should contain)\n * @return {Component|undefined}\n */\nfunction Component$getTopScopeParent(conditionOrFacet) {\n return _callGetScopeParent.call(this, _getTopScopeParent, conditionOrFacet);\n}\n\nfunction _getTopScopeParent(conditionFunc) {\n var topParent\n , parent = this;\n do {\n parent = _getScopeParent.call(parent, conditionFunc);\n if (parent)\n topParent = parent;\n } while (parent);\n\n return topParent;\n}\n\n\n/**\n * Component instance method\n * Returns scope parent with a given class, with same class if not specified\n *\n * @param {[Function]} ComponentClass component class that the parent should have, same class by default\n * @return {Component}\n */\nfunction Component$getTopScopeParentWithClass(ComponentClass) {\n ComponentClass = ComponentClass || this.constructor;\n return _getTopScopeParent.call(this, function(comp) {\n return comp instanceof ComponentClass;\n });\n}\n\n\n/**\n * Component instance method\n * Finds scope parent of component using DOM tree (unlike getScopeParent that simply goes up the scope tree).\n * While getScopeParent is faster it may fail if scope chain is not setup yet (e.g., when component has been just inserted).\n * The scope property of component will be changed to point to scope object of container facet of that parent.\n * Returned scope parent of the component will be undefined (as well as component's scope property) if no parent in the DOM tree has container facet.\n * TODO Method will not bind DOM children correctly if component has no container facet.\n *\n * @return {Component}\n */\nfunction Component$setScopeParentFromDOM() {\n var parentEl = this.el.parentNode;\n\n var parent, foundParent;\n while (parentEl && ! foundParent) {\n parent = Component.getComponent(parentEl);\n foundParent = parent && parent.container;\n parentEl = parentEl.parentNode;\n }\n\n this.remove(); // remove component from its current scope (if it is defined)\n if (foundParent) {\n this.rename(undefined, false);\n parent.container.scope._add(this);\n return parent;\n } \n}\n\n\n/**\n * Walks component tree, calling provided callback on each component\n *\n * @param callback\n * @param thisArg\n */\nfunction Component$walkScopeTree(callback, thisArg) {\n callback.call(thisArg, this);\n if (!this.container) return;\n this.container.scope._each(function(component) {\n component.walkScopeTree(callback, thisArg);\n });\n}\n\n\nfunction Component$treePathOf(component) {\n return domUtils.treePathOf(this.el, component.el);\n}\n\n\nfunction Component$getComponentAtTreePath(treePath, nearest) {\n var node = domUtils.getNodeAtTreePath(this.el, treePath, nearest);\n return Component.getComponent(node);\n}\n\n\nfunction Component$insertAtTreePath(treePath, component, nearest) {\n var wasInserted = domUtils.insertAtTreePath(this.el, treePath, component.el);\n if (wasInserted) component.setScopeParentFromDOM();\n return wasInserted;\n}\n\n\n/**\n * Broadcast message to component and to all its scope children\n *\n * @param {String|RegExp} msg message to be sent\n * @param {[Any]} data optional message data\n * @param {[Function]} callback optional callback\n * @param {[Boolean]} synchronously if it should use postMessageSync\n */\nfunction Component$broadcast(msg, data, callback, synchronously) {\n var postMethod = synchronously ? 'postMessageSync' : 'postMessage';\n this.walkScopeTree(function(component) {\n component[postMethod](msg, data, callback);\n });\n}\n\n\n/**\n * Destroy component: removes component from DOM, removes it from scope, deletes all references to DOM nodes and unsubscribes from all messages both component and all facets\n */\nfunction Component$destroy(quiet) {\n if (this._destroyed) {\n if (!quiet) logger.warn('Component destroy: component is already destroyed');\n return;\n }\n this.remove(false, quiet);\n this.allFacets('destroy');\n this[MESSENGER_PROPERTY].destroy();\n if (this.el) {\n domUtils.detachComponent(this.el);\n domUtils.removeElement(this.el);\n delete this.el;\n }\n this.componentInfo.destroy();\n this._destroyed = true;\n}\n\n\n/**\n * Returns true if component was destroyed\n *\n * @return {Boolean}\n */\nfunction Component$isDestroyed() {\n return this._destroyed;\n}\n", "'use strict';\n\n/**\n * `milo.Component.Facet`\n *\n * The class fot the facet of component. When a component is created, it\n * creates all its facets.\n *\n * See Facets section on information about available facets and on\n * how to create new facets classes.\n *\n * - Component - basic compponent class\n * - ComponentFacet - basic\n */\n\nvar Facet = require('../abstract/facet')\n , Messenger = require('../messenger')\n , FacetError = require('../util/error').Facet\n , componentUtils = require('./c_utils')\n , _ = require('mol-proto');\n\nvar ComponentFacet = _.createSubclass(Facet, 'ComponentFacet');\n\nmodule.exports = ComponentFacet;\n\n\n/**\n * postDomParent\n *\n * If facet has DOM parent facet (see `domParent` method), posts the message to this facet.\n *\n * @param {String} messageType\n * @param {Object} messageData\n */\nvar postDomParent = _.partial(_postParent, domParent);\n\n/**\n * postScopeParent\n *\n * If facet has scope parent facet (see `scopeParent` method), posts the message to this facet.\n *\n * @param {String} messageType\n * @param {Object} messageData\n */\nvar postScopeParent = _.partial(_postParent, scopeParent);\n\n\n_.extendProto(ComponentFacet, {\n init: ComponentFacet$init,\n start: ComponentFacet$start,\n check: ComponentFacet$check,\n destroy: ComponentFacet$destroy,\n onConfigMessages: ComponentFacet$onConfigMessages,\n domParent: domParent,\n postDomParent: postDomParent,\n scopeParent: scopeParent,\n postScopeParent: postScopeParent,\n getMessageSource: getMessageSource,\n dispatchSourceMessage: dispatchSourceMessage,\n _createMessenger: _createMessenger,\n _setMessageSource: _setMessageSource,\n _createMessageSource: _createMessageSource,\n _createMessageSourceWithAPI: _createMessageSourceWithAPI\n});\n\n_.extend(ComponentFacet, {\n requiresFacet: requiresFacet\n});\n\n\n/**\n * Expose Messenger methods on Facet prototype\n */\nvar MESSENGER_PROPERTY = '_messenger';\nMessenger.useWith(ComponentFacet, MESSENGER_PROPERTY, Messenger.defaultMethods);\n\n\n// initComponentFacet\nfunction ComponentFacet$init() {\n this._createMessenger();\n}\n\n\n// some subclasses (e.g. ModelFacet) overrride this method and do not create their own messenger\nfunction _createMessenger(){\n _.defineProperty(this, MESSENGER_PROPERTY, new Messenger(this));\n}\n\n\n// startComponentFacet\nfunction ComponentFacet$start() {\n if (this.config.messages)\n this.onConfigMessages(this.config.messages);\n}\n\n\nfunction ComponentFacet$onConfigMessages(messageSubscribers) {\n var notYetRegisteredMap = _.mapKeys(messageSubscribers, function(subscriber, messages) {\n var subscriberType = typeof subscriber;\n if (subscriberType == 'function')\n return this.on(messages, subscriber);\n\n if (subscriberType == 'object') {\n var contextType = typeof subscriber.context;\n if (contextType == 'object')\n return this.on(messages, subscriber);\n\n if (contextType == 'string') {\n if (subscriber.context == this.name || subscriber.context == 'facet')\n subscriber = {\n subscriber: subscriber.subscriber,\n context: this\n };\n else if (subscriber.context == 'owner')\n subscriber = {\n subscriber: subscriber.subscriber,\n context: this.owner\n };\n else\n throw new FacetError('unknown subscriber context in configuration: ' + subscriber.context);\n\n return this.on(messages, subscriber);\n }\n\n throw new FacetError('unknown subscriber context type in configuration: ' + contextType);\n }\n\n throw new FacetError('unknown subscriber type in configuration: ' + subscriberType);\n }, this);\n\n return notYetRegisteredMap;\n}\n\n\n// checkDependencies\nfunction ComponentFacet$check() {\n if (this.require) {\n this.require.forEach(function(reqFacet) {\n if (! this.owner.hasFacet(reqFacet))\n this.owner.addFacet(reqFacet);\n }, this);\n }\n}\n\n\n// destroys facet\nfunction ComponentFacet$destroy() {\n if (this[MESSENGER_PROPERTY]) this[MESSENGER_PROPERTY].destroy();\n this._destroyed = true;\n}\n\n\n/**\n * domParent\n *\n * @return {ComponentFacet} reference to the facet of the same class of the closest parent DOM element, that has a component with the same facet class attached to it. If such element doesn't exist method will return undefined.\n */\nfunction domParent() {\n var parentComponent = componentUtils.getContainingComponent(this.owner.el, false, this.name);\n return parentComponent && parentComponent[this.name];\n}\n\n\n/**\n * scopeParent\n *\n * @return {ComponentFacet} reference to the facet of the same class as `this` facet of the closest scope parent (i.e., the component that has the scope of the current component in its container facet).\n */\nfunction scopeParent() {\n var parentComponent = this.owner.getScopeParent(this.name);\n return parentComponent && parentComponent[this.name];\n}\n\n\nfunction _postParent(getParentMethod, messageType, messageData) {\n var parentFacet = getParentMethod.call(this);\n if (parentFacet)\n parentFacet.postMessage(messageType, messageData);\n}\n\n\nfunction _setMessageSource(messageSource) {\n this[MESSENGER_PROPERTY]._setMessageSource(messageSource);\n}\n\n\nfunction getMessageSource() {\n return this[MESSENGER_PROPERTY].getMessageSource();\n}\n\n\nfunction dispatchSourceMessage(message, data) {\n return this.getMessageSource().dispatchMessage(message, data);\n}\n\n\nfunction _createMessageSource(MessageSourceClass, options) {\n var messageSource = new MessageSourceClass(this, undefined, undefined, this.owner, options);\n this._setMessageSource(messageSource)\n\n _.defineProperty(this, '_messageSource', messageSource);\n}\n\n\nfunction _createMessageSourceWithAPI(MessageSourceClass, messengerAPIOrClass, options) {\n var messageSource = new MessageSourceClass(this, undefined, messengerAPIOrClass, this.owner, options);\n this._setMessageSource(messageSource)\n\n _.defineProperty(this, '_messageSource', messageSource);\n}\n\n\nfunction requiresFacet(facetName) {\n // 'this' refers to the Facet Class\n var facetRequire = this.prototype.require;\n\n return facetRequire && (facetRequire.indexOf(_.firstUpperCase(facetName)) >= 0\n || facetRequire.indexOf(_.firstLowerCase(facetName)) >= 0);\n}\n", "'use strict';\n\n\nvar ComponentFacet = require('../c_facet')\n , miloBinder = require('../../binder')\n , Scope = require('../scope')\n , _ = require('mol-proto')\n , facetsRegistry = require('./cf_registry')\n , domUtils = require('../../util/dom')\n , logger = require('../../util/logger');\n\n\n/**\n * `milo.registry.facets.get('Container')`\n * A special component facet that makes component create its own inner scope.\n * When [milo.binder](../../binder.js.html) binds DOM tree and creates components, if components are inside component WITH Container facet, they are put on the `scope` of it (component.container.scope - see [Scope](../scope.js.html)), otherwise they are put on the same scope even though they may be deeper in DOM tree.\n * It allows creating namespaces avoiding components names conflicts, at the same time creating more shallow components tree than the DOM tree.\n * To create components for elements inside the current component use:\n * ```\n * component.container.binder();\n * ```\n * See [milo.binder](../../binder.js.html)\n */\nvar Container = _.createSubclass(ComponentFacet, 'Container');\n\n\n/**\n * ####Container facet instance methods####\n *\n * - [binder](#Container$binder) - create components from DOM inside the current one\n */\n_.extendProto(Container, {\n start: Container$start,\n path: Container$path,\n getState: Container$getState,\n setState: Container$setState,\n binder: Container$binder,\n destroy: Container$destroy,\n unwrap: Container$unwrap,\n\n append: Container$append,\n insertBefore: Container$insertBefore,\n remove: Container$remove\n});\n\nfacetsRegistry.add(Container);\n\nmodule.exports = Container;\n\n\n/**\n * Container instance method.\n * Scans DOM, creates components and adds to scope children of component element.\n */\nfunction Container$binder() {\n return miloBinder(this.owner.el, this.scope, false);\n}\n\n\n/**\n * Container instance method.\n * Setup empty scope object on start\n */\nfunction Container$start() {\n ComponentFacet.prototype.start.apply(this, arguments);\n this.scope = new Scope(this.owner.el, this);\n}\n\n\nvar allowedNamePattern = /^[A-Za-z][A-Za-z0-9\\_\\$]*$/;\n/**\n * Container instance method.\n * Safely traverses component scope\n * Returns component in scope for a given path\n * If path is invalid the method will throw, if there is no component at a given path or some of the components along the path does not have Container facet the method will return undefined, \n * \n * @param {String} path path of child component in scope, each name should be prefixed with '.', e.g.: '.child.subchild'\n * @return {Component}\n */\nfunction Container$path(path) {\n path = path.split('.');\n var len = path.length;\n if (path[0] || len < 2) throwInvalidPath();\n var comp = this.owner;\n for (var i = 1; i < len; i++) {\n var name = path[i];\n if (!allowedNamePattern.test(name)) throwInvalidPath();\n if (!comp.container) return;\n comp = comp.container.scope[name];\n if (!comp) return;\n }\n return comp;\n\n function throwInvalidPath() {\n throw new Error('path ' + path + ' is invalid');\n }\n}\n\n\n/**\n * Container instance method\n * Called by `Component.prototype.getState` to get facet's state\n * Returns the state of components in the scope\n *\n * @param {Boolean} deepCopy true by default\n * @return {Object}\n */\nfunction Container$getState(deepCopy) {\n var state = { scope: {} };\n if (deepCopy !== false)\n this.scope._each(function(component, compName) {\n state.scope[compName] = component._getState();\n });\n return state;\n}\n\n\n/**\n * Container instance method\n * Called by `Component.prototype.setState` to set facet's state\n * Sets the state of components in the scope\n *\n * @param {Object} data data to set on facet's model\n */\nfunction Container$setState(state) {\n _.eachKey(state.scope, function(compData, compName) {\n var component = this.scope[compName];\n if (component)\n component.setState(compData);\n else\n logger.warn('component \"' + compName + '\" does not exist on scope');\n }, this);\n}\n\nfunction Container$destroy() {\n this.scope._each(function(component) {\n component.destroy();\n });\n this.scope._detachElement();\n ComponentFacet.prototype.destroy.apply(this, arguments);\n}\n\n\n/**\n * Container instance method\n * Moves all of the contents of the owner into the parent scope\n * \n * @param {Boolean} renameChildren pass false to not rename scope children (default is true)\n * @param {Boolean} destroy If not false, the component will be destroyed at the end (default is true).\n */\nfunction Container$unwrap(renameChildren, destroy) {\n domUtils.unwrapElement(this.owner.el);\n this.scope && this.scope._each(function (child) {\n child.remove();\n if (renameChildren !== false) child.rename(undefined, false);\n this.owner.scope && this.owner.scope._add(child);\n }, this);\n if (destroy !== false) this.owner.destroy();\n}\n\n\n/**\n * Container instance method\n * Append component to DOM and to scope\n * @param {Component} comp component that will be appended\n */\nfunction Container$append(comp) {\n this.scope._add(comp);\n this.owner.el.appendChild(comp.el);\n}\n\n\n/**\n * Container instance method\n * Insert component to DOM and to scope before another component\n * @param {Component} comp component that will be inserted\n * @param {Component} sibling component before which component will be appended\n */\nfunction Container$insertBefore(comp, sibling) {\n this.scope._add(comp);\n this.el.insertBefore(comp.el, sibling && sibling.el);\n}\n\nfunction Container$remove(comp) {\n this.scope._remove(comp);\n this.owner.el.removeChild(comp.el);\n}\n", - "'use strict';\n\nvar Mixin = require('../../abstract/mixin')\n , ComponentFacet = require('../c_facet')\n , facetsRegistry = require('./cf_registry')\n\n , Messenger = require('../../messenger')\n , DOMEventsSource = require('../msg_src/dom_events')\n , DataMsgAPI = require('../msg_api/data')\n , getElementDataAccess = require('../msg_api/de_data')\n , pathUtils = require('../../model/path_utils')\n , ModelPath = require('../../model/m_path')\n , modelUtils = require('../../model/model_utils')\n , changeDataHandler = require('../../model/change_data')\n , getTransactionFlag = changeDataHandler.getTransactionFlag\n , setTransactionFlag = changeDataHandler.setTransactionFlag\n , postTransactionFinished = changeDataHandler.postTransactionFinished\n\n , _ = require('mol-proto')\n , logger = require('../../util/logger');\n\n\n/**\n * `milo.registry.facets.get('Data')`\n * Facet to give access to DOM data\n */\nvar Data = _.createSubclass(ComponentFacet, 'Data');\n\n\n/**\n * Data facet instance methods\n *\n * - [start](#Data$start) - start Data facet\n * - [get](#Data$get) - get DOM data from DOM tree\n * - [set](#Data$set) - set DOM data to DOM tree\n * - [path](#Data$path) - get reference to Data facet by path\n */\n_.extendProto(Data, {\n start: Data$start,\n getState: Data$getState,\n setState: Data$setState,\n\n get: Data$get,\n set: Data$set,\n del: Data$del,\n splice: Data$splice,\n len: Data$len,\n path: Data$path,\n getPath: Data$getPath,\n getKey: Data$getKey,\n\n _get: Data$_get,\n _set: Data$_set,\n _del: Data$_del,\n _splice: Data$_splice,\n _len: Data$_len,\n\n _setScalarValue: Data$_setScalarValue,\n _getScalarValue: Data$_getScalarValue,\n _bubbleUpDataChange: Data$_bubbleUpDataChange,\n _queueDataChange: Data$_queueDataChange,\n _postDataChanges: Data$_postDataChanges,\n _prepareMessageSource: _prepareMessageSource\n});\n\nfacetsRegistry.add(Data);\n\nmodule.exports = Data;\n\n\n/**\n * ModelPath methods added to Data prototype\n */\n['push', 'pop', 'unshift', 'shift'].forEach(function(methodName) {\n var method = ModelPath.prototype[methodName];\n _.defineProperty(Data.prototype, methodName, method);\n});\n\n\n\n// these methods will be wrapped to support \"*\" pattern subscriptions\nvar proxyDataSourceMethods = {\n // value: 'value',\n trigger: 'trigger'\n };\n\n\n/**\n * Data facet instance method\n * Starts Data facet\n * Called by component after component is initialized.\n */\nfunction Data$start() {\n // change messenger methods to work with \"*\" subscriptions (like Model class)\n pathUtils.wrapMessengerMethods.call(this);\n\n ComponentFacet.prototype.start.apply(this, arguments);\n\n // get/set methods to set data of element\n this.elData = getElementDataAccess(this.owner.el);\n\n this._dataChangesQueue = [];\n\n this._prepareMessageSource();\n\n // store facet data path\n this._path = '.' + this.owner.name;\n\n // current value\n this._value = this.get();\n\n // prepare internal and external messengers\n // this._prepareMessengers();\n\n // subscribe to DOM event and accessors' messages\n this.onSync('', onOwnDataChange);\n\n // message to mark the end of batch on the current level\n this.onSync('datachangesfinished', onDataChangesFinished);\n\n // changes in scope children with Data facet\n this.onSync('childdata', onChildData);\n\n // to enable reactive connections\n this.onSync('changedata', changeDataHandler);\n}\n\n\n/**\n * Data facet instance method\n * Create and connect internal and external messengers of Data facet.\n * External messenger's methods are proxied on the Data facet and they allows \"*\" subscriptions.\n */\nfunction _prepareMessengers() {\n // Data facet will post all its changes on internal messenger\n var internalMessenger = new Messenger(this);\n\n // message source to connect internal messenger to external\n var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger);\n\n // external messenger to which all model users will subscribe,\n // that will allow \"*\" subscriptions and support \"changedata\" message api.\n var externalMessenger = new Messenger(this, Messenger.defaultMethods, internalMessengerSource);\n\n _.defineProperties(this, {\n _messenger: externalMessenger,\n _internalMessenger: internalMessenger\n });\n}\n\n\n/**\n * Data facet instance method\n * Initializes DOMEventsSource and connects it to Data facet messenger\n *\n * @private\n */\nfunction _prepareMessageSource() {\n var dataAPI = new DataMsgAPI(this.owner)\n , dataEventsSource = new DOMEventsSource(this, proxyDataSourceMethods, dataAPI, this.owner);\n this._setMessageSource(dataEventsSource);\n\n _.defineProperty(this, '_dataEventsSource', dataEventsSource);\n\n // make value method of DataMsgAPI available on Data facet\n // this is a private method, get() should be used to get data.\n Mixin.prototype._createProxyMethod.call(dataAPI, 'value', 'value', this);\n}\n\n\n/**\n * Subscriber to data change event\n *\n * @private\n * @param {String} msgType in this instance will be ''\n * @param {Object} data data change information\n */\nfunction onOwnDataChange(msgType, data) {\n this._bubbleUpDataChange(data);\n this._queueDataChange(data);\n if (data.path === '') {\n var inTransaction = getTransactionFlag(data);\n this.postMessage('datachangesfinished', { transaction: inTransaction });\n }\n}\n\n\n/**\n * Data facet instance method\n * Sends data `message` to DOM parent\n *\n * @private\n * @param {Object} msgData data change message\n */\nfunction Data$_bubbleUpDataChange(msgData) {\n var parentData = this.scopeParent();\n\n if (parentData) {\n var parentMsg = _.clone(msgData);\n parentMsg.path = (this._path || ('.' + thisComp.name)) + parentMsg.path;\n parentData.postMessage('childdata', parentMsg || msgData);\n }\n}\n\n\n/**\n * Data facet instance method\n * Queues data messages to be dispatched to connector\n *\n * @private\n * @param {Object} change data change description\n */\nfunction Data$_queueDataChange(change) {\n this._dataChangesQueue.push(change);\n}\n\n\n/**\n * Subscriber to datachangesfinished event.\n * Calls the method to post changes batch and bubbles up the message\n *\n * @param {[type]} msg [description]\n * @param {[type]} data [description]\n */\nfunction onDataChangesFinished(msg, data) {\n this._postDataChanges(data.inTransaction);\n var parentData = this.scopeParent();\n if (parentData) parentData.postMessage('datachangesfinished', data);\n}\n\n\n/**\n * Dispatches all changes collected in the batch\n * Used for data propagation - connector subscribes to this message\n *\n * @private\n */\nfunction Data$_postDataChanges(inTransaction) {\n var queue = this._dataChangesQueue.reverse();\n this.postMessageSync('datachanges', {\n changes: queue,\n transaction: inTransaction\n });\n this._dataChangesQueue = []; // it can't be .length = 0, as the actual array may still be used\n}\n\n\n/**\n * Subscriber to data change event in child Data facet\n *\n * @private\n * @param {String} msgType\n * @param {Obejct} data data change information\n */\nfunction onChildData(msgType, data) {\n this.postMessage(data.path, data);\n this._bubbleUpDataChange(data);\n this._queueDataChange(data);\n}\n\n\n/**\n * Data facet instance method\n * Sets data in DOM hierarchy recursively.\n * Returns the object with the data actually set (can be different, if components matching some properties are missing).\n *\n * @param {Object|String|Number} value value to be set. If the value if scalar, it will be set on component's element, if the value is object - on DOM tree inside component\n * @return {Object|String|Number}\n */\nfunction Data$set(value) {\n var inTransaction = getTransactionFlag(Data$set);\n\n var componentSetter = this.config.set;\n if (typeof componentSetter == 'function') {\n var result = componentSetter.call(this.owner, value);\n return result;\n }\n\n setTransactionFlag(this._set, inTransaction);\n\n var oldValue = this._value\n , newValue = this._set(value);\n\n // this message triggers onOwnDataChange, as well as actuall DOM change\n // so the parent gets notified\n var msg = { path: '', type: 'changed',\n newValue: newValue, oldValue: oldValue };\n setTransactionFlag(msg, inTransaction);\n this.postMessage('', msg);\n\n return newValue;\n}\n\n\nfunction Data$_set(value) {\n var inTransaction = getTransactionFlag(Data$_set);\n\n var valueSet;\n if (value != null && typeof value == 'object') {\n if (Array.isArray(value)) {\n valueSet = [];\n\n var listFacet = this.owner.list;\n if (listFacet){\n var listLength = listFacet.count()\n , newItemsCount = value.length - listLength;\n if (newItemsCount >= 3) {\n listFacet._addItems(newItemsCount);\n listFacet._updateDataPaths(listLength, listFacet.count());\n }\n\n value.forEach(function(childValue, index) {\n setChildData.call(this, valueSet, childValue, index, '[$$]');\n }, this);\n\n var listCount = listFacet.count()\n , removeCount = listCount - value.length;\n\n while (removeCount-- > 0)\n listFacet._removeItem(value.length);\n } else\n logger.warn('Data: setting array data without List facet');\n } else {\n valueSet = {};\n _.eachKey(value, function(childValue, key) {\n setChildData.call(this, valueSet, childValue, key, '.$$');\n }, this);\n }\n } else\n valueSet = this._setScalarValue(value);\n\n this._value = valueSet;\n\n return valueSet;\n\n\n function setChildData(valueSet, childValue, key, pathSyntax) {\n var childPath = pathSyntax.replace('$$', key);\n var childDataFacet = this.path(childPath, typeof childValue != 'undefined');\n if (childDataFacet) {\n setTransactionFlag(childDataFacet.set, inTransaction);\n valueSet[key] = childDataFacet.set(childValue);\n }\n }\n}\n\n\n/**\n * Data facet instance method\n * Deletes component from view and scope, only in case it has Item facet on it\n *\n * @param {String|Number} value value to set to DOM element\n */\nfunction Data$del() {\n var inTransaction = getTransactionFlag(Data$del);\n\n var componentDelete = this.config.del;\n if (typeof componentDelete == 'function') {\n var result = componentDelete.call(this.owner);\n postTransactionFinished.call(this, inTransaction);\n return result;\n }\n\n var oldValue = this._value\n\n setTransactionFlag(this._del, inTransaction);\n this._del();\n\n // this message triggers onOwnDataChange, as well as actuall DOM change\n // so the parent gets notified\n var msg = { path: '', type: 'deleted', oldValue: oldValue };\n setTransactionFlag(msg, inTransaction);\n this.postMessage('', msg);\n}\n\n\nfunction Data$_del() {\n var inTransaction = getTransactionFlag(Data$_del);\n setTransactionFlag(this._set, inTransaction);\n this._set();\n}\n\n\n/**\n * Data facet instance method\n * Sets scalar value to DOM element\n *\n * @private\n * @param {String|Number} value value to set to DOM element\n */\nfunction Data$_setScalarValue(value) {\n return this.elData.set(this.owner.el, value);\n}\n\n\n/**\n * Data facet instance method\n * Get structured data from DOM hierarchy recursively\n * Returns DOM data\n *\n * @param {Boolean} deepGet true by default\n * @return {Object}\n */\nfunction Data$get(deepGet) {\n var componentGetter = this.config.get;\n if (typeof componentGetter == 'function')\n return componentGetter.call(this.owner, deepGet);\n\n return this._get(deepGet);\n}\n\nfunction Data$_get(deepGet) {\n if (deepGet === false) // a hack to enable getting shallow state\n return;\n\n var comp = this.owner\n , scopeData;\n\n if (comp.list) {\n scopeData = [];\n comp.list.each(function(listItem, index) {\n scopeData[index] = listItem.data.get();\n });\n\n if (comp.container)\n comp.container.scope._each(function(scopeItem, name) {\n if (! comp.list.contains(scopeItem) && scopeItem.data)\n scopeData[name] = scopeItem.data.get();\n });\n } else if (comp.container) {\n scopeData = {};\n comp.container.scope._each(function(scopeItem, name) {\n if (scopeItem.data)\n scopeData[name] = scopeItem.data.get();\n });\n } else\n scopeData = this._getScalarValue();\n\n this._value = scopeData;\n\n return scopeData;\n}\n\n\n/**\n * Data facet instance method\n * Gets scalar data from DOM element\n *\n * @private\n */\nfunction Data$_getScalarValue() {\n return this.elData.get(this.owner.el);\n}\n\n\n/**\n * Data facet instance method\n * Splices List items. Requires List facet to be present on component. Works in the same way as array splice.\n * Returns data retrieved from removed items\n *\n * @param {Integer} spliceIndex index to delete/insert at\n * @param {Integer} spliceHowMany number of items to delete\n * @param {List} arguments optional items to insert\n * @return {Array}\n */\nfunction Data$splice(spliceIndex, spliceHowMany) { //, ... arguments\n var inTransaction = getTransactionFlag(Data$splice);\n\n var componentSplice = this.config.splice;\n if (typeof componentSplice == 'function') {\n var result = componentSplice.apply(this.owner, arguments);\n postTransactionFinished.call(this, inTransaction);\n return result;\n }\n\n setTransactionFlag(this._splice, inTransaction);\n var result = this._splice.apply(this, arguments);\n\n if (!result) return;\n\n var msg = { path: '', type: 'splice',\n index: result.spliceIndex,\n removed: result.removed,\n addedCount: result.addedCount,\n newValue: this._value };\n setTransactionFlag(msg, inTransaction);\n this.postMessage('', msg);\n\n return result.removed;\n}\n\n\nfunction Data$_splice(spliceIndex, spliceHowMany) { //, ... arguments\n var inTransaction = getTransactionFlag(Data$_splice);\n\n var listFacet = this.owner.list;\n if (! listFacet)\n return logger.warn('Data: cannot use splice method without List facet');\n\n var removed = [];\n\n var listLength = listFacet.count();\n arguments[0] = spliceIndex =\n modelUtils.normalizeSpliceIndex(spliceIndex, listLength);\n\n if (spliceHowMany > 0 && listLength > 0) {\n for (var i = spliceIndex; i < spliceIndex + spliceHowMany; i++) {\n var item = listFacet.item(spliceIndex);\n if (item) {\n var itemData = item.data.get();\n listFacet._removeItem(spliceIndex);\n } else\n logger.warn('Data: no item for index', i);\n\n removed.push(itemData);\n }\n\n listFacet._updateDataPaths(spliceIndex, listFacet.count());\n }\n\n var added = [];\n\n var argsLen = arguments.length\n , addItems = argsLen > 2\n , addedCount = argsLen - 2;\n if (addItems) {\n listFacet._addItems(addedCount, spliceIndex);\n for (var i = 2, j = spliceIndex; i < argsLen; i++, j++) {\n var item = listFacet.item(j);\n if (item) {\n setTransactionFlag(item.data.set, inTransaction);\n var itemData = item.data.set(arguments[i]);\n } else\n logger.warn('Data: no item for index', j);\n\n added.push(itemData);\n }\n\n // change paths of items that were added and items after them\n listFacet._updateDataPaths(spliceIndex, listFacet.count());\n }\n\n // if (Array.isArray(this._value)) {\n // _.prependArray(added, [spliceIndex, spliceHowMany]);\n // Array.prototype.splice.apply(this._value, added);\n // } else\n this._value = this.get();\n\n return {\n spliceIndex: spliceIndex,\n removed: removed,\n addedCount: addItems ? addedCount : 0\n };\n}\n\n\nfunction Data$len() {\n var componentLen = this.config.len;\n if (typeof componentLen == 'function')\n return componentLen.call(this.owner);\n else\n return this._len();\n}\n\n\nfunction Data$_len() {\n if (this.owner.list) return this.owner.list.count();\n else logger.error('Data: len called without list facet');\n}\n\n\n/**\n * Data facet instance method\n * Returns data facet of a child component (by scopes) corresponding to the path\n * @param {String} accessPath data access path\n */\nfunction Data$path(accessPath, createItem) {\n // createItem = true; // this hack seems to be no longer needed...\n\n if (! accessPath)\n return this;\n\n var parsedPath = pathUtils.parseAccessPath(accessPath);\n var currentComponent = this.owner;\n\n for (var i = 0, len = parsedPath.length; i < len; i++) {\n var pathNode = parsedPath[i]\n , nodeKey = pathUtils.getPathNodeKey(pathNode);\n if (pathNode.syntax == 'array' && currentComponent.list) {\n var itemComponent = currentComponent.list.item(nodeKey);\n if (! itemComponent && createItem !== false) {\n itemComponent = currentComponent.list._addItem(nodeKey);\n itemComponent.data._path = pathNode.property;\n }\n currentComponent = itemComponent;\n } else if (currentComponent.container)\n currentComponent = currentComponent.container.scope[nodeKey];\n\n var currentDataFacet = currentComponent && currentComponent.data;\n if (! currentDataFacet)\n break;\n }\n\n return currentDataFacet;\n}\n\n\n/**\n * Data facet instance method\n * Returns path to access this data facet from parent (using path method)\n *\n * @return {String}\n */\nfunction Data$getPath() {\n return this._path;\n}\n\n\n/**\n * Data facet instance method\n * Returns key to access the value related to this data facet on the value related to parent data facet.\n * If component has List facet, returns index\n *\n * @return {String|Integer}\n */\nfunction Data$getKey() {\n var path = this._path;\n return path[0] == '['\n ? +path.slice(1, -1) // remove \"[\" and \"]\"\n : path.slice(1) // remove leading \".\"\n}\n\n\n/**\n * Data facet instance method\n * Called by `Component.prototype.getState` to get facet's state\n * Returns DOM data\n *\n * @param {Boolean} deepState, true by default\n * @return {Object}\n */\nfunction Data$getState(deepState) {\n return { state: this.get(deepState) };\n}\n\n\n/**\n * Data facet instance method\n * Called by `Component.prototype.setState` to set facet's state\n * Simply sets model data\n *\n * @param {Object} state data to set on facet's model\n */\nfunction Data$setState(state) {\n return this.set(state.state);\n}\n", + "'use strict';\n\nvar Mixin = require('../../abstract/mixin')\n , ComponentFacet = require('../c_facet')\n , facetsRegistry = require('./cf_registry')\n\n , Messenger = require('../../messenger')\n , DOMEventsSource = require('../msg_src/dom_events')\n , DataMsgAPI = require('../msg_api/data')\n , getElementDataAccess = require('../msg_api/de_data')\n , pathUtils = require('../../model/path_utils')\n , ModelPath = require('../../model/m_path')\n , modelUtils = require('../../model/model_utils')\n , changeDataHandler = require('../../model/change_data')\n , getTransactionFlag = changeDataHandler.getTransactionFlag\n , setTransactionFlag = changeDataHandler.setTransactionFlag\n , postTransactionFinished = changeDataHandler.postTransactionFinished\n\n , _ = require('mol-proto')\n , logger = require('../../util/logger');\n\n\n/**\n * `milo.registry.facets.get('Data')`\n * Facet to give access to DOM data\n */\nvar Data = _.createSubclass(ComponentFacet, 'Data');\n\n\n/**\n * Data facet instance methods\n *\n * - [start](#Data$start) - start Data facet\n * - [get](#Data$get) - get DOM data from DOM tree\n * - [set](#Data$set) - set DOM data to DOM tree\n * - [path](#Data$path) - get reference to Data facet by path\n */\n_.extendProto(Data, {\n start: Data$start,\n getState: Data$getState,\n setState: Data$setState,\n\n get: Data$get,\n set: Data$set,\n del: Data$del,\n splice: Data$splice,\n len: Data$len,\n path: Data$path,\n getPath: Data$getPath,\n getKey: Data$getKey,\n\n _get: Data$_get,\n _set: Data$_set,\n _del: Data$_del,\n _splice: Data$_splice,\n _len: Data$_len,\n\n _setScalarValue: Data$_setScalarValue,\n _getScalarValue: Data$_getScalarValue,\n _bubbleUpDataChange: Data$_bubbleUpDataChange,\n _queueDataChange: Data$_queueDataChange,\n _postDataChanges: Data$_postDataChanges,\n _prepareMessageSource: _prepareMessageSource\n});\n\nfacetsRegistry.add(Data);\n\nmodule.exports = Data;\n\n\n/**\n * ModelPath methods added to Data prototype\n */\n['push', 'pop', 'unshift', 'shift'].forEach(function(methodName) {\n var method = ModelPath.prototype[methodName];\n _.defineProperty(Data.prototype, methodName, method);\n});\n\n\n\n// these methods will be wrapped to support \"*\" pattern subscriptions\nvar proxyDataSourceMethods = {\n // value: 'value',\n trigger: 'trigger'\n };\n\n\n/**\n * Data facet instance method\n * Starts Data facet\n * Called by component after component is initialized.\n */\nfunction Data$start() {\n // change messenger methods to work with \"*\" subscriptions (like Model class)\n pathUtils.wrapMessengerMethods.call(this);\n\n ComponentFacet.prototype.start.apply(this, arguments);\n\n // get/set methods to set data of element\n this.elData = getElementDataAccess(this.owner.el);\n\n this._dataChangesQueue = [];\n\n this._prepareMessageSource();\n\n // store facet data path\n this._path = '.' + this.owner.name;\n\n // current value\n this._value = this.get();\n\n // prepare internal and external messengers\n // this._prepareMessengers();\n\n // subscribe to DOM event and accessors' messages\n this.onSync('', onOwnDataChange);\n\n // message to mark the end of batch on the current level\n this.onSync('datachangesfinished', onDataChangesFinished);\n\n // changes in scope children with Data facet\n this.onSync('childdata', onChildData);\n\n // to enable reactive connections\n this.onSync('changedata', changeDataHandler);\n}\n\n\n/**\n * Data facet instance method\n * Create and connect internal and external messengers of Data facet.\n * External messenger's methods are proxied on the Data facet and they allows \"*\" subscriptions.\n */\n// function _prepareMessengers() {\n // Data facet will post all its changes on internal messenger\n // var internalMessenger = new Messenger(this);\n\n // message source to connect internal messenger to external\n // var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger);\n\n // external messenger to which all model users will subscribe,\n // that will allow \"*\" subscriptions and support \"changedata\" message api.\n // var externalMessenger = new Messenger(this, Messenger.defaultMethods, internalMessengerSource);\n\n// _.defineProperties(this, {\n// _messenger: externalMessenger,\n// _internalMessenger: internalMessenger\n// });\n// }\n\n\n/**\n * Data facet instance method\n * Initializes DOMEventsSource and connects it to Data facet messenger\n *\n * @private\n */\nfunction _prepareMessageSource() {\n var dataAPI = new DataMsgAPI(this.owner)\n , dataEventsSource = new DOMEventsSource(this, proxyDataSourceMethods, dataAPI, this.owner);\n this._setMessageSource(dataEventsSource);\n\n _.defineProperty(this, '_dataEventsSource', dataEventsSource);\n\n // make value method of DataMsgAPI available on Data facet\n // this is a private method, get() should be used to get data.\n Mixin.prototype._createProxyMethod.call(dataAPI, 'value', 'value', this);\n}\n\n\n/**\n * Subscriber to data change event\n *\n * @private\n * @param {String} msgType in this instance will be ''\n * @param {Object} data data change information\n */\nfunction onOwnDataChange(msgType, data) {\n this._bubbleUpDataChange(data);\n this._queueDataChange(data);\n if (data.path === '') {\n var inTransaction = getTransactionFlag(data);\n this.postMessage('datachangesfinished', { transaction: inTransaction });\n }\n}\n\n\n/**\n * Data facet instance method\n * Sends data `message` to DOM parent\n *\n * @private\n * @param {Object} msgData data change message\n */\nfunction Data$_bubbleUpDataChange(msgData) {\n var parentData = this.scopeParent();\n\n if (parentData) {\n var parentMsg = _.clone(msgData);\n parentMsg.path = (this._path || ('.' + this.owner.name)) + parentMsg.path;\n parentData.postMessage('childdata', parentMsg || msgData);\n }\n}\n\n\n/**\n * Data facet instance method\n * Queues data messages to be dispatched to connector\n *\n * @private\n * @param {Object} change data change description\n */\nfunction Data$_queueDataChange(change) {\n this._dataChangesQueue.push(change);\n}\n\n\n/**\n * Subscriber to datachangesfinished event.\n * Calls the method to post changes batch and bubbles up the message\n *\n * @param {[type]} msg [description]\n * @param {[type]} data [description]\n */\nfunction onDataChangesFinished(msg, data) {\n this._postDataChanges(data.inTransaction);\n var parentData = this.scopeParent();\n if (parentData) parentData.postMessage('datachangesfinished', data);\n}\n\n\n/**\n * Dispatches all changes collected in the batch\n * Used for data propagation - connector subscribes to this message\n *\n * @private\n */\nfunction Data$_postDataChanges(inTransaction) {\n var queue = this._dataChangesQueue.reverse();\n this.postMessageSync('datachanges', {\n changes: queue,\n transaction: inTransaction\n });\n this._dataChangesQueue = []; // it can't be .length = 0, as the actual array may still be used\n}\n\n\n/**\n * Subscriber to data change event in child Data facet\n *\n * @private\n * @param {String} msgType\n * @param {Obejct} data data change information\n */\nfunction onChildData(msgType, data) {\n this.postMessage(data.path, data);\n this._bubbleUpDataChange(data);\n this._queueDataChange(data);\n}\n\n\n/**\n * Data facet instance method\n * Sets data in DOM hierarchy recursively.\n * Returns the object with the data actually set (can be different, if components matching some properties are missing).\n *\n * @param {Object|String|Number} value value to be set. If the value if scalar, it will be set on component's element, if the value is object - on DOM tree inside component\n * @return {Object|String|Number}\n */\nfunction Data$set(value) {\n var inTransaction = getTransactionFlag(Data$set);\n\n var componentSetter = this.config.set;\n if (typeof componentSetter == 'function') {\n var result = componentSetter.call(this.owner, value);\n return result;\n }\n\n setTransactionFlag(this._set, inTransaction);\n\n var oldValue = this._value\n , newValue = this._set(value);\n\n // this message triggers onOwnDataChange, as well as actuall DOM change\n // so the parent gets notified\n var msg = { path: '', type: 'changed',\n newValue: newValue, oldValue: oldValue };\n setTransactionFlag(msg, inTransaction);\n this.postMessage('', msg);\n\n return newValue;\n}\n\n\nfunction Data$_set(value) {\n var inTransaction = getTransactionFlag(Data$_set);\n\n var valueSet;\n if (value != null && typeof value == 'object') {\n if (Array.isArray(value)) {\n valueSet = [];\n\n var listFacet = this.owner.list;\n if (listFacet){\n var listLength = listFacet.count()\n , newItemsCount = value.length - listLength;\n if (newItemsCount >= 3) {\n listFacet._addItems(newItemsCount);\n listFacet._updateDataPaths(listLength, listFacet.count());\n }\n\n value.forEach(function(childValue, index) {\n setChildData.call(this, valueSet, childValue, index, '[$$]');\n }, this);\n\n var listCount = listFacet.count()\n , removeCount = listCount - value.length;\n\n while (removeCount-- > 0)\n listFacet._removeItem(value.length);\n } else\n logger.warn('Data: setting array data without List facet');\n } else {\n valueSet = {};\n _.eachKey(value, function(childValue, key) {\n setChildData.call(this, valueSet, childValue, key, '.$$');\n }, this);\n }\n } else\n valueSet = this._setScalarValue(value);\n\n this._value = valueSet;\n\n return valueSet;\n\n\n function setChildData(valueSet, childValue, key, pathSyntax) {\n var childPath = pathSyntax.replace('$$', key);\n var childDataFacet = this.path(childPath, typeof childValue != 'undefined');\n if (childDataFacet) {\n setTransactionFlag(childDataFacet.set, inTransaction);\n valueSet[key] = childDataFacet.set(childValue);\n }\n }\n}\n\n\n/**\n * Data facet instance method\n * Deletes component from view and scope, only in case it has Item facet on it\n *\n * @param {String|Number} value value to set to DOM element\n */\nfunction Data$del() {\n var inTransaction = getTransactionFlag(Data$del);\n\n var componentDelete = this.config.del;\n if (typeof componentDelete == 'function') {\n var result = componentDelete.call(this.owner);\n postTransactionFinished.call(this, inTransaction);\n return result;\n }\n\n var oldValue = this._value;\n\n setTransactionFlag(this._del, inTransaction);\n this._del();\n\n // this message triggers onOwnDataChange, as well as actuall DOM change\n // so the parent gets notified\n var msg = { path: '', type: 'deleted', oldValue: oldValue };\n setTransactionFlag(msg, inTransaction);\n this.postMessage('', msg);\n}\n\n\nfunction Data$_del() {\n var inTransaction = getTransactionFlag(Data$_del);\n setTransactionFlag(this._set, inTransaction);\n this._set();\n}\n\n\n/**\n * Data facet instance method\n * Sets scalar value to DOM element\n *\n * @private\n * @param {String|Number} value value to set to DOM element\n */\nfunction Data$_setScalarValue(value) {\n return this.elData.set(this.owner.el, value);\n}\n\n\n/**\n * Data facet instance method\n * Get structured data from DOM hierarchy recursively\n * Returns DOM data\n *\n * @param {Boolean} deepGet true by default\n * @return {Object}\n */\nfunction Data$get(deepGet) {\n var componentGetter = this.config.get;\n if (typeof componentGetter == 'function')\n return componentGetter.call(this.owner, deepGet);\n\n return this._get(deepGet);\n}\n\nfunction Data$_get(deepGet) {\n if (deepGet === false) // a hack to enable getting shallow state\n return;\n\n var comp = this.owner\n , scopeData;\n\n if (comp.list) {\n scopeData = [];\n comp.list.each(function(listItem, index) {\n scopeData[index] = listItem.data.get();\n });\n\n if (comp.container)\n comp.container.scope._each(function(scopeItem, name) {\n if (! comp.list.contains(scopeItem) && scopeItem.data)\n scopeData[name] = scopeItem.data.get();\n });\n } else if (comp.container) {\n scopeData = {};\n comp.container.scope._each(function(scopeItem, name) {\n if (scopeItem.data)\n scopeData[name] = scopeItem.data.get();\n });\n } else\n scopeData = this._getScalarValue();\n\n this._value = scopeData;\n\n return scopeData;\n}\n\n\n/**\n * Data facet instance method\n * Gets scalar data from DOM element\n *\n * @private\n */\nfunction Data$_getScalarValue() {\n return this.elData.get(this.owner.el);\n}\n\n\n/**\n * Data facet instance method\n * Splices List items. Requires List facet to be present on component. Works in the same way as array splice.\n * Returns data retrieved from removed items\n *\n * @param {Integer} spliceIndex index to delete/insert at\n * @param {Integer} spliceHowMany number of items to delete\n * @param {List} arguments optional items to insert\n * @return {Array}\n */\nfunction Data$splice(spliceIndex, spliceHowMany) { //, ... arguments\n var inTransaction = getTransactionFlag(Data$splice);\n var result;\n\n var componentSplice = this.config.splice;\n if (typeof componentSplice == 'function') {\n result = componentSplice.apply(this.owner, arguments);\n postTransactionFinished.call(this, inTransaction);\n return result;\n }\n\n setTransactionFlag(this._splice, inTransaction);\n result = this._splice.apply(this, arguments);\n\n if (!result) return;\n\n var msg = { path: '', type: 'splice',\n index: result.spliceIndex,\n removed: result.removed,\n addedCount: result.addedCount,\n newValue: this._value };\n setTransactionFlag(msg, inTransaction);\n this.postMessage('', msg);\n\n return result.removed;\n}\n\n\nfunction Data$_splice(spliceIndex, spliceHowMany) { //, ... arguments\n var inTransaction = getTransactionFlag(Data$_splice);\n\n var listFacet = this.owner.list;\n if (! listFacet)\n return logger.warn('Data: cannot use splice method without List facet');\n\n var removed = [];\n\n var listLength = listFacet.count();\n arguments[0] = spliceIndex =\n modelUtils.normalizeSpliceIndex(spliceIndex, listLength);\n\n if (spliceHowMany > 0 && listLength > 0) {\n for (var i = spliceIndex; i < spliceIndex + spliceHowMany; i++) {\n var item = listFacet.item(spliceIndex);\n if (item) {\n var itemData = item.data.get();\n listFacet._removeItem(spliceIndex);\n } else\n logger.warn('Data: no item for index', i);\n\n removed.push(itemData);\n }\n\n listFacet._updateDataPaths(spliceIndex, listFacet.count());\n }\n\n var added = [];\n\n var argsLen = arguments.length\n , addItems = argsLen > 2\n , addedCount = argsLen - 2;\n if (addItems) {\n listFacet._addItems(addedCount, spliceIndex);\n for (var i = 2, j = spliceIndex; i < argsLen; i++, j++) {\n var item = listFacet.item(j);\n if (item) {\n setTransactionFlag(item.data.set, inTransaction);\n var itemData = item.data.set(arguments[i]);\n } else\n logger.warn('Data: no item for index', j);\n\n added.push(itemData);\n }\n\n // change paths of items that were added and items after them\n listFacet._updateDataPaths(spliceIndex, listFacet.count());\n }\n\n // if (Array.isArray(this._value)) {\n // _.prependArray(added, [spliceIndex, spliceHowMany]);\n // Array.prototype.splice.apply(this._value, added);\n // } else\n this._value = this.get();\n\n return {\n spliceIndex: spliceIndex,\n removed: removed,\n addedCount: addItems ? addedCount : 0\n };\n}\n\n\nfunction Data$len() {\n var componentLen = this.config.len;\n if (typeof componentLen == 'function')\n return componentLen.call(this.owner);\n else\n return this._len();\n}\n\n\nfunction Data$_len() {\n if (this.owner.list) return this.owner.list.count();\n else logger.error('Data: len called without list facet');\n}\n\n\n/**\n * Data facet instance method\n * Returns data facet of a child component (by scopes) corresponding to the path\n * @param {String} accessPath data access path\n */\nfunction Data$path(accessPath, createItem) {\n // createItem = true; // this hack seems to be no longer needed...\n\n if (! accessPath)\n return this;\n\n var parsedPath = pathUtils.parseAccessPath(accessPath);\n var currentComponent = this.owner;\n\n for (var i = 0, len = parsedPath.length; i < len; i++) {\n var pathNode = parsedPath[i]\n , nodeKey = pathUtils.getPathNodeKey(pathNode);\n if (pathNode.syntax == 'array' && currentComponent.list) {\n var itemComponent = currentComponent.list.item(nodeKey);\n if (! itemComponent && createItem !== false) {\n itemComponent = currentComponent.list._addItem(nodeKey);\n itemComponent.data._path = pathNode.property;\n }\n currentComponent = itemComponent;\n } else if (currentComponent.container)\n currentComponent = currentComponent.container.scope[nodeKey];\n\n var currentDataFacet = currentComponent && currentComponent.data;\n if (! currentDataFacet)\n break;\n }\n\n return currentDataFacet;\n}\n\n\n/**\n * Data facet instance method\n * Returns path to access this data facet from parent (using path method)\n *\n * @return {String}\n */\nfunction Data$getPath() {\n return this._path;\n}\n\n\n/**\n * Data facet instance method\n * Returns key to access the value related to this data facet on the value related to parent data facet.\n * If component has List facet, returns index\n *\n * @return {String|Integer}\n */\nfunction Data$getKey() {\n var path = this._path;\n return path[0] == '['\n ? +path.slice(1, -1) // remove \"[\" and \"]\"\n : path.slice(1) // remove leading \".\"\n}\n\n\n/**\n * Data facet instance method\n * Called by `Component.prototype.getState` to get facet's state\n * Returns DOM data\n *\n * @param {Boolean} deepState, true by default\n * @return {Object}\n */\nfunction Data$getState(deepState) {\n return { state: this.get(deepState) };\n}\n\n\n/**\n * Data facet instance method\n * Called by `Component.prototype.setState` to set facet's state\n * Simply sets model data\n *\n * @param {Object} state data to set on facet's model\n */\nfunction Data$setState(state) {\n return this.set(state.state);\n}\n", "'use strict';\n\n\nvar ComponentFacet = require('../c_facet')\n , facetsRegistry = require('./cf_registry') \n , _ = require('mol-proto')\n , check = require('../../util/check')\n , Match = check.Match\n , binder = require('../../binder')\n , BindAttribute = require('../../attributes/a_bind')\n , DomFacetError = require('../../util/error').DomFacet\n , domUtils = require('../../util/dom')\n , config = require('../../config')\n , doT = require('dot');\n\n\n/**\n * `milo.registry.facets.get('Dom')`\n * Facet with component related dom utils\n */\nvar Dom = _.createSubclass(ComponentFacet, 'Dom');\n\n_.extend(Dom, {\n createElement: Dom$$createElement\n});\n\n\n/**\n * Facet class method\n * Creates an element from a passed configuation object\n * \n * @param {Object} config with the properties `domConfig`, `content`, `template`\n * @return {Element} an html element \n */\nfunction Dom$$createElement(config) {\n var domConfig = config.domConfig || {}\n , tagName = domConfig.tagName || 'div'\n , newEl = document.createElement(tagName)\n , content = config.content\n , template = config.template;\n\n // TODO it will be called again when/if component is instantiated\n // Should be someproperty on element to indicate it's been called?\n _applyConfigToElement(newEl, domConfig);\n\n if (typeof content == 'string') {\n if (template)\n newEl.innerHTML = doT.template(template)({content: content});\n else\n newEl.innerHTML = content;\n }\n return newEl;\n}\n\n\nfunction _applyConfigToElement(el, config) {\n var cssClasses = config && config.cls\n , configAttributes = config && config.attributes;\n\n if (configAttributes)\n _.eachKey(configAttributes, function(attrValue, attrName) {\n el.setAttribute(attrName, attrValue);\n });\n\n if (cssClasses)\n _attachCssClasses(el, 'add', cssClasses);\n}\n\n\n_.extendProto(Dom, {\n start: start,\n\n show: show,\n hide: hide,\n toggle: toggle,\n detach: detach,\n remove: remove,\n append: append,\n prepend: prepend,\n appendChildren: appendChildren,\n prependChildren: prependChildren,\n insertAfter: insertAfter,\n insertBefore: insertBefore,\n appendToScopeParent: appendToScopeParent,\n children: Dom$children,\n setStyle: setStyle,\n setStyles: setStyles,\n copy: copy,\n createElement: createElement,\n\n addCssClasses: _.partial(_manageCssClasses, 'add'),\n removeCssClasses: _.partial(_manageCssClasses, 'remove'),\n toggleCssClasses: _.partial(_manageCssClasses, 'toggle'),\n\n find: find,\n hasTextBeforeSelection: hasTextBeforeSelection,\n hasTextAfterSelection: hasTextAfterSelection,\n});\n\nfacetsRegistry.add(Dom);\n\nmodule.exports = Dom;\n\n\n// start Dom facet\nfunction start() {\n var el = this.owner.el;\n _applyConfigToElement(el, this.config);\n var currentStyle = window.getComputedStyle(el)\n this._visible = currentStyle && currentStyle.display != 'none';\n}\n\n// show HTML element of component\nfunction show() {\n this.toggle(true);\n}\n\n// hide HTML element of component\nfunction hide() {\n this.toggle(false);\n}\n\n// show/hide\nfunction toggle(doShow) {\n doShow = typeof doShow == 'undefined'\n ? ! this._visible\n : !! doShow;\n\n this._visible = doShow;\n var el = this.owner.el;\n\n el.style.display = doShow ? 'block' : 'none';\n\n return doShow;\n}\n\n\nfunction _manageCssClasses(methodName, cssClasses, enforce) {\n _attachCssClasses(this.owner.el, methodName, cssClasses, enforce);\n}\n\n\nfunction _attachCssClasses(el, methodName, cssClasses, enforce) {\n var classList = el.classList\n , doToggle = methodName == 'toggle';\n\n if (Array.isArray(cssClasses))\n cssClasses.forEach(callMethod);\n else if (typeof cssClasses == 'string')\n callMethod(cssClasses);\n else\n throw new DomFacetError('unknown type of CSS classes parameter');\n\n function callMethod(cssCls) {\n doToggle\n // Only pass 'enforce' if a value has been provided (The 'toggle' function of the classList will treat undefined === false resulting in only allowing classes to be removed)\n ? enforce === undefined ? classList[methodName](cssCls) : classList[methodName](cssCls, enforce)\n : classList[methodName](cssCls);\n }\n}\n\n\nfunction detach() {\n if (this.owner.el) \n domUtils.detachComponent(this.owner.el);\n}\n\n\nfunction setStyle(property, value) {\n if (!this.owner.el) {\n throw new Error(\"Cannot call setStyle on owner with no element: \" + this.owner.constructor.name);\n }\n this.owner.el.style[property] = value;\n}\n\nfunction setStyles(properties) {\n for (var property in properties)\n this.owner.el.style[property] = properties[property];\n}\n\n\n// create a copy of DOM element using facet config if set\nfunction copy(isDeep) {\n return this.owner.el && this.owner.el.cloneNode(isDeep);\n}\n\n\nfunction createElement() {\n var newEl = Dom.createElement(this.config);\n return newEl;\n}\n\n\n// remove HTML element of component\nfunction remove() {\n domUtils.removeElement(this.owner.el);\n}\n\n// append inside HTML element of component\nfunction append(el) {\n this.owner.el.appendChild(el);\n}\n\n// prepend inside HTML element of component\nfunction prepend(el) {\n var thisEl = this.owner.el\n , firstChild = thisEl.firstChild;\n if (firstChild)\n thisEl.insertBefore(el, firstChild);\n else\n thisEl.appendChild(el);\n}\n\n// appends children of element inside this component's element\nfunction appendChildren(el) {\n while(el.childNodes.length)\n this.append(el.childNodes[0]);\n}\n\n// prepends children of element inside this component's element\nfunction prependChildren(el) {\n while(el.childNodes.length)\n this.prepend(el.childNodes[el.childNodes.length - 1]);\n}\n\nfunction insertAfter(el) {\n var thisEl = this.owner.el\n , parent = thisEl.parentNode; \n parent.insertBefore(el, thisEl.nextSibling);\n}\n\nfunction insertBefore(el) {\n var thisEl = this.owner.el\n , parent = thisEl.parentNode;\n parent.insertBefore(el, thisEl);\n}\n\n\n// appends component's element to scope parent. If it was alredy in DOM it will be moved\nfunction appendToScopeParent() {\n var parent = this.owner.getScopeParent();\n if (parent) parent.el.appendChild(this.owner.el);\n}\n\n\n/**\n * Dom facet instance method\n * Returns the list of child elements of the component element\n *\n * @return {Array[Element]}\n */\nfunction Dom$children() {\n return domUtils.children(this.owner.el);\n}\n\n\nvar findDirections = {\n 'up': 'previousNode',\n 'down': 'nextNode'\n};\n\n// Finds component passing optional iterator's test\n// in the same scope as the current component (this)\n// by traversing DOM tree upwards (direction = \"up\")\n// or downwards (direction = \"down\")\nfunction find(direction, iterator) {\n if (! findDirections.hasOwnProperty(direction))\n throw new DomFacetError('incorrect find direction: ' + direction);\n\n var el = this.owner.el\n , scope = this.owner.scope\n , treeWalker = document.createTreeWalker(scope._rootEl, NodeFilter.SHOW_ELEMENT);\n\n treeWalker.currentNode = el;\n var nextNode = treeWalker[findDirections[direction]]()\n , componentsNames = Object.keys(scope)\n , found = false;\n\n while (nextNode) {\n var attr = new BindAttribute(nextNode);\n if (attr.node) {\n attr.parse().validate();\n if (scope.hasOwnProperty(attr.compName)) {\n var component = scope[attr.compName];\n if (! iterator || iterator(component)) {\n found = true;\n break;\n }\n }\n }\n treeWalker.currentNode = nextNode;\n nextNode = treeWalker[findDirections[direction]]();\n }\n\n if (found) return component;\n}\n\n\n// returns true if the element has text before selection\nfunction hasTextBeforeSelection() {\n var selection = window.getSelection();\n if (! selection.isCollapsed) return true;\n \n var text = selection.focusNode && selection.focusNode.textContent;\n var startPos = text && text.charAt(0) == ' ' ? 1 : 0;\n if (selection.anchorOffset != startPos) return true;\n\n // walk up the DOM tree to check if there are text nodes before cursor\n var treeWalker = document.createTreeWalker(this.owner.el, NodeFilter.SHOW_TEXT);\n treeWalker.currentNode = selection.anchorNode;\n var prevNode = treeWalker.previousNode();\n\n var isText = prevNode ? !prevNode.nodeValue.trim() == '' : false;\n\n return isText;\n}\n\n\nfunction hasTextAfterSelection() {\n var selection = window.getSelection();\n if (! selection.isCollapsed) return true;\n\n var text = selection.focusNode && selection.focusNode.textContent;\n var startPos = text && text.charAt(text.length-1) == ' ' ? selection.anchorNode.length-1 : selection.anchorNode.length;\n if (selection.anchorOffset < startPos) return true;\n\n // walk up the DOM tree to check if there are text nodes after cursor\n var treeWalker = document.createTreeWalker(this.owner.el, NodeFilter.SHOW_TEXT);\n treeWalker.currentNode = selection.anchorNode;\n var nextNode = treeWalker.nextNode();\n \n //To capture when treewalker gives us an empty text node (unknown reason)\n var isText = nextNode ? !nextNode.nodeValue.trim() == '' : false;\n\n return isText;\n}\n", "'use strict';\n\n// \n// ###drag facet\n\nvar ComponentFacet = require('../c_facet')\n , facetsRegistry = require('./cf_registry')\n , DOMEventsSource = require('../msg_src/dom_events')\n , Component = require('../c_class')\n , DragDrop = require('../../util/dragdrop')\n , _ = require('mol-proto')\n , logger = require('../../util/logger');\n\n\n/**\n * `milo.registry.facets.get('Drag')`\n * Facet for components that can be dragged\n * Drag facet supports the following configuration parameters:\n *\n * - meta: object with properties\n * - params: object of key-value pairs that will be converted in url-like query string in the end of data type for metadata data type (or function that returns this object). See config.dragDrop.dataTypes.componentMetaTemplate\n * all values will converted to lowercase as datatype cannot store uppercase letters.\n * - data: data that will be stored in the above meta data type (or function)\n * - allowedEffects: string (or function) as specified here: https://developer.mozilla.org/en-US/docs/DragDrop/Drag_Operations#dragstart\n * - dataTypes: map of additional data types the component will supply to data transfer object, key is data type, value is a function that returns it, component will be passed as the context to this function\n *\n * If function is specified in any parameter it will be called with the component as the context\n */\nvar Drag = _.createSubclass(ComponentFacet, 'Drag');\n\n_.extendProto(Drag, {\n init: Drag$init,\n start: Drag$start,\n setHandle: Drag$setHandle\n});\n\nfacetsRegistry.add(Drag);\n\nmodule.exports = Drag;\n\n\nfunction Drag$init() {\n ComponentFacet.prototype.init.apply(this, arguments); \n\n this._createMessageSourceWithAPI(DOMEventsSource);\n this._dragData = {};\n\n var dataTypeInfo = this.config._dataTypeInfo || '';\n this._dataTypeInfo = typeof dataTypeInfo == 'function'\n ? dataTypeInfo\n : function() { return dataTypeInfo; };\n}\n\n\n/**\n * Drag facet instance method\n * Sets the drag handle element of component. This element has to be dragged for the component to be dragged.\n *\n * @param {Element} handleEl\n */\nfunction Drag$setHandle(handleEl) {\n if (! this.owner.el.contains(handleEl))\n return logger.warn('drag handle should be inside element to be dragged')\n this._dragHandle = handleEl;\n}\n\n\nfunction Drag$start() {\n ComponentFacet.prototype.start.apply(this, arguments);\n _addDragAttribute.call(this);\n\n this.onMessages({\n 'mousedown': onMouseDown,\n 'mouseenter mouseleave mousemove': onMouseMovement,\n 'dragstart': onDragStart,\n 'drag': onDragging,\n 'dragend': onDragEnd\n });\n\n this.owner.onMessages({\n 'getstatestarted':\n { subscriber: _removeDragAttribute, context: this },\n 'getstatecompleted':\n { subscriber: _addDragAttribute, context: this }\n });\n}\n\n\n/**\n * Adds draggable attribute to component's element\n *\n * @private\n */\nfunction _addDragAttribute() {\n if (this.owner.el)\n this.owner.el.setAttribute('draggable', true);\n}\n\n\nfunction _removeDragAttribute() {\n if (this.owner.el)\n this.owner.el.removeAttribute('draggable');\n}\n\n\nfunction onMouseDown(eventType, event) {\n this.__mouseDownTarget = event.target;\n if (targetInDragHandle.call(this)) {\n window.getSelection().empty();\n event.stopPropagation();\n }\n}\n\n\nfunction onMouseMovement(eventType, event) {\n var shouldBeDraggable = targetInDragHandle.call(this);\n this.owner.el.setAttribute('draggable', shouldBeDraggable);\n if (document.body.getAttribute('data-dragEnableEvent') != 'false')\n event.stopPropagation();\n}\n\n\nfunction onDragStart(eventType, event) {\n event.stopPropagation();\n if (this.config.off || ! targetInDragHandle.call(this)) {\n event.preventDefault();\n return;\n }\n\n var owner = this.owner;\n var dt = new DragDrop(event);\n\n this._dragData = dt.setComponentState(owner);\n setMeta.call(this);\n setAdditionalDataTypes.call(this);\n _setAllowedEffects.call(this, dt);\n\n DragDrop.service.postMessageSync('dragdropstarted', {\n eventType: 'dragstart',\n dragDrop: dt,\n dragFacet: this\n });\n\n function setMeta() {\n var metaConfig = this.config.meta\n , paramsConfig = metaConfig && metaConfig.params\n , metaDataConfig = metaConfig && metaConfig.data;\n\n var params = _.result(paramsConfig, owner)\n , data = _.result(metaDataConfig, owner);\n\n this._dragMetaDataType = dt.setComponentMeta(owner, params, data);\n this._dragMetaData = data;\n }\n\n function setAdditionalDataTypes() {\n if (this.config.dataTypes) {\n this._dataTypesData = _.mapKeys(this.config.dataTypes, function (getDataFunc, dataType) {\n var data = getDataFunc.call(this.owner, dataType);\n if (typeof data == 'object') data = JSON.stringify(data);\n if (data) dt.setData(dataType, data);\n return data;\n }, this);\n }\n }\n}\n\n\nfunction onDragging(eventType, event) {\n if (_dragIsDisabled.call(this, event)) return;\n\n var dt = new DragDrop(event);\n dt.setComponentState(this.owner, this._dragData);\n dt.setData(this._dragMetaDataType, this._dragMetaData);\n if (this._dataTypesData) {\n _.eachKey(this._dataTypesData, function(data, dataType) {\n if (data) dt.setData(dataType, data);\n });\n }\n\n _setAllowedEffects.call(this, dt);\n}\n\n\nfunction onDragEnd(eventType, event) {\n if (_dragIsDisabled.call(this, event)) return;\n\n event.stopPropagation();\n var dt = new DragDrop(event);\n DragDrop.service.postMessageSync('completedragdrop', {\n eventType: 'dragend',\n dragDrop: dt,\n dragFacet: this\n });\n}\n\n\nfunction _setAllowedEffects(DragDrop) {\n var effects = _.result(this.config.allowedEffects, this.owner);\n DragDrop.setAllowedEffects(effects);\n}\n\n\nfunction targetInDragHandle() {\n return ! this._dragHandle || this._dragHandle.contains(this.__mouseDownTarget);\n}\n\n\nfunction _dragIsDisabled(event) {\n if (this.config.off) {\n event.preventDefault();\n return true;\n }\n return false;\n}\n", "'use strict';\n\n// \n// ###drop facet\n\nvar ComponentFacet = require('../c_facet')\n , facetsRegistry = require('./cf_registry')\n , DOMEventsSource = require('../msg_src/dom_events')\n , DropMsgAPI = require('../msg_api/drop')\n , DragDrop = require('../../util/dragdrop')\n , DropError = require('../../util/error').Drop\n , _ = require('mol-proto')\n , _handleDropDependency;\n\n/**\n * `milo.registry.facets.get('Drop')`\n * Facet for components that can accept drops\n * Drop facet supports the following configuration parameters:\n *\n * - allow - an object that will define allowed data types during drag (`dragenter` and `dragover` events) with these properties:\n * - components: `true` by default (all components will be accepted)\n * OR string with allowed component class\n * OR list of allowed components classes (strings)\n * OR map with allowed classes in keys and `true`/test functions in values\n * OR test function that will be passed object defined below\n * OR `false` to NOT accept components\n * - dataTypes: `false` by default (no other data types will be accepted)\n * OR string with allowed data type\n * OR list of additional data types that a drop target would accept\n * OR test function that will be passed DragDrop object\n * OR `true` to accept all data types\n * - checkParent: `false` by default\n * OR `true` will call parent component drop allow to check if parent component will accept the component\n * If test functions are used, they should return boolean. Each test function can also set drop effect as defined here:\n * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer#dropEffect.28.29\n * Setting drop effect that is not allowed by dragged object will prevent drop.\n * Test functions for components will be passed the owner of Drop facet as context, the object with the following possible properties as the first parameter:\n * compClass - name of component class as stored in registry\n * compName - name of component (all lowercase)\n * params - parameters as encoded in dataType, passed to `milo.util.dragDrop.setComponentMeta` by Drag facet\n * metaDataType - data type of the data that has compClass, compName and params encoded\n *\n * ... and DragDrop instance as the second parameter\n *\n * Test function for other data types will be passed the owner of Drop facet as context and DragDrop instance as the first parameter\n *\n * ####Events####\n *\n * In addition to configuring allowed components and data types, components classes should subscribe to events.\n * At the very least, they should subscribe to `drop` event.\n *\n * Drop facet emits dragin/dragout messages that are emitted whenever actual component element is entered or left\n * (which is different from dragenter and dragleave messages that are emitted whenever any child element is entered or left, as long as event bubbles up)\n * If child component has drop facet attached, dragout will be emitted on the current component when the child is entered.\n *\n * You can see the demonstration of when messages are emitted [here](http://jsbin.com/buqov/6)\n * \n */\nvar Drop = _.createSubclass(ComponentFacet, 'Drop');\n\n\n_.extendProto(Drop, {\n init: Drop$init,\n start: Drop$start\n // _reattach: _reattachEventsOnElementChange\n});\n\nfacetsRegistry.add(Drop);\n\nmodule.exports = Drop;\n\n\nfunction Drop$init() {\n ComponentFacet.prototype.init.apply(this, arguments);\n this._createMessageSourceWithAPI(DOMEventsSource, new DropMsgAPI);\n}\n\n\nfunction Drop$start() {\n ComponentFacet.prototype.start.apply(this, arguments);\n this.owner.el.classList.add('cc-module-relative');\n this.onMessages({\n 'dragenter dragover': onDragging,\n 'drop': onDrop,\n 'dragenter dragover dragleave drop dragin dragout': postToService\n });\n}\n\n\nfunction onDragging(eventType, event) {\n var dt = new DragDrop(event);\n\n event.stopPropagation();\n event.preventDefault();\n\n if (! _handleDropDependency.call(this, dt))\n dt.setDropEffect('none');\n}\n\n\nfunction onDrop(eventType, event) {\n event.stopPropagation();\n var dt = new DragDrop(event);\n DragDrop.service.postMessageSync('dragdropcompleted', {\n eventType: 'drop',\n dragDrop: dt,\n dropFacet: this,\n component: this.owner\n });\n}\n\n\nfunction postToService(eventType, event) {\n DragDrop.service.postMessageSync(eventType, {\n event: event,\n dropFacet: this,\n component: this.owner\n });\n}\n\n\n_handleDropDependency = _.throttle(_handleDropDependencyNothrottle, 50);\nfunction _handleDropDependencyNothrottle(dt, originalDropComponent) {\n var allow = this.config.allow\n , parentAllowed = true;\n\n originalDropComponent = originalDropComponent || this.owner;\n\n if (allow && allow.checkParent) {\n var parent = this.owner.getScopeParent('Drop');\n if (parent)\n parentAllowed = _handleDropDependencyNothrottle.call(parent.drop, dt, originalDropComponent);\n }\n\n return parentAllowed && _isDropAllowed.call(this, dt, originalDropComponent);\n}\n\n\n/**\n * Checks if drop is allowed based on facet configuration (see above)\n * \n * @param {DragDrop} dt\n * @return {Boolean}\n */\nfunction _isDropAllowed(dt, originalDropComponent) {\n var allow = this.config.allow;\n\n if (dt.isComponent()) {\n var allowComps = allow && allow.components\n , meta = dt.getComponentMeta();\n\n switch (typeof allowComps) {\n case 'undefined':\n return true;\n case 'boolean':\n return allowComps;\n // component class\n case 'string':\n return meta && meta.compClass == allowComps;\n // test function\n case 'function':\n return allowComps.call(this.owner, meta, dt, originalDropComponent);\n case 'object':\n if (Array.isArray(allowComps))\n // list of allowed classes\n return allowComps.indexOf(meta && meta.compClass) >= 0;\n else {\n // map of class: boolean|test function\n var test = allowComps[meta && meta.compClass];\n return !! _.result(test, this.owner, meta, dt);\n }\n default:\n throw new DropError('Incorrect allowed components in config');\n }\n } else {\n var dataTypes = allow && allow.dataTypes\n switch (typeof dataTypes) {\n case 'undefined':\n return false;\n case 'string':\n return dt.types.indexOf(dataTypes) >= 0;\n }\n }\n\n // TODO test for other data types\n}\n", @@ -194,7 +219,7 @@ "'use strict';\n\nvar Component = require('../c_class')\n , componentsRegistry = require('../c_registry');\n\n\nvar MLTime = Component.createComponentClass('MLTime', {\n events: undefined,\n data: {\n get: MLTime_get,\n set: MLTime_set,\n del: MLTime_del,\n },\n dom: {\n cls: 'ml-ui-time'\n }\n});\n\ncomponentsRegistry.add(MLTime);\n\nmodule.exports = MLTime;\n\n\nvar TIME_REGEX = /^([0-9]{1,2})(?:\\:|\\.)([0-9]{1,2})$/\n , TIME_TEMPLATE = 'hh:mm';\n\nfunction MLTime_get() {\n var timeStr = this.el.value;\n var match = timeStr.match(TIME_REGEX);\n if (! match) return;\n var hours = match[1]\n , mins = match[2];\n if (hours > 23 || mins > 59) return;\n var time = new Date(1970, 0, 1, hours, mins);\n\n return _.toDate(time);\n}\n\n\nfunction MLTime_set(value) {\n var time = _.toDate(value);\n if (! time) {\n this.el.value = '';\n return;\n }\n\n var timeStr = TIME_TEMPLATE\n .replace('hh', pad(time.getHours()))\n .replace('mm', pad(time.getMinutes()));\n\n this.el.value = timeStr;\n return timeStr;\n\n function pad(n) {return n < 10 ? '0' + n : n; }\n}\n\n\nfunction MLTime_del() {\n this.el.value = '';\n}\n", "'use strict';\n\nvar Component = require('../c_class')\n , componentsRegistry = require('../c_registry');\n\n\nvar MLWrapper = Component.createComponentClass('MLWrapper', {\n container: undefined,\n data: undefined,\n events: undefined,\n dom: {\n cls: 'ml-ui-wrapper'\n }\n});\n\ncomponentsRegistry.add(MLWrapper);\n\nmodule.exports = MLWrapper;\n", "'use strict';\n\nvar Component = require('../../c_class')\n , componentsRegistry = require('../../c_registry')\n , componentName = require('../../../util/component_name')\n , logger = require('../../../util/logger')\n , check = require('../../../util/check')\n , Match = check.Match\n , _ = require('mol-proto');\n\n\nvar ALERT_CSS_CLASSES = {\n success: 'alert-success',\n warning: 'alert-warning',\n info: 'alert-info',\n danger: 'alert-danger',\n fixed: 'alert-fixed'\n};\n\n\nvar MLAlert = Component.createComponentClass('MLAlert', {\n container: undefined,\n events: undefined,\n dom: {\n cls: ['ml-bs-alert', 'alert', 'fade'],\n attributes: {\n 'role': 'alert',\n 'aria-hidden': 'true'\n }\n },\n template: {\n template: '\\\n {{? it.close }}\\\n \\\n {{?}}\\\n {{= it.message}}'\n }\n});\n\ncomponentsRegistry.add(MLAlert);\n\nmodule.exports = MLAlert;\n\n\n_.extend(MLAlert, {\n createAlert: MLAlert$$createAlert,\n openAlert: MLAlert$$openAlert,\n});\n\n\n_.extendProto(MLAlert, {\n openAlert: MLAlert$openAlert,\n closeAlert: MLAlert$closeAlert\n});\n\n\n/**\n * Creates and returns a new alert instance. To create and open at the same time use [openAlert](#MLAlert$$openAlert)\n * `options` is an object with the following properties:\n *\n * message: string alert message\n * type: optional string the type of alert message, one of success, warning, info, danger, fixed\n * default 'info'\n * close: optional false to prevent user from closing\n * or true (default) to enable closing and render a close button\n * timeout: optional timer, in milliseconds to automatically close the alert\n *\n * @param {Object} options alert configuration\n */\nfunction MLAlert$$createAlert(options) {\n check(options, {\n message: String,\n type: Match.Optional(String),\n close: Match.Optional(Boolean),\n timeout: Match.Optional(Number)\n });\n\n var alert = MLAlert.createOnElement();\n\n options = _prepareOptions(options);\n\n var alertCls = ALERT_CSS_CLASSES[options.type];\n alert.dom.addCssClasses(alertCls);\n\n alert._alert = {\n options: options,\n visible: false\n };\n\n alert.template.render(options).binder();\n\n var alertScope = alert.container.scope;\n\n if (options.close)\n alertScope.closeBtn.events.on('click',\n { subscriber: _onCloseBtnClick, context: alert });\n\n if (options.timeout)\n var timer = setTimeout(function(){\n if(alert._alert.visible)\n alert.closeAlert();\n }, options.timeout);\n\n return alert;\n}\n\n\n/**\n * Create and show alert popup\n *\n * @param {Object} options object with message, type, close and timeout\n * @return {MLAlert} the alert instance\n */\nfunction MLAlert$$openAlert(options) {\n var alert = MLAlert.createAlert(options);\n alert.openAlert();\n return alert;\n}\n\n\nfunction _onCloseBtnClick(type, event) {\n this.closeAlert();\n}\n\n\nfunction _prepareOptions(options) {\n options = _.clone(options);\n options.close = typeof options.close == 'undefined' || options.close === true;\n options.timeout = Math.floor(options.timeout);\n options.type = options.type || 'info';\n\n return options;\n}\n\n\n/**\n * Open the alert\n */\nfunction MLAlert$openAlert() {\n _toggleAlert.call(this, true);\n}\n\n\n/**\n * Close the alert\n */\nfunction MLAlert$closeAlert() {\n _toggleAlert.call(this, false);\n this.destroy();\n}\n\n\nfunction _toggleAlert(doShow) {\n doShow = typeof doShow == 'undefined'\n ? ! this._alert.visible\n : !! doShow;\n\n var addRemove = doShow ? 'add' : 'remove'\n , appendRemove = doShow ? 'appendChild' : 'removeChild';\n\n this._alert.visible = doShow;\n\n document.body[appendRemove](this.el);\n this.dom.toggle(doShow);\n this.el.setAttribute('aria-hidden', !doShow);\n this.el.classList[addRemove]('in');\n this.el[doShow ? 'focus' : 'blur']();\n}\n", - "'use strict';\n\nvar Component = require('../../c_class')\n , componentsRegistry = require('../../c_registry')\n , componentName = require('../../../util/component_name')\n , logger = require('../../../util/logger')\n , check = require('../../../util/check')\n , Match = check.Match\n , _ = require('mol-proto');\n\n\nvar DEFAULT_BUTTONS = [ { type: 'default', label: 'OK', result: 'OK' } ];\n\nvar CLOSE_OPTIONS = ['backdrop', 'keyboard', 'button'];\n\nvar BUTTON_CSS_CLASSES = { // TODO - use in template\n default: 'btn-default',\n primary: 'btn-primary',\n success: 'btn-success',\n info: 'btn-info',\n warning: 'btn-warning',\n danger: 'btn-danger',\n link: 'btn-link'\n}\n\n\n/**\n * Dialog class to show custom dialog boxes based on configuration - see [createDialog](#MLDialog$$createDialog) method.\n * Only one dialog can be opened at a time - trying to open another will log error to console. Currently opened dialog can be retrieved using [getCurrentDialog](#MLDialog$$getCurrentDialog) class method.\n */\nvar MLDialog = Component.createComponentClass('MLDialog', {\n container: undefined,\n events: undefined,\n dom: {\n cls: ['ml-bs-dialog', 'modal', 'fade'],\n attributes: {\n 'role': 'dialog',\n 'aria-hidden': 'true'\n }\n },\n template: {\n template: '\\\n
\\\n
\\\n {{? it.title }}\\\n
\\\n {{? it.close.button }}\\\n \\\n {{?}}\\\n

{{= it.title }}

\\\n
\\\n {{?}}\\\n {{? it.html || it.text }}\\\n
\\\n {{? it.html }}\\\n {{= it.html }}\\\n {{??}}\\\n

{{= it.text }}

\\\n {{?}}\\\n
\\\n {{?}}\\\n {{? it.buttons && it.buttons.length }}\\\n
\\\n {{~ it.buttons :btn }}\\\n \\\n {{~}}\\\n
\\\n {{?}}\\\n
\\\n
'\n }\n});\n\ncomponentsRegistry.add(MLDialog);\n\nmodule.exports = MLDialog;\n\n\n_.extend(MLDialog, {\n createDialog: MLDialog$$createDialog,\n openDialog: MLDialog$$openDialog,\n getOpenedDialog: MLDialog$$getOpenedDialog\n});\n\n\n_.extendProto(MLDialog, {\n openDialog: MLDialog$openDialog,\n closeDialog: MLDialog$closeDialog,\n destroy: MLDialog$destroy\n});\n\n\n/**\n * Creates and returns dialog instance. To create and open at the same time [openDialog](#MLDialog$$openDialog)\n * `options` is an object with the following properties:\n *\n * title: optional dialog title\n * html: optional dialog text as html (will take precedence over text if both text nd html are passed)\n * or\n * text: optional dialog text\n * close: optional false to prevent backdrop and esc key from closing the dialog and removing close button in top right corner\n * or true (default) to enable all close options\n * or object with properties\n * backdrop: false or true (default), close dialog when backdrop clicked\n * keyboard: false or true (default), close dialog when esc key is pressed\n * button: false or true (default), show close button in the header (won't be shown if there is no header when title is not passed)\n * buttons: optional array of buttons configurations, where each button config is an object\n * name: optional name of component, should be unique and should not be `closeBtn`, if not passed a timestamp based name will be used\n * type: button type, will determine button CSS style. Possible types are: defult, primary, success, info, warning, danger, link (map to related bootstrap button styles)\n * label: button label\n * close: optional false to prevent this button from closing dialog\n * result: string with dialog close result that will be passed to dialog subscriber as the first parameter\n * data: any value/object or function to create data that will be passed to dialog subscriber as the second parameter.\n * If function is passed it will be called with dialog as context and button options as parameter.\n *\n * If `title` is not passed, dialog will not have title section \n * If neither `text` nor `html` is passed, dialog will not have body section.\n * If `buttons` are not passed, there will only be OK button.\n *\n * When dialog is closed, the subscriber is called with reault and optional data as defined in buttons configurations.\n * If backdrop is clicked or ESC key is pressed the result will be 'dismissed'\n * If close button in the top right corner is clicked, the result will be 'closed' (default result)\n * \n * @param {Object} options dialog configuration\n * @param {Function} initialize function that is called to initialize the dialog\n */\nfunction MLDialog$$createDialog(options, initialize) {\n check(options, {\n title: Match.Optional(String),\n html: Match.Optional(String),\n text: Match.Optional(String),\n close: Match.Optional(Match.OneOf(Boolean, {\n backdrop: Match.Optional(Boolean),\n keyboard: Match.Optional(Boolean),\n button: Match.Optional(Boolean)\n })),\n buttons: Match.Optional([ {\n name: Match.Optional(String),\n type: String,\n label: String,\n close: Match.Optional(Boolean),\n result: Match.Optional(String),\n data: Match.Optional(Match.Any),\n cls: Match.Optional(String)\n } ])\n });\n\n var dialog = MLDialog.createOnElement();\n\n options = _prepareOptions(options);\n dialog._dialog = {\n options: options,\n visible: false\n };\n\n dialog.template\n .render(options)\n .binder();\n\n var dialogScope = dialog.container.scope;\n\n if (options.close.backdrop)\n dialog.events.on('click',\n { subscriber: _onBackdropClick, context: dialog });\n\n if (options.title && options.close.button)\n dialogScope.closeBtn.events.on('click',\n { subscriber: _onCloseBtnClick, context: dialog });\n\n options.buttons.forEach(function(btn) {\n var buttonSubscriber = {\n subscriber: _.partial(_dialogButtonClick, btn),\n context: dialog\n };\n dialogScope[btn.name].events.on('click', buttonSubscriber);\n });\n\n if (initialize) initialize(dialog);\n return dialog;\n}\n\n\nfunction _dialogButtonClick(button) {\n if (button.close !== false)\n _toggleDialog.call(this, false)\n\n var data = _.result(button.data, this, button);\n _dispatchResult.call(this, button.result, data);\n}\n\n\nfunction _dispatchResult(result, data) {\n var subscriber = this._dialog.subscriber;\n if (typeof subscriber == 'function')\n subscriber.call(this, result, data);\n else\n subscriber.subscriber.call(subscriber.context, result, data);\n}\n\n\nfunction _onBackdropClick(eventType, event) {\n if (event.target == this.el)\n this.closeDialog('dismissed');\n}\n\n\nfunction _onCloseBtnClick() {\n this.closeDialog('closed');\n}\n\n\nfunction _onKeyDown(event) {\n if (openedDialog\n && openedDialog._dialog.options.close.keyboard\n && event.keyCode == 27) // esc key\n openedDialog.closeDialog('dismissed');\n}\n\n\nfunction _prepareOptions(options) {\n options = _.clone(options);\n options.buttons = _.clone(options.buttons || DEFAULT_BUTTONS);\n options.buttons.forEach(function(btn) {\n btn.name = btn.name || componentName();\n });\n\n options.close = typeof options.close == 'undefined' || options.close === true\n ? _.object(CLOSE_OPTIONS, true)\n : typeof options.close == 'object'\n ? _.mapToObject(CLOSE_OPTIONS,\n function(opt) { return options.close[opt] !== false; })\n : _.object(CLOSE_OPTIONS, false);\n\n return options;\n}\n\n\n/**\n * Create and show dialog popup\n * \n * @param {Object} options object with title, text and buttons. See [createDialog](#MLDialog$$createDialog) for more information.\n * @param {Function|Object} subscriber optional subscriber function or object that is passed result and optional data. Unless context is defined, dialog will be the context.\n */\nfunction MLDialog$$openDialog(options, subscriber, initialize) {\n var dialog = MLDialog.createDialog(options, initialize);\n dialog.openDialog(subscriber);\n return dialog;\n}\n\n\n\nfunction _toggleDialog(doShow) {\n doShow = typeof doShow == 'undefined'\n ? ! this._dialog.visible\n : !! doShow;\n\n var addRemove = doShow ? 'add' : 'remove'\n , appendRemove = doShow ? 'appendChild' : 'removeChild';\n\n this._dialog.visible = doShow;\n\n if (doShow && ! dialogsInitialized)\n _initializeDialogs();\n\n document.body[appendRemove](this.el);\n if (backdropEl)\n document.body[appendRemove](backdropEl);\n this.dom.toggle(doShow);\n this.el.setAttribute('aria-hidden', !doShow);\n document.body.classList[addRemove]('modal-open');\n this.el.classList[addRemove]('in');\n\n openedDialog = doShow ? this : undefined;\n this.el[doShow ? 'focus' : 'blur']();\n}\n\n\nvar dialogsInitialized, backdropEl;\n\nfunction _initializeDialogs() {\n backdropEl = document.createElement('div');\n backdropEl.className = 'modal-backdrop fade in';\n document.addEventListener('keydown', _onKeyDown);\n dialogsInitialized = true;\n}\n\n\nvar openedDialog;\n\n/**\n * Opens dialog instance.\n * Subscriber object should have the same format as the subscriber for the Messenger (although Messenger is not used) - either function or object with subscriber and context properties.\n * \n * @param {Function|Object} subscriber subscriber object\n */\nfunction MLDialog$openDialog(subscriber) {\n check(subscriber, Match.OneOf(Function, { subscriber: Function, context: Match.Any }));\n\n if (openedDialog)\n return logger.warn('MLDialog openDialog: can\\'t open dialog, another dialog is already open');\n\n this._dialog.subscriber = subscriber;\n _toggleDialog.call(this, true);\n}\n\n\n/**\n * Closes dialog instance, optionally passing result and data to dialog subscriber.\n * If no result is passed, 'closed' will be passed to subscriber.\n *\n * @param {String} result dialog result, passed as the first parameter to subcsriber\n * @param {Any} data optional dialog data, passed as the second parameter to subscriber\n */\nfunction MLDialog$closeDialog(result, data) {\n if (! openedDialog)\n return logger.warn('MLDialog closeDialog: can\\'t close dialog, no dialog open');\n\n result = result || 'closed';\n\n _toggleDialog.call(this, false);\n _dispatchResult.call(this, result, data);\n}\n\n\n/**\n * Returns currently opened dialog\n *\n * @return {MLDialog}\n */\nfunction MLDialog$$getOpenedDialog() {\n return openedDialog;\n}\n\n\nfunction MLDialog$destroy() {\n document.removeEventListener('keydown', _onKeyDown);\n Component.prototype.destroy.apply(this, arguments);\n}\n", + "'use strict';\n\nvar Component = require('../../c_class')\n , componentsRegistry = require('../../c_registry')\n , componentName = require('../../../util/component_name')\n , logger = require('../../../util/logger')\n , check = require('../../../util/check')\n , Match = check.Match\n , _ = require('mol-proto');\n\n\nvar DEFAULT_BUTTONS = [ { type: 'default', label: 'OK', result: 'OK' } ];\n\nvar CLOSE_OPTIONS = ['backdrop', 'keyboard', 'button'];\n\nvar BUTTON_CSS_CLASSES = { // TODO - use in template\n default: 'btn-default',\n primary: 'btn-primary',\n success: 'btn-success',\n info: 'btn-info',\n warning: 'btn-warning',\n danger: 'btn-danger',\n link: 'btn-link'\n};\n\n\n/**\n * Dialog class to show custom dialog boxes based on configuration - see [createDialog](#MLDialog$$createDialog) method.\n * Only one dialog can be opened at a time - trying to open another will log error to console. Currently opened dialog can be retrieved using [getCurrentDialog](#MLDialog$$getCurrentDialog) class method.\n */\nvar MLDialog = Component.createComponentClass('MLDialog', {\n container: undefined,\n events: undefined,\n dom: {\n cls: ['ml-bs-dialog', 'modal', 'fade'],\n attributes: {\n 'role': 'dialog',\n 'aria-hidden': 'true'\n }\n },\n template: {\n template: '\\\n
\\\n
\\\n {{? it.title }}\\\n
\\\n {{? it.close.button }}\\\n \\\n {{?}}\\\n

{{= it.title }}

\\\n
\\\n {{?}}\\\n {{? it.html || it.text }}\\\n
\\\n {{? it.html }}\\\n {{= it.html }}\\\n {{??}}\\\n

{{= it.text }}

\\\n {{?}}\\\n
\\\n {{?}}\\\n {{? it.buttons && it.buttons.length }}\\\n
\\\n {{~ it.buttons :btn }}\\\n \\\n {{~}}\\\n
\\\n {{?}}\\\n
\\\n
'\n }\n});\n\ncomponentsRegistry.add(MLDialog);\n\nmodule.exports = MLDialog;\n\n\n_.extend(MLDialog, {\n createDialog: MLDialog$$createDialog,\n openDialog: MLDialog$$openDialog,\n getOpenedDialog: MLDialog$$getOpenedDialog\n});\n\n\n_.extendProto(MLDialog, {\n openDialog: MLDialog$openDialog,\n closeDialog: MLDialog$closeDialog,\n destroy: MLDialog$destroy\n});\n\n\n/**\n * Creates and returns dialog instance. To create and open at the same time [openDialog](#MLDialog$$openDialog)\n * `options` is an object with the following properties:\n *\n * title: optional dialog title\n * html: optional dialog text as html (will take precedence over text if both text nd html are passed)\n * or\n * text: optional dialog text\n * close: optional false to prevent backdrop and esc key from closing the dialog and removing close button in top right corner\n * or true (default) to enable all close options\n * or object with properties\n * backdrop: false or true (default), close dialog when backdrop clicked\n * keyboard: false or true (default), close dialog when esc key is pressed\n * button: false or true (default), show close button in the header (won't be shown if there is no header when title is not passed)\n * buttons: optional array of buttons configurations, where each button config is an object\n * name: optional name of component, should be unique and should not be `closeBtn`, if not passed a timestamp based name will be used\n * type: button type, will determine button CSS style. Possible types are: defult, primary, success, info, warning, danger, link (map to related bootstrap button styles)\n * label: button label\n * close: optional false to prevent this button from closing dialog\n * result: string with dialog close result that will be passed to dialog subscriber as the first parameter\n * data: any value/object or function to create data that will be passed to dialog subscriber as the second parameter.\n * If function is passed it will be called with dialog as context and button options as parameter.\n *\n * If `title` is not passed, dialog will not have title section \n * If neither `text` nor `html` is passed, dialog will not have body section.\n * If `buttons` are not passed, there will only be OK button.\n *\n * When dialog is closed, the subscriber is called with reault and optional data as defined in buttons configurations.\n * If backdrop is clicked or ESC key is pressed the result will be 'dismissed'\n * If close button in the top right corner is clicked, the result will be 'closed' (default result)\n * \n * @param {Object} options dialog configuration\n * @param {Function} initialize function that is called to initialize the dialog\n */\nfunction MLDialog$$createDialog(options, initialize) {\n check(options, {\n title: Match.Optional(String),\n html: Match.Optional(String),\n text: Match.Optional(String),\n close: Match.Optional(Match.OneOf(Boolean, {\n backdrop: Match.Optional(Boolean),\n keyboard: Match.Optional(Boolean),\n button: Match.Optional(Boolean)\n })),\n buttons: Match.Optional([ {\n name: Match.Optional(String),\n type: String,\n label: String,\n close: Match.Optional(Boolean),\n result: Match.Optional(String),\n data: Match.Optional(Match.Any),\n cls: Match.Optional(String)\n } ])\n });\n\n var dialog = MLDialog.createOnElement();\n\n options = _prepareOptions(options);\n dialog._dialog = {\n options: options,\n visible: false\n };\n\n dialog.template\n .render(options)\n .binder();\n\n var dialogScope = dialog.container.scope;\n\n if (options.close.backdrop)\n dialog.events.on('click',\n { subscriber: _onBackdropClick, context: dialog });\n\n if (options.title && options.close.button)\n dialogScope.closeBtn.events.on('click',\n { subscriber: _onCloseBtnClick, context: dialog });\n\n options.buttons.forEach(function(btn) {\n var buttonSubscriber = {\n subscriber: _.partial(_dialogButtonClick, btn),\n context: dialog\n };\n dialogScope[btn.name].events.on('click', buttonSubscriber);\n });\n\n if (initialize) initialize(dialog);\n return dialog;\n}\n\n\nfunction _dialogButtonClick(button) {\n if (button.close !== false)\n _toggleDialog.call(this, false);\n\n var data = _.result(button.data, this, button);\n _dispatchResult.call(this, button.result, data);\n}\n\n\nfunction _dispatchResult(result, data) {\n var subscriber = this._dialog.subscriber;\n if (typeof subscriber == 'function')\n subscriber.call(this, result, data);\n else\n subscriber.subscriber.call(subscriber.context, result, data);\n}\n\n\nfunction _onBackdropClick(eventType, event) {\n if (event.target == this.el)\n this.closeDialog('dismissed');\n}\n\n\nfunction _onCloseBtnClick() {\n this.closeDialog('closed');\n}\n\n\nfunction _onKeyDown(event) {\n if (openedDialog\n && openedDialog._dialog.options.close.keyboard\n && event.keyCode == 27) // esc key\n openedDialog.closeDialog('dismissed');\n}\n\n\nfunction _prepareOptions(options) {\n options = _.clone(options);\n options.buttons = _.clone(options.buttons || DEFAULT_BUTTONS);\n options.buttons.forEach(function(btn) {\n btn.name = btn.name || componentName();\n });\n\n options.close = typeof options.close == 'undefined' || options.close === true\n ? _.object(CLOSE_OPTIONS, true)\n : typeof options.close == 'object'\n ? _.mapToObject(CLOSE_OPTIONS,\n function(opt) { return options.close[opt] !== false; })\n : _.object(CLOSE_OPTIONS, false);\n\n return options;\n}\n\n\n/**\n * Create and show dialog popup\n * \n * @param {Object} options object with title, text and buttons. See [createDialog](#MLDialog$$createDialog) for more information.\n * @param {Function|Object} subscriber optional subscriber function or object that is passed result and optional data. Unless context is defined, dialog will be the context.\n */\nfunction MLDialog$$openDialog(options, subscriber, initialize) {\n var dialog = MLDialog.createDialog(options, initialize);\n dialog.openDialog(subscriber);\n return dialog;\n}\n\n\n\nfunction _toggleDialog(doShow) {\n doShow = typeof doShow == 'undefined'\n ? ! this._dialog.visible\n : !! doShow;\n\n var addRemove = doShow ? 'add' : 'remove'\n , appendRemove = doShow ? 'appendChild' : 'removeChild';\n\n this._dialog.visible = doShow;\n\n if (doShow && ! dialogsInitialized)\n _initializeDialogs();\n\n document.body[appendRemove](this.el);\n if (backdropEl)\n document.body[appendRemove](backdropEl);\n this.dom.toggle(doShow);\n this.el.setAttribute('aria-hidden', !doShow);\n document.body.classList[addRemove]('modal-open');\n this.el.classList[addRemove]('in');\n\n openedDialog = doShow ? this : undefined;\n this.el[doShow ? 'focus' : 'blur']();\n}\n\n\nvar dialogsInitialized, backdropEl;\n\nfunction _initializeDialogs() {\n backdropEl = document.createElement('div');\n backdropEl.className = 'modal-backdrop fade in';\n document.addEventListener('keydown', _onKeyDown);\n dialogsInitialized = true;\n}\n\n\nvar openedDialog;\n\n/**\n * Opens dialog instance.\n * Subscriber object should have the same format as the subscriber for the Messenger (although Messenger is not used) - either function or object with subscriber and context properties.\n * \n * @param {Function|Object} subscriber subscriber object\n */\nfunction MLDialog$openDialog(subscriber) {\n check(subscriber, Match.OneOf(Function, { subscriber: Function, context: Match.Any }));\n\n if (openedDialog)\n return logger.warn('MLDialog openDialog: can\\'t open dialog, another dialog is already open');\n\n this._dialog.subscriber = subscriber;\n _toggleDialog.call(this, true);\n}\n\n\n/**\n * Closes dialog instance, optionally passing result and data to dialog subscriber.\n * If no result is passed, 'closed' will be passed to subscriber.\n *\n * @param {String} result dialog result, passed as the first parameter to subcsriber\n * @param {Any} data optional dialog data, passed as the second parameter to subscriber\n */\nfunction MLDialog$closeDialog(result, data) {\n if (! openedDialog)\n return logger.warn('MLDialog closeDialog: can\\'t close dialog, no dialog open');\n\n result = result || 'closed';\n\n _toggleDialog.call(this, false);\n _dispatchResult.call(this, result, data);\n}\n\n\n/**\n * Returns currently opened dialog\n *\n * @return {MLDialog}\n */\nfunction MLDialog$$getOpenedDialog() {\n return openedDialog;\n}\n\n\nfunction MLDialog$destroy() {\n document.removeEventListener('keydown', _onKeyDown);\n Component.prototype.destroy.apply(this, arguments);\n}\n", "'use strict';\n\nvar Component = require('../../c_class')\n , componentsRegistry = require('../../c_registry')\n , _ = require('mol-proto')\n , logger = require('../../../util/logger')\n , DOMListeners = require('../../../util/dom_listeners');\n\n\nvar TOGGLE_CSS_CLASS = 'dropdown-toggle'\n , MENU_CSS_CLASS = 'dropdown-menu';\n\n\nvar MLDropdown = Component.createComponentClass('MLDropdown', {\n events: undefined,\n dom: {\n cls: ['ml-bs-dropdown', 'dropdown']\n }\n});\n\ncomponentsRegistry.add(MLDropdown);\n\nmodule.exports = MLDropdown;\n\n\n_.extendProto(MLDropdown, {\n start: MLDropdown$start,\n destroy: MLDropdown$destroy,\n toggleMenu: MLDropdown$toggleMenu,\n showMenu: MLDropdown$showMenu,\n hideMenu: MLDropdown$hideMenu\n});\n\n\nfunction MLDropdown$start() {\n var toggleEl = this.el.querySelector('.' + TOGGLE_CSS_CLASS)\n , menuEl = this.el.querySelector('.' + MENU_CSS_CLASS);\n\n if (! (toggleEl && menuEl))\n return logger.error('MLDropdown:', TOGGLE_CSS_CLASS, 'or', MENU_CSS_CLASS, 'isn\\'t found');\n\n var doc = window.document\n , clickHandler = this.toggleMenu.bind(this, undefined);\n\n var listeners = new DOMListeners;\n this._dropdown = {\n menu: menuEl,\n visible: false,\n listeners: listeners\n };\n this.hideMenu();\n var self = this;\n\n listeners.add(toggleEl, 'click', clickHandler);\n //maybe only add this events if is open?\n listeners.add(doc, 'mouseout', onDocOut);\n listeners.add(doc, 'click', onClick);\n\n\n function onDocOut(event) {\n var target = event.target\n , relatedTarget = event.relatedTarget\n , listeners = self._dropdown.listeners;\n\n if (isIframe(target))\n listeners.remove(target.contentWindow.document, 'click', onClick);\n\n if (isIframe(relatedTarget))\n listeners.add(relatedTarget.contentWindow.document, 'click', onClick);\n }\n\n function onClick(event) {\n if (!self.el.contains(event.target))\n self.hideMenu();\n }\n}\n\n\nfunction isIframe(el) {\n return el && el.tagName == 'IFRAME';\n}\n\n\nfunction MLDropdown$destroy() {\n this._dropdown.listeners.removeAll();\n delete this._dropdown;\n Component.prototype.destroy.apply(this, arguments);\n}\n\n\nfunction MLDropdown$showMenu() {\n this.toggleMenu(true);\n}\n\n\nfunction MLDropdown$hideMenu() {\n this.toggleMenu(false);\n}\n\n\nfunction MLDropdown$toggleMenu(doShow) {\n doShow = typeof doShow == 'undefined'\n ? ! this._dropdown.visible\n : !! doShow;\n\n this._dropdown.visible = doShow;\n\n var menu = this._dropdown.menu;\n menu.style.display = doShow\n ? 'block'\n : 'none';\n}\n", "'use strict';\n\n\n// \n// milo.config\n// -----------\n\n// It is the function that allows to change milo configurations and also\n// access them on config's properties.\n\n// ```javascript\n// milo.config({\n// attrs: {\n// bind: 'ml-bind',\n// load: 'ml-load'\n// }\n// });\n// ```\n\n\nvar _ = require('mol-proto')\n , doT = require('dot');\n\n\nmodule.exports = config;\n\nfunction config(options) {\n _.deepExtend(config, options);\n}\n\nconfig({\n attrs: {\n bind: 'ml-bind',\n load: 'ml-load'\n },\n componentRef: '___milo_component',\n componentPrefix: 'milo_',\n mixin: {\n instancePropertiesMap: '___mixin_instances'\n },\n template: {\n compile: doT.compile\n },\n domStorage: {\n typeSuffix: ':___milo_data_type',\n prefixSeparator: '/',\n root: '',\n messageKey: '___milo_message/',\n messageTimestamp: '___milo_timestamp',\n quotaExceeded: {\n throwError: true,\n message: false\n }\n },\n dragDrop: {\n dataTypes: {\n component: 'x-application/milo/component',\n componentMetaTemplate: 'x-application/milo/component-meta/%class/%name/%params',\n componentMetaRegex: /^x\\-application\\/milo\\/component\\-meta\\/([a-z0-9]+)\\/([a-z0-9]+)\\/([a-z0-9]*)$/,\n }\n },\n request: {\n jsonpTimeout: 60000,\n jsonpCallbackPrefix: '___milo_callback_',\n optionsKey: '___milo_options',\n defaults: {\n timeout: 60000\n }\n },\n websocket: {\n rpc: {\n timeout: 15000,\n responsePrefix: 'response_'\n }\n },\n check: true,\n debug: false\n});\n", "'use strict';\n\n\nvar miloMail = require('./services/mail')\n , request = require('./util/request')\n , logger = require('./util/logger')\n , utilDom = require('./util/dom')\n , config = require('./config')\n , LoadAttribute = require('./attributes/a_load')\n , LoaderError = require('./util/error').Loader;\n\n\nmodule.exports = loader;\n\n/**\n * `milo.loader`\n * \n * Recursively scans the document tree inside `rootEl` (document.body by default) looking for __ml-load__ @attribute.\n * One level load is executed. No additional loader get called on inside __ml-load__ attributes. \n *\n * Possible usages:\n * - milo.loader([myRootEl,][myRemoveAttribute,]myCallback)\n * \n * @param {Element} rootEl Root element inside which DOM will be scanned (document.body by default).\n * @param {Boolean} removeAttribute If set to true, then the __ml-load__ attribute will be removed once loader has been executed (False by default).\n * @param {Function} callback Callback to call after all elements get loaded (Required).\n */\nfunction loader(rootEl, removeAttribute, callback) {\n milo(function() {\n _loader(rootEl, removeAttribute, callback);\n });\n}\n\n\nfunction _loader(rootEl, removeAttribute, callback) {\n if (typeof rootEl == 'function') {\n callback = rootEl;\n rootEl = undefined;\n removeAttribute = false;\n }\n\n if (typeof removeAttribute == 'function') {\n callback = removeAttribute;\n removeAttribute = false;\n }\n\n rootEl = rootEl || document.body;\n\n miloMail.postMessage('loader', { state: 'started' });\n _loadViewsInElement(rootEl, removeAttribute, function(views) {\n miloMail.postMessage('loader', { \n state: 'finished',\n views: views\n });\n callback(views);\n });\n}\n\n\nfunction _loadViewsInElement(rootEl, removeAttribute, callback) {\n var loadElements = rootEl.getAttribute(config.attrs.load)\n ? [rootEl]\n : rootEl.querySelectorAll('[' + config.attrs.load + ']');\n\n var views = {}\n , totalCount = loadElements.length\n , loadedCount = 0;\n\n _.forEach(loadElements, function (el) {\n loadView(el, removeAttribute, function(err) {\n views[el.id] = err || el;\n loadedCount++;\n if (loadedCount == totalCount)\n callback(views);\n });\n });\n};\n\n\nfunction loadView(el, removeAttribute, callback) {\n if (utilDom.children(el).length)\n throw new LoaderError('can\\'t load html into element that is not empty');\n\n var attr = new LoadAttribute(el);\n\n attr.parse().validate();\n\n request.get(attr.loadUrl, function(err, html) {\n if (err) {\n err.message = err.message || 'can\\'t load file ' + attr.loadUrl;\n // logger.error(err.message);\n callback(err);\n return;\n }\n\n el.innerHTML = html;\n if (removeAttribute) LoadAttribute.remove(el);\n callback(null);\n });\n}\n", @@ -203,10 +228,8 @@ "'use strict';\n\nvar MessengerAPI = require('./m_api')\n , _ = require('mol-proto');\n\n\n/**\n * A generic subsclass of [MessengerAPI](./m_api.js.html) that supports pattern subscriptions to source.\n * Can be useful if the source is another Messenger.\n */\n var MessengerRegexpAPI = _.createSubclass(MessengerAPI, 'MessengerRegexpAPI');\n\n module.exports = MessengerRegexpAPI;\n\n\n_.extendProto(MessengerRegexpAPI, {\n init: init,\n addInternalMessage: addInternalMessage,\n removeInternalMessage: removeInternalMessage,\n getInternalMessages: getInternalMessages\n});\n\n\n/**\n * MessengerRegexpAPI instance method\n * Called by MessengerRegexpAPI constructor.\n */\nfunction init() {\n MessengerAPI.prototype.init.apply(this, arguments);\n _.defineProperties(this, {\n _patternInternalMessages: {}\n });\n this._catchAllSubscribed = false;\n}\n\n\n/**\n * MessengerRegexpAPI instance method\n * Augments MessengerAPI method by storing regexp\n *\n * @param {String} message internal message to be translated and added\n * @return {String|RegExp|undefined}\n */\nfunction addInternalMessage(message) {\n var sourceMessage = MessengerAPI.prototype.addInternalMessage.apply(this, arguments);\n \n // store regexp itself if sourceMessage is regexp\n if (sourceMessage && sourceMessage instanceof RegExp) {\n this._internalMessages[sourceMessage].pattern = sourceMessage;\n this._patternInternalMessages[sourceMessage] = this._internalMessages[sourceMessage];\n if (this._catchAllSubscribed) return;\n this._catchAllSubscribed = true;\n return /.*/;\n }\n\n return sourceMessage;\n}\n\n\n/**\n * MessengerRegexpAPI instance method\n * Augments MessengerAPI method by removing regexp subscirption\n * \n * @param {String} message internal message to be translated and added\n * @return {String|RegExp|undefined}\n */\nfunction removeInternalMessage(message) {\n var sourceMessage = MessengerAPI.prototype.removeInternalMessage.apply(this, arguments);\n\n if (sourceMessage && sourceMessage instanceof RegExp) {\n delete this._patternInternalMessages[sourceMessage];\n var noPatternInternalMessages = ! Object.keys(this._patternInternalMessages).length;\n if (noPatternInternalMessages) {\n this._catchAllSubscribed = false;\n return /.*/;\n }\n }\n\n return sourceMessage;\n}\n\n\n/**\n * MessengerAPI instance method\n * Augments MessengerAPI method by returning messages subscribed with regexp\n * This method is used by `MessageSource` to dispatch source message on the `Mesenger`.\n *\n * @param {String|RegExp} sourceMessage source message\n * @return {Array[String]}\n */\nfunction getInternalMessages(sourceMessage) {\n var internalMessages = MessengerAPI.prototype.getInternalMessages.apply(this, arguments);\n\n // add internal messages for regexp source subscriptions\n if (typeof sourceMessage == 'string') {\n internalMessages = internalMessages || [];\n var internalMessagesHash = _.object(internalMessages, true);\n\n _.eachKey(this._patternInternalMessages, function(patternMessages) {\n var sourcePattern = patternMessages.pattern;\n\n if (sourcePattern.test(sourceMessage))\n patternMessages.forEach(function(message) {\n if (internalMessagesHash[message]) return;\n internalMessages.push(message);\n internalMessagesHash[message] = true;\n });\n });\n } \n\n return internalMessages;\n}\n", "'use strict';\n\nvar Mixin = require('../abstract/mixin')\n , MessengerAPI = require('./m_api')\n , logger = require('../util/logger')\n , toBeImplemented = require('../util/error').toBeImplemented\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match;\n\n\n/**\n * `milo.classes.MessageSource`\n * An abstract class (subclass of [Mixin](../abstract/mixin.js.html)) for connecting [Messenger](./index.js.html) to external sources of messages (like DOM events) and defining higher level messages.\n * An instance of MessageSource can either be passed to Messenger constructor or later using `_setMessageSource` method of Messenger. Once set, MessageSource of Messenger cannot be changed.\n */\nvar MessageSource = _.createSubclass(Mixin, 'MessageSource', true);\n\nmodule.exports = MessageSource;\n\n\n/**\n * ####MessageSource instance methods####\n *\n * - [init](#init) - initializes messageSource - called by Mixin superclass\n * - [setMessenger](#setMessenger) - connects Messenger to MessageSource, is called from `init` or `_setMessageSource` methods of [Messenger](./index.js.html).\n * - [onSubscriberAdded](#onSubscriberAdded) - called by Messenger to notify when the first subscriber for an internal message was added, so MessageSource can subscribe to source\n * - [onSubscriberRemoved](#onSubscriberRemoved) - called by Messenger to notify when the last subscriber for an internal message was removed, so MessageSource can unsubscribe from source\n * - [dispatchMessage](#dispatchMessage) - dispatches source message. MessageSource subclass should implement mechanism when on actual source message this method is called.\n *\n * Methods below should be implemented in subclass:\n *\n * - [trigger](#trigger) - triggers messages on the source (an optional method)\n * - [addSourceSubscriber](#addSourceSubscriber) - adds listener/subscriber to external message\n * - [removeSourceSubscriber](#removeSourceSubscriber) - removes listener/subscriber from external message\n */\n_.extendProto(MessageSource, {\n init: init,\n destroy: MessageSource$destroy,\n setMessenger: setMessenger,\n onSubscriberAdded: onSubscriberAdded,\n onSubscriberRemoved: onSubscriberRemoved, \n dispatchMessage: dispatchMessage,\n postMessage: postMessage,\n _prepareMessengerAPI: _prepareMessengerAPI,\n\n // Methods below must be implemented in subclass\n trigger: toBeImplemented,\n addSourceSubscriber: toBeImplemented,\n removeSourceSubscriber: toBeImplemented\n});\n\n\n/**\n * MessageSource instance method.\n * Called by Mixin constructor.\n * MessageSource constructor should be passed the same parameters as this method signature.\n * If an instance of [MessengerAPI](./m_api.js.html) is passed as the third parameter, it extends MessageSource functionality to allow it to define new messages, to filter messages based on their data and to change message data. See [MessengerAPI](./m_api.js.html).\n *\n * @param {Object} hostObject Optional object that stores the MessageSource on one of its properties. It is used to proxy methods of MessageSource.\n * @param {Object[String]} proxyMethods Optional map of method names; key - proxy method name, value - MessageSource's method name.\n * @param {MessengerAPI} messengerAPI Optional instance of MessengerAPI.\n */\nfunction init(hostObject, proxyMethods, messengerAPI) {\n this._prepareMessengerAPI(messengerAPI);\n}\n\n\n/**\n * Destroys message source\n */\nfunction MessageSource$destroy() {\n if (this.messengerAPI)\n this.messengerAPI.destroy();\n}\n\n\n/**\n * MessageSource instance method.\n * Sets reference to Messenger instance.\n *\n * @param {Messenger} messenger reference to Messenger instance linked to this MessageSource\n */\nfunction setMessenger(messenger) {\n _.defineProperty(this, 'messenger', messenger);\n}\n\n\n/**\n * MessageSource instance method.\n * Prepares [MessengerAPI](./m_api.js.html) passed to constructor by proxying its methods to itself or if MessengerAPI wasn't passed defines two methods to avoid checking their availability every time the message is dispatched.\n *\n * @private\n * @param {MessengerAPI} messengerAPI Optional instance of MessengerAPI\n */\nfunction _prepareMessengerAPI(messengerAPI) {\n check(messengerAPI, Match.Optional(MessengerAPI));\n\n if (! messengerAPI)\n messengerAPI = new MessengerAPI;\n\n _.defineProperty(this, 'messengerAPI', messengerAPI);\n}\n\n\n/**\n * MessageSource instance method.\n * Subscribes to external source using `addSourceSubscriber` method that should be implemented in subclass.\n * This method is called by [Messenger](./index.js.html) when the first subscriber to the `message` is added.\n * Delegates to supplied or default [MessengerAPI](./m_api.js.html) for translation of `message` to `sourceMessage`. `MessageAPI.prototype.addInternalMessage` will return undefined if this `sourceMessage` was already subscribed to to prevent duplicate subscription.\n *\n * @param {String} message internal Messenger message that has to be subscribed to at the external source of messages.\n */\nfunction onSubscriberAdded(message) {\n var newSourceMessage = this.messengerAPI.addInternalMessage(message);\n if (typeof newSourceMessage != 'undefined')\n this.addSourceSubscriber(newSourceMessage);\n}\n\n\n/**\n * MessageSource instance method.\n * Unsubscribes from external source using `removeSourceSubscriber` method that should be implemented in subclass.\n * This method is called by [Messenger](./index.js.html) when the last subscriber to the `message` is removed.\n * Delegates to supplied or default [MessengerAPI](./m_api.js.html) for translation of `message` to `sourceMessage`. `MessageAPI.prototype.removeInternalMessage` will return undefined if this `sourceMessage` was not yet subscribed to to prevent unsubscription without previous subscription.\n *\n * @param {String} message internal Messenger message that has to be unsubscribed from at the external source of messages.\n */\nfunction onSubscriberRemoved(message) {\n var removedSourceMessage = this.messengerAPI.removeInternalMessage(message);\n if (typeof removedSourceMessage != 'undefined')\n this.removeSourceSubscriber(removedSourceMessage);\n}\n\n\n/**\n * MessageSource instance method.\n * Dispatches sourceMessage to Messenger.\n * Mechanism that calls this method when the source message is received should be implemented by subclass (see [DOMEventsSource](../components/msg_src/dom_events.js.html) for example).\n * Delegates to supplied or default [MessengerAPI](./m_api.js.html) to create internal message data (`createInternalData`) and to filter the message based on its data and/or message (`filterSourceMessage`).\n * Base MessengerAPI class implements these two methods in a trivial way (`createInternalData` simply returns external data, `filterSourceMessage` returns `true`), they are meant to be implemented by subclass.\n *\n * @param {String} sourceMessage source message received from external source\n * @param {Object} sourceData data received from external source\n */\nfunction dispatchMessage(sourceMessage, sourceData) {\n var api = this.messengerAPI\n , internalMessages = api.getInternalMessages(sourceMessage);\n\n if (internalMessages) \n internalMessages.forEach(function (message) {\n var internalData = api.createInternalData(sourceMessage, message, sourceData);\n\n var shouldDispatch = api.filterSourceMessage(sourceMessage, message, internalData);\n if (shouldDispatch) \n this.postMessage(message, internalData); \n \n }, this);\n}\n\n\n/**\n * Posts message on the messenger. This method is separated so specific message sources can make message dispatch synchronous by using `postMessageSync`\n * \n * @param {String} message\n * @param {Object} data\n */\nfunction postMessage(message, data) {\n this.messenger.postMessage(message, data);\n}\n", "'use strict';\n\n\nvar MessageSource = require('./m_source')\n , _ = require('mol-proto')\n , check = require('../util/check');\n\n\n/**\n * Subclass of MessageSource that allows to connect Messenger to another Messenger using it as external source.\n */\nvar MessengerMessageSource = _.createSubclass(MessageSource, 'MessengerMessageSource');\n\nmodule.exports = MessengerMessageSource;\n\n\n/**\n * ####MessengerMessageSource instance methods####\n */\n_.extendProto(MessengerMessageSource, {\n init: init,\n addSourceSubscriber: addSourceSubscriber,\n removeSourceSubscriber: removeSourceSubscriber,\n postMessage: MessengerMessageSource$postMessage\n});\n\n/**\n * Initializes MessengerMessageSource\n * Defines one parameter in addition to [MessageSource](./m_source.js.html) parameters\n *\n * @param {Messenger} sourceMessenger messenger this message source connects to\n */\nfunction init(hostObject, proxyMethods, messengerAPI, sourceMessenger) {\n MessageSource.prototype.init.apply(this, arguments);\n this.sourceMessenger = sourceMessenger;\n}\n\n\n/**\n * Subscribes to source message. See [MessageSource](./m_source.js.html) docs.\n *\n * @param {String|Regex} sourceMessage source message to subscribe to\n */\nfunction addSourceSubscriber(sourceMessage) {\n this.sourceMessenger.onSync(sourceMessage, { context: this, subscriber: this.dispatchMessage });\n}\n\n\n/**\n * Unsubscribes from source message. See [MessageSource](./m_source.js.html) docs.\n *\n * @param {String|Regex} sourceMessage source message to unsubscribe from\n */\nfunction removeSourceSubscriber(sourceMessage) {\n this.sourceMessenger.off(sourceMessage, { context: this, subscriber: this.dispatchMessage });\n}\n\n\n/**\n * Overrides defalut message source to dispatch messages synchronously\n * \n * @param {String} message\n * @param {Object} data\n */\nfunction MessengerMessageSource$postMessage(message, data) {\n this.messenger.postMessageSync(message, data);\n}\n", - "'use strict';\n\nvar _ = require('mol-proto');\n\n\n// register included facets\nrequire('./use_facets');\n\n// register included components\nrequire('./use_components');\n\n\n/**\n * `milo`\n *\n * A minimalist browser framework that binds DOM elements to JS components and components to models.\n *\n * `milo` is available as global object in the browser.\n * At the moment it is not possiible to require it with browserify to have it bundled with the app because of the way [brfs](https://github.com/substack/brfs) browserify plugin is implemented.\n * It is possible though to require `milo` with node to use universal parts of the framework (abstract classes, Messenger, Model, etc.):\n * ```\n * var milo = require('mol-milo');\n * ```\n * \n * `milo` itself is a function that in the browser can be used to delay execution until DOM is ready.\n */\nfunction milo(func) {\n milo.util.domReady(func);\n}\n\n\n/**\n * ####Milo packages####\n *\n * - [loader](./loader.js.html) - loading subviews into page\n * - [binder](./binder.js.html) - components instantiation and binding of DOM elements to them\n * - [minder](./minder.js.html) - data reactivity, one or two way, shallow or deep, as you like it\n * - [mail](./mail/index.js.html) - applicaiton level messenger, also connects to messages from other windows dispatched with `window.postMessage`.\n * - [config](./config.js.html) - milo configuration\n * - [util](./util/index.js.html) - logger, request, dom, check, error, etc.\n * - [classes](./classes.js.html) - abstract and base classes\n * - [attributes](./attributes/index.js.html) - classes that wrap DOM elements attributes recognized by milo\n * - [ComponentFacet](./components/c_facet.js.html) - base class of Component facet\n * - [Component](./components/c_class.js.html) - base Component class\n * - [Messenger](./messenger/index.js.html) - generic Messenger used in most other milo classes, can be mixed into app classes too.\n * - [Model](./model/index.js.html) - Model class that emits messages on changes to any depth without timer based watching\n * - [registry](./registry.js.html) - registries of fasets and components classes\n */\n_.extend(milo, {\n loader: require('./loader'),\n binder: require('./binder'),\n minder: require('./minder'),\n mail: require('./services/mail'),\n window: require('./services/window'),\n config: require('./config'),\n util: require('./util'),\n classes: require('./classes'),\n attributes: require('./attributes'),\n ComponentFacet: require('./components/c_facet'),\n Component: require('./components/c_class'),\n Messenger: require('./messenger'),\n Model: require('./model'),\n Command: require('./command'),\n registry: require('./registry'),\n milo_version: '0.1.4',\n createComponentClass: require('./util/create_component_class'),\n destroy: destroy\n});\n\n\n// export for node/browserify\nif (typeof module == 'object' && module.exports) \n module.exports = milo;\n\n// global milo for browser\nif (typeof window == 'object') {\n window.milo = milo;\n milo.mail.trigger('miloready');\n}\n\n\nfunction destroy() {\n milo.mail.destroy();\n milo.window.destroy();\n milo.minder.destroy();\n milo.util.destroy();\n}\n", - "'use strict';\n\nvar Connector = require('./model/connector')\n , Messenger = require('./messenger')\n , _ = require('mol-proto')\n , logger = require('./util/logger');\n\n\nmodule.exports = minder;\n\n\n/**\n * This function creates one or many Connector objects that\n * create live reactive connection between objects implementing\n * dataSource interface:\n * Objects should emit messages when any part of their data changes,\n * methods `on` and `off` should be implemented to subscribe/unsubscribe\n * to change notification messages, methods `set` and `get` should be implemented to get/set data\n * on path objects, pointing to particular parts of the object, method `path`\n * should return path object for a given path string (see path utils for path string syntax).\n * Both Model and Data facet are such data sources, they can be linked by Connector object.\n *\n * @param {Object} ds1 the first data source. Instead of the first data source an array can be passed with arrays of Connection objects parameters in each array element.\n * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @param {Object} ds2 the second data source\n * @param {Object} options not implemented yet\n */\nfunction minder(ds1, mode, ds2, options) {\n if (Array.isArray(ds1)) {\n var connDescriptions = ds1;\n var connectors = connDescriptions.map(function(descr) {\n return new Connector(descr[0], descr[1], descr[2], descr[3]);\n });\n connectors.forEach(_addConnector);\n return connectors;\n } else {\n var cnct = new Connector(ds1, mode, ds2, options);\n _addConnector(cnct);\n return cnct;\n }\n}\n\n\n/**\n * messenger of minder where it emits events related to all connectors\n * @type {Messenger}\n */\nvar _messenger = new Messenger(minder, Messenger.defaultMethods);\n\n\nvar _connectors = []\n , _receivedMessages = []\n , _isPropagating = false;\n\n\n_.extend(minder, {\n getConnectors: minder_getConnectors,\n getExpandedConnections: minder_getExpandedConnections,\n isPropagating: minder_isPropagating,\n whenPropagationCompleted: minder_whenPropagationCompleted,\n destroyConnector: minder_destroyConnector,\n destroy: minder_destroy\n});\n\n\nfunction _addConnector(cnct) {\n cnct.___minder_id = _connectors.push(cnct) - 1;\n cnct.on(/.*/, onConnectorMessage);\n minder.postMessage('added', { connector: cnct });\n minder.postMessage('turnedon', { connector: cnct });\n}\n\n\nfunction onConnectorMessage(msg, data) {\n var data = data ? _.clone(data) : {};\n _.extend(data, {\n id: this.___minder_id,\n connector: this\n });\n minder.postMessage(msg, data);\n if (! _receivedMessages.length && ! _isPropagating) {\n _.defer(_idleCheck);\n _isPropagating = true;\n }\n\n _receivedMessages.push({ msg: msg, data: data });\n}\n\n\nfunction _idleCheck() {\n if (_receivedMessages.length) {\n _receivedMessages.length = 0;\n _.defer(_idleCheck);\n minder.postMessage('propagationticked');\n } else {\n _isPropagating = false;\n minder.postMessage('propagationcompleted');\n }\n}\n\n\nfunction minder_isPropagating() {\n return _isPropagating;\n}\n\n\nfunction minder_whenPropagationCompleted(callback) {\n if (_isPropagating)\n minder.once('propagationcompleted', executeCallback);\n else\n _.defer(executeCallback);\n\n function executeCallback() {\n if (_isPropagating)\n minder.once('propagationcompleted', executeCallback);\n else\n callback();\n }\n}\n\n\nfunction minder_getConnectors(onOff) {\n if (typeof onOff == 'undefined')\n return _connectors;\n\n return _connectors.filter(function(cnct) {\n return cnct.isOn === onOff;\n });\n}\n\n\nfunction minder_destroyConnector(cnct) {\n cnct.destroy();\n var index = _connectors.indexOf(cnct);\n if (index >= 0)\n delete _connectors[index];\n else\n logger.warn('minder: connector destroyed that is not registered in minder');\n}\n\n\nfunction minder_getExpandedConnections(onOff, searchStr) {\n var connectors = minder.getConnectors(onOff);\n var connections = connectors.map(function(cnct) {\n var connection = {\n leftSource: _getExpandedSource(cnct.ds1),\n rightSource: _getExpandedSource(cnct.ds2),\n mode: cnct.mode,\n isOn: cnct.isOn\n };\n \n if (cnct.options)\n connection.options = cnct.options;\n\n return connection;\n });\n\n if (searchStr)\n connections = connections.filter(function(cnctn) {\n return _sourceMatchesString(cnctn.leftSource, searchStr)\n || _sourceMatchesString(cnctn.rightSource, searchStr);\n });\n\n return connections;\n}\n\n\nfunction _getExpandedSource(ds) {\n var source = [];\n if (typeof ds == 'function') {\n if (ds._model && ds._accessPath) {\n source.unshift(ds._accessPath);\n ds = ds._model;\n }\n\n source.unshift(ds);\n ds = ds._hostObject;\n }\n\n if (typeof ds == 'object') {\n source.unshift(ds);\n\n if (ds.owner)\n source.unshift(ds.owner);\n }\n\n return source;\n}\n\n\nfunction _sourceMatchesString(source, matchStr) {\n return source.some(function(srcNode) {\n var className = srcNode.constructor && srcNode.constructor.name;\n return _stringMatch(className, matchStr)\n || _stringMatch(srcNode.name, matchStr)\n || _stringMatch(srcNode, matchStr);\n });\n}\n\n\nfunction _stringMatch(str, substr) {\n return str && typeof str == 'string' && str.indexOf(substr) >= 0;\n}\n\n\nfunction minder_destroy() {\n _connectors.forEach(function(cnct) {\n destroyDS(cnct.ds1);\n destroyDS(cnct.ds2);\n cnct.destroy();\n });\n _messenger.destroy();\n minder._destroyed = true;\n\n function destroyDS(ds) {\n if (ds && !ds._destroyed) ds.destroy();\n }\n}\n", + "'use strict';\n\nvar core = require('milo-core');\nvar _ = require('mol-proto');\n\n\n// register included facets\nrequire('./use_facets');\n\n// register included components\nrequire('./use_components');\n\n\n/**\n * `milo`\n *\n * A minimalist browser framework that binds DOM elements to JS components and components to models.\n *\n * `milo` is available as global object in the browser.\n * At the moment it is not possiible to require it with browserify to have it bundled with the app because of the way [brfs](https://github.com/substack/brfs) browserify plugin is implemented.\n * It is possible though to require `milo` with node to use universal parts of the framework (abstract classes, Messenger, Model, etc.):\n * ```\n * var milo = require('mol-milo');\n * ```\n * \n * `milo` itself is a function that in the browser can be used to delay execution until DOM is ready.\n */\nfunction milo(func) {\n milo.util.domReady(func);\n}\n\n\n/**\n * ####Milo packages####\n *\n * - [loader](./loader.js.html) - loading subviews into page\n * - [binder](./binder.js.html) - components instantiation and binding of DOM elements to them\n * - [minder](./minder.js.html) - data reactivity, one or two way, shallow or deep, as you like it\n * - [mail](./mail/index.js.html) - applicaiton level messenger, also connects to messages from other windows dispatched with `window.postMessage`.\n * - [config](./config.js.html) - milo configuration\n * - [util](./util/index.js.html) - logger, request, dom, check, error, etc.\n * - [classes](./classes.js.html) - abstract and base classes\n * - [attributes](./attributes/index.js.html) - classes that wrap DOM elements attributes recognized by milo\n * - [ComponentFacet](./components/c_facet.js.html) - base class of Component facet\n * - [Component](./components/c_class.js.html) - base Component class\n * - [Messenger](./messenger/index.js.html) - generic Messenger used in most other milo classes, can be mixed into app classes too.\n * - [Model](./model/index.js.html) - Model class that emits messages on changes to any depth without timer based watching\n * - [registry](./registry.js.html) - registries of fasets and components classes\n */\n_.extend(milo, {\n Messenger: core.Messenger,\n Model: core.Model,\n minder: core.minder,\n loader: require('./loader'),\n binder: require('./binder'),\n mail: require('./services/mail'),\n window: require('./services/window'),\n config: require('./config'),\n util: require('./util'),\n classes: require('./classes'),\n attributes: require('./attributes'),\n ComponentFacet: require('./components/c_facet'),\n Component: require('./components/c_class'),\n Command: require('./command'),\n registry: require('./registry'),\n milo_version: '0.1.4',\n createComponentClass: require('./util/create_component_class'),\n destroy: destroy\n});\n\n\n// export for node/browserify\nif (typeof module == 'object' && module.exports) \n module.exports = milo;\n\n// global milo for browser\nif (typeof window == 'object') {\n window.milo = milo;\n milo.mail.trigger('miloready');\n}\n\n\nfunction destroy() {\n milo.mail.destroy();\n milo.window.destroy();\n milo.minder.destroy();\n milo.util.destroy();\n}\n", "'use strict';\n\n\nvar facetsRegistry = require('../components/c_facets/cf_registry')\n , logger = require('../util/logger')\n , config = require('../config')\n , pathUtils = require('./path_utils')\n , _ = require('mol-proto');\n\n/**\n * Utility function to process \"changedata\" messages emitted by Connector object.\n */\nmodule.exports = changeDataHandler;\n\n\n_.extend(changeDataHandler, {\n setTransactionFlag: setTransactionFlag,\n getTransactionFlag: getTransactionFlag,\n passTransactionFlag: passTransactionFlag,\n postTransactionFinished: postTransactionFinished\n});\n\n\n/**\n * Change data uses hidden property on accessor methods to pass flag that the accessor is executed as a part of change transaction.\n * Accessor methods are supposed to store this flag in a local variable and to clear it (because another accessor can be executed in or out of transaction) using `getTransactionFlag`\n *\n * @private\n * @param {Function} func accessor method reference\n * @param {Boolean} flag a flag to be set\n */\nfunction setTransactionFlag(func, flag) {\n _.defineProperty(func, '__inChangeTransaction', flag, _.CONF | _.WRIT);\n}\n\n\n/**\n * Retrieves and clears transaction flag from accessor method\n *\n * @private\n * @param {Function} func accessor method reference\n * @return {Boolean}\n */\nfunction getTransactionFlag(func) {\n var inTransaction = func.__inChangeTransaction;\n delete func.__inChangeTransaction;\n return inTransaction;\n}\n\n\nfunction passTransactionFlag(fromFunc, toFunc) {\n var inTransaction = getTransactionFlag(fromFunc);\n setTransactionFlag(toFunc, inTransaction);\n return inTransaction;\n}\n\n\n/**\n * Posts message on this to indicate the end of transaction unless `inChangeTransaction` is `true`.\n */\nfunction postTransactionFinished() {\n this.postMessageSync('datachanges', { transaction: false, changes: [] });\n}\n\n\n/**\n * subscriber to \"changedata\" event emitted by [Connector](./connector.js.html) object to enable reactive connections\n * Used by Data facet, Model and ModelPath. Can be used by any object that implements get/set/del/splice api and sets data deeply to the whole tree.\n * Object should call `changeDataHandler.initialize.call(this)` in its constructor.\n * TODO: optimize messages list to avoid setting duplicate values down the tree\n *\n * @param {String} msg should be \"changedata\" here\n * @param {Object} data batch of data change desciption objects\n * @param {Function} callback callback to call before and after the data is processed\n */\nfunction changeDataHandler(message, data, callback) {\n processChanges.call(this, data.changes, callback);\n}\n\n\n// map of message types to methods\nvar CHANGE_TYPE_TO_METHOD_MAP = {\n 'added': 'set',\n 'changed': 'set',\n 'deleted': 'del',\n 'removed': 'del'\n};\n\n\n/**\n * Processes queued \"changedata\" messages.\n * Posts \"changestarted\" and \"changecompleted\" messages and calls callback\n *\n * @param {[Function]} callback optional callback that is called with `(null, false)` parameters before change processing starts and `(null, true)` after it's finished.\n */\nfunction processChanges(transaction, callback) {\n notify.call(this, callback, false);\n processTransaction.call(this,\n prepareTransaction(\n validateTransaction(transaction)));\n notify.call(this, callback, true);\n}\n\n\nfunction notify(callback, changeFinished) {\n callback && callback(null, changeFinished);\n this.postMessage(changeFinished ? 'changecompleted' : 'changestarted');\n}\n\n\n/**\n * Checks that all messages from the transaction come from the same source.\n * Hack: reverses the transaction if it comes from the Data facet\n * Returns the reference to the transaction (for chaining)\n * \n * @param {Array} transaction transaction of data changes\n * @return {Array} \n */\nfunction validateTransaction(transaction) {\n var source = transaction[0].source\n , sameSource = true;\n\n if (transaction.length > 1) {\n for (var i = 1, len = transaction.length; i < len; i++)\n if (transaction[i].source != source) {\n logger.error('changedata: changes from different sources in the same transaction, sources:', transaction[i].source.name, source.name);\n sameSource = false;\n source = transaction[i].source;\n }\n }\n\n return transaction;\n}\n\n\nfunction prepareTransaction(transaction) {\n var todo = []\n , pathsToSplice = []\n , pathsToChange = []\n , hadSplice\n , exitLoop = {};\n\n\n try { transaction.forEach(checkChange); }\n catch (e) { if (e != exitLoop) throw e; }\n\n return todo;\n\n\n function checkChange(data) {\n (data.type == 'splice' ? checkSplice : checkMethod)(data);\n }\n\n\n function checkSplice(data) {\n var parsedPath = pathUtils.parseAccessPath(data.path);\n var parentPathChanged = pathsToChange.some(function(parentPath) {\n if (parsedPath.length < parentPath.length) return;\n return _pathIsParentOf(parentPath, parsedPath);\n });\n\n if (parentPathChanged) return;\n\n todo.push(data);\n\n if (! config.debug) throw exitLoop;\n pathsToSplice.push(parsedPath);\n hadSplice = true;\n }\n\n\n function checkMethod(data) {\n var parsedPath = pathUtils.parseAccessPath(data.path);\n var parentPathSpliced = pathsToSplice && pathsToSplice.some(function(parentPath) {\n if (parsedPath.length <= parentPath.length\n || parsedPath[parentPath.length].syntax != 'array') return;\n return _pathIsParentOf(parentPath, parsedPath);\n });\n\n if (parentPathSpliced) return;\n if (hadSplice) logger.error('changedata: child change is executed after splice; probably data source did not emit message with data.type==\"finished\"');\n\n var parentPathChanged = pathsToChange.some(function(parentPath) {\n if (parsedPath.length <= parentPath.length) return;\n return _pathIsParentOf(parentPath, parsedPath);\n });\n\n if (parentPathChanged) return;\n\n pathsToChange.push(parsedPath);\n\n todo.push(data);\n }\n\n\n function _pathIsParentOf(parentPath, childPath) {\n return parentPath.every(function(pathNode, index) {\n return pathNode.property == childPath[index].property;\n });\n }\n}\n\n\nfunction processTransaction(transaction) {\n transaction.forEach(processChange, this);\n postTransactionFinished.call(this, false);\n\n function processChange(data) {\n var modelPath = this.path(data.path, data.type != 'removed' && data.type != 'deleted');\n if (! modelPath) return;\n (data.type == 'splice' ? executeSplice : executeMethod)(modelPath, data);\n }\n}\n\n\nfunction executeSplice(modelPath, data) {\n var index = data.index\n , howMany = data.removed.length\n , spliceArgs = [index, howMany];\n\n spliceArgs = spliceArgs.concat(data.newValue.slice(index, index + data.addedCount));\n setTransactionFlag(modelPath.splice, true);\n modelPath.splice.apply(modelPath, spliceArgs);\n}\n\n\nfunction executeMethod(modelPath, data) {\n var methodName = CHANGE_TYPE_TO_METHOD_MAP[data.type];\n if (methodName) {\n setTransactionFlag(modelPath[methodName], true);\n modelPath[methodName](data.newValue);\n } else\n logger.error('unknown data change type');\n}\n", - "'use strict';\n\nvar ConnectorError = require('../util/error').Connector\n , Messenger = require('../messenger')\n , pathUtils = require('./path_utils')\n , _ = require('mol-proto')\n , logger = require('../util/logger');\n\n\nmodule.exports = Connector;\n\n\nvar modePattern = /^(\\<*)\\-+(\\>*)$/;\n\n\n/**\n * Connector\n * Class that creates connector object for data connection between\n * two data-sources\n * Data-sources should implement the following API:\n * get() - get value from datasource or its path\n * set(value) - set value to datasource or to its path\n * on(path, subscriber) - subscription to data changes with \"*\" support\n * off(path, subscriber)\n * path(accessPath) - to return the object that gives reference to some part of datasource\n * and complies with that api too.\n *\n * ####Events####\n *\n * - 'turnedon' - connector was turned on\n * - 'turnedoff' - connector was turned off\n * - 'changestarted' - change on connected datasource is started\n * - 'changecompleted' - change on connected datasource is completed\n * - 'destroyed' - connector was destroyed\n * \n * @param {Object} ds1 the first data source.\n * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @param {Object} ds2 the second data source\n * @param {Object} options not implemented yet\n * @return {Connector} when called with `new`, creates a Connector object.\n */\nfunction Connector(ds1, mode, ds2, options) {\n setupMode.call(this, mode);\n\n _.extend(this, {\n ds1: ds1,\n ds2: ds2,\n isOn: false,\n _changesQueue1: [],\n _changesQueue2: [],\n _messenger: new Messenger(this, Messenger.defaultMethods)\n });\n\n if (options) {\n this.options = options;\n\n var pathTranslation = options.pathTranslation;\n if (pathTranslation) {\n pathTranslation = _.clone(pathTranslation);\n var patternTranslation = getPatternTranslations(pathTranslation);\n _.extend(this, {\n pathTranslation1: reverseTranslationRules(pathTranslation),\n pathTranslation2: pathTranslation,\n patternTranslation1: reversePatternTranslationRules(patternTranslation),\n patternTranslation2: patternTranslation\n });\n }\n\n var dataTranslation = options.dataTranslation;\n if (dataTranslation) {\n _.extend(this, {\n dataTranslation1: dataTranslation['<-'],\n dataTranslation2: dataTranslation['->']\n });\n }\n\n var dataValidation = options.dataValidation;\n if (dataValidation) {\n _.extend(this, {\n dataValidation1: dataValidation['<-'],\n dataValidation2: dataValidation['->']\n });\n }\n }\n\n this.turnOn();\n}\n\n\nfunction setupMode(mode){\n var parsedMode = mode.match(modePattern);\n\n if (! parsedMode)\n modeParseError();\n\n var depth1 = parsedMode[1].length\n , depth2 = parsedMode[2].length;\n\n if (depth1 && depth2 && depth1 != depth2)\n modeParseError();\n\n if (! depth1 && ! depth2)\n modeParseError();\n\n _.extend(this, {\n mode: mode,\n depth1: depth1,\n depth2: depth2,\n });\n\n function modeParseError() {\n throw new ConnectorError('invalid Connector mode: ' + mode);\n }\n}\n\n\n_.extendProto(Connector, {\n turnOn: Connector$turnOn,\n turnOff: Connector$turnOff,\n destroy: Connector$destroy,\n changeMode: Connector$changeMode,\n deferChangeMode: Connector$deferChangeMode\n});\n\n/**\n * Function change the mode of the connection\n *\n * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @return {Object[String]}\n */\nfunction Connector$changeMode(mode) {\n this.turnOff();\n setupMode.call(this, mode);\n this.turnOn();\n return this;\n}\n\n\n/**\n * Function change the mode of the connection\n *\n * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @return {Object[String]}\n */\nfunction Connector$deferChangeMode(mode) {\n _.deferMethod(this, 'changeMode', mode);\n return this;\n}\n\n\n/**\n * Function that reverses translation rules for paths of connected odata sources\n *\n * @param {Object[String]} rules map of paths defining the translation rules\n * @return {Object[String]}\n */\nfunction reverseTranslationRules(rules) {\n var reverseRules = {};\n _.eachKey(rules, function(path2_value, path1_key) {\n reverseRules[path2_value] = path1_key;\n });\n return reverseRules;\n}\n\n\nfunction getPatternTranslations(pathTranslation) {\n var patternTranslation = [];\n _.eachKey(pathTranslation, function(path2_value, path1_key) {\n var starIndex1 = path1_key.indexOf('*')\n , starIndex2 = path2_value.indexOf('*');\n if (starIndex1 >= 0 && starIndex2 >= 0) { // pattern translation\n if (path1_key.slice(starIndex1) != path2_value.slice(starIndex2))\n _throwInvalidTranslation(path1_key, path2_value);\n delete pathTranslation[path1_key]; \n\n patternTranslation.push({\n fromPattern: pathUtils.createRegexPath(path1_key),\n fromStaticPath: _getStaticPath(path1_key, starIndex1),\n toPattern: pathUtils.createRegexPath(path2_value),\n toStaticPath: _getStaticPath(path2_value, starIndex2)\n });\n } else if (starIndex1 >= 0 || starIndex2 >= 0) // pattern only on one side of translation\n _throwInvalidTranslation(path1_key, path2_value);\n });\n\n return patternTranslation;\n\n\n function _throwInvalidTranslation(path1, path2) {\n throw new ConnectorError('Invalid pattern translation: ' + path1 + ', ' + path2);\n }\n\n\n function _getStaticPath(path, starIndex) {\n return path.replace(/[\\.\\[]?\\*.*$/, '');\n }\n}\n\n\nfunction reversePatternTranslationRules(patternTranslation) {\n return patternTranslation.map(function(pt) {\n return {\n fromPattern: pt.toPattern,\n fromStaticPath: pt.toStaticPath,\n toPattern: pt.fromPattern,\n toStaticPath: pt.fromStaticPath\n };\n });\n}\n\n\n/**\n * turnOn\n * Method of Connector that enables connection (if it was previously disabled)\n */\nfunction Connector$turnOn() {\n if (this.isOn)\n return logger.warn('data sources are already connected');\n\n var subscriptionPath = this._subscriptionPath =\n new Array(this.depth1 || this.depth2).join('*');\n\n var subscriptionPattern = pathUtils.createRegexPath(subscriptionPath);\n\n var self = this;\n if (this.depth1)\n this._link1 = linkDataSource('_link2', this.ds2, this.ds1, this._changesQueue1, this.pathTranslation1, this.patternTranslation1, this.dataTranslation1, this.dataValidation1);\n if (this.depth2)\n this._link2 = linkDataSource('_link1', this.ds1, this.ds2, this._changesQueue2, this.pathTranslation2, this.patternTranslation2, this.dataTranslation2, this.dataValidation2);\n\n this.isOn = true;\n this.postMessage('turnedon');\n\n\n function linkDataSource(reverseLink, fromDS, toDS, changesQueue, pathTranslation, patternTranslation, dataTranslation, dataValidation) {\n fromDS.onSync('datachanges', onData);\n return onData;\n\n function onData(message, batch) {\n var sendData = {\n changes: [],\n transaction: batch.transaction\n }\n\n batch.changes.forEach(function(change) {\n var sourcePath = change.path\n , targetPath = translatePath(sourcePath);\n\n if (typeof targetPath == 'undefined') return;\n\n var change = _.clone(change);\n _.extend(change, {\n source: fromDS,\n path: targetPath\n });\n\n translateData(sourcePath, change);\n validateData(sourcePath, change);\n });\n\n if (! changesQueue.length)\n _.defer(postChangeData);\n\n changesQueue.push(sendData);\n\n\n function translatePath(sourcePath) {\n if (pathTranslation) {\n var translatedPath = pathTranslation[sourcePath];\n if (translatedPath) return translatedPath;\n if (!patternTranslation.length) return;\n var pt = _.find(patternTranslation, function(pTranslation) {\n return pTranslation.fromPattern.test(sourcePath);\n });\n if (!pt) return;\n var translatedPath = sourcePath.replace(pt.fromStaticPath, pt.toStaticPath);\n } else if (! ((subscriptionPattern instanceof RegExp\n && subscriptionPattern.test(sourcePath))\n || subscriptionPattern == sourcePath)) return;\n\n return translatedPath || sourcePath;\n }\n\n\n function translateData(sourcePath, change) {\n if (dataTranslation) {\n var translate = dataTranslation[sourcePath];\n if (translate && typeof translate == 'function') {\n change.oldValue = translate(change.oldValue);\n change.newValue = translate(change.newValue);\n }\n }\n }\n\n \n function validateData(sourcePath, change) {\n propagateData(change);\n\n if (dataValidation) {\n var validators = dataValidation[sourcePath]\n , passedCount = 0\n , alreadyFailed = false;\n\n if (validators)\n validators.forEach(callValidator); \n }\n\n\n function callValidator(validator) {\n validator(change.newValue, function(err, response) {\n response.path = sourcePath;\n if (! alreadyFailed && (err || response.valid) && ++passedCount == validators.length) {\n fromDS.postMessage('validated', response);\n } else if (! response.valid) {\n alreadyFailed = true;\n fromDS.postMessage('validated', response);\n }\n });\n }\n }\n\n\n function propagateData(change) {\n sendData.changes.push(change);\n }\n\n\n function postChangeData() {\n // prevent endless loop of updates for 2-way connection\n if (self[reverseLink]) var callback = subscriptionSwitch;\n\n var transactions = mergeTransactions(changesQueue);\n changesQueue.length = 0;\n transactions.forEach(function(transaction) {\n // send data change instruction as message\n toDS.postMessageSync('changedata', { changes: transaction }, callback);\n });\n }\n\n\n function subscriptionSwitch(err, changeFinished) {\n if (err) return;\n var onOff = changeFinished ? 'onSync' : 'off';\n toDS[onOff]('datachanges', self[reverseLink]);\n\n var message = changeFinished ? 'changecompleted' : 'changestarted';\n self.postMessage(message, { source: fromDS, target: toDS });\n }\n\n\n function mergeTransactions(batches) {\n var transactions = []\n , currentTransaction;\n\n batches.forEach(function(batch) {\n if (! batch.transaction) currentTransaction = undefined;\n if (! batch.changes.length) return;\n\n if (batch.transaction) {\n if (currentTransaction)\n _.appendArray(currentTransaction, batch.changes);\n else {\n currentTransaction = _.clone(batch.changes);\n transactions.push(currentTransaction);\n }\n } else\n transactions.push(batch.changes);\n });\n\n return transactions;\n }\n }\n }\n}\n\n\n/**\n * turnOff\n * Method of Connector that disables connection (if it was previously enabled)\n */\nfunction Connector$turnOff() {\n if (! this.isOn)\n return logger.warn('data sources are already disconnected');\n\n var self = this;\n unlinkDataSource(this.ds1, '_link2', this.pathTranslation2);\n unlinkDataSource(this.ds2, '_link1', this.pathTranslation1);\n\n this.isOn = false;\n this.postMessage('turnedoff');\n\n\n function unlinkDataSource(fromDS, linkName, pathTranslation) {\n if (self[linkName]) {\n fromDS.off('datachanges', self[linkName]);\n delete self[linkName];\n }\n }\n}\n\n\n/**\n * Destroys connector object by turning it off and removing references to connected sources\n */\nfunction Connector$destroy() {\n this.turnOff();\n this.postMessage('destroyed');\n this._messenger.destroy();\n delete this.ds1;\n delete this.ds2;\n this._destroyed = true;\n}\n", "'use strict';\n\nvar ModelPath = require('./m_path')\n , synthesize = require('./synthesize')\n , pathUtils = require('./path_utils')\n , changeDataHandler = require('./change_data')\n , Messenger = require('../messenger')\n , MessengerMessageSource = require('../messenger/msngr_source')\n , ModelMsgAPI = require('./m_msg_api')\n , ModelError = require('../util/error').Model\n , Mixin = require('../abstract/mixin')\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match\n , logger = require('../util/logger')\n , jsonParse = require('../util/json_parse');\n\n\nmodule.exports = Model;\n\n\n/**\n * `milo.Model`\n * Model class instantiates objects that allow deep data access with __safe getters__ that return undefined (rather than throwing exception) when properties/items of unexisting objects/arrays are requested and __safe setters__ that create object trees when properties/items of unexisting objects/arrays are set and also post messages to allow subscription on changes and enable data reactivity.\n * Reactivity is implememnted via [Connector](./connector.js.html) that can be instantiated either directly or with more convenient interface of [milo.minder](../minder.js.html). At the moment model can be connected to [Data facet](../components/c_facets/Data.js.html) or to another model or [ModelPath](./m_path.js.html).\n * Model constructor returns objects that are functions at the same time; when called they return ModelPath objects that allow get/set access to any point in model data. See [ModelData](#ModelData) below.\n *\n * You can subscribe to model changes with `on` method by passing model access path in place of message, pattern or string with any number of stars to subscribe to a certain depth in model (e.g., `'***'` to subscribe to three levels).\n *\n * @constructor\n * @param {Object|Array} data optional initial array data. If it is planned to connect model to view it is usually better to instantiate an empty Model (`var m = new Model`), connect it to [Component](../components/c_class.js.html)'s [Data facet](../components/c_facets/Data.js.html) (e.g., `milo.minder(m, '<<->>', c.data);`) and then set the model with `m.set(data)` - the view will be automatically updated.\n * @param {Object} hostObject optional object that hosts model on one of its properties. Can be used when model itself is the context of the message subscriber and you need to travers to this object (although it is possible to set any context). Can also be used to proxy model's methods to the host like [Model facet](../components/c_facets/ModelFacet.js.html) is doing.\n * @param {Object} options pass { reactive: false } to use model without messaging when it is not needed - it makes it much faster\n * @return {Model}\n */\nfunction Model(data, hostObject, options) {\n // `model` will be returned by constructor instead of `this`. `model`\n // (`modelPath` function) should return a ModelPath object with \"synthesized\" methods\n // to get/set model properties, to subscribe to property changes, etc.\n // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below.\n var model = function modelPath(accessPath) { // , ... arguments that will be interpolated\n return Model$path.apply(model, arguments);\n };\n model.__proto__ = Model.prototype;\n\n model._hostObject = hostObject;\n model._options = options || {};\n\n if (model._options.reactive !== false) {\n model._prepareMessengers();\n // subscribe to \"changedata\" message to enable reactive connections\n model.onSync('changedata', changeDataHandler);\n }\n\n if (data) model._data = data;\n\n return model;\n}\n\nModel.prototype.__proto__ = Model.__proto__;\n\n\n/**\n * ####Model instance methods####\n *\n * - [path](#path) - returns ModelPath object that allows access to any point in Model\n * - [get](#Model$get) - get model data\n * - set - set model data, synthesized\n * - splice - splice model data (as array or pseudo-array), synthesized\n * - [len](./m_path.js.html#ModelPath$len) - returns length of array (or pseudo-array) in model in safe way, 0 if no length is set\n * - [push](./m_path.js.html#ModelPath$push) - add items to the end of array (or pseudo-array) in model\n * - [pop](./m_path.js.html#ModelPath$pop) - remove item from the end of array (or pseudo-array) in model\n * - [unshift](./m_path.js.html#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in model\n * - [shift](./m_path.js.html#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in model\n * - [proxyMessenger](#proxyMessenger) - proxy model's Messenger methods to host object\n * - [proxyMethods](#proxyMethods) - proxy model methods to host object\n */\n_.extendProto(Model, {\n path: Model$path,\n get: Model$get,\n proxyMessenger: proxyMessenger, // deprecated, should not be used\n proxyMethods: proxyMethods,\n _prepareMessengers: _prepareMessengers,\n _getHostObject: _getHostObject,\n destroy: Model$destroy\n});\n\n// set, del, splice are added to model\n_.extendProto(Model, synthesize.modelMethods);\n\n\n/**\n * - Path: ModelPath class as `milo.Model.Path`\n * - [registerWithDOMStorage](#Model$$registerWithDOMStorage)\n */\n_.extend(Model, {\n Path: ModelPath,\n registerWithDOMStorage: Model$$registerWithDOMStorage,\n useWith: Model$$useWith\n});\n\n\n/**\n * Expose Messenger methods on Facet prototype\n */\nvar MESSENGER_PROPERTY = '_messenger';\nMessenger.useWith(Model, MESSENGER_PROPERTY, Messenger.defaultMethods);\n\n\n/**\n * ModelPath methods added to Model prototype\n */\n['len', 'push', 'pop', 'unshift', 'shift'].forEach(function(methodName) {\n var method = ModelPath.prototype[methodName];\n _.defineProperty(Model.prototype, methodName, method);\n});\n\n\n/**\n * Model instance method.\n * Get model data.\n *\n * @return {Any}\n */\nfunction Model$get() {\n return this._data;\n}\n\n\n/**\n * Model instance method.\n * Returns ModelPath object that implements the same API as model but allows access to any point inside model as defined by `accessPath`.\n * See [ModelPath](./m_path.js.html) class for more information.\n *\n * @param {String} accessPath string that defines path to access model.\n * Path string consists of parts to define either property access (`\".name\"` to access property name) or array item access (`\"[1]\"` to access item with index 1).\n * Access path can contain as many parts as necessary (e.g. `\".list[0].name\"` to access property `name` in the first element of array stored in property `list`.\n * @param {List} arguments additional arguments of this method can be used to create interpolated paths.\n * E.g. `m.path(\"[$1].$2\", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m(\"[\" + id + \"].\" + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`.\n * @return {ModelPath}\n */\nfunction Model$path(accessPath) { // , ... arguments that will be interpolated\n if (! accessPath) return this;\n\n // \"null\" is context to pass to ModelPath, first parameter of bind\n // \"this\" (model) is added in front of all arguments\n _.splice(arguments, 0, 0, null, this);\n\n // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ...\n return new (Function.prototype.bind.apply(ModelPath, arguments));\n}\n\n\n/**\n * Model instance method.\n * Proxy model's Messenger methods to host object.\n *\n * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used.\n */\nfunction proxyMessenger(modelHostObject) {\n modelHostObject = modelHostObject || this._hostObject;\n Mixin.prototype._createProxyMethods.call(this[MESSENGER_PROPERTY], Messenger.defaultMethods, modelHostObject);\n}\n\n\nvar modelMethodsToProxy = ['path', 'get', 'set', 'del', 'splice', 'len', 'push', 'pop', 'unshift', 'shift'];\n\n\n/**\n * Expose model methods on\n * See same method in Mixin class for parameters meaning\n *\n * @param {Function} hostClass\n * @param {[type]} instanceKey\n * @param {[type]} mixinMethods optional\n */\nfunction Model$$useWith(hostClass, instanceKey, mixinMethods) {\n mixinMethods = mixinMethods || modelMethodsToProxy;\n Mixin.useWith.call(Model, hostClass, instanceKey, mixinMethods);\n}\n\n\n/**\n * Model instance method.\n * Proxy model methods to host object.\n *\n * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used.\n */\nfunction proxyMethods(modelHostObject) {\n modelHostObject = modelHostObject || this._hostObject;\n Mixin.prototype._createProxyMethods.call(this, modelMethodsToProxy, modelHostObject);\n}\n\n\n/**\n * Model instance method.\n * Create and connect internal and external model's messengers.\n * External messenger's methods are proxied on the model and they allows \"*\" subscriptions.\n */\nfunction _prepareMessengers() {\n // model will post all its changes on internal messenger\n var internalMessenger = new Messenger(this, undefined, undefined);\n\n // message source to connect internal messenger to external\n var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger);\n\n // external messenger to which all model users will subscribe,\n // that will allow \"*\" subscriptions and support \"changedata\" message api.\n var externalMessenger = new Messenger(this, undefined, internalMessengerSource);\n\n _.defineProperty(this, MESSENGER_PROPERTY, externalMessenger);\n _.defineProperty(this, '_internalMessenger', internalMessenger);\n}\n\n\nfunction _getHostObject() {\n return this._hostObject;\n}\n\n\nfunction Model$$registerWithDOMStorage() {\n var DOMStorage = require('../util/storage');\n DOMStorage.registerDataType('Model', Model_domStorageSerializer, Model_domStorageParser);\n DOMStorage.registerDataType('ModelPath', Model_domStorageSerializer, Model_domStorageParser, 'Model');\n}\n\n\nfunction Model_domStorageSerializer(value) {\n var data = value.get();\n return JSON.stringify(data);\n}\n\n\nfunction Model_domStorageParser(valueStr) {\n var data = jsonParse(valueStr);\n return new Model(data);\n}\n\n\nfunction Model$destroy() {\n this[MESSENGER_PROPERTY].destroy();\n this._internalMessenger.destroy();\n this._destroyed = true;\n}\n", "'use strict';\n\nvar MessengerRegexpAPI = require('../messenger/m_api_rx')\n , pathUtils = require('./path_utils')\n , _ = require('mol-proto');\n\n\n/**\n * Subclass of MessengerRegexpAPI that is used to translate messages of external messenger of Model to internal messenger of Model.\n */\nvar ModelMsgAPI = _.createSubclass(MessengerRegexpAPI, 'ModelMsgAPI');\n\nmodule.exports = ModelMsgAPI;\n\n\n/**\n * ####ModelMsgAPI instance methods####\n *\n * - [translateToSourceMessage](#translateToSourceMessage) - translates subscription paths with \"*\"s to regex, leaving other strings untouched\n */\n_.extendProto(ModelMsgAPI, {\n translateToSourceMessage: translateToSourceMessage,\n});\n\n\n/**\n * ModelMsgAPI instance method\n * Translates subscription paths with \"*\"s to regex, leaving other strings untouched.\n *\n * @param {String} accessPath relative access path to be translated\n * @return {RegExp|String}\n */\nfunction translateToSourceMessage(accessPath) {\n if (accessPath instanceof RegExp) return accessPath;\n\n return pathUtils.createRegexPath(accessPath);\n}\n", "'use strict';\n\nvar synthesize = require('./synthesize')\n , pathUtils = require('./path_utils')\n , changeDataHandler = require('./change_data')\n , Messenger = require('../messenger')\n , ModelPathMsgAPI = require('./path_msg_api')\n , MessengerMessageSource = require('../messenger/msngr_source')\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match;\n\n\nmodule.exports = ModelPath;\n\n\n/**\n * `milo.Model.Path`\n * ModelPath object that allows access to any point inside [Model](./index.js.html) as defined by `accessPath`\n *\n * @constructor\n * @param {Model} model Model instance that ModelPath gives access to.\n * @param {String} accessPath string that defines path to access model.\n * Path string consists of parts to define either property access (`\".name\"` to access property name) or array item access (`\"[1]\"` to access item with index 1).\n * Access path can contain as many parts as necessary (e.g. `\".list[0].name\"` to access property `name` in the first element of array stored in property `list`.\n * @param {List} arguments additional arguments of this method can be used to create interpolated paths.\n * E.g. `m.path(\"[$1].$2\", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m(\"[\" + id + \"].\" + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`.\n * @return {ModelPath}\n */\nfunction ModelPath(model, path) { // ,... - additional arguments for interpolation\n // check(model, Model);\n check(path, String);\n\n // `modelPath` will be returned by constructor instead of `this`. `modelPath`\n // (`modelPath_path` function) should also return a ModelPath object with \"synthesized\" methods\n // to get/set model properties, to subscribe to property changes, etc.\n // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below.\n var modelPath = function modelPath_path(accessPath) { // , ... arguments that will be interpolated\n return ModelPath$path.apply(modelPath, arguments);\n };\n modelPath.__proto__ = ModelPath.prototype;\n\n\n _.defineProperties(modelPath, {\n _model: model,\n _path: path,\n _args: _.slice(arguments, 1), // path will be the first element of this array\n _options: model._options\n });\n\n // parse access path\n var parsedPath = pathUtils.parseAccessPath(path);\n\n // compute access path string\n _.defineProperty(modelPath, '_accessPath', interpolateAccessPath(parsedPath, modelPath._args));\n\n if (modelPath._options.reactive !== false) {\n // messenger fails on \"*\" subscriptions\n modelPath._prepareMessenger();\n // subscribe to \"changedata\" message to enable reactive connections\n modelPath.onSync('changedata', changeDataHandler);\n }\n\n // compiling getter and setter\n var methods = synthesize(path, parsedPath);\n\n // adding methods to model path\n _.defineProperties(modelPath, methods);\n\n Object.freeze(modelPath);\n\n return modelPath;\n}\n\nModelPath.prototype.__proto__ = ModelPath.__proto__;\n\n\n/**\n * Interpolates path elements to compute real path\n *\n * @param {Array} parsedPath parsed path - array of path nodes\n * @param {Array} args path interpolation arguments, args[0] is path itself\n * @return {String}\n */\nfunction interpolateAccessPath(parsedPath, args) {\n return parsedPath.reduce(function(accessPathStr, currNode, index) {\n var interpolate = currNode.interpolate;\n return accessPathStr +\n (interpolate\n ? (currNode.syntax == 'array'\n ? '[' + args[interpolate] + ']'\n : '.' + args[interpolate])\n : currNode.property);\n }, '');\n}\n\n\n/**\n * ####ModelPath instance methods####\n *\n * - [path](#ModelPath$path) - gives access to path inside ModelPath\n * - get - synthesized\n * - set - synthesized\n * - splice - splice model data (as array or pseudo-array), synthesized\n * - [len](#ModelPath$len) - returns length of array (or pseudo-array) in safe way, 0 if no length is set\n * - [push](#ModelPath$push) - add items to the end of array (or pseudo-array) in ModelPath\n * - [pop](#ModelPath$pop) - remove item from the end of array (or pseudo-array) in ModelPath\n * - [unshift](#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in ModelPath\n * - [shift](#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in ModelPath\n */\n_.extendProto(ModelPath, {\n path: ModelPath$path,\n len: ModelPath$len,\n push: ModelPath$push,\n pop: ModelPath$pop,\n unshift: ModelPath$unshift,\n shift: ModelPath$shift,\n _prepareMessenger: _prepareMessenger,\n _getDefinition: _getDefinition,\n destroy: ModelPath$destroy\n});\n\n\n_.extend(ModelPath, {\n _createFromDefinition: _createFromDefinition\n})\n\n\n/**\n * Expose Messenger methods on Facet prototype\n */\nvar MESSENGER_PROPERTY = '_messenger';\nMessenger.useWith(ModelPath, MESSENGER_PROPERTY, Messenger.defaultMethods);\n\n\n/**\n * ModelPath instance method\n * Gives access to path inside ModelPath. Method works similarly to [path method](#Model$path) of model, using relative paths.\n *\n * @param {String} accessPath string that defines path to access model.\n * Path string consists of parts to define either property access (`\".name\"` to access property name) or array item access (`\"[1]\"` to access item with index 1).\n * Access path can contain as many parts as necessary (e.g. `\".list[0].name\"` to access property `name` in the first element of array stored in property `list`.\n * @param {List} arguments additional arguments of this method can be used to create interpolated paths.\n * E.g. `m.path(\"[$1].$2\", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m(\"[\" + id + \"].\" + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`.\n * @return {ModelPath}\n */\nfunction ModelPath$path(accessPath) { // , ... arguments that will be interpolated\n if (! accessPath) return this;\n\n var thisPathArgsCount = this._args.length - 1;\n\n if (thisPathArgsCount > 0) {// this path has interpolated arguments too\n accessPath = accessPath.replace(/\\$[1-9][0-9]*/g, function(str) {\n return '$' + (+str.slice(1) + thisPathArgsCount);\n });\n }\n\n var newPath = this._path + accessPath;\n\n // this._model is added in front of all arguments as the first parameter\n // of ModelPath constructor\n var args = [this._model, newPath]\n .concat(this._args.slice(1)) // remove old path from _args, as it is 1 based\n .concat(_.slice(arguments, 1)); // add new interpolation arguments\n\n // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ...\n return _.newApply(ModelPath, args);\n}\n\n\n/**\n * ModelPath and Model instance method\n * Returns length property and sets it to 0 if it wasn't set.\n *\n * @return {Any}\n */\nfunction ModelPath$len() {\n return this.path('.length').get() || 0;\n}\n\n\n/**\n * ModelPath and Model instance method\n * Adds items to the end of array (or pseudo-array). Returns new length.\n *\n * @param {List} arguments list of items that will be added to array (pseudo array)\n * @return {Integer}\n */\nfunction ModelPath$push() { // arguments\n var length = this.len();\n var newLength = length + arguments.length;\n\n _.splice(arguments, 0, 0, length, 0);\n this.splice.apply(this, arguments);\n\n return newLength;\n}\n\n\n/**\n * ModelPath and Model instance method\n * Removes item from the end of array (or pseudo-array). Returns this item.\n *\n * @return {Any}\n */\nfunction ModelPath$pop() {\n return this.splice(this.len() - 1, 1)[0];\n}\n\n\n/**\n * ModelPath and Model instance method\n * Inserts items to the beginning of the array. Returns new length.\n *\n * @param {List} arguments items to be inserted in the beginning of array\n * @return {Integer}\n */\nfunction ModelPath$unshift() { // arguments\n var length = this.len();\n length += arguments.length;\n\n _.splice(arguments, 0, 0, 0, 0);\n this.splice.apply(this, arguments);\n\n return length;\n}\n\n\n/**\n * ModelPath and Model instance method\n * Removes the item from the beginning of array (or pseudo-array). Returns this item.\n *\n * @return {Any}\n */\nfunction ModelPath$shift() { // arguments\n return this.splice(0, 1)[0];\n}\n\n\n/**\n * ModelPath instance method\n * Initializes ModelPath mesenger with Model's messenger as its source ([MessengerMessageSource](../messenger/msngr_source.js.html)) and [ModelPathMsgAPI](./path_msg_api.js.html) as [MessengerAPI](../messenger/m_api.js.html)\n */\nfunction _prepareMessenger() {\n var mPathAPI = new ModelPathMsgAPI(this._accessPath);\n\n // create MessengerMessageSource connected to Model's messenger\n var modelMessageSource = new MessengerMessageSource(this, undefined, mPathAPI, this._model);\n\n // create messenger with model passed as hostObject (default message dispatch context)\n // and without proxying methods (we don't want to proxy them to Model)\n var mPathMessenger = new Messenger(this, undefined, modelMessageSource);\n\n // store messenger on ModelPath instance\n _.defineProperty(this, MESSENGER_PROPERTY, mPathMessenger);\n}\n\n\n/**\n * Returns the object allowing to recreate model path\n *\n * @return {Object}\n */\nfunction _getDefinition() {\n return {\n model: this._model,\n path: this._path,\n args: this._args\n };\n}\n\n\n/**\n * Class method\n * Creates modelPath object from definition created by _getDefinition\n *\n * @param {Object} definition\n * @return {ModelPath}\n */\nfunction _createFromDefinition(definition) {\n check(definition, {\n model: Function, // Model\n path: String,\n args: Array\n });\n\n var m = definition.model;\n\n return m.apply(m, definition.args);\n}\n\n\nfunction ModelPath$destroy() {\n this[MESSENGER_PROPERTY].destroy();\n}\n", @@ -227,19 +250,20 @@ "'use strict';\n\nvar count = require('./count')\n , config = require('../config')\n , prefix = config.componentPrefix;\n\n\nmodule.exports = componentName;\n\n\nfunction componentName() {\n return prefix + count();\n}\n", "'use strict';\n\nvar timestamp = Date.now()\n , count = ''\n , uniqueID = '' + timestamp;\n\nfunction uniqueCount() {\n var newTimestamp = Date.now();\n uniqueID = '' + newTimestamp;\n if (timestamp == newTimestamp) {\n count = count === '' ? 0 : count + 1;\n uniqueID += '_' + count;\n } else {\n timestamp = newTimestamp;\n count = '';\n }\n\n return uniqueID;\n}\n\nuniqueCount.get = function() {\n return uniqueID;\n}\n\nmodule.exports = uniqueCount;\n", "'use strict';\n\nmodule.exports = createComponentClass;\n\n/**\n * Utility function which creates and registers new milo component. The component created will have\n * a reference to the super class used in its creation (Accessable using .super).\n *\n * @param {string} config.className - The name of the new component\n * @param {string} ['Component'] config.superClassName - The name of an existing component to be used as the new component's super class\n * @param {object=} config.facets - Facet configuration (Hash of facet name {string} to config {object})\n * @param {object=} config.methods - Methods of the new component (Hash of function name {string} to function {function})\n * @param {object=} config.staticMethods - Static methods of the new component (Hash of function name {string} to function {function})\n */\nfunction createComponentClass(config) {\n var componentRegistry = milo.registry.components;\n var SuperClass = componentRegistry.get(config.superClassName || 'Component');\n var ComponentClass = SuperClass.createComponentClass(config.className, config.facets);\n\n if(config.methods) {\n _.extendProto(ComponentClass, config.methods);\n }\n\n if(config.staticMethods) {\n if(config.staticMethods.super !== undefined) throw '\\'super\\' is a reserved keyword';\n\n _.extend(ComponentClass, config.staticMethods);\n }\n\n ComponentClass.super = SuperClass.prototype;\n \n componentRegistry.add(ComponentClass);\n\n return ComponentClass;\n}", - "'use strict';\n\n\nvar config = require('../config')\n , _ = require('mol-proto')\n , logger = require('./logger');\n\nvar domUtils = {\n children: children,\n filterNodeListByType: filterNodeListByType,\n containingElement: containingElement,\n selectElementContents: selectElementContents,\n selectElementText: selectElementText,\n getElementOffset: getElementOffset,\n setCaretPosition: setCaretPosition,\n getSelectionDirection: getSelectionDirection,\n setSelection: setSelection,\n clearSelection: clearSelection,\n removeElement: removeElement,\n unwrapElement: unwrapElement,\n wrapInElement: wrapInElement,\n detachComponent: detachComponent,\n firstTextNode: firstTextNode,\n lastTextNode: lastTextNode,\n trimNodeRight: trimNodeRight,\n trimNodeLeft: trimNodeLeft,\n stripHtml: stripHtml,\n htmlEntities: htmlEntities,\n walkTree: walkTree,\n createTreeWalker: createTreeWalker,\n\n treePathOf: treePathOf,\n getNodeAtTreePath: getNodeAtTreePath,\n insertAtTreePath: insertAtTreePath,\n isTreePathBefore: isTreePathBefore,\n\n getNodeWindow: getNodeWindow,\n\n getComponentsFromRange: getComponentsFromRange,\n deleteRangeWithComponents: deleteRangeWithComponents,\n forEachNodesInRange: forEachNodesInRange,\n areRangesEqual: areRangesEqual,\n\n addDebugPoint: addDebugPoint\n};\n\nmodule.exports = domUtils;\n\n\n/**\n * Returns the list of element children of DOM element\n *\n * @param {Element} el element to return the children of (only DOM elements)\n * @return {Array[Element]}\n */\n function children(el) {\n return filterNodeListByType(el.childNodes, Node.ELEMENT_NODE)\n }\n\n\n/**\n * Filters the list of nodes by type\n *\n * @param {NodeList} nodeList the list of nodes, for example childNodes property of DOM element\n * @param {Integer} nodeType an integer constant [defined by DOM API](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType), e.g. `Node.ELEMENT_NODE` or `Node.TEXT_NODE`\n * @return {Array[Node]}\n */\nfunction filterNodeListByType(nodeList, nodeType) {\n return _.filter(nodeList, function (node) {\n return node.nodeType == nodeType;\n });\n}\n\n\n/**\n * Find nearest parent element for node.\n * If node is an element, it will be returned.\n *\n * @param {Node} node\n * @return {Element|null}\n */\nfunction containingElement(node) {\n while (node) {\n if (node.nodeType == Node.ELEMENT_NODE)\n return node;\n node = node.parentNode;\n }\n return null;\n}\n\n\n/**\n * Selects inner contents of DOM element\n *\n * @param {Element} el DOM element\n */\nfunction selectElementContents(el) {\n var doc = el.ownerDocument;\n if (! doc) return logger.error('selectElementContents: element has no document')\n var range = doc.createRange();\n range.selectNodeContents(el);\n var win = getNodeWindow(el)\n , sel = win.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n\n/**\n * Selects text inside element\n * @param {Element} el\n */\nfunction selectElementText(el) {\n var fromNode = firstTextNode(el)\n , toNode = lastTextNode(el);\n\n if (fromNode && toNode)\n setSelection(fromNode, 0, toNode, toNode.textContent.length);\n}\n\n\n/**\n * Sets the caret position to the position in the node\n *\n * @param {Node} node DOM node\n * @param {Number} pos caret position\n */\nfunction setCaretPosition(node, pos) {\n var doc = node.ownerDocument;\n if (! doc) return logger.error('setCaretPosition: element has no document')\n var range = doc.createRange();\n range.setStart(node, pos);\n var win = getNodeWindow(node)\n , sel = win.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/**\n * get the direction of a selection\n *\n * 1 forward, -1 backward, 0 no direction, undefined one of the node is detached or in a different frame\n *\n * @param {sel} a selection object\n * @return {-1|0|1|undefined}\n */\nfunction getSelectionDirection(sel){\n return _getDirection(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);\n}\n\nfunction _getDirection(fromNode, startOffset, toNode, endOffset){\n var docPosition = fromNode.compareDocumentPosition(toNode);\n if (docPosition & Node.DOCUMENT_POSITION_FOLLOWING){\n return 1;\n }\n else if (docPosition & Node.DOCUMENT_POSITION_PRECEDING){\n return -1;\n }\n else if (fromNode == toNode){\n if (startOffset < endOffset){\n return 1;\n }\n else if (startOffset > endOffset){\n return -1;\n }\n else {\n return 0;\n }\n }\n}\n\n/**\n * Selects a range in a document\n *\n * @param {Node} fromNode DOM node to start selection in\n * @param {Number} startOffset\n * @param {Node} toNode DOM node to end selection in\n * @param {Number} endOffset\n */\nfunction setSelection(fromNode, startOffset, toNode, endOffset) {\n var doc = fromNode.ownerDocument;\n if (! doc) return logger('setCaretPosition: element has no document')\n var backward = _getDirection(fromNode, startOffset, toNode, endOffset) == -1;\n var range = doc.createRange();\n var container, originalContentEditable;\n // does not work in non contentEditable items\n\n var win = getNodeWindow(fromNode)\n , sel = win.getSelection();\n\n\n if (backward){\n range.setStart(toNode, endOffset);\n range.setEnd(fromNode, startOffset);\n range.collapse(false);\n }\n else {\n range.setStart(fromNode, startOffset);\n range.setEnd(toNode, endOffset);\n }\n\n container = range.commonAncestorContainer == Node.ELEMENT_NODE ?\n range.commonAncestorContainer :\n range.commonAncestorContainer.parentElement;\n\n if (!container.isContentEditable){\n originalContentEditable = container.contentEditable; // false or inherit\n container.contentEditable = \"true\";\n }\n\n sel.removeAllRanges();\n sel.addRange(range);\n\n if (backward){\n sel.extend(toNode, endOffset);\n }\n\n if (originalContentEditable){\n // restoring contentEditable\n container.contentEditable = originalContentEditable;\n }\n}\n\n/**\n * Clears selection in a given window\n * @param {Window} win\n */\nfunction clearSelection(win) {\n win = win || window;\n var sel = win.getSelection();\n sel.removeAllRanges();\n}\n\n\n/**\n * Calculates an element's total top and left offset from the document edge.\n *\n * @param {Element} el the element for which position needs to be returned\n * @param {includeBorder} if is to include the border width\n * @return {Object} vector object with properties topOffset and leftOffset\n */\nfunction getElementOffset(el, includeBorder) {\n var yPos, xPos;\n\n yPos = el.offsetTop;\n xPos = el.offsetLeft;\n el = el.offsetParent;\n\n while (el != null) {\n yPos += el.offsetTop + getBorder(el, 'Height', includeBorder);\n xPos += el.offsetLeft + getBorder(el, 'Width', includeBorder);\n el = el.offsetParent;\n }\n\n return { topOffset: yPos, leftOffset: xPos };\n}\n\n\nfunction getBorder(el, type, includeBorder) {\n if (includeBorder) {\n var side = (type == 'Height') ? 'top' : 'left',\n styles = window.getComputedStyle(el),\n sideValue = parseInt(styles.getPropertyValue('border-' + side + '-width'), 10);\n\n if (sideValue) return sideValue;\n }\n return 0;\n}\n\n\n/**\n * Removes element from the document\n *\n * @param {Element} el the element to be removed\n */\nfunction removeElement(el) {\n var parent = el.parentNode;\n if (parent){\n parent.removeChild(el);\n parent.normalize();\n }\n}\n\n\n/**\n * Returns the first child text node of an element\n *\n * @param {Element|Node} node the node to be searched, if the node is text node we return the node.\n * @return {TextNode}\n */\nfunction firstTextNode(node) {\n if (node.nodeType == Node.TEXT_NODE) return node;\n var treeWalker = createTreeWalker(node, NodeFilter.SHOW_TEXT);\n return treeWalker.firstChild();\n}\n\n\n/**\n * Returns the last child text node of an element\n *\n * @param {Element|Node} node the node to be searched, if the node is text node we return the node.\n * @return {TextNode}\n */\nfunction lastTextNode(node) {\n if (node.nodeType == Node.TEXT_NODE) return node;\n var treeWalker = createTreeWalker(node, NodeFilter.SHOW_TEXT);\n return treeWalker.lastChild();\n}\n\n\n/**\n * Removes element from the document putting its children in its place\n *\n * @param {Element} el the element to be \"unwrapped\"\n */\nfunction unwrapElement(el) {\n var parent = el.parentNode;\n\n if (parent) {\n var frag = document.createDocumentFragment();\n // must be copied to avoid iterating a mutating list of childNodes\n var children = _.slice(el.childNodes);\n children.forEach(frag.appendChild, frag);\n parent.replaceChild(frag, el);\n parent.normalize();\n }\n}\n\n\n/**\n * Wraps an element in another element\n *\n * @param {Element} wrapIntoEl\n * @param {Element} el\n */\nfunction wrapInElement(wrapIntoEl, el) {\n var parent = el.parentNode;\n\n if (parent) {\n parent.insertBefore(wrapIntoEl, el);\n wrapIntoEl.appendChild(el);\n }\n}\n\n\n/**\n * Trims a text node of trailing spaces, and returns true if a trim was performed.\n *\n * @param {TextNode} node\n * @return {Boolean}\n */\nfunction trimNodeRight(node) {\n return _trimNode(node, 'trimRight');\n}\n\n\n/**\n * Trims a text node of leading spaces, and returns true if a trim was performed.\n *\n * @param {TextNode} node\n * @return {Boolean}\n */\nfunction trimNodeLeft(node) {\n return _trimNode(node, 'trimLeft');\n}\n\n\nfunction _trimNode(node, methodName) {\n var len = node.length;\n node.textContent = node.textContent[methodName]();\n return len !== node.length;\n}\n\n\n/**\n * Removes the reference to component from element\n *\n * @param {Element} el\n */\nfunction detachComponent(el) {\n delete el[config.componentRef];\n}\n\n\n/**\n * Retrieves the content of a html string\n * @param {String} str Any string\n * @return {String} returns the string cleaned of any html content.\n */\nfunction stripHtml(str) {\n var div = document.createElement('DIV');\n div.innerHTML = str;\n return div.textContent || '';\n}\n\n\n/**\n * Convenience wrapper for native TreeWalker that automatically walks the tree and calls an iterator function.\n * This will not iterate the root element.\n * @param {HTMLElement} root The containing root element to be walked. Will not be iterated.\n * @param {NodeFiler} filter A NodeFilter constant, see https://developer.mozilla.org/en/docs/Web/API/TreeWalker\n * @param {Function} iterator A function to be called on each node. Returning 'false' will break.\n * @param {Object} context An optional context to passed, defaults to root.\n */\nfunction walkTree(root, filter, iterator, context) {\n var tw = document.createTreeWalker(root, filter);\n while(tw.nextNode()) {\n var result = iterator.call(context || root, tw.currentNode);\n if (result === false) break;\n }\n}\n\n\n/**\n * Returns array of child indexes of element path inside root element in DOM tree using breadth first tree traversal.\n * Returns undefined if the element is not inside root element, 0 if the root element itself is passed.\n *\n * @param {Element} rootEl element to search\n * @param {Element} el element to find the index of\n * @return {Array[Number]}\n */\nfunction treePathOf(rootEl, el) {\n if (! (rootEl && rootEl.contains(el))) return;\n\n var treePath = []\n , node = rootEl;\n\n while (node != el) {\n var nodeIndex = _.findIndex(node.childNodes, function(child) {\n return child.contains(el);\n });\n treePath.push(nodeIndex);\n node = node.childNodes[nodeIndex];\n }\n\n return treePath;\n}\n\n\n/**\n * Returns element at given tree path\n *\n * @param {Element} rootEl\n * @param {Array[Number]} treePath\n * @param {Boolean} nearest return nearest possible node if exact node does not exist\n * @return {Node}\n */\nfunction getNodeAtTreePath(rootEl, treePath, nearest) {\n if (!treePath) return;\n\n var len = treePath.length;\n if (len === 0) return rootEl;\n\n var node = rootEl;\n\n for (var i = 0; i < len; i++) {\n var children = node.childNodes;\n if (! children) {\n if (! nearest) node = undefined;\n break;\n }\n var childIndex = treePath[i]\n , child = children[childIndex];\n if (! child) {\n node = nearest\n ? children[children.length - 1]\n : undefined;\n break;\n }\n node = child;\n }\n\n return node;\n}\n\n\n/**\n * Inserts an element inside root at a given path in tree (that has the same meaning as the index returned by `treePathOf` function). If element is already in the root's tree, it will be removed first and then moved to the passed treeIndex\n * Insertion at index 0 is not possible and will return undefined as it would mean replacing the root element.\n *\n * @param {Element} rootEl element into which to insert\n * @param {Number} treeIndex index in DOM tree inside root element (see treePathOf)\n * @param {Element} el element to be inserted\n * @return {Boolean} true if was successfully inserted\n */\nfunction insertAtTreePath(rootEl, treePath, el, nearest) {\n var toNormalize = el.nodeType == Node.TEXT_NODE;\n if (rootEl.contains(el))\n removeElement(el); // can't use removeChild as rootEl here is not an immediate parent\n\n if (treePath.length == 0) return;\n\n var parent = getNodeAtTreePath(rootEl, treePath.slice(0, -1), nearest)\n , children = parent.childNodes;\n\n if (! children) {\n if (nearest) {\n parent = parent.parentNode;\n children = parent.childNodes;\n } else return;\n }\n\n var childIndex = treePath[treePath.length - 1]\n , child = children[childIndex];\n\n if (child) {\n parent.insertBefore(el, child);\n toNormalize && parent.normalize();\n return true;\n } else if (children.length === 0 && (childIndex === 0 || nearest)) {\n parent.appendChild(el);\n toNormalize && parent.normalize();\n return true;\n } else {\n child = children[childIndex - 1];\n if (child || nearest) {\n parent.appendChild(el);\n toNormalize && parent.normalize();\n return true;\n }\n }\n}\n\n\n/**\n * Returns `true` if the first tree path points to a node which is before the other in the document order.\n * @param {Array} path1 A treepath array\n * @param {Array} path2 A treepath array\n * @return {Boolean}\n */\nfunction isTreePathBefore(path1, path2) {\n var i = 0\n , isBefore;\n if (!Array.isArray(path1) && Array.isArray(path2))\n return logger.error('isTreePathBefore: One or both paths are not valid treepath arrays.');\n\n for (i; i < path1.length; i++) {\n if (path1[i] < path2[i]) {\n isBefore = true;\n break;\n } else if (path1[i] > path2[i]) {\n isBefore = false;\n break;\n }\n }\n\n if (typeof isBefore == 'undefined')\n if (path1.length < path2.length)\n logger.warn('isTreePathBefore: One node is inside another');\n\n return isBefore || false;\n}\n\n\n/**\n * Converts non latin characters to HTML entity codes.\n * @param {String} str the string to convert\n * @return {String} the string with html entities\n */\nfunction htmlEntities(str) {\n return str.replace(/[\\u00A0-\\u99999<>\\&]/gim, function(i) {\n return '&#'+i.charCodeAt(0)+';';\n });\n}\n\n\nfunction createTreeWalker(el, whatToShow) {\n whatToShow = whatToShow || (NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT);\n return document.createTreeWalker(el, whatToShow);\n}\n\n\n/**\n * Returns the reference to the window the node is in\n *\n * @param {Node} node\n * @return {Window}\n */\nfunction getNodeWindow(node) {\n var doc = node.ownerDocument;\n return doc && (doc.defaultView || doc.parentWindow);\n}\n\n\n\n/**\n * do something for each nodes contained in a range\n *\n * @param {range} a range\n * @param {cb} a function taking a node as argument\n\n */\nfunction forEachNodesInRange(range, cb){\n var rangeContainer = range.commonAncestorContainer\n , doc = rangeContainer.ownerDocument;\n\n function isNodeInsideRange(node){\n var nodeRange = document.createRange();\n var isInside = false;\n nodeRange.selectNode(node);\n\n if (nodeRange.compareBoundaryPoints(Range.START_TO_START, range) != -1\n && nodeRange.compareBoundaryPoints(Range.END_TO_END, range) != 1){\n isInside = true;\n }\n nodeRange.detach();\n return isInside;\n }\n\n var treeWalker = doc.createTreeWalker(rangeContainer,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);\n\n var currentNode;\n while (currentNode = treeWalker.nextNode()){\n if (isNodeInsideRange(currentNode)){\n cb(currentNode);\n }\n }\n}\n\n/**\n * get all components contained in a range\n *\n * @param {range} a DOM range.\n */\nfunction getComponentsFromRange(range) {\n var win = getNodeWindow(range.startContainer)\n , Component = win.milo.Component;\n\n var components = [];\n forEachNodesInRange(range, function (node){\n if (node.nodeType != Node.TEXT_NODE) {\n var comp = Component.getComponent(node);\n if (comp)\n components.push(comp);\n }\n });\n\n return components;\n}\n\n/**\n * delete a range\n *\n * @param {range} delete a DOM range and all the components inside\n */\nfunction deleteRangeWithComponents(range) {\n var components = getComponentsFromRange(range);\n\n components.forEach(function(comp) {\n comp.destroy(true);\n });\n\n range.deleteContents();\n}\n\n/**\n * check if two ranges are equivalent\n *\n * @param {range} range1\n * @param {range} range2\n * @return {Boolean} are the two ranges equivalent\n */\nfunction areRangesEqual(range1, range2){\n return range1.compareBoundaryPoints(Range.START_TO_START, range2) == 0 && range1.compareBoundaryPoints(Range.END_TO_END, range2) == 0;\n}\n\n\n/**\n * Adds a single pixel div to the body at a given x and y position. Useful for debugging position specific code.\n * @param {Number} x\n * @param {Number} y\n */\nfunction addDebugPoint(x, y) {\n var dbEl = document.createElement('div');\n dbEl.setAttribute('style', 'width: 1px; height: 1px; position:fixed; left:'+x+'px; top:'+y+'px; background-color:red; z-index: 100');\n setTimeout(function() {document.body.appendChild(dbEl);}, 200);\n}\n", + "'use strict';\n\n\nvar config = require('../config')\n , _ = require('mol-proto')\n , logger = require('./logger');\n\nvar domUtils = {\n children: children,\n filterNodeListByType: filterNodeListByType,\n containingElement: containingElement,\n selectElementContents: selectElementContents,\n selectElementText: selectElementText,\n getElementOffset: getElementOffset,\n setCaretPosition: setCaretPosition,\n getSelectionDirection: getSelectionDirection,\n setSelection: setSelection,\n clearSelection: clearSelection,\n removeElement: removeElement,\n unwrapElement: unwrapElement,\n wrapInElement: wrapInElement,\n detachComponent: detachComponent,\n firstTextNode: firstTextNode,\n lastTextNode: lastTextNode,\n trimNodeRight: trimNodeRight,\n trimNodeLeft: trimNodeLeft,\n stripHtml: stripHtml,\n htmlEntities: htmlEntities,\n walkTree: walkTree,\n createTreeWalker: createTreeWalker,\n\n treePathOf: treePathOf,\n getNodeAtTreePath: getNodeAtTreePath,\n insertAtTreePath: insertAtTreePath,\n isTreePathBefore: isTreePathBefore,\n\n getNodeWindow: getNodeWindow,\n\n getComponentsFromRange: getComponentsFromRange,\n deleteRangeWithComponents: deleteRangeWithComponents,\n forEachNodesInRange: forEachNodesInRange,\n areRangesEqual: areRangesEqual,\n\n addDebugPoint: addDebugPoint\n};\n\nmodule.exports = domUtils;\n\n\n/**\n * Returns the list of element children of DOM element\n *\n * @param {Element} el element to return the children of (only DOM elements)\n * @return {Array[Element]}\n */\n function children(el) {\n return filterNodeListByType(el.childNodes, Node.ELEMENT_NODE);\n }\n\n\n/**\n * Filters the list of nodes by type\n *\n * @param {NodeList} nodeList the list of nodes, for example childNodes property of DOM element\n * @param {Integer} nodeType an integer constant [defined by DOM API](https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType), e.g. `Node.ELEMENT_NODE` or `Node.TEXT_NODE`\n * @return {Array[Node]}\n */\nfunction filterNodeListByType(nodeList, nodeType) {\n return _.filter(nodeList, function (node) {\n return node.nodeType == nodeType;\n });\n}\n\n\n/**\n * Find nearest parent element for node.\n * If node is an element, it will be returned.\n *\n * @param {Node} node\n * @return {Element|null}\n */\nfunction containingElement(node) {\n while (node) {\n if (node.nodeType == Node.ELEMENT_NODE)\n return node;\n node = node.parentNode;\n }\n return null;\n}\n\n\n/**\n * Selects inner contents of DOM element\n *\n * @param {Element} el DOM element\n */\nfunction selectElementContents(el) {\n var doc = el.ownerDocument;\n if (! doc) return logger.error('selectElementContents: element has no document');\n var range = doc.createRange();\n range.selectNodeContents(el);\n var win = getNodeWindow(el)\n , sel = win.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n\n/**\n * Selects text inside element\n * @param {Element} el\n */\nfunction selectElementText(el) {\n var fromNode = firstTextNode(el)\n , toNode = lastTextNode(el);\n\n if (fromNode && toNode)\n setSelection(fromNode, 0, toNode, toNode.textContent.length);\n}\n\n\n/**\n * Sets the caret position to the position in the node\n *\n * @param {Node} node DOM node\n * @param {Number} pos caret position\n */\nfunction setCaretPosition(node, pos) {\n var doc = node.ownerDocument;\n if (! doc) return logger.error('setCaretPosition: element has no document');\n var range = doc.createRange();\n range.setStart(node, pos);\n var win = getNodeWindow(node)\n , sel = win.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n}\n\n/**\n * get the direction of a selection\n *\n * 1 forward, -1 backward, 0 no direction, undefined one of the node is detached or in a different frame\n *\n * @param {sel} a selection object\n * @return {-1|0|1|undefined}\n */\nfunction getSelectionDirection(sel){\n return _getDirection(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);\n}\n\nfunction _getDirection(fromNode, startOffset, toNode, endOffset){\n var docPosition = fromNode.compareDocumentPosition(toNode);\n if (docPosition & Node.DOCUMENT_POSITION_FOLLOWING){\n return 1;\n }\n else if (docPosition & Node.DOCUMENT_POSITION_PRECEDING){\n return -1;\n }\n else if (fromNode == toNode){\n if (startOffset < endOffset){\n return 1;\n }\n else if (startOffset > endOffset){\n return -1;\n }\n else {\n return 0;\n }\n }\n}\n\n/**\n * Selects a range in a document\n *\n * @param {Node} fromNode DOM node to start selection in\n * @param {Number} startOffset\n * @param {Node} toNode DOM node to end selection in\n * @param {Number} endOffset\n */\nfunction setSelection(fromNode, startOffset, toNode, endOffset) {\n var doc = fromNode.ownerDocument;\n if (! doc) return logger('setCaretPosition: element has no document');\n var backward = _getDirection(fromNode, startOffset, toNode, endOffset) == -1;\n var range = doc.createRange();\n var container, originalContentEditable;\n // does not work in non contentEditable items\n\n var win = getNodeWindow(fromNode)\n , sel = win.getSelection();\n\n\n if (backward){\n range.setStart(toNode, endOffset);\n range.setEnd(fromNode, startOffset);\n range.collapse(false);\n }\n else {\n range.setStart(fromNode, startOffset);\n range.setEnd(toNode, endOffset);\n }\n\n container = range.commonAncestorContainer == Node.ELEMENT_NODE ?\n range.commonAncestorContainer :\n range.commonAncestorContainer.parentElement;\n\n if (!container.isContentEditable){\n originalContentEditable = container.contentEditable; // false or inherit\n container.contentEditable = \"true\";\n }\n\n sel.removeAllRanges();\n sel.addRange(range);\n\n if (backward){\n sel.extend(toNode, endOffset);\n }\n\n if (originalContentEditable){\n // restoring contentEditable\n container.contentEditable = originalContentEditable;\n }\n}\n\n/**\n * Clears selection in a given window\n * @param {Window} win\n */\nfunction clearSelection(win) {\n win = win || window;\n var sel = win.getSelection();\n sel.removeAllRanges();\n}\n\n\n/**\n * Calculates an element's total top and left offset from the document edge.\n *\n * @param {Element} el the element for which position needs to be returned\n * @param {includeBorder} if is to include the border width\n * @return {Object} vector object with properties topOffset and leftOffset\n */\nfunction getElementOffset(el, includeBorder) {\n var yPos, xPos;\n\n yPos = el.offsetTop;\n xPos = el.offsetLeft;\n el = el.offsetParent;\n\n while (el) {\n yPos += el.offsetTop + getBorder(el, 'Height', includeBorder);\n xPos += el.offsetLeft + getBorder(el, 'Width', includeBorder);\n el = el.offsetParent;\n }\n\n return { topOffset: yPos, leftOffset: xPos };\n}\n\n\nfunction getBorder(el, type, includeBorder) {\n if (includeBorder) {\n var side = (type == 'Height') ? 'top' : 'left',\n styles = window.getComputedStyle(el),\n sideValue = parseInt(styles.getPropertyValue('border-' + side + '-width'), 10);\n\n if (sideValue) return sideValue;\n }\n return 0;\n}\n\n\n/**\n * Removes element from the document\n *\n * @param {Element} el the element to be removed\n */\nfunction removeElement(el) {\n var parent = el.parentNode;\n if (parent){\n parent.removeChild(el);\n parent.normalize();\n }\n}\n\n\n/**\n * Returns the first child text node of an element\n *\n * @param {Element|Node} node the node to be searched, if the node is text node we return the node.\n * @return {TextNode}\n */\nfunction firstTextNode(node) {\n if (node.nodeType == Node.TEXT_NODE) return node;\n var treeWalker = createTreeWalker(node, NodeFilter.SHOW_TEXT);\n return treeWalker.firstChild();\n}\n\n\n/**\n * Returns the last child text node of an element\n *\n * @param {Element|Node} node the node to be searched, if the node is text node we return the node.\n * @return {TextNode}\n */\nfunction lastTextNode(node) {\n if (node.nodeType == Node.TEXT_NODE) return node;\n var treeWalker = createTreeWalker(node, NodeFilter.SHOW_TEXT);\n return treeWalker.lastChild();\n}\n\n\n/**\n * Removes element from the document putting its children in its place\n *\n * @param {Element} el the element to be \"unwrapped\"\n */\nfunction unwrapElement(el) {\n var parent = el.parentNode;\n\n if (parent) {\n var frag = document.createDocumentFragment();\n // must be copied to avoid iterating a mutating list of childNodes\n var children = _.slice(el.childNodes);\n children.forEach(frag.appendChild, frag);\n parent.replaceChild(frag, el);\n parent.normalize();\n }\n}\n\n\n/**\n * Wraps an element in another element\n *\n * @param {Element} wrapIntoEl\n * @param {Element} el\n */\nfunction wrapInElement(wrapIntoEl, el) {\n var parent = el.parentNode;\n\n if (parent) {\n parent.insertBefore(wrapIntoEl, el);\n wrapIntoEl.appendChild(el);\n }\n}\n\n\n/**\n * Trims a text node of trailing spaces, and returns true if a trim was performed.\n *\n * @param {TextNode} node\n * @return {Boolean}\n */\nfunction trimNodeRight(node) {\n return _trimNode(node, 'trimRight');\n}\n\n\n/**\n * Trims a text node of leading spaces, and returns true if a trim was performed.\n *\n * @param {TextNode} node\n * @return {Boolean}\n */\nfunction trimNodeLeft(node) {\n return _trimNode(node, 'trimLeft');\n}\n\n\nfunction _trimNode(node, methodName) {\n var len = node.length;\n node.textContent = node.textContent[methodName]();\n return len !== node.length;\n}\n\n\n/**\n * Removes the reference to component from element\n *\n * @param {Element} el\n */\nfunction detachComponent(el) {\n delete el[config.componentRef];\n}\n\n\n/**\n * Retrieves the content of a html string\n * @param {String} str Any string\n * @return {String} returns the string cleaned of any html content.\n */\nfunction stripHtml(str) {\n var div = document.createElement('DIV');\n div.innerHTML = str;\n return div.textContent || '';\n}\n\n\n/**\n * Convenience wrapper for native TreeWalker that automatically walks the tree and calls an iterator function.\n * This will not iterate the root element.\n * @param {HTMLElement} root The containing root element to be walked. Will not be iterated.\n * @param {NodeFiler} filter A NodeFilter constant, see https://developer.mozilla.org/en/docs/Web/API/TreeWalker\n * @param {Function} iterator A function to be called on each node. Returning 'false' will break.\n * @param {Object} context An optional context to passed, defaults to root.\n */\nfunction walkTree(root, filter, iterator, context) {\n var tw = document.createTreeWalker(root, filter);\n while(tw.nextNode()) {\n var result = iterator.call(context || root, tw.currentNode);\n if (result === false) break;\n }\n}\n\n\n/**\n * Returns array of child indexes of element path inside root element in DOM tree using breadth first tree traversal.\n * Returns undefined if the element is not inside root element, 0 if the root element itself is passed.\n *\n * @param {Element} rootEl element to search\n * @param {Element} el element to find the index of\n * @return {Array[Number]}\n */\nfunction treePathOf(rootEl, el) {\n if (! (rootEl && rootEl.contains(el))) return;\n\n var treePath = []\n , node = rootEl;\n\n while (node != el) {\n var nodeIndex = _.findIndex(node.childNodes, containsEl);\n treePath.push(nodeIndex);\n node = node.childNodes[nodeIndex];\n }\n\n return treePath;\n\n function containsEl(child) {\n return child.contains(el);\n }\n}\n\n\n/**\n * Returns element at given tree path\n *\n * @param {Element} rootEl\n * @param {Array[Number]} treePath\n * @param {Boolean} nearest return nearest possible node if exact node does not exist\n * @return {Node}\n */\nfunction getNodeAtTreePath(rootEl, treePath, nearest) {\n if (!treePath) return;\n\n var len = treePath.length;\n if (len === 0) return rootEl;\n\n var node = rootEl;\n\n for (var i = 0; i < len; i++) {\n var children = node.childNodes;\n if (! children) {\n if (! nearest) node = undefined;\n break;\n }\n var childIndex = treePath[i]\n , child = children[childIndex];\n if (! child) {\n node = nearest\n ? children[children.length - 1]\n : undefined;\n break;\n }\n node = child;\n }\n\n return node;\n}\n\n\n/**\n * Inserts an element inside root at a given path in tree (that has the same meaning as the index returned by `treePathOf` function). If element is already in the root's tree, it will be removed first and then moved to the passed treeIndex\n * Insertion at index 0 is not possible and will return undefined as it would mean replacing the root element.\n *\n * @param {Element} rootEl element into which to insert\n * @param {Number} treeIndex index in DOM tree inside root element (see treePathOf)\n * @param {Element} el element to be inserted\n * @return {Boolean} true if was successfully inserted\n */\nfunction insertAtTreePath(rootEl, treePath, el, nearest) {\n var toNormalize = el.nodeType == Node.TEXT_NODE;\n if (rootEl.contains(el))\n removeElement(el); // can't use removeChild as rootEl here is not an immediate parent\n\n if (treePath.length == 0) return;\n\n var parent = getNodeAtTreePath(rootEl, treePath.slice(0, -1), nearest)\n , children = parent.childNodes;\n\n if (! children) {\n if (nearest) {\n parent = parent.parentNode;\n children = parent.childNodes;\n } else return;\n }\n\n var childIndex = treePath[treePath.length - 1]\n , child = children[childIndex];\n\n if (child) {\n parent.insertBefore(el, child);\n if (toNormalize) parent.normalize();\n return true;\n } else if (children.length === 0 && (childIndex === 0 || nearest)) {\n parent.appendChild(el);\n if (toNormalize) parent.normalize();\n return true;\n } else {\n child = children[childIndex - 1];\n if (child || nearest) {\n parent.appendChild(el);\n if (toNormalize) parent.normalize();\n return true;\n }\n }\n}\n\n\n/**\n * Returns `true` if the first tree path points to a node which is before the other in the document order.\n * @param {Array} path1 A treepath array\n * @param {Array} path2 A treepath array\n * @return {Boolean}\n */\nfunction isTreePathBefore(path1, path2) {\n var i = 0\n , isBefore;\n if (!Array.isArray(path1) && Array.isArray(path2))\n return logger.error('isTreePathBefore: One or both paths are not valid treepath arrays.');\n\n for (i; i < path1.length; i++) {\n if (path1[i] < path2[i]) {\n isBefore = true;\n break;\n } else if (path1[i] > path2[i]) {\n isBefore = false;\n break;\n }\n }\n\n if (typeof isBefore == 'undefined')\n if (path1.length < path2.length)\n logger.warn('isTreePathBefore: One node is inside another');\n\n return isBefore || false;\n}\n\n\n/**\n * Converts non latin characters to HTML entity codes.\n * @param {String} str the string to convert\n * @return {String} the string with html entities\n */\nfunction htmlEntities(str) {\n return str.replace(/[\\u00A0-\\u99999<>\\&]/gim, function(i) {\n return '&#'+i.charCodeAt(0)+';';\n });\n}\n\n\nfunction createTreeWalker(el, whatToShow) {\n whatToShow = whatToShow || (NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT);\n return document.createTreeWalker(el, whatToShow);\n}\n\n\n/**\n * Returns the reference to the window the node is in\n *\n * @param {Node} node\n * @return {Window}\n */\nfunction getNodeWindow(node) {\n var doc = node.ownerDocument;\n return doc && (doc.defaultView || doc.parentWindow);\n}\n\n\n\n/**\n * do something for each nodes contained in a range\n *\n * @param {range} a range\n * @param {cb} a function taking a node as argument\n\n */\nfunction forEachNodesInRange(range, cb){\n var rangeContainer = range.commonAncestorContainer\n , doc = rangeContainer.ownerDocument;\n\n function isNodeInsideRange(node){\n var nodeRange = document.createRange();\n var isInside = false;\n nodeRange.selectNode(node);\n\n if (nodeRange.compareBoundaryPoints(window.Range.START_TO_START, range) != -1\n && nodeRange.compareBoundaryPoints(window.Range.END_TO_END, range) != 1){\n isInside = true;\n }\n nodeRange.detach();\n return isInside;\n }\n\n var treeWalker = doc.createTreeWalker(rangeContainer,\n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);\n\n var currentNode;\n while (currentNode = treeWalker.nextNode()){ // should be assignment\n if (isNodeInsideRange(currentNode)){\n cb(currentNode);\n }\n }\n}\n\n/**\n * get all components contained in a range\n *\n * @param {range} a DOM range.\n */\nfunction getComponentsFromRange(range) {\n var win = getNodeWindow(range.startContainer)\n , Component = win.milo.Component;\n\n var components = [];\n forEachNodesInRange(range, function (node){\n if (node.nodeType != Node.TEXT_NODE) {\n var comp = Component.getComponent(node);\n if (comp)\n components.push(comp);\n }\n });\n\n return components;\n}\n\n/**\n * delete a range\n *\n * @param {range} delete a DOM range and all the components inside\n */\nfunction deleteRangeWithComponents(range) {\n var components = getComponentsFromRange(range);\n\n components.forEach(function(comp) {\n comp.destroy(true);\n });\n\n range.deleteContents();\n}\n\n/**\n * check if two ranges are equivalent\n *\n * @param {range} range1\n * @param {range} range2\n * @return {Boolean} are the two ranges equivalent\n */\nfunction areRangesEqual(range1, range2){\n return range1.compareBoundaryPoints(window.Range.START_TO_START, range2) == 0 && range1.compareBoundaryPoints(window.Range.END_TO_END, range2) == 0;\n}\n\n\n/**\n * Adds a single pixel div to the body at a given x and y position. Useful for debugging position specific code.\n * @param {Number} x\n * @param {Number} y\n */\nfunction addDebugPoint(x, y) {\n var dbEl = document.createElement('div');\n dbEl.setAttribute('style', 'width: 1px; height: 1px; position:fixed; left:'+x+'px; top:'+y+'px; background-color:red; z-index: 100');\n setTimeout(function() {document.body.appendChild(dbEl);}, 200);\n}\n", "'use strict';\n\n\nvar _ = require('mol-proto')\n , check = require('./check');\n\n\nmodule.exports = DOMListeners;\n\n\nfunction DOMListeners() {\n this.listeners = [];\n}\n\n\n_.extendProto(DOMListeners, {\n add: DOMListeners$add,\n remove: DOMListeners$remove,\n removeAll: DOMListeners$removeAll\n});\n\n\nfunction DOMListeners$add(target, eventType, handler) {\n this.listeners.push({\n target: target,\n eventType: eventType,\n handler: handler\n });\n target.addEventListener(eventType, handler);\n}\n\n\nfunction DOMListeners$remove(target, eventType, handler) {\n var listener = {\n target: target,\n eventType: eventType,\n handler: handler\n };\n var idx = _.findIndex(this.listeners, _.partial(_.isEqual, listener));\n\n if (idx > -1) {\n this.listeners.splice(idx, 1);\n _removeListener(listener);\n }\n}\n\n\nfunction DOMListeners$removeAll() {\n this.listeners.forEach(_removeListener);\n this.listeners = [];\n}\n\n\nfunction _removeListener(l) {\n l.target.removeEventListener(l.eventType, l.handler);\n}\n", "'use strict';\n\n\nvar _ = require('mol-proto');\n\n\nmodule.exports = domReady;\n\n\nvar domReadyFuncs = []\n , domReadySubscribed = false;\n\n\nfunction domReady(func) { // , arguments\n var self = this\n , args = _.slice(arguments, 1);\n if (isReady.call(this))\n callFunc();\n else {\n if (!domReadySubscribed) {\n document.addEventListener('readystatechange', onDomReady);\n domReadySubscribed = true;\n }\n domReadyFuncs.push(callFunc); // closure is added, so every time different function will be called\n }\n\n function callFunc() {\n func.apply(self, args);\n }\n}\n\n\nfunction onDomReady() {\n document.removeEventListener('readystatechange', onDomReady);\n domReadyFuncs.forEach(function(func) { func(); });\n}\n\n\n_.extend(domReady, {\n isReady: isReady\n});\n\n\nfunction isReady() {\n var readyState = document.readyState;\n return readyState == 'loading' ? false : readyState;\n}\n", "'use strict';\n\nvar Component = require('../components/c_class')\n , Messenger = require('../messenger')\n , dragDropConfig = require('../config').dragDrop\n , componentMetaRegex = dragDropConfig.dataTypes.componentMetaRegex\n , jsonParse = require('./json_parse')\n , _ = require('mol-proto')\n , base32 = require('base32');\n\n\nmodule.exports = DragDrop;\n\n\n/**\n * Wrapper for event.dataTransfer of drag-drop HTML API\n *\n * @constructor\n * @param {event} DOM event\n * @return {DragDrop}\n */\nfunction DragDrop(event) {\n this.event = event;\n this.dataTransfer = event.dataTransfer;\n this.types = event.dataTransfer.types;\n}\n\n/**\n * Usage:\n * var testDT = new DragDrop(event);\n * testDT.setComponentMeta(newComponent, {test: 'test', test2: 'test2'});\n * testDT.getComponentMeta();\n */\n\n_.extend(DragDrop, {\n componentDataType: DragDrop$$componentDataType\n});\n\n_.extendProto(DragDrop, {\n isComponent: DragDrop$isComponent,\n getComponentState: DragDrop$getComponentState,\n setComponentState: DragDrop$setComponentState,\n getComponentMeta: DragDrop$getComponentMeta,\n setComponentMeta: DragDrop$setComponentMeta,\n getAllowedEffects: DragDrop$getAllowedEffects,\n setAllowedEffects: DragDrop$setAllowedEffects,\n getDropEffect: DragDrop$getDropEffect,\n setDropEffect: DragDrop$setDropEffect,\n isEffectAllowed: DragDrop$isEffectAllowed,\n getData: DragDrop$getData,\n setData: DragDrop$setData,\n clearData: DragDrop$clearData\n});\n\n\nfunction DragDrop$$componentDataType() {\n return dragDropConfig.dataTypes.component;\n}\n\n\nfunction DragDrop$isComponent() {\n return _.indexOf(this.types, DragDrop.componentDataType()) >= 0;\n}\n\n\nfunction DragDrop$getComponentState() {\n var dataType = DragDrop.componentDataType()\n , stateStr = this.dataTransfer.getData(dataType)\n , state = jsonParse(stateStr);\n\n return state;\n}\n\n\nfunction DragDrop$setComponentState(component, stateStr){\n if (! stateStr) {\n var state = component.getTransferState({ requestedBy: 'drag' });\n stateStr = JSON.stringify(state);\n }\n var dataType = DragDrop.componentDataType();\n\n stateStr && this.dataTransfer.setData(dataType, stateStr);\n this.dataTransfer.setData('text/html', component.el.outerHTML);\n return stateStr;\n}\n\n\nfunction DragDrop$setComponentMeta(component, params, data) {\n var meta = _componentMeta(component);\n\n var paramsStr = _.toQueryString(params);\n var dataType = dragDropConfig.dataTypes.componentMetaTemplate\n .replace('%class', _encode(meta.compClass || ''))\n .replace('%name', _encode(meta.compName || ''))\n .replace('%params', _encode(paramsStr || ''));\n\n if (data && typeof data == 'object') data = JSON.stringify(data);\n\n this.dataTransfer.setData(dataType, data || '');\n\n return dataType;\n}\n\n\nfunction _encode(str) {\n return base32.encode(str).toLowerCase();\n}\n\n\nfunction _componentMeta(component) {\n return component.transfer\n ? component.transfer.getComponentMeta()\n : { \n compClass: component.constructor.name,\n compName: component.name\n };\n}\n\n\nfunction DragDrop$getComponentMeta() {\n var match;\n var metaDataType = _.find(this.types, function (dType) {\n match = dType.match(componentMetaRegex);\n return !!match;\n });\n if (!metaDataType) return;\n\n for (var i=1; i<4; i++)\n match[i] = base32.decode(match[i]);\n\n return {\n compClass: match[1],\n compName: match[2],\n params: _.fromQueryString(match[3]),\n metaDataType: metaDataType,\n metaData: _.jsonParse(this.dataTransfer.getData(metaDataType)) \n ? _.jsonParse(this.dataTransfer.getData(metaDataType)) \n : this.dataTransfer.getData(metaDataType)\n };\n}\n\n\n// as defined here: https://developer.mozilla.org/en-US/docs/DragDrop/Drag_Operations#dragstart\nfunction DragDrop$getAllowedEffects() {\n return this.dataTransfer.effectAllowed;\n}\n\n\nfunction DragDrop$setAllowedEffects(effects) {\n this.dataTransfer.effectAllowed = effects;\n}\n\n\nfunction DragDrop$getDropEffect() {\n return this.dataTransfer.dropEffect;\n}\n\n\nfunction DragDrop$setDropEffect(effect) {\n this.dataTransfer.dropEffect = effect;\n}\n\n\nfunction DragDrop$isEffectAllowed(effect) {\n var allowedEffects = this.getAllowedEffects()\n , isCopy = effect == 'copy'\n , isMove = effect == 'move'\n , isLink = effect == 'link'\n , isAllowed = isCopy || isLink || isMove;\n\n switch (allowedEffects) {\n case 'copy':\n case 'move':\n case 'link':\n return allowedEffects == effect;\n case 'copyLink':\n return isCopy || isLink;\n case 'copyMove':\n return isCopy || isMove;\n case 'linkMove':\n return isLink || isMove;\n case 'all':\n case 'uninitialized':\n return isAllowed;\n case 'none':\n return false;\n }\n}\n\n\nfunction DragDrop$getData(dataType) {\n return this.dataTransfer.getData(dataType);\n}\n\n\nfunction DragDrop$setData(dataType, dataStr) {\n this.dataTransfer.setData(dataType, dataStr);\n}\n\n\nfunction DragDrop$clearData(dataType) {\n this.dataTransfer.clearData(dataType);\n}\n\n\n/**\n * Drag drop service compensating for the lack of communication from drop target to drag source in DOM API\n */\nvar dragDropService = new Messenger;\n\nvar _currentDragDrop, _currentDragFacet;\n\n_.extend(DragDrop, {\n service: dragDropService,\n destroy: DragDrop_destroy\n});\n\n\ndragDropService.onMessages({\n // data is DragDropDataTransfer instance\n // fired by Drag facet on \"dragstart\" event\n 'dragdropstarted': onDragDropStarted, \n // data is object with at least dropEffect property\n // fired by Drop facet on \"drop\" event\n 'dragdropcompleted': onDragDropCompleted, \n // fired by Drag facet on \"dragend\" event to complete drag\n // if drop happended in another window or if it was cancelled\n 'completedragdrop': onCompleteDragDrop\n});\n\n\n_.extend(dragDropService, {\n getCurrentDragDrop: getCurrentDragDrop\n});\n\n\nfunction onDragDropStarted(msg, data) {\n _currentDragDrop = data.dragDrop;\n _currentDragFacet = data.dragFacet;\n}\n\n\nfunction onDragDropCompleted(msg, data) {\n _currentDragFacet && _currentDragFacet.postMessageSync('dragdropcompleted', data);\n _currentDragDrop = undefined;\n _currentDragFacet = undefined;\n}\n\n\nfunction onCompleteDragDrop(msg, data) {\n if (_currentDragDrop)\n dragDropService.postMessageSync('dragdropcompleted', data);\n}\n\n\nfunction getCurrentDragDrop() {\n return _currentDragDrop;\n}\n\n\nfunction DragDrop_destroy() {\n dragDropService.offAll();\n}\n", "// \n// milo.utils.error\n// -----------\n\n'use strict';\n\nvar _ = require('mol-proto');\n\n\n// module exports error classes for all names defined in this array\nvar errorClassNames = ['AbstractClass', 'Mixin', 'Messenger', 'Component',\n 'Attribute', 'Binder', 'Loader', 'MailMessageSource', 'Facet',\n 'Scope', 'Model', 'DomFacet', 'EditableFacet',\n 'List', 'Connector', 'Registry', 'FrameMessageSource',\n 'Drop', 'Angular', 'StorageMessageSource'];\n\nvar error = {\n toBeImplemented: error$toBeImplemented,\n createClass: error$createClass\n};\n\nerrorClassNames.forEach(function(name) {\n error[name] = error$createClass(name + 'Error');\n});\n\nmodule.exports = error;\n\n\nfunction error$createClass(errorClassName) {\n var ErrorClass = _.makeFunction(errorClassName, 'message',\n 'this.name = \"' + errorClassName + '\"; \\\n this.message = message || \"There was an error\";');\n _.makeSubclass(ErrorClass, Error);\n\n return ErrorClass;\n}\n\n\nfunction error$toBeImplemented() {\n throw new error.AbstractClass('calling the method of an absctract class');\n}\n", - "'use strict';\n\n\nvar Component = require('../components/c_class')\n , BindAttribute = require('../attributes/a_bind')\n , binder = require('../binder')\n , domUtils = require('./dom')\n , logger = require('./logger')\n , check = require('./check')\n , _ = require('mol-proto');\n\n\nvar createRangePaths = _createNodesAndPathsFunc(domUtils.treePathOf);\nvar createRangeNodes = _createNodesAndPathsFunc(domUtils.getNodeAtTreePath);\n\n\nvar fragmentUtils = module.exports = {\n getState: fragment_getState,\n getStateAsync: fragment_getStateAsync,\n\n expandRangeToSiblings: expandRangeToSiblings,\n getRangeSiblings: getRangeSiblings,\n createRangeFromSiblings: createRangeFromSiblings,\n createRangePaths: createRangePaths,\n createRangeNodes: createRangeNodes,\n createRangeFromNodes: createRangeFromNodes\n};\n\n\n\n/**\n * Creates an object with the state of wrapped range with components, including partially selected. The range will be cloned and wrapped in component with container facet before getting its state.\n * This function will log error and return undefined if range has no common ancestor that has component with container facet\n * \n * @param {Range} range DOM Range instance\n * @param {Boolean} renameChildren optional parameter, `true` to rename fragment child components\n * @param {String} wrapperClassName optional parameter to wrap in a custom component class\n * @return {Object}\n */\nfunction fragment_getState(range, renameChildren, wrapperClassName) {\n var rangeContainer = _getRangeContainer(range);\n if (! rangeContainer) {\n logger.error('fragment.getState: range has no common container');\n return;\n }\n\n var frag = range.cloneContents()\n , wrapper = _wrapFragmentInContainer(frag, wrapperClassName);\n\n _transferStates(rangeContainer, wrapper);\n if (renameChildren) _renameChildren(wrapper);\n var wrapperState = wrapper.getState();\n _.deferMethod(wrapper, 'destroy');\n return wrapperState;\n}\n\n\n/**\n * Creates an object with the state of wrapped range with components, including partially selected. The range will be cloned and wrapped in component with container facet before getting its state.\n * This function will return result and any error via callback.\n * \n * @param {Range} range DOM Range instance\n * @param {Boolean} renameChildren optional parameter, `true` to rename fragment child components\n * @param {Function} callback always the last parameter, optional parameters can be dropped; result is passed via callback with any error as first parameter\n */\nfunction fragment_getStateAsync(range, renameChildren, callback) {\n try {\n var rangeContainer = _getRangeContainer(range);\n if (! rangeContainer) {\n callback(new Error('fragment.getState: range has no common container'));\n return; // do NOT connect return to previous callback, getState should return undefined\n }\n\n if (typeof renameChildren == 'function') {\n callback = renameChildren;\n renameChildren = false;\n }\n\n var frag = range.cloneContents()\n , wrapper = _wrapFragmentInContainer(frag);\n\n _transferStates(rangeContainer, wrapper);\n _.defer(function() {\n wrapper.broadcast('stateready');\n _.defer(function() {\n if (renameChildren) _renameChildren(wrapper);\n var wrapperState = wrapper.getState();\n wrapper.destroy();\n callback(null, wrapperState);\n });\n });\n } catch (err) {\n callback(err);\n }\n}\n\n\nfunction _wrapFragmentInContainer(frag, wrapperClassName) {\n var wrapEl = document.createElement('div')\n , attr = new BindAttribute(wrapEl);\n\n _.extend(attr, {\n compClass: wrapperClassName || 'Component',\n compFacets: wrapperClassName ? [] : ['container'],\n compName: 'wrapper'\n });\n\n attr.decorate();\n\n wrapEl.appendChild(frag);\n var scope = binder(wrapEl);\n return scope.wrapper;\n}\n\n\nfunction _getRangeContainer(range) {\n var el = domUtils.containingElement(range.commonAncestorContainer);\n return Component.getContainingComponent(el, true, 'container');\n}\n\n\nfunction _transferStates(fromComp, toComp) {\n var fromScope = fromComp.container.scope;\n toComp.container.scope._each(function(toChildComp, name) {\n var fromChildComp = fromScope[name];\n if (! fromChildComp) return logger.error('fragment.getState: conponent', name, 'not found in range');\n var state = fromChildComp._getState(true);\n toChildComp.setState(state);\n });\n}\n\n\nfunction _renameChildren(comp) {\n comp.container.scope._each(function(child) {\n child.rename();\n });\n}\n\n\n\nfunction expandRangeToSiblings(range) {\n var siblings = getRangeSiblings(range);\n var range = createRangeFromSiblings(siblings);\n return range;\n}\n\nfunction createRangeFromSiblings(nodes) {\n var range = document.createRange();\n if (nodes.siblings) {\n range.setStartBefore(nodes.start);\n range.setEndAfter(nodes.end);\n } else\n range.selectNode(nodes.start);\n return range;\n}\n\nfunction getRangeSiblings(range) {\n var containerNode = range.commonAncestorContainer\n , startNode = range.startContainer\n , endNode = range.endContainer;\n\n if (startNode == endNode) {\n if (startNode != containerNode) logger.error('deleteSelectionCommand logical error: start==end, but container is different');\n return { siblings: false, start: startNode };\n }\n\n if (startNode == containerNode || endNode == containerNode)\n return { siblings: false, start: containerNode };\n\n var startSibling = _findContainingChild(containerNode, startNode);\n var endSibling = _findContainingChild(containerNode, endNode);\n\n if (startSibling && endSibling) {\n if (startSibling == endSibling) {\n logger.error('deleteSelectionCommand logical error: same siblings');\n return { siblings: false, start: startSibling };\n } else\n return { siblings: true, start: startSibling, end: endSibling };\n }\n}\n\n\n\nfunction createRangeFromNodes(nodes) {\n var range = document.createRange();\n if (nodes.siblings) {\n range.setStartBefore(nodes.start);\n range.setEndAfter(nodes.end);\n } else\n range.selectNode(nodes.start);\n return range;\n}\n\n\n\nfunction _findContainingChild(containerNode, selNode) {\n return _.find(containerNode.childNodes, function(node) {\n return node.contains(selNode);\n });\n}\n\n\n\n\nfunction _createNodesAndPathsFunc(func) {\n return function(rootEl, fromObj) {\n var toObj = {\n siblings: fromObj.siblings,\n start: func(rootEl, fromObj.start)\n };\n if (toObj.siblings)\n toObj.end = func(rootEl, fromObj.end);\n return toObj;\n }\n}\n\n\n", + "'use strict';\n\n\nvar Component = require('../components/c_class')\n , BindAttribute = require('../attributes/a_bind')\n , binder = require('../binder')\n , domUtils = require('./dom')\n , logger = require('./logger')\n , check = require('./check')\n , _ = require('mol-proto');\n\n\nvar createRangePaths = _createNodesAndPathsFunc(domUtils.treePathOf);\nvar createRangeNodes = _createNodesAndPathsFunc(domUtils.getNodeAtTreePath);\n\n\nvar fragmentUtils = module.exports = {\n getState: fragment_getState,\n getStateAsync: fragment_getStateAsync,\n\n expandRangeToSiblings: expandRangeToSiblings,\n getRangeSiblings: getRangeSiblings,\n createRangeFromSiblings: createRangeFromSiblings,\n createRangeFromNodes: createRangeFromSiblings, // alias\n createRangePaths: createRangePaths,\n createRangeNodes: createRangeNodes\n};\n\n\n/**\n * Creates an object with the state of wrapped range with components, including partially selected. The range will be cloned and wrapped in component with container facet before getting its state.\n * This function will log error and return undefined if range has no common ancestor that has component with container facet\n * \n * @param {Range} range DOM Range instance\n * @param {Boolean} renameChildren optional parameter, `true` to rename fragment child components\n * @param {String} wrapperClassName optional parameter to wrap in a custom component class\n * @return {Object}\n */\nfunction fragment_getState(range, renameChildren, wrapperClassName) {\n var rangeContainer = _getRangeContainer(range);\n if (! rangeContainer) {\n logger.error('fragment.getState: range has no common container');\n return;\n }\n\n var frag = range.cloneContents()\n , wrapper = _wrapFragmentInContainer(frag, wrapperClassName);\n\n _transferStates(rangeContainer, wrapper);\n if (renameChildren) _renameChildren(wrapper);\n var wrapperState = wrapper.getState();\n _.deferMethod(wrapper, 'destroy');\n return wrapperState;\n}\n\n\n/**\n * Creates an object with the state of wrapped range with components, including partially selected. The range will be cloned and wrapped in component with container facet before getting its state.\n * This function will return result and any error via callback.\n * \n * @param {Range} range DOM Range instance\n * @param {Boolean} renameChildren optional parameter, `true` to rename fragment child components\n * @param {Function} callback always the last parameter, optional parameters can be dropped; result is passed via callback with any error as first parameter\n */\nfunction fragment_getStateAsync(range, renameChildren, callback) {\n try {\n var rangeContainer = _getRangeContainer(range);\n if (! rangeContainer) {\n callback(new Error('fragment.getState: range has no common container'));\n return; // do NOT connect return to previous callback, getState should return undefined\n }\n\n if (typeof renameChildren == 'function') {\n callback = renameChildren;\n renameChildren = false;\n }\n\n var frag = range.cloneContents()\n , wrapper = _wrapFragmentInContainer(frag);\n\n _transferStates(rangeContainer, wrapper);\n _.defer(function() {\n wrapper.broadcast('stateready');\n _.defer(function() {\n if (renameChildren) _renameChildren(wrapper);\n var wrapperState = wrapper.getState();\n wrapper.destroy();\n callback(null, wrapperState);\n });\n });\n } catch (err) {\n callback(err);\n }\n}\n\n\nfunction _wrapFragmentInContainer(frag, wrapperClassName) {\n var wrapEl = document.createElement('div')\n , attr = new BindAttribute(wrapEl);\n\n _.extend(attr, {\n compClass: wrapperClassName || 'Component',\n compFacets: wrapperClassName ? [] : ['container'],\n compName: 'wrapper'\n });\n\n attr.decorate();\n\n wrapEl.appendChild(frag);\n var scope = binder(wrapEl);\n return scope.wrapper;\n}\n\n\nfunction _getRangeContainer(range) {\n var el = domUtils.containingElement(range.commonAncestorContainer);\n return Component.getContainingComponent(el, true, 'container');\n}\n\n\nfunction _transferStates(fromComp, toComp) {\n var fromScope = fromComp.container.scope;\n toComp.container.scope._each(function(toChildComp, name) {\n var fromChildComp = fromScope[name];\n if (! fromChildComp) return logger.error('fragment.getState: conponent', name, 'not found in range');\n var state = fromChildComp._getState(true);\n toChildComp.setState(state);\n });\n}\n\n\nfunction _renameChildren(comp) {\n comp.container.scope._each(function(child) {\n child.rename();\n });\n}\n\n\nfunction expandRangeToSiblings(range) {\n var siblings = getRangeSiblings(range);\n range = createRangeFromSiblings(siblings);\n return range;\n}\n\n\nfunction createRangeFromSiblings(nodes) {\n var range = document.createRange();\n if (nodes.siblings) {\n range.setStartBefore(nodes.start);\n range.setEndAfter(nodes.end);\n } else\n range.selectNode(nodes.start);\n return range;\n}\n\n\nfunction getRangeSiblings(range) {\n var containerNode = range.commonAncestorContainer\n , startNode = range.startContainer\n , endNode = range.endContainer;\n\n if (startNode == endNode) {\n if (startNode != containerNode) logger.error('deleteSelectionCommand logical error: start==end, but container is different');\n return { siblings: false, start: startNode };\n }\n\n if (startNode == containerNode || endNode == containerNode)\n return { siblings: false, start: containerNode };\n\n var startSibling = _findContainingChild(containerNode, startNode);\n var endSibling = _findContainingChild(containerNode, endNode);\n\n if (startSibling && endSibling) {\n if (startSibling == endSibling) {\n logger.error('deleteSelectionCommand logical error: same siblings');\n return { siblings: false, start: startSibling };\n } else\n return { siblings: true, start: startSibling, end: endSibling };\n }\n}\n\n\nfunction _findContainingChild(containerNode, selNode) {\n return _.find(containerNode.childNodes, function(node) {\n return node.contains(selNode);\n });\n}\n\n\nfunction _createNodesAndPathsFunc(func) {\n return function(rootEl, fromObj) {\n var toObj = {\n siblings: fromObj.siblings,\n start: func(rootEl, fromObj.start)\n };\n if (toObj.siblings)\n toObj.end = func(rootEl, fromObj.end);\n return toObj;\n };\n}\n\n\n", "'use strict';\n\n/**\n * `milo.util`\n */\nvar util = {\n logger: require('./logger'),\n request: require('./request'),\n websocket: require('./websocket'),\n check: require('./check'),\n error: require('./error'),\n count: require('./count'), // deprecated\n uniqueId: require('./count'),\n componentName: require('./component_name'),\n dom: require('./dom'),\n domListeners: require('./dom_listeners'),\n selection: require('./selection'),\n fragment: require('./fragment'),\n jsonParse: require('./json_parse'),\n storage: require('./storage'),\n domReady: require('./domready'),\n dragDrop: require('./dragdrop'),\n dialog: require('../components/ui/bootstrap/Dialog'),\n alert: require('../components/ui/bootstrap/Alert'),\n doT: require('dot'),\n destroy: util_destroy\n};\n\nmodule.exports = util;\n\n\nfunction util_destroy() {\n util.request.destroy();\n util.dragDrop.destroy();\n}\n", "'use strict';\n\n\nmodule.exports = jsonParse;\n\n\n/**\n * `milo.util.jsonParse`\n * Safe JSON.parse, returns undefined if JSON.parse throws an exception\n *\n * @param {String} str - JSON string representation of object\n * @return {Object|undefined}\n */\nfunction jsonParse(str) {\n try {\n return JSON.parse(str);\n } catch (e) {}\n}\n", "'use strict';\n\n// \n// milo.utils.logger\n// -----------\n\n// Application logger that has error, warn, info and debug\n// methods, that can be suppressed by setting log level.\n\n// Properties:\n\n// - level\n\n// - 0 - error\n// - 1 - warn\n// - 2 - info\n// - 3 - debug (default)\n\n// - enabled\n\n// true by default. Set to false to disable all logging in browser console.\n\n\nvar Logger = require('./logger_class');\n\nvar logger = new Logger({ level: 3 });\n\nmodule.exports = logger;\n", "'use strict';\n\n// ### Logger Class\n\n// Properties:\n\n// - level\n\n// - 0 - error\n// - 1 - warn\n// - 2 - info\n// - 3 - debug (default)\n\n// - enabled\n\n// true by default. Set to false to disable all logging in browser console.\n\n\nvar _ = require('mol-proto');\n\n\n/**\n * Log levels.\n */\n\nvar levels = [\n 'error',\n 'warn',\n 'info',\n 'debug'\n];\n\nvar maxLevelLength = Math.max.apply(Math, levels.map(function(level) { return level.length; }));\n\n/**\n * Colors for log levels.\n */\n\nvar colors = [\n 31,\n 33,\n 36,\n 90\n];\n\n/**\n * Pads the nice output to the longest log level.\n */\nfunction pad(str) {\n if (str.length < maxLevelLength)\n return str + new Array(maxLevelLength - str.length + 1).join(' ');\n\n return str;\n};\n\n\nfunction colored(str, color) {\n return '\\x1B[' + color + 'm' + str + ' -\\x1B[39m';\n}\n\n\nvar DEFAULT_OPTIONS = {\n level: 3,\n throwLevel: -1, // never throw\n enabled: true,\n logPrefix: ''\n}\n\n\n/**\n * Logger (console).\n *\n * @api public\n */\nvar Logger = function (opts) {\n _.extend(this, DEFAULT_OPTIONS);\n _.extend(this, opts || {});\n};\n\n\n/**\n * Log method.\n *\n * @api public\n */\n\nLogger.prototype.log = function (type) {\n var index = levels.indexOf(type);\n\n if (! this.enabled || index > this.level)\n return this;\n\n var args = _.slice(arguments, 1);\n\n if (index <= this.throwLevel)\n throw new Error([this.logPrefix, type + ':'].concat(args).join(' '));\n\n console.log.apply(\n console\n , [ this.logPrefixColor\n ? ' ' + colored(this.logPrefix, this.logPrefixColor)\n : this.logPrefix,\n (this.colors\n ? ' ' + colored(pad(type), colors[index])\n : type) + ':'\n ].concat(args)\n );\n\n return this;\n};\n\n/**\n * Generate methods.\n */\n\nlevels.forEach(function (name) {\n Logger.prototype[name] = function () {\n this.log.apply(this, [name].concat(_.toArray(arguments)));\n };\n});\n\n\nmodule.exports = Logger;\n", "'use strict';\n\n// milo.utils.request\n// -----------\n\n// Convenience functions wrapping XMLHTTPRequest functionality.\n\n// ```\n// var request = milo.utils.request\n// , opts: { method: 'GET' };\n\n// request(url, opts, function(err, data) {\n// logger.debug(data);\n// });\n\n// request.get(url, function(err, data) {\n// logger.debug(data);\n// });\n// ```\n\n// Only generic request and get, json, post convenience methods are currently implemented.\n\n\nvar _ = require('mol-proto')\n , count = require('./count')\n , config = require('../config')\n , logger = require('./logger')\n , Messenger = require('../messenger');\n\nmodule.exports = request;\n\n\nvar _pendingRequests = [];\n\nvar promiseThen = createPromiseOverride('then');\nvar promiseCatch = createPromiseOverride('catch');\n\n/**\n * Creates a function which is used to override standard promise behaviour and allow promise instances \n * created to maintain a reference to the request object no matter if .then() or .catch() is called.\n */\nfunction createPromiseOverride(functionName) {\n return function() {\n var promise = Promise.prototype[functionName].apply(this, arguments);\n keepRequestObject(promise, this._request);\n return promise;\n }\n}\n\n\nfunction request(url, opts, callback) {\n opts.url = url;\n opts.contentType = opts.contentType || 'application/json;charset=UTF-8';\n if (_messenger) request.postMessageSync('request', { options: opts });\n\n var req = new XMLHttpRequest();\n req.open(opts.method, opts.url, true);\n req.setRequestHeader('Content-Type', opts.contentType);\n setRequestHeaders(req, opts.headers);\n\n req.timeout = opts.timeout || config.request.defaults.timeout;\n req.onreadystatechange = req.ontimeout = req.onabort = onReady;\n\n var xPromise = _createXPromise(req);\n\n req.send(JSON.stringify(opts.data));\n req[config.request.optionsKey] = opts;\n\n _pendingRequests.push(req);\n\n return xPromise.promise;\n\n function onReady(e) {\n _onReady(req, callback, xPromise, e.type);\n }\n}\n\n\nfunction _createXPromise(request) {\n var resolvePromise, rejectPromise;\n var promise = new Promise(function(resolve, reject) {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n keepRequestObject(promise, request);\n promise.catch(_.noop); // Sometimes errors are handled within callbacks, so uncaught promise error message should be suppressed.\n\n return {\n promise: promise,\n resolve: resolvePromise,\n reject: rejectPromise\n }\n}\n\n// Ensures that the promise (and any promises created when calling .then/.catch) has a reference to the original request object\nfunction keepRequestObject(promise, request) {\n promise._request = request;\n promise.then = promiseThen;\n promise.catch = promiseCatch;\n\n return promise;\n}\n\n\nfunction setRequestHeaders(req, headers) {\n if (headers)\n _.eachKey(headers, function(value, key) {\n req.setRequestHeader(key, value);\n });\n}\n\nfunction _onReady(req, callback, xPromise, eventType) {\n if (req.readyState != 4) return;\n if (!req.status && eventType == 'readystatechange') return;\n\n _.spliceItem(_pendingRequests, req);\n\n var error;\n try {\n if ( req.status >= 200 && req.status < 400 ) {\n try {\n postMessage('success');\n callback && callback(null, req.responseText, req);\n } catch(e) { error = e; }\n xPromise.resolve(req.responseText);\n }\n else {\n var errorReason = req.status || eventType;\n try {\n postMessage('error');\n postMessage('error' + errorReason);\n callback && callback(errorReason, req.responseText, req);\n } catch(e) { error = e; }\n xPromise.reject({ reason: errorReason, response: req.responseText });\n }\n } catch(e) {\n error = error || e;\n }\n\n // not removing subscription creates memory leak, deleting property would not remove subscription\n req.onreadystatechange = req.ontimeout = req.onabort = undefined;\n\n if (!_pendingRequests.length)\n postMessage('requestscompleted');\n\n if (error) throw new Error('Exception: ' + error);\n\n function postMessage(msg) {\n if (_messenger) request.postMessage(msg,\n { status: status, response: req.responseText });\n }\n}\n\n\n_.extend(request, {\n get: request$get,\n post: request$post,\n json: request$json,\n jsonp: request$jsonp,\n file: request$file,\n useMessenger: request$useMessenger,\n destroy: request$destroy,\n whenRequestsCompleted: whenRequestsCompleted\n});\n\n\nvar _messenger;\n\n\nfunction request$useMessenger() {\n _messenger = new Messenger(request, ['on', 'once', 'onSync', 'off', 'onMessages', 'offMessages', 'postMessage', 'postMessageSync']);\n}\n\n\nfunction request$get(url, callback) {\n return request(url, { method: 'GET' }, callback);\n}\n\n\nfunction request$post(url, data, callback) {\n return request(url, { method: 'POST', data: data }, callback);\n}\n\n\nfunction request$json(url, callback) {\n var promise = request(url, { method: 'GET' });\n\n var jsonPromise = promise.then(JSON.parse);\n\n if (callback)\n jsonPromise\n .then(function(data) { callback(null, data); })\n .catch(function(errData) { callback(errData.reason, errData.response); });\n\n return jsonPromise;\n}\n\n\nvar jsonpOptions = { method: 'GET', jsonp: true };\nfunction request$jsonp(url, callback) {\n var script = document.createElement('script'),\n xPromise = _createXPromise(script),\n head = window.document.head,\n uniqueCallback = config.request.jsonpCallbackPrefix + count();\n\n var opts = _.extend({ url: url }, jsonpOptions);\n if (_messenger) request.postMessageSync('request', { options: opts });\n\n if (! _.isEqual(_.omitKeys(opts, 'url'), jsonpOptions))\n logger.warn('Ignored not allowed request options change in JSONP request - only URL can be changed');\n\n var timeout = setTimeout(function() {\n var err = new Error('No JSONP response or no callback in response');\n _onResult(err);\n }, config.request.jsonpTimeout);\n\n window[uniqueCallback] = _.partial(_onResult, null);\n\n _pendingRequests.push(window[uniqueCallback]);\n\n script.type = 'text/javascript';\n script.src = opts.url + (opts.url.indexOf('?') == -1 ? '?' : '&') + 'callback=' + uniqueCallback;\n\n head.appendChild(script);\n\n return xPromise.promise;\n\n\n function _onResult(err, result) {\n _.spliceItem(_pendingRequests, window[uniqueCallback]);\n try {\n postMessage(err ? 'error' : 'success', err, result);\n if (err) {\n logger.error('No JSONP response or timeout');\n postMessage('errorjsonptimeout', err);\n }\n callback && callback(err, result);\n }\n catch(e) { var error = e; }\n if (err) xPromise.reject(err);\n else xPromise.resolve(result);\n\n cleanUp();\n if (!_pendingRequests.length)\n postMessage('requestscompleted');\n\n if (error) throw error;\n }\n\n\n function cleanUp() {\n clearTimeout(timeout);\n head.removeChild(script);\n delete window[uniqueCallback];\n }\n\n\n function postMessage(msg, status, result) {\n if (_messenger) request.postMessage(msg,\n { status: status, response: result });\n }\n}\n\n\nfunction request$file(opts, fileData, callback, progress) {\n if (typeof opts == 'string')\n opts = { method: 'POST', url: opts };\n\n opts.method = opts.method || 'POST';\n opts.file = true;\n\n if (_messenger) request.postMessageSync('request', { options: opts });\n\n var req = new XMLHttpRequest();\n if (progress) req.upload.onprogress = progress;\n\n req.open(opts.method, opts.url, true);\n setRequestHeaders(req, opts.headers);\n\n req.timeout = opts.timeout || config.request.defaults.timeout;\n req.onreadystatechange = req.ontimeout = req.onabort = onReady;\n\n var xPromise = _createXPromise(req);\n\n if (opts.binary)\n req.send(fileData);\n else {\n var formData = new FormData();\n formData.append('file', fileData);\n req.send(formData);\n }\n\n _pendingRequests.push(req);\n\n return xPromise.promise;\n\n function onReady(e) {\n if (progress) req.upload.onprogress = undefined;\n _onReady(req, callback, xPromise, e.type);\n }\n}\n\n\nfunction request$destroy() {\n if (_messenger) _messenger.destroy();\n request._destroyed = true;\n}\n\n\nfunction whenRequestsCompleted(callback, timeout) {\n callback = _.once(callback);\n if (timeout)\n _.delay(callback, timeout, 'timeout');\n\n if (_pendingRequests.length)\n _messenger.once('requestscompleted', callback);\n else\n _.defer(callback);\n}\n", "'use strict';\n\n\nvar domUtils = require('../dom')\n , containingElement = domUtils.containingElement\n , setCaretPosition = domUtils.setCaretPosition\n , getComponentsFromRange = domUtils.getComponentsFromRange\n , deleteRangeWithComponents = domUtils.deleteRangeWithComponents\n , logger = require('../logger')\n , Component = require('../../components/c_class')\n , _ = require('mol-proto');\n\nmodule.exports = TextSelection;\n\n\n/**\n * Text selection class.\n * Serves as a helper to manage current selection\n * The object cannot be reused, if the selection changes some of its properties may contain information related to previous selection\n *\n * @param {Window} win window in which text selection is processed\n */\nfunction TextSelection(win) {\n if (! this instanceof TextSelection)\n return new TextSelection(win);\n this.window = win || window;\n this.init();\n}\n\n\n/**\n * TextSelection instance method\n * Returns selection start element\n *\n * @return {Element|null}\n */\nvar TextSelection$startElement = \n _.partial(_getElement, '_startElement', 'startContainer');\n\n\n/**\n * TextSelection instance method\n * Returns selection end element\n *\n * @return {Element|null}\n */\nvar TextSelection$endElement = \n _.partial(_getElement, '_endElement', 'endContainer');\n\n\n/**\n * TextSelection instance method\n * Returns selection end element\n *\n * @return {Element|null}\n */\nvar TextSelection$containingElement = \n _.partial(_getElement, '_containingElement', 'commonAncestorContainer');\n\n\n/**\n * TextSelection instance method\n * Returns selection start Component\n *\n * @return {Component}\n */\nvar TextSelection$startComponent = \n _.partial(_getComponent, '_startComponent', 'startElement');\n\n\n/**\n * TextSelection instance method\n * Returns selection end Component\n *\n * @return {Component}\n */\nvar TextSelection$endComponent = \n _.partial(_getComponent, '_endComponent', 'endElement');\n\n\n/**\n * TextSelection instance method\n * Returns selection end Component\n *\n * @return {Component}\n */\nvar TextSelection$containingComponent = \n _.partial(_getComponent, '_containingComponent', 'containingElement');\n\n\n_.extendProto(TextSelection, {\n init: TextSelection$init,\n text: TextSelection$text,\n textNodes: TextSelection$textNodes,\n clear: TextSelection$clear,\n\n startElement: TextSelection$startElement,\n endElement: TextSelection$endElement,\n containingElement: TextSelection$containingElement,\n\n startComponent: TextSelection$startComponent,\n endComponent: TextSelection$endComponent,\n containingComponent: TextSelection$containingComponent,\n\n containedComponents: TextSelection$containedComponents,\n eachContainedComponent: TextSelection$eachContainedComponent,\n del: TextSelection$del,\n _getPostDeleteSelectionPoint: _getPostDeleteSelectionPoint,\n _selectAfterDelete: _selectAfterDelete,\n\n getRange: TextSelection$getRange,\n getState: TextSelection$getState,\n getNormalizedRange: TextSelection$$getNormalizedRange,\n getDirection: TextSelection$$getDirection\n});\n\n\n_.extend(TextSelection, {\n createFromRange: TextSelection$$createFromRange,\n createFromState: TextSelection$$createFromState,\n createStateObject: TextSelection$$createStateObject\n});\n\n\n/**\n * TextSelection instance method\n * Initializes TextSelection from the current selection\n */\nfunction TextSelection$init() {\n this.selection = this.window.getSelection();\n if (this.selection.rangeCount)\n this.range = this.selection.getRangeAt(0);\n this.isCollapsed = this.selection.isCollapsed;\n}\n\n\n/**\n * TextSelection instance method\n * Retrieves and returns selection text\n *\n * @return {String}\n */\nfunction TextSelection$text() {\n if (! this.range) return undefined;\n\n if (! this._text)\n this._text = this.range.toString();\n\n return this._text;\n}\n\n\n/**\n * TextSelection instance method\n * Retrieves and returns selection text nodes\n *\n * @return {Array[Node]}\n */\nfunction TextSelection$textNodes() {\n if (! this.range) return undefined;\n\n if (! this._textNodes)\n this._textNodes = _getTextNodes.call(this);\n return this._textNodes;\n}\n\n\nfunction TextSelection$clear() {\n this.selection.removeAllRanges();\n}\n\n\n/**\n * Retrieves text and text nodes from selection saving them on properties of object\n *\n * @private\n * @param {TextSelection} this\n */\nfunction _getTextNodes() {\n // list of selected text nodes\n var textNodes = [];\n\n if (this.isCollapsed)\n return textNodes;\n\n // create TreeWalker to traverse the tree to select all text nodes\n var selStart = this.range.startContainer\n , selEnd = this.range.endContainer\n , rangeContainer = this.range.commonAncestorContainer;\n\n var treeWalker = this.window.document.createTreeWalker(rangeContainer, NodeFilter.SHOW_TEXT);\n var node = treeWalker.currentNode = selStart;\n\n // traverse DOM tree to collect all selected text nodes\n while (node && (! inEnd || selEnd.contains(node))) {\n textNodes.push(node);\n var inEnd = inEnd || selEnd.contains(node);\n node = treeWalker.nextNode();\n }\n return textNodes;\n}\n\n\n/**\n * Retrieves and returns start/end element from selection saving them on properties of object\n *\n * @private\n * @param {TextSelection} this\n * @return {Element|null}\n */\nfunction _getElement(thisPropName, rangePropName) {\n if (! this.range) return undefined;\n\n if (typeof this[thisPropName] == 'undefined')\n this[thisPropName] = containingElement(this.range[rangePropName]);\n return this[thisPropName];\n}\n\n\n/**\n * Retrieves and returns start/end component from selection saving them on properties of object\n *\n * @private\n * @param {TextSelection} this\n * @return {Component}\n */\nfunction _getComponent(thisPropName, elMethodName) {\n if (! this.range) return undefined;\n\n if (typeof this[thisPropName] == 'undefined')\n this[thisPropName] = Component.getContainingComponent(this[elMethodName]());\n return this[thisPropName];\n}\n\n\nfunction TextSelection$containedComponents() {\n if (this._containedComponents)\n return this._containedComponents;\n\n var components = this._containedComponents = [];\n\n if (this.isCollapsed || ! this.range) return components;\n\n return getComponentsFromRange(this.range);\n}\n\n\nfunction TextSelection$eachContainedComponent(callback, thisArg) {\n if (this.isCollapsed || ! this.range) return;\n\n var components = this.containedComponents();\n\n components.forEach(callback, thisArg);\n}\n\n\n/**\n * TextSelection instance method\n * Deletes the current selection and all components in it\n * \n * @param {Boolean} selectEndContainer set to true if the end container should be selected after deletion\n */\nfunction TextSelection$del(selectEndContainer) {\n if (this.isCollapsed || ! this.range) return;\n\n var selPoint = this._getPostDeleteSelectionPoint(selectEndContainer);\n\n deleteRangeWithComponents(this.range);\n\n this._selectAfterDelete(selPoint);\n selPoint.node.parentNode.normalize();\n}\n\n\nfunction _getPostDeleteSelectionPoint(selectEndContainer) {\n var selNode = this.range.startContainer;\n var selOffset = this.range.startOffset;\n if (selectEndContainer && this.range.startContainer != this.range.endContainer) {\n selNode = this.range.endContainer;\n selOffset = 0;\n }\n return { node: selNode, offset: selOffset };\n}\n\n\nfunction _selectAfterDelete(selPoint) {\n var selNode = selPoint.node\n , selOffset = selPoint.offset;\n\n if (!selNode) return;\n if (selNode.nodeType == Node.TEXT_NODE)\n selNode.textContent = selNode.textContent.trimRight();\n if (!selNode.nodeValue)\n selNode.nodeValue = '\\u00A0'; //non-breaking space, \\u200B for zero width space;\n\n var position = selOffset > selNode.length ? selNode.length : selOffset;\n setCaretPosition(selNode, position);\n}\n\n\n/**\n * Returns selection range\n *\n * @return {Range}\n */\nfunction TextSelection$getRange() {\n return this.range;\n}\n\n\n/**\n * Stores selection window, nodes and offsets in object\n */\nfunction TextSelection$getState(rootEl) {\n var r = this.range;\n var doc = rootEl.ownerDocument\n , win = doc.defaultView || doc.parentWindow;\n if (!r) return { window: win };\n return TextSelection.createStateObject(rootEl, r.startContainer, r.startOffset, r.endContainer, r.endOffset);\n}\n\n\nfunction TextSelection$$createStateObject(rootEl, startContainer, startOffset, endContainer, endOffset) {\n endContainer = endContainer || startContainer;\n endOffset = endOffset || startOffset;\n var doc = rootEl.ownerDocument\n , win = doc.defaultView || doc.parentWindow;\n return {\n window: win,\n rootEl: rootEl,\n start: _getSelectionPointState(rootEl, startContainer, startOffset),\n end: _getSelectionPointState(rootEl, endContainer, endOffset)\n };\n}\n\n\nfunction _getSelectionPointState(rootEl, node, offset) {\n var treePath = domUtils.treePathOf(rootEl, node);\n if (! treePath) logger.error('Selection point is outside of root element');\n return {\n treePath: treePath,\n offset: offset\n };\n}\n\n\n/**\n * Restores actual selection to the stored range\n */\nfunction TextSelection$$createFromState(state) {\n var domUtils = state.window.milo.util.dom;\n\n if (state.rootEl && state.start && state.end) {\n var startNode = _selectionNodeFromState(state.rootEl, state.start)\n , endNode = _selectionNodeFromState(state.rootEl, state.end);\n\n try {\n domUtils.setSelection(startNode, state.start.offset, endNode, state.end.offset);\n return new TextSelection(state.window);\n } catch(e) {\n logger.error('Text selection: can\\'t create selection', e, e.message);\n }\n } else {\n domUtils.clearSelection(state.window);\n return new TextSelection(state.window);\n }\n}\n\n\nfunction _selectionNodeFromState(rootEl, pointState) {\n var node = domUtils.getNodeAtTreePath(rootEl, pointState.treePath);\n if (! node) logger.error('TextSelection createFromState: no node at treePath');\n return node;\n}\n\n\n/**\n * Creates selection from passed range\n * \n * @param {Range} range\n * @param {Boolean} backward\n *\n * @return {TextSelection}\n */\nfunction TextSelection$$createFromRange(range, backward) {\n var win = range.startContainer.ownerDocument.defaultView\n , sel = win.getSelection()\n , endRange;\n\n sel.removeAllRanges();\n\n if (backward){\n endRange = range.cloneRange();\n endRange.collapse(false);\n\n sel.addRange(endRange);\n sel.extend(range.startContainer, range.startOffset) \n }\n else {\n sel.addRange(range);\n }\n\n return new TextSelection(win);\n}\n\n/**\n * Returns a normalized copy of the range\n * If you triple click an item, the end of the range is positioned at the beginning of the NEXT node.\n * this function returns a range with the end positioned at the end of the last textnode contained \n * inside a component with the \"editable\" facet\n * \n * @return {range}\n */\nfunction TextSelection$$getNormalizedRange(){\n var doc = this.range.commonAncestorContainer.ownerDocument\n , tw, previousNode\n , newRange = this.range.cloneRange();\n\n if (newRange.endContainer.nodeType !== Node.TEXT_NODE) {\n tw = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);\n tw.currentNode = newRange.endContainer;\n previousNode = tw.previousNode();\n newRange.setEnd(previousNode, previousNode.length);\n }\n\n return newRange;\n}\n\n/**\n * get the direction of a selection\n *\n * 1 forward, -1 backward, 0 no direction, undefined one of the node is detached or in a different frame\n *\n * @return {-1|0|1|undefined}\n */\nfunction TextSelection$$getDirection(){\n return domUtils.getSelectionDirection(this.selection); \n}\n\n", - "'use strict';\n\n\nvar DOMStorageError = require('../error').createClass('DomStorageError')\n , Messenger = require('../../messenger')\n , StorageMessageSource = require('./msg_src')\n , config = require('../../config')\n , jsonParse = require('../json_parse')\n , _ = require('mol-proto')\n , check = require('../check')\n , Match = check.Match;\n\n\nmodule.exports = DOMStorage;\n\n\n// shared keys stored by all instances, include key prefixes\nvar _storedKeys = {\n true: {}, // session storage\n false: {} // local storage\n};\n\n\n/**\n * DOMStorage class to simplify storage and retrieval of multiple items with types preservation to DOM storage (localStorage and sessionStorage).\n * Types will be stored in the key created from value keys with appended `milo.config.domStorage.typeSuffix`\n *\n * @param {String} keyPrefix prefix that will be added to all keys followed by `milo.config.domStorage.prefixSeparator` (\"/\" by default).\n * @param {Boolean} sessionOnly true to use sessionStorage. localStorage will be used by default.\n * @param {Window} win window to work in\n */\nfunction DOMStorage(keyPrefix, sessionOnly, win) {\n if (typeof window == 'undefined') return;\n win = win || window;\n\n keyPrefix = config.domStorage.root +\n (keyPrefix\n ? keyPrefix + config.domStorage.prefixSeparator\n : '');\n\n _.defineProperties(this, {\n keyPrefix: keyPrefix,\n sessionOnly: !! sessionOnly,\n window: win,\n _storage: sessionOnly ? win.sessionStorage : win.localStorage,\n _typeSuffix: config.domStorage.typeSuffix,\n _keys: {}\n }, _.WRIT);\n}\n\n\n_.extendProto(DOMStorage, {\n get: DOMStorage$get,\n set: DOMStorage$set,\n remove: DOMStorage$remove,\n hasItem: DOMStorage$hasItem,\n getItem: DOMStorage$getItem,\n setItem: DOMStorage$setItem,\n removeItem: DOMStorage$removeItem,\n _storageKey: DOMStorage$_storageKey,\n _domStorageKey: DOMStorage$_domStorageKey,\n getAllKeys: DOMStorage$getAllKeys,\n getAllItems: DOMStorage$getAllItems,\n createMessenger: DOMStorage$createMessenger,\n destroy: DOMStorage$destroy\n});\n\n\n/**\n * Expose Mesenger and MessageSource methods on DOMStorage\n */\nMessenger.useWith(DOMStorage, '_messenger', Messenger.defaultMethods);\nStorageMessageSource.useWith(DOMStorage, '_messageSource', ['trigger']);\n\n\nvar _sessionStorage = new DOMStorage('', true)\n , _localStorage = new DOMStorage('', false);\n\nvar _domStorage = {\n true: _sessionStorage,\n false: _localStorage\n };\n\n_.extend(DOMStorage, {\n registerDataType: DOMStorage$$registerDataType,\n local: _localStorage,\n session: _sessionStorage,\n storage: _domStorage,\n _storedKeys: _storedKeys // exposed for testing\n});\n\n\n/**\n * Sets data to DOM storage. `this.keyPrefix` is prepended to keys.\n *\n * @param {Object} data single object can be passed in which case keys will be used as keys in local storage.\n * @param {List} arguments alternatively just the list of arguments can be passed where arguments can be sequentially used as keys and values.\n */\nfunction DOMStorage$set(data) { // or arguments\n if (typeof data == 'object')\n _.eachKey(data, function(value, key) {\n this.setItem(key, value);\n }, this);\n else {\n var argsLen = arguments.length;\n if (argsLen % 2)\n throw new DomStorageError('DOMStorage: set should have even number of arguments or object');\n\n for (var i = 0; i < argsLen; i++) {\n var key = arguments[i]\n , value = arguments[++i];\n\n this.setItem(key, value);\n }\n }\n}\n\n\n/**\n * Gets data from DOM storage. `this.keyPrefix` is prepended to passed keys, but returned object will have keys without root keys.\n *\n * @param {List} arguments keys can be passed as strings or arrays of strings\n * @returns {Object}\n */\nfunction DOMStorage$get() { // , ... arguments\n var data = {};\n _.deepForEach(arguments, function(key) {\n data[key] = this.getItem(key);\n }, this);\n return data;\n}\n\n\n/**\n * Removes keys from DOM storage. `this.keyPrefix` is prepended to passed keys.\n *\n * @param {List} arguments keys can be passed as strings or arrays of strings\n */\nfunction DOMStorage$remove() { //, ... arguments\n _.deepForEach(arguments, function(key) {\n this.removeItem(key);\n }, this);\n}\n\n\n/**\n * Check for presence of single item in DOM storage. `this.keyPrefix` is prepended to passed key.\n *\n * @param {String} key\n * @return {Boolean}\n */\nfunction DOMStorage$hasItem(key) {\n var pKey = this._storageKey(key);\n return this._storage.getItem(pKey) != null;\n}\n\n\n/**\n * Gets single item from DOM storage prepending `this.keyPrefix` to passed key.\n * Reads type of the originally stored value from `key + this._typeSuffix` and converts data to the original type.\n *\n * @param {String} key\n * @return {Any}\n */\nfunction DOMStorage$getItem(key) {\n var pKey = this._storageKey(key);\n var dataType = _getKeyDataType.call(this, pKey);\n var valueStr = this._storage.getItem(pKey);\n var value = _parseData(valueStr, dataType);\n return value;\n}\n\n\n/**\n * Sets single item to DOM storage prepending `this.keyPrefix` to passed key.\n * Stores type of the stored value to `key + this._typeSuffix`.\n *\n * @param {String} key\n * @return {Any}\n */\nfunction DOMStorage$setItem(key, value) {\n var pKey = this._storageKey(key);\n var dataType = _setKeyDataType.call(this, pKey, value);\n var valueStr = _serializeData(value, dataType);\n try {\n this._storage.setItem(pKey, valueStr);\n } catch(e) {\n if (e.name == 'QuotaExceededError') {\n var cfg = config.domStorage.quotaExceeded;\n if (cfg.message)\n milo.mail.postMessage('quotaexceedederror', value);\n if (cfg.throwError)\n throw e;\n } else\n throw e;\n }\n this._keys[key] = true;\n _domStorage[this.sessionOnly]._keys[pKey] = true;\n}\n\n\n/**\n * Removes single item from DOM storage prepending `this.keyPrefix` to passed key.\n * Type of the stored value (in `key + this._typeSuffix` key) is also removed.\n *\n * @param {String} key\n * @return {Any}\n */\nfunction DOMStorage$removeItem(key) {\n var pKey = this._storageKey(key);\n this._storage.removeItem(pKey);\n _removeKeyDataType.call(this, pKey)\n delete this._keys[key];\n delete _domStorage[this.sessionOnly]._keys[pKey];\n}\n\n\n/**\n * Returns the array of all keys stored by this instance of DOMStorage\n *\n * @return {Array}\n */\nfunction DOMStorage$getAllKeys() {\n var storedKeys = Object.keys(this._keys);\n var keysInStorage = storedKeys.filter(function(key) {\n if (this.hasItem(key)) return true;\n else delete this._keys[key];\n }, this);\n return keysInStorage;\n}\n\n\n/**\n * Returns the map with all keys and values (deserialized) stored using this instance of DOMStorage\n *\n * @return {Object}\n */\nfunction DOMStorage$getAllItems() {\n return this.get(this.getAllKeys());\n}\n\n\n/**\n * Returns prefixed key for DOM storage for given unprefixed key.\n *\n * @param {String} key\n * @return {String}\n */\nfunction DOMStorage$_storageKey(key) {\n return this.keyPrefix + key;\n}\n\n\n/**\n * Returns unprefixed key to be used with this instance of DOMStorage fir given actual key in storage\n * If key has different prefix from the keyPrefix returns undefined\n *\n * @param {String} storageKey actual key in local/session storage\n * @return {String}\n */\nfunction DOMStorage$_domStorageKey(storageKey) {\n if (storageKey.indexOf(this._typeSuffix) >= 0) return;\n return _.unPrefix(storageKey, this.keyPrefix);\n}\n\n\n/**\n * Gets originally stored data type for given (prefixed) `key`.\n *\n * @param {String} pKey prefixed key of stored value\n * @return {String}\n */\nfunction _getKeyDataType(pKey) {\n pKey = _dataTypeKey.call(this, pKey);\n return this._storage.getItem(pKey);\n}\n\n\n/**\n * Stores data type for given (prefixed) `key` and `value`.\n * Returns data type for `value`.\n *\n * @param {String} pKey prefixed key of stored value\n * @param {Any} value\n * @return {String}\n */\nfunction _setKeyDataType(pKey, value) {\n var dataType = _getValueType(value);\n pKey = _dataTypeKey.call(this, pKey);\n this._storage.setItem(pKey, dataType);\n return dataType;\n}\n\n\n/**\n * Removes stored data type for given (prefixed) `key`.\n *\n * @param {String} pKey prefixed key of stored value\n */\nfunction _removeKeyDataType(pKey) {\n pKey = _dataTypeKey.call(this, pKey);\n this._storage.removeItem(pKey);\n}\n\n\n/**\n * Returns the key to store data type for given (prefixed) `key`.\n *\n * @param {String} pKey prefixed key of stored value\n * @return {String}\n */\nfunction _dataTypeKey(pKey) {\n return pKey + this._typeSuffix;\n}\n\n\n/**\n * Returns type of value as string. Class name returned for objects ('null' for null).\n * @param {Any} value\n * @return {String}\n */\nfunction _getValueType(value) {\n var valueType = typeof value\n , className = value && value.constructor.name\n , dataType = valuesDataTypes[className];\n return dataType || (\n valueType != 'object'\n ? valueType\n : value == null\n ? 'null'\n : value.constructor.name);\n}\nvar valuesDataTypes = {\n // can be registered with `registerDataType`\n}\n\n\n/**\n * Serializes value to be stored in DOM storage.\n *\n * @param {Any} value value to be serialized\n * @param {String} valueType optional data type to define serializer, _getValueType is used if not passed.\n * @return {String}\n */\nfunction _serializeData(value, valueType) {\n valueType = valueType || _getValueType(value);\n var serializer = dataSerializers[valueType];\n return serializer\n ? serializer(value, valueType)\n : value && value.toString == Object.prototype.toString\n ? JSON.stringify(value)\n : '' + value;\n}\nvar dataSerializers = {\n 'Array': JSON.stringify\n}\n\n\n/**\n * Parses string retrieved from DOM storage.\n *\n * @param {String} valueStr\n * @param {String} valueType data type that defines parser. Original sring will be returned if parser is not defined.\n * @return {Any}\n */\nfunction _parseData(valueStr, valueType) {\n var parser = dataParsers[valueType];\n return parser\n ? parser(valueStr, valueType)\n : valueStr;\n}\nvar dataParsers = {\n Object: jsonParse,\n Array: jsonParse,\n Date: function(valStr) { return new Date(valStr); },\n boolean: function(valStr) { return valStr == 'true'; },\n number: function(valStr) { return Number(valStr); },\n function: function(valStr) { return _.toFunction(valStr); },\n RegExp: function(valStr) { return _.toRegExp(valStr); }\n};\n\n\n/**\n * Registers data type to be saved in DOM storage. Class name can be used or result of `typeof` operator for non-objects to override default conversions.\n *\n * @param {String} valueType class (constructor) name or the string returned by typeof.\n * @param {Function} serializer optional serializer for this type\n * @param {Function} parser optional parser for this type\n * @param {[String]} storeAsDataType optional name of stored data type if different from valueType\n */\nfunction DOMStorage$$registerDataType(valueType, serializer, parser, storeAsDataType) {\n if (serializer) dataSerializers[valueType] = serializer;\n if (parser) dataParsers[valueType] = parser;\n valuesDataTypes[valueType] = storeAsDataType || valueType;\n}\n\n\nfunction DOMStorage$createMessenger() {\n var storageMessageSource = new StorageMessageSource(this);\n var messenger = new Messenger(this, undefined, storageMessageSource);\n _.defineProperties(this, {\n _messenger: messenger,\n _messageSource: storageMessageSource\n }, _.WRIT);\n}\n\n\nfunction DOMStorage$destroy() {\n this._storage = undefined;\n this.window = undefined;\n if (this._messenger) this._messenger.destroy();\n this._destroyed = true;\n}\n", + "'use strict';\n\n\nvar DOMStorageError = require('../error').createClass('DomStorageError')\n , Messenger = require('../../messenger')\n , StorageMessageSource = require('./msg_src')\n , config = require('../../config')\n , jsonParse = require('../json_parse')\n , _ = require('mol-proto')\n , check = require('../check')\n , Match = check.Match;\n\nrequire('./model')\n\nmodule.exports = DOMStorage;\n\n\n// shared keys stored by all instances, include key prefixes\nvar _storedKeys = {\n true: {}, // session storage\n false: {} // local storage\n};\n\n\n/**\n * DOMStorage class to simplify storage and retrieval of multiple items with types preservation to DOM storage (localStorage and sessionStorage).\n * Types will be stored in the key created from value keys with appended `milo.config.domStorage.typeSuffix`\n *\n * @param {String} keyPrefix prefix that will be added to all keys followed by `milo.config.domStorage.prefixSeparator` (\"/\" by default).\n * @param {Boolean} sessionOnly true to use sessionStorage. localStorage will be used by default.\n * @param {Window} win window to work in\n */\nfunction DOMStorage(keyPrefix, sessionOnly, win) {\n if (typeof window == 'undefined') return;\n win = win || window;\n\n keyPrefix = config.domStorage.root +\n (keyPrefix\n ? keyPrefix + config.domStorage.prefixSeparator\n : '');\n\n _.defineProperties(this, {\n keyPrefix: keyPrefix,\n sessionOnly: !! sessionOnly,\n window: win,\n _storage: sessionOnly ? win.sessionStorage : win.localStorage,\n _typeSuffix: config.domStorage.typeSuffix,\n _keys: {}\n }, _.WRIT);\n}\n\n\n_.extendProto(DOMStorage, {\n get: DOMStorage$get,\n set: DOMStorage$set,\n remove: DOMStorage$remove,\n hasItem: DOMStorage$hasItem,\n getItem: DOMStorage$getItem,\n setItem: DOMStorage$setItem,\n removeItem: DOMStorage$removeItem,\n _storageKey: DOMStorage$_storageKey,\n _domStorageKey: DOMStorage$_domStorageKey,\n getAllKeys: DOMStorage$getAllKeys,\n getAllItems: DOMStorage$getAllItems,\n createMessenger: DOMStorage$createMessenger,\n destroy: DOMStorage$destroy\n});\n\n\n/**\n * Expose Mesenger and MessageSource methods on DOMStorage\n */\nMessenger.useWith(DOMStorage, '_messenger', Messenger.defaultMethods);\nStorageMessageSource.useWith(DOMStorage, '_messageSource', ['trigger']);\n\n\nvar _sessionStorage = new DOMStorage('', true)\n , _localStorage = new DOMStorage('', false);\n\nvar _domStorage = {\n true: _sessionStorage,\n false: _localStorage\n };\n\n_.extend(DOMStorage, {\n registerDataType: DOMStorage$$registerDataType,\n local: _localStorage,\n session: _sessionStorage,\n storage: _domStorage,\n _storedKeys: _storedKeys // exposed for testing\n});\n\n\n/**\n * Sets data to DOM storage. `this.keyPrefix` is prepended to keys.\n *\n * @param {Object} data single object can be passed in which case keys will be used as keys in local storage.\n * @param {List} arguments alternatively just the list of arguments can be passed where arguments can be sequentially used as keys and values.\n */\nfunction DOMStorage$set(data) { // or arguments\n if (typeof data == 'object')\n _.eachKey(data, function(value, key) {\n this.setItem(key, value);\n }, this);\n else {\n var argsLen = arguments.length;\n if (argsLen % 2)\n throw new DomStorageError('DOMStorage: set should have even number of arguments or object');\n\n for (var i = 0; i < argsLen; i++) {\n var key = arguments[i]\n , value = arguments[++i];\n\n this.setItem(key, value);\n }\n }\n}\n\n\n/**\n * Gets data from DOM storage. `this.keyPrefix` is prepended to passed keys, but returned object will have keys without root keys.\n *\n * @param {List} arguments keys can be passed as strings or arrays of strings\n * @returns {Object}\n */\nfunction DOMStorage$get() { // , ... arguments\n var data = {};\n _.deepForEach(arguments, function(key) {\n data[key] = this.getItem(key);\n }, this);\n return data;\n}\n\n\n/**\n * Removes keys from DOM storage. `this.keyPrefix` is prepended to passed keys.\n *\n * @param {List} arguments keys can be passed as strings or arrays of strings\n */\nfunction DOMStorage$remove() { //, ... arguments\n _.deepForEach(arguments, function(key) {\n this.removeItem(key);\n }, this);\n}\n\n\n/**\n * Check for presence of single item in DOM storage. `this.keyPrefix` is prepended to passed key.\n *\n * @param {String} key\n * @return {Boolean}\n */\nfunction DOMStorage$hasItem(key) {\n var pKey = this._storageKey(key);\n return this._storage.getItem(pKey) != null;\n}\n\n\n/**\n * Gets single item from DOM storage prepending `this.keyPrefix` to passed key.\n * Reads type of the originally stored value from `key + this._typeSuffix` and converts data to the original type.\n *\n * @param {String} key\n * @return {Any}\n */\nfunction DOMStorage$getItem(key) {\n var pKey = this._storageKey(key);\n var dataType = _getKeyDataType.call(this, pKey);\n var valueStr = this._storage.getItem(pKey);\n var value = _parseData(valueStr, dataType);\n return value;\n}\n\n\n/**\n * Sets single item to DOM storage prepending `this.keyPrefix` to passed key.\n * Stores type of the stored value to `key + this._typeSuffix`.\n *\n * @param {String} key\n * @return {Any}\n */\nfunction DOMStorage$setItem(key, value) {\n var pKey = this._storageKey(key);\n var dataType = _setKeyDataType.call(this, pKey, value);\n var valueStr = _serializeData(value, dataType);\n try {\n this._storage.setItem(pKey, valueStr);\n } catch(e) {\n if (e.name == 'QuotaExceededError') {\n var cfg = config.domStorage.quotaExceeded;\n if (cfg.message)\n milo.mail.postMessage('quotaexceedederror', value);\n if (cfg.throwError)\n throw e;\n } else\n throw e;\n }\n this._keys[key] = true;\n _domStorage[this.sessionOnly]._keys[pKey] = true;\n}\n\n\n/**\n * Removes single item from DOM storage prepending `this.keyPrefix` to passed key.\n * Type of the stored value (in `key + this._typeSuffix` key) is also removed.\n *\n * @param {String} key\n * @return {Any}\n */\nfunction DOMStorage$removeItem(key) {\n var pKey = this._storageKey(key);\n this._storage.removeItem(pKey);\n _removeKeyDataType.call(this, pKey)\n delete this._keys[key];\n delete _domStorage[this.sessionOnly]._keys[pKey];\n}\n\n\n/**\n * Returns the array of all keys stored by this instance of DOMStorage\n *\n * @return {Array}\n */\nfunction DOMStorage$getAllKeys() {\n var storedKeys = Object.keys(this._keys);\n var keysInStorage = storedKeys.filter(function(key) {\n if (this.hasItem(key)) return true;\n else delete this._keys[key];\n }, this);\n return keysInStorage;\n}\n\n\n/**\n * Returns the map with all keys and values (deserialized) stored using this instance of DOMStorage\n *\n * @return {Object}\n */\nfunction DOMStorage$getAllItems() {\n return this.get(this.getAllKeys());\n}\n\n\n/**\n * Returns prefixed key for DOM storage for given unprefixed key.\n *\n * @param {String} key\n * @return {String}\n */\nfunction DOMStorage$_storageKey(key) {\n return this.keyPrefix + key;\n}\n\n\n/**\n * Returns unprefixed key to be used with this instance of DOMStorage fir given actual key in storage\n * If key has different prefix from the keyPrefix returns undefined\n *\n * @param {String} storageKey actual key in local/session storage\n * @return {String}\n */\nfunction DOMStorage$_domStorageKey(storageKey) {\n if (storageKey.indexOf(this._typeSuffix) >= 0) return;\n return _.unPrefix(storageKey, this.keyPrefix);\n}\n\n\n/**\n * Gets originally stored data type for given (prefixed) `key`.\n *\n * @param {String} pKey prefixed key of stored value\n * @return {String}\n */\nfunction _getKeyDataType(pKey) {\n pKey = _dataTypeKey.call(this, pKey);\n return this._storage.getItem(pKey);\n}\n\n\n/**\n * Stores data type for given (prefixed) `key` and `value`.\n * Returns data type for `value`.\n *\n * @param {String} pKey prefixed key of stored value\n * @param {Any} value\n * @return {String}\n */\nfunction _setKeyDataType(pKey, value) {\n var dataType = _getValueType(value);\n pKey = _dataTypeKey.call(this, pKey);\n this._storage.setItem(pKey, dataType);\n return dataType;\n}\n\n\n/**\n * Removes stored data type for given (prefixed) `key`.\n *\n * @param {String} pKey prefixed key of stored value\n */\nfunction _removeKeyDataType(pKey) {\n pKey = _dataTypeKey.call(this, pKey);\n this._storage.removeItem(pKey);\n}\n\n\n/**\n * Returns the key to store data type for given (prefixed) `key`.\n *\n * @param {String} pKey prefixed key of stored value\n * @return {String}\n */\nfunction _dataTypeKey(pKey) {\n return pKey + this._typeSuffix;\n}\n\n\n/**\n * Returns type of value as string. Class name returned for objects ('null' for null).\n * @param {Any} value\n * @return {String}\n */\nfunction _getValueType(value) {\n var valueType = typeof value\n , className = value && value.constructor.name\n , dataType = valuesDataTypes[className];\n return dataType || (\n valueType != 'object'\n ? valueType\n : value == null\n ? 'null'\n : value.constructor.name);\n}\nvar valuesDataTypes = {\n // can be registered with `registerDataType`\n}\n\n\n/**\n * Serializes value to be stored in DOM storage.\n *\n * @param {Any} value value to be serialized\n * @param {String} valueType optional data type to define serializer, _getValueType is used if not passed.\n * @return {String}\n */\nfunction _serializeData(value, valueType) {\n valueType = valueType || _getValueType(value);\n var serializer = dataSerializers[valueType];\n return serializer\n ? serializer(value, valueType)\n : value && value.toString == Object.prototype.toString\n ? JSON.stringify(value)\n : '' + value;\n}\nvar dataSerializers = {\n 'Array': JSON.stringify\n}\n\n\n/**\n * Parses string retrieved from DOM storage.\n *\n * @param {String} valueStr\n * @param {String} valueType data type that defines parser. Original sring will be returned if parser is not defined.\n * @return {Any}\n */\nfunction _parseData(valueStr, valueType) {\n var parser = dataParsers[valueType];\n return parser\n ? parser(valueStr, valueType)\n : valueStr;\n}\nvar dataParsers = {\n Object: jsonParse,\n Array: jsonParse,\n Date: function(valStr) { return new Date(valStr); },\n boolean: function(valStr) { return valStr == 'true'; },\n number: function(valStr) { return Number(valStr); },\n function: function(valStr) { return _.toFunction(valStr); },\n RegExp: function(valStr) { return _.toRegExp(valStr); }\n};\n\n\n/**\n * Registers data type to be saved in DOM storage. Class name can be used or result of `typeof` operator for non-objects to override default conversions.\n *\n * @param {String} valueType class (constructor) name or the string returned by typeof.\n * @param {Function} serializer optional serializer for this type\n * @param {Function} parser optional parser for this type\n * @param {[String]} storeAsDataType optional name of stored data type if different from valueType\n */\nfunction DOMStorage$$registerDataType(valueType, serializer, parser, storeAsDataType) {\n if (serializer) dataSerializers[valueType] = serializer;\n if (parser) dataParsers[valueType] = parser;\n valuesDataTypes[valueType] = storeAsDataType || valueType;\n}\n\n\nfunction DOMStorage$createMessenger() {\n var storageMessageSource = new StorageMessageSource(this);\n var messenger = new Messenger(this, undefined, storageMessageSource);\n _.defineProperties(this, {\n _messenger: messenger,\n _messageSource: storageMessageSource\n }, _.WRIT);\n}\n\n\nfunction DOMStorage$destroy() {\n this._storage = undefined;\n this.window = undefined;\n if (this._messenger) this._messenger.destroy();\n this._destroyed = true;\n}\n", + "'use strict';\n\nvar Model = require('milo-core').Model\n\nModel.registerWithDOMStorage = Model$$registerWithDOMStorage;\n\n\nfunction Model$$registerWithDOMStorage() {\n var DOMStorage = require('./index');\n DOMStorage.registerDataType('Model', Model_domStorageSerializer, Model_domStorageParser);\n DOMStorage.registerDataType('ModelPath', Model_domStorageSerializer, Model_domStorageParser, 'Model');\n}\n\n\nfunction Model_domStorageSerializer(value) {\n var data = value.get();\n return JSON.stringify(data);\n}\n\n\nfunction Model_domStorageParser(valueStr) {\n var data = _.jsonParse(valueStr);\n return new Model(data);\n}\n", "'use strict';\n\n\nvar MessageSource = require('../../messenger/m_source')\n , _ = require('mol-proto')\n , config = require('../../config')\n , miloCount = require('../../util/count')\n , StorageMessageSourceError = require('../../util/error').StorageMessageSource;\n\nvar StorageMessageSource = _.createSubclass(MessageSource, 'StorageMessageSource', true);\n\n\n_.extendProto(StorageMessageSource, {\n // implementing MessageSource interface\n init: init,\n addSourceSubscriber: StorageMessageSource$addSourceSubscriber,\n removeSourceSubscriber: StorageMessageSource$removeSourceSubscriber,\n postMessage: StorageMessageSource$postMessage,\n trigger: StorageMessageSource$trigger,\n\n //class specific methods\n handleEvent: handleEvent // event dispatcher - as defined by Event DOM API\n});\n\nmodule.exports = StorageMessageSource;\n\n\nfunction init(hostObject, proxyMethods, messengerAPIOrClass) {\n if (hostObject.constructor.name != 'DOMStorage')\n throw new StorageMessageSourceError('hostObject should be an instance of DOMStorage');\n this.storage = hostObject;\n this.messageKey = config.domStorage.messageKey;\n this.window = hostObject.window;\n MessageSource.prototype.init.apply(this, arguments);\n}\n\n\nfunction StorageMessageSource$addSourceSubscriber(sourceMessage) {\n this.window.addEventListener('storage', this, false);\n}\n\n\nfunction StorageMessageSource$removeSourceSubscriber(sourceMessage) {\n this.window.removeEventListener('storage', this, false);\n}\n\n\nfunction StorageMessageSource$postMessage(message, data) {\n this.messenger.postMessageSync(message, data);\n}\n\n\nfunction StorageMessageSource$trigger(msgType, data) {\n var key = this.messageKey + msgType;\n data = data || {};\n data[config.domStorage.messageTimestamp] = miloCount();\n _.deferMethod(this.storage, 'setItem', key, data);\n}\n\n\nfunction handleEvent(event) {\n if (event.storageArea != this.storage._storage) return;\n var key = this.storage._domStorageKey(event.key); if (! key) return;\n var msgType = _.unPrefix(key, this.messageKey); if (! msgType) return;\n var data = this.storage.getItem(key); if (! data) return;\n this.dispatchMessage(msgType, data);\n}\n", "'use strict';\n\n/**\n * `milo.util.websocket` \n**/\n\n\nvar Messenger = require('../../messenger')\n , WSMessageSource = require('./msg_src')\n , WSMsgAPI = require('./msg_api');\n\n\nfunction websocket() {\n var wsMessenger = new Messenger;\n var wsMsgSource = new WSMessageSource(wsMessenger, { send: 'trigger', connect: 'connect' }, new WSMsgAPI);\n wsMessenger._setMessageSource(wsMsgSource);\n return wsMessenger;\n}\n\n\nmodule.exports = websocket;\n", "'use strict';\n\nvar MessengerAPI = require('../../messenger/m_api')\n , _ = require('mol-proto')\n , check = require('../../util/check')\n , Match = check.Match;\n\n\nvar WSMsgAPI = _.createSubclass(MessengerAPI, 'WSMsgAPI', true);\n\n\n_.extendProto(WSMsgAPI, {\n translateToSourceMessage: translateToSourceMessage,\n filterSourceMessage: filterSourceMessage,\n createInternalData: createInternalData\n});\n\nmodule.exports = WSMsgAPI;\n\n\nvar SOCKET_MESSAGES = ['open', 'close', 'error', 'message'];\n\nfunction translateToSourceMessage(message) {\n return SOCKET_MESSAGES.indexOf(message) >= 0\n ? message\n : 'message';\n}\n\n\nfunction filterSourceMessage(sourceMessage, message, msgData) {\n if (SOCKET_MESSAGES.indexOf(message) >= 0) return true; // internal message is one of external messages\n if (sourceMessage == 'message') {\n var msgType = msgData && msgData.type;\n return msgType == message; // type equals internal message\n }\n};\n\n\nfunction createInternalData(sourceMessage, message, event) {\n var internalData = sourceMessage == 'message'\n ? _.jsonParse(event.data) || event.data\n : event;\n return internalData;\n}\n", @@ -248,6 +272,28 @@ "\n// not implemented\n// The reason for having an empty file and not throwing is to allow\n// untraditional implementation of this module.\n", "// doT.js\n// 2011-2014, Laura Doktorova, https://github.com/olado/doT\n// Licensed under the MIT license.\n\n(function() {\n\t\"use strict\";\n\n\tvar doT = {\n\t\tversion: \"1.0.3\",\n\t\ttemplateSettings: {\n\t\t\tevaluate: /\\{\\{([\\s\\S]+?(\\}?)+)\\}\\}/g,\n\t\t\tinterpolate: /\\{\\{=([\\s\\S]+?)\\}\\}/g,\n\t\t\tencode: /\\{\\{!([\\s\\S]+?)\\}\\}/g,\n\t\t\tuse: /\\{\\{#([\\s\\S]+?)\\}\\}/g,\n\t\t\tuseParams: /(^|[^\\w$])def(?:\\.|\\[[\\'\\\"])([\\w$\\.]+)(?:[\\'\\\"]\\])?\\s*\\:\\s*([\\w$\\.]+|\\\"[^\\\"]+\\\"|\\'[^\\']+\\'|\\{[^\\}]+\\})/g,\n\t\t\tdefine: /\\{\\{##\\s*([\\w\\.$]+)\\s*(\\:|=)([\\s\\S]+?)#\\}\\}/g,\n\t\t\tdefineParams:/^\\s*([\\w$]+):([\\s\\S]+)/,\n\t\t\tconditional: /\\{\\{\\?(\\?)?\\s*([\\s\\S]*?)\\s*\\}\\}/g,\n\t\t\titerate: /\\{\\{~\\s*(?:\\}\\}|([\\s\\S]+?)\\s*\\:\\s*([\\w$]+)\\s*(?:\\:\\s*([\\w$]+))?\\s*\\}\\})/g,\n\t\t\tvarname:\t\"it\",\n\t\t\tstrip:\t\ttrue,\n\t\t\tappend:\t\ttrue,\n\t\t\tselfcontained: false,\n\t\t\tdoNotSkipEncoded: false\n\t\t},\n\t\ttemplate: undefined, //fn, compile template\n\t\tcompile: undefined //fn, for express\n\t}, _globals;\n\n\tdoT.encodeHTMLSource = function(doNotSkipEncoded) {\n\t\tvar encodeHTMLRules = { \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\", \"/\": \"/\" },\n\t\t\tmatchHTML = doNotSkipEncoded ? /[&<>\"'\\/]/g : /&(?!#?\\w+;)|<|>|\"|'|\\//g;\n\t\treturn function(code) {\n\t\t\treturn code ? code.toString().replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : \"\";\n\t\t};\n\t};\n\n\t_globals = (function(){ return this || (0,eval)(\"this\"); }());\n\n\tif (typeof module !== \"undefined\" && module.exports) {\n\t\tmodule.exports = doT;\n\t} else if (typeof define === \"function\" && define.amd) {\n\t\tdefine(function(){return doT;});\n\t} else {\n\t\t_globals.doT = doT;\n\t}\n\n\tvar startend = {\n\t\tappend: { start: \"'+(\", end: \")+'\", startencode: \"'+encodeHTML(\" },\n\t\tsplit: { start: \"';out+=(\", end: \");out+='\", startencode: \"';out+=encodeHTML(\" }\n\t}, skip = /$^/;\n\n\tfunction resolveDefs(c, block, def) {\n\t\treturn ((typeof block === \"string\") ? block : block.toString())\n\t\t.replace(c.define || skip, function(m, code, assign, value) {\n\t\t\tif (code.indexOf(\"def.\") === 0) {\n\t\t\t\tcode = code.substring(4);\n\t\t\t}\n\t\t\tif (!(code in def)) {\n\t\t\t\tif (assign === \":\") {\n\t\t\t\t\tif (c.defineParams) value.replace(c.defineParams, function(m, param, v) {\n\t\t\t\t\t\tdef[code] = {arg: param, text: v};\n\t\t\t\t\t});\n\t\t\t\t\tif (!(code in def)) def[code]= value;\n\t\t\t\t} else {\n\t\t\t\t\tnew Function(\"def\", \"def['\"+code+\"']=\" + value)(def);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn \"\";\n\t\t})\n\t\t.replace(c.use || skip, function(m, code) {\n\t\t\tif (c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {\n\t\t\t\tif (def[d] && def[d].arg && param) {\n\t\t\t\t\tvar rw = (d+\":\"+param).replace(/'|\\\\/g, \"_\");\n\t\t\t\t\tdef.__exp = def.__exp || {};\n\t\t\t\t\tdef.__exp[rw] = def[d].text.replace(new RegExp(\"(^|[^\\\\w$])\" + def[d].arg + \"([^\\\\w$])\", \"g\"), \"$1\" + param + \"$2\");\n\t\t\t\t\treturn s + \"def.__exp['\"+rw+\"']\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar v = new Function(\"def\", \"return \" + code)(def);\n\t\t\treturn v ? resolveDefs(c, v, def) : v;\n\t\t});\n\t}\n\n\tfunction unescape(code) {\n\t\treturn code.replace(/\\\\('|\\\\)/g, \"$1\").replace(/[\\r\\t\\n]/g, \" \");\n\t}\n\n\tdoT.template = function(tmpl, c, def) {\n\t\tc = c || doT.templateSettings;\n\t\tvar cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv,\n\t\t\tstr = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;\n\n\t\tstr = (\"var out='\" + (c.strip ? str.replace(/(^|\\r|\\n)\\t* +| +\\t*(\\r|\\n|$)/g,\" \")\n\t\t\t\t\t.replace(/\\r|\\n|\\t|\\/\\*[\\s\\S]*?\\*\\//g,\"\"): str)\n\t\t\t.replace(/'|\\\\/g, \"\\\\$&\")\n\t\t\t.replace(c.interpolate || skip, function(m, code) {\n\t\t\t\treturn cse.start + unescape(code) + cse.end;\n\t\t\t})\n\t\t\t.replace(c.encode || skip, function(m, code) {\n\t\t\t\tneedhtmlencode = true;\n\t\t\t\treturn cse.startencode + unescape(code) + cse.end;\n\t\t\t})\n\t\t\t.replace(c.conditional || skip, function(m, elsecase, code) {\n\t\t\t\treturn elsecase ?\n\t\t\t\t\t(code ? \"';}else if(\" + unescape(code) + \"){out+='\" : \"';}else{out+='\") :\n\t\t\t\t\t(code ? \"';if(\" + unescape(code) + \"){out+='\" : \"';}out+='\");\n\t\t\t})\n\t\t\t.replace(c.iterate || skip, function(m, iterate, vname, iname) {\n\t\t\t\tif (!iterate) return \"';} } out+='\";\n\t\t\t\tsid+=1; indv=iname || \"i\"+sid; iterate=unescape(iterate);\n\t\t\t\treturn \"';var arr\"+sid+\"=\"+iterate+\";if(arr\"+sid+\"){var \"+vname+\",\"+indv+\"=-1,l\"+sid+\"=arr\"+sid+\".length-1;while(\"+indv+\"\n// milo.classes\n// -----------\n\n// This module contains foundation classes\n\nvar classes = {\n Mixin: require('./abstract/mixin'),\n MessageSource: require('./messenger/m_source'),\n MessengerMessageSource: require('./messenger/msngr_source'),\n MessengerAPI: require('./messenger/m_api'),\n MessengerRegexpAPI: require('./messenger/m_api_rx')\n};\n\nmodule.exports = classes;\n", + "'use strict';\n\n\nvar _ = require('mol-proto');\n\n\nmodule.exports = config;\n\nfunction config(options) {\n _.deepExtend(config, options);\n}\n\nconfig({\n mixin: {\n instancePropertiesMap: '___mixin_instances'\n },\n check: true,\n debug: false\n});\n", + "'use strict';\n\nvar Mixin = require('../abstract/mixin')\n , MessageSource = require('./m_source')\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match;\n\n\n/**\n * `milo.Messenger`\n * A generic Messenger class that is used for all kinds of messaging in milo. It is subclassed from [Mixin](../abstract/mixin.js.html) and it proxies its methods to the host object for convenience.\n * All facets and components have messenger attached to them. Messenger class interoperates with [MessageSource](./m_source.js.html) class that connects the messenger to some external source of messages (e.g., DOM events) and [MessengerAPI](./m_api.js.html) class that allows to define higher level messages than messages that exist on the source.\n * Messenger class is used internally in milo and can be used together with any objects/classes in the application.\n * milo also defines a global messenger [milo.mail](../mail/index.js.html) that dispatches `domready` event and can be used for any application wide messaging.\n * To initialize your app after DOM is ready use:\n * ```\n * milo.mail.on('domready', function() {\n * // application starts\n * });\n * ```\n * or the following shorter form of the same:\n * ```\n * milo(function() {\n * // application starts\n * });\n * ```\n */\nvar Messenger = _.createSubclass(Mixin, 'Messenger');\n\nvar messagesSplitRegExp = Messenger.messagesSplitRegExp = /\\s*(?:\\,|\\s)\\s*/;\n\n\n/**\n * ####Messenger instance methods####\n *\n * - [init](#init)\n * - [on](#Messenger$on) (alias - onMessage, deprecated)\n * - [off](#Messenger$off) (alias - offMessage, deprecated)\n * - [onMessages](#onMessages)\n * - [offMessages](#offMessages)\n * - [once](#once)\n * - [onceSync](#onceSync)\n * - [postMessage](#postMessage)\n * - [getSubscribers](#getSubscribers)\n *\n * \"Private\" methods\n *\n * - [_chooseSubscribersHash](#_chooseSubscribersHash)\n * - [_registerSubscriber](#_registerSubscriber)\n * - [_removeSubscriber](#_removeSubscriber)\n * - [_removeAllSubscribers](#_removeAllSubscribers)\n * - [_callPatternSubscribers](#_callPatternSubscribers)\n * - [_callSubscribers](#_callSubscribers)\n * - [_setMessageSource](#_setMessageSource)\n * - [getMessageSource](#getMessageSource)\n */\n_.extendProto(Messenger, {\n init: init, // called by Mixin (superclass)\n destroy: Messenger$destroy,\n on: Messenger$on,\n once: Messenger$once,\n onceSync: Messenger$onceSync,\n onSync: Messenger$onSync,\n onAsync: Messenger$onAsync,\n onMessage: Messenger$on, // deprecated\n off: Messenger$off,\n offMessage: Messenger$off, // deprecated\n onMessages: onMessages,\n offMessages: offMessages,\n offAll: Messenger$offAll,\n postMessage: postMessage,\n postMessageSync: postMessageSync,\n getSubscribers: getSubscribers,\n getMessageSource: getMessageSource,\n _chooseSubscribersHash: _chooseSubscribersHash,\n _registerSubscriber: _registerSubscriber,\n _removeSubscriber: _removeSubscriber,\n _removeAllSubscribers: _removeAllSubscribers,\n _callPatternSubscribers: _callPatternSubscribers,\n _callSubscribers: _callSubscribers,\n _callSubscriber: _callSubscriber,\n _setMessageSource: _setMessageSource\n});\n\n\n/**\n * A default map of proxy methods used by ComponentFacet and Component classes to pass to Messenger when it is instantiated.\n * This map is for convenience only, it is NOT used internally by Messenger, a host class should pass it for methods to be proxied this way.\n */\nMessenger.defaultMethods = {\n on: 'on',\n onSync: 'onSync',\n once: 'once',\n onceSync: 'onceSync',\n off: 'off',\n onMessages: 'onMessages',\n offMessages: 'offMessages',\n postMessage: 'postMessage',\n postMessageSync: 'postMessageSync',\n getSubscribers: 'getSubscribers'\n};\n\n\nmodule.exports = Messenger;\n\n\nMessenger.subscriptions = [];\n\n\n/**\n * Messenger instance method\n * Initializes Messenger. Method is called by Mixin class constructor.\n * See [on](#Messenger$on) method, [Messenger](#Messenger) class above and [MessageSource](./m_source.js.html) class.\n *\n * @param {Object} hostObject Optional object that stores the messenger on one of its properties. It is used to proxy methods of messenger and also as a context for subscribers when they are called by the Messenger. See `on` method.\n * @param {Object} proxyMethods Optional map of method names; key - proxy method name, value - messenger's method name.\n * @param {MessageSource} messageSource Optional messageSource linked to the messenger. If messageSource is supplied, the reference to the messenger will stored on its 'messenger' property\n */\nfunction init(hostObject, proxyMethods, messageSource) {\n // hostObject and proxyMethods are used in Mixin and checked there\n if (messageSource)\n this._setMessageSource(messageSource);\n\n _initializeSubscribers.call(this);\n}\n\n\nfunction _initializeSubscribers() {\n _.defineProperties(this, {\n _messageSubscribers: {},\n _patternMessageSubscribers: {},\n }, _.CONF);\n}\n\n\n/**\n * Destroys messenger. Maybe needs to unsubscribe all subscribers\n */\nfunction Messenger$destroy() {\n this.offAll();\n var messageSource = this.getMessageSource();\n if (messageSource)\n messageSource.destroy();\n}\n\n\n/**\n * Messenger instance method.\n * Registers a subscriber function for a certain message(s).\n * This method returns `true` if the subscription was successful. It can be unsuccessful if the passed subscriber has already been subscribed to this message type - double subscription never happens and it is safe to subscribe again - no error or warning is thrown or logged.\n * Subscriber is passed two parameters: `message` (string) and `data` (object). Data object is supplied when message is dispatched, Messenger itself adds nothing to it. For example, [events facet](../components/c_facets/Events.js.html) sends actual DOM event when it posts message.\n * Usage:\n * ```\n * // subscribes onMouseUpDown to two DOM events on component via events facet.\n * myComp.events.on('mousedown mouseup', onMouseUpDown);\n * function onMouseUpDown(eventType, event) {\n * // ...\n * }\n *\n * myComp.data.on(/.+/, function(msg, data) {\n * logger.debug(msg, data);\n * }); // subscribes anonymous function to all non-empty messages on data facet\n * // it will not be possible to unsubscribe anonymous subscriber separately,\n * // but myComp.data.off(/.+/) will unsubscribe it\n * ```\n * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the first subscriber for a given message is added, so it can subscribe to the source.\n * [Components](../components/c_class.js.html) and [facets](../components/c_facet.js.html) change this method name to `on` when they proxy it.\n * See [postMessage](#postMessage).\n *\n * @param {String|Array[String]|RegExp} messages Message types that should envoke the subscriber.\n * If string is passed, it can be a sigle message or multiple message types separated by whitespace with optional commas.\n * If an array of strings is passed, each string is a message type to subscribe for.\n * If a RegExp is passed, the subscriber will be envoked when the message dispatched on the messenger matches the pattern (or IS the RegExp with identical pattern).\n * Pattern subscriber does NOT cause any subscription to MessageSource, it only captures messages that are already subscribed to with precise message types.\n * @param {Function|Object} subscriber Message subscriber - a function that will be called when the message is dispatched on the messenger (usually via proxied postMessage method of host object).\n * If hostObject was supplied to Messenger constructor, hostObject will be the context (the value of this) for the subscriber envocation.\n * Subscriber can also be an object with properties `subscriber` (function) and `context` (\"this\" value when subscriber is called)\n * @return {Boolean}\n */\nfunction Messenger$on(messages, subscriber) {\n return _Messenger_onWithOptions.call(this, messages, subscriber);\n}\n\n\nfunction Messenger$once(messages, subscriber) {\n return _Messenger_onWithOptions.call(this, messages, subscriber, { dispatchTimes: 1 });\n}\n\nfunction Messenger$onceSync(messages, subscriber) {\n return _Messenger_onWithOptions.call(this, messages, subscriber, { dispatchTimes: 1, sync: true });\n}\n\n\nfunction Messenger$onSync(messages, subscriber) {\n return _Messenger_onWithOptions.call(this, messages, subscriber, { sync: true });\n}\n\n\nfunction Messenger$onAsync(messages, subscriber) {\n return _Messenger_onWithOptions.call(this, messages, subscriber, { sync: false });\n}\n\n\nfunction _Messenger_onWithOptions(messages, subscriber, options) {\n check(messages, Match.OneOf(String, [String], RegExp));\n check(subscriber, Match.OneOf(Function, {\n subscriber: Function,\n context: Match.Any,\n options: Match.Optional(Object),\n }));\n\n if (typeof subscriber == 'function') {\n subscriber = {\n subscriber: subscriber,\n context: this._hostObject,\n };\n }\n\n if (options) {\n subscriber.options = subscriber.options || {};\n _.extend(subscriber.options, options);\n }\n\n return _Messenger_on.call(this, messages, subscriber);\n}\n\n\nfunction _Messenger_on(messages, subscriber) {\n _.defineProperty(subscriber, '__messages', messages);\n return _eachMessage.call(this, '_registerSubscriber', messages, subscriber);\n}\n\n\nfunction _eachMessage(methodName, messages, subscriber) {\n if (typeof messages == 'string')\n messages = messages.split(messagesSplitRegExp);\n\n var subscribersHash = this._chooseSubscribersHash(messages);\n\n if (messages instanceof RegExp)\n return this[methodName](subscribersHash, messages, subscriber);\n\n else {\n var changed = false;\n\n messages.forEach(function(message) {\n var subscriptionChanged = this[methodName](subscribersHash, message, subscriber);\n changed = changed || subscriptionChanged;\n }, this);\n\n return changed;\n }\n}\n\n\n/**\n * \"Private\" Messenger instance method\n * It is called by [on](#Messenger$on) to register subscriber for one message type.\n * Returns `true` if this subscriber is not yet registered for this type of message.\n * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the first subscriber for a given message is added.\n *\n * @private\n * @param {Object} subscribersHash The map of subscribers determined by [on](#Messenger$on) based on Message type, can be `this._patternMessageSubscribers` or `this._messageSubscribers`\n * @param {String} message Message type\n * @param {Function|Object} subscriber Subscriber function to be added or object with properties `subscriber` (function) and `context` (value of \"this\" when subscriber is called)\n * @return {Boolean}\n */\nfunction _registerSubscriber(subscribersHash, message, subscriber) {\n if (! (subscribersHash[message] && subscribersHash[message].length)) {\n subscribersHash[message] = [];\n if (message instanceof RegExp)\n subscribersHash[message].pattern = message;\n if (this._messageSource)\n this._messageSource.onSubscriberAdded(message);\n var noSubscribers = true;\n }\n\n var msgSubscribers = subscribersHash[message];\n var notYetRegistered = noSubscribers || _indexOfSubscriber.call(this, msgSubscribers, subscriber) == -1;\n\n if (notYetRegistered)\n msgSubscribers.push(subscriber);\n\n return notYetRegistered;\n}\n\n\n/**\n * Finds subscriber index in the list\n *\n * @param {Array[Function|Object]} list list of subscribers\n * @param {Function|Object} subscriber subscriber function or object with properties `subscriber` (function) and `context` (\"this\" object)\n */\nfunction _indexOfSubscriber(list, subscriber) {\n var self = this;\n return _.findIndex(list, function(subscr){\n return subscriber.subscriber == subscr.subscriber\n && subscriber.context == subscr.context\n });\n}\n\n\n/**\n * Messenger instance method.\n * Subscribes to multiple messages passed as map together with subscribers.\n * Usage:\n * ```\n * myComp.events.onMessages({\n * 'mousedown': onMouseDown,\n * 'mouseup': onMouseUp\n * });\n * function onMouseDown(eventType, event) {}\n * function onMouseUp(eventType, event) {}\n * ```\n * Returns map with the same keys (message types) and boolean values indicating whether particular subscriber was added.\n * It is NOT possible to add pattern subscriber using this method, as although you can use RegExp as the key, JavaScript will automatically convert it to string.\n *\n * @param {Object[Function]} messageSubscribers Map of message subscribers to be added\n * @return {Object[Boolean]}\n */\nfunction onMessages(messageSubscribers) {\n check(messageSubscribers, Match.ObjectHash(Match.OneOf(Function, { subscriber: Function, context: Match.Any })));\n\n var notYetRegisteredMap = _.mapKeys(messageSubscribers, function(subscriber, messages) {\n return this.on(messages, subscriber);\n }, this);\n\n return notYetRegisteredMap;\n}\n\n\n/**\n * Messenger instance method.\n * Removes a subscriber for message(s). Removes all subscribers for the message if subscriber isn't passed.\n * This method returns `true` if the subscriber was registered. No error or warning is thrown or logged if you remove subscriber that was not registered.\n * [Components](../components/c_class.js.html) and [facets](../components/c_facet.js.html) change this method name to `off` when they proxy it.\n * Usage:\n * ```\n * // unsubscribes onMouseUpDown from two DOM events.\n * myComp.events.off('mousedown mouseup', onMouseUpDown);\n * ```\n * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the last subscriber for a given message is removed and there is no more subscribers for this message.\n *\n * @param {String|Array[String]|RegExp} messages Message types that a subscriber should be removed for.\n * If string is passed, it can be a sigle message or multiple message types separated by whitespace with optional commas.\n * If an array of strings is passed, each string is a message type to remove a subscriber for.\n * If a RegExp is passed, the pattern subscriber will be removed.\n * RegExp subscriber does NOT cause any subscription to MessageSource, it only captures messages that are already subscribed to with precise message types.\n * @param {Function} subscriber Message subscriber - Optional function that will be removed from the list of subscribers for the message(s). If subscriber is not supplied, all subscribers will be removed from this message(s).\n * @return {Boolean}\n */\nfunction Messenger$off(messages, subscriber) {\n check(messages, Match.OneOf(String, [String], RegExp));\n check(subscriber, Match.Optional(Match.OneOf(Function, {\n subscriber: Function,\n context: Match.Any,\n options: Match.Optional(Object),\n // __messages: Match.Optional(Match.OneOf(String, [String], RegExp))\n })));\n\n return _Messenger_off.call(this, messages, subscriber);\n}\n\n\nfunction _Messenger_off(messages, subscriber) {\n return _eachMessage.call(this, '_removeSubscriber', messages, subscriber);\n}\n\n\n/**\n * \"Private\" Messenger instance method\n * It is called by [off](#Messenger$off) to remove subscriber for one message type.\n * Returns `true` if this subscriber was registered for this type of message.\n * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified when the last subscriber for a given message is removed and there is no more subscribers for this message.\n *\n * @private\n * @param {Object} subscribersHash The map of subscribers determined by [off](#Messenger$off) based on message type, can be `this._patternMessageSubscribers` or `this._messageSubscribers`\n * @param {String} message Message type\n * @param {Function} subscriber Subscriber function to be removed\n * @return {Boolean}\n */\nfunction _removeSubscriber(subscribersHash, message, subscriber) {\n var msgSubscribers = subscribersHash[message];\n if (! msgSubscribers || ! msgSubscribers.length)\n return false; // nothing removed\n\n if (subscriber) {\n if (typeof subscriber == 'function')\n subscriber = { subscriber: subscriber, context: this._hostObject };\n\n var subscriberIndex = _indexOfSubscriber.call(this, msgSubscribers, subscriber);\n if (subscriberIndex == -1)\n return false; // nothing removed\n msgSubscribers.splice(subscriberIndex, 1);\n if (! msgSubscribers.length)\n this._removeAllSubscribers(subscribersHash, message);\n\n } else\n this._removeAllSubscribers(subscribersHash, message);\n\n return true; // subscriber(s) removed\n}\n\n\n/**\n * \"Private\" Messenger instance method\n * It is called by [_removeSubscriber](#_removeSubscriber) to remove all subscribers for one message type.\n * If messenger has [MessageSource](./m_source.js.html) attached to it, MessageSource will be notified that all message subscribers were removed so it can unsubscribe from the source.\n *\n * @private\n * @param {Object} subscribersHash The map of subscribers determined by [off](#Messenger$off) based on message type, can be `this._patternMessageSubscribers` or `this._messageSubscribers`\n * @param {String} message Message type\n */\nfunction _removeAllSubscribers(subscribersHash, message) {\n delete subscribersHash[message];\n if (this._messageSource && typeof message == 'string')\n this._messageSource.onSubscriberRemoved(message);\n}\n\n\n/**\n * Messenger instance method.\n * Unsubscribes from multiple messages passed as map together with subscribers.\n * Returns map with the same keys (message types) and boolean values indicating whether particular subscriber was removed.\n * If a subscriber for one of the messages is not supplied, all subscribers for this message will be removed.\n * Usage:\n * ```\n * myComp.events.offMessages({\n * 'mousedown': onMouseDown,\n * 'mouseup': onMouseUp,\n * 'click': undefined // all subscribers to this message will be removed\n * });\n * ```\n * It is NOT possible to remove pattern subscriber(s) using this method, as although you can use RegExp as the key, JavaScript will automatically convert it to string.\n *\n * @param {Object[Function]} messageSubscribers Map of message subscribers to be removed\n * @return {Object[Boolean]}\n */\nfunction offMessages(messageSubscribers) {\n check(messageSubscribers, Match.ObjectHash(Match.Optional(Match.OneOf(Function, { subscriber: Function, context: Match.Any }))));\n\n var subscriberRemovedMap = _.mapKeys(messageSubscribers, function(subscriber, messages) {\n return this.off(messages, subscriber);\n }, this);\n\n return subscriberRemovedMap;\n}\n\n\n/**\n * Unsubscribes all subscribers\n */\nfunction Messenger$offAll() {\n _offAllSubscribers.call(this, this._patternMessageSubscribers);\n _offAllSubscribers.call(this, this._messageSubscribers);\n}\n\n\nfunction _offAllSubscribers(subscribersHash) {\n _.eachKey(subscribersHash, function(subscribers, message) {\n this._removeAllSubscribers(subscribersHash, message);\n }, this);\n}\n\n\n// TODO - send event to messageSource\n\n\n/**\n * Messenger instance method.\n * Dispatches the message calling all subscribers registered for this message and, if the message is a string, calling all pattern subscribers when message matches the pattern.\n * Each subscriber is passed the same parameters that are passed to theis method.\n * The context of the subscriber envocation is set to the host object (`this._hostObject`) that was passed to the messenger constructor.\n * Subscribers are called in the next tick (\"asynchronously\") apart from those that were subscribed with `onSync` (or that have `options.sync == true`).\n *\n * @param {String|RegExp} message message to be dispatched\n * If the message is a string, the subscribers registered with exactly this message will be called and also pattern subscribers registered with the pattern that matches the dispatched message.\n * If the message is RegExp, only the subscribers registered with exactly this pattern will be called.\n * @param {Any} data data that will be passed to the subscriber as the second parameter. Messenger does not modify this data in any way.\n * @param {Function} callback optional callback to pass to subscriber\n * @param {Boolean} _synchronous if true passed, subscribers will be envoked synchronously apart from those that have `options.sync == false`. This parameter should not be used, instead postMessageSync should be used.\n */\nfunction postMessage(message, data, callback, _synchronous) {\n check(message, Match.OneOf(String, RegExp));\n check(callback, Match.Optional(Function));\n\n var subscribersHash = this._chooseSubscribersHash(message);\n var msgSubscribers = subscribersHash[message];\n\n this._callSubscribers(message, data, callback, msgSubscribers, _synchronous);\n\n if (typeof message == 'string')\n this._callPatternSubscribers(message, data, callback, msgSubscribers, _synchronous);\n}\n\n\n/**\n * Same as postMessage apart from envoking subscribers synchronously, apart from those subscribed with `onAsync` (or with `options.sync == false`).\n *\n * @param {String|RegExp} message\n * @param {Any} data\n * @param {Function} callback\n */\nfunction postMessageSync(message, data, callback) {\n this.postMessage(message, data, callback, true);\n}\n\n\n/**\n * \"Private\" Messenger instance method\n * Envokes pattern subscribers with the pattern that matches the message.\n * The method is called by [postMessage](#postMessage) - see more information there.\n *\n * @private\n * @param {String} message message to be dispatched. Pattern subscribers registered with the pattern that matches the dispatched message will be called.\n * @param {Any} data data that will be passed to the subscriber as the second parameter. Messenger does not modify this data in any way.\n * @param {Function} callback optional callback to pass to subscriber\n * @param {Array[Function|Object]} calledMsgSubscribers array of subscribers already called, they won't be called again if they are among pattern subscribers.\n */\nfunction _callPatternSubscribers(message, data, callback, calledMsgSubscribers, _synchronous) {\n _.eachKey(this._patternMessageSubscribers,\n function(patternSubscribers) {\n var pattern = patternSubscribers.pattern;\n if (pattern.test(message)) {\n if (calledMsgSubscribers) {\n var patternSubscribers = patternSubscribers.filter(function(subscriber) {\n var index = _indexOfSubscriber.call(this, calledMsgSubscribers, subscriber);\n return index == -1;\n });\n }\n this._callSubscribers(message, data, callback, patternSubscribers, _synchronous);\n }\n }\n , this);\n}\n\n\n/**\n * \"Private\" Messenger instance method\n * Envokes subscribers from the passed list.\n * The method is called by [postMessage](#postMessage) and [_callPatternSubscribers](#_callPatternSubscribers).\n *\n * @private\n * @param {String} message message to be dispatched, passed to subscribers as the first parameter.\n * @param {Any} data data that will be passed to the subscriber as the second parameter. Messenger does not modify this data in any way.\n * @param {Array[Function|Object]} msgSubscribers the array of message subscribers to be called. Each subscriber is called with the host object (see Messenger constructor) as the context.\n * @param {Function} callback optional callback to pass to subscriber\n */\nfunction _callSubscribers(message, data, callback, msgSubscribers, _synchronous) {\n if (msgSubscribers && msgSubscribers.length) {\n // cloning is necessary as some of the subscribers\n // can be unsubscribed during the dispatch\n // so this array would change in the process\n msgSubscribers = msgSubscribers.slice();\n\n msgSubscribers.forEach(function(subscriber) {\n this._callSubscriber(subscriber, message, data, callback, _synchronous);\n }, this);\n }\n}\n\n\nfunction _callSubscriber(subscriber, message, data, callback, _synchronous) {\n var syncSubscriber = subscriber.options && subscriber.options.sync\n , synchro = (_synchronous && syncSubscriber !== false)\n || syncSubscriber;\n\n var dispatchTimes = subscriber.options && subscriber.options.dispatchTimes;\n if (dispatchTimes) {\n if (dispatchTimes <= 1) {\n var messages = subscriber.__messages;\n this.off(messages, subscriber);\n } else if (dispatchTimes > 1)\n subscriber.options.dispatchTimes--;\n }\n\n if (synchro)\n subscriber.subscriber.call(subscriber.context, message, data, callback);\n else\n _.deferMethod(subscriber.subscriber, 'call', subscriber.context, message, data, callback);\n}\n\n\n/**\n * Messenger instance method.\n * Returns the array of subscribers that would be called if the message were dispatched.\n * If `includePatternSubscribers === false`, pattern subscribers with matching patters will not be included (by default they are included).\n * If there are no subscribers to the message, `undefined` will be returned, not an empty array, so it is safe to use the result in boolean tests.\n *\n * @param {String|RegExp} message Message to get subscribers for.\n * If the message is RegExp, only pattern subscribers registered with exactly this pattern will be returned.\n * If the message is String, subscribers registered with the string messages and pattern subscribers registered with matching pattern will be returned (unless the second parameter is false).\n * @param {Boolean} includePatternSubscribers Optional false to prevent inclusion of patter subscribers, by default they are included.\n * @return {Array|undefined}\n */\nfunction getSubscribers(message, includePatternSubscribers) {\n check(message, Match.OneOf(String, RegExp));\n\n var subscribersHash = this._chooseSubscribersHash(message);\n var msgSubscribers = subscribersHash[message]\n ? [].concat(subscribersHash[message])\n : [];\n\n // pattern subscribers are incuded by default\n if (includePatternSubscribers !== false && typeof message == 'string') {\n _.eachKey(this._patternMessageSubscribers,\n function(patternSubscribers) {\n var pattern = patternSubscribers.pattern;\n if (patternSubscribers && patternSubscribers.length\n && pattern.test(message))\n _.appendArray(msgSubscribers, patternSubscribers);\n }\n );\n }\n\n // return undefined if there are no subscribers\n return msgSubscribers.length\n ? msgSubscribers\n : undefined;\n}\n\n\n/**\n * \"Private\" Messenger instance method\n * Returns the map of subscribers for a given message type.\n *\n * @private\n * @param {String|RegExp} message Message to choose the map of subscribers for\n * @return {Object[Function]}\n */\nfunction _chooseSubscribersHash(message) {\n return message instanceof RegExp\n ? this._patternMessageSubscribers\n : this._messageSubscribers;\n}\n\n\n/**\n * Messenger instance method\n * Sets [MessageSource](./m_source.js.html) for the messenger also setting the reference to the messenger in the MessageSource.\n * MessageSource can be passed to message constructor; this method allows to set it at a later time. For example, the subclasses of [ComponentFacet](../components/c_facet.js.html) use this method to set different MessageSource'es in the messenger that is created by ComponentFacet.\n * Currently the method is implemented in such way that it can be called only once - MessageSource cannot be changed after this method is called.\n *\n * @param {MessageSource} messageSource an instance of MessageSource class to attach to this messenger (and to have this messenger attached to it too)\n */\nfunction _setMessageSource(messageSource) {\n check(messageSource, MessageSource);\n\n _.defineProperty(this, '_messageSource', messageSource);\n messageSource.messenger = this;\n}\n\n\n/**\n * Messenger instance method\n * Returns messenger MessageSource\n *\n * @return {MessageSource}\n */\nfunction getMessageSource() {\n return this._messageSource\n}\n", + "arguments[4][68][0].apply(exports,arguments)", + "arguments[4][69][0].apply(exports,arguments)", + "'use strict';\n\nvar Mixin = require('../abstract/mixin')\n , MessengerAPI = require('./m_api')\n , logger = require('../util/logger')\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match;\n\n\n/**\n * `milo.classes.MessageSource`\n * An abstract class (subclass of [Mixin](../abstract/mixin.js.html)) for connecting [Messenger](./index.js.html) to external sources of messages (like DOM events) and defining higher level messages.\n * An instance of MessageSource can either be passed to Messenger constructor or later using `_setMessageSource` method of Messenger. Once set, MessageSource of Messenger cannot be changed.\n */\nvar MessageSource = _.createSubclass(Mixin, 'MessageSource', true);\n\nmodule.exports = MessageSource;\n\n\n/**\n * ####MessageSource instance methods####\n *\n * - [init](#init) - initializes messageSource - called by Mixin superclass\n * - [setMessenger](#setMessenger) - connects Messenger to MessageSource, is called from `init` or `_setMessageSource` methods of [Messenger](./index.js.html).\n * - [onSubscriberAdded](#onSubscriberAdded) - called by Messenger to notify when the first subscriber for an internal message was added, so MessageSource can subscribe to source\n * - [onSubscriberRemoved](#onSubscriberRemoved) - called by Messenger to notify when the last subscriber for an internal message was removed, so MessageSource can unsubscribe from source\n * - [dispatchMessage](#dispatchMessage) - dispatches source message. MessageSource subclass should implement mechanism when on actual source message this method is called.\n *\n * Methods below should be implemented in subclass:\n *\n * - [trigger](#trigger) - triggers messages on the source (an optional method)\n * - [addSourceSubscriber](#addSourceSubscriber) - adds listener/subscriber to external message\n * - [removeSourceSubscriber](#removeSourceSubscriber) - removes listener/subscriber from external message\n */\n_.extendProto(MessageSource, {\n init: init,\n destroy: MessageSource$destroy,\n setMessenger: setMessenger,\n onSubscriberAdded: onSubscriberAdded,\n onSubscriberRemoved: onSubscriberRemoved, \n dispatchMessage: dispatchMessage,\n postMessage: postMessage,\n _prepareMessengerAPI: _prepareMessengerAPI,\n\n // Methods below must be implemented in subclass\n trigger: toBeImplemented,\n addSourceSubscriber: toBeImplemented,\n removeSourceSubscriber: toBeImplemented\n});\n\n\n/**\n * MessageSource instance method.\n * Called by Mixin constructor.\n * MessageSource constructor should be passed the same parameters as this method signature.\n * If an instance of [MessengerAPI](./m_api.js.html) is passed as the third parameter, it extends MessageSource functionality to allow it to define new messages, to filter messages based on their data and to change message data. See [MessengerAPI](./m_api.js.html).\n *\n * @param {Object} hostObject Optional object that stores the MessageSource on one of its properties. It is used to proxy methods of MessageSource.\n * @param {Object[String]} proxyMethods Optional map of method names; key - proxy method name, value - MessageSource's method name.\n * @param {MessengerAPI} messengerAPI Optional instance of MessengerAPI.\n */\nfunction init(hostObject, proxyMethods, messengerAPI) {\n this._prepareMessengerAPI(messengerAPI);\n}\n\n\n/**\n * Destroys message source\n */\nfunction MessageSource$destroy() {\n if (this.messengerAPI)\n this.messengerAPI.destroy();\n}\n\n\n/**\n * MessageSource instance method.\n * Sets reference to Messenger instance.\n *\n * @param {Messenger} messenger reference to Messenger instance linked to this MessageSource\n */\nfunction setMessenger(messenger) {\n _.defineProperty(this, 'messenger', messenger);\n}\n\n\n/**\n * MessageSource instance method.\n * Prepares [MessengerAPI](./m_api.js.html) passed to constructor by proxying its methods to itself or if MessengerAPI wasn't passed defines two methods to avoid checking their availability every time the message is dispatched.\n *\n * @private\n * @param {MessengerAPI} messengerAPI Optional instance of MessengerAPI\n */\nfunction _prepareMessengerAPI(messengerAPI) {\n check(messengerAPI, Match.Optional(MessengerAPI));\n\n if (! messengerAPI)\n messengerAPI = new MessengerAPI;\n\n _.defineProperty(this, 'messengerAPI', messengerAPI);\n}\n\n\n/**\n * MessageSource instance method.\n * Subscribes to external source using `addSourceSubscriber` method that should be implemented in subclass.\n * This method is called by [Messenger](./index.js.html) when the first subscriber to the `message` is added.\n * Delegates to supplied or default [MessengerAPI](./m_api.js.html) for translation of `message` to `sourceMessage`. `MessageAPI.prototype.addInternalMessage` will return undefined if this `sourceMessage` was already subscribed to to prevent duplicate subscription.\n *\n * @param {String} message internal Messenger message that has to be subscribed to at the external source of messages.\n */\nfunction onSubscriberAdded(message) {\n var newSourceMessage = this.messengerAPI.addInternalMessage(message);\n if (typeof newSourceMessage != 'undefined')\n this.addSourceSubscriber(newSourceMessage);\n}\n\n\n/**\n * MessageSource instance method.\n * Unsubscribes from external source using `removeSourceSubscriber` method that should be implemented in subclass.\n * This method is called by [Messenger](./index.js.html) when the last subscriber to the `message` is removed.\n * Delegates to supplied or default [MessengerAPI](./m_api.js.html) for translation of `message` to `sourceMessage`. `MessageAPI.prototype.removeInternalMessage` will return undefined if this `sourceMessage` was not yet subscribed to to prevent unsubscription without previous subscription.\n *\n * @param {String} message internal Messenger message that has to be unsubscribed from at the external source of messages.\n */\nfunction onSubscriberRemoved(message) {\n var removedSourceMessage = this.messengerAPI.removeInternalMessage(message);\n if (typeof removedSourceMessage != 'undefined')\n this.removeSourceSubscriber(removedSourceMessage);\n}\n\n\n/**\n * MessageSource instance method.\n * Dispatches sourceMessage to Messenger.\n * Mechanism that calls this method when the source message is received should be implemented by subclass (see [DOMEventsSource](../components/msg_src/dom_events.js.html) for example).\n * Delegates to supplied or default [MessengerAPI](./m_api.js.html) to create internal message data (`createInternalData`) and to filter the message based on its data and/or message (`filterSourceMessage`).\n * Base MessengerAPI class implements these two methods in a trivial way (`createInternalData` simply returns external data, `filterSourceMessage` returns `true`), they are meant to be implemented by subclass.\n *\n * @param {String} sourceMessage source message received from external source\n * @param {Object} sourceData data received from external source\n */\nfunction dispatchMessage(sourceMessage, sourceData) {\n var api = this.messengerAPI\n , internalMessages = api.getInternalMessages(sourceMessage);\n\n if (internalMessages) \n internalMessages.forEach(function (message) {\n var internalData = api.createInternalData(sourceMessage, message, sourceData);\n\n var shouldDispatch = api.filterSourceMessage(sourceMessage, message, internalData);\n if (shouldDispatch) \n this.postMessage(message, internalData); \n \n }, this);\n}\n\n\n/**\n * Posts message on the messenger. This method is separated so specific message sources can make message dispatch synchronous by using `postMessageSync`\n * \n * @param {String} message\n * @param {Object} data\n */\nfunction postMessage(message, data) {\n this.messenger.postMessage(message, data);\n}\n\n\nfunction toBeImplemented() {\n throw new Error('calling the method of an absctract class');\n}\n", + "arguments[4][71][0].apply(exports,arguments)", + "'use strict';\n\nvar _ = require('mol-proto');\n\n\n/**\n * ####Milo packages####\n *\n * - [minder](./minder.js.html) - data reactivity, one or two way, shallow or deep, as you like it\n * - [config](./config.js.html) - milo configuration\n * - [util](./util/index.js.html) - logger, request, dom, check, error, etc.\n * - [classes](./classes.js.html) - abstract and base classes\n * - [Messenger](./messenger/index.js.html) - generic Messenger used in most other milo classes, can be mixed into app classes too.\n * - [Model](./model/index.js.html) - Model class that emits messages on changes to any depth without timer based watching\n */\nvar milo = {\n minder: require('./minder'),\n config: require('./config'),\n util: require('./util'),\n classes: require('./classes'),\n Messenger: require('./messenger'),\n Model: require('./model'),\n destroy: destroy\n};\n\n\n// export for node/browserify\nif (typeof module == 'object' && module.exports) \n module.exports = milo;\n\n// global milo for browser\nif (typeof window == 'object')\n window.milo = milo;\n\n\nfunction destroy() {\n milo.minder.destroy();\n}\n", + "'use strict';\n\nvar Connector = require('./model/connector')\n , Messenger = require('./messenger')\n , _ = require('mol-proto')\n , logger = require('./util/logger');\n\n\nmodule.exports = minder;\n\n\n/**\n * This function creates one or many Connector objects that\n * create live reactive connection between objects implementing\n * dataSource interface:\n * Objects should emit messages when any part of their data changes,\n * methods `on` and `off` should be implemented to subscribe/unsubscribe\n * to change notification messages, methods `set` and `get` should be implemented to get/set data\n * on path objects, pointing to particular parts of the object, method `path`\n * should return path object for a given path string (see path utils for path string syntax).\n * Both Model and Data facet are such data sources, they can be linked by Connector object.\n *\n * @param {Object} ds1 the first data source. Instead of the first data source an array can be passed with arrays of Connection objects parameters in each array element.\n * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @param {Object} ds2 the second data source\n * @param {Object} options not implemented yet\n */\nfunction minder(ds1, mode, ds2, options) {\n if (Array.isArray(ds1)) {\n var connDescriptions = ds1;\n var connectors = connDescriptions.map(function(descr) {\n return new Connector(descr[0], descr[1], descr[2], descr[3]);\n });\n connectors.forEach(_addConnector);\n return connectors;\n } else {\n var cnct = new Connector(ds1, mode, ds2, options);\n _addConnector(cnct);\n return cnct;\n }\n}\n\n\n/**\n * messenger of minder where it emits events related to all connectors\n * @type {Messenger}\n */\nvar _messenger = new Messenger(minder, Messenger.defaultMethods);\n\n\nvar _connectors = []\n , _receivedMessages = []\n , _isPropagating = false;\n\n\n_.extend(minder, {\n getConnectors: minder_getConnectors,\n getExpandedConnections: minder_getExpandedConnections,\n isPropagating: minder_isPropagating,\n whenPropagationCompleted: minder_whenPropagationCompleted,\n destroyConnector: minder_destroyConnector,\n destroy: minder_destroy\n});\n\n\nfunction _addConnector(cnct) {\n cnct.___minder_id = _connectors.push(cnct) - 1;\n cnct.on(/.*/, onConnectorMessage);\n minder.postMessage('added', { connector: cnct });\n minder.postMessage('turnedon', { connector: cnct });\n}\n\n\nfunction onConnectorMessage(msg, data) {\n var data = data ? _.clone(data) : {};\n _.extend(data, {\n id: this.___minder_id,\n connector: this\n });\n minder.postMessage(msg, data);\n if (! _receivedMessages.length && ! _isPropagating) {\n _.defer(_idleCheck);\n _isPropagating = true;\n }\n\n _receivedMessages.push({ msg: msg, data: data });\n}\n\n\nfunction _idleCheck() {\n if (_receivedMessages.length) {\n _receivedMessages.length = 0;\n _.defer(_idleCheck);\n minder.postMessage('propagationticked');\n } else {\n _isPropagating = false;\n minder.postMessage('propagationcompleted');\n }\n}\n\n\nfunction minder_isPropagating() {\n return _isPropagating;\n}\n\n\nfunction minder_whenPropagationCompleted(callback) {\n if (_isPropagating)\n minder.once('propagationcompleted', executeCallback);\n else\n _.defer(executeCallback);\n\n function executeCallback() {\n if (_isPropagating)\n minder.once('propagationcompleted', executeCallback);\n else\n callback();\n }\n}\n\n\nfunction minder_getConnectors(onOff) {\n if (typeof onOff == 'undefined')\n return _connectors;\n\n return _connectors.filter(function(cnct) {\n return cnct.isOn === onOff;\n });\n}\n\n\nfunction minder_destroyConnector(cnct) {\n cnct.destroy();\n var index = _connectors.indexOf(cnct);\n if (index >= 0)\n delete _connectors[index];\n else\n logger.warn('minder: connector destroyed that is not registered in minder');\n}\n\n\nfunction minder_getExpandedConnections(onOff, searchStr) {\n var connectors = minder.getConnectors(onOff);\n var connections = connectors.map(function(cnct) {\n var connection = {\n leftSource: _getExpandedSource(cnct.ds1),\n rightSource: _getExpandedSource(cnct.ds2),\n mode: cnct.mode,\n isOn: cnct.isOn\n };\n \n if (cnct.options)\n connection.options = cnct.options;\n\n return connection;\n });\n\n if (searchStr)\n connections = connections.filter(function(cnctn) {\n return _sourceMatchesString(cnctn.leftSource, searchStr)\n || _sourceMatchesString(cnctn.rightSource, searchStr);\n });\n\n return connections;\n}\n\n\nfunction _getExpandedSource(ds) {\n var source = [];\n if (typeof ds == 'function') {\n if (ds._model && ds._accessPath) {\n source.unshift(ds._accessPath);\n ds = ds._model;\n }\n\n source.unshift(ds);\n ds = ds._hostObject;\n }\n\n if (typeof ds == 'object') {\n source.unshift(ds);\n\n if (ds.owner)\n source.unshift(ds.owner);\n }\n\n return source;\n}\n\n\nfunction _sourceMatchesString(source, matchStr) {\n return source.some(function(srcNode) {\n var className = srcNode.constructor && srcNode.constructor.name;\n return _stringMatch(className, matchStr)\n || _stringMatch(srcNode.name, matchStr)\n || _stringMatch(srcNode, matchStr);\n });\n}\n\n\nfunction _stringMatch(str, substr) {\n return str && typeof str == 'string' && str.indexOf(substr) >= 0;\n}\n\n\nfunction minder_destroy() {\n _connectors.forEach(function(cnct) {\n destroyDS(cnct.ds1);\n destroyDS(cnct.ds2);\n cnct.destroy();\n });\n _messenger.destroy();\n minder._destroyed = true;\n\n function destroyDS(ds) {\n if (ds && !ds._destroyed) ds.destroy();\n }\n}\n", + "'use strict';\n\n\nvar logger = require('../util/logger')\n , config = require('../config')\n , pathUtils = require('./path_utils')\n , _ = require('mol-proto');\n\n/**\n * Utility function to process \"changedata\" messages emitted by Connector object.\n */\nmodule.exports = changeDataHandler;\n\n\n_.extend(changeDataHandler, {\n setTransactionFlag: setTransactionFlag,\n getTransactionFlag: getTransactionFlag,\n passTransactionFlag: passTransactionFlag,\n postTransactionFinished: postTransactionFinished\n});\n\n\n/**\n * Change data uses hidden property on accessor methods to pass flag that the accessor is executed as a part of change transaction.\n * Accessor methods are supposed to store this flag in a local variable and to clear it (because another accessor can be executed in or out of transaction) using `getTransactionFlag`\n *\n * @private\n * @param {Function} func accessor method reference\n * @param {Boolean} flag a flag to be set\n */\nfunction setTransactionFlag(func, flag) {\n _.defineProperty(func, '__inChangeTransaction', flag, _.CONF | _.WRIT);\n}\n\n\n/**\n * Retrieves and clears transaction flag from accessor method\n *\n * @private\n * @param {Function} func accessor method reference\n * @return {Boolean}\n */\nfunction getTransactionFlag(func) {\n var inTransaction = func.__inChangeTransaction;\n delete func.__inChangeTransaction;\n return inTransaction;\n}\n\n\nfunction passTransactionFlag(fromFunc, toFunc) {\n var inTransaction = getTransactionFlag(fromFunc);\n setTransactionFlag(toFunc, inTransaction);\n return inTransaction;\n}\n\n\n/**\n * Posts message on this to indicate the end of transaction unless `inChangeTransaction` is `true`.\n */\nfunction postTransactionFinished() {\n this.postMessageSync('datachanges', { transaction: false, changes: [] });\n}\n\n\n/**\n * subscriber to \"changedata\" event emitted by [Connector](./connector.js.html) object to enable reactive connections\n * Used by Data facet, Model and ModelPath. Can be used by any object that implements get/set/del/splice api and sets data deeply to the whole tree.\n * Object should call `changeDataHandler.initialize.call(this)` in its constructor.\n * TODO: optimize messages list to avoid setting duplicate values down the tree\n *\n * @param {String} msg should be \"changedata\" here\n * @param {Object} data batch of data change desciption objects\n * @param {Function} callback callback to call before and after the data is processed\n */\nfunction changeDataHandler(message, data, callback) {\n processChanges.call(this, data.changes, callback);\n}\n\n\n// map of message types to methods\nvar CHANGE_TYPE_TO_METHOD_MAP = {\n 'added': 'set',\n 'changed': 'set',\n 'deleted': 'del',\n 'removed': 'del'\n};\n\n\n/**\n * Processes queued \"changedata\" messages.\n * Posts \"changestarted\" and \"changecompleted\" messages and calls callback\n *\n * @param {[Function]} callback optional callback that is called with `(null, false)` parameters before change processing starts and `(null, true)` after it's finished.\n */\nfunction processChanges(transaction, callback) {\n notify.call(this, callback, false);\n processTransaction.call(this,\n prepareTransaction(\n validateTransaction(transaction)));\n notify.call(this, callback, true);\n}\n\n\nfunction notify(callback, changeFinished) {\n callback && callback(null, changeFinished);\n this.postMessage(changeFinished ? 'changecompleted' : 'changestarted');\n}\n\n\n/**\n * Checks that all messages from the transaction come from the same source.\n * Hack: reverses the transaction if it comes from the Data facet\n * Returns the reference to the transaction (for chaining)\n * \n * @param {Array} transaction transaction of data changes\n * @return {Array} \n */\nfunction validateTransaction(transaction) {\n var source = transaction[0].source\n , sameSource = true;\n\n if (transaction.length > 1) {\n for (var i = 1, len = transaction.length; i < len; i++)\n if (transaction[i].source != source) {\n logger.error('changedata: changes from different sources in the same transaction, sources:', transaction[i].source.name, source.name);\n sameSource = false;\n source = transaction[i].source;\n }\n }\n\n return transaction;\n}\n\n\nfunction prepareTransaction(transaction) {\n var todo = []\n , pathsToSplice = []\n , pathsToChange = []\n , hadSplice\n , exitLoop = {};\n\n\n try { transaction.forEach(checkChange); }\n catch (e) { if (e != exitLoop) throw e; }\n\n return todo;\n\n\n function checkChange(data) {\n (data.type == 'splice' ? checkSplice : checkMethod)(data);\n }\n\n\n function checkSplice(data) {\n var parsedPath = pathUtils.parseAccessPath(data.path);\n var parentPathChanged = pathsToChange.some(function(parentPath) {\n if (parsedPath.length < parentPath.length) return;\n return _pathIsParentOf(parentPath, parsedPath);\n });\n\n if (parentPathChanged) return;\n\n todo.push(data);\n\n if (! config.debug) throw exitLoop;\n pathsToSplice.push(parsedPath);\n hadSplice = true;\n }\n\n\n function checkMethod(data) {\n var parsedPath = pathUtils.parseAccessPath(data.path);\n var parentPathSpliced = pathsToSplice && pathsToSplice.some(function(parentPath) {\n if (parsedPath.length <= parentPath.length\n || parsedPath[parentPath.length].syntax != 'array') return;\n return _pathIsParentOf(parentPath, parsedPath);\n });\n\n if (parentPathSpliced) return;\n if (hadSplice) logger.error('changedata: child change is executed after splice; probably data source did not emit message with data.type==\"finished\"');\n\n var parentPathChanged = pathsToChange.some(function(parentPath) {\n if (parsedPath.length <= parentPath.length) return;\n return _pathIsParentOf(parentPath, parsedPath);\n });\n\n if (parentPathChanged) return;\n\n pathsToChange.push(parsedPath);\n\n todo.push(data);\n }\n\n\n function _pathIsParentOf(parentPath, childPath) {\n return parentPath.every(function(pathNode, index) {\n return pathNode.property == childPath[index].property;\n });\n }\n}\n\n\nfunction processTransaction(transaction) {\n transaction.forEach(processChange, this);\n postTransactionFinished.call(this, false);\n\n function processChange(data) {\n var modelPath = this.path(data.path, data.type != 'removed' && data.type != 'deleted');\n if (! modelPath) return;\n (data.type == 'splice' ? executeSplice : executeMethod)(modelPath, data);\n }\n}\n\n\nfunction executeSplice(modelPath, data) {\n var index = data.index\n , howMany = data.removed.length\n , spliceArgs = [index, howMany];\n\n spliceArgs = spliceArgs.concat(data.newValue.slice(index, index + data.addedCount));\n setTransactionFlag(modelPath.splice, true);\n modelPath.splice.apply(modelPath, spliceArgs);\n}\n\n\nfunction executeMethod(modelPath, data) {\n var methodName = CHANGE_TYPE_TO_METHOD_MAP[data.type];\n if (methodName) {\n setTransactionFlag(modelPath[methodName], true);\n modelPath[methodName](data.newValue);\n } else\n logger.error('unknown data change type');\n}\n", + "'use strict';\n\nvar Messenger = require('../messenger')\n , pathUtils = require('./path_utils')\n , _ = require('mol-proto')\n , logger = require('../util/logger');\n\n\nmodule.exports = Connector;\n\n\nvar modePattern = /^(\\<*)\\-+(\\>*)$/;\n\n\n/**\n * Connector\n * Class that creates connector object for data connection between\n * two data-sources\n * Data-sources should implement the following API:\n * get() - get value from datasource or its path\n * set(value) - set value to datasource or to its path\n * on(path, subscriber) - subscription to data changes with \"*\" support\n * off(path, subscriber)\n * path(accessPath) - to return the object that gives reference to some part of datasource\n * and complies with that api too.\n *\n * ####Events####\n *\n * - 'turnedon' - connector was turned on\n * - 'turnedoff' - connector was turned off\n * - 'changestarted' - change on connected datasource is started\n * - 'changecompleted' - change on connected datasource is completed\n * - 'destroyed' - connector was destroyed\n * \n * @param {Object} ds1 the first data source.\n * @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @param {Object} ds2 the second data source\n * @param {Object} options not implemented yet\n * @return {Connector} when called with `new`, creates a Connector object.\n */\nfunction Connector(ds1, mode, ds2, options) {\n setupMode.call(this, mode);\n\n _.extend(this, {\n ds1: ds1,\n ds2: ds2,\n isOn: false,\n _changesQueue1: [],\n _changesQueue2: [],\n _messenger: new Messenger(this, Messenger.defaultMethods)\n });\n\n if (options) {\n this.options = options;\n\n var pathTranslation = options.pathTranslation;\n if (pathTranslation) {\n pathTranslation = _.clone(pathTranslation);\n var patternTranslation = getPatternTranslations(pathTranslation);\n _.extend(this, {\n pathTranslation1: reverseTranslationRules(pathTranslation),\n pathTranslation2: pathTranslation,\n patternTranslation1: reversePatternTranslationRules(patternTranslation),\n patternTranslation2: patternTranslation\n });\n }\n\n var dataTranslation = options.dataTranslation;\n if (dataTranslation) {\n _.extend(this, {\n dataTranslation1: dataTranslation['<-'],\n dataTranslation2: dataTranslation['->']\n });\n }\n\n var dataValidation = options.dataValidation;\n if (dataValidation) {\n _.extend(this, {\n dataValidation1: dataValidation['<-'],\n dataValidation2: dataValidation['->']\n });\n }\n }\n\n this.turnOn();\n}\n\n\nfunction setupMode(mode){\n var parsedMode = mode.match(modePattern);\n\n if (! parsedMode)\n modeParseError();\n\n var depth1 = parsedMode[1].length\n , depth2 = parsedMode[2].length;\n\n if (depth1 && depth2 && depth1 != depth2)\n modeParseError();\n\n if (! depth1 && ! depth2)\n modeParseError();\n\n _.extend(this, {\n mode: mode,\n depth1: depth1,\n depth2: depth2,\n });\n\n function modeParseError() {\n throw new Error('invalid Connector mode: ' + mode);\n }\n}\n\n\n_.extendProto(Connector, {\n turnOn: Connector$turnOn,\n turnOff: Connector$turnOff,\n destroy: Connector$destroy,\n changeMode: Connector$changeMode,\n deferChangeMode: Connector$deferChangeMode\n});\n\n/**\n * Function change the mode of the connection\n *\n * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @return {Object[String]}\n */\nfunction Connector$changeMode(mode) {\n this.turnOff();\n setupMode.call(this, mode);\n this.turnOn();\n return this;\n}\n\n\n/**\n * Function change the mode of the connection\n *\n * @param @param {String} mode the connection mode that defines the direction and the depth of connection. Possible values are '->', '<<-', '<<<->>>', etc.\n * @return {Object[String]}\n */\nfunction Connector$deferChangeMode(mode) {\n _.deferMethod(this, 'changeMode', mode);\n return this;\n}\n\n\n/**\n * Function that reverses translation rules for paths of connected odata sources\n *\n * @param {Object[String]} rules map of paths defining the translation rules\n * @return {Object[String]}\n */\nfunction reverseTranslationRules(rules) {\n var reverseRules = {};\n _.eachKey(rules, function(path2_value, path1_key) {\n reverseRules[path2_value] = path1_key;\n });\n return reverseRules;\n}\n\n\nfunction getPatternTranslations(pathTranslation) {\n var patternTranslation = [];\n _.eachKey(pathTranslation, function(path2_value, path1_key) {\n var starIndex1 = path1_key.indexOf('*')\n , starIndex2 = path2_value.indexOf('*');\n if (starIndex1 >= 0 && starIndex2 >= 0) { // pattern translation\n if (path1_key.slice(starIndex1) != path2_value.slice(starIndex2))\n _throwInvalidTranslation(path1_key, path2_value);\n delete pathTranslation[path1_key]; \n\n patternTranslation.push({\n fromPattern: pathUtils.createRegexPath(path1_key),\n fromStaticPath: _getStaticPath(path1_key, starIndex1),\n toPattern: pathUtils.createRegexPath(path2_value),\n toStaticPath: _getStaticPath(path2_value, starIndex2)\n });\n } else if (starIndex1 >= 0 || starIndex2 >= 0) // pattern only on one side of translation\n _throwInvalidTranslation(path1_key, path2_value);\n });\n\n return patternTranslation;\n\n\n function _throwInvalidTranslation(path1, path2) {\n throw new Error('Invalid pattern translation: ' + path1 + ', ' + path2);\n }\n\n\n function _getStaticPath(path, starIndex) {\n return path.replace(/[\\.\\[]?\\*.*$/, '');\n }\n}\n\n\nfunction reversePatternTranslationRules(patternTranslation) {\n return patternTranslation.map(function(pt) {\n return {\n fromPattern: pt.toPattern,\n fromStaticPath: pt.toStaticPath,\n toPattern: pt.fromPattern,\n toStaticPath: pt.fromStaticPath\n };\n });\n}\n\n\n/**\n * turnOn\n * Method of Connector that enables connection (if it was previously disabled)\n */\nfunction Connector$turnOn() {\n if (this.isOn)\n return logger.warn('data sources are already connected');\n\n var subscriptionPath = this._subscriptionPath =\n new Array(this.depth1 || this.depth2).join('*');\n\n var subscriptionPattern = pathUtils.createRegexPath(subscriptionPath);\n\n var self = this;\n if (this.depth1)\n this._link1 = linkDataSource('_link2', this.ds2, this.ds1, this._changesQueue1, this.pathTranslation1, this.patternTranslation1, this.dataTranslation1, this.dataValidation1);\n if (this.depth2)\n this._link2 = linkDataSource('_link1', this.ds1, this.ds2, this._changesQueue2, this.pathTranslation2, this.patternTranslation2, this.dataTranslation2, this.dataValidation2);\n\n this.isOn = true;\n this.postMessage('turnedon');\n\n\n function linkDataSource(reverseLink, fromDS, toDS, changesQueue, pathTranslation, patternTranslation, dataTranslation, dataValidation) {\n fromDS.onSync('datachanges', onData);\n return onData;\n\n function onData(message, batch) {\n var sendData = {\n changes: [],\n transaction: batch.transaction\n }\n\n batch.changes.forEach(function(change) {\n var sourcePath = change.path\n , targetPath = translatePath(sourcePath);\n\n if (typeof targetPath == 'undefined') return;\n\n var change = _.clone(change);\n _.extend(change, {\n source: fromDS,\n path: targetPath\n });\n\n translateData(sourcePath, change);\n validateData(sourcePath, change);\n });\n\n if (! changesQueue.length)\n _.defer(postChangeData);\n\n changesQueue.push(sendData);\n\n\n function translatePath(sourcePath) {\n if (pathTranslation) {\n var translatedPath = pathTranslation[sourcePath];\n if (translatedPath) return translatedPath;\n if (!patternTranslation.length) return;\n var pt = _.find(patternTranslation, function(pTranslation) {\n return pTranslation.fromPattern.test(sourcePath);\n });\n if (!pt) return;\n var translatedPath = sourcePath.replace(pt.fromStaticPath, pt.toStaticPath);\n } else if (! ((subscriptionPattern instanceof RegExp\n && subscriptionPattern.test(sourcePath))\n || subscriptionPattern == sourcePath)) return;\n\n return translatedPath || sourcePath;\n }\n\n\n function translateData(sourcePath, change) {\n if (dataTranslation) {\n var translate = dataTranslation[sourcePath];\n if (translate && typeof translate == 'function') {\n change.oldValue = translate(change.oldValue);\n change.newValue = translate(change.newValue);\n }\n }\n }\n\n \n function validateData(sourcePath, change) {\n propagateData(change);\n\n if (dataValidation) {\n var validators = dataValidation[sourcePath]\n , passedCount = 0\n , alreadyFailed = false;\n\n if (validators)\n validators.forEach(callValidator); \n }\n\n\n function callValidator(validator) {\n validator(change.newValue, function(err, response) {\n response.path = sourcePath;\n if (! alreadyFailed && (err || response.valid) && ++passedCount == validators.length) {\n fromDS.postMessage('validated', response);\n } else if (! response.valid) {\n alreadyFailed = true;\n fromDS.postMessage('validated', response);\n }\n });\n }\n }\n\n\n function propagateData(change) {\n sendData.changes.push(change);\n }\n\n\n function postChangeData() {\n // prevent endless loop of updates for 2-way connection\n if (self[reverseLink]) var callback = subscriptionSwitch;\n\n var transactions = mergeTransactions(changesQueue);\n changesQueue.length = 0;\n transactions.forEach(function(transaction) {\n // send data change instruction as message\n toDS.postMessageSync('changedata', { changes: transaction }, callback);\n });\n }\n\n\n function subscriptionSwitch(err, changeFinished) {\n if (err) return;\n var onOff = changeFinished ? 'onSync' : 'off';\n toDS[onOff]('datachanges', self[reverseLink]);\n\n var message = changeFinished ? 'changecompleted' : 'changestarted';\n self.postMessage(message, { source: fromDS, target: toDS });\n }\n\n\n function mergeTransactions(batches) {\n var transactions = []\n , currentTransaction;\n\n batches.forEach(function(batch) {\n if (! batch.transaction) currentTransaction = undefined;\n if (! batch.changes.length) return;\n\n if (batch.transaction) {\n if (currentTransaction)\n _.appendArray(currentTransaction, batch.changes);\n else {\n currentTransaction = _.clone(batch.changes);\n transactions.push(currentTransaction);\n }\n } else\n transactions.push(batch.changes);\n });\n\n return transactions;\n }\n }\n }\n}\n\n\n/**\n * turnOff\n * Method of Connector that disables connection (if it was previously enabled)\n */\nfunction Connector$turnOff() {\n if (! this.isOn)\n return logger.warn('data sources are already disconnected');\n\n var self = this;\n unlinkDataSource(this.ds1, '_link2', this.pathTranslation2);\n unlinkDataSource(this.ds2, '_link1', this.pathTranslation1);\n\n this.isOn = false;\n this.postMessage('turnedoff');\n\n\n function unlinkDataSource(fromDS, linkName, pathTranslation) {\n if (self[linkName]) {\n fromDS.off('datachanges', self[linkName]);\n delete self[linkName];\n }\n }\n}\n\n\n/**\n * Destroys connector object by turning it off and removing references to connected sources\n */\nfunction Connector$destroy() {\n this.turnOff();\n this.postMessage('destroyed');\n this._messenger.destroy();\n delete this.ds1;\n delete this.ds2;\n this._destroyed = true;\n}\n", + "'use strict';\n\nvar ModelPath = require('./m_path')\n , synthesize = require('./synthesize')\n , pathUtils = require('./path_utils')\n , changeDataHandler = require('./change_data')\n , Messenger = require('../messenger')\n , MessengerMessageSource = require('../messenger/msngr_source')\n , ModelMsgAPI = require('./m_msg_api')\n , Mixin = require('../abstract/mixin')\n , _ = require('mol-proto')\n , check = require('../util/check')\n , Match = check.Match\n , logger = require('../util/logger');\n\n\nmodule.exports = Model;\n\n\n/**\n * `milo.Model`\n * Model class instantiates objects that allow deep data access with __safe getters__ that return undefined (rather than throwing exception) when properties/items of unexisting objects/arrays are requested and __safe setters__ that create object trees when properties/items of unexisting objects/arrays are set and also post messages to allow subscription on changes and enable data reactivity.\n * Reactivity is implememnted via [Connector](./connector.js.html) that can be instantiated either directly or with more convenient interface of [milo.minder](../minder.js.html). At the moment model can be connected to [Data facet](../components/c_facets/Data.js.html) or to another model or [ModelPath](./m_path.js.html).\n * Model constructor returns objects that are functions at the same time; when called they return ModelPath objects that allow get/set access to any point in model data. See [ModelData](#ModelData) below.\n *\n * You can subscribe to model changes with `on` method by passing model access path in place of message, pattern or string with any number of stars to subscribe to a certain depth in model (e.g., `'***'` to subscribe to three levels).\n *\n * @constructor\n * @param {Object|Array} data optional initial array data. If it is planned to connect model to view it is usually better to instantiate an empty Model (`var m = new Model`), connect it to [Component](../components/c_class.js.html)'s [Data facet](../components/c_facets/Data.js.html) (e.g., `milo.minder(m, '<<->>', c.data);`) and then set the model with `m.set(data)` - the view will be automatically updated.\n * @param {Object} hostObject optional object that hosts model on one of its properties. Can be used when model itself is the context of the message subscriber and you need to travers to this object (although it is possible to set any context). Can also be used to proxy model's methods to the host like [Model facet](../components/c_facets/ModelFacet.js.html) is doing.\n * @param {Object} options pass { reactive: false } to use model without messaging when it is not needed - it makes it much faster\n * @return {Model}\n */\nfunction Model(data, hostObject, options) {\n // `model` will be returned by constructor instead of `this`. `model`\n // (`modelPath` function) should return a ModelPath object with \"synthesized\" methods\n // to get/set model properties, to subscribe to property changes, etc.\n // Additional arguments of modelPath can be used in the path using interpolation - see ModelPath below.\n var model = function modelPath(accessPath) { // , ... arguments that will be interpolated\n return Model$path.apply(model, arguments);\n };\n model.__proto__ = Model.prototype;\n\n model._hostObject = hostObject;\n model._options = options || {};\n\n if (model._options.reactive !== false) {\n model._prepareMessengers();\n // subscribe to \"changedata\" message to enable reactive connections\n model.onSync('changedata', changeDataHandler);\n }\n\n if (data) model._data = data;\n\n return model;\n}\n\nModel.prototype.__proto__ = Model.__proto__;\n\n\n/**\n * ####Model instance methods####\n *\n * - [path](#path) - returns ModelPath object that allows access to any point in Model\n * - [get](#Model$get) - get model data\n * - set - set model data, synthesized\n * - splice - splice model data (as array or pseudo-array), synthesized\n * - [len](./m_path.js.html#ModelPath$len) - returns length of array (or pseudo-array) in model in safe way, 0 if no length is set\n * - [push](./m_path.js.html#ModelPath$push) - add items to the end of array (or pseudo-array) in model\n * - [pop](./m_path.js.html#ModelPath$pop) - remove item from the end of array (or pseudo-array) in model\n * - [unshift](./m_path.js.html#ModelPath$unshift) - add items to the beginning of array (or pseudo-array) in model\n * - [shift](./m_path.js.html#ModelPath$shift) - remove item from the beginning of array (or pseudo-array) in model\n * - [proxyMessenger](#proxyMessenger) - proxy model's Messenger methods to host object\n * - [proxyMethods](#proxyMethods) - proxy model methods to host object\n */\n_.extendProto(Model, {\n path: Model$path,\n get: Model$get,\n proxyMessenger: proxyMessenger, // deprecated, should not be used\n proxyMethods: proxyMethods,\n _prepareMessengers: _prepareMessengers,\n _getHostObject: _getHostObject,\n destroy: Model$destroy\n});\n\n// set, del, splice are added to model\n_.extendProto(Model, synthesize.modelMethods);\n\n\n/**\n * - Path: ModelPath class as `milo.Model.Path`\n */\n_.extend(Model, {\n Path: ModelPath,\n useWith: Model$$useWith\n});\n\n\n/**\n * Expose Messenger methods on Facet prototype\n */\nvar MESSENGER_PROPERTY = '_messenger';\nMessenger.useWith(Model, MESSENGER_PROPERTY, Messenger.defaultMethods);\n\n\n/**\n * ModelPath methods added to Model prototype\n */\n['len', 'push', 'pop', 'unshift', 'shift'].forEach(function(methodName) {\n var method = ModelPath.prototype[methodName];\n _.defineProperty(Model.prototype, methodName, method);\n});\n\n\n/**\n * Model instance method.\n * Get model data.\n *\n * @return {Any}\n */\nfunction Model$get() {\n return this._data;\n}\n\n\n/**\n * Model instance method.\n * Returns ModelPath object that implements the same API as model but allows access to any point inside model as defined by `accessPath`.\n * See [ModelPath](./m_path.js.html) class for more information.\n *\n * @param {String} accessPath string that defines path to access model.\n * Path string consists of parts to define either property access (`\".name\"` to access property name) or array item access (`\"[1]\"` to access item with index 1).\n * Access path can contain as many parts as necessary (e.g. `\".list[0].name\"` to access property `name` in the first element of array stored in property `list`.\n * @param {List} arguments additional arguments of this method can be used to create interpolated paths.\n * E.g. `m.path(\"[$1].$2\", id, prop)` returns ModelPath to access property with name `prop` in array item with index `id`. Although this ModelPath object will work exactly as `m(\"[\" + id + \"].\" + prop)`, the interpolated is much more efficient as ModelPath with interpolation will not synthesize new getters and setters, while ModelPath with computed access path will synthesize new getters and setters for each pair of values of `id` and `prop`.\n * @return {ModelPath}\n */\nfunction Model$path(accessPath) { // , ... arguments that will be interpolated\n if (! accessPath) return this;\n\n // \"null\" is context to pass to ModelPath, first parameter of bind\n // \"this\" (model) is added in front of all arguments\n _.splice(arguments, 0, 0, null, this);\n\n // calling ModelPath constructor with new and the list of arguments: this (model), accessPath, ...\n return new (Function.prototype.bind.apply(ModelPath, arguments));\n}\n\n\n/**\n * Model instance method.\n * Proxy model's Messenger methods to host object.\n *\n * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used.\n */\nfunction proxyMessenger(modelHostObject) {\n modelHostObject = modelHostObject || this._hostObject;\n Mixin.prototype._createProxyMethods.call(this[MESSENGER_PROPERTY], Messenger.defaultMethods, modelHostObject);\n}\n\n\nvar modelMethodsToProxy = ['path', 'get', 'set', 'del', 'splice', 'len', 'push', 'pop', 'unshift', 'shift'];\n\n\n/**\n * Expose model methods on\n * See same method in Mixin class for parameters meaning\n *\n * @param {Function} hostClass\n * @param {[type]} instanceKey\n * @param {[type]} mixinMethods optional\n */\nfunction Model$$useWith(hostClass, instanceKey, mixinMethods) {\n mixinMethods = mixinMethods || modelMethodsToProxy;\n Mixin.useWith.call(Model, hostClass, instanceKey, mixinMethods);\n}\n\n\n/**\n * Model instance method.\n * Proxy model methods to host object.\n *\n * @param {Object} modelHostObject optional host object. If not passed, hostObject passed to Model constructor will be used.\n */\nfunction proxyMethods(modelHostObject) {\n modelHostObject = modelHostObject || this._hostObject;\n Mixin.prototype._createProxyMethods.call(this, modelMethodsToProxy, modelHostObject);\n}\n\n\n/**\n * Model instance method.\n * Create and connect internal and external model's messengers.\n * External messenger's methods are proxied on the model and they allows \"*\" subscriptions.\n */\nfunction _prepareMessengers() {\n // model will post all its changes on internal messenger\n var internalMessenger = new Messenger(this, undefined, undefined);\n\n // message source to connect internal messenger to external\n var internalMessengerSource = new MessengerMessageSource(this, undefined, new ModelMsgAPI, internalMessenger);\n\n // external messenger to which all model users will subscribe,\n // that will allow \"*\" subscriptions and support \"changedata\" message api.\n var externalMessenger = new Messenger(this, undefined, internalMessengerSource);\n\n _.defineProperty(this, MESSENGER_PROPERTY, externalMessenger);\n _.defineProperty(this, '_internalMessenger', internalMessenger);\n}\n\n\nfunction _getHostObject() {\n return this._hostObject;\n}\n\n\nfunction Model$destroy() {\n this[MESSENGER_PROPERTY].destroy();\n this._internalMessenger.destroy();\n this._destroyed = true;\n}\n", + "arguments[4][75][0].apply(exports,arguments)", + "arguments[4][76][0].apply(exports,arguments)", + "arguments[4][78][0].apply(exports,arguments)", + "'use strict';\n\n// \n// ### model path utils\n\nvar check = require('../util/check')\n , Match = check.Match\n , _ = require('mol-proto');\n\nvar pathUtils = {\n parseAccessPath: parseAccessPath,\n createRegexPath: createRegexPath,\n getPathNodeKey: getPathNodeKey,\n wrapMessengerMethods: wrapMessengerMethods\n};\n\nmodule.exports = pathUtils;\n\n\nvar propertyPathSyntax = '\\\\.[A-Za-z_-][A-Za-z0-9_-]*'\n , arrayPathSyntax = '\\\\[[0-9]+\\\\]'\n , interpolationSyntax = '\\\\$[1-9][0-9]*'\n , propertyInterpolateSyntax = '\\\\.' + interpolationSyntax\n , arrayInterpolateSyntax = '\\\\[' + interpolationSyntax + '\\\\]'\n\n , propertyStarSyntax = '\\\\.\\\\*'\n , arrayStarSyntax = '\\\\[\\\\*\\\\]'\n , starSyntax = '\\\\*'\n\n , pathParseSyntax = [\n propertyPathSyntax,\n arrayPathSyntax,\n propertyInterpolateSyntax,\n arrayInterpolateSyntax\n ].join('|')\n , pathParsePattern = new RegExp(pathParseSyntax, 'g')\n\n , patternPathParseSyntax = [\n pathParseSyntax,\n propertyStarSyntax,\n arrayStarSyntax,\n starSyntax\n ].join('|')\n , patternPathParsePattern = new RegExp(patternPathParseSyntax, 'g')\n\n //, targetPathParsePattern = /\\.[A-Za-z][A-Za-z0-9_]*|\\[[0-9]+\\]|\\.\\$[1-9][0-9]*|\\[\\$[1-9][0-9]*\\]|\\$[1-9][0-9]/g\n , pathNodeTypes = {\n '.': { syntax: 'object', empty: '{}' },\n '[': { syntax: 'array', empty: '[]'},\n '*': { syntax: 'match', empty: '{}'},\n };\n\nfunction parseAccessPath(path, nodeParsePattern) {\n nodeParsePattern = nodeParsePattern || pathParsePattern;\n\n var parsedPath = [];\n\n if (! path)\n return parsedPath;\n\n var unparsed = path.replace(nodeParsePattern, function(nodeStr) {\n var pathNode = { property: nodeStr };\n _.extend(pathNode, pathNodeTypes[nodeStr[0]]);\n if (nodeStr[1] == '$')\n pathNode.interpolate = getPathNodeKey(pathNode, true);\n\n parsedPath.push(pathNode);\n return '';\n });\n if (unparsed)\n throw new Error('incorrect model path: ' + path);\n\n return parsedPath;\n}\n\n\nvar nodeRegex = {\n '.*': propertyPathSyntax,\n '[*]': arrayPathSyntax\n};\nnodeRegex['*'] = nodeRegex['.*'] + '|' + nodeRegex['[*]'];\n\nfunction createRegexPath(path) {\n check(path, Match.OneOf(String, RegExp));\n\n if (path instanceof RegExp || path.indexOf('*') == -1)\n return path;\n\n var parsedPath = pathUtils.parseAccessPath(path, patternPathParsePattern)\n , regexStr = '^'\n // , regexStrEnd = ''\n , patternsStarted = false;\n\n parsedPath.forEach(function(pathNode) {\n var prop = pathNode.property\n , regex = nodeRegex[prop];\n \n if (regex) {\n // regexStr += '(' + regex;\n // regexStrEnd += '|)';\n regexStr += '(' + regex + '|)';\n // regexStrEnd += '|)';\n patternsStarted = true;\n } else {\n // if (patternsStarted)\n // throw new Error('\"*\" path segment cannot be in the middle of the path: ' + path);\n regexStr += prop.replace(/(\\.|\\[|\\])/g, '\\\\$1'); // add slash in front of symbols that have special meaning in regex\n }\n });\n\n regexStr += /* regexStrEnd + */ '$';\n\n try {\n return new RegExp(regexStr);\n } catch (e) {\n throw new Error('can\\'t construct regex for path pattern: ' + path);\n }\n}\n\n\nfunction getPathNodeKey(pathNode, interpolated) {\n var prop = pathNode.property\n , startIndex = interpolated ? 2 : 1;\n return pathNode.syntax == 'array'\n ? prop.slice(startIndex, prop.length - 1)\n : prop.slice(startIndex);\n}\n\n\n// TODO allow for multiple messages in a string\nfunction wrapMessengerMethods(methodsNames) {\n methodsNames = methodsNames || ['on', 'off'];\n var wrappedMethods = _.mapToObject(methodsNames, function(methodName) {\n var origMethod = this[methodName];\n // replacing message subsribe/unsubscribe/etc. to convert \"*\" message patterns to regexps\n return function(path, subscriber) {\n var regexPath = createRegexPath(path);\n origMethod.call(this, regexPath, subscriber);\n };\n }, this);\n _.defineProperties(this, wrappedMethods);\n}\n", + "'use strict';\n\nvar pathUtils = require('../path_utils')\n , modelUtils = require('../model_utils')\n , logger = require('../../util/logger')\n , fs = require('fs')\n , doT = require('dot')\n , _ = require('mol-proto')\n , changeDataHandler = require('../change_data')\n , getTransactionFlag = changeDataHandler.getTransactionFlag\n , postTransactionFinished = changeDataHandler.postTransactionFinished;\n\n\n/**\n * Templates to synthesize model getters and setters\n */\nvar templates = {\n get: \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\nmethod = function get() {\\n var m = {{# def.modelAccessPrefix }};\\n return m {{~ it.parsedPath :pathNode }}\\n {{? pathNode.interpolate}}\\n && (m = m[this._args[ {{= pathNode.interpolate }} ]])\\n {{??}}\\n && (m = m{{= pathNode.property }})\\n {{?}} {{~}};\\n};\\n\",\n set: \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\n{{# def.include_defines }}\\n{{# def.include_create_tree }}\\n\\n\\n/**\\n * Template that synthesizes setter for Model and for ModelPath\\n */\\nmethod = function set(value) {\\n {{# def.initVars:'set' }}\\n\\n {{# def.createTree:'set' }}\\n\\n {{\\n currNode = nextNode;\\n currProp = currNode && currNode.property;\\n }}\\n\\n {{ /* assign value to the last property */ }}\\n {{? currProp }}\\n wasDef = {{# def.wasDefined}};\\n {{# def.changeAccessPath }}\\n\\n var old = m{{# def.currProp }};\\n\\n {{ /* clone value to prevent same reference in linked models */ }}\\n m{{# def.currProp }} = cloneTree(value);\\n {{?}}\\n\\n {{ /* add message related to the last property change */ }}\\n if (this._options.reactive !== false) {\\n if (! wasDef)\\n {{# def.addMsg }} accessPath, type: 'added',\\n newValue: value });\\n else if (old != value)\\n {{# def.addMsg }} accessPath, type: 'changed',\\n oldValue: old, newValue: value });\\n\\n {{ /* add message related to changes in (sub)properties inside removed and assigned value */ }}\\n if (! wasDef || old != value)\\n addTreeChangesMessages(messages, messagesHash,\\n accessPath, old, value); /* defined in the function that synthesizes ModelPath setter */\\n\\n {{ /* post all stored messages */ }}\\n {{# def.postMessages }}\\n }\\n};\\n\",\n del: \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\n{{# def.include_defines }}\\n{{# def.include_traverse_tree }}\\n\\nmethod = function del() {\\n {{# def.initVars:'del' }}\\n\\n {{? it.parsedPath.length }}\\n {{# def.traverseTree }}\\n\\n {{\\n var currNode = it.parsedPath[count];\\n var currProp = currNode.property; \\n }}\\n\\n if (! treeDoesNotExist && m && m.hasOwnProperty && {{# def.wasDefined}}) {\\n var old = m{{# def.currProp }};\\n delete m{{# def.currProp }};\\n {{# def.changeAccessPath }}\\n var didDelete = true;\\n }\\n {{??}}\\n if (typeof m != 'undefined') {\\n var old = m;\\n {{# def.modelAccessPrefix }} = undefined;\\n var didDelete = true;\\n }\\n {{?}}\\n\\n if (didDelete && this._options.reactive !== false) {\\n {{# def.addMsg }} accessPath, type: 'deleted', oldValue: old });\\n\\n addTreeChangesMessages(messages, messagesHash,\\n accessPath, old, undefined); /* defined in the function that synthesizes ModelPath setter */\\n\\n {{ /* post all stored messages */ }}\\n {{# def.postMessages }}\\n }\\n};\\n\",\n splice: \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\n{{# def.include_defines }}\\n{{# def.include_create_tree }}\\n{{# def.include_traverse_tree }}\\n\\nmethod = function splice(spliceIndex, spliceHowMany) { /* ,... - extra arguments to splice into array */\\n {{# def.initVars:'splice' }}\\n\\n var argsLen = arguments.length;\\n var addItems = argsLen > 2;\\n\\n if (addItems) {\\n {{ /* only create model tree if items are inserted in array */ }}\\n\\n {{ /* if model is undefined it will be set to an empty array */ }} \\n var value = [];\\n {{# def.createTree:'splice' }}\\n\\n {{? nextNode }}\\n {{\\n var currNode = nextNode;\\n var currProp = currNode.property;\\n var emptyProp = '[]';\\n }}\\n\\n {{# def.createTreeStep }}\\n {{?}}\\n\\n } else if (spliceHowMany > 0) {\\n {{ /* if items are not inserted, only traverse model tree if items are deleted from array */ }}\\n {{? it.parsedPath.length }}\\n {{# def.traverseTree }}\\n\\n {{\\n var currNode = it.parsedPath[count];\\n var currProp = currNode.property; \\n }}\\n\\n {{ /* extra brace closes 'else' in def.traverseTreeStep */ }}\\n {{# def.traverseTreeStep }} }\\n {{?}}\\n }\\n\\n {{ /* splice items */ }}\\n if (addItems || (! treeDoesNotExist && m\\n && m.length > spliceIndex ) ) {\\n var oldLength = m.length = m.length || 0;\\n\\n arguments[0] = spliceIndex = normalizeSpliceIndex(spliceIndex, m.length);\\n\\n {{ /* clone added arguments to prevent same references in linked models */ }}\\n if (addItems)\\n for (var i = 2; i < argsLen; i++)\\n arguments[i] = cloneTree(arguments[i]);\\n\\n {{ /* actual splice call */ }}\\n var removed = Array.prototype.splice.apply(m, arguments);\\n\\n if (this._options.reactive !== false) {\\n {{# def.addMsg }} accessPath, type: 'splice',\\n index: spliceIndex, removed: removed, addedCount: addItems ? argsLen - 2 : 0,\\n newValue: m });\\n\\n if (removed && removed.length)\\n removed.forEach(function(item, index) {\\n var itemPath = accessPath + '[' + (spliceIndex + index) + ']';\\n {{# def.addMsg }} itemPath, type: 'removed', oldValue: item });\\n\\n if (valueIsTree(item))\\n addMessages(messages, messagesHash, itemPath, item, 'removed', 'oldValue');\\n });\\n\\n if (addItems)\\n for (var i = 2; i < argsLen; i++) {\\n var item = arguments[i];\\n var itemPath = accessPath + '[' + (spliceIndex + i - 2) + ']';\\n {{# def.addMsg }} itemPath, type: 'added', newValue: item });\\n\\n if (valueIsTree(item))\\n addMessages(messages, messagesHash, itemPath, item, 'added', 'newValue');\\n }\\n\\n {{ /* post all stored messages */ }}\\n {{# def.postMessages }}\\n }\\n }\\n\\n return removed || [];\\n}\\n\"\n};\n\nvar include_defines = \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\n/**\\n * Inserts initialization code\\n */\\n {{## def.initVars:method:\\n var m = {{# def.modelAccessPrefix }};\\n var messages = [], messagesHash = {};\\n var accessPath = '';\\n var treeDoesNotExist;\\n /* hack to prevent sending finished events to allow for propagation of batches without splitting them */\\n var inChangeTransaction = getTransactionFlag( {{= method }} );\\n #}}\\n\\n/**\\n * Inserts the beginning of function call to add message to list\\n */\\n{{## def.addMsg: addChangeMessage(messages, messagesHash, { path: #}}\\n\\n/**\\n * Inserts current property/index for both normal and interpolated properties/indexes\\n */\\n{{## def.currProp:{{? currNode.interpolate }}[this._args[ {{= currNode.interpolate }} ]]{{??}}{{= currProp }}{{?}} #}}\\n\\n/**\\n * Inserts condition to test whether normal/interpolated property/index exists\\n */\\n{{## def.wasDefined: m.hasOwnProperty(\\n {{? currNode.interpolate }}\\n this._args[ {{= currNode.interpolate }} ]\\n {{??}}\\n '{{= it.getPathNodeKey(currNode) }}'\\n {{?}}\\n) #}}\\n\\n\\n/**\\n * Inserts code to update access path for current property\\n * Because of the possibility of interpolated properties, it can't be calculated in template, it can only be calculated during accessor call.\\n */\\n{{## def.changeAccessPath:\\n accessPath += {{? currNode.interpolate }}\\n {{? currNode.syntax == 'array' }}\\n '[' + this._args[ {{= currNode.interpolate }} ] + ']';\\n {{??}}\\n '.' + this._args[ {{= currNode.interpolate }} ];\\n {{?}}\\n {{??}}\\n '{{= currProp }}';\\n {{?}}\\n#}}\\n\\n\\n/**\\n * Inserts code to post stored messages\\n */\\n{{## def.postMessages:\\n if (messages.length) {\\n {{# def.modelPostBatchCode }}('datachanges', {\\n changes: messages,\\n transaction: inChangeTransaction\\n });\\n\\n messages.forEach(function(msg) {\\n {{# def.modelPostMessageCode }}(msg.path, msg);\\n }, this);\\n }\\n#}}\\n\"\n , include_create_tree = \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\n/**\\n * Inserts code to create model tree as neccessary for `set` and `splice` accessors and to add messages to send list if the tree changes.\\n */\\n{{## def.createTree:method:\\n var wasDef = true;\\n var old = m;\\n\\n {{ var emptyProp = it.parsedPath[0] && it.parsedPath[0].empty; }}\\n {{? emptyProp }}\\n {{ /* create top level model if it was not previously defined */ }}\\n if (! m) {\\n m = {{# def.modelAccessPrefix }} = {{= emptyProp }};\\n wasDef = false;\\n\\n if (this._options.reactive !== false) {\\n {{# def.addMsg }} '', type: 'added',\\n newValue: m });\\n }\\n }\\n {{??}}\\n {{? method == 'splice' }}\\n if (! m) {\\n {{?}}\\n m = {{# def.modelAccessPrefix }} = cloneTree(value);\\n wasDef = typeof old != 'undefined';\\n {{? method == 'splice' }}\\n }\\n {{?}} \\n {{?}}\\n\\n\\n {{ /* create model tree if it doesn't exist */ }}\\n {{ var modelDataProperty = '';\\n var nextNode = it.parsedPath[0];\\n var count = it.parsedPath.length - 1;\\n\\n for (var i = 0; i < count; i++) {\\n var currNode = nextNode;\\n var currProp = currNode.property;\\n nextNode = it.parsedPath[i + 1];\\n var emptyProp = nextNode && nextNode.empty;\\n }}\\n\\n {{# def.createTreeStep }}\\n\\n {{ } /* for loop */ }}\\n#}}\\n\\n\\n/**\\n * Inserts code to create one step in the model tree\\n */\\n{{## def.createTreeStep:\\n {{# def.changeAccessPath }}\\n\\n if (! {{# def.wasDefined }}) { \\n {{ /* property does not exist */ }}\\n m = m{{# def.currProp }} = {{= emptyProp }};\\n\\n if (this._options.reactive !== false) {\\n {{# def.addMsg }} accessPath, type: 'added', \\n newValue: m });\\n }\\n\\n } else if (typeof m{{# def.currProp }} != 'object') {\\n {{ /* property is not object */ }}\\n var old = m{{# def.currProp }};\\n m = m{{# def.currProp }} = {{= emptyProp }};\\n\\n if (this._options.reactive !== false) {\\n {{# def.addMsg }} accessPath, type: 'changed', \\n oldValue: old, newValue: m });\\n }\\n\\n } else {\\n {{ /* property exists, just traverse down the model tree */ }}\\n m = m{{# def.currProp }};\\n }\\n#}}\\n\"\n , include_traverse_tree = \"'use strict';\\n/* Only use this style of comments, not \\\"//\\\" */\\n\\n/**\\n * Inserts code to traverse model tree for `delete` and `splice` accessors.\\n */\\n{{## def.traverseTree:\\n {{ \\n var count = it.parsedPath.length-1;\\n\\n for (var i = 0; i < count; i++) { \\n var currNode = it.parsedPath[i];\\n var currProp = currNode.property;\\n }}\\n {{# def.traverseTreeStep }}\\n\\n {{ } /* for loop */\\n\\n var i = count;\\n while (i--) { /* closing braces for else's above */\\n }}\\n }\\n {{ } /* while loop */ }}\\n#}}\\n\\n\\n/**\\n * Inserts code to traverse one step in the model tree\\n */\\n{{## def.traverseTreeStep:\\n if (! (m && m.hasOwnProperty && {{# def.wasDefined}} ) )\\n treeDoesNotExist = true;\\n else {\\n m = m{{# def.currProp }};\\n {{# def.changeAccessPath }}\\n {{ /* brace from else is not closed on purpose - all braces are closed in while loop */ }}\\n#}}\\n\";\n\nvar dotDef = {\n include_defines: include_defines,\n include_create_tree: include_create_tree,\n include_traverse_tree: include_traverse_tree,\n getPathNodeKey: pathUtils.getPathNodeKey,\n modelAccessPrefix: 'this._model._data',\n modelPostMessageCode: 'this._model._internalMessenger.postMessage',\n modelPostBatchCode: 'this._model.postMessageSync',\n internalMessenger: 'this._model._internalMessenger'\n};\n\nvar modelDotDef = _(dotDef).clone().extend({\n modelAccessPrefix: 'this._data',\n modelPostMessageCode: 'this._internalMessenger.postMessage',\n modelPostBatchCode: 'this.postMessageSync',\n internalMessenger: 'this._internalMessenger'\n})._();\n\n\nvar dotSettings = _.clone(doT.templateSettings);\ndotSettings.strip = false;\n\nvar synthesizers = _.mapKeys(templates, function(tmpl) {\n return doT.template(tmpl, dotSettings, dotDef); \n});\n\n\nvar modelSynthesizers = _.mapToObject(['set', 'del', 'splice'], function(methodName) {\n return doT.template(templates[methodName], dotSettings, modelDotDef);\n});\n\n\n/**\n * Function that synthesizes accessor methods.\n * Function is memoized so accessors are cached (up to 1000).\n *\n * @param {String} path Model/ModelPath access path\n * @param {Array} parsedPath array of path nodes\n * @return {Object[Function]}\n */\nvar synthesizePathMethods = _.memoize(_synthesizePathMethods, undefined, 1000);\n\nfunction _synthesizePathMethods(path, parsedPath) {\n var methods = _.mapKeys(synthesizers, function(synthszr) {\n return _synthesize(synthszr, path, parsedPath);\n });\n return methods;\n}\n\n\nvar normalizeSpliceIndex = modelUtils.normalizeSpliceIndex; // used in splice.dot.js\n\n\nfunction _synthesize(synthesizer, path, parsedPath) {\n var method\n , methodCode = synthesizer({\n parsedPath: parsedPath,\n getPathNodeKey: pathUtils.getPathNodeKey\n });\n\n try {\n eval(methodCode);\n } catch (e) {\n throw ModelError('ModelPath method compilation error; path: ' + path + ', code: ' + methodCode);\n }\n\n return method;\n\n\n // functions used by methods `set`, `delete` and `splice` (synthesized by template)\n function addChangeMessage(messages, messagesHash, msg) {\n messages.push(msg);\n messagesHash[msg.path] = msg;\n }\n\n function addTreeChangesMessages(messages, messagesHash, rootPath, oldValue, newValue) {\n var oldIsTree = valueIsTree(oldValue)\n , newIsTree = valueIsTree(newValue);\n\n if (newIsTree)\n addMessages(messages, messagesHash, rootPath, newValue, 'added', 'newValue');\n \n if (oldIsTree)\n addMessages(messages, messagesHash, rootPath, oldValue, 'removed', 'oldValue');\n }\n\n function addMessages(messages, messagesHash, rootPath, obj, msgType, valueProp) {\n _addMessages(rootPath, obj);\n\n\n function _addMessages(rootPath, obj) {\n if (Array.isArray(obj)) {\n var pathSyntax = rootPath + '[$$]';\n obj.forEach(function(value, index) {\n addMessage(value, index, pathSyntax);\n });\n } else {\n var pathSyntax = rootPath + '.$$';\n _.eachKey(obj, function(value, key) {\n addMessage(value, key, pathSyntax);\n });\n }\n }\n\n function addMessage(value, key, pathSyntax) {\n var path = pathSyntax.replace('$$', key)\n , existingMsg = messagesHash[path];\n\n if (existingMsg) {\n if (existingMsg.type == msgType)\n logger.error('setter error: same message type posted on the same path');\n else {\n existingMsg.type = 'changed';\n existingMsg[valueProp] = value;\n }\n } else {\n var msg = { path: path, type: msgType };\n msg[valueProp] = value;\n addChangeMessage(messages, messagesHash, msg);\n }\n\n if (valueIsTree(value))\n _addMessages(path, value);\n }\n }\n\n function cloneTree(value) {\n return valueIsNormalObject(value)\n ? _.deepClone(value)\n : value;\n }\n\n function protectValue(value) {\n return ! valueIsNormalObject(value)\n ? value\n : Array.isArray(value)\n ? value.slice()\n : Object.create(value);\n }\n\n function valueIsTree(value) {\n return valueIsNormalObject(value)\n && Object.keys(value).length;\n }\n\n function valueIsNormalObject(value) {\n return value != null\n && typeof value == \"object\"\n && ! (value instanceof Date)\n && ! (value instanceof RegExp);\n }\n\n function addBatchIdsToMessage(msg, batchId, msgId) {\n _.defineProperties(msg, {\n __batch_id: batchId,\n __msg_id: msgId\n });\n }\n}\n\n\n/**\n * Exports `synthesize` function with the following:\n *\n * - .modelMethods.set - `set` method for Model\n * - .modelMethods.del - `del` method for Model\n * - .modelMethods.splice - `splice` method for Model\n */\nmodule.exports = synthesizePathMethods;\n\nvar modelMethods = _.mapKeys(modelSynthesizers, function(synthesizer) {\n return _synthesize(synthesizer, '', []);\n});\n\nsynthesizePathMethods.modelMethods = modelMethods;\n", + "arguments[4][90][0].apply(exports,arguments)", + "'use strict';\n\n/**\n * `milo.util`\n */\nvar util = {\n logger: require('./logger'),\n check: require('./check'),\n};\n\nmodule.exports = util;\n", + "arguments[4][102][0].apply(exports,arguments)", + "arguments[4][103][0].apply(exports,arguments)", "'use strict';\n\nvar utils = require('./utils');\n\n\n/**\n * [__Prototype functions__](proto_prototype.js.html)\n *\n * - [extendProto](proto_prototype.js.html#extendProto)\n * - [createSubclass](proto_prototype.js.html#createSubclass)\n * - [makeSubclass](proto_prototype.js.html#makeSubclass)\n * - [newApply](proto_prototype.js.html#newApply)\n */\nvar prototypeMethods = require('./proto_prototype');\n\n\n/**\n * [__Object functions__](proto_object.js.html)\n *\n * - [extend](proto_object.js.html#extend)\n * - [clone](proto_object.js.html#clone)\n * - [defineProperty](proto_object.js.html#defineProperty)\n * - [defineProperties](proto_object.js.html#defineProperties)\n * - [deepExtend](proto_object.js.html#deepExtend)\n * - [deepClone](proto_object.js.html#deepClone)\n * - [keys](proto_object.js.html#keys)\n * - [allKeys](proto_object.js.html#allKeys)\n * - [values](proto_object.js.html#values)\n * - [keyOf](proto_object.js.html#keyOf)\n * - [allKeysOf](proto_object.js.html#allKeysOf)\n * - [eachKey](proto_object.js.html#eachKey)\n * - [mapKeys](proto_object.js.html#mapKeys)\n * - [reduceKeys](proto_object.js.html#reduceKeys)\n * - [filterKeys](proto_object.js.html#filterKeys)\n * - [someKey](proto_object.js.html#someKey)\n * - [everyKey](proto_object.js.html#everyKey)\n * - [findValue](proto_object.js.html#findValue)\n * - [findKey](proto_object.js.html#findKey)\n * - [pickKeys](proto_object.js.html#pickKeys)\n * - [omitKeys](proto_object.js.html#omitKeys)\n * - [isEqual](proto_object.js.html#isEqual)\n * - [isNot](proto_object.js.html#isNot)\n */\nvar objectMethods = require('./proto_object');\n\n\n/**\n * [__Array functions__](proto_array.js.html)\n *\n * - [find](proto_array.js.html#find)\n * - [findIndex](proto_array.js.html#findIndex)\n * - [appendArray](proto_array.js.html#appendArray)\n * - [prependArray](proto_array.js.html#prependArray)\n * - [spliceItem](proto_array.js.html#spliceItem)\n * - [toArray](proto_array.js.html#toArray)\n * - [object](proto_array.js.html#object)\n * - [mapToObject](proto_array.js.html#mapToObject)\n * - [unique](proto_array.js.html#unique)\n * - [deepForEach](proto_array.js.html#deepForEach)\n *\n * Functions that Array [implements natively](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Methods) are also added - they can be used with array-like objects and for chaining (native functions are always called).\n */\nvar arrayMethods = require('./proto_array');\n\n\n/**\n * [__Function functions__](proto_function.js.html)\n *\n * - [makeFunction](proto_function.js.html#makeFunction)\n * - [partial](proto_function.js.html#partial)\n * - [partialRight](proto_function.js.html#partialRight)\n * - [memoize](proto_function.js.html#memoize)\n * - [delay](proto_function.js.html#delay)\n * - [defer](proto_function.js.html#defer)\n * - [delayed](proto_function.js.html#delayed)\n * - [deferred](proto_function.js.html#deferred)\n * - [deferTicks](proto_function.js.html#deferTicks)\n * - [delayMethod](proto_function.js.html#delayMethod)\n * - [deferMethod](proto_function.js.html#deferMethod)\n * - [debounce](proto_function.js.html#debounce)\n * - [throttle](proto_function.js.html#throttle)\n * - [once](proto_function.js.html#once)\n * - [waitFor](proto_function.js.html#waitFor)\n*/\nvar functionMethods = require('./proto_function');\n\n\n/**\n * [__String functions__](proto_string.js.html)\n *\n * - [firstUpperCase](proto_string.js.html#firstUpperCase)\n * - [firstLowerCase](proto_string.js.html#firstLowerCase)\n * - [toRegExp](proto_string.js.html#toRegExp)\n * - [toFunction](proto_string.js.html#toFunction)\n * - [toDate](proto_string.js.html#toDate)\n * - [toQueryString](proto_string.js.html#toQueryString)\n * - [fromQueryString](proto_string.js.html#fromQueryString)\n * - [jsonParse](proto_string.js.html#jsonParse)\n * - [hashCode](proto_string.js.html#hashCode)\n * - [unPrefix](proto_string.js.html#unPrefix)\n */\nvar stringMethods = require('./proto_string');\n\n\n/**\n * [__Number functions__](proto_number.js.html)\n *\n * - [isNumeric](proto_number.js.html#isNumeric)\n */\nvar numberMethods = require('./proto_number');\n\n\n/**\n * [__Utility functions__](proto_util.js.html)\n *\n * - [times](proto_util.js.html#times)\n * - [repeat](proto_util.js.html#repeat)\n * - [tap](proto_util.js.html#tap)\n * - [result](proto_util.js.html#result)\n * - [identity](proto_util.js.html#identity)\n * - [property](proto_util.js.html#property)\n * - [compareProperty](proto_util.js.html#compareProperty)\n * - [noop](proto_util.js.html#noop)\n */\nvar utilMethods = require('./proto_util');\n\n\n/**\n * Chaining\n * ========\n *\n * `_` can be used to create a wrapped value (object, function, array, etc.) to allow chaining of Proto functions.\n * To unwrap, `_` method of a wrapped value should be used.\n * Usage:\n * ```\n * var arr = _({ 0: 3, 1: 4, 2: 5, length: 3})\n * .toArray()\n * .prependArray([1, 2])\n * .appendArray([6, 7, 8])\n * ._();\n * ```\n * A wrapped object is an instance of `_` (`Proto` class).\n *\n * Chaining is implemented for development convenience, but it has performance overhead, not only to wrap and unwrap values but in each function call.\n * Although all Proto functions are implemented as methods operating on this and the overhead to redefine them as functions is very small, the overhead to redefine them as methods of wrapped value is slightly higher - chaining is 15-25% slower than using functions (properties of _ that take the first parameter).\n * In cases when performance is critical, you may want to avoid using chaining.\n *\n * @param {Any} self A value to be wrapped\n * @return {Proto}\n */\nfunction Proto(self) {\n // wrap passed parameter in _ object\n var wrapped = Object.create(Proto.prototype);\n wrapped.self = self;\n return wrapped;\n};\n\nvar _ = Proto;\n\n\n// store raw methods from different modules in __ object (double \"_\")\nvar __ = {};\n\nobjectMethods.extend.call(__, objectMethods);\n__.extend.call(__, prototypeMethods);\n__.extend.call(__, arrayMethods);\n__.extend.call(__, stringMethods);\n__.extend.call(__, numberMethods);\n__.extend.call(__, functionMethods);\n__.extend.call(__, utilMethods);\n\n\n// add __ as property of Proto, so they can be used as mixins in other classes\n__.defineProperty(Proto, '__', __);\n\n\n// add _ method to unwrap wrapped value (Proto instance)\nfunction unwrapProto() { return this.self; }\n__.extendProto.call(Proto, { _: unwrapProto });\n\n// add constants (functions will be overwritten)\n__.extend.call(Proto, objectMethods._constants);\n\n// add functions that take first parameter instead of \"this\" to Proto\nvar protoFuncs = __.mapKeys.call(__, utils.makeProtoFunction, true);\n__.extend.call(Proto, protoFuncs);\n\n// add Proto wrapped value instance methods to Proto prototype\nvar protoInstanceMethods = __.mapKeys.call(__, utils.makeProtoInstanceMethod, true);\n__.extendProto.call(Proto, protoInstanceMethods);\n\n\n/**\n * In windows environment, a global `_` value is preserved in `_.underscore`\n */\nif (typeof window == 'object') {\n // preserve existing _ object\n if (window._)\n Proto.underscore = window._\n\n // expose global _ and Proto\n window._ = Proto;\n}\n\nif (typeof module == 'object' && module.exports)\n // export for node/browserify\n module.exports = Proto;\n", "'use strict';\n\nvar __ = require('./proto_object')\n , utils = require('./utils');\n\n\n/**\n * - [find](#find)\n * - [findIndex](#findIndex)\n * - [appendArray](#appendArray)\n * - [prependArray](#prependArray)\n * - [spliceItem](#spliceItem)\n * - [toArray](#toArray)\n * - [object](#object)\n * - [mapToObject](#mapToObject)\n * - [unique](#unique)\n * - [deepForEach](#deepForEach)\n *\n * These methods can be [chained](proto.js.html#Proto).\n */\nvar arrayMethods = module.exports = {\n // find: see below\n // findIndex: see below\n appendArray: appendArray,\n prependArray: prependArray,\n toArray: toArray,\n object: object,\n mapToObject: mapToObject,\n unique: unique,\n deepForEach: deepForEach,\n spliceItem: spliceItem\n};\n\n\n/**\n * Functions that Array [implements natively](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Methods) are also included for convenience - they can be used with array-like objects and for chaining (native functions are always called).\n * These methods can be [chained](proto.js.html#Proto) too.\n */\nvar nativeArrayMethodsNames = [ 'join', 'pop', 'push', 'concat',\n 'reverse', 'shift', 'unshift', 'slice', 'splice',\n 'sort', 'filter', 'forEach', 'some', 'every',\n 'map', 'indexOf', 'lastIndexOf', 'reduce', 'reduceRight'];\n\nvar nativeArrayMethods = mapToObject.call(nativeArrayMethodsNames,\n function(methodName) {\n return Array.prototype[methodName];\n });\n\n__.extend.call(arrayMethods, nativeArrayMethods);\n\n\n/**\n * Implementation of ES6 [Array __find__ method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) (native method is used if available).\n * Returns array element that passes callback test.\n *\n * @param {Array} self array to search in\n * @param {Function} callback should return `true` for item to pass the test, passed `value`, `index` and `self` as parameters\n * @param {Object} thisArg optional context (`this`) of callback call\n * @return {Any}\n */\narrayMethods.find = Array.prototype.find\n || utils.makeFindMethod(arrayMethods.forEach, 'value');\n\n\n/**\n * Implementation of ES6 [Array __findIndex__ method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) (native method is used if available).\n * Returns the index of array element that passes callback test. Returns `-1` if not found.\n *\n * @param {Array} self array to search in\n * @param {Function} callback should return `true` for item to pass the test, passed `value`, `index` and `self` as parameters\n * @param {Object} thisArg optional context (`this`) of callback call\n * @return {Integer}\n */\narrayMethods.findIndex = Array.prototype.findIndex\n || utils.makeFindMethod(arrayMethods.forEach, 'index');\n\n\n/**\n * Appends `arrayToAppend` to the end of array `self` in place (can be an instance of Array or array-like object).\n * Changes the value of `self` (it uses `Array.prototype.splice`) and returns `self`.\n *\n * @param {Array} self An array that will be modified\n * @param {Array|Array-like} arrayToAppend An array that will be appended\n * @return {Array}\n */\nfunction appendArray(arrayToAppend) {\n if (! arrayToAppend.length) return this;\n if (! Array.isArray(arrayToAppend))\n arrayToAppend = toArray.call(arrayToAppend);\n \n var args = [this.length, 0].concat(arrayToAppend);\n arrayMethods.splice.apply(this, args);\n\n return this;\n}\n\n\n/**\n * Prepends `arrayToPrepend` to the beginnig of array `self` in place (can be an instance of Array or array-like object).\n * Changes the value of `self` (it uses `Array.prototype.splice`) and returns `self`.\n *\n * @param {Array} self An array that will be modified\n * @param {Array|Array-like} arrayToAppend An array that will be prepended\n * @return {Array}\n */\nfunction prependArray(arrayToPrepend) {\n if (! arrayToPrepend.length) return this;\n if (! Array.isArray(arrayToPrepend))\n arrayToPrepend = toArray.call(arrayToPrepend);\n\n var args = [0, 0].concat(arrayToPrepend);\n arrayMethods.splice.apply(this, args);\n\n return this;\n}\n\n\n/**\n * Removes item from array that is found using indexOf (i.e. '===')\n * Modifies original array and returns the reference to it.\n * \n * @param {Array} self An array that will be modified\n * @param {Any} item item to be removed\n * @return {Array}\n */\nfunction spliceItem(item) {\n var index = this.indexOf(item);\n if (index >= 0) this.splice(index, 1);\n return this;\n}\n\n\n/**\n * Returns new array created from array-like object (e.g., `arguments` pseudo-array).\n *\n * @param {Array-like} self Object with numeric property length\n * @return {Array}\n */\nfunction toArray() {\n return arrayMethods.slice.call(this);\n}\n\n\n/**\n * Returns an object created from the array of `keys` and optional array of `values`.\n *\n * @param {Array} self Array of keys\n * @param {Array|any} values Optional array of values or the value to be assigned to each property.\n * @return {Object}\n */\nfunction object(values) {\n var obj = {}\n , valuesIsArray = Array.isArray(values);\n arrayMethods.forEach.call(this, function(key, index) {\n obj[key] = valuesIsArray ? values[index] : values;\n });\n\n return obj;\n}\n\n\n/**\n * Maps array to object.\n * Array elements become keys, value are taken from `callback`.\n * \n * @param {Array} self An array which values will become keys of the result\n * @param {Function} callback Callback is passed `value`, `index` and `self` and should return value that will be included in the result.\n * @param {Object} thisArg An optional context of iteration (the valueof `this`), will be undefined if this parameter is not passed.\n * @return {Object}\n */\nfunction mapToObject(callback, thisArg) {\n var result = {};\n Array.prototype.forEach.call(this, function(value, index) {\n result[value] = callback.call(thisArg, value, index, this);\n }, this);\n return result;\n}\n\n\n/**\n * Returns array without duplicates. Does not modify original array.\n *\n * @param {Array} self original array\n * @param {Function} callback comparison function, should return true for equal items, \"===\" is used if not passed.\n * @return {Array}\n */\nfunction unique(callback) {\n var filtered = [];\n if (! callback)\n itemIndex = itemIndexOf;\n\n this.forEach(function(item) {\n var index = itemIndex(item);\n if (index == -1)\n filtered.push(item);\n });\n\n return filtered;\n\n\n function itemIndex(item) {\n return arrayMethods.findIndex.call(filtered, function(it) {\n return callback(item, it);\n });\n }\n\n function itemIndexOf(item) {\n return filtered.indexOf(item);\n }\n}\n\n\n/**\n * Iterates array and elements that are arrays calling callback with each element that is not an array. Can be used to iterate over arguments list to avoid checking whether array or list of parameters is passed.\n *\n * @param {Array|Array-like} self array of elements and arraysto iterate.\n * @param {Function} callback called for each item that is not an array. Callback is passed item, index and original array as parameters.\n * @param {Any} thisArg optional callback envocation context\n */\nfunction deepForEach(callback, thisArg) {\n var index = 0, arr = this;\n _deepForEach.call(this);\n\n function _deepForEach() {\n arrayMethods.forEach.call(this, function(value) {\n if (Array.isArray(value))\n _deepForEach.call(value);\n else\n callback.call(thisArg, value, index++, arr);\n });\n }\n}\n", "'use strict';\n\n\nvar makeProtoFunction = require('./utils').makeProtoFunction\n , repeat = require('./proto_util').repeat;\n\n\n/**\n * - [makeFunction](#makeFunction)\n * - [partial](#partial)\n * - [partialRight](#partialRight)\n * - [memoize](#memoize)\n * - [delay](#delay)\n * - [defer](#defer)\n * - [delayed](#delayed)\n * - [deferred](#deferred)\n * - [deferTicks](#deferTicks)\n * - [delayMethod](#delayMethod)\n * - [deferMethod](#deferMethod)\n * - [debounce](#debounce)\n * - [throttle](#throttle)\n * - [once](#once)\n * - [waitFor](#waitFor)\n * - [not](#not)\n *\n * These methods can be [chained](proto.js.html#Proto)\n */\nvar functionMethods = module.exports = {\n makeFunction: makeFunction,\n partial: partial,\n partialRight: partialRight,\n memoize: memoize,\n delay: delay,\n defer: defer,\n delayed: delayed,\n deferred: deferred,\n deferTicks: deferTicks,\n delayMethod: delayMethod,\n deferMethod: deferMethod,\n debounce: debounce,\n throttle: throttle,\n once: once,\n waitFor: waitFor,\n not: not\n};\n\n\nvar slice = Array.prototype.slice;\n\n\n/**\n * Similarly to Function constructor creates a function from code.\n * Unlike Function constructor, the first argument is a function name\n *\n * @param {String} name new function name\n * @param {String} arg1, arg2, ... the names of function parameters\n * @param {String} funcBody function body\n * @return {Function}\n */\nfunction makeFunction(arg1, arg2, funcBody) {\n var name = this\n , count = arguments.length - 1\n , funcBody = arguments[count]\n , func\n , code = '';\n for (var i = 0; i < count; i++)\n code += ', ' + arguments[i];\n code = ['func = function ', name, '(', code.slice(2), ') {\\n'\n , funcBody, '\\n}'].join('');\n eval(code);\n return func;\n}\n\n\n/**\n * Creates a function as a result of partial function application with the passed parameters.\n *\n * @param {Function} self Function to be applied\n * @param {List} arguments Arguments after self will be prepended to the original function call when the partial function is called.\n * @return {Function}\n */\nfunction partial() { // , ... arguments\n var func = this;\n var args = slice.call(arguments);\n return function() {\n return func.apply(this, args.concat(slice.call(arguments)));\n };\n}\n\n\n/**\n * Creates a function as a result of partial function application with the passed parameters, but parameters are appended on the right.\n *\n * @param {Function} self Function to be applied\n * @param {List} arguments Arguments after self will be appended on the right to the original function call when the partial function is called.\n * @return {Function}\n */\nfunction partialRight() { // , ... arguments\n var func = this;\n var args = slice.call(arguments);\n return function() {\n return func.apply(this, slice.call(arguments).concat(args));\n };\n}\n\n\n/**\n * Creates a memoized version of the function using supplied hash function as key. If the hash is not supplied, uses its first parameter as the hash.\n * \n * @param {Function} self function to be memoized\n * @param {Function} hashFunc optional hash function that is passed all function arguments and should return cache key.\n * @param {Integer} limit optional maximum number of results to be stored in the cache. 1000 by default.\n * @return {Function} memoized function\n */\nfunction memoize(hashFunc, limit) {\n var func = this;\n var cache = {}, keysList = [];\n limit = limit || 1000;\n\n return function() {\n var key = hashFunc ? hashFunc.apply(this, arguments) : arguments[0];\n if (cache.hasOwnProperty(key))\n return cache[key];\n\n var result = cache[key] = func.apply(this, arguments);\n keysList.push(key);\n\n if (keysList.length > limit)\n delete cache[keysList.shift()];\n\n return result;\n };\n}\n\n\n/**\n * Delays function execution by a given time in milliseconds.\n * The context in function when it is executed is set to `null`.\n *\n * @param {Function} self function that execution has to be delayed\n * @param {Number} wait approximate dalay time in milliseconds\n * @param {List} arguments optional arguments that will be passed to the function\n */\nfunction delay(wait) { // , arguments\n var args = slice.call(arguments, 1);\n return _delay(this, wait, args);\n}\n \n\n/**\n * Defers function execution (executes as soon as execution loop becomes free)\n * The context in function when it is executed is set to `null`.\n *\n * @param {Function} self function that execution has to be delayed\n * @param {List} arguments optional arguments that will be passed to the function\n */\nfunction defer() { // , arguments\n return _delay(this, 1, arguments);\n}\n\nfunction _delay(func, wait, args, context) {\n return setTimeout(func.apply.bind(func, context || null, args), wait);\n}\n\n/**\n * Same as _.defer, takes first argument as the function to be deferred\n */\nvar deferFunc = makeProtoFunction(defer);\n\n/**\n * Defers function execution for `times` ticks (executes after execution loop becomes free `times` times)\n * The context in function when it is executed is set to `null`.\n *\n * @param {Function} self function that execution has to be delayed\n * @param {Integer} ticks number of times to defer execution\n * @param {List} arguments optional arguments that will be passed to the function\n */\nfunction deferTicks(ticks) { // , arguments\n if (ticks < 2) return defer.apply(this, arguments);\n var args = repeat.call(deferFunc, ticks - 1);\n args = args.concat(this, slice.call(arguments, 1)); \n return deferFunc.apply(null, args);\n}\n\n\n/**\n * Works like _.delay but allows to defer method call of `self` which will be the first _.delayMethod parameter\n *\n * @param {Object} self object to delay method call of\n * @param {Function|String} funcOrMethodName function or name of method\n * @param {Number} wait approximate dalay time in milliseconds\n * @param {List} arguments arguments to pass to method\n */\nfunction delayMethod(funcOrMethodName, wait) { // , ... arguments\n var args = slice.call(arguments, 2);\n return _delayMethod(this, funcOrMethodName, wait, args);\n}\n\n\n/**\n * Works like _.defer but allows to defer method call of `self` which will be the first _.deferMethod parameter\n *\n * @param {Object} self object to defer method call of\n * @param {Function|String} funcOrMethodName function or name of method\n * @param {List} arguments arguments to pass to method\n */\nfunction deferMethod(funcOrMethodName) { // , ... arguments\n var args = slice.call(arguments, 1);\n return _delayMethod(this, funcOrMethodName, 1, args);\n}\n\nfunction _delayMethod(object, funcOrMethodName, wait, args) {\n return setTimeout(function() {\n var func = typeof funcOrMethodName == 'string'\n ? object[funcOrMethodName]\n : funcOrMethodName;\n func.apply(object, args);\n }, wait);\n}\n\n\n/**\n * Returns function that will execute the original function `wait` ms after it has been called\n * The context in function when it is executed is set to `null`.\n * Arguments passed to the function are appended to the arguments passed to delayed.\n *\n * @param {Function} self function which execution has to be deferred\n * @param {Number} wait approximate dalay time in milliseconds\n * @param {List} arguments optional arguments that will be passed to the function\n * @return {Function}\n */\nfunction delayed(wait) { //, ... arguments\n var func = this\n , args = slice.call(arguments, 1);\n return function() { // ... arguments\n var passArgs = args.concat(slice.call(arguments));\n return _delay(func, wait, passArgs, this);\n };\n}\n\n\n/**\n * Returns function that will execute the original function on the next tick once it has been called\n * The context in function when it is executed is set to `null`.\n * Arguments passed to the function are appended to the arguments passed to deferred.\n *\n * @param {Function} self function which execution has to be deferred\n * @param {List} arguments optional arguments that will be passed to the function\n * @return {Function}\n */\nfunction deferred() { //, ... arguments\n var func = this\n , args = slice.call(arguments);\n return function() { // ... arguments\n var passArgs = args.concat(slice.call(arguments));\n return _delay(func, 1, passArgs, this);\n };\n}\n\n\n/**\n * Creates a function that will call original function once it has not been called for a specified time\n *\n * @param {Function} self function that execution has to be delayed\n * @param {Number} wait approximate dalay time in milliseconds\n * @param {Boolean} immediate true to invoke funciton immediately and then ignore following calls for wait milliseconds\n * @return {Function}\n */\nfunction debounce(wait, immediate) {\n var func = this; // first parameter of _.debounce\n var timeout, args, context, timestamp, result;\n return function() {\n context = this; // store original context\n args = arguments;\n timestamp = Date.now();\n var callNow = immediate && ! timeout;\n if (! timeout)\n timeout = setTimeout(later, wait);\n if (callNow)\n result = func.apply(context, args);\n return result;\n\n function later() {\n var last = Date.now() - timestamp;\n if (last < wait)\n timeout = setTimeout(later, wait - last);\n else {\n timeout = null;\n if (! immediate)\n result = func.apply(context, args);\n }\n }\n };\n}\n\n\n/**\n * Returns a function, that, when invoked, will only be triggered at most once during a given window of time. \n *\n * @param {Function} self function that execution has to be delayed\n * @param {Number} wait approximate delay time in milliseconds\n * @param {Object} options `{leading: false}` to disable the execution on the leading edge\n * @return {Function}\n */\nfunction throttle(wait, options) {\n var func = this; // first parameter of _.throttle\n var context, args, result;\n var timeout = null;\n var previous = 0;\n options || (options = {});\n\n return function() {\n var now = Date.now();\n if (!previous && options.leading === false) previous = now;\n var remaining = wait - (now - previous);\n context = this;\n args = arguments;\n if (remaining <= 0) {\n clearTimeout(timeout);\n timeout = null;\n previous = now;\n result = func.apply(context, args);\n } else if (!timeout && options.trailing !== false)\n timeout = setTimeout(later, remaining);\n\n return result;\n };\n\n function later() {\n previous = options.leading === false ? 0 : Date.now();\n timeout = null;\n result = func.apply(context, args);\n }\n}\n\n\n/**\n * Call passed function only once\n * @return {Function} self\n */\nfunction once() {\n var func = this\n , ran = false\n , memo;\n return function() {\n if (ran) return memo;\n ran = true;\n memo = func.apply(this, arguments);\n func = null;\n return memo;\n };\n}\n\n\n/**\n * Execute a function when the condition function returns a truthy value\n * it runs the condition function every `checkInterval` milliseconds (default 50)\n *\n * @param {Function} self function: if it returns true the callback is executed\n * @param {Function} callback runs when the condition is true\n * @param {Number} maxTimeout timeout before giving up (time in milliseconds)\n * @param {Function} timedOutFunc a function called if timeout is reached\n * @param {Number} checkInterval time interval when you run the condition function (time in milliseconds), default 50 ms\n */\nfunction waitFor(callback, maxTimeout, timedOutFunc, checkInterval){\n var start = Date.now();\n var condition = this;\n checkInterval = checkInterval || 50;\n var interval = setInterval(testCondition, checkInterval);\n\n function testCondition() {\n if (condition()) callback();\n else if (Date.now() - start >= maxTimeout)\n timedOutFunc && timedOutFunc();\n else return;\n clearInterval(interval);\n };\n}\n\n\n/**\n * returns the function that negates (! operator) the result of the original function\n * @param {Function} self function to negate\n * @return {Function}\n */\nfunction not() {\n var func = this;\n return function() {\n return !func.apply(this, arguments);\n };\n}\n", @@ -256,6 +302,10 @@ "'use strict';\n\n/**\n * - [extendProto](#extendProto)\n * - [createSubclass](#createSubclass)\n * - [makeSubclass](#makeSubclass)\n * - [newApply](#newApply)\n *\n * These methods can be [chained](proto.js.html#Proto)\n */\nvar prototypeMethods = module.exports = {\n extendProto: extendProto,\n createSubclass: createSubclass,\n makeSubclass: makeSubclass,\n newApply: newApply\n};\n\n\nvar __ = require('./proto_object');\n\n__.extend.call(__, require('./proto_function'));\n\n\n/**\n * Adds non-enumerable, non-configurable and non-writable properties to the prototype of constructor function.\n * Usage:\n * ```\n * function MyClass() {}\n * _.extendProto(MyClass, {\n * method1: function() {},\n * method2: function() {}\n * });\n * ```\n * To extend class via object:\n * ```\n * _.extendProto(obj.constructor, methods);\n * ```\n * Returns passed constructor, so functions _.extendProto, [_.extend](object.js.html#extend) and _.makeSubclass can be [chained](proto.js.html). \n *\n * @param {Function} self constructor function\n * @param {Object} methods a map of functions, keys will be instance methods (properties of the constructor prototype)\n * @return {Function}\n */\nfunction extendProto(methods) {\n var propDescriptors = {};\n\n __.eachKey.call(methods, function(method, name) {\n propDescriptors[name] = {\n enumerable: false,\n configurable: false,\n writable: false,\n value: method\n };\n });\n\n Object.defineProperties(this.prototype, propDescriptors);\n return this;\n}\n\n\n/**\n * Makes a subclass of class `thisClass`.\n * The returned function will have specified `name` if supplied.\n * The constructor of superclass will be called in subclass constructor by default unless `applyConstructor === false` (not just falsy).\n * Copies `thisClass` class methods to created subclass. For them to work correctly they should use `this` to refer to the class rather than explicit superclass name.\n *\n * @param {Function} thisClass A class to make subclass of\n * @param {String} name Optional name of subclass constructor function\n * @param {Boolean} applyConstructor Optional false value (not falsy) to prevent call of inherited constructor in the constructor of subclass\n * @return {Function}\n */\nfunction createSubclass(name, applyConstructor) {\n var thisClass = this;\n var subclass;\n\n // name is optional\n name = name || '';\n\n // apply superclass constructor\n var constructorCode = applyConstructor === false\n ? ''\n : 'thisClass.apply(this, arguments);';\n\n eval('subclass = function ' + name + '(){ ' + constructorCode + ' }');\n\n makeSubclass.call(subclass, thisClass);\n\n // copy class methods\n // - for them to work correctly they should not explictly use superclass name\n // and use \"this\" instead\n __.deepExtend.call(subclass, thisClass, true);\n\n return subclass;\n}\n\n\n/**\n * Sets up prototype chain to change `thisClass` (a constructor function) so that it becomes a subclass of `Superclass`.\n * Returns `thisClass` so it can be [chained](proto.js.html) with _.extendProto and [_.extend](object.js.html#extend).\n *\n * @param {Function} thisClass A class that will become a subclass of Superclass\n * @param {Function} Superclass A class that will become a superclass of thisClass\n * @return {Function}\n */\nfunction makeSubclass(Superclass) {\n // prototype chain\n this.prototype = Object.create(Superclass.prototype);\n \n // subclass identity\n extendProto.call(this, {\n constructor: this\n });\n return this;\n}\n\n\n/**\n * Calls constructor `this` with arguments passed as array\n * \n * @param {Function} thisClass A class constructor that will be called\n * @return {Array|Array-like} args Array of arguments that will be passed to constructor\n */\nfunction newApply(args) {\n if (! Array.isArray(args))\n args = Array.prototype.slice.call(args);\n // \"null\" is context to pass to class constructor, first parameter of bind\n var args = [null].concat(args);\n return new (Function.prototype.bind.apply(this, args));\n}\n", "'use strict';\n\n\nvar __ = require('./proto_object');\n\n\n/**\n * - [firstUpperCase](#firstUpperCase)\n * - [firstLowerCase](#firstLowerCase)\n * - [toRegExp](#toRegExp)\n * - [toFunction](#toFunction)\n * - [toDate](#toDate)\n * - [toQueryString](#toQueryString)\n * - [fromQueryString](#fromQueryString)\n * - [jsonParse](#jsonParse)\n * - [hashCode](#hashCode)\n * - [unPrefix](#unPrefix)\n */\n var stringMethods = module.exports = {\n firstUpperCase: firstUpperCase,\n firstLowerCase: firstLowerCase,\n toRegExp: toRegExp,\n toFunction: toFunction,\n toDate: toDate,\n toQueryString: toQueryString,\n fromQueryString: fromQueryString,\n jsonParse: jsonParse,\n hashCode: hashCode,\n unPrefix: unPrefix\n};\n\n\n/**\n * Returns string with the first character changed to upper case.\n *\n * @param {String} self A string that will have its first character replaced\n */\nfunction firstUpperCase() {\n return this ? this[0].toUpperCase() + this.slice(1) : this;\n}\n\n\n/**\n * Returns string with the first character changed to lower case.\n *\n * @param {String} self A string that will have its first character replaced\n */\nfunction firstLowerCase() {\n return this ? this[0].toLowerCase() + this.slice(1) : this;\n}\n\n\n/**\n * Converts string created by `toString` method of RegExp back to RegExp\n *\n * @param {String} self string containing regular expression including enclosing \"/\" symbols and flags\n * @return {RegExp}\n */\nfunction toRegExp() {\n var rx = this.match(regexpStringPattern);\n if (rx) return new RegExp(rx[1], rx[2]);\n}\nvar regexpStringPattern = /^\\/(.*)\\/([gimy]*)$/;\n\n\n/**\n * Converts string created by `toString` method of function back to function\n *\n * @param {String} self string containing full function code\n * @return {Function}\n */\nfunction toFunction() {\n var func;\n var code = 'func = ' + this + ';';\n try {\n eval(code);\n return func;\n } catch(e) {\n return;\n }\n}\n\n\n/**\n * Converts string to date in a safe way so that the resiult is undefined if date is invalid\n *\n * @param {String|Date} self string or date object to convert to VALID date\n * @return {[type]} [description]\n */\nfunction toDate() {\n if (! this) return;\n try {\n var date = new Date(this);\n } catch (e) {}\n if (date && date.getTime && !isNaN(date.getTime()))\n return date;\n}\n\n\n/**\n * Convert params object to a url style query string (without \"?\")\n * \n * @param {Object} self The object hash to be converted\n * @param {Function} encode optional function used to encode data, encodeURIComponent is used if not specified\n * @return {String} the resulting query string\n */\nfunction toQueryString(encode) {\n var qs = ''\n , params = this || {}\n , encode = encode || encodeURIComponent;\n\n __.eachKey.call(params, function(value, key) {\n qs += key + '=' + encode(value) + '&';\n });\n \n return qs.slice(0, -1);\n}\n\n\n/**\n * Convert url style query string (without \"?\") into object hash\n * \n * @param {String} self The string to be converted\n * @param {Function} decode optional decode function, decodeURIComponent will be used if not supplied\n * @return {Object} The resulting object hash\n */\nfunction fromQueryString(decode) {\n var pairs = this.split('&')\n , results = {}\n , decode = decode || decodeURIComponent;\n\n pairs.forEach(function(pair) {\n var splitPair = pair.split('=');\n if (splitPair.length < 2) return;\n var key = splitPair[0]\n , value = decode(splitPair[1] || '');\n if (!key) return;\n results[key] = value;\n });\n\n return results;\n}\n\n\n/**\n * Safe JSON.parse, returns undefined if JSON.parse throws an exception\n *\n * @param {String} self JSON string representation of object\n * @return {Object|undefined}\n */\nfunction jsonParse() {\n try {\n return JSON.parse(this);\n } catch (e) {}\n}\n\n\n/**\n * Dan Bernstein's algorythm to create hash from string\n *\n * @param {String} self string to convert to hash\n * @return {Number}\n */\nfunction hashCode() {\n var hash = 5381\n , str = this\n , len = str.length;\n for (var i = 0; i < len; i++) {\n var char = str.charCodeAt(i);\n hash = ((hash << 5) + hash) + char; /* hash * 33 + c */\n }\n return hash;\n}\n\n\n/**\n * Removes given prefix from the string. If string does not begin from the prefix, returns undefined\n * \n * @param {String} self\n * @return {String}\n */\nfunction unPrefix(str) {\n if (this.indexOf(str) == 0)\n return this.replace(str, '');\n}\n", "'use strict';\n\n/**\n * - [times](#times)\n * - [repeat](#repeat)\n * - [tap](#tap)\n * - [result](#result)\n * - [identity](#identity)\n * - [property](#property)\n * - [compareProperty](#compareProperty)\n * - [noop](#noop)\n */\nvar utilMethods = module.exports = {\n times: times,\n repeat: repeat,\n tap: tap,\n result: result,\n identity: identity,\n property: property,\n compareProperty: compareProperty,\n noop: noop\n};\n\n\n/**\n * Calls `callback` `self` times with `thisArg` as context. Callback is passed iteration index from 0 to `self-1`\n * \n * @param {Integer} self\n * @param {Function} callback\n * @param {Any} thisArg\n * @return {Array}\n */\nfunction times(callback, thisArg) {\n var arr = Array(Math.max(0, this));\n for (var i = 0; i < this; i++)\n arr[i] = callback.call(thisArg, i);\n return arr;\n}\n\n\n/**\n * Returns array with the first argument repeated `times` times\n * @param {Any} self\n * @param {Integer} times\n * @return {Array[Any]}\n */\nfunction repeat(times) {\n var arr = Array(Math.max(0, times));;\n for (var i = 0; i < times; i++)\n arr[i] = this;\n return arr;\n}\n\n\n/**\n * Function to tap into chained methods and to inspect intermediary result\n *\n * @param {Any} self value that's passed between chained methods\n * @param {Function} func function that will be called with the value (both as context and as the first parameter)\n * @return {Any}\n */\nfunction tap(func) {\n func.call(this, this);\n return this;\n};\n\n\n/**\n * Calls function `self` (first parameter of _.result) with given context and arguments\n * \n * @param {Function|Any} self\n * @param {Any} thisArg context\n * @param {List} arguments extra arguments\n * @return {Any}\n */\nfunction result(thisArg) { //, arguments\n var args = Array.prototype.slice.call(arguments, 1);\n return typeof this == 'function'\n ? this.apply(thisArg, args)\n : this;\n}\n\n\n/**\n * Returns self. Useful for using as an iterator if the actual value needs to be returned. Unlike in underscore and lodash, this function is NOT used as default iterator.\n *\n * @param {Any} self \n * @return {Any}\n */\nfunction identity() {\n return this;\n}\n\n\n/**\n * Returns function that picks the property from the object\n *\n * @param {String} self\n * @return {Function}\n */\nfunction property() {\n var key = this;\n return function(obj) {\n return obj[key];\n };\n}\n\n\n/**\n * Returns function that can be used in array sort to sort by a given property\n *\n * @param {String} self\n * @return {Function}\n */\nfunction compareProperty() {\n var key = this;\n return function(a, b) {\n return a[key] < b[key]\n ? -1\n : a[key] > b[key]\n ? 1\n : 0;\n };\n}\n\n\n/**\n * Function that does nothing\n */\nfunction noop() {}\n", - "'use strict';\n\nvar utils = module.exports = {\n makeProtoInstanceMethod: makeProtoInstanceMethod,\n makeProtoFunction: makeProtoFunction,\n makeFindMethod: makeFindMethod\n}\n\n\nfunction makeProtoInstanceMethod(method) {\n return function() {\n this.self = method.apply(this.self, arguments);\n return this;\n };\n}\n\n\nfunction makeProtoFunction(method) {\n return function() {\n // when the method is executed, the value of \"this\" will be arguments[0],\n // other arguments starting from #1 will passed to method as parameters.\n return method.call.apply(method, arguments);\n };\n}\n\n\nvar _error = new Error;\n\n/**\n * Returns `find` or `findIndex` method, depending on parameter\n *\n * @param {Function} eachMethod - method to use for iteration (forEach for array or eachKey for object)\n * @param {String} findWhat 'value' - returns find method of Array (implemented in ES6) or findValue method of Object, anything else = returns findIndex/findKey methods.\n * @return {Function}\n */\nfunction makeFindMethod(eachMethod, findWhat) {\n var argIndex = findWhat == 'value' ? 0 : 1;\n\n return function findValueOrIndex(callback, thisArg, onlyEnumerable) {\n var caughtError;\n try {\n eachMethod.call(this, testItem, thisArg, onlyEnumerable);\n } catch (found) {\n if (found === _error) throw caughtError;\n else return found;\n }\n // if looking for index and not found, return -1\n if (argIndex && eachMethod == Array.prototype.forEach)\n return -1; \n\n function testItem(value, index, self) {\n var test;\n try {\n test = callback.call(this, value, index, self);\n } catch(err) {\n caughtError = err;\n throw _error;\n }\n if (test)\n throw arguments[argIndex];\n }\n }\n}\n" + "'use strict';\n\nvar utils = module.exports = {\n makeProtoInstanceMethod: makeProtoInstanceMethod,\n makeProtoFunction: makeProtoFunction,\n makeFindMethod: makeFindMethod\n}\n\n\nfunction makeProtoInstanceMethod(method) {\n return function() {\n this.self = method.apply(this.self, arguments);\n return this;\n };\n}\n\n\nfunction makeProtoFunction(method) {\n return function() {\n // when the method is executed, the value of \"this\" will be arguments[0],\n // other arguments starting from #1 will passed to method as parameters.\n return method.call.apply(method, arguments);\n };\n}\n\n\nvar _error = new Error;\n\n/**\n * Returns `find` or `findIndex` method, depending on parameter\n *\n * @param {Function} eachMethod - method to use for iteration (forEach for array or eachKey for object)\n * @param {String} findWhat 'value' - returns find method of Array (implemented in ES6) or findValue method of Object, anything else = returns findIndex/findKey methods.\n * @return {Function}\n */\nfunction makeFindMethod(eachMethod, findWhat) {\n var argIndex = findWhat == 'value' ? 0 : 1;\n\n return function findValueOrIndex(callback, thisArg, onlyEnumerable) {\n var caughtError;\n try {\n eachMethod.call(this, testItem, thisArg, onlyEnumerable);\n } catch (found) {\n if (found === _error) throw caughtError;\n else return found;\n }\n // if looking for index and not found, return -1\n if (argIndex && eachMethod == Array.prototype.forEach)\n return -1; \n\n function testItem(value, index, self) {\n var test;\n try {\n test = callback.call(this, value, index, self);\n } catch(err) {\n caughtError = err;\n throw _error;\n }\n if (test)\n throw arguments[argIndex];\n }\n }\n}\n", + "arguments[4][141][0].apply(exports,arguments)", + "arguments[4][142][0].apply(exports,arguments)", + "arguments[4][146][0].apply(exports,arguments)", + "arguments[4][147][0].apply(exports,arguments)" ] } \ No newline at end of file diff --git a/milo.min.js b/milo.min.js new file mode 100644 index 0000000..3c1e988 --- /dev/null +++ b/milo.min.js @@ -0,0 +1,9 @@ +!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;gthis._maxLength){var b=this.actions.shift();b.destroy()}return this.position=this.actions.length,this.position-1}function e(){this.actions.length&&(this.position--,this.actions.length--)}function f(){for(var a=this.position;a=0||b.indexOf(v.firstLowerCase(a))>=0)}var r=a("../abstract/facet"),s=a("../messenger"),t=a("../util/error").Facet,u=a("./c_utils"),v=a("mol-proto"),w=v.createSubclass(r,"ComponentFacet");b.exports=w;var x=v.partial(k,i),y=v.partial(k,j);v.extendProto(w,{init:c,start:e,check:g,destroy:h,onConfigMessages:f,domParent:i,postDomParent:x,scopeParent:j,postScopeParent:y,getMessageSource:m,dispatchSourceMessage:n,_createMessenger:d,_setMessageSource:l,_createMessageSource:o,_createMessageSourceWithAPI:p}),v.extend(w,{requiresFacet:q});var z="_messenger";s.useWith(w,z,s.defaultMethods)},{"../abstract/facet":1,"../messenger":67,"../util/error":98,"./c_utils":34,"mol-proto":150}],18:[function(a,b){"use strict";function c(){return n(this.owner.el,this.scope,!1)}function d(){m.prototype.start.apply(this,arguments),this.scope=new o(this.owner.el,this)}function e(a){function b(){throw new Error("path "+a+" is invalid")}a=a.split(".");var c=a.length;(a[0]||2>c)&&b();for(var d=this.owner,e=1;c>e;e++){var f=a[e];if(u.test(f)||b(),!d.container)return;if(d=d.container.scope[f],!d)return}return d}function f(a){var b={scope:{}};return a!==!1&&this.scope._each(function(a,c){b.scope[c]=a._getState()}),b}function g(a){p.eachKey(a.scope,function(a,b){var c=this.scope[b];c?c.setState(a):s.warn('component "'+b+'" does not exist on scope')},this)}function h(){this.scope._each(function(a){a.destroy()}),this.scope._detachElement(),m.prototype.destroy.apply(this,arguments)}function i(a,b){r.unwrapElement(this.owner.el),this.scope&&this.scope._each(function(b){b.remove(),a!==!1&&b.rename(void 0,!1),this.owner.scope&&this.owner.scope._add(b)},this),b!==!1&&this.owner.destroy()}function j(a){this.scope._add(a),this.owner.el.appendChild(a.el)}function k(a,b){this.scope._add(a),this.el.insertBefore(a.el,b&&b.el)}function l(a){this.scope._remove(a),this.owner.el.removeChild(a.el)}var m=a("../c_facet"),n=a("../../binder"),o=a("../scope"),p=a("mol-proto"),q=a("./cf_registry"),r=a("../../util/dom"),s=a("../../util/logger"),t=p.createSubclass(m,"Container");p.extendProto(t,{start:d,path:e,getState:f,setState:g,binder:c,destroy:h,unwrap:i,append:j,insertBefore:k,remove:l}),q.add(t),b.exports=t;var u=/^[A-Za-z][A-Za-z0-9\_\$]*$/},{"../../binder":9,"../../util/dom":94,"../../util/logger":102,"../c_facet":17,"../scope":41,"./cf_registry":31,"mol-proto":150}],19:[function(a,b){"use strict";function c(){H.wrapMessengerMethods.call(this),C.prototype.start.apply(this,arguments),this.elData=G(this.owner.el),this._dataChangesQueue=[],this._prepareMessageSource(),this._path="."+this.owner.name,this._value=this.get(),this.onSync("",e),this.onSync("datachangesfinished",h),this.onSync("childdata",j),this.onSync("changedata",K)}function d(){var a=new F(this.owner),b=new E(this,R,a,this.owner);this._setMessageSource(b),O.defineProperty(this,"_dataEventsSource",b),B.prototype._createProxyMethod.call(a,"value","value",this)}function e(a,b){if(this._bubbleUpDataChange(b),this._queueDataChange(b),""===b.path){var c=L(b);this.postMessage("datachangesfinished",{transaction:c})}}function f(a){var b=this.scopeParent();if(b){var c=O.clone(a);c.path=(this._path||"."+this.owner.name)+c.path,b.postMessage("childdata",c||a)}}function g(a){this._dataChangesQueue.push(a)}function h(a,b){this._postDataChanges(b.inTransaction);var c=this.scopeParent();c&&c.postMessage("datachangesfinished",b)}function i(a){var b=this._dataChangesQueue.reverse();this.postMessageSync("datachanges",{changes:b,transaction:a}),this._dataChangesQueue=[]}function j(a,b){this.postMessage(b.path,b),this._bubbleUpDataChange(b),this._queueDataChange(b)}function k(a){var b=L(k),c=this.config.set;if("function"==typeof c){var d=c.call(this.owner,a);return d}M(this._set,b);var e=this._value,f=this._set(a),g={path:"",type:"changed",newValue:f,oldValue:e};return M(g,b),this.postMessage("",g),f}function l(a){function b(a,b,c,e){var f=e.replace("$$",c),g=this.path(f,"undefined"!=typeof b);g&&(M(g.set,d),a[c]=g.set(b))}var c,d=L(l);if(null!=a&&"object"==typeof a)if(Array.isArray(a)){c=[];var e=this.owner.list;if(e){var f=e.count(),g=a.length-f;g>=3&&(e._addItems(g),e._updateDataPaths(f,e.count())),a.forEach(function(a,d){b.call(this,c,a,d,"[$$]")},this);for(var h=e.count(),i=h-a.length;i-->0;)e._removeItem(a.length)}else P.warn("Data: setting array data without List facet")}else c={},O.eachKey(a,function(a,d){b.call(this,c,a,d,".$$")},this);else c=this._setScalarValue(a);return this._value=c,c}function m(){var a=L(m),b=this.config.del;if("function"==typeof b){var c=b.call(this.owner);return N.call(this,a),c}var d=this._value;M(this._del,a),this._del();var e={path:"",type:"deleted",oldValue:d};M(e,a),this.postMessage("",e)}function n(){var a=L(n);M(this._set,a),this._set()}function o(a){return this.elData.set(this.owner.el,a)}function p(a){var b=this.config.get;return"function"==typeof b?b.call(this.owner,a):this._get(a)}function q(a){if(a!==!1){var b,c=this.owner;return c.list?(b=[],c.list.each(function(a,c){b[c]=a.data.get()}),c.container&&c.container.scope._each(function(a,d){!c.list.contains(a)&&a.data&&(b[d]=a.data.get())})):c.container?(b={},c.container.scope._each(function(a,c){a.data&&(b[c]=a.data.get())})):b=this._getScalarValue(),this._value=b,b}}function r(){return this.elData.get(this.owner.el)}function s(){var a,b=L(s),c=this.config.splice;if("function"==typeof c)return a=c.apply(this.owner,arguments),N.call(this,b),a;if(M(this._splice,b),a=this._splice.apply(this,arguments)){var d={path:"",type:"splice",index:a.spliceIndex,removed:a.removed,addedCount:a.addedCount,newValue:this._value};return M(d,b),this.postMessage("",d),a.removed}}function t(a,b){var c=L(t),d=this.owner.list;if(!d)return P.warn("Data: cannot use splice method without List facet");var e=[],f=d.count();if(arguments[0]=a=J.normalizeSpliceIndex(a,f),b>0&&f>0){for(var g=a;a+b>g;g++){var h=d.item(a);if(h){var i=h.data.get();d._removeItem(a)}else P.warn("Data: no item for index",g);e.push(i)}d._updateDataPaths(a,d.count())}var j=[],k=arguments.length,l=k>2,m=k-2;if(l){d._addItems(m,a);for(var g=2,n=a;k>g;g++,n++){var h=d.item(n);if(h){M(h.data.set,c);var i=h.data.set(arguments[g])}else P.warn("Data: no item for index",n);j.push(i)}d._updateDataPaths(a,d.count())}return this._value=this.get(),{spliceIndex:a,removed:e,addedCount:l?m:0} +}function u(){var a=this.config.len;return"function"==typeof a?a.call(this.owner):this._len()}function v(){return this.owner.list?this.owner.list.count():void P.error("Data: len called without list facet")}function w(a,b){if(!a)return this;for(var c=H.parseAccessPath(a),d=this.owner,e=0,f=c.length;f>e;e++){var g=c[e],h=H.getPathNodeKey(g);if("array"==g.syntax&&d.list){var i=d.list.item(h);i||b===!1||(i=d.list._addItem(h),i.data._path=g.property),d=i}else d.container&&(d=d.container.scope[h]);var j=d&&d.data;if(!j)break}return j}function x(){return this._path}function y(){var a=this._path;return"["==a[0]?+a.slice(1,-1):a.slice(1)}function z(a){return{state:this.get(a)}}function A(a){return this.set(a.state)}var B=a("../../abstract/mixin"),C=a("../c_facet"),D=a("./cf_registry"),E=(a("../../messenger"),a("../msg_src/dom_events")),F=a("../msg_api/data"),G=a("../msg_api/de_data"),H=a("../../model/path_utils"),I=a("../../model/m_path"),J=a("../../model/model_utils"),K=a("../../model/change_data"),L=K.getTransactionFlag,M=K.setTransactionFlag,N=K.postTransactionFinished,O=a("mol-proto"),P=a("../../util/logger"),Q=O.createSubclass(C,"Data");O.extendProto(Q,{start:c,getState:z,setState:A,get:p,set:k,del:m,splice:s,len:u,path:w,getPath:x,getKey:y,_get:q,_set:l,_del:n,_splice:t,_len:v,_setScalarValue:o,_getScalarValue:r,_bubbleUpDataChange:f,_queueDataChange:g,_postDataChanges:i,_prepareMessageSource:d}),D.add(Q),b.exports=Q,["push","pop","unshift","shift"].forEach(function(a){var b=I.prototype[a];O.defineProperty(Q.prototype,a,b)});var R={trigger:"trigger"}},{"../../abstract/mixin":3,"../../messenger":67,"../../model/change_data":73,"../../model/m_path":76,"../../model/model_utils":77,"../../model/path_utils":79,"../../util/logger":102,"../c_facet":17,"../msg_api/data":36,"../msg_api/de_data":37,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],20:[function(a,b){"use strict";function c(a){var b=a.domConfig||{},c=b.tagName||"div",e=document.createElement(c),f=a.content,g=a.template;return d(e,b),"string"==typeof f&&(e.innerHTML=g?I.template(g)({content:f}):f),e}function d(a,b){var c=b&&b.cls,d=b&&b.attributes;d&&D.eachKey(d,function(b,c){a.setAttribute(c,b)}),c&&j(a,"add",c)}function e(){var a=this.owner.el;d(a,this.config);var b=window.getComputedStyle(a);this._visible=b&&"none"!=b.display}function f(){this.toggle(!0)}function g(){this.toggle(!1)}function h(a){a="undefined"==typeof a?!this._visible:!!a,this._visible=a;var b=this.owner.el;return b.style.display=a?"block":"none",a}function i(a,b,c){j(this.owner.el,a,b,c)}function j(a,b,c,d){function e(a){g?void 0===d?f[b](a):f[b](a,d):f[b](a)}var f=a.classList,g="toggle"==b;if(Array.isArray(c))c.forEach(e);else{if("string"!=typeof c)throw new G("unknown type of CSS classes parameter");e(c)}}function k(){this.owner.el&&H.detachComponent(this.owner.el)}function l(a,b){if(!this.owner.el)throw new Error("Cannot call setStyle on owner with no element: "+this.owner.constructor.name);this.owner.el.style[a]=b}function m(a){for(var b in a)this.owner.el.style[b]=a[b]}function n(a){return this.owner.el&&this.owner.el.cloneNode(a)}function o(){var a=J.createElement(this.config);return a}function p(){H.removeElement(this.owner.el)}function q(a){this.owner.el.appendChild(a)}function r(a){var b=this.owner.el,c=b.firstChild;c?b.insertBefore(a,c):b.appendChild(a)}function s(a){for(;a.childNodes.length;)this.append(a.childNodes[0])}function t(a){for(;a.childNodes.length;)this.prepend(a.childNodes[a.childNodes.length-1])}function u(a){var b=this.owner.el,c=b.parentNode;c.insertBefore(a,b.nextSibling)}function v(a){var b=this.owner.el,c=b.parentNode;c.insertBefore(a,b)}function w(){var a=this.owner.getScopeParent();a&&a.el.appendChild(this.owner.el)}function x(){return H.children(this.owner.el)}function y(a,b){if(!K.hasOwnProperty(a))throw new G("incorrect find direction: "+a);var c=this.owner.el,d=this.owner.scope,e=document.createTreeWalker(d._rootEl,NodeFilter.SHOW_ELEMENT);e.currentNode=c;for(var f=e[K[a]](),g=(Object.keys(d),!1);f;){var h=new F(f);if(h.node&&(h.parse().validate(),d.hasOwnProperty(h.compName))){var i=d[h.compName];if(!b||b(i)){g=!0;break}}e.currentNode=f,f=e[K[a]]()}return g?i:void 0}function z(){var a=window.getSelection();if(!a.isCollapsed)return!0;var b=a.focusNode&&a.focusNode.textContent,c=b&&" "==b.charAt(0)?1:0;if(a.anchorOffset!=c)return!0;var d=document.createTreeWalker(this.owner.el,NodeFilter.SHOW_TEXT);d.currentNode=a.anchorNode;var e=d.previousNode(),f=e?""==!e.nodeValue.trim():!1;return f}function A(){var a=window.getSelection();if(!a.isCollapsed)return!0;var b=a.focusNode&&a.focusNode.textContent,c=b&&" "==b.charAt(b.length-1)?a.anchorNode.length-1:a.anchorNode.length;if(a.anchorOffset=0;var f=d[e&&e.compClass];return!!q.result(f,this.owner,e,a);default:throw new p("Incorrect allowed components in config")}}else{var g=c&&c.dataTypes;switch(typeof g){case"undefined":return!1;case"string":return a.types.indexOf(g)>=0}}}var j,k=a("../c_facet"),l=a("./cf_registry"),m=a("../msg_src/dom_events"),n=a("../msg_api/drop"),o=a("../../util/dragdrop"),p=a("../../util/error").Drop,q=a("mol-proto"),r=q.createSubclass(k,"Drop");q.extendProto(r,{init:c,start:d}),l.add(r),b.exports=r,j=q.throttle(h,50)},{"../../util/dragdrop":97,"../../util/error":98,"../c_facet":17,"../msg_api/drop":38,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],23:[function(a,b){"use strict";function c(){d.prototype.init.apply(this,arguments);var a=new f(this,void 0,void 0,this.owner);this._setMessageSource(a),g.defineProperty(this,i,a)}var d=a("../c_facet"),e=a("./cf_registry"),f=(a("../../messenger"),a("../msg_src/dom_events")),g=a("mol-proto"),h=g.createSubclass(d,"Events");g.extendProto(h,{init:c}),e.add(h),b.exports=h;var i="_domEventsSource";f.useWith(h,i,["trigger"])},{"../../messenger":67,"../c_facet":17,"../msg_src/dom_events":39,"./cf_registry":31,"mol-proto":150}],24:[function(a,b){"use strict";function c(){k.prototype.init.apply(this,arguments);var a=new m(this,void 0,void 0,this.owner);this._setMessageSource(a),n.defineProperty(this,r,a)}function d(){function a(a){b.postMessage("domready",a)}k.prototype.start.apply(this,arguments);var b=this;milo(a)}function e(){k.prototype.destroy.apply(this,arguments)}function f(){return this.owner.el.contentWindow}function g(){var a=this.getWindow().document.readyState;return"loading"!=a?a:!1}function h(){var a=this.getWindow().milo;return this.isReady()&&a&&a.milo_version}function i(a){if("function"==typeof a){var b=this;this.whenMiloReady(function(){b.getWindow().milo(a)})}var c=this.getWindow();return c&&c.milo}function j(a,b){return function(c){function d(){c.apply(e,f)}var e=this,f=n.slice(arguments,1);a.call(this)?d():this.on(b,d)}}var k=a("../c_facet"),l=a("./cf_registry"),m=(a("../../messenger"),a("../msg_src/frame")),n=(a("../../services/de_constrs"),a("mol-proto")),o=n.createSubclass(k,"Frame"),p=j(g,"domready"),q=j(h,"message:miloready");n.extendProto(o,{init:c,start:d,destroy:e,getWindow:f,isReady:g,whenReady:p,isMiloReady:h,whenMiloReady:q,milo:i}),l.add(o),b.exports=o;var r="_messageSource";m.useWith(o,r,["trigger"])},{"../../messenger":67,"../../services/de_constrs":82,"../c_facet":17,"../msg_src/frame":40,"./cf_registry":31,"mol-proto":150}],25:[function(a,b){"use strict";function c(){return{state:{index:this.getIndex()}}}function d(a){this.setIndex(a.state.index)}function e(){return this.index}function f(a){this.index=a}function g(){this.list.removeItem(this.index)}function h(){this.list.extractItem(this.index)}var i=a("../c_facet"),j=a("./cf_registry"),k=(a("../../model"),a("mol-proto")),l=(a("../../services/mail"),k.createSubclass(i,"Item"));k.extendProto(l,{getState:c,setState:d,getIndex:e,setIndex:f,removeItem:g,extractItem:h,require:["Container","Dom","Data"]}),j.add(l),b.exports=l},{"../../model":74,"../../services/mail":84,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],26:[function(a,b){"use strict";function c(){y.prototype.init.apply(this,arguments);B.defineProperties(this,{_listItems:[],_listItemsHash:{}}),B.defineProperty(this,"itemSample",null,B.WRIT)}function d(){this.owner.on("childrenbound",e)}function e(){var a=this.dom.children(),b=this.list._listItems,c=this.list._listItemsHash;if(a&&a.forEach(function(a){var d=z.getComponent(a);d&&d.item&&(b.push(d),c[d.name]=d,d.item.list=this.list)},this),b.length){var d=b[0];b.splice(0,1),delete c[d.name],b.forEach(function(a,b){a.item.setIndex(b)})}if(!d)throw new E("No child component has Item facet");this.list.itemSample=d,d.dom.hide(),d.remove(!0),d.dom.removeCssClasses(L),d.walkScopeTree(function(a){delete a.el[K.componentRef]}),this.list._createCacheTemplate()}function f(){if(!this.itemSample)return!1;{var a=this.itemSample,b=a.el.cloneNode(!0),c=a.componentInfo.attr;B.clone(c)}c.compName="{{= it.componentName() }}",c.el=b,c.decorate();var d="{{ var i = it.count; while(i--) { }}"+b.outerHTML+"{{ } }}";this.itemsTemplate=G.compile(d)}function g(a){return this._listItems[a]}function h(){return this._listItems.length}function i(a,b){this._listItems.splice(a,0,b),this._listItemsHash[b.name]=b,b.item.list=this,b.item.setIndex(+a)}function k(a){return this._listItemsHash[a.name]==a}function l(a,b){return a=a||this.count(),this.owner.data.splice(a,0,b||{}),this.item(a)}function m(a){if(a=a||this.count(),this.item(a))throw E("attempt to create item with ID of existing item");var b=z.copy(this.itemSample,!0),c=this._itemPreviousComponent(a);return c.el.parentNode?(c.dom.insertAfter(b.el),this._setItem(a,b),b.el.style.display="",n.call(this,a+1),b):F.warn("list item sample was removed from DOM, probably caused by wrong data. Reset list data with array")}function n(a,b){a=a||0,b=b||this.count();for(var c=a;b>c;c++){var d=this._listItems[c];d?d.item.setIndex(c):F.warn("List: no item at position",c)}}function o(a,b){var c=B.slice(arguments,2);c.lengtha)throw new E("can't add negative number of items");if(0!=a){var c=this.itemsTemplate({componentName:D.componentName,count:a}),d=document.createElement("div");d.innerHTML=c,C(d,this.owner.container.scope);var e=J.children(d);if(a!=e.length&&F.error("number of items added is different from requested"),e&&e.length){var f=this.count(),g=0>b?0:"undefined"==typeof b||b>f?f:b,h=0==g?this.itemSample:this._listItems[g-1],i=document.createDocumentFragment(),j=[];if(e.forEach(function(a){var b=z.getComponent(a);return b?(j.push(b),this._setItem(g++,b),i.appendChild(a),void(a.style.display="")):F.error("List: element in new items is not a component")},this),n.call(this,g),!h.el.parentNode)return F.warn("list item sample was removed from DOM, probably caused by wrong data. Reset list data with array");h.dom.insertAfter(i),B.deferMethod(j,"forEach",function(a){a.broadcast("stateready")})}}}function q(a){return this.owner.data.splice(a,1)}function r(a){var b=this._removeItem(a,!1);return this._updateDataPaths(a,this.count()),b}function s(a,b){var c=this.item(a);return c?(this._listItems[a]=void 0,delete this._listItemsHash[c.name],b!==!1?c.destroy():(c.remove(),c.dom.remove()),this._listItems.splice(a,1),n.call(this,a),c):F.warn("attempt to remove list item with id that does not exist")}function t(a,b){var c=this.item(a);c.dom.insertAfter(b.el),this._removeItem(a),this._setItem(a,b)}function u(a){for(;a>=0&&!this._listItems[a];)a--;return a>=0?this._listItems[a]:this.itemSample}function v(a,b){for(var c=a;b>c;c++){var d=this.item(c);d?d.data._path="["+c+"]":F.warn("Data: no item for index",j)}}function w(a,b){this._listItems.forEach(function(b,c){b?a.apply(this,arguments):F.warn("List$each: item",c,"is undefined")},b||this)}function x(){this.itemSample&&this.itemSample.destroy(!0),y.prototype.destroy.apply(this,arguments)}var y=a("../c_facet"),z=a("../c_class"),A=a("./cf_registry"),B=a("mol-proto"),C=(a("../../services/mail"),a("../../binder")),D=a("../../util"),E=D.error.List,F=D.logger,G=a("dot"),H=D.check,I=H.Match,J=D.dom,K=a("../../config"),L="ml-list-item-sample",M=B.createSubclass(y,"List");B.extendProto(M,{init:c,start:d,destroy:x,require:["Container","Dom","Data"],_itemPreviousComponent:u,item:g,count:h,contains:k,addItem:l,addItems:o,replaceItem:t,removeItem:q,extractItem:r,each:w,_setItem:i,_removeItem:s,_addItem:m,_addItems:p,_createCacheTemplate:f,_updateDataPaths:v}),A.add(M),b.exports=M},{"../../binder":9,"../../config":65,"../../services/mail":84,"../../util":100,"../c_class":16,"../c_facet":17,"./cf_registry":31,dot:115,"mol-proto":150}],27:[function(a,b){"use strict";function c(){this.m=new j(this.config.data,this),h.prototype.init.apply(this,arguments)}function d(){var a=this.m.get();return"object"==typeof a&&(a=k.deepClone(a)),{state:a}}function e(a){return this.m.set(a.state)}function f(){this._messenger=this.m._messenger}function g(){this.m.destroy(),h.prototype.destroy.apply(this,arguments)}var h=a("../c_facet"),i=a("./cf_registry"),j=a("../../model"),k=(a("../../abstract/mixin"),a("mol-proto")),l=k.createSubclass(h,"Model");k.extendProto(l,{init:c,getState:d,setState:e,_createMessenger:f,destroy:g}),i.add(l),b.exports=l,j.useWith(l,"m")},{"../../abstract/mixin":3,"../../model":74,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],28:[function(a,b){"use strict";function c(){this.m=new h(this.config.options,this),f.prototype.init.apply(this,arguments),this.m.proxyMethods(this)}function d(){this._messenger=this.m._messenger}function e(){this.m.destroy(),f.prototype.destroy.apply(this,arguments)}var f=a("../c_facet"),g=a("./cf_registry"),h=a("../../model"),i=a("mol-proto"),j=i.createSubclass(f,"Options");i.extendProto(j,{init:c,destroy:e,_createMessenger:d}),g.add(j),b.exports=j},{"../../model":74,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],29:[function(a,b){"use strict";function c(){i.prototype.init.apply(this,arguments);var a=this.config.interpolate===!1?void 0:this.config.compile||milo.config.template.compile;this.set(this.config.template||"",a,this.config.compileOptions)}function d(){i.prototype.start.apply(this,arguments),this.config.autoRender&&(this.render(),this.config.autoBinder&&this.binder())}function e(){return this._template}function f(a,b,c){return l(a,n.OneOf(String,Function)),l(b,n.Optional(Function)),"function"==typeof a?this._template=a:(this._templateStr=a,b?this._compile=b:b=this._compile,b&&(this._template=b(a,c))),this}function g(a){return this.owner.el.innerHTML=this._template?this._template(a):this._templateStr,this}function h(){return this.owner.container?this.owner.container.binder():void m.error("TemplateFacet: Binder called without container facet.")}var i=a("../c_facet"),j=a("./cf_registry"),k=a("mol-proto"),l=a("../../util/check"),m=a("../../util/logger"),n=l.Match,o=(a("../../binder"),k.createSubclass(i,"Template"));k.extendProto(o,{init:c,start:d,set:f,getCompiled:e,render:g,binder:h}),j.add(o),b.exports=o},{"../../binder":9,"../../util/check":90,"../../util/logger":102,"../c_facet":17,"./cf_registry":31,"mol-proto":150}],30:[function(a,b){"use strict";function c(){j.prototype.init.apply(this,arguments),this._activeState="",this._defaultKey="",this._state={}}function d(){return this._state[this._activeState]||this._state[this._defaultKey]}function e(a){this._state[""]=a,this.setActiveState("")}function f(a){this._activeState=a}function g(a,b,c){if(!a)throw new Error("Transfer$setStateWithKey: no key");this._defaultKey=c?a:this._defaultKey||a,this._state[a]=b,this.setActiveState(a)}function h(a){return"string"==typeof a&&this._state[a]}function i(){var a=this.getState();return{compName:a&&a.compName,compClass:a&&a.compClass}}var j=a("../c_facet"),k=a("./cf_registry"),l=a("mol-proto"),m=l.createSubclass(j,"Transfer");l.extendProto(m,{init:c,getState:d,setState:e,setActiveState:f,setStateWithKey:g,getStateWithKey:h,getComponentMeta:i}),k.add(m),b.exports=m},{"../c_facet":17,"./cf_registry":31,"mol-proto":150}],31:[function(a,b){"use strict";var c=a("../../abstract/registry"),d=a("../c_facet"),e=new c(d);e.add(d),b.exports=e},{"../../abstract/registry":4,"../c_facet":17}],32:[function(a,b){"use strict";function c(a,b,c,d){c.parse().validate(),this.scope=a,this.el=b,this.attr=c,this.name=c.compName,this.ComponentClass=f(c,d),this.extraFacetsClasses=g(this.ComponentClass,c,d),this.ComponentClass&&i(this.ComponentClass,this.extraFacetsClasses)&&(this.container={})}function d(){delete this.el,this.attr.destroy()}function e(a,b){a=a||l(),m.rename(this,a,b),this.attr.compName=a,this.attr.decorate()}function f(a,b){var c=j.get(a.compClass);return c||h(b,"class "+a.compClass+" is not registered"),c}function g(a,b,c){var d=b.compFacets,e={};return Array.isArray(d)&&d.forEach(function(d){d=p.firstUpperCase(d),a.hasFacet(d)&&h(c,"class "+a.name+" already has facet "+d),e[d]&&h(c,"component "+b.compName+" already has facet "+d);var f=k.get(d);e[d]=f}),e}function h(a,b){if(a!==!1)throw new n(b);o.error("ComponentInfo binder error:",b)}function i(a,b){function c(){return a.prototype.facetsClasses&&p.someKey(a.prototype.facetsClasses,d)}function d(a){return a.requiresFacet("container")}return a.hasFacet("container")||"Container"in b||p.someKey(b,d)||c()}var j=a("./c_registry"),k=a("./c_facets/cf_registry"),l=a("../util/component_name"),m=a("./scope"),n=a("../util/error").Binder,o=a("../util/logger"),p=a("mol-proto");b.exports=c,p.extendProto(c,{destroy:d,rename:e})},{"../util/component_name":91,"../util/error":98,"../util/logger":102,"./c_facets/cf_registry":31,"./c_registry":33,"./scope":41,"mol-proto":150}],33:[function(a,b){"use strict";var c=a("../abstract/registry"),d=a("./c_class"),e=new c(d);e.add(d),b.exports=e},{"../abstract/registry":4,"./c_class":16}],34:[function(a,b){"use strict";function c(a){return a.hasOwnProperty(h.componentRef)}function d(a){return a&&a[h.componentRef]}function e(a,b,c){i(b,j.Optional(Boolean)),i(c,j.Optional(j.OneOf(Function,String)));var d=f(c);return g(a,b,d)}function f(a){if("function"==typeof a)return a;if("string"==typeof a){var b=_.firstLowerCase(a);return function(a){return a.hasFacet(b)}}}function g(a,b,c){if(b!==!1){var e=d(a);if(e&&(!c||c(e)))return e}return a.parentNode?g(a.parentNode,!0,c):void 0}{var h=a("../config"),i=a("../util/check"),j=i.Match;b.exports={isComponent:c,getComponent:d,getContainingComponent:e,_makeComponentConditionFunc:f}}},{"../config":65,"../util/check":90}],35:[function(a,b){"use strict";var c=a("../c_class"),d=a("../c_registry"),e=c.createComponentClass("View",["container"]);d.add(e),b.exports=e},{"../c_class":16,"../c_registry":33}],36:[function(a,b){"use strict";function c(a){h.prototype.init.apply(this,arguments),this.component=a,this.elData=i(a.el)}function d(){var a=this.component.data.config.get,b="function"==typeof a?a.call(this.component):this.elData.get(this.component.el);return this.component.data._value=b,b}function e(a){var b=this.component.data.config.event,c=b||this.elData.event(this.component.el);return""==a&&c?c:void 0}function f(a,b,c){return c.newValue!=c.oldValue}function g(){var a=this.component.data._value,b=this.value(),c={path:"",type:"changed",oldValue:a,newValue:b};return c}var h=a("../../messenger/m_api"),i=a("./de_data"),j=a("mol-proto"),k=a("../../util/check"),l=(k.Match,j.createSubclass(h,"DataMsgAPI",!0));j.extendProto(l,{init:c,translateToSourceMessage:e,filterSourceMessage:f,createInternalData:g,value:d}),b.exports=l},{"../../messenger/m_api":68,"../../util/check":90,"./de_data":37,"mol-proto":150}],37:[function(a,b){"use strict";function c(a){var b=h[a.type];return b?b.property:h.byDefault.property}function d(a){var b=h[a.type];return b?b.event:h.byDefault.event}var e=a("mol-proto"),f=function(a){var b=a.tagName.toLowerCase(),c=g[b];return c||g.byDefault};b.exports=f;var g={byDefault:{property:"innerHTML"},div:{property:"innerHTML"},span:{property:"innerHTML",event:"input"},p:{property:"innerHTML",event:"input"},input:{property:c,event:d},textarea:{property:"value",event:"input"},select:{property:"value",event:"change"},img:{property:"src"},caption:{property:"innerHTML",event:"input"},thead:{property:"innerHTML",event:"input"},tbody:{property:"innerHTML",event:"input"},tfoot:{property:"innerHTML",event:"input"}};e.eachKey(g,function(a){var b=a.property,c=a.event;"function"!=typeof b&&(a.property=function(){return b});var d=a.property;"function"!=typeof c&&(a.event=function(){return c}),a.get||(a.get=function(a){return a[d(a)]}),a.set||(a.set=function(a,b){return a[d(a)]="undefined"==typeof b?"":b})});var h={byDefault:{property:"value",event:"input"},checkbox:{property:"checked",event:"change"},radio:{property:"checked",event:"change"},text:{property:"value",event:"input"}}},{"mol-proto":150}],38:[function(a,b){"use strict";function c(a){return h.hasOwnProperty(a)?h[a]:a}function d(){delete this._currentTarget,delete this._inside}function e(a,b,c){var e=!0;return"dragenter"==a&&"dragin"==b?(this._currentTarget=c.target,e=!this._inside,this._inside=!0):"dragleave"==a&&"dragout"==b?(e=this._currentTarget==c.target,e&&d.call(this)):"drop"==a&&d.call(this),e}var f=a("../../messenger/m_api"),g=_.createSubclass(f,"DropMsgAPI",!0);_.extendProto(g,{translateToSourceMessage:c,filterSourceMessage:e}),b.exports=g;var h={dragin:"dragenter",dragout:"dragleave"}},{"../../messenger/m_api":68}],39:[function(a,b){"use strict";function c(a,b,c,d){j(d,h),this.component=d,g.prototype.init.apply(this,arguments)}function d(){g.prototype.destroy.apply(this,arguments),delete this.component}function e(){return this.component.el}var f=a("../../services/dom_source"),g=a("../../messenger/m_source"),h=a("../c_class"),i=a("mol-proto"),j=a("../../util/check"),k=(j.Match,i.createSubclass(f,"DOMEventsSource",!0));i.extendProto(k,{init:c,destroy:d,emitter:e}),b.exports=k},{"../../messenger/m_source":70,"../../services/dom_source":83,"../../util/check":90,"../c_class":16,"mol-proto":150}],40:[function(a,b){"use strict";function c(a,b,c,d){if(l(d,j),this.component=d,"iframe"!=d.el.tagName.toLowerCase())throw new n("component for FrameMessageSource can only be attached to iframe element");i.prototype.init.apply(this,arguments)}function d(){return this.component.el.contentWindow}function e(){var a=this.frameWindow();a?a.addEventListener("message",this,!1):m.warn("FrameMessageSource: frame window is undefined")}function f(){var a=this.frameWindow();a?a.removeEventListener("message",this,!1):m.warn("FrameMessageSource: frame window is undefined")}function g(a,b){b=b||{},b.type=a,this.frameWindow().postMessage(b,"*")}function h(a){this.dispatchMessage(a.data.type,a)}var i=a("../../messenger/m_source"),j=a("../c_class"),k=a("mol-proto"),l=a("../../util/check"),m=a("../../util/logger"),n=(l.Match,a("../../util/error").FrameMessageSource),o=k.createSubclass(i,"FrameMessageSource",!0);k.extendProto(o,{init:c,addSourceSubscriber:e,removeSourceSubscriber:f,trigger:g,frameWindow:d,handleEvent:h}),b.exports=o},{"../../messenger/m_source":70,"../../util/check":90,"../../util/error":98,"../../util/logger":102,"../c_class":16,"mol-proto":150}],41:[function(a,b){"use strict";function c(a,b){t.defineProperties(this,{_rootEl:a,_hostObject:b},t.WRIT)}function d(a,b){if("string"==typeof b?a.name=b:b=a.name,this.hasOwnProperty(b))throw new w("duplicate object name: "+b);l(b),f.call(this,a,b)}function e(a,b){"string"==typeof b?a.name=b:b=a.name;var c=this.hasOwnProperty(b);c?x.error("Scope: duplicate object name: "+b):(c=!y.test(b),c&&x.error("Scope: name should start from letter, this name is not allowed: "+b)),c&&(b=u(),a.name=b),f.call(this,a,b)}function f(a,b){this[b]=a,a.scope=this,"function"==typeof a.postMessage&&a.postMessage("addedtoscope")}function g(a){v(a,c),a._each(d,this)}function h(a,b){b._add(a),this._remove(a.name),a.scope=b}function i(a){a._each(function(b){this._add(b,b.name),a._remove(b.name)},this)}function j(a,b){t.eachKey(this,a,b||this,!0)}function k(a,b){return t.filterKeys(this,a,b||this,!0)}function l(a){if(!y.test(a))throw new w("name should start from letter, this name is not allowed: "+a)}function m(){return Object.keys(this).length}function n(){var a=Object.keys(this)[0];return a&&this[a]}function o(a,b){if(!(a in this))return void(b||x.warn("removing object that is not in scope"));var c=this[a];delete this[a],"function"==typeof c.postMessage&&c.postMessage("removedfromscope")}function p(){this._each(function(a,b){delete this[b].scope,delete this[b]},this)}function q(){this._rootEl=null}function r(a){return this.hasOwnProperty(a.name)}function s(a,b,c){a.scope&&c!==!1?(a.scope._remove(a.name),a.scope._add(a,b)):a.name=b}var t=a("mol-proto"),u=a("../util/component_name"),v=a("../util/check"),w=(v.Match,a("../util/error").Scope),x=a("../util/logger");t.extendProto(c,{_add:d,_safeAdd:e,_copy:g,_each:j,_move:h,_merge:i,_length:m,_any:n,_remove:o,_clean:p,_detachElement:q,_has:r,_filter:k}),t.extend(c,{rename:s}),b.exports=c;var y=/^[A-Za-z][A-Za-z0-9\_\$]*$/},{"../util/check":90,"../util/component_name":91,"../util/error":98,"../util/logger":102,"mol-proto":150}],42:[function(a,b){"use strict";function c(a){this.el.disabled=a}function d(){return!!this.el.disabled}var e=a("../c_class"),f=a("../c_registry"),g=e.createComponentClass("MLButton",{events:void 0,dom:{cls:"ml-ui-button"}});f.add(g),b.exports=g,_.extendProto(g,{disable:c,isDisabled:d})},{"../c_class":16,"../c_registry":33}],43:[function(a,b){"use strict";function c(){k.prototype.init.apply(this,arguments),this.on("childrenbound",d)}function d(){m.defineProperties(this,{_comboInput:this.container.scope.input,_comboList:this.container.scope.datalist}),this._comboList.template.set(o),this._comboInput.data.on("input",{subscriber:i,context:this})}function e(){return this._comboInput?this._comboInput.data.get():void 0}function f(a){return h.call(this,"set",a)}function g(){return h.call(this,"del",value)}function h(a,b){if(this._comboInput){var c=this._comboInput.data[a](b);return i.call(this),c}}function i(){this.data.dispatchSourceMessage(n)}function j(){this._comboList.template.render({comboOptions:this.model.get()})}var k=a("../c_class"),l=a("../c_registry"),m=a("mol-proto"),n="mlcombochange",o='{{~ it.comboOptions :option }} {{~}}',p=k.createComponentClass("MLCombo",{events:void 0,data:{get:e,set:f,del:g,splice:void 0,event:n},model:{messages:{"***":{subscriber:j,context:"owner"}}},dom:{cls:"ml-ui-datalist"},container:void 0});l.add(p),b.exports=p,m.extendProto(p,{init:c})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],44:[function(a,b){"use strict";function c(){r.prototype.init.apply(this,arguments),this._dataValidation=function(){},this.model.set([]),this.once("childrenbound",j)}function d(a){"function"==typeof a&&(this._dataValidation=a)}function e(a){this._combo.setOptions(a)}function f(){this._combo.clearComboInput() +}function g(a){this._combo.toggleAddButton(a)}function h(a){this._combo.setAddItemPrompt(a)}function i(){r.prototype.destroy.apply(this,arguments),this._connector&&milo.minder.destroyConnector(this._connector),this._connector=null}function j(){this.template.render().binder(),k.call(this)}function k(){t.defineProperties(this,{_combo:this.container.scope.combo,_list:this.container.scope.list}),this._connector=milo.minder(this._list.model,"<<<->>>",this.model),this._combo.data.on("",{subscriber:l,context:this}),this._combo.on("additem",{subscriber:q,context:this})}function l(a,b){b.newValue&&this._dataValidation(a,b,this._list.model.get())&&this._list.model.push(b.newValue),this._combo.data.del(),this._combo.data._value=""}function m(){this.data.dispatchSourceMessage(u)}function n(){var a=this.model.get();return"object"==typeof a?t.clone(a):a}function o(a){this.model.set(a)}function p(){return this.model.set([])}function q(a,b){this.postMessage("additem",b),this.events.postMessage("milo_combolistadditem",b)}var r=a("../c_class"),s=a("../c_registry"),t=a("mol-proto"),u="mlcombolistchange",v=r.createComponentClass("MLComboList",{dom:{cls:"ml-ui-combo-list"},data:{get:n,set:o,del:p,event:u},events:void 0,container:void 0,model:{messages:{"***":{subscriber:m,context:"owner"}}},template:{template:'
'}});s.add(v),b.exports=v,t.extendProto(v,{init:c,setOptions:e,setDataValidation:d,toggleAddButton:g,destroy:i,setAddItemPrompt:h,clearComboInput:f})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],45:[function(a,b){"use strict";function c(){return n.date(this.el.min)}function d(a){var b=n.toDate(a);this.el.min=b?k(b):""}function e(){return n.date(this.el.max)}function f(a){var b=n.toDate(a);this.el.max=b?k(b):""}function g(){return n.toDate(this.el.value)}function h(a){var b=n.toDate(a);this.el.value=b?k(b):"",j.call(this)}function i(){this.el.value="",j.call(this)}function j(){this.data.dispatchSourceMessage("input")}function k(a){function b(a){return 10>a?"0"+a:a}var c=[a.getFullYear(),b(a.getMonth()+1),b(a.getDate())],d=c.join("-");return d}var l=a("../c_class"),m=a("../c_registry"),n=a("mol-proto"),o=l.createComponentClass("MLDate",{events:void 0,data:{get:g,set:h,del:i},dom:{cls:"ml-ui-date"}});n.extendProto(o,{getMin:c,setMin:d,getMax:e,setMax:f}),m.add(o),b.exports=o},{"../c_class":16,"../c_registry":33,"mol-proto":150}],46:[function(a,b){"use strict";var c=a("../c_class"),d=a("../c_registry"),e=c.createComponentClass("MLDropTarget",["drop"]);d.add(e),b.exports=e},{"../c_class":16,"../c_registry":33}],47:[function(a,b){"use strict";function c(a){a.classList.toggle("ml-ui-foldtree--unfold")}function d(a,b){var c=b.getAttribute("data-item-id"),d=this._itemsMap[c];this.postMessage("mlfoldtree_"+a,{item:d,el:b})}function e(a,b){var e=b.target;if(e.classList.contains("ml-ui-foldtree-button"))c(e.parentNode.parentNode);else{if(!e.classList.contains("ml-ui-foldtree-label"))return;d.call(this,a,e)}b.stopPropagation()}function f(a){this._itemTemplate=h.compile(a)}function g(a){function b(a){if(a.items)var d=_.map(a.items,function(a){var b=k();return c._itemsMap[b]=a,b});return n({itemIDs:d,data:a,itemTemplate:c._itemTemplate||m,treeTemplate:b})}var c=this;this._data=a,c._itemsMap={},this.el.innerHTML=b(a)}var h=a("dot"),i=a("../c_registry"),j=a("../c_class"),k=a("../../util/count"),l='
    {{~ it.data.items :item:index }} {{ var hasSubTree = item.items && item.items.length; }}
  • {{? hasSubTree }}
    {{?}} {{= it.itemTemplate({ item: item, id: it.itemIDs[index] }) }}
    {{? hasSubTree }} {{= it.treeTemplate(item) }} {{?}}
  • {{~}}
',m=h.compile(' {{= it.item.label }} '),n=h.compile(l),o=j.createComponentClass("MLFoldTree",{container:void 0,events:{messages:{"click dblclick":{subscriber:e,context:"owner"}}},dom:{cls:"ml-ui-foldtree-main"}});i.add(o),b.exports=o,_.extendProto(o,{setItemTemplate:f,renderTree:g})},{"../../util/count":92,"../c_class":16,"../c_registry":33,dot:115}],48:[function(a,b){"use strict";var c=a("../c_class"),d=a("../c_registry"),e=c.createComponentClass("MLGroup",{container:void 0,data:void 0,events:void 0,dom:{cls:"ml-ui-group"}});d.add(e),b.exports=e},{"../c_class":16,"../c_registry":33}],49:[function(a,b){"use strict";var c=a("../c_class"),d=a("../c_registry"),e=c.createComponentClass("MLHyperlink",{events:void 0,data:void 0,dom:{cls:"ml-ui-hyperlink"}});d.add(e),b.exports=e},{"../c_class":16,"../c_registry":33}],50:[function(a,b){"use strict";function c(){i.prototype.init.apply(this,arguments)}function d(a){return this.model.set(a),a}function e(){var a=this.model.get();return a&&"object"==typeof a?k.clone(a):a}function f(){this.model.del()}function g(){this.data.dispatchSourceMessage(l)}function h(a,b){this.el.src=b.newValue,g.call(this)}var i=a("../c_class"),j=a("../c_registry"),k=a("mol-proto"),l="mlimagechange",m=i.createComponentClass("MLImage",{data:{set:d,get:e,del:f,splice:void 0,event:l},model:{messages:{".src":{subscriber:h,context:"owner"}}},events:void 0,container:void 0,dom:{tagName:"img",cls:"ml-ui-image"}});j.add(m),b.exports=m,k.extendProto(m,{init:c})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],51:[function(a,b){"use strict";function c(a){this.el.disabled=a}function d(){return!!this.el.disabled}function e(a){this.el.setAttribute("maxlength",a)}var f=a("../c_class"),g=a("../c_registry"),h=a("mol-proto"),i=f.createComponentClass("MLInput",{data:void 0,events:void 0,dom:{cls:"ml-ui-input"}});g.add(i),b.exports=i,h.extendProto(i,{disable:c,isDisabled:d,setMaxLength:e})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],52:[function(a,b){"use strict";function c(){p.prototype.init.apply(this,arguments),this.once("childrenbound",d),this.model.set([])}function d(){h.call(this)}function e(a){this._input.el.setAttribute("placeHolder",a)}function f(a){t=a||t}function g(){p.prototype.destroy.apply(this,arguments),this._connector&&milo.minder.destroyConnector(this._connector),this._connector=null}function h(){this.template.render().binder(),i.call(this)}function i(){r.defineProperties(this,{_input:this.container.scope.input,_button:this.container.scope.button,_list:this.container.scope.list}),this._connector=milo.minder(this._list.model,"<<<->>>",this.model),this._button.events.on("click",{subscriber:j,context:this})}function j(){var a=this._input.data.get(0);this._input.data&&t(a,function(a,b){this._list.model.push({label:a,value:b})}.bind(this)),this._input.data.del()}function k(){this.data.dispatchSourceMessage(s)}function l(){var a=this.model.get();return a?r.clone(a):void 0}function m(a){this.model.set(a)}function n(){return this.model.set([])}function o(){this.model.splice.apply(this.model,arguments)}var p=a("../c_class"),q=a("../c_registry"),r=a("mol-proto"),s="mlinputlistchange",t=function(a,b){b(a)},u=p.createComponentClass("MLInputList",{dom:{cls:"ml-ui-input-list"},data:{get:l,set:m,del:n,splice:o,event:s},events:void 0,container:void 0,model:{messages:{"***":{subscriber:k,context:"owner"}}},template:{template:'
'}});q.add(u),b.exports=u,r.extendProto(u,{init:c,setAsync:f,setPlaceHolder:e,destroy:g})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],53:[function(a,b){"use strict";function c(){h.prototype.init.apply(this,arguments),this.on("childrenbound",g)}function d(){this._connector&&milo.minder.destroyConnector(this._connector),this._connector=null,h.prototype.destroy.apply(this,arguments)}function e(a){this.model.splice(a,1)}function f(a,b){var c=this.model.splice(a,1);return this.model.splice(b,0,c[0])}function g(){this.model.set([]),this._connector=milo.minder(this.model,"<<<-",this.data).deferChangeMode("<<<->>>")}var h=a("../c_class"),i=a("../c_registry"),j=a("mol-proto"),k=h.createComponentClass("MLList",{dom:{cls:"ml-ui-list"},data:void 0,events:void 0,model:void 0,list:void 0});i.add(k),b.exports=k,j.extendProto(k,{init:c,destroy:d,removeItem:e,moveItem:f})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],54:[function(a,b){"use strict";function c(){q.prototype.init.apply(this,arguments),this.on("childrenbound",d)}function d(){var a=this.container.scope.deleteBtn;a&&a.events.on("click",{subscriber:this.removeItem,context:this})}function e(){try{var a=this.item.list.owner}catch(b){}a&&a.removeItem(this.item.index)}function f(a){var b=this.item.list.owner;b&&b.moveItem(this.item.index,a)}function g(a){return a.params&&a.params.index&&"MLListItem"==a.compClass}function h(){return this.isDropAllowed.apply(this,arguments)}function i(a,b){k.call(this);var c=new r(b),d=c.getComponentMeta(),e=c.getComponentState(),f=this.item.list.owner,g=d.params&&d.params.index;f.moveItem(+g,this.item.index,e)}function j(){this.dom.addCssClasses("ml-drag-over")}function k(){this.dom.removeCssClasses("ml-drag-over")}function l(){return{index:this.item.index}}function m(){var a=this.model.get();return null!==a&&"object"==typeof a?t.clone(a):a}function n(a){return"object"==typeof a&&this.data._set(a),this.model.set(a),p.call(this),a}function o(){this.data._del(),this.model.del(),p.call(this)}function p(){this.data.dispatchSourceMessage(u)}var q=a("../c_class"),r=a("../../util/dragdrop"),s=a("../c_registry"),t=a("mol-proto"),u="mllistitemchange",v=q.createComponentClass("MLListItem",{container:void 0,dom:void 0,drag:{meta:{params:l}},drop:{messages:{dragenter:{subscriber:j,context:"owner"},dragover:{subscriber:j,context:"owner"},dragleave:{subscriber:k,context:"owner"},drop:{subscriber:i,context:"owner"}},allow:{components:h}},data:{get:m,set:n,del:o,event:u},model:void 0,item:void 0});s.add(v);var v=b.exports=v;t.extendProto(v,{init:c,moveItem:f,removeItem:e,isDropAllowed:g})},{"../../util/dragdrop":97,"../c_class":16,"../c_registry":33,"mol-proto":150}],55:[function(a,b){"use strict";function c(){o.defineProperty(this,"_radioList",[],o.CONF),o.defineProperty(this,q,r+n()),this._renderOptions={},l.prototype.init.apply(this,arguments)}function d(a){this._renderOptions=a}function e(a){var b,c=this._radioList;return c.length?(c.forEach(function(c){c.checked=c.value==a,c.checked&&(b=a)}),i.call(this),b):void 0}function f(){var a=o.find(this._radioList,function(a){return a.checked});return a&&a.value||void 0}function g(){var a=this._radioList;return a.length&&a.forEach(function(a){a.checked=!1}),void i.call(this)}function h(a,b){"radio"==b.target.type&&i.call(this)}function i(){this.data.dispatchSourceMessage(p)}function j(){this.template.render({radioOptions:this.model.get(),elementName:this[q],_renderOptions:this._renderOptions});var a=this.el.querySelectorAll('input[type="radio"]'),b=o.toArray(a);this._radioList.length=0,this._radioList.splice.apply(this._radioList,[0,0].concat(b))}function k(){delete this._radioList,l.prototype.destroy.apply(this,arguments)}var l=a("../c_class"),m=a("../c_registry"),n=a("../../util/count"),o=a("mol-proto"),p="mlradiogroupchange",q="_mlRadioGroupElementID",r="ml-radio-group-",s=l.createComponentClass("MLRadioGroup",{data:{set:e,get:f,del:g,splice:void 0,event:p},model:{messages:{"***":{subscriber:j,context:"owner"}}},events:{messages:{click:{subscriber:h,context:"owner"}}},container:void 0,dom:{cls:"ml-ui-radio-group"},template:{template:'{{~ it.radioOptions :option }} {{##def.elID:{{= it.elementName }}-{{= option.value }}#}} {{~}}'}});m.add(s),b.exports=s,o.extendProto(s,{init:c,destroy:k,setRenderOptions:d})},{"../../util/count":92,"../c_class":16,"../c_registry":33,"mol-proto":150}],56:[function(a,b){"use strict";function c(a){var b={context:this,subscriber:e};this.model.off("**",b),this.model.set(a),this.model.on("**",b),e.call(this)}function d(a){this.el.disabled=a}function e(){this.template.render({selectOptions:this.model.get()})}var f=a("../c_class"),g=a("../c_registry"),h=a("mol-proto"),i=f.createComponentClass("MLSelect",{dom:{cls:"ml-ui-select"},data:void 0,events:void 0,model:{messages:{"**":{subscriber:e,context:"owner"}}},template:{template:'{{~ it.selectOptions :option }} {{~}}'}});g.add(i),b.exports=i,h.extendProto(i,{setOptions:c,disable:d})},{"../c_class":16,"../c_registry":33,"mol-proto":150}],57:[function(a,b){"use strict";function c(){K.prototype.init.apply(this,arguments),this.once("childrenbound",d),M.defineProperties(this,{_optionsData:[],_filteredOptionsData:[]},M.WRIT)}function d(){this.template.render().binder(),e.call(this)}function e(){var a=this.container.scope;M.defineProperties(this,{_comboInput:a.input,_comboList:a.list,_comboOptions:a.options,_comboBefore:a.before,_comboAfter:a.after,_comboAddItemDiv:a.addItemDiv,_comboAddPrompt:a.addPrompt,_comboAddBtn:a.addBtn,_optionTemplate:N.compile(R)}),M.defineProperties(this,{_startIndex:0,_endIndex:S,_hidden:!1,_elementHeight:U,_total:0,_optionsHeight:200,_lastScrollPos:0,_currentValue:null,_selected:null,_isAddButtonShown:!1},M.WRIT),this.dom.setStyles({position:"relative"}),p(this._comboList,this._comboOptions,this),q(this._comboInput,this),r(this._comboAddBtn,this),this.events.on("keydown",{subscriber:y,context:this})}function f(a){this._hidden=!a,this._comboList.dom.toggle(a)}function g(){this._hidden=!1,this.el.classList.add(P),this._comboList.dom.toggle(!0)}function h(){this._hidden=!0,this.el.classList.remove(P),this._comboList.dom.toggle(!1)}function i(a,b){this._comboAddItemDiv.dom.toggle(a),b&&b.preserveState&&(this.__showAddOnClick=this._isAddButtonShown),this._isAddButtonShown=a}function j(a){this._addItemPrompt=a,this._comboAddPrompt.el.innerHTML=a,this.toggleAddButton(!1)}function k(a){this._optionsData=a,this.setFilteredOptions(a)}function l(a){this._optionsURL=a.url,this._formatOptionsURL=a.formatOptions||function(a){return a}}function m(a){var b=this._optionsURL,c=this._comboInput.data.get();a=a||M.noop,milo.util.request.post(b,{name:c},function(b,d){if(b)return O.error('Can not search for "'+c+'"'),a(new Error("Request error"));var e=M.jsonParse(d);e?a(null,e):a(new Error("Data error"))})}function n(a){return a?(this._filteredOptionsData=a,this._total=a.length,void this.update()):O.error("setFilteredOptions: parameter is undefined")}function o(){var a=this._hidden,b=this._filteredOptionsData.slice(this._startIndex,this._endIndex);this._comboOptions.template.render({comboOptions:b}),this._elementHeight=this._elementHeight||U,a&&this.hideOptions();var c=this._startIndex*this._elementHeight,d=(this._total-this._endIndex)*this._elementHeight;this._comboBefore.el.style.height=c+"px",this._comboAfter.el.style.height=d>0?d+"px":"0px"}function p(a,b,c){c.toggleAddButton(!1),b.template.set(R),a.dom.setStyles({overflow:"scroll",height:c._optionsHeight+"px",width:"100%",position:"absolute",zIndex:10}),c.hideOptions(),a.events.onMessages({click:{subscriber:G,context:c},scroll:{subscriber:H,context:c}})}function q(a,b){a.events.once("focus",function(){a.data.on("",{subscriber:v,context:b}),a.events.on("click",{subscriber:D,context:b}),a.events.on("keydown",{subscriber:E,context:b})})}function r(a,b){a.events.on("click",{subscriber:F,context:b})}function s(){return this._currentValue}function t(a){this._currentValue=a,this._comboInput.data.set(a&&a.label),M.deferMethod(this,"hideOptions")}function u(){this._currentValue=null,this._comboInput.data.set("")}function v(a,b){var c=b.newValue&&b.newValue.trim();if(this._optionsURL){var d=this;m.call(this,function(a,b){if(!a&&b)try{var e=b.data.map(d._formatOptionsURL);d.setOptions(e),x.call(d,c,d._optionsData)}catch(f){O.error("Data error",f)}})}else{var e=w.call(this,c);x.call(this,c,e)}}function w(a){return this._optionsData.filter(function(b){if(delete b.selected,b.label){var c=b.label.toLowerCase();return 0==c.trim().toLowerCase().indexOf(a.toLowerCase())}})}function x(a,b){function c(b){return b.label.toLowerCase()===a.toLowerCase()}a?(b.length&&M.find(b,c)?this.toggleAddButton(!1,{preserveState:!0}):this._addItemPrompt&&this.toggleAddButton(this._optionsData.length>1||this._optionsURL),b.length?(this.showOptions(),b[0].selected=!0,this._selected=b[0]):this.hideOptions()):this.toggleAddButton(!1,{preserveState:!0}),this.setFilteredOptions(b),this._comboList.el.scrollTop=0}function y(a,b){var c=W[b.keyCode];c&&z.call(this,c)}function z(a){var b=this.el.querySelectorAll(".selected")[0],c=this._comboList.el.scrollTop,d=b?b.offsetTop:0,e=d-c;if(b){var f=I.call(this,b),g=this._filteredOptionsData[f],h=this._filteredOptionsData[f+a];h&&(delete g.selected,h.selected=!0,this._selected=h,this.update())}else this._filteredOptionsData[0]&&(this._filteredOptionsData[0].selected=!0,this.update());e>this._optionsHeight-2*this._elementHeight&&1===a&&(this._comboList.el.scrollTop+=this._elementHeight*a*5),ethis._lastScrollPos?"down":"up",e=this._comboOptions.el.lastElementChild,f=this._comboOptions.el.firstElementChild,g=e?e.offsetTop:0,h=f?f.offsetTop:0,i=g-c-this._optionsHeight+this._elementHeight,j=c-h,k=Math.floor(j/this._elementHeight),l=Math.floor(i/this._elementHeight),m=Math.floor(c/this._elementHeight)-T;("down"==d&&T>l||"up"==d&&T>k)&&(this._startIndex=m>0?m:0,this._endIndex=m+S,this._elementHeight=e.style.height,this.update()),this._lastScrollPos=c}function I(a){return Number(a.getAttribute("data-value"))+this._startIndex}function J(){delete this._selected.selected,this.hideOptions(),this.toggleAddButton(!1),this._comboInput.data.off("",{subscriber:v,context:this}),this.data.set(this._selected),this.data.dispatchSourceMessage(Q),this._comboInput.data.on("",{subscriber:v,context:this}),this._selected=null,this.setFilteredOptions(this._optionsData)}var K=a("../c_class"),L=a("../c_registry"),M=a("mol-proto"),N=a("dot"),O=a("../../util/logger"),P="ml-ui-supercombo-open",Q="mlsupercombochange",R='{{~ it.comboOptions :option:index }}
{{= option.label }}
{{~}}',S=100,T=25,U=20,V=K.createComponentClass("MLSuperCombo",{events:{messages:{mouseleave:{subscriber:B,context:"owner"},mouseover:{subscriber:A,context:"owner"}}},data:{get:s,set:t,del:u,splice:void 0,event:Q},dom:{cls:"ml-ui-supercombo"},template:{template:'
'},container:void 0});L.add(V),b.exports=V,M.extendProto(V,{init:c,showOptions:g,hideOptions:h,toggleOptions:f,setOptions:k,initOptionsURL:l,setFilteredOptions:n,update:o,toggleAddButton:i,setAddItemPrompt:j,clearComboInput:u});var W={40:1,38:-1}},{"../../util/logger":102,"../c_class":16,"../c_registry":33,dot:115,"mol-proto":150}],58:[function(a,b){"use strict";var c=a("../c_class"),d=a("../c_registry"),e=c.createComponentClass("MLText",{data:void 0,events:void 0,dom:{cls:"ml-ui-text"}});d.add(e),b.exports=e},{"../c_class":16,"../c_registry":33}],59:[function(a,b){"use strict";function c(a){return this._autoresize?l.warn("MLTextarea startAutoresize: autoresize is already on"):(this._autoresize=!0,this._autoresizeOptions=a,e.call(this),void d.call(this,"on"))}function d(a){this.events[a]("click",{subscriber:e,context:this}),this.data[a]("",{subscriber:e,context:this})}function e(){this.el.style.height=0;var a=this.el.scrollHeight,b=this._autoresizeOptions.minHeight,c=this._autoresizeOptions.maxHeight;a=a>=c?c:b>=a?b:a,this.el.style.height=a+"px"}function f(){return this._autoresize?(this._autoresize=!1,void d.call(this,"off")):l.warn("MLTextarea stopAutoresize: autoresize is not on")}function g(){return this._autoresize}function h(a){this.el.disabled=a}var i=a("../c_class"),j=a("../c_registry"),k=a("mol-proto"),l=a("../../util/logger"),m=i.createComponentClass("MLTextarea",{data:void 0,events:void 0,dom:{cls:"ml-ui-textarea"}});j.add(m),b.exports=m;k.extendProto(m,{startAutoresize:c,stopAutoresize:f,isAutoresized:g,disable:h})},{"../../util/logger":102,"../c_class":16,"../c_registry":33,"mol-proto":150}],60:[function(a,b){"use strict";function c(){var a=this.el.value,b=a.match(i);if(b){var c=b[1],d=b[2];if(!(c>23||d>59)){var e=new Date(1970,0,1,c,d);return _.toDate(e)}}}function d(a){function b(a){return 10>a?"0"+a:a}var c=_.toDate(a);if(!c)return void(this.el.value="");var d=j.replace("hh",b(c.getHours())).replace("mm",b(c.getMinutes()));return this.el.value=d,d}function e(){this.el.value=""}var f=a("../c_class"),g=a("../c_registry"),h=f.createComponentClass("MLTime",{events:void 0,data:{get:c,set:d,del:e},dom:{cls:"ml-ui-time"}});g.add(h),b.exports=h;var i=/^([0-9]{1,2})(?:\:|\.)([0-9]{1,2})$/,j="hh:mm"},{"../c_class":16,"../c_registry":33}],61:[function(a,b){"use strict";var c=a("../c_class"),d=a("../c_registry"),e=c.createComponentClass("MLWrapper",{container:void 0,data:void 0,events:void 0,dom:{cls:"ml-ui-wrapper"}});d.add(e),b.exports=e},{"../c_class":16,"../c_registry":33}],62:[function(a,b){"use strict";function c(a){l(a,{message:String,type:m.Optional(String),close:m.Optional(Boolean),timeout:m.Optional(Number)});var b=p.createOnElement();a=f(a);var c=o[a.type];b.dom.addCssClasses(c),b._alert={options:a,visible:!1},b.template.render(a).binder();var d=b.container.scope;if(a.close&&d.closeBtn.events.on("click",{subscriber:e,context:b}),a.timeout){setTimeout(function(){b._alert.visible&&b.closeAlert()},a.timeout)}return b}function d(a){var b=p.createAlert(a);return b.openAlert(),b}function e(){this.closeAlert()}function f(a){return a=n.clone(a),a.close="undefined"==typeof a.close||a.close===!0,a.timeout=Math.floor(a.timeout),a.type=a.type||"info",a}function g(){i.call(this,!0)}function h(){i.call(this,!1),this.destroy()}function i(a){a="undefined"==typeof a?!this._alert.visible:!!a;var b=a?"add":"remove",c=a?"appendChild":"removeChild";this._alert.visible=a,document.body[c](this.el),this.dom.toggle(a),this.el.setAttribute("aria-hidden",!a),this.el.classList[b]("in"),this.el[a?"focus":"blur"]()}var j=a("../../c_class"),k=a("../../c_registry"),l=(a("../../../util/component_name"),a("../../../util/logger"),a("../../../util/check")),m=l.Match,n=a("mol-proto"),o={success:"alert-success",warning:"alert-warning",info:"alert-info",danger:"alert-danger",fixed:"alert-fixed"},p=j.createComponentClass("MLAlert",{container:void 0,events:void 0,dom:{cls:["ml-bs-alert","alert","fade"],attributes:{role:"alert","aria-hidden":"true"}},template:{template:' {{? it.close }} {{?}} {{= it.message}}'}});k.add(p),b.exports=p,n.extend(p,{createAlert:c,openAlert:d}),n.extendProto(p,{openAlert:g,closeAlert:h})},{"../../../util/check":90,"../../../util/component_name":91,"../../../util/logger":102,"../../c_class":16,"../../c_registry":33,"mol-proto":150}],63:[function(a,b){"use strict";function c(a,b){u(a,{title:v.Optional(String),html:v.Optional(String),text:v.Optional(String),close:v.Optional(v.OneOf(Boolean,{backdrop:v.Optional(Boolean),keyboard:v.Optional(Boolean),button:v.Optional(Boolean)})),buttons:v.Optional([{name:v.Optional(String),type:String,label:String,close:v.Optional(Boolean),result:v.Optional(String),data:v.Optional(v.Any),cls:v.Optional(String)}])});var c=z.createOnElement();a=i(a),c._dialog={options:a,visible:!1},c.template.render(a).binder();var e=c.container.scope;return a.close.backdrop&&c.events.on("click",{subscriber:f,context:c}),a.title&&a.close.button&&e.closeBtn.events.on("click",{subscriber:g,context:c}),a.buttons.forEach(function(a){var b={subscriber:w.partial(d,a),context:c};e[a.name].events.on("click",b)}),b&&b(c),c}function d(a){a.close!==!1&&k.call(this,!1);var b=w.result(a.data,this,a);e.call(this,a.result,b)}function e(a,b){var c=this._dialog.subscriber;"function"==typeof c?c.call(this,a,b):c.subscriber.call(c.context,a,b)}function f(a,b){b.target==this.el&&this.closeDialog("dismissed")}function g(){this.closeDialog("closed")}function h(a){C&&C._dialog.options.close.keyboard&&27==a.keyCode&&C.closeDialog("dismissed")}function i(a){return a=w.clone(a),a.buttons=w.clone(a.buttons||x),a.buttons.forEach(function(a){a.name=a.name||s()}),a.close="undefined"==typeof a.close||a.close===!0?w.object(y,!0):"object"==typeof a.close?w.mapToObject(y,function(b){return a.close[b]!==!1}):w.object(y,!1),a}function j(a,b,c){var d=z.createDialog(a,c);return d.openDialog(b),d}function k(a){a="undefined"==typeof a?!this._dialog.visible:!!a;var b=a?"add":"remove",c=a?"appendChild":"removeChild";this._dialog.visible=a,a&&!A&&l(),document.body[c](this.el),B&&document.body[c](B),this.dom.toggle(a),this.el.setAttribute("aria-hidden",!a),document.body.classList[b]("modal-open"),this.el.classList[b]("in"),C=a?this:void 0,this.el[a?"focus":"blur"]()}function l(){B=document.createElement("div"),B.className="modal-backdrop fade in",document.addEventListener("keydown",h),A=!0}function m(a){return u(a,v.OneOf(Function,{subscriber:Function,context:v.Any})),C?t.warn("MLDialog openDialog: can't open dialog, another dialog is already open"):(this._dialog.subscriber=a,void k.call(this,!0))}function n(a,b){return C?(a=a||"closed",k.call(this,!1),void e.call(this,a,b)):t.warn("MLDialog closeDialog: can't close dialog, no dialog open")}function o(){return C}function p(){document.removeEventListener("keydown",h),q.prototype.destroy.apply(this,arguments)}var q=a("../../c_class"),r=a("../../c_registry"),s=a("../../../util/component_name"),t=a("../../../util/logger"),u=a("../../../util/check"),v=u.Match,w=a("mol-proto"),x=[{type:"default",label:"OK",result:"OK"}],y=["backdrop","keyboard","button"],z=q.createComponentClass("MLDialog",{container:void 0,events:void 0,dom:{cls:["ml-bs-dialog","modal","fade"],attributes:{role:"dialog","aria-hidden":"true"}},template:{template:' '}});r.add(z),b.exports=z,w.extend(z,{createDialog:c,openDialog:j,getOpenedDialog:o}),w.extendProto(z,{openDialog:m,closeDialog:n,destroy:p});var A,B,C},{"../../../util/check":90,"../../../util/component_name":91,"../../../util/logger":102,"../../c_class":16,"../../c_registry":33,"mol-proto":150}],64:[function(a,b){"use strict";function c(){function a(a){var c=a.target,e=a.relatedTarget,f=i._dropdown.listeners;d(c)&&f.remove(c.contentWindow.document,"click",b),d(e)&&f.add(e.contentWindow.document,"click",b)}function b(a){i.el.contains(a.target)||i.hideMenu()}var c=this.el.querySelector("."+n),e=this.el.querySelector("."+o);if(!c||!e)return l.error("MLDropdown:",n,"or",o,"isn't found");var f=window.document,g=this.toggleMenu.bind(this,void 0),h=new m;this._dropdown={menu:e,visible:!1,listeners:h},this.hideMenu();var i=this;h.add(c,"click",g),h.add(f,"mouseout",a),h.add(f,"click",b)}function d(a){return a&&"IFRAME"==a.tagName}function e(){this._dropdown.listeners.removeAll(),delete this._dropdown,i.prototype.destroy.apply(this,arguments)}function f(){this.toggleMenu(!0)}function g(){this.toggleMenu(!1)}function h(a){a="undefined"==typeof a?!this._dropdown.visible:!!a,this._dropdown.visible=a;var b=this._dropdown.menu;b.style.display=a?"block":"none"}var i=a("../../c_class"),j=a("../../c_registry"),k=a("mol-proto"),l=a("../../../util/logger"),m=a("../../../util/dom_listeners"),n="dropdown-toggle",o="dropdown-menu",p=i.createComponentClass("MLDropdown",{events:void 0,dom:{cls:["ml-bs-dropdown","dropdown"]}}); +j.add(p),b.exports=p,k.extendProto(p,{start:c,destroy:e,toggleMenu:h,showMenu:f,hideMenu:g})},{"../../../util/dom_listeners":95,"../../../util/logger":102,"../../c_class":16,"../../c_registry":33,"mol-proto":150}],65:[function(a,b){"use strict";function c(a){d.deepExtend(c,a)}var d=a("mol-proto"),e=a("dot");b.exports=c,c({attrs:{bind:"ml-bind",load:"ml-load"},componentRef:"___milo_component",componentPrefix:"milo_",mixin:{instancePropertiesMap:"___mixin_instances"},template:{compile:e.compile},domStorage:{typeSuffix:":___milo_data_type",prefixSeparator:"/",root:"",messageKey:"___milo_message/",messageTimestamp:"___milo_timestamp",quotaExceeded:{throwError:!0,message:!1}},dragDrop:{dataTypes:{component:"x-application/milo/component",componentMetaTemplate:"x-application/milo/component-meta/%class/%name/%params",componentMetaRegex:/^x\-application\/milo\/component\-meta\/([a-z0-9]+)\/([a-z0-9]+)\/([a-z0-9]*)$/}},request:{jsonpTimeout:6e4,jsonpCallbackPrefix:"___milo_callback_",optionsKey:"___milo_options",defaults:{timeout:6e4}},websocket:{rpc:{timeout:15e3,responsePrefix:"response_"}},check:!0,debug:!1})},{dot:115,"mol-proto":150}],66:[function(a,b){"use strict";function c(a,b,c){milo(function(){d(a,b,c)})}function d(a,b,c){"function"==typeof a&&(c=a,a=void 0,b=!1),"function"==typeof b&&(c=b,b=!1),a=a||document.body,g.postMessage("loader",{state:"started"}),e(a,b,function(a){g.postMessage("loader",{state:"finished",views:a}),c(a)})}function e(a,b,c){var d=a.getAttribute(j.attrs.load)?[a]:a.querySelectorAll("["+j.attrs.load+"]"),e={},g=d.length,h=0;_.forEach(d,function(a){f(a,b,function(b){e[a.id]=b||a,h++,h==g&&c(e)})})}function f(a,b,c){if(i.children(a).length)throw new l("can't load html into element that is not empty");var d=new k(a);d.parse().validate(),h.get(d.loadUrl,function(e,f){return e?(e.message=e.message||"can't load file "+d.loadUrl,void c(e)):(a.innerHTML=f,b&&k.remove(a),void c(null))})}var g=a("./services/mail"),h=a("./util/request"),i=(a("./util/logger"),a("./util/dom")),j=a("./config"),k=a("./attributes/a_load"),l=a("./util/error").Loader;b.exports=c},{"./attributes/a_load":7,"./config":65,"./services/mail":84,"./util/dom":94,"./util/error":98,"./util/logger":102,"./util/request":104}],67:[function(a,b){"use strict";function c(a,b,c){c&&this._setMessageSource(c),d.call(this)}function d(){I.defineProperties(this,{_messageSubscribers:{},_patternMessageSubscribers:{}},I.CONF)}function e(){this.offAll();var a=this.getMessageSource();a&&a.destroy()}function f(a,b){return k.call(this,a,b)}function g(a,b){return k.call(this,a,b,{dispatchTimes:1})}function h(a,b){return k.call(this,a,b,{dispatchTimes:1,sync:!0})}function i(a,b){return k.call(this,a,b,{sync:!0})}function j(a,b){return k.call(this,a,b,{sync:!1})}function k(a,b,c){return J(a,K.OneOf(String,[String],RegExp)),J(b,K.OneOf(Function,{subscriber:Function,context:K.Any,options:K.Optional(Object)})),"function"==typeof b&&(b={subscriber:b,context:this._hostObject}),c&&(b.options=b.options||{},I.extend(b.options,c)),l.call(this,a,b)}function l(a,b){return I.defineProperty(b,"__messages",a),m.call(this,"_registerSubscriber",a,b)}function m(a,b,c){"string"==typeof b&&(b=b.split(M));var d=this._chooseSubscribersHash(b);if(b instanceof RegExp)return this[a](d,b,c);var e=!1;return b.forEach(function(b){var f=this[a](d,b,c);e=e||f},this),e}function n(a,b,c){if(!a[b]||!a[b].length){a[b]=[],b instanceof RegExp&&(a[b].pattern=b),this._messageSource&&this._messageSource.onSubscriberAdded(b);var d=!0}var e=a[b],f=d||-1==o.call(this,e,c);return f&&e.push(c),f}function o(a,b){return I.findIndex(a,function(a){return b.subscriber==a.subscriber&&b.context==a.context})}function p(a){J(a,K.ObjectHash(K.OneOf(Function,{subscriber:Function,context:K.Any})));var b=I.mapKeys(a,function(a,b){return this.on(b,a)},this);return b}function q(a,b){return J(a,K.OneOf(String,[String],RegExp)),J(b,K.Optional(K.OneOf(Function,{subscriber:Function,context:K.Any,options:K.Optional(Object)}))),r.call(this,a,b)}function r(a,b){return m.call(this,"_removeSubscriber",a,b)}function s(a,b,c){var d=a[b];if(!d||!d.length)return!1;if(c){"function"==typeof c&&(c={subscriber:c,context:this._hostObject});var e=o.call(this,d,c);if(-1==e)return!1;d.splice(e,1),d.length||this._removeAllSubscribers(a,b)}else this._removeAllSubscribers(a,b);return!0}function t(a,b){delete a[b],this._messageSource&&"string"==typeof b&&this._messageSource.onSubscriberRemoved(b)}function u(a){J(a,K.ObjectHash(K.Optional(K.OneOf(Function,{subscriber:Function,context:K.Any}))));var b=I.mapKeys(a,function(a,b){return this.off(b,a)},this);return b}function v(){w.call(this,this._patternMessageSubscribers),w.call(this,this._messageSubscribers)}function w(a){I.eachKey(a,function(b,c){this._removeAllSubscribers(a,c)},this)}function x(a,b,c,d){J(a,K.OneOf(String,RegExp)),J(c,K.Optional(Function));var e=this._chooseSubscribersHash(a),f=e[a];this._callSubscribers(a,b,c,f,d),"string"==typeof a&&this._callPatternSubscribers(a,b,c,f,d)}function y(a,b,c){this.postMessage(a,b,c,!0)}function z(a,b,c,d,e){I.eachKey(this._patternMessageSubscribers,function(f){var g=f.pattern;if(g.test(a)){if(d)var f=f.filter(function(a){var b=o.call(this,d,a);return-1==b});this._callSubscribers(a,b,c,f,e)}},this)}function A(a,b,c,d,e){d&&d.length&&(d=d.slice(),d.forEach(function(d){this._callSubscriber(d,a,b,c,e)},this))}function B(a,b,c,d,e){var f=a.options&&a.options.sync,g=e&&f!==!1||f,h=a.options&&a.options.dispatchTimes;if(h)if(1>=h){var i=a.__messages;this.off(i,a)}else h>1&&a.options.dispatchTimes--;g?a.subscriber.call(a.context,b,c,d):I.deferMethod(a.subscriber,"call",a.context,b,c,d)}function C(a,b){J(a,K.OneOf(String,RegExp));var c=this._chooseSubscribersHash(a),d=c[a]?[].concat(c[a]):[];return b!==!1&&"string"==typeof a&&I.eachKey(this._patternMessageSubscribers,function(b){var c=b.pattern;b&&b.length&&c.test(a)&&I.appendArray(d,b)}),d.length?d:void 0}function D(a){return a instanceof RegExp?this._patternMessageSubscribers:this._messageSubscribers}function E(a){J(a,H),I.defineProperty(this,"_messageSource",a),a.messenger=this}function F(){return this._messageSource}var G=a("../abstract/mixin"),H=a("./m_source"),I=a("mol-proto"),J=a("../util/check"),K=J.Match,L=(a("../util/error").Messenger,I.createSubclass(G,"Messenger")),M=L.messagesSplitRegExp=/\s*(?:\,|\s)\s*/;I.extendProto(L,{init:c,destroy:e,on:f,once:g,onceSync:h,onSync:i,onAsync:j,onMessage:f,off:q,offMessage:q,onMessages:p,offMessages:u,offAll:v,postMessage:x,postMessageSync:y,getSubscribers:C,getMessageSource:F,_chooseSubscribersHash:D,_registerSubscriber:n,_removeSubscriber:s,_removeAllSubscribers:t,_callPatternSubscribers:z,_callSubscribers:A,_callSubscriber:B,_setMessageSource:E}),L.defaultMethods={on:"on",onSync:"onSync",once:"once",onceSync:"onceSync",off:"off",onMessages:"onMessages",offMessages:"offMessages",postMessage:"postMessage",postMessageSync:"postMessageSync",getSubscribers:"getSubscribers"},b.exports=L,L.subscriptions=[]},{"../abstract/mixin":3,"../util/check":90,"../util/error":98,"./m_source":70,"mol-proto":150}],68:[function(a,b){"use strict";function c(){this.init&&this.init.apply(this,arguments)}function d(){l.defineProperty(this,"_internalMessages",{})}function e(){}function f(a){var b,c=this.translateToSourceMessage(a);if("undefined"!=typeof c)return this._internalMessages.hasOwnProperty(c)?(b=this._internalMessages[c],void(-1==b.indexOf(a)?b.push(a):m.warn("Duplicate addInternalMessage call for internal message "+a))):(b=this._internalMessages[c]=[],b.push(a),c)}function g(a){function b(){m.warn("notification received: un-subscribe from internal message "+a+" without previous subscription notification")}var c=this.translateToSourceMessage(a);if("undefined"!=typeof c){var d=this._internalMessages[c];if(d&&d.length){var e=d.indexOf(a);if(e>=0){if(d.splice(e,1),0==d.length)return delete this._internalMessages[c],c}else b()}else b()}}function h(a){return this._internalMessages[a]}function i(a){return a}function j(a,b,c){return c}function k(){return!0}var l=a("mol-proto"),m=a("../util/logger");b.exports=c,l.extendProto(c,{init:d,destroy:e,addInternalMessage:f,removeInternalMessage:g,getInternalMessages:h,translateToSourceMessage:i,createInternalData:j,filterSourceMessage:k})},{"../util/logger":102,"mol-proto":150}],69:[function(a,b){"use strict";function c(){g.prototype.init.apply(this,arguments),h.defineProperties(this,{_patternInternalMessages:{}}),this._catchAllSubscribed=!1}function d(){var a=g.prototype.addInternalMessage.apply(this,arguments);if(a&&a instanceof RegExp){if(this._internalMessages[a].pattern=a,this._patternInternalMessages[a]=this._internalMessages[a],this._catchAllSubscribed)return;return this._catchAllSubscribed=!0,/.*/}return a}function e(){var a=g.prototype.removeInternalMessage.apply(this,arguments);if(a&&a instanceof RegExp){delete this._patternInternalMessages[a];var b=!Object.keys(this._patternInternalMessages).length;if(b)return this._catchAllSubscribed=!1,/.*/}return a}function f(a){var b=g.prototype.getInternalMessages.apply(this,arguments);if("string"==typeof a){b=b||[];var c=h.object(b,!0);h.eachKey(this._patternInternalMessages,function(d){var e=d.pattern;e.test(a)&&d.forEach(function(a){c[a]||(b.push(a),c[a]=!0)})})}return b}var g=a("./m_api"),h=a("mol-proto"),i=h.createSubclass(g,"MessengerRegexpAPI");b.exports=i,h.extendProto(i,{init:c,addInternalMessage:d,removeInternalMessage:e,getInternalMessages:f})},{"./m_api":68,"mol-proto":150}],70:[function(a,b){"use strict";function c(a,b,c){this._prepareMessengerAPI(c)}function d(){this.messengerAPI&&this.messengerAPI.destroy()}function e(a){n.defineProperty(this,"messenger",a)}function f(a){o(a,p.Optional(l)),a||(a=new l),n.defineProperty(this,"messengerAPI",a)}function g(a){var b=this.messengerAPI.addInternalMessage(a);"undefined"!=typeof b&&this.addSourceSubscriber(b)}function h(a){var b=this.messengerAPI.removeInternalMessage(a);"undefined"!=typeof b&&this.removeSourceSubscriber(b)}function i(a,b){var c=this.messengerAPI,d=c.getInternalMessages(a);d&&d.forEach(function(d){var e=c.createInternalData(a,d,b),f=c.filterSourceMessage(a,d,e);f&&this.postMessage(d,e)},this)}function j(a,b){this.messenger.postMessage(a,b)}var k=a("../abstract/mixin"),l=a("./m_api"),m=(a("../util/logger"),a("../util/error").toBeImplemented),n=a("mol-proto"),o=a("../util/check"),p=o.Match,q=n.createSubclass(k,"MessageSource",!0);b.exports=q,n.extendProto(q,{init:c,destroy:d,setMessenger:e,onSubscriberAdded:g,onSubscriberRemoved:h,dispatchMessage:i,postMessage:j,_prepareMessengerAPI:f,trigger:m,addSourceSubscriber:m,removeSourceSubscriber:m})},{"../abstract/mixin":3,"../util/check":90,"../util/error":98,"../util/logger":102,"./m_api":68,"mol-proto":150}],71:[function(a,b){"use strict";function c(a,b,c,d){g.prototype.init.apply(this,arguments),this.sourceMessenger=d}function d(a){this.sourceMessenger.onSync(a,{context:this,subscriber:this.dispatchMessage})}function e(a){this.sourceMessenger.off(a,{context:this,subscriber:this.dispatchMessage})}function f(a,b){this.messenger.postMessageSync(a,b)}var g=a("./m_source"),h=a("mol-proto"),i=(a("../util/check"),h.createSubclass(g,"MessengerMessageSource"));b.exports=i,h.extendProto(i,{init:c,addSourceSubscriber:d,removeSourceSubscriber:e,postMessage:f})},{"../util/check":90,"./m_source":70,"mol-proto":150}],72:[function(a,b){"use strict";function c(a){c.util.domReady(a)}function d(){c.mail.destroy(),c.window.destroy(),c.minder.destroy(),c.util.destroy()}var e=a("milo-core"),f=a("mol-proto");a("./use_facets"),a("./use_components"),f.extend(c,{Messenger:e.Messenger,Model:e.Model,minder:e.minder,loader:a("./loader"),binder:a("./binder"),mail:a("./services/mail"),window:a("./services/window"),config:a("./config"),util:a("./util"),classes:a("./classes"),attributes:a("./attributes"),ComponentFacet:a("./components/c_facet"),Component:a("./components/c_class"),Command:a("./command"),registry:a("./registry"),milo_version:"0.1.4",createComponentClass:a("./util/create_component_class"),destroy:d}),"object"==typeof b&&b.exports&&(b.exports=c),"object"==typeof window&&(window.milo=c,c.mail.trigger("miloready"))},{"./attributes":8,"./binder":9,"./classes":10,"./command":13,"./components/c_class":16,"./components/c_facet":17,"./config":65,"./loader":66,"./registry":81,"./services/mail":84,"./services/window":87,"./use_components":88,"./use_facets":89,"./util":100,"./util/create_component_class":93,"milo-core":124,"mol-proto":150}],73:[function(a,b){"use strict";function c(a,b){r.defineProperty(a,"__inChangeTransaction",b,r.CONF|r.WRIT)}function d(a){var b=a.__inChangeTransaction;return delete a.__inChangeTransaction,b}function e(a,b){var e=d(a);return c(b,e),e}function f(){this.postMessageSync("datachanges",{transaction:!1,changes:[]})}function g(a,b,c){h.call(this,b.changes,c)}function h(a,b){i.call(this,b,!1),l.call(this,k(j(a))),i.call(this,b,!0)}function i(a,b){a&&a(null,b),this.postMessage(b?"changecompleted":"changestarted")}function j(a){var b=a[0].source,c=!0;if(a.length>1)for(var d=1,e=a.length;e>d;d++)a[d].source!=b&&(o.error("changedata: changes from different sources in the same transaction, sources:",a[d].source.name,b.name),c=!1,b=a[d].source);return a}function k(a){function b(a){("splice"==a.type?c:d)(a)}function c(a){var b=q.parseAccessPath(a.path),c=i.some(function(a){return b.length0&&(a=a.replace(/\$[1-9][0-9]*/g,function(a){return"$"+(+a.slice(1)+b)}));var d=this._path+a,e=[this._model,d].concat(this._args.slice(1)).concat(u.slice(arguments,1));return u.newApply(c,e)}function f(){return this.path(".length").get()||0}function g(){var a=this.len(),b=a+arguments.length;return u.splice(arguments,0,0,a,0),this.splice.apply(this,arguments),b}function h(){return this.splice(this.len()-1,1)[0]}function i(){var a=this.len();return a+=arguments.length,u.splice(arguments,0,0,0,0),this.splice.apply(this,arguments),a}function j(){return this.splice(0,1)[0]}function k(){var a=new s(this._accessPath),b=new t(this,void 0,a,this._model),c=new r(this,void 0,b);u.defineProperty(this,w,c)}function l(){return{model:this._model,path:this._path,args:this._args}}function m(a){v(a,{model:Function,path:String,args:Array});var b=a.model;return b.apply(b,a.args)}function n(){this[w].destroy()}{var o=a("./synthesize"),p=a("./path_utils"),q=a("./change_data"),r=a("../messenger"),s=a("./path_msg_api"),t=a("../messenger/msngr_source"),u=a("mol-proto"),v=a("../util/check");v.Match}b.exports=c,c.prototype.__proto__=c.__proto__,u.extendProto(c,{path:e,len:f,push:g,pop:h,unshift:i,shift:j,_prepareMessenger:k,_getDefinition:l,destroy:n}),u.extend(c,{_createFromDefinition:m});var w="_messenger";r.useWith(c,w,r.defaultMethods)},{"../messenger":67,"../messenger/msngr_source":71,"../util/check":90,"./change_data":73,"./path_msg_api":78,"./path_utils":79,"./synthesize":80,"mol-proto":150}],77:[function(a,b){"use strict";function c(a,b){return a>b?b:a>=0?a:a+b>0?a+b:0}var d={normalizeSpliceIndex:c};b.exports=d},{}],78:[function(a,b){"use strict";function c(a){g.prototype.init.apply(this,arguments),this.rootPath=a}function d(a){return a instanceof RegExp?a:"datachanges"==a?a:this.rootPath+a}function e(a,b,c){if("datachanges"==b){var d=c.changes.map(f,this).filter(function(a){return a}),e={changes:d,transaction:c.transaction};return e}var e=f.call(this,c);return e}function f(a){var b=a.path,c=h.unPrefix(b,this.rootPath);if("string"==typeof c){var a=h.clone(a);return a.fullPath=b,a.path=c,a}}var g=a("../messenger/m_api"),h=(a("./path_utils"),a("../util/logger"),a("mol-proto")),i=h.createSubclass(g,"ModelPathMsgAPI");b.exports=i,h.extendProto(i,{init:c,translateToSourceMessage:d,createInternalData:e})},{"../messenger/m_api":68,"../util/logger":102,"./path_utils":79,"mol-proto":150}],79:[function(a,b){"use strict";function c(a,b){b=b||u;var c=[];if(!a)return c;var d=a.replace(b,function(a){var b={property:a};return i.extend(b,x[a[0]]),"$"==a[1]&&(b.interpolate=e(b,!0)),c.push(b),""});if(d)throw new j("incorrect model path: "+a);return c}function d(a){if(g(a,h.OneOf(String,RegExp)),a instanceof RegExp||-1==a.indexOf("*"))return a;var b=k.parseAccessPath(a,w),c="^",d=!1;b.forEach(function(a){var b=a.property,e=y[b];e?(c+="("+e+"|)",d=!0):c+=b.replace(/(\.|\[|\])/g,"\\$1")}),c+="$";try{return new RegExp(c)}catch(e){throw new j("can't construct regex for path pattern: "+a)}}function e(a,b){var c=a.property,d=b?2:1;return"array"==a.syntax?c.slice(d,c.length-1):c.slice(d)}function f(a){a=a||["on","off"];var b=i.mapToObject(a,function(a){var b=this[a];return function(a,c){var e=d(a);b.call(this,e,c)}},this);i.defineProperties(this,b)}var g=a("../util/check"),h=g.Match,i=a("mol-proto"),j=a("../util/error").Model,k={parseAccessPath:c,createRegexPath:d,getPathNodeKey:e,wrapMessengerMethods:f};b.exports=k;var l="\\.[A-Za-z_-][A-Za-z0-9_-]*",m="\\[[0-9]+\\]",n="\\$[1-9][0-9]*",o="\\."+n,p="\\["+n+"\\]",q="\\.\\*",r="\\[\\*\\]",s="\\*",t=[l,m,o,p].join("|"),u=new RegExp(t,"g"),v=[t,q,r,s].join("|"),w=new RegExp(v,"g"),x={".":{syntax:"object",empty:"{}"},"[":{syntax:"array",empty:"[]"},"*":{syntax:"match",empty:"{}"}},y={".*":l,"[*]":m};y["*"]=y[".*"]+"|"+y["[*]"]},{"../util/check":90,"../util/error":98,"mol-proto":150}],80:[function(require,module,exports){"use strict";function _synthesizePathMethods(a,b){var c=_.mapKeys(synthesizers,function(c){return _synthesize(c,a,b)});return c}function _synthesize(synthesizer,path,parsedPath){function addChangeMessage(a,b,c){a.push(c),b[c.path]=c}function addTreeChangesMessages(a,b,c,d,e){var f=valueIsTree(d),g=valueIsTree(e);g&&addMessages(a,b,c,e,"added","newValue"),f&&addMessages(a,b,c,d,"removed","oldValue")}function addMessages(a,b,c,d,e,f){function g(a,b){if(Array.isArray(b)){var c=a+"[$$]";b.forEach(function(a,b){h(a,b,c)})}else{var c=a+".$$";_.eachKey(b,function(a,b){h(a,b,c)})}}function h(c,d,h){var i=h.replace("$$",d),j=b[i];if(j)j.type==e?logger.error("setter error: same message type posted on the same path"):(j.type="changed",j[f]=c);else{var k={path:i,type:e};k[f]=c,addChangeMessage(a,b,k)}valueIsTree(c)&&g(i,c)}g(c,d)}function cloneTree(a){return valueIsNormalObject(a)?_.deepClone(a):a}function protectValue(a){return valueIsNormalObject(a)?Array.isArray(a)?a.slice():Object.create(a):a}function valueIsTree(a){return valueIsNormalObject(a)&&Object.keys(a).length}function valueIsNormalObject(a){return!(null==a||"object"!=typeof a||a instanceof Date||a instanceof RegExp)}function addBatchIdsToMessage(a,b,c){_.defineProperties(a,{__batch_id:b,__msg_id:c})}var method,methodCode=synthesizer({parsedPath:parsedPath,getPathNodeKey:pathUtils.getPathNodeKey});try{eval(methodCode)}catch(e){throw ModelError("ModelPath method compilation error; path: "+path+", code: "+methodCode)}return method}var pathUtils=require("../path_utils"),modelUtils=require("../model_utils"),logger=require("../../util/logger"),miloCount=require("../../util/count"),fs=require("fs"),doT=require("dot"),_=require("mol-proto"),changeDataHandler=require("../change_data"),getTransactionFlag=changeDataHandler.getTransactionFlag,postTransactionFinished=changeDataHandler.postTransactionFinished,templates={get:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\nmethod = function get() {\n var m = {{# def.modelAccessPrefix }};\n return m {{~ it.parsedPath :pathNode }}\n {{? pathNode.interpolate}}\n && (m = m[this._args[ {{= pathNode.interpolate }} ]])\n {{??}}\n && (m = m{{= pathNode.property }})\n {{?}} {{~}};\n};\n",set:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n\n\n/**\n * Template that synthesizes setter for Model and for ModelPath\n */\nmethod = function set(value) {\n {{# def.initVars:'set' }}\n\n {{# def.createTree:'set' }}\n\n {{\n currNode = nextNode;\n currProp = currNode && currNode.property;\n }}\n\n {{ /* assign value to the last property */ }}\n {{? currProp }}\n wasDef = {{# def.wasDefined}};\n {{# def.changeAccessPath }}\n\n var old = m{{# def.currProp }};\n\n {{ /* clone value to prevent same reference in linked models */ }}\n m{{# def.currProp }} = cloneTree(value);\n {{?}}\n\n {{ /* add message related to the last property change */ }}\n if (this._options.reactive !== false) {\n if (! wasDef)\n {{# def.addMsg }} accessPath, type: 'added',\n newValue: value });\n else if (old != value)\n {{# def.addMsg }} accessPath, type: 'changed',\n oldValue: old, newValue: value });\n\n {{ /* add message related to changes in (sub)properties inside removed and assigned value */ }}\n if (! wasDef || old != value)\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, value); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n",del:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_traverse_tree }}\n\nmethod = function del() {\n {{# def.initVars:'del' }}\n\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n if (! treeDoesNotExist && m && m.hasOwnProperty && {{# def.wasDefined}}) {\n var old = m{{# def.currProp }};\n delete m{{# def.currProp }};\n {{# def.changeAccessPath }}\n var didDelete = true;\n }\n {{??}}\n if (typeof m != 'undefined') {\n var old = m;\n {{# def.modelAccessPrefix }} = undefined;\n var didDelete = true;\n }\n {{?}}\n\n if (didDelete && this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'deleted', oldValue: old });\n\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, undefined); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n",splice:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n{{# def.include_traverse_tree }}\n\nmethod = function splice(spliceIndex, spliceHowMany) { /* ,... - extra arguments to splice into array */\n {{# def.initVars:'splice' }}\n\n var argsLen = arguments.length;\n var addItems = argsLen > 2;\n\n if (addItems) {\n {{ /* only create model tree if items are inserted in array */ }}\n\n {{ /* if model is undefined it will be set to an empty array */ }} \n var value = [];\n {{# def.createTree:'splice' }}\n\n {{? nextNode }}\n {{\n var currNode = nextNode;\n var currProp = currNode.property;\n var emptyProp = '[]';\n }}\n\n {{# def.createTreeStep }}\n {{?}}\n\n } else if (spliceHowMany > 0) {\n {{ /* if items are not inserted, only traverse model tree if items are deleted from array */ }}\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n {{ /* extra brace closes 'else' in def.traverseTreeStep */ }}\n {{# def.traverseTreeStep }} }\n {{?}}\n }\n\n {{ /* splice items */ }}\n if (addItems || (! treeDoesNotExist && m\n && m.length > spliceIndex ) ) {\n var oldLength = m.length = m.length || 0;\n\n arguments[0] = spliceIndex = normalizeSpliceIndex(spliceIndex, m.length);\n\n {{ /* clone added arguments to prevent same references in linked models */ }}\n if (addItems)\n for (var i = 2; i < argsLen; i++)\n arguments[i] = cloneTree(arguments[i]);\n\n {{ /* actual splice call */ }}\n var removed = Array.prototype.splice.apply(m, arguments);\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'splice',\n index: spliceIndex, removed: removed, addedCount: addItems ? argsLen - 2 : 0,\n newValue: m });\n\n if (removed && removed.length)\n removed.forEach(function(item, index) {\n var itemPath = accessPath + '[' + (spliceIndex + index) + ']';\n {{# def.addMsg }} itemPath, type: 'removed', oldValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'removed', 'oldValue');\n });\n\n if (addItems)\n for (var i = 2; i < argsLen; i++) {\n var item = arguments[i];\n var itemPath = accessPath + '[' + (spliceIndex + i - 2) + ']';\n {{# def.addMsg }} itemPath, type: 'added', newValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'added', 'newValue');\n }\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n }\n\n return removed || [];\n}\n"},include_defines="'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts initialization code\n */\n {{## def.initVars:method:\n var m = {{# def.modelAccessPrefix }};\n var messages = [], messagesHash = {};\n var accessPath = '';\n var treeDoesNotExist;\n /* hack to prevent sending finished events to allow for propagation of batches without splitting them */\n var inChangeTransaction = getTransactionFlag( {{= method }} );\n #}}\n\n/**\n * Inserts the beginning of function call to add message to list\n */\n{{## def.addMsg: addChangeMessage(messages, messagesHash, { path: #}}\n\n/**\n * Inserts current property/index for both normal and interpolated properties/indexes\n */\n{{## def.currProp:{{? currNode.interpolate }}[this._args[ {{= currNode.interpolate }} ]]{{??}}{{= currProp }}{{?}} #}}\n\n/**\n * Inserts condition to test whether normal/interpolated property/index exists\n */\n{{## def.wasDefined: m.hasOwnProperty(\n {{? currNode.interpolate }}\n this._args[ {{= currNode.interpolate }} ]\n {{??}}\n '{{= it.getPathNodeKey(currNode) }}'\n {{?}}\n) #}}\n\n\n/**\n * Inserts code to update access path for current property\n * Because of the possibility of interpolated properties, it can't be calculated in template, it can only be calculated during accessor call.\n */\n{{## def.changeAccessPath:\n accessPath += {{? currNode.interpolate }}\n {{? currNode.syntax == 'array' }}\n '[' + this._args[ {{= currNode.interpolate }} ] + ']';\n {{??}}\n '.' + this._args[ {{= currNode.interpolate }} ];\n {{?}}\n {{??}}\n '{{= currProp }}';\n {{?}}\n#}}\n\n\n/**\n * Inserts code to post stored messages\n */\n{{## def.postMessages:\n if (messages.length) {\n {{# def.modelPostBatchCode }}('datachanges', {\n changes: messages,\n transaction: inChangeTransaction\n });\n\n messages.forEach(function(msg) {\n {{# def.modelPostMessageCode }}(msg.path, msg);\n }, this);\n }\n#}}\n",include_create_tree="'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to create model tree as neccessary for `set` and `splice` accessors and to add messages to send list if the tree changes.\n */\n{{## def.createTree:method:\n var wasDef = true;\n var old = m;\n\n {{ var emptyProp = it.parsedPath[0] && it.parsedPath[0].empty; }}\n {{? emptyProp }}\n {{ /* create top level model if it was not previously defined */ }}\n if (! m) {\n m = {{# def.modelAccessPrefix }} = {{= emptyProp }};\n wasDef = false;\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} '', type: 'added',\n newValue: m });\n }\n }\n {{??}}\n {{? method == 'splice' }}\n if (! m) {\n {{?}}\n m = {{# def.modelAccessPrefix }} = cloneTree(value);\n wasDef = typeof old != 'undefined';\n {{? method == 'splice' }}\n }\n {{?}} \n {{?}}\n\n\n {{ /* create model tree if it doesn't exist */ }}\n {{ var modelDataProperty = '';\n var nextNode = it.parsedPath[0];\n var count = it.parsedPath.length - 1;\n\n for (var i = 0; i < count; i++) {\n var currNode = nextNode;\n var currProp = currNode.property;\n nextNode = it.parsedPath[i + 1];\n var emptyProp = nextNode && nextNode.empty;\n }}\n\n {{# def.createTreeStep }}\n\n {{ } /* for loop */ }}\n#}}\n\n\n/**\n * Inserts code to create one step in the model tree\n */\n{{## def.createTreeStep:\n {{# def.changeAccessPath }}\n\n if (! {{# def.wasDefined }}) { \n {{ /* property does not exist */ }}\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'added', \n newValue: m });\n }\n\n } else if (typeof m{{# def.currProp }} != 'object') {\n {{ /* property is not object */ }}\n var old = m{{# def.currProp }};\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'changed', \n oldValue: old, newValue: m });\n }\n\n } else {\n {{ /* property exists, just traverse down the model tree */ }}\n m = m{{# def.currProp }};\n }\n#}}\n",include_traverse_tree="'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to traverse model tree for `delete` and `splice` accessors.\n */\n{{## def.traverseTree:\n {{ \n var count = it.parsedPath.length-1;\n\n for (var i = 0; i < count; i++) { \n var currNode = it.parsedPath[i];\n var currProp = currNode.property;\n }}\n {{# def.traverseTreeStep }}\n\n {{ } /* for loop */\n\n var i = count;\n while (i--) { /* closing braces for else's above */\n }}\n }\n {{ } /* while loop */ }}\n#}}\n\n\n/**\n * Inserts code to traverse one step in the model tree\n */\n{{## def.traverseTreeStep:\n if (! (m && m.hasOwnProperty && {{# def.wasDefined}} ) )\n treeDoesNotExist = true;\n else {\n m = m{{# def.currProp }};\n {{# def.changeAccessPath }}\n {{ /* brace from else is not closed on purpose - all braces are closed in while loop */ }}\n#}}\n",dotDef={include_defines:include_defines,include_create_tree:include_create_tree,include_traverse_tree:include_traverse_tree,getPathNodeKey:pathUtils.getPathNodeKey,modelAccessPrefix:"this._model._data",modelPostMessageCode:"this._model._internalMessenger.postMessage",modelPostBatchCode:"this._model.postMessageSync",internalMessenger:"this._model._internalMessenger"},modelDotDef=_(dotDef).clone().extend({modelAccessPrefix:"this._data",modelPostMessageCode:"this._internalMessenger.postMessage",modelPostBatchCode:"this.postMessageSync",internalMessenger:"this._internalMessenger"})._(),dotSettings=_.clone(doT.templateSettings); +dotSettings.strip=!1;var synthesizers=_.mapKeys(templates,function(a){return doT.template(a,dotSettings,dotDef)}),modelSynthesizers=_.mapToObject(["set","del","splice"],function(a){return doT.template(templates[a],dotSettings,modelDotDef)}),synthesizePathMethods=_.memoize(_synthesizePathMethods,void 0,1e3),normalizeSpliceIndex=modelUtils.normalizeSpliceIndex;module.exports=synthesizePathMethods;var modelMethods=_.mapKeys(modelSynthesizers,function(a){return _synthesize(a,"",[])});synthesizePathMethods.modelMethods=modelMethods},{"../../util/count":92,"../../util/logger":102,"../change_data":73,"../model_utils":77,"../path_utils":79,dot:115,fs:113,"mol-proto":150}],81:[function(a,b){"use strict";b.exports={facets:a("./components/c_facets/cf_registry"),components:a("./components/c_registry"),commands:a("./command/cmd_registry")}},{"./command/cmd_registry":12,"./components/c_facets/cf_registry":31,"./components/c_registry":33}],82:[function(a,b){"use strict";var c=a("mol-proto"),d={ClipboardEvent:["copy","cut","paste","beforecopy","beforecut","beforepaste"],Event:["input","readystatechange"],FocusEvent:["focus","blur","focusin","focusout"],KeyboardEvent:["keydown","keypress","keyup"],MouseEvent:["click","contextmenu","dblclick","mousedown","mouseup","mouseenter","mouseleave","mousemove","mouseout","mouseover","show"],TouchEvent:["touchstart","touchend","touchmove","touchenter","touchleave","touchcancel"]};if("undefined"!=typeof window)var e=window;else e={},c.eachKey(d,function(a,b){var d=c.makeFunction(b,"type","properties","this.type = type; _.extend(this, properties);");e[b]=d});var f={};c.eachKey(d,function(a,b){a.forEach(function(a){if(Object.hasOwnProperty(f,a))throw new Error("duplicate event type "+a);f[a]=e[b]})}),b.exports=f},{"mol-proto":150}],83:[function(a,b){"use strict";function c(a,b,c,d){this.eventEmitter=d,j.prototype.init.apply(this,arguments)}function d(){j.prototype.destroy.apply(this,arguments),delete this.eventEmitter}function e(){return this.eventEmitter}function f(a,b){if(b&&"string"==typeof b){var c=p.test(b);b=b.replace(p,""),this.emitter()[a](b,this,c)}}function g(a){var b;"undefined"!=typeof window&&(b=a.eventPhase==window.Event.CAPTURING_PHASE),b&&(a+=q),this.dispatchMessage(a.type,a)}function h(a,b){this.messenger.postMessageSync(a,b)}function i(a,b){m(a,String),m(b,n.Optional(Object)),a=a.replace(p,"");var c=k[a];if("function"!=typeof c)throw new Error("unsupported event type");"undefined"!=typeof b&&(b.type=a);var d=new c(a,b),e=this.emitter().dispatchEvent(d);return e}var j=a("../messenger/m_source"),k=(a("../components/c_class"),a("./de_constrs")),l=a("mol-proto"),m=a("../util/check"),n=m.Match,o=l.createSubclass(j,"DOMEmitterSource",!0);l.extendProto(o,{init:c,destroy:d,addSourceSubscriber:l.partial(f,"addEventListener"),removeSourceSubscriber:l.partial(f,"removeEventListener"),postMessage:h,trigger:i,emitter:e,handleEvent:g}),b.exports=o;var p=/__capture$/,q="__capture"},{"../components/c_class":16,"../messenger/m_source":70,"../util/check":90,"./de_constrs":82,"mol-proto":150}],84:[function(a,b){"use strict";var c=a("../../messenger"),d=a("./mail_api"),e=a("./mail_source"),f=(a("mol-proto"),new c),g=new e(f,{trigger:"trigger"},new d);f._setMessageSource(g),b.exports=f},{"../../messenger":67,"./mail_api":85,"./mail_source":86,"mol-proto":150}],85:[function(a,b){"use strict";function c(a){return"domready"==a?"readystatechange":i.test(a)?"message":void 0}function d(a,b,c){return"readystatechange"==a?!0:"message"==a?j+c.data.type==b:void 0}var e=a("../../messenger/m_api"),f=a("mol-proto"),g=a("../../util/check"),h=(g.Match,f.createSubclass(e,"MailMsgAPI",!0));f.extendProto(h,{translateToSourceMessage:c,filterSourceMessage:d}),b.exports=h;var i=/^message\:/,j="message:"},{"../../messenger/m_api":68,"../../util/check":90,"mol-proto":150}],86:[function(a,b){"use strict";function c(a){if(e(a))if("loading"==document.readyState)document.addEventListener("readystatechange",this,!1);else{var b=k.readystatechange,c=new b("readystatechange",{target:document});this.dispatchMessage("readystatechange",c)}else this._windowSubscriberMethod("addEventListener",a)}function d(a){e(a)?document.removeEventListener("readystatechange",this,!1):this._windowSubscriberMethod("removeEventListener",a)}function e(a){return"readystatechange"==a&&"object"==typeof document}function f(a){return"message"==a&&"object"==typeof window}function g(a,b){f(b)&&window[a]("message",this,!1)}function h(a){this.dispatchMessage(a.type,a)}function i(a,b){b=b||{},b.type="message:"+a,"object"==typeof window&&window.postMessage(b,"*")}var j=a("../../messenger/m_source"),k=a("../de_constrs"),l=(a("../../util/error").MailMessageSource,a("mol-proto")),m=a("../../util/check"),n=(m.Match,l.createSubclass(j,"MailMessageSource",!0));l.extendProto(n,{addSourceSubscriber:c,removeSourceSubscriber:d,trigger:i,_windowSubscriberMethod:g,handleEvent:h}),b.exports=n},{"../../messenger/m_source":70,"../../util/check":90,"../../util/error":98,"../de_constrs":82,"mol-proto":150}],87:[function(a,b){"use strict";function c(){return window.top==window.self||window.__karma__}var d=a("../messenger"),e=a("./dom_source"),f=new d,g=new e(f,{trigger:"trigger"},void 0,window);f._setMessageSource(g),b.exports=f,_.extend(f,{isTop:c})},{"../messenger":67,"./dom_source":83}],88:[function(a){"use strict";a("./components/classes/View"),a("./components/ui/Group"),a("./components/ui/Wrapper"),a("./components/ui/Text"),a("./components/ui/Select"),a("./components/ui/Input"),a("./components/ui/InputList"),a("./components/ui/Textarea"),a("./components/ui/RadioGroup"),a("./components/ui/Button"),a("./components/ui/Hyperlink"),a("./components/ui/List"),a("./components/ui/ListItem"),a("./components/ui/Time"),a("./components/ui/Date"),a("./components/ui/Combo"),a("./components/ui/SuperCombo"),a("./components/ui/ComboList"),a("./components/ui/Image"),a("./components/ui/DropTarget"),a("./components/ui/FoldTree"),a("./components/ui/bootstrap/Dropdown")},{"./components/classes/View":35,"./components/ui/Button":42,"./components/ui/Combo":43,"./components/ui/ComboList":44,"./components/ui/Date":45,"./components/ui/DropTarget":46,"./components/ui/FoldTree":47,"./components/ui/Group":48,"./components/ui/Hyperlink":49,"./components/ui/Image":50,"./components/ui/Input":51,"./components/ui/InputList":52,"./components/ui/List":53,"./components/ui/ListItem":54,"./components/ui/RadioGroup":55,"./components/ui/Select":56,"./components/ui/SuperCombo":57,"./components/ui/Text":58,"./components/ui/Textarea":59,"./components/ui/Time":60,"./components/ui/Wrapper":61,"./components/ui/bootstrap/Dropdown":64}],89:[function(a){"use strict";a("./components/c_facets/Dom"),a("./components/c_facets/Data"),a("./components/c_facets/Frame"),a("./components/c_facets/Events"),a("./components/c_facets/Options"),a("./components/c_facets/Template"),a("./components/c_facets/Container"),a("./components/c_facets/ModelFacet"),a("./components/c_facets/Drag"),a("./components/c_facets/Drop"),a("./components/c_facets/List"),a("./components/c_facets/Item"),a("./components/c_facets/Transfer")},{"./components/c_facets/Container":18,"./components/c_facets/Data":19,"./components/c_facets/Dom":20,"./components/c_facets/Drag":21,"./components/c_facets/Drop":22,"./components/c_facets/Events":23,"./components/c_facets/Frame":24,"./components/c_facets/Item":25,"./components/c_facets/List":26,"./components/c_facets/ModelFacet":27,"./components/c_facets/Options":28,"./components/c_facets/Template":29,"./components/c_facets/Transfer":30}],90:[function(a,b){"use strict";function c(a){this.pattern=a}function d(a){if(0==a.length)throw new Error("Must provide at least one choice to Match.OneOf");this.choices=a}function e(a){this.condition=a}function f(a){this.pattern=a}function g(a){this.pattern=a}function h(a,b){this.Superclass=a,this.matchSuperclass=b}function i(a,b){if(b!==n.Any){for(var l=0;lb?1:b>d?-1:0:void 0}function k(a,b,c,d){var e=a.ownerDocument;if(!e)return N("setCaretPosition: element has no document");var f,g,h=-1==j(a,b,c,d),i=e.createRange(),k=F(a),l=k.getSelection();h?(i.setStart(c,d),i.setEnd(a,b),i.collapse(!1)):(i.setStart(a,b),i.setEnd(c,d)),f=i.commonAncestorContainer==Node.ELEMENT_NODE?i.commonAncestorContainer:i.commonAncestorContainer.parentElement,f.isContentEditable||(g=f.contentEditable,f.contentEditable="true"),l.removeAllRanges(),l.addRange(i),h&&l.extend(c,d),g&&(f.contentEditable=g)}function l(a){a=a||window;var b=a.getSelection();b.removeAllRanges()}function m(a,b){var c,d;for(c=a.offsetTop,d=a.offsetLeft,a=a.offsetParent;a;)c+=a.offsetTop+n(a,"Height",b),d+=a.offsetLeft+n(a,"Width",b),a=a.offsetParent;return{topOffset:c,leftOffset:d}}function n(a,b,c){if(c){var d="Height"==b?"top":"left",e=window.getComputedStyle(a),f=parseInt(e.getPropertyValue("border-"+d+"-width"),10);if(f)return f}return 0}function o(a){var b=a.parentNode;b&&(b.removeChild(a),b.normalize())}function p(a){if(a.nodeType==Node.TEXT_NODE)return a;var b=E(a,NodeFilter.SHOW_TEXT);return b.firstChild()}function q(a){if(a.nodeType==Node.TEXT_NODE)return a;var b=E(a,NodeFilter.SHOW_TEXT);return b.lastChild()}function r(a){var b=a.parentNode;if(b){var c=document.createDocumentFragment(),d=M.slice(a.childNodes);d.forEach(c.appendChild,c),b.replaceChild(c,a),b.normalize()}}function s(a,b){var c=b.parentNode;c&&(c.insertBefore(a,b),a.appendChild(b))}function t(a){return v(a,"trimRight")}function u(a){return v(a,"trimLeft")}function v(a,b){var c=a.length;return a.textContent=a.textContent[b](),c!==a.length}function w(a){delete a[L.componentRef]}function x(a){var b=document.createElement("DIV");return b.innerHTML=a,b.textContent||""}function y(a,b,c,d){for(var e=document.createTreeWalker(a,b);e.nextNode();){var f=c.call(d||a,e.currentNode);if(f===!1)break}}function z(a,b){function c(a){return a.contains(b)}if(a&&a.contains(b)){for(var d=[],e=a;e!=b;){var f=M.findIndex(e.childNodes,c);d.push(f),e=e.childNodes[f]}return d}}function A(a,b,c){if(b){var d=b.length;if(0===d)return a;for(var e=a,f=0;d>f;f++){var g=e.childNodes;if(!g){c||(e=void 0);break}var h=b[f],i=g[h];if(!i){e=c?g[g.length-1]:void 0;break}e=i}return e}}function B(a,b,c,d){var e=c.nodeType==Node.TEXT_NODE;if(a.contains(c)&&o(c),0!=b.length){var f=A(a,b.slice(0,-1),d),g=f.childNodes;if(!g){if(!d)return;f=f.parentNode,g=f.childNodes}var h=b[b.length-1],i=g[h];return i?(f.insertBefore(c,i),e&&f.normalize(),!0):0!==g.length||0!==h&&!d?(i=g[h-1],i||d?(f.appendChild(c),e&&f.normalize(),!0):void 0):(f.appendChild(c),e&&f.normalize(),!0)}}function C(a,b){var c,d=0;if(!Array.isArray(a)&&Array.isArray(b))return N.error("isTreePathBefore: One or both paths are not valid treepath arrays.");for(d;db[d]){c=!1;break}}return"undefined"==typeof c&&a.length\&]/gim,function(a){return"&#"+a.charCodeAt(0)+";"})}function E(a,b){return b=b||NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT,document.createTreeWalker(a,b)}function F(a){var b=a.ownerDocument;return b&&(b.defaultView||b.parentWindow)}function G(a,b){function c(b){var c=document.createRange(),d=!1;return c.selectNode(b),-1!=c.compareBoundaryPoints(window.Range.START_TO_START,a)&&1!=c.compareBoundaryPoints(window.Range.END_TO_END,a)&&(d=!0),c.detach(),d}for(var d,e=a.commonAncestorContainer,f=e.ownerDocument,g=f.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);d=g.nextNode();)c(d)&&b(d)}function H(a){var b=F(a.startContainer),c=b.milo.Component,d=[];return G(a,function(a){if(a.nodeType!=Node.TEXT_NODE){var b=c.getComponent(a);b&&d.push(b)}}),d}function I(a){var b=H(a);b.forEach(function(a){a.destroy(!0)}),a.deleteContents()}function J(a,b){return 0==a.compareBoundaryPoints(window.Range.START_TO_START,b)&&0==a.compareBoundaryPoints(window.Range.END_TO_END,b)}function K(a,b){var c=document.createElement("div");c.setAttribute("style","width: 1px; height: 1px; position:fixed; left:"+a+"px; top:"+b+"px; background-color:red; z-index: 100"),setTimeout(function(){document.body.appendChild(c)},200)}var L=a("../config"),M=a("mol-proto"),N=a("./logger"),O={children:c,filterNodeListByType:d,containingElement:e,selectElementContents:f,selectElementText:g,getElementOffset:m,setCaretPosition:h,getSelectionDirection:i,setSelection:k,clearSelection:l,removeElement:o,unwrapElement:r,wrapInElement:s,detachComponent:w,firstTextNode:p,lastTextNode:q,trimNodeRight:t,trimNodeLeft:u,stripHtml:x,htmlEntities:D,walkTree:y,createTreeWalker:E,treePathOf:z,getNodeAtTreePath:A,insertAtTreePath:B,isTreePathBefore:C,getNodeWindow:F,getComponentsFromRange:H,deleteRangeWithComponents:I,forEachNodesInRange:G,areRangesEqual:J,addDebugPoint:K};b.exports=O},{"../config":65,"./logger":102,"mol-proto":150}],95:[function(a,b){"use strict";function c(){this.listeners=[]}function d(a,b,c){this.listeners.push({target:a,eventType:b,handler:c}),a.addEventListener(b,c)}function e(a,b,c){var d={target:a,eventType:b,handler:c},e=h.findIndex(this.listeners,h.partial(h.isEqual,d));e>-1&&(this.listeners.splice(e,1),g(d))}function f(){this.listeners.forEach(g),this.listeners=[]}function g(a){a.target.removeEventListener(a.eventType,a.handler)}{var h=a("mol-proto");a("./check")}b.exports=c,h.extendProto(c,{add:d,remove:e,removeAll:f})},{"./check":90,"mol-proto":150}],96:[function(a,b){"use strict";function c(a){function b(){a.apply(c,i)}var c=this,i=f.slice(arguments,1);e.call(this)?b():(h||(document.addEventListener("readystatechange",d),h=!0),g.push(b))}function d(){document.removeEventListener("readystatechange",d),g.forEach(function(a){a()})}function e(){var a=document.readyState;return"loading"==a?!1:a}var f=a("mol-proto");b.exports=c;var g=[],h=!1;f.extend(c,{isReady:e})},{"mol-proto":150}],97:[function(a,b){"use strict";function c(a){this.event=a,this.dataTransfer=a.dataTransfer,this.types=a.dataTransfer.types}function d(){return z.dataTypes.component}function e(){return C.indexOf(this.types,c.componentDataType())>=0}function f(){var a=c.componentDataType(),b=this.dataTransfer.getData(a),d=B(b);return d}function g(a,b){if(!b){var d=a.getTransferState({requestedBy:"drag"});b=JSON.stringify(d)}var e=c.componentDataType();return b&&this.dataTransfer.setData(e,b),this.dataTransfer.setData("text/html",a.el.outerHTML),b}function h(a,b,c){var d=j(a),e=C.toQueryString(b),f=z.dataTypes.componentMetaTemplate.replace("%class",i(d.compClass||"")).replace("%name",i(d.compName||"")).replace("%params",i(e||""));return c&&"object"==typeof c&&(c=JSON.stringify(c)),this.dataTransfer.setData(f,c||""),f}function i(a){return D.encode(a).toLowerCase()}function j(a){return a.transfer?a.transfer.getComponentMeta():{compClass:a.constructor.name,compName:a.name}}function k(){var a,b=C.find(this.types,function(b){return a=b.match(A),!!a});if(b){for(var c=1;4>c;c++)a[c]=D.decode(a[c]);return{compClass:a[1],compName:a[2],params:C.fromQueryString(a[3]),metaDataType:b,metaData:C.jsonParse(this.dataTransfer.getData(b))?C.jsonParse(this.dataTransfer.getData(b)):this.dataTransfer.getData(b)}}}function l(){return this.dataTransfer.effectAllowed}function m(a){this.dataTransfer.effectAllowed=a}function n(){return this.dataTransfer.dropEffect}function o(a){this.dataTransfer.dropEffect=a}function p(a){var b=this.getAllowedEffects(),c="copy"==a,d="move"==a,e="link"==a,f=c||e||d;switch(b){case"copy":case"move":case"link":return b==a;case"copyLink":return c||e;case"copyMove":return c||d;case"linkMove":return e||d;case"all":case"uninitialized":return f;case"none":return!1}}function q(a){return this.dataTransfer.getData(a)}function r(a,b){this.dataTransfer.setData(a,b)}function s(a){this.dataTransfer.clearData(a)}function t(a,b){E=b.dragDrop,F=b.dragFacet}function u(a,b){F&&F.postMessageSync("dragdropcompleted",b),E=void 0,F=void 0}function v(a,b){E&&G.postMessageSync("dragdropcompleted",b)}function w(){return E}function x(){G.offAll()}var y=(a("../components/c_class"),a("../messenger")),z=a("../config").dragDrop,A=z.dataTypes.componentMetaRegex,B=a("./json_parse"),C=a("mol-proto"),D=a("base32");b.exports=c,C.extend(c,{componentDataType:d}),C.extendProto(c,{isComponent:e,getComponentState:f,setComponentState:g,getComponentMeta:k,setComponentMeta:h,getAllowedEffects:l,setAllowedEffects:m,getDropEffect:n,setDropEffect:o,isEffectAllowed:p,getData:q,setData:r,clearData:s});var E,F,G=new y;C.extend(c,{service:G,destroy:x}),G.onMessages({dragdropstarted:t,dragdropcompleted:u,completedragdrop:v}),C.extend(G,{getCurrentDragDrop:w})},{"../components/c_class":16,"../config":65,"../messenger":67,"./json_parse":101,base32:112,"mol-proto":150}],98:[function(a,b){"use strict";function c(a){var b=e.makeFunction(a,"message",'this.name = "'+a+'"; this.message = message || "There was an error";');return e.makeSubclass(b,Error),b}function d(){throw new g.AbstractClass("calling the method of an absctract class")}var e=a("mol-proto"),f=["AbstractClass","Mixin","Messenger","Component","Attribute","Binder","Loader","MailMessageSource","Facet","Scope","Model","DomFacet","EditableFacet","List","Connector","Registry","FrameMessageSource","Drop","Angular","StorageMessageSource"],g={toBeImplemented:d,createClass:c};f.forEach(function(a){g[a]=c(a+"Error")}),b.exports=g},{"mol-proto":150}],99:[function(a,b){"use strict";function c(a,b,c){var d=f(a);if(!d)return void r.error("fragment.getState: range has no common container");var i=a.cloneContents(),j=e(i,c);g(d,j),b&&h(j);var k=j.getState();return s.deferMethod(j,"destroy"),k}function d(a,b,c){try{var d=f(a);if(!d)return void c(new Error("fragment.getState: range has no common container"));"function"==typeof b&&(c=b,b=!1);var i=a.cloneContents(),j=e(i);g(d,j),s.defer(function(){j.broadcast("stateready"),s.defer(function(){b&&h(j);var a=j.getState();j.destroy(),c(null,a)})})}catch(k){c(k)}}function e(a,b){var c=document.createElement("div"),d=new o(c);s.extend(d,{compClass:b||"Component",compFacets:b?[]:["container"],compName:"wrapper"}),d.decorate(),c.appendChild(a);var e=p(c);return e.wrapper}function f(a){var b=q.containingElement(a.commonAncestorContainer);return n.getContainingComponent(b,!0,"container")}function g(a,b){var c=a.container.scope;b.container.scope._each(function(a,b){var d=c[b];if(!d)return r.error("fragment.getState: conponent",b,"not found in range");var e=d._getState(!0);a.setState(e)})}function h(a){a.container.scope._each(function(a){a.rename()})}function i(a){var b=k(a);return a=j(b)}function j(a){var b=document.createRange();return a.siblings?(b.setStartBefore(a.start),b.setEndAfter(a.end)):b.selectNode(a.start),b}function k(a){var b=a.commonAncestorContainer,c=a.startContainer,d=a.endContainer;if(c==d)return c!=b&&r.error("deleteSelectionCommand logical error: start==end, but container is different"),{siblings:!1,start:c};if(c==b||d==b)return{siblings:!1,start:b};var e=l(b,c),f=l(b,d);return e&&f?e==f?(r.error("deleteSelectionCommand logical error: same siblings"),{siblings:!1,start:e}):{siblings:!0,start:e,end:f}:void 0}function l(a,b){return s.find(a.childNodes,function(a){return a.contains(b)})}function m(a){return function(b,c){var d={siblings:c.siblings,start:a(b,c.start)};return d.siblings&&(d.end=a(b,c.end)),d}}{var n=a("../components/c_class"),o=a("../attributes/a_bind"),p=a("../binder"),q=a("./dom"),r=a("./logger"),s=(a("./check"),a("mol-proto")),t=m(q.treePathOf),u=m(q.getNodeAtTreePath);b.exports={getState:c,getStateAsync:d,expandRangeToSiblings:i,getRangeSiblings:k,createRangeFromSiblings:j,createRangeFromNodes:j,createRangePaths:t,createRangeNodes:u}}},{"../attributes/a_bind":5,"../binder":9,"../components/c_class":16,"./check":90,"./dom":94,"./logger":102,"mol-proto":150}],100:[function(a,b){"use strict";function c(){d.request.destroy(),d.dragDrop.destroy()}var d={logger:a("./logger"),request:a("./request"),websocket:a("./websocket"),check:a("./check"),error:a("./error"),count:a("./count"),uniqueId:a("./count"),componentName:a("./component_name"),dom:a("./dom"),domListeners:a("./dom_listeners"),selection:a("./selection"),fragment:a("./fragment"),jsonParse:a("./json_parse"),storage:a("./storage"),domReady:a("./domready"),dragDrop:a("./dragdrop"),dialog:a("../components/ui/bootstrap/Dialog"),alert:a("../components/ui/bootstrap/Alert"),doT:a("dot"),destroy:c};b.exports=d},{"../components/ui/bootstrap/Alert":62,"../components/ui/bootstrap/Dialog":63,"./check":90,"./component_name":91,"./count":92,"./dom":94,"./dom_listeners":95,"./domready":96,"./dragdrop":97,"./error":98,"./fragment":99,"./json_parse":101,"./logger":102,"./request":104,"./selection":105,"./storage":106,"./websocket":109,dot:115}],101:[function(a,b){"use strict";function c(a){try{return JSON.parse(a)}catch(b){}}b.exports=c},{}],102:[function(a,b){"use strict";var c=a("./logger_class"),d=new c({level:3});b.exports=d},{"./logger_class":103}],103:[function(a,b){"use strict";function c(a){return a.lengththis.level)return this;var g=e.slice(arguments,1);if(b<=this.throwLevel)throw new Error([this.logPrefix,a+":"].concat(g).join(" "));return console.log.apply(console,[this.logPrefixColor?" "+d(this.logPrefix,this.logPrefixColor):this.logPrefix,(this.colors?" "+d(c(a),h[b]):a)+":"].concat(g)),this},f.forEach(function(a){j.prototype[a]=function(){this.log.apply(this,[a].concat(e.toArray(arguments)))}}),b.exports=j},{"mol-proto":150}],104:[function(a,b){"use strict";function c(a){return function(){var b=Promise.prototype[a].apply(this,arguments);return f(b,this._request),b}}function d(a,b,c){function f(a){h(i,c,j,a.type)}b.url=a,b.contentType=b.contentType||"application/json;charset=UTF-8",y&&d.postMessageSync("request",{options:b});var i=new XMLHttpRequest;i.open(b.method,b.url,!0),i.setRequestHeader("Content-Type",b.contentType),g(i,b.headers),i.timeout=b.timeout||s.request.defaults.timeout,i.onreadystatechange=i.ontimeout=i.onabort=f;var j=e(i);return i.send(JSON.stringify(b.data)),i[s.request.optionsKey]=b,v.push(i),j.promise}function e(a){var b,c,d=new Promise(function(a,d){b=a,c=d});return f(d,a),d["catch"](q.noop),{promise:d,resolve:b,reject:c}}function f(a,b){return a._request=b,a.then=w,a["catch"]=x,a}function g(a,b){b&&q.eachKey(b,function(b,c){a.setRequestHeader(c,b)})}function h(a,b,c,e){function f(b){y&&d.postMessage(b,{status:status,response:a.responseText})}if(4==a.readyState&&(a.status||"readystatechange"!=e)){q.spliceItem(v,a);var g;try{if(a.status>=200&&a.status<400){try{f("success"),b&&b(null,a.responseText,a)}catch(h){g=h}c.resolve(a.responseText)}else{var i=a.status||e;try{f("error"),f("error"+i),b&&b(i,a.responseText,a)}catch(h){g=h}c.reject({reason:i,response:a.responseText})}}catch(h){g=g||h}if(a.onreadystatechange=a.ontimeout=a.onabort=void 0,v.length||f("requestscompleted"),g)throw new Error("Exception: "+g)}}function i(){y=new u(d,["on","once","onSync","off","onMessages","offMessages","postMessage","postMessageSync"])}function j(a,b){return d(a,{method:"GET"},b)}function k(a,b,c){return d(a,{method:"POST",data:b},c)}function l(a,b){var c=d(a,{method:"GET"}),e=c.then(JSON.parse);return b&&e.then(function(a){b(null,a)})["catch"](function(a){b(a.reason,a.response)}),e}function m(a,b){function c(a,c){q.spliceItem(v,window[k]);try{g(a?"error":"success",a,c),a&&(t.error("No JSONP response or timeout"),g("errorjsonptimeout",a)),b&&b(a,c)}catch(d){var e=d}if(a?i.reject(a):i.resolve(c),f(),v.length||g("requestscompleted"),e)throw e}function f(){clearTimeout(m),j.removeChild(h),delete window[k]}function g(a,b,c){y&&d.postMessage(a,{status:b,response:c})}var h=document.createElement("script"),i=e(h),j=window.document.head,k=s.request.jsonpCallbackPrefix+r(),l=q.extend({url:a},z);y&&d.postMessageSync("request",{options:l}),q.isEqual(q.omitKeys(l,"url"),z)||t.warn("Ignored not allowed request options change in JSONP request - only URL can be changed");var m=setTimeout(function(){var a=new Error("No JSONP response or no callback in response");c(a)},s.request.jsonpTimeout);return window[k]=q.partial(c,null),v.push(window[k]),h.type="text/javascript",h.src=l.url+(-1==l.url.indexOf("?")?"?":"&")+"callback="+k,j.appendChild(h),i.promise}function n(a,b,c,f){function i(a){f&&(j.upload.onprogress=void 0),h(j,c,k,a.type)}"string"==typeof a&&(a={method:"POST",url:a}),a.method=a.method||"POST",a.file=!0,y&&d.postMessageSync("request",{options:a});var j=new XMLHttpRequest;f&&(j.upload.onprogress=f),j.open(a.method,a.url,!0),g(j,a.headers),j.timeout=a.timeout||s.request.defaults.timeout,j.onreadystatechange=j.ontimeout=j.onabort=i;var k=e(j);if(a.binary)j.send(b);else{var l=new FormData;l.append("file",b),j.send(l)}return v.push(j),k.promise}function o(){y&&y.destroy(),d._destroyed=!0}function p(a,b){a=q.once(a),b&&q.delay(a,b,"timeout"),v.length?y.once("requestscompleted",a):q.defer(a)}var q=a("mol-proto"),r=a("./count"),s=a("../config"),t=a("./logger"),u=a("../messenger");b.exports=d;var v=[],w=c("then"),x=c("catch");q.extend(d,{get:j,post:k,json:l,jsonp:m,file:n,useMessenger:i,destroy:o,whenRequestsCompleted:p});var y,z={method:"GET",jsonp:!0}},{"../config":65,"../messenger":67,"./count":92,"./logger":102,"mol-proto":150}],105:[function(a,b){"use strict";function c(a){return!this instanceof c?new c(a):(this.window=a||window,void this.init())}function d(){this.selection=this.window.getSelection(),this.selection.rangeCount&&(this.range=this.selection.getRangeAt(0)),this.isCollapsed=this.selection.isCollapsed}function e(){return this.range?(this._text||(this._text=this.range.toString()),this._text):void 0}function f(){return this.range?(this._textNodes||(this._textNodes=h.call(this)),this._textNodes):void 0}function g(){this.selection.removeAllRanges()}function h(){var a=[];if(this.isCollapsed)return a;for(var b=this.range.startContainer,c=this.range.endContainer,d=this.range.commonAncestorContainer,e=this.window.document.createTreeWalker(d,NodeFilter.SHOW_TEXT),f=e.currentNode=b;f&&(!g||c.contains(f));){a.push(f);var g=g||c.contains(f);f=e.nextNode()}return a}function i(a,b){return this.range?("undefined"==typeof this[a]&&(this[a]=z(this.range[b])),this[a]):void 0}function j(a,b){return this.range?("undefined"==typeof this[a]&&(this[a]=E.getContainingComponent(this[b]())),this[a]):void 0}function k(){if(this._containedComponents)return this._containedComponents; +var a=this._containedComponents=[];return this.isCollapsed||!this.range?a:B(this.range)}function l(a,b){if(!this.isCollapsed&&this.range){var c=this.containedComponents();c.forEach(a,b)}}function m(a){if(!this.isCollapsed&&this.range){var b=this._getPostDeleteSelectionPoint(a);C(this.range),this._selectAfterDelete(b),b.node.parentNode.normalize()}}function n(a){var b=this.range.startContainer,c=this.range.startOffset;return a&&this.range.startContainer!=this.range.endContainer&&(b=this.range.endContainer,c=0),{node:b,offset:c}}function o(a){var b=a.node,c=a.offset;if(b){b.nodeType==Node.TEXT_NODE&&(b.textContent=b.textContent.trimRight()),b.nodeValue||(b.nodeValue=" ");var d=c>b.length?b.length:c;A(b,d)}}function p(){return this.range}function q(a){var b=this.range,d=a.ownerDocument,e=d.defaultView||d.parentWindow;return b?c.createStateObject(a,b.startContainer,b.startOffset,b.endContainer,b.endOffset):{window:e}}function r(a,b,c,d,e){d=d||b,e=e||c;var f=a.ownerDocument,g=f.defaultView||f.parentWindow;return{window:g,rootEl:a,start:s(a,b,c),end:s(a,d,e)}}function s(a,b,c){var d=y.treePathOf(a,b);return d||D.error("Selection point is outside of root element"),{treePath:d,offset:c}}function t(a){var b=a.window.milo.util.dom;if(!(a.rootEl&&a.start&&a.end))return b.clearSelection(a.window),new c(a.window);var d=u(a.rootEl,a.start),e=u(a.rootEl,a.end);try{return b.setSelection(d,a.start.offset,e,a.end.offset),new c(a.window)}catch(f){D.error("Text selection: can't create selection",f,f.message)}}function u(a,b){var c=y.getNodeAtTreePath(a,b.treePath);return c||D.error("TextSelection createFromState: no node at treePath"),c}function v(a,b){var d,e=a.startContainer.ownerDocument.defaultView,f=e.getSelection();return f.removeAllRanges(),b?(d=a.cloneRange(),d.collapse(!1),f.addRange(d),f.extend(a.startContainer,a.startOffset)):f.addRange(a),new c(e)}function w(){var a,b,c=this.range.commonAncestorContainer.ownerDocument,d=this.range.cloneRange();return d.endContainer.nodeType!==Node.TEXT_NODE&&(a=c.createTreeWalker(c.body,NodeFilter.SHOW_TEXT),a.currentNode=d.endContainer,b=a.previousNode(),d.setEnd(b,b.length)),d}function x(){return y.getSelectionDirection(this.selection)}var y=a("../dom"),z=y.containingElement,A=y.setCaretPosition,B=y.getComponentsFromRange,C=y.deleteRangeWithComponents,D=a("../logger"),E=a("../../components/c_class"),F=a("mol-proto");b.exports=c;var G=F.partial(i,"_startElement","startContainer"),H=F.partial(i,"_endElement","endContainer"),I=F.partial(i,"_containingElement","commonAncestorContainer"),J=F.partial(j,"_startComponent","startElement"),K=F.partial(j,"_endComponent","endElement"),L=F.partial(j,"_containingComponent","containingElement");F.extendProto(c,{init:d,text:e,textNodes:f,clear:g,startElement:G,endElement:H,containingElement:I,startComponent:J,endComponent:K,containingComponent:L,containedComponents:k,eachContainedComponent:l,del:m,_getPostDeleteSelectionPoint:n,_selectAfterDelete:o,getRange:p,getState:q,getNormalizedRange:w,getDirection:x}),F.extend(c,{createFromRange:v,createFromState:t,createStateObject:r})},{"../../components/c_class":16,"../dom":94,"../logger":102,"mol-proto":150}],106:[function(a,b){"use strict";function c(a,b,c){"undefined"!=typeof window&&(c=c||window,a=A.domStorage.root+(a?a+A.domStorage.prefixSeparator:""),C.defineProperties(this,{keyPrefix:a,sessionOnly:!!b,window:c,_storage:b?c.sessionStorage:c.localStorage,_typeSuffix:A.domStorage.typeSuffix,_keys:{}},C.WRIT))}function d(a){if("object"==typeof a)C.eachKey(a,function(a,b){this.setItem(b,a)},this);else{var b=arguments.length;if(b%2)throw new DomStorageError("DOMStorage: set should have even number of arguments or object");for(var c=0;b>c;c++){var d=arguments[c],e=arguments[++c];this.setItem(d,e)}}}function e(){var a={};return C.deepForEach(arguments,function(b){a[b]=this.getItem(b)},this),a}function f(){C.deepForEach(arguments,function(a){this.removeItem(a)},this)}function g(a){var b=this._storageKey(a);return null!=this._storage.getItem(b)}function h(a){var b=this._storageKey(a),c=o.call(this,b),d=this._storage.getItem(b),e=u(d,c);return e}function i(a,b){var c=this._storageKey(a),d=p.call(this,c,b),e=t(b,d);try{this._storage.setItem(c,e)}catch(f){if("QuotaExceededError"!=f.name)throw f;var g=A.domStorage.quotaExceeded;if(g.message&&milo.mail.postMessage("quotaexceedederror",b),g.throwError)throw f}this._keys[a]=!0,H[this.sessionOnly]._keys[c]=!0}function j(a){var b=this._storageKey(a);this._storage.removeItem(b),q.call(this,b),delete this._keys[a],delete H[this.sessionOnly]._keys[b]}function k(){var a=Object.keys(this._keys),b=a.filter(function(a){return this.hasItem(a)?!0:void delete this._keys[a]},this);return b}function l(){return this.get(this.getAllKeys())}function m(a){return this.keyPrefix+a}function n(a){return a.indexOf(this._typeSuffix)>=0?void 0:C.unPrefix(a,this.keyPrefix)}function o(a){return a=r.call(this,a),this._storage.getItem(a)}function p(a,b){var c=s(b);return a=r.call(this,a),this._storage.setItem(a,c),c}function q(a){a=r.call(this,a),this._storage.removeItem(a)}function r(a){return a+this._typeSuffix}function s(a){var b=typeof a,c=a&&a.constructor.name,d=I[c];return d||("object"!=b?b:null==a?"null":a.constructor.name)}function t(a,b){b=b||s(a);var c=J[b];return c?c(a,b):a&&a.toString==Object.prototype.toString?JSON.stringify(a):""+a}function u(a,b){var c=K[b];return c?c(a,b):a}function v(a,b,c,d){b&&(J[a]=b),c&&(K[a]=c),I[a]=d||a}function w(){var a=new z(this),b=new y(this,void 0,a);C.defineProperties(this,{_messenger:b,_messageSource:a},C.WRIT)}function x(){this._storage=void 0,this.window=void 0,this._messenger&&this._messenger.destroy(),this._destroyed=!0}{var y=(a("../error").createClass("DomStorageError"),a("../../messenger")),z=a("./msg_src"),A=a("../../config"),B=a("../json_parse"),C=a("mol-proto"),D=a("../check");D.Match}a("./model"),b.exports=c;var E={"true":{},"false":{}};C.extendProto(c,{get:e,set:d,remove:f,hasItem:g,getItem:h,setItem:i,removeItem:j,_storageKey:m,_domStorageKey:n,getAllKeys:k,getAllItems:l,createMessenger:w,destroy:x}),y.useWith(c,"_messenger",y.defaultMethods),z.useWith(c,"_messageSource",["trigger"]);var F=new c("",!0),G=new c("",!1),H={"true":F,"false":G};C.extend(c,{registerDataType:v,local:G,session:F,storage:H,_storedKeys:E});var I={},J={Array:JSON.stringify},K={Object:B,Array:B,Date:function(a){return new Date(a)},"boolean":function(a){return"true"==a},number:function(a){return Number(a)},"function":function(a){return C.toFunction(a)},RegExp:function(a){return C.toRegExp(a)}}},{"../../config":65,"../../messenger":67,"../check":90,"../error":98,"../json_parse":101,"./model":107,"./msg_src":108,"mol-proto":150}],107:[function(a){"use strict";function b(){var b=a("./index");b.registerDataType("Model",c,d),b.registerDataType("ModelPath",c,d,"Model")}function c(a){var b=a.get();return JSON.stringify(b)}function d(a){var b=_.jsonParse(a);return new e(b)}var e=a("milo-core").Model;e.registerWithDOMStorage=b},{"./index":106,"milo-core":124}],108:[function(a,b){"use strict";function c(a){if("DOMStorage"!=a.constructor.name)throw new m("hostObject should be an instance of DOMStorage");this.storage=a,this.messageKey=k.domStorage.messageKey,this.window=a.window,i.prototype.init.apply(this,arguments)}function d(){this.window.addEventListener("storage",this,!1)}function e(){this.window.removeEventListener("storage",this,!1)}function f(a,b){this.messenger.postMessageSync(a,b)}function g(a,b){var c=this.messageKey+a;b=b||{},b[k.domStorage.messageTimestamp]=l(),j.deferMethod(this.storage,"setItem",c,b)}function h(a){if(a.storageArea==this.storage._storage){var b=this.storage._domStorageKey(a.key);if(b){var c=j.unPrefix(b,this.messageKey);if(c){var d=this.storage.getItem(b);d&&this.dispatchMessage(c,d)}}}}var i=a("../../messenger/m_source"),j=a("mol-proto"),k=a("../../config"),l=a("../../util/count"),m=a("../../util/error").StorageMessageSource,n=j.createSubclass(i,"StorageMessageSource",!0);j.extendProto(n,{init:c,addSourceSubscriber:d,removeSourceSubscriber:e,postMessage:f,trigger:g,handleEvent:h}),b.exports=n},{"../../config":65,"../../messenger/m_source":70,"../../util/count":92,"../../util/error":98,"mol-proto":150}],109:[function(a,b){"use strict";function c(){var a=new d,b=new e(a,{send:"trigger",connect:"connect"},new f);return a._setMessageSource(b),a}var d=a("../../messenger"),e=a("./msg_src"),f=a("./msg_api");b.exports=c},{"../../messenger":67,"./msg_api":110,"./msg_src":111}],110:[function(a,b){"use strict";function c(a){return j.indexOf(a)>=0?a:"message"}function d(a,b,c){if(j.indexOf(b)>=0)return!0;if("message"==a){var d=c&&c.type;return d==b}}function e(a,b,c){var d="message"==a?g.jsonParse(c.data)||c.data:c;return d}var f=a("../../messenger/m_api"),g=a("mol-proto"),h=a("../../util/check"),i=(h.Match,g.createSubclass(f,"WSMsgAPI",!0));g.extendProto(i,{translateToSourceMessage:c,filterSourceMessage:d,createInternalData:e}),b.exports=i;var j=["open","close","error","message"]},{"../../messenger/m_api":68,"../../util/check":90,"mol-proto":150}],111:[function(a,b){"use strict";function c(a){this._options=a=a||{};var b=a.host||window.location.host.replace(/:.*/,""),c=a.port||"8080";this._ws&&(this._ws.onopen=this.ws.onmessage=this.ws.onclose=this.ws.onerror=void 0,this._ws.close()),this._ws=new WebSocket("ws://"+b+":"+c)}function d(a){f.call(this,"addEventListener",a)}function e(a){f.call(this,"removeEventListener",a)}function f(a,b){return this._ws?void this._ws[a](b,this):k.error("websocket is not created")}function g(a){this.dispatchMessage(a.type,a)}function h(a,b,c){function d(){f("off",b.callbackCorrId),c(new Error("websocket rpc: timeout"))}function e(a,b){if(clearInterval(h),"object"==typeof b){var d=b.error?new Error(b.error):null;c(d,b.data)}else c(new Error("websocket rpc: invalid response data"),b)}function f(a,b){g.messenger[a](m.websocket.rpc.responsePrefix+b,e)}if(!this._ws)return k.error("websocket is not created");b=b||{},b.type=a;var g=this;if(c){b.callbackCorrId=l();var h=j.delay(d,m.websocket.rpc.timeout);f("once",b.callbackCorrId)}this._ws.send(JSON.stringify(b))}var i=a("../../messenger/m_source"),j=a("mol-proto"),k=a("../../util/logger"),l=a("../../util/count"),m=a("../../config"),n=a("../../util/check"),o=(n.Match,j.createSubclass(i,"WSMessageSource",!0));j.extendProto(o,{addSourceSubscriber:d,removeSourceSubscriber:e,handleEvent:g,connect:c,trigger:h}),b.exports=o},{"../../config":65,"../../messenger/m_source":70,"../../util/check":90,"../../util/count":92,"../../util/logger":102,"mol-proto":150}],112:[function(a,b){!function(){function a(){var a=0,b=0;this.output="",this.readByte=function(c){return"string"==typeof c&&(c=c.charCodeAt(0)),0>a?b|=c>>-a:b=c<3?(a-=8,1):(4>a&&(this.output+=f[b>>3],a+=5),0)},this.finish=function(c){var d=this.output+(0>a?f[b>>3]:"")+(c?"$":"");return this.output="",d}}function c(){var a=0,b=0;this.output="",this.readChar=function(c){"string"!=typeof c&&"number"==typeof c&&(c=String.fromCharCode(c)),c=c.toLowerCase();var d=h()[c];"undefined"!=typeof d&&(d<<=3,b|=d>>>a,a+=5,a>=8&&(this.output+=String.fromCharCode(b),a-=8,b=a>0?d<<5-a&255:0))},this.finish=function(b){var c=this.output+(0>a?f[bits>>3]:"")+(b?"$":"");return this.output="",c}}function d(b){var c=new a,d=c.update(b,!0);return d}function e(a){var b=new c,d=b.update(a,!0);return d}var f="0123456789abcdefghjkmnpqrtuvwxyz",g={o:0,i:1,l:1,s:5},h=function(){for(var a={},b=0;b":">",'"':""","'":"'","/":"/"},c=a?/[&<>"'\/]/g:/&(?!#?\w+;)|<|>|"|'|\//g;return function(a){return a?a.toString().replace(c,function(a){return b[a]||a}):""}},d=function(){return this||(0,eval)("this")}(),"undefined"!=typeof b&&b.exports?b.exports=e:"function"==typeof define&&define.amd?define(function(){return e}):d.doT=e;var f={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},g=/$^/;e.template=function(b,h,i){h=h||e.templateSettings;var j,k,l=h.append?f.append:f.split,m=0,n=h.use||h.define?a(h,b,i||{}):b;n=("var out='"+(h.strip?n.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):n).replace(/'|\\/g,"\\$&").replace(h.interpolate||g,function(a,b){return l.start+c(b)+l.end}).replace(h.encode||g,function(a,b){return j=!0,l.startencode+c(b)+l.end}).replace(h.conditional||g,function(a,b,d){return b?d?"';}else if("+c(d)+"){out+='":"';}else{out+='":d?"';if("+c(d)+"){out+='":"';}out+='"}).replace(h.iterate||g,function(a,b,d,e){return b?(m+=1,k=e||"i"+m,b=c(b),"';var arr"+m+"="+b+";if(arr"+m+"){var "+d+","+k+"=-1,l"+m+"=arr"+m+".length-1;while("+k+"a;a++)c=e[a],/\.def(\.dot|\.jst)?$/.test(c)&&(console.log("Loaded def "+c),this.__includes[c.substring(0,c.indexOf("."))]=f(d+c));for(a=0,b=e.length;b>a;a++)c=e[a],/\.dot(\.def|\.jst)?$/.test(c)&&(console.log("Compiling "+c+" to function"),this.__rendermodule[c.substring(0,c.indexOf("."))]=this.compilePath(d+c)),/\.jst(\.dot|\.def)?$/.test(c)&&(console.log("Compiling "+c+" to file"),this.compileToFile(this.__destination+c.substring(0,c.indexOf("."))+".js",f(d+c)));return this.__rendermodule}},{"./doT":114,fs:113}],116:[function(a,b){"use strict";function c(a,b){l(a,m.Optional(m.OneOf(Object,Function))),k.defineProperty(this,"_hostObject",a),b&&this._createProxyMethods(b),this.init&&this.init.apply(this,arguments)}function d(a,b,c){if(c=c||this._hostObject,c[a])throw new Error("method "+a+" already defined in host object");var d=this[b];l(d,Function);var e=d.bind(this);k.defineProperty(c,a,e,k.WRIT)}function e(a,b){l(a,m.Optional(m.OneOf([String],m.ObjectHash(String)))),Array.isArray(a)?a.forEach(function(a){d.call(this,a,a,b)},this):k.eachKey(a,function(a,c){d.call(this,c,a,b)},this)}function f(a,b,c){l(a,Function),l(c,m.IdentifierString);var d=n.mixin.instancePropertiesMap,e=a[d]=a[d]||{};if(e[b.name])throw new Error("Mixin: instance property for method with name "+b.name+" is already set");e[b.name]=c}function g(a,b,c,d){var e=this.prototype[c];l(e,Function);var g=h.call(this,e);k.defineProperty(a.prototype,d,g,k.WRIT),f(a,e,b)}function h(a){return function(){var b=i.call(this,a.name);return a.apply(b,arguments)}}function i(a){if(this instanceof c)return this;var b=this.constructor[n.mixin.instancePropertiesMap];return this[b[a]]}function j(a,b,c){l(c,m.Optional(m.OneOf([String],m.ObjectHash(String)))),Array.isArray(c)?c.forEach(function(c){g.call(this,a,b,c,c)},this):k.eachKey(c,function(c,d){g.call(this,a,b,c,d)},this)}var k=a("mol-proto"),l=a("../util/check"),m=l.Match,n=a("../config");b.exports=c,k.extendProto(c,{_createProxyMethod:d,_createProxyMethods:e}),k.extend(c,{useWith:j})},{"../config":118,"../util/check":135,"mol-proto":141}],117:[function(a,b){"use strict";var c={Mixin:a("./abstract/mixin"),MessageSource:a("./messenger/m_source"),MessengerMessageSource:a("./messenger/msngr_source"),MessengerAPI:a("./messenger/m_api"),MessengerRegexpAPI:a("./messenger/m_api_rx")};b.exports=c},{"./abstract/mixin":116,"./messenger/m_api":120,"./messenger/m_api_rx":121,"./messenger/m_source":122,"./messenger/msngr_source":123}],118:[function(a,b){"use strict";function c(a){d.deepExtend(c,a)}var d=a("mol-proto");b.exports=c,c({mixin:{instancePropertiesMap:"___mixin_instances"},check:!0,debug:!1})},{"mol-proto":141}],119:[function(a,b){"use strict";function c(a,b,c){c&&this._setMessageSource(c),d.call(this)}function d(){I.defineProperties(this,{_messageSubscribers:{},_patternMessageSubscribers:{}},I.CONF)}function e(){this.offAll();var a=this.getMessageSource();a&&a.destroy()}function f(a,b){return k.call(this,a,b)}function g(a,b){return k.call(this,a,b,{dispatchTimes:1})}function h(a,b){return k.call(this,a,b,{dispatchTimes:1,sync:!0})}function i(a,b){return k.call(this,a,b,{sync:!0})}function j(a,b){return k.call(this,a,b,{sync:!1})}function k(a,b,c){return J(a,K.OneOf(String,[String],RegExp)),J(b,K.OneOf(Function,{subscriber:Function,context:K.Any,options:K.Optional(Object)})),"function"==typeof b&&(b={subscriber:b,context:this._hostObject}),c&&(b.options=b.options||{},I.extend(b.options,c)),l.call(this,a,b)}function l(a,b){return I.defineProperty(b,"__messages",a),m.call(this,"_registerSubscriber",a,b)}function m(a,b,c){"string"==typeof b&&(b=b.split(M));var d=this._chooseSubscribersHash(b);if(b instanceof RegExp)return this[a](d,b,c);var e=!1;return b.forEach(function(b){var f=this[a](d,b,c);e=e||f},this),e}function n(a,b,c){if(!a[b]||!a[b].length){a[b]=[],b instanceof RegExp&&(a[b].pattern=b),this._messageSource&&this._messageSource.onSubscriberAdded(b);var d=!0}var e=a[b],f=d||-1==o.call(this,e,c);return f&&e.push(c),f}function o(a,b){return I.findIndex(a,function(a){return b.subscriber==a.subscriber&&b.context==a.context})}function p(a){J(a,K.ObjectHash(K.OneOf(Function,{subscriber:Function,context:K.Any})));var b=I.mapKeys(a,function(a,b){return this.on(b,a)},this);return b}function q(a,b){return J(a,K.OneOf(String,[String],RegExp)),J(b,K.Optional(K.OneOf(Function,{subscriber:Function,context:K.Any,options:K.Optional(Object)}))),r.call(this,a,b)}function r(a,b){return m.call(this,"_removeSubscriber",a,b)}function s(a,b,c){var d=a[b];if(!d||!d.length)return!1;if(c){"function"==typeof c&&(c={subscriber:c,context:this._hostObject});var e=o.call(this,d,c);if(-1==e)return!1;d.splice(e,1),d.length||this._removeAllSubscribers(a,b)}else this._removeAllSubscribers(a,b);return!0}function t(a,b){delete a[b],this._messageSource&&"string"==typeof b&&this._messageSource.onSubscriberRemoved(b)}function u(a){J(a,K.ObjectHash(K.Optional(K.OneOf(Function,{subscriber:Function,context:K.Any}))));var b=I.mapKeys(a,function(a,b){return this.off(b,a)},this);return b}function v(){w.call(this,this._patternMessageSubscribers),w.call(this,this._messageSubscribers)}function w(a){I.eachKey(a,function(b,c){this._removeAllSubscribers(a,c)},this)}function x(a,b,c,d){J(a,K.OneOf(String,RegExp)),J(c,K.Optional(Function));var e=this._chooseSubscribersHash(a),f=e[a];this._callSubscribers(a,b,c,f,d),"string"==typeof a&&this._callPatternSubscribers(a,b,c,f,d)}function y(a,b,c){this.postMessage(a,b,c,!0)}function z(a,b,c,d,e){I.eachKey(this._patternMessageSubscribers,function(f){var g=f.pattern;if(g.test(a)){if(d)var f=f.filter(function(a){var b=o.call(this,d,a);return-1==b});this._callSubscribers(a,b,c,f,e)}},this)}function A(a,b,c,d,e){d&&d.length&&(d=d.slice(),d.forEach(function(d){this._callSubscriber(d,a,b,c,e)},this))}function B(a,b,c,d,e){var f=a.options&&a.options.sync,g=e&&f!==!1||f,h=a.options&&a.options.dispatchTimes;if(h)if(1>=h){var i=a.__messages;this.off(i,a)}else h>1&&a.options.dispatchTimes--;g?a.subscriber.call(a.context,b,c,d):I.deferMethod(a.subscriber,"call",a.context,b,c,d)}function C(a,b){J(a,K.OneOf(String,RegExp));var c=this._chooseSubscribersHash(a),d=c[a]?[].concat(c[a]):[];return b!==!1&&"string"==typeof a&&I.eachKey(this._patternMessageSubscribers,function(b){var c=b.pattern;b&&b.length&&c.test(a)&&I.appendArray(d,b)}),d.length?d:void 0}function D(a){return a instanceof RegExp?this._patternMessageSubscribers:this._messageSubscribers}function E(a){J(a,H),I.defineProperty(this,"_messageSource",a),a.messenger=this}function F(){return this._messageSource}var G=a("../abstract/mixin"),H=a("./m_source"),I=a("mol-proto"),J=a("../util/check"),K=J.Match,L=I.createSubclass(G,"Messenger"),M=L.messagesSplitRegExp=/\s*(?:\,|\s)\s*/;I.extendProto(L,{init:c,destroy:e,on:f,once:g,onceSync:h,onSync:i,onAsync:j,onMessage:f,off:q,offMessage:q,onMessages:p,offMessages:u,offAll:v,postMessage:x,postMessageSync:y,getSubscribers:C,getMessageSource:F,_chooseSubscribersHash:D,_registerSubscriber:n,_removeSubscriber:s,_removeAllSubscribers:t,_callPatternSubscribers:z,_callSubscribers:A,_callSubscriber:B,_setMessageSource:E}),L.defaultMethods={on:"on",onSync:"onSync",once:"once",onceSync:"onceSync",off:"off",onMessages:"onMessages",offMessages:"offMessages",postMessage:"postMessage",postMessageSync:"postMessageSync",getSubscribers:"getSubscribers"},b.exports=L,L.subscriptions=[]},{"../abstract/mixin":116,"../util/check":135,"./m_source":122,"mol-proto":141}],120:[function(a,b,c){arguments[4][68][0].apply(c,arguments)},{"../util/logger":137,"mol-proto":141}],121:[function(a,b,c){arguments[4][69][0].apply(c,arguments)},{"./m_api":120,"mol-proto":141}],122:[function(a,b){"use strict";function c(a,b,c){this._prepareMessengerAPI(c)}function d(){this.messengerAPI&&this.messengerAPI.destroy()}function e(a){n.defineProperty(this,"messenger",a)}function f(a){o(a,p.Optional(m)),a||(a=new m),n.defineProperty(this,"messengerAPI",a)}function g(a){var b=this.messengerAPI.addInternalMessage(a);"undefined"!=typeof b&&this.addSourceSubscriber(b)}function h(a){var b=this.messengerAPI.removeInternalMessage(a);"undefined"!=typeof b&&this.removeSourceSubscriber(b)}function i(a,b){var c=this.messengerAPI,d=c.getInternalMessages(a);d&&d.forEach(function(d){var e=c.createInternalData(a,d,b),f=c.filterSourceMessage(a,d,e);f&&this.postMessage(d,e)},this)}function j(a,b){this.messenger.postMessage(a,b)}function k(){throw new Error("calling the method of an absctract class")}var l=a("../abstract/mixin"),m=a("./m_api"),n=(a("../util/logger"),a("mol-proto")),o=a("../util/check"),p=o.Match,q=n.createSubclass(l,"MessageSource",!0);b.exports=q,n.extendProto(q,{init:c,destroy:d,setMessenger:e,onSubscriberAdded:g,onSubscriberRemoved:h,dispatchMessage:i,postMessage:j,_prepareMessengerAPI:f,trigger:k,addSourceSubscriber:k,removeSourceSubscriber:k})},{"../abstract/mixin":116,"../util/check":135,"../util/logger":137,"./m_api":120,"mol-proto":141}],123:[function(a,b,c){arguments[4][71][0].apply(c,arguments)},{"../util/check":135,"./m_source":122,"mol-proto":141}],124:[function(a,b){"use strict";function c(){d.minder.destroy()}var d=(a("mol-proto"),{minder:a("./minder"),config:a("./config"),util:a("./util"),classes:a("./classes"),Messenger:a("./messenger"),Model:a("./model"),destroy:c});"object"==typeof b&&b.exports&&(b.exports=d),"object"==typeof window&&(window.milo=d)},{"./classes":117,"./config":118,"./messenger":119,"./minder":125,"./model":128,"./util":136,"mol-proto":141}],125:[function(a,b){"use strict";function c(a,b,c,e){if(Array.isArray(a)){var f=a,g=f.map(function(a){return new p(a[0],a[1],a[2],a[3])});return g.forEach(d),g}var h=new p(a,b,c,e);return d(h),h}function d(a){a.___minder_id=u.push(a)-1,a.on(/.*/,e),c.postMessage("added",{connector:a}),c.postMessage("turnedon",{connector:a})}function e(a,b){var b=b?r.clone(b):{};r.extend(b,{id:this.___minder_id,connector:this}),c.postMessage(a,b),v.length||w||(r.defer(f),w=!0),v.push({msg:a,data:b})}function f(){v.length?(v.length=0,r.defer(f),c.postMessage("propagationticked")):(w=!1,c.postMessage("propagationcompleted"))}function g(){return w}function h(a){function b(){w?c.once("propagationcompleted",b):a()}w?c.once("propagationcompleted",b):r.defer(b)}function i(a){return"undefined"==typeof a?u:u.filter(function(b){return b.isOn===a})}function j(a){a.destroy();var b=u.indexOf(a);b>=0?delete u[b]:s.warn("minder: connector destroyed that is not registered in minder")}function k(a,b){var d=c.getConnectors(a),e=d.map(function(a){var b={leftSource:l(a.ds1),rightSource:l(a.ds2),mode:a.mode,isOn:a.isOn};return a.options&&(b.options=a.options),b});return b&&(e=e.filter(function(a){return m(a.leftSource,b)||m(a.rightSource,b)})),e}function l(a){var b=[];return"function"==typeof a&&(a._model&&a._accessPath&&(b.unshift(a._accessPath),a=a._model),b.unshift(a),a=a._hostObject),"object"==typeof a&&(b.unshift(a),a.owner&&b.unshift(a.owner)),b}function m(a,b){return a.some(function(a){var c=a.constructor&&a.constructor.name;return n(c,b)||n(a.name,b)||n(a,b)})}function n(a,b){return a&&"string"==typeof a&&a.indexOf(b)>=0}function o(){function a(a){a&&!a._destroyed&&a.destroy()}u.forEach(function(b){a(b.ds1),a(b.ds2),b.destroy()}),t.destroy(),c._destroyed=!0}var p=a("./model/connector"),q=a("./messenger"),r=a("mol-proto"),s=a("./util/logger");b.exports=c;var t=new q(c,q.defaultMethods),u=[],v=[],w=!1;r.extend(c,{getConnectors:i,getExpandedConnections:k,isPropagating:g,whenPropagationCompleted:h,destroyConnector:j,destroy:o})},{"./messenger":119,"./model/connector":127,"./util/logger":137,"mol-proto":141}],126:[function(a,b){"use strict";function c(a,b){r.defineProperty(a,"__inChangeTransaction",b,r.CONF|r.WRIT)}function d(a){var b=a.__inChangeTransaction;return delete a.__inChangeTransaction,b}function e(a,b){var e=d(a);return c(b,e),e}function f(){this.postMessageSync("datachanges",{transaction:!1,changes:[]})}function g(a,b,c){h.call(this,b.changes,c)}function h(a,b){i.call(this,b,!1),l.call(this,k(j(a))),i.call(this,b,!0)}function i(a,b){a&&a(null,b),this.postMessage(b?"changecompleted":"changestarted")}function j(a){var b=a[0].source,c=!0;if(a.length>1)for(var d=1,e=a.length;e>d;d++)a[d].source!=b&&(o.error("changedata: changes from different sources in the same transaction, sources:",a[d].source.name,b.name),c=!1,b=a[d].source);return a}function k(a){function b(a){("splice"==a.type?c:d)(a)}function c(a){var b=q.parseAccessPath(a.path),c=i.some(function(a){return b.length"]});var l=e.dataValidation;l&&o.extend(this,{dataValidation1:l["<-"],dataValidation2:l["->"]})}this.turnOn()}function d(a){function b(){throw new Error("invalid Connector mode: "+a)}var c=a.match(q);c||b();var d=c[1].length,e=c[2].length;d&&e&&d!=e&&b(),d||e||b(),o.extend(this,{mode:a,depth1:d,depth2:e})}function e(a){return this.turnOff(),d.call(this,a),this.turnOn(),this}function f(a){return o.deferMethod(this,"changeMode",a),this +}function g(a){var b={};return o.eachKey(a,function(a,c){b[a]=c}),b}function h(a){function b(a,b){throw new Error("Invalid pattern translation: "+a+", "+b)}function c(a){return a.replace(/[\.\[]?\*.*$/,"")}var d=[];return o.eachKey(a,function(e,f){var g=f.indexOf("*"),h=e.indexOf("*");g>=0&&h>=0?(f.slice(g)!=e.slice(h)&&b(f,e),delete a[f],d.push({fromPattern:n.createRegexPath(f),fromStaticPath:c(f,g),toPattern:n.createRegexPath(e),toStaticPath:c(e,h)})):(g>=0||h>=0)&&b(f,e)}),d}function i(a){return a.map(function(a){return{fromPattern:a.toPattern,fromStaticPath:a.toStaticPath,toPattern:a.fromPattern,toStaticPath:a.fromStaticPath}})}function j(){function a(a,b,e,f,g,h,i,j){function k(k,l){function m(a){if(g){var b=g[a];if(b)return b;if(!h.length)return;var d=o.find(h,function(b){return b.fromPattern.test(a)});if(!d)return;var b=a.replace(d.fromStaticPath,d.toStaticPath)}else if(!(c instanceof RegExp&&c.test(a)||c==a))return;return b||a}function n(a,b){if(i){var c=i[a];c&&"function"==typeof c&&(b.oldValue=c(b.oldValue),b.newValue=c(b.newValue))}}function p(a,c){function d(d){d(c.newValue,function(c,d){d.path=a,g||!c&&!d.valid||++f!=e.length?d.valid||(g=!0,b.postMessage("validated",d)):b.postMessage("validated",d)})}if(q(c),j){var e=j[a],f=0,g=!1;e&&e.forEach(d)}}function q(a){u.changes.push(a)}function r(){if(d[a])var b=s;var c=t(f);f.length=0,c.forEach(function(a){e.postMessageSync("changedata",{changes:a},b)})}function s(c,f){if(!c){var g=f?"onSync":"off";e[g]("datachanges",d[a]);var h=f?"changecompleted":"changestarted";d.postMessage(h,{source:b,target:e})}}function t(a){var b,c=[];return a.forEach(function(a){a.transaction||(b=void 0),a.changes.length&&(a.transaction?b?o.appendArray(b,a.changes):(b=o.clone(a.changes),c.push(b)):c.push(a.changes))}),c}var u={changes:[],transaction:l.transaction};l.changes.forEach(function(a){var c=a.path,d=m(c);if("undefined"!=typeof d){var a=o.clone(a);o.extend(a,{source:b,path:d}),n(c,a),p(c,a)}}),f.length||o.defer(r),f.push(u)}return b.onSync("datachanges",k),k}if(this.isOn)return p.warn("data sources are already connected");var b=this._subscriptionPath=new Array(this.depth1||this.depth2).join("*"),c=n.createRegexPath(b),d=this;this.depth1&&(this._link1=a("_link2",this.ds2,this.ds1,this._changesQueue1,this.pathTranslation1,this.patternTranslation1,this.dataTranslation1,this.dataValidation1)),this.depth2&&(this._link2=a("_link1",this.ds1,this.ds2,this._changesQueue2,this.pathTranslation2,this.patternTranslation2,this.dataTranslation2,this.dataValidation2)),this.isOn=!0,this.postMessage("turnedon")}function k(){function a(a,c){b[c]&&(a.off("datachanges",b[c]),delete b[c])}if(!this.isOn)return p.warn("data sources are already disconnected");var b=this;a(this.ds1,"_link2",this.pathTranslation2),a(this.ds2,"_link1",this.pathTranslation1),this.isOn=!1,this.postMessage("turnedoff")}function l(){this.turnOff(),this.postMessage("destroyed"),this._messenger.destroy(),delete this.ds1,delete this.ds2,this._destroyed=!0}var m=a("../messenger"),n=a("./path_utils"),o=a("mol-proto"),p=a("../util/logger");b.exports=c;var q=/^(\<*)\-+(\>*)$/;o.extendProto(c,{turnOn:j,turnOff:k,destroy:l,changeMode:e,deferChangeMode:f})},{"../messenger":119,"../util/logger":137,"./path_utils":133,"mol-proto":141}],128:[function(a,b){"use strict";function c(a,b,d){var f=function(){return e.apply(f,arguments)};return f.__proto__=c.prototype,f._hostObject=b,f._options=d||{},f._options.reactive!==!1&&(f._prepareMessengers(),f.onSync("changedata",n)),a&&(f._data=a),f}function d(){return this._data}function e(a){return a?(s.splice(arguments,0,0,null,this),new(Function.prototype.bind.apply(l,arguments))):this}function f(a){a=a||this._hostObject,r.prototype._createProxyMethods.call(this[u],o.defaultMethods,a)}function g(a,b,d){d=d||v,r.useWith.call(c,a,b,d)}function h(a){a=a||this._hostObject,r.prototype._createProxyMethods.call(this,v,a)}function i(){var a=new o(this,void 0,void 0),b=new p(this,void 0,new q,a),c=new o(this,void 0,b);s.defineProperty(this,u,c),s.defineProperty(this,"_internalMessenger",a)}function j(){return this._hostObject}function k(){this[u].destroy(),this._internalMessenger.destroy(),this._destroyed=!0}{var l=a("./m_path"),m=a("./synthesize"),n=(a("./path_utils"),a("./change_data")),o=a("../messenger"),p=a("../messenger/msngr_source"),q=a("./m_msg_api"),r=a("../abstract/mixin"),s=a("mol-proto"),t=a("../util/check");t.Match,a("../util/logger")}b.exports=c,c.prototype.__proto__=c.__proto__,s.extendProto(c,{path:e,get:d,proxyMessenger:f,proxyMethods:h,_prepareMessengers:i,_getHostObject:j,destroy:k}),s.extendProto(c,m.modelMethods),s.extend(c,{Path:l,useWith:g});var u="_messenger";o.useWith(c,u,o.defaultMethods),["len","push","pop","unshift","shift"].forEach(function(a){var b=l.prototype[a];s.defineProperty(c.prototype,a,b)});var v=["path","get","set","del","splice","len","push","pop","unshift","shift"]},{"../abstract/mixin":116,"../messenger":119,"../messenger/msngr_source":123,"../util/check":135,"../util/logger":137,"./change_data":126,"./m_msg_api":129,"./m_path":130,"./path_utils":133,"./synthesize":134,"mol-proto":141}],129:[function(a,b,c){arguments[4][75][0].apply(c,arguments)},{"../messenger/m_api_rx":121,"./path_utils":133,"mol-proto":141}],130:[function(a,b,c){arguments[4][76][0].apply(c,arguments)},{"../messenger":119,"../messenger/msngr_source":123,"../util/check":135,"./change_data":126,"./path_msg_api":132,"./path_utils":133,"./synthesize":134,"mol-proto":141}],131:[function(a,b){b.exports=a(77)},{}],132:[function(a,b,c){arguments[4][78][0].apply(c,arguments)},{"../messenger/m_api":120,"../util/logger":137,"./path_utils":133,"mol-proto":141}],133:[function(a,b){"use strict";function c(a,b){b=b||t;var c=[];if(!a)return c;var d=a.replace(b,function(a){var b={property:a};return i.extend(b,w[a[0]]),"$"==a[1]&&(b.interpolate=e(b,!0)),c.push(b),""});if(d)throw new Error("incorrect model path: "+a);return c}function d(a){if(g(a,h.OneOf(String,RegExp)),a instanceof RegExp||-1==a.indexOf("*"))return a;var b=j.parseAccessPath(a,v),c="^",d=!1;b.forEach(function(a){var b=a.property,e=x[b];e?(c+="("+e+"|)",d=!0):c+=b.replace(/(\.|\[|\])/g,"\\$1")}),c+="$";try{return new RegExp(c)}catch(e){throw new Error("can't construct regex for path pattern: "+a)}}function e(a,b){var c=a.property,d=b?2:1;return"array"==a.syntax?c.slice(d,c.length-1):c.slice(d)}function f(a){a=a||["on","off"];var b=i.mapToObject(a,function(a){var b=this[a];return function(a,c){var e=d(a);b.call(this,e,c)}},this);i.defineProperties(this,b)}var g=a("../util/check"),h=g.Match,i=a("mol-proto"),j={parseAccessPath:c,createRegexPath:d,getPathNodeKey:e,wrapMessengerMethods:f};b.exports=j;var k="\\.[A-Za-z_-][A-Za-z0-9_-]*",l="\\[[0-9]+\\]",m="\\$[1-9][0-9]*",n="\\."+m,o="\\["+m+"\\]",p="\\.\\*",q="\\[\\*\\]",r="\\*",s=[k,l,n,o].join("|"),t=new RegExp(s,"g"),u=[s,p,q,r].join("|"),v=new RegExp(u,"g"),w={".":{syntax:"object",empty:"{}"},"[":{syntax:"array",empty:"[]"},"*":{syntax:"match",empty:"{}"}},x={".*":k,"[*]":l};x["*"]=x[".*"]+"|"+x["[*]"]},{"../util/check":135,"mol-proto":141}],134:[function(require,module,exports){"use strict";function _synthesizePathMethods(a,b){var c=_.mapKeys(synthesizers,function(c){return _synthesize(c,a,b)});return c}function _synthesize(synthesizer,path,parsedPath){function addChangeMessage(a,b,c){a.push(c),b[c.path]=c}function addTreeChangesMessages(a,b,c,d,e){var f=valueIsTree(d),g=valueIsTree(e);g&&addMessages(a,b,c,e,"added","newValue"),f&&addMessages(a,b,c,d,"removed","oldValue")}function addMessages(a,b,c,d,e,f){function g(a,b){if(Array.isArray(b)){var c=a+"[$$]";b.forEach(function(a,b){h(a,b,c)})}else{var c=a+".$$";_.eachKey(b,function(a,b){h(a,b,c)})}}function h(c,d,h){var i=h.replace("$$",d),j=b[i];if(j)j.type==e?logger.error("setter error: same message type posted on the same path"):(j.type="changed",j[f]=c);else{var k={path:i,type:e};k[f]=c,addChangeMessage(a,b,k)}valueIsTree(c)&&g(i,c)}g(c,d)}function cloneTree(a){return valueIsNormalObject(a)?_.deepClone(a):a}function protectValue(a){return valueIsNormalObject(a)?Array.isArray(a)?a.slice():Object.create(a):a}function valueIsTree(a){return valueIsNormalObject(a)&&Object.keys(a).length}function valueIsNormalObject(a){return!(null==a||"object"!=typeof a||a instanceof Date||a instanceof RegExp)}function addBatchIdsToMessage(a,b,c){_.defineProperties(a,{__batch_id:b,__msg_id:c})}var method,methodCode=synthesizer({parsedPath:parsedPath,getPathNodeKey:pathUtils.getPathNodeKey});try{eval(methodCode)}catch(e){throw ModelError("ModelPath method compilation error; path: "+path+", code: "+methodCode)}return method}var pathUtils=require("../path_utils"),modelUtils=require("../model_utils"),logger=require("../../util/logger"),fs=require("fs"),doT=require("dot"),_=require("mol-proto"),changeDataHandler=require("../change_data"),getTransactionFlag=changeDataHandler.getTransactionFlag,postTransactionFinished=changeDataHandler.postTransactionFinished,templates={get:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\nmethod = function get() {\n var m = {{# def.modelAccessPrefix }};\n return m {{~ it.parsedPath :pathNode }}\n {{? pathNode.interpolate}}\n && (m = m[this._args[ {{= pathNode.interpolate }} ]])\n {{??}}\n && (m = m{{= pathNode.property }})\n {{?}} {{~}};\n};\n",set:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n\n\n/**\n * Template that synthesizes setter for Model and for ModelPath\n */\nmethod = function set(value) {\n {{# def.initVars:'set' }}\n\n {{# def.createTree:'set' }}\n\n {{\n currNode = nextNode;\n currProp = currNode && currNode.property;\n }}\n\n {{ /* assign value to the last property */ }}\n {{? currProp }}\n wasDef = {{# def.wasDefined}};\n {{# def.changeAccessPath }}\n\n var old = m{{# def.currProp }};\n\n {{ /* clone value to prevent same reference in linked models */ }}\n m{{# def.currProp }} = cloneTree(value);\n {{?}}\n\n {{ /* add message related to the last property change */ }}\n if (this._options.reactive !== false) {\n if (! wasDef)\n {{# def.addMsg }} accessPath, type: 'added',\n newValue: value });\n else if (old != value)\n {{# def.addMsg }} accessPath, type: 'changed',\n oldValue: old, newValue: value });\n\n {{ /* add message related to changes in (sub)properties inside removed and assigned value */ }}\n if (! wasDef || old != value)\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, value); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n",del:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_traverse_tree }}\n\nmethod = function del() {\n {{# def.initVars:'del' }}\n\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n if (! treeDoesNotExist && m && m.hasOwnProperty && {{# def.wasDefined}}) {\n var old = m{{# def.currProp }};\n delete m{{# def.currProp }};\n {{# def.changeAccessPath }}\n var didDelete = true;\n }\n {{??}}\n if (typeof m != 'undefined') {\n var old = m;\n {{# def.modelAccessPrefix }} = undefined;\n var didDelete = true;\n }\n {{?}}\n\n if (didDelete && this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'deleted', oldValue: old });\n\n addTreeChangesMessages(messages, messagesHash,\n accessPath, old, undefined); /* defined in the function that synthesizes ModelPath setter */\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n};\n",splice:"'use strict';\n/* Only use this style of comments, not \"//\" */\n\n{{# def.include_defines }}\n{{# def.include_create_tree }}\n{{# def.include_traverse_tree }}\n\nmethod = function splice(spliceIndex, spliceHowMany) { /* ,... - extra arguments to splice into array */\n {{# def.initVars:'splice' }}\n\n var argsLen = arguments.length;\n var addItems = argsLen > 2;\n\n if (addItems) {\n {{ /* only create model tree if items are inserted in array */ }}\n\n {{ /* if model is undefined it will be set to an empty array */ }} \n var value = [];\n {{# def.createTree:'splice' }}\n\n {{? nextNode }}\n {{\n var currNode = nextNode;\n var currProp = currNode.property;\n var emptyProp = '[]';\n }}\n\n {{# def.createTreeStep }}\n {{?}}\n\n } else if (spliceHowMany > 0) {\n {{ /* if items are not inserted, only traverse model tree if items are deleted from array */ }}\n {{? it.parsedPath.length }}\n {{# def.traverseTree }}\n\n {{\n var currNode = it.parsedPath[count];\n var currProp = currNode.property; \n }}\n\n {{ /* extra brace closes 'else' in def.traverseTreeStep */ }}\n {{# def.traverseTreeStep }} }\n {{?}}\n }\n\n {{ /* splice items */ }}\n if (addItems || (! treeDoesNotExist && m\n && m.length > spliceIndex ) ) {\n var oldLength = m.length = m.length || 0;\n\n arguments[0] = spliceIndex = normalizeSpliceIndex(spliceIndex, m.length);\n\n {{ /* clone added arguments to prevent same references in linked models */ }}\n if (addItems)\n for (var i = 2; i < argsLen; i++)\n arguments[i] = cloneTree(arguments[i]);\n\n {{ /* actual splice call */ }}\n var removed = Array.prototype.splice.apply(m, arguments);\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'splice',\n index: spliceIndex, removed: removed, addedCount: addItems ? argsLen - 2 : 0,\n newValue: m });\n\n if (removed && removed.length)\n removed.forEach(function(item, index) {\n var itemPath = accessPath + '[' + (spliceIndex + index) + ']';\n {{# def.addMsg }} itemPath, type: 'removed', oldValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'removed', 'oldValue');\n });\n\n if (addItems)\n for (var i = 2; i < argsLen; i++) {\n var item = arguments[i];\n var itemPath = accessPath + '[' + (spliceIndex + i - 2) + ']';\n {{# def.addMsg }} itemPath, type: 'added', newValue: item });\n\n if (valueIsTree(item))\n addMessages(messages, messagesHash, itemPath, item, 'added', 'newValue');\n }\n\n {{ /* post all stored messages */ }}\n {{# def.postMessages }}\n }\n }\n\n return removed || [];\n}\n"},include_defines="'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts initialization code\n */\n {{## def.initVars:method:\n var m = {{# def.modelAccessPrefix }};\n var messages = [], messagesHash = {};\n var accessPath = '';\n var treeDoesNotExist;\n /* hack to prevent sending finished events to allow for propagation of batches without splitting them */\n var inChangeTransaction = getTransactionFlag( {{= method }} );\n #}}\n\n/**\n * Inserts the beginning of function call to add message to list\n */\n{{## def.addMsg: addChangeMessage(messages, messagesHash, { path: #}}\n\n/**\n * Inserts current property/index for both normal and interpolated properties/indexes\n */\n{{## def.currProp:{{? currNode.interpolate }}[this._args[ {{= currNode.interpolate }} ]]{{??}}{{= currProp }}{{?}} #}}\n\n/**\n * Inserts condition to test whether normal/interpolated property/index exists\n */\n{{## def.wasDefined: m.hasOwnProperty(\n {{? currNode.interpolate }}\n this._args[ {{= currNode.interpolate }} ]\n {{??}}\n '{{= it.getPathNodeKey(currNode) }}'\n {{?}}\n) #}}\n\n\n/**\n * Inserts code to update access path for current property\n * Because of the possibility of interpolated properties, it can't be calculated in template, it can only be calculated during accessor call.\n */\n{{## def.changeAccessPath:\n accessPath += {{? currNode.interpolate }}\n {{? currNode.syntax == 'array' }}\n '[' + this._args[ {{= currNode.interpolate }} ] + ']';\n {{??}}\n '.' + this._args[ {{= currNode.interpolate }} ];\n {{?}}\n {{??}}\n '{{= currProp }}';\n {{?}}\n#}}\n\n\n/**\n * Inserts code to post stored messages\n */\n{{## def.postMessages:\n if (messages.length) {\n {{# def.modelPostBatchCode }}('datachanges', {\n changes: messages,\n transaction: inChangeTransaction\n });\n\n messages.forEach(function(msg) {\n {{# def.modelPostMessageCode }}(msg.path, msg);\n }, this);\n }\n#}}\n",include_create_tree="'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to create model tree as neccessary for `set` and `splice` accessors and to add messages to send list if the tree changes.\n */\n{{## def.createTree:method:\n var wasDef = true;\n var old = m;\n\n {{ var emptyProp = it.parsedPath[0] && it.parsedPath[0].empty; }}\n {{? emptyProp }}\n {{ /* create top level model if it was not previously defined */ }}\n if (! m) {\n m = {{# def.modelAccessPrefix }} = {{= emptyProp }};\n wasDef = false;\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} '', type: 'added',\n newValue: m });\n }\n }\n {{??}}\n {{? method == 'splice' }}\n if (! m) {\n {{?}}\n m = {{# def.modelAccessPrefix }} = cloneTree(value);\n wasDef = typeof old != 'undefined';\n {{? method == 'splice' }}\n }\n {{?}} \n {{?}}\n\n\n {{ /* create model tree if it doesn't exist */ }}\n {{ var modelDataProperty = '';\n var nextNode = it.parsedPath[0];\n var count = it.parsedPath.length - 1;\n\n for (var i = 0; i < count; i++) {\n var currNode = nextNode;\n var currProp = currNode.property;\n nextNode = it.parsedPath[i + 1];\n var emptyProp = nextNode && nextNode.empty;\n }}\n\n {{# def.createTreeStep }}\n\n {{ } /* for loop */ }}\n#}}\n\n\n/**\n * Inserts code to create one step in the model tree\n */\n{{## def.createTreeStep:\n {{# def.changeAccessPath }}\n\n if (! {{# def.wasDefined }}) { \n {{ /* property does not exist */ }}\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'added', \n newValue: m });\n }\n\n } else if (typeof m{{# def.currProp }} != 'object') {\n {{ /* property is not object */ }}\n var old = m{{# def.currProp }};\n m = m{{# def.currProp }} = {{= emptyProp }};\n\n if (this._options.reactive !== false) {\n {{# def.addMsg }} accessPath, type: 'changed', \n oldValue: old, newValue: m });\n }\n\n } else {\n {{ /* property exists, just traverse down the model tree */ }}\n m = m{{# def.currProp }};\n }\n#}}\n",include_traverse_tree="'use strict';\n/* Only use this style of comments, not \"//\" */\n\n/**\n * Inserts code to traverse model tree for `delete` and `splice` accessors.\n */\n{{## def.traverseTree:\n {{ \n var count = it.parsedPath.length-1;\n\n for (var i = 0; i < count; i++) { \n var currNode = it.parsedPath[i];\n var currProp = currNode.property;\n }}\n {{# def.traverseTreeStep }}\n\n {{ } /* for loop */\n\n var i = count;\n while (i--) { /* closing braces for else's above */\n }}\n }\n {{ } /* while loop */ }}\n#}}\n\n\n/**\n * Inserts code to traverse one step in the model tree\n */\n{{## def.traverseTreeStep:\n if (! (m && m.hasOwnProperty && {{# def.wasDefined}} ) )\n treeDoesNotExist = true;\n else {\n m = m{{# def.currProp }};\n {{# def.changeAccessPath }}\n {{ /* brace from else is not closed on purpose - all braces are closed in while loop */ }}\n#}}\n",dotDef={include_defines:include_defines,include_create_tree:include_create_tree,include_traverse_tree:include_traverse_tree,getPathNodeKey:pathUtils.getPathNodeKey,modelAccessPrefix:"this._model._data",modelPostMessageCode:"this._model._internalMessenger.postMessage",modelPostBatchCode:"this._model.postMessageSync",internalMessenger:"this._model._internalMessenger"},modelDotDef=_(dotDef).clone().extend({modelAccessPrefix:"this._data",modelPostMessageCode:"this._internalMessenger.postMessage",modelPostBatchCode:"this.postMessageSync",internalMessenger:"this._internalMessenger"})._(),dotSettings=_.clone(doT.templateSettings);dotSettings.strip=!1;var synthesizers=_.mapKeys(templates,function(a){return doT.template(a,dotSettings,dotDef)}),modelSynthesizers=_.mapToObject(["set","del","splice"],function(a){return doT.template(templates[a],dotSettings,modelDotDef)}),synthesizePathMethods=_.memoize(_synthesizePathMethods,void 0,1e3),normalizeSpliceIndex=modelUtils.normalizeSpliceIndex;module.exports=synthesizePathMethods;var modelMethods=_.mapKeys(modelSynthesizers,function(a){return _synthesize(a,"",[])});synthesizePathMethods.modelMethods=modelMethods},{"../../util/logger":137,"../change_data":126,"../model_utils":131,"../path_utils":133,dot:140,fs:113,"mol-proto":141}],135:[function(a,b,c){arguments[4][90][0].apply(c,arguments)},{"../config":118,"mol-proto":141}],136:[function(a,b){"use strict";var c={logger:a("./logger"),check:a("./check")};b.exports=c},{"./check":135,"./logger":137}],137:[function(a,b,c){arguments[4][102][0].apply(c,arguments)},{"./logger_class":138}],138:[function(a,b,c){arguments[4][103][0].apply(c,arguments)},{"mol-proto":141}],139:[function(a,b){b.exports=a(114)},{}],140:[function(a,b){b.exports=a(115)},{"./doT":139,fs:113}],141:[function(a,b){"use strict";function c(a){var b=Object.create(c.prototype);return b.self=a,b}function d(){return this.self}var e=a("./utils"),f=a("./proto_prototype"),g=a("./proto_object"),h=a("./proto_array"),i=a("./proto_function"),j=a("./proto_string"),k=a("./proto_number"),l=a("./proto_util"),m={};g.extend.call(m,g),m.extend.call(m,f),m.extend.call(m,h),m.extend.call(m,j),m.extend.call(m,k),m.extend.call(m,i),m.extend.call(m,l),m.defineProperty(c,"__",m),m.extendProto.call(c,{_:d}),m.extend.call(c,g._constants);var n=m.mapKeys.call(m,e.makeProtoFunction,!0);m.extend.call(c,n);var o=m.mapKeys.call(m,e.makeProtoInstanceMethod,!0);m.extendProto.call(c,o),"object"==typeof window&&(window._&&(c.underscore=window._),window._=c),"object"==typeof b&&b.exports&&(b.exports=c)},{"./proto_array":142,"./proto_function":143,"./proto_number":144,"./proto_object":145,"./proto_prototype":146,"./proto_string":147,"./proto_util":148,"./utils":149}],142:[function(a,b){"use strict";function c(a){if(!a.length)return this;Array.isArray(a)||(a=f.call(a));var b=[this.length,0].concat(a);return m.splice.apply(this,b),this}function d(a){if(!a.length)return this;Array.isArray(a)||(a=f.call(a));var b=[0,0].concat(a);return m.splice.apply(this,b),this}function e(a){var b=this.indexOf(a);return b>=0&&this.splice(b,1),this}function f(){return m.slice.call(this)}function g(a){var b={},c=Array.isArray(a);return m.forEach.call(this,function(d,e){b[d]=c?a[e]:a}),b}function h(a,b){var c={};return Array.prototype.forEach.call(this,function(d,e){c[d]=a.call(b,d,e,this)},this),c}function i(a){function b(b){return m.findIndex.call(d,function(c){return a(b,c)})}function c(a){return d.indexOf(a)}var d=[];return a||(b=c),this.forEach(function(a){var c=b(a);-1==c&&d.push(a)}),d}function j(a,b){function c(){m.forEach.call(this,function(f){Array.isArray(f)?c.call(f):a.call(b,f,d++,e)})}var d=0,e=this;c.call(this)}var k=a("./proto_object"),l=a("./utils"),m=b.exports={appendArray:c,prependArray:d,toArray:f,object:g,mapToObject:h,unique:i,deepForEach:j,spliceItem:e},n=["join","pop","push","concat","reverse","shift","unshift","slice","splice","sort","filter","forEach","some","every","map","indexOf","lastIndexOf","reduce","reduceRight"],o=h.call(n,function(a){return Array.prototype[a]});k.extend.call(m,o),m.find=Array.prototype.find||l.makeFindMethod(m.forEach,"value"),m.findIndex=Array.prototype.findIndex||l.makeFindMethod(m.forEach,"index")},{"./proto_object":145,"./utils":149}],143:[function(require,module,exports){"use strict";function makeFunction(arg1,arg2,funcBody){for(var name=this,count=arguments.length-1,funcBody=arguments[count],func,code="",i=0;count>i;i++)code+=", "+arguments[i];return code=["func = function ",name,"(",code.slice(2),") {\n",funcBody,"\n}"].join(""),eval(code),func}function partial(){var a=this,b=slice.call(arguments);return function(){return a.apply(this,b.concat(slice.call(arguments)))}}function partialRight(){var a=this,b=slice.call(arguments);return function(){return a.apply(this,slice.call(arguments).concat(b))}}function memoize(a,b){var c=this,d={},e=[];return b=b||1e3,function(){var f=a?a.apply(this,arguments):arguments[0];if(d.hasOwnProperty(f))return d[f];var g=d[f]=c.apply(this,arguments);return e.push(f),e.length>b&&delete d[e.shift()],g}}function delay(a){var b=slice.call(arguments,1);return _delay(this,a,b)}function defer(){return _delay(this,1,arguments)}function _delay(a,b,c,d){return setTimeout(a.apply.bind(a,d||null,c),b)}function deferTicks(a){if(2>a)return defer.apply(this,arguments);var b=repeat.call(deferFunc,a-1);return b=b.concat(this,slice.call(arguments,1)),deferFunc.apply(null,b)}function delayMethod(a,b){var c=slice.call(arguments,2);return _delayMethod(this,a,b,c)}function deferMethod(a){var b=slice.call(arguments,1);return _delayMethod(this,a,1,b)}function _delayMethod(a,b,c,d){return setTimeout(function(){var c="string"==typeof b?a[b]:b;c.apply(a,d)},c)}function delayed(a){var b=this,c=slice.call(arguments,1);return function(){var d=c.concat(slice.call(arguments));return _delay(b,a,d,this)}}function deferred(){var a=this,b=slice.call(arguments);return function(){var c=b.concat(slice.call(arguments));return _delay(a,1,c,this)}}function debounce(a,b){var c,d,e,f,g,h=this;return function(){function i(){var j=Date.now()-f;a>j?c=setTimeout(i,a-j):(c=null,b||(g=h.apply(e,d)))}e=this,d=arguments,f=Date.now();var j=b&&!c;return c||(c=setTimeout(i,a)),j&&(g=h.apply(e,d)),g}}function throttle(a,b){function c(){i=b.leading===!1?0:Date.now(),h=null,f=g.apply(d,e)}var d,e,f,g=this,h=null,i=0;return b||(b={}),function(){var j=Date.now();i||b.leading!==!1||(i=j);var k=a-(j-i);return d=this,e=arguments,0>=k?(clearTimeout(h),h=null,i=j,f=g.apply(d,e)):h||b.trailing===!1||(h=setTimeout(c,k)),f}}function once(){var a,b=this,c=!1;return function(){return c?a:(c=!0,a=b.apply(this,arguments),b=null,a)}}function waitFor(a,b,c,d){function e(){if(g())a();else{if(!(Date.now()-f>=b))return;c&&c()}clearInterval(h)}var f=Date.now(),g=this;d=d||50;var h=setInterval(e,d)}function not(){var a=this;return function(){return!a.apply(this,arguments)}}var makeProtoFunction=require("./utils").makeProtoFunction,repeat=require("./proto_util").repeat,functionMethods=module.exports={makeFunction:makeFunction,partial:partial,partialRight:partialRight,memoize:memoize,delay:delay,defer:defer,delayed:delayed,deferred:deferred,deferTicks:deferTicks,delayMethod:delayMethod,deferMethod:deferMethod,debounce:debounce,throttle:throttle,once:once,waitFor:waitFor,not:not},slice=Array.prototype.slice,deferFunc=makeProtoFunction(defer)},{"./proto_util":148,"./utils":149}],144:[function(a,b){"use strict";function c(){return!isNaN(parseFloat(this))&&isFinite(this)}b.exports={isNumeric:c}},{}],145:[function(a,b){"use strict";function c(a,b){var c={};return p.call(a,function(b,d){c[d]=Object.getOwnPropertyDescriptor(a,d)},this,b),Object.defineProperties(this,c),this}function d(){if(Array.isArray(this))return this.slice();if(this instanceof Date)return new Date(this);if(this instanceof RegExp)return new RegExp(this);var a=Object.create(this.constructor.prototype);return c.call(a,this),a}function e(a,b,c){return Object.defineProperty(this,a,f(b,c)),this}function f(a,b){var d={value:a};return b&&c.call(d,{enumerable:!!(b&B.ENUMERABLE),configurable:!!(b&B.CONFIGURABLE),writable:!!(b&B.WRITABLE)}),d}function g(a,b){var c=q.call(a,function(a){return f(a,b)},!0);return Object.defineProperties(this,c),this}function h(a,b){return i(this,a,b,[])}function i(a,b,c,d){if(!(d.indexOf(b)>=0)){d.push(b);var e=Array.isArray(b)?Array.prototype.forEach:p;return e.call(b,function(e,f){var g=Object.getOwnPropertyDescriptor(b,f);"object"!=typeof e||null==e||e instanceof RegExp||e instanceof Date?Object.defineProperty(a,f,g):(a.hasOwnProperty(f)&&"object"==typeof a[f]&&null!=a[f]||(a[f]=Array.isArray(e)?[]:{}),i(a[f],e,c,d))},this,c),a}}function j(a){if(this instanceof Date)return new Date(this);if(this instanceof RegExp)return new RegExp(this);var b=Array.isArray(this)?[]:{};return h.call(b,this,a),b}function k(){return Object.keys(this)}function l(a){var b=a?Object.keys(this):m.call(this);return b.map(function(a){return this[a]},this)}function m(){return Object.getOwnPropertyNames(this)}function n(a,b){for(var c=b?Object.keys(this):m.call(this),d=0;dd;d++){var e=b.charCodeAt(d);a=(a<<5)+a+e}return a}function unPrefix(a){return 0==this.indexOf(a)?this.replace(a,""):void 0}var __=require("./proto_object"),stringMethods=module.exports={firstUpperCase:firstUpperCase,firstLowerCase:firstLowerCase,toRegExp:toRegExp,toFunction:toFunction,toDate:toDate,toQueryString:toQueryString,fromQueryString:fromQueryString,jsonParse:jsonParse,hashCode:hashCode,unPrefix:unPrefix},regexpStringPattern=/^\/(.*)\/([gimy]*)$/},{"./proto_object":145}],148:[function(a,b){"use strict";function c(a,b){for(var c=Array(Math.max(0,this)),d=0;this>d;d++)c[d]=a.call(b,d);return c}function d(a){for(var b=Array(Math.max(0,a)),c=0;a>c;c++)b[c]=this;return b}function e(a){return a.call(this,this),this}function f(a){var b=Array.prototype.slice.call(arguments,1);return"function"==typeof this?this.apply(a,b):this}function g(){return this}function h(){var a=this;return function(b){return b[a]}}function i(){var a=this;return function(b,c){return b[a]c[a]?1:0}}function j(){}b.exports={times:c,repeat:d,tap:e,result:f,identity:g,property:h,compareProperty:i,noop:j}},{}],149:[function(a,b){"use strict";function c(a){return function(){return this.self=a.apply(this.self,arguments),this}}function d(a){return function(){return a.call.apply(a,arguments)}}function e(a,b){var c="value"==b?0:1;return function(b,d,e){function g(a,d,e){var g;try{g=b.call(this,a,d,e)}catch(i){throw h=i,f}if(g)throw arguments[c]}var h;try{a.call(this,g,d,e)}catch(i){if(i===f)throw h;return i}return c&&a==Array.prototype.forEach?-1:void 0}}var f=(b.exports={makeProtoInstanceMethod:c,makeProtoFunction:d,makeFindMethod:e},new Error)},{}],150:[function(a,b,c){arguments[4][141][0].apply(c,arguments)},{"./proto_array":151,"./proto_function":152,"./proto_number":153,"./proto_object":154,"./proto_prototype":155,"./proto_string":156,"./proto_util":157,"./utils":158}],151:[function(a,b,c){arguments[4][142][0].apply(c,arguments)},{"./proto_object":154,"./utils":158}],152:[function(a,b){b.exports=a(143)},{"./proto_util":157,"./utils":158}],153:[function(a,b){b.exports=a(144)},{}],154:[function(a,b){b.exports=a(145)},{"./utils":158}],155:[function(a,b,c){arguments[4][146][0].apply(c,arguments)},{"./proto_function":152,"./proto_object":154}],156:[function(a,b,c){arguments[4][147][0].apply(c,arguments)},{"./proto_object":154}],157:[function(a,b){b.exports=a(148)},{}],158:[function(a,b){b.exports=a(149)},{}]},{},[72]); +//# sourceMappingURL=milo.min.js.map \ No newline at end of file diff --git a/milo.min.js.map b/milo.min.js.map new file mode 100644 index 0000000..5cb35ad --- /dev/null +++ b/milo.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"milo.min.js","sources":["milo.bundle.js"],"names":["e","t","n","r","s","o","u","a","require","i","Error","f","exports","call","length",1,"module","Facet","owner","config","this","name","_","firstLowerCase","constructor","init","apply","arguments","extendProto","mol-proto",2,"FacetedObject","instantiateFacet","FacetClass","facetName","fctConfig","facetsConfig","facets","facetsDescriptors","enumerable","value","FacetError","facetsClasses","eachKey","Object","defineProperties","defineProperty","FacetedObject$addFacet","facetConfig","throwOnErrors","check","Function","Match","Optional","String","protoFacets","prototype","message","logger","error","newFacet","ENUM","FacetedObject$$hasFacet","FacetedObject$$getFacetConfig","hasFacet","FacetedObject$$createFacetedClass","addInheritedFacets","superClass","facetsInfo","facetsInfoName","inheritedFacetsInfo","clone","extend","ObjectHash","Subclass","fctName","hasOwnProperty","FacetedClass","createSubclass","createFacetedClass","getFacetConfig","addFacet","../util/check","../util/error","./facet",3,"Mixin","hostObject","proxyMethods","OneOf","_createProxyMethods","_createProxyMethod","proxyMethodName","mixinMethodName","_hostObject","MixinError","method","boundMethod","bind","WRIT","Array","isArray","forEach","methodName","Mixin_setInstanceKey","hostClass","instanceKey","IdentifierString","prop","mixin","instancePropertiesMap","instanceKeys","Mixin_addMethod","hostMethodName","wrappedMethod","_wrapMixinMethod","mixinInstance","_getMixinInstance","Mixin$$useWith","mixinMethods","useWith","../config",4,"ClassRegistry","FoundationClass","setClass","__registeredClasses","add","aClass","RegistryError","get","remove","nameOrClass","clean","Registry",5,"attrName","attrs","parse","node","bindTo","match","ATTRIBUTE_REGEXP","AttributeError","compClass","compFacets","split","FACETS_SPLIT_REGEXP","undefined","compName","validate","render","milo","util","componentName","ATTRIBUTE_TEMPLATE","replace","join","BindAttribute$$setInfo","el","componentClass","componentFacets","attr","BindAttribute","decorate","Attribute","setInfo","./a_class",6,"attributes","Attribute$$remove","deep","removeAttribute","selector","children","querySelectorAll","childEl","Attribute$remove","Attribute$destroy","Attribute$get","getAttribute","Attribute$set","setAttribute","Attribute$decorate","set","toBeImplemented","destroy",7,"load","loadUrl","LoadAttribute",8,"./a_bind","./a_load",9,"binder","scopeEl","rootScope","bindRootElement","createBinderScope","scope","info","ComponentInfo","Component","create","twoPass","scanScope","scan","Scope","_rootEl","addMethod","_each","compInfo","aComponent","container","scopeObjectFactory","createScopeForElement","postChildrenBoundMessage","elComp","getComponent","postMessageSync","scopedObject","isContainer","childNodes","innerScope","createScopeForChildren","containerEl","utilDom","document","body","componentsRegistry","Binder","./attributes/a_bind","./components/c_facets/cf_registry","./components/c_info","./components/c_registry","./components/scope","./services/mail","./util/check","./util/dom","./util/error",10,"classes","MessageSource","MessengerMessageSource","MessengerAPI","DOMEventsSource","Transaction","TransactionHistory","./abstract/facet","./abstract/faceted_object","./abstract/mixin","./abstract/registry","./command/transaction","./command/transaction_history","./components/msg_src/dom_events","./messenger/m_api","./messenger/m_source","./messenger/msngr_source",11,"ActionsHistory","maxLength","_maxLength","Infinity","actions","position","ActionsHistory$store","command","_truncateToCurrentPosition","push","act","shift","ActionsHistory$deleteLast","ActionsHistory$undo","cb","undo","ActionsHistory$redo","redo","ActionsHistory$undoAll","ActionsHistory$redoAll","ActionsHistory$undoAllAsync","deferMethod","defer","ActionsHistory$redoAllAsync","ActionsHistory$each","funcOrMethod","thisArg","func","ActionsHistory$eachReverse","reverse","each","ActionsHistory$getLastAction","ActionsHistory$getDescription","map","getDescription","store","deleteLast","undoAll","redoAll","undoAllAsync","redoAllAsync","eachReverse","getLastAction","../util/logger",12,"Command","commandsRegistry","../abstract/registry","./index",13,"Command$init","args","slice","Command$execute","result","Command$setUndo","undoCommand","UNDO_COMMAND","warn","Command$getUndo","Command$undo","undoCmd","getUndo","execute","Command$setArguments","toArray","Command$getArguments","Command$changeArguments","Command$addArguments","appendArray","Command$$create","newApply","Command$$createWithUndo","Command$destroy","Command$setComment","comment","Command$getDescription","setUndo","setArguments","addArguments","getArguments","changeArguments","setComment","createWithUndo",14,"commands","Transaction$execute","Transaction$undo","Transaction$redo","Transaction$destroy","Transaction$storeCommand","Transaction$merge","transaction","cmd","Transaction$setComment","Transaction$getDescription","storeCommand","merge","./actions_history",15,"transactions","currentBatch","currentTransaction","SCHEDULED","TransactionHistory$storeCommand","appendTransaction","_postTransactionMessage","_storeTransaction","TransactionHistory$deleteLastTransaction","_addBatchToTransaction","_storeCurrentTransaction","TransactionHistory$endTransaction","TransactionHistory$storeTransaction","endTransaction","msg","_messenger","postMessage","TransactionHistory$undo","TransactionHistory$redo","TransactionHistory$inTransaction","TransactionHistory$getDescription","TransactionHistory$useMessenger","Messenger","defaultMethods","TransactionHistory$destroy","storeTransaction","deleteLastTransaction","inTransaction","useMessenger","../messenger","./transaction",16,"Component$$createComponentClass","configMap","fct","keys","fctClassName","firstUpperCase","facetsRegistry","ComponentClass","_registerWithDomStorage","className","DOMStorage","registerDataType","Component_domStorageSerializer","Component_domStorageParser","component","state","getState","JSON","stringify","compStr","jsonParse","createFromState","Component$$create","ComponentError","extraFacetsClasses","Component$$copy","deepCopy","Boolean","newEl","dom","copy","cloneNode","createOnElement","extraFacets","_getState","setState","Component$$createOnElement","innerHTML","_createComponentElement","_findOrCreateComponentRootScope","_addAttributeAndBindComponent","broadcast","Dom","domFacetConfig","templateFacetConfig","template","elConfig","domConfig","content","createElement","parent","getContainingComponent","miloBinder","Component$$createFromState","newUniqueName","ObjectIncluding","facetsStates","outerHTML","wrapEl","_createComponentWrapElement","_any","_add","domUtils","compEl","miloComponentName","Component$$createFromDataTransfer","dataTransfer","dataType","find","types","type","COMPONENT_DATA_TYPE_REGEX","test","getData","Component$init","element","componentInfo","componentRef","messenger","MESSENGER_PROPERTY","allFacets","start","Component$start","Component$createElement","Component$hasFacet","facetNameOrClass","facet","ComponentFacet","Component$addFacet","facetClassName","Component$allFacets","mapKeys","Component$rename","renameInScope","rename","Component$remove","preserveScopeProperty","quiet","_remove","Component$insertInto","parentEl","referenceEl","insertBefore","setScopeParentFromDOM","Component$getState","rootComponent","Component$getTransferState","options","transfer","Component$_getState","deepState","filterKeys","fctState","Component$setState","Component$getScopeParent","conditionOrFacet","_callGetScopeParent","_getScopeParent","_getScopeParentFunc","conditionFunc","componentUtils","_makeComponentConditionFunc","Component$getScopeParentWithClass","comp","Component$getTopScopeParent","_getTopScopeParent","topParent","Component$getTopScopeParentWithClass","Component$setScopeParentFromDOM","foundParent","parentNode","Component$walkScopeTree","callback","walkScopeTree","Component$treePathOf","treePathOf","Component$getComponentAtTreePath","treePath","nearest","getNodeAtTreePath","Component$insertAtTreePath","wasInserted","insertAtTreePath","Component$broadcast","data","synchronously","postMethod","Component$destroy","_destroyed","detachComponent","removeElement","Component$isDestroyed","createComponentClass","isComponent","createFromDataTransfer","insertInto","getTransferState","getScopeParent","getTopScopeParent","getScopeParentWithClass","getTopScopeParentWithClass","getComponentAtTreePath","isDestroyed","../abstract/faceted_object","../attributes/a_bind","../binder","../util/component_name","../util/dom","../util/json_parse","../util/storage","./c_facets/cf_registry","./c_utils","./scope",17,"ComponentFacet$init","_createMessenger","ComponentFacet$start","messages","onConfigMessages","ComponentFacet$onConfigMessages","messageSubscribers","notYetRegisteredMap","subscriber","subscriberType","on","contextType","context","ComponentFacet$check","reqFacet","ComponentFacet$destroy","domParent","parentComponent","scopeParent","_postParent","getParentMethod","messageType","messageData","parentFacet","_setMessageSource","messageSource","getMessageSource","dispatchSourceMessage","dispatchMessage","_createMessageSource","MessageSourceClass","_createMessageSourceWithAPI","messengerAPIOrClass","requiresFacet","facetRequire","indexOf","postDomParent","partial","postScopeParent","../abstract/facet",18,"Container$binder","Container$start","Container$path","path","throwInvalidPath","len","allowedNamePattern","Container$getState","Container$setState","compData","Container$destroy","_detachElement","Container$unwrap","renameChildren","unwrapElement","child","Container$append","appendChild","Container$insertBefore","sibling","Container$remove","removeChild","Container","unwrap","append","../../binder","../../util/dom","../../util/logger","../c_facet","../scope","./cf_registry",19,"Data$start","pathUtils","wrapMessengerMethods","elData","getElementDataAccess","_dataChangesQueue","_prepareMessageSource","_path","_value","onSync","onOwnDataChange","onDataChangesFinished","onChildData","changeDataHandler","dataAPI","DataMsgAPI","dataEventsSource","proxyDataSourceMethods","msgType","_bubbleUpDataChange","_queueDataChange","getTransactionFlag","Data$_bubbleUpDataChange","msgData","parentData","parentMsg","Data$_queueDataChange","change","_postDataChanges","Data$_postDataChanges","queue","changes","Data$set","componentSetter","setTransactionFlag","_set","oldValue","newValue","Data$_set","setChildData","valueSet","childValue","key","pathSyntax","childPath","childDataFacet","listFacet","list","listLength","count","newItemsCount","_addItems","_updateDataPaths","index","listCount","removeCount","_removeItem","_setScalarValue","Data$del","componentDelete","del","postTransactionFinished","_del","Data$_del","Data$_setScalarValue","Data$get","deepGet","componentGetter","_get","Data$_get","scopeData","listItem","scopeItem","contains","_getScalarValue","Data$_getScalarValue","Data$splice","componentSplice","splice","_splice","spliceIndex","removed","addedCount","Data$_splice","spliceHowMany","modelUtils","normalizeSpliceIndex","item","itemData","added","argsLen","addItems","j","Data$len","componentLen","_len","Data$_len","Data$path","accessPath","createItem","parsedPath","parseAccessPath","currentComponent","pathNode","nodeKey","getPathNodeKey","syntax","itemComponent","_addItem","property","currentDataFacet","Data$getPath","Data$getKey","Data$getState","Data$setState","ModelPath","Data","getPath","getKey","trigger","../../abstract/mixin","../../messenger","../../model/change_data","../../model/m_path","../../model/model_utils","../../model/path_utils","../msg_api/data","../msg_api/de_data","../msg_src/dom_events",20,"Dom$$createElement","tagName","_applyConfigToElement","doT","cssClasses","cls","configAttributes","attrValue","_attachCssClasses","currentStyle","window","getComputedStyle","_visible","display","show","toggle","hide","doShow","style","_manageCssClasses","enforce","callMethod","cssCls","doToggle","classList","DomFacetError","detach","setStyle","setStyles","properties","isDeep","prepend","thisEl","firstChild","appendChildren","prependChildren","insertAfter","nextSibling","appendToScopeParent","Dom$children","direction","iterator","findDirections","treeWalker","createTreeWalker","NodeFilter","SHOW_ELEMENT","currentNode","nextNode","found","hasTextBeforeSelection","selection","getSelection","isCollapsed","text","focusNode","textContent","startPos","charAt","anchorOffset","SHOW_TEXT","anchorNode","prevNode","previousNode","isText","nodeValue","trim","hasTextAfterSelection","DomFacet","addCssClasses","removeCssClasses","toggleCssClasses","up","down","../../attributes/a_bind","../../config","../../util/check","../../util/error","dot",21,"Drag$init","_dragData","dataTypeInfo","_dataTypeInfo","Drag$setHandle","handleEl","_dragHandle","Drag$start","_addDragAttribute","onMessages","mousedown","onMouseDown","mouseenter mouseleave mousemove","onMouseMovement","dragstart","onDragStart","drag","onDragging","dragend","onDragEnd","getstatestarted","_removeDragAttribute","getstatecompleted","eventType","event","__mouseDownTarget","target","targetInDragHandle","empty","stopPropagation","shouldBeDraggable","setMeta","metaConfig","meta","paramsConfig","params","metaDataConfig","_dragMetaDataType","dt","setComponentMeta","_dragMetaData","setAdditionalDataTypes","dataTypes","_dataTypesData","getDataFunc","setData","off","preventDefault","DragDrop","setComponentState","_setAllowedEffects","service","dragDrop","dragFacet","_dragIsDisabled","effects","allowedEffects","setAllowedEffects","Drag","setHandle","../../util/dragdrop","../c_class",22,"Drop$init","DropMsgAPI","Drop$start","dragenter dragover","drop","onDrop","dragenter dragover dragleave drop dragin dragout","postToService","_handleDropDependency","setDropEffect","dropFacet","_handleDropDependencyNothrottle","originalDropComponent","allow","parentAllowed","checkParent","_isDropAllowed","allowComps","components","getComponentMeta","DropError","Drop","throttle","../msg_api/drop",23,"Events$init","domEventsSource","MSG_SOURCE_KEY","Events",24,"Frame$init","FrameMessageSource","Frame$start","postDomReady","self","Frame$destroy","Frame$getWindow","contentWindow","Frame$isReady","readyState","getWindow","Frame$isMiloReady","frameMilo","isReady","milo_version","Frame$milo","whenMiloReady","win","_makeWhenReadyFunc","isReadyFunc","callFunc","Frame","Frame$whenReady","Frame$whenMiloReady","whenReady","isMiloReady","../../services/de_constrs","../msg_src/frame",25,"ItemFacet$getState","getIndex","ItemFacet$setState","setIndex","ItemFacet$getIndex","ItemFacet$setIndex","ItemFacet$removeItem","removeItem","ItemFacet$extractItem","extractItem","ItemFacet","../../model","../../services/mail",26,"List$init","_listItems","_listItemsHash","List$start","onChildrenBound","items","itemsHash","foundItem","ListError","itemSample","LIST_SAMPLE_CSS_CLASS","miloConfig","_createCacheTemplate","List$_createCacheTemplate","itemElCopy","itemsTemplateStr","itemsTemplate","compile","List$item","List$count","List$_setItem","List$contains","List$addItem","List$_addItem","prevComponent","_itemPreviousComponent","_setItem","_updateItemsIndexes","fromIndex","toIndex","List$addItems","itemsData","concat","repeat","spliceArgs","dataFacet","List$_addItems","Integer","itemsHTML","miloUtil","frag","createDocumentFragment","newComponents","List$removeItem","List$extractItem","itemComp","List$_removeItem","doDestroyItem","List$replaceItem","newItem","oldItem","List$_updateDataPaths","List$each","List$destroy","List","addItem","replaceItem","../../util",27,"ModelFacet$init","m","Model","ModelFacet$getState","modelValue","deepClone","ModelFacet$setState","ModelFacet$_createMessenger","ModelFacet$destroy","ModelFacet",28,"Options$init","Options$_createMessenger","Options$destroy","Options",29,"Template$init","interpolate","compileOptions","Template$start","autoRender","autoBinder","Template$getCompiled","_template","Template$set","templateStr","_templateStr","_compile","Template$render","Template$binder","Template","getCompiled",30,"Transfer$init","_activeState","_defaultKey","_state","Transfer$getState","Transfer$setState","setActiveState","Transfer$setActiveState","Transfer$setStateWithKey","isDefaultKey","Transfer$getStateWithKey","Transfer$getComponentMeta","Transfer","setStateWithKey","getStateWithKey",31,"../../abstract/registry",32,"getComponentClass","getComponentExtraFacets","hasContainerFacet","ComponentInfo$destroy","ComponentInfo$rename","reportBinderError","BinderError","classHasFacetThatRequiresContainer","someKey","facetRequiresContainer","./c_registry",33,"./c_class",34,"returnCurrent","_getContainingComponent",35,"View","../c_registry",36,"DataMsgAPI$init","DataMsgAPI$value","translateToSourceMessage","componentEvent","filterSourceMessage","sourceMessage","createInternalData","internalData","../../messenger/m_api","./de_data",37,"inputDataProperty","inputType","inputElementTypes","byDefault","inputChangeEvent","toLowerCase","domElementsDataAccess","div","span","p","input","textarea","select","img","caption","thead","tbody","tfoot","tagInfo","propFunc","checkbox","radio",38,"dropEventsMap","resetFilterVars","_currentTarget","_inside","ok","dragin","dragout",39,"DOMEventsSource$destroy","emitter","DOMEmitterSource","../../messenger/m_source","../../services/dom_source",40,"FrameMessageSourceError","frameWindow","addSourceSubscriber","addEventListener","removeSourceSubscriber","removeEventListener","handleEvent",41,"rootEl","Scope$_add","object","ScopeError","checkName","__add","Scope$_safeAdd","shouldRename","Scope$_copy","aScope","Scope$_move","otherScope","Scope$_merge","Scope$_each","Scope$_filter","Scope$_length","Scope$_any","Scope$_remove","Scope$_clean","Scope$_detachElement","Scope$_has","Scope$$rename","obj","_safeAdd","_copy","_move","_merge","_length","_clean","_has","_filter",42,"MLButton$disable","disable","disabled","MLButton$isDisabled","MLButton","events","isDisabled",43,"MLCombo$init","_comboInput","_comboList","datalist","DATALIST_TEMPLATE","dispatchChangeMessage","MLCombo_get","MLCombo_set","changeComboData","MLCombo_del","COMBO_CHANGE_MESSAGE","onOptionsChange","comboOptions","model","MLCombo","***",44,"MLComboList$init","_dataValidation","once","MLComboList$setDataValidation","dataValidation","MLComboList$setOptions","arr","_combo","setOptions","MLComboList$clearComboInput","clearComboInput","MLComboList$toggleAddButton","toggleAddButton","MLComboList$setAddItemPrompt","prompt","setAddItemPrompt","MLComboList$destroy","_connector","minder","destroyConnector","componentSetup","combo","_list","onComboChange","onAddItem","onItemsChange","COMBO_LIST_CHANGE_MESSAGE","MLComboList_get","MLComboList_set","MLComboList_del","MLComboList","setDataValidation",45,"MLDate$getMin","date","min","MLDate$setMin","toDate","toISO8601Format","MLDate$getMax","max","MLDate$setMax","MLDate_get","MLDate_set","dispatchInputMessage","MLDate_del","pad","dateArr","getFullYear","getMonth","getDate","dateStr","MLDate","getMin","setMin","getMax","setMax",46,"MLDropTarget",47,"foldUnfold","itemMessage","id","_itemsMap","onItemEvent","MLFoldTree$setItemTemplate","_itemTemplate","MLFoldTree$renderTree","_renderTree","itemsIDs","miloCount","COMPILED_TREE_TEMPLATE","itemIDs","itemTemplate","DEFAULT_COMPILED_ITEM_TEMPLATE","treeTemplate","_data","TREE_TEMPLATE","MLFoldTree","click dblclick","setItemTemplate","renderTree","../../util/count",48,"MLGroup",49,"MLHyperlink",50,"MLImage$init","MLImage_set","MLImage_get","MLImage_del","IMAGE_CHANGE_MESSAGE","onModelChange","src","MLImage",".src",51,"MLInput$disable","MLInput$isDisabled","MLInput$setMaxLength","MLInput","setMaxLength",52,"MLInputList$init","MLInputList$setPlaceHolder","placeHolder","_input","MLInputList$setAsync","newHandler","asyncHandler","MLInputList$destroy","_button","button","onClick","label","INPUT_LIST_CHANGE_MESSAGE","MLInputList_get","MLInputList_set","MLInputList_del","MLInputList_splice","MLInputList","setAsync","setPlaceHolder",53,"MLList$init","MLList$destroy","MLList$removeItem","MLList$moveItem","from","to","splicedData","deferChangeMode","MLList","moveItem",54,"MLListItem$init","deleteBtn","MLListItem$removeItem","listOwner","MLListItem$moveItem","MLListItem$isDropAllowed","isComponentAllowed","isDropAllowed","onItemDrop","onDragOut","getComponentState","onDragHover","getMetaData","MLListItem_get","MLListItem_set","_sendChangeMessage","MLListItem_del","LISTITEM_CHANGE_MESSAGE","MLListItem","dragenter","dragover","dragleave",55,"MLRadioGroup$init","CONF","ELEMENT_NAME_PROPERTY","ELEMENT_NAME_PREFIX","_renderOptions","MLRadioGroup$setRenderOptions","MLRadioGroup_set","setResult","_radioList","checked","MLRadioGroup_get","MLRadioGroup_del","onGroupClick","RADIO_CHANGE_MESSAGE","radioOptions","elementName","radioEls","MLRadioGroup$destroy","MLRadioGroup","click","setRenderOptions",56,"MLSelect$setOptions","modelChangeListener","MLSelect$disable","selectOptions","MLSelect","**",57,"MLSuperCombo$init","_optionsData","_filteredOptionsData","_comboOptions","_comboBefore","before","_comboAfter","after","_comboAddItemDiv","addItemDiv","_comboAddPrompt","addPrompt","_comboAddBtn","addBtn","_optionTemplate","OPTIONS_TEMPLATE","_startIndex","_endIndex","MAX_RENDERED","_hidden","_elementHeight","DEFAULT_ELEMENT_HEIGHT","_total","_optionsHeight","_lastScrollPos","_currentValue","_selected","_isAddButtonShown","setupComboList","setupComboInput","setupComboBtn","changeSelected","MLSuperCombo$toggleOptions","MLSuperCombo$showOptions","COMBO_OPEN","MLSuperCombo$hideOptions","MLSuperCombo$toggleAddButton","preserveState","__showAddOnClick","MLSuperCombo$setAddItemPrompt","_addItemPrompt","MLSuperCombo$setOptions","setFilteredOptions","MLSuperCombo$initOptionsURL","_optionsURL","url","_formatOptionsURL","formatOptions","_getOptionsURL","queryString","noop","request","post","err","response","responseData","MLSuperCombo$setFilteredOptions","update","MLSuperCombo$update","wasHidden","arrToShow","hideOptions","beforeHeight","afterHeight","height","overflow","width","zIndex","onListClick","scroll","onListScroll","onDataChange","onInputClick","onEnterKey","btn","onAddBtn","MLSuperCombo_get","MLSuperCombo_set","MLSuperCombo_del","_updateOptionsAndAddButton","filteredData","_filterData","filter","option","selected","filteredArr","isExactMatch","showOptions","scrollTop","directionMap","keyCode","_changeSelected","scrollPos","selectedPos","offsetTop","relativePos","_getDataValueFromElement","thisItem","adjItem","onMouseOver","_mouseIsOver","onMouseLeave","_mouseOutTimer","clearInterval","setTimeout","_onMouseLeave","_setData","lastElementChild","lastChild","firstElementChild","lastElPosition","firstElPosition","distFromLastEl","distFromFirstEl","elsFromStart","Math","floor","elsToTheEnd","totalElementsBefore","BUFFER","Number","MLSuperCombo","mouseleave","mouseover","toggleOptions","initOptionsURL",58,"MLText",59,"MLTextarea$startAutoresize","_autoresize","_autoresizeOptions","_adjustAreaHeight","_manageSubscriptions","onOff","newHeight","scrollHeight","minHeight","maxHeight","MLTextarea$stopAutoresize","MLTextarea$isAutoresized","MLTextarea$disable","MLTextarea","startAutoresize","stopAutoresize","isAutoresized",60,"MLTime_get","timeStr","TIME_REGEX","hours","mins","time","Date","MLTime_set","TIME_TEMPLATE","getHours","getMinutes","MLTime_del","MLTime",61,"MLWrapper",62,"MLAlert$$createAlert","close","timeout","alert","MLAlert","_prepareOptions","alertCls","ALERT_CSS_CLASSES","_alert","visible","alertScope","closeBtn","_onCloseBtnClick","closeAlert","MLAlert$$openAlert","createAlert","openAlert","MLAlert$openAlert","_toggleAlert","MLAlert$closeAlert","addRemove","appendRemove","success","warning","danger","fixed","role","aria-hidden","../../../util/check","../../../util/component_name","../../../util/logger","../../c_class","../../c_registry",63,"MLDialog$$createDialog","initialize","title","html","backdrop","keyboard","buttons","Any","dialog","MLDialog","_dialog","dialogScope","_onBackdropClick","buttonSubscriber","_dialogButtonClick","_toggleDialog","_dispatchResult","closeDialog","_onKeyDown","openedDialog","DEFAULT_BUTTONS","CLOSE_OPTIONS","mapToObject","opt","MLDialog$$openDialog","createDialog","openDialog","dialogsInitialized","_initializeDialogs","backdropEl","MLDialog$openDialog","MLDialog$closeDialog","MLDialog$$getOpenedDialog","MLDialog$destroy","getOpenedDialog",64,"MLDropdown$start","onDocOut","relatedTarget","listeners","_dropdown","isIframe","hideMenu","toggleEl","querySelector","TOGGLE_CSS_CLASS","menuEl","MENU_CSS_CLASS","doc","clickHandler","toggleMenu","DOMListeners","menu","MLDropdown$destroy","removeAll","MLDropdown$showMenu","MLDropdown$hideMenu","MLDropdown$toggleMenu","MLDropdown","showMenu","../../../util/dom_listeners",65,"deepExtend","componentPrefix","domStorage","typeSuffix","prefixSeparator","root","messageKey","messageTimestamp","quotaExceeded","throwError","componentMetaTemplate","componentMetaRegex","jsonpTimeout","jsonpCallbackPrefix","optionsKey","defaults","websocket","rpc","responsePrefix","debug",66,"loader","_loader","miloMail","_loadViewsInElement","views","loadElements","totalCount","loadedCount","loadView","LoaderError","Loader","./attributes/a_load","./config","./util/logger","./util/request",67,"_initializeSubscribers","_messageSubscribers","_patternMessageSubscribers","Messenger$destroy","offAll","Messenger$on","_Messenger_onWithOptions","Messenger$once","dispatchTimes","Messenger$onceSync","sync","Messenger$onSync","Messenger$onAsync","RegExp","_Messenger_on","_eachMessage","messagesSplitRegExp","subscribersHash","_chooseSubscribersHash","changed","subscriptionChanged","_registerSubscriber","pattern","_messageSource","onSubscriberAdded","noSubscribers","msgSubscribers","notYetRegistered","_indexOfSubscriber","findIndex","subscr","Messenger$off","_Messenger_off","_removeSubscriber","subscriberIndex","_removeAllSubscribers","onSubscriberRemoved","offMessages","subscriberRemovedMap","Messenger$offAll","_offAllSubscribers","subscribers","_synchronous","_callSubscribers","_callPatternSubscribers","calledMsgSubscribers","patternSubscribers","_callSubscriber","syncSubscriber","synchro","__messages","getSubscribers","includePatternSubscribers","onceSync","onAsync","onMessage","offMessage","subscriptions","../abstract/mixin","./m_source",68,"MessengerAPI$destroy","addInternalMessage","internalMsgs","_internalMessages","removeInternalMessage","unexpectedNotificationWarning","messageIndex","getInternalMessages","sourceData",69,"_patternInternalMessages","_catchAllSubscribed","noPatternInternalMessages","internalMessages","internalMessagesHash","patternMessages","sourcePattern","MessengerRegexpAPI","./m_api",70,"messengerAPI","_prepareMessengerAPI","MessageSource$destroy","setMessenger","newSourceMessage","removedSourceMessage","api","shouldDispatch",71,"sourceMessenger","MessengerMessageSource$postMessage",72,"domReady","mail","core","registry","./attributes","./binder","./classes","./command","./components/c_class","./components/c_facet","./loader","./registry","./services/window","./use_components","./use_facets","./util","./util/create_component_class","milo-core",73,"flag","__inChangeTransaction","passTransactionFlag","fromFunc","toFunc","processChanges","notify","processTransaction","prepareTransaction","validateTransaction","changeFinished","source","sameSource","checkChange","checkSplice","checkMethod","parentPathChanged","pathsToChange","some","parentPath","_pathIsParentOf","todo","exitLoop","pathsToSplice","hadSplice","parentPathSpliced","every","processChange","modelPath","executeSplice","executeMethod","howMany","CHANGE_TYPE_TO_METHOD_MAP","deleted","../components/c_facets/cf_registry","./path_utils",74,"Model$path","__proto__","_options","reactive","_prepareMessengers","Model$get","proxyMessenger","modelHostObject","Model$$useWith","modelMethodsToProxy","internalMessenger","internalMessengerSource","ModelMsgAPI","externalMessenger","_getHostObject","Model$$registerWithDOMStorage","Model_domStorageSerializer","Model_domStorageParser","valueStr","Model$destroy","_internalMessenger","synthesize","modelMethods","Path","registerWithDOMStorage","../messenger/msngr_source","./change_data","./m_msg_api","./m_path","./synthesize",75,"createRegexPath","../messenger/m_api_rx",76,"ModelPath$path","_model","_args","interpolateAccessPath","_prepareMessenger","methods","freeze","reduce","accessPathStr","currNode","thisPathArgsCount","str","newPath","ModelPath$len","ModelPath$push","newLength","ModelPath$pop","ModelPath$unshift","ModelPath$shift","mPathAPI","ModelPathMsgAPI","_accessPath","modelMessageSource","mPathMessenger","_getDefinition","_createFromDefinition","definition","ModelPath$destroy","pop","unshift","./path_msg_api",77,78,"rootPath","internalChanges","truncateChangePath","fullPath","unPrefix","../messenger/m_api",79,"nodeParsePattern","pathParsePattern","unparsed","nodeStr","pathNodeTypes","ModelError","patternPathParsePattern","regexStr","patternsStarted","regex","nodeRegex","interpolated","startIndex","methodsNames","wrappedMethods","origMethod","regexPath","propertyPathSyntax","arrayPathSyntax","interpolationSyntax","propertyInterpolateSyntax","arrayInterpolateSyntax","propertyStarSyntax","arrayStarSyntax","starSyntax","pathParseSyntax","patternPathParseSyntax",".","[","*",".*","[*]",80,"_synthesizePathMethods","synthesizers","synthszr","_synthesize","synthesizer","addChangeMessage","messagesHash","addTreeChangesMessages","oldIsTree","valueIsTree","newIsTree","addMessages","valueProp","_addMessages","addMessage","existingMsg","cloneTree","valueIsNormalObject","protectValue","addBatchIdsToMessage","batchId","msgId","__batch_id","__msg_id","methodCode","eval","fs","templates","include_defines","include_create_tree","include_traverse_tree","dotDef","modelAccessPrefix","modelPostMessageCode","modelPostBatchCode","modelDotDef","dotSettings","templateSettings","strip","tmpl","modelSynthesizers","synthesizePathMethods","memoize","../change_data","../model_utils","../path_utils",81,"./command/cmd_registry",82,"eventTypes","ClipboardEvent","Event","FocusEvent","KeyboardEvent","MouseEvent","TouchEvent","global","eTypes","eventConstructorName","eventConstructor","makeFunction","domEventsConstructors",83,"eventEmitter","DOMEmitterSource$destroy","sourceSubscriberMethod","capture","useCapturePattern","isCapturePhase","eventPhase","CAPTURING_PHASE","useCapturePostfix","DOMEmitterSource$postMessage","EventConstructor","domEvent","notCancelled","dispatchEvent","../components/c_class","../messenger/m_source","./de_constrs",84,"MailMsgAPI","MailMessageSource","mailMsgSource","./mail_api","./mail_source",85,"windowMessageRegExp","windowMessagePrefix",86,"isReadyStateChange","readystatechange","_windowSubscriberMethod","isWindowMessage","../de_constrs",87,"windowService_isTop","top","__karma__","windowService","domEmitterSource","isTop","./dom_source",88,"./components/classes/View","./components/ui/Button","./components/ui/Combo","./components/ui/ComboList","./components/ui/Date","./components/ui/DropTarget","./components/ui/FoldTree","./components/ui/Group","./components/ui/Hyperlink","./components/ui/Image","./components/ui/Input","./components/ui/InputList","./components/ui/List","./components/ui/ListItem","./components/ui/RadioGroup","./components/ui/Select","./components/ui/SuperCombo","./components/ui/Text","./components/ui/Textarea","./components/ui/Time","./components/ui/Wrapper","./components/ui/bootstrap/Dropdown",89,"./components/c_facets/Container","./components/c_facets/Data","./components/c_facets/Dom","./components/c_facets/Drag","./components/c_facets/Drop","./components/c_facets/Events","./components/c_facets/Frame","./components/c_facets/Item","./components/c_facets/List","./components/c_facets/ModelFacet","./components/c_facets/Options","./components/c_facets/Template","./components/c_facets/Transfer",90,"choices","Where","condition","Superclass","matchSuperclassToo","matchSuperclass","checkSubtree","typeofChecks","_jsKeywords","valueElement","_prependPath","unknownKeysAllowed","keyPattern","emptyHash","requiredPatterns","optionalPatterns","subPattern","subValue","base","TypeError",91,"prefix","./count",92,"uniqueCount","newTimestamp","now","uniqueID","timestamp",93,"componentRegistry","SuperClass","superClassName","staticMethods",94,"filterNodeListByType","Node","ELEMENT_NODE","nodeList","nodeType","containingElement","selectElementContents","ownerDocument","range","createRange","selectNodeContents","getNodeWindow","sel","removeAllRanges","addRange","selectElementText","fromNode","firstTextNode","toNode","lastTextNode","setSelection","setCaretPosition","pos","setStart","getSelectionDirection","_getDirection","focusOffset","startOffset","endOffset","docPosition","compareDocumentPosition","DOCUMENT_POSITION_FOLLOWING","DOCUMENT_POSITION_PRECEDING","originalContentEditable","backward","setEnd","collapse","commonAncestorContainer","parentElement","isContentEditable","contentEditable","clearSelection","getElementOffset","includeBorder","yPos","xPos","offsetLeft","offsetParent","getBorder","topOffset","leftOffset","side","styles","sideValue","parseInt","getPropertyValue","normalize","TEXT_NODE","replaceChild","wrapInElement","wrapIntoEl","trimNodeRight","_trimNode","trimNodeLeft","stripHtml","walkTree","tw","containsEl","nodeIndex","childIndex","toNormalize","isTreePathBefore","path1","path2","isBefore","htmlEntities","charCodeAt","whatToShow","defaultView","parentWindow","forEachNodesInRange","isNodeInsideRange","nodeRange","isInside","selectNode","compareBoundaryPoints","Range","START_TO_START","END_TO_END","rangeContainer","getComponentsFromRange","startContainer","deleteRangeWithComponents","deleteContents","areRangesEqual","range1","range2","addDebugPoint","x","y","dbEl","./logger",95,"DOMListeners$add","handler","DOMListeners$remove","listener","idx","isEqual","_removeListener","DOMListeners$removeAll","l","./check",96,"domReadySubscribed","onDomReady","domReadyFuncs",97,"DragDrop$$componentDataType","dragDropConfig","DragDrop$isComponent","componentDataType","DragDrop$getComponentState","stateStr","DragDrop$setComponentState","requestedBy","DragDrop$setComponentMeta","_componentMeta","paramsStr","toQueryString","_encode","base32","encode","DragDrop$getComponentMeta","metaDataType","dType","decode","fromQueryString","metaData","DragDrop$getAllowedEffects","effectAllowed","DragDrop$setAllowedEffects","DragDrop$getDropEffect","dropEffect","DragDrop$setDropEffect","effect","DragDrop$isEffectAllowed","getAllowedEffects","isCopy","isMove","isLink","isAllowed","DragDrop$getData","DragDrop$setData","dataStr","DragDrop$clearData","clearData","onDragDropStarted","_currentDragDrop","_currentDragFacet","onDragDropCompleted","onCompleteDragDrop","dragDropService","getCurrentDragDrop","DragDrop_destroy","getDropEffect","isEffectAllowed","dragdropstarted","dragdropcompleted","completedragdrop","./json_parse",98,"error$createClass","errorClassName","ErrorClass","makeSubclass","error$toBeImplemented","AbstractClass","errorClassNames","createClass",99,"fragment_getState","wrapperClassName","_getRangeContainer","cloneContents","wrapper","_wrapFragmentInContainer","_transferStates","_renameChildren","wrapperState","fragment_getStateAsync","fromComp","toComp","fromScope","toChildComp","fromChildComp","expandRangeToSiblings","siblings","getRangeSiblings","createRangeFromSiblings","nodes","setStartBefore","setEndAfter","end","containerNode","startNode","endNode","endContainer","startSibling","_findContainingChild","endSibling","selNode","_createNodesAndPathsFunc","fromObj","toObj","createRangePaths","createRangeNodes","getStateAsync","createRangeFromNodes","./dom",100,"util_destroy","uniqueId","domListeners","fragment","storage","../components/ui/bootstrap/Alert","../components/ui/bootstrap/Dialog","./component_name","./dom_listeners","./domready","./dragdrop","./error","./fragment","./request","./selection","./storage","./websocket",101,102,"Logger","level","./logger_class",103,"maxLevelLength","colored","color","levels","colors","DEFAULT_OPTIONS","throwLevel","enabled","logPrefix","opts","log","console","logPrefixColor",104,"createPromiseOverride","functionName","promise","Promise","keepRequestObject","_request","onReady","_onReady","req","xPromise","contentType","XMLHttpRequest","open","setRequestHeader","setRequestHeaders","headers","onreadystatechange","ontimeout","onabort","_createXPromise","send","_pendingRequests","resolvePromise","rejectPromise","resolve","reject","then","promiseThen","promiseCatch","status","responseText","spliceItem","errorReason","reason","request$useMessenger","request$get","request$post","request$json","jsonPromise","errData","request$jsonp","_onResult","uniqueCallback","cleanUp","clearTimeout","head","script","jsonpOptions","omitKeys","request$file","fileData","progress","upload","onprogress","file","binary","formData","FormData","request$destroy","whenRequestsCompleted","delay","json","jsonp",105,"TextSelection","TextSelection$init","rangeCount","getRangeAt","TextSelection$text","_text","toString","TextSelection$textNodes","_textNodes","_getTextNodes","TextSelection$clear","textNodes","selStart","selEnd","inEnd","_getElement","thisPropName","rangePropName","_getComponent","elMethodName","TextSelection$containedComponents","_containedComponents","TextSelection$eachContainedComponent","containedComponents","TextSelection$del","selectEndContainer","selPoint","_getPostDeleteSelectionPoint","_selectAfterDelete","selOffset","offset","trimRight","TextSelection$getRange","TextSelection$getState","createStateObject","TextSelection$$createStateObject","_getSelectionPointState","TextSelection$$createFromState","_selectionNodeFromState","pointState","TextSelection$$createFromRange","endRange","cloneRange","TextSelection$$getNormalizedRange","newRange","TextSelection$$getDirection","TextSelection$startElement","TextSelection$endElement","TextSelection$containingElement","TextSelection$startComponent","TextSelection$endComponent","TextSelection$containingComponent","clear","startElement","endElement","startComponent","endComponent","containingComponent","eachContainedComponent","getRange","getNormalizedRange","getDirection","createFromRange","../../components/c_class","../dom","../logger",106,"keyPrefix","sessionOnly","_storage","sessionStorage","localStorage","_typeSuffix","_keys","DOMStorage$set","setItem","DomStorageError","DOMStorage$get","deepForEach","getItem","DOMStorage$remove","DOMStorage$hasItem","pKey","_storageKey","DOMStorage$getItem","_getKeyDataType","_parseData","DOMStorage$setItem","_setKeyDataType","_serializeData","cfg","_domStorage","DOMStorage$removeItem","_removeKeyDataType","DOMStorage$getAllKeys","storedKeys","keysInStorage","hasItem","DOMStorage$getAllItems","getAllKeys","DOMStorage$_storageKey","DOMStorage$_domStorageKey","storageKey","_dataTypeKey","_getValueType","valueType","valuesDataTypes","serializer","dataSerializers","parser","dataParsers","DOMStorage$$registerDataType","storeAsDataType","DOMStorage$createMessenger","storageMessageSource","StorageMessageSource","DOMStorage$destroy","_storedKeys","true","false","_domStorageKey","getAllItems","createMessenger","_sessionStorage","_localStorage","local","session","valStr","boolean","number","function","toFunction","toRegExp","../check","../error","../json_parse","./model","./msg_src",107,108,"StorageMessageSourceError","StorageMessageSource$addSourceSubscriber","StorageMessageSource$removeSourceSubscriber","StorageMessageSource$postMessage","StorageMessageSource$trigger","storageArea",109,"wsMessenger","wsMsgSource","WSMessageSource","connect","WSMsgAPI","./msg_api",110,"SOCKET_MESSAGES",111,"WSMessageSource$connect","host","location","port","_ws","onopen","ws","onmessage","onclose","onerror","WebSocket","_wsSubscriberMethod","WSMessageSource$handleEvent","WSMessageSource$trigger","onTimeout","toggleRpcSubscription","callbackCorrId","onResponse","interval","corrId",112,"Encoder","skip","bits","output","readByte","byte","alphabet","finish","Decoder","readChar","char","fromCharCode","val","lookup","encoder","decoder","alias","table","flush",113,114,"resolveDefs","c","block","def","define","code","assign","substring","defineParams","param","v","arg","use","useParams","d","rw","__exp","unescape","_globals","version","evaluate","conditional","iterate","varname","selfcontained","doNotSkipEncoded","encodeHTMLSource","encodeHTMLRules","&","<",">","\"","'","/","matchHTML","amd","startend","startencode","needhtmlencode","indv","cse","sid","elsecase","vname","iname","_encodeHTML",115,"InstallDots","__path","__destination","destination","__global","__rendermodule","rendermodule","__settings","__includes","addexports","ret","readdata","readFileSync","process","compileAll","compileToFile","fn","modulename","lastIndexOf","defs","settings","compileoptions","defaultcompiled","compiled","writeFileSync","compilePath","k","defFolder","sources","readdirSync","./doT",116,117,"./messenger/m_api_rx",118,119,120,121,122,123,124,"./messenger","./minder",125,"ds1","mode","ds2","connDescriptions","connectors","descr","Connector","_addConnector","cnct","___minder_id","_connectors","onConnectorMessage","connector","_receivedMessages","_isPropagating","_idleCheck","minder_isPropagating","minder_whenPropagationCompleted","executeCallback","minder_getConnectors","isOn","minder_destroyConnector","minder_getExpandedConnections","searchStr","getConnectors","connections","connection","leftSource","_getExpandedSource","rightSource","cnctn","_sourceMatchesString","ds","matchStr","srcNode","_stringMatch","substr","minder_destroy","destroyDS","getExpandedConnections","isPropagating","whenPropagationCompleted","./model/connector",126,127,"setupMode","_changesQueue1","_changesQueue2","pathTranslation","patternTranslation","getPatternTranslations","pathTranslation1","reverseTranslationRules","pathTranslation2","patternTranslation1","reversePatternTranslationRules","patternTranslation2","dataTranslation","dataTranslation1","dataTranslation2","dataValidation1","dataValidation2","turnOn","modeParseError","parsedMode","modePattern","depth1","depth2","Connector$changeMode","turnOff","Connector$deferChangeMode","rules","reverseRules","path2_value","path1_key","_throwInvalidTranslation","_getStaticPath","starIndex1","starIndex2","fromPattern","fromStaticPath","toPattern","toStaticPath","pt","Connector$turnOn","linkDataSource","reverseLink","fromDS","toDS","changesQueue","onData","batch","translatePath","sourcePath","translatedPath","pTranslation","subscriptionPattern","translateData","translate","validateData","callValidator","validator","alreadyFailed","valid","passedCount","validators","propagateData","sendData","postChangeData","subscriptionSwitch","mergeTransactions","batches","targetPath","subscriptionPath","_subscriptionPath","_link1","_link2","Connector$turnOff","unlinkDataSource","linkName","Connector$destroy","changeMode",128,129,130,131,132,133,134,135,136,137,138,139,140,141,"Proto","wrapped","unwrapProto","utils","prototypeMethods","objectMethods","arrayMethods","functionMethods","stringMethods","numberMethods","utilMethods","__","_constants","protoFuncs","makeProtoFunction","protoInstanceMethods","makeProtoInstanceMethod","underscore","./proto_array","./proto_function","./proto_number","./proto_object","./proto_prototype","./proto_string","./proto_util","./utils",142,"arrayToAppend","prependArray","arrayToPrepend","values","valuesIsArray","unique","itemIndex","filtered","it","itemIndexOf","_deepForEach","nativeArrayMethodsNames","nativeArrayMethods","makeFindMethod",143,"arg1","arg2","funcBody","partialRight","hashFunc","limit","cache","keysList","wait","_delay","deferTicks","ticks","deferFunc","delayMethod","funcOrMethodName","_delayMethod","delayed","passArgs","deferred","debounce","immediate","later","last","callNow","previous","leading","remaining","trailing","memo","ran","waitFor","maxTimeout","timedOutFunc","checkInterval","testCondition","setInterval","not",144,"isNumeric","isNaN","parseFloat","isFinite",145,"onlyEnumerable","descriptors","getOwnPropertyDescriptor","clonedObject","propertyName","decriptorFlags","_getDescriptor","descriptor","constants","ENUMERABLE","configurable","CONFIGURABLE","writable","WRITABLE","propertyValues","_extendTree","selfNode","objNode","objTraversed","loop","allKeys","getOwnPropertyNames","keyOf","searchElement","allKeysOf","mapProperty","reduceKeys","initialValue","filterProperty","testProperty","_passed","everyKey","_didNotPass","pickKeys","ArrayProto","multiline","ignoreCase","isNot","findValue","findKey",146,"propDescriptors","applyConstructor","thisClass","subclass","constructorCode",147,"toUpperCase","rx","regexpStringPattern","getTime","qs","encodeURIComponent","pairs","results","decodeURIComponent","pair","splitPair","hashCode","hash",148,"times","tap","identity","compareProperty","b",149,"eachMethod","findWhat","argIndex","testItem","caughtError","_error",150,151,152,153,154,155,156,157,158],"mappings":"CAAC,QAAUA,GAAEC,EAAEC,EAAEC,GAAG,QAASC,GAAEC,EAAEC,GAAG,IAAIJ,EAAEG,GAAG,CAAC,IAAIJ,EAAEI,GAAG,CAAC,GAAIE,GAAkB,kBAATC,UAAqBA,OAAQ,KAAIF,GAAGC,EAAE,MAAOA,GAAEF,GAAE,EAAI,IAAGI,EAAE,MAAOA,GAAEJ,GAAE,EAAI,MAAM,IAAIK,OAAM,uBAAuBL,EAAE,KAAK,GAAIM,GAAET,EAAEG,IAAIO,WAAYX,GAAEI,GAAG,GAAGQ,KAAKF,EAAEC,QAAQ,SAASZ,GAAG,GAAIE,GAAED,EAAEI,GAAG,GAAGL,EAAG,OAAOI,GAAEF,EAAEA,EAAEF,IAAIW,EAAEA,EAAEC,QAAQZ,EAAEC,EAAEC,EAAEC,GAAG,MAAOD,GAAEG,GAAGO,QAAkD,IAAI,GAA1CH,GAAkB,kBAATD,UAAqBA,QAAgBH,EAAE,EAAEA,EAAEF,EAAEW,OAAOT,IAAID,EAAED,EAAEE,GAAI,OAAOD,KAAKW,GAAG,SAASP,EAAQQ,GAC/a,YAeA,SAASC,GAAMC,EAAOC,GAClBC,KAAKC,KAAOC,EAAEC,eAAeH,KAAKI,YAAYH,MAC9CD,KAAKF,MAAQA,EACbE,KAAKD,OAASA,MACdC,KAAKK,KAAKC,MAAMN,KAAMO,WAhB1B,GAAIL,GAAId,EAAQ,YAEhBQ,GAAOJ,QAAUK,EAqBjBK,EAAEM,YAAYX,GACVQ,KAAM,iBAGPI,YAAY,MAAMC,GAAG,SAAStB,EAAQQ,GACzC,YAsBA,SAASe,KA4BL,QAASC,GAAiBC,EAAYC,GAElC,GAAIC,GAAYC,EAAaF,EAG7BG,GAAOH,GAAa,GAAID,GAAWb,KAAMe,GAGzCG,EAAkBJ,IACdK,YAAY,EACZC,MAAOH,EAAOH,IAnCtB,GAAIE,GAAehB,KAAKgB,iBAEpBE,KACED,IAIN,IAAIjB,KAAKI,aAAeO,EACpB,KAAM,IAAIU,GAAW,4DAGrBrB,MAAKsB,eACLpB,EAAEqB,QAAQvB,KAAKsB,cAAeV,EAAkBZ,MAAM,GAG1DwB,OAAOC,iBAAiBzB,KAAMkB,GAG9BhB,EAAEwB,eAAe1B,KAAM,SAAUiB,GAG7BjB,KAAKK,MACLL,KAAKK,KAAKC,MAAMN,KAAMO,WAqD9B,QAASoB,GAAuBd,EAAYe,EAAad,EAAWe,GAChEC,EAAMjB,EAAYkB,UAClBD,EAAMhB,EAAWkB,EAAMC,SAASC,SAGhCpB,EAAYZ,EAAEC,eAAeW,GAAaD,EAAWZ,KAGrD,IAAIkC,GAAcnC,KAAKI,YAAYgC,UAAUd,aAG7C,IAAIa,GAAeA,EAAYrB,GAC3B,KAAM,IAAIO,GAAW,SAAWP,EAAY,iCAAmCd,KAAKI,YAAYH,KAGpG,IAAID,KAAKc,GAAY,CACjB,GAAIuB,GAAU,SAAWvB,EAAY,+BACrC,IAAIe,KAAkB,EAClB,MAAOS,QAAOC,MAAM,2BAA4BF,EAEhD,MAAM,IAAIhB,GAAWgB,GAI7B,GAAIG,GAAWxC,KAAKiB,OAAOH,GAAa,GAAID,GAAWb,KAAM4B,EAK7D,OAFA1B,GAAEwB,eAAe1B,KAAMc,EAAW0B,EAAUtC,EAAEuC,MAEvCD,EAYX,QAASE,GAAwB5B,GAE7B,GAAIqB,GAAcnC,KAAKoC,UAAUd,aACjC,OAAOa,IAAeA,EAAYrB,GAStC,QAAS6B,GAA8B7B,GACnC,MAAOd,MAAK4C,SAAS9B,GAAad,KAAKoC,UAAUpB,aAAaF,GAAa,KAe/E,QAAS+B,GAAkC5C,EAAMqB,EAAeN,GA4B5D,QAAS8B,GAAmBC,EAAYC,EAAYC,GAChD,GAAIC,GAAsBH,EAAWX,UAAUa,EAC/C,OAAIC,GACOhD,EAAEgD,GACAC,QACAC,OAAOJ,OAAkB9C,IAE3B8C,EAlCflB,EAAM7B,EAAMiC,QACZJ,EAAMR,EAAeU,EAAMC,SAASD,EAAMqB,WAAWrB,EAAMsB,SAASzD,GAAO,MAC3EiC,EAAMd,EAAcgB,EAAMC,SAAST,SAG/BR,GACAd,EAAEqB,QAAQP,EAAc,SAASD,EAAWwC,GACxC,IAAMjC,EAAckC,eAAeD,GAC/B,KAAM,IAAIlC,GAAW,4BAA8BkC,EAAU,kCAIzE,IAAIE,GAAevD,EAAEwD,eAAe1D,KAAMC,GAAM,EAYhD,OATAqB,GAAgBwB,EAAmB9C,KAAMsB,EAAe,iBACxDN,EAAe8B,EAAmB9C,KAAMgB,EAAc,gBAGtDd,EAAEM,YAAYiD,GACVnC,cAAeA,EACfN,aAAcA,IAGXyC,EA/LX,GAAI5D,GAAQT,EAAQ,WACdc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MACdX,EAAajC,EAAQ,iBAAiBS,KAE5CD,GAAOJ,QAAUmB,EA+DjBT,EAAEkD,OAAOzC,GACLgD,mBAAoBd,EACpBD,SAAUF,EACVkB,eAAgBjB,IASpBzC,EAAEM,YAAYG,GACVkD,SAAUlC,MA2HXmC,gBAAgB,GAAGC,gBAAgB,GAAGC,UAAU,EAAEvD,YAAY,MAAMwD,GAAG,SAAS7E,EAAQQ,GAC3F,YA0BA,SAASsE,GAAMC,EAAYC,GACvBtC,EAAMqC,EAAYnC,EAAMC,SAASD,EAAMqC,MAAM7C,OAAQO,YAGrD7B,EAAEwB,eAAe1B,KAAM,cAAemE,GAGlCC,GACApE,KAAKsE,oBAAoBF,GAGzBpE,KAAKK,MACLL,KAAKK,KAAKC,MAAMN,KAAMO,WAmC9B,QAASgE,GAAmBC,EAAiBC,EAAiBN,GAI1D,GAHAA,EAAaA,GAAcnE,KAAK0E,YAG5BP,EAAWK,GACX,KAAM,IAAIG,GAAW,UAAYH,EACR,kCAE7B,IAAII,GAAS5E,KAAKyE,EAClB3C,GAAM8C,EAAQ7C,SAGd,IAAI8C,GAAcD,EAAOE,KAAK9E,KAE9BE,GAAEwB,eAAeyC,EAAYK,EAAiBK,EAAa3E,EAAE6E,MAUjE,QAAST,GAAoBF,EAAcD,GACvCrC,EAAMsC,EAAcpC,EAAMC,SAASD,EAAMqC,OAAOnC,QAASF,EAAMqB,WAAWnB,WAGtE8C,MAAMC,QAAQb,GACdA,EAAac,QAAQ,SAASC,GAG1BZ,EAAmB9E,KAAKO,KAAMmF,EAAYA,EAAYhB,IACvDnE,MAEHE,EAAEqB,QAAQ6C,EAAc,SAASK,EAAiBD,GAG9CD,EAAmB9E,KAAKO,KAAMwE,EAAiBC,EAAiBN,IACjEnE,MAaX,QAASoF,GAAqBC,EAAWT,EAAQU,GAC7CxD,EAAMuD,EAAWtD,UACjBD,EAAMwD,EAAatD,EAAMuD,iBAEzB,IAAIC,GAAOzF,EAAO0F,MAAMC,sBAClBC,EAAeN,EAAUG,GAAQH,EAAUG,MAEjD,IAAIG,EAAaf,EAAO3E,MACpB,KAAM,IAAIX,OAAM,iDACVsF,EAAO3E,KAAO,kBAExB0F,GAAaf,EAAO3E,MAAQqF,EAahC,QAASM,GAAgBP,EAAWC,EAAab,EAAiBoB,GAC9D,GAAIjB,GAAS5E,KAAKoC,UAAUqC,EAC5B3C,GAAM8C,EAAQ7C,SAEd,IAAI+D,GAAgBC,EAAiBtG,KAAKO,KAAM4E,EAEhD1E,GAAEwB,eAAe2D,EAAUjD,UAAWyD,EAAgBC,EAAe5F,EAAE6E,MAEvEK,EAAqBC,EAAWT,EAAQU,GAW5C,QAASS,GAAiBnB,GACtB,MAAO,YACH,GAAIoB,GAAgBC,EAAkBxG,KAAKO,KAAM4E,EAAO3E,KACxD,OAAO2E,GAAOtE,MAAM0F,EAAezF,YAa3C,QAAS0F,GAAkBd,GACvB,GAAInF,eAAgBkE,GAAO,MAAOlE,KAClC,IAAI2F,GAAe3F,KAAKI,YAAYL,EAAO0F,MAAMC,sBACjD,OAAO1F,MAAK2F,EAAaR,IAY7B,QAASe,GAAeb,EAAWC,EAAaa,GAC5CrE,EAAMqE,EAAcnE,EAAMC,SAASD,EAAMqC,OAAOnC,QAASF,EAAMqB,WAAWnB,WAEtE8C,MAAMC,QAAQkB,GACdA,EAAajB,QAAQ,SAASC,GAC1BS,EAAgBnG,KAAKO,KAAMqF,EAAWC,EAAaH,EAAYA,IAChEnF,MAEHE,EAAEqB,QAAQ4E,EAAc,SAAS1B,EAAiBoB,GAC9CD,EAAgBnG,KAAKO,KAAMqF,EAAWC,EAAab,EAAiBoB,IACrE7F,MA/MX,GAAIE,GAAId,EAAQ,aACV0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MACd2C,EAAavF,EAAQ,iBAAiB8E,MACtCnE,EAASX,EAAQ,YAGvBQ,GAAOJ,QAAU0E,EAwCjBhE,EAAEM,YAAY0D,GACVK,mBAAoBA,EACpBD,oBAAqBA,IAUzBpE,EAAEkD,OAAOc,GACLkC,QAASF,MAsJVG,YAAY,GAAGvC,gBAAgB,GAAGC,gBAAgB,GAAGtD,YAAY,MAAM6F,GAAG,SAASlH,EAAQQ,GAC9F,YAiBA,SAAS2G,GAAeC,GAChBA,GACAxG,KAAKyG,SAASD,GAElBxG,KAAK0G,uBA8BT,QAASC,GAAIC,EAAQ3G,GAKjB,GAJAA,EAAOA,GAAQ2G,EAAO3G,KAEtB6B,EAAM7B,EAAM+B,EAAMuD,iBAAkB,yCAEhCvF,KAAKwG,gBAIL,KAAM,IAAIK,GAAc,iEAE5B,IALQD,GAAU5G,KAAKwG,iBACf1E,EAAM8E,EAAQ5E,EAAMsB,SAAStD,KAAKwG,iBAAkB,oDAIxDxG,KAAK0G,oBAAoBzG,GACzB,KAAM,IAAI4G,GAAc,UAAY5G,EAAO,0BAE/CD,MAAK0G,oBAAoBzG,GAAQ2G,EAUrC,QAASE,GAAI7G,GAET,MADA6B,GAAM7B,EAAMiC,OAAQ,6BACblC,KAAK0G,oBAAoBzG,GAUpC,QAAS8G,GAAOC,GACZlF,EAAMkF,EAAahF,EAAMqC,MAAMnC,OAAQH,UAAW,iCAElD,IAAI9B,GAA6B,gBAAf+G,GACIA,EACAA,EAAY/G,IAElC,KAAMD,KAAK0G,oBAAoBzG,GAC3B,KAAM,IAAI4G,GAAc,iCAErB7G,MAAK0G,oBAAoBzG,GAOpC,QAASgH,KACLjH,KAAK0G,uBAST,QAASD,GAASD,GACd1E,EAAM0E,EAAiBzE,UACvB7B,EAAEwB,eAAe1B,KAAM,kBAAmBwG,EAAiBtG,EAAEuC,MAlHjE,GAAIvC,GAAId,EAAQ,aACVyH,EAAgBzH,EAAQ,iBAAiB8H,SACzCpF,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,KAEpBpC,GAAOJ,QAAU+G,EA2BjBrG,EAAEM,YAAY+F,GACVI,IAAKA,EACLG,IAAKA,EACLC,OAAQA,EACRE,MAAOA,EACPR,SAAUA,MAgFX3C,gBAAgB,GAAGC,gBAAgB,GAAGtD,YAAY,MAAM0G,GAAG,SAAS/H,EAAQQ,GAC/E,YAoEA,SAASwH,KACL,MAAOrH,GAAOsH,MAAMvC,KAWvB,QAASwC,KACN,GAAMtH,KAAKuH,KAAX,CAEA,GAAInG,GAAQpB,KAAK8G,KAEjB,IAAI1F,EACA,GAAIoG,GAASpG,EAAMqG,MAAMC,EAE7B,KAAMF,EACF,KAAM,IAAIG,GAAe,0BAA4BvG,EAMzD,OAJApB,MAAK4H,UAAYJ,EAAO,IAAM,YAC9BxH,KAAK6H,WAAcL,EAAO,IAAMA,EAAO,GAAGM,MAAMC,IAAyBC,OACzEhI,KAAKiI,SAAWT,EAAO,IAAMQ,OAEtBhI,MAUX,QAASkI,KAGL,GAFApG,EAAM9B,KAAKiI,SAAUjG,EAAMuD,mBAErBvF,KAAK4H,UACP,KAAM,IAAID,GAAe,8BAAgC3H,KAAK4H,UAElE,OAAO5H,MAUX,QAASmI,KAEL,MADAnI,MAAKiI,SAAWjI,KAAKiI,UAAYG,KAAKC,KAAKC,gBACpCC,EACMC,QAAQ,aAAcxI,KAAK4H,WAAa,IACxCY,QAAQ,cAAexI,KAAK6H,YAAc7H,KAAK6H,WAAWnI,OAC7B,IAAMM,KAAK6H,WAAWY,KAAK,MAAQ,IACnC,IAC7BD,QAAQ,YAAaxI,KAAKiI,UAW3C,QAASS,GAAuBC,EAAIC,EAAgBN,EAAeO,GAC/D,GAAIC,GAAO,GAAIC,GAAcJ,EAC7BzI,GAAEkD,OAAO0F,GACLlB,UAAWgB,EACXX,SAAUK,EACVT,WAAYgB,IAEhBC,EAAKE,WAhJT,GAAIC,GAAY7J,EAAQ,aAClBuI,EAAiBvI,EAAQ,iBAAiB6J,UAC1ClJ,EAASX,EAAQ,aACjBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MAGhB0F,EAAkB,gDAChBK,EAAsB,kBACtBQ,EAAqB,kCAevBQ,EAAgB7I,EAAEwD,eAAeuF,EAAW,iBAAiB,EAWjE/I,GAAEM,YAAYuI,GACV3B,SAAUA,EACVE,MAAOA,EACPY,SAAUA,EACVC,OAAQA,IASZjI,EAAEkD,OAAO2F,GACLG,QAASR,IAIb9I,EAAOJ,QAAUuJ,IA6Fd1C,YAAY,GAAGvC,gBAAgB,GAAGC,gBAAgB,GAAGoF,YAAY,EAAE1I,YAAY,MAAM2I,GAAG,SAAShK,EAAQQ,GAC5G,YAkBA,SAASqJ,GAAUN,EAAI1I,GACnBD,KAAKC,KAAOA,GAAQD,KAAKoH,WACzBpH,KAAK2I,GAAKA,EAGV3I,KAAKuH,KAAOoB,EAAGU,WAAWrJ,KAAKC,MAuCnC,QAASqJ,GAAkBX,EAAIY,GAC3B,GAAItJ,GAAOD,KAAKoC,UAAUgF,UAG1B,IAFAuB,EAAGa,gBAAgBvJ,GAEfsJ,EAAM,CACN,GAAIE,GAAW,IAAMxJ,EAAO,IACxByJ,EAAWf,EAAGgB,iBAAiBF,EACnCvJ,GAAEgF,QAAQwE,EAAU,SAASE,GACzBA,EAAQJ,gBAAgBvJ,MAMpC,QAAS4J,WACE7J,MAAKuH,KAIhB,QAASuC,WACE9J,MAAK2I,SACL3I,MAAKuH,KAQhB,QAASwC,KACL,MAAO/J,MAAK2I,GAAGqB,aAAahK,KAAKC,MASrC,QAASgK,GAAc7I,GACnBpB,KAAK2I,GAAGuB,aAAalK,KAAKC,KAAMmB,GAQpC,QAAS+I,KACLnK,KAAKoK,IAAIpK,KAAKmI,UA7GlB,GAAIjI,GAAId,EAAQ,aACV0C,EAAQ1C,EAAQ,iBAEhBiL,GADQvI,EAAME,MACI5C,EAAQ,iBAAiBiL,gBAGjDzK,GAAOJ,QAAUyJ,EAmBjB/I,EAAEkD,OAAO6F,GACLlC,OAAQuC,IAkBZpJ,EAAEM,YAAYyI,GACVnC,IAAKiD,EACLK,IAAKH,EACLlD,OAAQ8C,EACRb,SAAUmB,EAEVG,QAASR,EAGT1C,SAAUiD,EACV/C,MAAO+C,EACPnC,SAAUmC,EACVlC,OAAQkC,MAwDTvG,gBAAgB,GAAGC,gBAAgB,GAAGtD,YAAY,MAAM8J,GAAG,SAASnL,EAAQQ,GAC/E,YA4CA,SAASwH,KACL,MAAOrH,GAAOsH,MAAMmD,KAWxB,QAASlD,KACL,MAAMtH,MAAKuH,MAEXvH,KAAKyK,QAAUzK,KAAK8G,MACb9G,MAHP,OAcJ,QAASkI,KAEL,MAAOlI,MASX,QAASmI,KACL,MAAOnI,MAAKyK,QAjFhB,GAAIxB,GAAY7J,EAAQ,aAElBW,GADiBX,EAAQ,iBAAiB6J,UACjC7J,EAAQ,cACjBc,EAAId,EAAQ,aASdsL,EAAgBxK,EAAEwD,eAAeuF,EAAW,iBAAiB,EAWjE/I,GAAEM,YAAYkK,GACVtD,SAAUA,EACVE,MAAOA,EACPY,SAAUA,EACVC,OAAQA,IAGZvI,EAAOJ,QAAUkL,IAsDdrE,YAAY,GAAGtC,gBAAgB,GAAGoF,YAAY,EAAE1I,YAAY,MAAMkK,GAAG,SAASvL,EAAQQ,GACzF,YAQiBA,GAAOJ,SACpBsF,KAAM1F,EAAQ,YACdoL,KAAMpL,EAAQ,eAGfwL,WAAW,EAAEC,WAAW,IAAIC,GAAG,SAAS1L,EAAQQ,GACnD,YA8CA,SAASmL,GAAOC,EAASC,EAAWC,EAAiBrJ,GACjD,MAAOsJ,GAAkBH,EAAS,SAASI,EAAOzC,EAAIG,EAAMjH,GACxD,GAAIwJ,GAAO,GAAIC,GAAcF,EAAOzC,EAAIG,EAAMjH,EAC9C,OAAO0J,GAAUC,OAAOH,EAAMxJ,IAC/BoJ,EAAWC,EAAiBrJ,GAKnC,QAAS4J,GAAQT,EAASC,EAAWC,EAAiBrJ,GAClD,GAAI6J,GAAYX,EAAOY,KAAKX,EAASC,EAAWC,EAAiBrJ,EACjE,OAAOkJ,GAAOS,OAAOE,EAAW1D,OAAWnG,GAK/C,QAAS8J,GAAKX,EAASC,EAAWC,EAAiBrJ,GAC/C,MAAOsJ,GAAkBH,EAAS,SAASI,EAAOzC,EAAIG,EAAMjH,GACxD,MAAO,IAAIyJ,GAAcF,EAAOzC,EAAIG,EAAMjH,IAC3CoJ,EAAWC,EAAiBrJ,GAKnC,QAAS2J,GAAOE,EAAWvH,EAAYtC,GACnC,GAAIuJ,GAAQ,GAAIQ,GAAMF,EAAUG,QAAS1H,GACnC2H,EAAYjK,KAAkB,EAAQ,WAAa,MAezD,OAbA6J,GAAUK,MAAM,SAASC,GAErB,GAAIX,GAAOnL,EAAEiD,MAAM6I,EACnBX,GAAKD,MAAQA,CAGb,IAAIa,GAAaV,EAAUC,OAAOH,EAAMxJ,EAExCuJ,GAAMU,GAAWG,EAAYA,EAAWhM,MACpCgM,EAAWC,YACXD,EAAWC,UAAUd,MAAQI,EAAOQ,EAASE,UAAUd,MAAOa,EAAWC,UAAWrK,MAGrFuJ,EAYX,QAASD,GAAkBH,EAASmB,EAAoBlB,EAAWC,EAAiBrJ,GAUhF,QAASuK,GAAsBhB,EAAOzC,EAAIuC,GAqCtC,QAASmB,GAAyB1D,GAC9B,GAAI2D,GAASf,EAAUgB,aAAa5D,EAEhC2D,IACAA,EAAOE,gBAAgB,iBAvC/B,GAAI1D,GAAO,GAAIC,GAAcJ,EAG7B,IAAIG,EAAKvB,MAAQ2D,KAAoB,EACjC,GAAIuB,GAAeN,EAAmBf,EAAOzC,EAAIG,EAAMjH,GACjD6K,EAAqC,mBAAhBD,IAA+BA,EAAaP,SAK3E,IAAIvD,EAAGgE,YAAchE,EAAGgE,WAAWjN,OAAQ,CACvC,GAAIgN,EAAa,CACb,GAAIE,GAAa,GAAIhB,GAAMjD,EAC3B8D,GAAaP,UAAUd,MAAQwB,EAC/BA,EAAWlI,YAAc+H,EAAaP,UAG1CW,EAAuBlE,EAAI+D,EAAcE,EAAaxB,GAe1D,MAXIsB,KAAiBD,EAAaP,UAAUd,QACxCqB,EAAaP,UAAUd,MAAQ,GAAIQ,GAAMjD,IAIzC8D,GACArB,EAAMU,GAAWW,EAAc3D,EAAKb,UAGxCoE,EAAyB1D,GAElB8D,EAYX,QAASI,GAAuBC,EAAa1B,GACzC,GAAI1B,GAAWqD,EAAQrD,SAASoD,EAKhC,OAHA5M,GAAEgF,QAAQwE,EAAU,SAASnC,GACzB6E,EAAsBhB,EAAO7D,GAAM,KAEhC6D,EA7DX,GAAIJ,GAAUA,GAAWgC,SAASC,KAC5B7B,EAAQH,GAAa,GAAIW,GAAMZ,GAC/Bc,EAAYjK,KAAkB,EAAQ,WAAa,MAIzD,OAFAuK,GAAsBhB,EAAOJ,EAASE,GAE/BE,EAxGX,CAAA,GACM8B,IADS9N,EAAQ,mBACIA,EAAQ,4BAE7BmM,GADiBnM,EAAQ,qCACb8N,EAAmBpG,IAAI,cACnCwE,EAAgBlM,EAAQ,uBACxBwM,EAAQxM,EAAQ,sBAChB2J,EAAgB3J,EAAQ,uBAExBc,GADcd,EAAQ,gBAAgB+N,OAClC/N,EAAQ,cACZ0C,EAAQ1C,EAAQ,gBAChB2N,EAAU3N,EAAQ,aACT0C,GAAME,MAGrB+I,EAAOY,KAAOA,EACdZ,EAAOS,OAASA,EAChBT,EAAOU,QAAUA,EAGjB7L,EAAOJ,QAAUuL,IAgJdqC,sBAAsB,EAAEC,oCAAoC,GAAGC,sBAAsB,GAAGC,0BAA0B,GAAGC,qBAAqB,GAAGC,kBAAkB,GAAGC,eAAe,GAAGC,aAAa,GAAGC,eAAe,GAAGnN,YAAY,MAAMoN,IAAI,SAASzO,EAAQQ,GAChQ,YAQA,IAAIkO,IACAjO,MAAOT,EAAQ,oBACfuB,cAAevB,EAAQ,6BACvBwM,MAAOxM,EAAQ,sBACfmH,cAAenH,EAAQ,uBACvB8E,MAAO9E,EAAQ,oBACf2O,cAAe3O,EAAQ,wBACvB4O,uBAAwB5O,EAAQ,4BAChC6O,aAAc7O,EAAQ,qBACtB8O,gBAAiB9O,EAAQ,mCACzB+O,YAAa/O,EAAQ,yBACrBgP,mBAAoBhP,EAAQ,iCAGhCQ,GAAOJ,QAAUsO,IAEdO,mBAAmB,EAAEC,4BAA4B,EAAEC,mBAAmB,EAAEC,sBAAsB,EAAEC,wBAAwB,GAAGC,gCAAgC,GAAGC,kCAAkC,GAAGnB,qBAAqB,GAAGoB,oBAAoB,GAAGC,uBAAuB,GAAGC,2BAA2B,KAAKC,IAAI,SAAS3P,EAAQQ,GACpU,YAgBA,SAASoP,GAAeC,GACpBjP,KAAKkP,WAAaD,GAAaE,IAC/BnP,KAAKoP,WACLpP,KAAKqP,SAAW,EAqBpB,QAASC,GAAqBC,GAI1B,GAHAC,EAA2B/P,KAAKO,MAChCA,KAAKoP,QAAQK,KAAKF,GAEdvP,KAAKoP,QAAQ1P,OAASM,KAAKkP,WAAY,CACvC,GAAIQ,GAAM1P,KAAKoP,QAAQO,OACvBD,GAAIpF,UAIR,MADAtK,MAAKqP,SAAWrP,KAAKoP,QAAQ1P,OACtBM,KAAKqP,SAAW,EAI3B,QAASO,KACA5P,KAAKoP,QAAQ1P,SAClBM,KAAKqP,WACLrP,KAAKoP,QAAQ1P,UAIjB,QAAS8P,KACL,IAAK,GAAInQ,GAAIW,KAAKqP,SAAUhQ,EAAIW,KAAKoP,QAAQ1P,OAAQL,IACjDW,KAAKoP,QAAQ/P,GAAGiL,SACpBtK,MAAKoP,QAAQ1P,OAASM,KAAKqP,SAI/B,QAASQ,GAAoBC,GACzB,GAAqB,GAAjB9P,KAAKqP,SAAT,CACA,GAAIK,GAAM1P,KAAKoP,UAAUpP,KAAKqP,SAE9B,OADAK,GAAIK,KAAKD,GACFJ,GAIX,QAASM,GAAoBF,GACzB,GAAI9P,KAAKqP,UAAYrP,KAAKoP,QAAQ1P,OAAlC,CACA,GAAIgQ,GAAM1P,KAAKoP,QAAQpP,KAAKqP,WAE5B,OADAK,GAAIO,KAAKH,GACFJ,GAIX,QAASQ,KACL,KAAOlQ,KAAKqP,UAAUrP,KAAK+P,OAI/B,QAASI,KACL,KAAOnQ,KAAKqP,SAAWrP,KAAKoP,QAAQ1P,QAAQM,KAAKiQ,OAIrD,QAASG,GAA4BN,GAC7B9P,KAAKqP,WACLrP,KAAK+P,OACD/P,KAAKqP,SACLnP,EAAEmQ,YAAYrQ,KAAM,eAAgB8P,GAEhCA,GAAI5P,EAAEoQ,MAAMR,IAK5B,QAASS,GAA4BT,GAC7B9P,KAAKqP,SAAWrP,KAAKoP,QAAQ1P,SAC7BM,KAAKiQ,OACDjQ,KAAKqP,SAAWrP,KAAKoP,QAAQ1P,OAC7BQ,EAAEmQ,YAAYrQ,KAAM,eAAgB8P,GAEhCA,GAAI5P,EAAEoQ,MAAMR,IAK5B,QAASU,GAAoBC,EAAcC,GACvC,GAAIC,GAA8B,gBAAhBF,GACJ,SAASf,GAAOA,EAAIe,MACpBA,CAEdzQ,MAAKoP,QAAQlK,QAAQyL,EAAMD,GAAW1Q,MAI1C,QAAS4Q,GAA2BH,EAAcC,GAC9C1Q,KAAKoP,QAAQyB,UACb7Q,KAAK8Q,KAAKL,EAAcC,GACxB1Q,KAAKoP,QAAQyB,UAIjB,QAASE,KACL,MAAO/Q,MAAKqP,UAAYrP,KAAKoP,QAAQpP,KAAKqP,SAAW,GAIzD,QAAS2B,KACL,GAAI5B,GAAUpP,KAAKoP,QAAQ6B,IAAI,SAASvB,GACpC,MAAOA,GAAIwB,kBAEf,QACI9B,QAASA,EACTC,SAAUrP,KAAKqP,SACf3P,OAAQ0P,EAAQ1P,QA7IxB,CAAA,GAAIQ,GAAId,EAAQ,YACDA,GAAQ,kBAGvBQ,EAAOJ,QAAUwP,EAgBjB9O,EAAEM,YAAYwO,GACVmC,MAAO7B,EACP8B,WAAYxB,EACZG,KAAMF,EACNI,KAAMD,EACNqB,QAASnB,EACToB,QAASnB,EACToB,aAAcnB,EACdoB,aAAcjB,EACdO,KAAMN,EACNiB,YAAab,EACbc,cAAeX,EAEfG,eAAgBF,MAgHjBW,iBAAiB,IAAIlR,YAAY,MAAMmR,IAAI,SAASxS,EAAQQ,GAC/D,YAEA,IAAI2G,GAAgBnH,EAAQ,wBACtByS,EAAUzS,EAAQ,WAMpB0S,EAAmB,GAAIvL,GAAcsL,EAGzCC,GAAiBnL,IAAIkL,GAErBjS,EAAOJ,QAAUsS,IAEdC,uBAAuB,EAAEC,UAAU,KAAKC,IAAI,SAAS7S,EAAQQ,GAChE,YAsBA,SAASiS,KACL7R,KAAKK,KAAKC,MAAMN,KAAMO,WA4C1B,QAAS2R,GAAavB,GAClB7O,EAAM6O,EAAM3O,EAAMC,SAASF,WAC3B/B,KAAK2Q,KAAOA,GAAQ,aACpB3Q,KAAKmS,KAAOjS,EAAEkS,MAAM7R,UAAW,GAOnC,QAAS8R,GAAgBvC,GACrB,GAAIwC,GAAStS,KAAK2Q,KAAKrQ,MAAMN,KAAMA,KAAKmS,KAExC,OADIrC,IAAI5P,EAAEoQ,MAAMR,GACTwC,EASX,QAASC,GAAgBC,GACjBxS,KAAKyS,IACLnQ,EAAOoQ,KAAK,gDAEhB1S,KAAKyS,GAAgBD,EACrBA,EAAYC,GAAgBzS,KAShC,QAAS2S,KACL,MAAO3S,MAAKyS,GAOhB,QAASG,GAAa9C,GAClB,GAAI+C,GAAU7S,KAAK8S,SACnB,KAAMD,EAAS,MAAOvQ,GAAOC,MAAM,mDACnC,IAAI+P,GAASO,EAAQE,SAErB,OADIjD,IAAI5P,EAAEoQ,MAAMR,GACTwC,EASX,QAASU,KACDhT,KAAKmS,MAAQnS,KAAKmS,KAAKzS,QACvB4C,EAAOoQ,KAAK,2DAChB1S,KAAKmS,KAAOjS,EAAE+S,QAAQ1S,WAI1B,QAAS2S,KACL,MAAOlT,MAAKmS,KAIhB,QAASgB,KACLnT,KAAKmS,KAAOjS,EAAE+S,QAAQ1S,WAS1B,QAAS6S,KACCpT,KAAKmS,OAAMnS,KAAKmS,SACtBjS,EAAEmT,YAAYrT,KAAKmS,KAAM5R,WAY7B,QAAS+S,KACL,MAAOpT,GAAEqT,SAASvT,KAAMO,WAI5B,QAASiT,KACL,KAAM,IAAIlU,OAAM,qDAOpB,QAASmU,WACEzT,MAAK2Q,WACL3Q,MAAKmS,IACZ,IAAIU,GAAU7S,KAAKyS,EACfI,WACO7S,MAAKyS,GAAcA,SACnBzS,MAAKyS,GACZI,EAAQvI,WAKhB,QAASoJ,GAAmBC,GACxB3T,KAAK2T,QAAUA,EAInB,QAASC,KACL,OACIjD,KAAM3Q,KAAK2Q,KAAK1Q,KAChB0T,QAAS3T,KAAK2T,SA/LtB,GAAIzT,GAAId,EAAQ,aACV0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MACdM,EAASlD,EAAQ,kBAGnBqT,EAAe,cAGnB7S,GAAOJ,QAAUqS,EA0BjB3R,EAAEM,YAAYqR,GACVxR,KAAM6R,EACNa,QAASV,EACTwB,QAAStB,EACTO,QAASH,EACT5C,KAAM6C,EACN3C,KAAMoC,EACNyB,aAAcd,EACde,aAAcX,EACdY,aAAcd,EACde,gBAAiBd,EACjB7I,QAASmJ,EAETS,WAAYR,EACZxC,eAAgB0C,IASpB1T,EAAEkD,OAAOyO,GACLrG,OAAQ8H,EACRa,eAAgBX,MAuIjB1P,gBAAgB,GAAG6N,iBAAiB,IAAIlR,YAAY,MAAM2T,IAAI,SAAShV,EAAQQ,GAClF,YAUA,SAASuO,KACLnO,KAAKqU,SAAW,GAAIrF,GAiBxB,QAASsF,KACLtU,KAAKqU,SAASvD,KAAK,WAIvB,QAASyD,GAAiBzE,GACtB9P,KAAKqU,SAAS9C,aAAazB,GAI/B,QAAS0E,GAAiB1E,GACtB9P,KAAKqU,SAAS7C,aAAa1B,GAI/B,QAAS2E,KACLzU,KAAKqU,SAASvD,KAAK,WAIvB,QAAS4D,GAAyBnF,GAC9BvP,KAAKqU,SAASlD,MAAM5B,GAIxB,QAASoF,GAAkBC,GACvBA,EAAYP,SAASvD,KAAK,SAAS+D,GAC/B7U,KAAKqU,SAASlD,MAAM0D,IACrB7U,MAIP,QAAS8U,GAAuBnB,GAC5B3T,KAAK2T,QAAUA,EAInB,QAASoB,KACL,GAAIV,GAAWrU,KAAKqU,SAASnD,gBAC7B,QACImD,SAAUA,EAASjF,QACnBuE,QAAS3T,KAAK2T,SAlEtB,GAAI3E,GAAiB5P,EAAQ,qBACvBc,EAAId,EAAQ,YAGlBQ,GAAOJ,QAAU2O,EAQjBjO,EAAEM,YAAY2N,GACV4E,QAASuB,EACTvE,KAAMwE,EACNtE,KAAMuE,EACNlK,QAASmK,EACTO,aAAcN,EACdO,MAAON,EAEPT,WAAYY,EACZ5D,eAAgB6D,MAiDjBG,oBAAoB,GAAGzU,YAAY,MAAM0U,IAAI,SAAS/V,EAAQQ,GACjE,YAgBA,SAASwO,GAAmBa,GACxBjP,KAAKoV,aAAe,GAAIpG,GAAeC,GACvCjP,KAAKqV,aAAerN,OACpBhI,KAAKsV,mBAAqBtN,OAC1BhI,KAAKuV,IAAa,EAwBtB,QAASC,GAAgCjG,EAASkG,GAC9C,GAAIA,IAAuBzV,KAAKsV,qBAAsBtV,KAAKqV,aAAe,CACtE,GAAIT,GAAc5U,KAAKoV,aAAa1D,eAGpC,OAFAkD,GAAYI,aAAazF,OACzBmG,GAAwBjW,KAAKO,KAAM,WAAY4U,GAI7C5U,KAAKqV,eAAcrV,KAAKqV,aAAe,GAAIlH,IACjDnO,KAAKqV,aAAaL,aAAazF,GACzBvP,KAAKuV,KACPvV,KAAKuV,IAAa,EAClBrV,EAAEmQ,YAAYrQ,KAAM2V,IAK5B,QAASC,KACD5V,KAAKqV,cAAgBrV,KAAKsV,oBAC1BtV,KAAKqV,aAAerN,OACpBhI,KAAKsV,mBAAqBtN,QAE1BhI,KAAKoV,aAAahE,aAK1B,QAASuE,KACD3V,KAAKqV,cACLQ,EAAuBpW,KAAKO,MAC5BE,EAAEmQ,YAAYrQ,KAAM2V,KAEpBG,EAAyBrW,KAAKO,MAC9BA,KAAKuV,IAAa,GAK1B,QAASQ,KACLF,EAAuBpW,KAAKO,MAC5B8V,EAAyBrW,KAAKO,MAIlC,QAAS6V,KACD7V,KAAKqV,eACCrV,KAAKsV,qBAAoBtV,KAAKsV,mBAAqB,GAAInH,IAC7DnO,KAAKsV,mBAAmBL,MAAMjV,KAAKqV,cACnCrV,KAAKqV,aAAerN,QAK5B,QAAS8N,KACL,GAAI9V,KAAKsV,mBAAoB,CACzB,GAAIzW,GAAImB,KAAKsV,kBACbtV,MAAKoV,aAAajE,MAAMtS,GACxB6W,EAAwBjW,KAAKO,KAAM,SAAUnB,GAE7CmB,KAAKsV,mBAAqBtN,QAKlC,QAASgO,GAAoCpB,GACzC5U,KAAKiW,iBAELjW,KAAKoV,aAAajE,MAAMyD,GACxBc,EAAwBjW,KAAKO,KAAM,SAAU4U,GAIjD,QAASc,GAAwBQ,EAAKtB,GAC9B5U,KAAKmW,YACLnW,KAAKmW,WAAWC,YAAYF,GAAOtB,YAAaA,IAIxD,QAASyB,GAAwBvG,GAC7B,GAAIjR,GAAImB,KAAKoV,aAAarF,KAAKD,EAE/B,OADIjR,IAAG6W,EAAwBjW,KAAKO,KAAM,SAAUnB,GAC7CA,EAIX,QAASyX,GAAwBxG,GAC7B,GAAIjR,GAAImB,KAAKoV,aAAanF,KAAKH,EAE/B,OADIjR,IAAG6W,EAAwBjW,KAAKO,KAAM,SAAUnB,GAC7CA,EAIX,QAAS0X,KACL,MAAOvW,MAAKuV,GAIhB,QAASiB,KACL,MAAOxW,MAAKoV,aAAalE,iBAI7B,QAASuF,KACL,MAAOzW,MAAKmW,WAAa,GAAIO,GAAU1W,KAAM0W,EAAUC,gBAI3D,QAASC,KACD5W,KAAKmW,YAAYnW,KAAKmW,WAAW7L,gBAC9BtK,MAAKoV,aAtJhB,GAAIpG,GAAiB5P,EAAQ,qBACvB+O,EAAc/O,EAAQ,iBAEtBsX,GADStX,EAAQ,kBACLA,EAAQ,iBACpBc,EAAId,EAAQ,YAGlBQ,GAAOJ,QAAU4O,CAGjB,IAAImH,GAAY,YAWhBrV,GAAEM,YAAY4N,GACV4G,aAAcQ,EACdS,eAAgBF,EAChBc,iBAAkBb,EAClBc,sBAAuBlB,EACvB7F,KAAMsG,EACNpG,KAAMqG,EACNS,cAAeR,EAEfrF,eAAgBsF,EAChBQ,aAAcP,EACdnM,QAASsM,MAyHVK,eAAe,GAAGtF,iBAAiB,IAAIuD,oBAAoB,GAAGgC,gBAAgB,GAAGzW,YAAY,MAAM0W,IAAI,SAAS/X,EAAQQ,GAC3H,YAoMA,SAASwX,GAAgCnX,EAAMe,GAE3C,GAAIgE,MAAMC,QAAQjE,GAAe,CAC7B,GAAIqW,KACJrW,GAAakE,QAAQ,SAASoS,GAC1B,GAAI/T,GAAUrD,EAAEC,eAAemX,EAC/BD,GAAU9T,QAEdvC,EAAeqW,EAInB,GAAI/V,EACuB,iBAAhBN,IAA4Bd,EAAEqX,KAAKvW,GAActB,SACxD4B,KACApB,EAAEqB,QAAQP,EAAc,SAASD,EAAWuW,GACxC,GAAI/T,GAAUrD,EAAEC,eAAemX,GAC3BE,EAAetX,EAAEuX,eAAeH,EACpChW,GAAciC,GAAWmU,EAAe5Q,IAAI0Q,KAKpD,IAAIG,GAAiBhX,EAAcgD,mBAAmBlE,KAAKO,KAAMC,EAAMqB,EAAeN,EAItF,OAFA4W,GAAwB3X,GAEjB0X,EAIX,QAASC,GAAwBC,GAC7BC,GAAWC,iBAAiBF,EAAWG,EAAgCC,GAI3E,QAASD,GAA+BE,GACpC,GAAIC,GAAQD,EAAUE,UACtB,OAAOC,MAAKC,UAAUH,GAI1B,QAASF,GAA2BM,GAChC,GAAIJ,GAAQK,GAAUD,EACtB,OAAIJ,GACO5M,GAAUkN,gBAAgBN,GADrC,OAcJ,QAASO,GAAkBrN,EAAMxJ,GAC7B,GAAI8V,GAAiBtM,EAAKsM,cAE1B,IAA6B,kBAAlBA,GAA8B,CACrC,GAAItV,GAAU,sDAAyDsV,GAAiB,UACxF,IAAI9V,KAAkB,EAIlB,KAAM,IAAI8W,IAAetW,EAHzBC,GAAOC,MAAM,YAAaF,EAAS,uCACnCsV,EAAiBpM,GAKzB,GAAIU,GAAa,GAAI0L,GAAetM,EAAKD,MAAOC,EAAK1C,GAAI0C,EAAKpL,KAAMoL,EAQpE,OANIA,GAAKuN,oBACL1Y,EAAEqB,QAAQ8J,EAAKuN,mBAAoB,SAAS/X,GAClCoL,EAAWrJ,SAAS/B,IACtBoL,EAAWpI,SAAShD,EAAYmH,OAAWA,OAAWnG,KAG3DoK,EAaX,QAAS4M,GAAgBX,EAAWY,GAIhC,GAHAhX,EAAMoW,EAAW3M,IACjBzJ,EAAMgX,EAAU9W,EAAMC,SAAS8W,UAE3BD,IAAaZ,EAAUhM,UACvB,KAAM,IAAIyM,IAAe,qDAG7B,IAAIK,GAAQd,EAAUe,IACJf,EAAUe,IAAIC,KAAKJ,GACnBZ,EAAUvP,GAAGwQ,UAAUL,GAErCnB,EAAiBO,EAAU9X,YAG3B6L,EAAa0L,EAAeyB,gBAAgBJ,EAAOhR,OAAWkQ,EAAU9M,MAAO8M,EAAUmB,aACzFlB,EAAQD,EAAUoB,UAAUR,IAAY,EAG5C,OAFA7M,GAAWsN,SAASpB,GACpBjY,EAAEmQ,YAAYpE,EAAY,YAAa,cAChCA,EAeX,QAASuN,GAA2B7Q,EAAI8Q,EAAWxO,EAAWoO,GAC1DvX,EAAM2X,EAAWzX,EAAMC,SAASC,SAChCJ,EAAMmJ,EAAWjJ,EAAMC,SAAS2J,KAChC9J,EAAMuX,EAAarX,EAAMC,UAAUC,UAG/ByG,GAAM8Q,IAAW9Q,EAAG8Q,UAAYA,GACpC9Q,EAAKA,GAAM+Q,EAAwBja,KAAKO,KAAMyZ,GAC9CxO,EAAYA,GAAa0O,EAAgChR,EACzD,IAAIsD,GAAa2N,EAA8Bna,KAAKO,KAAM2I,EAAIsC,EAAWoO,EAEzE,OADApN,GAAW4N,UAAU,cACd5N,EAGX,QAASyN,GAAwBD,GAE7B,GAAIK,GAAMpC,EAAe5Q,IAAI,OACvBiT,EAAiB/Z,KAAK4D,eAAe,OACrCoW,EAAsBha,KAAK4D,eAAe,YAC1CqW,EAAWD,GAAuBA,EAAoBC,SAExDC,GACAC,UAAWJ,EACXE,SAAUA,EACVG,QAASX,EAGb,OAAOK,GAAIO,cAAcH,GAG7B,QAASP,GAAgChR,GACrC,GAAI2R,GAAS/O,GAAUgP,uBAAuB5R,GAAI,EAAO,YACzD,OAAO2R,GAASA,EAAOpO,UAAUd,MAAQ,GAAIQ,IAAMjD,GAGvD,QAASiR,GAA8BjR,EAAIsC,EAAWoO,GAElD,GAAIvQ,GAAO,GAAIC,IAAcJ,EAE7BG,GAAKlB,UAAY5H,KAAKC,KACtB6I,EAAKjB,WAAawR,EAClBvQ,EAAKE,UAGL,IAAIwR,GAAapb,EAAQ,YAGzB,OAFAob,GAAW7R,EAAIsC,GAERA,EAAUnC,EAAKb,UAc1B,QAASwS,GAA2BtC,EAAOlN,EAAWyP,EAAe7Y,GACjEC,EAAMqW,EAAOnW,EAAM2Y,iBACf1S,SAAUjG,EAAMC,SAASC,QACzB0F,UAAW5F,EAAMC,SAASC,QAC1BmX,YAAarX,EAAMC,UAAUC,SAC7B0Y,aAAc5Y,EAAMC,SAAST,QAC7BqZ,UAAW3Y,SAGf,IAAIsY,GAAapb,EAAQ,aAGrB0b,EAASC,EAA4B5C,EAAOuC,GAG5CtP,EAAQoP,EAAWM,EAAQ9S,OAAWA,OAAWnG,GAGjDqW,EAAY9M,EAAM4P,MAYtB,OATI/P,KACAiN,EAAU9M,MAAQH,EAClBA,EAAUgQ,KAAK/C,IAInBA,EAAUqB,SAASpB,GACnBjY,EAAEmQ,YAAY6H,EAAW,YAAa,cAE/BA,EAKX,QAAS6C,GAA4B5C,EAAOuC,GACxC,GAAII,GAAS9N,SAASqN,cAAc,MACpCS,GAAOrB,UAAYtB,EAAM0C,SAEzB,IAAInR,GAAWwR,GAASxR,SAASoR,EACjC,IAAuB,GAAnBpR,EAAShK,OACT,KAAM,IAAIiZ,IAAe,6DAA+DjP,EAAShK,OAAS,iBAC9G,IAAIyb,GAASzR,EAAS,GAClBZ,EAAO,GAAIC,IAAcoS,EAM7B,OALArS,GAAKb,SAAWyS,EAAgBU,IAAsBjD,EAAMlQ,SAC5Da,EAAKlB,UAAYuQ,EAAMvQ,UACvBkB,EAAKjB,WAAasQ,EAAMkB,YACxBvQ,EAAKE,WAEE8R,EASX,QAASO,GAAkCC,GACvC,GAAIC,GAAWrb,EAAEsb,KAAKF,EAAaG,MAAO,SAAUC,GAChD,MAAOC,IAA0BC,KAAKF,IAE1C,IAAKH,EAAL,CAEA,GAAIpD,GAAQjY,EAAEsY,UAAU8C,EAAaO,QAAQN,GAC7C,IAAKpD,EAEL,MAAO5M,IAAUkN,gBAAgBN,EAAOnQ,QAAW,IAkBvD,QAAS8T,GAAe1Q,EAAO2Q,EAAS9b,EAAM+b,GAK1C,GAHAhc,KAAK2I,GAAKoT,GAAW/b,KAAKqa,gBAGtBra,KAAK2I,GAAI,CAET,GAAI2D,GAAStM,KAAK2I,GAAG5I,EAAOkc,aACxB3P,IACAhK,EAAOoQ,KAAK,aAAezS,EAAO,mDAAqDqM,EAAOrM,MAElGD,KAAK2I,GAAG5I,EAAOkc,cAAgBjc,KAGnCE,EAAEuB,iBAAiBzB,MACfgc,cAAeA,EACf3C,gBACDnZ,EAAEuC,MAELzC,KAAKC,KAAOA,EACZD,KAAKoL,MAAQA,CAGb,IAAI8Q,GAAY,GAAIxF,GAAU1W,KAC9BE,GAAEwB,eAAe1B,KAAMmc,GAAoBD,GAG3Clc,KAAKoc,UAAU,SAGfpc,KAAKoc,UAAU,SAGXpc,KAAKqc,OAAOrc,KAAKqc,QAQzB,QAASC,MAYT,QAASC,KACL,MAAuB,mBAAZvP,WAGXhN,KAAK2I,GAAK3I,KAAKiZ,IACDjZ,KAAKiZ,IAAIoB,gBACTrN,SAASqN,cAAc,OAE9Bra,KAAK2I,IAPZ,OAkBJ,QAAS6T,GAAmBC,GACxB,GAAI3b,GAAYZ,EAAEC,eAA0C,kBAApBsc,GACFA,EAAiBxc,KACjBwc,GAElCC,EAAQ1c,KAAKc,EAIjB,QAHM4b,YAAiBC,IACnBra,EAAOoQ,KAAK,iBAAkB5R,EAAW,uDAEnC4b,EAad,QAASE,GAAmBH,EAAkB7a,EAAad,EAAWe,GAClEC,EAAM2a,EAAkBza,EAAMqC,MAAMnC,OAAQF,EAAMsB,SAASqZ,KAC3D7a,EAAMF,EAAaI,EAAMC,SAAST,SAClCM,EAAMhB,EAAWkB,EAAMC,SAASC,QAEhC,IAAIrB,EAEJ,IAA+B,gBAApB4b,GAA8B,CACrC,GAAII,GAAiB3c,EAAEuX,eAAegF,EACtC5b,GAAa6W,EAAe5Q,IAAI+V,OAEhChc,GAAa4b,CAEZ3b,KACDA,EAAYZ,EAAEC,eAAeU,EAAWZ,OAE5CD,KAAKqZ,YAAY5J,KAAK3O,EAGtB,IAAI0B,GAAW7B,EAAcyB,UAAUyB,SAASpE,KAAKO,KAAMa,EAAYe,EAAad,EAAWe,EAG3FW,GAASV,OAAOU,EAASV,QACzBU,EAAS6Z,OAAO7Z,EAAS6Z,QAYjC,QAASS,GAAoBlY,GACzB,GAAIuN,GAAOjS,EAAEkS,MAAM7R,UAAW,EAE9B,OAAOL,GAAE6c,QAAQ/c,KAAKiB,OAAQ,SAASyb,GACnC,MAAIA,IAAiC,kBAAjBA,GAAM9X,GACf8X,EAAM9X,GAAQtE,MAAMoc,EAAOvK,GADtC,SAYR,QAAS6K,GAAiB/c,EAAMgd,GAC5Bhd,EAAOA,GAAQmb,IACfpb,KAAKgc,cAAckB,OAAOjd,GAAM,GAChC2L,GAAMsR,OAAOld,KAAMC,EAAMgd,GAW7B,QAASE,GAAiBC,EAAuBC,GACzCrd,KAAKoL,QACLpL,KAAKoL,MAAMkS,QAAQtd,KAAKC,KAAMod,GACxBD,SACKpd,MAAKoL,OAWxB,QAASmS,GAAqBC,EAAUC,GACpCD,EAASE,aAAa1d,KAAK2I,GAAI8U,GAC/Bzd,KAAK2d,wBAaT,QAASC,KACL5d,KAAK6Z,UAAU,mBAAqBgE,cAAe7d,MAAQgI,QAAW,EACtE,IAAImQ,GAAQnY,KAAKsZ,WAAU,EAG3B,OAFAnB,GAAM0C,UAAY7a,KAAK2I,GAAGkS,UAC1B3a,EAAEmQ,YAAYrQ,KAAM,YAAa,qBAAuB6d,cAAe7d,MAAQgI,QAAW,GACnFmQ,EAeX,QAAS2F,GAA2BC,GAChC,MAAO/d,MAAKge,SACFhe,KAAKge,SAAS5F,SAAS2F,GACvB/d,KAAKoY,SAAS2F,GAa5B,QAASE,GAAoBC,GAEzB,GAAItD,GAAe5a,KAAKoc,UAAU,WAAY8B,KAAc,GAAQ,GAAQ,EAK5E,OAJAtD,GAAe1a,EAAEie,WAAWvD,EAAc,SAASwD,GAC/C,QAAUA,KAIVnW,SAAUjI,KAAKC,KACf2H,UAAW5H,KAAKI,YAAYH,KAC5BoZ,YAAarZ,KAAKqZ,YAClBuB,aAAcA,GAatB,QAASyD,GAAmBlG,GACpBA,EAAMyC,cACN1a,EAAEqB,QAAQ4W,EAAMyC,aAAc,SAASwD,EAAU7a,GAC7C,GAAImZ,GAAQ1c,KAAKuD,EACbmZ,IAAkC,kBAAlBA,GAAMnD,UACtBmD,EAAMnD,SAAS6E,IACpBpe,MAYX,QAASse,GAAyBC,GAC9B,MAAOC,GAAoB/e,KAAKO,KAAMye,EAAiBF,GAG3D,QAASC,GAAoBE,EAAqBH,GAC9Czc,EAAMyc,EAAkBvc,EAAMC,SAASD,EAAMqC,MAAMtC,SAAUG,SAC7D,IAAIyc,GAAgBC,EAAeC,4BAA4BN,EAC/D,OAAOG,GAAoBjf,KAAKO,KAAM2e,GAG1C,QAASF,GAAgBE,GACrB,GAAIrE,EACJ,KAAMA,EAASta,KAAKoL,MAAM1G,YAAY5E,MAAS,MAAMlB,IAIrD,MAAI0b,IACMqE,GAAiBA,EAAcrE,GAC1BA,EAEAmE,EAAgBhf,KAAK6a,EAAQqE,GAJ5C,OAgBJ,QAASG,GAAkCnH,GAEvC,MADAA,GAAiBA,GAAkB3X,KAAKI,YACjCqe,EAAgBhf,KAAKO,KAAM,SAAS+e,GACvC,MAAOA,aAAgBpH,KAa/B,QAASqH,GAA4BT,GACjC,MAAOC,GAAoB/e,KAAKO,KAAMif,EAAoBV,GAG9D,QAASU,GAAmBN,GACxB,GAAIO,GACE5E,EAASta,IACf,GACIsa,GAASmE,EAAgBhf,KAAK6a,EAAQqE,GAClCrE,IACA4E,EAAY5E,SACXA,EAET,OAAO4E,GAWX,QAASC,GAAqCxH,GAE1C,MADAA,GAAiBA,GAAkB3X,KAAKI,YACjC6e,EAAmBxf,KAAKO,KAAM,SAAS+e,GAC1C,MAAOA,aAAgBpH,KAe/B,QAASyH,KAIL,IAHA,GAEI9E,GAAQ+E,EAFR7B,EAAWxd,KAAK2I,GAAG2W,WAGhB9B,IAAc6B,GACjB/E,EAAS/O,GAAUgB,aAAaiR,GAChC6B,EAAc/E,GAAUA,EAAOpO,UAC/BsR,EAAWA,EAAS8B,UAIxB,OADAtf,MAAK+G,SACDsY,GACArf,KAAKkd,OAAOlV,QAAW,GACvBsS,EAAOpO,UAAUd,MAAM6P,KAAKjb,MACrBsa,GAHX,OAcJ,QAASiF,GAAwBC,EAAU9O,GACvC8O,EAAS/f,KAAKiR,EAAS1Q,MAClBA,KAAKkM,WACVlM,KAAKkM,UAAUd,MAAMW,MAAM,SAASmM,GAChCA,EAAUuH,cAAcD,EAAU9O,KAK1C,QAASgP,GAAqBxH,GAC1B,MAAOgD,IAASyE,WAAW3f,KAAK2I,GAAIuP,EAAUvP,IAIlD,QAASiX,GAAiCC,EAAUC,GAChD,GAAIvY,GAAO2T,GAAS6E,kBAAkB/f,KAAK2I,GAAIkX,EAAUC,EACzD,OAAOvU,IAAUgB,aAAahF,GAIlC,QAASyY,GAA2BH,EAAU3H,GAC1C,GAAI+H,GAAc/E,GAASgF,iBAAiBlgB,KAAK2I,GAAIkX,EAAU3H,EAAUvP,GAEzE,OADIsX,IAAa/H,EAAUyF,wBACpBsC,EAYX,QAASE,GAAoBjK,EAAKkK,EAAMZ,EAAUa,GAC9C,GAAIC,GAAaD,EAAgB,kBAAoB,aACrDrgB,MAAKyf,cAAc,SAASvH,GACxBA,EAAUoI,GAAYpK,EAAKkK,EAAMZ,KAQzC,QAASe,GAAkBlD,GACvB,MAAIrd,MAAKwgB,gBACAnD,GAAO/a,EAAOoQ,KAAK,uDAG5B1S,KAAK+G,QAAO,EAAOsW,GACnBrd,KAAKoc,UAAU,WACfpc,KAAKmc,IAAoB7R,UACrBtK,KAAK2I,KACLuS,GAASuF,gBAAgBzgB,KAAK2I,IAC9BuS,GAASwF,cAAc1gB,KAAK2I,UACrB3I,MAAK2I,IAEhB3I,KAAKgc,cAAc1R,eACnBtK,KAAKwgB,YAAa,IAStB,QAASG,KACL,MAAO3gB,MAAKwgB,WAp5BhB,GAAI7f,GAAgBvB,EAAQ,8BACtBsY,EAAiBtY,EAAQ,0BACzBud,EAAiBjF,EAAe5Q,IAAI,kBACpC8X,EAAiBxf,EAAQ,aACzBsX,EAAYtX,EAAQ,gBACpBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MACdjC,EAASX,EAAQ,aACjBgc,EAAoBhc,EAAQ,0BAC5BkD,EAASlD,EAAQ,kBACjB8b,GAAW9b,EAAQ,eACnBuZ,GAAiBvZ,EAAQ,iBAAiBmM,UAC1CxC,GAAgB3J,EAAQ,wBACxBwM,GAAQxM,EAAQ,WAChB0Y,GAAa1Y,EAAQ,mBACrBoZ,GAAYpZ,EAAQ,sBAsDtBmM,IApD8BqT,EAAeC,4BAoDjC3e,EAAEwD,eAAe/C,EAAe,aAAa,GAE7Df,GAAOJ,QAAU+L,GAEjBqM,EAAwB,aAgBxB1X,EAAEkD,OAAOmI,IACLqV,qBAAsBxJ,EACtB5L,OAAQkN,EACRQ,KAAML,EACNO,gBAAiBI,EACjBqH,YAAajC,EAAeiC,YAC5BtU,aAAcqS,EAAerS,aAC7BgO,uBAAwBqE,EAAerE,uBACvC9B,gBAAiBgC,EACjBqG,uBAAwBzF,UAErB9P,IAAU5H,mBAmCjBzD,EAAEM,YAAY+K,IACVlL,KAAMyb,EACNO,MAAOC,EACPjC,cAAekC,EACf3Z,SAAU4Z,EACV3Y,SAAU+Y,EACVR,UAAWU,EACXI,OAAQF,EACRjW,OAAQoW,EACR4D,WAAYxD,EAEZnF,SAAUwF,EACVoD,iBAAkBlD,EAClBxE,UAAW2E,EACX1E,SAAU8E,EAEV4C,eAAgB3C,EAChB4C,kBAAmBlC,EACnBmC,wBAAyBrC,EACzBsC,2BAA4BjC,EAE5BxB,sBAAuByB,EAEvBK,cAAeF,EAEfI,WAAYD,EACZ2B,uBAAwBzB,EACxBM,iBAAkBF,EAElBnG,UAAWsG,EACX7V,QAASiW,EACTe,YAAaX,GAOjB,IAAIxE,IAAqB,YACzBzF,GAAUtQ,QAAQmF,GAAW4Q,GAAoBzF,EAAUC,eAG3D,IACIgF,IAA4B,iEAouB7B4F,6BAA6B,EAAEC,uBAAuB,EAAEC,YAAY,EAAEpb,YAAY,GAAG4Q,eAAe,GAAGnT,gBAAgB,GAAG4d,yBAAyB,GAAGC,cAAc,GAAG5d,gBAAgB,GAAG6d,qBAAqB,IAAIjQ,iBAAiB,IAAIkQ,kBAAkB,IAAIC,yBAAyB,GAAGC,YAAY,GAAGC,UAAU,GAAGvhB,YAAY,MAAMwhB,IAAI,SAAS7iB,EAAQQ,GAChW,YA8EA,SAASsiB,KACLliB,KAAKmiB,mBAKT,QAASA,KACLjiB,EAAEwB,eAAe1B,KAAMmc,EAAoB,GAAIzF,GAAU1W,OAK7D,QAASoiB,KACDpiB,KAAKD,OAAOsiB,UACZriB,KAAKsiB,iBAAiBtiB,KAAKD,OAAOsiB,UAI1C,QAASE,GAAgCC,GACrC,GAAIC,GAAsBviB,EAAE6c,QAAQyF,EAAoB,SAASE,EAAYL,GACzE,GAAIM,SAAwBD,EAC5B,IAAsB,YAAlBC,EACA,MAAO3iB,MAAK4iB,GAAGP,EAAUK,EAE7B,IAAsB,UAAlBC,EAA4B,CAC5B,GAAIE,SAAqBH,GAAWI,OACpC,IAAmB,UAAfD,EACA,MAAO7iB,MAAK4iB,GAAGP,EAAUK,EAE7B,IAAmB,UAAfG,EAAyB,CACzB,GAAIH,EAAWI,SAAW9iB,KAAKC,MAA8B,SAAtByiB,EAAWI,QAC9CJ,GACIA,WAAYA,EAAWA,WACvBI,QAAS9iB,UAEZ,CAAA,GAA0B,SAAtB0iB,EAAWI,QAMhB,KAAM,IAAIzhB,GAAW,gDAAkDqhB,EAAWI,QALlFJ,IACIA,WAAYA,EAAWA,WACvBI,QAAS9iB,KAAKF,OAKtB,MAAOE,MAAK4iB,GAAGP,EAAUK,GAG7B,KAAM,IAAIrhB,GAAW,qDAAuDwhB,GAGhF,KAAM,IAAIxhB,GAAW,6CAA+CshB,IACrE3iB,KAEH,OAAOyiB,GAKX,QAASM,KACD/iB,KAAKZ,SACLY,KAAKZ,QAAQ8F,QAAQ,SAAS8d,GACpBhjB,KAAKF,MAAM8C,SAASogB,IACtBhjB,KAAKF,MAAM+D,SAASmf,IACzBhjB,MAMX,QAASijB,KACDjjB,KAAKmc,IAAqBnc,KAAKmc,GAAoB7R,UACvDtK,KAAKwgB,YAAa,EAStB,QAAS0C,KACL,GAAIC,GAAkBvE,EAAerE,uBAAuBva,KAAKF,MAAM6I,IAAI,EAAO3I,KAAKC,KACvF,OAAOkjB,IAAmBA,EAAgBnjB,KAAKC,MASnD,QAASmjB,KACL,GAAID,GAAkBnjB,KAAKF,MAAMmhB,eAAejhB,KAAKC,KACrD,OAAOkjB,IAAmBA,EAAgBnjB,KAAKC,MAInD,QAASojB,GAAYC,EAAiBC,EAAaC,GAC/C,GAAIC,GAAcH,EAAgB7jB,KAAKO,KACnCyjB,IACAA,EAAYrN,YAAYmN,EAAaC,GAI7C,QAASE,GAAkBC,GACvB3jB,KAAKmc,GAAoBuH,kBAAkBC,GAI/C,QAASC,KACL,MAAO5jB,MAAKmc,GAAoByH,mBAIpC,QAASC,GAAsBxhB,EAAS+d,GACpC,MAAOpgB,MAAK4jB,mBAAmBE,gBAAgBzhB,EAAS+d,GAI5D,QAAS2D,GAAqBC,EAAoBjG,GAC9C,GAAI4F,GAAgB,GAAIK,GAAmBhkB,KAAMgI,OAAWA,OAAWhI,KAAKF,MAAOie,EACnF/d,MAAK0jB,kBAAkBC,GAEvBzjB,EAAEwB,eAAe1B,KAAM,iBAAkB2jB,GAI7C,QAASM,GAA4BD,EAAoBE,EAAqBnG,GAC1E,GAAI4F,GAAgB,GAAIK,GAAmBhkB,KAAMgI,OAAWkc,EAAqBlkB,KAAKF,MAAOie,EAC7F/d,MAAK0jB,kBAAkBC,GAEvBzjB,EAAEwB,eAAe1B,KAAM,iBAAkB2jB,GAI7C,QAASQ,GAAcrjB,GAEnB,GAAIsjB,GAAepkB,KAAKoC,UAAUhD,OAElC,OAAOglB,KAAiBA,EAAaC,QAAQnkB,EAAEuX,eAAe3W,KAAe,GACtDsjB,EAAaC,QAAQnkB,EAAEC,eAAeW,KAAe,GA1MhF,GAAIjB,GAAQT,EAAQ,qBACdsX,EAAYtX,EAAQ,gBACpBiC,EAAajC,EAAQ,iBAAiBS,MACtC+e,EAAiBxf,EAAQ,aACzBc,EAAId,EAAQ,aAEdud,EAAiBzc,EAAEwD,eAAe7D,EAAO,iBAE7CD,GAAOJ,QAAUmd,CAWjB,IAAI2H,GAAgBpkB,EAAEqkB,QAAQlB,EAAaH,GAUvCsB,EAAkBtkB,EAAEqkB,QAAQlB,EAAaD,EAG7CljB,GAAEM,YAAYmc,GACVtc,KAAM6hB,EACN7F,MAAO+F,EACPtgB,MAAOihB,EACPzY,QAAS2Y,EACTX,iBAAkBC,EAClBW,UAAWA,EACXoB,cAAeA,EACflB,YAAaA,EACboB,gBAAiBA,EACjBZ,iBAAkBA,EAClBC,sBAAuBA,EACvB1B,iBAAkBA,EAClBuB,kBAAmBA,EACnBK,qBAAsBA,EACtBE,4BAA6BA,IAGjC/jB,EAAEkD,OAAOuZ,GACLwH,cAAeA,GAOnB,IAAIhI,GAAqB,YACzBzF,GAAUtQ,QAAQuW,EAAgBR,EAAoBzF,EAAUC,kBAkJ7D8N,oBAAoB,EAAExN,eAAe,GAAGlT,gBAAgB,GAAGge,YAAY,GAAGthB,YAAY,MAAMikB,IAAI,SAAStlB,EAAQQ,GACpH,YAsDA,SAAS+kB,KACL,MAAOnK,GAAWxa,KAAKF,MAAM6I,GAAI3I,KAAKoL,OAAO,GAQjD,QAASwZ,KACLjI,EAAeva,UAAUia,MAAM/b,MAAMN,KAAMO,WAC3CP,KAAKoL,MAAQ,GAAIQ,GAAM5L,KAAKF,MAAM6I,GAAI3I,MAc1C,QAAS6kB,GAAeC,GAcpB,QAASC,KACL,KAAM,IAAIzlB,OAAM,QAAUwlB,EAAO,eAdrCA,EAAOA,EAAKhd,MAAM,IAClB,IAAIkd,GAAMF,EAAKplB,QACXolB,EAAK,IAAY,EAANE,IAASD,GAExB,KAAK,GADDhG,GAAO/e,KAAKF,MACPT,EAAI,EAAO2lB,EAAJ3lB,EAASA,IAAK,CAC1B,GAAIY,GAAO6kB,EAAKzlB,EAEhB,IADK4lB,EAAmBrJ,KAAK3b,IAAO8kB,KAC/BhG,EAAK7S,UAAW,MAErB,IADA6S,EAAOA,EAAK7S,UAAUd,MAAMnL,IACvB8e,EAAM,OAEf,MAAOA,GAgBX,QAASmG,GAAmBpM,GACxB,GAAIX,IAAU/M,SAKd,OAJI0N,MAAa,GACb9Y,KAAKoL,MAAMW,MAAM,SAASmM,EAAWjQ,GACjCkQ,EAAM/M,MAAMnD,GAAYiQ,EAAUoB,cAEnCnB,EAWX,QAASgN,GAAmBhN,GACxBjY,EAAEqB,QAAQ4W,EAAM/M,MAAO,SAASga,EAAUnd,GACtC,GAAIiQ,GAAYlY,KAAKoL,MAAMnD,EACvBiQ,GACAA,EAAUqB,SAAS6L,GAEnB9iB,EAAOoQ,KAAK,cAAgBzK,EAAW,8BAC5CjI,MAGP,QAASqlB,KACLrlB,KAAKoL,MAAMW,MAAM,SAASmM,GACtBA,EAAU5N,YAEdtK,KAAKoL,MAAMka,iBACX3I,EAAeva,UAAUkI,QAAQhK,MAAMN,KAAMO,WAWjD,QAASglB,GAAiBC,EAAgBlb,GACtC4Q,EAASuK,cAAczlB,KAAKF,MAAM6I,IAClC3I,KAAKoL,OAASpL,KAAKoL,MAAMW,MAAM,SAAU2Z,GACrCA,EAAM3e,SACFye,KAAmB,GAAOE,EAAMxI,OAAOlV,QAAW,GACtDhI,KAAKF,MAAMsL,OAASpL,KAAKF,MAAMsL,MAAM6P,KAAKyK,IAC3C1lB,MACCsK,KAAY,GAAOtK,KAAKF,MAAMwK,UAStC,QAASqb,GAAiB5G,GACtB/e,KAAKoL,MAAM6P,KAAK8D,GAChB/e,KAAKF,MAAM6I,GAAGid,YAAY7G,EAAKpW,IAUnC,QAASkd,GAAuB9G,EAAM+G,GAClC9lB,KAAKoL,MAAM6P,KAAK8D,GAChB/e,KAAK2I,GAAG+U,aAAaqB,EAAKpW,GAAImd,GAAWA,EAAQnd,IAGrD,QAASod,GAAiBhH,GACtB/e,KAAKoL,MAAMkS,QAAQyB,GACnB/e,KAAKF,MAAM6I,GAAGqd,YAAYjH,EAAKpW,IAtLnC,GAAIgU,GAAiBvd,EAAQ,cACvBob,EAAapb,EAAQ,gBACrBwM,EAAQxM,EAAQ,YAChBc,EAAId,EAAQ,aACZsY,EAAiBtY,EAAQ,iBACzB8b,EAAW9b,EAAQ,kBACnBkD,EAASlD,EAAQ,qBAcnB6mB,EAAY/lB,EAAEwD,eAAeiZ,EAAgB,YAQjDzc,GAAEM,YAAYylB,GACV5J,MAAOuI,EACPE,KAAMD,EACNzM,SAAU8M,EACV3L,SAAU4L,EACVpa,OAAQ4Z,EACRra,QAAS+a,EACTa,OAAQX,EAERY,OAAQR,EACRjI,aAAcmI,EACd9e,OAAQgf,IAGZrO,EAAe/Q,IAAIsf,GAEnBrmB,EAAOJ,QAAUymB,CAsBjB,IAAIhB,GAAqB,+BAuHtBmB,eAAe,EAAEC,iBAAiB,GAAGC,oBAAoB,IAAIC,aAAa,GAAGC,WAAW,GAAGC,gBAAgB,GAAGhmB,YAAY,MAAMimB,IAAI,SAAStnB,EAAQQ,GACxJ,YA4FA,SAAS+mB,KAELC,EAAUC,qBAAqBpnB,KAAKO,MAEpC2c,EAAeva,UAAUia,MAAM/b,MAAMN,KAAMO,WAG3CP,KAAK8mB,OAASC,EAAqB/mB,KAAKF,MAAM6I,IAE9C3I,KAAKgnB,qBAELhnB,KAAKinB,wBAGLjnB,KAAKknB,MAAQ,IAAMlnB,KAAKF,MAAMG,KAG9BD,KAAKmnB,OAASnnB,KAAK8G,MAMnB9G,KAAKonB,OAAO,GAAIC,GAGhBrnB,KAAKonB,OAAO,sBAAuBE,GAGnCtnB,KAAKonB,OAAO,YAAaG,GAGzBvnB,KAAKonB,OAAO,aAAcI,GAiC9B,QAASP,KACL,GAAIQ,GAAU,GAAIC,GAAW1nB,KAAKF,OAC5B6nB,EAAmB,GAAIzZ,GAAgBlO,KAAM4nB,EAAwBH,EAASznB,KAAKF,MACzFE,MAAK0jB,kBAAkBiE,GAEvBznB,EAAEwB,eAAe1B,KAAM,oBAAqB2nB,GAI5CzjB,EAAM9B,UAAUmC,mBAAmB9E,KAAKgoB,EAAS,QAAS,QAASznB,MAWvE,QAASqnB,GAAgBQ,EAASzH,GAG9B,GAFApgB,KAAK8nB,oBAAoB1H,GACzBpgB,KAAK+nB,iBAAiB3H,GACJ,KAAdA,EAAK0E,KAAa,CAClB,GAAI/N,GAAgBiR,EAAmB5H,EACvCpgB,MAAKoW,YAAY,uBAAyBxB,YAAamC,KAY/D,QAASkR,GAAyBC,GAC9B,GAAIC,GAAanoB,KAAKojB,aAEtB,IAAI+E,EAAY,CACZ,GAAIC,GAAYloB,EAAEiD,MAAM+kB,EACxBE,GAAUtD,MAAQ9kB,KAAKknB,OAAU,IAAMlnB,KAAKF,MAAMG,MAAUmoB,EAAUtD,KACtEqD,EAAW/R,YAAY,YAAagS,GAAaF,IAYzD,QAASG,GAAsBC,GAC3BtoB,KAAKgnB,kBAAkBvX,KAAK6Y,GAWhC,QAAShB,GAAsBpR,EAAKkK,GAChCpgB,KAAKuoB,iBAAiBnI,EAAKrJ,cAC3B,IAAIoR,GAAanoB,KAAKojB,aAClB+E,IAAYA,EAAW/R,YAAY,sBAAuBgK,GAUlE,QAASoI,GAAsBzR,GAC3B,GAAI0R,GAAQzoB,KAAKgnB,kBAAkBnW,SACnC7Q,MAAKwM,gBAAgB,eACjBkc,QAASD,EACT7T,YAAamC,IAEjB/W,KAAKgnB,qBAWT,QAASO,GAAYM,EAASzH,GAC1BpgB,KAAKoW,YAAYgK,EAAK0E,KAAM1E,GAC5BpgB,KAAK8nB,oBAAoB1H,GACzBpgB,KAAK+nB,iBAAiB3H,GAY1B,QAASuI,GAASvnB,GACd,GAAI2V,GAAgBiR,EAAmBW,GAEnCC,EAAkB5oB,KAAKD,OAAOqK,GAClC,IAA8B,kBAAnBwe,GAA+B,CACtC,GAAItW,GAASsW,EAAgBnpB,KAAKO,KAAKF,MAAOsB,EAC9C,OAAOkR,GAGXuW,EAAmB7oB,KAAK8oB,KAAM/R,EAE9B,IAAIgS,GAAW/oB,KAAKmnB,OACd6B,EAAWhpB,KAAK8oB,KAAK1nB,GAIvB8U,GAAQ4O,KAAM,GAAIpJ,KAAM,UAChBsN,SAAUA,EAAUD,SAAUA,EAI1C,OAHAF,GAAmB3S,EAAKa,GACxB/W,KAAKoW,YAAY,GAAIF,GAEd8S,EAIX,QAASC,GAAU7nB,GA0Cf,QAAS8nB,GAAaC,EAAUC,EAAYC,EAAKC,GAC7C,GAAIC,GAAYD,EAAW9gB,QAAQ,KAAM6gB,GACrCG,EAAiBxpB,KAAK8kB,KAAKyE,EAAgC,mBAAdH,GAC7CI,KACAX,EAAmBW,EAAepf,IAAK2M,GACvCoS,EAASE,GAAOG,EAAepf,IAAIgf,IA9C3C,GAEID,GAFApS,EAAgBiR,EAAmBiB,EAGvC,IAAa,MAAT7nB,GAAiC,gBAATA,GACxB,GAAI4D,MAAMC,QAAQ7D,GAAQ,CACtB+nB,IAEA,IAAIM,GAAYzpB,KAAKF,MAAM4pB,IAC3B,IAAID,EAAU,CACV,GAAIE,GAAaF,EAAUG,QACrBC,EAAgBzoB,EAAM1B,OAASiqB,CACjCE,IAAiB,IACjBJ,EAAUK,UAAUD,GACpBJ,EAAUM,iBAAiBJ,EAAYF,EAAUG,UAGrDxoB,EAAM8D,QAAQ,SAASkkB,EAAYY,GAC/Bd,EAAazpB,KAAKO,KAAMmpB,EAAUC,EAAYY,EAAO,SACtDhqB,KAKH,KAHA,GAAIiqB,GAAYR,EAAUG,QACpBM,EAAcD,EAAY7oB,EAAM1B,OAE/BwqB,IAAgB,GACnBT,EAAUU,YAAY/oB,EAAM1B,YAEhC4C,GAAOoQ,KAAK,mDAEhByW,MACAjpB,EAAEqB,QAAQH,EAAO,SAASgoB,EAAYC,GAClCH,EAAazpB,KAAKO,KAAMmpB,EAAUC,EAAYC,EAAK,QACpDrpB,UAGPmpB,GAAWnpB,KAAKoqB,gBAAgBhpB,EAIpC,OAFApB,MAAKmnB,OAASgC,EAEPA,EAoBX,QAASkB,KACL,GAAItT,GAAgBiR,EAAmBqC,GAEnCC,EAAkBtqB,KAAKD,OAAOwqB,GAClC,IAA8B,kBAAnBD,GAA+B,CACtC,GAAIhY,GAASgY,EAAgB7qB,KAAKO,KAAKF,MAEvC,OADA0qB,GAAwB/qB,KAAKO,KAAM+W,GAC5BzE,EAGX,GAAIyW,GAAW/oB,KAAKmnB,MAEpB0B,GAAmB7oB,KAAKyqB,KAAM1T,GAC9B/W,KAAKyqB,MAIL,IAAIvU,IAAQ4O,KAAM,GAAIpJ,KAAM,UAAWqN,SAAUA,EACjDF,GAAmB3S,EAAKa,GACxB/W,KAAKoW,YAAY,GAAIF,GAIzB,QAASwU,KACL,GAAI3T,GAAgBiR,EAAmB0C,EACvC7B,GAAmB7oB,KAAK8oB,KAAM/R,GAC9B/W,KAAK8oB,OAWT,QAAS6B,GAAqBvpB,GAC1B,MAAOpB,MAAK8mB,OAAO1c,IAAIpK,KAAKF,MAAM6I,GAAIvH,GAY1C,QAASwpB,GAASC,GACd,GAAIC,GAAkB9qB,KAAKD,OAAO+G,GAClC,OAA8B,kBAAnBgkB,GACAA,EAAgBrrB,KAAKO,KAAKF,MAAO+qB,GAErC7qB,KAAK+qB,KAAKF,GAGrB,QAASG,GAAUH,GACf,GAAIA,KAAY,EAAhB,CAGA,GACMI,GADFlM,EAAO/e,KAAKF,KAyBhB,OAtBIif,GAAK2K,MACLuB,KACAlM,EAAK2K,KAAK5Y,KAAK,SAASoa,EAAUlB,GAC9BiB,EAAUjB,GAASkB,EAAS9K,KAAKtZ,QAGjCiY,EAAK7S,WACL6S,EAAK7S,UAAUd,MAAMW,MAAM,SAASof,EAAWlrB,IACrC8e,EAAK2K,KAAK0B,SAASD,IAAcA,EAAU/K,OAC7C6K,EAAUhrB,GAAQkrB,EAAU/K,KAAKtZ,UAEtCiY,EAAK7S,WACZ+e,KACAlM,EAAK7S,UAAUd,MAAMW,MAAM,SAASof,EAAWlrB,GACvCkrB,EAAU/K,OACV6K,EAAUhrB,GAAQkrB,EAAU/K,KAAKtZ,UAGzCmkB,EAAYjrB,KAAKqrB,kBAErBrrB,KAAKmnB,OAAS8D,EAEPA,GAUX,QAASK,KACL,MAAOtrB,MAAK8mB,OAAOhgB,IAAI9G,KAAKF,MAAM6I,IActC,QAAS4iB,KACL,GACIjZ,GADAyE,EAAgBiR,EAAmBuD,GAGnCC,EAAkBxrB,KAAKD,OAAO0rB,MAClC,IAA8B,kBAAnBD,GAGP,MAFAlZ,GAASkZ,EAAgBlrB,MAAMN,KAAKF,MAAOS,WAC3CiqB,EAAwB/qB,KAAKO,KAAM+W,GAC5BzE,CAMX,IAHAuW,EAAmB7oB,KAAK0rB,QAAS3U,GACjCzE,EAAStS,KAAK0rB,QAAQprB,MAAMN,KAAMO,WAElC,CAEA,GAAI2V,IAAQ4O,KAAM,GAAIpJ,KAAM,SAChBsO,MAAO1X,EAAOqZ,YACdC,QAAStZ,EAAOsZ,QAChBC,WAAYvZ,EAAOuZ,WACnB7C,SAAUhpB,KAAKmnB,OAI3B,OAHA0B,GAAmB3S,EAAKa,GACxB/W,KAAKoW,YAAY,GAAIF,GAEd5D,EAAOsZ,SAIlB,QAASE,GAAaH,EAAaI,GAC/B,GAAIhV,GAAgBiR,EAAmB8D,GAEnCrC,EAAYzpB,KAAKF,MAAM4pB,IAC3B,KAAMD,EACF,MAAOnnB,GAAOoQ,KAAK,oDAEvB,IAAIkZ,MAEAjC,EAAaF,EAAUG,OAI3B,IAHArpB,UAAU,GAAKorB,EACXK,EAAWC,qBAAqBN,EAAahC,GAE7CoC,EAAgB,GAAKpC,EAAa,EAAG,CACrC,IAAK,GAAItqB,GAAIssB,EAAiBA,EAAcI,EAAlB1sB,EAAiCA,IAAK,CAC5D,GAAI6sB,GAAOzC,EAAUyC,KAAKP,EAC1B,IAAIO,EAAM,CACN,GAAIC,GAAWD,EAAK9L,KAAKtZ,KACzB2iB,GAAUU,YAAYwB,OAEtBrpB,GAAOoQ,KAAK,0BAA2BrT,EAE3CusB,GAAQnc,KAAK0c,GAGjB1C,EAAUM,iBAAiB4B,EAAalC,EAAUG,SAGtD,GAAIwC,MAEAC,EAAU9rB,UAAUb,OAClB4sB,EAAWD,EAAU,EACrBR,EAAaQ,EAAU,CAC7B,IAAIC,EAAU,CACV7C,EAAUK,UAAU+B,EAAYF,EAChC,KAAK,GAAItsB,GAAI,EAAGktB,EAAIZ,EAAiBU,EAAJhtB,EAAaA,IAAKktB,IAAK,CACpD,GAAIL,GAAOzC,EAAUyC,KAAKK,EAC1B,IAAIL,EAAM,CACNrD,EAAmBqD,EAAK9L,KAAKhW,IAAK2M,EAClC,IAAIoV,GAAWD,EAAK9L,KAAKhW,IAAI7J,UAAUlB,QAEvCiD,GAAOoQ,KAAK,0BAA2B6Z,EAE3CH,GAAM3c,KAAK0c,GAIf1C,EAAUM,iBAAiB4B,EAAalC,EAAUG,SAStD,MAFI5pB,MAAKmnB,OAASnnB,KAAK8G,OAGnB6kB,YAAaA,EACbC,QAASA,EACTC,WAAYS,EAAWT,EAAa;CAK5C,QAASW,KACL,GAAIC,GAAezsB,KAAKD,OAAOilB,GAC/B,OAA2B,kBAAhByH,GACAA,EAAahtB,KAAKO,KAAKF,OAEvBE,KAAK0sB,OAIpB,QAASC,KACL,MAAI3sB,MAAKF,MAAM4pB,KAAa1pB,KAAKF,MAAM4pB,KAAKE,YACvCtnB,GAAOC,MAAM,uCAStB,QAASqqB,GAAUC,EAAYC,GAG3B,IAAMD,EACF,MAAO7sB,KAKX,KAAK,GAHD+sB,GAAanG,EAAUoG,gBAAgBH,GACvCI,EAAmBjtB,KAAKF,MAEnBT,EAAI,EAAG2lB,EAAM+H,EAAWrtB,OAAYslB,EAAJ3lB,EAASA,IAAK,CACnD,GAAI6tB,GAAWH,EAAW1tB,GACpB8tB,EAAUvG,EAAUwG,eAAeF,EACzC,IAAuB,SAAnBA,EAASG,QAAqBJ,EAAiBvD,KAAM,CACrD,GAAI4D,GAAgBL,EAAiBvD,KAAKwC,KAAKiB,EACzCG,IAAiBR,KAAe,IAClCQ,EAAgBL,EAAiBvD,KAAK6D,SAASJ,GAC/CG,EAAclN,KAAK8G,MAAQgG,EAASM,UAExCP,EAAmBK,MACZL,GAAiB/gB,YACxB+gB,EAAmBA,EAAiB/gB,UAAUd,MAAM+hB,GAExD,IAAIM,GAAmBR,GAAoBA,EAAiB7M,IAC5D,KAAMqN,EACF,MAGR,MAAOA,GAUX,QAASC,KACL,MAAO1tB,MAAKknB,MAWhB,QAASyG,KACL,GAAI7I,GAAO9kB,KAAKknB,KAChB,OAAkB,KAAXpC,EAAK,IACDA,EAAK1S,MAAM,EAAG,IACf0S,EAAK1S,MAAM,GAYzB,QAASwb,GAAc1P,GACnB,OAAS/F,MAAOnY,KAAK8G,IAAIoX,IAW7B,QAAS2P,GAAc1V,GACnB,MAAOnY,MAAKoK,IAAI+N,EAAMA,OA7oB1B,GAAIjU,GAAQ9E,EAAQ,wBACdud,EAAiBvd,EAAQ,cACzBsY,EAAiBtY,EAAQ,iBAGzB8O,GADY9O,EAAQ,mBACFA,EAAQ,0BAC1BsoB,EAAatoB,EAAQ,mBACrB2nB,EAAuB3nB,EAAQ,sBAC/BwnB,EAAYxnB,EAAQ,0BACpB0uB,EAAY1uB,EAAQ,sBACpB4sB,EAAa5sB,EAAQ,2BACrBooB,EAAoBpoB,EAAQ,2BAC5B4oB,EAAqBR,EAAkBQ,mBACvCa,EAAqBrB,EAAkBqB,mBACvC2B,EAA0BhD,EAAkBgD,wBAE5CtqB,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,qBAOnB2uB,EAAO7tB,EAAEwD,eAAeiZ,EAAgB,OAW5Czc,GAAEM,YAAYutB,GACV1R,MAAOsK,EACPvO,SAAUwV,EACVrU,SAAUsU,EAEV/mB,IAAK8jB,EACLxgB,IAAKue,EACL4B,IAAKF,EACLoB,OAAQF,EACRvG,IAAKwH,EACL1H,KAAM8H,EACNoB,QAASN,EACTO,OAAQN,EAER5C,KAAMC,EACNlC,KAAMG,EACNwB,KAAMC,EACNgB,QAASI,EACTY,KAAMC,EAENvC,gBAAiBO,EACjBU,gBAAiBC,EACjBxD,oBAAqBG,EACrBF,iBAAkBM,EAClBE,iBAAkBC,EAClBvB,sBAAuBA,IAG3BvP,EAAe/Q,IAAIonB,GAEnBnuB,EAAOJ,QAAUuuB,GAMhB,OAAQ,MAAO,UAAW,SAAS7oB,QAAQ,SAASC,GACjD,GAAIP,GAASkpB,EAAU1rB,UAAU+C,EACjCjF,GAAEwB,eAAeqsB,EAAK3rB,UAAW+C,EAAYP,IAMjD,IAAIgjB,IAEIsG,QAAS,aA+jBdC,uBAAuB,EAAEC,kBAAkB,GAAGC,0BAA0B,GAAGC,qBAAqB,GAAGC,0BAA0B,GAAGC,yBAAyB,GAAGlI,oBAAoB,IAAIC,aAAa,GAAGkI,kBAAkB,GAAGC,qBAAqB,GAAGC,wBAAwB,GAAGlI,gBAAgB,GAAGhmB,YAAY,MAAMmuB,IAAI,SAASxvB,EAAQQ,GACzU,YAkCA,SAASivB,GAAmB9uB,GACxB,GAAIoa,GAAYpa,EAAOoa,cACjB2U,EAAU3U,EAAU2U,SAAW,MAC/B9V,EAAQhM,SAASqN,cAAcyU,GAC/B1U,EAAUra,EAAOqa,QACjBH,EAAWla,EAAOka,QAYxB,OARA8U,GAAsB/V,EAAOmB,GAEP,gBAAXC,KAEHpB,EAAMS,UADNQ,EACkB+U,EAAI/U,SAASA,IAAWG,QAASA,IAEjCA,GAEnBpB,EAIX,QAAS+V,GAAsBpmB,EAAI5I,GAC/B,GAAIkvB,GAAalvB,GAAUA,EAAOmvB,IAC5BC,EAAmBpvB,GAAUA,EAAOsJ,UAEtC8lB,IACAjvB,EAAEqB,QAAQ4tB,EAAkB,SAASC,EAAWhoB,GAC5CuB,EAAGuB,aAAa9C,EAAUgoB,KAG9BH,GACAI,EAAkB1mB,EAAI,MAAOsmB,GAwCrC,QAAS5S,KACL,GAAI1T,GAAK3I,KAAKF,MAAM6I,EACpBomB,GAAsBpmB,EAAI3I,KAAKD,OAC/B,IAAIuvB,GAAeC,OAAOC,iBAAiB7mB,EAC3C3I,MAAKyvB,SAAWH,GAAwC,QAAxBA,EAAaI,QAIjD,QAASC,KACL3vB,KAAK4vB,QAAO,GAIhB,QAASC,KACL7vB,KAAK4vB,QAAO,GAIhB,QAASA,GAAOE,GACZA,EAA0B,mBAAVA,IACA9vB,KAAKyvB,WACJK,EAEjB9vB,KAAKyvB,SAAWK,CAChB,IAAInnB,GAAK3I,KAAKF,MAAM6I,EAIpB,OAFAA,GAAGonB,MAAML,QAAUI,EAAS,QAAU,OAE/BA,EAIX,QAASE,GAAkB7qB,EAAY8pB,EAAYgB,GAC/CZ,EAAkBrvB,KAAKF,MAAM6I,GAAIxD,EAAY8pB,EAAYgB,GAI7D,QAASZ,GAAkB1mB,EAAIxD,EAAY8pB,EAAYgB,GAWnD,QAASC,GAAWC,GAChBC,EAEkBpoB,SAAZioB,EAAwBI,EAAUlrB,GAAYgrB,GAAUE,EAAUlrB,GAAYgrB,EAAQF,GACtFI,EAAUlrB,GAAYgrB,GAdhC,GAAIE,GAAY1nB,EAAG0nB,UACbD,EAAyB,UAAdjrB,CAEjB,IAAIH,MAAMC,QAAQgqB,GACdA,EAAW/pB,QAAQgrB,OAClB,CAAA,GAAyB,gBAAdjB,GAGZ,KAAM,IAAIqB,GAAc,wCAFxBJ,GAAWjB,IAanB,QAASsB,KACDvwB,KAAKF,MAAM6I,IACXuS,EAASuF,gBAAgBzgB,KAAKF,MAAM6I,IAI5C,QAAS6nB,GAAShD,EAAUpsB,GACxB,IAAKpB,KAAKF,MAAM6I,GACZ,KAAM,IAAIrJ,OAAM,kDAAoDU,KAAKF,MAAMM,YAAYH,KAE/FD,MAAKF,MAAM6I,GAAGonB,MAAMvC,GAAYpsB,EAGpC,QAASqvB,GAAUC,GACf,IAAK,GAAIlD,KAAYkD,GACjB1wB,KAAKF,MAAM6I,GAAGonB,MAAMvC,GAAYkD,EAAWlD,GAKnD,QAAStU,GAAKyX,GACV,MAAO3wB,MAAKF,MAAM6I,IAAM3I,KAAKF,MAAM6I,GAAGwQ,UAAUwX,GAIpD,QAAStW,KACL,GAAIrB,GAAQc,EAAIO,cAAcra,KAAKD,OACnC,OAAOiZ,GAKX,QAASjS,KACLmU,EAASwF,cAAc1gB,KAAKF,MAAM6I,IAItC,QAASwd,GAAOxd,GACZ3I,KAAKF,MAAM6I,GAAGid,YAAYjd,GAI9B,QAASioB,GAAQjoB,GACb,GAAIkoB,GAAS7wB,KAAKF,MAAM6I,GAClBmoB,EAAaD,EAAOC,UACtBA,GACAD,EAAOnT,aAAa/U,EAAImoB,GAExBD,EAAOjL,YAAYjd,GAI3B,QAASooB,GAAepoB,GACpB,KAAMA,EAAGgE,WAAWjN,QAChBM,KAAKmmB,OAAOxd,EAAGgE,WAAW,IAIlC,QAASqkB,GAAgBroB,GACrB,KAAMA,EAAGgE,WAAWjN,QAChBM,KAAK4wB,QAAQjoB,EAAGgE,WAAWhE,EAAGgE,WAAWjN,OAAS,IAG1D,QAASuxB,GAAYtoB,GACjB,GAAIkoB,GAAS7wB,KAAKF,MAAM6I,GAClB2R,EAASuW,EAAOvR,UACtBhF,GAAOoD,aAAa/U,EAAIkoB,EAAOK,aAGnC,QAASxT,GAAa/U,GAClB,GAAIkoB,GAAS7wB,KAAKF,MAAM6I,GAClB2R,EAASuW,EAAOvR,UACtBhF,GAAOoD,aAAa/U,EAAIkoB,GAK5B,QAASM,KACL,GAAI7W,GAASta,KAAKF,MAAMmhB,gBACpB3G,IAAQA,EAAO3R,GAAGid,YAAY5lB,KAAKF,MAAM6I,IAUjD,QAASyoB,KACL,MAAOlW,GAASxR,SAAS1J,KAAKF,MAAM6I,IAaxC,QAAS6S,GAAK6V,EAAWC,GACrB,IAAMC,EAAe/tB,eAAe6tB,GAChC,KAAM,IAAIf,GAAc,6BAA+Be,EAE3D,IAAI1oB,GAAK3I,KAAKF,MAAM6I,GACdyC,EAAQpL,KAAKF,MAAMsL,MACnBomB,EAAaxkB,SAASykB,iBAAiBrmB,EAAMS,QAAS6lB,WAAWC,aAEvEH,GAAWI,YAAcjpB,CAKzB,KAJA,GAAIkpB,GAAWL,EAAWD,EAAeF,MAEnCS,GADkBtwB,OAAO+V,KAAKnM,IACtB,GAEPymB,GAAU,CACb,GAAI/oB,GAAO,GAAIC,GAAc8oB,EAC7B,IAAI/oB,EAAKvB,OACLuB,EAAKxB,QAAQY,WACTkD,EAAM5H,eAAesF,EAAKb,WAAW,CACrC,GAAIiQ,GAAY9M,EAAMtC,EAAKb,SAC3B,KAAMqpB,GAAYA,EAASpZ,GAAY,CACnC4Z,GAAQ,CACR,QAIZN,EAAWI,YAAcC,EACzBA,EAAWL,EAAWD,EAAeF,MAGzC,MAAIS,GAAc5Z,EAAlB,OAKJ,QAAS6Z,KACL,GAAIC,GAAYzC,OAAO0C,cACvB,KAAMD,EAAUE,YAAa,OAAO,CAEpC,IAAIC,GAAOH,EAAUI,WAAaJ,EAAUI,UAAUC,YAClDC,EAAWH,GAA0B,KAAlBA,EAAKI,OAAO,GAAY,EAAI,CACnD,IAAIP,EAAUQ,cAAgBF,EAAU,OAAO,CAG/C,IAAId,GAAaxkB,SAASykB,iBAAiBzxB,KAAKF,MAAM6I,GAAI+oB,WAAWe,UACrEjB,GAAWI,YAAcI,EAAUU,UACnC,IAAIC,GAAWnB,EAAWoB,eAEtBC,EAASF,EAAyC,KAA7BA,EAASG,UAAUC,QAAe,CAE3D,OAAOF,GAIX,QAASG,KACL,GAAIhB,GAAYzC,OAAO0C,cACvB,KAAMD,EAAUE,YAAa,OAAO,CAEpC,IAAIC,GAAOH,EAAUI,WAAaJ,EAAUI,UAAUC,YAClDC,EAAWH,GAAsC,KAA9BA,EAAKI,OAAOJ,EAAKzyB,OAAO,GAAYsyB,EAAUU,WAAWhzB,OAAO,EAAIsyB,EAAUU,WAAWhzB,MAChH,IAAIsyB,EAAUQ,aAAeF,EAAU,OAAO,CAG9C,IAAId,GAAaxkB,SAASykB,iBAAiBzxB,KAAKF,MAAM6I,GAAI+oB,WAAWe,UACrEjB,GAAWI,YAAcI,EAAUU,UACnC,IAAIb,GAAWL,EAAWK,WAGtBgB,EAAShB,EAAyC,KAA7BA,EAASiB,UAAUC,QAAe,CAE3D,OAAOF,GA3UX,GAAIlW,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBAGhB2J,GAFQjH,EAAME,MACL5C,EAAQ,gBACDA,EAAQ,4BACxBkxB,EAAgBlxB,EAAQ,oBAAoB6zB,SAC5C/X,EAAW9b,EAAQ,kBAEnB4vB,GADS5vB,EAAQ,gBACXA,EAAQ,QAOhB0a,EAAM5Z,EAAEwD,eAAeiZ,EAAgB,MAE3Czc,GAAEkD,OAAO0W,GACLO,cAAewU,IA8CnB3uB,EAAEM,YAAYsZ,GACVuC,MAAOA,EAEPsT,KAAMA,EACNE,KAAMA,EACND,OAAQA,EACRW,OAAQA,EACRxpB,OAAQA,EACRof,OAAQA,EACRyK,QAASA,EACTG,eAAgBA,EAChBC,gBAAiBA,EACjBC,YAAaA,EACbvT,aAAcA,EACdyT,oBAAqBA,EACrBznB,SAAU0nB,EACVZ,SAAUA,EACVC,UAAWA,EACXvX,KAAMA,EACNmB,cAAeA,EAEf6Y,cAAehzB,EAAEqkB,QAAQyL,EAAmB,OAC5CmD,iBAAkBjzB,EAAEqkB,QAAQyL,EAAmB,UAC/CoD,iBAAkBlzB,EAAEqkB,QAAQyL,EAAmB,UAE/CxU,KAAMA,EACNuW,uBAAwBA,EACxBiB,sBAAuBA,IAG3Btb,EAAe/Q,IAAImT,GAEnBla,EAAOJ,QAAUsa,CA2JjB,IAAIyX,IACA8B,GAAM,eACNC,KAAQ,cA+ETC,0BAA0B,EAAEnN,eAAe,EAAEoN,eAAe,GAAGC,mBAAmB,GAAGpN,iBAAiB,GAAGqN,mBAAmB,GAAGnN,aAAa,GAAGE,gBAAgB,GAAGkN,IAAM,IAAIlzB,YAAY,MAAMmzB,IAAI,SAASx0B,EAAQQ,GACtN,YAyCA,SAASi0B,KACLlX,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,WAE1CP,KAAKikB,4BAA4B/V,GACjClO,KAAK8zB,YAEL,IAAIC,GAAe/zB,KAAKD,OAAOi0B,eAAiB,EAChDh0B,MAAKg0B,cAAuC,kBAAhBD,GACFA,EACA,WAAa,MAAOA,IAUlD,QAASE,GAAeC,GACpB,MAAMl0B,MAAKF,MAAM6I,GAAGyiB,SAAS8I,QAE7Bl0B,KAAKm0B,YAAcD,GADR5xB,EAAOoQ,KAAK,sDAK3B,QAAS0hB,KACLzX,EAAeva,UAAUia,MAAM/b,MAAMN,KAAMO,WAC3C8zB,EAAkB50B,KAAKO,MAEvBA,KAAKs0B,YACDC,UAAaC,EACbC,kCAAmCC,EACnCC,UAAaC,EACbC,KAAQC,EACRC,QAAWC,IAGfh1B,KAAKF,MAAMw0B,YACPW,iBACMvS,WAAYwS,EAAsBpS,QAAS9iB,MACjDm1B,mBACMzS,WAAY2R,EAAmBvR,QAAS9iB,QAUtD,QAASq0B,KACDr0B,KAAKF,MAAM6I,IACX3I,KAAKF,MAAM6I,GAAGuB,aAAa,aAAa,GAIhD,QAASgrB,KACDl1B,KAAKF,MAAM6I,IACX3I,KAAKF,MAAM6I,GAAGa,gBAAgB,aAItC,QAASgrB,GAAYY,EAAWC,GAC5Br1B,KAAKs1B,kBAAoBD,EAAME,OAC3BC,EAAmB/1B,KAAKO,QACxBuvB,OAAO0C,eAAewD,QACtBJ,EAAMK,mBAKd,QAAShB,GAAgBU,EAAWC,GAChC,GAAIM,GAAoBH,EAAmB/1B,KAAKO,KAChDA,MAAKF,MAAM6I,GAAGuB,aAAa,YAAayrB,GACkB,SAAtD3oB,SAASC,KAAKjD,aAAa,yBAC3BqrB,EAAMK,kBAId,QAASd,GAAYQ,EAAWC,GAqB5B,QAASO,KACL,GAAIC,GAAa71B,KAAKD,OAAO+1B,KACvBC,EAAeF,GAAcA,EAAWG,OACxCC,EAAiBJ,GAAcA,EAAWzV,KAE5C4V,EAAS91B,EAAEoS,OAAOyjB,EAAcj2B,GAC9BsgB,EAAOlgB,EAAEoS,OAAO2jB,EAAgBn2B,EAEtCE,MAAKk2B,kBAAoBC,EAAGC,iBAAiBt2B,EAAOk2B,EAAQ5V,GAC5DpgB,KAAKq2B,cAAgBjW,EAGzB,QAASkW,KACDt2B,KAAKD,OAAOw2B,YACZv2B,KAAKw2B,eAAiBt2B,EAAE6c,QAAQ/c,KAAKD,OAAOw2B,UAAW,SAAUE,EAAalb,GAC1E,GAAI6E,GAAOqW,EAAYh3B,KAAKO,KAAKF,MAAOyb,EAGxC,OAFmB,gBAAR6E,KAAkBA,EAAO/H,KAAKC,UAAU8H,IAC/CA,GAAM+V,EAAGO,QAAQnb,EAAU6E,GACxBA,GACRpgB,OAtCX,GADAq1B,EAAMK,kBACF11B,KAAKD,OAAO42B,MAASnB,EAAmB/1B,KAAKO,MAE7C,WADAq1B,GAAMuB,gBAIV,IAAI92B,GAAQE,KAAKF,MACbq2B,EAAK,GAAIU,GAASxB,EAEtBr1B,MAAK8zB,UAAYqC,EAAGW,kBAAkBh3B,GACtC81B,EAAQn2B,KAAKO,MACbs2B,EAAuB72B,KAAKO,MAC5B+2B,EAAmBt3B,KAAKO,KAAMm2B,GAE9BU,EAASG,QAAQxqB,gBAAgB,mBAC7B4oB,UAAW,YACX6B,SAAUd,EACVe,UAAWl3B,OA4BnB,QAAS80B,GAAWM,EAAWC,GAC3B,IAAI8B,EAAgB13B,KAAKO,KAAMq1B,GAA/B,CAEA,GAAIc,GAAK,GAAIU,GAASxB,EACtBc,GAAGW,kBAAkB92B,KAAKF,MAAOE,KAAK8zB,WACtCqC,EAAGO,QAAQ12B,KAAKk2B,kBAAmBl2B,KAAKq2B,eACpCr2B,KAAKw2B,gBACLt2B,EAAEqB,QAAQvB,KAAKw2B,eAAgB,SAASpW,EAAM7E,GACtC6E,GAAM+V,EAAGO,QAAQnb,EAAU6E,KAIvC2W,EAAmBt3B,KAAKO,KAAMm2B,IAIlC,QAASnB,GAAUI,EAAWC,GAC1B,IAAI8B,EAAgB13B,KAAKO,KAAMq1B,GAA/B,CAEAA,EAAMK,iBACN,IAAIS,GAAK,GAAIU,GAASxB,EACtBwB,GAASG,QAAQxqB,gBAAgB,oBAC7B4oB,UAAW,UACX6B,SAAUd,EACVe,UAAWl3B,QAKnB,QAAS+2B,GAAmBF,GACxB,GAAIO,GAAUl3B,EAAEoS,OAAOtS,KAAKD,OAAOs3B,eAAgBr3B,KAAKF,MACxD+2B,GAASS,kBAAkBF,GAI/B,QAAS5B,KACL,OAASx1B,KAAKm0B,aAAen0B,KAAKm0B,YAAY/I,SAASprB,KAAKs1B,mBAIhE,QAAS6B,GAAgB9B,GACrB,MAAIr1B,MAAKD,OAAO42B,KACZtB,EAAMuB,kBACC,IAEJ,EAhNX,GAAIja,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzB8O,EAAkB9O,EAAQ,yBAE1By3B,GADYz3B,EAAQ,cACTA,EAAQ,wBACnBc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,qBAiBnBm4B,EAAOr3B,EAAEwD,eAAeiZ,EAAgB,OAE5Czc,GAAEM,YAAY+2B,GACVl3B,KAAMwzB,EACNxX,MAAO+X,EACPoD,UAAWvD,IAGfvc,EAAe/Q,IAAI4wB,GAEnB33B,EAAOJ,QAAU+3B,IAkLdE,sBAAsB,GAAGnR,oBAAoB,IAAIoR,aAAa,GAAGnR,aAAa,GAAGoI,wBAAwB,GAAGlI,gBAAgB,GAAGhmB,YAAY,MAAMk3B,IAAI,SAASv4B,EAAQQ,GACzK,YAwEA,SAASg4B,KACLjb,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,WAC1CP,KAAKikB,4BAA4B/V,EAAiB,GAAI2pB,IAI1D,QAASC,KACLnb,EAAeva,UAAUia,MAAM/b,MAAMN,KAAMO,WAC3CP,KAAKF,MAAM6I,GAAG0nB,UAAU1pB,IAAI,sBAC5B3G,KAAKs0B,YACDyD,qBAAsBjD,EACtBkD,KAAQC,EACRC,mDAAoDC,IAK5D,QAASrD,GAAWM,EAAWC,GAC3B,GAAIc,GAAK,GAAIU,GAASxB,EAEtBA,GAAMK,kBACNL,EAAMuB,iBAEAwB,EAAsB34B,KAAKO,KAAMm2B,IACnCA,EAAGkC,cAAc,QAIzB,QAASJ,GAAO7C,EAAWC,GACvBA,EAAMK,iBACN,IAAIS,GAAK,GAAIU,GAASxB,EACtBwB,GAASG,QAAQxqB,gBAAgB,qBAC7B4oB,UAAW,OACX6B,SAAUd,EACVmC,UAAWt4B,KACXkY,UAAWlY,KAAKF,QAKxB,QAASq4B,GAAc/C,EAAWC,GAC9BwB,EAASG,QAAQxqB,gBAAgB4oB,GAC7BC,MAAOA,EACPiD,UAAWt4B,KACXkY,UAAWlY,KAAKF,QAMxB,QAASy4B,GAAgCpC,EAAIqC,GACzC,GAAIC,GAAQz4B,KAAKD,OAAO04B,MAClBC,GAAgB,CAItB,IAFAF,EAAwBA,GAAyBx4B,KAAKF,MAElD24B,GAASA,EAAME,YAAa,CAC5B,GAAIre,GAASta,KAAKF,MAAMmhB,eAAe,OACnC3G,KACAoe,EAAgBH,EAAgC94B,KAAK6a,EAAO0d,KAAM7B,EAAIqC,IAG9E,MAAOE,IAAiBE,EAAen5B,KAAKO,KAAMm2B,EAAIqC,GAU1D,QAASI,GAAezC,EAAIqC,GACxB,GAAIC,GAAQz4B,KAAKD,OAAO04B,KAExB,IAAItC,EAAGtV,cAAe,CAClB,GAAIgY,GAAaJ,GAASA,EAAMK,WAC1BhD,EAAOK,EAAG4C,kBAEhB,cAAeF,IACX,IAAK,YACD,OAAO,CACX,KAAK,UACD,MAAOA,EAEX,KAAK,SACD,MAAO/C,IAAQA,EAAKluB,WAAaixB,CAErC,KAAK,WACD,MAAOA,GAAWp5B,KAAKO,KAAKF,MAAOg2B,EAAMK,EAAIqC,EACjD,KAAK,SACD,GAAIxzB,MAAMC,QAAQ4zB,GAEd,MAAOA,GAAWxU,QAAQyR,GAAQA,EAAKluB,YAAc,CAGrD,IAAIgU,GAAOid,EAAW/C,GAAQA,EAAKluB,UACnC,SAAU1H,EAAEoS,OAAOsJ,EAAM5b,KAAKF,MAAOg2B,EAAMK,EAEnD,SACI,KAAM,IAAI6C,GAAU,+CAEzB,CACH,GAAIzC,GAAYkC,GAASA,EAAMlC,SAC/B,cAAeA,IACX,IAAK,YACD,OAAO,CACX,KAAK,SACD,MAAOJ,GAAG1a,MAAM4I,QAAQkS,IAAc,IA/KtD,GAOM6B,GAPFzb,EAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzB8O,EAAkB9O,EAAQ,yBAC1By4B,EAAaz4B,EAAQ,mBACrBy3B,EAAWz3B,EAAQ,uBACnB45B,EAAY55B,EAAQ,oBAAoB65B,KACxC/4B,EAAId,EAAQ,aA+Cd65B,EAAO/4B,EAAEwD,eAAeiZ,EAAgB,OAG5Czc,GAAEM,YAAYy4B,GACV54B,KAAMu3B,EACNvb,MAAOyb,IAIXpgB,EAAe/Q,IAAIsyB,GAEnBr5B,EAAOJ,QAAUy5B,EAoDjBb,EAAwBl4B,EAAEg5B,SAASX,EAAiC,MAkEjEd,sBAAsB,GAAG/D,mBAAmB,GAAGnN,aAAa,GAAG4S,kBAAkB,GAAGxK,wBAAwB,GAAGlI,gBAAgB,GAAGhmB,YAAY,MAAM24B,IAAI,SAASh6B,EAAQQ,GAC5K,YAkDA,SAASy5B,KACL1c,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,UAE1C,IAAI+4B,GAAkB,GAAIprB,GAAgBlO,KAAMgI,OAAWA,OAAWhI,KAAKF,MAC3EE,MAAK0jB,kBAAkB4V,GACvBp5B,EAAEwB,eAAe1B,KAAMu5B,EAAgBD,GArD3C,GAAI3c,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBAEzB8O,GADY9O,EAAQ,mBACFA,EAAQ,0BAC1Bc,EAAId,EAAQ,aAedo6B,EAASt5B,EAAEwD,eAAeiZ,EAAgB,SAQ9Czc,GAAEM,YAAYg5B,GACVn5B,KAAMg5B,IAIV3hB,EAAe/Q,IAAI6yB,GAEnB55B,EAAOJ,QAAUg6B,CAMjB,IAAID,GAAiB,kBACrBrrB,GAAgB9H,QAAQozB,EAAQD,GAAiB,cAe9CnL,kBAAkB,GAAG7H,aAAa,GAAGoI,wBAAwB,GAAGlI,gBAAgB,GAAGhmB,YAAY,MAAMg5B,IAAI,SAASr6B,EAAQQ,GAC7H,YAwFA,SAAS85B,KACL/c,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,UAE1C,IAAIojB,GAAgB,GAAIgW,GAAmB35B,KAAMgI,OAAWA,OAAWhI,KAAKF,MAC5EE,MAAK0jB,kBAAkBC,GAEvBzjB,EAAEwB,eAAe1B,KAAMu5B,EAAgB5V,GAQ3C,QAASiW,KAKL,QAASC,GAAaxE,GAClByE,EAAK1jB,YAAY,WAAYif,GALjC1Y,EAAeva,UAAUia,MAAM/b,MAAMN,KAAMO,UAC3C,IAAIu5B,GAAO95B,IACXoI,MAAKyxB,GAQT,QAASE,KACLpd,EAAeva,UAAUkI,QAAQhK,MAAMN,KAAMO,WAUjD,QAASy5B,KACL,MAAOh6B,MAAKF,MAAM6I,GAAGsxB,cAUzB,QAASC,KACL,GAAIC,GAAan6B,KAAKo6B,YAAYptB,SAASmtB,UAC3C,OAAsB,WAAdA,EAA0BA,GAAa,EAUnD,QAASE,KACL,GAAIC,GAAYt6B,KAAKo6B,YAAYhyB,IACjC,OAAOpI,MAAKu6B,WAAaD,GAAaA,EAAUE,aAYpD,QAASC,GAAW9pB,GAChB,GAAmB,kBAARA,GAAoB,CAC3B,GAAImpB,GAAO95B,IACXA,MAAK06B,cAAc,WACfZ,EAAKM,YAAYhyB,KAAKuI,KAG9B,GAAIgqB,GAAM36B,KAAKo6B,WACf,OAAOO,IAAOA,EAAIvyB,KAItB,QAASwyB,GAAmBC,EAAaxF,GACrC,MAAO,UAA6B1kB,GAQhC,QAASmqB,KACLnqB,EAAKrQ,MAAMw5B,EAAM3nB,GARrB,GAAI2nB,GAAO95B,KACLmS,EAAOjS,EAAEkS,MAAM7R,UAAW,EAC5Bs6B,GAAYp7B,KAAKO,MACjB86B,IAEA96B,KAAK4iB,GAAGyS,EAAOyF,IAjL3B,GAAIne,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBAEzBu6B,GADYv6B,EAAQ,mBACCA,EAAQ,qBAE7Bc,GADwBd,EAAQ,6BAC5BA,EAAQ,cA+Bb27B,EAAQ76B,EAAEwD,eAAeiZ,EAAgB,SAM1Cqe,EAAkBJ,EAAmBV,EAAe,YAKpDe,EAAsBL,EAAmBP,EAAmB,oBAQhEn6B,GAAEM,YAAYu6B,GACV16B,KAAMq5B,EACNrd,MAAOud,EACPtvB,QAASyvB,EACTK,UAAWJ,EACXO,QAASL,EACTgB,UAAWF,EACXG,YAAad,EACbK,cAAeO,EACf7yB,KAAMqyB,IAKV/iB,EAAe/Q,IAAIo0B,GAEnBn7B,EAAOJ,QAAUu7B,CAMjB,IAAIxB,GAAiB,gBACrBI,GAAmBvzB,QAAQ20B,EAAOxB,GAAiB,cA2GhDnL,kBAAkB,GAAGgN,4BAA4B,GAAG7U,aAAa,GAAG8U,mBAAmB,GAAG5U,gBAAgB,GAAGhmB,YAAY,MAAM66B,IAAI,SAASl8B,EAAQQ,GACvJ,YA2BA,SAAS27B,KACL,OAASpjB,OACL6R,MAAOhqB,KAAKw7B,aAKpB,QAASC,GAAmBtjB,GACxBnY,KAAK07B,SAASvjB,EAAMA,MAAM6R,OAS9B,QAAS2R,KACL,MAAO37B,MAAKgqB,MAShB,QAAS4R,GAAmB5R,GACxBhqB,KAAKgqB,MAAQA,EAQjB,QAAS6R,KAEL77B,KAAK0pB,KAAKoS,WAAW97B,KAAKgqB,OAQ9B,QAAS+R,KACL/7B,KAAK0pB,KAAKsS,YAAYh8B,KAAKgqB,OAvE/B,GAAIrN,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBAEzBc,GADQd,EAAQ,eACZA,EAAQ,cAId68B,GAHa78B,EAAQ,uBAGTc,EAAEwD,eAAeiZ,EAAgB,QAEjDzc,GAAEM,YAAYy7B,GACV7jB,SAAUmjB,EACVhiB,SAAUkiB,EACVD,SAAUG,EACVD,SAAUE,EACVE,WAAYD,EACZG,YAAaD,EACb38B,SAAU,YAAa,MAAO,UAGlCsY,EAAe/Q,IAAIs1B,GAEnBr8B,EAAOJ,QAAUy8B,IAqDdC,cAAc,GAAGC,sBAAsB,GAAG5V,aAAa,GAAGE,gBAAgB,GAAGhmB,YAAY,MAAM27B,IAAI,SAASh9B,EAAQQ,GACvH,YA4DA,SAASy8B,KACL1f,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,UAG1CL,GAAEuB,iBAAiBzB,MACfs8B,cACAC,oBAEJr8B,EAAEwB,eAAe1B,KAAM,aAAc,KAAME,EAAE6E,MAQjD,QAASy3B,KAELx8B,KAAKF,MAAM8iB,GAAG,gBAAiB6Z,GAInC,QAASA,KAEL,GAAI/yB,GAAW1J,KAAKiZ,IAAIvP,WAClBgzB,EAAQ18B,KAAK0pB,KAAK4S,WAClBK,EAAY38B,KAAK0pB,KAAK6S,cAW5B,IATA7yB,GAAYA,EAASxE,QAAQ,SAAS0E,GAClC,GAAImV,GAAOxT,EAAUgB,aAAa3C,EAC9BmV,IAAQA,EAAKmN,OACbwQ,EAAMjtB,KAAKsP,GACX4d,EAAU5d,EAAK9e,MAAQ8e,EACvBA,EAAKmN,KAAKxC,KAAO1pB,KAAK0pB,OAE3B1pB,MAEC08B,EAAMh9B,OAAQ,CACd,GAAIk9B,GAAYF,EAAM,EACtBA,GAAMjR,OAAO,EAAG,SACTkR,GAAUC,EAAU38B,MAC3By8B,EAAMx3B,QAAQ,SAASgnB,EAAMlC,GACzBkC,EAAKA,KAAKwP,SAAS1R,KAK3B,IAAM4S,EAAW,KAAM,IAAIC,GAAU,oCAErC78B,MAAK0pB,KAAKoT,WAAaF,EAGvBA,EAAU3jB,IAAI4W,OACd+M,EAAU71B,QAAO,GACjB61B,EAAU3jB,IAAIka,iBAAiB4J,GAG/BH,EAAUnd,cAAc,SAASV,SACtBA,GAAKpW,GAAGq0B,EAAW/gB,gBAG9Bjc,KAAK0pB,KAAKuT,uBAId,QAASC,KACL,IAAKl9B,KAAK88B,WAAY,OAAO,CAE7B,EAAA,GAAIA,GAAa98B,KAAK88B,WAGlBK,EAAaL,EAAWn0B,GAAGwQ,WAAU,GACrCrQ,EAAOg0B,EAAW9gB,cAAclT,IACrB5I,GAAEiD,MAAM2F,GACvBA,EAAKb,SAAW,4BAChBa,EAAKH,GAAKw0B,EACVr0B,EAAKE,UAEL,IAAIo0B,GACE,uCACAD,EAAWtiB,UACX,SAEN7a,MAAKq9B,cAAgBrO,EAAIsO,QAAQF,GAUrC,QAASG,GAAUvT,GACf,MAAOhqB,MAAKs8B,WAAWtS,GAS3B,QAASwT,KACL,MAAOx9B,MAAKs8B,WAAW58B,OAI3B,QAAS+9B,GAAczT,EAAO9R,GAC1BlY,KAAKs8B,WAAW7Q,OAAOzB,EAAO,EAAG9R,GACjClY,KAAKu8B,eAAerkB,EAAUjY,MAAQiY,EACtCA,EAAUgU,KAAKxC,KAAO1pB,KACtBkY,EAAUgU,KAAKwP,UAAU1R,GAU7B,QAAS0T,GAAcxlB,GACnB,MAAOlY,MAAKu8B,eAAerkB,EAAUjY,OAASiY,EAWlD,QAASylB,GAAa3T,EAAOmC,GAGzB,MAFAnC,GAAQA,GAAShqB,KAAK4pB,QACtB5pB,KAAKF,MAAMsgB,KAAKqL,OAAOzB,EAAO,EAAGmC,OAC1BnsB,KAAKksB,KAAKlC,GAUrB,QAAS4T,GAAc5T,GAEnB,GADAA,EAAQA,GAAShqB,KAAK4pB,QAClB5pB,KAAKksB,KAAKlC,GACV,KAAM6S,GAAU,kDAGpB,IAAI3kB,GAAY3M,EAAU2N,KAAKlZ,KAAK88B,YAAY,GAC5Ce,EAAgB79B,KAAK89B,uBAAuB9T,EAEhD,OAAK6T,GAAcl1B,GAAG2W,YAItBue,EAAc5kB,IAAIgY,YAAY/Y,EAAUvP,IAGxC3I,KAAK+9B,SAAS/T,EAAO9R,GAGrBA,EAAUvP,GAAGonB,MAAML,QAAU,GAE7BsO,EAAoBv+B,KAAKO,KAAMgqB,EAAQ,GAEhC9R,GAbI5V,EAAOoQ,KAAK,oGAiB3B,QAASsrB,GAAoBC,EAAWC,GACpCD,EAAYA,GAAa,EACzBC,EAAUA,GAAWl+B,KAAK4pB,OAC1B,KAAK,GAAIvqB,GAAI4+B,EAAeC,EAAJ7+B,EAAaA,IAAK,CACtC,GAAI6Y,GAAYlY,KAAKs8B,WAAWj9B,EAC5B6Y,GACAA,EAAUgU,KAAKwP,SAASr8B,GAExBiD,EAAOoQ,KAAK,4BAA6BrT,IAKrD,QAAS8+B,GAAcvU,EAAOI,GAC1B,GAAIoU,GAAYl+B,EAAEkS,MAAM7R,UAAW,EAC/B69B,GAAU1+B,OAASkqB,GACnBwU,EAAUC,OAAOn+B,EAAEo+B,OAAO1U,EAAQwU,EAAU1+B,WAChD,IAAI6+B,IAAcvU,EAAO,GAAGqU,OAAOD,GAC/BI,EAAYx+B,KAAKF,MAAMsgB,IAC3Boe,GAAU/S,OAAOnrB,MAAMk+B,EAAWD,GAWtC,QAASE,GAAe7U,EAAOI,GAE3B,GADAloB,EAAM8nB,EAAO5nB,EAAM08B,SACP,EAAR9U,EACA,KAAM,IAAIiT,GAAU,qCAExB,IAAa,GAATjT,EAAJ,CAEA,GAAI+U,GAAY3+B,KAAKq9B,eACjB/0B,cAAes2B,EAASt2B,cACxBshB,MAAOA,IAGP9O,EAAS9N,SAASqN,cAAc,MACpCS,GAAOrB,UAAYklB,EAEnBnkB,EAAWM,EAAQ9a,KAAKF,MAAMoM,UAAUd,MACxC,IAAI1B,GAAWwR,EAASxR,SAASoR,EAKjC,IAHI8O,GAASlgB,EAAShK,QAClB4C,EAAOC,MAAM,qDAEbmH,GAAYA,EAAShK,OAAQ,CAC7B,GAAIiqB,GAAa3pB,KAAK4pB,QAClB+B,EAAsB,EAAR3B,EACI,EACgB,mBAATA,IAAwBA,EAAQL,EACnCA,EACAK,EAEtB6T,EAA+B,GAAflS,EACM3rB,KAAK88B,WACL98B,KAAKs8B,WAAW3Q,EAAc,GAEpDkT,EAAO7xB,SAAS8xB,yBACdC,IAcN,IAZAr1B,EAASxE,QAAQ,SAASyD,GACtB,GAAIuP,GAAY3M,EAAUgB,aAAa5D,EACvC,OAAMuP,IAEN6mB,EAActvB,KAAKyI,GACnBlY,KAAK+9B,SAASpS,IAAezT,GAC7B2mB,EAAKjZ,YAAYjd,QACjBA,EAAGonB,MAAML,QAAU,KAJRptB,EAAOC,MAAM,kDAKzBvC,MAEHg+B,EAAoBv+B,KAAKO,KAAM2rB,IAE1BkS,EAAcl1B,GAAG2W,WAClB,MAAOhd,GAAOoQ,KAAK,mGAGvBmrB,GAAc5kB,IAAIgY,YAAY4N,GAE9B3+B,EAAEmQ,YAAY0uB,EAAe,UAAW,SAAShgB,GAC7CA,EAAKlF,UAAU,kBAW3B,QAASmlB,GAAgBhV,GACrB,MAAOhqB,MAAKF,MAAMsgB,KAAKqL,OAAOzB,EAAO,GASzC,QAASiV,GAAiBjV,GACtB,GAAIkV,GAAWl/B,KAAKmqB,YAAYH,GAAO,EAEvC,OADAhqB,MAAK+pB,iBAAiBC,EAAOhqB,KAAK4pB,SAC3BsV,EAYX,QAASC,GAAiBnV,EAAOoV,GAC7B,GAAIrgB,GAAO/e,KAAKksB,KAAKlC,EAErB,OAAMjL,IAGN/e,KAAKs8B,WAAWtS,GAAShiB,aAClBhI,MAAKu8B,eAAexd,EAAK9e,MAC5Bm/B,KAAkB,EAAOrgB,EAAKzU,WAE9ByU,EAAKhY,SACLgY,EAAK9F,IAAIlS,UAGb/G,KAAKs8B,WAAW7Q,OAAOzB,EAAO,GAC9BgU,EAAoBv+B,KAAKO,KAAMgqB,GAExBjL,GAbIzc,EAAOoQ,KAAK,2DAiB3B,QAAS2sB,GAAiBrV,EAAOsV,GAC7B,GAAIC,GAAUv/B,KAAKksB,KAAKlC,EACxBuV,GAAQtmB,IAAIgY,YAAYqO,EAAQ32B,IAChC3I,KAAKmqB,YAAYH,GACjBhqB,KAAK+9B,SAAS/T,EAAOsV,GAKzB,QAASxB,GAAuB9T,GAC5B,KAAOA,GAAS,IAAOhqB,KAAKs8B,WAAWtS,IACnCA,GAEJ,OAAOA,IAAS,EACFhqB,KAAKs8B,WAAWtS,GAChBhqB,KAAK88B,WAMvB,QAAS0C,GAAsBvB,EAAWC,GACtC,IAAK,GAAI7+B,GAAI4+B,EAAeC,EAAJ7+B,EAAaA,IAAK,CACtC,GAAI6sB,GAAOlsB,KAAKksB,KAAK7sB,EACjB6sB,GACAA,EAAK9L,KAAK8G,MAAQ,IAAM7nB,EAAI,IAE5BiD,EAAOoQ,KAAK,0BAA2B6Z,IAWnD,QAASkT,GAAUjgB,EAAU9O,GACzB1Q,KAAKs8B,WAAWp3B,QAAQ,SAASgnB,EAAMlC,GAC/BkC,EAAM1M,EAASlf,MAAMN,KAAMO,WAC1B+B,EAAOoQ,KAAK,kBAAmBsX,EAAO,iBAC5CtZ,GAAW1Q,MAQlB,QAAS0/B,KACD1/B,KAAK88B,YAAY98B,KAAK88B,WAAWxyB,SAAQ,GAC7CqS,EAAeva,UAAUkI,QAAQhK,MAAMN,KAAMO,WA1ajD,GAAIoc,GAAiBvd,EAAQ,cACvBmM,EAAYnM,EAAQ,cACpBsY,EAAiBtY,EAAQ,iBACzBc,EAAId,EAAQ,aAEZob,GADWpb,EAAQ,uBACNA,EAAQ,iBACrBw/B,EAAWx/B,EAAQ,cACnBy9B,EAAY+B,EAASr8B,MAAMo9B,KAC3Br9B,EAASs8B,EAASt8B,OAClB0sB,EAAM5vB,EAAQ,OACd0C,EAAQ88B,EAAS98B,MACjBE,EAAQF,EAAME,MACdkZ,EAAW0jB,EAAS3lB,IACpB+jB,EAAa59B,EAAQ,gBAGvB29B,EAAwB,sBAMxB4C,EAAOz/B,EAAEwD,eAAeiZ,EAAgB,OAE5Czc,GAAEM,YAAYm/B,GACVt/B,KAAMg8B,EACNhgB,MAAOmgB,EACPlyB,QAASo1B,EAETtgC,SAAU,YAAa,MAAO,QAC9B0+B,uBAAwBA,EAExB5R,KAAMqR,EACN3T,MAAO4T,EACPpS,SAAUsS,EACVkC,QAASjC,EACTrR,SAAU6R,EACV0B,YAAaR,EACbvD,WAAYkD,EACZhD,YAAaiD,EACbnuB,KAAM2uB,EACN1B,SAAUN,EACVtT,YAAagV,EACb5R,SAAUqQ,EACV9T,UAAW2U,EACXxB,qBAAsBC,EACtBnT,iBAAkByV,IAGtB9nB,EAAe/Q,IAAIg5B,GAEnB//B,EAAOJ,QAAUmgC,IA0XdvZ,eAAe,EAAEoN,eAAe,GAAG2I,sBAAsB,GAAG2D,aAAa,IAAIpI,aAAa,GAAGnR,aAAa,GAAGE,gBAAgB,GAAGkN,IAAM,IAAIlzB,YAAY,MAAMs/B,IAAI,SAAS3gC,EAAQQ,GACpL,YA+BA,SAASogC,KACLhgC,KAAKigC,EAAI,GAAIC,GAAMlgC,KAAKD,OAAOqgB,KAAMpgB,MACrC2c,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,WAY9C,QAAS4/B,KACL,GAAIC,GAAapgC,KAAKigC,EAAEn5B,KAGxB,OAFyB,gBAAds5B,KACPA,EAAalgC,EAAEmgC,UAAUD,KACpBjoB,MAAOioB,GAWpB,QAASE,GAAoBnoB,GACzB,MAAOnY,MAAKigC,EAAE71B,IAAI+N,EAAMA,OAI5B,QAASooB,KACLvgC,KAAKmW,WAAanW,KAAKigC,EAAE9pB,WAI7B,QAASqqB,KACLxgC,KAAKigC,EAAE31B,UACPqS,EAAeva,UAAUkI,QAAQhK,MAAMN,KAAMO,WAtEjD,GAAIoc,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzB8gC,EAAQ9gC,EAAQ,eAEhBc,GADQd,EAAQ,wBACZA,EAAQ,cAIdqhC,EAAavgC,EAAEwD,eAAeiZ,EAAgB,QAElDzc,GAAEM,YAAYigC,GACVpgC,KAAM2/B,EACN5nB,SAAU+nB,EACV5mB,SAAU+mB,EACVne,iBAAkBoe,EAClBj2B,QAASk2B,IAGb9oB,EAAe/Q,IAAI85B,GAEnB7gC,EAAOJ,QAAUihC,EAMjBP,EAAM95B,QAAQq6B,EAAY,OA+CvBtS,uBAAuB,EAAE+N,cAAc,GAAG3V,aAAa,GAAGE,gBAAgB,GAAGhmB,YAAY,MAAMigC,IAAI,SAASthC,EAAQQ,GACvH,YAuBA,SAAS+gC,KACL3gC,KAAKigC,EAAI,GAAIC,GAAMlgC,KAAKD,OAAOge,QAAS/d,MACxC2c,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,WAC1CP,KAAKigC,EAAE77B,aAAapE,MAIxB,QAAS4gC,KACL5gC,KAAKmW,WAAanW,KAAKigC,EAAE9pB,WAI7B,QAAS0qB,KACL7gC,KAAKigC,EAAE31B,UACPqS,EAAeva,UAAUkI,QAAQhK,MAAMN,KAAMO,WAnCjD,GAAIoc,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzB8gC,EAAQ9gC,EAAQ,eAEhBc,EAAId,EAAQ,aAId0hC,EAAU5gC,EAAEwD,eAAeiZ,EAAgB,UAE/Czc,GAAEM,YAAYsgC,GACVzgC,KAAMsgC,EACNr2B,QAASu2B,EACT1e,iBAAkBye,IAGtBlpB,EAAe/Q,IAAIm6B,GAEnBlhC,EAAOJ,QAAUshC,IAoBd5E,cAAc,GAAG3V,aAAa,GAAGE,gBAAgB,GAAGhmB,YAAY,MAAMsgC,IAAI,SAAS3hC,EAAQQ,GAC9F,YA0CA,SAASohC,KACLrkB,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,UAI1C,IAAI+8B,GAAUt9B,KAAKD,OAAOkhC,eAAgB,EACxBj5B,OACAhI,KAAKD,OAAOu9B,SAAWl1B,KAAKrI,OAAOka,SAASqjB,OAE9Dt9B,MAAKoK,IAAIpK,KAAKD,OAAOka,UAAY,GAAIqjB,EAASt9B,KAAKD,OAAOmhC,gBAI9D,QAASC,KACLxkB,EAAeva,UAAUia,MAAM/b,MAAMN,KAAMO,WACvCP,KAAKD,OAAOqhC,aACZphC,KAAKmI,SACDnI,KAAKD,OAAOshC,YACZrhC,KAAK+K,UAKjB,QAASu2B,KACL,MAAOthC,MAAKuhC,UAIhB,QAASC,GAAaC,EAAanE,EAAS4D,GAiBxC,MAhBAp/B,GAAM2/B,EAAaz/B,EAAMqC,MAAMnC,OAAQH,WACvCD,EAAMw7B,EAASt7B,EAAMC,SAASF,WAEJ,kBAAf0/B,GACPzhC,KAAKuhC,UAAYE,GAEjBzhC,KAAK0hC,aAAeD,EAChBnE,EACAt9B,KAAK2hC,SAAWrE,EAEhBA,EAAUt9B,KAAK2hC,SAEfrE,IACAt9B,KAAKuhC,UAAYjE,EAAQmE,EAAaP,KAGvClhC,KAIX,QAAS4hC,GAAgBxhB,GAKrB,MAJApgB,MAAKF,MAAM6I,GAAG8Q,UAAYzZ,KAAKuhC,UACDvhC,KAAKuhC,UAAUnhB,GACfpgB,KAAK0hC,aAE5B1hC,KAIX,QAAS6hC,KACL,MAAI7hC,MAAKF,MAAMoM,UACJlM,KAAKF,MAAMoM,UAAUnB,aAE5BzI,GAAOC,MAAM,yDA1FrB,GAAIoa,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBAChBkD,EAASlD,EAAQ,qBACjB4C,EAAQF,EAAME,MAKhB8/B,GAJW1iC,EAAQ,gBAIRc,EAAEwD,eAAeiZ,EAAgB,YAEhDzc,GAAEM,YAAYshC,GACVzhC,KAAM2gC,EACN3kB,MAAO8kB,EACP/2B,IAAKo3B,EACLO,YAAaT,EACbn5B,OAAQy5B,EACR72B,OAAQ82B,IAKZnqB,EAAe/Q,IAAIm7B,GAEnBliC,EAAOJ,QAAUsiC,IAoEd1b,eAAe,EAAEqN,mBAAmB,GAAGnN,oBAAoB,IAAIC,aAAa,GAAGE,gBAAgB,GAAGhmB,YAAY,MAAMuhC,IAAI,SAAS5iC,EAAQQ,GAC5I,YA6BA,SAASqiC,KACLtlB,EAAeva,UAAU/B,KAAKC,MAAMN,KAAMO,WAC1CP,KAAKkiC,aAAe,GACpBliC,KAAKmiC,YAAc,GACnBniC,KAAKoiC,UAUT,QAASC,KACL,MAAOriC,MAAKoiC,OAAOpiC,KAAKkiC,eAAiBliC,KAAKoiC,OAAOpiC,KAAKmiC,aAU9D,QAASG,GAAkBnqB,GACvBnY,KAAKoiC,OAAO,IAAMjqB,EAClBnY,KAAKuiC,eAAe,IAQxB,QAASC,GAAwBnZ,GAC7BrpB,KAAKkiC,aAAe7Y,EAWxB,QAASoZ,GAAyBpZ,EAAKlR,EAAOuqB,GAC1C,IAAKrZ,EAAK,KAAM,IAAI/pB,OAAM,mCAGtBU,MAAKmiC,YADLO,EACmBrZ,EAEArpB,KAAKmiC,aAAe9Y,EAE3CrpB,KAAKoiC,OAAO/Y,GAAOlR,EACnBnY,KAAKuiC,eAAelZ,GAIxB,QAASsZ,GAAyBtZ,GAC9B,MAAqB,gBAAPA,IAAmBrpB,KAAKoiC,OAAO/Y,GAIjD,QAASuZ,KACL,GAAIzqB,GAAQnY,KAAKoY,UACjB,QACInQ,SAAUkQ,GAASA,EAAMlQ,SACzBL,UAAWuQ,GAASA,EAAMvQ,WAhGlC,GAAI+U,GAAiBvd,EAAQ,cACvBsY,EAAiBtY,EAAQ,iBACzBc,EAAId,EAAQ,aAQdyjC,EAAW3iC,EAAEwD,eAAeiZ,EAAgB,WAEhDzc,GAAEM,YAAYqiC,GACVxiC,KAAM4hC,EACN7pB,SAAUiqB,EACV9oB,SAAU+oB,EACVC,eAAgBC,EAChBM,gBAAiBL,EACjBM,gBAAiBJ,EACjB5J,iBAAkB6J,IAGtBlrB,EAAe/Q,IAAIk8B,GAEnBjjC,EAAOJ,QAAUqjC,IA4Edtc,aAAa,GAAGE,gBAAgB,GAAGhmB,YAAY,MAAMuiC,IAAI,SAAS5jC,EAAQQ,GAC7E,YAEA,IAAI2G,GAAgBnH,EAAQ,2BACtBud,EAAiBvd,EAAQ,cAO1BsY,EAAiB,GAAInR,GAAcoW,EAIxCjF,GAAe/Q,IAAIgW,GAEnB/c,EAAOJ,QAAUkY,IAEdurB,0BAA0B,EAAE1c,aAAa,KAAK2c,IAAI,SAAS9jC,EAAQQ,GACtE,YAwBA,SAAS0L,GAAcF,EAAOzC,EAAIG,EAAMjH,GACpCiH,EAAKxB,QAAQY,WAEblI,KAAKoL,MAAQA,EACbpL,KAAK2I,GAAKA,EACV3I,KAAK8I,KAAOA,EACZ9I,KAAKC,KAAO6I,EAAKb,SACjBjI,KAAK2X,eAAiBwrB,EAAkBr6B,EAAMjH,GAC9C7B,KAAK4Y,mBAAqBwqB,EAAwBpjC,KAAK2X,eAAgB7O,EAAMjH,GAEzE7B,KAAK2X,gBACE0rB,EAAkBrjC,KAAK2X,eAAgB3X,KAAK4Y,sBACnD5Y,KAAKkM,cAqBb,QAASo3B,WACEtjC,MAAK2I,GACZ3I,KAAK8I,KAAKwB,UAWd,QAASi5B,GAAqBtjC,EAAMgd,GAChChd,EAAOA,GAAQqI,IACfsD,EAAMsR,OAAOld,KAAMC,EAAMgd,GACzBjd,KAAK8I,KAAKb,SAAWhI,EACrBD,KAAK8I,KAAKE,WAId,QAASm6B,GAAkBr6B,EAAMjH,GAC7B,GAAI8V,GAAiBzK,EAAmBpG,IAAIgC,EAAKlB,UAGjD,OAFM+P,IACF6rB,EAAkB3hC,EAAe,SAAWiH,EAAKlB,UAAY,sBAC1D+P,EAIX,QAASyrB,GAAwBzrB,EAAgB7O,EAAMjH,GACnD,GAAIZ,GAAS6H,EAAKjB,WACZ+Q,IAeN,OAbI5T,OAAMC,QAAQhE,IACdA,EAAOiE,QAAQ,SAAS3B,GACpBA,EAAUrD,EAAEuX,eAAelU,GACvBoU,EAAe/U,SAASW,IACxBigC,EAAkB3hC,EAAe,SAAW8V,EAAe1X,KACnC,sBAAwBsD,GAChDqV,EAAmBrV,IACnBigC,EAAkB3hC,EAAe,aAAeiH,EAAKb,SAC7B,sBAAwB1E,EACpD,IAAI1C,GAAa6W,EAAe5Q,IAAIvD,EACpCqV,GAAmBrV,GAAW1C,IAG/B+X,EAIX,QAAS4qB,GAAkB3hC,EAAeQ,GACtC,GAAIR,KAAkB,EAGlB,KAAM,IAAI4hC,GAAYphC,EAFtBC,GAAOC,MAAM,8BAA+BF,GAMpD,QAASghC,GAAkB1rB,EAAgBiB,GAMvC,QAAS8qB,KACL,MAAQ/rB,GAAevV,UAAUd,eAC1BpB,EAAEyjC,QAAQhsB,EAAevV,UAAUd,cAAesiC,GAG7D,QAASA,GAAuB/iC,GAC5B,MAAOA,GAAWsjB,cAAc,aAXpC,MAAQxM,GAAe/U,SAAS,cACzB,aAAegW,IACf1Y,EAAEyjC,QAAQ/qB,EAAoBgrB,IAC9BF,IArHX,GAAIx2B,GAAqB9N,EAAQ,gBAC3BsY,EAAiBtY,EAAQ,0BACzBkJ,EAAgBlJ,EAAQ,0BACxBwM,EAAQxM,EAAQ,WAChBqkC,EAAcrkC,EAAQ,iBAAiB+N,OACvC7K,EAASlD,EAAQ,kBACjBc,EAAId,EAAQ,YAGlBQ,GAAOJ,QAAU8L,EAoCjBpL,EAAEM,YAAY8K,GACVhB,QAASg5B,EACTpmB,OAAQqmB,MAkFT7hB,yBAAyB,GAAG3d,gBAAgB,GAAG4N,iBAAiB,IAAImQ,yBAAyB,GAAG+hB,eAAe,GAAG7hB,UAAU,GAAGvhB,YAAY,MAAMqjC,IAAI,SAAS1kC,EAAQQ,GACzK,YAEA,IAAI2G,GAAgBnH,EAAQ,wBACtBmM,EAAYnM,EAAQ,aAMtB8N,EAAqB,GAAI3G,GAAcgF,EAG3C2B,GAAmBvG,IAAI4E,GAEvB3L,EAAOJ,QAAU0N,IAEd6E,uBAAuB,EAAEgyB,YAAY,KAAKC,IAAI,SAAS5kC,EAAQQ,GAClE,YAwBA,SAASihB,GAAYlY,GACjB,MAAOA,GAAGnF,eAAezD,EAAOkc,cAUpC,QAAS1P,GAAa5D,GAClB,MAAOA,IAAMA,EAAG5I,EAAOkc,cAgB3B,QAAS1B,GAAuBhT,EAAM08B,EAAe1lB,GAEjDzc,EAAMmiC,EAAejiC,EAAMC,SAAS8W,UACpCjX,EAAMyc,EAAkBvc,EAAMC,SAASD,EAAMqC,MAAMtC,SAAUG,SAE7D,IAAIyc,GAAgBE,EAA4BN,EAEhD,OAAO2lB,GAAwB38B,EAAM08B,EAAetlB,GAIxD,QAASE,GAA4BN,GACjC,GAA+B,kBAApBA,GACP,MAAOA,EACN,IAA+B,gBAApBA,GAA8B,CAC1C,GAAIzd,GAAYZ,EAAEC,eAAeoe,EACjC,OAAO,UAAUQ,GACd,MAAOA,GAAKnc,SAAS9B,KAMhC,QAASojC,GAAwBv7B,EAAIs7B,EAAetlB,GAGhD,GAAIslB,KAAkB,EAAO,CACzB,GAAIllB,GAAOxS,EAAa5D,EACxB,IAAIoW,KAAWJ,GAAiBA,EAAcI,IAC1C,MAAOA,GAKf,MAAIpW,GAAG2W,WACI4kB,EAAwBv7B,EAAG2W,YAAY,EAAMX,GADxD,OApFJ,CAAA,GAAI5e,GAASX,EAAQ,aACf0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,KAGCpC,GAAOJ,SACxBqhB,YAAaA,EACbtU,aAAcA,EACdgO,uBAAwBA,EACxBsE,4BAA6BA,MA+E9BxY,YAAY,GAAGvC,gBAAgB,KAAKqgC,IAAI,SAAS/kC,EAAQQ,GAC5D,YAEA,IAAI2L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/BglC,EAAO74B,EAAUqV,qBAAqB,QAAS,aAEnD1T,GAAmBvG,IAAIy9B,GAEvBxkC,EAAOJ,QAAU4kC,IAEd1M,aAAa,GAAG2M,gBAAgB,KAAKC,IAAI,SAASllC,EAAQQ,GAC7D,YAgCA,SAAS2kC,GAAgBrsB,GACrBjK,EAAa7L,UAAU/B,KAAKC,MAAMN,KAAMO,WAExCP,KAAKkY,UAAYA,EACjBlY,KAAK8mB,OAASC,EAAqB7O,EAAUvP,IAKjD,QAAS67B,KACL,GAAI1Z,GAAkB9qB,KAAKkY,UAAUkI,KAAKrgB,OAAO+G,IAC7CkiB,EAAqC,kBAAnB8B,GACJA,EAAgBrrB,KAAKO,KAAKkY,WAC1BlY,KAAK8mB,OAAOhgB,IAAI9G,KAAKkY,UAAUvP,GAIjD,OAFA3I,MAAKkY,UAAUkI,KAAK+G,OAAS6B,EAEtBA,EAOX,QAASyb,GAAyBpiC,GAC9B,GAAIqiC,GAAiB1kC,KAAKkY,UAAUkI,KAAKrgB,OAAOs1B,MAC5CA,EAAQqP,GAAkB1kC,KAAK8mB,OAAOuO,MAAMr1B,KAAKkY,UAAUvP,GAE/D,OAAe,IAAXtG,GAAiBgzB,EACVA,EADX,OAMJ,QAASsP,GAAoBC,EAAeviC,EAAS+d,GACjD,MAAOA,GAAK4I,UAAY5I,EAAK2I,SAIjC,QAAS8b,KACL,GAAI9b,GAAW/oB,KAAKkY,UAAUkI,KAAK+G,OAC7B6B,EAAWhpB,KAAKoB,QAElB0jC,GACAhgB,KAAM,GACNpJ,KAAM,UACNqN,SAAUA,EACVC,SAAUA,EAEd,OAAO8b,GA9EX,GAAI72B,GAAe7O,EAAQ,yBACrB2nB,EAAuB3nB,EAAQ,aAC/Bc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBASlBsoB,GARU5lB,EAAME,MAQH9B,EAAEwD,eAAeuK,EAAc,cAAc,GAG9D/N,GAAEM,YAAYknB,GAEVrnB,KAAMkkC,EACNE,yBAA0BA,EAC1BE,oBAAqBA,EACrBE,mBAAoBA,EAGpBzjC,MAAOojC,IAGX5kC,EAAOJ,QAAUkoB,IAuDdqd,wBAAwB,GAAGtR,mBAAmB,GAAGuR,YAAY,GAAGvkC,YAAY,MAAMwkC,IAAI,SAAS7lC,EAAQQ,GAC1G,YA0HA,SAASslC,GAAkBv8B,GACvB,GAAIw8B,GAAYC,EAAkBz8B,EAAG+S,KACrC,OAAOypB,GACGA,EAAU3X,SACV4X,EAAkBC,UAAU7X,SAU1C,QAAS8X,GAAiB38B,GACtB,GAAIw8B,GAAYC,EAAkBz8B,EAAG+S,KACrC,OAAOypB,GACGA,EAAU9P,MACV+P,EAAkBC,UAAUhQ,MAzI1C,GAAIn1B,GAAId,EAAQ,aAUZ2nB,EAAuB,SAASpe,GAChC,GAAImmB,GAAUnmB,EAAGmmB,QAAQyW,cACnBze,EAAS0e,EAAsB1W,EACrC,OAAOhI,IAAU0e,EAAsBH,UAG3CzlC,GAAOJ,QAAUunB,CAMjB,IAAIye,IACAH,WACI7X,SAAU,aAEdiY,KACIjY,SAAU,aAGdkY,MACIlY,SAAU,YACV6H,MAAO,SAEXsQ,GACInY,SAAU,YACV6H,MAAO,SAEXuQ,OACIpY,SAAU0X,EACV7P,MAAOiQ,GAEXO,UACIrY,SAAU,QACV6H,MAAO,SAEXyQ,QACItY,SAAU,QACV6H,MAAO,UAEX0Q,KACIvY,SAAU,OAEdwY,SACIxY,SAAU,YACV6H,MAAO,SAEX4Q,OACIzY,SAAU,YACV6H,MAAO,SAEX6Q,OACI1Y,SAAU,YACV6H,MAAO,SAEX8Q,OACI3Y,SAAU,YACV6H,MAAO,SAMfn1B,GAAEqB,QAAQikC,EAAuB,SAASY,GACtC,GAAI5Y,GAAW4Y,EAAQ5Y,SACjB6H,EAAQ+Q,EAAQ/Q,KACC,mBAAZ7H,KACP4Y,EAAQ5Y,SAAW,WAAa,MAAOA,IAC3C,IAAI6Y,GAAWD,EAAQ5Y,QACH,mBAAT6H,KACP+Q,EAAQ/Q,MAAQ,WAAa,MAAOA,KAClC+Q,EAAQt/B,MACVs/B,EAAQt/B,IAAM,SAAS6B,GAAM,MAAOA,GAAG09B,EAAS19B,MAC9Cy9B,EAAQh8B,MACVg8B,EAAQh8B,IAAM,SAASzB,EAAIvH,GACvB,MAAQuH,GAAG09B,EAAS19B,IAAuB,mBAATvH,GAAuB,GAAKA,KAQ1E,IAAIgkC,IACAC,WACI7X,SAAU,QACV6H,MAAO,SAEXiR,UACI9Y,SAAU,UACV6H,MAAO,UAEXkR,OACI/Y,SAAU,UACV6H,MAAO,UAEXlD,MACI3E,SAAU,QACV6H,MAAO,YAgCZ50B,YAAY,MAAM+lC,IAAI,SAASpnC,EAAQQ,GAC1C,YAyBA,SAAS6kC,GAAyBpiC,GAC9B,MAAOokC,GAAcjjC,eAAenB,GAC1BokC,EAAcpkC,GACdA,EAGd,QAASqkC,WACE1mC,MAAK2mC,qBACL3mC,MAAK4mC,QAGhB,QAASjC,GAAoBC,EAAeviC,EAAS+d,GACjD,GAAIymB,IAAK,CAWT,OATqB,aAAjBjC,GAA2C,UAAXviC,GAChCrC,KAAK2mC,eAAiBvmB,EAAKmV,OAC3BsR,GAAM7mC,KAAK4mC,QACX5mC,KAAK4mC,SAAU,GACS,aAAjBhC,GAA2C,WAAXviC,GACvCwkC,EAAK7mC,KAAK2mC,gBAAkBvmB,EAAKmV,OAC7BsR,GAAIH,EAAgBjnC,KAAKO,OACL,QAAjB4kC,GAAyB8B,EAAgBjnC,KAAKO,MAElD6mC,EA7CX,GAAI54B,GAAe7O,EAAQ,yBAGvBy4B,EAAa33B,EAAEwD,eAAeuK,EAAc,cAAc,EAG9D/N,GAAEM,YAAYq3B,GAEV4M,yBAA0BA,EAC1BE,oBAAqBA,IAIzB/kC,EAAOJ,QAAUq4B,CAGjB,IAAI4O,IACAK,OAAU,YACVC,QAAW,eA8BZhC,wBAAwB,KAAKiC,IAAI,SAAS5nC,EAAQQ,GACrD,YA2BA,SAASS,GAAK8D,EAAYC,EAAc8f,EAAqBhM,GACzDpW,EAAMoW,EAAW3M,GACjBvL,KAAKkY,UAAYA,EACjBnK,EAAc3L,UAAU/B,KAAKC,MAAMN,KAAMO,WAI7C,QAAS0mC,KACLl5B,EAAc3L,UAAUkI,QAAQhK,MAAMN,KAAMO,iBACrCP,MAAKkY,UAKhB,QAASgvB,KACL,MAAOlnC,MAAKkY,UAAUvP,GAvC1B,GAAIw+B,GAAmB/nC,EAAQ,6BACzB2O,EAAgB3O,EAAQ,4BACxBmM,EAAYnM,EAAQ,cACpBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBAGlB8O,GAFUpM,EAAME,MAEE9B,EAAEwD,eAAeyjC,EAAkB,mBAAmB,GAG5EjnC,GAAEM,YAAY0N,GACV7N,KAAMA,EACNiK,QAAS28B,EACTC,QAASA,IAGbtnC,EAAOJ,QAAU0O,IA0Bdk5B,2BAA2B,GAAGC,4BAA4B,GAAG5T,mBAAmB,GAAGiE,aAAa,GAAGj3B,YAAY,MAAM6mC,IAAI,SAASloC,EAAQQ,GAC7I,YA8BA,SAASS,GAAK8D,EAAYC,EAAc8f,EAAqBhM,GAIzD,GAHApW,EAAMoW,EAAW3M,GACjBvL,KAAKkY,UAAYA,EAEyB,UAAtCA,EAAUvP,GAAGmmB,QAAQyW,cACrB,KAAM,IAAIgC,GAAwB,0EAEtCx5B,GAAc3L,UAAU/B,KAAKC,MAAMN,KAAMO,WAI7C,QAASinC,KACL,MAAOxnC,MAAKkY,UAAUvP,GAAGsxB,cAK7B,QAASwN,KACL,GAAI9M,GAAM36B,KAAKwnC,aACX7M,GAAKA,EAAI+M,iBAAiB,UAAW1nC,MAAM,GAC1CsC,EAAOoQ,KAAK,iDAKrB,QAASi1B,KACL,GAAIhN,GAAM36B,KAAKwnC,aACX7M,GAAKA,EAAIiN,oBAAoB,UAAW5nC,MAAM,GAC7CsC,EAAOoQ,KAAK,iDAIrB,QAASwb,GAAQrG,EAASzH,GACtBA,EAAOA,MACPA,EAAK1E,KAAOmM,EAEZ7nB,KAAKwnC,cAAcpxB,YAAYgK,EAAM,KAKzC,QAASynB,GAAYxS,GACjBr1B,KAAK8jB,gBAAgBuR,EAAMjV,KAAK1E,KAAM2Z,GApE1C,GAAItnB,GAAgB3O,EAAQ,4BACtBmM,EAAYnM,EAAQ,cACpBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBAChBkD,EAASlD,EAAQ,qBAEjBmoC,GADQzlC,EAAME,MACY5C,EAAQ,oBAAoBu6B,oBAExDA,EAAqBz5B,EAAEwD,eAAeqK,EAAe,sBAAsB,EAG/E7N,GAAEM,YAAYm5B,GAEVt5B,KAAMA,EACNonC,oBAAqBA,EACrBE,uBAAwBA,EACxBzZ,QAASA,EAGTsZ,YAAaA,EACbK,YAAaA,IAGjBjoC,EAAOJ,QAAUm6B,IAgDdyN,2BAA2B,GAAG3T,mBAAmB,GAAGC,mBAAmB,GAAGpN,oBAAoB,IAAIoR,aAAa,GAAGj3B,YAAY,MAAMqnC,IAAI,SAAS1oC,EAAQQ,GAC5J,YAgBA,SAASgM,GAAMm8B,EAAQ5jC,GACnBjE,EAAEuB,iBAAiBzB,MACf6L,QAASk8B,EACTrjC,YAAaP,GACdjE,EAAE6E,MAqCT,QAASijC,GAAWC,EAAQhoC,GAMxB,GALmB,gBAARA,GACPgoC,EAAOhoC,KAAOA,EAEdA,EAAOgoC,EAAOhoC,KAEdD,KAAKwD,eAAevD,GACpB,KAAM,IAAIioC,GAAW,0BAA4BjoC,EAErDkoC,GAAUloC,GACVmoC,EAAM3oC,KAAKO,KAAMioC,EAAQhoC,GAU7B,QAASooC,GAAeJ,EAAQhoC,GACT,gBAARA,GACPgoC,EAAOhoC,KAAOA,EAEdA,EAAOgoC,EAAOhoC,IAElB,IAAIqoC,GAAetoC,KAAKwD,eAAevD,EACnCqoC,GACAhmC,EAAOC,MAAM,iCAAmCtC,IAEhDqoC,GAAiBrjB,EAAmBrJ,KAAK3b,GACrCqoC,GACAhmC,EAAOC,MAAM,mEAAqEtC,IAGtFqoC,IACAroC,EAAOqI,IACP2/B,EAAOhoC,KAAOA,GAGlBmoC,EAAM3oC,KAAKO,KAAMioC,EAAQhoC,GAI7B,QAASmoC,GAAMH,EAAQhoC,GACnBD,KAAKC,GAAQgoC,EACbA,EAAO78B,MAAQpL,KAEmB,kBAAvBioC,GAAO7xB,aACd6xB,EAAO7xB,YAAY,gBAU3B,QAASmyB,GAAYC,GACjB1mC,EAAM0mC,EAAQ58B,GAEd48B,EAAOz8B,MAAMi8B,EAAYhoC,MAU7B,QAASyoC,GAAYvwB,EAAWwwB,GAC5BA,EAAWztB,KAAK/C,GAChBlY,KAAKsd,QAAQpF,EAAUjY,MACvBiY,EAAU9M,MAAQs9B,EAStB,QAASC,GAAav9B,GAClBA,EAAMW,MAAM,SAAUgT,GAClB/e,KAAKib,KAAK8D,EAAMA,EAAK9e,MACrBmL,EAAMkS,QAAQyB,EAAK9e,OACpBD,MAUP,QAAS4oC,GAAYppB,EAAU9O,GAC3BxQ,EAAEqB,QAAQvB,KAAMwf,EAAU9O,GAAW1Q,MAAM,GAW/C,QAAS6oC,GAAcrpB,EAAU9O,GAC7B,MAAOxQ,GAAEie,WAAWne,KAAMwf,EAAU9O,GAAW1Q,MAAM,GAQzD,QAASmoC,GAAUloC,GACf,IAAMglB,EAAmBrJ,KAAK3b,GAC1B,KAAM,IAAIioC,GAAW,4DAA8DjoC,GAS3F,QAAS6oC,KACL,MAAOtnC,QAAO+V,KAAKvX,MAAMN,OAU7B,QAASqpC,KACL,GAAI1f,GAAM7nB,OAAO+V,KAAKvX,MAAM,EAC5B,OAAOqpB,IAAOrpB,KAAKqpB,GAUvB,QAAS2f,GAAc/oC,EAAMod,GACzB,KAAOpd,IAAQD,OAEX,YADKqd,GAAO/a,EAAOoQ,KAAK,wCAI5B,IAAIu1B,GAASjoC,KAAKC,SAEXD,MAAKC,GAEsB,kBAAvBgoC,GAAO7xB,aACd6xB,EAAO7xB,YAAY,oBAQ3B,QAAS6yB,KACLjpC,KAAK+L,MAAM,SAASk8B,EAAQhoC,SACjBD,MAAKC,GAAMmL,YACXpL,MAAKC,IACbD,MAGP,QAASkpC,KACLlpC,KAAK6L,QAAU,KASnB,QAASs9B,GAAWlB,GAChB,MAAOjoC,MAAKwD,eAAeykC,EAAOhoC,MAUtC,QAASmpC,GAAcC,EAAKppC,EAAMgd,GAC1BosB,EAAIj+B,OAAS6R,KAAkB,GAC/BosB,EAAIj+B,MAAMkS,QAAQ+rB,EAAIppC,MACtBopC,EAAIj+B,MAAM6P,KAAKouB,EAAKppC,IAEpBopC,EAAIppC,KAAOA,EApQnB,GAAIC,GAAId,EAAQ,aACVkJ,EAAgBlJ,EAAQ,0BACxB0C,EAAQ1C,EAAQ,iBAEhB8oC,GADQpmC,EAAME,MACD5C,EAAQ,iBAAiBwM,OACtCtJ,EAASlD,EAAQ,iBAgBvBc,GAAEM,YAAYoL,GACVqP,KAAM+sB,EACNsB,SAAUjB,EACVkB,MAAOhB,EACPx8B,MAAO68B,EACPY,MAAOf,EACPgB,OAAQd,EACRe,QAASZ,EACT9tB,KAAM+tB,EACNzrB,QAAS0rB,EACTW,OAAQV,EACR3jB,eAAgB4jB,EAChBU,KAAMT,EACNU,QAAShB,IAIb3oC,EAAEkD,OAAOwI,GACLsR,OAAQksB,IAIZxpC,EAAOJ,QAAUoM,CAGjB,IAAIqZ,GAAqB,+BAyNtBnhB,gBAAgB,GAAG4d,yBAAyB,GAAG3d,gBAAgB,GAAG4N,iBAAiB,IAAIlR,YAAY,MAAMqpC,IAAI,SAAS1qC,EAAQQ,GACjI,YAuBA,SAASmqC,GAAiBC,GACtBhqC,KAAK2I,GAAGshC,SAAWD,EAGvB,QAASE,KACL,QAASlqC,KAAK2I,GAAGshC,SA1BrB,GAAI1+B,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/B+qC,EAAW5+B,EAAUqV,qBAAqB,YAC1CwpB,OAAQpiC,OACRiR,KACIiW,IAAK,iBAIbhiB,GAAmBvG,IAAIwjC,GAEvBvqC,EAAOJ,QAAU2qC,EAEjBjqC,EAAEM,YAAY2pC,GACVH,QAASD,EACTM,WAAYH,MAabxS,aAAa,GAAG2M,gBAAgB,KAAKiG,IAAI,SAASlrC,EAAQQ,GAC7D,YA2CA,SAAS2qC,KACLh/B,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WACrCP,KAAK4iB,GAAG,gBAAiB6Z,GAG7B,QAASA,KACLv8B,EAAEuB,iBAAiBzB,MACfwqC,YAAexqC,KAAKkM,UAAUd,MAAMw6B,MACpC6E,WAAczqC,KAAKkM,UAAUd,MAAMs/B,WAGvC1qC,KAAKyqC,WAAWxwB,SAAS7P,IAAIugC,GAE7B3qC,KAAKwqC,YAAYpqB,KAAKwC,GAAG,SACnBF,WAAYkoB,EAAuB9nB,QAAS9iB,OAGtD,QAAS6qC,KACL,MAAM7qC,MAAKwqC,YACJxqC,KAAKwqC,YAAYpqB,KAAKtZ,MAD7B,OAIJ,QAASgkC,GAAY1pC,GACjB,MAAO2pC,GAAgBtrC,KAAKO,KAAM,MAAOoB,GAG7C,QAAS4pC,KACL,MAAOD,GAAgBtrC,KAAKO,KAAM,MAAOoB,OAG7C,QAAS2pC,GAAgBnmC,EAAQxD,GAC7B,GAAMpB,KAAKwqC,YAAX,CACA,GAAIl4B,GAAStS,KAAKwqC,YAAYpqB,KAAKxb,GAAQxD,EAE3C,OADAwpC,GAAsBnrC,KAAKO,MACpBsS,GAKX,QAASs4B,KACL5qC,KAAKogB,KAAKyD,sBAAsBonB,GAGpC,QAASC,KACLlrC,KAAKyqC,WAAWxwB,SAAS9R,QACrBgjC,aAAcnrC,KAAKorC,MAAMtkC,QAtFjC,GAAIyE,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAGd6rC,EAAuB,gBAEvBN,EAAoB,0IAIpBU,EAAU9/B,EAAUqV,qBAAqB,WACzCwpB,OAAQpiC,OACRoY,MACItZ,IAAK+jC,EACLzgC,IAAK0gC,EACLvgB,IAAKygB,EACLvf,OAAQzjB,OACRqtB,MAAO4V,GAEXG,OACI/oB,UACIipB,OAAS5oB,WAAYwoB,EAAiBpoB,QAAS,WAGvD7J,KACIiW,IAAK,kBAEThjB,UAAWlE,QAGfkF,GAAmBvG,IAAI0kC,GAEvBzrC,EAAOJ,QAAU6rC,EAGjBnrC,EAAEM,YAAY6qC,GACVhrC,KAAMkqC,MAqDP7S,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAM8qC,IAAI,SAASnsC,EAAQQ,GAC7E,YAsDA,SAAS4rC,KACLjgC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WACrCP,KAAKyrC,gBAAkB,aACvBzrC,KAAKorC,MAAMhhC,QACXpK,KAAK0rC,KAAK,gBAAiBjP,GAI/B,QAASkP,GAA8BC,GACN,kBAAlBA,KACP5rC,KAAKyrC,gBAAkBG,GAG/B,QAASC,GAAuBC,GAC5B9rC,KAAK+rC,OAAOC,WAAWF,GAI3B,QAASG,KACLjsC,KAAK+rC,OAAOG;CAQhB,QAASC,GAA4Bxc,GACjC3vB,KAAK+rC,OAAOK,gBAAgBzc,GAIhC,QAAS0c,GAA6BC,GACnCtsC,KAAK+rC,OAAOQ,iBAAiBD,GAIhC,QAASE,KACLjhC,EAAUnJ,UAAUkI,QAAQhK,MAAMN,KAAMO,WACxCP,KAAKysC,YAAcrkC,KAAKskC,OAAOC,iBAAiB3sC,KAAKysC,YACrDzsC,KAAKysC,WAAa,KAItB,QAAShQ,KACLz8B,KAAKia,SAAS9R,SAAS4C,SACvB6hC,EAAentC,KAAKO,MAGxB,QAAS4sC,KACL1sC,EAAEuB,iBAAiBzB,MACf+rC,OAAU/rC,KAAKkM,UAAUd,MAAMyhC,MAC/BC,MAAS9sC,KAAKkM,UAAUd,MAAMse,OAGlC1pB,KAAKysC,WAAarkC,KAAKskC,OAAO1sC,KAAK8sC,MAAM1B,MAAO,UAAWprC,KAAKorC,OAChEprC,KAAK+rC,OAAO3rB,KAAKwC,GAAG,IAAMF,WAAYqqB,EAAejqB,QAAS9iB,OAC9DA,KAAK+rC,OAAOnpB,GAAG,WAAaF,WAAYsqB,EAAWlqB,QAAS9iB,OAGhE,QAAS+sC,GAAc72B,EAAKkK,GACpBA,EAAK4I,UAAYhpB,KAAKyrC,gBAAgBv1B,EAAKkK,EAAMpgB,KAAK8sC,MAAM1B,MAAMtkC,QAClE9G,KAAK8sC,MAAM1B,MAAM37B,KAAK2Q,EAAK4I,UAC/BhpB,KAAK+rC,OAAO3rB,KAAKmK,MAEjBvqB,KAAK+rC,OAAO3rB,KAAK+G,OAAS,GAG9B,QAAS8lB,KACLjtC,KAAKogB,KAAKyD,sBAAsBqpB,GAGpC,QAASC,KACL,GAAI/rC,GAAQpB,KAAKorC,MAAMtkC,KACvB,OAAuB,gBAAT1F,GAAoBlB,EAAEiD,MAAM/B,GAASA,EAGvD,QAASgsC,GAAgBhsC,GACrBpB,KAAKorC,MAAMhhC,IAAIhJ,GAGnB,QAASisC,KACL,MAAOrtC,MAAKorC,MAAMhhC,QAItB,QAAS4iC,GAAU92B,EAAKkK,GACpBpgB,KAAKoW,YAAY,UAAWgK,GAC5BpgB,KAAKoqC,OAAOh0B,YAAY,wBAAyBgK,GA5IrD,GAAI7U,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAEd8tC,EAA4B,oBAG5BI,EAAc/hC,EAAUqV,qBAAqB,eAC7C3H,KACIiW,IAAK,oBAET9O,MACItZ,IAAKqmC,EACL/iC,IAAKgjC,EACL7iB,IAAK8iB,EACLhY,MAAO6X,GAEX9C,OAAQpiC,OACRkE,UAAWlE,OACXojC,OACI/oB,UACIipB,OAAS5oB,WAAYuqB,EAAenqB,QAAS,WAGrD7I,UACIA,SAAU,gYAWlB/M,GAAmBvG,IAAI2mC,GAEvB1tC,EAAOJ,QAAU8tC,EAGjBptC,EAAEM,YAAY8sC,GACVjtC,KAAMmrC,EACNQ,WAAYH,EACZ0B,kBAAmB5B,EACnBS,gBAAiBD,EACjB7hC,QAASkiC,EACTD,iBAAkBF,EAClBH,gBAAkBD,MA+FnBvU,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAM+sC,IAAI,SAASpuC,EAAQQ,GAC7E,YA8BA,SAAS6tC,KACL,MAAOvtC,GAAEwtC,KAAK1tC,KAAK2I,GAAGglC,KAI1B,QAASC,GAAcxsC,GACnB,GAAIssC,GAAOxtC,EAAE2tC,OAAOzsC,EAEpBpB,MAAK2I,GAAGglC,IAAMD,EAAOI,EAAgBJ,GAAQ,GAIjD,QAASK,KACL,MAAO7tC,GAAEwtC,KAAK1tC,KAAK2I,GAAGqlC,KAI1B,QAASC,GAAc7sC,GACnB,GAAIssC,GAAOxtC,EAAE2tC,OAAOzsC,EAEpBpB,MAAK2I,GAAGqlC,IAAMN,EAAOI,EAAgBJ,GAAQ,GAIjD,QAASQ,KACL,MAAOhuC,GAAE2tC,OAAO7tC,KAAK2I,GAAGvH,OAI5B,QAAS+sC,GAAW/sC,GAChB,GAAIssC,GAAOxtC,EAAE2tC,OAAOzsC,EAEpBpB,MAAK2I,GAAGvH,MAAQssC,EAAOI,EAAgBJ,GAAQ,GAE/CU,EAAqB3uC,KAAKO,MAG9B,QAASquC,KACLruC,KAAK2I,GAAGvH,MAAQ,GAEhBgtC,EAAqB3uC,KAAKO,MAI9B,QAASouC,KACLpuC,KAAKogB,KAAKyD,sBAAsB,SAIpC,QAASiqB,GAAgBJ,GAWrB,QAASY,GAAIxvC,GAAK,MAAW,IAAJA,EAAS,IAAMA,EAAIA,EAV5C,GAAIyvC,IACAb,EAAKc,cACLF,EAAIZ,EAAKe,WAAa,GACtBH,EAAIZ,EAAKgB,YAGTC,EAAUJ,EAAQ9lC,KAAK,IAE3B,OAAOkmC,GAtFX,GAAIpjC,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAEdwvC,EAASrjC,EAAUqV,qBAAqB,UACxCwpB,OAAQpiC,OACRoY,MACItZ,IAAKonC,EACL9jC,IAAK+jC,EACL5jB,IAAK8jB,GAETp1B,KACIiW,IAAK,eAIbhvB,GAAEM,YAAYouC,GACVC,OAAQpB,EACRqB,OAAQlB,EACRmB,OAAQhB,EACRiB,OAAQf,IAGZ/gC,EAAmBvG,IAAIioC,GAEvBhvC,EAAOJ,QAAUovC,IAiEdlX,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAMwuC,IAAI,SAAS7vC,EAAQQ,GAC7E,YAGA,IAAI2L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/B8vC,EAAe3jC,EAAUqV,qBAAqB,gBAAiB,QAGnE1T,GAAmBvG,IAAIuoC,GAEvBtvC,EAAOJ,QAAU0vC,IAEdxX,aAAa,GAAG2M,gBAAgB,KAAK8K,IAAI,SAAS/vC,EAAQQ,GAC7D,YAoDA,SAASwvC,GAAWzmC,GAChBA,EAAG0nB,UAAUT,OAAO,0BAGxB,QAASyf,GAAYn5B,EAAKvN,GACtB,GAAI2mC,GAAK3mC,EAAGqB,aAAa,gBACnBkiB,EAAOlsB,KAAKuvC,UAAUD,EAE5BtvC,MAAKoW,YAAY,cAAgBF,GAC7BgW,KAAMA,EACNvjB,GAAIA,IAIZ,QAAS6mC,GAAYt5B,EAAKtX,GACtB,GAAI+J,GAAK/J,EAAE22B,MACX,IAAI5sB,EAAG0nB,UAAUjF,SAAS,yBACtBgkB,EAAWzmC,EAAG2W,WAAWA,gBACxB,CAAA,IAAI3W,EAAG0nB,UAAUjF,SAAS,wBAE1B,MADDikB,GAAY5vC,KAAKO,KAAMkW,EAAKvN,GAEhC/J,EAAE82B,kBAGN,QAAS+Z,GAA4BhO,GACjCzhC,KAAK0vC,cAAgB1gB,EAAIsO,QAAQmE,GAGrC,QAASkO,GAAuBvvB,GAM5B,QAASwvB,GAAaxvB,GAClB,GAAIA,EAAKsc,MACL,GAAImT,GAAW3vC,EAAE+Q,IAAImP,EAAKsc,MAAO,SAASxQ,GACtC,GAAIojB,GAAKQ,GAET,OADAhW,GAAKyV,UAAUD,GAAMpjB,EACdojB,GAGf,OAAOS,IACHC,QAASH,EACTzvB,KAAMA,EACN6vB,aAAcnW,EAAK4V,eAAiBQ,EACpCC,aAAcP,IAjBtB,GAAI9V,GAAO95B,IACXA,MAAKowC,MAAQhwB,EACb0Z,EAAKyV,aACLvvC,KAAK2I,GAAG8Q,UAAYm2B,EAAYxvB,GAlFpC,GAAI4O,GAAM5vB,EAAQ,OACZ8N,EAAqB9N,EAAQ,iBAC7BmM,EAAYnM,EAAQ,cACpB0wC,EAAY1wC,EAAQ,oBAEtBixC,EAAgB,62BAiBhBH,EAAiClhB,EAAIsO,QAAQ,sIAI3CyS,EAAyB/gB,EAAIsO,QAAQ+S,GAGvCC,EAAa/kC,EAAUqV,qBAAqB,cAC5C1U,UAAWlE,OACXoiC,QACI/nB,UACIkuB,kBAAoB7tB,WAAY8sB,EAAa1sB,QAAS,WAG9D7J,KACIiW,IAAK,wBAIbhiB,GAAmBvG,IAAI2pC,GAEvB1wC,EAAOJ,QAAU8wC,EAEjBpwC,EAAEM,YAAY8vC,GACVE,gBAAiBf,EACjBgB,WAAYd,MAsDbe,mBAAmB,GAAGhZ,aAAa,GAAG2M,gBAAgB,GAAG1Q,IAAM,MAAMgd,IAAI,SAASvxC,EAAQQ,GAC7F,YAEA,IAAI2L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/BwxC,EAAUrlC,EAAUqV,qBAAqB,WACzC1U,UAAWlE,OACXoY,KAAMpY,OACNoiC,OAAQpiC,OACRiR,KACIiW,IAAK,gBAIbhiB,GAAmBvG,IAAIiqC,GAEvBhxC,EAAOJ,QAAUoxC,IAEdlZ,aAAa,GAAG2M,gBAAgB,KAAKwM,IAAI,SAASzxC,EAAQQ,GAC7D,YAEA,IAAI2L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/B0xC,EAAcvlC,EAAUqV,qBAAqB,eAC7CwpB,OAAQpiC,OACRoY,KAAMpY,OACNiR,KACIiW,IAAK,oBAIbhiB,GAAmBvG,IAAImqC,GAEvBlxC,EAAOJ,QAAUsxC,IAEdpZ,aAAa,GAAG2M,gBAAgB,KAAK0M,IAAI,SAAS3xC,EAAQQ,GAC7D,YA4CA,SAASoxC,KACLzlC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WAUzC,QAAS0wC,GAAY7vC,GAEjB,MADApB,MAAKorC,MAAMhhC,IAAIhJ,GACRA,EAUX,QAAS8vC,KACL,GAAI9vC,GAAQpB,KAAKorC,MAAMtkC,KACvB,OAAO1F,IAAyB,gBAATA,GAAoBlB,EAAEiD,MAAM/B,GAASA,EAQhE,QAAS+vC,KACLnxC,KAAKorC,MAAM7gB,MAKf,QAASqgB,KACL5qC,KAAKogB,KAAKyD,sBAAsButB,GAIpC,QAASC,GAAcvsB,EAAM1E,GACzBpgB,KAAK2I,GAAG2oC,IAAMlxB,EAAK4I,SACnB4hB,EAAsBnrC,KAAKO,MAxF/B,GAAIuL,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAGdgyC,EAAuB,gBAEvBG,EAAUhmC,EAAUqV,qBAAqB,WACzCR,MACIhW,IAAK6mC,EACLnqC,IAAKoqC,EACL3mB,IAAK4mB,EACL1lB,OAAQzjB,OACRqtB,MAAO+b,GAEXhG,OACI/oB,UACImvB,QAAU9uB,WAAY2uB,EAAevuB,QAAS,WAGtDsnB,OAAQpiC,OACRkE,UAAWlE,OACXiR,KACI6V,QAAS,MACTI,IAAK,gBAIbhiB,GAAmBvG,IAAI4qC,GAEvB3xC,EAAOJ,QAAU+xC,EAGjBrxC,EAAEM,YAAY+wC,GACVlxC,KAAM2wC,MAyDPtZ,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAMgxC,IAAI,SAASryC,EAAQQ,GAC7E,YAyBA,SAAS8xC,GAAgB1H,GACrBhqC,KAAK2I,GAAGshC,SAAWD,EAGvB,QAAS2H,KACL,QAAS3xC,KAAK2I,GAAGshC,SAGrB,QAAS2H,GAAqBlyC,GAC1BM,KAAK2I,GAAGuB,aAAa,YAAaxK,GAhCtC,GAAI6L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAGdyyC,EAAUtmC,EAAUqV,qBAAqB,WACzCR,KAAMpY,OACNoiC,OAAQpiC,OACRiR,KACIiW,IAAK,gBAIbhiB,GAAmBvG,IAAIkrC,GAEvBjyC,EAAOJ,QAAUqyC,EAEjB3xC,EAAEM,YAAYqxC,GACV7H,QAAS0H,EACTrH,WAAYsH,EACZG,aAAcF,MAefla,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAMsxC,IAAI,SAAS3yC,EAAQQ,GAC7E,YAsDA,SAASoyC,KACLzmC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WACrCP,KAAK0rC,KAAK,gBAAiBjP,GAC3Bz8B,KAAKorC,MAAMhhC,QAGf,QAASqyB,KACLt0B,EAAO1I,KAAKO,MAGhB,QAASiyC,GAA2BC,GAChClyC,KAAKmyC,OAAOxpC,GAAGuB,aAAa,cAAegoC,GAG/C,QAASE,GAAqBC,GAC1BC,EAAeD,GAAcC,EAGjC,QAASC,KACLhnC,EAAUnJ,UAAUkI,QAAQhK,MAAMN,KAAMO,WACxCP,KAAKysC,YAAcrkC,KAAKskC,OAAOC,iBAAiB3sC,KAAKysC,YACrDzsC,KAAKysC,WAAa,KAGtB,QAAStkC,KACLnI,KAAKia,SAAS9R,SAAS4C,SACvB6hC,EAAentC,KAAKO,MAGxB,QAAS4sC,KACL1sC,EAAEuB,iBAAiBzB,MACfmyC,OAAUnyC,KAAKkM,UAAUd,MAAMw6B,MAC/B4M,QAAWxyC,KAAKkM,UAAUd,MAAMqnC,OAChC3F,MAAS9sC,KAAKkM,UAAUd,MAAMse,OAElC1pB,KAAKysC,WAAarkC,KAAKskC,OAAO1sC,KAAK8sC,MAAM1B,MAAO,UAAWprC,KAAKorC,OAChEprC,KAAKwyC,QAAQpI,OAAOxnB,GAAG,SAAUF,WAAYgwB,EAAS5vB,QAAS9iB,OAGnE,QAAS0yC,KACL,GAAItxC,GAAQpB,KAAKmyC,OAAO/xB,KAAKtZ,IAAI,EAC7B9G,MAAKmyC,OAAO/xB,MACZkyB,EAAalxC,EAAO,SAAUuxC,EAAOvxC,GACjCpB,KAAK8sC,MAAM1B,MAAM37B,MAAOkjC,MAAOA,EAAOvxC,MAAOA,KAC/C0D,KAAK9E,OACXA,KAAKmyC,OAAO/xB,KAAKmK,MAGrB,QAAS0iB,KACLjtC,KAAKogB,KAAKyD,sBAAsB+uB,GAGpC,QAASC,KACL,GAAIzH,GAAQprC,KAAKorC,MAAMtkC,KACvB,OAAOskC,GAAQlrC,EAAEiD,MAAMioC,GAASpjC,OAGpC,QAAS8qC,GAAgB1xC,GACrBpB,KAAKorC,MAAMhhC,IAAIhJ,GAGnB,QAAS2xC,KACL,MAAO/yC,MAAKorC,MAAMhhC,QAGtB,QAAS4oC,KACLhzC,KAAKorC,MAAM3f,OAAOnrB,MAAMN,KAAKorC,MAAO7qC,WAtHxC,GAAIgL,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAEdwzC,EAA4B,oBAE5BN,EAAe,SAAUlxC,EAAOoe,GAAWA,EAASpe,IAEpD6xC,EAAc1nC,EAAUqV,qBAAqB,eAC7C3H,KACIiW,IAAK,oBAET9O,MACItZ,IAAK+rC,EACLzoC,IAAK0oC,EACLvoB,IAAKwoB,EACLtnB,OAAQunB,EACR3d,MAAOud,GAEXxI,OAAQpiC,OACRkE,UAAWlE,OACXojC,OACI/oB,UACIipB,OAAS5oB,WAAYuqB,EAAenqB,QAAS,WAGrD7I,UACIA,SAAU,weAclB/M,GAAmBvG,IAAIssC,GAEvBrzC,EAAOJ,QAAUyzC,EAEjB/yC,EAAEM,YAAYyyC,GACV5yC,KAAM2xC,EACNkB,SAAUd,EACVe,eAAgBlB,EAChB3nC,QAASioC,MAuEV7a,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAM2yC,IAAI,SAASh0C,EAAQQ,GAC7E,YAkCA,SAASyzC,KACL9nC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WACrCP,KAAK4iB,GAAG,gBAAiB6Z,GAI7B,QAAS6W,KACLtzC,KAAKysC,YAAcrkC,KAAKskC,OAAOC,iBAAiB3sC,KAAKysC,YACrDzsC,KAAKysC,WAAa,KAClBlhC,EAAUnJ,UAAUkI,QAAQhK,MAAMN,KAAMO,WAI5C,QAASgzC,GAAkBvpB,GACvBhqB,KAAKorC,MAAM3f,OAAOzB,EAAO,GAI7B,QAASwpB,GAAgBC,EAAMC,GAC3B,GAAIC,GAAc3zC,KAAKorC,MAAM3f,OAAOgoB,EAAM,EAC1C,OAAOzzC,MAAKorC,MAAM3f,OAAOioB,EAAI,EAAGC,EAAY,IAIhD,QAASlX,KACLz8B,KAAKorC,MAAMhhC,QACXpK,KAAKysC,WAAarkC,KAAKskC,OAAO1sC,KAAKorC,MAAO,OAAQprC,KAAKogB,MAAMwzB,gBAAgB,WA1DjF,GAAIroC,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAMdy0C,EAAStoC,EAAUqV,qBAAqB,UACxC3H,KACIiW,IAAK,cAET9O,KAAMpY,OACNoiC,OAAQpiC,OACRojC,MAAOpjC,OACP0hB,KAAM1hB,QAIVkF,GAAmBvG,IAAIktC,GAEvBj0C,EAAOJ,QAAUq0C,EAGjB3zC,EAAEM,YAAYqzC,GACVxzC,KAAMgzC,EACN/oC,QAASgpC,EACTxX,WAAYyX,EACZO,SAAUN,MAiCX9b,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAMszC,IAAI,SAAS30C,EAAQQ,GAC7E,YAoDA,SAASo0C,KACLzoC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WACrCP,KAAK4iB,GAAG,gBAAiB6Z,GAI7B,QAASA,KACL,GAAIwX,GAAYj0C,KAAKkM,UAAUd,MAAM6oC,SACrCA,IAAaA,EAAU7J,OAAOxnB,GAAG,SAAWF,WAAY1iB,KAAK87B,WAAYhZ,QAAS9iB,OAItF,QAASk0C,KACL,IAAM,GAAIC,GAAYn0C,KAAKksB,KAAKxC,KAAK5pB,MAAS,MAAMlB,IACpDu1C,GAAaA,EAAUrY,WAAW97B,KAAKksB,KAAKlC,OAIhD,QAASoqB,GAAoBpqB,GACzB,GAAImqB,GAAYn0C,KAAKksB,KAAKxC,KAAK5pB,KAC/Bq0C,IAAaA,EAAUL,SAAS9zC,KAAKksB,KAAKlC,MAAOA,GAIrD,QAASqqB,GAAyBve,GAC9B,MAAOA,GAAKE,QAAUF,EAAKE,OAAOhM,OAA2B,cAAlB8L,EAAKluB,UAIpD,QAAS0sC,KACL,MAAOt0C,MAAKu0C,cAAcj0C,MAAMN,KAAMO,WAI1C,QAASi0C,GAAWpf,EAAWC,GAC3Bof,EAAUh1C,KAAKO,KACf,IAAIm2B,GAAK,GAAIU,GAASxB,GAClBS,EAAOK,EAAG4C,mBACV5gB,EAAQge,EAAGue,oBACXP,EAAYn0C,KAAKksB,KAAKxC,KAAK5pB,MAC3BkqB,EAAQ8L,EAAKE,QAAUF,EAAKE,OAAOhM,KAEvCmqB,GAAUL,UAAU9pB,EAAOhqB,KAAKksB,KAAKlC,MAAO7R,GAIhD,QAASw8B,KACL30C,KAAKiZ,IAAIia,cAAc,gBAI3B,QAASuhB,KACLz0C,KAAKiZ,IAAIka,iBAAiB,gBAI9B,QAASyhB,KACL,OACI5qB,MAAOhqB,KAAKksB,KAAKlC,OAKzB,QAAS6qB,KACL,GAAIzzC,GAAQpB,KAAKorC,MAAMtkC,KACvB,OAAiB,QAAV1F,GAAkC,gBAATA,GAAoBlB,EAAEiD,MAAM/B,GAASA,EAIzE,QAAS0zC,GAAe1zC,GAKpB,MAJoB,gBAATA,IACPpB,KAAKogB,KAAK0I,KAAK1nB,GACnBpB,KAAKorC,MAAMhhC,IAAIhJ,GACf2zC,EAAmBt1C,KAAKO,MACjBoB,EAIX,QAAS4zC,KACLh1C,KAAKogB,KAAKqK,OACVzqB,KAAKorC,MAAM7gB,MACXwqB,EAAmBt1C,KAAKO,MAI5B,QAAS+0C,KACL/0C,KAAKogB,KAAKyD,sBAAsBoxB,GAxIpC,GAAI1pC,GAAYnM,EAAQ,cAClBy3B,EAAWz3B,EAAQ,uBACnB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAGd61C,EAA0B,mBAE1BC,EAAa3pC,EAAUqV,qBAAqB,cAC5C1U,UAAWlE,OACXiR,IAAKjR,OACL6sB,MACIiB,MACIE,OAAQ4e,IAGhB5c,MACI3V,UACI8yB,WAAezyB,WAAYiyB,EAAa7xB,QAAS,SACjDsyB,UAAc1yB,WAAYiyB,EAAa7xB,QAAS,SAChDuyB,WAAe3yB,WAAY+xB,EAAW3xB,QAAS,SAC/CkV,MAAUtV,WAAY8xB,EAAY1xB,QAAS,UAE/C2V,OACIK,WAAYwb,IAGpBl0B,MACItZ,IAAK+tC,EACLzqC,IAAK0qC,EACLvqB,IAAKyqB,EACL3f,MAAO4f,GAEX7J,MAAOpjC,OACPkkB,KAAMlkB,QAGVkF,GAAmBvG,IAAIuuC,EAEvB,IAAIA,GAAat1C,EAAOJ,QAAU01C,CAGlCh1C,GAAEM,YAAY00C,GACV70C,KAAM2zC,EACNF,SAAUM,EACVtY,WAAYoY,EACZK,cAAeF,MAgGhB5c,sBAAsB,GAAGC,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAM60C,IAAI,SAASl2C,EAAQQ,GACtG,YA6DA,SAAS21C,KACLr1C,EAAEwB,eAAe1B,KAAM,gBAAkBE,EAAEs1C,MAC3Ct1C,EAAEwB,eAAe1B,KAAMy1C,EAAuBC,EAAsB5F,KACpE9vC,KAAK21C,kBACLpqC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WAIzC,QAASq1C,GAA8B73B,GACnC/d,KAAK21C,eAAiB53B,EAU1B,QAAS83B,GAAiBz0C,GACtB,GACM00C,GADF/3B,EAAU/d,KAAK+1C,UAEnB,OAAIh4B,GAAQre,QACRqe,EAAQ7Y,QAAQ,SAASqhC,GACrBA,EAAMyP,QAAUzP,EAAMnlC,OAASA,EAC3BmlC,EAAMyP,UACNF,EAAY10C,KAGpBwpC,EAAsBnrC,KAAKO,MAEpB81C,GATX,OAoBJ,QAASG,KACL,GAAID,GAAU91C,EAAEsb,KAAKxb,KAAK+1C,WAAY,SAASxP,GAC3C,MAAOA,GAAMyP,SAGjB,OAAOA,IAAWA,EAAQ50C,OAAS4G,OAQvC,QAASkuC,KACL,GAAIn4B,GAAU/d,KAAK+1C,UAOnB,OANIh4B,GAAQre,QACRqe,EAAQ7Y,QAAQ,SAASqhC,GACrBA,EAAMyP,SAAU,QAGxBpL,GAAsBnrC,KAAKO,MAQ/B,QAASm2C,GAAa/gB,EAAWC,GACJ,SAArBA,EAAME,OAAO7Z,MACbkvB,EAAsBnrC,KAAKO,MAInC,QAAS4qC,KACL5qC,KAAKogB,KAAKyD,sBAAsBuyB,GAKpC,QAASlL,KACLlrC,KAAKia,SAAS9R,QACVkuC,aAAcr2C,KAAKorC,MAAMtkC,MACzBwvC,YAAat2C,KAAKy1C,GAClBE,eAAgB31C,KAAK21C,gBAGzB,IAAIY,GAAWv2C,KAAK2I,GAAGgB,iBAAiB,uBAClCoU,EAAU7d,EAAE+S,QAAQsjC,EAE1Bv2C,MAAK+1C,WAAWr2C,OAAS,EACzBM,KAAK+1C,WAAWtqB,OAAOnrB,MAAMN,KAAK+1C,YAAa,EAAG,GAAG1X,OAAOtgB,IAIhE,QAASy4B,WACEx2C,MAAK+1C,WACZxqC,EAAUnJ,UAAUkI,QAAQhK,MAAMN,KAAMO,WA9J5C,GAAIgL,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7B0wC,EAAY1wC,EAAQ,oBACpBc,EAAId,EAAQ,aAGdg3C,EAAuB,qBACrBX,EAAwB,yBACxBC,EAAsB,kBAExBe,EAAelrC,EAAUqV,qBAAqB,gBAC9CR,MACIhW,IAAKyrC,EACL/uC,IAAKmvC,EACL1rB,IAAK2rB,EACLzqB,OAAQzjB,OACRqtB,MAAO+gB,GAEXhL,OACI/oB,UACIipB,OAAS5oB,WAAYwoB,EAAiBpoB,QAAS,WAGvDsnB,QACI/nB,UACIq0B,OAAWh0B,WAAYyzB,EAAcrzB,QAAS,WAGtD5W,UAAWlE,OACXiR,KACIiW,IAAK,qBAETjV,UACIA,SAAU,kMAEgEy7B,EAAsB,8RAQxGxoC,GAAmBvG,IAAI8vC,GAEvB72C,EAAOJ,QAAUi3C,EAGjBv2C,EAAEM,YAAYi2C,GACVp2C,KAAMk1C,EACNjrC,QAASksC,EACTG,iBAAkBf,MA8GnBlF,mBAAmB,GAAGhZ,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAMm2C,IAAI,SAASx3C,EAAQQ,GACnG,YAqCA,SAASi3C,GAAoB94B,GAEzB,GAAI+4B,IAAwBh0B,QAAS9iB,KAAM0iB,WAAYwoB,EAEvDlrC,MAAKorC,MAAMzU,IAAI,KAAMmgB,GACrB92C,KAAKorC,MAAMhhC,IAAI2T,GACf/d,KAAKorC,MAAMxoB,GAAG,KAAMk0B,GAEpB5L,EAAgBzrC,KAAKO,MAIzB,QAAS+2C,GAAiB/M,GACtBhqC,KAAK2I,GAAGshC,SAAWD,EAIvB,QAASkB,KACLlrC,KAAKia,SAAS9R,QAAS6uC,cAAeh3C,KAAKorC,MAAMtkC,QArDrD,GAAIyE,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aAGd63C,EAAW1rC,EAAUqV,qBAAqB,YAC1C3H,KACIiW,IAAK,gBAET9O,KAAMpY,OACNoiC,OAAQpiC,OACRojC,OACI/oB,UACI60B,MAAQx0B,WAAYwoB,EAAiBpoB,QAAS,WAGtD7I,UACIA,SAAU,0LAOlB/M,GAAmBvG,IAAIswC,GAEvBr3C,EAAOJ,QAAUy3C,EAGjB/2C,EAAEM,YAAYy2C,GACVjL,WAAY6K,EACZ7M,QAAS+M,MAyBVrf,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAM02C,IAAI,SAAS/3C,EAAQQ,GAC7E,YAkFA,SAASw3C,KACL7rC,EAAUnJ,UAAU/B,KAAKC,MAAMN,KAAMO,WAErCP,KAAK0rC,KAAK,gBAAiBjP,GAE3Bv8B,EAAEuB,iBAAiBzB,MACfq3C,gBACAC,yBACDp3C,EAAE6E,MAMT,QAAS03B,KACLz8B,KAAKia,SAAS9R,SAAS4C,SACvB6hC,EAAentC,KAAKO,MAOxB,QAAS4sC,KACL,GAAIxhC,GAAQpL,KAAKkM,UAAUd,KAE3BlL,GAAEuB,iBAAiBzB,MACfwqC,YAAap/B,EAAMw6B,MACnB6E,WAAYr/B,EAAMse,KAClB6tB,cAAensC,EAAM2S,QACrBy5B,aAAcpsC,EAAMqsC,OACpBC,YAAatsC,EAAMusC,MACnBC,iBAAkBxsC,EAAMysC,WACxBC,gBAAiB1sC,EAAM2sC,UACvBC,aAAc5sC,EAAM6sC,OACpBC,gBAAiBlpB,EAAIsO,QAAQ6a,KAGjCj4C,EAAEuB,iBAAiBzB,MACfo4C,YAAa,EACbC,UAAWC,EACXC,SAAS,EACTC,eAAgBC,EAChBC,OAAQ,EACRC,eAAgB,IAChBC,eAAgB,EAChBC,cAAe,KACfC,UAAW,KACXC,mBAAmB,GACpB74C,EAAE6E,MAGL/E,KAAKiZ,IAAIwX,WAAYphB,SAAU,aAC/B2pC,EAAeh5C,KAAKyqC,WAAYzqC,KAAKu3C,cAAev3C,MACpDi5C,EAAgBj5C,KAAKwqC,YAAaxqC,MAClCk5C,EAAcl5C,KAAKg4C,aAAch4C,MAEjCA,KAAKoqC,OAAOxnB,GAAG,WAAaF,WAAYy2B,EAAgBr2B,QAAS9iB,OAUrE,QAASo5C,GAA2BzpB,GAChC3vB,KAAKu4C,SAAW5oB,EAChB3vB,KAAKyqC,WAAWxxB,IAAI2W,OAAOD,GAO/B,QAAS0pB,KACLr5C,KAAKu4C,SAAU,EACfv4C,KAAK2I,GAAG0nB,UAAU1pB,IAAI2yC,GACtBt5C,KAAKyqC,WAAWxxB,IAAI2W,QAAO,GAO/B,QAAS2pB,KACLv5C,KAAKu4C,SAAU,EACfv4C,KAAK2I,GAAG0nB,UAAUtpB,OAAOuyC,GACzBt5C,KAAKyqC,WAAWxxB,IAAI2W,QAAO,GAO/B,QAAS4pB,GAA6B7pB,EAAM5R,GACxC/d,KAAK43C,iBAAiB3+B,IAAI2W,OAAOD,GAC7B5R,GAAWA,EAAQ07B,gBAAez5C,KAAK05C,iBAAmB15C,KAAK+4C,mBACnE/4C,KAAK+4C,kBAAoBppB,EAI7B,QAASgqB,GAA8BrN,GACnCtsC,KAAK45C,eAAiBtN,EACtBtsC,KAAK83C,gBAAgBnvC,GAAG8Q,UAAY6yB,EACpCtsC,KAAKosC,iBAAgB,GAUzB,QAASyN,GAAwB/N,GAC7B9rC,KAAKq3C,aAAevL,EACpB9rC,KAAK85C,mBAAmBhO,GAU5B,QAASiO,GAA4Bh8B,GACjC/d,KAAKg6C,YAAcj8B,EAAQk8B,IAC3Bj6C,KAAKk6C,kBAAoBn8B,EAAQo8B,eAAiB,SAASv7C,GAAG,MAAOA,IAQzE,QAASw7C,GAAetqC,GACpB,GAAImqC,GAAMj6C,KAAKg6C,YACXK,EAAcr6C,KAAKwqC,YAAYpqB,KAAKtZ,KAExCgJ,GAAKA,GAAM5P,EAAEo6C,KACblyC,KAAKC,KAAKkyC,QAAQC,KAAKP,GAAOh6C,KAAMo6C,GAAe,SAAUI,EAAKC,GAC9D,GAAID,EAEA,MADAn4C,GAAOC,MAAM,uBAAyB83C,EAAc,KAC7CvqC,EAAG,GAAIxQ,OAAM,iBAGxB,IAAIq7C,GAAez6C,EAAEsY,UAAUkiC,EAC3BC,GAAc7qC,EAAG,KAAM6qC,GACtB7qC,EAAG,GAAIxQ,OAAM,iBAW1B,QAASs7C,GAAgC9O,GACrC,MAAMA,IACN9rC,KAAKs3C,qBAAuBxL,EAC5B9rC,KAAK04C,OAAS5M,EAAIpsC,WAClBM,MAAK66C,UAHav4C,EAAOC,MAAM,8CAWnC,QAASu4C,KACL,GAAIC,GAAY/6C,KAAKu4C,QAEjByC,EAAYh7C,KAAKs3C,qBAAqBllC,MAAMpS,KAAKo4C,YAAap4C,KAAKq4C,UAEvEr4C,MAAKu3C,cAAct9B,SAAS9R,QACxBgjC,aAAc6P,IAGlBh7C,KAAKw4C,eAAiBx4C,KAAKw4C,gBAAkBC,EAEzCsC,GACA/6C,KAAKi7C,aAET,IAAIC,GAAel7C,KAAKo4C,YAAcp4C,KAAKw4C,eACvC2C,GAAen7C,KAAK04C,OAAS14C,KAAKq4C,WAAar4C,KAAKw4C,cACxDx4C,MAAKw3C,aAAa7uC,GAAGonB,MAAMqrB,OAASF,EAAe,KACnDl7C,KAAK03C,YAAY/uC,GAAGonB,MAAMqrB,OAASD,EAAc,EAAIA,EAAc,KAAO,MAU9E,QAASnC,GAAetvB,EAAM3L,EAAS+b,GACnCA,EAAKsS,iBAAgB,GACrBruB,EAAQ9D,SAAS7P,IAAI+tC,GAErBzuB,EAAKzQ,IAAIwX,WACL4qB,SAAU,SACVD,OAAQthB,EAAK6e,eAAiB,KAC9B2C,MAAO,OACPjsC,SAAU,WACVksC,OAAQ,KAKZzhB,EAAKmhB,cACLvxB,EAAK0gB,OAAO9V,YACRoiB,OAAUh0B,WAAY84B,EAAa14B,QAASgX,GAC5C2hB,QAAW/4B,WAAYg5B,EAAc54B,QAASgX,KAUtD,QAASmf,GAAgBrT,EAAO9L,GAC5B8L,EAAMwE,OAAOsB,KAAK,QAAS,WACvB9F,EAAMxlB,KAAKwC,GAAG,IAAMF,WAAYi5B,EAAc74B,QAASgX,IACvD8L,EAAMwE,OAAOxnB,GAAG,SAAUF,WAAYk5B,EAAc94B,QAASgX,IAC7D8L,EAAMwE,OAAOxnB,GAAG,WAAYF,WAAYm5B,EAAY/4B,QAASgX,MASrE,QAASof,GAAc4C,EAAKhiB,GACxBgiB,EAAI1R,OAAOxnB,GAAG,SAAWF,WAAYq5B,EAAUj5B,QAASgX,IAO5D,QAASkiB,KACL,MAAOh8C,MAAK64C,cAOhB,QAASoD,GAAiB5S,GACtBrpC,KAAK64C,cAAgBxP,EACrBrpC,KAAKwqC,YAAYpqB,KAAKhW,IAAIi/B,GAAOA,EAAIsJ,OACrCzyC,EAAEmQ,YAAYrQ,KAAM,eAMxB,QAASk8C,KACLl8C,KAAK64C,cAAgB,KACrB74C,KAAKwqC,YAAYpqB,KAAKhW,IAAI,IAW9B,QAASuxC,GAAazlC,EAAKkK,GACvB,GAAI+R,GAAO/R,EAAK4I,UAAY5I,EAAK4I,SAAS+J,MAC1C,IAAI/yB,KAAKg6C,YAAa,CAClB,GAAIlgB,GAAO95B,IACXo6C,GAAe36C,KAAKO,KAAM,SAASy6C,EAAKE,GACpC,IAAIF,GAAQE,EACZ,IACI,GAAI58B,GAAU48B,EAAav6B,KAAKnP,IAAI6oB,EAAKogB,kBACzCpgB,GAAKkS,WAAWjuB,GAChBo+B,EAA2B18C,KAAKq6B,EAAM3H,EAAM2H,EAAKud,cACnD,MAAMz4C,GACJ0D,EAAOC,MAAM,aAAc3D,UAGhC,CACH,GAAIw9C,GAAeC,EAAY58C,KAAKO,KAAMmyB,EAC1CgqB,GAA2B18C,KAAKO,KAAMmyB,EAAMiqB,IAKpD,QAASC,GAAYlqB,GACjB,MAAOnyB,MAAKq3C,aAAaiF,OAAO,SAASC,GAErC,SADOA,GAAOC,SACVD,EAAO5J,MAAO,CACd,GAAIA,GAAQ4J,EAAO5J,MAAMpN,aACzB,OAAiE,IAA1DoN,EAAM5f,OAAOwS,cAAclhB,QAAQ8N,EAAKoT,kBAM3D,QAAS4W,GAA2BhqB,EAAMsqB,GAsBtC,QAASC,GAAaxwB,GAClB,MAAOA,GAAKymB,MAAMpN,gBAAkBpT,EAAKoT,cAtBxCpT,GAGGsqB,EAAY/8C,QAAUQ,EAAEsb,KAAKihC,EAAaC,GAC1C18C,KAAKosC,iBAAgB,GAASqN,eAAe,IACtCz5C,KAAK45C,gBACZ55C,KAAKosC,gBAAgBpsC,KAAKq3C,aAAa33C,OAAS,GAAKM,KAAKg6C,aAG1DyC,EAAY/8C,QACZM,KAAK28C,cACLF,EAAY,GAAGD,UAAW,EAC1Bx8C,KAAK84C,UAAY2D,EAAY,IAE7Bz8C,KAAKi7C,eAbTj7C,KAAKosC,iBAAgB,GAASqN,eAAe,IAiBjDz5C,KAAK85C,mBAAmB2C,GACxBz8C,KAAKyqC,WAAW9hC,GAAGi0C,UAAY,EAoBnC,QAASzD,GAAez9B,EAAM2Z,GAE1B,GAAIhE,GAAYwrB,EAAaxnB,EAAMynB,QAEhCzrB,IACC0rB,EAAgBt9C,KAAKO,KAAMqxB,GAGnC,QAAS0rB,GAAgB1rB,GAErB,GAAImrB,GAAWx8C,KAAK2I,GAAGgB,iBAAiB,aAAa,GAC/CqzC,EAAYh9C,KAAKyqC,WAAW9hC,GAAGi0C,UAC/BK,EAAcT,EAAWA,EAASU,UAAY,EAC9CC,EAAcF,EAAcD,CAElC,IAAIR,EAAU,CACV,GAAIxyB,GAAQozB,EAAyB39C,KAAKO,KAAMw8C,GAC1Ca,EAAWr9C,KAAKs3C,qBAAqBttB,GACrCszB,EAAUt9C,KAAKs3C,qBAAqBttB,EAAQqH,EAE9CisB,WACOD,GAASb,SAChBc,EAAQd,UAAW,EACnBx8C,KAAK84C,UAAYwE,EACjBt9C,KAAK66C,cAGL76C,MAAKs3C,qBAAqB,KAC1Bt3C,KAAKs3C,qBAAqB,GAAGkF,UAAW,EACxCx8C,KAAK66C,SAITsC,GAAcn9C,KAAK24C,eAAqC,EAApB34C,KAAKw4C,gBAAkC,IAAdnnB,IAC7DrxB,KAAKyqC,WAAW9hC,GAAGi0C,WAAa58C,KAAKw4C,eAAennB,EAAU,GAE9D8rB,EAAcn9C,KAAKw4C,gBAAgC,KAAdnnB,IACrCrxB,KAAKyqC,WAAW9hC,GAAGi0C,WAAa58C,KAAKw4C,eAAennB,EAAU,GAUtE,QAASksB,KACLv9C,KAAKw9C,cAAe,EAUxB,QAASC,KACL,GAAI3jB,GAAO95B,IACXA,MAAKw9C,cAAe,EAChBx9C,KAAK09C,gBAAgBC,cAAc39C,KAAK09C,gBAC5C19C,KAAK09C,eAAiBE,WAAW,WACxB9jB,EAAK0jB,cACNK,EAAcp+C,KAAKq6B,IACxB,KAGP,QAAS+jB,KACL79C,KAAKi7C,cACLj7C,KAAKosC,iBAAgB,GAASqN,eAAe,IAUjD,QAASmC,KACL57C,KAAK28C,cACD38C,KAAK05C,kBAAkB15C,KAAKosC,iBAAgB,GAUpD,QAASyP,GAAWngC,EAAM2Z,GACD,IAAjBA,EAAMynB,SACF98C,KAAK84C,WACLgF,EAASr+C,KAAKO,MAU1B,QAAS+7C,KACL,GAAI37B,IAASuyB,MAAO3yC,KAAKwqC,YAAY7hC,GAAGvH,MACxCpB,MAAKoW,YAAY,UAAWgK,GAC5BpgB,KAAKoqC,OAAOh0B,YAAY,yBAA0BgK,GAClDpgB,KAAKosC,iBAAgB,GAASqN,eAAe,IAUjD,QAAS+B,GAAa9/B,EAAM2Z,GACxB,GAAIrL,GAAQozB,EAAyB39C,KAAKO,KAAMq1B,EAAME,QAClDnV,EAAOpgB,KAAKs3C,qBAAqBttB,EAErChqB,MAAK84C,UAAY14B,EACjB09B,EAASr+C,KAAKO,MACdA,KAAK66C,SAUT,QAASa,GAAchgC,EAAM2Z,GACzB,GAAI2nB,GAAY3nB,EAAME,OAAOqnB,UACvBvrB,EAAY2rB,EAAYh9C,KAAK44C,eAAiB,OAAS,KACvD9nB,EAAa9wB,KAAKu3C,cAAc5uC,GAAGo1C,iBACnCC,EAAYh+C,KAAKu3C,cAAc5uC,GAAGs1C,kBAClCC,EAAiBptB,EAAaA,EAAWosB,UAAY,EACrDiB,EAAkBH,EAAYA,EAAUd,UAAY,EACpDkB,EAAiBF,EAAiBlB,EAAYh9C,KAAK24C,eAAiB34C,KAAKw4C,eACzE6F,EAAkBrB,EAAYmB,EAC9BG,EAAeC,KAAKC,MAAMH,EAAkBr+C,KAAKw4C,gBACjDiG,EAAcF,KAAKC,MAAMJ,EAAiBp+C,KAAKw4C,gBAC/CkG,EAAsBH,KAAKC,MAAMxB,EAAYh9C,KAAKw4C,gBAAkBmG,GAExD,QAAbttB,GAAqCstB,EAAdF,GACP,MAAbptB,GAAoCstB,EAAfL,KACzBt+C,KAAKo4C,YAAcsG,EAAsB,EAAIA,EAAsB,EACnE1+C,KAAKq4C,UAAYqG,EAAsBpG,EACvCt4C,KAAKw4C,eAAiB1nB,EAAWf,MAAMqrB,OACvCp7C,KAAK66C,UAET76C,KAAK44C,eAAiBoE,EAY1B,QAASI,GAAyBz0C,GAC9B,MAAOi2C,QAAOj2C,EAAGqB,aAAa,eAAiBhK,KAAKo4C,YAQxD,QAAS0F,WACE99C,MAAK84C,UAAU0D,SACtBx8C,KAAKi7C,cACLj7C,KAAKosC,iBAAgB,GACrBpsC,KAAKwqC,YAAYpqB,KAAKuW,IAAI,IAAMjU,WAAYi5B,EAAc74B,QAAS9iB,OAEnEA,KAAKogB,KAAKhW,IAAIpK,KAAK84C,WACnB94C,KAAKogB,KAAKyD,sBAAsBonB,GAChCjrC,KAAKwqC,YAAYpqB,KAAKwC,GAAG,IAAMF,WAAYi5B,EAAc74B,QAAS9iB,OAElEA,KAAK84C,UAAY,KACjB94C,KAAK85C,mBAAmB95C,KAAKq3C,cArmBjC,GAAI9rC,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aACZ4vB,EAAM5vB,EAAQ,OACdkD,EAASlD,EAAQ,qBAEnBk6C,EAAa,wBACbrO,EAAuB,qBAEvBkN,EAAmB,mMAInBG,EAAe,IACfqG,EAAS,GACTlG,EAAyB,GAEzBoG,EAAetzC,EAAUqV,qBAAqB,gBAC9CwpB,QACI/nB,UACIy8B,YAAep8B,WAAY+6B,EAAc36B,QAAS,SAClDi8B,WAAcr8B,WAAY66B,EAAaz6B,QAAS,WAGxD1C,MACItZ,IAAKk1C,EACL5xC,IAAK6xC,EACL1xB,IAAK2xB,EACLzwB,OAAQzjB,OACRqtB,MAAO4V,GAEXhyB,KACIiW,IAAK,oBAETjV,UACIA,SAAU,4qBAWd/N,UAAWlE,QAGfkF,GAAmBvG,IAAIk4C,GAEvBj/C,EAAOJ,QAAUq/C,EAKjB3+C,EAAEM,YAAYq+C,GACVx+C,KAAM+2C,EACNuF,YAAatD,EACb4B,YAAa1B,EACbyF,cAAe5F,EACfpN,WAAY6N,EACZoF,eAAgBlF,EAChBD,mBAAoBc,EACpBC,OAAQC,EACR1O,gBAAiBoN,EACjBjN,iBAAkBoN,EAClBzN,gBAAiBgQ,GA8VrB,IAAIW,IAAiBvV,GAAM,EAAGd,GAAM,MAuMjClgB,oBAAoB,IAAIoR,aAAa,GAAG2M,gBAAgB,GAAG1Q,IAAM,IAAIlzB,YAAY,MAAMy+C,IAAI,SAAS9/C,EAAQQ,GAC/G,YAEA,IAAI2L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/B+/C,EAAS5zC,EAAUqV,qBAAqB,UACxCR,KAAMpY,OACNoiC,OAAQpiC,OACRiR,KACIiW,IAAK,eAIbhiB,GAAmBvG,IAAIw4C,GAEvBv/C,EAAOJ,QAAU2/C,IAEdznB,aAAa,GAAG2M,gBAAgB,KAAK+a,IAAI,SAAShgD,EAAQQ,GAC7D,YAgCA,SAASy/C,GAA2BthC,GAChC,MAAI/d,MAAKs/C,YACEh9C,EAAOoQ,KAAK,yDACvB1S,KAAKs/C,aAAc,EACnBt/C,KAAKu/C,mBAAqBxhC,EAE1ByhC,EAAkB//C,KAAKO,UACvBy/C,GAAqBhgD,KAAKO,KAAM,OAIpC,QAASy/C,GAAqBC,GAC1B1/C,KAAKoqC,OAAOsV,GAAO,SAAWh9B,WAAY88B,EAAmB18B,QAAS9iB,OACtEA,KAAKogB,KAAKs/B,GAAO,IAAMh9B,WAAY88B,EAAmB18B,QAAS9iB,OAInE,QAASw/C,KACLx/C,KAAK2I,GAAGonB,MAAMqrB,OAAS,CAEvB,IAAIuE,GAAY3/C,KAAK2I,GAAGi3C,aAClBC,EAAY7/C,KAAKu/C,mBAAmBM,UACpCC,EAAY9/C,KAAKu/C,mBAAmBO,SAE1CH,GAAYA,GAAaG,EACXA,EACaD,GAAbF,EACAE,EACAF,EAEd3/C,KAAK2I,GAAGonB,MAAMqrB,OAASuE,EAAY,KAIvC,QAASI,KACL,MAAM//C,MAAKs/C,aAEXt/C,KAAKs/C,aAAc,MACnBG,GAAqBhgD,KAAKO,KAAM,QAFrBsC,EAAOoQ,KAAK,mDAM3B,QAASstC,KACL,MAAOhgD,MAAKs/C,YAUhB,QAASW,GAAmBjW,GACxBhqC,KAAK2I,GAAGshC,SAAWD,EApFvB,GAAIz+B,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAC7Bc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,qBAGnB8gD,EAAa30C,EAAUqV,qBAAqB,cAC5CR,KAAMpY,OACNoiC,OAAQpiC,OACRiR,KACIiW,IAAK,mBAIbhiB,GAAmBvG,IAAIu5C,GAEvBtgD,EAAOJ,QAAU0gD,CAMjBhgD,GAAEM,YAAY0/C,GACVC,gBAAiBd,EACjBe,eAAgBL,EAChBM,cAAeL,EACfhW,QAASiW,MA4DV35B,oBAAoB,IAAIoR,aAAa,GAAG2M,gBAAgB,GAAG5jC,YAAY,MAAM6/C,IAAI,SAASlhD,EAAQQ,GACrG,YA0BA,SAAS2gD,KACL,GAAIC,GAAUxgD,KAAK2I,GAAGvH,MAClBqG,EAAQ+4C,EAAQ/4C,MAAMg5C,EAC1B,IAAMh5C,EAAN,CACA,GAAIi5C,GAAQj5C,EAAM,GACZk5C,EAAOl5C,EAAM,EACnB,MAAIi5C,EAAQ,IAAMC,EAAO,IAAzB,CACA,GAAIC,GAAO,GAAIC,MAAK,KAAM,EAAG,EAAGH,EAAOC,EAEvC,OAAOzgD,GAAE2tC,OAAO+S,KAIpB,QAASE,GAAW1/C,GAchB,QAASktC,GAAIxvC,GAAI,MAAW,IAAJA,EAAS,IAAMA,EAAIA,EAb3C,GAAI8hD,GAAO1gD,EAAE2tC,OAAOzsC,EACpB,KAAMw/C,EAEF,YADA5gD,KAAK2I,GAAGvH,MAAQ,GAIpB,IAAIo/C,GAAUO,EACLv4C,QAAQ,KAAM8lC,EAAIsS,EAAKI,aACvBx4C,QAAQ,KAAM8lC,EAAIsS,EAAKK,cAGhC,OADAjhD,MAAK2I,GAAGvH,MAAQo/C,EACTA,EAMX,QAASU,KACLlhD,KAAK2I,GAAGvH,MAAQ,GAxDpB,GAAImK,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/B+hD,EAAS51C,EAAUqV,qBAAqB,UACxCwpB,OAAQpiC,OACRoY,MACItZ,IAAKy5C,EACLn2C,IAAK02C,EACLv2B,IAAK22B,GAETjoC,KACIiW,IAAK,eAIbhiB,GAAmBvG,IAAIw6C,GAEvBvhD,EAAOJ,QAAU2hD,CAGjB,IAAIV,GAAa,sCACXM,EAAgB,UAqCnBrpB,aAAa,GAAG2M,gBAAgB,KAAK+c,IAAI,SAAShiD,EAAQQ,GAC7D,YAEA,IAAI2L,GAAYnM,EAAQ,cAClB8N,EAAqB9N,EAAQ,iBAG/BiiD,EAAY91C,EAAUqV,qBAAqB,aAC3C1U,UAAWlE,OACXoY,KAAMpY,OACNoiC,OAAQpiC,OACRiR,KACIiW,IAAK,kBAIbhiB,GAAmBvG,IAAI06C,GAEvBzhD,EAAOJ,QAAU6hD,IAEd3pB,aAAa,GAAG2M,gBAAgB,KAAKid,IAAI,SAASliD,EAAQQ,GAC7D,YAqEA,SAAS2hD,GAAqBxjC,GAC1Bjc,EAAMic,GACF1b,QAASH,OACTwZ,KAAM1Z,EAAMC,SAASC,QACrBs/C,MAAOx/C,EAAMC,SAAS8W,SACtB0oC,QAASz/C,EAAMC,SAAS28C,SAG5B,IAAI8C,GAAQC,EAAQvoC,iBAEpB2E,GAAU6jC,EAAgB7jC,EAE1B,IAAI8jC,GAAWC,EAAkB/jC,EAAQrC,KACzCgmC,GAAMzoC,IAAIia,cAAc2uB,GAExBH,EAAMK,QACFhkC,QAASA,EACTikC,SAAS,GAGbN,EAAMznC,SAAS9R,OAAO4V,GAAShT,QAE/B,IAAIk3C,GAAaP,EAAMx1C,UAAUd,KAMjC,IAJI2S,EAAQyjC,OACRS,EAAWC,SAAS9X,OAAOxnB,GAAG,SACxBF,WAAYy/B,EAAkBr/B,QAAS4+B,IAE7C3jC,EAAQ0jC,QACR,CAAY7D,WAAW,WAChB8D,EAAMK,OAAOC,SACZN,EAAMU,cACXrkC,EAAQ0jC,SAEf,MAAOC,GAUX,QAASW,GAAmBtkC,GACxB,GAAI2jC,GAAQC,EAAQW,YAAYvkC,EAEhC,OADA2jC,GAAMa,YACCb,EAIX,QAASS,KACLniD,KAAKoiD,aAIT,QAASR,GAAgB7jC,GAMrB,MALAA,GAAU7d,EAAEiD,MAAM4a,GAClBA,EAAQyjC,MAAgC,mBAAjBzjC,GAAQyjC,OAAwBzjC,EAAQyjC,SAAU,EACzEzjC,EAAQ0jC,QAAUlD,KAAKC,MAAMzgC,EAAQ0jC,SACrC1jC,EAAQrC,KAAOqC,EAAQrC,MAAQ,OAExBqC,EAOX,QAASykC,KACLC,EAAahjD,KAAKO,MAAM,GAO5B,QAAS0iD,KACLD,EAAahjD,KAAKO,MAAM,GACxBA,KAAKsK,UAIT,QAASm4C,GAAa3yB,GAClBA,EAA0B,mBAAVA,IACA9vB,KAAK+hD,OAAOC,UACXlyB,CAEjB,IAAI6yB,GAAY7yB,EAAS,MAAQ,SAC3B8yB,EAAe9yB,EAAS,cAAgB,aAE9C9vB,MAAK+hD,OAAOC,QAAUlyB,EAEtB9iB,SAASC,KAAK21C,GAAc5iD,KAAK2I,IACjC3I,KAAKiZ,IAAI2W,OAAOE,GAChB9vB,KAAK2I,GAAGuB,aAAa,eAAgB4lB,GACrC9vB,KAAK2I,GAAG0nB,UAAUsyB,GAAW,MAC7B3iD,KAAK2I,GAAGmnB,EAAS,QAAU,UApK/B,GAAIvkB,GAAYnM,EAAQ,iBAClB8N,EAAqB9N,EAAQ,oBAG7B0C,GAFgB1C,EAAQ,gCACfA,EAAQ,wBACTA,EAAQ,wBAChB4C,EAAQF,EAAME,MACd9B,EAAId,EAAQ,aAGd0iD,GACAe,QAAS,gBACTC,QAAS,gBACTz3C,KAAM,aACN03C,OAAQ,eACRC,MAAO,eAIPrB,EAAUp2C,EAAUqV,qBAAqB,WACzC1U,UAAWlE,OACXoiC,OAAQpiC,OACRiR,KACIiW,KAAM,cAAe,QAAS,QAC9B7lB,YACI45C,KAAQ,QACRC,cAAe,SAGvBjpC,UACIA,SAAU,qNAQlB/M,GAAmBvG,IAAIg7C,GAEvB/hD,EAAOJ,QAAUmiD,EAGjBzhD,EAAEkD,OAAOu+C,GACLW,YAAaf,EACbgB,UAAWF,IAIfniD,EAAEM,YAAYmhD,GACVY,UAAWC,EACXJ,WAAYM,MAqHbS,sBAAsB,GAAGC,+BAA+B,GAAGC,uBAAuB,IAAIC,gBAAgB,GAAGC,mBAAmB,GAAG9iD,YAAY,MAAM+iD,IAAI,SAASpkD,EAAQQ,GACzK,YAgIA,SAAS6jD,GAAuB1lC,EAAS2lC,GACrC5hD,EAAMic,GACF4lC,MAAO3hD,EAAMC,SAASC,QACtB0hD,KAAM5hD,EAAMC,SAASC,QACrBiwB,KAAMnwB,EAAMC,SAASC,QACrBs/C,MAAOx/C,EAAMC,SAASD,EAAMqC,MAAM0U,SAC9B8qC,SAAU7hD,EAAMC,SAAS8W,SACzB+qC,SAAU9hD,EAAMC,SAAS8W,SACzB05B,OAAQzwC,EAAMC,SAAS8W,YAE3BgrC,QAAS/hD,EAAMC,WACXhC,KAAM+B,EAAMC,SAASC,QACrBwZ,KAAMxZ,OACNywC,MAAOzwC,OACPs/C,MAAOx/C,EAAMC,SAAS8W,SACtBzG,OAAQtQ,EAAMC,SAASC,QACvBke,KAAMpe,EAAMC,SAASD,EAAMgiD,KAC3B90B,IAAKltB,EAAMC,SAASC,YAI5B,IAAI+hD,GAASC,EAAS9qC,iBAEtB2E,GAAU6jC,EAAgB7jC,GAC1BkmC,EAAOE,SACHpmC,QAASA,EACTikC,SAAS,GAGbiC,EAAOhqC,SACF9R,OAAO4V,GACPhT,QAEL,IAAIq5C,GAAcH,EAAO/3C,UAAUd,KAmBnC,OAjBI2S,GAAQyjC,MAAMqC,UACdI,EAAO7Z,OAAOxnB,GAAG,SACXF,WAAY2hC,EAAkBvhC,QAASmhC,IAE7ClmC,EAAQ4lC,OAAS5lC,EAAQyjC,MAAM/O,QAC/B2R,EAAYlC,SAAS9X,OAAOxnB,GAAG,SACzBF,WAAYy/B,EAAkBr/B,QAASmhC,IAEjDlmC,EAAQgmC,QAAQ7+C,QAAQ,SAAS42C,GAC7B,GAAIwI,IACA5hC,WAAYxiB,EAAEqkB,QAAQggC,EAAoBzI,GAC1Ch5B,QAASmhC,EAEbG,GAAYtI,EAAI77C,MAAMmqC,OAAOxnB,GAAG,QAAS0hC,KAGzCZ,GAAYA,EAAWO,GACpBA,EAIX,QAASM,GAAmB9R,GACpBA,EAAO+O,SAAU,GACjBgD,EAAc/kD,KAAKO,MAAM,EAE7B,IAAIogB,GAAOlgB,EAAEoS,OAAOmgC,EAAOryB,KAAMpgB,KAAMyyC,EACvCgS,GAAgBhlD,KAAKO,KAAMyyC,EAAOngC,OAAQ8N,GAI9C,QAASqkC,GAAgBnyC,EAAQ8N,GAC7B,GAAIsC,GAAa1iB,KAAKmkD,QAAQzhC,UACL,mBAAdA,GACPA,EAAWjjB,KAAKO,KAAMsS,EAAQ8N,GAE9BsC,EAAWA,WAAWjjB,KAAKijB,EAAWI,QAASxQ,EAAQ8N,GAI/D,QAASikC,GAAiBjvB,EAAWC,GAC7BA,EAAME,QAAUv1B,KAAK2I,IACrB3I,KAAK0kD,YAAY,aAIzB,QAASvC,KACLniD,KAAK0kD,YAAY,UAIrB,QAASC,GAAWtvB,GACZuvB,GACOA,EAAaT,QAAQpmC,QAAQyjC,MAAMsC,UAClB,IAAjBzuB,EAAMynB,SACb8H,EAAaF,YAAY,aAIjC,QAAS9C,GAAgB7jC,GAcrB,MAbAA,GAAU7d,EAAEiD,MAAM4a,GAClBA,EAAQgmC,QAAU7jD,EAAEiD,MAAM4a,EAAQgmC,SAAWc,GAC7C9mC,EAAQgmC,QAAQ7+C,QAAQ,SAAS42C,GAC7BA,EAAI77C,KAAO67C,EAAI77C,MAAQqI,MAG3ByV,EAAQyjC,MAAgC,mBAAjBzjC,GAAQyjC,OAAwBzjC,EAAQyjC,SAAU,EACnDthD,EAAE+nC,OAAO6c,GAAe,GACA,gBAAjB/mC,GAAQyjC,MACXthD,EAAE6kD,YAAYD,EACZ,SAASE,GAAO,MAAOjnC,GAAQyjC,MAAMwD,MAAS,IAChD9kD,EAAE+nC,OAAO6c,GAAe,GAE3C/mC,EAUX,QAASknC,GAAqBlnC,EAAS2E,EAAYghC,GAC/C,GAAIO,GAASC,EAASgB,aAAannC,EAAS2lC,EAE5C,OADAO,GAAOkB,WAAWziC,GACXuhC,EAKX,QAASO,GAAc10B,GACnBA,EAA0B,mBAAVA,IACA9vB,KAAKmkD,QAAQnC,UACZlyB,CAEjB,IAAI6yB,GAAY7yB,EAAS,MAAQ,SAC3B8yB,EAAe9yB,EAAS,cAAgB,aAE9C9vB,MAAKmkD,QAAQnC,QAAUlyB,EAEnBA,IAAYs1B,GACZC,IAEJr4C,SAASC,KAAK21C,GAAc5iD,KAAK2I,IAC7B28C,GACAt4C,SAASC,KAAK21C,GAAc0C,GAChCtlD,KAAKiZ,IAAI2W,OAAOE,GAChB9vB,KAAK2I,GAAGuB,aAAa,eAAgB4lB,GACrC9iB,SAASC,KAAKojB,UAAUsyB,GAAW,cACnC3iD,KAAK2I,GAAG0nB,UAAUsyB,GAAW,MAE7BiC,EAAe90B,EAAS9vB,KAAOgI,OAC/BhI,KAAK2I,GAAGmnB,EAAS,QAAU,UAM/B,QAASu1B,KACLC,EAAat4C,SAASqN,cAAc,OACpCirC,EAAWztC,UAAY,yBACvB7K,SAAS06B,iBAAiB,UAAWid,GACrCS,GAAqB,EAYzB,QAASG,GAAoB7iC,GAGzB,MAFA5gB,GAAM4gB,EAAY1gB,EAAMqC,MAAMtC,UAAY2gB,WAAY3gB,SAAU+gB,QAAS9gB,EAAMgiD,OAE3EY,EACOtiD,EAAOoQ,KAAK,2EAEvB1S,KAAKmkD,QAAQzhC,WAAaA,MAC1B8hC,GAAc/kD,KAAKO,MAAM,IAW7B,QAASwlD,GAAqBlzC,EAAQ8N,GAClC,MAAMwkC,IAGNtyC,EAASA,GAAU,SAEnBkyC,EAAc/kD,KAAKO,MAAM,OACzBykD,GAAgBhlD,KAAKO,KAAMsS,EAAQ8N,IALxB9d,EAAOoQ,KAAK,4DAc3B,QAAS+yC,KACL,MAAOb,GAIX,QAASc,KACL14C,SAAS46B,oBAAoB,UAAW+c,GACxCp5C,EAAUnJ,UAAUkI,QAAQhK,MAAMN,KAAMO,WAhV5C,GAAIgL,GAAYnM,EAAQ,iBAClB8N,EAAqB9N,EAAQ,oBAC7BkJ,EAAgBlJ,EAAQ,gCACxBkD,EAASlD,EAAQ,wBACjB0C,EAAQ1C,EAAQ,uBAChB4C,EAAQF,EAAME,MACd9B,EAAId,EAAQ,aAGdylD,IAAsBnpC,KAAM,UAAWi3B,MAAO,KAAMrgC,OAAQ,OAE5DwyC,GAAiB,WAAY,WAAY,UAiBzCZ,EAAW34C,EAAUqV,qBAAqB,YAC1C1U,UAAWlE,OACXoiC,OAAQpiC,OACRiR,KACIiW,KAAM,eAAgB,QAAS,QAC/B7lB,YACI45C,KAAQ,SACRC,cAAe,SAGvBjpC,UACIA,SAAU,04CAkClB/M,GAAmBvG,IAAIu9C,GAEvBtkD,EAAOJ,QAAU0kD,EAGjBhkD,EAAEkD,OAAO8gD,GACLgB,aAAczB,EACd0B,WAAYF,EACZU,gBAAiBF,IAIrBvlD,EAAEM,YAAY0jD,GACViB,WAAYI,EACZb,YAAac,EACbl7C,QAASo7C,GA6Lb,IAAIN,GAAoBE,EAUpBV,IAoDDzB,sBAAsB,GAAGC,+BAA+B,GAAGC,uBAAuB,IAAIC,gBAAgB,GAAGC,mBAAmB,GAAG9iD,YAAY,MAAMmlD,IAAI,SAASxmD,EAAQQ,GACzK,YAkCA,SAASimD,KAyBL,QAASC,GAASzwB,GACd,GAAIE,GAASF,EAAME,OACbwwB,EAAgB1wB,EAAM0wB,cACtBC,EAAYlsB,EAAKmsB,UAAUD,SAE7BE,GAAS3wB,IACTywB,EAAUj/C,OAAOwuB,EAAO0E,cAAcjtB,SAAU,QAAS0lC,GAEzDwT,EAASH,IACTC,EAAUr/C,IAAIo/C,EAAc9rB,cAAcjtB,SAAU,QAAS0lC,GAGrE,QAASA,GAAQrd,GACRyE,EAAKnxB,GAAGyiB,SAASiK,EAAME,SACxBuE,EAAKqsB,WAtCb,GAAIC,GAAWpmD,KAAK2I,GAAG09C,cAAc,IAAMC,GACrCC,EAASvmD,KAAK2I,GAAG09C,cAAc,IAAMG,EAE3C,KAAOJ,IAAYG,EACf,MAAOjkD,GAAOC,MAAM,cAAe+jD,EAAkB,KAAME,EAAgB,cAE/E,IAAIC,GAAMl3B,OAAOviB,SACX05C,EAAe1mD,KAAK2mD,WAAW7hD,KAAK9E,KAAMgI,QAE5Cg+C,EAAY,GAAIY,EACpB5mD,MAAKimD,WACDY,KAAMN,EACNvE,SAAS,EACTgE,UAAWA,GAEfhmD,KAAKmmD,UACL,IAAIrsB,GAAO95B,IAEXgmD,GAAUr/C,IAAIy/C,EAAU,QAASM,GAEjCV,EAAUr/C,IAAI8/C,EAAK,WAAYX,GAC/BE,EAAUr/C,IAAI8/C,EAAK,QAAS/T,GAsBhC,QAASwT,GAASv9C,GACd,MAAOA,IAAoB,UAAdA,EAAGmmB,QAIpB,QAASg4B,KACL9mD,KAAKimD,UAAUD,UAAUe,kBAClB/mD,MAAKimD,UACZ16C,EAAUnJ,UAAUkI,QAAQhK,MAAMN,KAAMO,WAI5C,QAASymD,KACLhnD,KAAK2mD,YAAW,GAIpB,QAASM,KACLjnD,KAAK2mD,YAAW,GAIpB,QAASO,GAAsBp3B,GAC3BA,EAA0B,mBAAVA,IACA9vB,KAAKimD,UAAUjE,UACdlyB,EAEjB9vB,KAAKimD,UAAUjE,QAAUlyB,CAEzB,IAAI+2B,GAAO7mD,KAAKimD,UAAUY,IAC1BA,GAAK92B,MAAML,QAAUI,EACK,QACA,OA5G9B,GAAIvkB,GAAYnM,EAAQ,iBAClB8N,EAAqB9N,EAAQ,oBAC7Bc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,wBACjBwnD,EAAexnD,EAAQ,+BAGzBknD,EAAmB,kBACjBE,EAAiB,gBAGnBW,EAAa57C,EAAUqV,qBAAqB,cAC5CwpB,OAAQpiC,OACRiR,KACIiW,KAAM,iBAAkB,cAIhChiB;EAAmBvG,IAAIwgD,GAEvBvnD,EAAOJ,QAAU2nD,EAGjBjnD,EAAEM,YAAY2mD,GACV9qC,MAAOwpC,EACPv7C,QAASw8C,EACTH,WAAYO,EACZE,SAAUJ,EACVb,SAAUc,MAmFXI,8BAA8B,GAAGhE,uBAAuB,IAAIC,gBAAgB,GAAGC,mBAAmB,GAAG9iD,YAAY,MAAM6mD,IAAI,SAASloD,EAAQQ,GAC/I,YA0BA,SAASG,GAAOge,GACZ7d,EAAEqnD,WAAWxnD,EAAQge,GAPzB,GAAI7d,GAAId,EAAQ,aACV4vB,EAAM5vB,EAAQ,MAGpBQ,GAAOJ,QAAUO,EAMjBA,GACIsH,OACIvC,KAAM,UACN0F,KAAM,WAEVyR,aAAc,oBACdurC,gBAAiB,QACjB/hD,OACIC,sBAAuB,sBAE3BuU,UACIqjB,QAAStO,EAAIsO,SAEjBmqB,YACIC,WAAY,qBACZC,gBAAiB,IACjBC,KAAM,GACNC,WAAY,mBACZC,iBAAkB,oBAClBC,eACIC,YAAY,EACZ3lD,SAAS,IAGjB40B,UACIV,WACIre,UAAW,+BACX+vC,sBAAuB,yDACvBC,mBAAoB,mFAG5B3N,SACI4N,aAAc,IACdC,oBAAqB,oBACrBC,WAAY,kBACZC,UACI7G,QAAS,MAGjB8G,WACIC,KACI/G,QAAS,KACTgH,eAAgB,cAGxB3mD,OAAO,EACP4mD,OAAO,MAGR/0B,IAAM,IAAIlzB,YAAY,MAAMkoD,IAAI,SAASvpD,EAAQQ,GACpD,YA2BA,SAASgpD,GAAO7gB,EAAQv+B,EAAiBgW,GACrCpX,KAAK,WACDygD,EAAQ9gB,EAAQv+B,EAAiBgW,KAKzC,QAASqpC,GAAQ9gB,EAAQv+B,EAAiBgW,GACjB,kBAAVuoB,KACPvoB,EAAWuoB,EACXA,EAAS//B,OACTwB,GAAkB,GAGQ,kBAAnBA,KACPgW,EAAWhW,EACXA,GAAkB,GAGtBu+B,EAASA,GAAU/6B,SAASC,KAE5B67C,EAAS1yC,YAAY,UAAY+B,MAAO,YACxC4wC,EAAoBhhB,EAAQv+B,EAAiB,SAASw/C,GAClDF,EAAS1yC,YAAY,UACjB+B,MAAO,WACP6wC,MAAOA,IAEXxpC,EAASwpC,KAKjB,QAASD,GAAoBhhB,EAAQv+B,EAAiBgW,GAClD,GAAIypC,GAAelhB,EAAO/9B,aAAajK,EAAOsH,MAAMmD,OAC7Bu9B,GACDA,EAAOp+B,iBAAiB,IAAM5J,EAAOsH,MAAMmD,KAAO,KAEpEw+C,KACEE,EAAaD,EAAavpD,OAC1BypD,EAAc,CAEpBjpD,GAAEgF,QAAQ+jD,EAAc,SAAUtgD,GAC9BygD,EAASzgD,EAAIa,EAAiB,SAASixC,GACnCuO,EAAMrgD,EAAG2mC,IAAMmL,GAAO9xC,EACtBwgD,IACIA,GAAeD,GACf1pC,EAASwpC,OAMzB,QAASI,GAASzgD,EAAIa,EAAiBgW,GACnC,GAAIzS,EAAQrD,SAASf,GAAIjJ,OACrB,KAAM,IAAI2pD,GAAY,iDAE1B,IAAIvgD,GAAO,GAAI4B,GAAc/B,EAE7BG,GAAKxB,QAAQY,WAEbqyC,EAAQzzC,IAAIgC,EAAK2B,QAAS,SAASgwC,EAAKmJ,GACpC,MAAInJ,IACAA,EAAIp4C,QAAUo4C,EAAIp4C,SAAW,mBAAsByG,EAAK2B,YAExD+U,GAASi7B,KAIb9xC,EAAG8Q,UAAYmqC,EACXp6C,GAAiBkB,EAAc3D,OAAO4B,OAC1C6W,GAAS,SA9FjB,GAAIspC,GAAW1pD,EAAQ,mBACjBm7C,EAAUn7C,EAAQ,kBAElB2N,GADS3N,EAAQ,iBACPA,EAAQ,eAClBW,EAASX,EAAQ,YACjBsL,EAAgBtL,EAAQ,uBACxBiqD,EAAcjqD,EAAQ,gBAAgBkqD,MAG5C1pD,GAAOJ,QAAUopD,IAyFdW,sBAAsB,EAAEC,WAAW,GAAG/7C,kBAAkB,GAAGE,aAAa,GAAGC,eAAe,GAAG67C,gBAAgB,IAAIC,iBAAiB,MAAMC,IAAI,SAASvqD,EAAQQ,GAChK,YAyHA,SAASS,GAAK8D,EAAYC,EAAcuf,GAEhCA,GACA3jB,KAAK0jB,kBAAkBC,GAE3BimC,EAAuBnqD,KAAKO,MAIhC,QAAS4pD,KACL1pD,EAAEuB,iBAAiBzB,MACf6pD,uBACAC,+BACD5pD,EAAEs1C,MAOT,QAASuU,KACL/pD,KAAKgqD,QACL,IAAIrmC,GAAgB3jB,KAAK4jB,kBACrBD,IACAA,EAAcrZ,UAqCtB,QAAS2/C,GAAa5nC,EAAUK,GAC5B,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAIzD,QAASynC,GAAe9nC,EAAUK,GAC9B,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc0nC,cAAe,IAGtF,QAASC,GAAmBhoC,EAAUK,GAClC,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc0nC,cAAe,EAAGE,MAAM,IAI/F,QAASC,GAAiBloC,EAAUK,GAChC,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc4nC,MAAM,IAI7E,QAASE,GAAkBnoC,EAAUK,GACjC,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc4nC,MAAM,IAI7E,QAASJ,GAAyB7nC,EAAUK,EAAY3E,GAoBpD,MAnBAjc,GAAMugB,EAAUrgB,EAAMqC,MAAMnC,QAASA,QAASuoD,SAC9C3oD,EAAM4gB,EAAY1gB,EAAMqC,MAAMtC,UAC1B2gB,WAAY3gB,SACZ+gB,QAAS9gB,EAAMgiD,IACfjmC,QAAS/b,EAAMC,SAAST,WAGH,kBAAdkhB,KACPA,GACIA,WAAYA,EACZI,QAAS9iB,KAAK0E,cAIlBqZ,IACA2E,EAAW3E,QAAU2E,EAAW3E,YAChC7d,EAAEkD,OAAOsf,EAAW3E,QAASA,IAG1B2sC,EAAcjrD,KAAKO,KAAMqiB,EAAUK,GAI9C,QAASgoC,GAAcroC,EAAUK,GAE7B,MADAxiB,GAAEwB,eAAeghB,EAAY,aAAcL,GACpCsoC,EAAalrD,KAAKO,KAAM,sBAAuBqiB,EAAUK,GAIpE,QAASioC,GAAaxlD,EAAYkd,EAAUK,GACjB,gBAAZL,KACPA,EAAWA,EAASva,MAAM8iD,GAE9B,IAAIC,GAAkB7qD,KAAK8qD,uBAAuBzoC,EAElD,IAAIA,YAAoBooC,QACpB,MAAOzqD,MAAKmF,GAAY0lD,EAAiBxoC,EAAUK,EAGnD,IAAIqoC,IAAU,CAOd,OALA1oC,GAASnd,QAAQ,SAAS7C,GACtB,GAAI2oD,GAAsBhrD,KAAKmF,GAAY0lD,EAAiBxoD,EAASqgB,EACrEqoC,GAAUA,GAAWC,GACtBhrD,MAEI+qD,EAiBf,QAASE,GAAoBJ,EAAiBxoD,EAASqgB,GACnD,IAAOmoC,EAAgBxoD,KAAYwoD,EAAgBxoD,GAAS3C,OAAS,CACjEmrD,EAAgBxoD,MACZA,YAAmBooD,UACnBI,EAAgBxoD,GAAS6oD,QAAU7oD,GACnCrC,KAAKmrD,gBACLnrD,KAAKmrD,eAAeC,kBAAkB/oD,EAC1C,IAAIgpD,IAAgB,EAGxB,GAAIC,GAAiBT,EAAgBxoD,GACjCkpD,EAAmBF,GAA8E,IAA7DG,EAAmB/rD,KAAKO,KAAMsrD,EAAgB5oC,EAKtF,OAHI6oC,IACAD,EAAe77C,KAAKiT,GAEjB6oC,EAUX,QAASC,GAAmB9hC,EAAMhH,GAE9B,MAAOxiB,GAAEurD,UAAU/hC,EAAM,SAASgiC,GAC9B,MAAOhpC,GAAWA,YAAcgpC,EAAOhpC,YAC5BA,EAAWI,SAAW4oC,EAAO5oC,UAuBhD,QAASwR,GAAW9R,GAChB1gB,EAAM0gB,EAAoBxgB,EAAMqB,WAAWrB,EAAMqC,MAAMtC,UAAY2gB,WAAY3gB,SAAU+gB,QAAS9gB,EAAMgiD,OAExG,IAAIvhC,GAAsBviB,EAAE6c,QAAQyF,EAAoB,SAASE,EAAYL,GACzE,MAAOriB,MAAK4iB,GAAGP,EAAUK,IAC1B1iB,KAEH,OAAOyiB,GAwBX,QAASkpC,GAActpC,EAAUK,GAS7B,MARA5gB,GAAMugB,EAAUrgB,EAAMqC,MAAMnC,QAASA,QAASuoD,SAC9C3oD,EAAM4gB,EAAY1gB,EAAMC,SAASD,EAAMqC,MAAMtC,UACzC2gB,WAAY3gB,SACZ+gB,QAAS9gB,EAAMgiD,IACfjmC,QAAS/b,EAAMC,SAAST,YAIrBoqD,EAAensD,KAAKO,KAAMqiB,EAAUK,GAI/C,QAASkpC,GAAevpC,EAAUK,GAC9B,MAAOioC,GAAalrD,KAAKO,KAAM,oBAAqBqiB,EAAUK,GAgBlE,QAASmpC,GAAkBhB,EAAiBxoD,EAASqgB,GACjD,GAAI4oC,GAAiBT,EAAgBxoD,EACrC,KAAMipD,IAAoBA,EAAe5rD,OACrC,OAAO,CAEX,IAAIgjB,EAAY,CACa,kBAAdA,KACPA,GAAeA,WAAYA,EAAYI,QAAS9iB,KAAK0E,aAEzD,IAAIonD,GAAkBN,EAAmB/rD,KAAKO,KAAMsrD,EAAgB5oC,EACpE,IAAuB,IAAnBopC,EACA,OAAO,CACXR,GAAe7/B,OAAOqgC,EAAiB,GACjCR,EAAe5rD,QACjBM,KAAK+rD,sBAAsBlB,EAAiBxoD,OAGhDrC,MAAK+rD,sBAAsBlB,EAAiBxoD,EAEhD,QAAO,EAaX,QAAS0pD,GAAsBlB,EAAiBxoD,SACrCwoD,GAAgBxoD,GACnBrC,KAAKmrD,gBAAoC,gBAAX9oD,IAC9BrC,KAAKmrD,eAAea,oBAAoB3pD,GAsBhD,QAAS4pD,GAAYzpC,GACjB1gB,EAAM0gB,EAAoBxgB,EAAMqB,WAAWrB,EAAMC,SAASD,EAAMqC,MAAMtC,UAAY2gB,WAAY3gB,SAAU+gB,QAAS9gB,EAAMgiD,QAEvH,IAAIkI,GAAuBhsD,EAAE6c,QAAQyF,EAAoB,SAASE,EAAYL,GAC1E,MAAOriB,MAAK22B,IAAItU,EAAUK,IAC3B1iB,KAEH,OAAOksD,GAOX,QAASC,KACLC,EAAmB3sD,KAAKO,KAAMA,KAAK8pD,4BACnCsC,EAAmB3sD,KAAKO,KAAMA,KAAK6pD,qBAIvC,QAASuC,GAAmBvB,GACxB3qD,EAAEqB,QAAQspD,EAAiB,SAASwB,EAAahqD,GAC7CrC,KAAK+rD,sBAAsBlB,EAAiBxoD,IAC7CrC,MAqBP,QAASoW,GAAY/T,EAAS+d,EAAMZ,EAAU8sC,GAC1CxqD,EAAMO,EAASL,EAAMqC,MAAMnC,OAAQuoD,SACnC3oD,EAAM0d,EAAUxd,EAAMC,SAASF,UAE/B,IAAI8oD,GAAkB7qD,KAAK8qD,uBAAuBzoD,GAC9CipD,EAAiBT,EAAgBxoD,EAErCrC,MAAKusD,iBAAiBlqD,EAAS+d,EAAMZ,EAAU8rC,EAAgBgB,GAEzC,gBAAXjqD,IACPrC,KAAKwsD,wBAAwBnqD,EAAS+d,EAAMZ,EAAU8rC,EAAgBgB,GAW9E,QAAS9/C,GAAgBnK,EAAS+d,EAAMZ,GACpCxf,KAAKoW,YAAY/T,EAAS+d,EAAMZ,GAAU,GAe9C,QAASgtC,GAAwBnqD,EAAS+d,EAAMZ,EAAUitC,EAAsBH,GAC5EpsD,EAAEqB,QAAQvB,KAAK8pD,2BACX,SAAS4C,GACL,GAAIxB,GAAUwB,EAAmBxB,OACjC,IAAIA,EAAQtvC,KAAKvZ,GAAU,CACvB,GAAIoqD,EACA,GAAIC,GAAqBA,EAAmBpQ,OAAO,SAAS55B,GACxD,GAAIsH,GAAQwhC,EAAmB/rD,KAAKO,KAAMysD,EAAsB/pC,EAChE,OAAgB,IAATsH,GAGfhqB,MAAKusD,iBAAiBlqD,EAAS+d,EAAMZ,EAAUktC,EAAoBJ,KAG7EtsD,MAeN,QAASusD,GAAiBlqD,EAAS+d,EAAMZ,EAAU8rC,EAAgBgB,GAC3DhB,GAAkBA,EAAe5rD,SAIjC4rD,EAAiBA,EAAel5C,QAEhCk5C,EAAepmD,QAAQ,SAASwd,GAC5B1iB,KAAK2sD,gBAAgBjqC,EAAYrgB,EAAS+d,EAAMZ,EAAU8sC,IAC3DtsD,OAKX,QAAS2sD,GAAgBjqC,EAAYrgB,EAAS+d,EAAMZ,EAAU8sC,GAC1D,GAAIM,GAAiBlqC,EAAW3E,SAAW2E,EAAW3E,QAAQusC,KACxDuC,EAAWP,GAAgBM,KAAmB,GACnCA,EAEbxC,EAAgB1nC,EAAW3E,SAAW2E,EAAW3E,QAAQqsC,aAC7D,IAAIA,EACA,GAAqB,GAAjBA,EAAoB,CACpB,GAAI/nC,GAAWK,EAAWoqC,UAC1B9sD,MAAK22B,IAAItU,EAAUK,OACZ0nC,GAAgB,GACvB1nC,EAAW3E,QAAQqsC,eAGvByC,GACAnqC,EAAWA,WAAWjjB,KAAKijB,EAAWI,QAASzgB,EAAS+d,EAAMZ,GAE9Dtf,EAAEmQ,YAAYqS,EAAWA,WAAY,OAAQA,EAAWI,QAASzgB,EAAS+d,EAAMZ,GAgBxF,QAASutC,GAAe1qD,EAAS2qD,GAC7BlrD,EAAMO,EAASL,EAAMqC,MAAMnC,OAAQuoD,QAEnC,IAAII,GAAkB7qD,KAAK8qD,uBAAuBzoD,GAC9CipD,EAAiBT,EAAgBxoD,MACRg8B,OAAOwsB,EAAgBxoD,MAgBpD,OAZI2qD,MAA8B,GAA2B,gBAAX3qD,IAC9CnC,EAAEqB,QAAQvB,KAAK8pD,2BACX,SAAS4C,GACL,GAAIxB,GAAUwB,EAAmBxB,OAC7BwB,IAAsBA,EAAmBhtD,QAClCwrD,EAAQtvC,KAAKvZ,IACpBnC,EAAEmT,YAAYi4C,EAAgBoB,KAMvCpB,EAAe5rD,OACR4rD,EACAtjD,OAYlB,QAAS8iD,GAAuBzoD,GAC5B,MAAOA,aAAmBooD,QACZzqD,KAAK8pD,2BACL9pD,KAAK6pD,oBAYvB,QAASnmC,GAAkBC,GACvB7hB,EAAM6hB,EAAe5V,GAErB7N,EAAEwB,eAAe1B,KAAM,iBAAkB2jB,GACzCA,EAAczH,UAAYlc,KAU9B,QAAS4jB,KACL,MAAO5jB,MAAKmrD,eArpBhB,GAAIjnD,GAAQ9E,EAAQ,qBAEd2O,EAAgB3O,EAAQ,cACxBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MAuBhB0U,GAtBmBtX,EAAQ,iBAAiBsX,UAsBhCxW,EAAEwD,eAAeQ,EAAO,cAEpC0mD,EAAsBl0C,EAAUk0C,oBAAsB,iBA2B1D1qD,GAAEM,YAAYkW,GACVrW,KAAMA,EACNiK,QAASy/C,EACTnnC,GAAIqnC,EACJve,KAAMye,EACN8C,SAAU5C,EACVjjC,OAAQmjC,EACR2C,QAAS1C,EACT2C,UAAWlD,EACXtzB,IAAKg1B,EACLyB,WAAYzB,EACZr3B,WAAYA,EACZ23B,YAAaA,EACbjC,OAAQmC,EACR/1C,YAAaA,EACb5J,gBAAiBA,EACjBugD,eAAgBA,EAChBnpC,iBAAkBA,EAClBknC,uBAAwBA,EACxBG,oBAAqBA,EACrBY,kBAAmBA,EACnBE,sBAAuBA,EACvBS,wBAAyBA,EACzBD,iBAAkBA,EAClBI,gBAAiBA,EACjBjpC,kBAAmBA,IAQvBhN,EAAUC,gBACNiM,GAAI,KACJwE,OAAQ,SACRskB,KAAM,OACNuhB,SAAU,WACVt2B,IAAK,MACLrC,WAAY,aACZ23B,YAAa,cACb71C,YAAa,cACb5J,gBAAiB,kBACjBugD,eAAgB,kBAIpBntD,EAAOJ,QAAUkX,EAGjBA,EAAU22C,mBA6iBPC,oBAAoB,EAAExpD,gBAAgB,GAAGC,gBAAgB,GAAGwpD,aAAa,GAAG9sD,YAAY,MAAM+sD,IAAI,SAASpuD,EAAQQ,GACtH,YAuBA,SAASqO,KACDjO,KAAKK,MACLL,KAAKK,KAAKC,MAAMN,KAAMO,WAoC9B,QAASF,KACLH,EAAEwB,eAAe1B,KAAM,wBAO3B,QAASytD,MAaT,QAASC,GAAmBrrD,GACxB,GAAIsrD,GACE/oB,EAAgB5kC,KAAKykC,yBAAyBpiC,EAEpD,IAA4B,mBAAjBuiC,GAEX,MAAI5kC,MAAK4tD,kBAAkBpqD,eAAeohC,IACtC+oB,EAAe3tD,KAAK4tD,kBAAkBhpB,QACD,IAAjC+oB,EAAatpC,QAAQhiB,GACrBsrD,EAAal+C,KAAKpN,GAElBC,EAAOoQ,KAAK,0DAA4DrQ,MAE5EsrD,EAAe3tD,KAAK4tD,kBAAkBhpB,MACtC+oB,EAAal+C,KAAKpN,GACXuiC,GAaf,QAASipB,GAAsBxrD,GAqB3B,QAASyrD,KACLxrD,EAAOoQ,KAAK,6DAA+DrQ,EAC5D,+CAtBnB,GAAIuiC,GAAgB5kC,KAAKykC,yBAAyBpiC,EAElD,IAA4B,mBAAjBuiC,GAAX,CAEA,GAAI+oB,GAAe3tD,KAAK4tD,kBAAkBhpB,EAE1C,IAAI+oB,GAAgBA,EAAajuD,OAAQ,CACrC,GAAIquD,GAAeJ,EAAatpC,QAAQhiB,EACxC,IAAI0rD,GAAgB,GAEhB,GADAJ,EAAaliC,OAAOsiC,EAAc,GACP,GAAvBJ,EAAajuD,OAEb,aADOM,MAAK4tD,kBAAkBhpB,GACvBA,MAGXkpB,SAEJA,MAkBR,QAASE,GAAoBppB,GACzB,MAAO5kC,MAAK4tD,kBAAkBhpB,GAWlC,QAASH,GAAyBpiC,GAC9B,MAAOA,GAcX,QAASwiC,GAAmBD,EAAeviC,EAAS4rD,GAChD,MAAOA,GAcX,QAAStpB,KACL,OAAO,EA3LX,GAAIzkC,GAAId,EAAQ,aACVkD,EAASlD,EAAQ,iBAGvBQ,GAAOJ,QAAUyO,EAqCjB/N,EAAEM,YAAYyN,GACV5N,KAAMA,EACNiK,QAASmjD,EACTC,mBAAoBA,EACpBG,sBAAuBA,EACvBG,oBAAqBA,EAGrBvpB,yBAA0BA,EAC1BI,mBAAoBA,EACpBF,oBAAqBA,MA2ItBhzB,iBAAiB,IAAIlR,YAAY,MAAMytD,IAAI,SAAS9uD,EAAQQ,GAC/D,YA2BA,SAASS,KACL4N,EAAa7L,UAAU/B,KAAKC,MAAMN,KAAMO,WACxCL,EAAEuB,iBAAiBzB,MACfmuD,8BAEJnuD,KAAKouD,qBAAsB,EAW/B,QAASV,KACL,GAAI9oB,GAAgB32B,EAAa7L,UAAUsrD,mBAAmBptD,MAAMN,KAAMO,UAG1E,IAAIqkC,GAAiBA,YAAyB6lB,QAAQ,CAGlD,GAFAzqD,KAAK4tD,kBAAkBhpB,GAAesmB,QAAUtmB,EAChD5kC,KAAKmuD,yBAAyBvpB,GAAiB5kC,KAAK4tD,kBAAkBhpB,GAClE5kC,KAAKouD,oBAAqB,MAE9B,OADIpuD,MAAKouD,qBAAsB,EACxB,KAGX,MAAOxpB,GAWX,QAASipB,KACL,GAAIjpB,GAAgB32B,EAAa7L,UAAUyrD,sBAAsBvtD,MAAMN,KAAMO,UAE7E,IAAIqkC,GAAiBA,YAAyB6lB,QAAQ,OAC3CzqD,MAAKmuD,yBAAyBvpB,EACrC,IAAIypB,IAA8B7sD,OAAO+V,KAAKvX,KAAKmuD,0BAA0BzuD,MAC7E,IAAI2uD,EAEA,MADAruD,MAAKouD,qBAAsB,EACpB,KAIf,MAAOxpB,GAYX,QAASopB,GAAoBppB,GACzB,GAAI0pB,GAAmBrgD,EAAa7L,UAAU4rD,oBAAoB1tD,MAAMN,KAAMO,UAG9E,IAA4B,gBAAjBqkC,GAA2B,CAClC0pB,EAAmBA,KACnB,IAAIC,GAAuBruD,EAAE+nC,OAAOqmB,GAAkB,EAEtDpuD,GAAEqB,QAAQvB,KAAKmuD,yBAA0B,SAASK,GAC9C,GAAIC,GAAgBD,EAAgBtD,OAEhCuD,GAAc7yC,KAAKgpB,IACnB4pB,EAAgBtpD,QAAQ,SAAS7C,GACzBksD,EAAqBlsD,KACzBisD,EAAiB7+C,KAAKpN,GACtBksD,EAAqBlsD,IAAW,OAKhD,MAAOisD,GA5GX,GAAIrgD,GAAe7O,EAAQ,WACrBc,EAAId,EAAQ,aAObsvD,EAAqBxuD,EAAEwD,eAAeuK,EAAc,qBAExDrO,GAAOJ,QAAUkvD,EAGlBxuD,EAAEM,YAAYkuD,GACVruD,KAAMA,EACNqtD,mBAAoBA,EACpBG,sBAAuBA,EACvBG,oBAAqBA,MA8FtBW,UAAU,GAAGluD,YAAY,MAAMmuD,IAAI,SAASxvD,EAAQQ,GACvD,YA+DA,SAASS,GAAK8D,EAAYC,EAAcyqD,GACpC7uD,KAAK8uD,qBAAqBD,GAO9B,QAASE,KACD/uD,KAAK6uD,cACL7uD,KAAK6uD,aAAavkD,UAU1B,QAAS0kD,GAAa9yC,GAClBhc,EAAEwB,eAAe1B,KAAM,YAAakc,GAWxC,QAAS4yC,GAAqBD,GAC1B/sD,EAAM+sD,EAAc7sD,EAAMC,SAASgM,IAE7B4gD,IACFA,EAAe,GAAI5gD,IAEvB/N,EAAEwB,eAAe1B,KAAM,eAAgB6uD,GAY3C,QAASzD,GAAkB/oD,GACvB,GAAI4sD,GAAmBjvD,KAAK6uD,aAAanB,mBAAmBrrD,EAC7B,oBAApB4sD,IACPjvD,KAAKynC,oBAAoBwnB,GAYjC,QAASjD,GAAoB3pD,GACzB,GAAI6sD,GAAuBlvD,KAAK6uD,aAAahB,sBAAsBxrD,EAChC,oBAAxB6sD,IACPlvD,KAAK2nC,uBAAuBunB,GAcpC,QAASprC,GAAgB8gB,EAAeqpB,GACpC,GAAIkB,GAAMnvD,KAAK6uD,aACTP,EAAmBa,EAAInB,oBAAoBppB,EAE7C0pB,IACAA,EAAiBppD,QAAQ,SAAU7C,GAC/B,GAAIyiC,GAAeqqB,EAAItqB,mBAAmBD,EAAeviC,EAAS4rD,GAE9DmB,EAAiBD,EAAIxqB,oBAAoBC,EAAeviC,EAASyiC,EACjEsqB,IACApvD,KAAKoW,YAAY/T,EAASyiC,IAE/B9kC,MAUX,QAASoW,GAAY/T,EAAS+d,GAC1BpgB,KAAKkc,UAAU9F,YAAY/T,EAAS+d,GAtKxC,GAAIlc,GAAQ9E,EAAQ,qBACd6O,EAAe7O,EAAQ,WAEvBiL,GADSjL,EAAQ,kBACCA,EAAQ,iBAAiBiL,iBAC3CnK,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MAQhB+L,EAAgB7N,EAAEwD,eAAeQ,EAAO,iBAAiB,EAE7DtE,GAAOJ,QAAUuO,EAkBjB7N,EAAEM,YAAYuN,GACV1N,KAAMA,EACNiK,QAASykD,EACTC,aAAcA,EACd5D,kBAAmBA,EACnBY,oBAAqBA,EACrBloC,gBAAiBA,EACjB1N,YAAaA,EACb04C,qBAAsBA,EAGtB5gC,QAAS7jB,EACTo9B,oBAAqBp9B,EACrBs9B,uBAAwBt9B,MA0HzBijD,oBAAoB,EAAExpD,gBAAgB,GAAGC,gBAAgB,GAAG4N,iBAAiB,IAAIg9C,UAAU,GAAGluD,YAAY,MAAM4uD,IAAI,SAASjwD,EAAQQ,GACxI,YAgCA,SAASS,GAAK8D,EAAYC,EAAcyqD,EAAcS,GAClDvhD,EAAc3L,UAAU/B,KAAKC,MAAMN,KAAMO,WACzCP,KAAKsvD,gBAAkBA,EAS3B,QAAS7nB,GAAoB7C,GACzB5kC,KAAKsvD,gBAAgBloC,OAAOwd,GAAiB9hB,QAAS9iB,KAAM0iB,WAAY1iB,KAAK8jB,kBASjF,QAAS6jB,GAAuB/C,GAC5B5kC,KAAKsvD,gBAAgB34B,IAAIiO,GAAiB9hB,QAAS9iB,KAAM0iB,WAAY1iB,KAAK8jB,kBAU9E,QAASyrC,GAAmCltD,EAAS+d,GACjDpgB,KAAKkc,UAAU1P,gBAAgBnK,EAAS+d,GA9D5C,GAAIrS,GAAgB3O,EAAQ,cACtBc,EAAId,EAAQ,aAOd4O,GANU5O,EAAQ,iBAMOc,EAAEwD,eAAeqK,EAAe,0BAE7DnO,GAAOJ,QAAUwO,EAMjB9N,EAAEM,YAAYwN,GACV3N,KAAMA,EACNonC,oBAAqBA,EACrBE,uBAAwBA,EACxBvxB,YAAam5C,MA6CdzrD,gBAAgB,GAAGypD,aAAa,GAAG9sD,YAAY,MAAM+uD,IAAI,SAASpwD,EAAQQ,GAC7E,YA2BA,SAASwI,GAAKuI,GACVvI,EAAKC,KAAKonD,SAAS9+C,GAsDvB,QAASrG,KACLlC,EAAKsnD,KAAKplD,UACVlC,EAAKmnB,OAAOjlB,UACZlC,EAAKskC,OAAOpiC,UACZlC,EAAKC,KAAKiC,UApFd,GAAIqlD,GAAOvwD,EAAQ,aACfc,EAAId,EAAQ,YAIhBA,GAAQ,gBAGRA,EAAQ,oBAuCRc,EAAEkD,OAAOgF,GACLsO,UAAWi5C,EAAKj5C,UAChBwpB,MAAOyvB,EAAKzvB,MACZwM,OAAQijB,EAAKjjB,OACbkc,OAAQxpD,EAAQ,YAChB2L,OAAQ3L,EAAQ,YAChBswD,KAAMtwD,EAAQ,mBACdmwB,OAAQnwB,EAAQ,qBAChBW,OAAQX,EAAQ,YAChBiJ,KAAMjJ,EAAQ,UACd0O,QAAS1O,EAAQ,aACjBiK,WAAYjK,EAAQ,gBACpBud,eAAgBvd,EAAQ,wBACxBmM,UAAWnM,EAAQ,wBACnByS,QAASzS,EAAQ,aACjBwwD,SAAUxwD,EAAQ,cAClBo7B,aAAc,QACd5Z,qBAAsBxhB,EAAQ,iCAC9BkL,QAASA,IAKQ,gBAAV1K,IAAsBA,EAAOJ,UACpCI,EAAOJ,QAAU4I,GAGA,gBAAVmnB,UACPA,OAAOnnB,KAAOA,EACdA,EAAKsnD,KAAKxhC,QAAQ,gBAWnB2hC,eAAe,EAAEC,WAAW,EAAEC,YAAY,GAAGC,YAAY,GAAGC,uBAAuB,GAAGC,uBAAuB,GAAG1G,WAAW,GAAG2G,WAAW,GAAGC,aAAa,GAAG3iD,kBAAkB,GAAG4iD,oBAAoB,GAAGC,mBAAmB,GAAGC,eAAe,GAAGC,SAAS,IAAIC,gCAAgC,GAAGC,YAAY,IAAIjwD,YAAY,MAAMkwD,IAAI,SAASvxD,EAAQQ,GAC1V,YA+BA,SAASipB,GAAmBlY,EAAMigD,GAC9B1wD,EAAEwB,eAAeiP,EAAM,wBAAyBigD,EAAM1wD,EAAEs1C,KAAOt1C,EAAE6E,MAWrE,QAASijB,GAAmBrX,GACxB,GAAIoG,GAAgBpG,EAAKkgD,qBAEzB,cADOlgD,GAAKkgD,sBACL95C,EAIX,QAAS+5C,GAAoBC,EAAUC,GACnC,GAAIj6C,GAAgBiR,EAAmB+oC,EAEvC,OADAloC,GAAmBmoC,EAAQj6C,GACpBA,EAOX,QAASyT,KACLxqB,KAAKwM,gBAAgB,eAAiBoI,aAAa,EAAO8T,aAc9D,QAASlB,GAAkBnlB,EAAS+d,EAAMZ,GACtCyxC,EAAexxD,KAAKO,KAAMogB,EAAKsI,QAASlJ,GAmB5C,QAASyxC,GAAer8C,EAAa4K,GACjC0xC,EAAOzxD,KAAKO,KAAMwf,GAAU,GAC5B2xC,EAAmB1xD,KAAKO,KACpBoxD,EACIC,EAAoBz8C,KAC5Bs8C,EAAOzxD,KAAKO,KAAMwf,GAAU,GAIhC,QAAS0xC,GAAO1xC,EAAU8xC,GACtB9xC,GAAYA,EAAS,KAAM8xC,GAC3BtxD,KAAKoW,YAAYk7C,EAAiB,kBAAoB,iBAY1D,QAASD,GAAoBz8C,GACzB,GAAI28C,GAAS38C,EAAY,GAAG28C,OACtBC,GAAa,CAEnB,IAAI58C,EAAYlV,OAAS,EACrB,IAAK,GAAIL,GAAI,EAAG2lB,EAAMpQ,EAAYlV,OAAYslB,EAAJ3lB,EAASA,IAC3CuV,EAAYvV,GAAGkyD,QAAUA,IACzBjvD,EAAOC,MAAM,+EAAgFqS,EAAYvV,GAAGkyD,OAAOtxD,KAAMsxD,EAAOtxD,MAChIuxD,GAAa,EACbD,EAAS38C,EAAYvV,GAAGkyD,OAIpC,OAAO38C,GAIX,QAASw8C,GAAmBx8C,GAcxB,QAAS68C,GAAYrxC,IACH,UAAbA,EAAK1E,KAAmBg2C,EAAcC,GAAavxC,GAIxD,QAASsxC,GAAYtxC,GACjB,GAAI2M,GAAanG,EAAUoG,gBAAgB5M,EAAK0E,MAC5C8sC,EAAoBC,EAAcC,KAAK,SAASC,GAChD,MAAIhlC,GAAWrtB,OAASqyD,EAAWryD,OAAnC,OACOsyD,EAAgBD,EAAYhlC,IAGvC,KAAI6kC,EAAJ,CAIA,GAFAK,EAAKxiD,KAAK2Q,IAEJrgB,EAAO2oD,MAAO,KAAMwJ,EAC1BC,GAAc1iD,KAAKsd,GACnBqlC,GAAY,GAIhB,QAAST,GAAYvxC,GACjB,GAAI2M,GAAanG,EAAUoG,gBAAgB5M,EAAK0E,MAC5CutC,EAAoBF,GAAiBA,EAAcL,KAAK,SAASC,GACjE,MAAIhlC,GAAWrtB,QAAUqyD,EAAWryD,QACW,SAAxCqtB,EAAWglC,EAAWryD,QAAQ2tB,OADrC,OAEO2kC,EAAgBD,EAAYhlC,IAGvC,KAAIslC,EAAJ,CACID,GAAW9vD,EAAOC,MAAM,0HAE5B,IAAIqvD,GAAoBC,EAAcC,KAAK,SAASC,GAChD,MAAIhlC,GAAWrtB,QAAUqyD,EAAWryD,OAApC,OACOsyD,EAAgBD,EAAYhlC,IAGnC6kC,KAEJC,EAAcpiD,KAAKsd,GAEnBklC,EAAKxiD,KAAK2Q,KAId,QAAS4xC,GAAgBD,EAAYxoC,GACjC,MAAOwoC,GAAWO,MAAM,SAASplC,EAAUlD,GACvC,MAAOkD,GAASM,UAAYjE,EAAUS,GAAOwD,WA7DrD,GAGM4kC,GAHFH,KACEE,KACAN,KAEAK,IAGN,KAAMt9C,EAAY1P,QAAQusD,GAC1B,MAAO7yD,GAAK,GAAIA,GAAKszD,EAAU,KAAMtzD,GAErC,MAAOqzD,GAyDX,QAASd,GAAmBv8C,GAIxB,QAAS29C,GAAcnyC,GACnB,GAAIoyC,GAAYxyD,KAAK8kB,KAAK1E,EAAK0E,KAAmB,WAAb1E,EAAK1E,MAAkC,WAAb0E,EAAK1E,KAC9D82C,KACQ,UAAbpyC,EAAK1E,KAAmB+2C,EAAgBC,GAAeF,EAAWpyC,GANvExL,EAAY1P,QAAQqtD,EAAevyD,MACnCwqB,EAAwB/qB,KAAKO,MAAM,GAUvC,QAASyyD,GAAcD,EAAWpyC,GAC9B,GAAI4J,GAAQ5J,EAAK4J,MACX2oC,EAAUvyC,EAAKwL,QAAQlsB,OACvB6+B,GAAcvU,EAAO2oC,EAE3Bp0B,GAAaA,EAAWF,OAAOje,EAAK4I,SAAS5W,MAAM4X,EAAOA,EAAQ5J,EAAKyL,aACvEhD,EAAmB2pC,EAAU/mC,QAAQ,GACrC+mC,EAAU/mC,OAAOnrB,MAAMkyD,EAAWj0B,GAItC,QAASm0B,GAAcF,EAAWpyC,GAC9B,GAAIjb,GAAaytD,EAA0BxyC,EAAK1E,KAC5CvW,IACA0jB,EAAmB2pC,EAAUrtD,IAAa,GAC1CqtD,EAAUrtD,GAAYib,EAAK4I,WAE3B1mB,EAAOC,MAAM,4BArOrB,GACMD,IADelD,EAAQ,sCACdA,EAAQ,mBACjBW,EAASX,EAAQ,aACjBwnB,EAAYxnB,EAAQ,gBACpBc,EAAId,EAAQ,YAKlBQ,GAAOJ,QAAUgoB,EAGjBtnB,EAAEkD,OAAOokB,GACLqB,mBAAoBA,EACpBb,mBAAoBA,EACpB8oC,oBAAqBA,EACrBtmC,wBAAyBA,GA8D7B,IAAIooC,IACAxmC,MAAW,MACX2+B,QAAW,MACX8H,QAAW,MACXjnC,QAAW,SAsJZknC,qCAAqC,GAAGzsD,YAAY,GAAGsL,iBAAiB,IAAIohD,eAAe,GAAGtyD,YAAY,MAAMuyD,IAAI,SAAS5zD,EAAQQ,GACxI,YAmCA,SAASsgC,GAAM9f,EAAMjc,EAAY4Z,GAK7B,GAAIqtB,GAAQ,WACR,MAAO6nB,GAAW3yD,MAAM8qC,EAAO7qC,WAenC,OAbA6qC,GAAM8nB,UAAYhzB,EAAM99B,UAExBgpC,EAAM1mC,YAAcP,EACpBinC,EAAM+nB,SAAWp1C,MAEbqtB,EAAM+nB,SAASC,YAAa,IAC5BhoB,EAAMioB,qBAENjoB,EAAMhkB,OAAO,aAAcI,IAG3BpH,IAAMgrB,EAAMgF,MAAQhwB,GAEjBgrB,EAoEX,QAASkoB,KACL,MAAOtzD,MAAKowC,MAgBhB,QAAS6iB,GAAWpmC,GAChB,MAAMA,IAIN3sB,EAAEurB,OAAOlrB,UAAW,EAAG,EAAG,KAAMP,MAGzB,IAAK+B,SAASK,UAAU0C,KAAKxE,MAAMwtB,EAAWvtB,aAP5BP,KAiB7B,QAASuzD,GAAeC,GACpBA,EAAkBA,GAAmBxzD,KAAK0E,YAC1CR,EAAM9B,UAAUkC,oBAAoB7E,KAAKO,KAAKmc,GAAqBzF,EAAUC,eAAgB68C,GAejG,QAASC,GAAepuD,EAAWC,EAAaa,GAC5CA,EAAeA,GAAgButD,EAC/BxvD,EAAMkC,QAAQ3G,KAAKygC,EAAO76B,EAAWC,EAAaa,GAUtD,QAAS/B,GAAaovD,GAClBA,EAAkBA,GAAmBxzD,KAAK0E,YAC1CR,EAAM9B,UAAUkC,oBAAoB7E,KAAKO,KAAM0zD,EAAqBF,GASxE,QAASH,KAEL,GAAIM,GAAoB,GAAIj9C,GAAU1W,KAAMgI,OAAWA,QAGnD4rD,EAA0B,GAAI5lD,GAAuBhO,KAAMgI,OAAW,GAAI6rD,GAAaF,GAIvFG,EAAoB,GAAIp9C,GAAU1W,KAAMgI,OAAW4rD,EAEvD1zD,GAAEwB,eAAe1B,KAAMmc,EAAoB23C,GAC3C5zD,EAAEwB,eAAe1B,KAAM,qBAAsB2zD,GAIjD,QAASI,KACL,MAAO/zD,MAAK0E,YAIhB,QAASsvD,KACL,GAAIl8C,GAAa1Y,EAAQ,kBACzB0Y,GAAWC,iBAAiB,QAASk8C,EAA4BC,GACjEp8C,EAAWC,iBAAiB,YAAak8C,EAA4BC,EAAwB,SAIjG,QAASD,GAA2B7yD,GAChC,GAAIgf,GAAOhf,EAAM0F,KACjB,OAAOuR,MAAKC,UAAU8H,GAI1B,QAAS8zC,GAAuBC,GAC5B,GAAI/zC,GAAO5H,EAAU27C,EACrB,OAAO,IAAIj0B,GAAM9f,GAIrB,QAASg0C,KACLp0D,KAAKmc,GAAoB7R,UACzBtK,KAAKq0D,mBAAmB/pD,UACxBtK,KAAKwgB,YAAa,EAhPtB,GAAIsN,GAAY1uB,EAAQ,YAClBk1D,EAAal1D,EAAQ,gBAErBooB,GADYpoB,EAAQ,gBACAA,EAAQ,kBAC5BsX,EAAYtX,EAAQ,gBACpB4O,EAAyB5O,EAAQ,6BACjCy0D,EAAcz0D,EAAQ,eAEtB8E,GADa9E,EAAQ,iBAAiB8gC,MAC9B9gC,EAAQ,sBAChBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAGhBoZ,GAFQ1W,EAAME,MACL5C,EAAQ,kBACLA,EAAQ,sBAG1BQ,GAAOJ,QAAU0gC,EAyCjBA,EAAM99B,UAAU8wD,UAAYhzB,EAAMgzB,UAkBlChzD,EAAEM,YAAY0/B,GACVpb,KAAMmuC,EACNnsD,IAAKwsD,EACLC,eAAgBA,EAChBnvD,aAAcA,EACdivD,mBAAoBA,EACpBU,eAAgBA,EAChBzpD,QAAS8pD,IAIbl0D,EAAEM,YAAY0/B,EAAOo0B,EAAWC,cAOhCr0D,EAAEkD,OAAO88B,GACLs0B,KAAM1mC,EACN2mC,uBAAwBT,EACxB5tD,QAASqtD,GAOb,IAAIt3C,GAAqB,YACzBzF,GAAUtQ,QAAQ85B,EAAO/jB,EAAoBzF,EAAUC,iBAMtD,MAAO,OAAQ,MAAO,UAAW,SAASzR,QAAQ,SAASC,GACxD,GAAIP,GAASkpB,EAAU1rB,UAAU+C,EACjCjF,GAAEwB,eAAew+B,EAAM99B,UAAW+C,EAAYP,IAmDlD,IAAI8uD,IAAuB,OAAQ,MAAO,MAAO,MAAO,SAAU,MAAO,OAAQ,MAAO,UAAW,WAgFhGpG,oBAAoB,EAAEr2C,eAAe,GAAGy9C,4BAA4B,GAAG5wD,gBAAgB,GAAGC,gBAAgB,GAAG6d,qBAAqB,IAAIjQ,iBAAiB,IAAIkQ,kBAAkB,IAAI8yC,gBAAgB,GAAGC,cAAc,GAAGC,WAAW,GAAG9B,eAAe,GAAG+B,eAAe,GAAGr0D,YAAY,MAAMs0D,IAAI,SAAS31D,EAAQQ,GACjT,YAgCA,SAAS6kC,GAAyB5X,GAC9B,MAAIA,aAAsB49B,QAAe59B,EAElCjG,EAAUouC,gBAAgBnoC,GAjCrC,GAAI6hC,GAAqBtvD,EAAQ,yBAC3BwnB,EAAYxnB,EAAQ,gBACpBc,EAAId,EAAQ,aAMdy0D,EAAc3zD,EAAEwD,eAAegrD,EAAoB,cAEvD9uD,GAAOJ,QAAUq0D,EAQjB3zD,EAAEM,YAAYqzD,GACVpvB,yBAA0BA,MAiB3BwwB,wBAAwB,GAAGlC,eAAe,GAAGtyD,YAAY,MAAMy0D,IAAI,SAAS91D,EAAQQ,GACvF,YA6BA,SAASkuB,GAAUsd,EAAOtmB,GAEtBhjB,EAAMgjB,EAAM5iB,OAMZ,IAAIswD,GAAY,WACZ,MAAO2C,GAAe70D,MAAMkyD,EAAWjyD,WAE3CiyD,GAAUU,UAAYplC,EAAU1rB,UAGhClC,EAAEuB,iBAAiB+wD,GACf4C,OAAQhqB,EACRlkB,MAAOpC,EACPuwC,MAAOn1D,EAAEkS,MAAM7R,UAAW,GAC1B4yD,SAAU/nB,EAAM+nB,UAIpB,IAAIpmC,GAAanG,EAAUoG,gBAAgBlI,EAG3C5kB,GAAEwB,eAAe8wD,EAAW,cAAe8C,EAAsBvoC,EAAYylC,EAAU6C,QAEnF7C,EAAUW,SAASC,YAAa,IAEhCZ,EAAU+C,oBAEV/C,EAAUprC,OAAO,aAAcI,GAInC,IAAIguC,GAAUlB,EAAWxvC,EAAMiI,EAO/B,OAJA7sB,GAAEuB,iBAAiB+wD,EAAWgD,GAE9Bh0D,OAAOi0D,OAAOjD,GAEPA,EAaX,QAAS8C,GAAsBvoC,EAAY5a,GACvC,MAAO4a,GAAW2oC,OAAO,SAASC,EAAeC,GAC7C,GAAI30B,GAAc20B,EAAS30B,WAC3B,OAAO00B,IACE10B,EACyB,SAAnB20B,EAASvoC,OACN,IAAMlb,EAAK8uB,GAAe,IAC1B,IAAM9uB,EAAK8uB,GACf20B,EAASpoC,WACxB,IAqDP,QAAS2nC,GAAetoC,GACpB,IAAMA,EAAY,MAAO7sB,KAEzB,IAAI61D,GAAoB71D,KAAKq1D,MAAM31D,OAAS,CAExCm2D,GAAoB,IACpBhpC,EAAaA,EAAWrkB,QAAQ,iBAAkB,SAASstD,GACvD,MAAO,MAAQA,EAAI1jD,MAAM,GAAKyjD,KAItC,IAAIE,GAAU/1D,KAAKknB,MAAQ2F,EAIvB1a,GAAQnS,KAAKo1D,OAAQW,GACZ13B,OAAOr+B,KAAKq1D,MAAMjjD,MAAM,IACxBisB,OAAOn+B,EAAEkS,MAAM7R,UAAW,GAGvC,OAAOL,GAAEqT,SAASua,EAAW3b,GAUjC,QAAS6jD,KACL,MAAOh2D,MAAK8kB,KAAK,WAAWhe,OAAS,EAWzC,QAASmvD,KACL,GAAIv2D,GAASM,KAAKglB,MACdkxC,EAAYx2D,EAASa,UAAUb,MAKnC,OAHAQ,GAAEurB,OAAOlrB,UAAW,EAAG,EAAGb,EAAQ,GAClCM,KAAKyrB,OAAOnrB,MAAMN,KAAMO,WAEjB21D,EAUX,QAASC,KACL,MAAOn2D,MAAKyrB,OAAOzrB,KAAKglB,MAAQ,EAAG,GAAG,GAW1C,QAASoxC,KACL,GAAI12D,GAASM,KAAKglB,KAMlB,OALAtlB,IAAUa,UAAUb,OAEpBQ,EAAEurB,OAAOlrB,UAAW,EAAG,EAAG,EAAG,GAC7BP,KAAKyrB,OAAOnrB,MAAMN,KAAMO,WAEjBb,EAUX,QAAS22D,KACL,MAAOr2D,MAAKyrB,OAAO,EAAG,GAAG,GAQ7B,QAAS8pC,KACL,GAAIe,GAAW,GAAIC,GAAgBv2D,KAAKw2D,aAGpCC,EAAqB,GAAIzoD,GAAuBhO,KAAMgI,OAAWsuD,EAAUt2D,KAAKo1D,QAIhFsB,EAAiB,GAAIhgD,GAAU1W,KAAMgI,OAAWyuD,EAGpDv2D,GAAEwB,eAAe1B,KAAMmc,EAAoBu6C,GAS/C,QAASC,KACL,OACIvrB,MAAOprC,KAAKo1D,OACZtwC,KAAM9kB,KAAKknB,MACX/U,KAAMnS,KAAKq1D,OAYnB,QAASuB,GAAsBC,GAC3B/0D,EAAM+0D,GACFzrB,MAAOrpC,SACP+iB,KAAM5iB,OACNiQ,KAAMnN,OAGV,IAAIi7B,GAAI42B,EAAWzrB,KAEnB,OAAOnL,GAAE3/B,MAAM2/B,EAAG42B,EAAW1kD,MAIjC,QAAS2kD,KACL92D,KAAKmc,GAAoB7R,UAnS7B,CAAA,GAAIgqD,GAAal1D,EAAQ,gBACnBwnB,EAAYxnB,EAAQ,gBACpBooB,EAAoBpoB,EAAQ,iBAC5BsX,EAAYtX,EAAQ,gBACpBm3D,EAAkBn3D,EAAQ,kBAC1B4O,EAAyB5O,EAAQ,6BACjCc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,gBACR0C,GAAME,MAGpBpC,EAAOJ,QAAUsuB,EA6DjBA,EAAU1rB,UAAU8wD,UAAYplC,EAAUolC,UAoC1ChzD,EAAEM,YAAYstB,GACVhJ,KAAMqwC,EACNnwC,IAAKgxC,EACLvmD,KAAMwmD,EACNc,IAAKZ,EACLa,QAASZ,EACTzmD,MAAO0mD,EACPd,kBAAmBA,EACnBoB,eAAgBA,EAChBrsD,QAASwsD,IAIb52D,EAAEkD,OAAO0qB,GACL8oC,sBAAuBA,GAO3B,IAAIz6C,GAAqB,YACzBzF,GAAUtQ,QAAQ0nB,EAAW3R,EAAoBzF,EAAUC,kBAoKxDM,eAAe,GAAGy9C,4BAA4B,GAAG5wD,gBAAgB,GAAG6wD,gBAAgB,GAAGsC,iBAAiB,GAAGlE,eAAe,GAAG+B,eAAe,GAAGr0D,YAAY,MAAMy2D,IAAI,SAAS93D,EAAQQ,GACzL,YAUA,SAASqsB,GAAqBN,EAAajsB,GACvC,MAAOisB,GAAcjsB,EACXA,EACAisB,GAAe,EACXA,EACAA,EAAcjsB,EAAS,EACnBisB,EAAcjsB,EACd,EAdtB,GAAIssB,IACAC,qBAAsBA,EAG1BrsB,GAAOJ,QAAUwsB,OAaXmrC,IAAI,SAAS/3D,EAAQQ,GAC3B,YAoCA,SAASS,GAAK+2D,GACVnpD,EAAa7L,UAAU/B,KAAKC,MAAMN,KAAMO,WACxCP,KAAKo3D,SAAWA,EAUpB,QAAS3yB,GAAyBpiC,GAG9B,MAAIA,aAAmBooD,QACZpoD,EACI,eAAXA,EACOA,EAEJrC,KAAKo3D,SAAW/0D,EAa3B,QAASwiC,GAAmBD,EAAeviC,EAAS4rD,GAEhD,GAAe,eAAX5rD,EAA0B,CAC1B,GAAIg1D,GAAkBpJ,EAAWvlC,QAC5BzX,IAAIqmD,EAAoBt3D,MACxBs8C,OAAO,SAASh0B,GAAU,MAAOA,KAClCwc,GACApc,QAAS2uC,EACTziD,YAAaq5C,EAAWr5C,YAG5B,OAAOkwB,GAGX,GAAIA,GAAewyB,EAAmB73D,KAAKO,KAAMiuD,EACjD,OAAOnpB,GAIX,QAASwyB,GAAmBhvC,GACxB,GAAIivC,GAAWjvC,EAAOxD,KAChBA,EAAO5kB,EAAEs3D,SAASD,EAAUv3D,KAAKo3D,SAEvC,IAAmB,gBAARtyC,GAAkB,CACzB,GAAIwD,GAASpoB,EAAEiD,MAAMmlB,EAGrB,OAFAA,GAAOivC,SAAWA,EAClBjvC,EAAOxD,KAAOA,EACPwD,GA9Ff,GAAIra,GAAe7O,EAAQ,sBAGrBc,GAFYd,EAAQ,gBACXA,EAAQ,kBACbA,EAAQ,cAMdm3D,EAAkBr2D,EAAEwD,eAAeuK,EAAc,kBAErDrO,GAAOJ,QAAU+2D,EAUjBr2D,EAAEM,YAAY+1D,GACVl2D,KAAMA,EACNokC,yBAA0BA,EAC1BI,mBAAoBA,MA0ErB4yB,qBAAqB,GAAG9lD,iBAAiB,IAAIohD,eAAe,GAAGtyD,YAAY,MAAMi3D,IAAI,SAASt4D,EAAQQ,GACzG,YAqDA,SAASotB,GAAgBlI,EAAM6yC,GAC3BA,EAAmBA,GAAoBC,CAEvC,IAAI7qC,KAEJ,KAAMjI,EACF,MAAOiI,EAEX,IAAI8qC,GAAW/yC,EAAKtc,QAAQmvD,EAAkB,SAASG,GACnD,GAAI5qC,IAAaM,SAAUsqC,EAM3B,OALA53D,GAAEkD,OAAO8pB,EAAU6qC,EAAcD,EAAQ,KACvB,KAAdA,EAAQ,KACR5qC,EAAS+T,YAAc7T,EAAeF,GAAU,IAEpDH,EAAWtd,KAAKyd,GACT,IAEX,IAAI2qC,EACA,KAAM,IAAIG,GAAW,yBAA2BlzC,EAEpD,OAAOiI,GAUX,QAASioC,GAAgBlwC,GAGrB,GAFAhjB,EAAMgjB,EAAM9iB,EAAMqC,MAAMnC,OAAQuoD,SAE5B3lC,YAAgB2lC,SAA+B,IAArB3lC,EAAKT,QAAQ,KACvC,MAAOS,EAEX,IAAIiI,GAAanG,EAAUoG,gBAAgBlI,EAAMmzC,GAC3CC,EAAW,IAEXC,GAAkB,CAExBprC,GAAW7nB,QAAQ,SAASgoB,GACxB,GAAI1nB,GAAO0nB,EAASM,SACd4qC,EAAQC,EAAU7yD,EAEpB4yD,IAGAF,GAAY,IAAME,EAAQ,KAE1BD,GAAkB,GAIlBD,GAAY1yD,EAAKgD,QAAQ,cAAe,UAIhD0vD,GAAgC,GAEhC,KACI,MAAO,IAAIzN,QAAOyN,GACpB,MAAOt5D,GACL,KAAM,IAAIo5D,GAAW,2CAA8ClzC,IAK3E,QAASsI,GAAeF,EAAUorC,GAC9B,GAAI9yD,GAAO0nB,EAASM,SACd+qC,EAAaD,EAAe,EAAI,CACtC,OAA0B,SAAnBprC,EAASG,OACV7nB,EAAK4M,MAAMmmD,EAAY/yD,EAAK9F,OAAS,GACrC8F,EAAK4M,MAAMmmD,GAKrB,QAAS1xC,GAAqB2xC,GAC1BA,EAAeA,IAAiB,KAAM,MACtC,IAAIC,GAAiBv4D,EAAE6kD,YAAYyT,EAAc,SAASrzD,GACtD,GAAIuzD,GAAa14D,KAAKmF,EAEtB,OAAO,UAAS2f,EAAMpC,GAClB,GAAIi2C,GAAY3D,EAAgBlwC,EAChC4zC,GAAWj5D,KAAKO,KAAM24D,EAAWj2C,KAEtC1iB,KACHE,GAAEuB,iBAAiBzB,KAAMy4D,GAxI7B,GAAI32D,GAAQ1C,EAAQ,iBACd4C,EAAQF,EAAME,MACd9B,EAAId,EAAQ,aACZ44D,EAAa54D,EAAQ,iBAAiB8gC,MAExCtZ,GACAoG,gBAAiBA,EACjBgoC,gBAAiBA,EACjB5nC,eAAgBA,EAChBvG,qBAAsBA,EAG1BjnB,GAAOJ,QAAUonB,CAGjB,IAAIgyC,GAAqB,8BACnBC,EAAkB,eAClBC,EAAsB,iBACtBC,EAA4B,MAAQD,EACpCE,EAAyB,MAAQF,EAAsB,MAEvDG,EAAqB,SACrBC,EAAkB,YAClBC,EAAa,MAEbC,GACsBR,EACAC,EACAE,EACAC,GACFvwD,KAAK,KACzBmvD,EAAmB,GAAInN,QAAO2O,EAAiB,KAE/CC,GAC8BD,EACAH,EACAC,EACAC,GACF1wD,KAAK,KACjCwvD,EAA0B,GAAIxN,QAAO4O,EAAwB,KAG7DtB,GACEuB,KAAOjsC,OAAQ,SAAUoI,MAAO,MAChC8jC,KAAOlsC,OAAQ,QAASoI,MAAO,MAC/B+jC,KAAOnsC,OAAQ,QAASoI,MAAO,OA2BnC4iC,GACAoB,KAAMb,EACNc,MAAOb,EAEXR,GAAU,KAAOA,EAAU,MAAQ,IAAMA,EAAU,SA+DhDv0D,gBAAgB,GAAGC,gBAAgB,GAAGtD,YAAY,MAAMk5D,IAAI,SAASv6D,QAAQQ,OAAOJ,SACvF,YAsEA,SAASo6D,wBAAuB90C,EAAMiI,GAClC,GAAIyoC,GAAUt1D,EAAE6c,QAAQ88C,aAAc,SAASC,GAC3C,MAAOC,aAAYD,EAAUh1C,EAAMiI,IAEvC,OAAOyoC,GAOX,QAASuE,aAAYC,YAAal1C,KAAMiI,YAiBpC,QAASktC,kBAAiB53C,EAAU63C,EAAchkD,GAC9CmM,EAAS5S,KAAKyG,GACdgkD,EAAahkD,EAAI4O,MAAQ5O,EAG7B,QAASikD,wBAAuB93C,EAAU63C,EAAc9C,EAAUruC,EAAUC,GACxE,GAAIoxC,GAAYC,YAAYtxC,GACtBuxC,EAAYD,YAAYrxC,EAE1BsxC,IACAC,YAAYl4C,EAAU63C,EAAc9C,EAAUpuC,EAAU,QAAS,YAEjEoxC,GACAG,YAAYl4C,EAAU63C,EAAc9C,EAAUruC,EAAU,UAAW,YAG3E,QAASwxC,aAAYl4C,EAAU63C,EAAc9C,EAAU/tB,EAAKxhB,EAAS2yC,GAIjE,QAASC,GAAarD,EAAU/tB,GAC5B,GAAIrkC,MAAMC,QAAQokC,GAAM,CACpB,GAAI/f,GAAa8tC,EAAW,MAC5B/tB,GAAInkC,QAAQ,SAAS9D,EAAO4oB,GACxB0wC,EAAWt5D,EAAO4oB,EAAOV,SAE1B,CACH,GAAIA,GAAa8tC,EAAW,KAC5Bl3D,GAAEqB,QAAQ8nC,EAAK,SAASjoC,EAAOioB,GAC3BqxC,EAAWt5D,EAAOioB,EAAKC,MAKnC,QAASoxC,GAAWt5D,EAAOioB,EAAKC,GAC5B,GAAIxE,GAAOwE,EAAW9gB,QAAQ,KAAM6gB,GAC9BsxC,EAAcT,EAAap1C,EAEjC,IAAI61C,EACIA,EAAYj/C,MAAQmM,EACpBvlB,OAAOC,MAAM,4DAEbo4D,EAAYj/C,KAAO,UACnBi/C,EAAYH,GAAap5D,OAE1B,CACH,GAAI8U,IAAQ4O,KAAMA,EAAMpJ,KAAMmM,EAC9B3R,GAAIskD,GAAap5D,EACjB64D,iBAAiB53C,EAAU63C,EAAchkD,GAGzCmkD,YAAYj5D,IACZq5D,EAAa31C,EAAM1jB,GAnC3Bq5D,EAAarD,EAAU/tB,GAuC3B,QAASuxB,WAAUx5D,GACf,MAAOy5D,qBAAoBz5D,GACjBlB,EAAEmgC,UAAUj/B,GACZA,EAGd,QAAS05D,cAAa15D,GAClB,MAASy5D,qBAAoBz5D,GAEnB4D,MAAMC,QAAQ7D,GACVA,EAAMgR,QACN5Q,OAAOgK,OAAOpK,GAHlBA,EAMd,QAASi5D,aAAYj5D,GACjB,MAAOy5D,qBAAoBz5D,IAChBI,OAAO+V,KAAKnW,GAAO1B,OAGlC,QAASm7D,qBAAoBz5D,GACzB,QAAgB,MAATA,GACoB,gBAATA,IACJA,YAAiBy/C,OACjBz/C,YAAiBqpD,SAGnC,QAASsQ,sBAAqB7kD,EAAK8kD,EAASC,GACxC/6D,EAAEuB,iBAAiByU,GACfglD,WAAYF,EACZG,SAAUF,IArGlB,GAAIr2D,QACEw2D,WAAapB,aACXjtC,WAAYA,WACZK,eAAgBxG,UAAUwG,gBAGlC,KACIiuC,KAAKD,YACP,MAAOx8D,GACL,KAAMo5D,YAAW,6CAA+ClzC,KAAO,WAAas2C,YAGxF,MAAOx2D,QA5FX,GAAIgiB,WAAYxnB,QAAQ,iBAClB4sB,WAAa5sB,QAAQ,kBACrBkD,OAASlD,QAAQ,qBACjB0wC,UAAY1wC,QAAQ,oBACpBk8D,GAAKl8D,QAAQ,MACb4vB,IAAM5vB,QAAQ,OACdc,EAAId,QAAQ,aACZooB,kBAAoBpoB,QAAQ,kBAC5B4oB,mBAAqBR,kBAAkBQ,mBACvCwC,wBAA0BhD,kBAAkBgD,wBAM9C+wC,WACAz0D,IAAK,2XACLsD,IAAK,8+CACLmgB,IAAK,+sCACLkB,OAAQ,4qGAGR+vC,gBAAkB,khEAChBC,oBAAsB,w6EACtBC,sBAAwB,+8BAE1BC,QACAH,gBAAiBA,gBACjBC,oBAAqBA,oBACrBC,sBAAuBA,sBACvBtuC,eAAgBxG,UAAUwG,eAC1BwuC,kBAAmB,oBACnBC,qBAAsB,6CACtBC,mBAAoB,8BACpBnI,kBAAmB,kCAGnBoI,YAAc77D,EAAEy7D,QAAQx4D,QAAQC,QAChCw4D,kBAAmB,aACnBC,qBAAsB,sCACtBC,mBAAoB,uBACpBnI,kBAAmB,4BACpBzzD,IAGC87D,YAAc97D,EAAEiD,MAAM6rB,IAAIitC,iBAC9BD;YAAYE,OAAQ,CAEpB,IAAIrC,cAAe35D,EAAE6c,QAAQw+C,UAAW,SAASY,GAC7C,MAAOntC,KAAI/U,SAASkiD,EAAMH,YAAaL,UAIvCS,kBAAoBl8D,EAAE6kD,aAAa,MAAO,MAAO,UAAW,SAAS5/C,GACrE,MAAO6pB,KAAI/U,SAASshD,UAAUp2D,GAAa62D,YAAaD,eAYxDM,sBAAwBn8D,EAAEo8D,QAAQ1C,uBAAwB5xD,OAAW,KAUrEikB,qBAAuBD,WAAWC,oBAsHtCrsB,QAAOJ,QAAU68D,qBAEjB,IAAI9H,cAAer0D,EAAE6c,QAAQq/C,kBAAmB,SAASpC,GACrD,MAAOD,aAAYC,EAAa,QAGpCqC,uBAAsB9H,aAAeA,eAElC7jB,mBAAmB,GAAGpqB,oBAAoB,IAAIi2C,iBAAiB,GAAGC,iBAAiB,GAAGC,gBAAgB,GAAG9oC,IAAM,IAAI2nC,GAAK,IAAI76D,YAAY,MAAMi8D,IAAI,SAASt9D,EAAQQ,GACtK,YAQeA,GAAOJ,SAClByB,OAAQ7B,EAAQ,qCAChB05B,WAAY15B,EAAQ,2BACpBiV,SAAUjV,EAAQ,6BAGnBu9D,yBAAyB,GAAGtvD,oCAAoC,GAAGE,0BAA0B,KAAKqvD,IAAI,SAASx9D,EAAQQ,GAC1H,YAMA,IAAIM,GAAId,EAAQ,aAKZy9D,GACAC,gBAAiB,OAAQ,MAAO,QAAS,aAAc,YAAa,eACpEC,OAAQ,QAAS,oBACjBC,YAAa,QAAS,OAAQ,UAAW,YACzCC,eAAgB,UAAW,WAAa,SACxCC,YAAa,QAAS,cAAe,WAAY,YAAa,UACjD,aAAc,aAAc,YAAa,WAAY,YACrD,QACbC,YAAa,aAAc,WAAY,YAAa,aAAc,aAAc,eAKpF,IAAqB,mBAAV5tC,QACP,GAAI6tC,GAAS7tC,WAEb6tC,MACAl9D,EAAEqB,QAAQs7D,EAAY,SAASQ,EAAQC,GACnC,GAAIC,GAAmBr9D,EAAEs9D,aAAaF,EAAsB,OAAQ,aAChE,gDACJF,GAAOE,GAAwBC,GAKvC,IAAIE,KAEJv9D,GAAEqB,QAAQs7D,EAAY,SAASQ,EAAQC,GACnCD,EAAOn4D,QAAQ,SAASwW,GACpB,GAAIla,OAAOgC,eAAei6D,EAAuB/hD,GAC7C,KAAM,IAAIpc,OAAM,wBAA0Boc,EAE9C+hD,GAAsB/hD,GAAQ0hD,EAAOE,OAK7C19D,EAAOJ,QAAUi+D,IAEdh9D,YAAY,MAAMi9D,IAAI,SAASt+D,EAAQQ,GAC1C,YAmCA,SAASS,GAAK8D,EAAYC,EAAc8f,EAAqBy5C,GACzD39D,KAAK29D,aAAeA,EACpB5vD,EAAc3L,UAAU/B,KAAKC,MAAMN,KAAMO,WAI7C,QAASq9D,KACL7vD,EAAc3L,UAAUkI,QAAQhK,MAAMN,KAAMO,iBACrCP,MAAK29D,aAKhB,QAASz2B,KACL,MAAOlnC,MAAK29D,aAIhB,QAASE,GAAuBj5D,EAAQwwB,GACpC,GAAOA,GAAiC,gBAAbA,GAA3B,CACA,GAAI0oC,GAAUC,EAAkBniD,KAAKwZ,EACrCA,GAAYA,EAAU5sB,QAAQu1D,EAAmB,IACjD/9D,KAAKknC,UAAUtiC,GAAQwwB,EAAWp1B,KAAM89D,IAK5C,QAASj2B,GAAYxS,GACjB,GAAI2oC,EACiB,oBAAVzuC,UACPyuC,EAAiB3oC,EAAM4oC,YAAc1uC,OAAOwtC,MAAMmB,iBAElDF,IACA3oC,GAAS8oC,GAEbn+D,KAAK8jB,gBAAgBuR,EAAM3Z,KAAM2Z,GAIrC,QAAS+oC,GAA6B/7D,EAAS+d,GAC3CpgB,KAAKkc,UAAU1P,gBAAgBnK,EAAS+d,GAI5C,QAAS8N,GAAQkH,EAAW1E,GACxB5uB,EAAMszB,EAAWlzB,QACjBJ,EAAM4uB,EAAY1uB,EAAMC,SAAST,SAEjC4zB,EAAYA,EAAU5sB,QAAQu1D,EAAmB,GACjD,IAAIM,GAAmBZ,EAAsBroC,EAE7C,IAA+B,kBAApBipC,GACP,KAAM,IAAI/+D,OAAM,yBAGK,oBAAdoxB,KACPA,EAAWhV,KAAO0Z,EAEtB,IAAIkpC,GAAW,GAAID,GAAiBjpC,EAAW1E,GAC3C6tC,EAAev+D,KAAKknC,UAAUs3B,cAAcF,EAChD,OAAOC,GA5FX,GAAIxwD,GAAgB3O,EAAQ,yBAEtBq+D,GADYr+D,EAAQ,yBACIA,EAAQ,iBAChCc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MAEhBmlC,EAAmBjnC,EAAEwD,eAAeqK,EAAe,oBAAoB,EAG3E7N,GAAEM,YAAY2mC,GAEV9mC,KAAMA,EACNiK,QAASszD,EACTn2B,oBAAqBvnC,EAAEqkB,QAAQs5C,EAAwB,oBACvDl2B,uBAAwBznC,EAAEqkB,QAAQs5C,EAAwB,uBAC1DznD,YAAagoD,EACblwC,QAASA,EAGTgZ,QAASA,EACTW,YAAaA,IAGjBjoC,EAAOJ,QAAU2nC,CAGjB,IAAI42B,GAAoB,aAClBI,EAAoB,cAmEvBM,wBAAwB,GAAGC,wBAAwB,GAAG56D,gBAAgB,GAAG66D,eAAe,GAAGl+D,YAAY,MAAMm+D,IAAI,SAASx/D,EAAQQ,GACrI,YAgBA,IAAI8W,GAAYtX,EAAQ,mBAClBy/D,EAAaz/D,EAAQ,cACrB0/D,EAAoB1/D,EAAQ,iBAI9B0pD,GAHM1pD,EAAQ,aAGH,GAAIsX,IAEfqoD,EAAgB,GAAID,GAAkBhW,GAAY56B,QAAS,WAAa,GAAI2wC,GAEhF/V,GAASplC,kBAAkBq7C,GAG3Bn/D,EAAOJ,QAAUspD,IAEd16B,kBAAkB,GAAG4wC,aAAa,GAAGC,gBAAgB,GAAGx+D,YAAY,MAAMy+D,IAAI,SAAS9/D,EAAQQ,GAClG,YAyBA,SAAS6kC,GAAyBpiC,GAC9B,MAAe,YAAXA,EACO,mBACF88D,EAAoBvjD,KAAKvZ,GACvB,UADN,OAMT,QAASsiC,GAAoBC,EAAe/c,EAASK,GACjD,MAAqB,oBAAjB0c,GAIO,EACiB,WAAjBA,EACAw6B,EAAsBl3C,EAAQ9H,KAAK1E,MAAQmM,EAD/C,OAtCX,GAAI5Z,GAAe7O,EAAQ,yBACrBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBAIlBy/D,GAHU/8D,EAAME,MAGH9B,EAAEwD,eAAeuK,EAAc,cAAc,GAG9D/N,GAAEM,YAAYq+D,GACVp6B,yBAA0BA,EAC1BE,oBAAqBA,IAGzB/kC,EAAOJ,QAAUq/D,CAMjB,IAAIM,GAAsB,aACpBC,EAAsB,aAqBzBr6B,wBAAwB,GAAGtR,mBAAmB,GAAGhzB,YAAY,MAAM4+D,IAAI,SAASjgE,EAAQQ,GAC3F,YA4BA,SAAS6nC,GAAoB7C,GACzB,GAAI06B,EAAmB16B,GACnB,GAA2B,WAAvB53B,SAASmtB,WACTntB,SAAS06B,iBAAiB,mBAAoB1nC,MAAM,OACnD,CACD,GAAIq+D,GAAmBZ,EAAsB8B,iBACzCjB,EAAW,GAAID,GAAiB,oBAAsB9oC,OAAQvoB,UAClEhN,MAAK8jB,gBAAgB,mBAAoBw6C,OAG7Ct+D,MAAKw/D,wBAAwB,mBAAoB56B,GAIzD,QAAS+C,GAAuB/C,GACxB06B,EAAmB16B,GACnB53B,SAAS46B,oBAAoB,mBAAoB5nC,MAAM,GAEvDA,KAAKw/D,wBAAwB,sBAAuB56B,GAI5D,QAAS06B,GAAmB16B,GACxB,MAAwB,oBAAjBA,GAA0D,gBAAZ53B,UAGzD,QAASyyD,GAAgB76B,GACrB,MAAwB,WAAjBA,GAA+C,gBAAVrV,QAGhD,QAASiwC,GAAwB56D,EAAQggC,GACjC66B,EAAgB76B,IAChBrV,OAAO3qB,GAAQ,UAAW5E,MAAM,GAKxC,QAAS6nC,GAAYxS,GACjBr1B,KAAK8jB,gBAAgBuR,EAAM3Z,KAAM2Z,GAIrC,QAASnH,GAAQrG,EAASzH,GACtBA,EAAOA,MACPA,EAAK1E,KAAO,WAAamM,EAEJ,gBAAV0H,SACPA,OAAOnZ,YAAYgK,EAAM,KAzEjC,GAAIrS,GAAgB3O,EAAQ,4BACtBq+D,EAAwBr+D,EAAQ,iBAEhCc,GADyBd,EAAQ,oBAAoB0/D,kBACjD1/D,EAAQ,cACZ0C,EAAQ1C,EAAQ,oBAIlB0/D,GAHUh9D,EAAME,MAGI9B,EAAEwD,eAAeqK,EAAe,qBAAqB,GAG7E7N,GAAEM,YAAYs+D,GAEVr3B,oBAAqBA,EACrBE,uBAAwBA,EACxBzZ,QAASA,EAGTsxC,wBAAyBA,EACzB33B,YAAaA,IAIjBjoC,EAAOJ,QAAUs/D,IAqDd13B,2BAA2B,GAAG3T,mBAAmB,GAAGC,mBAAmB,GAAGgsC,gBAAgB,GAAGj/D,YAAY,MAAMk/D,IAAI,SAASvgE,EAAQQ,GACvI,YAoBA,SAASggE,KACL,MAAOrwC,QAAOswC,KAAOtwC,OAAOuK,MAAQvK,OAAOuwC,UAlB/C,GAAIppD,GAAYtX,EAAQ,gBAClB+nC,EAAmB/nC,EAAQ,gBAG7B2gE,EAAgB,GAAIrpD,GACpBspD,EAAmB,GAAI74B,GAAiB44B,GAAiB7xC,QAAS,WAAalmB,OAAWunB,OAC9FwwC,GAAcr8C,kBAAkBs8C,GAGhCpgE,EAAOJ,QAAUugE,EAGjB7/D,EAAEkD,OAAO28D,GACLE,MAAOL,MAQR3oD,eAAe,GAAGipD,eAAe,KAAKC,IAAI,SAAS/gE,GACtD,YAEAA,GAAQ,6BACRA,EAAQ,yBACRA,EAAQ,2BACRA,EAAQ,wBACRA,EAAQ,0BACRA,EAAQ,yBACRA,EAAQ,6BACRA,EAAQ,4BACRA,EAAQ,8BACRA,EAAQ,0BACRA,EAAQ,6BACRA,EAAQ,wBACRA,EAAQ,4BACRA,EAAQ,wBACRA,EAAQ,wBACRA,EAAQ,yBACRA,EAAQ,8BACRA,EAAQ,6BACRA,EAAQ,yBACRA,EAAQ,8BACRA,EAAQ,4BAERA,EAAQ,wCAGLghE,4BAA4B,GAAGC,yBAAyB,GAAGC,wBAAwB,GAAGC,4BAA4B,GAAGC,uBAAuB,GAAGC,6BAA6B,GAAGC,2BAA2B,GAAGC,wBAAwB,GAAGC,4BAA4B,GAAGC,wBAAwB,GAAGC,wBAAwB,GAAGC,4BAA4B,GAAGC,uBAAuB,GAAGC,2BAA2B,GAAGC,6BAA6B,GAAGC,yBAAyB,GAAGC,6BAA6B,GAAGC,uBAAuB,GAAGC,2BAA2B,GAAGC,uBAAuB,GAAGC,0BAA0B,GAAGC,qCAAqC,KAAKC,IAAI,SAAStiE,GACzpB,YAEAA,GAAQ,6BACRA,EAAQ,8BACRA,EAAQ,+BACRA,EAAQ,gCACRA,EAAQ,iCACRA,EAAQ,kCACRA,EAAQ,mCACRA,EAAQ,oCACRA,EAAQ,8BACRA,EAAQ,8BACRA,EAAQ,8BACRA,EAAQ,8BACRA,EAAQ,oCAELuiE,kCAAkC,GAAGC,6BAA6B,GAAGC,4BAA4B,GAAGC,6BAA6B,GAAGC,6BAA6B,GAAGC,+BAA+B,GAAGC,8BAA8B,GAAGC,6BAA6B,GAAGC,6BAA6B,GAAGC,mCAAmC,GAAGC,gCAAgC,GAAGC,iCAAiC,GAAGC,iCAAiC,KAAKC,IAAI,SAASpjE,EAAQQ,GACld,YAwIA,SAASqC,GAASipD,GACdlrD,KAAKkrD,QAAUA,EAGnB,QAAS7mD,GAAMo+D,GACX,GAAsB,GAAlBA,EAAQ/iE,OACR,KAAM,IAAIJ,OAAM,kDACpBU,MAAKyiE,QAAUA,EAGnB,QAASC,GAAMC,GACX3iE,KAAK2iE,UAAYA,EAGrB,QAAShoD,GAAgBuwC,GACrBlrD,KAAKkrD,QAAUA,EAGnB,QAAS7nD,GAAW6nD,GAChBlrD,KAAKkrD,QAAUA,EAGnB,QAAS5nD,GAASs/D,EAAYC,GAC1B7iE,KAAK4iE,WAAaA,EAClB5iE,KAAK8iE,gBAAkBD,EAa3B,QAASE,GAAa3hE,EAAO8pD,GAEzB,GAAIA,IAAYlpD,EAAMgiD,IAAtB,CAKA,IAAK,GAAI3kD,GAAI,EAAGA,EAAI2jE,EAAatjE,SAAUL,EACvC,GAAI6rD,IAAY8X,EAAa3jE,GAAG,GAAI,CAChC,SAAW+B,KAAU4hE,EAAa3jE,GAAG,GACjC,MACJ,MAAM,IAAI2C,GAAM1C,MAAM,YAAc0jE,EAAa3jE,GAAG,GAAK,eACN+B,IAG3D,GAAgB,OAAZ8pD,EAAkB,CAClB,GAAc,OAAV9pD,EACA,MACJ,MAAM,IAAIY,GAAM1C,MAAM,sBAAwB+Y,KAAKC,UAAUlX,IAIjE,GAAI8pD,IAAYlpD,EAAM08B,QAAS,CAO3B,GAAqB,gBAAVt9B,KAA+B,EAARA,KAAeA,EAC7C,MACJ,MAAM,IAAIY,GAAM1C,MAAM,0BACK8B,YAAiBI,QAAS6W,KAAKC,UAAUlX,GAASA,IAGjF,GAAI8pD,IAAYlpD,EAAMuD,iBAAkB,CACpC,GAAqB,gBAAVnE,IAAsBY,EAAMuD,iBAAiBqW,KAAKxa,IACtB,IAA5B6hE,EAAY5+C,QAAQgF,GAC3B,MACJ,MAAM,IAAIrnB,GAAM1C,MAAM,oCACK8B,YAAiBI,QAAS6W,KAAKC,UAAUlX,GAASA,IAQjF,GAJI8pD,IAAY1pD,SACZ0pD,EAAUlpD,EAAM2Y,qBAGhBuwC,YAAmBlmD,OAAO,CAC1B,GAAuB,IAAnBkmD,EAAQxrD,OACR,KAAMJ,OAAM,iDACY+Y,KAAKC,UAAU4yC,GAC3C,KAAKlmD,MAAMC,QAAQ7D,GACf,KAAM,IAAIY,GAAM1C,MAAM,uBAAyB+Y,KAAKC,UAAUlX,GAalE,YAVAA,GAAM8D,QAAQ,SAAUg+D,EAAcl5C,GAClC,IACI+4C,EAAaG,EAAchY,EAAQ,IACrC,MAAOzQ,GAIL,KAHIA,aAAez4C,GAAM1C,QACrBm7C,EAAI31B,KAAOq+C,EAAan5C,EAAOywB,EAAI31B,OAEjC21B,KAQlB,GAAIyQ,YAAmBwX,GAAO,CAC1B,GAAIxX,EAAQyX,UAAUvhE,GAClB,MAEJ,MAAM,IAAIY,GAAM1C,MAAM,iCAO1B,GAHI4rD,YAAmBjpD,KACnBipD,EAAUlpD,EAAMqC,MAAM2D,OAAWkjD,EAAQA,UAEzCA,YAAmB7mD,GAAO,CAC1B,IAAK,GAAIhF,GAAI,EAAGA,EAAI6rD,EAAQuX,QAAQ/iE,SAAUL,EAC1C,IAGI,WAFA0jE,GAAa3hE,EAAO8pD,EAAQuX,QAAQpjE,IAGtC,MAAOo7C,GAGL,KAAMA,YAAez4C,GAAM1C,OACvB,KAAMm7C,GAIlB,KAAM,IAAIz4C,GAAM1C,MAAM,mDAK1B,GAAI4rD,YAAmBnpD,UAAU,CAC7B,GAAIX,YAAiB8pD,GACjB,MAEJ,MAAM,IAAIlpD,GAAM1C,MAAM,YAAc4rD,EAAQ9qD,YAAYH,MAG5D,GAAImjE,IAAqB,CAMzB,IALIlY,YAAmBvwC,KACnByoD,GAAqB,EACrBlY,EAAUA,EAAQA,SAGlBA,YAAmB7nD,GAAvB,CACI,GAAIggE,GAAanY,EAAQA,QACrBoY,GAAY,CAChB,KAAK,GAAIj6C,KAAOjoB,GACZkiE,GAAY,EACZxhE,EAAMV,EAAMioB,GAAMg6C,EAEtB,IAAIC,EACA,KAAM,IAAIthE,GAAM1C,MAAM,YAAc4rD,EAAQ9qD,YAAYH,UAIhE,IAAIirD,YAAmB5nD,GAAvB,CACI,GAAIs/D,GAAa1X,EAAQ0X,UACzB,IAAI1X,EAAQ4X,iBAAmB1hE,GAASwhE,EACpC,MACJ,MAAOxhE,EAAMgB,oBAAqBwgE,IAC9B,KAAM,IAAI5gE,GAAM1C,MAAM,YAAc4rD,EAAQ9qD,YAAYH,KAAO,OAAS2iE,EAAW3iE,UAL3F,CASA,GAAuB,gBAAZirD,GACP,KAAM5rD,OAAM,oCAKhB,IAAqB,gBAAV8B,GACP,KAAM,IAAIY,GAAM1C,MAAM,8BAAiC8B,GAC3D,IAAc,OAAVA,EACA,KAAM,IAAIY,GAAM1C,MAAM,4BAE1B,IAAIikE,MACAC,IAEJtjE,GAAEqB,QAAQ2pD,EAAS,SAASuY,EAAYp6C,GAChC6hC,EAAQ7hC,YAAgBpnB,GACxBuhE,EAAiBn6C,GAAO6hC,EAAQ7hC,GAAK6hC,QAErCqY,EAAiBl6C,GAAO6hC,EAAQ7hC,IACrCrpB,MAAM,GAETE,EAAEqB,QAAQH,EAAO,SAASsiE,EAAUr6C,GAChC,GAAIq6C,GAAWtiE,EAAMioB,EACrB,KACI,GAAIk6C,EAAiB//D,eAAe6lB,GAChC05C,EAAaW,EAAUH,EAAiBl6C,UACjCk6C,GAAiBl6C,OACrB,IAAIm6C,EAAiBhgE,eAAe6lB,GACvC05C,EAAaW,EAAUF,EAAiBn6C,QAExC,KAAK+5C,EACD,KAAM,IAAIphE,GAAM1C,MAAM,eAEhC,MAAOm7C,GAGL,KAFIA,aAAez4C,GAAM1C,QACrBm7C,EAAI31B,KAAOq+C,EAAa95C,EAAKoxB,EAAI31B,OAC/B21B,IAEXz6C,MAAM,GAETE,EAAEqB,QAAQgiE,EAAkB,SAASniE,EAAOioB,GACxC,KAAM,IAAIrnB,GAAM1C,MAAM,gBAAkB+pB,EAAM,MAC/CrpB,MAAM,KAcb,QAASmjE,GAAa95C,EAAKs6C,GAMvB,MALqB,gBAATt6C,IAAqBA,EAAI5hB,MAAM,YACvC4hB,EAAM,IAAMA,EAAM,IACZA,EAAI5hB,MAAMzF,EAAMuD,mBAAiD,IAA5B09D,EAAY5+C,QAAQgF,KAC/DA,EAAMhR,KAAKC,WAAW+Q,KAEtBs6C,GAAoB,MAAZA,EAAK,GACNt6C,EAAM,IAAMs6C,EAChBt6C,EAAMs6C,EA1TjB,GAAIzjE,GAAId,EAAQ,aACVW,EAASX,EAAQ,aAEnB0C,EAAQ,SAAUV,EAAO8pD,GACzB,GAAInrD,EAAO+B,SAAU,EAIrB,IACIihE,EAAa3hE,EAAO8pD,GACtB,MAAOzQ,GAGL,KAFKA,aAAez4C,GAAM1C,OAAUm7C,EAAI31B,OACpC21B,EAAIp4C,SAAW,aAAeo4C,EAAI31B,MAChC21B,GAId76C,GAAOJ,QAAUsC,CAEjB,IAAIE,GAAQF,EAAME,OACdC,SAAU,SAAUipD,GAChB,MAAO,IAAIjpD,GAASipD,IAExB7mD,MAAO,WACH,MAAO,IAAIA,GAAM9D,YAErByjD,KAAM,WACN0e,MAAO,SAAUC,GACb,MAAO,IAAID,GAAMC,IAErBhoD,gBAAiB,SAAUuwC,GACvB,MAAO,IAAIvwC,GAAgBuwC,IAG/BxsB,SAAU,eAGVn5B,iBAAkB,wBAGlBlC,WAAY,SAAS6nD,GACjB,MAAO,IAAI7nD,GAAW6nD,IAG1B5nD,SAAU,SAASs/D,EAAYC,GAC3B,MAAO,IAAIv/D,GAASs/D,EAAYC,IAIpCvjE,MAAOskE,UAgBPhoD,KAAM,SAAUxa,EAAO8pD,GACnB,IAEI,MADA6X,GAAa3hE,EAAO8pD,IACb,EACT,MAAOtsD,GACL,GAAIA,YAAaoD,GAAM1C,MACnB,OAAO,CAEX,MAAMV,MAgCdokE,IACC9gE,OAAQ,WACR08C,OAAQ,WACR7lC,QAAS,YACThX,SAAU,aAGViG,OAAW,cAwLZi7D,GAAe,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,OACpE,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,OAAQ,OAAQ,OACjE,QAAS,QAAS,QAAS,QAAS,QAAS,QAAS,QAAS,QAC/D,SAAU,SAAU,SAAU,SAAU,SAAU,SAAU,SAC5D,SAAU,UAAW,UAAW,UAAW,UAAW,UAAW,WACjE,WAAY,WAAY,YAAa,YAAa,YAAa,aAC/D,gBAeD58D,YAAY,GAAG5F,YAAY,MAAMojE,IAAI,SAASzkE,EAAQQ,GACzD,YAUA,SAAS0I,KACL,MAAOw7D,GAASl6C,IATpB,GAAIA,GAAQxqB,EAAQ,WACdW,EAASX,EAAQ,aACjB0kE,EAAS/jE,EAAOynD,eAGtB5nD,GAAOJ,QAAU8I,IAOdjC,YAAY,GAAG09D,UAAU,KAAKC,IAAI,SAAS5kE,EAAQQ,GACtD,YAMA,SAASqkE,KACL,GAAIC,GAAerjB,KAAKsjB,KAUxB,OATAC,GAAW,GAAKF,EACZG,GAAaH,GACbt6C,EAAkB,KAAVA,EAAe,EAAIA,EAAQ,EACnCw6C,GAAY,IAAMx6C,IAElBy6C,EAAYH,EACZt6C,EAAQ,IAGLw6C,EAfX,GAAIC,GAAYxjB,KAAKsjB,MACfv6C,EAAQ,GACRw6C,EAAW,GAAKC,CAgBtBJ,GAAYn9D,IAAM,WACd,MAAOs9D,IAGXxkE,EAAOJ,QAAUykE,OAEXK,IAAI,SAASllE,EAAQQ,GAC3B,YAcA,SAASghB,GAAqB7gB,GAC1B,GAAIwkE,GAAoBn8D,KAAKwnD,SAAS92B,WAClC0rC,EAAaD,EAAkBz9D,IAAI/G,EAAO0kE,gBAAkB,aAC5D9sD,EAAiB6sD,EAAW5jD,qBAAqB7gB,EAAO8X,UAAW9X,EAAOkB,OAM9E,IAJGlB,EAAOy1D,SACNt1D,EAAEM,YAAYmX,EAAgB5X,EAAOy1D,SAGtCz1D,EAAO2kE,cAAe,CACrB,GAAkC18D,SAA/BjI,EAAO2kE,cAAP3kE,SAA0C,KAAM,+BAEnDG,GAAEkD,OAAOuU,EAAgB5X,EAAO2kE,eAOpC,MAJA/sD,GAAAA,SAAuB6sD,EAAWpiE,UAElCmiE,EAAkB59D,IAAIgR,GAEfA,EA/BX/X,EAAOJ,QAAUohB,OAiCX+jD,IAAI,SAASvlE,EAAQQ,GAC3B,YAuDC,SAAS8J,GAASf,GACf,MAAOi8D,GAAqBj8D,EAAGgE,WAAYk4D,KAAKC,cAWpD,QAASF,GAAqBG,EAAUC,GACpC,MAAO9kE,GAAEo8C,OAAOyoB,EAAU,SAAUx9D,GAChC,MAAOA,GAAKy9D,UAAYA,IAYhC,QAASC,GAAkB19D,GACvB,KAAOA,GAAM,CACT,GAAIA,EAAKy9D,UAAYH,KAAKC,aACtB,MAAOv9D,EACXA,GAAOA,EAAK+X,WAEhB,MAAO,MASX,QAAS4lD,GAAsBv8D,GAC3B,GAAI89C,GAAM99C,EAAGw8D,aACb,KAAM1e,EAAK,MAAOnkD,GAAOC,MAAM,iDAC/B,IAAI6iE,GAAQ3e,EAAI4e,aAChBD,GAAME,mBAAmB38D,EACzB,IAAIgyB,GAAM4qC,EAAc58D,GAClB68D,EAAM7qC,EAAI1I,cAChBuzC,GAAIC,kBACJD,EAAIE,SAASN,GAQjB,QAASO,GAAkBh9D,GACvB,GAAIi9D,GAAWC,EAAcl9D,GACvBm9D,EAASC,EAAap9D,EAExBi9D,IAAYE,GACZE,EAAaJ,EAAU,EAAGE,EAAQA,EAAOzzC,YAAY3yB,QAU7D,QAASumE,GAAiB1+D,EAAM2+D,GAC5B,GAAIzf,GAAMl/C,EAAK49D,aACf,KAAM1e,EAAK,MAAOnkD,GAAOC,MAAM,4CAC/B,IAAI6iE,GAAQ3e,EAAI4e,aAChBD,GAAMe,SAAS5+D,EAAM2+D,EACrB,IAAIvrC,GAAM4qC,EAAch+D,GAClBi+D,EAAM7qC,EAAI1I,cAChBuzC,GAAIC,kBACJD,EAAIE,SAASN,GAWjB,QAASgB,GAAsBZ,GAC3B,MAAOa,GAAcb,EAAI9yC,WAAY8yC,EAAIhzC,aAAcgzC,EAAIpzC,UAAWozC,EAAIc,aAG9E,QAASD,GAAcT,EAAUW,EAAaT,EAAQU,GAClD,GAAIC,GAAcb,EAASc,wBAAwBZ,EACnD,OAAIW,GAAc5B,KAAK8B,4BACZ,EAEFF,EAAc5B,KAAK+B,4BACjB,GAEFhB,GAAYE,EACCU,EAAdD,EACO,EAEFA,EAAcC,EACZ,GAGA,EARV,OAqBT,QAASR,GAAaJ,EAAUW,EAAaT,EAAQU,GACjD,GAAI/f,GAAMmf,EAAST,aACnB,KAAM1e,EAAK,MAAOnkD,GAAO,4CACzB,IAEI4J,GAAW26D,EAFXC,EAAsE,IAA3DT,EAAcT,EAAUW,EAAaT,EAAQU,GACxDpB,EAAQ3e,EAAI4e,cAIZ1qC,EAAM4qC,EAAcK,GAClBJ,EAAM7qC,EAAI1I,cAGZ60C,IACA1B,EAAMe,SAASL,EAAQU,GACvBpB,EAAM2B,OAAOnB,EAAUW,GACvBnB,EAAM4B,UAAS,KAGf5B,EAAMe,SAASP,EAAUW,GACzBnB,EAAM2B,OAAOjB,EAAQU,IAGzBt6D,EAAYk5D,EAAM6B,yBAA2BpC,KAAKC,aAC9CM,EAAM6B,wBACN7B,EAAM6B,wBAAwBC,cAE7Bh7D,EAAUi7D,oBACXN,EAA0B36D,EAAUk7D,gBACpCl7D,EAAUk7D,gBAAkB,QAGhC5B,EAAIC,kBACJD,EAAIE,SAASN,GAET0B,GACAtB,EAAIpiE,OAAO0iE,EAAQU,GAGnBK,IAEA36D,EAAUk7D,gBAAkBP,GAQpC,QAASQ,GAAe1sC,GACpBA,EAAMA,GAAOpL,MACb,IAAIi2C,GAAM7qC,EAAI1I,cACduzC,GAAIC,kBAWR,QAAS6B,GAAiB3+D,EAAI4+D,GAC1B,GAAIC,GAAMC,CAMV,KAJAD,EAAO7+D,EAAGu0C,UACVuqB,EAAO9+D,EAAG++D,WACV/+D,EAAKA,EAAGg/D,aAEDh/D,GACH6+D,GAAQ7+D,EAAGu0C,UAAY0qB,EAAUj/D,EAAI,SAAU4+D,GAC/CE,GAAQ9+D,EAAG++D,WAAaE,EAAUj/D,EAAI,QAAS4+D,GAC/C5+D,EAAKA,EAAGg/D,YAGZ,QAASE,UAAWL,EAAMM,WAAYL,GAI1C,QAASG,GAAUj/D,EAAI+S,EAAM6rD,GACzB,GAAIA,EAAe,CACf,GAAIQ,GAAgB,UAARrsD,EAAoB,MAAQ,OACpCssD,EAASz4C,OAAOC,iBAAiB7mB,GACjCs/D,EAAYC,SAASF,EAAOG,iBAAiB,UAAYJ,EAAO,UAAW,GAE/E,IAAIE,EAAW,MAAOA,GAE1B,MAAO,GASX,QAASvnD,GAAc/X,GACnB,GAAI2R,GAAS3R,EAAG2W,UACZhF,KACAA,EAAO0L,YAAYrd,GACnB2R,EAAO8tD,aAWf,QAASvC,GAAct+D,GACnB,GAAIA,EAAKy9D,UAAYH,KAAKwD,UAAW,MAAO9gE,EAC5C,IAAIiqB,GAAaC,EAAiBlqB,EAAMmqB,WAAWe,UACnD,OAAOjB,GAAWV,aAUtB,QAASi1C,GAAax+D,GAClB,GAAIA,EAAKy9D,UAAYH,KAAKwD,UAAW,MAAO9gE,EAC5C,IAAIiqB,GAAaC,EAAiBlqB,EAAMmqB,WAAWe,UACnD,OAAOjB,GAAWwsB,YAStB,QAASv4B,GAAc9c,GACnB,GAAI2R,GAAS3R,EAAG2W,UAEhB,IAAIhF,EAAQ,CACR,GAAIukB,GAAO7xB,SAAS8xB,yBAEhBp1B,EAAWxJ,EAAEkS,MAAMzJ,EAAGgE,WAC1BjD,GAASxE,QAAQ25B,EAAKjZ,YAAaiZ,GACnCvkB,EAAOguD,aAAazpC,EAAMl2B,GAC1B2R,EAAO8tD,aAWf,QAASG,GAAcC,EAAY7/D,GAC/B,GAAI2R,GAAS3R,EAAG2W,UAEZhF,KACAA,EAAOoD,aAAa8qD,EAAY7/D,GAChC6/D,EAAW5iD,YAAYjd,IAW/B,QAAS8/D,GAAclhE,GACnB,MAAOmhE,GAAUnhE,EAAM,aAU3B,QAASohE,GAAaphE,GAClB,MAAOmhE,GAAUnhE,EAAM,YAI3B,QAASmhE,GAAUnhE,EAAMpC,GACrB,GAAI6f,GAAMzd,EAAK7H,MAEf,OADA6H,GAAK8qB,YAAc9qB,EAAK8qB,YAAYltB,KAC7B6f,IAAQzd,EAAK7H,OASxB,QAAS+gB,GAAgB9X,SACdA,GAAG5I,EAAOkc,cASrB,QAAS2sD,GAAU9S,GACf,GAAIrwB,GAAMz4B,SAASqN,cAAc,MAEjC,OADAorB,GAAIhsB,UAAYq8C,EACTrwB,EAAIpT,aAAe,GAY9B,QAASw2C,GAASjhB,EAAMtL,EAAQhrB,EAAUxO,GAEtC,IADA,GAAIgmD,GAAK97D,SAASykB,iBAAiBm2B,EAAMtL,GACnCwsB,EAAGj3C,YAAY,CACjB,GAAIvf,GAASgf,EAAS7xB,KAAKqjB,GAAW8kC,EAAMkhB,EAAGl3C,YAC/C,IAAItf,KAAW,EAAO,OAa9B,QAASqN,GAAWooB,EAAQp/B,GAcxB,QAASogE,GAAWrjD,GAChB,MAAOA,GAAM0F,SAASziB,GAd1B,GAAOo/B,GAAUA,EAAO3c,SAASziB,GAAjC,CAKA,IAHA,GAAIkX,MACEtY,EAAOwgC,EAENxgC,GAAQoB,GAAI,CACf,GAAIqgE,GAAY9oE,EAAEurD,UAAUlkD,EAAKoF,WAAYo8D,EAC7ClpD,GAASpQ,KAAKu5D,GACdzhE,EAAOA,EAAKoF,WAAWq8D,GAG3B,MAAOnpD,IAgBX,QAASE,GAAkBgoB,EAAQloB,EAAUC,GACzC,GAAKD,EAAL,CAEA,GAAImF,GAAMnF,EAASngB,MACnB,IAAY,IAARslB,EAAW,MAAO+iB,EAItB,KAAK,GAFDxgC,GAAOwgC,EAEF1oC,EAAI,EAAO2lB,EAAJ3lB,EAASA,IAAK,CAC1B,GAAIqK,GAAWnC,EAAKoF,UACpB,KAAMjD,EAAU,CACNoW,IAASvY,EAAOS,OACtB,OAEJ,GAAIihE,GAAappD,EAASxgB,GACpBqmB,EAAQhc,EAASu/D,EACvB,KAAMvjD,EAAO,CACTne,EAAOuY,EACGpW,EAASA,EAAShK,OAAS,GAC3BsI,MACV,OAEJT,EAAOme,EAGX,MAAOne,IAaX,QAAS2Y,GAAiB6nB,EAAQloB,EAAUlX,EAAImX,GAC5C,GAAIopD,GAAcvgE,EAAGq8D,UAAYH,KAAKwD,SAItC,IAHItgC,EAAO3c,SAASziB,IAChB+X,EAAc/X,GAEK,GAAnBkX,EAASngB,OAAb,CAEA,GAAI4a,GAASyF,EAAkBgoB,EAAQloB,EAASzN,MAAM,EAAG,IAAK0N,GACxDpW,EAAW4Q,EAAO3N,UAExB,KAAMjD,EAAU,CACZ,IAAIoW,EAGG,MAFHxF,GAASA,EAAOgF,WAChB5V,EAAW4Q,EAAO3N,WAI1B,GAAIs8D,GAAappD,EAASA,EAASngB,OAAS,GACtCgmB,EAAQhc,EAASu/D,EAEvB,OAAIvjD,IACApL,EAAOoD,aAAa/U,EAAI+c,GACpBwjD,GAAa5uD,EAAO8tD,aACjB,GACoB,IAApB1+D,EAAShK,QAAgC,IAAfupE,IAAoBnpD,GAKrD4F,EAAQhc,EAASu/D,EAAa,GAC1BvjD,GAAS5F,GACTxF,EAAOsL,YAAYjd,GACfugE,GAAa5uD,EAAO8tD,aACjB,GAHX,SALA9tD,EAAOsL,YAAYjd,GACfugE,GAAa5uD,EAAO8tD,aACjB,IAkBf,QAASe,GAAiBC,EAAOC,GAC7B,GACMC,GADFjqE,EAAI,CAER,KAAK2F,MAAMC,QAAQmkE,IAAUpkE,MAAMC,QAAQokE,GACvC,MAAO/mE,GAAOC,MAAM,qEAExB,KAAKlD,EAAGA,EAAI+pE,EAAM1pE,OAAQL,IAAK,CAC3B,GAAI+pE,EAAM/pE,GAAKgqE,EAAMhqE,GAAI,CACrBiqE,GAAW,CACX,OACG,GAAIF,EAAM/pE,GAAKgqE,EAAMhqE,GAAI,CAC5BiqE,GAAW,CACX,QAQR,MAJuB,mBAAZA,IACHF,EAAM1pE,OAAS2pE,EAAM3pE,QACrB4C,EAAOoQ,KAAK,gDAEb42D,IAAY,EASvB,QAASC,GAAazT,GAClB,MAAOA,GAAIttD,QAAQ,0BAA2B,SAASnJ,GACnD,MAAO,KAAKA,EAAEmqE,WAAW,GAAG,MAKpC,QAAS/3C,GAAiB9oB,EAAI8gE,GAE1B,MADAA,GAAaA,GAAe/3C,WAAWe,UAAYf,WAAWC,aACvD3kB,SAASykB,iBAAiB9oB,EAAI8gE,GAUzC,QAASlE,GAAch+D,GACnB,GAAIk/C,GAAMl/C,EAAK49D,aACf,OAAO1e,KAAQA,EAAIijB,aAAejjB,EAAIkjB,cAY1C,QAASC,GAAoBxE,EAAOt1D,GAIhC,QAAS+5D,GAAkBtiE,GACvB,GAAIuiE,GAAY98D,SAASq4D,cACrB0E,GAAW,CAQf,OAPAD,GAAUE,WAAWziE,GAEsD,IAAvEuiE,EAAUG,sBAAsB16C,OAAO26C,MAAMC,eAAgB/E,IACS,GAAnE0E,EAAUG,sBAAsB16C,OAAO26C,MAAME,WAAYhF,KAC5D2E,GAAW,GAEfD,EAAUv5C,SACHw5C,EAOX,IApBA,GAmBIn4C,GAnBAy4C,EAAiBjF,EAAM6B,wBACrBxgB,EAAM4jB,EAAelF,cAevB3zC,EAAai1B,EAAIh1B,iBAAiB44C,EAC9B34C,WAAWC,aAAeD,WAAWe,WAGtCb,EAAcJ,EAAWK,YACxBg4C,EAAkBj4C,IAClB9hB,EAAG8hB,GAUf,QAAS04C,GAAuBlF,GAC5B,GAAIzqC,GAAM4qC,EAAcH,EAAMmF,gBACxBh/D,EAAYovB,EAAIvyB,KAAKmD,UAEvButB,IASJ,OARA8wC,GAAoBxE,EAAO,SAAU79D,GACjC,GAAIA,EAAKy9D,UAAYH,KAAKwD,UAAW,CACjC,GAAItpD,GAAOxT,EAAUgB,aAAahF,EAC9BwX,IACA+Z,EAAWrpB,KAAKsP,MAIrB+Z,EAQX,QAAS0xC,GAA0BpF,GAC/B,GAAItsC,GAAawxC,EAAuBlF,EAExCtsC,GAAW5zB,QAAQ,SAAS6Z,GACxBA,EAAKzU,SAAQ,KAGjB86D,EAAMqF,iBAUV,QAASC,GAAeC,EAAQC,GAC5B,MAA4E,IAArED,EAAOV,sBAAsB16C,OAAO26C,MAAMC,eAAgBS,IAAiF,GAAjED,EAAOV,sBAAsB16C,OAAO26C,MAAME,WAAYQ,GAS3I,QAASC,GAAcC,EAAGC,GACtB,GAAIC,GAAOh+D,SAASqN,cAAc,MAClC2wD,GAAK9gE,aAAa,QAAS,iDAAiD4gE,EAAE,WAAWC,EAAE,0CAC3FntB,WAAW,WAAY5wC,SAASC,KAAK2Y,YAAYolD,IAAS,KAnqB9D,GAAIjrE,GAASX,EAAQ,aACfc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,YAEnB8b,GACAxR,SAAUA,EACVk7D,qBAAsBA,EACtBK,kBAAmBA,EACnBC,sBAAuBA,EACvBS,kBAAmBA,EACnB2B,iBAAkBA,EAClBrB,iBAAkBA,EAClBG,sBAAuBA,EACvBJ,aAAcA,EACdqB,eAAgBA,EAChB3mD,cAAeA,EACf+E,cAAeA,EACf8iD,cAAeA,EACf9nD,gBAAiBA,EACjBolD,cAAeA,EACfE,aAAcA,EACd0C,cAAeA,EACfE,aAAcA,EACdC,UAAWA,EACXW,aAAcA,EACdV,SAAUA,EACVp3C,iBAAkBA,EAElB9R,WAAYA,EACZI,kBAAmBA,EACnBG,iBAAkBA,EAClBipD,iBAAkBA,EAElB5D,cAAeA,EAEf+E,uBAAwBA,EACxBE,0BAA2BA,EAC3BZ,oBAAqBA,EACrBc,eAAgBA,EAEhBG,cAAeA,EAGnBjrE,GAAOJ,QAAU0b,IA2nBd7U,YAAY,GAAG4kE,WAAW,IAAIxqE,YAAY,MAAMyqE,IAAI,SAAS9rE,EAAQQ,GACxE,YAUA,SAASgnD,KACL5mD,KAAKgmD,aAWT,QAASmlB,GAAiB51C,EAAQH,EAAWg2C,GACzCprE,KAAKgmD,UAAUv2C,MACX8lB,OAAQA,EACRH,UAAWA,EACXg2C,QAASA,IAEb71C,EAAOmS,iBAAiBtS,EAAWg2C,GAIvC,QAASC,GAAoB91C,EAAQH,EAAWg2C,GAC5C,GAAIE,IACA/1C,OAAQA,EACRH,UAAWA,EACXg2C,QAASA,GAETG,EAAMrrE,EAAEurD,UAAUzrD,KAAKgmD,UAAW9lD,EAAEqkB,QAAQrkB,EAAEsrE,QAASF,GAEvDC,GAAM,KACNvrE,KAAKgmD,UAAUv6B,OAAO8/C,EAAK,GAC3BE,EAAgBH,IAKxB,QAASI,KACL1rE,KAAKgmD,UAAU9gD,QAAQumE,GACvBzrE,KAAKgmD,aAIT,QAASylB,GAAgBE,GACrBA,EAAEp2C,OAAOqS,oBAAoB+jC,EAAEv2C,UAAWu2C,EAAEP,SAnDhD,CAAA,GAAIlrE,GAAId,EAAQ,YACFA,GAAQ,WAGtBQ,EAAOJ,QAAUonD,EAQjB1mD,EAAEM,YAAYomD,GACVjgD,IAAKwkE,EACLpkE,OAAQskE,EACRtkB,UAAW2kB,MAuCZE,UAAU,GAAGnrE,YAAY,MAAMorE,IAAI,SAASzsE,EAAQQ,GACvD,YAaA,SAAS6vD,GAAS9+C,GAad,QAASmqB,KACLnqB,EAAKrQ,MAAMw5B,EAAM3nB,GAbrB,GAAI2nB,GAAO95B,KACLmS,EAAOjS,EAAEkS,MAAM7R,UAAW,EAC5Bg6B,GAAQ96B,KAAKO,MACb86B,KAEKgxC,IACD9+D,SAAS06B,iBAAiB,mBAAoBqkC,GAC9CD,GAAqB,GAEzBE,EAAcv8D,KAAKqrB,IAS3B,QAASixC,KACL/+D,SAAS46B,oBAAoB,mBAAoBmkC,GACjDC,EAAc9mE,QAAQ,SAASyL,GAAQA,MAS3C,QAAS4pB,KACL,GAAIJ,GAAantB,SAASmtB,UAC1B,OAAqB,WAAdA,GAA0B,EAAQA,EA1C7C,GAAIj6B,GAAId,EAAQ,YAGhBQ,GAAOJ,QAAUiwD,CAGjB,IAAIuc,MACEF,GAAqB,CA4B3B5rE,GAAEkD,OAAOqsD,GACLl1B,QAASA,MASV95B,YAAY,MAAMwrE,IAAI,SAAS7sE,EAAQQ,GAC1C,YAqBA,SAASi3B,GAASxB,GACdr1B,KAAKq1B,MAAQA,EACbr1B,KAAKsb,aAAe+Z,EAAM/Z,aAC1Btb,KAAKyb,MAAQ4Z,EAAM/Z,aAAaG,MA+BpC,QAASywD,KACL,MAAOC,GAAe51C,UAAUre,UAIpC,QAASk0D,KACL,MAAOlsE,GAAEmkB,QAAQrkB,KAAKyb,MAAOob,EAASw1C,sBAAwB,EAIlE,QAASC,KACL,GAAI/wD,GAAWsb,EAASw1C,oBAClBE,EAAWvsE,KAAKsb,aAAaO,QAAQN,GACrCpD,EAAQK,EAAU+zD,EAExB,OAAOp0D,GAIX,QAASq0D,GAA2Bt0D,EAAWq0D,GAC3C,IAAMA,EAAU,CACZ,GAAIp0D,GAAQD,EAAU8I,kBAAmByrD,YAAa,QACtDF,GAAWl0D,KAAKC,UAAUH,GAE9B,GAAIoD,GAAWsb,EAASw1C,mBAIxB,OAFAE,IAAYvsE,KAAKsb,aAAaob,QAAQnb,EAAUgxD,GAChDvsE,KAAKsb,aAAaob,QAAQ,YAAaxe,EAAUvP,GAAGkS,WAC7C0xD,EAIX,QAASG,GAA0Bx0D,EAAW8d,EAAQ5V,GAClD,GAAI0V,GAAO62C,EAAez0D,GAEtB00D,EAAY1sE,EAAE2sE,cAAc72C,GAC5Bza,EAAW4wD,EAAe51C,UAAU0xB,sBACvBz/C,QAAQ,SAAUskE,EAAQh3C,EAAKluB,WAAa,KAC5CY,QAAQ,QAASskE,EAAQh3C,EAAK7tB,UAAY,KAC1CO,QAAQ,UAAWskE,EAAQF,GAAa,IAMzD,OAJIxsD,IAAuB,gBAARA,KAAkBA,EAAO/H,KAAKC,UAAU8H,IAE3DpgB,KAAKsb,aAAaob,QAAQnb,EAAU6E,GAAQ,IAErC7E,EAIX,QAASuxD,GAAQhX,GACb,MAAOiX,GAAOC,OAAOlX,GAAKvwB,cAI9B,QAASonC,GAAez0D,GACpB,MAAOA,GAAU8F,SACP9F,EAAU8F,SAAS+a,oBAEjBnxB,UAAWsQ,EAAU9X,YAAYH,KACjCgI,SAAUiQ,EAAUjY,MAKpC,QAASgtE,KACL,GAAIxlE,GACAylE,EAAehtE,EAAEsb,KAAKxb,KAAKyb,MAAO,SAAU0xD,GAE5C,MADA1lE,GAAQ0lE,EAAM1lE,MAAMygD,KACXzgD,GAEb,IAAKylE,EAAL,CAEA,IAAK,GAAI7tE,GAAE,EAAK,EAAFA,EAAKA,IACfoI,EAAMpI,GAAK0tE,EAAOK,OAAO3lE,EAAMpI,GAEnC,QACIuI,UAAWH,EAAM,GACjBQ,SAAUR,EAAM,GAChBuuB,OAAQ91B,EAAEmtE,gBAAgB5lE,EAAM,IAChCylE,aAAcA,EACdI,SAAUptE,EAAEsY,UAAUxY,KAAKsb,aAAaO,QAAQqxD,IAClChtE,EAAEsY,UAAUxY,KAAKsb,aAAaO,QAAQqxD,IACtCltE,KAAKsb,aAAaO,QAAQqxD,KAMhD,QAASK,KACL,MAAOvtE,MAAKsb,aAAakyD,cAI7B,QAASC,GAA2Br2C,GAChCp3B,KAAKsb,aAAakyD,cAAgBp2C,EAItC,QAASs2C,KACL,MAAO1tE,MAAKsb,aAAaqyD,WAI7B,QAASC,GAAuBC,GAC5B7tE,KAAKsb,aAAaqyD,WAAaE,EAInC,QAASC,GAAyBD,GAC9B,GAAIx2C,GAAiBr3B,KAAK+tE,oBACpBC,EAAmB,QAAVH,EACTI,EAAmB,QAAVJ,EACTK,EAAmB,QAAVL,EACTM,EAAYH,GAAUE,GAAUD,CAEtC,QAAQ52C,GACJ,IAAK,OACL,IAAK,OACL,IAAK,OACD,MAAOA,IAAkBw2C,CAC7B,KAAK,WACD,MAAOG,IAAUE,CACrB,KAAK,WACD,MAAOF,IAAUC,CACrB,KAAK,WACD,MAAOC,IAAUD,CACrB,KAAK,MACL,IAAK,gBACD,MAAOE,EACX,KAAK,OACD,OAAO,GAKnB,QAASC,GAAiB7yD,GACtB,MAAOvb,MAAKsb,aAAaO,QAAQN,GAIrC,QAAS8yD,GAAiB9yD,EAAU+yD,GAChCtuE,KAAKsb,aAAaob,QAAQnb,EAAU+yD,GAIxC,QAASC,GAAmBhzD,GACxBvb,KAAKsb,aAAakzD,UAAUjzD,GAmChC,QAASkzD,GAAkBv4D,EAAKkK,GAC5BsuD,EAAmBtuD,EAAK6W,SACxB03C,EAAoBvuD,EAAK8W,UAI7B,QAAS03C,GAAoB14D,EAAKkK,GAC9BuuD,GAAqBA,EAAkBniE,gBAAgB,oBAAqB4T,GAC5EsuD,EAAmB1mE,OACnB2mE,EAAoB3mE,OAIxB,QAAS6mE,GAAmB34D,EAAKkK,GACzBsuD,GACAI,EAAgBtiE,gBAAgB,oBAAqB4T,GAI7D,QAAS2uD,KACL,MAAOL,GAIX,QAASM,KACLF,EAAgB9kB,SAnQpB,GACMtzC,IADUtX,EAAQ,yBACNA,EAAQ,iBACpB+sE,EAAiB/sE,EAAQ,aAAa63B,SACtCixB,EAAqBikB,EAAe51C,UAAU2xB,mBAC9C1vC,EAAYpZ,EAAQ,gBACpBc,EAAId,EAAQ,aACZ2tE,EAAS3tE,EAAQ,SAGvBQ,GAAOJ,QAAUq3B,EAuBjB32B,EAAEkD,OAAOyzB,GACLw1C,kBAAmBH,IAGvBhsE,EAAEM,YAAYq2B,GACVhW,YAAaurD,EACb13B,kBAAmB43B,EACnBx1C,kBAAmB01C,EACnBzzC,iBAAkBk0C,EAClB72C,iBAAkBs2C,EAClBqB,kBAAmBR,EACnBj2C,kBAAmBm2C,EACnBwB,cAAevB,EACfr1C,cAAeu1C,EACfsB,gBAAiBpB,EACjBjyD,QAASuyD,EACT13C,QAAS23C,EACTG,UAAWD,GA6Jf,IAEIG,GAAkBC,EAFlBG,EAAkB,GAAIp4D,EAI1BxW,GAAEkD,OAAOyzB,GACLG,QAAS83C,EACTxkE,QAAS0kE,IAIbF,EAAgBx6C,YAGZ66C,gBAAmBV,EAGnBW,kBAAqBR,EAGrBS,iBAAoBR,IAIxB3uE,EAAEkD,OAAO0rE,GACLC,mBAAoBA,MAgCrBtQ,wBAAwB,GAAGp4D,YAAY,GAAG4Q,eAAe,GAAGq4D,eAAe,IAAIvC,OAAS,IAAItsE,YAAY,MAAM8uE,IAAI,SAASnwE,EAAQQ,GAKtI,YAwBA,SAAS4vE,GAAkBC,GACvB,GAAIC,GAAaxvE,EAAEs9D,aAAaiS,EAAgB,UACxC,gBAAkBA,EAAiB,kEAI3C,OAFAvvE,GAAEyvE,aAAaD,EAAYpwE,OAEpBowE,EAIX,QAASE,KACL,KAAM,IAAIrtE,GAAMstE,cAAc,4CAjClC,GAAI3vE,GAAId,EAAQ,aAIZ0wE,GAAmB,gBAAiB,QAAS,YAAa,YACvC,YAAa,SAAU,SAAU,oBAAqB,QACtD,QAAS,QAAS,WAAY,gBAC9B,OAAQ,YAAa,WAAY,qBACjC,OAAQ,UAAW,wBAEtCvtE,GACA8H,gBAAiBulE,EACjBG,YAAaP,EAGjBM,GAAgB5qE,QAAQ,SAASjF,GAC7BsC,EAAMtC,GAAQuvE,EAAkBvvE,EAAO,WAG3CL,EAAOJ,QAAU+C,IAiBd9B,YAAY,MAAMuvE,IAAI,SAAS5wE,EAAQQ,GAC1C,YAsCA,SAASqwE,GAAkB7K,EAAO5/C,EAAgB0qD,GAC9C,GAAI7F,GAAiB8F,EAAmB/K,EACxC,KAAMiF,EAEF,WADA/nE,GAAOC,MAAM,mDAIjB,IAAIs8B,GAAOumC,EAAMgL,gBACXC,EAAUC,EAAyBzxC,EAAMqxC,EAE/CK,GAAgBlG,EAAgBgG,GAC5B7qD,GAAgBgrD,EAAgBH,EACpC,IAAII,GAAeJ,EAAQj4D,UAE3B,OADAlY,GAAEmQ,YAAYggE,EAAS,WAChBI,EAYX,QAASC,GAAuBtL,EAAO5/C,EAAgBhG,GACnD,IACI,GAAI6qD,GAAiB8F,EAAmB/K,EACxC,KAAMiF,EAEF,WADA7qD,GAAS,GAAIlgB,OAAM,oDAIM,mBAAlBkmB,KACPhG,EAAWgG,EACXA,GAAiB,EAGrB,IAAIqZ,GAAOumC,EAAMgL,gBACXC,EAAUC,EAAyBzxC,EAEzC0xC,GAAgBlG,EAAgBgG,GAChCnwE,EAAEoQ,MAAM,WACJ+/D,EAAQx2D,UAAU,cAClB3Z,EAAEoQ,MAAM,WACAkV,GAAgBgrD,EAAgBH,EACpC,IAAII,GAAeJ,EAAQj4D,UAC3Bi4D,GAAQ/lE,UACRkV,EAAS,KAAMixD,OAGzB,MAAOh2B,GACLj7B,EAASi7B,IAKjB,QAAS61B,GAAyBzxC,EAAMqxC,GACpC,GAAIp1D,GAAS9N,SAASqN,cAAc,OAC9BvR,EAAO,GAAIC,GAAc+R,EAE/B5a,GAAEkD,OAAO0F,GACLlB,UAAWsoE,GAAoB,YAC/BroE,WAAYqoE,MAAyB,aACrCjoE,SAAU,YAGda,EAAKE,WAEL8R,EAAO8K,YAAYiZ,EACnB,IAAIzzB,GAAQL,EAAO+P,EACnB,OAAO1P,GAAMilE,QAIjB,QAASF,GAAmB/K,GACxB,GAAIz8D,GAAKuS,EAAS+pD,kBAAkBG,EAAM6B,wBAC1C,OAAO17D,GAAUgP,uBAAuB5R,GAAI,EAAM,aAItD,QAAS4nE,GAAgBI,EAAUC,GAC/B,GAAIC,GAAYF,EAASzkE,UAAUd,KACnCwlE,GAAO1kE,UAAUd,MAAMW,MAAM,SAAS+kE,EAAa7wE,GAC/C,GAAI8wE,GAAgBF,EAAU5wE,EAC9B,KAAM8wE,EAAe,MAAOzuE,GAAOC,MAAM,+BAAgCtC,EAAM,qBAC/E,IAAIkY,GAAQ44D,EAAcz3D,WAAU,EACpCw3D,GAAYv3D,SAASpB,KAK7B,QAASq4D,GAAgBzxD,GACrBA,EAAK7S,UAAUd,MAAMW,MAAM,SAAS2Z,GAChCA,EAAMxI,WAKd,QAAS8zD,GAAsB5L,GAC3B,GAAI6L,GAAWC,EAAiB9L,EAEhC,OADAA,GAAQ+L,EAAwBF,GAKpC,QAASE,GAAwBC,GAC7B,GAAIhM,GAAQp4D,SAASq4D,aAMrB,OALI+L,GAAMH,UACN7L,EAAMiM,eAAeD,EAAM/0D,OAC3B+oD,EAAMkM,YAAYF,EAAMG,MAExBnM,EAAM4E,WAAWoH,EAAM/0D,OACpB+oD,EAIX,QAAS8L,GAAiB9L,GACtB,GAAIoM,GAAgBpM,EAAM6B,wBACpBwK,EAAYrM,EAAMmF,eAClBmH,EAAUtM,EAAMuM,YAEtB,IAAIF,GAAaC,EAEb,MADID,IAAaD,GAAelvE,EAAOC,MAAM,iFACpC0uE,UAAU,EAAO50D,MAAOo1D,EAGrC,IAAIA,GAAaD,GAAiBE,GAAWF,EACzC,OAASP,UAAU,EAAO50D,MAAOm1D,EAErC,IAAII,GAAeC,EAAqBL,EAAeC,GACnDK,EAAaD,EAAqBL,EAAeE,EAErD,OAAIE,IAAgBE,EACZF,GAAgBE,GAChBxvE,EAAOC,MAAM,wDACJ0uE,UAAU,EAAO50D,MAAOu1D,KAExBX,UAAU,EAAM50D,MAAOu1D,EAAcL,IAAKO,GAL3D,OAUJ,QAASD,GAAqBL,EAAeO,GACzC,MAAO7xE,GAAEsb,KAAKg2D,EAAc7kE,WAAY,SAASpF,GAC7C,MAAOA,GAAK6jB,SAAS2mD,KAK7B,QAASC,GAAyBrhE,GAC9B,MAAO,UAASo3B,EAAQkqC,GACpB,GAAIC,IACAjB,SAAUgB,EAAQhB,SAClB50D,MAAO1L,EAAKo3B,EAAQkqC,EAAQ51D,OAIhC,OAFI61D,GAAMjB,WACNiB,EAAMX,IAAM5gE,EAAKo3B,EAAQkqC,EAAQV,MAC9BW,GAlMf,CAAA,GAAI3mE,GAAYnM,EAAQ,yBAClB2J,EAAgB3J,EAAQ,wBACxB2L,EAAS3L,EAAQ,aACjB8b,EAAW9b,EAAQ,SACnBkD,EAASlD,EAAQ,YAEjBc,GADQd,EAAQ,WACZA,EAAQ,cAGd+yE,EAAmBH,EAAyB92D,EAASyE,YACrDyyD,EAAmBJ,EAAyB92D,EAAS6E,kBAGrCngB,GAAOJ,SACvB4Y,SAAU63D,EACVoC,cAAe3B,EAEfM,sBAAuBA,EACvBE,iBAAkBA,EAClBC,wBAAyBA,EACzBmB,qBAAsBnB,EACtBgB,iBAAkBA,EAClBC,iBAAkBA,MAkLnB5wD,uBAAuB,EAAEC,YAAY,EAAEg9C,wBAAwB,GAAGmN,UAAU,GAAG2G,QAAQ,GAAGtH,WAAW,IAAIxqE,YAAY,MAAM+xE,KAAK,SAASpzE,EAAQQ,GACpJ,YA+BA,SAAS6yE,KACLpqE,EAAKkyC,QAAQjwC,UACbjC,EAAK4uB,SAAS3sB,UA5BlB,GAAIjC,IACA/F,OAAQlD,EAAQ,YAChBm7C,QAASn7C,EAAQ,aACjBmpD,UAAWnpD,EAAQ,eACnB0C,MAAO1C,EAAQ,WACfmD,MAAOnD,EAAQ,WACfwqB,MAAOxqB,EAAQ,WACfszE,SAAUtzE,EAAQ,WAClBkJ,cAAelJ,EAAQ,oBACvB6Z,IAAK7Z,EAAQ,SACbuzE,aAAcvzE,EAAQ,mBACtB4yB,UAAW5yB,EAAQ,eACnBwzE,SAAUxzE,EAAQ,cAClBoZ,UAAWpZ,EAAQ,gBACnByzE,QAASzzE,EAAQ,aACjBqwD,SAAUrwD,EAAQ,cAClB63B,SAAU73B,EAAQ,cAClB6kD,OAAQ7kD,EAAQ,qCAChBsiD,MAAOtiD,EAAQ,oCACf4vB,IAAK5vB,EAAQ,OACbkL,QAASmoE,EAGb7yE,GAAOJ,QAAU6I,IAQdyqE,mCAAmC,GAAGC,oCAAoC,GAAGnH,UAAU,GAAGoH,mBAAmB,GAAGjP,UAAU,GAAGwO,QAAQ,GAAGU,kBAAkB,GAAGC,aAAa,GAAGC,aAAa,GAAGC,UAAU,GAAGC,aAAa,GAAG/D,eAAe,IAAIrE,WAAW,IAAIqI,YAAY,IAAIC,cAAc,IAAIC,YAAY,IAAIC,cAAc,IAAI9/C,IAAM,MAAM+/C,KAAK,SAASt0E,EAAQQ,GACrW,YAaA,SAAS4Y,GAAUs9C,GACf,IACI,MAAOz9C,MAAK/Q,MAAMwuD,GACpB,MAAOl3D,KAbbgB,EAAOJ,QAAUgZ,OAgBXm7D,KAAK,SAASv0E,EAAQQ,GAC5B,YAuBA,IAAIg0E,GAASx0E,EAAQ,kBAEjBkD,EAAS,GAAIsxE,IAASC,MAAO,GAEjCj0E,GAAOJ,QAAU8C,IAEdwxE,iBAAiB,MAAMC,KAAK,SAAS30E,EAAQQ,GAChD,YAgDA,SAAS0uC,GAAIwnB,GACT,MAAIA,GAAIp2D,OAASs0E,EACNle,EAAM,GAAI9wD,OAAMgvE,EAAiBle,EAAIp2D,OAAS,GAAG+I,KAAK,KAE1DqtD,EAIX,QAASme,GAAQne,EAAKoe,GAClB,MAAO,KAAUA,EAAQ,IAAMpe,EAAM,UAvCzC,GAAI51D,GAAId,EAAQ,aAOZ+0E,GACA,QACA,OACA,OACA,SAGAH,EAAiBz1B,KAAKvQ,IAAI1tC,MAAMi+C,KAAM41B,EAAOljE,IAAI,SAAS4iE,GAAS,MAAOA,GAAMn0E,UAMhF00E,GACA,GACA,GACA,GACA,IAmBAC,GACAR,MAAO,EACPS,WAAY,GACZC,SAAS,EACTC,UAAW,IASXZ,EAAS,SAAUa,GACnBv0E,EAAEkD,OAAOpD,KAAMq0E,GACfn0E,EAAEkD,OAAOpD,KAAMy0E,OAUnBb,GAAOxxE,UAAUsyE,IAAM,SAAUh5D,GAC7B,GAAIsO,GAAQmqD,EAAO9vD,QAAQ3I,EAE3B,KAAM1b,KAAKu0E,SAAWvqD,EAAQhqB,KAAK6zE,MAC/B,MAAO7zE,KAEX,IAAImS,GAAOjS,EAAEkS,MAAM7R,UAAW,EAE9B,IAAIypB,GAAShqB,KAAKs0E,WACd,KAAM,IAAIh1E,QAAOU,KAAKw0E,UAAW94D,EAAO,KAAK2iB,OAAOlsB,GAAM1J,KAAK,KAanE,OAXAksE,SAAQD,IAAIp0E,MACNq0E,SACE30E,KAAK40E,eACD,MAAQX,EAAQj0E,KAAKw0E,UAAWx0E,KAAK40E,gBACrC50E,KAAKw0E,WACRx0E,KAAKo0E,OACF,IAAMH,EAAQ3lC,EAAI5yB,GAAO04D,EAAOpqD,IAChCtO,GAAQ,KACZ2iB,OAAOlsB,IAGRnS,MAOXm0E,EAAOjvE,QAAQ,SAAUjF,GACrB2zE,EAAOxxE,UAAUnC,GAAQ,WACrBD,KAAK00E,IAAIp0E,MAAMN,MAAOC,GAAMo+B,OAAOn+B,EAAE+S,QAAQ1S,gBAKrDX,EAAOJ,QAAUo0E,IAEdnzE,YAAY,MAAMo0E,KAAK,SAASz1E,EAAQQ,GAC3C,YAyCA,SAASk1E,GAAsBC,GAC3B,MAAO,YACH,GAAIC,GAAUC,QAAQ7yE,UAAU2yE,GAAcz0E,MAAMN,KAAMO,UAE1D,OADA20E,GAAkBF,EAASh1E,KAAKm1E,UACzBH,GAKf,QAASz6B,GAAQN,EAAKw6B,EAAMj1D,GAsBxB,QAAS41D,GAAQx2E,GACby2E,EAASC,EAAK91D,EAAU+1D,EAAU32E,EAAE8c,MAtBxC+4D,EAAKx6B,IAAMA,EACXw6B,EAAKe,YAAcf,EAAKe,aAAe,iCACnCr/D,GAAYokC,EAAQ/tC,gBAAgB,WAAauR,QAAS02D,GAE9D,IAAIa,GAAM,GAAIG,eACdH,GAAII,KAAKjB,EAAK7vE,OAAQ6vE,EAAKx6B,KAAK,GAChCq7B,EAAIK,iBAAiB,eAAgBlB,EAAKe,aAC1CI,EAAkBN,EAAKb,EAAKoB,SAE5BP,EAAI7zB,QAAUgzB,EAAKhzB,SAAW1hD,EAAOw6C,QAAQ+N,SAAS7G,QACtD6zB,EAAIQ,mBAAqBR,EAAIS,UAAYT,EAAIU,QAAUZ,CAEvD,IAAIG,GAAWU,EAAgBX,EAO/B,OALAA,GAAIY,KAAK79D,KAAKC,UAAUm8D,EAAKr0D,OAC7Bk1D,EAAIv1E,EAAOw6C,QAAQ8N,YAAcosB,EAEjC0B,EAAiB1mE,KAAK6lE,GAEfC,EAASP,QAQpB,QAASiB,GAAgB17B,GACrB,GAAI67B,GAAgBC,EAChBrB,EAAU,GAAIC,SAAQ,SAASqB,EAASC,GACxCH,EAAiBE,EACjBD,EAAgBE,GAMpB,OAHArB,GAAkBF,EAASz6B,GAC3By6B,EAAAA,SAAc90E,EAAEo6C,OAGZ06B,QAASA,EACTsB,QAASF,EACTG,OAAQF,GAKhB,QAASnB,GAAkBF,EAASz6B,GAKhC,MAJAy6B,GAAQG,SAAW56B,EACnBy6B,EAAQwB,KAAOC,EACfzB,EAAAA,SAAgB0B,EAET1B,EAIX,QAASY,GAAkBN,EAAKO,GACxBA,GACA31E,EAAEqB,QAAQs0E,EAAS,SAASz0E,EAAOioB,GAC/BisD,EAAIK,iBAAiBtsD,EAAKjoB,KAItC,QAASi0E,GAASC,EAAK91D,EAAU+1D,EAAUngD,GAoCvC,QAAShf,GAAYF,GACbC,GAAYokC,EAAQnkC,YAAYF,GAC9BygE,OAAQA,OAAQj8B,SAAU46B,EAAIsB,eArCxC,GAAsB,GAAlBtB,EAAIn7C,aACHm7C,EAAIqB,QAAuB,oBAAbvhD,GAAnB,CAEAl1B,EAAE22E,WAAWV,EAAkBb,EAE/B,IAAI/yE,EACJ,KACI,GAAK+yE,EAAIqB,QAAU,KAAOrB,EAAIqB,OAAS,IAAM,CACzC,IACIvgE,EAAY,WACZoJ,GAAYA,EAAS,KAAM81D,EAAIsB,aAActB,GAC/C,MAAM12E,GAAK2D,EAAQ3D,EACrB22E,EAASe,QAAQhB,EAAIsB,kBAEpB,CACD,GAAIE,GAAcxB,EAAIqB,QAAUvhD,CAChC,KACIhf,EAAY,SACZA,EAAY,QAAU0gE,GACtBt3D,GAAYA,EAASs3D,EAAaxB,EAAIsB,aAActB,GACtD,MAAM12E,GAAK2D,EAAQ3D,EACrB22E,EAASgB,QAASQ,OAAQD,EAAap8B,SAAU46B,EAAIsB,gBAE3D,MAAMh4E,GACJ2D,EAAQA,GAAS3D,EASrB,GALA02E,EAAIQ,mBAAqBR,EAAIS,UAAYT,EAAIU,QAAUhuE,OAElDmuE,EAAiBz2E,QAClB0W,EAAY,qBAEZ7T,EAAO,KAAM,IAAIjD,OAAM,cAAgBiD,IAwB/C,QAASy0E,KACL7gE,EAAa,GAAIO,GAAU6jC,GAAU,KAAM,OAAQ,SAAU,MAAO,aAAc,cAAe,cAAe,oBAIpH,QAAS08B,GAAYh9B,EAAKz6B,GACtB,MAAO+6B,GAAQN,GAAOr1C,OAAQ,OAAS4a,GAI3C,QAAS03D,GAAaj9B,EAAK75B,EAAMZ,GAC7B,MAAO+6B,GAAQN,GAAOr1C,OAAQ,OAAQwb,KAAMA,GAAQZ,GAIxD,QAAS23D,GAAal9B,EAAKz6B,GACvB,GAAIw1D,GAAUz6B,EAAQN,GAAOr1C,OAAQ,QAEjCwyE,EAAcpC,EAAQwB,KAAKn+D,KAAK/Q,MAOpC,OALIkY,IACA43D,EACCZ,KAAK,SAASp2D,GAAQZ,EAAS,KAAMY,KADtCg3D,SAEO,SAASC,GAAW73D,EAAS63D,EAAQN,OAAQM,EAAQ38B,YAEzD08B,EAKX,QAASE,GAAcr9B,EAAKz6B,GA6BxB,QAAS+3D,GAAU98B,EAAKnoC,GACpBpS,EAAE22E,WAAWV,EAAkB5mD,OAAOioD,GACtC,KACIphE,EAAYqkC,EAAM,QAAU,UAAWA,EAAKnoC,GACxCmoC,IACAn4C,EAAOC,MAAM,gCACb6T,EAAY,oBAAqBqkC,IAErCj7B,GAAYA,EAASi7B,EAAKnoC,GAE9B,MAAM1T,GAAK,GAAI2D,GAAQ3D,EAQvB,GAPI67C,EAAK86B,EAASgB,OAAO97B,GACpB86B,EAASe,QAAQhkE,GAEtBmlE,IACKtB,EAAiBz2E,QAClB0W,EAAY,qBAEZ7T,EAAO,KAAMA,GAIrB,QAASk1E,KACLC,aAAaj2B,GACbk2B,EAAK3xD,YAAY4xD,SACVroD,QAAOioD,GAIlB,QAASphE,GAAYF,EAAKygE,EAAQrkE,GAC1B6D,GAAYokC,EAAQnkC,YAAYF,GAC9BygE,OAAQA,EAAQj8B,SAAUpoC,IA3DpC,GAAIslE,GAAS5qE,SAASqN,cAAc,UAChCk7D,EAAWU,EAAgB2B,GAC3BD,EAAOpoD,OAAOviB,SAAS2qE,KACvBH,EAAiBz3E,EAAOw6C,QAAQ6N,oBAAsBx+B,IAEtD6qD,EAAOv0E,EAAEkD,QAAS62C,IAAKA,GAAO49B,EAC9B1hE,IAAYokC,EAAQ/tC,gBAAgB,WAAauR,QAAS02D,IAExDv0E,EAAEsrE,QAAQtrE,EAAE43E,SAASrD,EAAM,OAAQoD,IACrCv1E,EAAOoQ,KAAK,wFAEhB,IAAI+uC,GAAU7D,WAAW,WACrB,GAAInD,GAAM,GAAIn7C,OAAM,+CACpBi4E,GAAU98B,IACX16C,EAAOw6C,QAAQ4N,aAWlB,OATA54B,QAAOioD,GAAkBt3E,EAAEqkB,QAAQgzD,EAAW,MAE9CpB,EAAiB1mE,KAAK8f,OAAOioD,IAE7BI,EAAOl8D,KAAO,kBACdk8D,EAAOtmC,IAAMmjC,EAAKx6B,KAAgC,IAAzBw6B,EAAKx6B,IAAI51B,QAAQ,KAAa,IAAM,KAAO,YAAcmzD,EAElFG,EAAK/xD,YAAYgyD,GAEVrC,EAASP,QAuCpB,QAAS+C,GAAatD,EAAMuD,EAAUx4D,EAAUy4D,GAgC5C,QAAS7C,GAAQx2E,GACTq5E,IAAU3C,EAAI4C,OAAOC,WAAanwE,QACtCqtE,EAASC,EAAK91D,EAAU+1D,EAAU32E,EAAE8c,MAjCrB,gBAAR+4D,KACPA,GAAS7vE,OAAQ,OAAQq1C,IAAKw6B,IAElCA,EAAK7vE,OAAS6vE,EAAK7vE,QAAU,OAC7B6vE,EAAK2D,MAAO,EAERjiE,GAAYokC,EAAQ/tC,gBAAgB,WAAauR,QAAS02D,GAE9D,IAAIa,GAAM,GAAIG,eACVwC,KAAU3C,EAAI4C,OAAOC,WAAaF,GAEtC3C,EAAII,KAAKjB,EAAK7vE,OAAQ6vE,EAAKx6B,KAAK,GAChC27B,EAAkBN,EAAKb,EAAKoB,SAE5BP,EAAI7zB,QAAUgzB,EAAKhzB,SAAW1hD,EAAOw6C,QAAQ+N,SAAS7G,QACtD6zB,EAAIQ,mBAAqBR,EAAIS,UAAYT,EAAIU,QAAUZ,CAEvD,IAAIG,GAAWU,EAAgBX,EAE/B,IAAIb,EAAK4D,OACL/C,EAAIY,KAAK8B,OACR,CACD,GAAIM,GAAW,GAAIC,SACnBD,GAASnyD,OAAO,OAAQ6xD,GACxB1C,EAAIY,KAAKoC,GAKb,MAFAnC,GAAiB1mE,KAAK6lE,GAEfC,EAASP,QASpB,QAASwD,KACDriE,GAAYA,EAAW7L,UAC3BiwC,EAAQ/5B,YAAa,EAIzB,QAASi4D,GAAsBj5D,EAAUiiC,GACrCjiC,EAAWtf,EAAEwrC,KAAKlsB,GACdiiC,GACAvhD,EAAEw4E,MAAMl5D,EAAUiiC,EAAS,WAE3B00B,EAAiBz2E,OACjByW,EAAWu1B,KAAK,oBAAqBlsB,GAErCtf,EAAEoQ,MAAMkP,GAvShB,GAAItf,GAAId,EAAQ,aACVwqB,EAAQxqB,EAAQ,WAChBW,EAASX,EAAQ,aACjBkD,EAASlD,EAAQ,YACjBsX,EAAYtX,EAAQ,eAE1BQ,GAAOJ,QAAU+6C,CAGjB,IAAI47B,MAEAM,EAAc3B,EAAsB,QACpC4B,EAAe5B,EAAsB,QAwHzC50E,GAAEkD,OAAOm3C,GACLzzC,IAAKmwE,EACLz8B,KAAM08B,EACNyB,KAAMxB,EACNyB,MAAOtB,EACPc,KAAML,EACN/gE,aAAcggE,EACd1sE,QAASkuE,EACTC,sBAAuBA,GAI3B,IAAItiE,GAgCA0hE,GAAiBjzE,OAAQ,MAAOg0E,OAAO,KA0HxCvyE,YAAY,GAAG4Q,eAAe,GAAG8sD,UAAU,GAAGkH,WAAW,IAAIxqE,YAAY,MAAMo4E,KAAK,SAASz5E,EAAQQ,GACxG,YAsBA,SAASk5E,GAAcn+C,GACnB,OAAM36B,eAAgB84E,GACX,GAAIA,GAAcn+C,IAC7B36B,KAAKuvB,OAASoL,GAAOpL,WACrBvvB,MAAKK,QAsGT,QAAS04E,KACL/4E,KAAKgyB,UAAYhyB,KAAKuvB,OAAO0C,eACzBjyB,KAAKgyB,UAAUgnD,aACfh5E,KAAKolE,MAAQplE,KAAKgyB,UAAUinD,WAAW,IAC3Cj5E,KAAKkyB,YAAclyB,KAAKgyB,UAAUE,YAUtC,QAASgnD,KACL,MAAMl5E,MAAKolE,OAELplE,KAAKm5E,QACPn5E,KAAKm5E,MAAQn5E,KAAKolE,MAAMgU,YAErBp5E,KAAKm5E,OALanxE,OAe7B,QAASqxE,KACL,MAAMr5E,MAAKolE,OAELplE,KAAKs5E,aACPt5E,KAAKs5E,WAAaC,EAAc95E,KAAKO,OAClCA,KAAKs5E,YAJatxE,OAQ7B,QAASwxE,KACLx5E,KAAKgyB,UAAUyzC,kBAUnB,QAAS8T,KAEL,GAAIE,KAEJ,IAAIz5E,KAAKkyB,YACL,MAAOunD,EAWX,KARA,GAAIC,GAAW15E,KAAKolE,MAAMmF,eACpBoP,EAAS35E,KAAKolE,MAAMuM,aACpBtH,EAAiBrqE,KAAKolE,MAAM6B,wBAE9Bz1C,EAAaxxB,KAAKuvB,OAAOviB,SAASykB,iBAAiB44C,EAAgB34C,WAAWe,WAC9ElrB,EAAOiqB,EAAWI,YAAc8nD,EAG7BnyE,KAAWqyE,GAASD,EAAOvuD,SAAS7jB,KAAQ,CAC/CkyE,EAAUhqE,KAAKlI,EACf,IAAIqyE,GAAQA,GAASD,EAAOvuD,SAAS7jB,EACrCA,GAAOiqB,EAAWK,WAEtB,MAAO4nD,GAWX,QAASI,GAAYC,EAAcC,GAC/B,MAAM/5E,MAAKolE,OAEsB,mBAAtBplE,MAAK85E,KACZ95E,KAAK85E,GAAgB7U,EAAkBjlE,KAAKolE,MAAM2U,KAC/C/5E,KAAK85E,IAJa9xE,OAe7B,QAASgyE,GAAcF,EAAcG,GACjC,MAAMj6E,MAAKolE,OAEsB,mBAAtBplE,MAAK85E,KACZ95E,KAAK85E,GAAgBvuE,EAAUgP,uBAAuBva,KAAKi6E,OACxDj6E,KAAK85E,IAJa9xE,OAQ7B,QAASkyE,KACL,GAAIl6E,KAAKm6E,qBACL,MAAOn6E,MAAKm6E,oBAEhB;GAAIrhD,GAAa94B,KAAKm6E,uBAEtB,OAAIn6E,MAAKkyB,cAAiBlyB,KAAKolE,MAActsC,EAEtCwxC,EAAuBtqE,KAAKolE,OAIvC,QAASgV,GAAqC56D,EAAU9O,GACpD,IAAI1Q,KAAKkyB,aAAiBlyB,KAAKolE,MAA/B,CAEA,GAAItsC,GAAa94B,KAAKq6E,qBAEtBvhD,GAAW5zB,QAAQsa,EAAU9O,IAUjC,QAAS4pE,GAAkBC,GACvB,IAAIv6E,KAAKkyB,aAAiBlyB,KAAKolE,MAA/B,CAEA,GAAIoV,GAAWx6E,KAAKy6E,6BAA6BF,EAEjD/P,GAA0BxqE,KAAKolE,OAE/BplE,KAAK06E,mBAAmBF,GACxBA,EAASjzE,KAAK+X,WAAW8oD,aAI7B,QAASqS,GAA6BF,GAClC,GAAIxI,GAAU/xE,KAAKolE,MAAMmF,eACrBoQ,EAAY36E,KAAKolE,MAAMmB,WAK3B,OAJIgU,IAAsBv6E,KAAKolE,MAAMmF,gBAAkBvqE,KAAKolE,MAAMuM,eAC9DI,EAAU/xE,KAAKolE,MAAMuM,aACrBgJ,EAAY,IAEPpzE,KAAMwqE,EAAS6I,OAAQD,GAIpC,QAASD,GAAmBF,GACxB,GAAIzI,GAAUyI,EAASjzE,KACjBozE,EAAYH,EAASI,MAE3B,IAAK7I,EAAL,CACIA,EAAQ/M,UAAYH,KAAKwD,YACzB0J,EAAQ1/C,YAAc0/C,EAAQ1/C,YAAYwoD,aACzC9I,EAAQj/C,YACTi/C,EAAQj/C,UAAY,IAExB,IAAIzjB,GAAWsrE,EAAY5I,EAAQryE,OAASqyE,EAAQryE,OAASi7E,CAC7D1U,GAAiB8L,EAAS1iE,IAS9B,QAASyrE,KACL,MAAO96E,MAAKolE,MAOhB,QAAS2V,GAAuBhzC,GAC5B,GAAIhpC,GAAIiB,KAAKolE,MACT3e,EAAM1e,EAAOo9B,cACXxqC,EAAM8rB,EAAIijB,aAAejjB,EAAIkjB,YACnC,OAAK5qE,GACE+5E,EAAckC,kBAAkBjzC,EAAQhpC,EAAEwrE,eAAgBxrE,EAAEwnE,YAAaxnE,EAAE4yE,aAAc5yE,EAAEynE,YADjFj3C,OAAQoL,GAK7B,QAASsgD,GAAiClzC,EAAQwiC,EAAgBhE,EAAaoL,EAAcnL,GACzFmL,EAAeA,GAAgBpH,EAC/B/D,EAAYA,GAAaD,CACzB,IAAI9f,GAAM1e,EAAOo9B,cACXxqC,EAAM8rB,EAAIijB,aAAejjB,EAAIkjB,YACnC,QACIp6C,OAAQoL,EACRoN,OAAQA,EACR1rB,MAAO6+D,EAAwBnzC,EAAQwiC,EAAgBhE,GACvDgL,IAAK2J,EAAwBnzC,EAAQ4pC,EAAcnL,IAK3D,QAAS0U,GAAwBnzC,EAAQxgC,EAAMqzE,GAC3C,GAAI/6D,GAAW3E,EAASyE,WAAWooB,EAAQxgC,EAE3C,OADMsY,IAAUvd,EAAOC,MAAM,+CAEzBsd,SAAUA,EACV+6D,OAAQA,GAQhB,QAASO,GAA+BhjE,GACpC,GAAI+C,GAAW/C,EAAMoX,OAAOnnB,KAAKC,KAAK4Q,GAEtC,MAAId,EAAM4vB,QAAU5vB,EAAMkE,OAASlE,EAAMo5D,KAYrC,MADAr2D,GAASmsD,eAAelvD,EAAMoX,QACvB,GAAIupD,GAAc3gE,EAAMoX,OAX/B,IAAIkiD,GAAY2J,EAAwBjjE,EAAM4vB,OAAQ5vB,EAAMkE,OACtDq1D,EAAU0J,EAAwBjjE,EAAM4vB,OAAQ5vB,EAAMo5D,IAE5D,KAEI,MADAr2D,GAAS8qD,aAAayL,EAAWt5D,EAAMkE,MAAMu+D,OAAQlJ,EAASv5D,EAAMo5D,IAAIqJ,QACjE,GAAI9B,GAAc3gE,EAAMoX,QACjC,MAAM3wB,GACJ0D,EAAOC,MAAM,yCAA2C3D,EAAGA,EAAEyD,UASzE,QAAS+4E,GAAwBrzC,EAAQszC,GACrC,GAAI9zE,GAAO2T,EAAS6E,kBAAkBgoB,EAAQszC,EAAWx7D,SAEzD,OADMtY,IAAMjF,EAAOC,MAAM,sDAClBgF,EAYX,QAAS+zE,GAA+BlW,EAAO0B,GAC3C,GAEMyU,GAFF5gD,EAAMyqC,EAAMmF,eAAepF,cAAcuE,YACvClE,EAAM7qC,EAAI1I,cAgBhB,OAbAuzC,GAAIC,kBAEAqB,GACAyU,EAAWnW,EAAMoW,aACjBD,EAASvU,UAAS,GAElBxB,EAAIE,SAAS6V,GACb/V,EAAIpiE,OAAOgiE,EAAMmF,eAAgBnF,EAAMmB,cAGvCf,EAAIE,SAASN,GAGV,GAAI0T,GAAcn+C,GAW7B,QAAS8gD,KACL,GACM3S,GAAIl2C,EADN6zB,EAAMzmD,KAAKolE,MAAM6B,wBAAwB9B,cAEvCuW,EAAW17E,KAAKolE,MAAMoW,YAS5B,OAPIE,GAAS/J,aAAa3M,WAAaH,KAAKwD,YACxCS,EAAKriB,EAAIh1B,iBAAiBg1B,EAAIx5C,KAAMykB,WAAWe,WAC/Cq2C,EAAGl3C,YAAc8pD,EAAS/J,aAC1B/+C,EAAek2C,EAAGl2C,eAClB8oD,EAAS3U,OAAOn0C,EAAcA,EAAalzB,SAGxCg8E,EAUX,QAASC,KACL,MAAOzgE,GAASkrD,sBAAsBpmE,KAAKgyB,WAjb/C,GAAI9W,GAAW9b,EAAQ,UACjB6lE,EAAoB/pD,EAAS+pD,kBAC7BgB,EAAmB/qD,EAAS+qD,iBAC5BqE,EAAyBpvD,EAASovD,uBAClCE,EAA4BtvD,EAASsvD,0BACrCloE,EAASlD,EAAQ,aACjBmM,EAAYnM,EAAQ,4BACpBc,EAAId,EAAQ,YAElBQ,GAAOJ,QAAUs5E,CAwBjB,IAAI8C,GACA17E,EAAEqkB,QAAQs1D,EAAa,gBAAiB,kBASxCgC,EACA37E,EAAEqkB,QAAQs1D,EAAa,cAAe,gBAStCiC,EACA57E,EAAEqkB,QAAQs1D,EAAa,qBAAsB,2BAS7CkC,EACA77E,EAAEqkB,QAAQy1D,EAAe,kBAAmB,gBAS5CgC,EACA97E,EAAEqkB,QAAQy1D,EAAe,gBAAiB,cAS1CiC,EACA/7E,EAAEqkB,QAAQy1D,EAAe,uBAAwB,oBAGrD95E,GAAEM,YAAYs4E,GACVz4E,KAAM04E,EACN5mD,KAAM+mD,EACNO,UAAWJ,EACX6C,MAAO1C,EAEP2C,aAAcP,EACdQ,WAAYP,EACZ5W,kBAAmB6W,EAEnBO,eAAgBN,EAChBO,aAAcN,EACdO,oBAAqBN,EAErB5B,oBAAqBH,EACrBsC,uBAAwBpC,EACxB7vD,IAAK+vD,EACLG,6BAA8BA,EAC9BC,mBAAoBA,EAEpB+B,SAAU3B,EACV1iE,SAAU2iE,EACV2B,mBAAoBjB,EACpBkB,aAAchB,IAIlBz7E,EAAEkD,OAAO01E,GACL8D,gBAAiBtB,EACjB7iE,gBAAiB0iE,EACjBH,kBAAmBC,MAgUpB4B,2BAA2B,GAAGC,SAAS,GAAGC,YAAY,IAAIt8E,YAAY,MAAMu8E,KAAK,SAAS59E,EAAQQ,GACrG,YAgCA,SAASkY,GAAWmlE,EAAWC,EAAaviD,GACnB,mBAAVpL,UACXoL,EAAMA,GAAOpL,OAEb0tD,EAAYl9E,EAAO0nD,WAAWG,MACjBq1B,EACKA,EAAYl9E,EAAO0nD,WAAWE,gBAC9B,IAElBznD,EAAEuB,iBAAiBzB,MACfi9E,UAAWA,EACXC,cAAgBA,EAChB3tD,OAAQoL,EACRwiD,SAAUD,EAAcviD,EAAIyiD,eAAiBziD,EAAI0iD,aACjDC,YAAav9E,EAAO0nD,WAAWC,WAC/B61B,UACDr9E,EAAE6E,OAmDT,QAASy4E,GAAep9D,GACpB,GAAmB,gBAARA,GACPlgB,EAAEqB,QAAQ6e,EAAM,SAAShf,EAAOioB,GAC5BrpB,KAAKy9E,QAAQp0D,EAAKjoB,IACnBpB,UACF,CACD,GAAIqsB,GAAU9rB,UAAUb,MACxB,IAAI2sB,EAAU,EACV,KAAM,IAAIqxD,iBAAgB,iEAE9B,KAAK,GAAIr+E,GAAI,EAAOgtB,EAAJhtB,EAAaA,IAAK,CAC9B,GAAIgqB,GAAM9oB,UAAUlB,GACd+B,EAAQb,YAAYlB,EAE1BW,MAAKy9E,QAAQp0D,EAAKjoB,KAY9B,QAASu8E,KACL,GAAIv9D,KAIJ,OAHAlgB,GAAE09E,YAAYr9E,UAAW,SAAS8oB,GAC9BjJ,EAAKiJ,GAAOrpB,KAAK69E,QAAQx0D,IAC1BrpB,MACIogB,EASX,QAAS09D,KACL59E,EAAE09E,YAAYr9E,UAAW,SAAS8oB,GAC9BrpB,KAAK87B,WAAWzS,IACjBrpB,MAUP,QAAS+9E,GAAmB10D,GACxB,GAAI20D,GAAOh+E,KAAKi+E,YAAY50D,EAC5B,OAAsC,OAA/BrpB,KAAKm9E,SAASU,QAAQG,GAWjC,QAASE,GAAmB70D,GACxB,GAAI20D,GAAOh+E,KAAKi+E,YAAY50D,GACxB9N,EAAW4iE,EAAgB1+E,KAAKO,KAAMg+E,GACtC7pB,EAAWn0D,KAAKm9E,SAASU,QAAQG,GACjC58E,EAAQg9E,EAAWjqB,EAAU54C,EACjC,OAAOna,GAWX,QAASi9E,GAAmBh1D,EAAKjoB,GAC7B,GAAI48E,GAAOh+E,KAAKi+E,YAAY50D,GACxB9N,EAAW+iE,EAAgB7+E,KAAKO,KAAMg+E,EAAM58E,GAC5C+yD,EAAWoqB,EAAen9E,EAAOma,EACrC,KACIvb,KAAKm9E,SAASM,QAAQO,EAAM7pB,GAC9B,MAAMv1D,GACJ,GAAc,sBAAVA,EAAEqB,KAOF,KAAMrB,EANN,IAAI4/E,GAAMz+E,EAAO0nD,WAAWM,aAG5B,IAFIy2B,EAAIn8E,SACJ+F,KAAKsnD,KAAKt5C,YAAY,qBAAsBhV,GAC5Co9E,EAAIx2B,WACJ,KAAMppD,GAIlBoB,KAAKu9E,MAAMl0D,IAAO,EAClBo1D,EAAYz+E,KAAKk9E,aAAaK,MAAMS,IAAQ,EAWhD,QAASU,GAAsBr1D,GAC3B,GAAI20D,GAAOh+E,KAAKi+E,YAAY50D,EAC5BrpB,MAAKm9E,SAASrhD,WAAWkiD,GACzBW,EAAmBl/E,KAAKO,KAAMg+E,SACvBh+E,MAAKu9E,MAAMl0D,SACXo1D,GAAYz+E,KAAKk9E,aAAaK,MAAMS,GAS/C,QAASY,KACL,GAAIC,GAAar9E,OAAO+V,KAAKvX,KAAKu9E,OAC9BuB,EAAgBD,EAAWviC,OAAO,SAASjzB,GAC3C,MAAIrpB,MAAK++E,QAAQ11D,IAAa,aAClBrpB,MAAKu9E,MAAMl0D,IACxBrpB,KACH,OAAO8+E,GASX,QAASE,KACL,MAAOh/E,MAAK8G,IAAI9G,KAAKi/E,cAUzB,QAASC,GAAuB71D,GAC5B,MAAOrpB,MAAKi9E,UAAY5zD,EAW5B,QAAS81D,GAA0BC,GAC/B,MAAIA,GAAW/6D,QAAQrkB,KAAKs9E,cAAgB,EAA5C,OACOp9E,EAAEs3D,SAAS4nB,EAAYp/E,KAAKi9E,WAUvC,QAASkB,GAAgBH,GAErB,MADAA,GAAOqB,EAAa5/E,KAAKO,KAAMg+E,GACxBh+E,KAAKm9E,SAASU,QAAQG,GAYjC,QAASM,GAAgBN,EAAM58E,GAC3B,GAAIma,GAAW+jE,EAAcl+E,EAG7B,OAFA48E,GAAOqB,EAAa5/E,KAAKO,KAAMg+E,GAC/Bh+E,KAAKm9E,SAASM,QAAQO,EAAMziE,GACrBA,EASX,QAASojE,GAAmBX,GACxBA,EAAOqB,EAAa5/E,KAAKO,KAAMg+E,GAC/Bh+E,KAAKm9E,SAASrhD,WAAWkiD,GAU7B,QAASqB,GAAarB,GAClB,MAAOA,GAAOh+E,KAAKs9E,YASvB,QAASgC,GAAcl+E,GACnB,GAAIm+E,SAAmBn+E,GACjByW,EAAYzW,GAASA,EAAMhB,YAAYH,KACvCsb,EAAWikE,EAAgB3nE,EACjC,OAAO0D,KACc,UAAbgkE,EACMA,EACS,MAATn+E,EACI,OACAA,EAAMhB,YAAYH,MAcxC,QAASs+E,GAAen9E,EAAOm+E,GAC3BA,EAAYA,GAAaD,EAAcl+E,EACvC,IAAIq+E,GAAaC,EAAgBH,EACjC,OAAOE,GACGA,EAAWr+E,EAAOm+E,GAClBn+E,GAASA,EAAMg4E,UAAY53E,OAAOY,UAAUg3E,SACxC/gE,KAAKC,UAAUlX,GACf,GAAKA,EAcvB,QAASg9E,GAAWjqB,EAAUorB,GAC1B,GAAII,GAASC,EAAYL,EACzB,OAAOI,GACGA,EAAOxrB,EAAUorB,GACjBprB,EAqBd,QAAS0rB,GAA6BN,EAAWE,EAAYE,EAAQG,GAC7DL,IAAYC,EAAgBH,GAAaE,GACzCE,IAAQC,EAAYL,GAAaI,GACrCH,EAAgBD,GAAaO,GAAmBP,EAIpD,QAASQ,KACL,GAAIC,GAAuB,GAAIC,GAAqBjgF,MAChDkc,EAAY,GAAIxF,GAAU1W,KAAMgI,OAAWg4E,EAC/C9/E,GAAEuB,iBAAiBzB,MACfmW,WAAY+F,EACZivC,eAAgB60B,GACjB9/E,EAAE6E,MAIT,QAASm7E,KACLlgF,KAAKm9E,SAAWn1E,OAChBhI,KAAKuvB,OAASvnB,OACVhI,KAAKmW,YAAYnW,KAAKmW,WAAW7L,UACrCtK,KAAKwgB,YAAa,EAzZtB,CAAA,GACM9J,IADgBtX,EAAQ,YAAY2wE,YAAY,mBACpC3wE,EAAQ,oBACpB6gF,EAAuB7gF,EAAQ,aAC/BW,EAASX,EAAQ,gBACjBoZ,EAAYpZ,EAAQ,iBACpBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,WACR0C,GAAME,MAEpB5C,EAAQ,WAERQ,EAAOJ,QAAUsY,CAIjB,IAAIqoE,IACAC,UACAC,WAgCJngF,GAAEM,YAAYsX,GACVhR,IAAK62E,EACLvzE,IAAKozE,EACLz2E,OAAQ+2E,EACRiB,QAAShB,EACTF,QAASK,EACTT,QAASY,EACTviD,WAAY4iD,EACZT,YAAaiB,EACboB,eAAgBnB,EAChBF,WAAYL,EACZ2B,YAAavB,EACbwB,gBAAiBT,EACjBz1E,QAAS41E,IAObxpE,EAAUtQ,QAAQ0R,EAAY,aAAcpB,EAAUC,gBACtDspE,EAAqB75E,QAAQ0R,EAAY,kBAAmB,WAG5D,IAAI2oE,GAAkB,GAAI3oE,GAAW,IAAI,GACnC4oE,EAAgB,GAAI5oE,GAAW,IAAI,GAErC2mE,GACI2B,OAAMK,EACNJ,QAAOK,EAGfxgF,GAAEkD,OAAO0U,GACLC,iBAAkB8nE,EAClBc,MAAOD,EACPE,QAASH,EACT5N,QAAS4L,EACT0B,YAAaA,GAoPjB,IAAIX,MAqBAE,GACA16E,MAASqT,KAAKC,WAiBdsnE,GACAp+E,OAAQgX,EACRxT,MAAOwT,EACPqoC,KAAM,SAASggC,GAAU,MAAO,IAAIhgC,MAAKggC,IACzCC,UAAS,SAASD,GAAU,MAAiB,QAAVA,GACnCE,OAAQ,SAASF,GAAU,MAAOjiC,QAAOiiC,IACzCG,WAAU,SAASH,GAAU,MAAO3gF,GAAE+gF,WAAWJ,IACjDp2B,OAAQ,SAASo2B,GAAU,MAAO3gF,GAAEghF,SAASL,OAoC9CrtD,eAAe,GAAGpF,kBAAkB,GAAG+yD,WAAW,GAAGC,WAAW,GAAGC,gBAAgB,IAAIC,UAAU,IAAIC,YAAY,IAAI9gF,YAAY,MAAM+gF,KAAK,SAASpiF,GACxJ,YAOA,SAAS40D,KACL,GAAIl8C,GAAa1Y,EAAQ,UACzB0Y,GAAWC,iBAAiB,QAASk8C,EAA4BC,GACjEp8C,EAAWC,iBAAiB,YAAak8C,EAA4BC,EAAwB,SAIjG,QAASD,GAA2B7yD,GAChC,GAAIgf,GAAOhf,EAAM0F,KACjB,OAAOuR,MAAKC,UAAU8H,GAI1B,QAAS8zC,GAAuBC,GAC5B,GAAI/zC,GAAOlgB,EAAEsY,UAAU27C,EACvB,OAAO,IAAIj0B,GAAM9f,GApBrB,GAAI8f,GAAQ9gC,EAAQ,aAAa8gC,KAEjCA,GAAMu0B,uBAAyBT,IAqB5BhiD,UAAU,IAAI0+C,YAAY,MAAM+wB,KAAK,SAASriF,EAAQQ,GACzD,YA2BA,SAASS,GAAK8D,GACV,GAAmC,cAA/BA,EAAW/D,YAAYH,KACvB,KAAM,IAAIyhF,GAA0B,iDACxC1hF,MAAK6yE,QAAU1uE,EACfnE,KAAK6nD,WAAa9nD,EAAO0nD,WAAWI,WACpC7nD,KAAKuvB,OAASprB,EAAWorB,OACzBxhB,EAAc3L,UAAU/B,KAAKC,MAAMN,KAAMO,WAI7C,QAASohF,KACL3hF,KAAKuvB,OAAOmY,iBAAiB,UAAW1nC,MAAM,GAIlD,QAAS4hF,KACL5hF,KAAKuvB,OAAOqY,oBAAoB,UAAW5nC,MAAM,GAIrD,QAAS6hF,GAAiCx/E,EAAS+d,GAC/CpgB,KAAKkc,UAAU1P,gBAAgBnK,EAAS+d,GAI5C,QAAS0hE,GAA6Bj6D,EAASzH,GAC3C,GAAIiJ,GAAMrpB,KAAK6nD,WAAahgC,CAC5BzH,GAAOA,MACPA,EAAKrgB,EAAO0nD,WAAWK,kBAAoBhY,IAC3C5vC,EAAEmQ,YAAYrQ,KAAK6yE,QAAS,UAAWxpD,EAAKjJ,GAIhD,QAASynB,GAAYxS,GACjB,GAAIA,EAAM0sD,aAAe/hF,KAAK6yE,QAAQsK,SAAtC,CACA,GAAI9zD,GAAMrpB,KAAK6yE,QAAQyN,eAAejrD,EAAMhM,IAAM,IAAMA,EAAN,CAClD,GAAIxB,GAAU3nB,EAAEs3D,SAASnuC,EAAKrpB,KAAK6nD,WAAa,IAAMhgC,EAAN,CAChD,GAAIzH,GAAOpgB,KAAK6yE,QAAQgL,QAAQx0D,EAAYjJ,IAC5CpgB,KAAK8jB,gBAAgB+D,EAASzH,MA9DlC,GAAIrS,GAAgB3O,EAAQ,4BACtBc,EAAId,EAAQ,aACZW,EAASX,EAAQ,gBACjB0wC,EAAY1wC,EAAQ,oBACpBsiF,EAA4BtiF,EAAQ,oBAAoB6gF,qBAE1DA,EAAuB//E,EAAEwD,eAAeqK,EAAe,wBAAwB,EAGnF7N,GAAEM,YAAYy/E,GAEV5/E,KAAMA,EACNonC,oBAAqBk6C,EACrBh6C,uBAAwBi6C,EACxBxrE,YAAayrE,EACb3zD,QAAS4zD,EAGTj6C,YAAaA,IAGjBjoC,EAAOJ,QAAUygF,IA4CdzsD,eAAe,GAAG4T,2BAA2B,GAAGsJ,mBAAmB,GAAGhd,mBAAmB,GAAGjzB,YAAY,MAAMuhF,KAAK,SAAS5iF,EAAQQ,GACvI,YAYA,SAAS2oD,KACL,GAAI05B,GAAc,GAAIvrE,GAClBwrE,EAAc,GAAIC,GAAgBF,GAAe/L,KAAM,UAAWkM,QAAS,WAAa,GAAIC,GAEhG,OADAJ,GAAYv+D,kBAAkBw+D,GACvBD,EATX,GAAIvrE,GAAYtX,EAAQ,mBAClB+iF,EAAkB/iF,EAAQ,aAC1BijF,EAAWjjF,EAAQ,YAWzBQ,GAAOJ,QAAU+oD,IAEdn6B,kBAAkB,GAAGk0D,YAAY,IAAIf,YAAY,MAAMgB,KAAK,SAASnjF,EAAQQ,GAChF,YAsBA,SAAS6kC,GAAyBpiC,GAC9B,MAAOmgF,GAAgBn+D,QAAQhiB,IAAY,EACjCA,EACA,UAId,QAASsiC,GAAoBC,EAAeviC,EAAS6lB,GACjD,GAAIs6D,EAAgBn+D,QAAQhiB,IAAY,EAAG,OAAO,CAClD,IAAqB,WAAjBuiC,EAA4B,CAC5B,GAAI/c,GAAUK,GAAWA,EAAQxM,IACjC,OAAOmM,IAAWxlB,GAK1B,QAASwiC,GAAmBD,EAAeviC,EAASgzB,GAChD,GAAIyP,GAAgC,WAAjBF,EACG1kC,EAAEsY,UAAU6c,EAAMjV,OAASiV,EAAMjV,KACjCiV,CACtB,OAAOyP,GAxCX,GAAI72B,GAAe7O,EAAQ,yBACrBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,oBAIlBijF,GAHUvgF,EAAME,MAGL9B,EAAEwD,eAAeuK,EAAc,YAAY,GAG1D/N,GAAEM,YAAY6hF,GACV59C,yBAA0BA,EAC1BE,oBAAqBA,EACrBE,mBAAoBA,IAGxBjlC,EAAOJ,QAAU6iF,CAGjB,IAAIG,IAAmB,OAAQ,QAAS,QAAS,aAyB9Cz9C,wBAAwB,GAAGtR,mBAAmB,GAAGhzB,YAAY,MAAMgiF,KAAK,SAASrjF,EAAQQ,GAC5F,YA8BA,SAAS8iF,GAAwB3kE,GAC7B/d,KAAKmzD,SAAWp1C,EAAUA,KAE1B,IAAI4kE,GAAO5kE,EAAQ4kE,MAAQpzD,OAAOqzD,SAASD,KAAKn6E,QAAQ,MAAO,IACzDq6E,EAAO9kE,EAAQ8kE,MAAQ,MAIzB7iF,MAAK8iF,MAEL9iF,KAAK8iF,IAAIC,OAAS/iF,KAAKgjF,GAAGC,UAAYjjF,KAAKgjF,GAAGE,QAAUljF,KAAKgjF,GAAGG,QAAUn7E,OAC1EhI,KAAK8iF,IAAIthC,SAGbxhD,KAAK8iF,IAAM,GAAIM,WAAU,QAAUT,EAAO,IAAME,GAOpD,QAASp7C,GAAqB7C,GAC1By+C,EAAoB5jF,KAAKO,KAAM,mBAAoB4kC,GAIvD,QAAS+C,GAAwB/C,GAC7By+C,EAAoB5jF,KAAKO,KAAM,sBAAuB4kC,GAI1D,QAASy+C,GAAqBz+E,EAAQggC,GAClC,MAAK5kC,MAAK8iF,QACV9iF,MAAK8iF,IAAIl+E,GAAQggC,EAAe5kC,MADVsC,EAAOC,MAAM,4BAMvC,QAAS+gF,GAA6BjuD,GAClCr1B,KAAK8jB,gBAAgBuR,EAAM3Z,KAAM2Z,GAIrC,QAASkuD,GAAyBrtE,EAAKkK,EAAMZ,GAiBzC,QAASgkE,KACLC,EAAsB,MAAOrjE,EAAKsjE,gBAClClkE,EAAS,GAAIlgB,OAAM,2BAGvB,QAASqkF,GAAWztE,EAAKgS,GAErB,GADAy1B,cAAcimC,GACQ,gBAAX17D,GAAqB,CAC5B,GAAIuyB,GAAMvyB,EAAQ3lB,MAAQ,GAAIjD,OAAM4oB,EAAQ3lB,OAAS,IACrDid,GAASi7B,EAAKvyB,EAAQ9H,UAEtBZ,GAAS,GAAIlgB,OAAM,wCAAyC4oB,GAGpE,QAASu7D,GAAsB/jC,EAAOmkC,GAClC/pD,EAAK5d,UAAUwjC,GAAO3/C,EAAOwoD,UAAUC,IAAIC,eAAiBo7B,EAAQF,GA/BxE,IAAK3jF,KAAK8iF,IAAK,MAAOxgF,GAAOC,MAAM,2BAEnC6d,GAAOA,MACPA,EAAK1E,KAAOxF,CAEZ,IAAI4jB,GAAO95B,IAEX,IAAIwf,EAAU,CACVY,EAAKsjE,eAAiBhR,GACtB,IAAIkR,GAAW1jF,EAAEw4E,MAAM8K,EAAWzjF,EAAOwoD,UAAUC,IAAI/G,QACvDgiC,GAAsB,OAAQrjE,EAAKsjE,gBAGvC1jF,KAAK8iF,IAAI5M,KAAK79D,KAAKC,UAAU8H,IApFjC,GAAIrS,GAAgB3O,EAAQ,4BACtBc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,qBACjBszE,EAAWtzE,EAAQ,oBACnBW,EAASX,EAAQ,gBACjB0C,EAAQ1C,EAAQ,oBAIlB+iF,GAHUrgF,EAAME,MAGE9B,EAAEwD,eAAeqK,EAAe,mBAAmB,GAGzE7N,GAAEM,YAAY2hF,GAEV16C,oBAAqBA,EACrBE,uBAAwBA,EAGxBE,YAAay7C,EACblB,QAASM,EACTx0D,QAASq1D,IAIb3jF,EAAOJ,QAAU2iF,IAkFd3uD,eAAe,GAAG4T,2BAA2B,GAAG3T,mBAAmB,GAAGid,mBAAmB,GAAGpqB,oBAAoB,IAAI7lB,YAAY,MAAMqjF,KAAK,SAAS1kF,EAAQQ,IAC9J,WAuCD,QAASmkF,KACL,GAAIC,GAAO,EACPC,EAAO,CAEXjkF,MAAKkkF,OAAS,GAIdlkF,KAAKmkF,SAAW,SAASC,GAUrB,MARmB,gBAARA,KAAkBA,EAAOA,EAAK5a,WAAW,IAEzC,EAAPwa,EACAC,GAASG,IAAUJ,EAEnBC,EAAQG,GAAQJ,EAAQ,IAGxBA,EAAO,GAEPA,GAAQ,EACD,IAGA,EAAPA,IAEAhkF,KAAKkkF,QAAUG,EAASJ,GAAQ,GAChCD,GAAQ,GAGL,IAIXhkF,KAAKskF,OAAS,SAASxiF,GACnB,GAAIoiF,GAASlkF,KAAKkkF,QAAiB,EAAPF,EAAWK,EAASJ,GAAQ,GAAK,KAAOniF,EAAQ,IAAM,GAElF,OADA9B,MAAKkkF,OAAS,GACPA,GA4Bf,QAASK,KACL,GAAIP,GAAO,EACPI,EAAO,CAEXpkF,MAAKkkF,OAAS,GAKdlkF,KAAKwkF,SAAW,SAASC,GACF,gBAARA,IACY,gBAARA,KACPA,EAAOviF,OAAOwiF,aAAaD,IAGnCA,EAAOA,EAAKl/C,aACZ,IAAIo/C,GAAMC,IAASH,EACD,oBAAPE,KAKXA,IAAQ,EACRP,GAAQO,IAAQX,EAChBA,GAAQ,EACJA,GAAQ,IAERhkF,KAAKkkF,QAAUhiF,OAAOwiF,aAAaN,GACnCJ,GAAQ,EACMI,EAAVJ,EAAO,EAAWW,GAAQ,EAAIX,EAAS,IAC/B,KAKpBhkF,KAAKskF,OAAS,SAASxiF,GACnB,GAAIoiF,GAASlkF,KAAKkkF,QAAiB,EAAPF,EAAWK,EAASJ,MAAQ,GAAK,KAAOniF,EAAQ,IAAM,GAElF,OADA9B,MAAKkkF,OAAS,GACPA,GAuBf,QAASlX,GAAOpnC,GACd,GAAIi/C,GAAU,GAAId,GACdG,EAASW,EAAQhqC,OAAOjV,GAAO,EACnC,OAAOs+C,GAIT,QAAS9W,GAAOxnC,GACZ,GAAIk/C,GAAU,GAAIP,GACdL,EAASY,EAAQjqC,OAAOjV,GAAO,EACnC,OAAOs+C,GA1KX,GAAIG,GAAW,mCACXU,GAAU9lF,EAAE,EAAGI,EAAE,EAAGssE,EAAE,EAAG3sE,EAAE,GAS3B4lF,EAAS,WAGT,IAAK,GAFDI,MAEK3lF,EAAI,EAAGA,EAAIglF,EAAS3kF,OAAQL,IACjC2lF,EAAMX,EAAShlF,IAAMA,CAGzB,KAAK,GAAIgqB,KAAO07D,GACPA,EAAMvhF,eAAe6lB,KAC1B27D,EAAM37D,GAAO27D,EAAM,GAAKD,EAAM17D,IAGlC,OADAu7D,GAAS,WAAa,MAAOI,IACtBA,EA8DXjB,GAAQ3hF,UAAUy4C,OAAS,SAASjV,EAAOq/C,GACvC,IAAK,GAAI5lF,GAAI,EAAGA,EAAIumC,EAAMlmC,QACtBL,GAAKW,KAAKmkF,SAASv+C,EAAMvmC,GAG7B,IAAI6kF,GAASlkF,KAAKkkF,MAKlB,OAJAlkF,MAAKkkF,OAAS,GACVe,IACFf,GAAUlkF,KAAKskF,UAEVJ,GA+CXK,EAAQniF,UAAUy4C,OAAS,SAASjV,EAAOq/C,GACvC,IAAK,GAAI5lF,GAAI,EAAGA,EAAIumC,EAAMlmC,OAAQL,IAC9BW,KAAKwkF,SAAS5+C,EAAMvmC,GAExB,IAAI6kF,GAASlkF,KAAKkkF,MAKlB,OAJAlkF,MAAKkkF,OAAS,GACVe,IACFf,GAAUlkF,KAAKskF,UAEVJ,EAuBX,IAAInX,IACAwX,QAASA,EACTR,QAASA,EACT/W,OAAQA,EACRI,OAAQA,EAGU,oBAAX79C,UAETA,OAAOw9C,OAASA,GAGI,mBAAXntE,IAA0BA,EAAOJ,UAE1CI,EAAOJ,QAAUutE,WAIbmY,KAAK,iBAMLC,KAAK,SAAS/lF,EAAQQ,IAK3B,WACA,YA+CA,SAASwlF,GAAYC,EAAGC,EAAOC,GAC9B,OAA0B,gBAAVD,GAAsBA,EAAQA,EAAMlM,YACnD5wE,QAAQ68E,EAAEG,QAAUxB,EAAM,SAAS/jD,EAAGwlD,EAAMC,EAAQtkF,GAcpD,MAb6B,KAAzBqkF,EAAKphE,QAAQ,UAChBohE,EAAOA,EAAKE,UAAU,IAEjBF,IAAQF,KACE,MAAXG,GACCL,EAAEO,cAAcxkF,EAAMoH,QAAQ68E,EAAEO,aAAc,SAAS3lD,EAAG4lD,EAAOC,GACpEP,EAAIE,IAASM,IAAKF,EAAO1zD,KAAM2zD,KAE1BL,IAAQF,KAAMA,EAAIE,GAAOrkF,IAE/B,GAAIW,UAAS,MAAO,QAAQ0jF,EAAK,MAAQrkF,GAAOmkF,IAG3C,KAEP/8E,QAAQ68E,EAAEW,KAAOhC,EAAM,SAAS/jD,EAAGwlD,GAC/BJ,EAAEY,YAAWR,EAAOA,EAAKj9E,QAAQ68E,EAAEY,UAAW,SAAShmD,EAAGjhC,EAAGknF,EAAGL,GACnE,GAAIN,EAAIW,IAAMX,EAAIW,GAAGH,KAAOF,EAAO,CAClC,GAAIM,IAAMD,EAAE,IAAIL,GAAOr9E,QAAQ,QAAS,IAGxC,OAFA+8E,GAAIa,MAAQb,EAAIa,UAChBb,EAAIa,MAAMD,GAAMZ,EAAIW,GAAG/zD,KAAK3pB,QAAQ,GAAIiiD,QAAO,cAAgB86B,EAAIW,GAAGH,IAAM,YAAa,KAAM,KAAOF,EAAQ,MACvG7mF,EAAI,cAAcmnF,EAAG,QAG9B,IAAIL,GAAI,GAAI/jF,UAAS,MAAO,UAAY0jF,GAAMF,EAC9C,OAAOO,GAAIV,EAAYC,EAAGS,EAAGP,GAAOO,IAItC,QAASO,GAASZ,GACjB,MAAOA,GAAKj9E,QAAQ,YAAa,MAAMA,QAAQ,YAAa,KA9E7D,GAoBG89E,GApBCt3D,GACHu3D,QAAS,QACTtqB,kBACCuqB,SAAa,4BACbvlD,YAAa,uBACb+rC,OAAa,uBACbgZ,IAAa,uBACbC,UAAa,0GACbT,OAAa,+CACbI,aAAa,yBACba,YAAa,mCACbC,QAAa,2EACbC,QAAS,KACTzqB,OAAQ,EACR/1C,QAAS,EACTygE,eAAe,EACfC,kBAAkB,GAEnB5sE,SAAUjS,OACVs1B,QAAUt1B,OAGXgnB,GAAI83D,iBAAmB,SAASD,GAC/B,GAAIE,IAAoBC,IAAK,QAASC,IAAK,QAASC,IAAK,QAASC,IAAK,QAASC,IAAK,QAASC,IAAK,SAClGC,EAAYT,EAAmB,aAAe,yBAC/C,OAAO,UAASpB,GACf,MAAOA,GAAOA,EAAKrM,WAAW5wE,QAAQ8+E,EAAW,SAASrnD,GAAI,MAAO8mD,GAAgB9mD,IAAMA,IAAO,KAIpGqmD,EAAY,WAAY,MAAOtmF,QAAS,EAAEq7D,MAAM,WAE1B,mBAAXz7D,IAA0BA,EAAOJ,QAC3CI,EAAOJ,QAAUwvB,EACW,kBAAXw2D,SAAyBA,OAAO+B,IACjD/B,OAAO,WAAW,MAAOx2D,KAEzBs3D,EAASt3D,IAAMA,CAGhB,IAAIw4D,IACHrhE,QAAU9J,MAAO,MAAYk1D,IAAK,MAAYkW,YAAa,iBAC3D3/E,OAAUuU,MAAO,WAAYk1D,IAAK,WAAYkW,YAAa,uBACzDzD,EAAO,IAsCVh1D,GAAI/U,SAAW,SAASkiD,EAAMkpB,EAAGE,GAChCF,EAAIA,GAAKr2D,EAAIitC,gBACb,IAAuDyrB,GAAyBC,EAA5EC,EAAMvC,EAAEl/D,OAASqhE,EAASrhE,OAASqhE,EAAS1/E,MAAuB+/E,EAAM,EAC5E/xB,EAAQuvB,EAAEW,KAAOX,EAAEG,OAAUJ,EAAYC,EAAGlpB,EAAMopB,OAAappB,CAEhErG,IAAO,aAAeuvB,EAAEnpB,MAAQpG,EAAIttD,QAAQ,iCAAiC,KACzEA,QAAQ,6BAA6B,IAAKstD,GAC5CttD,QAAQ,QAAS,QACjBA,QAAQ68E,EAAEpkD,aAAe+iD,EAAM,SAAS/jD,EAAGwlD,GAC3C,MAAOmC,GAAIvrE,MAAQgqE,EAASZ,GAAQmC,EAAIrW,MAExC/oE,QAAQ68E,EAAErY,QAAUgX,EAAM,SAAS/jD,EAAGwlD,GAEtC,MADAiC,IAAiB,EACVE,EAAIH,YAAcpB,EAASZ,GAAQmC,EAAIrW,MAE9C/oE,QAAQ68E,EAAEoB,aAAezC,EAAM,SAAS/jD,EAAG6nD,EAAUrC,GACrD,MAAOqC,GACLrC,EAAO,cAAgBY,EAASZ,GAAQ,WAAa,iBACrDA,EAAO,QAAUY,EAASZ,GAAQ,WAAa,cAEjDj9E,QAAQ68E,EAAEqB,SAAW1C,EAAM,SAAS/jD,EAAGymD,EAASqB,EAAOC,GACvD,MAAKtB,IACLmB,GAAK,EAAGF,EAAKK,GAAS,IAAIH,EAAKnB,EAAQL,EAASK,GACzC,YAAYmB,EAAI,IAAInB,EAAQ,UAAUmB,EAAI,SAASE,EAAM,IAAIJ,EAAK,QAAQE,EAAI,OAAOA,EAAI,mBAAmBF,EAAK,KAAKE,EAAI,KAC/HE,EAAM,OAAOF,EAAI,IAAIF,EAAK,eAHP,iBAKrBn/E,QAAQ68E,EAAEmB,UAAYxC,EAAM,SAAS/jD,EAAGwlD,GACxC,MAAO,KAAOY,EAASZ,GAAQ,WAE9B,iBACDj9E,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAAOA,QAAQ,MAAO,OAC3DA,QAAQ,2BAA4B,MAAMA,QAAQ,QAAS,IAGzDk/E,IACErC,EAAEuB,gBAAiBN,GAAaA,EAAS2B,cAAa3B,EAAS2B,YAAcj5D,EAAI83D,iBAAiBzB,EAAEwB,mBACzG/wB,EAAM,wEACH9mC,EAAI83D,iBAAiB1N,WAAa,KAAOiM,EAAEwB,kBAAoB,IAAM,MACrE/wB,EAEJ,KACC,MAAO,IAAI/zD,UAASsjF,EAAEsB,QAAS7wB,GAC9B,MAAOl3D,GAER,KADuB,mBAAZ+1E,UAAyBA,QAAQD,IAAI,yCAA2C5e,GACrFl3D,IAIRowB,EAAIsO,QAAU,SAAS6+B,EAAMopB,GAC5B,MAAOv2D,GAAI/U,SAASkiD,EAAM,KAAMopB,YAI5B2C,KAAK,SAAS9oF,EAAQQ,GAsC5B,QAASuoF,GAAYlpF,GACpBe,KAAKooF,OAAWnpF,EAAE6lB,MAAQ,KACgB,MAAtC9kB,KAAKooF,OAAOpoF,KAAKooF,OAAO1oF,OAAO,KAAYM,KAAKooF,QAAU,KAC9DpoF,KAAKqoF,cAAgBppF,EAAEqpF,aAAetoF,KAAKooF,OACa,MAApDpoF,KAAKqoF,cAAcroF,KAAKqoF,cAAc3oF,OAAO,KAAYM,KAAKqoF,eAAiB,KACnFroF,KAAKuoF,SAAYtpF,EAAEm+D,QAAU,gBAC7Bp9D,KAAKwoF,eAAiBvpF,EAAEwpF,iBACxBzoF,KAAK0oF,WAAczpF,EAAEg9D,iBAAmB/iD,EAAKja,EAAEg9D,iBAAkB/iD,EAAK8V,EAAIitC,mBAAqBj0D,OAC/FhI,KAAK2oF,cAuCN,QAASC,GAAWppF,GACnB,IAAK,GAAIqpF,GAAK,GAAIxpF,EAAE,EAAGA,EAAGG,EAAQE,OAAQL,IACzCwpF,GAAO,UAAYrpF,EAAQH,GAAI,IAAMG,EAAQH,GAAG,GAEjD,OAAOwpF,GAGR,QAAS3vE,GAAKja,EAAGy0C,GAChBA,EAAKA,KACL,KAAK,GAAIlmB,KAAYvuB,GACpBy0C,EAAGlmB,GAAYvuB,EAAEuuB,EAElB,OAAOkmB,GAGR,QAASo1C,GAAShkE,GACjB,GAAI1E,GAAOk7C,EAAGytB,aAAajkE,EAC3B,OAAI1E,GAAaA,EAAKg5D,eACtBzE,SAAQD,IAAI,iBAAmB5vD,GAzEhC,GAAIw2C,GAAKl8D,EAAQ,MAChB4vB,EAAMpvB,EAAOJ,QAAUJ,EAAQ,QAEhC4vB,GAAIg6D,QAAU,SAASjrE,GAEtB,MAAO,IAAIoqE,GAAYpqE,GAASkrE,cAcjCd,EAAY/lF,UAAU8mF,cAAgB,SAASpkE,EAAM7K,EAAUsrE,GAC9DA,EAAMA,KACN,IAOG4D,GAPCC,EAAatkE,EAAK6gE,UAAU7gE,EAAKukE,YAAY,KAAK,EAAGvkE,EAAKukE,YAAY,MACvEC,EAAOpwE,EAAKlZ,KAAK2oF,WAAYzvE,EAAKqsE,IAClCgE,EAAWvpF,KAAK0oF,YAAc15D,EAAIitC,iBAClCutB,EAAiBtwE,EAAKqwE,GACtBE,EAAkBz6D,EAAI/U,SAASA,EAAUsvE,EAAUD,GACnD9pF,KACAkqF,EAAW,EAGd,KAAK,GAAIl8D,KAAY87D,GAChBA,EAAK97D,KAAc+3D,EAAI/3D,IAAa87D,EAAK97D,KAAcxtB,KAAK2oF,WAAWn7D,KAC1E27D,EAAKnhF,OACyB,gBAAnBshF,GAAK97D,GACf27D,EAAKn6D,EAAI/U,SAASqvE,EAAK97D,GAAW+7D,EAAUD,GACR,kBAAnBA,GAAK97D,GACtB27D,EAAKG,EAAK97D,GACA87D,EAAK97D,GAAUu4D,MACzByD,EAAe7C,QAAU2C,EAAK97D,GAAUu4D,IACxCoD,EAAKn6D,EAAI/U,SAASqvE,EAAK97D,GAAU2E,KAAMq3D,EAAgBF,IAEpDH,IACHO,GAAYP,EAAG/P,WAAW5wE,QAAQ,YAAaglB,GAC/ChuB,EAAQiQ,KAAK+d,IAIhBk8D,IAAYD,EAAgBrQ,WAAW5wE,QAAQ,YAAa4gF,GAC5D9tB,EAAGquB,cAAc7kE,EAAM,eAAiB4kE,EACrC,cAAgBN,EAAa,kBAAoBp6D,EAAI83D,iBAAiB1N,WAAa,KAAOmQ,EAAS1C,kBAAoB,IAAM,MAC7H+B,EAAWppF,GACX,uJACAQ,KAAKuoF,SAAW,IAAMvoF,KAAKuoF,SAAW,QAAUvoF,KAAKuoF,SAAW,KAAOa,EAAa,qBAwBxFjB,EAAY/lF,UAAUwnF,YAAc,SAAS9kE,GAC5C,GAAI1E,GAAO0oE,EAAShkE,EACpB,OAAI1E,GACI4O,EAAI/U,SAASmG,EACjBpgB,KAAK0oF,YAAc15D,EAAIitC,iBACvB/iD,EAAKlZ,KAAK2oF,aAHd,QAODR,EAAY/lF,UAAU6mF,WAAa,WAClCtU,QAAQD,IAAI,iCAEZ,IAECmV,GAAGle,EAAG1rE,EAFH6pF,EAAY9pF,KAAKooF,OACpB2B,EAAUzuB,EAAG0uB,YAAYF,EAG1B,KAAKD,EAAI,EAAGle,EAAIoe,EAAQrqF,OAAYisE,EAAJke,EAAOA,IACtC5pF,EAAO8pF,EAAQF,GACX,uBAAuBjuE,KAAK3b,KAC/B00E,QAAQD,IAAI,cAAgBz0E,GAC5BD,KAAK2oF,WAAW1oF,EAAK0lF,UAAU,EAAG1lF,EAAKokB,QAAQ,OAASykE,EAASgB,EAAY7pF,GAI/E,KAAK4pF,EAAI,EAAGle,EAAIoe,EAAQrqF,OAAYisE,EAAJke,EAAOA,IACtC5pF,EAAO8pF,EAAQF,GACX,uBAAuBjuE,KAAK3b,KAC/B00E,QAAQD,IAAI,aAAez0E,EAAO,gBAClCD,KAAKwoF,eAAevoF,EAAK0lF,UAAU,EAAG1lF,EAAKokB,QAAQ,OAASrkB,KAAK4pF,YAAYE,EAAY7pF,IAEtF,uBAAuB2b,KAAK3b,KAC/B00E,QAAQD,IAAI,aAAez0E,EAAO,YAClCD,KAAKkpF,cAAclpF,KAAKqoF,cAAgBpoF,EAAK0lF,UAAU,EAAG1lF,EAAKokB,QAAQ,MAAQ,MAC7EykE,EAASgB,EAAY7pF,IAGzB,OAAOD,MAAKwoF,kBAGVyB,QAAQ,IAAI3uB,GAAK,MAAM4uB,KAAK,SAAS9qF,EAAQQ,GAChD,YAyBA,SAASsE,GAAMC,EAAYC,GACvBtC,EAAMqC,EAAYnC,EAAMC,SAASD,EAAMqC,MAAM7C,OAAQO,YAGrD7B,EAAEwB,eAAe1B,KAAM,cAAemE,GAGlCC,GACApE,KAAKsE,oBAAoBF,GAGzBpE,KAAKK,MACLL,KAAKK,KAAKC,MAAMN,KAAMO,WAmC9B,QAASgE,GAAmBC,EAAiBC,EAAiBN,GAI1D,GAHAA,EAAaA,GAAcnE,KAAK0E,YAG5BP,EAAWK,GACX,KAAM,IAAIlF,OAAM,UAAYkF,EACZ,kCAEpB,IAAII,GAAS5E,KAAKyE,EAClB3C,GAAM8C,EAAQ7C,SAGd,IAAI8C,GAAcD,EAAOE,KAAK9E,KAE9BE,GAAEwB,eAAeyC,EAAYK,EAAiBK,EAAa3E,EAAE6E,MAUjE,QAAST,GAAoBF,EAAcD,GACvCrC,EAAMsC,EAAcpC,EAAMC,SAASD,EAAMqC,OAAOnC,QAASF,EAAMqB,WAAWnB,WAGtE8C,MAAMC,QAAQb,GACdA,EAAac,QAAQ,SAASC,GAG1BZ,EAAmB9E,KAAKO,KAAMmF,EAAYA,EAAYhB,IACvDnE,MAEHE,EAAEqB,QAAQ6C,EAAc,SAASK,EAAiBD,GAG9CD,EAAmB9E,KAAKO,KAAMwE,EAAiBC,EAAiBN,IACjEnE,MAaX,QAASoF,GAAqBC,EAAWT,EAAQU,GAC7CxD,EAAMuD,EAAWtD,UACjBD,EAAMwD,EAAatD,EAAMuD,iBAEzB,IAAIC,GAAOzF,EAAO0F,MAAMC,sBAClBC,EAAeN,EAAUG,GAAQH,EAAUG,MAEjD,IAAIG,EAAaf,EAAO3E,MACpB,KAAM,IAAIX,OAAM,iDACVsF,EAAO3E,KAAO,kBAExB0F,GAAaf,EAAO3E,MAAQqF,EAahC,QAASM,GAAgBP,EAAWC,EAAab,EAAiBoB,GAC9D,GAAIjB,GAAS5E,KAAKoC,UAAUqC,EAC5B3C,GAAM8C,EAAQ7C,SAEd,IAAI+D,GAAgBC,EAAiBtG,KAAKO,KAAM4E,EAEhD1E,GAAEwB,eAAe2D,EAAUjD,UAAWyD,EAAgBC,EAAe5F,EAAE6E,MAEvEK,EAAqBC,EAAWT,EAAQU,GAW5C,QAASS,GAAiBnB,GACtB,MAAO,YACH,GAAIoB,GAAgBC,EAAkBxG,KAAKO,KAAM4E,EAAO3E,KACxD,OAAO2E,GAAOtE,MAAM0F,EAAezF,YAa3C,QAAS0F,GAAkBd,GACvB,GAAInF,eAAgBkE,GAAO,MAAOlE,KAClC,IAAI2F,GAAe3F,KAAKI,YAAYL,EAAO0F,MAAMC,sBACjD,OAAO1F,MAAK2F,EAAaR,IAY7B,QAASe,GAAeb,EAAWC,EAAaa,GAC5CrE,EAAMqE,EAAcnE,EAAMC,SAASD,EAAMqC,OAAOnC,QAASF,EAAMqB,WAAWnB,WAEtE8C,MAAMC,QAAQkB,GACdA,EAAajB,QAAQ,SAASC,GAC1BS,EAAgBnG,KAAKO,KAAMqF,EAAWC,EAAaH,EAAYA,IAChEnF,MAEHE,EAAEqB,QAAQ4E,EAAc,SAAS1B,EAAiBoB,GAC9CD,EAAgBnG,KAAKO,KAAMqF,EAAWC,EAAab,EAAiBoB,IACrE7F,MA9MX,GAAIE,GAAId,EAAQ,aACV0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MACdjC,EAASX,EAAQ,YAGvBQ,GAAOJ,QAAU0E,EAwCjBhE,EAAEM,YAAY0D,GACVK,mBAAoBA,EACpBD,oBAAqBA,IAUzBpE,EAAEkD,OAAOc,GACLkC,QAASF,MAsJVG,YAAY,IAAIvC,gBAAgB,IAAIrD,YAAY,MAAM0pF,KAAK,SAAS/qF,EAAQQ,GAC/E,YAQA,IAAIkO,IACA5J,MAAO9E,EAAQ,oBACf2O,cAAe3O,EAAQ,wBACvB4O,uBAAwB5O,EAAQ,4BAChC6O,aAAc7O,EAAQ,qBACtBsvD,mBAAoBtvD,EAAQ,wBAGhCQ,GAAOJ,QAAUsO,IAEdS,mBAAmB,IAAIK,oBAAoB,IAAIw7E,uBAAuB,IAAIv7E,uBAAuB,IAAIC,2BAA2B,MAAMu7E,KAAK,SAASjrF,EAAQQ,GAC/J,YAQA,SAASG,GAAOge,GACZ7d,EAAEqnD,WAAWxnD,EAAQge,GANzB,GAAI7d,GAAId,EAAQ,YAGhBQ,GAAOJ,QAAUO,EAMjBA,GACI0F,OACIC,sBAAuB,sBAE3B5D,OAAO,EACP4mD,OAAO,MAGRjoD,YAAY,MAAM6pF,KAAK,SAASlrF,EAAQQ,GAC3C,YAuHA,SAASS,GAAK8D,EAAYC,EAAcuf,GAEhCA,GACA3jB,KAAK0jB,kBAAkBC,GAE3BimC,EAAuBnqD,KAAKO,MAIhC,QAAS4pD,KACL1pD,EAAEuB,iBAAiBzB,MACf6pD,uBACAC,+BACD5pD,EAAEs1C,MAOT,QAASuU,KACL/pD,KAAKgqD,QACL,IAAIrmC,GAAgB3jB,KAAK4jB,kBACrBD,IACAA,EAAcrZ,UAqCtB,QAAS2/C,GAAa5nC,EAAUK,GAC5B,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAIzD,QAASynC,GAAe9nC,EAAUK,GAC9B,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc0nC,cAAe,IAGtF,QAASC,GAAmBhoC,EAAUK,GAClC,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc0nC,cAAe,EAAGE,MAAM,IAI/F,QAASC,GAAiBloC,EAAUK,GAChC,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc4nC,MAAM,IAI7E,QAASE,GAAkBnoC,EAAUK,GACjC,MAAOwnC,GAAyBzqD,KAAKO,KAAMqiB,EAAUK,GAAc4nC,MAAM,IAI7E,QAASJ,GAAyB7nC,EAAUK,EAAY3E,GAoBpD,MAnBAjc,GAAMugB,EAAUrgB,EAAMqC,MAAMnC,QAASA,QAASuoD,SAC9C3oD,EAAM4gB,EAAY1gB,EAAMqC,MAAMtC,UAC1B2gB,WAAY3gB,SACZ+gB,QAAS9gB,EAAMgiD,IACfjmC,QAAS/b,EAAMC,SAAST,WAGH,kBAAdkhB,KACPA,GACIA,WAAYA,EACZI,QAAS9iB,KAAK0E,cAIlBqZ,IACA2E,EAAW3E,QAAU2E,EAAW3E,YAChC7d,EAAEkD,OAAOsf,EAAW3E,QAASA,IAG1B2sC,EAAcjrD,KAAKO,KAAMqiB,EAAUK,GAI9C,QAASgoC,GAAcroC,EAAUK,GAE7B,MADAxiB,GAAEwB,eAAeghB,EAAY,aAAcL,GACpCsoC,EAAalrD,KAAKO,KAAM,sBAAuBqiB,EAAUK,GAIpE,QAASioC,GAAaxlD,EAAYkd,EAAUK,GACjB,gBAAZL,KACPA,EAAWA,EAASva,MAAM8iD,GAE9B,IAAIC,GAAkB7qD,KAAK8qD,uBAAuBzoC,EAElD,IAAIA,YAAoBooC,QACpB,MAAOzqD,MAAKmF,GAAY0lD,EAAiBxoC,EAAUK,EAGnD,IAAIqoC,IAAU,CAOd,OALA1oC,GAASnd,QAAQ,SAAS7C,GACtB,GAAI2oD,GAAsBhrD,KAAKmF,GAAY0lD,EAAiBxoD,EAASqgB,EACrEqoC,GAAUA,GAAWC,GACtBhrD,MAEI+qD,EAiBf,QAASE,GAAoBJ,EAAiBxoD,EAASqgB,GACnD,IAAOmoC,EAAgBxoD,KAAYwoD,EAAgBxoD,GAAS3C,OAAS,CACjEmrD,EAAgBxoD,MACZA,YAAmBooD,UACnBI,EAAgBxoD,GAAS6oD,QAAU7oD,GACnCrC,KAAKmrD,gBACLnrD,KAAKmrD,eAAeC,kBAAkB/oD,EAC1C,IAAIgpD,IAAgB,EAGxB,GAAIC,GAAiBT,EAAgBxoD,GACjCkpD,EAAmBF,GAA8E,IAA7DG,EAAmB/rD,KAAKO,KAAMsrD,EAAgB5oC,EAKtF,OAHI6oC,IACAD,EAAe77C,KAAKiT,GAEjB6oC,EAUX,QAASC,GAAmB9hC,EAAMhH,GAE9B,MAAOxiB,GAAEurD,UAAU/hC,EAAM,SAASgiC,GAC9B,MAAOhpC,GAAWA,YAAcgpC,EAAOhpC,YAC5BA,EAAWI,SAAW4oC,EAAO5oC,UAuBhD,QAASwR,GAAW9R,GAChB1gB,EAAM0gB,EAAoBxgB,EAAMqB,WAAWrB,EAAMqC,MAAMtC,UAAY2gB,WAAY3gB,SAAU+gB,QAAS9gB,EAAMgiD,OAExG,IAAIvhC,GAAsBviB,EAAE6c,QAAQyF,EAAoB,SAASE,EAAYL,GACzE,MAAOriB,MAAK4iB,GAAGP,EAAUK,IAC1B1iB,KAEH,OAAOyiB,GAwBX,QAASkpC,GAActpC,EAAUK,GAS7B,MARA5gB,GAAMugB,EAAUrgB,EAAMqC,MAAMnC,QAASA,QAASuoD,SAC9C3oD,EAAM4gB,EAAY1gB,EAAMC,SAASD,EAAMqC,MAAMtC,UACzC2gB,WAAY3gB,SACZ+gB,QAAS9gB,EAAMgiD,IACfjmC,QAAS/b,EAAMC,SAAST,YAIrBoqD,EAAensD,KAAKO,KAAMqiB,EAAUK,GAI/C,QAASkpC,GAAevpC,EAAUK,GAC9B,MAAOioC,GAAalrD,KAAKO,KAAM,oBAAqBqiB,EAAUK,GAgBlE,QAASmpC,GAAkBhB,EAAiBxoD,EAASqgB,GACjD,GAAI4oC,GAAiBT,EAAgBxoD,EACrC,KAAMipD,IAAoBA,EAAe5rD,OACrC,OAAO,CAEX,IAAIgjB,EAAY,CACa,kBAAdA,KACPA,GAAeA,WAAYA,EAAYI,QAAS9iB,KAAK0E,aAEzD,IAAIonD,GAAkBN,EAAmB/rD,KAAKO,KAAMsrD,EAAgB5oC,EACpE,IAAuB,IAAnBopC,EACA,OAAO,CACXR,GAAe7/B,OAAOqgC,EAAiB,GACjCR,EAAe5rD,QACjBM,KAAK+rD,sBAAsBlB,EAAiBxoD,OAGhDrC,MAAK+rD,sBAAsBlB,EAAiBxoD,EAEhD,QAAO,EAaX,QAAS0pD,GAAsBlB,EAAiBxoD,SACrCwoD,GAAgBxoD,GACnBrC,KAAKmrD,gBAAoC,gBAAX9oD,IAC9BrC,KAAKmrD,eAAea,oBAAoB3pD,GAsBhD,QAAS4pD,GAAYzpC,GACjB1gB,EAAM0gB,EAAoBxgB,EAAMqB,WAAWrB,EAAMC,SAASD,EAAMqC,MAAMtC,UAAY2gB,WAAY3gB,SAAU+gB,QAAS9gB,EAAMgiD,QAEvH,IAAIkI,GAAuBhsD,EAAE6c,QAAQyF,EAAoB,SAASE,EAAYL,GAC1E,MAAOriB,MAAK22B,IAAItU,EAAUK,IAC3B1iB,KAEH,OAAOksD,GAOX,QAASC,KACLC,EAAmB3sD,KAAKO,KAAMA,KAAK8pD,4BACnCsC,EAAmB3sD,KAAKO,KAAMA,KAAK6pD,qBAIvC,QAASuC,GAAmBvB,GACxB3qD,EAAEqB,QAAQspD,EAAiB,SAASwB,EAAahqD,GAC7CrC,KAAK+rD,sBAAsBlB,EAAiBxoD,IAC7CrC,MAqBP,QAASoW,GAAY/T,EAAS+d,EAAMZ,EAAU8sC,GAC1CxqD,EAAMO,EAASL,EAAMqC,MAAMnC,OAAQuoD,SACnC3oD,EAAM0d,EAAUxd,EAAMC,SAASF,UAE/B,IAAI8oD,GAAkB7qD,KAAK8qD,uBAAuBzoD,GAC9CipD,EAAiBT,EAAgBxoD,EAErCrC,MAAKusD,iBAAiBlqD,EAAS+d,EAAMZ,EAAU8rC,EAAgBgB,GAEzC,gBAAXjqD,IACPrC,KAAKwsD,wBAAwBnqD,EAAS+d,EAAMZ,EAAU8rC,EAAgBgB,GAW9E,QAAS9/C,GAAgBnK,EAAS+d,EAAMZ,GACpCxf,KAAKoW,YAAY/T,EAAS+d,EAAMZ,GAAU,GAe9C,QAASgtC,GAAwBnqD,EAAS+d,EAAMZ,EAAUitC,EAAsBH,GAC5EpsD,EAAEqB,QAAQvB,KAAK8pD,2BACX,SAAS4C,GACL,GAAIxB,GAAUwB,EAAmBxB,OACjC,IAAIA,EAAQtvC,KAAKvZ,GAAU,CACvB,GAAIoqD,EACA,GAAIC,GAAqBA,EAAmBpQ,OAAO,SAAS55B,GACxD,GAAIsH,GAAQwhC,EAAmB/rD,KAAKO,KAAMysD,EAAsB/pC,EAChE,OAAgB,IAATsH,GAGfhqB,MAAKusD,iBAAiBlqD,EAAS+d,EAAMZ,EAAUktC,EAAoBJ,KAG7EtsD,MAeN,QAASusD,GAAiBlqD,EAAS+d,EAAMZ,EAAU8rC,EAAgBgB,GAC3DhB,GAAkBA,EAAe5rD,SAIjC4rD,EAAiBA,EAAel5C,QAEhCk5C,EAAepmD,QAAQ,SAASwd,GAC5B1iB,KAAK2sD,gBAAgBjqC,EAAYrgB,EAAS+d,EAAMZ,EAAU8sC,IAC3DtsD,OAKX,QAAS2sD,GAAgBjqC,EAAYrgB,EAAS+d,EAAMZ,EAAU8sC,GAC1D,GAAIM,GAAiBlqC,EAAW3E,SAAW2E,EAAW3E,QAAQusC,KACxDuC,EAAWP,GAAgBM,KAAmB,GACnCA,EAEbxC,EAAgB1nC,EAAW3E,SAAW2E,EAAW3E,QAAQqsC,aAC7D,IAAIA,EACA,GAAqB,GAAjBA,EAAoB,CACpB,GAAI/nC,GAAWK,EAAWoqC,UAC1B9sD,MAAK22B,IAAItU,EAAUK,OACZ0nC,GAAgB,GACvB1nC,EAAW3E,QAAQqsC,eAGvByC,GACAnqC,EAAWA,WAAWjjB,KAAKijB,EAAWI,QAASzgB,EAAS+d,EAAMZ,GAE9Dtf,EAAEmQ,YAAYqS,EAAWA,WAAY,OAAQA,EAAWI,QAASzgB,EAAS+d,EAAMZ,GAgBxF,QAASutC,GAAe1qD,EAAS2qD,GAC7BlrD,EAAMO,EAASL,EAAMqC,MAAMnC,OAAQuoD,QAEnC,IAAII,GAAkB7qD,KAAK8qD,uBAAuBzoD,GAC9CipD,EAAiBT,EAAgBxoD,MACRg8B,OAAOwsB,EAAgBxoD,MAgBpD,OAZI2qD,MAA8B,GAA2B,gBAAX3qD,IAC9CnC,EAAEqB,QAAQvB,KAAK8pD,2BACX,SAAS4C,GACL,GAAIxB,GAAUwB,EAAmBxB,OAC7BwB,IAAsBA,EAAmBhtD,QAClCwrD,EAAQtvC,KAAKvZ,IACpBnC,EAAEmT,YAAYi4C,EAAgBoB,KAMvCpB,EAAe5rD,OACR4rD,EACAtjD,OAYlB,QAAS8iD,GAAuBzoD,GAC5B,MAAOA,aAAmBooD,QACZzqD,KAAK8pD,2BACL9pD,KAAK6pD,oBAYvB,QAASnmC,GAAkBC,GACvB7hB,EAAM6hB,EAAe5V,GAErB7N,EAAEwB,eAAe1B,KAAM,iBAAkB2jB,GACzCA,EAAczH,UAAYlc,KAU9B,QAAS4jB,KACL,MAAO5jB,MAAKmrD,eAnpBhB,GAAIjnD,GAAQ9E,EAAQ,qBACd2O,EAAgB3O,EAAQ,cACxBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MAsBhB0U,EAAYxW,EAAEwD,eAAeQ,EAAO,aAEpC0mD,EAAsBl0C,EAAUk0C,oBAAsB,iBA2B1D1qD,GAAEM,YAAYkW,GACVrW,KAAMA,EACNiK,QAASy/C,EACTnnC,GAAIqnC,EACJve,KAAMye,EACN8C,SAAU5C,EACVjjC,OAAQmjC,EACR2C,QAAS1C,EACT2C,UAAWlD,EACXtzB,IAAKg1B,EACLyB,WAAYzB,EACZr3B,WAAYA,EACZ23B,YAAaA,EACbjC,OAAQmC,EACR/1C,YAAaA,EACb5J,gBAAiBA,EACjBugD,eAAgBA,EAChBnpC,iBAAkBA,EAClBknC,uBAAwBA,EACxBG,oBAAqBA,EACrBY,kBAAmBA,EACnBE,sBAAuBA,EACvBS,wBAAyBA,EACzBD,iBAAkBA,EAClBI,gBAAiBA,EACjBjpC,kBAAmBA,IAQvBhN,EAAUC,gBACNiM,GAAI,KACJwE,OAAQ,SACRskB,KAAM,OACNuhB,SAAU,WACVt2B,IAAK,MACLrC,WAAY,aACZ23B,YAAa,cACb71C,YAAa,cACb5J,gBAAiB,kBACjBugD,eAAgB,kBAIpBntD,EAAOJ,QAAUkX,EAGjBA,EAAU22C,mBA6iBPC,oBAAoB,IAAIxpD,gBAAgB,IAAIypD,aAAa,IAAI9sD,YAAY,MAAM8pF,KAAK,SAASnrF,EAAQQ,EAAOJ,GAC/Ge,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/BoR,iBAAiB,IAAIlR,YAAY,MAAM+pF,KAAK,SAASprF,EAAQQ,EAAOJ,GACvEe,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/BouD,UAAU,IAAIluD,YAAY,MAAMgqF,KAAK,SAASrrF,EAAQQ,GACzD,YA8DA,SAASS,GAAK8D,EAAYC,EAAcyqD,GACpC7uD,KAAK8uD,qBAAqBD,GAO9B,QAASE,KACD/uD,KAAK6uD,cACL7uD,KAAK6uD,aAAavkD,UAU1B,QAAS0kD,GAAa9yC,GAClBhc,EAAEwB,eAAe1B,KAAM,YAAakc,GAWxC,QAAS4yC,GAAqBD,GAC1B/sD,EAAM+sD,EAAc7sD,EAAMC,SAASgM,IAE7B4gD,IACFA,EAAe,GAAI5gD,IAEvB/N,EAAEwB,eAAe1B,KAAM,eAAgB6uD,GAY3C,QAASzD,GAAkB/oD,GACvB,GAAI4sD,GAAmBjvD,KAAK6uD,aAAanB,mBAAmBrrD,EAC7B,oBAApB4sD,IACPjvD,KAAKynC,oBAAoBwnB,GAYjC,QAASjD,GAAoB3pD,GACzB,GAAI6sD,GAAuBlvD,KAAK6uD,aAAahB,sBAAsBxrD,EAChC,oBAAxB6sD,IACPlvD,KAAK2nC,uBAAuBunB,GAcpC,QAASprC,GAAgB8gB,EAAeqpB,GACpC,GAAIkB,GAAMnvD,KAAK6uD,aACTP,EAAmBa,EAAInB,oBAAoBppB,EAE7C0pB,IACAA,EAAiBppD,QAAQ,SAAU7C,GAC/B,GAAIyiC,GAAeqqB,EAAItqB,mBAAmBD,EAAeviC,EAAS4rD,GAE9DmB,EAAiBD,EAAIxqB,oBAAoBC,EAAeviC,EAASyiC,EACjEsqB,IACApvD,KAAKoW,YAAY/T,EAASyiC,IAE/B9kC,MAUX,QAASoW,GAAY/T,EAAS+d,GAC1BpgB,KAAKkc,UAAU9F,YAAY/T,EAAS+d,GAIxC,QAAS/V,KACL,KAAM,IAAI/K,OAAM,4CA1KpB,GAAI4E,GAAQ9E,EAAQ,qBACd6O,EAAe7O,EAAQ,WAEvBc,GADSd,EAAQ,kBACbA,EAAQ,cACZ0C,EAAQ1C,EAAQ,iBAChB4C,EAAQF,EAAME,MAQhB+L,EAAgB7N,EAAEwD,eAAeQ,EAAO,iBAAiB,EAE7DtE,GAAOJ,QAAUuO,EAkBjB7N,EAAEM,YAAYuN,GACV1N,KAAMA,EACNiK,QAASykD,EACTC,aAAcA,EACd5D,kBAAmBA,EACnBY,oBAAqBA,EACrBloC,gBAAiBA,EACjB1N,YAAaA,EACb04C,qBAAsBA,EAGtB5gC,QAAS7jB,EACTo9B,oBAAqBp9B,EACrBs9B,uBAAwBt9B,MA+HzBijD,oBAAoB,IAAIxpD,gBAAgB,IAAI6N,iBAAiB,IAAIg9C,UAAU,IAAIluD,YAAY,MAAMiqF,KAAK,SAAStrF,EAAQQ,EAAOJ,GACjIe,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/BuD,gBAAgB,IAAIypD,aAAa,IAAI9sD,YAAY,MAAMkqF,KAAK,SAASvrF,EAAQQ,GAChF,YAmCA,SAAS0K,KACLlC,EAAKskC,OAAOpiC,UAlChB,GAaIlC,IAbIhJ,EAAQ,cAcZstC,OAAQttC,EAAQ,YAChBW,OAAQX,EAAQ,YAChBiJ,KAAMjJ,EAAQ,UACd0O,QAAS1O,EAAQ,aACjBsX,UAAWtX,EAAQ,eACnB8gC,MAAO9gC,EAAQ,WACfkL,QAASA,GAKQ,iBAAV1K,IAAsBA,EAAOJ,UACpCI,EAAOJ,QAAU4I,GAGA,gBAAVmnB,UACPA,OAAOnnB,KAAOA,KAOf2nD,YAAY,IAAIvG,WAAW,IAAIohC,cAAc,IAAIC,WAAW,IAAIvJ,UAAU,IAAI9wB,SAAS,IAAI/vD,YAAY,MAAMqqF,KAAK,SAAS1rF,EAAQQ,GACtI,YA2BA,SAAS8sC,GAAOq+C,EAAKC,EAAMC,EAAKltE,GAC5B,GAAI/Y,MAAMC,QAAQ8lF,GAAM,CACpB,GAAIG,GAAmBH,EACnBI,EAAaD,EAAiBj6E,IAAI,SAASm6E,GAC3C,MAAO,IAAIC,GAAUD,EAAM,GAAIA,EAAM,GAAIA,EAAM,GAAIA,EAAM,KAG7D,OADAD,GAAWjmF,QAAQomF,GACZH,EAEP,GAAII,GAAO,GAAIF,GAAUN,EAAKC,EAAMC,EAAKltE,EAEzC,OADAutE,GAAcC,GACPA,EA2Bf,QAASD,GAAcC,GACnBA,EAAKC,aAAeC,EAAYh8E,KAAK87E,GAAQ,EAC7CA,EAAK3oE,GAAG,KAAM8oE,GACdh/C,EAAOt2B,YAAY,SAAWu1E,UAAWJ,IACzC7+C,EAAOt2B,YAAY,YAAcu1E,UAAWJ,IAIhD,QAASG,GAAmBx1E,EAAKkK,GAC7B,GAAIA,GAAOA,EAAOlgB,EAAEiD,MAAMid,KAC1BlgB,GAAEkD,OAAOgd,GACLkvB,GAAItvC,KAAKwrF,aACTG,UAAW3rF,OAEf0sC,EAAOt2B,YAAYF,EAAKkK,GAClBwrE,EAAkBlsF,QAAYmsF,IAChC3rF,EAAEoQ,MAAMw7E,GACRD,GAAiB,GAGrBD,EAAkBn8E,MAAOyG,IAAKA,EAAKkK,KAAMA,IAI7C,QAAS0rE,KACDF,EAAkBlsF,QAClBksF,EAAkBlsF,OAAS,EAC3BQ,EAAEoQ,MAAMw7E,GACRp/C,EAAOt2B,YAAY,uBAEnBy1E,GAAiB,EACjBn/C,EAAOt2B,YAAY,yBAK3B,QAAS21E,KACL,MAAOF,GAIX,QAASG,GAAgCxsE,GAMrC,QAASysE,KACDJ,EACAn/C,EAAOhB,KAAK,uBAAwBugD,GAEpCzsE,IATJqsE,EACAn/C,EAAOhB,KAAK,uBAAwBugD,GAEpC/rF,EAAEoQ,MAAM27E,GAWhB,QAASC,GAAqBxsC,GAC1B,MAAoB,mBAATA,GACA+rC,EAEJA,EAAYnvC,OAAO,SAASivC,GAC/B,MAAOA,GAAKY,OAASzsC,IAK7B,QAAS0sC,GAAwBb,GAC7BA,EAAKjhF,SACL,IAAI0f,GAAQyhE,EAAYpnE,QAAQknE,EAC5BvhE,IAAS,QACFyhE,GAAYzhE,GAEnB1nB,EAAOoQ,KAAK,gEAIpB,QAAS25E,GAA8B3sC,EAAO4sC,GAC1C,GAAInB,GAAaz+C,EAAO6/C,cAAc7sC,GAClC8sC,EAAerB,EAAWl6E,IAAI,SAASs6E,GACvC,GAAIkB,IACAC,WAAYC,EAAmBpB,EAAKR,KACpC6B,YAAaD,EAAmBpB,EAAKN,KACrCD,KAAMO,EAAKP,KACXmB,KAAMZ,EAAKY,KAMf,OAHIZ,GAAKxtE,UACL0uE,EAAW1uE,QAAUwtE,EAAKxtE,SAEvB0uE,GASX,OANIH,KACAE,EAAcA,EAAYlwC,OAAO,SAASuwC,GACtC,MAAOC,GAAqBD,EAAMH,WAAYJ,IACnCQ,EAAqBD,EAAMD,YAAaN,MAGpDE,EAIX,QAASG,GAAmBI,GACxB,GAAIx7B,KAkBJ,OAjBiB,kBAANw7B,KACHA,EAAG33B,QAAU23B,EAAGv2B,cAChBjF,EAAOyF,QAAQ+1B,EAAGv2B,aAClBu2B,EAAKA,EAAG33B,QAGZ7D,EAAOyF,QAAQ+1B,GACfA,EAAKA,EAAGroF,aAGK,gBAANqoF,KACPx7B,EAAOyF,QAAQ+1B,GAEXA,EAAGjtF,OACHyxD,EAAOyF,QAAQ+1B,EAAGjtF,QAGnByxD,EAIX,QAASu7B,GAAqBv7B,EAAQy7B,GAClC,MAAOz7B,GAAOO,KAAK,SAASm7B,GACxB,GAAIp1E,GAAYo1E,EAAQ7sF,aAAe6sF,EAAQ7sF,YAAYH,IAC3D,OAAOitF,GAAar1E,EAAWm1E,IACpBE,EAAaD,EAAQhtF,KAAM+sF,IAC3BE,EAAaD,EAASD,KAKzC,QAASE,GAAap3B,EAAKq3B,GACvB,MAAOr3B,IAAqB,gBAAPA,IAAmBA,EAAIzxC,QAAQ8oE,IAAW,EAInE,QAASC,KASL,QAASC,GAAUN,GACXA,IAAOA,EAAGvsE,YAAYusE,EAAGziF,UATjCmhF,EAAYvmF,QAAQ,SAASqmF,GACzB8B,EAAU9B,EAAKR,KACfsC,EAAU9B,EAAKN,KACfM,EAAKjhF,YAET6L,EAAW7L,UACXoiC,EAAOlsB,YAAa,EAlNxB,GAAI6qE,GAAYjsF,EAAQ,qBAClBsX,EAAYtX,EAAQ,eACpBc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,gBAGvBQ,GAAOJ,QAAUktC,CAuCjB,IAAIv2B,GAAa,GAAIO,GAAUg2B,EAAQh2B,EAAUC,gBAG7C80E,KACEG,KACAC,GAAiB,CAGvB3rF,GAAEkD,OAAOspC,GACL6/C,cAAeL,EACfoB,uBAAwBjB,EACxBkB,cAAexB,EACfyB,yBAA0BxB,EAC1Br/C,iBAAkBy/C,EAClB9hF,QAAS8iF,MA8JVxC,cAAc,IAAI6C,oBAAoB,IAAIhkC,gBAAgB,IAAIhpD,YAAY,MAAMitF,KAAK,SAAStuF,EAAQQ,GACzG,YA8BA,SAASipB,GAAmBlY,EAAMigD,GAC9B1wD,EAAEwB,eAAeiP,EAAM,wBAAyBigD,EAAM1wD,EAAEs1C,KAAOt1C,EAAE6E,MAWrE,QAASijB,GAAmBrX,GACxB,GAAIoG,GAAgBpG,EAAKkgD,qBAEzB,cADOlgD,GAAKkgD,sBACL95C,EAIX,QAAS+5C,GAAoBC,EAAUC,GACnC,GAAIj6C,GAAgBiR,EAAmB+oC,EAEvC,OADAloC,GAAmBmoC,EAAQj6C,GACpBA,EAOX,QAASyT,KACLxqB,KAAKwM,gBAAgB,eAAiBoI,aAAa,EAAO8T,aAc9D,QAASlB,GAAkBnlB,EAAS+d,EAAMZ,GACtCyxC,EAAexxD,KAAKO,KAAMogB,EAAKsI,QAASlJ,GAmB5C,QAASyxC,GAAer8C,EAAa4K,GACjC0xC,EAAOzxD,KAAKO,KAAMwf,GAAU,GAC5B2xC,EAAmB1xD,KAAKO,KACpBoxD,EACIC,EAAoBz8C,KAC5Bs8C,EAAOzxD,KAAKO,KAAMwf,GAAU,GAIhC,QAAS0xC,GAAO1xC,EAAU8xC,GACtB9xC,GAAYA,EAAS,KAAM8xC,GAC3BtxD,KAAKoW,YAAYk7C,EAAiB,kBAAoB,iBAY1D,QAASD,GAAoBz8C,GACzB,GAAI28C,GAAS38C,EAAY,GAAG28C,OACtBC,GAAa,CAEnB,IAAI58C,EAAYlV,OAAS,EACrB,IAAK,GAAIL,GAAI,EAAG2lB,EAAMpQ,EAAYlV,OAAYslB,EAAJ3lB,EAASA,IAC3CuV,EAAYvV,GAAGkyD,QAAUA,IACzBjvD,EAAOC,MAAM,+EAAgFqS,EAAYvV,GAAGkyD,OAAOtxD,KAAMsxD,EAAOtxD,MAChIuxD,GAAa,EACbD,EAAS38C,EAAYvV,GAAGkyD,OAIpC,OAAO38C,GAIX,QAASw8C,GAAmBx8C,GAcxB,QAAS68C,GAAYrxC,IACH,UAAbA,EAAK1E,KAAmBg2C,EAAcC,GAAavxC,GAIxD,QAASsxC,GAAYtxC,GACjB,GAAI2M,GAAanG,EAAUoG,gBAAgB5M,EAAK0E,MAC5C8sC,EAAoBC,EAAcC,KAAK,SAASC,GAChD,MAAIhlC,GAAWrtB,OAASqyD,EAAWryD,OAAnC,OACOsyD,EAAgBD,EAAYhlC,IAGvC,KAAI6kC,EAAJ,CAIA,GAFAK,EAAKxiD,KAAK2Q,IAEJrgB,EAAO2oD,MAAO,KAAMwJ,EAC1BC,GAAc1iD,KAAKsd,GACnBqlC,GAAY,GAIhB,QAAST,GAAYvxC,GACjB,GAAI2M,GAAanG,EAAUoG,gBAAgB5M,EAAK0E,MAC5CutC,EAAoBF,GAAiBA,EAAcL,KAAK,SAASC,GACjE,MAAIhlC,GAAWrtB,QAAUqyD,EAAWryD,QACW,SAAxCqtB,EAAWglC,EAAWryD,QAAQ2tB,OADrC,OAEO2kC,EAAgBD,EAAYhlC,IAGvC,KAAIslC,EAAJ,CACID,GAAW9vD,EAAOC,MAAM,0HAE5B,IAAIqvD,GAAoBC,EAAcC,KAAK,SAASC,GAChD,MAAIhlC,GAAWrtB,QAAUqyD,EAAWryD,OAApC,OACOsyD,EAAgBD,EAAYhlC,IAGnC6kC,KAEJC,EAAcpiD,KAAKsd,GAEnBklC,EAAKxiD,KAAK2Q,KAId,QAAS4xC,GAAgBD,EAAYxoC,GACjC,MAAOwoC,GAAWO,MAAM,SAASplC,EAAUlD,GACvC,MAAOkD,GAASM,UAAYjE,EAAUS,GAAOwD,WA7DrD,GAGM4kC,GAHFH,KACEE,KACAN,KAEAK,IAGN,KAAMt9C,EAAY1P,QAAQusD,GAC1B,MAAO7yD,GAAK,GAAIA,GAAKszD,EAAU,KAAMtzD,GAErC,MAAOqzD,GAyDX,QAASd,GAAmBv8C,GAIxB,QAAS29C,GAAcnyC,GACnB,GAAIoyC,GAAYxyD,KAAK8kB,KAAK1E,EAAK0E,KAAmB,WAAb1E,EAAK1E,MAAkC,WAAb0E,EAAK1E,KAC9D82C,KACQ,UAAbpyC,EAAK1E,KAAmB+2C,EAAgBC,GAAeF,EAAWpyC,GANvExL,EAAY1P,QAAQqtD,EAAevyD,MACnCwqB,EAAwB/qB,KAAKO,MAAM,GAUvC,QAASyyD,GAAcD,EAAWpyC,GAC9B,GAAI4J,GAAQ5J,EAAK4J,MACX2oC,EAAUvyC,EAAKwL,QAAQlsB,OACvB6+B,GAAcvU,EAAO2oC,EAE3Bp0B,GAAaA,EAAWF,OAAOje,EAAK4I,SAAS5W,MAAM4X,EAAOA,EAAQ5J,EAAKyL,aACvEhD,EAAmB2pC,EAAU/mC,QAAQ,GACrC+mC,EAAU/mC,OAAOnrB,MAAMkyD,EAAWj0B,GAItC,QAASm0B,GAAcF,EAAWpyC,GAC9B,GAAIjb,GAAaytD,EAA0BxyC,EAAK1E,KAC5CvW,IACA0jB,EAAmB2pC,EAAUrtD,IAAa,GAC1CqtD,EAAUrtD,GAAYib,EAAK4I,WAE3B1mB,EAAOC,MAAM,4BApOrB,GAAID,GAASlD,EAAQ,kBACfW,EAASX,EAAQ,aACjBwnB,EAAYxnB,EAAQ,gBACpBc,EAAId,EAAQ,YAKlBQ,GAAOJ,QAAUgoB,EAGjBtnB,EAAEkD,OAAOokB,GACLqB,mBAAoBA,EACpBb,mBAAoBA,EACpB8oC,oBAAqBA,EACrBtmC,wBAAyBA,GA8D7B,IAAIooC,IACAxmC,MAAW,MACX2+B,QAAW,MACX8H,QAAW,MACXjnC,QAAW,SAsJZvlB,YAAY,IAAIsL,iBAAiB,IAAIohD,eAAe,IAAItyD,YAAY,MAAMktF,KAAK,SAASvuF,EAAQQ,GACnG,YAwCA,SAASyrF,GAAUN,EAAKC,EAAMC,EAAKltE,GAY/B,GAXA6vE,EAAUnuF,KAAKO,KAAMgrF,GAErB9qF,EAAEkD,OAAOpD,MACL+qF,IAAKA,EACLE,IAAKA,EACLkB,MAAM,EACN0B,kBACAC,kBACA33E,WAAY,GAAIO,GAAU1W,KAAM0W,EAAUC,kBAG1CoH,EAAS,CACT/d,KAAK+d,QAAUA,CAEf,IAAIgwE,GAAkBhwE,EAAQgwE,eAC9B,IAAIA,EAAiB,CACjBA,EAAkB7tF,EAAEiD,MAAM4qF,EAC1B,IAAIC,GAAqBC,EAAuBF,EAChD7tF,GAAEkD,OAAOpD,MACLkuF,iBAAkBC,EAAwBJ,GAC1CK,iBAAkBL,EAClBM,oBAAqBC,EAA+BN,GACpDO,oBAAqBP,IAI7B,GAAIQ,GAAkBzwE,EAAQywE,eAC1BA,IACAtuF,EAAEkD,OAAOpD,MACLyuF,iBAAkBD,EAAgB,MAClCE,iBAAkBF,EAAgB,OAI1C,IAAI5iD,GAAiB7tB,EAAQ6tB,cACzBA,IACA1rC,EAAEkD,OAAOpD,MACL2uF,gBAAiB/iD,EAAe,MAChCgjD,gBAAiBhjD,EAAe,QAK5C5rC,KAAK6uF,SAIT,QAASjB,GAAU5C,GAqBf,QAAS8D,KACL,KAAM,IAAIxvF,OAAM,2BAA6B0rF,GArBjD,GAAI+D,GAAa/D,EAAKvjF,MAAMunF,EAEtBD,IACFD,GAEJ,IAAIG,GAASF,EAAW,GAAGrvF,OACrBwvF,EAASH,EAAW,GAAGrvF,MAEzBuvF,IAAUC,GAAUD,GAAUC,GAC9BJ,IAEEG,GAAYC,GACdJ,IAEJ5uF,EAAEkD,OAAOpD,MACLgrF,KAAMA,EACNiE,OAAQA,EACRC,OAAQA,IAuBhB,QAASC,GAAqBnE,GAI1B,MAHAhrF,MAAKovF,UACLxB,EAAUnuF,KAAKO,KAAMgrF,GACrBhrF,KAAK6uF,SACE7uF,KAUX,QAASqvF,GAA0BrE,GAE/B,MADA9qF,GAAEmQ,YAAYrQ,KAAM,aAAcgrF,GAC3BhrF;CAUX,QAASmuF,GAAwBmB,GAC7B,GAAIC,KAIJ,OAHArvF,GAAEqB,QAAQ+tF,EAAO,SAASE,EAAaC,GACnCF,EAAaC,GAAeC,IAEzBF,EAIX,QAAStB,GAAuBF,GAuB5B,QAAS2B,GAAyBtmB,EAAOC,GACrC,KAAM,IAAI/pE,OAAM,gCAAkC8pE,EAAQ,KAAOC,GAIrE,QAASsmB,GAAe7qE,GACpB,MAAOA,GAAKtc,QAAQ,eAAgB,IA5BxC,GAAIwlF,KAmBJ,OAlBA9tF,GAAEqB,QAAQwsF,EAAiB,SAASyB,EAAaC,GAC7C,GAAIG,GAAaH,EAAUprE,QAAQ,KAC7BwrE,EAAaL,EAAYnrE,QAAQ,IACnCurE,IAAc,GAAKC,GAAc,GAC7BJ,EAAUr9E,MAAMw9E,IAAeJ,EAAYp9E,MAAMy9E,IACjDH,EAAyBD,EAAWD,SACjCzB,GAAgB0B,GAEvBzB,EAAmBv+E,MACfqgF,YAAalpE,EAAUouC,gBAAgBy6B,GACvCM,eAAgBJ,EAAeF,EAAWG,GAC1CI,UAAWppE,EAAUouC,gBAAgBw6B,GACrCS,aAAcN,EAAeH,EAAaK,OAEvCD,GAAc,GAAKC,GAAc,IACxCH,EAAyBD,EAAWD,KAGrCxB,EAcX,QAASM,GAA+BN,GACpC,MAAOA,GAAmB/8E,IAAI,SAASi/E,GACnC,OACIJ,YAAaI,EAAGF,UAChBD,eAAgBG,EAAGD,aACnBD,UAAWE,EAAGJ,YACdG,aAAcC,EAAGH,kBAU7B,QAASI,KAmBL,QAASC,GAAeC,EAAaC,EAAQC,EAAMC,EAAczC,EAAiBC,EAAoBQ,EAAiB5iD,GAInH,QAAS6kD,GAAOpuF,EAASquF,GA4BrB,QAASC,GAAcC,GACnB,GAAI7C,EAAiB,CACjB,GAAI8C,GAAiB9C,EAAgB6C,EACrC,IAAIC,EAAgB,MAAOA,EAC3B,KAAK7C,EAAmBtuF,OAAQ,MAChC,IAAIwwF,GAAKhwF,EAAEsb,KAAKwyE,EAAoB,SAAS8C,GACzC,MAAOA,GAAahB,YAAYl0E,KAAKg1E,IAEzC,KAAKV,EAAI,MACT,IAAIW,GAAiBD,EAAWpoF,QAAQ0nF,EAAGH,eAAgBG,EAAGD,kBAC3D,MAAQc,YAA+BtmC,SAC1BsmC,EAAoBn1E,KAAKg1E,IAC5BG,GAAuBH,GAAa,MAErD,OAAOC,IAAkBD,EAI7B,QAASI,GAAcJ,EAAYtoE,GAC/B,GAAIkmE,EAAiB,CACjB,GAAIyC,GAAYzC,EAAgBoC,EAC5BK,IAAiC,kBAAbA,KACpB3oE,EAAOS,SAAWkoE,EAAU3oE,EAAOS,UACnCT,EAAOU,SAAWioE,EAAU3oE,EAAOU,YAM/C,QAASkoE,GAAaN,EAAYtoE,GAa9B,QAAS6oE,GAAcC,GACnBA,EAAU9oE,EAAOU,SAAU,SAASyxB,EAAKC,GACrCA,EAAS51B,KAAO8rE,EACVS,IAAkB52C,IAAOC,EAAS42C,SAAYC,GAAeC,EAAW9xF,OAEjEg7C,EAAS42C,QAClBD,GAAgB,EAChBf,EAAOl6E,YAAY,YAAaskC,IAHhC41C,EAAOl6E,YAAY,YAAaskC,KAd5C,GAFA+2C,EAAcnpE,GAEVsjB,EAAgB,CAChB,GAAI4lD,GAAa5lD,EAAeglD,GAC1BW,EAAc,EACdF,GAAgB,CAElBG,IACAA,EAAWtsF,QAAQisF,IAkB/B,QAASM,GAAcnpE,GACnBopE,EAAShpE,QAAQjZ,KAAK6Y,GAI1B,QAASqpE,KAEL,GAAI73D,EAAKu2D,GAAc,GAAI7wE,GAAWoyE,CAEtC,IAAIx8E,GAAey8E,EAAkBrB,EACrCA,GAAa9wF,OAAS,EACtB0V,EAAalQ,QAAQ,SAAS0P,GAE1B27E,EAAK/jF,gBAAgB,cAAgBkc,QAAS9T,GAAe4K,KAKrE,QAASoyE,GAAmBn3C,EAAK6W,GAC7B,IAAI7W,EAAJ,CACA,GAAIiF,GAAQ4R,EAAiB,SAAW,KACxCi/B,GAAK7wC,GAAO,cAAe5lB,EAAKu2D,GAEhC,IAAIhuF,GAAUivD,EAAiB,kBAAoB,eACnDx3B,GAAK1jB,YAAY/T,GAAWkvD,OAAQ++B,EAAQ/6D,OAAQg7D,KAIxD,QAASsB,GAAkBC,GACvB,GACMx8E,GADFF,IAkBJ,OAfA08E,GAAQ5sF,QAAQ,SAASwrF,GACfA,EAAM97E,cAAaU,EAAqBtN,QACxC0oF,EAAMhoE,QAAQhpB,SAEhBgxF,EAAM97E,YACFU,EACApV,EAAEmT,YAAYiC,EAAoBo7E,EAAMhoE,UAExCpT,EAAqBpV,EAAEiD,MAAMutF,EAAMhoE,SACnCtT,EAAa3F,KAAK6F,IAGtBF,EAAa3F,KAAKihF,EAAMhoE,YAGzBtT,EAlIX,GAAIs8E,IACAhpE,WACA9T,YAAa87E,EAAM97E,YAGvB87E,GAAMhoE,QAAQxjB,QAAQ,SAASojB,GAC3B,GAAIsoE,GAAatoE,EAAOxD,KAClBitE,EAAapB,EAAcC,EAEjC,IAAyB,mBAAdmB,GAAX,CAEA,GAAIzpE,GAASpoB,EAAEiD,MAAMmlB,EACrBpoB,GAAEkD,OAAOklB,GACLipC,OAAQ++B,EACRxrE,KAAMitE,IAGVf,EAAcJ,EAAYtoE,GAC1B4oE,EAAaN,EAAYtoE,MAGvBkoE,EAAa9wF,QACfQ,EAAEoQ,MAAMqhF,GAEZnB,EAAa/gF,KAAKiiF,GA3BtB,MADApB,GAAOlpE,OAAO,cAAeqpE,GACtBA,EApBX,GAAIzwF,KAAKmsF,KACL,MAAO7pF,GAAOoQ,KAAK,qCAEvB,IAAIs/E,GAAmBhyF,KAAKiyF,kBACxB,GAAIjtF,OAAMhF,KAAKivF,QAAUjvF,KAAKkvF,QAAQzmF,KAAK,KAE3CsoF,EAAsBnqE,EAAUouC,gBAAgBg9B,GAEhDl4D,EAAO95B,IACPA,MAAKivF,SACLjvF,KAAKkyF,OAAS9B,EAAe,SAAUpwF,KAAKirF,IAAKjrF,KAAK+qF,IAAK/qF,KAAK6tF,eAAgB7tF,KAAKkuF,iBAAkBluF,KAAKquF,oBAAqBruF,KAAKyuF,iBAAkBzuF,KAAK2uF,kBAC7J3uF,KAAKkvF,SACLlvF,KAAKmyF,OAAS/B,EAAe,SAAUpwF,KAAK+qF,IAAK/qF,KAAKirF,IAAKjrF,KAAK8tF,eAAgB9tF,KAAKouF,iBAAkBpuF,KAAKuuF,oBAAqBvuF,KAAK0uF,iBAAkB1uF,KAAK4uF,kBAEjK5uF,KAAKmsF,MAAO,EACZnsF,KAAKoW,YAAY,YAqJrB,QAASg8E,KAYL,QAASC,GAAiB/B,EAAQgC,GAC1Bx4D,EAAKw4D,KACLhC,EAAO35D,IAAI,cAAemD,EAAKw4D,UACxBx4D,GAAKw4D,IAdpB,IAAMtyF,KAAKmsF,KACP,MAAO7pF,GAAOoQ,KAAK,wCAEvB,IAAIonB,GAAO95B,IACXqyF,GAAiBryF,KAAK+qF,IAAK,SAAU/qF,KAAKouF,kBAC1CiE,EAAiBryF,KAAKirF,IAAK,SAAUjrF,KAAKkuF,kBAE1CluF,KAAKmsF,MAAO,EACZnsF,KAAKoW,YAAY,aAerB,QAASm8E,KACLvyF,KAAKovF,UACLpvF,KAAKoW,YAAY,aACjBpW,KAAKmW,WAAW7L,gBACTtK,MAAK+qF,UACL/qF,MAAKirF,IACZjrF,KAAKwgB,YAAa,EAvZtB,GAAI9J,GAAYtX,EAAQ,gBAClBwnB,EAAYxnB,EAAQ,gBACpBc,EAAId,EAAQ,aACZkD,EAASlD,EAAQ,iBAGvBQ,GAAOJ,QAAU6rF,CAGjB,IAAI2D,GAAc,iBAwGlB9uF,GAAEM,YAAY6qF,GACVwD,OAAQsB,EACRf,QAASgD,EACT9nF,QAASioF,EACTC,WAAYrD,EACZv7C,gBAAiBy7C,MAoSlBp4E,eAAe,IAAItF,iBAAiB,IAAIohD,eAAe,IAAItyD,YAAY,MAAMgyF,KAAK,SAASrzF,EAAQQ,GACtG,YAiCA,SAASsgC,GAAM9f,EAAMjc,EAAY4Z,GAK7B,GAAIqtB,GAAQ,WACR,MAAO6nB,GAAW3yD,MAAM8qC,EAAO7qC,WAenC,OAbA6qC,GAAM8nB,UAAYhzB,EAAM99B,UAExBgpC,EAAM1mC,YAAcP,EACpBinC,EAAM+nB,SAAWp1C,MAEbqtB,EAAM+nB,SAASC,YAAa,IAC5BhoB,EAAMioB,qBAENjoB,EAAMhkB,OAAO,aAAcI,IAG3BpH,IAAMgrB,EAAMgF,MAAQhwB,GAEjBgrB,EAkEX,QAASkoB,KACL,MAAOtzD,MAAKowC,MAgBhB,QAAS6iB,GAAWpmC,GAChB,MAAMA,IAIN3sB,EAAEurB,OAAOlrB,UAAW,EAAG,EAAG,KAAMP,MAGzB,IAAK+B,SAASK,UAAU0C,KAAKxE,MAAMwtB,EAAWvtB,aAP5BP,KAiB7B,QAASuzD,GAAeC,GACpBA,EAAkBA,GAAmBxzD,KAAK0E,YAC1CR,EAAM9B,UAAUkC,oBAAoB7E,KAAKO,KAAKmc,GAAqBzF,EAAUC,eAAgB68C,GAejG,QAASC,GAAepuD,EAAWC,EAAaa,GAC5CA,EAAeA,GAAgButD,EAC/BxvD,EAAMkC,QAAQ3G,KAAKygC,EAAO76B,EAAWC,EAAaa,GAUtD,QAAS/B,GAAaovD,GAClBA,EAAkBA,GAAmBxzD,KAAK0E,YAC1CR,EAAM9B,UAAUkC,oBAAoB7E,KAAKO,KAAM0zD,EAAqBF,GASxE,QAASH,KAEL,GAAIM,GAAoB,GAAIj9C,GAAU1W,KAAMgI,OAAWA,QAGnD4rD,EAA0B,GAAI5lD,GAAuBhO,KAAMgI,OAAW,GAAI6rD,GAAaF,GAIvFG,EAAoB,GAAIp9C,GAAU1W,KAAMgI,OAAW4rD,EAEvD1zD,GAAEwB,eAAe1B,KAAMmc,EAAoB23C,GAC3C5zD,EAAEwB,eAAe1B,KAAM,qBAAsB2zD,GAIjD,QAASI,KACL,MAAO/zD,MAAK0E,YAIhB,QAAS0vD,KACLp0D,KAAKmc,GAAoB7R,UACzBtK,KAAKq0D,mBAAmB/pD,UACxBtK,KAAKwgB,YAAa,EAzNtB,CAAA,GAAIsN,GAAY1uB,EAAQ,YAClBk1D,EAAal1D,EAAQ,gBAErBooB,GADYpoB,EAAQ,gBACAA,EAAQ,kBAC5BsX,EAAYtX,EAAQ,gBACpB4O,EAAyB5O,EAAQ,6BACjCy0D,EAAcz0D,EAAQ,eACtB8E,EAAQ9E,EAAQ,qBAChBc,EAAId,EAAQ,aACZ0C,EAAQ1C,EAAQ,gBACR0C,GAAME,MACL5C,EAAQ,kBAGvBQ,EAAOJ,QAAU0gC,EAyCjBA,EAAM99B,UAAU8wD,UAAYhzB,EAAMgzB,UAkBlChzD,EAAEM,YAAY0/B,GACVpb,KAAMmuC,EACNnsD,IAAKwsD,EACLC,eAAgBA,EAChBnvD,aAAcA,EACdivD,mBAAoBA,EACpBU,eAAgBA,EAChBzpD,QAAS8pD,IAIbl0D,EAAEM,YAAY0/B,EAAOo0B,EAAWC,cAMhCr0D,EAAEkD,OAAO88B,GACLs0B,KAAM1mC,EACN1nB,QAASqtD,GAOb,IAAIt3C,GAAqB,YACzBzF,GAAUtQ,QAAQ85B,EAAO/jB,EAAoBzF,EAAUC,iBAMtD,MAAO,OAAQ,MAAO,UAAW,SAASzR,QAAQ,SAASC,GACxD,GAAIP,GAASkpB,EAAU1rB,UAAU+C,EACjCjF,GAAEwB,eAAew+B,EAAM99B,UAAW+C,EAAYP,IAmDlD,IAAI8uD,IAAuB,OAAQ,MAAO,MAAO,MAAO,SAAU,MAAO,OAAQ,MAAO,UAAW,WA6DhGpG,oBAAoB,IAAIr2C,eAAe,IAAIy9C,4BAA4B,IAAI5wD,gBAAgB,IAAI6N,iBAAiB,IAAIgjD,gBAAgB,IAAIC,cAAc,IAAIC,WAAW,IAAI9B,eAAe,IAAI+B,eAAe,IAAIr0D,YAAY,MAAMiyF,KAAK,SAAStzF,EAAQQ,EAAOJ,GACjQe,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/B00D,wBAAwB,IAAIlC,eAAe,IAAItyD,YAAY,MAAMkyF,KAAK,SAASvzF,EAAQQ,EAAOJ,GACjGe,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/B0W,eAAe,IAAIy9C,4BAA4B,IAAI5wD,gBAAgB,IAAI6wD,gBAAgB,IAAIsC,iBAAiB,IAAIlE,eAAe,IAAI+B,eAAe,IAAIr0D,YAAY,MAAMmyF,KAAK,SAASxzF,EAAQQ,GACjMA,EAAOJ,QAAQJ,EAAQ,SACjByzF,KAAK,SAASzzF,EAAQQ,EAAOJ,GACnCe,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/Bk3D,qBAAqB,IAAI9lD,iBAAiB,IAAIohD,eAAe,IAAItyD,YAAY,MAAMqyF,KAAK,SAAS1zF,EAAQQ,GAC5G,YAoDA,SAASotB,GAAgBlI,EAAM6yC,GAC3BA,EAAmBA,GAAoBC,CAEvC,IAAI7qC,KAEJ,KAAMjI,EACF,MAAOiI,EAEX,IAAI8qC,GAAW/yC,EAAKtc,QAAQmvD,EAAkB,SAASG,GACnD,GAAI5qC,IAAaM,SAAUsqC,EAM3B,OALA53D,GAAEkD,OAAO8pB,EAAU6qC,EAAcD,EAAQ,KACvB,KAAdA,EAAQ,KACR5qC,EAAS+T,YAAc7T,EAAeF,GAAU,IAEpDH,EAAWtd,KAAKyd,GACT,IAEX,IAAI2qC,EACA,KAAM,IAAIv4D,OAAM,yBAA2BwlB,EAE/C,OAAOiI,GAUX,QAASioC,GAAgBlwC,GAGrB,GAFAhjB,EAAMgjB,EAAM9iB,EAAMqC,MAAMnC,OAAQuoD,SAE5B3lC,YAAgB2lC,SAA+B,IAArB3lC,EAAKT,QAAQ,KACvC,MAAOS,EAEX,IAAIiI,GAAanG,EAAUoG,gBAAgBlI,EAAMmzC,GAC3CC,EAAW,IAEXC,GAAkB,CAExBprC,GAAW7nB,QAAQ,SAASgoB,GACxB,GAAI1nB,GAAO0nB,EAASM,SACd4qC,EAAQC,EAAU7yD,EAEpB4yD,IAGAF,GAAY,IAAME,EAAQ,KAE1BD,GAAkB,GAIlBD,GAAY1yD,EAAKgD,QAAQ,cAAe,UAIhD0vD,GAAgC,GAEhC,KACI,MAAO,IAAIzN,QAAOyN,GACpB,MAAOt5D,GACL,KAAM,IAAIU,OAAM,2CAA8CwlB,IAKtE,QAASsI,GAAeF,EAAUorC,GAC9B,GAAI9yD,GAAO0nB,EAASM,SACd+qC,EAAaD,EAAe,EAAI,CACtC,OAA0B,SAAnBprC,EAASG,OACV7nB,EAAK4M,MAAMmmD,EAAY/yD,EAAK9F,OAAS,GACrC8F,EAAK4M,MAAMmmD,GAKrB,QAAS1xC,GAAqB2xC,GAC1BA,EAAeA,IAAiB,KAAM,MACtC,IAAIC,GAAiBv4D,EAAE6kD,YAAYyT,EAAc,SAASrzD,GACtD,GAAIuzD,GAAa14D,KAAKmF,EAEtB,OAAO,UAAS2f,EAAMpC,GAClB,GAAIi2C,GAAY3D,EAAgBlwC,EAChC4zC,GAAWj5D,KAAKO,KAAM24D,EAAWj2C,KAEtC1iB,KACHE,GAAEuB,iBAAiBzB,KAAMy4D,GAvI7B,GAAI32D,GAAQ1C,EAAQ,iBACd4C,EAAQF,EAAME,MACd9B,EAAId,EAAQ,aAEdwnB,GACAoG,gBAAiBA,EACjBgoC,gBAAiBA,EACjB5nC,eAAgBA,EAChBvG,qBAAsBA,EAG1BjnB,GAAOJ,QAAUonB,CAGjB,IAAIgyC,GAAqB,8BACnBC,EAAkB,eAClBC,EAAsB,iBACtBC,EAA4B,MAAQD,EACpCE,EAAyB,MAAQF,EAAsB,MAEvDG,EAAqB,SACrBC,EAAkB,YAClBC,EAAa,MAEbC,GACsBR,EACAC,EACAE,EACAC,GACFvwD,KAAK,KACzBmvD,EAAmB,GAAInN,QAAO2O,EAAiB,KAE/CC,GAC8BD,EACAH,EACAC,EACAC,GACF1wD,KAAK,KACjCwvD,EAA0B,GAAIxN,QAAO4O,EAAwB,KAG7DtB,GACEuB,KAAOjsC,OAAQ,SAAUoI,MAAO,MAChC8jC,KAAOlsC,OAAQ,QAASoI,MAAO,MAC/B+jC,KAAOnsC,OAAQ,QAASoI,MAAO,OA2BnC4iC,GACAoB,KAAMb,EACNc,MAAOb,EAEXR,GAAU,KAAOA,EAAU,MAAQ,IAAMA,EAAU,SA+DhDv0D,gBAAgB,IAAIrD,YAAY,MAAMsyF,KAAK,SAAS3zF,QAAQQ,OAAOJ,SACtE,YAqEA,SAASo6D,wBAAuB90C,EAAMiI,GAClC,GAAIyoC,GAAUt1D,EAAE6c,QAAQ88C,aAAc,SAASC,GAC3C,MAAOC,aAAYD,EAAUh1C,EAAMiI,IAEvC,OAAOyoC,GAOX,QAASuE,aAAYC,YAAal1C,KAAMiI,YAiBpC,QAASktC,kBAAiB53C,EAAU63C,EAAchkD,GAC9CmM,EAAS5S,KAAKyG,GACdgkD,EAAahkD,EAAI4O,MAAQ5O,EAG7B,QAASikD,wBAAuB93C,EAAU63C,EAAc9C,EAAUruC,EAAUC,GACxE,GAAIoxC,GAAYC,YAAYtxC,GACtBuxC,EAAYD,YAAYrxC,EAE1BsxC,IACAC,YAAYl4C,EAAU63C,EAAc9C,EAAUpuC,EAAU,QAAS,YAEjEoxC,GACAG,YAAYl4C,EAAU63C,EAAc9C,EAAUruC,EAAU,UAAW,YAG3E,QAASwxC,aAAYl4C,EAAU63C,EAAc9C,EAAU/tB,EAAKxhB,EAAS2yC,GAIjE,QAASC,GAAarD,EAAU/tB,GAC5B,GAAIrkC,MAAMC,QAAQokC,GAAM,CACpB,GAAI/f,GAAa8tC,EAAW,MAC5B/tB,GAAInkC,QAAQ,SAAS9D,EAAO4oB,GACxB0wC,EAAWt5D,EAAO4oB,EAAOV,SAE1B,CACH,GAAIA,GAAa8tC,EAAW,KAC5Bl3D,GAAEqB,QAAQ8nC,EAAK,SAASjoC,EAAOioB,GAC3BqxC,EAAWt5D,EAAOioB,EAAKC,MAKnC,QAASoxC,GAAWt5D,EAAOioB,EAAKC,GAC5B,GAAIxE,GAAOwE,EAAW9gB,QAAQ,KAAM6gB,GAC9BsxC,EAAcT,EAAap1C,EAEjC,IAAI61C,EACIA,EAAYj/C,MAAQmM,EACpBvlB,OAAOC,MAAM,4DAEbo4D,EAAYj/C,KAAO,UACnBi/C,EAAYH,GAAap5D,OAE1B,CACH,GAAI8U,IAAQ4O,KAAMA,EAAMpJ,KAAMmM,EAC9B3R,GAAIskD,GAAap5D,EACjB64D,iBAAiB53C,EAAU63C,EAAchkD,GAGzCmkD,YAAYj5D,IACZq5D,EAAa31C,EAAM1jB,GAnC3Bq5D,EAAarD,EAAU/tB,GAuC3B,QAASuxB,WAAUx5D,GACf,MAAOy5D,qBAAoBz5D,GACjBlB,EAAEmgC,UAAUj/B,GACZA,EAGd,QAAS05D,cAAa15D,GAClB,MAASy5D,qBAAoBz5D,GAEnB4D,MAAMC,QAAQ7D,GACVA,EAAMgR,QACN5Q,OAAOgK,OAAOpK,GAHlBA,EAMd,QAASi5D,aAAYj5D,GACjB,MAAOy5D,qBAAoBz5D,IAChBI,OAAO+V,KAAKnW,GAAO1B,OAGlC,QAASm7D,qBAAoBz5D,GACzB,QAAgB,MAATA,GACoB,gBAATA,IACJA,YAAiBy/C,OACjBz/C,YAAiBqpD,SAGnC,QAASsQ,sBAAqB7kD,EAAK8kD,EAASC,GACxC/6D,EAAEuB,iBAAiByU,GACfglD,WAAYF,EACZG,SAAUF,IArGlB,GAAIr2D,QACEw2D,WAAapB,aACXjtC,WAAYA,WACZK,eAAgBxG,UAAUwG,gBAGlC,KACIiuC,KAAKD,YACP,MAAOx8D,GACL,KAAMo5D,YAAW,6CAA+ClzC,KAAO,WAAas2C,YAGxF,MAAOx2D,QA3FX,GAAIgiB,WAAYxnB,QAAQ,iBAClB4sB,WAAa5sB,QAAQ,kBACrBkD,OAASlD,QAAQ,qBACjBk8D,GAAKl8D,QAAQ,MACb4vB,IAAM5vB,QAAQ,OACdc,EAAId,QAAQ,aACZooB,kBAAoBpoB,QAAQ,kBAC5B4oB,mBAAqBR,kBAAkBQ,mBACvCwC,wBAA0BhD,kBAAkBgD,wBAM9C+wC,WACAz0D,IAAK,2XACLsD,IAAK,8+CACLmgB,IAAK,+sCACLkB,OAAQ,4qGAGR+vC,gBAAkB,khEAChBC,oBAAsB,w6EACtBC,sBAAwB,+8BAE1BC,QACAH,gBAAiBA,gBACjBC,oBAAqBA,oBACrBC,sBAAuBA,sBACvBtuC,eAAgBxG,UAAUwG,eAC1BwuC,kBAAmB,oBACnBC,qBAAsB,6CACtBC,mBAAoB,8BACpBnI,kBAAmB,kCAGnBoI,YAAc77D,EAAEy7D,QAAQx4D,QAAQC,QAChCw4D,kBAAmB,aACnBC,qBAAsB,sCACtBC,mBAAoB,uBACpBnI,kBAAmB,4BACpBzzD,IAGC87D,YAAc97D,EAAEiD,MAAM6rB,IAAIitC,iBAC9BD,aAAYE,OAAQ,CAEpB,IAAIrC,cAAe35D,EAAE6c,QAAQw+C,UAAW,SAASY,GAC7C,MAAOntC,KAAI/U,SAASkiD,EAAMH,YAAaL,UAIvCS,kBAAoBl8D,EAAE6kD,aAAa,MAAO,MAAO,UAAW,SAAS5/C,GACrE,MAAO6pB,KAAI/U,SAASshD,UAAUp2D,GAAa62D,YAAaD,eAYxDM,sBAAwBn8D,EAAEo8D,QAAQ1C,uBAAwB5xD,OAAW,KAUrEikB,qBAAuBD,WAAWC,oBAsHtCrsB,QAAOJ,QAAU68D,qBAEjB,IAAI9H,cAAer0D,EAAE6c,QAAQq/C,kBAAmB,SAASpC,GACrD,MAAOD,aAAYC,EAAa,QAGpCqC,uBAAsB9H,aAAeA,eAElCjuC,oBAAoB,IAAIi2C,iBAAiB,IAAIC,iBAAiB,IAAIC,gBAAgB,IAAI9oC,IAAM,IAAI2nC,GAAK,IAAI76D,YAAY,MAAMuyF,KAAK,SAAS5zF,EAAQQ,EAAOJ,GAC3Je,UAAU,GAAG,IAAI,GAAGD,MAAMd,EAAQe,aAC/B8F,YAAY,IAAI5F,YAAY,MAAMwyF,KAAK,SAAS7zF,EAAQQ,GAC3D,YAKA,IAAIyI,IACA/F,OAAQlD,EAAQ,YAChB0C,MAAO1C,EAAQ,WAGnBQ,GAAOJ,QAAU6I,IAEdujE,UAAU,IAAIX,WAAW,MAAMioB,KAAK,SAAS9zF,EAAQQ,EAAOJ,GAC/De,UAAU,GAAG,KAAK,GAAGD,MAAMd,EAAQe,aAChCuzE,iBAAiB,MAAMqf,KAAK,SAAS/zF,EAAQQ,EAAOJ,GACvDe,UAAU,GAAG,KAAK,GAAGD,MAAMd,EAAQe,aAChCE,YAAY,MAAM2yF,KAAK,SAASh0F,EAAQQ,GAC3CA,EAAOJ,QAAQJ,EAAQ,UACjBi0F,KAAK,SAASj0F,EAAQQ,GAC5BA,EAAOJ,QAAQJ,EAAQ,OACpB6qF,QAAQ,IAAI3uB,GAAK,MAAMg4B,KAAK,SAASl0F,EAAQQ,GAChD,YAsJA,SAAS2zF,GAAMz5D,GAEX,GAAI05D,GAAUhyF,OAAOgK,OAAO+nF,EAAMnxF,UAElC,OADAoxF,GAAQ15D,KAAOA,EACR05D,EAuBX,QAASC,KAAgB,MAAOzzF,MAAK85B,KA/KrC,GAAI45D,GAAQt0F,EAAQ,WAWhBu0F,EAAmBv0F,EAAQ,qBA8B3Bw0F,EAAgBx0F,EAAQ,kBAmBxBy0F,EAAez0F,EAAQ,iBAsBvB00F,EAAkB10F,EAAQ,oBAiB1B20F,EAAgB30F,EAAQ,kBAQxB40F,EAAgB50F,EAAQ,kBAexB60F,EAAc70F,EAAQ,gBAqCtB80F,IAEJN,GAAcxwF,OAAO3D,KAAKy0F,EAAIN,GAC9BM,EAAG9wF,OAAO3D,KAAKy0F,EAAIP,GACnBO,EAAG9wF,OAAO3D,KAAKy0F,EAAIL,GACnBK,EAAG9wF,OAAO3D,KAAKy0F,EAAIH,GACnBG,EAAG9wF,OAAO3D,KAAKy0F,EAAIF,GACnBE,EAAG9wF,OAAO3D,KAAKy0F,EAAIJ,GACnBI,EAAG9wF,OAAO3D,KAAKy0F,EAAID,GAInBC,EAAGxyF,eAAe6xF,EAAO,KAAMW,GAK/BA,EAAG1zF,YAAYf,KAAK8zF,GAASrzF,EAAGuzF,IAGhCS,EAAG9wF,OAAO3D,KAAK8zF,EAAOK,EAAcO,WAGpC,IAAIC,GAAaF,EAAGn3E,QAAQtd,KAAKy0F,EAAIR,EAAMW,mBAAmB,EAC9DH,GAAG9wF,OAAO3D,KAAK8zF,EAAOa,EAGtB,IAAIE,GAAuBJ,EAAGn3E,QAAQtd,KAAKy0F,EAAIR,EAAMa,yBAAyB,EAC9EL,GAAG1zF,YAAYf,KAAK8zF,EAAOe,GAMN,gBAAV/kE,UAEHA,OAAOrvB,IACPqzF,EAAMiB,WAAajlE,OAAOrvB,GAG9BqvB,OAAOrvB,EAAIqzF,GAGM,gBAAV3zF,IAAsBA,EAAOJ,UAEpCI,EAAOJ,QAAU+zF,KAElBkB,gBAAgB,IAAIC,mBAAmB,IAAIC,iBAAiB,IAAIC,iBAAiB,IAAIC,oBAAoB,IAAIC,iBAAiB,IAAIC,eAAe,IAAIC,UAAU,MAAMC,KAAK,SAAS71F,EAAQQ,GAC9L,YAqFA,SAASyT,GAAY6hF,GACjB,IAAMA,EAAcx1F,OAAQ,MAAOM,KAC7BgF,OAAMC,QAAQiwF,KAChBA,EAAgBjiF,EAAQxT,KAAKy1F,GAEjC,IAAI/iF,IAAQnS,KAAKN,OAAQ,GAAG2+B,OAAO62D,EAGnC,OAFArB,GAAapoE,OAAOnrB,MAAMN,KAAMmS,GAEzBnS,KAYX,QAASm1F,GAAaC,GAClB,IAAMA,EAAe11F,OAAQ,MAAOM,KAC9BgF,OAAMC,QAAQmwF,KAChBA,EAAiBniF,EAAQxT,KAAK21F,GAElC,IAAIjjF,IAAQ,EAAG,GAAGksB,OAAO+2D,EAGzB,OAFAvB,GAAapoE,OAAOnrB,MAAMN,KAAMmS,GAEzBnS,KAYX,QAAS62E,GAAW3qD,GAChB,GAAIlC,GAAQhqB,KAAKqkB,QAAQ6H,EAEzB,OADIlC,IAAS,GAAGhqB,KAAKyrB,OAAOzB,EAAO,GAC5BhqB,KAUX,QAASiT,KACL,MAAO4gF,GAAazhF,MAAM3S,KAAKO,MAWnC,QAASioC,GAAOotD,GACZ,GAAIhsD,MACEisD,EAAgBtwF,MAAMC,QAAQowF,EAKpC,OAJAxB,GAAa3uF,QAAQzF,KAAKO,KAAM,SAASqpB,EAAKW,GAC1Cqf,EAAIhgB,GAAOisE,EAAgBD,EAAOrrE,GAASqrE,IAGxChsD,EAaX,QAAS0b,GAAYvlC,EAAU9O,GAC3B,GAAI4B,KAIJ,OAHAtN,OAAM5C,UAAU8C,QAAQzF,KAAKO,KAAM,SAASoB,EAAO4oB,GAC/C1X,EAAOlR,GAASoe,EAAS/f,KAAKiR,EAAStP,EAAO4oB,EAAOhqB,OACtDA,MACIsS,EAWX,QAASijF,GAAO/1E,GAcZ,QAASg2E,GAAUtpE,GACf,MAAO2nE,GAAapoC,UAAUhsD,KAAKg2F,EAAU,SAASC,GAClD,MAAOl2E,GAAS0M,EAAMwpE,KAI9B,QAASC,GAAYzpE,GACjB,MAAOupE,GAASpxE,QAAQ6H,GApB5B,GAAIupE,KAUJ,OATMj2E,KACFg2E,EAAYG,GAEhB31F,KAAKkF,QAAQ,SAASgnB,GAClB,GAAIlC,GAAQwrE,EAAUtpE,EACT,KAATlC,GACAyrE,EAAShmF,KAAKyc,KAGfupE,EAsBX,QAAS7X,GAAYp+D,EAAU9O,GAI3B,QAASklF,KACL/B,EAAa3uF,QAAQzF,KAAKO,KAAM,SAASoB,GACjC4D,MAAMC,QAAQ7D,GACdw0F,EAAan2F,KAAK2B,GAElBoe,EAAS/f,KAAKiR,EAAStP,EAAO4oB,IAAS8hB,KARnD,GAAI9hB,GAAQ,EAAG8hB,EAAM9rC,IACrB41F,GAAan2F,KAAKO,MA3NtB,GAAIk0F,GAAK90F,EAAQ,kBACXs0F,EAAQt0F,EAAQ,WAiBlBy0F,EAAej0F,EAAOJ,SAGtB6T,YAAaA,EACb8hF,aAAcA,EACdliF,QAASA,EACTg1B,OAAQA,EACR8c,YAAaA,EACbwwC,OAAQA,EACR3X,YAAaA,EACb/G,WAAYA,GAQZgf,GAA4B,OAAQ,MAAO,OAAQ,SACnD,UAAW,QAAS,UAAW,QAAS,SACxC,OAAQ,SAAU,UAAW,OAAQ,QACrC,MAAO,UAAW,cAAe,SAAU,eAE3CC,EAAqB/wC,EAAYtlD,KAAKo2F,EAClC,SAAS1wF,GACL,MAAOH,OAAM5C,UAAU+C,IAGnC+uF,GAAG9wF,OAAO3D,KAAKo0F,EAAciC,GAY7BjC,EAAar4E,KAAOxW,MAAM5C,UAAUoZ,MAC7Bk4E,EAAMqC,eAAelC,EAAa3uF,QAAS,SAYlD2uF,EAAapoC,UAAYzmD,MAAM5C,UAAUqpD,WAClCioC,EAAMqC,eAAelC,EAAa3uF,QAAS,WA+J/C0vF,iBAAiB,IAAII,UAAU,MAAMgB,KAAK,SAAS52F,QAAQQ,OAAOJ,SACrE,YA2DA,SAASg+D,cAAay4B,KAAMC,KAAMC,UAM9B,IAAK,GALDl2F,MAAOD,KACL4pB,MAAQrpB,UAAUb,OAAS,EAC3By2F,SAAW51F,UAAUqpB,OACrBjZ,KACA80E,KAAO,GACJpmF,EAAI,EAAOuqB,MAAJvqB,EAAWA,IACvBomF,MAAQ,KAAOllF,UAAUlB,EAI7B,OAHAomF,OAAQ,mBAAoBxlF,KAAM,IAAKwlF,KAAKrzE,MAAM,GAAI,QACxC+jF,SAAU,OAAO1tF,KAAK,IACpC4yD,KAAKoqB,MACE90E,KAWX,QAAS4T,WACL,GAAI5T,GAAO3Q,KACPmS,EAAOC,MAAM3S,KAAKc,UACtB,OAAO,YACH,MAAOoQ,GAAKrQ,MAAMN,KAAMmS,EAAKksB,OAAOjsB,MAAM3S,KAAKc,cAYvD,QAAS61F,gBACL,GAAIzlF,GAAO3Q,KACPmS,EAAOC,MAAM3S,KAAKc,UACtB,OAAO,YACH,MAAOoQ,GAAKrQ,MAAMN,KAAMoS,MAAM3S,KAAKc,WAAW89B,OAAOlsB,KAa7D,QAASmqD,SAAQ+5B,EAAUC,GACvB,GAAI3lF,GAAO3Q,KACPu2F,KAAYC,IAGhB,OAFAF,GAAQA,GAAS,IAEV,WACH,GAAIjtE,GAAMgtE,EAAWA,EAAS/1F,MAAMN,KAAMO,WAAaA,UAAU,EACjE,IAAIg2F,EAAM/yF,eAAe6lB,GACrB,MAAOktE,GAAMltE,EAEjB,IAAI/W,GAASikF,EAAMltE,GAAO1Y,EAAKrQ,MAAMN,KAAMO,UAM3C,OALAi2F,GAAS/mF,KAAK4Z,GAEVmtE,EAAS92F,OAAS42F,SACXC,GAAMC,EAAS7mF,SAEnB2C,GAaf,QAASomE,OAAM+d,GACX,GAAItkF,GAAOC,MAAM3S,KAAKc,UAAW,EACjC,OAAOm2F,QAAO12F,KAAMy2F,EAAMtkF,GAW9B,QAAS7B,SACL,MAAOomF,QAAO12F,KAAM,EAAGO,WAG3B,QAASm2F,QAAO/lF,EAAM8lF,EAAMtkF,EAAM2Q,GAC9B,MAAO86B,YAAWjtC,EAAKrQ,MAAMwE,KAAK6L,EAAMmS,GAAW,KAAM3Q,GAAOskF,GAgBpE,QAASE,YAAWC,GAChB,GAAY,EAARA,EAAW,MAAOtmF,OAAMhQ,MAAMN,KAAMO,UACxC,IAAI4R,GAAOmsB,OAAO7+B,KAAKo3F,UAAWD,EAAQ,EAE1C,OADAzkF,GAAOA,EAAKksB,OAAOr+B,KAAMoS,MAAM3S,KAAKc,UAAW,IACxCs2F,UAAUv2F,MAAM,KAAM6R,GAYjC,QAAS2kF,aAAYC,EAAkBN,GACnC,GAAItkF,GAAOC,MAAM3S,KAAKc,UAAW,EACjC,OAAOy2F,cAAah3F,KAAM+2F,EAAkBN,EAAMtkF,GAWtD,QAAS9B,aAAY0mF,GACjB,GAAI5kF,GAAOC,MAAM3S,KAAKc,UAAW,EACjC,OAAOy2F,cAAah3F,KAAM+2F,EAAkB,EAAG5kF,GAGnD,QAAS6kF,cAAa/uD,EAAQ8uD,EAAkBN,EAAMtkF,GAClD,MAAOyrC,YAAW,WACd,GAAIjtC,GAAkC,gBAApBomF,GACJ9uD,EAAO8uD,GACPA,CACdpmF,GAAKrQ,MAAM2nC,EAAQ91B,IACpBskF,GAcP,QAASQ,SAAQR,GACb,GAAI9lF,GAAO3Q,KACLmS,EAAOC,MAAM3S,KAAKc,UAAW,EACnC,OAAO,YACH,GAAI22F,GAAW/kF,EAAKksB,OAAOjsB,MAAM3S,KAAKc,WACtC,OAAOm2F,QAAO/lF,EAAM8lF,EAAMS,EAAUl3F,OAc5C,QAASm3F,YACL,GAAIxmF,GAAO3Q,KACLmS,EAAOC,MAAM3S,KAAKc,UACxB,OAAO,YACH,GAAI22F,GAAW/kF,EAAKksB,OAAOjsB,MAAM3S,KAAKc,WACtC,OAAOm2F,QAAO/lF,EAAM,EAAGumF,EAAUl3F,OAazC,QAASo3F,UAASX,EAAMY,GACpB,GACI51C,GAAStvC,EAAM2Q,EAASuhD,EAAW/xD,EADnC3B,EAAO3Q,IAEX,OAAO,YAWH,QAASs3F,KACL,GAAIC,GAAO12C,KAAKsjB,MAAQE,CACboyB,GAAPc,EACA91C,EAAU7D,WAAW05C,EAAOb,EAAOc,IAEnC91C,EAAU,KACJ41C,IACF/kF,EAAS3B,EAAKrQ,MAAMwiB,EAAS3Q,KAjBzC2Q,EAAU9iB,KACVmS,EAAO5R,UACP8jE,EAAYxjB,KAAKsjB,KACjB,IAAIqzB,GAAUH,IAAe51C,CAK7B,OAJMA,KACFA,EAAU7D,WAAW05C,EAAOb,IAC5Be,IACAllF,EAAS3B,EAAKrQ,MAAMwiB,EAAS3Q,IAC1BG,GAwBf,QAAS4mB,UAASu9D,EAAM14E,GAwBpB,QAASu5E,KACLG,EAAW15E,EAAQ25E,WAAY,EAAQ,EAAI72C,KAAKsjB,MAChD1iB,EAAU,KACVnvC,EAAS3B,EAAKrQ,MAAMwiB,EAAS3Q,GA1BjC,GACI2Q,GAAS3Q,EAAMG,EADf3B,EAAO3Q,KAEPyhD,EAAU,KACVg2C,EAAW,CAGf,OAFA15E,KAAYA,MAEL,WACH,GAAIomD,GAAMtjB,KAAKsjB,KACVszB,IAAY15E,EAAQ25E,WAAY,IAAOD,EAAWtzB,EACvD,IAAIwzB,GAAYlB,GAAQtyB,EAAMszB,EAW9B,OAVA30E,GAAU9iB,KACVmS,EAAO5R,UACU,GAAbo3F,GACAjgB,aAAaj2B,GACbA,EAAU,KACVg2C,EAAWtzB,EACX7xD,EAAS3B,EAAKrQ,MAAMwiB,EAAS3Q,IACrBsvC,GAAW1jC,EAAQ65E,YAAa,IACxCn2C,EAAU7D,WAAW05C,EAAOK,IAEzBrlF,GAef,QAASo5B,QACL,GAEMmsD,GAFFlnF,EAAO3Q,KACL83F,GAAM,CAEZ,OAAO,YACH,MAAIA,GAAYD,GAChBC,GAAM,EACND,EAAOlnF,EAAKrQ,MAAMN,KAAMO,WACxBoQ,EAAO,KACAknF,IAef,QAASE,SAAQv4E,EAAUw4E,EAAYC,EAAcC,GAMjD,QAASC,KACL,GAAIx1B,IAAanjD,QACZ,CAAA,KAAIqhC,KAAKsjB,MAAQ9nD,GAAS27E,GAE1B,MADDC,IAAgBA,IAEpBt6C,cAAcimC,GAVlB,GAAIvnE,GAAQwkC,KAAKsjB,MACbxB,EAAY3iE,IAChBk4F,GAAgBA,GAAiB,EACjC,IAAItU,GAAWwU,YAAYD,EAAeD,GAiB9C,QAASG,OACL,GAAI1nF,GAAO3Q,IACX,OAAO,YACH,OAAQ2Q,EAAKrQ,MAAMN,KAAMO,YAjYjC,GAAI8zF,mBAAoBj1F,QAAQ,WAAWi1F,kBACrC/1D,OAASl/B,QAAQ,gBAAgBk/B,OAuBnCw1D,gBAAkBl0F,OAAOJ,SACzBg+D,aAAcA,aACdj5C,QAASA,QACT6xE,aAAcA,aACd95B,QAASA,QACToc,MAAOA,MACPpoE,MAAOA,MACP2mF,QAASA,QACTE,SAAUA,SACVR,WAAYA,WACZG,YAAaA,YACbzmF,YAAaA,YACb+mF,SAAUA,SACVl+D,SAAUA,SACVwS,KAAMA,KACNqsD,QAASA,QACTM,IAAKA,KAILjmF,MAAQpN,MAAM5C,UAAUgQ,MAwHxBykF,UAAYxC,kBAAkB/jF,SAiO/BykF,eAAe,IAAIC,UAAU,MAAMsD,KAAK,SAASl5F,EAAQQ,GAC5D,YAgBA,SAAS24F,KACL,OAAQC,MAAMC,WAAWz4F,QAAU04F,SAAS14F,MAZ5BJ,EAAOJ,SACvB+4F,UAAWA,QAcTI,KAAK,SAASv5F,EAAQQ,GAC5B,YA+GA,SAASwD,GAAOimC,EAAKuvD,GACjB,GAAIC,KAQJ,OANAt3F,GAAQ9B,KAAK4pC,EAAK,SAASjoC,EAAOoE,GAC9BqzF,EAAYrzF,GAAQhE,OAAOs3F,yBAAyBzvD,EAAK7jC,IAC1DxF,KAAM44F,GAETp3F,OAAOC,iBAAiBzB,KAAM64F,GAEvB74F,KAeX,QAASmD,KACL,GAAI6B,MAAMC,QAAQjF,MAAO,MAAOA,MAAKoS,OACrC,IAAIpS,eAAgB6gD,MAAM,MAAO,IAAIA,MAAK7gD,KAC1C,IAAIA,eAAgByqD,QAAQ,MAAO,IAAIA,QAAOzqD,KAC9C,IAAI+4F,GAAev3F,OAAOgK,OAAOxL,KAAKI,YAAYgC,UAElD,OADAgB,GAAO3D,KAAKs5F,EAAc/4F,MACnB+4F,EAuBX,QAASr3F,GAAes3F,EAAc53F,EAAO63F,GAGzC,MAFAz3F,QAAOE,eAAe1B,KAAMg5F,EACxBE,EAAe93F,EAAO63F,IACnBj5F,KAIX,QAASk5F,GAAe93F,EAAO63F,GAC3B,GAAIE,IAAe/3F,MAAOA,EAQ1B,OAPI63F,IACA71F,EAAO3D,KAAK05F,GACRh4F,cAAgB83F,EAAiBG,EAAUC,YAC3CC,gBAAkBL,EAAiBG,EAAUG,cAC7CC,YAAcP,EAAiBG,EAAUK,YAG1CN,EA2BX,QAAS13F,GAAiBi4F,EAAgBT,GACtC,GAAIJ,GAAc97E,EAAQtd,KAAKi6F,EAAgB,SAASt4F,GACpD,MAAO83F,GAAe93F,EAAO63F,KAC9B,EAEH,OADAz3F,QAAOC,iBAAiBzB,KAAM64F,GACvB74F,KAoCX,QAASunD,GAAWle,EAAKuvD,GACrB,MAAOe,GAAY35F,KAAMqpC,EAAKuvD,MAIlC,QAASe,GAAYC,EAAUC,EAASjB,EAAgBkB,GACpD,KAAIA,EAAaz1E,QAAQw1E,IAAY,GAArC,CAGAC,EAAarqF,KAAKoqF,EAElB,IAAIE,GAAO/0F,MAAMC,QAAQ40F,GAAW70F,MAAM5C,UAAU8C,QAAU3D,CAc9D,OAZAw4F,GAAKt6F,KAAKo6F,EAAS,SAASz4F,EAAOoE,GAC/B,GAAI2zF,GAAa33F,OAAOs3F,yBAAyBe,EAASr0F,EACtC,iBAATpE,IAA8B,MAATA,GAClBA,YAAiBqpD,SAAcrpD,YAAiBy/C,MAM1Dr/C,OAAOE,eAAek4F,EAAUp0F,EAAM2zF,IAL/BS,EAASp2F,eAAegC,IACK,gBAAlBo0F,GAASp0F,IAAuC,MAAlBo0F,EAASp0F,KACrDo0F,EAASp0F,GAASR,MAAMC,QAAQ7D,UACpCu4F,EAAYC,EAASp0F,GAAOpE,EAAOw3F,EAAgBkB,KAGxD95F,KAAM44F,GAEFgB,GAWX,QAASv5D,GAAUu4D,GACf,GAAI54F,eAAgB6gD,MAAM,MAAO,IAAIA,MAAK7gD,KAC1C,IAAIA,eAAgByqD,QAAQ,MAAO,IAAIA,QAAOzqD,KAC9C,IAAI+4F,GAAe/zF,MAAMC,QAAQjF,WAEjC,OADAunD,GAAW9nD,KAAKs5F,EAAc/4F,KAAM44F,GAC7BG,EAUX,QAASxhF,KACL,MAAO/V,QAAO+V,KAAKvX,MAUvB,QAASq1F,GAAOuD,GACZ,GAAIloE,GAAakoE,EACHp3F,OAAO+V,KAAKvX,MACZg6F,EAAQv6F,KAAKO,KAE3B,OAAO0wB,GAAWzf,IAAI,SAASzL,GAC3B,MAAOxF,MAAKwF,IACbxF,MAWN,QAASg6F,KACN,MAAOx4F,QAAOy4F,oBAAoBj6F,MAetC,QAASk6F,GAAMC,EAAevB,GAK1B,IAAK,GAJDloE,GAAakoE,EACKp3F,OAAO+V,KAAKvX,MACZg6F,EAAQv6F,KAAKO,MAE1BX,EAAI,EAAGA,EAAIqxB,EAAWhxB,OAAQL,IACnC,GAAI86F,IAAkBn6F,KAAK0wB,EAAWrxB,IAClC,MAAOqxB,GAAWrxB,EAE1B,OAAO2I,QAYX,QAASoyF,GAAUD,EAAevB,GAC9B,GAAIloE,GAAakoE,EACKp3F,OAAO+V,KAAKvX,MACZg6F,EAAQv6F,KAAKO,MAE/BuX,EAAOmZ,EAAW4rB,OAAO,SAAS92C,GAClC,MAAO20F,KAAkBn6F,KAAKwF,IAC/BxF,KAEH,OAAOuX,GAmBX,QAAShW,GAAQie,EAAU9O,EAASkoF,GAChC,GAAIloE,GAAakoE,EACKp3F,OAAO+V,KAAKvX,MACZg6F,EAAQv6F,KAAKO,KAMnC,OAJA0wB,GAAWxrB,QAAQ,SAASM,GACxBga,EAAS/f,KAAKiR,EAAS1Q,KAAKwF,GAAOA,EAAMxF,OAC1CA,MAEIA,KAqBX,QAAS+c,GAAQyC,EAAU9O,EAASkoF,GAKhC,QAASyB,GAAYj5F,EAAOioB,EAAKyQ,GAC7B++D,EAAYxvE,GAAO7nB,OAAOs3F,yBAAyBh/D,EAAMzQ,GACzDwvE,EAAYxvE,GAAKjoB,MAAQoe,EAAS/f,KAAKO,KAAMoB,EAAOioB,EAAKyQ,GAN7D,GAAI++D,KAEJ,OADAt3F,GAAQ9B,KAAKO,KAAMq6F,EAAa3pF,EAASkoF,GAClCp3F,OAAOgK,OAAOxL,KAAKI,YAAYgC,UAAWy2F,GAyBrD,QAASyB,GAAW96E,EAAU+6E,EAAc7pF,EAASkoF,GACjD,GAAIloE,GAAakoE,EACKp3F,OAAO+V,KAAKvX,MACZg6F,EAAQv6F,KAAKO,MAE/B63F,EAAO0C,CAMX,OAJA7pE,GAAWxrB,QAAQ,SAASM,GACxBqyF,EAAOr4E,EAAS/f,KAAKiR,EAASmnF,EAAM73F,KAAKwF,GAAOA,EAAMxF,OACvDA,MAEI63F,EAmBX,QAAS15E,GAAWqB,EAAU9O,EAASkoF,GAKnC,QAAS4B,GAAep5F,EAAOioB,EAAKyQ,GAC5Bta,EAAS/f,KAAKO,KAAMoB,EAAOioB,EAAKyQ,KAChC++D,EAAYxvE,GAAO7nB,OAAOs3F,yBAAyBh/D,EAAMzQ,IANjE,GAAIwvE,KAEJ,OADAt3F,GAAQ9B,KAAKO,KAAMw6F,EAAgB9pF,EAASkoF,GACrCp3F,OAAOgK,OAAOxL,KAAKI,YAAYgC,UAAWy2F,GAqBrD,QAASl1D,GAAQnkB,EAAU9O,EAASkoF,GAShC,QAAS6B,GAAar5F,EAAOioB,EAAKyQ,GAC9B,GAAIta,EAAS/f,KAAKO,KAAMoB,EAAOioB,EAAKyQ,GAChC,KAAM4gE,GAVd,IACIn5F,EAAQ9B,KAAKO,KAAMy6F,EAAc/pF,EAASkoF,GAC5C,MAAOh9E,GACL,GAAIA,IAAS8+E,EAAS,OAAO,CACxB,MAAM9+E,GAEf,OAAO,EAkBX,QAAS++E,GAASn7E,EAAU9O,EAASkoF,GASjC,QAAS6B,GAAar5F,EAAOioB,EAAKyQ,GAC9B,IAAMta,EAAS/f,KAAKO,KAAMoB,EAAOioB,EAAKyQ,GAClC,KAAM8gE,GAVd,IACIr5F,EAAQ9B,KAAKO,KAAMy6F,EAAc/pF,EAASkoF,GAC5C,MAAOh9E,GACL,GAAIA,IAASg/E,EAAa,OAAO,CAC5B,MAAMh/E,GAEf,OAAO,EAkBX,QAASi/E,KACL,GAAItjF,GAAO8mB,EAAO/9B,MAAMw6F,EAAYv6F,WAC9B8oC,EAAM7nC,OAAOgK,OAAOxL,KAAKI,YAAYgC,UAK3C,OAJAmV,GAAKrS,QAAQ,SAASmkB,GACdrpB,KAAKwD,eAAe6lB,KACpBggB,EAAIhgB,GAAOrpB,KAAKqpB,KACrBrpB,MACIqpC,EAWX,QAASyuC,KACL,GAAIvgE,GAAO8mB,EAAO/9B,MAAMw6F,EAAYv6F,WAC9B8oC,EAAMlmC,EAAM1D,KAAKO,KAIvB,OAHAuX,GAAKrS,QAAQ,SAASmkB,SACXggB,GAAIhgB,IACZrpB,MACIqpC,EAUX,QAASmiC,GAAQniC,GACb,GAAIrpC,OAASqpC,EAAK,MAAgB,KAATrpC,MAAc,EAAEA,MAAQ,EAAEqpC,CACnD,IAAY,MAARrpC,MAAuB,MAAPqpC,EAAa,OAAO,CACxC,IAAIxxB,GAAY7X,KAAKI,YAAYH,IACjC,IAAI4X,GAAawxB,EAAIjpC,YAAYH,KAAM,OAAO,CAC9C,QAAQ4X,GACJ,IAAK,SACD,MAAO7X,OAAQkC,OAAOmnC,EAC1B,KAAK,SACD,MAAOrpC,QAASA,KAAOqpC,IAAQA,EAAe,GAARrpC,KAAY,EAAEA,MAAQ,EAAEqpC,EAAMrpC,OAASqpC,CACjF,KAAK,OACL,IAAK,UACD,OAAQrpC,OAASqpC,CACrB,KAAK,SACD,MAAOrpC,MAAKuxD,QAAUloB,EAAIkoB,QACfvxD,KAAKo9D,QAAU/zB,EAAI+zB,QACnBp9D,KAAK+6F,WAAa1xD,EAAI0xD,WACtB/6F,KAAKg7F,YAAc3xD,EAAI2xD,WAE1C,MAAmB,gBAARh7F,OAAkC,gBAAPqpC,IAAwB,EAE1DrkC,MAAMC,QAAQjF,MACPA,KAAKN,QAAU2pC,EAAI3pC,QACfM,KAAKsyD,MAAM,SAASpmC,EAAMlC,GACzB,MAAOwhD,GAAQ/rE,KAAKysB,EAAMmd,EAAIrf,MAGnCgwE,EAAQv6F,KAAKO,MAAMN,QAAUs6F,EAAQv6F,KAAK4pC,GAAK3pC,QAC3Ci7F,EAASl7F,KAAKO,KAAM,SAASoB,EAAOioB,GACnC,MAAOmiD,GAAQ/rE,KAAK2B,EAAOioC,EAAIhgB;GAYnD,QAAS4xE,GAAM5xD,GACX,OAAQmiC,EAAQ/rE,KAAKO,KAAMqpC,GApnB/B,GAAIqqD,GAAQt0F,EAAQ,WA8BhBw0F,EAAgBh0F,EAAOJ,SACvB4D,OAAQA,EACRD,MAAOA,EACPzB,eAAgBA,EAChBD,iBAAkBA,EAClB8lD,WAAYA,EACZlnB,UAAWA,EACX9oB,KAAMA,EACNyiF,QAASA,EACT3E,OAAQA,EACR6E,MAAOA,EACPE,UAAWA,EACX74F,QAASA,EACTwb,QAASA,EACTu9E,WAAYA,EACZn8E,WAAYA,EACZwlB,QAASA,EACTg3D,SAAUA,EACVE,SAAUA,EACV/iB,SAAUA,EACVtM,QAASA,EACTyvB,MAAOA,GAQP7B,GACAC,WAAY,EACZ52F,KAAM,EACN82F,aAAc,EACd/jD,KAAM,EACNikD,SAAU,EACV10F,KAAM,EAGVrD,GAAejC,KAAKm0F,EAAe,aAAcwF,GAajDxF,EAAcsH,UAAYxH,EAAMqC,eAAex0F,EAAS,SAaxDqyF,EAAcuH,QAAUzH,EAAMqC,eAAex0F,EAAS,MA4YtD,IAAIm5F,MACEE,KAoDFE,EAAa91F,MAAM5C,UACjBi8B,EAASy8D,EAAWz8D,SAuFvB22D,UAAU,MAAMoG,KAAK,SAASh8F,QAAQQ,OAAOJ,SAChD,YA2CA,SAASgB,aAAYg1D,GACjB,GAAI6lC,KAYJ,OAVAnH,IAAG3yF,QAAQ9B,KAAK+1D,EAAS,SAAS5wD,EAAQ3E,GACtCo7F,EAAgBp7F,IACZkB,YAAY,EACZm4F,cAAc,EACdE,UAAU,EACVp4F,MAAOwD,KAIfpD,OAAOC,iBAAiBzB,KAAKoC,UAAWi5F,GACjCr7F,KAeX,QAAS0D,gBAAezD,KAAMq7F,kBAC1B,GAAIC,WAAYv7F,KACZw7F,QAGJv7F,MAAOA,MAAQ,EAGf,IAAIw7F,iBAAkBH,oBAAqB,EACjC,GACA,mCAWV,OATAjgC,MAAK,uBAAyBp7D,KAAO,OAASw7F,gBAAkB,MAEhE9rB,aAAalwE,KAAK+7F,SAAUD,WAK5BrH,GAAG3sC,WAAW9nD,KAAK+7F,SAAUD,WAAW,GAEjCC,SAYX,QAAS7rB,cAAa/M,GAQlB,MANA5iE,MAAKoC,UAAYZ,OAAOgK,OAAOo3D,EAAWxgE,WAG1C5B,YAAYf,KAAKO,MACbI,YAAaJ,OAEVA,KAUX,QAASuT,UAASpB,GACRnN,MAAMC,QAAQkN,KAChBA,EAAOnN,MAAM5C,UAAUgQ,MAAM3S,KAAK0S,GAEtC,IAAIA,IAAQ,MAAMksB,OAAOlsB,EACzB,OAAO,KAAKpQ,SAASK,UAAU0C,KAAKxE,MAAMN,KAAMmS,IArHpD,GAAIwhF,kBAAmB/zF,OAAOJ,SAC1BgB,YAAaA,YACbkD,eAAgBA,eAChBisE,aAAcA,aACdp8D,SAAUA,UAIV2gF,GAAK90F,QAAQ,iBAEjB80F,IAAG9wF,OAAO3D,KAAKy0F,GAAI90F,QAAQ,uBA8GxBs1F,mBAAmB,IAAIE,iBAAiB,MAAM8G,KAAK,SAASt8F,QAAQQ,OAAOJ,SAC9E,YAqCA,SAASiY,kBACL,MAAOzX,MAAOA,KAAK,GAAG27F,cAAgB37F,KAAKoS,MAAM,GAAKpS,KAS1D,QAASG,kBACL,MAAOH,MAAOA,KAAK,GAAGulC,cAAgBvlC,KAAKoS,MAAM,GAAKpS,KAU1D,QAASkhF,YACL,GAAI0a,GAAK57F,KAAKyH,MAAMo0F,oBACpB,OAAID,GAAW,GAAInxC,QAAOmxC,EAAG,GAAIA,EAAG,IAApC,OAWJ,QAAS3a,cACL,GAAItwE,MACA80E,KAAO,UAAYzlF,KAAO,GAC9B,KAEI,MADAq7D,MAAKoqB,MACE90E,KACT,MAAM/R,GACJ,QAWR,QAASivC,UACL,GAAM7tC,KAAN,CACA,IACI,GAAI0tC,GAAO,GAAImT,MAAK7gD,MACtB,MAAOpB,IACT,MAAI8uC,IAAQA,EAAKouD,UAAYtD,MAAM9qD,EAAKouD,WAC7BpuD,EADX,QAYJ,QAASm/B,eAAcG,GACnB,GAAI+uB,GAAK,GACH/lE,EAASh2B,SACTgtE,EAASA,GAAUgvB,kBAMzB,OAJA9H,IAAG3yF,QAAQ9B,KAAKu2B,EAAQ,SAAS50B,EAAOioB,GACpC0yE,GAAM1yE,EAAM,IAAM2jD,EAAO5rE,GAAS,MAG/B26F,EAAG3pF,MAAM,EAAG,IAWvB,QAASi7D,iBAAgBD,GACrB,GAAI6uB,GAAQj8F,KAAK8H,MAAM,KACjBo0F,KACA9uB,EAASA,GAAU+uB,kBAWzB,OATAF,GAAM/2F,QAAQ,SAASk3F,GACnB,GAAIC,GAAYD,EAAKt0F,MAAM,IAC3B,MAAIu0F,EAAU38F,OAAS,GAAvB,CACA,GAAI2pB,GAAMgzE,EAAU,GACdj7F,EAAQgsE,EAAOivB,EAAU,IAAM,GAChChzE,KACL6yE,EAAQ7yE,GAAOjoB,MAGZ86F,EAUX,QAAS1jF,aACL,IACI,MAAOH,MAAK/Q,MAAMtH,MACpB,MAAOpB,KAUb,QAAS09F,YAIL,IAAK,GAHDC,GAAO,KACLzmC,EAAM91D,KACNglB,EAAM8wC,EAAIp2D,OACPL,EAAI,EAAO2lB,EAAJ3lB,EAASA,IAAK,CAC1B,GAAIolF,GAAO3uB,EAAI0T,WAAWnqE,EAC1Bk9F,IAASA,GAAQ,GAAKA,EAAQ9X,EAElC,MAAO8X,GAUX,QAAS/kC,UAAS1B,GACd,MAAyB,IAArB91D,KAAKqkB,QAAQyxC,GACN91D,KAAKwI,QAAQstD,EAAK,IAD7B,OAnLJ,GAAIo+B,IAAK90F,QAAQ,kBAeZ20F,cAAgBn0F,OAAOJ,SACxBiY,eAAgBA,eAChBtX,eAAgBA,eAChB+gF,SAAUA,SACVD,WAAYA,WACZpzC,OAAQA,OACRg/B,cAAeA,cACfQ,gBAAiBA,gBACjB70D,UAAWA,UACX8jF,SAAUA,SACV9kC,SAAUA,UAkCVqkC,oBAAsB,wBA4HvBjH,iBAAiB,MAAM4H,KAAK,SAASp9F,EAAQQ,GAChD,YAgCA,SAAS68F,GAAMj9E,EAAU9O,GAErB,IAAK,GADDo7B,GAAM9mC,MAAMu5C,KAAKvQ,IAAI,EAAGhuC,OACnBX,EAAI,EAAOW,KAAJX,EAAUA,IACtBysC,EAAIzsC,GAAKmgB,EAAS/f,KAAKiR,EAASrR,EACpC,OAAOysC,GAUX,QAASxN,GAAOm+D,GAEZ,IAAK,GADD3wD,GAAM9mC,MAAMu5C,KAAKvQ,IAAI,EAAGyuD,IACnBp9F,EAAI,EAAOo9F,EAAJp9F,EAAWA,IACvBysC,EAAIzsC,GAAKW,IACb,OAAO8rC,GAWX,QAAS4wD,GAAI/rF,GAET,MADAA,GAAKlR,KAAKO,KAAMA,MACTA,KAYX,QAASsS,GAAO5B,GACZ,GAAIyB,GAAOnN,MAAM5C,UAAUgQ,MAAM3S,KAAKc,UAAW,EACjD,OAAsB,kBAARP,MACJA,KAAKM,MAAMoQ,EAASyB,GACpBnS,KAUd,QAAS28F,KACL,MAAO38F,MAUX,QAASwtB,KACL,GAAInE,GAAMrpB,IACV,OAAO,UAASqpC,GACZ,MAAOA,GAAIhgB,IAWnB,QAASuzE,KACL,GAAIvzE,GAAMrpB,IACV,OAAO,UAASb,EAAG09F,GACf,MAAO19F,GAAEkqB,GAAOwzE,EAAExzE,GACZ,GACAlqB,EAAEkqB,GAAOwzE,EAAExzE,GACP,EACA,GAQlB,QAASixB,MArHS16C,EAAOJ,SACrBi9F,MAAOA,EACPn+D,OAAQA,EACRo+D,IAAKA,EACLpqF,OAAQA,EACRqqF,SAAUA,EACVnvE,SAAUA,EACVovE,gBAAiBA,EACjBtiD,KAAMA,QA+GJwiD,KAAK,SAAS19F,EAAQQ,GAC5B,YASA,SAAS20F,GAAwB3vF,GAC7B,MAAO,YAEH,MADA5E,MAAK85B,KAAOl1B,EAAOtE,MAAMN,KAAK85B,KAAMv5B,WAC7BP,MAKf,QAASq0F,GAAkBzvF,GACvB,MAAO,YAGH,MAAOA,GAAOnF,KAAKa,MAAMsE,EAAQrE,YAczC,QAASw1F,GAAegH,EAAYC,GAChC,GAAIC,GAAuB,SAAZD,EAAsB,EAAI,CAEzC,OAAO,UAA0Bx9E,EAAU9O,EAASkoF,GAYhD,QAASsE,GAAS97F,EAAO4oB,EAAO8P,GAC5B,GAAIle,EACJ,KACIA,EAAO4D,EAAS/f,KAAKO,KAAMoB,EAAO4oB,EAAO8P,GAC3C,MAAM2gB,GAEJ,KADA0iD,GAAc1iD,EACR2iD,EAEV,GAAIxhF,EACA,KAAMrb,WAAU08F,GApBxB,GAAIE,EACJ,KACIJ,EAAWt9F,KAAKO,KAAMk9F,EAAUxsF,EAASkoF,GAC3C,MAAO9mE,GACL,GAAIA,IAAUsrE,EAAQ,KAAMD,EACvB,OAAOrrE,GAGhB,MAAImrE,IAAYF,GAAc/3F,MAAM5C,UAAU8C,QACnC,GADX,QA7CR,GAwBIk4F,IAxBQx9F,EAAOJ,SACf+0F,wBAAyBA,EACzBF,kBAAmBA,EACnB0B,eAAgBA,GAqBP,GAAIz2F,aAsCX+9F,KAAK,SAASj+F,EAAQQ,EAAOJ,GACnCe,UAAU,GAAG,KAAK,GAAGD,MAAMd,EAAQe,aAChCk0F,gBAAgB,IAAIC,mBAAmB,IAAIC,iBAAiB,IAAIC,iBAAiB,IAAIC,oBAAoB,IAAIC,iBAAiB,IAAIC,eAAe,IAAIC,UAAU,MAAMsI,KAAK,SAASl+F,EAAQQ,EAAOJ,GACrMe,UAAU,GAAG,KAAK,GAAGD,MAAMd,EAAQe,aAChCq0F,iBAAiB,IAAII,UAAU,MAAMuI,KAAK,SAASn+F,EAAQQ,GAC9DA,EAAOJ,QAAQJ,EAAQ,OACpB21F,eAAe,IAAIC,UAAU,MAAMwI,KAAK,SAASp+F,EAAQQ,GAC5DA,EAAOJ,QAAQJ,EAAQ,UACjBq+F,KAAK,SAASr+F,EAAQQ,GAC5BA,EAAOJ,QAAQJ,EAAQ,OACpB41F,UAAU,MAAM0I,KAAK,SAASt+F,EAAQQ,EAAOJ,GAChDe,UAAU,GAAG,KAAK,GAAGD,MAAMd,EAAQe,aAChCm0F,mBAAmB,IAAIE,iBAAiB,MAAM+I,KAAK,SAASv+F,EAAQQ,EAAOJ,GAC9Ee,UAAU,GAAG,KAAK,GAAGD,MAAMd,EAAQe,aAChCq0F,iBAAiB,MAAMgJ,KAAK,SAASx+F,EAAQQ,GAChDA,EAAOJ,QAAQJ,EAAQ,UACjBy+F,KAAK,SAASz+F,EAAQQ,GAC5BA,EAAOJ,QAAQJ,EAAQ,eACZ","sourceRoot":"/"} \ No newline at end of file diff --git a/package.json b/package.json index 851ab32..3fed3cf 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,13 @@ "dependencies": { "async": "~0.2.9", "base32": "git://github.com/milojs/base32-js.git", + "dot": "^1.0.3", + "milo-core": "^0.1.13", + "mol-proto": "^0.1.12" + }, + "devDependencies": { "brfs": "0.0.8", "browserify": "~2.35.4", - "dot": "^1.0.3", "grunt": "~0.4.1", "grunt-browserify": "~1.2.11", "grunt-contrib-uglify": "~0.2.7", @@ -40,7 +44,6 @@ "karma-spec-reporter": "0.0.6", "karma-webdriver-launcher": "^0.2.0", "mocha": "~1.16.2", - "mol-proto": "git://github.com/milojs/proto.git", "requirejs": "~2.1.9" } }