theme-lib
Version:
This is a simple example Angular Library published to npm.
571 lines • 42.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/*
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Directive, ElementRef, forwardRef, Inject, InjectionToken, Input } from '@angular/core';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR, Validators, } from '@angular/forms';
import { fromEvent, merge } from 'rxjs';
import { map, takeWhile, filter, take } from 'rxjs/operators';
import { NB_DOCUMENT } from '../../theme.options';
import { NbDateService } from '../calendar-kit';
/*
* The `NbDatepickerAdapter` instances provide way how to parse, format and validate
* different date types.
* */
/**
* @abstract
* @template D
*/
export class NbDatepickerAdapter {
}
if (false) {
/** @type {?} */
NbDatepickerAdapter.prototype.picker;
/**
* @abstract
* @param {?} value
* @param {?} format
* @return {?}
*/
NbDatepickerAdapter.prototype.parse = function (value, format) { };
/**
* @abstract
* @param {?} value
* @param {?} format
* @return {?}
*/
NbDatepickerAdapter.prototype.format = function (value, format) { };
/**
* @abstract
* @param {?} value
* @param {?} format
* @return {?}
*/
NbDatepickerAdapter.prototype.isValid = function (value, format) { };
}
/**
* @record
* @template D
*/
export function NbPickerValidatorConfig() { }
if (false) {
/** @type {?} */
NbPickerValidatorConfig.prototype.min;
/** @type {?} */
NbPickerValidatorConfig.prototype.max;
/** @type {?} */
NbPickerValidatorConfig.prototype.filter;
}
/*
* Datepicker is an control that can pick any values anyway.
* It has to be bound to the datepicker directive through nbDatepicker input.
* */
/**
* @abstract
* @template T
*/
export class NbDatepicker {
}
if (false) {
/** @type {?} */
NbDatepicker.prototype.format;
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.value = function () { };
/**
* @abstract
* @param {?} value
* @return {?}
*/
NbDatepicker.prototype.value = function (value) { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.valueChange = function () { };
/**
* @abstract
* @param {?} hostRef
* @return {?}
*/
NbDatepicker.prototype.attach = function (hostRef) { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.getValidatorConfig = function () { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.show = function () { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.hide = function () { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.shouldHide = function () { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.isShown = function () { };
/**
* @abstract
* @return {?}
*/
NbDatepicker.prototype.blur = function () { };
}
/** @type {?} */
export const NB_DATE_ADAPTER = new InjectionToken('Datepicker Adapter');
/*
* The `NbDatepickerDirective` is form control that gives you ability to select dates and ranges. The datepicker
* is shown when input receives a `focus` event.
*
* ```html
* <input [nbDatepicker]="datepicker">
* <nb-datepicker #datepicker></nb-datepicker>
* ```
*
* @stacked-example(Showcase, datepicker/datepicker-showcase.component)
*
* ### Installation
*
* Import `NbDatepickerModule.forRoot()` to your root module.
* ```ts
* @NgModule({
* imports: [
* // ...
* NbDatepickerModule.forRoot(),
* ],
* })
* export class AppModule { }
* ```
* And `NbDatepickerModule` to your feature module.
* ```ts
* @NgModule({
* imports: [
* // ...
* NbDatepickerModule,
* ],
* })
* export class PageModule { }
* ```
* ### Usage
*
* If you want to use range selection, you have to use `NbRangepickerComponent` instead:
*
* ```html
* <input [nbDatepicker]="rangepicker">
* <nb-rangepicker #rangepicker></nb-rangepicker>
* ```
*
* Both range and date pickers support all parameters as calendar, so, check `NbCalendarComponent` for additional
* info.
*
* @stacked-example(Range showcase, datepicker/rangepicker-showcase.component)
*
* Datepicker is the form control so it can be bound with angular forms through ngModel and form controls.
*
* @stacked-example(Forms, datepicker/datepicker-forms.component)
*
* `NbDatepickerDirective` may be validated using `min` and `max` dates passed to the datepicker.
* And `filter` predicate that receives date object and has to return a boolean value.
*
* @stacked-example(Validation, datepicker/datepicker-validation.component)
*
* The `NbDatepickerComponent` supports date formatting:
*
* ```html
* <input [nbDatepicker]="datepicker">
* <nb-datepicker #datepicker format="MM\dd\yyyy"></nb-datepicker>
* ```
*
* ## Formatting Issue
*
* By default, datepicker uses angulars `LOCALE_ID` token for localization and `DatePipe` for dates formatting.
* And native `Date.parse(...)` for dates parsing. But native `Date.parse` function doesn't support formats.
* To provide custom formatting you have to use one of the following packages:
*
* - `@nebular/moment` - provides moment date adapter that uses moment for date objects. This means datepicker than
* will operate only moment date objects. If you want to use it you have to install it: `npm i @nebular/moment`, and
* import `NbMomentDateModule` from this package.
*
* - `@nebular/date-fns` - adapter for popular date-fns library. This way is preferred if you need only date formatting.
* Because date-fns is treeshakable, tiny and operates native date objects. If you want to use it you have to
* install it: `npm i @nebular/date-fns`, and import `NbDateFnsDateModule` from this package.
*
* @styles
*
* datepicker-fg
* datepicker-bg
* datepicker-border
* datepicker-border-radius
* datepicker-shadow
* datepicker-arrow-size
* */
/**
* @template D
*/
export class NbDatepickerDirective {
/**
* @param {?} document
* @param {?} datepickerAdapters
* @param {?} hostRef
* @param {?} dateService
*/
constructor(document, datepickerAdapters, hostRef, dateService) {
this.document = document;
this.datepickerAdapters = datepickerAdapters;
this.hostRef = hostRef;
this.dateService = dateService;
this.alive = true;
this.onChange = () => { };
this.onTouched = () => { };
/*
* Form control validators will be called in validators context, so, we need to bind them.
* */
this.validator = Validators.compose([
this.parseValidator,
this.minValidator,
this.maxValidator,
this.filterValidator,
].map(fn => fn.bind(this)));
this.subscribeOnInputChange();
}
/*
* Provides datepicker component.
* */
/**
* @param {?} picker
* @return {?}
*/
set setPicker(picker) {
this.picker = picker;
this.setupPicker();
}
/*
* Returns html input element.
* */
/**
* @return {?}
*/
get input() {
return this.hostRef.nativeElement;
}
/*
* Returns host input value.
* */
/**
* @return {?}
*/
get inputValue() {
return this.input.value;
}
/**
* @return {?}
*/
ngOnDestroy() {
this.alive = false;
}
/*
* Writes value in picker and html input element.
* */
/**
* @param {?} value
* @return {?}
*/
writeValue(value) {
this.writePicker(value);
this.writeInput(value);
}
/**
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
this.input.disabled = isDisabled;
}
/*
* Form control validation based on picker validator config.
* */
/**
* @return {?}
*/
validate() {
return this.validator(null);
}
/*
* Hides picker, focuses the input
*/
/**
* @protected
* @return {?}
*/
hidePicker() {
this.input.focus();
this.picker.hide();
}
/*
* Validates that we can parse value correctly.
* */
/**
* @protected
* @return {?}
*/
parseValidator() {
/** @type {?} */
const isValid = this.datepickerAdapter.isValid(this.inputValue, this.picker.format);
return isValid ? null : { nbDatepickerParse: { value: this.inputValue } };
}
/*
* Validates passed value is greater than min.
* */
/**
* @protected
* @return {?}
*/
minValidator() {
/** @type {?} */
const config = this.picker.getValidatorConfig();
/** @type {?} */
const date = this.datepickerAdapter.parse(this.inputValue, this.picker.format);
return (!config.min || !date || this.dateService.compareDates(config.min, date) <= 0) ?
null : { nbDatepickerMin: { min: config.min, actual: date } };
}
/*
* Validates passed value is smaller than max.
* */
/**
* @protected
* @return {?}
*/
maxValidator() {
/** @type {?} */
const config = this.picker.getValidatorConfig();
/** @type {?} */
const date = this.datepickerAdapter.parse(this.inputValue, this.picker.format);
return (!config.max || !date || this.dateService.compareDates(config.max, date) >= 0) ?
null : { nbDatepickerMax: { max: config.max, actual: date } };
}
/*
* Validates passed value satisfy the filter.
* */
/**
* @protected
* @return {?}
*/
filterValidator() {
/** @type {?} */
const config = this.picker.getValidatorConfig();
/** @type {?} */
const date = this.datepickerAdapter.parse(this.inputValue, this.picker.format);
return (!config.filter || !date || config.filter(date)) ?
null : { nbDatepickerFilter: true };
}
/*
* Chooses datepicker adapter based on passed picker component.
* */
/**
* @protected
* @return {?}
*/
chooseDatepickerAdapter() {
this.datepickerAdapter = this.datepickerAdapters.find(({ picker }) => this.picker instanceof picker);
if (this.noDatepickerAdapterProvided()) {
throw new Error('No datepickerAdapter provided for picker');
}
}
/*
* Attaches picker to the host input element and subscribes on value changes.
* */
/**
* @protected
* @return {?}
*/
setupPicker() {
this.chooseDatepickerAdapter();
this.picker.attach(this.hostRef);
if (this.hostRef.nativeElement.value) {
this.picker.value = this.datepickerAdapter.parse(this.hostRef.nativeElement.value, this.picker.format);
}
this.picker.valueChange
.pipe(takeWhile(() => this.alive))
.subscribe((value) => {
this.writePicker(value);
this.writeInput(value);
this.onChange(value);
if (this.picker.shouldHide()) {
this.hidePicker();
}
});
merge(this.picker.blur, fromEvent(this.input, 'blur').pipe(filter(() => !this.picker.isShown && this.document.activeElement !== this.input))).pipe(takeWhile(() => this.alive), take(1)).subscribe(() => this.onTouched());
}
/**
* @protected
* @param {?} value
* @return {?}
*/
writePicker(value) {
this.picker.value = value;
}
/**
* @protected
* @param {?} value
* @return {?}
*/
writeInput(value) {
/** @type {?} */
const stringRepresentation = this.datepickerAdapter.format(value, this.picker.format);
this.hostRef.nativeElement.value = stringRepresentation;
}
/*
* Validates if no datepicker adapter provided.
* */
/**
* @protected
* @return {?}
*/
noDatepickerAdapterProvided() {
return !this.datepickerAdapter || !(this.datepickerAdapter instanceof NbDatepickerAdapter);
}
/**
* @protected
* @return {?}
*/
subscribeOnInputChange() {
fromEvent(this.input, 'input')
.pipe(map(() => this.inputValue), takeWhile(() => this.alive))
.subscribe((value) => this.handleInputChange(value));
}
/*
* Parses input value and write if it isn't null.
* */
/**
* @protected
* @param {?} value
* @return {?}
*/
handleInputChange(value) {
/** @type {?} */
const date = this.parseInputValue(value);
this.onChange(date);
this.writePicker(date);
}
/**
* @protected
* @param {?} value
* @return {?}
*/
parseInputValue(value) {
if (this.datepickerAdapter.isValid(value, this.picker.format)) {
return this.datepickerAdapter.parse(value, this.picker.format);
}
return null;
}
}
NbDatepickerDirective.decorators = [
{ type: Directive, args: [{
selector: 'input[nbDatepicker]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NbDatepickerDirective),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => NbDatepickerDirective),
multi: true,
},
],
},] }
];
/** @nocollapse */
NbDatepickerDirective.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] },
{ type: Array, decorators: [{ type: Inject, args: [NB_DATE_ADAPTER,] }] },
{ type: ElementRef },
{ type: NbDateService }
];
NbDatepickerDirective.propDecorators = {
setPicker: [{ type: Input, args: ['nbDatepicker',] }]
};
if (false) {
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.datepickerAdapter;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.picker;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.alive;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.onChange;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.onTouched;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.validator;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.document;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.datepickerAdapters;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.hostRef;
/**
* @type {?}
* @protected
*/
NbDatepickerDirective.prototype.dateService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9kYXRlcGlja2VyL2RhdGVwaWNrZXIuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQU1BLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUM1RyxPQUFPLEVBRUwsYUFBYSxFQUNiLGlCQUFpQixFQUlqQixVQUFVLEdBQ1gsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQUUsU0FBUyxFQUFjLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7Ozs7O0FBT2hELE1BQU0sT0FBZ0IsbUJBQW1CO0NBb0J4Qzs7O0lBaEJDLHFDQUEyQjs7Ozs7OztJQUszQixtRUFBaUQ7Ozs7Ozs7SUFLakQsb0VBQWtEOzs7Ozs7O0lBS2xELHFFQUF5RDs7Ozs7O0FBTTNELDZDQWVDOzs7SUFYQyxzQ0FBTzs7SUFLUCxzQ0FBTzs7SUFLUCx5Q0FBdUI7Ozs7Ozs7Ozs7QUFPekIsTUFBTSxPQUFnQixZQUFZO0NBK0JqQzs7O0lBM0JDLDhCQUF3Qjs7Ozs7SUFFeEIsK0NBQXdCOzs7Ozs7SUFFeEIsb0RBQTZCOzs7OztJQUU3QixxREFBMEM7Ozs7OztJQUsxQyx1REFBcUM7Ozs7O0lBS3JDLDREQUEwRDs7Ozs7SUFFMUQsOENBQWdCOzs7OztJQUVoQiw4Q0FBZ0I7Ozs7O0lBRWhCLG9EQUErQjs7Ozs7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QkFBcUI7Z0JBQy9CLFNBQVMsRUFBRTtvQkFDVDt3QkFDRSxPQUFPLEVBQUUsaUJBQWlCO3dCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixDQUFDO3dCQUNwRCxLQUFLLEVBQUUsSUFBSTtxQkFDWjtvQkFDRDt3QkFDRSxPQUFPLEVBQUUsYUFBYTt3QkFDdEIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQzt3QkFDcEQsS0FBSyxFQUFFLElBQUk7cUJBQ1o7aUJBQ0Y7YUFDRjs7Ozs0Q0FrQ2MsTUFBTSxTQUFDLFdBQVc7d0NBQ2xCLE1BQU0sU0FBQyxlQUFlO1lBL09qQixVQUFVO1lBZXJCLGFBQWE7Ozt3QkFrTW5CLEtBQUssU0FBQyxjQUFjOzs7Ozs7O0lBU3JCLGtEQUFvRDs7Ozs7SUFLcEQsdUNBQWtDOzs7OztJQUNsQyxzQ0FBZ0M7Ozs7O0lBQ2hDLHlDQUEyQzs7Ozs7SUFDM0MsMENBQTJDOzs7OztJQUszQywwQ0FLNEI7Ozs7O0lBRWhCLHlDQUF1Qzs7Ozs7SUFDdkMsbURBQStFOzs7OztJQUMvRSx3Q0FBNkI7Ozs7O0lBQzdCLDRDQUF1QyIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIEBsaWNlbnNlXHJcbiAqIENvcHlyaWdodCBBa3Zlby4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuICovXHJcblxyXG5pbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIGZvcndhcmRSZWYsIEluamVjdCwgSW5qZWN0aW9uVG9rZW4sIElucHV0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtcclxuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcclxuICBOR19WQUxJREFUT1JTLFxyXG4gIE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gIFZhbGlkYXRpb25FcnJvcnMsXHJcbiAgVmFsaWRhdG9yLFxyXG4gIFZhbGlkYXRvckZuLFxyXG4gIFZhbGlkYXRvcnMsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9zcmMvdHlwZSc7XHJcbmltcG9ydCB7IGZyb21FdmVudCwgT2JzZXJ2YWJsZSwgbWVyZ2UgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgbWFwLCB0YWtlV2hpbGUsIGZpbHRlciwgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IE5CX0RPQ1VNRU5UIH0gZnJvbSAnLi4vLi4vdGhlbWUub3B0aW9ucyc7XHJcbmltcG9ydCB7IE5iRGF0ZVNlcnZpY2UgfSBmcm9tICcuLi9jYWxlbmRhci1raXQnO1xyXG5cclxuXHJcbi8qXHJcbiAqIFRoZSBgTmJEYXRlcGlja2VyQWRhcHRlcmAgaW5zdGFuY2VzIHByb3ZpZGUgd2F5IGhvdyB0byBwYXJzZSwgZm9ybWF0IGFuZCB2YWxpZGF0ZVxyXG4gKiBkaWZmZXJlbnQgZGF0ZSB0eXBlcy5cclxuICogKi9cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE5iRGF0ZXBpY2tlckFkYXB0ZXI8RD4ge1xyXG4gIC8qXHJcbiAgICogUGlja2VyIGNvbXBvbmVudCBjbGFzcy5cclxuICAgKiAqL1xyXG4gIGFic3RyYWN0IHBpY2tlcjogVHlwZTxhbnk+O1xyXG5cclxuICAvKlxyXG4gICAqIFBhcnNlIGRhdGUgc3RyaW5nIGFjY29yZGluZyB0byB0aGUgZm9ybWF0LlxyXG4gICAqICovXHJcbiAgYWJzdHJhY3QgcGFyc2UodmFsdWU6IHN0cmluZywgZm9ybWF0OiBzdHJpbmcpOiBEO1xyXG5cclxuICAvKlxyXG4gICAqIEZvcm1hdCBkYXRlIGFjY29yZGluZyB0byB0aGUgZm9ybWF0LlxyXG4gICAqICovXHJcbiAgYWJzdHJhY3QgZm9ybWF0KHZhbHVlOiBELCBmb3JtYXQ6IHN0cmluZyk6IHN0cmluZztcclxuXHJcbiAgLypcclxuICAgKiBWYWxpZGF0ZXMgZGF0ZSBzdHJpbmcgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgZm9ybWF0LlxyXG4gICAqICovXHJcbiAgYWJzdHJhY3QgaXNWYWxpZCh2YWx1ZTogc3RyaW5nLCBmb3JtYXQ6IHN0cmluZyk6IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qXHJcbiAqIFZhbGlkYXRvcnMgY29uZmlnIHRoYXQgd2lsbCBiZSB1c2VkIGJ5IGZvcm0gY29udHJvbCB0byBwZXJmb3JtIHByb3BlciB2YWxpZGF0aW9uLlxyXG4gKiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIE5iUGlja2VyVmFsaWRhdG9yQ29uZmlnPEQ+IHtcclxuICAvKlxyXG4gICAqIE1pbmltdW0gZGF0ZSBhdmFpbGFibGUgaW4gcGlja2VyLlxyXG4gICAqICovXHJcbiAgbWluOiBEO1xyXG5cclxuICAvKlxyXG4gICAqIE1heGltdW0gZGF0ZSBhdmFpbGFibGUgaW4gcGlja2VyLlxyXG4gICAqICovXHJcbiAgbWF4OiBEO1xyXG5cclxuICAvKlxyXG4gICAqIFByZWRpY2F0ZSB0aGF0IGRldGVybWluZXMgaXMgdmFsdWUgYXZhaWxhYmxlIGZvciBwaWNraW5nLlxyXG4gICAqICovXHJcbiAgZmlsdGVyOiAoRCkgPT4gYm9vbGVhbjtcclxufVxyXG5cclxuLypcclxuICogRGF0ZXBpY2tlciBpcyBhbiBjb250cm9sIHRoYXQgY2FuIHBpY2sgYW55IHZhbHVlcyBhbnl3YXkuXHJcbiAqIEl0IGhhcyB0byBiZSBib3VuZCB0byB0aGUgZGF0ZXBpY2tlciBkaXJlY3RpdmUgdGhyb3VnaCBuYkRhdGVwaWNrZXIgaW5wdXQuXHJcbiAqICovXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBOYkRhdGVwaWNrZXI8VD4ge1xyXG4gIC8qXHJcbiAgICogSFRNTCBpbnB1dCBlbGVtZW50IGRhdGUgZm9ybWF0LlxyXG4gICAqICovXHJcbiAgYWJzdHJhY3QgZm9ybWF0OiBzdHJpbmc7XHJcblxyXG4gIGFic3RyYWN0IGdldCB2YWx1ZSgpOiBUO1xyXG5cclxuICBhYnN0cmFjdCBzZXQgdmFsdWUodmFsdWU6IFQpO1xyXG5cclxuICBhYnN0cmFjdCBnZXQgdmFsdWVDaGFuZ2UoKTogT2JzZXJ2YWJsZTxUPjtcclxuXHJcbiAgLypcclxuICAgKiBBdHRhY2hlcyBkYXRlcGlja2VyIHRvIHRoZSBuYXRpdmUgaW5wdXQgZWxlbWVudC5cclxuICAgKiAqL1xyXG4gIGFic3RyYWN0IGF0dGFjaChob3N0UmVmOiBFbGVtZW50UmVmKTtcclxuXHJcbiAgLypcclxuICAgKiBSZXR1cm5zIHZhbGlkYXRvciBjb25maWd1cmF0aW9uIGJhc2VkIG9uIHRoZSBpbnB1dCBwcm9wZXJ0aWVzLlxyXG4gICAqICovXHJcbiAgYWJzdHJhY3QgZ2V0VmFsaWRhdG9yQ29uZmlnKCk6IE5iUGlja2VyVmFsaWRhdG9yQ29uZmlnPFQ+O1xyXG5cclxuICBhYnN0cmFjdCBzaG93KCk7XHJcblxyXG4gIGFic3RyYWN0IGhpZGUoKTtcclxuXHJcbiAgYWJzdHJhY3Qgc2hvdWxkSGlkZSgpOiBib29sZWFuO1xyXG5cclxuICBhYnN0cmFjdCBnZXQgaXNTaG93bigpOiBib29sZWFuO1xyXG5cclxuICBhYnN0cmFjdCBnZXQgYmx1cigpOiBPYnNlcnZhYmxlPHZvaWQ+O1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgTkJfREFURV9BREFQVEVSID0gbmV3IEluamVjdGlvblRva2VuPE5iRGF0ZXBpY2tlckFkYXB0ZXI8YW55Pj4oJ0RhdGVwaWNrZXIgQWRhcHRlcicpO1xyXG5cclxuXHJcbi8qXHJcbiAqIFRoZSBgTmJEYXRlcGlja2VyRGlyZWN0aXZlYCBpcyBmb3JtIGNvbnRyb2wgdGhhdCBnaXZlcyB5b3UgYWJpbGl0eSB0byBzZWxlY3QgZGF0ZXMgYW5kIHJhbmdlcy4gVGhlIGRhdGVwaWNrZXJcclxuICogaXMgc2hvd24gd2hlbiBpbnB1dCByZWNlaXZlcyBhIGBmb2N1c2AgZXZlbnQuXHJcbiAqXHJcbiAqIGBgYGh0bWxcclxuICogPGlucHV0IFtuYkRhdGVwaWNrZXJdPVwiZGF0ZXBpY2tlclwiPlxyXG4gKiA8bmItZGF0ZXBpY2tlciAjZGF0ZXBpY2tlcj48L25iLWRhdGVwaWNrZXI+XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFNob3djYXNlLCBkYXRlcGlja2VyL2RhdGVwaWNrZXItc2hvd2Nhc2UuY29tcG9uZW50KVxyXG4gKlxyXG4gKiAjIyMgSW5zdGFsbGF0aW9uXHJcbiAqXHJcbiAqIEltcG9ydCBgTmJEYXRlcGlja2VyTW9kdWxlLmZvclJvb3QoKWAgdG8geW91ciByb290IG1vZHVsZS5cclxuICogYGBgdHNcclxuICogQE5nTW9kdWxlKHtcclxuICogICBpbXBvcnRzOiBbXHJcbiAqICAgXHQvLyAuLi5cclxuICogICAgIE5iRGF0ZXBpY2tlck1vZHVsZS5mb3JSb290KCksXHJcbiAqICAgXSxcclxuICogfSlcclxuICogZXhwb3J0IGNsYXNzIEFwcE1vZHVsZSB7IH1cclxuICogYGBgXHJcbiAqIEFuZCBgTmJEYXRlcGlja2VyTW9kdWxlYCB0byB5b3VyIGZlYXR1cmUgbW9kdWxlLlxyXG4gKiBgYGB0c1xyXG4gKiBATmdNb2R1bGUoe1xyXG4gKiAgIGltcG9ydHM6IFtcclxuICogICBcdC8vIC4uLlxyXG4gKiAgICAgTmJEYXRlcGlja2VyTW9kdWxlLFxyXG4gKiAgIF0sXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBQYWdlTW9kdWxlIHsgfVxyXG4gKiBgYGBcclxuICogIyMjIFVzYWdlXHJcbiAqXHJcbiAqIElmIHlvdSB3YW50IHRvIHVzZSByYW5nZSBzZWxlY3Rpb24sIHlvdSBoYXZlIHRvIHVzZSBgTmJSYW5nZXBpY2tlckNvbXBvbmVudGAgaW5zdGVhZDpcclxuICpcclxuICogYGBgaHRtbFxyXG4gKiA8aW5wdXQgW25iRGF0ZXBpY2tlcl09XCJyYW5nZXBpY2tlclwiPlxyXG4gKiA8bmItcmFuZ2VwaWNrZXIgI3JhbmdlcGlja2VyPjwvbmItcmFuZ2VwaWNrZXI+XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBCb3RoIHJhbmdlIGFuZCBkYXRlIHBpY2tlcnMgc3VwcG9ydCBhbGwgcGFyYW1ldGVycyBhcyBjYWxlbmRhciwgc28sIGNoZWNrIGBOYkNhbGVuZGFyQ29tcG9uZW50YCBmb3IgYWRkaXRpb25hbFxyXG4gKiBpbmZvLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFJhbmdlIHNob3djYXNlLCBkYXRlcGlja2VyL3JhbmdlcGlja2VyLXNob3djYXNlLmNvbXBvbmVudClcclxuICpcclxuICogRGF0ZXBpY2tlciBpcyB0aGUgZm9ybSBjb250cm9sIHNvIGl0IGNhbiBiZSBib3VuZCB3aXRoIGFuZ3VsYXIgZm9ybXMgdGhyb3VnaCBuZ01vZGVsIGFuZCBmb3JtIGNvbnRyb2xzLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKEZvcm1zLCBkYXRlcGlja2VyL2RhdGVwaWNrZXItZm9ybXMuY29tcG9uZW50KVxyXG4gKlxyXG4gKiBgTmJEYXRlcGlja2VyRGlyZWN0aXZlYCBtYXkgYmUgdmFsaWRhdGVkIHVzaW5nIGBtaW5gIGFuZCBgbWF4YCBkYXRlcyBwYXNzZWQgdG8gdGhlIGRhdGVwaWNrZXIuXHJcbiAqIEFuZCBgZmlsdGVyYCBwcmVkaWNhdGUgdGhhdCByZWNlaXZlcyBkYXRlIG9iamVjdCBhbmQgaGFzIHRvIHJldHVybiBhIGJvb2xlYW4gdmFsdWUuXHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoVmFsaWRhdGlvbiwgZGF0ZXBpY2tlci9kYXRlcGlja2VyLXZhbGlkYXRpb24uY29tcG9uZW50KVxyXG4gKlxyXG4gKiBUaGUgYE5iRGF0ZXBpY2tlckNvbXBvbmVudGAgc3VwcG9ydHMgZGF0ZSBmb3JtYXR0aW5nOlxyXG4gKlxyXG4gKiBgYGBodG1sXHJcbiAqIDxpbnB1dCBbbmJEYXRlcGlja2VyXT1cImRhdGVwaWNrZXJcIj5cclxuICogPG5iLWRhdGVwaWNrZXIgI2RhdGVwaWNrZXIgZm9ybWF0PVwiTU1cXGRkXFx5eXl5XCI+PC9uYi1kYXRlcGlja2VyPlxyXG4gKiBgYGBcclxuICpcclxuICogIyMgRm9ybWF0dGluZyBJc3N1ZVxyXG4gKlxyXG4gKiBCeSBkZWZhdWx0LCBkYXRlcGlja2VyIHVzZXMgYW5ndWxhcnMgYExPQ0FMRV9JRGAgdG9rZW4gZm9yIGxvY2FsaXphdGlvbiBhbmQgYERhdGVQaXBlYCBmb3IgZGF0ZXMgZm9ybWF0dGluZy5cclxuICogQW5kIG5hdGl2ZSBgRGF0ZS5wYXJzZSguLi4pYCBmb3IgZGF0ZXMgcGFyc2luZy4gQnV0IG5hdGl2ZSBgRGF0ZS5wYXJzZWAgZnVuY3Rpb24gZG9lc24ndCBzdXBwb3J0IGZvcm1hdHMuXHJcbiAqIFRvIHByb3ZpZGUgY3VzdG9tIGZvcm1hdHRpbmcgeW91IGhhdmUgdG8gdXNlIG9uZSBvZiB0aGUgZm9sbG93aW5nIHBhY2thZ2VzOlxyXG4gKlxyXG4gKiAtIGBAbmVidWxhci9tb21lbnRgIC0gcHJvdmlkZXMgbW9tZW50IGRhdGUgYWRhcHRlciB0aGF0IHVzZXMgbW9tZW50IGZvciBkYXRlIG9iamVjdHMuIFRoaXMgbWVhbnMgZGF0ZXBpY2tlciB0aGFuXHJcbiAqIHdpbGwgb3BlcmF0ZSBvbmx5IG1vbWVudCBkYXRlIG9iamVjdHMuIElmIHlvdSB3YW50IHRvIHVzZSBpdCB5b3UgaGF2ZSB0byBpbnN0YWxsIGl0OiBgbnBtIGkgQG5lYnVsYXIvbW9tZW50YCwgYW5kXHJcbiAqIGltcG9ydCBgTmJNb21lbnREYXRlTW9kdWxlYCBmcm9tIHRoaXMgcGFja2FnZS5cclxuICpcclxuICogLSBgQG5lYnVsYXIvZGF0ZS1mbnNgIC0gYWRhcHRlciBmb3IgcG9wdWxhciBkYXRlLWZucyBsaWJyYXJ5LiBUaGlzIHdheSBpcyBwcmVmZXJyZWQgaWYgeW91IG5lZWQgb25seSBkYXRlIGZvcm1hdHRpbmcuXHJcbiAqIEJlY2F1c2UgZGF0ZS1mbnMgaXMgdHJlZXNoYWthYmxlLCB0aW55IGFuZCBvcGVyYXRlcyBuYXRpdmUgZGF0ZSBvYmplY3RzLiBJZiB5b3Ugd2FudCB0byB1c2UgaXQgeW91IGhhdmUgdG9cclxuICogaW5zdGFsbCBpdDogYG5wbSBpIEBuZWJ1bGFyL2RhdGUtZm5zYCwgYW5kIGltcG9ydCBgTmJEYXRlRm5zRGF0ZU1vZHVsZWAgZnJvbSB0aGlzIHBhY2thZ2UuXHJcbiAqXHJcbiAqIEBzdHlsZXNcclxuICpcclxuICogZGF0ZXBpY2tlci1mZ1xyXG4gKiBkYXRlcGlja2VyLWJnXHJcbiAqIGRhdGVwaWNrZXItYm9yZGVyXHJcbiAqIGRhdGVwaWNrZXItYm9yZGVyLXJhZGl1c1xyXG4gKiBkYXRlcGlja2VyLXNoYWRvd1xyXG4gKiBkYXRlcGlja2VyLWFycm93LXNpemVcclxuICogKi9cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdpbnB1dFtuYkRhdGVwaWNrZXJdJyxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5iRGF0ZXBpY2tlckRpcmVjdGl2ZSksXHJcbiAgICAgIG11bHRpOiB0cnVlLFxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcclxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmJEYXRlcGlja2VyRGlyZWN0aXZlKSxcclxuICAgICAgbXVsdGk6IHRydWUsXHJcbiAgICB9LFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOYkRhdGVwaWNrZXJEaXJlY3RpdmU8RD4gaW1wbGVtZW50cyBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBWYWxpZGF0b3Ige1xyXG4gIC8qXHJcbiAgICogUHJvdmlkZXMgZGF0ZXBpY2tlciBjb21wb25lbnQuXHJcbiAgICogKi9cclxuICBASW5wdXQoJ25iRGF0ZXBpY2tlcicpXHJcbiAgc2V0IHNldFBpY2tlcihwaWNrZXI6IE5iRGF0ZXBpY2tlcjxEPikge1xyXG4gICAgdGhpcy5waWNrZXIgPSBwaWNrZXI7XHJcbiAgICB0aGlzLnNldHVwUGlja2VyKCk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIERhdGVwaWNrZXIgYWRhcHRlci5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBkYXRlcGlja2VyQWRhcHRlcjogTmJEYXRlcGlja2VyQWRhcHRlcjxEPjtcclxuXHJcbiAgLypcclxuICAgKiBEYXRlcGlja2VyIGluc3RhbmNlLlxyXG4gICAqICovXHJcbiAgcHJvdGVjdGVkIHBpY2tlcjogTmJEYXRlcGlja2VyPEQ+O1xyXG4gIHByb3RlY3RlZCBhbGl2ZTogYm9vbGVhbiA9IHRydWU7XHJcbiAgcHJvdGVjdGVkIG9uQ2hhbmdlOiAoRCkgPT4gdm9pZCA9ICgpID0+IHt9O1xyXG4gIHByb3RlY3RlZCBvblRvdWNoZWQ6ICgpID0+IHZvaWQgPSAoKSA9PiB7fTtcclxuXHJcbiAgLypcclxuICAgKiBGb3JtIGNvbnRyb2wgdmFsaWRhdG9ycyB3aWxsIGJlIGNhbGxlZCBpbiB2YWxpZGF0b3JzIGNvbnRleHQsIHNvLCB3ZSBuZWVkIHRvIGJpbmQgdGhlbS5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCB2YWxpZGF0b3I6IFZhbGlkYXRvckZuID0gVmFsaWRhdG9ycy5jb21wb3NlKFtcclxuICAgIHRoaXMucGFyc2VWYWxpZGF0b3IsXHJcbiAgICB0aGlzLm1pblZhbGlkYXRvcixcclxuICAgIHRoaXMubWF4VmFsaWRhdG9yLFxyXG4gICAgdGhpcy5maWx0ZXJWYWxpZGF0b3IsXHJcbiAgXS5tYXAoZm4gPT4gZm4uYmluZCh0aGlzKSkpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihASW5qZWN0KE5CX0RPQ1VNRU5UKSBwcm90ZWN0ZWQgZG9jdW1lbnQsXHJcbiAgICAgICAgICAgICAgQEluamVjdChOQl9EQVRFX0FEQVBURVIpIHByb3RlY3RlZCBkYXRlcGlja2VyQWRhcHRlcnM6IE5iRGF0ZXBpY2tlckFkYXB0ZXI8RD5bXSxcclxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgaG9zdFJlZjogRWxlbWVudFJlZixcclxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgZGF0ZVNlcnZpY2U6IE5iRGF0ZVNlcnZpY2U8RD4pIHtcclxuICAgIHRoaXMuc3Vic2NyaWJlT25JbnB1dENoYW5nZSgpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBSZXR1cm5zIGh0bWwgaW5wdXQgZWxlbWVudC5cclxuICAgKiAqL1xyXG4gIGdldCBpbnB1dCgpOiBIVE1MSW5wdXRFbGVtZW50IHtcclxuICAgIHJldHVybiB0aGlzLmhvc3RSZWYubmF0aXZlRWxlbWVudDtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogUmV0dXJucyBob3N0IGlucHV0IHZhbHVlLlxyXG4gICAqICovXHJcbiAgZ2V0IGlucHV0VmFsdWUoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmlucHV0LnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmFsaXZlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFdyaXRlcyB2YWx1ZSBpbiBwaWNrZXIgYW5kIGh0bWwgaW5wdXQgZWxlbWVudC5cclxuICAgKiAqL1xyXG4gIHdyaXRlVmFsdWUodmFsdWU6IEQpIHtcclxuICAgIHRoaXMud3JpdGVQaWNrZXIodmFsdWUpO1xyXG4gICAgdGhpcy53cml0ZUlucHV0KHZhbHVlKTtcclxuICB9XHJcblxyXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcclxuICB9XHJcblxyXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5pbnB1dC5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIEZvcm0gY29udHJvbCB2YWxpZGF0aW9uIGJhc2VkIG9uIHBpY2tlciB2YWxpZGF0b3IgY29uZmlnLlxyXG4gICAqICovXHJcbiAgdmFsaWRhdGUoKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdG9yKG51bGwpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBIaWRlcyBwaWNrZXIsIGZvY3VzZXMgdGhlIGlucHV0XHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGhpZGVQaWNrZXIoKSB7XHJcbiAgICB0aGlzLmlucHV0LmZvY3VzKCk7XHJcbiAgICB0aGlzLnBpY2tlci5oaWRlKCk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFZhbGlkYXRlcyB0aGF0IHdlIGNhbiBwYXJzZSB2YWx1ZSBjb3JyZWN0bHkuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgcGFyc2VWYWxpZGF0b3IoKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG4gICAgY29uc3QgaXNWYWxpZCA9IHRoaXMuZGF0ZXBpY2tlckFkYXB0ZXIuaXNWYWxpZCh0aGlzLmlucHV0VmFsdWUsIHRoaXMucGlja2VyLmZvcm1hdCk7XHJcbiAgICByZXR1cm4gaXNWYWxpZCA/IG51bGwgOiB7IG5iRGF0ZXBpY2tlclBhcnNlOiB7IHZhbHVlOiB0aGlzLmlucHV0VmFsdWUgfSB9O1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBWYWxpZGF0ZXMgcGFzc2VkIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBtaW4uXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgbWluVmFsaWRhdG9yKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcclxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMucGlja2VyLmdldFZhbGlkYXRvckNvbmZpZygpO1xyXG4gICAgY29uc3QgZGF0ZSA9IHRoaXMuZGF0ZXBpY2tlckFkYXB0ZXIucGFyc2UodGhpcy5pbnB1dFZhbHVlLCB0aGlzLnBpY2tlci5mb3JtYXQpO1xyXG4gICAgcmV0dXJuICghY29uZmlnLm1pbiB8fCAhZGF0ZSB8fCB0aGlzLmRhdGVTZXJ2aWNlLmNvbXBhcmVEYXRlcyhjb25maWcubWluLCBkYXRlKSA8PSAwKSA/XHJcbiAgICAgIG51bGwgOiB7IG5iRGF0ZXBpY2tlck1pbjogeyBtaW46IGNvbmZpZy5taW4sIGFjdHVhbDogZGF0ZSB9IH07XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFZhbGlkYXRlcyBwYXNzZWQgdmFsdWUgaXMgc21hbGxlciB0aGFuIG1heC5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBtYXhWYWxpZGF0b3IoKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5waWNrZXIuZ2V0VmFsaWRhdG9yQ29uZmlnKCk7XHJcbiAgICBjb25zdCBkYXRlID0gdGhpcy5kYXRlcGlja2VyQWRhcHRlci5wYXJzZSh0aGlzLmlucHV0VmFsdWUsIHRoaXMucGlja2VyLmZvcm1hdCk7XHJcbiAgICByZXR1cm4gKCFjb25maWcubWF4IHx8ICFkYXRlIHx8IHRoaXMuZGF0ZVNlcnZpY2UuY29tcGFyZURhdGVzKGNvbmZpZy5tYXgsIGRhdGUpID49IDApID9cclxuICAgICAgbnVsbCA6IHsgbmJEYXRlcGlja2VyTWF4OiB7IG1heDogY29uZmlnLm1heCwgYWN0dWFsOiBkYXRlIH0gfTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogVmFsaWRhdGVzIHBhc3NlZCB2YWx1ZSBzYXRpc2Z5IHRoZSBmaWx0ZXIuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgZmlsdGVyVmFsaWRhdG9yKCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcclxuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMucGlja2VyLmdldFZhbGlkYXRvckNvbmZpZygpO1xyXG4gICAgY29uc3QgZGF0ZSA9IHRoaXMuZGF0ZXBpY2tlckFkYXB0ZXIucGFyc2UodGhpcy5pbnB1dFZhbHVlLCB0aGlzLnBpY2tlci5mb3JtYXQpO1xyXG4gICAgcmV0dXJuICghY29uZmlnLmZpbHRlciB8fCAhZGF0ZSB8fCBjb25maWcuZmlsdGVyKGRhdGUpKSA/XHJcbiAgICAgIG51bGwgOiB7IG5iRGF0ZXBpY2tlckZpbHRlcjogdHJ1ZSB9O1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBDaG9vc2VzIGRhdGVwaWNrZXIgYWRhcHRlciBiYXNlZCBvbiBwYXNzZWQgcGlja2VyIGNvbXBvbmVudC5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBjaG9vc2VEYXRlcGlja2VyQWRhcHRlcigpIHtcclxuICAgIHRoaXMuZGF0ZXBpY2tlckFkYXB0ZXIgPSB0aGlzLmRhdGVwaWNrZXJBZGFwdGVycy5maW5kKCh7IHBpY2tlciB9KSA9PiB0aGlzLnBpY2tlciBpbnN0YW5jZW9mIHBpY2tlcik7XHJcblxyXG4gICAgaWYgKHRoaXMubm9EYXRlcGlja2VyQWRhcHRlclByb3ZpZGVkKCkpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBkYXRlcGlja2VyQWRhcHRlciBwcm92aWRlZCBmb3IgcGlja2VyJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIEF0dGFjaGVzIHBpY2tlciB0byB0aGUgaG9zdCBpbnB1dCBlbGVtZW50IGFuZCBzdWJzY3JpYmVzIG9uIHZhbHVlIGNoYW5nZXMuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgc2V0dXBQaWNrZXIoKSB7XHJcbiAgICB0aGlzLmNob29zZURhdGVwaWNrZXJBZGFwdGVyKCk7XHJcbiAgICB0aGlzLnBpY2tlci5hdHRhY2godGhpcy5ob3N0UmVmKTtcclxuXHJcbiAgICBpZiAodGhpcy5ob3N0UmVmLm5hdGl2ZUVsZW1lbnQudmFsdWUpIHtcclxuICAgICAgdGhpcy5waWNrZXIudmFsdWUgPSB0aGlzLmRhdGVwaWNrZXJBZGFwdGVyLnBhcnNlKHRoaXMuaG9zdFJlZi5uYXRpdmVFbGVtZW50LnZhbHVlLCB0aGlzLnBpY2tlci5mb3JtYXQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMucGlja2VyLnZhbHVlQ2hhbmdlXHJcbiAgICAgIC5waXBlKHRha2VXaGlsZSgoKSA9PiB0aGlzLmFsaXZlKSlcclxuICAgICAgLnN1YnNjcmliZSgodmFsdWU6IEQpID0+IHtcclxuICAgICAgICB0aGlzLndyaXRlUGlja2VyKHZhbHVlKTtcclxuICAgICAgICB0aGlzLndyaXRlSW5wdXQodmFsdWUpO1xyXG4gICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5waWNrZXIuc2hvdWxkSGlkZSgpKSB7XHJcbiAgICAgICAgICB0aGlzLmhpZGVQaWNrZXIoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIG1lcmdlKFxyXG4gICAgICB0aGlzLnBpY2tlci5ibHVyLFxyXG4gICAgICBmcm9tRXZlbnQodGhpcy5pbnB1dCwgJ2JsdXInKS5waXBlKFxyXG4gICAgICAgIGZpbHRlcigoKSA9PiAhdGhpcy5waWNrZXIuaXNTaG93biAmJiB0aGlzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgIT09IHRoaXMuaW5wdXQpLFxyXG4gICAgICApLFxyXG4gICAgKS5waXBlKFxyXG4gICAgICB0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSksXHJcbiAgICAgIHRha2UoMSksXHJcbiAgICApLnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uVG91Y2hlZCgpKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCB3cml0ZVBpY2tlcih2YWx1ZTogRCkge1xyXG4gICAgdGhpcy5waWNrZXIudmFsdWUgPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCB3cml0ZUlucHV0KHZhbHVlOiBEKSB7XHJcbiAgICBjb25zdCBzdHJpbmdSZXByZXNlbnRhdGlvbiA9IHRoaXMuZGF0ZXBpY2tlckFkYXB0ZXIuZm9ybWF0KHZhbHVlLCB0aGlzLnBpY2tlci5mb3JtYXQpO1xyXG4gICAgdGhpcy5ob3N0UmVmLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSBzdHJpbmdSZXByZXNlbnRhdGlvbjtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogVmFsaWRhdGVzIGlmIG5vIGRhdGVwaWNrZXIgYWRhcHRlciBwcm92aWRlZC5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBub0RhdGVwaWNrZXJBZGFwdGVyUHJvdmlkZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIXRoaXMuZGF0ZXBpY2tlckFkYXB0ZXIgfHwgISh0aGlzLmRhdGVwaWNrZXJBZGFwdGVyIGluc3RhbmNlb2YgTmJEYXRlcGlja2VyQWRhcHRlcik7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgc3Vic2NyaWJlT25JbnB1dENoYW5nZSgpIHtcclxuICAgIGZyb21FdmVudCh0aGlzLmlucHV0LCAnaW5wdXQnKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKCkgPT4gdGhpcy5pbnB1dFZhbHVlKSxcclxuICAgICAgICB0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSksXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZSgodmFsdWU6IHN0cmluZykgPT4gdGhpcy5oYW5kbGVJbnB1dENoYW5nZSh2YWx1ZSkpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBQYXJzZXMgaW5wdXQgdmFsdWUgYW5kIHdyaXRlIGlmIGl0IGlzbid0IG51bGwuXHJcbiAgICogKi9cclxuICBwcm90ZWN0ZWQgaGFuZGxlSW5wdXRDaGFuZ2UodmFsdWU6IHN0cmluZykge1xyXG4gICAgY29uc3QgZGF0ZSA9IHRoaXMucGFyc2VJbnB1dFZhbHVlKHZhbHVlKTtcclxuXHJcbiAgICB0aGlzLm9uQ2hhbmdlKGRhdGUpO1xyXG4gICAgdGhpcy53cml0ZVBpY2tlcihkYXRlKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBwYXJzZUlucHV0VmFsdWUodmFsdWUpOiBEIHwgbnVsbCB7XHJcbiAgICBpZiAodGhpcy5kYXRlcGlja2VyQWRhcHRlci5pc1ZhbGlkKHZhbHVlLCB0aGlzLnBpY2tlci5mb3JtYXQpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGVwaWNrZXJBZGFwdGVyLnBhcnNlKHZhbHVlLCB0aGlzLnBpY2tlci5mb3JtYXQpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxufVxyXG4iXX0=