UNPKG

@handsontable/angular-wrapper

Version:

Best Data Grid for Angular with Spreadsheet Look and Feel.

150 lines 21.1 kB
import { createComponent, Injectable } from '@angular/core'; import Handsontable from 'handsontable'; import { HotCellRendererComponent } from './hot-cell-renderer.component'; import * as i0 from "@angular/core"; export const INVALID_RENDERER_WARNING = 'The provided renderer component was not recognized as a valid custom renderer. ' + 'It must either extend HotCellRendererComponent or be a valid TemplateRef. ' + 'Please ensure that your custom renderer is implemented correctly and imported from the proper source.'; /** * Type guard that checks if the given object is a TemplateRef. * * @param obj - The object to check. * @returns True if the object is a TemplateRef; otherwise, false. */ export function isTemplateRef(obj) { return obj && typeof obj.createEmbeddedView === 'function'; } /** * Type guard to check if an object is an instance of HotCellRendererComponent. * * @param obj - The object to check. * @returns True if the object is a HotCellRendererComponent, false otherwise. */ export function isHotCellRendererComponent(obj) { return obj?.RENDERER_MARKER === HotCellRendererComponent.RENDERER_MARKER; } /** * Service for dynamically creating Angular components or templates as custom renderers for Handsontable. * * This service allows you to create a renderer function that wraps a given Angular component or TemplateRef * so that it can be used as a Handsontable renderer. * * @example * const customRenderer = dynamicComponentService.createRendererFromComponent(MyRendererComponent, { someProp: value }); * // Use customRenderer in your Handsontable configuration */ export class DynamicComponentService { appRef; environmentInjector; constructor(appRef, environmentInjector) { this.appRef = appRef; this.environmentInjector = environmentInjector; } /** * Creates a custom renderer function for Handsontable from an Angular component or TemplateRef. * The generated renderer function will be used by Handsontable to render cell content. * * @param component - The Angular component type or TemplateRef to use as renderer. * @param componentProps - An object containing additional properties to use by the renderer. * @param register - If true, registers the renderer with Handsontable using the component's name. * @returns A renderer function that can be used in Handsontable's configuration. */ createRendererFromComponent(component, componentProps = {}, register = false) { return (instance, td, row, col, prop, value, cellProperties) => { const properties = { value, instance, td, row, col, prop, cellProperties }; if (componentProps) { Object.assign(cellProperties, { rendererProps: componentProps }); } const rendererParameters = [ instance, td, row, col, prop, value, cellProperties ]; Handsontable.renderers.BaseRenderer.apply(this, rendererParameters); td.innerHTML = ''; if (isTemplateRef(component)) { this.attachTemplateToElement(component, td, properties); } else if (isHotCellRendererComponent(component)) { const componentRef = this.createComponent(component, properties); this.attachComponentToElement(componentRef, td); } else { console.warn(INVALID_RENDERER_WARNING); } if (register && isHotCellRendererComponent(component)) { Handsontable.renderers.registerRenderer(component.constructor.name, component); } return td; }; } /** * Attaches an embedded view created from a TemplateRef to a given DOM element. * * @param template - The TemplateRef to create an embedded view from. * @param tdEl - The target DOM element (a table cell) to which the view will be appended. * @param properties - Context object providing properties to be used within the template. */ attachTemplateToElement(template, tdEl, properties) { const embeddedView = template.createEmbeddedView({ $implicit: properties.value, ...properties, }); embeddedView.detectChanges(); embeddedView.rootNodes.forEach((node) => { tdEl.appendChild(node); }); } /** * Dynamically creates an Angular component of the given type. * * @param component - The Angular component type to be created. * @param rendererParameters - An object containing input properties to assign to the component instance. * @returns The ComponentRef of the dynamically created component. */ createComponent(component, rendererParameters) { const componentRef = createComponent(component, { environmentInjector: this.environmentInjector }); Object.keys(rendererParameters).forEach(key => { if (rendererParameters.hasOwnProperty(key)) { componentRef.setInput(key, rendererParameters[key]); } else { console.warn(`Input property "${key}" does not exist on component instance: ${component?.name}.`); } }); componentRef.changeDetectorRef.detectChanges(); this.appRef.attachView(componentRef.hostView); return componentRef; } /** * Attaches a dynamically created component's view to a specified DOM container element. * * @param componentRef - The reference to the dynamically created component. * @param container - The target DOM element to which the component's root node will be appended. */ attachComponentToElement(componentRef, container) { const domElem = componentRef.hostView .rootNodes[0]; container.appendChild(domElem); } /** * Destroys a dynamically created component and detaches its view from the Angular application. * * @param componentRef - The reference to the component to be destroyed. */ destroyComponent(componentRef) { this.appRef.detachView(componentRef.hostView); componentRef.destroy(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicComponentService, deps: [{ token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicComponentService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicComponentService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG90LWR5bmFtaWMtcmVuZGVyZXItY29tcG9uZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9ob3QtdGFibGUvc3JjL2xpYi9yZW5kZXJlci9ob3QtZHluYW1pYy1yZW5kZXJlci1jb21wb25lbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ3lCLGVBQWUsRUFDUCxVQUFVLEVBRWpELE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sWUFBWSxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQzs7QUFJdkUsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQ25DLGlGQUFpRjtJQUNqRiw0RUFBNEU7SUFDNUUsdUdBQXVHLENBQUM7QUFlMUc7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFJLEdBQVE7SUFDdkMsT0FBTyxHQUFHLElBQUksT0FBTyxHQUFHLENBQUMsa0JBQWtCLEtBQUssVUFBVSxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxHQUFRO0lBQ2pELE9BQU8sR0FBRyxFQUFFLGVBQWUsS0FBSyx3QkFBd0IsQ0FBQyxlQUFlLENBQUM7QUFDM0UsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUlILE1BQU0sT0FBTyx1QkFBdUI7SUFFeEI7SUFDQTtJQUZWLFlBQ1UsTUFBc0IsRUFDdEIsbUJBQXdDO1FBRHhDLFdBQU0sR0FBTixNQUFNLENBQWdCO1FBQ3RCLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7SUFDL0MsQ0FBQztJQUVKOzs7Ozs7OztPQVFHO0lBQ0gsMkJBQTJCLENBQ3pCLFNBQTRELEVBQzVELGlCQUFzQyxFQUFFLEVBQ3hDLFdBQW9CLEtBQUs7UUFFekIsT0FBTyxDQUNMLFFBQTJCLEVBQzNCLEVBQXdCLEVBQ3hC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LElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUU5QyxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyx3QkFBd0IsQ0FDOUIsWUFBNkIsRUFDN0IsU0FBc0I7UUFFdEIsTUFBTSxPQUFPLEdBQUksWUFBWSxDQUFDLFFBQStCO2FBQzFELFNBQVMsQ0FBQyxDQUFDLENBQWdCLENBQUM7UUFDL0IsU0FBUyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGdCQUFnQixDQUFJLFlBQTZCO1FBQy9DLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDekIsQ0FBQzt3R0E1SVUsdUJBQXVCOzRHQUF2Qix1QkFBdUIsY0FGdEIsTUFBTTs7NEZBRVAsdUJBQXVCO2tCQUhuQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFwcGxpY2F0aW9uUmVmLCBDb21wb25lbnRSZWYsIGNyZWF0ZUNvbXBvbmVudCxcbiAgRW1iZWRkZWRWaWV3UmVmLCBFbnZpcm9ubWVudEluamVjdG9yLCBJbmplY3RhYmxlLFxuICBUZW1wbGF0ZVJlZiwgVHlwZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QmFzZVJlbmRlcmVyfSBmcm9tICdoYW5kc29udGFibGUvcmVuZGVyZXJzJztcbmltcG9ydCBIYW5kc29udGFibGUgZnJvbSAnaGFuZHNvbnRhYmxlJztcbmltcG9ydCB7SG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50fSBmcm9tICcuL2hvdC1jZWxsLXJlbmRlcmVyLmNvbXBvbmVudCc7XG5cbnR5cGUgQmFzZVJlbmRlcmVyUGFyYW1ldGVycyA9IFBhcmFtZXRlcnM8QmFzZVJlbmRlcmVyPjtcblxuZXhwb3J0IGNvbnN0IElOVkFMSURfUkVOREVSRVJfV0FSTklORyA9XG4gICdUaGUgcHJvdmlkZWQgcmVuZGVyZXIgY29tcG9uZW50IHdhcyBub3QgcmVjb2duaXplZCBhcyBhIHZhbGlkIGN1c3RvbSByZW5kZXJlci4gJyArXG4gICdJdCBtdXN0IGVpdGhlciBleHRlbmQgSG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50IG9yIGJlIGEgdmFsaWQgVGVtcGxhdGVSZWYuICcgK1xuICAnUGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgY3VzdG9tIHJlbmRlcmVyIGlzIGltcGxlbWVudGVkIGNvcnJlY3RseSBhbmQgaW1wb3J0ZWQgZnJvbSB0aGUgcHJvcGVyIHNvdXJjZS4nO1xuXG4vKipcbiAqIEFuIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIHBhcmFtZXRlcnMgcGFzc2VkIHRvIGEgSGFuZHNvbnRhYmxlIHJlbmRlcmVyLlxuICovXG5pbnRlcmZhY2UgQmFzZVJlbmRlcmVyUGFyYW1ldGVyc09iamVjdCB7XG4gIGluc3RhbmNlOiBIYW5kc29udGFibGUuQ29yZTtcbiAgdGQ6IEhUTUxUYWJsZUNlbGxFbGVtZW50O1xuICByb3c6IG51bWJlcjtcbiAgY29sOiBudW1iZXI7XG4gIHByb3A6IHN0cmluZyB8IG51bWJlcjtcbiAgdmFsdWU6IGFueTtcbiAgY2VsbFByb3BlcnRpZXM6IEhhbmRzb250YWJsZS5DZWxsUHJvcGVydGllcztcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRoYXQgY2hlY2tzIGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBUZW1wbGF0ZVJlZi5cbiAqXG4gKiBAcGFyYW0gb2JqIC0gVGhlIG9iamVjdCB0byBjaGVjay5cbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIG9iamVjdCBpcyBhIFRlbXBsYXRlUmVmOyBvdGhlcndpc2UsIGZhbHNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUZW1wbGF0ZVJlZjxUPihvYmo6IGFueSk6IG9iaiBpcyBUZW1wbGF0ZVJlZjxUPiB7XG4gIHJldHVybiBvYmogJiYgdHlwZW9mIG9iai5jcmVhdGVFbWJlZGRlZFZpZXcgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhbiBvYmplY3QgaXMgYW4gaW5zdGFuY2Ugb2YgSG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSBvYmogLSBUaGUgb2JqZWN0IHRvIGNoZWNrLlxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgb2JqZWN0IGlzIGEgSG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50LCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0hvdENlbGxSZW5kZXJlckNvbXBvbmVudChvYmo6IGFueSk6IG9iaiBpcyBUeXBlPEhvdENlbGxSZW5kZXJlckNvbXBvbmVudD4ge1xuICByZXR1cm4gb2JqPy5SRU5ERVJFUl9NQVJLRVIgPT09IEhvdENlbGxSZW5kZXJlckNvbXBvbmVudC5SRU5ERVJFUl9NQVJLRVI7XG59XG5cbi8qKlxuICogU2VydmljZSBmb3IgZHluYW1pY2FsbHkgY3JlYXRpbmcgQW5ndWxhciBjb21wb25lbnRzIG9yIHRlbXBsYXRlcyBhcyBjdXN0b20gcmVuZGVyZXJzIGZvciBIYW5kc29udGFibGUuXG4gKlxuICogVGhpcyBzZXJ2aWNlIGFsbG93cyB5b3UgdG8gY3JlYXRlIGEgcmVuZGVyZXIgZnVuY3Rpb24gdGhhdCB3cmFwcyBhIGdpdmVuIEFuZ3VsYXIgY29tcG9uZW50IG9yIFRlbXBsYXRlUmVmXG4gKiBzbyB0aGF0IGl0IGNhbiBiZSB1c2VkIGFzIGEgSGFuZHNvbnRhYmxlIHJlbmRlcmVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjdXN0b21SZW5kZXJlciA9IGR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLmNyZWF0ZVJlbmRlcmVyRnJvbUNvbXBvbmVudChNeVJlbmRlcmVyQ29tcG9uZW50LCB7IHNvbWVQcm9wOiB2YWx1ZSB9KTtcbiAqIC8vIFVzZSBjdXN0b21SZW5kZXJlciBpbiB5b3VyIEhhbmRzb250YWJsZSBjb25maWd1cmF0aW9uXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljQ29tcG9uZW50U2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXBwUmVmOiBBcHBsaWNhdGlvblJlZixcbiAgICBwcml2YXRlIGVudmlyb25tZW50SW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3JcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgY3VzdG9tIHJlbmRlcmVyIGZ1bmN0aW9uIGZvciBIYW5kc29udGFibGUgZnJvbSBhbiBBbmd1bGFyIGNvbXBvbmVudCBvciBUZW1wbGF0ZVJlZi5cbiAgICogVGhlIGdlbmVyYXRlZCByZW5kZXJlciBmdW5jdGlvbiB3aWxsIGJlIHVzZWQgYnkgSGFuZHNvbnRhYmxlIHRvIHJlbmRlciBjZWxsIGNvbnRlbnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb21wb25lbnQgLSBUaGUgQW5ndWxhciBjb21wb25lbnQgdHlwZSBvciBUZW1wbGF0ZVJlZiB0byB1c2UgYXMgcmVuZGVyZXIuXG4gICAqIEBwYXJhbSBjb21wb25lbnRQcm9wcyAtIEFuIG9iamVjdCBjb250YWluaW5nIGFkZGl0aW9uYWwgcHJvcGVydGllcyB0byB1c2UgYnkgdGhlIHJlbmRlcmVyLlxuICAgKiBAcGFyYW0gcmVnaXN0ZXIgLSBJZiB0cnVlLCByZWdpc3RlcnMgdGhlIHJlbmRlcmVyIHdpdGggSGFuZHNvbnRhYmxlIHVzaW5nIHRoZSBjb21wb25lbnQncyBuYW1lLlxuICAgKiBAcmV0dXJucyBBIHJlbmRlcmVyIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgaW4gSGFuZHNvbnRhYmxlJ3MgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGNyZWF0ZVJlbmRlcmVyRnJvbUNvbXBvbmVudChcbiAgICBjb21wb25lbnQ6IFR5cGU8SG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50PiB8IFRlbXBsYXRlUmVmPGFueT4sXG4gICAgY29tcG9uZW50UHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSxcbiAgICByZWdpc3RlcjogYm9vbGVhbiA9IGZhbHNlXG4gICkge1xuICAgIHJldHVybiAoXG4gICAgICBpbnN0YW5jZTogSGFuZHNvbnRhYmxlLkNvcmUsXG4gICAgICB0ZDogSFRNTFRhYmxlQ2VsbEVsZW1lbnQsXG4gICAgICByb3c6IG51bWJlcixcbiAgICAgIGNvbDogbnVtYmVyLFxuICAgICAgcHJvcDogc3RyaW5nIHwgbnVtYmVyLFxuICAgICAgdmFsdWU6IGFueSxcbiAgICAgIGNlbGxQcm9wZXJ0aWVzOiBIYW5kc29udGFibGUuQ2VsbFByb3BlcnRpZXNcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXM6IEJhc2VSZW5kZXJlclBhcmFtZXRlcnNPYmplY3QgPSB7XG4gICAgICAgIHZhbHVlLCBpbnN0YW5jZSwgdGQsIHJvdywgY29sLCBwcm9wLCBjZWxsUHJvcGVydGllc1xuICAgICAgfTtcblxuICAgICAgaWYgKGNvbXBvbmVudFByb3BzKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24oY2VsbFByb3BlcnRpZXMsIHtyZW5kZXJlclByb3BzOiBjb21wb25lbnRQcm9wc30pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZW5kZXJlclBhcmFtZXRlcnM6IEJhc2VSZW5kZXJlclBhcmFtZXRlcnMgPSBbXG4gICAgICAgIGluc3RhbmNlLCB0ZCwgcm93LCBjb2wsIHByb3AsIHZhbHVlLCBjZWxsUHJvcGVydGllc1xuICAgICAgXTtcblxuICAgICAgSGFuZHNvbnRhYmxlLnJlbmRlcmVycy5CYXNlUmVuZGVyZXIuYXBwbHkodGhpcywgcmVuZGVyZXJQYXJhbWV0ZXJzKTtcblxuICAgICAgdGQuaW5uZXJIVE1MID0gJyc7XG5cbiAgICAgIGlmIChpc1RlbXBsYXRlUmVmKGNvbXBvbmVudCkpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hUZW1wbGF0ZVRvRWxlbWVudChjb21wb25lbnQsIHRkLCBwcm9wZXJ0aWVzKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNIb3RDZWxsUmVuZGVyZXJDb21wb25lbnQoY29tcG9uZW50KSl7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IHRoaXMuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudCwgcHJvcGVydGllcyk7XG4gICAgICAgIHRoaXMuYXR0YWNoQ29tcG9uZW50VG9FbGVtZW50KGNvbXBvbmVudFJlZiwgdGQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKElOVkFMSURfUkVOREVSRVJfV0FSTklORylcbiAgICAgIH1cblxuICAgICAgaWYgKHJlZ2lzdGVyICYmIGlzSG90Q2VsbFJlbmRlcmVyQ29tcG9uZW50KGNvbXBvbmVudCkpIHtcbiAgICAgICAgSGFuZHNvbnRhYmxlLnJlbmRlcmVycy5yZWdpc3RlclJlbmRlcmVyKFxuICAgICAgICAgIGNvbXBvbmVudC5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgICAgICAgIGNvbXBvbmVudCBhcyBhbnkgYXMgQmFzZVJlbmRlcmVyXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0ZDtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIGFuIGVtYmVkZGVkIHZpZXcgY3JlYXRlZCBmcm9tIGEgVGVtcGxhdGVSZWYgdG8gYSBnaXZlbiBET00gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHRlbXBsYXRlIC0gVGhlIFRlbXBsYXRlUmVmIHRvIGNyZWF0ZSBhbiBlbWJlZGRlZCB2aWV3IGZyb20uXG4gICAqIEBwYXJhbSB0ZEVsIC0gVGhlIHRhcmdldCBET00gZWxlbWVudCAoYSB0YWJsZSBjZWxsKSB0byB3aGljaCB0aGUgdmlldyB3aWxsIGJlIGFwcGVuZGVkLlxuICAgKiBAcGFyYW0gcHJvcGVydGllcyAtIENvbnRleHQgb2JqZWN0IHByb3ZpZGluZyBwcm9wZXJ0aWVzIHRvIGJlIHVzZWQgd2l0aGluIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIHByaXZhdGUgYXR0YWNoVGVtcGxhdGVUb0VsZW1lbnQoXG4gICAgdGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4sXG4gICAgdGRFbDogSFRNTFRhYmxlQ2VsbEVsZW1lbnQsXG4gICAgcHJvcGVydGllczogQmFzZVJlbmRlcmVyUGFyYW1ldGVyc09iamVjdFxuICApIHtcbiAgICBjb25zdCBlbWJlZGRlZFZpZXc6IEVtYmVkZGVkVmlld1JlZjxhbnk+ID0gdGVtcGxhdGUuY3JlYXRlRW1iZWRkZWRWaWV3KHtcbiAgICAgICRpbXBsaWNpdDogcHJvcGVydGllcy52YWx1ZSxcbiAgICAgIC4uLnByb3BlcnRpZXMsXG4gICAgfSk7XG4gICAgZW1iZWRkZWRWaWV3LmRldGVjdENoYW5nZXMoKTtcblxuICAgIGVtYmVkZGVkVmlldy5yb290Tm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgdGRFbC5hcHBlbmRDaGlsZChub2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEeW5hbWljYWxseSBjcmVhdGVzIGFuIEFuZ3VsYXIgY29tcG9uZW50IG9mIHRoZSBnaXZlbiB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIEFuZ3VsYXIgY29tcG9uZW50IHR5cGUgdG8gYmUgY3JlYXRlZC5cbiAgICogQHBhcmFtIHJlbmRlcmVyUGFyYW1ldGVycyAtIEFuIG9iamVjdCBjb250YWluaW5nIGlucHV0IHByb3BlcnRpZXMgdG8gYXNzaWduIHRvIHRoZSBjb21wb25lbnQgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIFRoZSBDb21wb25lbnRSZWYgb2YgdGhlIGR5bmFtaWNhbGx5IGNyZWF0ZWQgY29tcG9uZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVDb21wb25lbnQ8VCBleHRlbmRzIEhvdENlbGxSZW5kZXJlckNvbXBvbmVudD4oXG4gICAgY29tcG9uZW50OiBUeXBlPFQ+LFxuICAgIHJlbmRlcmVyUGFyYW1ldGVyczogQmFzZVJlbmRlcmVyUGFyYW1ldGVyc09iamVjdFxuICApOiBDb21wb25lbnRSZWY8VD4ge1xuICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IGNyZWF0ZUNvbXBvbmVudChjb21wb25lbnQsIHtcbiAgICAgIGVudmlyb25tZW50SW5qZWN0b3I6IHRoaXMuZW52aXJvbm1lbnRJbmplY3RvclxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmtleXMocmVuZGVyZXJQYXJhbWV0ZXJzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAocmVuZGVyZXJQYXJhbWV0ZXJzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgY29tcG9uZW50UmVmLnNldElucHV0KGtleSwgcmVuZGVyZXJQYXJhbWV0ZXJzW2tleV0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oYElucHV0IHByb3BlcnR5IFwiJHtrZXl9XCIgZG9lcyBub3QgZXhpc3Qgb24gY29tcG9uZW50IGluc3RhbmNlOiAke2NvbXBvbmVudD8ubmFtZX0uYCk7XG4gICAgICB9XG4gICAgfSlcbiAgICBjb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgdGhpcy5hcHBSZWYuYXR0YWNoVmlldyhjb21wb25lbnRSZWYuaG9zdFZpZXcpO1xuXG4gICAgcmV0dXJuIGNvbXBvbmVudFJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2hlcyBhIGR5bmFtaWNhbGx5IGNyZWF0ZWQgY29tcG9uZW50J3MgdmlldyB0byBhIHNwZWNpZmllZCBET00gY29udGFpbmVyIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBjb21wb25lbnRSZWYgLSBUaGUgcmVmZXJlbmNlIHRvIHRoZSBkeW5hbWljYWxseSBjcmVhdGVkIGNvbXBvbmVudC5cbiAgICogQHBhcmFtIGNvbnRhaW5lciAtIFRoZSB0YXJnZXQgRE9NIGVsZW1lbnQgdG8gd2hpY2ggdGhlIGNvbXBvbmVudCdzIHJvb3Qgbm9kZSB3aWxsIGJlIGFwcGVuZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBhdHRhY2hDb21wb25lbnRUb0VsZW1lbnQ8VD4oXG4gICAgY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8VD4sXG4gICAgY29udGFpbmVyOiBIVE1MRWxlbWVudFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBkb21FbGVtID0gKGNvbXBvbmVudFJlZi5ob3N0VmlldyBhcyBFbWJlZGRlZFZpZXdSZWY8VD4pXG4gICAgICAucm9vdE5vZGVzWzBdIGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChkb21FbGVtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyBhIGR5bmFtaWNhbGx5IGNyZWF0ZWQgY29tcG9uZW50IGFuZCBkZXRhY2hlcyBpdHMgdmlldyBmcm9tIHRoZSBBbmd1bGFyIGFwcGxpY2F0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gY29tcG9uZW50UmVmIC0gVGhlIHJlZmVyZW5jZSB0byB0aGUgY29tcG9uZW50IHRvIGJlIGRlc3Ryb3llZC5cbiAgICovXG4gIGRlc3Ryb3lDb21wb25lbnQ8VD4oY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8VD4pOiB2b2lkIHtcbiAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KGNvbXBvbmVudFJlZi5ob3N0Vmlldyk7XG4gICAgY29tcG9uZW50UmVmLmRlc3Ryb3koKTtcbiAgfVxufVxuIl19