@smartbit4all/ng-client 4.2.113 → 4.2.115

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 (34) hide show
  1. package/esm2022/lib/smart-client/smart-component-api-client.mjs +34 -2
  2. package/esm2022/lib/smart-form/api/model/fileUploaderProperties.mjs +2 -0
  3. package/esm2022/lib/smart-form/api/model/models.mjs +2 -1
  4. package/esm2022/lib/smart-form/services/smartform.layout-definition.service.mjs +2 -5
  5. package/esm2022/lib/smart-form/smartfileuploader/smartfileuploader.component.mjs +126 -29
  6. package/esm2022/lib/smart-form/smartform.form-model.mjs +1 -1
  7. package/esm2022/lib/smart-form/widgets/smartformwidget/smartformwidget.component.mjs +18 -13
  8. package/esm2022/lib/view-context/projects.mjs +4 -3
  9. package/esm2022/lib/view-context/smart-ui-action/components/upload-widget/photo-capture-widget/photo-capture-widget.component.mjs +198 -0
  10. package/esm2022/lib/view-context/smart-ui-action/components/upload-widget/upload-widget.component.mjs +118 -0
  11. package/esm2022/lib/view-context/smart-ui-action/components/upload-widget/voice-record-widget/voice-record-widget.component.mjs +186 -0
  12. package/esm2022/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/ui-action-file-upload-dialog.component.mjs +15 -104
  13. package/esm2022/lib/view-context/smart-view-context.module.mjs +18 -13
  14. package/esm2022/lib/view-context/smart-view-context.service.mjs +2 -2
  15. package/fesm2022/smartbit4all-ng-client.mjs +1178 -1024
  16. package/fesm2022/smartbit4all-ng-client.mjs.map +1 -1
  17. package/lib/smart-client/smart-component-api-client.d.ts +2 -0
  18. package/lib/smart-form/api/model/fileUploaderProperties.d.ts +17 -0
  19. package/lib/smart-form/api/model/models.d.ts +1 -0
  20. package/lib/smart-form/smartfileuploader/smartfileuploader.component.d.ts +15 -2
  21. package/lib/smart-form/smartform.form-model.d.ts +2 -2
  22. package/lib/smart-form/widgets/smartformwidget/smartformwidget.component.d.ts +10 -2
  23. package/lib/view-context/projects.d.ts +3 -2
  24. package/lib/view-context/smart-ui-action/components/upload-widget/upload-widget.component.d.ts +38 -0
  25. package/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/ui-action-file-upload-dialog.component.d.ts +2 -19
  26. package/lib/view-context/smart-view-context.module.d.ts +50 -49
  27. package/lib/view-context/smart-view-context.service.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/smartbit4all-ng-client-4.2.115.tgz +0 -0
  30. package/esm2022/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/photo-capture-widget/photo-capture-widget.component.mjs +0 -198
  31. package/esm2022/lib/view-context/smart-ui-action/dialogs/ui-action-file-upload-dialog/voice-record-widget/voice-record-widget.component.mjs +0 -186
  32. package/smartbit4all-ng-client-4.2.113.tgz +0 -0
  33. /package/lib/view-context/smart-ui-action/{dialogs/ui-action-file-upload-dialog → components/upload-widget}/photo-capture-widget/photo-capture-widget.component.d.ts +0 -0
  34. /package/lib/view-context/smart-ui-action/{dialogs/ui-action-file-upload-dialog → components/upload-widget}/voice-record-widget/voice-record-widget.component.d.ts +0 -0
@@ -82,6 +82,8 @@ export declare abstract class SmartComponentApiClient<T> implements UseUiAction2
82
82
  addDataChangeActionHandler(key: string): void;
83
83
  removeDataChangeActionHandler(key: string): void;
84
84
  protected dataChangeActionHandler(event: SophisticatedValueChange): void;
85
+ protected handleLayoutUploadCallback(form: SmartComponentLayoutComponent): void;
86
+ protected handleUploadCallback(form: SmartformComponent): void;
85
87
  protected handleDataChangeSubscriptions(): void;
86
88
  getInvalidFields(): SmartFormInvalidFields;
87
89
  protected validateForm(form: SmartformComponent | undefined, aggregatedInvalidFields: SmartFormInvalidFields): void;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Form layout definition
3
+ * Contains form layout definition objects.
4
+ *
5
+ * The version of the OpenAPI document: 1.0.0
6
+ * Contact: info@it4all.hu
7
+ *
8
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9
+ * https://openapi-generator.tech
10
+ * Do not edit the class manually.
11
+ */
12
+ import { UiActionUploadDescriptor } from '../../../view-context/api/model/uiActionUploadDescriptor';
13
+ export interface FileUploaderProperties {
14
+ uiActionCode?: string;
15
+ isMultiple?: boolean;
16
+ uploadDescriptor?: UiActionUploadDescriptor;
17
+ }
@@ -1,3 +1,4 @@
1
+ export * from './fileUploaderProperties';
1
2
  export * from './imageProperties';
2
3
  export * from './propertyMapping';
3
4
  export * from './selectionDefinition';
@@ -1,22 +1,35 @@
1
1
  import { ElementRef, OnInit } from '@angular/core';
2
2
  import { MatSnackBar } from '@angular/material/snack-bar';
3
3
  import { SmartFileUploaderI18n } from './smartfileuploader.model';
4
+ import { UiActionDescriptor } from '../../view-context/api/model/models';
4
5
  import * as i0 from "@angular/core";
5
6
  export declare class SmartfileuploaderComponent implements OnInit {
6
7
  private _snackBar;
7
8
  fileInput: ElementRef<HTMLInputElement>;
8
- files: any[];
9
- uploadCallback: (files: any[]) => void;
9
+ files: File[];
10
+ uploadCallback: (files: File[]) => void;
10
11
  fileFormats?: string[];
11
12
  maxSizeMb?: number;
12
13
  i18n?: SmartFileUploaderI18n;
13
14
  useIconButton: boolean;
14
15
  isMultiple?: boolean;
16
+ isDragOver: boolean;
17
+ errors: string[];
15
18
  constructor(_snackBar: MatSnackBar);
16
19
  ngOnInit(): void;
20
+ private processFiles;
17
21
  getFile(event: any): void;
22
+ onDrop(event: DragEvent): void;
23
+ onDragOver(event: DragEvent): void;
24
+ onDragLeave(event: DragEvent): void;
18
25
  remove(index: number): void;
19
26
  uploadFile(): void;
27
+ formatSize(bytes: number): string;
28
+ filePreviewUrl(file: File): string | null;
29
+ downloadFile(file: File): void;
30
+ get uploadButton(): UiActionDescriptor;
31
+ get downloadButton(): UiActionDescriptor;
32
+ get removeButton(): UiActionDescriptor;
20
33
  static ɵfac: i0.ɵɵFactoryDeclaration<SmartfileuploaderComponent, never>;
21
34
  static ɵcmp: i0.ɵɵComponentDeclaration<SmartfileuploaderComponent, "smartfileuploader", never, { "uploadCallback": { "alias": "uploadCallback"; "required": false; }; "fileFormats": { "alias": "fileFormats"; "required": false; }; "maxSizeMb": { "alias": "maxSizeMb"; "required": false; }; "i18n": { "alias": "i18n"; "required": false; }; "useIconButton": { "alias": "useIconButton"; "required": false; }; "isMultiple": { "alias": "isMultiple"; "required": false; }; }, {}, never, never, false, never>;
22
35
  }
@@ -1,5 +1,5 @@
1
1
  import { QuillModules } from 'ngx-quill';
2
- import { ImageProperties, SelectionDefinition, SmartFormInputMode, SmartFormWidgetDirection, SmartFormWidgetType, SmartWidgetHint, SortDefinition, TextFieldProperties, ValueChangeMode } from './api';
2
+ import { FileUploaderProperties, ImageProperties, SelectionDefinition, SmartFormInputMode, SmartFormWidgetDirection, SmartFormWidgetType, SmartWidgetHint, SortDefinition, TextFieldProperties, ValueChangeMode } from './api';
3
3
  import { SmartFormTextFieldButton, SmartFormWidgetWidth, SmartIndicator, SmartValidator, ToggleLabelPosition } from './smartform.model';
