tango-app-ui-manage-billing 3.3.34 → 3.3.35
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.
- package/esm2022/lib/components/bank-transactions/bank-transactions.component.mjs +130 -8
- package/esm2022/lib/components/brand-invoices/brand-invoices.component.mjs +3 -3
- package/esm2022/lib/components/services/billing.service.mjs +10 -1
- package/fesm2022/tango-app-ui-manage-billing.mjs +268 -139
- package/fesm2022/tango-app-ui-manage-billing.mjs.map +1 -1
- package/lib/components/bank-transactions/bank-transactions.component.d.ts +14 -1
- package/lib/components/services/billing.service.d.ts +3 -0
- package/package.json +1 -1
|
@@ -2,12 +2,14 @@ import { Component } from '@angular/core';
|
|
|
2
2
|
import { Subject, takeUntil } from 'rxjs';
|
|
3
3
|
import { InvoicePreviewComponent } from '../invoice-preview/invoice-preview.component';
|
|
4
4
|
import { ResolveTransactionComponent } from './resolve-transaction/resolve-transaction.component';
|
|
5
|
+
import { DeleteConfirmationComponent } from '../tango-manage-billing/delete-confirmation/delete-confirmation.component';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
import * as i1 from "../services/billing.service";
|
|
7
8
|
import * as i2 from "tango-app-ui-shared";
|
|
8
9
|
import * as i3 from "@ng-bootstrap/ng-bootstrap";
|
|
9
|
-
import * as i4 from "
|
|
10
|
-
import * as i5 from "@angular/
|
|
10
|
+
import * as i4 from "tango-app-ui-global";
|
|
11
|
+
import * as i5 from "@angular/common";
|
|
12
|
+
import * as i6 from "@angular/forms";
|
|
11
13
|
// Bank-statement reconciliation tab. Upload a statement export (CSV/XLSX),
|
|
12
14
|
// rows land in the `banktransaction` collection and are bucketed by status:
|
|
13
15
|
// reconciled / needs_review / unmatched / excluded. Classification rules are
|
|
@@ -17,6 +19,7 @@ export class BankTransactionsComponent {
|
|
|
17
19
|
toast;
|
|
18
20
|
changeDetector;
|
|
19
21
|
modalService;
|
|
22
|
+
gs;
|
|
20
23
|
// 'upload' shows the dropzone (empty collection); 'results' the table view.
|
|
21
24
|
stage = 'upload';
|
|
22
25
|
loading = true;
|
|
@@ -57,12 +60,15 @@ export class BankTransactionsComponent {
|
|
|
57
60
|
pageSize = 10;
|
|
58
61
|
itemsPerPage = 10;
|
|
59
62
|
paginationSizes = [10, 20, 30];
|
|
63
|
+
// Multi-select for bulk delete. Reconciled rows are never selectable.
|
|
64
|
+
selectedIds = new Set();
|
|
60
65
|
destroy$ = new Subject();
|
|
61
|
-
constructor(billingService, toast, changeDetector, modalService) {
|
|
66
|
+
constructor(billingService, toast, changeDetector, modalService, gs) {
|
|
62
67
|
this.billingService = billingService;
|
|
63
68
|
this.toast = toast;
|
|
64
69
|
this.changeDetector = changeDetector;
|
|
65
70
|
this.modalService = modalService;
|
|
71
|
+
this.gs = gs;
|
|
66
72
|
}
|
|
67
73
|
ngOnInit() {
|
|
68
74
|
this.loadList(true);
|
|
@@ -88,6 +94,7 @@ export class BankTransactionsComponent {
|
|
|
88
94
|
next: (res) => {
|
|
89
95
|
this.loading = false;
|
|
90
96
|
this.rows = res?.data?.data || [];
|
|
97
|
+
this.selectedIds.clear();
|
|
91
98
|
this.totalItems = res?.data?.count || 0;
|
|
92
99
|
if (res?.data?.cards) {
|
|
93
100
|
this.cards = res.data.cards;
|
|
@@ -277,6 +284,121 @@ export class BankTransactionsComponent {
|
|
|
277
284
|
}
|
|
278
285
|
}).catch(() => { });
|
|
279
286
|
}
|
|
287
|
+
// ===== Selection (bulk delete) =====
|
|
288
|
+
// A row is selectable only if it is not reconciled.
|
|
289
|
+
isSelectable(t) {
|
|
290
|
+
return !!t && t.status !== 'reconciled';
|
|
291
|
+
}
|
|
292
|
+
isSelected(t) {
|
|
293
|
+
return !!t?._id && this.selectedIds.has(t._id);
|
|
294
|
+
}
|
|
295
|
+
toggleSelect(t) {
|
|
296
|
+
if (!this.isSelectable(t) || !t?._id) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (this.selectedIds.has(t._id)) {
|
|
300
|
+
this.selectedIds.delete(t._id);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.selectedIds.add(t._id);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// Rows on the current page that can be selected (excludes reconciled).
|
|
307
|
+
get selectableRows() {
|
|
308
|
+
return this.rows.filter((r) => this.isSelectable(r));
|
|
309
|
+
}
|
|
310
|
+
get allSelected() {
|
|
311
|
+
const sel = this.selectableRows;
|
|
312
|
+
return sel.length > 0 && sel.every((r) => this.selectedIds.has(r._id));
|
|
313
|
+
}
|
|
314
|
+
toggleSelectAll(event) {
|
|
315
|
+
const checked = event?.target?.checked;
|
|
316
|
+
if (checked) {
|
|
317
|
+
this.selectableRows.forEach((r) => this.selectedIds.add(r._id));
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
this.selectableRows.forEach((r) => this.selectedIds.delete(r._id));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
get selectedCount() {
|
|
324
|
+
return this.selectedIds.size;
|
|
325
|
+
}
|
|
326
|
+
deleteSelected() {
|
|
327
|
+
if (!this.selectedIds.size) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const ids = Array.from(this.selectedIds);
|
|
331
|
+
const modalRef = this.modalService.open(DeleteConfirmationComponent, { centered: true, size: 'md' });
|
|
332
|
+
modalRef.result.then((res) => {
|
|
333
|
+
if (res !== 'Yes') {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
this.billingService.deleteSelectedBankTransactions(ids).pipe(takeUntil(this.destroy$)).subscribe({
|
|
337
|
+
next: (r) => {
|
|
338
|
+
const deleted = r?.data?.deleted ?? 0;
|
|
339
|
+
const skipped = r?.data?.skipped ?? 0;
|
|
340
|
+
let msg = `${deleted} transaction(s) deleted`;
|
|
341
|
+
if (skipped) {
|
|
342
|
+
msg += ` · ${skipped} reconciled kept`;
|
|
343
|
+
}
|
|
344
|
+
this.toast.getPrimaryToast(msg);
|
|
345
|
+
this.currentPage = 1;
|
|
346
|
+
this.loadList();
|
|
347
|
+
},
|
|
348
|
+
error: (err) => this.toast.getErrorToast(err?.error?.message || 'Failed to delete transactions'),
|
|
349
|
+
});
|
|
350
|
+
}).catch(() => { });
|
|
351
|
+
}
|
|
352
|
+
// ===== Delete =====
|
|
353
|
+
// Delete a single (non-reconciled) transaction after confirmation. Reconciled
|
|
354
|
+
// rows never show the delete button, and the backend rejects them anyway.
|
|
355
|
+
deleteTransaction(t) {
|
|
356
|
+
if (!t?._id || t.status === 'reconciled') {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const modalRef = this.modalService.open(DeleteConfirmationComponent, { centered: true, size: 'md' });
|
|
360
|
+
modalRef.result.then((res) => {
|
|
361
|
+
if (res !== 'Yes') {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
this.billingService.deleteBankTransaction(t._id).pipe(takeUntil(this.destroy$)).subscribe({
|
|
365
|
+
next: () => {
|
|
366
|
+
this.toast.getPrimaryToast('Transaction deleted');
|
|
367
|
+
this.loadList();
|
|
368
|
+
},
|
|
369
|
+
error: (err) => this.toast.getErrorToast(err?.error?.message || 'Failed to delete transaction'),
|
|
370
|
+
});
|
|
371
|
+
}).catch(() => { });
|
|
372
|
+
}
|
|
373
|
+
// Delete all non-reconciled transactions from the current statement batch
|
|
374
|
+
// (by fileName). Reconciled rows are preserved by the backend.
|
|
375
|
+
deleteAll() {
|
|
376
|
+
const fileName = this.rows?.[0]?.fileName;
|
|
377
|
+
if (!fileName) {
|
|
378
|
+
this.toast.getErrorToast('No statement file found for these transactions');
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const modalRef = this.modalService.open(DeleteConfirmationComponent, { centered: true, size: 'md' });
|
|
382
|
+
modalRef.result.then((res) => {
|
|
383
|
+
if (res !== 'Yes') {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
this.billingService.deleteAllBankTransactions(fileName).pipe(takeUntil(this.destroy$)).subscribe({
|
|
387
|
+
next: (r) => {
|
|
388
|
+
const deleted = r?.data?.deleted ?? 0;
|
|
389
|
+
const skipped = r?.data?.skipped ?? 0;
|
|
390
|
+
let msg = `${deleted} transaction(s) deleted`;
|
|
391
|
+
if (skipped) {
|
|
392
|
+
msg += ` · ${skipped} reconciled kept`;
|
|
393
|
+
}
|
|
394
|
+
this.toast.getPrimaryToast(msg);
|
|
395
|
+
this.currentPage = 1;
|
|
396
|
+
this.loadList();
|
|
397
|
+
},
|
|
398
|
+
error: (err) => this.toast.getErrorToast(err?.error?.message || 'Failed to delete transactions'),
|
|
399
|
+
});
|
|
400
|
+
}).catch(() => { });
|
|
401
|
+
}
|
|
280
402
|
// ===== Display helpers =====
|
|
281
403
|
statusLabel(s) {
|
|
282
404
|
const map = {
|
|
@@ -301,11 +423,11 @@ export class BankTransactionsComponent {
|
|
|
301
423
|
return this.cards.total;
|
|
302
424
|
return this.cards[id]?.count || 0;
|
|
303
425
|
}
|
|
304
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BankTransactionsComponent, deps: [{ token: i1.BillingService }, { token: i2.ToastService }, { token: i0.ChangeDetectorRef }, { token: i3.NgbModal }], target: i0.ɵɵFactoryTarget.Component });
|
|
305
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: BankTransactionsComponent, selector: "lib-bank-transactions", ngImport: i0, template: "<div>\n <!-- ============ Upload stage (no statements yet) ============ -->\n <div *ngIf=\"stage === 'upload' && !loading\" class=\"px-4 pb-4\">\n <div class=\"billingheader ms-1 mt-6\">Bank Statement Reconciliation</div>\n <div class=\"text-muted small ms-1 mt-1\">Upload a bank statement \u2014 transactions are stored and split into\n Reconciled, Needs review, Unmatched and Excluded.</div>\n <label class=\"dropzone mt-4\" for=\"stmt-file\">\n <div class=\"dz-ic\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 21V9M8 13l4-4 4 4M5 5h14\" />\n </svg>\n </div>\n <div class=\"dz-title mt-3\">Upload bank statement</div>\n <div class=\"text-muted small mt-1\">Drag & drop or click to browse \u00B7 <strong>Excel (.xlsx, .xls) or CSV</strong></div>\n <button type=\"button\" class=\"btn btn-primary btn-sm mt-3\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file').click(); event.preventDefault();\">\n {{ uploading ? 'Parsing\u2026' : 'Upload & parse' }}\n </button>\n </label>\n <input id=\"stmt-file\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\" (change)=\"onFileSelected($event)\">\n </div>\n\n <!-- ============ Results stage ============ -->\n <div *ngIf=\"stage === 'results'\">\n <!-- Upload-another action -->\n <div class=\"d-flex justify-content-end align-items-center mt-4 me-4\">\n <input id=\"stmt-file-again\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\"\n (change)=\"onFileSelected($event)\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file-again').click()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"\n stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">{{ uploading ? 'Parsing\u2026' : 'Upload another statement' }}</span>\n </button>\n </div>\n\n <!-- Status cards \u2014 clicking a card filters the table (click again to clear) -->\n <div class=\"row g-3 mt-1 mb-2 mx-2\">\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'reconciled'\"\n (click)=\"toggleCardFilter('reconciled')\">\n <div class=\"invoice-card-label\">Reconciled\n <svg class=\"info-ic\" ngbTooltip=\"Payments automatically matched to an invoice (payer name + amount), or manually reconciled.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-success\">{{ cards.reconciled.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.reconciled.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'needs_review'\"\n (click)=\"toggleCardFilter('needs_review')\">\n <div class=\"invoice-card-label\">Needs review\n <svg class=\"info-ic\" ngbTooltip=\"Payer matches a customer but the amount doesn't match an invoice, or a dollar payment matched \u2014 confirm before reconciling.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-warning\">{{ cards.needs_review.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.needs_review.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'unmatched'\"\n (click)=\"toggleCardFilter('unmatched')\">\n <div class=\"invoice-card-label\">Unmatched\n <svg class=\"info-ic\" ngbTooltip=\"Payer name doesn't match any customer's invoice \u2014 identify the customer and map it manually.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-danger\">{{ cards.unmatched.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.unmatched.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'excluded'\"\n (click)=\"toggleCardFilter('excluded')\">\n <div class=\"invoice-card-label\">Excluded\n <svg class=\"info-ic\" ngbTooltip=\"Not a customer payment (no payer name) or manually marked as not to be considered.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value\">{{ cards.excluded.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.excluded.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Status tabs + search/filter -->\n <div class=\"card-header paymenthistory border-0\">\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\n <button *ngFor=\"let tab of statusTabs\" class=\"btn btn-sm status-tab\"\n [class.active]=\"activeStatus === tab.id\"\n (click)=\"setStatus(tab.id)\">\n {{ tab.label }}\n <span *ngIf=\"countOf(tab.id)\" class=\"countchip ms-1\">{{ countOf(tab.id) }}</span>\n </button>\n </div>\n <div class=\"card-toolbar ms-auto\">\n <div class=\"d-flex align-items-center position-relative my-1\">\n <span class=\"svg-icon invoicesearch svg-icon-1 position-absolute mt-6 ms-3\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <rect opacity=\"0.5\" x=\"17.0365\" y=\"15.1223\" width=\"8.15546\" height=\"2\" rx=\"1\"\n transform=\"rotate(45 17.0365 15.1223)\" fill=\"currentColor\"></rect>\n <path d=\"M11 19C6.55556 19 3 15.4444 3 11C3 6.55556 6.55556 3 11 3C15.4444 3 19 6.55556 19 11C19 15.4444 15.4444 19 11 19ZM11 5C7.53333 5 5 7.53333 5 11C5 14.4667 7.53333 17 11 17C14.4667 17 17 14.4667 17 11C17 7.53333 14.4667 5 11 5Z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n <input [(ngModel)]=\"searchValue\" type=\"text\" class=\"form-control ps-14 invoicesearch\"\n placeholder=\"Search payer, narration, UTR...\" autocomplete=\"off\" (change)=\"searchField()\" />\n <!-- Filter dropdown \u2014 opens a self-contained popover anchored to\n the button (lib-filters can't host the date-range inputs). -->\n <div class=\"position-relative txn-filter-wrap\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\"\n (click)=\"toggleFilter()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"#344054\" stroke-width=\"2\">\n <path d=\"M3 5h18M6 12h12M10 19h4\" />\n </svg>\n <span class=\"ms-2\">Filter</span>\n <span *ngIf=\"activeFilterCount\" class=\"countchip ms-1\">{{ activeFilterCount }}</span>\n </button>\n <div *ngIf=\"filterOpen\" class=\"txn-filter-pop card\">\n <div class=\"txn-filter-title\">Filter Options</div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 from</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftFromDate\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 to</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftToDate\">\n </div>\n <div class=\"mb-2\">\n <label class=\"form-label small fw-semibold\">Source</label>\n <select class=\"form-select\" [(ngModel)]=\"draftSource\">\n <option value=\"all\">All sources</option>\n <option value=\"bank\">Bank Statement</option>\n <option value=\"va\">Virtual Account</option>\n <option value=\"gateway\">Gateway</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"d-flex justify-content-end mb-2\" *ngIf=\"activeFilterCount\">\n <button class=\"btn btn-link btn-sm p-0\" (click)=\"clearFilters()\">Clear all</button>\n </div>\n <!-- Filters apply only on Apply; Cancel discards changes. -->\n <div class=\"d-flex gap-2 mt-2\">\n <button class=\"btn btn-outline-secondary btn-sm flex-fill\" (click)=\"cancelFilters()\">Cancel</button>\n <button class=\"btn btn-primary btn-sm flex-fill\" (click)=\"applyFilters()\">Apply</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Loading shimmer -->\n <ng-container *ngIf=\"loading\">\n <div class=\"row loader d-flex justify-content-center align-items-center\">\n <div class=\"shimmer\">\n <div class=\"wrapper\">\n <div class=\"stroke animate title\"></div>\n <div class=\"stroke animate link\"></div>\n <div class=\"stroke animate description\"></div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Empty -->\n <ng-container *ngIf=\"!loading && noData\">\n <div class=\"row\">\n <div class=\"col-lg-12 mb-3\">\n <div class=\"card-body d-flex justify-content-center align-items-center flex-column\">\n <img class=\"img-src w-25\" src=\"./assets/tango/Icons/Nodata.svg\" alt=\"\">\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Transactions table -->\n <div *ngIf=\"!loading && !noData\" class=\"table-responsive\">\n <table class=\"table accordion table bottom-border invoivetable text-nowrap\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Source</th>\n <th>Payer (from narration)</th>\n <th>Reference / UTR</th>\n <th>Amount</th>\n <th>Brand Name</th>\n <th>Invoice</th>\n <th>Result</th>\n <th>Status</th>\n <th>Action</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let t of rows\">\n <td>\n <div class=\"table-title\">{{ t.valueDate | date: 'dd MMM, yyyy' }}</div>\n </td>\n <td>\n <span class=\"srcchip\" [class.srcchip-va]=\"t.source === 'va'\">{{ sourceLabel(t.source) }}</span>\n </td>\n <td>\n <div class=\"table-title payer-cell\">{{ t.payer || '\u2014' }}</div>\n <div class=\"narration-sub\" [title]=\"t.narration\">{{ t.narration }}</div>\n </td>\n <td>\n <span class=\"mono\">{{ t.refNo || '\u2014' }}</span>\n </td>\n <td>\n <div class=\"table-title\"><strong>\u20B9{{ t.amount | number:'1.2-2':'en-IN' }}</strong></div>\n </td>\n <td>\n <div class=\"table-title\">{{ t.identifiedClientName || '\u2014' }}</div>\n </td>\n <td>\n <div class=\"table-title\">\n <!-- Multiple invoices settled by one payment: link each individually. -->\n <ng-container *ngIf=\"t.appliedInvoices?.length > 1; else singleInv\">\n <ng-container *ngFor=\"let a of t.appliedInvoices; let last = last\">\n <a class=\"invoice-link\" (click)=\"openInvoicePreviewById(a.invoiceId, a.invoice); $event.stopPropagation()\">{{ a.invoice }}</a><span *ngIf=\"!last\">, </span>\n </ng-container>\n </ng-container>\n <ng-template #singleInv>\n <a *ngIf=\"t.invoice && t.invoiceId\" class=\"invoice-link\"\n (click)=\"openInvoicePreview(t); $event.stopPropagation()\">{{ t.invoice }}</a>\n <span *ngIf=\"t.invoice && !t.invoiceId\">{{ t.invoice }}</span>\n <span *ngIf=\"!t.invoice\">\u2014</span>\n </ng-template>\n </div>\n </td>\n <td>\n <div class=\"result-note\" [title]=\"t.resultNote\">{{ t.resultNote || '\u2014' }}</div>\n </td>\n <td>\n <span *ngIf=\"t.contacted\" class=\"pill pill-amber\">Reaching out</span>\n <span *ngIf=\"!t.contacted\" [ngClass]=\"statusPillClass(t.status)\">{{ statusLabel(t.status) }}</span>\n </td>\n <td>\n <button *ngIf=\"t.status === 'needs_review' || t.status === 'unmatched'\"\n class=\"btn btn-sm btn-primary\" (click)=\"openResolve(t)\">Resolve</button>\n <!-- Reconciled rows: Edit re-opens the Resolve & reconcile\n popup so the matched invoice / resolution can be changed. -->\n <button *ngIf=\"t.status === 'reconciled'\"\n class=\"btn btn-sm btn-outline\" (click)=\"openResolve(t)\">Edit</button>\n </td>\n </tr>\n </tbody>\n </table>\n <lib-pagination class=\"text-start\" [itemsPerPage]=\"itemsPerPage\" [currentPage]=\"currentPage\"\n [totalItems]=\"totalItems\" [paginationSizes]=\"paginationSizes\" [pageSize]=\"pageSize\"\n (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\n </div>\n </div>\n</div>", styles: [".dropzone{display:block;border:1.5px dashed #E4E7EC;border-radius:14px;padding:34px;text-align:center;cursor:pointer;background:#fbfdff;transition:border-color .15s,background .15s}.dropzone:hover{border-color:#1493f5;background:#f5faff}.dz-ic{width:52px;height:52px;border-radius:14px;background:#e8f3fe;color:#1493f5;display:grid;place-items:center;margin:0 auto}.dz-title{font-weight:700;font-size:15px;color:#101828}.invoice-card{border:1px solid #E4E7EC;border-radius:12px;padding:18px 22px;background:#fff}.invoice-card.card-clickable{cursor:pointer;transition:border-color .12s,box-shadow .12s}.invoice-card.card-clickable:hover{border-color:#bcd9f7}.invoice-card.card-active{border-color:#1493f5;box-shadow:0 0 0 3px #1493f51f}.status-tab{border:0;border-radius:8px;padding:7px 14px;font-weight:600;color:#5b6472;background:transparent}.status-tab:hover{background:#f4f6f9}.status-tab.active{background:#e8f3fe;color:#1493f5}.status-tab.active .countchip{background:#d3e9fd;color:#1573c4}.invoice-card-label{color:#475467;font-size:13.5px;font-weight:500}.invoice-card-value{font-size:22px;font-weight:700;color:#101828;margin-top:6px;letter-spacing:-.3px}.invoice-card-value.text-success{color:#138a52}.invoice-card-value.text-danger{color:#d64545}.invoice-card-value.text-warning{color:#b9740a}.invoice-card-sub{color:#98a2b3;font-size:12.5px;margin-top:4px}.pill{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}.pill-green{background:#e7f7ee;color:#138a52}.pill-amber{background:#fdf0dc;color:#b9740a}.pill-red{background:#fdecec;color:#d64545}.pill-gray{background:#f1f3f6;color:#667085}.srcchip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;border:1px solid #E4E7EC;color:#475467;background:#fff;white-space:nowrap}.srcchip.srcchip-va{color:#7a3ea8;border-color:#e4d4f3;background:#f7f0fc}.countchip{background:#f1f3f6;color:#667085;font-weight:600;font-size:11px;border-radius:999px;padding:1px 8px}.payer-cell{max-width:230px;white-space:normal;line-height:1.35;font-weight:600}.narration-sub{max-width:230px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#98a2b3;font-size:11.5px;margin-top:2px}.result-note{max-width:220px;white-space:normal;line-height:1.4;color:#475467;font-size:12.5px}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;color:#344054}.filter-panel{border:1px solid #E4E7EC;border-radius:14px;padding:16px 18px;background:#fbfdff}.invoice-link{color:#00a3ff;cursor:pointer;text-decoration:none}.invoice-link:hover{text-decoration:underline}.txn-filter-wrap{margin-left:10px}.txn-filter-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:40;width:280px;padding:16px;border:1px solid #E4E7EC;border-radius:12px;box-shadow:0 8px 24px #1018281f;background:#fff}.txn-filter-title{font-weight:700;color:#101828;font-size:14px;margin-bottom:12px}.invoice-card-label .info-ic{color:#c4c9d2;cursor:help;vertical-align:middle;margin-left:4px}.svg-icon.invoicesearch.position-absolute{top:50%;transform:translateY(-50%);margin-top:0!important}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i2.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "pipe", type: i4.DecimalPipe, name: "number" }, { kind: "pipe", type: i4.DatePipe, name: "date" }] });
|
|
426
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BankTransactionsComponent, deps: [{ token: i1.BillingService }, { token: i2.ToastService }, { token: i0.ChangeDetectorRef }, { token: i3.NgbModal }, { token: i4.GlobalStateService }], target: i0.ɵɵFactoryTarget.Component });
|
|
427
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: BankTransactionsComponent, selector: "lib-bank-transactions", ngImport: i0, template: "<div>\n <!-- ============ Upload stage (no statements yet) ============ -->\n <div *ngIf=\"stage === 'upload' && !loading\" class=\"px-4 pb-4\">\n <div class=\"billingheader ms-1 mt-6\">Bank Statement Reconciliation</div>\n <div class=\"text-muted small ms-1 mt-1\">Upload a bank statement \u2014 transactions are stored and split into\n Reconciled, Needs review, Unmatched and Excluded.</div>\n <label class=\"dropzone mt-4\" for=\"stmt-file\">\n <div class=\"dz-ic\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 21V9M8 13l4-4 4 4M5 5h14\" />\n </svg>\n </div>\n <div class=\"dz-title mt-3\">Upload bank statement</div>\n <div class=\"text-muted small mt-1\">Drag & drop or click to browse \u00B7 <strong>Excel (.xlsx, .xls) or CSV</strong></div>\n <button type=\"button\" class=\"btn btn-primary btn-sm mt-3\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file').click(); event.preventDefault();\">\n {{ uploading ? 'Parsing\u2026' : 'Upload & parse' }}\n </button>\n </label>\n <input id=\"stmt-file\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\" (change)=\"onFileSelected($event)\">\n </div>\n\n <!-- ============ Results stage ============ -->\n <div *ngIf=\"stage === 'results'\">\n <!-- Upload-another action -->\n <div class=\"d-flex justify-content-end align-items-center mt-4 me-4\">\n <input id=\"stmt-file-again\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\"\n (change)=\"onFileSelected($event)\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file-again').click()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"\n stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">{{ uploading ? 'Parsing\u2026' : 'Upload another statement' }}</span>\n </button>\n </div>\n\n <!-- Status cards \u2014 clicking a card filters the table (click again to clear) -->\n <div class=\"row g-3 mt-1 mb-2 mx-2\">\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'reconciled'\"\n (click)=\"toggleCardFilter('reconciled')\">\n <div class=\"invoice-card-label\">Reconciled\n <svg class=\"info-ic\" ngbTooltip=\"Payments automatically matched to an invoice (payer name + amount), or manually reconciled.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-success\">{{ cards.reconciled.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.reconciled.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'needs_review'\"\n (click)=\"toggleCardFilter('needs_review')\">\n <div class=\"invoice-card-label\">Needs review\n <svg class=\"info-ic\" ngbTooltip=\"Payer matches a customer but the amount doesn't match an invoice, or a dollar payment matched \u2014 confirm before reconciling.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-warning\">{{ cards.needs_review.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.needs_review.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'unmatched'\"\n (click)=\"toggleCardFilter('unmatched')\">\n <div class=\"invoice-card-label\">Unmatched\n <svg class=\"info-ic\" ngbTooltip=\"Payer name doesn't match any customer's invoice \u2014 identify the customer and map it manually.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-danger\">{{ cards.unmatched.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.unmatched.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'excluded'\"\n (click)=\"toggleCardFilter('excluded')\">\n <div class=\"invoice-card-label\">Excluded\n <svg class=\"info-ic\" ngbTooltip=\"Not a customer payment (no payer name) or manually marked as not to be considered.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value\">{{ cards.excluded.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.excluded.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Status tabs + search/filter -->\n <div class=\"card-header paymenthistory border-0\">\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\n <button *ngFor=\"let tab of statusTabs\" class=\"btn btn-sm status-tab\"\n [class.active]=\"activeStatus === tab.id\"\n (click)=\"setStatus(tab.id)\">\n {{ tab.label }}\n <span *ngIf=\"countOf(tab.id)\" class=\"countchip ms-1\">{{ countOf(tab.id) }}</span>\n </button>\n </div>\n <div class=\"card-toolbar ms-auto\">\n <div class=\"d-flex align-items-center position-relative my-1\">\n <span class=\"svg-icon invoicesearch svg-icon-1 position-absolute mt-6 ms-3\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <rect opacity=\"0.5\" x=\"17.0365\" y=\"15.1223\" width=\"8.15546\" height=\"2\" rx=\"1\"\n transform=\"rotate(45 17.0365 15.1223)\" fill=\"currentColor\"></rect>\n <path d=\"M11 19C6.55556 19 3 15.4444 3 11C3 6.55556 6.55556 3 11 3C15.4444 3 19 6.55556 19 11C19 15.4444 15.4444 19 11 19ZM11 5C7.53333 5 5 7.53333 5 11C5 14.4667 7.53333 17 11 17C14.4667 17 17 14.4667 17 11C17 7.53333 14.4667 5 11 5Z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n <input [(ngModel)]=\"searchValue\" type=\"text\" class=\"form-control ps-14 invoicesearch\"\n placeholder=\"Search payer, narration, UTR...\" autocomplete=\"off\" (change)=\"searchField()\" />\n <!-- Filter dropdown \u2014 opens a self-contained popover anchored to\n the button (lib-filters can't host the date-range inputs). -->\n <div class=\"position-relative txn-filter-wrap\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\"\n (click)=\"toggleFilter()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"#344054\" stroke-width=\"2\">\n <path d=\"M3 5h18M6 12h12M10 19h4\" />\n </svg>\n <span class=\"ms-2\">Filter</span>\n <span *ngIf=\"activeFilterCount\" class=\"countchip ms-1\">{{ activeFilterCount }}</span>\n </button>\n <div *ngIf=\"filterOpen\" class=\"txn-filter-pop card\">\n <div class=\"txn-filter-title\">Filter Options</div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 from</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftFromDate\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 to</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftToDate\">\n </div>\n <div class=\"mb-2\">\n <label class=\"form-label small fw-semibold\">Source</label>\n <select class=\"form-select\" [(ngModel)]=\"draftSource\">\n <option value=\"all\">All sources</option>\n <option value=\"bank\">Bank Statement</option>\n <option value=\"va\">Virtual Account</option>\n <option value=\"gateway\">Gateway</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"d-flex justify-content-end mb-2\" *ngIf=\"activeFilterCount\">\n <button class=\"btn btn-link btn-sm p-0\" (click)=\"clearFilters()\">Clear all</button>\n </div>\n <!-- Filters apply only on Apply; Cancel discards changes. -->\n <div class=\"d-flex gap-2 mt-2\">\n <button class=\"btn btn-outline-secondary btn-sm flex-fill\" (click)=\"cancelFilters()\">Cancel</button>\n <button class=\"btn btn-primary btn-sm flex-fill\" (click)=\"applyFilters()\">Apply</button>\n </div>\n </div>\n </div>\n <!-- Delete selected (non-reconciled) rows. -->\n <button *ngIf=\"selectedCount > 0 && (gs.userAccess | async)?.Global_Billing_isEdit\"\n type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader ms-2 delete-all-btn\"\n (click)=\"deleteSelected()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"\n stroke=\"#D92D20\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">Delete selected ({{ selectedCount }})</span>\n </button>\n <!-- Delete all (non-reconciled) for the current statement batch.\n Reconciled rows are always preserved by the backend. -->\n <button *ngIf=\"!noData && (gs.userAccess | async)?.Global_Billing_isEdit\"\n type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader ms-2 delete-all-btn\"\n (click)=\"deleteAll()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"\n stroke=\"#D92D20\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">Delete all</span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Loading shimmer -->\n <ng-container *ngIf=\"loading\">\n <div class=\"row loader d-flex justify-content-center align-items-center\">\n <div class=\"shimmer\">\n <div class=\"wrapper\">\n <div class=\"stroke animate title\"></div>\n <div class=\"stroke animate link\"></div>\n <div class=\"stroke animate description\"></div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Empty -->\n <ng-container *ngIf=\"!loading && noData\">\n <div class=\"row\">\n <div class=\"col-lg-12 mb-3\">\n <div class=\"card-body d-flex justify-content-center align-items-center flex-column\">\n <img class=\"img-src w-25\" src=\"./assets/tango/Icons/Nodata.svg\" alt=\"\">\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Transactions table -->\n <div *ngIf=\"!loading && !noData\" class=\"table-responsive\">\n <table class=\"table accordion table bottom-border invoivetable text-nowrap\">\n <thead>\n <tr>\n <th *ngIf=\"(gs.userAccess | async)?.Global_Billing_isEdit\" style=\"width:40px;\">\n <input type=\"checkbox\" [checked]=\"allSelected\" (change)=\"toggleSelectAll($event)\"\n [disabled]=\"selectableRows.length === 0\" ngbTooltip=\"Select all (excludes reconciled)\">\n </th>\n <th>Date</th>\n <th>Source</th>\n <th>Payer (from narration)</th>\n <th>Reference / UTR</th>\n <th>Amount</th>\n <th>Brand Name</th>\n <th>Invoice</th>\n <th>Result</th>\n <th>Status</th>\n <th>Action</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let t of rows\">\n <td *ngIf=\"(gs.userAccess | async)?.Global_Billing_isEdit\" style=\"width:40px;\">\n <!-- Reconciled rows can't be selected. -->\n <input type=\"checkbox\" *ngIf=\"isSelectable(t)\" [checked]=\"isSelected(t)\" (change)=\"toggleSelect(t)\">\n <span *ngIf=\"!isSelectable(t)\" class=\"lock-ic\" ngbTooltip=\"Reconciled \u2014 cannot be deleted\">\uD83D\uDD12</span>\n </td>\n <td>\n <div class=\"table-title\">{{ t.valueDate | date: 'dd MMM, yyyy' }}</div>\n </td>\n <td>\n <span class=\"srcchip\" [class.srcchip-va]=\"t.source === 'va'\">{{ sourceLabel(t.source) }}</span>\n </td>\n <td>\n <div class=\"table-title payer-cell\">{{ t.payer || '\u2014' }}</div>\n <div class=\"narration-sub\" [title]=\"t.narration\">{{ t.narration }}</div>\n </td>\n <td>\n <span class=\"mono\">{{ t.refNo || '\u2014' }}</span>\n </td>\n <td>\n <div class=\"table-title\"><strong>\u20B9{{ t.amount | number:'1.2-2':'en-IN' }}</strong></div>\n </td>\n <td>\n <div class=\"table-title\">{{ t.identifiedClientName || '\u2014' }}</div>\n </td>\n <td>\n <div class=\"table-title\">\n <!-- Multiple invoices settled by one payment: link each individually. -->\n <ng-container *ngIf=\"t.appliedInvoices?.length > 1; else singleInv\">\n <ng-container *ngFor=\"let a of t.appliedInvoices; let last = last\">\n <a class=\"invoice-link\" (click)=\"openInvoicePreviewById(a.invoiceId, a.invoice); $event.stopPropagation()\">{{ a.invoice }}</a><span *ngIf=\"!last\">, </span>\n </ng-container>\n </ng-container>\n <ng-template #singleInv>\n <a *ngIf=\"t.invoice && t.invoiceId\" class=\"invoice-link\"\n (click)=\"openInvoicePreview(t); $event.stopPropagation()\">{{ t.invoice }}</a>\n <span *ngIf=\"t.invoice && !t.invoiceId\">{{ t.invoice }}</span>\n <span *ngIf=\"!t.invoice\">\u2014</span>\n </ng-template>\n </div>\n </td>\n <td>\n <div class=\"result-note\" [title]=\"t.resultNote\">{{ t.resultNote || '\u2014' }}</div>\n </td>\n <td>\n <span *ngIf=\"t.contacted\" class=\"pill pill-amber\">Reaching out</span>\n <span *ngIf=\"!t.contacted\" [ngClass]=\"statusPillClass(t.status)\">{{ statusLabel(t.status) }}</span>\n </td>\n <td>\n <button *ngIf=\"t.status === 'needs_review' || t.status === 'unmatched'\"\n class=\"btn btn-sm btn-primary\" (click)=\"openResolve(t)\">Resolve</button>\n <!-- Reconciled rows: Edit re-opens the Resolve & reconcile\n popup so the matched invoice / resolution can be changed. -->\n <button *ngIf=\"t.status === 'reconciled'\"\n class=\"btn btn-sm btn-outline\" (click)=\"openResolve(t)\">Edit</button>\n <!-- Delete: reconciled rows are protected and never deletable. -->\n <button *ngIf=\"t.status !== 'reconciled' && (gs.userAccess | async)?.Global_Billing_isEdit\"\n class=\"btn btn-sm btn-icon delete-txn\" ngbTooltip=\"Delete transaction\"\n (click)=\"deleteTransaction(t)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 5v6m4-6v6\"\n stroke=\"#D92D20\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </td>\n </tr>\n </tbody>\n </table>\n <lib-pagination class=\"text-start\" [itemsPerPage]=\"itemsPerPage\" [currentPage]=\"currentPage\"\n [totalItems]=\"totalItems\" [paginationSizes]=\"paginationSizes\" [pageSize]=\"pageSize\"\n (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\n </div>\n </div>\n</div>", styles: [".dropzone{display:block;border:1.5px dashed #E4E7EC;border-radius:14px;padding:34px;text-align:center;cursor:pointer;background:#fbfdff;transition:border-color .15s,background .15s}.dropzone:hover{border-color:#1493f5;background:#f5faff}.dz-ic{width:52px;height:52px;border-radius:14px;background:#e8f3fe;color:#1493f5;display:grid;place-items:center;margin:0 auto}.dz-title{font-weight:700;font-size:15px;color:#101828}.invoice-card{border:1px solid #E4E7EC;border-radius:12px;padding:18px 22px;background:#fff}.invoice-card.card-clickable{cursor:pointer;transition:border-color .12s,box-shadow .12s}.invoice-card.card-clickable:hover{border-color:#bcd9f7}.invoice-card.card-active{border-color:#1493f5;box-shadow:0 0 0 3px #1493f51f}.status-tab{border:0;border-radius:8px;padding:7px 14px;font-weight:600;color:#5b6472;background:transparent}.status-tab:hover{background:#f4f6f9}.status-tab.active{background:#e8f3fe;color:#1493f5}.status-tab.active .countchip{background:#d3e9fd;color:#1573c4}.invoice-card-label{color:#475467;font-size:13.5px;font-weight:500}.invoice-card-value{font-size:22px;font-weight:700;color:#101828;margin-top:6px;letter-spacing:-.3px}.invoice-card-value.text-success{color:#138a52}.invoice-card-value.text-danger{color:#d64545}.invoice-card-value.text-warning{color:#b9740a}.invoice-card-sub{color:#98a2b3;font-size:12.5px;margin-top:4px}.pill{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}.pill-green{background:#e7f7ee;color:#138a52}.pill-amber{background:#fdf0dc;color:#b9740a}.pill-red{background:#fdecec;color:#d64545}.pill-gray{background:#f1f3f6;color:#667085}.srcchip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;border:1px solid #E4E7EC;color:#475467;background:#fff;white-space:nowrap}.srcchip.srcchip-va{color:#7a3ea8;border-color:#e4d4f3;background:#f7f0fc}.countchip{background:#f1f3f6;color:#667085;font-weight:600;font-size:11px;border-radius:999px;padding:1px 8px}.payer-cell{max-width:230px;white-space:normal;line-height:1.35;font-weight:600}.narration-sub{max-width:230px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#98a2b3;font-size:11.5px;margin-top:2px}.result-note{max-width:220px;white-space:normal;line-height:1.4;color:#475467;font-size:12.5px}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;color:#344054}.filter-panel{border:1px solid #E4E7EC;border-radius:14px;padding:16px 18px;background:#fbfdff}.invoice-link{color:#00a3ff;cursor:pointer;text-decoration:none}.invoice-link:hover{text-decoration:underline}.txn-filter-wrap{margin-left:10px}.txn-filter-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:40;width:280px;padding:16px;border:1px solid #E4E7EC;border-radius:12px;box-shadow:0 8px 24px #1018281f;background:#fff}.txn-filter-title{font-weight:700;color:#101828;font-size:14px;margin-bottom:12px}.invoice-card-label .info-ic{color:#c4c9d2;cursor:help;vertical-align:middle;margin-left:4px}.svg-icon.invoicesearch.position-absolute{top:50%;transform:translateY(-50%);margin-top:0!important}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", 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]" }, { kind: "directive", type: i6.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i2.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }, { kind: "pipe", type: i5.DatePipe, name: "date" }] });
|
|
306
428
|
}
|
|
307
429
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BankTransactionsComponent, decorators: [{
|
|
308
430
|
type: Component,
|
|
309
|
-
args: [{ selector: 'lib-bank-transactions', template: "<div>\n <!-- ============ Upload stage (no statements yet) ============ -->\n <div *ngIf=\"stage === 'upload' && !loading\" class=\"px-4 pb-4\">\n <div class=\"billingheader ms-1 mt-6\">Bank Statement Reconciliation</div>\n <div class=\"text-muted small ms-1 mt-1\">Upload a bank statement \u2014 transactions are stored and split into\n Reconciled, Needs review, Unmatched and Excluded.</div>\n <label class=\"dropzone mt-4\" for=\"stmt-file\">\n <div class=\"dz-ic\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 21V9M8 13l4-4 4 4M5 5h14\" />\n </svg>\n </div>\n <div class=\"dz-title mt-3\">Upload bank statement</div>\n <div class=\"text-muted small mt-1\">Drag & drop or click to browse \u00B7 <strong>Excel (.xlsx, .xls) or CSV</strong></div>\n <button type=\"button\" class=\"btn btn-primary btn-sm mt-3\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file').click(); event.preventDefault();\">\n {{ uploading ? 'Parsing\u2026' : 'Upload & parse' }}\n </button>\n </label>\n <input id=\"stmt-file\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\" (change)=\"onFileSelected($event)\">\n </div>\n\n <!-- ============ Results stage ============ -->\n <div *ngIf=\"stage === 'results'\">\n <!-- Upload-another action -->\n <div class=\"d-flex justify-content-end align-items-center mt-4 me-4\">\n <input id=\"stmt-file-again\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\"\n (change)=\"onFileSelected($event)\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file-again').click()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"\n stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">{{ uploading ? 'Parsing\u2026' : 'Upload another statement' }}</span>\n </button>\n </div>\n\n <!-- Status cards \u2014 clicking a card filters the table (click again to clear) -->\n <div class=\"row g-3 mt-1 mb-2 mx-2\">\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'reconciled'\"\n (click)=\"toggleCardFilter('reconciled')\">\n <div class=\"invoice-card-label\">Reconciled\n <svg class=\"info-ic\" ngbTooltip=\"Payments automatically matched to an invoice (payer name + amount), or manually reconciled.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-success\">{{ cards.reconciled.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.reconciled.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'needs_review'\"\n (click)=\"toggleCardFilter('needs_review')\">\n <div class=\"invoice-card-label\">Needs review\n <svg class=\"info-ic\" ngbTooltip=\"Payer matches a customer but the amount doesn't match an invoice, or a dollar payment matched \u2014 confirm before reconciling.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-warning\">{{ cards.needs_review.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.needs_review.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'unmatched'\"\n (click)=\"toggleCardFilter('unmatched')\">\n <div class=\"invoice-card-label\">Unmatched\n <svg class=\"info-ic\" ngbTooltip=\"Payer name doesn't match any customer's invoice \u2014 identify the customer and map it manually.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-danger\">{{ cards.unmatched.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.unmatched.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'excluded'\"\n (click)=\"toggleCardFilter('excluded')\">\n <div class=\"invoice-card-label\">Excluded\n <svg class=\"info-ic\" ngbTooltip=\"Not a customer payment (no payer name) or manually marked as not to be considered.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value\">{{ cards.excluded.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.excluded.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Status tabs + search/filter -->\n <div class=\"card-header paymenthistory border-0\">\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\n <button *ngFor=\"let tab of statusTabs\" class=\"btn btn-sm status-tab\"\n [class.active]=\"activeStatus === tab.id\"\n (click)=\"setStatus(tab.id)\">\n {{ tab.label }}\n <span *ngIf=\"countOf(tab.id)\" class=\"countchip ms-1\">{{ countOf(tab.id) }}</span>\n </button>\n </div>\n <div class=\"card-toolbar ms-auto\">\n <div class=\"d-flex align-items-center position-relative my-1\">\n <span class=\"svg-icon invoicesearch svg-icon-1 position-absolute mt-6 ms-3\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <rect opacity=\"0.5\" x=\"17.0365\" y=\"15.1223\" width=\"8.15546\" height=\"2\" rx=\"1\"\n transform=\"rotate(45 17.0365 15.1223)\" fill=\"currentColor\"></rect>\n <path d=\"M11 19C6.55556 19 3 15.4444 3 11C3 6.55556 6.55556 3 11 3C15.4444 3 19 6.55556 19 11C19 15.4444 15.4444 19 11 19ZM11 5C7.53333 5 5 7.53333 5 11C5 14.4667 7.53333 17 11 17C14.4667 17 17 14.4667 17 11C17 7.53333 14.4667 5 11 5Z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n <input [(ngModel)]=\"searchValue\" type=\"text\" class=\"form-control ps-14 invoicesearch\"\n placeholder=\"Search payer, narration, UTR...\" autocomplete=\"off\" (change)=\"searchField()\" />\n <!-- Filter dropdown \u2014 opens a self-contained popover anchored to\n the button (lib-filters can't host the date-range inputs). -->\n <div class=\"position-relative txn-filter-wrap\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\"\n (click)=\"toggleFilter()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"#344054\" stroke-width=\"2\">\n <path d=\"M3 5h18M6 12h12M10 19h4\" />\n </svg>\n <span class=\"ms-2\">Filter</span>\n <span *ngIf=\"activeFilterCount\" class=\"countchip ms-1\">{{ activeFilterCount }}</span>\n </button>\n <div *ngIf=\"filterOpen\" class=\"txn-filter-pop card\">\n <div class=\"txn-filter-title\">Filter Options</div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 from</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftFromDate\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 to</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftToDate\">\n </div>\n <div class=\"mb-2\">\n <label class=\"form-label small fw-semibold\">Source</label>\n <select class=\"form-select\" [(ngModel)]=\"draftSource\">\n <option value=\"all\">All sources</option>\n <option value=\"bank\">Bank Statement</option>\n <option value=\"va\">Virtual Account</option>\n <option value=\"gateway\">Gateway</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"d-flex justify-content-end mb-2\" *ngIf=\"activeFilterCount\">\n <button class=\"btn btn-link btn-sm p-0\" (click)=\"clearFilters()\">Clear all</button>\n </div>\n <!-- Filters apply only on Apply; Cancel discards changes. -->\n <div class=\"d-flex gap-2 mt-2\">\n <button class=\"btn btn-outline-secondary btn-sm flex-fill\" (click)=\"cancelFilters()\">Cancel</button>\n <button class=\"btn btn-primary btn-sm flex-fill\" (click)=\"applyFilters()\">Apply</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Loading shimmer -->\n <ng-container *ngIf=\"loading\">\n <div class=\"row loader d-flex justify-content-center align-items-center\">\n <div class=\"shimmer\">\n <div class=\"wrapper\">\n <div class=\"stroke animate title\"></div>\n <div class=\"stroke animate link\"></div>\n <div class=\"stroke animate description\"></div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Empty -->\n <ng-container *ngIf=\"!loading && noData\">\n <div class=\"row\">\n <div class=\"col-lg-12 mb-3\">\n <div class=\"card-body d-flex justify-content-center align-items-center flex-column\">\n <img class=\"img-src w-25\" src=\"./assets/tango/Icons/Nodata.svg\" alt=\"\">\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Transactions table -->\n <div *ngIf=\"!loading && !noData\" class=\"table-responsive\">\n <table class=\"table accordion table bottom-border invoivetable text-nowrap\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Source</th>\n <th>Payer (from narration)</th>\n <th>Reference / UTR</th>\n <th>Amount</th>\n <th>Brand Name</th>\n <th>Invoice</th>\n <th>Result</th>\n <th>Status</th>\n <th>Action</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let t of rows\">\n <td>\n <div class=\"table-title\">{{ t.valueDate | date: 'dd MMM, yyyy' }}</div>\n </td>\n <td>\n <span class=\"srcchip\" [class.srcchip-va]=\"t.source === 'va'\">{{ sourceLabel(t.source) }}</span>\n </td>\n <td>\n <div class=\"table-title payer-cell\">{{ t.payer || '\u2014' }}</div>\n <div class=\"narration-sub\" [title]=\"t.narration\">{{ t.narration }}</div>\n </td>\n <td>\n <span class=\"mono\">{{ t.refNo || '\u2014' }}</span>\n </td>\n <td>\n <div class=\"table-title\"><strong>\u20B9{{ t.amount | number:'1.2-2':'en-IN' }}</strong></div>\n </td>\n <td>\n <div class=\"table-title\">{{ t.identifiedClientName || '\u2014' }}</div>\n </td>\n <td>\n <div class=\"table-title\">\n <!-- Multiple invoices settled by one payment: link each individually. -->\n <ng-container *ngIf=\"t.appliedInvoices?.length > 1; else singleInv\">\n <ng-container *ngFor=\"let a of t.appliedInvoices; let last = last\">\n <a class=\"invoice-link\" (click)=\"openInvoicePreviewById(a.invoiceId, a.invoice); $event.stopPropagation()\">{{ a.invoice }}</a><span *ngIf=\"!last\">, </span>\n </ng-container>\n </ng-container>\n <ng-template #singleInv>\n <a *ngIf=\"t.invoice && t.invoiceId\" class=\"invoice-link\"\n (click)=\"openInvoicePreview(t); $event.stopPropagation()\">{{ t.invoice }}</a>\n <span *ngIf=\"t.invoice && !t.invoiceId\">{{ t.invoice }}</span>\n <span *ngIf=\"!t.invoice\">\u2014</span>\n </ng-template>\n </div>\n </td>\n <td>\n <div class=\"result-note\" [title]=\"t.resultNote\">{{ t.resultNote || '\u2014' }}</div>\n </td>\n <td>\n <span *ngIf=\"t.contacted\" class=\"pill pill-amber\">Reaching out</span>\n <span *ngIf=\"!t.contacted\" [ngClass]=\"statusPillClass(t.status)\">{{ statusLabel(t.status) }}</span>\n </td>\n <td>\n <button *ngIf=\"t.status === 'needs_review' || t.status === 'unmatched'\"\n class=\"btn btn-sm btn-primary\" (click)=\"openResolve(t)\">Resolve</button>\n <!-- Reconciled rows: Edit re-opens the Resolve & reconcile\n popup so the matched invoice / resolution can be changed. -->\n <button *ngIf=\"t.status === 'reconciled'\"\n class=\"btn btn-sm btn-outline\" (click)=\"openResolve(t)\">Edit</button>\n </td>\n </tr>\n </tbody>\n </table>\n <lib-pagination class=\"text-start\" [itemsPerPage]=\"itemsPerPage\" [currentPage]=\"currentPage\"\n [totalItems]=\"totalItems\" [paginationSizes]=\"paginationSizes\" [pageSize]=\"pageSize\"\n (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\n </div>\n </div>\n</div>", styles: [".dropzone{display:block;border:1.5px dashed #E4E7EC;border-radius:14px;padding:34px;text-align:center;cursor:pointer;background:#fbfdff;transition:border-color .15s,background .15s}.dropzone:hover{border-color:#1493f5;background:#f5faff}.dz-ic{width:52px;height:52px;border-radius:14px;background:#e8f3fe;color:#1493f5;display:grid;place-items:center;margin:0 auto}.dz-title{font-weight:700;font-size:15px;color:#101828}.invoice-card{border:1px solid #E4E7EC;border-radius:12px;padding:18px 22px;background:#fff}.invoice-card.card-clickable{cursor:pointer;transition:border-color .12s,box-shadow .12s}.invoice-card.card-clickable:hover{border-color:#bcd9f7}.invoice-card.card-active{border-color:#1493f5;box-shadow:0 0 0 3px #1493f51f}.status-tab{border:0;border-radius:8px;padding:7px 14px;font-weight:600;color:#5b6472;background:transparent}.status-tab:hover{background:#f4f6f9}.status-tab.active{background:#e8f3fe;color:#1493f5}.status-tab.active .countchip{background:#d3e9fd;color:#1573c4}.invoice-card-label{color:#475467;font-size:13.5px;font-weight:500}.invoice-card-value{font-size:22px;font-weight:700;color:#101828;margin-top:6px;letter-spacing:-.3px}.invoice-card-value.text-success{color:#138a52}.invoice-card-value.text-danger{color:#d64545}.invoice-card-value.text-warning{color:#b9740a}.invoice-card-sub{color:#98a2b3;font-size:12.5px;margin-top:4px}.pill{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}.pill-green{background:#e7f7ee;color:#138a52}.pill-amber{background:#fdf0dc;color:#b9740a}.pill-red{background:#fdecec;color:#d64545}.pill-gray{background:#f1f3f6;color:#667085}.srcchip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;border:1px solid #E4E7EC;color:#475467;background:#fff;white-space:nowrap}.srcchip.srcchip-va{color:#7a3ea8;border-color:#e4d4f3;background:#f7f0fc}.countchip{background:#f1f3f6;color:#667085;font-weight:600;font-size:11px;border-radius:999px;padding:1px 8px}.payer-cell{max-width:230px;white-space:normal;line-height:1.35;font-weight:600}.narration-sub{max-width:230px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#98a2b3;font-size:11.5px;margin-top:2px}.result-note{max-width:220px;white-space:normal;line-height:1.4;color:#475467;font-size:12.5px}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;color:#344054}.filter-panel{border:1px solid #E4E7EC;border-radius:14px;padding:16px 18px;background:#fbfdff}.invoice-link{color:#00a3ff;cursor:pointer;text-decoration:none}.invoice-link:hover{text-decoration:underline}.txn-filter-wrap{margin-left:10px}.txn-filter-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:40;width:280px;padding:16px;border:1px solid #E4E7EC;border-radius:12px;box-shadow:0 8px 24px #1018281f;background:#fff}.txn-filter-title{font-weight:700;color:#101828;font-size:14px;margin-bottom:12px}.invoice-card-label .info-ic{color:#c4c9d2;cursor:help;vertical-align:middle;margin-left:4px}.svg-icon.invoicesearch.position-absolute{top:50%;transform:translateY(-50%);margin-top:0!important}\n"] }]
|
|
310
|
-
}], ctorParameters: () => [{ type: i1.BillingService }, { type: i2.ToastService }, { type: i0.ChangeDetectorRef }, { type: i3.NgbModal }] });
|
|
311
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFuay10cmFuc2FjdGlvbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tbWFuYWdlLWJpbGxpbmcvc3JjL2xpYi9jb21wb25lbnRzL2JhbmstdHJhbnNhY3Rpb25zL2JhbmstdHJhbnNhY3Rpb25zLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy9iYW5rLXRyYW5zYWN0aW9ucy9iYW5rLXRyYW5zYWN0aW9ucy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXFCLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDaEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJMUMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0scURBQXFELENBQUM7Ozs7Ozs7QUFFbEcsMkVBQTJFO0FBQzNFLDRFQUE0RTtBQUM1RSw2RUFBNkU7QUFDN0UseUVBQXlFO0FBTXpFLE1BQU0sT0FBTyx5QkFBeUI7SUFpRDFCO0lBQ0E7SUFDQTtJQUNBO0lBbkRWLDRFQUE0RTtJQUM1RSxLQUFLLEdBQXlCLFFBQVEsQ0FBQztJQUN2QyxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ2YsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRWYsSUFBSSxHQUFVLEVBQUUsQ0FBQztJQUNqQixVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsS0FBSyxHQUFHO1FBQ04sVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFO1FBQ25DLFlBQVksRUFBRSxFQUFFLEtBQUssRUFB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QzdDLENBQUM7d0dBblRVLHlCQUF5Qjs0RkFBekIseUJBQXlCLDZEQ2pCdEMsdTVpQkE0UE07OzRGRDNPTyx5QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0UsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgT25EZXN0cm95LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTmdiTW9kYWwgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XG5pbXBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktc2hhcmVkJztcbmltcG9ydCB7IEJpbGxpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYmlsbGluZy5zZXJ2aWNlJztcbmltcG9ydCB7IEludm9pY2VQcmV2aWV3Q29tcG9uZW50IH0gZnJvbSAnLi4vaW52b2ljZS1wcmV2aWV3L2ludm9pY2UtcHJldmlldy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVzb2x2ZVRyYW5zYWN0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9yZXNvbHZlLXRyYW5zYWN0aW9uL3Jlc29sdmUtdHJhbnNhY3Rpb24uY29tcG9uZW50JztcblxuLy8gQmFuay1zdGF0ZW1lbnQgcmVjb25jaWxpYXRpb24gdGFiLiBVcGxvYWQgYSBzdGF0ZW1lbnQgZXhwb3J0IChDU1YvWExTWCksXG4vLyByb3dzIGxhbmQgaW4gdGhlIGBiYW5rdHJhbnNhY3Rpb25gIGNvbGxlY3Rpb24gYW5kIGFyZSBidWNrZXRlZCBieSBzdGF0dXM6XG4vLyByZWNvbmNpbGVkIC8gbmVlZHNfcmV2aWV3IC8gdW5tYXRjaGVkIC8gZXhjbHVkZWQuIENsYXNzaWZpY2F0aW9uIHJ1bGVzIGFyZVxuLy8gbm90IHdpcmVkIHlldCDigJQgbmV3IHJvd3MgYXJyaXZlIGFzICd1bm1hdGNoZWQnIHVudGlsIHRoYXQgcGFzcyBleGlzdHMuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItYmFuay10cmFuc2FjdGlvbnMnLFxuICB0ZW1wbGF0ZVVybDogJy4vYmFuay10cmFuc2FjdGlvbnMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vYmFuay10cmFuc2FjdGlvbnMuY29tcG9uZW50LnNjc3MnXG59KVxuZXhwb3J0IGNsYXNzIEJhbmtUcmFuc2FjdGlvbnNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIC8vICd1cGxvYWQnIHNob3dzIHRoZSBkcm9wem9uZSAoZW1wdHkgY29sbGVjdGlvbik7ICdyZXN1bHRzJyB0aGUgdGFibGUgdmlldy5cbiAgc3RhZ2U6ICd1cGxvYWQnIHwgJ3Jlc3VsdHMnID0gJ3VwbG9hZCc7XG4gIGxvYWRpbmcgPSB0cnVlO1xuICB1cGxvYWRpbmcgPSBmYWxzZTtcbiAgbm9EYXRhID0gZmFsc2U7XG5cbiAgcm93czogYW55W10gPSBbXTtcbiAgdG90YWxJdGVtcyA9IDA7XG4gIGNhcmRzID0ge1xuICAgIHJlY29uY2lsZWQ6IHsgY291bnQ6IDAsIGFtb3VudDogMCB9LFxuICAgIG5lZWRzX3JldmlldzogeyBjb3VudDogMCwgYW1vdW50OiAwIH0sXG4gICAgdW5tYXRjaGVkOiB7IGNvdW50OiAwLCBhbW91bnQ6IDAgfSxcbiAgICBleGNsdWRlZDogeyBjb3VudDogMCwgYW1vdW50OiAwIH0sXG4gICAgdG90YWw6IDAsXG4gIH07XG5cbiAgLy8gU3RhdHVzIHNlZ21lbnQgdGFicyDigJQgaWRzIG1hdGNoIHRoZSBiYWNrZW5kIGVudW0uXG4gIHN0YXR1c1RhYnMgPSBbXG4gICAgeyBpZDogJ2FsbCcsIGxhYmVsOiAnQWxsJyB9LFxuICAgIHsgaWQ6ICdyZWNvbmNpbGVkJywgbGFiZWw6ICdSZWNvbmNpbGVkJyB9LFxuICAgIHsgaWQ6ICduZWVkc19yZXZpZXcnLCBsYWJlbDogJ05lZWRzIHJldmlldycgfSxcbiAgICB7IGlkOiAndW5tYXRjaGVkJywgbGFiZWw6ICdVbm1hdGNoZWQnIH0sXG4gICAgeyBpZDogJ2V4Y2x1ZGVkJywgbGFiZWw6ICdFeGNsdWRlZCcgfSxcbiAgXTtcbiAgYWN0aXZlU3RhdHVzID0gJ2FsbCc7XG5cbiAgLy8gRmlsdGVyIHBvcG92ZXIgc3RhdGUuXG4gIGZpbHRlck9wZW4gPSBmYWxzZTtcbiAgLy8gQ29tbWl0dGVkIChhcHBsaWVkKSBmaWx0ZXIgdmFsdWVzIOKAlCB0aGVzZSBkcml2ZSB0aGUgbGlzdC5cbiAgZnJvbURhdGUgPSAnJztcbiAgdG9EYXRlID0gJyc7XG4gIHNvdXJjZSA9ICdhbGwnO1xuICAvLyBEcmFmdCB2YWx1ZXMgYm91bmQgdG8gdGhlIHBvcG92ZXIgaW5wdXRzLiBOb3RoaW5nIGlzIGFwcGxpZWQgdW50aWwgdGhlXG4gIC8vIHVzZXIgY2xpY2tzIEFwcGx5OyBDYW5jZWwgZGlzY2FyZHMgdGhlc2UgYmFjayB0byB0aGUgY29tbWl0dGVkIHZhbHVlcy5cbiAgZHJhZnRGcm9tRGF0ZSA9ICcnO1xuICBkcmFmdFRvRGF0ZSA9ICcnO1xuICBkcmFmdFNvdXJjZSA9ICdhbGwnO1xuICBzZWFyY2hWYWx1ZSA9ICcnO1xuXG4gIC8vIFBhZ2luYXRpb24g4oCUIG1pcnJvcnMgdGhlIEFsbCBJbnZvaWNlcyB0YWJsZS5cbiAgY3VycmVudFBhZ2UgPSAxO1xuICBwYWdlU2l6ZSA9IDEwO1xuICBpdGVtc1BlclBhZ2UgPSAxMDtcbiAgcGFnaW5hdGlvblNpemVzID0gWzEwLCAyMCwgMzBdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYmlsbGluZ1NlcnZpY2U6IEJpbGxpbmdTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3Q6IFRvYXN0U2VydmljZSxcbiAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTmdiTW9kYWwsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRMaXN0KHRydWUpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgLy8gZmlyc3RMb2FkIGRlY2lkZXMgdGhlIHN0YWdlOiBhbiBlbXB0eSwgdW5maWx0ZXJlZCBjb2xsZWN0aW9uIG1lYW5zIHRoZVxuICAvLyB1c2VyIGhhcyBuZXZlciB1cGxvYWRlZCDigJQgc2hvdyB0aGUgZHJvcHpvbmUgaW5zdGVhZCBvZiBhbiBlbXB0eSB0YWJsZS5cbiAgbG9hZExpc3QoZmlyc3RMb2FkID0gZmFsc2UpIHtcbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGZpbHRlcnMgPSB7XG4gICAgICBzdGF0dXM6IHRoaXMuYWN0aXZlU3RhdHVzLFxuICAgICAgZnJvbTogdGhpcy5mcm9tRGF0ZSxcbiAgICAgIHRvOiB0aGlzLnRvRGF0ZSxcbiAgICAgIHNvdXJjZTogdGhpcy5zb3VyY2UsXG4gICAgICBzZWFyY2hWYWx1ZTogdGhpcy5zZWFyY2hWYWx1ZSxcbiAgICAgIGxpbWl0OiB0aGlzLnBhZ2VTaXplLFxuICAgICAgb2Zmc2V0OiB0aGlzLmN1cnJlbnRQYWdlLFxuICAgIH07XG4gICAgdGhpcy5iaWxsaW5nU2VydmljZS5iYW5rVHJhbnNhY3Rpb25MaXN0KGZpbHRlcnMpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlcykgPT4ge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yb3dzID0gcmVzPy5kYXRhPy5kYXRhIHx8IFtdO1xuICAgICAgICB0aGlzLnRvdGFsSXRlbXMgPSByZXM/LmRhdGE/LmNvdW50IHx8IDA7XG4gICAgICAgIGlmIChyZXM/LmRhdGE/LmNhcmRzKSB7XG4gICAgICAgICAgdGhpcy5jYXJkcyA9IHJlcy5kYXRhLmNhcmRzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9EYXRhID0gdGhpcy5yb3dzLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgaWYgKGZpcnN0TG9hZCkge1xuICAgICAgICAgIHRoaXMuc3RhZ2UgPSB0aGlzLmNhcmRzLnRvdGFsID4gMCA/ICdyZXN1bHRzJyA6ICd1cGxvYWQnO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJvd3MgPSBbXTtcbiAgICAgICAgdGhpcy50b3RhbEl0ZW1zID0gMDtcbiAgICAgICAgdGhpcy5ub0RhdGEgPSB0cnVlO1xuICAgICAgICBpZiAoZmlyc3RMb2FkKSB7XG4gICAgICAgICAgdGhpcy5zdGFnZSA9ICd1cGxvYWQnO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIG9uRmlsZVNlbGVjdGVkKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBmaWxlOiBGaWxlID0gZXZlbnQ/LnRhcmdldD8uZmlsZXM/LlswXTtcbiAgICBpZiAoIWZpbGUpIHJldHVybjtcbiAgICBjb25zdCBvayA9IC9cXC4oeGxzeHx4bHN8Y3N2KSQvaS50ZXN0KGZpbGUubmFtZSk7XG4gICAgaWYgKCFvaykge1xuICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdVcGxvYWQgdGhlIGJhbmsgc3RhdGVtZW50IGFzIEV4Y2VsICgueGxzeCwgLnhscykgb3IgQ1NWJyk7XG4gICAgICBldmVudC50YXJnZXQudmFsdWUgPSAnJztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy51cGxvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UudXBsb2FkQmFua1N0YXRlbWVudChmaWxlKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXMpID0+IHtcbiAgICAgICAgdGhpcy51cGxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgZCA9IHJlcz8uZGF0YSB8fCB7fTtcbiAgICAgICAgY29uc3QgcyA9IGQuc3VtbWFyeSB8fCB7fTtcbiAgICAgICAgbGV0IG1zZyA9IGBcIiR7ZmlsZS5uYW1lfVwiIOKAlCAke2QuaW5zZXJ0ZWQgfHwgMH0gdHJhbnNhY3Rpb25zIGFkZGVkYDtcbiAgICAgICAgaWYgKGQuaW5zZXJ0ZWQpIHtcbiAgICAgICAgICBtc2cgKz0gYDogJHtzLnJlY29uY2lsZWQgfHwgMH0gcmVjb25jaWxlZCwgJHtzLm5lZWRzX3JldmlldyB8fCAwfSBuZWVkIHJldmlldywgYCArXG4gICAgICAgICAgICAgICAgIGAke3MudW5tYXRjaGVkIHx8IDB9IHVubWF0Y2hlZCwgJHtzLmV4Y2x1ZGVkIHx8IDB9IGV4Y2x1ZGVkYDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZC5kdXBsaWNhdGVzKSBtc2cgKz0gYCAoJHtkLmR1cGxpY2F0ZXN9IGR1cGxpY2F0ZXMgc2tpcHBlZClgO1xuICAgICAgICBpZiAoZC5jbG9zZWRJbnZvaWNlcz8ubGVuZ3RoKSBtc2cgKz0gYCDCtyAke2QuY2xvc2VkSW52b2ljZXMubGVuZ3RofSBpbnZvaWNlKHMpIGNsb3NlZCBhcyBwYWlkYDtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QobXNnKTtcbiAgICAgICAgLy8gQXV0by1yZWNvbmNpbGlhdGlvbiBtYXkgaGF2ZSBjbG9zZWQgaW52b2ljZXMg4oCUIHJlZmV0Y2ggb3B0aW9ucyBuZXh0IHRpbWUuXG4gICAgICAgIHRoaXMucmVzb2x2ZU9wdGlvbnNDYWNoZSA9IG51bGw7XG4gICAgICAgIHRoaXMuc3RhZ2UgPSAncmVzdWx0cyc7XG4gICAgICAgIHRoaXMuYWN0aXZlU3RhdHVzID0gJ2FsbCc7XG4gICAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgICB0aGlzLmxvYWRMaXN0KCk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgdGhpcy51cGxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBwYXJzZSB0aGUgc3RhdGVtZW50IGZpbGUnKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9LFxuICAgIH0pO1xuICAgIGV2ZW50LnRhcmdldC52YWx1ZSA9ICcnO1xuICB9XG5cbiAgc2V0U3RhdHVzKGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVN0YXR1cyA9IGlkO1xuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xuICAgIHRoaXMubG9hZExpc3QoKTtcbiAgfVxuXG4gIC8vIFN0YXQgY2FyZHMgZG91YmxlIGFzIGZpbHRlcnM6IGNsaWNraW5nIHNlbGVjdHMgdGhhdCBzdGF0dXMsIGNsaWNraW5nIHRoZVxuICAvLyBhbHJlYWR5LXNlbGVjdGVkIGNhcmQgY2xlYXJzIGJhY2sgdG8gQWxsLlxuICB0b2dnbGVDYXJkRmlsdGVyKGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNldFN0YXR1cyh0aGlzLmFjdGl2ZVN0YXR1cyA9PT0gaWQgPyAnYWxsJyA6IGlkKTtcbiAgfVxuXG4gIHRvZ2dsZUZpbHRlcigpIHtcbiAgICAvLyBPcGVuaW5nOiBzZWVkIHRoZSBkcmFmdCBpbnB1dHMgZnJvbSB0aGUgY3VycmVudGx5LWFwcGxpZWQgZmlsdGVycyBzbyB0aGVcbiAgICAvLyBwb3BvdmVyIHJlZmxlY3RzIHdoYXQncyBhY3RpdmUuIENsb3NpbmcgdmlhIHRoZSBidXR0b24gPSBjYW5jZWwuXG4gICAgaWYgKCF0aGlzLmZpbHRlck9wZW4pIHtcbiAgICAgIHRoaXMuZHJhZnRGcm9tRGF0ZSA9IHRoaXMuZnJvbURhdGU7XG4gICAgICB0aGlzLmRyYWZ0VG9EYXRlID0gdGhpcy50b0RhdGU7XG4gICAgICB0aGlzLmRyYWZ0U291cmNlID0gdGhpcy5zb3VyY2U7XG4gICAgICB0aGlzLmZpbHRlck9wZW4gPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZpbHRlck9wZW4gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvLyBDb21taXQgdGhlIGRyYWZ0IHNlbGVjdGlvbnMgYW5kIHJlbG9hZC4gT25seSBub3cgZG9lcyB0aGUgZmlsdGVyIHRha2VcbiAgLy8gZWZmZWN0OyB0aGUgcG9wb3ZlciBjbG9zZXMuXG4gIGFwcGx5RmlsdGVycygpIHtcbiAgICB0aGlzLmZyb21EYXRlID0gdGhpcy5kcmFmdEZyb21EYXRlO1xuICAgIHRoaXMudG9EYXRlID0gdGhpcy5kcmFmdFRvRGF0ZTtcbiAgICB0aGlzLnNvdXJjZSA9IHRoaXMuZHJhZnRTb3VyY2U7XG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XG4gICAgdGhpcy5maWx0ZXJPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5sb2FkTGlzdCgpO1xuICB9XG5cbiAgLy8gRGlzY2FyZCBkcmFmdCBlZGl0cyBhbmQgY2xvc2Ugd2l0aG91dCBhcHBseWluZy5cbiAgY2FuY2VsRmlsdGVycygpIHtcbiAgICB0aGlzLmRyYWZ0RnJvbURhdGUgPSB0aGlzLmZyb21EYXRlO1xuICAgIHRoaXMuZHJhZnRUb0RhdGUgPSB0aGlzLnRvRGF0ZTtcbiAgICB0aGlzLmRyYWZ0U291cmNlID0gdGhpcy5zb3VyY2U7XG4gICAgdGhpcy5maWx0ZXJPcGVuID0gZmFsc2U7XG4gIH1cblxuICBjbGVhckZpbHRlcnMoKSB7XG4gICAgdGhpcy5mcm9tRGF0ZSA9ICcnO1xuICAgIHRoaXMudG9EYXRlID0gJyc7XG4gICAgdGhpcy5zb3VyY2UgPSAnYWxsJztcbiAgICB0aGlzLmRyYWZ0RnJvbURhdGUgPSAnJztcbiAgICB0aGlzLmRyYWZ0VG9EYXRlID0gJyc7XG4gICAgdGhpcy5kcmFmdFNvdXJjZSA9ICdhbGwnO1xuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xuICAgIHRoaXMuZmlsdGVyT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMubG9hZExpc3QoKTtcbiAgfVxuXG4gIGdldCBhY3RpdmVGaWx0ZXJDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiAodGhpcy5mcm9tRGF0ZSA/IDEgOiAwKSArICh0aGlzLnRvRGF0ZSA/IDEgOiAwKSArICh0aGlzLnNvdXJjZSAhPT0gJ2FsbCcgPyAxIDogMCk7XG4gIH1cblxuICBzZWFyY2hGaWVsZCgpIHtcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcbiAgICB0aGlzLmxvYWRMaXN0KCk7XG4gIH1cblxuICBvblBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyKSB7XG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IHBhZ2U7XG4gICAgdGhpcy5sb2FkTGlzdCgpO1xuICB9XG5cbiAgb25QYWdlU2l6ZUNoYW5nZShzaXplOiBudW1iZXIpIHtcbiAgICB0aGlzLnBhZ2VTaXplID0gc2l6ZTtcbiAgICB0aGlzLml0ZW1zUGVyUGFnZSA9IHNpemU7XG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XG4gICAgdGhpcy5sb2FkTGlzdCgpO1xuICB9XG5cbiAgLy8gUmVjb25jaWxlZCByb3dzIGNhcnJ5IHRoZSBtYXRjaGVkIGludm9pY2UncyBfaWQg4oCUIG9wZW4gdGhlIHNhbWUgcHJldmlld1xuICAvLyBwb3B1cCB0aGUgQWxsIEludm9pY2VzIHRhYmxlIHVzZXMuXG4gIG9wZW5JbnZvaWNlUHJldmlldyh0OiBhbnkpIHtcbiAgICB0aGlzLm9wZW5JbnZvaWNlUHJldmlld0J5SWQodD8uaW52b2ljZUlkKTtcbiAgfVxuXG4gIC8vIE9wZW4gdGhlIGludm9pY2UgcHJldmlldyBmb3IgYSBzcGVjaWZpYyBpbnZvaWNlIGlkIOKAlCB1c2VkIGJ5IHRoZSBzaW5nbGVcbiAgLy8gYW5kIG11bHRpLWludm9pY2UgKGFwcGxpZWRJbnZvaWNlcykgY2VsbHMgYWxpa2UuXG4gIG9wZW5JbnZvaWNlUHJldmlld0J5SWQoaW52b2ljZUlkOiBzdHJpbmcsIF9pbnZvaWNlTm8/OiBzdHJpbmcpIHtcbiAgICBpZiAoIWludm9pY2VJZCkgcmV0dXJuO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0SW52b2ljZUJ5SWQoaW52b2ljZUlkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBpbnZvaWNlRGF0YSA9IHJlcz8uZGF0YTtcbiAgICAgICAgaWYgKCFpbnZvaWNlRGF0YSkge1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGxvYWQgaW52b2ljZScpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtb2RhbFJlZiA9IHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4oSW52b2ljZVByZXZpZXdDb21wb25lbnQsIHtcbiAgICAgICAgICBjZW50ZXJlZDogdHJ1ZSwgc2l6ZTogJ3hsJywgc2Nyb2xsYWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIG1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLmludm9pY2VEYXRhID0gaW52b2ljZURhdGE7XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGxvYWQgaW52b2ljZScpLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gXCJSZXNvbHZlICYgcmVjb25jaWxlXCIgcG9wdXAgZm9yIG5lZWRzLXJldmlldyAvIHVubWF0Y2hlZCByb3dzLiBUaGVcbiAgLy8gY3VzdG9tZXIvaW52b2ljZSBvcHRpb25zIGFyZSBjYWNoZWQgZm9yIHRoZSBwYWdlIHNlc3Npb24g4oCUIGZldGNoZWQgb25jZSxcbiAgLy8gaW52YWxpZGF0ZWQgb25seSB3aGVuIGFuIGFjdGlvbiBjaGFuZ2VzIGludm9pY2Ugc3RhdGUgKHJlY29uY2lsZSkgb3IgYVxuICAvLyBuZXcgc3RhdGVtZW50IGlzIHVwbG9hZGVkLlxuICBwcml2YXRlIHJlc29sdmVPcHRpb25zQ2FjaGU6IGFueVtdIHwgbnVsbCA9IG51bGw7XG5cbiAgb3BlblJlc29sdmUodDogYW55KSB7XG4gICAgaWYgKHRoaXMucmVzb2x2ZU9wdGlvbnNDYWNoZSkge1xuICAgICAgdGhpcy5zaG93UmVzb2x2ZU1vZGFsKHQsIHRoaXMucmVzb2x2ZU9wdGlvbnNDYWNoZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuYmFua1Jlc29sdmVPcHRpb25zKCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzKSA9PiB7XG4gICAgICAgIHRoaXMucmVzb2x2ZU9wdGlvbnNDYWNoZSA9IHJlcz8uZGF0YSB8fCBbXTtcbiAgICAgICAgdGhpcy5zaG93UmVzb2x2ZU1vZGFsKHQsIHRoaXMucmVzb2x2ZU9wdGlvbnNDYWNoZSEpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBsb2FkIGN1c3RvbWVycyBhbmQgaW52b2ljZXMnKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1Jlc29sdmVNb2RhbCh0OiBhbnksIG9wdGlvbnM6IGFueVtdKSB7XG4gICAgY29uc3QgbW9kYWxSZWYgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKFJlc29sdmVUcmFuc2FjdGlvbkNvbXBvbmVudCwge1xuICAgICAgY2VudGVyZWQ6IHRydWUsIHNpemU6ICdtZCcsIHNjcm9sbGFibGU6IHRydWUsXG4gICAgfSk7XG4gICAgbW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2UudHhuID0gdDtcbiAgICBtb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS5vcHRpb25zID0gb3B0aW9ucztcbiAgICBtb2RhbFJlZi5yZXN1bHQudGhlbigobXNnOiBhbnkpID0+IHtcbiAgICAgIGlmIChtc2cpIHtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoU3RyaW5nKG1zZykpO1xuICAgICAgICAvLyBBIHJlc29sdmUgbWF5IGhhdmUgY2xvc2VkL3BhcnRpYWxseS1wYWlkIGFuIGludm9pY2Ug4oCUIHJlZmV0Y2ggbmV4dCB0aW1lLlxuICAgICAgICB0aGlzLnJlc29sdmVPcHRpb25zQ2FjaGUgPSBudWxsO1xuICAgICAgICB0aGlzLmxvYWRMaXN0KCk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKCkgPT4ge30pO1xuICB9XG5cbiAgLy8gPT09PT0gRGlzcGxheSBoZWxwZXJzID09PT09XG4gIHN0YXR1c0xhYmVsKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgcmVjb25jaWxlZDogJ1JlY29uY2lsZWQnLCBuZWVkc19yZXZpZXc6ICdOZWVkcyByZXZpZXcnLFxuICAgICAgdW5tYXRjaGVkOiAnVW5tYXRjaGVkJywgZXhjbHVkZWQ6ICdFeGNsdWRlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW3NdIHx8IHM7XG4gIH1cblxuICBzdGF0dXNQaWxsQ2xhc3Moczogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICByZWNvbmNpbGVkOiAncGlsbCBwaWxsLWdyZWVuJywgbmVlZHNfcmV2aWV3OiAncGlsbCBwaWxsLWFtYmVyJyxcbiAgICAgIHVubWF0Y2hlZDogJ3BpbGwgcGlsbC1yZWQnLCBleGNsdWRlZDogJ3BpbGwgcGlsbC1ncmF5JyxcbiAgICB9O1xuICAgIHJldHVybiBtYXBbc10gfHwgJ3BpbGwgcGlsbC1ncmF5JztcbiAgfVxuXG4gIHNvdXJjZUxhYmVsKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyBiYW5rOiAnQmFuayBTdGF0ZW1lbnQnLCB2YTogJ1ZpcnR1YWwgQWNjb3VudCcsIGdhdGV3YXk6ICdHYXRld2F5JywgbWFudWFsOiAnTWFudWFsJyB9O1xuICAgIHJldHVybiBtYXBbc10gfHwgcztcbiAgfVxuXG4gIGNvdW50T2YoaWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgaWYgKGlkID09PSAnYWxsJykgcmV0dXJuIHRoaXMuY2FyZHMudG90YWw7XG4gICAgcmV0dXJuICh0aGlzLmNhcmRzIGFzIGFueSlbaWRdPy5jb3VudCB8fCAwO1xuICB9XG59IiwiPGRpdj5cbiAgICA8IS0tID09PT09PT09PT09PSBVcGxvYWQgc3RhZ2UgKG5vIHN0YXRlbWVudHMgeWV0KSA9PT09PT09PT09PT0gLS0+XG4gICAgPGRpdiAqbmdJZj1cInN0YWdlID09PSAndXBsb2FkJyAmJiAhbG9hZGluZ1wiIGNsYXNzPVwicHgtNCBwYi00XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJiaWxsaW5naGVhZGVyIG1zLTEgbXQtNlwiPkJhbmsgU3RhdGVtZW50IFJlY29uY2lsaWF0aW9uPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG1zLTEgbXQtMVwiPlVwbG9hZCBhIGJhbmsgc3RhdGVtZW50IOKAlCB0cmFuc2FjdGlvbnMgYXJlIHN0b3JlZCBhbmQgc3BsaXQgaW50b1xuICAgICAgICAgICAgUmVjb25jaWxlZCwgTmVlZHMgcmV2aWV3LCBVbm1hdGNoZWQgYW5kIEV4Y2x1ZGVkLjwvZGl2PlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJkcm9wem9uZSBtdC00XCIgZm9yPVwic3RtdC1maWxlXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHotaWNcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTIgMjFWOU04IDEzbDQtNCA0IDRNNSA1aDE0XCIgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImR6LXRpdGxlIG10LTNcIj5VcGxvYWQgYmFuayBzdGF0ZW1lbnQ8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG10LTFcIj5EcmFnICZhbXA7IGRyb3Agb3IgY2xpY2sgdG8gYnJvd3NlIMK3IDxzdHJvbmc+RXhjZWwgKC54bHN4LCAueGxzKSBvciBDU1Y8L3N0cm9uZz48L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IGJ0bi1zbSBtdC0zXCIgW2Rpc2FibGVkXT1cInVwbG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgb25jbGljaz1cImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdG10LWZpbGUnKS5jbGljaygpOyBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1wiPlxuICAgICAgICAgICAgICAgIHt7IHVwbG9hZGluZyA/ICdQYXJzaW5n4oCmJyA6ICdVcGxvYWQgJiBwYXJzZScgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8aW5wdXQgaWQ9XCJzdG10LWZpbGVcIiB0eXBlPVwiZmlsZVwiIGFjY2VwdD1cIi54bHN4LC54bHMsLmNzdlwiIGNsYXNzPVwiZC1ub25lXCIgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3RlZCgkZXZlbnQpXCI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tID09PT09PT09PT09PSBSZXN1bHRzIHN0YWdlID09PT09PT09PT09PSAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwic3RhZ2UgPT09ICdyZXN1bHRzJ1wiPlxuICAgICAgICA8IS0tIFVwbG9hZC1hbm90aGVyIGFjdGlvbiAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZW5kIGFsaWduLWl0ZW1zLWNlbnRlciBtdC00IG1lLTRcIj5cbiAgICAgICAgICAgIDxpbnB1dCBpZD1cInN0bXQtZmlsZS1hZ2FpblwiIHR5cGU9XCJmaWxlXCIgYWNjZXB0PVwiLnhsc3gsLnhscywuY3N2XCIgY2xhc3M9XCJkLW5vbmVcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25GaWxlU2VsZWN0ZWQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gYWxpZ24taXRlbXMtZW5kIHRleHQtbm93cmFwIGludmhlYWRlclwiIFtkaXNhYmxlZF09XCJ1cGxvYWRpbmdcIlxuICAgICAgICAgICAgICAgIG9uY2xpY2s9XCJkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RtdC1maWxlLWFnYWluJykuY2xpY2soKVwiPlxuICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE3LjUgMTIuNVYxNS44MzMzQzE3LjUgMTYuMjc1NCAxNy4zMjQ0IDE2LjY5OTMgMTcuMDExOCAxNy4wMTE4QzE2LjY5OTMgMTcuMzI0NCAxNi4yNzU0IDE3LjUgMTUuODMzMyAxNy41SDQuMTY2NjdDMy43MjQ2NCAxNy41IDMuMzAwNzIgMTcuMzI0NCAyLjk4ODE2IDE3LjAxMThDMi42NzU1OSAxNi42OTkzIDIuNSAxNi4yNzU0IDIuNSAxNS44MzMzVjEyLjVNMTQuMTY2NyA2LjY2NjY3TDEwIDIuNU0xMCAyLjVMNS44MzMzMyA2LjY2NjY3TTEwIDIuNVYxMi41XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMzNDQwNTRcIiBzdHJva2Utd2lkdGg9XCIxLjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1zLTJcIj57eyB1cGxvYWRpbmcgPyAnUGFyc2luZ+KApicgOiAnVXBsb2FkIGFub3RoZXIgc3RhdGVtZW50JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFN0YXR1cyBjYXJkcyDigJQgY2xpY2tpbmcgYSBjYXJkIGZpbHRlcnMgdGhlIHRhYmxlIChjbGljayBhZ2FpbiB0byBjbGVhcikgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgZy0zIG10LTEgbWItMiBteC0yXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZCBjYXJkLWNsaWNrYWJsZVwiIFtjbGFzcy5jYXJkLWFjdGl2ZV09XCJhY3RpdmVTdGF0dXMgPT09ICdyZWNvbmNpbGVkJ1wiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDYXJkRmlsdGVyKCdyZWNvbmNpbGVkJylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1sYWJlbFwiPlJlY29uY2lsZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJpbmZvLWljXCIgbmdiVG9vbHRpcD1cIlBheW1lbnRzIGF1dG9tYXRpY2FsbHkgbWF0Y2hlZCB0byBhbiBpbnZvaWNlIChwYXllciBuYW1lICsgYW1vdW50KSwgb3IgbWFudWFsbHkgcmVjb25jaWxlZC5cIiBwbGFjZW1lbnQ9XCJ0b3BcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj48Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjlcIi8+PHBhdGggZD1cIk0xMiAxMXY1TTEyIDhoLjAxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC12YWx1ZSB0ZXh0LXN1Y2Nlc3NcIj57eyBjYXJkcy5yZWNvbmNpbGVkLmNvdW50IH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLWNhcmQtc3ViXCI+4oK5e3sgY2FyZHMucmVjb25jaWxlZC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2xcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkIGNhcmQtY2xpY2thYmxlXCIgW2NsYXNzLmNhcmQtYWN0aXZlXT1cImFjdGl2ZVN0YXR1cyA9PT0gJ25lZWRzX3JldmlldydcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlQ2FyZEZpbHRlcignbmVlZHNfcmV2aWV3JylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1sYWJlbFwiPk5lZWRzIHJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImluZm8taWNcIiBuZ2JUb29sdGlwPVwiUGF5ZXIgbWF0Y2hlcyBhIGN1c3RvbWVyIGJ1dCB0aGUgYW1vdW50IGRvZXNuJ3QgbWF0Y2ggYW4gaW52b2ljZSwgb3IgYSBkb2xsYXIgcGF5bWVudCBtYXRjaGVkIOKAlCBjb25maXJtIGJlZm9yZSByZWNvbmNpbGluZy5cIiBwbGFjZW1lbnQ9XCJ0b3BcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj48Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjlcIi8+PHBhdGggZD1cIk0xMiAxMXY1TTEyIDhoLjAxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC12YWx1ZSB0ZXh0LXdhcm5pbmdcIj57eyBjYXJkcy5uZWVkc19yZXZpZXcuY291bnQgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1zdWJcIj7igrl7eyBjYXJkcy5uZWVkc19yZXZpZXcuYW1vdW50IHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZCBjYXJkLWNsaWNrYWJsZVwiIFtjbGFzcy5jYXJkLWFjdGl2ZV09XCJhY3RpdmVTdGF0dXMgPT09ICd1bm1hdGNoZWQnXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNhcmRGaWx0ZXIoJ3VubWF0Y2hlZCcpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLWNhcmQtbGFiZWxcIj5Vbm1hdGNoZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJpbmZvLWljXCIgbmdiVG9vbHRpcD1cIlBheWVyIG5hbWUgZG9lc24ndCBtYXRjaCBhbnkgY3VzdG9tZXIncyBpbnZvaWNlIOKAlCBpZGVudGlmeSB0aGUgY3VzdG9tZXIgYW5kIG1hcCBpdCBtYW51YWxseS5cIiBwbGFjZW1lbnQ9XCJ0b3BcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj48Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjlcIi8+PHBhdGggZD1cIk0xMiAxMXY1TTEyIDhoLjAxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC12YWx1ZSB0ZXh0LWRhbmdlclwiPnt7IGNhcmRzLnVubWF0Y2hlZC5jb3VudCB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkLXN1YlwiPuKCuXt7IGNhcmRzLnVubWF0Y2hlZC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2xcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkIGNhcmQtY2xpY2thYmxlXCIgW2NsYXNzLmNhcmQtYWN0aXZlXT1cImFjdGl2ZVN0YXR1cyA9PT0gJ2V4Y2x1ZGVkJ1wiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDYXJkRmlsdGVyKCdleGNsdWRlZCcpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLWNhcmQtbGFiZWxcIj5FeGNsdWRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImluZm8taWNcIiBuZ2JUb29sdGlwPVwiTm90IGEgY3VzdG9tZXIgcGF5bWVudCAobm8gcGF5ZXIgbmFtZSkgb3IgbWFudWFsbHkgbWFya2VkIGFzIG5vdCB0byBiZSBjb25zaWRlcmVkLlwiIHBsYWNlbWVudD1cInRvcFwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPjxjaXJjbGUgY3g9XCIxMlwiIGN5PVwiMTJcIiByPVwiOVwiLz48cGF0aCBkPVwiTTEyIDExdjVNMTIgOGguMDFcIi8+PC9zdmc+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkLXZhbHVlXCI+e3sgY2FyZHMuZXhjbHVkZWQuY291bnQgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1zdWJcIj7igrl7eyBjYXJkcy5leGNsdWRlZC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBTdGF0dXMgdGFicyArIHNlYXJjaC9maWx0ZXIgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBwYXltZW50aGlzdG9yeSBib3JkZXItMFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTIgZmxleC13cmFwXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdGb3I9XCJsZXQgdGFiIG9mIHN0YXR1c1RhYnNcIiBjbGFzcz1cImJ0biBidG4tc20gc3RhdHVzLXRhYlwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlU3RhdHVzID09PSB0YWIuaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2V0U3RhdHVzKHRhYi5pZClcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgdGFiLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiY291bnRPZih0YWIuaWQpXCIgY2xhc3M9XCJjb3VudGNoaXAgbXMtMVwiPnt7IGNvdW50T2YodGFiLmlkKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdG9vbGJhciBtcy1hdXRvXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgcG9zaXRpb24tcmVsYXRpdmUgbXktMVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN2Zy1pY29uIGludm9pY2VzZWFyY2ggc3ZnLWljb24tMSBwb3NpdGlvbi1hYnNvbHV0ZSBtdC02IG1zLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxyZWN0IG9wYWNpdHk9XCIwLjVcIiB4PVwiMTcuMDM2NVwiIHk9XCIxNS4xMjIzXCIgd2lkdGg9XCI4LjE1NTQ2XCIgaGVpZ2h0PVwiMlwiIHJ4PVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSg0NSAxNy4wMzY1IDE1LjEyMjMpXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiPjwvcmVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTExIDE5QzYuNTU1NTYgMTkgMyAxNS40NDQ0IDMgMTFDMyA2LjU1NTU2IDYuNTU1NTYgMyAxMSAzQzE1LjQ0NDQgMyAxOSA2LjU1NTU2IDE5IDExQzE5IDE1LjQ0NDQgMTUuNDQ0NCAxOSAxMSAxOVpNMTEgNUM3LjUzMzMzIDUgNSA3LjUzMzMzIDUgMTFDNSAxNC40NjY3IDcuNTMzMzMgMTcgMTEgMTdDMTQuNDY2NyAxNyAxNyAxNC40NjY3IDE3IDExQzE3IDcuNTMzMzMgMTQuNDY2NyA1IDExIDVaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiPjwvcGF0aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbKG5nTW9kZWwpXT1cInNlYXJjaFZhbHVlXCIgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBwcy0xNCBpbnZvaWNlc2VhcmNoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIHBheWVyLCBuYXJyYXRpb24sIFVUUi4uLlwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiIChjaGFuZ2UpPVwic2VhcmNoRmllbGQoKVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRmlsdGVyIGRyb3Bkb3duIOKAlCBvcGVucyBhIHNlbGYtY29udGFpbmVkIHBvcG92ZXIgYW5jaG9yZWQgdG9cbiAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgYnV0dG9uIChsaWItZmlsdGVycyBjYW4ndCBob3N0IHRoZSBkYXRlLXJhbmdlIGlucHV0cykuIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmUgdHhuLWZpbHRlci13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1vdXRsaW5lIGJ0biBhbGlnbi1pdGVtcy1lbmQgdGV4dC1ub3dyYXAgaW52aGVhZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRmlsdGVyKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTMgNWgxOE02IDEyaDEyTTEwIDE5aDRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXMtMlwiPkZpbHRlcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjdGl2ZUZpbHRlckNvdW50XCIgY2xhc3M9XCJjb3VudGNoaXAgbXMtMVwiPnt7IGFjdGl2ZUZpbHRlckNvdW50IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmlsdGVyT3BlblwiIGNsYXNzPVwidHhuLWZpbHRlci1wb3AgY2FyZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eG4tZmlsdGVyLXRpdGxlXCI+RmlsdGVyIE9wdGlvbnM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIHNtYWxsIGZ3LXNlbWlib2xkXCI+RGF0ZSDigJQgZnJvbTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZGF0ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgWyhuZ01vZGVsKV09XCJkcmFmdEZyb21EYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBzbWFsbCBmdy1zZW1pYm9sZFwiPkRhdGUg4oCUIHRvPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJkYXRlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbKG5nTW9kZWwpXT1cImRyYWZ0VG9EYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBzbWFsbCBmdy1zZW1pYm9sZFwiPlNvdXJjZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIFsobmdNb2RlbCldPVwiZHJhZnRTb3VyY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJhbGxcIj5BbGwgc291cmNlczwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImJhbmtcIj5CYW5rIFN0YXRlbWVudDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInZhXCI+VmlydHVhbCBBY2NvdW50PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZ2F0ZXdheVwiPkdhdGV3YXk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJtYW51YWxcIj5NYW51YWw8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZW5kIG1iLTJcIiAqbmdJZj1cImFjdGl2ZUZpbHRlckNvdW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpbmsgYnRuLXNtIHAtMFwiIChjbGljayk9XCJjbGVhckZpbHRlcnMoKVwiPkNsZWFyIGFsbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRmlsdGVycyBhcHBseSBvbmx5IG9uIEFwcGx5OyBDYW5jZWwgZGlzY2FyZHMgY2hhbmdlcy4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMiBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGJ0bi1zbSBmbGV4LWZpbGxcIiAoY2xpY2spPVwiY2FuY2VsRmlsdGVycygpXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgYnRuLXNtIGZsZXgtZmlsbFwiIChjbGljayk9XCJhcHBseUZpbHRlcnMoKVwiPkFwcGx5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBMb2FkaW5nIHNoaW1tZXIgLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IGxvYWRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hpbW1lclwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwid3JhcHBlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0cm9rZSBhbmltYXRlIHRpdGxlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Ryb2tlIGFuaW1hdGUgbGlua1wiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0cm9rZSBhbmltYXRlIGRlc2NyaXB0aW9uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gRW1wdHkgLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbG9hZGluZyAmJiBub0RhdGFcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLWxnLTEyIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgY2xhc3M9XCJpbWctc3JjIHctMjVcIiBzcmM9XCIuL2Fzc2V0cy90YW5nby9JY29ucy9Ob2RhdGEuc3ZnXCIgYWx0PVwiXCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gVHJhbnNhY3Rpb25zIHRhYmxlIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWxvYWRpbmcgJiYgIW5vRGF0YVwiIGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgYWNjb3JkaW9uIHRhYmxlIGJvdHRvbS1ib3JkZXIgaW52b2l2ZXRhYmxlIHRleHQtbm93cmFwXCI+XG4gICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+RGF0ZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+U291cmNlPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5QYXllciAoZnJvbSBuYXJyYXRpb24pPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5SZWZlcmVuY2UgLyBVVFI8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkFtb3VudDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+QnJhbmQgTmFtZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+SW52b2ljZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+UmVzdWx0PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5TdGF0dXM8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkFjdGlvbjwvdGg+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgdCBvZiByb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXRpdGxlXCI+e3sgdC52YWx1ZURhdGUgfCBkYXRlOiAnZGQgTU1NLCB5eXl5JyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyY2NoaXBcIiBbY2xhc3Muc3JjY2hpcC12YV09XCJ0LnNvdXJjZSA9PT0gJ3ZhJ1wiPnt7IHNvdXJjZUxhYmVsKHQuc291cmNlKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXRpdGxlIHBheWVyLWNlbGxcIj57eyB0LnBheWVyIHx8ICfigJQnIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5hcnJhdGlvbi1zdWJcIiBbdGl0bGVdPVwidC5uYXJyYXRpb25cIj57eyB0Lm5hcnJhdGlvbiB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vbm9cIj57eyB0LnJlZk5vIHx8ICfigJQnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGl0bGVcIj48c3Ryb25nPuKCuXt7IHQuYW1vdW50IHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Ryb25nPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGl0bGVcIj57eyB0LmlkZW50aWZpZWRDbGllbnROYW1lIHx8ICfigJQnIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS10aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIE11bHRpcGxlIGludm9pY2VzIHNldHRsZWQgYnkgb25lIHBheW1lbnQ6IGxpbmsgZWFjaCBpbmRpdmlkdWFsbHkuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidC5hcHBsaWVkSW52b2ljZXM/Lmxlbmd0aCA+IDE7IGVsc2Ugc2luZ2xlSW52XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBhIG9mIHQuYXBwbGllZEludm9pY2VzOyBsZXQgbGFzdCA9IGxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImludm9pY2UtbGlua1wiIChjbGljayk9XCJvcGVuSW52b2ljZVByZXZpZXdCeUlkKGEuaW52b2ljZUlkLCBhLmludm9pY2UpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj57eyBhLmludm9pY2UgfX08L2E+PHNwYW4gKm5nSWY9XCIhbGFzdFwiPiwgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZUludj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhICpuZ0lmPVwidC5pbnZvaWNlICYmIHQuaW52b2ljZUlkXCIgY2xhc3M9XCJpbnZvaWNlLWxpbmtcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvcGVuSW52b2ljZVByZXZpZXcodCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPnt7IHQuaW52b2ljZSB9fTwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwidC5pbnZvaWNlICYmICF0Lmludm9pY2VJZFwiPnt7IHQuaW52b2ljZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIXQuaW52b2ljZVwiPuKAlDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlc3VsdC1ub3RlXCIgW3RpdGxlXT1cInQucmVzdWx0Tm90ZVwiPnt7IHQucmVzdWx0Tm90ZSB8fCAn4oCUJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInQuY29udGFjdGVkXCIgY2xhc3M9XCJwaWxsIHBpbGwtYW1iZXJcIj5SZWFjaGluZyBvdXQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhdC5jb250YWN0ZWRcIiBbbmdDbGFzc109XCJzdGF0dXNQaWxsQ2xhc3ModC5zdGF0dXMpXCI+e3sgc3RhdHVzTGFiZWwodC5zdGF0dXMpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwidC5zdGF0dXMgPT09ICduZWVkc19yZXZpZXcnIHx8IHQuc3RhdHVzID09PSAndW5tYXRjaGVkJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tcHJpbWFyeVwiIChjbGljayk9XCJvcGVuUmVzb2x2ZSh0KVwiPlJlc29sdmU8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFJlY29uY2lsZWQgcm93czogRWRpdCByZS1vcGVucyB0aGUgUmVzb2x2ZSAmIHJlY29uY2lsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wdXAgc28gdGhlIG1hdGNoZWQgaW52b2ljZSAvIHJlc29sdXRpb24gY2FuIGJlIGNoYW5nZWQuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJ0LnN0YXR1cyA9PT0gJ3JlY29uY2lsZWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lXCIgKGNsaWNrKT1cIm9wZW5SZXNvbHZlKHQpXCI+RWRpdDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgIDxsaWItcGFnaW5hdGlvbiBjbGFzcz1cInRleHQtc3RhcnRcIiBbaXRlbXNQZXJQYWdlXT1cIml0ZW1zUGVyUGFnZVwiIFtjdXJyZW50UGFnZV09XCJjdXJyZW50UGFnZVwiXG4gICAgICAgICAgICAgICAgW3RvdGFsSXRlbXNdPVwidG90YWxJdGVtc1wiIFtwYWdpbmF0aW9uU2l6ZXNdPVwicGFnaW5hdGlvblNpemVzXCIgW3BhZ2VTaXplXT1cInBhZ2VTaXplXCJcbiAgICAgICAgICAgICAgICAocGFnZUNoYW5nZSk9XCJvblBhZ2VDaGFuZ2UoJGV2ZW50KVwiIChwYWdlU2l6ZUNoYW5nZSk9XCJvblBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj48L2xpYi1wYWdpbmF0aW9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PiJdfQ==
|
|
431
|
+
args: [{ selector: 'lib-bank-transactions', template: "<div>\n <!-- ============ Upload stage (no statements yet) ============ -->\n <div *ngIf=\"stage === 'upload' && !loading\" class=\"px-4 pb-4\">\n <div class=\"billingheader ms-1 mt-6\">Bank Statement Reconciliation</div>\n <div class=\"text-muted small ms-1 mt-1\">Upload a bank statement \u2014 transactions are stored and split into\n Reconciled, Needs review, Unmatched and Excluded.</div>\n <label class=\"dropzone mt-4\" for=\"stmt-file\">\n <div class=\"dz-ic\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 21V9M8 13l4-4 4 4M5 5h14\" />\n </svg>\n </div>\n <div class=\"dz-title mt-3\">Upload bank statement</div>\n <div class=\"text-muted small mt-1\">Drag & drop or click to browse \u00B7 <strong>Excel (.xlsx, .xls) or CSV</strong></div>\n <button type=\"button\" class=\"btn btn-primary btn-sm mt-3\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file').click(); event.preventDefault();\">\n {{ uploading ? 'Parsing\u2026' : 'Upload & parse' }}\n </button>\n </label>\n <input id=\"stmt-file\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\" (change)=\"onFileSelected($event)\">\n </div>\n\n <!-- ============ Results stage ============ -->\n <div *ngIf=\"stage === 'results'\">\n <!-- Upload-another action -->\n <div class=\"d-flex justify-content-end align-items-center mt-4 me-4\">\n <input id=\"stmt-file-again\" type=\"file\" accept=\".xlsx,.xls,.csv\" class=\"d-none\"\n (change)=\"onFileSelected($event)\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\" [disabled]=\"uploading\"\n onclick=\"document.getElementById('stmt-file-again').click()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"\n stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">{{ uploading ? 'Parsing\u2026' : 'Upload another statement' }}</span>\n </button>\n </div>\n\n <!-- Status cards \u2014 clicking a card filters the table (click again to clear) -->\n <div class=\"row g-3 mt-1 mb-2 mx-2\">\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'reconciled'\"\n (click)=\"toggleCardFilter('reconciled')\">\n <div class=\"invoice-card-label\">Reconciled\n <svg class=\"info-ic\" ngbTooltip=\"Payments automatically matched to an invoice (payer name + amount), or manually reconciled.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-success\">{{ cards.reconciled.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.reconciled.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'needs_review'\"\n (click)=\"toggleCardFilter('needs_review')\">\n <div class=\"invoice-card-label\">Needs review\n <svg class=\"info-ic\" ngbTooltip=\"Payer matches a customer but the amount doesn't match an invoice, or a dollar payment matched \u2014 confirm before reconciling.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-warning\">{{ cards.needs_review.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.needs_review.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'unmatched'\"\n (click)=\"toggleCardFilter('unmatched')\">\n <div class=\"invoice-card-label\">Unmatched\n <svg class=\"info-ic\" ngbTooltip=\"Payer name doesn't match any customer's invoice \u2014 identify the customer and map it manually.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value text-danger\">{{ cards.unmatched.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.unmatched.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n <div class=\"col\">\n <div class=\"invoice-card card-clickable\" [class.card-active]=\"activeStatus === 'excluded'\"\n (click)=\"toggleCardFilter('excluded')\">\n <div class=\"invoice-card-label\">Excluded\n <svg class=\"info-ic\" ngbTooltip=\"Not a customer payment (no payer name) or manually marked as not to be considered.\" placement=\"top\" (click)=\"$event.stopPropagation()\" xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5M12 8h.01\"/></svg>\n </div>\n <div class=\"invoice-card-value\">{{ cards.excluded.count }}</div>\n <div class=\"invoice-card-sub\">\u20B9{{ cards.excluded.amount | number:'1.2-2':'en-IN' }}</div>\n </div>\n </div>\n </div>\n\n <!-- Status tabs + search/filter -->\n <div class=\"card-header paymenthistory border-0\">\n <div class=\"d-flex align-items-center gap-2 flex-wrap\">\n <button *ngFor=\"let tab of statusTabs\" class=\"btn btn-sm status-tab\"\n [class.active]=\"activeStatus === tab.id\"\n (click)=\"setStatus(tab.id)\">\n {{ tab.label }}\n <span *ngIf=\"countOf(tab.id)\" class=\"countchip ms-1\">{{ countOf(tab.id) }}</span>\n </button>\n </div>\n <div class=\"card-toolbar ms-auto\">\n <div class=\"d-flex align-items-center position-relative my-1\">\n <span class=\"svg-icon invoicesearch svg-icon-1 position-absolute mt-6 ms-3\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <rect opacity=\"0.5\" x=\"17.0365\" y=\"15.1223\" width=\"8.15546\" height=\"2\" rx=\"1\"\n transform=\"rotate(45 17.0365 15.1223)\" fill=\"currentColor\"></rect>\n <path d=\"M11 19C6.55556 19 3 15.4444 3 11C3 6.55556 6.55556 3 11 3C15.4444 3 19 6.55556 19 11C19 15.4444 15.4444 19 11 19ZM11 5C7.53333 5 5 7.53333 5 11C5 14.4667 7.53333 17 11 17C14.4667 17 17 14.4667 17 11C17 7.53333 14.4667 5 11 5Z\"\n fill=\"currentColor\"></path>\n </svg>\n </span>\n <input [(ngModel)]=\"searchValue\" type=\"text\" class=\"form-control ps-14 invoicesearch\"\n placeholder=\"Search payer, narration, UTR...\" autocomplete=\"off\" (change)=\"searchField()\" />\n <!-- Filter dropdown \u2014 opens a self-contained popover anchored to\n the button (lib-filters can't host the date-range inputs). -->\n <div class=\"position-relative txn-filter-wrap\">\n <button type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader\"\n (click)=\"toggleFilter()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"#344054\" stroke-width=\"2\">\n <path d=\"M3 5h18M6 12h12M10 19h4\" />\n </svg>\n <span class=\"ms-2\">Filter</span>\n <span *ngIf=\"activeFilterCount\" class=\"countchip ms-1\">{{ activeFilterCount }}</span>\n </button>\n <div *ngIf=\"filterOpen\" class=\"txn-filter-pop card\">\n <div class=\"txn-filter-title\">Filter Options</div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 from</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftFromDate\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label small fw-semibold\">Date \u2014 to</label>\n <input type=\"date\" class=\"form-control\" [(ngModel)]=\"draftToDate\">\n </div>\n <div class=\"mb-2\">\n <label class=\"form-label small fw-semibold\">Source</label>\n <select class=\"form-select\" [(ngModel)]=\"draftSource\">\n <option value=\"all\">All sources</option>\n <option value=\"bank\">Bank Statement</option>\n <option value=\"va\">Virtual Account</option>\n <option value=\"gateway\">Gateway</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"d-flex justify-content-end mb-2\" *ngIf=\"activeFilterCount\">\n <button class=\"btn btn-link btn-sm p-0\" (click)=\"clearFilters()\">Clear all</button>\n </div>\n <!-- Filters apply only on Apply; Cancel discards changes. -->\n <div class=\"d-flex gap-2 mt-2\">\n <button class=\"btn btn-outline-secondary btn-sm flex-fill\" (click)=\"cancelFilters()\">Cancel</button>\n <button class=\"btn btn-primary btn-sm flex-fill\" (click)=\"applyFilters()\">Apply</button>\n </div>\n </div>\n </div>\n <!-- Delete selected (non-reconciled) rows. -->\n <button *ngIf=\"selectedCount > 0 && (gs.userAccess | async)?.Global_Billing_isEdit\"\n type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader ms-2 delete-all-btn\"\n (click)=\"deleteSelected()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"\n stroke=\"#D92D20\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">Delete selected ({{ selectedCount }})</span>\n </button>\n <!-- Delete all (non-reconciled) for the current statement batch.\n Reconciled rows are always preserved by the backend. -->\n <button *ngIf=\"!noData && (gs.userAccess | async)?.Global_Billing_isEdit\"\n type=\"button\" class=\"btn-outline btn align-items-end text-nowrap invheader ms-2 delete-all-btn\"\n (click)=\"deleteAll()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"\n stroke=\"#D92D20\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"ms-2\">Delete all</span>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Loading shimmer -->\n <ng-container *ngIf=\"loading\">\n <div class=\"row loader d-flex justify-content-center align-items-center\">\n <div class=\"shimmer\">\n <div class=\"wrapper\">\n <div class=\"stroke animate title\"></div>\n <div class=\"stroke animate link\"></div>\n <div class=\"stroke animate description\"></div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Empty -->\n <ng-container *ngIf=\"!loading && noData\">\n <div class=\"row\">\n <div class=\"col-lg-12 mb-3\">\n <div class=\"card-body d-flex justify-content-center align-items-center flex-column\">\n <img class=\"img-src w-25\" src=\"./assets/tango/Icons/Nodata.svg\" alt=\"\">\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- Transactions table -->\n <div *ngIf=\"!loading && !noData\" class=\"table-responsive\">\n <table class=\"table accordion table bottom-border invoivetable text-nowrap\">\n <thead>\n <tr>\n <th *ngIf=\"(gs.userAccess | async)?.Global_Billing_isEdit\" style=\"width:40px;\">\n <input type=\"checkbox\" [checked]=\"allSelected\" (change)=\"toggleSelectAll($event)\"\n [disabled]=\"selectableRows.length === 0\" ngbTooltip=\"Select all (excludes reconciled)\">\n </th>\n <th>Date</th>\n <th>Source</th>\n <th>Payer (from narration)</th>\n <th>Reference / UTR</th>\n <th>Amount</th>\n <th>Brand Name</th>\n <th>Invoice</th>\n <th>Result</th>\n <th>Status</th>\n <th>Action</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let t of rows\">\n <td *ngIf=\"(gs.userAccess | async)?.Global_Billing_isEdit\" style=\"width:40px;\">\n <!-- Reconciled rows can't be selected. -->\n <input type=\"checkbox\" *ngIf=\"isSelectable(t)\" [checked]=\"isSelected(t)\" (change)=\"toggleSelect(t)\">\n <span *ngIf=\"!isSelectable(t)\" class=\"lock-ic\" ngbTooltip=\"Reconciled \u2014 cannot be deleted\">\uD83D\uDD12</span>\n </td>\n <td>\n <div class=\"table-title\">{{ t.valueDate | date: 'dd MMM, yyyy' }}</div>\n </td>\n <td>\n <span class=\"srcchip\" [class.srcchip-va]=\"t.source === 'va'\">{{ sourceLabel(t.source) }}</span>\n </td>\n <td>\n <div class=\"table-title payer-cell\">{{ t.payer || '\u2014' }}</div>\n <div class=\"narration-sub\" [title]=\"t.narration\">{{ t.narration }}</div>\n </td>\n <td>\n <span class=\"mono\">{{ t.refNo || '\u2014' }}</span>\n </td>\n <td>\n <div class=\"table-title\"><strong>\u20B9{{ t.amount | number:'1.2-2':'en-IN' }}</strong></div>\n </td>\n <td>\n <div class=\"table-title\">{{ t.identifiedClientName || '\u2014' }}</div>\n </td>\n <td>\n <div class=\"table-title\">\n <!-- Multiple invoices settled by one payment: link each individually. -->\n <ng-container *ngIf=\"t.appliedInvoices?.length > 1; else singleInv\">\n <ng-container *ngFor=\"let a of t.appliedInvoices; let last = last\">\n <a class=\"invoice-link\" (click)=\"openInvoicePreviewById(a.invoiceId, a.invoice); $event.stopPropagation()\">{{ a.invoice }}</a><span *ngIf=\"!last\">, </span>\n </ng-container>\n </ng-container>\n <ng-template #singleInv>\n <a *ngIf=\"t.invoice && t.invoiceId\" class=\"invoice-link\"\n (click)=\"openInvoicePreview(t); $event.stopPropagation()\">{{ t.invoice }}</a>\n <span *ngIf=\"t.invoice && !t.invoiceId\">{{ t.invoice }}</span>\n <span *ngIf=\"!t.invoice\">\u2014</span>\n </ng-template>\n </div>\n </td>\n <td>\n <div class=\"result-note\" [title]=\"t.resultNote\">{{ t.resultNote || '\u2014' }}</div>\n </td>\n <td>\n <span *ngIf=\"t.contacted\" class=\"pill pill-amber\">Reaching out</span>\n <span *ngIf=\"!t.contacted\" [ngClass]=\"statusPillClass(t.status)\">{{ statusLabel(t.status) }}</span>\n </td>\n <td>\n <button *ngIf=\"t.status === 'needs_review' || t.status === 'unmatched'\"\n class=\"btn btn-sm btn-primary\" (click)=\"openResolve(t)\">Resolve</button>\n <!-- Reconciled rows: Edit re-opens the Resolve & reconcile\n popup so the matched invoice / resolution can be changed. -->\n <button *ngIf=\"t.status === 'reconciled'\"\n class=\"btn btn-sm btn-outline\" (click)=\"openResolve(t)\">Edit</button>\n <!-- Delete: reconciled rows are protected and never deletable. -->\n <button *ngIf=\"t.status !== 'reconciled' && (gs.userAccess | async)?.Global_Billing_isEdit\"\n class=\"btn btn-sm btn-icon delete-txn\" ngbTooltip=\"Delete transaction\"\n (click)=\"deleteTransaction(t)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M3 6h18M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 5v6m4-6v6\"\n stroke=\"#D92D20\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </td>\n </tr>\n </tbody>\n </table>\n <lib-pagination class=\"text-start\" [itemsPerPage]=\"itemsPerPage\" [currentPage]=\"currentPage\"\n [totalItems]=\"totalItems\" [paginationSizes]=\"paginationSizes\" [pageSize]=\"pageSize\"\n (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\n </div>\n </div>\n</div>", styles: [".dropzone{display:block;border:1.5px dashed #E4E7EC;border-radius:14px;padding:34px;text-align:center;cursor:pointer;background:#fbfdff;transition:border-color .15s,background .15s}.dropzone:hover{border-color:#1493f5;background:#f5faff}.dz-ic{width:52px;height:52px;border-radius:14px;background:#e8f3fe;color:#1493f5;display:grid;place-items:center;margin:0 auto}.dz-title{font-weight:700;font-size:15px;color:#101828}.invoice-card{border:1px solid #E4E7EC;border-radius:12px;padding:18px 22px;background:#fff}.invoice-card.card-clickable{cursor:pointer;transition:border-color .12s,box-shadow .12s}.invoice-card.card-clickable:hover{border-color:#bcd9f7}.invoice-card.card-active{border-color:#1493f5;box-shadow:0 0 0 3px #1493f51f}.status-tab{border:0;border-radius:8px;padding:7px 14px;font-weight:600;color:#5b6472;background:transparent}.status-tab:hover{background:#f4f6f9}.status-tab.active{background:#e8f3fe;color:#1493f5}.status-tab.active .countchip{background:#d3e9fd;color:#1573c4}.invoice-card-label{color:#475467;font-size:13.5px;font-weight:500}.invoice-card-value{font-size:22px;font-weight:700;color:#101828;margin-top:6px;letter-spacing:-.3px}.invoice-card-value.text-success{color:#138a52}.invoice-card-value.text-danger{color:#d64545}.invoice-card-value.text-warning{color:#b9740a}.invoice-card-sub{color:#98a2b3;font-size:12.5px;margin-top:4px}.pill{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}.pill-green{background:#e7f7ee;color:#138a52}.pill-amber{background:#fdf0dc;color:#b9740a}.pill-red{background:#fdecec;color:#d64545}.pill-gray{background:#f1f3f6;color:#667085}.srcchip{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 9px;border-radius:999px;border:1px solid #E4E7EC;color:#475467;background:#fff;white-space:nowrap}.srcchip.srcchip-va{color:#7a3ea8;border-color:#e4d4f3;background:#f7f0fc}.countchip{background:#f1f3f6;color:#667085;font-weight:600;font-size:11px;border-radius:999px;padding:1px 8px}.payer-cell{max-width:230px;white-space:normal;line-height:1.35;font-weight:600}.narration-sub{max-width:230px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#98a2b3;font-size:11.5px;margin-top:2px}.result-note{max-width:220px;white-space:normal;line-height:1.4;color:#475467;font-size:12.5px}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;color:#344054}.filter-panel{border:1px solid #E4E7EC;border-radius:14px;padding:16px 18px;background:#fbfdff}.invoice-link{color:#00a3ff;cursor:pointer;text-decoration:none}.invoice-link:hover{text-decoration:underline}.txn-filter-wrap{margin-left:10px}.txn-filter-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:40;width:280px;padding:16px;border:1px solid #E4E7EC;border-radius:12px;box-shadow:0 8px 24px #1018281f;background:#fff}.txn-filter-title{font-weight:700;color:#101828;font-size:14px;margin-bottom:12px}.invoice-card-label .info-ic{color:#c4c9d2;cursor:help;vertical-align:middle;margin-left:4px}.svg-icon.invoicesearch.position-absolute{top:50%;transform:translateY(-50%);margin-top:0!important}\n"] }]
|
|
432
|
+
}], ctorParameters: () => [{ type: i1.BillingService }, { type: i2.ToastService }, { type: i0.ChangeDetectorRef }, { type: i3.NgbModal }, { type: i4.GlobalStateService }] });
|
|
433
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFuay10cmFuc2FjdGlvbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tbWFuYWdlLWJpbGxpbmcvc3JjL2xpYi9jb21wb25lbnRzL2JhbmstdHJhbnNhY3Rpb25zL2JhbmstdHJhbnNhY3Rpb25zLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy9iYW5rLXRyYW5zYWN0aW9ucy9iYW5rLXRyYW5zYWN0aW9ucy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXFCLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDaEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJMUMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDbEcsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sMkVBQTJFLENBQUM7Ozs7Ozs7O0FBR3hILDJFQUEyRTtBQUMzRSw0RUFBNEU7QUFDNUUsNkVBQTZFO0FBQzdFLHlFQUF5RTtBQU16RSxNQUFNLE9BQU8seUJBQXlCO0lBb0QxQjtJQUNBO0lBQ0E7SUFDQTtJQUNEO0lBdkRULDRFQUE0RTtJQUM1RSxLQUFLLEdBQXlCLFFBQVEsQ0FBQztJQUN2QyxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ2YsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBRWYsSUFBSSxHQUFVLEVBQUUsQ0FBQztJQUNqQixVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsS0FBSyxHQUFHO1FBQ04sVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFB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QUFDLEtBQWEsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxDQUFDO0lBQzdDLENBQUM7d0dBbmFVLHlCQUF5Qjs0RkFBekIseUJBQXlCLDZEQ25CdEMsZzhwQkFtU007OzRGRGhSTyx5QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0UsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgT25EZXN0cm95LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTmdiTW9kYWwgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XG5pbXBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktc2hhcmVkJztcbmltcG9ydCB7IEJpbGxpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYmlsbGluZy5zZXJ2aWNlJztcbmltcG9ydCB7IEludm9pY2VQcmV2aWV3Q29tcG9uZW50IH0gZnJvbSAnLi4vaW52b2ljZS1wcmV2aWV3L2ludm9pY2UtcHJldmlldy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVzb2x2ZVRyYW5zYWN0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9yZXNvbHZlLXRyYW5zYWN0aW9uL3Jlc29sdmUtdHJhbnNhY3Rpb24uY29tcG9uZW50JztcbmltcG9ydCB7IERlbGV0ZUNvbmZpcm1hdGlvbkNvbXBvbmVudCB9IGZyb20gJy4uL3RhbmdvLW1hbmFnZS1iaWxsaW5nL2RlbGV0ZS1jb25maXJtYXRpb24vZGVsZXRlLWNvbmZpcm1hdGlvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgR2xvYmFsU3RhdGVTZXJ2aWNlIH0gZnJvbSAndGFuZ28tYXBwLXVpLWdsb2JhbCc7XG5cbi8vIEJhbmstc3RhdGVtZW50IHJlY29uY2lsaWF0aW9uIHRhYi4gVXBsb2FkIGEgc3RhdGVtZW50IGV4cG9ydCAoQ1NWL1hMU1gpLFxuLy8gcm93cyBsYW5kIGluIHRoZSBgYmFua3RyYW5zYWN0aW9uYCBjb2xsZWN0aW9uIGFuZCBhcmUgYnVja2V0ZWQgYnkgc3RhdHVzOlxuLy8gcmVjb25jaWxlZCAvIG5lZWRzX3JldmlldyAvIHVubWF0Y2hlZCAvIGV4Y2x1ZGVkLiBDbGFzc2lmaWNhdGlvbiBydWxlcyBhcmVcbi8vIG5vdCB3aXJlZCB5ZXQg4oCUIG5ldyByb3dzIGFycml2ZSBhcyAndW5tYXRjaGVkJyB1bnRpbCB0aGF0IHBhc3MgZXhpc3RzLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLWJhbmstdHJhbnNhY3Rpb25zJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2JhbmstdHJhbnNhY3Rpb25zLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2JhbmstdHJhbnNhY3Rpb25zLmNvbXBvbmVudC5zY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBCYW5rVHJhbnNhY3Rpb25zQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvLyAndXBsb2FkJyBzaG93cyB0aGUgZHJvcHpvbmUgKGVtcHR5IGNvbGxlY3Rpb24pOyAncmVzdWx0cycgdGhlIHRhYmxlIHZpZXcuXG4gIHN0YWdlOiAndXBsb2FkJyB8ICdyZXN1bHRzJyA9ICd1cGxvYWQnO1xuICBsb2FkaW5nID0gdHJ1ZTtcbiAgdXBsb2FkaW5nID0gZmFsc2U7XG4gIG5vRGF0YSA9IGZhbHNlO1xuXG4gIHJvd3M6IGFueVtdID0gW107XG4gIHRvdGFsSXRlbXMgPSAwO1xuICBjYXJkcyA9IHtcbiAgICByZWNvbmNpbGVkOiB7IGNvdW50OiAwLCBhbW91bnQ6IDAgfSxcbiAgICBuZWVkc19yZXZpZXc6IHsgY291bnQ6IDAsIGFtb3VudDogMCB9LFxuICAgIHVubWF0Y2hlZDogeyBjb3VudDogMCwgYW1vdW50OiAwIH0sXG4gICAgZXhjbHVkZWQ6IHsgY291bnQ6IDAsIGFtb3VudDogMCB9LFxuICAgIHRvdGFsOiAwLFxuICB9O1xuXG4gIC8vIFN0YXR1cyBzZWdtZW50IHRhYnMg4oCUIGlkcyBtYXRjaCB0aGUgYmFja2VuZCBlbnVtLlxuICBzdGF0dXNUYWJzID0gW1xuICAgIHsgaWQ6ICdhbGwnLCBsYWJlbDogJ0FsbCcgfSxcbiAgICB7IGlkOiAncmVjb25jaWxlZCcsIGxhYmVsOiAnUmVjb25jaWxlZCcgfSxcbiAgICB7IGlkOiAnbmVlZHNfcmV2aWV3JywgbGFiZWw6ICdOZWVkcyByZXZpZXcnIH0sXG4gICAgeyBpZDogJ3VubWF0Y2hlZCcsIGxhYmVsOiAnVW5tYXRjaGVkJyB9LFxuICAgIHsgaWQ6ICdleGNsdWRlZCcsIGxhYmVsOiAnRXhjbHVkZWQnIH0sXG4gIF07XG4gIGFjdGl2ZVN0YXR1cyA9ICdhbGwnO1xuXG4gIC8vIEZpbHRlciBwb3BvdmVyIHN0YXRlLlxuICBmaWx0ZXJPcGVuID0gZmFsc2U7XG4gIC8vIENvbW1pdHRlZCAoYXBwbGllZCkgZmlsdGVyIHZhbHVlcyDigJQgdGhlc2UgZHJpdmUgdGhlIGxpc3QuXG4gIGZyb21EYXRlID0gJyc7XG4gIHRvRGF0ZSA9ICcnO1xuICBzb3VyY2UgPSAnYWxsJztcbiAgLy8gRHJhZnQgdmFsdWVzIGJvdW5kIHRvIHRoZSBwb3BvdmVyIGlucHV0cy4gTm90aGluZyBpcyBhcHBsaWVkIHVudGlsIHRoZVxuICAvLyB1c2VyIGNsaWNrcyBBcHBseTsgQ2FuY2VsIGRpc2NhcmRzIHRoZXNlIGJhY2sgdG8gdGhlIGNvbW1pdHRlZCB2YWx1ZXMuXG4gIGRyYWZ0RnJvbURhdGUgPSAnJztcbiAgZHJhZnRUb0RhdGUgPSAnJztcbiAgZHJhZnRTb3VyY2UgPSAnYWxsJztcbiAgc2VhcmNoVmFsdWUgPSAnJztcblxuICAvLyBQYWdpbmF0aW9uIOKAlCBtaXJyb3JzIHRoZSBBbGwgSW52b2ljZXMgdGFibGUuXG4gIGN1cnJlbnRQYWdlID0gMTtcbiAgcGFnZVNpemUgPSAxMDtcbiAgaXRlbXNQZXJQYWdlID0gMTA7XG4gIHBhZ2luYXRpb25TaXplcyA9IFsxMCwgMjAsIDMwXTtcblxuICAvLyBNdWx0aS1zZWxlY3QgZm9yIGJ1bGsgZGVsZXRlLiBSZWNvbmNpbGVkIHJvd3MgYXJlIG5ldmVyIHNlbGVjdGFibGUuXG4gIHNlbGVjdGVkSWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBiaWxsaW5nU2VydmljZTogQmlsbGluZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSB0b2FzdDogVG9hc3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgbW9kYWxTZXJ2aWNlOiBOZ2JNb2RhbCxcbiAgICBwdWJsaWMgZ3M6IEdsb2JhbFN0YXRlU2VydmljZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubG9hZExpc3QodHJ1ZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvLyBmaXJzdExvYWQgZGVjaWRlcyB0aGUgc3RhZ2U6IGFuIGVtcHR5LCB1bmZpbHRlcmVkIGNvbGxlY3Rpb24gbWVhbnMgdGhlXG4gIC8vIHVzZXIgaGFzIG5ldmVyIHVwbG9hZGVkIOKAlCBzaG93IHRoZSBkcm9wem9uZSBpbnN0ZWFkIG9mIGFuIGVtcHR5IHRhYmxlLlxuICBsb2FkTGlzdChmaXJzdExvYWQgPSBmYWxzZSkge1xuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgY29uc3QgZmlsdGVycyA9IHtcbiAgICAgIHN0YXR1czogdGhpcy5hY3RpdmVTdGF0dXMsXG4gICAgICBmcm9tOiB0aGlzLmZyb21EYXRlLFxuICAgICAgdG86IHRoaXMudG9EYXRlLFxuICAgICAgc291cmNlOiB0aGlzLnNvdXJjZSxcbiAgICAgIHNlYXJjaFZhbHVlOiB0aGlzLnNlYXJjaFZhbHVlLFxuICAgICAgbGltaXQ6IHRoaXMucGFnZVNpemUsXG4gICAgICBvZmZzZXQ6IHRoaXMuY3VycmVudFBhZ2UsXG4gICAgfTtcbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmJhbmtUcmFuc2FjdGlvbkxpc3QoZmlsdGVycykucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzKSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJvd3MgPSByZXM/LmRhdGE/LmRhdGEgfHwgW107XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJZHMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy50b3RhbEl0ZW1zID0gcmVzPy5kYXRhPy5jb3VudCB8fCAwO1xuICAgICAgICBpZiAocmVzPy5kYXRhPy5jYXJkcykge1xuICAgICAgICAgIHRoaXMuY2FyZHMgPSByZXMuZGF0YS5jYXJkcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vRGF0YSA9IHRoaXMucm93cy5sZW5ndGggPT09IDA7XG4gICAgICAgIGlmIChmaXJzdExvYWQpIHtcbiAgICAgICAgICB0aGlzLnN0YWdlID0gdGhpcy5jYXJkcy50b3RhbCA+IDAgPyAncmVzdWx0cycgOiAndXBsb2FkJztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yb3dzID0gW107XG4gICAgICAgIHRoaXMudG90YWxJdGVtcyA9IDA7XG4gICAgICAgIHRoaXMubm9EYXRhID0gdHJ1ZTtcbiAgICAgICAgaWYgKGZpcnN0TG9hZCkge1xuICAgICAgICAgIHRoaXMuc3RhZ2UgPSAndXBsb2FkJztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBvbkZpbGVTZWxlY3RlZChldmVudDogYW55KSB7XG4gICAgY29uc3QgZmlsZTogRmlsZSA9IGV2ZW50Py50YXJnZXQ/LmZpbGVzPy5bMF07XG4gICAgaWYgKCFmaWxlKSByZXR1cm47XG4gICAgY29uc3Qgb2sgPSAvXFwuKHhsc3h8eGxzfGNzdikkL2kudGVzdChmaWxlLm5hbWUpO1xuICAgIGlmICghb2spIHtcbiAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnVXBsb2FkIHRoZSBiYW5rIHN0YXRlbWVudCBhcyBFeGNlbCAoLnhsc3gsIC54bHMpIG9yIENTVicpO1xuICAgICAgZXZlbnQudGFyZ2V0LnZhbHVlID0gJyc7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudXBsb2FkaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLnVwbG9hZEJhbmtTdGF0ZW1lbnQoZmlsZSkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzKSA9PiB7XG4gICAgICAgIHRoaXMudXBsb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGQgPSByZXM/LmRhdGEgfHwge307XG4gICAgICAgIGNvbnN0IHMgPSBkLnN1bW1hcnkgfHwge307XG4gICAgICAgIGxldCBtc2cgPSBgXCIke2ZpbGUubmFtZX1cIiDigJQgJHtkLmluc2VydGVkIHx8IDB9IHRyYW5zYWN0aW9ucyBhZGRlZGA7XG4gICAgICAgIGlmIChkLmluc2VydGVkKSB7XG4gICAgICAgICAgbXNnICs9IGA6ICR7cy5yZWNvbmNpbGVkIHx8IDB9IHJlY29uY2lsZWQsICR7cy5uZWVkc19yZXZpZXcgfHwgMH0gbmVlZCByZXZpZXcsIGAgK1xuICAgICAgICAgICAgICAgICBgJHtzLnVubWF0Y2hlZCB8fCAwfSB1bm1hdGNoZWQsICR7cy5leGNsdWRlZCB8fCAwfSBleGNsdWRlZGA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGQuZHVwbGljYXRlcykgbXNnICs9IGAgKCR7ZC5kdXBsaWNhdGVzfSBkdXBsaWNhdGVzIHNraXBwZWQpYDtcbiAgICAgICAgaWYgKGQuY2xvc2VkSW52b2ljZXM/Lmxlbmd0aCkgbXNnICs9IGAgwrcgJHtkLmNsb3NlZEludm9pY2VzLmxlbmd0aH0gaW52b2ljZShzKSBjbG9zZWQgYXMgcGFpZGA7XG4gICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KG1zZyk7XG4gICAgICAgIC8vIEF1dG8tcmVjb25jaWxpYXRpb24gbWF5IGhhdmUgY2xvc2VkIGludm9pY2VzIOKAlCByZWZldGNoIG9wdGlvbnMgbmV4dCB0aW1lLlxuICAgICAgICB0aGlzLnJlc29sdmVPcHRpb25zQ2FjaGUgPSBudWxsO1xuICAgICAgICB0aGlzLnN0YWdlID0gJ3Jlc3VsdHMnO1xuICAgICAgICB0aGlzLmFjdGl2ZVN0YXR1cyA9ICdhbGwnO1xuICAgICAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcbiAgICAgICAgdGhpcy5sb2FkTGlzdCgpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgIHRoaXMudXBsb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdChlcnI/LmVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gcGFyc2UgdGhlIHN0YXRlbWVudCBmaWxlJyk7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgICBldmVudC50YXJnZXQudmFsdWUgPSAnJztcbiAgfVxuXG4gIHNldFN0YXR1cyhpZDogc3RyaW5nKSB7XG4gICAgdGhpcy5hY3RpdmVTdGF0dXMgPSBpZDtcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcbiAgICB0aGlzLmxvYWRMaXN0KCk7XG4gIH1cblxuICAvLyBTdGF0IGNhcmRzIGRvdWJsZSBhcyBmaWx0ZXJzOiBjbGlja2luZyBzZWxlY3RzIHRoYXQgc3RhdHVzLCBjbGlja2luZyB0aGVcbiAgLy8gYWxyZWFkeS1zZWxlY3RlZCBjYXJkIGNsZWFycyBiYWNrIHRvIEFsbC5cbiAgdG9nZ2xlQ2FyZEZpbHRlcihpZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zZXRTdGF0dXModGhpcy5hY3RpdmVTdGF0dXMgPT09IGlkID8gJ2FsbCcgOiBpZCk7XG4gIH1cblxuICB0b2dnbGVGaWx0ZXIoKSB7XG4gICAgLy8gT3BlbmluZzogc2VlZCB0aGUgZHJhZnQgaW5wdXRzIGZyb20gdGhlIGN1cnJlbnRseS1hcHBsaWVkIGZpbHRlcnMgc28gdGhlXG4gICAgLy8gcG9wb3ZlciByZWZsZWN0cyB3aGF0J3MgYWN0aXZlLiBDbG9zaW5nIHZpYSB0aGUgYnV0dG9uID0gY2FuY2VsLlxuICAgIGlmICghdGhpcy5maWx0ZXJPcGVuKSB7XG4gICAgICB0aGlzLmRyYWZ0RnJvbURhdGUgPSB0aGlzLmZyb21EYXRlO1xuICAgICAgdGhpcy5kcmFmdFRvRGF0ZSA9IHRoaXMudG9EYXRlO1xuICAgICAgdGhpcy5kcmFmdFNvdXJjZSA9IHRoaXMuc291cmNlO1xuICAgICAgdGhpcy5maWx0ZXJPcGVuID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5maWx0ZXJPcGVuID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29tbWl0IHRoZSBkcmFmdCBzZWxlY3Rpb25zIGFuZCByZWxvYWQuIE9ubHkgbm93IGRvZXMgdGhlIGZpbHRlciB0YWtlXG4gIC8vIGVmZmVjdDsgdGhlIHBvcG92ZXIgY2xvc2VzLlxuICBhcHBseUZpbHRlcnMoKSB7XG4gICAgdGhpcy5mcm9tRGF0ZSA9IHRoaXMuZHJhZnRGcm9tRGF0ZTtcbiAgICB0aGlzLnRvRGF0ZSA9IHRoaXMuZHJhZnRUb0RhdGU7XG4gICAgdGhpcy5zb3VyY2UgPSB0aGlzLmRyYWZ0U291cmNlO1xuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xuICAgIHRoaXMuZmlsdGVyT3BlbiA9IGZhbHNlO1xuICAgIHRoaXMubG9hZExpc3QoKTtcbiAgfVxuXG4gIC8vIERpc2NhcmQgZHJhZnQgZWRpdHMgYW5kIGNsb3NlIHdpdGhvdXQgYXBwbHlpbmcuXG4gIGNhbmNlbEZpbHRlcnMoKSB7XG4gICAgdGhpcy5kcmFmdEZyb21EYXRlID0gdGhpcy5mcm9tRGF0ZTtcbiAgICB0aGlzLmRyYWZ0VG9EYXRlID0gdGhpcy50b0RhdGU7XG4gICAgdGhpcy5kcmFmdFNvdXJjZSA9IHRoaXMuc291cmNlO1xuICAgIHRoaXMuZmlsdGVyT3BlbiA9IGZhbHNlO1xuICB9XG5cbiAgY2xlYXJGaWx0ZXJzKCkge1xuICAgIHRoaXMuZnJvbURhdGUgPSAnJztcbiAgICB0aGlzLnRvRGF0ZSA9ICcnO1xuICAgIHRoaXMuc291cmNlID0gJ2FsbCc7XG4gICAgdGhpcy5kcmFmdEZyb21EYXRlID0gJyc7XG4gICAgdGhpcy5kcmFmdFRvRGF0ZSA9ICcnO1xuICAgIHRoaXMuZHJhZnRTb3VyY2UgPSAnYWxsJztcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcbiAgICB0aGlzLmZpbHRlck9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmxvYWRMaXN0KCk7XG4gIH1cblxuICBnZXQgYWN0aXZlRmlsdGVyQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKHRoaXMuZnJvbURhdGUgPyAxIDogMCkgKyAodGhpcy50b0RhdGUgPyAxIDogMCkgKyAodGhpcy5zb3VyY2UgIT09ICdhbGwnID8gMSA6IDApO1xuICB9XG5cbiAgc2VhcmNoRmllbGQoKSB7XG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XG4gICAgdGhpcy5sb2FkTGlzdCgpO1xuICB9XG5cbiAgb25QYWdlQ2hhbmdlKHBhZ2U6IG51bWJlcikge1xuICAgIHRoaXMuY3VycmVudFBhZ2UgPSBwYWdlO1xuICAgIHRoaXMubG9hZExpc3QoKTtcbiAgfVxuXG4gIG9uUGFnZVNpemVDaGFuZ2Uoc2l6ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5wYWdlU2l6ZSA9IHNpemU7XG4gICAgdGhpcy5pdGVtc1BlclBhZ2UgPSBzaXplO1xuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xuICAgIHRoaXMubG9hZExpc3QoKTtcbiAgfVxuXG4gIC8vIFJlY29uY2lsZWQgcm93cyBjYXJyeSB0aGUgbWF0Y2hlZCBpbnZvaWNlJ3MgX2lkIOKAlCBvcGVuIHRoZSBzYW1lIHByZXZpZXdcbiAgLy8gcG9wdXAgdGhlIEFsbCBJbnZvaWNlcyB0YWJsZSB1c2VzLlxuICBvcGVuSW52b2ljZVByZXZpZXcodDogYW55KSB7XG4gICAgdGhpcy5vcGVuSW52b2ljZVByZXZpZXdCeUlkKHQ/Lmludm9pY2VJZCk7XG4gIH1cblxuICAvLyBPcGVuIHRoZSBpbnZvaWNlIHByZXZpZXcgZm9yIGEgc3BlY2lmaWMgaW52b2ljZSBpZCDigJQgdXNlZCBieSB0aGUgc2luZ2xlXG4gIC8vIGFuZCBtdWx0aS1pbnZvaWNlIChhcHBsaWVkSW52b2ljZXMpIGNlbGxzIGFsaWtlLlxuICBvcGVuSW52b2ljZVByZXZpZXdCeUlkKGludm9pY2VJZDogc3RyaW5nLCBfaW52b2ljZU5vPzogc3RyaW5nKSB7XG4gICAgaWYgKCFpbnZvaWNlSWQpIHJldHVybjtcbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmdldEludm9pY2VCeUlkKGludm9pY2VJZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgaW52b2ljZURhdGEgPSByZXM/LmRhdGE7XG4gICAgICAgIGlmICghaW52b2ljZURhdGEpIHtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBsb2FkIGludm9pY2UnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbW9kYWxSZWYgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKEludm9pY2VQcmV2aWV3Q29tcG9uZW50LCB7XG4gICAgICAgICAgY2VudGVyZWQ6IHRydWUsIHNpemU6ICd4bCcsIHNjcm9sbGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBtb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS5pbnZvaWNlRGF0YSA9IGludm9pY2VEYXRhO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBsb2FkIGludm9pY2UnKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFwiUmVzb2x2ZSAmIHJlY29uY2lsZVwiIHBvcHVwIGZvciBuZWVkcy1yZXZpZXcgLyB1bm1hdGNoZWQgcm93cy4gVGhlXG4gIC8vIGN1c3RvbWVyL2ludm9pY2Ugb3B0aW9ucyBhcmUgY2FjaGVkIGZvciB0aGUgcGFnZSBzZXNzaW9uIOKAlCBmZXRjaGVkIG9uY2UsXG4gIC8vIGludmFsaWRhdGVkIG9ubHkgd2hlbiBhbiBhY3Rpb24gY2hhbmdlcyBpbnZvaWNlIHN0YXRlIChyZWNvbmNpbGUpIG9yIGFcbiAgLy8gbmV3IHN0YXRlbWVudCBpcyB1cGxvYWRlZC5cbiAgcHJpdmF0ZSByZXNvbHZlT3B0aW9uc0NhY2hlOiBhbnlbXSB8IG51bGwgPSBudWxsO1xuXG4gIG9wZW5SZXNvbHZlKHQ6IGFueSkge1xuICAgIGlmICh0aGlzLnJlc29sdmVPcHRpb25zQ2FjaGUpIHtcbiAgICAgIHRoaXMuc2hvd1Jlc29sdmVNb2RhbCh0LCB0aGlzLnJlc29sdmVPcHRpb25zQ2FjaGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmJhbmtSZXNvbHZlT3B0aW9ucygpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlcykgPT4ge1xuICAgICAgICB0aGlzLnJlc29sdmVPcHRpb25zQ2FjaGUgPSByZXM/LmRhdGEgfHwgW107XG4gICAgICAgIHRoaXMuc2hvd1Jlc29sdmVNb2RhbCh0LCB0aGlzLnJlc29sdmVPcHRpb25zQ2FjaGUhKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4gdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gbG9hZCBjdXN0b21lcnMgYW5kIGludm9pY2VzJyksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNob3dSZXNvbHZlTW9kYWwodDogYW55LCBvcHRpb25zOiBhbnlbXSkge1xuICAgIGNvbnN0IG1vZGFsUmVmID0gdGhpcy5tb2RhbFNlcnZpY2Uub3BlbihSZXNvbHZlVHJhbnNhY3Rpb25Db21wb25lbnQsIHtcbiAgICAgIGNlbnRlcmVkOiB0cnVlLCBzaXplOiAnbWQnLCBzY3JvbGxhYmxlOiB0cnVlLFxuICAgIH0pO1xuICAgIG1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLnR4biA9IHQ7XG4gICAgbW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2Uub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgbW9kYWxSZWYucmVzdWx0LnRoZW4oKG1zZzogYW55KSA9PiB7XG4gICAgICBpZiAobXNnKSB7XG4gICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KFN0cmluZyhtc2cpKTtcbiAgICAgICAgLy8gQSByZXNvbHZlIG1heSBoYXZlIGNsb3NlZC9wYXJ0aWFsbHktcGFpZCBhbiBpbnZvaWNlIOKAlCByZWZldGNoIG5leHQgdGltZS5cbiAgICAgICAgdGhpcy5yZXNvbHZlT3B0aW9uc0NhY2hlID0gbnVsbDtcbiAgICAgICAgdGhpcy5sb2FkTGlzdCgpO1xuICAgICAgfVxuICAgIH0pLmNhdGNoKCgpID0+IHt9KTtcbiAgfVxuXG4gIC8vID09PT09IFNlbGVjdGlvbiAoYnVsayBkZWxldGUpID09PT09XG4gIC8vIEEgcm93IGlzIHNlbGVjdGFibGUgb25seSBpZiBpdCBpcyBub3QgcmVjb25jaWxlZC5cbiAgaXNTZWxlY3RhYmxlKHQ6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXQgJiYgdC5zdGF0dXMgIT09ICdyZWNvbmNpbGVkJztcbiAgfVxuXG4gIGlzU2VsZWN0ZWQodDogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdD8uX2lkICYmIHRoaXMuc2VsZWN0ZWRJZHMuaGFzKHQuX2lkKTtcbiAgfVxuXG4gIHRvZ2dsZVNlbGVjdCh0OiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuaXNTZWxlY3RhYmxlKHQpIHx8ICF0Py5faWQpIHsgcmV0dXJuOyB9XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRJZHMuaGFzKHQuX2lkKSkge1xuICAgICAgdGhpcy5zZWxlY3RlZElkcy5kZWxldGUodC5faWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkSWRzLmFkZCh0Ll9pZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gUm93cyBvbiB0aGUgY3VycmVudCBwYWdlIHRoYXQgY2FuIGJlIHNlbGVjdGVkIChleGNsdWRlcyByZWNvbmNpbGVkKS5cbiAgZ2V0IHNlbGVjdGFibGVSb3dzKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzLmZpbHRlcigocikgPT4gdGhpcy5pc1NlbGVjdGFibGUocikpO1xuICB9XG5cbiAgZ2V0IGFsbFNlbGVjdGVkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0YWJsZVJvd3M7XG4gICAgcmV0dXJuIHNlbC5sZW5ndGggPiAwICYmIHNlbC5ldmVyeSgocikgPT4gdGhpcy5zZWxlY3RlZElkcy5oYXMoci5faWQpKTtcbiAgfVxuXG4gIHRvZ2dsZVNlbGVjdEFsbChldmVudDogYW55KSB7XG4gICAgY29uc3QgY2hlY2tlZCA9IGV2ZW50Py50YXJnZXQ/LmNoZWNrZWQ7XG4gICAgaWYgKGNoZWNrZWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0YWJsZVJvd3MuZm9yRWFjaCgocikgPT4gdGhpcy5zZWxlY3RlZElkcy5hZGQoci5faWQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RhYmxlUm93cy5mb3JFYWNoKChyKSA9PiB0aGlzLnNlbGVjdGVkSWRzLmRlbGV0ZShyLl9pZCkpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBzZWxlY3RlZENvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRJZHMuc2l6ZTtcbiAgfVxuXG4gIGRlbGV0ZVNlbGVjdGVkKCkge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZElkcy5zaXplKSB7IHJldHVybjsgfVxuICAgIGNvbnN0IGlkcyA9IEFycmF5LmZyb20odGhpcy5zZWxlY3RlZElkcyk7XG4gICAgY29uc3QgbW9kYWxSZWYgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKERlbGV0ZUNvbmZpcm1hdGlvbkNvbXBvbmVudCwgeyBjZW50ZXJlZDogdHJ1ZSwgc2l6ZTogJ21kJyB9KTtcbiAgICBtb2RhbFJlZi5yZXN1bHQudGhlbigocmVzOiBhbnkpID0+IHtcbiAgICAgIGlmIChyZXMgIT09ICdZZXMnKSB7IHJldHVybjsgfVxuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS5kZWxldGVTZWxlY3RlZEJhbmtUcmFuc2FjdGlvbnMoaWRzKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHI6IGFueSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRlbGV0ZWQgPSByPy5kYXRhPy5kZWxldGVkID8/IDA7XG4gICAgICAgICAgY29uc3Qgc2tpcHBlZCA9IHI/LmRhdGE/LnNraXBwZWQgPz8gMDtcbiAgICAgICAgICBsZXQgbXNnID0gYCR7ZGVsZXRlZH0gdHJhbnNhY3Rpb24ocykgZGVsZXRlZGA7XG4gICAgICAgICAgaWYgKHNraXBwZWQpIHsgbXNnICs9IGAgwrcgJHtza2lwcGVkfSByZWNvbmNpbGVkIGtlcHRgOyB9XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QobXNnKTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcbiAgICAgICAgICB0aGlzLmxvYWRMaXN0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyKSA9PiB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGRlbGV0ZSB0cmFuc2FjdGlvbnMnKSxcbiAgICAgIH0pO1xuICAgIH0pLmNhdGNoKCgpID0+IHt9KTtcbiAgfVxuXG4gIC8vID09PT09IERlbGV0ZSA9PT09PVxuICAvLyBEZWxldGUgYSBzaW5nbGUgKG5vbi1yZWNvbmNpbGVkKSB0cmFuc2FjdGlvbiBhZnRlciBjb25maXJtYXRpb24uIFJlY29uY2lsZWRcbiAgLy8gcm93cyBuZXZlciBzaG93IHRoZSBkZWxldGUgYnV0dG9uLCBhbmQgdGhlIGJhY2tlbmQgcmVqZWN0cyB0aGVtIGFueXdheS5cbiAgZGVsZXRlVHJhbnNhY3Rpb24odDogYW55KSB7XG4gICAgaWYgKCF0Py5faWQgfHwgdC5zdGF0dXMgPT09ICdyZWNvbmNpbGVkJykgeyByZXR1cm47IH1cbiAgICBjb25zdCBtb2RhbFJlZiA9IHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4oRGVsZXRlQ29uZmlybWF0aW9uQ29tcG9uZW50LCB7IGNlbnRlcmVkOiB0cnVlLCBzaXplOiAnbWQnIH0pO1xuICAgIG1vZGFsUmVmLnJlc3VsdC50aGVuKChyZXM6IGFueSkgPT4ge1xuICAgICAgaWYgKHJlcyAhPT0gJ1llcycpIHsgcmV0dXJuOyB9XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmRlbGV0ZUJhbmtUcmFuc2FjdGlvbih0Ll9pZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnVHJhbnNhY3Rpb24gZGVsZXRlZCcpO1xuICAgICAgICAgIHRoaXMubG9hZExpc3QoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdChlcnI/LmVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gZGVsZXRlIHRyYW5zYWN0aW9uJyksXG4gICAgICB9KTtcbiAgICB9KS5jYXRjaCgoKSA9PiB7fSk7XG4gIH1cblxuICAvLyBEZWxldGUgYWxsIG5vbi1yZWNvbmNpbGVkIHRyYW5zYWN0aW9ucyBmcm9tIHRoZSBjdXJyZW50IHN0YXRlbWVudCBiYXRjaFxuICAvLyAoYnkgZmlsZU5hbWUpLiBSZWNvbmNpbGVkIHJvd3MgYXJlIHByZXNlcnZlZCBieSB0aGUgYmFja2VuZC5cbiAgZGVsZXRlQWxsKCkge1xuICAgIGNvbnN0IGZpbGVOYW1lID0gdGhpcy5yb3dzPy5bMF0/LmZpbGVOYW1lO1xuICAgIGlmICghZmlsZU5hbWUpIHtcbiAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnTm8gc3RhdGVtZW50IGZpbGUgZm91bmQgZm9yIHRoZXNlIHRyYW5zYWN0aW9ucycpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtb2RhbFJlZiA9IHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4oRGVsZXRlQ29uZmlybWF0aW9uQ29tcG9uZW50LCB7IGNlbnRlcmVkOiB0cnVlLCBzaXplOiAnbWQnIH0pO1xuICAgIG1vZGFsUmVmLnJlc3VsdC50aGVuKChyZXM6IGFueSkgPT4ge1xuICAgICAgaWYgKHJlcyAhPT0gJ1llcycpIHsgcmV0dXJuOyB9XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmRlbGV0ZUFsbEJhbmtUcmFuc2FjdGlvbnMoZmlsZU5hbWUpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocjogYW55KSA9PiB7XG4gICAgICAgICAgY29uc3QgZGVsZXRlZCA9IHI/LmRhdGE/LmRlbGV0ZWQgPz8gMDtcbiAgICAgICAgICBjb25zdCBza2lwcGVkID0gcj8uZGF0YT8uc2tpcHBlZCA/PyAwO1xuICAgICAgICAgIGxldCBtc2cgPSBgJHtkZWxldGVkfSB0cmFuc2FjdGlvbihzKSBkZWxldGVkYDtcbiAgICAgICAgICBpZiAoc2tpcHBlZCkgeyBtc2cgKz0gYCDCtyAke3NraXBwZWR9IHJlY29uY2lsZWQga2VwdGA7IH1cbiAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdChtc2cpO1xuICAgICAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgICAgIHRoaXMubG9hZExpc3QoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdChlcnI/LmVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gZGVsZXRlIHRyYW5zYWN0aW9ucycpLFxuICAgICAgfSk7XG4gICAgfSkuY2F0Y2goKCkgPT4ge30pO1xuICB9XG5cbiAgLy8gPT09PT0gRGlzcGxheSBoZWxwZXJzID09PT09XG4gIHN0YXR1c0xhYmVsKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgcmVjb25jaWxlZDogJ1JlY29uY2lsZWQnLCBuZWVkc19yZXZpZXc6ICdOZWVkcyByZXZpZXcnLFxuICAgICAgdW5tYXRjaGVkOiAnVW5tYXRjaGVkJywgZXhjbHVkZWQ6ICdFeGNsdWRlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW3NdIHx8IHM7XG4gIH1cblxuICBzdGF0dXNQaWxsQ2xhc3Moczogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICByZWNvbmNpbGVkOiAncGlsbCBwaWxsLWdyZWVuJywgbmVlZHNfcmV2aWV3OiAncGlsbCBwaWxsLWFtYmVyJyxcbiAgICAgIHVubWF0Y2hlZDogJ3BpbGwgcGlsbC1yZWQnLCBleGNsdWRlZDogJ3BpbGwgcGlsbC1ncmF5JyxcbiAgICB9O1xuICAgIHJldHVybiBtYXBbc10gfHwgJ3BpbGwgcGlsbC1ncmF5JztcbiAgfVxuXG4gIHNvdXJjZUxhYmVsKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgbWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0geyBiYW5rOiAnQmFuayBTdGF0ZW1lbnQnLCB2YTogJ1ZpcnR1YWwgQWNjb3VudCcsIGdhdGV3YXk6ICdHYXRld2F5JywgbWFudWFsOiAnTWFudWFsJyB9O1xuICAgIHJldHVybiBtYXBbc10gfHwgcztcbiAgfVxuXG4gIGNvdW50T2YoaWQ6IHN0cmluZyk6IG51bWJlciB7XG4gICAgaWYgKGlkID09PSAnYWxsJykgcmV0dXJuIHRoaXMuY2FyZHMudG90YWw7XG4gICAgcmV0dXJuICh0aGlzLmNhcmRzIGFzIGFueSlbaWRdPy5jb3VudCB8fCAwO1xuICB9XG59IiwiPGRpdj5cbiAgICA8IS0tID09PT09PT09PT09PSBVcGxvYWQgc3RhZ2UgKG5vIHN0YXRlbWVudHMgeWV0KSA9PT09PT09PT09PT0gLS0+XG4gICAgPGRpdiAqbmdJZj1cInN0YWdlID09PSAndXBsb2FkJyAmJiAhbG9hZGluZ1wiIGNsYXNzPVwicHgtNCBwYi00XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJiaWxsaW5naGVhZGVyIG1zLTEgbXQtNlwiPkJhbmsgU3RhdGVtZW50IFJlY29uY2lsaWF0aW9uPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG1zLTEgbXQtMVwiPlVwbG9hZCBhIGJhbmsgc3RhdGVtZW50IOKAlCB0cmFuc2FjdGlvbnMgYXJlIHN0b3JlZCBhbmQgc3BsaXQgaW50b1xuICAgICAgICAgICAgUmVjb25jaWxlZCwgTmVlZHMgcmV2aWV3LCBVbm1hdGNoZWQgYW5kIEV4Y2x1ZGVkLjwvZGl2PlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJkcm9wem9uZSBtdC00XCIgZm9yPVwic3RtdC1maWxlXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHotaWNcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTIgMjFWOU04IDEzbDQtNCA0IDRNNSA1aDE0XCIgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImR6LXRpdGxlIG10LTNcIj5VcGxvYWQgYmFuayBzdGF0ZW1lbnQ8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG10LTFcIj5EcmFnICZhbXA7IGRyb3Agb3IgY2xpY2sgdG8gYnJvd3NlIMK3IDxzdHJvbmc+RXhjZWwgKC54bHN4LCAueGxzKSBvciBDU1Y8L3N0cm9uZz48L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IGJ0bi1zbSBtdC0zXCIgW2Rpc2FibGVkXT1cInVwbG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgb25jbGljaz1cImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdG10LWZpbGUnKS5jbGljaygpOyBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1wiPlxuICAgICAgICAgICAgICAgIHt7IHVwbG9hZGluZyA/ICdQYXJzaW5n4oCmJyA6ICdVcGxvYWQgJiBwYXJzZScgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8aW5wdXQgaWQ9XCJzdG10LWZpbGVcIiB0eXBlPVwiZmlsZVwiIGFjY2VwdD1cIi54bHN4LC54bHMsLmNzdlwiIGNsYXNzPVwiZC1ub25lXCIgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3RlZCgkZXZlbnQpXCI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tID09PT09PT09PT09PSBSZXN1bHRzIHN0YWdlID09PT09PT09PT09PSAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwic3RhZ2UgPT09ICdyZXN1bHRzJ1wiPlxuICAgICAgICA8IS0tIFVwbG9hZC1hbm90aGVyIGFjdGlvbiAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZW5kIGFsaWduLWl0ZW1zLWNlbnRlciBtdC00IG1lLTRcIj5cbiAgICAgICAgICAgIDxpbnB1dCBpZD1cInN0bXQtZmlsZS1hZ2FpblwiIHR5cGU9XCJmaWxlXCIgYWNjZXB0PVwiLnhsc3gsLnhscywuY3N2XCIgY2xhc3M9XCJkLW5vbmVcIlxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25GaWxlU2VsZWN0ZWQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gYWxpZ24taXRlbXMtZW5kIHRleHQtbm93cmFwIGludmhlYWRlclwiIFtkaXNhYmxlZF09XCJ1cGxvYWRpbmdcIlxuICAgICAgICAgICAgICAgIG9uY2xpY2s9XCJkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RtdC1maWxlLWFnYWluJykuY2xpY2soKVwiPlxuICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE3LjUgMTIuNVYxNS44MzMzQzE3LjUgMTYuMjc1NCAxNy4zMjQ0IDE2LjY5OTMgMTcuMDExOCAxNy4wMTE4QzE2LjY5OTMgMTcuMzI0NCAxNi4yNzU0IDE3LjUgMTUuODMzMyAxNy41SDQuMTY2NjdDMy43MjQ2NCAxNy41IDMuMzAwNzIgMTcuMzI0NCAyLjk4ODE2IDE3LjAxMThDMi42NzU1OSAxNi42OTkzIDIuNSAxNi4yNzU0IDIuNSAxNS44MzMzVjEyLjVNMTQuMTY2NyA2LjY2NjY3TDEwIDIuNU0xMCAyLjVMNS44MzMzMyA2LjY2NjY3TTEwIDIuNVYxMi41XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMzNDQwNTRcIiBzdHJva2Utd2lkdGg9XCIxLjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1zLTJcIj57eyB1cGxvYWRpbmcgPyAnUGFyc2luZ+KApicgOiAnVXBsb2FkIGFub3RoZXIgc3RhdGVtZW50JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFN0YXR1cyBjYXJkcyDigJQgY2xpY2tpbmcgYSBjYXJkIGZpbHRlcnMgdGhlIHRhYmxlIChjbGljayBhZ2FpbiB0byBjbGVhcikgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgZy0zIG10LTEgbWItMiBteC0yXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZCBjYXJkLWNsaWNrYWJsZVwiIFtjbGFzcy5jYXJkLWFjdGl2ZV09XCJhY3RpdmVTdGF0dXMgPT09ICdyZWNvbmNpbGVkJ1wiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDYXJkRmlsdGVyKCdyZWNvbmNpbGVkJylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1sYWJlbFwiPlJlY29uY2lsZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJpbmZvLWljXCIgbmdiVG9vbHRpcD1cIlBheW1lbnRzIGF1dG9tYXRpY2FsbHkgbWF0Y2hlZCB0byBhbiBpbnZvaWNlIChwYXllciBuYW1lICsgYW1vdW50KSwgb3IgbWFudWFsbHkgcmVjb25jaWxlZC5cIiBwbGFjZW1lbnQ9XCJ0b3BcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj48Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjlcIi8+PHBhdGggZD1cIk0xMiAxMXY1TTEyIDhoLjAxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC12YWx1ZSB0ZXh0LXN1Y2Nlc3NcIj57eyBjYXJkcy5yZWNvbmNpbGVkLmNvdW50IH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLWNhcmQtc3ViXCI+4oK5e3sgY2FyZHMucmVjb25jaWxlZC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2xcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkIGNhcmQtY2xpY2thYmxlXCIgW2NsYXNzLmNhcmQtYWN0aXZlXT1cImFjdGl2ZVN0YXR1cyA9PT0gJ25lZWRzX3JldmlldydcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlQ2FyZEZpbHRlcignbmVlZHNfcmV2aWV3JylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1sYWJlbFwiPk5lZWRzIHJldmlld1xuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImluZm8taWNcIiBuZ2JUb29sdGlwPVwiUGF5ZXIgbWF0Y2hlcyBhIGN1c3RvbWVyIGJ1dCB0aGUgYW1vdW50IGRvZXNuJ3QgbWF0Y2ggYW4gaW52b2ljZSwgb3IgYSBkb2xsYXIgcGF5bWVudCBtYXRjaGVkIOKAlCBjb25maXJtIGJlZm9yZSByZWNvbmNpbGluZy5cIiBwbGFjZW1lbnQ9XCJ0b3BcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj48Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjlcIi8+PHBhdGggZD1cIk0xMiAxMXY1TTEyIDhoLjAxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC12YWx1ZSB0ZXh0LXdhcm5pbmdcIj57eyBjYXJkcy5uZWVkc19yZXZpZXcuY291bnQgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1zdWJcIj7igrl7eyBjYXJkcy5uZWVkc19yZXZpZXcuYW1vdW50IHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZCBjYXJkLWNsaWNrYWJsZVwiIFtjbGFzcy5jYXJkLWFjdGl2ZV09XCJhY3RpdmVTdGF0dXMgPT09ICd1bm1hdGNoZWQnXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNhcmRGaWx0ZXIoJ3VubWF0Y2hlZCcpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLWNhcmQtbGFiZWxcIj5Vbm1hdGNoZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJpbmZvLWljXCIgbmdiVG9vbHRpcD1cIlBheWVyIG5hbWUgZG9lc24ndCBtYXRjaCBhbnkgY3VzdG9tZXIncyBpbnZvaWNlIOKAlCBpZGVudGlmeSB0aGUgY3VzdG9tZXIgYW5kIG1hcCBpdCBtYW51YWxseS5cIiBwbGFjZW1lbnQ9XCJ0b3BcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj48Y2lyY2xlIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjlcIi8+PHBhdGggZD1cIk0xMiAxMXY1TTEyIDhoLjAxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC12YWx1ZSB0ZXh0LWRhbmdlclwiPnt7IGNhcmRzLnVubWF0Y2hlZC5jb3VudCB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkLXN1YlwiPuKCuXt7IGNhcmRzLnVubWF0Y2hlZC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2xcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkIGNhcmQtY2xpY2thYmxlXCIgW2NsYXNzLmNhcmQtYWN0aXZlXT1cImFjdGl2ZVN0YXR1cyA9PT0gJ2V4Y2x1ZGVkJ1wiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDYXJkRmlsdGVyKCdleGNsdWRlZCcpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLWNhcmQtbGFiZWxcIj5FeGNsdWRlZFxuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyBjbGFzcz1cImluZm8taWNcIiBuZ2JUb29sdGlwPVwiTm90IGEgY3VzdG9tZXIgcGF5bWVudCAobm8gcGF5ZXIgbmFtZSkgb3IgbWFudWFsbHkgbWFya2VkIGFzIG5vdCB0byBiZSBjb25zaWRlcmVkLlwiIHBsYWNlbWVudD1cInRvcFwiIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiPjxjaXJjbGUgY3g9XCIxMlwiIGN5PVwiMTJcIiByPVwiOVwiLz48cGF0aCBkPVwiTTEyIDExdjVNMTIgOGguMDFcIi8+PC9zdmc+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52b2ljZS1jYXJkLXZhbHVlXCI+e3sgY2FyZHMuZXhjbHVkZWQuY291bnQgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtY2FyZC1zdWJcIj7igrl7eyBjYXJkcy5leGNsdWRlZC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBTdGF0dXMgdGFicyArIHNlYXJjaC9maWx0ZXIgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBwYXltZW50aGlzdG9yeSBib3JkZXItMFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTIgZmxleC13cmFwXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdGb3I9XCJsZXQgdGFiIG9mIHN0YXR1c1RhYnNcIiBjbGFzcz1cImJ0biBidG4tc20gc3RhdHVzLXRhYlwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlU3RhdHVzID09PSB0YWIuaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2V0U3RhdHVzKHRhYi5pZClcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgdGFiLmxhYmVsIH19XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiY291bnRPZih0YWIuaWQpXCIgY2xhc3M9XCJjb3VudGNoaXAgbXMtMVwiPnt7IGNvdW50T2YodGFiLmlkKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdG9vbGJhciBtcy1hdXRvXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgcG9zaXRpb24tcmVsYXRpdmUgbXktMVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN2Zy1pY29uIGludm9pY2VzZWFyY2ggc3ZnLWljb24tMSBwb3NpdGlvbi1hYnNvbHV0ZSBtdC02IG1zLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxyZWN0IG9wYWNpdHk9XCIwLjVcIiB4PVwiMTcuMDM2NVwiIHk9XCIxNS4xMjIzXCIgd2lkdGg9XCI4LjE1NTQ2XCIgaGVpZ2h0PVwiMlwiIHJ4PVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT1cInJvdGF0ZSg0NSAxNy4wMzY1IDE1LjEyMjMpXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiPjwvcmVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTExIDE5QzYuNTU1NTYgMTkgMyAxNS40NDQ0IDMgMTFDMyA2LjU1NTU2IDYuNTU1NTYgMyAxMSAzQzE1LjQ0NDQgMyAxOSA2LjU1NTU2IDE5IDExQzE5IDE1LjQ0NDQgMTUuNDQ0NCAxOSAxMSAxOVpNMTEgNUM3LjUzMzMzIDUgNSA3LjUzMzMzIDUgMTFDNSAxNC40NjY3IDcuNTMzMzMgMTcgMTEgMTdDMTQuNDY2NyAxNyAxNyAxNC40NjY3IDE3IDExQzE3IDcuNTMzMzMgMTQuNDY2NyA1IDExIDVaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiPjwvcGF0aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCBbKG5nTW9kZWwpXT1cInNlYXJjaFZhbHVlXCIgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBwcy0xNCBpbnZvaWNlc2VhcmNoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIHBheWVyLCBuYXJyYXRpb24sIFVUUi4uLlwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiIChjaGFuZ2UpPVwic2VhcmNoRmllbGQoKVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRmlsdGVyIGRyb3Bkb3duIOKAlCBvcGVucyBhIHNlbGYtY29udGFpbmVkIHBvcG92ZXIgYW5jaG9yZWQgdG9cbiAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgYnV0dG9uIChsaWItZmlsdGVycyBjYW4ndCBob3N0IHRoZSBkYXRlLXJhbmdlIGlucHV0cykuIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmUgdHhuLWZpbHRlci13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1vdXRsaW5lIGJ0biBhbGlnbi1pdGVtcy1lbmQgdGV4dC1ub3dyYXAgaW52aGVhZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRmlsdGVyKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLXdpZHRoPVwiMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTMgNWgxOE02IDEyaDEyTTEwIDE5aDRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXMtMlwiPkZpbHRlcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImFjdGl2ZUZpbHRlckNvdW50XCIgY2xhc3M9XCJjb3VudGNoaXAgbXMtMVwiPnt7IGFjdGl2ZUZpbHRlckNvdW50IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmlsdGVyT3BlblwiIGNsYXNzPVwidHhuLWZpbHRlci1wb3AgY2FyZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0eG4tZmlsdGVyLXRpdGxlXCI+RmlsdGVyIE9wdGlvbnM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIHNtYWxsIGZ3LXNlbWlib2xkXCI+RGF0ZSDigJQgZnJvbTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZGF0ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgWyhuZ01vZGVsKV09XCJkcmFmdEZyb21EYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBzbWFsbCBmdy1zZW1pYm9sZFwiPkRhdGUg4oCUIHRvPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJkYXRlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbKG5nTW9kZWwpXT1cImRyYWZ0VG9EYXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBzbWFsbCBmdy1zZW1pYm9sZFwiPlNvdXJjZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIFsobmdNb2RlbCldPVwiZHJhZnRTb3VyY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJhbGxcIj5BbGwgc291cmNlczwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImJhbmtcIj5CYW5rIFN0YXRlbWVudDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInZhXCI+VmlydHVhbCBBY2NvdW50PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZ2F0ZXdheVwiPkdhdGV3YXk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJtYW51YWxcIj5NYW51YWw8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZW5kIG1iLTJcIiAqbmdJZj1cImFjdGl2ZUZpbHRlckNvdW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpbmsgYnRuLXNtIHAtMFwiIChjbGljayk9XCJjbGVhckZpbHRlcnMoKVwiPkNsZWFyIGFsbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRmlsdGVycyBhcHBseSBvbmx5IG9uIEFwcGx5OyBDYW5jZWwgZGlzY2FyZHMgY2hhbmdlcy4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMiBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGJ0bi1zbSBmbGV4LWZpbGxcIiAoY2xpY2spPVwiY2FuY2VsRmlsdGVycygpXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgYnRuLXNtIGZsZXgtZmlsbFwiIChjbGljayk9XCJhcHBseUZpbHRlcnMoKVwiPkFwcGx5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIHNlbGVjdGVkIChub24tcmVjb25jaWxlZCkgcm93cy4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJzZWxlY3RlZENvdW50ID4gMCAmJiAoZ3MudXNlckFjY2VzcyB8IGFzeW5jKT8uR2xvYmFsX0JpbGxpbmdfaXNFZGl0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1vdXRsaW5lIGJ0biBhbGlnbi1pdGVtcy1lbmQgdGV4dC1ub3dyYXAgaW52aGVhZGVyIG1zLTIgZGVsZXRlLWFsbC1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZVNlbGVjdGVkKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMyA2aDE4TTggNlY0YTEgMSAwIDAgMSAxLTFoNmExIDEgMCAwIDEgMSAxdjJtMiAwdjE0YTIgMiAwIDAgMS0yIDJIN2EyIDIgMCAwIDEtMi0yVjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjRDkyRDIwXCIgc3Ryb2tlLXdpZHRoPVwiMS42XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtcy0yXCI+RGVsZXRlIHNlbGVjdGVkICh7eyBzZWxlY3RlZENvdW50IH19KTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRGVsZXRlIGFsbCAobm9uLXJlY29uY2lsZWQpIGZvciB0aGUgY3VycmVudCBzdGF0ZW1lbnQgYmF0Y2guXG4gICAgICAgICAgICAgICAgICAgICAgICAgUmVjb25jaWxlZCByb3dzIGFyZSBhbHdheXMgcHJlc2VydmVkIGJ5IHRoZSBiYWNrZW5kLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cIiFub0RhdGEgJiYgKGdzLnVzZXJBY2Nlc3MgfCBhc3luYyk/Lkdsb2JhbF9CaWxsaW5nX2lzRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gYWxpZ24taXRlbXMtZW5kIHRleHQtbm93cmFwIGludmhlYWRlciBtcy0yIGRlbGV0ZS1hbGwtYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVBbGwoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjE4XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0zIDZoMThNOCA2VjRhMSAxIDAgMCAxIDEtMWg2YTEgMSAwIDAgMSAxIDF2Mm0yIDB2MTRhMiAyIDAgMCAxLTIgMkg3YTIgMiAwIDAgMS0yLTJWNlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiNEOTJEMjBcIiBzdHJva2Utd2lkdGg9XCIxLjZcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1zLTJcIj5EZWxldGUgYWxsPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIExvYWRpbmcgc2hpbW1lciAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvYWRpbmdcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgbG9hZGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzaGltbWVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3cmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Ryb2tlIGFuaW1hdGUgdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdHJva2UgYW5pbWF0ZSBsaW5rXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Ryb2tlIGFuaW1hdGUgZGVzY3JpcHRpb25cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBFbXB0eSAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFsb2FkaW5nICYmIG5vRGF0YVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbGctMTIgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlciBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBjbGFzcz1cImltZy1zcmMgdy0yNVwiIHNyYz1cIi4vYXNzZXRzL3RhbmdvL0ljb25zL05vZGF0YS5zdmdcIiBhbHQ9XCJcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBUcmFuc2FjdGlvbnMgdGFibGUgLS0+XG4gICAgICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZyAmJiAhbm9EYXRhXCIgY2xhc3M9XCJ0YWJsZS1yZXNwb25zaXZlXCI+XG4gICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSBhY2NvcmRpb24gdGFibGUgYm90dG9tLWJvcmRlciBpbnZvaXZldGFibGUgdGV4dC1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aCAqbmdJZj1cIihncy51c2VyQWNjZXNzIHwgYXN5bmMpPy5HbG9iYWxfQmlsbGluZ19pc0VkaXRcIiBzdHlsZT1cIndpZHRoOjQwcHg7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIFtjaGVja2VkXT1cImFsbFNlbGVjdGVkXCIgKGNoYW5nZSk9XCJ0b2dnbGVTZWxlY3RBbGwoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJzZWxlY3RhYmxlUm93cy5sZW5ndGggPT09IDBcIiBuZ2JUb29sdGlwPVwiU2VsZWN0IGFsbCAoZXhjbHVkZXMgcmVjb25jaWxlZClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+RGF0ZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+U291cmNlPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5QYXllciAoZnJvbSBuYXJyYXRpb24pPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5SZWZlcmVuY2UgLyBVVFI8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkFtb3VudDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+QnJhbmQgTmFtZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+SW52b2ljZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGg+UmVzdWx0PC90aD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5TdGF0dXM8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoPkFjdGlvbjwvdGg+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgdCBvZiByb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCIoZ3MudXNlckFjY2VzcyB8IGFzeW5jKT8uR2xvYmFsX0JpbGxpbmdfaXNFZGl0XCIgc3R5bGU9XCJ3aWR0aDo0MHB4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVjb25jaWxlZCByb3dzIGNhbid0IGJlIHNlbGVjdGVkLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgKm5nSWY9XCJpc1NlbGVjdGFibGUodClcIiBbY2hlY2tlZF09XCJpc1NlbGVjdGVkKHQpXCIgKGNoYW5nZSk9XCJ0b2dnbGVTZWxlY3QodClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFpc1NlbGVjdGFibGUodClcIiBjbGFzcz1cImxvY2staWNcIiBuZ2JUb29sdGlwPVwiUmVjb25jaWxlZCDigJQgY2Fubm90IGJlIGRlbGV0ZWRcIj7wn5SSPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGl0bGVcIj57eyB0LnZhbHVlRGF0ZSB8IGRhdGU6ICdkZCBNTU0sIHl5eXknIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JjY2hpcFwiIFtjbGFzcy5zcmNjaGlwLXZhXT1cInQuc291cmNlID09PSAndmEnXCI+e3sgc291cmNlTGFiZWwodC5zb3VyY2UpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGl0bGUgcGF5ZXItY2VsbFwiPnt7IHQucGF5ZXIgfHwgJ+KAlCcgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmFycmF0aW9uLXN1YlwiIFt0aXRsZV09XCJ0Lm5hcnJhdGlvblwiPnt7IHQubmFycmF0aW9uIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9ub1wiPnt7IHQucmVmTm8gfHwgJ+KAlCcgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS10aXRsZVwiPjxzdHJvbmc+4oK5e3sgdC5hbW91bnQgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zdHJvbmc+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS10aXRsZVwiPnt7IHQuaWRlbnRpZmllZENsaWVudE5hbWUgfHwgJ+KAlCcgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gTXVsdGlwbGUgaW52b2ljZXMgc2V0dGxlZCBieSBvbmUgcGF5bWVudDogbGluayBlYWNoIGluZGl2aWR1YWxseS4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0LmFwcGxpZWRJbnZvaWNlcz8ubGVuZ3RoID4gMTsgZWxzZSBzaW5nbGVJbnZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGEgb2YgdC5hcHBsaWVkSW52b2ljZXM7IGxldCBsYXN0ID0gbGFzdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiaW52b2ljZS1saW5rXCIgKGNsaWNrKT1cIm9wZW5JbnZvaWNlUHJldmlld0J5SWQoYS5pbnZvaWNlSWQsIGEuaW52b2ljZSk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPnt7IGEuaW52b2ljZSB9fTwvYT48c3BhbiAqbmdJZj1cIiFsYXN0XCI+LCA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlSW52PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgKm5nSWY9XCJ0Lmludm9pY2UgJiYgdC5pbnZvaWNlSWRcIiBjbGFzcz1cImludm9pY2UtbGlua1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5JbnZvaWNlUHJldmlldyh0KTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+e3sgdC5pbnZvaWNlIH19PC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJ0Lmludm9pY2UgJiYgIXQuaW52b2ljZUlkXCI+e3sgdC5pbnZvaWNlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhdC5pbnZvaWNlXCI+4oCUPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzdWx0LW5vdGVcIiBbdGl0bGVdPVwidC5yZXN1bHROb3RlXCI+e3sgdC5yZXN1bHROb3RlIHx8ICfigJQnIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwidC5jb250YWN0ZWRcIiBjbGFzcz1cInBpbGwgcGlsbC1hbWJlclwiPlJlYWNoaW5nIG91dDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiF0LmNvbnRhY3RlZFwiIFtuZ0NsYXNzXT1cInN0YXR1c1BpbGxDbGFzcyh0LnN0YXR1cylcIj57eyBzdGF0dXNMYWJlbCh0LnN0YXR1cykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJ0LnN0YXR1cyA9PT0gJ25lZWRzX3JldmlldycgfHwgdC5zdGF0dXMgPT09ICd1bm1hdGNoZWQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1wcmltYXJ5XCIgKGNsaWNrKT1cIm9wZW5SZXNvbHZlKHQpXCI+UmVzb2x2ZTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVjb25jaWxlZCByb3dzOiBFZGl0IHJlLW9wZW5zIHRoZSBSZXNvbHZlICYgcmVjb25jaWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1cCBzbyB0aGUgbWF0Y2hlZCBpbnZvaWNlIC8gcmVzb2x1dGlvbiBjYW4gYmUgY2hhbmdlZC4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInQuc3RhdHVzID09PSAncmVjb25jaWxlZCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmVcIiAoY2xpY2spPVwib3BlblJlc29sdmUodClcIj5FZGl0PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBEZWxldGU6IHJlY29uY2lsZWQgcm93cyBhcmUgcHJvdGVjdGVkIGFuZCBuZXZlciBkZWxldGFibGUuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJ0LnN0YXR1cyAhPT0gJ3JlY29uY2lsZWQnICYmIChncy51c2VyQWNjZXNzIHwgYXN5bmMpPy5HbG9iYWxfQmlsbGluZ19pc0VkaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tc20gYnRuLWljb24gZGVsZXRlLXR4blwiIG5nYlRvb2x0aXA9XCJEZWxldGUgdHJhbnNhY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlVHJhbnNhY3Rpb24odClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxOFwiIGhlaWdodD1cIjE4XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTMgNmgxOE04IDZWNGExIDEgMCAwIDEgMS0xaDZhMSAxIDAgMCAxIDEgMXYybTIgMHYxNGEyIDIgMCAwIDEtMiAySDdhMiAyIDAgMCAxLTItMlY2bTMgNXY2bTQtNnY2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjRDkyRDIwXCIgc3Ryb2tlLXdpZHRoPVwiMS42XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgPGxpYi1wYWdpbmF0aW9uIGNsYXNzPVwidGV4dC1zdGFydFwiIFtpdGVtc1BlclBhZ2VdPVwiaXRlbXNQZXJQYWdlXCIgW2N1cnJlbnRQYWdlXT1cImN1cnJlbnRQYWdlXCJcbiAgICAgICAgICAgICAgICBbdG90YWxJdGVtc109XCJ0b3RhbEl0ZW1zXCIgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIiBbcGFnZVNpemVdPVwicGFnZVNpemVcIlxuICAgICAgICAgICAgICAgIChwYWdlQ2hhbmdlKT1cIm9uUGFnZUNoYW5nZSgkZXZlbnQpXCIgKHBhZ2VTaXplQ2hhbmdlKT1cIm9uUGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiPjwvbGliLXBhZ2luYXRpb24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9kaXY+Il19
|