ng-tailwind 4.1.13 → 4.1.14

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 (202) hide show
  1. package/README.md +24 -24
  2. package/animations/ngt-angular-animations.d.ts +5 -5
  3. package/base/ngt-base-ng-model.d.ts +32 -32
  4. package/components/ngt-action/ngt-action.component.d.ts +16 -16
  5. package/components/ngt-action/ngt-action.module.d.ts +10 -10
  6. package/components/ngt-button/ngt-button.component.d.ts +25 -25
  7. package/components/ngt-button/ngt-button.module.d.ts +10 -10
  8. package/components/ngt-checkbox/ngt-checkbox.component.d.ts +47 -46
  9. package/components/ngt-checkbox/ngt-checkbox.module.d.ts +10 -10
  10. package/components/ngt-content/ngt-content.component.d.ts +12 -12
  11. package/components/ngt-content/ngt-content.module.d.ts +8 -8
  12. package/components/ngt-datatable/ngt-datatable.component.d.ts +117 -117
  13. package/components/ngt-datatable/ngt-datatable.module.d.ts +24 -24
  14. package/components/ngt-datatable/ngt-tbody/ngt-tbody.component.d.ts +14 -14
  15. package/components/ngt-datatable/ngt-td/ngt-td.component.d.ts +14 -14
  16. package/components/ngt-datatable/ngt-td-check/ngt-td-check.component.d.ts +29 -29
  17. package/components/ngt-datatable/ngt-th/ngt-th.component.d.ts +51 -51
  18. package/components/ngt-datatable/ngt-th-check/ngt-th-check.component.d.ts +22 -22
  19. package/components/ngt-datatable/ngt-thead/ngt-thead.component.d.ts +13 -13
  20. package/components/ngt-datatable/ngt-tr/ngt-tr.component.d.ts +20 -20
  21. package/components/ngt-date/ngt-date.component.d.ts +79 -79
  22. package/components/ngt-date/ngt-date.module.d.ts +13 -13
  23. package/components/ngt-dropdown/ngt-dropdown-container/ngt-dropdown-container.component.d.ts +8 -8
  24. package/components/ngt-dropdown/ngt-dropdown.component.d.ts +53 -53
  25. package/components/ngt-dropdown/ngt-dropdown.module.d.ts +9 -9
  26. package/components/ngt-dropzone/custom-dropzone-preview/custom-dropzone-preview.component.d.ts +14 -14
  27. package/components/ngt-dropzone/ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component.d.ts +25 -25
  28. package/components/ngt-dropzone/ngt-dropzone-view/ngt-dropzone-view.component.d.ts +35 -35
  29. package/components/ngt-dropzone/ngt-dropzone.component.d.ts +86 -86
  30. package/components/ngt-dropzone/ngt-dropzone.meta.d.ts +27 -27
  31. package/components/ngt-dropzone/ngt-dropzone.module.d.ts +17 -17
  32. package/components/ngt-floating-button/ngt-floating-button.component.d.ts +35 -35
  33. package/components/ngt-floating-button/ngt-floating-button.module.d.ts +10 -10
  34. package/components/ngt-form/ngt-form-validation-message/ngt-form-validation-message.component.d.ts +10 -10
  35. package/components/ngt-form/ngt-form.component.d.ts +55 -55
  36. package/components/ngt-form/ngt-form.module.d.ts +9 -9
  37. package/components/ngt-header-nav/ngt-header-nav.component.d.ts +14 -14
  38. package/components/ngt-header-nav/ngt-header-nav.module.d.ts +8 -8
  39. package/components/ngt-helper/ngt-helper.component.d.ts +25 -25
  40. package/components/ngt-helper/ngt-helper.module.d.ts +10 -10
  41. package/components/ngt-input/ngt-input.component.d.ts +109 -109
  42. package/components/ngt-input/ngt-input.module.d.ts +14 -14
  43. package/components/ngt-modal/ngt-modal-body/ngt-modal-body.component.d.ts +5 -5
  44. package/components/ngt-modal/ngt-modal-footer/ngt-modal-footer.component.d.ts +5 -5
  45. package/components/ngt-modal/ngt-modal-header/ngt-modal-header.component.d.ts +15 -15
  46. package/components/ngt-modal/ngt-modal.component.d.ts +25 -25
  47. package/components/ngt-modal/ngt-modal.module.d.ts +11 -11
  48. package/components/ngt-multi-select/ngt-multi-select.component.d.ts +103 -103
  49. package/components/ngt-multi-select/ngt-multi-select.module.d.ts +15 -15
  50. package/components/ngt-pagination/ngt-pagination.component.d.ts +43 -43
  51. package/components/ngt-pagination/ngt-pagination.module.d.ts +12 -12
  52. package/components/ngt-popover/ngt-popover-tooltip/ngt-popover-tooltip.component.d.ts +15 -15
  53. package/components/ngt-popover/ngt-popover.component.d.ts +31 -31
  54. package/components/ngt-popover/ngt-popover.directive.d.ts +27 -27
  55. package/components/ngt-popover/ngt-popover.module.d.ts +11 -11
  56. package/components/ngt-portlet/ngt-portlet-body/ngt-portlet-body.component.d.ts +12 -12
  57. package/components/ngt-portlet/ngt-portlet-footer/ngt-portlet-footer.component.d.ts +12 -12
  58. package/components/ngt-portlet/ngt-portlet-header/ngt-portlet-header.component.d.ts +17 -17
  59. package/components/ngt-portlet/ngt-portlet.component.d.ts +20 -20
  60. package/components/ngt-portlet/ngt-portlet.module.d.ts +13 -13
  61. package/components/ngt-radio-button/ngt-radio-button-container/ngt-radio-button-container.component.d.ts +9 -9
  62. package/components/ngt-radio-button/ngt-radio-button.component.d.ts +35 -35
  63. package/components/ngt-radio-button/ngt-radio-button.module.d.ts +11 -11
  64. package/components/ngt-section/ngt-section.component.d.ts +29 -29
  65. package/components/ngt-section/ngt-section.module.d.ts +11 -11
  66. package/components/ngt-select/ngt-select.component.d.ts +135 -135
  67. package/components/ngt-select/ngt-select.directive.d.ts +20 -20
  68. package/components/ngt-select/ngt-select.module.d.ts +16 -16
  69. package/components/ngt-shining/ngt-shining.component.d.ts +19 -19
  70. package/components/ngt-shining/ngt-shining.module.d.ts +8 -8
  71. package/components/ngt-sidenav/ngt-sidenav.component.d.ts +32 -32
  72. package/components/ngt-sidenav/ngt-sidenav.module.d.ts +8 -8
  73. package/components/ngt-slider/ngt-slider.component.d.ts +34 -34
  74. package/components/ngt-slider/ngt-slider.module.d.ts +9 -9
  75. package/components/ngt-svg/ngt-svg.component.d.ts +13 -13
  76. package/components/ngt-svg/ngt-svg.module.d.ts +10 -10
  77. package/components/ngt-tag/ngt-tag.component.d.ts +13 -13
  78. package/components/ngt-tag/ngt-tag.module.d.ts +9 -9
  79. package/components/ngt-textarea/ngt-textarea.component.d.ts +49 -49
  80. package/components/ngt-textarea/ngt-textarea.module.d.ts +13 -13
  81. package/components/ngt-validation/ngt-validation.component.d.ts +13 -13
  82. package/components/ngt-validation/ngt-validation.module.d.ts +8 -8
  83. package/directives/ngt-stylizable/ngt-stylizable.directive.d.ts +68 -68
  84. package/directives/ngt-stylizable/ngt-stylizable.module.d.ts +8 -8
  85. package/enums/size.enum.d.ts +8 -8
  86. package/esm2020/animations/ngt-angular-animations.mjs +34 -34
  87. package/esm2020/base/ngt-base-ng-model.mjs +90 -90
  88. package/esm2020/components/ngt-action/ngt-action.component.mjs +54 -54
  89. package/esm2020/components/ngt-action/ngt-action.module.mjs +28 -28
  90. package/esm2020/components/ngt-button/ngt-button.component.mjs +115 -115
  91. package/esm2020/components/ngt-button/ngt-button.module.mjs +28 -28
  92. package/esm2020/components/ngt-checkbox/ngt-checkbox.component.mjs +177 -175
  93. package/esm2020/components/ngt-checkbox/ngt-checkbox.module.mjs +28 -28
  94. package/esm2020/components/ngt-content/ngt-content.component.mjs +32 -32
  95. package/esm2020/components/ngt-content/ngt-content.module.mjs +20 -20
  96. package/esm2020/components/ngt-datatable/ngt-datatable.component.mjs +431 -431
  97. package/esm2020/components/ngt-datatable/ngt-datatable.module.mjs +95 -95
  98. package/esm2020/components/ngt-datatable/ngt-tbody/ngt-tbody.component.mjs +57 -57
  99. package/esm2020/components/ngt-datatable/ngt-td/ngt-td.component.mjs +62 -62
  100. package/esm2020/components/ngt-datatable/ngt-td-check/ngt-td-check.component.mjs +113 -113
  101. package/esm2020/components/ngt-datatable/ngt-th/ngt-th.component.mjs +211 -211
  102. package/esm2020/components/ngt-datatable/ngt-th-check/ngt-th-check.component.mjs +91 -91
  103. package/esm2020/components/ngt-datatable/ngt-thead/ngt-thead.component.mjs +55 -55
  104. package/esm2020/components/ngt-datatable/ngt-tr/ngt-tr.component.mjs +86 -86
  105. package/esm2020/components/ngt-date/ngt-date.component.mjs +418 -418
  106. package/esm2020/components/ngt-date/ngt-date.module.mjs +40 -40
  107. package/esm2020/components/ngt-dropdown/ngt-dropdown-container/ngt-dropdown-container.component.mjs +19 -19
  108. package/esm2020/components/ngt-dropdown/ngt-dropdown.component.mjs +204 -204
  109. package/esm2020/components/ngt-dropdown/ngt-dropdown.module.mjs +21 -21
  110. package/esm2020/components/ngt-dropzone/custom-dropzone-preview/custom-dropzone-preview.component.mjs +54 -54
  111. package/esm2020/components/ngt-dropzone/ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component.mjs +66 -66
  112. package/esm2020/components/ngt-dropzone/ngt-dropzone-view/ngt-dropzone-view.component.mjs +94 -94
  113. package/esm2020/components/ngt-dropzone/ngt-dropzone.component.mjs +464 -464
  114. package/esm2020/components/ngt-dropzone/ngt-dropzone.meta.mjs +24 -24
  115. package/esm2020/components/ngt-dropzone/ngt-dropzone.module.mjs +55 -55
  116. package/esm2020/components/ngt-floating-button/ngt-floating-button.component.mjs +119 -119
  117. package/esm2020/components/ngt-floating-button/ngt-floating-button.module.mjs +28 -28
  118. package/esm2020/components/ngt-form/ngt-form-validation-message/ngt-form-validation-message.component.mjs +22 -22
  119. package/esm2020/components/ngt-form/ngt-form.component.mjs +193 -193
  120. package/esm2020/components/ngt-form/ngt-form.module.mjs +29 -29
  121. package/esm2020/components/ngt-header-nav/ngt-header-nav.component.mjs +39 -39
  122. package/esm2020/components/ngt-header-nav/ngt-header-nav.module.mjs +20 -20
  123. package/esm2020/components/ngt-helper/ngt-helper.component.mjs +68 -68
  124. package/esm2020/components/ngt-helper/ngt-helper.module.mjs +28 -28
  125. package/esm2020/components/ngt-input/ngt-input.component.mjs +722 -722
  126. package/esm2020/components/ngt-input/ngt-input.module.mjs +47 -47
  127. package/esm2020/components/ngt-modal/ngt-modal-body/ngt-modal-body.component.mjs +11 -11
  128. package/esm2020/components/ngt-modal/ngt-modal-footer/ngt-modal-footer.component.mjs +11 -11
  129. package/esm2020/components/ngt-modal/ngt-modal-header/ngt-modal-header.component.mjs +38 -38
  130. package/esm2020/components/ngt-modal/ngt-modal.component.mjs +102 -102
  131. package/esm2020/components/ngt-modal/ngt-modal.module.mjs +39 -39
  132. package/esm2020/components/ngt-multi-select/ngt-multi-select.component.mjs +446 -446
  133. package/esm2020/components/ngt-multi-select/ngt-multi-select.module.mjs +52 -52
  134. package/esm2020/components/ngt-pagination/ngt-pagination.component.mjs +162 -162
  135. package/esm2020/components/ngt-pagination/ngt-pagination.module.mjs +36 -36
  136. package/esm2020/components/ngt-popover/ngt-popover-tooltip/ngt-popover-tooltip.component.mjs +40 -40
  137. package/esm2020/components/ngt-popover/ngt-popover.component.mjs +85 -85
  138. package/esm2020/components/ngt-popover/ngt-popover.directive.mjs +105 -105
  139. package/esm2020/components/ngt-popover/ngt-popover.module.mjs +36 -36
  140. package/esm2020/components/ngt-portlet/ngt-portlet-body/ngt-portlet-body.component.mjs +34 -34
  141. package/esm2020/components/ngt-portlet/ngt-portlet-footer/ngt-portlet-footer.component.mjs +33 -33
  142. package/esm2020/components/ngt-portlet/ngt-portlet-header/ngt-portlet-header.component.mjs +53 -53
  143. package/esm2020/components/ngt-portlet/ngt-portlet.component.mjs +74 -74
  144. package/esm2020/components/ngt-portlet/ngt-portlet.module.mjs +47 -47
  145. package/esm2020/components/ngt-radio-button/ngt-radio-button-container/ngt-radio-button-container.component.mjs +19 -19
  146. package/esm2020/components/ngt-radio-button/ngt-radio-button.component.mjs +125 -125
  147. package/esm2020/components/ngt-radio-button/ngt-radio-button.module.mjs +29 -29
  148. package/esm2020/components/ngt-section/ngt-section.component.mjs +119 -119
  149. package/esm2020/components/ngt-section/ngt-section.module.mjs +32 -32
  150. package/esm2020/components/ngt-select/ngt-select.component.mjs +552 -552
  151. package/esm2020/components/ngt-select/ngt-select.directive.mjs +36 -36
  152. package/esm2020/components/ngt-select/ngt-select.module.mjs +65 -65
  153. package/esm2020/components/ngt-shining/ngt-shining.component.mjs +40 -40
  154. package/esm2020/components/ngt-shining/ngt-shining.module.mjs +20 -20
  155. package/esm2020/components/ngt-sidenav/ngt-sidenav.component.mjs +132 -132
  156. package/esm2020/components/ngt-sidenav/ngt-sidenav.module.mjs +20 -20
  157. package/esm2020/components/ngt-slider/ngt-slider.component.mjs +99 -99
  158. package/esm2020/components/ngt-slider/ngt-slider.module.mjs +24 -24
  159. package/esm2020/components/ngt-svg/ngt-svg.component.mjs +53 -53
  160. package/esm2020/components/ngt-svg/ngt-svg.module.mjs +28 -28
  161. package/esm2020/components/ngt-tag/ngt-tag.component.mjs +37 -37
  162. package/esm2020/components/ngt-tag/ngt-tag.module.mjs +24 -24
  163. package/esm2020/components/ngt-textarea/ngt-textarea.component.mjs +238 -238
  164. package/esm2020/components/ngt-textarea/ngt-textarea.module.mjs +43 -43
  165. package/esm2020/components/ngt-validation/ngt-validation.component.mjs +26 -26
  166. package/esm2020/components/ngt-validation/ngt-validation.module.mjs +20 -20
  167. package/esm2020/directives/ngt-stylizable/ngt-stylizable.directive.mjs +290 -290
  168. package/esm2020/directives/ngt-stylizable/ngt-stylizable.module.mjs +20 -20
  169. package/esm2020/enums/size.enum.mjs +11 -11
  170. package/esm2020/helpers/enum/enum.mjs +7 -7
  171. package/esm2020/helpers/form/form.mjs +14 -14
  172. package/esm2020/helpers/input-mask/input-mask.helper.mjs +23 -23
  173. package/esm2020/helpers/routing/route.mjs +11 -11
  174. package/esm2020/helpers/uuid.mjs +10 -10
  175. package/esm2020/ng-tailwind.mjs +4 -4
  176. package/esm2020/public-api.mjs +121 -121
  177. package/esm2020/services/http/ngt-attachment-http.service.mjs +3 -3
  178. package/esm2020/services/http/ngt-http-form.service.mjs +3 -3
  179. package/esm2020/services/http/ngt-http-resource.service.mjs +3 -3
  180. package/esm2020/services/http/ngt-http-validation.service.mjs +3 -3
  181. package/esm2020/services/http/ngt-http.service.mjs +3 -3
  182. package/esm2020/services/http/ngt-translate.service.mjs +3 -3
  183. package/esm2020/services/ngt-stylizable/ngt-stylizable.service.mjs +273 -273
  184. package/fesm2015/ng-tailwind.mjs +7792 -7790
  185. package/fesm2015/ng-tailwind.mjs.map +1 -1
  186. package/fesm2020/ng-tailwind.mjs +7655 -7653
  187. package/fesm2020/ng-tailwind.mjs.map +1 -1
  188. package/helpers/enum/enum.d.ts +1 -1
  189. package/helpers/form/form.d.ts +4 -4
  190. package/helpers/input-mask/input-mask.helper.d.ts +17 -17
  191. package/helpers/routing/route.d.ts +2 -2
  192. package/helpers/uuid.d.ts +1 -1
  193. package/index.d.ts +5 -5
  194. package/package.json +1 -1
  195. package/public-api.d.ts +83 -83
  196. package/services/http/ngt-attachment-http.service.d.ts +10 -10
  197. package/services/http/ngt-http-form.service.d.ts +5 -5
  198. package/services/http/ngt-http-resource.service.d.ts +12 -12
  199. package/services/http/ngt-http-validation.service.d.ts +11 -11
  200. package/services/http/ngt-http.service.d.ts +27 -27
  201. package/services/http/ngt-translate.service.d.ts +29 -29
  202. package/services/ngt-stylizable/ngt-stylizable.service.d.ts +96 -96