4
4
  import { ImageResource, Style } from '../view-context/api';
5
5
  export declare type SmartFormWidget<T> = SmartTextField<T> | SmartTextFieldNumber<T> | SmartTextFieldChips<T> | SmartTextFieldLookup<T> | SmartTextBox<T> | SmartSelect<T> | SmartSelectMultiple<T> | SmartCheckBox<T> | SmartCheckBox2<T> | SmartRadioButton<T> | SmartDatePicker<T> | SmartDateTimePicker<T> | SmartContainer<T> | SmartLabel | SmartTime<T> | SmartToggle<T> | SmartIndicatorItem | SmartFileUploader | SmartImage | SmartDivider | SmartButton | SmartFormInlineComponent | SmartRichText | SmartSortable<T> | SmartMatrix | SmartYoutubePlayer | SmartMonthPicker | SmartSvg;
@@ -501,10 +501,10 @@ export interface SmartFileUploader {
501
501
  cssLabelClass?: string;
502
502
  style?: Style;
503
503
  labelStyle?: Style;
504
- uploadCallback: (key: string, files: any[]) => void;
505
504
  fileFormats?: string[];
506
505
  maxSizeMb?: number;
507
506
  i18n?: any;
507
+ fileUploaderProperties?: FileUploaderProperties;
508
508
  }
