@ngx-i18nsupport/ngx-i18nsupport-lib
Version:
A Typescript library to work with Angular generated i18n files (xliff, xmb)
620 lines • 42.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { DOMUtilities } from './dom-utilities';
import { AbstractTransUnit } from './abstract-trans-unit';
import { XmbMessageParser } from './xmb-message-parser';
/**
* Created by martin on 01.05.2017.
* A Translation Unit in an XMB file.
*/
var /**
* Created by martin on 01.05.2017.
* A Translation Unit in an XMB file.
*/
XmbTransUnit = /** @class */ (function (_super) {
tslib_1.__extends(XmbTransUnit, _super);
function XmbTransUnit(_element, _id, _translationMessagesFile) {
return _super.call(this, _element, _id, _translationMessagesFile) || this;
}
/**
* Parses something like 'c:\xxx:7' and returns source and linenumber.
* @param sourceAndPos something like 'c:\xxx:7', last colon is the separator
* @return source and linenumber
*/
/**
* Parses something like 'c:\xxx:7' and returns source and linenumber.
* @private
* @param {?} sourceAndPos something like 'c:\xxx:7', last colon is the separator
* @return {?} source and linenumber
*/
XmbTransUnit.parseSourceAndPos = /**
* Parses something like 'c:\xxx:7' and returns source and linenumber.
* @private
* @param {?} sourceAndPos something like 'c:\xxx:7', last colon is the separator
* @return {?} source and linenumber
*/
function (sourceAndPos) {
/** @type {?} */
var index = sourceAndPos.lastIndexOf(':');
if (index < 0) {
return {
sourcefile: sourceAndPos,
linenumber: 0
};
}
else {
return {
sourcefile: sourceAndPos.substring(0, index),
linenumber: XmbTransUnit.parseLineNumber(sourceAndPos.substring(index + 1))
};
}
};
/**
* @private
* @param {?} lineNumberString
* @return {?}
*/
XmbTransUnit.parseLineNumber = /**
* @private
* @param {?} lineNumberString
* @return {?}
*/
function (lineNumberString) {
return Number.parseInt(lineNumberString, 10);
};
/**
* Get content to translate.
* Source parts are excluded here.
* @return source content
*/
/**
* Get content to translate.
* Source parts are excluded here.
* @return {?} source content
*/
XmbTransUnit.prototype.sourceContent = /**
* Get content to translate.
* Source parts are excluded here.
* @return {?} source content
*/
function () {
/** @type {?} */
var msgContent = DOMUtilities.getXMLContent(this._element);
/** @type {?} */
var reSourceElem = /<source>.*<\/source>/g;
msgContent = msgContent.replace(reSourceElem, '');
return msgContent;
};
/**
* Test, wether setting of source content is supported.
* If not, setSourceContent in trans-unit will do nothing.
* xtb does not support this, all other formats do.
*/
/**
* Test, wether setting of source content is supported.
* If not, setSourceContent in trans-unit will do nothing.
* xtb does not support this, all other formats do.
* @return {?}
*/
XmbTransUnit.prototype.supportsSetSourceContent = /**
* Test, wether setting of source content is supported.
* If not, setSourceContent in trans-unit will do nothing.
* xtb does not support this, all other formats do.
* @return {?}
*/
function () {
return false;
};
/**
* Set new source content in the transunit.
* Normally, this is done by ng-extract.
* Method only exists to allow xliffmerge to merge missing changed source content.
* @param newContent the new content.
*/
/**
* Set new source content in the transunit.
* Normally, this is done by ng-extract.
* Method only exists to allow xliffmerge to merge missing changed source content.
* @param {?} newContent the new content.
* @return {?}
*/
XmbTransUnit.prototype.setSourceContent = /**
* Set new source content in the transunit.
* Normally, this is done by ng-extract.
* Method only exists to allow xliffmerge to merge missing changed source content.
* @param {?} newContent the new content.
* @return {?}
*/
function (newContent) {
// not supported
};
/**
* Return a parser used for normalized messages.
*/
/**
* Return a parser used for normalized messages.
* @protected
* @return {?}
*/
XmbTransUnit.prototype.messageParser = /**
* Return a parser used for normalized messages.
* @protected
* @return {?}
*/
function () {
return new XmbMessageParser();
};
/**
* The original text value, that is to be translated, as normalized message.
*/
/**
* The original text value, that is to be translated, as normalized message.
* @return {?}
*/
XmbTransUnit.prototype.createSourceContentNormalized = /**
* The original text value, that is to be translated, as normalized message.
* @return {?}
*/
function () {
return this.messageParser().createNormalizedMessageFromXML(this._element, null);
};
/**
* the translated value (containing all markup, depends on the concrete format used).
*/
/**
* the translated value (containing all markup, depends on the concrete format used).
* @return {?}
*/
XmbTransUnit.prototype.targetContent = /**
* the translated value (containing all markup, depends on the concrete format used).
* @return {?}
*/
function () {
// in fact, target and source are just the same in xmb
return this.sourceContent();
};
/**
* the translated value, but all placeholders are replaced with {{n}} (starting at 0)
* and all embedded html is replaced by direct html markup.
*/
/**
* the translated value, but all placeholders are replaced with {{n}} (starting at 0)
* and all embedded html is replaced by direct html markup.
* @return {?}
*/
XmbTransUnit.prototype.targetContentNormalized = /**
* the translated value, but all placeholders are replaced with {{n}} (starting at 0)
* and all embedded html is replaced by direct html markup.
* @return {?}
*/
function () {
return new XmbMessageParser().createNormalizedMessageFromXML(this._element, this.sourceContentNormalized());
};
/**
* State of the translation.
* (not supported in xmb)
*/
/**
* State of the translation.
* (not supported in xmb)
* @return {?}
*/
XmbTransUnit.prototype.nativeTargetState = /**
* State of the translation.
* (not supported in xmb)
* @return {?}
*/
function () {
return null; // not supported in xmb
};
/**
* Map an abstract state (new, translated, final) to a concrete state used in the xml.
* Returns the state to be used in the xml.
* @param state one of Constants.STATE...
* @returns a native state (depends on concrete format)
* @throws error, if state is invalid.
*/
/**
* Map an abstract state (new, translated, final) to a concrete state used in the xml.
* Returns the state to be used in the xml.
* @throws error, if state is invalid.
* @protected
* @param {?} state one of Constants.STATE...
* @return {?} a native state (depends on concrete format)
*/
XmbTransUnit.prototype.mapStateToNativeState = /**
* Map an abstract state (new, translated, final) to a concrete state used in the xml.
* Returns the state to be used in the xml.
* @throws error, if state is invalid.
* @protected
* @param {?} state one of Constants.STATE...
* @return {?} a native state (depends on concrete format)
*/
function (state) {
return state;
};
/**
* Map a native state (found in the document) to an abstract state (new, translated, final).
* Returns the abstract state.
* @param nativeState nativeState
*/
/**
* Map a native state (found in the document) to an abstract state (new, translated, final).
* Returns the abstract state.
* @protected
* @param {?} nativeState nativeState
* @return {?}
*/
XmbTransUnit.prototype.mapNativeStateToState = /**
* Map a native state (found in the document) to an abstract state (new, translated, final).
* Returns the abstract state.
* @protected
* @param {?} nativeState nativeState
* @return {?}
*/
function (nativeState) {
return nativeState;
};
/**
* set state in xml.
* (not supported in xmb)
* @param nativeState nativeState
*/
/**
* set state in xml.
* (not supported in xmb)
* @protected
* @param {?} nativeState nativeState
* @return {?}
*/
XmbTransUnit.prototype.setNativeTargetState = /**
* set state in xml.
* (not supported in xmb)
* @protected
* @param {?} nativeState nativeState
* @return {?}
*/
function (nativeState) {
// not supported for xmb
};
/**
* All the source elements in the trans unit.
* The source element is a reference to the original template.
* It contains the name of the template file and a line number with the position inside the template.
* It is just a help for translators to find the context for the translation.
* This is set when using Angular 4.0 or greater.
* Otherwise it just returns an empty array.
*/
/**
* All the source elements in the trans unit.
* The source element is a reference to the original template.
* It contains the name of the template file and a line number with the position inside the template.
* It is just a help for translators to find the context for the translation.
* This is set when using Angular 4.0 or greater.
* Otherwise it just returns an empty array.
* @return {?}
*/
XmbTransUnit.prototype.sourceReferences = /**
* All the source elements in the trans unit.
* The source element is a reference to the original template.
* It contains the name of the template file and a line number with the position inside the template.
* It is just a help for translators to find the context for the translation.
* This is set when using Angular 4.0 or greater.
* Otherwise it just returns an empty array.
* @return {?}
*/
function () {
/** @type {?} */
var sourceElements = this._element.getElementsByTagName('source');
/** @type {?} */
var sourceRefs = [];
for (var i = 0; i < sourceElements.length; i++) {
/** @type {?} */
var elem = sourceElements.item(i);
/** @type {?} */
var sourceAndPos = DOMUtilities.getPCDATA(elem);
sourceRefs.push(XmbTransUnit.parseSourceAndPos(sourceAndPos));
}
return sourceRefs;
};
/**
* Set source ref elements in the transunit.
* Normally, this is done by ng-extract.
* Method only exists to allow xliffmerge to merge missing source refs.
* @param sourceRefs the sourcerefs to set. Old ones are removed.
*/
/**
* Set source ref elements in the transunit.
* Normally, this is done by ng-extract.
* Method only exists to allow xliffmerge to merge missing source refs.
* @param {?} sourceRefs the sourcerefs to set. Old ones are removed.
* @return {?}
*/
XmbTransUnit.prototype.setSourceReferences = /**
* Set source ref elements in the transunit.
* Normally, this is done by ng-extract.
* Method only exists to allow xliffmerge to merge missing source refs.
* @param {?} sourceRefs the sourcerefs to set. Old ones are removed.
* @return {?}
*/
function (sourceRefs) {
this.removeAllSourceReferences();
/** @type {?} */
var insertPosition = this._element.childNodes.item(0);
for (var i = sourceRefs.length - 1; i >= 0; i--) {
/** @type {?} */
var ref = sourceRefs[i];
/** @type {?} */
var source = this._element.ownerDocument.createElement('source');
source.appendChild(this._element.ownerDocument.createTextNode(ref.sourcefile + ':' + ref.linenumber.toString(10)));
this._element.insertBefore(source, insertPosition);
insertPosition = source;
}
};
/**
* @private
* @return {?}
*/
XmbTransUnit.prototype.removeAllSourceReferences = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var sourceElements = this._element.getElementsByTagName('source');
/** @type {?} */
var toBeRemoved = [];
for (var i = 0; i < sourceElements.length; i++) {
/** @type {?} */
var elem = sourceElements.item(i);
toBeRemoved.push(elem);
}
toBeRemoved.forEach((/**
* @param {?} elem
* @return {?}
*/
function (elem) { elem.parentNode.removeChild(elem); }));
};
/**
* The description set in the template as value of the i18n-attribute.
* e.g. i18n="mydescription".
* In xmb this is stored in the attribute "desc".
*/
/**
* The description set in the template as value of the i18n-attribute.
* e.g. i18n="mydescription".
* In xmb this is stored in the attribute "desc".
* @return {?}
*/
XmbTransUnit.prototype.description = /**
* The description set in the template as value of the i18n-attribute.
* e.g. i18n="mydescription".
* In xmb this is stored in the attribute "desc".
* @return {?}
*/
function () {
return this._element.getAttribute('desc');
};
/**
* The meaning (intent) set in the template as value of the i18n-attribute.
* This is the part in front of the | symbol.
* e.g. i18n="meaning|mydescription".
* In xmb this is stored in the attribute "meaning".
*/
/**
* The meaning (intent) set in the template as value of the i18n-attribute.
* This is the part in front of the | symbol.
* e.g. i18n="meaning|mydescription".
* In xmb this is stored in the attribute "meaning".
* @return {?}
*/
XmbTransUnit.prototype.meaning = /**
* The meaning (intent) set in the template as value of the i18n-attribute.
* This is the part in front of the | symbol.
* e.g. i18n="meaning|mydescription".
* In xmb this is stored in the attribute "meaning".
* @return {?}
*/
function () {
return this._element.getAttribute('meaning');
};
/**
* Test, wether setting of description and meaning is supported.
* If not, setDescription and setMeaning will do nothing.
* xtb does not support this, all other formats do.
*/
/**
* Test, wether setting of description and meaning is supported.
* If not, setDescription and setMeaning will do nothing.
* xtb does not support this, all other formats do.
* @return {?}
*/
XmbTransUnit.prototype.supportsSetDescriptionAndMeaning = /**
* Test, wether setting of description and meaning is supported.
* If not, setDescription and setMeaning will do nothing.
* xtb does not support this, all other formats do.
* @return {?}
*/
function () {
return false;
};
/**
* Change description property of trans-unit.
* @param description description
*/
/**
* Change description property of trans-unit.
* @param {?} description description
* @return {?}
*/
XmbTransUnit.prototype.setDescription = /**
* Change description property of trans-unit.
* @param {?} description description
* @return {?}
*/
function (description) {
// not supported, do nothing
};
/**
* Change meaning property of trans-unit.
* @param meaning meaning
*/
/**
* Change meaning property of trans-unit.
* @param {?} meaning meaning
* @return {?}
*/
XmbTransUnit.prototype.setMeaning = /**
* Change meaning property of trans-unit.
* @param {?} meaning meaning
* @return {?}
*/
function (meaning) {
// not supported, do nothing
};
/**
* Get all notes of the trans-unit.
* There are NO notes in xmb/xtb
*/
/**
* Get all notes of the trans-unit.
* There are NO notes in xmb/xtb
* @return {?}
*/
XmbTransUnit.prototype.notes = /**
* Get all notes of the trans-unit.
* There are NO notes in xmb/xtb
* @return {?}
*/
function () {
return [];
};
/**
* Test, wether setting of notes is supported.
* If not, setNotes will do nothing.
* xtb does not support this, all other formats do.
*/
/**
* Test, wether setting of notes is supported.
* If not, setNotes will do nothing.
* xtb does not support this, all other formats do.
* @return {?}
*/
XmbTransUnit.prototype.supportsSetNotes = /**
* Test, wether setting of notes is supported.
* If not, setNotes will do nothing.
* xtb does not support this, all other formats do.
* @return {?}
*/
function () {
return false;
};
/**
* Add notes to trans unit.
* @param newNotes the notes to add.
* NOT Supported in xmb/xtb
*/
/**
* Add notes to trans unit.
* @param {?} newNotes the notes to add.
* NOT Supported in xmb/xtb
* @return {?}
*/
XmbTransUnit.prototype.setNotes = /**
* Add notes to trans unit.
* @param {?} newNotes the notes to add.
* NOT Supported in xmb/xtb
* @return {?}
*/
function (newNotes) {
// not supported, do nothing
};
/**
* Copy source to target to use it as dummy translation.
* Returns a changed copy of this trans unit.
* receiver is not changed.
* (internal usage only, a client should call importNewTransUnit on ITranslationMessageFile)
* In xmb there is nothing to do, because there is only a target, no source.
*/
/**
* Copy source to target to use it as dummy translation.
* Returns a changed copy of this trans unit.
* receiver is not changed.
* (internal usage only, a client should call importNewTransUnit on ITranslationMessageFile)
* In xmb there is nothing to do, because there is only a target, no source.
* @param {?} isDefaultLang
* @param {?} copyContent
* @param {?} targetFile
* @return {?}
*/
XmbTransUnit.prototype.cloneWithSourceAsTarget = /**
* Copy source to target to use it as dummy translation.
* Returns a changed copy of this trans unit.
* receiver is not changed.
* (internal usage only, a client should call importNewTransUnit on ITranslationMessageFile)
* In xmb there is nothing to do, because there is only a target, no source.
* @param {?} isDefaultLang
* @param {?} copyContent
* @param {?} targetFile
* @return {?}
*/
function (isDefaultLang, copyContent, targetFile) {
return this;
};
/**
* Copy source to target to use it as dummy translation.
* (internal usage only, a client should call createTranslationFileForLang on ITranslationMessageFile)
*/
/**
* Copy source to target to use it as dummy translation.
* (internal usage only, a client should call createTranslationFileForLang on ITranslationMessageFile)
* @param {?} isDefaultLang
* @param {?} copyContent
* @return {?}
*/
XmbTransUnit.prototype.useSourceAsTarget = /**
* Copy source to target to use it as dummy translation.
* (internal usage only, a client should call createTranslationFileForLang on ITranslationMessageFile)
* @param {?} isDefaultLang
* @param {?} copyContent
* @return {?}
*/
function (isDefaultLang, copyContent) {
// do nothing
};
/**
* Set the translation to a given string (including markup).
* In fact, xmb cannot be translated.
* So this throws an error.
* @param translation translation
*/
/**
* Set the translation to a given string (including markup).
* In fact, xmb cannot be translated.
* So this throws an error.
* @protected
* @param {?} translation translation
* @return {?}
*/
XmbTransUnit.prototype.translateNative = /**
* Set the translation to a given string (including markup).
* In fact, xmb cannot be translated.
* So this throws an error.
* @protected
* @param {?} translation translation
* @return {?}
*/
function (translation) {
throw new Error('You cannot translate xmb files, use xtb instead.');
};
return XmbTransUnit;
}(AbstractTransUnit));
/**
* Created by martin on 01.05.2017.
* A Translation Unit in an XMB file.
*/
export { XmbTransUnit };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1iLXRyYW5zLXVuaXQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Abmd4LWkxOG5zdXBwb3J0L25neC1pMThuc3VwcG9ydC1saWIvIiwic291cmNlcyI6WyJpbXBsL3htYi10cmFucy11bml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBSUEsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHNCQUFzQixDQUFDOzs7OztBQVF0RDs7Ozs7SUFBa0Msd0NBQWlCO0lBRS9DLHNCQUFZLFFBQWlCLEVBQUUsR0FBVyxFQUFFLHdCQUFrRDtlQUMxRixrQkFBTSxRQUFRLEVBQUUsR0FBRyxFQUFFLHdCQUF3QixDQUFDO0lBQ2xELENBQUM7SUFFRDs7OztPQUlHOzs7Ozs7O0lBQ1ksOEJBQWlCOzs7Ozs7SUFBaEMsVUFBaUMsWUFBb0I7O1lBQzNDLEtBQUssR0FBRyxZQUFZLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQztRQUMzQyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUU7WUFDWCxPQUFPO2dCQUNILFVBQVUsRUFBRSxZQUFZO2dCQUN4QixVQUFVLEVBQUUsQ0FBQzthQUNoQixDQUFDO1NBQ0w7YUFBTTtZQUNILE9BQU87Z0JBQ0gsVUFBVSxFQUFFLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQztnQkFDNUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDOUUsQ0FBQztTQUNMO0lBQ0wsQ0FBQzs7Ozs7O0lBRWMsNEJBQWU7Ozs7O0lBQTlCLFVBQStCLGdCQUF3QjtRQUNuRCxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVEOzs7O09BSUc7Ozs7OztJQUNJLG9DQUFhOzs7OztJQUFwQjs7WUFDUSxVQUFVLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDOztZQUNwRCxZQUFZLEdBQVcsdUJBQXVCO1FBQ3BELFVBQVUsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNsRCxPQUFPLFVBQVUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7Ozs7T0FJRzs7Ozs7OztJQUNILCtDQUF3Qjs7Ozs7O0lBQXhCO1FBQ0ksT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7OztPQUtHOzs7Ozs7OztJQUNJLHVDQUFnQjs7Ozs7OztJQUF2QixVQUF3QixVQUFrQjtRQUN0QyxnQkFBZ0I7SUFDcEIsQ0FBQztJQUVEOztPQUVHOzs7Ozs7SUFDTyxvQ0FBYTs7Ozs7SUFBdkI7UUFDSSxPQUFPLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7Ozs7O0lBQ0ksb0RBQTZCOzs7O0lBQXBDO1FBQ0ksT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsOEJBQThCLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRUQ7O09BRUc7Ozs7O0lBQ0ksb0NBQWE7Ozs7SUFBcEI7UUFDSSxzREFBc0Q7UUFDdEQsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7T0FHRzs7Ozs7O0lBQ0gsOENBQXVCOzs7OztJQUF2QjtRQUNJLE9BQU8sSUFBSSxnQkFBZ0IsRUFBRSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUMsQ0FBQztJQUNoSCxDQUFDO0lBRUQ7OztPQUdHOzs7Ozs7SUFDSSx3Q0FBaUI7Ozs7O0lBQXhCO1FBQ0ksT0FBTyxJQUFJLENBQUMsQ0FBQyx1QkFBdUI7SUFDeEMsQ0FBQztJQUVEOzs7Ozs7T0FNRzs7Ozs7Ozs7O0lBQ08sNENBQXFCOzs7Ozs7OztJQUEvQixVQUFnQyxLQUFhO1FBQ3pDLE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7OztPQUlHOzs7Ozs7OztJQUNPLDRDQUFxQjs7Ozs7OztJQUEvQixVQUFnQyxXQUFtQjtRQUMvQyxPQUFPLFdBQVcsQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7T0FJRzs7Ozs7Ozs7SUFDTywyQ0FBb0I7Ozs7Ozs7SUFBOUIsVUFBK0IsV0FBbUI7UUFDOUMsd0JBQXdCO0lBQzVCLENBQUM7SUFFRDs7Ozs7OztPQU9HOzs7Ozs7Ozs7O0lBQ0ksdUNBQWdCOzs7Ozs7Ozs7SUFBdkI7O1lBQ1UsY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDOztZQUM3RCxVQUFVLEdBQWlELEVBQUU7UUFDbkUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7O2dCQUN0QyxJQUFJLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7O2dCQUM3QixZQUFZLEdBQVcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUM7WUFDekQsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztTQUNqRTtRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFFRDs7Ozs7T0FLRzs7Ozs7Ozs7SUFDSSwwQ0FBbUI7Ozs7Ozs7SUFBMUIsVUFBMkIsVUFBc0Q7UUFDN0UsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7O1lBQzdCLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3JELEtBQUssSUFBSSxDQUFDLEdBQUcsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTs7Z0JBQ3ZDLEdBQUcsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDOztnQkFDbkIsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUM7WUFDbEUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25ILElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztZQUNuRCxjQUFjLEdBQUcsTUFBTSxDQUFDO1NBQzNCO0lBQ0wsQ0FBQzs7Ozs7SUFFTyxnREFBeUI7Ozs7SUFBakM7O1lBQ1UsY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDOztZQUM3RCxXQUFXLEdBQUcsRUFBRTtRQUN0QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTs7Z0JBQ3RDLElBQUksR0FBRyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzFCO1FBQ0QsV0FBVyxDQUFDLE9BQU87Ozs7UUFBQyxVQUFDLElBQUksSUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRDs7OztPQUlHOzs7Ozs7O0lBQ0ksa0NBQVc7Ozs7OztJQUFsQjtRQUNJLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7OztPQUtHOzs7Ozs7OztJQUNJLDhCQUFPOzs7Ozs7O0lBQWQ7UUFDSSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRDs7OztPQUlHOzs7Ozs7O0lBQ0ksdURBQWdDOzs7Ozs7SUFBdkM7UUFDSSxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQ7OztPQUdHOzs7Ozs7SUFDSSxxQ0FBYzs7Ozs7SUFBckIsVUFBc0IsV0FBbUI7UUFDckMsNEJBQTRCO0lBQ2hDLENBQUM7SUFFRDs7O09BR0c7Ozs7OztJQUNJLGlDQUFVOzs7OztJQUFqQixVQUFrQixPQUFlO1FBQzdCLDRCQUE0QjtJQUNoQyxDQUFDO0lBRUQ7OztPQUdHOzs7Ozs7SUFDSSw0QkFBSzs7Ozs7SUFBWjtRQUNJLE9BQU8sRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7O09BSUc7Ozs7Ozs7SUFDSSx1Q0FBZ0I7Ozs7OztJQUF2QjtRQUNJLE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7OztPQUlHOzs7Ozs7O0lBQ0ksK0JBQVE7Ozs7OztJQUFmLFVBQWdCLFFBQWlCO1FBQzdCLDRCQUE0QjtJQUNoQyxDQUFDO0lBRUQ7Ozs7OztPQU1HOzs7Ozs7Ozs7Ozs7SUFDSSw4Q0FBdUI7Ozs7Ozs7Ozs7O0lBQTlCLFVBQStCLGFBQXNCLEVBQUUsV0FBb0IsRUFBRSxVQUFvQztRQUM3RyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQ7OztPQUdHOzs7Ozs7OztJQUNJLHdDQUFpQjs7Ozs7OztJQUF4QixVQUF5QixhQUFzQixFQUFFLFdBQW9CO1FBQ2pFLGFBQWE7SUFDakIsQ0FBQztJQUVEOzs7OztPQUtHOzs7Ozs7Ozs7SUFDTyxzQ0FBZTs7Ozs7Ozs7SUFBekIsVUFBMEIsV0FBbUI7UUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFTCxtQkFBQztBQUFELENBQUMsQUFsUkQsQ0FBa0MsaUJBQWlCLEdBa1JsRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SVRyYW5zbGF0aW9uTWVzc2FnZXNGaWxlfSBmcm9tICcuLi9hcGkvaS10cmFuc2xhdGlvbi1tZXNzYWdlcy1maWxlJztcclxuaW1wb3J0IHtJTm9ybWFsaXplZE1lc3NhZ2V9IGZyb20gJy4uL2FwaS9pLW5vcm1hbGl6ZWQtbWVzc2FnZSc7XHJcbmltcG9ydCB7SVRyYW5zVW5pdH0gZnJvbSAnLi4vYXBpL2ktdHJhbnMtdW5pdCc7XHJcbmltcG9ydCB7SU5vdGV9IGZyb20gJy4uL2FwaS9pLW5vdGUnO1xyXG5pbXBvcnQge0RPTVV0aWxpdGllc30gZnJvbSAnLi9kb20tdXRpbGl0aWVzJztcclxuaW1wb3J0IHtBYnN0cmFjdFRyYW5zVW5pdH0gZnJvbSAnLi9hYnN0cmFjdC10cmFucy11bml0JztcclxuaW1wb3J0IHtYbWJNZXNzYWdlUGFyc2VyfSBmcm9tICcuL3htYi1tZXNzYWdlLXBhcnNlcic7XHJcbmltcG9ydCB7UGFyc2VkTWVzc2FnZX0gZnJvbSAnLi9wYXJzZWQtbWVzc2FnZSc7XHJcbmltcG9ydCB7QWJzdHJhY3RNZXNzYWdlUGFyc2VyfSBmcm9tICcuL2Fic3RyYWN0LW1lc3NhZ2UtcGFyc2VyJztcclxuLyoqXHJcbiAqIENyZWF0ZWQgYnkgbWFydGluIG9uIDAxLjA1LjIwMTcuXHJcbiAqIEEgVHJhbnNsYXRpb24gVW5pdCBpbiBhbiBYTUIgZmlsZS5cclxuICovXHJcblxyXG5leHBvcnQgY2xhc3MgWG1iVHJhbnNVbml0IGV4dGVuZHMgQWJzdHJhY3RUcmFuc1VuaXQgaW1wbGVtZW50cyBJVHJhbnNVbml0IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihfZWxlbWVudDogRWxlbWVudCwgX2lkOiBzdHJpbmcsIF90cmFuc2xhdGlvbk1lc3NhZ2VzRmlsZTogSVRyYW5zbGF0aW9uTWVzc2FnZXNGaWxlKSB7XHJcbiAgICAgICAgc3VwZXIoX2VsZW1lbnQsIF9pZCwgX3RyYW5zbGF0aW9uTWVzc2FnZXNGaWxlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnNlcyBzb21ldGhpbmcgbGlrZSAnYzpcXHh4eDo3JyBhbmQgcmV0dXJucyBzb3VyY2UgYW5kIGxpbmVudW1iZXIuXHJcbiAgICAgKiBAcGFyYW0gc291cmNlQW5kUG9zIHNvbWV0aGluZyBsaWtlICdjOlxceHh4OjcnLCBsYXN0IGNvbG9uIGlzIHRoZSBzZXBhcmF0b3JcclxuICAgICAqIEByZXR1cm4gc291cmNlIGFuZCBsaW5lbnVtYmVyXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIHBhcnNlU291cmNlQW5kUG9zKHNvdXJjZUFuZFBvczogc3RyaW5nKTogeyBzb3VyY2VmaWxlOiBzdHJpbmcsIGxpbmVudW1iZXIgfSB7XHJcbiAgICAgICAgY29uc3QgaW5kZXggPSBzb3VyY2VBbmRQb3MubGFzdEluZGV4T2YoJzonKTtcclxuICAgICAgICBpZiAoaW5kZXggPCAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBzb3VyY2VmaWxlOiBzb3VyY2VBbmRQb3MsXHJcbiAgICAgICAgICAgICAgICBsaW5lbnVtYmVyOiAwXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZWZpbGU6IHNvdXJjZUFuZFBvcy5zdWJzdHJpbmcoMCwgaW5kZXgpLFxyXG4gICAgICAgICAgICAgICAgbGluZW51bWJlcjogWG1iVHJhbnNVbml0LnBhcnNlTGluZU51bWJlcihzb3VyY2VBbmRQb3Muc3Vic3RyaW5nKGluZGV4ICsgMSkpXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIHBhcnNlTGluZU51bWJlcihsaW5lTnVtYmVyU3RyaW5nOiBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBOdW1iZXIucGFyc2VJbnQobGluZU51bWJlclN0cmluZywgMTApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IGNvbnRlbnQgdG8gdHJhbnNsYXRlLlxyXG4gICAgICogU291cmNlIHBhcnRzIGFyZSBleGNsdWRlZCBoZXJlLlxyXG4gICAgICogQHJldHVybiBzb3VyY2UgY29udGVudFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc291cmNlQ29udGVudCgpOiBzdHJpbmcge1xyXG4gICAgICAgIGxldCBtc2dDb250ZW50ID0gRE9NVXRpbGl0aWVzLmdldFhNTENvbnRlbnQodGhpcy5fZWxlbWVudCk7XHJcbiAgICAgICAgY29uc3QgcmVTb3VyY2VFbGVtOiBSZWdFeHAgPSAvPHNvdXJjZT4uKjxcXC9zb3VyY2U+L2c7XHJcbiAgICAgICAgbXNnQ29udGVudCA9IG1zZ0NvbnRlbnQucmVwbGFjZShyZVNvdXJjZUVsZW0sICcnKTtcclxuICAgICAgICByZXR1cm4gbXNnQ29udGVudDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3QsIHdldGhlciBzZXR0aW5nIG9mIHNvdXJjZSBjb250ZW50IGlzIHN1cHBvcnRlZC5cclxuICAgICAqIElmIG5vdCwgc2V0U291cmNlQ29udGVudCBpbiB0cmFucy11bml0IHdpbGwgZG8gbm90aGluZy5cclxuICAgICAqIHh0YiBkb2VzIG5vdCBzdXBwb3J0IHRoaXMsIGFsbCBvdGhlciBmb3JtYXRzIGRvLlxyXG4gICAgICovXHJcbiAgICBzdXBwb3J0c1NldFNvdXJjZUNvbnRlbnQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2V0IG5ldyBzb3VyY2UgY29udGVudCBpbiB0aGUgdHJhbnN1bml0LlxyXG4gICAgICogTm9ybWFsbHksIHRoaXMgaXMgZG9uZSBieSBuZy1leHRyYWN0LlxyXG4gICAgICogTWV0aG9kIG9ubHkgZXhpc3RzIHRvIGFsbG93IHhsaWZmbWVyZ2UgdG8gbWVyZ2UgbWlzc2luZyBjaGFuZ2VkIHNvdXJjZSBjb250ZW50LlxyXG4gICAgICogQHBhcmFtIG5ld0NvbnRlbnQgdGhlIG5ldyBjb250ZW50LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0U291cmNlQ29udGVudChuZXdDb250ZW50OiBzdHJpbmcpIHtcclxuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm4gYSBwYXJzZXIgdXNlZCBmb3Igbm9ybWFsaXplZCBtZXNzYWdlcy5cclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIG1lc3NhZ2VQYXJzZXIoKTogQWJzdHJhY3RNZXNzYWdlUGFyc2VyIHtcclxuICAgICAgICByZXR1cm4gbmV3IFhtYk1lc3NhZ2VQYXJzZXIoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBvcmlnaW5hbCB0ZXh0IHZhbHVlLCB0aGF0IGlzIHRvIGJlIHRyYW5zbGF0ZWQsIGFzIG5vcm1hbGl6ZWQgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZVNvdXJjZUNvbnRlbnROb3JtYWxpemVkKCk6IFBhcnNlZE1lc3NhZ2Uge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2VQYXJzZXIoKS5jcmVhdGVOb3JtYWxpemVkTWVzc2FnZUZyb21YTUwodGhpcy5fZWxlbWVudCwgbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0aGUgdHJhbnNsYXRlZCB2YWx1ZSAoY29udGFpbmluZyBhbGwgbWFya3VwLCBkZXBlbmRzIG9uIHRoZSBjb25jcmV0ZSBmb3JtYXQgdXNlZCkuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB0YXJnZXRDb250ZW50KCk6IHN0cmluZyB7XHJcbiAgICAgICAgLy8gaW4gZmFjdCwgdGFyZ2V0IGFuZCBzb3VyY2UgYXJlIGp1c3QgdGhlIHNhbWUgaW4geG1iXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc291cmNlQ29udGVudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogdGhlIHRyYW5zbGF0ZWQgdmFsdWUsIGJ1dCBhbGwgcGxhY2Vob2xkZXJzIGFyZSByZXBsYWNlZCB3aXRoIHt7bn19IChzdGFydGluZyBhdCAwKVxyXG4gICAgICogYW5kIGFsbCBlbWJlZGRlZCBodG1sIGlzIHJlcGxhY2VkIGJ5IGRpcmVjdCBodG1sIG1hcmt1cC5cclxuICAgICAqL1xyXG4gICAgdGFyZ2V0Q29udGVudE5vcm1hbGl6ZWQoKTogSU5vcm1hbGl6ZWRNZXNzYWdlIHtcclxuICAgICAgICByZXR1cm4gbmV3IFhtYk1lc3NhZ2VQYXJzZXIoKS5jcmVhdGVOb3JtYWxpemVkTWVzc2FnZUZyb21YTUwodGhpcy5fZWxlbWVudCwgdGhpcy5zb3VyY2VDb250ZW50Tm9ybWFsaXplZCgpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0YXRlIG9mIHRoZSB0cmFuc2xhdGlvbi5cclxuICAgICAqIChub3Qgc3VwcG9ydGVkIGluIHhtYilcclxuICAgICAqL1xyXG4gICAgcHVibGljIG5hdGl2ZVRhcmdldFN0YXRlKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7IC8vIG5vdCBzdXBwb3J0ZWQgaW4geG1iXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXAgYW4gYWJzdHJhY3Qgc3RhdGUgKG5ldywgdHJhbnNsYXRlZCwgZmluYWwpIHRvIGEgY29uY3JldGUgc3RhdGUgdXNlZCBpbiB0aGUgeG1sLlxyXG4gICAgICogUmV0dXJucyB0aGUgc3RhdGUgdG8gYmUgdXNlZCBpbiB0aGUgeG1sLlxyXG4gICAgICogQHBhcmFtIHN0YXRlIG9uZSBvZiBDb25zdGFudHMuU1RBVEUuLi5cclxuICAgICAqIEByZXR1cm5zIGEgbmF0aXZlIHN0YXRlIChkZXBlbmRzIG9uIGNvbmNyZXRlIGZvcm1hdClcclxuICAgICAqIEB0aHJvd3MgZXJyb3IsIGlmIHN0YXRlIGlzIGludmFsaWQuXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBtYXBTdGF0ZVRvTmF0aXZlU3RhdGUoc3RhdGU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFwIGEgbmF0aXZlIHN0YXRlIChmb3VuZCBpbiB0aGUgZG9jdW1lbnQpIHRvIGFuIGFic3RyYWN0IHN0YXRlIChuZXcsIHRyYW5zbGF0ZWQsIGZpbmFsKS5cclxuICAgICAqIFJldHVybnMgdGhlIGFic3RyYWN0IHN0YXRlLlxyXG4gICAgICogQHBhcmFtIG5hdGl2ZVN0YXRlIG5hdGl2ZVN0YXRlXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBtYXBOYXRpdmVTdGF0ZVRvU3RhdGUobmF0aXZlU3RhdGU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogc2V0IHN0YXRlIGluIHhtbC5cclxuICAgICAqIChub3Qgc3VwcG9ydGVkIGluIHhtYilcclxuICAgICAqIEBwYXJhbSBuYXRpdmVTdGF0ZSBuYXRpdmVTdGF0ZVxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgc2V0TmF0aXZlVGFyZ2V0U3RhdGUobmF0aXZlU3RhdGU6IHN0cmluZykge1xyXG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgZm9yIHhtYlxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWxsIHRoZSBzb3VyY2UgZWxlbWVudHMgaW4gdGhlIHRyYW5zIHVuaXQuXHJcbiAgICAgKiBUaGUgc291cmNlIGVsZW1lbnQgaXMgYSByZWZlcmVuY2UgdG8gdGhlIG9yaWdpbmFsIHRlbXBsYXRlLlxyXG4gICAgICogSXQgY29udGFpbnMgdGhlIG5hbWUgb2YgdGhlIHRlbXBsYXRlIGZpbGUgYW5kIGEgbGluZSBudW1iZXIgd2l0aCB0aGUgcG9zaXRpb24gaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cclxuICAgICAqIEl0IGlzIGp1c3QgYSBoZWxwIGZvciB0cmFuc2xhdG9ycyB0byBmaW5kIHRoZSBjb250ZXh0IGZvciB0aGUgdHJhbnNsYXRpb24uXHJcbiAgICAgKiBUaGlzIGlzIHNldCB3aGVuIHVzaW5nIEFuZ3VsYXIgNC4wIG9yIGdyZWF0ZXIuXHJcbiAgICAgKiBPdGhlcndpc2UgaXQganVzdCByZXR1cm5zIGFuIGVtcHR5IGFycmF5LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc291cmNlUmVmZXJlbmNlcygpOiB7IHNvdXJjZWZpbGU6IHN0cmluZywgbGluZW51bWJlcjogbnVtYmVyIH1bXSB7XHJcbiAgICAgICAgY29uc3Qgc291cmNlRWxlbWVudHMgPSB0aGlzLl9lbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzb3VyY2UnKTtcclxuICAgICAgICBjb25zdCBzb3VyY2VSZWZzOiB7IHNvdXJjZWZpbGU6IHN0cmluZywgbGluZW51bWJlcjogbnVtYmVyIH1bXSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc291cmNlRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgZWxlbSA9IHNvdXJjZUVsZW1lbnRzLml0ZW0oaSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUFuZFBvczogc3RyaW5nID0gRE9NVXRpbGl0aWVzLmdldFBDREFUQShlbGVtKTtcclxuICAgICAgICAgICAgc291cmNlUmVmcy5wdXNoKFhtYlRyYW5zVW5pdC5wYXJzZVNvdXJjZUFuZFBvcyhzb3VyY2VBbmRQb3MpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNvdXJjZVJlZnM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgc291cmNlIHJlZiBlbGVtZW50cyBpbiB0aGUgdHJhbnN1bml0LlxyXG4gICAgICogTm9ybWFsbHksIHRoaXMgaXMgZG9uZSBieSBuZy1leHRyYWN0LlxyXG4gICAgICogTWV0aG9kIG9ubHkgZXhpc3RzIHRvIGFsbG93IHhsaWZmbWVyZ2UgdG8gbWVyZ2UgbWlzc2luZyBzb3VyY2UgcmVmcy5cclxuICAgICAqIEBwYXJhbSBzb3VyY2VSZWZzIHRoZSBzb3VyY2VyZWZzIHRvIHNldC4gT2xkIG9uZXMgYXJlIHJlbW92ZWQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRTb3VyY2VSZWZlcmVuY2VzKHNvdXJjZVJlZnM6IHtzb3VyY2VmaWxlOiBzdHJpbmcsIGxpbmVudW1iZXI6IG51bWJlcn1bXSkge1xyXG4gICAgICAgIHRoaXMucmVtb3ZlQWxsU291cmNlUmVmZXJlbmNlcygpO1xyXG4gICAgICAgIGxldCBpbnNlcnRQb3NpdGlvbiA9IHRoaXMuX2VsZW1lbnQuY2hpbGROb2Rlcy5pdGVtKDApO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSBzb3VyY2VSZWZzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlZiA9IHNvdXJjZVJlZnNbaV07XHJcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHRoaXMuX2VsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzb3VyY2UnKTtcclxuICAgICAgICAgICAgc291cmNlLmFwcGVuZENoaWxkKHRoaXMuX2VsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShyZWYuc291cmNlZmlsZSArICc6JyArIHJlZi5saW5lbnVtYmVyLnRvU3RyaW5nKDEwKSkpO1xyXG4gICAgICAgICAgICB0aGlzLl9lbGVtZW50Lmluc2VydEJlZm9yZShzb3VyY2UsIGluc2VydFBvc2l0aW9uKTtcclxuICAgICAgICAgICAgaW5zZXJ0UG9zaXRpb24gPSBzb3VyY2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgcmVtb3ZlQWxsU291cmNlUmVmZXJlbmNlcygpIHtcclxuICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50cyA9IHRoaXMuX2VsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NvdXJjZScpO1xyXG4gICAgICAgIGNvbnN0IHRvQmVSZW1vdmVkID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2VFbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBlbGVtID0gc291cmNlRWxlbWVudHMuaXRlbShpKTtcclxuICAgICAgICAgICAgdG9CZVJlbW92ZWQucHVzaChlbGVtKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdG9CZVJlbW92ZWQuZm9yRWFjaCgoZWxlbSkgPT4ge2VsZW0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtKTsgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZGVzY3JpcHRpb24gc2V0IGluIHRoZSB0ZW1wbGF0ZSBhcyB2YWx1ZSBvZiB0aGUgaTE4bi1hdHRyaWJ1dGUuXHJcbiAgICAgKiBlLmcuIGkxOG49XCJteWRlc2NyaXB0aW9uXCIuXHJcbiAgICAgKiBJbiB4bWIgdGhpcyBpcyBzdG9yZWQgaW4gdGhlIGF0dHJpYnV0ZSBcImRlc2NcIi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGRlc2NyaXB0aW9uKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQuZ2V0QXR0cmlidXRlKCdkZXNjJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbWVhbmluZyAoaW50ZW50KSBzZXQgaW4gdGhlIHRlbXBsYXRlIGFzIHZhbHVlIG9mIHRoZSBpMThuLWF0dHJpYnV0ZS5cclxuICAgICAqIFRoaXMgaXMgdGhlIHBhcnQgaW4gZnJvbnQgb2YgdGhlIHwgc3ltYm9sLlxyXG4gICAgICogZS5nLiBpMThuPVwibWVhbmluZ3xteWRlc2NyaXB0aW9uXCIuXHJcbiAgICAgKiBJbiB4bWIgdGhpcyBpcyBzdG9yZWQgaW4gdGhlIGF0dHJpYnV0ZSBcIm1lYW5pbmdcIi5cclxuICAgICAqL1xyXG4gICAgcHVibGljIG1lYW5pbmcoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ21lYW5pbmcnKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3QsIHdldGhlciBzZXR0aW5nIG9mIGRlc2NyaXB0aW9uIGFuZCBtZWFuaW5nIGlzIHN1cHBvcnRlZC5cclxuICAgICAqIElmIG5vdCwgc2V0RGVzY3JpcHRpb24gYW5kIHNldE1lYW5pbmcgd2lsbCBkbyBub3RoaW5nLlxyXG4gICAgICogeHRiIGRvZXMgbm90IHN1cHBvcnQgdGhpcywgYWxsIG90aGVyIGZvcm1hdHMgZG8uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdXBwb3J0c1NldERlc2NyaXB0aW9uQW5kTWVhbmluZygpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGFuZ2UgZGVzY3JpcHRpb24gcHJvcGVydHkgb2YgdHJhbnMtdW5pdC5cclxuICAgICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBkZXNjcmlwdGlvblxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0RGVzY3JpcHRpb24oZGVzY3JpcHRpb246IHN0cmluZykge1xyXG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQsIGRvIG5vdGhpbmdcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoYW5nZSBtZWFuaW5nIHByb3BlcnR5IG9mIHRyYW5zLXVuaXQuXHJcbiAgICAgKiBAcGFyYW0gbWVhbmluZyBtZWFuaW5nXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXRNZWFuaW5nKG1lYW5pbmc6IHN0cmluZykge1xyXG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQsIGRvIG5vdGhpbmdcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCBhbGwgbm90ZXMgb2YgdGhlIHRyYW5zLXVuaXQuXHJcbiAgICAgKiBUaGVyZSBhcmUgTk8gbm90ZXMgaW4geG1iL3h0YlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbm90ZXMoKTogSU5vdGVbXSB7XHJcbiAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdCwgd2V0aGVyIHNldHRpbmcgb2Ygbm90ZXMgaXMgc3VwcG9ydGVkLlxyXG4gICAgICogSWYgbm90LCBzZXROb3RlcyB3aWxsIGRvIG5vdGhpbmcuXHJcbiAgICAgKiB4dGIgZG9lcyBub3Qgc3VwcG9ydCB0aGlzLCBhbGwgb3RoZXIgZm9ybWF0cyBkby5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN1cHBvcnRzU2V0Tm90ZXMoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkIG5vdGVzIHRvIHRyYW5zIHVuaXQuXHJcbiAgICAgKiBAcGFyYW0gbmV3Tm90ZXMgdGhlIG5vdGVzIHRvIGFkZC5cclxuICAgICAqIE5PVCBTdXBwb3J0ZWQgaW4geG1iL3h0YlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2V0Tm90ZXMobmV3Tm90ZXM6IElOb3RlW10pIHtcclxuICAgICAgICAvLyBub3Qgc3VwcG9ydGVkLCBkbyBub3RoaW5nXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb3B5IHNvdXJjZSB0byB0YXJnZXQgdG8gdXNlIGl0IGFzIGR1bW15IHRyYW5zbGF0aW9uLlxyXG4gICAgICogUmV0dXJucyBhIGNoYW5nZWQgY29weSBvZiB0aGlzIHRyYW5zIHVuaXQuXHJcbiAgICAgKiByZWNlaXZlciBpcyBub3QgY2hhbmdlZC5cclxuICAgICAqIChpbnRlcm5hbCB1c2FnZSBvbmx5LCBhIGNsaWVudCBzaG91bGQgY2FsbCBpbXBvcnROZXdUcmFuc1VuaXQgb24gSVRyYW5zbGF0aW9uTWVzc2FnZUZpbGUpXHJcbiAgICAgKiBJbiB4bWIgdGhlcmUgaXMgbm90aGluZyB0byBkbywgYmVjYXVzZSB0aGVyZSBpcyBvbmx5IGEgdGFyZ2V0LCBubyBzb3VyY2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjbG9uZVdpdGhTb3VyY2VBc1RhcmdldChpc0RlZmF1bHRMYW5nOiBib29sZWFuLCBjb3B5Q29udGVudDogYm9vbGVhbiwgdGFyZ2V0RmlsZTogSVRyYW5zbGF0aW9uTWVzc2FnZXNGaWxlKTogQWJzdHJhY3RUcmFuc1VuaXQge1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29weSBzb3VyY2UgdG8gdGFyZ2V0IHRvIHVzZSBpdCBhcyBkdW1teSB0cmFuc2xhdGlvbi5cclxuICAgICAqIChpbnRlcm5hbCB1c2FnZSBvbmx5LCBhIGNsaWVudCBzaG91bGQgY2FsbCBjcmVhdGVUcmFuc2xhdGlvbkZpbGVGb3JMYW5nIG9uIElUcmFuc2xhdGlvbk1lc3NhZ2VGaWxlKVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdXNlU291cmNlQXNUYXJnZXQoaXNEZWZhdWx0TGFuZzogYm9vbGVhbiwgY29weUNvbnRlbnQ6IGJvb2xlYW4pIHtcclxuICAgICAgICAvLyBkbyBub3RoaW5nXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhlIHRyYW5zbGF0aW9uIHRvIGEgZ2l2ZW4gc3RyaW5nIChpbmNsdWRpbmcgbWFya3VwKS5cclxuICAgICAqIEluIGZhY3QsIHhtYiBjYW5ub3QgYmUgdHJhbnNsYXRlZC5cclxuICAgICAqIFNvIHRoaXMgdGhyb3dzIGFuIGVycm9yLlxyXG4gICAgICogQHBhcmFtIHRyYW5zbGF0aW9uIHRyYW5zbGF0aW9uXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCB0cmFuc2xhdGVOYXRpdmUodHJhbnNsYXRpb246IHN0cmluZykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGNhbm5vdCB0cmFuc2xhdGUgeG1iIGZpbGVzLCB1c2UgeHRiIGluc3RlYWQuJyk7XHJcbiAgICB9XHJcblxyXG59XHJcbiJdfQ==