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});\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});\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:'