ngx-scandoc 0.0.1 → 1.0.1

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 (71) hide show
  1. package/core/app.worker.d.ts +1 -0
  2. package/core/components/components.module.d.ts +8 -0
  3. package/core/components/webcam/domain/webcam-image.d.ts +35 -0
  4. package/core/components/webcam/domain/webcam-init-error.d.ts +4 -0
  5. package/core/components/webcam/domain/webcam-mirror-properties.d.ts +3 -0
  6. package/core/components/webcam/util/webcam.util.d.ts +8 -0
  7. package/core/components/webcam/webcam/webcam.component.d.ts +202 -0
  8. package/core/components/webcam/webcam.module.d.ts +9 -0
  9. package/core/pipes/pipes.module.d.ts +7 -0
  10. package/core/pipes/safeResourceUrl.pipe.d.ts +10 -0
  11. package/core/shared/material.module.d.ts +28 -0
  12. package/dialogs/components/blank/blank.component.d.ts +17 -0
  13. package/dialogs/components/confirm/confirm.component.d.ts +30 -0
  14. package/dialogs/components/loading/loading.component.d.ts +5 -0
  15. package/dialogs/components/scan-mobile/scan-mobile.component.d.ts +16 -0
  16. package/dialogs/components/scan-profile/scan-profile.component.d.ts +124 -0
  17. package/dialogs/components/scan-selfie/scan-selfie.component.d.ts +83 -0
  18. package/dialogs/dialogs.core.provider.d.ts +18 -0
  19. package/dialogs/dialogs.module.d.ts +21 -0
  20. package/esm2020/core/app.worker.mjs +236 -0
  21. package/esm2020/core/components/components.module.mjs +18 -0
  22. package/esm2020/core/components/webcam/domain/webcam-image.mjs +58 -0
  23. package/esm2020/core/components/webcam/domain/webcam-init-error.mjs +3 -0
  24. package/esm2020/core/components/webcam/domain/webcam-mirror-properties.mjs +3 -0
  25. package/esm2020/core/components/webcam/util/webcam.util.mjs +48 -0
  26. package/esm2020/core/components/webcam/webcam/webcam.component.mjs +861 -0
  27. package/esm2020/core/components/webcam/webcam.module.mjs +22 -0
  28. package/esm2020/core/pipes/pipes.module.mjs +19 -0
  29. package/esm2020/core/pipes/safeResourceUrl.pipe.mjs +20 -0
  30. package/esm2020/core/shared/material.module.mjs +162 -0
  31. package/esm2020/dialogs/components/blank/blank.component.mjs +47 -0
  32. package/esm2020/dialogs/components/confirm/confirm.component.mjs +53 -0
  33. package/esm2020/dialogs/components/loading/loading.component.mjs +12 -0
  34. package/esm2020/dialogs/components/scan-mobile/scan-mobile.component.mjs +43 -0
  35. package/esm2020/dialogs/components/scan-profile/scan-profile.component.mjs +756 -0
  36. package/esm2020/dialogs/components/scan-selfie/scan-selfie.component.mjs +392 -0
  37. package/esm2020/dialogs/dialogs.core.provider.mjs +100 -0
  38. package/esm2020/dialogs/dialogs.module.mjs +89 -0
  39. package/esm2020/forms/form.module.mjs +87 -0
  40. package/esm2020/forms/types/avatar.type.mjs +53 -0
  41. package/esm2020/forms/types/profile.image.type.mjs +54 -0
  42. package/esm2020/forms/types/title.type.mjs +60 -0
  43. package/esm2020/lib/ngx-scandoc.module.mjs +28 -11
  44. package/esm2020/providers/auth.provider.mjs +57 -0
  45. package/esm2020/providers/interceptor.provider.mjs +61 -0
  46. package/esm2020/providers/scan.form.mjs +386 -0
  47. package/esm2020/providers/scan.provider.mjs +490 -0
  48. package/esm2020/providers/translation.provider.mjs +50 -0
  49. package/esm2020/providers/webrtc.provider.mjs +58 -0
  50. package/esm2020/public-api.mjs +22 -4
  51. package/fesm2015/ngx-scandoc.mjs +4178 -32
  52. package/fesm2015/ngx-scandoc.mjs.map +1 -1
  53. package/fesm2020/ngx-scandoc.mjs +4154 -32
  54. package/fesm2020/ngx-scandoc.mjs.map +1 -1
  55. package/forms/form.module.d.ts +18 -0
  56. package/forms/types/avatar.type.d.ts +14 -0
  57. package/forms/types/profile.image.type.d.ts +14 -0
  58. package/forms/types/title.type.d.ts +12 -0
  59. package/lib/ngx-scandoc.module.d.ts +20 -2
  60. package/package.json +6 -2
  61. package/providers/auth.provider.d.ts +21 -0
  62. package/providers/interceptor.provider.d.ts +13 -0
  63. package/providers/scan.form.d.ts +13 -0
  64. package/providers/scan.provider.d.ts +239 -0
  65. package/providers/translation.provider.d.ts +9 -0
  66. package/providers/webrtc.provider.d.ts +11 -0
  67. package/public-api.d.ts +21 -3
  68. package/esm2020/lib/ngx-scandoc.component.mjs +0 -22
  69. package/esm2020/lib/ngx-scandoc.service.mjs +0 -14
  70. package/lib/ngx-scandoc.component.d.ts +0 -8
  71. package/lib/ngx-scandoc.service.d.ts +0 -6
@@ -1,53 +1,4175 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Component, NgModule } from '@angular/core';
2
+ import { EventEmitter, Component, Input, Output, ViewChild, HostListener, NgModule, Pipe, Injectable, Inject, ViewContainerRef, ChangeDetectionStrategy } from '@angular/core';
3
+ import * as i5 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { Observable, from, of, Subject, throwError } from 'rxjs';
6
+ import { tap, switchMap, map, share, catchError } from 'rxjs/operators';
7
+ import * as i1 from '@angular/cdk/layout';
8
+ import { Breakpoints } from '@angular/cdk/layout';
9
+ import * as i2 from '@angular/cdk/platform';
10
+ import { PlatformModule } from '@angular/cdk/platform';
11
+ import * as i1$1 from '@angular/platform-browser';
12
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
13
+ import { MatBadgeModule } from '@angular/material/badge';
14
+ import * as i3 from '@angular/material/button';
15
+ import { MatButtonModule } from '@angular/material/button';
16
+ import * as i12 from '@angular/material/card';
17
+ import { MatCardModule } from '@angular/material/card';
18
+ import { MatCheckboxModule } from '@angular/material/checkbox';
19
+ import { MatChipsModule } from '@angular/material/chips';
20
+ import * as i8 from '@angular/material/core';
21
+ import { MatNativeDateModule } from '@angular/material/core';
22
+ import { MatDatepickerModule } from '@angular/material/datepicker';
23
+ import * as i1$3 from '@angular/material/dialog';
24
+ import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
25
+ import * as i9 from '@angular/material/icon';
26
+ import { MatIconModule } from '@angular/material/icon';
27
+ import { MatInputModule } from '@angular/material/input';
28
+ import { MatListModule } from '@angular/material/list';
29
+ import { MatMenuModule } from '@angular/material/menu';
30
+ import { MatPaginatorModule } from '@angular/material/paginator';
31
+ import * as i1$4 from '@angular/material/progress-bar';
32
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
33
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
34
+ import * as i7 from '@angular/material/select';
35
+ import { MatSelectModule } from '@angular/material/select';
36
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
37
+ import { MatSliderModule } from '@angular/material/slider';
38
+ import { MatSnackBarModule } from '@angular/material/snack-bar';
39
+ import { MatTableModule } from '@angular/material/table';
40
+ import { MatTabsModule } from '@angular/material/tabs';
41
+ import * as i6 from '@angular/forms';
42
+ import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
43
+ import { v4 } from 'uuid';
44
+ import moment from 'moment';
45
+ import * as i1$2 from '@angular/common/http';
46
+ import { HttpHeaders, HTTP_INTERCEPTORS } from '@angular/common/http';
47
+ import jwt_decode from 'jwt-decode';
48
+ import * as i4 from '@angular/flex-layout';
49
+ import { FlexModule, FlexLayoutModule } from '@angular/flex-layout';
50
+ import * as i5$1 from '@angular/flex-layout/extended';
51
+ import * as i4$1 from '@ngx-translate/core';
52
+ import { TranslateModule } from '@ngx-translate/core';
53
+ import { webSocket } from 'rxjs/webSocket';
54
+ import * as i3$1 from 'angularx-qrcode';
55
+ import { QRCodeModule } from 'angularx-qrcode';
56
+ import * as i6$1 from '@angular/material/form-field';
57
+ import * as i8$1 from '@ngx-formly/core';
58
+ import { FormlyModule } from '@ngx-formly/core';
59
+ import { FieldType, FormlyMaterialModule } from '@ngx-formly/material';
60
+ import * as i3$2 from 'ngx-avatars';
61
+ import { AvatarModule } from 'ngx-avatars';
62
+ import { FormlySelectModule } from '@ngx-formly/core/select';
63
+ import { FormlyMatDatepickerModule } from '@ngx-formly/material/datepicker';
3
64
 