509
509
  export interface SmartImage {
510
510
  type: SmartFormWidgetType.IMAGE;
@@ -13,11 +13,18 @@ import { SmartButton, SmartFormWidget, SmartItem, SmartItems } from '../../smart
13
13
  import { SmartFormTextFieldButtonIconPosition, SmartValidator, SophisticatedValueChange, Value } from '../../smartform.model';
14
14
  import { ComponentLibrary } from '../../../view-context/utility/componentLibrary';
15
15
  import { EditorTextChangeEvent } from 'primeng/editor';
16
- import { UiActionDescriptor } from '../../../view-context/api';
16
+ import { UiActionDescriptor, UiActionUploadDescriptor } from '../../../view-context/api';
17
17
  import * as i0 from "@angular/core";
18
18
  export declare class SmartWidgetSettings {
19
19
  static useUtc: boolean;
20
20
  }
21
+ export interface UploadCallbackProps {
22
+ files: File[];
23
+ actionCode: string;
24
+ uploadDescriptor: UiActionUploadDescriptor;
25
+ isMultiple: Boolean;
26
+ }
27
+ export type UploadCallback = (props: UploadCallbackProps) => Promise<void>;
21
28
  export declare class SmartformwidgetComponent implements OnInit, OnDestroy, AfterViewInit {
22
29
  private service;
23
30
  private cfService;
@@ -26,6 +33,7 @@ export declare class SmartformwidgetComponent implements OnInit, OnDestroy, Afte
26
33
  changeDetector: ChangeDetectorRef;
27
34
  private _destroy$;
28
35
  hidePassword: boolean;
36
+ uploadCallback?: UploadCallback;
29
37
  form: UntypedFormGroup;
30
38
  widgetInstance: SmartFormWidget<any>;
31
39
  onBlur?: Subject<any>;
@@ -128,7 +136,7 @@ export declare class SmartformwidgetComponent implements OnInit, OnDestroy, Afte
128
136
  getIndicatorItemClass(index: number): string;
129
137
  getIndicatorStatusLabelColor(): string;
130
138
  getIndicatorStatusLabel(): string;
131
- upload(files: any[]): void;
139
+ upload(event: any, uiACtionCode: string): void;
132
140
  getButtonType(descriptor: any): string;
133
141
  isOnlyIcon(descriptor: any): boolean;
134
142
  onButtonClicked(instance: SmartButton): void;
@@ -13,7 +13,8 @@ export * from './smart-ui-action/dialogs/ui-action-input-dialog/ui-action-input-
13
13
  export * from './smart-ui-action/dialogs/ui-action-input-dialog/ui-action-input-dialog.component';
14
14
  export * from './smart-ui-action/dialogs/ui-action-dialog-button/ui-action-dialog-button.component';
15
15
  export * from './utility/componentLibrary';
16
- export * from './smart-ui-action/dialogs/ui-action-file-upload-dialog/photo-capture-widget/photo-capture-widget.component';
17
- export * from './smart-ui-action/dialogs/ui-action-file-upload-dialog/voice-record-widget/voice-record-widget.component';
18
16
  export * from './smart-ui-action/ui-action-button/ui-action-button.component';
19
17
  export * from './smart-ui-action/components/menu/menu.component';
18
+ export * from './smart-ui-action/components/upload-widget/upload-widget.component';
19
+ export * from './smart-ui-action/components/upload-widget/photo-capture-widget/photo-capture-widget.component';
20
+ export * from './smart-ui-action/components/upload-widget/voice-record-widget/voice-record-widget.component';
@@ -0,0 +1,38 @@
1
+ import { ChangeDetectorRef, EventEmitter } from '@angular/core';
2
+ import { FileUpload } from 'primeng/fileupload';
3
+ import { UiActionUploadDescriptor, UploadWidgetType } from '../../../api';
4
+ import { ComponentLibrary } from '../../../utility/componentLibrary';
5
+ import { SmartfileuploaderComponent } from '../../../../smart-form/smartfileuploader/smartfileuploader.component';
6
+ import { SmartFileUploaderI18n } from '../../../../smart-form/smartfileuploader/smartfileuploader.model';
7
+ import * as i0 from "@angular/core";
8
+ export declare class UploadWidgetComponent {
9
+ private cdr;
10
+ compLib?: ComponentLibrary | undefined;
11
+ fileUploadPrime: FileUpload;
12
+ fileUploadMaterial: SmartfileuploaderComponent;
13
+ uploadDescriptor: UiActionUploadDescriptor;
14
+ isMultiple: boolean;
15
+ uploadFilesEvent: EventEmitter<{
16
+ files: any[];
17
+ uploadDescriptor?: UiActionUploadDescriptor | undefined;
18
+ }>;
19
+ componentLibrary: typeof ComponentLibrary;
20
+ uploadWidgetType: typeof UploadWidgetType;
21
+ i18n?: SmartFileUploaderI18n;
22
+ maxSizeMb: number;
23
+ fileFormats?: string[];
24
+ constructor(cdr: ChangeDetectorRef, compLib?: ComponentLibrary | undefined);
25
+ ngOnInit(): void;
26
+ isMobile(): boolean;
27
+ setUp(): Promise<void>;
28
+ upload(files: any[]): void;
29
+ uploadFiles(event: any): void;
30
+ uploadRecording(file: any): void;
31
+ uploadImage(files: any): void;
32
+ loadFilesIntoWidget(files: File[]): void;
33
+ widgetNeeded(type: UploadWidgetType): boolean;
34
+ downloadFile(file: File): void;
35
+ formatSize(bytes: number): string;
36
+ static ɵfac: i0.ɵɵFactoryDeclaration<UploadWidgetComponent, [null, { optional: true; }]>;
37
+ static ɵcmp: i0.ɵɵComponentDeclaration<UploadWidgetComponent, "smart-upload-widget", never, { "uploadDescriptor": { "alias": "uploadDescriptor"; "required": false; }; "isMultiple": { "alias": "isMultiple"; "required": false; }; }, { "uploadFilesEvent": "uploadFilesEvent"; }, never, never, false, never>;
38
+ }
@@ -1,8 +1,7 @@
1
1
  import { ChangeDetectorRef, OnDestroy } from '@angular/core';
2
- import { UiActionDescriptor, UploadWidgetType } from '../../../api';
2
+ import { UiActionDescriptor } from '../../../api';
3
3
  import { UiActionDescriptorService } from '../../ui-action.descriptor.service';
4
4
  import { UiActionFileUploadDialogService } from './ui-action-file-upload-dialog.service';
5
- import { SmartFileUploaderI18n } from '../../../../smart-form/smartfileuploader/smartfileuploader.model';
6
5
  import { ComponentLibrary } from '../../../projects';
7
6
  import { FileUpload } from 'primeng/fileupload';
8
7
  import { SmartfileuploaderComponent } from '../../../../smart-form/smartfileuploader/smartfileuploader.component';
@@ -18,13 +17,7 @@ export declare class UiActionFileUploadDialogComponent implements OnDestroy {
18
17
  dialogType: 'dialog' | 'inputDialog' | 'input2Dialog';
19
18
  descriptor?: UiActionDescriptor;
20
19
  componentLibrary: typeof ComponentLibrary;
21
- uploadWidgetType: typeof UploadWidgetType;
22
- i18n?: SmartFileUploaderI18n;
23
- maxSizeMb: number;
24
- fileFormats?: string[];
25
20
  isMultiple?: boolean;
26
- hasFiles?: boolean;
27
- uploadedFiles: any[];
28
21
  cancelButton: UiActionDescriptor;
29
22
  constructor(service: UiActionFileUploadDialogService, compLib: ComponentLibrary, manager: UiActionDescriptorService, cdr: ChangeDetectorRef);
30
23
  ngOnDestroy(): void;
@@ -36,18 +29,8 @@ export declare class UiActionFileUploadDialogComponent implements OnDestroy {
36
29
  getActionButtonColor(): string;
37
30
  getCancelButtonLabel(): string;
38
31
  getCancelButtonColor(): string;
39
- upload(files: any[]): void;
40
- onSelect(event: any): void;
41
- onRemove(event: any): void;
42
- uploadFiles(event: any): void;
32
+ upload(event: any): void;
43
33
  cancel(): void;
44
- uploadRecording(file: any): void;
45
- uploadImage(files: any): void;
46
- loadFilesIntoWidget(files: File[]): void;
47
- widgetNeeded(type: UploadWidgetType): boolean;
48
- downloadFile(file: File): void;
49
- removeFile(index: number): void;
50
- formatSize(bytes: number): string;
51
34
  static ɵfac: i0.ɵɵFactoryDeclaration<UiActionFileUploadDialogComponent, never>;
52
35
  static ɵcmp: i0.ɵɵComponentDeclaration<UiActionFileUploadDialogComponent, "lib-ui-action-file-upload-dialog", never, {}, {}, never, never, false, never>;
53
36
  }
@@ -18,56 +18,57 @@ import * as i16 from "../smart-form/smartfileuploader/large-file-snack-bar/large
18
18
  import * as i17 from "../smart-form/widgets/smartformwidget/sortable-widget/sortable-widget.component";
19
19
  import * as i18 from "../smart-form/widgets/components/smart-month-picker/smart-month-picker.component";
20
20
  import * as i19 from "../smart-form/highlightMacthingString-pipe";
21
- import * as i20 from "./smart-ui-action/dialogs/ui-action-file-upload-dialog/voice-record-widget/voice-record-widget.component";
22
- import * as i21 from "./smart-ui-action/dialogs/ui-action-file-upload-dialog/photo-capture-widget/photo-capture-widget.component";
23
- import * as i22 from "./smart-ui-action/ui-action-button/ui-action-button.component";
24
- import * as i23 from "./smart-ui-action/components/menu/menu.component";
25
- import * as i24 from "@angular/common";
26
- import * as i25 from "@angular/common/http";
27
- import * as i26 from "@angular/material/core";
28
- import * as i27 from "@angular/material/button";
29
- import * as i28 from "primeng/button";
30
- import * as i29 from "@angular/material/icon";
31
- import * as i30 from "@angular/material/snack-bar";
32
- import * as i31 from "../smart-icon/smart-icon.module";
33
- import * as i32 from "@angular/material/tooltip";
34
- import * as i33 from "../shared/shared.module";
35
- import * as i34 from "primeng/api";
36
- import * as i35 from "@angular/platform-browser";
37
- import * as i36 from "@angular/material/chips";
38
- import * as i37 from "@angular/forms";
39
- import * as i38 from "@angular/material/form-field";
40
- import * as i39 from "@angular/material/checkbox";
41
- import * as i40 from "@angular/material/select";
42
- import * as i41 from "@angular/material/input";
43
- import * as i42 from "@angular/material/datepicker";
44
- import * as i43 from "@angular/material-moment-adapter";
45
- import * as i44 from "@angular/material/radio";
46
- import * as i45 from "@angular/material/slide-toggle";
47
- import * as i46 from "@angular/material/autocomplete";
48
- import * as i47 from "ngx-quill";
49
- import * as i48 from "@angular/cdk/drag-drop";
50
- import * as i49 from "@angular/youtube-player";
51
- import * as i50 from "primeng/inputtext";
52
- import * as i51 from "primeng/dropdown";
53
- import * as i52 from "primeng/multiselect";
54
- import * as i53 from "primeng/inputswitch";
55
- import * as i54 from "primeng/inputnumber";
56
- import * as i55 from "primeng/inputtextarea";
57
- import * as i56 from "primeng/image";
58
- import * as i57 from "primeng/floatlabel";
59
- import * as i58 from "primeng/toast";
60
- import * as i59 from "primeng/dynamicdialog";
61
- import * as i60 from "primeng/fileupload";
62
- import * as i61 from "primeng/chips";
63
- import * as i62 from "primeng/calendar";
64
- import * as i63 from "primeng/checkbox";
65
- import * as i64 from "primeng/orderlist";
66
- import * as i65 from "primeng/inputmask";
67
- import * as i66 from "primeng/editor";
68
- import * as i67 from "@angular/material/menu";
21
+ import * as i20 from "./smart-ui-action/ui-action-button/ui-action-button.component";
22
+ import * as i21 from "./smart-ui-action/components/menu/menu.component";
23
+ import * as i22 from "./smart-ui-action/components/upload-widget/upload-widget.component";
24
+ import * as i23 from "./smart-ui-action/components/upload-widget/voice-record-widget/voice-record-widget.component";
25
+ import * as i24 from "./smart-ui-action/components/upload-widget/photo-capture-widget/photo-capture-widget.component";
26
+ import * as i25 from "@angular/common";
27
+ import * as i26 from "@angular/common/http";
28
+ import * as i27 from "@angular/material/core";
29
+ import * as i28 from "@angular/material/button";
30
+ import * as i29 from "primeng/button";
31
+ import * as i30 from "@angular/material/icon";
32
+ import * as i31 from "@angular/material/snack-bar";
33
+ import * as i32 from "../smart-icon/smart-icon.module";
34
+ import * as i33 from "@angular/material/tooltip";
35
+ import * as i34 from "../shared/shared.module";
36
+ import * as i35 from "primeng/api";
37
+ import * as i36 from "@angular/platform-browser";
38
+ import * as i37 from "@angular/material/chips";
39
+ import * as i38 from "@angular/forms";
40
+ import * as i39 from "@angular/material/form-field";
41
+ import * as i40 from "@angular/material/checkbox";
42
+ import * as i41 from "@angular/material/select";
43
+ import * as i42 from "@angular/material/input";
44
+ import * as i43 from "@angular/material/datepicker";
45
+ import * as i44 from "@angular/material-moment-adapter";
46
+ import * as i45 from "@angular/material/radio";
47
+ import * as i46 from "@angular/material/slide-toggle";
48
+ import * as i47 from "@angular/material/autocomplete";
49
+ import * as i48 from "ngx-quill";
50
+ import * as i49 from "@angular/cdk/drag-drop";
51
+ import * as i50 from "@angular/youtube-player";
52
+ import * as i51 from "primeng/inputtext";
53
+ import * as i52 from "primeng/dropdown";
54
+ import * as i53 from "primeng/multiselect";
55
+ import * as i54 from "primeng/inputswitch";
56
+ import * as i55 from "primeng/inputnumber";
57
+ import * as i56 from "primeng/inputtextarea";
58
+ import * as i57 from "primeng/image";
59
+ import * as i58 from "primeng/floatlabel";
60
+ import * as i59 from "primeng/toast";
61
+ import * as i60 from "primeng/dynamicdialog";
62
+ import * as i61 from "primeng/fileupload";
63
+ import * as i62 from "primeng/chips";
64
+ import * as i63 from "primeng/calendar";
65
+ import * as i64 from "primeng/checkbox";
66
+ import * as i65 from "primeng/orderlist";
67
+ import * as i66 from "primeng/inputmask";
68
+ import * as i67 from "primeng/editor";
69
+ import * as i68 from "@angular/material/menu";
69
70
  export declare class SmartViewContextModule {
70
71
  static ɵfac: i0.ɵɵFactoryDeclaration<SmartViewContextModule, never>;
71
- static ɵmod: i0.ɵɵNgModuleDeclaration<SmartViewContextModule, [typeof i1.MessageDialogComponent, typeof i2.SmartViewContextErrorDialogComponent, typeof i3.SmartViewRedirect, typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i6.UiActionConfirmDialogComponent, typeof i7.UiActionFileUploadDialogComponent, typeof i8.InvalidFieldsSnackBarComponent, typeof i9.SmartformComponent, typeof i10.UiActionDialogButtonComponent, typeof i11.SmartformwidgetComponent, typeof i12.SmartfileuploaderComponent, typeof i13.TrackCapsDirective, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i16.LargeFileSnackBarComponent, typeof i17.SortableWidgetComponent, typeof i18.SmartMonthPickerComponent, typeof i19.HighlightPipe, typeof i20.VoiceRecordWidgetComponent, typeof i21.PhotoCaptureWidgetComponent, typeof i22.UiActionButtonComponent, typeof i23.MenuComponent], [typeof i24.CommonModule, typeof i25.HttpClientModule, typeof i26.MatCommonModule, typeof i27.MatButtonModule, typeof i28.ButtonModule, typeof i29.MatIconModule, typeof i30.MatSnackBarModule, typeof i31.SmartIconModule, typeof i32.MatTooltipModule, typeof i33.SharedModule, typeof i34.SharedModule, typeof i35.BrowserModule, typeof i36.MatChipsModule, typeof i37.FormsModule, typeof i37.ReactiveFormsModule, typeof i38.MatFormFieldModule, typeof i39.MatCheckboxModule, typeof i40.MatSelectModule, typeof i41.MatInputModule, typeof i42.MatDatepickerModule, typeof i43.MatMomentDateModule, typeof i44.MatRadioModule, typeof i45.MatSlideToggleModule, typeof i46.MatAutocompleteModule, typeof i47.QuillModule, typeof i48.DragDropModule, typeof i49.YouTubePlayerModule, typeof i50.InputTextModule, typeof i51.DropdownModule, typeof i52.MultiSelectModule, typeof i37.FormsModule, typeof i53.InputSwitchModule, typeof i54.InputNumberModule, typeof i55.InputTextareaModule, typeof i56.ImageModule, typeof i57.FloatLabelModule, typeof i24.CommonModule, typeof i58.ToastModule, typeof i59.DynamicDialogModule, typeof i60.FileUploadModule, typeof i61.ChipsModule, typeof i62.CalendarModule, typeof i63.CheckboxModule, typeof i64.OrderListModule, typeof i65.InputMaskModule, typeof i66.EditorModule, typeof i67.MatMenuModule, typeof i31.SmartIconModule], [typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i9.SmartformComponent, typeof i11.SmartformwidgetComponent, typeof i10.UiActionDialogButtonComponent, typeof i12.SmartfileuploaderComponent, typeof i19.HighlightPipe, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i20.VoiceRecordWidgetComponent, typeof i21.PhotoCaptureWidgetComponent, typeof i22.UiActionButtonComponent, typeof i23.MenuComponent]>;
72
+ static ɵmod: i0.ɵɵNgModuleDeclaration<SmartViewContextModule, [typeof i1.MessageDialogComponent, typeof i2.SmartViewContextErrorDialogComponent, typeof i3.SmartViewRedirect, typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i6.UiActionConfirmDialogComponent, typeof i7.UiActionFileUploadDialogComponent, typeof i8.InvalidFieldsSnackBarComponent, typeof i9.SmartformComponent, typeof i10.UiActionDialogButtonComponent, typeof i11.SmartformwidgetComponent, typeof i12.SmartfileuploaderComponent, typeof i13.TrackCapsDirective, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i16.LargeFileSnackBarComponent, typeof i17.SortableWidgetComponent, typeof i18.SmartMonthPickerComponent, typeof i19.HighlightPipe, typeof i20.UiActionButtonComponent, typeof i21.MenuComponent, typeof i22.UploadWidgetComponent, typeof i23.VoiceRecordWidgetComponent, typeof i24.PhotoCaptureWidgetComponent], [typeof i25.CommonModule, typeof i26.HttpClientModule, typeof i27.MatCommonModule, typeof i28.MatButtonModule, typeof i29.ButtonModule, typeof i30.MatIconModule, typeof i31.MatSnackBarModule, typeof i32.SmartIconModule, typeof i33.MatTooltipModule, typeof i34.SharedModule, typeof i35.SharedModule, typeof i36.BrowserModule, typeof i37.MatChipsModule, typeof i38.FormsModule, typeof i38.ReactiveFormsModule, typeof i39.MatFormFieldModule, typeof i40.MatCheckboxModule, typeof i41.MatSelectModule, typeof i42.MatInputModule, typeof i43.MatDatepickerModule, typeof i44.MatMomentDateModule, typeof i45.MatRadioModule, typeof i46.MatSlideToggleModule, typeof i47.MatAutocompleteModule, typeof i48.QuillModule, typeof i49.DragDropModule, typeof i50.YouTubePlayerModule, typeof i51.InputTextModule, typeof i52.DropdownModule, typeof i53.MultiSelectModule, typeof i38.FormsModule, typeof i54.InputSwitchModule, typeof i55.InputNumberModule, typeof i56.InputTextareaModule, typeof i57.ImageModule, typeof i58.FloatLabelModule, typeof i25.CommonModule, typeof i59.ToastModule, typeof i60.DynamicDialogModule, typeof i61.FileUploadModule, typeof i62.ChipsModule, typeof i63.CalendarModule, typeof i64.CheckboxModule, typeof i65.OrderListModule, typeof i66.InputMaskModule, typeof i67.EditorModule, typeof i68.MatMenuModule, typeof i32.SmartIconModule], [typeof i4.UiActionToolbarComponent, typeof i5.UiActionInputDialogComponent, typeof i9.SmartformComponent, typeof i11.SmartformwidgetComponent, typeof i10.UiActionDialogButtonComponent, typeof i12.SmartfileuploaderComponent, typeof i19.HighlightPipe, typeof i14.ComparableDropdownDirective, typeof i15.ComparableMultiselectDirective, typeof i20.UiActionButtonComponent, typeof i21.MenuComponent, typeof i22.UploadWidgetComponent, typeof i23.VoiceRecordWidgetComponent, typeof i24.PhotoCaptureWidgetComponent]>;
72
73
  static ɵinj: i0.ɵɵInjectorDeclaration<SmartViewContextModule>;
73
74
  }
@@ -34,7 +34,7 @@ export declare class SmartViewContextService implements OnDestroy {
34
34
  viewContextHasBeenSynced: Subject<void>;
35
35
  private initializeRunning;
36
36
  smartViewContextApiErrors?: SmartViewContextApiErrors;
37
- openSmartLink: Subject<void>;
37
+ openSmartLink: Subject<string>;
38
38
  isOpeningSmartLink: boolean;
39
39
  private dialogRefs;
40
40
  private actionDescriptors?;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartbit4all/ng-client",
3
- "version": "4.2.113",
3
+ "version": "4.2.115",
4
4
  "peerDependencies": {
5
5
  "@angular/animations": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0",
6
6
  "@angular/common": "^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0",
@@ -1,198 +0,0 @@
1
- import { Component, EventEmitter, Inject, Input, Optional, Output, ViewChild, } from '@angular/core';
2
- import { COMPONENT_LIBRARY, ComponentLibrary } from '../../../../utility/componentLibrary';
3
- import { UiActionButtonType } from '../../../../api/model/uiActionButtonType';
4
- import { IconPosition } from '../../../../api/model/iconPosition';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/common";
7
- import * as i2 from "../../../ui-action-button/ui-action-button.component";
8
- import * as i3 from "../../../../utility/componentLibrary";
9
- export class PhotoCaptureWidgetComponent {
10
- constructor(compLib) {
11
- this.photoCaptured = new EventEmitter();
12
- this.cameraActive = false;
13
- this.isCaptured = false;
14
- this.componentLibrary = ComponentLibrary;
15
- this.captureButton = {
16
- type: UiActionButtonType.RAISED,
17
- title: 'Kép készítése',
18
- icon: 'camera',
19
- iconPosition: IconPosition.PRE,
20
- color: 'primary',
21
- };
22
- this.compLib = compLib ?? ComponentLibrary.PRIMENG;
23
- this.updateToggleButton();
24
- }
25
- isMobile() {
26
- return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
27
- }
28
- async startCamera() {
29
- this.stream = await navigator.mediaDevices.getUserMedia({ video: true });
30
- this.videoRef.nativeElement.srcObject = this.stream;
31
- this.videoRef.nativeElement.play();
32
- this.cameraActive = true;
33
- this.isCaptured = false;
34
- this.updateToggleButton();
35
- }
36
- stopCamera() {
37
- this.stream?.getTracks().forEach((track) => track.stop());
38
- this.stream = undefined;
39
- this.cameraActive = false;
40
- this.updateToggleButton();
41
- }
42
- async capturePhoto() {
43
- const video = this.videoRef.nativeElement;
44
- const canvas = this.canvasRef.nativeElement;
45
- const context = canvas.getContext('2d');
46
- if (!context)
47
- return;
48
- canvas.width = video.videoWidth;
49
- canvas.height = video.videoHeight;
50
- context.drawImage(video, 0, 0);
51
- const blob = await new Promise((resolve) => canvas.toBlob(resolve, 'image/jpeg', 0.9));
52
- if (!blob)
53
- return;
54
- let file = new File([blob], `photo_${Date.now()}.jpg`, { type: 'image/jpeg' });
55
- if (this.maxFileSize && file.size > this.maxFileSize) {
56
- file = await this.compressImageFile(file, this.maxFileSize);
57
- }
58
- this.photoCaptured.emit([file]);
59
- this.isCaptured = true;
60
- this.stopCamera();
61
- }
62
- getPhotoDataURL() {
63
- return this.canvasRef.nativeElement.toDataURL('image/png');
64
- }
65
- async onFileSelected(event) {
66
- const input = event.target;
67
- if (!input.files || input.files.length === 0)
68
- return;
69
- const maxSize = this.maxFileSize;
70
- const filesArray = Array.from(input.files);
71
- const processedFiles = [];
72
- for (const file of filesArray) {
73
- if (maxSize && file.size > maxSize && file.type.startsWith('image/')) {
74
- try {
75
- const compressed = await this.compressImageFile(file, maxSize);
76
- processedFiles.push(compressed);
77
- }
78
- catch {
79
- processedFiles.push(file);
80
- }
81
- }
82
- else {
83
- processedFiles.push(file);
84
- }
85
- }
86
- this.photoCaptured.emit(processedFiles);
87
- }
88
- toggleCamera() {
89
- if (this.cameraActive) {
90
- this.stopCamera();
91
- }
92
- else {
93
- this.startCamera();
94
- }
95
- }
96
- updateToggleButton() {
97
- let icon = this.compLib === ComponentLibrary.PRIMENG ? 'power-off' : 'power_settings_new';
98
- let title;
99
- let color;
100
- if (this.cameraActive) {
101
- title = 'Kamera kikapcsolása';
102
- color = this.compLib === ComponentLibrary.PRIMENG ? 'danger' : 'red';
103
- }
104
- else {
105
- title = 'Kamera bekapcsolása';
106
- color = 'primary';
107
- }
108
- this.toggleCameraButton = {
109
- type: UiActionButtonType.RAISED,
110
- title: title,
111
- icon: icon,
112
- color,
113
- iconPosition: IconPosition.PRE,
114
- };
115
- }
116
- async compressImageFile(file, maxFileSize) {
117
- if (!file.type.startsWith('image/'))
118
- return file;
119
- const img = await new Promise((resolve, reject) => {
120
- const url = URL.createObjectURL(file);
121
- const image = new Image();
122
- image.onload = () => {
123
- URL.revokeObjectURL(url);
124
- resolve(image);
125
- };
126
- image.onerror = (e) => {
127
- URL.revokeObjectURL(url);
128
- reject(e);
129
- };
130
- image.src = url;
131
- });
132
- const canvas = document.createElement('canvas');
133
- const ctx = canvas.getContext('2d');
134
- if (!ctx)
135
- return file;
136
- let width = img.naturalWidth;
137
- let height = img.naturalHeight;
138
- let quality = 0.9;
139
- const minQuality = 0.4;
140
- const minDimension = 640;
141
- const getBlob = (q) => new Promise((resolve) => {
142
- canvas.width = width;
143
- canvas.height = height;
144
- ctx.clearRect(0, 0, width, height);
145
- ctx.drawImage(img, 0, 0, width, height);
146
- canvas.toBlob((blob) => {
147
- if (blob)
148
- resolve(blob);
149
- }, 'image/jpeg', q);
150
- });
151
- let blob = await getBlob(quality);
152
- while (blob.size > maxFileSize) {
153
- if (quality > minQuality) {
154
- quality -= 0.1;
155
- }
156
- else if (width > minDimension && height > minDimension) {
157
- width = Math.floor(width * 0.8);
158
- height = Math.floor(height * 0.8);
159
- quality = 0.9;
160
- }
161
- else {
162
- break;
163
- }
164
- blob = await getBlob(quality);
165
- }
166
- if (blob.size <= maxFileSize) {
167
- return new File([blob], file.name, { type: 'image/jpeg' });
168
- }
169
- else {
170
- return file;
171
- }
172
- }
173
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PhotoCaptureWidgetComponent, deps: [{ token: COMPONENT_LIBRARY, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
174
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PhotoCaptureWidgetComponent, selector: "photo-capture-widget", inputs: { maxFileSize: "maxFileSize" }, outputs: { photoCaptured: "photoCaptured" }, viewQueries: [{ propertyName: "videoRef", first: true, predicate: ["video"], descendants: true }, { propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true }, { propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"photoWidgetContainer\">\r\n <ng-container *ngIf=\"!isMobile()\">\r\n <video #video autoplay [hidden]=\"isCaptured || !cameraActive\"></video>\r\n <canvas #canvas [hidden]=\"!isCaptured || cameraActive\"></canvas>\r\n\r\n <ng-container *ngIf=\"!cameraActive && !isCaptured\">\r\n <p class=\"message\">Kapcsolja be a kamer\u00E1t a k\u00E9p k\u00E9sz\u00EDt\u00E9s\u00E9hez!</p>\r\n </ng-container>\r\n\r\n <div class=\"controls\">\r\n <!-- START CAMERA -->\r\n <ui-action-button [descriptor]=\"toggleCameraButton\" (actionClick)=\"toggleCamera()\">\r\n </ui-action-button>\r\n\r\n <!-- CAPTURE CAMERA -->\r\n <ui-action-button\r\n [disabled]=\"!cameraActive\"\r\n [descriptor]=\"captureButton\"\r\n (actionClick)=\"capturePhoto()\"\r\n >\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"isMobile()\">\r\n <div class=\"controls\">\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"image/*\"\r\n capture=\"environment\"\r\n (change)=\"onFileSelected($event)\"\r\n style=\"display: none\"\r\n />\r\n\r\n <ui-action-button [descriptor]=\"captureButton\" (actionClick)=\"fileInput.click()\">\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [".photoWidgetContainer{border-radius:5px;width:100%;max-width:100%;display:flex;flex-direction:column;justify-content:center;border:1px solid #dee2e6}.message{text-align:center;color:#6b7280}video,canvas{border-top-right-radius:5px;border-top-left-radius:5px;width:100%}.controls{padding:.5rem;display:flex;gap:1rem;flex-direction:row;justify-content:center;background:#f8f9fa;border-top:1px solid #dee2e6;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.controls ::ng-deep button{border-radius:3px}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.UiActionButtonComponent, selector: "ui-action-button", inputs: ["disabled", "descriptor", "code", "addedCssClass"], outputs: ["actionClick", "actionDoubleClick"] }] }); }
175
- }
176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PhotoCaptureWidgetComponent, decorators: [{
177
- type: Component,
178
- args: [{ selector: 'photo-capture-widget', template: "<div class=\"photoWidgetContainer\">\r\n <ng-container *ngIf=\"!isMobile()\">\r\n <video #video autoplay [hidden]=\"isCaptured || !cameraActive\"></video>\r\n <canvas #canvas [hidden]=\"!isCaptured || cameraActive\"></canvas>\r\n\r\n <ng-container *ngIf=\"!cameraActive && !isCaptured\">\r\n <p class=\"message\">Kapcsolja be a kamer\u00E1t a k\u00E9p k\u00E9sz\u00EDt\u00E9s\u00E9hez!</p>\r\n </ng-container>\r\n\r\n <div class=\"controls\">\r\n <!-- START CAMERA -->\r\n <ui-action-button [descriptor]=\"toggleCameraButton\" (actionClick)=\"toggleCamera()\">\r\n </ui-action-button>\r\n\r\n <!-- CAPTURE CAMERA -->\r\n <ui-action-button\r\n [disabled]=\"!cameraActive\"\r\n [descriptor]=\"captureButton\"\r\n (actionClick)=\"capturePhoto()\"\r\n >\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"isMobile()\">\r\n <div class=\"controls\">\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"image/*\"\r\n capture=\"environment\"\r\n (change)=\"onFileSelected($event)\"\r\n style=\"display: none\"\r\n />\r\n\r\n <ui-action-button [descriptor]=\"captureButton\" (actionClick)=\"fileInput.click()\">\r\n </ui-action-button>\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [".photoWidgetContainer{border-radius:5px;width:100%;max-width:100%;display:flex;flex-direction:column;justify-content:center;border:1px solid #dee2e6}.message{text-align:center;color:#6b7280}video,canvas{border-top-right-radius:5px;border-top-left-radius:5px;width:100%}.controls{padding:.5rem;display:flex;gap:1rem;flex-direction:row;justify-content:center;background:#f8f9fa;border-top:1px solid #dee2e6;border-bottom-right-radius:5px;border-bottom-left-radius:5px}.controls ::ng-deep button{border-radius:3px}\n"] }]
179
- }], ctorParameters: () => [{ type: i3.ComponentLibrary, decorators: [{
180
- type: Inject,
181
- args: [COMPONENT_LIBRARY]
182
- }, {
183
- type: Optional
184
- }] }], propDecorators: { videoRef: [{
185
- type: ViewChild,
186
- args: ['video']
187
- }], canvasRef: [{
188
- type: ViewChild,
189
- args: ['canvas']
190
- }], fileInputRef: [{
191
- type: ViewChild,
192
- args: ['fileInput']
193
- }], maxFileSize: [{
194
- type: Input
195
- }], photoCaptured: [{
196
- type: Output
197
- }] } });
198
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhvdG8tY2FwdHVyZS13aWRnZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtbmctY2xpZW50L3NyYy9saWIvdmlldy1jb250ZXh0L3NtYXJ0LXVpLWFjdGlvbi9kaWFsb2dzL3VpLWFjdGlvbi1maWxlLXVwbG9hZC1kaWFsb2cvcGhvdG8tY2FwdHVyZS13aWRnZXQvcGhvdG8tY2FwdHVyZS13aWRnZXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc21hcnQtbmctY2xpZW50L3NyYy9saWIvdmlldy1jb250ZXh0L3NtYXJ0LXVpLWFjdGlvbi9kaWFsb2dzL3VpLWFjdGlvbi1maWxlLXVwbG9hZC1kaWFsb2cvcGhvdG8tY2FwdHVyZS13aWRnZXQvcGhvdG8tY2FwdHVyZS13aWRnZXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUUzRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7Ozs7O0FBUWxFLE1BQU0sT0FBTywyQkFBMkI7SUEwQnRDLFlBQW1ELE9BQTBCO1FBcEJuRSxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFckQsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUtuQixxQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztRQUlwQyxrQkFBYSxH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QUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUM3RCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7K0dBcE1VLDJCQUEyQixrQkEwQmxCLGlCQUFpQjttR0ExQjFCLDJCQUEyQixzYUNyQnhDLG0xQ0F3Q0E7OzRGRG5CYSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0Usc0JBQXNCOzswQkE4Qm5CLE1BQU07MkJBQUMsaUJBQWlCOzswQkFBRyxRQUFRO3lDQXpCNUIsUUFBUTtzQkFBM0IsU0FBUzt1QkFBQyxPQUFPO2dCQUNHLFNBQVM7c0JBQTdCLFNBQVM7dUJBQUMsUUFBUTtnQkFDSyxZQUFZO3NCQUFuQyxTQUFTO3VCQUFDLFdBQVc7Z0JBRWIsV0FBVztzQkFBbkIsS0FBSztnQkFDSSxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgRWxlbWVudFJlZixcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5qZWN0LFxyXG4gIElucHV0LFxyXG4gIE9wdGlvbmFsLFxyXG4gIE91dHB1dCxcclxuICBWaWV3Q2hpbGQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENPTVBPTkVOVF9MSUJSQVJZLCBDb21wb25lbnRMaWJyYXJ5IH0gZnJvbSAnLi4vLi4vLi4vLi4vdXRpbGl0eS9jb21wb25lbnRMaWJyYXJ5JztcclxuaW1wb3J0IHsgVWlBY3Rpb25Nb2RlbCB9IGZyb20gJy4uLy4uLy4uL3VpLWFjdGlvbi5tb2RlbCc7XHJcbmltcG9ydCB7IFVpQWN0aW9uQnV0dG9uVHlwZSB9IGZyb20gJy4uLy4uLy4uLy4uL2FwaS9tb2RlbC91aUFjdGlvbkJ1dHRvblR5cGUnO1xyXG5pbXBvcnQgeyBJY29uUG9zaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9hcGkvbW9kZWwvaWNvblBvc2l0aW9uJztcclxuaW1wb3J0IHsgVWlBY3Rpb25EZXNjcmlwdG9yIH0gZnJvbSAnLi4vLi4vLi4vLi4vYXBpJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncGhvdG8tY2FwdHVyZS13aWRnZXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9waG90by1jYXB0dXJlLXdpZGdldC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL3Bob3RvLWNhcHR1cmUtd2lkZ2V0LmNvbXBvbmVudC5jc3MnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgUGhvdG9DYXB0dXJlV2lkZ2V0Q29tcG9uZW50IHtcclxuICBAVmlld0NoaWxkKCd2aWRlbycpIHZpZGVvUmVmITogRWxlbWVudFJlZjxIVE1MVmlkZW9FbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdjYW52YXMnKSBjYW52YXNSZWYhOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdmaWxlSW5wdXQnKSBmaWxlSW5wdXRSZWYhOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xyXG5cclxuICBASW5wdXQoKSBtYXhGaWxlU2l6ZT86IG51bWJlcjtcclxuICBAT3V0cHV0KCkgcGhvdG9DYXB0dXJlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZVtdPigpO1xyXG5cclxuICBjYW1lcmFBY3RpdmUgPSBmYWxzZTtcclxuICBpc0NhcHR1cmVkID0gZmFsc2U7XHJcblxyXG4gIHN0cmVhbT86IE1lZGlhU3RyZWFtO1xyXG5cclxuICBjb21wTGliOiBDb21wb25lbnRMaWJyYXJ5O1xyXG4gIGNvbXBvbmVudExpYnJhcnkgPSBDb21wb25lbnRMaWJyYXJ5O1xyXG5cclxuICB0b2dnbGVDYW1lcmFCdXR0b24hOiBVaUFjdGlvbkRlc2NyaXB0b3I7XHJcblxyXG4gIGNhcHR1cmVCdXR0b246IFVpQWN0aW9uRGVzY3JpcHRvciA9IHtcclxuICAgIHR5cGU6IFVpQWN0aW9uQnV0dG9uVHlwZS5SQUlTRUQsXHJcbiAgICB0aXRsZTogJ0vDqXAga8Opc3rDrXTDqXNlJyxcclxuICAgIGljb246ICdjYW1lcmEnLFxyXG4gICAgaWNvblBvc2l0aW9uOiBJY29uUG9zaXRpb24uUFJFLFxyXG4gICAgY29sb3I6ICdwcmltYXJ5JyxcclxuICB9O1xyXG5cclxuICBjb25zdHJ1Y3RvcihASW5qZWN0KENPTVBPTkVOVF9MSUJSQVJZKSBAT3B0aW9uYWwoKSBjb21wTGliPzogQ29tcG9uZW50TGlicmFyeSkge1xyXG4gICAgdGhpcy5jb21wTGliID0gY29tcExpYiA/PyBDb21wb25lbnRMaWJyYXJ5LlBSSU1FTkc7XHJcbiAgICB0aGlzLnVwZGF0ZVRvZ2dsZUJ1dHRvbigpO1xyXG4gIH1cclxuXHJcbiAgaXNNb2JpbGUoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gL2lQaG9uZXxpUGFkfGlQb2R8QW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBzdGFydENhbWVyYSgpIHtcclxuICAgIHRoaXMuc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoeyB2aWRlbzogdHJ1ZSB9KTtcclxuICAgIHRoaXMudmlkZW9SZWYubmF0aXZlRWxlbWVudC5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbTtcclxuICAgIHRoaXMudmlkZW9SZWYubmF0aXZlRWxlbWVudC5wbGF5KCk7XHJcbiAgICB0aGlzLmNhbWVyYUFjdGl2ZSA9IHRydWU7XHJcbiAgICB0aGlzLmlzQ2FwdHVyZWQgPSBmYWxzZTtcclxuICAgIHRoaXMudXBkYXRlVG9nZ2xlQnV0dG9uKCk7XHJcbiAgfVxyXG5cclxuICBzdG9wQ2FtZXJhKCkge1xyXG4gICAgdGhpcy5zdHJlYW0/LmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB0cmFjay5zdG9wKCkpO1xyXG4gICAgdGhpcy5zdHJlYW0gPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmNhbWVyYUFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgdGhpcy51cGRhdGVUb2dnbGVCdXR0b24oKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNhcHR1cmVQaG90bygpIHtcclxuICAgIGNvbnN0IHZpZGVvID0gdGhpcy52aWRlb1JlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIGNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGlmICghY29udGV4dCkgcmV0dXJuO1xyXG5cclxuICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XHJcbiAgICBjYW52YXMuaGVpZ2h0ID0gdmlkZW8udmlkZW9IZWlnaHQ7XHJcbiAgICBjb250ZXh0LmRyYXdJbWFnZSh2aWRlbywgMCwgMCk7XHJcblxyXG4gICAgY29uc3QgYmxvYiA9IGF3YWl0IG5ldyBQcm9taXNlPEJsb2IgfCBudWxsPigocmVzb2x2ZSkgPT5cclxuICAgICAgY2FudmFzLnRvQmxvYihyZXNvbHZlLCAnaW1hZ2UvanBlZycsIDAuOSlcclxuICAgICk7XHJcbiAgICBpZiAoIWJsb2IpIHJldHVybjtcclxuXHJcbiAgICBsZXQgZmlsZSA9IG5ldyBGaWxlKFtibG9iXSwgYHBob3RvXyR7RGF0ZS5ub3coKX0uanBnYCwgeyB0eXBlOiAnaW1hZ2UvanBlZycgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMubWF4RmlsZVNpemUgJiYgZmlsZS5zaXplID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xyXG4gICAgICBmaWxlID0gYXdhaXQgdGhpcy5jb21wcmVzc0ltYWdlRmlsZShmaWxlLCB0aGlzLm1heEZpbGVTaXplKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnBob3RvQ2FwdHVyZWQuZW1pdChbZmlsZV0pO1xyXG4gICAgdGhpcy5pc0NhcHR1cmVkID0gdHJ1ZTtcclxuICAgIHRoaXMuc3RvcENhbWVyYSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGhvdG9EYXRhVVJMKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudC50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgb25GaWxlU2VsZWN0ZWQoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBjb25zdCBpbnB1dCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgaWYgKCFpbnB1dC5maWxlcyB8fCBpbnB1dC5maWxlcy5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBtYXhTaXplID0gdGhpcy5tYXhGaWxlU2l6ZTtcclxuICAgIGNvbnN0IGZpbGVzQXJyYXkgPSBBcnJheS5mcm9tKGlucHV0LmZpbGVzKTtcclxuICAgIGNvbnN0IHByb2Nlc3NlZEZpbGVzOiBGaWxlW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXNBcnJheSkge1xyXG4gICAgICBpZiAobWF4U2l6ZSAmJiBmaWxlLnNpemUgPiBtYXhTaXplICYmIGZpbGUudHlwZS5zdGFydHNXaXRoKCdpbWFnZS8nKSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBjb25zdCBjb21wcmVzc2VkID0gYXdhaXQgdGhpcy5jb21wcmVzc0ltYWdlRmlsZShmaWxlLCBtYXhTaXplKTtcclxuICAgICAgICAgIHByb2Nlc3NlZEZpbGVzLnB1c2goY29tcHJlc3NlZCk7XHJcbiAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICBwcm9jZXNzZWRGaWxlcy5wdXNoKGZpbGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBwcm9jZXNzZWRGaWxlcy5wdXNoKGZpbGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5waG90b0NhcHR1cmVkLmVtaXQocHJvY2Vzc2VkRmlsZXMpO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlQ2FtZXJhKCkge1xyXG4gICAgaWYgKHRoaXMuY2FtZXJhQWN0aXZlKSB7XHJcbiAgICAgIHRoaXMuc3RvcENhbWVyYSgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zdGFydENhbWVyYSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlVG9nZ2xlQnV0dG9uKCkge1xyXG4gICAgbGV0IGljb24gPSB0aGlzLmNvbXBMaWIgPT09IENvbXBvbmVudExpYnJhcnkuUFJJTUVORyA/ICdwb3dlci1vZmYnIDogJ3Bvd2VyX3NldHRpbmdzX25ldyc7XHJcbiAgICBsZXQgdGl0bGU7XHJcbiAgICBsZXQgY29sb3I7XHJcbiAgICBpZiAodGhpcy5jYW1lcmFBY3RpdmUpIHtcclxuICAgICAgdGl0bGUgPSAnS2FtZXJhIGtpa2FwY3NvbMOhc2EnO1xyXG4gICAgICBjb2xvciA9IHRoaXMuY29tcExpYiA9PT0gQ29tcG9uZW50TGlicmFyeS5QUklNRU5HID8gJ2RhbmdlcicgOiAncmVkJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRpdGxlID0gJ0thbWVyYSBiZWthcGNzb2zDoXNhJztcclxuICAgICAgY29sb3IgPSAncHJpbWFyeSc7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy50b2dnbGVDYW1lcmFCdXR0b24gPSB7XHJcbiAgICAgIHR5cGU6IFVpQWN0aW9uQnV0dG9uVHlwZS5SQUlTRUQsXHJcbiAgICAgIHRpdGxlOiB0aXRsZSxcclxuICAgICAgaWNvbjogaWNvbixcclxuICAgICAgY29sb3IsXHJcbiAgICAgIGljb25Qb3NpdGlvbjogSWNvblBvc2l0aW9uLlBSRSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGNvbXByZXNzSW1hZ2VGaWxlKGZpbGU6IEZpbGUsIG1heEZpbGVTaXplOiBudW1iZXIpOiBQcm9taXNlPEZpbGU+IHtcclxuICAgIGlmICghZmlsZS50eXBlLnN0YXJ0c1dpdGgoJ2ltYWdlLycpKSByZXR1cm4gZmlsZTtcclxuXHJcbiAgICBjb25zdCBpbWcgPSBhd2FpdCBuZXcgUHJvbWlzZTxIVE1MSW1hZ2VFbGVtZW50PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XHJcbiAgICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XHJcbiAgICAgIGltYWdlLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XHJcbiAgICAgICAgcmVzb2x2ZShpbWFnZSk7XHJcbiAgICAgIH07XHJcbiAgICAgIGltYWdlLm9uZXJyb3IgPSAoZSkgPT4ge1xyXG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcclxuICAgICAgICByZWplY3QoZSk7XHJcbiAgICAgIH07XHJcbiAgICAgIGltYWdlLnNyYyA9IHVybDtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xyXG4gICAgY29uc3QgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XHJcbiAgICBpZiAoIWN0eCkgcmV0dXJuIGZpbGU7XHJcblxyXG4gICAgbGV0IHdpZHRoID0gaW1nLm5hdHVyYWxXaWR0aDtcclxuICAgIGxldCBoZWlnaHQgPSBpbWcubmF0dXJhbEhlaWdodDtcclxuICAgIGxldCBxdWFsaXR5ID0gMC45O1xyXG4gICAgY29uc3QgbWluUXVhbGl0eSA9IDAuNDtcclxuICAgIGNvbnN0IG1pbkRpbWVuc2lvbiA9IDY0MDtcclxuXHJcbiAgICBjb25zdCBnZXRCbG9iID0gKHE6IG51bWJlcik6IFByb21pc2U8QmxvYj4gPT5cclxuICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICBjYW52YXMud2lkdGggPSB3aWR0aDtcclxuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xyXG4gICAgICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7XHJcbiAgICAgICAgY3R4LmRyYXdJbWFnZShpbWcsIDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xyXG4gICAgICAgIGNhbnZhcy50b0Jsb2IoXHJcbiAgICAgICAgICAoYmxvYikgPT4ge1xyXG4gICAgICAgICAgICBpZiAoYmxvYikgcmVzb2x2ZShibG9iKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICAnaW1hZ2UvanBlZycsXHJcbiAgICAgICAgICBxXHJcbiAgICAgICAgKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgbGV0IGJsb2IgPSBhd2FpdCBnZXRCbG9iKHF1YWxpdHkpO1xyXG5cclxuICAgIHdoaWxlIChibG9iLnNpemUgPiBtYXhGaWxlU2l6ZSkge1xyXG4gICAgICBpZiAocXVhbGl0eSA+IG1pblF1YWxpdHkpIHtcclxuICAgICAgICBxdWFsaXR5IC09IDAuMTtcclxuICAgICAgfSBlbHNlIGlmICh3aWR0aCA+IG1pbkRpbWVuc2lvbiAmJiBoZWlnaHQgPiBtaW5EaW1lbnNpb24pIHtcclxuICAgICAgICB3aWR0aCA9IE1hdGguZmxvb3Iod2lkdGggKiAwLjgpO1xyXG4gICAgICAgIGhlaWdodCA9IE1hdGguZmxvb3IoaGVpZ2h0ICogMC44KTtcclxuICAgICAgICBxdWFsaXR5ID0gMC45O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGJsb2IgPSBhd2FpdCBnZXRCbG9iKHF1YWxpdHkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChibG9iLnNpemUgPD0gbWF4RmlsZVNpemUpIHtcclxuICAgICAgcmV0dXJuIG5ldyBGaWxlKFtibG9iXSwgZmlsZS5uYW1lLCB7IHR5cGU6ICdpbWFnZS9qcGVnJyB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBmaWxlO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwicGhvdG9XaWRnZXRDb250YWluZXJcIj5cclxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzTW9iaWxlKClcIj5cclxuICAgIDx2aWRlbyAjdmlkZW8gYXV0b3BsYXkgW2hpZGRlbl09XCJpc0NhcHR1cmVkIHx8ICFjYW1lcmFBY3RpdmVcIj48L3ZpZGVvPlxyXG4gICAgPGNhbnZhcyAjY2FudmFzIFtoaWRkZW5dPVwiIWlzQ2FwdHVyZWQgfHwgY2FtZXJhQWN0aXZlXCI+PC9jYW52YXM+XHJcblxyXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjYW1lcmFBY3RpdmUgJiYgIWlzQ2FwdHVyZWRcIj5cclxuICAgICAgPHAgY2xhc3M9XCJtZXNzYWdlXCI+S2FwY3NvbGphIGJlIGEga2FtZXLDoXQgYSBrw6lwIGvDqXN6w610w6lzw6loZXohPC9wPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImNvbnRyb2xzXCI+XHJcbiAgICAgIDwhLS0gU1RBUlQgQ0FNRVJBIC0tPlxyXG4gICAgICA8dWktYWN0aW9uLWJ1dHRvbiBbZGVzY3JpcHRvcl09XCJ0b2dnbGVDYW1lcmFCdXR0b25cIiAoYWN0aW9uQ2xpY2spPVwidG9nZ2xlQ2FtZXJhKClcIj5cclxuICAgICAgPC91aS1hY3Rpb24tYnV0dG9uPlxyXG5cclxuICAgICAgPCEtLSBDQVBUVVJFIENBTUVSQSAtLT5cclxuICAgICAgPHVpLWFjdGlvbi1idXR0b25cclxuICAgICAgICBbZGlzYWJsZWRdPVwiIWNhbWVyYUFjdGl2ZVwiXHJcbiAgICAgICAgW2Rlc2NyaXB0b3JdPVwiY2FwdHVyZUJ1dHRvblwiXHJcbiAgICAgICAgKGFjdGlvbkNsaWNrKT1cImNhcHR1cmVQaG90bygpXCJcclxuICAgICAgPlxyXG4gICAgICA8L3VpLWFjdGlvbi1idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTW9iaWxlKClcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjb250cm9sc1wiPlxyXG4gICAgICA8aW5wdXRcclxuICAgICAgICAjZmlsZUlucHV0XHJcbiAgICAgICAgdHlwZT1cImZpbGVcIlxyXG4gICAgICAgIGFjY2VwdD1cImltYWdlLypcIlxyXG4gICAgICAgIGNhcHR1cmU9XCJlbnZpcm9ubWVudFwiXHJcbiAgICAgICAgKGNoYW5nZSk9XCJvbkZpbGVTZWxlY3RlZCgkZXZlbnQpXCJcclxuICAgICAgICBzdHlsZT1cImRpc3BsYXk6IG5vbmVcIlxyXG4gICAgICAvPlxyXG5cclxuICAgICAgPHVpLWFjdGlvbi1idXR0b24gW2Rlc2NyaXB0b3JdPVwiY2FwdHVyZUJ1dHRvblwiIChhY3Rpb25DbGljayk9XCJmaWxlSW5wdXQuY2xpY2soKVwiPlxyXG4gICAgICA8L3VpLWFjdGlvbi1idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L25nLWNvbnRhaW5lcj5cclxuPC9kaXY+XHJcbiJdfQ==