@ekyc_qoobiss/qbs-ect-cmp 1.5.11

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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/assets/animations/face/LookDown.gif +0 -0
  4. package/dist/assets/animations/face/LookLeft.gif +0 -0
  5. package/dist/assets/animations/face/LookRight.gif +0 -0
  6. package/dist/assets/animations/face/LookUp.gif +0 -0
  7. package/dist/assets/animations/face/TiltLeft.gif +0 -0
  8. package/dist/assets/animations/face/TiltRight.gif +0 -0
  9. package/dist/assets/animations/face/general.gif +0 -0
  10. package/dist/assets/animations/id/present-id.gif +0 -0
  11. package/dist/assets/animations/id/straighten-id.gif +0 -0
  12. package/dist/assets/animations/id/tilt-id.gif +0 -0
  13. package/dist/assets/buletin/metadata.json +1 -0
  14. package/dist/assets/buletin/model.json +1 -0
  15. package/dist/assets/buletin/weights.bin +0 -0
  16. package/dist/assets/buletin-v2/metadata.json +1 -0
  17. package/dist/assets/buletin-v2/model.json +1 -0
  18. package/dist/assets/buletin-v2/weights.bin +0 -0
  19. package/dist/assets/canvas-masks/face_green.svg +8 -0
  20. package/dist/assets/canvas-masks/face_white.svg +8 -0
  21. package/dist/assets/canvas-masks/id_green.svg +6 -0
  22. package/dist/assets/canvas-masks/id_white.svg +6 -0
  23. package/dist/assets/capture-error/idError.png +0 -0
  24. package/dist/assets/capture-error/idError.svg +8 -0
  25. package/dist/assets/capture-error/selfieError.png +0 -0
  26. package/dist/assets/capture-error/selfieError.svg +11 -0
  27. package/dist/assets/complete.svg +4 -0
  28. package/dist/assets/howtos/circle.svg +11 -0
  29. package/dist/assets/howtos/idscan.svg +293 -0
  30. package/dist/assets/howtos/liveness.svg +97 -0
  31. package/dist/assets/landing/device.svg +14 -0
  32. package/dist/assets/landing/id.svg +3 -0
  33. package/dist/assets/landing/info.svg +3 -0
  34. package/dist/assets/landing/validation.svg +16 -0
  35. package/dist/cjs/agreement-check_12.cjs.entry.js +6143 -0
  36. package/dist/cjs/index-9ebcada7.js +1487 -0
  37. package/dist/cjs/index.cjs.js +2 -0
  38. package/dist/cjs/loader-dots.cjs.entry.js +19 -0
  39. package/dist/cjs/loader.cjs.js +21 -0
  40. package/dist/cjs/qbs-ect-cmp.cjs.js +19 -0
  41. package/dist/collection/assets/canvas-masks/face_green.svg +8 -0
  42. package/dist/collection/assets/canvas-masks/face_white.svg +8 -0
  43. package/dist/collection/assets/canvas-masks/id_green.svg +6 -0
  44. package/dist/collection/assets/canvas-masks/id_white.svg +6 -0
  45. package/dist/collection/assets/capture-error/idError.svg +8 -0
  46. package/dist/collection/assets/capture-error/selfieError.svg +11 -0
  47. package/dist/collection/assets/complete.svg +4 -0
  48. package/dist/collection/assets/howtos/circle.svg +11 -0
  49. package/dist/collection/assets/howtos/idscan.svg +293 -0
  50. package/dist/collection/assets/howtos/liveness.svg +97 -0
  51. package/dist/collection/assets/landing/device.svg +14 -0
  52. package/dist/collection/assets/landing/id.svg +3 -0
  53. package/dist/collection/assets/landing/info.svg +3 -0
  54. package/dist/collection/assets/landing/validation.svg +16 -0
  55. package/dist/collection/collection-manifest.json +24 -0
  56. package/dist/collection/components/agreement-check/agreement-check.css +0 -0
  57. package/dist/collection/components/agreement-check/agreement-check.js +75 -0
  58. package/dist/collection/components/agreement-info/agreement-info.css +0 -0
  59. package/dist/collection/components/agreement-info/agreement-info.js +72 -0
  60. package/dist/collection/components/capture-error/capture-error.css +0 -0
  61. package/dist/collection/components/capture-error/capture-error.js +107 -0
  62. package/dist/collection/components/controls/camera/camera.css +43 -0
  63. package/dist/collection/components/controls/camera/camera.js +306 -0
  64. package/dist/collection/components/controls/loader-dots/loader-dots.css +61 -0
  65. package/dist/collection/components/controls/loader-dots/loader-dots.js +18 -0
  66. package/dist/collection/components/end-redirect/end-redirect.css +128 -0
  67. package/dist/collection/components/end-redirect/end-redirect.js +25 -0
  68. package/dist/collection/components/how-to-info/how-to-info.css +0 -0
  69. package/dist/collection/components/how-to-info/how-to-info.js +105 -0
  70. package/dist/collection/components/id-back-capture/id-back-capture.css +35 -0
  71. package/dist/collection/components/id-back-capture/id-back-capture.js +201 -0
  72. package/dist/collection/components/id-capture/id-capture.css +35 -0
  73. package/dist/collection/components/id-capture/id-capture.js +201 -0
  74. package/dist/collection/components/identification-component/identification-component.css +999 -0
  75. package/dist/collection/components/identification-component/identification-component.js +397 -0
  76. package/dist/collection/components/landing-validation/landing-validation.css +0 -0
  77. package/dist/collection/components/landing-validation/landing-validation.js +78 -0
  78. package/dist/collection/components/selfie-capture/selfie-capture.css +22 -0
  79. package/dist/collection/components/selfie-capture/selfie-capture.js +198 -0
  80. package/dist/collection/components/sms-code-validation/sms-code-validation.css +0 -0
  81. package/dist/collection/components/sms-code-validation/sms-code-validation.js +91 -0
  82. package/dist/collection/global.js +0 -0
  83. package/dist/collection/helpers/ApiCall.js +153 -0
  84. package/dist/collection/helpers/Cameras.js +98 -0
  85. package/dist/collection/helpers/Events.js +79 -0
  86. package/dist/collection/helpers/ML5.js +20 -0
  87. package/dist/collection/helpers/Stream.js +223 -0
  88. package/dist/collection/helpers/canvas.js +10 -0
  89. package/dist/collection/helpers/index.js +54 -0
  90. package/dist/collection/helpers/security.js +25 -0
  91. package/dist/collection/helpers/store.js +15 -0
  92. package/dist/collection/helpers/textValues.js +82 -0
  93. package/dist/collection/index.js +1 -0
  94. package/dist/collection/libs/FaceML5Detector/FaceML5Detector.js +206 -0
  95. package/dist/collection/libs/FaceML5Detector/FacePose.js +84 -0
  96. package/dist/collection/libs/IDML5Detector/IDML5Detector.js +110 -0
  97. package/dist/collection/libs/IDML5Detector/IDPose.js +5 -0
  98. package/dist/collection/models/ICamera.js +1 -0
  99. package/dist/collection/models/IConstraints.js +1 -0
  100. package/dist/collection/models/IDevice.js +1 -0
  101. package/dist/collection/utils/utils.js +10 -0
  102. package/dist/esm/agreement-check_12.entry.js +6128 -0
  103. package/dist/esm/index-3fe6775c.js +1457 -0
  104. package/dist/esm/index.js +1 -0
  105. package/dist/esm/loader-dots.entry.js +15 -0
  106. package/dist/esm/loader.js +17 -0
  107. package/dist/esm/polyfills/core-js.js +11 -0
  108. package/dist/esm/polyfills/css-shim.js +1 -0
  109. package/dist/esm/polyfills/dom.js +79 -0
  110. package/dist/esm/polyfills/es5-html-element.js +1 -0
  111. package/dist/esm/polyfills/index.js +34 -0
  112. package/dist/esm/polyfills/system.js +6 -0
  113. package/dist/esm/qbs-ect-cmp.js +17 -0
  114. package/dist/index.cjs.js +1 -0
  115. package/dist/index.js +1 -0
  116. package/dist/loader/cdn.js +3 -0
  117. package/dist/loader/index.cjs.js +3 -0
  118. package/dist/loader/index.d.ts +12 -0
  119. package/dist/loader/index.es2017.js +3 -0
  120. package/dist/loader/index.js +4 -0
  121. package/dist/loader/package.json +11 -0
  122. package/dist/qbs-ect-cmp/index.esm.js +0 -0
  123. package/dist/qbs-ect-cmp/p-3ef0bad2.entry.js +1373 -0
  124. package/dist/qbs-ect-cmp/p-3fa495e4.js +2 -0
  125. package/dist/qbs-ect-cmp/p-a69bb428.entry.js +1 -0
  126. package/dist/qbs-ect-cmp/qbs-ect-cmp.css +1 -0
  127. package/dist/qbs-ect-cmp/qbs-ect-cmp.esm.js +1 -0
  128. package/dist/types/components/agreement-check/agreement-check.d.ts +11 -0
  129. package/dist/types/components/agreement-info/agreement-info.d.ts +13 -0
  130. package/dist/types/components/capture-error/capture-error.d.ts +11 -0
  131. package/dist/types/components/controls/camera/camera.d.ts +33 -0
  132. package/dist/types/components/controls/loader-dots/loader-dots.d.ts +3 -0
  133. package/dist/types/components/end-redirect/end-redirect.d.ts +4 -0
  134. package/dist/types/components/how-to-info/how-to-info.d.ts +13 -0
  135. package/dist/types/components/id-back-capture/id-back-capture.d.ts +26 -0
  136. package/dist/types/components/id-capture/id-capture.d.ts +26 -0
  137. package/dist/types/components/identification-component/identification-component.d.ts +31 -0
  138. package/dist/types/components/landing-validation/landing-validation.d.ts +11 -0
  139. package/dist/types/components/selfie-capture/selfie-capture.d.ts +26 -0
  140. package/dist/types/components/sms-code-validation/sms-code-validation.d.ts +14 -0
  141. package/dist/types/components.d.ts +262 -0
  142. package/dist/types/global.d.ts +0 -0
  143. package/dist/types/helpers/ApiCall.d.ts +12 -0
  144. package/dist/types/helpers/Cameras.d.ts +8 -0
  145. package/dist/types/helpers/Events.d.ts +12 -0
  146. package/dist/types/helpers/ML5.d.ts +8 -0
  147. package/dist/types/helpers/Stream.d.ts +58 -0
  148. package/dist/types/helpers/canvas.d.ts +2 -0
  149. package/dist/types/helpers/index.d.ts +4 -0
  150. package/dist/types/helpers/security.d.ts +4 -0
  151. package/dist/types/helpers/store.d.ts +10 -0
  152. package/dist/types/helpers/textValues.d.ts +78 -0
  153. package/dist/types/index.d.ts +1 -0
  154. package/dist/types/libs/FaceML5Detector/FaceML5Detector.d.ts +43 -0
  155. package/dist/types/libs/FaceML5Detector/FacePose.d.ts +37 -0
  156. package/dist/types/libs/IDML5Detector/IDML5Detector.d.ts +22 -0
  157. package/dist/types/libs/IDML5Detector/IDPose.d.ts +4 -0
  158. package/dist/types/models/ICamera.d.ts +10 -0
  159. package/dist/types/models/IConstraints.d.ts +21 -0
  160. package/dist/types/models/IDevice.d.ts +11 -0
  161. package/dist/types/stencil-public-runtime.d.ts +1581 -0
  162. package/dist/types/utils/utils.d.ts +2 -0
  163. package/package.json +51 -0
