facecog-liveness-showcase 0.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 (229) hide show
  1. package/.browserslistrc +15 -0
  2. package/.dockerignore +48 -0
  3. package/.editorconfig +16 -0
  4. package/.eslintrc.json +47 -0
  5. package/.vercelignore +7 -0
  6. package/.vscode/extensions.json +5 -0
  7. package/.vscode/settings.json +3 -0
  8. package/DOCKER.md +221 -0
  9. package/Dockerfile +33 -0
  10. package/README.md +268 -0
  11. package/angular.json +156 -0
  12. package/capacitor.config.ts +9 -0
  13. package/docker-compose.dev.yml +20 -0
  14. package/docker-compose.yml +18 -0
  15. package/ionic.config.json +7 -0
  16. package/jest.config.js +38 -0
  17. package/nginx.conf +50 -0
  18. package/package.json +131 -0
  19. package/patches/ng-packagr+20.3.2.patch +60 -0
  20. package/projects/facecog-liveness-verification/README.md +295 -0
  21. package/projects/facecog-liveness-verification/ng-package.json +7 -0
  22. package/projects/facecog-liveness-verification/package.json +48 -0
  23. package/projects/facecog-liveness-verification/scripts/build-with-wrapper-copy.js +38 -0
  24. package/projects/facecog-liveness-verification/scripts/copy-wrapper-after-ngc.js +35 -0
  25. package/projects/facecog-liveness-verification/sources/FaceLivenessReactWrapper.tsx +320 -0
  26. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.generated.d.ts +28 -0
  27. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.generated.js +247 -0
  28. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.generated.js.map +1 -0
  29. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.js.map +1 -0
  30. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/FaceLivenessReactWrapper.ts +5 -0
  31. package/projects/facecog-liveness-verification/src/lib/components/aws-face-liveness/aws-face-liveness.component.ts +500 -0
  32. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.html +41 -0
  33. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.scss +234 -0
  34. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.spec.ts +158 -0
  35. package/projects/facecog-liveness-verification/src/lib/components/camera-permission/camera-permission.component.ts +58 -0
  36. package/projects/facecog-liveness-verification/src/lib/components/camera-verification/camera-verification.component.html +34 -0
  37. package/projects/facecog-liveness-verification/src/lib/components/camera-verification/camera-verification.component.ts +210 -0
  38. package/projects/facecog-liveness-verification/src/lib/components/dialogs/save-custom-pose-dialog.component.ts +174 -0
  39. package/projects/facecog-liveness-verification/src/lib/components/facetec-scan/facetec-scan.component.html +45 -0
  40. package/projects/facecog-liveness-verification/src/lib/components/facetec-scan/facetec-scan.component.scss +87 -0
  41. package/projects/facecog-liveness-verification/src/lib/components/facetec-scan/facetec-scan.component.ts +182 -0
  42. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.html +394 -0
  43. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.scss +1567 -0
  44. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.spec.ts +699 -0
  45. package/projects/facecog-liveness-verification/src/lib/components/intro/intro.component.ts +721 -0
  46. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.html +120 -0
  47. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.scss +611 -0
  48. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.spec.ts +605 -0
  49. package/projects/facecog-liveness-verification/src/lib/components/live-preview/live-preview.component.ts +524 -0
  50. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.html +73 -0
  51. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.scss +19 -0
  52. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.spec.ts +673 -0
  53. package/projects/facecog-liveness-verification/src/lib/components/liveness-flow/liveness-flow.component.ts +963 -0
  54. package/projects/facecog-liveness-verification/src/lib/components/liveness-verification/liveness-verification.component.html +38 -0
  55. package/projects/facecog-liveness-verification/src/lib/components/liveness-verification/liveness-verification.component.scss +10 -0
  56. package/projects/facecog-liveness-verification/src/lib/components/liveness-verification/liveness-verification.component.ts +233 -0
  57. package/projects/facecog-liveness-verification/src/lib/components/pose-selection/pose-selection.component.html +17 -0
  58. package/projects/facecog-liveness-verification/src/lib/components/pose-selection/pose-selection.component.spec.ts +35 -0
  59. package/projects/facecog-liveness-verification/src/lib/components/pose-selection/pose-selection.component.ts +33 -0
  60. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.html +17 -0
  61. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.scss +156 -0
  62. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.spec.ts +46 -0
  63. package/projects/facecog-liveness-verification/src/lib/components/processing/processing.component.ts +18 -0
  64. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.html +190 -0
  65. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.scss +534 -0
  66. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.spec.ts +286 -0
  67. package/projects/facecog-liveness-verification/src/lib/components/verification-result/verification-result.component.ts +155 -0
  68. package/projects/facecog-liveness-verification/src/lib/interfaces/analyze-response.interface.ts +16 -0
  69. package/projects/facecog-liveness-verification/src/lib/interfaces/aws-face-liveness.interface.ts +46 -0
  70. package/projects/facecog-liveness-verification/src/lib/interfaces/backend-adapter.interface.ts +21 -0
  71. package/projects/facecog-liveness-verification/src/lib/interfaces/backend-http-client.interface.ts +93 -0
  72. package/projects/facecog-liveness-verification/src/lib/interfaces/backend-response.interface.ts +9 -0
  73. package/projects/facecog-liveness-verification/src/lib/interfaces/camera-provider.interface.ts +107 -0
  74. package/projects/facecog-liveness-verification/src/lib/interfaces/category-info.interface.ts +9 -0
  75. package/projects/facecog-liveness-verification/src/lib/interfaces/custom-pose-data.interface.ts +14 -0
  76. package/projects/facecog-liveness-verification/src/lib/interfaces/custom-pose-repository.interface.ts +48 -0
  77. package/projects/facecog-liveness-verification/src/lib/interfaces/custom-pose-response.interface.ts +14 -0
  78. package/projects/facecog-liveness-verification/src/lib/interfaces/index.ts +52 -0
  79. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-action-result.interface.ts +13 -0
  80. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-config.interface.ts +17 -0
  81. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-metadata.interface.ts +17 -0
  82. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-result.interface.ts +24 -0
  83. package/projects/facecog-liveness-verification/src/lib/interfaces/liveness-verification-config.interface.ts +41 -0
  84. package/projects/facecog-liveness-verification/src/lib/interfaces/multi-backend-analyze-response.interface.ts +21 -0
  85. package/projects/facecog-liveness-verification/src/lib/interfaces/multi-backend-liveness-result.interface.ts +14 -0
  86. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-definition.interface.ts +35 -0
  87. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-keypoint.interface.ts +12 -0
  88. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-match-result.interface.ts +9 -0
  89. package/projects/facecog-liveness-verification/src/lib/interfaces/pose-verify-response.interface.ts +8 -0
  90. package/projects/facecog-liveness-verification/src/lib/interfaces/scan-results.interface.ts +29 -0
  91. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-plan.interface.ts +42 -0
  92. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-progress-event.interface.ts +12 -0
  93. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-session.interface.ts +72 -0
  94. package/projects/facecog-liveness-verification/src/lib/interfaces/verification-step-change-event.interface.ts +11 -0
  95. package/projects/facecog-liveness-verification/src/lib/interfaces/video-recording.interface.ts +9 -0
  96. package/projects/facecog-liveness-verification/src/lib/liveness-verification.module.ts +123 -0
  97. package/projects/facecog-liveness-verification/src/lib/models/constants/aws-face-liveness-component.token.ts +23 -0
  98. package/projects/facecog-liveness-verification/src/lib/models/constants/category-info.constant.ts +14 -0
  99. package/projects/facecog-liveness-verification/src/lib/models/constants/default-liveness-config.constant.ts +18 -0
  100. package/projects/facecog-liveness-verification/src/lib/models/constants/index.ts +5 -0
  101. package/projects/facecog-liveness-verification/src/lib/models/constants/liveness-verification-config.token.ts +16 -0
  102. package/projects/facecog-liveness-verification/src/lib/models/constants/pose-definitions.constant.ts +377 -0
  103. package/projects/facecog-liveness-verification/src/lib/models/index.ts +5 -0
  104. package/projects/facecog-liveness-verification/src/lib/models/utils/index.ts +2 -0
  105. package/projects/facecog-liveness-verification/src/lib/models/utils/pose.utils.spec.ts +76 -0
  106. package/projects/facecog-liveness-verification/src/lib/models/utils/pose.utils.ts +59 -0
  107. package/projects/facecog-liveness-verification/src/lib/services/aws-face-liveness.service.ts +49 -0
  108. package/projects/facecog-liveness-verification/src/lib/services/backend-http.service.spec.ts +111 -0
  109. package/projects/facecog-liveness-verification/src/lib/services/backend-http.service.ts +130 -0
  110. package/projects/facecog-liveness-verification/src/lib/services/backends/azure-backend.service.spec.ts +69 -0
  111. package/projects/facecog-liveness-verification/src/lib/services/backends/azure-backend.service.ts +72 -0
  112. package/projects/facecog-liveness-verification/src/lib/services/backends/facetec-backend.service.spec.ts +24 -0
  113. package/projects/facecog-liveness-verification/src/lib/services/backends/facetec-backend.service.ts +35 -0
  114. package/projects/facecog-liveness-verification/src/lib/services/backends/mock-backend.service.spec.ts +36 -0
  115. package/projects/facecog-liveness-verification/src/lib/services/backends/mock-backend.service.ts +39 -0
  116. package/projects/facecog-liveness-verification/src/lib/services/backends/openpose-backend.service.spec.ts +81 -0
  117. package/projects/facecog-liveness-verification/src/lib/services/backends/openpose-backend.service.ts +72 -0
  118. package/projects/facecog-liveness-verification/src/lib/services/backends/rekognition-analysis-backend.service.spec.ts +69 -0
  119. package/projects/facecog-liveness-verification/src/lib/services/backends/rekognition-analysis-backend.service.ts +83 -0
  120. package/projects/facecog-liveness-verification/src/lib/services/camera.service.spec.ts +200 -0
  121. package/projects/facecog-liveness-verification/src/lib/services/camera.service.ts +155 -0
  122. package/projects/facecog-liveness-verification/src/lib/services/custom-poses-api.service.ts +117 -0
  123. package/projects/facecog-liveness-verification/src/lib/services/index.ts +18 -0
  124. package/projects/facecog-liveness-verification/src/lib/services/liveness-backend.service.spec.ts +103 -0
  125. package/projects/facecog-liveness-verification/src/lib/services/liveness-backend.service.ts +61 -0
  126. package/projects/facecog-liveness-verification/src/lib/services/liveness-config.service.spec.ts +109 -0
  127. package/projects/facecog-liveness-verification/src/lib/services/liveness-config.service.ts +70 -0
  128. package/projects/facecog-liveness-verification/src/lib/services/liveness-orchestrator.service.spec.ts +144 -0
  129. package/projects/facecog-liveness-verification/src/lib/services/liveness-orchestrator.service.ts +162 -0
  130. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/hand-gesture-detection.service.ts +315 -0
  131. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/index.ts +5 -0
  132. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/openpose.service.ts +287 -0
  133. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/pose-comparison.service.ts +353 -0
  134. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/pose-matching.service.ts +2370 -0
  135. package/projects/facecog-liveness-verification/src/lib/services/pose-detection/reference-pose.service.ts +271 -0
  136. package/projects/facecog-liveness-verification/src/lib/services/pose-selection.service.spec.ts +183 -0
  137. package/projects/facecog-liveness-verification/src/lib/services/pose-selection.service.ts +179 -0
  138. package/projects/facecog-liveness-verification/src/lib/services/verification-api.service.spec.ts +159 -0
  139. package/projects/facecog-liveness-verification/src/lib/services/verification-api.service.ts +151 -0
  140. package/projects/facecog-liveness-verification/src/lib/services/verification-plan.service.spec.ts +184 -0
  141. package/projects/facecog-liveness-verification/src/lib/services/verification-plan.service.ts +94 -0
  142. package/projects/facecog-liveness-verification/src/lib/services/video-recorder.service.spec.ts +52 -0
  143. package/projects/facecog-liveness-verification/src/lib/services/video-recorder.service.ts +117 -0
  144. package/projects/facecog-liveness-verification/src/lib/types/detection-strategy.type.ts +5 -0
  145. package/projects/facecog-liveness-verification/src/lib/types/index.ts +7 -0
  146. package/projects/facecog-liveness-verification/src/lib/types/liveness-action.type.ts +31 -0
  147. package/projects/facecog-liveness-verification/src/lib/types/liveness-backend.type.ts +5 -0
  148. package/projects/facecog-liveness-verification/src/lib/types/pose-category.type.ts +5 -0
  149. package/projects/facecog-liveness-verification/src/lib/types/pose-difficulty.type.ts +5 -0
  150. package/projects/facecog-liveness-verification/src/lib/types/verification-flow-step.type.ts +5 -0
  151. package/projects/facecog-liveness-verification/src/lib/types/verification-step-kind.type.ts +4 -0
  152. package/projects/facecog-liveness-verification/src/public-api.ts +150 -0
  153. package/projects/facecog-liveness-verification/tsconfig.lib.json +20 -0
  154. package/projects/facecog-liveness-verification/tsconfig.lib.prod.json +11 -0
  155. package/projects/facecog-liveness-verification/tsconfig.spec.json +13 -0
  156. package/projects/facecog-liveness-verification/tsconfig.wrapper.json +15 -0
  157. package/projects/facecog-liveness-verification-test/src/app/app-routing.module.ts +22 -0
  158. package/projects/facecog-liveness-verification-test/src/app/app.component.html +3 -0
  159. package/projects/facecog-liveness-verification-test/src/app/app.component.scss +0 -0
  160. package/projects/facecog-liveness-verification-test/src/app/app.component.ts +11 -0
  161. package/projects/facecog-liveness-verification-test/src/app/app.module.ts +27 -0
  162. package/projects/facecog-liveness-verification-test/src/app/home/home-routing.module.ts +16 -0
  163. package/projects/facecog-liveness-verification-test/src/app/home/home.module.ts +19 -0
  164. package/projects/facecog-liveness-verification-test/src/app/home/home.page.html +39 -0
  165. package/projects/facecog-liveness-verification-test/src/app/home/home.page.scss +97 -0
  166. package/projects/facecog-liveness-verification-test/src/app/home/home.page.spec.ts +24 -0
  167. package/projects/facecog-liveness-verification-test/src/app/home/home.page.ts +92 -0
  168. package/projects/facecog-liveness-verification-test/src/app/home/verification-modal.component.ts +106 -0
  169. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Bold_0.ttf +0 -0
  170. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Medium_0.ttf +0 -0
  171. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Regular_0.ttf +0 -0
  172. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-SemiBold_0.ttf +0 -0
  173. package/projects/facecog-liveness-verification-test/src/assets/fonts/gilroy/Gilroy-Thin_0.ttf +0 -0
  174. package/projects/facecog-liveness-verification-test/src/assets/icon/favicon.png +0 -0
  175. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Five_Fingers_Left.jpg +0 -0
  176. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Left_Palm.jpg +0 -0
  177. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Ok_Sign_Right.jpg +0 -0
  178. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Peace_Sign_Left.jpg +0 -0
  179. package/projects/facecog-liveness-verification-test/src/assets/images/poses/README.md +77 -0
  180. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Right_Palm.jpg +0 -0
  181. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Speak_Phrase.jpg +0 -0
  182. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Three_Fingers_Right.jpg +0 -0
  183. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Thumbs_Up_Left.jpg +0 -0
  184. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Thumbs_Up_Right.jpg +0 -0
  185. package/projects/facecog-liveness-verification-test/src/assets/images/poses/Wave_Right.jpg +0 -0
  186. package/projects/facecog-liveness-verification-test/src/assets/images/poses/blink.jpeg +0 -0
  187. package/projects/facecog-liveness-verification-test/src/assets/images/poses/blink_twice.jpeg +0 -0
  188. package/projects/facecog-liveness-verification-test/src/assets/images/poses/center_face.png +0 -0
  189. package/projects/facecog-liveness-verification-test/src/assets/images/poses/clap.jpeg +0 -0
  190. package/projects/facecog-liveness-verification-test/src/assets/images/poses/cover_mouth.png +0 -0
  191. package/projects/facecog-liveness-verification-test/src/assets/images/poses/cover_right_eye.png +0 -0
  192. package/projects/facecog-liveness-verification-test/src/assets/images/poses/cross_arms.png +0 -0
  193. package/projects/facecog-liveness-verification-test/src/assets/images/poses/face_straight.png +0 -0
  194. package/projects/facecog-liveness-verification-test/src/assets/images/poses/follow_dot.png +0 -0
  195. package/projects/facecog-liveness-verification-test/src/assets/images/poses/look_down.png +0 -0
  196. package/projects/facecog-liveness-verification-test/src/assets/images/poses/look_up.png +0 -0
  197. package/projects/facecog-liveness-verification-test/src/assets/images/poses/move_closer.png +0 -0
  198. package/projects/facecog-liveness-verification-test/src/assets/images/poses/nod.png +0 -0
  199. package/projects/facecog-liveness-verification-test/src/assets/images/poses/open_mouth.png +0 -0
  200. package/projects/facecog-liveness-verification-test/src/assets/images/poses/raise_eyebrow.png +0 -0
  201. package/projects/facecog-liveness-verification-test/src/assets/images/poses/rotate_face.jpeg +0 -0
  202. package/projects/facecog-liveness-verification-test/src/assets/images/poses/shake_head.jpeg +0 -0
  203. package/projects/facecog-liveness-verification-test/src/assets/images/poses/smile.png +0 -0
  204. package/projects/facecog-liveness-verification-test/src/assets/images/poses/tilt_left.png +0 -0
  205. package/projects/facecog-liveness-verification-test/src/assets/images/poses/tilt_right.png +0 -0
  206. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_chin_left.jpg +0 -0
  207. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_left_cheek.jpeg +0 -0
  208. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_nose_right.png +0 -0
  209. package/projects/facecog-liveness-verification-test/src/assets/images/poses/touch_right_cheek.jpeg +0 -0
  210. package/projects/facecog-liveness-verification-test/src/assets/images/poses/turn_left.png +0 -0
  211. package/projects/facecog-liveness-verification-test/src/assets/images/poses/turn_right.png +0 -0
  212. package/projects/facecog-liveness-verification-test/src/assets/images/poses/wink.jpeg +0 -0
  213. package/projects/facecog-liveness-verification-test/src/assets/images/reference-pose.jpg +0 -0
  214. package/projects/facecog-liveness-verification-test/src/assets/shapes.svg +1 -0
  215. package/projects/facecog-liveness-verification-test/src/environments/environment.prod.ts +4 -0
  216. package/projects/facecog-liveness-verification-test/src/environments/environment.ts +17 -0
  217. package/projects/facecog-liveness-verification-test/src/global.scss +288 -0
  218. package/projects/facecog-liveness-verification-test/src/index.html +31 -0
  219. package/projects/facecog-liveness-verification-test/src/main.ts +6 -0
  220. package/projects/facecog-liveness-verification-test/src/polyfills.ts +55 -0
  221. package/projects/facecog-liveness-verification-test/src/theme/nextsapien-theme.scss +174 -0
  222. package/projects/facecog-liveness-verification-test/src/theme/variables.scss +2 -0
  223. package/projects/facecog-liveness-verification-test/src/zone-flags.ts +6 -0
  224. package/projects/facecog-liveness-verification-test/tsconfig.app.json +15 -0
  225. package/projects/facecog-liveness-verification-test/tsconfig.spec.json +14 -0
  226. package/setup-jest.ts +118 -0
  227. package/tsconfig.json +41 -0
  228. package/tsconfig.spec.json +15 -0
  229. package/vercel.json +24 -0
