@adobe/cq-angular-editable-components
Version:
* [API](#api) * [Documentation](#documentation) * [Changelog](#changelog)
675 lines (659 loc) • 75.3 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@adobe/cq-spa-component-mapping'), require('@adobe/cq-spa-page-model-manager'), require('@angular/core'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('@adobe/cq-angular-editable-components', ['exports', '@adobe/cq-spa-component-mapping', '@adobe/cq-spa-page-model-manager', '@angular/core', '@angular/common'], factory) :
(factory((global.adobe = global.adobe || {}, global.adobe['cq-angular-editable-components'] = {}),null,null,global.ng.core,global.ng.common));
}(this, (function (exports,cqSpaComponentMapping,cqSpaPageModelManager,core,common) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var ComponentMappingWithConfig = (function () {
function ComponentMappingWithConfig(spaMapping) {
this.spaMapping = spaMapping;
this.editConfigMap = new WeakMap();
}
/**
* @param {?} resourceTypes
* @param {?} clazz
* @param {?=} editConfig
* @return {?}
*/
ComponentMappingWithConfig.prototype.map = /**
* @param {?} resourceTypes
* @param {?} clazz
* @param {?=} editConfig
* @return {?}
*/
function (resourceTypes, clazz, editConfig) {
if (editConfig === void 0) {
editConfig = null;
}
var /** @type {?} */ innerClass = clazz;
if (editConfig) {
this.editConfigMap.set(clazz, editConfig);
}
this.spaMapping.map(resourceTypes, innerClass);
};
/**
* @param {?} resourceType
* @return {?}
*/
ComponentMappingWithConfig.prototype.get = /**
* @param {?} resourceType
* @return {?}
*/
function (resourceType) {
return this.spaMapping.get(resourceType);
};
/**
* @param {?} component
* @return {?}
*/
ComponentMappingWithConfig.prototype.getEditConfig = /**
* @param {?} component
* @return {?}
*/
function (component) {
return this.editConfigMap.get(component);
};
return ComponentMappingWithConfig;
}());
var /** @type {?} */ componentMapping = new ComponentMappingWithConfig(cqSpaComponentMapping.ComponentMapping);
/**
* @param {?} resourceTypes
* @return {?}
*/
function MapTo(resourceTypes) {
return function (clazz, editConfig) {
if (editConfig === void 0) {
editConfig = null;
}
return componentMapping.map(resourceTypes, clazz, editConfig);
};
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var /** @type {?} */ Constants = {
/**
* Class names associated with a new section component
*
*/
NEW_SECTION_CLASS_NAMES: 'new section',
TYPE_PROP: cqSpaPageModelManager.Constants.TYPE_PROP,
/**
* List of child items of an item
*
*/
ITEMS_PROP: cqSpaPageModelManager.Constants.ITEMS_PROP,
/**
* Order in which the items should be listed
*
*/
ITEMS_ORDER_PROP: cqSpaPageModelManager.Constants.ITEMS_ORDER_PROP,
/**
* Path of the item
*
*/
PATH_PROP: cqSpaPageModelManager.Constants.PATH_PROP,
/**
* Children of an item
*
*/
CHILDREN_PROP: cqSpaPageModelManager.Constants.CHILDREN_PROP,
/**
* Path of the resource in the model
*
*/
DATA_PATH_PROP: ':dataPath',
/**
* Hierarchical type of the item
*/
HIERARCHY_TYPE_PROP: ':hierarchyType'
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/*
* ADOBE CONFIDENTIAL
*
* Copyright 2018 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*/
/**
* Selector that identifies the node that contains the WCM mode state
*
*/
var /** @type {?} */ WCM_MODE_META_SELECTOR = 'meta[property="cq:wcmmode"]';
/**
* The editor is in one of the edition modes
*/
var /** @type {?} */ EDIT_MODE = 'edit';
/**
* The editor is in preview mode
*/
var /** @type {?} */ PREVIEW_MODE = 'preview';
/**
* Returns the current WCM mode
*
* <p>Note that the value isn't, as of the date of this writing, updated by the editor</p>
*
*
* @return {?}
*/
function getWCMMode() {
var /** @type {?} */ wcmModeMeta = document.head.querySelector(WCM_MODE_META_SELECTOR);
return wcmModeMeta && wcmModeMeta.content;
}
/**
* Helper functions for interacting with the AEM environment
*
*/
var /** @type {?} */ Utils = {
/**
* Is the app used in the context of the AEM Page editor
*
*/
isInEditor: /**
* Is the app used in the context of the AEM Page editor
*
* @return {?}
*/ function () {
var /** @type {?} */ wcmMode = getWCMMode();
return wcmMode && (EDIT_MODE === wcmMode || PREVIEW_MODE === wcmMode);
}
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var /** @type {?} */ PLACEHOLDER_CLASS_NAME = 'cq-placeholder';
var /** @type {?} */ DRAG_DROP_CLASS_NAME = 'cq-dd-';
var AEMComponentDirective = (function () {
function AEMComponentDirective(renderer, viewContainer, factoryResolver, ngZone) {
this.renderer = renderer;
this.viewContainer = viewContainer;
this.factoryResolver = factoryResolver;
this.ngZone = ngZone;
}
/**
* @return {?}
*/
AEMComponentDirective.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.renderComponent(componentMapping.get(this.type));
};
Object.defineProperty(AEMComponentDirective.prototype, "type", {
/**
* Returns the type of the cqModel if exists.
*/
get: /**
* Returns the type of the cqModel if exists.
* @return {?}
*/ function () {
return this.cqModel && this.cqModel[":type"];
},
enumerable: true,
configurable: true
});
Object.defineProperty(AEMComponentDirective.prototype, "columnClasses", {
/**
* Returns the column classes of the cqModel
*/
get: /**
* Returns the column classes of the cqModel
* @return {?}
*/ function () {
return this.cqModel && (this.cqModel.columnClassNames || '');
},
enumerable: true,
configurable: true
});
/**
* Updates the cqModel
* @return {?}
*/
AEMComponentDirective.prototype.updateCqModel = /**
* Updates the cqModel
* @return {?}
*/
function () {
var _this = this;
// Fetching the latest data for the item at the given path
this.getCqModel().then(function (model) {
_this.ngZone.run(function () {
model[Constants.DATA_PATH_PROP] = _this.path;
_this.cqModel = model;
_this.updateComponentData();
_this.setupElement();
var /** @type {?} */ editConfig = componentMapping.getEditConfig(componentMapping.get(_this.type));
if (editConfig) {
_this.setupPlaceholder(editConfig);
}
});
});
};
/**
* Returns the Cq Model
*
* @return {?}
*/
AEMComponentDirective.prototype.getCqModel = /**
* Returns the Cq Model
*
* @return {?}
*/
function () {
return cqSpaPageModelManager.PageModelManager.getData({ pagePath: this.pagePath, dataPath: this.path });
};
/**
* Renders a component dynamically based on the component definition
*
* @param {?} componentDefinition The component definition to render
* @return {?}
*/
AEMComponentDirective.prototype.renderComponent = /**
* Renders a component dynamically based on the component definition
*
* @param {?} componentDefinition The component definition to render
* @return {?}
*/
function (componentDefinition) {
if (componentDefinition) {
var /** @type {?} */ factory = this.factoryResolver.resolveComponentFactory(componentDefinition);
this.viewContainer.clear();
this._component = this.viewContainer.createComponent(factory);
this.updateComponentData();
this.setupElement();
var /** @type {?} */ editConfig = componentMapping.getEditConfig(componentDefinition);
if (editConfig && Utils.isInEditor) {
this.setupPlaceholder(editConfig);
}
cqSpaPageModelManager.PageModelManager.removeListener({ pagePath: this.pagePath, dataPath: this.path, callback: this.updateCqModel.bind(this) });
cqSpaPageModelManager.PageModelManager.addListener({ pagePath: this.pagePath, dataPath: this.path, callback: this.updateCqModel.bind(this) });
}
};
/**
* Updates the data of the component based the data of the directive
* @return {?}
*/
AEMComponentDirective.prototype.updateComponentData = /**
* Updates the data of the component based the data of the directive
* @return {?}
*/
function () {
this._component.instance.cqModel = this.cqModel;
this._component.instance.path = this.path;
this._component.instance.pagePath = this.pagePath;
this._component.instance.modelName = this.modelName;
};
/**
* Setups the DOM element, setting the classes and attributes needed for the AEM editor.
* @return {?}
*/
AEMComponentDirective.prototype.setupElement = /**
* Setups the DOM element, setting the classes and attributes needed for the AEM editor.
* @return {?}
*/
function () {
var _this = this;
if (this._oldClasses) {
var /** @type {?} */ oldClasses = this._oldClasses.split(' ');
oldClasses.forEach(function (columnClass) {
_this.renderer.removeClass(_this._component.location.nativeElement, columnClass);
});
}
this._oldClasses = this.columnClasses;
// Manually add the classes
if (this.columnClasses) {
var /** @type {?} */ classes = this.columnClasses.split(' ');
classes.forEach(function (columnClass) {
_this.renderer.addClass(_this._component.location.nativeElement, columnClass);
});
}
if (this.path) {
this.renderer.setAttribute(this._component.location.nativeElement, "data-cq-data-path", this.path);
}
};
/**
* Setups the placeholder of needed for the AEM editor
*
* @param {?} editConfig - the editConfig, which will dictate the classes to be added on.
* @return {?}
*/
AEMComponentDirective.prototype.setupPlaceholder = /**
* Setups the placeholder of needed for the AEM editor
*
* @param {?} editConfig - the editConfig, which will dictate the classes to be added on.
* @return {?}
*/
function (editConfig) {
// Remove previous drag and drop class names
this.renderer.removeClass(this._component.location.nativeElement, DRAG_DROP_CLASS_NAME + editConfig.dragDropName);
if (editConfig.dragDropName && editConfig.dragDropName.trim().length > 0) {
this.renderer.addClass(this._component.location.nativeElement, DRAG_DROP_CLASS_NAME + editConfig.dragDropName);
}
if (this.usePlaceholder(editConfig)) {
this.renderer.addClass(this._component.location.nativeElement, PLACEHOLDER_CLASS_NAME);
this._component.location.nativeElement.dataset.emptytext = editConfig.emptyLabel;
}
else {
this.renderer.removeClass(this._component.location.nativeElement, PLACEHOLDER_CLASS_NAME);
delete this._component.location.nativeElement.dataset.emptytext;
}
};
/**
* Determines if the placeholder should e displayed.
*
* @param {?} editConfig - the edit config of the directive
* @return {?}
*/
AEMComponentDirective.prototype.usePlaceholder = /**
* Determines if the placeholder should e displayed.
*
* @param {?} editConfig - the edit config of the directive
* @return {?}
*/
function (editConfig) {
return editConfig.isEmpty && typeof editConfig.isEmpty === "function" && editConfig.isEmpty(this.cqModel);
};
/**
* @return {?}
*/
AEMComponentDirective.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
cqSpaPageModelManager.PageModelManager.removeListener({ pagePath: this.pagePath, dataPath: this.path, callback: this.updateCqModel.bind(this) });
this._component && this._component.destroy();
};
AEMComponentDirective.decorators = [
{ type: core.Directive, args: [{
selector: '[aemComponent]'
},] },
];
/** @nocollapse */
AEMComponentDirective.ctorParameters = function () {
return [
{ type: core.Renderer2, },
{ type: core.ViewContainerRef, },
{ type: core.ComponentFactoryResolver, },
{ type: core.NgZone, },
];
};
AEMComponentDirective.propDecorators = {
"cqModel": [{ type: core.Input },],
"path": [{ type: core.Input },],
"pagePath": [{ type: core.Input },],
"modelName": [{ type: core.Input },],
"aemComponent": [{ type: core.Input },],
};
return AEMComponentDirective;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var AEMContainerComponent = (function () {
function AEMContainerComponent() {
this.path = '';
this.pagePath = '';
this.modelName = '';
}
/**
* Returns the aggregated path of this container path and the provided path
*
* @param path - the provided path to aggregate with the container path
*/
/**
* Returns the aggregated path of this container path and the provided path
*
* @param {?} path - the provided path to aggregate with the container path
* @return {?}
*/
AEMContainerComponent.prototype.getDataPath = /**
* Returns the aggregated path of this container path and the provided path
*
* @param {?} path - the provided path to aggregate with the container path
* @return {?}
*/
function (path) {
return this.path ? this.path + "/" + path : path;
};
/**
* Return the page path from the data, defaulting to the provided pagePath to the container.
*/
/**
* Return the page path from the data, defaulting to the provided pagePath to the container.
* @return {?}
*/
AEMContainerComponent.prototype.getPagePath = /**
* Return the page path from the data, defaulting to the provided pagePath to the container.
* @return {?}
*/
function () {
return this.cqModel[Constants.PATH_PROP] || this.pagePath;
};
/**
* Returns the item data from the cqModel
*
* @param itemKey - the itemKey to look for in the items.
*/
/**
* Returns the item data from the cqModel
*
* @param {?} itemKey - the itemKey to look for in the items.
* @return {?}
*/
AEMContainerComponent.prototype.getItem = /**
* Returns the item data from the cqModel
*
* @param {?} itemKey - the itemKey to look for in the items.
* @return {?}
*/
function (itemKey) {
return this.cqModel[Constants.ITEMS_PROP][itemKey];
};
Object.defineProperty(AEMContainerComponent.prototype, "itemsOrder", {
/**
* Returns the itemsOrder array from the cqModel
*/
get: /**
* Returns the itemsOrder array from the cqModel
* @return {?}
*/ function () {
return this.cqModel && this.cqModel[Constants.ITEMS_ORDER_PROP];
},
enumerable: true,
configurable: true
});
AEMContainerComponent.decorators = [
{ type: core.Component, args: [{
selector: 'aem-container',
host: {
'[attr.data-cq-data-path]': 'path'
},
template: "<ng-container *ngFor=\"let itemKey of itemsOrder\">\n <ng-container [aemComponent] [cqModel]='getItem(itemKey)' [pagePath]='getPagePath()' [path]='getDataPath(itemKey)' [modelName]='itemKey'></ng-container>\n</ng-container>\n"
},] },
];
/** @nocollapse */
AEMContainerComponent.ctorParameters = function () { return []; };
AEMContainerComponent.propDecorators = {
"cqModel": [{ type: core.Input },],
"path": [{ type: core.Input },],
"pagePath": [{ type: core.Input },],
"modelName": [{ type: core.Input },],
};
return AEMContainerComponent;
}());
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b)
if (b.hasOwnProperty(p))
d[p] = b[p]; };
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var /** @type {?} */ CONTAINER_CLASS_NAMES = 'aem-container';
var /** @type {?} */ PLACEHOLDER_CLASS_NAMES = Constants.NEW_SECTION_CLASS_NAMES + ' aem-Grid-newComponent';
var AEMResponsiveGridComponent = (function (_super) {
__extends(AEMResponsiveGridComponent, _super);
function AEMResponsiveGridComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(AEMResponsiveGridComponent.prototype, "isInEditMode", {
/**
* Returns weather of not we are in the editor
*/
get: /**
* Returns weather of not we are in the editor
* @return {?}
*/ function () {
return Utils.isInEditor();
},
enumerable: true,
configurable: true
});
Object.defineProperty(AEMResponsiveGridComponent.prototype, "placeholderClass", {
/**
* Returns the placeholder classes
*/
get: /**
* Returns the placeholder classes
* @return {?}
*/ function () {
return PLACEHOLDER_CLASS_NAMES;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AEMResponsiveGridComponent.prototype, "placeholdePath", {
/**
* Returns the placeholder path
*/
get: /**
* Returns the placeholder path
* @return {?}
*/ function () {
return this.path && this.path + "/*";
},
enumerable: true,
configurable: true
});
Object.defineProperty(AEMResponsiveGridComponent.prototype, "gridClasses", {
/**
* Returns the gridClasses for the cqModel of the responsive grid
*/
get: /**
* Returns the gridClasses for the cqModel of the responsive grid
* @return {?}
*/ function () {
return this.cqModel && (this.cqModel["gridClassNames"] || '');
},
enumerable: true,
configurable: true
});
Object.defineProperty(AEMResponsiveGridComponent.prototype, "classNames", {
/**
* Returns the class names of the responsive grid based on the data from the cqModel
*/
get: /**
* Returns the class names of the responsive grid based on the data from the cqModel
* @return {?}
*/ function () {
if (!this.cqModel) {
return '';
}
var /** @type {?} */ classNames = CONTAINER_CLASS_NAMES;
if (this.cqModel.classNames) {
classNames += ' ' + (this.cqModel.classNames || '');
}
if (this.cqModel.columnClassNames) {
classNames += ' ' + (this.cqModel.columnClassNames || '');
}
return classNames;
},
enumerable: true,
configurable: true
});
AEMResponsiveGridComponent.decorators = [
{ type: core.Component, args: [{
selector: 'aem-responsivegrid',
host: {
'[class]': 'classNames',
'[attr.data-cq-data-path]': 'path'
},
template: "<div [class]=\"gridClasses\">\n <ng-container *ngFor=\"let itemKey of itemsOrder\">\n <ng-container [aemComponent] [cqModel]='getItem(itemKey)' [pagePath]='getPagePath()' [path]='getDataPath(itemKey)' [modelName]='itemKey'></ng-container>\n </ng-container>\n <div *ngIf=\"isInEditMode\" [attr.data-cq-data-path]=\"placeholdePath\" [class]=\"placeholderClass\"></div>\n</div>\n",
},] },
];
return AEMResponsiveGridComponent;
}(AEMContainerComponent));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var SpaAngularEditableComponentsModule = (function () {
function SpaAngularEditableComponentsModule() {
}
SpaAngularEditableComponentsModule.decorators = [
{ type: core.NgModule, args: [{
imports: [common.CommonModule],
declarations: [AEMContainerComponent, AEMResponsiveGridComponent, AEMComponentDirective],
exports: [AEMContainerComponent, AEMResponsiveGridComponent, AEMComponentDirective]
},] },
];
return SpaAngularEditableComponentsModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
exports.AEMComponentDirective = AEMComponentDirective;
exports.AEMContainerComponent = AEMContainerComponent;
exports.AEMResponsiveGridComponent = AEMResponsiveGridComponent;
exports.ComponentMappingWithConfig = ComponentMappingWithConfig;
exports.ComponentMapping = componentMapping;
exports.MapTo = MapTo;
exports.Constants = Constants;
exports.Utils = Utils;
exports.SpaAngularEditableComponentsModule = SpaAngularEditableComponentsModule;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRvYmUtY3EtYW5ndWxhci1lZGl0YWJsZS1jb21wb25lbnRzLnVtZC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGFkb2JlL2NxLWFuZ3VsYXItZWRpdGFibGUtY29tcG9uZW50cy9saWIvbGF5b3V0L2NvbXBvbmVudC1tYXBwaW5nLnRzIiwibmc6Ly9AYWRvYmUvY3EtYW5ndWxhci1lZGl0YWJsZS1jb21wb25lbnRzL2xpYi9sYXlvdXQvY29uc3RhbnRzLnRzIiwibmc6Ly9AYWRvYmUvY3EtYW5ndWxhci1lZGl0YWJsZS1jb21wb25lbnRzL2xpYi9sYXlvdXQvdXRpbHMudHMiLCJuZzovL0BhZG9iZS9jcS1hbmd1bGFyLWVkaXRhYmxlLWNvbXBvbmVudHMvbGliL2xheW91dC9hZW0tY29tcG9uZW50LmRpcmVjdGl2ZS50cyIsIm5nOi8vQGFkb2JlL2NxLWFuZ3VsYXItZWRpdGFibGUtY29tcG9uZW50cy9saWIvbGF5b3V0L2FlbS1jb250YWluZXIvYWVtLWNvbnRhaW5lci5jb21wb25lbnQudHMiLG51bGwsIm5nOi8vQGFkb2JlL2NxLWFuZ3VsYXItZWRpdGFibGUtY29tcG9uZW50cy9saWIvbGF5b3V0L2FlbS1yZXNwb25zaXZlZ3JpZC9hZW0tcmVzcG9uc2l2ZWdyaWQuY29tcG9uZW50LnRzIiwibmc6Ly9AYWRvYmUvY3EtYW5ndWxhci1lZGl0YWJsZS1jb21wb25lbnRzL2xpYi9jcS1hbmd1bGFyLWVkaXRhYmxlLWNvbXBvbmVudHMubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBBRE9CRSBDT05GSURFTlRJQUxcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOCBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZFxuICogQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnNcbiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycyxcbiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWRcbiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0c1xuICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsXG4gKiBwYXRlbnRzIGluIHByb2Nlc3MsIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IHRyYWRlIHNlY3JldCBvciBjb3B5cmlnaHQgbGF3LlxuICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsXG4gKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZFxuICogZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC5cbiAqL1xuXG5pbXBvcnQgeyBDb21wb25lbnRNYXBwaW5nIGFzIFNQQUNvbXBvbmVudE1hcHBpbmcgfSBmcm9tIFwiQGFkb2JlL2NxLXNwYS1jb21wb25lbnQtbWFwcGluZ1wiO1xuXG5leHBvcnQgY2xhc3MgQ29tcG9uZW50TWFwcGluZ1dpdGhDb25maWcge1xuICBwcml2YXRlIGVkaXRDb25maWdNYXA6V2Vha01hcDxhbnksIGFueT4gID0gbmV3IFdlYWtNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNwYU1hcHBpbmc6U1BBQ29tcG9uZW50TWFwcGluZykge31cblxuICBtYXAocmVzb3VyY2VUeXBlcywgY2xhenosIGVkaXRDb25maWcgPSBudWxsKSB7XG4gICAgICBsZXQgaW5uZXJDbGFzcyA9IGNsYXp6O1xuXG4gICAgICBpZiAoZWRpdENvbmZpZykge1xuICAgICAgICAgIHRoaXMuZWRpdENvbmZpZ01hcC5zZXQoY2xhenosIGVkaXRDb25maWcpO1xuICAgICAgfVxuICAgICAgdGhpcy5zcGFNYXBwaW5nLm1hcChyZXNvdXJjZVR5cGVzLCBpbm5lckNsYXNzKTtcbiAgfTtcblxuICBnZXQocmVzb3VyY2VUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuc3BhTWFwcGluZy5nZXQocmVzb3VyY2VUeXBlKTtcbiAgfVxuXG4gIGdldEVkaXRDb25maWcoY29tcG9uZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdENvbmZpZ01hcC5nZXQoY29tcG9uZW50KTtcbiAgfVxufVxuXG5sZXQgY29tcG9uZW50TWFwcGluZyA9IG5ldyBDb21wb25lbnRNYXBwaW5nV2l0aENvbmZpZyhTUEFDb21wb25lbnRNYXBwaW5nKTtcblxuZnVuY3Rpb24gTWFwVG8ocmVzb3VyY2VUeXBlcykge1xuICAgIHJldHVybiAoY2xhenosIGVkaXRDb25maWcgPSBudWxsKSA9PiB7XG4gICAgICAgIHJldHVybiBjb21wb25lbnRNYXBwaW5nLm1hcChyZXNvdXJjZVR5cGVzLCBjbGF6eiwgZWRpdENvbmZpZyk7XG4gICAgfTtcbn1cblxuXG5leHBvcnQgeyBjb21wb25lbnRNYXBwaW5nIGFzIENvbXBvbmVudE1hcHBpbmcsIE1hcFRvIH07XG4iLCIvKlxuICogQURPQkUgQ09ORklERU5USUFMXG4gKlxuICogQ29weXJpZ2h0IDIwMTggQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWRcbiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zXG4gKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsXG4gKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkXG4gKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHNcbiAqIHN1cHBsaWVycyBhbmQgbWF5IGJlIGNvdmVyZWQgYnkgVS5TLiBhbmQgRm9yZWlnbiBQYXRlbnRzLFxuICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy5cbiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbFxuICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWRcbiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuXG4gKi9cblxuaW1wb3J0IHtDb25zdGFudHMgYXMgUE1Db25zdGFudHN9IGZyb20gJ0BhZG9iZS9jcS1zcGEtcGFnZS1tb2RlbC1tYW5hZ2VyJztcblxuZXhwb3J0IGNvbnN0IENvbnN0YW50cyA9IHtcblxuICAgIC8qKlxuICAgICAqIENsYXNzIG5hbWVzIGFzc29jaWF0ZWQgd2l0aCBhIG5ldyBzZWN0aW9uIGNvbXBvbmVudFxuICAgICAqXG4gICAgICovXG4gICAgTkVXX1NFQ1RJT05fQ0xBU1NfTkFNRVM6ICduZXcgc2VjdGlvbicsXG5cbiAgICBUWVBFX1BST1A6IFBNQ29uc3RhbnRzLlRZUEVfUFJPUCxcblxuICAgIC8qKlxuICAgICAqIExpc3Qgb2YgY2hpbGQgaXRlbXMgb2YgYW4gaXRlbVxuICAgICAqXG4gICAgICovXG4gICAgSVRFTVNfUFJPUDogUE1Db25zdGFudHMuSVRFTVNfUFJPUCxcblxuICAgIC8qKlxuICAgICAqIE9yZGVyIGluIHdoaWNoIHRoZSBpdGVtcyBzaG91bGQgYmUgbGlzdGVkXG4gICAgICpcbiAgICAgKi9cbiAgICBJVEVNU19PUkRFUl9QUk9QOiBQTUNvbnN0YW50cy5JVEVNU19PUkRFUl9QUk9QLFxuXG4gICAgLyoqXG4gICAgICogUGF0aCBvZiB0aGUgaXRlbVxuICAgICAqXG4gICAgICovXG4gICAgUEFUSF9QUk9QOiBQTUNvbnN0YW50cy5QQVRIX1BST1AsXG5cbiAgICAvKipcbiAgICAgKiBDaGlsZHJlbiBvZiBhbiBpdGVtXG4gICAgICpcbiAgICAgKi9cbiAgICBDSElMRFJFTl9QUk9QOiBQTUNvbnN0YW50cy5DSElMRFJFTl9QUk9QLFxuXG4gICAgLyoqXG4gICAgICogUGF0aCBvZiB0aGUgcmVzb3VyY2UgaW4gdGhlIG1vZGVsXG4gICAgICpcbiAgICAgKi9cbiAgICBEQVRBX1BBVEhfUFJPUDogJzpkYXRhUGF0aCcsXG5cbiAgICAvKipcbiAgICAgKiBIaWVyYXJjaGljYWwgdHlwZSBvZiB0aGUgaXRlbVxuICAgICAqL1xuICAgIEhJRVJBUkNIWV9UWVBFX1BST1A6ICc6aGllcmFyY2h5VHlwZSdcbn07XG4iLCIvKlxuICogQURPQkUgQ09ORklERU5USUFMXG4gKlxuICogQ29weXJpZ2h0IDIwMTggQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWRcbiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zXG4gKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsXG4gKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkXG4gKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHNcbiAqIHN1cHBsaWVycyBhbmQgbWF5IGJlIGNvdmVyZWQgYnkgVS5TLiBhbmQgRm9yZWlnbiBQYXRlbnRzLFxuICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy5cbiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbFxuICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWRcbiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuXG4gKi9cblxuLyoqXG4gKiBTZWxlY3RvciB0aGF0IGlkZW50aWZpZXMgdGhlIG5vZGUgdGhhdCBjb250YWlucyB0aGUgV0NNIG1vZGUgc3RhdGVcbiAqXG4gKi9cbmNvbnN0IFdDTV9NT0RFX01FVEFfU0VMRUNUT1I6c3RyaW5nID0gJ21ldGFbcHJvcGVydHk9XCJjcTp3Y21tb2RlXCJdJztcblxuLyoqXG4gKiBUaGUgZWRpdG9yIGlzIGluIG9uZSBvZiB0aGUgZWRpdGlvbiBtb2Rlc1xuICovXG5jb25zdCBFRElUX01PREU6c3RyaW5nID0gJ2VkaXQnO1xuXG4vKipcbiAqIFRoZSBlZGl0b3IgaXMgaW4gcHJldmlldyBtb2RlXG4gKi9cbmNvbnN0IFBSRVZJRVdfTU9ERTpzdHJpbmcgPSAncHJldmlldyc7XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCBXQ00gbW9kZVxuICpcbiAqIDxwPk5vdGUgdGhhdCB0aGUgdmFsdWUgaXNuJ3QsIGFzIG9mIHRoZSBkYXRlIG9mIHRoaXMgd3JpdGluZywgdXBkYXRlZCBieSB0aGUgZWRpdG9yPC9wPlxuICpcbiAqXG4gKi9cbmZ1bmN0aW9uIGdldFdDTU1vZGUoKSB7XG4gICAgY29uc3Qgd2NtTW9kZU1ldGE6YW55ID0gZG9jdW1lbnQuaGVhZC5xdWVyeVNlbGVjdG9yKFdDTV9NT0RFX01FVEFfU0VMRUNUT1IpO1xuICAgIHJldHVybiB3Y21Nb2RlTWV0YSAmJiB3Y21Nb2RlTWV0YS5jb250ZW50O1xufVxuXG4vKipcbiAqIEhlbHBlciBmdW5jdGlvbnMgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIEFFTSBlbnZpcm9ubWVudFxuICpcbiAqL1xuZXhwb3J0IGNvbnN0IFV0aWxzID0ge1xuXG4gICAgLyoqXG4gICAgICogSXMgdGhlIGFwcCB1c2VkIGluIHRoZSBjb250ZXh0IG9mIHRoZSBBRU0gUGFnZSBlZGl0b3JcbiAgICAgKlxuICAgICAqL1xuICAgIGlzSW5FZGl0b3IoKSB7XG4gICAgICAgIGNvbnN0IHdjbU1vZGUgPSBnZXRXQ01Nb2RlKCk7XG4gICAgICAgIHJldHVybiB3Y21Nb2RlICYmIChFRElUX01PREUgPT09IHdjbU1vZGUgfHwgUFJFVklFV19NT0RFID09PSB3Y21Nb2RlKTtcbiAgICB9XG59O1xuIiwiLypcbiAqIEFET0JFIENPTkZJREVOVElBTFxuICpcbiAqIENvcHlyaWdodCAyMDE4IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWluc1xuICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLFxuICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZFxuICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzXG4gKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cyxcbiAqIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuXG4gKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWxcbiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkXG4gKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLlxuICovXG5cbmltcG9ydCB7IERpcmVjdGl2ZSwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBSZW5kZXJlcjIsIE5nWm9uZSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIFZpZXdDb250YWluZXJSZWYsIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgQXBwbGljYXRpb25SZWYsIENvbXBvbmVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBDb21wb25lbnRNYXBwaW5nIH0gZnJvbSBcIi4vY29tcG9uZW50LW1hcHBpbmdcIjtcblxuaW1wb3J0IHsgUGFnZU1vZGVsTWFuYWdlciB9IGZyb20gJ0BhZG9iZS9jcS1zcGEtcGFnZS1tb2RlbC1tYW5hZ2VyJztcblxuaW1wb3J0IHsgQ29uc3RhbnRzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBVdGlscyB9IGZyb20gXCIuL3V0aWxzXCI7XG5cblxuY29uc3QgUExBQ0VIT0xERVJfQ0xBU1NfTkFNRSA9ICdjcS1wbGFjZWhvbGRlcic7XG5jb25zdCBEUkFHX0RST1BfUkVHRVggPSAvY3EtZGQtKFteIF0pKy9nO1xuY29uc3QgRFJBR19EUk9QX0NMQVNTX05BTUUgPSAnY3EtZGQtJztcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2FlbUNvbXBvbmVudF0nXG59KVxuXG5leHBvcnQgY2xhc3MgQUVNQ29tcG9uZW50RGlyZWN0aXZlIHtcbiAgcHJpdmF0ZSBfY29tcG9uZW50OkNvbXBvbmVudFJlZjxhbnk+O1xuICBwcml2YXRlIF9vbGRDbGFzc2VzOnN0cmluZztcblxuICBASW5wdXQoKSBjcU1vZGVsOmFueTtcbiAgQElucHV0KCkgcGF0aDpzdHJpbmc7XG4gIEBJbnB1dCgpIHBhZ2VQYXRoOnN0cmluZztcbiAgQElucHV0KCkgbW9kZWxOYW1lOnN0cmluZztcbiAgQElucHV0KCkgYWVtQ29tcG9uZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWYsXG4gICAgcHJpdmF0ZSBmYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lKSB7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnJlbmRlckNvbXBvbmVudChDb21wb25lbnRNYXBwaW5nLmdldCh0aGlzLnR5cGUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0eXBlIG9mIHRoZSBjcU1vZGVsIGlmIGV4aXN0cy5cbiAgICovXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiB0aGlzLmNxTW9kZWwgJiYgdGhpcy5jcU1vZGVsW1wiOnR5cGVcIl07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29sdW1uIGNsYXNzZXMgb2YgdGhlIGNxTW9kZWxcbiAgICovXG4gIGdldCBjb2x1bW5DbGFzc2VzKCkge1xuICAgIHJldHVybiB0aGlzLmNxTW9kZWwgJiYgKHRoaXMuY3FNb2RlbC5jb2x1bW5DbGFzc05hbWVzIHx8ICcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBjcU1vZGVsXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUNxTW9kZWwoKSB7XG4gICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgIC8vIEZldGNoaW5nIHRoZSBsYXRlc3QgZGF0YSBmb3IgdGhlIGl0ZW0gYXQgdGhlIGdpdmVuIHBhdGhcbiAgICB0aGlzLmdldENxTW9kZWwoKS50aGVuKG1vZGVsID0+IHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBtb2RlbFtDb25zdGFudHMuREFUQV9QQVRIX1BST1BdID0gdGhpcy5wYXRoO1xuICAgICAgICAgIHRoaXMuY3FNb2RlbCA9IG1vZGVsO1xuICAgICAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50RGF0YSgpO1xuICAgICAgICAgIHRoaXMuc2V0dXBFbGVtZW50KCk7XG4gICAgICAgICAgbGV0IGVkaXRDb25maWcgPSBDb21wb25lbnRNYXBwaW5nLmdldEVkaXRDb25maWcoQ29tcG9uZW50TWFwcGluZy5nZXQodGhpcy50eXBlKSk7XG4gICAgICAgICAgaWYgKGVkaXRDb25maWcpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0dXBQbGFjZWhvbGRlcihlZGl0Q29uZmlnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIENxIE1vZGVsXG4gICAqXG4gICAqL1xuICBwcml2YXRlIGdldENxTW9kZWwoKSB7XG4gICAgICByZXR1cm4gUGFnZU1vZGVsTWFuYWdlci5nZXREYXRhKHtwYWdlUGF0aDogdGhpcy5wYWdlUGF0aCwgZGF0YVBhdGg6IHRoaXMucGF0aH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgYSBjb21wb25lbnQgZHluYW1pY2FsbHkgYmFzZWQgb24gdGhlIGNvbXBvbmVudCBkZWZpbml0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBjb21wb25lbnREZWZpbml0aW9uIFRoZSBjb21wb25lbnQgZGVmaW5pdGlvbiB0byByZW5kZXJcbiAgICovXG4gIHByaXZhdGUgcmVuZGVyQ29tcG9uZW50KGNvbXBvbmVudERlZmluaXRpb246YW55KSB7XG4gICAgaWYgKGNvbXBvbmVudERlZmluaXRpb24pIHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmZhY3RvcnlSZXNvbHZlci5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShjb21wb25lbnREZWZpbml0aW9uKTtcbiAgICAgIHRoaXMudmlld0NvbnRhaW5lci5jbGVhcigpO1xuICAgICAgdGhpcy5fY29tcG9uZW50ID0gdGhpcy52aWV3Q29udGFpbmVyLmNyZWF0ZUNvbXBvbmVudChmYWN0b3J5KTtcblxuICAgICAgdGhpcy51cGRhdGVDb21wb25lbnREYXRhKCk7XG4gICAgICB0aGlzLnNldHVwRWxlbWVudCgpO1xuICAgICAgbGV0IGVkaXRDb25maWcgPSBDb21wb25lbnRNYXBwaW5nLmdldEVkaXRDb25maWcoY29tcG9uZW50RGVmaW5pdGlvbik7XG4gICAgICBpZiAoZWRpdENvbmZpZyAmJiBVdGlscy5pc0luRWRpdG9yKSB7XG4gICAgICAgIHRoaXMuc2V0dXBQbGFjZWhvbGRlcihlZGl0Q29uZmlnKTtcbiAgICAgIH1cbiAgICAgIFBhZ2VNb2RlbE1hbmFnZXIucmVtb3ZlTGlzdGVuZXIoe3BhZ2VQYXRoOiB0aGlzLnBhZ2VQYXRoLCBkYXRhUGF0aDogdGhpcy5wYXRoLCBjYWxsYmFjazogdGhpcy51cGRhdGVDcU1vZGVsLmJpbmQodGhpcykgfSk7XG4gICAgICBQYWdlTW9kZWxNYW5hZ2VyLmFkZExpc3RlbmVyKHtwYWdlUGF0aDogdGhpcy5wYWdlUGF0aCwgZGF0YVBhdGg6IHRoaXMucGF0aCwgY2FsbGJhY2s6IHRoaXMudXBkYXRlQ3FNb2RlbC5iaW5kKHRoaXMpIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBkYXRhIG9mIHRoZSBjb21wb25lbnQgYmFzZWQgdGhlIGRhdGEgb2YgdGhlIGRpcmVjdGl2ZVxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVDb21wb25lbnREYXRhKCkge1xuICAgIHRoaXMuX2NvbXBvbmVudC5pbnN0YW5jZS5jcU1vZGVsID0gdGhpcy5jcU1vZGVsO1xuICAgIHRoaXMuX2NvbXBvbmVudC5pbnN0YW5jZS5wYXRoID0gdGhpcy5wYXRoO1xuICAgIHRoaXMuX2NvbXBvbmVudC5pbnN0YW5jZS5wYWdlUGF0aCA9IHRoaXMucGFnZVBhdGg7XG4gICAgdGhpcy5fY29tcG9uZW50Lmluc3RhbmNlLm1vZGVsTmFtZSA9IHRoaXMubW9kZWxOYW1lO1xuXG4gIH1cblxuICAvKipcbiAgICogU2V0dXBzIHRoZSBET00gZWxlbWVudCwgc2V0dGluZyB0aGUgY2xhc3NlcyBhbmQgYXR0cmlidXRlcyBuZWVkZWQgZm9yIHRoZSBBRU0gZWRpdG9yLlxuICAgKi9cbiAgcHJpdmF0ZSBzZXR1cEVsZW1lbnQoKSAge1xuICAgIGlmICh0aGlzLl9vbGRDbGFzc2VzKSB7XG4gICAgICBsZXQgb2xkQ2xhc3NlcyA9IHRoaXMuX29sZENsYXNzZXMuc3BsaXQoJyAnKTtcbiAgICAgIG9sZENsYXNzZXMuZm9yRWFjaCgoY29sdW1uQ2xhc3MpID0+IHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLl9jb21wb25lbnQubG9jYXRpb24ubmF0aXZlRWxlbWVudCwgY29sdW1uQ2xhc3MpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fb2xkQ2xhc3NlcyA9IHRoaXMuY29sdW1uQ2xhc3NlcztcbiAgICAvLyBNYW51YWxseSBhZGQgdGhlIGNsYXNzZXNcbiAgICBpZiAodGhpcy5jb2x1bW5DbGFzc2VzKSB7XG4gICAgICBsZXQgY2xhc3NlcyA9IHRoaXMuY29sdW1uQ2xhc3Nlcy5zcGxpdCgnICcpO1xuICAgICAgY2xhc3Nlcy5mb3JFYWNoKChjb2x1bW5DbGFzcykgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKHRoaXMuX2NvbXBvbmVudC5sb2NhdGlvbi5uYXRpdmVFbGVtZW50LCBjb2x1bW5DbGFzcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYXRoKSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0aGlzLl9jb21wb25lbnQubG9jYXRpb24ubmF0aXZlRWxlbWVudCwgXCJkYXRhLWNxLWRhdGEtcGF0aFwiICx0aGlzLnBhdGgpO1xuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFNldHVwcyB0aGUgcGxhY2Vob2xkZXIgb2YgbmVlZGVkIGZvciB0aGUgQUVNIGVkaXRvclxuICAgKlxuICAgKiBAcGFyYW0gZWRpdENvbmZpZyAtIHRoZSBlZGl0Q29uZmlnLCB3aGljaCB3aWxsIGRpY3RhdGUgdGhlIGNsYXNzZXMgdG8gYmUgYWRkZWQgb24uXG4gICAqL1xuICBwcml2YXRlIHNldHVwUGxhY2Vob2xkZXIoZWRpdENvbmZpZykge1xuICAgIC8vIFJlbW92ZSBwcmV2aW91cyBkcmFnIGFuZCBkcm9wIGNsYXNzIG5hbWVzXG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLl9jb21wb25lbnQubG9jYXRpb24ubmF0aXZlRWxlbWVudCwgRFJBR19EUk9QX0NMQVNTX05BTUUgKyBlZGl0Q29uZmlnLmRyYWdEcm9wTmFtZSk7XG5cbiAgICBpZiAoZWRpdENvbmZpZy5kcmFnRHJvcE5hbWUgJiYgZWRpdENvbmZpZy5kcmFnRHJvcE5hbWUudHJpbSgpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLl9jb21wb25lbnQubG9jYXRpb24ubmF0aXZlRWxlbWVudCwgRFJBR19EUk9QX0NMQVNTX05BTUUgKyBlZGl0Q29uZmlnLmRyYWdEcm9wTmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudXNlUGxhY2Vob2xkZXIoZWRpdENvbmZpZykpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLl9jb21wb25lbnQubG9jYXRpb24ubmF0aXZlRWxlbWVudCwgUExBQ0VIT0xERVJfQ0xBU1NfTkFNRSk7XG4gICAgICAgIHRoaXMuX2NvbXBvbmVudC5sb2NhdGlvbi5uYXRpdmVFbGVtZW50LmRhdGFzZXQuZW1wdHl0ZXh0ID0gZWRpdENvbmZpZy5lbXB0eUxhYmVsO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5fY29tcG9uZW50LmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQsIFBMQUNFSE9MREVSX0NMQVNTX05BTUUpO1xuICAgICAgICBkZWxldGUgdGhpcy5fY29tcG9uZW50LmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQuZGF0YXNldC5lbXB0eXRleHQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHBsYWNlaG9sZGVyIHNob3VsZCBlIGRpc3BsYXllZC5cbiAgICpcbiAgICogQHBhcmFtIGVkaXRDb25maWcgLSB0aGUgZWRpdCBjb25maWcgb2YgdGhlIGRpcmVjdGl2ZVxuICAgKi9cbiAgcHJpdmF0ZSB1c2VQbGFjZWhvbGRlcihlZGl0Q29uZmlnKSB7XG4gICAgcmV0dXJuIGVkaXRDb25maWcuaXNFbXB0eSAmJiB0eXBlb2YgZWRpdENvbmZpZy5pc0VtcHR5ID09PSBcImZ1bmN0aW9uXCIgJiYgZWRpdENvbmZpZy5pc0VtcHR5KHRoaXMuY3FNb2RlbCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBQYWdlTW9kZWxNYW5hZ2VyLnJlbW92ZUxpc3RlbmVyKHtwYWdlUGF0aDogdGhpcy5wYWdlUGF0aCwgZGF0YVBhdGg6IHRoaXMucGF0aCwgY2FsbGJhY2s6IHRoaXMudXBkYXRlQ3FNb2RlbC5iaW5kKHRoaXMpIH0pO1xuICAgIHRoaXMuX2NvbXBvbmVudCAmJiB0aGlzLl9jb21wb25lbnQuZGVzdHJveSgpO1xuICB9XG5cbn1cbiIsIi8qXG4gKiBBRE9CRSBDT05GSURFTlRJQUxcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOCBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZFxuICogQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnNcbiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycyxcbiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWRcbiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0c1xuICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsXG4gKiBwYXRlbnRzIGluIHByb2Nlc3MsIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IHRyYWRlIHNlY3JldCBvciBjb3B5cmlnaHQgbGF3LlxuICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsXG4gKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZFxuICogZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC5cbiAqL1xuXG5pbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb25zdGFudHMgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhZW0tY29udGFpbmVyJyxcbiAgaG9zdDoge1xuICAgICAgJ1thdHRyLmRhdGEtY3EtZGF0YS1wYXRoXSc6J3BhdGgnXG4gIH0sXG4gIHRlbXBsYXRlOiBgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbUtleSBvZiBpdGVtc09yZGVyXCI+XG4gIDxuZy1jb250YWluZXIgW2FlbUNvbXBvbmVudF0gW2NxTW9kZWxdPSdnZXRJdGVtKGl0ZW1LZXkpJyBbcGFnZVBhdGhdPSdnZXRQYWdlUGF0aCgpJyBbcGF0aF09J2dldERhdGFQYXRoKGl0ZW1LZXkpJyBbbW9kZWxOYW1lXT0naXRlbUtleSc+PC9uZy1jb250YWluZXI+XG48L25nLWNvbnRhaW5lcj5cbmBcbn0pXG5leHBvcnQgY2xhc3MgQUVNQ29udGFpbmVyQ29tcG9uZW50IHtcbiAgQElucHV0KCkgY3FNb2RlbDphbnk7XG4gIEBJbnB1dCgpIHBhdGg6c3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIHBhZ2VQYXRoOnN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBtb2RlbE5hbWU6c3RyaW5nID0gJyc7XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBhZ2dyZWdhdGVkIHBhdGggb2YgdGhpcyBjb250YWluZXIgcGF0aCBhbmQgdGhlIHByb3ZpZGVkIHBhdGhcbiAgICpcbiAgICogQHBhcmFtIHBhdGggLSB0aGUgcHJvdmlkZWQgcGF0aCB0byBhZ2dyZWdhdGUgd2l0aCB0aGUgY29udGFpbmVyIHBhdGhcbiAgICovXG4gIGdldERhdGFQYXRoKHBhdGgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXRoID8gdGhpcy5wYXRoICsgXCIvXCIgKyBwYXRoIDogcGF0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHBhZ2UgcGF0aCBmcm9tIHRoZSBkYXRhLCBkZWZhdWx0aW5nIHRvIHRoZSBwcm92aWRlZCBwYWdlUGF0aCB0byB0aGUgY29udGFpbmVyLlxuICAgKi9cbiAgZ2V0UGFnZVBhdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3FNb2RlbFtDb25zdGFudHMuUEFUSF9QUk9QXSB8fCB0aGlzLnBhZ2VQYXRoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGl0ZW0gZGF0YSBmcm9tIHRoZSBjcU1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSBpdGVtS2V5IC0gdGhlIGl0ZW1LZXkgdG8gbG9vayBmb3IgaW4gdGhlIGl0ZW1zLlxuICAgKi9cbiAgZ2V0SXRlbShpdGVtS2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuY3FNb2RlbFtDb25zdGFudHMuSVRFTVNfUFJPUF1baXRlbUtleV07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaXRlbXNPcmRlciBhcnJheSBmcm9tIHRoZSBjcU1vZGVsXG4gICAqL1xuICBnZXQgaXRlbXNPcmRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5jcU1vZGVsICYmIHRoaXMuY3FNb2RlbFtDb25zdGFudHMuSVRFTVNfT1JERVJfUFJPUF07XG4gIH1cbn1cblxuIiwiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpOyB5b3UgbWF5IG5vdCB1c2VcclxudGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGVcclxuTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuXHJcblRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcclxuS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRFxyXG5XQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLFxyXG5NRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULlxyXG5cclxuU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXHJcbmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDApXHJcbiAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9u