4
- class NgxScandocService {
5
- constructor() { }
65
+ /**
66
+ * Container class for a captured webcam image
67
+ * @author basst314, davidshen84
68
+ */
69
+ class WebcamImage {
70
+ constructor(imageAsDataUrl, mimeType, imageData, resized) {
71
+ this._mimeType = mimeType;
72
+ this._imageAsDataUrl = imageAsDataUrl;
73
+ this._imageData = imageData;
74
+ this._imageResized = resized;
75
+ }
76
+ /**
77
+ * Extracts the Base64 data out of the given dataUrl.
78
+ * @param dataUrl the given dataUrl
79
+ * @param mimeType the mimeType of the data
80
+ */
81
+ static getDataFromDataUrl(dataUrl, mimeType) {
82
+ return dataUrl.replace(`data:${mimeType};base64,`, '');
83
+ }
84
+ /**
85
+ * Get the base64 encoded image data
86
+ * @returns base64 data of the image
87
+ */
88
+ get imageAsBase64() {
89
+ return this._imageAsBase64
90
+ ? this._imageAsBase64
91
+ : (this._imageAsBase64 = WebcamImage.getDataFromDataUrl(this._imageAsDataUrl, this._mimeType));
92
+ }
93
+ /**
94
+ * Get the encoded image as dataUrl
95
+ * @returns the dataUrl of the image
96
+ */
97
+ get imageAsDataUrl() {
98
+ return this._imageAsDataUrl;
99
+ }
100
+ /**
101
+ * Get the ImageData object associated with the canvas' 2d context.
102
+ * @returns the ImageData of the canvas's 2d context.
103
+ */
104
+ get imageData() {
105
+ return this._imageData;
106
+ }
107
+ get imageResized() {
108
+ return this._imageResized;
109
+ }
110
+ get dataUrl() {
111
+ const canvas = document.createElement('canvas');
112
+ const { width, height } = this._imageData;
113
+ canvas.width = width;
114
+ canvas.height = height;
115
+ const ctx = canvas.getContext('2d');
116
+ if (ctx) {
117
+ ctx.putImageData(this._imageData, 0, 0);
118
+ }
119
+ return canvas.toDataURL(this._mimeType, 1);
120
+ }
121
+ }
122
+
123
+ class WebcamUtil {
124
+ /**
125
+ * Lists available videoInput devices
126
+ * @returns a list of media device info.
127
+ */
128
+ static getAvailableVideoInputs() {
129
+ return new Observable((observer) => {
130
+ if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
131
+ return observer.error(null);
132
+ }
133
+ const _window = window;
134
+ let streams;
135
+ from(navigator.mediaDevices.getUserMedia({
136
+ video: { deviceId: undefined },
137
+ }))
138
+ .pipe(tap((s) => { streams = s; }), switchMap((s) => from(navigator.mediaDevices.enumerateDevices())))
139
+ .subscribe((devices) => {
140
+ // console.log(streams);
141
+ if (streams) {
142
+ streams.getTracks().forEach((track) => {
143
+ track.stop();
144
+ });
145
+ }
146
+ observer.next(devices.filter((device) => device.kind === 'videoinput'));
147
+ });
148
+ });
149
+ // return new Promise((resolve, reject) => {
150
+ // navigator.mediaDevices.getUserMedia({
151
+ // video: undefined,
152
+ // });
153
+ // navigator.mediaDevices
154
+ // .enumerateDevices()
155
+ // .then((devices: MediaDeviceInfo[]) => {
156
+ // resolve(
157
+ // devices.filter(
158
+ // (device: MediaDeviceInfo) => device.kind === 'videoinput'
159
+ // )
160
+ // );
161
+ // })
162
+ // .catch((err) => {
163
+ // reject(err.message || err);
164
+ // });
165
+ // });
166
+ }
167
+ }
168
+
169
+ const workertext = `
170
+
171
+
172
+ let readStream = true;
173
+ async function blobToBase64(blob) {
174
+ return new Promise((resolve, _) => {
175
+ const reader = new FileReader();
176
+ reader.onloadend = () => resolve(reader.result);
177
+ reader.readAsDataURL(blob);
178
+ });
179
+ }
180
+ async function delay(ms) {
181
+ return new Promise((resolve) =>
182
+ ms > 0 ? setTimeout(resolve, ms) : resolve(0)
183
+ );
184
+ }
185
+
186
+ function calculateDelay(startTime) {
187
+ const endTime = Date.now();
188
+ // difference in ms
189
+ const dt = endTime - startTime;
190
+ const delay = 100 - dt;
191
+ // console.log('[WORKER TIME]', dt, '[DELAY 100-x]', delay);
192
+ return delay > 4 ? delay : 0;
193
+ }
194
+ async function parseFrame(frameStream, trackSettings) {
195
+ const reader = frameStream.getReader();
196
+
197
+ while (readStream) {
198
+ const time = Date.now();
199
+ const result = await reader.read();
200
+ if (result.done) break;
201
+
202
+ const frameFromCamera = result.value;
203
+
204
+ await parseFrameFromCamera(frameFromCamera, trackSettings);
205
+ // wait
206
+ await delay(calculateDelay(time));
207
+ }
208
+ }
209
+
210
+ async function parseFrameFast(frameStream, trackSettings) {
211
+ console.warn('FAST', performance.now());
212
+ const reader = frameStream.getReader();
213
+ const { width, height } = trackSettings;
214
+ const offscreenSmall = new OffscreenCanvas(384, 384);
215
+ const context = offscreenSmall.getContext('2d');
216
+ let time = 0;
217
+ while (true) {
218
+ // const t0 = performance.now();
219
+ // console.time('result');
220
+ const result = reader.read();
221
+ // console.timeEnd('result');
222
+ if (result.done) break;
223
+
224
+ const frameFromCamera = result.value;
225
+ // console.log(frameFromCamera.timestamp);
226
+
227
+ // const tt = frameFromCamera.timestamp - time;
228
+ // console.log(tt / 1000);
229
+ // time = frameFromCamera.timestamp;
230
+
231
+ // console.time('bitmap');
232
+ const bitmap = await createImageBitmap(frameFromCamera, {
233
+ premultiplyAlpha: 'default',
234
+ });
235
+ console.warn(new Date().getTime());
236
+ // console.timeEnd('bitmap');
237
+
238
+ // context.clearRect(0, 0, 384, 384);
239
+ // console.time('draw');
240
+ // context.drawImage(bitmap, 0, 0, width, height, 0, 0, 384, 384);
241
+ // console.timeEnd('draw');
242
+ // console.time('transfer');
243
+ // const bitmapSmall = offscreenSmall.transferToImageBitmap();
244
+ // console.timeEnd('transfer');
245
+
246
+ frameFromCamera.close();
247
+ // //
248
+ // const t1 = performance.now();
249
+
250
+
251
+ // await parseFrameFromCamera(frameFromCamera, trackSettings);
252
+ }
253
+ }
254
+
255
+ async function parseFrameFromCamera(frameFromCamera, trackSettings) {
256
+ const { width, height } = trackSettings;
257
+ const offscreenSmall = new OffscreenCanvas(384, 384);
258
+ // console.time('bit2');
259
+ const bitmap = await createImageBitmap(frameFromCamera, {
260
+ premultiplyAlpha: 'default',
261
+ });
262
+ // console.timeEnd('bit2');
263
+ const context = offscreenSmall.getContext('2d');
264
+
265
+ // console.time('buffer');
266
+ // const buffer = new Uint8Array(frameFromCamera.allocationSize());
267
+ // let layout = await frameFromCamera.copyTo(buffer);
268
+
269
+ // const base64 = await blobToBase64(new Blob([buffer]));
270
+ // console.log(base64)
271
+ // console.timeEnd('buffer');
272
+
273
+ if (context) {
274
+ context.imageSmoothingEnabled = false;
275
+
276
+ // let videoFrame2 = frameFromCamera.clone();
277
+
278
+ // createImageBitmap();
279
+
280
+ // console.time('clear');
281
+ // context.clearRect(0, 0, width, height);
282
+ // console.timeEnd('clear');
283
+ // console.time('draw');
284
+ context.drawImage(bitmap, 0, 0, width, height, 0, 0, 384, 384);
285
+ // console.timeEnd('draw');
286
+ // context.drawImage(bit, 0, 0);
287
+ // bit2.close();
288
+ // bit.close();
289
+ // console.timeEnd('draw');
290
+ // console.time('capture');
291
+
292
+ // const bitmapsmall = offscreenSmall.transferToImageBitmap();
293
+
294
+ // const imageData = context.getImageData(0, 0, 384, 384);
295
+ // console.timeEnd('capture');
296
+ // console.time('blob');
297
+ const resized = await offscreenSmall.convertToBlob({
298
+ type: 'image/jpeg',
299
+ });
300
+ // console.timeEnd('blob');
301
+ // console.log(resized);
302
+ // console.time('base64');
303
+ const base64 = await blobToBase64(resized);
304
+ //console.timeEnd('base64');
305
+ // console.log(blob);
306
+
307
+ // console.time('convert')
308
+ // await convert(bitmap, trackSettings)
309
+ // console.timeEnd('convert');
310
+ // console.log(
311
+ // '%c ',
312
+ // 'font-size:384px; background:url('+blob+') no-repeat;'
313
+ // );
314
+
315
+ // console.timeEnd('blob');
316
+ postMessage({ base64, bitmap }, [bitmap]);
317
+ // videoFrame2.close();
318
+ }
319
+ frameFromCamera.close();
320
+ }
321
+
322
+ async function convert(image, trackSettings) {
323
+ const { width, height } = trackSettings;
324
+
325
+ const offscreenSmall = new OffscreenCanvas(width, height);
326
+
327
+ const context = offscreenSmall.getContext('2d');
328
+
329
+ // console.time('buffer');
330
+ // const buffer = new Uint8Array(frameFromCamera.allocationSize());
331
+ // let layout = await frameFromCamera.copyTo(buffer);
332
+ // console.timeEnd('buffer');
333
+
334
+ if (context) {
335
+ context.imageSmoothingEnabled = false;
336
+ // let videoFrame2 = frameFromCamera.clone();
337
+ console.warn(image);
338
+ // createImageBitmap();
339
+
340
+ // console.time('clear');
341
+ // context.clearRect(0, 0, width, height);
342
+ // console.timeEnd('clear');
343
+
344
+ context.drawImage(image, 0, 0);
345
+ // context.drawImage(bit, 0, 0);
346
+ // image.close();
347
+ // console.timeEnd('drawB');
348
+ console.time('blob2');
349
+ const resized = await offscreenSmall.convertToBlob({
350
+ type: 'image/jpeg',
351
+ });
352
+ console.timeEnd('blob2');
353
+
354
+ // image.close();
355
+ // console.time('base64');
356
+ const base64 = await blobToBase64(resized);
357
+
358
+ // console.log(blob);
359
+
360
+ // console.log(
361
+ // '%c ',
362
+ // 'font-size:384px; background:url(' + base64 + ') no-repeat;'
363
+ // );
364
+
365
+ // console.timeEnd('base64');
366
+ //postMessage({ type: 'convert', base64 });
367
+ }
368
+ }
369
+ addEventListener('message', ({ data }) => {
370
+ const { type, image, frameStream, trackSettings } = data;
371
+ // console.log(data);
372
+ switch (type) {
373
+ case 'start':
374
+ readStream = true;
375
+ parseFrame(frameStream, trackSettings);
376
+ break;
377
+
378
+ case 'fast':
379
+ readStream = true;
380
+ parseFrameFast(frameStream, trackSettings);
381
+ break;
382
+
383
+ case 'stop':
384
+ console.warn('STOP WORKER');
385
+ readStream = false;
386
+ break;
387
+
388
+ case 'convert':
389
+ convert(image, trackSettings);
390
+ break;
391
+ }
392
+
393
+ // const canvas = document.createElement('canvas');
394
+ // const ctx = canvas.getContext('2d');
395
+
396
+ // if (data.canvas) {
397
+ // postMessage('ok');
398
+ // } else {
399
+
400
+ // postMessage(response);
401
+ // }
402
+ });
403
+ `;
404
+
405
+ class WebcamComponent {
406
+ constructor(breakpointObserver, platform, cd, zone) {
407
+ this.breakpointObserver = breakpointObserver;
408
+ this.platform = platform;
409
+ this.cd = cd;
410
+ this.zone = zone;
411
+ /** Defines the max width of the webcam area in px */
412
+ this.width = 640;
413
+ /** Defines the max height of the webcam area in px */
414
+ this.height = 480;
415
+ /** Defines base constraints to apply when requesting video track from UserMedia */
416
+ this.videoOptions = WebcamComponent.DEFAULT_VIDEO_OPTIONS;
417
+ /** Flag to enable/disable camera switch. If enabled, a switch icon will be displayed if multiple cameras were found */
418
+ this.allowCameraSwitch = true;
419
+ /** Flag to control whether an ImageData object is stored into the WebcamImage object. */
420
+ this.captureImageData = false;
421
+ /** The image type to use when capturing snapshots */
422
+ this.imageType = WebcamComponent.DEFAULT_IMAGE_TYPE;
423
+ /** The image quality to use when capturing snapshots (number between 0 and 1) */
424
+ this.imageQuality = WebcamComponent.DEFAULT_IMAGE_QUALITY;
425
+ /** EventEmitter which fires when an image has been captured */
426
+ this.imageCapture = new EventEmitter();
427
+ /** Emits a mediaError if webcam cannot be initialized (e.g. missing user permissions) */
428
+ this.initError = new EventEmitter();
429
+ /** Emits when the webcam video was clicked */
430
+ this.imageClick = new EventEmitter();
431
+ /** Emits the active deviceId after the active video device was switched */
432
+ this.cameraSwitched = new EventEmitter();
433
+ this.videoReady = new EventEmitter();
434
+ this.showVideo = false;
435
+ this.destroyed = new EventEmitter();
436
+ /** available video devices */
437
+ this.availableVideoInputs = [];
438
+ /** Indicates whether the video device is ready to be switched */
439
+ this.videoInitialized = false;
440
+ this.canvasEl = document.createElement('canvas');
441
+ /** Index of active video in availableVideoInputs */
442
+ this.activeVideoInputIndex = -1;
443
+ /** MediaStream object in use for streaming UserMedia data */
444
+ this.mediaStream = null;
445
+ this.shutdown = false;
446
+ this.canStart = true;
447
+ this.videoSize = { width: 1920, height: 1080 };
448
+ this.canvasSize = { width: 1280, height: 720 };
449
+ this.landscape = true;
450
+ // if (typeof Worker !== 'undefined') {
451
+ // // Create a new
452
+ // this.worker = new Worker(
453
+ // new URL('./../../../../app/app.worker', import.meta.url)
454
+ // );
455
+ // this.worker.onmessage = ({ data }) => {
456
+ // console.log(`page got message: ${data}`);
457
+ // };
458
+ // console.log('POST');
459
+ // this.worker.postMessage('hello');
460
+ // } else {
461
+ // // Web workers are not supported in this environment.
462
+ // // You should add a fallback so that your program still executes correctly.
463
+ // }
464
+ }
465
+ /**
466
+ * If the given Observable emits, an image will be captured and emitted through 'imageCapture' EventEmitter
467
+ */
468
+ set trigger(trigger) {
469
+ if (this.triggerSubscription) {
470
+ this.triggerSubscription.unsubscribe();
471
+ }
472
+ // Subscribe to events from this Observable to take snapshots
473
+ this.triggerSubscription = trigger.subscribe((time) => {
474
+ this.takeSnapshot(time);
475
+ });
476
+ }
477
+ onResize() {
478
+ this.videoReady.next(false);
479
+ this.resizeStage();
480
+ }
481
+ /**
482
+ * Get MediaTrackConstraints to request streaming the given device
483
+ * @param deviceId
484
+ * @param baseMediaTrackConstraints base constraints to merge deviceId-constraint into
485
+ * @returns
486
+ */
487
+ static getMediaConstraintsForDevice(deviceId, baseMediaTrackConstraints) {
488
+ const result = baseMediaTrackConstraints
489
+ ? baseMediaTrackConstraints
490
+ : this.DEFAULT_VIDEO_OPTIONS;
491
+ if (deviceId) {
492
+ result.deviceId = { exact: deviceId };
493
+ }
494
+ return result;
495
+ }
496
+ /**
497
+ * Tries to harvest the deviceId from the given mediaStreamTrack object.
498
+ * Browsers populate this object differently; this method tries some different approaches
499
+ * to read the id.
500
+ * @param mediaStreamTrack
501
+ * @returns deviceId if found in the mediaStreamTrack
502
+ */
503
+ static getDeviceIdFromMediaStreamTrack(mediaStreamTrack) {
504
+ if (mediaStreamTrack.getSettings &&
505
+ mediaStreamTrack.getSettings() &&
506
+ mediaStreamTrack.getSettings().deviceId) {
507
+ return mediaStreamTrack.getSettings().deviceId;
508
+ }
509
+ else if (mediaStreamTrack.getConstraints &&
510
+ mediaStreamTrack.getConstraints() &&
511
+ mediaStreamTrack.getConstraints().deviceId) {
512
+ const deviceIdObj = mediaStreamTrack.getConstraints().deviceId;
513
+ return WebcamComponent.getValueFromConstrainDOMString(deviceIdObj);
514
+ }
515
+ }
516
+ /**
517
+ * Tries to harvest the facingMode from the given mediaStreamTrack object.
518
+ * Browsers populate this object differently; this method tries some different approaches
519
+ * to read the value.
520
+ * @param mediaStreamTrack
521
+ * @returns facingMode if found in the mediaStreamTrack
522
+ */
523
+ static getFacingModeFromMediaStreamTrack(mediaStreamTrack) {
524
+ if (mediaStreamTrack) {
525
+ if (mediaStreamTrack.getSettings &&
526
+ mediaStreamTrack.getSettings() &&
527
+ mediaStreamTrack.getSettings().facingMode) {
528
+ return mediaStreamTrack.getSettings().facingMode;
529
+ }
530
+ else if (mediaStreamTrack.getConstraints &&
531
+ mediaStreamTrack.getConstraints() &&
532
+ mediaStreamTrack.getConstraints().facingMode) {
533
+ const facingModeConstraint = mediaStreamTrack.getConstraints().facingMode;
534
+ return WebcamComponent.getValueFromConstrainDOMString(facingModeConstraint);
535
+ }
536
+ }
537
+ }
538
+ /**
539
+ * Determines whether the given mediaStreamTrack claims itself as user facing
540
+ * @param mediaStreamTrack
541
+ */
542
+ static isUserFacing(mediaStreamTrack) {
543
+ const facingMode = WebcamComponent.getFacingModeFromMediaStreamTrack(mediaStreamTrack);
544
+ return facingMode ? 'user' === facingMode.toLowerCase() : false;
545
+ }
546
+ /**
547
+ * Extracts the value from the given ConstrainDOMString
548
+ * @param constrainDOMString
549
+ */
550
+ static getValueFromConstrainDOMString(constrainDOMString) {
551
+ if (constrainDOMString) {
552
+ if (constrainDOMString instanceof String) {
553
+ return String(constrainDOMString);
554
+ }
555
+ else if (Array.isArray(constrainDOMString) &&
556
+ Array(constrainDOMString).length > 0) {
557
+ return String(constrainDOMString[0]);
558
+ }
559
+ else if (typeof constrainDOMString === 'object') {
560
+ if (constrainDOMString['exact']) {
561
+ return String(constrainDOMString['exact']);
562
+ }
563
+ else if (constrainDOMString['ideal']) {
564
+ return String(constrainDOMString['ideal']);
565
+ }
566
+ }
567
+ }
568
+ return null;
569
+ }
570
+ resizeStage() {
571
+ setTimeout(() => {
572
+ this.updateSize();
573
+ this.updatecanvasSize();
574
+ this.drawRectangle();
575
+ this.cd.detectChanges();
576
+ this.videoReady.next(true);
577
+ }, 10);
578
+ }
579
+ get canvasHeight() {
580
+ const landscape = this.width > this.height;
581
+ const aspect = this.videoSize.width / this.videoSize.height;
582
+ if (!landscape) {
583
+ return this.width * aspect;
584
+ }
585
+ return this.height;
586
+ }
587
+ updatecanvasSize() {
588
+ console.log(this.width, this.height);
589
+ const landscape = this.width > this.height;
590
+ const aspect = this.videoSize.width / this.videoSize.height;
591
+ let width = this.width;
592
+ let height = this.height;
593
+ if (landscape) {
594
+ height = width / aspect;
595
+ }
596
+ else {
597
+ height = width / aspect;
598
+ }
599
+ if (height > this.height) {
600
+ height = this.height;
601
+ width = this.height * aspect;
602
+ }
603
+ this.canvasSize = { width: Math.round(width), height: Math.round(height) };
604
+ console.log(this.canvasSize, this.videoSize);
605
+ if (this.isMobile) {
606
+ this.video.nativeElement.setAttribute('height', this.canvasSize.height);
607
+ this.video.nativeElement.setAttribute('width', this.canvasSize.width);
608
+ }
609
+ else {
610
+ if (this.videoSize.width > this.videoSize.hight) {
611
+ this.video.nativeElement.setAttribute('height', this.canvasSize.height);
612
+ }
613
+ else {
614
+ this.video.nativeElement.setAttribute('width', this.canvasSize.width);
615
+ }
616
+ }
617
+ this.cd.detectChanges();
618
+ }
619
+ setupWorker() {
620
+ if (typeof Worker !== 'undefined') {
621
+ // Create a new
622
+ if (this.type !== 'selfie') {
623
+ this.zone.runOutsideAngular(() => {
624
+ var blob = new Blob([workertext], { type: 'text/javascript' });
625
+ var url = URL.createObjectURL(blob);
626
+ this.worker = new Worker(url);
627
+ this.worker.onmessage = ({ data }) => {
628
+ if (data.base64) {
629
+ data.type == 'data';
630
+ this.imageHandler.next(data);
631
+ }
632
+ };
633
+ });
634
+ }
635
+ }
636
+ }
637
+ ngAfterViewInit() {
638
+ this.setupWorker();
639
+ if (this.imageHandler) {
640
+ this.imageHandler.subscribe((resp) => {
641
+ if (resp.type === 'stop') {
642
+ this.worker?.postMessage({ type: 'stop' });
643
+ }
644
+ });
645
+ }
646
+ this.breakpointObserver
647
+ .observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
648
+ .subscribe((state) => {
649
+ if (this.platform.IOS || this.platform.ANDROID) {
650
+ // this.landscape = state.breakpoints[Breakpoints.HandsetLandscape];
651
+ }
652
+ const mobile = this.platform.IOS;
653
+ if (state.matches && mobile) {
654
+ this.updateSize();
655
+ this.updatecanvasSize();
656
+ this.drawRectangle();
657
+ }
658
+ });
659
+ if (this.switchCamera) {
660
+ if (this.switchCameraSubscription) {
661
+ this.switchCameraSubscription.unsubscribe();
662
+ }
663
+ // Subscribe to events from this Observable to switch video device
664
+ this.switchCameraSubscription = this.switchCamera.subscribe((value) => {
665
+ this.switchToVideoInput(value);
666
+ });
667
+ }
668
+ this.detectAvailableDevices()
669
+ .then(() => {
670
+ // start video
671
+ if (this.canStart) {
672
+ this.switchToVideoInput('');
673
+ }
674
+ })
675
+ .catch((err) => {
676
+ this.initError.next({ message: err });
677
+ // fallback: still try to load webcam, even if device enumeration failed
678
+ if (this.canStart) {
679
+ this.switchToVideoInput('');
680
+ }
681
+ });
682
+ }
683
+ ngOnDestroy() {
684
+ this.canStart = false;
685
+ this.nativeVideoElement.pause();
686
+ this.destroyed.emit(true);
687
+ this.stopMediaTracks();
688
+ this.unsubscribeFromSubscriptions();
689
+ this.shutdown = true;
690
+ // shut down worker
691
+ if (this.imageHandler) {
692
+ this.imageHandler.next({ type: 'stop' });
693
+ }
694
+ if (this.nativeVideoElement.srcObject) {
695
+ this.nativeVideoElement.srcObject
696
+ .getTracks()
697
+ .forEach((track) => {
698
+ track.stop();
699
+ });
700
+ this.nativeVideoElement.srcObject = null;
701
+ }
702
+ // this.nativeVideoElement.src = null;
703
+ // this.nativeVideoElement.srcObject = null;
704
+ }
705
+ takeSelfie() {
706
+ const _video = this.nativeVideoElement;
707
+ const mimeType = this.imageType
708
+ ? this.imageType
709
+ : WebcamComponent.DEFAULT_IMAGE_TYPE;
710
+ let _canvas = document.createElement('canvas'); //this.canvasSnapshot.nativeElement;
711
+ const { width, height } = this.videoSize;
712
+ console.log(width, height);
713
+ const { padding, top, rWidth, rHeight } = this.snapRectangle;
714
+ _canvas.width = rWidth;
715
+ _canvas.height = rHeight;
716
+ const ctx = _canvas.getContext('2d', {
717
+ alpha: false,
718
+ powerPreference: 'high-performance',
719
+ antialias: false,
720
+ depth: false,
721
+ desynchronized: true,
722
+ });
723
+ if (ctx) {
724
+ ctx.drawImage(_video, padding, top, rWidth, rHeight, 0, 0, rWidth, rHeight);
725
+ const imgAsUrl = _canvas.toDataURL(mimeType, 1);
726
+ this.imageCapture.emit(new WebcamImage(imgAsUrl, mimeType, new ImageData(1, 1), null));
727
+ }
728
+ }
729
+ /**
730
+ * Takes a snapshot of the current webcam's view and emits the image as an event
731
+ */
732
+ takeSnapshot(time) {
733
+ if (this.type === 'selfie') {
734
+ this.takeSelfie();
735
+ return;
736
+ }
737
+ if (this.trackProcessor) {
738
+ return;
739
+ }
740
+ this.zone.runOutsideAngular(() => {
741
+ const canvasSmalSize = 384;
742
+ const _video = this.nativeVideoElement;
743
+ const mimeType = this.imageType
744
+ ? this.imageType
745
+ : WebcamComponent.DEFAULT_IMAGE_TYPE;
746
+ let _canvas = document.createElement('canvas'); //this.canvasSnapshot.nativeElement;
747
+ const { width, height } = this.videoSize;
748
+ _canvas.width = width;
749
+ _canvas.height = height;
750
+ const ctx = _canvas.getContext('2d', {
751
+ alpha: false,
752
+ powerPreference: 'high-performance',
753
+ antialias: false,
754
+ depth: false,
755
+ desynchronized: true,
756
+ });
757
+ const canvas = document.createElement('canvas'); // needs an initial size
758
+ canvas.height = canvasSmalSize;
759
+ canvas.width = canvasSmalSize;
760
+ const ctxO = canvas.getContext('2d', {
761
+ alpha: false,
762
+ powerPreference: 'high-performance',
763
+ antialias: false,
764
+ depth: false,
765
+ desynchronized: true,
766
+ });
767
+ if (ctx && ctxO) {
768
+ ctx.imageSmoothingEnabled = false;
769
+ ctx.drawImage(_video, 0, 0);
770
+ ctxO.drawImage(_video, 0, 0, canvasSmalSize, canvasSmalSize);
771
+ const imData = ctx.getImageData(0, 0, this.videoSize.width, this.videoSize.height);
772
+ const resize = canvas.toDataURL(mimeType, 1);
773
+ const currentTime = new Date().getTime();
774
+ const diff = currentTime - time;
775
+ const delay = diff > 100 ? 0 : 100 - diff;
776
+ const timeout = setTimeout(() => {
777
+ this.imageCapture.emit(new WebcamImage('', mimeType, imData, resize));
778
+ clearTimeout(timeout);
779
+ }, delay);
780
+ }
781
+ });
782
+ }
783
+ update() { }
784
+ resizeImage(base64data) {
785
+ return new Observable((observer) => {
786
+ let canvas = document.createElement('canvas');
787
+ const ctx = canvas.getContext('2d');
788
+ const max_size = 384;
789
+ let image = new Image();
790
+ image.src = base64data;
791
+ image.onload = () => {
792
+ let width = image.width;
793
+ let height = image.height;
794
+ if (width < height) {
795
+ height *= max_size / width;
796
+ width = max_size;
797
+ }
798
+ else {
799
+ width *= max_size / height;
800
+ height = max_size;
801
+ }
802
+ canvas.width = width;
803
+ canvas.height = height;
804
+ // console.log(width, height);
805
+ if (ctx) {
806
+ // ctx.rotate((90 * Math.PI) / 180);
807
+ // ctx.translate(0, -canvas.width);
808
+ ctx.drawImage(image, 0, 0, 384, 384);
809
+ observer.next(canvas.toDataURL());
810
+ ctx.clearRect(0, 0, 1, 1);
811
+ }
812
+ else {
813
+ observer.error({ type: 'generic error' });
814
+ }
815
+ image = null;
816
+ canvas = null;
817
+ };
818
+ image.onerror = (e) => {
819
+ observer.error(e);
820
+ };
821
+ });
822
+ }
823
+ /**
824
+ * Switches to the next/previous video device
825
+ * @param forward
826
+ */
827
+ rotateVideoInput(forward) {
828
+ if (this.availableVideoInputs && this.availableVideoInputs.length > 1) {
829
+ const increment = forward
830
+ ? 1
831
+ : this.availableVideoInputs.length - 1;
832
+ const nextInputIndex = (this.activeVideoInputIndex + increment) %
833
+ this.availableVideoInputs.length;
834
+ this.switchToVideoInput(this.availableVideoInputs[nextInputIndex].deviceId);
835
+ }
836
+ }
837
+ /**
838
+ * Switches the camera-view to the specified video device
839
+ */
840
+ switchToVideoInput(deviceId) {
841
+ // if(deviceId){
842
+ this.videoInitialized = false;
843
+ this.stopMediaTracks();
844
+ this.initWebcam(deviceId, this.videoOptions);
845
+ // }
846
+ }
847
+ /**
848
+ * Event-handler for video resize event.
849
+ * Triggers Angular change detection so that new video dimensions get applied
850
+ */
851
+ videoResize() {
852
+ // here to trigger Angular change detection
853
+ }
854
+ get videoWidth() {
855
+ const videoRatio = this.getVideoAspectRatio();
856
+ return Math.min(this.width, this.height * videoRatio);
857
+ }
858
+ get videoHeight() {
859
+ const videoRatio = this.getVideoAspectRatio();
860
+ return Math.min(this.height, this.width / videoRatio);
861
+ }
862
+ get videoStyleClasses() {
863
+ let classes = '';
864
+ if (this.isMirrorImage()) {
865
+ classes += 'mirrored ';
866
+ }
867
+ return classes.trim();
868
+ }
869
+ get nativeVideoElement() {
870
+ return this.video.nativeElement;
871
+ }
872
+ // public get smallVideoElement() {
873
+ // return this.videoSmall;
874
+ // }
875
+ /**
876
+ * Returns the video aspect ratio of the active video stream
877
+ */
878
+ getVideoAspectRatio() {
879
+ // calculate ratio from video element dimensions if present
880
+ const videoElement = this.nativeVideoElement;
881
+ if (videoElement.videoWidth &&
882
+ videoElement.videoWidth > 0 &&
883
+ videoElement.videoHeight &&
884
+ videoElement.videoHeight > 0) {
885
+ return videoElement.videoWidth / videoElement.videoHeight;
886
+ }
887
+ // nothing present - calculate ratio based on width/height params
888
+ return this.width / this.height;
889
+ }
890
+ updateSize() {
891
+ const track = this.mediaStream?.getTracks()[0];
892
+ if (track) {
893
+ let desired = {
894
+ width: {
895
+ ideal: 0,
896
+ },
897
+ height: {
898
+ ideal: 0,
899
+ },
900
+ // facingMode:'user',
901
+ frameRate: { min: 20, ideal: 24, max: 24 },
902
+ };
903
+ if (typeof track.getCapabilities === 'function') {
904
+ const { width, height } = track.getCapabilities();
905
+ desired = {
906
+ width: {
907
+ ideal: this.landscape && this.isMobile ? height?.max : width?.max,
908
+ },
909
+ height: {
910
+ ideal: this.landscape && this.isMobile ? width?.max : height?.max,
911
+ },
912
+ // facingMode:'user',
913
+ frameRate: { min: 20, ideal: 24, max: 24 },
914
+ };
915
+ }
916
+ else {
917
+ desired = {
918
+ width: {
919
+ ideal: 1920,
920
+ },
921
+ height: {
922
+ ideal: 1080,
923
+ },
924
+ // facingMode:'user',
925
+ frameRate: { min: 20, ideal: 30, max: 31 },
926
+ };
927
+ }
928
+ if (desired.height.ideal && desired.height.ideal >= 1600) {
929
+ desired.height.ideal = 1600;
930
+ desired.width.ideal = 1600;
931
+ }
932
+ if (this.platform.ANDROID) {
933
+ //desired.width.ideal = 2160;
934
+ //desired.height.ideal = 2160;
935
+ // if (!this.landscape) {
936
+ // } else {
937
+ // desired.width.ideal = width?.max;
938
+ // desired.height.ideal = height?.max;
939
+ // }
940
+ }
941
+ track.applyConstraints(desired);
942
+ //track.getSettings().facingMode!=='user';
943
+ this.videoSize = {
944
+ height: this.landscape
945
+ ? track.getSettings().height
946
+ : track.getSettings().width,
947
+ width: this.landscape
948
+ ? track.getSettings().width
949
+ : track.getSettings().height,
950
+ };
951
+ this.cd.detectChanges();
952
+ }
953
+ }
954
+ getStreamTrack(stream) {
955
+ return stream.getVideoTracks()[0];
956
+ }
957
+ getTrackSettings() { }
958
+ accesVideoTrack(videoTrackConstraints) {
959
+ return from(navigator.mediaDevices.getUserMedia(videoTrackConstraints)).pipe(switchMap((stream) => {
960
+ // default resolution 1280x720, check max resolution
961
+ const track = this.getStreamTrack(stream);
962
+ const capabilities = track.getCapabilities();
963
+ const { facingMode, height, width } = capabilities;
964
+ const desired = {
965
+ width: {
966
+ min: this.landscape && this.isMobile ? height?.max : width?.max,
967
+ },
968
+ // height: {
969
+ // exact: this.landscape && this.isMobile ? width?.max : height?.max,
970
+ // },
971
+ // facingMode:'en',
972
+ // frameRate: { min: 25, ideal: 30, max: 31 },
973
+ };
974
+ // get max width
975
+ const { width: sWidth, height: sHeight } = track.getSettings();
976
+ if (desired.width.min != sWidth) {
977
+ return this.accesVideoTrack({ video: desired });
978
+ }
979
+ //return this.accesVideoTrack({video:desired});
980
+ return of(stream);
981
+ }));
982
+ }
983
+ drawRectangle() {
984
+ const _canvas = this.canvas.nativeElement;
985
+ const ctx = _canvas.getContext('2d');
986
+ ctx.clearRect(0, 0, _canvas.width, _canvas.height);
987
+ // ctx.drawImage(_video, 0, 0, _canvas.width, _canvas.height);
988
+ const { padding, top, rWidth, rHeight } = this.cardRectangle;
989
+ ctx.strokeStyle = 'red';
990
+ ctx.strokeRect(padding, top, rWidth, rHeight);
991
+ }
992
+ getMaxAvailableResolution() { }
993
+ /**
994
+ * Init webcam live view
995
+ */
996
+ initWebcam(deviceId, userVideoTrackConstraints) {
997
+ const _video = this.nativeVideoElement;
998
+ // const videoStreamer = this.videoStreamer.nativeElement;
999
+ // const videoSmall = document.createElement('video');
1000
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
1001
+ // merge deviceId -> userVideoTrackConstraints
1002
+ const videoTrackConstraints = WebcamComponent.getMediaConstraintsForDevice(deviceId, userVideoTrackConstraints);
1003
+ // // if (deviceId) {
1004
+ // this.accesVideoTrack({ video: videoTrackConstraints }).subscribe(
1005
+ // (stream: MediaStream) => {
1006
+ // console.log(
1007
+ // 'VALID SETTINGS',
1008
+ // stream.getVideoTracks()[0].getSettings()
1009
+ // );
1010
+ // }
1011
+ // );
1012
+ // }
1013
+ if (this.platform.ANDROID) {
1014
+ videoTrackConstraints.width = 1600;
1015
+ videoTrackConstraints.height = 1600;
1016
+ }
1017
+ const constraints = {
1018
+ exact: deviceId,
1019
+ width: { min: 480, ideal: 1280 },
1020
+ height: { min: 480, ideal: 720 },
1021
+ // aspectRatio: 3 / 2,
1022
+ frameRate: { min: 20 },
1023
+ };
1024
+ navigator.mediaDevices
1025
+ .getUserMedia({ video: videoTrackConstraints })
1026
+ .then((stream) => {
1027
+ this.mediaStream = stream;
1028
+ _video.srcObject = stream;
1029
+ this.updateSize();
1030
+ this.updatecanvasSize();
1031
+ _video.play();
1032
+ _video.onplay = () => {
1033
+ this.setActiveCamera(stream);
1034
+ this.drawRectangle();
1035
+ };
1036
+ })
1037
+ .catch((err) => {
1038
+ console.log(err);
1039
+ this.initError.next({
1040
+ message: err.message,
1041
+ mediaStreamError: err,
1042
+ });
1043
+ });
1044
+ }
1045
+ else {
1046
+ this.initError.next({
1047
+ message: 'Cannot read UserMedia from MediaDevices.',
1048
+ });
1049
+ }
1050
+ }
1051
+ get isMobile() {
1052
+ return this.platform.ANDROID || this.platform.IOS;
1053
+ }
1054
+ get cardRectangle() {
1055
+ const _canvas = this.canvas.nativeElement;
1056
+ const docSize = this.type === 'selfie' ? 1 : 86 / 55;
1057
+ let padding = 10;
1058
+ let rWidth = _canvas.width - 2 * padding;
1059
+ let rHeight = rWidth / docSize;
1060
+ let top = (_canvas.height - rHeight) / 2;
1061
+ if (!this.isMobile) {
1062
+ padding = 40;
1063
+ rHeight = _canvas.height - 2 * padding;
1064
+ rWidth = rHeight * docSize;
1065
+ top = (_canvas.height - rHeight) / 2;
1066
+ padding = (_canvas.width - rWidth) / 2;
1067
+ }
1068
+ return { padding, top, rWidth, rHeight };
1069
+ }
1070
+ get snapRectangle() {
1071
+ const _canvas = this.canvas.nativeElement;
1072
+ const ar = this.videoSize.width / _canvas.width;
1073
+ let { padding, top, rWidth, rHeight } = this.cardRectangle;
1074
+ padding = padding * ar;
1075
+ top = top * ar;
1076
+ rWidth = rWidth * ar;
1077
+ rHeight = rHeight * ar;
1078
+ return { padding, top, rWidth, rHeight };
1079
+ }
1080
+ setActiveCamera(stream) {
1081
+ this.videoReady.next(false);
1082
+ this.showVideo = false;
1083
+ this.activeVideoSettings = stream.getVideoTracks()[0].getSettings();
1084
+ const activeDeviceId = WebcamComponent.getDeviceIdFromMediaStreamTrack(stream.getVideoTracks()[0]);
1085
+ const videoTrack = stream.getTracks()[0];
1086
+ this.trackSettings = videoTrack.getSettings();
1087
+ this.cameraSwitched.next(activeDeviceId);
1088
+ setTimeout(() => {
1089
+ this.zone.run(() => {
1090
+ this.resizeStage();
1091
+ this.showVideo = true;
1092
+ this.videoReady.next(true);
1093
+ if (MediaStreamTrackProcessor) {
1094
+ this.trackProcessor = new MediaStreamTrackProcessor(videoTrack);
1095
+ let frameStream = this.trackProcessor.readable;
1096
+ if (!this.shutdown) {
1097
+ this.worker?.postMessage({
1098
+ type: 'start',
1099
+ frameStream: frameStream,
1100
+ trackSettings: this.trackSettings,
1101
+ }, [frameStream]);
1102
+ }
1103
+ }
1104
+ });
1105
+ }, 500);
1106
+ }
1107
+ getActiveVideoTrack() {
1108
+ return this.mediaStream ? this.mediaStream.getVideoTracks()[0] : null;
1109
+ }
1110
+ isMirrorImage() {
1111
+ if (!this.getActiveVideoTrack()) {
1112
+ return false;
1113
+ }
1114
+ // check for explicit mirror override parameter
1115
+ {
1116
+ let mirror = 'auto';
1117
+ if (this.mirrorImage) {
1118
+ if (typeof this.mirrorImage === 'string') {
1119
+ mirror = String(this.mirrorImage).toLowerCase();
1120
+ }
1121
+ else {
1122
+ // WebcamMirrorProperties
1123
+ if (this.mirrorImage.x) {
1124
+ mirror = this.mirrorImage.x.toLowerCase();
1125
+ }
1126
+ }
1127
+ }
1128
+ switch (mirror) {
1129
+ case 'always':
1130
+ return true;
1131
+ case 'never':
1132
+ return false;
1133
+ }
1134
+ }
1135
+ // default: enable mirroring if webcam is user facing
1136
+ return WebcamComponent.isUserFacing(this.getActiveVideoTrack());
1137
+ }
1138
+ /**
1139
+ * Stops all active media tracks.
1140
+ * This prevents the webcam from being indicated as active,
1141
+ * even if it is no longer used by this component.
1142
+ */
1143
+ stopMediaTracks() {
1144
+ // this.video.nativeElement.pause();
1145
+ if (this.video.nativeElement.srcObject) {
1146
+ this.video.nativeElement.srcObject
1147
+ .getTracks()
1148
+ .forEach((track) => {
1149
+ track.stop();
1150
+ });
1151
+ this.video.nativeElement.srcObject = null;
1152
+ this.video.nativeElement.src = '';
1153
+ }
1154
+ if (this.mediaStream && this.mediaStream.getTracks) {
1155
+ // getTracks() returns all media tracks (video+audio)
1156
+ this.mediaStream
1157
+ .getTracks()
1158
+ .forEach((track) => track.stop());
1159
+ }
1160
+ }
1161
+ /**
1162
+ * Unsubscribe from all open subscriptions
1163
+ */
1164
+ unsubscribeFromSubscriptions() {
1165
+ if (this.triggerSubscription) {
1166
+ this.triggerSubscription.unsubscribe();
1167
+ }
1168
+ if (this.switchCameraSubscription) {
1169
+ this.switchCameraSubscription.unsubscribe();
1170
+ }
1171
+ }
1172
+ /**
1173
+ * Reads available input devices
1174
+ */
1175
+ detectAvailableDevices() {
1176
+ return new Promise((resolve, reject) => {
1177
+ WebcamUtil.getAvailableVideoInputs().subscribe((devices) => {
1178
+ this.availableVideoInputs = devices;
1179
+ resolve(devices);
1180
+ }, (err) => {
1181
+ this.availableVideoInputs = [];
1182
+ reject(err);
1183
+ });
1184
+ });
1185
+ }
1186
+ }
1187
+ WebcamComponent.DEFAULT_VIDEO_OPTIONS = {
1188
+ facingMode: 'environment',
1189
+ };
1190
+ WebcamComponent.DEFAULT_IMAGE_TYPE = 'image/jpeg';
1191
+ WebcamComponent.DEFAULT_IMAGE_QUALITY = 1;
1192
+ WebcamComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WebcamComponent, deps: [{ token: i1.BreakpointObserver }, { token: i2.Platform }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
1193
+ WebcamComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: WebcamComponent, selector: "app-webcam", inputs: { imageHandler: "imageHandler", id: "id", type: "type", width: "width", height: "height", videoOptions: "videoOptions", allowCameraSwitch: "allowCameraSwitch", mirrorImage: "mirrorImage", captureImageData: "captureImageData", imageType: "imageType", imageQuality: "imageQuality", trigger: "trigger", switchCamera: "switchCamera" }, outputs: { imageCapture: "imageCapture", initError: "initError", imageClick: "imageClick", cameraSwitched: "cameraSwitched", videoReady: "videoReady", destroyed: "destroyed" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "video", first: true, predicate: ["video"], descendants: true, static: true }, { propertyName: "videoStreamer", first: true, predicate: ["videoStreamer"], descendants: true, static: true }, { propertyName: "canvas", first: true, predicate: ["canvas"], descendants: true, static: true }, { propertyName: "canvasSnapshot", first: true, predicate: ["canvasSnapshot"], descendants: true, static: true }, { propertyName: "canvasResize", first: true, predicate: ["canvasResize"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"webcam-wrapper\">\n <div>\n <video\n #video\n autoplay\n muted\n style=\"display: block\"\n playsinline\n\n ></video>\n\n <div class=\"rectangle\">\n <canvas\n #canvas\n [ngStyle]=\"{ visibility: showVideo ? 'visible' : 'hidden' }\"\n [width]=\"canvasSize.width\"\n [height]=\"canvasSize.height\"\n ></canvas>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:row;flex:1;transform:transale3d(0,0,0);background-color:#000}.webcam-wrapper{display:flex;flex-direction:row;align-items:center;flex:1;justify-content:center}.webcam-wrapper canvas{transform:transale3d(0,0,0);display:block;position:relative;z-index:20;left:0;top:0}.webcam-wrapper .rectangle{position:absolute;left:0;top:0;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
1194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WebcamComponent, decorators: [{
1195
+ type: Component,
1196
+ args: [{ selector: 'app-webcam', template: "<div class=\"webcam-wrapper\">\n <div>\n <video\n #video\n autoplay\n muted\n style=\"display: block\"\n playsinline\n\n ></video>\n\n <div class=\"rectangle\">\n <canvas\n #canvas\n [ngStyle]=\"{ visibility: showVideo ? 'visible' : 'hidden' }\"\n [width]=\"canvasSize.width\"\n [height]=\"canvasSize.height\"\n ></canvas>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:row;flex:1;transform:transale3d(0,0,0);background-color:#000}.webcam-wrapper{display:flex;flex-direction:row;align-items:center;flex:1;justify-content:center}.webcam-wrapper canvas{transform:transale3d(0,0,0);display:block;position:relative;z-index:20;left:0;top:0}.webcam-wrapper .rectangle{position:absolute;left:0;top:0;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%;height:100%}\n"] }]
1197
+ }], ctorParameters: function () { return [{ type: i1.BreakpointObserver }, { type: i2.Platform }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }]; }, propDecorators: { imageHandler: [{
1198
+ type: Input
1199
+ }], id: [{
1200
+ type: Input
1201
+ }], type: [{
1202
+ type: Input
1203
+ }], width: [{
1204
+ type: Input
1205
+ }], height: [{
1206
+ type: Input
1207
+ }], videoOptions: [{
1208
+ type: Input
1209
+ }], allowCameraSwitch: [{
1210
+ type: Input
1211
+ }], mirrorImage: [{
1212
+ type: Input
1213
+ }], captureImageData: [{
1214
+ type: Input
1215
+ }], imageType: [{
1216
+ type: Input
1217
+ }], imageQuality: [{
1218
+ type: Input
1219
+ }], imageCapture: [{
1220
+ type: Output
1221
+ }], initError: [{
1222
+ type: Output
1223
+ }], imageClick: [{
1224
+ type: Output
1225
+ }], cameraSwitched: [{
1226
+ type: Output
1227
+ }], videoReady: [{
1228
+ type: Output
1229
+ }], destroyed: [{
1230
+ type: Output
1231
+ }], video: [{
1232
+ type: ViewChild,
1233
+ args: ['video', { static: true }]
1234
+ }], videoStreamer: [{
1235
+ type: ViewChild,
1236
+ args: ['videoStreamer', { static: true }]
1237
+ }], canvas: [{
1238
+ type: ViewChild,
1239
+ args: ['canvas', { static: true }]
1240
+ }], canvasSnapshot: [{
1241
+ type: ViewChild,
1242
+ args: ['canvasSnapshot', { static: true }]
1243
+ }], canvasResize: [{
1244
+ type: ViewChild,
1245
+ args: ['canvasResize', { static: true }]
1246
+ }], trigger: [{
1247
+ type: Input
1248
+ }], switchCamera: [{
1249
+ type: Input
1250
+ }], onResize: [{
1251
+ type: HostListener,
1252
+ args: ['window:resize', ['$event']]
1253
+ }] } });
1254
+
1255
+ const COMPONENTS = [
1256
+ WebcamComponent
1257
+ ];
1258
+ class WebcamModule {
1259
+ }
1260
+ WebcamModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WebcamModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1261
+ WebcamModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: WebcamModule, declarations: [WebcamComponent], imports: [CommonModule, PlatformModule], exports: [WebcamComponent] });
1262
+ WebcamModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WebcamModule, imports: [CommonModule, PlatformModule] });
1263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: WebcamModule, decorators: [{
1264
+ type: NgModule,
1265
+ args: [{
1266
+ imports: [CommonModule, PlatformModule],
1267
+ declarations: [COMPONENTS],
1268
+ exports: [COMPONENTS],
1269
+ }]
1270
+ }] });
1271
+
1272
+ class CoreComponentsModule {
1273
+ }
1274
+ CoreComponentsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CoreComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1275
+ CoreComponentsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: CoreComponentsModule, imports: [CommonModule, WebcamModule], exports: [WebcamModule] });
1276
+ CoreComponentsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CoreComponentsModule, imports: [CommonModule, WebcamModule, WebcamModule] });
1277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CoreComponentsModule, decorators: [{
1278
+ type: NgModule,
1279
+ args: [{
1280
+ imports: [CommonModule, WebcamModule],
1281
+ declarations: [],
1282
+ exports: [WebcamModule],
1283
+ }]
1284
+ }] });
1285
+
1286
+ class SafeResourceUrlPipe {
1287
+ constructor(sanitizer) {
1288
+ this.sanitizer = sanitizer;
1289
+ }
1290
+ transform(style) {
1291
+ return this.sanitizer.bypassSecurityTrustResourceUrl(style);
1292
+ // return this.sanitizer.bypassSecurityTrustStyle(style);
1293
+ // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
1294
+ }
1295
+ }
1296
+ SafeResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SafeResourceUrlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
1297
+ SafeResourceUrlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: SafeResourceUrlPipe, name: "safeResourceUrl" });
1298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SafeResourceUrlPipe, decorators: [{
1299
+ type: Pipe,
1300
+ args: [{ name: 'safeResourceUrl' }]
1301
+ }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
1302
+
1303
+ class CorePipesModule {
1304
+ }
1305
+ CorePipesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CorePipesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1306
+ CorePipesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: CorePipesModule, declarations: [SafeResourceUrlPipe], exports: [SafeResourceUrlPipe] });
1307
+ CorePipesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CorePipesModule });
1308
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CorePipesModule, decorators: [{
1309
+ type: NgModule,
1310
+ args: [{
1311
+ declarations: [SafeResourceUrlPipe],
1312
+ imports: [],
1313
+ exports: [
1314
+ SafeResourceUrlPipe,
1315
+ ],
1316
+ }]
1317
+ }] });
1318
+
1319
+ class MaterialModule {
1320
+ }
1321
+ MaterialModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1322
+ MaterialModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: MaterialModule, imports: [MatNativeDateModule,
1323
+ MatDatepickerModule,
1324
+ MatCardModule,
1325
+ MatMenuModule,
1326
+ MatIconModule,
1327
+ MatButtonModule,
1328
+ MatDialogModule,
1329
+ MatInputModule,
1330
+ MatSnackBarModule,
1331
+ MatProgressBarModule,
1332
+ MatTableModule,
1333
+ MatProgressSpinnerModule,
1334
+ MatPaginatorModule,
1335
+ MatSelectModule,
1336
+ MatCheckboxModule,
1337
+ MatChipsModule,
1338
+ MatBadgeModule,
1339
+ MatListModule,
1340
+ MatTabsModule,
1341
+ MatSliderModule,
1342
+ MatSlideToggleModule], exports: [MatNativeDateModule,
1343
+ MatDatepickerModule,
1344
+ MatSelectModule,
1345
+ MatCardModule,
1346
+ MatMenuModule,
1347
+ MatIconModule,
1348
+ MatButtonModule,
1349
+ MatDialogModule,
1350
+ MatInputModule,
1351
+ MatSnackBarModule,
1352
+ MatProgressBarModule,
1353
+ MatProgressSpinnerModule,
1354
+ MatTableModule,
1355
+ MatPaginatorModule,
1356
+ MatChipsModule,
1357
+ MatBadgeModule,
1358
+ MatCheckboxModule,
1359
+ MatListModule,
1360
+ MatTabsModule,
1361
+ MatSlideToggleModule,
1362
+ MatAutocompleteModule] });
1363
+ MaterialModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaterialModule, imports: [MatNativeDateModule,
1364
+ MatDatepickerModule,
1365
+ MatCardModule,
1366
+ MatMenuModule,
1367
+ MatIconModule,
1368
+ MatButtonModule,
1369
+ MatDialogModule,
1370
+ MatInputModule,
1371
+ MatSnackBarModule,
1372
+ MatProgressBarModule,
1373
+ MatTableModule,
1374
+ MatProgressSpinnerModule,
1375
+ MatPaginatorModule,
1376
+ MatSelectModule,
1377
+ MatCheckboxModule,
1378
+ MatChipsModule,
1379
+ MatBadgeModule,
1380
+ MatListModule,
1381
+ MatTabsModule,
1382
+ MatSliderModule,
1383
+ MatSlideToggleModule, MatNativeDateModule,
1384
+ MatDatepickerModule,
1385
+ MatSelectModule,
1386
+ MatCardModule,
1387
+ MatMenuModule,
1388
+ MatIconModule,
1389
+ MatButtonModule,
1390
+ MatDialogModule,
1391
+ MatInputModule,
1392
+ MatSnackBarModule,
1393
+ MatProgressBarModule,
1394
+ MatProgressSpinnerModule,
1395
+ MatTableModule,
1396
+ MatPaginatorModule,
1397
+ MatChipsModule,
1398
+ MatBadgeModule,
1399
+ MatCheckboxModule,
1400
+ MatListModule,
1401
+ MatTabsModule,
1402
+ MatSlideToggleModule,
1403
+ MatAutocompleteModule] });
1404
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MaterialModule, decorators: [{
1405
+ type: NgModule,
1406
+ args: [{
1407
+ imports: [
1408
+ MatNativeDateModule,
1409
+ MatDatepickerModule,
1410
+ MatCardModule,
1411
+ MatMenuModule,
1412
+ MatIconModule,
1413
+ MatButtonModule,
1414
+ MatDialogModule,
1415
+ MatInputModule,
1416
+ MatSnackBarModule,
1417
+ MatProgressBarModule,
1418
+ MatTableModule,
1419
+ MatProgressSpinnerModule,
1420
+ MatPaginatorModule,
1421
+ MatSelectModule,
1422
+ MatCheckboxModule,
1423
+ MatChipsModule,
1424
+ MatBadgeModule,
1425
+ MatListModule,
1426
+ MatTabsModule,
1427
+ MatSliderModule,
1428
+ MatSlideToggleModule,
1429
+ ],
1430
+ exports: [
1431
+ MatNativeDateModule,
1432
+ MatDatepickerModule,
1433
+ MatSelectModule,
1434
+ MatCardModule,
1435
+ MatMenuModule,
1436
+ MatIconModule,
1437
+ MatButtonModule,
1438
+ MatDialogModule,
1439
+ MatInputModule,
1440
+ MatSnackBarModule,
1441
+ MatProgressBarModule,
1442
+ MatProgressSpinnerModule,
1443
+ MatTableModule,
1444
+ MatPaginatorModule,
1445
+ MatChipsModule,
1446
+ MatBadgeModule,
1447
+ MatCheckboxModule,
1448
+ MatListModule,
1449
+ MatTabsModule,
1450
+ MatSlideToggleModule,
1451
+ MatAutocompleteModule,
1452
+ ],
1453
+ providers: [],
1454
+ }]
1455
+ }] });
1456
+
1457
+ class AuthProvider {
1458
+ constructor(http, config) {
1459
+ this.http = http;
1460
+ this.config = config;
1461
+ this.token = '';
1462
+ this.tokenTimestamps = {
1463
+ exp: 0,
1464
+ iat: 0,
1465
+ };
1466
+ }
1467
+ setConfig() { }
1468
+ get tokenExpired() {
1469
+ if (this.token == '' || this.tokenTimestamps.exp === 0) {
1470
+ console.log('EXPIRED');
1471
+ return true;
1472
+ }
1473
+ const { iat, exp } = this.tokenTimestamps;
1474
+ return iat + 20 > exp;
1475
+ }
1476
+ resetToken() {
1477
+ this.token = '';
1478
+ }
1479
+ get accesToken() {
1480
+ return this.tokenExpired ? this.getToken() : of(this.token);
1481
+ }
1482
+ getToken() {
1483
+ return this.http
1484
+ .post(this.config.path, {
1485
+ clientId: this.config.clientId,
1486
+ token: this.config.tokenName,
1487
+ })
1488
+ .pipe(map((data) => data.accessToken), tap((token) => {
1489
+ this.token = token;
1490
+ const decoded = jwt_decode(this.token);
1491
+ const { iat, exp } = decoded;
1492
+ this.tokenTimestamps = { iat, exp };
1493
+ }));
1494
+ }
6
1495
  }
