@dotglitch/ngx-common 1.1.17 → 1.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/components/command-palette/breadcrumb/breadcrumb.component.d.ts +16 -0
  2. package/components/command-palette/command-palette.component.d.ts +21 -3
  3. package/components/command-palette/shortcut/shortcut.component.d.ts +1 -1
  4. package/components/menu/menu.component.d.ts +1 -1
  5. package/directives/image-cache.directive.d.ts +46 -0
  6. package/directives/menu.directive.d.ts +1 -1
  7. package/esm2022/components/command-palette/breadcrumb/breadcrumb.component.mjs +30 -0
  8. package/esm2022/components/command-palette/command-palette.component.mjs +191 -54
  9. package/esm2022/components/command-palette/shortcut/shortcut.component.mjs +5 -5
  10. package/esm2022/components/dynamic-html/dynamic-html.component.mjs +3 -3
  11. package/esm2022/components/dynamic-html/dynamic-html.module.mjs +4 -4
  12. package/esm2022/components/dynamic-html/dynamic-html.service.mjs +3 -3
  13. package/esm2022/components/filemanager/file-grid/file-grid.component.mjs +3 -3
  14. package/esm2022/components/filemanager/filemanager.component.mjs +3 -3
  15. package/esm2022/components/filemanager/folder-rename/folder-rename.component.mjs +3 -3
  16. package/esm2022/components/filemanager/toolbar/breadcrumb/breadcrumb.component.mjs +3 -3
  17. package/esm2022/components/filemanager/toolbar/icon-button/icon-button.component.mjs +3 -3
  18. package/esm2022/components/filemanager/toolbar/toolbar.component.mjs +3 -3
  19. package/esm2022/components/filemanager/tree-view/tree-view.component.mjs +3 -3
  20. package/esm2022/components/lazy-loader/lazy-loader.component.mjs +3 -3
  21. package/esm2022/components/lazy-loader/lazy-loader.module.mjs +4 -4
  22. package/esm2022/components/lazy-loader/lazy-loader.service.mjs +3 -3
  23. package/esm2022/components/menu/menu.component.mjs +11 -8
  24. package/esm2022/components/react-magic-wrapper/react-magic-wrapper.component.mjs +3 -3
  25. package/esm2022/components/tabulator/tabulator.component.mjs +3 -3
  26. package/esm2022/components/tooltip/tooltip.component.mjs +3 -3
  27. package/esm2022/components/vscode/vscode.component.mjs +3 -3
  28. package/esm2022/directives/image-cache.directive.mjs +143 -0
  29. package/esm2022/directives/menu.directive.mjs +27 -29
  30. package/esm2022/directives/tooltip.directive.mjs +24 -28
  31. package/esm2022/pipes/html-bypass.pipe.mjs +3 -3
  32. package/esm2022/pipes/resource-bypass.pipe.mjs +3 -3
  33. package/esm2022/pipes/script-bypass.pipe.mjs +3 -3
  34. package/esm2022/pipes/style-bypass.pipe.mjs +3 -3
  35. package/esm2022/pipes/url-bypass.pipe.mjs +3 -3
  36. package/esm2022/public-api.mjs +2 -1
  37. package/esm2022/services/command-palette.service.mjs +8 -5
  38. package/esm2022/services/dependency.service.mjs +3 -3
  39. package/esm2022/services/dialog.service.mjs +3 -3
  40. package/esm2022/services/fetch.service.mjs +3 -3
  41. package/esm2022/services/file.service.mjs +3 -3
  42. package/esm2022/services/keyboard.service.mjs +3 -3
  43. package/esm2022/services/navigation.service.mjs +3 -3
  44. package/esm2022/services/theme.service.mjs +3 -3
  45. package/fesm2022/{dotglitch-ngx-common-folder-rename.component-0RqscdRS.mjs → dotglitch-ngx-common-folder-rename.component-VI_uH5-6.mjs} +8 -7
  46. package/fesm2022/dotglitch-ngx-common-folder-rename.component-VI_uH5-6.mjs.map +1 -0
  47. package/fesm2022/dotglitch-ngx-common.mjs +515 -215
  48. package/fesm2022/dotglitch-ngx-common.mjs.map +1 -1
  49. package/package.json +5 -4
  50. package/public-api.d.ts +1 -0
  51. package/services/command-palette.service.d.ts +20 -1
  52. package/fesm2022/dotglitch-ngx-common-folder-rename.component-0RqscdRS.mjs.map +0 -1
@@ -0,0 +1,16 @@
1
+ import { CommandPaletteComponent } from '../command-palette.component';
2
+ import { CommandAction } from '../../../services/command-palette.service';
3
+ import * as i0 from "@angular/core";
4
+ export declare class BreadcrumbComponent {
5
+ private commandPalette;
6
+ breadcrumbs: {
7
+ action: CommandAction;
8
+ commands: CommandAction[];
9
+ destroying: boolean;
10
+ selectedIndex: number;
11
+ }[];
12
+ constructor(commandPalette: CommandPaletteComponent);
13
+ selectBreadcrumb(crumb: any): void;
14
+ static ɵfac: i0.ɵɵFactoryDeclaration<BreadcrumbComponent, never>;
15
+ static ɵcmp: i0.ɵɵComponentDeclaration<BreadcrumbComponent, "ngx-commandpalette-breadcrumb", never, { "breadcrumbs": { "alias": "breadcrumbs"; "required": false; }; }, {}, never, never, true, never>;
16
+ }
@@ -1,20 +1,38 @@
1
- import { OnInit } from '@angular/core';
1
+ import { ChangeDetectorRef, ElementRef, OnInit } from '@angular/core';
2
2
  import { CommandAction, CommandPaletteService } from '../../services/command-palette.service';
3
3
  import { MatDialogRef } from '@angular/material/dialog';
4
+ import { NgScrollbar } from 'ngx-scrollbar';
4
5
  import * as i0 from "@angular/core";
5
6
  export declare class CommandPaletteComponent implements OnInit {
6
7
  private readonly commandPalette;
7
8
  private readonly dialog;
9
+ private readonly elementRef;
10
+ private readonly changeDetector;
11
+ scrollbar: NgScrollbar;
12
+ textInput: ElementRef<HTMLInputElement>;
8
13
  contextElement: HTMLElement;
14
+ get el(): HTMLElement;
15
+ readonly MAT_ICON_REGEX: RegExp;
9
16
  queryString: string;
10
17
  activeIndex: number;
18
+ readonly rowHeight = 29;
19
+ readonly padding = 6;
11
20
  commands: CommandAction[];
12
21
  filteredCommands: CommandAction[];
13
- constructor(commandPalette: CommandPaletteService, dialog: MatDialogRef<any>, data: any);
22
+ breadcrumbs: {
23
+ action: CommandAction;
24
+ commands: CommandAction[];
25
+ destroying: boolean;
26
+ selectedIndex: number;
27
+ }[];
28
+ constructor(commandPalette: CommandPaletteService, dialog: MatDialogRef<any>, elementRef: ElementRef, changeDetector: ChangeDetectorRef, data: any);
14
29
  ngOnInit(): void;
15
30
  onKeyDown(evt: KeyboardEvent): void;
31
+ private filterResults;
32
+ setCommandList(commands: CommandAction[]): void;
33
+ private focusRow;
16
34
  executeCommand(command: CommandAction): void;
17
35
  onBlur(): void;
18
36
  static ɵfac: i0.ɵɵFactoryDeclaration<CommandPaletteComponent, never>;
19
- static ɵcmp: i0.ɵɵComponentDeclaration<CommandPaletteComponent, "app-command-palette", never, { "contextElement": { "alias": "contextElement"; "required": false; }; }, {}, never, never, true, never>;
37
+ static ɵcmp: i0.ɵɵComponentDeclaration<CommandPaletteComponent, "ngx-command-palette", never, { "contextElement": { "alias": "contextElement"; "required": false; }; }, {}, never, never, true, never>;
20
38
  }
@@ -5,5 +5,5 @@ export declare class ShortcutComponent {
5
5
  keys: string[];
6
6
  ngOnChanges(): void;
7
7
  static ɵfac: i0.ɵɵFactoryDeclaration<ShortcutComponent, never>;
8
- static ɵcmp: i0.ɵɵComponentDeclaration<ShortcutComponent, "app-shortcut", never, { "shortcut": { "alias": "shortcut"; "required": false; }; }, {}, never, never, true, never>;
8
+ static ɵcmp: i0.ɵɵComponentDeclaration<ShortcutComponent, "ngx-commandpalette-shortcut", never, { "shortcut": { "alias": "shortcut"; "required": false; }; }, {}, never, never, true, never>;
9
9
  }
@@ -50,7 +50,7 @@ export declare class MenuComponent implements OnInit {
50
50
  * @param evt
51
51
  * @returns
52
52
  */
53
- onMenuItemClick(item: MenuItem, row: HTMLTableRowElement): Promise<any>;
53
+ onMenuItemClick(item: MenuItem, row: HTMLTableRowElement, keepOpen?: boolean): Promise<any>;
54
54
  /**
55
55
  *
56
56
  * @param label
@@ -0,0 +1,46 @@
1
+ import { ElementRef, InjectionToken } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export type NgxImageCacheConfig = {
4
+ /**
5
+ * Image to use as a placeholder while loading the main image
6
+ * Recommended to use inlined SVG or a base64 encoded image
7
+ */
8
+ loadingPlaceholder?: string;
9
+ /**
10
+ * Image to use as a placeholder where images fail to load
11
+ * Recommended to use inlined SVG or a base64 encoded image
12
+ */
13
+ brokenPlaceholder?: string;
14
+ };
15
+ export declare const NGX_IMAGE_CACHE_CONFIG: InjectionToken<NgxImageCacheConfig>;
16
+ export type NgxImageCacheConfiguration = {
17
+ /**
18
+ * Max age to cache an image in milliseconds.
19
+ * If set to `0` or a negative number, images will never expire.
20
+ */
21
+ maxAge: number;
22
+ /**
23
+ * Set to `false` to disable memory caching for the image
24
+ * If both `cacheInMemory` and `cacheInIndexedDB` are false,
25
+ * no caching will happen. (You'll still get the loader)
26
+ */
27
+ cacheInMemory: boolean;
28
+ /**
29
+ * Set to `false` to disable indexedDB caching for the image
30
+ * If both `cacheInMemory` and `cacheInIndexedDB` are false,
31
+ * no caching will happen. (You'll still get the loader)
32
+ */
33
+ cacheInIndexedDB: boolean;
34
+ };
35
+ export declare class NgxImageCacheDirective {
36
+ private readonly element;
37
+ private readonly cacheConfig;
38
+ url: string;
39
+ configuration: NgxImageCacheConfiguration;
40
+ private get el();
41
+ constructor(element: ElementRef, cacheConfig: NgxImageCacheConfig);
42
+ ngOnChanges(): void;
43
+ getCachedImage(): Promise<void>;
44
+ static ɵfac: i0.ɵɵFactoryDeclaration<NgxImageCacheDirective, [null, { optional: true; }]>;
45
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NgxImageCacheDirective, "img[ngx-cache]", never, { "url": { "alias": "source"; "required": false; }; "configuration": { "alias": "ngx-cache-config"; "required": false; }; }, {}, never, never, true, never>;
46
+ }
@@ -24,7 +24,7 @@ export declare class MenuDirective {
24
24
  config: MenuOptions;
25
25
  constructor(dialog: MatDialog, viewContainer: ViewContainerRef);
26
26
  ngAfterViewInit(): void;
27
- openMenu(evt: PointerEvent, items?: MenuItem[]): Promise<[value: any]>;
27
+ openMenu(evt: PointerEvent, items?: MenuItem[], keepOpen?: boolean): Promise<[value: any]>;
28
28
  static ɵfac: i0.ɵɵFactoryDeclaration<MenuDirective, never>;
29
29
  static ɵdir: i0.ɵɵDirectiveDeclaration<MenuDirective, "[ngx-contextmenu],[ngx-menu]", never, { "data": { "alias": "ngx-menu-context"; "required": false; }; "ctxMenuItems": { "alias": "ngx-contextmenu"; "required": false; }; "menuItems": { "alias": "ngx-menu"; "required": false; }; "config": { "alias": "ngx-menu-config"; "required": false; }; }, {}, never, never, true, never>;
30
30
  }
