@smarterplan/ngx-smarterplan-locations 0.2.21 → 0.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/esm2020/lib/components/carousel/carousel.component.mjs +27 -27
  2. package/esm2020/lib/components/chevron/chevron.component.mjs +17 -17
  3. package/esm2020/lib/components/detail-location/detail-location.component.mjs +154 -154
  4. package/esm2020/lib/components/form-location/form-location.component.mjs +237 -237
  5. package/esm2020/lib/components/images/images.component.mjs +90 -90
  6. package/esm2020/lib/components/locations/locations.component.mjs +141 -141
  7. package/esm2020/lib/components/locations/map/map-popup/map-popup.component.mjs +65 -65
  8. package/esm2020/lib/components/locations/map/map.component.mjs +90 -90
  9. package/esm2020/lib/components/plan-legend/plan-legend.component.mjs +47 -0
  10. package/esm2020/lib/components/plans/calibration/calibration.component.mjs +468 -468
  11. package/esm2020/lib/components/plans/edit-plan/edit-plan.component.mjs +324 -324
  12. package/esm2020/lib/components/plans/plans.component.mjs +210 -210
  13. package/esm2020/lib/components/tab-navigation/tab-navigation.component.mjs +41 -41
  14. package/esm2020/lib/components/visits/visits.component.mjs +235 -235
  15. package/esm2020/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +230 -230
  16. package/esm2020/lib/components/zones/add-zone/add-zone.component.mjs +294 -294
  17. package/esm2020/lib/components/zones/add-zone/selection/selection.component.mjs +76 -76
  18. package/esm2020/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +414 -413
  19. package/esm2020/lib/components/zones/zones.component.mjs +236 -232
  20. package/esm2020/lib/helper.service.mjs +134 -134
  21. package/esm2020/lib/ngx-smarterplan-location-routing.module.mjs +49 -49
  22. package/esm2020/lib/ngx-smarterplan-locations.module.mjs +125 -122
  23. package/esm2020/lib/ngx-smarterplan-locations.service.mjs +13 -13
  24. package/esm2020/lib/pipes/count-audio-sweeps.pipe.mjs +26 -26
  25. package/esm2020/lib/radio-button/radio-button.component.mjs +26 -26
  26. package/esm2020/public-api.mjs +8 -8
  27. package/esm2020/smarterplan-ngx-smarterplan-locations.mjs +4 -4
  28. package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs +3676 -3624
  29. package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
  30. package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs +3520 -3472
  31. package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
  32. package/lib/components/carousel/carousel.component.d.ts +12 -12
  33. package/lib/components/chevron/chevron.component.d.ts +9 -9
  34. package/lib/components/detail-location/detail-location.component.d.ts +51 -51
  35. package/lib/components/form-location/form-location.component.d.ts +45 -45
  36. package/lib/components/images/images.component.d.ts +28 -28
  37. package/lib/components/locations/locations.component.d.ts +50 -50
  38. package/lib/components/locations/map/map-popup/map-popup.component.d.ts +22 -22
  39. package/lib/components/locations/map/map.component.d.ts +22 -22
  40. package/lib/components/plan-legend/plan-legend.component.d.ts +14 -0
  41. package/lib/components/plans/calibration/calibration.component.d.ts +140 -140
  42. package/lib/components/plans/edit-plan/edit-plan.component.d.ts +55 -55
  43. package/lib/components/plans/plans.component.d.ts +59 -59
  44. package/lib/components/tab-navigation/tab-navigation.component.d.ts +13 -13
  45. package/lib/components/visits/visits.component.d.ts +51 -51
  46. package/lib/components/zones/add-audio-zone/add-audio-zone.component.d.ts +63 -63
  47. package/lib/components/zones/add-zone/add-zone.component.d.ts +67 -67
  48. package/lib/components/zones/add-zone/selection/selection.component.d.ts +44 -44
  49. package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +96 -96
  50. package/lib/components/zones/zones.component.d.ts +67 -67
  51. package/lib/helper.service.d.ts +53 -53
  52. package/lib/ngx-smarterplan-location-routing.module.d.ts +7 -7
  53. package/lib/ngx-smarterplan-locations.module.d.ts +36 -35
  54. package/lib/ngx-smarterplan-locations.service.d.ts +6 -6
  55. package/lib/pipes/count-audio-sweeps.pipe.d.ts +10 -10
  56. package/lib/radio-button/radio-button.component.d.ts +12 -12
  57. package/package.json +1 -1
  58. package/public-api.d.ts +4 -4
  59. package/smarterplan-ngx-smarterplan-locations.d.ts +5 -5