7
- NgxScandocService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8
- NgxScandocService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocService, providedIn: 'root' });
9
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocService, decorators: [{
1496
+ AuthProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthProvider, deps: [{ token: i1$2.HttpClient }, { token: 'configAuth' }], target: i0.ɵɵFactoryTarget.Injectable });
1497
+ AuthProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthProvider, providedIn: 'root' });
1498
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AuthProvider, decorators: [{
10
1499
  type: Injectable,
11
1500
  args: [{
12
- providedIn: 'root'
1501
+ providedIn: 'root',
13
1502
  }]
14
- }], ctorParameters: function () { return []; } });
1503
+ }], ctorParameters: function () { return [{ type: i1$2.HttpClient }, { type: undefined, decorators: [{
1504
+ type: Inject,
1505
+ args: ['configAuth']
1506
+ }] }]; } });
1507
+
1508
+ class ScanProvider {
1509
+ constructor(http, auth, config) {
1510
+ this.http = http;
1511
+ this.auth = auth;
1512
+ this.config = config;
1513
+ this.enableVerification = true;
1514
+ this.canStoreImages = true;
1515
+ }
1516
+ genderList() {
1517
+ return {
1518
+ M: 'MALE',
1519
+ 'M/M': 'MALE',
1520
+ F: 'FEMALE',
1521
+ 'F/F': 'FEMALE',
1522
+ };
1523
+ }
1524
+ stateless(DocumentFaceImage, LiveFaceImage) {
1525
+ const data = {
1526
+ AcceptTermsAndConditions: true,
1527
+ DataFields: {
1528
+ DocumentFaceImageType: 'base64',
1529
+ DocumentFaceImage,
1530
+ LiveFaceImageType: 'base64',
1531
+ LiveFaceImage,
1532
+ },
1533
+ };
1534
+ const $request = this.http.post(this.config.stateLessPath, data);
1535
+ return $request;
1536
+ }
1537
+ sendLog(data) {
1538
+ const { TransactionID } = data.Response;
1539
+ const $request = this.http.post(this.config.errorLoggingPath, data, {
1540
+ headers: new HttpHeaders({
1541
+ TransactionID,
1542
+ }),
1543
+ });
1544
+ return $request;
1545
+ }
1546
+ burst(Images) {
1547
+ const data = {
1548
+ AcceptTermsAndConditions: true,
1549
+ DataFields: {
1550
+ Images,
1551
+ },
1552
+ };
1553
+ const $request = this.http.post(this.config.validationPath, data);
1554
+ return $request;
1555
+ }
1556
+ countries() {
1557
+ return this.http.get('/assets/data/countries.json').pipe(map((data) => {
1558
+ return data.data.map((c) => {
1559
+ return { label: c.short.en, value: c.cca2 };
1560
+ });
1561
+ }));
1562
+ }
1563
+ countryList() {
1564
+ return {
1565
+ AFG: 'AF',
1566
+ ALB: 'AL',
1567
+ DZA: 'DZ',
1568
+ ASM: 'AS',
1569
+ AND: 'AD',
1570
+ AGO: 'AO',
1571
+ AIA: 'AI',
1572
+ ATG: 'AG',
1573
+ ARG: 'AR',
1574
+ ARM: 'AM',
1575
+ ABW: 'AW',
1576
+ AUS: 'AU',
1577
+ AUT: 'AT',
1578
+ AZE: 'AZ',
1579
+ BHS: 'BS',
1580
+ BHR: 'BH',
1581
+ BGD: 'BD',
1582
+ BRB: 'BB',
1583
+ BLR: 'BY',
1584
+ BEL: 'BE',
1585
+ BLZ: 'BZ',
1586
+ BEN: 'BJ',
1587
+ BMU: 'BM',
1588
+ BTN: 'BT',
1589
+ BOL: 'BO',
1590
+ BIH: 'BA',
1591
+ BWA: 'BW',
1592
+ BRA: 'BR',
1593
+ VGB: 'VG',
1594
+ BRN: 'BN',
1595
+ BGR: 'BG',
1596
+ BFA: 'BF',
1597
+ BDI: 'BI',
1598
+ KHM: 'KH',
1599
+ CMR: 'CM',
1600
+ CAN: 'CA',
1601
+ CPV: 'CV',
1602
+ CAF: 'CF',
1603
+ TCD: 'TD',
1604
+ CHL: 'CL',
1605
+ CHN: 'CN',
1606
+ HKG: 'HK',
1607
+ MAC: 'MO',
1608
+ COL: 'CO',
1609
+ COM: 'KM',
1610
+ COG: 'CG',
1611
+ CRI: 'CR',
1612
+ CIV: 'CI',
1613
+ HRV: 'HR',
1614
+ CUB: 'CU',
1615
+ CYP: 'CY',
1616
+ CZE: 'CZ',
1617
+ DNK: 'DK',
1618
+ DJI: 'DJ',
1619
+ DMA: 'DM',
1620
+ DOM: 'DO',
1621
+ ECU: 'EC',
1622
+ EGY: 'EG',
1623
+ SLV: 'SV',
1624
+ GNQ: 'GQ',
1625
+ ERI: 'ER',
1626
+ EST: 'EE',
1627
+ ETH: 'ET',
1628
+ FRO: 'FO',
1629
+ FJI: 'FJ',
1630
+ FIN: 'FI',
1631
+ FRA: 'FR',
1632
+ GUF: 'GF',
1633
+ PYF: 'PF',
1634
+ GAB: 'GA',
1635
+ GMB: 'GM',
1636
+ GEO: 'GE',
1637
+ DEU: 'DE',
1638
+ GHA: 'GH',
1639
+ GRC: 'GR',
1640
+ GRL: 'GL',
1641
+ GRD: 'GD',
1642
+ GLP: 'GP',
1643
+ GUM: 'GU',
1644
+ GTM: 'GT',
1645
+ GNB: 'GW',
1646
+ HTI: 'HT',
1647
+ HND: 'HN',
1648
+ ISL: 'IS',
1649
+ IDN: 'ID',
1650
+ IRQ: 'IQ',
1651
+ ITA: 'IT',
1652
+ JPN: 'JP',
1653
+ JOR: 'JO',
1654
+ KAZ: 'KZ',
1655
+ KEN: 'KE',
1656
+ KIR: 'KI',
1657
+ PRK: 'KP',
1658
+ KOR: 'KR',
1659
+ KWT: 'KW',
1660
+ KGZ: 'KG',
1661
+ LAO: 'LA',
1662
+ LVA: 'LV',
1663
+ LBN: 'LB',
1664
+ LSO: 'LS',
1665
+ LBR: 'LR',
1666
+ LBY: 'LY',
1667
+ LIE: 'LI',
1668
+ LTU: 'LT',
1669
+ LUX: 'LU',
1670
+ MDG: 'MG',
1671
+ MWI: 'MW',
1672
+ MYS: 'MY',
1673
+ MDV: 'MV',
1674
+ MLI: 'ML',
1675
+ MLT: 'MT',
1676
+ MHL: 'MH',
1677
+ MTQ: 'MQ',
1678
+ MRT: 'MR',
1679
+ MUS: 'MU',
1680
+ MEX: 'MX',
1681
+ FSM: 'FM',
1682
+ MDA: 'MD',
1683
+ MCO: 'MC',
1684
+ MNG: 'MN',
1685
+ MNE: 'ME',
1686
+ MSR: 'MS',
1687
+ MAR: 'MA',
1688
+ MOZ: 'MZ',
1689
+ MMR: 'MM',
1690
+ NAM: 'NA',
1691
+ NRU: 'NR',
1692
+ NPL: 'NP',
1693
+ NLD: 'NL',
1694
+ ANT: 'AN',
1695
+ NCL: 'NC',
1696
+ NZL: 'NZ',
1697
+ NIC: 'NI',
1698
+ NER: 'NE',
1699
+ NGA: 'NG',
1700
+ MNP: 'MP',
1701
+ NOR: 'NO',
1702
+ OMN: 'OM',
1703
+ PAK: 'PK',
1704
+ PLW: 'PW',
1705
+ PSE: 'PS',
1706
+ PAN: 'PA',
1707
+ PNG: 'PG',
1708
+ PRY: 'PY',
1709
+ PER: 'PE',
1710
+ PHL: 'PH',
1711
+ PCN: 'PN',
1712
+ POL: 'PL',
1713
+ PRT: 'PT',
1714
+ PRI: 'PR',
1715
+ QAT: 'QA',
1716
+ REU: 'RE',
1717
+ ROU: 'RO',
1718
+ RUS: 'RU',
1719
+ RWA: 'RW',
1720
+ KNA: 'KN',
1721
+ LCA: 'LC',
1722
+ VCT: 'VC',
1723
+ WSM: 'WS',
1724
+ SMR: 'SM',
1725
+ STP: 'ST',
1726
+ SAU: 'SA',
1727
+ SEN: 'SN',
1728
+ SRB: 'RS',
1729
+ SYC: 'SC',
1730
+ SLE: 'SL',
1731
+ SGP: 'SG',
1732
+ SVK: 'SK',
1733
+ SVN: 'SI',
1734
+ SLB: 'SB',
1735
+ SOM: 'SO',
1736
+ ZAF: 'ZA',
1737
+ ESP: 'ES',
1738
+ LKA: 'LK',
1739
+ SDN: 'SD',
1740
+ SUR: 'SR',
1741
+ SWZ: 'SZ',
1742
+ SWE: 'SE',
1743
+ CHE: 'CH',
1744
+ SYR: 'SY',
1745
+ TJK: 'TJ',
1746
+ TZA: 'TZ',
1747
+ THA: 'TH',
1748
+ TLS: 'TL',
1749
+ TGO: 'TG',
1750
+ TON: 'TO',
1751
+ TTO: 'TT',
1752
+ TUN: 'TN',
1753
+ TUR: 'TR',
1754
+ TKM: 'TM',
1755
+ TUV: 'TV',
1756
+ UGA: 'UG',
1757
+ UKR: 'UA',
1758
+ ARE: 'AE',
1759
+ GBR: 'GB',
1760
+ USA: 'US',
1761
+ URY: 'UY',
1762
+ UZB: 'UZ',
1763
+ VUT: 'VU',
1764
+ VEN: 'VE',
1765
+ VNM: 'VN',
1766
+ VIR: 'VI',
1767
+ YEM: 'YE',
1768
+ ZMB: 'ZM',
1769
+ ZWE: 'ZW',
1770
+ };
1771
+ }
1772
+ get fields() {
1773
+ return [
1774
+ {
1775
+ key: 'Birth Date',
1776
+ form: 'birthDate',
1777
+ type: 'date',
1778
+ main: false,
1779
+ blastKey: 'BirthDate',
1780
+ },
1781
+ {
1782
+ key: 'Given Name',
1783
+ form: 'firstName',
1784
+ ucFirst: true,
1785
+ type: 'string',
1786
+ main: true,
1787
+ blastKey: 'Name',
1788
+ },
1789
+ {
1790
+ key: 'Surname',
1791
+ form: 'lastName',
1792
+ ucFirst: true,
1793
+ type: 'string',
1794
+ main: true,
1795
+ blastKey: 'Surname',
1796
+ },
1797
+ {
1798
+ key: 'Sex',
1799
+ form: 'gender',
1800
+ type: 'gender',
1801
+ main: false,
1802
+ blastKey: 'Gender',
1803
+ },
1804
+ {
1805
+ key: 'Document Class Name',
1806
+ type: 'string',
1807
+ form: 'documentType',
1808
+ main: false,
1809
+ blastKey: 'docType',
1810
+ },
1811
+ {
1812
+ key: 'Document Number',
1813
+ type: 'string',
1814
+ form: 'documentNumber',
1815
+ main: false,
1816
+ blastKey: 'DocumentNumber',
1817
+ },
1818
+ {
1819
+ key: 'Issuing State Code',
1820
+ type: 'country',
1821
+ form: 'issueStateCode',
1822
+ blastKey: 'CountryOfIssue',
1823
+ main: false,
1824
+ },
1825
+ {
1826
+ key: 'Expiration Date',
1827
+ type: 'date',
1828
+ form: 'expirationDate',
1829
+ blastKey: 'ExpiryDate',
1830
+ main: false,
1831
+ },
1832
+ {
1833
+ key: 'Issue Date',
1834
+ type: 'date',
1835
+ form: 'issueDate',
1836
+ blastKey: 'IssuedDate',
1837
+ main: false,
1838
+ },
1839
+ {
1840
+ key: 'Birth Place',
1841
+ type: 'string',
1842
+ form: 'birthPlace',
1843
+ blastKey: 'PlaceOfBirth',
1844
+ main: false,
1845
+ },
1846
+ {
1847
+ key: 'Issuing Authority',
1848
+ type: 'string',
1849
+ form: 'issuingPlace',
1850
+ blastKey: 'IssuingAuthority',
1851
+ main: false,
1852
+ },
1853
+ {
1854
+ key: 'Nationality Code',
1855
+ type: 'country',
1856
+ form: 'nationality',
1857
+ main: false,
1858
+ blastKey: 'Nationality',
1859
+ },
1860
+ {
1861
+ key: 'street1',
1862
+ type: 'string',
1863
+ form: 'street1',
1864
+ main: false,
1865
+ blastKey: 'AddressStreet',
1866
+ },
1867
+ {
1868
+ key: 'city',
1869
+ type: 'string',
1870
+ form: 'city',
1871
+ main: false,
1872
+ blastKey: 'AddressCity',
1873
+ },
1874
+ {
1875
+ key: 'country',
1876
+ type: 'country',
1877
+ form: 'country',
1878
+ main: false,
1879
+ blastKey: 'Country',
1880
+ },
1881
+ {
1882
+ key: 'zip',
1883
+ type: 'string',
1884
+ form: 'zip',
1885
+ main: false,
1886
+ blastKey: 'AddressZip',
1887
+ },
1888
+ ];
1889
+ }
1890
+ parseBlast(results) {
1891
+ const countries = this.countryList();
1892
+ const genders = this.genderList();
1893
+ const data = this.fields;
1894
+ const validatedAddressFields = [
1895
+ 'AddressCity',
1896
+ 'AddressZip',
1897
+ 'AddressCounty',
1898
+ 'AddressStreet',
1899
+ ].filter((key) => results[key].Validated);
1900
+ // if no address is validated
1901
+ if (validatedAddressFields.length === 0) {
1902
+ if (results.Address.Validated) {
1903
+ results.AddressStreet = results.Address;
1904
+ }
1905
+ }
1906
+ const out = data.map((itm) => {
1907
+ const res = results[itm.blastKey];
1908
+ if (res) {
1909
+ const value = res.RecommendedValue || '';
1910
+ switch (itm.type) {
1911
+ case 'string':
1912
+ itm.value = value;
1913
+ if (itm.ucFirst) {
1914
+ const name = value.toLowerCase();
1915
+ itm.value = name.charAt(0).toUpperCase() + name.slice(1);
1916
+ }
1917
+ break;
1918
+ case 'date':
1919
+ itm.value = value ? moment(value, 'DD.MM.YYYY').toDate() : null;
1920
+ // if (value.indexOf('/Date') >= 0) {
1921
+ // console.log(value);
1922
+ // const timestamp = value.replace(/\D/gm, '');
1923
+ // //itm.value = moment.unix(timestamp / 1000).toDate();
1924
+ // itm.value = moment(
1925
+ // timestamp - moment(timestamp, 'x').utcOffset() * 60 * 1000,
1926
+ // 'x',
1927
+ // ).toDate();
1928
+ // }
1929
+ break;
1930
+ case 'country':
1931
+ itm.value = countries[value] || null;
1932
+ break;
1933
+ case 'gender':
1934
+ itm.value = genders[value] || null;
1935
+ }
1936
+ }
1937
+ return itm;
1938
+ });
1939
+ const model = {};
1940
+ out.forEach((element) => {
1941
+ console.log(element);
1942
+ model[element.form] = element.value;
1943
+ });
1944
+ model.documentType = results.Metadata.DocumentType;
1945
+ console.log(model);
1946
+ return {
1947
+ fields: out,
1948
+ model,
1949
+ };
1950
+ }
1951
+ blastPost(data) {
1952
+ // const $request = this.api.http.get('/assets/json/blastscan.json');
1953
+ const $request = this.http.post(this.config.extractionPath, data);
1954
+ return $request.pipe(map((m) => {
1955
+ if (m.Metadata && m.Metadata.length > 0) {
1956
+ const metadata = m.Metadata[0];
1957
+ m.Data.Country = {
1958
+ RecommendedValue: metadata.Country,
1959
+ };
1960
+ m.Data.Metadata = metadata;
1961
+ }
1962
+ return m;
1963
+ }));
1964
+ }
1965
+ blobToDataUrl(file) {
1966
+ return Observable.create((obs) => {
1967
+ const reader = new FileReader();
1968
+ reader.onerror = (err) => obs.error(err);
1969
+ reader.onabort = (err) => obs.error(err);
1970
+ reader.onload = () => {
1971
+ obs.next(reader.result);
1972
+ };
1973
+ reader.onloadend = () => obs.complete();
1974
+ return reader.readAsDataURL(file);
1975
+ });
1976
+ }
1977
+ }
1978
+ ScanProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanProvider, deps: [{ token: i1$2.HttpClient }, { token: AuthProvider }, { token: 'config' }], target: i0.ɵɵFactoryTarget.Injectable });
1979
+ ScanProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanProvider, providedIn: 'root' });
1980
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanProvider, decorators: [{
1981
+ type: Injectable,
1982
+ args: [{
1983
+ providedIn: 'root',
1984
+ }]
1985
+ }], ctorParameters: function () { return [{ type: i1$2.HttpClient }, { type: AuthProvider }, { type: undefined, decorators: [{
1986
+ type: Inject,
1987
+ args: ['config']
1988
+ }] }]; } });
1989
+
1990
+ class BlankComponent {
1991
+ constructor(dialogRef, data, componentFactoryResolver, cd) {
1992
+ this.dialogRef = dialogRef;
1993
+ this.data = data;
1994
+ this.componentFactoryResolver = componentFactoryResolver;
1995
+ this.cd = cd;
1996
+ this.initSet = false;
1997
+ }
1998
+ setModel(model) {
1999
+ this.data.data.model = model;
2000
+ this.init();
2001
+ }
2002
+ init() {
2003
+ this.initSet = true;
2004
+ const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.data.component);
2005
+ this.body?.clear();
2006
+ const componentRef = this.body?.createComponent(componentFactory);
2007
+ componentRef.instance.data = this.data.data;
2008
+ componentRef.instance.dialogRef = this.dialogRef;
2009
+ if (componentRef.instance.init) {
2010
+ componentRef.instance.init();
2011
+ }
2012
+ this.cd.detectChanges();
2013
+ }
2014
+ ngAfterViewInit() {
2015
+ if (!this.initSet) {
2016
+ this.init();
2017
+ }
2018
+ }
2019
+ }
2020
+ BlankComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BlankComponent, deps: [{ token: i1$3.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: i0.ComponentFactoryResolver }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2021
+ BlankComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BlankComponent, selector: "app-dialog-blank", viewQueries: [{ propertyName: "body", first: true, predicate: ["body"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<ng-template #body></ng-template>\n", styles: [":host{display:flex;flex:1;flex-direction:column;overflow:hidden;height:100%}\n"] });
2022
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BlankComponent, decorators: [{
2023
+ type: Component,
2024
+ args: [{ selector: 'app-dialog-blank', template: "<ng-template #body></ng-template>\n", styles: [":host{display:flex;flex:1;flex-direction:column;overflow:hidden;height:100%}\n"] }]
2025
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }, { type: undefined, decorators: [{
2026
+ type: Inject,
2027
+ args: [MAT_DIALOG_DATA]
2028
+ }] }, { type: i0.ComponentFactoryResolver }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { body: [{
2029
+ type: ViewChild,
2030
+ args: ['body', { read: ViewContainerRef, static: true }]
2031
+ }] } });
2032
+
2033
+ class LoadingComponent {
2034
+ }
2035
+ LoadingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2036
+ LoadingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: LoadingComponent, selector: "app-loading", ngImport: i0, template: "<div style=\"width:240px;\">\n\n <div class=\"pb-16\" style=\"font-size: 18px;padding-bottom:16px;\">\n Loading...\n </div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: i1$4.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }] });
2037
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: LoadingComponent, decorators: [{
2038
+ type: Component,
2039
+ args: [{ selector: 'app-loading', template: "<div style=\"width:240px;\">\n\n <div class=\"pb-16\" style=\"font-size: 18px;padding-bottom:16px;\">\n Loading...\n </div>\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n</div>\n" }]
2040
+ }] });
15
2041
 
16
- class NgxScandocComponent {
17
- constructor() { }
2042
+ class ConfirmComponent {
2043
+ constructor(dialogRef, data) {
2044
+ this.dialogRef = dialogRef;
2045
+ this.data = data;
2046
+ this.showDetails = false;
2047
+ this.images = {
2048
+ alert: 'page-lost.svg',
2049
+ prompt: 'bedroom.svg',
2050
+ dirty: 'opps.svg',
2051
+ };
2052
+ this.options = {};
2053
+ }
2054
+ onEnterPress(e) {
2055
+ this.action(true);
2056
+ }
2057
+ onEscapePress(e) {
2058
+ this.action(false);
2059
+ }
18
2060
  ngOnInit() {
2061
+ console.log(this.data);
2062
+ this.options = this.data.options || {};
2063
+ this.type = this.options.type || this.data.type || 'prompt';
2064
+ }
2065
+ action(key) {
2066
+ this.dialogRef.close(key);
19
2067
  }
2068
+ close() { }
20
2069
  }
21
- NgxScandocComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
22
- NgxScandocComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgxScandocComponent, selector: "lib-ngx-scandoc", ngImport: i0, template: `
23
- <p>
24
- ngx-scandoc works!
25
- </p>
26
- `, isInline: true });
27
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocComponent, decorators: [{
2070
+ ConfirmComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ConfirmComponent, deps: [{ token: i1$3.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
2071
+ ConfirmComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ConfirmComponent, selector: "app-confirm", host: { listeners: { "document:keyup.enter": "onEnterPress($event)", "document:keyup.escape": "onEscapePress($event)" } }, ngImport: i0, template: "<header class=\"page-header\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n\n\n <div class=\"title\" ngClass.lt-sm=\"title-small\">\n {{ data.title | translate }}\n\n <!-- {{ data.text.statusText }} {{ data.text.status }} -->\n </div>\n\n <span fxFlex></span>\n\n <!-- <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button> -->\n <!-- <mat-icon class=\"mr-16\" style=\"color:#888;\">info_outline</mat-icon> -->\n</header>\n\n<div fxLayout=\"column\" fxLayoutAlign=\"center center\">\n <!-- <img\n style=\"height: 240px; margin: 34px 0px;display: none;\"\n [src]=\"'/assets/images/illustrations/' + images[type]\"\n /> -->\n <!-- <img style=\"width:60px;\" src=\"/assets/images/illustrations/door-lock.png\"> -->\n\n <div class=\"text\" *ngIf=\"data.text\">\n <span [innerHtml]=\"data.text\"></span>\n </div>\n</div>\n\n<!-- -->\n\n<footer>\n\n <div class=\"actions\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button\n *ngIf=\"!data.alert && !options?.hideCancelButton\"\n (click)=\"action(false)\"\n mat-raised-button\n >\n {{ data.cancel || 'core.page.cancel' | translate }}\n </button>\n\n <button\n *ngIf=\"data.no && !options?.hideNoButton\"\n (click)=\"action('no')\"\n\n mat-raised-button\n >\n {{ data.no }}\n </button>\n <button\n *ngIf=\"!data.hideOkButton && !options?.hideOkButton\"\n (click)=\"action(true)\"\n color=\"accent\"\n mat-raised-button\n >\n <ng-container *ngIf=\"!data.alert\">\n {{ data.ok || 'core.page.confirm' | translate }}\n </ng-container>\n\n <ng-container *ngIf=\"data.alert\">\n {{ data.ok || 'core.page.close' | translate }}\n </ng-container>\n </button>\n </div>\n</footer>\n", styles: [":host{display:flex;flex-direction:column;flex:1;height:100%;width:100%}.title{font-size:18px}.text{padding:0 30px;text-align:center;font-size:16px;margin:40px 0}.actions{min-height:60px}.actions button{min-width:120px;margin-right:16px;box-shadow:none;text-transform:uppercase}footer{background-color:#fff}footer button{box-shadow:none!important;border:1px solid rgba(0,0,0,.12);font-size:13px}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i4.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i4.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i5$1.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }] });
2072
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ConfirmComponent, decorators: [{
28
2073
  type: Component,
29
- args: [{ selector: 'lib-ngx-scandoc', template: `
30
- <p>
31
- ngx-scandoc works!
32
- </p>
33
- ` }]
2074
+ args: [{ selector: 'app-confirm', template: "<header class=\"page-header\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n\n\n <div class=\"title\" ngClass.lt-sm=\"title-small\">\n {{ data.title | translate }}\n\n <!-- {{ data.text.statusText }} {{ data.text.status }} -->\n </div>\n\n <span fxFlex></span>\n\n <!-- <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button> -->\n <!-- <mat-icon class=\"mr-16\" style=\"color:#888;\">info_outline</mat-icon> -->\n</header>\n\n<div fxLayout=\"column\" fxLayoutAlign=\"center center\">\n <!-- <img\n style=\"height: 240px; margin: 34px 0px;display: none;\"\n [src]=\"'/assets/images/illustrations/' + images[type]\"\n /> -->\n <!-- <img style=\"width:60px;\" src=\"/assets/images/illustrations/door-lock.png\"> -->\n\n <div class=\"text\" *ngIf=\"data.text\">\n <span [innerHtml]=\"data.text\"></span>\n </div>\n</div>\n\n<!-- -->\n\n<footer>\n\n <div class=\"actions\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button\n *ngIf=\"!data.alert && !options?.hideCancelButton\"\n (click)=\"action(false)\"\n mat-raised-button\n >\n {{ data.cancel || 'core.page.cancel' | translate }}\n </button>\n\n <button\n *ngIf=\"data.no && !options?.hideNoButton\"\n (click)=\"action('no')\"\n\n mat-raised-button\n >\n {{ data.no }}\n </button>\n <button\n *ngIf=\"!data.hideOkButton && !options?.hideOkButton\"\n (click)=\"action(true)\"\n color=\"accent\"\n mat-raised-button\n >\n <ng-container *ngIf=\"!data.alert\">\n {{ data.ok || 'core.page.confirm' | translate }}\n </ng-container>\n\n <ng-container *ngIf=\"data.alert\">\n {{ data.ok || 'core.page.close' | translate }}\n </ng-container>\n </button>\n </div>\n</footer>\n", styles: [":host{display:flex;flex-direction:column;flex:1;height:100%;width:100%}.title{font-size:18px}.text{padding:0 30px;text-align:center;font-size:16px;margin:40px 0}.actions{min-height:60px}.actions button{min-width:120px;margin-right:16px;box-shadow:none;text-transform:uppercase}footer{background-color:#fff}footer button{box-shadow:none!important;border:1px solid rgba(0,0,0,.12);font-size:13px}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"] }]
2075
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }, { type: undefined, decorators: [{
2076
+ type: Inject,
2077
+ args: [MAT_DIALOG_DATA]
2078
+ }] }]; }, propDecorators: { onEnterPress: [{
2079
+ type: HostListener,
2080
+ args: ['document:keyup.enter', ['$event']]
2081
+ }], onEscapePress: [{
2082
+ type: HostListener,
2083
+ args: ['document:keyup.escape', ['$event']]
2084
+ }] } });
2085
+
2086
+ class webRtcProvider {
2087
+ constructor() {
2088
+ this.pc = new RTCPeerConnection();
2089
+ }
2090
+ connect(id = 1) {
2091
+ this.subject = webSocket('wss://localhost:3000?id=' + id);
2092
+ }
2093
+ setup() {
2094
+ this.connect(1);
2095
+ // try {
2096
+ // this.pc = new RTCPeerConnection({
2097
+ // iceServers: [
2098
+ // { urls: 'stun:stun.services.mozilla.com' },
2099
+ // { urls: 'stun:stun.l.google.com:19302' },
2100
+ // ],
2101
+ // });
2102
+ // } catch (error) {
2103
+ // console.log(error);
2104
+ // this.pc = new RTCPeerConnection({
2105
+ // iceServers: [
2106
+ // { urls: 'stun:stun.services.mozilla.com' },
2107
+ // { urls: 'stun:stun.l.google.com:19302' },
2108
+ // ],
2109
+ // });
2110
+ // }
2111
+ // this.pc.onicecandidate = (event) => {
2112
+ // event.candidate
2113
+ // ? this.sendMessage({ ice: event.candidate })
2114
+ // : console.log('Sent All Ice');
2115
+ // };
2116
+ // if (this.pc) {
2117
+ // from(this.pc.createOffer())
2118
+ // .pipe(switchMap((offer) => from(this.pc.setLocalDescription(offer))))
2119
+ // .subscribe((data: any) => {
2120
+ // this.sendMessage({
2121
+ // type: 'offer',
2122
+ // sdp: this.pc.localDescription,
2123
+ // });
2124
+ // });
2125
+ // }
2126
+ }
2127
+ sendMessage(data) {
2128
+ console.log(data);
2129
+ this.subject.next(JSON.stringify(data));
2130
+ }
2131
+ }
2132
+ webRtcProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: webRtcProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2133
+ webRtcProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: webRtcProvider, providedIn: 'root' });
2134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: webRtcProvider, decorators: [{
2135
+ type: Injectable,
2136
+ args: [{
2137
+ providedIn: 'root',
2138
+ }]
34
2139
  }], ctorParameters: function () { return []; } });