@@ -0,0 +1,30 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "../command-palette.component";
4
+ export class BreadcrumbComponent {
5
+ constructor(commandPalette) {
6
+ this.commandPalette = commandPalette;
7
+ this.breadcrumbs = [];
8
+ }
9
+ selectBreadcrumb(crumb) {
10
+ const index = this.breadcrumbs.indexOf(crumb);
11
+ if (index == -1)
12
+ throw new Error("Something terrible happened.");
13
+ const layer = this.breadcrumbs.at(-1);
14
+ layer.destroying = true;
15
+ setTimeout(() => {
16
+ this.commandPalette.setCommandList(this.breadcrumbs.at(-2).commands);
17
+ this.commandPalette.breadcrumbs.pop();
18
+ this.commandPalette.activeIndex = layer.selectedIndex;
19
+ }, 190);
20
+ }
21
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: BreadcrumbComponent, deps: [{ token: i1.CommandPaletteComponent }], target: i0.ɵɵFactoryTarget.Component }); }
22
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.2", type: BreadcrumbComponent, isStandalone: true, selector: "ngx-commandpalette-breadcrumb", inputs: { breadcrumbs: "breadcrumbs" }, ngImport: i0, template: "@for (crumb of breadcrumbs; track crumb; let i = $index) {\n <div class=\"crumb\">\n <div\n class=\"crumb_inner\"\n [class.destroy]=\"crumb.destroying\"\n [class.root]=\"i == 0\"\n (click)=\"selectBreadcrumb(crumb)\"\n >\n {{crumb.action.label}}\n </div>\n </div>\n}\n", styles: [":host{display:flex}.crumb{overflow:hidden;height:26px;padding:0 16px;margin:0 -16px}.crumb .crumb_inner{--background-color: #3498db;color:#fff;position:relative;background:var(--background-color);padding:2px 5px 0 6px;margin-right:12px;text-align:center;white-space:pre;font-size:14px;-webkit-user-select:none;user-select:none;cursor:pointer;transition:transform var(--transition),opacity var(--transition),width var(--transition);animation:crumbIn var(--transition) 1}.crumb .crumb_inner.destroy{animation:crumbOut var(--transition) 1}.crumb .crumb_inner:before,.crumb .crumb_inner:after{content:\"\";position:absolute;top:0;border:0 solid var(--background-color);border-width:14px 8px;width:0;height:0}.crumb .crumb_inner:before{left:-14px;border-left-color:#0000}.crumb .crumb_inner:after{left:100%;border-color:#0000;border-left-color:var(--background-color)}.crumb .crumb_inner:hover{--background-color: #1abc9c}.crumb .crumb_inner:active{--background-color: #16a085}.crumb:nth-child(2n) .crumb_inner{--background-color: #2980b9}.crumb:first-child .crumb_inner{padding-left:6px;border-radius:4px 0 0 4px}.crumb:first-child .crumb_inner:before{border:none}.crumb:last-child:not(:only-child) .crumb_inner{padding-right:6px;border-radius:0 4px 4px 0}.crumb:last-child:not(:only-child) .crumb_inner:after{border:none}@keyframes crumbIn{0%{transform:translate(-10px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes crumbOut{to{transform:translate(-10px);opacity:0}0%{transform:translate(0);opacity:1}}mat-form-field input{transition:width .2s ease,opacity .15s 0ms cubic-bezier(.4,0,.2,1)!important}\n"] }); }
23
+ }
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: BreadcrumbComponent, decorators: [{
25
+ type: Component,
26
+ args: [{ selector: 'ngx-commandpalette-breadcrumb', standalone: true, template: "@for (crumb of breadcrumbs; track crumb; let i = $index) {\n <div class=\"crumb\">\n <div\n class=\"crumb_inner\"\n [class.destroy]=\"crumb.destroying\"\n [class.root]=\"i == 0\"\n (click)=\"selectBreadcrumb(crumb)\"\n >\n {{crumb.action.label}}\n </div>\n </div>\n}\n", styles: [":host{display:flex}.crumb{overflow:hidden;height:26px;padding:0 16px;margin:0 -16px}.crumb .crumb_inner{--background-color: #3498db;color:#fff;position:relative;background:var(--background-color);padding:2px 5px 0 6px;margin-right:12px;text-align:center;white-space:pre;font-size:14px;-webkit-user-select:none;user-select:none;cursor:pointer;transition:transform var(--transition),opacity var(--transition),width var(--transition);animation:crumbIn var(--transition) 1}.crumb .crumb_inner.destroy{animation:crumbOut var(--transition) 1}.crumb .crumb_inner:before,.crumb .crumb_inner:after{content:\"\";position:absolute;top:0;border:0 solid var(--background-color);border-width:14px 8px;width:0;height:0}.crumb .crumb_inner:before{left:-14px;border-left-color:#0000}.crumb .crumb_inner:after{left:100%;border-color:#0000;border-left-color:var(--background-color)}.crumb .crumb_inner:hover{--background-color: #1abc9c}.crumb .crumb_inner:active{--background-color: #16a085}.crumb:nth-child(2n) .crumb_inner{--background-color: #2980b9}.crumb:first-child .crumb_inner{padding-left:6px;border-radius:4px 0 0 4px}.crumb:first-child .crumb_inner:before{border:none}.crumb:last-child:not(:only-child) .crumb_inner{padding-right:6px;border-radius:0 4px 4px 0}.crumb:last-child:not(:only-child) .crumb_inner:after{border:none}@keyframes crumbIn{0%{transform:translate(-10px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes crumbOut{to{transform:translate(-10px);opacity:0}0%{transform:translate(0);opacity:1}}mat-form-field input{transition:width .2s ease,opacity .15s 0ms cubic-bezier(.4,0,.2,1)!important}\n"] }]
27
+ }], ctorParameters: () => [{ type: i1.CommandPaletteComponent }], propDecorators: { breadcrumbs: [{
28
+ type: Input
29
+ }] } });
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJlYWRjcnVtYi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21tb24vc3JjL2NvbXBvbmVudHMvY29tbWFuZC1wYWxldHRlL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21tb24vc3JjL2NvbXBvbmVudHMvY29tbWFuZC1wYWxldHRlL2JyZWFkY3J1bWIvYnJlYWRjcnVtYi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0FBVWpELE1BQU0sT0FBTyxtQkFBbUI7SUFTNUIsWUFDWSxjQUF1QztRQUF2QyxtQkFBYyxHQUFkLGNBQWMsQ0FBeUI7UUFSMUMsZ0JBQVcsR0FLZCxFQUFFLENBQUM7SUFNVCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsS0FBSztRQUNsQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7WUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFFcEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxLQUFLLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN4QixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyRSxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDO1FBQzFELENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUNYLENBQUM7OEdBM0JRLG1CQUFtQjtrR0FBbkIsbUJBQW1CLGlJQ1ZoQyxvV0FZQTs7MkZERmEsbUJBQW1CO2tCQU4vQixTQUFTOytCQUNJLCtCQUErQixjQUc3QixJQUFJOzRGQUlQLFdBQVc7c0JBQW5CLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tYW5kUGFsZXR0ZUNvbXBvbmVudCB9IGZyb20gJy4uL2NvbW1hbmQtcGFsZXR0ZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ29tbWFuZEFjdGlvbiB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2NvbW1hbmQtcGFsZXR0ZS5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduZ3gtY29tbWFuZHBhbGV0dGUtYnJlYWRjcnVtYicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2JyZWFkY3J1bWIuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2JyZWFkY3J1bWIuY29tcG9uZW50LnNjc3MnXSxcbiAgICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIEJyZWFkY3J1bWJDb21wb25lbnQge1xuXG4gICAgQElucHV0KCkgYnJlYWRjcnVtYnM6IHtcbiAgICAgICAgYWN0aW9uOiBDb21tYW5kQWN0aW9uLFxuICAgICAgICBjb21tYW5kczogQ29tbWFuZEFjdGlvbltdLFxuICAgICAgICBkZXN0cm95aW5nOiBib29sZWFuLFxuICAgICAgICBzZWxlY3RlZEluZGV4OiBudW1iZXJcbiAgICB9W10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGNvbW1hbmRQYWxldHRlOiBDb21tYW5kUGFsZXR0ZUNvbXBvbmVudFxuICAgICkge1xuXG4gICAgfVxuXG4gICAgc2VsZWN0QnJlYWRjcnVtYihjcnVtYikge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuYnJlYWRjcnVtYnMuaW5kZXhPZihjcnVtYik7XG4gICAgICAgIGlmIChpbmRleCA9PSAtMSlcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbWV0aGluZyB0ZXJyaWJsZSBoYXBwZW5lZC5cIik7XG5cbiAgICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLmJyZWFkY3J1bWJzLmF0KC0xKTtcbiAgICAgICAgbGF5ZXIuZGVzdHJveWluZyA9IHRydWU7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb21tYW5kUGFsZXR0ZS5zZXRDb21tYW5kTGlzdCh0aGlzLmJyZWFkY3J1bWJzLmF0KC0yKS5jb21tYW5kcyk7XG4gICAgICAgICAgICB0aGlzLmNvbW1hbmRQYWxldHRlLmJyZWFkY3J1bWJzLnBvcCgpO1xuICAgICAgICAgICAgdGhpcy5jb21tYW5kUGFsZXR0ZS5hY3RpdmVJbmRleCA9IGxheWVyLnNlbGVjdGVkSW5kZXg7XG4gICAgICAgIH0sIDE5MClcbiAgICB9XG59XG4iLCJAZm9yIChjcnVtYiBvZiBicmVhZGNydW1iczsgdHJhY2sgY3J1bWI7IGxldCBpID0gJGluZGV4KSB7XG4gICAgPGRpdiBjbGFzcz1cImNydW1iXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwiY3J1bWJfaW5uZXJcIlxuICAgICAgICAgICAgW2NsYXNzLmRlc3Ryb3ldPVwiY3J1bWIuZGVzdHJveWluZ1wiXG4gICAgICAgICAgICBbY2xhc3Mucm9vdF09XCJpID09IDBcIlxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdEJyZWFkY3J1bWIoY3J1bWIpXCJcbiAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7Y3J1bWIuYWN0aW9uLmxhYmVsfX1cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG59XG4iXX0=
@@ -1,51 +1,105 @@
1
- import { Component, HostListener, Inject, Input } from '@angular/core';
1
+ import { Component, HostListener, Inject, Input, ViewChild, isDevMode } from '@angular/core';
2
2
  import { MatInputModule } from '@angular/material/input';
