ngrx-forms
Version:
Proper integration of forms in Angular 4 applications using ngrx
217 lines • 63.7 kB
JavaScript
import { isBoxed } from './boxing';
import { deepEquals, isEmpty } from './util';
/**
* This function determines if a value is a form state.
*/
export function isFormState(state) {
return !!state && state.hasOwnProperty('id') && state.hasOwnProperty('value') && state.hasOwnProperty('errors');
}
/**
* This function determines if a value is an array state.
*/
export function isArrayState(state) {
return isFormState(state) && state.hasOwnProperty('controls') && Array.isArray(state.controls);
}
/**
* This function determines if a value is a group state.
*/
export function isGroupState(state) {
return isFormState(state) && state.hasOwnProperty('controls') && !Array.isArray(state.controls) && typeof state.controls !== 'function';
}
export function createChildState(id, childValue) {
if (isBoxed(childValue)) {
return createFormControlState(id, childValue);
}
if (childValue !== null && Array.isArray(childValue)) {
return createFormArrayState(id, childValue);
}
if (childValue !== null && typeof childValue === 'object') {
return createFormGroupState(id, childValue);
}
return createFormControlState(id, childValue);
}
export function verifyFormControlValueIsValid(value) {
if (value === null || ['string', 'number', 'boolean', 'undefined'].indexOf(typeof value) >= 0) {
return value;
}
if (!isBoxed(value)) {
const errorMsg = 'Form control states only support undefined, null, string, number, and boolean values as well as boxed values';
throw new Error(`${errorMsg}; got ${JSON.stringify(value)} of type ${typeof value}`); // `;
}
if (value.value === null || ['string', 'number', 'boolean', 'undefined'].indexOf(typeof value.value) >= 0) {
return value;
}
const serialized = JSON.stringify(value);
const deserialized = JSON.parse(serialized);
if (deepEquals(value, deserialized, { treatUndefinedAndMissingKeyAsSame: true })) {
return value;
}
throw new Error(`A form control value must be serializable (i.e. value === JSON.parse(JSON.stringify(value))), got: ${JSON.stringify(value)}`);
}
/**
* This function creates a form control state with an ID and a value.
*/
export function createFormControlState(id, value) {
return {
id,
value: verifyFormControlValueIsValid(value),
errors: {},
pendingValidations: [],
isValidationPending: false,
isValid: true,
isInvalid: false,
isEnabled: true,
isDisabled: false,
isDirty: false,
isPristine: true,
isTouched: false,
isUntouched: true,
isSubmitted: false,
isUnsubmitted: true,
isFocused: false,
isUnfocused: true,
userDefinedProperties: {},
};
}
export function getFormGroupValue(controls, originalValue) {
let hasChanged = Object.keys(originalValue).length !== Object.keys(controls).length;
const newValue = Object.keys(controls).reduce((res, key) => {
const control = controls[key];
hasChanged = hasChanged || originalValue[key] !== control.value;
res[key] = control.value;
return res;
}, {});
return hasChanged ? newValue : originalValue;
}
export function getFormGroupErrors(controls, originalErrors) {
let hasChanged = false;
const groupErrors = Object.keys(originalErrors)
.filter(key => !key.startsWith('_'))
.reduce((res, key) => Object.assign(res, { [key]: originalErrors[key] }), {});
const newErrors = Object.keys(controls).reduce((res, key) => {
const control = controls[key];
const controlErrors = control.errors;
if (!isEmpty(controlErrors)) {
hasChanged = hasChanged || originalErrors[`_${key}`] !== controlErrors;
Object.assign(res, { [`_${key}`]: control.errors });
}
else {
hasChanged = hasChanged || originalErrors.hasOwnProperty(`_${key}`);
}
return res;
}, groupErrors);
hasChanged = hasChanged || Object.keys(originalErrors).length !== Object.keys(newErrors).length;
return hasChanged ? newErrors : originalErrors;
}
export function computeGroupState(id, controls, value, errors, pendingValidations, userDefinedProperties, flags) {
value = getFormGroupValue(controls, value);
errors = getFormGroupErrors(controls, errors);
const isValid = isEmpty(errors);
const isDirty = flags.wasOrShouldBeDirty || Object.keys(controls).some(key => controls[key].isDirty);
const isEnabled = flags.wasOrShouldBeEnabled || Object.keys(controls).some(key => controls[key].isEnabled);
const isTouched = flags.wasOrShouldBeTouched || Object.keys(controls).some(key => controls[key].isTouched);
const isSubmitted = flags.wasOrShouldBeSubmitted || Object.keys(controls).some(key => controls[key].isSubmitted);
const isValidationPending = pendingValidations.length > 0 || Object.keys(controls).some(key => controls[key].isValidationPending);
return {
id,
value,
errors,
pendingValidations,
isValidationPending,
isValid,
isInvalid: !isValid,
isEnabled,
isDisabled: !isEnabled,
isDirty,
isPristine: !isDirty,
isTouched,
isUntouched: !isTouched,
isSubmitted,
isUnsubmitted: !isSubmitted,
userDefinedProperties,
controls,
};
}
/**
* This function creates a form group state with an ID and a value.
* From the value the shape of the group state is inferred, i.e.
* object properties are inferred as form groups, array properties
* are inferred as form arrays, and primitive properties are inferred
* as form controls.
*/
export function createFormGroupState(id, initialValue) {
const controls = Object.keys(initialValue)
.map((key) => [key, createChildState(`${id}.${key}`, initialValue[key])])
.reduce((res, [controlId, state]) => Object.assign(res, { [controlId]: state }), {});
return computeGroupState(id, controls, initialValue, {}, [], {}, { wasOrShouldBeEnabled: true });
}
function getFormArrayValue(controls, originalValue) {
let hasChanged = Object.keys(originalValue).length !== Object.keys(controls).length;
const newValue = controls.map((state, i) => {
hasChanged = hasChanged || originalValue[i] !== state.value;
return state.value;
});
return hasChanged ? newValue : originalValue;
}
function getFormArrayErrors(controls, originalErrors) {
let hasChanged = false;
const groupErrors = Object.keys(originalErrors)
.filter(key => !key.startsWith('_'))
.reduce((res, key) => Object.assign(res, { [key]: originalErrors[key] }), {});
const newErrors = controls.reduce((res, state, i) => {
const controlErrors = state.errors;
if (!isEmpty(controlErrors)) {
hasChanged = hasChanged || originalErrors[`_${i}`] !== controlErrors;
Object.assign(res, { [`_${i}`]: controlErrors });
}
else {
hasChanged = hasChanged || originalErrors.hasOwnProperty(`_${i}`);
}
return res;
}, groupErrors);
hasChanged = hasChanged || Object.keys(originalErrors).length !== Object.keys(newErrors).length;
return hasChanged ? newErrors : originalErrors;
}
export function computeArrayState(id, inferredControls, value, errors, pendingValidations, userDefinedProperties, flags) {
const controls = inferredControls;
value = getFormArrayValue(controls, value);
errors = getFormArrayErrors(controls, errors);
const isValid = isEmpty(errors);
const isDirty = flags.wasOrShouldBeDirty || controls.some(state => state.isDirty);
const isEnabled = flags.wasOrShouldBeEnabled || controls.some(state => state.isEnabled);
const isTouched = flags.wasOrShouldBeTouched || controls.some(state => state.isTouched);
const isSubmitted = flags.wasOrShouldBeSubmitted || controls.some(state => state.isSubmitted);
const isValidationPending = pendingValidations.length > 0 || controls.some(state => state.isValidationPending);
return {
id,
value,
errors,
pendingValidations,
isValidationPending,
isValid,
isInvalid: !isValid,
isEnabled,
isDisabled: !isEnabled,
isDirty,
isPristine: !isDirty,
isTouched,
isUntouched: !isTouched,
isSubmitted,
isUnsubmitted: !isSubmitted,
userDefinedProperties,
controls: inferredControls,
};
}
/**
* This function creates a form array state with an ID and a value.
* From the value the shape of the array state is inferred, i.e.
* object values are inferred as form groups, array values
* are inferred as form arrays, and primitive values are inferred
* as form controls.
*/
export function createFormArrayState(id, initialValue) {
const controls = initialValue
.map((value, i) => createChildState(`${id}.${i}`, value));
return computeArrayState(id, controls, initialValue, {}, [], {}, { wasOrShouldBeEnabled: true });
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFTLE9BQU8sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMxQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLFFBQVEsQ0FBQztBQTZrQjdDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBZSxLQUFVO0lBQ2xELE9BQU8sQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNsSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFlLEtBQVU7SUFDbkQsT0FBTyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFFLEtBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUMxRyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUFnQyxLQUFVO0lBQ3BFLE9BQU8sV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFFLEtBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSSxPQUFRLEtBQWEsQ0FBQyxRQUFRLEtBQUssVUFBVSxDQUFDO0FBQzVKLENBQUM7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQVMsRUFBVSxFQUFFLFVBQWtCO0lBQ3JFLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1FBQ3ZCLE9BQU8sc0JBQXNCLENBQU0sRUFBRSxFQUFFLFVBQVUsQ0FBc0IsQ0FBQztLQUN6RTtJ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QUFXLENBQUMsQ0FBQztJQUM5RixNQUFNLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQy9HLE9BQU87UUFDTCxFQUFFO1FBQ0YsS0FBSztRQUNMLE1BQU07UUFDTixrQkFBa0I7UUFDbEIsbUJBQW1CO1FBQ25CLE9BQU87UUFDUCxTQUFTLEVBQUUsQ0FBQyxPQUFPO1FBQ25CLFNBQVM7UUFDVCxVQUFVLEVBQUUsQ0FBQyxTQUFTO1FBQ3RCLE9BQU87UUFDUCxVQUFVLEVBQUUsQ0FBQyxPQUFPO1FBQ3BCLFNBQVM7UUFDVCxXQUFXLEVBQUUsQ0FBQyxTQUFTO1FBQ3ZCLFdBQVc7UUFDWCxhQUFhLEVBQUUsQ0FBQyxXQUFXO1FBQzNCLHFCQUFxQjtRQUNyQixRQUFRLEVBQUUsZ0JBQWdCO0tBQzNCLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxFQUFxQixFQUNyQixZQUFzQjtJQUV0QixNQUFNLFFBQVEsR0FBRyxZQUFZO1NBQzFCLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFNUQsT0FBTyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLG9CQUFvQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDbkcsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJveGVkLCBpc0JveGVkIH0gZnJvbSAnLi9ib3hpbmcnO1xyXG5pbXBvcnQgeyBkZWVwRXF1YWxzLCBpc0VtcHR5IH0gZnJvbSAnLi91dGlsJztcclxuXHJcbmV4cG9ydCB0eXBlIEZvcm1Db250cm9sVmFsdWVUeXBlcyA9IEJveGVkPGFueT4gfCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCB8IHVuZGVmaW5lZDtcclxuZXhwb3J0IHR5cGUgTmdyeEZvcm1Db250cm9sSWQgPSBzdHJpbmc7XHJcblxyXG4vKipcclxuICogVGhpcyB0eXBlIHJlcHJlc2VudHMgYSBjb2xsZWN0aW9uIG9mIG5hbWVkIGVycm9ycy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGlvbkVycm9ycyB7IHJlYWRvbmx5IFtrZXk6IHN0cmluZ106IGFueTsgfVxyXG5leHBvcnQgaW50ZXJmYWNlIEtleVZhbHVlIHsgW2tleTogc3RyaW5nXTogYW55OyB9XHJcblxyXG4vKipcclxuICogQmFzZSBpbnRlcmZhY2UgZm9yIGFsbCB0eXBlcyBvZiBmb3JtIHN0YXRlcy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgQWJzdHJhY3RDb250cm9sU3RhdGU8VFZhbHVlPiB7XHJcbiAgLyoqXHJcbiAgICogVGhlIHVuaXF1ZSBJRCBvZiB0aGUgZm9ybSBzdGF0ZS4gVXN1YWxseSB0aGlzIGlzIHRoZSBuYW1lIG9yIGluZGV4XHJcbiAgICogb2YgdGhlIGNvbnRyb2wgaW4gdGhlIGZvcm0gdmFsdWUgcHJlZml4ZWQgYnkgdGhlIElEIG9mIHRoZSBjb250YWluaW5nXHJcbiAgICogZ3JvdXAgb3IgYXJyYXksIGUuZy4gYE1ZX0ZPUk0uc29tZVRleHRJbnB1dGAgb3IgYE1ZX0ZPUk0uMGAuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHZhbHVlIG9mIHRoZSBmb3JtIHN0YXRlLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IHZhbHVlOiBUVmFsdWU7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYHRydWVgIGlmIHRoZSBzdGF0ZSBkb2VzIG5vdCBoYXZlIGFueSBlcnJvcnMuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNWYWxpZDogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAgaWYgdGhlIHN0YXRlIGhhcyBhdCBsZWFzdCBvbmUgZXJyb3IuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNJbnZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZXJyb3JzIG9mIHRoZSBzdGF0ZS4gVGhpcyBwcm9wZXJ0eSBhbHdheXMgaGFzIGEgdmFsdWUuXHJcbiAgICogSWYgdGhlIHN0YXRlIGhhcyBubyBlcnJvcnMgdGhlIHByb3BlcnR5IGlzIHNldCB0byBge31gLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGVycm9yczogVmFsaWRhdGlvbkVycm9ycztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIG5hbWVzIG9mIGFsbCBhc3luY2hyb25vdXMgdmFsaWRhdGlvbnMgY3VycmVudGx5IHJ1bm5pbmdcclxuICAgKiBmb3IgdGhlIHN0YXRlLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IHBlbmRpbmdWYWxpZGF0aW9uczogcmVhZG9ubHkgc3RyaW5nW107XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNvbnRyb2wgaXMgY3VycmVudGx5IGJlaW5nXHJcbiAgICogYXN5bmNocm9ub3VzbHkgdmFsaWRhdGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVmFsaWRhdGlvblBlbmRpbmc6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHN0YXRlIGlzIGVuYWJsZWQuIFdoZW4gaXRcclxuICAgKiBpcyBgZmFsc2VgIHRoZSBgZXJyb3JzYCBhcmUgYWx3YXlzIGB7fWAgKGkuZS4gdGhlIHN0YXRlIGlzXHJcbiAgICogYWx3YXlzIHZhbGlkIGlmIGRpc2FibGVkKSBhbmQgYHBlbmRpbmdWYWxpZGF0aW9uc2AgaXMgYWx3YXlzIGBbXWBcclxuICAgKiAoaS5lLiBhbGwgcGVuZGluZyB2YWxpZGF0aW9ucyBhcmUgY2FuY2VsbGVkKS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHN0YXRlIGlzIGRpc2FibGVkLiBXaGVuIGl0XHJcbiAgICogaXMgYHRydWVgIHRoZSBgZXJyb3JzYCBhcmUgYWx3YXlzIGB7fWAgKGkuZS4gdGhlIHN0YXRlIGlzXHJcbiAgICogYWx3YXlzIHZhbGlkIGlmIGRpc2FibGVkKSBhbmQgYHBlbmRpbmdWYWxpZGF0aW9uc2AgaXMgYWx3YXlzIGBbXWBcclxuICAgKiAoaS5lLiBhbGwgcGVuZGluZyB2YWxpZGF0aW9ucyBhcmUgY2FuY2VsbGVkKS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0Rpc2FibGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgc3RhdGUncyB2YWx1ZSBjaGFuZ2VzLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzRGlydHk6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYHRydWVgIGFzIGxvbmcgYXMgdGhlIHN0YXRlJ3MgdmFsdWUgbmV2ZXIgY2hhbmdlZC5cclxuICAgKi9cclxuICByZWFkb25seSBpc1ByaXN0aW5lOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgc3RhdGUgaXMgdG91Y2hlZC5cclxuICAgKi9cclxuICByZWFkb25seSBpc1RvdWNoZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYHRydWVgIGFzIGxvbmcgYXMgdGhlIHN0YXRlIGlzIG5vdCB0b3VjaGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW50b3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgc3RhdGUgaXMgc3VibWl0dGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzU3VibWl0dGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBhcyBsb25nIGFzIHRoZSBzdGF0ZSBpcyBub3Qgc3VibWl0dGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW5zdWJtaXR0ZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYSBjb250YWluZXIgZm9yIHVzZXItZGVmaW5lZCBtZXRhZGF0YSAoZS5nLiBpZlxyXG4gICAqIHlvdSB3YW50ZWQgdG8gY291bnQgdGhlIG51bWJlciBvZiB0aW1lcyBhIHN0YXRlJ3MgdmFsdWUgaGFzIGJlZW5cclxuICAgKiBjaGFuZ2VkLCB3aGF0IGtleXMgd2VyZSBwcmVzc2VkIG9uIGFuIGlucHV0LCBvciBob3cgb2Z0ZW4gYSBmb3JtXHJcbiAgICogaGFzIGJlZW4gc3VibWl0dGVkIGV0Yy4pLiBXaGlsZSBpdCBpcyBwb3NzaWJsZSB0byBzdG9yZSB0aGlzIGtpbmRcclxuICAgKiBvZiBpbmZvcm1hdGlvbiBvdXRzaWRlIG9mICoqbmdyeC1mb3JtcyoqIGluIHlvdXIgb3duIHN0YXRlIHRoZVxyXG4gICAqIGB1c2VyRGVmaW5lZFByb3BlcnRpZXNgIGFsbG93IHlvdSB0byBzdG9yZSB5b3VyIG93biBtZXRhZGF0YVxyXG4gICAqIGRpcmVjdGx5IGluIHRoZSBzdGF0ZS5cclxuICAgKi9cclxuICByZWFkb25seSB1c2VyRGVmaW5lZFByb3BlcnRpZXM6IEtleVZhbHVlO1xyXG59XHJcblxyXG4vKipcclxuICogU3RhdGUgYXNzb2NpYXRlZCB3aXRoIGEgZm9ybSBjb250cm9sLCBpLmUuIGFuIEhUTUwgZm9ybVxyXG4gKiBlbGVtZW50IGluIHRoZSB2aWV3IChlLmcuIGBpbnB1dGAsIGBzZWxlY3RgLCBgdGV4dGFyZWFgIGV0Yy4pLlxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBGb3JtQ29udHJvbFN0YXRlPFRWYWx1ZSBleHRlbmRzIEZvcm1Db250cm9sVmFsdWVUeXBlcz4gZXh0ZW5kcyBBYnN0cmFjdENvbnRyb2xTdGF0ZTxUVmFsdWU+IHtcclxuICAvKipcclxuICAgKiBUaGUgdmFsdWUgb2YgdGhlIGZvcm0gc3RhdGUuIEZvcm0gY29udHJvbHMgb25seSBzdXBwb3J0IHZhbHVlcyBvZlxyXG4gICAqIHR5cGUgYHN0cmluZ2AsIGBudW1iZXJgLCBgYm9vbGVhbmAsIGBudWxsYCwgYW5kIGB1bmRlZmluZWRgIHRvXHJcbiAgICoga2VlcCB0aGUgc3RhdGUgc3RyaW5nIHNlcmlhbGl6YWJsZS5cclxuICAgKi9cclxuICByZWFkb25seSB2YWx1ZTogVFZhbHVlO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiB0aGUgZm9ybSBjb250cm9sIGRvZXMgbm90IGhhdmUgYW55IGVycm9ycy5cclxuICAgKi9cclxuICByZWFkb25seSBpc1ZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiB0aGUgZm9ybSBjb250cm9sIGhhcyBhdCBsZWFzdCBvbmUgZXJyb3IuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNJbnZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZXJyb3JzIG9mIHRoZSBmb3JtIGNvbnRyb2wuIFRoaXMgcHJvcGVydHkgYWx3YXlzIGhhcyBhIHZhbHVlLlxyXG4gICAqIElmIHRoZSBjb250cm9sIGhhcyBubyBlcnJvcnMgdGhlIHByb3BlcnR5IGlzIHNldCB0byBge31gLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGVycm9yczogVmFsaWRhdGlvbkVycm9ycztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIG5hbWVzIG9mIGFsbCBhc3luY2hyb25vdXMgdmFsaWRhdGlvbnMgY3VycmVudGx5IHJ1bm5pbmcgZm9yIHRoZVxyXG4gICAqIGZvcm0gY29udHJvbC5cclxuICAgKi9cclxuICByZWFkb25seSBwZW5kaW5nVmFsaWRhdGlvbnM6IHJlYWRvbmx5IHN0cmluZ1tdO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGluZGljYXRlcyB3aGV0aGVyIHRoZSBjb250cm9sIGlzIGN1cnJlbnRseSBiZWluZ1xyXG4gICAqIGFzeW5jaHJvbm91c2x5IHZhbGlkYXRlZCAoaS5lLiB0aGlzIGlzIGB0cnVlYCBpZiBhbmQgb25seSBpZlxyXG4gICAqIGBwZW5kaW5nVmFsaWRhdGlvbnNgIGlzIG5vdCBlbXB0eSkuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNWYWxpZGF0aW9uUGVuZGluZzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpbmRpY2F0ZXMgd2hldGhlciB0aGUgZm9ybSBjb250cm9sIGlzIGVuYWJsZWQuXHJcbiAgICogV2hlbiBpdCBpcyBgZmFsc2VgIHRoZSBgZXJyb3JzYCBhcmUgYWx3YXlzIGB7fWAgKGkuZS4gdGhlIGZvcm1cclxuICAgKiBjb250cm9sIGlzIGFsd2F5cyB2YWxpZCBpZiBkaXNhYmxlZCkgYW5kIGBwZW5kaW5nVmFsaWRhdGlvbnNgXHJcbiAgICogaXMgYWx3YXlzIGBbXWAgKGkuZS4gYWxsIHBlbmRpbmcgdmFsaWRhdGlvbnMgYXJlIGNhbmNlbGxlZCkuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNFbmFibGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGluZGljYXRlcyB3aGV0aGVyIHRoZSBmb3JtIGNvbnRyb2wgaXMgZGlzYWJsZWQuXHJcbiAgICogV2hlbiBpdCBpcyBgdHJ1ZWAgdGhlIGBlcnJvcnNgIGFyZSBhbHdheXMgYHt9YCAoaS5lLiB0aGUgZm9ybVxyXG4gICAqIGNvbnRyb2wgaXMgYWx3YXlzIHZhbGlkIGlmIGRpc2FibGVkKSBhbmQgYHBlbmRpbmdWYWxpZGF0aW9uc2BcclxuICAgKiBpcyBhbHdheXMgYFtdYCAoaS5lLiBhbGwgcGVuZGluZyB2YWxpZGF0aW9ucyBhcmUgY2FuY2VsbGVkKS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0Rpc2FibGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgdW5kZXJseWluZ1xyXG4gICAqIGBGb3JtVmlld0FkYXB0ZXJgIG9yIGBDb250cm9sVmFsdWVBY2Nlc3NvcmAgcmVwb3J0cyBhIG5ld1xyXG4gICAqIHZhbHVlIGZvciB0aGUgZmlyc3QgdGltZS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0RpcnR5OiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBhcyBsb25nIGFzIHRoZSB1bmRlcmx5aW5nXHJcbiAgICogYEZvcm1WaWV3QWRhcHRlcmAgb3IgYENvbnRyb2xWYWx1ZUFjY2Vzc29yYCBoYXMgbmV2ZXJcclxuICAgKiByZXBvcnRlZCBhIG5ldyB2YWx1ZS5cclxuICAgKi9cclxuICByZWFkb25seSBpc1ByaXN0aW5lOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYmFzZWQgb24gdGhlIHJ1bGVzIG9mIHRoZVxyXG4gICAqIHVuZGVybHlpbmcgYEZvcm1WaWV3QWRhcHRlcmAgKHVzdWFsbHkgb24gYGJsdXJgIGZvciBtb3N0IGZvcm1cclxuICAgKiBlbGVtZW50cykuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNUb3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBhcyBsb25nIGFzIHRoZSBjb250cm9sIGlzIG5vdCB0b3VjaGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW50b3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgZ3JvdXAgb3IgYXJyYXlcclxuICAgKiBjb250YWluaW5nIHRoaXMgZm9ybSBjb250cm9sIGlzIHN1Ym1pdHRlZC4gQSBmb3JtIGNvbnRyb2wgY2FuXHJcbiAgICogbmV2ZXIgYmUgc3VibWl0dGVkIG9uIGl0cyBvd24uXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNTdWJtaXR0ZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYHRydWVgIGFzIGxvbmcgYXMgdGhlIHN0YXRlIGlzIG5vdCBzdWJtaXR0ZWQuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNVbnN1Ym1pdHRlZDogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBzZXQgdG8gYHRydWVgIGlmIHRoZSBmb3JtIGNvbnRyb2wgY3VycmVudGx5XHJcbiAgICogaGFzIGZvY3VzLiBUaGlzIGZlYXR1cmUgaXMgb3B0LWluLiBUbyBlbmFibGUgaXQgeW91IGhhdmUgdG9cclxuICAgKiBlbmFibGUgaXQgZm9yIGEgZ2l2ZW4gZm9ybSBlbGVtZW50IGxpa2UgdGhpczpcclxuICAgKlxyXG5gYGBodG1sXHJcbjxpbnB1dCBbbmdyeEZvcm1Db250cm9sU3RhdGVdPVwic3RhdGVcIlxyXG4gICAgICBbbmdyeEVuYWJsZUZvY3VzVHJhY2tpbmddPVwidHJ1ZVwiIC8+XHJcbmBgYFxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzRm9jdXNlZDogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAgaWYgdGhlIGNvbnRyb2wgY3VycmVudGx5IGRvZXMgbm90IGhhdmVcclxuICAgKiBmb2N1cyBvciBmb2N1cyB0cmFja2luZyBpcyBub3QgZW5hYmxlZCBmb3IgdGhlIGZvcm0gY29udHJvbC5cclxuICAgKi9cclxuICByZWFkb25seSBpc1VuZm9jdXNlZDogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoaXMgdHlwZSByZXByZXNlbnRzIHRoZSBjaGlsZCBjb250cm9sIHN0YXRlcyBvZiBhIGZvcm0gZ3JvdXAuXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBGb3JtR3JvdXBDb250cm9sczxUVmFsdWUgZXh0ZW5kcyBLZXlWYWx1ZT4gPSB7XHJcbiAgcmVhZG9ubHkgW2NvbnRyb2xJZCBpbiBrZXlvZiBUVmFsdWVdOiBGb3JtU3RhdGU8VFZhbHVlW2NvbnRyb2xJZF0+O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEZvcm0gZ3JvdXBzIGFyZSBjb2xsZWN0aW9ucyBvZiBuYW1lZCBjb250cm9scy4gSnVzdCBsaWtlIGNvbnRyb2xzXHJcbiAqIGdyb3VwcyBhcmUgcmVwcmVzZW50ZWQgYXMgcGxhaW4gc3RhdGUgb2JqZWN0cy4gVGhlIHN0YXRlIG9mIGFcclxuICogZ3JvdXAgaXMgZGV0ZXJtaW5lZCBhbG1vc3QgZnVsbHkgYnkgaXRzIGNoaWxkIHN0YXRlcy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRm9ybUdyb3VwU3RhdGU8VFZhbHVlIGV4dGVuZHMgS2V5VmFsdWU+IGV4dGVuZHMgQWJzdHJhY3RDb250cm9sU3RhdGU8VFZhbHVlPiB7XHJcbiAgLyoqXHJcbiAgICogVGhlIGFnZ3JlZ2F0ZWQgdmFsdWUgb2YgdGhlIGZvcm0gZ3JvdXAuIFRoZSB2YWx1ZSBpcyBjb21wdXRlZCBieVxyXG4gICAqIGFnZ3JlZ2F0aW5nIHRoZSB2YWx1ZXMgb2YgYWxsIGNoaWxkcmVuLCBlLmcuXHJcbiAgICpcclxuYGBgdHlwZXNjcmlwdFxyXG57XHJcbiAgY2hpbGQxOiAnc29tZSB2YWx1ZScsXHJcbiAgY2hpbGQyOiB7XHJcbiAgICBuZXN0ZWRDaGlsZDogMTAsXHJcbiAgfSxcclxufVxyXG5gYGBcclxuICAgKi9cclxuICByZWFkb25seSB2YWx1ZTogVFZhbHVlO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiB0aGUgZm9ybSBncm91cCBkb2VzIG5vdCBoYXZlIGFueSBlcnJvcnNcclxuICAgKiBpdHNlbGYgYW5kIG5vbmUgb2YgaXRzIGNoaWxkcmVuIGhhdmUgYW55IGVycm9ycy5cclxuICAgKi9cclxuICByZWFkb25seSBpc1ZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiB0aGUgZm9ybSBncm91cCBvciBhbnkgb2YgaXRzIGNoaWxkcmVuXHJcbiAgICogaGF2ZSBhdCBsZWFzdCBvbmUgZXJyb3IuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNJbnZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZXJyb3JzIG9mIHRoZSBmb3JtIGdyb3VwLiBUaGlzIHByb3BlcnR5IGlzIGNvbXB1dGVkIGJ5IG1lcmdpbmdcclxuICAgKiB0aGUgZXJyb3JzIG9mIHRoZSBncm91cCB3aXRoIHRoZSBlcnJvcnMgb2YgYWxsIGl0cyBjaGlsZHJlbiB3aGVyZVxyXG4gICAqIHRoZSBjaGlsZCBlcnJvcnMgYXJlIGEgcHJvcGVydHkgb2YgdGhlIGBlcnJvcnNgIG9iamVjdCBwcmVmaXhlZCB3aXRoXHJcbiAgICogYW4gdW5kZXJzY29yZSwgZS5nLlxyXG4gICAqXHJcbmBgYFxyXG57XHJcbiAgZ3JvdXBFcnJvcjogdHJ1ZSxcclxuICBfY2hpbGQ6IHtcclxuICAgIGNoaWxkRXJyb3I6IHRydWUsXHJcbiAgfSxcclxufVxyXG5gYGBcclxuICAgKlxyXG4gICAqIElmIG5laXRoZXIgdGhlIGdyb3VwIG5vciBhbnkgY2hpbGRyZW4gaGF2ZSBlcnJvcnMgdGhlIHByb3BlcnR5IGlzXHJcbiAgICogc2V0IHRvIGB7fWAuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JzO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgbmFtZXMgb2YgYWxsIGFzeW5jaHJvbm91cyB2YWxpZGF0aW9ucyBjdXJyZW50bHkgcnVubmluZyBmb3IgdGhlXHJcbiAgICogZm9ybSBncm91cC5cclxuICAgKi9cclxuICByZWFkb25seSBwZW5kaW5nVmFsaWRhdGlvbnM6IHJlYWRvbmx5IHN0cmluZ1tdO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGluZGljYXRlcyB3aGV0aGVyIHRoZSBncm91cCBvciBhbnkgb2YgaXRzIGNoaWxkcmVuXHJcbiAgICogYXJlIGN1cnJlbnRseSBiZWluZyBhc3luY2hyb25vdXNseSB2YWxpZGF0ZWQuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNWYWxpZGF0aW9uUGVuZGluZzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpbmRpY2F0ZXMgd2hldGhlciB0aGUgZm9ybSBncm91cCBpcyBlbmFibGVkLiBJdCBpc1xyXG4gICAqIGB0cnVlYCBpZiBhbmQgb25seSBpZiBhdCBsZWFzdCBvbmUgb2YgaXRzIGNoaWxkIHN0YXRlcyBpc1xyXG4gICAqIGVuYWJsZWQuIFdoZW4gaXQgaXMgYGZhbHNlYCB0aGUgYGVycm9yc2AgYXJlIGFsd2F5cyBge31gIChpLmUuXHJcbiAgICogdGhlIGZvcm0gZ3JvdXAgaXMgYWx3YXlzIHZhbGlkIGlmIGRpc2FibGVkKSBhbmQgYHBlbmRpbmdWYWxpZGF0aW9uc2BcclxuICAgKiBpcyBhbHdheXMgYFtdYCAoaS5lLiBhbGwgcGVuZGluZyB2YWxpZGF0aW9ucyBhcmUgY2FuY2VsbGVkKS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGZvcm0gZ3JvdXAgaXMgZGlzYWJsZWQuIEl0IGlzXHJcbiAgICogYHRydWVgIGlmIGFuZCBvbmx5IGlmIGFsbCBvZiBpdHMgY2hpbGQgc3RhdGUgYXJlIGRpc2FibGVkLiBXaGVuXHJcbiAgICogaXQgaXMgYHRydWVgIHRoZSBgZXJyb3JzYCBhcmUgYWx3YXlzIGB7fWAgKGkuZS4gdGhlIGZvcm0gZ3JvdXBcclxuICAgKiBpcyBhbHdheXMgdmFsaWQgaWYgZGlzYWJsZWQpIGFuZCBgcGVuZGluZ1ZhbGlkYXRpb25zYCBpcyBhbHdheXNcclxuICAgKiBgW11gIChpLmUuIGFsbCBwZW5kaW5nIHZhbGlkYXRpb25zIGFyZSBjYW5jZWxsZWQpLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzRGlzYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYHRydWVgIGlmIGFuZCBvbmx5IGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgZm9ybVxyXG4gICAqIGdyb3VwJ3MgY2hpbGQgc3RhdGVzIGlzIG1hcmtlZCBhcyBkaXJ0eS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0RpcnR5OiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiBhbmQgb25seSBpZiBhbGwgb2YgdGhlIGZvcm0gZ3JvdXAnc1xyXG4gICAqIGNoaWxkIHN0YXRlcyBhcmUgcHJpc3RpbmUuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNQcmlzdGluZTogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAgaWYgYW5kIG9ubHkgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb3JtXHJcbiAgICogZ3JvdXAncyBjaGlsZCBzdGF0ZXMgaXMgbWFya2VkIGFzIHRvdWNoZWQuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNUb3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiBhbmQgb25seSBpZiBhbGwgb2YgdGhlIGZvcm0gZ3JvdXAnc1xyXG4gICAqIGNoaWxkIHN0YXRlcyBhcmUgdW50b3VjaGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW50b3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgZm9ybSBncm91cCBpc1xyXG4gICAqIHN1Ym1pdHRlZC4gVGhpcyBpcyB0cmFja2VkIGJ5IHRoZSBgTmdyeEZvcm1EaXJlY3RpdmVgLCB3aGljaFxyXG4gICAqIG5lZWRzIHRvIGJlIGFwcGxpZWQgdG8gYSBmb3JtIGxpa2UgdGhpczpcclxuICAgKlxyXG5gYGBodG1sXHJcbjxmb3JtIFtuZ3J4Rm9ybVN0YXRlXT1cImdyb3VwU3RhdGVcIj5cclxuPC9mb3JtPlxyXG5gYGBcclxuICAgKlxyXG4gICAqIE5vdGUgdGhhdCBhcHBseWluZyB0aGlzIGRpcmVjdGl2ZSB0byBhIGZvcm0gcHJldmVudHMgbm9ybWFsIGZvcm1cclxuICAgKiBzdWJtaXNzaW9uIHNpbmNlIHRoYXQgZG9lcyBub3QgbWFrZSBtdWNoIHNlbnNlIGZvciBuZ3J4IGZvcm1zLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzU3VibWl0dGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBhcyBsb25nIGFzIHRoZSBzdGF0ZSBpcyBub3Qgc3VibWl0dGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW5zdWJtaXR0ZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgY29udGFpbnMgYWxsIGNoaWxkIHN0YXRlcyBvZiB0aGUgZm9ybSBncm91cC4gQXNcclxuICAgKiB5b3UgbWF5IGhhdmUgbm90aWNlZCB0aGUgdHlwZSBvZiBlYWNoIGNoaWxkIHN0YXRlIGlzXHJcbiAgICogYEFic3RyYWN0Q29udHJvbFN0YXRlYCB3aGljaCBzb21ldGltZXMgZm9yY2VzIHlvdSB0byBjYXN0IHRoZVxyXG4gICAqIHN0YXRlIGV4cGxpY2l0bHkuIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBpbXByb3ZlIHRoaXMgdHlwaW5nXHJcbiAgICogdW50aWwgW2NvbmRpdGlvbmFsIG1hcHBlZCB0eXBlc10oaHR0cHM6Ly9naXRodWIuY29tL01pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8xMjQyNClcclxuICAgKiBhcmUgYWRkZWQgdG8gVHlwZVNjcmlwdC5cclxuICAgKi9cclxuICByZWFkb25seSBjb250cm9sczogRm9ybUdyb3VwQ29udHJvbHM8VFZhbHVlPjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZvcm0gYXJyYXlzIGFyZSBjb2xsZWN0aW9ucyBvZiBjb250cm9scy4gVGhleSBhcmUgcmVwcmVzZW50ZWQgYXNcclxuICogcGxhaW4gc3RhdGUgYXJyYXlzLiBUaGUgc3RhdGUgb2YgYW4gYXJyYXkgaXMgZGV0ZXJtaW5lZCBhbG1vc3RcclxuICogZnVsbHkgYnkgaXRzIGNoaWxkIHN0YXRlcy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRm9ybUFycmF5U3RhdGU8VFZhbHVlPiBleHRlbmRzIEFic3RyYWN0Q29udHJvbFN0YXRlPHJlYWRvbmx5IFRWYWx1ZVtdPiB7XHJcbiAgLyoqXHJcbiAgICogVGhlIGFnZ3JlZ2F0ZWQgdmFsdWUgb2YgdGhlIGZvcm0gYXJyYXkuIFRoZSB2YWx1ZSBpcyBjb21wdXRlZCBieVxyXG4gICAqIGFnZ3JlZ2F0aW5nIHRoZSB2YWx1ZXMgb2YgYWxsIGNoaWxkcmVuIGludG8gYW4gYXJyYXkuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgdmFsdWU6IFRWYWx1ZVtdO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiB0aGUgZm9ybSBhcnJheSBkb2VzIG5vdCBoYXZlIGFueSBlcnJvcnNcclxuICAgKiBpdHNlbGYgYW5kIG5vbmUgb2YgaXRzIGNoaWxkcmVuIGhhdmUgYW55IGVycm9ycy5cclxuICAgKi9cclxuICByZWFkb25seSBpc1ZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiB0aGUgZm9ybSBhcnJheSBvciBhbnkgb2YgaXRzIGNoaWxkcmVuXHJcbiAgICogaGF2ZSBhdCBsZWFzdCBvbmUgZXJyb3IuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNJbnZhbGlkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZXJyb3JzIG9mIHRoZSBmb3JtIGFycmF5LiBUaGlzIHByb3BlcnR5IGlzIGNvbXB1dGVkIGJ5IG1lcmdpbmdcclxuICAgKiB0aGUgZXJyb3JzIG9mIHRoZSBhcnJheSB3aXRoIHRoZSBlcnJvcnMgb2YgYWxsIGl0cyBjaGlsZHJlbiB3aGVyZVxyXG4gICAqIHRoZSBjaGlsZCBlcnJvcnMgYXJlIGEgcHJvcGVydHkgb2YgdGhlIGBlcnJvcnNgIG9iamVjdCBwcmVmaXhlZCB3aXRoXHJcbiAgICogYW4gdW5kZXJzY29yZSwgZS5nLlxyXG4gICAqXHJcbmBgYFxyXG57XHJcbiAgYXJyYXlFcnJvcjogdHJ1ZSxcclxuICBfMDoge1xyXG4gICAgY2hpbGRFcnJvcjogdHJ1ZSxcclxuICB9LFxyXG59XHJcbmBgYFxyXG4gICAqXHJcbiAgICogSWYgbmVpdGhlciB0aGUgYXJyYXkgbm9yIGFueSBjaGlsZHJlbiBoYXZlIGVycm9ycyB0aGUgcHJvcGVydHkgaXNcclxuICAgKiBzZXQgdG8gYHt9YC5cclxuICAgKi9cclxuICByZWFkb25seSBlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnM7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBuYW1lcyBvZiBhbGwgYXN5bmNocm9ub3VzIHZhbGlkYXRpb25zIGN1cnJlbnRseSBydW5uaW5nIGZvciB0aGVcclxuICAgKiBmb3JtIGFycmF5LlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IHBlbmRpbmdWYWxpZGF0aW9uczogcmVhZG9ubHkgc3RyaW5nW107XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGFycmF5IG9yIGFueSBvZiBpdHMgY2hpbGRyZW5cclxuICAgKiBhcmUgY3VycmVudGx5IGJlaW5nIGFzeW5jaHJvbm91c2x5IHZhbGlkYXRlZC5cclxuICAgKi9cclxuICByZWFkb25seSBpc1ZhbGlkYXRpb25QZW5kaW5nOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGluZGljYXRlcyB3aGV0aGVyIHRoZSBmb3JtIGFycmF5IGlzIGVuYWJsZWQuIEl0IGlzXHJcbiAgICogYHRydWVgIGlmIGFuZCBvbmx5IGlmIGF0IGxlYXN0IG9uZSBvZiBpdHMgY2hpbGQgc3RhdGVzIGlzXHJcbiAgICogZW5hYmxlZC4gV2hlbiBpdCBpcyBgZmFsc2VgIHRoZSBgZXJyb3JzYCBhcmUgYWx3YXlzIGB7fWAgKGkuZS5cclxuICAgKiB0aGUgZm9ybSBhcnJheSBpcyBhbHdheXMgdmFsaWQgaWYgZGlzYWJsZWQpIGFuZCBgcGVuZGluZ1ZhbGlkYXRpb25zYFxyXG4gICAqIGlzIGFsd2F5cyBgW11gIChpLmUuIGFsbCBwZW5kaW5nIHZhbGlkYXRpb25zIGFyZSBjYW5jZWxsZWQpLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzRW5hYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpbmRpY2F0ZXMgd2hldGhlciB0aGUgZm9ybSBhcnJheSBpcyBkaXNhYmxlZC4gSXQgaXNcclxuICAgKiBgdHJ1ZWAgaWYgYW5kIG9ubHkgaWYgYWxsIG9mIGl0cyBjaGlsZCBzdGF0ZXMgYXJlIGRpc2FibGVkLiBXaGVuXHJcbiAgICogaXQgaXMgYHRydWVgIHRoZSBgZXJyb3JzYCBhcmUgYWx3YXlzIGB7fWAgKGkuZS4gdGhlIGZvcm0gYXJyYXlcclxuICAgKiBpcyBhbHdheXMgdmFsaWQgaWYgZGlzYWJsZWQpIGFuZCBgcGVuZGluZ1ZhbGlkYXRpb25zYCBpcyBhbHdheXNcclxuICAgKiBgW11gIChpLmUuIGFsbCBwZW5kaW5nIHZhbGlkYXRpb25zIGFyZSBjYW5jZWxsZWQpLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzRGlzYWJsZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgaXMgYHRydWVgIGlmIGFuZCBvbmx5IGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgZm9ybVxyXG4gICAqIGFycmF5J3MgY2hpbGQgc3RhdGVzIGlzIG1hcmtlZCBhcyBkaXJ0eS5cclxuICAgKi9cclxuICByZWFkb25seSBpc0RpcnR5OiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiBhbmQgb25seSBpZiBhbGwgb2YgdGhlIGZvcm0gYXJyYXknc1xyXG4gICAqIGNoaWxkIHN0YXRlcyBhcmUgcHJpc3RpbmUuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNQcmlzdGluZTogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAgaWYgYW5kIG9ubHkgaWYgYXQgbGVhc3Qgb25lIG9mIHRoZSBmb3JtXHJcbiAgICogYXJyYXkncyBjaGlsZCBzdGF0ZXMgaXMgbWFya2VkIGFzIHRvdWNoZWQuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgaXNUb3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBpZiBhbmQgb25seSBpZiBhbGwgb2YgdGhlIGZvcm0gYXJyYXknc1xyXG4gICAqIGNoaWxkIHN0YXRlcyBhcmUgdW50b3VjaGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW50b3VjaGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIHNldCB0byBgdHJ1ZWAgYXMgc29vbiBhcyB0aGUgZm9ybSBhcnJheSBpc1xyXG4gICAqIHN1Ym1pdHRlZC4gVGhpcyBpcyB0cmFja2VkIGJ5IHRoZSBgTmdyeEZvcm1EaXJlY3RpdmVgLCB3aGljaFxyXG4gICAqIG5lZWRzIHRvIGJlIGFwcGxpZWQgdG8gYSBmb3JtIGxpa2UgdGhpczpcclxuICAgKlxyXG5gYGBodG1sXHJcbjxmb3JtIFtuZ3J4Rm9ybVN0YXRlXT1cImFycmF5U3RhdGVcIj5cclxuPC9mb3JtPlxyXG5gYGBcclxuICAgKlxyXG4gICAqIE5vdGUgdGhhdCBhcHBseWluZyB0aGlzIGRpcmVjdGl2ZSB0byBhIGZvcm0gcHJldmVudHMgbm9ybWFsIGZvcm1cclxuICAgKiBzdWJtaXNzaW9uIHNpbmNlIHRoYXQgZG9lcyBub3QgbWFrZSBtdWNoIHNlbnNlIGZvciBuZ3J4IGZvcm1zLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzU3VibWl0dGVkOiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBUaGlzIHByb3BlcnR5IGlzIGB0cnVlYCBhcyBsb25nIGFzIHRoZSBzdGF0ZSBpcyBub3Qgc3VibWl0dGVkLlxyXG4gICAqL1xyXG4gIHJlYWRvbmx5IGlzVW5zdWJtaXR0ZWQ6IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoaXMgcHJvcGVydHkgY29udGFpbnMgYWxsIGNoaWxkIHN0YXRlcyBvZiB0aGUgZm9ybSBhcnJheS4gQXNcclxuICAgKiB5b3UgbWF5IGhhdmUgbm90aWNlZCB0aGUgdHlwZSBvZiBlYWNoIGNoaWxkIHN0YXRlIGlzXHJcbiAgICogYEFic3RyYWN0Q29udHJvbFN0YXRlYCB3aGljaCBzb21ldGltZXMgZm9yY2VzIHlvdSB0byBjYXN0IHRoZVxyXG4gICAqIHN0YXRlIGV4cGxpY2l0bHkuIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBpbXByb3ZlIHRoaXMgdHlwaW5nXHJcbiAgICogdW50aWwgW2NvbmRpdGlvbmFsIG1hcHBlZCB0eXBlc10oaHR0cHM6Ly9naXRodWIuY29tL01pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8xMjQyNClcclxuICAgKiBhcmUgYWRkZWQgdG8gVHlwZVNjcmlwdC5cclxuICAgKi9cclxuICByZWFkb25seSBjb250cm9sczogcmVhZG9ubHkgRm9ybVN0YXRlPFRWYWx1ZT5bXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoaXMgaXMgYSBoZWxwZXIgdHlwZSB0aGF0IGFsbG93cyB3b3JraW5nIGFyb3VuZCB0aGUgZGlzdHJpYnV0aXZlbmVzc1xyXG4gKiBvZiBjb25kaXRpb25hbCB0eXBlcy5cclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlV3JhcHBlcjxUPiB7XHJcbiAgdDogVDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoaXMgaXMgYSBoZWxwZXIgdHlwZSB0aGF0IGluZmVycyB0aGUgY29ycmVjdCBmb3JtIHN0YXRlIHR5cGUgYmFzZWRcclxuICogb24gdGhlIGJveGVkIHR5cGUgY29udGFpbmVkIGluIHRoZSBpbmZlcmVuY2Ugd3JhcHBlci5cclxuICovXHJcbmV4cG9ydCB0eXBlIEluZmVycmVkQm94ZWRGb3JtU3RhdGU8VCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8YW55Pj4gPVxyXG4gIFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPEJveGVkPGluZmVyIFU+PiA/IEZvcm1Db250cm9sU3RhdGU8Qm94ZWQ8VT4+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxCb3hlZDxpbmZlciBVPiB8IHVuZGVmaW5lZD4gPyBGb3JtQ29udHJvbFN0YXRlPEJveGVkPFU+IHwgdW5kZWZpbmVkPlxyXG4gIDogVCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8Qm94ZWQ8aW5mZXIgVT4gfCBudWxsPiA/IEZvcm1Db250cm9sU3RhdGU8Qm94ZWQ8VT4gfCBudWxsPlxyXG4gIDogVCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8Qm94ZWQ8aW5mZXIgVT4gfCB1bmRlZmluZWQgfCBudWxsPiA/IEZvcm1Db250cm9sU3RhdGU8Qm94ZWQ8VT4gfCB1bmRlZmluZWQgfCBudWxsPlxyXG4gIDogbmV2ZXJcclxuICA7XHJcblxyXG4vKipcclxuICogVGhpcyBpcyBhIGhlbHBlciB0eXBlIHRoYXQgaW5mZXJzIHRoZSBjb3JyZWN0IGZvcm0gc3RhdGUgdHlwZSBiYXNlZFxyXG4gKiBvbiB0aGUgc3RyaW5nIHR5cGUgY29udGFpbmVkIGluIHRoZSBpbmZlcmVuY2Ugd3JhcHBlci5cclxuICovXHJcbmV4cG9ydCB0eXBlIEluZmVycmVkU3RyaW5nRm9ybVN0YXRlPFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPGFueT4+ID1cclxuICBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxzdHJpbmc+ID8gRm9ybUNvbnRyb2xTdGF0ZTxzdHJpbmc+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxzdHJpbmcgfCB1bmRlZmluZWQ+ID8gRm9ybUNvbnRyb2xTdGF0ZTxzdHJpbmcgfCB1bmRlZmluZWQ+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxzdHJpbmcgfCBudWxsPiA/IEZvcm1Db250cm9sU3RhdGU8c3RyaW5nIHwgbnVsbD5cclxuICA6IFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPHN0cmluZyB8IHVuZGVmaW5lZCB8IG51bGw+ID8gRm9ybUNvbnRyb2xTdGF0ZTxzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsPlxyXG4gIDogbmV2ZXJcclxuICA7XHJcblxyXG4vKipcclxuICogVGhpcyBpcyBhIGhlbHBlciB0eXBlIHRoYXQgaW5mZXJzIHRoZSBjb3JyZWN0IGZvcm0gc3RhdGUgdHlwZSBiYXNlZFxyXG4gKiBvbiB0aGUgbnVtYmVyIHR5cGUgY29udGFpbmVkIGluIHRoZSBpbmZlcmVuY2Ugd3JhcHBlci5cclxuICovXHJcbmV4cG9ydCB0eXBlIEluZmVycmVkTnVtYmVyRm9ybVN0YXRlPFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPGFueT4+ID1cclxuICBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxudW1iZXI+ID8gRm9ybUNvbnRyb2xTdGF0ZTxudW1iZXI+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxudW1iZXIgfCB1bmRlZmluZWQ+ID8gRm9ybUNvbnRyb2xTdGF0ZTxudW1iZXIgfCB1bmRlZmluZWQ+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxudW1iZXIgfCBudWxsPiA/IEZvcm1Db250cm9sU3RhdGU8bnVtYmVyIHwgbnVsbD5cclxuICA6IFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGw+ID8gRm9ybUNvbnRyb2xTdGF0ZTxudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsPlxyXG4gIDogbmV2ZXJcclxuICA7XHJcblxyXG4vKipcclxuICogVGhpcyBpcyBhIGhlbHBlciB0eXBlIHRoYXQgaW5mZXJzIHRoZSBjb3JyZWN0IGZvcm0gc3RhdGUgdHlwZSBiYXNlZFxyXG4gKiBvbiB0aGUgYm9vbGVhbiB0eXBlIGNvbnRhaW5lZCBpbiB0aGUgaW5mZXJlbmNlIHdyYXBwZXIuXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBJbmZlcnJlZEJvb2xlYW5Gb3JtU3RhdGU8VCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8YW55Pj4gPVxyXG4gIFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPGJvb2xlYW4+ID8gRm9ybUNvbnRyb2xTdGF0ZTxib29sZWFuPlxyXG4gIDogVCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8Ym9vbGVhbiB8IHVuZGVmaW5lZD4gPyBGb3JtQ29udHJvbFN0YXRlPGJvb2xlYW4gfCB1bmRlZmluZWQ+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxib29sZWFuIHwgbnVsbD4gPyBGb3JtQ29udHJvbFN0YXRlPGJvb2xlYW4gfCBudWxsPlxyXG4gIDogVCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8Ym9vbGVhbiB8IHVuZGVmaW5lZCB8IG51bGw+ID8gRm9ybUNvbnRyb2xTdGF0ZTxib29sZWFuIHwgdW5kZWZpbmVkIHwgbnVsbD5cclxuICA6IG5ldmVyXHJcbiAgO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgaXMgYSBoZWxwZXIgdHlwZSB0aGF0IGluZmVycyB0aGUgY29ycmVjdCBmb3JtIHN0YXRlIHR5cGUgYmFzZWRcclxuICogb24gdGhlIHR5cGUgY29udGFpbmVkIGluIHRoZSBpbmZlcmVuY2Ugd3JhcHBlci5cclxuICovXHJcbmV4cG9ydCB0eXBlIEluZmVycmVkRm9ybVN0YXRlPFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPGFueT4+ID1cclxuICAvLyAoYWIpdXNlICdzeW1ib2wnIHRvIGNhdGNoICdhbnknIHR5cGluZ1xyXG4gIFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPHN5bWJvbD4gPyBBYnN0cmFjdENvbnRyb2xTdGF0ZTxhbnk+XHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjx1bmRlZmluZWQ+ID8gQWJzdHJhY3RDb250cm9sU3RhdGU8YW55PlxyXG4gIDogVCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8bnVsbD4gPyBBYnN0cmFjdENvbnRyb2xTdGF0ZTxhbnk+XHJcblxyXG4gIC8vIGNvbnRyb2xcclxuICA6IFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPEJveGVkPGFueT4gfCB1bmRlZmluZWQgfCBudWxsPiA/IEluZmVycmVkQm94ZWRGb3JtU3RhdGU8VD5cclxuICA6IFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPHN0cmluZyB8IHVuZGVmaW5lZCB8IG51bGw+ID8gSW5mZXJyZWRTdHJpbmdGb3JtU3RhdGU8VD5cclxuICA6IFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGw+ID8gSW5mZXJyZWROdW1iZXJGb3JtU3RhdGU8VD5cclxuICA6IFQgZXh0ZW5kcyBJbmZlcmVuY2VXcmFwcGVyPGJvb2xlYW4gfCB1bmRlZmluZWQgfCBudWxsPiA/IEluZmVycmVkQm9vbGVhbkZvcm1TdGF0ZTxUPlxyXG5cclxuICAvLyBhcnJheVxyXG4gIDogVCBleHRlbmRzIEluZmVyZW5jZVdyYXBwZXI8cmVhZG9ubHkgKGluZmVyIFUpW10gfCB1bmRlZmluZWQgfCBudWxsPiA/IEZvcm1BcnJheVN0YXRlPFU+XHJcblxyXG4gIC8vIGdyb3VwXHJcbiAgOiBUIGV4dGVuZHMgSW5mZXJlbmNlV3JhcHBlcjxpbmZlciBVIHwgdW5kZWZpbmVkIHwgbnVsbD4gPyBVIGV4dGVuZHMgS2V5VmFsdWUgPyBGb3JtR3JvdXBTdGF0ZTxVPiA6IG5ldmVyXHJcblxyXG4gIC8vIGZhbGxiYWNrIHR5cGUgKHRoaXMgY2FzZSBzaG91bGQgbmV2ZXIgKG5vIHB1biBpbnRlbmRlZCkgYmUgaGl0KVxyXG4gIDogbmV2ZXJcclxuICA7XHJcblxyXG4vKipcclxuICogVGhpcyBpcyBhIHR5cGUgdGhhdCBjYW4gaW5mZXIgdGhlIGNvbmNyZXRlIHR5cGUgb2YgYSBmb3JtIHN0YXRlIGJhc2VkXHJcbiAqIG9uIHRoZSBnaXZlbiB0eXBlIHBhcmFtZXRlci5cclxuICovXHJcbmV4cG9ydCB0eXBlIEZvcm1TdGF0ZTxUPiA9IEluZmVycmVkRm9ybVN0YXRlPEluZmVyZW5jZVdyYXBwZXI8VD4+O1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgZnVuY3Rpb24gZGV0ZXJtaW5lcyBpZiBhIHZhbHVlIGlzIGEgZm9ybSBzdGF0ZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc0Zvcm1TdGF0ZTxUVmFsdWUgPSBhbnk+KHN0YXRlOiBhbnkpOiBzdGF0ZSBpcyBGb3JtU3RhdGU8VFZhbHVlPiB7XHJcbiAgcmV0dXJuICEhc3RhdGUgJiYgc3RhdGUuaGFzT3duUHJvcGVydHkoJ2lkJykgJiYgc3RhdGUuaGFzT3duUHJvcGVydHkoJ3ZhbHVlJykgJiYgc3RhdGUuaGFzT3duUHJvcGVydHkoJ2Vycm9ycycpO1xyXG59XHJcblxyXG4vKipcclxuICogVGhpcyBmdW5jdGlvbiBkZXRlcm1pbmVzIGlmIGEgdmFsdWUgaXMgYW4gYXJyYXkgc3RhdGUuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheVN0YXRlPFRWYWx1ZSA9IGFueT4oc3RhdGU6IGFueSk6IHN0YXRlIGlzIEZvcm1BcnJheVN0YXRlPFRWYWx1ZT4ge1xyXG4gIHJldHVybiBpc0Zvcm1TdGF0ZShzdGF0ZSkgJiYgc3RhdGUuaGFzT3duUHJvcGVydHkoJ2NvbnRyb2xzJykgJiYgQXJyYXkuaXNBcnJheSgoc3RhdGUgYXMgYW55KS5jb250cm9scyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGlzIGZ1bmN0aW9uIGRldGVybWluZXMgaWYgYSB2YWx1ZSBpcyBhIGdyb3VwIHN0YXRlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzR3JvdXBTdGF0ZTxUVmFsdWUgZXh0ZW5kcyBLZXlWYWx1ZSA9IGFueT4oc3RhdGU6IGFueSk6IHN0YXRlIGlzIEZvcm1Hcm91cFN0YXRlPFRWYWx1ZT4ge1xyXG4gIHJldHVybiBpc0Zvcm1TdGF0ZShzdGF0ZSkgJiYgc3RhdGUuaGFzT3duUHJvcGVydHkoJ2NvbnRyb2xzJykgJiYgIUFycmF5LmlzQXJyYXkoKHN0YXRlIGFzIGFueSkuY29udHJvbHMpICYmIHR5cGVvZiAoc3RhdGUgYXMgYW55KS5jb250cm9scyAhPT0gJ2Z1bmN0aW9uJztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNoaWxkU3RhdGU8VFZhbHVlPihpZDogc3RyaW5nLCBjaGlsZFZhbHVlOiBUVmFsdWUpOiBGb3JtU3RhdGU8VFZhbHVlPiB7XHJcbiAgaWYgKGlzQm94ZWQoY2hpbGRWYWx1ZSkpIHtcclxuICAgIHJldHVybiBjcmVhdGVGb3JtQ29udHJvbFN0YXRlPGFueT4oaWQsIGNoaWxkVmFsdWUpIGFzIEZvcm1TdGF0ZTxUVmFsdWU+O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNoaWxkVmFsdWUgIT09IG51bGwgJiYgQXJyYXkuaXNBcnJheShjaGlsZFZhbHVlKSkge1xyXG4gICAgcmV0dXJuIGNyZWF0ZUZv