techlify-inventory-common 18.36.0 → 18.37.0
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/inventory-common/inventory-common-routing.module.mjs +2 -2
- package/esm2022/lib/inventory-common/product/product-list/product-list.component.mjs +15 -17
- package/esm2022/lib/inventory-common/product/product-quick-search/product-quick-search.component.mjs +17 -36
- package/esm2022/lib/inventory-common/product/product-view-page/product-view-page.component.mjs +8 -8
- package/esm2022/lib/inventory-common/product/product.module.mjs +10 -10
- package/esm2022/lib/inventory-common/product/widgets/product-category-badges/product-category-badges.component.mjs +3 -3
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-form/stock-issue-form.component.mjs +165 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-import-page/stock-issue-import-page.component.mjs +59 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-list/stock-issue-list.component.mjs +140 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-page/stock-issue-page.component.mjs +96 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-page/stock-issue-page.module.mjs +87 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-product-form/stock-issue-product-form-button/stock-issue-product-form-button.component.mjs +35 -0
- package/esm2022/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-product-form/stock-issue-product-form.component.mjs +1 -1
- package/esm2022/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-product.service.mjs +1 -1
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-products-list/stock-issue-products-list.component.mjs +138 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-routing.module.mjs +46 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-simple-form/stock-issue-form-button/stock-issue-form-button.component.mjs +48 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-simple-form/stock-issue-form.module.mjs +43 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-simple-form/stock-issue-simple-form/stock-issue-simple-form.component.mjs +201 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-view/stock-issue-view.component.mjs +66 -0
- package/esm2022/lib/inventory-common/stock-issue/stock-issue.module.mjs +51 -0
- package/esm2022/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue.service.mjs +1 -1
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-form/stock-receipt-form.component.mjs +221 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-list/stock-receipt-list.component.mjs +153 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-product-list/stock-receipt-product-list.component.mjs +146 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-simple-form/stock-receipt-form-button/stock-receipt-form-button.component.mjs +42 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-simple-form/stock-receipt-simple-form/stock-receipt-simple-form.component.mjs +180 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-simple-form/stock-receipt-simple-form.module.mjs +51 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-view/stock-receipt-view.component.mjs +4 -5
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts-page/stock-receipts-page.component.mjs +70 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts-routing.module.mjs +8 -8
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts.module.mjs +20 -25
- package/esm2022/lib/inventory-common/supplier/supplier-view/supplier-view.component.mjs +4 -4
- package/esm2022/lib/inventory-common/supplier/supplier.module.mjs +8 -9
- package/esm2022/lib/inventory-common/supplier/suppliers-list/suppliers-list.component.mjs +3 -4
- package/esm2022/public-api.mjs +16 -17
- package/fesm2022/{techlify-inventory-common-category.module-CUqub2ML.mjs → techlify-inventory-common-category.module-CJbYoRGj.mjs} +4 -4
- package/fesm2022/{techlify-inventory-common-category.module-CUqub2ML.mjs.map → techlify-inventory-common-category.module-CJbYoRGj.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-measure.module-CIonhS7Z.mjs → techlify-inventory-common-measure.module-D8oqfZTV.mjs} +4 -4
- package/fesm2022/{techlify-inventory-common-measure.module-CIonhS7Z.mjs.map → techlify-inventory-common-measure.module-D8oqfZTV.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-purchase-order-view.component-5zmdBnE-.mjs → techlify-inventory-common-purchase-order-view.component-BDuk0Xek.mjs} +4 -4
- package/fesm2022/{techlify-inventory-common-purchase-order-view.component-5zmdBnE-.mjs.map → techlify-inventory-common-purchase-order-view.component-BDuk0Xek.mjs.map} +1 -1
- package/fesm2022/techlify-inventory-common-stock-issue-form.component-B0-TBlZL.mjs +164 -0
- package/fesm2022/techlify-inventory-common-stock-issue-form.component-B0-TBlZL.mjs.map +1 -0
- package/fesm2022/techlify-inventory-common-stock-issue-view.component-DJIQ6dVF.mjs +66 -0
- package/fesm2022/techlify-inventory-common-stock-issue-view.component-DJIQ6dVF.mjs.map +1 -0
- package/fesm2022/{techlify-inventory-common-techlify-inventory-common-DVM9NowZ.mjs → techlify-inventory-common-techlify-inventory-common-CQSzjNhk.mjs} +1700 -1857
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-CQSzjNhk.mjs.map +1 -0
- package/fesm2022/techlify-inventory-common.mjs +1 -1
- package/lib/inventory-common/product/product-view-page/product-view-page.component.d.ts +4 -4
- package/lib/inventory-common/product/product.module.d.ts +4 -4
- package/lib/inventory-common/{stock-issuances/stock-issue-batch-form/stock-issue-batch-form.component.d.ts → stock-issue/stock-issue-form/stock-issue-form.component.d.ts} +6 -4
- package/lib/inventory-common/{stock-issuances/grouped-stock-issue-list/grouped-stock-issue-list.component.d.ts → stock-issue/stock-issue-list/stock-issue-list.component.d.ts} +3 -3
- package/lib/inventory-common/{stock-issuances/stock-issue-list/stock-issue-list.component.d.ts → stock-issue/stock-issue-page/stock-issue-page.component.d.ts} +3 -3
- package/lib/inventory-common/stock-issue/stock-issue-page/stock-issue-page.module.d.ts +20 -0
- package/lib/inventory-common/{stock-issuances/itemized-stock-issue-products-list/itemized-stock-issue-products-list.component.d.ts → stock-issue/stock-issue-products-list/stock-issue-products-list.component.d.ts} +3 -3
- package/lib/inventory-common/{stock-issuances/stock-issue-form → stock-issue/stock-issue-simple-form}/stock-issue-form.module.d.ts +2 -2
- package/lib/inventory-common/{stock-issuances/stock-issue-form/stock-issue-form/stock-issue-form.component.d.ts → stock-issue/stock-issue-simple-form/stock-issue-simple-form/stock-issue-simple-form.component.d.ts} +3 -3
- package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-view/stock-issue-view.component.d.ts +1 -1
- package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue.module.d.ts +4 -4
- package/lib/inventory-common/stock-receipts/{stock-receipt-batch-form/stock-receipt-batch-form.component.d.ts → stock-receipt-form/stock-receipt-form.component.d.ts} +6 -4
- package/lib/inventory-common/stock-receipts/{grouped-stock-receipt-list/grouped-stock-receipt-list.component.d.ts → stock-receipt-list/stock-receipt-list.component.d.ts} +3 -3
- package/lib/inventory-common/stock-receipts/{itemized-stock-receipt-products-list/itemized-stock-receipt-products-list.component.d.ts → stock-receipt-product-list/stock-receipt-product-list.component.d.ts} +3 -3
- package/lib/inventory-common/stock-receipts/{stock-receipt-form/stock-receipt-form/stock-receipt-form.component.d.ts → stock-receipt-simple-form/stock-receipt-simple-form/stock-receipt-simple-form.component.d.ts} +1 -1
- package/lib/inventory-common/stock-receipts/stock-receipt-simple-form/stock-receipt-simple-form.module.d.ts +15 -0
- package/lib/inventory-common/stock-receipts/stock-receipt-view/stock-receipt-view.component.d.ts +2 -2
- package/lib/inventory-common/stock-receipts/{stock-receipts-list-page/stock-receipts-list-page.component.d.ts → stock-receipts-page/stock-receipts-page.component.d.ts} +3 -3
- package/lib/inventory-common/stock-receipts/stock-receipts.module.d.ts +18 -19
- package/lib/inventory-common/supplier/supplier.module.d.ts +6 -7
- package/package.json +5 -2
- package/public-api.d.ts +15 -16
- package/esm2022/lib/inventory-common/stock-issuances/grouped-stock-issue-list/grouped-stock-issue-list.component.mjs +0 -139
- package/esm2022/lib/inventory-common/stock-issuances/itemized-stock-issue-products-list/itemized-stock-issue-products-list.component.mjs +0 -138
- package/esm2022/lib/inventory-common/stock-issuances/stock-issuance-delete-button/stock-issuance-delete-button.component.mjs +0 -47
- package/esm2022/lib/inventory-common/stock-issuances/stock-issuance-delete-button/stock-issuance-delete-button.module.mjs +0 -19
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-batch-form/stock-issue-batch-form.component.mjs +0 -163
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-form/stock-issue-form/stock-issue-form.component.mjs +0 -201
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-form/stock-issue-form-button/stock-issue-form-button.component.mjs +0 -48
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-form/stock-issue-form.module.mjs +0 -43
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-import-page/stock-issue-import-page.component.mjs +0 -59
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-list/stock-issue-list.component.mjs +0 -96
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-list/stock-issue-list.module.mjs +0 -91
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-product-form/stock-issue-product-form-button/stock-issue-product-form-button.component.mjs +0 -35
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-routing.module.mjs +0 -46
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-view/stock-issue-view.component.mjs +0 -68
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue.module.mjs +0 -51
- package/esm2022/lib/inventory-common/stock-receipts/grouped-stock-receipt-list/grouped-stock-receipt-list.component.mjs +0 -151
- package/esm2022/lib/inventory-common/stock-receipts/itemized-stock-receipt-products-list/itemized-stock-receipt-products-list.component.mjs +0 -146
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-batch-form/stock-receipt-batch-form.component.mjs +0 -208
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-delete-button/stock-receipt-delete-button.component.mjs +0 -47
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-form/stock-receipt-form/stock-receipt-form.component.mjs +0 -180
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-form/stock-receipt-form-button/stock-receipt-form-button.component.mjs +0 -42
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-form/stock-receipt-form.module.mjs +0 -51
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts-list-page/stock-receipts-list-page.component.mjs +0 -70
- package/esm2022/lib/inventory-common/supplier/supplier-delete-button/supplier-delete-button.component.mjs +0 -64
- package/fesm2022/techlify-inventory-common-stock-issue-batch-form.component-CnRySjgj.mjs +0 -162
- package/fesm2022/techlify-inventory-common-stock-issue-batch-form.component-CnRySjgj.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-stock-issue-view.component-D1sTvEWD.mjs +0 -66
- package/fesm2022/techlify-inventory-common-stock-issue-view.component-D1sTvEWD.mjs.map +0 -1
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-DVM9NowZ.mjs.map +0 -1
- package/lib/inventory-common/stock-issuances/stock-issuance-delete-button/stock-issuance-delete-button.component.d.ts +0 -18
- package/lib/inventory-common/stock-issuances/stock-issuance-delete-button/stock-issuance-delete-button.module.d.ts +0 -9
- package/lib/inventory-common/stock-issuances/stock-issue-list/stock-issue-list.module.d.ts +0 -21
- package/lib/inventory-common/stock-receipts/stock-receipt-delete-button/stock-receipt-delete-button.component.d.ts +0 -18
- package/lib/inventory-common/stock-receipts/stock-receipt-form/stock-receipt-form.module.d.ts +0 -15
- package/lib/inventory-common/supplier/supplier-delete-button/supplier-delete-button.component.d.ts +0 -18
- /package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-import-page/stock-issue-import-page.component.d.ts +0 -0
- /package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-product-form/stock-issue-product-form-button/stock-issue-product-form-button.component.d.ts +0 -0
- /package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-product-form/stock-issue-product-form.component.d.ts +0 -0
- /package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-product.service.d.ts +0 -0
- /package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue-routing.module.d.ts +0 -0
- /package/lib/inventory-common/{stock-issuances/stock-issue-form → stock-issue/stock-issue-simple-form}/stock-issue-form-button/stock-issue-form-button.component.d.ts +0 -0
- /package/lib/inventory-common/{stock-issuances → stock-issue}/stock-issue.service.d.ts +0 -0
- /package/lib/inventory-common/stock-receipts/{stock-receipt-form → stock-receipt-simple-form}/stock-receipt-form-button/stock-receipt-form-button.component.d.ts +0 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { Component, signal } from "@angular/core";
|
|
2
|
+
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
|
3
|
+
import { TechlifyFormComponentInterface, TechlifyIconModule } from "ngx-techlify-core";
|
|
4
|
+
import { MaterialModule } from '../../material.module';
|
|
5
|
+
import { CommonModule } from '@angular/common';
|
|
6
|
+
import { SearchableSelectorModule } from 'ngx-techlify-core';
|
|
7
|
+
import { LocationSelectorComponent } from '../../location/location-selector/location-selector.component';
|
|
8
|
+
import { debounceTime } from 'rxjs';
|
|
9
|
+
import moment from 'moment';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "ngx-techlify-core";
|
|
12
|
+
import * as i2 from "@angular/forms";
|
|
13
|
+
import * as i3 from "../stock-receipt.service";
|
|
14
|
+
import * as i4 from "@angular/router";
|
|
15
|
+
import * as i5 from "../../location/location.service";
|
|
16
|
+
import * as i6 from "@angular/common";
|
|
17
|
+
import * as i7 from "@angular/material/button";
|
|
18
|
+
import * as i8 from "@angular/material/card";
|
|
19
|
+
import * as i9 from "@angular/material/datepicker";
|
|
20
|
+
import * as i10 from "@angular/material/form-field";
|
|
21
|
+
import * as i11 from "@angular/material/icon";
|
|
22
|
+
import * as i12 from "@angular/material/input";
|
|
23
|
+
import * as i13 from "@angular/material/tooltip";
|
|
24
|
+
export class StockReceiptFormComponent extends TechlifyFormComponentInterface {
|
|
25
|
+
formValidatorService;
|
|
26
|
+
fb;
|
|
27
|
+
stockReceiptService;
|
|
28
|
+
router;
|
|
29
|
+
route;
|
|
30
|
+
locationService;
|
|
31
|
+
location;
|
|
32
|
+
locationCount = signal(0);
|
|
33
|
+
stockReceiptId = signal(null);
|
|
34
|
+
stockReceipt = signal(null);
|
|
35
|
+
constructor(formValidatorService, fb, stockReceiptService, router, route, locationService, location) {
|
|
36
|
+
super(formValidatorService);
|
|
37
|
+
this.formValidatorService = formValidatorService;
|
|
38
|
+
this.fb = fb;
|
|
39
|
+
this.stockReceiptService = stockReceiptService;
|
|
40
|
+
this.router = router;
|
|
41
|
+
this.route = route;
|
|
42
|
+
this.locationService = locationService;
|
|
43
|
+
this.location = location;
|
|
44
|
+
this.errorMessages = {
|
|
45
|
+
supplier_id: {
|
|
46
|
+
required: 'The supplier field is required.',
|
|
47
|
+
},
|
|
48
|
+
date: {
|
|
49
|
+
required: 'The date field is required.',
|
|
50
|
+
},
|
|
51
|
+
particulars: {
|
|
52
|
+
required: 'The particulars field is required.',
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
this.form = this.fb.group({
|
|
56
|
+
supplier_id: ['', Validators.compose([Validators.required])],
|
|
57
|
+
date: [new Date(), Validators.compose([Validators.required])],
|
|
58
|
+
particulars: ['', Validators.compose([Validators.required])],
|
|
59
|
+
stock_receipt_products: this.fb.array([])
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
ngOnInit() {
|
|
63
|
+
this.locationService.count().subscribe((count) => {
|
|
64
|
+
this.locationCount.set(count);
|
|
65
|
+
});
|
|
66
|
+
const id = this.route.snapshot.paramMap.get('id');
|
|
67
|
+
if (id) {
|
|
68
|
+
this.stockReceiptId.set(+id);
|
|
69
|
+
this.loadStockReceipt(+id);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
loadStockReceipt(id) {
|
|
73
|
+
this.isWorking = true;
|
|
74
|
+
this.stockReceiptService.show(id, { with: 'stockReceiptProducts.product' }).subscribe({
|
|
75
|
+
next: (response) => {
|
|
76
|
+
this.isWorking = false;
|
|
77
|
+
this.stockReceipt.set(response.item);
|
|
78
|
+
},
|
|
79
|
+
error: () => {
|
|
80
|
+
this.isWorking = false;
|
|
81
|
+
},
|
|
82
|
+
complete: () => {
|
|
83
|
+
this.form.patchValue({
|
|
84
|
+
supplier_id: this.stockReceipt().supplier_id,
|
|
85
|
+
date: this.stockReceipt().date ? new Date(this.stockReceipt().date) : new Date(),
|
|
86
|
+
particulars: this.stockReceipt().details,
|
|
87
|
+
});
|
|
88
|
+
this.stockReceiptProducts.clear();
|
|
89
|
+
this.stockReceipt().stock_receipt_products?.forEach((srp) => {
|
|
90
|
+
const group = this.createStockReceiptProduct();
|
|
91
|
+
group.patchValue({
|
|
92
|
+
id: srp.id,
|
|
93
|
+
product_id: srp.product_id,
|
|
94
|
+
location_id: srp.location_id,
|
|
95
|
+
quantity: srp.quantity,
|
|
96
|
+
purchase_price: srp.purchase_price,
|
|
97
|
+
total_amount: (srp.quantity || 0) * (srp.purchase_price || 0),
|
|
98
|
+
particulars: srp.particulars,
|
|
99
|
+
});
|
|
100
|
+
const index = this.stockReceiptProducts.length;
|
|
101
|
+
group.get('quantity')?.valueChanges.pipe(debounceTime(300))
|
|
102
|
+
.subscribe(() => this.updateRowTotal(index));
|
|
103
|
+
group.get('purchase_price')?.valueChanges.pipe(debounceTime(300))
|
|
104
|
+
.subscribe(() => this.updateRowTotal(index));
|
|
105
|
+
this.stockReceiptProducts.push(group);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
get stockReceiptProducts() {
|
|
111
|
+
return this.form.get('stock_receipt_products');
|
|
112
|
+
}
|
|
113
|
+
createStockReceiptProduct() {
|
|
114
|
+
return this.fb.group({
|
|
115
|
+
id: [''],
|
|
116
|
+
product_id: ['', Validators.required],
|
|
117
|
+
location_id: ['', this.locationCount() > 0 ? Validators.required : null],
|
|
118
|
+
quantity: [1, [Validators.required, Validators.min(1)]],
|
|
119
|
+
purchase_price: [0, [Validators.required, Validators.min(0)]],
|
|
120
|
+
total_amount: [{ value: 0, disabled: true }],
|
|
121
|
+
particulars: ['']
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
getSelectedProduct(index) {
|
|
125
|
+
return this.stockReceipt()
|
|
126
|
+
?.stock_receipt_products?.find((sr) => sr.id === this.stockReceiptProducts.at(index)?.get('id')?.value)?.product;
|
|
127
|
+
}
|
|
128
|
+
addStockReceiptProduct() {
|
|
129
|
+
const group = this.createStockReceiptProduct();
|
|
130
|
+
const index = this.stockReceiptProducts.length;
|
|
131
|
+
group.get('quantity')?.valueChanges.pipe(debounceTime(300))
|
|
132
|
+
.subscribe(() => this.updateRowTotal(index));
|
|
133
|
+
group.get('purchase_price')?.valueChanges.pipe(debounceTime(300))
|
|
134
|
+
.subscribe(() => this.updateRowTotal(index));
|
|
135
|
+
this.stockReceiptProducts.push(group);
|
|
136
|
+
}
|
|
137
|
+
removeStockReceiptProduct(index) {
|
|
138
|
+
this.stockReceiptProducts.removeAt(index);
|
|
139
|
+
}
|
|
140
|
+
clearProducts() {
|
|
141
|
+
this.stockReceiptProducts.clear();
|
|
142
|
+
}
|
|
143
|
+
getRowTotal(index) {
|
|
144
|
+
const row = this.stockReceiptProducts.at(index);
|
|
145
|
+
if (!row) {
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
const quantity = row.get('quantity')?.value;
|
|
149
|
+
const purchasePrice = row.get('purchase_price')?.value;
|
|
150
|
+
return quantity * purchasePrice;
|
|
151
|
+
}
|
|
152
|
+
updateRowTotal(index) {
|
|
153
|
+
this.stockReceiptProducts.at(index)
|
|
154
|
+
?.get('total_amount')
|
|
155
|
+
?.setValue(this.getRowTotal(index));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* We're doing a little more than a normal submit so we won't use the
|
|
159
|
+
* techlify-form's submit method
|
|
160
|
+
*/
|
|
161
|
+
save() {
|
|
162
|
+
if (this.form.invalid) {
|
|
163
|
+
this.form.markAllAsTouched();
|
|
164
|
+
this.form.markAsDirty();
|
|
165
|
+
this.alertService.addAlert('Please check the form for errors.', 'error');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (this.stockReceiptProducts.length === 0) {
|
|
169
|
+
this.alertService.addAlert('Please add at least one product.', 'error');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const formData = this.form.getRawValue();
|
|
173
|
+
const data = {
|
|
174
|
+
id: this.stockReceipt()?.id ?? null,
|
|
175
|
+
date: moment(formData.date).format('YYYY-MM-DD'),
|
|
176
|
+
supplier_id: formData.supplier_id,
|
|
177
|
+
details: formData.particulars,
|
|
178
|
+
products: formData.stock_receipt_products.map((row) => ({
|
|
179
|
+
id: row.product_id,
|
|
180
|
+
product_id: row.product_id,
|
|
181
|
+
supplier_id: formData.supplier_id,
|
|
182
|
+
quantity: row.quantity,
|
|
183
|
+
purchase_price: row.purchase_price,
|
|
184
|
+
amount: (parseFloat(row.quantity) || 0) * (parseFloat(row.purchase_price) || 0),
|
|
185
|
+
location_id: row.location_id,
|
|
186
|
+
particulars: row.particulars,
|
|
187
|
+
}))
|
|
188
|
+
};
|
|
189
|
+
this.isWorking = true;
|
|
190
|
+
const request$ = this.stockReceipt()?.id
|
|
191
|
+
? this.stockReceiptService.update(data)
|
|
192
|
+
: this.stockReceiptService.store(data);
|
|
193
|
+
request$.subscribe({
|
|
194
|
+
next: () => {
|
|
195
|
+
this.isWorking = false;
|
|
196
|
+
this.alertService.addAlert('Stock receipts saved successfully!', 'success');
|
|
197
|
+
this.location.back();
|
|
198
|
+
},
|
|
199
|
+
error: () => {
|
|
200
|
+
this.isWorking = false;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
cancel() {
|
|
205
|
+
this.location.back();
|
|
206
|
+
}
|
|
207
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StockReceiptFormComponent, deps: [{ token: i1.FormValidatorService }, { token: i2.FormBuilder }, { token: i3.StockReceiptService }, { token: i4.Router }, { token: i4.ActivatedRoute }, { token: i5.LocationService }, { token: i6.Location }], target: i0.ɵɵFactoryTarget.Component });
|
|
208
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: StockReceiptFormComponent, isStandalone: true, selector: "app-stock-receipt-form", usesInheritance: true, ngImport: i0, template: "<mat-card class=\"d-flex flex-column gap-2 container\">\n <mat-card-content>\n\n <div class=\"d-flex flex-column gap-1\">\n <h5>\n <span class=\"material-symbols-outlined align-middle\">download</span>\n Receive Stock\n </h5>\n </div>\n\n <form class=\"d-flex flex-column gap-2\" [formGroup]=\"form\" (submit)=\"save()\">\n\n <div class=\"d-flex flex-column\">\n <div class=\"d-flex flex-row gap-2 justify-content-between\">\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Supplier</mat-label>\n <app-searchable-selector apiUrl='api/suppliers' formControlName=\"supplier_id\"\n titleField='company_name' required></app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('supplier_id')\">{{ getErrorMessage('supplier_id') }}</mat-error>\n </mat-form-field>\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Date</mat-label>\n <input matInput [matDatepicker]=\"picker\" placeholder=\"Date\" formControlName=\"date\" required>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('date')\">{{ getErrorMessage('date') }}</mat-error>\n </mat-form-field>\n </div>\n\n <div class=\"d-flex flex-row gap-2 justify-content-between\">\n <div class=\"w-50\">\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Particulars</mat-label>\n <textarea matInput placeholder=\"Particulars\" formControlName=\"particulars\"></textarea>\n <mat-error *ngIf=\"isFieldValid('particulars')\">{{ getErrorMessage('particulars')\n }}</mat-error>\n </mat-form-field>\n </div>\n </div>\n </div>\n\n <table class=\"table mt-3\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">Product</th>\n <th *ngIf=\"locationCount() > 0\" scope=\"col\">Location</th>\n <th scope=\"col\">Quantity</th>\n <th scope=\"col\">Purchase Price</th>\n <th scope=\"col\">Total Value</th>\n <th scope=\"col\">Particulars</th>\n <th scope=\"col\" class=\"text-center\" width=\"50\"></th>\n </tr>\n </thead>\n <tbody formArrayName=\"stock_receipt_products\">\n <tr *ngFor=\"let row of stockReceiptProducts.controls; let i = index\" [formGroupName]=\"i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td>\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Product</mat-label>\n <app-searchable-selector apiUrl='api/products' formControlName=\"product_id\"\n titleField='name' [cache]=\"true\" [selectedValue]=\"getSelectedProduct(i)\" required></app-searchable-selector>\n </mat-form-field>\n </td>\n <td *ngIf=\"locationCount() > 0\">\n <app-location-selector appearance='outline' formControlName=\"location_id\"></app-location-selector>\n </td>\n <td>\n <mat-form-field appearance='outline' class='fl-sm'>\n <mat-label>Quantity</mat-label>\n <input matInput formControlName=\"quantity\" type=\"number\" min=\"1\">\n </mat-form-field>\n </td>\n <td>\n <mat-form-field appearance='outline' class='fl-sm'>\n <mat-label>Purchase Price</mat-label>\n <input matInput formControlName=\"purchase_price\" type=\"number\" min=\"0\">\n </mat-form-field>\n </td>\n <td>\n <mat-form-field appearance='outline' class='fl-sm'>\n <mat-label>Total Value</mat-label>\n <input matInput [value]=\"getRowTotal(i) | currency\" readonly>\n </mat-form-field>\n </td>\n <td>\n <mat-form-field appearance='outline'>\n <mat-label>Particulars</mat-label>\n <input matInput formControlName=\"particulars\">\n </mat-form-field>\n </td>\n <td class=\"text-center align-middle\">\n <div class=\"d-flex gap-2 justify-content-center align-items-center text-secondary\">\n <app-techlify-icon role='button' name='delete' (click)=\"removeStockReceiptProduct(i)\"\n matTooltip=\"Remove row\"></app-techlify-icon>\n </div>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan=\"8\" class=\"text-end\">\n <div class=\"d-flex flex-row gap-2 justify-content-end\">\n <button mat-button color=\"primary\" type=\"button\" (click)=\"clearProducts()\"\n [disabled]=\"stockReceiptProducts.length === 0\">\n <mat-icon>block</mat-icon> CLEAR ALL\n </button>\n <button mat-raised-button color=\"primary\" type=\"button\"\n (click)=\"addStockReceiptProduct()\">\n <mat-icon>add</mat-icon> ADD\n </button>\n </div>\n </td>\n </tr>\n </tfoot>\n </table>\n\n <div class=\"d-flex justify-content-end align-items-center gap-2 mt-2\">\n <button [disabled]=\"isWorking\" mat-flat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button [disabled]=\"isWorking || stockReceiptProducts.length === 0\" mat-raised-button color=\"primary\"\n type=\"submit\">Save</button>\n </div>\n\n </form>\n\n </mat-card-content>\n</mat-card>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: MaterialModule }, { kind: "component", type: i7.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i9.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i9.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i9.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: SearchableSelectorModule }, { kind: "component", type: i1.SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: LocationSelectorComponent, selector: "app-location-selector", inputs: ["appearance", "label", "placeholder", "includeNone"] }, { kind: "ngmodule", type: TechlifyIconModule }, { kind: "component", type: i1.TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }], preserveWhitespaces: true });
|
|
209
|
+
}
|
|
210
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StockReceiptFormComponent, decorators: [{
|
|
211
|
+
type: Component,
|
|
212
|
+
args: [{ selector: 'app-stock-receipt-form', standalone: true, imports: [
|
|
213
|
+
CommonModule,
|
|
214
|
+
ReactiveFormsModule,
|
|
215
|
+
MaterialModule,
|
|
216
|
+
SearchableSelectorModule,
|
|
217
|
+
LocationSelectorComponent,
|
|
218
|
+
TechlifyIconModule
|
|
219
|
+
], template: "<mat-card class=\"d-flex flex-column gap-2 container\">\n <mat-card-content>\n\n <div class=\"d-flex flex-column gap-1\">\n <h5>\n <span class=\"material-symbols-outlined align-middle\">download</span>\n Receive Stock\n </h5>\n </div>\n\n <form class=\"d-flex flex-column gap-2\" [formGroup]=\"form\" (submit)=\"save()\">\n\n <div class=\"d-flex flex-column\">\n <div class=\"d-flex flex-row gap-2 justify-content-between\">\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Supplier</mat-label>\n <app-searchable-selector apiUrl='api/suppliers' formControlName=\"supplier_id\"\n titleField='company_name' required></app-searchable-selector>\n <mat-error *ngIf=\"isFieldValid('supplier_id')\">{{ getErrorMessage('supplier_id') }}</mat-error>\n </mat-form-field>\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Date</mat-label>\n <input matInput [matDatepicker]=\"picker\" placeholder=\"Date\" formControlName=\"date\" required>\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('date')\">{{ getErrorMessage('date') }}</mat-error>\n </mat-form-field>\n </div>\n\n <div class=\"d-flex flex-row gap-2 justify-content-between\">\n <div class=\"w-50\">\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Particulars</mat-label>\n <textarea matInput placeholder=\"Particulars\" formControlName=\"particulars\"></textarea>\n <mat-error *ngIf=\"isFieldValid('particulars')\">{{ getErrorMessage('particulars')\n }}</mat-error>\n </mat-form-field>\n </div>\n </div>\n </div>\n\n <table class=\"table mt-3\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">Product</th>\n <th *ngIf=\"locationCount() > 0\" scope=\"col\">Location</th>\n <th scope=\"col\">Quantity</th>\n <th scope=\"col\">Purchase Price</th>\n <th scope=\"col\">Total Value</th>\n <th scope=\"col\">Particulars</th>\n <th scope=\"col\" class=\"text-center\" width=\"50\"></th>\n </tr>\n </thead>\n <tbody formArrayName=\"stock_receipt_products\">\n <tr *ngFor=\"let row of stockReceiptProducts.controls; let i = index\" [formGroupName]=\"i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td>\n <mat-form-field appearance='outline' class=\"w-100\">\n <mat-label>Product</mat-label>\n <app-searchable-selector apiUrl='api/products' formControlName=\"product_id\"\n titleField='name' [cache]=\"true\" [selectedValue]=\"getSelectedProduct(i)\" required></app-searchable-selector>\n </mat-form-field>\n </td>\n <td *ngIf=\"locationCount() > 0\">\n <app-location-selector appearance='outline' formControlName=\"location_id\"></app-location-selector>\n </td>\n <td>\n <mat-form-field appearance='outline' class='fl-sm'>\n <mat-label>Quantity</mat-label>\n <input matInput formControlName=\"quantity\" type=\"number\" min=\"1\">\n </mat-form-field>\n </td>\n <td>\n <mat-form-field appearance='outline' class='fl-sm'>\n <mat-label>Purchase Price</mat-label>\n <input matInput formControlName=\"purchase_price\" type=\"number\" min=\"0\">\n </mat-form-field>\n </td>\n <td>\n <mat-form-field appearance='outline' class='fl-sm'>\n <mat-label>Total Value</mat-label>\n <input matInput [value]=\"getRowTotal(i) | currency\" readonly>\n </mat-form-field>\n </td>\n <td>\n <mat-form-field appearance='outline'>\n <mat-label>Particulars</mat-label>\n <input matInput formControlName=\"particulars\">\n </mat-form-field>\n </td>\n <td class=\"text-center align-middle\">\n <div class=\"d-flex gap-2 justify-content-center align-items-center text-secondary\">\n <app-techlify-icon role='button' name='delete' (click)=\"removeStockReceiptProduct(i)\"\n matTooltip=\"Remove row\"></app-techlify-icon>\n </div>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan=\"8\" class=\"text-end\">\n <div class=\"d-flex flex-row gap-2 justify-content-end\">\n <button mat-button color=\"primary\" type=\"button\" (click)=\"clearProducts()\"\n [disabled]=\"stockReceiptProducts.length === 0\">\n <mat-icon>block</mat-icon> CLEAR ALL\n </button>\n <button mat-raised-button color=\"primary\" type=\"button\"\n (click)=\"addStockReceiptProduct()\">\n <mat-icon>add</mat-icon> ADD\n </button>\n </div>\n </td>\n </tr>\n </tfoot>\n </table>\n\n <div class=\"d-flex justify-content-end align-items-center gap-2 mt-2\">\n <button [disabled]=\"isWorking\" mat-flat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button [disabled]=\"isWorking || stockReceiptProducts.length === 0\" mat-raised-button color=\"primary\"\n type=\"submit\">Save</button>\n </div>\n\n </form>\n\n </mat-card-content>\n</mat-card>" }]
|
|
220
|
+
}], ctorParameters: () => [{ type: i1.FormValidatorService }, { type: i2.FormBuilder }, { type: i3.StockReceiptService }, { type: i4.Router }, { type: i4.ActivatedRoute }, { type: i5.LocationService }, { type: i6.Location }] });
|
|
221
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvY2stcmVjZWlwdC1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3N0b2NrLXJlY2VpcHRzL3N0b2NrLXJlY2VpcHQtZm9ybS9zdG9jay1yZWNlaXB0LWZvcm0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52ZW50b3J5LWNvbW1vbi9zcmMvbGliL2ludmVudG9yeS1jb21tb24vc3RvY2stcmVjZWlwdHMvc3RvY2stcmVjZWlwdC1mb3JtL3N0b2NrLXJlY2VpcHQtZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxRCxPQUFPLEVBQTBCLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pGLE9BQU8sRUFBd0IsOEJBQThCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzdELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDhEQUE4RCxDQUFDO0FBR3pHLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7QUFpQjVCLE1BQU0sT0FBTyx5QkFBMEIsU0FBUSw4QkFBOEI7SUFPMUM7SUFDbkI7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBWFosYUFBYSxHQUFHLE1BQU0sQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUVsQyxjQUFjLEdBQUcsTUFBTSxDQUFnQixJQUFJLENBQUMsQ0FBQztJQUM3QyxZQUFZLEdBQUcsTUFBTSxDQUFNLElBQUksQ0FBQyxDQUFDO0lBRWpDLFlBQStCLG9CQUEwQyxFQUM3RCxFQUFlLEVBQ2YsbUJBQXdDLEVBQ3hDLE1BQWMsRUFDZCxLQUFxQixFQUNyQixlQUFnQyxFQUNoQyxRQUFrQjtRQUUxQixLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQVJELHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBc0I7UUFDN0QsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUNmLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQ3JCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNoQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBSTFCLElBQUksQ0FBQyxhQUFhLEdBQUc7WUFDakIsV0FBVyxFQUFFO2dCQUNULFFBQVEsRUFBRSxpQ0FBaUM7YUFDOUM7WUFDRCxJQUFJLEVBQUU7Z0JBQ0YsUUFBUSxFQUFFLDZCQUE2QjthQUMxQztZQUNELFdBQVcsRUFBRTtnQkFDVCxRQUFRLEVBQUUsb0NBQW9DO2FBQ2pEO1NBQ0osQ0FBQztRQUVGLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDdEIsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUM1RCxJQUFJLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUM3RCxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzVELHNCQUFzQixFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztTQUM1QyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUU7WUFDckQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xELElBQUksRUFBRSxFQUFFLENBQUM7WUFDTCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9CLENBQUM7SUFDTCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsRUFBVTtRQUMvQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSw4QkFBOEIsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2xGLElBQUksRUFBRSxDQUFDLFFBQWEsRUFBRSxFQUFFO2dCQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLENBQUM7WUFDRCxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUNSLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBQzNCLENBQUM7WUFDRCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNYLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO29CQUNqQixXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLFdBQVc7b0JBQzVDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFO29CQUNoRixXQUFXLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLE9BQU87aUJBQzNDLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtvQkFDN0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7b0JBQy9DLEtBQUssQ0FBQyxVQUFVLENBQUM7d0JBQ2IsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFO3dCQUNWLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVTt3QkFDMUIsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXO3dCQUM1QixRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVE7d0JBQ3RCLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYzt3QkFDbEMsWUFBWSxFQUFFLENBQUMsR0FBRyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLElBQUksQ0FBQyxDQUFDO3dCQUM3RCxXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVc7cUJBQy9CLENBQUMsQ0FBQztvQkFDSCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDO29CQUMvQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO3lCQUN0RCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUNqRCxLQUFLLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7eUJBQzVELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7b0JBQ2pELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzFDLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztTQUNKLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxJQUFJLG9CQUFvQjtRQUNwQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFjLENBQUM7SUFDaEUsQ0FBQztJQUVELHlCQUF5QjtRQUNyQixPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO1lBQ2pCLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNSLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDO1lBQ3JDLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDeEUsUUFBUSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkQsY0FBYyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0QsWUFBWSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUM1QyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7U0FDcEIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELGtCQUFrQixDQUFDLEtBQWE7UUFDNUIsT0FBTyxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ3RCLEVBQUUsc0JBQXNCLEVBQUUsSUFBSSxDQUMxQixDQUFDLEVBQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQy9FLEVBQUUsT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFFRCxzQkFBc0I7UUFDbEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7UUFDL0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQztRQUUvQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3RELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDakQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQzVELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFakQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQseUJBQXlCLENBQUMsS0FBYTtRQUNuQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxhQUFhO1FBQ1QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RDLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBYTtRQUNyQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNQLE9BQU8sQ0FBQyxDQUFDO1FBQ2IsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxDQUFDO1FBQzVDLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxLQUFLLENBQUM7UUFDdkQsT0FBTyxRQUFRLEdBQUcsYUFBYSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxjQUFjLENBQUMsS0FBYTtRQUN4QixJQUFJLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUMvQixFQUFFLEdBQUcsQ0FBQyxjQUFjLENBQUM7WUFDckIsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJO1FBQ0EsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLG1DQUFtQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3pFLE9BQU87UUFDWCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLGtDQUFrQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3hFLE9BQU87UUFDWCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QyxNQUFNLElBQUksR0FBUTtZQUNkLEVBQUUsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsRUFBRSxJQUFJLElBQUk7WUFDbkMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQztZQUNoRCxXQUFXLEVBQUUsUUFBUSxDQUFDLFdBQVc7WUFDakMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxXQUFXO1lBQzdCLFFBQVEsRUFBRSxRQUFRLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN6RCxFQUFFLEVBQUUsR0FBRyxDQUFDLFVBQVU7Z0JBQ2xCLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVTtnQkFDMUIsV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXO2dCQUNqQyxRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVE7Z0JBQ3RCLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYztnQkFDbEMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMvRSxXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVc7Z0JBQzVCLFdBQVcsRUFBRSxHQUFHLENBQUMsV0FBVzthQUMvQixDQUFDLENBQUM7U0FDTixDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxFQUFFLEVBQUU7WUFDcEMsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ3ZDLENBQUMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTNDLFFBQVEsQ0FBQyxTQUFTLENBQUM7WUFDZixJQUFJLEVBQUUsR0FBRyxFQUFFO2dCQUNQLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUN2QixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxvQ0FBb0MsRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDNUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QixDQUFDO1lBQ0QsS0FBSyxFQUFFLEdBQUcsRUFBRTtnQkFDUixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUMzQixDQUFDO1NBQ0osQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELE1BQU07UUFDRixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7d0dBMU1RLHlCQUF5Qjs0RkFBekIseUJBQXlCLHlHQzNCdEMseWpPQThIVywyQ0Q1R0gsWUFBWSwwVEFDWixtQkFBbUIsb3REQUNuQixjQUFjLDBtRUFDZCx3QkFBd0IsbWhCQUN4Qix5QkFBeUIsZ0lBQ3pCLGtCQUFrQjs7NEZBSWIseUJBQXlCO2tCQWRyQyxTQUFTOytCQUNJLHdCQUF3QixjQUV0QixJQUFJLFdBQ1A7d0JBQ0wsWUFBWTt3QkFDWixtQkFBbUI7d0JBQ25CLGNBQWM7d0JBQ2Qsd0JBQXdCO3dCQUN4Qix5QkFBeUI7d0JBQ3pCLGtCQUFrQjtxQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgc2lnbmFsIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEZvcm1BcnJheSwgRm9ybUJ1aWxkZXIsIFJlYWN0aXZlRm9ybXNNb2R1bGUsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBGb3JtVmFsaWRhdG9yU2VydmljZSwgVGVjaGxpZnlGb3JtQ29tcG9uZW50SW50ZXJmYWNlLCBUZWNobGlmeUljb25Nb2R1bGUgfSBmcm9tIFwibmd4LXRlY2hsaWZ5LWNvcmVcIjtcbmltcG9ydCB7IE1hdGVyaWFsTW9kdWxlIH0gZnJvbSAnLi4vLi4vbWF0ZXJpYWwubW9kdWxlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSwgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgU2VhcmNoYWJsZVNlbGVjdG9yTW9kdWxlIH0gZnJvbSAnbmd4LXRlY2hsaWZ5LWNvcmUnO1xuaW1wb3J0IHsgTG9jYXRpb25TZWxlY3RvckNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2xvY2F0aW9uL2xvY2F0aW9uLXNlbGVjdG9yL2xvY2F0aW9uLXNlbGVjdG9yLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdG9ja1JlY2VpcHRTZXJ2aWNlIH0gZnJvbSAnLi4vc3RvY2stcmVjZWlwdC5zZXJ2aWNlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyBMb2NhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9sb2NhdGlvbi9sb2NhdGlvbi5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhcHAtc3RvY2stcmVjZWlwdC1mb3JtJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vc3RvY2stcmVjZWlwdC1mb3JtLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgQ29tbW9uTW9kdWxlLFxuICAgICAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgICAgICBNYXRlcmlhbE1vZHVsZSxcbiAgICAgICAgU2VhcmNoYWJsZVNlbGVjdG9yTW9kdWxlLFxuICAgICAgICBMb2NhdGlvblNlbGVjdG9yQ29tcG9uZW50LFxuICAgICAgICBUZWNobGlmeUljb25Nb2R1bGVcbiAgICBdXG59KVxuXG5leHBvcnQgY2xhc3MgU3RvY2tSZWNlaXB0Rm9ybUNvbXBvbmVudCBleHRlbmRzIFRlY2hsaWZ5Rm9ybUNvbXBvbmVudEludGVyZmFjZSBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgICBsb2NhdGlvbkNvdW50ID0gc2lnbmFsPG51bWJlcj4oMCk7XG5cbiAgICBzdG9ja1JlY2VpcHRJZCA9IHNpZ25hbDxudW1iZXIgfCBudWxsPihudWxsKTtcbiAgICBzdG9ja1JlY2VpcHQgPSBzaWduYWw8YW55PihudWxsKTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBvdmVycmlkZSBmb3JtVmFsaWRhdG9yU2VydmljZTogRm9ybVZhbGlkYXRvclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgICAgICBwcml2YXRlIHN0b2NrUmVjZWlwdFNlcnZpY2U6IFN0b2NrUmVjZWlwdFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgICAgICBwcml2YXRlIGxvY2F0aW9uU2VydmljZTogTG9jYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGxvY2F0aW9uOiBMb2NhdGlvblxuICAgICkge1xuICAgICAgICBzdXBlcihmb3JtVmFsaWRhdG9yU2VydmljZSk7XG5cbiAgICAgICAgdGhpcy5lcnJvck1lc3NhZ2VzID0ge1xuICAgICAgICAgICAgc3VwcGxpZXJfaWQ6IHtcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogJ1RoZSBzdXBwbGllciBmaWVsZCBpcyByZXF1aXJlZC4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRhdGU6IHtcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogJ1RoZSBkYXRlIGZpZWxkIGlzIHJlcXVpcmVkLicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGFydGljdWxhcnM6IHtcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogJ1RoZSBwYXJ0aWN1bGFycyBmaWVsZCBpcyByZXF1aXJlZC4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICAgIHN1cHBsaWVyX2lkOiBbJycsIFZhbGlkYXRvcnMuY29tcG9zZShbVmFsaWRhdG9ycy5yZXF1aXJlZF0pXSxcbiAgICAgICAgICAgIGRhdGU6IFtuZXcgRGF0ZSgpLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWRdKV0sXG4gICAgICAgICAgICBwYXJ0aWN1bGFyczogWycnLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWRdKV0sXG4gICAgICAgICAgICBzdG9ja19yZWNlaXB0X3Byb2R1Y3RzOiB0aGlzLmZiLmFycmF5KFtdKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2NhdGlvblNlcnZpY2UuY291bnQoKS5zdWJzY3JpYmUoKGNvdW50OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHRoaXMubG9jYXRpb25Db3VudC5zZXQoY291bnQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBpZCA9IHRoaXMucm91dGUuc25hcHNob3QucGFyYW1NYXAuZ2V0KCdpZCcpO1xuICAgICAgICBpZiAoaWQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvY2tSZWNlaXB0SWQuc2V0KCtpZCk7XG4gICAgICAgICAgICB0aGlzLmxvYWRTdG9ja1JlY2VpcHQoK2lkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgbG9hZFN0b2NrUmVjZWlwdChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNXb3JraW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdG9ja1JlY2VpcHRTZXJ2aWNlLnNob3coaWQsIHsgd2l0aDogJ3N0b2NrUmVjZWlwdFByb2R1Y3RzLnByb2R1Y3QnIH0pLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiAocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNXb3JraW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5zdG9ja1JlY2VpcHQuc2V0KHJlc3BvbnNlLml0ZW0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1dvcmtpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5wYXRjaFZhbHVlKHtcbiAgICAgICAgICAgICAgICAgICAgc3VwcGxpZXJfaWQ6IHRoaXMuc3RvY2tSZWNlaXB0KCkuc3VwcGxpZXJfaWQsXG4gICAgICAgICAgICAgICAgICAgIGRhdGU6IHRoaXMuc3RvY2tSZWNlaXB0KCkuZGF0ZSA/IG5ldyBEYXRlKHRoaXMuc3RvY2tSZWNlaXB0KCkuZGF0ZSkgOiBuZXcgRGF0ZSgpLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWN1bGFyczogdGhpcy5zdG9ja1JlY2VpcHQoKS5kZXRhaWxzLFxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5jbGVhcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvY2tSZWNlaXB0KCkuc3RvY2tfcmVjZWlwdF9wcm9kdWN0cz8uZm9yRWFjaCgoc3JwOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXAgPSB0aGlzLmNyZWF0ZVN0b2NrUmVjZWlwdFByb2R1Y3QoKTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAucGF0Y2hWYWx1ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogc3JwLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdF9pZDogc3JwLnByb2R1Y3RfaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbl9pZDogc3JwLmxvY2F0aW9uX2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcXVhbnRpdHk6IHNycC5xdWFudGl0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1cmNoYXNlX3ByaWNlOiBzcnAucHVyY2hhc2VfcHJpY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9hbW91bnQ6IChzcnAucXVhbnRpdHkgfHwgMCkgKiAoc3JwLnB1cmNoYXNlX3ByaWNlIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljdWxhcnM6IHNycC5wYXJ0aWN1bGFycyxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLmdldCgncXVhbnRpdHknKT8udmFsdWVDaGFuZ2VzLnBpcGUoZGVib3VuY2VUaW1lKDMwMCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMudXBkYXRlUm93VG90YWwoaW5kZXgpKTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAuZ2V0KCdwdXJjaGFzZV9wcmljZScpPy52YWx1ZUNoYW5nZXMucGlwZShkZWJvdW5jZVRpbWUoMzAwKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy51cGRhdGVSb3dUb3RhbChpbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b2NrUmVjZWlwdFByb2R1Y3RzLnB1c2goZ3JvdXApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXQgc3RvY2tSZWNlaXB0UHJvZHVjdHMoKTogRm9ybUFycmF5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybS5nZXQoJ3N0b2NrX3JlY2VpcHRfcHJvZHVjdHMnKSBhcyBGb3JtQXJyYXk7XG4gICAgfVxuXG4gICAgY3JlYXRlU3RvY2tSZWNlaXB0UHJvZHVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICAgICAgaWQ6IFsnJ10sXG4gICAgICAgICAgICBwcm9kdWN0X2lkOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgICAgICAgbG9jYXRpb25faWQ6IFsnJywgdGhpcy5sb2NhdGlvbkNvdW50KCkgPiAwID8gVmFsaWRhdG9ycy5yZXF1aXJlZCA6IG51bGxdLFxuICAgICAgICAgICAgcXVhbnRpdHk6IFsxLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMSldXSxcbiAgICAgICAgICAgIHB1cmNoYXNlX3ByaWNlOiBbMCwgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWluKDApXV0sXG4gICAgICAgICAgICB0b3RhbF9hbW91bnQ6IFt7IHZhbHVlOiAwLCBkaXNhYmxlZDogdHJ1ZSB9XSxcbiAgICAgICAgICAgIHBhcnRpY3VsYXJzOiBbJyddXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldFNlbGVjdGVkUHJvZHVjdChpbmRleDogbnVtYmVyKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvY2tSZWNlaXB0KClcbiAgICAgICAgICAgID8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0cz8uZmluZChcbiAgICAgICAgICAgICAgICAoc3I6IGFueSkgPT4gc3IuaWQgPT09IHRoaXMuc3RvY2tSZWNlaXB0UHJvZHVjdHMuYXQoaW5kZXgpPy5nZXQoJ2lkJyk/LnZhbHVlXG4gICAgICAgICAgICApPy5wcm9kdWN0O1xuICAgIH1cblxuICAgIGFkZFN0b2NrUmVjZWlwdFByb2R1Y3QoKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5jcmVhdGVTdG9ja1JlY2VpcHRQcm9kdWN0KCk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5sZW5ndGg7XG5cbiAgICAgICAgZ3JvdXAuZ2V0KCdxdWFudGl0eScpPy52YWx1ZUNoYW5nZXMucGlwZShkZWJvdW5jZVRpbWUoMzAwKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy51cGRhdGVSb3dUb3RhbChpbmRleCkpO1xuICAgICAgICBncm91cC5nZXQoJ3B1cmNoYXNlX3ByaWNlJyk/LnZhbHVlQ2hhbmdlcy5waXBlKGRlYm91bmNlVGltZSgzMDApKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnVwZGF0ZVJvd1RvdGFsKGluZGV4KSk7XG5cbiAgICAgICAgdGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5wdXNoKGdyb3VwKTtcbiAgICB9XG5cbiAgICByZW1vdmVTdG9ja1JlY2VpcHRQcm9kdWN0KGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5yZW1vdmVBdChpbmRleCk7XG4gICAgfVxuXG4gICAgY2xlYXJQcm9kdWN0cygpIHtcbiAgICAgICAgdGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5jbGVhcigpO1xuICAgIH1cblxuICAgIGdldFJvd1RvdGFsKGluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCByb3cgPSB0aGlzLnN0b2NrUmVjZWlwdFByb2R1Y3RzLmF0KGluZGV4KTtcbiAgICAgICAgaWYgKCFyb3cpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHF1YW50aXR5ID0gcm93LmdldCgncXVhbnRpdHknKT8udmFsdWU7XG4gICAgICAgIGNvbnN0IHB1cmNoYXNlUHJpY2UgPSByb3cuZ2V0KCdwdXJjaGFzZV9wcmljZScpPy52YWx1ZTtcbiAgICAgICAgcmV0dXJuIHF1YW50aXR5ICogcHVyY2hhc2VQcmljZTtcbiAgICB9XG5cbiAgICB1cGRhdGVSb3dUb3RhbChpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuc3RvY2tSZWNlaXB0UHJvZHVjdHMuYXQoaW5kZXgpXG4gICAgICAgICAgICA/LmdldCgndG90YWxfYW1vdW50JylcbiAgICAgICAgICAgID8uc2V0VmFsdWUodGhpcy5nZXRSb3dUb3RhbChpbmRleCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdlJ3JlIGRvaW5nIGEgbGl0dGxlIG1vcmUgdGhhbiBhIG5vcm1hbCBzdWJtaXQgc28gd2Ugd29uJ3QgdXNlIHRoZVxuICAgICAqIHRlY2hsaWZ5LWZvcm0ncyBzdWJtaXQgbWV0aG9kXG4gICAgICovXG4gICAgc2F2ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9ybS5pbnZhbGlkKSB7XG4gICAgICAgICAgICB0aGlzLmZvcm0ubWFya0FsbEFzVG91Y2hlZCgpO1xuICAgICAgICAgICAgdGhpcy5mb3JtLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRBbGVydCgnUGxlYXNlIGNoZWNrIHRoZSBmb3JtIGZvciBlcnJvcnMuJywgJ2Vycm9yJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdG9ja1JlY2VpcHRQcm9kdWN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZEFsZXJ0KCdQbGVhc2UgYWRkIGF0IGxlYXN0IG9uZSBwcm9kdWN0LicsICdlcnJvcicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmZvcm0uZ2V0UmF3VmFsdWUoKTtcbiAgICAgICAgY29uc3QgZGF0YTogYW55ID0ge1xuICAgICAgICAgICAgaWQ6IHRoaXMuc3RvY2tSZWNlaXB0KCk/LmlkID8/IG51bGwsXG4gICAgICAgICAgICBkYXRlOiBtb21lbnQoZm9ybURhdGEuZGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgICAgICBzdXBwbGllcl9pZDogZm9ybURhdGEuc3VwcGxpZXJfaWQsXG4gICAgICAgICAgICBkZXRhaWxzOiBmb3JtRGF0YS5wYXJ0aWN1bGFycyxcbiAgICAgICAgICAgIHByb2R1Y3RzOiBmb3JtRGF0YS5zdG9ja19yZWNlaXB0X3Byb2R1Y3RzLm1hcCgocm93OiBhbnkpID0+ICh7XG4gICAgICAgICAgICAgICAgaWQ6IHJvdy5wcm9kdWN0X2lkLFxuICAgICAgICAgICAgICAgIHByb2R1Y3RfaWQ6IHJvdy5wcm9kdWN0X2lkLFxuICAgICAgICAgICAgICAgIHN1cHBsaWVyX2lkOiBmb3JtRGF0YS5zdXBwbGllcl9pZCxcbiAgICAgICAgICAgICAgICBxdWFudGl0eTogcm93LnF1YW50aXR5LFxuICAgICAgICAgICAgICAgIHB1cmNoYXNlX3ByaWNlOiByb3cucHVyY2hhc2VfcHJpY2UsXG4gICAgICAgICAgICAgICAgYW1vdW50OiAocGFyc2VGbG9hdChyb3cucXVhbnRpdHkpIHx8IDApICogKHBhcnNlRmxvYXQocm93LnB1cmNoYXNlX3ByaWNlKSB8fCAwKSxcbiAgICAgICAgICAgICAgICBsb2NhdGlvbl9pZDogcm93LmxvY2F0aW9uX2lkLFxuICAgICAgICAgICAgICAgIHBhcnRpY3VsYXJzOiByb3cucGFydGljdWxhcnMsXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmlzV29ya2luZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IHJlcXVlc3QkID0gdGhpcy5zdG9ja1JlY2VpcHQoKT8uaWRcbiAgICAgICAgICAgID8gdGhpcy5zdG9ja1JlY2VpcHRTZXJ2aWNlLnVwZGF0ZShkYXRhKVxuICAgICAgICAgICAgOiB0aGlzLnN0b2NrUmVjZWlwdFNlcnZpY2Uuc3RvcmUoZGF0YSk7XG5cbiAgICAgICAgcmVxdWVzdCQuc3Vic2NyaWJlKHtcbiAgICAgICAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzV29ya2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZEFsZXJ0KCdTdG9jayByZWNlaXB0cyBzYXZlZCBzdWNjZXNzZnVsbHkhJywgJ3N1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2F0aW9uLmJhY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNXb3JraW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNhbmNlbCgpIHtcbiAgICAgICAgdGhpcy5sb2NhdGlvbi5iYWNrKCk7XG4gICAgfVxufVxuIiwiPG1hdC1jYXJkIGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0yIGNvbnRhaW5lclwiPlxuICAgIDxtYXQtY2FyZC1jb250ZW50PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTFcIj5cbiAgICAgICAgICAgIDxoNT5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgYWxpZ24tbWlkZGxlXCI+ZG93bmxvYWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgUmVjZWl2ZSBTdG9ja1xuICAgICAgICAgICAgPC9oNT5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGZvcm0gY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTJcIiBbZm9ybUdyb3VwXT1cImZvcm1cIiAoc3VibWl0KT1cInNhdmUoKVwiPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LXJvdyBnYXAtMiBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT0nb3V0bGluZScgY2xhc3M9XCJ3LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5TdXBwbGllcjwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGFwcC1zZWFyY2hhYmxlLXNlbGVjdG9yIGFwaVVybD0nYXBpL3N1cHBsaWVycycgZm9ybUNvbnRyb2xOYW1lPVwic3VwcGxpZXJfaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlRmllbGQ9J2NvbXBhbnlfbmFtZScgcmVxdWlyZWQ+PC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJpc0ZpZWxkVmFsaWQoJ3N1cHBsaWVyX2lkJylcIj57eyBnZXRFcnJvck1lc3NhZ2UoJ3N1cHBsaWVyX2lkJykgfX08L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9J291dGxpbmUnIGNsYXNzPVwidy0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+RGF0ZTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFttYXREYXRlcGlja2VyXT1cInBpY2tlclwiIHBsYWNlaG9sZGVyPVwiRGF0ZVwiIGZvcm1Db250cm9sTmFtZT1cImRhdGVcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwicGlja2VyXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWRhdGVwaWNrZXIgI3BpY2tlcj48L21hdC1kYXRlcGlja2VyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImlzRmllbGRWYWxpZCgnZGF0ZScpXCI+e3sgZ2V0RXJyb3JNZXNzYWdlKCdkYXRlJykgfX08L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1yb3cgZ2FwLTIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPSdvdXRsaW5lJyBjbGFzcz1cInctMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5QYXJ0aWN1bGFyczwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIlBhcnRpY3VsYXJzXCIgZm9ybUNvbnRyb2xOYW1lPVwicGFydGljdWxhcnNcIj48L3RleHRhcmVhPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJpc0ZpZWxkVmFsaWQoJ3BhcnRpY3VsYXJzJylcIj57eyBnZXRFcnJvck1lc3NhZ2UoJ3BhcnRpY3VsYXJzJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L21hdC1lcnJvcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIG10LTNcIj5cbiAgICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0aCBzY29wZT1cImNvbFwiPiM8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPVwiY29sXCI+UHJvZHVjdDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggKm5nSWY9XCJsb2NhdGlvbkNvdW50KCkgPiAwXCIgc2NvcGU9XCJjb2xcIj5Mb2NhdGlvbjwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5RdWFudGl0eTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5QdXJjaGFzZSBQcmljZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5Ub3RhbCBWYWx1ZTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5QYXJ0aWN1bGFyczwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIiBjbGFzcz1cInRleHQtY2VudGVyXCIgd2lkdGg9XCI1MFwiPjwvdGg+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICA8dGJvZHkgZm9ybUFycmF5TmFtZT1cInN0b2NrX3JlY2VpcHRfcHJvZHVjdHNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2Ygc3RvY2tSZWNlaXB0UHJvZHVjdHMuY29udHJvbHM7IGxldCBpID0gaW5kZXhcIiBbZm9ybUdyb3VwTmFtZV09XCJpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9XCJyb3dcIj57eyBpICsgMSB9fTwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9J291dGxpbmUnIGNsYXNzPVwidy0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5Qcm9kdWN0PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9J2FwaS9wcm9kdWN0cycgZm9ybUNvbnRyb2xOYW1lPVwicHJvZHVjdF9pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZUZpZWxkPSduYW1lJyBbY2FjaGVdPVwidHJ1ZVwiIFtzZWxlY3RlZFZhbHVlXT1cImdldFNlbGVjdGVkUHJvZHVjdChpKVwiIHJlcXVpcmVkPjwvYXBwLXNlYXJjaGFibGUtc2VsZWN0b3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJsb2NhdGlvbkNvdW50KCkgPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGFwcC1sb2NhdGlvbi1zZWxlY3RvciBhcHBlYXJhbmNlPSdvdXRsaW5lJyBmb3JtQ29udHJvbE5hbWU9XCJsb2NhdGlvbl9pZFwiPjwvYXBwLWxvY2F0aW9uLXNlbGVjdG9yPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT0nb3V0bGluZScgY2xhc3M9J2ZsLXNtJz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5RdWFudGl0eTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgZm9ybUNvbnRyb2xOYW1lPVwicXVhbnRpdHlcIiB0eXBlPVwibnVtYmVyXCIgbWluPVwiMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPSdvdXRsaW5lJyBjbGFzcz0nZmwtc20nPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlB1cmNoYXNlIFByaWNlPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBmb3JtQ29udHJvbE5hbWU9XCJwdXJjaGFzZV9wcmljZVwiIHR5cGU9XCJudW1iZXJcIiBtaW49XCIwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9J291dGxpbmUnIGNsYXNzPSdmbC1zbSc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+VG90YWwgVmFsdWU8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFt2YWx1ZV09XCJnZXRSb3dUb3RhbChpKSB8IGN1cnJlbmN5XCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9J291dGxpbmUnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlBhcnRpY3VsYXJzPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBmb3JtQ29udHJvbE5hbWU9XCJwYXJ0aWN1bGFyc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1jZW50ZXIgYWxpZ24tbWlkZGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMiBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlciB0ZXh0LXNlY29uZGFyeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YXBwLXRlY2hsaWZ5LWljb24gcm9sZT0nYnV0dG9uJyBuYW1lPSdkZWxldGUnIChjbGljayk9XCJyZW1vdmVTdG9ja1JlY2VpcHRQcm9kdWN0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJSZW1vdmUgcm93XCI+PC9hcHAtdGVjaGxpZnktaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICA8dGZvb3Q+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiOFwiIGNsYXNzPVwidGV4dC1lbmRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93IGdhcC0yIGp1c3RpZnktY29udGVudC1lbmRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtYnV0dG9uIGNvbG9yPVwicHJpbWFyeVwiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xlYXJQcm9kdWN0cygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJzdG9ja1JlY2VpcHRQcm9kdWN0cy5sZW5ndGggPT09IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5ibG9jazwvbWF0LWljb24+IENMRUFSIEFMTFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdG9ja1JlY2VpcHRQcm9kdWN0KClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPiBBRERcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGZvb3Q+XG4gICAgICAgICAgICA8L3RhYmxlPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1lbmQgYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yIG10LTJcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCJpc1dvcmtpbmdcIiBtYXQtZmxhdC1idXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjYW5jZWwoKVwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cImlzV29ya2luZyB8fCBzdG9ja1JlY2VpcHRQcm9kdWN0cy5sZW5ndGggPT09IDBcIiBtYXQtcmFpc2VkLWJ1dHRvbiBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwic3VibWl0XCI+U2F2ZTwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPC9mb3JtPlxuXG4gICAgPC9tYXQtY2FyZC1jb250ZW50PlxuPC9tYXQtY2FyZD4iXX0=
|