3
3
  import { MAT_DIALOG_DATA } from '@angular/material/dialog';
4
4
  import { ScrollingModule } from '@angular/cdk/scrolling';
5
- import { NgScrollbarModule } from 'ngx-scrollbar';
5
+ import { NgScrollbar, NgScrollbarModule } from 'ngx-scrollbar';
6
6
  import { ShortcutComponent } from './shortcut/shortcut.component';
7
+ import { MatIconModule } from '@angular/material/icon';
8
+ import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
7
9
  import * as i0 from "@angular/core";
8
10
  import * as i1 from "../../services/command-palette.service";
9
11
  import * as i2 from "@angular/material/dialog";
10
- import * as i3 from "@angular/material/input";
11
- import * as i4 from "@angular/material/form-field";
12
- import * as i5 from "@angular/cdk/scrolling";
13
- import * as i6 from "ngx-scrollbar";
12
+ import * as i3 from "@angular/material/icon";
13
+ import * as i4 from "@angular/material/input";
14
+ import * as i5 from "@angular/material/form-field";
15
+ import * as i6 from "@angular/cdk/scrolling";
16
+ import * as i7 from "ngx-scrollbar";
14
17
  export class CommandPaletteComponent {
15
- constructor(commandPalette, dialog, data) {
18
+ get el() { return this.elementRef.nativeElement; }
19
+ constructor(commandPalette, dialog, elementRef, changeDetector, data) {
16
20
  this.commandPalette = commandPalette;
17
21
  this.dialog = dialog;
22
+ this.elementRef = elementRef;
23
+ this.changeDetector = changeDetector;
24
+ this.MAT_ICON_REGEX = /[:\/\.]/;
18
25
  this.queryString = "";
19
26
  this.activeIndex = 0;
27
+ this.rowHeight = 29;
28
+ this.padding = 6;
20
29
  this.commands = [];
21
30
  this.filteredCommands = [];
31
+ this.breadcrumbs = [];
22
32
  this.contextElement = this.contextElement ?? data.contextElement;
23
33
  }
24
34
  ngOnInit() {
25
- this.commands = this.commandPalette.getRegisteredCommands(this.contextElement)
26
- .filter(c => c.visibleInList != false);
27
- this.filteredCommands = this.commands;
28
- // Reset the filter labels
29
- this.commands.forEach(command => command['_renderedLabel'] = '');
35
+ this.commands = this.commandPalette.getRegisteredCommands(this.contextElement);
36
+ this.setCommandList(this.commands);
37
+ // TODO: custom name
38
+ this.breadcrumbs.push({
39
+ action: { label: "/" },
40
+ commands: this.commands,
41
+ destroying: false,
42
+ selectedIndex: 0
43
+ });
30
44
  }
31
45
  onKeyDown(evt) {
32
- if (evt.key == "Enter") {
33
- // Fire the first command
34
- if (this.filteredCommands.length > 0)
35
- this.executeCommand(this.filteredCommands[this.activeIndex]);
36
- evt.stopPropagation();
37
- return;
38
- }
39
- if (evt.key == "ArrowUp") {
40
- // Fire the first command
41
- this.activeIndex = Math.max(this.activeIndex - 1, 0);
42
- evt.stopPropagation();
43
- return;
44
- }
45
- if (evt.key == "ArrowDown") {
46
- this.activeIndex = Math.min(this.filteredCommands.length - 1, this.activeIndex + 1);
47
- evt.stopPropagation();
48
- return;
46
+ switch (evt.key) {
47
+ case "Enter": {
48
+ // Fire the first command
49
+ if (this.filteredCommands.length > 0)
50
+ this.executeCommand(this.filteredCommands[this.activeIndex]);
51
+ evt.stopPropagation();
52
+ return;
53
+ }
54
+ case "ArrowUp": {
55
+ this.activeIndex = Math.max(this.activeIndex - 1, 0);
56
+ evt.stopPropagation();
57
+ this.focusRow();
58
+ return;
59
+ }
60
+ case "ArrowDown": {
61
+ this.activeIndex = Math.min(this.filteredCommands.length - 1, this.activeIndex + 1);
62
+ evt.stopPropagation();
63
+ this.focusRow();
64
+ return;
65
+ }
66
+ case "PageUp": {
67
+ // Fire the first command
68
+ this.activeIndex = Math.max(this.activeIndex - 12, 0);
69
+ evt.stopPropagation();
70
+ this.focusRow();
71
+ return;
72
+ }
73
+ case "PageDown": {
74
+ this.activeIndex = Math.min(this.filteredCommands.length - 1, this.activeIndex + 12);
75
+ evt.stopPropagation();
76
+ this.focusRow();
77
+ return;
78
+ }
79
+ case "Escape": {
80
+ this.dialog.close();
81
+ evt.stopPropagation();
82
+ return;
83
+ }
84
+ case "Backspace": {
85
+ // If we have no characters and we're hitting backspace, go back
86
+ // to the previous menu in the breadcrumb
87
+ if (this.queryString.length == 0 && this.breadcrumbs.length > 1) {
88
+ const layer = this.breadcrumbs.at(-1);
89
+ layer.destroying = true;
90
+ setTimeout(() => {
91
+ this.setCommandList(this.breadcrumbs.at(-2).commands);
92
+ this.breadcrumbs.pop();
93
+ this.activeIndex = layer.selectedIndex;
94
+ }, 190);
95
+ return;
96
+ }
97
+ else {
98
+ break;
99
+ }
100
+ }
101
+ case "Delete": {
102
+ }
49
103
  }
50
104
  this.activeIndex = 0;
51
105
  this.commands.forEach(c => c['_renderedLabel'] = '');
@@ -53,17 +107,23 @@ export class CommandPaletteComponent {
53
107
  // value so that it's updated
54
108
  setTimeout(() => {
55
109
  this.queryString = evt.target.value;
56
- // Whitespace doesn't count.
57
- if (this.queryString.trim().length == 0) {
58
- this.filteredCommands = this.commands;
59
- return;
60
- }
61
- const queryChars = this.queryString
62
- .toLowerCase()
63
- .split('');
64
- const matchedCommands = [];
65
- for (const command of this.commands) {
66
- const { label } = command;
110
+ this.filterResults();
111
+ });
112
+ }
113
+ async filterResults() {
114
+ // Whitespace doesn't count.
115
+ if (this.queryString.trim().length == 0) {
116
+ this.filteredCommands = this.commands;
117
+ return;
118
+ }
119
+ const queryChars = this.queryString
120
+ .toLowerCase()
121
+ .split('');
122
+ const matchedCommands = [];
123
+ for (const command of this.commands) {
124
+ const { label } = command;
125
+ // Check the label
126
+ if (command.label) {
67
127
  const commandChars = label
68
128
  .toLowerCase()
69
129
  .split('');
@@ -87,34 +147,111 @@ export class CommandPaletteComponent {
87
147
  matchedCommands.push(command);
88
148
  }
89
149
  }
90
- this.filteredCommands = matchedCommands;
91
- });
150
+ // Check the hint
151
+ if (command.hint) {
152
+ const commandChars = label
153
+ .toLowerCase()
154
+ .split('');
155
+ let renderedHint = '';
156
+ let lastIndex = 0;
157
+ let isMatch = true;
158
+ for (const char of queryChars) {
159
+ const index = commandChars.indexOf(char, lastIndex);
160
+ if (index == -1) {
161
+ isMatch = false;
162
+ break;
163
+ }
164
+ else {
165
+ renderedHint += label.slice(lastIndex, index) + `<b>${label.slice(index, index + 1)}</b>`;
166
+ lastIndex = index + 1;
167
+ }
168
+ }
169
+ renderedHint += label.slice(lastIndex);
170
+ if (isMatch) {
171
+ command['_renderedHint'] = renderedHint;
172
+ matchedCommands.push(command);
173
+ }
174
+ }
175
+ }
176
+ this.filteredCommands = matchedCommands;
177
+ }
178
+ setCommandList(commands) {
179
+ this.commands = commands
180
+ .filter(c => c.visibleInList != false);
181
+ this.filteredCommands = this.commands;
182
+ this.queryString = '';
183
+ this.activeIndex = 0;
184
+ // Reset the filter labels
185
+ this.commands.forEach(command => command['_renderedLabel'] = '');
186
+ }
187
+ focusRow() {
188
+ const top = this.activeIndex * this.rowHeight;
189
+ const height = this.rowHeight;
190
+ const viewTop = this.scrollbar?.viewport?.scrollTop;
191
+ const viewHeight = this.scrollbar?.viewport?.clientHeight;
192
+ const viewBottom = viewTop + viewHeight;
193
+ if (top < viewTop) {
194
+ this.scrollbar.viewport.nativeElement.scrollTo({ top: top + this.padding });
195
+ }
196
+ else if ((top + height) > viewBottom) {
197
+ this.scrollbar.viewport.nativeElement.scrollTo({ top: ((top + this.rowHeight) - viewHeight) + this.padding });
198
+ }
199
+ // Immediately check for changes to update template
200
+ this.changeDetector.detectChanges();
92
201
  }
93
202
  executeCommand(command) {
94
- this.commandPalette.invokeAction(command);
95
- this.dialog.close();
203
+ // Open a sub menu of items
204
+ if (Array.isArray(command.subMenu)) {
205
+ this.breadcrumbs.push({
206
+ action: command,
207
+ commands: command.subMenu,
208
+ selectedIndex: this.activeIndex,
209
+ destroying: false
210
+ });
211
+ this.setCommandList(command.subMenu);
212
+ }
213
+ // Directly invoke the action and kill the dialog
214
+ else {
215
+ this.commandPalette.invokeAction(command);
216
+ this.dialog.close();
217
+ }
96
218
  }
97
219
  onBlur() {
98
- // this.dialog.close();
220
+ if (!isDevMode()) {
221
+ this.dialog.close();
222
+ }
99
223
  }
100
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.1", ngImport: i0, type: CommandPaletteComponent, deps: [{ token: i1.CommandPaletteService }, { token: i2.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
101
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.1", type: CommandPaletteComponent, isStandalone: true, selector: "app-command-palette", inputs: { contextElement: "contextElement" }, host: { listeners: { "window:blur": "onBlur()" } }, ngImport: i0, template: "<mat-form-field style=\"width: 100%; padding: 8px 8px 0 8px\">\n <input\n matInput\n type=\"text\"\n [value]=\"queryString\"\n (keydown)=\"onKeyDown($event)\"\n >\n</mat-form-field>\n\n@if (filteredCommands.length == 0) {\n <div class=\"commands\">\n <div class=\"command selected\">\n <div class=\"label\">No matching results.</div>\n </div>\n </div>\n}\n@else {\n <div\n class=\"commands\"\n [style.flex]=\"(filteredCommands.length * 28) + 'px'\"\n >\n <ng-scrollbar>\n <cdk-virtual-scroll-viewport itemSize=\"28\" scrollViewport>\n <div\n *cdkVirtualFor=\"let command of filteredCommands; let index = index\"\n class=\"command\"\n [class.selected]=\"index==activeIndex\"\n (click)=\"executeCommand(command)\"\n >\n <div\n class=\"label\"\n [innerHTML]=\"command['_renderedLabel'] || command.label || command.description\"\n ></div>\n <div>\n @for (shortcut of (command.shortcutKey?.find ? command.shortcutKey : [command.shortcutKey]); track shortcut) {\n @if (shortcut) {\n <app-shortcut [shortcut]=\"shortcut\"></app-shortcut>\n }\n }\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-scrollbar>\n </div>\n}\n\n", styles: [":host{display:flex;flex-direction:column;width:860px;max-height:460px;border:1px solid #484848;border-radius:5px;background-color:#222;-webkit-user-select:none;user-select:none}.commands{max-height:100%;overflow:hidden}.commands .command{display:flex;height:28px;padding-left:16px;padding-right:32px;align-items:center;border-radius:3px;justify-content:space-between}.commands .command:hover{background-color:#2a2d2e}.commands .command.selected{background-color:#04395e}.commands .command .label ::ng-deep b{color:#2196f3}ng-scrollbar.ng-scrollbar{--scrollbar-padding: 0px;--scrollbar-size: 14px;--scrollbar-border-radius: 0;--scrollbar-thumb-color: #0000;--scrollbar-thumb-transition: height ease-out .15s, width ease-out .15s, background-color ease 1.2s}ng-scrollbar.ng-scrollbar:hover{--scrollbar-thumb-color: #444}cdk-virtual-scroll-viewport{height:100%}:host ::ng-deep .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding:4px 0}:host ::ng-deep .mat-mdc-form-field-infix{min-height:32px}:host ::ng-deep .mat-mdc-text-field-wrapper{margin-bottom:8px}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .dark :host{border:1px solid #e5e5e5;background-color:#f8f8f8}::ng-deep .dark :host .commands .command:hover{background-color:#f2f2f2}::ng-deep .dark :host .commands .command.selected{background-color:#e8e8e8}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i5.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i5.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i5.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: NgScrollbarModule }, { kind: "component", type: i6.NgScrollbar, selector: "ng-scrollbar", inputs: ["disabled", "sensorDisabled", "pointerEventsDisabled", "viewportPropagateMouseMove", "autoHeightDisabled", "autoWidthDisabled", "viewClass", "trackClass", "thumbClass", "minThumbSize", "trackClickScrollDuration", "pointerEventsMethod", "track", "visibility", "appearance", "position", "sensorDebounce", "scrollAuditTime"], outputs: ["updated"], exportAs: ["ngScrollbar"] }, { kind: "directive", type: i6.ScrollViewport, selector: "[scrollViewport]" }, { kind: "component", type: ShortcutComponent, selector: "app-shortcut", inputs: ["shortcut"] }] }); }
224
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CommandPaletteComponent, deps: [{ token: i1.CommandPaletteService }, { token: i2.MatDialogRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component }); }
225
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.2", type: CommandPaletteComponent, isStandalone: true, selector: "ngx-command-palette", inputs: { contextElement: "contextElement" }, host: { listeners: { "click": "textInput.nativeElement.focus()", "window:blur": "onBlur()", "window:resize": "onBlur()" } }, viewQueries: [{ propertyName: "scrollbar", first: true, predicate: NgScrollbar, descendants: true }, { propertyName: "textInput", first: true, predicate: ["textinput"], descendants: true }], ngImport: i0, template: "<mat-form-field style=\"width: 100%; padding: 8px 8px 0 8px\">\n <ngx-commandpalette-breadcrumb\n [breadcrumbs]=\"breadcrumbs\"\n />\n <input\n #textinput\n matInput\n type=\"text\"\n [value]=\"queryString\"\n (keydown)=\"onKeyDown($event)\"\n >\n</mat-form-field>\n\n@if (filteredCommands.length == 0) {\n <div class=\"commands\">\n <div class=\"command selected\">\n <div class=\"label\">No matching results.</div>\n </div>\n </div>\n}\n@else {\n <div\n class=\"commands\"\n [style.flex]=\"(filteredCommands.length * rowHeight) + 'px'\"\n [class.shadow]=\"scrollbar?.viewport?.scrollTop > 2\"\n >\n <ng-scrollbar #scrollbar>\n <cdk-virtual-scroll-viewport [itemSize]=\"rowHeight\" scrollViewport [minBufferPx]=\"150\">\n <div\n *cdkVirtualFor=\"let command of filteredCommands; let index = index\"\n class=\"command\"\n [style.height]=\"rowHeight + 'px'\"\n [class.selected]=\"index==activeIndex\"\n [class.has-icon]=\"command.icon\"\n [attr.index]=\"index\"\n (click)=\"executeCommand(command)\"\n >\n @if (command.icon) {\n <div class=\"icon\">\n @if (!MAT_ICON_REGEX.test(command.icon)) {\n <mat-icon [fontIcon]=\"command.icon\"></mat-icon>\n }\n @else {\n <img [src]=\"command.icon\"/>\n }\n </div>\n }\n\n <div\n class=\"label\"\n [innerHTML]=\"command['_renderedLabel'] || command.label || command.description\"\n ></div>\n\n @if (command['_renderedHint'] || command.hint) {\n <div\n class=\"hint\"\n [innerHTML]=\"command['_renderedHint'] || command.hint\"\n ></div>\n }\n <div style=\"flex: 1\"></div>\n\n <div>\n @for (shortcut of (command.shortcutKey?.find ? command.shortcutKey : [command.shortcutKey]); track shortcut) {\n @if (shortcut) {\n <ngx-commandpalette-shortcut [shortcut]=\"shortcut\"/>\n }\n }\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-scrollbar>\n </div>\n}\n\n", styles: [":host{display:flex;flex-direction:column;width:860px;max-height:460px;border:1px solid #484848;border-radius:6px;background-color:#222;-webkit-user-select:none;user-select:none;overflow:hidden;--text-color: #ccc;--transition: .25s ease}.commands{max-height:100%;overflow:hidden;position:relative;padding:0 6px}.commands .command{display:flex;padding-left:16px;padding-right:32px;align-items:center;border-radius:3px;justify-content:space-between;color:var(--text-color);font-size:15.5px;background-color:#0000}.commands .command:hover{background-color:#2a2d2e}.commands .command.selected{background-color:#04395e}.commands .command.has-icon{padding-left:8px}.commands .command .label ::ng-deep b{color:#2196f3}.commands .command .icon{width:38px;height:100%;display:flex;align-items:center;justify-content:center}.commands .command img{max-height:100%;padding:4px}.commands .command .hint{margin-left:12px;opacity:.75}.commands.shadow:after{box-shadow:#000 0 6px 6px -6px inset}.commands:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:6px;box-shadow:#0000 0 6px 6px -6px inset;transition:box-shadow .3s ease}ng-scrollbar.ng-scrollbar{--scrollbar-padding: 0px;--scrollbar-size: 14px;--scrollbar-border-radius: 0;--scrollbar-thumb-color: #4440;--scrollbar-thumb-transition: height ease-out .15s, width ease-out .15s, background-color ease 1.2s;animation:fadeScrollbar 1.2s ease}ng-scrollbar.ng-scrollbar:hover{--scrollbar-thumb-color: #444f}@keyframes fadeScrollbar{0%{--scrollbar-thumb-color: #444f}to{--scrollbar-thumb-color: #4440}}cdk-virtual-scroll-viewport{height:100%;padding-bottom:6px}:host ::ng-deep .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding:2px 0 4px}:host ::ng-deep .mat-mdc-form-field-infix{min-height:32px;display:flex}:host ::ng-deep .mat-mdc-text-field-wrapper{margin-bottom:8px;padding:0 12px}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .light app-command-palette{border:1px solid #e5e5e5;background-color:#f8f8f8;--text-color: #262626}::ng-deep .light app-command-palette .commands .command:hover{background-color:#f2f2f2}::ng-deep .light app-command-palette .commands .command.selected{background-color:#e8e8e8}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i6.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i6.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i6.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: NgScrollbarModule }, { kind: "component", type: i7.NgScrollbar, selector: "ng-scrollbar", inputs: ["disabled", "sensorDisabled", "pointerEventsDisabled", "viewportPropagateMouseMove", "autoHeightDisabled", "autoWidthDisabled", "viewClass", "trackClass", "thumbClass", "minThumbSize", "trackClickScrollDuration", "pointerEventsMethod", "track", "visibility", "appearance", "position", "sensorDebounce", "scrollAuditTime"], outputs: ["updated"], exportAs: ["ngScrollbar"] }, { kind: "directive", type: i7.ScrollViewport, selector: "[scrollViewport]" }, { kind: "component", type: ShortcutComponent, selector: "ngx-commandpalette-shortcut", inputs: ["shortcut"] }, { kind: "component", type: BreadcrumbComponent, selector: "ngx-commandpalette-breadcrumb", inputs: ["breadcrumbs"] }] }); }
102
226
  }
103
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.1", ngImport: i0, type: CommandPaletteComponent, decorators: [{
227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CommandPaletteComponent, decorators: [{
104
228
  type: Component,
105
- args: [{ selector: 'app-command-palette', imports: [
229
+ args: [{ selector: 'ngx-command-palette', host: {
230
+ "(click)": "textInput.nativeElement.focus()"
231
+ }, imports: [
232
+ MatIconModule,
106
233
  MatInputModule,
107
234
  ScrollingModule,
108
235
  NgScrollbarModule,
109
- ShortcutComponent
110
- ], standalone: true, template: "<mat-form-field style=\"width: 100%; padding: 8px 8px 0 8px\">\n <input\n matInput\n type=\"text\"\n [value]=\"queryString\"\n (keydown)=\"onKeyDown($event)\"\n >\n</mat-form-field>\n\n@if (filteredCommands.length == 0) {\n <div class=\"commands\">\n <div class=\"command selected\">\n <div class=\"label\">No matching results.</div>\n </div>\n </div>\n}\n@else {\n <div\n class=\"commands\"\n [style.flex]=\"(filteredCommands.length * 28) + 'px'\"\n >\n <ng-scrollbar>\n <cdk-virtual-scroll-viewport itemSize=\"28\" scrollViewport>\n <div\n *cdkVirtualFor=\"let command of filteredCommands; let index = index\"\n class=\"command\"\n [class.selected]=\"index==activeIndex\"\n (click)=\"executeCommand(command)\"\n >\n <div\n class=\"label\"\n [innerHTML]=\"command['_renderedLabel'] || command.label || command.description\"\n ></div>\n <div>\n @for (shortcut of (command.shortcutKey?.find ? command.shortcutKey : [command.shortcutKey]); track shortcut) {\n @if (shortcut) {\n <app-shortcut [shortcut]=\"shortcut\"></app-shortcut>\n }\n }\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-scrollbar>\n </div>\n}\n\n", styles: [":host{display:flex;flex-direction:column;width:860px;max-height:460px;border:1px solid #484848;border-radius:5px;background-color:#222;-webkit-user-select:none;user-select:none}.commands{max-height:100%;overflow:hidden}.commands .command{display:flex;height:28px;padding-left:16px;padding-right:32px;align-items:center;border-radius:3px;justify-content:space-between}.commands .command:hover{background-color:#2a2d2e}.commands .command.selected{background-color:#04395e}.commands .command .label ::ng-deep b{color:#2196f3}ng-scrollbar.ng-scrollbar{--scrollbar-padding: 0px;--scrollbar-size: 14px;--scrollbar-border-radius: 0;--scrollbar-thumb-color: #0000;--scrollbar-thumb-transition: height ease-out .15s, width ease-out .15s, background-color ease 1.2s}ng-scrollbar.ng-scrollbar:hover{--scrollbar-thumb-color: #444}cdk-virtual-scroll-viewport{height:100%}:host ::ng-deep .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding:4px 0}:host ::ng-deep .mat-mdc-form-field-infix{min-height:32px}:host ::ng-deep .mat-mdc-text-field-wrapper{margin-bottom:8px}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .dark :host{border:1px solid #e5e5e5;background-color:#f8f8f8}::ng-deep .dark :host .commands .command:hover{background-color:#f2f2f2}::ng-deep .dark :host .commands .command.selected{background-color:#e8e8e8}\n"] }]
111
- }], ctorParameters: () => [{ type: i1.CommandPaletteService }, { type: i2.MatDialogRef }, { type: undefined, decorators: [{
236
+ ShortcutComponent,
237
+ BreadcrumbComponent
238
+ ], standalone: true, template: "<mat-form-field style=\"width: 100%; padding: 8px 8px 0 8px\">\n <ngx-commandpalette-breadcrumb\n [breadcrumbs]=\"breadcrumbs\"\n />\n <input\n #textinput\n matInput\n type=\"text\"\n [value]=\"queryString\"\n (keydown)=\"onKeyDown($event)\"\n >\n</mat-form-field>\n\n@if (filteredCommands.length == 0) {\n <div class=\"commands\">\n <div class=\"command selected\">\n <div class=\"label\">No matching results.</div>\n </div>\n </div>\n}\n@else {\n <div\n class=\"commands\"\n [style.flex]=\"(filteredCommands.length * rowHeight) + 'px'\"\n [class.shadow]=\"scrollbar?.viewport?.scrollTop > 2\"\n >\n <ng-scrollbar #scrollbar>\n <cdk-virtual-scroll-viewport [itemSize]=\"rowHeight\" scrollViewport [minBufferPx]=\"150\">\n <div\n *cdkVirtualFor=\"let command of filteredCommands; let index = index\"\n class=\"command\"\n [style.height]=\"rowHeight + 'px'\"\n [class.selected]=\"index==activeIndex\"\n [class.has-icon]=\"command.icon\"\n [attr.index]=\"index\"\n (click)=\"executeCommand(command)\"\n >\n @if (command.icon) {\n <div class=\"icon\">\n @if (!MAT_ICON_REGEX.test(command.icon)) {\n <mat-icon [fontIcon]=\"command.icon\"></mat-icon>\n }\n @else {\n <img [src]=\"command.icon\"/>\n }\n </div>\n }\n\n <div\n class=\"label\"\n [innerHTML]=\"command['_renderedLabel'] || command.label || command.description\"\n ></div>\n\n @if (command['_renderedHint'] || command.hint) {\n <div\n class=\"hint\"\n [innerHTML]=\"command['_renderedHint'] || command.hint\"\n ></div>\n }\n <div style=\"flex: 1\"></div>\n\n <div>\n @for (shortcut of (command.shortcutKey?.find ? command.shortcutKey : [command.shortcutKey]); track shortcut) {\n @if (shortcut) {\n <ngx-commandpalette-shortcut [shortcut]=\"shortcut\"/>\n }\n }\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n </ng-scrollbar>\n </div>\n}\n\n", styles: [":host{display:flex;flex-direction:column;width:860px;max-height:460px;border:1px solid #484848;border-radius:6px;background-color:#222;-webkit-user-select:none;user-select:none;overflow:hidden;--text-color: #ccc;--transition: .25s ease}.commands{max-height:100%;overflow:hidden;position:relative;padding:0 6px}.commands .command{display:flex;padding-left:16px;padding-right:32px;align-items:center;border-radius:3px;justify-content:space-between;color:var(--text-color);font-size:15.5px;background-color:#0000}.commands .command:hover{background-color:#2a2d2e}.commands .command.selected{background-color:#04395e}.commands .command.has-icon{padding-left:8px}.commands .command .label ::ng-deep b{color:#2196f3}.commands .command .icon{width:38px;height:100%;display:flex;align-items:center;justify-content:center}.commands .command img{max-height:100%;padding:4px}.commands .command .hint{margin-left:12px;opacity:.75}.commands.shadow:after{box-shadow:#000 0 6px 6px -6px inset}.commands:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:6px;box-shadow:#0000 0 6px 6px -6px inset;transition:box-shadow .3s ease}ng-scrollbar.ng-scrollbar{--scrollbar-padding: 0px;--scrollbar-size: 14px;--scrollbar-border-radius: 0;--scrollbar-thumb-color: #4440;--scrollbar-thumb-transition: height ease-out .15s, width ease-out .15s, background-color ease 1.2s;animation:fadeScrollbar 1.2s ease}ng-scrollbar.ng-scrollbar:hover{--scrollbar-thumb-color: #444f}@keyframes fadeScrollbar{0%{--scrollbar-thumb-color: #444f}to{--scrollbar-thumb-color: #4440}}cdk-virtual-scroll-viewport{height:100%;padding-bottom:6px}:host ::ng-deep .mdc-text-field--no-label:not(.mdc-text-field--outlined):not(.mdc-text-field--textarea) .mat-mdc-form-field-infix{padding:2px 0 4px}:host ::ng-deep .mat-mdc-form-field-infix{min-height:32px;display:flex}:host ::ng-deep .mat-mdc-text-field-wrapper{margin-bottom:8px;padding:0 12px}:host ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .light app-command-palette{border:1px solid #e5e5e5;background-color:#f8f8f8;--text-color: #262626}::ng-deep .light app-command-palette .commands .command:hover{background-color:#f2f2f2}::ng-deep .light app-command-palette .commands .command.selected{background-color:#e8e8e8}\n"] }]
239
+ }], ctorParameters: () => [{ type: i1.CommandPaletteService }, { type: i2.MatDialogRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
112
240
  type: Inject,
113
241
  args: [MAT_DIALOG_DATA]
114
- }] }], propDecorators: { contextElement: [{
242
+ }] }], propDecorators: { scrollbar: [{
243
+ type: ViewChild,
244
+ args: [NgScrollbar]
245
+ }], textInput: [{
246
+ type: ViewChild,
247
+ args: ['textinput']
248
+ }], contextElement: [{
115
249
  type: Input
116
250
  }], onBlur: [{
117
251
  type: HostListener,
118
252
  args: ["window:blur"]
253
+ }, {
254
+ type: HostListener,
255
+ args: ["window:resize"]
119
256
  }] } });