@@ -1,91 +1,91 @@
1
- import { Component } from '@angular/core';
2
- import { InventoryStatus } from '@smarterplan/ngx-smarterplan-core';
3
- import * as i0 from "@angular/core";
4
- import * as i1 from "@angular/router";
5
- import * as i2 from "@smarterplan/ngx-smarterplan-core";
6
- import * as i3 from "../tab-navigation/tab-navigation.component";
7
- import * as i4 from "../carousel/carousel.component";
8
- import * as i5 from "@angular/common";
9
- import * as i6 from "@ng-bootstrap/ng-bootstrap";
10
- import * as i7 from "@ngx-translate/core";
11
- export class ImagesComponent {
12
- constructor(route, spaceService, visitService, nodeService) {
13
- this.route = route;
14
- this.spaceService = spaceService;
15
- this.visitService = visitService;
16
- this.nodeService = nodeService;
17
- this.loading = false;
18
- this.menuItems = [];
19
- }
20
- ngOnInit() {
21
- this.spaceID = this.route.snapshot.paramMap.get("id");
22
- this.loadImages();
23
- }
24
- setupMenuItems() {
25
- this.menuItems = [
26
- { label: "Locations", url: "/localisation" },
27
- {
28
- label: this.currentSpace.name,
29
- url: `/localisation/${this.spaceID}`,
30
- },
31
- { label: "360° Images" },
32
- ];
33
- if (this.currentVisit) {
34
- this.menuItems.push({ label: this.currentVisit.name });
35
- }
36
- }
37
- onGoBack() {
38
- this.currentVisit = null;
39
- this.currentImages = null;
40
- this.setupMenuItems();
41
- }
42
- async loadImages() {
43
- this.loading = true;
44
- this.currentSpace = await this.spaceService.getSpace(this.spaceID);
45
- this.setupMenuItems();
46
- this.images = await this.visitService.loadImagesForSpace(this.currentSpace);
47
- if (this.currentSpace.visits.length === 1) {
48
- this.setVisit(this.currentSpace.visits[0]);
49
- }
50
- this.loading = false;
51
- }
52
- setVisit(visit) {
53
- this.currentVisit = visit;
54
- this.currentImages = this.images.filter((im) => {
55
- return im.visit === visit;
56
- });
57
- this.setupMenuItems();
58
- }
59
- setCurrentScan(id) {
60
- this.currentScanID = id;
61
- }
62
- async onInventoryClick() {
63
- const { node } = this.currentVisit;
64
- const { filename } = this.currentImages[this.currentScanID]; // 110ee452_sweep.jpeg
65
- // check if node has already errors of inventory
66
- const missingFilesErrors = [
67
- InventoryStatus.ERROR_FILE_JSON_NOT_EXIST,
68
- InventoryStatus.ERROR_FILE_MODEL_NOT_EXIST,
69
- InventoryStatus.ERROR_FILE_OBJ_NOT_EXIST,
70
- ];
71
- if (node.inventoryStatus &&
72
- missingFilesErrors.includes(node.inventoryStatus)) {
73
- alert("Files missing for this visit's inventory. Contact your administrator.");
74
- }
75
- else {
76
- await this.nodeService.updateNode({
77
- id: node.id,
78
- inventoryStatus: InventoryStatus.TO_RUN_ONE_IMAGE,
79
- navigationForInventory: filename.split("_")[0],
80
- });
81
- alert("Automatic AI Inventory started! Detected equipments will appear soon in the visit.");
82
- }
83
- }
84
- }
85
- ImagesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ImagesComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i2.NodeService }], target: i0.ɵɵFactoryTarget.Component });
86
- ImagesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: ImagesComponent, selector: "lib-images", ngImport: i0, template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""], components: [{ type: i3.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { type: i4.CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { type: i6.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { type: i6.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }], pipes: { "translate": i7.TranslatePipe } });
87
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ImagesComponent, decorators: [{
88
- type: Component,
89
- args: [{ selector: 'lib-images', template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""] }]
90
- }], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i2.SpaceService }, { type: i2.VisitService }, { type: i2.NodeService }]; } });
1
+ import { Component } from '@angular/core';
2
+ import { InventoryStatus } from '@smarterplan/ngx-smarterplan-core';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/router";
5
+ import * as i2 from "@smarterplan/ngx-smarterplan-core";
6
+ import * as i3 from "../tab-navigation/tab-navigation.component";
7
+ import * as i4 from "../carousel/carousel.component";
8
+ import * as i5 from "@angular/common";
9
+ import * as i6 from "@ng-bootstrap/ng-bootstrap";
10
+ import * as i7 from "@ngx-translate/core";
11
+ export class ImagesComponent {
12
+ constructor(route, spaceService, visitService, nodeService) {
13
+ this.route = route;
14
+ this.spaceService = spaceService;
15
+ this.visitService = visitService;
16
+ this.nodeService = nodeService;
17
+ this.loading = false;
18
+ this.menuItems = [];
19
+ }
20
+ ngOnInit() {
21
+ this.spaceID = this.route.snapshot.paramMap.get("id");
22
+ this.loadImages();
23
+ }
24
+ setupMenuItems() {
25
+ this.menuItems = [
26
+ { label: "Locations", url: "/localisation" },
27
+ {
28
+ label: this.currentSpace.name,
29
+ url: `/localisation/${this.spaceID}`,
30
+ },
31
+ { label: "360° Images" },
32
+ ];
33
+ if (this.currentVisit) {
34
+ this.menuItems.push({ label: this.currentVisit.name });
35
+ }
36
+ }
37
+ onGoBack() {
38
+ this.currentVisit = null;
39
+ this.currentImages = null;
40
+ this.setupMenuItems();
41
+ }
42
+ async loadImages() {
43
+ this.loading = true;
44
+ this.currentSpace = await this.spaceService.getSpace(this.spaceID);
45
+ this.setupMenuItems();
46
+ this.images = await this.visitService.loadImagesForSpace(this.currentSpace);
47
+ if (this.currentSpace.visits.length === 1) {
48
+ this.setVisit(this.currentSpace.visits[0]);
49
+ }
50
+ this.loading = false;
51
+ }
52
+ setVisit(visit) {
53
+ this.currentVisit = visit;
54
+ this.currentImages = this.images.filter((im) => {
55
+ return im.visit === visit;
56
+ });
57
+ this.setupMenuItems();
58
+ }
59
+ setCurrentScan(id) {
60
+ this.currentScanID = id;
61
+ }
62
+ async onInventoryClick() {
63
+ const { node } = this.currentVisit;
64
+ const { filename } = this.currentImages[this.currentScanID]; // 110ee452_sweep.jpeg
65
+ // check if node has already errors of inventory
66
+ const missingFilesErrors = [
67
+ InventoryStatus.ERROR_FILE_JSON_NOT_EXIST,
68
+ InventoryStatus.ERROR_FILE_MODEL_NOT_EXIST,
69
+ InventoryStatus.ERROR_FILE_OBJ_NOT_EXIST,
70
+ ];
71
+ if (node.inventoryStatus &&
72
+ missingFilesErrors.includes(node.inventoryStatus)) {
73
+ alert("Files missing for this visit's inventory. Contact your administrator.");
74
+ }
75
+ else {
76
+ await this.nodeService.updateNode({
77
+ id: node.id,
78
+ inventoryStatus: InventoryStatus.TO_RUN_ONE_IMAGE,
79
+ navigationForInventory: filename.split("_")[0],
80
+ });
81
+ alert("Automatic AI Inventory started! Detected equipments will appear soon in the visit.");
82
+ }
83
+ }
84
+ }
85
+ ImagesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ImagesComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i2.NodeService }], target: i0.ɵɵFactoryTarget.Component });
86
+ ImagesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: ImagesComponent, selector: "lib-images", ngImport: i0, template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""], components: [{ type: i3.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { type: i4.CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { type: i6.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { type: i6.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }], pipes: { "translate": i7.TranslatePipe } });
87
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ImagesComponent, decorators: [{
88
+ type: Component,
89
+ args: [{ selector: 'lib-images', template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""] }]
90
+ }], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i2.SpaceService }, { type: i2.VisitService }, { type: i2.NodeService }]; } });
91
91
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2VzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL2ltYWdlcy9pbWFnZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvaW1hZ2VzL2ltYWdlcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBRWxELE9BQU8sRUFBbUUsZUFBZSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7Ozs7Ozs7OztBQU9ySSxNQUFNLE9BQU8sZUFBZTtJQWtCeEIsWUFDWSxLQUFxQixFQUNyQixZQUEwQixFQUMxQixZQUEwQixFQUMxQixXQUF3QjtRQUh4QixVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUNyQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQVZwQyxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBSWhCLGNBQVMsR0FBZSxFQUFFLENBQUM7SUFPeEIsQ0FBQztJQUVKLFFBQVE7UUFDSixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxjQUFjO1FBQ1YsSUFBSSxDQUFDLFNBQVMsR0FBRztZQUNiLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUUsZUFBZSxFQUFFO1lBQzVDO2dCQUNJLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxD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U0FBUzsrQkFDRSxZQUFZIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFNwYWNlLCBWaXNpdCwgTWVudUl0ZW0sIFNwYWNlU2VydmljZSwgVmlzaXRTZXJ2aWNlLCBOb2RlU2VydmljZSwgSW52ZW50b3J5U3RhdHVzIH0gZnJvbSAnQHNtYXJ0ZXJwbGFuL25neC1zbWFydGVycGxhbi1jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLWltYWdlcycsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbWFnZXMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9pbWFnZXMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBJbWFnZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgaW1hZ2VzOiBBcnJheTxhbnk+O1xuXG4gICAgc3BhY2VJRDogc3RyaW5nO1xuXG4gICAgY3VycmVudFNwYWNlOiBTcGFjZTtcblxuICAgIGN1cnJlbnRWaXNpdDogVmlzaXQ7XG5cbiAgICBjdXJyZW50SW1hZ2VzOiBBcnJheTxhbnk+O1xuXG4gICAgbG9hZGluZyA9IGZhbHNlO1xuXG4gICAgY3VycmVudFNjYW5JRDogc3RyaW5nO1xuXG4gICAgbWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgc3BhY2VTZXJ2aWNlOiBTcGFjZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgdmlzaXRTZXJ2aWNlOiBWaXNpdFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVTZXJ2aWNlLFxuICAgICkge31cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNwYWNlSUQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmFtTWFwLmdldChcImlkXCIpO1xuICAgICAgICB0aGlzLmxvYWRJbWFnZXMoKTtcbiAgICB9XG5cbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXG4gICAgICAgICAgICB7IGxhYmVsOiBcIkxvY2F0aW9uc1wiLCB1cmw6IFwiL2xvY2FsaXNhdGlvblwiIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMuY3VycmVudFNwYWNlLm5hbWUsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuc3BhY2VJRH1gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgbGFiZWw6IFwiMzYwwrAgSW1hZ2VzXCIgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAodGhpcy5jdXJyZW50VmlzaXQpIHtcbiAgICAgICAgICAgIHRoaXMubWVudUl0ZW1zLnB1c2goeyBsYWJlbDogdGhpcy5jdXJyZW50VmlzaXQubmFtZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uR29CYWNrKCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRWaXNpdCA9IG51bGw7XG4gICAgICAgIHRoaXMuY3VycmVudEltYWdlcyA9IG51bGw7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICB9XG5cbiAgICBhc3luYyBsb2FkSW1hZ2VzKCkge1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJRCk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICAgICAgdGhpcy5pbWFnZXMgPSBhd2FpdCB0aGlzLnZpc2l0U2VydmljZS5sb2FkSW1hZ2VzRm9yU3BhY2UoXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFNwYWNlLnZpc2l0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0VmlzaXQodGhpcy5jdXJyZW50U3BhY2UudmlzaXRzWzBdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzZXRWaXNpdCh2aXNpdCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRWaXNpdCA9IHZpc2l0O1xuICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZXMgPSB0aGlzLmltYWdlcy5maWx0ZXIoKGltKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gaW0udmlzaXQgPT09IHZpc2l0O1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xuICAgIH1cblxuICAgIHNldEN1cnJlbnRTY2FuKGlkKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFNjYW5JRCA9IGlkO1xuICAgIH1cblxuICAgIGFzeW5jIG9uSW52ZW50b3J5Q2xpY2soKSB7XG4gICAgICAgIGNvbnN0IHsgbm9kZSB9ID0gdGhpcy5jdXJyZW50VmlzaXQ7XG4gICAgICAgIGNvbnN0IHsgZmlsZW5hbWUgfSA9IHRoaXMuY3VycmVudEltYWdlc1t0aGlzLmN1cnJlbnRTY2FuSURdOyAvLyAxMTBlZTQ1Ml9zd2VlcC5qcGVnXG4gICAgICAgIC8vIGNoZWNrIGlmIG5vZGUgaGFzIGFscmVhZHkgZXJyb3JzIG9mIGludmVudG9yeVxuICAgICAgICBjb25zdCBtaXNzaW5nRmlsZXNFcnJvcnMgPSBbXG4gICAgICAgICAgICBJbnZlbnRvcnlTdGF0dXMuRVJST1JfRklMRV9KU09OX05PVF9FWElTVCxcbiAgICAgICAgICAgIEludmVudG9yeVN0YXR1cy5FUlJPUl9GSUxFX01PREVMX05PVF9FWElTVCxcbiAgICAgICAgICAgIEludmVudG9yeVN0YXR1cy5FUlJPUl9GSUxFX09CSl9OT1RfRVhJU1QsXG4gICAgICAgIF07XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIG5vZGUuaW52ZW50b3J5U3RhdHVzICYmXG4gICAgICAgICAgICBtaXNzaW5nRmlsZXNFcnJvcnMuaW5jbHVkZXMobm9kZS5pbnZlbnRvcnlTdGF0dXMpXG4gICAgICAgICkge1xuICAgICAgICAgICAgYWxlcnQoXG4gICAgICAgICAgICAgICAgXCJGaWxlcyBtaXNzaW5nIGZvciB0aGlzIHZpc2l0J3MgaW52ZW50b3J5LiBDb250YWN0IHlvdXIgYWRtaW5pc3RyYXRvci5cIixcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLm5vZGVTZXJ2aWNlLnVwZGF0ZU5vZGUoe1xuICAgICAgICAgICAgICAgIGlkOiBub2RlLmlkLFxuICAgICAgICAgICAgICAgIGludmVudG9yeVN0YXR1czogSW52ZW50b3J5U3RhdHVzLlRPX1JVTl9PTkVfSU1BR0UsXG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbkZvckludmVudG9yeTogZmlsZW5hbWUuc3BsaXQoXCJfXCIpWzBdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhbGVydChcbiAgICAgICAgICAgICAgICBcIkF1dG9tYXRpYyBBSSBJbnZlbnRvcnkgc3RhcnRlZCEgRGV0ZWN0ZWQgZXF1aXBtZW50cyB3aWxsIGFwcGVhciBzb29uIGluIHRoZSB2aXNpdC5cIixcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWQgZGFzaGJvYXJkLXRhYiBjb2wtc20tMTAgbWItM1wiICpuZ0lmPVwiY3VycmVudFNwYWNlXCIgPlxuICAgIDxkaXYgY2xhc3M9XCJtLTNcIj5cbiAgICAgIDxsaWItdGFiLW5hdmlnYXRpb24gW21lbnVJdGVtc109J21lbnVJdGVtcycgKG9uR29CYWNrKT1cIm9uR29CYWNrKClcIj48L2xpYi10YWItbmF2aWdhdGlvbj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIiAqbmdJZj1cImxvYWRpbmdcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyLWJvcmRlclwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj57eydMb2FkaW5nJyB8IHRyYW5zbGF0ZX19Li4uPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBuZ2JEcm9wZG93biBjbGFzcz1cImQtaW5saW5lLWJsb2NrXCIgKm5nSWY9XCJjdXJyZW50U3BhY2UudmlzaXRzICYmIGN1cnJlbnRTcGFjZS52aXNpdHMubGVuZ3RoID4gMFwiPlxuICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tbGFiZWwtZmlsZSByb3VuZGVkLXBpbGxcIiBpZD1cImRyb3Bkb3duQmFzaWMxXCIgKm5nSWY9XCIhY3VycmVudFZpc2l0XCJcbiAgICAgICAgbmdiRHJvcGRvd25Ub2dnbGU+e3snQ2hvb3NlIDNEIHZpc2l0JyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICA8ZGl2IG5nYkRyb3Bkb3duTWVudSBhcmlhLWxhYmVsbGVkYnk9XCJkcm9wZG93bkJhc2ljMVwiPlxuICAgICAgICA8YnV0dG9uIG5nYkRyb3Bkb3duSXRlbSAqbmdGb3I9XCJsZXQgdmlzaXQgb2YgY3VycmVudFNwYWNlLnZpc2l0c1wiIChjbGljayk9XCJzZXRWaXNpdCh2aXNpdClcIj4ge3sgdmlzaXQubmFtZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxoMyAqbmdJZj1cImN1cnJlbnRWaXNpdFwiPnt7IGN1cnJlbnRWaXNpdC5uYW1lIH19PC9oMz5cbiAgICA8ZGl2IGNsYXNzPVwibXQtM1wiICpuZ0lmPVwiY3VycmVudFZpc2l0ICYmIGN1cnJlbnRJbWFnZXMubGVuZ3RoID09IDAgJiYgIWxvYWRpbmdcIj5cbiAgICAgIDxoND57eydObyBpbXBvcnRlZCBpbWFnZXMnIHwgdHJhbnNsYXRlIH19PC9oND5cbiAgICAgIDxwPnt7J0ZvciBpbXBvcnQ6IGdvIFZpcnR1YWwgVmlzaXRzID0+IEltcG9ydCBJbWFnZXMnIHwgdHJhbnNsYXRlfX08L3A+XG4gICAgPC9kaXY+XG4gICAgPGJ1dHRvbiAqbmdJZj1cImN1cnJlbnRWaXNpdCAmJiBjdXJyZW50SW1hZ2VzLmxlbmd0aCA+IDAgJiYgIWxvYWRpbmdcIlxuICAgICAgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbm8tbG93ZXJjYXNlIG1iLTJcIiAoY2xpY2spPVwib25JbnZlbnRvcnlDbGljaygpXCI+XG4gICAgICB7eydSdW4gQUkgaW52ZW50b3J5IG9uIHRoaXMgaW1hZ2UnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICA8bGliLWNhcm91c2VsIFtpbWFnZXNdPVwiY3VycmVudEltYWdlc1wiICpuZ0lmPVwiY3VycmVudEltYWdlc1wiIChjdXJyZW50U2Nhbik9XCJzZXRDdXJyZW50U2NhbigkZXZlbnQpXCI+PC9saWItY2Fyb3VzZWw+XG4gIDwvZGl2PiJdfQ==