@@ -1,464 +1,464 @@
1
- import { Component, EventEmitter, Host, Input, Optional, Output, SkipSelf, ViewChild, ViewEncapsulation, } from '@angular/core';
2
- import { ControlContainer, NgForm, Validators } from '@angular/forms';
3
- import { NgxDropzoneComponent } from 'ngx-dropzone';
4
- import { forkJoin } from 'rxjs';
5
- import { map } from 'rxjs/operators';
6
- import Viewer from 'viewerjs';
7
- import { NgtBaseNgModel, NgtMakeProvider } from '../../base/ngt-base-ng-model';
8
- import { getEnumFromString } from '../../helpers/enum/enum';
9
- import { uuid } from '../../helpers/uuid';
10
- import { NgtStylizableService } from '../../services/ngt-stylizable/ngt-stylizable.service';
11
- import { NgtDropzoneFileViewerComponent } from './ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component';
12
- import { NgtDropzoneErrorType, NgtDropzonePreviewType } from './ngt-dropzone.meta';
13
- import * as i0 from "@angular/core";
14
- import * as i1 from "@angular/forms";
15
- import * as i2 from "../../services/http/ngt-attachment-http.service";
16
- import * as i3 from "@angular/common";
17
- import * as i4 from "../ngt-validation/ngt-validation.component";
18
- import * as i5 from "ngx-dropzone";
19
- import * as i6 from "../ngt-helper/ngt-helper.component";
20
- import * as i7 from "./ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component";
21
- import * as i8 from "./ngt-dropzone-view/ngt-dropzone-view.component";
22
- import * as i9 from "./custom-dropzone-preview/custom-dropzone-preview.component";
23
- export class NgtDropzoneComponent extends NgtBaseNgModel {
24
- ;
25
- constructor(formContainer, ngtAttachmentHttpService, injector, changeDetector) {
26
- super();
27
- this.formContainer = formContainer;
28
- this.ngtAttachmentHttpService = ngtAttachmentHttpService;
29
- this.injector = injector;
30
- this.changeDetector = changeDetector;
31
- this.helpTextColor = 'text-green-500';
32
- // Behavior
33
- this.resources = [];
34
- this.multipleSelection = false;
35
- this.showFileName = false;
36
- this.disableClick = false;
37
- this.disabled = false;
38
- this.viewMode = false;
39
- this.removable = false;
40
- this.canDownloadFile = true;
41
- this.verticalExpandable = false;
42
- this.acceptedFiles = '*' /** Mime type */;
43
- this.previewType = NgtDropzonePreviewType.DEFAULT;
44
- this.isRequired = false;
45
- this.onFileSelected = new EventEmitter();
46
- this.onFileSelectError = new EventEmitter();
47
- this.onFileUploadFail = new EventEmitter();
48
- this.onFileRemoved = new EventEmitter();
49
- this.onFileUploadInit = new EventEmitter();
50
- this.onFileUploaded = new EventEmitter();
51
- this.onFilePreviewLoaded = new EventEmitter();
52
- this.dropzoneHeight = '180px';
53
- this.uploadedResources = [];
54
- this.forceDisableClick = false;
55
- this.nativeValue = [];
56
- this.showNgtDropzoneFileViewer = false;
57
- this.componentReady = false;
58
- this.loading = false;
59
- this.ngxElementId = uuid();
60
- this.imageViewerOptions = {
61
- navbar: true,
62
- toolbar: {
63
- zoomIn: true,
64
- zoomOut: true,
65
- reset: true,
66
- rotateLeft: true,
67
- rotateRight: true,
68
- prev: true,
69
- next: true,
70
- }
71
- };
72
- this.subscriptions = [];
73
- this.ngtDropzoneLoaderStyle = new NgtStylizableService();
74
- this.ngtDropzoneLoaderStyle.load(this.injector, 'NgtDropzoneLoader', {
75
- h: 'h-8',
76
- color: {
77
- text: 'text-gray-600'
78
- }
79
- });
80
- }
81
- ngOnChanges(changes) {
82
- if (changes.previewType) {
83
- this.previewType = getEnumFromString(changes.previewType.currentValue, NgtDropzonePreviewType);
84
- }
85
- }
86
- ngAfterContentChecked() {
87
- if (this.container && this.container.nativeElement) {
88
- this.dropzoneHeight = `${this.container.nativeElement.parentElement.offsetHeight}px`;
89
- this.changeDetector.detectChanges();
90
- }
91
- }
92
- ngOnInit() {
93
- setTimeout(() => {
94
- this.componentReady = true;
95
- setTimeout(() => {
96
- this.initComponent();
97
- });
98
- }, 500);
99
- }
100
- ngOnDestroy() {
101
- this.destroySubscriptions();
102
- }
103
- imagePreview(index) {
104
- const images = this.uploadedResources.filter((resource) => this.isImage(resource));
105
- const imagesDiv = document.createElement("div");
106
- images.forEach((image) => {
107
- let imageElement = document.createElement("img");
108
- imageElement.src = image.file.url;
109
- imagesDiv.appendChild(imageElement);
110
- });
111
- this.onImageClick(imagesDiv, index);
112
- }
113
- onImageClick(element, index) {
114
- if (!this.viewMode) {
115
- this.forceDisableClick = true;
116
- }
117
- const ngtDropzoneComponent = this;
118
- if (index !== null && index !== undefined) {
119
- this.imageViewerOptions = { ...this.imageViewerOptions, ...{ initialViewIndex: index } };
120
- }
121
- const viewer = new Viewer(element, {
122
- ...this.imageViewerOptions, ...{
123
- hidden() {
124
- ngtDropzoneComponent.forceDisableClick = false;
125
- viewer.destroy();
126
- }
127
- }
128
- });
129
- viewer.show();
130
- }
131
- onFileClick(url, name, size) {
132
- this.forceDisableClick = true;
133
- this.showNgtDropzoneFileViewer = true;
134
- this.ngtDropzoneFileViewer.url = url;
135
- this.ngtDropzoneFileViewer.fileName = name;
136
- this.ngtDropzoneFileViewer.fileSize = size;
137
- this.ngtDropzoneFileViewer.init();
138
- this.subscriptions.push(this.ngtDropzoneFileViewer.onClose.subscribe(() => {
139
- this.showNgtDropzoneFileViewer = false;
140
- this.forceDisableClick = false;
141
- }));
142
- }
143
- async onSelect(event) {
144
- if (event.rejectedFiles.length) {
145
- for (const rejectedFile of event.rejectedFiles) {
146
- if (rejectedFile.reason == 'size') {
147
- this.onFileSelectError.emit(NgtDropzoneErrorType.SIZE);
148
- break;
149
- }
150
- else if (rejectedFile.reason == 'no_multiple') {
151
- this.onFileSelectError.emit(NgtDropzoneErrorType.NO_MULTIPLE);
152
- break;
153
- }
154
- else if (rejectedFile.reason == 'type') {
155
- this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
156
- break;
157
- }
158
- else {
159
- this.onFileSelectError.emit(NgtDropzoneErrorType.DEFAULT);
160
- break;
161
- }
162
- }
163
- }
164
- if (this.itemsLimit) {
165
- if (this.itemsLimit == 1 && event.addedFiles
166
- && event.addedFiles.length == this.itemsLimit && this.uploadedResources.length == this.itemsLimit) {
167
- this.uploadedResources = [];
168
- }
169
- if (event.addedFiles
170
- && event.addedFiles.length + this.uploadedResources.length <= this.itemsLimit) {
171
- this.onFileSelected.emit(event);
172
- this.uploadFiles(event.addedFiles);
173
- }
174
- else {
175
- this.onFileSelectError.emit(NgtDropzoneErrorType.ITEMS_LIMIT);
176
- }
177
- }
178
- else {
179
- this.onFileSelected.emit(event);
180
- this.uploadFiles(event.addedFiles);
181
- }
182
- }
183
- async uploadFiles(files) {
184
- if (files && files.length) {
185
- const temporaryFiles = [];
186
- const temporaryAttachments = [];
187
- const observables = [];
188
- const unacceptedFiles = [];
189
- this.loading = true;
190
- this.onFileUploadInit.emit();
191
- files.forEach(file => {
192
- if (file.type.includes(this.unacceptedFiles)) {
193
- return unacceptedFiles.push(file);
194
- }
195
- observables.push(this.ngtAttachmentHttpService.upload(this.remoteResource, file).pipe(map((response) => {
196
- if (response && response.data) {
197
- if (response.data.attributes && response.data.attributes.data) {
198
- file['url'] = response.data.attributes.data.url;
199
- }
200
- temporaryFiles.push({
201
- id: response.data.id,
202
- size: file.size,
203
- file: file
204
- });
205
- response.data['loaded'] = true;
206
- temporaryAttachments.push(response.data);
207
- }
208
- })));
209
- });
210
- if (!observables.length && unacceptedFiles.length) {
211
- this.loading = false;
212
- return this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
213
- }
214
- this.subscriptions.push(forkJoin(observables).subscribe((response) => {
215
- this.uploadedResources.push(...temporaryFiles);
216
- if (this.itemsLimit == 1) {
217
- this.onNativeChange([...temporaryAttachments]);
218
- }
219
- else {
220
- this.onNativeChange([...temporaryAttachments, ...this.nativeValue]);
221
- }
222
- this.onFileUploaded.emit();
223
- this.loading = false;
224
- if (unacceptedFiles.length) {
225
- this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
226
- }
227
- }, (error) => {
228
- this.onFileUploadFail.emit(error);
229
- this.loading = false;
230
- }));
231
- }
232
- }
233
- async loadFilePreview(attachments) {
234
- if (attachments && attachments.length && attachments[0]) {
235
- let temporaryResource = [];
236
- let observables = [];
237
- attachments.forEach(attachment => {
238
- if (!(attachment instanceof File) && !attachment.loaded) {
239
- this.loading = true;
240
- attachment['loaded'] = true;
241
- observables.push(this.ngtAttachmentHttpService.thumbnail(attachment).pipe(map((response) => {
242
- temporaryResource.push({
243
- id: response.data.getApiId(),
244
- file: response.data.getAttribute('file')
245
- });
246
- })));
247
- }
248
- });
249
- this.subscriptions.push(forkJoin(observables).subscribe((response) => {
250
- this.uploadedResources.push(...temporaryResource);
251
- this.onNativeChange(attachments);
252
- this.onFilePreviewLoaded.emit();
253
- this.loading = false;
254
- }, (error) => {
255
- this.loading = false;
256
- }));
257
- }
258
- }
259
- onRemove(resource) {
260
- this.uploadedResources.splice(this.uploadedResources.indexOf(resource), 1);
261
- this.nativeValue = this.nativeValue.filter(element => element.id != resource.id);
262
- this.onNativeChange(this.nativeValue);
263
- this.onFileRemoved.emit(resource);
264
- }
265
- isImage(resource) {
266
- return this.previewType == 'IMAGE'
267
- || (resource.file && resource.file.type
268
- && resource.file.type.includes('image')
269
- && !resource.file.type.includes('dwg'));
270
- }
271
- isVideo(resource) {
272
- return this.previewType == 'VIDEO' || (resource.file && resource.file.type && resource.file.type.includes('video'));
273
- }
274
- isAudio(resource) {
275
- return (resource.file && resource.file.type && resource.file.type.includes('audio'));
276
- }
277
- isFile(resource) {
278
- return !this.isImage(resource) && !this.isAudio(resource) && !this.isVideo(resource);
279
- }
280
- getFormattedFileSize(resource) {
281
- if (resource) {
282
- let size = resource.size || resource.fileSize;
283
- if (!size) {
284
- if (resource.file && resource.file.size) {
285
- size = resource.file.size;
286
- }
287
- else {
288
- size = 0;
289
- }
290
- }
291
- if (parseFloat(size) > 1000000) {
292
- return (parseFloat(size) / 1000000).toFixed(2) + ' Mb';
293
- }
294
- return Math.round(parseFloat(size) / 1000) + ' Kb';
295
- }
296
- }
297
- onNativeChange(value) {
298
- if (value === undefined) {
299
- this.value = [];
300
- this.nativeValue = [];
301
- }
302
- else {
303
- this.nativeValue = value;
304
- if (JSON.stringify(this.value) != JSON.stringify(this.nativeValue)) {
305
- this.value = this.nativeValue;
306
- }
307
- }
308
- }
309
- change(value) {
310
- if (value && !this.viewMode) {
311
- this.onNativeChange(Array.isArray(value) ? value : [value]);
312
- if (this.componentReady) {
313
- this.loadFilePreview(Array.isArray(value) ? value : [value]);
314
- }
315
- }
316
- }
317
- downloadFile(attachment) {
318
- this.ngtAttachmentHttpService.download(attachment).subscribe(() => { });
319
- }
320
- reset() {
321
- this.uploadedResources = [];
322
- this.value = [];
323
- this.nativeValue = [];
324
- this.initComponent();
325
- }
326
- openFileSelector() {
327
- document.getElementById(this.ngxElementId).click();
328
- }
329
- initComponent() {
330
- if (this.viewMode) {
331
- this.previewType = NgtDropzonePreviewType.DEFAULT;
332
- return;
333
- }
334
- if (this.formContainer && this.formContainer.control
335
- && (this.formControl = this.formContainer.control.get(this.name))) {
336
- this.resetFilesLoad();
337
- this.loadFilePreview(Array.isArray(this.value) ? this.value : [this.value]);
338
- this.updateValidations();
339
- if (this.value) {
340
- this.formControl.markAsDirty();
341
- }
342
- else {
343
- this.formControl.markAsPristine();
344
- }
345
- }
346
- }
347
- resetFilesLoad() {
348
- if (Array.isArray(this.value)) {
349
- this.value.forEach(element => {
350
- if (element) {
351
- element['loaded'] = false;
352
- }
353
- });
354
- }
355
- }
356
- updateValidations() {
357
- if (!this.formControl) {
358
- return;
359
- }
360
- let syncValidators = [];
361
- if (this.isRequired) {
362
- syncValidators.push(Validators.required);
363
- }
364
- syncValidators.push();
365
- setTimeout(() => {
366
- this.formControl.setValidators(syncValidators);
367
- this.formControl.updateValueAndValidity();
368
- });
369
- }
370
- destroySubscriptions() {
371
- this.subscriptions.forEach(subscription => subscription.unsubscribe());
372
- this.subscriptions = [];
373
- }
374
- }
375
- NgtDropzoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgtDropzoneComponent, deps: [{ token: i1.ControlContainer, host: true, optional: true }, { token: i2.NgtAttachmentHttpService, optional: true, skipSelf: true }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
376
- NgtDropzoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: NgtDropzoneComponent, selector: "ngt-dropzone", inputs: { label: "label", placeholder: "placeholder", helpTextColor: "helpTextColor", helpText: "helpText", helpTitle: "helpTitle", resources: "resources", multipleSelection: "multipleSelection", itemsLimit: "itemsLimit", showFileName: "showFileName", disableClick: "disableClick", disabled: "disabled", viewMode: "viewMode", removable: "removable", canDownloadFile: "canDownloadFile", verticalExpandable: "verticalExpandable", acceptedFiles: "acceptedFiles", unacceptedFiles: "unacceptedFiles", maxFileSize: "maxFileSize", previewType: "previewType", isRequired: "isRequired", name: "name", remoteResource: "remoteResource" }, outputs: { onFileSelected: "onFileSelected", onFileSelectError: "onFileSelectError", onFileUploadFail: "onFileUploadFail", onFileRemoved: "onFileRemoved", onFileUploadInit: "onFileUploadInit", onFileUploaded: "onFileUploaded", onFilePreviewLoaded: "onFilePreviewLoaded" }, providers: [
377
- NgtMakeProvider(NgtDropzoneComponent),
378
- ], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "ngxDropzone", first: true, predicate: NgxDropzoneComponent, descendants: true, static: true }, { propertyName: "ngtDropzoneFileViewer", first: true, predicate: NgtDropzoneFileViewerComponent, descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col h-full w-full\" #container>\n <label *ngIf=\"label\" class=\"flex mb-2 text-sm\">\n {{ label }}:\n\n <span class=\"text-red-500 font-bold text-md ml-1\" *ngIf=\"isRequired\">*</span>\n\n <ngt-helper *ngIf=\"helpText\" [helpTitle]=\"helpTitle\" [iconColor]=\"helpTextColor\" class=\"ml-1\">\n {{ helpText }}\n </ngt-helper>\n </label>\n\n <div *ngIf=\"!viewMode\" class=\"h-full w-full relative\">\n <div *ngIf=\"loading\" class=\"flex absolute justify-center items-center w-full h-full cursor-wait z-10\">\n <div class=\"div-loader\"></div>\n </div>\n\n <ngx-dropzone [id]=\"ngxElementId\" [multiple]='multipleSelection' [maxFileSize]='maxFileSize'\n (change)='onSelect($event)' [class.single-attachment]='itemsLimit == 1' [accept]='acceptedFiles'\n [disabled]='disabled || loading' [expandable]='verticalExpandable'\n [disableClick]='disableClick || forceDisableClick' [ngStyle]=\"{ 'height': dropzoneHeight }\" #ngxDropzone>\n <ng-container *ngIf=\"!loading\">\n <ngx-dropzone-label *ngIf=\"!uploadedResources?.length\" class=\"px-2\">\n {{ placeholder }}\n </ngx-dropzone-label>\n\n <ng-container *ngFor=\"let resource of uploadedResources; let index = index\">\n <div class=\"flex flex-col w-48 mx-4\"\n title=\"{{ resource?.file?.name || '' }} ({{ getFormattedFileSize(resource) }})\">\n <custom-dropzone-preview *ngIf=\"previewType == 'DEFAULT' && isFile(resource)\"\n [file]='resource.file' [removable]=\"removable\" (removed)=\"onRemove(resource)\"\n (click)=\"onFileClick(resource.file.url, resource.file.name, resource.file.size)\"\n ngProjectAs=\"ngx-dropzone-preview\">\n </custom-dropzone-preview>\n\n <div *ngIf=\"isImage(resource)\" class=\"cursor-pointer\" (click)=\"imagePreview(index)\" #gallery>\n <ngx-dropzone-image-preview class=\"image-preview-default-class\" [file]=\"resource.file\"\n [removable]=\"removable\" (removed)=\"onRemove(resource)\">\n </ngx-dropzone-image-preview>\n </div>\n\n <ngx-dropzone-video-preview *ngIf=\"isVideo(resource) || isAudio(resource)\"\n [file]=\"resource.file\" [removable]=\"removable\" (removed)=\"onRemove(resource)\">\n </ngx-dropzone-video-preview>\n\n <p *ngIf=\"showFileName\"\n class=\"w-full truncate text-gray-500 text-center text-sm font-mono mt-2\">\n {{ resource?.file?.name || '' }}\n </p>\n </div>\n </ng-container>\n </ng-container>\n </ngx-dropzone>\n </div>\n\n <ngt-dropzone-view *ngIf=\"viewMode\" class=\"h-full w-full\" [resources]=\"resources\" [loading]=\"loading\"\n [placeholder]=\"placeholder\" [dropzoneHeight]=\"dropzoneHeight\"\n (onFileClick)=\"onFileClick($event.previewUrl, $event.name, $event.fileSize)\"\n (onImageClick)=\"onImageClick($event.div, $event.index)\">\n </ngt-dropzone-view>\n\n <ngt-dropzone-file-viewer [hidden]=\"!showNgtDropzoneFileViewer\" (onClose)=\"forceDisableClick = false\"\n [canDownloadFile]=\"canDownloadFile\" [disableContent]=\"canDownloadFile ? 'none' : 'popout'\">\n </ngt-dropzone-file-viewer>\n\n <input *ngIf='componentReady' type=\"hidden\" [ngModel]=\"value\" [name]=\"name\" [value]=\"value\">\n <ngt-validation [control]=\"formControl\" [container]=\"formContainer\"></ngt-validation>\n</div>", styles: [".single-attachment{border:none!important;margin:unset!important;overflow:hidden!important;display:flex!important;justify-content:center!important}.image-preview-default-class{margin:unset!important}custom-dropzone-preview{height:100%!important;min-height:unset!important;margin:unset!important}.div-loader{width:4rem;height:4rem;border:3px solid #a0aec038;border-top-color:#a0aec0;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.NgtValidationComponent, selector: "ngt-validation", inputs: ["control", "container", "minValue", "minLength"] }, { kind: "component", type: i5.NgxDropzoneComponent, selector: "ngx-dropzone, [ngx-dropzone]", inputs: ["accept", "disabled", "multiple", "maxFileSize", "expandable", "disableClick", "id", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["change"] }, { kind: "directive", type: i5.ɵb, selector: "ngx-dropzone-label" }, { kind: "component", type: i5.NgxDropzoneImagePreviewComponent, selector: "ngx-dropzone-image-preview" }, { kind: "component", type: i5.NgxDropzoneVideoPreviewComponent, selector: "ngx-dropzone-video-preview" }, { kind: "component", type: i6.NgtHelperComponent, selector: "ngt-helper", inputs: ["helpTextColor", "helpText", "helpTitle", "icon", "iconSize", "iconColor", "iconTitle", "tooltipSize", "autoXReverse", "helperReverseYPosition"] }, { kind: "component", type: i7.NgtDropzoneFileViewerComponent, selector: "ngt-dropzone-file-viewer", inputs: ["url", "fileName", "fileSize", "disableContent", "canDownloadFile"], outputs: ["onClose"] }, { kind: "component", type: i8.NgtDropzoneViewComponent, selector: "ngt-dropzone-view", inputs: ["resources", "dropzoneHeight", "loading", "placeholder"], outputs: ["onImageClick", "onFileClick"] }, { kind: "component", type: i9.CustomDropzonePreviewComponent, selector: "custom-dropzone-preview" }], viewProviders: [
379
- { provide: ControlContainer, useExisting: NgForm }
380
- ], encapsulation: i0.ViewEncapsulation.None });
381
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgtDropzoneComponent, decorators: [{
382
- type: Component,
383
- args: [{ selector: 'ngt-dropzone', encapsulation: ViewEncapsulation.None, providers: [
384
- NgtMakeProvider(NgtDropzoneComponent),
385
- ], viewProviders: [
386
- { provide: ControlContainer, useExisting: NgForm }
387
- ], template: "<div class=\"flex flex-col h-full w-full\" #container>\n <label *ngIf=\"label\" class=\"flex mb-2 text-sm\">\n {{ label }}:\n\n <span class=\"text-red-500 font-bold text-md ml-1\" *ngIf=\"isRequired\">*</span>\n\n <ngt-helper *ngIf=\"helpText\" [helpTitle]=\"helpTitle\" [iconColor]=\"helpTextColor\" class=\"ml-1\">\n {{ helpText }}\n </ngt-helper>\n </label>\n\n <div *ngIf=\"!viewMode\" class=\"h-full w-full relative\">\n <div *ngIf=\"loading\" class=\"flex absolute justify-center items-center w-full h-full cursor-wait z-10\">\n <div class=\"div-loader\"></div>\n </div>\n\n <ngx-dropzone [id]=\"ngxElementId\" [multiple]='multipleSelection' [maxFileSize]='maxFileSize'\n (change)='onSelect($event)' [class.single-attachment]='itemsLimit == 1' [accept]='acceptedFiles'\n [disabled]='disabled || loading' [expandable]='verticalExpandable'\n [disableClick]='disableClick || forceDisableClick' [ngStyle]=\"{ 'height': dropzoneHeight }\" #ngxDropzone>\n <ng-container *ngIf=\"!loading\">\n <ngx-dropzone-label *ngIf=\"!uploadedResources?.length\" class=\"px-2\">\n {{ placeholder }}\n </ngx-dropzone-label>\n\n <ng-container *ngFor=\"let resource of uploadedResources; let index = index\">\n <div class=\"flex flex-col w-48 mx-4\"\n title=\"{{ resource?.file?.name || '' }} ({{ getFormattedFileSize(resource) }})\">\n <custom-dropzone-preview *ngIf=\"previewType == 'DEFAULT' && isFile(resource)\"\n [file]='resource.file' [removable]=\"removable\" (removed)=\"onRemove(resource)\"\n (click)=\"onFileClick(resource.file.url, resource.file.name, resource.file.size)\"\n ngProjectAs=\"ngx-dropzone-preview\">\n </custom-dropzone-preview>\n\n <div *ngIf=\"isImage(resource)\" class=\"cursor-pointer\" (click)=\"imagePreview(index)\" #gallery>\n <ngx-dropzone-image-preview class=\"image-preview-default-class\" [file]=\"resource.file\"\n [removable]=\"removable\" (removed)=\"onRemove(resource)\">\n </ngx-dropzone-image-preview>\n </div>\n\n <ngx-dropzone-video-preview *ngIf=\"isVideo(resource) || isAudio(resource)\"\n [file]=\"resource.file\" [removable]=\"removable\" (removed)=\"onRemove(resource)\">\n </ngx-dropzone-video-preview>\n\n <p *ngIf=\"showFileName\"\n class=\"w-full truncate text-gray-500 text-center text-sm font-mono mt-2\">\n {{ resource?.file?.name || '' }}\n </p>\n </div>\n </ng-container>\n </ng-container>\n </ngx-dropzone>\n </div>\n\n <ngt-dropzone-view *ngIf=\"viewMode\" class=\"h-full w-full\" [resources]=\"resources\" [loading]=\"loading\"\n [placeholder]=\"placeholder\" [dropzoneHeight]=\"dropzoneHeight\"\n (onFileClick)=\"onFileClick($event.previewUrl, $event.name, $event.fileSize)\"\n (onImageClick)=\"onImageClick($event.div, $event.index)\">\n </ngt-dropzone-view>\n\n <ngt-dropzone-file-viewer [hidden]=\"!showNgtDropzoneFileViewer\" (onClose)=\"forceDisableClick = false\"\n [canDownloadFile]=\"canDownloadFile\" [disableContent]=\"canDownloadFile ? 'none' : 'popout'\">\n </ngt-dropzone-file-viewer>\n\n <input *ngIf='componentReady' type=\"hidden\" [ngModel]=\"value\" [name]=\"name\" [value]=\"value\">\n <ngt-validation [control]=\"formControl\" [container]=\"formContainer\"></ngt-validation>\n</div>", styles: [".single-attachment{border:none!important;margin:unset!important;overflow:hidden!important;display:flex!important;justify-content:center!important}.image-preview-default-class{margin:unset!important}custom-dropzone-preview{height:100%!important;min-height:unset!important;margin:unset!important}.div-loader{width:4rem;height:4rem;border:3px solid #a0aec038;border-top-color:#a0aec0;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
388
- }], ctorParameters: function () { return [{ type: i1.ControlContainer, decorators: [{
389
- type: Optional
390
- }, {
391
- type: Host
392
- }] }, { type: i2.NgtAttachmentHttpService, decorators: [{
393
- type: Optional
394
- }, {
395
- type: SkipSelf
396
- }] }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { container: [{
397
- type: ViewChild,
398
- args: ['container']
399
- }], ngxDropzone: [{
400
- type: ViewChild,
401
- args: [NgxDropzoneComponent, { static: true }]
402
- }], ngtDropzoneFileViewer: [{
403
- type: ViewChild,
404
- args: [NgtDropzoneFileViewerComponent, { static: true }]
405
- }], label: [{
406
- type: Input
407
- }], placeholder: [{
408
- type: Input
409
- }], helpTextColor: [{
410
- type: Input
411
- }], helpText: [{
412
- type: Input
413
- }], helpTitle: [{
414
- type: Input
415
- }], resources: [{
416
- type: Input
417
- }], multipleSelection: [{
418
- type: Input
419
- }], itemsLimit: [{
420
- type: Input
421
- }], showFileName: [{
422
- type: Input
423
- }], disableClick: [{
424
- type: Input
425
- }], disabled: [{
426
- type: Input
427
- }], viewMode: [{
428
- type: Input
429
- }], removable: [{
430
- type: Input
431
- }], canDownloadFile: [{
432
- type: Input
433
- }], verticalExpandable: [{
434
- type: Input
435
- }], acceptedFiles: [{
436
- type: Input
437
- }], unacceptedFiles: [{
438
- type: Input
439
- }], maxFileSize: [{
440
- type: Input
441
- }], previewType: [{
442
- type: Input
443
- }], isRequired: [{
444
- type: Input
445
- }], name: [{
446
- type: Input
447
- }], remoteResource: [{
448
- type: Input
449
- }], onFileSelected: [{
450
- type: Output
451
- }], onFileSelectError: [{
452
- type: Output
453
- }], onFileUploadFail: [{
454
- type: Output
455
- }], onFileRemoved: [{
456
- type: Output
457
- }], onFileUploadInit: [{
458
- type: Output
459
- }], onFileUploaded: [{
460
- type: Output
461
- }], onFilePreviewLoaded: [{
462
- type: Output
463
- }] } });
464
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd0LWRyb3B6b25lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhaWx3aW5kL3NyYy9jb21wb25lbnRzL25ndC1kcm9wem9uZS9uZ3QtZHJvcHpvbmUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctdGFpbHdpbmQvc3JjL2NvbXBvbmVudHMvbmd0LWRyb3B6b25lL25ndC1kcm9wem9uZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0gsU0FBUyxFQUVULFlBQVksRUFDWixJQUFJLEVBRUosS0FBSyxFQUdMLFFBQVEsRUFDUixNQUFNLEVBRU4sUUFBUSxFQUNSLFNBQVMsRUFDVCxpQkFBaUIsR0FDcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQTBCLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxRQUFRLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLE1BQU0sTUFBTSxVQUFVLENBQUM7QUFFOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFMUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFDNUYsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sK0RBQStELENBQUM7QUFDL0csT0FBTyxFQUFFLG9CQUFvQixFQUFtQixzQkFBc0Is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LEVBQUU7Z0JBRzNDLEtBQUs7c0JBQXBCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLO2dCQUNVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBQ1UsU0FBUztzQkFBeEIsS0FBSztnQkFHVSxTQUFTO3NCQUF4QixLQUFLO2dCQUNVLGlCQUFpQjtzQkFBaEMsS0FBSztnQkFDVSxVQUFVO3NCQUF6QixLQUFLO2dCQUNVLFlBQVk7c0JBQTNCLEtBQUs7Z0JBQ1UsWUFBWTtzQkFBM0IsS0FBSztnQkFDVSxRQUFRO3NCQUF2QixLQUFLO2dCQUNVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBQ1UsU0FBUztzQkFBeEIsS0FBSztnQkFDVSxlQUFlO3NCQUE5QixLQUFLO2dCQUNVLGtCQUFrQjtzQkFBakMsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLO2dCQUNVLGVBQWU7c0JBQTlCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxXQUFXO3NCQUExQixLQUFLO2dCQUNVLFVBQVU7c0JBQXpCLEtBQUs7Z0JBQ1UsSUFBSTtzQkFBbkIsS0FBSztnQkFDVSxjQUFjO3NCQUE3QixLQUFLO2dCQUVXLGNBQWM7c0JBQTlCLE1BQU07Z0JBQ1UsaUJBQWlCO3NCQUFqQyxNQUFNO2dCQUNVLGdCQUFnQjtzQkFBaEMsTUFBTTtnQkFDVSxhQUFhO3NCQUE3QixNQUFNO2dCQUNVLGdCQUFnQjtzQkFBaEMsTUFBTTtnQkFDVSxjQUFjO3NCQUE5QixNQUFNO2dCQUNVLG1CQUFtQjtzQkFBbkMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQWZ0ZXJDb250ZW50Q2hlY2tlZCxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdCxcbiAgICBJbmplY3RvcixcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LFxuICAgIE9wdGlvbmFsLFxuICAgIE91dHB1dCxcbiAgICBTaW1wbGVDaGFuZ2VzLFxuICAgIFNraXBTZWxmLFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sQ29udGFpbmVyLCBOZ0Zvcm0sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBOZ3hEcm9wem9uZUNoYW5nZUV2ZW50LCBOZ3hEcm9wem9uZUNvbXBvbmVudCB9IGZyb20gJ25neC1kcm9wem9uZSc7XG5pbXBvcnQgeyBmb3JrSm9pbiwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgVmlld2VyIGZyb20gJ3ZpZXdlcmpzJztcblxuaW1wb3J0IHsgTmd0QmFzZU5nTW9kZWwsIE5ndE1ha2VQcm92aWRlciB9IGZyb20gJy4uLy4uL2Jhc2Uvbmd0LWJhc2UtbmctbW9kZWwnO1xuaW1wb3J0IHsgZ2V0RW51bUZyb21TdHJpbmcgfSBmcm9tICcuLi8uLi9oZWxwZXJzL2VudW0vZW51bSc7XG5pbXBvcnQgeyB1dWlkIH0gZnJvbSAnLi4vLi4vaGVscGVycy91dWlkJztcbmltcG9ydCB7IE5ndEF0dGFjaG1lbnRIdHRwU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2h0dHAvbmd0LWF0dGFjaG1lbnQtaHR0cC5zZXJ2aWNlJztcbmltcG9ydCB7IE5ndFN0eWxpemFibGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbmd0LXN0eWxpemFibGUvbmd0LXN0eWxpemFibGUuc2VydmljZSc7XG5pbXBvcnQgeyBOZ3REcm9wem9uZUZpbGVWaWV3ZXJDb21wb25lbnQgfSBmcm9tICcuL25ndC1kcm9wem9uZS1maWxlLXZpZXdlci9uZ3QtZHJvcHpvbmUtZmlsZS12aWV3ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IE5ndERyb3B6b25lRXJyb3JUeXBlLCBOZ3REcm9wem9uZUZpbGUsIE5ndERyb3B6b25lUHJldmlld1R5cGUgfSBmcm9tICcuL25ndC1kcm9wem9uZS5tZXRhJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICduZ3QtZHJvcHpvbmUnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9uZ3QtZHJvcHpvbmUuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL25ndC1kcm9wem9uZS5jb21wb25lbnQuY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgTmd0TWFrZVByb3ZpZGVyKE5ndERyb3B6b25lQ29tcG9uZW50KSxcbiAgICBdLFxuICAgIHZpZXdQcm92aWRlcnM6IFtcbiAgICAgICAgeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogTmdGb3JtIH1cbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIE5ndERyb3B6b25lQ29tcG9uZW50IGV4dGVuZHMgTmd0QmFzZU5nTW9kZWwgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJDb250ZW50Q2hlY2tlZCB7XG4gICAgQFZpZXdDaGlsZCgnY29udGFpbmVyJykgcHVibGljIGNvbnRhaW5lcjogRWxlbWVudFJlZjtcbiAgICBAVmlld0NoaWxkKE5neERyb3B6b25lQ29tcG9uZW50LCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgbmd4RHJvcHpvbmU6IE5neERyb3B6b25lQ29tcG9uZW50O1xuICAgIEBWaWV3Q2hpbGQoTmd0RHJvcHpvbmVGaWxlVmlld2VyQ29tcG9uZW50LCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgbmd0RHJvcHpvbmVGaWxlVmlld2VyOiBOZ3REcm9wem9uZUZpbGVWaWV3ZXJDb21wb25lbnQ7XG5cbiAgICAvLyBWaXN1YWxcbiAgICBASW5wdXQoKSBwdWJsaWMgbGFiZWw6IHN0cmluZztcbiAgICBASW5wdXQoKSBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZztcbiAgICBASW5wdXQoKSBwdWJsaWMgaGVscFRleHRDb2xvcjogc3RyaW5nID0gJ3RleHQtZ3JlZW4tNTAwJztcbiAgICBASW5wdXQoKSBwdWJsaWMgaGVscFRleHQ6IHN0cmluZztcbiAgICBASW5wdXQoKSBwdWJsaWMgaGVscFRpdGxlOiBzdHJpbmc7XG5cbiAgICAvLyBCZWhhdmlvclxuICAgIEBJbnB1dCgpIHB1YmxpYyByZXNvdXJjZXM6IEFycmF5PE5ndERyb3B6b25lRmlsZT4gPSBbXTtcbiAgICBASW5wdXQoKSBwdWJsaWMgbXVsdGlwbGVTZWxlY3Rpb246IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBwdWJsaWMgaXRlbXNMaW1pdDogbnVtYmVyO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzaG93RmlsZU5hbWU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBwdWJsaWMgZGlzYWJsZUNsaWNrOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgcHVibGljIGRpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgcHVibGljIHZpZXdNb2RlOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgcHVibGljIHJlbW92YWJsZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjYW5Eb3dubG9hZEZpbGU6IGJvb2xlYW4gPSB0cnVlO1xuICAgIEBJbnB1dCgpIHB1YmxpYyB2ZXJ0aWNhbEV4cGFuZGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBwdWJsaWMgYWNjZXB0ZWRGaWxlczogc3RyaW5nID0gJyonIC8qKiBNaW1lIHR5cGUgKi87XG4gICAgQElucHV0KCkgcHVibGljIHVuYWNjZXB0ZWRGaWxlczogc3RyaW5nOyAvKiogTWltZSB0eXBlICovO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBtYXhGaWxlU2l6ZTogbnVtYmVyOyAvKiogQnl0ZXMgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgcHJldmlld1R5cGU6IE5ndERyb3B6b25lUHJldmlld1R5cGUgPSBOZ3REcm9wem9uZVByZXZpZXdUeXBlLkRFRkFVTFQ7XG4gICAgQElucHV0KCkgcHVibGljIGlzUmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBwdWJsaWMgbmFtZTogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHB1YmxpYyByZW1vdGVSZXNvdXJjZTogYW55O1xuXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVTZWxlY3RlZDogRXZlbnRFbWl0dGVyPE5neERyb3B6b25lQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlU2VsZWN0RXJyb3I6IEV2ZW50RW1pdHRlcjxOZ3REcm9wem9uZUVycm9yVHlwZT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVVcGxvYWRGYWlsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVJlbW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVVcGxvYWRJbml0ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlVXBsb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVQcmV2aWV3TG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgcHVibGljIGRyb3B6b25lSGVpZ2h0OiBzdHJpbmcgPSAnMTgwcHgnO1xuICAgIHB1YmxpYyB1cGxvYWRlZFJlc291cmNlcyA9IFtdO1xuICAgIHB1YmxpYyBmb3JjZURpc2FibGVDbGljazogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHB1YmxpYyBuYXRpdmVWYWx1ZSA9IFtdO1xuICAgIHB1YmxpYyBzaG93Tmd0RHJvcHpvbmVGaWxlVmlld2VyOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIGNvbXBvbmVudFJlYWR5ID0gZmFsc2U7XG4gICAgcHVibGljIGxvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgbmd0RHJvcHpvbmVMb2FkZXJTdHlsZTogTmd0U3R5bGl6YWJsZVNlcnZpY2U7XG4gICAgcHVibGljIG5neEVsZW1lbnRJZDogc3RyaW5nID0gdXVpZCgpO1xuICAgIHB1YmxpYyBpbWFnZVZpZXdlck9wdGlvbnM6IGFueSA9IHtcbiAgICAgICAgbmF2YmFyOiB0cnVlLFxuICAgICAgICB0b29sYmFyOiB7XG4gICAgICAgICAgICB6b29tSW46IHRydWUsXG4gICAgICAgICAgICB6b29tT3V0OiB0cnVlLFxuICAgICAgICAgICAgcmVzZXQ6IHRydWUsXG4gICAgICAgICAgICByb3RhdGVMZWZ0OiB0cnVlLFxuICAgICAgICAgICAgcm90YXRlUmlnaHQ6IHRydWUsXG4gICAgICAgICAgICBwcmV2OiB0cnVlLFxuICAgICAgICAgICAgbmV4dDogdHJ1ZSxcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIHN1YnNjcmlwdGlvbnM6IEFycmF5PFN1YnNjcmlwdGlvbj4gPSBbXTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgICAgQE9wdGlvbmFsKCkgQEhvc3QoKVxuICAgICAgICBwdWJsaWMgZm9ybUNvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lcixcbiAgICAgICAgQE9wdGlvbmFsKCkgQFNraXBTZWxmKClcbiAgICAgICAgcHJpdmF0ZSBuZ3RBdHRhY2htZW50SHR0cFNlcnZpY2U6IE5ndEF0dGFjaG1lbnRIdHRwU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVMb2FkZXJTdHlsZSA9IG5ldyBOZ3RTdHlsaXphYmxlU2VydmljZSgpO1xuXG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVMb2FkZXJTdHlsZS5sb2FkKHRoaXMuaW5qZWN0b3IsICdOZ3REcm9wem9uZUxvYWRlcicsIHtcbiAgICAgICAgICAgIGg6ICdoLTgnLFxuICAgICAgICAgICAgY29sb3I6IHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAndGV4dC1ncmF5LTYwMCdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICAgICAgaWYgKGNoYW5nZXMucHJldmlld1R5cGUpIHtcbiAgICAgICAgICAgIHRoaXMucHJldmlld1R5cGUgPSBnZXRFbnVtRnJvbVN0cmluZyhjaGFuZ2VzLnByZXZpZXdUeXBlLmN1cnJlbnRWYWx1ZSwgTmd0RHJvcHpvbmVQcmV2aWV3VHlwZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRDaGVja2VkKCkge1xuICAgICAgICBpZiAodGhpcy5jb250YWluZXIgJiYgdGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5kcm9wem9uZUhlaWdodCA9IGAke3RoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHR9cHhgO1xuXG4gICAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudFJlYWR5ID0gdHJ1ZTtcblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0Q29tcG9uZW50KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgNTAwKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveVN1YnNjcmlwdGlvbnMoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW1hZ2VQcmV2aWV3KGluZGV4KSB7XG4gICAgICAgIGNvbnN0IGltYWdlcyA9IHRoaXMudXBsb2FkZWRSZXNvdXJjZXMuZmlsdGVyKChyZXNvdXJjZSkgPT4gdGhpcy5pc0ltYWdlKHJlc291cmNlKSk7XG4gICAgICAgIGNvbnN0IGltYWdlc0RpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cbiAgICAgICAgaW1hZ2VzLmZvckVhY2goKGltYWdlKSA9PiB7XG4gICAgICAgICAgICBsZXQgaW1hZ2VFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcblxuICAgICAgICAgICAgaW1hZ2VFbGVtZW50LnNyYyA9IGltYWdlLmZpbGUudXJsO1xuXG4gICAgICAgICAgICBpbWFnZXNEaXYuYXBwZW5kQ2hpbGQoaW1hZ2VFbGVtZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5vbkltYWdlQ2xpY2soaW1hZ2VzRGl2LCBpbmRleCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uSW1hZ2VDbGljayhlbGVtZW50LCBpbmRleD8pIHtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmZvcmNlRGlzYWJsZUNsaWNrID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ndERyb3B6b25lQ29tcG9uZW50ID0gdGhpcztcblxuICAgICAgICBpZiAoaW5kZXggIT09IG51bGwgJiYgaW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5pbWFnZVZpZXdlck9wdGlvbnMgPSB7IC4uLnRoaXMuaW1hZ2VWaWV3ZXJPcHRpb25zLCAuLi57IGluaXRpYWxWaWV3SW5kZXg6IGluZGV4IH0gfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZXdlciA9IG5ldyBWaWV3ZXIoZWxlbWVudCwge1xuICAgICAgICAgICAgLi4udGhpcy5pbWFnZVZpZXdlck9wdGlvbnMsIC4uLntcbiAgICAgICAgICAgICAgICBoaWRkZW4oKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ndERyb3B6b25lQ29tcG9uZW50LmZvcmNlRGlzYWJsZUNsaWNrID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHZpZXdlci5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB2aWV3ZXIuc2hvdygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkZpbGVDbGljayh1cmw6IHN0cmluZywgbmFtZTogc3RyaW5nLCBzaXplOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5mb3JjZURpc2FibGVDbGljayA9IHRydWU7XG4gICAgICAgIHRoaXMuc2hvd05ndERyb3B6b25lRmlsZVZpZXdlciA9IHRydWU7XG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVGaWxlVmlld2VyLnVybCA9IHVybDtcbiAgICAgICAgdGhpcy5uZ3REcm9wem9uZUZpbGVWaWV3ZXIuZmlsZU5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci5maWxlU2l6ZSA9IHNpemU7XG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVGaWxlVmlld2VyLmluaXQoKTtcblxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci5vbkNsb3NlLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNob3dOZ3REcm9wem9uZUZpbGVWaWV3ZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZm9yY2VEaXNhYmxlQ2xpY2sgPSBmYWxzZTtcbiAgICAgICAgfSkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBvblNlbGVjdChldmVudDogTmd4RHJvcHpvbmVDaGFuZ2VFdmVudCkge1xuICAgICAgICBpZiAoZXZlbnQucmVqZWN0ZWRGaWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVqZWN0ZWRGaWxlIG9mIDxhbnk+ZXZlbnQucmVqZWN0ZWRGaWxlcykge1xuICAgICAgICAgICAgICAgIGlmIChyZWplY3RlZEZpbGUucmVhc29uID09ICdzaXplJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdEVycm9yLmVtaXQoTmd0RHJvcHpvbmVFcnJvclR5cGUuU0laRSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWRGaWxlLnJlYXNvbiA9PSAnbm9fbXVsdGlwbGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5OT19NVUxUSVBMRSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWRGaWxlLnJlYXNvbiA9PSAndHlwZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLlRZUEUpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdEVycm9yLmVtaXQoTmd0RHJvcHpvbmVFcnJvclR5cGUuREVGQVVMVCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLml0ZW1zTGltaXQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLml0ZW1zTGltaXQgPT0gMSAmJiBldmVudC5hZGRlZEZpbGVzXG4gICAgICAgICAgICAgICAgJiYgZXZlbnQuYWRkZWRGaWxlcy5sZW5ndGggPT0gdGhpcy5pdGVtc0xpbWl0ICYmIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMubGVuZ3RoID09IHRoaXMuaXRlbXNMaW1pdCkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGV2ZW50LmFkZGVkRmlsZXNcbiAgICAgICAgICAgICAgICAmJiBldmVudC5hZGRlZEZpbGVzLmxlbmd0aCArIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMubGVuZ3RoIDw9IHRoaXMuaXRlbXNMaW1pdCkge1xuICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0ZWQuZW1pdChldmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy51cGxvYWRGaWxlcyhldmVudC5hZGRlZEZpbGVzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLklURU1TX0xJTUlUKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0ZWQuZW1pdChldmVudCk7XG4gICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKGV2ZW50LmFkZGVkRmlsZXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHVwbG9hZEZpbGVzKGZpbGVzOiBBcnJheTxGaWxlPikge1xuICAgICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCB0ZW1wb3JhcnlGaWxlcyA9IFtdO1xuICAgICAgICAgICAgY29uc3QgdGVtcG9yYXJ5QXR0YWNobWVudHMgPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IG9ic2VydmFibGVzID0gW107XG4gICAgICAgICAgICBjb25zdCB1bmFjY2VwdGVkRmlsZXMgPSBbXTtcblxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMub25GaWxlVXBsb2FkSW5pdC5lbWl0KCk7XG5cbiAgICAgICAgICAgIGZpbGVzLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGUudHlwZS5pbmNsdWRlcyh0aGlzLnVuYWNjZXB0ZWRGaWxlcykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuYWNjZXB0ZWRGaWxlcy5wdXNoKGZpbGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9ic2VydmFibGVzLnB1c2godGhpcy5uZ3RBdHRhY2htZW50SHR0cFNlcnZpY2UudXBsb2FkKHRoaXMucmVtb3RlUmVzb3VyY2UsIGZpbGUpLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIG1hcCgocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuZGF0YS5hdHRyaWJ1dGVzICYmIHJlc3BvbnNlLmRhdGEuYXR0cmlidXRlcy5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVbJ3VybCddID0gcmVzcG9uc2UuZGF0YS5hdHRyaWJ1dGVzLmRhdGEudXJsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBvcmFyeUZpbGVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZDogcmVzcG9uc2UuZGF0YS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZTogZmlsZS5zaXplLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlOiBmaWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZGF0YVsnbG9hZGVkJ10gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBvcmFyeUF0dGFjaG1lbnRzLnB1c2gocmVzcG9uc2UuZGF0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKCFvYnNlcnZhYmxlcy5sZW5ndGggJiYgdW5hY2NlcHRlZEZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5UWVBFKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgZm9ya0pvaW4ob2JzZXJ2YWJsZXMpLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzLnB1c2goLi4udGVtcG9yYXJ5RmlsZXMpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pdGVtc0xpbWl0ID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKFsuLi50ZW1wb3JhcnlBdHRhY2htZW50c10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKFsuLi50ZW1wb3JhcnlBdHRhY2htZW50cywgLi4udGhpcy5uYXRpdmVWYWx1ZV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVVwbG9hZGVkLmVtaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodW5hY2NlcHRlZEZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5UWVBFKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVVwbG9hZEZhaWwuZW1pdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgbG9hZEZpbGVQcmV2aWV3KGF0dGFjaG1lbnRzOiBhbnkpIHtcbiAgICAgICAgaWYgKGF0dGFjaG1lbnRzICYmIGF0dGFjaG1lbnRzLmxlbmd0aCAmJiBhdHRhY2htZW50c1swXSkge1xuICAgICAgICAgICAgbGV0IHRlbXBvcmFyeVJlc291cmNlID0gW107XG4gICAgICAgICAgICBsZXQgb2JzZXJ2YWJsZXMgPSBbXTtcblxuICAgICAgICAgICAgYXR0YWNobWVudHMuZm9yRWFjaChhdHRhY2htZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIShhdHRhY2htZW50IGluc3RhbmNlb2YgRmlsZSkgJiYgIWF0dGFjaG1lbnQubG9hZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRbJ2xvYWRlZCddID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2YWJsZXMucHVzaCh0aGlzLm5ndEF0dGFjaG1lbnRIdHRwU2VydmljZS50aHVtYm5haWwoYXR0YWNobWVudCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBvcmFyeVJlc291cmNlLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZDogcmVzcG9uc2UuZGF0YS5nZXRBcGlJZCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlOiByZXNwb25zZS5kYXRhLmdldEF0dHJpYnV0ZSgnZmlsZScpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgZm9ya0pvaW4ob2JzZXJ2YWJsZXMpLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzLnB1c2goLi4udGVtcG9yYXJ5UmVzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZShhdHRhY2htZW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVByZXZpZXdMb2FkZWQuZW1pdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uUmVtb3ZlKHJlc291cmNlOiBhbnkpIHtcbiAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcy5zcGxpY2UodGhpcy51cGxvYWRlZFJlc291cmNlcy5pbmRleE9mKHJlc291cmNlKSwgMSk7XG4gICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSB0aGlzLm5hdGl2ZVZhbHVlLmZpbHRlcihlbGVtZW50ID0+IGVsZW1lbnQuaWQgIT0gcmVzb3VyY2UuaWQpO1xuICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKHRoaXMubmF0aXZlVmFsdWUpO1xuICAgICAgICB0aGlzLm9uRmlsZVJlbW92ZWQuZW1pdChyZXNvdXJjZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGlzSW1hZ2UocmVzb3VyY2U6IGFueSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcmV2aWV3VHlwZSA9PSAnSU1BR0UnXG4gICAgICAgICAgICB8fCAoXG4gICAgICAgICAgICAgICAgcmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnR5cGVcbiAgICAgICAgICAgICAgICAmJiByZXNvdXJjZS5maWxlLnR5cGUuaW5jbHVkZXMoJ2ltYWdlJylcbiAgICAgICAgICAgICAgICAmJiAhcmVzb3VyY2UuZmlsZS50eXBlLmluY2x1ZGVzKCdkd2cnKVxuICAgICAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNWaWRlbyhyZXNvdXJjZTogYW55KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByZXZpZXdUeXBlID09ICdWSURFTycgfHwgKHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlICYmIHJlc291cmNlLmZpbGUudHlwZS5pbmNsdWRlcygndmlkZW8nKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGlzQXVkaW8ocmVzb3VyY2U6IGFueSkge1xuICAgICAgICByZXR1cm4gKHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlICYmIHJlc291cmNlLmZpbGUudHlwZS5pbmNsdWRlcygnYXVkaW8nKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGlzRmlsZShyZXNvdXJjZTogYW55KSB7XG4gICAgICAgIHJldHVybiAhdGhpcy5pc0ltYWdlKHJlc291cmNlKSAmJiAhdGhpcy5pc0F1ZGlvKHJlc291cmNlKSAmJiAhdGhpcy5pc1ZpZGVvKHJlc291cmNlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0Rm9ybWF0dGVkRmlsZVNpemUocmVzb3VyY2U6IGFueSkge1xuICAgICAgICBpZiAocmVzb3VyY2UpIHtcbiAgICAgICAgICAgIGxldCBzaXplID0gcmVzb3VyY2Uuc2l6ZSB8fCByZXNvdXJjZS5maWxlU2l6ZTtcblxuICAgICAgICAgICAgaWYgKCFzaXplKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS5zaXplKSB7XG4gICAgICAgICAgICAgICAgICAgIHNpemUgPSByZXNvdXJjZS5maWxlLnNpemU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocGFyc2VGbG9hdChzaXplKSA+IDEwMDAwMDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKHBhcnNlRmxvYXQoc2l6ZSkgLyAxMDAwMDAwKS50b0ZpeGVkKDIpICsgJyBNYic7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHBhcnNlRmxvYXQoc2l6ZSkgLyAxMDAwKSArICcgS2InO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uTmF0aXZlQ2hhbmdlKHZhbHVlOiBhbnkpIHtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbXTtcbiAgICAgICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KHRoaXMudmFsdWUpICE9IEpTT04uc3RyaW5naWZ5KHRoaXMubmF0aXZlVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubmF0aXZlVmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2hhbmdlKHZhbHVlOiBhbnkpIHtcbiAgICAgICAgaWYgKHZhbHVlICYmICF0aGlzLnZpZXdNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50UmVhZHkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRGaWxlUHJldmlldyhBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgZG93bmxvYWRGaWxlKGF0dGFjaG1lbnQ6IGFueSkge1xuICAgICAgICB0aGlzLm5ndEF0dGFjaG1lbnRIdHRwU2VydmljZS5kb3dubG9hZChhdHRhY2htZW50KS5zdWJzY3JpYmUoKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVzZXQoKSB7XG4gICAgICAgIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMgPSBbXTtcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xuICAgICAgICB0aGlzLm5hdGl2ZVZhbHVlID0gW107XG4gICAgICAgIHRoaXMuaW5pdENvbXBvbmVudCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvcGVuRmlsZVNlbGVjdG9yKCkge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm5neEVsZW1lbnRJZCkuY2xpY2soKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRDb21wb25lbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLnZpZXdNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXdUeXBlID0gTmd0RHJvcHpvbmVQcmV2aWV3VHlwZS5ERUZBVUxUO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5mb3JtQ29udGFpbmVyICYmIHRoaXMuZm9ybUNvbnRhaW5lci5jb250cm9sXG4gICAgICAgICAgICAmJiAodGhpcy5mb3JtQ29udHJvbCA9IHRoaXMuZm9ybUNvbnRhaW5lci5jb250cm9sLmdldCh0aGlzLm5hbWUpKSkge1xuICAgICAgICAgICAgdGhpcy5yZXNldEZpbGVzTG9hZCgpO1xuICAgICAgICAgICAgdGhpcy5sb2FkRmlsZVByZXZpZXcoQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlKSA/IHRoaXMudmFsdWUgOiBbdGhpcy52YWx1ZV0pO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVWYWxpZGF0aW9ucygpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy52YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JtQ29udHJvbC5tYXJrQXNQcmlzdGluZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNldEZpbGVzTG9hZCgpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy52YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50Wydsb2FkZWQnXSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVWYWxpZGF0aW9ucygpIHtcbiAgICAgICAgaWYgKCF0aGlzLmZvcm1Db250cm9sKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3luY1ZhbGlkYXRvcnMgPSBbXTtcblxuICAgICAgICBpZiAodGhpcy5pc1JlcXVpcmVkKSB7XG4gICAgICAgICAgICBzeW5jVmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3luY1ZhbGlkYXRvcnMucHVzaCgpO1xuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWxpZGF0b3JzKHN5bmNWYWxpZGF0b3JzKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybUNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc3Ryb3lTdWJzY3JpcHRpb25zKCkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWJzY3JpcHRpb24gPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSBbXTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBoLWZ1bGwgdy1mdWxsXCIgI2NvbnRhaW5lcj5cbiAgICA8bGFiZWwgKm5nSWY9XCJsYWJlbFwiIGNsYXNzPVwiZmxleCBtYi0yIHRleHQtc21cIj5cbiAgICAgICAge3sgbGFiZWwgfX06XG5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXJlZC01MDAgZm9udC1ib2xkIHRleHQtbWQgbWwtMVwiICpuZ0lmPVwiaXNSZXF1aXJlZFwiPio8L3NwYW4+XG5cbiAgICAgICAgPG5ndC1oZWxwZXIgKm5nSWY9XCJoZWxwVGV4dFwiIFtoZWxwVGl0bGVdPVwiaGVscFRpdGxlXCIgW2ljb25Db2xvcl09XCJoZWxwVGV4dENvbG9yXCIgY2xhc3M9XCJtbC0xXCI+XG4gICAgICAgICAgICB7eyBoZWxwVGV4dCB9fVxuICAgICAgICA8L25ndC1oZWxwZXI+XG4gICAgPC9sYWJlbD5cblxuICAgIDxkaXYgKm5nSWY9XCIhdmlld01vZGVcIiBjbGFzcz1cImgtZnVsbCB3LWZ1bGwgcmVsYXRpdmVcIj5cbiAgICAgICAgPGRpdiAqbmdJZj1cImxvYWRpbmdcIiBjbGFzcz1cImZsZXggYWJzb2x1dGUganVzdGlmeS1jZW50ZXIgaXRlbXMtY2VudGVyIHctZnVsbCBoLWZ1bGwgY3Vyc29yLXdhaXQgei0xMFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpdi1sb2FkZXJcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPG5neC1kcm9wem9uZSBbaWRdPVwibmd4RWxlbWVudElkXCIgW211bHRpcGxlXT0nbXVsdGlwbGVTZWxlY3Rpb24nIFttYXhGaWxlU2l6ZV09J21heEZpbGVTaXplJ1xuICAgICAgICAgICAgKGNoYW5nZSk9J29uU2VsZWN0KCRldmVudCknIFtjbGFzcy5zaW5nbGUtYXR0YWNobWVudF09J2l0ZW1zTGltaXQgPT0gMScgW2FjY2VwdF09J2FjY2VwdGVkRmlsZXMnXG4gICAgICAgICAgICBbZGlzYWJsZWRdPSdkaXNhYmxlZCB8fCBsb2FkaW5nJyBbZXhwYW5kYWJsZV09J3ZlcnRpY2FsRXhwYW5kYWJsZSdcbiAgICAgICAgICAgIFtkaXNhYmxlQ2xpY2tdPSdkaXNhYmxlQ2xpY2sgfHwgZm9yY2VEaXNhYmxlQ2xpY2snIFtuZ1N0eWxlXT1cInsgJ2hlaWdodCc6IGRyb3B6b25lSGVpZ2h0IH1cIiAjbmd4RHJvcHpvbmU+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICA8bmd4LWRyb3B6b25lLWxhYmVsICpuZ0lmPVwiIXVwbG9hZGVkUmVzb3VyY2VzPy5sZW5ndGhcIiBjbGFzcz1cInB4LTJcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgcGxhY2Vob2xkZXIgfX1cbiAgICAgICAgICAgICAgICA8L25neC1kcm9wem9uZS1sYWJlbD5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHJlc291cmNlIG9mIHVwbG9hZGVkUmVzb3VyY2VzOyBsZXQgaW5kZXggPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCB3LTQ4IG14LTRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJ7eyByZXNvdXJjZT8uZmlsZT8ubmFtZSB8fCAnJyB9fSAoe3sgZ2V0Rm9ybWF0dGVkRmlsZVNpemUocmVzb3VyY2UpIH19KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGN1c3RvbS1kcm9wem9uZS1wcmV2aWV3ICpuZ0lmPVwicHJldmlld1R5cGUgPT0gJ0RFRkFVTFQnICYmIGlzRmlsZShyZXNvdXJjZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWxlXT0ncmVzb3VyY2UuZmlsZScgW3JlbW92YWJsZV09XCJyZW1vdmFibGVcIiAocmVtb3ZlZCk9XCJvblJlbW92ZShyZXNvdXJjZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkZpbGVDbGljayhyZXNvdXJjZS5maWxlLnVybCwgcmVzb3VyY2UuZmlsZS5uYW1lLCByZXNvdXJjZS5maWxlLnNpemUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZ1Byb2plY3RBcz1cIm5neC1kcm9wem9uZS1wcmV2aWV3XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2N1c3RvbS1kcm9wem9uZS1wcmV2aWV3PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNJbWFnZShyZXNvdXJjZSlcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cImltYWdlUHJldmlldyhpbmRleClcIiAjZ2FsbGVyeT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmd4LWRyb3B6b25lLWltYWdlLXByZXZpZXcgY2xhc3M9XCJpbWFnZS1wcmV2aWV3LWRlZmF1bHQtY2xhc3NcIiBbZmlsZV09XCJyZXNvdXJjZS5maWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlbW92YWJsZV09XCJyZW1vdmFibGVcIiAocmVtb3ZlZCk9XCJvblJlbW92ZShyZXNvdXJjZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25neC1kcm9wem9uZS1pbWFnZS1wcmV2aWV3PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtZHJvcHpvbmUtdmlkZW8tcHJldmlldyAqbmdJZj1cImlzVmlkZW8ocmVzb3VyY2UpIHx8IGlzQXVkaW8ocmVzb3VyY2UpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsZV09XCJyZXNvdXJjZS5maWxlXCIgW3JlbW92YWJsZV09XCJyZW1vdmFibGVcIiAocmVtb3ZlZCk9XCJvblJlbW92ZShyZXNvdXJjZSlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmd4LWRyb3B6b25lLXZpZGVvLXByZXZpZXc+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwic2hvd0ZpbGVOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInctZnVsbCB0cnVuY2F0ZSB0ZXh0LWdyYXktNTAwIHRleHQtY2VudGVyIHRleHQtc20gZm9udC1tb25vIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByZXNvdXJjZT8uZmlsZT8ubmFtZSB8fCAnJyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25neC1kcm9wem9uZT5cbiAgICA8L2Rpdj5cblxuICAgIDxuZ3QtZHJvcHpvbmUtdmlldyAqbmdJZj1cInZpZXdNb2RlXCIgY2xhc3M9XCJoLWZ1bGwgdy1mdWxsXCIgW3Jlc291cmNlc109XCJyZXNvdXJjZXNcIiBbbG9hZGluZ109XCJsb2FkaW5nXCJcbiAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCIgW2Ryb3B6b25lSGVpZ2h0XT1cImRyb3B6b25lSGVpZ2h0XCJcbiAgICAgICAgKG9uRmlsZUNsaWNrKT1cIm9uRmlsZUNsaWNrKCRldmVudC5wcmV2aWV3VXJsLCAkZXZlbnQubmFtZSwgJGV2ZW50LmZpbGVTaXplKVwiXG4gICAgICAgIChvbkltYWdlQ2xpY2spPVwib25JbWFnZUNsaWNrKCRldmVudC5kaXYsICRldmVudC5pbmRleClcIj5cbiAgICA8L25ndC1kcm9wem9uZS12aWV3PlxuXG4gICAgPG5ndC1kcm9wem9uZS1maWxlLXZpZXdlciBbaGlkZGVuXT1cIiFzaG93Tmd0RHJvcHpvbmVGaWxlVmlld2VyXCIgKG9uQ2xvc2UpPVwiZm9yY2VEaXNhYmxlQ2xpY2sgPSBmYWxzZVwiXG4gICAgICAgIFtjYW5Eb3dubG9hZEZpbGVdPVwiY2FuRG93bmxvYWRGaWxlXCIgW2Rpc2FibGVDb250ZW50XT1cImNhbkRvd25sb2FkRmlsZSA/ICdub25lJyA6ICdwb3BvdXQnXCI+XG4gICAgPC9uZ3QtZHJvcHpvbmUtZmlsZS12aWV3ZXI+XG5cbiAgICA8aW5wdXQgKm5nSWY9J2NvbXBvbmVudFJlYWR5JyB0eXBlPVwiaGlkZGVuXCIgW25nTW9kZWxdPVwidmFsdWVcIiBbbmFtZV09XCJuYW1lXCIgW3ZhbHVlXT1cInZhbHVlXCI+XG4gICAgPG5ndC12YWxpZGF0aW9uIFtjb250cm9sXT1cImZvcm1Db250cm9sXCIgW2NvbnRhaW5lcl09XCJmb3JtQ29udGFpbmVyXCI+PC9uZ3QtdmFsaWRhdGlvbj5cbjwvZGl2PiJdfQ==
1
+ import { Component, EventEmitter, Host, Input, Optional, Output, SkipSelf, ViewChild, ViewEncapsulation, } from '@angular/core';
2
+ import { ControlContainer, NgForm, Validators } from '@angular/forms';
3
+ import { NgxDropzoneComponent } from 'ngx-dropzone';
4
+ import { forkJoin } from 'rxjs';
5
+ import { map } from 'rxjs/operators';
6
+ import Viewer from 'viewerjs';
7
+ import { NgtBaseNgModel, NgtMakeProvider } from '../../base/ngt-base-ng-model';
8
+ import { getEnumFromString } from '../../helpers/enum/enum';
9
+ import { uuid } from '../../helpers/uuid';
10
+ import { NgtStylizableService } from '../../services/ngt-stylizable/ngt-stylizable.service';
11
+ import { NgtDropzoneFileViewerComponent } from './ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component';
12
+ import { NgtDropzoneErrorType, NgtDropzonePreviewType } from './ngt-dropzone.meta';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "@angular/forms";
15
+ import * as i2 from "../../services/http/ngt-attachment-http.service";
16
+ import * as i3 from "@angular/common";
17
+ import * as i4 from "../ngt-validation/ngt-validation.component";
18
+ import * as i5 from "ngx-dropzone";
19
+ import * as i6 from "../ngt-helper/ngt-helper.component";
20
+ import * as i7 from "./ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component";
21
+ import * as i8 from "./ngt-dropzone-view/ngt-dropzone-view.component";
22
+ import * as i9 from "./custom-dropzone-preview/custom-dropzone-preview.component";
23
+ export class NgtDropzoneComponent extends NgtBaseNgModel {
24
+ ;
25
+ constructor(formContainer, ngtAttachmentHttpService, injector, changeDetector) {
26
+ super();
27
+ this.formContainer = formContainer;
28
+ this.ngtAttachmentHttpService = ngtAttachmentHttpService;
29
+ this.injector = injector;
30
+ this.changeDetector = changeDetector;
31
+ this.helpTextColor = 'text-green-500';
32
+ // Behavior
33
+ this.resources = [];
34
+ this.multipleSelection = false;
35
+ this.showFileName = false;
36
+ this.disableClick = false;
37
+ this.disabled = false;
38
+ this.viewMode = false;
39
+ this.removable = false;
40
+ this.canDownloadFile = true;
41
+ this.verticalExpandable = false;
42
+ this.acceptedFiles = '*' /** Mime type */;
43
+ this.previewType = NgtDropzonePreviewType.DEFAULT;
44
+ this.isRequired = false;
45
+ this.onFileSelected = new EventEmitter();
46
+ this.onFileSelectError = new EventEmitter();
47
+ this.onFileUploadFail = new EventEmitter();
48
+ this.onFileRemoved = new EventEmitter();
49
+ this.onFileUploadInit = new EventEmitter();
50
+ this.onFileUploaded = new EventEmitter();
51
+ this.onFilePreviewLoaded = new EventEmitter();
52
+ this.dropzoneHeight = '180px';
53
+ this.uploadedResources = [];
54
+ this.forceDisableClick = false;
55
+ this.nativeValue = [];
56
+ this.showNgtDropzoneFileViewer = false;
57
+ this.componentReady = false;
58
+ this.loading = false;
59
+ this.ngxElementId = uuid();
60
+ this.imageViewerOptions = {
61
+ navbar: true,
62
+ toolbar: {
63
+ zoomIn: true,
64
+ zoomOut: true,
65
+ reset: true,
66
+ rotateLeft: true,
67
+ rotateRight: true,
68
+ prev: true,
69
+ next: true,
70
+ }
71
+ };
72
+ this.subscriptions = [];
73
+ this.ngtDropzoneLoaderStyle = new NgtStylizableService();
74
+ this.ngtDropzoneLoaderStyle.load(this.injector, 'NgtDropzoneLoader', {
75
+ h: 'h-8',
76
+ color: {
77
+ text: 'text-gray-600'
78
+ }
79
+ });
80
+ }
81
+ ngOnChanges(changes) {
82
+ if (changes.previewType) {
83
+ this.previewType = getEnumFromString(changes.previewType.currentValue, NgtDropzonePreviewType);
84
+ }
85
+ }
86
+ ngAfterContentChecked() {
87
+ if (this.container && this.container.nativeElement) {
88
+ this.dropzoneHeight = `${this.container.nativeElement.parentElement.offsetHeight}px`;
89
+ this.changeDetector.detectChanges();
90
+ }
91
+ }
92
+ ngOnInit() {
93
+ setTimeout(() => {
94
+ this.componentReady = true;
95
+ setTimeout(() => {
96
+ this.initComponent();
97
+ });
98
+ }, 500);
99
+ }
100
+ ngOnDestroy() {
101
+ this.destroySubscriptions();
102
+ }
103
+ imagePreview(index) {
104
+ const images = this.uploadedResources.filter((resource) => this.isImage(resource));
105
+ const imagesDiv = document.createElement("div");
106
+ images.forEach((image) => {
107
+ let imageElement = document.createElement("img");
108
+ imageElement.src = image.file.url;
109
+ imagesDiv.appendChild(imageElement);
110
+ });
111
+ this.onImageClick(imagesDiv, index);
112
+ }
113
+ onImageClick(element, index) {
114
+ if (!this.viewMode) {
115
+ this.forceDisableClick = true;
116
+ }
117
+ const ngtDropzoneComponent = this;
118
+ if (index !== null && index !== undefined) {
119
+ this.imageViewerOptions = { ...this.imageViewerOptions, ...{ initialViewIndex: index } };
120
+ }
121
+ const viewer = new Viewer(element, {
122
+ ...this.imageViewerOptions, ...{
123
+ hidden() {
124
+ ngtDropzoneComponent.forceDisableClick = false;
125
+ viewer.destroy();
126
+ }
127
+ }
128
+ });
129
+ viewer.show();
130
+ }
131
+ onFileClick(url, name, size) {
132
+ this.forceDisableClick = true;
133
+ this.showNgtDropzoneFileViewer = true;
134
+ this.ngtDropzoneFileViewer.url = url;
135
+ this.ngtDropzoneFileViewer.fileName = name;
136
+ this.ngtDropzoneFileViewer.fileSize = size;
137
+ this.ngtDropzoneFileViewer.init();
138
+ this.subscriptions.push(this.ngtDropzoneFileViewer.onClose.subscribe(() => {
139
+ this.showNgtDropzoneFileViewer = false;
140
+ this.forceDisableClick = false;
141
+ }));
142
+ }
143
+ async onSelect(event) {
144
+ if (event.rejectedFiles.length) {
145
+ for (const rejectedFile of event.rejectedFiles) {
146
+ if (rejectedFile.reason == 'size') {
147
+ this.onFileSelectError.emit(NgtDropzoneErrorType.SIZE);
148
+ break;
149
+ }
150
+ else if (rejectedFile.reason == 'no_multiple') {
151
+ this.onFileSelectError.emit(NgtDropzoneErrorType.NO_MULTIPLE);
152
+ break;
153
+ }
154
+ else if (rejectedFile.reason == 'type') {
155
+ this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
156
+ break;
157
+ }
158
+ else {
159
+ this.onFileSelectError.emit(NgtDropzoneErrorType.DEFAULT);
160
+ break;
161
+ }
162
+ }
163
+ }
164
+ if (this.itemsLimit) {
165
+ if (this.itemsLimit == 1 && event.addedFiles
166
+ && event.addedFiles.length == this.itemsLimit && this.uploadedResources.length == this.itemsLimit) {
167
+ this.uploadedResources = [];
168
+ }
169
+ if (event.addedFiles
170
+ && event.addedFiles.length + this.uploadedResources.length <= this.itemsLimit) {
171
+ this.onFileSelected.emit(event);
172
+ this.uploadFiles(event.addedFiles);
173
+ }
174
+ else {
175
+ this.onFileSelectError.emit(NgtDropzoneErrorType.ITEMS_LIMIT);
176
+ }
177
+ }
178
+ else {
179
+ this.onFileSelected.emit(event);
180
+ this.uploadFiles(event.addedFiles);
181
+ }
182
+ }
183
+ async uploadFiles(files) {
184
+ if (files && files.length) {
185
+ const temporaryFiles = [];
186
+ const temporaryAttachments = [];
187
+ const observables = [];
188
+ const unacceptedFiles = [];
189
+ this.loading = true;
190
+ this.onFileUploadInit.emit();
191
+ files.forEach(file => {
192
+ if (file.type.includes(this.unacceptedFiles)) {
193
+ return unacceptedFiles.push(file);
194
+ }
195
+ observables.push(this.ngtAttachmentHttpService.upload(this.remoteResource, file).pipe(map((response) => {
196
+ if (response && response.data) {
197
+ if (response.data.attributes && response.data.attributes.data) {
198
+ file['url'] = response.data.attributes.data.url;
199
+ }
200
+ temporaryFiles.push({
201
+ id: response.data.id,
202
+ size: file.size,
203
+ file: file
204
+ });
205
+ response.data['loaded'] = true;
206
+ temporaryAttachments.push(response.data);
207
+ }
208
+ })));
209
+ });
210
+ if (!observables.length && unacceptedFiles.length) {
211
+ this.loading = false;
212
+ return this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
213
+ }
214
+ this.subscriptions.push(forkJoin(observables).subscribe((response) => {
215
+ this.uploadedResources.push(...temporaryFiles);
216
+ if (this.itemsLimit == 1) {
217
+ this.onNativeChange([...temporaryAttachments]);
218
+ }
219
+ else {
220
+ this.onNativeChange([...temporaryAttachments, ...this.nativeValue]);
221
+ }
222
+ this.onFileUploaded.emit();
223
+ this.loading = false;
224
+ if (unacceptedFiles.length) {
225
+ this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
226
+ }
227
+ }, (error) => {
228
+ this.onFileUploadFail.emit(error);
229
+ this.loading = false;
230
+ }));
231
+ }
232
+ }
233
+ async loadFilePreview(attachments) {
234
+ if (attachments && attachments.length && attachments[0]) {
235
+ let temporaryResource = [];
236
+ let observables = [];
237
+ attachments.forEach(attachment => {
238
+ if (!(attachment instanceof File) && !attachment.loaded) {
239
+ this.loading = true;
240
+ attachment['loaded'] = true;
241
+ observables.push(this.ngtAttachmentHttpService.thumbnail(attachment).pipe(map((response) => {
242
+ temporaryResource.push({
243
+ id: response.data.getApiId(),
244
+ file: response.data.getAttribute('file')
245
+ });
246
+ })));
247
+ }
248
+ });
249
+ this.subscriptions.push(forkJoin(observables).subscribe((response) => {
250
+ this.uploadedResources.push(...temporaryResource);
251
+ this.onNativeChange(attachments);
252
+ this.onFilePreviewLoaded.emit();
253
+ this.loading = false;
254
+ }, (error) => {
255
+ this.loading = false;
256
+ }));
257
+ }
258
+ }
259
+ onRemove(resource) {
260
+ this.uploadedResources.splice(this.uploadedResources.indexOf(resource), 1);
261
+ this.nativeValue = this.nativeValue.filter(element => element.id != resource.id);
262
+ this.onNativeChange(this.nativeValue);
263
+ this.onFileRemoved.emit(resource);
264
+ }
265
+ isImage(resource) {
266
+ return this.previewType == 'IMAGE'
267
+ || (resource.file && resource.file.type
268
+ && resource.file.type.includes('image')
269
+ && !resource.file.type.includes('dwg'));
270
+ }
271
+ isVideo(resource) {
272
+ return this.previewType == 'VIDEO' || (resource.file && resource.file.type && resource.file.type.includes('video'));
273
+ }
274
+ isAudio(resource) {
275
+ return (resource.file && resource.file.type && resource.file.type.includes('audio'));
276
+ }
277
+ isFile(resource) {
278
+ return !this.isImage(resource) && !this.isAudio(resource) && !this.isVideo(resource);
279
+ }
280
+ getFormattedFileSize(resource) {
281
+ if (resource) {
282
+ let size = resource.size || resource.fileSize;
283
+ if (!size) {
284
+ if (resource.file && resource.file.size) {
285
+ size = resource.file.size;
286
+ }
287
+ else {
288
+ size = 0;
289
+ }
290
+ }
291
+ if (parseFloat(size) > 1000000) {
292
+ return (parseFloat(size) / 1000000).toFixed(2) + ' Mb';
293
+ }
294
+ return Math.round(parseFloat(size) / 1000) + ' Kb';
295
+ }
296
+ }
297
+ onNativeChange(value) {
298
+ if (value === undefined) {
299
+ this.value = [];
300
+ this.nativeValue = [];
301
+ }
302
+ else {
303
+ this.nativeValue = value;
304
+ if (JSON.stringify(this.value) != JSON.stringify(this.nativeValue)) {
305
+ this.value = this.nativeValue;
306
+ }
307
+ }
308
+ }
309
+ change(value) {
310
+ if (value && !this.viewMode) {
311
+ this.onNativeChange(Array.isArray(value) ? value : [value]);
312
+ if (this.componentReady) {
313
+ this.loadFilePreview(Array.isArray(value) ? value : [value]);
314
+ }
315
+ }
316
+ }
317
+ downloadFile(attachment) {
318
+ this.ngtAttachmentHttpService.download(attachment).subscribe(() => { });
319
+ }
320
+ reset() {
321
+ this.uploadedResources = [];
322
+ this.value = [];
323
+ this.nativeValue = [];
324
+ this.initComponent();
325
+ }
326
+ openFileSelector() {
327
+ document.getElementById(this.ngxElementId).click();
328
+ }
329
+ initComponent() {
330
+ if (this.viewMode) {
331
+ this.previewType = NgtDropzonePreviewType.DEFAULT;
332
+ return;
333
+ }
334
+ if (this.formContainer && this.formContainer.control
335
+ && (this.formControl = this.formContainer.control.get(this.name))) {
336
+ this.resetFilesLoad();
337
+ this.loadFilePreview(Array.isArray(this.value) ? this.value : [this.value]);
338
+ this.updateValidations();
339
+ if (this.value) {
340
+ this.formControl.markAsDirty();
341
+ }
342
+ else {
343
+ this.formControl.markAsPristine();
344
+ }
345
+ }
346
+ }
347
+ resetFilesLoad() {
348
+ if (Array.isArray(this.value)) {
349
+ this.value.forEach(element => {
350
+ if (element) {
351
+ element['loaded'] = false;
352
+ }
353
+ });
354
+ }
355
+ }
356
+ updateValidations() {
357
+ if (!this.formControl) {
358
+ return;
359
+ }
360
+ let syncValidators = [];
361
+ if (this.isRequired) {
362
+ syncValidators.push(Validators.required);
363
+ }
364
+ syncValidators.push();
365
+ setTimeout(() => {
366
+ this.formControl.setValidators(syncValidators);
367
+ this.formControl.updateValueAndValidity();
368
+ });
369
+ }
370
+ destroySubscriptions() {
371
+ this.subscriptions.forEach(subscription => subscription.unsubscribe());
372
+ this.subscriptions = [];
373
+ }
374
+ }
375
+ NgtDropzoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgtDropzoneComponent, deps: [{ token: i1.ControlContainer, host: true, optional: true }, { token: i2.NgtAttachmentHttpService, optional: true, skipSelf: true }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
376
+ NgtDropzoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.8", type: NgtDropzoneComponent, selector: "ngt-dropzone", inputs: { label: "label", placeholder: "placeholder", helpTextColor: "helpTextColor", helpText: "helpText", helpTitle: "helpTitle", resources: "resources", multipleSelection: "multipleSelection", itemsLimit: "itemsLimit", showFileName: "showFileName", disableClick: "disableClick", disabled: "disabled", viewMode: "viewMode", removable: "removable", canDownloadFile: "canDownloadFile", verticalExpandable: "verticalExpandable", acceptedFiles: "acceptedFiles", unacceptedFiles: "unacceptedFiles", maxFileSize: "maxFileSize", previewType: "previewType", isRequired: "isRequired", name: "name", remoteResource: "remoteResource" }, outputs: { onFileSelected: "onFileSelected", onFileSelectError: "onFileSelectError", onFileUploadFail: "onFileUploadFail", onFileRemoved: "onFileRemoved", onFileUploadInit: "onFileUploadInit", onFileUploaded: "onFileUploaded", onFilePreviewLoaded: "onFilePreviewLoaded" }, providers: [
377
+ NgtMakeProvider(NgtDropzoneComponent),
378
+ ], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "ngxDropzone", first: true, predicate: NgxDropzoneComponent, descendants: true, static: true }, { propertyName: "ngtDropzoneFileViewer", first: true, predicate: NgtDropzoneFileViewerComponent, descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"flex flex-col h-full w-full\" #container>\r\n <label *ngIf=\"label\" class=\"flex mb-2 text-sm\">\r\n {{ label }}:\r\n\r\n <span class=\"text-red-500 font-bold text-md ml-1\" *ngIf=\"isRequired\">*</span>\r\n\r\n <ngt-helper *ngIf=\"helpText\" [helpTitle]=\"helpTitle\" [iconColor]=\"helpTextColor\" class=\"ml-1\">\r\n {{ helpText }}\r\n </ngt-helper>\r\n </label>\r\n\r\n <div *ngIf=\"!viewMode\" class=\"h-full w-full relative\">\r\n <div *ngIf=\"loading\" class=\"flex absolute justify-center items-center w-full h-full cursor-wait z-10\">\r\n <div class=\"div-loader\"></div>\r\n </div>\r\n\r\n <ngx-dropzone [id]=\"ngxElementId\" [multiple]='multipleSelection' [maxFileSize]='maxFileSize'\r\n (change)='onSelect($event)' [class.single-attachment]='itemsLimit == 1' [accept]='acceptedFiles'\r\n [disabled]='disabled || loading' [expandable]='verticalExpandable'\r\n [disableClick]='disableClick || forceDisableClick' [ngStyle]=\"{ 'height': dropzoneHeight }\" #ngxDropzone>\r\n <ng-container *ngIf=\"!loading\">\r\n <ngx-dropzone-label *ngIf=\"!uploadedResources?.length\" class=\"px-2\">\r\n {{ placeholder }}\r\n </ngx-dropzone-label>\r\n\r\n <ng-container *ngFor=\"let resource of uploadedResources; let index = index\">\r\n <div class=\"flex flex-col w-48 mx-4\"\r\n title=\"{{ resource?.file?.name || '' }} ({{ getFormattedFileSize(resource) }})\">\r\n <custom-dropzone-preview *ngIf=\"previewType == 'DEFAULT' && isFile(resource)\"\r\n [file]='resource.file' [removable]=\"removable\" (removed)=\"onRemove(resource)\"\r\n (click)=\"onFileClick(resource.file.url, resource.file.name, resource.file.size)\"\r\n ngProjectAs=\"ngx-dropzone-preview\">\r\n </custom-dropzone-preview>\r\n\r\n <div *ngIf=\"isImage(resource)\" class=\"cursor-pointer\" (click)=\"imagePreview(index)\" #gallery>\r\n <ngx-dropzone-image-preview class=\"image-preview-default-class\" [file]=\"resource.file\"\r\n [removable]=\"removable\" (removed)=\"onRemove(resource)\">\r\n </ngx-dropzone-image-preview>\r\n </div>\r\n\r\n <ngx-dropzone-video-preview *ngIf=\"isVideo(resource) || isAudio(resource)\"\r\n [file]=\"resource.file\" [removable]=\"removable\" (removed)=\"onRemove(resource)\">\r\n </ngx-dropzone-video-preview>\r\n\r\n <p *ngIf=\"showFileName\"\r\n class=\"w-full truncate text-gray-500 text-center text-sm font-mono mt-2\">\r\n {{ resource?.file?.name || '' }}\r\n </p>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ngx-dropzone>\r\n </div>\r\n\r\n <ngt-dropzone-view *ngIf=\"viewMode\" class=\"h-full w-full\" [resources]=\"resources\" [loading]=\"loading\"\r\n [placeholder]=\"placeholder\" [dropzoneHeight]=\"dropzoneHeight\"\r\n (onFileClick)=\"onFileClick($event.previewUrl, $event.name, $event.fileSize)\"\r\n (onImageClick)=\"onImageClick($event.div, $event.index)\">\r\n </ngt-dropzone-view>\r\n\r\n <ngt-dropzone-file-viewer [hidden]=\"!showNgtDropzoneFileViewer\" (onClose)=\"forceDisableClick = false\"\r\n [canDownloadFile]=\"canDownloadFile\" [disableContent]=\"canDownloadFile ? 'none' : 'popout'\">\r\n </ngt-dropzone-file-viewer>\r\n\r\n <input *ngIf='componentReady' type=\"hidden\" [ngModel]=\"value\" [name]=\"name\" [value]=\"value\">\r\n <ngt-validation [control]=\"formControl\" [container]=\"formContainer\"></ngt-validation>\r\n</div>", styles: [".single-attachment{border:none!important;margin:unset!important;overflow:hidden!important;display:flex!important;justify-content:center!important}.image-preview-default-class{margin:unset!important}custom-dropzone-preview{height:100%!important;min-height:unset!important;margin:unset!important}.div-loader{width:4rem;height:4rem;border:3px solid #a0aec038;border-top-color:#a0aec0;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.NgtValidationComponent, selector: "ngt-validation", inputs: ["control", "container", "minValue", "minLength"] }, { kind: "component", type: i5.NgxDropzoneComponent, selector: "ngx-dropzone, [ngx-dropzone]", inputs: ["accept", "disabled", "multiple", "maxFileSize", "expandable", "disableClick", "id", "aria-label", "aria-labelledby", "aria-describedby"], outputs: ["change"] }, { kind: "directive", type: i5.ɵb, selector: "ngx-dropzone-label" }, { kind: "component", type: i5.NgxDropzoneImagePreviewComponent, selector: "ngx-dropzone-image-preview" }, { kind: "component", type: i5.NgxDropzoneVideoPreviewComponent, selector: "ngx-dropzone-video-preview" }, { kind: "component", type: i6.NgtHelperComponent, selector: "ngt-helper", inputs: ["helpTextColor", "helpText", "helpTitle", "icon", "iconSize", "iconColor", "iconTitle", "tooltipSize", "autoXReverse", "helperReverseYPosition"] }, { kind: "component", type: i7.NgtDropzoneFileViewerComponent, selector: "ngt-dropzone-file-viewer", inputs: ["url", "fileName", "fileSize", "disableContent", "canDownloadFile"], outputs: ["onClose"] }, { kind: "component", type: i8.NgtDropzoneViewComponent, selector: "ngt-dropzone-view", inputs: ["resources", "dropzoneHeight", "loading", "placeholder"], outputs: ["onImageClick", "onFileClick"] }, { kind: "component", type: i9.CustomDropzonePreviewComponent, selector: "custom-dropzone-preview" }], viewProviders: [
379
+ { provide: ControlContainer, useExisting: NgForm }
380
+ ], encapsulation: i0.ViewEncapsulation.None });
381
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: NgtDropzoneComponent, decorators: [{
382
+ type: Component,
383
+ args: [{ selector: 'ngt-dropzone', encapsulation: ViewEncapsulation.None, providers: [
384
+ NgtMakeProvider(NgtDropzoneComponent),
385
+ ], viewProviders: [
386
+ { provide: ControlContainer, useExisting: NgForm }
387
+ ], template: "<div class=\"flex flex-col h-full w-full\" #container>\r\n <label *ngIf=\"label\" class=\"flex mb-2 text-sm\">\r\n {{ label }}:\r\n\r\n <span class=\"text-red-500 font-bold text-md ml-1\" *ngIf=\"isRequired\">*</span>\r\n\r\n <ngt-helper *ngIf=\"helpText\" [helpTitle]=\"helpTitle\" [iconColor]=\"helpTextColor\" class=\"ml-1\">\r\n {{ helpText }}\r\n </ngt-helper>\r\n </label>\r\n\r\n <div *ngIf=\"!viewMode\" class=\"h-full w-full relative\">\r\n <div *ngIf=\"loading\" class=\"flex absolute justify-center items-center w-full h-full cursor-wait z-10\">\r\n <div class=\"div-loader\"></div>\r\n </div>\r\n\r\n <ngx-dropzone [id]=\"ngxElementId\" [multiple]='multipleSelection' [maxFileSize]='maxFileSize'\r\n (change)='onSelect($event)' [class.single-attachment]='itemsLimit == 1' [accept]='acceptedFiles'\r\n [disabled]='disabled || loading' [expandable]='verticalExpandable'\r\n [disableClick]='disableClick || forceDisableClick' [ngStyle]=\"{ 'height': dropzoneHeight }\" #ngxDropzone>\r\n <ng-container *ngIf=\"!loading\">\r\n <ngx-dropzone-label *ngIf=\"!uploadedResources?.length\" class=\"px-2\">\r\n {{ placeholder }}\r\n </ngx-dropzone-label>\r\n\r\n <ng-container *ngFor=\"let resource of uploadedResources; let index = index\">\r\n <div class=\"flex flex-col w-48 mx-4\"\r\n title=\"{{ resource?.file?.name || '' }} ({{ getFormattedFileSize(resource) }})\">\r\n <custom-dropzone-preview *ngIf=\"previewType == 'DEFAULT' && isFile(resource)\"\r\n [file]='resource.file' [removable]=\"removable\" (removed)=\"onRemove(resource)\"\r\n (click)=\"onFileClick(resource.file.url, resource.file.name, resource.file.size)\"\r\n ngProjectAs=\"ngx-dropzone-preview\">\r\n </custom-dropzone-preview>\r\n\r\n <div *ngIf=\"isImage(resource)\" class=\"cursor-pointer\" (click)=\"imagePreview(index)\" #gallery>\r\n <ngx-dropzone-image-preview class=\"image-preview-default-class\" [file]=\"resource.file\"\r\n [removable]=\"removable\" (removed)=\"onRemove(resource)\">\r\n </ngx-dropzone-image-preview>\r\n </div>\r\n\r\n <ngx-dropzone-video-preview *ngIf=\"isVideo(resource) || isAudio(resource)\"\r\n [file]=\"resource.file\" [removable]=\"removable\" (removed)=\"onRemove(resource)\">\r\n </ngx-dropzone-video-preview>\r\n\r\n <p *ngIf=\"showFileName\"\r\n class=\"w-full truncate text-gray-500 text-center text-sm font-mono mt-2\">\r\n {{ resource?.file?.name || '' }}\r\n </p>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n </ngx-dropzone>\r\n </div>\r\n\r\n <ngt-dropzone-view *ngIf=\"viewMode\" class=\"h-full w-full\" [resources]=\"resources\" [loading]=\"loading\"\r\n [placeholder]=\"placeholder\" [dropzoneHeight]=\"dropzoneHeight\"\r\n (onFileClick)=\"onFileClick($event.previewUrl, $event.name, $event.fileSize)\"\r\n (onImageClick)=\"onImageClick($event.div, $event.index)\">\r\n </ngt-dropzone-view>\r\n\r\n <ngt-dropzone-file-viewer [hidden]=\"!showNgtDropzoneFileViewer\" (onClose)=\"forceDisableClick = false\"\r\n [canDownloadFile]=\"canDownloadFile\" [disableContent]=\"canDownloadFile ? 'none' : 'popout'\">\r\n </ngt-dropzone-file-viewer>\r\n\r\n <input *ngIf='componentReady' type=\"hidden\" [ngModel]=\"value\" [name]=\"name\" [value]=\"value\">\r\n <ngt-validation [control]=\"formControl\" [container]=\"formContainer\"></ngt-validation>\r\n</div>", styles: [".single-attachment{border:none!important;margin:unset!important;overflow:hidden!important;display:flex!important;justify-content:center!important}.image-preview-default-class{margin:unset!important}custom-dropzone-preview{height:100%!important;min-height:unset!important;margin:unset!important}.div-loader{width:4rem;height:4rem;border:3px solid #a0aec038;border-top-color:#a0aec0;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
388
+ }], ctorParameters: function () { return [{ type: i1.ControlContainer, decorators: [{
389
+ type: Optional
390
+ }, {
391
+ type: Host
392
+ }] }, { type: i2.NgtAttachmentHttpService, decorators: [{
393
+ type: Optional
394
+ }, {
395
+ type: SkipSelf
396
+ }] }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { container: [{
397
+ type: ViewChild,
398
+ args: ['container']
399
+ }], ngxDropzone: [{
400
+ type: ViewChild,
401
+ args: [NgxDropzoneComponent, { static: true }]
402
+ }], ngtDropzoneFileViewer: [{
403
+ type: ViewChild,
404
+ args: [NgtDropzoneFileViewerComponent, { static: true }]
405
+ }], label: [{
406
+ type: Input
407
+ }], placeholder: [{
408
+ type: Input
409
+ }], helpTextColor: [{
410
+ type: Input
411
+ }], helpText: [{
412
+ type: Input
413
+ }], helpTitle: [{
414
+ type: Input
415
+ }], resources: [{
416
+ type: Input
417
+ }], multipleSelection: [{
418
+ type: Input
419
+ }], itemsLimit: [{
420
+ type: Input
421
+ }], showFileName: [{
422
+ type: Input
423
+ }], disableClick: [{
424
+ type: Input
425
+ }], disabled: [{
426
+ type: Input
427
+ }], viewMode: [{
428
+ type: Input
429
+ }], removable: [{
430
+ type: Input
431
+ }], canDownloadFile: [{
432
+ type: Input
433
+ }], verticalExpandable: [{
434
+ type: Input
435
+ }], acceptedFiles: [{
436
+ type: Input
437
+ }], unacceptedFiles: [{
438
+ type: Input
439
+ }], maxFileSize: [{
440
+ type: Input
441
+ }], previewType: [{
442
+ type: Input
443
+ }], isRequired: [{
444
+ type: Input
445
+ }], name: [{
446
+ type: Input
447
+ }], remoteResource: [{
448
+ type: Input
449
+ }], onFileSelected: [{
450
+ type: Output
451
+ }], onFileSelectError: [{
452
+ type: Output
453
+ }], onFileUploadFail: [{
454
+ type: Output
455
+ }], onFileRemoved: [{
456
+ type: Output
457
+ }], onFileUploadInit: [{
458
+ type: Output
459
+ }], onFileUploaded: [{
460
+ type: Output
461
+ }], onFilePreviewLoaded: [{
462
+ type: Output
463
+ }] } });
464
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd0LWRyb3B6b25lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhaWx3aW5kL3NyYy9jb21wb25lbnRzL25ndC1kcm9wem9uZS9uZ3QtZHJvcHpvbmUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctdGFpbHdpbmQvc3JjL2NvbXBvbmVudHMvbmd0LWRyb3B6b25lL25ndC1kcm9wem9uZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0gsU0FBUyxFQUVULFlBQVksRUFDWixJQUFJLEVBRUosS0FBSyxFQUdMLFFBQVEsRUFDUixNQUFNLEVBRU4sUUFBUSxFQUNSLFNBQVMsRUFDVCxpQkFBaUIsR0FDcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RSxPQUFPLEVBQTBCLG9CQUFvQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxRQUFRLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLE1BQU0sTUFBTSxVQUFVLENBQUM7QUFFOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFMUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0RBQXNELENBQUM7QUFDNUYsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sK0RBQStELENBQUM7QUFDL0csT0FBTyxFQUFFLG9CQUFvQixFQUFtQixzQkFBc0Is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LEVBQUU7Z0JBRzNDLEtBQUs7c0JBQXBCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLO2dCQUNVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBQ1UsU0FBUztzQkFBeEIsS0FBSztnQkFHVSxTQUFTO3NCQUF4QixLQUFLO2dCQUNVLGlCQUFpQjtzQkFBaEMsS0FBSztnQkFDVSxVQUFVO3NCQUF6QixLQUFLO2dCQUNVLFlBQVk7c0JBQTNCLEtBQUs7Z0JBQ1UsWUFBWTtzQkFBM0IsS0FBSztnQkFDVSxRQUFRO3NCQUF2QixLQUFLO2dCQUNVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBQ1UsU0FBUztzQkFBeEIsS0FBSztnQkFDVSxlQUFlO3NCQUE5QixLQUFLO2dCQUNVLGtCQUFrQjtzQkFBakMsS0FBSztnQkFDVSxhQUFhO3NCQUE1QixLQUFLO2dCQUNVLGVBQWU7c0JBQTlCLEtBQUs7Z0JBQ1UsV0FBVztzQkFBMUIsS0FBSztnQkFDVSxXQUFXO3NCQUExQixLQUFLO2dCQUNVLFVBQVU7c0JBQXpCLEtBQUs7Z0JBQ1UsSUFBSTtzQkFBbkIsS0FBSztnQkFDVSxjQUFjO3NCQUE3QixLQUFLO2dCQUVXLGNBQWM7c0JBQTlCLE1BQU07Z0JBQ1UsaUJBQWlCO3NCQUFqQyxNQUFNO2dCQUNVLGdCQUFnQjtzQkFBaEMsTUFBTTtnQkFDVSxhQUFhO3NCQUE3QixNQUFNO2dCQUNVLGdCQUFnQjtzQkFBaEMsTUFBTTtnQkFDVSxjQUFjO3NCQUE5QixNQUFNO2dCQUNVLG1CQUFtQjtzQkFBbkMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBBZnRlckNvbnRlbnRDaGVja2VkLFxyXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBFbGVtZW50UmVmLFxyXG4gICAgRXZlbnRFbWl0dGVyLFxyXG4gICAgSG9zdCxcclxuICAgIEluamVjdG9yLFxyXG4gICAgSW5wdXQsXHJcbiAgICBPbkRlc3Ryb3ksXHJcbiAgICBPbkluaXQsXHJcbiAgICBPcHRpb25hbCxcclxuICAgIE91dHB1dCxcclxuICAgIFNpbXBsZUNoYW5nZXMsXHJcbiAgICBTa2lwU2VsZixcclxuICAgIFZpZXdDaGlsZCxcclxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sQ29udGFpbmVyLCBOZ0Zvcm0sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE5neERyb3B6b25lQ2hhbmdlRXZlbnQsIE5neERyb3B6b25lQ29tcG9uZW50IH0gZnJvbSAnbmd4LWRyb3B6b25lJztcclxuaW1wb3J0IHsgZm9ya0pvaW4sIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCBWaWV3ZXIgZnJvbSAndmlld2VyanMnO1xyXG5cclxuaW1wb3J0IHsgTmd0QmFzZU5nTW9kZWwsIE5ndE1ha2VQcm92aWRlciB9IGZyb20gJy4uLy4uL2Jhc2Uvbmd0LWJhc2UtbmctbW9kZWwnO1xyXG5pbXBvcnQgeyBnZXRFbnVtRnJvbVN0cmluZyB9IGZyb20gJy4uLy4uL2hlbHBlcnMvZW51bS9lbnVtJztcclxuaW1wb3J0IHsgdXVpZCB9IGZyb20gJy4uLy4uL2hlbHBlcnMvdXVpZCc7XHJcbmltcG9ydCB7IE5ndEF0dGFjaG1lbnRIdHRwU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2h0dHAvbmd0LWF0dGFjaG1lbnQtaHR0cC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTmd0U3R5bGl6YWJsZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9uZ3Qtc3R5bGl6YWJsZS9uZ3Qtc3R5bGl6YWJsZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTmd0RHJvcHpvbmVGaWxlVmlld2VyQ29tcG9uZW50IH0gZnJvbSAnLi9uZ3QtZHJvcHpvbmUtZmlsZS12aWV3ZXIvbmd0LWRyb3B6b25lLWZpbGUtdmlld2VyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IE5ndERyb3B6b25lRXJyb3JUeXBlLCBOZ3REcm9wem9uZUZpbGUsIE5ndERyb3B6b25lUHJldmlld1R5cGUgfSBmcm9tICcuL25ndC1kcm9wem9uZS5tZXRhJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICduZ3QtZHJvcHpvbmUnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL25ndC1kcm9wem9uZS5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9uZ3QtZHJvcHpvbmUuY29tcG9uZW50LmNzcyddLFxyXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxuICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIE5ndE1ha2VQcm92aWRlcihOZ3REcm9wem9uZUNvbXBvbmVudCksXHJcbiAgICBdLFxyXG4gICAgdmlld1Byb3ZpZGVyczogW1xyXG4gICAgICAgIHsgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IE5nRm9ybSB9XHJcbiAgICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOZ3REcm9wem9uZUNvbXBvbmVudCBleHRlbmRzIE5ndEJhc2VOZ01vZGVsIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyQ29udGVudENoZWNrZWQge1xyXG4gICAgQFZpZXdDaGlsZCgnY29udGFpbmVyJykgcHVibGljIGNvbnRhaW5lcjogRWxlbWVudFJlZjtcclxuICAgIEBWaWV3Q2hpbGQoTmd4RHJvcHpvbmVDb21wb25lbnQsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBuZ3hEcm9wem9uZTogTmd4RHJvcHpvbmVDb21wb25lbnQ7XHJcbiAgICBAVmlld0NoaWxkKE5ndERyb3B6b25lRmlsZVZpZXdlckNvbXBvbmVudCwgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIG5ndERyb3B6b25lRmlsZVZpZXdlcjogTmd0RHJvcHpvbmVGaWxlVmlld2VyQ29tcG9uZW50O1xyXG5cclxuICAgIC8vIFZpc3VhbFxyXG4gICAgQElucHV0KCkgcHVibGljIGxhYmVsOiBzdHJpbmc7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBoZWxwVGV4dENvbG9yOiBzdHJpbmcgPSAndGV4dC1ncmVlbi01MDAnO1xyXG4gICAgQElucHV0KCkgcHVibGljIGhlbHBUZXh0OiBzdHJpbmc7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgaGVscFRpdGxlOiBzdHJpbmc7XHJcblxyXG4gICAgLy8gQmVoYXZpb3JcclxuICAgIEBJbnB1dCgpIHB1YmxpYyByZXNvdXJjZXM6IEFycmF5PE5ndERyb3B6b25lRmlsZT4gPSBbXTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBtdWx0aXBsZVNlbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgcHVibGljIGl0ZW1zTGltaXQ6IG51bWJlcjtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBzaG93RmlsZU5hbWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlQ2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgcHVibGljIHZpZXdNb2RlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgcmVtb3ZhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgY2FuRG93bmxvYWRGaWxlOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyB2ZXJ0aWNhbEV4cGFuZGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBhY2NlcHRlZEZpbGVzOiBzdHJpbmcgPSAnKicgLyoqIE1pbWUgdHlwZSAqLztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyB1bmFjY2VwdGVkRmlsZXM6IHN0cmluZzsgLyoqIE1pbWUgdHlwZSAqLztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBtYXhGaWxlU2l6ZTogbnVtYmVyOyAvKiogQnl0ZXMgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBwcmV2aWV3VHlwZTogTmd0RHJvcHpvbmVQcmV2aWV3VHlwZSA9IE5ndERyb3B6b25lUHJldmlld1R5cGUuREVGQVVMVDtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBpc1JlcXVpcmVkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgbmFtZTogc3RyaW5nO1xyXG4gICAgQElucHV0KCkgcHVibGljIHJlbW90ZVJlc291cmNlOiBhbnk7XHJcblxyXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVTZWxlY3RlZDogRXZlbnRFbWl0dGVyPE5neERyb3B6b25lQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVTZWxlY3RFcnJvcjogRXZlbnRFbWl0dGVyPE5ndERyb3B6b25lRXJyb3JUeXBlPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlVXBsb2FkRmFpbDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVJlbW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVVwbG9hZEluaXQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVVwbG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVQcmV2aWV3TG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG5cclxuICAgIHB1YmxpYyBkcm9wem9uZUhlaWdodDogc3RyaW5nID0gJzE4MHB4JztcclxuICAgIHB1YmxpYyB1cGxvYWRlZFJlc291cmNlcyA9IFtdO1xyXG4gICAgcHVibGljIGZvcmNlRGlzYWJsZUNsaWNrOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgbmF0aXZlVmFsdWUgPSBbXTtcclxuICAgIHB1YmxpYyBzaG93Tmd0RHJvcHpvbmVGaWxlVmlld2VyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgY29tcG9uZW50UmVhZHkgPSBmYWxzZTtcclxuICAgIHB1YmxpYyBsb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgbmd0RHJvcHpvbmVMb2FkZXJTdHlsZTogTmd0U3R5bGl6YWJsZVNlcnZpY2U7XHJcbiAgICBwdWJsaWMgbmd4RWxlbWVudElkOiBzdHJpbmcgPSB1dWlkKCk7XHJcbiAgICBwdWJsaWMgaW1hZ2VWaWV3ZXJPcHRpb25zOiBhbnkgPSB7XHJcbiAgICAgICAgbmF2YmFyOiB0cnVlLFxyXG4gICAgICAgIHRvb2xiYXI6IHtcclxuICAgICAgICAgICAgem9vbUluOiB0cnVlLFxyXG4gICAgICAgICAgICB6b29tT3V0OiB0cnVlLFxyXG4gICAgICAgICAgICByZXNldDogdHJ1ZSxcclxuICAgICAgICAgICAgcm90YXRlTGVmdDogdHJ1ZSxcclxuICAgICAgICAgICAgcm90YXRlUmlnaHQ6IHRydWUsXHJcbiAgICAgICAgICAgIHByZXY6IHRydWUsXHJcbiAgICAgICAgICAgIG5leHQ6IHRydWUsXHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBwcml2YXRlIHN1YnNjcmlwdGlvbnM6IEFycmF5PFN1YnNjcmlwdGlvbj4gPSBbXTtcclxuXHJcbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXHJcbiAgICAgICAgQE9wdGlvbmFsKCkgQEhvc3QoKVxyXG4gICAgICAgIHB1YmxpYyBmb3JtQ29udGFpbmVyOiBDb250cm9sQ29udGFpbmVyLFxyXG4gICAgICAgIEBPcHRpb25hbCgpIEBTa2lwU2VsZigpXHJcbiAgICAgICAgcHJpdmF0ZSBuZ3RBdHRhY2htZW50SHR0cFNlcnZpY2U6IE5ndEF0dGFjaG1lbnRIdHRwU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcclxuICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgICkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcblxyXG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVMb2FkZXJTdHlsZSA9IG5ldyBOZ3RTdHlsaXphYmxlU2VydmljZSgpO1xyXG5cclxuICAgICAgICB0aGlzLm5ndERyb3B6b25lTG9hZGVyU3R5bGUubG9hZCh0aGlzLmluamVjdG9yLCAnTmd0RHJvcHpvbmVMb2FkZXInLCB7XHJcbiAgICAgICAgICAgIGg6ICdoLTgnLFxyXG4gICAgICAgICAgICBjb2xvcjoge1xyXG4gICAgICAgICAgICAgICAgdGV4dDogJ3RleHQtZ3JheS02MDAnXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgICAgIGlmIChjaGFuZ2VzLnByZXZpZXdUeXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMucHJldmlld1R5cGUgPSBnZXRFbnVtRnJvbVN0cmluZyhjaGFuZ2VzLnByZXZpZXdUeXBlLmN1cnJlbnRWYWx1ZSwgTmd0RHJvcHpvbmVQcmV2aWV3VHlwZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyICYmIHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5kcm9wem9uZUhlaWdodCA9IGAke3RoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQucGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHR9cHhgO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWFkeSA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdENvbXBvbmVudCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LCA1MDApO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLmRlc3Ryb3lTdWJzY3JpcHRpb25zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGltYWdlUHJldmlldyhpbmRleCkge1xyXG4gICAgICAgIGNvbnN0IGltYWdlcyA9IHRoaXMudXBsb2FkZWRSZXNvdXJjZXMuZmlsdGVyKChyZXNvdXJjZSkgPT4gdGhpcy5pc0ltYWdlKHJlc291cmNlKSk7XHJcbiAgICAgICAgY29uc3QgaW1hZ2VzRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuXHJcbiAgICAgICAgaW1hZ2VzLmZvckVhY2goKGltYWdlKSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBpbWFnZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpO1xyXG5cclxuICAgICAgICAgICAgaW1hZ2VFbGVtZW50LnNyYyA9IGltYWdlLmZpbGUudXJsO1xyXG5cclxuICAgICAgICAgICAgaW1hZ2VzRGl2LmFwcGVuZENoaWxkKGltYWdlRWxlbWVudCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMub25JbWFnZUNsaWNrKGltYWdlc0RpdiwgaW5kZXgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvbkltYWdlQ2xpY2soZWxlbWVudCwgaW5kZXg/KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9yY2VEaXNhYmxlQ2xpY2sgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgbmd0RHJvcHpvbmVDb21wb25lbnQgPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoaW5kZXggIT09IG51bGwgJiYgaW5kZXggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICB0aGlzLmltYWdlVmlld2VyT3B0aW9ucyA9IHsgLi4udGhpcy5pbWFnZVZpZXdlck9wdGlvbnMsIC4uLnsgaW5pdGlhbFZpZXdJbmRleDogaW5kZXggfSB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgdmlld2VyID0gbmV3IFZpZXdlcihlbGVtZW50LCB7XHJcbiAgICAgICAgICAgIC4uLnRoaXMuaW1hZ2VWaWV3ZXJPcHRpb25zLCAuLi57XHJcbiAgICAgICAgICAgICAgICBoaWRkZW4oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmd0RHJvcHpvbmVDb21wb25lbnQuZm9yY2VEaXNhYmxlQ2xpY2sgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2aWV3ZXIuZGVzdHJveSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHZpZXdlci5zaG93KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG9uRmlsZUNsaWNrKHVybDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHNpemU6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuZm9yY2VEaXNhYmxlQ2xpY2sgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc2hvd05ndERyb3B6b25lRmlsZVZpZXdlciA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5uZ3REcm9wem9uZUZpbGVWaWV3ZXIudXJsID0gdXJsO1xyXG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVGaWxlVmlld2VyLmZpbGVOYW1lID0gbmFtZTtcclxuICAgICAgICB0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci5maWxlU2l6ZSA9IHNpemU7XHJcbiAgICAgICAgdGhpcy5uZ3REcm9wem9uZUZpbGVWaWV3ZXIuaW5pdCgpO1xyXG5cclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci5vbkNsb3NlLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2hvd05ndERyb3B6b25lRmlsZVZpZXdlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmZvcmNlRGlzYWJsZUNsaWNrID0gZmFsc2U7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBvblNlbGVjdChldmVudDogTmd4RHJvcHpvbmVDaGFuZ2VFdmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC5yZWplY3RlZEZpbGVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlamVjdGVkRmlsZSBvZiA8YW55PmV2ZW50LnJlamVjdGVkRmlsZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZWplY3RlZEZpbGUucmVhc29uID09ICdzaXplJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5TSVpFKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWRGaWxlLnJlYXNvbiA9PSAnbm9fbXVsdGlwbGUnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLk5PX01VTFRJUExFKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWRGaWxlLnJlYXNvbiA9PSAndHlwZScpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdEVycm9yLmVtaXQoTmd0RHJvcHpvbmVFcnJvclR5cGUuVFlQRSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5ERUZBVUxUKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXRlbXNMaW1pdCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pdGVtc0xpbWl0ID09IDEgJiYgZXZlbnQuYWRkZWRGaWxlc1xyXG4gICAgICAgICAgICAgICAgJiYgZXZlbnQuYWRkZWRGaWxlcy5sZW5ndGggPT0gdGhpcy5pdGVtc0xpbWl0ICYmIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMubGVuZ3RoID09IHRoaXMuaXRlbXNMaW1pdCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcyA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZXZlbnQuYWRkZWRGaWxlc1xyXG4gICAgICAgICAgICAgICAgJiYgZXZlbnQuYWRkZWRGaWxlcy5sZW5ndGggKyB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzLmxlbmd0aCA8PSB0aGlzLml0ZW1zTGltaXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0ZWQuZW1pdChldmVudCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKGV2ZW50LmFkZGVkRmlsZXMpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLklURU1TX0xJTUlUKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0ZWQuZW1pdChldmVudCk7XHJcbiAgICAgICAgICAgIHRoaXMudXBsb2FkRmlsZXMoZXZlbnQuYWRkZWRGaWxlcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB1cGxvYWRGaWxlcyhmaWxlczogQXJyYXk8RmlsZT4pIHtcclxuICAgICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRlbXBvcmFyeUZpbGVzID0gW107XHJcbiAgICAgICAgICAgIGNvbnN0IHRlbXBvcmFyeUF0dGFjaG1lbnRzID0gW107XHJcbiAgICAgICAgICAgIGNvbnN0IG9ic2VydmFibGVzID0gW107XHJcbiAgICAgICAgICAgIGNvbnN0IHVuYWNjZXB0ZWRGaWxlcyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5vbkZpbGVVcGxvYWRJbml0LmVtaXQoKTtcclxuXHJcbiAgICAgICAgICAgIGZpbGVzLmZvckVhY2goZmlsZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZmlsZS50eXBlLmluY2x1ZGVzKHRoaXMudW5hY2NlcHRlZEZpbGVzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmFjY2VwdGVkRmlsZXMucHVzaChmaWxlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBvYnNlcnZhYmxlcy5wdXNoKHRoaXMubmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlLnVwbG9hZCh0aGlzLnJlbW90ZVJlc291cmNlLCBmaWxlKS5waXBlKFxyXG4gICAgICAgICAgICAgICAgICAgIG1hcCgocmVzcG9uc2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmRhdGEuYXR0cmlidXRlcyAmJiByZXNwb25zZS5kYXRhLmF0dHJpYnV0ZXMuZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVbJ3VybCddID0gcmVzcG9uc2UuZGF0YS5hdHRyaWJ1dGVzLmRhdGEudXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBvcmFyeUZpbGVzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiByZXNwb25zZS5kYXRhLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IGZpbGUuc2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlOiBmaWxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmRhdGFbJ2xvYWRlZCddID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBvcmFyeUF0dGFjaG1lbnRzLnB1c2gocmVzcG9uc2UuZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgKSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFvYnNlcnZhYmxlcy5sZW5ndGggJiYgdW5hY2NlcHRlZEZpbGVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5UWVBFKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXHJcbiAgICAgICAgICAgICAgICBmb3JrSm9pbihvYnNlcnZhYmxlcykuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgIChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzLnB1c2goLi4udGVtcG9yYXJ5RmlsZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXRlbXNMaW1pdCA9PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKFsuLi50ZW1wb3JhcnlBdHRhY2htZW50c10pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZShbLi4udGVtcG9yYXJ5QXR0YWNobWVudHMsIC4uLnRoaXMubmF0aXZlVmFsdWVdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVVcGxvYWRlZC5lbWl0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVuYWNjZXB0ZWRGaWxlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5UWVBFKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlVXBsb2FkRmFpbC5lbWl0KGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGxvYWRGaWxlUHJldmlldyhhdHRhY2htZW50czogYW55KSB7XHJcbiAgICAgICAgaWYgKGF0dGFjaG1lbnRzICYmIGF0dGFjaG1lbnRzLmxlbmd0aCAmJiBhdHRhY2htZW50c1swXSkge1xyXG4gICAgICAgICAgICBsZXQgdGVtcG9yYXJ5UmVzb3VyY2UgPSBbXTtcclxuICAgICAgICAgICAgbGV0IG9ic2VydmFibGVzID0gW107XHJcblxyXG4gICAgICAgICAgICBhdHRhY2htZW50cy5mb3JFYWNoKGF0dGFjaG1lbnQgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCEoYXR0YWNobWVudCBpbnN0YW5jZW9mIEZpbGUpICYmICFhdHRhY2htZW50LmxvYWRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudFsnbG9hZGVkJ10gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmFibGVzLnB1c2godGhpcy5uZ3RBdHRhY2htZW50SHR0cFNlcnZpY2UudGh1bWJuYWlsKGF0dGFjaG1lbnQpLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgocmVzcG9uc2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcG9yYXJ5UmVzb3VyY2UucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHJlc3BvbnNlLmRhdGEuZ2V0QXBpSWQoKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlOiByZXNwb25zZS5kYXRhLmdldEF0dHJpYnV0ZSgnZmlsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcclxuICAgICAgICAgICAgICAgIGZvcmtKb2luKG9ic2VydmFibGVzKS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMucHVzaCguLi50ZW1wb3JhcnlSZXNvdXJjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25OYXRpdmVDaGFuZ2UoYXR0YWNobWVudHMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVByZXZpZXdMb2FkZWQuZW1pdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb25SZW1vdmUocmVzb3VyY2U6IGFueSkge1xyXG4gICAgICAgIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMuc3BsaWNlKHRoaXMudXBsb2FkZWRSZXNvdXJjZXMuaW5kZXhPZihyZXNvdXJjZSksIDEpO1xyXG4gICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSB0aGlzLm5hdGl2ZVZhbHVlLmZpbHRlcihlbGVtZW50ID0+IGVsZW1lbnQuaWQgIT0gcmVzb3VyY2UuaWQpO1xyXG4gICAgICAgIHRoaXMub25OYXRpdmVDaGFuZ2UodGhpcy5uYXRpdmVWYWx1ZSk7XHJcbiAgICAgICAgdGhpcy5vbkZpbGVSZW1vdmVkLmVtaXQocmVzb3VyY2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpc0ltYWdlKHJlc291cmNlOiBhbnkpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wcmV2aWV3VHlwZSA9PSAnSU1BR0UnXHJcbiAgICAgICAgICAgIHx8IChcclxuICAgICAgICAgICAgICAgIHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlXHJcbiAgICAgICAgICAgICAgICAmJiByZXNvdXJjZS5maWxlLnR5cGUuaW5jbHVkZXMoJ2ltYWdlJylcclxuICAgICAgICAgICAgICAgICYmICFyZXNvdXJjZS5maWxlLnR5cGUuaW5jbHVkZXMoJ2R3ZycpXHJcbiAgICAgICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzVmlkZW8ocmVzb3VyY2U6IGFueSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByZXZpZXdUeXBlID09ICdWSURFTycgfHwgKHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlICYmIHJlc291cmNlLmZpbGUudHlwZS5pbmNsdWRlcygndmlkZW8nKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzQXVkaW8ocmVzb3VyY2U6IGFueSkge1xyXG4gICAgICAgIHJldHVybiAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnR5cGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlLmluY2x1ZGVzKCdhdWRpbycpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgaXNGaWxlKHJlc291cmNlOiBhbnkpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMuaXNJbWFnZShyZXNvdXJjZSkgJiYgIXRoaXMuaXNBdWRpbyhyZXNvdXJjZSkgJiYgIXRoaXMuaXNWaWRlbyhyZXNvdXJjZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEZvcm1hdHRlZEZpbGVTaXplKHJlc291cmNlOiBhbnkpIHtcclxuICAgICAgICBpZiAocmVzb3VyY2UpIHtcclxuICAgICAgICAgICAgbGV0IHNpemUgPSByZXNvdXJjZS5zaXplIHx8IHJlc291cmNlLmZpbGVTaXplO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFzaXplKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICBzaXplID0gcmVzb3VyY2UuZmlsZS5zaXplO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzaXplID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHBhcnNlRmxvYXQoc2l6ZSkgPiAxMDAwMDAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHBhcnNlRmxvYXQoc2l6ZSkgLyAxMDAwMDAwKS50b0ZpeGVkKDIpICsgJyBNYic7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHBhcnNlRmxvYXQoc2l6ZSkgLyAxMDAwKSArICcgS2InO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb25OYXRpdmVDaGFuZ2UodmFsdWU6IGFueSkge1xyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5uYXRpdmVWYWx1ZSA9IFtdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChKU09OLnN0cmluZ2lmeSh0aGlzLnZhbHVlKSAhPSBKU09OLnN0cmluZ2lmeSh0aGlzLm5hdGl2ZVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubmF0aXZlVmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNoYW5nZSh2YWx1ZTogYW55KSB7XHJcbiAgICAgICAgaWYgKHZhbHVlICYmICF0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25OYXRpdmVDaGFuZ2UoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50UmVhZHkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZEZpbGVQcmV2aWV3KEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZG93bmxvYWRGaWxlKGF0dGFjaG1lbnQ6IGFueSkge1xyXG4gICAgICAgIHRoaXMubmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlLmRvd25sb2FkKGF0dGFjaG1lbnQpLnN1YnNjcmliZSgoKSA9PiB7IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZXNldCgpIHtcclxuICAgICAgICB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzID0gW107XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xyXG4gICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSBbXTtcclxuICAgICAgICB0aGlzLmluaXRDb21wb25lbnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb3BlbkZpbGVTZWxlY3RvcigpIHtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm5neEVsZW1lbnRJZCkuY2xpY2soKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGluaXRDb21wb25lbnQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudmlld01vZGUpIHtcclxuICAgICAgICAgICAgdGhpcy5wcmV2aWV3VHlwZSA9IE5ndERyb3B6b25lUHJldmlld1R5cGUuREVGQVVMVDtcclxuXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmZvcm1Db250YWluZXIgJiYgdGhpcy5mb3JtQ29udGFpbmVyLmNvbnRyb2xcclxuICAgICAgICAgICAgJiYgKHRoaXMuZm9ybUNvbnRyb2wgPSB0aGlzLmZvcm1Db250YWluZXIuY29udHJvbC5nZXQodGhpcy5uYW1lKSkpIHtcclxuICAgICAgICAgICAgdGhpcy5yZXNldEZpbGVzTG9hZCgpO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRGaWxlUHJldmlldyhBcnJheS5pc0FycmF5KHRoaXMudmFsdWUpID8gdGhpcy52YWx1ZSA6IFt0aGlzLnZhbHVlXSk7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVmFsaWRhdGlvbnMoKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc0RpcnR5KCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc1ByaXN0aW5lKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZXNldEZpbGVzTG9hZCgpIHtcclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLnZhbHVlKSkge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlLmZvckVhY2goZWxlbWVudCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbJ2xvYWRlZCddID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHVwZGF0ZVZhbGlkYXRpb25zKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5mb3JtQ29udHJvbCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgc3luY1ZhbGlkYXRvcnMgPSBbXTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNSZXF1aXJlZCkge1xyXG4gICAgICAgICAgICBzeW5jVmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMucmVxdWlyZWQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3luY1ZhbGlkYXRvcnMucHVzaCgpO1xyXG5cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRWYWxpZGF0b3JzKHN5bmNWYWxpZGF0b3JzKTtcclxuICAgICAgICAgICAgdGhpcy5mb3JtQ29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBkZXN0cm95U3Vic2NyaXB0aW9ucygpIHtcclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWJzY3JpcHRpb24gPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpO1xyXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IFtdO1xyXG4gICAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGgtZnVsbCB3LWZ1bGxcIiAjY29udGFpbmVyPlxyXG4gICAgPGxhYmVsICpuZ0lmPVwibGFiZWxcIiBjbGFzcz1cImZsZXggbWItMiB0ZXh0LXNtXCI+XHJcbiAgICAgICAge3sgbGFiZWwgfX06XHJcblxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1yZWQtNTAwIGZvbnQtYm9sZCB0ZXh0LW1kIG1sLTFcIiAqbmdJZj1cImlzUmVxdWlyZWRcIj4qPC9zcGFuPlxyXG5cclxuICAgICAgICA8bmd0LWhlbHBlciAqbmdJZj1cImhlbHBUZXh0XCIgW2hlbHBUaXRsZV09XCJoZWxwVGl0bGVcIiBbaWNvbkNvbG9yXT1cImhlbHBUZXh0Q29sb3JcIiBjbGFzcz1cIm1sLTFcIj5cclxuICAgICAgICAgICAge3sgaGVscFRleHQgfX1cclxuICAgICAgICA8L25ndC1oZWxwZXI+XHJcbiAgICA8L2xhYmVsPlxyXG5cclxuICAgIDxkaXYgKm5nSWY9XCIhdmlld01vZGVcIiBjbGFzcz1cImgtZnVsbCB3LWZ1bGwgcmVsYXRpdmVcIj5cclxuICAgICAgICA8ZGl2ICpuZ0lmPVwibG9hZGluZ1wiIGNsYXNzPVwiZmxleCBhYnNvbHV0ZSBqdXN0aWZ5LWNlbnRlciBpdGVtcy1jZW50ZXIgdy1mdWxsIGgtZnVsbCBjdXJzb3Itd2FpdCB6LTEwXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaXYtbG9hZGVyXCI+PC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxuZ3gtZHJvcHpvbmUgW2lkXT1cIm5neEVsZW1lbnRJZFwiIFttdWx0aXBsZV09J211bHRpcGxlU2VsZWN0aW9uJyBbbWF4RmlsZVNpemVdPSdtYXhGaWxlU2l6ZSdcclxuICAgICAgICAgICAgKGNoYW5nZSk9J29uU2VsZWN0KCRldmVudCknIFtjbGFzcy5zaW5nbGUtYXR0YWNobWVudF09J2l0ZW1zTGltaXQgPT0gMScgW2FjY2VwdF09J2FjY2VwdGVkRmlsZXMnXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09J2Rpc2FibGVkIHx8IGxvYWRpbmcnIFtleHBhbmRhYmxlXT0ndmVydGljYWxFeHBhbmRhYmxlJ1xyXG4gICAgICAgICAgICBbZGlzYWJsZUNsaWNrXT0nZGlzYWJsZUNsaWNrIHx8IGZvcmNlRGlzYWJsZUNsaWNrJyBbbmdTdHlsZV09XCJ7ICdoZWlnaHQnOiBkcm9wem9uZUhlaWdodCB9XCIgI25neERyb3B6b25lPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWxvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgIDxuZ3gtZHJvcHpvbmUtbGFiZWwgKm5nSWY9XCIhdXBsb2FkZWRSZXNvdXJjZXM/Lmxlbmd0aFwiIGNsYXNzPVwicHgtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7IHBsYWNlaG9sZGVyIH19XHJcbiAgICAgICAgICAgICAgICA8L25neC1kcm9wem9uZS1sYWJlbD5cclxuXHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByZXNvdXJjZSBvZiB1cGxvYWRlZFJlc291cmNlczsgbGV0IGluZGV4ID0gaW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCB3LTQ4IG14LTRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cInt7IHJlc291cmNlPy5maWxlPy5uYW1lIHx8ICcnIH19ICh7eyBnZXRGb3JtYXR0ZWRGaWxlU2l6ZShyZXNvdXJjZSkgfX0pXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjdXN0b20tZHJvcHpvbmUtcHJldmlldyAqbmdJZj1cInByZXZpZXdUeXBlID09ICdERUZBVUxUJyAmJiBpc0ZpbGUocmVzb3VyY2UpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaWxlXT0ncmVzb3VyY2UuZmlsZScgW3JlbW92YWJsZV09XCJyZW1vdmFibGVcIiAocmVtb3ZlZCk9XCJvblJlbW92ZShyZXNvdXJjZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRmlsZUNsaWNrKHJlc291cmNlLmZpbGUudXJsLCByZXNvdXJjZS5maWxlLm5hbWUsIHJlc291cmNlLmZpbGUuc2l6ZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmdQcm9qZWN0QXM9XCJuZ3gtZHJvcHpvbmUtcHJldmlld1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2N1c3RvbS1kcm9wem9uZS1wcmV2aWV3PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzSW1hZ2UocmVzb3VyY2UpXCIgY2xhc3M9XCJjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJpbWFnZVByZXZpZXcoaW5kZXgpXCIgI2dhbGxlcnk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmd4LWRyb3B6b25lLWltYWdlLXByZXZpZXcgY2xhc3M9XCJpbWFnZS1wcmV2aWV3LWRlZmF1bHQtY2xhc3NcIiBbZmlsZV09XCJyZXNvdXJjZS5maWxlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVtb3ZhYmxlXT1cInJlbW92YWJsZVwiIChyZW1vdmVkKT1cIm9uUmVtb3ZlKHJlc291cmNlKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtZHJvcHpvbmUtaW1hZ2UtcHJldmlldz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bmd4LWRyb3B6b25lLXZpZGVvLXByZXZpZXcgKm5nSWY9XCJpc1ZpZGVvKHJlc291cmNlKSB8fCBpc0F1ZGlvKHJlc291cmNlKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmlsZV09XCJyZXNvdXJjZS5maWxlXCIgW3JlbW92YWJsZV09XCJyZW1vdmFibGVcIiAocmVtb3ZlZCk9XCJvblJlbW92ZShyZXNvdXJjZSlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtZHJvcHpvbmUtdmlkZW8tcHJldmlldz5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwic2hvd0ZpbGVOYW1lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy1mdWxsIHRydW5jYXRlIHRleHQtZ3JheS01MDAgdGV4dC1jZW50ZXIgdGV4dC1zbSBmb250LW1vbm8gbXQtMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcmVzb3VyY2U/LmZpbGU/Lm5hbWUgfHwgJycgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9wPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvbmd4LWRyb3B6b25lPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPG5ndC1kcm9wem9uZS12aWV3ICpuZ0lmPVwidmlld01vZGVcIiBjbGFzcz1cImgtZnVsbCB3LWZ1bGxcIiBbcmVzb3VyY2VzXT1cInJlc291cmNlc1wiIFtsb2FkaW5nXT1cImxvYWRpbmdcIlxyXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiIFtkcm9wem9uZUhlaWdodF09XCJkcm9wem9uZUhlaWdodFwiXHJcbiAgICAgICAgKG9uRmlsZUNsaWNrKT1cIm9uRmlsZUNsaWNrKCRldmVudC5wcmV2aWV3VXJsLCAkZXZlbnQubmFtZSwgJGV2ZW50LmZpbGVTaXplKVwiXHJcbiAgICAgICAgKG9uSW1hZ2VDbGljayk9XCJvbkltYWdlQ2xpY2soJGV2ZW50LmRpdiwgJGV2ZW50LmluZGV4KVwiPlxyXG4gICAgPC9uZ3QtZHJvcHpvbmUtdmlldz5cclxuXHJcbiAgICA8bmd0LWRyb3B6b25lLWZpbGUtdmlld2VyIFtoaWRkZW5dPVwiIXNob3dOZ3REcm9wem9uZUZpbGVWaWV3ZXJcIiAob25DbG9zZSk9XCJmb3JjZURpc2FibGVDbGljayA9IGZhbHNlXCJcclxuICAgICAgICBbY2FuRG93bmxvYWRGaWxlXT1cImNhbkRvd25sb2FkRmlsZVwiIFtkaXNhYmxlQ29udGVudF09XCJjYW5Eb3dubG9hZEZpbGUgPyAnbm9uZScgOiAncG9wb3V0J1wiPlxyXG4gICAgPC9uZ3QtZHJvcHpvbmUtZmlsZS12aWV3ZXI+XHJcblxyXG4gICAgPGlucHV0ICpuZ0lmPSdjb21wb25lbnRSZWFkeScgdHlwZT1cImhpZGRlblwiIFtuZ01vZGVsXT1cInZhbHVlXCIgW25hbWVdPVwibmFtZVwiIFt2YWx1ZV09XCJ2YWx1ZVwiPlxyXG4gICAgPG5ndC12YWxpZGF0aW9uIFtjb250cm9sXT1cImZvcm1Db250cm9sXCIgW2NvbnRhaW5lcl09XCJmb3JtQ29udGFpbmVyXCI+PC9uZ3QtdmFsaWRhdGlvbj5cclxuPC9kaXY+Il19