@handsontable/angular-wrapper
Version:
Best Data Grid for Angular with Spreadsheet Look and Feel.
144 lines • 20 kB
JavaScript
import { Component, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import Handsontable from 'handsontable/base';
import { HotSettingsResolver } from './services/hot-settings-resolver.service';
import * as i0 from "@angular/core";
import * as i1 from "./services/hot-settings-resolver.service";
import * as i2 from "./services/hot-config.service";
export const HOT_DESTROYED_WARNING = 'The Handsontable instance bound to this component was destroyed and cannot be' + ' used properly.';
export class HotTableComponent {
_hotSettingsResolver;
_hotConfig;
ngZone;
// component inputs
/** The data for the Handsontable instance. */
data = null;
/** The settings for the Handsontable instance. */
settings;
/** The container element for the Handsontable instance. */
container;
/** The Handsontable instance. */
__hotInstance = null;
configSubscription;
constructor(_hotSettingsResolver, _hotConfig, ngZone) {
this._hotSettingsResolver = _hotSettingsResolver;
this._hotConfig = _hotConfig;
this.ngZone = ngZone;
}
/**
* Gets the Handsontable instance.
* @returns The Handsontable instance or `null` if it's not yet been created or has been destroyed.
*/
get hotInstance() {
if (!this.__hotInstance || (this.__hotInstance && !this.__hotInstance.isDestroyed)) {
// Will return the Handsontable instance or `null` if it's not yet been created.
return this.__hotInstance;
}
else {
console.warn(HOT_DESTROYED_WARNING);
return null;
}
}
/**
* Sets the Handsontable instance.
* @param hotInstance The Handsontable instance to set.
*/
set hotInstance(hotInstance) {
this.__hotInstance = hotInstance;
}
/**
* Initializes the Handsontable instance after the view has been initialized.
* The initial settings of the table are also prepared here
*/
ngAfterViewInit() {
let options = this._hotSettingsResolver.applyCustomSettings(this.settings, this.ngZone);
const negotiatedSettings = this.getNegotiatedSettings(options);
options = { ...options, ...negotiatedSettings, data: this.data };
this.ngZone.runOutsideAngular(() => {
this.hotInstance = new Handsontable.Core(this.container.nativeElement, options);
// @ts-ignore
this.hotInstance.init();
});
this.configSubscription = this._hotConfig.config$.subscribe((config) => {
if (this.hotInstance) {
const negotiatedSettings = this.getNegotiatedSettings(this.settings);
this.updateHotTable(negotiatedSettings);
}
});
}
ngOnChanges(changes) {
if (this.hotInstance === null) {
return;
}
if (changes.settings && !changes.settings.firstChange) {
const newOptions = this._hotSettingsResolver.applyCustomSettings(changes.settings.currentValue, this.ngZone);
this.updateHotTable(newOptions);
}
if (changes.data && !changes.data.firstChange) {
this.hotInstance?.updateData(changes.data.currentValue);
}
}
/**
* Destroys the Handsontable instance and clears the columns from custom editors.
*/
ngOnDestroy() {
this.ngZone.runOutsideAngular(() => {
if (this.hotInstance) {
this.hotInstance.getSettings().columns
?.filter((column) => column._editorComponentReference)
.forEach((column) => {
column._editorComponentReference?.destroy();
});
this.hotInstance.destroy();
}
});
this.configSubscription.unsubscribe();
}
/**
* Updates the Handsontable instance with new settings.
* @param newSettings The new settings to apply to the Handsontable instance.
*/
updateHotTable(newSettings) {
if (!this.hotInstance) {
return;
}
this.ngZone.runOutsideAngular(() => {
this.hotInstance?.updateSettings(newSettings, false);
});
}
/**
* Merges the provided Handsontable grid settings with the global configuration.
*
* This method retrieves the global configuration from the HotConfigService and negotiates the final
* Handsontable settings by giving precedence to the provided settings.
* Additionally, the `layoutDirection` is only merged if the Handsontable instance has not yet been initialized.
*
* @param settings - The grid settings provided by the user or component.
* @returns The final negotiated grid settings after merging with global defaults.
*/
getNegotiatedSettings(settings) {
const hotConfig = this._hotConfig.getConfig();
const negotiatedSettings = {};
negotiatedSettings.licenseKey = settings.licenseKey ?? hotConfig.license;
negotiatedSettings.themeName = settings.themeName ?? hotConfig.themeName;
negotiatedSettings.language = settings.language ?? hotConfig.language;
// settings that can be set only before the Handsontable instance is initialized
if (!this.__hotInstance) {
negotiatedSettings.layoutDirection = settings.layoutDirection ?? hotConfig.layoutDirection;
}
return negotiatedSettings;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotTableComponent, deps: [{ token: i1.HotSettingsResolver }, { token: i2.HotConfigService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: HotTableComponent, selector: "hot-table", inputs: { data: "data", settings: "settings" }, providers: [HotSettingsResolver], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: '<div #container></div>', isInline: true, styles: [":host{display:block}\n"], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: HotTableComponent, decorators: [{
type: Component,
args: [{ selector: 'hot-table', template: '<div #container></div>', encapsulation: ViewEncapsulation.None, providers: [HotSettingsResolver], styles: [":host{display:block}\n"] }]
}], ctorParameters: function () { return [{ type: i1.HotSettingsResolver }, { type: i2.HotConfigService }, { type: i0.NgZone }]; }, propDecorators: { data: [{
type: Input
}], settings: [{
type: Input
}], container: [{
type: ViewChild,
args: ['container', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG90LXRhYmxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2hvdC10YWJsZS9zcmMvbGliL2hvdC10YWJsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFFVCxLQUFLLEVBS0wsU0FBUyxFQUNULGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLFlBQVksTUFBTSxtQkFBbUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7OztBQU0vRSxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRywrRUFBK0UsR0FBRyxpQkFBaUIsQ0FBQztBQWV6SSxNQUFNLE9BQU8saUJBQWlCO0lBZVI7SUFBbUQ7SUFBcUM7SUFkNUcsbUJBQW1CO0lBQ25CLDhDQUE4QztJQUNyQyxJQUFJLEdBQTZDLElBQUksQ0FBQztJQUMvRCxrREFBa0Q7SUFDekMsUUFBUSxDQUFlO0lBRWhDLDJEQUEyRDtJQUVwRCxTQUFTLENBQTZCO0lBRTdDLGlDQUFpQztJQUN6QixhQUFhLEdBQXdCLElBQUksQ0FBQztJQUMxQyxrQkFBa0IsQ0FBZTtJQUV6QyxZQUFvQixvQkFBeUMsRUFBVSxVQUE0QixFQUFTLE1BQWM7UUFBdEcseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFxQjtRQUFVLGVBQVUsR0FBVixVQUFVLENBQWtCO1FBQVMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUFHLENBQUM7SUFFOUg7OztPQUdHO0lBQ0gsSUFBVyxXQUFXO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDbEYsZ0ZBQWdGO1lBQ2hGLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztTQUMzQjthQUFNO1lBQ0wsT0FBTyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQ3BDLE9BQU8sSUFBSSxDQUFDO1NBQ2I7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBWSxXQUFXLENBQUMsV0FBVztRQUNqQyxJQUFJLENBQUMsYUFBYSxHQUFHLFdBQVcsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZUFBZTtRQUNiLElBQUksT0FBTyxHQUE4QixJQUFJLENBQUMsb0JBQW9CLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkgsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0QsT0FBTyxHQUFHLEVBQUUsR0FBRyxPQUFPLEVBQUUsR0FBRyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBRWpFLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQ2pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBRWhGLGFBQWE7WUFDYixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3JFLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDcEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNyRSxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLENBQUM7YUFDekM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLElBQUksRUFBRTtZQUM3QixPQUFPO1NBQ1I7UUFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRTtZQUNyRCxNQUFNLFVBQVUsR0FBOEIsSUFBSSxDQUFDLG9CQUFvQixDQUFDLG1CQUFtQixDQUN6RixPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksRUFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FDWixDQUFDO1lBRUYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUNqQztRQUVELElBQUksT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQzdDLElBQUksQ0FBQyxXQUFXLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDekQ7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUU7WUFDakMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNuQixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQW9DO29CQUNsRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLHlCQUF5QixDQUFDO3FCQUNyRCxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtvQkFDbEIsTUFBTSxDQUFDLHlCQUF5QixFQUFFLE9BQU8sRUFBRSxDQUFDO2dCQUM5QyxDQUFDLENBQUMsQ0FBQztnQkFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2FBQzVCO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGNBQWMsQ0FBQyxXQUFzQztRQUMzRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUNqQyxJQUFJLENBQUMsV0FBVyxFQUFFLGNBQWMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0sscUJBQXFCLENBQUMsUUFBc0I7UUFDbEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUM5QyxNQUFNLGtCQUFrQixHQUE4QixFQUFFLENBQUM7UUFFekQsa0JBQWtCLENBQUMsVUFBVSxHQUFHLFFBQVEsQ0FBQyxVQUFVLElBQUksU0FBUyxDQUFDLE9BQU8sQ0FBQztRQUN6RSxrQkFBa0IsQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQ3pFLGtCQUFrQixDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUM7UUFFdEUsZ0ZBQWdGO1FBQ2hGLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3ZCLGtCQUFrQixDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUMsZUFBZSxJQUFJLFNBQVMsQ0FBQyxlQUFlLENBQUM7U0FDNUY7UUFFRCxPQUFPLGtCQUFrQixDQUFDO0lBQzVCLENBQUM7d0dBM0lVLGlCQUFpQjs0RkFBakIsaUJBQWlCLG9GQVRqQixDQUFDLG1CQUFtQixDQUFDLHVKQUZ0Qix3QkFBd0I7OzRGQVd2QixpQkFBaUI7a0JBYjdCLFNBQVM7K0JBQ0UsV0FBVyxZQUNYLHdCQUF3QixpQkFDbkIsaUJBQWlCLENBQUMsSUFBSSxhQUMxQixDQUFDLG1CQUFtQixDQUFDOzhKQVl2QixJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFJQyxTQUFTO3NCQURmLFNBQVM7dUJBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgSGFuZHNvbnRhYmxlIGZyb20gJ2hhbmRzb250YWJsZS9iYXNlJztcbmltcG9ydCB7IEhvdFNldHRpbmdzUmVzb2x2ZXIgfSBmcm9tICcuL3NlcnZpY2VzL2hvdC1zZXR0aW5ncy1yZXNvbHZlci5zZXJ2aWNlJztcbmltcG9ydCB7IEhvdENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2hvdC1jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBHcmlkU2V0dGluZ3MgfSBmcm9tICcuL21vZGVscy9ncmlkLXNldHRpbmdzJztcbmltcG9ydCB7IENvbHVtblNldHRpbmdzSW50ZXJuYWwgfSBmcm9tICcuL21vZGVscy9jb2x1bW4tc2V0dGluZ3MnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBjb25zdCBIT1RfREVTVFJPWUVEX1dBUk5JTkcgPSAnVGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSBib3VuZCB0byB0aGlzIGNvbXBvbmVudCB3YXMgZGVzdHJveWVkIGFuZCBjYW5ub3QgYmUnICsgJyB1c2VkIHByb3Blcmx5Lic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hvdC10YWJsZScsXG4gIHRlbXBsYXRlOiAnPGRpdiAjY29udGFpbmVyPjwvZGl2PicsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHByb3ZpZGVyczogW0hvdFNldHRpbmdzUmVzb2x2ZXJdLFxuICBzdHlsZXM6IFtcbiAgICBgXG4gICAgICA6aG9zdCB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgfVxuICAgIGAsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEhvdFRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvLyBjb21wb25lbnQgaW5wdXRzXG4gIC8qKiBUaGUgZGF0YSBmb3IgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZS4gKi9cbiAgQElucHV0KCkgZGF0YTogSGFuZHNvbnRhYmxlLkdyaWRTZXR0aW5nc1snZGF0YSddIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgc2V0dGluZ3MgZm9yIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UuICovXG4gIEBJbnB1dCgpIHNldHRpbmdzOiBHcmlkU2V0dGluZ3M7XG5cbiAgLyoqIFRoZSBjb250YWluZXIgZWxlbWVudCBmb3IgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZS4gKi9cbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJywgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHB1YmxpYyBjb250YWluZXI6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIC8qKiBUaGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlLiAqL1xuICBwcml2YXRlIF9faG90SW5zdGFuY2U6IEhhbmRzb250YWJsZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbmZpZ1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2hvdFNldHRpbmdzUmVzb2x2ZXI6IEhvdFNldHRpbmdzUmVzb2x2ZXIsIHByaXZhdGUgX2hvdENvbmZpZzogSG90Q29uZmlnU2VydmljZSwgcHVibGljIG5nWm9uZTogTmdab25lKSB7fVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIFRoZSBIYW5kc29udGFibGUgaW5zdGFuY2Ugb3IgYG51bGxgIGlmIGl0J3Mgbm90IHlldCBiZWVuIGNyZWF0ZWQgb3IgaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgKi9cbiAgcHVibGljIGdldCBob3RJbnN0YW5jZSgpOiBIYW5kc29udGFibGUgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuX19ob3RJbnN0YW5jZSB8fCAodGhpcy5fX2hvdEluc3RhbmNlICYmICF0aGlzLl9faG90SW5zdGFuY2UuaXNEZXN0cm95ZWQpKSB7XG4gICAgICAvLyBXaWxsIHJldHVybiB0aGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlIG9yIGBudWxsYCBpZiBpdCdzIG5vdCB5ZXQgYmVlbiBjcmVhdGVkLlxuICAgICAgcmV0dXJuIHRoaXMuX19ob3RJbnN0YW5jZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS53YXJuKEhPVF9ERVNUUk9ZRURfV0FSTklORyk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlLlxuICAgKiBAcGFyYW0gaG90SW5zdGFuY2UgVGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSB0byBzZXQuXG4gICAqL1xuICBwcml2YXRlIHNldCBob3RJbnN0YW5jZShob3RJbnN0YW5jZSkge1xuICAgIHRoaXMuX19ob3RJbnN0YW5jZSA9IGhvdEluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHRoZSBIYW5kc29udGFibGUgaW5zdGFuY2UgYWZ0ZXIgdGhlIHZpZXcgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG4gICAqIFRoZSBpbml0aWFsIHNldHRpbmdzIG9mIHRoZSB0YWJsZSBhcmUgYWxzbyBwcmVwYXJlZCBoZXJlXG4gICAqL1xuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgbGV0IG9wdGlvbnM6IEhhbmRzb250YWJsZS5HcmlkU2V0dGluZ3MgPSB0aGlzLl9ob3RTZXR0aW5nc1Jlc29sdmVyLmFwcGx5Q3VzdG9tU2V0dGluZ3ModGhpcy5zZXR0aW5ncywgdGhpcy5uZ1pvbmUpO1xuXG4gICAgY29uc3QgbmVnb3RpYXRlZFNldHRpbmdzID0gdGhpcy5nZXROZWdvdGlhdGVkU2V0dGluZ3Mob3B0aW9ucyk7XG4gICAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucywgLi4ubmVnb3RpYXRlZFNldHRpbmdzLCBkYXRhOiB0aGlzLmRhdGEgfTtcblxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHRoaXMuaG90SW5zdGFuY2UgPSBuZXcgSGFuZHNvbnRhYmxlLkNvcmUodGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudCwgb3B0aW9ucyk7XG5cbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHRoaXMuaG90SW5zdGFuY2UuaW5pdCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jb25maWdTdWJzY3JpcHRpb24gPSB0aGlzLl9ob3RDb25maWcuY29uZmlnJC5zdWJzY3JpYmUoKGNvbmZpZykgPT4ge1xuICAgICAgaWYgKHRoaXMuaG90SW5zdGFuY2UpIHtcbiAgICAgICAgY29uc3QgbmVnb3RpYXRlZFNldHRpbmdzID0gdGhpcy5nZXROZWdvdGlhdGVkU2V0dGluZ3ModGhpcy5zZXR0aW5ncyk7XG4gICAgICAgIHRoaXMudXBkYXRlSG90VGFibGUobmVnb3RpYXRlZFNldHRpbmdzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5ob3RJbnN0YW5jZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzLnNldHRpbmdzICYmICFjaGFuZ2VzLnNldHRpbmdzLmZpcnN0Q2hhbmdlKSB7XG4gICAgICBjb25zdCBuZXdPcHRpb25zOiBIYW5kc29udGFibGUuR3JpZFNldHRpbmdzID0gdGhpcy5faG90U2V0dGluZ3NSZXNvbHZlci5hcHBseUN1c3RvbVNldHRpbmdzKFxuICAgICAgICBjaGFuZ2VzLnNldHRpbmdzLmN1cnJlbnRWYWx1ZSxcbiAgICAgICAgdGhpcy5uZ1pvbmVcbiAgICAgICk7XG5cbiAgICAgIHRoaXMudXBkYXRlSG90VGFibGUobmV3T3B0aW9ucyk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMuZGF0YSAmJiAhY2hhbmdlcy5kYXRhLmZpcnN0Q2hhbmdlKSB7XG4gICAgICB0aGlzLmhvdEluc3RhbmNlPy51cGRhdGVEYXRhKGNoYW5nZXMuZGF0YS5jdXJyZW50VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyB0aGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlIGFuZCBjbGVhcnMgdGhlIGNvbHVtbnMgZnJvbSBjdXN0b20gZWRpdG9ycy5cbiAgICovXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmhvdEluc3RhbmNlKSB7XG4gICAgICAgICh0aGlzLmhvdEluc3RhbmNlLmdldFNldHRpbmdzKCkuY29sdW1ucyBhcyBDb2x1bW5TZXR0aW5nc0ludGVybmFsW10pXG4gICAgICAgICAgPy5maWx0ZXIoKGNvbHVtbikgPT4gY29sdW1uLl9lZGl0b3JDb21wb25lbnRSZWZlcmVuY2UpXG4gICAgICAgICAgLmZvckVhY2goKGNvbHVtbikgPT4ge1xuICAgICAgICAgICAgY29sdW1uLl9lZGl0b3JDb21wb25lbnRSZWZlcmVuY2U/LmRlc3Ryb3koKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ob3RJbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbmZpZ1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSB3aXRoIG5ldyBzZXR0aW5ncy5cbiAgICogQHBhcmFtIG5ld1NldHRpbmdzIFRoZSBuZXcgc2V0dGluZ3MgdG8gYXBwbHkgdG8gdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZS5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlSG90VGFibGUobmV3U2V0dGluZ3M6IEhhbmRzb250YWJsZS5HcmlkU2V0dGluZ3MpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaG90SW5zdGFuY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICB0aGlzLmhvdEluc3RhbmNlPy51cGRhdGVTZXR0aW5ncyhuZXdTZXR0aW5ncywgZmFsc2UpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlcyB0aGUgcHJvdmlkZWQgSGFuZHNvbnRhYmxlIGdyaWQgc2V0dGluZ3Mgd2l0aCB0aGUgZ2xvYmFsIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHJldHJpZXZlcyB0aGUgZ2xvYmFsIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgSG90Q29uZmlnU2VydmljZSBhbmQgbmVnb3RpYXRlcyB0aGUgZmluYWxcbiAgICogSGFuZHNvbnRhYmxlIHNldHRpbmdzIGJ5IGdpdmluZyBwcmVjZWRlbmNlIHRvIHRoZSBwcm92aWRlZCBzZXR0aW5ncy5cbiAgICogQWRkaXRpb25hbGx5LCB0aGUgYGxheW91dERpcmVjdGlvbmAgaXMgb25seSBtZXJnZWQgaWYgdGhlIEhhbmRzb250YWJsZSBpbnN0YW5jZSBoYXMgbm90IHlldCBiZWVuIGluaXRpYWxpemVkLlxuICAgKlxuICAgKiBAcGFyYW0gc2V0dGluZ3MgLSBUaGUgZ3JpZCBzZXR0aW5ncyBwcm92aWRlZCBieSB0aGUgdXNlciBvciBjb21wb25lbnQuXG4gICAqIEByZXR1cm5zIFRoZSBmaW5hbCBuZWdvdGlhdGVkIGdyaWQgc2V0dGluZ3MgYWZ0ZXIgbWVyZ2luZyB3aXRoIGdsb2JhbCBkZWZhdWx0cy5cbiAgICovXG4gIHByaXZhdGUgZ2V0TmVnb3RpYXRlZFNldHRpbmdzKHNldHRpbmdzOiBHcmlkU2V0dGluZ3MpOiBIYW5kc29udGFibGUuR3JpZFNldHRpbmdzIHtcbiAgICBjb25zdCBob3RDb25maWcgPSB0aGlzLl9ob3RDb25maWcuZ2V0Q29uZmlnKCk7XG4gICAgY29uc3QgbmVnb3RpYXRlZFNldHRpbmdzOiBIYW5kc29udGFibGUuR3JpZFNldHRpbmdzID0ge307XG5cbiAgICBuZWdvdGlhdGVkU2V0dGluZ3MubGljZW5zZUtleSA9IHNldHRpbmdzLmxpY2Vuc2VLZXkgPz8gaG90Q29uZmlnLmxpY2Vuc2U7XG4gICAgbmVnb3RpYXRlZFNldHRpbmdzLnRoZW1lTmFtZSA9IHNldHRpbmdzLnRoZW1lTmFtZSA/PyBob3RDb25maWcudGhlbWVOYW1lO1xuICAgIG5lZ290aWF0ZWRTZXR0aW5ncy5sYW5ndWFnZSA9IHNldHRpbmdzLmxhbmd1YWdlID8/IGhvdENvbmZpZy5sYW5ndWFnZTtcblxuICAgIC8vIHNldHRpbmdzIHRoYXQgY2FuIGJlIHNldCBvbmx5IGJlZm9yZSB0aGUgSGFuZHNvbnRhYmxlIGluc3RhbmNlIGlzIGluaXRpYWxpemVkXG4gICAgaWYgKCF0aGlzLl9faG90SW5zdGFuY2UpIHtcbiAgICAgIG5lZ290aWF0ZWRTZXR0aW5ncy5sYXlvdXREaXJlY3Rpb24gPSBzZXR0aW5ncy5sYXlvdXREaXJlY3Rpb24gPz8gaG90Q29uZmlnLmxheW91dERpcmVjdGlvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gbmVnb3RpYXRlZFNldHRpbmdzO1xuICB9XG59XG4iXX0=