@circe/core
Version:
Circe Components for Angular :: Core Services and Tools
256 lines • 38.7 kB
JavaScript
import { Injectable } from '@angular/core';
import { npaElementFields, npaHashTypes } from '../_types/element.types';
export const boxModelTypeConstants = {
HORIZONTAL: 'horizontal',
VERTICAL: 'vertical'
};
export class BoxModelService {
constructor() {
this._defaultBoxModelType = boxModelTypeConstants.VERTICAL;
this._defaultElementHashType = npaHashTypes.class;
this._defaultComputedStylePropertyProcessed = false;
this._allowCssUnits = ['px', '%'];
this._additionHorizontalInsideClasses = ['padding-left', 'padding-right', 'border-left-width', 'border-right-width'];
this._additionHorizontalOutsideClasses = ['margin-left', 'margin-right'];
this._additionVerticalInsideClasses = ['padding-top', 'padding-bottom', 'border-top-width', 'border-bottom-width'];
this._additionVerticalOutsideClasses = ['margin-top', 'margin-bottom'];
this._fontSizeRule = { applyOnElements: ['i'], boxModelType: boxModelTypeConstants.HORIZONTAL };
}
/**
* _isElementHash
*
* @description
* Checks if element given param is ElementHash type.
*/
static _isElementHash(element) {
return !!(typeof element === 'object' &&
npaElementFields.type in element &&
npaElementFields.name in element &&
(Object.keys(element).length === 2 || Object.keys(element).length === 3));
}
/**
* _isElementQuery
*
* @description
* Checks if element given param is ElementQuery type.
*/
static _isElementQuery(element) {
return !!(typeof element === 'object' &&
npaElementFields.query in element &&
(Object.keys(element).length === 1 || Object.keys(element).length === 2));
}
/**
* _isNativeDomElement
*
* @description
* Checks if element given param is a native DOM element.
*/
static _isNativeDomElement(param) {
const _paramsToCheck = [
'getBoundingClientRect', 'getElementsByClassName', 'getElementsByTagName', 'querySelector'
];
return (!!param) ? (_paramsToCheck.map((e) => e in param)).every((el) => !!el) : false;
}
/**
* getSizeValues
*
* @description
* Get computed height and width from a SizeObject.
*/
static getSizeUnits(sizeObject) {
return {
height: sizeObject.height.value + sizeObject.height.unit,
width: sizeObject.width.value + sizeObject.height.unit
};
}
/**
* _convertToElementIdArray
*
* @description
* Transform elementId type to array of Dom elements.
*/
_convertToElementIdArray(elementId) {
const _auxArgument = [];
const _elementId = (Array.isArray(elementId)) ? elementId : [elementId];
for (const element of _elementId) {
_auxArgument.push(this.getElement(element));
}
return _auxArgument;
}
_getElementAdditions(element, boxModelType) {
const _type = boxModelType || this._defaultBoxModelType;
const _elementStyle = window.getComputedStyle(element);
const _output = {
boxModelAdditionInside: 0,
boxModelAdditionOutside: 0
};
const _auxOutputInside = [];
const _auxOutputOutside = [];
if (_type === boxModelTypeConstants.HORIZONTAL) {
this._additionHorizontalInsideClasses.forEach((e) => {
_auxOutputInside.push(_elementStyle.getPropertyValue(e));
});
this._additionHorizontalOutsideClasses.forEach((e) => {
_auxOutputOutside.push(_elementStyle.getPropertyValue(e));
});
}
else {
this._additionVerticalInsideClasses.forEach((e) => {
_auxOutputInside.push(_elementStyle.getPropertyValue(e));
});
this._additionVerticalOutsideClasses.forEach((e) => {
_auxOutputOutside.push(_elementStyle.getPropertyValue(e));
});
}
_auxOutputInside.forEach((el) => {
if (el !== '0px') {
_output.boxModelAdditionInside += this.readCssUnits(el).value;
}
});
_auxOutputOutside.forEach((el) => {
if (el !== '0px') {
_output.boxModelAdditionOutside += this.readCssUnits(el).value;
}
});
return _output;
}
getComputedStyleProperty(element, property, processed) {
const _processed = processed || this._defaultComputedStylePropertyProcessed;
const _elementComputedStyles = window.getComputedStyle(element);
const _output = _elementComputedStyles.getPropertyValue(property);
if (_output && _processed) {
return this.readCssUnits(_output);
}
return _output;
}
processElementForSpecialRules(element) {
if (this._fontSizeRule.applyOnElements.includes(element.tagName.toLowerCase())) {
const _elementBoxModel = this.getBoxModel(element, boxModelTypeConstants.HORIZONTAL);
const _elementFontSize = this.getComputedStyleProperty(element, 'font-size', true);
if (_elementBoxModel.boxModelExtractedInside !== _elementFontSize.value) {
element.style.width = `${_elementFontSize.value}px`;
return element;
}
}
return element;
}
readCssUnits(expression) {
const _output = { value: 0, unit: '' };
this._allowCssUnits.forEach((e) => {
if (expression.includes(e)) {
_output.unit = e;
const _aux = expression.split(e).filter((el) => !!el);
if (_aux.length === 1) {
_output.value = Number(_aux[0]);
}
return;
}
});
return (_output.value && _output.unit) ? _output : null;
}
processSizeString(sizeString) {
const _output = { width: null, height: null };
if (sizeString) {
const _auxSize = sizeString.split(' ');
if (_auxSize.length === 1) {
const _cssUnit = this.readCssUnits(_auxSize[0]);
_output.width = _cssUnit;
_output.height = _cssUnit;
}
else if (_auxSize.length === 2) {
_output.height = this.readCssUnits(_auxSize[0]);
_output.width = this.readCssUnits(_auxSize[1]);
}
}
return (_output.width && _output.height) ? _output : null;
}
/**
* getElement
*
* @description
* Returns an element DOM native object from different types of given params.
*/
getElement(element) {
let _output = element;
let _element = element;
let _shadowElement = document;
if (typeof element === 'string') {
_element = { type: this._defaultElementHashType, name: element };
}
else {
if (npaElementFields.shadowElement in _element) {
_shadowElement = this.getElement(_element.shadowElement);
}
}
if (!BoxModelService._isNativeDomElement(_element)) {
if (BoxModelService._isElementHash(_element)) {
switch (_element.type) {
case npaHashTypes.class:
_output = _shadowElement.getElementsByClassName(_element.name).item(0);
break;
case npaHashTypes.tag:
_output = _shadowElement.getElementsByTagName(_element.name).item(0);
break;
case npaHashTypes.id:
_output = document.getElementById(_element.name);
break;
}
}
else if (BoxModelService._isElementQuery(_element)) {
_output = _shadowElement.querySelector(_element.query);
}
}
if (!BoxModelService._isNativeDomElement(_output)) {
throw new Error('BoxModel.getElement: Unrecognizable element.');
}
return _output;
}
getDimensions(element) {
let _output;
const _element = this.getElement(element);
if (!!_element) {
const _elementRect = _element.getBoundingClientRect();
_output = {
height: { value: _elementRect.height, unit: 'px' },
width: { value: _elementRect.width, unit: 'px' }
};
}
return _output;
}
getBoxModel(elementId, boxModelType) {
const _output = {
type: boxModelType || this._defaultBoxModelType,
boxModel: 0,
boxModelAdditions: 0,
boxModelAggregated: 0,
boxModelExtracted: 0,
boxModelAdditionsInside: 0,
boxModelAdditionsOutside: 0,
boxModelAggregatedInside: 0,
boxModelAggregatedOutside: 0,
boxModelExtractedInside: 0,
boxModelExtractedOutside: 0
};
const _elementId = this._convertToElementIdArray(elementId);
_elementId.forEach((e) => {
const _elementRect = e.getBoundingClientRect();
const _additions = this._getElementAdditions(e, _output.type);
_output.boxModel += (_output.type === boxModelTypeConstants.HORIZONTAL) ? _elementRect.width : _elementRect.height;
_output.boxModelAdditions += _additions.boxModelAdditionInside + _additions.boxModelAdditionOutside;
_output.boxModelAdditionsInside += _additions.boxModelAdditionInside;
_output.boxModelAdditionsOutside += _additions.boxModelAdditionOutside;
});
_output.boxModelAggregated = _output.boxModel + _output.boxModelAdditions;
_output.boxModelExtracted = _output.boxModel - _output.boxModelAdditions;
_output.boxModelAggregatedInside = _output.boxModel + _output.boxModelAdditionsInside;
_output.boxModelAggregatedOutside = _output.boxModel + _output.boxModelAdditionsOutside;
_output.boxModelExtractedInside = _output.boxModel - _output.boxModelAdditionsInside;
_output.boxModelExtractedOutside = _output.boxModel - _output.boxModelAdditionsOutside;
return _output;
}
}
BoxModelService.decorators = [
{ type: Injectable }
];
BoxModelService.ctorParameters = () => [];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm94LW1vZGVsLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvYm94LW1vZGVsL2JveC1tb2RlbC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFjLGdCQUFnQixFQUFnRCxZQUFZLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQTRDbEksTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUc7SUFDbkMsVUFBVSxFQUFFLFlBQTRCO0lBQ3hDLFFBQVEsRUFBRSxVQUEwQjtDQUNyQyxDQUFDO0FBRVksTUFBTSxPQUFPLGVBQWU7SUFleEM7UUFDRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcscUJBQXFCLENBQUMsUUFBUSxDQUFDO1FBRTNELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDO1FBRWxELElBQUksQ0FBQyxzQ0FBc0MsR0FBRyxLQUFLLENBQUM7UUFFcEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsZ0NBQWdDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsZUFBZSxFQUFFLG1CQUFtQixFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFDckgsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLENBQUMsYUFBYSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyw4QkFBOEIsR0FBRyxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1FBQ25ILElBQUksQ0FBQywrQkFBK0IsR0FBRyxDQUFDLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUV2RSxJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsZUFBZSxFQUFFLENBQUMsR0FBRyxD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LEdBQUcsVUFBVSxDQUFDLHVCQUF1QixDQUFDO1lBQ3BHLE9BQU8sQ0FBQyx1QkFBdUIsSUFBSSxVQUFVLENBQUMsc0JBQXNCLENBQUM7WUFDckUsT0FBTyxDQUFDLHdCQUF3QixJQUFJLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQztRQUN6RSxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxrQkFBa0IsR0FBRyxPQUFPLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztRQUMxRSxPQUFPLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7UUFDekUsT0FBTyxDQUFDLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDO1FBQ3RGLE9BQU8sQ0FBQyx5QkFBeUIsR0FBRyxPQUFPLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQztRQUN4RixPQUFPLENBQUMsdUJBQXVCLEdBQUcsT0FBTyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsdUJBQXVCLENBQUM7UUFDckYsT0FBTyxDQUFDLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLHdCQUF3QixDQUFDO1FBQ3ZGLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7OztZQWxSRixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTnBhRWxlbWVudCwgbnBhRWxlbWVudEZpZWxkcywgTnBhRWxlbWVudEhhc2gsIE5wYUVsZW1lbnRRdWVyeSwgTnBhSGFzaFR5cGUsIG5wYUhhc2hUeXBlc30gZnJvbSAnLi4vX3R5cGVzL2VsZW1lbnQudHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNpemVPYmplY3Qge1xuICB3aWR0aDogUHJvY2Vzc2VkVW5pdE9iamVjdDtcbiAgaGVpZ2h0OiBQcm9jZXNzZWRVbml0T2JqZWN0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNpemVVbml0c09iamVjdCB7XG4gIGhlaWdodDogc3RyaW5nO1xuICB3aWR0aDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb2Nlc3NlZFVuaXRPYmplY3Qge1xuICB2YWx1ZTogbnVtYmVyO1xuICB1bml0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIEVsZW1lbnRJZCA9IE5wYUVsZW1lbnQgfCBBcnJheTxOcGFFbGVtZW50PjtcblxuZXhwb3J0IHR5cGUgQm94TW9kZWxUeXBlID0gJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJztcbmV4cG9ydCBpbnRlcmZhY2UgQm94TW9kZWxTd2FwT2JqZWN0IHtcbiAgdHlwZTogQm94TW9kZWxUeXBlO1xuICBib3hNb2RlbDogbnVtYmVyO1xuICBib3hNb2RlbEFkZGl0aW9uczogbnVtYmVyO1xuICBib3hNb2RlbEFnZ3JlZ2F0ZWQ6IG51bWJlcjtcbiAgYm94TW9kZWxFeHRyYWN0ZWQ6IG51bWJlcjtcbiAgYm94TW9kZWxBZGRpdGlvbnNJbnNpZGU6IG51bWJlcjtcbiAgYm94TW9kZWxBZGRpdGlvbnNPdXRzaWRlOiBudW1iZXI7XG4gIGJveE1vZGVsQWdncmVnYXRlZEluc2lkZTogbnVtYmVyO1xuICBib3hNb2RlbEFnZ3JlZ2F0ZWRPdXRzaWRlOiBudW1iZXI7XG4gIGJveE1vZGVsRXh0cmFjdGVkSW5zaWRlOiBudW1iZXI7XG4gIGJveE1vZGVsRXh0cmFjdGVkT3V0c2lkZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJveE1vZGVsQWRkaXRpb25PYmplY3Qge1xuICBib3hNb2RlbEFkZGl0aW9uSW5zaWRlOiBudW1iZXI7XG4gIGJveE1vZGVsQWRkaXRpb25PdXRzaWRlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BlY2lhbFJ1bGVPYmplY3Qge1xuICBhcHBseU9uRWxlbWVudHM6IEFycmF5PHN0cmluZz47XG4gIGJveE1vZGVsVHlwZTogQm94TW9kZWxUeXBlO1xufVxuXG5leHBvcnQgY29uc3QgYm94TW9kZWxUeXBlQ29uc3RhbnRzID0ge1xuICBIT1JJWk9OVEFMOiAnaG9yaXpvbnRhbCcgYXMgQm94TW9kZWxUeXBlLFxuICBWRVJUSUNBTDogJ3ZlcnRpY2FsJyBhcyBCb3hNb2RlbFR5cGVcbn07XG5cbkBJbmplY3RhYmxlKCkgZXhwb3J0IGNsYXNzIEJveE1vZGVsU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRCb3hNb2RlbFR5cGU6IEJveE1vZGVsVHlwZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0RWxlbWVudEhhc2hUeXBlOiBOcGFIYXNoVHlwZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0Q29tcHV0ZWRTdHlsZVByb3BlcnR5UHJvY2Vzc2VkOiBib29sZWFuO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2FsbG93Q3NzVW5pdHM6IEFycmF5PHN0cmluZz47XG4gIHByaXZhdGUgcmVhZG9ubHkgX2FkZGl0aW9uSG9yaXpvbnRhbEluc2lkZUNsYXNzZXM6IEFycmF5PHN0cmluZz47XG4gIHByaXZhdGUgcmVhZG9ubHkgX2FkZGl0aW9uSG9yaXpvbnRhbE91dHNpZGVDbGFzc2VzOiBBcnJheTxzdHJpbmc+O1xuICBwcml2YXRlIHJlYWRvbmx5IF9hZGRpdGlvblZlcnRpY2FsSW5zaWRlQ2xhc3NlczogQXJyYXk8c3RyaW5nPjtcbiAgcHJpdmF0ZSByZWFkb25seSBfYWRkaXRpb25WZXJ0aWNhbE91dHNpZGVDbGFzc2VzOiBBcnJheTxzdHJpbmc+O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZvbnRTaXplUnVsZTogU3BlY2lhbFJ1bGVPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fZGVmYXVsdEJveE1vZGVsVHlwZSA9IGJveE1vZGVsVHlwZUNvbnN0YW50cy5WRVJUSUNBTDtcblxuICAgIHRoaXMuX2RlZmF1bHRFbGVtZW50SGFzaFR5cGUgPSBucGFIYXNoVHlwZXMuY2xhc3M7XG5cbiAgICB0aGlzLl9kZWZhdWx0Q29tcHV0ZWRTdHlsZVByb3BlcnR5UHJvY2Vzc2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9hbGxvd0Nzc1VuaXRzID0gWydweCcsICclJ107XG4gICAgdGhpcy5fYWRkaXRpb25Ib3Jpem9udGFsSW5zaWRlQ2xhc3NlcyA9IFsncGFkZGluZy1sZWZ0JywgJ3BhZGRpbmctcmlnaHQnLCAnYm9yZGVyLWxlZnQtd2lkdGgnLCAnYm9yZGVyLXJpZ2h0LXdpZHRoJ107XG4gICAgdGhpcy5fYWRkaXRpb25Ib3Jpem9udGFsT3V0c2lkZUNsYXNzZXMgPSBbJ21hcmdpbi1sZWZ0JywgJ21hcmdpbi1yaWdodCddO1xuICAgIHRoaXMuX2FkZGl0aW9uVmVydGljYWxJbnNpZGVDbGFzc2VzID0gWydwYWRkaW5nLXRvcCcsICdwYWRkaW5nLWJvdHRvbScsICdib3JkZXItdG9wLXdpZHRoJywgJ2JvcmRlci1ib3R0b20td2lkdGgnXTtcbiAgICB0aGlzLl9hZGRpdGlvblZlcnRpY2FsT3V0c2lkZUNsYXNzZXMgPSBbJ21hcmdpbi10b3AnLCAnbWFyZ2luLWJvdHRvbSddO1xuXG4gICAgdGhpcy5fZm9udFNpemVSdWxlID0geyBhcHBseU9uRWxlbWVudHM6IFsnaSddLCBib3hNb2RlbFR5cGU6IGJveE1vZGVsVHlwZUNvbnN0YW50cy5IT1JJWk9OVEFMIH07XG4gIH1cblxuICAvKipcbiAgICogX2lzRWxlbWVudEhhc2hcbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIENoZWNrcyBpZiBlbGVtZW50IGdpdmVuIHBhcmFtIGlzIEVsZW1lbnRIYXNoIHR5cGUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIF9pc0VsZW1lbnRIYXNoKGVsZW1lbnQ6IE5wYUVsZW1lbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEoXG4gICAgICB0eXBlb2YgZWxlbWVudCA9PT0gJ29iamVjdCcgJiZcbiAgICAgIG5wYUVsZW1lbnRGaWVsZHMudHlwZSBpbiBlbGVtZW50ICYmXG4gICAgICBucGFFbGVtZW50RmllbGRzLm5hbWUgaW4gZWxlbWVudCAmJlxuICAgICAgKE9iamVjdC5rZXlzKGVsZW1lbnQpLmxlbmd0aCA9PT0gMiB8fCBPYmplY3Qua2V5cyhlbGVtZW50KS5sZW5ndGggPT09IDMpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBfaXNFbGVtZW50UXVlcnlcbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIENoZWNrcyBpZiBlbGVtZW50IGdpdmVuIHBhcmFtIGlzIEVsZW1lbnRRdWVyeSB0eXBlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBfaXNFbGVtZW50UXVlcnkoZWxlbWVudDogTnBhRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIShcbiAgICAgIHR5cGVvZiBlbGVtZW50ID09PSAnb2JqZWN0JyAmJlxuICAgICAgbnBhRWxlbWVudEZpZWxkcy5xdWVyeSBpbiBlbGVtZW50ICYmXG4gICAgICAoT2JqZWN0LmtleXMoZWxlbWVudCkubGVuZ3RoID09PSAxIHx8IE9iamVjdC5rZXlzKGVsZW1lbnQpLmxlbmd0aCA9PT0gMilcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIF9pc05hdGl2ZURvbUVsZW1lbnRcbiAgICpcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIENoZWNrcyBpZiBlbGVtZW50IGdpdmVuIHBhcmFtIGlzIGEgbmF0aXZlIERPTSBlbGVtZW50LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBfaXNOYXRpdmVEb21FbGVtZW50KHBhcmFtOiBhbnkpOiBwYXJhbSBpcyBFbGVtZW50IHtcbiAgICBjb25zdCBfcGFyYW1zVG9DaGVjazogQXJyYXk8c3RyaW5nPiA9IFtcbiAgICAgICdnZXRCb3VuZGluZ0NsaWVudFJlY3QnLCAnZ2V0RWxlbWVudHNCeUNsYXNzTmFtZScsICdnZXRFbGVtZW50c0J5VGFnTmFtZScsICdxdWVyeVNlbGVjdG9yJ1xuICAgIF07XG4gICAgcmV0dXJuICghIXBhcmFtKSA/IChfcGFyYW1zVG9DaGVjay5tYXAoKGU6IHN0cmluZykgPT4gZSBpbiBwYXJhbSkpLmV2ZXJ5KChlbCkgPT4gISFlbCkgOiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXRTaXplVmFsdWVzXG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBHZXQgY29tcHV0ZWQgaGVpZ2h0IGFuZCB3aWR0aCBmcm9tIGEgU2l6ZU9iamVjdC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZ2V0U2l6ZVVuaXRzKHNpemVPYmplY3Q6IFNpemVPYmplY3QpOiBTaXplVW5pdHNPYmplY3Qge1xuICAgIHJldHVybiB7XG4gICAgICBoZWlnaHQ6IHNpemVPYmplY3QuaGVpZ2h0LnZhbHVlICsgc2l6ZU9iamVjdC5oZWlnaHQudW5pdCxcbiAgICAgIHdpZHRoOiBzaXplT2JqZWN0LndpZHRoLnZhbHVlICsgc2l6ZU9iamVjdC5oZWlnaHQudW5pdFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogX2NvbnZlcnRUb0VsZW1lbnRJZEFycmF5XG4gICAqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBUcmFuc2Zvcm0gZWxlbWVudElkIHR5cGUgdG8gYXJyYXkgb2YgRG9tIGVsZW1lbnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBfY29udmVydFRvRWxlbWVudElkQXJyYXkoZWxlbWVudElkOiBFbGVtZW50SWQpOiBBcnJheTxFbGVtZW50PiB7XG4gICAgY29uc3QgX2F1eEFyZ3VtZW50OiBBcnJheTxFbGVtZW50PiA9IFtdO1xuICAgIGNvbnN0IF9lbGVtZW50SWQ6IEFycmF5PE5wYUVsZW1lbnQ+ID0gKEFycmF5LmlzQXJyYXkoZWxlbWVudElkKSkgPyBlbGVtZW50SWQgOiBbZWxlbWVudElkXTtcbiAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgX2VsZW1lbnRJZCkge1xuICAgICAgX2F1eEFyZ3VtZW50LnB1c2godGhpcy5nZXRFbGVtZW50KGVsZW1lbnQpKTtcbiAgICB9XG4gICAgcmV0dXJuIF9hdXhBcmd1bWVudDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldEVsZW1lbnRBZGRpdGlvbnMoZWxlbWVudDogRWxlbWVudCwgYm94TW9kZWxUeXBlPzogQm94TW9kZWxUeXBlKTogQm94TW9kZWxBZGRpdGlvbk9iamVjdCB7XG4gICAgY29uc3QgX3R5cGU6IEJveE1vZGVsVHlwZSA9IGJveE1vZGVsVHlwZSB8fCB0aGlzLl9kZWZhdWx0Qm94TW9kZWxUeXBlO1xuICAgIGNvbnN0IF9lbGVtZW50U3R5bGU6IENTU1N0eWxlRGVjbGFyYXRpb24gPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgICBjb25zdCBfb3V0cHV0OiBCb3hNb2RlbEFkZGl0aW9uT2JqZWN0ID0ge1xuICAgICAgYm94TW9kZWxBZGRpdGlvbkluc2lkZTogMCxcbiAgICAgIGJveE1vZGVsQWRkaXRpb25PdXRzaWRlOiAwXG4gICAgfTtcbiAgICBjb25zdCBfYXV4T3V0cHV0SW5zaWRlOiBBcnJheTxzdHJpbmc+ID0gW107XG4gICAgY29uc3QgX2F1eE91dHB1dE91dHNpZGU6IEFycmF5PHN0cmluZz4gPSBbXTtcbiAgICBpZiAoX3R5cGUgPT09IGJveE1vZGVsVHlwZUNvbnN0YW50cy5IT1JJWk9OVEFMKSB7XG4gICAgICB0aGlzLl9hZGRpdGlvbkhvcml6b250YWxJbnNpZGVDbGFzc2VzLmZvckVhY2goKGU6IHN0cmluZykgPT4ge1xuICAgICAgICBfYXV4T3V0cHV0SW5zaWRlLnB1c2goX2VsZW1lbnRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKGUpKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5fYWRkaXRpb25Ib3Jpem9udGFsT3V0c2lkZUNsYXNzZXMuZm9yRWFjaCgoZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIF9hdXhPdXRwdXRPdXRzaWRlLnB1c2goX2VsZW1lbnRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKGUpKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hZGRpdGlvblZlcnRpY2FsSW5zaWRlQ2xhc3Nlcy5mb3JFYWNoKChlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgX2F1eE91dHB1dEluc2lkZS5wdXNoKF9lbGVtZW50U3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShlKSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX2FkZGl0aW9uVmVydGljYWxPdXRzaWRlQ2xhc3Nlcy5mb3JFYWNoKChlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgX2F1eE91dHB1dE91dHNpZGUucHVzaChfZWxlbWVudFN0eWxlLmdldFByb3BlcnR5VmFsdWUoZSkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIF9hdXhPdXRwdXRJbnNpZGUuZm9yRWFjaCgoZWw6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKGVsICE9PSAnMHB4Jykge1xuICAgICAgICBfb3V0cHV0LmJveE1vZGVsQWRkaXRpb25JbnNpZGUgKz0gdGhpcy5yZWFkQ3NzVW5pdHMoZWwpLnZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIF9hdXhPdXRwdXRPdXRzaWRlLmZvckVhY2goKGVsOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChlbCAhPT0gJzBweCcpIHtcbiAgICAgICAgX291dHB1dC5ib3hNb2RlbEFkZGl0aW9uT3V0c2lkZSArPSB0aGlzLnJlYWRDc3NVbml0cyhlbCkudmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIF9vdXRwdXQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29tcHV0ZWRTdHlsZVByb3BlcnR5KGVsZW1lbnQ6IEVsZW1lbnQsIHByb3BlcnR5OiBzdHJpbmcsIHByb2Nlc3NlZD86IGJvb2xlYW4pOiBzdHJpbmcgfCBQcm9jZXNzZWRVbml0T2JqZWN0IHtcbiAgICBjb25zdCBfcHJvY2Vzc2VkOiBib29sZWFuID0gcHJvY2Vzc2VkIHx8IHRoaXMuX2RlZmF1bHRDb21wdXRlZFN0eWxlUHJvcGVydHlQcm9jZXNzZWQ7XG4gICAgY29uc3QgX2VsZW1lbnRDb21wdXRlZFN0eWxlczogQ1NTU3R5bGVEZWNsYXJhdGlvbiA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICAgIGNvbnN0IF9vdXRwdXQ6IHN0cmluZyA9IF9lbGVtZW50Q29tcHV0ZWRTdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSk7XG4gICAgaWYgKF9vdXRwdXQgJiYgX3Byb2Nlc3NlZCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVhZENzc1VuaXRzKF9vdXRwdXQpO1xuICAgIH1cbiAgICByZXR1cm4gX291dHB1dDtcbiAgfVxuXG4gIHB1YmxpYyBwcm9jZXNzRWxlbWVudEZvclNwZWNpYWxSdWxlcyhlbGVtZW50OiBFbGVtZW50KTogRWxlbWVudCB7XG4gICAgaWYgKHRoaXMuX2ZvbnRTaXplUnVsZS5hcHBseU9uRWxlbWVudHMuaW5jbHVkZXMoZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICBjb25zdCBfZWxlbWVudEJveE1vZGVsOiBCb3hNb2RlbFN3YXBPYmplY3QgPSB0aGlzLmdldEJveE1vZGVsKGVsZW1lbnQsIGJveE1vZGVsVHlwZUNvbnN0YW50cy5IT1JJWk9OVEFMKTtcbiAgICAgIGNvbnN0IF9lbGVtZW50Rm9udFNpemU6IFByb2Nlc3NlZFVuaXRPYmplY3QgPSB0aGlzLmdldENvbXB1dGVkU3R5bGVQcm9wZXJ0eShlbGVtZW50LCAnZm9udC1zaXplJywgdHJ1ZSkgYXMgUHJvY2Vzc2VkVW5pdE9iamVjdDtcbiAgICAgIGlmIChfZWxlbWVudEJveE1vZGVsLmJveE1vZGVsRXh0cmFjdGVkSW5zaWRlICE9PSBfZWxlbWVudEZvbnRTaXplLnZhbHVlKSB7XG4gICAgICAgIChlbGVtZW50IGFzIEhUTUxFbGVtZW50KS5zdHlsZS53aWR0aCA9IGAke19lbGVtZW50Rm9udFNpemUudmFsdWV9cHhgO1xuICAgICAgICByZXR1cm4gZWxlbWVudCBhcyBFbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIHB1YmxpYyByZWFkQ3NzVW5pdHMoZXhwcmVzc2lvbjogc3RyaW5nKTogUHJvY2Vzc2VkVW5pdE9iamVjdCB7XG4gICAgY29uc3QgX291dHB1dDogUHJvY2Vzc2VkVW5pdE9iamVjdCA9IHsgdmFsdWU6IDAsIHVuaXQ6ICcnIH07XG4gICAgdGhpcy5fYWxsb3dDc3NVbml0cy5mb3JFYWNoKChlOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChleHByZXNzaW9uLmluY2x1ZGVzKGUpKSB7XG4gICAgICAgIF9vdXRwdXQudW5pdCA9IGU7XG4gICAgICAgIGNvbnN0IF9hdXg6IEFycmF5PHN0cmluZz4gPSBleHByZXNzaW9uLnNwbGl0KGUpLmZpbHRlcigoZWw6IHN0cmluZykgPT4gISFlbCk7XG4gICAgICAgIGlmIChfYXV4Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIF9vdXRwdXQudmFsdWUgPSBOdW1iZXIoX2F1eFswXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiAoX291dHB1dC52YWx1ZSAmJiBfb3V0cHV0LnVuaXQpID8gX291dHB1dCA6IG51bGw7XG4gIH1cblxuICBwdWJsaWMgcHJvY2Vzc1NpemVTdHJpbmcoc2l6ZVN0cmluZzogc3RyaW5nKTogU2l6ZU9iamVjdCB7XG4gICAgY29uc3QgX291dHB1dDogU2l6ZU9iamVjdCA9IHsgd2lkdGg6IG51bGwsIGhlaWdodDogbnVsbCB9O1xuICAgIGlmIChzaXplU3RyaW5nKSB7XG4gICAgICBjb25zdCBfYXV4U2l6ZTogQXJyYXk8c3RyaW5nPiA9IHNpemVTdHJpbmcuc3BsaXQoJyAnKTtcbiAgICAgIGlmIChfYXV4U2l6ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgY29uc3QgX2Nzc1VuaXQ6IFByb2Nlc3NlZFVuaXRPYmplY3QgPSB0aGlzLnJlYWRDc3NVbml0cyhfYXV4U2l6ZVswXSk7XG4gICAgICAgIF9vdXRwdXQud2lkdGggPSBfY3NzVW5pdDtcbiAgICAgICAgX291dHB1dC5oZWlnaHQgPSBfY3NzVW5pdDtcbiAgICAgIH0gZWxzZSBpZiAoX2F1eFNpemUubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIF9vdXRwdXQuaGVpZ2h0ID0gdGhpcy5yZWFkQ3NzVW5pdHMoX2F1eFNpemVbMF0pO1xuICAgICAgICBfb3V0cHV0LndpZHRoID0gdGhpcy5yZWFkQ3NzVW5pdHMoX2F1eFNpemVbMV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gKF9vdXRwdXQud2lkdGggJiYgX291dHB1dC5oZWlnaHQpID8gX291dHB1dCA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogZ2V0RWxlbWVudFxuICAgKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogUmV0dXJucyBhbiBlbGVtZW50IERPTSBuYXRpdmUgb2JqZWN0IGZyb20gZGlmZmVyZW50IHR5cGVzIG9mIGdpdmVuIHBhcmFtcy5cbiAgICovXG4gIHB1YmxpYyBnZXRFbGVtZW50KGVsZW1lbnQ6IE5wYUVsZW1lbnQpOiBFbGVtZW50IHtcbiAgICBsZXQgX291dHB1dDogRWxlbWVudCA9IGVsZW1lbnQgYXMgRWxlbWVudDtcbiAgICBsZXQgX2VsZW1lbnQ6IE5wYUVsZW1lbnQgPSBlbGVtZW50O1xuICAgIGxldCBfc2hhZG93RWxlbWVudDogRWxlbWVudCB8IERvY3VtZW50ID0gZG9jdW1lbnQ7XG4gICAgaWYgKHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgX2VsZW1lbnQgPSB7IHR5cGU6IHRoaXMuX2RlZmF1bHRFbGVtZW50SGFzaFR5cGUsIG5hbWU6IGVsZW1lbnQgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG5wYUVsZW1lbnRGaWVsZHMuc2hhZG93RWxlbWVudCBpbiAoX2VsZW1lbnQgYXMgTnBhRWxlbWVudEhhc2ggfCBOcGFFbGVtZW50UXVlcnkpKSB7XG4gICAgICAgIF9zaGFkb3dFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KChfZWxlbWVudCBhcyBOcGFFbGVtZW50SGFzaCB8IE5wYUVsZW1lbnRRdWVyeSkuc2hhZG93RWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghQm94TW9kZWxTZXJ2aWNlLl9pc05hdGl2ZURvbUVsZW1lbnQoX2VsZW1lbnQpKSB7XG4gICAgICBpZiAoQm94TW9kZWxTZXJ2aWNlLl9pc0VsZW1lbnRIYXNoKF9lbGVtZW50KSkge1xuICAgICAgICBzd2l0Y2ggKChfZWxlbWVudCBhcyBOcGFFbGVtZW50SGFzaCkudHlwZSkge1xuICAgICAgICAgIGNhc2UgbnBhSGFzaFR5cGVzLmNsYXNzOlxuICAgICAgICAgICAgX291dHB1dCA9IF9zaGFkb3dFbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoKF9lbGVtZW50IGFzIE5wYUVsZW1lbnRIYXNoKS5uYW1lKS5pdGVtKDApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBucGFIYXNoVHlwZXMudGFnOlxuICAgICAgICAgICAgX291dHB1dCA9IF9zaGFkb3dFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKChfZWxlbWVudCBhcyBOcGFFbGVtZW50SGFzaCkubmFtZSkuaXRlbSgwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgbnBhSGFzaFR5cGVzLmlkOlxuICAgICAgICAgICAgX291dHB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKChfZWxlbWVudCBhcyBOcGFFbGVtZW50SGFzaCkubmFtZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChCb3hNb2RlbFNlcnZpY2UuX2lzRWxlbWVudFF1ZXJ5KF9lbGVtZW50KSkge1xuICAgICAgICBfb3V0cHV0ID0gX3NoYWRvd0VsZW1lbnQucXVlcnlTZWxlY3RvcigoX2VsZW1lbnQgYXMgTnBhRWxlbWVudFF1ZXJ5KS5xdWVyeSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghQm94TW9kZWxTZXJ2aWNlLl9pc05hdGl2ZURvbUVsZW1lbnQoX291dHB1dCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQm94TW9kZWwuZ2V0RWxlbWVudDogVW5yZWNvZ25pemFibGUgZWxlbWVudC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIF9vdXRwdXQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0RGltZW5zaW9ucyhlbGVtZW50OiBOcGFFbGVtZW50KTogU2l6ZU9iamVjdCB7XG4gICAgbGV0IF9vdXRwdXQ6IFNpemVPYmplY3Q7XG4gICAgY29uc3QgX2VsZW1lbnQ6IEVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQoZWxlbWVudCk7XG4gICAgaWYgKCEhX2VsZW1lbnQpIHtcbiAgICAgIGNvbnN0IF9lbGVtZW50UmVjdDogRE9NUmVjdCA9IF9lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgX291dHB1dCA9IHtcbiAgICAgICAgaGVpZ2h0OiB7IHZhbHVlOiBfZWxlbWVudFJlY3QuaGVpZ2h0LCB1bml0OiAncHgnIH0sXG4gICAgICAgIHdpZHRoOiB7IHZhbHVlOiBfZWxlbWVudFJlY3Qud2lkdGgsIHVuaXQ6ICdweCcgfVxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIF9vdXRwdXQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0Qm94TW9kZWwoZWxlbWVudElkOiBFbGVtZW50SWQsIGJveE1vZGVsVHlwZT86IEJveE1vZGVsVHlwZSk6IEJveE1vZGVsU3dhcE9iamVjdCB7XG4gICAgY29uc3QgX291dHB1dDogQm94TW9kZWxTd2FwT2JqZWN0ID0ge1xuICAgICAgdHlwZTogYm94TW9kZWxUeXBlIHx8IHRoaXMuX2RlZmF1bHRCb3hNb2RlbFR5cGUsXG4gICAgICBib3hNb2RlbDogMCxcbiAgICAgIGJveE1vZGVsQWRkaXRpb25zOiAwLFxuICAgICAgYm94TW9kZWxBZ2dyZWdhdGVkOiAwLFxuICAgICAgYm94TW9kZWxFeHRyYWN0ZWQ6IDAsXG4gICAgICBib3hNb2RlbEFkZGl0aW9uc0luc2lkZTogMCxcbiAgICAgIGJveE1vZGVsQWRkaXRpb25zT3V0c2lkZTogMCxcbiAgICAgIGJveE1vZGVsQWdncmVnYXRlZEluc2lkZTogMCxcbiAgICAgIGJveE1vZGVsQWdncmVnYXRlZE91dHNpZGU6IDAsXG4gICAgICBib3hNb2RlbEV4dHJhY3RlZEluc2lkZTogMCxcbiAgICAgIGJveE1vZGVsRXh0cmFjdGVkT3V0c2lkZTogMFxuICAgIH07XG4gICAgY29uc3QgX2VsZW1lbnRJZDogQXJyYXk8RWxlbWVudD4gPSB0aGlzLl9jb252ZXJ0VG9FbGVtZW50SWRBcnJheShlbGVtZW50SWQpO1xuICAgIF9lbGVtZW50SWQuZm9yRWFjaCgoZTogRWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgX2VsZW1lbnRSZWN0OiBET01SZWN0IHwgQ2xpZW50UmVjdCA9IGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBfYWRkaXRpb25zOiBCb3hNb2RlbEFkZGl0aW9uT2JqZWN0ID0gdGhpcy5fZ2V0RWxlbWVudEFkZGl0aW9ucyhlLCBfb3V0cHV0LnR5cGUpO1xuICAgICAgX291dHB1dC5ib3hNb2RlbCArPSAoX291dHB1dC50eXBlID09PSBib3hNb2RlbFR5cGVDb25zdGFudHMuSE9SSVpPTlRBTCkgPyBfZWxlbWVudFJlY3Qud2lkdGggOiBfZWxlbWVudFJlY3QuaGVpZ2h0O1xuICAgICAgX291dHB1dC5ib3hNb2RlbEFkZGl0aW9ucyArPSBfYWRkaXRpb25zLmJveE1vZGVsQWRkaXRpb25JbnNpZGUgKyBfYWRkaXRpb25zLmJveE1vZGVsQWRkaXRpb25PdXRzaWRlO1xuICAgICAgX291dHB1dC5ib3hNb2RlbEFkZGl0aW9uc0luc2lkZSArPSBfYWRkaXRpb25zLmJveE1vZGVsQWRkaXRpb25JbnNpZGU7XG4gICAgICBfb3V0cHV0LmJveE1vZGVsQWRkaXRpb25zT3V0c2lkZSArPSBfYWRkaXRpb25zLmJveE1vZGVsQWRkaXRpb25PdXRzaWRlO1xuICAgIH0pO1xuICAgIF9vdXRwdXQuYm94TW9kZWxBZ2dyZWdhdGVkID0gX291dHB1dC5ib3hNb2RlbCArIF9vdXRwdXQuYm94TW9kZWxBZGRpdGlvbnM7XG4gICAgX291dHB1dC5ib3hNb2RlbEV4dHJhY3RlZCA9IF9vdXRwdXQuYm94TW9kZWwgLSBfb3V0cHV0LmJveE1vZGVsQWRkaXRpb25zO1xuICAgIF9vdXRwdXQuYm94TW9kZWxBZ2dyZWdhdGVkSW5zaWRlID0gX291dHB1dC5ib3hNb2RlbCArIF9vdXRwdXQuYm94TW9kZWxBZGRpdGlvbnNJbnNpZGU7XG4gICAgX291dHB1dC5ib3hNb2RlbEFnZ3JlZ2F0ZWRPdXRzaWRlID0gX291dHB1dC5ib3hNb2RlbCArIF9vdXRwdXQuYm94TW9kZWxBZGRpdGlvbnNPdXRzaWRlO1xuICAgIF9vdXRwdXQuYm94TW9kZWxFeHRyYWN0ZWRJbnNpZGUgPSBfb3V0cHV0LmJveE1vZGVsIC0gX291dHB1dC5ib3hNb2RlbEFkZGl0aW9uc0luc2lkZTtcbiAgICBfb3V0cHV0LmJveE1vZGVsRXh0cmFjdGVkT3V0c2lkZSA9IF9vdXRwdXQuYm94TW9kZWwgLSBfb3V0cHV0LmJveE1vZGVsQWRkaXRpb25zT3V0c2lkZTtcbiAgICByZXR1cm4gX291dHB1dDtcbiAgfVxufVxuIl19