@@ -0,0 +1,91 @@
1
+ import { h } from '@stencil/core';
2
+ import { ApiCall } from '../../helpers/ApiCall';
3
+ import store from '../../helpers/store';
4
+ import { PhoneValidationValues, CodeValidationValues } from '../../helpers/textValues';
5
+ export class SmsCodeValidation {
6
+ constructor() {
7
+ this.title = undefined;
8
+ this.details = undefined;
9
+ this.buttonText = undefined;
10
+ this.phoneNumber = undefined;
11
+ this.code = undefined;
12
+ this.apiCall = new ApiCall();
13
+ }
14
+ async doAction() {
15
+ if (store.flowStatus == 'CODE' || store.flowStatus == 'CODEERROR') {
16
+ var codeChecked = await this.apiCall.CheckOTPCode(store.requestId, this.code);
17
+ if (typeof codeChecked === 'boolean' && codeChecked) {
18
+ store.flowStatus = 'HOWTOID';
19
+ }
20
+ else {
21
+ store.flowStatus = 'CODEERROR';
22
+ }
23
+ }
24
+ if (store.flowStatus == 'PHONE') {
25
+ var codeSent = await this.apiCall.SendOTPCode(store.requestId, this.phoneNumber);
26
+ if (typeof codeSent === 'boolean' && codeSent) {
27
+ store.flowStatus = 'CODE';
28
+ }
29
+ }
30
+ }
31
+ componentWillRender() {
32
+ if (store.flowStatus == 'PHONE') {
33
+ this.title = PhoneValidationValues.Title;
34
+ this.details = PhoneValidationValues.Description;
35
+ this.buttonText = PhoneValidationValues.Button;
36
+ }
37
+ if (store.flowStatus == 'CODE' || store.flowStatus == 'CODEERROR') {
38
+ this.title = CodeValidationValues.Title;
39
+ this.details = CodeValidationValues.Description;
40
+ this.buttonText = CodeValidationValues.Button;
41
+ }
42
+ }
43
+ handleChangePhone(ev) {
44
+ let value = ev.target ? ev.target.value : '';
45
+ this.phoneNumber = value.replace(/\D/g, '');
46
+ if (this.phoneNumber.length > 10)
47
+ this.phoneNumber = this.phoneNumber.substring(0, 10);
48
+ ev.target.value = this.phoneNumber;
49
+ }
50
+ handleChangeCode(ev) {
51
+ let value = ev.target ? ev.target.value : '';
52
+ this.code = value;
53
+ if (this.code.length > 4)
54
+ this.code = this.code.substring(0, 4);
55
+ ev.target.value = this.code;
56
+ }
57
+ render() {
58
+ let inputBlock;
59
+ let errorBlock;
60
+ if (store.flowStatus == 'CODEERROR') {
61
+ errorBlock = h("p", { class: "main-text font-size-18 mt-15 color-red" }, CodeValidationValues.Error);
62
+ }
63
+ if (store.flowStatus == 'PHONE') {
64
+ inputBlock = (h("div", { class: "input-container mb-15" }, h("label", { class: "font-size-18 mb-1" }, h("b", null, PhoneValidationValues.Label)), h("input", { type: "tel", id: "phoneInput", class: "main-input", onInput: ev => this.handleChangePhone(ev), value: this.phoneNumber })));
65
+ }
66
+ else {
67
+ inputBlock = (h("div", { class: "input-container mb-15" }, h("input", { type: "text", id: "codeInput", class: "main-input", onInput: ev => this.handleChangeCode(ev), value: this.code })));
68
+ }
69
+ return (h("div", { class: "container" }, h("div", { class: "row row-validare" }, h("div", null, h("h1", null, this.title), errorBlock == null ? h("p", { class: "main-text font-size-2 mt-15 mb-20" }, this.details) : errorBlock), inputBlock, h("div", { class: "btn-buletin" }, h("button", { id: "action", class: "main-button", onClick: () => this.doAction() }, this.buttonText), h("p", { class: "main-text font-size-18 text-right mb-0" }, PhoneValidationValues.FooterText)))));
70
+ }
71
+ static get is() { return "sms-code-validation"; }
72
+ static get originalStyleUrls() {
73
+ return {
74
+ "$": ["sms-code-validation.css"]
75
+ };
76
+ }
77
+ static get styleUrls() {
78
+ return {
79
+ "$": ["sms-code-validation.css"]
80
+ };
81
+ }
82
+ static get states() {
83
+ return {
84
+ "title": {},
85
+ "details": {},
86
+ "buttonText": {},
87
+ "phoneNumber": {},
88
+ "code": {}
89
+ };
90
+ }
91
+ }
File without changes
@@ -0,0 +1,153 @@
1
+ import store from './store';
2
+ export class ApiCall {
3
+ constructor() {
4
+ this.toBase64 = (file) => new Promise((resolve, reject) => {
5
+ const reader = new FileReader();
6
+ reader.readAsDataURL(file);
7
+ reader.onload = () => resolve(reader.result);
8
+ reader.onerror = error => reject(error);
9
+ });
10
+ }
11
+ async Post(url, data) {
12
+ try {
13
+ let resp = await fetch(store.apiBaseUrl + url, {
14
+ method: 'POST',
15
+ body: data,
16
+ headers: {
17
+ 'Content-Type': 'application/json',
18
+ 'Authorization': 'IDKYC-TOKEN ' + store.token,
19
+ // 'ApiKey': '2E1DF612-E9F3-4B8A-9154-5256E412D90C',
20
+ },
21
+ });
22
+ if (!resp.ok) {
23
+ return new Error(resp.statusText);
24
+ }
25
+ return await resp.json();
26
+ }
27
+ catch (err) {
28
+ console.log(err);
29
+ return err;
30
+ }
31
+ }
32
+ async Get(url) {
33
+ try {
34
+ let resp = await fetch(store.apiBaseUrl + url, {
35
+ method: 'GET',
36
+ headers: {
37
+ 'Content-Type': 'application/json',
38
+ 'Authorization': 'IDKYC-TOKEN ' + store.token,
39
+ // 'ApiKey': '2E1DF612-E9F3-4B8A-9154-5256E412D90C',
40
+ },
41
+ });
42
+ if (!resp.ok) {
43
+ return new Error(resp.statusText);
44
+ }
45
+ return await resp.json();
46
+ }
47
+ catch (err) {
48
+ console.log(err);
49
+ return err;
50
+ }
51
+ }
52
+ async SendOTPCode(requestId, phoneNumber) {
53
+ let data = { requestId: requestId, phone: phoneNumber };
54
+ let jsonResp = await this.Post('/validation/otp/send', JSON.stringify(data));
55
+ if (typeof jsonResp != 'boolean') {
56
+ return false;
57
+ }
58
+ return jsonResp;
59
+ }
60
+ async CheckOTPCode(requestId, otpCode) {
61
+ let data = { requestId: requestId, otp: otpCode };
62
+ let jsonResp = await this.Post('/validation/otp/check', JSON.stringify(data));
63
+ if (typeof jsonResp != 'boolean') {
64
+ return false;
65
+ }
66
+ return jsonResp;
67
+ }
68
+ async AddIdentificationRequest(requestId, deviceInfo) {
69
+ let data = { requestId: requestId, clientDeviceInfo: deviceInfo };
70
+ let jsonResp = await this.Post('/validation/identity/insert', JSON.stringify(data));
71
+ if (typeof jsonResp.hasIdBack == 'boolean') {
72
+ store.hasIdBack = jsonResp.hasIdBack;
73
+ return true;
74
+ }
75
+ else {
76
+ return false;
77
+ }
78
+ }
79
+ async UploadFileForRequestB64(requestId, type, file) {
80
+ let data = {
81
+ requestId: requestId,
82
+ type: type,
83
+ data: await this.toBase64(file),
84
+ };
85
+ let respJson = await this.Post('/validation/upload/capture', JSON.stringify(data));
86
+ if (respJson && respJson.file_path) {
87
+ if (type == 'IdFront') {
88
+ return respJson.isValid;
89
+ }
90
+ return true;
91
+ }
92
+ else {
93
+ return false;
94
+ }
95
+ }
96
+ async UploadFileForRequest(requestId, type, file) {
97
+ try {
98
+ let data = new FormData();
99
+ data.append('requestId', requestId);
100
+ data.append('type', type);
101
+ data.append('file', file);
102
+ let resp = await fetch(store.apiBaseUrl + '/validation/upload/file', {
103
+ method: 'POST',
104
+ body: data,
105
+ });
106
+ if (!resp.ok) {
107
+ console.log(resp.statusText);
108
+ return false;
109
+ }
110
+ let respJson = await resp.json();
111
+ if (respJson && respJson.file_path) {
112
+ if (type == 'IdFront') {
113
+ return respJson.isValid;
114
+ }
115
+ return true;
116
+ }
117
+ else {
118
+ return false;
119
+ }
120
+ }
121
+ catch (err) {
122
+ console.log(err);
123
+ return false;
124
+ }
125
+ }
126
+ async GetAgreement(agreementType) {
127
+ try {
128
+ let resp = await this.Get('/validation/agreement/content?type=' + agreementType + '&requestId=' + store.requestId);
129
+ if (resp) {
130
+ return resp.htmlText;
131
+ }
132
+ return '';
133
+ }
134
+ catch (err) {
135
+ console.log(err);
136
+ return '';
137
+ }
138
+ }
139
+ async GenerateAgreement(agreementType) {
140
+ try {
141
+ let data = { requestId: store.requestId, documentType: agreementType };
142
+ let resp = await this.Post('/validation/agreement/generate', JSON.stringify(data));
143
+ if (typeof resp != 'boolean') {
144
+ return false;
145
+ }
146
+ return resp;
147
+ }
148
+ catch (err) {
149
+ console.log(err);
150
+ return false;
151
+ }
152
+ }
153
+ }
@@ -0,0 +1,98 @@
1
+ export class Cameras {
2
+ async GetCameras(deviceInfo) {
3
+ var allDevices = [];
4
+ const devices = await navigator.mediaDevices.enumerateDevices();
5
+ const videoDevices = devices.filter(device => device.kind === 'videoinput');
6
+ for (const device of videoDevices) {
7
+ const updatedConstraints = this.GetConstraints(device.deviceId, deviceInfo);
8
+ const stream = await navigator.mediaDevices.getUserMedia(updatedConstraints);
9
+ stream.getVideoTracks().forEach(track => {
10
+ if (deviceInfo.isFirefox) {
11
+ const settings = track.getSettings();
12
+ let facingMode = settings.facingMode && settings.facingMode.length > 0 ? settings.facingMode[0] : '';
13
+ facingMode = facingMode === 'e' ? 'environment' : facingMode;
14
+ allDevices.push({
15
+ deviceId: device.deviceId,
16
+ name: device.label,
17
+ height: settings.height,
18
+ width: settings.width,
19
+ frameRate: Number(settings.frameRate.max),
20
+ torch: false,
21
+ recommended: false,
22
+ facingMode: facingMode,
23
+ });
24
+ }
25
+ else {
26
+ const capabilities = track.getCapabilities();
27
+ let facingMode = capabilities.facingMode && capabilities.facingMode.length > 0 ? capabilities.facingMode[0] : '';
28
+ facingMode = facingMode === 'e' ? 'environment' : facingMode;
29
+ allDevices.push({
30
+ deviceId: device.deviceId,
31
+ name: device.label,
32
+ height: capabilities.height.max,
33
+ width: capabilities.width.max,
34
+ frameRate: Number(capabilities.frameRate.max),
35
+ torch: capabilities.torch,
36
+ recommended: false,
37
+ facingMode: facingMode,
38
+ });
39
+ }
40
+ });
41
+ stream.getTracks().forEach(track => {
42
+ track.stop();
43
+ });
44
+ }
45
+ if (allDevices.length > 0) {
46
+ allDevices = allDevices.sort((a, b) => b.frameRate - a.frameRate);
47
+ var firstOption = allDevices.find(i => i.name.indexOf('0,') != -1 && i.facingMode === 'environment');
48
+ if (firstOption) {
49
+ allDevices[allDevices.indexOf(firstOption)].recommended = true;
50
+ }
51
+ else {
52
+ var firstEnv = allDevices.find(i => i.facingMode === 'environment');
53
+ if (firstEnv) {
54
+ allDevices[allDevices.indexOf(firstEnv)].recommended = true;
55
+ }
56
+ }
57
+ }
58
+ return allDevices;
59
+ }
60
+ GetConstraints(selectedDeviceId, device, portrait = false) {
61
+ let constraints = {
62
+ audio: false,
63
+ video: {
64
+ frameRate: 30
65
+ }
66
+ };
67
+ if (selectedDeviceId) {
68
+ constraints.video.deviceId = {
69
+ exact: selectedDeviceId,
70
+ };
71
+ }
72
+ if (device.isWin) {
73
+ constraints.video.width = { ideal: 1280 };
74
+ }
75
+ else {
76
+ if (portrait) {
77
+ constraints.video.facingMode = 'user';
78
+ constraints.video.width = { ideal: 1280 };
79
+ constraints.video.height = { ideal: 720 };
80
+ }
81
+ else {
82
+ constraints.video.facingMode = 'environment';
83
+ constraints.video.width = { ideal: 740 };
84
+ constraints.video.aspectRatio = 1;
85
+ }
86
+ }
87
+ return constraints;
88
+ }
89
+ GetRecommendedCamera(cameras) {
90
+ if (cameras && cameras.length > 0) {
91
+ var recommDevice = cameras.find(c => c.recommended);
92
+ if (recommDevice) {
93
+ return recommDevice;
94
+ }
95
+ }
96
+ return null;
97
+ }
98
+ }
@@ -0,0 +1,79 @@
1
+ export default class Events {
2
+ static init(element) {
3
+ this.cameraModule = element;
4
+ }
5
+ static captureEvent(photos) {
6
+ this.cameraModule.dispatchEvent(new CustomEvent('capture', {
7
+ detail: {
8
+ photos,
9
+ },
10
+ bubbles: true,
11
+ cancelable: true,
12
+ composed: true,
13
+ }));
14
+ }
15
+ static recordingAvailable(recording) {
16
+ this.cameraModule.dispatchEvent(new CustomEvent('recordingAvailable', {
17
+ detail: {
18
+ recording,
19
+ },
20
+ bubbles: true,
21
+ cancelable: true,
22
+ composed: true,
23
+ }));
24
+ }
25
+ static closeEvent() {
26
+ this.cameraModule.dispatchEvent(new CustomEvent('close', {
27
+ bubbles: false,
28
+ cancelable: true,
29
+ composed: true,
30
+ }));
31
+ }
32
+ static cameraReadyEvent() {
33
+ this.cameraModule.dispatchEvent(new CustomEvent('cameraReady', {
34
+ bubbles: false,
35
+ cancelable: true,
36
+ composed: true,
37
+ }));
38
+ }
39
+ static errorEvent(error) {
40
+ this.cameraModule.dispatchEvent(new CustomEvent('error', {
41
+ detail: {
42
+ error,
43
+ },
44
+ bubbles: true,
45
+ cancelable: true,
46
+ composed: true,
47
+ }));
48
+ }
49
+ static detectionError(error) {
50
+ this.cameraModule.dispatchEvent(new CustomEvent('detectionError', {
51
+ detail: {
52
+ error,
53
+ },
54
+ bubbles: true,
55
+ cancelable: true,
56
+ composed: true,
57
+ }));
58
+ }
59
+ static loadedModels(loadedModels) {
60
+ this.cameraModule.dispatchEvent(new CustomEvent('loadedModels', {
61
+ detail: {
62
+ loadedModels,
63
+ },
64
+ bubbles: true,
65
+ cancelable: true,
66
+ composed: true,
67
+ }));
68
+ }
69
+ static detectorInitialized(initializationTime) {
70
+ this.cameraModule.dispatchEvent(new CustomEvent('detectorInitialized', {
71
+ detail: {
72
+ initializationTime,
73
+ },
74
+ bubbles: true,
75
+ cancelable: true,
76
+ composed: true,
77
+ }));
78
+ }
79
+ }
@@ -0,0 +1,20 @@
1
+ import ml5 from 'ml5';
2
+ export class ML5 {
3
+ constructor() {
4
+ this.init();
5
+ }
6
+ static getInstance() {
7
+ if (!ML5.instance) {
8
+ ML5.instance = new ML5();
9
+ }
10
+ return ML5.instance;
11
+ }
12
+ async init() {
13
+ return new Promise(async (resolve) => {
14
+ this.classifier = await ml5.imageClassifier('../../assets/buletin-v2/model.json');
15
+ this.faceapi = await ml5.faceApi({ withLandmarks: true, withDescriptors: false });
16
+ resolve();
17
+ console.log('ML5 LOADED!!!');
18
+ });
19
+ }
20
+ }
@@ -0,0 +1,223 @@
1
+ import Events from './Events';
2
+ import { IDML5Detector } from '../libs/IDML5Detector/IDML5Detector';
3
+ import { FaceML5Detector } from '../libs/FaceML5Detector/FaceML5Detector';
4
+ import { FacePose } from '../libs/FaceML5Detector/FacePose';
5
+ import { FacePosePick } from '../libs/FaceML5Detector/FacePose';
6
+ import { addExifInImg } from './security';
7
+ var ImageFormat;
8
+ (function (ImageFormat) {
9
+ ImageFormat["JPEG"] = "image/jpeg";
10
+ ImageFormat["PNG"] = "image/png";
11
+ })(ImageFormat || (ImageFormat = {}));
12
+ export class Stream {
13
+ constructor(device, _modelPath) {
14
+ this.streamPaused = false;
15
+ this.recordedChunks = [];
16
+ this.videoSize = { width: 0, height: 0 };
17
+ this.pauseStream = () => {
18
+ this.streamPaused = true;
19
+ this.mediaRecorder.pause();
20
+ this.videoElement.pause();
21
+ // this.dropMask();
22
+ // if (this.faceDetection) Detector.getInstance().stopDetector();
23
+ };
24
+ this.device = device;
25
+ this.idML5Detector = IDML5Detector.getInstance(this, device.isMobile);
26
+ this.faceML5Detector = FaceML5Detector.getInstance(this, device.isMobile);
27
+ }
28
+ setFaceDetection(val) {
29
+ this.faceDetection = val;
30
+ this.idDetection = !val;
31
+ }
32
+ setIdDetection(val) {
33
+ this.idDetection = val;
34
+ this.faceDetection = !val;
35
+ }
36
+ // public setProbabilityThreshold(val: number): void {
37
+ // Detector.getInstance().setProbabilityThreshold(val);
38
+ // }
39
+ setCallbackChangeTitle(fun) {
40
+ this.callbackChangeTitle = fun;
41
+ }
42
+ setCallbackStopAnimation(fun) {
43
+ this.callbackStopAnimation = fun;
44
+ }
45
+ setCallbackVideoStarted(fun) {
46
+ this.callbackVideoStarted = fun;
47
+ }
48
+ setCallbackErrors(fun) {
49
+ this.callbackErrors = fun;
50
+ }
51
+ setCallbackAutoCapturing(fun) {
52
+ this.callbackAutoCapturing = fun;
53
+ }
54
+ // public setCallbackFaceDetectionErrors(fun: (e: PipelineResult) => void): void {
55
+ // this.callbackFaceDetectionErrors = fun;
56
+ // }
57
+ setCallbackRecordingReady(fun) {
58
+ this.callbackRecordingReady = fun;
59
+ }
60
+ setCallbackTimeElapsed(fun) {
61
+ this.callbackTimeElapsed = fun;
62
+ }
63
+ static getInstance(device, modelPath) {
64
+ if (!Stream.instance) {
65
+ Stream.instance = new Stream(device, modelPath);
66
+ }
67
+ return Stream.instance;
68
+ }
69
+ // public returnErrors(errors: PipelineResult) {
70
+ // this.callbackFaceDetectionErrors(errors);
71
+ // }
72
+ autoCapturing() {
73
+ this.callbackAutoCapturing();
74
+ }
75
+ timeElapsed() {
76
+ this.callbackTimeElapsed();
77
+ }
78
+ updateHtmlElements(videoElement, canvasElement, component) {
79
+ this.videoElement = videoElement;
80
+ this.canvasElement = canvasElement;
81
+ this.idML5Detector.updateHtmlElements(this.videoElement, this.canvasElement, component);
82
+ this.faceML5Detector.updateHtmlElements(this.videoElement, this.canvasElement, component);
83
+ }
84
+ static orientationChange() { }
85
+ startStream(stream) {
86
+ if (this.stream)
87
+ this.stream.getTracks().forEach((track) => track.stop());
88
+ this.stream = stream;
89
+ if ('srcObject' in this.videoElement) {
90
+ this.videoElement.srcObject = stream;
91
+ }
92
+ else {
93
+ this.videoElement.src = window.URL.createObjectURL(stream);
94
+ }
95
+ this.videoElement.addEventListener('loadedmetadata', async (_e) => {
96
+ this.videoElement.play().then(() => {
97
+ this.streamPaused = false;
98
+ Events.cameraReadyEvent();
99
+ this.updateCanvasSize(this.canvasElement);
100
+ this.updateVideoSize(this.videoElement);
101
+ this.callbackVideoStarted();
102
+ if (this.idDetection)
103
+ this.startIdDetection();
104
+ if (this.faceDetection)
105
+ this.startFaceDetection();
106
+ });
107
+ }, false);
108
+ }
109
+ async initStream(stream) {
110
+ this.startStream(stream);
111
+ this.recordStream();
112
+ }
113
+ async resumeStream() {
114
+ this.streamPaused = false;
115
+ this.mediaRecorder.resume();
116
+ await this.videoElement.play();
117
+ // this.drawMask();
118
+ // if (this.faceDetection) await Detector.getInstance().startDetector();
119
+ }
120
+ recordStream() {
121
+ var options = { mimeType: 'video/webm;codecs=vp8', videoBitsPerSecond: 1500000 };
122
+ if (!MediaRecorder.isTypeSupported(options.mimeType)) {
123
+ if (this.device.isIos || this.device.isSafari)
124
+ options.mimeType = 'video/mp4;codecs:h264';
125
+ }
126
+ this.recordedChunks = [];
127
+ this.mediaRecorder = new MediaRecorder(this.stream, options);
128
+ this.mediaRecorder.ondataavailable = event => {
129
+ this.recordedChunks.push(event.data);
130
+ };
131
+ this.mediaRecorder.onstop = async () => {
132
+ this.saveVideoRecording(this.recordedChunks, options.mimeType);
133
+ this.recordedChunks = [];
134
+ };
135
+ this.mediaRecorder.start(); // Start recording, and dump data every second
136
+ }
137
+ async saveVideoRecording(videoTosave, mimeType) {
138
+ var blob = new Blob(videoTosave, {
139
+ type: mimeType.split(';')[0],
140
+ });
141
+ this.callbackRecordingReady(blob);
142
+ }
143
+ updateCanvasSize(canvas) {
144
+ this.videoSize = { width: this.videoElement.videoWidth, height: this.videoElement.videoHeight };
145
+ canvas.width = this.videoSize.width;
146
+ canvas.height = this.videoSize.height;
147
+ }
148
+ updateVideoSize(video) {
149
+ this.videoSize = { width: this.videoElement.videoWidth, height: this.videoElement.videoHeight };
150
+ video.width = this.videoSize.width;
151
+ video.height = this.videoSize.height;
152
+ }
153
+ dropStream() {
154
+ if (!this.streamStopped()) {
155
+ this.stream.getTracks().forEach((track) => track.stop());
156
+ this.videoElement.srcObject = null;
157
+ }
158
+ if (this.mediaRecorder && this.mediaRecorder.state != 'inactive') {
159
+ this.mediaRecorder.stop();
160
+ }
161
+ // if (this.faceDetection) Detector.getInstance().stopDetector();
162
+ }
163
+ streamStopped() {
164
+ return !(this.stream && this.stream.getTracks && this.stream.getTracks().length > 0);
165
+ }
166
+ takePhoto() {
167
+ return new Promise(async (resolve) => {
168
+ const canvas = document.createElement('canvas');
169
+ canvas.width = this.videoElement.videoWidth;
170
+ canvas.height = this.videoElement.videoHeight;
171
+ resolve([await this.getFrame(canvas)]);
172
+ });
173
+ }
174
+ getFrame(canvas) {
175
+ return new Promise(resolve => {
176
+ const context = canvas.getContext('2d');
177
+ context.drawImage(this.videoElement, 0, 0, canvas.width, canvas.height);
178
+ canvas.toBlob((frame) => {
179
+ if (frame.type === ImageFormat.JPEG && !this.device.isIos) {
180
+ try {
181
+ addExifInImg(frame, this.stream.getTracks()[0], this.videoSize).then(updatedFrame => resolve(updatedFrame));
182
+ }
183
+ catch (e) {
184
+ resolve(frame);
185
+ this.callbackErrors(e, false);
186
+ }
187
+ }
188
+ else {
189
+ resolve(frame);
190
+ }
191
+ }, ImageFormat.PNG, 1);
192
+ let outCanvContext = this.canvasElement.getContext('2d');
193
+ outCanvContext.drawImage(this.videoElement, 0, 0, this.canvasElement.width, this.canvasElement.height);
194
+ });
195
+ }
196
+ async startIdDetection() {
197
+ if (this.streamPaused)
198
+ return;
199
+ this.idML5Detector.initDetector();
200
+ }
201
+ async startFaceDetection() {
202
+ if (this.streamPaused)
203
+ return;
204
+ this.faceML5Detector.initDetector();
205
+ }
206
+ requestFacePose() {
207
+ var pose = FacePosePick.randomEnum(FacePose);
208
+ // var pose = FacePose.TiltLeft;
209
+ this.callbackChangeTitle(pose);
210
+ return pose;
211
+ }
212
+ changeFacePose() {
213
+ this.callbackChangeTitle(null);
214
+ }
215
+ changeIDPose(pose) {
216
+ this.callbackChangeTitle(pose);
217
+ }
218
+ stopAnimation() {
219
+ this.callbackStopAnimation();
220
+ }
221
+ }
222
+ window.addEventListener('resize', Stream.orientationChange, false);
223
+ window.addEventListener('orientationchange', Stream.orientationChange, false);
@@ -0,0 +1,10 @@
1
+ export function videoRatio(videoElement) {
2
+ const hRatio = videoElement.clientWidth / videoElement.videoWidth;
3
+ const vRatio = videoElement.clientHeight / videoElement.videoHeight;
4
+ return Math.min(hRatio, vRatio);
5
+ }
6
+ export function getVideoRatio(videoElement) {
7
+ const hRatio = videoElement.clientWidth / videoElement.videoWidth;
8
+ const vRatio = videoElement.clientHeight / videoElement.videoHeight;
9
+ return Math.min(hRatio, vRatio);
10
+ }