120
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9jb21tYW5kLXBhbGV0dGUvY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9jb21tYW5kLXBhbGV0dGUvY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFFL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxlQUFlLEVBQWdCLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQzs7Ozs7Ozs7QUFjbEUsTUFBTSxPQUFPLHVCQUF1QjtJQVVoQyxZQUNxQixjQUFxQyxFQUNyQyxNQUF5QixFQUNqQixJQUFTO1FBRmpCLG1CQUFjLEdBQWQsY0FBYyxDQUF1QjtRQUNyQyxXQUFNLEdBQU4sTUFBTSxDQUFtQjtRQVI5QyxnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUNqQixnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUVoQixhQUFRLEdBQW9CLEVBQUUsQ0FBQztRQUMvQixxQkFBZ0IsR0FBb0IsRUFBRSxDQUFDO1FBT25DLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDO0lBQ3JFLENBQUM7SUFFRCxRQUFRO1FBQ0osSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUM7YUFDekUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGFBQWEsSUFBSSxLQUFLLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUV0QywwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQWtCO1FBQ3hCLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNyQix5QkFBeUI7WUFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBRWpFLEdBQUcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1gsQ0FBQztRQUVELElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUN2Qix5QkFBeUI7WUFDekIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBRW5ELEdBQUcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1gsQ0FBQztRQUVELElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sR0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLFdBQVcsR0FBQyxDQUFDLENBQUMsQ0FBQztZQUVoRixHQUFHLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDdEIsT0FBTztRQUNYLENBQUM7UUFFRCxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRXJELDRDQUE0QztRQUM1Qyw2QkFBNkI7UUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNaLElBQUksQ0FBQyxXQUFXLEdBQUksR0FBRyxDQUFDLE1BQTJCLENBQUMsS0FBSyxDQUFDO1lBRTFELDRCQUE0QjtZQUM1QixJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDdEMsT0FBTztZQUNYLENBQUM7WUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVztpQkFDOUIsV0FBVyxFQUFFO2lCQUNiLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUVmLE1BQU0sZUFBZSxHQUFvQixFQUFFLENBQUM7WUFFNUMsS0FBSyxNQUFNLE9BQU8sSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxPQUFPLENBQUM7Z0JBRTFCLE1BQU0sWUFBWSxHQUFHLEtBQUs7cUJBQ3JCLFdBQVcsRUFBRTtxQkFDYixLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBRWYsSUFBSSxhQUFhLEdBQUcsRUFBRSxDQUFDO2dCQUN2QixJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUM7Z0JBQ2xCLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQztnQkFFbkIsS0FBSyxNQUFNLElBQUksSUFBSSxVQUFVLEVBQUUsQ0FBQztvQkFDNUIsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBRXBELElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ2QsT0FBTyxHQUFHLEtBQUssQ0FBQzt3QkFDaEIsTUFBTTtvQkFDVixDQUFDO3lCQUNJLENBQUM7d0JBQ0YsYUFBYSxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxHQUFDLENBQUMsQ0FBRSxNQUFNLENBQUM7d0JBQzFGLFNBQVMsR0FBRyxLQUFLLEdBQUMsQ0FBQyxDQUFDO29CQUN4QixDQUFDO2dCQUNMLENBQUM7Z0JBRUQsYUFBYSxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBRXhDLElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1YsT0FBTyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsYUFBYSxDQUFDO29CQUMxQyxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNsQyxDQUFDO1lBQ0wsQ0FBQztZQUVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxlQUFlLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDO0lBRUQsY0FBYyxDQUFDLE9BQXNCO1FBQ2pDLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUdELE1BQU07UUFDRix1QkFBdUI7SUFDM0IsQ0FBQzs4R0FwSFEsdUJBQXVCLG1GQWFwQixlQUFlO2tHQWJsQix1QkFBdUIsaUxDcEJwQyx1bERBOENBLDI3Q0RqQ1EsY0FBYyxxakJBQ2QsZUFBZSwyakJBQ2YsaUJBQWlCLGlqQkFDakIsaUJBQWlCOzsyRkFJWix1QkFBdUI7a0JBWm5DLFNBQVM7K0JBQ0kscUJBQXFCLFdBR3RCO3dCQUNMLGNBQWM7d0JBQ2QsZUFBZTt3QkFDZixpQkFBaUI7d0JBQ2pCLGlCQUFpQjtxQkFDcEIsY0FDVyxJQUFJOzswQkFlWCxNQUFNOzJCQUFDLGVBQWU7eUNBWGxCLGNBQWM7c0JBQXRCLEtBQUs7Z0JBZ0hOLE1BQU07c0JBREwsWUFBWTt1QkFBQyxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0TGlzdGVuZXIsIEluamVjdCwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbWFuZEFjdGlvbiwgQ29tbWFuZFBhbGV0dGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29tbWFuZC1wYWxldHRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBTY3JvbGxpbmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7IE5nU2Nyb2xsYmFyTW9kdWxlIH0gZnJvbSAnbmd4LXNjcm9sbGJhcic7XG5pbXBvcnQgeyBTaG9ydGN1dENvbXBvbmVudCB9IGZyb20gJy4vc2hvcnRjdXQvc2hvcnRjdXQuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhcHAtY29tbWFuZC1wYWxldHRlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jb21tYW5kLXBhbGV0dGUuY29tcG9uZW50LnNjc3MnXSxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIE1hdElucHV0TW9kdWxlLFxuICAgICAgICBTY3JvbGxpbmdNb2R1bGUsXG4gICAgICAgIE5nU2Nyb2xsYmFyTW9kdWxlLFxuICAgICAgICBTaG9ydGN1dENvbXBvbmVudFxuICAgIF0sXG4gICAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBDb21tYW5kUGFsZXR0ZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBASW5wdXQoKSBjb250ZXh0RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICBxdWVyeVN0cmluZyA9IFwiXCI7XG4gICAgYWN0aXZlSW5kZXggPSAwO1xuXG4gICAgY29tbWFuZHM6IENvbW1hbmRBY3Rpb25bXSA9IFtdO1xuICAgIGZpbHRlcmVkQ29tbWFuZHM6IENvbW1hbmRBY3Rpb25bXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZFBhbGV0dGU6IENvbW1hbmRQYWxldHRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkaWFsb2c6IE1hdERpYWxvZ1JlZjxhbnk+LFxuICAgICAgICBASW5qZWN0KE1BVF9ESUFMT0dfREFUQSkgZGF0YTogYW55XG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29udGV4dEVsZW1lbnQgPSB0aGlzLmNvbnRleHRFbGVtZW50ID8/IGRhdGEuY29udGV4dEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuY29tbWFuZHMgPSB0aGlzLmNvbW1hbmRQYWxldHRlLmdldFJlZ2lzdGVyZWRDb21tYW5kcyh0aGlzLmNvbnRleHRFbGVtZW50KVxuICAgICAgICAgICAgLmZpbHRlcihjID0+IGMudmlzaWJsZUluTGlzdCAhPSBmYWxzZSk7XG4gICAgICAgIHRoaXMuZmlsdGVyZWRDb21tYW5kcyA9IHRoaXMuY29tbWFuZHM7XG5cbiAgICAgICAgLy8gUmVzZXQgdGhlIGZpbHRlciBsYWJlbHNcbiAgICAgICAgdGhpcy5jb21tYW5kcy5mb3JFYWNoKGNvbW1hbmQgPT4gY29tbWFuZFsnX3JlbmRlcmVkTGFiZWwnXSA9ICcnKTtcbiAgICB9XG5cbiAgICBvbktleURvd24oZXZ0OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgICAgIGlmIChldnQua2V5ID09IFwiRW50ZXJcIikge1xuICAgICAgICAgICAgLy8gRmlyZSB0aGUgZmlyc3QgY29tbWFuZFxuICAgICAgICAgICAgaWYgKHRoaXMuZmlsdGVyZWRDb21tYW5kcy5sZW5ndGggPiAwKVxuICAgICAgICAgICAgICAgIHRoaXMuZXhlY3V0ZUNvbW1hbmQodGhpcy5maWx0ZXJlZENvbW1hbmRzW3RoaXMuYWN0aXZlSW5kZXhdKTtcblxuICAgICAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2dC5rZXkgPT0gXCJBcnJvd1VwXCIpIHtcbiAgICAgICAgICAgIC8vIEZpcmUgdGhlIGZpcnN0IGNvbW1hbmRcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlSW5kZXggPSBNYXRoLm1heCh0aGlzLmFjdGl2ZUluZGV4LTEsIDApO1xuXG4gICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZ0LmtleSA9PSBcIkFycm93RG93blwiKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZUluZGV4ID0gTWF0aC5taW4odGhpcy5maWx0ZXJlZENvbW1hbmRzLmxlbmd0aC0xLCB0aGlzLmFjdGl2ZUluZGV4KzEpO1xuXG4gICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFjdGl2ZUluZGV4ID0gMDtcbiAgICAgICAgdGhpcy5jb21tYW5kcy5mb3JFYWNoKGMgPT4gY1snX3JlbmRlcmVkTGFiZWwnXSA9ICcnKTtcblxuICAgICAgICAvLyBDaGVjayBpbiB0aGUgbmV4dCB0aWNrIHRvIGdldCB0aGUgaW5wdXQnc1xuICAgICAgICAvLyB2YWx1ZSBzbyB0aGF0IGl0J3MgdXBkYXRlZFxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucXVlcnlTdHJpbmcgPSAoZXZ0LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcblxuICAgICAgICAgICAgLy8gV2hpdGVzcGFjZSBkb2Vzbid0IGNvdW50LlxuICAgICAgICAgICAgaWYgKHRoaXMucXVlcnlTdHJpbmcudHJpbSgpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJlZENvbW1hbmRzID0gdGhpcy5jb21tYW5kcztcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHF1ZXJ5Q2hhcnMgPSB0aGlzLnF1ZXJ5U3RyaW5nXG4gICAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICAuc3BsaXQoJycpO1xuXG4gICAgICAgICAgICBjb25zdCBtYXRjaGVkQ29tbWFuZHM6IENvbW1hbmRBY3Rpb25bXSA9IFtdO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbW1hbmQgb2YgdGhpcy5jb21tYW5kcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgbGFiZWwgfSA9IGNvbW1hbmQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjb21tYW5kQ2hhcnMgPSBsYWJlbFxuICAgICAgICAgICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICAgICAgICAuc3BsaXQoJycpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHJlbmRlcmVkTGFiZWwgPSAnJztcbiAgICAgICAgICAgICAgICBsZXQgbGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICBsZXQgaXNNYXRjaCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoYXIgb2YgcXVlcnlDaGFycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGNvbW1hbmRDaGFycy5pbmRleE9mKGNoYXIsIGxhc3RJbmRleCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc01hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVkTGFiZWwgKz0gbGFiZWwuc2xpY2UobGFzdEluZGV4LCBpbmRleCkgKyBgPGI+JHtsYWJlbC5zbGljZShpbmRleCwgaW5kZXgrMSkgfTwvYj5gO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEluZGV4ID0gaW5kZXgrMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlbmRlcmVkTGFiZWwgKz0gbGFiZWwuc2xpY2UobGFzdEluZGV4KTtcblxuICAgICAgICAgICAgICAgIGlmIChpc01hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRbJ19yZW5kZXJlZExhYmVsJ10gPSByZW5kZXJlZExhYmVsO1xuICAgICAgICAgICAgICAgICAgICBtYXRjaGVkQ29tbWFuZHMucHVzaChjb21tYW5kKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuZmlsdGVyZWRDb21tYW5kcyA9IG1hdGNoZWRDb21tYW5kcztcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBleGVjdXRlQ29tbWFuZChjb21tYW5kOiBDb21tYW5kQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuY29tbWFuZFBhbGV0dGUuaW52b2tlQWN0aW9uKGNvbW1hbmQpO1xuICAgICAgICB0aGlzLmRpYWxvZy5jbG9zZSgpO1xuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6Ymx1clwiKVxuICAgIG9uQmx1cigpIHtcbiAgICAgICAgLy8gdGhpcy5kaWFsb2cuY2xvc2UoKTtcbiAgICB9XG59XG4iLCI8bWF0LWZvcm0tZmllbGQgc3R5bGU9XCJ3aWR0aDogMTAwJTsgcGFkZGluZzogOHB4IDhweCAwIDhweFwiPlxuICAgIDxpbnB1dFxuICAgICAgICBtYXRJbnB1dFxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIFt2YWx1ZV09XCJxdWVyeVN0cmluZ1wiXG4gICAgICAgIChrZXlkb3duKT1cIm9uS2V5RG93bigkZXZlbnQpXCJcbiAgICA+XG48L21hdC1mb3JtLWZpZWxkPlxuXG5AaWYgKGZpbHRlcmVkQ29tbWFuZHMubGVuZ3RoID09IDApIHtcbiAgICA8ZGl2IGNsYXNzPVwiY29tbWFuZHNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbW1hbmQgc2VsZWN0ZWRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbFwiPk5vIG1hdGNoaW5nIHJlc3VsdHMuPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxufVxuQGVsc2Uge1xuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJjb21tYW5kc1wiXG4gICAgICAgIFtzdHlsZS5mbGV4XT1cIihmaWx0ZXJlZENvbW1hbmRzLmxlbmd0aCAqIDI4KSArICdweCdcIlxuICAgID5cbiAgICAgICAgPG5nLXNjcm9sbGJhcj5cbiAgICAgICAgICAgIDxjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQgaXRlbVNpemU9XCIyOFwiIHNjcm9sbFZpZXdwb3J0PlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgKmNka1ZpcnR1YWxGb3I9XCJsZXQgY29tbWFuZCBvZiBmaWx0ZXJlZENvbW1hbmRzOyBsZXQgaW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tbWFuZFwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJpbmRleD09YWN0aXZlSW5kZXhcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhlY3V0ZUNvbW1hbmQoY29tbWFuZClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsYWJlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cImNvbW1hbmRbJ19yZW5kZXJlZExhYmVsJ10gfHwgY29tbWFuZC5sYWJlbCB8fCBjb21tYW5kLmRlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAoc2hvcnRjdXQgb2YgKGNvbW1hbmQuc2hvcnRjdXRLZXk/LmZpbmQgPyBjb21tYW5kLnNob3J0Y3V0S2V5IDogW2NvbW1hbmQuc2hvcnRjdXRLZXldKTsgdHJhY2sgc2hvcnRjdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHNob3J0Y3V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhcHAtc2hvcnRjdXQgW3Nob3J0Y3V0XT1cInNob3J0Y3V0XCI+PC9hcHAtc2hvcnRjdXQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0PlxuICAgICAgICA8L25nLXNjcm9sbGJhcj5cbiAgICA8L2Rpdj5cbn1cblxuIl19
257
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9jb21tYW5kLXBhbGV0dGUvY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi9zcmMvY29tcG9uZW50cy9jb21tYW5kLXBhbGV0dGUvY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBcUIsU0FBUyxFQUFjLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFVLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFcEksT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxlQUFlLEVBQWdCLE1BQU0sMEJBQTBCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxXQUFXLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0QsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDOzs7Ozs7Ozs7QUFtQnhFLE1BQU0sT0FBTyx1QkFBdUI7SUFPaEMsSUFBSSxFQUFFLEtBQUssT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQTRCLENBQUMsQ0FBQyxDQUFDO0lBbUJqRSxZQUNxQixjQUFxQyxFQUNyQyxNQUF5QixFQUN6QixVQUFzQixFQUN0QixjQUFpQyxFQUN6QixJQUFTO1FBSmpCLG1CQUFjLEdBQWQsY0FBYyxDQUF1QjtRQUNyQyxXQUFN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QUM7WUFFSCxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsaURBQWlEO2FBQzVDLENBQUM7WUFDRixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLENBQUM7SUFDTCxDQUFDO0lBSUQsTUFBTTtRQUNGLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QixDQUFDO0lBQ0wsQ0FBQzs4R0F2UVEsdUJBQXVCLDhJQStCcEIsZUFBZTtrR0EvQmxCLHVCQUF1QixxU0FFckIsV0FBVyx5SUM3QjFCLDh1RkEwRUEsaXhFRHhEUSxhQUFhLG1MQUNiLGNBQWMscWpCQUNkLGVBQWUsMmpCQUNmLGlCQUFpQixpakJBQ2pCLGlCQUFpQiw4RkFDakIsbUJBQW1COzsyRkFJZCx1QkFBdUI7a0JBakJuQyxTQUFTOytCQUNJLHFCQUFxQixRQUd6Qjt3QkFDRixTQUFTLEVBQUUsaUNBQWlDO3FCQUMvQyxXQUNRO3dCQUNMLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxlQUFlO3dCQUNmLGlCQUFpQjt3QkFDakIsaUJBQWlCO3dCQUNqQixtQkFBbUI7cUJBQ3RCLGNBQ1csSUFBSTs7MEJBaUNYLE1BQU07MkJBQUMsZUFBZTt5Q0E3QkgsU0FBUztzQkFBaEMsU0FBUzt1QkFBQyxXQUFXO2dCQUNFLFNBQVM7c0JBQWhDLFNBQVM7dUJBQUMsV0FBVztnQkFFYixjQUFjO3NCQUF0QixLQUFLO2dCQThQTixNQUFNO3NCQUZMLFlBQVk7dUJBQUMsYUFBYTs7c0JBQzFCLFlBQVk7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgSW5qZWN0LCBJbnB1dCwgT25Jbml0LCBWaWV3Q2hpbGQsIGlzRGV2TW9kZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbWFuZEFjdGlvbiwgQ29tbWFuZFBhbGV0dGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29tbWFuZC1wYWxldHRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBTY3JvbGxpbmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7IE5nU2Nyb2xsYmFyLCBOZ1Njcm9sbGJhck1vZHVsZSB9IGZyb20gJ25neC1zY3JvbGxiYXInO1xuaW1wb3J0IHsgU2hvcnRjdXRDb21wb25lbnQgfSBmcm9tICcuL3Nob3J0Y3V0L3Nob3J0Y3V0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBCcmVhZGNydW1iQ29tcG9uZW50IH0gZnJvbSAnLi9icmVhZGNydW1iL2JyZWFkY3J1bWIuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduZ3gtY29tbWFuZC1wYWxldHRlJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY29tbWFuZC1wYWxldHRlLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jb21tYW5kLXBhbGV0dGUuY29tcG9uZW50LnNjc3MnXSxcbiAgICBob3N0OiB7XG4gICAgICAgIFwiKGNsaWNrKVwiOiBcInRleHRJbnB1dC5uYXRpdmVFbGVtZW50LmZvY3VzKClcIlxuICAgIH0sXG4gICAgaW1wb3J0czogW1xuICAgICAgICBNYXRJY29uTW9kdWxlLFxuICAgICAgICBNYXRJbnB1dE1vZHVsZSxcbiAgICAgICAgU2Nyb2xsaW5nTW9kdWxlLFxuICAgICAgICBOZ1Njcm9sbGJhck1vZHVsZSxcbiAgICAgICAgU2hvcnRjdXRDb21wb25lbnQsXG4gICAgICAgIEJyZWFkY3J1bWJDb21wb25lbnRcbiAgICBdLFxuICAgIHN0YW5kYWxvbmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgQ29tbWFuZFBhbGV0dGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgQFZpZXdDaGlsZChOZ1Njcm9sbGJhcikgc2Nyb2xsYmFyOiBOZ1Njcm9sbGJhcjtcbiAgICBAVmlld0NoaWxkKCd0ZXh0aW5wdXQnKSB0ZXh0SW5wdXQ6IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XG5cbiAgICBASW5wdXQoKSBjb250ZXh0RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgICBnZXQgZWwoKSB7IHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDsgfVxuXG4gICAgcmVhZG9ubHkgTUFUX0lDT05fUkVHRVggPSAvWzpcXC9cXC5dLztcblxuICAgIHF1ZXJ5U3RyaW5nID0gXCJcIjtcbiAgICBhY3RpdmVJbmRleCA9IDA7XG4gICAgcmVhZG9ubHkgcm93SGVpZ2h0ID0gMjk7XG4gICAgcmVhZG9ubHkgcGFkZGluZyA9IDY7XG5cbiAgICBjb21tYW5kczogQ29tbWFuZEFjdGlvbltdID0gW107XG4gICAgZmlsdGVyZWRDb21tYW5kczogQ29tbWFuZEFjdGlvbltdID0gW107XG5cbiAgICBicmVhZGNydW1iczoge1xuICAgICAgICBhY3Rpb246IENvbW1hbmRBY3Rpb24sXG4gICAgICAgIGNvbW1hbmRzOiBDb21tYW5kQWN0aW9uW10sXG4gICAgICAgIGRlc3Ryb3lpbmc6IGJvb2xlYW4sXG4gICAgICAgIHNlbGVjdGVkSW5kZXg6IG51bWJlclxuICAgIH1bXSA9IFtdO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY29tbWFuZFBhbGV0dGU6IENvbW1hbmRQYWxldHRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBkaWFsb2c6IE1hdERpYWxvZ1JlZjxhbnk+LFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBASW5qZWN0KE1BVF9ESUFMT0dfREFUQSkgZGF0YTogYW55XG4gICAgKSB7XG4gICAgICAgIHRoaXMuY29udGV4dEVsZW1lbnQgPSB0aGlzLmNvbnRleHRFbGVtZW50ID8/IGRhdGEuY29udGV4dEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuY29tbWFuZHMgPSB0aGlzLmNvbW1hbmRQYWxldHRlLmdldFJlZ2lzdGVyZWRDb21tYW5kcyh0aGlzLmNvbnRleHRFbGVtZW50KVxuICAgICAgICB0aGlzLnNldENvbW1hbmRMaXN0KHRoaXMuY29tbWFuZHMpO1xuXG4gICAgICAgIC8vIFRPRE86IGN1c3RvbSBuYW1lXG4gICAgICAgIHRoaXMuYnJlYWRjcnVtYnMucHVzaCh7XG4gICAgICAgICAgICBhY3Rpb246IHsgbGFiZWw6IFwiL1wiIH0sXG4gICAgICAgICAgICBjb21tYW5kczogdGhpcy5jb21tYW5kcyxcbiAgICAgICAgICAgIGRlc3Ryb3lpbmc6IGZhbHNlLFxuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleDogMFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbktleURvd24oZXZ0OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgICAgIHN3aXRjaChldnQua2V5KSB7XG4gICAgICAgICAgICBjYXNlIFwiRW50ZXJcIjoge1xuICAgICAgICAgICAgICAgIC8vIEZpcmUgdGhlIGZpcnN0IGNvbW1hbmRcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJlZENvbW1hbmRzLmxlbmd0aCA+IDApXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhlY3V0ZUNvbW1hbmQodGhpcy5maWx0ZXJlZENvbW1hbmRzW3RoaXMuYWN0aXZlSW5kZXhdKTtcblxuICAgICAgICAgICAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiQXJyb3dVcFwiOiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVJbmRleCA9IE1hdGgubWF4KHRoaXMuYWN0aXZlSW5kZXgtMSwgMCk7XG5cbiAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1c1JvdygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJBcnJvd0Rvd25cIjoge1xuICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlSW5kZXggPSBNYXRoLm1pbih0aGlzLmZpbHRlcmVkQ29tbWFuZHMubGVuZ3RoLTEsIHRoaXMuYWN0aXZlSW5kZXgrMSk7XG5cbiAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1c1JvdygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJQYWdlVXBcIjoge1xuICAgICAgICAgICAgICAgIC8vIEZpcmUgdGhlIGZpcnN0IGNvbW1hbmRcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZUluZGV4ID0gTWF0aC5tYXgodGhpcy5hY3RpdmVJbmRleC0xMiwgMCk7XG5cbiAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1c1JvdygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJQYWdlRG93blwiOiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVJbmRleCA9IE1hdGgubWluKHRoaXMuZmlsdGVyZWRDb21tYW5kcy5sZW5ndGgtMSwgdGhpcy5hY3RpdmVJbmRleCsxMik7XG5cbiAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1c1JvdygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJFc2NhcGVcIjoge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlhbG9nLmNsb3NlKCk7XG4gICAgICAgICAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgXCJCYWNrc3BhY2VcIjoge1xuICAgICAgICAgICAgICAgIC8vIElmIHdlIGhhdmUgbm8gY2hhcmFjdGVycyBhbmQgd2UncmUgaGl0dGluZyBiYWNrc3BhY2UsIGdvIGJhY2tcbiAgICAgICAgICAgICAgICAvLyB0byB0aGUgcHJldmlvdXMgbWVudSBpbiB0aGUgYnJlYWRjcnVtYlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnF1ZXJ5U3RyaW5nLmxlbmd0aCA9PSAwICYmIHRoaXMuYnJlYWRjcnVtYnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXllciA9IHRoaXMuYnJlYWRjcnVtYnMuYXQoLTEpO1xuICAgICAgICAgICAgICAgICAgICBsYXllci5kZXN0cm95aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldENvbW1hbmRMaXN0KHRoaXMuYnJlYWRjcnVtYnMuYXQoLTIpLmNvbW1hbmRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnJlYWRjcnVtYnMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZUluZGV4ID0gbGF5ZXIuc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgfSwgMTkwKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiRGVsZXRlXCI6IHtcblxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5hY3RpdmVJbmRleCA9IDA7XG4gICAgICAgIHRoaXMuY29tbWFuZHMuZm9yRWFjaChjID0+IGNbJ19yZW5kZXJlZExhYmVsJ10gPSAnJyk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaW4gdGhlIG5leHQgdGljayB0byBnZXQgdGhlIGlucHV0J3NcbiAgICAgICAgLy8gdmFsdWUgc28gdGhhdCBpdCdzIHVwZGF0ZWRcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnF1ZXJ5U3RyaW5nID0gKGV2dC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XG4gICAgICAgICAgICB0aGlzLmZpbHRlclJlc3VsdHMoKTtcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGZpbHRlclJlc3VsdHMoKSB7XG4gICAgICAgIC8vIFdoaXRlc3BhY2UgZG9lc24ndCBjb3VudC5cbiAgICAgICAgaWYgKHRoaXMucXVlcnlTdHJpbmcudHJpbSgpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcmVkQ29tbWFuZHMgPSB0aGlzLmNvbW1hbmRzO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcXVlcnlDaGFycyA9IHRoaXMucXVlcnlTdHJpbmdcbiAgICAgICAgICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAuc3BsaXQoJycpO1xuXG4gICAgICAgIGNvbnN0IG1hdGNoZWRDb21tYW5kczogQ29tbWFuZEFjdGlvbltdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBjb21tYW5kIG9mIHRoaXMuY29tbWFuZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgbGFiZWwgfSA9IGNvbW1hbmQ7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIHRoZSBsYWJlbFxuICAgICAgICAgICAgaWYgKGNvbW1hbmQubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21tYW5kQ2hhcnMgPSBsYWJlbFxuICAgICAgICAgICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICAgICAgICAuc3BsaXQoJycpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHJlbmRlcmVkTGFiZWwgPSAnJztcbiAgICAgICAgICAgICAgICBsZXQgbGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICBsZXQgaXNNYXRjaCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoYXIgb2YgcXVlcnlDaGFycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGNvbW1hbmRDaGFycy5pbmRleE9mKGNoYXIsIGxhc3RJbmRleCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc01hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVkTGFiZWwgKz0gbGFiZWwuc2xpY2UobGFzdEluZGV4LCBpbmRleCkgKyBgPGI+JHtsYWJlbC5zbGljZShpbmRleCwgaW5kZXggKyAxKX08L2I+YDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlbmRlcmVkTGFiZWwgKz0gbGFiZWwuc2xpY2UobGFzdEluZGV4KTtcblxuICAgICAgICAgICAgICAgIGlmIChpc01hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbW1hbmRbJ19yZW5kZXJlZExhYmVsJ10gPSByZW5kZXJlZExhYmVsO1xuICAgICAgICAgICAgICAgICAgICBtYXRjaGVkQ29tbWFuZHMucHVzaChjb21tYW5kKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIHRoZSBoaW50XG4gICAgICAgICAgICBpZiAoY29tbWFuZC5oaW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29tbWFuZENoYXJzID0gbGFiZWxcbiAgICAgICAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICAgICAgLnNwbGl0KCcnKTtcblxuICAgICAgICAgICAgICAgIGxldCByZW5kZXJlZEhpbnQgPSAnJztcbiAgICAgICAgICAgICAgICBsZXQgbGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICBsZXQgaXNNYXRjaCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoYXIgb2YgcXVlcnlDaGFycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IGNvbW1hbmRDaGFycy5pbmRleE9mKGNoYXIsIGxhc3RJbmRleCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc01hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVkSGludCArPSBsYWJlbC5zbGljZShsYXN0SW5kZXgsIGluZGV4KSArIGA8Yj4ke2xhYmVsLnNsaWNlKGluZGV4LCBpbmRleCArIDEpfTwvYj5gO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEluZGV4ID0gaW5kZXggKyAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVuZGVyZWRIaW50ICs9IGxhYmVsLnNsaWNlKGxhc3RJbmRleCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBjb21tYW5kWydfcmVuZGVyZWRIaW50J10gPSByZW5kZXJlZEhpbnQ7XG4gICAgICAgICAgICAgICAgICAgIG1hdGNoZWRDb21tYW5kcy5wdXNoKGNvbW1hbmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZmlsdGVyZWRDb21tYW5kcyA9IG1hdGNoZWRDb21tYW5kcztcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Q29tbWFuZExpc3QoY29tbWFuZHM6IENvbW1hbmRBY3Rpb25bXSkge1xuICAgICAgICB0aGlzLmNvbW1hbmRzID0gY29tbWFuZHNcbiAgICAgICAgICAgIC5maWx0ZXIoYyA9PiBjLnZpc2libGVJbkxpc3QgIT0gZmFsc2UpO1xuICAgICAgICB0aGlzLmZpbHRlcmVkQ29tbWFuZHMgPSB0aGlzLmNvbW1hbmRzO1xuICAgICAgICB0aGlzLnF1ZXJ5U3RyaW5nID0gJyc7XG4gICAgICAgIHRoaXMuYWN0aXZlSW5kZXggPSAwO1xuXG4gICAgICAgIC8vIFJlc2V0IHRoZSBmaWx0ZXIgbGFiZWxzXG4gICAgICAgIHRoaXMuY29tbWFuZHMuZm9yRWFjaChjb21tYW5kID0+IGNvbW1hbmRbJ19yZW5kZXJlZExhYmVsJ10gPSAnJyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmb2N1c1JvdygpIHtcbiAgICAgICAgY29uc3QgdG9wID0gdGhpcy5hY3RpdmVJbmRleCAqIHRoaXMucm93SGVpZ2h0O1xuICAgICAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnJvd0hlaWdodDtcblxuICAgICAgICBjb25zdCB2aWV3VG9wID0gdGhpcy5zY3JvbGxiYXI/LnZpZXdwb3J0Py5zY3JvbGxUb3A7XG4gICAgICAgIGNvbnN0IHZpZXdIZWlnaHQgPSB0aGlzLnNjcm9sbGJhcj8udmlld3BvcnQ/LmNsaWVudEhlaWdodDtcbiAgICAgICAgY29uc3Qgdmlld0JvdHRvbSA9IHZpZXdUb3AgKyB2aWV3SGVpZ2h0O1xuXG4gICAgICAgIGlmICh0b3AgPCB2aWV3VG9wKSB7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbGJhci52aWV3cG9ydC5uYXRpdmVFbGVtZW50LnNjcm9sbFRvKHsgdG9wOiB0b3AgKyB0aGlzLnBhZGRpbmcgfSlcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgodG9wICsgaGVpZ2h0KSA+IHZpZXdCb3R0b20pIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsYmFyLnZpZXdwb3J0Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG8oeyB0b3A6ICgodG9wICsgdGhpcy5yb3dIZWlnaHQpIC0gdmlld0hlaWdodCkgKyB0aGlzLnBhZGRpbmcgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEltbWVkaWF0ZWx5IGNoZWNrIGZvciBjaGFuZ2VzIHRvIHVwZGF0ZSB0ZW1wbGF0ZVxuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBleGVjdXRlQ29tbWFuZChjb21tYW5kOiBDb21tYW5kQWN0aW9uKSB7XG4gICAgICAgIC8vIE9wZW4gYSBzdWIgbWVudSBvZiBpdGVtc1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShjb21tYW5kLnN1Yk1lbnUpKSB7XG4gICAgICAgICAgICB0aGlzLmJyZWFkY3J1bWJzLnB1c2goe1xuICAgICAgICAgICAgICAgIGFjdGlvbjogY29tbWFuZCxcbiAgICAgICAgICAgICAgICBjb21tYW5kczogY29tbWFuZC5zdWJNZW51LFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkSW5kZXg6IHRoaXMuYWN0aXZlSW5kZXgsXG4gICAgICAgICAgICAgICAgZGVzdHJveWluZzogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnNldENvbW1hbmRMaXN0KGNvbW1hbmQuc3ViTWVudSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRGlyZWN0bHkgaW52b2tlIHRoZSBhY3Rpb24gYW5kIGtpbGwgdGhlIGRpYWxvZ1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29tbWFuZFBhbGV0dGUuaW52b2tlQWN0aW9uKGNvbW1hbmQpO1xuICAgICAgICAgICAgdGhpcy5kaWFsb2cuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6Ymx1clwiKVxuICAgIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6cmVzaXplXCIpXG4gICAgb25CbHVyKCkge1xuICAgICAgICBpZiAoIWlzRGV2TW9kZSgpKSB7XG4gICAgICAgICAgICB0aGlzLmRpYWxvZy5jbG9zZSgpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiPG1hdC1mb3JtLWZpZWxkIHN0eWxlPVwid2lkdGg6IDEwMCU7IHBhZGRpbmc6IDhweCA4cHggMCA4cHhcIj5cbiAgICA8bmd4LWNvbW1hbmRwYWxldHRlLWJyZWFkY3J1bWJcbiAgICAgICAgW2JyZWFkY3J1bWJzXT1cImJyZWFkY3J1bWJzXCJcbiAgICAvPlxuICAgIDxpbnB1dFxuICAgICAgICAjdGV4dGlucHV0XG4gICAgICAgIG1hdElucHV0XG4gICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgW3ZhbHVlXT1cInF1ZXJ5U3RyaW5nXCJcbiAgICAgICAgKGtleWRvd24pPVwib25LZXlEb3duKCRldmVudClcIlxuICAgID5cbjwvbWF0LWZvcm0tZmllbGQ+XG5cbkBpZiAoZmlsdGVyZWRDb21tYW5kcy5sZW5ndGggPT0gMCkge1xuICAgIDxkaXYgY2xhc3M9XCJjb21tYW5kc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29tbWFuZCBzZWxlY3RlZFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxhYmVsXCI+Tm8gbWF0Y2hpbmcgcmVzdWx0cy48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG59XG5AZWxzZSB7XG4gICAgPGRpdlxuICAgICAgICBjbGFzcz1cImNvbW1hbmRzXCJcbiAgICAgICAgW3N0eWxlLmZsZXhdPVwiKGZpbHRlcmVkQ29tbWFuZHMubGVuZ3RoICogcm93SGVpZ2h0KSArICdweCdcIlxuICAgICAgICBbY2xhc3Muc2hhZG93XT1cInNjcm9sbGJhcj8udmlld3BvcnQ/LnNjcm9sbFRvcCA+IDJcIlxuICAgID5cbiAgICAgICAgPG5nLXNjcm9sbGJhciAjc2Nyb2xsYmFyPlxuICAgICAgICAgICAgPGNkay12aXJ0dWFsLXNjcm9sbC12aWV3cG9ydCBbaXRlbVNpemVdPVwicm93SGVpZ2h0XCIgc2Nyb2xsVmlld3BvcnQgW21pbkJ1ZmZlclB4XT1cIjE1MFwiPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgKmNka1ZpcnR1YWxGb3I9XCJsZXQgY29tbWFuZCBvZiBmaWx0ZXJlZENvbW1hbmRzOyBsZXQgaW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tbWFuZFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHRdPVwicm93SGVpZ2h0ICsgJ3B4J1wiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJpbmRleD09YWN0aXZlSW5kZXhcIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaGFzLWljb25dPVwiY29tbWFuZC5pY29uXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dHIuaW5kZXhdPVwiaW5kZXhcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhlY3V0ZUNvbW1hbmQoY29tbWFuZClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChjb21tYW5kLmljb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpY29uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghTUFUX0lDT05fUkVHRVgudGVzdChjb21tYW5kLmljb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBbZm9udEljb25dPVwiY29tbWFuZC5pY29uXCI+PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiY29tbWFuZC5pY29uXCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsYWJlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cImNvbW1hbmRbJ19yZW5kZXJlZExhYmVsJ10gfHwgY29tbWFuZC5sYWJlbCB8fCBjb21tYW5kLmRlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIEBpZiAoY29tbWFuZFsnX3JlbmRlcmVkSGludCddIHx8IGNvbW1hbmQuaGludCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaGludFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJjb21tYW5kWydfcmVuZGVyZWRIaW50J10gfHwgY29tbWFuZC5oaW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZmxleDogMVwiPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChzaG9ydGN1dCBvZiAoY29tbWFuZC5zaG9ydGN1dEtleT8uZmluZCA/IGNvbW1hbmQuc2hvcnRjdXRLZXkgOiBbY29tbWFuZC5zaG9ydGN1dEtleV0pOyB0cmFjayBzaG9ydGN1dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2hvcnRjdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1jb21tYW5kcGFsZXR0ZS1zaG9ydGN1dCBbc2hvcnRjdXRdPVwic2hvcnRjdXRcIi8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvY2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0PlxuICAgICAgICA8L25nLXNjcm9sbGJhcj5cbiAgICA8L2Rpdj5cbn1cblxuIl19