ng-tailwind 2.24.310 → 2.24.314

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 (193) 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/bundles/ng-tailwind.umd.js +7318 -7271
  5. package/bundles/ng-tailwind.umd.js.map +1 -1
  6. package/components/ngt-action/ngt-action.component.d.ts +13 -13
  7. package/components/ngt-action/ngt-action.module.d.ts +2 -2
  8. package/components/ngt-button/ngt-button.component.d.ts +22 -22
  9. package/components/ngt-button/ngt-button.module.d.ts +2 -2
  10. package/components/ngt-checkbox/ngt-checkbox.component.d.ts +41 -41
  11. package/components/ngt-checkbox/ngt-checkbox.module.d.ts +2 -2
  12. package/components/ngt-content/ngt-content.component.d.ts +9 -9
  13. package/components/ngt-content/ngt-content.module.d.ts +2 -2
  14. package/components/ngt-datatable/ngt-datatable.component.d.ts +112 -112
  15. package/components/ngt-datatable/ngt-datatable.module.d.ts +2 -2
  16. package/components/ngt-datatable/ngt-tbody/ngt-tbody.component.d.ts +11 -11
  17. package/components/ngt-datatable/ngt-td/ngt-td.component.d.ts +11 -11
  18. package/components/ngt-datatable/ngt-td-check/ngt-td-check.component.d.ts +24 -24
  19. package/components/ngt-datatable/ngt-th/ngt-th.component.d.ts +47 -47
  20. package/components/ngt-datatable/ngt-th-check/ngt-th-check.component.d.ts +19 -19
  21. package/components/ngt-datatable/ngt-thead/ngt-thead.component.d.ts +10 -10
  22. package/components/ngt-datatable/ngt-tr/ngt-tr.component.d.ts +17 -17
  23. package/components/ngt-date/ngt-date.component.d.ts +71 -71
  24. package/components/ngt-date/ngt-date.module.d.ts +2 -2
  25. package/components/ngt-dropdown/ngt-dropdown-container/ngt-dropdown-container.component.d.ts +5 -5
  26. package/components/ngt-dropdown/ngt-dropdown.component.d.ts +42 -42
  27. package/components/ngt-dropdown/ngt-dropdown.module.d.ts +2 -2
  28. package/components/ngt-dropzone/custom-dropzone-preview/custom-dropzone-preview.component.d.ts +11 -11
  29. package/components/ngt-dropzone/ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component.d.ts +12 -12
  30. package/components/ngt-dropzone/ngt-dropzone-view/ngt-dropzone-view.component.d.ts +21 -21
  31. package/components/ngt-dropzone/ngt-dropzone.component.d.ts +103 -103
  32. package/components/ngt-dropzone/ngt-dropzone.module.d.ts +2 -2
  33. package/components/ngt-floating-button/ngt-floating-button.component.d.ts +32 -32
  34. package/components/ngt-floating-button/ngt-floating-button.module.d.ts +2 -2
  35. package/components/ngt-form/ngt-form-validation-message/ngt-form-validation-message.component.d.ts +7 -7
  36. package/components/ngt-form/ngt-form-validation-message/ngt-form-validation-message.module.d.ts +2 -2
  37. package/components/ngt-form/ngt-form.component.d.ts +52 -52
  38. package/components/ngt-form/ngt-form.module.d.ts +2 -2
  39. package/components/ngt-header-nav/ngt-header-nav.component.d.ts +11 -11
  40. package/components/ngt-header-nav/ngt-header-nav.module.d.ts +2 -2
  41. package/components/ngt-helper/ngt-helper.component.d.ts +15 -10
  42. package/components/ngt-helper/ngt-helper.module.d.ts +2 -2
  43. package/components/ngt-input/ngt-input.component.d.ts +92 -92
  44. package/components/ngt-input/ngt-input.module.d.ts +2 -2
  45. package/components/ngt-modal/ngt-modal-body/ngt-modal-body.component.d.ts +2 -2
  46. package/components/ngt-modal/ngt-modal-footer/ngt-modal-footer.component.d.ts +2 -2
  47. package/components/ngt-modal/ngt-modal-header/ngt-modal-header.component.d.ts +12 -12
  48. package/components/ngt-modal/ngt-modal.component.d.ts +19 -19
  49. package/components/ngt-modal/ngt-modal.module.d.ts +2 -2
  50. package/components/ngt-multi-select/ngt-multi-select.component.d.ts +97 -97
  51. package/components/ngt-multi-select/ngt-multi-select.module.d.ts +2 -2
  52. package/components/ngt-pagination/ngt-pagination.component.d.ts +40 -40
  53. package/components/ngt-pagination/ngt-pagination.module.d.ts +2 -2
  54. package/components/ngt-portlet/ngt-portlet-body/ngt-portlet-body.component.d.ts +9 -9
  55. package/components/ngt-portlet/ngt-portlet-footer/ngt-portlet-footer.component.d.ts +9 -9
  56. package/components/ngt-portlet/ngt-portlet-header/ngt-portlet-header.component.d.ts +14 -14
  57. package/components/ngt-portlet/ngt-portlet.component.d.ts +17 -17
  58. package/components/ngt-portlet/ngt-portlet.module.d.ts +2 -2
  59. package/components/ngt-radio-button/ngt-radio-button-container/ngt-radio-button-container.component.d.ts +6 -6
  60. package/components/ngt-radio-button/ngt-radio-button.component.d.ts +27 -27
  61. package/components/ngt-radio-button/ngt-radio-button.module.d.ts +2 -2
  62. package/components/ngt-section/ngt-section.component.d.ts +23 -23
  63. package/components/ngt-section/ngt-section.module.d.ts +2 -2
  64. package/components/ngt-select/ngt-select.component.d.ts +122 -122
  65. package/components/ngt-select/ngt-select.directive.d.ts +13 -13
  66. package/components/ngt-select/ngt-select.module.d.ts +2 -2
  67. package/components/ngt-shining/ngt-shining.component.d.ts +16 -16
  68. package/components/ngt-shining/ngt-shining.module.d.ts +2 -2
  69. package/components/ngt-sidenav/ngt-sidenav.component.d.ts +29 -29
  70. package/components/ngt-sidenav/ngt-sidenav.module.d.ts +2 -2
  71. package/components/ngt-slider/ngt-slider.component.d.ts +31 -31
  72. package/components/ngt-slider/ngt-slider.module.d.ts +2 -2
  73. package/components/ngt-svg/ngt-svg.component.d.ts +10 -10
  74. package/components/ngt-svg/ngt-svg.module.d.ts +2 -2
  75. package/components/ngt-tag/ngt-tag.component.d.ts +10 -10
  76. package/components/ngt-tag/ngt-tag.module.d.ts +2 -2
  77. package/components/ngt-textarea/ngt-textarea.component.d.ts +46 -46
  78. package/components/ngt-textarea/ngt-textarea.module.d.ts +2 -2
  79. package/components/ngt-validation/ngt-validation.component.d.ts +10 -10
  80. package/components/ngt-validation/ngt-validation.module.d.ts +2 -2
  81. package/directives/ngt-stylizable/ngt-stylizable.directive.d.ts +65 -63
  82. package/directives/ngt-stylizable/ngt-stylizable.module.d.ts +2 -2
  83. package/enums/size.enum.d.ts +8 -8
  84. package/esm2015/animations/ngt-angular-animations.js +34 -34
  85. package/esm2015/base/ngt-base-ng-model.js +90 -90
  86. package/esm2015/components/ngt-action/ngt-action.component.js +49 -49
  87. package/esm2015/components/ngt-action/ngt-action.module.js +19 -19
  88. package/esm2015/components/ngt-button/ngt-button.component.js +106 -106
  89. package/esm2015/components/ngt-button/ngt-button.module.js +19 -19
  90. package/esm2015/components/ngt-checkbox/ngt-checkbox.component.js +137 -137
  91. package/esm2015/components/ngt-checkbox/ngt-checkbox.module.js +19 -19
  92. package/esm2015/components/ngt-content/ngt-content.component.js +33 -33
  93. package/esm2015/components/ngt-content/ngt-content.module.js +15 -15
  94. package/esm2015/components/ngt-datatable/ngt-datatable.component.js +400 -400
  95. package/esm2015/components/ngt-datatable/ngt-datatable.module.js +58 -58
  96. package/esm2015/components/ngt-datatable/ngt-tbody/ngt-tbody.component.js +58 -60
  97. package/esm2015/components/ngt-datatable/ngt-td/ngt-td.component.js +63 -63
  98. package/esm2015/components/ngt-datatable/ngt-td-check/ngt-td-check.component.js +102 -102
  99. package/esm2015/components/ngt-datatable/ngt-th/ngt-th.component.js +192 -192
  100. package/esm2015/components/ngt-datatable/ngt-th-check/ngt-th-check.component.js +87 -87
  101. package/esm2015/components/ngt-datatable/ngt-thead/ngt-thead.component.js +56 -58
  102. package/esm2015/components/ngt-datatable/ngt-tr/ngt-tr.component.js +76 -76
  103. package/esm2015/components/ngt-date/ngt-date.component.js +354 -352
  104. package/esm2015/components/ngt-date/ngt-date.module.js +25 -25
  105. package/esm2015/components/ngt-dropdown/ngt-dropdown-container/ngt-dropdown-container.component.js +20 -20
  106. package/esm2015/components/ngt-dropdown/ngt-dropdown.component.js +165 -165
  107. package/esm2015/components/ngt-dropdown/ngt-dropdown.module.js +16 -16
  108. package/esm2015/components/ngt-dropzone/custom-dropzone-preview/custom-dropzone-preview.component.js +47 -47
  109. package/esm2015/components/ngt-dropzone/ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component.js +46 -45
  110. package/esm2015/components/ngt-dropzone/ngt-dropzone-view/ngt-dropzone-view.component.js +67 -67
  111. package/esm2015/components/ngt-dropzone/ngt-dropzone.component.js +411 -411
  112. package/esm2015/components/ngt-dropzone/ngt-dropzone.module.js +37 -37
  113. package/esm2015/components/ngt-floating-button/ngt-floating-button.component.js +94 -94
  114. package/esm2015/components/ngt-floating-button/ngt-floating-button.module.js +19 -19
  115. package/esm2015/components/ngt-form/ngt-form-validation-message/ngt-form-validation-message.component.js +23 -23
  116. package/esm2015/components/ngt-form/ngt-form-validation-message/ngt-form-validation-message.module.js +15 -15
  117. package/esm2015/components/ngt-form/ngt-form.component.js +181 -181
  118. package/esm2015/components/ngt-form/ngt-form.module.js +17 -17
  119. package/esm2015/components/ngt-header-nav/ngt-header-nav.component.js +38 -38
  120. package/esm2015/components/ngt-header-nav/ngt-header-nav.module.js +15 -15
  121. package/esm2015/components/ngt-helper/ngt-helper.component.js +44 -24
  122. package/esm2015/components/ngt-helper/ngt-helper.module.js +19 -19
  123. package/esm2015/components/ngt-input/ngt-input.component.js +610 -608
  124. package/esm2015/components/ngt-input/ngt-input.module.js +28 -28
  125. package/esm2015/components/ngt-modal/ngt-modal-body/ngt-modal-body.component.js +11 -11
  126. package/esm2015/components/ngt-modal/ngt-modal-footer/ngt-modal-footer.component.js +11 -11
  127. package/esm2015/components/ngt-modal/ngt-modal-header/ngt-modal-header.component.js +40 -40
  128. package/esm2015/components/ngt-modal/ngt-modal.component.js +79 -79
  129. package/esm2015/components/ngt-modal/ngt-modal.module.js +28 -28
  130. package/esm2015/components/ngt-multi-select/ngt-multi-select.component.js +392 -392
  131. package/esm2015/components/ngt-multi-select/ngt-multi-select.module.js +33 -33
  132. package/esm2015/components/ngt-pagination/ngt-pagination.component.js +172 -172
  133. package/esm2015/components/ngt-pagination/ngt-pagination.module.js +23 -23
  134. package/esm2015/components/ngt-portlet/ngt-portlet-body/ngt-portlet-body.component.js +32 -32
  135. package/esm2015/components/ngt-portlet/ngt-portlet-footer/ngt-portlet-footer.component.js +33 -33
  136. package/esm2015/components/ngt-portlet/ngt-portlet-header/ngt-portlet-header.component.js +47 -45
  137. package/esm2015/components/ngt-portlet/ngt-portlet.component.js +58 -58
  138. package/esm2015/components/ngt-portlet/ngt-portlet.module.js +32 -32
  139. package/esm2015/components/ngt-radio-button/ngt-radio-button-container/ngt-radio-button-container.component.js +19 -19
  140. package/esm2015/components/ngt-radio-button/ngt-radio-button.component.js +97 -97
  141. package/esm2015/components/ngt-radio-button/ngt-radio-button.module.js +18 -18
  142. package/esm2015/components/ngt-section/ngt-section.component.js +98 -98
  143. package/esm2015/components/ngt-section/ngt-section.module.js +21 -21
  144. package/esm2015/components/ngt-select/ngt-select.component.js +467 -465
  145. package/esm2015/components/ngt-select/ngt-select.directive.js +35 -35
  146. package/esm2015/components/ngt-select/ngt-select.module.js +40 -40
  147. package/esm2015/components/ngt-shining/ngt-shining.component.js +41 -41
  148. package/esm2015/components/ngt-shining/ngt-shining.module.js +15 -15
  149. package/esm2015/components/ngt-sidenav/ngt-sidenav.component.js +123 -123
  150. package/esm2015/components/ngt-sidenav/ngt-sidenav.module.js +15 -15
  151. package/esm2015/components/ngt-slider/ngt-slider.component.js +82 -82
  152. package/esm2015/components/ngt-slider/ngt-slider.module.js +17 -17
  153. package/esm2015/components/ngt-svg/ngt-svg.component.js +52 -52
  154. package/esm2015/components/ngt-svg/ngt-svg.module.js +19 -19
  155. package/esm2015/components/ngt-tag/ngt-tag.component.js +36 -36
  156. package/esm2015/components/ngt-tag/ngt-tag.module.js +17 -17
  157. package/esm2015/components/ngt-textarea/ngt-textarea.component.js +211 -209
  158. package/esm2015/components/ngt-textarea/ngt-textarea.module.js +24 -24
  159. package/esm2015/components/ngt-validation/ngt-validation.component.js +24 -24
  160. package/esm2015/components/ngt-validation/ngt-validation.module.js +15 -15
  161. package/esm2015/directives/ngt-stylizable/ngt-stylizable.directive.js +227 -220
  162. package/esm2015/directives/ngt-stylizable/ngt-stylizable.module.js +15 -15
  163. package/esm2015/enums/size.enum.js +11 -11
  164. package/esm2015/helpers/enum/enum.js +7 -7
  165. package/esm2015/helpers/form/form.js +14 -14
  166. package/esm2015/helpers/routing/route.js +11 -11
  167. package/esm2015/helpers/uuid.js +10 -10
  168. package/esm2015/ng-tailwind.js +10 -10
  169. package/esm2015/public-api.js +117 -117
  170. package/esm2015/services/http/ngt-attachment-http.service.js +3 -3
  171. package/esm2015/services/http/ngt-http-form.service.js +3 -3
  172. package/esm2015/services/http/ngt-http-resource.service.js +3 -3
  173. package/esm2015/services/http/ngt-http-validation.service.js +4 -4
  174. package/esm2015/services/http/ngt-http.service.js +3 -3
  175. package/esm2015/services/http/ngt-translate.service.js +3 -3
  176. package/esm2015/services/ngt-stylizable/ngt-stylizable.service.js +273 -266
  177. package/fesm2015/ng-tailwind.js +6404 -6365
  178. package/fesm2015/ng-tailwind.js.map +1 -1
  179. package/helpers/enum/enum.d.ts +1 -1
  180. package/helpers/form/form.d.ts +4 -4
  181. package/helpers/routing/route.d.ts +2 -2
  182. package/helpers/uuid.d.ts +1 -1
  183. package/ng-tailwind.d.ts +10 -10
  184. package/ng-tailwind.metadata.json +1 -1
  185. package/package.json +1 -1
  186. package/public-api.d.ts +80 -80
  187. package/services/http/ngt-attachment-http.service.d.ts +10 -10
  188. package/services/http/ngt-http-form.service.d.ts +5 -5
  189. package/services/http/ngt-http-resource.service.d.ts +12 -12
  190. package/services/http/ngt-http-validation.service.d.ts +10 -10
  191. package/services/http/ngt-http.service.d.ts +27 -27
  192. package/services/http/ngt-translate.service.d.ts +27 -27
  193. package/services/ngt-stylizable/ngt-stylizable.service.d.ts +96 -93
