@cqa-lib/cqa-ui 1.1.549 → 1.1.550

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.
@@ -3,12 +3,11 @@ import { DEFAULT_MODULAR_LABELS, } from '../modular-table-template.models';
3
3
  import * as i0 from "@angular/core";
4
4
  import * as i1 from "@angular/material/icon";
5
5
  import * as i2 from "../../../search-bar/search-bar.component";
6
- import * as i3 from "@angular/material/progress-spinner";
7
- import * as i4 from "@angular/common";
8
- import * as i5 from "../directives/folder-drop.directive";
9
- import * as i6 from "../directives/folder-drag.directive";
10
- import * as i7 from "@angular/forms";
11
- import * as i8 from "@angular/cdk/overlay";
6
+ import * as i3 from "@angular/common";
7
+ import * as i4 from "../directives/folder-drop.directive";
8
+ import * as i5 from "../directives/folder-drag.directive";
9
+ import * as i6 from "@angular/forms";
10
+ import * as i7 from "@angular/cdk/overlay";
12
11
  export class FolderSidebarComponent {
13
12
  constructor(cdr) {
14
13
  this.cdr = cdr;
@@ -24,6 +23,7 @@ export class FolderSidebarComponent {
24
23
  this.allowDrop = true;
25
24
  this.showCounts = true;
26
25
  this.collapsed = false;
26
+ this.foldersAccordionExpanded = true;
27
27
  this.labels = { ...DEFAULT_MODULAR_LABELS };
28
28
  /** When true, the sidebar emits `searchChange` and skips its local name filter
29
29
  * — the host is expected to swap `folders` with server-side search results.
@@ -42,6 +42,11 @@ export class FolderSidebarComponent {
42
42
  * spinner; when set during pagination, a small spinner appears at the
43
43
  * bottom of the tree. */
44
44
  this.rootFoldersLoading = false;
45
+ /** Folder ids currently being saved (rename / move / etc). The sidebar renders
46
+ * a small spinner in place of the count so the user gets feedback while the
47
+ * host's API call is in flight. The host is responsible for adding/removing
48
+ * ids around its async call. */
49
+ this.savingFolderIds = [];
45
50
  this.folderSelected = new EventEmitter();
46
51
  this.folderExpansionToggled = new EventEmitter();
47
52
  /** Lazy-load: fires when the user expands a node whose children haven't been
@@ -71,6 +76,7 @@ export class FolderSidebarComponent {
71
76
  /** Fires when a folder row is dropped onto another folder (or the Unorganized row). */
72
77
  this.folderDropped = new EventEmitter();
73
78
  this.collapsedChange = new EventEmitter();
79
+ this.foldersAccordionExpandedChange = new EventEmitter();
74
80
  /** Bound to the search input. Exposed as an Input so hosts can seed/restore
75
81
  * the visible search term across destroy/re-create cycles (e.g., when the
76
82
  * sidebar is `*ngIf`'d out by a view-mode toggle and re-mounted later). */
@@ -114,8 +120,35 @@ export class FolderSidebarComponent {
114
120
  * Used to throttle the scroll-based pagination so we don't re-emit until the
115
121
  * host has actually appended a new page. */
116
122
  this.lastRootLoadEmittedAt = -1;
123
+ /** Toggles the inline folder-search input. When closing while a query is active,
124
+ * also clear the search so the tree reverts to its full state. */
125
+ this.searchVisible = false;
117
126
  this.trackByRow = (_, row) => `${row.kind}_${row.node.id}`;
118
127
  }
128
+ isFolderSaving(id) {
129
+ return this.savingFolderIds?.includes(id) ?? false;
130
+ }
131
+ folderRowTooltip(node) {
132
+ const name = node?.name || '';
133
+ if (node?.totalCount == null) {
134
+ return name || null;
135
+ }
136
+ const tpl = node.totalCount === 1
137
+ ? this.labels.folderTooltipTotalSingular
138
+ : this.labels.folderTooltipTotalPlural;
139
+ const countLine = (tpl || '').replace('{n}', String(node.totalCount));
140
+ return name ? `${name}\n${countLine}` : countLine;
141
+ }
142
+ /** Visual depth indent: linear up to a cap, then quarter-rate beyond, so deep
143
+ * trees don't push the row content off the right edge of the panel. */
144
+ rowIndent(depth) {
145
+ const step = 16;
146
+ const cap = 6;
147
+ const base = 8;
148
+ if (depth <= cap)
149
+ return base + depth * step;
150
+ return base + cap * step + (depth - cap) * 4;
151
+ }
119
152
  get expandedSet() {
120
153
  return new Set(this.expandedFolderIds || []);
121
154
  }
@@ -478,8 +511,28 @@ export class FolderSidebarComponent {
478
511
  }
479
512
  togglePanel() {
480
513
  this.collapsed = !this.collapsed;
514
+ if (this.collapsed)
515
+ this.searchVisible = false;
481
516
  this.collapsedChange.emit(this.collapsed);
482
517
  }
518
+ toggleFoldersAccordion() {
519
+ this.foldersAccordionExpanded = !this.foldersAccordionExpanded;
520
+ if (!this.foldersAccordionExpanded)
521
+ this.searchVisible = false;
522
+ this.foldersAccordionExpandedChange.emit(this.foldersAccordionExpanded);
523
+ this.cdr.markForCheck();
524
+ }
525
+ toggleSearchVisible() {
526
+ if (!this.foldersAccordionExpanded && !this.searchVisible) {
527
+ this.foldersAccordionExpanded = true;
528
+ this.foldersAccordionExpandedChange.emit(true);
529
+ }
530
+ this.searchVisible = !this.searchVisible;
531
+ if (!this.searchVisible && (this.searchValue || '').trim()) {
532
+ this.onSearchClear();
533
+ }
534
+ this.cdr.markForCheck();
535
+ }
483
536
  rowDropped(targetId, event) {
484
537
  // Directive already emits with the bound folder id, but normalise in case callers
485
538
  // wire raw events.
@@ -631,10 +684,10 @@ FolderSidebarComponent.RENAME_LIMIT_FLASH_MS = 600;
631
684
  * position is within this many px of the end. */
632
685
  FolderSidebarComponent.SCROLL_LOAD_THRESHOLD_PX = 64;
633
686
  FolderSidebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: FolderSidebarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
634
- FolderSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: FolderSidebarComponent, selector: "cqa-folder-sidebar", inputs: { folders: "folders", selectedFolderId: "selectedFolderId", expandedFolderIds: "expandedFolderIds", unorganizedCount: "unorganizedCount", allowCreate: "allowCreate", allowRename: "allowRename", allowDelete: "allowDelete", allowMove: "allowMove", allowDuplicate: "allowDuplicate", allowDrop: "allowDrop", showCounts: "showCounts", collapsed: "collapsed", labels: "labels", serverSideSearch: "serverSideSearch", rootTotal: "rootTotal", folderSearchLoading: "folderSearchLoading", rootFoldersLoading: "rootFoldersLoading", searchValue: "searchValue" }, outputs: { folderSelected: "folderSelected", folderExpansionToggled: "folderExpansionToggled", folderChildrenRequested: "folderChildrenRequested", folderLoadMoreRequested: "folderLoadMoreRequested", searchChange: "searchChange", rootLoadMoreRequested: "rootLoadMoreRequested", folderCreated: "folderCreated", folderCreateRequested: "folderCreateRequested", folderRenamed: "folderRenamed", folderDeleted: "folderDeleted", folderMoveRequested: "folderMoveRequested", folderDuplicateRequested: "folderDuplicateRequested", testsDropped: "testsDropped", folderDropped: "folderDropped", collapsedChange: "collapsedChange" }, host: { listeners: { "document:click": "onDocumentClick()", "document:keydown.escape": "onEscape()", "document:dragend": "onDocumentDragEnd()" }, classAttribute: "cqa-ui-root" }, ngImport: i0, template: "<!-- Reusable folder icon. Render via <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: node.color }\"></ng-container>. -->\n<ng-template #folderIcon let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-4 cqa-h-4 cqa-shrink-0\">\n <svg width=\"13\" height=\"12\" viewBox=\"0 0 13 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.1916 9.85824C12.1916 10.1677 12.0687 10.4644 11.8499 10.6832C11.6311 10.902 11.3343 11.0249 11.0249 11.0249H1.69157C1.38215 11.0249 1.0854 10.902 0.866611 10.6832C0.647819 10.4644 0.524902 10.1677 0.524902 9.85824V1.69157C0.524902 1.38215 0.647819 1.0854 0.866611 0.866611C1.0854 0.647819 1.38215 0.524902 1.69157 0.524902H4.60824L5.7749 2.2749H11.0249C11.3343 2.2749 11.6311 2.39782 11.8499 2.61661C12.0687 2.8354 12.1916 3.13215 12.1916 3.44157V9.85824Z\" [attr.stroke]=\"color || '#99999E'\" stroke-width=\"1.05\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<aside\n class=\"cqa-flex cqa-flex-col cqa-bg-white cqa-border cqa-border-neutral-200 cqa-rounded-lg cqa-h-full cqa-min-h-0\"\n [class.cqa-w-[240px]]=\"!collapsed\"\n [class.cqa-w-[48px]]=\"collapsed\"\n style=\"transition: width 150ms ease;\"\n>\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-3 cqa-py-1\"\n [style.border-bottom]=\"collapsed ? null : '1px solid #E2E2E3'\"\n [style.margin-bottom.px]=\"collapsed ? 0 : 8\"\n >\n <span *ngIf=\"!collapsed\" class=\"cqa-text-sm cqa-font-semibold cqa-text-neutral-900\">\n {{ labels.folders }}\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\" [class.cqa-w-full]=\"collapsed\" [class.cqa-justify-center]=\"collapsed\">\n <button\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"togglePanel()\"\n [attr.aria-label]=\"collapsed ? 'Expand folders panel' : 'Collapse folders panel'\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">\n {{ collapsed ? 'chevron_right' : 'keyboard_double_arrow_left' }}\n </mat-icon>\n </button>\n <button\n *ngIf=\"!collapsed && allowCreate\"\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"requestCreate(null)\"\n [attr.aria-label]=\"labels.newFolder\"\n [title]=\"labels.newFolder\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!collapsed\">\n <!-- Search -->\n <div class=\"cqa-px-3 cqa-pb-2\">\n <div class=\"cqa-relative\">\n <cqa-search-bar\n size=\"sm\"\n [fullWidth]=\"true\"\n [value]=\"searchValue\"\n [placeholder]=\"labels.searchFoldersPlaceholder\"\n [showClear]=\"true\"\n (valueChange)=\"onSearchInput($event)\"\n (cleared)=\"onSearchClear()\"\n ></cqa-search-bar>\n <span\n *ngIf=\"folderSearchLoading\"\n class=\"cqa-absolute cqa-right-8 cqa-inset-y-0 cqa-flex cqa-items-center\"\n aria-live=\"polite\"\n aria-label=\"Searching folders\"\n >\n <mat-spinner diameter=\"14\" mode=\"indeterminate\"></mat-spinner>\n </span>\n </div>\n </div>\n\n <!-- Tree (folders only \u2014 Unorganized sits directly below; tree caps at 60vh and scrolls when overflowing).\n Scroll-based lazy-loading at the root level: nearing the bottom emits\n `rootLoadMoreRequested`, which the host responds to by fetching the\n next page of roots. -->\n <div role=\"tree\" class=\"cqa-min-h-0 cqa-max-h-[60vh] cqa-overflow-y-auto cqa-py-1 cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB]\"\n (scroll)=\"onTreeScroll($event)\">\n <!-- Initial-load spinner: only renders when we have no folders yet AND\n no search active (search has its own inline spinner). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length === 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-6\"\n aria-live=\"polite\"\n >\n <mat-spinner diameter=\"20\" mode=\"indeterminate\"></mat-spinner>\n </div>\n <div\n *ngIf=\"searchValue?.trim() && rows.length === 0 && !folderSearchLoading\"\n class=\"cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-neutral-500 cqa-text-center\"\n >\n {{ labels.noFoldersFound }}\n </div>\n <ng-container *ngFor=\"let row of rows; let i = index; trackBy: trackByRow\">\n <!-- Synthetic loading row (lazy fetch in flight) -->\n <div\n *ngIf=\"row.kind === 'loading'\"\n [style.paddingLeft.px]=\"8 + row.depth * 16\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-1.5 cqa-text-sm cqa-text-neutral-500\"\n aria-live=\"polite\"\n >\n <mat-spinner diameter=\"14\" mode=\"indeterminate\"></mat-spinner>\n <span>Loading\u2026</span>\n </div>\n <!-- Synthetic load-more row (more children available on backend) -->\n <button\n *ngIf=\"row.kind === 'load-more'\"\n type=\"button\"\n [style.paddingLeft.px]=\"8 + row.depth * 16\"\n class=\"cqa-flex cqa-items-center cqa-w-full cqa-py-1.5 cqa-text-sm cqa-text-indigo-600 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onLoadMore(row.node); $event.stopPropagation()\"\n >\n <span>Load more ({{ (row.node.totalChildren ?? 0) - (row.node.children?.length ?? 0) }})</span>\n </button>\n <!-- Real folder row -->\n <div\n *ngIf=\"row.kind === 'folder'\"\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"row.hasChildren ? isExpanded(row.node.id) : null\"\n [attr.aria-selected]=\"isSelected(row.node.id)\"\n [attr.data-folder-row-id]=\"row.node.id\"\n [cqaFolderDrop]=\"row.node.id\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(row.node.id, $event)\"\n (folderDropped)=\"onFolderRowDropped(row.node.id, $event)\"\n [cqaFolderDrag]=\"row.node.id\"\n [dragEnabled]=\"allowDrop\"\n (dragstart)=\"onFolderDragStart(row.node)\"\n (dragend)=\"onFolderDragEnd()\"\n (dragover)=\"onFolderRowDragOver(row)\"\n (dragleave)=\"onFolderRowDragLeave(row)\"\n (click)=\"onSelect(row.node)\"\n (contextmenu)=\"openContextMenu(row.node, $event)\"\n (keydown)=\"onRowKeydown($event, row, i)\"\n class=\"cqa-group cqa-flex cqa-items-center cqa-gap-1 cqa-pr-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-indigo-50 focus:cqa-outline-none focus:cqa-bg-indigo-50 cqa-relative\"\n [class.cqa-bg-indigo-50]=\"isSelected(row.node.id) || contextMenuFolderId === row.node.id\"\n [style.paddingLeft.px]=\"8 + row.depth * 16\"\n [attr.title]=\"row.node.totalCount != null ? (row.node.totalCount + ' total including subfolders') : null\"\n >\n <span\n *ngIf=\"isSelected(row.node.id)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <button\n type=\"button\"\n class=\"cqa-p-0\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [style.visibility]=\"row.hasChildren ? 'visible' : 'hidden'\"\n (click)=\"onToggle(row.node, $event)\"\n [attr.aria-label]=\"isExpanded(row.node.id) ? 'Collapse' : 'Expand'\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">\n {{ isExpanded(row.node.id) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: row.node.color }\"></ng-container>\n\n <ng-container *ngIf=\"renamingId === row.node.id; else nameTpl\">\n <input\n type=\"text\"\n size=\"1\"\n [attr.data-folder-rename-input]=\"row.node.id\"\n [attr.maxlength]=\"renameMaxLength\"\n class=\"cqa-flex-1 cqa-min-w-0 cqa-w-full cqa-px-2 cqa-py-0.5 cqa-rounded cqa-border cqa-bg-white cqa-text-sm cqa-shadow-sm focus:cqa-outline-none focus:cqa-ring-1\"\n [ngClass]=\"(isRenameDraftValid && !renameLimitFlash)\n ? 'cqa-border-neutral-300 focus:cqa-border-indigo-400 focus:cqa-ring-indigo-200'\n : 'cqa-border-[#EF4444] focus:cqa-border-[#EF4444] focus:cqa-ring-[#FCA5A5]'\"\n [attr.aria-invalid]=\"!isRenameDraftValid || renameLimitFlash\"\n [(ngModel)]=\"renameDraft\"\n (keydown)=\"onRenameKey($event, row.node)\"\n (keypress)=\"$event.stopPropagation()\"\n (keyup)=\"$event.stopPropagation()\"\n (blur)=\"commitRename(row.node)\"\n (click)=\"$event.stopPropagation()\"\n />\n </ng-container>\n <ng-template #nameTpl>\n <span\n class=\"cqa-flex-1 cqa-text-sm cqa-truncate\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n (dblclick)=\"beginRename(row.node, $event)\"\n >{{ row.node.name }}</span>\n </ng-template>\n\n <!-- Count shown at rest; hidden on row hover when delete is allowed -->\n <span\n *ngIf=\"showCounts && row.node.count != null\"\n class=\"cqa-text-xs cqa-tabular-nums cqa-ml-1\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [class.group-hover:cqa-hidden]=\"allowDelete\"\n >{{ row.node.count }}</span>\n\n <button\n *ngIf=\"hasAnyContextAction\"\n type=\"button\"\n class=\"cqa-p-0.5 cqa-rounded hover:cqa-bg-neutral-200\"\n [style.color]=\"isSelected(row.node.id) || contextMenuFolderId === row.node.id ? '#3F43EE' : '#4C4C51'\"\n [class.cqa-hidden]=\"contextMenuFolderId !== row.node.id\"\n [class.group-hover:cqa-inline-flex]=\"true\"\n [class.cqa-inline-flex]=\"contextMenuFolderId === row.node.id\"\n (click)=\"openContextMenu(row.node, $event)\"\n [attr.aria-label]=\"'Open actions for ' + row.node.name\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"contextMenuFolderId === row.node.id\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">more_horiz</mat-icon>\n </button>\n </div>\n </ng-container>\n <!-- Root-level pagination is now driven by scroll (see `(scroll)` on the\n tree container above). Per-folder children retain the explicit\n \"Load more\" button rendered inside the rows loop above, since\n subtrees aren't independently scrollable. -->\n <!-- Pagination spinner \u2014 visible only when fetching an additional page\n of roots (folders.length > 0 distinguishes from initial-load case). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length > 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-2\"\n aria-live=\"polite\"\n >\n <mat-spinner diameter=\"14\" mode=\"indeterminate\"></mat-spinner>\n </div>\n </div>\n\n <!-- Divider between folder tree and pinned Unorganized tab -->\n <div\n aria-hidden=\"true\"\n class=\"cqa-mx-3 cqa-shrink-0\"\n style=\"height: 1px; background-color: #E5E7EB; margin-top: 6px; margin-bottom: 6px;\"\n ></div>\n\n <!-- Unorganized \u2014 pinned below the scrollable folder tree so it stays visible regardless of folder count -->\n <div\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(null)\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-px-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-indigo-50 focus:cqa-outline-none focus:cqa-bg-indigo-50 cqa-relative cqa-shrink-0\"\n [class.cqa-bg-indigo-50]=\"isSelected(null)\"\n [cqaFolderDrop]=\"null\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(null, $event)\"\n (folderDropped)=\"onFolderRowDropped(null, $event)\"\n (click)=\"onSelectUnorganized()\"\n >\n <span\n *ngIf=\"isSelected(null)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <mat-icon [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <span class=\"cqa-flex-1 cqa-text-sm\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ labels.unorganized }}</span>\n <span *ngIf=\"showCounts\" class=\"cqa-text-xs cqa-tabular-nums\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ unorganizedCount }}</span>\n </div>\n\n <!-- Folder context menu (right-click / ellipsis). A 0\u00D70 fixed-position\n anchor at the click coords drives a cdkConnectedOverlay; CDK's\n flexible-connected positioning auto-flips up/left when the menu\n would overflow the viewport (last-folder-near-bottom case). -->\n <div #ctxAnchor cdkOverlayOrigin\n class=\"cqa-fixed cqa-w-0 cqa-h-0 cqa-pointer-events-none\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"></div>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"ctxAnchor\"\n [cdkConnectedOverlayOpen]=\"contextMenuFolderId !== null\"\n [cdkConnectedOverlayPositions]=\"contextMenuPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n (overlayOutsideClick)=\"onOverlayOutsideClick()\"\n (detach)=\"closeContextMenu()\"\n >\n <!-- The lib's tailwind config sets important: '.cqa-ui-root', which\n emits descendant selectors like `.cqa-ui-root .cqa-bg-white`.\n CDK Overlay teleports this template into the global overlay\n container (outside the host's cqa-ui-root), so we wrap the menu in\n an ancestor cqa-ui-root div to re-establish the utility scope. -->\n <div class=\"cqa-ui-root\">\n <div\n role=\"menu\"\n class=\"cqa-min-w-[180px] cqa-bg-white cqa-border cqa-border-neutral-200 cqa-rounded-md cqa-shadow-lg cqa-py-1\"\n (click)=\"$event.stopPropagation()\"\n (contextmenu)=\"$event.preventDefault(); $event.stopPropagation()\"\n >\n <ng-container *ngIf=\"folderById(contextMenuFolderId) as menuNode\">\n <button\n *ngIf=\"allowCreate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextCreateSubfolder(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">create_new_folder</mat-icon>\n <span>{{ labels.folderMenuCreateSubfolder }}</span>\n </button>\n <button\n *ngIf=\"allowRename\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextRename(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">edit</mat-icon>\n <span>{{ labels.folderMenuRename }}</span>\n </button>\n <button\n *ngIf=\"allowMove\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextMove(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">drive_file_move</mat-icon>\n <span>{{ labels.folderMenuMove }}</span>\n </button>\n <button\n *ngIf=\"allowDuplicate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextDuplicate(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">content_copy</mat-icon>\n <span>{{ labels.folderMenuDuplicate }}</span>\n </button>\n <div *ngIf=\"allowDelete && (allowCreate || allowRename || allowMove || allowDuplicate)\" class=\"cqa-h-px cqa-bg-neutral-200 cqa-my-1\"></div>\n <button\n *ngIf=\"allowDelete\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-red-600 hover:cqa-bg-red-50 cqa-text-left\"\n (click)=\"onContextDelete(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">delete_outline</mat-icon>\n <span>{{ labels.folderMenuDelete }}</span>\n </button>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n </ng-container>\n</aside>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2.SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i5.FolderDropDirective, selector: "[cqaFolderDrop]", inputs: ["cqaFolderDrop", "dropEnabled"], outputs: ["testsDropped", "folderDropped"] }, { type: i6.FolderDragDirective, selector: "[cqaFolderDrag]", inputs: ["cqaFolderDrag", "dragEnabled"] }, { type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i7.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i8.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { type: i8.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
687
+ FolderSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: FolderSidebarComponent, selector: "cqa-folder-sidebar", inputs: { folders: "folders", selectedFolderId: "selectedFolderId", expandedFolderIds: "expandedFolderIds", unorganizedCount: "unorganizedCount", allowCreate: "allowCreate", allowRename: "allowRename", allowDelete: "allowDelete", allowMove: "allowMove", allowDuplicate: "allowDuplicate", allowDrop: "allowDrop", showCounts: "showCounts", collapsed: "collapsed", foldersAccordionExpanded: "foldersAccordionExpanded", labels: "labels", serverSideSearch: "serverSideSearch", rootTotal: "rootTotal", folderSearchLoading: "folderSearchLoading", rootFoldersLoading: "rootFoldersLoading", savingFolderIds: "savingFolderIds", searchValue: "searchValue" }, outputs: { folderSelected: "folderSelected", folderExpansionToggled: "folderExpansionToggled", folderChildrenRequested: "folderChildrenRequested", folderLoadMoreRequested: "folderLoadMoreRequested", searchChange: "searchChange", rootLoadMoreRequested: "rootLoadMoreRequested", folderCreated: "folderCreated", folderCreateRequested: "folderCreateRequested", folderRenamed: "folderRenamed", folderDeleted: "folderDeleted", folderMoveRequested: "folderMoveRequested", folderDuplicateRequested: "folderDuplicateRequested", testsDropped: "testsDropped", folderDropped: "folderDropped", collapsedChange: "collapsedChange", foldersAccordionExpandedChange: "foldersAccordionExpandedChange" }, host: { listeners: { "document:click": "onDocumentClick()", "document:keydown.escape": "onEscape()", "document:dragend": "onDocumentDragEnd()" }, classAttribute: "cqa-ui-root" }, ngImport: i0, template: "<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 16\" [attr.height]=\"size || 16\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable folder icon. Render via <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: node.color }\"></ng-container>. -->\n<ng-template #folderIcon let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-4 cqa-h-4 cqa-flex-shrink-0\">\n <svg width=\"13\" height=\"12\" viewBox=\"0 0 13 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.1916 9.85824C12.1916 10.1677 12.0687 10.4644 11.8499 10.6832C11.6311 10.902 11.3343 11.0249 11.0249 11.0249H1.69157C1.38215 11.0249 1.0854 10.902 0.866611 10.6832C0.647819 10.4644 0.524902 10.1677 0.524902 9.85824V1.69157C0.524902 1.38215 0.647819 1.0854 0.866611 0.866611C1.0854 0.647819 1.38215 0.524902 1.69157 0.524902H4.60824L5.7749 2.2749H11.0249C11.3343 2.2749 11.6311 2.39782 11.8499 2.61661C12.0687 2.8354 12.1916 3.13215 12.1916 3.44157V9.85824Z\" [attr.stroke]=\"color || '#99999E'\" stroke-width=\"1.05\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<aside\n class=\"cqa-flex cqa-flex-col cqa-bg-white cqa-h-full cqa-min-h-0\"\n [class.cqa-border]=\"!collapsed\"\n [class.cqa-border-neutral-200]=\"!collapsed\"\n [class.cqa-rounded-lg]=\"!collapsed\"\n [style.width.px]=\"collapsed ? 22 : 240\"\n style=\"overflow: hidden; transition: width 260ms cubic-bezier(0.4, 0, 0.2, 1);\"\n>\n <!-- Collapsed rail: the entire sidebar becomes a single click target so the\n slim strip reads as an obvious \"expand me\" handle. -->\n <button\n *ngIf=\"collapsed\"\n type=\"button\"\n style=\"width: 22px;\"\n class=\"cqa-group cqa-flex cqa-flex-col cqa-items-center cqa-flex-shrink-0 cqa-h-full cqa-py-2 cqa-gap-3 cqa-bg-neutral-50 cqa-border cqa-border-neutral-200 cqa-text-neutral-500 hover:cqa-bg-indigo-50 hover:cqa-border-indigo-200 hover:cqa-text-indigo-600 focus:cqa-outline-none focus:cqa-ring-2 focus:cqa-ring-indigo-200 cqa-cursor-pointer\"\n (click)=\"togglePanel()\"\n [attr.aria-label]=\"'Expand folders panel'\"\n [title]=\"'Expand folders panel'\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">chevron_right</mat-icon>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"12\" viewBox=\"0 0 13 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12.1916 9.85824C12.1916 10.1677 12.0687 10.4644 11.8499 10.6832C11.6311 10.902 11.3343 11.0249 11.0249 11.0249H1.69157C1.38215 11.0249 1.0854 10.902 0.866611 10.6832C0.647819 10.4644 0.524902 10.1677 0.524902 9.85824V1.69157C0.524902 1.38215 0.647819 1.0854 0.866611 0.866611C1.0854 0.647819 1.38215 0.524902 1.69157 0.524902H4.60824L5.7749 2.2749H11.0249C11.3343 2.2749 11.6311 2.39782 11.8499 2.61661C12.0687 2.8354 12.1916 3.13215 12.1916 3.44157V9.85824Z\" stroke=\"currentColor\" stroke-width=\"1.05\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </button>\n\n <div *ngIf=\"!collapsed\" class=\"cqa-flex cqa-flex-col cqa-h-full cqa-min-h-0 cqa-pb-2\" style=\"width: 240px;\">\n <!-- Header (expanded) -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-py-1 cqa-px-3\"\n style=\"border-bottom: 1px solid #E2E2E3; margin-bottom: 8px;\"\n >\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-neutral-900 cqa-py-0.5\">{{ labels.folders }}</span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\">\n <button\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"togglePanel()\"\n [attr.aria-label]=\"'Collapse folders panel'\"\n [title]=\"'Collapse folders panel'\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">keyboard_double_arrow_left</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100\"\n [class.cqa-text-neutral-500]=\"!searchVisible\"\n [class.cqa-text-indigo-600]=\"searchVisible\"\n [class.cqa-bg-neutral-100]=\"searchVisible\"\n (click)=\"toggleSearchVisible()\"\n [attr.aria-label]=\"searchVisible ? 'Hide folder search' : 'Search folders'\"\n [attr.aria-pressed]=\"searchVisible\"\n [title]=\"searchVisible ? 'Hide folder search' : 'Search folders'\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">search</mat-icon>\n </button>\n <button\n *ngIf=\"allowCreate\"\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"requestCreate(null)\"\n [attr.aria-label]=\"labels.newFolder\"\n [title]=\"labels.newFolder\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container>\n <!-- Search (toggled via the search icon in the header) -->\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"searchVisible ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-pb-2\">\n <div class=\"cqa-relative\">\n <cqa-search-bar\n size=\"sm\"\n [fullWidth]=\"true\"\n [value]=\"searchValue\"\n [autoFocus]=\"searchVisible\"\n [placeholder]=\"labels.searchFoldersPlaceholder\"\n [showClear]=\"true\"\n (valueChange)=\"onSearchInput($event)\"\n (cleared)=\"onSearchClear()\"\n ></cqa-search-bar>\n <span\n *ngIf=\"folderSearchLoading\"\n class=\"cqa-absolute cqa-right-8 cqa-inset-y-0 cqa-flex cqa-items-center\"\n aria-live=\"polite\"\n aria-label=\"Searching folders\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Organized section header \u2014 visually distinct from folder rows so it reads\n as a view/section toggle rather than a folder item. -->\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-px-3 cqa-py-1 cqa-text-left cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE] focus:cqa-outline-none focus:cqa-text-[#3F43EE] cqa-flex-shrink-0 cqa-uppercase\"\n (click)=\"toggleFoldersAccordion()\"\n [attr.aria-expanded]=\"foldersAccordionExpanded\"\n [attr.aria-label]=\"foldersAccordionExpanded ? 'Collapse organized folders' : 'Expand organized folders'\"\n >\n <span class=\"cqa-text-[11px] cqa-font-semibold cqa-tracking-wider\">{{ labels.organized }}</span>\n <mat-icon\n style=\"font-size:16px;width:16px;height:16px;transition: transform 200ms ease;\"\n [style.transform]=\"foldersAccordionExpanded ? 'rotate(0deg)' : 'rotate(-90deg)'\"\n >expand_more</mat-icon>\n </button>\n\n <!-- Tree (folders only \u2014 Unorganized sits directly below; tree caps at 60vh and scrolls when overflowing).\n Scroll-based lazy-loading at the root level: nearing the bottom emits\n `rootLoadMoreRequested`, which the host responds to by fetching the\n next page of roots. -->\n <div\n class=\"cqa-grid cqa-min-h-0\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"foldersAccordionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div role=\"tree\" class=\"cqa-min-h-0 cqa-max-h-[40vh] cqa-overflow-y-auto cqa-py-1 cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB]\"\n (scroll)=\"onTreeScroll($event)\">\n <!-- Initial-load spinner: only renders when we have no folders yet AND\n no search active (search has its own inline spinner). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length === 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-6\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n <div\n *ngIf=\"searchValue?.trim() && rows.length === 0 && !folderSearchLoading\"\n class=\"cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-neutral-500 cqa-text-center\"\n >\n {{ labels.noFoldersFound }}\n </div>\n <ng-container *ngFor=\"let row of rows; let i = index; trackBy: trackByRow\">\n <!-- Synthetic loading row (lazy fetch in flight) -->\n <div\n *ngIf=\"row.kind === 'loading'\"\n [style.paddingLeft.px]=\"rowIndent(row.depth)\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-1.5 cqa-text-sm cqa-text-neutral-500\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>\n <span>Loading\u2026</span>\n </div>\n <!-- Synthetic load-more row (more children available on backend) -->\n <button\n *ngIf=\"row.kind === 'load-more'\"\n type=\"button\"\n [style.paddingLeft.px]=\"rowIndent(row.depth)\"\n class=\"cqa-flex cqa-items-center cqa-w-full cqa-py-1.5 cqa-text-sm cqa-text-indigo-600 hover:cqa-bg-[#D8D9FC] cqa-text-left\"\n (click)=\"onLoadMore(row.node); $event.stopPropagation()\"\n >\n <span>Load more ({{ (row.node.totalChildren ?? 0) - (row.node.children?.length ?? 0) }})</span>\n </button>\n <!-- Real folder row -->\n <div\n *ngIf=\"row.kind === 'folder'\"\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"row.hasChildren ? isExpanded(row.node.id) : null\"\n [attr.aria-selected]=\"isSelected(row.node.id)\"\n [attr.data-folder-row-id]=\"row.node.id\"\n [cqaFolderDrop]=\"row.node.id\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(row.node.id, $event)\"\n (folderDropped)=\"onFolderRowDropped(row.node.id, $event)\"\n [cqaFolderDrag]=\"row.node.id\"\n [dragEnabled]=\"allowDrop\"\n (dragstart)=\"onFolderDragStart(row.node)\"\n (dragend)=\"onFolderDragEnd()\"\n (dragover)=\"onFolderRowDragOver(row)\"\n (dragleave)=\"onFolderRowDragLeave(row)\"\n (click)=\"onSelect(row.node)\"\n (contextmenu)=\"openContextMenu(row.node, $event)\"\n (keydown)=\"onRowKeydown($event, row, i)\"\n class=\"cqa-group cqa-flex cqa-items-center cqa-gap-1 cqa-pr-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-[#D8D9FC] focus:cqa-outline-none focus:cqa-bg-[#D8D9FC] cqa-relative\"\n [style.background-color]=\"(isSelected(row.node.id) || contextMenuFolderId === row.node.id) ? '#D8D9FC' : null\"\n [style.paddingLeft.px]=\"rowIndent(row.depth)\"\n [attr.title]=\"folderRowTooltip(row.node)\"\n >\n <span\n *ngIf=\"isSelected(row.node.id)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <button\n type=\"button\"\n class=\"cqa-p-0\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [style.visibility]=\"row.hasChildren ? 'visible' : 'hidden'\"\n (click)=\"onToggle(row.node, $event)\"\n [attr.aria-label]=\"isExpanded(row.node.id) ? 'Collapse' : 'Expand'\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">\n {{ isExpanded(row.node.id) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: row.node.color }\"></ng-container>\n\n <ng-container *ngIf=\"renamingId === row.node.id; else nameTpl\">\n <input\n type=\"text\"\n size=\"1\"\n [attr.data-folder-rename-input]=\"row.node.id\"\n [attr.maxlength]=\"renameMaxLength\"\n class=\"cqa-flex-1 cqa-min-w-0 cqa-w-full cqa-px-2 cqa-py-0.5 cqa-rounded cqa-border cqa-bg-white cqa-text-sm cqa-shadow-sm focus:cqa-outline-none focus:cqa-ring-1\"\n [ngClass]=\"(isRenameDraftValid && !renameLimitFlash)\n ? 'cqa-border-neutral-300 focus:cqa-border-indigo-400 focus:cqa-ring-indigo-200'\n : 'cqa-border-[#EF4444] focus:cqa-border-[#EF4444] focus:cqa-ring-[#FCA5A5]'\"\n [attr.aria-invalid]=\"!isRenameDraftValid || renameLimitFlash\"\n [(ngModel)]=\"renameDraft\"\n (keydown)=\"onRenameKey($event, row.node)\"\n (keypress)=\"$event.stopPropagation()\"\n (keyup)=\"$event.stopPropagation()\"\n (blur)=\"commitRename(row.node)\"\n (click)=\"$event.stopPropagation()\"\n />\n </ng-container>\n <ng-template #nameTpl>\n <span\n class=\"cqa-flex-1 cqa-text-sm cqa-truncate\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n (dblclick)=\"beginRename(row.node, $event)\"\n >{{ row.node.name }}</span>\n </ng-template>\n\n <!-- Saving indicator: replaces the count while the host's rename/save\n API call is in flight, so the user gets immediate feedback. -->\n <span\n *ngIf=\"isFolderSaving(row.node.id)\"\n class=\"cqa-flex cqa-items-center cqa-ml-1 cqa-flex-shrink-0\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Saving ' + row.node.name\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 12 }\"></ng-container>\n </span>\n\n <!-- Count shown at rest; hidden on row hover when delete is allowed -->\n <span\n *ngIf=\"!isFolderSaving(row.node.id) && showCounts && row.node.count != null\"\n class=\"cqa-text-xs cqa-tabular-nums cqa-ml-1\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [class.group-hover:cqa-hidden]=\"allowDelete\"\n >{{ row.node.count }}</span>\n\n <button\n *ngIf=\"hasAnyContextAction\"\n type=\"button\"\n class=\"cqa-p-0.5 cqa-rounded hover:cqa-bg-neutral-200\"\n [style.color]=\"isSelected(row.node.id) || contextMenuFolderId === row.node.id ? '#3F43EE' : '#4C4C51'\"\n [class.cqa-hidden]=\"contextMenuFolderId !== row.node.id\"\n [class.group-hover:cqa-inline-flex]=\"true\"\n [class.cqa-inline-flex]=\"contextMenuFolderId === row.node.id\"\n (click)=\"openContextMenu(row.node, $event)\"\n [attr.aria-label]=\"'Open actions for ' + row.node.name\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"contextMenuFolderId === row.node.id\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">more_horiz</mat-icon>\n </button>\n </div>\n </ng-container>\n <!-- Root-level pagination is now driven by scroll (see `(scroll)` on the\n tree container above). Per-folder children retain the explicit\n \"Load more\" button rendered inside the rows loop above, since\n subtrees aren't independently scrollable. -->\n <!-- Pagination spinner \u2014 visible only when fetching an additional page\n of roots (folders.length > 0 distinguishes from initial-load case). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length > 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-2\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Divider between folder tree and pinned Unorganized tab -->\n <div\n aria-hidden=\"true\"\n class=\"cqa-mx-3 cqa-flex-shrink-0\"\n style=\"height: 1px; background-color: #E5E7EB; margin-top: 6px; margin-bottom: 6px;\"\n ></div>\n\n <!-- Unorganized \u2014 pinned below the scrollable folder tree so it stays visible regardless of folder count -->\n <div\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(null)\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-px-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-[#D8D9FC] focus:cqa-outline-none focus:cqa-bg-[#D8D9FC] cqa-relative cqa-flex-shrink-0\"\n [style.background-color]=\"isSelected(null) ? '#D8D9FC' : null\"\n [cqaFolderDrop]=\"null\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(null, $event)\"\n (folderDropped)=\"onFolderRowDropped(null, $event)\"\n (click)=\"onSelectUnorganized()\"\n >\n <span\n *ngIf=\"isSelected(null)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <mat-icon [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <span class=\"cqa-flex-1 cqa-text-sm\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ labels.unorganized }}</span>\n <span *ngIf=\"showCounts\" class=\"cqa-text-xs cqa-tabular-nums\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ unorganizedCount }}</span>\n </div>\n\n <!-- Folder context menu (right-click / ellipsis). A 0\u00D70 fixed-position\n anchor at the click coords drives a cdkConnectedOverlay; CDK's\n flexible-connected positioning auto-flips up/left when the menu\n would overflow the viewport (last-folder-near-bottom case). -->\n <div #ctxAnchor cdkOverlayOrigin\n class=\"cqa-fixed cqa-w-0 cqa-h-0 cqa-pointer-events-none\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"></div>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"ctxAnchor\"\n [cdkConnectedOverlayOpen]=\"contextMenuFolderId !== null\"\n [cdkConnectedOverlayPositions]=\"contextMenuPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n (overlayOutsideClick)=\"onOverlayOutsideClick()\"\n (detach)=\"closeContextMenu()\"\n >\n <!-- The lib's tailwind config sets important: '.cqa-ui-root', which\n emits descendant selectors like `.cqa-ui-root .cqa-bg-white`.\n CDK Overlay teleports this template into the global overlay\n container (outside the host's cqa-ui-root), so we wrap the menu in\n an ancestor cqa-ui-root div to re-establish the utility scope. -->\n <div class=\"cqa-ui-root\">\n <div\n role=\"menu\"\n class=\"cqa-min-w-[180px] cqa-bg-white cqa-border cqa-border-neutral-200 cqa-rounded-md cqa-shadow-lg cqa-py-1\"\n (click)=\"$event.stopPropagation()\"\n (contextmenu)=\"$event.preventDefault(); $event.stopPropagation()\"\n >\n <ng-container *ngIf=\"folderById(contextMenuFolderId) as menuNode\">\n <button\n *ngIf=\"allowCreate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextCreateSubfolder(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">create_new_folder</mat-icon>\n <span>{{ labels.folderMenuCreateSubfolder }}</span>\n </button>\n <button\n *ngIf=\"allowRename\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextRename(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">edit</mat-icon>\n <span>{{ labels.folderMenuRename }}</span>\n </button>\n <button\n *ngIf=\"allowMove\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextMove(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">drive_file_move</mat-icon>\n <span>{{ labels.folderMenuMove }}</span>\n </button>\n <button\n *ngIf=\"allowDuplicate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextDuplicate(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">content_copy</mat-icon>\n <span>{{ labels.folderMenuDuplicate }}</span>\n </button>\n <div *ngIf=\"allowDelete && (allowCreate || allowRename || allowMove || allowDuplicate)\" class=\"cqa-h-px cqa-bg-neutral-200 cqa-my-1\"></div>\n <button\n *ngIf=\"allowDelete\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-red-600 hover:cqa-bg-red-50 cqa-text-left\"\n (click)=\"onContextDelete(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">delete_outline</mat-icon>\n <span>{{ labels.folderMenuDelete }}</span>\n </button>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n </ng-container>\n </div>\n</aside>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2.SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.FolderDropDirective, selector: "[cqaFolderDrop]", inputs: ["cqaFolderDrop", "dropEnabled"], outputs: ["testsDropped", "folderDropped"] }, { type: i5.FolderDragDirective, selector: "[cqaFolderDrag]", inputs: ["cqaFolderDrag", "dragEnabled"] }, { type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i6.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i7.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { type: i7.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
635
688
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: FolderSidebarComponent, decorators: [{
636
689
  type: Component,
637
- args: [{ selector: 'cqa-folder-sidebar', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Reusable folder icon. Render via <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: node.color }\"></ng-container>. -->\n<ng-template #folderIcon let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-4 cqa-h-4 cqa-shrink-0\">\n <svg width=\"13\" height=\"12\" viewBox=\"0 0 13 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.1916 9.85824C12.1916 10.1677 12.0687 10.4644 11.8499 10.6832C11.6311 10.902 11.3343 11.0249 11.0249 11.0249H1.69157C1.38215 11.0249 1.0854 10.902 0.866611 10.6832C0.647819 10.4644 0.524902 10.1677 0.524902 9.85824V1.69157C0.524902 1.38215 0.647819 1.0854 0.866611 0.866611C1.0854 0.647819 1.38215 0.524902 1.69157 0.524902H4.60824L5.7749 2.2749H11.0249C11.3343 2.2749 11.6311 2.39782 11.8499 2.61661C12.0687 2.8354 12.1916 3.13215 12.1916 3.44157V9.85824Z\" [attr.stroke]=\"color || '#99999E'\" stroke-width=\"1.05\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<aside\n class=\"cqa-flex cqa-flex-col cqa-bg-white cqa-border cqa-border-neutral-200 cqa-rounded-lg cqa-h-full cqa-min-h-0\"\n [class.cqa-w-[240px]]=\"!collapsed\"\n [class.cqa-w-[48px]]=\"collapsed\"\n style=\"transition: width 150ms ease;\"\n>\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-3 cqa-py-1\"\n [style.border-bottom]=\"collapsed ? null : '1px solid #E2E2E3'\"\n [style.margin-bottom.px]=\"collapsed ? 0 : 8\"\n >\n <span *ngIf=\"!collapsed\" class=\"cqa-text-sm cqa-font-semibold cqa-text-neutral-900\">\n {{ labels.folders }}\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\" [class.cqa-w-full]=\"collapsed\" [class.cqa-justify-center]=\"collapsed\">\n <button\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"togglePanel()\"\n [attr.aria-label]=\"collapsed ? 'Expand folders panel' : 'Collapse folders panel'\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">\n {{ collapsed ? 'chevron_right' : 'keyboard_double_arrow_left' }}\n </mat-icon>\n </button>\n <button\n *ngIf=\"!collapsed && allowCreate\"\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"requestCreate(null)\"\n [attr.aria-label]=\"labels.newFolder\"\n [title]=\"labels.newFolder\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"!collapsed\">\n <!-- Search -->\n <div class=\"cqa-px-3 cqa-pb-2\">\n <div class=\"cqa-relative\">\n <cqa-search-bar\n size=\"sm\"\n [fullWidth]=\"true\"\n [value]=\"searchValue\"\n [placeholder]=\"labels.searchFoldersPlaceholder\"\n [showClear]=\"true\"\n (valueChange)=\"onSearchInput($event)\"\n (cleared)=\"onSearchClear()\"\n ></cqa-search-bar>\n <span\n *ngIf=\"folderSearchLoading\"\n class=\"cqa-absolute cqa-right-8 cqa-inset-y-0 cqa-flex cqa-items-center\"\n aria-live=\"polite\"\n aria-label=\"Searching folders\"\n >\n <mat-spinner diameter=\"14\" mode=\"indeterminate\"></mat-spinner>\n </span>\n </div>\n </div>\n\n <!-- Tree (folders only \u2014 Unorganized sits directly below; tree caps at 60vh and scrolls when overflowing).\n Scroll-based lazy-loading at the root level: nearing the bottom emits\n `rootLoadMoreRequested`, which the host responds to by fetching the\n next page of roots. -->\n <div role=\"tree\" class=\"cqa-min-h-0 cqa-max-h-[60vh] cqa-overflow-y-auto cqa-py-1 cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB]\"\n (scroll)=\"onTreeScroll($event)\">\n <!-- Initial-load spinner: only renders when we have no folders yet AND\n no search active (search has its own inline spinner). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length === 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-6\"\n aria-live=\"polite\"\n >\n <mat-spinner diameter=\"20\" mode=\"indeterminate\"></mat-spinner>\n </div>\n <div\n *ngIf=\"searchValue?.trim() && rows.length === 0 && !folderSearchLoading\"\n class=\"cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-neutral-500 cqa-text-center\"\n >\n {{ labels.noFoldersFound }}\n </div>\n <ng-container *ngFor=\"let row of rows; let i = index; trackBy: trackByRow\">\n <!-- Synthetic loading row (lazy fetch in flight) -->\n <div\n *ngIf=\"row.kind === 'loading'\"\n [style.paddingLeft.px]=\"8 + row.depth * 16\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-1.5 cqa-text-sm cqa-text-neutral-500\"\n aria-live=\"polite\"\n >\n <mat-spinner diameter=\"14\" mode=\"indeterminate\"></mat-spinner>\n <span>Loading\u2026</span>\n </div>\n <!-- Synthetic load-more row (more children available on backend) -->\n <button\n *ngIf=\"row.kind === 'load-more'\"\n type=\"button\"\n [style.paddingLeft.px]=\"8 + row.depth * 16\"\n class=\"cqa-flex cqa-items-center cqa-w-full cqa-py-1.5 cqa-text-sm cqa-text-indigo-600 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onLoadMore(row.node); $event.stopPropagation()\"\n >\n <span>Load more ({{ (row.node.totalChildren ?? 0) - (row.node.children?.length ?? 0) }})</span>\n </button>\n <!-- Real folder row -->\n <div\n *ngIf=\"row.kind === 'folder'\"\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"row.hasChildren ? isExpanded(row.node.id) : null\"\n [attr.aria-selected]=\"isSelected(row.node.id)\"\n [attr.data-folder-row-id]=\"row.node.id\"\n [cqaFolderDrop]=\"row.node.id\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(row.node.id, $event)\"\n (folderDropped)=\"onFolderRowDropped(row.node.id, $event)\"\n [cqaFolderDrag]=\"row.node.id\"\n [dragEnabled]=\"allowDrop\"\n (dragstart)=\"onFolderDragStart(row.node)\"\n (dragend)=\"onFolderDragEnd()\"\n (dragover)=\"onFolderRowDragOver(row)\"\n (dragleave)=\"onFolderRowDragLeave(row)\"\n (click)=\"onSelect(row.node)\"\n (contextmenu)=\"openContextMenu(row.node, $event)\"\n (keydown)=\"onRowKeydown($event, row, i)\"\n class=\"cqa-group cqa-flex cqa-items-center cqa-gap-1 cqa-pr-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-indigo-50 focus:cqa-outline-none focus:cqa-bg-indigo-50 cqa-relative\"\n [class.cqa-bg-indigo-50]=\"isSelected(row.node.id) || contextMenuFolderId === row.node.id\"\n [style.paddingLeft.px]=\"8 + row.depth * 16\"\n [attr.title]=\"row.node.totalCount != null ? (row.node.totalCount + ' total including subfolders') : null\"\n >\n <span\n *ngIf=\"isSelected(row.node.id)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <button\n type=\"button\"\n class=\"cqa-p-0\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [style.visibility]=\"row.hasChildren ? 'visible' : 'hidden'\"\n (click)=\"onToggle(row.node, $event)\"\n [attr.aria-label]=\"isExpanded(row.node.id) ? 'Collapse' : 'Expand'\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">\n {{ isExpanded(row.node.id) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: row.node.color }\"></ng-container>\n\n <ng-container *ngIf=\"renamingId === row.node.id; else nameTpl\">\n <input\n type=\"text\"\n size=\"1\"\n [attr.data-folder-rename-input]=\"row.node.id\"\n [attr.maxlength]=\"renameMaxLength\"\n class=\"cqa-flex-1 cqa-min-w-0 cqa-w-full cqa-px-2 cqa-py-0.5 cqa-rounded cqa-border cqa-bg-white cqa-text-sm cqa-shadow-sm focus:cqa-outline-none focus:cqa-ring-1\"\n [ngClass]=\"(isRenameDraftValid && !renameLimitFlash)\n ? 'cqa-border-neutral-300 focus:cqa-border-indigo-400 focus:cqa-ring-indigo-200'\n : 'cqa-border-[#EF4444] focus:cqa-border-[#EF4444] focus:cqa-ring-[#FCA5A5]'\"\n [attr.aria-invalid]=\"!isRenameDraftValid || renameLimitFlash\"\n [(ngModel)]=\"renameDraft\"\n (keydown)=\"onRenameKey($event, row.node)\"\n (keypress)=\"$event.stopPropagation()\"\n (keyup)=\"$event.stopPropagation()\"\n (blur)=\"commitRename(row.node)\"\n (click)=\"$event.stopPropagation()\"\n />\n </ng-container>\n <ng-template #nameTpl>\n <span\n class=\"cqa-flex-1 cqa-text-sm cqa-truncate\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n (dblclick)=\"beginRename(row.node, $event)\"\n >{{ row.node.name }}</span>\n </ng-template>\n\n <!-- Count shown at rest; hidden on row hover when delete is allowed -->\n <span\n *ngIf=\"showCounts && row.node.count != null\"\n class=\"cqa-text-xs cqa-tabular-nums cqa-ml-1\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [class.group-hover:cqa-hidden]=\"allowDelete\"\n >{{ row.node.count }}</span>\n\n <button\n *ngIf=\"hasAnyContextAction\"\n type=\"button\"\n class=\"cqa-p-0.5 cqa-rounded hover:cqa-bg-neutral-200\"\n [style.color]=\"isSelected(row.node.id) || contextMenuFolderId === row.node.id ? '#3F43EE' : '#4C4C51'\"\n [class.cqa-hidden]=\"contextMenuFolderId !== row.node.id\"\n [class.group-hover:cqa-inline-flex]=\"true\"\n [class.cqa-inline-flex]=\"contextMenuFolderId === row.node.id\"\n (click)=\"openContextMenu(row.node, $event)\"\n [attr.aria-label]=\"'Open actions for ' + row.node.name\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"contextMenuFolderId === row.node.id\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">more_horiz</mat-icon>\n </button>\n </div>\n </ng-container>\n <!-- Root-level pagination is now driven by scroll (see `(scroll)` on the\n tree container above). Per-folder children retain the explicit\n \"Load more\" button rendered inside the rows loop above, since\n subtrees aren't independently scrollable. -->\n <!-- Pagination spinner \u2014 visible only when fetching an additional page\n of roots (folders.length > 0 distinguishes from initial-load case). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length > 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-2\"\n aria-live=\"polite\"\n >\n <mat-spinner diameter=\"14\" mode=\"indeterminate\"></mat-spinner>\n </div>\n </div>\n\n <!-- Divider between folder tree and pinned Unorganized tab -->\n <div\n aria-hidden=\"true\"\n class=\"cqa-mx-3 cqa-shrink-0\"\n style=\"height: 1px; background-color: #E5E7EB; margin-top: 6px; margin-bottom: 6px;\"\n ></div>\n\n <!-- Unorganized \u2014 pinned below the scrollable folder tree so it stays visible regardless of folder count -->\n <div\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(null)\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-px-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-indigo-50 focus:cqa-outline-none focus:cqa-bg-indigo-50 cqa-relative cqa-shrink-0\"\n [class.cqa-bg-indigo-50]=\"isSelected(null)\"\n [cqaFolderDrop]=\"null\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(null, $event)\"\n (folderDropped)=\"onFolderRowDropped(null, $event)\"\n (click)=\"onSelectUnorganized()\"\n >\n <span\n *ngIf=\"isSelected(null)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <mat-icon [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <span class=\"cqa-flex-1 cqa-text-sm\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ labels.unorganized }}</span>\n <span *ngIf=\"showCounts\" class=\"cqa-text-xs cqa-tabular-nums\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ unorganizedCount }}</span>\n </div>\n\n <!-- Folder context menu (right-click / ellipsis). A 0\u00D70 fixed-position\n anchor at the click coords drives a cdkConnectedOverlay; CDK's\n flexible-connected positioning auto-flips up/left when the menu\n would overflow the viewport (last-folder-near-bottom case). -->\n <div #ctxAnchor cdkOverlayOrigin\n class=\"cqa-fixed cqa-w-0 cqa-h-0 cqa-pointer-events-none\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"></div>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"ctxAnchor\"\n [cdkConnectedOverlayOpen]=\"contextMenuFolderId !== null\"\n [cdkConnectedOverlayPositions]=\"contextMenuPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n (overlayOutsideClick)=\"onOverlayOutsideClick()\"\n (detach)=\"closeContextMenu()\"\n >\n <!-- The lib's tailwind config sets important: '.cqa-ui-root', which\n emits descendant selectors like `.cqa-ui-root .cqa-bg-white`.\n CDK Overlay teleports this template into the global overlay\n container (outside the host's cqa-ui-root), so we wrap the menu in\n an ancestor cqa-ui-root div to re-establish the utility scope. -->\n <div class=\"cqa-ui-root\">\n <div\n role=\"menu\"\n class=\"cqa-min-w-[180px] cqa-bg-white cqa-border cqa-border-neutral-200 cqa-rounded-md cqa-shadow-lg cqa-py-1\"\n (click)=\"$event.stopPropagation()\"\n (contextmenu)=\"$event.preventDefault(); $event.stopPropagation()\"\n >\n <ng-container *ngIf=\"folderById(contextMenuFolderId) as menuNode\">\n <button\n *ngIf=\"allowCreate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextCreateSubfolder(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">create_new_folder</mat-icon>\n <span>{{ labels.folderMenuCreateSubfolder }}</span>\n </button>\n <button\n *ngIf=\"allowRename\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextRename(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">edit</mat-icon>\n <span>{{ labels.folderMenuRename }}</span>\n </button>\n <button\n *ngIf=\"allowMove\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextMove(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">drive_file_move</mat-icon>\n <span>{{ labels.folderMenuMove }}</span>\n </button>\n <button\n *ngIf=\"allowDuplicate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextDuplicate(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">content_copy</mat-icon>\n <span>{{ labels.folderMenuDuplicate }}</span>\n </button>\n <div *ngIf=\"allowDelete && (allowCreate || allowRename || allowMove || allowDuplicate)\" class=\"cqa-h-px cqa-bg-neutral-200 cqa-my-1\"></div>\n <button\n *ngIf=\"allowDelete\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-red-600 hover:cqa-bg-red-50 cqa-text-left\"\n (click)=\"onContextDelete(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">delete_outline</mat-icon>\n <span>{{ labels.folderMenuDelete }}</span>\n </button>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n </ng-container>\n</aside>\n", styles: [] }]
690
+ args: [{ selector: 'cqa-folder-sidebar', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 16\" [attr.height]=\"size || 16\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable folder icon. Render via <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: node.color }\"></ng-container>. -->\n<ng-template #folderIcon let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-4 cqa-h-4 cqa-flex-shrink-0\">\n <svg width=\"13\" height=\"12\" viewBox=\"0 0 13 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.1916 9.85824C12.1916 10.1677 12.0687 10.4644 11.8499 10.6832C11.6311 10.902 11.3343 11.0249 11.0249 11.0249H1.69157C1.38215 11.0249 1.0854 10.902 0.866611 10.6832C0.647819 10.4644 0.524902 10.1677 0.524902 9.85824V1.69157C0.524902 1.38215 0.647819 1.0854 0.866611 0.866611C1.0854 0.647819 1.38215 0.524902 1.69157 0.524902H4.60824L5.7749 2.2749H11.0249C11.3343 2.2749 11.6311 2.39782 11.8499 2.61661C12.0687 2.8354 12.1916 3.13215 12.1916 3.44157V9.85824Z\" [attr.stroke]=\"color || '#99999E'\" stroke-width=\"1.05\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<aside\n class=\"cqa-flex cqa-flex-col cqa-bg-white cqa-h-full cqa-min-h-0\"\n [class.cqa-border]=\"!collapsed\"\n [class.cqa-border-neutral-200]=\"!collapsed\"\n [class.cqa-rounded-lg]=\"!collapsed\"\n [style.width.px]=\"collapsed ? 22 : 240\"\n style=\"overflow: hidden; transition: width 260ms cubic-bezier(0.4, 0, 0.2, 1);\"\n>\n <!-- Collapsed rail: the entire sidebar becomes a single click target so the\n slim strip reads as an obvious \"expand me\" handle. -->\n <button\n *ngIf=\"collapsed\"\n type=\"button\"\n style=\"width: 22px;\"\n class=\"cqa-group cqa-flex cqa-flex-col cqa-items-center cqa-flex-shrink-0 cqa-h-full cqa-py-2 cqa-gap-3 cqa-bg-neutral-50 cqa-border cqa-border-neutral-200 cqa-text-neutral-500 hover:cqa-bg-indigo-50 hover:cqa-border-indigo-200 hover:cqa-text-indigo-600 focus:cqa-outline-none focus:cqa-ring-2 focus:cqa-ring-indigo-200 cqa-cursor-pointer\"\n (click)=\"togglePanel()\"\n [attr.aria-label]=\"'Expand folders panel'\"\n [title]=\"'Expand folders panel'\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">chevron_right</mat-icon>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"12\" viewBox=\"0 0 13 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12.1916 9.85824C12.1916 10.1677 12.0687 10.4644 11.8499 10.6832C11.6311 10.902 11.3343 11.0249 11.0249 11.0249H1.69157C1.38215 11.0249 1.0854 10.902 0.866611 10.6832C0.647819 10.4644 0.524902 10.1677 0.524902 9.85824V1.69157C0.524902 1.38215 0.647819 1.0854 0.866611 0.866611C1.0854 0.647819 1.38215 0.524902 1.69157 0.524902H4.60824L5.7749 2.2749H11.0249C11.3343 2.2749 11.6311 2.39782 11.8499 2.61661C12.0687 2.8354 12.1916 3.13215 12.1916 3.44157V9.85824Z\" stroke=\"currentColor\" stroke-width=\"1.05\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </button>\n\n <div *ngIf=\"!collapsed\" class=\"cqa-flex cqa-flex-col cqa-h-full cqa-min-h-0 cqa-pb-2\" style=\"width: 240px;\">\n <!-- Header (expanded) -->\n <div\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-py-1 cqa-px-3\"\n style=\"border-bottom: 1px solid #E2E2E3; margin-bottom: 8px;\"\n >\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-neutral-900 cqa-py-0.5\">{{ labels.folders }}</span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\">\n <button\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"togglePanel()\"\n [attr.aria-label]=\"'Collapse folders panel'\"\n [title]=\"'Collapse folders panel'\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">keyboard_double_arrow_left</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100\"\n [class.cqa-text-neutral-500]=\"!searchVisible\"\n [class.cqa-text-indigo-600]=\"searchVisible\"\n [class.cqa-bg-neutral-100]=\"searchVisible\"\n (click)=\"toggleSearchVisible()\"\n [attr.aria-label]=\"searchVisible ? 'Hide folder search' : 'Search folders'\"\n [attr.aria-pressed]=\"searchVisible\"\n [title]=\"searchVisible ? 'Hide folder search' : 'Search folders'\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">search</mat-icon>\n </button>\n <button\n *ngIf=\"allowCreate\"\n type=\"button\"\n class=\"cqa-p-1 cqa-rounded hover:cqa-bg-neutral-100 cqa-text-neutral-500\"\n (click)=\"requestCreate(null)\"\n [attr.aria-label]=\"labels.newFolder\"\n [title]=\"labels.newFolder\"\n >\n <mat-icon style=\"font-size:18px;width:18px;height:18px\">add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container>\n <!-- Search (toggled via the search icon in the header) -->\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"searchVisible ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-pb-2\">\n <div class=\"cqa-relative\">\n <cqa-search-bar\n size=\"sm\"\n [fullWidth]=\"true\"\n [value]=\"searchValue\"\n [autoFocus]=\"searchVisible\"\n [placeholder]=\"labels.searchFoldersPlaceholder\"\n [showClear]=\"true\"\n (valueChange)=\"onSearchInput($event)\"\n (cleared)=\"onSearchClear()\"\n ></cqa-search-bar>\n <span\n *ngIf=\"folderSearchLoading\"\n class=\"cqa-absolute cqa-right-8 cqa-inset-y-0 cqa-flex cqa-items-center\"\n aria-live=\"polite\"\n aria-label=\"Searching folders\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Organized section header \u2014 visually distinct from folder rows so it reads\n as a view/section toggle rather than a folder item. -->\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-w-full cqa-px-3 cqa-py-1 cqa-text-left cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE] focus:cqa-outline-none focus:cqa-text-[#3F43EE] cqa-flex-shrink-0 cqa-uppercase\"\n (click)=\"toggleFoldersAccordion()\"\n [attr.aria-expanded]=\"foldersAccordionExpanded\"\n [attr.aria-label]=\"foldersAccordionExpanded ? 'Collapse organized folders' : 'Expand organized folders'\"\n >\n <span class=\"cqa-text-[11px] cqa-font-semibold cqa-tracking-wider\">{{ labels.organized }}</span>\n <mat-icon\n style=\"font-size:16px;width:16px;height:16px;transition: transform 200ms ease;\"\n [style.transform]=\"foldersAccordionExpanded ? 'rotate(0deg)' : 'rotate(-90deg)'\"\n >expand_more</mat-icon>\n </button>\n\n <!-- Tree (folders only \u2014 Unorganized sits directly below; tree caps at 60vh and scrolls when overflowing).\n Scroll-based lazy-loading at the root level: nearing the bottom emits\n `rootLoadMoreRequested`, which the host responds to by fetching the\n next page of roots. -->\n <div\n class=\"cqa-grid cqa-min-h-0\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"foldersAccordionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div role=\"tree\" class=\"cqa-min-h-0 cqa-max-h-[40vh] cqa-overflow-y-auto cqa-py-1 cqa-scrollbar-thin cqa-scrollbar-track-transparent cqa-scrollbar-thumb-[#E5E7EB] cqa-scrollbar-thumb-rounded-full cqa-scrollbar-thumb-hover:cqa-bg-[#D1D5DB]\"\n (scroll)=\"onTreeScroll($event)\">\n <!-- Initial-load spinner: only renders when we have no folders yet AND\n no search active (search has its own inline spinner). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length === 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-6\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n <div\n *ngIf=\"searchValue?.trim() && rows.length === 0 && !folderSearchLoading\"\n class=\"cqa-px-3 cqa-py-2 cqa-text-sm cqa-text-neutral-500 cqa-text-center\"\n >\n {{ labels.noFoldersFound }}\n </div>\n <ng-container *ngFor=\"let row of rows; let i = index; trackBy: trackByRow\">\n <!-- Synthetic loading row (lazy fetch in flight) -->\n <div\n *ngIf=\"row.kind === 'loading'\"\n [style.paddingLeft.px]=\"rowIndent(row.depth)\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-1.5 cqa-text-sm cqa-text-neutral-500\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>\n <span>Loading\u2026</span>\n </div>\n <!-- Synthetic load-more row (more children available on backend) -->\n <button\n *ngIf=\"row.kind === 'load-more'\"\n type=\"button\"\n [style.paddingLeft.px]=\"rowIndent(row.depth)\"\n class=\"cqa-flex cqa-items-center cqa-w-full cqa-py-1.5 cqa-text-sm cqa-text-indigo-600 hover:cqa-bg-[#D8D9FC] cqa-text-left\"\n (click)=\"onLoadMore(row.node); $event.stopPropagation()\"\n >\n <span>Load more ({{ (row.node.totalChildren ?? 0) - (row.node.children?.length ?? 0) }})</span>\n </button>\n <!-- Real folder row -->\n <div\n *ngIf=\"row.kind === 'folder'\"\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-expanded]=\"row.hasChildren ? isExpanded(row.node.id) : null\"\n [attr.aria-selected]=\"isSelected(row.node.id)\"\n [attr.data-folder-row-id]=\"row.node.id\"\n [cqaFolderDrop]=\"row.node.id\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(row.node.id, $event)\"\n (folderDropped)=\"onFolderRowDropped(row.node.id, $event)\"\n [cqaFolderDrag]=\"row.node.id\"\n [dragEnabled]=\"allowDrop\"\n (dragstart)=\"onFolderDragStart(row.node)\"\n (dragend)=\"onFolderDragEnd()\"\n (dragover)=\"onFolderRowDragOver(row)\"\n (dragleave)=\"onFolderRowDragLeave(row)\"\n (click)=\"onSelect(row.node)\"\n (contextmenu)=\"openContextMenu(row.node, $event)\"\n (keydown)=\"onRowKeydown($event, row, i)\"\n class=\"cqa-group cqa-flex cqa-items-center cqa-gap-1 cqa-pr-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-[#D8D9FC] focus:cqa-outline-none focus:cqa-bg-[#D8D9FC] cqa-relative\"\n [style.background-color]=\"(isSelected(row.node.id) || contextMenuFolderId === row.node.id) ? '#D8D9FC' : null\"\n [style.paddingLeft.px]=\"rowIndent(row.depth)\"\n [attr.title]=\"folderRowTooltip(row.node)\"\n >\n <span\n *ngIf=\"isSelected(row.node.id)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <button\n type=\"button\"\n class=\"cqa-p-0\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [style.visibility]=\"row.hasChildren ? 'visible' : 'hidden'\"\n (click)=\"onToggle(row.node, $event)\"\n [attr.aria-label]=\"isExpanded(row.node.id) ? 'Collapse' : 'Expand'\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">\n {{ isExpanded(row.node.id) ? 'expand_more' : 'chevron_right' }}\n </mat-icon>\n </button>\n <ng-container *ngTemplateOutlet=\"folderIcon; context: { color: row.node.color }\"></ng-container>\n\n <ng-container *ngIf=\"renamingId === row.node.id; else nameTpl\">\n <input\n type=\"text\"\n size=\"1\"\n [attr.data-folder-rename-input]=\"row.node.id\"\n [attr.maxlength]=\"renameMaxLength\"\n class=\"cqa-flex-1 cqa-min-w-0 cqa-w-full cqa-px-2 cqa-py-0.5 cqa-rounded cqa-border cqa-bg-white cqa-text-sm cqa-shadow-sm focus:cqa-outline-none focus:cqa-ring-1\"\n [ngClass]=\"(isRenameDraftValid && !renameLimitFlash)\n ? 'cqa-border-neutral-300 focus:cqa-border-indigo-400 focus:cqa-ring-indigo-200'\n : 'cqa-border-[#EF4444] focus:cqa-border-[#EF4444] focus:cqa-ring-[#FCA5A5]'\"\n [attr.aria-invalid]=\"!isRenameDraftValid || renameLimitFlash\"\n [(ngModel)]=\"renameDraft\"\n (keydown)=\"onRenameKey($event, row.node)\"\n (keypress)=\"$event.stopPropagation()\"\n (keyup)=\"$event.stopPropagation()\"\n (blur)=\"commitRename(row.node)\"\n (click)=\"$event.stopPropagation()\"\n />\n </ng-container>\n <ng-template #nameTpl>\n <span\n class=\"cqa-flex-1 cqa-text-sm cqa-truncate\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n (dblclick)=\"beginRename(row.node, $event)\"\n >{{ row.node.name }}</span>\n </ng-template>\n\n <!-- Saving indicator: replaces the count while the host's rename/save\n API call is in flight, so the user gets immediate feedback. -->\n <span\n *ngIf=\"isFolderSaving(row.node.id)\"\n class=\"cqa-flex cqa-items-center cqa-ml-1 cqa-flex-shrink-0\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Saving ' + row.node.name\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 12 }\"></ng-container>\n </span>\n\n <!-- Count shown at rest; hidden on row hover when delete is allowed -->\n <span\n *ngIf=\"!isFolderSaving(row.node.id) && showCounts && row.node.count != null\"\n class=\"cqa-text-xs cqa-tabular-nums cqa-ml-1\"\n [style.color]=\"isSelected(row.node.id) ? '#3F43EE' : '#4C4C51'\"\n [class.group-hover:cqa-hidden]=\"allowDelete\"\n >{{ row.node.count }}</span>\n\n <button\n *ngIf=\"hasAnyContextAction\"\n type=\"button\"\n class=\"cqa-p-0.5 cqa-rounded hover:cqa-bg-neutral-200\"\n [style.color]=\"isSelected(row.node.id) || contextMenuFolderId === row.node.id ? '#3F43EE' : '#4C4C51'\"\n [class.cqa-hidden]=\"contextMenuFolderId !== row.node.id\"\n [class.group-hover:cqa-inline-flex]=\"true\"\n [class.cqa-inline-flex]=\"contextMenuFolderId === row.node.id\"\n (click)=\"openContextMenu(row.node, $event)\"\n [attr.aria-label]=\"'Open actions for ' + row.node.name\"\n [attr.aria-haspopup]=\"'menu'\"\n [attr.aria-expanded]=\"contextMenuFolderId === row.node.id\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">more_horiz</mat-icon>\n </button>\n </div>\n </ng-container>\n <!-- Root-level pagination is now driven by scroll (see `(scroll)` on the\n tree container above). Per-folder children retain the explicit\n \"Load more\" button rendered inside the rows loop above, since\n subtrees aren't independently scrollable. -->\n <!-- Pagination spinner \u2014 visible only when fetching an additional page\n of roots (folders.length > 0 distinguishes from initial-load case). -->\n <div\n *ngIf=\"rootFoldersLoading && folders.length > 0 && !searchValue?.trim()\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-py-2\"\n aria-live=\"polite\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 14 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Divider between folder tree and pinned Unorganized tab -->\n <div\n aria-hidden=\"true\"\n class=\"cqa-mx-3 cqa-flex-shrink-0\"\n style=\"height: 1px; background-color: #E5E7EB; margin-top: 6px; margin-bottom: 6px;\"\n ></div>\n\n <!-- Unorganized \u2014 pinned below the scrollable folder tree so it stays visible regardless of folder count -->\n <div\n role=\"treeitem\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(null)\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-px-3 cqa-py-1.5 cqa-cursor-pointer hover:cqa-bg-[#D8D9FC] focus:cqa-outline-none focus:cqa-bg-[#D8D9FC] cqa-relative cqa-flex-shrink-0\"\n [style.background-color]=\"isSelected(null) ? '#D8D9FC' : null\"\n [cqaFolderDrop]=\"null\"\n [dropEnabled]=\"allowDrop\"\n (testsDropped)=\"rowDropped(null, $event)\"\n (folderDropped)=\"onFolderRowDropped(null, $event)\"\n (click)=\"onSelectUnorganized()\"\n >\n <span\n *ngIf=\"isSelected(null)\"\n class=\"cqa-absolute cqa-left-0 cqa-top-0 cqa-bottom-0 cqa-w-[3px] cqa-bg-indigo-600\"\n ></span>\n <mat-icon [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <span class=\"cqa-flex-1 cqa-text-sm\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ labels.unorganized }}</span>\n <span *ngIf=\"showCounts\" class=\"cqa-text-xs cqa-tabular-nums\" [style.color]=\"isSelected(null) ? '#3F43EE' : '#4C4C51'\">{{ unorganizedCount }}</span>\n </div>\n\n <!-- Folder context menu (right-click / ellipsis). A 0\u00D70 fixed-position\n anchor at the click coords drives a cdkConnectedOverlay; CDK's\n flexible-connected positioning auto-flips up/left when the menu\n would overflow the viewport (last-folder-near-bottom case). -->\n <div #ctxAnchor cdkOverlayOrigin\n class=\"cqa-fixed cqa-w-0 cqa-h-0 cqa-pointer-events-none\"\n [style.left.px]=\"contextMenuPosition.x\"\n [style.top.px]=\"contextMenuPosition.y\"></div>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"ctxAnchor\"\n [cdkConnectedOverlayOpen]=\"contextMenuFolderId !== null\"\n [cdkConnectedOverlayPositions]=\"contextMenuPositions\"\n [cdkConnectedOverlayHasBackdrop]=\"false\"\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\n [cdkConnectedOverlayPush]=\"true\"\n (overlayOutsideClick)=\"onOverlayOutsideClick()\"\n (detach)=\"closeContextMenu()\"\n >\n <!-- The lib's tailwind config sets important: '.cqa-ui-root', which\n emits descendant selectors like `.cqa-ui-root .cqa-bg-white`.\n CDK Overlay teleports this template into the global overlay\n container (outside the host's cqa-ui-root), so we wrap the menu in\n an ancestor cqa-ui-root div to re-establish the utility scope. -->\n <div class=\"cqa-ui-root\">\n <div\n role=\"menu\"\n class=\"cqa-min-w-[180px] cqa-bg-white cqa-border cqa-border-neutral-200 cqa-rounded-md cqa-shadow-lg cqa-py-1\"\n (click)=\"$event.stopPropagation()\"\n (contextmenu)=\"$event.preventDefault(); $event.stopPropagation()\"\n >\n <ng-container *ngIf=\"folderById(contextMenuFolderId) as menuNode\">\n <button\n *ngIf=\"allowCreate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextCreateSubfolder(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">create_new_folder</mat-icon>\n <span>{{ labels.folderMenuCreateSubfolder }}</span>\n </button>\n <button\n *ngIf=\"allowRename\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextRename(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">edit</mat-icon>\n <span>{{ labels.folderMenuRename }}</span>\n </button>\n <button\n *ngIf=\"allowMove\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextMove(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">drive_file_move</mat-icon>\n <span>{{ labels.folderMenuMove }}</span>\n </button>\n <button\n *ngIf=\"allowDuplicate\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-neutral-800 hover:cqa-bg-indigo-50 cqa-text-left\"\n (click)=\"onContextDuplicate(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">content_copy</mat-icon>\n <span>{{ labels.folderMenuDuplicate }}</span>\n </button>\n <div *ngIf=\"allowDelete && (allowCreate || allowRename || allowMove || allowDuplicate)\" class=\"cqa-h-px cqa-bg-neutral-200 cqa-my-1\"></div>\n <button\n *ngIf=\"allowDelete\"\n type=\"button\"\n role=\"menuitem\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-w-full cqa-px-3 cqa-py-1.5 cqa-text-sm cqa-text-red-600 hover:cqa-bg-red-50 cqa-text-left\"\n (click)=\"onContextDelete(menuNode)\"\n >\n <mat-icon style=\"font-size:16px;width:16px;height:16px\">delete_outline</mat-icon>\n <span>{{ labels.folderMenuDelete }}</span>\n </button>\n </ng-container>\n </div>\n </div>\n </ng-template>\n\n </ng-container>\n </div>\n</aside>\n", styles: [] }]
638
691
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { folders: [{
639
692
  type: Input
640
693
  }], selectedFolderId: [{
@@ -659,6 +712,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
659
712
  type: Input
660
713
  }], collapsed: [{
661
714
  type: Input
715
+ }], foldersAccordionExpanded: [{
716
+ type: Input
662
717
  }], labels: [{
663
718
  type: Input
664
719
  }], serverSideSearch: [{
@@ -669,6 +724,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
669
724
  type: Input
670
725
  }], rootFoldersLoading: [{
671
726
  type: Input
727
+ }], savingFolderIds: [{
728
+ type: Input
672
729
  }], folderSelected: [{
673
730
  type: Output
674
731
  }], folderExpansionToggled: [{
@@ -699,6 +756,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
699
756
  type: Output
700
757
  }], collapsedChange: [{
701
758
  type: Output
759
+ }], foldersAccordionExpandedChange: [{
760
+ type: Output
702
761
  }], searchValue: [{
703
762
  type: Input
704
763
  }], onDocumentClick: [{
@@ -711,4 +770,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
711
770
  type: HostListener,
712
771
  args: ['document:dragend']
713
772
  }] } });
714
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9sZGVyLXNpZGViYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90ZW1wbGF0ZXMvbW9kdWxhci10YWJsZS10ZW1wbGF0ZS9mb2xkZXItc2lkZWJhci9mb2xkZXItc2lkZWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RlbXBsYXRlcy9tb2R1bGFyLXRhYmxlLXRlbXBsYXRlL2ZvbGRlci1zaWRlYmFyL2ZvbGRlci1zaWRlYmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQ0wsc0JBQXNCLEdBSXZCLE1BQU0sa0NBQWtDLENBQUM7Ozs7Ozs7Ozs7QUFvQjFDLE1BQU0sT0FBTyxzQkFBc0I7SUEyR2pDLFlBQW9CLEdBQXNCO1FBQXRCLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBMUdqQyxZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUMzQixxQkFBZ0IsR0FBa0IsSUFBSSxDQUFDO1FBQ3ZDLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztRQUNqQyxxQkFBZ0IsR0FBVyxDQUFDLENBQUM7UUFDN0IsZ0JBQVcsR0FBWSxJQUFJLENBQUM7UUFDNUIsZ0JBQVcsR0FBWSxJQUFJLENBQUM7UUFDNUIsZ0JBQVcsR0FBWSxJQUFJLENBQUM7UUFDNUIsY0FBUyxHQUFZLElBQUksQ0FBQztRQUMxQixtQkFBYyxHQUFZLElBQUksQ0FBQztRQUMvQixjQUFTLEdBQVksSUFBSSxDQUFDO1FBQzFCLGVBQVUsR0FBWSxJQUFJLENBQUM7UUFDM0IsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUMzQixXQUFNLEdBQWtCLEVBQUUsR0FBRyxzQkFBc0IsRUFBRSxD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S0FBSztnQkFLRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBR0csU0FBUztzQkFBakIsS0FBSztnQkFJRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBS0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUVJLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csc0JBQXNCO3NCQUEvQixNQUFNO2dCQUlHLHVCQUF1QjtzQkFBaEMsTUFBTTtnQkFHRyx1QkFBdUI7c0JBQWhDLE1BQU07Z0JBR0csWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUVHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFFRyx3QkFBd0I7c0JBQWpDLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBS0UsV0FBVztzQkFBbkIsS0FBSztnQkFxWE4sZUFBZTtzQkFEZCxZQUFZO3VCQUFDLGdCQUFnQjtnQkFNOUIsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLHlCQUF5QjtnQkF3R3ZDLGlCQUFpQjtzQkFEaEIsWUFBWTt1QkFBQyxrQkFBa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb25uZWN0ZWRQb3NpdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7XG4gIERFRkFVTFRfTU9EVUxBUl9MQUJFTFMsXG4gIEZvbGRlck5vZGUsXG4gIEZvbGRlclJlbmFtZWRQYXlsb2FkLFxuICBNb2R1bGFyTGFiZWxzLFxufSBmcm9tICcuLi9tb2R1bGFyLXRhYmxlLXRlbXBsYXRlLm1vZGVscyc7XG5cbi8qKiBBIHJvdyBpbiB0aGUgZmxhdHRlbmVkIHNpZGViYXIgdHJlZS4gYGtpbmRgIGRpc3Rpbmd1aXNoZXMgcmVhbCBmb2xkZXIgcm93c1xuICogIGZyb20gdGhlIGxhenktbG9hZCBhZmZvcmRhbmNlcyAoJ2xvYWRpbmcnIHNwaW5uZXIsICdsb2FkLW1vcmUnIGJ1dHRvbikgdGhhdFxuICogIHRoZSBgcm93c2AgZ2V0dGVyIGludGVybGVhdmVzIGluc2lkZSBhbiBleHBhbmRlZCBzdWJ0cmVlLiAqL1xuaW50ZXJmYWNlIFJlbmRlck5vZGUge1xuICBraW5kOiAnZm9sZGVyJyB8ICdsb2FkaW5nJyB8ICdsb2FkLW1vcmUnO1xuICBub2RlOiBGb2xkZXJOb2RlO1xuICBkZXB0aDogbnVtYmVyO1xuICB2aXNpYmxlOiBib29sZWFuO1xuICBoYXNDaGlsZHJlbjogYm9vbGVhbjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY3FhLWZvbGRlci1zaWRlYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZvbGRlci1zaWRlYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbXSxcbiAgaG9zdDogeyBjbGFzczogJ2NxYS11aS1yb290JyB9LFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgRm9sZGVyU2lkZWJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGZvbGRlcnM6IEZvbGRlck5vZGVbXSA9IFtdO1xuICBASW5wdXQoKSBzZWxlY3RlZEZvbGRlcklkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgZXhwYW5kZWRGb2xkZXJJZHM6IG51bWJlcltdID0gW107XG4gIEBJbnB1dCgpIHVub3JnYW5pemVkQ291bnQ6IG51bWJlciA9IDA7XG4gIEBJbnB1dCgpIGFsbG93Q3JlYXRlOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgYWxsb3dSZW5hbWU6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBhbGxvd0RlbGV0ZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGFsbG93TW92ZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGFsbG93RHVwbGljYXRlOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgYWxsb3dEcm9wOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgc2hvd0NvdW50czogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGNvbGxhcHNlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBsYWJlbHM6IE1vZHVsYXJMYWJlbHMgPSB7IC4uLkRFRkFVTFRfTU9EVUxBUl9MQUJFTFMgfTtcbiAgLyoqIFdoZW4gdHJ1ZSwgdGhlIHNpZGViYXIgZW1pdHMgYHNlYXJjaENoYW5nZWAgYW5kIHNraXBzIGl0cyBsb2NhbCBuYW1lIGZpbHRlclxuICAgKiAg4oCUIHRoZSBob3N0IGlzIGV4cGVjdGVkIHRvIHN3YXAgYGZvbGRlcnNgIHdpdGggc2VydmVyLXNpZGUgc2VhcmNoIHJlc3VsdHMuXG4gICAqICBEZWZhdWx0IGtlZXBzIHRoZSBsZWdhY3kgY2xpZW50LXNpZGUgYmVoYXZpb3VyIGZvciBjYWxsZXJzIHRoYXQgaGF2ZW4ndFxuICAgKiAgb3B0ZWQgaW50byBsYXp5IGxvYWRpbmcgeWV0LiAqL1xuICBASW5wdXQoKSBzZXJ2ZXJTaWRlU2VhcmNoOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBCYWNrZW5kLXJlcG9ydGVkIHRvdGFsIHJvb3QgZm9sZGVycy4gV2hlbiBgZm9sZGVycy5sZW5ndGggPCByb290VG90YWxgIHRoZVxuICAgKiAgc2lkZWJhciByZW5kZXJzIGEgdG9wLWxldmVsIFwiTG9hZCBtb3JlXCIgYWZmb3JkYW5jZSBhZnRlciB0aGUgdHJlZS4gKi9cbiAgQElucHV0KCkgcm9vdFRvdGFsOiBudW1iZXIgPSAwO1xuICAvKiogVHJ1ZSB3aGlsZSBhIHNlcnZlci1zaWRlIGZvbGRlci1zZWFyY2ggcmVxdWVzdCBpcyBpbiBmbGlnaHQuIFRoZSBzaWRlYmFyXG4gICAqICBzaG93cyBhIHNwaW5uZXIgbmV4dCB0byB0aGUgc2VhcmNoIGlucHV0IHNvIHRoZSB1c2VyIGNhbiB0ZWxsIHR5cGluZ1xuICAgKiAgaGFzIGJlZW4gcmVnaXN0ZXJlZC4gKi9cbiAgQElucHV0KCkgZm9sZGVyU2VhcmNoTG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogVHJ1ZSB3aGlsZSBhIHJvb3QtcGFnZSBmZXRjaCBpcyBpbiBmbGlnaHQgKGluaXRpYWwgbG9hZCBPUiBzY3JvbGwtZHJpdmVuXG4gICAqICBwYWdpbmF0aW9uKS4gV2hlbiBzZXQgd2l0aCBubyBmb2xkZXJzIHlldCwgdGhlIHNpZGViYXIgc2hvd3MgYSBjZW50ZXJlZFxuICAgKiAgc3Bpbm5lcjsgd2hlbiBzZXQgZHVyaW5nIHBhZ2luYXRpb24sIGEgc21hbGwgc3Bpbm5lciBhcHBlYXJzIGF0IHRoZVxuICAgKiAgYm90dG9tIG9mIHRoZSB0cmVlLiAqL1xuICBASW5wdXQoKSByb290Rm9sZGVyc0xvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBAT3V0cHV0KCkgZm9sZGVyU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IG51bGw+KCk7XG4gIEBPdXRwdXQoKSBmb2xkZXJFeHBhbnNpb25Ub2dnbGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXI7IGV4cGFuZGVkOiBib29sZWFuIH0+KCk7XG4gIC8qKiBMYXp5LWxvYWQ6IGZpcmVzIHdoZW4gdGhlIHVzZXIgZXhwYW5kcyBhIG5vZGUgd2hvc2UgY2hpbGRyZW4gaGF2ZW4ndCBiZWVuXG4gICAqICBmZXRjaGVkIHlldCAoYGhhc0NoaWxkcmVuID09PSB0cnVlICYmIGxvYWRlZFBhZ2VzID09PSB1bmRlZmluZWRgKS4gSG9zdFxuICAgKiAgcmVzcG9uZHMgYnkgY2FsbGluZyBpdHMgYGxvYWRGb2xkZXJDaGlsZHJlbihpZCwgMClgLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyQ2hpbGRyZW5SZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgLyoqIExhenktbG9hZDogZmlyZXMgd2hlbiB0aGUgdXNlciBjbGlja3MgdGhlIHBlci1mb2xkZXIgXCJMb2FkIG1vcmVcIiByb3cuXG4gICAqICBIb3N0IHJlc3BvbmRzIGJ5IGNhbGxpbmcgYGxvYWRGb2xkZXJDaGlsZHJlbihpZCwgbmV4dFBhZ2UpYC4gKi9cbiAgQE91dHB1dCgpIGZvbGRlckxvYWRNb3JlUmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXI7IG5leHRQYWdlOiBudW1iZXIgfT4oKTtcbiAgLyoqIERlYm91bmNlZCBzZWFyY2gtaW5wdXQgdmFsdWUuIEFsd2F5cyBlbWl0dGVkOyBvbmx5IGNvbnN1bWVkIGJ5IGhvc3RzIHRoYXRcbiAgICogIHNldCBgc2VydmVyU2lkZVNlYXJjaD10cnVlYCB0byByZS1mZXRjaCB0aGUgdHJlZSBmcm9tIHRoZSBiYWNrZW5kLiAqL1xuICBAT3V0cHV0KCkgc2VhcmNoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBMYXp5LWxvYWQ6IHVzZXIgY2xpY2tlZCB0aGUgdG9wLWxldmVsIFwiTG9hZCBtb3JlXCIgYWZmb3JkYW5jZSBmb3Igcm9vdHMuICovXG4gIEBPdXRwdXQoKSByb290TG9hZE1vcmVSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBFbWl0dGVkIGFmdGVyIHRoZSBob3N0IGNvbXBsZXRlcyBmb2xkZXIgY3JlYXRpb24gKGUuZy4sIGlubGluZSByZW5hbWUgZmxvdykuIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyQ3JlYXRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8eyBwYXJlbnRJZDogbnVtYmVyIHwgbnVsbDsgbmFtZTogc3RyaW5nIH0+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIHRoZSBcIitcIiBoZWFkZXIgYnV0dG9uLiBIb3N0IHNob3VsZCBvcGVuIGEgY3JlYXRpb24gbW9kYWwuICovXG4gIEBPdXRwdXQoKSBmb2xkZXJDcmVhdGVSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcGFyZW50SWQ6IG51bWJlciB8IG51bGwgfT4oKTtcbiAgLyoqIENhcnJpZXMgdGhlIGZ1bGwgcmVuYW1lZCBmb2xkZXIgbm9kZSArIHBhcmVudCBpZCBzbyBob3N0cyBjYW4gaXNzdWUgY29tcGxldGUgdXBkYXRlIHJlcXVlc3RzLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyUmVuYW1lZCA9IG5ldyBFdmVudEVtaXR0ZXI8Rm9sZGVyUmVuYW1lZFBheWxvYWQ+KCk7XG4gIEBPdXRwdXQoKSBmb2xkZXJEZWxldGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXIgfT4oKTtcbiAgLyoqIFVzZXIgcGlja2VkIFwiTW92ZSBmb2xkZXJcIiBmcm9tIHRoZSBjb250ZXh0IG1lbnUuIEhvc3Qgb3BlbnMgdGhlIGZvbGRlciBwaWNrZXIuICovXG4gIEBPdXRwdXQoKSBmb2xkZXJNb3ZlUmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXIgfT4oKTtcbiAgLyoqIFVzZXIgcGlja2VkIFwiRHVwbGljYXRlIGZvbGRlclwiIGZyb20gdGhlIGNvbnRleHQgbWVudS4gSG9zdCBjbG9uZXMgdGhlIHN1YnRyZWUgKHRlc3RzIHJlZmVyZW5jZWQsIG5vdCBjb3BpZWQpLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyRHVwbGljYXRlUmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXIgfT4oKTtcbiAgQE91dHB1dCgpIHRlc3RzRHJvcHBlZCA9IG5ldyBFdmVudEVtaXR0ZXI8eyB0ZXN0SWRzOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+OyB0YXJnZXRGb2xkZXJJZDogbnVtYmVyIHwgbnVsbCB9PigpO1xuICAvKiogRmlyZXMgd2hlbiBhIGZvbGRlciByb3cgaXMgZHJvcHBlZCBvbnRvIGFub3RoZXIgZm9sZGVyIChvciB0aGUgVW5vcmdhbml6ZWQgcm93KS4gKi9cbiAgQE91dHB1dCgpIGZvbGRlckRyb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IG51bWJlcjsgbmV3UGFyZW50SWQ6IG51bWJlciB8IG51bGwgfT4oKTtcbiAgQE91dHB1dCgpIGNvbGxhcHNlZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogQm91bmQgdG8gdGhlIHNlYXJjaCBpbnB1dC4gRXhwb3NlZCBhcyBhbiBJbnB1dCBzbyBob3N0cyBjYW4gc2VlZC9yZXN0b3JlXG4gICAqICB0aGUgdmlzaWJsZSBzZWFyY2ggdGVybSBhY3Jvc3MgZGVzdHJveS9yZS1jcmVhdGUgY3ljbGVzIChlLmcuLCB3aGVuIHRoZVxuICAgKiAgc2lkZWJhciBpcyBgKm5nSWZgJ2Qgb3V0IGJ5IGEgdmlldy1tb2RlIHRvZ2dsZSBhbmQgcmUtbW91bnRlZCBsYXRlcikuICovXG4gIEBJbnB1dCgpIHNlYXJjaFZhbHVlOiBzdHJpbmcgPSAnJztcbiAgLyoqIERlYm91bmNlIHRpbWVyIGZvciBgc2VhcmNoQ2hhbmdlYCBlbWlzc2lvbnM7IGNsZWFyZWQgb24gZWFjaCBrZXlzdHJva2Ugc29cbiAgICogIHRoZSBob3N0IG9ubHkgcmUtZmV0Y2hlcyBvbmNlIHRoZSB1c2VyIHBhdXNlcyB0eXBpbmcuICovXG4gIHByaXZhdGUgc2VhcmNoRW1pdFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTRUFSQ0hfREVCT1VOQ0VfTVMgPSAzMDA7XG4gIHJlbmFtaW5nSWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICByZW5hbWVEcmFmdDogc3RyaW5nID0gJyc7XG4gIC8qKiBJbmxpbmUgcmVuYW1lIHVzZXMgdGhlIHNhbWUgbmFtZSBydWxlcyBhcyB0aGUgTmV3IEZvbGRlciBkaWFsb2cuICovXG4gIHJlYWRvbmx5IHJlbmFtZU1heExlbmd0aDogbnVtYmVyID0gMjA7XG4gIC8qKiBUcmFuc2llbnQgZmxhZzogdHVybnMgdGhlIHJlbmFtZSBpbnB1dCByZWQgYnJpZWZseSB3aGVuIHRoZSB1c2VyIGtleXN0cm9rZXNcbiAgICogIHdoaWxlIGFscmVhZHkgYXQgYHJlbmFtZU1heExlbmd0aGAsIHNvIHRoZSBzaWxlbnQgbWF4bGVuZ3RoIGNsYW1wIGdldHMgYVxuICAgKiAgdmlzaWJsZSBcInlvdSd2ZSBoaXQgdGhlIGNhcFwiIHNpZ25hbC4gQ2xlYXJlZCBieSBgcmVuYW1lTGltaXRGbGFzaFRpbWVyYC4gKi9cbiAgcmVuYW1lTGltaXRGbGFzaCA9IGZhbHNlO1xuICBwcml2YXRlIHJlbmFtZUxpbWl0Rmxhc2hUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUkVOQU1FX0xJTUlUX0ZMQVNIX01TID0gNjAwO1xuXG4gIC8qKiBJZCBvZiB0aGUgZm9sZGVyIHdob3NlIGNvbnRleHQgbWVudSBpcyBvcGVuLCBvciBudWxsIHdoZW4gY2xvc2VkLiAqL1xuICBjb250ZXh0TWVudUZvbGRlcklkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFN1cHByZXNzIG91dHNpZGUtY2xpY2sgaGFuZGxpbmcgdW50aWwgdGhpcyB0aW1lc3RhbXA7IHByb3RlY3RzIGFnYWluc3QgdGhlXG4gICAqICByaWdodC1jbGljayB0aGF0IG9wZW5zIHRoZSBtZW51IGFsc28gYmVpbmcgaW50ZXJwcmV0ZWQgYXMgYW4gb3V0c2lkZSBjbGljay4gKi9cbiAgcHJpdmF0ZSBfc3VwcHJlc3NPdXRzaWRlQ2xpY2tVbnRpbCA9IDA7XG4gIC8qKiBWaWV3cG9ydC1hbmNob3JlZCBwb3NpdGlvbiAoY2xpZW50IGNvb3JkaW5hdGVzKSBmb3IgdGhlIGZsb2F0aW5nIG1lbnUuXG4gICAqICBEcml2ZXMgdGhlIGludmlzaWJsZSBjZGtPdmVybGF5T3JpZ2luIGFuY2hvcjsgQ0RLIE92ZXJsYXkgdGhlbiBwaWNrcyB0aGVcbiAgICogIGJlc3Qgb2YgYGNvbnRleHRNZW51UG9zaXRpb25zYCBzbyB0aGUgbWVudSBuZXZlciBvdmVyZmxvd3MgdGhlIHZpZXdwb3J0LiAqL1xuICBjb250ZXh0TWVudVBvc2l0aW9uOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPSB7IHg6IDAsIHk6IDAgfTtcblxuICAvKiogUG9zaXRpb24gcHJpb3JpdHkgZm9yIHRoZSBDREstb3ZlcmxheS1yZW5kZXJlZCBjb250ZXh0IG1lbnUuIENESyB0cmllcyBlYWNoXG4gICAqICBpbiBvcmRlciBhbmQgdXNlcyB0aGUgZmlyc3Qgb25lIHRoYXQgZml0cyDigJQgc28gdGhlIG1lbnUgb3BlbnMgZG93bndhcmQgYnlcbiAgICogIGRlZmF1bHQgYW5kIGZsaXBzIHVwIC8gbGVmdCB3aGVuIHRvbyBjbG9zZSB0byB0aGUgYm90dG9tIG9yIHJpZ2h0IGVkZ2UuICovXG4gIHJlYWRvbmx5IGNvbnRleHRNZW51UG9zaXRpb25zOiBDb25uZWN0ZWRQb3NpdGlvbltdID0gW1xuICAgIHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ2JvdHRvbScsIG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ3RvcCcgfSxcbiAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnLCAgICBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH0sXG4gICAgeyBvcmlnaW5YOiAnZW5kJywgICBvcmlnaW5ZOiAnYm90dG9tJywgb3ZlcmxheVg6ICdlbmQnLCAgIG92ZXJsYXlZOiAndG9wJyB9LFxuICAgIHsgb3JpZ2luWDogJ2VuZCcsICAgb3JpZ2luWTogJ3RvcCcsICAgIG92ZXJsYXlYOiAnZW5kJywgICBvdmVybGF5WTogJ2JvdHRvbScgfSxcbiAgXTtcblxuICAvKiogUGVuZGluZyBhdXRvLWV4cGFuZCB0aW1lcnMgd2hpbGUgYSBmb2xkZXIgZHJhZyBpcyBob3ZlcmVkIG92ZXIgY29sbGFwc2VkIHJvd3MuICovXG4gIHByaXZhdGUgZHJhZ0V4cGFuZFRpbWVycyA9IG5ldyBNYXA8bnVtYmVyLCBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0Pj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBEUkFHX0VYUEFORF9ERUxBWV9NUyA9IDYwMDtcbiAgLyoqIElkIG9mIHRoZSBmb2xkZXIgY3VycmVudGx5IGJlaW5nIGRyYWdnZWQ7IHVzZWQgdG8gc2tpcCBjeWNsZSB0YXJnZXRzIGFuZCBzb3VyY2UtaG92ZXIgZXhwYW5zaW9uLiAqL1xuICBwcml2YXRlIGFjdGl2ZUZvbGRlckRyYWdJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIGdldCBleHBhbmRlZFNldCgpOiBTZXQ8bnVtYmVyPiB7XG4gICAgcmV0dXJuIG5ldyBTZXQodGhpcy5leHBhbmRlZEZvbGRlcklkcyB8fCBbXSk7XG4gIH1cblxuICAvKiogRmxhdHRlbmVkLCBkZXB0aC1hd2FyZSBsaXN0IG9mIHJvd3MgdG8gcmVuZGVyIGluIG9yZGVyLiBBbmNlc3RvcnMgb2YgbWF0Y2hlcyBhcmUga2VwdC4gKi9cbiAgZ2V0IHJvd3MoKTogUmVuZGVyTm9kZVtdIHtcbiAgICAvLyBTZXJ2ZXItc2lkZSBtb2RlOiBob3N0IHByZS1maWx0ZXJzIGBmb2xkZXJzYDsgd2Ugc2tpcCB0aGUgbG9jYWwgZmlsdGVyIHNvXG4gICAgLy8gcmVzdWx0cyBhcmVuJ3QgZG91YmxlLWZpbHRlcmVkIChiYWNrZW5kIG1heSB1c2UgZGlmZmVyZW50IGZ1enp5IGxvZ2ljKS5cbiAgICBjb25zdCBsb2NhbFNlYXJjaCA9IHRoaXMuc2VydmVyU2lkZVNlYXJjaFxuICAgICAgPyAnJ1xuICAgICAgOiAodGhpcy5zZWFyY2hWYWx1ZSB8fCAnJykudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgZXhwYW5kZWQgPSB0aGlzLmV4cGFuZGVkU2V0O1xuICAgIGNvbnN0IGtlZXBTZXQgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICBpZiAobG9jYWxTZWFyY2gpIHtcbiAgICAgIGNvbnN0IG1hcmsgPSAobm9kZXM6IEZvbGRlck5vZGVbXSwgYW5jZXN0b3JzOiBudW1iZXJbXSk6IHZvaWQgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2Ygbm9kZXMgfHwgW10pIHtcbiAgICAgICAgICBjb25zdCBtYXRjaGVkID0gKG4ubmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhsb2NhbFNlYXJjaCk7XG4gICAgICAgICAgY29uc3QgY2hpbGRBbmNlc3RvcnMgPSBbLi4uYW5jZXN0b3JzLCBuLmlkXTtcbiAgICAgICAgICBpZiAobWF0Y2hlZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBhIG9mIGFuY2VzdG9ycykga2VlcFNldC5hZGQoYSk7XG4gICAgICAgICAgICBrZWVwU2V0LmFkZChuLmlkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG4uY2hpbGRyZW4/Lmxlbmd0aCkgbWFyayhuLmNoaWxkcmVuLCBjaGlsZEFuY2VzdG9ycyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBtYXJrKHRoaXMuZm9sZGVycywgW10pO1xuICAgIH1cblxuICAgIGNvbnN0IG91dDogUmVuZGVyTm9kZVtdID0gW107XG4gICAgY29uc3Qgd2FsayA9IChub2RlczogRm9sZGVyTm9kZVtdLCBkZXB0aDogbnVtYmVyLCBwYXJlbnRWaXNpYmxlOiBib29sZWFuKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG4gb2Ygbm9kZXMgfHwgW10pIHtcbiAgICAgICAgY29uc3Qgc2VhcmNoVmlzaWJsZSA9ICFsb2NhbFNlYXJjaCB8fCBrZWVwU2V0LmhhcyhuLmlkKTtcbiAgICAgICAgY29uc3QgdmlzaWJsZSA9IHBhcmVudFZpc2libGUgJiYgc2VhcmNoVmlzaWJsZTtcbiAgICAgICAgLy8gU2hvdyB0aGUgY2hldnJvbiB3aGVuIHRoZSBiYWNrZW5kIHNheXMgdGhpcyBmb2xkZXIgaGFzIGNoaWxkcmVuXG4gICAgICAgIC8vIChsYXp5LWxvYWQ6IGNoaWxkcmVuIG1heSBub3QgYmUgZmV0Y2hlZCB5ZXQpIE9SIHdoZW4gY2hpbGRyZW4gYXJlXG4gICAgICAgIC8vIGFscmVhZHkgcG9wdWxhdGVkIChlYWdlciBtb2RlIGZvciBjYWxsZXJzIHRoYXQgcHJlLWJ1aWxkIHRoZSB0cmVlKS5cbiAgICAgICAgY29uc3QgaGFzQ2hpbGRyZW4gPSAhIW4uaGFzQ2hpbGRyZW4gfHwgISEobi5jaGlsZHJlbiAmJiBuLmNoaWxkcmVuLmxlbmd0aCk7XG4gICAgICAgIG91dC5wdXNoKHsga2luZDogJ2ZvbGRlcicsIG5vZGU6IG4sIGRlcHRoLCB2aXNpYmxlLCBoYXNDaGlsZHJlbiB9KTtcbiAgICAgICAgY29uc3QgZXhwYW5kZWRCeVNlYXJjaCA9ICEhbG9jYWxTZWFyY2ggJiYga2VlcFNldC5oYXMobi5pZCk7XG4gICAgICAgIGNvbnN0IGlzTm9kZUV4cGFuZGVkID0gZXhwYW5kZWQuaGFzKG4uaWQpIHx8IGV4cGFuZGVkQnlTZWFyY2g7XG4gICAgICAgIGlmICghaXNOb2RlRXhwYW5kZWQgfHwgIWhhc0NoaWxkcmVuKSBjb250aW51ZTtcbiAgICAgICAgLy8gUmVjdXJzZSBmb3IgY2hpbGRyZW4gdGhhdCBhcmUgYWxyZWFkeSBpbiBtZW1vcnkuXG4gICAgICAgIGlmIChuLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgICAgICB3YWxrKG4uY2hpbGRyZW4sIGRlcHRoICsgMSwgdmlzaWJsZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQXBwZW5kIGxhenktbG9hZCBhZmZvcmRhbmNlcyBhdCB0aGUgZW5kIG9mIHRoZSBvcGVuIHN1YnRyZWU6XG4gICAgICAgIC8vIC0gJ2xvYWRpbmcnIHdoaWxlIGEgY2hpbGRyZW4tcGFnZSBmZXRjaCBpcyBpbiBmbGlnaHQuXG4gICAgICAgIC8vIC0gJ2xvYWQtbW9yZScgd2hlbiBtb3JlIGNoaWxkcmVuIGV4aXN0IG9uIHRoZSBiYWNrZW5kIHRoYW4gd2UgaGF2ZS5cbiAgICAgICAgaWYgKG4uY2hpbGRyZW5Mb2FkaW5nKSB7XG4gICAgICAgICAgb3V0LnB1c2goeyBraW5kOiAnbG9hZGluZycsIG5vZGU6IG4sIGRlcHRoOiBkZXB0aCArIDEsIHZpc2libGUsIGhhc0NoaWxkcmVuOiBmYWxzZSB9KTtcbiAgICAgICAgfSBlbHNlIGlmICgobi5jaGlsZHJlbj8ubGVuZ3RoID8/IDApIDwgKG4udG90YWxDaGlsZHJlbiA/PyAwKSkge1xuICAgICAgICAgIG91dC5wdXNoKHsga2luZDogJ2xvYWQtbW9yZScsIG5vZGU6IG4sIGRlcHRoOiBkZXB0aCArIDEsIHZpc2libGUsIGhhc0NoaWxkcmVuOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgd2Fsayh0aGlzLmZvbGRlcnMsIDAsIHRydWUpO1xuICAgIHJldHVybiBvdXQuZmlsdGVyKHIgPT4gci52aXNpYmxlKTtcbiAgfVxuXG4gIGlzRXhwYW5kZWQoaWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmV4cGFuZGVkU2V0LmhhcyhpZCk7XG4gIH1cblxuICBpc1NlbGVjdGVkKGlkOiBudW1iZXIgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgaWYgKGlkID09IG51bGwgJiYgdGhpcy5zZWxlY3RlZEZvbGRlcklkID09IG51bGwpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBpZCAhPSBudWxsICYmIHRoaXMuc2VsZWN0ZWRGb2xkZXJJZCAhPSBudWxsICYmIGlkID09PSB0aGlzLnNlbGVjdGVkRm9sZGVySWQ7XG4gIH1cblxuICBvblRvZ2dsZShuOiBGb2xkZXJOb2RlLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBleHBhbmRlZCA9ICF0aGlzLmlzRXhwYW5kZWQobi5pZCk7XG4gICAgdGhpcy5mb2xkZXJFeHBhbnNpb25Ub2dnbGVkLmVtaXQoeyBpZDogbi5pZCwgZXhwYW5kZWQgfSk7XG4gICAgLy8gTGF6eSBmZXRjaDogaWYgdGhlIHVzZXIgaXMgZXhwYW5kaW5nIGEgbm9kZSB3aG9zZSBjaGlsZHJlbiBoYXZlbid0IGJlZW5cbiAgICAvLyBsb2FkZWQgeWV0LCBhc2sgdGhlIGhvc3QgdG8gZmV0Y2ggdGhlbS4gU2tpcCB3aGVuIG5vdCBsYXp5IChsb2FkZWRQYWdlc1xuICAgIC8vIGFscmVhZHkgc2V0KSBvciBub3QgZXhwYW5kaW5nLlxuICAgIGlmIChleHBhbmRlZCAmJiBuLmhhc0NoaWxkcmVuICYmIG4ubG9hZGVkUGFnZXMgPT0gbnVsbCkge1xuICAgICAgdGhpcy5mb2xkZXJDaGlsZHJlblJlcXVlc3RlZC5lbWl0KG4uaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZWFyY2ggaW5wdXQgaGFuZGxlcjogdXBkYXRlcyB0aGUgbG9jYWwgYHNlYXJjaFZhbHVlYCBpbW1lZGlhdGVseSAoc28gdGhlXG4gICAqICBpbnB1dCBzdGF5cyByZXNwb25zaXZlKSBhbmQgZGVib3VuY2VzIGBzZWFyY2hDaGFuZ2VgIGVtaXNzaW9ucyBzbyBhIGhvc3RcbiAgICogIGRvaW5nIHNlcnZlci1zaWRlIHNlYXJjaCBmaXJlcyBhdCBtb3N0IG9uZSByZXF1ZXN0IHBlciBwYXVzZS4gKi9cbiAgb25TZWFyY2hJbnB1dCh0ZXJtOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaFZhbHVlID0gdGVybTtcbiAgICBpZiAodGhpcy5zZWFyY2hFbWl0VGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnNlYXJjaEVtaXRUaW1lcik7XG4gICAgdGhpcy5zZWFyY2hFbWl0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc2VhcmNoQ2hhbmdlLmVtaXQodGhpcy5zZWFyY2hWYWx1ZSk7XG4gICAgICB0aGlzLnNlYXJjaEVtaXRUaW1lciA9IG51bGw7XG4gICAgfSwgRm9sZGVyU2lkZWJhckNvbXBvbmVudC5TRUFSQ0hfREVCT1VOQ0VfTVMpO1xuICB9XG5cbiAgLyoqIFNlYXJjaCBpbnB1dCBjbGVhciBoYW5kbGVyOiBmbHVzaGVzIHRoZSBkZWJvdW5jZSBzbyB0aGUgaG9zdCBzZWVzIGFuXG4gICAqICBlbXB0eSB0ZXJtIGltbWVkaWF0ZWx5IGFuZCBjYW4gcmVzdG9yZSB0aGUgbGF6eSB0cmVlLiAqL1xuICBvblNlYXJjaENsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoVmFsdWUgPSAnJztcbiAgICBpZiAodGhpcy5zZWFyY2hFbWl0VGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNlYXJjaEVtaXRUaW1lcik7XG4gICAgICB0aGlzLnNlYXJjaEVtaXRUaW1lciA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc2VhcmNoQ2hhbmdlLmVtaXQoJycpO1xuICB9XG5cbiAgLyoqIExhenktbG9hZDogdXNlciBjbGlja2VkIHRoZSBwZXItZm9sZGVyIFwiTG9hZCBtb3JlXCIgcm93LiBUaGUgc2lkZWJhciB0cmFja3NcbiAgICogIHBhZ2luYXRpb24gdmlhIGBub2RlLmxvYWRlZFBhZ2VzYDsgdGhlIG5leHQgcGFnZSBpcyBsb2FkZWRQYWdlcyArIDEuICovXG4gIG9uTG9hZE1vcmUobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIGlmIChuLmxvYWRlZFBhZ2VzID09IG51bGwpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlckxvYWRNb3JlUmVxdWVzdGVkLmVtaXQoeyBpZDogbi5pZCwgbmV4dFBhZ2U6IG4ubG9hZGVkUGFnZXMgKyAxIH0pO1xuICB9XG5cbiAgLyoqIENhY2hlZCBgZm9sZGVycy5sZW5ndGhgIGF0IHRoZSBtb21lbnQgd2UgbGFzdCBlbWl0dGVkIGByb290TG9hZE1vcmVSZXF1ZXN0ZWRgLlxuICAgKiAgVXNlZCB0byB0aHJvdHRsZSB0aGUgc2Nyb2xsLWJhc2VkIHBhZ2luYXRpb24gc28gd2UgZG9uJ3QgcmUtZW1pdCB1bnRpbCB0aGVcbiAgICogIGhvc3QgaGFzIGFjdHVhbGx5IGFwcGVuZGVkIGEgbmV3IHBhZ2UuICovXG4gIHByaXZhdGUgbGFzdFJvb3RMb2FkRW1pdHRlZEF0OiBudW1iZXIgPSAtMTtcbiAgLyoqIFRocmVzaG9sZCAocHgpIGZvciBcIm5lYXIgdGhlIGJvdHRvbVwiIOKAlCBlbWl0IGEgbG9hZC1tb3JlIG9uY2UgdGhlIHNjcm9sbFxuICAgKiAgcG9zaXRpb24gaXMgd2l0aGluIHRoaXMgbWFueSBweCBvZiB0aGUgZW5kLiAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTQ1JPTExfTE9BRF9USFJFU0hPTERfUFggPSA2NDtcblxuICAvKiogVmVydGljYWwtc2Nyb2xsIGhhbmRsZXIgZm9yIHRoZSByb290LWZvbGRlciBsaXN0LiBGaXJlcyBgcm9vdExvYWRNb3JlUmVxdWVzdGVkYFxuICAgKiAgd2hlbiB0aGUgdXNlciBzY3JvbGxzIHdpdGhpbiB0aGUgdGhyZXNob2xkIG9mIHRoZSBib3R0b20gYW5kIG1vcmUgcm9vdHNcbiAgICogIGFyZSBhdmFpbGFibGUgb24gdGhlIGJhY2tlbmQuIFN1cHByZXNzZWQgZHVyaW5nIHNpZGViYXIgc2VhcmNoLiAqL1xuICBvblRyZWVTY3JvbGwoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VhcmNoVmFsdWU/LnRyaW0oKSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmZvbGRlcnMubGVuZ3RoID49IHRoaXMucm9vdFRvdGFsKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZm9sZGVycy5sZW5ndGggPT09IHRoaXMubGFzdFJvb3RMb2FkRW1pdHRlZEF0KSByZXR1cm47XG4gICAgY29uc3QgZWwgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgIGlmICghZWwpIHJldHVybjtcbiAgICBjb25zdCBkaXN0YW5jZUZyb21Cb3R0b20gPSBlbC5zY3JvbGxIZWlnaHQgLSAoZWwuc2Nyb2xsVG9wICsgZWwuY2xpZW50SGVpZ2h0KTtcbiAgICBpZiAoZGlzdGFuY2VGcm9tQm90dG9tID4gRm9sZGVyU2lkZWJhckNvbXBvbmVudC5TQ1JPTExfTE9BRF9USFJFU0hPTERfUFgpIHJldHVybjtcbiAgICB0aGlzLmxhc3RSb290TG9hZEVtaXR0ZWRBdCA9IHRoaXMuZm9sZGVycy5sZW5ndGg7XG4gICAgdGhpcy5yb290TG9hZE1vcmVSZXF1ZXN0ZWQuZW1pdCgpO1xuICB9XG5cbiAgb25TZWxlY3QobjogRm9sZGVyTm9kZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5yZW5hbWluZ0lkICE9IG51bGwpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlclNlbGVjdGVkLmVtaXQobiA9PSBudWxsID8gbnVsbCA6IG4uaWQpO1xuICB9XG5cbiAgb25TZWxlY3RVbm9yZ2FuaXplZCgpOiB2b2lkIHtcbiAgICAvLyBTZW50aW5lbDogaG9zdHMgdGhhdCBrZWVwIGFuIFwiVW5vcmdhbml6ZWRcIiBidWNrZXQgY2FuIHRyZWF0IGEgbnVsbCBzZWxlY3Rpb25cbiAgICAvLyBhcyBcInNob3cgdW5vcmdhbml6ZWRcIi4gSWYgdGhlcmUgaXMgYWxyZWFkeSBhIHJvb3QgKG51bGwpIHNlbGVjdGlvbiBwYXR0ZXJuLFxuICAgIC8vIHRoaXMgbWF0Y2hlcyBpdC4gSG9zdCBkZWNpZGVzIHNlbWFudGljcy5cbiAgICB0aGlzLmZvbGRlclNlbGVjdGVkLmVtaXQobnVsbCk7XG4gIH1cblxuICBiZWdpblJlbmFtZShuOiBGb2xkZXJOb2RlLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYWxsb3dSZW5hbWUpIHJldHVybjtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLnJlbmFtaW5nSWQgPSBuLmlkO1xuICAgIHRoaXMucmVuYW1lRHJhZnQgPSBuLm5hbWU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgdGhpcy5mb2N1c1JlbmFtZUlucHV0KG4uaWQpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIHJlbmFtZSBkcmFmdCBwYXNzZXMgdGhlIG5hbWUgcnVsZXMgKG5vbi1lbXB0eSwgd2l0aGluIG1heCBsZW5ndGgpLiAqL1xuICBnZXQgaXNSZW5hbWVEcmFmdFZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHRyaW1tZWQgPSAodGhpcy5yZW5hbWVEcmFmdCB8fCAnJykudHJpbSgpO1xuICAgIHJldHVybiB0cmltbWVkLmxlbmd0aCA+IDAgJiYgdHJpbW1lZC5sZW5ndGggPD0gdGhpcy5yZW5hbWVNYXhMZW5ndGg7XG4gIH1cblxuICBjb21taXRSZW5hbWUobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIC8vIERpc2NhcmQgaW52YWxpZCBkcmFmdHMgKGVtcHR5IC8gdG9vIGxvbmcpIGluc3RlYWQgb2YgY29tbWl0dGluZyBhIGJhZCBuYW1lLlxuICAgIC8vIFRoZSB1c2VyIHNlZXMgdGhlIHJlZCBib3JkZXIgd2hpbGUgZWRpdGluZzsgb24gYmx1ciB3ZSByZXZlcnQgdG8gdGhlIG9yaWdpbmFsLlxuICAgIGlmICghdGhpcy5pc1JlbmFtZURyYWZ0VmFsaWQpIHtcbiAgICAgIHRoaXMuY2FuY2VsUmVuYW1lKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5hbWUgPSAodGhpcy5yZW5hbWVEcmFmdCB8fCAnJykudHJpbSgpO1xuICAgIGlmIChuYW1lICE9PSBuLm5hbWUpIHtcbiAgICAgIC8vIEVtaXQgdGhlIGZ1bGwgcmVuYW1lZCBub2RlICh3aXRoIHRoZSBuZXcgbmFtZSkgKyBwYXJlbnQgY29udGV4dCBzbyBob3N0cyBjYW5cbiAgICAgIC8vIGNhbGwgYFBVVCAvdGVzdF9jYXNlX2ZvbGRlcnMve2lkfWAgd2l0aG91dCByZS1yZXNvbHZpbmcgZnJvbSB0aGVpciBjYWNoZWQgdHJlZS5cbiAgICAgIGNvbnN0IGZvbGRlcjogRm9sZGVyTm9kZSA9IHsgLi4ubiwgbmFtZSB9O1xuICAgICAgdGhpcy5mb2xkZXJSZW5hbWVkLmVtaXQoe1xuICAgICAgICBmb2xkZXIsXG4gICAgICAgIHBhcmVudElkOiB0aGlzLnBhcmVudElkT2Yobi5pZCksXG4gICAgICAgIHByZXZpb3VzTmFtZTogbi5uYW1lLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuY2FuY2VsUmVuYW1lKCk7XG4gIH1cblxuICBjYW5jZWxSZW5hbWUoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5hbWluZ0lkID0gbnVsbDtcbiAgICB0aGlzLnJlbmFtZURyYWZ0ID0gJyc7XG4gICAgdGhpcy5jbGVhclJlbmFtZUxpbWl0Rmxhc2goKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uUmVuYW1lS2V5KGV2ZW50OiBLZXlib2FyZEV2ZW50LCBuOiBGb2xkZXJOb2RlKTogdm9pZCB7XG4gICAgLy8gU3RvcCBidWJibGluZyBzbyB0aGUgcm93J3Mga2V5ZG93biBoYW5kbGVyICh3aGljaCB0cmVhdHMgU3BhY2UvRW50ZXIvQXJyb3dzIGFzXG4gICAgLy8gc2VsZWN0aW9uIC8gdHJlZSBuYXZpZ2F0aW9uKSBjYW4ndCBzd2FsbG93IGNoYXJhY3RlcnMgdHlwZWQgaW50byB0aGUgcmVuYW1lIGlucHV0LlxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAvLyBEb24ndCBzd2FsbG93IHRoZSB1c2VyJ3MgZWRpdCBvbiBFbnRlciB3aGVuIHRoZSBkcmFmdCBpcyBpbnZhbGlkIOKAlCBrZWVwXG4gICAgICAvLyB0aGUgaW5wdXQgb3BlbiAocmVkIGJvcmRlciBhbHJlYWR5IHNpZ25hbHMgdGhlIGlzc3VlKSBhbmQgbGV0IHRoZW0gZml4IGl0LlxuICAgICAgaWYgKCF0aGlzLmlzUmVuYW1lRHJhZnRWYWxpZCkgcmV0dXJuO1xuICAgICAgdGhpcy5jb21taXRSZW5hbWUobik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5jYW5jZWxSZW5hbWUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRm9yIGFueSBvdGhlciBrZXlzdHJva2UsIGRldGVjdCBcInVzZXIgaXMgdHJ5aW5nIHRvIHR5cGUgcGFzdCBtYXhsZW5ndGhcIiBhbmRcbiAgICAvLyBicmllZmx5IGZsYXNoIHRoZSBpbnB1dCByZWQuIFRoZSBicm93c2VyJ3MgYG1heGxlbmd0aGAgYXR0cmlidXRlIGFscmVhZHlcbiAgICAvLyBzaWxlbnRseSBibG9ja3MgdGhlIGNoYXJhY3RlcjsgdGhpcyBzdXJmYWNlcyBhIHZpc2libGUgXCJ5b3UndmUgaGl0IHRoZSBjYXBcIlxuICAgIC8vIHNpZ25hbCB0aGF0IHdvdWxkIG90aGVyd2lzZSBiZSBtaXNzaW5nLlxuICAgIGlmICh0aGlzLmlzUHJpbnRhYmxlS2V5KGV2ZW50KSAmJiB0aGlzLndvdWxkRXhjZWVkUmVuYW1lTGltaXQoZXZlbnQpKSB7XG4gICAgICB0aGlzLnRyaWdnZXJSZW5hbWVMaW1pdEZsYXNoKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1ByaW50YWJsZUtleShldmVudDogS2V5Ym9hcmRFdmVudCk6IGJvb2xlYW4ge1xuICAgIC8vIFNpbmdsZS1jaGFyYWN0ZXIga2V5cyBhcmUgcHJpbnRhYmxlcyAoYSwgQiwgMSwgISwgc3BhY2UpLiBNb2RpZmllci1kcml2ZW5cbiAgICAvLyBzaG9ydGN1dHMgKEN0cmwvTWV0YSkgc2hvdWxkbid0IGNvdW50IOKAlCB0aGV5IGRvbid0IGluc2VydCB0ZXh0LlxuICAgIHJldHVybiBldmVudC5rZXkubGVuZ3RoID09PSAxICYmICFldmVudC5jdHJsS2V5ICYmICFldmVudC5tZXRhS2V5ICYmICFldmVudC5hbHRLZXk7XG4gIH1cblxuICBwcml2YXRlIHdvdWxkRXhjZWVkUmVuYW1lTGltaXQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiBib29sZWFuIHtcbiAgICAvLyBUaGUgbmV3IGxlbmd0aCBhZnRlciB0aGUga2V5c3Ryb2tlIHdvdWxkIGJlOiBjdXJyZW50IC0gc2VsZWN0aW9uTGVuZ3RoICsgMS5cbiAgICAvLyBJZiBhIHNlbGVjdGlvbiBjb3ZlcnMgcGFydCBvZiB0aGUgdmFsdWUsIHR5cGluZyByZXBsYWNlcyB0aGF0IHJhbmdlLCBzbyB0aGVcbiAgICAvLyBuZXQgbGVuZ3RoIG1pZ2h0IHN0aWxsIGZpdCB1bmRlciB0aGUgY2FwLlxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50IHwgbnVsbDtcbiAgICBjb25zdCBzdGFydCA9IHRhcmdldD8uc2VsZWN0aW9uU3RhcnQgPz8gMDtcbiAgICBjb25zdCBlbmQgPSB0YXJnZXQ/LnNlbGVjdGlvbkVuZCA/PyAwO1xuICAgIGNvbnN0IHNlbGVjdGVkTGVuID0gTWF0aC5tYXgoMCwgZW5kIC0gc3RhcnQpO1xuICAgIGNvbnN0IGRyYWZ0TGVuID0gKHRoaXMucmVuYW1lRHJhZnQgfHwgJycpLmxlbmd0aDtcbiAgICByZXR1cm4gZHJhZnRMZW4gLSBzZWxlY3RlZExlbiA+PSB0aGlzLnJlbmFtZU1heExlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgdHJpZ2dlclJlbmFtZUxpbWl0Rmxhc2goKTogdm9pZCB7XG4gICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbmFtZUxpbWl0Rmxhc2hUaW1lcik7XG4gICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMucmVuYW1lTGltaXRGbGFzaCA9IGZhbHNlO1xuICAgICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSwgRm9sZGVyU2lkZWJhckNvbXBvbmVudC5SRU5BTUVfTElNSVRfRkxBU0hfTVMpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclJlbmFtZUxpbWl0Rmxhc2goKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVuYW1lTGltaXRGbGFzaFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIpO1xuICAgICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLnJlbmFtZUxpbWl0Rmxhc2ggPSBmYWxzZTtcbiAgfVxuXG4gIGRlbGV0ZUZvbGRlcihuOiBGb2xkZXJOb2RlLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYWxsb3dEZWxldGUpIHJldHVybjtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmZvbGRlckRlbGV0ZWQuZW1pdCh7IGlkOiBuLmlkIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5zIHRoZSBmb2xkZXIgY29udGV4dCBtZW51IGFuY2hvcmVkIGF0IHRoZSBnaXZlbiBjbGllbnQgY29vcmRpbmF0ZXMuXG4gICAqIENhbGxlZCBmcm9tIGJvdGggKGNvbnRleHRtZW51KSBvbiB0aGUgcm93IGFuZCAoY2xpY2spIG9uIHRoZSBlbGxpcHNpcyBidXR0b24uXG4gICAqIFRoZSB0ZW1wbGF0ZSByZW5kZXJzIHRoZSBtZW51IHZpYSBjZGtDb25uZWN0ZWRPdmVybGF5IGFuY2hvcmVkIG9uIGFuXG4gICAqIGludmlzaWJsZSAww5cwIG9yaWdpbiBhdCBgY29udGV4dE1lbnVQb3NpdGlvbmA7IENESydzIGZsZXhpYmxlLWNvbm5lY3RlZFxuICAgKiBwb3NpdGlvbmluZyBhdXRvLWZsaXBzIHVwL2xlZnQgd2hlbiB0aGUgcHJlZmVycmVkIHBsYWNlbWVudCB3b3VsZCBvdmVyZmxvd1xuICAgKiB0aGUgdmlld3BvcnQgKGUuZy4gcmlnaHQtY2xpY2tpbmcgdGhlIGxhc3QgZm9sZGVyIG5lYXIgdGhlIGJvdHRvbSBlZGdlKS5cbiAgICovXG4gIG9wZW5Db250ZXh0TWVudShuOiBGb2xkZXJOb2RlLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmhhc0FueUNvbnRleHRBY3Rpb24pIHJldHVybjtcbiAgICB0aGlzLmNvbnRleHRNZW51Rm9sZGVySWQgPSBuLmlkO1xuICAgIHRoaXMuY29udGV4dE1lbnVQb3NpdGlvbiA9IHsgeDogZXZlbnQuY2xpZW50WCwgeTogZXZlbnQuY2xpZW50WSB9O1xuICAgIC8vIENESydzIG91dHNpZGUtY2xpY2sgZGlzcGF0Y2hlciBhdHRhY2hlcyBib2R5LWxldmVsIGNhcHR1cmUtcGhhc2UgbGlzdGVuZXJzXG4gICAgLy8gZm9yIGNsaWNrL2F1eGNsaWNrL2NvbnRleHRtZW51LiBPbiByaWdodC1jbGljayB0aGUgY29udGV4dG1lbnUrYXV4Y2xpY2tcbiAgICAvLyBldmVudHMgZmlyZSBvbiB0aGUgc2FtZSBnZXN0dXJlIHRoYXQgb3BlbmVkIHRoZSBtZW51LCB3aGljaCB3b3VsZFxuICAgIC8vIGltbWVkaWF0ZWx5IGNsb3NlIGl0LiBTdXBwcmVzcyBvdXRzaWRlLWNsaWNrIGhhbmRsaW5nIGZvciBhIHNob3J0IHdpbmRvdy5cbiAgICB0aGlzLl9zdXBwcmVzc091dHNpZGVDbGlja1VudGlsID0gRGF0ZS5ub3coKSArIDI1MDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uT3ZlcmxheU91dHNpZGVDbGljaygpOiB2b2lkIHtcbiAgICBpZiAoRGF0ZS5ub3coKSA8IHRoaXMuX3N1cHByZXNzT3V0c2lkZUNsaWNrVW50aWwpIHJldHVybjtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgfVxuXG4gIGNsb3NlQ29udGV4dE1lbnUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29udGV4dE1lbnVGb2xkZXJJZCA9PSBudWxsKSByZXR1cm47XG4gICAgdGhpcy5jb250ZXh0TWVudUZvbGRlcklkID0gbnVsbDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoZW4gYXQgbGVhc3Qgb25lIG1lbnUgZW50cnkgaXMgZW5hYmxlZCDigJQgb3RoZXJ3aXNlIHRoZSB0cmlnZ2VyIGlzIHN1cHByZXNzZWQgZW50aXJlbHkuICovXG4gIGdldCBoYXNBbnlDb250ZXh0QWN0aW9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFsbG93Q3JlYXRlIHx8IHRoaXMuYWxsb3dSZW5hbWUgfHwgdGhpcy5hbGxvd01vdmUgfHwgdGhpcy5hbGxvd0R1cGxpY2F0ZSB8fCB0aGlzLmFsbG93RGVsZXRlO1xuICB9XG5cbiAgb25Db250ZXh0Q3JlYXRlU3ViZm9sZGVyKG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dDcmVhdGUpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlckNyZWF0ZVJlcXVlc3RlZC5lbWl0KHsgcGFyZW50SWQ6IG4uaWQgfSk7XG4gIH1cblxuICBvbkNvbnRleHRSZW5hbWUobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VDb250ZXh0TWVudSgpO1xuICAgIGlmICghdGhpcy5hbGxvd1JlbmFtZSkgcmV0dXJuO1xuICAgIHRoaXMucmVuYW1pbmdJZCA9IG4uaWQ7XG4gICAgdGhpcy5yZW5hbWVEcmFmdCA9IG4ubmFtZTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB0aGlzLmZvY3VzUmVuYW1lSW5wdXQobi5pZCk7XG4gIH1cblxuICBvbkNvbnRleHRNb3ZlKG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dNb3ZlKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJNb3ZlUmVxdWVzdGVkLmVtaXQoeyBpZDogbi5pZCB9KTtcbiAgfVxuXG4gIG9uQ29udGV4dER1cGxpY2F0ZShuOiBGb2xkZXJOb2RlKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUNvbnRleHRNZW51KCk7XG4gICAgaWYgKCF0aGlzLmFsbG93RHVwbGljYXRlKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJEdXBsaWNhdGVSZXF1ZXN0ZWQuZW1pdCh7IGlkOiBuLmlkIH0pO1xuICB9XG5cbiAgb25Db250ZXh0RGVsZXRlKG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dEZWxldGUpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlckRlbGV0ZWQuZW1pdCh7IGlkOiBuLmlkIH0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snKVxuICBvbkRvY3VtZW50Q2xpY2soKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUNvbnRleHRNZW51KCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScpXG4gIG9uRXNjYXBlKCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VDb250ZXh0TWVudSgpO1xuICB9XG5cbiAgLyoqIFRlbXBsYXRlIGhlbHBlcjogcmVzb2x2ZSBhIGZvbGRlciBub2RlIGJ5IGlkIGZyb20gdGhlIGlucHV0IHRyZWUuICovXG4gIGZvbGRlckJ5SWQoaWQ6IG51bWJlciB8IG51bGwpOiBGb2xkZXJOb2RlIHwgbnVsbCB7XG4gICAgaWYgKGlkID09IG51bGwpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGZpbmQgPSAobm9kZXM6IEZvbGRlck5vZGVbXSk6IEZvbGRlck5vZGUgfCBudWxsID0+IHtcbiAgICAgIGZvciAoY29uc3QgbiBvZiBub2RlcyB8fCBbXSkge1xuICAgICAgICBpZiAobi5pZCA9PT0gaWQpIHJldHVybiBuO1xuICAgICAgICBpZiAobi5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgICAgY29uc3QgaGl0ID0gZmluZChuLmNoaWxkcmVuKTtcbiAgICAgICAgICBpZiAoaGl0KSByZXR1cm4gaGl0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIHJldHVybiBmaW5kKHRoaXMuZm9sZGVycyk7XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgcGFyZW50IGlkIG9mIGBpZGAsIG9yIG51bGwgd2hlbiBgaWRgIGlzIGEgcm9vdCBmb2xkZXIgLyBub3QgZm91bmQuICovXG4gIHByaXZhdGUgcGFyZW50SWRPZihpZDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgbGV0IHJlc3VsdDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgd2FsayA9IChub2RlczogRm9sZGVyTm9kZVtdLCBwYXJlbnRJZDogbnVtYmVyIHwgbnVsbCk6IGJvb2xlYW4gPT4ge1xuICAgICAgZm9yIChjb25zdCBuIG9mIG5vZGVzIHx8IFtdKSB7XG4gICAgICAgIGlmIChuLmlkID09PSBpZCkge1xuICAgICAgICAgIHJlc3VsdCA9IHBhcmVudElkO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuLmNoaWxkcmVuPy5sZW5ndGggJiYgd2FsayhuLmNoaWxkcmVuLCBuLmlkKSkgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICB3YWxrKHRoaXMuZm9sZGVycywgbnVsbCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHJlcXVlc3RDcmVhdGUocGFyZW50SWQ6IG51bWJlciB8IG51bGwgPSBudWxsKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmFsbG93Q3JlYXRlKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJDcmVhdGVSZXF1ZXN0ZWQuZW1pdCh7IHBhcmVudElkIH0pO1xuICB9XG5cbiAgdG9nZ2xlUGFuZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jb2xsYXBzZWQgPSAhdGhpcy5jb2xsYXBzZWQ7XG4gICAgdGhpcy5jb2xsYXBzZWRDaGFuZ2UuZW1pdCh0aGlzLmNvbGxhcHNlZCk7XG4gIH1cblxuICByb3dEcm9wcGVkKHRhcmdldElkOiBudW1iZXIgfCBudWxsLCBldmVudDogeyB0ZXN0SWRzOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+OyB0YXJnZXRGb2xkZXJJZDogbnVtYmVyIHwgbnVsbCB9KTogdm9pZCB7XG4gICAgLy8gRGlyZWN0aXZlIGFscmVhZHkgZW1pdHMgd2l0aCB0aGUgYm91bmQgZm9sZGVyIGlkLCBidXQgbm9ybWFsaXNlIGluIGNhc2UgY2FsbGVyc1xuICAgIC8vIHdpcmUgcmF3IGV2ZW50cy5cbiAgICB0aGlzLnRlc3RzRHJvcHBlZC5lbWl0KHsgdGVzdElkczogZXZlbnQudGVzdElkcywgdGFyZ2V0Rm9sZGVySWQ6IHRhcmdldElkIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERyb3AgdGFyZ2V0IHJlY2VpdmVkIGEgZm9sZGVyIGRyYWcuIFZhbGlkYXRlIGFnYWluc3Qgc2VsZi9kZXNjZW5kYW50IGN5Y2xlcyBhbmRcbiAgICogZW1pdCBgZm9sZGVyRHJvcHBlZGAgaWYgdGhlIG1vdmUgaXMgbGVnYWwuIENhbGxlZCBmcm9tIHRoZSBkaXJlY3RpdmUnc1xuICAgKiBgKGZvbGRlckRyb3BwZWQpYCBvdXRwdXQgb24gZXZlcnkgcm93IGFuZCBvbiB0aGUgVW5vcmdhbml6ZWQgcm93LlxuICAgKi9cbiAgb25Gb2xkZXJSb3dEcm9wcGVkKHRhcmdldElkOiBudW1iZXIgfCBudWxsLCBldmVudDogeyBmb2xkZXJJZDogbnVtYmVyOyB0YXJnZXRGb2xkZXJJZDogbnVtYmVyIHwgbnVsbCB9KTogdm9pZCB7XG4gICAgdGhpcy5jbGVhckFsbEV4cGFuZFRpbWVycygpO1xuICAgIHRoaXMuYWN0aXZlRm9sZGVyRHJhZ0lkID0gbnVsbDtcbiAgICBjb25zdCBzb3VyY2VJZCA9IGV2ZW50LmZvbGRlcklkO1xuICAgIGlmICh0YXJnZXRJZCAhPSBudWxsICYmIHRhcmdldElkID09PSBzb3VyY2VJZCkgcmV0dXJuO1xuICAgIGlmICh0YXJnZXRJZCAhPSBudWxsICYmIHRoaXMuaXNEZXNjZW5kYW50T2Yoc291cmNlSWQsIHRhcmdldElkKSkgcmV0dXJuO1xuICAgIHRoaXMuZm9sZGVyRHJvcHBlZC5lbWl0KHsgaWQ6IHNvdXJjZUlkLCBuZXdQYXJlbnRJZDogdGFyZ2V0SWQgfSk7XG4gIH1cblxuICAvKiogUmVtZW1iZXIgdGhlIGRyYWdnZWQgZm9sZGVyIHNvIHdlIGNhbiBibG9jayBzZWxmLWhvdmVyIGV4cGFuc2lvbiBhbmQgY3ljbGUgZHJvcHMuICovXG4gIG9uRm9sZGVyRHJhZ1N0YXJ0KG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUZvbGRlckRyYWdJZCA9IG4uaWQ7XG4gIH1cblxuICBvbkZvbGRlckRyYWdFbmQoKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVGb2xkZXJEcmFnSWQgPSBudWxsO1xuICAgIHRoaXMuY2xlYXJBbGxFeHBhbmRUaW1lcnMoKTtcbiAgfVxuXG4gIC8qKiBTY2hlZHVsZSBhbiBhdXRvLWV4cGFuZCBmb3IgYSBjb2xsYXBzZWQgZm9sZGVyIHRoYXQgaGFzIGNoaWxkcmVuIGR1cmluZyBkcmFnLWhvdmVyLiAqL1xuICBvbkZvbGRlclJvd0RyYWdPdmVyKHJvdzogUmVuZGVyTm9kZSk6IHZvaWQge1xuICAgIGNvbnN0IGlkID0gcm93Lm5vZGUuaWQ7XG4gICAgaWYgKCFyb3cuaGFzQ2hpbGRyZW4pIHJldHVybjtcbiAgICBpZiAodGhpcy5pc0V4cGFuZGVkKGlkKSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmFjdGl2ZUZvbGRlckRyYWdJZCA9PT0gaWQpIHJldHVybjsgLy8gZG9uJ3QgZXhwYW5kIHRoZSBzb3VyY2VcbiAgICBpZiAodGhpcy5kcmFnRXhwYW5kVGltZXJzLmhhcyhpZCkpIHJldHVybjtcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kcmFnRXhwYW5kVGltZXJzLmRlbGV0ZShpZCk7XG4gICAgICBpZiAoIXRoaXMuaXNFeHBhbmRlZChpZCkpIHtcbiAgICAgICAgdGhpcy5mb2xkZXJFeHBhbnNpb25Ub2dnbGVkLmVtaXQoeyBpZCwgZXhwYW5kZWQ6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfSwgdGhpcy5EUkFHX0VYUEFORF9ERUxBWV9NUyk7XG4gICAgdGhpcy5kcmFnRXhwYW5kVGltZXJzLnNldChpZCwgdGltZXIpO1xuICB9XG5cbiAgb25Gb2xkZXJSb3dEcmFnTGVhdmUocm93OiBSZW5kZXJOb2RlKTogdm9pZCB7XG4gICAgY29uc3QgaWQgPSByb3cubm9kZS5pZDtcbiAgICBjb25zdCB0aW1lciA9IHRoaXMuZHJhZ0V4cGFuZFRpbWVycy5nZXQoaWQpO1xuICAgIGlmICh0aW1lciAhPSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgdGhpcy5kcmFnRXhwYW5kVGltZXJzLmRlbGV0ZShpZCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6ZHJhZ2VuZCcpXG4gIG9uRG9jdW1lbnREcmFnRW5kKCk6IHZvaWQge1xuICAgIHRoaXMub25Gb2xkZXJEcmFnRW5kKCk7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGVuIGBjYW5kaWRhdGVJZGAgaXMgYHNvdXJjZUlkYCBpdHNlbGYgb3IgYW55IGRlc2NlbmRhbnQgb2YgaXQuICovXG4gIHByaXZhdGUgaXNEZXNjZW5kYW50T2Yoc291cmNlSWQ6IG51bWJlciwgY2FuZGlkYXRlSWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHNvdXJjZSA9IHRoaXMuZm9sZGVyQnlJZChzb3VyY2VJZCk7XG4gICAgaWYgKCFzb3VyY2UpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBzdGFjazogRm9sZGVyTm9kZVtdID0gW3NvdXJjZV07XG4gICAgd2hpbGUgKHN0YWNrLmxlbmd0aCkge1xuICAgICAgY29uc3QgbiA9IHN0YWNrLnBvcCgpITtcbiAgICAgIGlmIChuLmlkID09PSBjYW5kaWRhdGVJZCkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAobi5jaGlsZHJlbj8ubGVuZ3RoKSBzdGFjay5wdXNoKC4uLm4uY2hpbGRyZW4pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGNsZWFyQWxsRXhwYW5kVGltZXJzKCk6IHZvaWQge1xuICAgIHRoaXMuZHJhZ0V4cGFuZFRpbWVycy5mb3JFYWNoKHQgPT4gY2xlYXJUaW1lb3V0KHQpKTtcbiAgICB0aGlzLmRyYWdFeHBhbmRUaW1lcnMuY2xlYXIoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJBbGxFeHBhbmRUaW1lcnMoKTtcbiAgICB0aGlzLmNsZWFyUmVuYW1lTGltaXRGbGFzaCgpO1xuICAgIGlmICh0aGlzLnNlYXJjaEVtaXRUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuc2VhcmNoRW1pdFRpbWVyKTtcbiAgICAgIHRoaXMuc2VhcmNoRW1pdFRpbWVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB0cmFja0J5Um93ID0gKF86IG51bWJlciwgcm93OiBSZW5kZXJOb2RlKSA9PiBgJHtyb3cua2luZH1fJHtyb3cubm9kZS5pZH1gO1xuXG4gIG9uUm93S2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCwgcm93OiBSZW5kZXJOb2RlLCBpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgcm93cyA9IHRoaXMucm93cztcbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgY2FzZSAnQXJyb3dEb3duJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBuZXh0ID0gcm93c1tpbmRleCArIDFdO1xuICAgICAgICBpZiAobmV4dCkgdGhpcy5mb2N1c1Jvd0VsZW1lbnQobmV4dC5ub2RlLmlkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdBcnJvd1VwJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBwcmV2ID0gcm93c1tpbmRleCAtIDFdO1xuICAgICAgICBpZiAocHJldikgdGhpcy5mb2N1c1Jvd0VsZW1lbnQocHJldi5ub2RlLmlkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdBcnJvd1JpZ2h0Jzoge1xuICAgICAgICBpZiAocm93Lmhhc0NoaWxkcmVuICYmICF0aGlzLmlzRXhwYW5kZWQocm93Lm5vZGUuaWQpKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLmZvbGRlckV4cGFuc2lvblRvZ2dsZWQuZW1pdCh7IGlkOiByb3cubm9kZS5pZCwgZXhwYW5kZWQ6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdBcnJvd0xlZnQnOiB7XG4gICAgICAgIGlmIChyb3cuaGFzQ2hpbGRyZW4gJiYgdGhpcy5pc0V4cGFuZGVkKHJvdy5ub2RlLmlkKSkge1xuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdGhpcy5mb2xkZXJFeHBhbnNpb25Ub2dnbGVkLmVtaXQoeyBpZDogcm93Lm5vZGUuaWQsIGV4cGFuZGVkOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgIGNhc2UgJyAnOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMub25TZWxlY3Qocm93Lm5vZGUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZvY3VzUm93RWxlbWVudChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihgW2RhdGEtZm9sZGVyLXJvdy1pZD1cIiR7aWR9XCJdYCk7XG4gICAgICBlbD8uZm9jdXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb2N1c2VzIHRoZSBpbmxpbmUgcmVuYW1lIGlucHV0IGZvciB0aGUgZ2l2ZW4gZm9sZGVyLiBVc2VzIGBzZXRUaW1lb3V0YCAobm90XG4gICAqIG1pY3JvdGFzaykgYmVjYXVzZSB0aGUgaW5wdXQgaXMgZ2F0ZWQgYnkgYCpuZ0lmPVwicmVuYW1pbmdJZCA9PT0gLi4uXCJgIGFuZFxuICAgKiBtdXN0IHN1cnZpdmUgdGhlIG5leHQgT25QdXNoIGNoYW5nZS1kZXRlY3Rpb24gY3ljbGUgYmVmb3JlIGl0J3MgaW4gdGhlIERPTS5cbiAgICovXG4gIHByaXZhdGUgZm9jdXNSZW5hbWVJbnB1dChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTElucHV0RWxlbWVudD4oYFtkYXRhLWZvbGRlci1yZW5hbWUtaW5wdXQ9XCIke2lkfVwiXWApO1xuICAgICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgICAgZWwuZm9jdXMoKTtcbiAgICAgIGVsLnNlbGVjdCgpO1xuICAgIH0sIDApO1xuICB9XG59XG4iLCI8IS0tIFJldXNhYmxlIGZvbGRlciBpY29uLiBSZW5kZXIgdmlhIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJmb2xkZXJJY29uOyBjb250ZXh0OiB7IGNvbG9yOiBub2RlLmNvbG9yIH1cIj48L25nLWNvbnRhaW5lcj4uIC0tPlxuPG5nLXRlbXBsYXRlICNmb2xkZXJJY29uIGxldC1jb2xvcj1cImNvbG9yXCI+XG4gIDxzcGFuIGNsYXNzPVwiY3FhLWlubGluZS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS13LTQgY3FhLWgtNCBjcWEtc2hyaW5rLTBcIj5cbiAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMTMgMTJcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgIDxwYXRoIGQ9XCJNMTIuMTkxNiA5Ljg1ODI0QzEyLjE5MTYgMTAuMTY3NyAxMi4wNjg3IDEwLjQ2NDQgMTEuODQ5OSAxMC42ODMyQzExLjYzMTEgMTAuOTAyIDExLjMzNDMgMTEuMDI0OSAxMS4wMjQ5IDExLjAyNDlIMS42OTE1N0MxLjM4MjE1IDExLjAyNDkgMS4wODU0IDEwLjkwMiAwLjg2NjYxMSAxMC42ODMyQzAuNjQ3ODE5IDEwLjQ2NDQgMC41MjQ5MDIgMTAuMTY3NyAwLjUyNDkwMiA5Ljg1ODI0VjEuNjkxNTdDMC41MjQ5MDIgMS4zODIxNSAwLjY0NzgxOSAxLjA4NTQgMC44NjY2MTEgMC44NjY2MTFDMS4wODU0IDAuNjQ3ODE5IDEuMzgyMTUgMC41MjQ5MDIgMS42OTE1NyAwLjUyNDkwMkg0LjYwODI0TDUuNzc0OSAyLjI3NDlIMTEuMDI0OUMxMS4zMzQzIDIuMjc0OSAxMS42MzExIDIuMzk3ODIgMTEuODQ5OSAyLjYxNjYxQzEyLjA2ODcgMi44MzU0IDEyLjE5MTYgMy4xMzIxNSAxMi4xOTE2IDMuNDQxNTdWOS44NTgyNFpcIiBbYXR0ci5zdHJva2VdPVwiY29sb3IgfHwgJyM5OTk5OUUnXCIgc3Ryb2tlLXdpZHRoPVwiMS4wNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cbiAgICA8L3N2Zz5cbiAgPC9zcGFuPlxuPC9uZy10ZW1wbGF0ZT5cblxuPGFzaWRlXG4gIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1iZy13aGl0ZSBjcWEtYm9yZGVyIGNxYS1ib3JkZXItbmV1dHJhbC0yMDAgY3FhLXJvdW5kZWQtbGcgY3FhLWgtZnVsbCBjcWEtbWluLWgtMFwiXG4gIFtjbGFzcy5jcWEtdy1bMjQwcHhdXT1cIiFjb2xsYXBzZWRcIlxuICBbY2xhc3MuY3FhLXctWzQ4cHhdXT1cImNvbGxhcHNlZFwiXG4gIHN0eWxlPVwidHJhbnNpdGlvbjogd2lkdGggMTUwbXMgZWFzZTtcIlxuPlxuICA8IS0tIEhlYWRlciAtLT5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1weC0zIGNxYS1weS0xXCJcbiAgICBbc3R5bGUuYm9yZGVyLWJvdHRvbV09XCJjb2xsYXBzZWQgPyBudWxsIDogJzFweCBzb2xpZCAjRTJFMkUzJ1wiXG4gICAgW3N0eWxlLm1hcmdpbi1ib3R0b20ucHhdPVwiY29sbGFwc2VkID8gMCA6IDhcIlxuICA+XG4gICAgPHNwYW4gKm5nSWY9XCIhY29sbGFwc2VkXCIgY2xhc3M9XCJjcWEtdGV4dC1zbSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1uZXV0cmFsLTkwMFwiPlxuICAgICAge3sgbGFiZWxzLmZvbGRlcnMgfX1cbiAgICA8L3NwYW4+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0xXCIgW2NsYXNzLmNxYS13LWZ1bGxdPVwiY29sbGFwc2VkXCIgW2NsYXNzLmNxYS1qdXN0aWZ5LWNlbnRlcl09XCJjb2xsYXBzZWRcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiY3FhLXAtMSBjcWEtcm91bmRlZCBob3ZlcjpjcWEtYmctbmV1dHJhbC0xMDAgY3FhLXRleHQtbmV1dHJhbC01MDBcIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlUGFuZWwoKVwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiY29sbGFwc2VkID8gJ0V4cGFuZCBmb2xkZXJzIHBhbmVsJyA6ICdDb2xsYXBzZSBmb2xkZXJzIHBhbmVsJ1wiXG4gICAgICA+XG4gICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxOHB4O3dpZHRoOjE4cHg7aGVpZ2h0OjE4cHhcIj5cbiAgICAgICAgICB7eyBjb2xsYXBzZWQgPyAnY2hldnJvbl9yaWdodCcgOiAna2V5Ym9hcmRfZG91YmxlX2Fycm93X2xlZnQnIH19XG4gICAgICAgIDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgKm5nSWY9XCIhY29sbGFwc2VkICYmIGFsbG93Q3JlYXRlXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiY3FhLXAtMSBjcWEtcm91bmRlZCBob3ZlcjpjcWEtYmctbmV1dHJhbC0xMDAgY3FhLXRleHQtbmV1dHJhbC01MDBcIlxuICAgICAgICAoY2xpY2spPVwicmVxdWVzdENyZWF0ZShudWxsKVwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwibGFiZWxzLm5ld0ZvbGRlclwiXG4gICAgICAgIFt0aXRsZV09XCJsYWJlbHMubmV3Rm9sZGVyXCJcbiAgICAgID5cbiAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE4cHg7d2lkdGg6MThweDtoZWlnaHQ6MThweFwiPmFkZDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjb2xsYXBzZWRcIj5cbiAgICA8IS0tIFNlYXJjaCAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLXB4LTMgY3FhLXBiLTJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtcmVsYXRpdmVcIj5cbiAgICAgICAgPGNxYS1zZWFyY2gtYmFyXG4gICAgICAgICAgc2l6ZT1cInNtXCJcbiAgICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAgIFt2YWx1ZV09XCJzZWFyY2hWYWx1ZVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImxhYmVscy5zZWFyY2hGb2xkZXJzUGxhY2Vob2xkZXJcIlxuICAgICAgICAgIFtzaG93Q2xlYXJdPVwidHJ1ZVwiXG4gICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uU2VhcmNoSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgKGNsZWFyZWQpPVwib25TZWFyY2hDbGVhcigpXCJcbiAgICAgICAgPjwvY3FhLXNlYXJjaC1iYXI+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgKm5nSWY9XCJmb2xkZXJTZWFyY2hMb2FkaW5nXCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtcmlnaHQtOCBjcWEtaW5zZXQteS0wIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgIGFyaWEtbGl2ZT1cInBvbGl0ZVwiXG4gICAgICAgICAgYXJpYS1sYWJlbD1cIlNlYXJjaGluZyBmb2xkZXJzXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxtYXQtc3Bpbm5lciBkaWFtZXRlcj1cIjE0XCIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIj48L21hdC1zcGlubmVyPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gVHJlZSAoZm9sZGVycyBvbmx5IOKAlCBVbm9yZ2FuaXplZCBzaXRzIGRpcmVjdGx5IGJlbG93OyB0cmVlIGNhcHMgYXQgNjB2aCBhbmQgc2Nyb2xscyB3aGVuIG92ZXJmbG93aW5nKS5cbiAgICAgICAgIFNjcm9sbC1iYXNlZCBsYXp5LWxvYWRpbmcgYXQgdGhlIHJvb3QgbGV2ZWw6IG5lYXJpbmcgdGhlIGJvdHRvbSBlbWl0c1xuICAgICAgICAgYHJvb3RMb2FkTW9yZVJlcXVlc3RlZGAsIHdoaWNoIHRoZSBob3N0IHJlc3BvbmRzIHRvIGJ5IGZldGNoaW5nIHRoZVxuICAgICAgICAgbmV4dCBwYWdlIG9mIHJvb3RzLiAtLT5cbiAgICA8ZGl2IHJvbGU9XCJ0cmVlXCIgY2xhc3M9XCJjcWEtbWluLWgtMCBjcWEtbWF4LWgtWzYwdmhdIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLXB5LTEgY3FhLXNjcm9sbGJhci10aGluIGNxYS1zY3JvbGxiYXItdHJhY2stdHJhbnNwYXJlbnQgY3FhLXNjcm9sbGJhci10aHVtYi1bI0U1RTdFQl0gY3FhLXNjcm9sbGJhci10aHVtYi1yb3VuZGVkLWZ1bGwgY3FhLXNjcm9sbGJhci10aHVtYi1ob3ZlcjpjcWEtYmctWyNEMUQ1REJdXCJcbiAgICAgICAgIChzY3JvbGwpPVwib25UcmVlU2Nyb2xsKCRldmVudClcIj5cbiAgICAgIDwhLS0gSW5pdGlhbC1sb2FkIHNwaW5uZXI6IG9ubHkgcmVuZGVycyB3aGVuIHdlIGhhdmUgbm8gZm9sZGVycyB5ZXQgQU5EXG4gICAgICAgICAgIG5vIHNlYXJjaCBhY3RpdmUgKHNlYXJjaCBoYXMgaXRzIG93biBpbmxpbmUgc3Bpbm5lcikuIC0tPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cInJvb3RGb2xkZXJzTG9hZGluZyAmJiBmb2xkZXJzLmxlbmd0aCA9PT0gMCAmJiAhc2VhcmNoVmFsdWU/LnRyaW0oKVwiXG4gICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXB5LTZcIlxuICAgICAgICBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgICAgPlxuICAgICAgICA8bWF0LXNwaW5uZXIgZGlhbWV0ZXI9XCIyMFwiIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cInNlYXJjaFZhbHVlPy50cmltKCkgJiYgcm93cy5sZW5ndGggPT09IDAgJiYgIWZvbGRlclNlYXJjaExvYWRpbmdcIlxuICAgICAgICBjbGFzcz1cImNxYS1weC0zIGNxYS1weS0yIGNxYS10ZXh0LXNtIGNxYS10ZXh0LW5ldXRyYWwtNTAwIGNxYS10ZXh0LWNlbnRlclwiXG4gICAgICA+XG4gICAgICAgIHt7IGxhYmVscy5ub0ZvbGRlcnNGb3VuZCB9fVxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByb3cgb2Ygcm93czsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeVJvd1wiPlxuICAgICAgICA8IS0tIFN5bnRoZXRpYyBsb2FkaW5nIHJvdyAobGF6eSBmZXRjaCBpbiBmbGlnaHQpIC0tPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nSWY9XCJyb3cua2luZCA9PT0gJ2xvYWRpbmcnXCJcbiAgICAgICAgICBbc3R5bGUucGFkZGluZ0xlZnQucHhdPVwiOCArIHJvdy5kZXB0aCAqIDE2XCJcbiAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS1weS0xLjUgY3FhLXRleHQtc20gY3FhLXRleHQtbmV1dHJhbC01MDBcIlxuICAgICAgICAgIGFyaWEtbGl2ZT1cInBvbGl0ZVwiXG4gICAgICAgID5cbiAgICAgICAgICA8bWF0LXNwaW5uZXIgZGlhbWV0ZXI9XCIxNFwiIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICA8c3Bhbj5Mb2FkaW5n4oCmPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPCEtLSBTeW50aGV0aWMgbG9hZC1tb3JlIHJvdyAobW9yZSBjaGlsZHJlbiBhdmFpbGFibGUgb24gYmFja2VuZCkgLS0+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAqbmdJZj1cInJvdy5raW5kID09PSAnbG9hZC1tb3JlJ1wiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgW3N0eWxlLnBhZGRpbmdMZWZ0LnB4XT1cIjggKyByb3cuZGVwdGggKiAxNlwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS13LWZ1bGwgY3FhLXB5LTEuNSBjcWEtdGV4dC1zbSBjcWEtdGV4dC1pbmRpZ28tNjAwIGhvdmVyOmNxYS1iZy1pbmRpZ28tNTAgY3FhLXRleHQtbGVmdFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uTG9hZE1vcmUocm93Lm5vZGUpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICA+XG4gICAgICAgICAgPHNwYW4+TG9hZCBtb3JlICh7eyAocm93Lm5vZGUudG90YWxDaGlsZHJlbiA/PyAwKSAtIChyb3cubm9kZS5jaGlsZHJlbj8ubGVuZ3RoID8/IDApIH19KTwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwhLS0gUmVhbCBmb2xkZXIgcm93IC0tPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nSWY9XCJyb3cua2luZCA9PT0gJ2ZvbGRlcidcIlxuICAgICAgICAgIHJvbGU9XCJ0cmVlaXRlbVwiXG4gICAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cInJvdy5oYXNDaGlsZHJlbiA/IGlzRXhwYW5kZWQocm93Lm5vZGUuaWQpIDogbnVsbFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKVwiXG4gICAgICAgICAgW2F0dHIuZGF0YS1mb2xkZXItcm93LWlkXT1cInJvdy5ub2RlLmlkXCJcbiAgICAgICAgICBbY3FhRm9sZGVyRHJvcF09XCJyb3cubm9kZS5pZFwiXG4gICAgICAgICAgW2Ryb3BFbmFibGVkXT1cImFsbG93RHJvcFwiXG4gICAgICAgICAgKHRlc3RzRHJvcHBlZCk9XCJyb3dEcm9wcGVkKHJvdy5ub2RlLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAoZm9sZGVyRHJvcHBlZCk9XCJvbkZvbGRlclJvd0Ryb3BwZWQocm93Lm5vZGUuaWQsICRldmVudClcIlxuICAgICAgICAgIFtjcWFGb2xkZXJEcmFnXT1cInJvdy5ub2RlLmlkXCJcbiAgICAgICAgICBbZHJhZ0VuYWJsZWRdPVwiYWxsb3dEcm9wXCJcbiAgICAgICAgICAoZHJhZ3N0YXJ0KT1cIm9uRm9sZGVyRHJhZ1N0YXJ0KHJvdy5ub2RlKVwiXG4gICAgICAgICAgKGRyYWdlbmQpPVwib25Gb2xkZXJEcmFnRW5kKClcIlxuICAgICAgICAgIChkcmFnb3Zlcik9XCJvbkZvbGRlclJvd0RyYWdPdmVyKHJvdylcIlxuICAgICAgICAgIChkcmFnbGVhdmUpPVwib25Gb2xkZXJSb3dEcmFnTGVhdmUocm93KVwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uU2VsZWN0KHJvdy5ub2RlKVwiXG4gICAgICAgICAgKGNvbnRleHRtZW51KT1cIm9wZW5Db250ZXh0TWVudShyb3cubm9kZSwgJGV2ZW50KVwiXG4gICAgICAgICAgKGtleWRvd24pPVwib25Sb3dLZXlkb3duKCRldmVudCwgcm93LCBpKVwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZ3JvdXAgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEgY3FhLXByLTMgY3FhLXB5LTEuNSBjcWEtY3Vyc29yLXBvaW50ZXIgaG92ZXI6Y3FhLWJnLWluZGlnby01MCBmb2N1czpjcWEtb3V0bGluZS1ub25lIGZvY3VzOmNxYS1iZy1pbmRpZ28tNTAgY3FhLXJlbGF0aXZlXCJcbiAgICAgICAgICBbY2xhc3MuY3FhLWJnLWluZGlnby01MF09XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKSB8fCBjb250ZXh0TWVudUZvbGRlcklkID09PSByb3cubm9kZS5pZFwiXG4gICAgICAgICAgW3N0eWxlLnBhZGRpbmdMZWZ0LnB4XT1cIjggKyByb3cuZGVwdGggKiAxNlwiXG4gICAgICAgICAgW2F0dHIudGl0bGVdPVwicm93Lm5vZGUudG90YWxDb3VudCAhPSBudWxsID8gKHJvdy5ub2RlLnRvdGFsQ291bnQgKyAnIHRvdGFsIGluY2x1ZGluZyBzdWJmb2xkZXJzJykgOiBudWxsXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAqbmdJZj1cImlzU2VsZWN0ZWQocm93Lm5vZGUuaWQpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWFic29sdXRlIGNxYS1sZWZ0LTAgY3FhLXRvcC0wIGNxYS1ib3R0b20tMCBjcWEtdy1bM3B4XSBjcWEtYmctaW5kaWdvLTYwMFwiXG4gICAgICAgICAgPjwvc3Bhbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXAtMFwiXG4gICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwiaXNTZWxlY3RlZChyb3cubm9kZS5pZCkgPyAnIzNGNDNFRScgOiAnIzRDNEM1MSdcIlxuICAgICAgICAgICAgW3N0eWxlLnZpc2liaWxpdHldPVwicm93Lmhhc0NoaWxkcmVuID8gJ3Zpc2libGUnIDogJ2hpZGRlbidcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uVG9nZ2xlKHJvdy5ub2RlLCAkZXZlbnQpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiaXNFeHBhbmRlZChyb3cubm9kZS5pZCkgPyAnQ29sbGFwc2UnIDogJ0V4cGFuZCdcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxNnB4O3dpZHRoOjE2cHg7aGVpZ2h0OjE2cHhcIj5cbiAgICAgICAgICAgICAge3sgaXNFeHBhbmRlZChyb3cubm9kZS5pZCkgPyAnZXhwYW5kX21vcmUnIDogJ2NoZXZyb25fcmlnaHQnIH19XG4gICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJmb2xkZXJJY29uOyBjb250ZXh0OiB7IGNvbG9yOiByb3cubm9kZS5jb2xvciB9XCI+PC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicmVuYW1pbmdJZCA9PT0gcm93Lm5vZGUuaWQ7IGVsc2UgbmFtZVRwbFwiPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgc2l6ZT1cIjFcIlxuICAgICAgICAgICAgICBbYXR0ci5kYXRhLWZvbGRlci1yZW5hbWUtaW5wdXRdPVwicm93Lm5vZGUuaWRcIlxuICAgICAgICAgICAgICBbYXR0ci5tYXhsZW5ndGhdPVwicmVuYW1lTWF4TGVuZ3RoXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1taW4tdy0wIGNxYS13LWZ1bGwgY3FhLXB4LTIgY3FhLXB5LTAuNSBjcWEtcm91bmRlZCBjcWEtYm9yZGVyIGNxYS1iZy13aGl0ZSBjcWEtdGV4dC1zbSBjcWEtc2hhZG93LXNtIGZvY3VzOmNxYS1vdXRsaW5lLW5vbmUgZm9jdXM6Y3FhLXJpbmctMVwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIihpc1JlbmFtZURyYWZ0VmFsaWQgJiYgIXJlbmFtZUxpbWl0Rmxhc2gpXG4gICAgICAgICAgICAgICAgPyAnY3FhLWJvcmRlci1uZXV0cmFsLTMwMCBmb2N1czpjcWEtYm9yZGVyLWluZGlnby00MDAgZm9jdXM6Y3FhLXJpbmctaW5kaWdvLTIwMCdcbiAgICAgICAgICAgICAgICA6ICdjcWEtYm9yZGVyLVsjRUY0NDQ0XSBmb2N1czpjcWEtYm9yZGVyLVsjRUY0NDQ0XSBmb2N1czpjcWEtcmluZy1bI0ZDQTVBNV0nXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1pbnZhbGlkXT1cIiFpc1JlbmFtZURyYWZ0VmFsaWQgfHwgcmVuYW1lTGltaXRGbGFzaFwiXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicmVuYW1lRHJhZnRcIlxuICAgICAgICAgICAgICAoa2V5ZG93bik9XCJvblJlbmFtZUtleSgkZXZlbnQsIHJvdy5ub2RlKVwiXG4gICAgICAgICAgICAgIChrZXlwcmVzcyk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgICAoa2V5dXApPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgKGJsdXIpPVwiY29tbWl0UmVuYW1lKHJvdy5ub2RlKVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgI25hbWVUcGw+XG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLXRleHQtc20gY3FhLXRydW5jYXRlXCJcbiAgICAgICAgICAgICAgW3N0eWxlLmNvbG9yXT1cImlzU2VsZWN0ZWQocm93Lm5vZGUuaWQpID8gJyMzRjQzRUUnIDogJyM0QzRDNTEnXCJcbiAgICAgICAgICAgICAgKGRibGNsaWNrKT1cImJlZ2luUmVuYW1lKHJvdy5ub2RlLCAkZXZlbnQpXCJcbiAgICAgICAgICAgID57eyByb3cubm9kZS5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgICA8IS0tIENvdW50IHNob3duIGF0IHJlc3Q7IGhpZGRlbiBvbiByb3cgaG92ZXIgd2hlbiBkZWxldGUgaXMgYWxsb3dlZCAtLT5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgKm5nSWY9XCJzaG93Q291bnRzICYmIHJvdy5ub2RlLmNvdW50ICE9IG51bGxcIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtdGFidWxhci1udW1zIGNxYS1tbC0xXCJcbiAgICAgICAgICAgIFtzdHlsZS5jb2xvcl09XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKSA/ICcjM0Y0M0VFJyA6ICcjNEM0QzUxJ1wiXG4gICAgICAgICAgICBbY2xhc3MuZ3JvdXAtaG92ZXI6Y3FhLWhpZGRlbl09XCJhbGxvd0RlbGV0ZVwiXG4gICAgICAgICAgPnt7IHJvdy5ub2RlLmNvdW50IH19PC9zcGFuPlxuXG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNBbnlDb250ZXh0QWN0aW9uXCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtcC0wLjUgY3FhLXJvdW5kZWQgaG92ZXI6Y3FhLWJnLW5ldXRyYWwtMjAwXCJcbiAgICAgICAgICAgIFtzdHlsZS5jb2xvcl09XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKSB8fCBjb250ZXh0TWVudUZvbGRlcklkID09PSByb3cubm9kZS5pZCA/ICcjM0Y0M0VFJyA6ICcjNEM0QzUxJ1wiXG4gICAgICAgICAgICBbY2xhc3MuY3FhLWhpZGRlbl09XCJjb250ZXh0TWVudUZvbGRlcklkICE9PSByb3cubm9kZS5pZFwiXG4gICAgICAgICAgICBbY2xhc3MuZ3JvdXAtaG92ZXI6Y3FhLWlubGluZS1mbGV4XT1cInRydWVcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1pbmxpbmUtZmxleF09XCJjb250ZXh0TWVudUZvbGRlcklkID09PSByb3cubm9kZS5pZFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib3BlbkNvbnRleHRNZW51KHJvdy5ub2RlLCAkZXZlbnQpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ09wZW4gYWN0aW9ucyBmb3IgJyArIHJvdy5ub2RlLm5hbWVcIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1oYXNwb3B1cF09XCInbWVudSdcIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJjb250ZXh0TWVudUZvbGRlcklkID09PSByb3cubm9kZS5pZFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPm1vcmVfaG9yaXo8L21hdC1pY29uPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPCEtLSBSb290LWxldmVsIHBhZ2luYXRpb24gaXMgbm93IGRyaXZlbiBieSBzY3JvbGwgKHNlZSBgKHNjcm9sbClgIG9uIHRoZVxuICAgICAgICAgICB0cmVlIGNvbnRhaW5lciBhYm92ZSkuIFBlci1mb2xkZXIgY2hpbGRyZW4gcmV0YWluIHRoZSBleHBsaWNpdFxuICAgICAgICAgICBcIkxvYWQgbW9yZVwiIGJ1dHRvbiByZW5kZXJlZCBpbnNpZGUgdGhlIHJvd3MgbG9vcCBhYm92ZSwgc2luY2VcbiAgICAgICAgICAgc3VidHJlZXMgYXJlbid0IGluZGVwZW5kZW50bHkgc2Nyb2xsYWJsZS4gLS0+XG4gICAgICA8IS0tIFBhZ2luYXRpb24gc3Bpbm5lciDigJQgdmlzaWJsZSBvbmx5IHdoZW4gZmV0Y2hpbmcgYW4gYWRkaXRpb25hbCBwYWdlXG4gICAgICAgICAgIG9mIHJvb3RzIChmb2xkZXJzLmxlbmd0aCA+IDAgZGlzdGluZ3Vpc2hlcyBmcm9tIGluaXRpYWwtbG9hZCBjYXNlKS4gLS0+XG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0lmPVwicm9vdEZvbGRlcnNMb2FkaW5nICYmIGZvbGRlcnMubGVuZ3RoID4gMCAmJiAhc2VhcmNoVmFsdWU/LnRyaW0oKVwiXG4gICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXB5LTJcIlxuICAgICAgICBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgICAgPlxuICAgICAgICA8bWF0LXNwaW5uZXIgZGlhbWV0ZXI9XCIxNFwiIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBEaXZpZGVyIGJldHdlZW4gZm9sZGVyIHRyZWUgYW5kIHBpbm5lZCBVbm9yZ2FuaXplZCB0YWIgLS0+XG4gICAgPGRpdlxuICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgIGNsYXNzPVwiY3FhLW14LTMgY3FhLXNocmluay0wXCJcbiAgICAgIHN0eWxlPVwiaGVpZ2h0OiAxcHg7IGJhY2tncm91bmQtY29sb3I6ICNFNUU3RUI7IG1hcmdpbi10b3A6IDZweDsgbWFyZ2luLWJvdHRvbTogNnB4O1wiXG4gICAgPjwvZGl2PlxuXG4gICAgPCEtLSBVbm9yZ2FuaXplZCDigJQgcGlubmVkIGJlbG93IHRoZSBzY3JvbGxhYmxlIGZvbGRlciB0cmVlIHNvIGl0IHN0YXlzIHZpc2libGUgcmVnYXJkbGVzcyBvZiBmb2xkZXIgY291bnQgLS0+XG4gICAgPGRpdlxuICAgICAgcm9sZT1cInRyZWVpdGVtXCJcbiAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQobnVsbClcIlxuICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtcHgtMyBjcWEtcHktMS41IGNxYS1jdXJzb3ItcG9pbnRlciBob3ZlcjpjcWEtYmctaW5kaWdvLTUwIGZvY3VzOmNxYS1vdXRsaW5lLW5vbmUgZm9jdXM6Y3FhLWJnLWluZGlnby01MCBjcWEtcmVsYXRpdmUgY3FhLXNocmluay0wXCJcbiAgICAgIFtjbGFzcy5jcWEtYmctaW5kaWdvLTUwXT1cImlzU2VsZWN0ZWQobnVsbClcIlxuICAgICAgW2NxYUZvbGRlckRyb3BdPVwibnVsbFwiXG4gICAgICBbZHJvcEVuYWJsZWRdPVwiYWxsb3dEcm9wXCJcbiAgICAgICh0ZXN0c0Ryb3BwZWQpPVwicm93RHJvcHBlZChudWxsLCAkZXZlbnQpXCJcbiAgICAgIChmb2xkZXJEcm9wcGVkKT1cIm9uRm9sZGVyUm93RHJvcHBlZChudWxsLCAkZXZlbnQpXCJcbiAgICAgIChjbGljayk9XCJvblNlbGVjdFVub3JnYW5pemVkKClcIlxuICAgID5cbiAgICAgIDxzcGFuXG4gICAgICAgICpuZ0lmPVwiaXNTZWxlY3RlZChudWxsKVwiXG4gICAgICAgIGNsYXNzPVwiY3FhLWFic29sdXRlIGNxYS1sZWZ0LTAgY3FhLXRvcC0wIGNxYS1ib3R0b20tMCBjcWEtdy1bM3B4XSBjcWEtYmctaW5kaWdvLTYwMFwiXG4gICAgICA+PC9zcGFuPlxuICAgICAgPG1hdC1pY29uIFtzdHlsZS5jb2xvcl09XCJpc1NlbGVjdGVkKG51bGwpID8gJyMzRjQzRUUnIDogJyM0QzRDNTEnXCIgc3R5bGU9XCJmb250LXNpemU6MTZweDt3aWR0aDoxNnB4O2hlaWdodDoxNnB4XCI+aW5ib3g8L21hdC1pY29uPlxuICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtZmxleC0xIGNxYS10ZXh0LXNtXCIgW3N0eWxlLmNvbG9yXT1cImlzU2VsZWN0ZWQobnVsbCkgPyAnIzNGNDNFRScgOiAnIzRDNEM1MSdcIj57eyBsYWJlbHMudW5vcmdhbml6ZWQgfX08L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cInNob3dDb3VudHNcIiBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10YWJ1bGFyLW51bXNcIiBbc3R5bGUuY29sb3JdPVwiaXNTZWxlY3RlZChudWxsKSA/ICcjM0Y0M0VFJyA6ICcjNEM0QzUxJ1wiPnt7IHVub3JnYW5pemVkQ291bnQgfX08L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEZvbGRlciBjb250ZXh0IG1lbnUgKHJpZ2h0LWNsaWNrIC8gZWxsaXBzaXMpLiBBIDDDlzAgZml4ZWQtcG9zaXRpb25cbiAgICAgICAgIGFuY2hvciBhdCB0aGUgY2xpY2sgY29vcmRzIGRyaXZlcyBhIGNka0Nvbm5lY3RlZE92ZXJsYXk7IENESydzXG4gICAgICAgICBmbGV4aWJsZS1jb25uZWN0ZWQgcG9zaXRpb25pbmcgYXV0by1mbGlwcyB1cC9sZWZ0IHdoZW4gdGhlIG1lbnVcbiAgICAgICAgIHdvdWxkIG92ZXJmbG93IHRoZSB2aWV3cG9ydCAobGFzdC1mb2xkZXItbmVhci1ib3R0b20gY2FzZSkuIC0tPlxuICAgIDxkaXYgI2N0eEFuY2hvciBjZGtPdmVybGF5T3JpZ2luXG4gICAgICAgICBjbGFzcz1cImNxYS1maXhlZCBjcWEtdy0wIGNxYS1oLTAgY3FhLXBvaW50ZXItZXZlbnRzLW5vbmVcIlxuICAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwiY29udGV4dE1lbnVQb3NpdGlvbi54XCJcbiAgICAgICAgIFtzdHlsZS50b3AucHhdPVwiY29udGV4dE1lbnVQb3NpdGlvbi55XCI+PC9kaXY+XG5cbiAgICA8bmctdGVtcGxhdGVcbiAgICAgIGNka0Nvbm5lY3RlZE92ZXJsYXlcbiAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3JpZ2luXT1cImN0eEFuY2hvclwiXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9wZW5dPVwiY29udGV4dE1lbnVGb2xkZXJJZCAhPT0gbnVsbFwiXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uc109XCJjb250ZXh0TWVudVBvc2l0aW9uc1wiXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheUhhc0JhY2tkcm9wXT1cImZhbHNlXCJcbiAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5RmxleGlibGVEaW1lbnNpb25zXT1cImZhbHNlXCJcbiAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5UHVzaF09XCJ0cnVlXCJcbiAgICAgIChvdmVybGF5T3V0c2lkZUNsaWNrKT1cIm9uT3ZlcmxheU91dHNpZGVDbGljaygpXCJcbiAgICAgIChkZXRhY2gpPVwiY2xvc2VDb250ZXh0TWVudSgpXCJcbiAgICA+XG4gICAgICA8IS0tIFRoZSBsaWIncyB0YWlsd2luZCBjb25maWcgc2V0cyBpbXBvcnRhbnQ6ICcuY3FhLXVpLXJvb3QnLCB3aGljaFxuICAgICAgICAgICBlbWl0cyBkZXNjZW5kYW50IHNlbGVjdG9ycyBsaWtlIGAuY3FhLXVpLXJvb3QgLmNxYS1iZy13aGl0ZWAuXG4gICAgICAgICAgIENESyBPdmVybGF5IHRlbGVwb3J0cyB0aGlzIHRlbXBsYXRlIGludG8gdGhlIGdsb2JhbCBvdmVybGF5XG4gICAgICAgICAgIGNvbnRhaW5lciAob3V0c2lkZSB0aGUgaG9zdCdzIGNxYS11aS1yb290KSwgc28gd2Ugd3JhcCB0aGUgbWVudSBpblxuICAgICAgICAgICBhbiBhbmNlc3RvciBjcWEtdWktcm9vdCBkaXYgdG8gcmUtZXN0YWJsaXNoIHRoZSB1dGlsaXR5IHNjb3BlLiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtdWktcm9vdFwiPlxuICAgICAgPGRpdlxuICAgICAgICByb2xlPVwibWVudVwiXG4gICAgICAgIGNsYXNzPVwiY3FhLW1pbi13LVsxODBweF0gY3FhLWJnLXdoaXRlIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1uZXV0cmFsLTIwMCBjcWEtcm91bmRlZC1tZCBjcWEtc2hhZG93LWxnIGNxYS1weS0xXCJcbiAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgIChjb250ZXh0bWVudSk9XCIkZXZlbnQucHJldmVudERlZmF1bHQoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImZvbGRlckJ5SWQoY29udGV4dE1lbnVGb2xkZXJJZCkgYXMgbWVudU5vZGVcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgcm9sZT1cIm1lbnVpdGVtXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLXctZnVsbCBjcWEtcHgtMyBjcWEtcHktMS41IGNxYS10ZXh0LXNtIGNxYS10ZXh0LW5ldXRyYWwtODAwIGhvdmVyOmNxYS1iZy1pbmRpZ28tNTAgY3FhLXRleHQtbGVmdFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25Db250ZXh0Q3JlYXRlU3ViZm9sZGVyKG1lbnVOb2RlKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPmNyZWF0ZV9uZXdfZm9sZGVyPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDxzcGFuPnt7IGxhYmVscy5mb2xkZXJNZW51Q3JlYXRlU3ViZm9sZGVyIH19PC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiYWxsb3dSZW5hbWVcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICByb2xlPVwibWVudWl0ZW1cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtdy1mdWxsIGNxYS1weC0zIGNxYS1weS0xLjUgY3FhLXRleHQtc20gY3FhLXRleHQtbmV1dHJhbC04MDAgaG92ZXI6Y3FhLWJnLWluZGlnby01MCBjcWEtdGV4dC1sZWZ0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkNvbnRleHRSZW5hbWUobWVudU5vZGUpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJmb250LXNpemU6MTZweDt3aWR0aDoxNnB4O2hlaWdodDoxNnB4XCI+ZWRpdDwvbWF0LWljb24+XG4gICAgICAgICAgICA8c3Bhbj57eyBsYWJlbHMuZm9sZGVyTWVudVJlbmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImFsbG93TW92ZVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIHJvbGU9XCJtZW51aXRlbVwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS13LWZ1bGwgY3FhLXB4LTMgY3FhLXB5LTEuNSBjcWEtdGV4dC1zbSBjcWEtdGV4dC1uZXV0cmFsLTgwMCBob3ZlcjpjcWEtYmctaW5kaWdvLTUwIGNxYS10ZXh0LWxlZnRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29udGV4dE1vdmUobWVudU5vZGUpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJmb250LXNpemU6MTZweDt3aWR0aDoxNnB4O2hlaWdodDoxNnB4XCI+ZHJpdmVfZmlsZV9tb3ZlPC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDxzcGFuPnt7IGxhYmVscy5mb2xkZXJNZW51TW92ZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImFsbG93RHVwbGljYXRlXCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgcm9sZT1cIm1lbnVpdGVtXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLXctZnVsbCBjcWEtcHgtMyBjcWEtcHktMS41IGNxYS10ZXh0LXNtIGNxYS10ZXh0LW5ldXRyYWwtODAwIGhvdmVyOmNxYS1iZy1pbmRpZ28tNTAgY3FhLXRleHQtbGVmdFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25Db250ZXh0RHVwbGljYXRlKG1lbnVOb2RlKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPmNvbnRlbnRfY29weTwvbWF0LWljb24+XG4gICAgICAgICAgICA8c3Bhbj57eyBsYWJlbHMuZm9sZGVyTWVudUR1cGxpY2F0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYWxsb3dEZWxldGUgJiYgKGFsbG93Q3JlYXRlIHx8IGFsbG93UmVuYW1lIHx8IGFsbG93TW92ZSB8fCBhbGxvd0R1cGxpY2F0ZSlcIiBjbGFzcz1cImNxYS1oLXB4IGNxYS1iZy1uZXV0cmFsLTIwMCBjcWEtbXktMVwiPjwvZGl2PlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiYWxsb3dEZWxldGVcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICByb2xlPVwibWVudWl0ZW1cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtdy1mdWxsIGNxYS1weC0zIGNxYS1weS0xLjUgY3FhLXRleHQtc20gY3FhLXRleHQtcmVkLTYwMCBob3ZlcjpjcWEtYmctcmVkLTUwIGNxYS10ZXh0LWxlZnRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29udGV4dERlbGV0ZShtZW51Tm9kZSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxNnB4O3dpZHRoOjE2cHg7aGVpZ2h0OjE2cHhcIj5kZWxldGVfb3V0bGluZTwvbWF0LWljb24+XG4gICAgICAgICAgICA8c3Bhbj57eyBsYWJlbHMuZm9sZGVyTWVudURlbGV0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgPC9uZy1jb250YWluZXI+XG48L2FzaWRlPlxuIl19
773
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9sZGVyLXNpZGViYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90ZW1wbGF0ZXMvbW9kdWxhci10YWJsZS10ZW1wbGF0ZS9mb2xkZXItc2lkZWJhci9mb2xkZXItc2lkZWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RlbXBsYXRlcy9tb2R1bGFyLXRhYmxlLXRlbXBsYXRlL2ZvbGRlci1zaWRlYmFyL2ZvbGRlci1zaWRlYmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQ0wsc0JBQXNCLEdBSXZCLE1BQU0sa0NBQWtDLENBQUM7Ozs7Ozs7OztBQW9CMUMsTUFBTSxPQUFPLHNCQUFzQjtJQTRJakMsWUFBb0IsR0FBc0I7UUFBdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUEzSWpDLFlBQU8sR0FBaUIsRUFBRSxDQUFDO1FBQzNCLHFCQUFnQixHQUFrQixJQUFJLENBQUM7UUFDdkMsc0JBQWlCLEdBQWEsRUFBRSxDQUFDO1FBQ2pDLHFCQUFnQixHQUFXLENBQUMsQ0FBQztRQUM3QixnQkFBVyxHQUFZLElBQUksQ0FBQztRQUM1QixnQkFBVyxHQUFZLElBQUksQ0FBQztRQUM1QixnQkFBVyxHQUFZLElBQUksQ0FBQztRQUM1QixjQUFTLEdBQVksSUFBSSxDQUFDO1FBQzFCLG1CQUFjLEdBQVksSUFBSSxDQUFDO1FBQy9CLGNBQVMsR0FBWSxJQUFJLENBQUM7UUFDMUIsZUFBVSxHQUFZLElBQUksQ0FBQztRQUMzQixjQUFTLEdBQVksS0FBSyxDQUFDO1FBQzNCLDZCQUF3QixHQUFZLElBQUksQ0FBQztRQUN6QyxXQUFNLEdB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UztzQkFBakIsS0FBSztnQkFJRyxtQkFBbUI7c0JBQTNCLEtBQUs7Z0JBS0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUtHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBNEJJLGNBQWM7c0JBQXZCLE1BQU07Z0JBQ0csc0JBQXNCO3NCQUEvQixNQUFNO2dCQUlHLHVCQUF1QjtzQkFBaEMsTUFBTTtnQkFHRyx1QkFBdUI7c0JBQWhDLE1BQU07Z0JBR0csWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUVHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFFRyx3QkFBd0I7c0JBQWpDLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGVBQWU7c0JBQXhCLE1BQU07Z0JBQ0csOEJBQThCO3NCQUF2QyxNQUFNO2dCQUtFLFdBQVc7c0JBQW5CLEtBQUs7Z0JBcVhOLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0I7Z0JBTTlCLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyx5QkFBeUI7Z0JBK0h2QyxpQkFBaUI7c0JBRGhCLFlBQVk7dUJBQUMsa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29ubmVjdGVkUG9zaXRpb24gfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQge1xuICBERUZBVUxUX01PRFVMQVJfTEFCRUxTLFxuICBGb2xkZXJOb2RlLFxuICBGb2xkZXJSZW5hbWVkUGF5bG9hZCxcbiAgTW9kdWxhckxhYmVscyxcbn0gZnJvbSAnLi4vbW9kdWxhci10YWJsZS10ZW1wbGF0ZS5tb2RlbHMnO1xuXG4vKiogQSByb3cgaW4gdGhlIGZsYXR0ZW5lZCBzaWRlYmFyIHRyZWUuIGBraW5kYCBkaXN0aW5ndWlzaGVzIHJlYWwgZm9sZGVyIHJvd3NcbiAqICBmcm9tIHRoZSBsYXp5LWxvYWQgYWZmb3JkYW5jZXMgKCdsb2FkaW5nJyBzcGlubmVyLCAnbG9hZC1tb3JlJyBidXR0b24pIHRoYXRcbiAqICB0aGUgYHJvd3NgIGdldHRlciBpbnRlcmxlYXZlcyBpbnNpZGUgYW4gZXhwYW5kZWQgc3VidHJlZS4gKi9cbmludGVyZmFjZSBSZW5kZXJOb2RlIHtcbiAga2luZDogJ2ZvbGRlcicgfCAnbG9hZGluZycgfCAnbG9hZC1tb3JlJztcbiAgbm9kZTogRm9sZGVyTm9kZTtcbiAgZGVwdGg6IG51bWJlcjtcbiAgdmlzaWJsZTogYm9vbGVhbjtcbiAgaGFzQ2hpbGRyZW46IGJvb2xlYW47XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NxYS1mb2xkZXItc2lkZWJhcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9mb2xkZXItc2lkZWJhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogW10sXG4gIGhvc3Q6IHsgY2xhc3M6ICdjcWEtdWktcm9vdCcgfSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIEZvbGRlclNpZGViYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBmb2xkZXJzOiBGb2xkZXJOb2RlW10gPSBbXTtcbiAgQElucHV0KCkgc2VsZWN0ZWRGb2xkZXJJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGV4cGFuZGVkRm9sZGVySWRzOiBudW1iZXJbXSA9IFtdO1xuICBASW5wdXQoKSB1bm9yZ2FuaXplZENvdW50OiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBhbGxvd0NyZWF0ZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGFsbG93UmVuYW1lOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgYWxsb3dEZWxldGU6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBhbGxvd01vdmU6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBhbGxvd0R1cGxpY2F0ZTogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIGFsbG93RHJvcDogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpIHNob3dDb3VudHM6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBjb2xsYXBzZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgZm9sZGVyc0FjY29yZGlvbkV4cGFuZGVkOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KCkgbGFiZWxzOiBNb2R1bGFyTGFiZWxzID0geyAuLi5ERUZBVUxUX01PRFVMQVJfTEFCRUxTIH07XG4gIC8qKiBXaGVuIHRydWUsIHRoZSBzaWRlYmFyIGVtaXRzIGBzZWFyY2hDaGFuZ2VgIGFuZCBza2lwcyBpdHMgbG9jYWwgbmFtZSBmaWx0ZXJcbiAgICogIOKAlCB0aGUgaG9zdCBpcyBleHBlY3RlZCB0byBzd2FwIGBmb2xkZXJzYCB3aXRoIHNlcnZlci1zaWRlIHNlYXJjaCByZXN1bHRzLlxuICAgKiAgRGVmYXVsdCBrZWVwcyB0aGUgbGVnYWN5IGNsaWVudC1zaWRlIGJlaGF2aW91ciBmb3IgY2FsbGVycyB0aGF0IGhhdmVuJ3RcbiAgICogIG9wdGVkIGludG8gbGF6eSBsb2FkaW5nIHlldC4gKi9cbiAgQElucHV0KCkgc2VydmVyU2lkZVNlYXJjaDogYm9vbGVhbiA9IGZhbHNlO1xuICAvKiogQmFja2VuZC1yZXBvcnRlZCB0b3RhbCByb290IGZvbGRlcnMuIFdoZW4gYGZvbGRlcnMubGVuZ3RoIDwgcm9vdFRvdGFsYCB0aGVcbiAgICogIHNpZGViYXIgcmVuZGVycyBhIHRvcC1sZXZlbCBcIkxvYWQgbW9yZVwiIGFmZm9yZGFuY2UgYWZ0ZXIgdGhlIHRyZWUuICovXG4gIEBJbnB1dCgpIHJvb3RUb3RhbDogbnVtYmVyID0gMDtcbiAgLyoqIFRydWUgd2hpbGUgYSBzZXJ2ZXItc2lkZSBmb2xkZXItc2VhcmNoIHJlcXVlc3QgaXMgaW4gZmxpZ2h0LiBUaGUgc2lkZWJhclxuICAgKiAgc2hvd3MgYSBzcGlubmVyIG5leHQgdG8gdGhlIHNlYXJjaCBpbnB1dCBzbyB0aGUgdXNlciBjYW4gdGVsbCB0eXBpbmdcbiAgICogIGhhcyBiZWVuIHJlZ2lzdGVyZWQuICovXG4gIEBJbnB1dCgpIGZvbGRlclNlYXJjaExvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqIFRydWUgd2hpbGUgYSByb290LXBhZ2UgZmV0Y2ggaXMgaW4gZmxpZ2h0IChpbml0aWFsIGxvYWQgT1Igc2Nyb2xsLWRyaXZlblxuICAgKiAgcGFnaW5hdGlvbikuIFdoZW4gc2V0IHdpdGggbm8gZm9sZGVycyB5ZXQsIHRoZSBzaWRlYmFyIHNob3dzIGEgY2VudGVyZWRcbiAgICogIHNwaW5uZXI7IHdoZW4gc2V0IGR1cmluZyBwYWdpbmF0aW9uLCBhIHNtYWxsIHNwaW5uZXIgYXBwZWFycyBhdCB0aGVcbiAgICogIGJvdHRvbSBvZiB0aGUgdHJlZS4gKi9cbiAgQElucHV0KCkgcm9vdEZvbGRlcnNMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKiBGb2xkZXIgaWRzIGN1cnJlbnRseSBiZWluZyBzYXZlZCAocmVuYW1lIC8gbW92ZSAvIGV0YykuIFRoZSBzaWRlYmFyIHJlbmRlcnNcbiAgICogIGEgc21hbGwgc3Bpbm5lciBpbiBwbGFjZSBvZiB0aGUgY291bnQgc28gdGhlIHVzZXIgZ2V0cyBmZWVkYmFjayB3aGlsZSB0aGVcbiAgICogIGhvc3QncyBBUEkgY2FsbCBpcyBpbiBmbGlnaHQuIFRoZSBob3N0IGlzIHJlc3BvbnNpYmxlIGZvciBhZGRpbmcvcmVtb3ZpbmdcbiAgICogIGlkcyBhcm91bmQgaXRzIGFzeW5jIGNhbGwuICovXG4gIEBJbnB1dCgpIHNhdmluZ0ZvbGRlcklkczogQXJyYXk8bnVtYmVyPiA9IFtdO1xuXG4gIGlzRm9sZGVyU2F2aW5nKGlkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zYXZpbmdGb2xkZXJJZHM/LmluY2x1ZGVzKGlkKSA/PyBmYWxzZTtcbiAgfVxuXG4gIGZvbGRlclJvd1Rvb2x0aXAobm9kZTogRm9sZGVyTm9kZSk6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IG5hbWUgPSBub2RlPy5uYW1lIHx8ICcnO1xuICAgIGlmIChub2RlPy50b3RhbENvdW50ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBuYW1lIHx8IG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHRwbCA9IG5vZGUudG90YWxDb3VudCA9PT0gMVxuICAgICAgPyB0aGlzLmxhYmVscy5mb2xkZXJUb29sdGlwVG90YWxTaW5ndWxhclxuICAgICAgOiB0aGlzLmxhYmVscy5mb2xkZXJUb29sdGlwVG90YWxQbHVyYWw7XG4gICAgY29uc3QgY291bnRMaW5lID0gKHRwbCB8fCAnJykucmVwbGFjZSgne259JywgU3RyaW5nKG5vZGUudG90YWxDb3VudCkpO1xuICAgIHJldHVybiBuYW1lID8gYCR7bmFtZX1cXG4ke2NvdW50TGluZX1gIDogY291bnRMaW5lO1xuICB9XG5cbiAgLyoqIFZpc3VhbCBkZXB0aCBpbmRlbnQ6IGxpbmVhciB1cCB0byBhIGNhcCwgdGhlbiBxdWFydGVyLXJhdGUgYmV5b25kLCBzbyBkZWVwXG4gICAqICB0cmVlcyBkb24ndCBwdXNoIHRoZSByb3cgY29udGVudCBvZmYgdGhlIHJpZ2h0IGVkZ2Ugb2YgdGhlIHBhbmVsLiAqL1xuICByb3dJbmRlbnQoZGVwdGg6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3Qgc3RlcCA9IDE2O1xuICAgIGNvbnN0IGNhcCA9IDY7XG4gICAgY29uc3QgYmFzZSA9IDg7XG4gICAgaWYgKGRlcHRoIDw9IGNhcCkgcmV0dXJuIGJhc2UgKyBkZXB0aCAqIHN0ZXA7XG4gICAgcmV0dXJuIGJhc2UgKyBjYXAgKiBzdGVwICsgKGRlcHRoIC0gY2FwKSAqIDQ7XG4gIH1cblxuICBAT3V0cHV0KCkgZm9sZGVyU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlciB8IG51bGw+KCk7XG4gIEBPdXRwdXQoKSBmb2xkZXJFeHBhbnNpb25Ub2dnbGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXI7IGV4cGFuZGVkOiBib29sZWFuIH0+KCk7XG4gIC8qKiBMYXp5LWxvYWQ6IGZpcmVzIHdoZW4gdGhlIHVzZXIgZXhwYW5kcyBhIG5vZGUgd2hvc2UgY2hpbGRyZW4gaGF2ZW4ndCBiZWVuXG4gICAqICBmZXRjaGVkIHlldCAoYGhhc0NoaWxkcmVuID09PSB0cnVlICYmIGxvYWRlZFBhZ2VzID09PSB1bmRlZmluZWRgKS4gSG9zdFxuICAgKiAgcmVzcG9uZHMgYnkgY2FsbGluZyBpdHMgYGxvYWRGb2xkZXJDaGlsZHJlbihpZCwgMClgLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyQ2hpbGRyZW5SZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgLyoqIExhenktbG9hZDogZmlyZXMgd2hlbiB0aGUgdXNlciBjbGlja3MgdGhlIHBlci1mb2xkZXIgXCJMb2FkIG1vcmVcIiByb3cuXG4gICAqICBIb3N0IHJlc3BvbmRzIGJ5IGNhbGxpbmcgYGxvYWRGb2xkZXJDaGlsZHJlbihpZCwgbmV4dFBhZ2UpYC4gKi9cbiAgQE91dHB1dCgpIGZvbGRlckxvYWRNb3JlUmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXI7IG5leHRQYWdlOiBudW1iZXIgfT4oKTtcbiAgLyoqIERlYm91bmNlZCBzZWFyY2gtaW5wdXQgdmFsdWUuIEFsd2F5cyBlbWl0dGVkOyBvbmx5IGNvbnN1bWVkIGJ5IGhvc3RzIHRoYXRcbiAgICogIHNldCBgc2VydmVyU2lkZVNlYXJjaD10cnVlYCB0byByZS1mZXRjaCB0aGUgdHJlZSBmcm9tIHRoZSBiYWNrZW5kLiAqL1xuICBAT3V0cHV0KCkgc2VhcmNoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIC8qKiBMYXp5LWxvYWQ6IHVzZXIgY2xpY2tlZCB0aGUgdG9wLWxldmVsIFwiTG9hZCBtb3JlXCIgYWZmb3JkYW5jZSBmb3Igcm9vdHMuICovXG4gIEBPdXRwdXQoKSByb290TG9hZE1vcmVSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIC8qKiBFbWl0dGVkIGFmdGVyIHRoZSBob3N0IGNvbXBsZXRlcyBmb2xkZXIgY3JlYXRpb24gKGUuZy4sIGlubGluZSByZW5hbWUgZmxvdykuIFJlc2VydmVkIGZvciBmdXR1cmUgdXNlLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyQ3JlYXRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8eyBwYXJlbnRJZDogbnVtYmVyIHwgbnVsbDsgbmFtZTogc3RyaW5nIH0+KCk7XG4gIC8qKiBFbWl0dGVkIHdoZW4gdGhlIHVzZXIgY2xpY2tzIHRoZSBcIitcIiBoZWFkZXIgYnV0dG9uLiBIb3N0IHNob3VsZCBvcGVuIGEgY3JlYXRpb24gbW9kYWwuICovXG4gIEBPdXRwdXQoKSBmb2xkZXJDcmVhdGVSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcGFyZW50SWQ6IG51bWJlciB8IG51bGwgfT4oKTtcbiAgLyoqIENhcnJpZXMgdGhlIGZ1bGwgcmVuYW1lZCBmb2xkZXIgbm9kZSArIHBhcmVudCBpZCBzbyBob3N0cyBjYW4gaXNzdWUgY29tcGxldGUgdXBkYXRlIHJlcXVlc3RzLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyUmVuYW1lZCA9IG5ldyBFdmVudEVtaXR0ZXI8Rm9sZGVyUmVuYW1lZFBheWxvYWQ+KCk7XG4gIEBPdXRwdXQoKSBmb2xkZXJEZWxldGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXIgfT4oKTtcbiAgLyoqIFVzZXIgcGlja2VkIFwiTW92ZSBmb2xkZXJcIiBmcm9tIHRoZSBjb250ZXh0IG1lbnUuIEhvc3Qgb3BlbnMgdGhlIGZvbGRlciBwaWNrZXIuICovXG4gIEBPdXRwdXQoKSBmb2xkZXJNb3ZlUmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXIgfT4oKTtcbiAgLyoqIFVzZXIgcGlja2VkIFwiRHVwbGljYXRlIGZvbGRlclwiIGZyb20gdGhlIGNvbnRleHQgbWVudS4gSG9zdCBjbG9uZXMgdGhlIHN1YnRyZWUgKHRlc3RzIHJlZmVyZW5jZWQsIG5vdCBjb3BpZWQpLiAqL1xuICBAT3V0cHV0KCkgZm9sZGVyRHVwbGljYXRlUmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBudW1iZXIgfT4oKTtcbiAgQE91dHB1dCgpIHRlc3RzRHJvcHBlZCA9IG5ldyBFdmVudEVtaXR0ZXI8eyB0ZXN0SWRzOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+OyB0YXJnZXRGb2xkZXJJZDogbnVtYmVyIHwgbnVsbCB9PigpO1xuICAvKiogRmlyZXMgd2hlbiBhIGZvbGRlciByb3cgaXMgZHJvcHBlZCBvbnRvIGFub3RoZXIgZm9sZGVyIChvciB0aGUgVW5vcmdhbml6ZWQgcm93KS4gKi9cbiAgQE91dHB1dCgpIGZvbGRlckRyb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgaWQ6IG51bWJlcjsgbmV3UGFyZW50SWQ6IG51bWJlciB8IG51bGwgfT4oKTtcbiAgQE91dHB1dCgpIGNvbGxhcHNlZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIGZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogQm91bmQgdG8gdGhlIHNlYXJjaCBpbnB1dC4gRXhwb3NlZCBhcyBhbiBJbnB1dCBzbyBob3N0cyBjYW4gc2VlZC9yZXN0b3JlXG4gICAqICB0aGUgdmlzaWJsZSBzZWFyY2ggdGVybSBhY3Jvc3MgZGVzdHJveS9yZS1jcmVhdGUgY3ljbGVzIChlLmcuLCB3aGVuIHRoZVxuICAgKiAgc2lkZWJhciBpcyBgKm5nSWZgJ2Qgb3V0IGJ5IGEgdmlldy1tb2RlIHRvZ2dsZSBhbmQgcmUtbW91bnRlZCBsYXRlcikuICovXG4gIEBJbnB1dCgpIHNlYXJjaFZhbHVlOiBzdHJpbmcgPSAnJztcbiAgLyoqIERlYm91bmNlIHRpbWVyIGZvciBgc2VhcmNoQ2hhbmdlYCBlbWlzc2lvbnM7IGNsZWFyZWQgb24gZWFjaCBrZXlzdHJva2Ugc29cbiAgICogIHRoZSBob3N0IG9ubHkgcmUtZmV0Y2hlcyBvbmNlIHRoZSB1c2VyIHBhdXNlcyB0eXBpbmcuICovXG4gIHByaXZhdGUgc2VhcmNoRW1pdFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTRUFSQ0hfREVCT1VOQ0VfTVMgPSAzMDA7XG4gIHJlbmFtaW5nSWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICByZW5hbWVEcmFmdDogc3RyaW5nID0gJyc7XG4gIC8qKiBJbmxpbmUgcmVuYW1lIHVzZXMgdGhlIHNhbWUgbmFtZSBydWxlcyBhcyB0aGUgTmV3IEZvbGRlciBkaWFsb2cuICovXG4gIHJlYWRvbmx5IHJlbmFtZU1heExlbmd0aDogbnVtYmVyID0gMjA7XG4gIC8qKiBUcmFuc2llbnQgZmxhZzogdHVybnMgdGhlIHJlbmFtZSBpbnB1dCByZWQgYnJpZWZseSB3aGVuIHRoZSB1c2VyIGtleXN0cm9rZXNcbiAgICogIHdoaWxlIGFscmVhZHkgYXQgYHJlbmFtZU1heExlbmd0aGAsIHNvIHRoZSBzaWxlbnQgbWF4bGVuZ3RoIGNsYW1wIGdldHMgYVxuICAgKiAgdmlzaWJsZSBcInlvdSd2ZSBoaXQgdGhlIGNhcFwiIHNpZ25hbC4gQ2xlYXJlZCBieSBgcmVuYW1lTGltaXRGbGFzaFRpbWVyYC4gKi9cbiAgcmVuYW1lTGltaXRGbGFzaCA9IGZhbHNlO1xuICBwcml2YXRlIHJlbmFtZUxpbWl0Rmxhc2hUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUkVOQU1FX0xJTUlUX0ZMQVNIX01TID0gNjAwO1xuXG4gIC8qKiBJZCBvZiB0aGUgZm9sZGVyIHdob3NlIGNvbnRleHQgbWVudSBpcyBvcGVuLCBvciBudWxsIHdoZW4gY2xvc2VkLiAqL1xuICBjb250ZXh0TWVudUZvbGRlcklkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFN1cHByZXNzIG91dHNpZGUtY2xpY2sgaGFuZGxpbmcgdW50aWwgdGhpcyB0aW1lc3RhbXA7IHByb3RlY3RzIGFnYWluc3QgdGhlXG4gICAqICByaWdodC1jbGljayB0aGF0IG9wZW5zIHRoZSBtZW51IGFsc28gYmVpbmcgaW50ZXJwcmV0ZWQgYXMgYW4gb3V0c2lkZSBjbGljay4gKi9cbiAgcHJpdmF0ZSBfc3VwcHJlc3NPdXRzaWRlQ2xpY2tVbnRpbCA9IDA7XG4gIC8qKiBWaWV3cG9ydC1hbmNob3JlZCBwb3NpdGlvbiAoY2xpZW50IGNvb3JkaW5hdGVzKSBmb3IgdGhlIGZsb2F0aW5nIG1lbnUuXG4gICAqICBEcml2ZXMgdGhlIGludmlzaWJsZSBjZGtPdmVybGF5T3JpZ2luIGFuY2hvcjsgQ0RLIE92ZXJsYXkgdGhlbiBwaWNrcyB0aGVcbiAgICogIGJlc3Qgb2YgYGNvbnRleHRNZW51UG9zaXRpb25zYCBzbyB0aGUgbWVudSBuZXZlciBvdmVyZmxvd3MgdGhlIHZpZXdwb3J0LiAqL1xuICBjb250ZXh0TWVudVBvc2l0aW9uOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPSB7IHg6IDAsIHk6IDAgfTtcblxuICAvKiogUG9zaXRpb24gcHJpb3JpdHkgZm9yIHRoZSBDREstb3ZlcmxheS1yZW5kZXJlZCBjb250ZXh0IG1lbnUuIENESyB0cmllcyBlYWNoXG4gICAqICBpbiBvcmRlciBhbmQgdXNlcyB0aGUgZmlyc3Qgb25lIHRoYXQgZml0cyDigJQgc28gdGhlIG1lbnUgb3BlbnMgZG93bndhcmQgYnlcbiAgICogIGRlZmF1bHQgYW5kIGZsaXBzIHVwIC8gbGVmdCB3aGVuIHRvbyBjbG9zZSB0byB0aGUgYm90dG9tIG9yIHJpZ2h0IGVkZ2UuICovXG4gIHJlYWRvbmx5IGNvbnRleHRNZW51UG9zaXRpb25zOiBDb25uZWN0ZWRQb3NpdGlvbltdID0gW1xuICAgIHsgb3JpZ2luWDogJ3N0YXJ0Jywgb3JpZ2luWTogJ2JvdHRvbScsIG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ3RvcCcgfSxcbiAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnLCAgICBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nIH0sXG4gICAgeyBvcmlnaW5YOiAnZW5kJywgICBvcmlnaW5ZOiAnYm90dG9tJywgb3ZlcmxheVg6ICdlbmQnLCAgIG92ZXJsYXlZOiAndG9wJyB9LFxuICAgIHsgb3JpZ2luWDogJ2VuZCcsICAgb3JpZ2luWTogJ3RvcCcsICAgIG92ZXJsYXlYOiAnZW5kJywgICBvdmVybGF5WTogJ2JvdHRvbScgfSxcbiAgXTtcblxuICAvKiogUGVuZGluZyBhdXRvLWV4cGFuZCB0aW1lcnMgd2hpbGUgYSBmb2xkZXIgZHJhZyBpcyBob3ZlcmVkIG92ZXIgY29sbGFwc2VkIHJvd3MuICovXG4gIHByaXZhdGUgZHJhZ0V4cGFuZFRpbWVycyA9IG5ldyBNYXA8bnVtYmVyLCBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0Pj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBEUkFHX0VYUEFORF9ERUxBWV9NUyA9IDYwMDtcbiAgLyoqIElkIG9mIHRoZSBmb2xkZXIgY3VycmVudGx5IGJlaW5nIGRyYWdnZWQ7IHVzZWQgdG8gc2tpcCBjeWNsZSB0YXJnZXRzIGFuZCBzb3VyY2UtaG92ZXIgZXhwYW5zaW9uLiAqL1xuICBwcml2YXRlIGFjdGl2ZUZvbGRlckRyYWdJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIGdldCBleHBhbmRlZFNldCgpOiBTZXQ8bnVtYmVyPiB7XG4gICAgcmV0dXJuIG5ldyBTZXQodGhpcy5leHBhbmRlZEZvbGRlcklkcyB8fCBbXSk7XG4gIH1cblxuICAvKiogRmxhdHRlbmVkLCBkZXB0aC1hd2FyZSBsaXN0IG9mIHJvd3MgdG8gcmVuZGVyIGluIG9yZGVyLiBBbmNlc3RvcnMgb2YgbWF0Y2hlcyBhcmUga2VwdC4gKi9cbiAgZ2V0IHJvd3MoKTogUmVuZGVyTm9kZVtdIHtcbiAgICAvLyBTZXJ2ZXItc2lkZSBtb2RlOiBob3N0IHByZS1maWx0ZXJzIGBmb2xkZXJzYDsgd2Ugc2tpcCB0aGUgbG9jYWwgZmlsdGVyIHNvXG4gICAgLy8gcmVzdWx0cyBhcmVuJ3QgZG91YmxlLWZpbHRlcmVkIChiYWNrZW5kIG1heSB1c2UgZGlmZmVyZW50IGZ1enp5IGxvZ2ljKS5cbiAgICBjb25zdCBsb2NhbFNlYXJjaCA9IHRoaXMuc2VydmVyU2lkZVNlYXJjaFxuICAgICAgPyAnJ1xuICAgICAgOiAodGhpcy5zZWFyY2hWYWx1ZSB8fCAnJykudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgZXhwYW5kZWQgPSB0aGlzLmV4cGFuZGVkU2V0O1xuICAgIGNvbnN0IGtlZXBTZXQgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICBpZiAobG9jYWxTZWFyY2gpIHtcbiAgICAgIGNvbnN0IG1hcmsgPSAobm9kZXM6IEZvbGRlck5vZGVbXSwgYW5jZXN0b3JzOiBudW1iZXJbXSk6IHZvaWQgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IG4gb2Ygbm9kZXMgfHwgW10pIHtcbiAgICAgICAgICBjb25zdCBtYXRjaGVkID0gKG4ubmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhsb2NhbFNlYXJjaCk7XG4gICAgICAgICAgY29uc3QgY2hpbGRBbmNlc3RvcnMgPSBbLi4uYW5jZXN0b3JzLCBuLmlkXTtcbiAgICAgICAgICBpZiAobWF0Y2hlZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBhIG9mIGFuY2VzdG9ycykga2VlcFNldC5hZGQoYSk7XG4gICAgICAgICAgICBrZWVwU2V0LmFkZChuLmlkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG4uY2hpbGRyZW4/Lmxlbmd0aCkgbWFyayhuLmNoaWxkcmVuLCBjaGlsZEFuY2VzdG9ycyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBtYXJrKHRoaXMuZm9sZGVycywgW10pO1xuICAgIH1cblxuICAgIGNvbnN0IG91dDogUmVuZGVyTm9kZVtdID0gW107XG4gICAgY29uc3Qgd2FsayA9IChub2RlczogRm9sZGVyTm9kZVtdLCBkZXB0aDogbnVtYmVyLCBwYXJlbnRWaXNpYmxlOiBib29sZWFuKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG4gb2Ygbm9kZXMgfHwgW10pIHtcbiAgICAgICAgY29uc3Qgc2VhcmNoVmlzaWJsZSA9ICFsb2NhbFNlYXJjaCB8fCBrZWVwU2V0LmhhcyhuLmlkKTtcbiAgICAgICAgY29uc3QgdmlzaWJsZSA9IHBhcmVudFZpc2libGUgJiYgc2VhcmNoVmlzaWJsZTtcbiAgICAgICAgLy8gU2hvdyB0aGUgY2hldnJvbiB3aGVuIHRoZSBiYWNrZW5kIHNheXMgdGhpcyBmb2xkZXIgaGFzIGNoaWxkcmVuXG4gICAgICAgIC8vIChsYXp5LWxvYWQ6IGNoaWxkcmVuIG1heSBub3QgYmUgZmV0Y2hlZCB5ZXQpIE9SIHdoZW4gY2hpbGRyZW4gYXJlXG4gICAgICAgIC8vIGFscmVhZHkgcG9wdWxhdGVkIChlYWdlciBtb2RlIGZvciBjYWxsZXJzIHRoYXQgcHJlLWJ1aWxkIHRoZSB0cmVlKS5cbiAgICAgICAgY29uc3QgaGFzQ2hpbGRyZW4gPSAhIW4uaGFzQ2hpbGRyZW4gfHwgISEobi5jaGlsZHJlbiAmJiBuLmNoaWxkcmVuLmxlbmd0aCk7XG4gICAgICAgIG91dC5wdXNoKHsga2luZDogJ2ZvbGRlcicsIG5vZGU6IG4sIGRlcHRoLCB2aXNpYmxlLCBoYXNDaGlsZHJlbiB9KTtcbiAgICAgICAgY29uc3QgZXhwYW5kZWRCeVNlYXJjaCA9ICEhbG9jYWxTZWFyY2ggJiYga2VlcFNldC5oYXMobi5pZCk7XG4gICAgICAgIGNvbnN0IGlzTm9kZUV4cGFuZGVkID0gZXhwYW5kZWQuaGFzKG4uaWQpIHx8IGV4cGFuZGVkQnlTZWFyY2g7XG4gICAgICAgIGlmICghaXNOb2RlRXhwYW5kZWQgfHwgIWhhc0NoaWxkcmVuKSBjb250aW51ZTtcbiAgICAgICAgLy8gUmVjdXJzZSBmb3IgY2hpbGRyZW4gdGhhdCBhcmUgYWxyZWFkeSBpbiBtZW1vcnkuXG4gICAgICAgIGlmIChuLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgICAgICB3YWxrKG4uY2hpbGRyZW4sIGRlcHRoICsgMSwgdmlzaWJsZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQXBwZW5kIGxhenktbG9hZCBhZmZvcmRhbmNlcyBhdCB0aGUgZW5kIG9mIHRoZSBvcGVuIHN1YnRyZWU6XG4gICAgICAgIC8vIC0gJ2xvYWRpbmcnIHdoaWxlIGEgY2hpbGRyZW4tcGFnZSBmZXRjaCBpcyBpbiBmbGlnaHQuXG4gICAgICAgIC8vIC0gJ2xvYWQtbW9yZScgd2hlbiBtb3JlIGNoaWxkcmVuIGV4aXN0IG9uIHRoZSBiYWNrZW5kIHRoYW4gd2UgaGF2ZS5cbiAgICAgICAgaWYgKG4uY2hpbGRyZW5Mb2FkaW5nKSB7XG4gICAgICAgICAgb3V0LnB1c2goeyBraW5kOiAnbG9hZGluZycsIG5vZGU6IG4sIGRlcHRoOiBkZXB0aCArIDEsIHZpc2libGUsIGhhc0NoaWxkcmVuOiBmYWxzZSB9KTtcbiAgICAgICAgfSBlbHNlIGlmICgobi5jaGlsZHJlbj8ubGVuZ3RoID8/IDApIDwgKG4udG90YWxDaGlsZHJlbiA/PyAwKSkge1xuICAgICAgICAgIG91dC5wdXNoKHsga2luZDogJ2xvYWQtbW9yZScsIG5vZGU6IG4sIGRlcHRoOiBkZXB0aCArIDEsIHZpc2libGUsIGhhc0NoaWxkcmVuOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gICAgd2Fsayh0aGlzLmZvbGRlcnMsIDAsIHRydWUpO1xuICAgIHJldHVybiBvdXQuZmlsdGVyKHIgPT4gci52aXNpYmxlKTtcbiAgfVxuXG4gIGlzRXhwYW5kZWQoaWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmV4cGFuZGVkU2V0LmhhcyhpZCk7XG4gIH1cblxuICBpc1NlbGVjdGVkKGlkOiBudW1iZXIgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgaWYgKGlkID09IG51bGwgJiYgdGhpcy5zZWxlY3RlZEZvbGRlcklkID09IG51bGwpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBpZCAhPSBudWxsICYmIHRoaXMuc2VsZWN0ZWRGb2xkZXJJZCAhPSBudWxsICYmIGlkID09PSB0aGlzLnNlbGVjdGVkRm9sZGVySWQ7XG4gIH1cblxuICBvblRvZ2dsZShuOiBGb2xkZXJOb2RlLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBleHBhbmRlZCA9ICF0aGlzLmlzRXhwYW5kZWQobi5pZCk7XG4gICAgdGhpcy5mb2xkZXJFeHBhbnNpb25Ub2dnbGVkLmVtaXQoeyBpZDogbi5pZCwgZXhwYW5kZWQgfSk7XG4gICAgLy8gTGF6eSBmZXRjaDogaWYgdGhlIHVzZXIgaXMgZXhwYW5kaW5nIGEgbm9kZSB3aG9zZSBjaGlsZHJlbiBoYXZlbid0IGJlZW5cbiAgICAvLyBsb2FkZWQgeWV0LCBhc2sgdGhlIGhvc3QgdG8gZmV0Y2ggdGhlbS4gU2tpcCB3aGVuIG5vdCBsYXp5IChsb2FkZWRQYWdlc1xuICAgIC8vIGFscmVhZHkgc2V0KSBvciBub3QgZXhwYW5kaW5nLlxuICAgIGlmIChleHBhbmRlZCAmJiBuLmhhc0NoaWxkcmVuICYmIG4ubG9hZGVkUGFnZXMgPT0gbnVsbCkge1xuICAgICAgdGhpcy5mb2xkZXJDaGlsZHJlblJlcXVlc3RlZC5lbWl0KG4uaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZWFyY2ggaW5wdXQgaGFuZGxlcjogdXBkYXRlcyB0aGUgbG9jYWwgYHNlYXJjaFZhbHVlYCBpbW1lZGlhdGVseSAoc28gdGhlXG4gICAqICBpbnB1dCBzdGF5cyByZXNwb25zaXZlKSBhbmQgZGVib3VuY2VzIGBzZWFyY2hDaGFuZ2VgIGVtaXNzaW9ucyBzbyBhIGhvc3RcbiAgICogIGRvaW5nIHNlcnZlci1zaWRlIHNlYXJjaCBmaXJlcyBhdCBtb3N0IG9uZSByZXF1ZXN0IHBlciBwYXVzZS4gKi9cbiAgb25TZWFyY2hJbnB1dCh0ZXJtOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaFZhbHVlID0gdGVybTtcbiAgICBpZiAodGhpcy5zZWFyY2hFbWl0VGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnNlYXJjaEVtaXRUaW1lcik7XG4gICAgdGhpcy5zZWFyY2hFbWl0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc2VhcmNoQ2hhbmdlLmVtaXQodGhpcy5zZWFyY2hWYWx1ZSk7XG4gICAgICB0aGlzLnNlYXJjaEVtaXRUaW1lciA9IG51bGw7XG4gICAgfSwgRm9sZGVyU2lkZWJhckNvbXBvbmVudC5TRUFSQ0hfREVCT1VOQ0VfTVMpO1xuICB9XG5cbiAgLyoqIFNlYXJjaCBpbnB1dCBjbGVhciBoYW5kbGVyOiBmbHVzaGVzIHRoZSBkZWJvdW5jZSBzbyB0aGUgaG9zdCBzZWVzIGFuXG4gICAqICBlbXB0eSB0ZXJtIGltbWVkaWF0ZWx5IGFuZCBjYW4gcmVzdG9yZSB0aGUgbGF6eSB0cmVlLiAqL1xuICBvblNlYXJjaENsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoVmFsdWUgPSAnJztcbiAgICBpZiAodGhpcy5zZWFyY2hFbWl0VGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNlYXJjaEVtaXRUaW1lcik7XG4gICAgICB0aGlzLnNlYXJjaEVtaXRUaW1lciA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc2VhcmNoQ2hhbmdlLmVtaXQoJycpO1xuICB9XG5cbiAgLyoqIExhenktbG9hZDogdXNlciBjbGlja2VkIHRoZSBwZXItZm9sZGVyIFwiTG9hZCBtb3JlXCIgcm93LiBUaGUgc2lkZWJhciB0cmFja3NcbiAgICogIHBhZ2luYXRpb24gdmlhIGBub2RlLmxvYWRlZFBhZ2VzYDsgdGhlIG5leHQgcGFnZSBpcyBsb2FkZWRQYWdlcyArIDEuICovXG4gIG9uTG9hZE1vcmUobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIGlmIChuLmxvYWRlZFBhZ2VzID09IG51bGwpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlckxvYWRNb3JlUmVxdWVzdGVkLmVtaXQoeyBpZDogbi5pZCwgbmV4dFBhZ2U6IG4ubG9hZGVkUGFnZXMgKyAxIH0pO1xuICB9XG5cbiAgLyoqIENhY2hlZCBgZm9sZGVycy5sZW5ndGhgIGF0IHRoZSBtb21lbnQgd2UgbGFzdCBlbWl0dGVkIGByb290TG9hZE1vcmVSZXF1ZXN0ZWRgLlxuICAgKiAgVXNlZCB0byB0aHJvdHRsZSB0aGUgc2Nyb2xsLWJhc2VkIHBhZ2luYXRpb24gc28gd2UgZG9uJ3QgcmUtZW1pdCB1bnRpbCB0aGVcbiAgICogIGhvc3QgaGFzIGFjdHVhbGx5IGFwcGVuZGVkIGEgbmV3IHBhZ2UuICovXG4gIHByaXZhdGUgbGFzdFJvb3RMb2FkRW1pdHRlZEF0OiBudW1iZXIgPSAtMTtcbiAgLyoqIFRocmVzaG9sZCAocHgpIGZvciBcIm5lYXIgdGhlIGJvdHRvbVwiIOKAlCBlbWl0IGEgbG9hZC1tb3JlIG9uY2UgdGhlIHNjcm9sbFxuICAgKiAgcG9zaXRpb24gaXMgd2l0aGluIHRoaXMgbWFueSBweCBvZiB0aGUgZW5kLiAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBTQ1JPTExfTE9BRF9USFJFU0hPTERfUFggPSA2NDtcblxuICAvKiogVmVydGljYWwtc2Nyb2xsIGhhbmRsZXIgZm9yIHRoZSByb290LWZvbGRlciBsaXN0LiBGaXJlcyBgcm9vdExvYWRNb3JlUmVxdWVzdGVkYFxuICAgKiAgd2hlbiB0aGUgdXNlciBzY3JvbGxzIHdpdGhpbiB0aGUgdGhyZXNob2xkIG9mIHRoZSBib3R0b20gYW5kIG1vcmUgcm9vdHNcbiAgICogIGFyZSBhdmFpbGFibGUgb24gdGhlIGJhY2tlbmQuIFN1cHByZXNzZWQgZHVyaW5nIHNpZGViYXIgc2VhcmNoLiAqL1xuICBvblRyZWVTY3JvbGwoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VhcmNoVmFsdWU/LnRyaW0oKSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmZvbGRlcnMubGVuZ3RoID49IHRoaXMucm9vdFRvdGFsKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZm9sZGVycy5sZW5ndGggPT09IHRoaXMubGFzdFJvb3RMb2FkRW1pdHRlZEF0KSByZXR1cm47XG4gICAgY29uc3QgZWwgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgIGlmICghZWwpIHJldHVybjtcbiAgICBjb25zdCBkaXN0YW5jZUZyb21Cb3R0b20gPSBlbC5zY3JvbGxIZWlnaHQgLSAoZWwuc2Nyb2xsVG9wICsgZWwuY2xpZW50SGVpZ2h0KTtcbiAgICBpZiAoZGlzdGFuY2VGcm9tQm90dG9tID4gRm9sZGVyU2lkZWJhckNvbXBvbmVudC5TQ1JPTExfTE9BRF9USFJFU0hPTERfUFgpIHJldHVybjtcbiAgICB0aGlzLmxhc3RSb290TG9hZEVtaXR0ZWRBdCA9IHRoaXMuZm9sZGVycy5sZW5ndGg7XG4gICAgdGhpcy5yb290TG9hZE1vcmVSZXF1ZXN0ZWQuZW1pdCgpO1xuICB9XG5cbiAgb25TZWxlY3QobjogRm9sZGVyTm9kZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5yZW5hbWluZ0lkICE9IG51bGwpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlclNlbGVjdGVkLmVtaXQobiA9PSBudWxsID8gbnVsbCA6IG4uaWQpO1xuICB9XG5cbiAgb25TZWxlY3RVbm9yZ2FuaXplZCgpOiB2b2lkIHtcbiAgICAvLyBTZW50aW5lbDogaG9zdHMgdGhhdCBrZWVwIGFuIFwiVW5vcmdhbml6ZWRcIiBidWNrZXQgY2FuIHRyZWF0IGEgbnVsbCBzZWxlY3Rpb25cbiAgICAvLyBhcyBcInNob3cgdW5vcmdhbml6ZWRcIi4gSWYgdGhlcmUgaXMgYWxyZWFkeSBhIHJvb3QgKG51bGwpIHNlbGVjdGlvbiBwYXR0ZXJuLFxuICAgIC8vIHRoaXMgbWF0Y2hlcyBpdC4gSG9zdCBkZWNpZGVzIHNlbWFudGljcy5cbiAgICB0aGlzLmZvbGRlclNlbGVjdGVkLmVtaXQobnVsbCk7XG4gIH1cblxuICBiZWdpblJlbmFtZShuOiBGb2xkZXJOb2RlLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYWxsb3dSZW5hbWUpIHJldHVybjtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLnJlbmFtaW5nSWQgPSBuLmlkO1xuICAgIHRoaXMucmVuYW1lRHJhZnQgPSBuLm5hbWU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgdGhpcy5mb2N1c1JlbmFtZUlucHV0KG4uaWQpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIHJlbmFtZSBkcmFmdCBwYXNzZXMgdGhlIG5hbWUgcnVsZXMgKG5vbi1lbXB0eSwgd2l0aGluIG1heCBsZW5ndGgpLiAqL1xuICBnZXQgaXNSZW5hbWVEcmFmdFZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHRyaW1tZWQgPSAodGhpcy5yZW5hbWVEcmFmdCB8fCAnJykudHJpbSgpO1xuICAgIHJldHVybiB0cmltbWVkLmxlbmd0aCA+IDAgJiYgdHJpbW1lZC5sZW5ndGggPD0gdGhpcy5yZW5hbWVNYXhMZW5ndGg7XG4gIH1cblxuICBjb21taXRSZW5hbWUobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIC8vIERpc2NhcmQgaW52YWxpZCBkcmFmdHMgKGVtcHR5IC8gdG9vIGxvbmcpIGluc3RlYWQgb2YgY29tbWl0dGluZyBhIGJhZCBuYW1lLlxuICAgIC8vIFRoZSB1c2VyIHNlZXMgdGhlIHJlZCBib3JkZXIgd2hpbGUgZWRpdGluZzsgb24gYmx1ciB3ZSByZXZlcnQgdG8gdGhlIG9yaWdpbmFsLlxuICAgIGlmICghdGhpcy5pc1JlbmFtZURyYWZ0VmFsaWQpIHtcbiAgICAgIHRoaXMuY2FuY2VsUmVuYW1lKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5hbWUgPSAodGhpcy5yZW5hbWVEcmFmdCB8fCAnJykudHJpbSgpO1xuICAgIGlmIChuYW1lICE9PSBuLm5hbWUpIHtcbiAgICAgIC8vIEVtaXQgdGhlIGZ1bGwgcmVuYW1lZCBub2RlICh3aXRoIHRoZSBuZXcgbmFtZSkgKyBwYXJlbnQgY29udGV4dCBzbyBob3N0cyBjYW5cbiAgICAgIC8vIGNhbGwgYFBVVCAvdGVzdF9jYXNlX2ZvbGRlcnMve2lkfWAgd2l0aG91dCByZS1yZXNvbHZpbmcgZnJvbSB0aGVpciBjYWNoZWQgdHJlZS5cbiAgICAgIGNvbnN0IGZvbGRlcjogRm9sZGVyTm9kZSA9IHsgLi4ubiwgbmFtZSB9O1xuICAgICAgdGhpcy5mb2xkZXJSZW5hbWVkLmVtaXQoe1xuICAgICAgICBmb2xkZXIsXG4gICAgICAgIHBhcmVudElkOiB0aGlzLnBhcmVudElkT2Yobi5pZCksXG4gICAgICAgIHByZXZpb3VzTmFtZTogbi5uYW1lLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuY2FuY2VsUmVuYW1lKCk7XG4gIH1cblxuICBjYW5jZWxSZW5hbWUoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5hbWluZ0lkID0gbnVsbDtcbiAgICB0aGlzLnJlbmFtZURyYWZ0ID0gJyc7XG4gICAgdGhpcy5jbGVhclJlbmFtZUxpbWl0Rmxhc2goKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uUmVuYW1lS2V5KGV2ZW50OiBLZXlib2FyZEV2ZW50LCBuOiBGb2xkZXJOb2RlKTogdm9pZCB7XG4gICAgLy8gU3RvcCBidWJibGluZyBzbyB0aGUgcm93J3Mga2V5ZG93biBoYW5kbGVyICh3aGljaCB0cmVhdHMgU3BhY2UvRW50ZXIvQXJyb3dzIGFzXG4gICAgLy8gc2VsZWN0aW9uIC8gdHJlZSBuYXZpZ2F0aW9uKSBjYW4ndCBzd2FsbG93IGNoYXJhY3RlcnMgdHlwZWQgaW50byB0aGUgcmVuYW1lIGlucHV0LlxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAvLyBEb24ndCBzd2FsbG93IHRoZSB1c2VyJ3MgZWRpdCBvbiBFbnRlciB3aGVuIHRoZSBkcmFmdCBpcyBpbnZhbGlkIOKAlCBrZWVwXG4gICAgICAvLyB0aGUgaW5wdXQgb3BlbiAocmVkIGJvcmRlciBhbHJlYWR5IHNpZ25hbHMgdGhlIGlzc3VlKSBhbmQgbGV0IHRoZW0gZml4IGl0LlxuICAgICAgaWYgKCF0aGlzLmlzUmVuYW1lRHJhZnRWYWxpZCkgcmV0dXJuO1xuICAgICAgdGhpcy5jb21taXRSZW5hbWUobik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5jYW5jZWxSZW5hbWUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRm9yIGFueSBvdGhlciBrZXlzdHJva2UsIGRldGVjdCBcInVzZXIgaXMgdHJ5aW5nIHRvIHR5cGUgcGFzdCBtYXhsZW5ndGhcIiBhbmRcbiAgICAvLyBicmllZmx5IGZsYXNoIHRoZSBpbnB1dCByZWQuIFRoZSBicm93c2VyJ3MgYG1heGxlbmd0aGAgYXR0cmlidXRlIGFscmVhZHlcbiAgICAvLyBzaWxlbnRseSBibG9ja3MgdGhlIGNoYXJhY3RlcjsgdGhpcyBzdXJmYWNlcyBhIHZpc2libGUgXCJ5b3UndmUgaGl0IHRoZSBjYXBcIlxuICAgIC8vIHNpZ25hbCB0aGF0IHdvdWxkIG90aGVyd2lzZSBiZSBtaXNzaW5nLlxuICAgIGlmICh0aGlzLmlzUHJpbnRhYmxlS2V5KGV2ZW50KSAmJiB0aGlzLndvdWxkRXhjZWVkUmVuYW1lTGltaXQoZXZlbnQpKSB7XG4gICAgICB0aGlzLnRyaWdnZXJSZW5hbWVMaW1pdEZsYXNoKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1ByaW50YWJsZUtleShldmVudDogS2V5Ym9hcmRFdmVudCk6IGJvb2xlYW4ge1xuICAgIC8vIFNpbmdsZS1jaGFyYWN0ZXIga2V5cyBhcmUgcHJpbnRhYmxlcyAoYSwgQiwgMSwgISwgc3BhY2UpLiBNb2RpZmllci1kcml2ZW5cbiAgICAvLyBzaG9ydGN1dHMgKEN0cmwvTWV0YSkgc2hvdWxkbid0IGNvdW50IOKAlCB0aGV5IGRvbid0IGluc2VydCB0ZXh0LlxuICAgIHJldHVybiBldmVudC5rZXkubGVuZ3RoID09PSAxICYmICFldmVudC5jdHJsS2V5ICYmICFldmVudC5tZXRhS2V5ICYmICFldmVudC5hbHRLZXk7XG4gIH1cblxuICBwcml2YXRlIHdvdWxkRXhjZWVkUmVuYW1lTGltaXQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiBib29sZWFuIHtcbiAgICAvLyBUaGUgbmV3IGxlbmd0aCBhZnRlciB0aGUga2V5c3Ryb2tlIHdvdWxkIGJlOiBjdXJyZW50IC0gc2VsZWN0aW9uTGVuZ3RoICsgMS5cbiAgICAvLyBJZiBhIHNlbGVjdGlvbiBjb3ZlcnMgcGFydCBvZiB0aGUgdmFsdWUsIHR5cGluZyByZXBsYWNlcyB0aGF0IHJhbmdlLCBzbyB0aGVcbiAgICAvLyBuZXQgbGVuZ3RoIG1pZ2h0IHN0aWxsIGZpdCB1bmRlciB0aGUgY2FwLlxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50IHwgbnVsbDtcbiAgICBjb25zdCBzdGFydCA9IHRhcmdldD8uc2VsZWN0aW9uU3RhcnQgPz8gMDtcbiAgICBjb25zdCBlbmQgPSB0YXJnZXQ/LnNlbGVjdGlvbkVuZCA/PyAwO1xuICAgIGNvbnN0IHNlbGVjdGVkTGVuID0gTWF0aC5tYXgoMCwgZW5kIC0gc3RhcnQpO1xuICAgIGNvbnN0IGRyYWZ0TGVuID0gKHRoaXMucmVuYW1lRHJhZnQgfHwgJycpLmxlbmd0aDtcbiAgICByZXR1cm4gZHJhZnRMZW4gLSBzZWxlY3RlZExlbiA+PSB0aGlzLnJlbmFtZU1heExlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgdHJpZ2dlclJlbmFtZUxpbWl0Rmxhc2goKTogdm9pZCB7XG4gICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbmFtZUxpbWl0Rmxhc2hUaW1lcik7XG4gICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMucmVuYW1lTGltaXRGbGFzaCA9IGZhbHNlO1xuICAgICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIgPSBudWxsO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSwgRm9sZGVyU2lkZWJhckNvbXBvbmVudC5SRU5BTUVfTElNSVRfRkxBU0hfTVMpO1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclJlbmFtZUxpbWl0Rmxhc2goKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVuYW1lTGltaXRGbGFzaFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIpO1xuICAgICAgdGhpcy5yZW5hbWVMaW1pdEZsYXNoVGltZXIgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLnJlbmFtZUxpbWl0Rmxhc2ggPSBmYWxzZTtcbiAgfVxuXG4gIGRlbGV0ZUZvbGRlcihuOiBGb2xkZXJOb2RlLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYWxsb3dEZWxldGUpIHJldHVybjtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmZvbGRlckRlbGV0ZWQuZW1pdCh7IGlkOiBuLmlkIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW5zIHRoZSBmb2xkZXIgY29udGV4dCBtZW51IGFuY2hvcmVkIGF0IHRoZSBnaXZlbiBjbGllbnQgY29vcmRpbmF0ZXMuXG4gICAqIENhbGxlZCBmcm9tIGJvdGggKGNvbnRleHRtZW51KSBvbiB0aGUgcm93IGFuZCAoY2xpY2spIG9uIHRoZSBlbGxpcHNpcyBidXR0b24uXG4gICAqIFRoZSB0ZW1wbGF0ZSByZW5kZXJzIHRoZSBtZW51IHZpYSBjZGtDb25uZWN0ZWRPdmVybGF5IGFuY2hvcmVkIG9uIGFuXG4gICAqIGludmlzaWJsZSAww5cwIG9yaWdpbiBhdCBgY29udGV4dE1lbnVQb3NpdGlvbmA7IENESydzIGZsZXhpYmxlLWNvbm5lY3RlZFxuICAgKiBwb3NpdGlvbmluZyBhdXRvLWZsaXBzIHVwL2xlZnQgd2hlbiB0aGUgcHJlZmVycmVkIHBsYWNlbWVudCB3b3VsZCBvdmVyZmxvd1xuICAgKiB0aGUgdmlld3BvcnQgKGUuZy4gcmlnaHQtY2xpY2tpbmcgdGhlIGxhc3QgZm9sZGVyIG5lYXIgdGhlIGJvdHRvbSBlZGdlKS5cbiAgICovXG4gIG9wZW5Db250ZXh0TWVudShuOiBGb2xkZXJOb2RlLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmhhc0FueUNvbnRleHRBY3Rpb24pIHJldHVybjtcbiAgICB0aGlzLmNvbnRleHRNZW51Rm9sZGVySWQgPSBuLmlkO1xuICAgIHRoaXMuY29udGV4dE1lbnVQb3NpdGlvbiA9IHsgeDogZXZlbnQuY2xpZW50WCwgeTogZXZlbnQuY2xpZW50WSB9O1xuICAgIC8vIENESydzIG91dHNpZGUtY2xpY2sgZGlzcGF0Y2hlciBhdHRhY2hlcyBib2R5LWxldmVsIGNhcHR1cmUtcGhhc2UgbGlzdGVuZXJzXG4gICAgLy8gZm9yIGNsaWNrL2F1eGNsaWNrL2NvbnRleHRtZW51LiBPbiByaWdodC1jbGljayB0aGUgY29udGV4dG1lbnUrYXV4Y2xpY2tcbiAgICAvLyBldmVudHMgZmlyZSBvbiB0aGUgc2FtZSBnZXN0dXJlIHRoYXQgb3BlbmVkIHRoZSBtZW51LCB3aGljaCB3b3VsZFxuICAgIC8vIGltbWVkaWF0ZWx5IGNsb3NlIGl0LiBTdXBwcmVzcyBvdXRzaWRlLWNsaWNrIGhhbmRsaW5nIGZvciBhIHNob3J0IHdpbmRvdy5cbiAgICB0aGlzLl9zdXBwcmVzc091dHNpZGVDbGlja1VudGlsID0gRGF0ZS5ub3coKSArIDI1MDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG9uT3ZlcmxheU91dHNpZGVDbGljaygpOiB2b2lkIHtcbiAgICBpZiAoRGF0ZS5ub3coKSA8IHRoaXMuX3N1cHByZXNzT3V0c2lkZUNsaWNrVW50aWwpIHJldHVybjtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgfVxuXG4gIGNsb3NlQ29udGV4dE1lbnUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29udGV4dE1lbnVGb2xkZXJJZCA9PSBudWxsKSByZXR1cm47XG4gICAgdGhpcy5jb250ZXh0TWVudUZvbGRlcklkID0gbnVsbDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoZW4gYXQgbGVhc3Qgb25lIG1lbnUgZW50cnkgaXMgZW5hYmxlZCDigJQgb3RoZXJ3aXNlIHRoZSB0cmlnZ2VyIGlzIHN1cHByZXNzZWQgZW50aXJlbHkuICovXG4gIGdldCBoYXNBbnlDb250ZXh0QWN0aW9uKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmFsbG93Q3JlYXRlIHx8IHRoaXMuYWxsb3dSZW5hbWUgfHwgdGhpcy5hbGxvd01vdmUgfHwgdGhpcy5hbGxvd0R1cGxpY2F0ZSB8fCB0aGlzLmFsbG93RGVsZXRlO1xuICB9XG5cbiAgb25Db250ZXh0Q3JlYXRlU3ViZm9sZGVyKG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dDcmVhdGUpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlckNyZWF0ZVJlcXVlc3RlZC5lbWl0KHsgcGFyZW50SWQ6IG4uaWQgfSk7XG4gIH1cblxuICBvbkNvbnRleHRSZW5hbWUobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VDb250ZXh0TWVudSgpO1xuICAgIGlmICghdGhpcy5hbGxvd1JlbmFtZSkgcmV0dXJuO1xuICAgIHRoaXMucmVuYW1pbmdJZCA9IG4uaWQ7XG4gICAgdGhpcy5yZW5hbWVEcmFmdCA9IG4ubmFtZTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB0aGlzLmZvY3VzUmVuYW1lSW5wdXQobi5pZCk7XG4gIH1cblxuICBvbkNvbnRleHRNb3ZlKG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dNb3ZlKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJNb3ZlUmVxdWVzdGVkLmVtaXQoeyBpZDogbi5pZCB9KTtcbiAgfVxuXG4gIG9uQ29udGV4dER1cGxpY2F0ZShuOiBGb2xkZXJOb2RlKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUNvbnRleHRNZW51KCk7XG4gICAgaWYgKCF0aGlzLmFsbG93RHVwbGljYXRlKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJEdXBsaWNhdGVSZXF1ZXN0ZWQuZW1pdCh7IGlkOiBuLmlkIH0pO1xuICB9XG5cbiAgb25Db250ZXh0RGVsZXRlKG46IEZvbGRlck5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlQ29udGV4dE1lbnUoKTtcbiAgICBpZiAoIXRoaXMuYWxsb3dEZWxldGUpIHJldHVybjtcbiAgICB0aGlzLmZvbGRlckRlbGV0ZWQuZW1pdCh7IGlkOiBuLmlkIH0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snKVxuICBvbkRvY3VtZW50Q2xpY2soKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZUNvbnRleHRNZW51KCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScpXG4gIG9uRXNjYXBlKCk6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VDb250ZXh0TWVudSgpO1xuICB9XG5cbiAgLyoqIFRlbXBsYXRlIGhlbHBlcjogcmVzb2x2ZSBhIGZvbGRlciBub2RlIGJ5IGlkIGZyb20gdGhlIGlucHV0IHRyZWUuICovXG4gIGZvbGRlckJ5SWQoaWQ6IG51bWJlciB8IG51bGwpOiBGb2xkZXJOb2RlIHwgbnVsbCB7XG4gICAgaWYgKGlkID09IG51bGwpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IGZpbmQgPSAobm9kZXM6IEZvbGRlck5vZGVbXSk6IEZvbGRlck5vZGUgfCBudWxsID0+IHtcbiAgICAgIGZvciAoY29uc3QgbiBvZiBub2RlcyB8fCBbXSkge1xuICAgICAgICBpZiAobi5pZCA9PT0gaWQpIHJldHVybiBuO1xuICAgICAgICBpZiAobi5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgICAgY29uc3QgaGl0ID0gZmluZChuLmNoaWxkcmVuKTtcbiAgICAgICAgICBpZiAoaGl0KSByZXR1cm4gaGl0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIHJldHVybiBmaW5kKHRoaXMuZm9sZGVycyk7XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgcGFyZW50IGlkIG9mIGBpZGAsIG9yIG51bGwgd2hlbiBgaWRgIGlzIGEgcm9vdCBmb2xkZXIgLyBub3QgZm91bmQuICovXG4gIHByaXZhdGUgcGFyZW50SWRPZihpZDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgbGV0IHJlc3VsdDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgd2FsayA9IChub2RlczogRm9sZGVyTm9kZVtdLCBwYXJlbnRJZDogbnVtYmVyIHwgbnVsbCk6IGJvb2xlYW4gPT4ge1xuICAgICAgZm9yIChjb25zdCBuIG9mIG5vZGVzIHx8IFtdKSB7XG4gICAgICAgIGlmIChuLmlkID09PSBpZCkge1xuICAgICAgICAgIHJlc3VsdCA9IHBhcmVudElkO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuLmNoaWxkcmVuPy5sZW5ndGggJiYgd2FsayhuLmNoaWxkcmVuLCBuLmlkKSkgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICB3YWxrKHRoaXMuZm9sZGVycywgbnVsbCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHJlcXVlc3RDcmVhdGUocGFyZW50SWQ6IG51bWJlciB8IG51bGwgPSBudWxsKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmFsbG93Q3JlYXRlKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJDcmVhdGVSZXF1ZXN0ZWQuZW1pdCh7IHBhcmVudElkIH0pO1xuICB9XG5cbiAgdG9nZ2xlUGFuZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jb2xsYXBzZWQgPSAhdGhpcy5jb2xsYXBzZWQ7XG4gICAgaWYgKHRoaXMuY29sbGFwc2VkKSB0aGlzLnNlYXJjaFZpc2libGUgPSBmYWxzZTtcbiAgICB0aGlzLmNvbGxhcHNlZENoYW5nZS5lbWl0KHRoaXMuY29sbGFwc2VkKTtcbiAgfVxuXG4gIHRvZ2dsZUZvbGRlcnNBY2NvcmRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5mb2xkZXJzQWNjb3JkaW9uRXhwYW5kZWQgPSAhdGhpcy5mb2xkZXJzQWNjb3JkaW9uRXhwYW5kZWQ7XG4gICAgaWYgKCF0aGlzLmZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZCkgdGhpcy5zZWFyY2hWaXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5mb2xkZXJzQWNjb3JkaW9uRXhwYW5kZWRDaGFuZ2UuZW1pdCh0aGlzLmZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZCk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKiogVG9nZ2xlcyB0aGUgaW5saW5lIGZvbGRlci1zZWFyY2ggaW5wdXQuIFdoZW4gY2xvc2luZyB3aGlsZSBhIHF1ZXJ5IGlzIGFjdGl2ZSxcbiAgICogIGFsc28gY2xlYXIgdGhlIHNlYXJjaCBzbyB0aGUgdHJlZSByZXZlcnRzIHRvIGl0cyBmdWxsIHN0YXRlLiAqL1xuICBzZWFyY2hWaXNpYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIHRvZ2dsZVNlYXJjaFZpc2libGUoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZCAmJiAhdGhpcy5zZWFyY2hWaXNpYmxlKSB7XG4gICAgICB0aGlzLmZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZCA9IHRydWU7XG4gICAgICB0aGlzLmZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZENoYW5nZS5lbWl0KHRydWUpO1xuICAgIH1cbiAgICB0aGlzLnNlYXJjaFZpc2libGUgPSAhdGhpcy5zZWFyY2hWaXNpYmxlO1xuICAgIGlmICghdGhpcy5zZWFyY2hWaXNpYmxlICYmICh0aGlzLnNlYXJjaFZhbHVlIHx8ICcnKS50cmltKCkpIHtcbiAgICAgIHRoaXMub25TZWFyY2hDbGVhcigpO1xuICAgIH1cbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHJvd0Ryb3BwZWQodGFyZ2V0SWQ6IG51bWJlciB8IG51bGwsIGV2ZW50OiB7IHRlc3RJZHM6IEFycmF5PHN0cmluZyB8IG51bWJlcj47IHRhcmdldEZvbGRlcklkOiBudW1iZXIgfCBudWxsIH0pOiB2b2lkIHtcbiAgICAvLyBEaXJlY3RpdmUgYWxyZWFkeSBlbWl0cyB3aXRoIHRoZSBib3VuZCBmb2xkZXIgaWQsIGJ1dCBub3JtYWxpc2UgaW4gY2FzZSBjYWxsZXJzXG4gICAgLy8gd2lyZSByYXcgZXZlbnRzLlxuICAgIHRoaXMudGVzdHNEcm9wcGVkLmVtaXQoeyB0ZXN0SWRzOiBldmVudC50ZXN0SWRzLCB0YXJnZXRGb2xkZXJJZDogdGFyZ2V0SWQgfSk7XG4gIH1cblxuICAvKipcbiAgICogRHJvcCB0YXJnZXQgcmVjZWl2ZWQgYSBmb2xkZXIgZHJhZy4gVmFsaWRhdGUgYWdhaW5zdCBzZWxmL2Rlc2NlbmRhbnQgY3ljbGVzIGFuZFxuICAgKiBlbWl0IGBmb2xkZXJEcm9wcGVkYCBpZiB0aGUgbW92ZSBpcyBsZWdhbC4gQ2FsbGVkIGZyb20gdGhlIGRpcmVjdGl2ZSdzXG4gICAqIGAoZm9sZGVyRHJvcHBlZClgIG91dHB1dCBvbiBldmVyeSByb3cgYW5kIG9uIHRoZSBVbm9yZ2FuaXplZCByb3cuXG4gICAqL1xuICBvbkZvbGRlclJvd0Ryb3BwZWQodGFyZ2V0SWQ6IG51bWJlciB8IG51bGwsIGV2ZW50OiB7IGZvbGRlcklkOiBudW1iZXI7IHRhcmdldEZvbGRlcklkOiBudW1iZXIgfCBudWxsIH0pOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyQWxsRXhwYW5kVGltZXJzKCk7XG4gICAgdGhpcy5hY3RpdmVGb2xkZXJEcmFnSWQgPSBudWxsO1xuICAgIGNvbnN0IHNvdXJjZUlkID0gZXZlbnQuZm9sZGVySWQ7XG4gICAgaWYgKHRhcmdldElkICE9IG51bGwgJiYgdGFyZ2V0SWQgPT09IHNvdXJjZUlkKSByZXR1cm47XG4gICAgaWYgKHRhcmdldElkICE9IG51bGwgJiYgdGhpcy5pc0Rlc2NlbmRhbnRPZihzb3VyY2VJZCwgdGFyZ2V0SWQpKSByZXR1cm47XG4gICAgdGhpcy5mb2xkZXJEcm9wcGVkLmVtaXQoeyBpZDogc291cmNlSWQsIG5ld1BhcmVudElkOiB0YXJnZXRJZCB9KTtcbiAgfVxuXG4gIC8qKiBSZW1lbWJlciB0aGUgZHJhZ2dlZCBmb2xkZXIgc28gd2UgY2FuIGJsb2NrIHNlbGYtaG92ZXIgZXhwYW5zaW9uIGFuZCBjeWNsZSBkcm9wcy4gKi9cbiAgb25Gb2xkZXJEcmFnU3RhcnQobjogRm9sZGVyTm9kZSk6IHZvaWQge1xuICAgIHRoaXMuYWN0aXZlRm9sZGVyRHJhZ0lkID0gbi5pZDtcbiAgfVxuXG4gIG9uRm9sZGVyRHJhZ0VuZCgpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZUZvbGRlckRyYWdJZCA9IG51bGw7XG4gICAgdGhpcy5jbGVhckFsbEV4cGFuZFRpbWVycygpO1xuICB9XG5cbiAgLyoqIFNjaGVkdWxlIGFuIGF1dG8tZXhwYW5kIGZvciBhIGNvbGxhcHNlZCBmb2xkZXIgdGhhdCBoYXMgY2hpbGRyZW4gZHVyaW5nIGRyYWctaG92ZXIuICovXG4gIG9uRm9sZGVyUm93RHJhZ092ZXIocm93OiBSZW5kZXJOb2RlKTogdm9pZCB7XG4gICAgY29uc3QgaWQgPSByb3cubm9kZS5pZDtcbiAgICBpZiAoIXJvdy5oYXNDaGlsZHJlbikgcmV0dXJuO1xuICAgIGlmICh0aGlzLmlzRXhwYW5kZWQoaWQpKSByZXR1cm47XG4gICAgaWYgKHRoaXMuYWN0aXZlRm9sZGVyRHJhZ0lkID09PSBpZCkgcmV0dXJuOyAvLyBkb24ndCBleHBhbmQgdGhlIHNvdXJjZVxuICAgIGlmICh0aGlzLmRyYWdFeHBhbmRUaW1lcnMuaGFzKGlkKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmRyYWdFeHBhbmRUaW1lcnMuZGVsZXRlKGlkKTtcbiAgICAgIGlmICghdGhpcy5pc0V4cGFuZGVkKGlkKSkge1xuICAgICAgICB0aGlzLmZvbGRlckV4cGFuc2lvblRvZ2dsZWQuZW1pdCh7IGlkLCBleHBhbmRlZDogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICB9LCB0aGlzLkRSQUdfRVhQQU5EX0RFTEFZX01TKTtcbiAgICB0aGlzLmRyYWdFeHBhbmRUaW1lcnMuc2V0KGlkLCB0aW1lcik7XG4gIH1cblxuICBvbkZvbGRlclJvd0RyYWdMZWF2ZShyb3c6IFJlbmRlck5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHJvdy5ub2RlLmlkO1xuICAgIGNvbnN0IHRpbWVyID0gdGhpcy5kcmFnRXhwYW5kVGltZXJzLmdldChpZCk7XG4gICAgaWYgKHRpbWVyICE9IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB0aGlzLmRyYWdFeHBhbmRUaW1lcnMuZGVsZXRlKGlkKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpkcmFnZW5kJylcbiAgb25Eb2N1bWVudERyYWdFbmQoKTogdm9pZCB7XG4gICAgdGhpcy5vbkZvbGRlckRyYWdFbmQoKTtcbiAgfVxuXG4gIC8qKiBUcnVlIHdoZW4gYGNhbmRpZGF0ZUlkYCBpcyBgc291cmNlSWRgIGl0c2VsZiBvciBhbnkgZGVzY2VuZGFudCBvZiBpdC4gKi9cbiAgcHJpdmF0ZSBpc0Rlc2NlbmRhbnRPZihzb3VyY2VJZDogbnVtYmVyLCBjYW5kaWRhdGVJZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc291cmNlID0gdGhpcy5mb2xkZXJCeUlkKHNvdXJjZUlkKTtcbiAgICBpZiAoIXNvdXJjZSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHN0YWNrOiBGb2xkZXJOb2RlW10gPSBbc291cmNlXTtcbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgICBjb25zdCBuID0gc3RhY2sucG9wKCkhO1xuICAgICAgaWYgKG4uaWQgPT09IGNhbmRpZGF0ZUlkKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChuLmNoaWxkcmVuPy5sZW5ndGgpIHN0YWNrLnB1c2goLi4ubi5jaGlsZHJlbik7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJBbGxFeHBhbmRUaW1lcnMoKTogdm9pZCB7XG4gICAgdGhpcy5kcmFnRXhwYW5kVGltZXJzLmZvckVhY2godCA9PiBjbGVhclRpbWVvdXQodCkpO1xuICAgIHRoaXMuZHJhZ0V4cGFuZFRpbWVycy5jbGVhcigpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhckFsbEV4cGFuZFRpbWVycygpO1xuICAgIHRoaXMuY2xlYXJSZW5hbWVMaW1pdEZsYXNoKCk7XG4gICAgaWYgKHRoaXMuc2VhcmNoRW1pdFRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5zZWFyY2hFbWl0VGltZXIpO1xuICAgICAgdGhpcy5zZWFyY2hFbWl0VGltZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHRyYWNrQnlSb3cgPSAoXzogbnVtYmVyLCByb3c6IFJlbmRlck5vZGUpID0+IGAke3Jvdy5raW5kfV8ke3Jvdy5ub2RlLmlkfWA7XG5cbiAgb25Sb3dLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50LCByb3c6IFJlbmRlck5vZGUsIGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCByb3dzID0gdGhpcy5yb3dzO1xuICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICBjYXNlICdBcnJvd0Rvd24nOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IG5leHQgPSByb3dzW2luZGV4ICsgMV07XG4gICAgICAgIGlmIChuZXh0KSB0aGlzLmZvY3VzUm93RWxlbWVudChuZXh0Lm5vZGUuaWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0Fycm93VXAnOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IHByZXYgPSByb3dzW2luZGV4IC0gMV07XG4gICAgICAgIGlmIChwcmV2KSB0aGlzLmZvY3VzUm93RWxlbWVudChwcmV2Lm5vZGUuaWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOiB7XG4gICAgICAgIGlmIChyb3cuaGFzQ2hpbGRyZW4gJiYgIXRoaXMuaXNFeHBhbmRlZChyb3cubm9kZS5pZCkpIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHRoaXMuZm9sZGVyRXhwYW5zaW9uVG9nZ2xlZC5lbWl0KHsgaWQ6IHJvdy5ub2RlLmlkLCBleHBhbmRlZDogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0Fycm93TGVmdCc6IHtcbiAgICAgICAgaWYgKHJvdy5oYXNDaGlsZHJlbiAmJiB0aGlzLmlzRXhwYW5kZWQocm93Lm5vZGUuaWQpKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLmZvbGRlckV4cGFuc2lvblRvZ2dsZWQuZW1pdCh7IGlkOiByb3cubm9kZS5pZCwgZXhwYW5kZWQ6IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnRW50ZXInOlxuICAgICAgY2FzZSAnICc6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5vblNlbGVjdChyb3cubm9kZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZm9jdXNSb3dFbGVtZW50KGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KGBbZGF0YS1mb2xkZXItcm93LWlkPVwiJHtpZH1cIl1gKTtcbiAgICAgIGVsPy5mb2N1cygpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvY3VzZXMgdGhlIGlubGluZSByZW5hbWUgaW5wdXQgZm9yIHRoZSBnaXZlbiBmb2xkZXIuIFVzZXMgYHNldFRpbWVvdXRgIChub3RcbiAgICogbWljcm90YXNrKSBiZWNhdXNlIHRoZSBpbnB1dCBpcyBnYXRlZCBieSBgKm5nSWY9XCJyZW5hbWluZ0lkID09PSAuLi5cImAgYW5kXG4gICAqIG11c3Qgc3Vydml2ZSB0aGUgbmV4dCBPblB1c2ggY2hhbmdlLWRldGVjdGlvbiBjeWNsZSBiZWZvcmUgaXQncyBpbiB0aGUgRE9NLlxuICAgKi9cbiAgcHJpdmF0ZSBmb2N1c1JlbmFtZUlucHV0KGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MSW5wdXRFbGVtZW50PihgW2RhdGEtZm9sZGVyLXJlbmFtZS1pbnB1dD1cIiR7aWR9XCJdYCk7XG4gICAgICBpZiAoIWVsKSByZXR1cm47XG4gICAgICBlbC5mb2N1cygpO1xuICAgICAgZWwuc2VsZWN0KCk7XG4gICAgfSwgMCk7XG4gIH1cbn1cbiIsIjwhLS0gUmV1c2FibGUgaW5kZXRlcm1pbmF0ZSBsb2FkaW5nIHNwaW5uZXIuIFJlbmRlciB2aWFcbiAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvYWRpbmdTcGlubmVyOyBjb250ZXh0OiB7IHNpemU6IDE0IH1cIj48L25nLWNvbnRhaW5lcj4uIC0tPlxuPG5nLXRlbXBsYXRlICNsb2FkaW5nU3Bpbm5lciBsZXQtc2l6ZT1cInNpemVcIj5cbiAgPHN2ZyBbYXR0ci53aWR0aF09XCJzaXplIHx8IDE2XCIgW2F0dHIuaGVpZ2h0XT1cInNpemUgfHwgMTZcIiB2aWV3Qm94PVwiMCAwIDUwIDUwXCIgYXJpYS1sYWJlbD1cImxvYWRpbmdcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgPGNpcmNsZSBjeD1cIjI1XCIgY3k9XCIyNVwiIHI9XCIyMFwiIHN0cm9rZT1cIiNFNUU3RUJcIiBzdHJva2Utd2lkdGg9XCI2XCIgZmlsbD1cIm5vbmVcIj48L2NpcmNsZT5cbiAgICA8cGF0aCBkPVwiTTQ1IDI1YTIwIDIwIDAgMCAwLTIwLTIwXCIgc3Ryb2tlPVwiIzRGNDZFNVwiIHN0cm9rZS13aWR0aD1cIjZcIiBmaWxsPVwibm9uZVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIj5cbiAgICAgIDxhbmltYXRlVHJhbnNmb3JtIGF0dHJpYnV0ZU5hbWU9XCJ0cmFuc2Zvcm1cIiB0eXBlPVwicm90YXRlXCIgZnJvbT1cIjAgMjUgMjVcIiB0bz1cIjM2MCAyNSAyNVwiIGR1cj1cIjAuOHNcIiByZXBlYXRDb3VudD1cImluZGVmaW5pdGVcIj48L2FuaW1hdGVUcmFuc2Zvcm0+XG4gICAgPC9wYXRoPlxuICA8L3N2Zz5cbjwvbmctdGVtcGxhdGU+XG5cbjwhLS0gUmV1c2FibGUgZm9sZGVyIGljb24uIFJlbmRlciB2aWEgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvbGRlckljb247IGNvbnRleHQ6IHsgY29sb3I6IG5vZGUuY29sb3IgfVwiPjwvbmctY29udGFpbmVyPi4gLS0+XG48bmctdGVtcGxhdGUgI2ZvbGRlckljb24gbGV0LWNvbG9yPVwiY29sb3JcIj5cbiAgPHNwYW4gY2xhc3M9XCJjcWEtaW5saW5lLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXctNCBjcWEtaC00IGNxYS1mbGV4LXNocmluay0wXCI+XG4gICAgPHN2ZyB3aWR0aD1cIjEzXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDEzIDEyXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICA8cGF0aCBkPVwiTTEyLjE5MTYgOS44NTgyNEMxMi4xOTE2IDEwLjE2NzcgMTIuMDY4NyAxMC40NjQ0IDExLjg0OTkgMTAuNjgzMkMxMS42MzExIDEwLjkwMiAxMS4zMzQzIDExLjAyNDkgMTEuMDI0OSAxMS4wMjQ5SDEuNjkxNTdDMS4zODIxNSAxMS4wMjQ5IDEuMDg1NCAxMC45MDIgMC44NjY2MTEgMTAuNjgzMkMwLjY0NzgxOSAxMC40NjQ0IDAuNTI0OTAyIDEwLjE2NzcgMC41MjQ5MDIgOS44NTgyNFYxLjY5MTU3QzAuNTI0OTAyIDEuMzgyMTUgMC42NDc4MTkgMS4wODU0IDAuODY2NjExIDAuODY2NjExQzEuMDg1NCAwLjY0NzgxOSAxLjM4MjE1IDAuNTI0OTAyIDEuNjkxNTcgMC41MjQ5MDJINC42MDgyNEw1Ljc3NDkgMi4yNzQ5SDExLjAyNDlDMTEuMzM0MyAyLjI3NDkgMTEuNjMxMSAyLjM5NzgyIDExLjg0OTkgMi42MTY2MUMxMi4wNjg3IDIuODM1NCAxMi4xOTE2IDMuMTMyMTUgMTIuMTkxNiAzLjQ0MTU3VjkuODU4MjRaXCIgW2F0dHIuc3Ryb2tlXT1cImNvbG9yIHx8ICcjOTk5OTlFJ1wiIHN0cm9rZS13aWR0aD1cIjEuMDVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgPC9zdmc+XG4gIDwvc3Bhbj5cbjwvbmctdGVtcGxhdGU+XG5cbjxhc2lkZVxuICBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtYmctd2hpdGUgY3FhLWgtZnVsbCBjcWEtbWluLWgtMFwiXG4gIFtjbGFzcy5jcWEtYm9yZGVyXT1cIiFjb2xsYXBzZWRcIlxuICBbY2xhc3MuY3FhLWJvcmRlci1uZXV0cmFsLTIwMF09XCIhY29sbGFwc2VkXCJcbiAgW2NsYXNzLmNxYS1yb3VuZGVkLWxnXT1cIiFjb2xsYXBzZWRcIlxuICBbc3R5bGUud2lkdGgucHhdPVwiY29sbGFwc2VkID8gMjIgOiAyNDBcIlxuICBzdHlsZT1cIm92ZXJmbG93OiBoaWRkZW47IHRyYW5zaXRpb246IHdpZHRoIDI2MG1zIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSk7XCJcbj5cbiAgPCEtLSBDb2xsYXBzZWQgcmFpbDogdGhlIGVudGlyZSBzaWRlYmFyIGJlY29tZXMgYSBzaW5nbGUgY2xpY2sgdGFyZ2V0IHNvIHRoZVxuICAgICAgIHNsaW0gc3RyaXAgcmVhZHMgYXMgYW4gb2J2aW91cyBcImV4cGFuZCBtZVwiIGhhbmRsZS4gLS0+XG4gIDxidXR0b25cbiAgICAqbmdJZj1cImNvbGxhcHNlZFwiXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgc3R5bGU9XCJ3aWR0aDogMjJweDtcIlxuICAgIGNsYXNzPVwiY3FhLWdyb3VwIGNxYS1mbGV4IGNxYS1mbGV4LWNvbCBjcWEtaXRlbXMtY2VudGVyIGNxYS1mbGV4LXNocmluay0wIGNxYS1oLWZ1bGwgY3FhLXB5LTIgY3FhLWdhcC0zIGNxYS1iZy1uZXV0cmFsLTUwIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1uZXV0cmFsLTIwMCBjcWEtdGV4dC1uZXV0cmFsLTUwMCBob3ZlcjpjcWEtYmctaW5kaWdvLTUwIGhvdmVyOmNxYS1ib3JkZXItaW5kaWdvLTIwMCBob3ZlcjpjcWEtdGV4dC1pbmRpZ28tNjAwIGZvY3VzOmNxYS1vdXRsaW5lLW5vbmUgZm9jdXM6Y3FhLXJpbmctMiBmb2N1czpjcWEtcmluZy1pbmRpZ28tMjAwIGNxYS1jdXJzb3ItcG9pbnRlclwiXG4gICAgKGNsaWNrKT1cInRvZ2dsZVBhbmVsKClcIlxuICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0V4cGFuZCBmb2xkZXJzIHBhbmVsJ1wiXG4gICAgW3RpdGxlXT1cIidFeHBhbmQgZm9sZGVycyBwYW5lbCdcIlxuICA+XG4gICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPmNoZXZyb25fcmlnaHQ8L21hdC1pY29uPlxuICAgIDxzcGFuIGNsYXNzPVwiY3FhLWlubGluZS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMTMgMTJcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgPHBhdGggZD1cIk0xMi4xOTE2IDkuODU4MjRDMTIuMTkxNiAxMC4xNjc3IDEyLjA2ODcgMTAuNDY0NCAxMS44NDk5IDEwLjY4MzJDMTEuNjMxMSAxMC45MDIgMTEuMzM0MyAxMS4wMjQ5IDExLjAyNDkgMTEuMDI0OUgxLjY5MTU3QzEuMzgyMTUgMTEuMDI0OSAxLjA4NTQgMTAuOTAyIDAuODY2NjExIDEwLjY4MzJDMC42NDc4MTkgMTAuNDY0NCAwLjUyNDkwMiAxMC4xNjc3IDAuNTI0OTAyIDkuODU4MjRWMS42OTE1N0MwLjUyNDkwMiAxLjM4MjE1IDAuNjQ3ODE5IDEuMDg1NCAwLjg2NjYxMSAwLjg2NjYxMUMxLjA4NTQgMC42NDc4MTkgMS4zODIxNSAwLjUyNDkwMiAxLjY5MTU3IDAuNTI0OTAySDQuNjA4MjRMNS43NzQ5IDIuMjc0OUgxMS4wMjQ5QzExLjMzNDMgMi4yNzQ5IDExLjYzMTEgMi4zOTc4MiAxMS44NDk5IDIuNjE2NjFDMTIuMDY4NyAyLjgzNTQgMTIuMTkxNiAzLjEzMjE1IDEyLjE5MTYgMy40NDE1N1Y5Ljg1ODI0WlwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuMDVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIi8+XG4gICAgICA8L3N2Zz5cbiAgICA8L3NwYW4+XG4gIDwvYnV0dG9uPlxuXG4gIDxkaXYgKm5nSWY9XCIhY29sbGFwc2VkXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWgtZnVsbCBjcWEtbWluLWgtMCBjcWEtcGItMlwiIHN0eWxlPVwid2lkdGg6IDI0MHB4O1wiPlxuICA8IS0tIEhlYWRlciAoZXhwYW5kZWQpIC0tPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLXB5LTEgY3FhLXB4LTNcIlxuICAgIHN0eWxlPVwiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNFMkUyRTM7IG1hcmdpbi1ib3R0b206IDhweDtcIlxuICA+XG4gICAgPHNwYW4gY2xhc3M9XCJjcWEtdGV4dC1zbSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdGV4dC1uZXV0cmFsLTkwMCBjcWEtcHktMC41XCI+e3sgbGFiZWxzLmZvbGRlcnMgfX08L3NwYW4+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0xXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1wLTEgY3FhLXJvdW5kZWQgaG92ZXI6Y3FhLWJnLW5ldXRyYWwtMTAwIGNxYS10ZXh0LW5ldXRyYWwtNTAwXCJcbiAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVBhbmVsKClcIlxuICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidDb2xsYXBzZSBmb2xkZXJzIHBhbmVsJ1wiXG4gICAgICAgIFt0aXRsZV09XCInQ29sbGFwc2UgZm9sZGVycyBwYW5lbCdcIlxuICAgICAgPlxuICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJmb250LXNpemU6MThweDt3aWR0aDoxOHB4O2hlaWdodDoxOHB4XCI+a2V5Ym9hcmRfZG91YmxlX2Fycm93X2xlZnQ8L21hdC1pY29uPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1wLTEgY3FhLXJvdW5kZWQgaG92ZXI6Y3FhLWJnLW5ldXRyYWwtMTAwXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LW5ldXRyYWwtNTAwXT1cIiFzZWFyY2hWaXNpYmxlXCJcbiAgICAgICAgW2NsYXNzLmNxYS10ZXh0LWluZGlnby02MDBdPVwic2VhcmNoVmlzaWJsZVwiXG4gICAgICAgIFtjbGFzcy5jcWEtYmctbmV1dHJhbC0xMDBdPVwic2VhcmNoVmlzaWJsZVwiXG4gICAgICAgIChjbGljayk9XCJ0b2dnbGVTZWFyY2hWaXNpYmxlKClcIlxuICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInNlYXJjaFZpc2libGUgPyAnSGlkZSBmb2xkZXIgc2VhcmNoJyA6ICdTZWFyY2ggZm9sZGVycydcIlxuICAgICAgICBbYXR0ci5hcmlhLXByZXNzZWRdPVwic2VhcmNoVmlzaWJsZVwiXG4gICAgICAgIFt0aXRsZV09XCJzZWFyY2hWaXNpYmxlID8gJ0hpZGUgZm9sZGVyIHNlYXJjaCcgOiAnU2VhcmNoIGZvbGRlcnMnXCJcbiAgICAgID5cbiAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE4cHg7d2lkdGg6MThweDtoZWlnaHQ6MThweFwiPnNlYXJjaDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgKm5nSWY9XCJhbGxvd0NyZWF0ZVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1wLTEgY3FhLXJvdW5kZWQgaG92ZXI6Y3FhLWJnLW5ldXRyYWwtMTAwIGNxYS10ZXh0LW5ldXRyYWwtNTAwXCJcbiAgICAgICAgKGNsaWNrKT1cInJlcXVlc3RDcmVhdGUobnVsbClcIlxuICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImxhYmVscy5uZXdGb2xkZXJcIlxuICAgICAgICBbdGl0bGVdPVwibGFiZWxzLm5ld0ZvbGRlclwiXG4gICAgICA+XG4gICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxOHB4O3dpZHRoOjE4cHg7aGVpZ2h0OjE4cHhcIj5hZGQ8L21hdC1pY29uPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxuZy1jb250YWluZXI+XG4gICAgPCEtLSBTZWFyY2ggKHRvZ2dsZWQgdmlhIHRoZSBzZWFyY2ggaWNvbiBpbiB0aGUgaGVhZGVyKSAtLT5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImNxYS1ncmlkXCJcbiAgICAgIHN0eWxlPVwidHJhbnNpdGlvbjogZ3JpZC10ZW1wbGF0ZS1yb3dzIDMwMG1zIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSk7XCJcbiAgICAgIFtzdHlsZS5ncmlkLXRlbXBsYXRlLXJvd3NdPVwic2VhcmNoVmlzaWJsZSA/ICcxZnInIDogJzBmcidcIlxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtbWluLWgtMFwiIHN0eWxlPVwib3ZlcmZsb3c6IGhpZGRlbjtcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1weC0zIGNxYS1wYi0yXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNxYS1yZWxhdGl2ZVwiPlxuICAgICAgICAgICAgPGNxYS1zZWFyY2gtYmFyXG4gICAgICAgICAgICAgIHNpemU9XCJzbVwiXG4gICAgICAgICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgIFt2YWx1ZV09XCJzZWFyY2hWYWx1ZVwiXG4gICAgICAgICAgICAgIFthdXRvRm9jdXNdPVwic2VhcmNoVmlzaWJsZVwiXG4gICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJsYWJlbHMuc2VhcmNoRm9sZGVyc1BsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgW3Nob3dDbGVhcl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uU2VhcmNoSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIChjbGVhcmVkKT1cIm9uU2VhcmNoQ2xlYXIoKVwiXG4gICAgICAgICAgICA+PC9jcWEtc2VhcmNoLWJhcj5cbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICpuZ0lmPVwiZm9sZGVyU2VhcmNoTG9hZGluZ1wiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWFic29sdXRlIGNxYS1yaWdodC04IGNxYS1pbnNldC15LTAgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgIGFyaWEtbGl2ZT1cInBvbGl0ZVwiXG4gICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZWFyY2hpbmcgZm9sZGVyc1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2FkaW5nU3Bpbm5lcjsgY29udGV4dDogeyBzaXplOiAxNCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXplZCBzZWN0aW9uIGhlYWRlciDigJQgdmlzdWFsbHkgZGlzdGluY3QgZnJvbSBmb2xkZXIgcm93cyBzbyBpdCByZWFkc1xuICAgICAgICAgYXMgYSB2aWV3L3NlY3Rpb24gdG9nZ2xlIHJhdGhlciB0aGFuIGEgZm9sZGVyIGl0ZW0uIC0tPlxuICAgIDxidXR0b25cbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLXctZnVsbCBjcWEtcHgtMyBjcWEtcHktMSBjcWEtdGV4dC1sZWZ0IGNxYS10ZXh0LVsjNkQ2RDc0XSBob3ZlcjpjcWEtdGV4dC1bIzNGNDNFRV0gZm9jdXM6Y3FhLW91dGxpbmUtbm9uZSBmb2N1czpjcWEtdGV4dC1bIzNGNDNFRV0gY3FhLWZsZXgtc2hyaW5rLTAgY3FhLXVwcGVyY2FzZVwiXG4gICAgICAoY2xpY2spPVwidG9nZ2xlRm9sZGVyc0FjY29yZGlvbigpXCJcbiAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiZm9sZGVyc0FjY29yZGlvbkV4cGFuZGVkXCJcbiAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiZm9sZGVyc0FjY29yZGlvbkV4cGFuZGVkID8gJ0NvbGxhcHNlIG9yZ2FuaXplZCBmb2xkZXJzJyA6ICdFeHBhbmQgb3JnYW5pemVkIGZvbGRlcnMnXCJcbiAgICA+XG4gICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LVsxMXB4XSBjcWEtZm9udC1zZW1pYm9sZCBjcWEtdHJhY2tpbmctd2lkZXJcIj57eyBsYWJlbHMub3JnYW5pemVkIH19PC9zcGFuPlxuICAgICAgPG1hdC1pY29uXG4gICAgICAgIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweDt0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMjAwbXMgZWFzZTtcIlxuICAgICAgICBbc3R5bGUudHJhbnNmb3JtXT1cImZvbGRlcnNBY2NvcmRpb25FeHBhbmRlZCA/ICdyb3RhdGUoMGRlZyknIDogJ3JvdGF0ZSgtOTBkZWcpJ1wiXG4gICAgICA+ZXhwYW5kX21vcmU8L21hdC1pY29uPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPCEtLSBUcmVlIChmb2xkZXJzIG9ubHkg4oCUIFVub3JnYW5pemVkIHNpdHMgZGlyZWN0bHkgYmVsb3c7IHRyZWUgY2FwcyBhdCA2MHZoIGFuZCBzY3JvbGxzIHdoZW4gb3ZlcmZsb3dpbmcpLlxuICAgICAgICAgU2Nyb2xsLWJhc2VkIGxhenktbG9hZGluZyBhdCB0aGUgcm9vdCBsZXZlbDogbmVhcmluZyB0aGUgYm90dG9tIGVtaXRzXG4gICAgICAgICBgcm9vdExvYWRNb3JlUmVxdWVzdGVkYCwgd2hpY2ggdGhlIGhvc3QgcmVzcG9uZHMgdG8gYnkgZmV0Y2hpbmcgdGhlXG4gICAgICAgICBuZXh0IHBhZ2Ugb2Ygcm9vdHMuIC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiY3FhLWdyaWQgY3FhLW1pbi1oLTBcIlxuICAgICAgc3R5bGU9XCJ0cmFuc2l0aW9uOiBncmlkLXRlbXBsYXRlLXJvd3MgMzAwbXMgY3ViaWMtYmV6aWVyKDAuNCwgMCwgMC4yLCAxKTtcIlxuICAgICAgW3N0eWxlLmdyaWQtdGVtcGxhdGUtcm93c109XCJmb2xkZXJzQWNjb3JkaW9uRXhwYW5kZWQgPyAnMWZyJyA6ICcwZnInXCJcbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLW1pbi1oLTBcIiBzdHlsZT1cIm92ZXJmbG93OiBoaWRkZW47XCI+XG4gICAgPGRpdiByb2xlPVwidHJlZVwiIGNsYXNzPVwiY3FhLW1pbi1oLTAgY3FhLW1heC1oLVs0MHZoXSBjcWEtb3ZlcmZsb3cteS1hdXRvIGNxYS1weS0xIGNxYS1zY3JvbGxiYXItdGhpbiBjcWEtc2Nyb2xsYmFyLXRyYWNrLXRyYW5zcGFyZW50IGNxYS1zY3JvbGxiYXItdGh1bWItWyNFNUU3RUJdIGNxYS1zY3JvbGxiYXItdGh1bWItcm91bmRlZC1mdWxsIGNxYS1zY3JvbGxiYXItdGh1bWItaG92ZXI6Y3FhLWJnLVsjRDFENURCXVwiXG4gICAgICAgICAoc2Nyb2xsKT1cIm9uVHJlZVNjcm9sbCgkZXZlbnQpXCI+XG4gICAgICA8IS0tIEluaXRpYWwtbG9hZCBzcGlubmVyOiBvbmx5IHJlbmRlcnMgd2hlbiB3ZSBoYXZlIG5vIGZvbGRlcnMgeWV0IEFORFxuICAgICAgICAgICBubyBzZWFyY2ggYWN0aXZlIChzZWFyY2ggaGFzIGl0cyBvd24gaW5saW5lIHNwaW5uZXIpLiAtLT5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nSWY9XCJyb290Rm9sZGVyc0xvYWRpbmcgJiYgZm9sZGVycy5sZW5ndGggPT09IDAgJiYgIXNlYXJjaFZhbHVlPy50cmltKClcIlxuICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1weS02XCJcbiAgICAgICAgYXJpYS1saXZlPVwicG9saXRlXCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvYWRpbmdTcGlubmVyOyBjb250ZXh0OiB7IHNpemU6IDIwIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cInNlYXJjaFZhbHVlPy50cmltKCkgJiYgcm93cy5sZW5ndGggPT09IDAgJiYgIWZvbGRlclNlYXJjaExvYWRpbmdcIlxuICAgICAgICBjbGFzcz1cImNxYS1weC0zIGNxYS1weS0yIGNxYS10ZXh0LXNtIGNxYS10ZXh0LW5ldXRyYWwtNTAwIGNxYS10ZXh0LWNlbnRlclwiXG4gICAgICA+XG4gICAgICAgIHt7IGxhYmVscy5ub0ZvbGRlcnNGb3VuZCB9fVxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByb3cgb2Ygcm93czsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeVJvd1wiPlxuICAgICAgICA8IS0tIFN5bnRoZXRpYyBsb2FkaW5nIHJvdyAobGF6eSBmZXRjaCBpbiBmbGlnaHQpIC0tPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nSWY9XCJyb3cua2luZCA9PT0gJ2xvYWRpbmcnXCJcbiAgICAgICAgICBbc3R5bGUucGFkZGluZ0xlZnQucHhdPVwicm93SW5kZW50KHJvdy5kZXB0aClcIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLXB5LTEuNSBjcWEtdGV4dC1zbSBjcWEtdGV4dC1uZXV0cmFsLTUwMFwiXG4gICAgICAgICAgYXJpYS1saXZlPVwicG9saXRlXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2FkaW5nU3Bpbm5lcjsgY29udGV4dDogeyBzaXplOiAxNCB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPHNwYW4+TG9hZGluZ+KApjwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDwhLS0gU3ludGhldGljIGxvYWQtbW9yZSByb3cgKG1vcmUgY2hpbGRyZW4gYXZhaWxhYmxlIG9uIGJhY2tlbmQpIC0tPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCJyb3cua2luZCA9PT0gJ2xvYWQtbW9yZSdcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIFtzdHlsZS5wYWRkaW5nTGVmdC5weF09XCJyb3dJbmRlbnQocm93LmRlcHRoKVwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS13LWZ1bGwgY3FhLXB5LTEuNSBjcWEtdGV4dC1zbSBjcWEtdGV4dC1pbmRpZ28tNjAwIGhvdmVyOmNxYS1iZy1bI0Q4RDlGQ10gY3FhLXRleHQtbGVmdFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uTG9hZE1vcmUocm93Lm5vZGUpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICA+XG4gICAgICAgICAgPHNwYW4+TG9hZCBtb3JlICh7eyAocm93Lm5vZGUudG90YWxDaGlsZHJlbiA/PyAwKSAtIChyb3cubm9kZS5jaGlsZHJlbj8ubGVuZ3RoID8/IDApIH19KTwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwhLS0gUmVhbCBmb2xkZXIgcm93IC0tPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nSWY9XCJyb3cua2luZCA9PT0gJ2ZvbGRlcidcIlxuICAgICAgICAgIHJvbGU9XCJ0cmVlaXRlbVwiXG4gICAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cInJvdy5oYXNDaGlsZHJlbiA/IGlzRXhwYW5kZWQocm93Lm5vZGUuaWQpIDogbnVsbFwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKVwiXG4gICAgICAgICAgW2F0dHIuZGF0YS1mb2xkZXItcm93LWlkXT1cInJvdy5ub2RlLmlkXCJcbiAgICAgICAgICBbY3FhRm9sZGVyRHJvcF09XCJyb3cubm9kZS5pZFwiXG4gICAgICAgICAgW2Ryb3BFbmFibGVkXT1cImFsbG93RHJvcFwiXG4gICAgICAgICAgKHRlc3RzRHJvcHBlZCk9XCJyb3dEcm9wcGVkKHJvdy5ub2RlLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAoZm9sZGVyRHJvcHBlZCk9XCJvbkZvbGRlclJvd0Ryb3BwZWQocm93Lm5vZGUuaWQsICRldmVudClcIlxuICAgICAgICAgIFtjcWFGb2xkZXJEcmFnXT1cInJvdy5ub2RlLmlkXCJcbiAgICAgICAgICBbZHJhZ0VuYWJsZWRdPVwiYWxsb3dEcm9wXCJcbiAgICAgICAgICAoZHJhZ3N0YXJ0KT1cIm9uRm9sZGVyRHJhZ1N0YXJ0KHJvdy5ub2RlKVwiXG4gICAgICAgICAgKGRyYWdlbmQpPVwib25Gb2xkZXJEcmFnRW5kKClcIlxuICAgICAgICAgIChkcmFnb3Zlcik9XCJvbkZvbGRlclJvd0RyYWdPdmVyKHJvdylcIlxuICAgICAgICAgIChkcmFnbGVhdmUpPVwib25Gb2xkZXJSb3dEcmFnTGVhdmUocm93KVwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uU2VsZWN0KHJvdy5ub2RlKVwiXG4gICAgICAgICAgKGNvbnRleHRtZW51KT1cIm9wZW5Db250ZXh0TWVudShyb3cubm9kZSwgJGV2ZW50KVwiXG4gICAgICAgICAgKGtleWRvd24pPVwib25Sb3dLZXlkb3duKCRldmVudCwgcm93LCBpKVwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZ3JvdXAgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTEgY3FhLXByLTMgY3FhLXB5LTEuNSBjcWEtY3Vyc29yLXBvaW50ZXIgaG92ZXI6Y3FhLWJnLVsjRDhEOUZDXSBmb2N1czpjcWEtb3V0bGluZS1ub25lIGZvY3VzOmNxYS1iZy1bI0Q4RDlGQ10gY3FhLXJlbGF0aXZlXCJcbiAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1jb2xvcl09XCIoaXNTZWxlY3RlZChyb3cubm9kZS5pZCkgfHwgY29udGV4dE1lbnVGb2xkZXJJZCA9PT0gcm93Lm5vZGUuaWQpID8gJyNEOEQ5RkMnIDogbnVsbFwiXG4gICAgICAgICAgW3N0eWxlLnBhZGRpbmdMZWZ0LnB4XT1cInJvd0luZGVudChyb3cuZGVwdGgpXCJcbiAgICAgICAgICBbYXR0ci50aXRsZV09XCJmb2xkZXJSb3dUb29sdGlwKHJvdy5ub2RlKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgKm5nSWY9XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKVwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtbGVmdC0wIGNxYS10b3AtMCBjcWEtYm90dG9tLTAgY3FhLXctWzNweF0gY3FhLWJnLWluZGlnby02MDBcIlxuICAgICAgICAgID48L3NwYW4+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1wLTBcIlxuICAgICAgICAgICAgW3N0eWxlLmNvbG9yXT1cImlzU2VsZWN0ZWQocm93Lm5vZGUuaWQpID8gJyMzRjQzRUUnIDogJyM0QzRDNTEnXCJcbiAgICAgICAgICAgIFtzdHlsZS52aXNpYmlsaXR5XT1cInJvdy5oYXNDaGlsZHJlbiA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvblRvZ2dsZShyb3cubm9kZSwgJGV2ZW50KVwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImlzRXhwYW5kZWQocm93Lm5vZGUuaWQpID8gJ0NvbGxhcHNlJyA6ICdFeHBhbmQnXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJmb250LXNpemU6MTZweDt3aWR0aDoxNnB4O2hlaWdodDoxNnB4XCI+XG4gICAgICAgICAgICAgIHt7IGlzRXhwYW5kZWQocm93Lm5vZGUuaWQpID8gJ2V4cGFuZF9tb3JlJyA6ICdjaGV2cm9uX3JpZ2h0JyB9fVxuICAgICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZm9sZGVySWNvbjsgY29udGV4dDogeyBjb2xvcjogcm93Lm5vZGUuY29sb3IgfVwiPjwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInJlbmFtaW5nSWQgPT09IHJvdy5ub2RlLmlkOyBlbHNlIG5hbWVUcGxcIj5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIHNpemU9XCIxXCJcbiAgICAgICAgICAgICAgW2F0dHIuZGF0YS1mb2xkZXItcmVuYW1lLWlucHV0XT1cInJvdy5ub2RlLmlkXCJcbiAgICAgICAgICAgICAgW2F0dHIubWF4bGVuZ3RoXT1cInJlbmFtZU1heExlbmd0aFwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXgtMSBjcWEtbWluLXctMCBjcWEtdy1mdWxsIGNxYS1weC0yIGNxYS1weS0wLjUgY3FhLXJvdW5kZWQgY3FhLWJvcmRlciBjcWEtYmctd2hpdGUgY3FhLXRleHQtc20gY3FhLXNoYWRvdy1zbSBmb2N1czpjcWEtb3V0bGluZS1ub25lIGZvY3VzOmNxYS1yaW5nLTFcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCIoaXNSZW5hbWVEcmFmdFZhbGlkICYmICFyZW5hbWVMaW1pdEZsYXNoKVxuICAgICAgICAgICAgICAgID8gJ2NxYS1ib3JkZXItbmV1dHJhbC0zMDAgZm9jdXM6Y3FhLWJvcmRlci1pbmRpZ28tNDAwIGZvY3VzOmNxYS1yaW5nLWluZGlnby0yMDAnXG4gICAgICAgICAgICAgICAgOiAnY3FhLWJvcmRlci1bI0VGNDQ0NF0gZm9jdXM6Y3FhLWJvcmRlci1bI0VGNDQ0NF0gZm9jdXM6Y3FhLXJpbmctWyNGQ0E1QTVdJ1wiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtaW52YWxpZF09XCIhaXNSZW5hbWVEcmFmdFZhbGlkIHx8IHJlbmFtZUxpbWl0Rmxhc2hcIlxuICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJlbmFtZURyYWZ0XCJcbiAgICAgICAgICAgICAgKGtleWRvd24pPVwib25SZW5hbWVLZXkoJGV2ZW50LCByb3cubm9kZSlcIlxuICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgKGtleXVwKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAgIChibHVyKT1cImNvbW1pdFJlbmFtZShyb3cubm9kZSlcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNuYW1lVHBsPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS10ZXh0LXNtIGNxYS10cnVuY2F0ZVwiXG4gICAgICAgICAgICAgIFtzdHlsZS5jb2xvcl09XCJpc1NlbGVjdGVkKHJvdy5ub2RlLmlkKSA/ICcjM0Y0M0VFJyA6ICcjNEM0QzUxJ1wiXG4gICAgICAgICAgICAgIChkYmxjbGljayk9XCJiZWdpblJlbmFtZShyb3cubm9kZSwgJGV2ZW50KVwiXG4gICAgICAgICAgICA+e3sgcm93Lm5vZGUubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgPCEtLSBTYXZpbmcgaW5kaWNhdG9yOiByZXBsYWNlcyB0aGUgY291bnQgd2hpbGUgdGhlIGhvc3QncyByZW5hbWUvc2F2ZVxuICAgICAgICAgICAgICAgQVBJIGNhbGwgaXMgaW4gZmxpZ2h0LCBzbyB0aGUgdXNlciBnZXRzIGltbWVkaWF0ZSBmZWVkYmFjay4gLS0+XG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICpuZ0lmPVwiaXNGb2xkZXJTYXZpbmcocm93Lm5vZGUuaWQpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtbWwtMSBjcWEtZmxleC1zaHJpbmstMFwiXG4gICAgICAgICAgICBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInU2F2aW5nICcgKyByb3cubm9kZS5uYW1lXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9hZGluZ1NwaW5uZXI7IGNvbnRleHQ6IHsgc2l6ZTogMTIgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgIDwhLS0gQ291bnQgc2hvd24gYXQgcmVzdDsgaGlkZGVuIG9uIHJvdyBob3ZlciB3aGVuIGRlbGV0ZSBpcyBhbGxvd2VkIC0tPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAqbmdJZj1cIiFpc0ZvbGRlclNhdmluZyhyb3cubm9kZS5pZCkgJiYgc2hvd0NvdW50cyAmJiByb3cubm9kZS5jb3VudCAhPSBudWxsXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXRleHQteHMgY3FhLXRhYnVsYXItbnVtcyBjcWEtbWwtMVwiXG4gICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwiaXNTZWxlY3RlZChyb3cubm9kZS5pZCkgPyAnIzNGNDNFRScgOiAnIzRDNEM1MSdcIlxuICAgICAgICAgICAgW2NsYXNzLmdyb3VwLWhvdmVyOmNxYS1oaWRkZW5dPVwiYWxsb3dEZWxldGVcIlxuICAgICAgICAgID57eyByb3cubm9kZS5jb3VudCB9fTwvc3Bhbj5cblxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICpuZ0lmPVwiaGFzQW55Q29udGV4dEFjdGlvblwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLXAtMC41IGNxYS1yb3VuZGVkIGhvdmVyOmNxYS1iZy1uZXV0cmFsLTIwMFwiXG4gICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwiaXNTZWxlY3RlZChyb3cubm9kZS5pZCkgfHwgY29udGV4dE1lbnVGb2xkZXJJZCA9PT0gcm93Lm5vZGUuaWQgPyAnIzNGNDNFRScgOiAnIzRDNEM1MSdcIlxuICAgICAgICAgICAgW2NsYXNzLmNxYS1oaWRkZW5dPVwiY29udGV4dE1lbnVGb2xkZXJJZCAhPT0gcm93Lm5vZGUuaWRcIlxuICAgICAgICAgICAgW2NsYXNzLmdyb3VwLWhvdmVyOmNxYS1pbmxpbmUtZmxleF09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtjbGFzcy5jcWEtaW5saW5lLWZsZXhdPVwiY29udGV4dE1lbnVGb2xkZXJJZCA9PT0gcm93Lm5vZGUuaWRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5Db250ZXh0TWVudShyb3cubm9kZSwgJGV2ZW50KVwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidPcGVuIGFjdGlvbnMgZm9yICcgKyByb3cubm9kZS5uYW1lXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwiJ21lbnUnXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiY29udGV4dE1lbnVGb2xkZXJJZCA9PT0gcm93Lm5vZGUuaWRcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxNnB4O3dpZHRoOjE2cHg7aGVpZ2h0OjE2cHhcIj5tb3JlX2hvcml6PC9tYXQtaWNvbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwhLS0gUm9vdC1sZXZlbCBwYWdpbmF0aW9uIGlzIG5vdyBkcml2ZW4gYnkgc2Nyb2xsIChzZWUgYChzY3JvbGwpYCBvbiB0aGVcbiAgICAgICAgICAgdHJlZSBjb250YWluZXIgYWJvdmUpLiBQZXItZm9sZGVyIGNoaWxkcmVuIHJldGFpbiB0aGUgZXhwbGljaXRcbiAgICAgICAgICAgXCJMb2FkIG1vcmVcIiBidXR0b24gcmVuZGVyZWQgaW5zaWRlIHRoZSByb3dzIGxvb3AgYWJvdmUsIHNpbmNlXG4gICAgICAgICAgIHN1YnRyZWVzIGFyZW4ndCBpbmRlcGVuZGVudGx5IHNjcm9sbGFibGUuIC0tPlxuICAgICAgPCEtLSBQYWdpbmF0aW9uIHNwaW5uZXIg4oCUIHZpc2libGUgb25seSB3aGVuIGZldGNoaW5nIGFuIGFkZGl0aW9uYWwgcGFnZVxuICAgICAgICAgICBvZiByb290cyAoZm9sZGVycy5sZW5ndGggPiAwIGRpc3Rpbmd1aXNoZXMgZnJvbSBpbml0aWFsLWxvYWQgY2FzZSkuIC0tPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cInJvb3RGb2xkZXJzTG9hZGluZyAmJiBmb2xkZXJzLmxlbmd0aCA+IDAgJiYgIXNlYXJjaFZhbHVlPy50cmltKClcIlxuICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1weS0yXCJcbiAgICAgICAgYXJpYS1saXZlPVwicG9saXRlXCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvYWRpbmdTcGlubmVyOyBjb250ZXh0OiB7IHNpemU6IDE0IH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIERpdmlkZXIgYmV0d2VlbiBmb2xkZXIgdHJlZSBhbmQgcGlubmVkIFVub3JnYW5pemVkIHRhYiAtLT5cbiAgICA8ZGl2XG4gICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgY2xhc3M9XCJjcWEtbXgtMyBjcWEtZmxleC1zaHJpbmstMFwiXG4gICAgICBzdHlsZT1cImhlaWdodDogMXB4OyBiYWNrZ3JvdW5kLWNvbG9yOiAjRTVFN0VCOyBtYXJnaW4tdG9wOiA2cHg7IG1hcmdpbi1ib3R0b206IDZweDtcIlxuICAgID48L2Rpdj5cblxuICAgIDwhLS0gVW5vcmdhbml6ZWQg4oCUIHBpbm5lZCBiZWxvdyB0aGUgc2Nyb2xsYWJsZSBmb2xkZXIgdHJlZSBzbyBpdCBzdGF5cyB2aXNpYmxlIHJlZ2FyZGxlc3Mgb2YgZm9sZGVyIGNvdW50IC0tPlxuICAgIDxkaXZcbiAgICAgIHJvbGU9XCJ0cmVlaXRlbVwiXG4gICAgICB0YWJpbmRleD1cIjBcIlxuICAgICAgW2F0dHIuYXJpYS1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKG51bGwpXCJcbiAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLXB4LTMgY3FhLXB5LTEuNSBjcWEtY3Vyc29yLXBvaW50ZXIgaG92ZXI6Y3FhLWJnLVsjRDhEOUZDXSBmb2N1czpjcWEtb3V0bGluZS1ub25lIGZvY3VzOmNxYS1iZy1bI0Q4RDlGQ10gY3FhLXJlbGF0aXZlIGNxYS1mbGV4LXNocmluay0wXCJcbiAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cImlzU2VsZWN0ZWQobnVsbCkgPyAnI0Q4RDlGQycgOiBudWxsXCJcbiAgICAgIFtjcWFGb2xkZXJEcm9wXT1cIm51bGxcIlxuICAgICAgW2Ryb3BFbmFibGVkXT1cImFsbG93RHJvcFwiXG4gICAgICAodGVzdHNEcm9wcGVkKT1cInJvd0Ryb3BwZWQobnVsbCwgJGV2ZW50KVwiXG4gICAgICAoZm9sZGVyRHJvcHBlZCk9XCJvbkZvbGRlclJvd0Ryb3BwZWQobnVsbCwgJGV2ZW50KVwiXG4gICAgICAoY2xpY2spPVwib25TZWxlY3RVbm9yZ2FuaXplZCgpXCJcbiAgICA+XG4gICAgICA8c3BhblxuICAgICAgICAqbmdJZj1cImlzU2VsZWN0ZWQobnVsbClcIlxuICAgICAgICBjbGFzcz1cImNxYS1hYnNvbHV0ZSBjcWEtbGVmdC0wIGNxYS10b3AtMCBjcWEtYm90dG9tLTAgY3FhLXctWzNweF0gY3FhLWJnLWluZGlnby02MDBcIlxuICAgICAgPjwvc3Bhbj5cbiAgICAgIDxtYXQtaWNvbiBbc3R5bGUuY29sb3JdPVwiaXNTZWxlY3RlZChudWxsKSA/ICcjM0Y0M0VFJyA6ICcjNEM0QzUxJ1wiIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPmluYm94PC9tYXQtaWNvbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLWZsZXgtMSBjcWEtdGV4dC1zbVwiIFtzdHlsZS5jb2xvcl09XCJpc1NlbGVjdGVkKG51bGwpID8gJyMzRjQzRUUnIDogJyM0QzRDNTEnXCI+e3sgbGFiZWxzLnVub3JnYW5pemVkIH19PC9zcGFuPlxuICAgICAgPHNwYW4gKm5nSWY9XCJzaG93Q291bnRzXCIgY2xhc3M9XCJjcWEtdGV4dC14cyBjcWEtdGFidWxhci1udW1zXCIgW3N0eWxlLmNvbG9yXT1cImlzU2VsZWN0ZWQobnVsbCkgPyAnIzNGNDNFRScgOiAnIzRDNEM1MSdcIj57eyB1bm9yZ2FuaXplZENvdW50IH19PC9zcGFuPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBGb2xkZXIgY29udGV4dCBtZW51IChyaWdodC1jbGljayAvIGVsbGlwc2lzKS4gQSAww5cwIGZpeGVkLXBvc2l0aW9uXG4gICAgICAgICBhbmNob3IgYXQgdGhlIGNsaWNrIGNvb3JkcyBkcml2ZXMgYSBjZGtDb25uZWN0ZWRPdmVybGF5OyBDREsnc1xuICAgICAgICAgZmxleGlibGUtY29ubmVjdGVkIHBvc2l0aW9uaW5nIGF1dG8tZmxpcHMgdXAvbGVmdCB3aGVuIHRoZSBtZW51XG4gICAgICAgICB3b3VsZCBvdmVyZmxvdyB0aGUgdmlld3BvcnQgKGxhc3QtZm9sZGVyLW5lYXItYm90dG9tIGNhc2UpLiAtLT5cbiAgICA8ZGl2ICNjdHhBbmNob3IgY2RrT3ZlcmxheU9yaWdpblxuICAgICAgICAgY2xhc3M9XCJjcWEtZml4ZWQgY3FhLXctMCBjcWEtaC0wIGNxYS1wb2ludGVyLWV2ZW50cy1ub25lXCJcbiAgICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cImNvbnRleHRNZW51UG9zaXRpb24ueFwiXG4gICAgICAgICBbc3R5bGUudG9wLnB4XT1cImNvbnRleHRNZW51UG9zaXRpb24ueVwiPjwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlXG4gICAgICBjZGtDb25uZWN0ZWRPdmVybGF5XG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJjdHhBbmNob3JcIlxuICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlPcGVuXT1cImNvbnRleHRNZW51Rm9sZGVySWQgIT09IG51bGxcIlxuICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbnNdPVwiY29udGV4dE1lbnVQb3NpdGlvbnNcIlxuICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlIYXNCYWNrZHJvcF09XCJmYWxzZVwiXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheUZsZXhpYmxlRGltZW5zaW9uc109XCJmYWxzZVwiXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheVB1c2hdPVwidHJ1ZVwiXG4gICAgICAob3ZlcmxheU91dHNpZGVDbGljayk9XCJvbk92ZXJsYXlPdXRzaWRlQ2xpY2soKVwiXG4gICAgICAoZGV0YWNoKT1cImNsb3NlQ29udGV4dE1lbnUoKVwiXG4gICAgPlxuICAgICAgPCEtLSBUaGUgbGliJ3MgdGFpbHdpbmQgY29uZmlnIHNldHMgaW1wb3J0YW50OiAnLmNxYS11aS1yb290Jywgd2hpY2hcbiAgICAgICAgICAgZW1pdHMgZGVzY2VuZGFudCBzZWxlY3RvcnMgbGlrZSBgLmNxYS11aS1yb290IC5jcWEtYmctd2hpdGVgLlxuICAgICAgICAgICBDREsgT3ZlcmxheSB0ZWxlcG9ydHMgdGhpcyB0ZW1wbGF0ZSBpbnRvIHRoZSBnbG9iYWwgb3ZlcmxheVxuICAgICAgICAgICBjb250YWluZXIgKG91dHNpZGUgdGhlIGhvc3QncyBjcWEtdWktcm9vdCksIHNvIHdlIHdyYXAgdGhlIG1lbnUgaW5cbiAgICAgICAgICAgYW4gYW5jZXN0b3IgY3FhLXVpLXJvb3QgZGl2IHRvIHJlLWVzdGFibGlzaCB0aGUgdXRpbGl0eSBzY29wZS4gLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLXVpLXJvb3RcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgcm9sZT1cIm1lbnVcIlxuICAgICAgICBjbGFzcz1cImNxYS1taW4tdy1bMTgwcHhdIGNxYS1iZy13aGl0ZSBjcWEtYm9yZGVyIGNxYS1ib3JkZXItbmV1dHJhbC0yMDAgY3FhLXJvdW5kZWQtbWQgY3FhLXNoYWRvdy1sZyBjcWEtcHktMVwiXG4gICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAoY29udGV4dG1lbnUpPVwiJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICA+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmb2xkZXJCeUlkKGNvbnRleHRNZW51Rm9sZGVySWQpIGFzIG1lbnVOb2RlXCI+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJhbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIHJvbGU9XCJtZW51aXRlbVwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS13LWZ1bGwgY3FhLXB4LTMgY3FhLXB5LTEuNSBjcWEtdGV4dC1zbSBjcWEtdGV4dC1uZXV0cmFsLTgwMCBob3ZlcjpjcWEtYmctaW5kaWdvLTUwIGNxYS10ZXh0LWxlZnRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29udGV4dENyZWF0ZVN1YmZvbGRlcihtZW51Tm9kZSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxNnB4O3dpZHRoOjE2cHg7aGVpZ2h0OjE2cHhcIj5jcmVhdGVfbmV3X2ZvbGRlcjwvbWF0LWljb24+XG4gICAgICAgICAgICA8c3Bhbj57eyBsYWJlbHMuZm9sZGVyTWVudUNyZWF0ZVN1YmZvbGRlciB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImFsbG93UmVuYW1lXCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgcm9sZT1cIm1lbnVpdGVtXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLXctZnVsbCBjcWEtcHgtMyBjcWEtcHktMS41IGNxYS10ZXh0LXNtIGNxYS10ZXh0LW5ldXRyYWwtODAwIGhvdmVyOmNxYS1iZy1pbmRpZ28tNTAgY3FhLXRleHQtbGVmdFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25Db250ZXh0UmVuYW1lKG1lbnVOb2RlKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPmVkaXQ8L21hdC1pY29uPlxuICAgICAgICAgICAgPHNwYW4+e3sgbGFiZWxzLmZvbGRlck1lbnVSZW5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJhbGxvd01vdmVcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICByb2xlPVwibWVudWl0ZW1cIlxuICAgICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMiBjcWEtdy1mdWxsIGNxYS1weC0zIGNxYS1weS0xLjUgY3FhLXRleHQtc20gY3FhLXRleHQtbmV1dHJhbC04MDAgaG92ZXI6Y3FhLWJnLWluZGlnby01MCBjcWEtdGV4dC1sZWZ0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkNvbnRleHRNb3ZlKG1lbnVOb2RlKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7d2lkdGg6MTZweDtoZWlnaHQ6MTZweFwiPmRyaXZlX2ZpbGVfbW92ZTwvbWF0LWljb24+XG4gICAgICAgICAgICA8c3Bhbj57eyBsYWJlbHMuZm9sZGVyTWVudU1vdmUgfX08L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJhbGxvd0R1cGxpY2F0ZVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIHJvbGU9XCJtZW51aXRlbVwiXG4gICAgICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWdhcC0yIGNxYS13LWZ1bGwgY3FhLXB4LTMgY3FhLXB5LTEuNSBjcWEtdGV4dC1zbSBjcWEtdGV4dC1uZXV0cmFsLTgwMCBob3ZlcjpjcWEtYmctaW5kaWdvLTUwIGNxYS10ZXh0LWxlZnRcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uQ29udGV4dER1cGxpY2F0ZShtZW51Tm9kZSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxtYXQtaWNvbiBzdHlsZT1cImZvbnQtc2l6ZToxNnB4O3dpZHRoOjE2cHg7aGVpZ2h0OjE2cHhcIj5jb250ZW50X2NvcHk8L21hdC1pY29uPlxuICAgICAgICAgICAgPHNwYW4+e3sgbGFiZWxzLmZvbGRlck1lbnVEdXBsaWNhdGUgfX08L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImFsbG93RGVsZXRlICYmIChhbGxvd0NyZWF0ZSB8fCBhbGxvd1JlbmFtZSB8fCBhbGxvd01vdmUgfHwgYWxsb3dEdXBsaWNhdGUpXCIgY2xhc3M9XCJjcWEtaC1weCBjcWEtYmctbmV1dHJhbC0yMDAgY3FhLW15LTFcIj48L2Rpdj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImFsbG93RGVsZXRlXCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgcm9sZT1cIm1lbnVpdGVtXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtZ2FwLTIgY3FhLXctZnVsbCBjcWEtcHgtMyBjcWEtcHktMS41IGNxYS10ZXh0LXNtIGNxYS10ZXh0LXJlZC02MDAgaG92ZXI6Y3FhLWJnLXJlZC01MCBjcWEtdGV4dC1sZWZ0XCJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkNvbnRleHREZWxldGUobWVudU5vZGUpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWljb24gc3R5bGU9XCJmb250LXNpemU6MTZweDt3aWR0aDoxNnB4O2hlaWdodDoxNnB4XCI+ZGVsZXRlX291dGxpbmU8L21hdC1pY29uPlxuICAgICAgICAgICAgPHNwYW4+e3sgbGFiZWxzLmZvbGRlck1lbnVEZWxldGUgfX08L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvYXNpZGU+XG4iXX0=