@@ -0,0 +1,117 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { VideoRecording } from '../interfaces/video-recording.interface';
3
+
4
+ @Injectable({
5
+ providedIn: 'root'
6
+ })
7
+ export class VideoRecorderService {
8
+ private mediaRecorder: MediaRecorder | null = null;
9
+ private recordedChunks: Blob[] = [];
10
+ private startTime: number = 0;
11
+
12
+ constructor() {}
13
+
14
+ /**
15
+ * Start recording video from the provided stream
16
+ */
17
+ startRecording(stream: MediaStream): Promise<void> {
18
+ return new Promise((resolve, reject) => {
19
+ try {
20
+ this.recordedChunks = [];
21
+
22
+ const mimeType = this.getSupportedMimeType();
23
+
24
+ this.mediaRecorder = new MediaRecorder(stream, {
25
+ mimeType,
26
+ videoBitsPerSecond: 2500000
27
+ });
28
+
29
+ this.mediaRecorder.ondataavailable = (event) => {
30
+ if (event.data && event.data.size > 0) {
31
+ this.recordedChunks.push(event.data);
32
+ }
33
+ };
34
+
35
+ this.mediaRecorder.onerror = (event: Event) => {
36
+ console.error('MediaRecorder error:', event);
37
+ reject(new Error('Recording failed'));
38
+ };
39
+
40
+ this.mediaRecorder.start(100);
41
+ this.startTime = Date.now();
42
+ resolve();
43
+ } catch (error) {
44
+ reject(error);
45
+ }
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Stop recording and return the video blob
51
+ */
52
+ stopRecording(): Promise<VideoRecording> {
53
+ return new Promise((resolve, reject) => {
54
+ if (!this.mediaRecorder) {
55
+ reject(new Error('No active recording'));
56
+ return;
57
+ }
58
+
59
+ this.mediaRecorder.onstop = () => {
60
+ const duration = (Date.now() - this.startTime) / 1000;
61
+ const blob = new Blob(this.recordedChunks, {
62
+ type: this.getSupportedMimeType()
63
+ });
64
+ const sizeMB = blob.size / (1024 * 1024);
65
+
66
+ resolve({
67
+ blob,
68
+ sizeMB,
69
+ duration
70
+ });
71
+
72
+ this.recordedChunks = [];
73
+ this.mediaRecorder = null;
74
+ };
75
+
76
+ this.mediaRecorder.stop();
77
+ });
78
+ }
79
+
80
+ /**
81
+ * Get supported MIME type for video recording
82
+ */
83
+ private getSupportedMimeType(): string {
84
+ const types = [
85
+ 'video/webm;codecs=vp9',
86
+ 'video/webm;codecs=vp8',
87
+ 'video/webm',
88
+ 'video/mp4'
89
+ ];
90
+
91
+ for (const type of types) {
92
+ if (MediaRecorder.isTypeSupported(type)) {
93
+ return type;
94
+ }
95
+ }
96
+
97
+ return 'video/webm';
98
+ }
99
+
100
+ /**
101
+ * Check if recording is in progress
102
+ */
103
+ isRecording(): boolean {
104
+ return this.mediaRecorder !== null && this.mediaRecorder.state === 'recording';
105
+ }
106
+
107
+ /**
108
+ * Cleanup resources
109
+ */
110
+ cleanup(): void {
111
+ if (this.mediaRecorder && this.mediaRecorder.state === 'recording') {
112
+ this.mediaRecorder.stop();
113
+ }
114
+ this.mediaRecorder = null;
115
+ this.recordedChunks = [];
116
+ }
117
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Detection strategy types for pose verification
3
+ */
4
+ export type DetectionStrategy = 'face-api' | 'openpose' | 'combined';
5
+
@@ -0,0 +1,7 @@
1
+ export { LivenessBackend } from './liveness-backend.type';
2
+ export { VerificationFlowStep } from './verification-flow-step.type';
3
+ export { LivenessAction } from './liveness-action.type';
4
+ export { PoseCategory } from './pose-category.type';
5
+ export { PoseDifficulty } from './pose-difficulty.type';
6
+ export { DetectionStrategy } from './detection-strategy.type';
7
+ export { VerificationStepKind } from './verification-step-kind.type';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Liveness action types for verification challenges
3
+ */
4
+ export type LivenessAction =
5
+ | 'face-center'
6
+ | 'turn-left'
7
+ | 'turn-right'
8
+ | 'tilt-left'
9
+ | 'tilt-right'
10
+ | 'look-up'
11
+ | 'look-down'
12
+ | 'blink'
13
+ | 'blink-twice'
14
+ | 'wink'
15
+ | 'follow-dot'
16
+ | 'nod'
17
+ | 'shake-head'
18
+ | 'smile'
19
+ | 'open-mouth'
20
+ | 'speak-phrase'
21
+ | 'raise-eyebrows'
22
+ | 'rotate-face'
23
+ | 'smile-thumbs-up'
24
+ | 'hand-gesture'
25
+ | 'wave'
26
+ | 'clap'
27
+ | 'cross-arms'
28
+ | 'point'
29
+ | 'combined-pose'
30
+ | 'custom-pose';
31
+
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Supported liveness verification backends
3
+ */
4
+ export type LivenessBackend = 'amazon' | 'openpose' | 'facetec' | 'azure' | 'mock';
5
+
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Pose category types
3
+ */
4
+ export type PoseCategory = 'face' | 'head' | 'hand' | 'gesture' | 'combined';
5
+
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Pose difficulty levels
3
+ */
4
+ export type PoseDifficulty = 'easy' | 'medium' | 'hard';
5
+
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Flow step types for verification process
3
+ */
4
+ export type VerificationFlowStep = 'intro' | 'permission' | 'preview' | 'facetec' | 'processing' | 'result';
5
+
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Type of verification step in the sequential flow
3
+ */
4
+ export type VerificationStepKind = 'gesture' | 'facetec';
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @naniteninja/liveness-verification
3
+ *
4
+ * Angular library for liveness verification with pose detection and multi-backend support.
5
+ *
6
+ * @example Basic Usage
7
+ * ```typescript
8
+ * // In your module
9
+ * import { LivenessVerificationModule } from '@naniteninja/liveness-verification';
10
+ *
11
+ * @NgModule({
12
+ * imports: [
13
+ * LivenessVerificationModule.forRoot({
14
+ * apiUrl: 'https://api.example.com',
15
+ * backends: ['amazon', 'facetec']
16
+ * })
17
+ * ]
18
+ * })
19
+ * export class AppModule {}
20
+ *
21
+ * // In your template
22
+ * <facecog-liveness-verification
23
+ * [pose]="5"
24
+ * (verificationComplete)="onVerificationComplete($event)">
25
+ * </facecog-liveness-verification>
26
+ * ```
27
+ *
28
+ * @example Standalone Usage
29
+ * ```typescript
30
+ * import {
31
+ * LivenessVerificationComponent,
32
+ * provideLivenessVerification
33
+ * } from '@naniteninja/liveness-verification';
34
+ *
35
+ * bootstrapApplication(AppComponent, {
36
+ * providers: [
37
+ * provideLivenessVerification({ backends: ['mock'] })
38
+ * ]
39
+ * });
40
+ * ```
41
+ */
42
+
43
+ // Module
44
+ export { LivenessVerificationModule, provideLivenessVerification, provideLivenessFlow } from './lib/liveness-verification.module';
45
+
46
+ // Components
47
+ export { LivenessVerificationComponent } from './lib/components/liveness-verification/liveness-verification.component';
48
+ export { PoseSelectionComponent } from './lib/components/pose-selection/pose-selection.component';
49
+ export { CameraVerificationComponent, CapturedVerificationData } from './lib/components/camera-verification/camera-verification.component';
50
+ export { VerificationResultComponent } from './lib/components/verification-result/verification-result.component';
51
+ export { CameraPermissionComponent } from './lib/components/camera-permission/camera-permission.component';
52
+ export { ProcessingComponent } from './lib/components/processing/processing.component';
53
+ export { SaveCustomPoseDialogComponent } from './lib/components/dialogs/save-custom-pose-dialog.component';
54
+ export { IntroComponent } from './lib/components/intro/intro.component';
55
+ export { LivePreviewComponent } from './lib/components/live-preview/live-preview.component';
56
+ export { FaceTecScanComponent } from './lib/components/facetec-scan/facetec-scan.component';
57
+ export { LivenessFlowComponent } from './lib/components/liveness-flow/liveness-flow.component';
58
+ export { AwsFaceLivenessComponent } from './lib/components/aws-face-liveness/aws-face-liveness.component';
59
+
60
+ // Types
61
+ export { LivenessBackend } from './lib/types/liveness-backend.type';
62
+ export { VerificationFlowStep } from './lib/types/verification-flow-step.type';
63
+ export { LivenessAction } from './lib/types/liveness-action.type';
64
+ export { PoseCategory } from './lib/types/pose-category.type';
65
+ export { PoseDifficulty } from './lib/types/pose-difficulty.type';
66
+ export { DetectionStrategy } from './lib/types/detection-strategy.type';
67
+ export { VerificationStepKind } from './lib/types/verification-step-kind.type';
68
+
69
+ // Interfaces
70
+ export { LivenessVerificationConfig } from './lib/interfaces/liveness-verification-config.interface';
71
+ export { VerificationStepChangeEvent } from './lib/interfaces/verification-step-change-event.interface';
72
+ export { VerificationProgressEvent } from './lib/interfaces/verification-progress-event.interface';
73
+ export { LivenessConfig } from './lib/interfaces/liveness-config.interface';
74
+ export { LivenessMetadata } from './lib/interfaces/liveness-metadata.interface';
75
+ export { AnalyzeResponse } from './lib/interfaces/analyze-response.interface';
76
+ export { MultiBackendAnalyzeResponse } from './lib/interfaces/multi-backend-analyze-response.interface';
77
+ export { LivenessResult } from './lib/interfaces/liveness-result.interface';
78
+ export { PoseMatchResult } from './lib/interfaces/pose-match-result.interface';
79
+ export { LivenessActionResult } from './lib/interfaces/liveness-action-result.interface';
80
+ export { VideoRecording } from './lib/interfaces/video-recording.interface';
81
+ export { BackendResponse } from './lib/interfaces/backend-response.interface';
82
+ export { MultiBackendLivenessResult } from './lib/interfaces/multi-backend-liveness-result.interface';
83
+ export { PoseKeypoint } from './lib/interfaces/pose-keypoint.interface';
84
+ export { PoseDefinition } from './lib/interfaces/pose-definition.interface';
85
+ export { CategoryInfo } from './lib/interfaces/category-info.interface';
86
+ export { CustomPoseData } from './lib/interfaces/custom-pose-data.interface';
87
+ export { CustomPoseResponse } from './lib/interfaces/custom-pose-response.interface';
88
+ export { PoseVerifyResponse } from './lib/interfaces/pose-verify-response.interface';
89
+ export { VerificationStep, VerificationPlan, GestureResult, FaceTecResult } from './lib/interfaces/verification-plan.interface';
90
+ export {
91
+ VerificationSessionStartRequest,
92
+ VerificationSessionStartResponse,
93
+ VerifyGesturesRequest,
94
+ VerifyGesturesResponse,
95
+ VerifyFaceTecRequest,
96
+ VerifyFaceTecResponse,
97
+ VerifyFinalizeResponse
98
+ } from './lib/interfaces/verification-session.interface';
99
+ export { AwsFaceLivenessSessionResponse, AwsFaceLivenessResultsResponse, AwsCredentialsResponse } from './lib/interfaces/aws-face-liveness.interface';
100
+ export { FaceTecScanResult, AwsFaceLivenessScanResult } from './lib/interfaces/scan-results.interface';
101
+
102
+ // Constants
103
+ export { DEFAULT_LIVENESS_CONFIG } from './lib/models/constants/default-liveness-config.constant';
104
+ export { LIVENESS_VERIFICATION_CONFIG } from './lib/models/constants/liveness-verification-config.token';
105
+ export { AWS_FACE_LIVENESS_COMPONENT } from './lib/models/constants/aws-face-liveness-component.token';
106
+ export { POSE_DEFINITIONS } from './lib/models/constants/pose-definitions.constant';
107
+ export { CATEGORY_INFO } from './lib/models/constants/category-info.constant';
108
+
109
+ // Utils
110
+ export {
111
+ getPosesByCategory,
112
+ getPosesByDifficulty,
113
+ getPoseById,
114
+ customPoseToPoseDefinition,
115
+ mergeCustomPoses,
116
+ getCustomPosesOnly
117
+ } from './lib/models/utils/pose.utils';
118
+
119
+ // Services
120
+ export { LivenessConfigService } from './lib/services/liveness-config.service';
121
+ export { PoseSelectionService, SelectedPoseInfo } from './lib/services/pose-selection.service';
122
+ export { CameraService } from './lib/services/camera.service';
123
+ export { VideoRecorderService } from './lib/services/video-recorder.service';
124
+ export { BackendHttpService } from './lib/services/backend-http.service';
125
+ export { CustomPosesApiService } from './lib/services/custom-poses-api.service';
126
+ export { VerificationPlanService } from './lib/services/verification-plan.service';
127
+ export { VerificationApiService } from './lib/services/verification-api.service';
128
+ export { AwsFaceLivenessService } from './lib/services/aws-face-liveness.service';
129
+ export { LivenessBackendService } from './lib/services/liveness-backend.service';
130
+
131
+ // Provider/Backend Abstractions (Interfaces & Injection Tokens)
132
+ export { ICameraProvider, CAMERA_PROVIDER, BrightnessData } from './lib/interfaces/camera-provider.interface';
133
+ export { ICustomPoseRepository, CUSTOM_POSE_REPOSITORY } from './lib/interfaces/custom-pose-repository.interface';
134
+ export { IBackendAdapter } from './lib/interfaces/backend-adapter.interface';
135
+ export { IBackendHttpClient, BACKEND_HTTP_CLIENT, SessionResponse } from './lib/interfaces/backend-http-client.interface';
136
+
137
+ // Backend Services
138
+ export { MockBackendService } from './lib/services/backends/mock-backend.service';
139
+ export { RekognitionAnalysisBackendService, AmazonBackendService } from './lib/services/backends/rekognition-analysis-backend.service';
140
+ export { OpenPoseBackendService } from './lib/services/backends/openpose-backend.service';
141
+ export { FaceTecBackendService } from './lib/services/backends/facetec-backend.service';
142
+ export { AzureBackendService } from './lib/services/backends/azure-backend.service';
143
+ export { LivenessOrchestratorService } from './lib/services/liveness-orchestrator.service';
144
+
145
+ // Pose Detection Services
146
+ export { OpenposeService, PoseKeypoints } from './lib/services/pose-detection/openpose.service';
147
+ export { HandGestureDetectionService, HandGestureResult } from './lib/services/pose-detection/hand-gesture-detection.service';
148
+ export { ReferencePoseService, ReferencePose } from './lib/services/pose-detection/reference-pose.service';
149
+ export { PoseComparisonService, PoseComparisonResult } from './lib/services/pose-detection/pose-comparison.service';
150
+ export { PoseMatchingService } from './lib/services/pose-detection/pose-matching.service';
@@ -0,0 +1,20 @@
1
+ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
+ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
+ {
4
+ "extends": "../../tsconfig.json",
5
+ "compilerOptions": {
6
+ "outDir": "../../out-tsc/lib",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "inlineSources": true,
10
+ "types": [],
11
+ "allowJs": true
12
+ },
13
+ "include": [
14
+ "src/**/*.ts",
15
+ "src/**/*.js"
16
+ ],
17
+ "exclude": [
18
+ "**/*.spec.ts"
19
+ ]
20
+ }
@@ -0,0 +1,11 @@
1
+ /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
+ /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
+ {
4
+ "extends": "./tsconfig.lib.json",
5
+ "compilerOptions": {
6
+ "declarationMap": false
7
+ },
8
+ "angularCompilerOptions": {
9
+ "compilationMode": "partial"
10
+ }
11
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../out-tsc/spec",
5
+ "types": ["jest"],
6
+ "esModuleInterop": true,
7
+ "emitDecoratorMetadata": true
8
+ },
9
+ "include": [
10
+ "src/**/*.ts",
11
+ "src/**/*.spec.ts"
12
+ ]
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "src/lib/components/aws-face-liveness",
5
+ "rootDir": "sources",
6
+ "declaration": false,
7
+ "declarationMap": false,
8
+ "module": "esnext",
9
+ "moduleResolution": "node",
10
+ "jsx": "react-jsx",
11
+ "noEmit": false
12
+ },
13
+ "include": ["sources/FaceLivenessReactWrapper.tsx"],
14
+ "exclude": []
15
+ }
@@ -0,0 +1,22 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
3
+
4
+ const routes: Routes = [
5
+ {
6
+ path: 'home',
7
+ loadComponent: () => import('./home/home.page').then(m => m.HomePage)
8
+ },
9
+ {
10
+ path: '',
11
+ redirectTo: 'home',
12
+ pathMatch: 'full'
13
+ },
14
+ ];
15
+
16
+ @NgModule({
17
+ imports: [
18
+ RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
19
+ ],
20
+ exports: [RouterModule]
21
+ })
22
+ export class AppRoutingModule { }
@@ -0,0 +1,3 @@
1
+ <ion-app>
2
+ <ion-router-outlet></ion-router-outlet>
3
+ </ion-app>
@@ -0,0 +1,11 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'app-root',
5
+ templateUrl: 'app.component.html',
6
+ styleUrls: ['app.component.scss'],
7
+ standalone: false,
8
+ })
9
+ export class AppComponent {
10
+ constructor() {}
11
+ }
@@ -0,0 +1,27 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { BrowserModule } from '@angular/platform-browser';
3
+ import { RouteReuseStrategy } from '@angular/router';
4
+ import { HttpClientModule } from '@angular/common/http';
5
+
6
+ import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
7
+ import { provideLivenessFlow } from '@naniteninja/liveness-verification';
8
+
9
+ import { AppComponent } from './app.component';
10
+ import { AppRoutingModule } from './app-routing.module';
11
+ import { environment } from '../environments/environment';
12
+
13
+ @NgModule({
14
+ declarations: [AppComponent],
15
+ imports: [
16
+ BrowserModule,
17
+ HttpClientModule,
18
+ IonicModule.forRoot(),
19
+ AppRoutingModule
20
+ ],
21
+ providers: [
22
+ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
23
+ ...provideLivenessFlow({ apiUrl: environment.apiUrl })
24
+ ],
25
+ bootstrap: [AppComponent],
26
+ })
27
+ export class AppModule {}
@@ -0,0 +1,16 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { RouterModule, Routes } from '@angular/router';
3
+ import { HomePage } from './home.page';
4
+
5
+ const routes: Routes = [
6
+ {
7
+ path: '',
8
+ component: HomePage,
9
+ }
10
+ ];
11
+
12
+ @NgModule({
13
+ imports: [RouterModule.forChild(routes)],
14
+ exports: [RouterModule]
15
+ })
16
+ export class HomePageRoutingModule {}
@@ -0,0 +1,19 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { IonicModule } from '@ionic/angular';
4
+ import { FormsModule } from '@angular/forms';
5
+ import { HomePage } from './home.page';
6
+
7
+ import { HomePageRoutingModule } from './home-routing.module';
8
+
9
+
10
+ @NgModule({
11
+ imports: [
12
+ CommonModule,
13
+ FormsModule,
14
+ IonicModule,
15
+ HomePageRoutingModule,
16
+ HomePage
17
+ ]
18
+ })
19
+ export class HomePageModule {}
@@ -0,0 +1,39 @@
1
+ <ion-header>
2
+ <ion-toolbar color="primary">
3
+ <ion-title>Liveness Verification Showcase</ion-title>
4
+ </ion-toolbar>
5
+ </ion-header>
6
+
7
+ <ion-content class="ion-padding">
8
+ <div class="showcase-container">
9
+ <div class="showcase-header">
10
+ <ion-icon name="shield-checkmark" color="primary" class="hero-icon"></ion-icon>
11
+ <h1>Verification Showcase</h1>
12
+ <p>Test the liveness verification flow as it would appear inside a host application modal.</p>
13
+ </div>
14
+
15
+ <div class="showcase-actions">
16
+ <ion-button expand="block" (click)="openVerificationModal()">
17
+ <ion-icon slot="start" name="person-circle"></ion-icon>
18
+ Start Verification (Modal)
19
+ </ion-button>
20
+
21
+ <ion-button expand="block" fill="outline" (click)="openPoseSpecificModal()">
22
+ <ion-icon slot="start" name="camera"></ion-icon>
23
+ Pose-Specific Verification (Modal)
24
+ </ion-button>
25
+ </div>
26
+
27
+ <div class="last-result" *ngIf="lastResult">
28
+ <h3>Last Result</h3>
29
+ <ion-card [color]="lastResult.success ? 'success' : 'danger'">
30
+ <ion-card-content>
31
+ <p><strong>{{ lastResult.success ? 'Verification Successful' : 'Verification Failed' }}</strong></p>
32
+ <p *ngIf="lastResult.confidence">Confidence: {{ (lastResult.confidence * 100).toFixed(1) }}%</p>
33
+ <p *ngIf="lastResult.error">Error: {{ lastResult.error }}</p>
34
+ <p *ngIf="lastResult.metadata?.backend">Backend: {{ lastResult.metadata.backend }}</p>
35
+ </ion-card-content>
36
+ </ion-card>
37
+ </div>
38
+ </div>
39
+ </ion-content>
@@ -0,0 +1,97 @@
1
+ .showcase-container {
2
+ max-width: 480px;
3
+ margin: 0 auto;
4
+ padding: 24px 0;
5
+ }
6
+
7
+ .showcase-header {
8
+ text-align: center;
9
+ margin-bottom: 40px;
10
+
11
+ .hero-icon {
12
+ font-size: 80px;
13
+ margin-bottom: 16px;
14
+ }
15
+
16
+ h1 {
17
+ font-size: 24px;
18
+ font-weight: 700;
19
+ margin: 0 0 8px;
20
+ }
21
+
22
+ p {
23
+ font-size: 15px;
24
+ color: var(--ion-color-medium);
25
+ line-height: 1.5;
26
+ margin: 0;
27
+ }
28
+ }
29
+
30
+ .showcase-actions {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 12px;
34
+ margin-bottom: 32px;
35
+ }
36
+
37
+ .last-result {
38
+ h3 {
39
+ font-size: 16px;
40
+ font-weight: 600;
41
+ margin: 0 0 12px;
42
+ color: var(--ion-text-color);
43
+ }
44
+
45
+ ion-card {
46
+ margin: 0;
47
+ }
48
+
49
+ p {
50
+ margin: 4px 0;
51
+ font-size: 14px;
52
+ }
53
+ }
54
+
55
+ .verification-modal-wrapper {
56
+ display: flex;
57
+ flex-direction: column;
58
+ height: 100%;
59
+ width: 100%;
60
+ background: var(--ion-background-color, #fff);
61
+ }
62
+
63
+ .verification-modal-header {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+ padding: 12px 16px;
68
+ background: var(--ion-color-primary);
69
+ color: #fff;
70
+ flex-shrink: 0;
71
+
72
+ h2 {
73
+ margin: 0;
74
+ font-size: 18px;
75
+ font-weight: 600;
76
+ }
77
+
78
+ button {
79
+ background: none;
80
+ border: none;
81
+ color: #fff;
82
+ font-size: 24px;
83
+ cursor: pointer;
84
+ padding: 4px;
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ }
89
+ }
90
+
91
+ .verification-modal-body {
92
+ flex: 1;
93
+ min-height: 0;
94
+ overflow: hidden;
95
+ display: flex;
96
+ flex-direction: column;
97
+ }