@@ -1,411 +1,411 @@
1
- import { __awaiter } from "tslib";
2
- import { ChangeDetectorRef, Component, EventEmitter, Host, Injector, Input, Optional, Output, SkipSelf, ViewChild, ViewEncapsulation, } from '@angular/core';
3
- import { ControlContainer, NgForm, Validators } from '@angular/forms';
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 { NgtAttachmentHttpService } from '../../services/http/ngt-attachment-http.service';
10
- import { NgtStylizableService } from '../../services/ngt-stylizable/ngt-stylizable.service';
11
- import { NgtDropzoneFileViewerComponent } from './ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component';
12
- ;
13
- export var NgtDropzoneFileTypeEnum;
14
- (function (NgtDropzoneFileTypeEnum) {
15
- NgtDropzoneFileTypeEnum["DOC"] = "DOC";
16
- NgtDropzoneFileTypeEnum["PDF"] = "PDF";
17
- NgtDropzoneFileTypeEnum["XLS"] = "XLS";
18
- NgtDropzoneFileTypeEnum["OTHER"] = "OTHER";
19
- })(NgtDropzoneFileTypeEnum || (NgtDropzoneFileTypeEnum = {}));
20
- export var NgtDropzonePreviewType;
21
- (function (NgtDropzonePreviewType) {
22
- NgtDropzonePreviewType["DEFAULT"] = "DEFAULT";
23
- NgtDropzonePreviewType["IMAGE"] = "IMAGE";
24
- NgtDropzonePreviewType["VIDEO"] = "VIDEO";
25
- })(NgtDropzonePreviewType || (NgtDropzonePreviewType = {}));
26
- export var NgtDropzoneErrorType;
27
- (function (NgtDropzoneErrorType) {
28
- NgtDropzoneErrorType["DEFAULT"] = "DEFAULT";
29
- NgtDropzoneErrorType["SIZE"] = "SIZE";
30
- NgtDropzoneErrorType["NO_MULTIPLE"] = "NO_MULTIPLE";
31
- NgtDropzoneErrorType["ITEMS_LIMIT"] = "ITEMS_LIMIT";
32
- NgtDropzoneErrorType["TYPE"] = "TYPE";
33
- })(NgtDropzoneErrorType || (NgtDropzoneErrorType = {}));
34
- export class NgtDropzoneComponent extends NgtBaseNgModel {
35
- constructor(formContainer, ngtAttachmentHttpService, injector, changeDetector) {
36
- super();
37
- this.formContainer = formContainer;
38
- this.ngtAttachmentHttpService = ngtAttachmentHttpService;
39
- this.injector = injector;
40
- this.changeDetector = changeDetector;
41
- this.helpTextColor = 'text-green-500';
42
- // Behavior
43
- this.resources = [];
44
- this.multipleSelection = false;
45
- this.showFileName = false;
46
- this.disableClick = false;
47
- this.disabled = false;
48
- this.viewMode = false;
49
- this.removable = false;
50
- this.verticalExpandable = false;
51
- this.acceptedFiles = '*' /** Mime type */;
52
- this.previewType = NgtDropzonePreviewType.DEFAULT;
53
- this.isRequired = false;
54
- this.onFileSelected = new EventEmitter();
55
- this.onFileSelectError = new EventEmitter();
56
- this.onFileUploadFail = new EventEmitter();
57
- this.onFileRemoved = new EventEmitter();
58
- this.onFileUploaded = new EventEmitter();
59
- this.onFilePreviewLoaded = new EventEmitter();
60
- this.dropzoneHeight = '180px';
61
- this.uploadedResources = [];
62
- this.forceDisableClick = false;
63
- this.nativeValue = [];
64
- this.showNgtDropzoneFileViewer = false;
65
- this.componentReady = false;
66
- this.loading = false;
67
- this.imageViewerOptions = {
68
- navbar: true,
69
- toolbar: {
70
- zoomIn: true,
71
- zoomOut: true,
72
- reset: true,
73
- rotateLeft: true,
74
- rotateRight: true,
75
- prev: true,
76
- next: true,
77
- }
78
- };
79
- this.subscriptions = [];
80
- this.ngtDropzoneLoaderStyle = new NgtStylizableService();
81
- this.ngtDropzoneLoaderStyle.load(this.injector, 'NgtDropzoneLoader', {
82
- h: 'h-8',
83
- color: {
84
- text: 'text-gray-600'
85
- }
86
- });
87
- }
88
- ngOnChanges(changes) {
89
- if (changes.previewType) {
90
- this.previewType = getEnumFromString(changes.previewType.currentValue, NgtDropzonePreviewType);
91
- }
92
- }
93
- ngAfterContentChecked() {
94
- if (this.container && this.container.nativeElement) {
95
- this.dropzoneHeight = `${this.container.nativeElement.parentElement.offsetHeight}px`;
96
- this.changeDetector.detectChanges();
97
- }
98
- }
99
- ngOnInit() {
100
- setTimeout(() => {
101
- this.componentReady = true;
102
- setTimeout(() => {
103
- this.initComponent();
104
- });
105
- }, 500);
106
- }
107
- ngOnDestroy() {
108
- this.destroySubscriptions();
109
- }
110
- onImageClick(element, index) {
111
- if (!this.viewMode) {
112
- this.forceDisableClick = true;
113
- }
114
- const ngtDropzoneComponent = this;
115
- if (index) {
116
- this.imageViewerOptions = Object.assign(Object.assign({}, this.imageViewerOptions), { initialViewIndex: index });
117
- }
118
- const viewer = new Viewer(element, Object.assign(Object.assign({}, this.imageViewerOptions), {
119
- hidden() {
120
- ngtDropzoneComponent.forceDisableClick = false;
121
- viewer.destroy();
122
- }
123
- }));
124
- viewer.show();
125
- }
126
- onFileClick(url, name) {
127
- this.forceDisableClick = true;
128
- this.showNgtDropzoneFileViewer = true;
129
- this.ngtDropzoneFileViewer.url = url;
130
- this.ngtDropzoneFileViewer.fileName = name;
131
- this.ngtDropzoneFileViewer.init();
132
- this.subscriptions.push(this.ngtDropzoneFileViewer.onClose.subscribe(() => {
133
- this.showNgtDropzoneFileViewer = false;
134
- this.forceDisableClick = false;
135
- }));
136
- }
137
- onSelect(event) {
138
- return __awaiter(this, void 0, void 0, function* () {
139
- if (event.rejectedFiles.length) {
140
- for (const rejectedFile of event.rejectedFiles) {
141
- if (rejectedFile.reason == 'size') {
142
- this.onFileSelectError.emit(NgtDropzoneErrorType.SIZE);
143
- break;
144
- }
145
- else if (rejectedFile.reason == 'no_multiple') {
146
- this.onFileSelectError.emit(NgtDropzoneErrorType.NO_MULTIPLE);
147
- break;
148
- }
149
- else if (rejectedFile.reason == 'type') {
150
- this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
151
- break;
152
- }
153
- else {
154
- this.onFileSelectError.emit(NgtDropzoneErrorType.DEFAULT);
155
- break;
156
- }
157
- }
158
- }
159
- if (this.itemsLimit) {
160
- if (this.itemsLimit == 1 && event.addedFiles
161
- && event.addedFiles.length == this.itemsLimit && this.uploadedResources.length == this.itemsLimit) {
162
- this.uploadedResources = [];
163
- }
164
- if (event.addedFiles
165
- && event.addedFiles.length + this.uploadedResources.length <= this.itemsLimit) {
166
- this.onFileSelected.emit(event);
167
- this.uploadFiles(event.addedFiles);
168
- }
169
- else {
170
- this.onFileSelectError.emit(NgtDropzoneErrorType.ITEMS_LIMIT);
171
- }
172
- }
173
- else {
174
- this.onFileSelected.emit(event);
175
- this.uploadFiles(event.addedFiles);
176
- }
177
- });
178
- }
179
- uploadFiles(files) {
180
- return __awaiter(this, void 0, void 0, function* () {
181
- if (files && files.length) {
182
- let temporaryFiles = [];
183
- let temporaryAttachments = [];
184
- let observables = [];
185
- this.loading = true;
186
- files.forEach(file => {
187
- observables.push(this.ngtAttachmentHttpService.upload(this.remoteResource, file).pipe(map((response) => {
188
- if (response && response.data) {
189
- if (response.data.attributes && response.data.attributes.data) {
190
- file['url'] = response.data.attributes.data.url;
191
- }
192
- temporaryFiles.push({
193
- id: response.data.id,
194
- size: file.size,
195
- file: file
196
- });
197
- response.data['loaded'] = true;
198
- temporaryAttachments.push(response.data);
199
- }
200
- })));
201
- });
202
- this.subscriptions.push(forkJoin(observables).subscribe((response) => {
203
- this.uploadedResources.push(...temporaryFiles);
204
- if (this.itemsLimit == 1) {
205
- this.onNativeChange([...temporaryAttachments]);
206
- }
207
- else {
208
- this.onNativeChange([...temporaryAttachments, ...this.nativeValue]);
209
- }
210
- this.onFileUploaded.emit();
211
- this.loading = false;
212
- }, (error) => {
213
- this.onFileUploadFail.emit(error);
214
- this.loading = false;
215
- }));
216
- }
217
- });
218
- }
219
- loadFilePreview(attachments) {
220
- return __awaiter(this, void 0, void 0, function* () {
221
- if (attachments && attachments.length && attachments[0]) {
222
- let temporaryResource = [];
223
- let observables = [];
224
- attachments.forEach(attachment => {
225
- if (!(attachment instanceof File) && !attachment.loaded) {
226
- this.loading = true;
227
- attachment['loaded'] = true;
228
- observables.push(this.ngtAttachmentHttpService.thumbnail(attachment).pipe(map((response) => {
229
- temporaryResource.push({
230
- id: response.data.getApiId(),
231
- file: response.data.getAttribute('file')
232
- });
233
- })));
234
- }
235
- });
236
- this.subscriptions.push(forkJoin(observables).subscribe((response) => {
237
- this.uploadedResources.push(...temporaryResource);
238
- this.onNativeChange(attachments);
239
- this.onFilePreviewLoaded.emit();
240
- this.loading = false;
241
- }, (error) => {
242
- this.loading = false;
243
- }));
244
- }
245
- });
246
- }
247
- onRemove(resource) {
248
- this.uploadedResources.splice(this.uploadedResources.indexOf(resource), 1);
249
- this.nativeValue = this.nativeValue.filter(element => element.id != resource.id);
250
- this.onNativeChange(this.nativeValue);
251
- this.onFileRemoved.emit(resource);
252
- }
253
- isImage(resource) {
254
- return this.previewType == 'IMAGE' || (resource.file && resource.file.type && resource.file.type.includes('image'));
255
- }
256
- isVideo(resource) {
257
- return this.previewType == 'VIDEO' || (resource.file && resource.file.type && resource.file.type.includes('video'));
258
- }
259
- isAudio(resource) {
260
- return (resource.file && resource.file.type && resource.file.type.includes('audio'));
261
- }
262
- isFile(resource) {
263
- return !this.isImage(resource) && !this.isAudio(resource) && !this.isVideo(resource);
264
- }
265
- getFormattedFileSize(resource) {
266
- if (resource) {
267
- let size = resource.size || resource.fileSize;
268
- if (!size) {
269
- if (resource.file && resource.file.size) {
270
- size = resource.file.size;
271
- }
272
- else {
273
- size = 0;
274
- }
275
- }
276
- if (parseFloat(size) > 1000000) {
277
- return (parseFloat(size) / 1000000).toFixed(2) + ' Mb';
278
- }
279
- return Math.round(parseFloat(size) / 1000) + ' Kb';
280
- }
281
- }
282
- onNativeChange(value) {
283
- if (value === undefined) {
284
- this.value = [];
285
- this.nativeValue = [];
286
- }
287
- else {
288
- this.nativeValue = value;
289
- if (JSON.stringify(this.value) != JSON.stringify(this.nativeValue)) {
290
- this.value = this.nativeValue;
291
- }
292
- }
293
- }
294
- change(value) {
295
- if (value && !this.viewMode) {
296
- this.onNativeChange(Array.isArray(value) ? value : [value]);
297
- if (this.componentReady) {
298
- this.loadFilePreview(Array.isArray(value) ? value : [value]);
299
- }
300
- }
301
- }
302
- downloadFile(attachment) {
303
- this.ngtAttachmentHttpService.download(attachment).subscribe(() => { });
304
- }
305
- reset() {
306
- this.uploadedResources = [];
307
- this.value = [];
308
- this.nativeValue = [];
309
- this.initComponent();
310
- }
311
- openFileSelector() {
312
- document.getElementById('ngxDropzone').click();
313
- }
314
- initComponent() {
315
- if (this.viewMode) {
316
- this.previewType = NgtDropzonePreviewType.DEFAULT;
317
- return;
318
- }
319
- if (this.formContainer && this.formContainer.control
320
- && (this.formControl = this.formContainer.control.get(this.name))) {
321
- this.resetFilesLoad();
322
- this.loadFilePreview(Array.isArray(this.value) ? this.value : [this.value]);
323
- this.updateValidations();
324
- if (this.value) {
325
- this.formControl.markAsDirty();
326
- }
327
- else {
328
- this.formControl.markAsPristine();
329
- }
330
- }
331
- }
332
- resetFilesLoad() {
333
- if (Array.isArray(this.value)) {
334
- this.value.forEach(element => {
335
- if (element) {
336
- element['loaded'] = false;
337
- }
338
- });
339
- }
340
- }
341
- updateValidations() {
342
- if (!this.formControl) {
343
- return;
344
- }
345
- let syncValidators = [];
346
- if (this.isRequired) {
347
- syncValidators.push(Validators.required);
348
- }
349
- syncValidators.push();
350
- setTimeout(() => {
351
- this.formControl.setValidators(syncValidators);
352
- this.formControl.updateValueAndValidity();
353
- });
354
- }
355
- destroySubscriptions() {
356
- this.subscriptions.forEach(subscription => subscription.unsubscribe());
357
- this.subscriptions = [];
358
- }
359
- }
360
- NgtDropzoneComponent.decorators = [
361
- { type: Component, args: [{
362
- selector: 'ngt-dropzone',
363
- 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=\"ngxDropzone\" [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\">\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)\"\n ngProjectAs=\"ngx-dropzone-preview\">\n </custom-dropzone-preview>\n\n <div *ngIf=\"isImage(resource)\" class=\"cursor-pointer\" (click)=\"onImageClick(gallery)\" #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\" [resources]=\"resources\" class=\"h-full w-full\"></ngt-dropzone-view>\n\n <ngt-dropzone-file-viewer [hidden]=\"!showNgtDropzoneFileViewer\" (onClose)=\"forceDisableClick = false\">\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>",
364
- encapsulation: ViewEncapsulation.None,
365
- providers: [
366
- NgtMakeProvider(NgtDropzoneComponent),
367
- ],
368
- viewProviders: [
369
- { provide: ControlContainer, useExisting: NgForm }
370
- ],
371
- styles: [".single-attachment{border:none!important;overflow:hidden!important;display:flex!important;justify-content:center!important}.image-preview-default-class,.single-attachment{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%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}"]
372
- },] }
373
- ];
374
- NgtDropzoneComponent.ctorParameters = () => [
375
- { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }] },
376
- { type: NgtAttachmentHttpService, decorators: [{ type: Optional }, { type: SkipSelf }] },
377
- { type: Injector },
378
- { type: ChangeDetectorRef }
379
- ];
380
- NgtDropzoneComponent.propDecorators = {
381
- container: [{ type: ViewChild, args: ['container',] }],
382
- ngxDropzone: [{ type: ViewChild, args: ['ngxDropzone', { static: true },] }],
383
- ngtDropzoneFileViewer: [{ type: ViewChild, args: [NgtDropzoneFileViewerComponent, { static: true },] }],
384
- label: [{ type: Input }],
385
- placeholder: [{ type: Input }],
386
- helpTextColor: [{ type: Input }],
387
- helpText: [{ type: Input }],
388
- helpTitle: [{ type: Input }],
389
- resources: [{ type: Input }],
390
- multipleSelection: [{ type: Input }],
391
- itemsLimit: [{ type: Input }],
392
- showFileName: [{ type: Input }],
393
- disableClick: [{ type: Input }],
394
- disabled: [{ type: Input }],
395
- viewMode: [{ type: Input }],
396
- removable: [{ type: Input }],
397
- verticalExpandable: [{ type: Input }],
398
- acceptedFiles: [{ type: Input }],
399
- maxFileSize: [{ type: Input }],
400
- previewType: [{ type: Input }],
401
- isRequired: [{ type: Input }],
402
- name: [{ type: Input }],
403
- remoteResource: [{ type: Input }],
404
- onFileSelected: [{ type: Output }],
405
- onFileSelectError: [{ type: Output }],
406
- onFileUploadFail: [{ type: Output }],
407
- onFileRemoved: [{ type: Output }],
408
- onFileUploaded: [{ type: Output }],
409
- onFilePreviewLoaded: [{ type: Output }]
410
- };
411
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd0LWRyb3B6b25lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhaWx3aW5kL3NyYy9jb21wb25lbnRzL25ndC1kcm9wem9uZS9uZ3QtZHJvcHpvbmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBRUgsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVCxZQUFZLEVBQ1osSUFBSSxFQUNKLFFBQVEsRUFDUixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sRUFFTixRQUFRLEVBQ1IsU0FBUyxFQUNULGlCQUFpQixHQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRFLE9BQU8sRUFBRSxRQUFRLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLE1BQU0sTUFBTSxVQUFVLENBQUM7QUFFOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUMzRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUM1RixPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSwrREFBK0QsQ0FBQztBQVM5RyxDQUFDO0FBRUYsTUFBTSxDQUFOLElBQVksdUJBS1g7QUFMRCxXQUFZLHVCQUF1QjtJQUMvQixzQ0FBVyxDQUFBO0lBQ1gsc0NBQVcsQ0FBQTtJQUNYLHNDQUFXLENBQUE7SUFDWCwwQ0FBZSxDQUFBO0FBQ25CLENBQUMsRUFMVyx1QkFBdUIsS0FBdkIs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Q0FDTCxLQUFLOzRCQUNMLEtBQUs7MEJBQ0wsS0FBSzswQkFDTCxLQUFLO3lCQUNMLEtBQUs7bUJBQ0wsS0FBSzs2QkFDTCxLQUFLOzZCQUVMLE1BQU07Z0NBQ04sTUFBTTsrQkFDTixNQUFNOzRCQUNOLE1BQU07NkJBQ04sTUFBTTtrQ0FDTixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBBZnRlckNvbnRlbnRDaGVja2VkLFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBIb3N0LFxuICAgIEluamVjdG9yLFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgT3B0aW9uYWwsXG4gICAgT3V0cHV0LFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgU2tpcFNlbGYsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xDb250YWluZXIsIE5nRm9ybSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE5neERyb3B6b25lQ2hhbmdlRXZlbnQsIE5neERyb3B6b25lQ29tcG9uZW50IH0gZnJvbSAnbmd4LWRyb3B6b25lJztcbmltcG9ydCB7IGZvcmtKb2luLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCBWaWV3ZXIgZnJvbSAndmlld2VyanMnO1xuXG5pbXBvcnQgeyBOZ3RCYXNlTmdNb2RlbCwgTmd0TWFrZVByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vYmFzZS9uZ3QtYmFzZS1uZy1tb2RlbCc7XG5pbXBvcnQgeyBnZXRFbnVtRnJvbVN0cmluZyB9IGZyb20gJy4uLy4uL2hlbHBlcnMvZW51bS9lbnVtJztcbmltcG9ydCB7IE5ndEF0dGFjaG1lbnRIdHRwU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2h0dHAvbmd0LWF0dGFjaG1lbnQtaHR0cC5zZXJ2aWNlJztcbmltcG9ydCB7IE5ndFN0eWxpemFibGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbmd0LXN0eWxpemFibGUvbmd0LXN0eWxpemFibGUuc2VydmljZSc7XG5pbXBvcnQgeyBOZ3REcm9wem9uZUZpbGVWaWV3ZXJDb21wb25lbnQgfSBmcm9tICcuL25ndC1kcm9wem9uZS1maWxlLXZpZXdlci9uZ3QtZHJvcHpvbmUtZmlsZS12aWV3ZXIuY29tcG9uZW50JztcblxuZXhwb3J0IGludGVyZmFjZSBOZ3REcm9wem9uZUZpbGUge1xuICAgIGRvd25sb2FkVXJsOiBzdHJpbmc7XG4gICAgcHJldmlld1VybDogc3RyaW5nO1xuICAgIHRodW1ibmFpbFVybDogc3RyaW5nO1xuICAgIG5hbWU6IHN0cmluZztcbiAgICBtaW1lVHlwZTogc3RyaW5nO1xuICAgIGZpbGVTaXplOiBhbnk7XG59O1xuXG5leHBvcnQgZW51bSBOZ3REcm9wem9uZUZpbGVUeXBlRW51bSB7XG4gICAgRE9DID0gJ0RPQycsXG4gICAgUERGID0gJ1BERicsXG4gICAgWExTID0gJ1hMUycsXG4gICAgT1RIRVIgPSAnT1RIRVInXG59XG5cbmV4cG9ydCBlbnVtIE5ndERyb3B6b25lUHJldmlld1R5cGUge1xuICAgIERFRkFVTFQgPSAnREVGQVVMVCcsXG4gICAgSU1BR0UgPSAnSU1BR0UnLFxuICAgIFZJREVPID0gJ1ZJREVPJ1xufVxuXG5leHBvcnQgZW51bSBOZ3REcm9wem9uZUVycm9yVHlwZSB7XG4gICAgREVGQVVMVCA9ICdERUZBVUxUJyxcbiAgICBTSVpFID0gJ1NJWkUnLFxuICAgIE5PX01VTFRJUExFID0gJ05PX01VTFRJUExFJyxcbiAgICBJVEVNU19MSU1JVCA9ICdJVEVNU19MSU1JVCcsXG4gICAgVFlQRSA9ICdUWVBFJ1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25ndC1kcm9wem9uZScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL25ndC1kcm9wem9uZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vbmd0LWRyb3B6b25lLmNvbXBvbmVudC5jc3MnXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICBOZ3RNYWtlUHJvdmlkZXIoTmd0RHJvcHpvbmVDb21wb25lbnQpLFxuICAgIF0sXG4gICAgdmlld1Byb3ZpZGVyczogW1xuICAgICAgICB7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBOZ0Zvcm0gfVxuICAgIF1cbn0pXG5leHBvcnQgY2xhc3MgTmd0RHJvcHpvbmVDb21wb25lbnQgZXh0ZW5kcyBOZ3RCYXNlTmdNb2RlbCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlckNvbnRlbnRDaGVja2VkIHtcbiAgICBAVmlld0NoaWxkKCdjb250YWluZXInKSBwdWJsaWMgY29udGFpbmVyOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoJ25neERyb3B6b25lJywgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIG5neERyb3B6b25lOiBOZ3hEcm9wem9uZUNvbXBvbmVudDtcbiAgICBAVmlld0NoaWxkKE5ndERyb3B6b25lRmlsZVZpZXdlckNvbXBvbmVudCwgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIG5ndERyb3B6b25lRmlsZVZpZXdlcjogTmd0RHJvcHpvbmVGaWxlVmlld2VyQ29tcG9uZW50O1xuXG4gICAgLy8gVmlzdWFsXG4gICAgQElucHV0KCkgcHVibGljIGxhYmVsOiBzdHJpbmc7XG4gICAgQElucHV0KCkgcHVibGljIHBsYWNlaG9sZGVyOiBzdHJpbmc7XG4gICAgQElucHV0KCkgcHVibGljIGhlbHBUZXh0Q29sb3I6IHN0cmluZyA9ICd0ZXh0LWdyZWVuLTUwMCc7XG4gICAgQElucHV0KCkgcHVibGljIGhlbHBUZXh0OiBzdHJpbmc7XG4gICAgQElucHV0KCkgcHVibGljIGhlbHBUaXRsZTogc3RyaW5nO1xuXG4gICAgLy8gQmVoYXZpb3JcbiAgICBASW5wdXQoKSBwdWJsaWMgcmVzb3VyY2VzOiBBcnJheTxOZ3REcm9wem9uZUZpbGU+ID0gW107XG4gICAgQElucHV0KCkgcHVibGljIG11bHRpcGxlU2VsZWN0aW9uOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgcHVibGljIGl0ZW1zTGltaXQ6IG51bWJlcjtcbiAgICBASW5wdXQoKSBwdWJsaWMgc2hvd0ZpbGVOYW1lOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgcHVibGljIGRpc2FibGVDbGljazogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHB1YmxpYyB2aWV3TW9kZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHB1YmxpYyByZW1vdmFibGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBwdWJsaWMgdmVydGljYWxFeHBhbmRhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgcHVibGljIGFjY2VwdGVkRmlsZXM6IHN0cmluZyA9ICcqJyAvKiogTWltZSB0eXBlICovO1xuICAgIEBJbnB1dCgpIHB1YmxpYyBtYXhGaWxlU2l6ZTogbnVtYmVyOyAvKiogQnl0ZXMgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgcHJldmlld1R5cGU6IE5ndERyb3B6b25lUHJldmlld1R5cGUgPSBOZ3REcm9wem9uZVByZXZpZXdUeXBlLkRFRkFVTFQ7XG4gICAgQElucHV0KCkgcHVibGljIGlzUmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBwdWJsaWMgbmFtZTogc3RyaW5nO1xuICAgIEBJbnB1dCgpIHB1YmxpYyByZW1vdGVSZXNvdXJjZTogYW55O1xuXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVTZWxlY3RlZDogRXZlbnRFbWl0dGVyPE5neERyb3B6b25lQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlU2VsZWN0RXJyb3I6IEV2ZW50RW1pdHRlcjxOZ3REcm9wem9uZUVycm9yVHlwZT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVVcGxvYWRGYWlsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVJlbW92ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVVcGxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVByZXZpZXdMb2FkZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICBwdWJsaWMgZHJvcHpvbmVIZWlnaHQ6IHN0cmluZyA9ICcxODBweCc7XG4gICAgcHVibGljIHVwbG9hZGVkUmVzb3VyY2VzID0gW107XG4gICAgcHVibGljIGZvcmNlRGlzYWJsZUNsaWNrOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIG5hdGl2ZVZhbHVlID0gW107XG4gICAgcHVibGljIHNob3dOZ3REcm9wem9uZUZpbGVWaWV3ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgY29tcG9uZW50UmVhZHkgPSBmYWxzZTtcbiAgICBwdWJsaWMgbG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHB1YmxpYyBuZ3REcm9wem9uZUxvYWRlclN0eWxlOiBOZ3RTdHlsaXphYmxlU2VydmljZTtcbiAgICBwdWJsaWMgaW1hZ2VWaWV3ZXJPcHRpb25zOiBhbnkgPSB7XG4gICAgICAgIG5hdmJhcjogdHJ1ZSxcbiAgICAgICAgdG9vbGJhcjoge1xuICAgICAgICAgICAgem9vbUluOiB0cnVlLFxuICAgICAgICAgICAgem9vbU91dDogdHJ1ZSxcbiAgICAgICAgICAgIHJlc2V0OiB0cnVlLFxuICAgICAgICAgICAgcm90YXRlTGVmdDogdHJ1ZSxcbiAgICAgICAgICAgIHJvdGF0ZVJpZ2h0OiB0cnVlLFxuICAgICAgICAgICAgcHJldjogdHJ1ZSxcbiAgICAgICAgICAgIG5leHQ6IHRydWUsXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBBcnJheTxTdWJzY3JpcHRpb24+ID0gW107XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICAgIEBPcHRpb25hbCgpIEBIb3N0KClcbiAgICAgICAgcHVibGljIGZvcm1Db250YWluZXI6IENvbnRyb2xDb250YWluZXIsXG4gICAgICAgIEBPcHRpb25hbCgpIEBTa2lwU2VsZigpXG4gICAgICAgIHByaXZhdGUgbmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlOiBOZ3RBdHRhY2htZW50SHR0cFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICApIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLm5ndERyb3B6b25lTG9hZGVyU3R5bGUgPSBuZXcgTmd0U3R5bGl6YWJsZVNlcnZpY2UoKTtcblxuICAgICAgICB0aGlzLm5ndERyb3B6b25lTG9hZGVyU3R5bGUubG9hZCh0aGlzLmluamVjdG9yLCAnTmd0RHJvcHpvbmVMb2FkZXInLCB7XG4gICAgICAgICAgICBoOiAnaC04JyxcbiAgICAgICAgICAgIGNvbG9yOiB7XG4gICAgICAgICAgICAgICAgdGV4dDogJ3RleHQtZ3JheS02MDAnXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGlmIChjaGFuZ2VzLnByZXZpZXdUeXBlKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXdUeXBlID0gZ2V0RW51bUZyb21TdHJpbmcoY2hhbmdlcy5wcmV2aWV3VHlwZS5jdXJyZW50VmFsdWUsIE5ndERyb3B6b25lUHJldmlld1R5cGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGFpbmVyICYmIHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuZHJvcHpvbmVIZWlnaHQgPSBgJHt0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0fXB4YDtcblxuICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRSZWFkeSA9IHRydWU7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdENvbXBvbmVudCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIDUwMCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3lTdWJzY3JpcHRpb25zKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9uSW1hZ2VDbGljayhlbGVtZW50LCBpbmRleD8pIHtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmZvcmNlRGlzYWJsZUNsaWNrID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5ndERyb3B6b25lQ29tcG9uZW50ID0gdGhpcztcblxuICAgICAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VWaWV3ZXJPcHRpb25zID0geyAuLi50aGlzLmltYWdlVmlld2VyT3B0aW9ucywgLi4ueyBpbml0aWFsVmlld0luZGV4OiBpbmRleCB9IH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2aWV3ZXIgPSBuZXcgVmlld2VyKGVsZW1lbnQsIHtcbiAgICAgICAgICAgIC4uLnRoaXMuaW1hZ2VWaWV3ZXJPcHRpb25zLCAuLi57XG4gICAgICAgICAgICAgICAgaGlkZGVuKCkge1xuICAgICAgICAgICAgICAgICAgICBuZ3REcm9wem9uZUNvbXBvbmVudC5mb3JjZURpc2FibGVDbGljayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB2aWV3ZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmlld2VyLnNob3coKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25GaWxlQ2xpY2sodXJsLCBuYW1lKSB7XG4gICAgICAgIHRoaXMuZm9yY2VEaXNhYmxlQ2xpY2sgPSB0cnVlO1xuICAgICAgICB0aGlzLnNob3dOZ3REcm9wem9uZUZpbGVWaWV3ZXIgPSB0cnVlO1xuICAgICAgICB0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci51cmwgPSB1cmw7XG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVGaWxlVmlld2VyLmZpbGVOYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5uZ3REcm9wem9uZUZpbGVWaWV3ZXIuaW5pdCgpO1xuXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKHRoaXMubmd0RHJvcHpvbmVGaWxlVmlld2VyLm9uQ2xvc2Uuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2hvd05ndERyb3B6b25lRmlsZVZpZXdlciA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5mb3JjZURpc2FibGVDbGljayA9IGZhbHNlO1xuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIG9uU2VsZWN0KGV2ZW50OiBOZ3hEcm9wem9uZUNoYW5nZUV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5yZWplY3RlZEZpbGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCByZWplY3RlZEZpbGUgb2YgPGFueT5ldmVudC5yZWplY3RlZEZpbGVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlamVjdGVkRmlsZS5yZWFzb24gPT0gJ3NpemUnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5TSVpFKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWplY3RlZEZpbGUucmVhc29uID09ICdub19tdWx0aXBsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLk5PX01VTFRJUExFKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWplY3RlZEZpbGUucmVhc29uID09ICd0eXBlJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdEVycm9yLmVtaXQoTmd0RHJvcHpvbmVFcnJvclR5cGUuVFlQRSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5ERUZBVUxUKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaXRlbXNMaW1pdCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXRlbXNMaW1pdCA9PSAxICYmIGV2ZW50LmFkZGVkRmlsZXNcbiAgICAgICAgICAgICAgICAmJiBldmVudC5hZGRlZEZpbGVzLmxlbmd0aCA9PSB0aGlzLml0ZW1zTGltaXQgJiYgdGhpcy51cGxvYWRlZFJlc291cmNlcy5sZW5ndGggPT0gdGhpcy5pdGVtc0xpbWl0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcyA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXZlbnQuYWRkZWRGaWxlc1xuICAgICAgICAgICAgICAgICYmIGV2ZW50LmFkZGVkRmlsZXMubGVuZ3RoICsgdGhpcy51cGxvYWRlZFJlc291cmNlcy5sZW5ndGggPD0gdGhpcy5pdGVtc0xpbWl0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RlZC5lbWl0KGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKGV2ZW50LmFkZGVkRmlsZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdEVycm9yLmVtaXQoTmd0RHJvcHpvbmVFcnJvclR5cGUuSVRFTVNfTElNSVQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RlZC5lbWl0KGV2ZW50KTtcbiAgICAgICAgICAgIHRoaXMudXBsb2FkRmlsZXMoZXZlbnQuYWRkZWRGaWxlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdXBsb2FkRmlsZXMoZmlsZXM6IEFycmF5PEZpbGU+KSB7XG4gICAgICAgIGlmIChmaWxlcyAmJiBmaWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGxldCB0ZW1wb3JhcnlGaWxlcyA9IFtdO1xuICAgICAgICAgICAgbGV0IHRlbXBvcmFyeUF0dGFjaG1lbnRzID0gW107XG4gICAgICAgICAgICBsZXQgb2JzZXJ2YWJsZXMgPSBbXTtcblxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcblxuICAgICAgICAgICAgZmlsZXMuZm9yRWFjaChmaWxlID0+IHtcbiAgICAgICAgICAgICAgICBvYnNlcnZhYmxlcy5wdXNoKHRoaXMubmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlLnVwbG9hZCh0aGlzLnJlbW90ZVJlc291cmNlLCBmaWxlKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICBtYXAoKHJlc3BvbnNlOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmRhdGEuYXR0cmlidXRlcyAmJiByZXNwb25zZS5kYXRhLmF0dHJpYnV0ZXMuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlWyd1cmwnXSA9IHJlc3BvbnNlLmRhdGEuYXR0cmlidXRlcy5kYXRhLnVybDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wb3JhcnlGaWxlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHJlc3BvbnNlLmRhdGEuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU6IGZpbGUuc2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZTogZmlsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmRhdGFbJ2xvYWRlZCddID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wb3JhcnlBdHRhY2htZW50cy5wdXNoKHJlc3BvbnNlLmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICAgICAgICAgIGZvcmtKb2luKG9ic2VydmFibGVzKS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICAgICAgIChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcy5wdXNoKC4uLnRlbXBvcmFyeUZpbGVzKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXRlbXNMaW1pdCA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZShbLi4udGVtcG9yYXJ5QXR0YWNobWVudHNdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZShbLi4udGVtcG9yYXJ5QXR0YWNobWVudHMsIC4uLnRoaXMubmF0aXZlVmFsdWVdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVVcGxvYWRlZC5lbWl0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVVwbG9hZEZhaWwuZW1pdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgbG9hZEZpbGVQcmV2aWV3KGF0dGFjaG1lbnRzOiBhbnkpIHtcbiAgICAgICAgaWYgKGF0dGFjaG1lbnRzICYmIGF0dGFjaG1lbnRzLmxlbmd0aCAmJiBhdHRhY2htZW50c1swXSkge1xuICAgICAgICAgICAgbGV0IHRlbXBvcmFyeVJlc291cmNlID0gW107XG4gICAgICAgICAgICBsZXQgb2JzZXJ2YWJsZXMgPSBbXTtcblxuICAgICAgICAgICAgYXR0YWNobWVudHMuZm9yRWFjaChhdHRhY2htZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIShhdHRhY2htZW50IGluc3RhbmNlb2YgRmlsZSkgJiYgIWF0dGFjaG1lbnQubG9hZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRbJ2xvYWRlZCddID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2YWJsZXMucHVzaCh0aGlzLm5ndEF0dGFjaG1lbnRIdHRwU2VydmljZS50aHVtYm5haWwoYXR0YWNobWVudCkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCgocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBvcmFyeVJlc291cmNlLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZDogcmVzcG9uc2UuZGF0YS5nZXRBcGlJZCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlOiByZXNwb25zZS5kYXRhLmdldEF0dHJpYnV0ZSgnZmlsZScpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgZm9ya0pvaW4ob2JzZXJ2YWJsZXMpLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzLnB1c2goLi4udGVtcG9yYXJ5UmVzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZShhdHRhY2htZW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVByZXZpZXdMb2FkZWQuZW1pdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uUmVtb3ZlKHJlc291cmNlOiBhbnkpIHtcbiAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcy5zcGxpY2UodGhpcy51cGxvYWRlZFJlc291cmNlcy5pbmRleE9mKHJlc291cmNlKSwgMSk7XG4gICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSB0aGlzLm5hdGl2ZVZhbHVlLmZpbHRlcihlbGVtZW50ID0+IGVsZW1lbnQuaWQgIT0gcmVzb3VyY2UuaWQpO1xuICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKHRoaXMubmF0aXZlVmFsdWUpO1xuICAgICAgICB0aGlzLm9uRmlsZVJlbW92ZWQuZW1pdChyZXNvdXJjZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGlzSW1hZ2UocmVzb3VyY2U6IGFueSkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcmV2aWV3VHlwZSA9PSAnSU1BR0UnIHx8IChyZXNvdXJjZS5maWxlICYmIHJlc291cmNlLmZpbGUudHlwZSAmJiByZXNvdXJjZS5maWxlLnR5cGUuaW5jbHVkZXMoJ2ltYWdlJykpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc1ZpZGVvKHJlc291cmNlOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJldmlld1R5cGUgPT0gJ1ZJREVPJyB8fCAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnR5cGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlLmluY2x1ZGVzKCd2aWRlbycpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNBdWRpbyhyZXNvdXJjZTogYW55KSB7XG4gICAgICAgIHJldHVybiAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnR5cGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlLmluY2x1ZGVzKCdhdWRpbycpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNGaWxlKHJlc291cmNlOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzSW1hZ2UocmVzb3VyY2UpICYmICF0aGlzLmlzQXVkaW8ocmVzb3VyY2UpICYmICF0aGlzLmlzVmlkZW8ocmVzb3VyY2UpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRGb3JtYXR0ZWRGaWxlU2l6ZShyZXNvdXJjZTogYW55KSB7XG4gICAgICAgIGlmIChyZXNvdXJjZSkge1xuICAgICAgICAgICAgbGV0IHNpemUgPSByZXNvdXJjZS5zaXplIHx8IHJlc291cmNlLmZpbGVTaXplO1xuXG4gICAgICAgICAgICBpZiAoIXNpemUpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnNpemUpIHtcbiAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IHJlc291cmNlLmZpbGUuc2l6ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzaXplID0gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChwYXJzZUZsb2F0KHNpemUpID4gMTAwMDAwMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAocGFyc2VGbG9hdChzaXplKSAvIDEwMDAwMDApLnRvRml4ZWQoMikgKyAnIE1iJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIE1hdGgucm91bmQocGFyc2VGbG9hdChzaXplKSAvIDEwMDApICsgJyBLYic7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgb25OYXRpdmVDaGFuZ2UodmFsdWU6IGFueSkge1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5uYXRpdmVWYWx1ZSA9IFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5uYXRpdmVWYWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodGhpcy52YWx1ZSkgIT0gSlNPTi5zdHJpbmdpZnkodGhpcy5uYXRpdmVWYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy5uYXRpdmVWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjaGFuZ2UodmFsdWU6IGFueSkge1xuICAgICAgICBpZiAodmFsdWUgJiYgIXRoaXMudmlld01vZGUpIHtcbiAgICAgICAgICAgIHRoaXMub25OYXRpdmVDaGFuZ2UoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV0pO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jb21wb25lbnRSZWFkeSkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZEZpbGVQcmV2aWV3KEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBkb3dubG9hZEZpbGUoYXR0YWNobWVudDogYW55KSB7XG4gICAgICAgIHRoaXMubmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlLmRvd25sb2FkKGF0dGFjaG1lbnQpLnN1YnNjcmliZSgoKSA9PiB7IH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyByZXNldCgpIHtcbiAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcyA9IFtdO1xuICAgICAgICB0aGlzLnZhbHVlID0gW107XG4gICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSBbXTtcbiAgICAgICAgdGhpcy5pbml0Q29tcG9uZW50KCk7XG4gICAgfVxuXG4gICAgcHVibGljIG9wZW5GaWxlU2VsZWN0b3IoKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZ3hEcm9wem9uZScpLmNsaWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0Q29tcG9uZW50KCkge1xuICAgICAgICBpZiAodGhpcy52aWV3TW9kZSkge1xuICAgICAgICAgICAgdGhpcy5wcmV2aWV3VHlwZSA9IE5ndERyb3B6b25lUHJldmlld1R5cGUuREVGQVVMVDtcblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuZm9ybUNvbnRhaW5lciAmJiB0aGlzLmZvcm1Db250YWluZXIuY29udHJvbFxuICAgICAgICAgICAgJiYgKHRoaXMuZm9ybUNvbnRyb2wgPSB0aGlzLmZvcm1Db250YWluZXIuY29udHJvbC5nZXQodGhpcy5uYW1lKSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVzZXRGaWxlc0xvYWQoKTtcbiAgICAgICAgICAgIHRoaXMubG9hZEZpbGVQcmV2aWV3KEFycmF5LmlzQXJyYXkodGhpcy52YWx1ZSkgPyB0aGlzLnZhbHVlIDogW3RoaXMudmFsdWVdKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVmFsaWRhdGlvbnMoKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVzZXRGaWxlc0xvYWQoKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMudmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFsnbG9hZGVkJ10gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlVmFsaWRhdGlvbnMoKSB7XG4gICAgICAgIGlmICghdGhpcy5mb3JtQ29udHJvbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN5bmNWYWxpZGF0b3JzID0gW107XG5cbiAgICAgICAgaWYgKHRoaXMuaXNSZXF1aXJlZCkge1xuICAgICAgICAgICAgc3luY1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLnJlcXVpcmVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN5bmNWYWxpZGF0b3JzLnB1c2goKTtcblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc2V0VmFsaWRhdG9ycyhzeW5jVmFsaWRhdG9ycyk7XG4gICAgICAgICAgICB0aGlzLmZvcm1Db250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZXN0cm95U3Vic2NyaXB0aW9ucygpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goc3Vic2NyaXB0aW9uID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gW107XG4gICAgfVxufVxuIl19
1
+ import { __awaiter } from "tslib";
2
+ import { ChangeDetectorRef, Component, EventEmitter, Host, Injector, Input, Optional, Output, SkipSelf, ViewChild, ViewEncapsulation, } from '@angular/core';
3
+ import { ControlContainer, NgForm, Validators } from '@angular/forms';
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 { NgtAttachmentHttpService } from '../../services/http/ngt-attachment-http.service';
10
+ import { NgtStylizableService } from '../../services/ngt-stylizable/ngt-stylizable.service';
11
+ import { NgtDropzoneFileViewerComponent } from './ngt-dropzone-file-viewer/ngt-dropzone-file-viewer.component';
12
+ ;
13
+ export var NgtDropzoneFileTypeEnum;
14
+ (function (NgtDropzoneFileTypeEnum) {
15
+ NgtDropzoneFileTypeEnum["DOC"] = "DOC";
16
+ NgtDropzoneFileTypeEnum["PDF"] = "PDF";
17
+ NgtDropzoneFileTypeEnum["XLS"] = "XLS";
18
+ NgtDropzoneFileTypeEnum["OTHER"] = "OTHER";
19
+ })(NgtDropzoneFileTypeEnum || (NgtDropzoneFileTypeEnum = {}));
20
+ export var NgtDropzonePreviewType;
21
+ (function (NgtDropzonePreviewType) {
22
+ NgtDropzonePreviewType["DEFAULT"] = "DEFAULT";
23
+ NgtDropzonePreviewType["IMAGE"] = "IMAGE";
24
+ NgtDropzonePreviewType["VIDEO"] = "VIDEO";
25
+ })(NgtDropzonePreviewType || (NgtDropzonePreviewType = {}));
26
+ export var NgtDropzoneErrorType;
27
+ (function (NgtDropzoneErrorType) {
28
+ NgtDropzoneErrorType["DEFAULT"] = "DEFAULT";
29
+ NgtDropzoneErrorType["SIZE"] = "SIZE";
30
+ NgtDropzoneErrorType["NO_MULTIPLE"] = "NO_MULTIPLE";
31
+ NgtDropzoneErrorType["ITEMS_LIMIT"] = "ITEMS_LIMIT";
32
+ NgtDropzoneErrorType["TYPE"] = "TYPE";
33
+ })(NgtDropzoneErrorType || (NgtDropzoneErrorType = {}));
34
+ export class NgtDropzoneComponent extends NgtBaseNgModel {
35
+ constructor(formContainer, ngtAttachmentHttpService, injector, changeDetector) {
36
+ super();
37
+ this.formContainer = formContainer;
38
+ this.ngtAttachmentHttpService = ngtAttachmentHttpService;
39
+ this.injector = injector;
40
+ this.changeDetector = changeDetector;
41
+ this.helpTextColor = 'text-green-500';
42
+ // Behavior
43
+ this.resources = [];
44
+ this.multipleSelection = false;
45
+ this.showFileName = false;
46
+ this.disableClick = false;
47
+ this.disabled = false;
48
+ this.viewMode = false;
49
+ this.removable = false;
50
+ this.verticalExpandable = false;
51
+ this.acceptedFiles = '*' /** Mime type */;
52
+ this.previewType = NgtDropzonePreviewType.DEFAULT;
53
+ this.isRequired = false;
54
+ this.onFileSelected = new EventEmitter();
55
+ this.onFileSelectError = new EventEmitter();
56
+ this.onFileUploadFail = new EventEmitter();
57
+ this.onFileRemoved = new EventEmitter();
58
+ this.onFileUploaded = new EventEmitter();
59
+ this.onFilePreviewLoaded = new EventEmitter();
60
+ this.dropzoneHeight = '180px';
61
+ this.uploadedResources = [];
62
+ this.forceDisableClick = false;
63
+ this.nativeValue = [];
64
+ this.showNgtDropzoneFileViewer = false;
65
+ this.componentReady = false;
66
+ this.loading = false;
67
+ this.imageViewerOptions = {
68
+ navbar: true,
69
+ toolbar: {
70
+ zoomIn: true,
71
+ zoomOut: true,
72
+ reset: true,
73
+ rotateLeft: true,
74
+ rotateRight: true,
75
+ prev: true,
76
+ next: true,
77
+ }
78
+ };
79
+ this.subscriptions = [];
80
+ this.ngtDropzoneLoaderStyle = new NgtStylizableService();
81
+ this.ngtDropzoneLoaderStyle.load(this.injector, 'NgtDropzoneLoader', {
82
+ h: 'h-8',
83
+ color: {
84
+ text: 'text-gray-600'
85
+ }
86
+ });
87
+ }
88
+ ngOnChanges(changes) {
89
+ if (changes.previewType) {
90
+ this.previewType = getEnumFromString(changes.previewType.currentValue, NgtDropzonePreviewType);
91
+ }
92
+ }
93
+ ngAfterContentChecked() {
94
+ if (this.container && this.container.nativeElement) {
95
+ this.dropzoneHeight = `${this.container.nativeElement.parentElement.offsetHeight}px`;
96
+ this.changeDetector.detectChanges();
97
+ }
98
+ }
99
+ ngOnInit() {
100
+ setTimeout(() => {
101
+ this.componentReady = true;
102
+ setTimeout(() => {
103
+ this.initComponent();
104
+ });
105
+ }, 500);
106
+ }
107
+ ngOnDestroy() {
108
+ this.destroySubscriptions();
109
+ }
110
+ onImageClick(element, index) {
111
+ if (!this.viewMode) {
112
+ this.forceDisableClick = true;
113
+ }
114
+ const ngtDropzoneComponent = this;
115
+ if (index) {
116
+ this.imageViewerOptions = Object.assign(Object.assign({}, this.imageViewerOptions), { initialViewIndex: index });
117
+ }
118
+ const viewer = new Viewer(element, Object.assign(Object.assign({}, this.imageViewerOptions), {
119
+ hidden() {
120
+ ngtDropzoneComponent.forceDisableClick = false;
121
+ viewer.destroy();
122
+ }
123
+ }));
124
+ viewer.show();
125
+ }
126
+ onFileClick(url, name) {
127
+ this.forceDisableClick = true;
128
+ this.showNgtDropzoneFileViewer = true;
129
+ this.ngtDropzoneFileViewer.url = url;
130
+ this.ngtDropzoneFileViewer.fileName = name;
131
+ this.ngtDropzoneFileViewer.init();
132
+ this.subscriptions.push(this.ngtDropzoneFileViewer.onClose.subscribe(() => {
133
+ this.showNgtDropzoneFileViewer = false;
134
+ this.forceDisableClick = false;
135
+ }));
136
+ }
137
+ onSelect(event) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ if (event.rejectedFiles.length) {
140
+ for (const rejectedFile of event.rejectedFiles) {
141
+ if (rejectedFile.reason == 'size') {
142
+ this.onFileSelectError.emit(NgtDropzoneErrorType.SIZE);
143
+ break;
144
+ }
145
+ else if (rejectedFile.reason == 'no_multiple') {
146
+ this.onFileSelectError.emit(NgtDropzoneErrorType.NO_MULTIPLE);
147
+ break;
148
+ }
149
+ else if (rejectedFile.reason == 'type') {
150
+ this.onFileSelectError.emit(NgtDropzoneErrorType.TYPE);
151
+ break;
152
+ }
153
+ else {
154
+ this.onFileSelectError.emit(NgtDropzoneErrorType.DEFAULT);
155
+ break;
156
+ }
157
+ }
158
+ }
159
+ if (this.itemsLimit) {
160
+ if (this.itemsLimit == 1 && event.addedFiles
161
+ && event.addedFiles.length == this.itemsLimit && this.uploadedResources.length == this.itemsLimit) {
162
+ this.uploadedResources = [];
163
+ }
164
+ if (event.addedFiles
165
+ && event.addedFiles.length + this.uploadedResources.length <= this.itemsLimit) {
166
+ this.onFileSelected.emit(event);
167
+ this.uploadFiles(event.addedFiles);
168
+ }
169
+ else {
170
+ this.onFileSelectError.emit(NgtDropzoneErrorType.ITEMS_LIMIT);
171
+ }
172
+ }
173
+ else {
174
+ this.onFileSelected.emit(event);
175
+ this.uploadFiles(event.addedFiles);
176
+ }
177
+ });
178
+ }
179
+ uploadFiles(files) {
180
+ return __awaiter(this, void 0, void 0, function* () {
181
+ if (files && files.length) {
182
+ let temporaryFiles = [];
183
+ let temporaryAttachments = [];
184
+ let observables = [];
185
+ this.loading = true;
186
+ files.forEach(file => {
187
+ observables.push(this.ngtAttachmentHttpService.upload(this.remoteResource, file).pipe(map((response) => {
188
+ if (response && response.data) {
189
+ if (response.data.attributes && response.data.attributes.data) {
190
+ file['url'] = response.data.attributes.data.url;
191
+ }
192
+ temporaryFiles.push({
193
+ id: response.data.id,
194
+ size: file.size,
195
+ file: file
196
+ });
197
+ response.data['loaded'] = true;
198
+ temporaryAttachments.push(response.data);
199
+ }
200
+ })));
201
+ });
202
+ this.subscriptions.push(forkJoin(observables).subscribe((response) => {
203
+ this.uploadedResources.push(...temporaryFiles);
204
+ if (this.itemsLimit == 1) {
205
+ this.onNativeChange([...temporaryAttachments]);
206
+ }
207
+ else {
208
+ this.onNativeChange([...temporaryAttachments, ...this.nativeValue]);
209
+ }
210
+ this.onFileUploaded.emit();
211
+ this.loading = false;
212
+ }, (error) => {
213
+ this.onFileUploadFail.emit(error);
214
+ this.loading = false;
215
+ }));
216
+ }
217
+ });
218
+ }
219
+ loadFilePreview(attachments) {
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ if (attachments && attachments.length && attachments[0]) {
222
+ let temporaryResource = [];
223
+ let observables = [];
224
+ attachments.forEach(attachment => {
225
+ if (!(attachment instanceof File) && !attachment.loaded) {
226
+ this.loading = true;
227
+ attachment['loaded'] = true;
228
+ observables.push(this.ngtAttachmentHttpService.thumbnail(attachment).pipe(map((response) => {
229
+ temporaryResource.push({
230
+ id: response.data.getApiId(),
231
+ file: response.data.getAttribute('file')
232
+ });
233
+ })));
234
+ }
235
+ });
236
+ this.subscriptions.push(forkJoin(observables).subscribe((response) => {
237
+ this.uploadedResources.push(...temporaryResource);
238
+ this.onNativeChange(attachments);
239
+ this.onFilePreviewLoaded.emit();
240
+ this.loading = false;
241
+ }, (error) => {
242
+ this.loading = false;
243
+ }));
244
+ }
245
+ });
246
+ }
247
+ onRemove(resource) {
248
+ this.uploadedResources.splice(this.uploadedResources.indexOf(resource), 1);
249
+ this.nativeValue = this.nativeValue.filter(element => element.id != resource.id);
250
+ this.onNativeChange(this.nativeValue);
251
+ this.onFileRemoved.emit(resource);
252
+ }
253
+ isImage(resource) {
254
+ return this.previewType == 'IMAGE' || (resource.file && resource.file.type && resource.file.type.includes('image'));
255
+ }
256
+ isVideo(resource) {
257
+ return this.previewType == 'VIDEO' || (resource.file && resource.file.type && resource.file.type.includes('video'));
258
+ }
259
+ isAudio(resource) {
260
+ return (resource.file && resource.file.type && resource.file.type.includes('audio'));
261
+ }
262
+ isFile(resource) {
263
+ return !this.isImage(resource) && !this.isAudio(resource) && !this.isVideo(resource);
264
+ }
265
+ getFormattedFileSize(resource) {
266
+ if (resource) {
267
+ let size = resource.size || resource.fileSize;
268
+ if (!size) {
269
+ if (resource.file && resource.file.size) {
270
+ size = resource.file.size;
271
+ }
272
+ else {
273
+ size = 0;
274
+ }
275
+ }
276
+ if (parseFloat(size) > 1000000) {
277
+ return (parseFloat(size) / 1000000).toFixed(2) + ' Mb';
278
+ }
279
+ return Math.round(parseFloat(size) / 1000) + ' Kb';
280
+ }
281
+ }
282
+ onNativeChange(value) {
283
+ if (value === undefined) {
284
+ this.value = [];
285
+ this.nativeValue = [];
286
+ }
287
+ else {
288
+ this.nativeValue = value;
289
+ if (JSON.stringify(this.value) != JSON.stringify(this.nativeValue)) {
290
+ this.value = this.nativeValue;
291
+ }
292
+ }
293
+ }
294
+ change(value) {
295
+ if (value && !this.viewMode) {
296
+ this.onNativeChange(Array.isArray(value) ? value : [value]);
297
+ if (this.componentReady) {
298
+ this.loadFilePreview(Array.isArray(value) ? value : [value]);
299
+ }
300
+ }
301
+ }
302
+ downloadFile(attachment) {
303
+ this.ngtAttachmentHttpService.download(attachment).subscribe(() => { });
304
+ }
305
+ reset() {
306
+ this.uploadedResources = [];
307
+ this.value = [];
308
+ this.nativeValue = [];
309
+ this.initComponent();
310
+ }
311
+ openFileSelector() {
312
+ document.getElementById('ngxDropzone').click();
313
+ }
314
+ initComponent() {
315
+ if (this.viewMode) {
316
+ this.previewType = NgtDropzonePreviewType.DEFAULT;
317
+ return;
318
+ }
319
+ if (this.formContainer && this.formContainer.control
320
+ && (this.formControl = this.formContainer.control.get(this.name))) {
321
+ this.resetFilesLoad();
322
+ this.loadFilePreview(Array.isArray(this.value) ? this.value : [this.value]);
323
+ this.updateValidations();
324
+ if (this.value) {
325
+ this.formControl.markAsDirty();
326
+ }
327
+ else {
328
+ this.formControl.markAsPristine();
329
+ }
330
+ }
331
+ }
332
+ resetFilesLoad() {
333
+ if (Array.isArray(this.value)) {
334
+ this.value.forEach(element => {
335
+ if (element) {
336
+ element['loaded'] = false;
337
+ }
338
+ });
339
+ }
340
+ }
341
+ updateValidations() {
342
+ if (!this.formControl) {
343
+ return;
344
+ }
345
+ let syncValidators = [];
346
+ if (this.isRequired) {
347
+ syncValidators.push(Validators.required);
348
+ }
349
+ syncValidators.push();
350
+ setTimeout(() => {
351
+ this.formControl.setValidators(syncValidators);
352
+ this.formControl.updateValueAndValidity();
353
+ });
354
+ }
355
+ destroySubscriptions() {
356
+ this.subscriptions.forEach(subscription => subscription.unsubscribe());
357
+ this.subscriptions = [];
358
+ }
359
+ }
360
+ NgtDropzoneComponent.decorators = [
361
+ { type: Component, args: [{
362
+ selector: 'ngt-dropzone',
363
+ 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=\"ngxDropzone\" [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\">\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)\"\r\n ngProjectAs=\"ngx-dropzone-preview\">\r\n </custom-dropzone-preview>\r\n\r\n <div *ngIf=\"isImage(resource)\" class=\"cursor-pointer\" (click)=\"onImageClick(gallery)\" #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\" [resources]=\"resources\" class=\"h-full w-full\"></ngt-dropzone-view>\r\n\r\n <ngt-dropzone-file-viewer [hidden]=\"!showNgtDropzoneFileViewer\" (onClose)=\"forceDisableClick = false\">\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>",
364
+ encapsulation: ViewEncapsulation.None,
365
+ providers: [
366
+ NgtMakeProvider(NgtDropzoneComponent),
367
+ ],
368
+ viewProviders: [
369
+ { provide: ControlContainer, useExisting: NgForm }
370
+ ],
371
+ styles: [".single-attachment{border:none!important;overflow:hidden!important;display:flex!important;justify-content:center!important}.image-preview-default-class,.single-attachment{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%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}"]
372
+ },] }
373
+ ];
374
+ NgtDropzoneComponent.ctorParameters = () => [
375
+ { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }] },
376
+ { type: NgtAttachmentHttpService, decorators: [{ type: Optional }, { type: SkipSelf }] },
377
+ { type: Injector },
378
+ { type: ChangeDetectorRef }
379
+ ];
380
+ NgtDropzoneComponent.propDecorators = {
381
+ container: [{ type: ViewChild, args: ['container',] }],
382
+ ngxDropzone: [{ type: ViewChild, args: ['ngxDropzone', { static: true },] }],
383
+ ngtDropzoneFileViewer: [{ type: ViewChild, args: [NgtDropzoneFileViewerComponent, { static: true },] }],
384
+ label: [{ type: Input }],
385
+ placeholder: [{ type: Input }],
386
+ helpTextColor: [{ type: Input }],
387
+ helpText: [{ type: Input }],
388
+ helpTitle: [{ type: Input }],
389
+ resources: [{ type: Input }],
390
+ multipleSelection: [{ type: Input }],
391
+ itemsLimit: [{ type: Input }],
392
+ showFileName: [{ type: Input }],
393
+ disableClick: [{ type: Input }],
394
+ disabled: [{ type: Input }],
395
+ viewMode: [{ type: Input }],
396
+ removable: [{ type: Input }],
397
+ verticalExpandable: [{ type: Input }],
398
+ acceptedFiles: [{ type: Input }],
399
+ maxFileSize: [{ type: Input }],
400
+ previewType: [{ type: Input }],
401
+ isRequired: [{ type: Input }],
402
+ name: [{ type: Input }],
403
+ remoteResource: [{ type: Input }],
404
+ onFileSelected: [{ type: Output }],
405
+ onFileSelectError: [{ type: Output }],
406
+ onFileUploadFail: [{ type: Output }],
407
+ onFileRemoved: [{ type: Output }],
408
+ onFileUploaded: [{ type: Output }],
409
+ onFilePreviewLoaded: [{ type: Output }]
410
+ };
411
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd0LWRyb3B6b25lLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXRhaWx3aW5kL3NyYy9jb21wb25lbnRzL25ndC1kcm9wem9uZS9uZ3QtZHJvcHpvbmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBRUgsaUJBQWlCLEVBQ2pCLFNBQVMsRUFFVCxZQUFZLEVBQ1osSUFBSSxFQUNKLFFBQVEsRUFDUixLQUFLLEVBR0wsUUFBUSxFQUNSLE1BQU0sRUFFTixRQUFRLEVBQ1IsU0FBUyxFQUNULGlCQUFpQixHQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRFLE9BQU8sRUFBRSxRQUFRLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLE1BQU0sTUFBTSxVQUFVLENBQUM7QUFFOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMvRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUMzRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzREFBc0QsQ0FBQztBQUM1RixPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSwrREFBK0QsQ0FBQztBQVM5RyxDQUFDO0FBRUYsTUFBTSxDQUFOLElBQVksdUJBS1g7QUFMRCxXQUFZLHVCQUF1QjtJQUMvQixzQ0FBVyxDQUFBO0lBQ1gsc0NBQVcsQ0FBQTtJQUNYLHNDQUFXLENBQUE7SUFDWCwwQ0FBZSxDQUFBO0FBQ25CLENBQUMsRUFMVyx1QkFBdUIsS0FBdkIs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Q0FDTCxLQUFLOzRCQUNMLEtBQUs7MEJBQ0wsS0FBSzswQkFDTCxLQUFLO3lCQUNMLEtBQUs7bUJBQ0wsS0FBSzs2QkFDTCxLQUFLOzZCQUVMLE1BQU07Z0NBQ04sTUFBTTsrQkFDTixNQUFNOzRCQUNOLE1BQU07NkJBQ04sTUFBTTtrQ0FDTixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIEFmdGVyQ29udGVudENoZWNrZWQsXHJcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIENvbXBvbmVudCxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBIb3N0LFxyXG4gICAgSW5qZWN0b3IsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE9uSW5pdCxcclxuICAgIE9wdGlvbmFsLFxyXG4gICAgT3V0cHV0LFxyXG4gICAgU2ltcGxlQ2hhbmdlcyxcclxuICAgIFNraXBTZWxmLFxyXG4gICAgVmlld0NoaWxkLFxyXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbnRyb2xDb250YWluZXIsIE5nRm9ybSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgTmd4RHJvcHpvbmVDaGFuZ2VFdmVudCwgTmd4RHJvcHpvbmVDb21wb25lbnQgfSBmcm9tICduZ3gtZHJvcHpvbmUnO1xyXG5pbXBvcnQgeyBmb3JrSm9pbiwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IFZpZXdlciBmcm9tICd2aWV3ZXJqcyc7XHJcblxyXG5pbXBvcnQgeyBOZ3RCYXNlTmdNb2RlbCwgTmd0TWFrZVByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vYmFzZS9uZ3QtYmFzZS1uZy1tb2RlbCc7XHJcbmltcG9ydCB7IGdldEVudW1Gcm9tU3RyaW5nIH0gZnJvbSAnLi4vLi4vaGVscGVycy9lbnVtL2VudW0nO1xyXG5pbXBvcnQgeyBOZ3RBdHRhY2htZW50SHR0cFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9odHRwL25ndC1hdHRhY2htZW50LWh0dHAuc2VydmljZSc7XHJcbmltcG9ydCB7IE5ndFN0eWxpemFibGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbmd0LXN0eWxpemFibGUvbmd0LXN0eWxpemFibGUuc2VydmljZSc7XHJcbmltcG9ydCB7IE5ndERyb3B6b25lRmlsZVZpZXdlckNvbXBvbmVudCB9IGZyb20gJy4vbmd0LWRyb3B6b25lLWZpbGUtdmlld2VyL25ndC1kcm9wem9uZS1maWxlLXZpZXdlci5jb21wb25lbnQnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBOZ3REcm9wem9uZUZpbGUge1xyXG4gICAgZG93bmxvYWRVcmw6IHN0cmluZztcclxuICAgIHByZXZpZXdVcmw6IHN0cmluZztcclxuICAgIHRodW1ibmFpbFVybDogc3RyaW5nO1xyXG4gICAgbmFtZTogc3RyaW5nO1xyXG4gICAgbWltZVR5cGU6IHN0cmluZztcclxuICAgIGZpbGVTaXplOiBhbnk7XHJcbn07XHJcblxyXG5leHBvcnQgZW51bSBOZ3REcm9wem9uZUZpbGVUeXBlRW51bSB7XHJcbiAgICBET0MgPSAnRE9DJyxcclxuICAgIFBERiA9ICdQREYnLFxyXG4gICAgWExTID0gJ1hMUycsXHJcbiAgICBPVEhFUiA9ICdPVEhFUidcclxufVxyXG5cclxuZXhwb3J0IGVudW0gTmd0RHJvcHpvbmVQcmV2aWV3VHlwZSB7XHJcbiAgICBERUZBVUxUID0gJ0RFRkFVTFQnLFxyXG4gICAgSU1BR0UgPSAnSU1BR0UnLFxyXG4gICAgVklERU8gPSAnVklERU8nXHJcbn1cclxuXHJcbmV4cG9ydCBlbnVtIE5ndERyb3B6b25lRXJyb3JUeXBlIHtcclxuICAgIERFRkFVTFQgPSAnREVGQVVMVCcsXHJcbiAgICBTSVpFID0gJ1NJWkUnLFxyXG4gICAgTk9fTVVMVElQTEUgPSAnTk9fTVVMVElQTEUnLFxyXG4gICAgSVRFTVNfTElNSVQgPSAnSVRFTVNfTElNSVQnLFxyXG4gICAgVFlQRSA9ICdUWVBFJ1xyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnbmd0LWRyb3B6b25lJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9uZ3QtZHJvcHpvbmUuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vbmd0LWRyb3B6b25lLmNvbXBvbmVudC5jc3MnXSxcclxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgICBwcm92aWRlcnM6IFtcclxuICAgICAgICBOZ3RNYWtlUHJvdmlkZXIoTmd0RHJvcHpvbmVDb21wb25lbnQpLFxyXG4gICAgXSxcclxuICAgIHZpZXdQcm92aWRlcnM6IFtcclxuICAgICAgICB7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBOZ0Zvcm0gfVxyXG4gICAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmd0RHJvcHpvbmVDb21wb25lbnQgZXh0ZW5kcyBOZ3RCYXNlTmdNb2RlbCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlckNvbnRlbnRDaGVja2VkIHtcclxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lcicpIHB1YmxpYyBjb250YWluZXI6IEVsZW1lbnRSZWY7XHJcbiAgICBAVmlld0NoaWxkKCduZ3hEcm9wem9uZScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBuZ3hEcm9wem9uZTogTmd4RHJvcHpvbmVDb21wb25lbnQ7XHJcbiAgICBAVmlld0NoaWxkKE5ndERyb3B6b25lRmlsZVZpZXdlckNvbXBvbmVudCwgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIG5ndERyb3B6b25lRmlsZVZpZXdlcjogTmd0RHJvcHpvbmVGaWxlVmlld2VyQ29tcG9uZW50O1xyXG5cclxuICAgIC8vIFZpc3VhbFxyXG4gICAgQElucHV0KCkgcHVibGljIGxhYmVsOiBzdHJpbmc7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBoZWxwVGV4dENvbG9yOiBzdHJpbmcgPSAndGV4dC1ncmVlbi01MDAnO1xyXG4gICAgQElucHV0KCkgcHVibGljIGhlbHBUZXh0OiBzdHJpbmc7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgaGVscFRpdGxlOiBzdHJpbmc7XHJcblxyXG4gICAgLy8gQmVoYXZpb3JcclxuICAgIEBJbnB1dCgpIHB1YmxpYyByZXNvdXJjZXM6IEFycmF5PE5ndERyb3B6b25lRmlsZT4gPSBbXTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBtdWx0aXBsZVNlbGVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgcHVibGljIGl0ZW1zTGltaXQ6IG51bWJlcjtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBzaG93RmlsZU5hbWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlQ2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgcHVibGljIHZpZXdNb2RlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgcmVtb3ZhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgdmVydGljYWxFeHBhbmRhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgYWNjZXB0ZWRGaWxlczogc3RyaW5nID0gJyonIC8qKiBNaW1lIHR5cGUgKi87XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgbWF4RmlsZVNpemU6IG51bWJlcjsgLyoqIEJ5dGVzICovXHJcbiAgICBASW5wdXQoKSBwdWJsaWMgcHJldmlld1R5cGU6IE5ndERyb3B6b25lUHJldmlld1R5cGUgPSBOZ3REcm9wem9uZVByZXZpZXdUeXBlLkRFRkFVTFQ7XHJcbiAgICBASW5wdXQoKSBwdWJsaWMgaXNSZXF1aXJlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgQElucHV0KCkgcHVibGljIG5hbWU6IHN0cmluZztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyByZW1vdGVSZXNvdXJjZTogYW55O1xyXG5cclxuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlU2VsZWN0ZWQ6IEV2ZW50RW1pdHRlcjxOZ3hEcm9wem9uZUNoYW5nZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlU2VsZWN0RXJyb3I6IEV2ZW50RW1pdHRlcjxOZ3REcm9wem9uZUVycm9yVHlwZT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICBAT3V0cHV0KCkgcHVibGljIG9uRmlsZVVwbG9hZEZhaWw6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVSZW1vdmVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvbkZpbGVVcGxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25GaWxlUHJldmlld0xvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgICBwdWJsaWMgZHJvcHpvbmVIZWlnaHQ6IHN0cmluZyA9ICcxODBweCc7XHJcbiAgICBwdWJsaWMgdXBsb2FkZWRSZXNvdXJjZXMgPSBbXTtcclxuICAgIHB1YmxpYyBmb3JjZURpc2FibGVDbGljazogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHVibGljIG5hdGl2ZVZhbHVlID0gW107XHJcbiAgICBwdWJsaWMgc2hvd05ndERyb3B6b25lRmlsZVZpZXdlcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHVibGljIGNvbXBvbmVudFJlYWR5ID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgbG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHVibGljIG5ndERyb3B6b25lTG9hZGVyU3R5bGU6IE5ndFN0eWxpemFibGVTZXJ2aWNlO1xyXG4gICAgcHVibGljIGltYWdlVmlld2VyT3B0aW9uczogYW55ID0ge1xyXG4gICAgICAgIG5hdmJhcjogdHJ1ZSxcclxuICAgICAgICB0b29sYmFyOiB7XHJcbiAgICAgICAgICAgIHpvb21JbjogdHJ1ZSxcclxuICAgICAgICAgICAgem9vbU91dDogdHJ1ZSxcclxuICAgICAgICAgICAgcmVzZXQ6IHRydWUsXHJcbiAgICAgICAgICAgIHJvdGF0ZUxlZnQ6IHRydWUsXHJcbiAgICAgICAgICAgIHJvdGF0ZVJpZ2h0OiB0cnVlLFxyXG4gICAgICAgICAgICBwcmV2OiB0cnVlLFxyXG4gICAgICAgICAgICBuZXh0OiB0cnVlLFxyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBBcnJheTxTdWJzY3JpcHRpb24+ID0gW107XHJcblxyXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBPcHRpb25hbCgpIEBIb3N0KClcclxuICAgICAgICBwdWJsaWMgZm9ybUNvbnRhaW5lcjogQ29udHJvbENvbnRhaW5lcixcclxuICAgICAgICBAT3B0aW9uYWwoKSBAU2tpcFNlbGYoKVxyXG4gICAgICAgIHByaXZhdGUgbmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlOiBOZ3RBdHRhY2htZW50SHR0cFNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXHJcbiAgICAgICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICApIHtcclxuICAgICAgICBzdXBlcigpO1xyXG5cclxuICAgICAgICB0aGlzLm5ndERyb3B6b25lTG9hZGVyU3R5bGUgPSBuZXcgTmd0U3R5bGl6YWJsZVNlcnZpY2UoKTtcclxuXHJcbiAgICAgICAgdGhpcy5uZ3REcm9wem9uZUxvYWRlclN0eWxlLmxvYWQodGhpcy5pbmplY3RvciwgJ05ndERyb3B6b25lTG9hZGVyJywge1xyXG4gICAgICAgICAgICBoOiAnaC04JyxcclxuICAgICAgICAgICAgY29sb3I6IHtcclxuICAgICAgICAgICAgICAgIHRleHQ6ICd0ZXh0LWdyYXktNjAwJ1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgICAgICBpZiAoY2hhbmdlcy5wcmV2aWV3VHlwZSkge1xyXG4gICAgICAgICAgICB0aGlzLnByZXZpZXdUeXBlID0gZ2V0RW51bUZyb21TdHJpbmcoY2hhbmdlcy5wcmV2aWV3VHlwZS5jdXJyZW50VmFsdWUsIE5ndERyb3B6b25lUHJldmlld1R5cGUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRDaGVja2VkKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbnRhaW5lciAmJiB0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZHJvcHpvbmVIZWlnaHQgPSBgJHt0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0fXB4YDtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50UmVhZHkgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRDb21wb25lbnQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSwgNTAwKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95U3Vic2NyaXB0aW9ucygpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvbkltYWdlQ2xpY2soZWxlbWVudCwgaW5kZXg/KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9yY2VEaXNhYmxlQ2xpY2sgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3Qgbmd0RHJvcHpvbmVDb21wb25lbnQgPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoaW5kZXgpIHtcclxuICAgICAgICAgICAgdGhpcy5pbWFnZVZpZXdlck9wdGlvbnMgPSB7IC4uLnRoaXMuaW1hZ2VWaWV3ZXJPcHRpb25zLCAuLi57IGluaXRpYWxWaWV3SW5kZXg6IGluZGV4IH0gfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IHZpZXdlciA9IG5ldyBWaWV3ZXIoZWxlbWVudCwge1xyXG4gICAgICAgICAgICAuLi50aGlzLmltYWdlVmlld2VyT3B0aW9ucywgLi4ue1xyXG4gICAgICAgICAgICAgICAgaGlkZGVuKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ndERyb3B6b25lQ29tcG9uZW50LmZvcmNlRGlzYWJsZUNsaWNrID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmlld2VyLmRlc3Ryb3koKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB2aWV3ZXIuc2hvdygpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvbkZpbGVDbGljayh1cmwsIG5hbWUpIHtcclxuICAgICAgICB0aGlzLmZvcmNlRGlzYWJsZUNsaWNrID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLnNob3dOZ3REcm9wem9uZUZpbGVWaWV3ZXIgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMubmd0RHJvcHpvbmVGaWxlVmlld2VyLnVybCA9IHVybDtcclxuICAgICAgICB0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci5maWxlTmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5uZ3REcm9wem9uZUZpbGVWaWV3ZXIuaW5pdCgpO1xyXG5cclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLm5ndERyb3B6b25lRmlsZVZpZXdlci5vbkNsb3NlLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2hvd05ndERyb3B6b25lRmlsZVZpZXdlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmZvcmNlRGlzYWJsZUNsaWNrID0gZmFsc2U7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBvblNlbGVjdChldmVudDogTmd4RHJvcHpvbmVDaGFuZ2VFdmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC5yZWplY3RlZEZpbGVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlamVjdGVkRmlsZSBvZiA8YW55PmV2ZW50LnJlamVjdGVkRmlsZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZWplY3RlZEZpbGUucmVhc29uID09ICdzaXplJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5TSVpFKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWRGaWxlLnJlYXNvbiA9PSAnbm9fbXVsdGlwbGUnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLk5PX01VTFRJUExFKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWRGaWxlLnJlYXNvbiA9PSAndHlwZScpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVNlbGVjdEVycm9yLmVtaXQoTmd0RHJvcHpvbmVFcnJvclR5cGUuVFlQRSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0RXJyb3IuZW1pdChOZ3REcm9wem9uZUVycm9yVHlwZS5ERUZBVUxUKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXRlbXNMaW1pdCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pdGVtc0xpbWl0ID09IDEgJiYgZXZlbnQuYWRkZWRGaWxlc1xyXG4gICAgICAgICAgICAgICAgJiYgZXZlbnQuYWRkZWRGaWxlcy5sZW5ndGggPT0gdGhpcy5pdGVtc0xpbWl0ICYmIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMubGVuZ3RoID09IHRoaXMuaXRlbXNMaW1pdCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcyA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZXZlbnQuYWRkZWRGaWxlc1xyXG4gICAgICAgICAgICAgICAgJiYgZXZlbnQuYWRkZWRGaWxlcy5sZW5ndGggKyB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzLmxlbmd0aCA8PSB0aGlzLml0ZW1zTGltaXQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0ZWQuZW1pdChldmVudCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKGV2ZW50LmFkZGVkRmlsZXMpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVTZWxlY3RFcnJvci5lbWl0KE5ndERyb3B6b25lRXJyb3JUeXBlLklURU1TX0xJTUlUKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub25GaWxlU2VsZWN0ZWQuZW1pdChldmVudCk7XHJcbiAgICAgICAgICAgIHRoaXMudXBsb2FkRmlsZXMoZXZlbnQuYWRkZWRGaWxlcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB1cGxvYWRGaWxlcyhmaWxlczogQXJyYXk8RmlsZT4pIHtcclxuICAgICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGxldCB0ZW1wb3JhcnlGaWxlcyA9IFtdO1xyXG4gICAgICAgICAgICBsZXQgdGVtcG9yYXJ5QXR0YWNobWVudHMgPSBbXTtcclxuICAgICAgICAgICAgbGV0IG9ic2VydmFibGVzID0gW107XHJcblxyXG4gICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgZmlsZXMuZm9yRWFjaChmaWxlID0+IHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmFibGVzLnB1c2godGhpcy5uZ3RBdHRhY2htZW50SHR0cFNlcnZpY2UudXBsb2FkKHRoaXMucmVtb3RlUmVzb3VyY2UsIGZpbGUpLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgbWFwKChyZXNwb25zZTogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5kYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuZGF0YS5hdHRyaWJ1dGVzICYmIHJlc3BvbnNlLmRhdGEuYXR0cmlidXRlcy5kYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVsndXJsJ10gPSByZXNwb25zZS5kYXRhLmF0dHJpYnV0ZXMuZGF0YS51cmw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcG9yYXJ5RmlsZXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IHJlc3BvbnNlLmRhdGEuaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZTogZmlsZS5zaXplLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGU6IGZpbGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZGF0YVsnbG9hZGVkJ10gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcG9yYXJ5QXR0YWNobWVudHMucHVzaChyZXNwb25zZS5kYXRhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICApKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcclxuICAgICAgICAgICAgICAgIGZvcmtKb2luKG9ic2VydmFibGVzKS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkZWRSZXNvdXJjZXMucHVzaCguLi50ZW1wb3JhcnlGaWxlcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pdGVtc0xpbWl0ID09IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25OYXRpdmVDaGFuZ2UoWy4uLnRlbXBvcmFyeUF0dGFjaG1lbnRzXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uTmF0aXZlQ2hhbmdlKFsuLi50ZW1wb3JhcnlBdHRhY2htZW50cywgLi4udGhpcy5uYXRpdmVWYWx1ZV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmlsZVVwbG9hZGVkLmVtaXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZpbGVVcGxvYWRGYWlsLmVtaXQoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgbG9hZEZpbGVQcmV2aWV3KGF0dGFjaG1lbnRzOiBhbnkpIHtcclxuICAgICAgICBpZiAoYXR0YWNobWVudHMgJiYgYXR0YWNobWVudHMubGVuZ3RoICYmIGF0dGFjaG1lbnRzWzBdKSB7XHJcbiAgICAgICAgICAgIGxldCB0ZW1wb3JhcnlSZXNvdXJjZSA9IFtdO1xyXG4gICAgICAgICAgICBsZXQgb2JzZXJ2YWJsZXMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIGF0dGFjaG1lbnRzLmZvckVhY2goYXR0YWNobWVudCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIShhdHRhY2htZW50IGluc3RhbmNlb2YgRmlsZSkgJiYgIWF0dGFjaG1lbnQubG9hZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50Wydsb2FkZWQnXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2YWJsZXMucHVzaCh0aGlzLm5ndEF0dGFjaG1lbnRIdHRwU2VydmljZS50aHVtYm5haWwoYXR0YWNobWVudCkucGlwZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChyZXNwb25zZTogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wb3JhcnlSZXNvdXJjZS5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZDogcmVzcG9uc2UuZGF0YS5nZXRBcGlJZCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGU6IHJlc3BvbnNlLmRhdGEuZ2V0QXR0cmlidXRlKCdmaWxlJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxyXG4gICAgICAgICAgICAgICAgZm9ya0pvaW4ob2JzZXJ2YWJsZXMpLnN1YnNjcmliZShcclxuICAgICAgICAgICAgICAgICAgICAocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcy5wdXNoKC4uLnRlbXBvcmFyeVJlc291cmNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZShhdHRhY2htZW50cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25GaWxlUHJldmlld0xvYWRlZC5lbWl0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvblJlbW92ZShyZXNvdXJjZTogYW55KSB7XHJcbiAgICAgICAgdGhpcy51cGxvYWRlZFJlc291cmNlcy5zcGxpY2UodGhpcy51cGxvYWRlZFJlc291cmNlcy5pbmRleE9mKHJlc291cmNlKSwgMSk7XHJcbiAgICAgICAgdGhpcy5uYXRpdmVWYWx1ZSA9IHRoaXMubmF0aXZlVmFsdWUuZmlsdGVyKGVsZW1lbnQgPT4gZWxlbWVudC5pZCAhPSByZXNvdXJjZS5pZCk7XHJcbiAgICAgICAgdGhpcy5vbk5hdGl2ZUNoYW5nZSh0aGlzLm5hdGl2ZVZhbHVlKTtcclxuICAgICAgICB0aGlzLm9uRmlsZVJlbW92ZWQuZW1pdChyZXNvdXJjZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzSW1hZ2UocmVzb3VyY2U6IGFueSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByZXZpZXdUeXBlID09ICdJTUFHRScgfHwgKHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlICYmIHJlc291cmNlLmZpbGUudHlwZS5pbmNsdWRlcygnaW1hZ2UnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzVmlkZW8ocmVzb3VyY2U6IGFueSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByZXZpZXdUeXBlID09ICdWSURFTycgfHwgKHJlc291cmNlLmZpbGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlICYmIHJlc291cmNlLmZpbGUudHlwZS5pbmNsdWRlcygndmlkZW8nKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzQXVkaW8ocmVzb3VyY2U6IGFueSkge1xyXG4gICAgICAgIHJldHVybiAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnR5cGUgJiYgcmVzb3VyY2UuZmlsZS50eXBlLmluY2x1ZGVzKCdhdWRpbycpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgaXNGaWxlKHJlc291cmNlOiBhbnkpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMuaXNJbWFnZShyZXNvdXJjZSkgJiYgIXRoaXMuaXNBdWRpbyhyZXNvdXJjZSkgJiYgIXRoaXMuaXNWaWRlbyhyZXNvdXJjZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEZvcm1hdHRlZEZpbGVTaXplKHJlc291cmNlOiBhbnkpIHtcclxuICAgICAgICBpZiAocmVzb3VyY2UpIHtcclxuICAgICAgICAgICAgbGV0IHNpemUgPSByZXNvdXJjZS5zaXplIHx8IHJlc291cmNlLmZpbGVTaXplO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFzaXplKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2UuZmlsZSAmJiByZXNvdXJjZS5maWxlLnNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICBzaXplID0gcmVzb3VyY2UuZmlsZS5zaXplO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBzaXplID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHBhcnNlRmxvYXQoc2l6ZSkgPiAxMDAwMDAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHBhcnNlRmxvYXQoc2l6ZSkgLyAxMDAwMDAwKS50b0ZpeGVkKDIpICsgJyBNYic7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHBhcnNlRmxvYXQoc2l6ZSkgLyAxMDAwKSArICcgS2InO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb25OYXRpdmVDaGFuZ2UodmFsdWU6IGFueSkge1xyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5uYXRpdmVWYWx1ZSA9IFtdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChKU09OLnN0cmluZ2lmeSh0aGlzLnZhbHVlKSAhPSBKU09OLnN0cmluZ2lmeSh0aGlzLm5hdGl2ZVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMubmF0aXZlVmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNoYW5nZSh2YWx1ZTogYW55KSB7XHJcbiAgICAgICAgaWYgKHZhbHVlICYmICF0aGlzLnZpZXdNb2RlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25OYXRpdmVDaGFuZ2UoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50UmVhZHkpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZEZpbGVQcmV2aWV3KEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZG93bmxvYWRGaWxlKGF0dGFjaG1lbnQ6IGFueSkge1xyXG4gICAgICAgIHRoaXMubmd0QXR0YWNobWVudEh0dHBTZXJ2aWNlLmRvd25sb2FkKGF0dGFjaG1lbnQpLnN1YnNjcmliZSgoKSA9PiB7IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZXNldCgpIHtcclxuICAgICAgICB0aGlzLnVwbG9hZGVkUmVzb3VyY2VzID0gW107XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtdO1xyXG4gICAgICAgIHRoaXMubmF0aXZlVmFsdWUgPSBbXTtcclxuICAgICAgICB0aGlzLmluaXRDb21wb25lbnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb3BlbkZpbGVTZWxlY3RvcigpIHtcclxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbmd4RHJvcHpvbmUnKS5jbGljaygpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaW5pdENvbXBvbmVudCgpIHtcclxuICAgICAgICBpZiAodGhpcy52aWV3TW9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLnByZXZpZXdUeXBlID0gTmd0RHJvcHpvbmVQcmV2aWV3VHlwZS5ERUZBVUxUO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZm9ybUNvbnRhaW5lciAmJiB0aGlzLmZvcm1Db250YWluZXIuY29udHJvbFxyXG4gICAgICAgICAgICAmJiAodGhpcy5mb3JtQ29udHJvbCA9IHRoaXMuZm9ybUNvbnRhaW5lci5jb250cm9sLmdldCh0aGlzLm5hbWUpKSkge1xyXG4gICAgICAgICAgICB0aGlzLnJlc2V0RmlsZXNMb2FkKCk7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZEZpbGVQcmV2aWV3KEFycmF5LmlzQXJyYXkodGhpcy52YWx1ZSkgPyB0aGlzLnZhbHVlIDogW3RoaXMudmFsdWVdKTtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVWYWxpZGF0aW9ucygpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzRGlydHkoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzUHJpc3RpbmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlc2V0RmlsZXNMb2FkKCkge1xyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMudmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUuZm9yRWFjaChlbGVtZW50ID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFsnbG9hZGVkJ10gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgdXBkYXRlVmFsaWRhdGlvbnMoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmZvcm1Db250cm9sKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBzeW5jVmFsaWRhdG9ycyA9IFtdO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc1JlcXVpcmVkKSB7XHJcbiAgICAgICAgICAgIHN5bmNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5yZXF1aXJlZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzeW5jVmFsaWRhdG9ycy5wdXNoKCk7XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Db250cm9sLnNldFZhbGlkYXRvcnMoc3luY1ZhbGlkYXRvcnMpO1xyXG4gICAgICAgICAgICB0aGlzLmZvcm1Db250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGRlc3Ryb3lTdWJzY3JpcHRpb25zKCkge1xyXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHN1YnNjcmlwdGlvbiA9PiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKSk7XHJcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gW107XHJcbiAgICB9XHJcbn1cclxuIl19