35
2140
 
36
- class NgxScandocModule {
2141
+ class ScanMobileComponent {
2142
+ constructor(dialogRef, data, rtcProvider) {
2143
+ this.dialogRef = dialogRef;
2144
+ this.data = data;
2145
+ this.rtcProvider = rtcProvider;
2146
+ }
2147
+ ngOnInit() {
2148
+ this.rtcProvider.setup();
2149
+ this.rtcProvider.subject.subscribe((msg) => {
2150
+ console.log('[MSG]' + msg);
2151
+ }, // Called whenever there is a message from the server.
2152
+ (err) => console.log(err), // Called if at any point WebSocket API signals some kind of error.
2153
+ () => console.log('complete') // Called when connection is closed (for whatever reason).
2154
+ );
2155
+ console.log(this.data);
2156
+ const path = 'https://192.168.1.104:4200/';
2157
+ this.code = path + 'mobile?id=1';
2158
+ }
2159
+ close() {
2160
+ this.dialogRef.close();
2161
+ }
2162
+ action() { }
37
2163
  }
38
- NgxScandocModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
39
- NgxScandocModulemod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, declarations: [NgxScandocComponent], exports: [NgxScandocComponent] });
40
- NgxScandocModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule });
41
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, decorators: [{
2164
+ ScanMobileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanMobileComponent, deps: [{ token: i1$3.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: webRtcProvider }], target: i0.ɵɵFactoryTarget.Component });
2165
+ ScanMobileComponentcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScanMobileComponent, selector: "app-scan-mobile", ngImport: i0, template: "<header class=\"page-header\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <div class=\"title\" ngClass.lt-sm=\"title-small\">\n Send to mobile\n\n <!-- {{ data.text.statusText }} {{ data.text.status }} -->\n </div>\n\n <span fxFlex></span>\n\n <!-- <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button> -->\n <!-- <mat-icon class=\"mr-16\" style=\"color:#888;\">info_outline</mat-icon> -->\n</header>\n\n<div fxLayout=\"column\" fxLayoutAlign=\"center center\">\n <!-- <img\n style=\"height: 240px; margin: 34px 0px;display: none;\"\n [src]=\"'/assets/images/illustrations/' + images[type]\"\n /> -->\n <!-- <img style=\"width:60px;\" src=\"/assets/images/illustrations/door-lock.png\"> -->\n\n<qrcode [qrdata]=\"code\" [width]=\"256\" [errorCorrectionLevel]=\"'M'\"></qrcode>\n\n\n</div>\n\n<!-- -->\n\n<footer>\n <div class=\"actions\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button (click)=\"close()\" mat-raised-button>\n {{ \"core.page.cancel\" | translate }}\n </button>\n\n <button (click)=\"action()\" color=\"accent\" mat-raised-button>\n <ng-container>\n {{ \"core.page.ok\" | translate }}\n </ng-container>\n </button>\n </div>\n</footer>\n", styles: [":host{display:flex;flex-direction:column;flex:1;height:100%;width:100%}.title{font-size:18px}.text{padding:0 30px;text-align:center;font-size:16px;margin:40px 0}.actions{min-height:60px}.actions button{min-width:120px;margin-right:16px;box-shadow:none;text-transform:uppercase}footer{background-color:#fff}footer button{box-shadow:none!important;border:1px solid rgba(0,0,0,.12);font-size:13px}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"], dependencies: [{ kind: "component", type: i3$1.QRCodeComponent, selector: "qrcode", inputs: ["allowEmptyString", "colorDark", "colorLight", "cssClass", "elementType", "errorCorrectionLevel", "imageSrc", "imageHeight", "imageWidth", "margin", "qrdata", "scale", "version", "width", "alt", "ariaLabel", "title"], outputs: ["qrCodeURL"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i4.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i4.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i4.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i5$1.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }] });
2166
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanMobileComponent, decorators: [{
2167
+ type: Component,
2168
+ args: [{ selector: 'app-scan-mobile', template: "<header class=\"page-header\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <div class=\"title\" ngClass.lt-sm=\"title-small\">\n Send to mobile\n\n <!-- {{ data.text.statusText }} {{ data.text.status }} -->\n </div>\n\n <span fxFlex></span>\n\n <!-- <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button> -->\n <!-- <mat-icon class=\"mr-16\" style=\"color:#888;\">info_outline</mat-icon> -->\n</header>\n\n<div fxLayout=\"column\" fxLayoutAlign=\"center center\">\n <!-- <img\n style=\"height: 240px; margin: 34px 0px;display: none;\"\n [src]=\"'/assets/images/illustrations/' + images[type]\"\n /> -->\n <!-- <img style=\"width:60px;\" src=\"/assets/images/illustrations/door-lock.png\"> -->\n\n<qrcode [qrdata]=\"code\" [width]=\"256\" [errorCorrectionLevel]=\"'M'\"></qrcode>\n\n\n</div>\n\n<!-- -->\n\n<footer>\n <div class=\"actions\" fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button (click)=\"close()\" mat-raised-button>\n {{ \"core.page.cancel\" | translate }}\n </button>\n\n <button (click)=\"action()\" color=\"accent\" mat-raised-button>\n <ng-container>\n {{ \"core.page.ok\" | translate }}\n </ng-container>\n </button>\n </div>\n</footer>\n", styles: [":host{display:flex;flex-direction:column;flex:1;height:100%;width:100%}.title{font-size:18px}.text{padding:0 30px;text-align:center;font-size:16px;margin:40px 0}.actions{min-height:60px}.actions button{min-width:120px;margin-right:16px;box-shadow:none;text-transform:uppercase}footer{background-color:#fff}footer button{box-shadow:none!important;border:1px solid rgba(0,0,0,.12);font-size:13px}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"] }]
2169
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialogRef }, { type: undefined, decorators: [{
2170
+ type: Inject,
2171
+ args: [MAT_DIALOG_DATA]
2172
+ }] }, { type: webRtcProvider }]; } });
2173
+
2174
+ class ScanSelfieComponent {
2175
+ constructor(cd, scanProvider, dialogs,
2176
+ // private formProvider: ScanFieldsProvider,
2177
+ translate) {
2178
+ this.cd = cd;
2179
+ this.scanProvider = scanProvider;
2180
+ this.dialogs = dialogs;
2181
+ this.translate = translate;
2182
+ this.scanBlastData = [
2183
+ {
2184
+ title: 'pms.dialogs.components.scanProfile.front',
2185
+ description: 'pms.dialogs.components.scanProfile.frontDescription',
2186
+ side: 'FRONT',
2187
+ },
2188
+ {
2189
+ title: 'pms.dialogs.components.scanProfile.back',
2190
+ description: 'pms.dialogs.components.scanProfile.backDescription',
2191
+ disabled: true,
2192
+ side: 'BACK',
2193
+ },
2194
+ ];
2195
+ this.type = 'desktop';
2196
+ this.actions = new EventEmitter();
2197
+ this.mediaDevices = [];
2198
+ this.videoOptions = {
2199
+ width: 1920,
2200
+ height: 1080,
2201
+ facingMode: 'environment',
2202
+ };
2203
+ this.multipleWebcamsAvailable = false;
2204
+ // webcam snapshot trigger
2205
+ this.documentTypeSelected = false;
2206
+ this.preview = null;
2207
+ this.allowCameraSwitch = true;
2208
+ this.error = false;
2209
+ this.cameraReady = false;
2210
+ this.scaning = false;
2211
+ this.scanDatas = [];
2212
+ this.trigger = new Subject();
2213
+ // switch to next / previous / specific webcam; true/false: forward/backwards, string: deviceId
2214
+ this.nextWebcam = new Subject();
2215
+ this.form = new FormGroup({});
2216
+ }
2217
+ onResize() {
2218
+ if (this.wraper) {
2219
+ this.width = this.wraper.nativeElement.clientWidth;
2220
+ this.height = this.wraper.nativeElement.clientHeight;
2221
+ console.log(this.width, this.height);
2222
+ setTimeout(() => {
2223
+ const video = this.wraper?.nativeElement.querySelector('video');
2224
+ if (video) {
2225
+ // console.log(video.clientWidth, video.clientHeight);
2226
+ this.videoWidth = video.clientWidth;
2227
+ this.videoHeight = video.clientHeight;
2228
+ }
2229
+ }, 100);
2230
+ this.cd.detectChanges();
2231
+ }
2232
+ }
2233
+ init() {
2234
+ console.log('HAS MULTI');
2235
+ // this.result=true;
2236
+ // this.result ={};
2237
+ this.fields = []; //this.formProvider.document();
2238
+ WebcamUtil.getAvailableVideoInputs().subscribe((mediaDevices) => {
2239
+ console.log('[DEVICES]', mediaDevices);
2240
+ this.mediaDevices = mediaDevices;
2241
+ this.multipleWebcamsAvailable = mediaDevices && mediaDevices.length > 1;
2242
+ this.singleScan(this.scanBlastData[0]);
2243
+ });
2244
+ }
2245
+ handleImage(webcamImage) {
2246
+ console.log('[received webcam image]', webcamImage);
2247
+ this.webcamImage = webcamImage;
2248
+ this.preview = webcamImage.imageAsDataUrl;
2249
+ this.cd.detectChanges();
2250
+ }
2251
+ handleInitError(error) {
2252
+ console.log(error);
2253
+ }
2254
+ get scanBlastCanUpload() {
2255
+ return this.scanBlastData[0].image ? true : false;
2256
+ }
2257
+ cameraWasSwitched(deviceId) {
2258
+ console.log('active device: ' + deviceId);
2259
+ this.deviceId = deviceId;
2260
+ this.cameraReady = true;
2261
+ this.defaultDevice = deviceId;
2262
+ this.onResize();
2263
+ }
2264
+ get nextWebcamObservable() {
2265
+ return this.nextWebcam.asObservable();
2266
+ }
2267
+ ngAfterViewInit() {
2268
+ this.cd.detectChanges();
2269
+ }
2270
+ selectCamera(event) {
2271
+ console.log(event);
2272
+ this.nextWebcam.next(event.value);
2273
+ }
2274
+ close() {
2275
+ this.dialogRef?.close();
2276
+ }
2277
+ singleScan(side) {
2278
+ this.scanType = side.side;
2279
+ this.preview = null;
2280
+ this.selectedSide = side;
2281
+ this.selectedSide.image = null;
2282
+ this.documentTypeSelected = true;
2283
+ this.scanBlastData[1].disabled = false;
2284
+ this.cd.detectChanges();
2285
+ setTimeout(() => {
2286
+ this.onResize();
2287
+ }, 10);
2288
+ }
2289
+ getBase64(file) {
2290
+ return new Observable((observer) => {
2291
+ const reader = new FileReader();
2292
+ reader.readAsDataURL(file);
2293
+ reader.onload = () => {
2294
+ observer.next(reader.result);
2295
+ };
2296
+ reader.onerror = (error) => {
2297
+ observer.error(error);
2298
+ };
2299
+ });
2300
+ }
2301
+ handleFileInput(target, event, side) {
2302
+ const files = target.files;
2303
+ this.selectedSide = side;
2304
+ console.log(files);
2305
+ const file = files.item(0);
2306
+ this.resolutionLimit(file)
2307
+ .pipe(switchMap((valid) => {
2308
+ return valid ? this.getBase64(file) : of(false);
2309
+ }))
2310
+ .subscribe((imageAsDataUrl) => {
2311
+ // console.log(imageAsDataUrl);
2312
+ event.target.value = null;
2313
+ if (!imageAsDataUrl) {
2314
+ this.dialogs.alert('core.page.error', this.translate.instant('pms.dialogs.components.scanProfile.minResolution'));
2315
+ }
2316
+ else {
2317
+ side.image = {
2318
+ imageAsDataUrl,
2319
+ };
2320
+ if (this.selectedSide.side === 'FRONT') {
2321
+ this.scanBlastData[1].disabled = false;
2322
+ }
2323
+ }
2324
+ this.cd.detectChanges();
2325
+ });
2326
+ }
2327
+ rotateBase64Image(base64data) {
2328
+ return new Observable((observer) => {
2329
+ const canvas = document.createElement('canvas');
2330
+ const ctx = canvas.getContext('2d');
2331
+ var image = new Image();
2332
+ image.src = base64data;
2333
+ image.onload = () => {
2334
+ console.log(canvas);
2335
+ canvas.width = image.height;
2336
+ canvas.height = image.width;
2337
+ if (ctx) {
2338
+ ctx.rotate((90 * Math.PI) / 180);
2339
+ ctx.translate(0, -canvas.width);
2340
+ ctx.drawImage(image, 0, 0);
2341
+ observer.next(canvas.toDataURL());
2342
+ }
2343
+ else {
2344
+ observer.error({ type: 'generic error' });
2345
+ }
2346
+ };
2347
+ image.onerror = (e) => {
2348
+ observer.error(e);
2349
+ };
2350
+ });
2351
+ }
2352
+ sendMobile() {
2353
+ this.dialogs.scanMobile({ id: 1 });
2354
+ }
2355
+ singleScanRotate(side) {
2356
+ console.log(side);
2357
+ this.rotateBase64Image(side.image.imageAsDataUrl).subscribe((data) => {
2358
+ side.image = { imageAsDataUrl: data };
2359
+ this.cd.detectChanges();
2360
+ });
2361
+ }
2362
+ singleScanRemove(side) {
2363
+ side.image = null;
2364
+ if (side.side === 'FRONT') {
2365
+ this.scanBlastData[1].disabled = true;
2366
+ }
2367
+ this.cd.detectChanges();
2368
+ }
2369
+ resolutionLimit(file) {
2370
+ const minWidth = 1280;
2371
+ const minHeight = 720;
2372
+ return new Observable((observer) => {
2373
+ const img = new Image();
2374
+ img.src = window.URL.createObjectURL(file);
2375
+ img.onload = () => {
2376
+ const width = img.naturalWidth;
2377
+ const height = img.naturalHeight;
2378
+ let valid = false;
2379
+ if (width > height) {
2380
+ valid = width >= minWidth && height >= minHeight;
2381
+ }
2382
+ else {
2383
+ valid = width >= minHeight && height >= minWidth;
2384
+ }
2385
+ observer.next(valid);
2386
+ };
2387
+ img.onerror = (error) => {
2388
+ observer.error(error);
2389
+ };
2390
+ });
2391
+ }
2392
+ getImgBase64(num) {
2393
+ return this.scanBlastData[num].image.dataUrl.split(',')[1];
2394
+ }
2395
+ scanBlastFinish() {
2396
+ if (this.type === 'mobile') {
2397
+ this.actions.emit({ data: this.scanBlastData });
2398
+ this.retake();
2399
+ return;
2400
+ }
2401
+ const loading = this.dialogs.loading();
2402
+ this.scaning = true;
2403
+ const payload = {
2404
+ AcceptTermsAndConditions: true,
2405
+ DataFields: {
2406
+ FrontImageType: 'base64',
2407
+ FrontImageCropped: false,
2408
+ BackImageType: 'base64',
2409
+ BackImageCropped: false,
2410
+ FrontImage: this.getImgBase64(0),
2411
+ BackImage: this.scanBlastData[1].image ? this.getImgBase64(1) : null,
2412
+ },
2413
+ Settings: {
2414
+ ShouldValidate: true,
2415
+ ShouldReturnDocumentImage: true,
2416
+ ShouldReturnFaceIfDetected: true,
2417
+ SkipImageSizeCheck: true,
2418
+ CanStoreImages: this.scanProvider.canStoreImages,
2419
+ },
2420
+ // CallBackUrl: 'http://demo:5000/report/extracted/',
2421
+ };
2422
+ if (!this.scanBlastData[1].image) {
2423
+ payload.Settings.IgnoreBackImage = true;
2424
+ }
2425
+ this.scanProvider.blastPost(payload).subscribe((data) => {
2426
+ const results = data.Data;
2427
+ loading.close();
2428
+ this.documentTypeSelected = true;
2429
+ this.scaning = false;
2430
+ if (results && data.Metadata.length > 0) {
2431
+ if (data.ImageData?.Documents) {
2432
+ const { Documents } = data.ImageData;
2433
+ this.images = Documents.map((image, i) => {
2434
+ return { data: 'data:image/jpeg;base64,' + Documents[i] };
2435
+ });
2436
+ }
2437
+ this.result = this.scanProvider.parseBlast(results);
2438
+ console.log('RES', this.result);
2439
+ this.model = this.result.model;
2440
+ if (data.ImageData?.FaceImage) {
2441
+ this.model._avatar =
2442
+ 'data:image/jpeg;base64,' + data.ImageData?.FaceImage;
2443
+ }
2444
+ console.log('MODEL', this.model);
2445
+ }
2446
+ else {
2447
+ console.log('ERROR');
2448
+ // this.scanSide = 0;
2449
+ this.error = true;
2450
+ this.preview = true;
2451
+ // this.documentTypeSelected = false;
2452
+ // this.retry();
2453
+ }
2454
+ this.cd.detectChanges();
2455
+ }, (err) => {
2456
+ loading.close();
2457
+ // this.scanSide = 0;
2458
+ this.error = true;
2459
+ this.preview = true;
2460
+ this.documentTypeSelected = true;
2461
+ this.scaning = false;
2462
+ });
2463
+ }
2464
+ cameraOff(ev) {
2465
+ this.cameraReady = false;
2466
+ this.cd.detectChanges();
2467
+ }
2468
+ continue() {
2469
+ if (this.scanProvider.enableVerification) {
2470
+ const loading = this.dialogs.loading();
2471
+ console.log(this.data.avatar);
2472
+ this.scanProvider
2473
+ .stateless(this.data.avatar.split(',')[1], this.webcamImage?.imageAsDataUrl.split(',')[1])
2474
+ .subscribe((resp) => {
2475
+ loading.close();
2476
+ if (resp.Data?.Verified) {
2477
+ this.dialogRef?.close(this.webcamImage);
2478
+ }
2479
+ else {
2480
+ this.dialogs.alert('Verification failed!', "We can't verify that your selfie is same as image on document.");
2481
+ }
2482
+ console.log(resp);
2483
+ }, (err) => {
2484
+ loading.close();
2485
+ this.dialogRef?.close(this.webcamImage);
2486
+ });
2487
+ }
2488
+ else {
2489
+ this.dialogRef?.close(this.webcamImage);
2490
+ }
2491
+ // this.dialogRef.close(this.webcamImage)
2492
+ }
2493
+ retry() {
2494
+ this.preview = false;
2495
+ this.result = false;
2496
+ if (this.error) {
2497
+ this.documentTypeSelected = false;
2498
+ this.scanBlastData.forEach((element) => {
2499
+ element.image = null;
2500
+ });
2501
+ }
2502
+ this.error = false;
2503
+ }
2504
+ triggerSnapshot() {
2505
+ this.trigger.next(0);
2506
+ }
2507
+ scan() {
2508
+ console.log('SCAN');
2509
+ this.triggerSnapshot();
2510
+ this.scanDatas[0] = true;
2511
+ }
2512
+ retake() {
2513
+ this.preview = false;
2514
+ this.error = false;
2515
+ this.result = false;
2516
+ this.scanSide = 0;
2517
+ this.scanDatas = [];
2518
+ this.scaning = false;
2519
+ this.images = [];
2520
+ this.documentTypeSelected = false;
2521
+ this.scanBlastData.forEach((m) => {
2522
+ m.image = null;
2523
+ });
2524
+ this.cd.detectChanges();
2525
+ }
2526
+ use() { }
2527
+ selfie() { }
2528
+ }
2529
+ ScanSelfieComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanSelfieComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: ScanProvider }, { token: DialogsCoreProvider }, { token: i4$1.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
2530
+ ScanSelfieComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScanSelfieComponent, selector: "app-scan-selfie", inputs: { type: "type" }, outputs: { actions: "actions" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "wraper", first: true, predicate: ["wraper"], descendants: true }], ngImport: i0, template: "<header class=\"page-header\" fxLayout=\"row\">\n <div class=\"title\" ngClass.lt-sm=\"title-small\">Selfie</div>\n\n <span fxFlex></span>\n <ng-container\n *ngIf=\"\n documentTypeSelected &&\n !result &&\n !error &&\n multipleWebcamsAvailable &&\n !preview\n \"\n >\n <div class=\"separator\"></div>\n <div style=\"padding: 0px 16px\">\n <div fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <mat-form-field\n style=\"font-size: 14px; width: 200px; margin-top: 8px\"\n class=\"w-200 mr-16 mt-8\"\n >\n <mat-label> Camera </mat-label>\n <mat-select\n (selectionChange)=\"selectCamera($event)\"\n [(ngModel)]=\"deviceId\"\n >\n <mat-option\n *ngFor=\"let device of mediaDevices\"\n [value]=\"device.deviceId\"\n >\n {{ device.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </ng-container>\n\n <ng-container>\n <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n </ng-container>\n <!-- <ng-container *ngIf=\"type === 'desktop'\">\n <div class=\"separator\"></div>\n <button mat-button (click)=\"sendMobile()\">\n <mat-icon>tablet_mac</mat-icon>\n </button>\n\n <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n </ng-container> -->\n</header>\n\n<div *ngIf=\"!result\" fxFlex fxLayout=\"column\">\n <div fxFlex #wraper class=\"wraper\" fxLayout=\"row\">\n <div\n style=\"\n position: absolute;\n top: 0px;\n left: 0px;\n right: 0px;\n bottom: 0px;\n z-index: 20;\n background-color: whitesmoke;\n \"\n *ngIf=\"!cameraReady && !preview\"\n >\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <ng-container *ngIf=\"!error\">\n <!-- <div\n class=\"rectangle\"\n [ngStyle]=\"{\n 'width.px': videoHeight * 0.75 * 1.588,\n 'height.px': videoHeight * 0.75\n }\"\n ></div>\n <svg\n *ngIf=\"videoWidth\"\n style=\"position: absolute; left: 0px; top: 0px\"\n width=\"0\"\n height=\"0\"\n >\n <defs>\n <clipPath id=\"myClip\">\n <rect\n stroke-width=\"6\"\n stroke-color=\"red\"\n [attr.x]=\"(videoWidth - videoHeight * 0.75 * 1.588) / 2\"\n [attr.y]=\"(videoHeight * 0.25) / 2\"\n [attr.width]=\"videoHeight * 0.75 * 1.588\"\n [attr.height]=\"videoHeight * 0.75\"\n rx=\"25\"\n />\n </clipPath>\n </defs>\n </svg> -->\n\n <app-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n [imageQuality]=\"1\"\n #webcam\n fxFlex\n [trigger]=\"trigger\"\n (imageCapture)=\"handleImage($event)\"\n [allowCameraSwitch]=\"allowCameraSwitch\"\n [videoOptions]=\"videoOptions\"\n [switchCamera]=\"nextWebcamObservable\"\n (cameraSwitched)=\"cameraWasSwitched($event)\"\n (initError)=\"handleInitError($event)\"\n type=\"selfie\"\n [width]=\"width\"\n [height]=\"height\"\n (destroyed)=\"cameraOff($event)\"\n >\n </app-webcam>\n </ng-container>\n <div\n fxLayout=\"row\"\n fxFlex\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"z-index: 20; position: absolute; width: 100%; height: 100%\"\n >\n <div\n class=\"scanPreview\"\n fxFlex\n fxLayout=\"column\"\n *ngIf=\"!error && !scaning\"\n >\n <div\n fxFlex\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer fxLayout=\"row\" class=\"p-8\">\n <button\n [disabled]=\"!cameraReady\"\n class=\"w-100-p\"\n *ngIf=\"!preview\"\n mat-raised-button\n (click)=\"scan()\"\n >\n <ng-container>\n TAKE SELFIE\n </ng-container>\n </button>\n\n <div\n class=\"w-100-p\"\n *ngIf=\"preview\"\n fxLayout=\"row\"\n fxLayoutAlign=\"start center\"\n fxFlex\n >\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n RETRY\n </button>\n\n <button\n [disabled]=\"error\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n CONTINUE\n\n </button>\n </div>\n </footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5}.element{margin-bottom:8px}.element label{font-size:14px}.element div{font-size:18px}.wraper{position:relative;overflow:hidden}h3{color:#459ae5;font-size:16px}.preview{width:100%;border-radius:1%}.documentTypeWraper{width:400px}.documentTypeWraper .label{font-size:14px;margin-bottom:20px}.documentTypeWraper button{box-shadow:none}.overPane{position:absolute;width:100%;height:100%;top:0;left:0}.overPane app-webcam{clip-path:url(#myClip)}.subhead{height:55px;padding-top:8px}.rectangle{z-index:2;position:absolute;top:50%;left:50%;width:85.6mm;height:53.98mm;transform:translate(-50%,-50%);box-sizing:border-box;border:2px dashed #459be5;border-radius:3mm}.mask{z-index:1;position:absolute;width:100%;height:100%;background-position:center center;background-size:380mm;background-repeat:no-repeat}.label{font-size:11px;margin-top:4px}footer button{box-shadow:none!important;height:45px;min-height:45px;border:1px solid rgba(0,0,0,.12);text-transform:uppercase}h4{font-size:16px}.images label{font-size:11px;color:#888;line-height:20px}.images .title{padding:8px 0;font-weight:600}.images img{margin-bottom:16px}.error .title{font-size:22px}.error ul{font-size:18px}.photo{width:120px;height:120px;overflow:hidden}.signature{width:200px}mat-card{box-shadow:none!important}.scanBlastWraper button{text-transform:uppercase}.scanBlastWraper.mobile mat-card{margin:4px!important}.scanBlastWraper.mobile .description{font-size:12px;flex-direction:row!important}.scanBlastWraper.mobile .description .imgWrap{padding:0!important}.scanBlastWraper.mobile .description .btnActions{position:absolute;right:0}.scanBlastWraper.mobile .description button{font-size:11px!important;margin:0!important;position:absolute;right:16px}.scanBlastWraper.mobile .description button.rotateButton{top:58px}.scanBlastWraper.mobile .description button.remButton{top:8px}.scanBlastWraper.mobile .description button mat-icon{margin:0!important}.scanBlastWraper.mobile .description button div.label{display:none}.mobile .scanBlast button{font-size:11px!important}.scanBlast{display:flex;flex-direction:row;flex:1;padding:0 4px}.scanBlast mat-card{padding:0;box-shadow:none;margin:8px 4px;flex:1}.scanBlast mat-card .head{display:flex;flex-direction:row;align-items:center;justify-items:center;border-bottom:1px solid rgba(0,0,0,.12);height:60px;padding:8px}.scanBlast mat-card .head.small{height:30px!important;padding:4px 8px!important}.scanBlast mat-card .head.small .title{font-size:12px!important;margin-left:4px!important}.scanBlast mat-card .head button{max-width:120px;height:40px;box-shadow:none;border:1px solid rgba(0,0,0,.12)}.scanBlast mat-card .head .title{margin-left:16px;color:#459ae5;font-size:16px}.scanBlast mat-card .content{margin:8px;flex:1}.scanBlast mat-card .description{text-align:center;color:#888;font-size:14px}.scanBlast mat-card .actions{background-color:#e9e9e9;display:flex;flex-direction:row}.scanBlast mat-card .actions .mat-button-disabled{background-color:#fff!important}.scanBlast mat-card .actions button{box-shadow:none;width:50%;margin:8px;height:40px;font-size:12px}.scanBlast mat-card .actions button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder{flex:1;border-radius:6px;display:flex;flex-direction:column}.scanBlast mat-card .previewPlaceholder .description{display:flex;flex:1;flex-direction:column;justify-content:center}.scanBlast mat-card .previewPlaceholder button{box-shadow:none;margin-top:8px;height:40px;font-size:12px}.scanBlast mat-card .previewPlaceholder button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder .imgWrap{flex-direction:column;flex:1;padding:8px;background-color:#f5f5f5;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap img{width:100%;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap .image{background-position:center;background-repeat:no-repeat;background-size:contain}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}.summary label{font-size:12px;color:#888;margin-top:2px}.summary .name{font-size:14px}.selfieContainer{display:flex;flex-direction:column;margin-bottom:20px}.selfieContainer button{box-shadow:none;border:1px solid rgba(0,0,0,.12)}.selfieContainer .selfie{margin:8px auto;width:120px;height:120px;border-radius:60px;border:1px solid rgba(0,0,0,.12)}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"], dependencies: [{ kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "component", type: i7.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i8.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i1$4.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: WebcamComponent, selector: "app-webcam", inputs: ["imageHandler", "id", "type", "width", "height", "videoOptions", "allowCameraSwitch", "mirrorImage", "captureImageData", "imageType", "imageQuality", "trigger", "switchCamera"], outputs: ["imageCapture", "initError", "imageClick", "cameraSwitched", "videoReady", "destroyed"] }, { kind: "directive", type: i4.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i4.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i4.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i5$1.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanSelfieComponent, decorators: [{
2532
+ type: Component,
2533
+ args: [{ selector: 'app-scan-selfie', changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"page-header\" fxLayout=\"row\">\n <div class=\"title\" ngClass.lt-sm=\"title-small\">Selfie</div>\n\n <span fxFlex></span>\n <ng-container\n *ngIf=\"\n documentTypeSelected &&\n !result &&\n !error &&\n multipleWebcamsAvailable &&\n !preview\n \"\n >\n <div class=\"separator\"></div>\n <div style=\"padding: 0px 16px\">\n <div fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <mat-form-field\n style=\"font-size: 14px; width: 200px; margin-top: 8px\"\n class=\"w-200 mr-16 mt-8\"\n >\n <mat-label> Camera </mat-label>\n <mat-select\n (selectionChange)=\"selectCamera($event)\"\n [(ngModel)]=\"deviceId\"\n >\n <mat-option\n *ngFor=\"let device of mediaDevices\"\n [value]=\"device.deviceId\"\n >\n {{ device.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </ng-container>\n\n <ng-container>\n <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n </ng-container>\n <!-- <ng-container *ngIf=\"type === 'desktop'\">\n <div class=\"separator\"></div>\n <button mat-button (click)=\"sendMobile()\">\n <mat-icon>tablet_mac</mat-icon>\n </button>\n\n <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n </ng-container> -->\n</header>\n\n<div *ngIf=\"!result\" fxFlex fxLayout=\"column\">\n <div fxFlex #wraper class=\"wraper\" fxLayout=\"row\">\n <div\n style=\"\n position: absolute;\n top: 0px;\n left: 0px;\n right: 0px;\n bottom: 0px;\n z-index: 20;\n background-color: whitesmoke;\n \"\n *ngIf=\"!cameraReady && !preview\"\n >\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <ng-container *ngIf=\"!error\">\n <!-- <div\n class=\"rectangle\"\n [ngStyle]=\"{\n 'width.px': videoHeight * 0.75 * 1.588,\n 'height.px': videoHeight * 0.75\n }\"\n ></div>\n <svg\n *ngIf=\"videoWidth\"\n style=\"position: absolute; left: 0px; top: 0px\"\n width=\"0\"\n height=\"0\"\n >\n <defs>\n <clipPath id=\"myClip\">\n <rect\n stroke-width=\"6\"\n stroke-color=\"red\"\n [attr.x]=\"(videoWidth - videoHeight * 0.75 * 1.588) / 2\"\n [attr.y]=\"(videoHeight * 0.25) / 2\"\n [attr.width]=\"videoHeight * 0.75 * 1.588\"\n [attr.height]=\"videoHeight * 0.75\"\n rx=\"25\"\n />\n </clipPath>\n </defs>\n </svg> -->\n\n <app-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n [imageQuality]=\"1\"\n #webcam\n fxFlex\n [trigger]=\"trigger\"\n (imageCapture)=\"handleImage($event)\"\n [allowCameraSwitch]=\"allowCameraSwitch\"\n [videoOptions]=\"videoOptions\"\n [switchCamera]=\"nextWebcamObservable\"\n (cameraSwitched)=\"cameraWasSwitched($event)\"\n (initError)=\"handleInitError($event)\"\n type=\"selfie\"\n [width]=\"width\"\n [height]=\"height\"\n (destroyed)=\"cameraOff($event)\"\n >\n </app-webcam>\n </ng-container>\n <div\n fxLayout=\"row\"\n fxFlex\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"z-index: 20; position: absolute; width: 100%; height: 100%\"\n >\n <div\n class=\"scanPreview\"\n fxFlex\n fxLayout=\"column\"\n *ngIf=\"!error && !scaning\"\n >\n <div\n fxFlex\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer fxLayout=\"row\" class=\"p-8\">\n <button\n [disabled]=\"!cameraReady\"\n class=\"w-100-p\"\n *ngIf=\"!preview\"\n mat-raised-button\n (click)=\"scan()\"\n >\n <ng-container>\n TAKE SELFIE\n </ng-container>\n </button>\n\n <div\n class=\"w-100-p\"\n *ngIf=\"preview\"\n fxLayout=\"row\"\n fxLayoutAlign=\"start center\"\n fxFlex\n >\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n RETRY\n </button>\n\n <button\n [disabled]=\"error\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n CONTINUE\n\n </button>\n </div>\n </footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5}.element{margin-bottom:8px}.element label{font-size:14px}.element div{font-size:18px}.wraper{position:relative;overflow:hidden}h3{color:#459ae5;font-size:16px}.preview{width:100%;border-radius:1%}.documentTypeWraper{width:400px}.documentTypeWraper .label{font-size:14px;margin-bottom:20px}.documentTypeWraper button{box-shadow:none}.overPane{position:absolute;width:100%;height:100%;top:0;left:0}.overPane app-webcam{clip-path:url(#myClip)}.subhead{height:55px;padding-top:8px}.rectangle{z-index:2;position:absolute;top:50%;left:50%;width:85.6mm;height:53.98mm;transform:translate(-50%,-50%);box-sizing:border-box;border:2px dashed #459be5;border-radius:3mm}.mask{z-index:1;position:absolute;width:100%;height:100%;background-position:center center;background-size:380mm;background-repeat:no-repeat}.label{font-size:11px;margin-top:4px}footer button{box-shadow:none!important;height:45px;min-height:45px;border:1px solid rgba(0,0,0,.12);text-transform:uppercase}h4{font-size:16px}.images label{font-size:11px;color:#888;line-height:20px}.images .title{padding:8px 0;font-weight:600}.images img{margin-bottom:16px}.error .title{font-size:22px}.error ul{font-size:18px}.photo{width:120px;height:120px;overflow:hidden}.signature{width:200px}mat-card{box-shadow:none!important}.scanBlastWraper button{text-transform:uppercase}.scanBlastWraper.mobile mat-card{margin:4px!important}.scanBlastWraper.mobile .description{font-size:12px;flex-direction:row!important}.scanBlastWraper.mobile .description .imgWrap{padding:0!important}.scanBlastWraper.mobile .description .btnActions{position:absolute;right:0}.scanBlastWraper.mobile .description button{font-size:11px!important;margin:0!important;position:absolute;right:16px}.scanBlastWraper.mobile .description button.rotateButton{top:58px}.scanBlastWraper.mobile .description button.remButton{top:8px}.scanBlastWraper.mobile .description button mat-icon{margin:0!important}.scanBlastWraper.mobile .description button div.label{display:none}.mobile .scanBlast button{font-size:11px!important}.scanBlast{display:flex;flex-direction:row;flex:1;padding:0 4px}.scanBlast mat-card{padding:0;box-shadow:none;margin:8px 4px;flex:1}.scanBlast mat-card .head{display:flex;flex-direction:row;align-items:center;justify-items:center;border-bottom:1px solid rgba(0,0,0,.12);height:60px;padding:8px}.scanBlast mat-card .head.small{height:30px!important;padding:4px 8px!important}.scanBlast mat-card .head.small .title{font-size:12px!important;margin-left:4px!important}.scanBlast mat-card .head button{max-width:120px;height:40px;box-shadow:none;border:1px solid rgba(0,0,0,.12)}.scanBlast mat-card .head .title{margin-left:16px;color:#459ae5;font-size:16px}.scanBlast mat-card .content{margin:8px;flex:1}.scanBlast mat-card .description{text-align:center;color:#888;font-size:14px}.scanBlast mat-card .actions{background-color:#e9e9e9;display:flex;flex-direction:row}.scanBlast mat-card .actions .mat-button-disabled{background-color:#fff!important}.scanBlast mat-card .actions button{box-shadow:none;width:50%;margin:8px;height:40px;font-size:12px}.scanBlast mat-card .actions button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder{flex:1;border-radius:6px;display:flex;flex-direction:column}.scanBlast mat-card .previewPlaceholder .description{display:flex;flex:1;flex-direction:column;justify-content:center}.scanBlast mat-card .previewPlaceholder button{box-shadow:none;margin-top:8px;height:40px;font-size:12px}.scanBlast mat-card .previewPlaceholder button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder .imgWrap{flex-direction:column;flex:1;padding:8px;background-color:#f5f5f5;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap img{width:100%;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap .image{background-position:center;background-repeat:no-repeat;background-size:contain}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}.summary label{font-size:12px;color:#888;margin-top:2px}.summary .name{font-size:14px}.selfieContainer{display:flex;flex-direction:column;margin-bottom:20px}.selfieContainer button{box-shadow:none;border:1px solid rgba(0,0,0,.12)}.selfieContainer .selfie{margin:8px auto;width:120px;height:120px;border-radius:60px;border:1px solid rgba(0,0,0,.12)}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"] }]
2534
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: ScanProvider }, { type: DialogsCoreProvider }, { type: i4$1.TranslateService }]; }, propDecorators: { type: [{
2535
+ type: Input
2536
+ }], actions: [{
2537
+ type: Output
2538
+ }], wraper: [{
2539
+ type: ViewChild,
2540
+ args: ['wraper']
2541
+ }], onResize: [{
2542
+ type: HostListener,
2543
+ args: ['window:resize', ['$event']]
2544
+ }] } });
2545
+
2546
+ class DialogsCoreProvider {
2547
+ constructor(matDialog) {
2548
+ this.matDialog = matDialog;
2549
+ this.components = {
2550
+ ScanProfile: { component: ScanProfileComponent },
2551
+ Loading: { component: LoadingComponent },
2552
+ ConfirmComponent: { component: ConfirmComponent },
2553
+ ScanMobileComponent: { component: ScanMobileComponent },
2554
+ ScanSelfie: { component: ScanSelfieComponent },
2555
+ };
2556
+ this.blank = BlankComponent;
2557
+ }
2558
+ getComponent(name) {
2559
+ if (!this.components[name]) {
2560
+ console.warn('Component missing', name, this.components);
2561
+ }
2562
+ return this.components[name].component;
2563
+ }
2564
+ open(config, withComponent = true) {
2565
+ // console.log(config);
2566
+ const panelClass = config.panelClass ? config.panelClass : config.name;
2567
+ const component = this.getComponent(config.name);
2568
+ const dialogRef = this.matDialog.open(this.blank, {
2569
+ panelClass,
2570
+ data: {
2571
+ data: config.data,
2572
+ withComponent,
2573
+ component,
2574
+ },
2575
+ autoFocus: false,
2576
+ width: config.width || '',
2577
+ height: config.height || '',
2578
+ maxWidth: config.maxWidth || '',
2579
+ minWidth: config.minWidth || '',
2580
+ maxHeight: config.maxHeight || '',
2581
+ minHeight: config.minHeight || '',
2582
+ position: config.position || {},
2583
+ hasBackdrop: config.hasBackdrop === undefined ? true : config.hasBackdrop,
2584
+ disableClose: config.disableClose === undefined ? true : config.disableClose,
2585
+ });
2586
+ return dialogRef;
2587
+ }
2588
+ scanProfile(data) {
2589
+ return this.open({
2590
+ name: 'ScanProfile',
2591
+ panelClass: 'ScanProfileComponent',
2592
+ data,
2593
+ });
2594
+ }
2595
+ // Generic loading dialog
2596
+ loading(title = '') {
2597
+ return this.open({
2598
+ name: 'Loading',
2599
+ data: { title },
2600
+ });
2601
+ }
2602
+ alert(title, text) {
2603
+ return this.open({
2604
+ name: 'ConfirmComponent',
2605
+ maxWidth: '600px',
2606
+ panelClass: 'DialogNoPadding',
2607
+ minWidth: '440px',
2608
+ data: { title, text, alert: true },
2609
+ });
2610
+ }
2611
+ scanMobile(data) {
2612
+ return this.open({
2613
+ name: 'ScanMobileComponent',
2614
+ maxWidth: '600px',
2615
+ panelClass: 'DialogNoPadding',
2616
+ minWidth: '440px',
2617
+ data,
2618
+ });
2619
+ }
2620
+ scanSelfie(data) {
2621
+ return this.open({
2622
+ name: 'ScanSelfie',
2623
+ panelClass: 'ScanProfileComponent',
2624
+ data,
2625
+ });
2626
+ }
2627
+ }
2628
+ DialogsCoreProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogsCoreProvider, deps: [{ token: i1$3.MatDialog }], target: i0.ɵɵFactoryTarget.Injectable });
2629
+ DialogsCoreProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogsCoreProvider, providedIn: 'root' });
2630
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogsCoreProvider, decorators: [{
2631
+ type: Injectable,
2632
+ args: [{
2633
+ providedIn: 'root',
2634
+ }]
2635
+ }], ctorParameters: function () { return [{ type: i1$3.MatDialog }]; } });
2636
+
2637
+ class TranslationProvider {
2638
+ constructor(translate) {
2639
+ this.translate = translate;
2640
+ }
2641
+ forms(item, namespace = null) {
2642
+ if (item.fieldGroup) {
2643
+ item.fieldGroup = item.fieldGroup.map((field) => this.forms(field));
2644
+ }
2645
+ const prefix = namespace ? namespace + '.' : '';
2646
+ if (item.templateOptions &&
2647
+ (item.templateOptions.label ||
2648
+ item.templateOptions.placeholder ||
2649
+ item.templateOptions.options)) {
2650
+ if (!item.expressionProperties) {
2651
+ item.expressionProperties = {};
2652
+ }
2653
+ if (item.templateOptions.label) {
2654
+ item.expressionProperties['templateOptions.label'] =
2655
+ this.translate.stream(prefix + item.templateOptions.label);
2656
+ }
2657
+ if (item.templateOptions.placeholder) {
2658
+ item.expressionProperties['templateOptions.placeholder'] =
2659
+ this.translate.stream(prefix + item.templateOptions.placeholder);
2660
+ }
2661
+ if (Array.isArray(item.templateOptions.options)) {
2662
+ item.expressionProperties['templateOptions.options'] =
2663
+ item.templateOptions.options.map((m) => {
2664
+ // console.log(m);
2665
+ if (m.label) {
2666
+ m.label = this.translate.instant(prefix + m.label);
2667
+ }
2668
+ return m;
2669
+ });
2670
+ }
2671
+ }
2672
+ return item;
2673
+ }
2674
+ }
2675
+ TranslationProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TranslationProvider, deps: [{ token: i4$1.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable });
2676
+ TranslationProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TranslationProvider, providedIn: 'root' });
2677
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TranslationProvider, decorators: [{
2678
+ type: Injectable,
2679
+ args: [{
2680
+ providedIn: 'root',
2681
+ }]
2682
+ }], ctorParameters: function () { return [{ type: i4$1.TranslateService }]; } });
2683
+
2684
+ class ScanFieldsProvider {
2685
+ constructor(translate, provider) {
2686
+ this.translate = translate;
2687
+ this.provider = provider;
2688
+ }
2689
+ update() {
2690
+ return [
2691
+ {
2692
+ fieldGroupClassName: 'px-16',
2693
+ fieldGroup: [
2694
+ {
2695
+ wrappers: [],
2696
+ type: 'checkbox',
2697
+ key: 'profile',
2698
+ class: 'checkbox ',
2699
+ defaultValue: true,
2700
+ templateOptions: {
2701
+ label: 'form.scan.document.update.profile',
2702
+ },
2703
+ },
2704
+ {
2705
+ wrappers: [],
2706
+ type: 'checkbox',
2707
+ class: 'checkbox ',
2708
+ key: 'document',
2709
+ defaultValue: true,
2710
+ templateOptions: {
2711
+ label: 'form.scan.document.update.document',
2712
+ },
2713
+ },
2714
+ {
2715
+ wrappers: [],
2716
+ type: 'checkbox',
2717
+ class: 'checkbox ',
2718
+ key: 'attachment',
2719
+ defaultValue: true,
2720
+ templateOptions: {
2721
+ label: 'form.scan.document.update.attachment',
2722
+ },
2723
+ },
2724
+ ].map((item) => this.translate.forms(item)),
2725
+ },
2726
+ ];
2727
+ }
2728
+ document() {
2729
+ return [
2730
+ {
2731
+ className: 'w-200-p',
2732
+ fieldGroupClassName: 'form-flex-row border-card profile-details',
2733
+ fieldGroup: [
2734
+ {
2735
+ className: 'card-group',
2736
+ fieldGroupClassName: 'wraper',
2737
+ fieldGroup: [
2738
+ {
2739
+ type: 'title',
2740
+ templateOptions: {
2741
+ label: 'form.scan.document.guestDetailsTitle',
2742
+ },
2743
+ },
2744
+ // {
2745
+ // type: 'profile-image',
2746
+ // key: '_avatar',
2747
+ // templateOptions: {
2748
+ // label: 'form.scan.document.firstName',
2749
+ // },
2750
+ // },
2751
+ {
2752
+ type: 'input',
2753
+ key: 'firstName',
2754
+ className: 'small',
2755
+ templateOptions: {
2756
+ label: 'form.scan.document.firstName',
2757
+ required: true,
2758
+ },
2759
+ },
2760
+ {
2761
+ type: 'input',
2762
+ key: 'lastName',
2763
+ className: 'small',
2764
+ templateOptions: {
2765
+ label: 'form.scan.document.lastName',
2766
+ required: true,
2767
+ },
2768
+ },
2769
+ {
2770
+ className: 'small',
2771
+ key: 'secondName',
2772
+ type: 'input',
2773
+ templateOptions: {
2774
+ color: 'accent',
2775
+ label: 'form.scan.document.secondLastName',
2776
+ },
2777
+ hideExpression: 'model.hideSecondLastName',
2778
+ },
2779
+ {
2780
+ type: 'input',
2781
+ key: 'middleName',
2782
+ className: 'small',
2783
+ templateOptions: {
2784
+ label: 'form.scan.document.middleName',
2785
+ },
2786
+ },
2787
+ {
2788
+ className: '',
2789
+ fieldGroupClassName: 'form-flex-row space-between',
2790
+ fieldGroup: [
2791
+ {
2792
+ type: 'datepicker',
2793
+ key: 'birthDate',
2794
+ className: 'w-100-p small mr-8',
2795
+ templateOptions: {
2796
+ label: 'form.scan.document.birthDate',
2797
+ },
2798
+ },
2799
+ {
2800
+ type: 'select',
2801
+ key: 'gender',
2802
+ className: 'w-100-p small ml-8',
2803
+ templateOptions: {
2804
+ label: 'form.scan.document.gender',
2805
+ options: [
2806
+ { value: 'MALE', label: 'MALE' },
2807
+ { value: 'FEMALE', label: 'FEMALE' },
2808
+ { value: 'NA', label: 'N/A' },
2809
+ ],
2810
+ },
2811
+ },
2812
+ ],
2813
+ },
2814
+ {
2815
+ type: 'input',
2816
+ key: 'birthPlace',
2817
+ className: 'small',
2818
+ templateOptions: {
2819
+ label: 'form.scan.document.birthPlace',
2820
+ },
2821
+ },
2822
+ {
2823
+ type: 'select',
2824
+ key: 'birthCountry',
2825
+ className: 'small',
2826
+ templateOptions: {
2827
+ label: 'form.scan.document.birthCountry',
2828
+ options: this.provider.countries(),
2829
+ },
2830
+ },
2831
+ {
2832
+ className: 'small',
2833
+ key: 'nationality',
2834
+ type: 'select',
2835
+ templateOptions: {
2836
+ label: 'form.scan.document.nationality',
2837
+ // appearance: 'outline',
2838
+ // options: this.profileProvider.nationalities(),
2839
+ options: this.provider.countries(),
2840
+ },
2841
+ },
2842
+ ],
2843
+ },
2844
+ {
2845
+ className: 'card-group',
2846
+ fieldGroupClassName: 'wraper',
2847
+ fieldGroup: [
2848
+ {
2849
+ type: 'title',
2850
+ templateOptions: {
2851
+ label: 'form.scan.document.documentTitle',
2852
+ },
2853
+ },
2854
+ {
2855
+ type: 'select',
2856
+ key: 'documentType',
2857
+ templateOptions: {
2858
+ label: 'form.scan.document.documentType',
2859
+ options: [
2860
+ { value: 'ID', label: 'Identity Document' },
2861
+ { value: 'PASS', label: 'Passport' },
2862
+ { value: 'DL', label: 'Driver Licence' },
2863
+ ],
2864
+ // valueProp: 'id',
2865
+ // labelProp: 'value',
2866
+ required: true,
2867
+ },
2868
+ },
2869
+ {
2870
+ type: 'input',
2871
+ key: 'documentNumber',
2872
+ templateOptions: {
2873
+ label: 'form.scan.document.documentNumber',
2874
+ required: true,
2875
+ },
2876
+ },
2877
+ {
2878
+ className: '',
2879
+ fieldGroupClassName: 'form-flex-row space-between',
2880
+ fieldGroup: [
2881
+ {
2882
+ type: 'datepicker',
2883
+ key: 'issueDate',
2884
+ className: 'small mr-8',
2885
+ templateOptions: {
2886
+ label: 'form.scan.document.issueDate',
2887
+ },
2888
+ },
2889
+ {
2890
+ type: 'datepicker',
2891
+ key: 'expirationDate',
2892
+ className: 'small ml-8',
2893
+ templateOptions: {
2894
+ label: 'form.scan.document.expirationDate',
2895
+ },
2896
+ },
2897
+ ],
2898
+ },
2899
+ {
2900
+ type: 'select',
2901
+ key: 'issueStateCode',
2902
+ templateOptions: {
2903
+ label: 'form.scan.document.issuingStateCode',
2904
+ options: this.provider.countries(),
2905
+ },
2906
+ },
2907
+ {
2908
+ type: 'input',
2909
+ key: 'issuingPlace',
2910
+ templateOptions: {
2911
+ label: 'form.scan.document.issuingPlace',
2912
+ required: false,
2913
+ },
2914
+ },
2915
+ {
2916
+ className: '',
2917
+ fieldGroupClassName: 'form-flex-row space-between',
2918
+ fieldGroup: [
2919
+ {
2920
+ type: 'title',
2921
+ templateOptions: {
2922
+ label: 'form.scan.document.addressTitle',
2923
+ badge: 'communications',
2924
+ },
2925
+ },
2926
+ ].map((item) => this.translate.forms(item)),
2927
+ },
2928
+ // {
2929
+ // className: 'small',
2930
+ // key: 'typeID',
2931
+ // type: 'select',
2932
+ // templateOptions: {
2933
+ // label: 'form.profile.address.type',
2934
+ // required: true,
2935
+ // // options: this.profileProvider.addressTypes(),
2936
+ // expressionProperties: {
2937
+ // 'templateOptions.disabled': (model: any) =>
2938
+ // model.newAddress,
2939
+ // },
2940
+ // onClearValue: (field: FormlyFieldConfig) => {
2941
+ // field.formControl?.setValue('');
2942
+ // field.model.typeID = 0;
2943
+ // },
2944
+ // onSetNewValue: (field: FormlyFieldConfig, optObj: any) => {
2945
+ // field.formControl?.setValue(optObj.value);
2946
+ // field.model.typeID = optObj.value;
2947
+ // },
2948
+ // },
2949
+ // expressionProperties: {
2950
+ // 'templateOptions.disabled': (model: any) => !model.newAddress,
2951
+ // },
2952
+ // },
2953
+ {
2954
+ className: 'small',
2955
+ key: 'country',
2956
+ type: 'select',
2957
+ templateOptions: {
2958
+ required: true,
2959
+ label: 'form.profile.address.country',
2960
+ options: this.provider.countries(),
2961
+ },
2962
+ // expressionProperties: {
2963
+ // 'templateOptions.disabled': (model: any) => !model.newAddress,
2964
+ // },
2965
+ hooks: {
2966
+ onInit: (model) => {
2967
+ console.log(model);
2968
+ },
2969
+ },
2970
+ },
2971
+ {
2972
+ className: '',
2973
+ fieldGroupClassName: 'form-flex-row space-between',
2974
+ fieldGroup: [
2975
+ {
2976
+ className: 'mr-8 w-100-p',
2977
+ key: 'zip',
2978
+ type: 'input',
2979
+ templateOptions: {
2980
+ label: 'form.profile.address.zip',
2981
+ labelProp: (item) => {
2982
+ return `${item.zip} (${item.city})`;
2983
+ },
2984
+ set: (field, option) => {
2985
+ // console.log(option, field);
2986
+ field.formControl.setValue(option.value.zip);
2987
+ // set CITY
2988
+ field.form.get('city').setValue(option.value.city);
2989
+ },
2990
+ filter: (key, field) => {
2991
+ // return this.profileProvider.zipCodes({
2992
+ // countryCode: field.form.get('country').value,
2993
+ // zip: key,
2994
+ // });
2995
+ },
2996
+ },
2997
+ // expressionProperties: {
2998
+ // 'templateOptions.disabled': (model: any) =>
2999
+ // !model.newAddress,
3000
+ // },
3001
+ },
3002
+ {
3003
+ className: 'small ml-8',
3004
+ key: 'city',
3005
+ type: 'input',
3006
+ templateOptions: {
3007
+ label: 'form.profile.address.city',
3008
+ },
3009
+ // expressionProperties: {
3010
+ // 'templateOptions.disabled': (model: any) =>
3011
+ // !model.newAddress,
3012
+ // },
3013
+ },
3014
+ ].map((item) => this.translate.forms(item)),
3015
+ },
3016
+ // {
3017
+ // className: 'small',
3018
+ // key: 'state',
3019
+ // type: 'input',
3020
+ // templateOptions: {
3021
+ // label: 'form.profile.address.state',
3022
+ // },
3023
+ // // expressionProperties: {
3024
+ // // 'templateOptions.disabled': (model: any) => !model.newAddress,
3025
+ // // },
3026
+ // },
3027
+ // {
3028
+ // className: 'small',
3029
+ // key: 'countryStateID',
3030
+ // type: 'select',
3031
+ // templateOptions: {
3032
+ // label: 'form.profile.address.regionalStatistics',
3033
+ // options: this.provider.countries(),
3034
+ // },
3035
+ // // expressionProperties: {
3036
+ // // 'templateOptions.disabled': (model: any) => !model.newAddress,
3037
+ // // },
3038
+ // },
3039
+ {
3040
+ className: 'small w-100-p',
3041
+ key: 'street1',
3042
+ type: 'input',
3043
+ templateOptions: {
3044
+ label: 'form.profile.address.street',
3045
+ },
3046
+ // expressionProperties: {
3047
+ // 'templateOptions.disabled': (model: any) => !model.newAddress,
3048
+ // },
3049
+ },
3050
+ ],
3051
+ },
3052
+ ],
3053
+ },
3054
+ ].map((item) => this.translate.forms(item));
3055
+ }
3056
+ }
3057
+ ScanFieldsProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanFieldsProvider, deps: [{ token: TranslationProvider }, { token: ScanProvider }], target: i0.ɵɵFactoryTarget.Injectable });
3058
+ ScanFieldsProvider.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanFieldsProvider, providedIn: 'root' });
3059
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanFieldsProvider, decorators: [{
3060
+ type: Injectable,
3061
+ args: [{
3062
+ providedIn: 'root',
3063
+ }]
3064
+ }], ctorParameters: function () { return [{ type: TranslationProvider }, { type: ScanProvider }]; } });
3065
+
3066
+ class ScanProfileComponent {
3067
+ constructor(cd, scanProvider, dialogs, formProvider, zone, translate, auth // private api: ServerProvider
3068
+ ) {
3069
+ this.cd = cd;
3070
+ this.scanProvider = scanProvider;
3071
+ this.dialogs = dialogs;
3072
+ this.formProvider = formProvider;
3073
+ this.zone = zone;
3074
+ this.translate = translate;
3075
+ this.auth = auth;
3076
+ this.scanBlastData = [
3077
+ {
3078
+ title: 'pms.dialogs.components.scanProfile.front',
3079
+ description: 'pms.dialogs.components.scanProfile.frontDescription',
3080
+ side: 'FRONT',
3081
+ },
3082
+ {
3083
+ title: 'pms.dialogs.components.scanProfile.back',
3084
+ description: 'pms.dialogs.components.scanProfile.backDescription',
3085
+ disabled: true,
3086
+ side: 'BACK',
3087
+ },
3088
+ ];
3089
+ this.type = 'desktop';
3090
+ this.actions = new EventEmitter();
3091
+ this.mediaDevices = [];
3092
+ this.videoOptions = {
3093
+ width: 1920,
3094
+ height: 1080,
3095
+ facingMode: 'environment',
3096
+ };
3097
+ this.startTime = 0;
3098
+ this.isDebug = false;
3099
+ this.multipleWebcamsAvailable = false;
3100
+ this.scanInProgress = false;
3101
+ // webcam snapshot trigger
3102
+ this.documentTypeSelected = false;
3103
+ this.preview = null;
3104
+ this.errorCode = '1000';
3105
+ this.displayInfo = 'Position document inside rectange and hold steady.';
3106
+ this.allowCameraSwitch = true;
3107
+ this.verificationErrorSent = false;
3108
+ this.error = false;
3109
+ this.cameraReady = false;
3110
+ this.scaning = false;
3111
+ this.imageHandler = new Subject();
3112
+ this.logData = {
3113
+ AcceptTermsAndConditions: true,
3114
+ Request: null,
3115
+ Response: null,
3116
+ ExpectedOutput: null,
3117
+ };
3118
+ this.scanDatas = [];
3119
+ this.idScan = null;
3120
+ this.validation = false;
3121
+ this.scannedImages = [];
3122
+ this.scanDelay = 0;
3123
+ this.trigger = new Subject();
3124
+ // switch to next / previous / specific webcam; true/false: forward/backwards, string: deviceId
3125
+ this.nextWebcam = new Subject();
3126
+ this.imageVerified = false;
3127
+ this.form = new FormGroup({});
3128
+ this.scanImageTimestamps = {
3129
+ time: 0,
3130
+ load: 0,
3131
+ };
3132
+ }
3133
+ onResize() {
3134
+ if (this.wraper) {
3135
+ this.width = this.wraper.nativeElement.clientWidth;
3136
+ this.height = this.wraper.nativeElement.clientHeight;
3137
+ setTimeout(() => {
3138
+ const video = this.wraper?.nativeElement.querySelector('video');
3139
+ if (video) {
3140
+ // console.log(video.clientWidth, video.clientHeight);
3141
+ this.videoWidth = video.clientWidth;
3142
+ this.videoHeight = video.clientHeight;
3143
+ }
3144
+ this.cd.detectChanges();
3145
+ }, 100);
3146
+ this.cd.detectChanges();
3147
+ }
3148
+ }
3149
+ resetLogData() {
3150
+ this.logData = {
3151
+ Request: null,
3152
+ Response: null,
3153
+ ExpectedOutput: null,
3154
+ AcceptTermsAndConditions: true,
3155
+ };
3156
+ }
3157
+ ngOnDestroy() {
3158
+ if (this.scanTimeout) {
3159
+ clearTimeout(this.scanTimeout);
3160
+ }
3161
+ if (this.imageHandlerSubscription) {
3162
+ this.imageHandlerSubscription.unsubscribe();
3163
+ }
3164
+ }
3165
+ init() {
3166
+ this.auth.accesToken.subscribe();
3167
+ this.resetLogData();
3168
+ // this.result=true;
3169
+ // this.result ={};
3170
+ this.fields = this.formProvider.document();
3171
+ WebcamUtil.getAvailableVideoInputs().subscribe((mediaDevices) => {
3172
+ console.log('[DEVICES]', mediaDevices.map((d) => d.label));
3173
+ this.mediaDevices = mediaDevices;
3174
+ this.multipleWebcamsAvailable = mediaDevices && mediaDevices.length > 1;
3175
+ });
3176
+ }
3177
+ scan() {
3178
+ // this.triggerSnapshot();
3179
+ // this.scanDatas[0] = true;
3180
+ // if (this.scanTimeout) {
3181
+ // clearTimeout(this.scanTimeout);
3182
+ // }
3183
+ // this.scanTimeout = setTimeout(() => {
3184
+ // this.scan();
3185
+ // }, 1);
3186
+ }
3187
+ DataUrlFromImage() { }
3188
+ handleImage(webcamImage) {
3189
+ // console.log('[received webcam image]', webcamImage);
3190
+ this.zone.runOutsideAngular(() => {
3191
+ const consoleBackground = "font-size:300px;background-image: url('" +
3192
+ webcamImage.imageResized +
3193
+ "');background-size: contain; background-repeat: no-repeat;";
3194
+ // console.log('%c ', consoleBackground);
3195
+ const time = new Date().getTime();
3196
+ if (this.scanImageTimestamps.load > 0) {
3197
+ const { load } = this.scanImageTimestamps;
3198
+ const diff = time - load;
3199
+ // console.log('time:', diff);
3200
+ this.scanDelay = diff;
3201
+ }
3202
+ this.scanImageTimestamps.load = time;
3203
+ if (webcamImage.imageData) {
3204
+ this.scannedImages.push(webcamImage);
3205
+ }
3206
+ this.cd.detectChanges();
3207
+ if (this.scannedImages.length > 4 && !this.validation) {
3208
+ console.timeEnd('scan');
3209
+ console.time('scan');
3210
+ // get last 10
3211
+ console.log('CAPTURED:', this.scannedImages.length);
3212
+ const images = this.scannedImages.slice(-5);
3213
+ // set images to 0
3214
+ this.scannedImages = [];
3215
+ const imagesArray = images.map((m) => m.imageResized.split(',')[1]);
3216
+ this.validation = true;
3217
+ this.handleBurstData(imagesArray, images);
3218
+ // this.scanProvider.burst(imagesArray).subscribe((resp: any) => {
3219
+ // // console.clear()
3220
+ // console.log([resp.Info]);
3221
+ // this.validation = false;
3222
+ // this.displayInfo = resp.Info;
3223
+ // if (resp.Validated) {
3224
+ // if (this.scanTimeout) {
3225
+ // clearTimeout(this.scanTimeout);
3226
+ // }
3227
+ // this.webcamImage = images[resp.Index];
3228
+ // // this.preview = this.webcamImage.imageAsDataUrl;
3229
+ // this.cd.detectChanges();
3230
+ // const { DocType, Series, Side } = resp;
3231
+ // // For ID ask for other side
3232
+ // if (DocType === 'ID') {
3233
+ // if (Side === 'FRONT') {
3234
+ // this.scanBlastData[0].image = this.webcamImage;
3235
+ // } else {
3236
+ // this.scanBlastData[1].image = this.webcamImage;
3237
+ // }
3238
+ // if (this.scanBlastData[0].image && this.scanBlastData[1].image) {
3239
+ // console.warn('UPLOAD');
3240
+ // this.scanBlastFinish();
3241
+ // } else {
3242
+ // const num = Side === 'FRONT' ? 1 : 0;
3243
+ // this.singleScan(this.scanBlastData[num]);
3244
+ // this.scan();
3245
+ // this.idScan = this.scanBlastData[num].side;
3246
+ // console.log('ID SIDE', this.idScan);
3247
+ // this.displayInfo = 'Please turn the document over!';
3248
+ // }
3249
+ // } else {
3250
+ // this.scanBlastData[0].image = this.webcamImage;
3251
+ // console.warn('UPLOAD');
3252
+ // this.scanBlastFinish();
3253
+ // }
3254
+ // console.log(DocType, Series, Side);
3255
+ // this.scannedImages = [];
3256
+ // }
3257
+ // });
3258
+ }
3259
+ if (this.cameraReady) {
3260
+ // console.log('delay', this.scanDelay);
3261
+ //console.log('timeD', new Date().getTime());
3262
+ this.trigger.next(new Date().getTime());
3263
+ // if (this.scanDelay < 100) {
3264
+ // const diff = 100 - this.scanDelay;
3265
+ // console.log(diff);
3266
+ // const time2 = new Date().getTime();
3267
+ // // const sub = of(1)
3268
+ // // .pipe(delay(diff))
3269
+ // // .subscribe((resp) => {
3270
+ // // console.log(new Date().getTime()-time);
3271
+ // // this.trigger.next();
3272
+ // // sub.unsubscribe();
3273
+ // // });
3274
+ // const timeout = setTimeout(() => {
3275
+ // console.log('TO', new Date().getTime() - time2);
3276
+ // this.trigger.next();
3277
+ // clearTimeout(timeout);
3278
+ // }, diff);
3279
+ // } else {
3280
+ // this.trigger.next();
3281
+ // }
3282
+ }
3283
+ });
3284
+ // this.scanImageTimestamps = {
3285
+ // time: new Date().getTime(),
3286
+ // load:
3287
+ // };
3288
+ // this.webcamImage = webcamImage;
3289
+ // this.preview = webcamImage.imageAsDataUrl;
3290
+ // this.cd.detectChanges();
3291
+ }
3292
+ handleBurstData(imagesArray, images, type = 'plain') {
3293
+ this.scanProvider.burst(imagesArray).subscribe((resp) => {
3294
+ this.displayInfo = resp.Info;
3295
+ console.timeEnd('validationPOST');
3296
+ console.log('AnalysisTime', resp.AnalysisTime);
3297
+ const { DocType, Series, Side, InfoCode } = resp;
3298
+ // if (InfoCode === '1006' && this.idScan) {
3299
+ // this.handleLongValidationError(image);
3300
+ // }
3301
+ if (resp.Validated) {
3302
+ console.log('[SCANNED INDEX]', resp.Index);
3303
+ const selectedImage = images[resp.Index];
3304
+ // this.preview = this.webcamImage.imageAsDataUrl;
3305
+ this.cd.detectChanges();
3306
+ let image = selectedImage;
3307
+ if (type == 'worker') {
3308
+ const dataUrl = this.handleBitmapImage(selectedImage.bitmap);
3309
+ image = { dataUrl };
3310
+ }
3311
+ if (InfoCode === '1007') {
3312
+ // For ID ask for other side
3313
+ if (Side === 'FRONT') {
3314
+ this.scanBlastData[0].image = image;
3315
+ }
3316
+ else {
3317
+ this.scanBlastData[1].image = image;
3318
+ }
3319
+ if (this.scanBlastData[0].image && this.scanBlastData[1].image) {
3320
+ console.warn('UPLOAD');
3321
+ if (type == 'worker') {
3322
+ this.imageHandler.next({ type: 'stop' });
3323
+ }
3324
+ this.scanBlastFinish();
3325
+ }
3326
+ else {
3327
+ const num = Side === 'FRONT' ? 1 : 0;
3328
+ this.singleScan(this.scanBlastData[num]);
3329
+ this.scan();
3330
+ this.idScan = this.scanBlastData[num].side;
3331
+ console.log('ID SIDE', this.idScan);
3332
+ this.displayInfo = 'Please turn the document over!';
3333
+ this.validation = false;
3334
+ }
3335
+ }
3336
+ else {
3337
+ this.scanBlastData[0].image = image;
3338
+ console.warn('UPLOAD');
3339
+ if (type == 'worker') {
3340
+ this.imageHandler.next({ type: 'stop' });
3341
+ }
3342
+ this.scanBlastFinish();
3343
+ }
3344
+ this.scannedImages = [];
3345
+ // this.scanBlastData[0].image = selectedImage;
3346
+ //this.scanBlastFinish();
3347
+ }
3348
+ else {
3349
+ this.validation = false;
3350
+ }
3351
+ });
3352
+ }
3353
+ handleInitError(error) {
3354
+ console.log(error);
3355
+ }
3356
+ get scanBlastCanUpload() {
3357
+ return this.scanBlastData[0].image ? true : false;
3358
+ }
3359
+ cameraWasSwitched(deviceId) {
3360
+ console.log('[active device]', deviceId);
3361
+ this.deviceId = deviceId;
3362
+ this.cameraReady = true;
3363
+ this.defaultDevice = deviceId;
3364
+ setTimeout(() => {
3365
+ this.onResize();
3366
+ this.scan();
3367
+ }, 300);
3368
+ }
3369
+ get nextWebcamObservable() {
3370
+ return this.nextWebcam.asObservable();
3371
+ }
3372
+ handleLongValidationError(img) {
3373
+ // save current image after 10sec
3374
+ const diff = (Date.now() - this.startTime) / 1000;
3375
+ if (diff > 15 && !this.verificationErrorSent) {
3376
+ this.verificationErrorSent = true;
3377
+ const dataUrl = this.handleBitmapImage(img.bitmap);
3378
+ console.warn('SENT');
3379
+ this.displayInfo = 'Cant detect document!';
3380
+ this.logData.Request = this.scanProvider
3381
+ .sendLog({
3382
+ AcceptTermsAndConditions: true,
3383
+ ExpectedOutput: {},
3384
+ Request: {
3385
+ verification: dataUrl.split(',')[1],
3386
+ },
3387
+ Response: {
3388
+ TransactionID: v4(),
3389
+ },
3390
+ })
3391
+ .subscribe();
3392
+ }
3393
+ }
3394
+ ngAfterViewInit() {
3395
+ this.cd.detectChanges();
3396
+ this.autoScan();
3397
+ this.imageHandlerSubscription = this.imageHandler.subscribe((webcamImage) => {
3398
+ // return;
3399
+ if (this.startTime === 0) {
3400
+ this.startTime = Date.now();
3401
+ }
3402
+ this.zone.runOutsideAngular(() => {
3403
+ if (webcamImage.base64) {
3404
+ const time = new Date().getTime();
3405
+ if (this.scanImageTimestamps.load > 0) {
3406
+ const { load } = this.scanImageTimestamps;
3407
+ const diff = time - load;
3408
+ console.warn('TIME', diff);
3409
+ this.scanDelay = diff;
3410
+ }
3411
+ this.scanImageTimestamps.load = time;
3412
+ this.scannedImages.push(webcamImage);
3413
+ this.handleLongValidationError(webcamImage);
3414
+ }
3415
+ // this.cd.detectChanges();
3416
+ if (this.scannedImages.length > 4 && !this.validation) {
3417
+ // get last 10
3418
+ console.timeEnd('validationTOTAL_UI');
3419
+ console.time('validationTOTAL_UI');
3420
+ const images = this.scannedImages.slice(-5);
3421
+ // set images to 0
3422
+ this.scannedImages = [];
3423
+ console.log(images);
3424
+ const imagesArray = images.map((m) => m.base64.split(',')[1]);
3425
+ this.validation = true;
3426
+ this.handleBurstData(imagesArray, images, 'worker');
3427
+ console.time('validationPOST');
3428
+ }
3429
+ this.cd.detectChanges();
3430
+ });
3431
+ });
3432
+ }
3433
+ handleBitmapImage(bitmap) {
3434
+ const { width, height } = bitmap;
3435
+ const offscreenSmall = document.createElement('canvas');
3436
+ offscreenSmall.width = width;
3437
+ offscreenSmall.height = height;
3438
+ const ctx = offscreenSmall.getContext('bitmaprenderer');
3439
+ if (ctx) {
3440
+ ctx.imageSmoothingEnabled = false;
3441
+ ctx.transferFromImageBitmap(bitmap);
3442
+ bitmap.close();
3443
+ const data = ctx.canvas.toDataURL('image/jpeg');
3444
+ return data;
3445
+ }
3446
+ return null;
3447
+ }
3448
+ autoScan() {
3449
+ const side = this.scanBlastData[0];
3450
+ this.idScan = null;
3451
+ this.singleScan(side);
3452
+ }
3453
+ selectCamera(event) {
3454
+ this.cameraReady = false;
3455
+ this.nextWebcam.next(event.value);
3456
+ this.scanInProgress = false;
3457
+ }
3458
+ close() {
3459
+ this.dialogRef?.close();
3460
+ }
3461
+ singleScan(side) {
3462
+ this.scanType = side.side;
3463
+ this.preview = null;
3464
+ this.selectedSide = side;
3465
+ this.selectedSide.image = null;
3466
+ this.documentTypeSelected = true;
3467
+ this.scanBlastData[1].disabled = false;
3468
+ this.cd.detectChanges();
3469
+ setTimeout(() => {
3470
+ this.onResize();
3471
+ }, 10);
3472
+ }
3473
+ getBase64(file) {
3474
+ return new Observable((observer) => {
3475
+ const reader = new FileReader();
3476
+ reader.readAsDataURL(file);
3477
+ reader.onload = () => {
3478
+ observer.next(reader.result);
3479
+ };
3480
+ reader.onerror = (error) => {
3481
+ observer.error(error);
3482
+ };
3483
+ });
3484
+ }
3485
+ handleFileInput(target, event, side) {
3486
+ const files = target.files;
3487
+ this.selectedSide = side;
3488
+ console.log(files);
3489
+ const file = files.item(0);
3490
+ this.resolutionLimit(file)
3491
+ .pipe(switchMap((valid) => {
3492
+ return valid ? this.getBase64(file) : of(false);
3493
+ }))
3494
+ .subscribe((imageAsDataUrl) => {
3495
+ // console.log(imageAsDataUrl);
3496
+ event.target.value = null;
3497
+ if (!imageAsDataUrl) {
3498
+ this.dialogs.alert('core.page.error', this.translate.instant('pms.dialogs.components.scanProfile.minResolution'));
3499
+ }
3500
+ else {
3501
+ side.image = {
3502
+ imageAsDataUrl,
3503
+ };
3504
+ if (this.selectedSide.side === 'FRONT') {
3505
+ this.scanBlastData[1].disabled = false;
3506
+ }
3507
+ }
3508
+ this.cd.detectChanges();
3509
+ });
3510
+ }
3511
+ rotateBase64Image(base64data) {
3512
+ return new Observable((observer) => {
3513
+ const canvas = document.createElement('canvas');
3514
+ const ctx = canvas.getContext('2d');
3515
+ var image = new Image();
3516
+ image.src = base64data;
3517
+ image.onload = () => {
3518
+ console.log(canvas);
3519
+ canvas.width = image.height;
3520
+ canvas.height = image.width;
3521
+ if (ctx) {
3522
+ ctx.rotate((90 * Math.PI) / 180);
3523
+ ctx.translate(0, -canvas.width);
3524
+ ctx.drawImage(image, 0, 0);
3525
+ observer.next(canvas.toDataURL());
3526
+ }
3527
+ else {
3528
+ observer.error({ type: 'generic error' });
3529
+ }
3530
+ };
3531
+ image.onerror = (e) => {
3532
+ observer.error(e);
3533
+ };
3534
+ });
3535
+ }
3536
+ sendMobile() {
3537
+ this.dialogs.scanMobile({ id: 1 });
3538
+ }
3539
+ singleScanRotate(side) {
3540
+ console.log(side);
3541
+ this.rotateBase64Image(side.image.imageAsDataUrl).subscribe((data) => {
3542
+ side.image = { imageAsDataUrl: data };
3543
+ this.cd.detectChanges();
3544
+ });
3545
+ }
3546
+ singleScanRemove(side) {
3547
+ side.image = null;
3548
+ if (side.side === 'FRONT') {
3549
+ this.scanBlastData[1].disabled = true;
3550
+ }
3551
+ this.cd.detectChanges();
3552
+ }
3553
+ resolutionLimit(file) {
3554
+ const minWidth = 1280;
3555
+ const minHeight = 720;
3556
+ return new Observable((observer) => {
3557
+ const img = new Image();
3558
+ img.src = window.URL.createObjectURL(file);
3559
+ img.onload = () => {
3560
+ const width = img.naturalWidth;
3561
+ const height = img.naturalHeight;
3562
+ let valid = false;
3563
+ if (width > height) {
3564
+ valid = width >= minWidth && height >= minHeight;
3565
+ }
3566
+ else {
3567
+ valid = width >= minHeight && height >= minWidth;
3568
+ }
3569
+ observer.next(valid);
3570
+ };
3571
+ img.onerror = (error) => {
3572
+ observer.error(error);
3573
+ };
3574
+ });
3575
+ }
3576
+ getImgBase64(num) {
3577
+ console.log('GET 64');
3578
+ return this.scanBlastData[num].image.dataUrl.split(',')[1];
3579
+ }
3580
+ scanBlastFinish() {
3581
+ console.time('upload');
3582
+ if (this.type === 'mobile') {
3583
+ this.actions.emit({ data: this.scanBlastData });
3584
+ this.retake();
3585
+ return;
3586
+ }
3587
+ this.idScan = null;
3588
+ // const loading = this.dialogs.loading();
3589
+ this.scaning = true;
3590
+ this.cd.detectChanges();
3591
+ console.time('payload');
3592
+ const payload = {
3593
+ AcceptTermsAndConditions: true,
3594
+ DataFields: {
3595
+ FrontImageType: 'base64',
3596
+ FrontImageCropped: false,
3597
+ BackImageType: 'base64',
3598
+ BackImageCropped: false,
3599
+ FrontImage: this.getImgBase64(0),
3600
+ BackImage: this.scanBlastData[1].image ? this.getImgBase64(1) : null,
3601
+ },
3602
+ Settings: {
3603
+ ShouldValidate: true,
3604
+ ShouldReturnDocumentImage: true,
3605
+ ShouldReturnFaceIfDetected: true,
3606
+ SkipImageSizeCheck: true,
3607
+ CanStoreImages: this.scanProvider.canStoreImages,
3608
+ },
3609
+ // CallBackUrl: 'http://demo:5000/report/extracted/',
3610
+ };
3611
+ if (!this.scanBlastData[1].image) {
3612
+ payload.Settings.IgnoreBackImage = true;
3613
+ }
3614
+ this.logData.Request = JSON.parse(JSON.stringify(payload));
3615
+ console.timeEnd('payload');
3616
+ this.scanProvider
3617
+ .blastPost(payload)
3618
+ .subscribe((data) => {
3619
+ //console.log(data);
3620
+ const results = data.Data;
3621
+ console.timeEnd('upload');
3622
+ console.time('parse');
3623
+ // data.InfoCode = '1001';
3624
+ this.logData.Response = JSON.parse(JSON.stringify(data));
3625
+ //loading.close();
3626
+ this.documentTypeSelected = true;
3627
+ this.scaning = false;
3628
+ if (data.InfoCode === '1001') {
3629
+ this.error = true;
3630
+ console.log('[ERROR] 1001');
3631
+ this.errorCode = '1001';
3632
+ // this.scanSide = 0;
3633
+ this.preview = true;
3634
+ this.cd.detectChanges();
3635
+ return;
3636
+ }
3637
+ if (data.InfoCode === '1002') {
3638
+ this.error = true;
3639
+ console.log('[ERROR] 1002');
3640
+ this.errorCode = '1002';
3641
+ // this.scanSide = 0;
3642
+ this.preview = true;
3643
+ this.cd.detectChanges();
3644
+ return;
3645
+ }
3646
+ if (results && data.Metadata.length > 0 && data.InfoCode === '1000') {
3647
+ console.log('Extraction time', data.AnalysisTime);
3648
+ this.zone.run(() => {
3649
+ if (data.ImageData?.Documents) {
3650
+ const { Documents } = data.ImageData;
3651
+ this.images = Documents.map((image, i) => {
3652
+ return { data: 'data:image/jpeg;base64,' + Documents[i] };
3653
+ });
3654
+ }
3655
+ this.result = this.scanProvider.parseBlast(results);
3656
+ console.log('RES', this.result);
3657
+ this.cd.detectChanges();
3658
+ this.model = this.result.model;
3659
+ if (data.ImageData?.FaceImage) {
3660
+ this.model._avatar =
3661
+ 'data:image/jpeg;base64,' + data.ImageData?.FaceImage;
3662
+ }
3663
+ console.log('MODEL', this.model);
3664
+ this.cd.detectChanges();
3665
+ });
3666
+ }
3667
+ else {
3668
+ console.log('ERROR');
3669
+ // this.scanSide = 0;
3670
+ this.error = true;
3671
+ this.preview = true;
3672
+ this.cd.detectChanges();
3673
+ // this.documentTypeSelected = false;
3674
+ // this.retry();
3675
+ }
3676
+ this.cd.detectChanges();
3677
+ console.timeEnd('parse');
3678
+ }, (err) => {
3679
+ // loading.close();
3680
+ // this.scanSide = 0;
3681
+ this.error = true;
3682
+ this.preview = true;
3683
+ this.documentTypeSelected = true;
3684
+ this.scaning = false;
3685
+ });
3686
+ }
3687
+ cameraOff(ev) {
3688
+ this.cameraReady = false;
3689
+ this.cd.detectChanges();
3690
+ }
3691
+ continue() {
3692
+ this.documentTypeSelected = false;
3693
+ setTimeout(() => {
3694
+ this.selectedSide.image = this.webcamImage;
3695
+ if (this.selectedSide.side === 'FRONT') {
3696
+ this.scanBlastData[1].disabled = false;
3697
+ }
3698
+ this.cd.detectChanges();
3699
+ }, 200);
3700
+ }
3701
+ retry() {
3702
+ this.preview = false;
3703
+ this.validation = false;
3704
+ this.errorCode = '1000';
3705
+ this.result = false;
3706
+ if (this.error) {
3707
+ this.documentTypeSelected = false;
3708
+ this.scanBlastData.forEach((element) => {
3709
+ element.image = null;
3710
+ });
3711
+ }
3712
+ this.error = false;
3713
+ this.autoScan();
3714
+ this.cd.detectChanges();
3715
+ }
3716
+ triggerSnapshot() {
3717
+ this.trigger.next(0);
3718
+ }
3719
+ retake() {
3720
+ this.validation = false;
3721
+ this.preview = false;
3722
+ this.error = false;
3723
+ this.result = false;
3724
+ this.scanSide = 0;
3725
+ this.imageVerified = false;
3726
+ this.scanDatas = [];
3727
+ this.scaning = false;
3728
+ this.images = [];
3729
+ this.scanInProgress = false;
3730
+ this.documentTypeSelected = false;
3731
+ this.scanBlastData.forEach((m) => {
3732
+ m.image = null;
3733
+ });
3734
+ this.autoScan();
3735
+ this.cd.detectChanges();
3736
+ }
3737
+ cancel() {
3738
+ this.documentTypeSelected = false;
3739
+ }
3740
+ use() {
3741
+ // save images??
3742
+ if (this.scanProvider.canStoreImages) {
3743
+ this.logData.ExpectedOutput = JSON.parse(JSON.stringify(this.model));
3744
+ if (this.logData.ExpectedOutput?._avatar) {
3745
+ delete this.logData.ExpectedOutput._avatar;
3746
+ }
3747
+ this.scanProvider.sendLog(this.logData).subscribe();
3748
+ console.log(this.logData);
3749
+ }
3750
+ this.dialogRef?.close({
3751
+ model: this.model,
3752
+ images: this.images,
3753
+ });
3754
+ }
3755
+ selfie() {
3756
+ this.dialogs
3757
+ .scanSelfie({ avatar: this.model._avatar })
3758
+ .afterClosed()
3759
+ .subscribe((resp) => {
3760
+ if (resp) {
3761
+ console.log(resp);
3762
+ if (this.scanProvider.enableVerification) {
3763
+ this.imageVerified = true;
3764
+ }
3765
+ this.model._avatar = resp.imageAsDataUrl;
3766
+ this.cd.detectChanges();
3767
+ }
3768
+ });
3769
+ }
3770
+ videoReady(event) {
3771
+ this.cameraReady = event;
3772
+ if (this.cameraReady && !this.scanInProgress) {
3773
+ this.scanInProgress = true;
3774
+ setTimeout(() => {
3775
+ this.trigger.next(new Date().getTime());
3776
+ }, 1000);
3777
+ }
3778
+ }
3779
+ }
3780
+ ScanProfileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanProfileComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: ScanProvider }, { token: DialogsCoreProvider }, { token: ScanFieldsProvider }, { token: i0.NgZone }, { token: i4$1.TranslateService }, { token: AuthProvider }], target: i0.ɵɵFactoryTarget.Component });
3781
+ ScanProfileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScanProfileComponent, selector: "app-scan-profile", inputs: { type: "type" }, outputs: { actions: "actions" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "wraper", first: true, predicate: ["wraper"], descendants: true }], ngImport: i0, template: "<!-- <div *ngIf=\"isDebug\" class=\"debug\">\n <ng-container *ngFor=\"let img of scannedImages; let index = index\">\n <div style=\"display: flex; flex-direction: column\">\n <img [src]=\"img.imageResized\" />\n {{ index }}\n </div>\n </ng-container>\n</div> -->\n\n<header class=\"page-header\">\n <div class=\"title\" ngClass.lt-sm=\"title-small\">Scan</div>\n\n <span fxFlex></span>\n\n <!-- <mat-slide-toggle style=\"margin:0px 20px\" [(ngModel)]=\"isDebug\"\n >Debug</mat-slide-toggle\n > -->\n\n <ng-container\n *ngIf=\"\n documentTypeSelected &&\n !result &&\n !error &&\n multipleWebcamsAvailable &&\n !preview\n \"\n >\n <div class=\"separator\"></div>\n <div style=\"padding: 0px 16px\">\n <div fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <mat-form-field\n style=\"font-size: 14px; width: 200px; margin-top: 8px\"\n class=\"w-100 mr-16 mt-8\"\n >\n <mat-label> Camera </mat-label>\n <mat-select\n (selectionChange)=\"selectCamera($event)\"\n [(ngModel)]=\"deviceId\"\n >\n <mat-option\n *ngFor=\"let device of mediaDevices\"\n [value]=\"device.deviceId\"\n >\n {{ device.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"type === 'desktop'\">\n <!-- <div class=\"separator\"></div>\n <button mat-button (click)=\"sendMobile()\">\n <mat-icon>tablet_mac</mat-icon>\n </button> -->\n\n <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n </ng-container>\n</header>\n\n<div *ngIf=\"result\" fxFlex fxLayout=\"column\">\n <!-- <div *ngIf=\"result\" fxFlex fxLayout=\"column\"> -->\n <div\n fxFlex\n #wraper\n class=\"wraper\"\n fxLayout=\"row\"\n style=\"overflow: auto\"\n protelPerfectScrollbar\n class=\"pt-8 pr-8\"\n fxLayout.lt-md=\"column\"\n >\n <div fxFlex class=\"\">\n <div fxFlex>\n <mat-card style=\"margin: 4px; padding: 4px 16px\">\n <h3>Avatar</h3>\n <div\n style=\"display: flex; flex-direction: row; align-items: center\"\n class=\"selfieContainer\"\n >\n <div class=\"selfie\" style=\"width: 200px\">\n <img\n *ngIf=\"model?._avatar\"\n class=\"preview\"\n style=\"width: 120px; height: 120px; border-radius: 60px\"\n [src]=\"model._avatar\"\n />\n </div>\n <button\n [disabled]=\"imageVerified\"\n (click)=\"selfie()\"\n mat-raised-button\n >\n Take selfie\n </button>\n </div>\n </mat-card>\n\n <form\n fxLayout=\"row\"\n fxLayoutAlign=\"start center\"\n class=\"px-16 py-0 w-100-p\"\n [formGroup]=\"form\"\n >\n <formly-form\n ngClass.lt-md=\"mobile\"\n fxFlex\n [form]=\"form\"\n [fields]=\"fields\"\n [model]=\"model\"\n >\n </formly-form>\n </form>\n </div>\n </div>\n <div fxFlex class=\"pr-16 m-4\">\n <mat-card style=\"margin: 4px; padding-top: 2px\" class=\"images\">\n <h3>Images</h3>\n <ng-container *ngFor=\"let img of images\">\n <div fxLayout=\"column\">\n <ng-container *ngIf=\"img.side === 0\">\n <div class=\"title\">Front Side</div>\n </ng-container>\n <ng-container *ngIf=\"img.side === 1\">\n <div class=\"title\">Back Side</div>\n </ng-container>\n <img\n class=\"preview\"\n style=\"max-width: 460px; border-radius: 1rem\"\n [src]=\"img.data\"\n />\n </div>\n </ng-container>\n </mat-card>\n </div>\n </div>\n\n <div></div>\n\n <footer fxLayout=\"row\" class=\"p-8\">\n <div class=\"w-100-p\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <button fxFlex class=\"mr-8\" mat-raised-button (click)=\"retake()\">\n {{ \"pms.dialogs.components.scanProfile.reTake\" | translate }}\n </button>\n <button\n [disabled]=\"error || form.invalid\"\n fxFlex\n class=\"ml-8\"\n mat-raised-button\n (click)=\"use()\"\n >\n {{ \"pms.dialogs.components.scanProfile.useData\" | translate }}\n </button>\n </div>\n </footer>\n</div>\n\n<div\n style=\"position: relative\"\n *ngIf=\"!result && documentTypeSelected\"\n fxFlex\n fxLayout=\"column\"\n>\n <div fxFlex #wraper class=\"wraper\" fxLayout=\"row\">\n <div\n style=\"\n position: absolute;\n top: 0px;\n left: 0px;\n right: 0px;\n bottom: 0px;\n z-index: 20;\n background-color: whitesmoke;\n \"\n *ngIf=\"!cameraReady && !preview\"\n >\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <div *ngIf=\"!preview\" style=\"position: absolute; left: 0px\">\n DELAY:{{ scanDelay }}\n </div>\n\n <div\n *ngIf=\"scaning\"\n style=\"\n position: absolute;\n z-index: 200;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n \"\n fxlayout=\"row\"\n fxLayoutAlign=\"center center\"\n >\n <!-- <mat-progress-spinner\n mode=\"indeterminate\"\n color=\"accent\"\n [strokeWidth]=\"10\"\n ></mat-progress-spinner> -->\n </div>\n\n <ng-container *ngIf=\"!error\">\n <!-- <div\n class=\"rectangle\"\n [ngStyle]=\"{\n 'width.px': videoHeight * 0.75 * 1.588,\n 'height.px': videoHeight * 0.75\n }\"\n ></div>\n <svg\n *ngIf=\"videoWidth\"\n style=\"position: absolute; left: 0px; top: 0px\"\n width=\"0\"\n height=\"0\"\n >\n <defs>\n <clipPath id=\"myClip\">\n <rect\n stroke-width=\"6\"\n stroke-color=\"red\"\n [attr.x]=\"(videoWidth - videoHeight * 0.75 * 1.588) / 2\"\n [attr.y]=\"(videoHeight * 0.25) / 2\"\n [attr.width]=\"videoHeight * 0.75 * 1.588\"\n [attr.height]=\"videoHeight * 0.75\"\n rx=\"25\"\n />\n </clipPath>\n </defs>\n </svg> -->\n\n <app-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n [imageQuality]=\"1\"\n #webcam\n fxFlex\n type=\"document\"\n [trigger]=\"trigger\"\n [imageHandler]=\"imageHandler\"\n (imageCapture)=\"handleImage($event)\"\n [allowCameraSwitch]=\"allowCameraSwitch\"\n [videoOptions]=\"videoOptions\"\n [switchCamera]=\"nextWebcamObservable\"\n (cameraSwitched)=\"cameraWasSwitched($event)\"\n (initError)=\"handleInitError($event)\"\n [width]=\"width\"\n [height]=\"height\"\n (destroyed)=\"cameraOff($event)\"\n (videoReady)=\"videoReady($event)\"\n >\n </app-webcam>\n </ng-container>\n <div\n fxLayout=\"row\"\n fxFlex\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"z-index: 20; position: absolute; width: 100%; height: 100%\"\n >\n <div class=\"p-16 error\" *ngIf=\"error\">\n <div style=\"max-width: \">\n <div class=\"title\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-icon>error_outline</mat-icon\n ><span class=\"ml-8\">{{\n \"pms.dialogs.components.scanProfile.unableToDetectId\" | translate\n }}</span>\n </div>\n\n <ng-container *ngIf=\"errorCode === '1001'\">\n <div>\n Could not classify the given object as a supported document.\n </div>\n </ng-container>\n <ng-container *ngIf=\"errorCode === '1002'\">\n <div>\n Something is wrong with extraction data. Please try again.\n </div>\n </ng-container>\n\n <ul *ngIf=\"errorCode === '1000'\">\n <li>\n {{\n \"pms.dialogs.components.scanProfile.placeIdCloseToDevice\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.ensureSufficientLight\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.holdDocumentSteady\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureAllEdgesOfTheIdAreVisible\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureThereAreNoGlareAndShadowsOnTheId\"\n | translate\n }}\n </li>\n </ul>\n </div>\n </div>\n\n <div\n class=\"scanPreview\"\n fxFlex\n fxLayout=\"column\"\n *ngIf=\"!error && !scaning\"\n >\n <!-- <div class=\"py-16\" style=\"font-size: 16px\">\n {{\n \"pms.dialogs.components.scanProfile.ensureAllTextsAreVisible\"\n | translate\n }}\n </div> -->\n <div\n fxFlex\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer fxLayout=\"row\" style=\"height: 80px\" class=\"p-8\">\n <div class=\"displayInfo\" ngClass.lt-sm=\"mobile\" *ngIf=\"!preview && cameraReady\">\n {{ displayInfo }}\n </div>\n <div style=\"height: 26px\">\n <div\n style=\"text-align: center; font-size: 18px\"\n *ngIf=\"idScan && !preview && cameraReady\"\n >\n <ng-container *ngIf=\"idScan === 'BACK'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureBack\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureFront\" | translate }}\n </ng-container>\n </div>\n </div>\n\n <!-- <button\n [disabled]=\"!cameraReady\"\n class=\"w-100-p\"\n *ngIf=\"!preview\"\n mat-raised-button\n (click)=\"scan()\"\n >\n <ng-container>\n <ng-container *ngIf=\"scanType === 'FRONT'\">{{\n \"pms.dialogs.components.scanProfile.captureFront\" | translate\n }}</ng-container>\n <ng-container *ngIf=\"scanType === 'BACK'\">{{\n \"pms.dialogs.components.scanProfile.captureBack\" | translate\n }}</ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"scanSide === 1\">{{\n \"pms.dialogs.components.scanProfile.captureBackOfId\" | translate\n }}</ng-container>\n </button> -->\n\n <div\n class=\"w-100-p\"\n *ngIf=\"preview\"\n fxLayout=\"row\"\n fxLayoutAlign=\"start center\"\n fxFlex\n >\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n {{ \"pms.dialogs.components.scanProfile.retry\" | translate }}\n </button>\n\n <button\n [disabled]=\"error\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n {{\n \"pms.dialogs.components.scanProfile.continueWithSelectedImage\"\n | translate\n }}\n </button>\n </div>\n </footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5}.page-header{display:flex;flex-direction:row;align-items:center}.page-header button{height:100%}.debug{position:absolute;left:0;width:100%;height:80px;top:0;border-bottom:1px solid #ccc;background-color:#f8f8f8;display:flex;overflow:hidden;color:#000}.debug img{height:50px;border:1px solid #000}.displayInfo{text-align:center;height:20px;flex:1;position:absolute;width:100%;background-color:#000;height:30px;bottom:55px;left:0;line-height:30px;color:#fff;z-index:200}.displayInfo.mobile{font-size:12px}.element{margin-bottom:8px}.element label{font-size:14px}.element div{font-size:18px}.wraper{position:relative;overflow:hidden}.preview{width:100%;border-radius:1%}.documentTypeWraper{width:400px}.documentTypeWraper .label{font-size:14px;margin-bottom:20px}.documentTypeWraper button{box-shadow:none}.overPane{position:absolute;width:100%;height:100%;top:0;left:0}.overPane app-webcam{clip-path:url(#myClip)}.subhead{height:55px;padding-top:8px}.rectangle{z-index:2;position:absolute;top:50%;left:50%;width:85.6mm;height:53.98mm;transform:translate(-50%,-50%);box-sizing:border-box;border:2px dashed #459be5;border-radius:3mm}.mask{z-index:1;position:absolute;width:100%;height:100%;background-position:center center;background-size:380mm;background-repeat:no-repeat}.label{font-size:11px;margin-top:4px}footer button{box-shadow:none!important;height:45px;min-height:45px;text-transform:uppercase}h4{font-size:16px}.images .title{padding:8px 0;font-weight:600}.images img{margin-bottom:16px}.error{display:flex;align-items:center;justify-content:center;flex:1}.error .title{font-size:20px;margin-bottom:8px}.error .title mat-icon{margin-right:8px}.error ul{font-size:18px;list-style-type:none}.photo{width:120px;height:120px;overflow:hidden}.signature{width:200px}mat-card{box-shadow:none!important}.scanBlastWraper button{text-transform:uppercase}.scanBlastWraper.mobile mat-card{margin:4px!important}.scanBlastWraper.mobile .description{flex-direction:row!important}.scanBlastWraper.mobile .description .imgWrap{padding:0!important}.scanBlastWraper.mobile .description .btnActions{position:absolute;right:0}.scanBlastWraper.mobile .description button{margin:0!important;position:absolute;right:16px}.scanBlastWraper.mobile .description button.rotateButton{top:58px}.scanBlastWraper.mobile .description button.remButton{top:8px}.scanBlastWraper.mobile .description button mat-icon{margin:0!important}.scanBlastWraper.mobile .description button div.label{display:none}.scanBlast{display:flex;flex-direction:row;flex:1;padding:0 4px}.scanBlast mat-card{padding:0;box-shadow:none;margin:8px 4px;flex:1}.scanBlast mat-card .head{display:flex;flex-direction:row;align-items:center;justify-items:center;border-bottom:1px solid rgba(0,0,0,.12);height:60px;padding:8px}.scanBlast mat-card .head.small{height:30px!important;padding:4px 8px!important}.scanBlast mat-card .head.small .title{font-size:12px!important;margin-left:4px!important}.scanBlast mat-card .head button{max-width:120px;height:40px;box-shadow:none;border:1px solid rgba(0,0,0,.12)}.scanBlast mat-card .head .title{margin-left:16px;color:#459ae5;font-size:16px}.scanBlast mat-card .content{margin:8px;flex:1}.scanBlast mat-card .description{text-align:center;color:#888}.scanBlast mat-card .actions{background-color:#e9e9e9;display:flex;flex-direction:row}.scanBlast mat-card .actions .mat-button-disabled{background-color:#fff!important}.scanBlast mat-card .actions button{box-shadow:none;width:50%;margin:8px;height:40px;font-size:12px}.scanBlast mat-card .actions button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder{flex:1;border-radius:6px;display:flex;flex-direction:column}.scanBlast mat-card .previewPlaceholder .description{display:flex;flex:1;flex-direction:column;justify-content:center}.scanBlast mat-card .previewPlaceholder button{box-shadow:none;margin-top:8px;height:40px;font-size:12px}.scanBlast mat-card .previewPlaceholder button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder .imgWrap{flex-direction:column;flex:1;padding:8px;background-color:#f5f5f5;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap img{width:100%;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap .image{background-position:center;background-repeat:no-repeat;background-size:contain}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"], dependencies: [{ kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8$1.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "component", type: i7.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i8.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i12.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "component", type: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i1$4.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: WebcamComponent, selector: "app-webcam", inputs: ["imageHandler", "id", "type", "width", "height", "videoOptions", "allowCameraSwitch", "mirrorImage", "captureImageData", "imageType", "imageQuality", "trigger", "switchCamera"], outputs: ["imageCapture", "initError", "imageClick", "cameraSwitched", "videoReady", "destroyed"] }, { kind: "directive", type: i4.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i4.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i4.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i5$1.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3782
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanProfileComponent, decorators: [{
3783
+ type: Component,
3784
+ args: [{ selector: 'app-scan-profile', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- <div *ngIf=\"isDebug\" class=\"debug\">\n <ng-container *ngFor=\"let img of scannedImages; let index = index\">\n <div style=\"display: flex; flex-direction: column\">\n <img [src]=\"img.imageResized\" />\n {{ index }}\n </div>\n </ng-container>\n</div> -->\n\n<header class=\"page-header\">\n <div class=\"title\" ngClass.lt-sm=\"title-small\">Scan</div>\n\n <span fxFlex></span>\n\n <!-- <mat-slide-toggle style=\"margin:0px 20px\" [(ngModel)]=\"isDebug\"\n >Debug</mat-slide-toggle\n > -->\n\n <ng-container\n *ngIf=\"\n documentTypeSelected &&\n !result &&\n !error &&\n multipleWebcamsAvailable &&\n !preview\n \"\n >\n <div class=\"separator\"></div>\n <div style=\"padding: 0px 16px\">\n <div fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <mat-form-field\n style=\"font-size: 14px; width: 200px; margin-top: 8px\"\n class=\"w-100 mr-16 mt-8\"\n >\n <mat-label> Camera </mat-label>\n <mat-select\n (selectionChange)=\"selectCamera($event)\"\n [(ngModel)]=\"deviceId\"\n >\n <mat-option\n *ngFor=\"let device of mediaDevices\"\n [value]=\"device.deviceId\"\n >\n {{ device.label }}\n </mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"type === 'desktop'\">\n <!-- <div class=\"separator\"></div>\n <button mat-button (click)=\"sendMobile()\">\n <mat-icon>tablet_mac</mat-icon>\n </button> -->\n\n <div class=\"separator\"></div>\n\n <button mat-button (click)=\"close()\">\n <mat-icon>close</mat-icon>\n </button>\n </ng-container>\n</header>\n\n<div *ngIf=\"result\" fxFlex fxLayout=\"column\">\n <!-- <div *ngIf=\"result\" fxFlex fxLayout=\"column\"> -->\n <div\n fxFlex\n #wraper\n class=\"wraper\"\n fxLayout=\"row\"\n style=\"overflow: auto\"\n protelPerfectScrollbar\n class=\"pt-8 pr-8\"\n fxLayout.lt-md=\"column\"\n >\n <div fxFlex class=\"\">\n <div fxFlex>\n <mat-card style=\"margin: 4px; padding: 4px 16px\">\n <h3>Avatar</h3>\n <div\n style=\"display: flex; flex-direction: row; align-items: center\"\n class=\"selfieContainer\"\n >\n <div class=\"selfie\" style=\"width: 200px\">\n <img\n *ngIf=\"model?._avatar\"\n class=\"preview\"\n style=\"width: 120px; height: 120px; border-radius: 60px\"\n [src]=\"model._avatar\"\n />\n </div>\n <button\n [disabled]=\"imageVerified\"\n (click)=\"selfie()\"\n mat-raised-button\n >\n Take selfie\n </button>\n </div>\n </mat-card>\n\n <form\n fxLayout=\"row\"\n fxLayoutAlign=\"start center\"\n class=\"px-16 py-0 w-100-p\"\n [formGroup]=\"form\"\n >\n <formly-form\n ngClass.lt-md=\"mobile\"\n fxFlex\n [form]=\"form\"\n [fields]=\"fields\"\n [model]=\"model\"\n >\n </formly-form>\n </form>\n </div>\n </div>\n <div fxFlex class=\"pr-16 m-4\">\n <mat-card style=\"margin: 4px; padding-top: 2px\" class=\"images\">\n <h3>Images</h3>\n <ng-container *ngFor=\"let img of images\">\n <div fxLayout=\"column\">\n <ng-container *ngIf=\"img.side === 0\">\n <div class=\"title\">Front Side</div>\n </ng-container>\n <ng-container *ngIf=\"img.side === 1\">\n <div class=\"title\">Back Side</div>\n </ng-container>\n <img\n class=\"preview\"\n style=\"max-width: 460px; border-radius: 1rem\"\n [src]=\"img.data\"\n />\n </div>\n </ng-container>\n </mat-card>\n </div>\n </div>\n\n <div></div>\n\n <footer fxLayout=\"row\" class=\"p-8\">\n <div class=\"w-100-p\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <button fxFlex class=\"mr-8\" mat-raised-button (click)=\"retake()\">\n {{ \"pms.dialogs.components.scanProfile.reTake\" | translate }}\n </button>\n <button\n [disabled]=\"error || form.invalid\"\n fxFlex\n class=\"ml-8\"\n mat-raised-button\n (click)=\"use()\"\n >\n {{ \"pms.dialogs.components.scanProfile.useData\" | translate }}\n </button>\n </div>\n </footer>\n</div>\n\n<div\n style=\"position: relative\"\n *ngIf=\"!result && documentTypeSelected\"\n fxFlex\n fxLayout=\"column\"\n>\n <div fxFlex #wraper class=\"wraper\" fxLayout=\"row\">\n <div\n style=\"\n position: absolute;\n top: 0px;\n left: 0px;\n right: 0px;\n bottom: 0px;\n z-index: 20;\n background-color: whitesmoke;\n \"\n *ngIf=\"!cameraReady && !preview\"\n >\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <div *ngIf=\"!preview\" style=\"position: absolute; left: 0px\">\n DELAY:{{ scanDelay }}\n </div>\n\n <div\n *ngIf=\"scaning\"\n style=\"\n position: absolute;\n z-index: 200;\n width: 100%;\n height: 100%;\n top: 0px;\n left: 0px;\n \"\n fxlayout=\"row\"\n fxLayoutAlign=\"center center\"\n >\n <!-- <mat-progress-spinner\n mode=\"indeterminate\"\n color=\"accent\"\n [strokeWidth]=\"10\"\n ></mat-progress-spinner> -->\n </div>\n\n <ng-container *ngIf=\"!error\">\n <!-- <div\n class=\"rectangle\"\n [ngStyle]=\"{\n 'width.px': videoHeight * 0.75 * 1.588,\n 'height.px': videoHeight * 0.75\n }\"\n ></div>\n <svg\n *ngIf=\"videoWidth\"\n style=\"position: absolute; left: 0px; top: 0px\"\n width=\"0\"\n height=\"0\"\n >\n <defs>\n <clipPath id=\"myClip\">\n <rect\n stroke-width=\"6\"\n stroke-color=\"red\"\n [attr.x]=\"(videoWidth - videoHeight * 0.75 * 1.588) / 2\"\n [attr.y]=\"(videoHeight * 0.25) / 2\"\n [attr.width]=\"videoHeight * 0.75 * 1.588\"\n [attr.height]=\"videoHeight * 0.75\"\n rx=\"25\"\n />\n </clipPath>\n </defs>\n </svg> -->\n\n <app-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n [imageQuality]=\"1\"\n #webcam\n fxFlex\n type=\"document\"\n [trigger]=\"trigger\"\n [imageHandler]=\"imageHandler\"\n (imageCapture)=\"handleImage($event)\"\n [allowCameraSwitch]=\"allowCameraSwitch\"\n [videoOptions]=\"videoOptions\"\n [switchCamera]=\"nextWebcamObservable\"\n (cameraSwitched)=\"cameraWasSwitched($event)\"\n (initError)=\"handleInitError($event)\"\n [width]=\"width\"\n [height]=\"height\"\n (destroyed)=\"cameraOff($event)\"\n (videoReady)=\"videoReady($event)\"\n >\n </app-webcam>\n </ng-container>\n <div\n fxLayout=\"row\"\n fxFlex\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"z-index: 20; position: absolute; width: 100%; height: 100%\"\n >\n <div class=\"p-16 error\" *ngIf=\"error\">\n <div style=\"max-width: \">\n <div class=\"title\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-icon>error_outline</mat-icon\n ><span class=\"ml-8\">{{\n \"pms.dialogs.components.scanProfile.unableToDetectId\" | translate\n }}</span>\n </div>\n\n <ng-container *ngIf=\"errorCode === '1001'\">\n <div>\n Could not classify the given object as a supported document.\n </div>\n </ng-container>\n <ng-container *ngIf=\"errorCode === '1002'\">\n <div>\n Something is wrong with extraction data. Please try again.\n </div>\n </ng-container>\n\n <ul *ngIf=\"errorCode === '1000'\">\n <li>\n {{\n \"pms.dialogs.components.scanProfile.placeIdCloseToDevice\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.ensureSufficientLight\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.holdDocumentSteady\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureAllEdgesOfTheIdAreVisible\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureThereAreNoGlareAndShadowsOnTheId\"\n | translate\n }}\n </li>\n </ul>\n </div>\n </div>\n\n <div\n class=\"scanPreview\"\n fxFlex\n fxLayout=\"column\"\n *ngIf=\"!error && !scaning\"\n >\n <!-- <div class=\"py-16\" style=\"font-size: 16px\">\n {{\n \"pms.dialogs.components.scanProfile.ensureAllTextsAreVisible\"\n | translate\n }}\n </div> -->\n <div\n fxFlex\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer fxLayout=\"row\" style=\"height: 80px\" class=\"p-8\">\n <div class=\"displayInfo\" ngClass.lt-sm=\"mobile\" *ngIf=\"!preview && cameraReady\">\n {{ displayInfo }}\n </div>\n <div style=\"height: 26px\">\n <div\n style=\"text-align: center; font-size: 18px\"\n *ngIf=\"idScan && !preview && cameraReady\"\n >\n <ng-container *ngIf=\"idScan === 'BACK'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureBack\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureFront\" | translate }}\n </ng-container>\n </div>\n </div>\n\n <!-- <button\n [disabled]=\"!cameraReady\"\n class=\"w-100-p\"\n *ngIf=\"!preview\"\n mat-raised-button\n (click)=\"scan()\"\n >\n <ng-container>\n <ng-container *ngIf=\"scanType === 'FRONT'\">{{\n \"pms.dialogs.components.scanProfile.captureFront\" | translate\n }}</ng-container>\n <ng-container *ngIf=\"scanType === 'BACK'\">{{\n \"pms.dialogs.components.scanProfile.captureBack\" | translate\n }}</ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"scanSide === 1\">{{\n \"pms.dialogs.components.scanProfile.captureBackOfId\" | translate\n }}</ng-container>\n </button> -->\n\n <div\n class=\"w-100-p\"\n *ngIf=\"preview\"\n fxLayout=\"row\"\n fxLayoutAlign=\"start center\"\n fxFlex\n >\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n {{ \"pms.dialogs.components.scanProfile.retry\" | translate }}\n </button>\n\n <button\n [disabled]=\"error\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n {{\n \"pms.dialogs.components.scanProfile.continueWithSelectedImage\"\n | translate\n }}\n </button>\n </div>\n </footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5}.page-header{display:flex;flex-direction:row;align-items:center}.page-header button{height:100%}.debug{position:absolute;left:0;width:100%;height:80px;top:0;border-bottom:1px solid #ccc;background-color:#f8f8f8;display:flex;overflow:hidden;color:#000}.debug img{height:50px;border:1px solid #000}.displayInfo{text-align:center;height:20px;flex:1;position:absolute;width:100%;background-color:#000;height:30px;bottom:55px;left:0;line-height:30px;color:#fff;z-index:200}.displayInfo.mobile{font-size:12px}.element{margin-bottom:8px}.element label{font-size:14px}.element div{font-size:18px}.wraper{position:relative;overflow:hidden}.preview{width:100%;border-radius:1%}.documentTypeWraper{width:400px}.documentTypeWraper .label{font-size:14px;margin-bottom:20px}.documentTypeWraper button{box-shadow:none}.overPane{position:absolute;width:100%;height:100%;top:0;left:0}.overPane app-webcam{clip-path:url(#myClip)}.subhead{height:55px;padding-top:8px}.rectangle{z-index:2;position:absolute;top:50%;left:50%;width:85.6mm;height:53.98mm;transform:translate(-50%,-50%);box-sizing:border-box;border:2px dashed #459be5;border-radius:3mm}.mask{z-index:1;position:absolute;width:100%;height:100%;background-position:center center;background-size:380mm;background-repeat:no-repeat}.label{font-size:11px;margin-top:4px}footer button{box-shadow:none!important;height:45px;min-height:45px;text-transform:uppercase}h4{font-size:16px}.images .title{padding:8px 0;font-weight:600}.images img{margin-bottom:16px}.error{display:flex;align-items:center;justify-content:center;flex:1}.error .title{font-size:20px;margin-bottom:8px}.error .title mat-icon{margin-right:8px}.error ul{font-size:18px;list-style-type:none}.photo{width:120px;height:120px;overflow:hidden}.signature{width:200px}mat-card{box-shadow:none!important}.scanBlastWraper button{text-transform:uppercase}.scanBlastWraper.mobile mat-card{margin:4px!important}.scanBlastWraper.mobile .description{flex-direction:row!important}.scanBlastWraper.mobile .description .imgWrap{padding:0!important}.scanBlastWraper.mobile .description .btnActions{position:absolute;right:0}.scanBlastWraper.mobile .description button{margin:0!important;position:absolute;right:16px}.scanBlastWraper.mobile .description button.rotateButton{top:58px}.scanBlastWraper.mobile .description button.remButton{top:8px}.scanBlastWraper.mobile .description button mat-icon{margin:0!important}.scanBlastWraper.mobile .description button div.label{display:none}.scanBlast{display:flex;flex-direction:row;flex:1;padding:0 4px}.scanBlast mat-card{padding:0;box-shadow:none;margin:8px 4px;flex:1}.scanBlast mat-card .head{display:flex;flex-direction:row;align-items:center;justify-items:center;border-bottom:1px solid rgba(0,0,0,.12);height:60px;padding:8px}.scanBlast mat-card .head.small{height:30px!important;padding:4px 8px!important}.scanBlast mat-card .head.small .title{font-size:12px!important;margin-left:4px!important}.scanBlast mat-card .head button{max-width:120px;height:40px;box-shadow:none;border:1px solid rgba(0,0,0,.12)}.scanBlast mat-card .head .title{margin-left:16px;color:#459ae5;font-size:16px}.scanBlast mat-card .content{margin:8px;flex:1}.scanBlast mat-card .description{text-align:center;color:#888}.scanBlast mat-card .actions{background-color:#e9e9e9;display:flex;flex-direction:row}.scanBlast mat-card .actions .mat-button-disabled{background-color:#fff!important}.scanBlast mat-card .actions button{box-shadow:none;width:50%;margin:8px;height:40px;font-size:12px}.scanBlast mat-card .actions button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder{flex:1;border-radius:6px;display:flex;flex-direction:column}.scanBlast mat-card .previewPlaceholder .description{display:flex;flex:1;flex-direction:column;justify-content:center}.scanBlast mat-card .previewPlaceholder button{box-shadow:none;margin-top:8px;height:40px;font-size:12px}.scanBlast mat-card .previewPlaceholder button mat-icon{margin-right:8px}.scanBlast mat-card .previewPlaceholder .imgWrap{flex-direction:column;flex:1;padding:8px;background-color:#f5f5f5;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap img{width:100%;border-radius:4px}.scanBlast mat-card .previewPlaceholder .imgWrap .image{background-position:center;background-repeat:no-repeat;background-size:contain}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}\n", ".page-header{z-index:2000;height:64px;padding:0;background-color:#fff;border-bottom:1px solid rgba(0,0,0,.12)}.page-header .title{padding-left:24px;line-height:64px;font-size:18px}.page-header .separator{width:1px;background-color:#0000001f;height:100%}.page-header .total{line-height:64px}.page-header .total span{font-weight:700}.page-footer{height:64px}.page-footer button{margin-left:24px;box-shadow:none!important}\n"] }]
3785
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: ScanProvider }, { type: DialogsCoreProvider }, { type: ScanFieldsProvider }, { type: i0.NgZone }, { type: i4$1.TranslateService }, { type: AuthProvider }]; }, propDecorators: { type: [{
3786
+ type: Input
3787
+ }], actions: [{
3788
+ type: Output
3789
+ }], wraper: [{
3790
+ type: ViewChild,
3791
+ args: ['wraper']
3792
+ }], onResize: [{
3793
+ type: HostListener,
3794
+ args: ['window:resize', ['$event']]
3795
+ }] } });
3796
+
3797
+ class AvatarTypeComponent extends FieldType {
3798
+ constructor(cd) {
3799
+ super();
3800
+ this.cd = cd;
3801
+ this.width = 'w-120';
3802
+ this.padding = 'px-32 pt-8 pb-8';
3803
+ }
3804
+ ngOnChange() { }
3805
+ ngAfterViewInit() {
3806
+ if (this.to.width) {
3807
+ this.width = this.to.width;
3808
+ }
3809
+ if (this.to.padding) {
3810
+ this.padding = this.to.padding;
3811
+ }
3812
+ this.cd.detectChanges();
3813
+ }
3814
+ }
3815
+ AvatarTypeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AvatarTypeComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3816
+ AvatarTypeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AvatarTypeComponent, selector: "app-formly-avatar-type", usesInheritance: true, ngImport: i0, template: `
3817
+ <mat-card
3818
+ [ngClass]="padding"
3819
+ fxLayout="column"
3820
+ fxLayoutAlign="center center"
3821
+ >
3822
+ <ngx-avatars
3823
+ [name]="model[key.toString()]"
3824
+ [ngClass]="width"
3825
+ ></ngx-avatars>
3826
+ </mat-card>
3827
+ `, isInline: true, styles: ["mat-card{border-radius:0;box-shadow:none!important}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i12.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "component", type: i3$2.AvatarComponent, selector: "ngx-avatars", inputs: ["round", "size", "textSizeRatio", "bgColor", "fgColor", "borderColor", "style", "cornerRadius", "facebookId", "twitterId", "googleId", "instagramId", "vkontakteId", "skypeId", "gravatarId", "githubId", "src", "name", "value", "referrerpolicy", "placeholder", "initialsSize"], outputs: ["clickOnAvatar"] }] });
3828
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AvatarTypeComponent, decorators: [{
3829
+ type: Component,
3830
+ args: [{ selector: 'app-formly-avatar-type', template: `
3831
+ <mat-card
3832
+ [ngClass]="padding"
3833
+ fxLayout="column"
3834
+ fxLayoutAlign="center center"
3835
+ >
3836
+ <ngx-avatars
3837
+ [name]="model[key.toString()]"
3838
+ [ngClass]="width"
3839
+ ></ngx-avatars>
3840
+ </mat-card>
3841
+ `, styles: ["mat-card{border-radius:0;box-shadow:none!important}\n"] }]
3842
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
3843
+
3844
+ class TitleTypeComponent extends FieldType {
3845
+ constructor(cd) {
3846
+ super();
3847
+ this.cd = cd;
3848
+ }
3849
+ ngOnInit() {
3850
+ this.opt = {
3851
+ badge: this.to.badge,
3852
+ };
3853
+ }
3854
+ ngAfterViewInit() {
3855
+ this.cd.detectChanges();
3856
+ }
3857
+ }
3858
+ TitleTypeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TitleTypeComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3859
+ TitleTypeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TitleTypeComponent, selector: "app-formly-title-type", usesInheritance: true, ngImport: i0, template: `
3860
+ <div fxLayout="row" fxLayoutAlign="start center">
3861
+ <h3>
3862
+ <span>{{ to.label }}</span>
3863
+
3864
+ <span
3865
+ *ngIf="opt.badge && model[opt.badge] && model[opt.badge].length > 1"
3866
+ matBadgeSize="small"
3867
+ matBadgeColor="primary"
3868
+ matBadgeOverlap="false"
3869
+ ></span>
3870
+ </h3>
3871
+ <span fxFlex></span>
3872
+ <div *ngIf="to.chip" class="chip">
3873
+ {{ to.chip | translate }}
3874
+ </div>
3875
+ </div>
3876
+ `, isInline: true, styles: [".chip{background:whitesmoke;border-radius:6px;padding:4px 8px;font-size:12px;color:#888;font-weight:600}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4$1.TranslatePipe, name: "translate" }] });
3877
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TitleTypeComponent, decorators: [{
3878
+ type: Component,
3879
+ args: [{ selector: 'app-formly-title-type', template: `
3880
+ <div fxLayout="row" fxLayoutAlign="start center">
3881
+ <h3>
3882
+ <span>{{ to.label }}</span>
3883
+
3884
+ <span
3885
+ *ngIf="opt.badge && model[opt.badge] && model[opt.badge].length > 1"
3886
+ matBadgeSize="small"
3887
+ matBadgeColor="primary"
3888
+ matBadgeOverlap="false"
3889
+ ></span>
3890
+ </h3>
3891
+ <span fxFlex></span>
3892
+ <div *ngIf="to.chip" class="chip">
3893
+ {{ to.chip | translate }}
3894
+ </div>
3895
+ </div>
3896
+ `, styles: [".chip{background:whitesmoke;border-radius:6px;padding:4px 8px;font-size:12px;color:#888;font-weight:600}\n"] }]
3897
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
3898
+
3899
+ class ProfileImageTypeComponent extends FieldType {
3900
+ constructor(cd) {
3901
+ super();
3902
+ this.cd = cd;
3903
+ }
3904
+ ngOnChange() { }
3905
+ ngAfterViewInit() {
3906
+ if (this.to.width) {
3907
+ this.width = this.to.width;
3908
+ }
3909
+ if (this.to.padding) {
3910
+ this.padding = this.to.padding;
3911
+ }
3912
+ this.cd.detectChanges();
3913
+ }
3914
+ }
3915
+ ProfileImageTypeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ProfileImageTypeComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3916
+ ProfileImageTypeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ProfileImageTypeComponent, selector: "app-formly-profile-image-type", usesInheritance: true, ngImport: i0, template: `
3917
+ <mat-card
3918
+
3919
+ fxLayout="column"
3920
+ fxLayoutAlign="center center"
3921
+ >
3922
+ <ngx-avatars
3923
+ class="profile-image"
3924
+ [src]="model[key.toString()]"
3925
+ [size]="150"
3926
+
3927
+ ></ngx-avatars>
3928
+ </mat-card>
3929
+ `, isInline: true, styles: ["mat-card{border-radius:0;box-shadow:none!important}.profile-image{width:150px;height:150px;border-radius:50%}\n"], dependencies: [{ kind: "component", type: i12.MatCard, selector: "mat-card", exportAs: ["matCard"] }, { kind: "component", type: i3$2.AvatarComponent, selector: "ngx-avatars", inputs: ["round", "size", "textSizeRatio", "bgColor", "fgColor", "borderColor", "style", "cornerRadius", "facebookId", "twitterId", "googleId", "instagramId", "vkontakteId", "skypeId", "gravatarId", "githubId", "src", "name", "value", "referrerpolicy", "placeholder", "initialsSize"], outputs: ["clickOnAvatar"] }] });
3930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ProfileImageTypeComponent, decorators: [{
3931
+ type: Component,
3932
+ args: [{ selector: 'app-formly-profile-image-type', template: `
3933
+ <mat-card
3934
+
3935
+ fxLayout="column"
3936
+ fxLayoutAlign="center center"
3937
+ >
3938
+ <ngx-avatars
3939
+ class="profile-image"
3940
+ [src]="model[key.toString()]"
3941
+ [size]="150"
3942
+
3943
+ ></ngx-avatars>
3944
+ </mat-card>
3945
+ `, styles: ["mat-card{border-radius:0;box-shadow:none!important}.profile-image{width:150px;height:150px;border-radius:50%}\n"] }]
3946
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
3947
+
3948
+ class AppFormModule {
3949
+ }
3950
+ AppFormModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AppFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3951
+ AppFormModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: AppFormModule, declarations: [TitleTypeComponent,
3952
+ AvatarTypeComponent,
3953
+ ProfileImageTypeComponent], imports: [CommonModule,
3954
+ FormsModule,
3955
+ FormlyMatDatepickerModule,
3956
+ FormlySelectModule,
3957
+ MaterialModule,
3958
+ AvatarModule,
3959
+ TranslateModule,
3960
+ FormlyMaterialModule, i8$1.FormlyModule], exports: [FormlyModule] });
3961
+ AppFormModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AppFormModule, imports: [CommonModule,
3962
+ FormsModule,
3963
+ FormlyMatDatepickerModule,
3964
+ FormlySelectModule,
3965
+ MaterialModule,
3966
+ AvatarModule,
3967
+ TranslateModule,
3968
+ FormlyMaterialModule,
3969
+ FormlyModule.forRoot({
3970
+ types: [
3971
+ {
3972
+ name: 'title',
3973
+ component: TitleTypeComponent,
3974
+ wrappers: [],
3975
+ },
3976
+ {
3977
+ name: 'profile-image',
3978
+ component: ProfileImageTypeComponent,
3979
+ wrappers: [],
3980
+ },
3981
+ ],
3982
+ }), FormlyModule] });
3983
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AppFormModule, decorators: [{
42
3984
  type: NgModule,
43
3985
  args: [{
44
3986
  declarations: [
45
- NgxScandocComponent
3987
+ TitleTypeComponent,
3988
+ AvatarTypeComponent,
3989
+ ProfileImageTypeComponent,
3990
+ ],
3991
+ imports: [
3992
+ CommonModule,
3993
+ FormsModule,
3994
+ FormlyMatDatepickerModule,
3995
+ FormlySelectModule,
3996
+ MaterialModule,
3997
+ AvatarModule,
3998
+ TranslateModule,
3999
+ FormlyMaterialModule,
4000
+ FormlyModule.forRoot({
4001
+ types: [
4002
+ {
4003
+ name: 'title',
4004
+ component: TitleTypeComponent,
4005
+ wrappers: [],
4006
+ },
4007
+ {
4008
+ name: 'profile-image',
4009
+ component: ProfileImageTypeComponent,
4010
+ wrappers: [],
4011
+ },
4012
+ ],
4013
+ }),
4014
+ ],
4015
+ providers: [],
4016
+ exports: [FormlyModule],
4017
+ }]
4018
+ }] });
4019
+
4020
+ class DialogsModule {
4021
+ }
4022
+ DialogsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4023
+ DialogsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: DialogsModule, declarations: [ScanProfileComponent,
4024
+ BlankComponent,
4025
+ LoadingComponent,
4026
+ ConfirmComponent,
4027
+ ScanMobileComponent,
4028
+ ScanSelfieComponent], imports: [QRCodeModule,
4029
+ ReactiveFormsModule,
4030
+ CommonModule,
4031
+ FormsModule,
4032
+ AppFormModule,
4033
+ TranslateModule,
4034
+ MaterialModule,
4035
+ CoreComponentsModule,
4036
+ CorePipesModule,
4037
+ FlexModule,
4038
+ FlexLayoutModule], exports: [ScanProfileComponent,
4039
+ LoadingComponent,
4040
+ BlankComponent,
4041
+ ScanMobileComponent,
4042
+ MaterialModule,
4043
+ ScanSelfieComponent] });
4044
+ DialogsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogsModule, providers: [DialogsCoreProvider], imports: [QRCodeModule,
4045
+ ReactiveFormsModule,
4046
+ CommonModule,
4047
+ FormsModule,
4048
+ AppFormModule,
4049
+ TranslateModule,
4050
+ MaterialModule,
4051
+ CoreComponentsModule,
4052
+ CorePipesModule,
4053
+ FlexModule,
4054
+ FlexLayoutModule, MaterialModule] });
4055
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DialogsModule, decorators: [{
4056
+ type: NgModule,
4057
+ args: [{
4058
+ declarations: [
4059
+ ScanProfileComponent,
4060
+ BlankComponent,
4061
+ LoadingComponent,
4062
+ ConfirmComponent,
4063
+ ScanMobileComponent,
4064
+ ScanSelfieComponent,
46
4065
  ],
47
- imports: [],
48
4066
  exports: [
49
- NgxScandocComponent
50
- ]
4067
+ ScanProfileComponent,
4068
+ LoadingComponent,
4069
+ BlankComponent,
4070
+ ScanMobileComponent,
4071
+ MaterialModule,
4072
+ ScanSelfieComponent,
4073
+ ],
4074
+ imports: [
4075
+ QRCodeModule,
4076
+ ReactiveFormsModule,
4077
+ CommonModule,
4078
+ FormsModule,
4079
+ AppFormModule,
4080
+ TranslateModule,
4081
+ MaterialModule,
4082
+ CoreComponentsModule,
4083
+ CorePipesModule,
4084
+ FlexModule,
4085
+ FlexLayoutModule,
4086
+ ],
4087
+ providers: [DialogsCoreProvider]
4088
+ }]
4089
+ }] });
4090
+
4091
+ class HttpErrorInterceptor {
4092
+ constructor(injector) {
4093
+ this.injector = injector;
4094
+ }
4095
+ intercept(req, next) {
4096
+ console.log(req.url);
4097
+ if (req.url.indexOf('auth') >= 0 || req.url.indexOf('/assets/') >= 0) {
4098
+ return next.handle(req);
4099
+ }
4100
+ const authProvider = this.injector.get(AuthProvider);
4101
+ this.inflightAuthRequest = authProvider.accesToken;
4102
+ return this.inflightAuthRequest.pipe(share(), switchMap((token) => {
4103
+ // unset request inflight
4104
+ this.inflightAuthRequest = null;
4105
+ const transaction = req.headers.get('TransactionID');
4106
+ const authReq = req.clone({
4107
+ headers: this.getHeaders(token, transaction || ''),
4108
+ });
4109
+ return next.handle(authReq);
4110
+ }), catchError((err) => {
4111
+ let tokenExpired = false;
4112
+ if (err.errors) {
4113
+ const find = err.erros.find((es) => es.indexOf('Invalid token') > -1);
4114
+ tokenExpired = find ? true : false;
4115
+ }
4116
+ console.log(err);
4117
+ if (err.status === 401 || tokenExpired) {
4118
+ authProvider.resetToken();
4119
+ return this.intercept(req, next);
4120
+ }
4121
+ else {
4122
+ return throwError(() => new Error('' + (err && err.status ? ':' + err.status : '')));
4123
+ }
4124
+ }));
4125
+ }
4126
+ getHeaders(token, TransactionID) {
4127
+ if (TransactionID) {
4128
+ return new HttpHeaders({
4129
+ 'Content-Type': 'application/json',
4130
+ Authorization: token,
4131
+ TransactionID,
4132
+ });
4133
+ }
4134
+ return new HttpHeaders({
4135
+ 'Content-Type': 'application/json',
4136
+ Authorization: token,
4137
+ });
4138
+ }
4139
+ }
4140
+ HttpErrorInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpErrorInterceptor, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
4141
+ HttpErrorInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpErrorInterceptor });
4142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: HttpErrorInterceptor, decorators: [{
4143
+ type: Injectable
4144
+ }], ctorParameters: function () { return [{ type: i0.Injector }]; } });
4145
+
4146
+ class NgxScandocModule {
4147
+ static forRoot(config) {
4148
+ return {
4149
+ ngModule: NgxScandocModule,
4150
+ providers: [
4151
+ AuthProvider,
4152
+ { provide: 'configAuth', useValue: config.auth },
4153
+ ScanProvider,
4154
+ { provide: 'config', useValue: config.scan },
4155
+ {
4156
+ provide: HTTP_INTERCEPTORS,
4157
+ useClass: HttpErrorInterceptor,
4158
+ multi: true,
4159
+ },
4160
+ ],
4161
+ };
4162
+ }
4163
+ }
4164
+ NgxScandocModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4165
+ NgxScandocModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, imports: [CoreComponentsModule, DialogsModule], exports: [CoreComponentsModule, DialogsModule] });
4166
+ NgxScandocModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, imports: [CoreComponentsModule, DialogsModule, CoreComponentsModule, DialogsModule] });
4167
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxScandocModule, decorators: [{
4168
+ type: NgModule,
4169
+ args: [{
4170
+ declarations: [],
4171
+ imports: [CoreComponentsModule, DialogsModule],
4172
+ exports: [CoreComponentsModule, DialogsModule],
51
4173
  }]
52
4174
  }] });
53
4175
 
@@ -59,5 +4181,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
59
4181
  * Generated bundle index. Do not edit.
60
4182
  */
61
4183
 
62
- export { NgxScandocComponent, NgxScandocModule, NgxScandocService };
4184
+ export { AppFormModule, AuthProvider, BlankComponent, CoreComponentsModule, CorePipesModule, DialogsCoreProvider, DialogsModule, HttpErrorInterceptor, LoadingComponent, MaterialModule, NgxScandocModule, SafeResourceUrlPipe, ScanFieldsProvider, ScanMobileComponent, ScanProfileComponent, ScanProvider, ScanSelfieComponent, TranslationProvider, WebcamComponent, WebcamModule, webRtcProvider };
63
4185
  //# sourceMappingURL=ngx-scandoc.mjs.map