UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

350 lines 30 kB
/** * @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 { ComponentFactoryResolver, Inject, Injectable, Injector, TemplateRef } from '@angular/core'; import { fromEvent as observableFromEvent } from 'rxjs'; import { filter } from 'rxjs/operators'; import { NbComponentPortal, NbOverlayService, NbPortalInjector, NbPositionBuilderService, NbTemplatePortal, } from '../cdk'; import { NB_DOCUMENT } from '../../theme.options'; import { NB_DIALOG_CONFIG, NbDialogConfig } from './dialog-config'; import { NbDialogRef } from './dialog-ref'; import { NbDialogContainerComponent } from './dialog-container'; /* * The `NbDialogService` helps to open dialogs. * * @stacked-example(Showcase, dialog/dialog-showcase.component) * * A new dialog is opened by calling the `open` method with a component to be loaded and an optional configuration. * `open` method will return `NbDialogRef` that can be used for the further manipulations. * * ### Installation * * Import `NbDialogModule.forRoot()` to your app module. * ```ts * @NgModule({ * imports: [ * // ... * NbDialogModule.forRoot(config), * ], * }) * export class AppModule { } * ``` * * If you are using it in a lazy loaded module than you have to install it with `NbDialogModule.forChild()`: * ```ts * @NgModule({ * imports: [ * // ... * NbDialogModule.forChild(config), * ], * }) * export class LazyLoadedModule { } * ``` * * ### Usage * * ```ts * const dialogRef = this.dialogService.open(MyDialogComponent, { ... }); * ``` * * `NbDialogRef` gives capability access reference to the rendered dialog component, * destroy dialog and some other options described below. * * Also, you can inject `NbDialogRef` in dialog component. * * ```ts * this.dialogService.open(MyDialogComponent, { ... }); * * // my-dialog.component.ts * constructor(protected dialogRef: NbDialogRef) { * } * * close() { * this.dialogRef.close(); * } * ``` * * Instead of component you can create dialog from TemplateRef: * * @stacked-example(Template ref, dialog/dialog-template.component) * * The dialog may return result through `NbDialogRef`. Calling component can receive this result with `onClose` * stream of `NbDialogRef`. * * @stacked-example(Result, dialog/dialog-result.component) * * ### Configuration * * As we mentioned above, `open` method of the `NbDialogService` may receive optional configuration options. * Also, you can provide global dialogs configuration through `NbDialogModule.forRoot({ ... })`. * * This config may contain the following: * * `context` - both, template and component may receive data through `config.context` property. * For components, this data will be assigned through inputs. * For templates, you can access it inside template as $implicit. * * ```ts * this.dialogService.open(template, { context: 'pass data in template' }); * ``` * * ```html * <ng-template let-some-additional-data> * {{ some-additional-data }} * <ng-template/> * ``` * * `hasBackdrop` - determines is service have to render backdrop under the dialog. * Default is true. * @stacked-example(Backdrop, dialog/dialog-has-backdrop.component) * * `closeOnBackdropClick` - close dialog on backdrop click if true. * Default is true. * @stacked-example(Backdrop click, dialog/dialog-backdrop-click.component) * * `closeOnEsc` - close dialog on escape button on the keyboard. * Default is true. * @stacked-example(Escape hit, dialog/dialog-esc.component) * * `hasScroll` - Disables scroll on content under dialog if true and does nothing otherwise. * Default is false. * Please, open dialogs in the separate window and try to scroll. * @stacked-example(Scroll, dialog/dialog-scroll.component) * * `autoFocus` - Focuses dialog automatically after open if true. It's useful to prevent misclicks on * trigger elements and opening multiple dialogs. * Default is true. * * As you can see, if you open dialog with auto focus dialog will focus first focusable element * or just blur previously focused automatically. * Otherwise, without auto focus, the focus will stay on the previously focused element. * Please, open dialogs in the separate window and try to click on the button without focus * and then hit space any times. Multiple same dialogs will be opened. * @stacked-example(Auto focus, dialog/dialog-auto-focus.component) * */ export class NbDialogService { /** * @param {?} document * @param {?} globalConfig * @param {?} positionBuilder * @param {?} overlay * @param {?} injector * @param {?} cfr */ constructor(document, globalConfig, positionBuilder, overlay, injector, cfr) { this.document = document; this.globalConfig = globalConfig; this.positionBuilder = positionBuilder; this.overlay = overlay; this.injector = injector; this.cfr = cfr; } /* * Opens new instance of the dialog, may receive optional config. * */ /** * @template T * @param {?} content * @param {?=} userConfig * @return {?} */ open(content, userConfig = {}) { /** @type {?} */ const config = new NbDialogConfig(Object.assign({}, this.globalConfig, userConfig)); /** @type {?} */ const overlayRef = this.createOverlay(config); /** @type {?} */ const dialogRef = new NbDialogRef(overlayRef); /** @type {?} */ const container = this.createContainer(config, overlayRef); this.createContent(config, content, container, dialogRef); this.registerCloseListeners(config, overlayRef, dialogRef); return dialogRef; } /** * @protected * @param {?} config * @return {?} */ createOverlay(config) { /** @type {?} */ const positionStrategy = this.createPositionStrategy(); /** @type {?} */ const scrollStrategy = this.createScrollStrategy(config.hasScroll); return this.overlay.create({ positionStrategy, scrollStrategy, hasBackdrop: config.hasBackdrop, backdropClass: config.backdropClass, }); } /** * @protected * @return {?} */ createPositionStrategy() { return this.positionBuilder .global() .centerVertically() .centerHorizontally(); } /** * @protected * @param {?} hasScroll * @return {?} */ createScrollStrategy(hasScroll) { if (hasScroll) { return this.overlay.scrollStrategies.noop(); } else { return this.overlay.scrollStrategies.block(); } } /** * @protected * @param {?} config * @param {?} overlayRef * @return {?} */ createContainer(config, overlayRef) { /** @type {?} */ const injector = new NbPortalInjector(this.createInjector(config), new WeakMap([[NbDialogConfig, config]])); /** @type {?} */ const containerPortal = new NbComponentPortal(NbDialogContainerComponent, null, injector, this.cfr); /** @type {?} */ const containerRef = overlayRef.attach(containerPortal); return containerRef.instance; } /** * @protected * @template T * @param {?} config * @param {?} content * @param {?} container * @param {?} dialogRef * @return {?} */ createContent(config, content, container, dialogRef) { if (content instanceof TemplateRef) { /** @type {?} */ const portal = this.createTemplatePortal(config, content, dialogRef); container.attachTemplatePortal(portal); } else { /** @type {?} */ const portal = this.createComponentPortal(config, content, dialogRef); dialogRef.componentRef = container.attachComponentPortal(portal); if (config.context) { Object.assign(dialogRef.componentRef.instance, Object.assign({}, config.context)); } } } /** * @protected * @template T * @param {?} config * @param {?} content * @param {?} dialogRef * @return {?} */ createTemplatePortal(config, content, dialogRef) { return new NbTemplatePortal(content, null, (/** @type {?} */ ({ $implicit: config.context, dialogRef }))); } /* * We're creating portal with custom injector provided through config or using global injector. * This approach provides us capability inject `NbDialogRef` in dialog component. * */ /** * @protected * @template T * @param {?} config * @param {?} content * @param {?} dialogRef * @return {?} */ createComponentPortal(config, content, dialogRef) { /** @type {?} */ const injector = this.createInjector(config); /** @type {?} */ const portalInjector = new NbPortalInjector(injector, new WeakMap([[NbDialogRef, dialogRef]])); return new NbComponentPortal(content, config.viewContainerRef, portalInjector); } /** * @protected * @param {?} config * @return {?} */ createInjector(config) { return config.viewContainerRef && config.viewContainerRef.injector || this.injector; } /** * @protected * @template T * @param {?} config * @param {?} overlayRef * @param {?} dialogRef * @return {?} */ registerCloseListeners(config, overlayRef, dialogRef) { if (config.closeOnBackdropClick) { overlayRef.backdropClick().subscribe(() => dialogRef.close()); } if (config.closeOnEsc) { observableFromEvent(this.document, 'keyup') .pipe(filter((event) => event.keyCode === 27)) .subscribe(() => dialogRef.close()); } } } NbDialogService.decorators = [ { type: Injectable } ]; /** @nocollapse */ NbDialogService.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [NB_DOCUMENT,] }] }, { type: undefined, decorators: [{ type: Inject, args: [NB_DIALOG_CONFIG,] }] }, { type: NbPositionBuilderService }, { type: NbOverlayService }, { type: Injector }, { type: ComponentFactoryResolver } ]; if (false) { /** * @type {?} * @protected */ NbDialogService.prototype.document; /** * @type {?} * @protected */ NbDialogService.prototype.globalConfig; /** * @type {?} * @protected */ NbDialogService.prototype.positionBuilder; /** * @type {?} * @protected */ NbDialogService.prototype.overlay; /** * @type {?} * @protected */ NbDialogService.prototype.injector; /** * @type {?} * @protected */ NbDialogService.prototype.cfr; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9kaWFsb2cvZGlhbG9nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBTUEsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBUSxNQUFNLGVBQWUsQ0FBQztBQUMxRyxPQUFPLEVBQUUsU0FBUyxJQUFJLG1CQUFtQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QyxPQUFPLEVBQ0wsaUJBQWlCLEVBR2pCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBRXhCLGdCQUFnQixHQUNqQixNQUFNLFFBQVEsQ0FBQztBQUNoQixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDM0MsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFIaEUsTUFBTSxPQUFPLGVBQWU7Ozs7Ozs7OztJQUMxQixZQUEyQyxRQUFRLEVBQ0gsWUFBWSxFQUN0QyxlQUF5QyxFQUN6QyxPQUF5QixFQUN6QixRQUFrQixFQUNsQixHQUE2QjtRQUxSLGFBQVEsR0FBUixRQUFRLENBQUE7UUFDSCxpQkFBWSxHQUFaLFlBQVksQ0FBQTtRQUN0QyxvQkFBZSxHQUFm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O1NBQy9EO1FBRUQsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFO1lBQ3JCLG1CQUFtQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDO2lCQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBb0IsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sS0FBSyxFQUFFLENBQUMsQ0FBQztpQkFDNUQsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1NBQ3ZDO0lBQ0gsQ0FBQzs7O1lBNUdGLFVBQVU7Ozs7NENBRUksTUFBTSxTQUFDLFdBQVc7NENBQ2xCLE1BQU0sU0FBQyxnQkFBZ0I7WUE5SHBDLHdCQUF3QjtZQUZ4QixnQkFBZ0I7WUFScUMsUUFBUTtZQUF0RCx3QkFBd0I7Ozs7Ozs7SUF1SW5CLG1DQUF1Qzs7Ozs7SUFDdkMsdUNBQWdEOzs7OztJQUNoRCwwQ0FBbUQ7Ozs7O0lBQ25ELGtDQUFtQzs7Ozs7SUFDbkMsbUNBQTRCOzs7OztJQUM1Qiw4QkFBdUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBAbGljZW5zZVxyXG4gKiBDb3B5cmlnaHQgQWt2ZW8uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBJbmplY3QsIEluamVjdGFibGUsIEluamVjdG9yLCBUZW1wbGF0ZVJlZiwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBmcm9tRXZlbnQgYXMgb2JzZXJ2YWJsZUZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQge1xyXG4gIE5iQ29tcG9uZW50UG9ydGFsLFxyXG4gIE5iR2xvYmFsUG9zaXRpb25TdHJhdGVneSxcclxuICBOYk92ZXJsYXlSZWYsXHJcbiAgTmJPdmVybGF5U2VydmljZSxcclxuICBOYlBvcnRhbEluamVjdG9yLFxyXG4gIE5iUG9zaXRpb25CdWlsZGVyU2VydmljZSxcclxuICBOYlNjcm9sbFN0cmF0ZWd5LFxyXG4gIE5iVGVtcGxhdGVQb3J0YWwsXHJcbn0gZnJvbSAnLi4vY2RrJztcclxuaW1wb3J0IHsgTkJfRE9DVU1FTlQgfSBmcm9tICcuLi8uLi90aGVtZS5vcHRpb25zJztcclxuaW1wb3J0IHsgTkJfRElBTE9HX0NPTkZJRywgTmJEaWFsb2dDb25maWcgfSBmcm9tICcuL2RpYWxvZy1jb25maWcnO1xyXG5pbXBvcnQgeyBOYkRpYWxvZ1JlZiB9IGZyb20gJy4vZGlhbG9nLXJlZic7XHJcbmltcG9ydCB7IE5iRGlhbG9nQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9kaWFsb2ctY29udGFpbmVyJztcclxuXHJcblxyXG4vKlxyXG4gKiBUaGUgYE5iRGlhbG9nU2VydmljZWAgaGVscHMgdG8gb3BlbiBkaWFsb2dzLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFNob3djYXNlLCBkaWFsb2cvZGlhbG9nLXNob3djYXNlLmNvbXBvbmVudClcclxuICpcclxuICogQSBuZXcgZGlhbG9nIGlzIG9wZW5lZCBieSBjYWxsaW5nIHRoZSBgb3BlbmAgbWV0aG9kIHdpdGggYSBjb21wb25lbnQgdG8gYmUgbG9hZGVkIGFuZCBhbiBvcHRpb25hbCBjb25maWd1cmF0aW9uLlxyXG4gKiBgb3BlbmAgbWV0aG9kIHdpbGwgcmV0dXJuIGBOYkRpYWxvZ1JlZmAgdGhhdCBjYW4gYmUgdXNlZCBmb3IgdGhlIGZ1cnRoZXIgbWFuaXB1bGF0aW9ucy5cclxuICpcclxuICogIyMjIEluc3RhbGxhdGlvblxyXG4gKlxyXG4gKiBJbXBvcnQgYE5iRGlhbG9nTW9kdWxlLmZvclJvb3QoKWAgdG8geW91ciBhcHAgbW9kdWxlLlxyXG4gKiBgYGB0c1xyXG4gKiBATmdNb2R1bGUoe1xyXG4gKiAgIGltcG9ydHM6IFtcclxuICogICBcdC8vIC4uLlxyXG4gKiAgICAgTmJEaWFsb2dNb2R1bGUuZm9yUm9vdChjb25maWcpLFxyXG4gKiAgIF0sXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBBcHBNb2R1bGUgeyB9XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBJZiB5b3UgYXJlIHVzaW5nIGl0IGluIGEgbGF6eSBsb2FkZWQgbW9kdWxlIHRoYW4geW91IGhhdmUgdG8gaW5zdGFsbCBpdCB3aXRoIGBOYkRpYWxvZ01vZHVsZS5mb3JDaGlsZCgpYDpcclxuICogYGBgdHNcclxuICogQE5nTW9kdWxlKHtcclxuICogICBpbXBvcnRzOiBbXHJcbiAqICAgXHQvLyAuLi5cclxuICogICAgIE5iRGlhbG9nTW9kdWxlLmZvckNoaWxkKGNvbmZpZyksXHJcbiAqICAgXSxcclxuICogfSlcclxuICogZXhwb3J0IGNsYXNzIExhenlMb2FkZWRNb2R1bGUgeyB9XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiAjIyMgVXNhZ2VcclxuICpcclxuICogYGBgdHNcclxuICogY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dTZXJ2aWNlLm9wZW4oTXlEaWFsb2dDb21wb25lbnQsIHsgLi4uIH0pO1xyXG4gKiBgYGBcclxuICpcclxuICogYE5iRGlhbG9nUmVmYCBnaXZlcyBjYXBhYmlsaXR5IGFjY2VzcyByZWZlcmVuY2UgdG8gdGhlIHJlbmRlcmVkIGRpYWxvZyBjb21wb25lbnQsXHJcbiAqIGRlc3Ryb3kgZGlhbG9nIGFuZCBzb21lIG90aGVyIG9wdGlvbnMgZGVzY3JpYmVkIGJlbG93LlxyXG4gKlxyXG4gKiBBbHNvLCB5b3UgY2FuIGluamVjdCBgTmJEaWFsb2dSZWZgIGluIGRpYWxvZyBjb21wb25lbnQuXHJcbiAqXHJcbiAqIGBgYHRzXHJcbiAqIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKE15RGlhbG9nQ29tcG9uZW50LCB7IC4uLiB9KTtcclxuICpcclxuICogLy8gbXktZGlhbG9nLmNvbXBvbmVudC50c1xyXG4gKiBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgZGlhbG9nUmVmOiBOYkRpYWxvZ1JlZikge1xyXG4gKiB9XHJcbiAqXHJcbiAqIGNsb3NlKCkge1xyXG4gKiAgIHRoaXMuZGlhbG9nUmVmLmNsb3NlKCk7XHJcbiAqIH1cclxuICogYGBgXHJcbiAqXHJcbiAqIEluc3RlYWQgb2YgY29tcG9uZW50IHlvdSBjYW4gY3JlYXRlIGRpYWxvZyBmcm9tIFRlbXBsYXRlUmVmOlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFRlbXBsYXRlIHJlZiwgZGlhbG9nL2RpYWxvZy10ZW1wbGF0ZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqIFRoZSBkaWFsb2cgbWF5IHJldHVybiByZXN1bHQgdGhyb3VnaCBgTmJEaWFsb2dSZWZgLiBDYWxsaW5nIGNvbXBvbmVudCBjYW4gcmVjZWl2ZSB0aGlzIHJlc3VsdCB3aXRoIGBvbkNsb3NlYFxyXG4gKiBzdHJlYW0gb2YgYE5iRGlhbG9nUmVmYC5cclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShSZXN1bHQsIGRpYWxvZy9kaWFsb2ctcmVzdWx0LmNvbXBvbmVudClcclxuICpcclxuICogIyMjIENvbmZpZ3VyYXRpb25cclxuICpcclxuICogQXMgd2UgbWVudGlvbmVkIGFib3ZlLCBgb3BlbmAgbWV0aG9kIG9mIHRoZSBgTmJEaWFsb2dTZXJ2aWNlYCBtYXkgcmVjZWl2ZSBvcHRpb25hbCBjb25maWd1cmF0aW9uIG9wdGlvbnMuXHJcbiAqIEFsc28sIHlvdSBjYW4gcHJvdmlkZSBnbG9iYWwgZGlhbG9ncyBjb25maWd1cmF0aW9uIHRocm91Z2ggYE5iRGlhbG9nTW9kdWxlLmZvclJvb3QoeyAuLi4gfSlgLlxyXG4gKlxyXG4gKiBUaGlzIGNvbmZpZyBtYXkgY29udGFpbiB0aGUgZm9sbG93aW5nOlxyXG4gKlxyXG4gKiBgY29udGV4dGAgLSBib3RoLCB0ZW1wbGF0ZSBhbmQgY29tcG9uZW50IG1heSByZWNlaXZlIGRhdGEgdGhyb3VnaCBgY29uZmlnLmNvbnRleHRgIHByb3BlcnR5LlxyXG4gKiBGb3IgY29tcG9uZW50cywgdGhpcyBkYXRhIHdpbGwgYmUgYXNzaWduZWQgdGhyb3VnaCBpbnB1dHMuXHJcbiAqIEZvciB0ZW1wbGF0ZXMsIHlvdSBjYW4gYWNjZXNzIGl0IGluc2lkZSB0ZW1wbGF0ZSBhcyAkaW1wbGljaXQuXHJcbiAqXHJcbiAqIGBgYHRzXHJcbiAqIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuKHRlbXBsYXRlLCB7IGNvbnRleHQ6ICdwYXNzIGRhdGEgaW4gdGVtcGxhdGUnIH0pO1xyXG4gKiBgYGBcclxuICpcclxuICogYGBgaHRtbFxyXG4gKiA8bmctdGVtcGxhdGUgbGV0LXNvbWUtYWRkaXRpb25hbC1kYXRhPlxyXG4gKiAgIHt7IHNvbWUtYWRkaXRpb25hbC1kYXRhIH19XHJcbiAqIDxuZy10ZW1wbGF0ZS8+XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBgaGFzQmFja2Ryb3BgIC0gZGV0ZXJtaW5lcyBpcyBzZXJ2aWNlIGhhdmUgdG8gcmVuZGVyIGJhY2tkcm9wIHVuZGVyIHRoZSBkaWFsb2cuXHJcbiAqIERlZmF1bHQgaXMgdHJ1ZS5cclxuICogQHN0YWNrZWQtZXhhbXBsZShCYWNrZHJvcCwgZGlhbG9nL2RpYWxvZy1oYXMtYmFja2Ryb3AuY29tcG9uZW50KVxyXG4gKlxyXG4gKiBgY2xvc2VPbkJhY2tkcm9wQ2xpY2tgIC0gY2xvc2UgZGlhbG9nIG9uIGJhY2tkcm9wIGNsaWNrIGlmIHRydWUuXHJcbiAqIERlZmF1bHQgaXMgdHJ1ZS5cclxuICogQHN0YWNrZWQtZXhhbXBsZShCYWNrZHJvcCBjbGljaywgZGlhbG9nL2RpYWxvZy1iYWNrZHJvcC1jbGljay5jb21wb25lbnQpXHJcbiAqXHJcbiAqIGBjbG9zZU9uRXNjYCAtIGNsb3NlIGRpYWxvZyBvbiBlc2NhcGUgYnV0dG9uIG9uIHRoZSBrZXlib2FyZC5cclxuICogRGVmYXVsdCBpcyB0cnVlLlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKEVzY2FwZSBoaXQsIGRpYWxvZy9kaWFsb2ctZXNjLmNvbXBvbmVudClcclxuICpcclxuICogYGhhc1Njcm9sbGAgLSBEaXNhYmxlcyBzY3JvbGwgb24gY29udGVudCB1bmRlciBkaWFsb2cgaWYgdHJ1ZSBhbmQgZG9lcyBub3RoaW5nIG90aGVyd2lzZS5cclxuICogRGVmYXVsdCBpcyBmYWxzZS5cclxuICogUGxlYXNlLCBvcGVuIGRpYWxvZ3MgaW4gdGhlIHNlcGFyYXRlIHdpbmRvdyBhbmQgdHJ5IHRvIHNjcm9sbC5cclxuICogQHN0YWNrZWQtZXhhbXBsZShTY3JvbGwsIGRpYWxvZy9kaWFsb2ctc2Nyb2xsLmNvbXBvbmVudClcclxuICpcclxuICogYGF1dG9Gb2N1c2AgLSBGb2N1c2VzIGRpYWxvZyBhdXRvbWF0aWNhbGx5IGFmdGVyIG9wZW4gaWYgdHJ1ZS4gSXQncyB1c2VmdWwgdG8gcHJldmVudCBtaXNjbGlja3Mgb25cclxuICogdHJpZ2dlciBlbGVtZW50cyBhbmQgb3BlbmluZyBtdWx0aXBsZSBkaWFsb2dzLlxyXG4gKiBEZWZhdWx0IGlzIHRydWUuXHJcbiAqXHJcbiAqIEFzIHlvdSBjYW4gc2VlLCBpZiB5b3Ugb3BlbiBkaWFsb2cgd2l0aCBhdXRvIGZvY3VzIGRpYWxvZyB3aWxsIGZvY3VzIGZpcnN0IGZvY3VzYWJsZSBlbGVtZW50XHJcbiAqIG9yIGp1c3QgYmx1ciBwcmV2aW91c2x5IGZvY3VzZWQgYXV0b21hdGljYWxseS5cclxuICogT3RoZXJ3aXNlLCB3aXRob3V0IGF1dG8gZm9jdXMsIHRoZSBmb2N1cyB3aWxsIHN0YXkgb24gdGhlIHByZXZpb3VzbHkgZm9jdXNlZCBlbGVtZW50LlxyXG4gKiBQbGVhc2UsIG9wZW4gZGlhbG9ncyBpbiB0aGUgc2VwYXJhdGUgd2luZG93IGFuZCB0cnkgdG8gY2xpY2sgb24gdGhlIGJ1dHRvbiB3aXRob3V0IGZvY3VzXHJcbiAqIGFuZCB0aGVuIGhpdCBzcGFjZSBhbnkgdGltZXMuIE11bHRpcGxlIHNhbWUgZGlhbG9ncyB3aWxsIGJlIG9wZW5lZC5cclxuICogQHN0YWNrZWQtZXhhbXBsZShBdXRvIGZvY3VzLCBkaWFsb2cvZGlhbG9nLWF1dG8tZm9jdXMuY29tcG9uZW50KVxyXG4gKiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBOYkRpYWxvZ1NlcnZpY2Uge1xyXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoTkJfRE9DVU1FTlQpIHByb3RlY3RlZCBkb2N1bWVudCxcclxuICAgICAgICAgICAgICBASW5qZWN0KE5CX0RJQUxPR19DT05GSUcpIHByb3RlY3RlZCBnbG9iYWxDb25maWcsXHJcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIHBvc2l0aW9uQnVpbGRlcjogTmJQb3NpdGlvbkJ1aWxkZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBvdmVybGF5OiBOYk92ZXJsYXlTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBpbmplY3RvcjogSW5qZWN0b3IsXHJcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIGNmcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyKSB7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIE9wZW5zIG5ldyBpbnN0YW5jZSBvZiB0aGUgZGlhbG9nLCBtYXkgcmVjZWl2ZSBvcHRpb25hbCBjb25maWcuXHJcbiAgICogKi9cclxuICBvcGVuPFQ+KGNvbnRlbnQ6IFR5cGU8VD4gfCBUZW1wbGF0ZVJlZjxUPiwgdXNlckNvbmZpZzogUGFydGlhbDxOYkRpYWxvZ0NvbmZpZzxUPj4gPSB7fSk6IE5iRGlhbG9nUmVmPFQ+IHtcclxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBOYkRpYWxvZ0NvbmZpZyh7IC4uLnRoaXMuZ2xvYmFsQ29uZmlnLCAuLi51c2VyQ29uZmlnIH0pO1xyXG4gICAgY29uc3Qgb3ZlcmxheVJlZiA9IHRoaXMuY3JlYXRlT3ZlcmxheShjb25maWcpO1xyXG4gICAgY29uc3QgZGlhbG9nUmVmID0gbmV3IE5iRGlhbG9nUmVmPFQ+KG92ZXJsYXlSZWYpO1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5jcmVhdGVDb250YWluZXIoY29uZmlnLCBvdmVybGF5UmVmKTtcclxuICAgIHRoaXMuY3JlYXRlQ29udGVudChjb25maWcsIGNvbnRlbnQsIGNvbnRhaW5lciwgZGlhbG9nUmVmKTtcclxuXHJcbiAgICB0aGlzLnJlZ2lzdGVyQ2xvc2VMaXN0ZW5lcnMoY29uZmlnLCBvdmVybGF5UmVmLCBkaWFsb2dSZWYpO1xyXG5cclxuICAgIHJldHVybiBkaWFsb2dSZWY7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgY3JlYXRlT3ZlcmxheShjb25maWc6IE5iRGlhbG9nQ29uZmlnKTogTmJPdmVybGF5UmVmIHtcclxuICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3kgPSB0aGlzLmNyZWF0ZVBvc2l0aW9uU3RyYXRlZ3koKTtcclxuICAgIGNvbnN0IHNjcm9sbFN0cmF0ZWd5ID0gdGhpcy5jcmVhdGVTY3JvbGxTdHJhdGVneShjb25maWcuaGFzU2Nyb2xsKTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5vdmVybGF5LmNyZWF0ZSh7XHJcbiAgICAgIHBvc2l0aW9uU3RyYXRlZ3ksXHJcbiAgICAgIHNjcm9sbFN0cmF0ZWd5LFxyXG4gICAgICBoYXNCYWNrZHJvcDogY29uZmlnLmhhc0JhY2tkcm9wLFxyXG4gICAgICBiYWNrZHJvcENsYXNzOiBjb25maWcuYmFja2Ryb3BDbGFzcyxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZVBvc2l0aW9uU3RyYXRlZ3koKTogTmJHbG9iYWxQb3NpdGlvblN0cmF0ZWd5IHtcclxuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uQnVpbGRlclxyXG4gICAgICAuZ2xvYmFsKClcclxuICAgICAgLmNlbnRlclZlcnRpY2FsbHkoKVxyXG4gICAgICAuY2VudGVySG9yaXpvbnRhbGx5KCk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgY3JlYXRlU2Nyb2xsU3RyYXRlZ3koaGFzU2Nyb2xsOiBib29sZWFuKTogTmJTY3JvbGxTdHJhdGVneSB7XHJcbiAgICBpZiAoaGFzU2Nyb2xsKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLm92ZXJsYXkuc2Nyb2xsU3RyYXRlZ2llcy5ub29wKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMuYmxvY2soKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjcmVhdGVDb250YWluZXIoY29uZmlnOiBOYkRpYWxvZ0NvbmZpZywgb3ZlcmxheVJlZjogTmJPdmVybGF5UmVmKTogTmJEaWFsb2dDb250YWluZXJDb21wb25lbnQge1xyXG4gICAgY29uc3QgaW5qZWN0b3IgPSBuZXcgTmJQb3J0YWxJbmplY3Rvcih0aGlzLmNyZWF0ZUluamVjdG9yKGNvbmZpZyksIG5ldyBXZWFrTWFwKFtbTmJEaWFsb2dDb25maWcsIGNvbmZpZ11dKSk7XHJcbiAgICBjb25zdCBjb250YWluZXJQb3J0YWwgPSBuZXcgTmJDb21wb25lbnRQb3J0YWwoTmJEaWFsb2dDb250YWluZXJDb21wb25lbnQsIG51bGwsIGluamVjdG9yLCB0aGlzLmNmcik7XHJcbiAgICBjb25zdCBjb250YWluZXJSZWYgPSBvdmVybGF5UmVmLmF0dGFjaChjb250YWluZXJQb3J0YWwpO1xyXG4gICAgcmV0dXJuIGNvbnRhaW5lclJlZi5pbnN0YW5jZTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBjcmVhdGVDb250ZW50PFQ+KGNvbmZpZzogTmJEaWFsb2dDb25maWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogVHlwZTxUPiB8IFRlbXBsYXRlUmVmPFQ+LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogTmJEaWFsb2dDb250YWluZXJDb21wb25lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nUmVmOiBOYkRpYWxvZ1JlZjxUPikge1xyXG4gICAgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBUZW1wbGF0ZVJlZikge1xyXG4gICAgICBjb25zdCBwb3J0YWwgPSB0aGlzLmNyZWF0ZVRlbXBsYXRlUG9ydGFsKGNvbmZpZywgY29udGVudCwgZGlhbG9nUmVmKTtcclxuICAgICAgY29udGFpbmVyLmF0dGFjaFRlbXBsYXRlUG9ydGFsKHBvcnRhbCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBwb3J0YWwgPSB0aGlzLmNyZWF0ZUNvbXBvbmVudFBvcnRhbChjb25maWcsIGNvbnRlbnQsIGRpYWxvZ1JlZik7XHJcbiAgICAgIGRpYWxvZ1JlZi5jb21wb25lbnRSZWYgPSBjb250YWluZXIuYXR0YWNoQ29tcG9uZW50UG9ydGFsKHBvcnRhbCk7XHJcblxyXG4gICAgICBpZiAoY29uZmlnLmNvbnRleHQpIHtcclxuICAgICAgICBPYmplY3QuYXNzaWduKGRpYWxvZ1JlZi5jb21wb25lbnRSZWYuaW5zdGFuY2UsIHsgLi4uY29uZmlnLmNvbnRleHQgfSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZVRlbXBsYXRlUG9ydGFsPFQ+KGNvbmZpZzogTmJEaWFsb2dDb25maWcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFRlbXBsYXRlUmVmPFQ+LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWY6IE5iRGlhbG9nUmVmPFQ+KTogTmJUZW1wbGF0ZVBvcnRhbCB7XHJcbiAgICByZXR1cm4gbmV3IE5iVGVtcGxhdGVQb3J0YWwoY29udGVudCwgbnVsbCwgPGFueT57ICRpbXBsaWNpdDogY29uZmlnLmNvbnRleHQsIGRpYWxvZ1JlZiB9KTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogV2UncmUgY3JlYXRpbmcgcG9ydGFsIHdpdGggY3VzdG9tIGluamVjdG9yIHByb3ZpZGVkIHRocm91Z2ggY29uZmlnIG9yIHVzaW5nIGdsb2JhbCBpbmplY3Rvci5cclxuICAgKiBUaGlzIGFwcHJvYWNoIHByb3ZpZGVzIHVzIGNhcGFiaWxpdHkgaW5qZWN0IGBOYkRpYWxvZ1JlZmAgaW4gZGlhbG9nIGNvbXBvbmVudC5cclxuICAgKiAqL1xyXG4gIHByb3RlY3RlZCBjcmVhdGVDb21wb25lbnRQb3J0YWw8VD4oY29uZmlnOiBOYkRpYWxvZ0NvbmZpZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFR5cGU8VD4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWY6IE5iRGlhbG9nUmVmPFQ+KTogTmJDb21wb25lbnRQb3J0YWwge1xyXG4gICAgY29uc3QgaW5qZWN0b3IgPSB0aGlzLmNyZWF0ZUluamVjdG9yKGNvbmZpZyk7XHJcbiAgICBjb25zdCBwb3J0YWxJbmplY3RvciA9IG5ldyBOYlBvcnRhbEluamVjdG9yKGluamVjdG9yLCBuZXcgV2Vha01hcChbW05iRGlhbG9nUmVmLCBkaWFsb2dSZWZdXSkpO1xyXG4gICAgcmV0dXJuIG5ldyBOYkNvbXBvbmVudFBvcnRhbChjb250ZW50LCBjb25maWcudmlld0NvbnRhaW5lclJlZiwgcG9ydGFsSW5qZWN0b3IpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGNyZWF0ZUluamVjdG9yKGNvbmZpZzogTmJEaWFsb2dDb25maWcpOiBJbmplY3RvciB7XHJcbiAgICByZXR1cm4gY29uZmlnLnZpZXdDb250YWluZXJSZWYgJiYgY29uZmlnLnZpZXdDb250YWluZXJSZWYuaW5qZWN0b3IgfHwgdGhpcy5pbmplY3RvcjtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCByZWdpc3RlckNsb3NlTGlzdGVuZXJzPFQ+KGNvbmZpZzogTmJEaWFsb2dDb25maWcsIG92ZXJsYXlSZWY6IE5iT3ZlcmxheVJlZiwgZGlhbG9nUmVmOiBOYkRpYWxvZ1JlZjxUPikge1xyXG4gICAgaWYgKGNvbmZpZy5jbG9zZU9uQmFja2Ryb3BDbGljaykge1xyXG4gICAgICBvdmVybGF5UmVmLmJhY2tkcm9wQ2xpY2soKS5zdWJzY3JpYmUoKCkgPT4gZGlhbG9nUmVmLmNsb3NlKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjb25maWcuY2xvc2VPbkVzYykge1xyXG4gICAgICBvYnNlcnZhYmxlRnJvbUV2ZW50KHRoaXMuZG9jdW1lbnQsICdrZXl1cCcpXHJcbiAgICAgICAgLnBpcGUoZmlsdGVyKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gZXZlbnQua2V5Q29kZSA9PT0gMjcpKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gZGlhbG9nUmVmLmNsb3NlKCkpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=