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,120 @@
1
+ <div class="live-preview-container">
2
+ <!-- Camera unavailable overlay -->
3
+ <div class="camera-error-container" *ngIf="cameraError() !== 'none'">
4
+ <div class="camera-error-content">
5
+ <div class="error-icon-container">
6
+ <ion-icon
7
+ [name]="cameraError() === 'not-found' ? 'videocam-off' : cameraError() === 'not-readable' ? 'lock-closed' : 'alert-circle'"
8
+ class="error-icon">
9
+ </ion-icon>
10
+ </div>
11
+
12
+ <h2 class="error-title" *ngIf="cameraError() === 'not-found'">Camera Not Found</h2>
13
+ <h2 class="error-title" *ngIf="cameraError() === 'not-readable'">Camera Unavailable</h2>
14
+ <h2 class="error-title" *ngIf="cameraError() === 'denied'">Camera Access Denied</h2>
15
+ <h2 class="error-title" *ngIf="cameraError() === 'generic'">Camera Error</h2>
16
+
17
+ <p class="error-description" *ngIf="cameraError() === 'not-found'">
18
+ No camera was detected on your device. Please ensure a camera is connected and enabled.
19
+ </p>
20
+ <p class="error-description" *ngIf="cameraError() === 'not-readable'">
21
+ Your camera is currently in use by another application. Please close other apps using the camera and try again.
22
+ </p>
23
+ <p class="error-description" *ngIf="cameraError() === 'denied'">
24
+ Camera access was denied. Please update your browser or app permissions to allow camera access.
25
+ </p>
26
+ <p class="error-description" *ngIf="cameraError() === 'generic'">
27
+ An unexpected error occurred while accessing your camera. Please check your settings and try again.
28
+ </p>
29
+
30
+ <div class="error-tips">
31
+ <div class="tip-item">
32
+ <ion-icon name="settings-outline"></ion-icon>
33
+ <span>Check your browser/app settings to ensure camera permissions are enabled.</span>
34
+ </div>
35
+ <div class="tip-item">
36
+ <ion-icon name="phone-portrait-outline"></ion-icon>
37
+ <span>On mobile, go to System Settings &gt; App Permissions &gt; Camera.</span>
38
+ </div>
39
+ <div class="tip-item">
40
+ <ion-icon name="desktop-outline"></ion-icon>
41
+ <span>On desktop, check the camera icon in your browser's address bar.</span>
42
+ </div>
43
+ </div>
44
+
45
+ <ion-button expand="block" (click)="retryCamera()" class="retry-button">
46
+ <ion-icon name="refresh" slot="start"></ion-icon>
47
+ Try Again
48
+ </ion-button>
49
+ </div>
50
+ </div>
51
+
52
+ <!-- Normal camera view -->
53
+ <div class="camera-view" *ngIf="cameraError() === 'none'">
54
+ <video #videoElement autoplay playsinline class="video-feed"></video>
55
+
56
+ <!-- Canvas for drawing -->
57
+ <canvas #canvasOverlay class="canvas-overlay"></canvas>
58
+
59
+ <!-- Overlay with face guide and controls -->
60
+ <div class="overlay">
61
+ <!-- Face guide container (oval removed) -->
62
+ <div class="face-guide-container">
63
+ <!-- Selected pose overlay (if pose was selected from grid) -->
64
+ <div class="pose-reference-overlay" *ngIf="showPoseOverlay() && selectedPose">
65
+ <img [src]="selectedPose.imageUrl" alt="Selected Pose" class="pose-reference-image">
66
+ <p class="pose-hint">{{ selectedPose.pose.description }}</p>
67
+ </div>
68
+
69
+ <!-- Custom uploaded pose overlay (legacy) -->
70
+ <div class="reference-pose-overlay" *ngIf="showPoseOverlay() && referencePose && !selectedPose">
71
+ <img [src]="referencePose.imageData" alt="Reference Pose" class="reference-pose-image">
72
+ <p class="pose-hint">{{ referencePose.poseDescription }}</p>
73
+ </div>
74
+
75
+ <!-- Default overlay (no pose selected) -->
76
+ <div class="smile-reference-overlay" *ngIf="showPoseOverlay() && !selectedPose && !referencePose">
77
+ <ion-icon name="happy-outline" class="smile-icon"></ion-icon>
78
+ <p class="smile-hint">{{ currentPoseDescription() }}</p>
79
+ </div>
80
+ </div>
81
+
82
+ <!-- Moving dot for "Follow Dot" pose -->
83
+ <div class="moving-dot" *ngIf="showFollowDot()" [style.left.px]="dotX()" [style.top.px]="dotY()"></div>
84
+
85
+ <!-- Status message at top -->
86
+ <div class="status-message-top">
87
+ <ion-text>
88
+ <p>{{ statusMessage() }}</p>
89
+ </ion-text>
90
+ </div>
91
+
92
+ <!-- Lighting warning -->
93
+ <div class="lighting-warning" *ngIf="lightingWarning()">
94
+ <ion-icon
95
+ [name]="isLowLight() ? 'moon' : 'sunny'"
96
+ class="warning-icon">
97
+ </ion-icon>
98
+ <span>{{ lightingWarning() }}</span>
99
+ </div>
100
+
101
+ <!-- Capturing loader overlay -->
102
+ <div class="capturing-loader" *ngIf="isMatching()">
103
+ <div class="loader-content">
104
+ <ion-spinner name="crescent" color="light"></ion-spinner>
105
+ <p class="loader-text">Capturing...</p>
106
+ </div>
107
+ </div>
108
+
109
+ <!-- Capture button at bottom -->
110
+ <div class="capture-button-container" *ngIf="!isMatching()">
111
+ <button
112
+ class="capture-btn"
113
+ (click)="manualCapture()"
114
+ [disabled]="isMatching()">
115
+ <ion-icon name="camera"></ion-icon>
116
+ </button>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </div>
@@ -0,0 +1,611 @@
1
+ .live-preview-container {
2
+ --background: #000;
3
+ --padding-top: 0;
4
+ --padding-bottom: 0;
5
+ position: relative;
6
+ width: 100%;
7
+ height: 100%;
8
+ }
9
+
10
+ .camera-error-container {
11
+ display: flex;
12
+ flex-direction: column;
13
+ align-items: center;
14
+ justify-content: center;
15
+ height: 100%;
16
+ width: 100%;
17
+ background: var(--ion-background-color, #fff);
18
+ padding: 24px;
19
+
20
+ .camera-error-content {
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: center;
24
+ max-width: 480px;
25
+ width: 100%;
26
+ text-align: center;
27
+ }
28
+
29
+ .error-icon-container {
30
+ width: 120px;
31
+ height: 120px;
32
+ border-radius: 50%;
33
+ background: linear-gradient(135deg, rgba(235, 68, 90, 0.15) 0%, rgba(235, 68, 90, 0.08) 100%);
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ margin-bottom: 24px;
38
+ box-shadow: 0 8px 24px rgba(235, 68, 90, 0.15);
39
+
40
+ .error-icon {
41
+ font-size: 56px;
42
+ color: var(--ion-color-danger, #eb445a);
43
+ }
44
+ }
45
+
46
+ .error-title {
47
+ font-size: 22px;
48
+ font-weight: 700;
49
+ color: var(--ion-text-color, #1a1a1a);
50
+ margin: 0 0 12px;
51
+ }
52
+
53
+ .error-description {
54
+ font-size: 15px;
55
+ line-height: 1.6;
56
+ color: var(--ion-color-medium, #92949c);
57
+ margin: 0 0 24px;
58
+ }
59
+
60
+ .error-tips {
61
+ display: flex;
62
+ flex-direction: column;
63
+ gap: 10px;
64
+ width: 100%;
65
+ margin-bottom: 28px;
66
+ text-align: left;
67
+
68
+ .tip-item {
69
+ display: flex;
70
+ align-items: flex-start;
71
+ gap: 10px;
72
+ padding: 10px 14px;
73
+ border-radius: 10px;
74
+ background: rgba(var(--ion-color-medium-rgb, 146, 148, 156), 0.08);
75
+ font-size: 13px;
76
+ line-height: 1.5;
77
+ color: var(--ion-text-color, #1a1a1a);
78
+
79
+ ion-icon {
80
+ font-size: 18px;
81
+ flex-shrink: 0;
82
+ margin-top: 1px;
83
+ color: var(--ion-color-medium, #92949c);
84
+ }
85
+ }
86
+ }
87
+
88
+ .retry-button {
89
+ width: 100%;
90
+ }
91
+ }
92
+
93
+ .camera-view {
94
+ position: relative;
95
+ width: 100%;
96
+ height: 100%;
97
+ background: #000;
98
+
99
+ .video-feed {
100
+ width: 100%;
101
+ height: 100%;
102
+ object-fit: cover;
103
+ transform: scaleX(-1); // Mirror the camera like a selfie
104
+ }
105
+
106
+ .canvas-overlay {
107
+ position: absolute;
108
+ top: 0;
109
+ left: 0;
110
+ width: 100%;
111
+ height: 100%;
112
+ pointer-events: none;
113
+ z-index: 1;
114
+ transform: scaleX(-1); // Mirror to match video
115
+ }
116
+
117
+ .overlay {
118
+ position: absolute;
119
+ top: 0;
120
+ left: 0;
121
+ right: 0;
122
+ bottom: 0;
123
+ display: flex;
124
+ flex-direction: column;
125
+ justify-content: space-between;
126
+ align-items: center;
127
+ pointer-events: none;
128
+
129
+ .face-guide-container {
130
+ position: absolute;
131
+ top: 50%;
132
+ left: 50%;
133
+ transform: translate(-50%, -50%);
134
+ width: 552px;
135
+ height: 552px;
136
+ display: flex;
137
+ justify-content: center;
138
+ align-items: center;
139
+
140
+ .example-image-container {
141
+ position: absolute;
142
+ top: 50%;
143
+ left: 50%;
144
+ transform: translate(-50%, -50%);
145
+ width: 420px;
146
+ height: 510px;
147
+ display: flex;
148
+ justify-content: center;
149
+ align-items: center;
150
+ border-radius: 50%;
151
+ overflow: hidden;
152
+ z-index: 1;
153
+
154
+ .example-image {
155
+ width: 100%;
156
+ height: 100%;
157
+ object-fit: cover;
158
+ opacity: 0.4;
159
+ filter: grayscale(30%);
160
+ transition: opacity 0.3s ease;
161
+ animation: fadeInOut 3s ease-in-out infinite;
162
+ }
163
+ }
164
+ }
165
+
166
+ // Reference pose image overlay (for custom uploaded poses)
167
+ .reference-pose-overlay {
168
+ position: absolute;
169
+ bottom: 120px;
170
+ left: 20px;
171
+ width: 180px;
172
+ height: 180px;
173
+ display: flex;
174
+ flex-direction: column;
175
+ align-items: center;
176
+ justify-content: center;
177
+ z-index: 3;
178
+ animation: slideInLeft 0.5s ease-in-out;
179
+ pointer-events: none; // Allow clicks to pass through
180
+ background: rgba(0, 0, 0, 0.4);
181
+ border-radius: 16px;
182
+ padding: 8px;
183
+ backdrop-filter: blur(8px);
184
+ border: 2px solid rgba(255, 255, 255, 0.3);
185
+
186
+ .reference-pose-image {
187
+ width: 100%;
188
+ height: 100%;
189
+ object-fit: contain;
190
+ opacity: 0.9; // Higher opacity for corner view
191
+ filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3));
192
+ border-radius: 12px;
193
+ }
194
+
195
+ .pose-hint {
196
+ position: absolute;
197
+ top: -35px;
198
+ left: 0;
199
+ color: #fff;
200
+ font-size: 13px;
201
+ font-weight: 600;
202
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
203
+ background: rgba(0, 0, 0, 0.7);
204
+ padding: 6px 12px;
205
+ border-radius: 12px;
206
+ backdrop-filter: blur(10px);
207
+ white-space: nowrap;
208
+ }
209
+ }
210
+
211
+ // Selected pose overlay (from pose selection grid) - new
212
+ .pose-reference-overlay {
213
+ position: absolute;
214
+ bottom: 120px;
215
+ left: 20px;
216
+ width: 180px;
217
+ height: 180px;
218
+ display: flex;
219
+ flex-direction: column;
220
+ align-items: center;
221
+ justify-content: center;
222
+ z-index: 3;
223
+ animation: slideInLeft 0.5s ease-out;
224
+
225
+ .pose-reference-image {
226
+ width: 160px;
227
+ height: 160px;
228
+ border-radius: 12px;
229
+ border: 2px solid white;
230
+ opacity: 0.9;
231
+ object-fit: cover;
232
+ background: rgba(0, 0, 0, 0.6);
233
+ backdrop-filter: blur(10px);
234
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
235
+ animation: fadeInOut 3s ease-in-out infinite;
236
+ }
237
+
238
+ .pose-hint {
239
+ margin: 8px 0 0;
240
+ font-size: 12px;
241
+ font-weight: 600;
242
+ color: white;
243
+ text-align: center;
244
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
245
+ background: rgba(0, 0, 0, 0.7);
246
+ padding: 6px 12px;
247
+ border-radius: 12px;
248
+ backdrop-filter: blur(10px);
249
+ max-width: 180px;
250
+ overflow: hidden;
251
+ text-overflow: ellipsis;
252
+ }
253
+ }
254
+
255
+ // Default smile overlay (when no pose selected)
256
+ .smile-reference-overlay {
257
+ position: absolute;
258
+ top: 50%;
259
+ left: 50%;
260
+ transform: translate(-50%, -50%);
261
+ display: flex;
262
+ flex-direction: column;
263
+ align-items: center;
264
+ justify-content: center;
265
+ gap: 16px;
266
+ z-index: 2;
267
+ animation: fadeIn 0.5s ease-in-out;
268
+
269
+ .smile-icon {
270
+ font-size: 120px;
271
+ color: rgba(255, 255, 255, 0.9);
272
+ filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.8));
273
+ animation: smilePulse 2s ease-in-out infinite;
274
+ }
275
+
276
+ .smile-hint {
277
+ color: #fff;
278
+ font-size: 18px;
279
+ font-weight: 600;
280
+ text-align: center;
281
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
282
+ background: rgba(0, 0, 0, 0.5);
283
+ padding: 8px 16px;
284
+ border-radius: 16px;
285
+ backdrop-filter: blur(10px);
286
+ max-width: 300px;
287
+ }
288
+ }
289
+
290
+ .status-message-top {
291
+ position: absolute;
292
+ top: 30px;
293
+ left: 0;
294
+ right: 0;
295
+ text-align: center;
296
+ padding: 0 20px;
297
+ z-index: 2;
298
+
299
+ ion-text p {
300
+ margin: 0;
301
+ font-size: 17px;
302
+ font-weight: 600;
303
+ color: #fff;
304
+ line-height: 1.4;
305
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
306
+ letter-spacing: 0.3px;
307
+ background: rgba(0, 0, 0, 0.5);
308
+ padding: 12px 20px;
309
+ border-radius: 24px;
310
+ backdrop-filter: blur(10px);
311
+ display: inline-block;
312
+ }
313
+ }
314
+
315
+ .lighting-warning {
316
+ position: absolute;
317
+ top: 100px;
318
+ left: 0;
319
+ right: 0;
320
+ text-align: center;
321
+ padding: 0 20px;
322
+ z-index: 2;
323
+ display: flex;
324
+ align-items: center;
325
+ justify-content: center;
326
+ gap: 8px;
327
+ font-size: 15px;
328
+ font-weight: 600;
329
+ color: #fff;
330
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
331
+ background: rgba(255, 152, 0, 0.9);
332
+ padding: 10px 18px;
333
+ border-radius: 20px;
334
+ backdrop-filter: blur(10px);
335
+ margin: 0 auto;
336
+ max-width: fit-content;
337
+ animation: warningPulse 2s ease-in-out infinite;
338
+
339
+ .warning-icon {
340
+ font-size: 20px;
341
+ color: #fff;
342
+ }
343
+
344
+ span {
345
+ color: #fff;
346
+ }
347
+ }
348
+
349
+ .moving-dot {
350
+ position: absolute;
351
+ width: 30px;
352
+ height: 30px;
353
+ background: radial-gradient(circle, #ff4444 0%, #ff0000 50%, #cc0000 100%);
354
+ border-radius: 50%;
355
+ box-shadow:
356
+ 0 0 20px rgba(255, 68, 68, 0.8),
357
+ 0 0 40px rgba(255, 68, 68, 0.4),
358
+ inset 0 0 10px rgba(255, 255, 255, 0.3);
359
+ z-index: 10;
360
+ pointer-events: none;
361
+ transform: translate(-50%, -50%);
362
+ animation: dotPulse 1s ease-in-out infinite;
363
+ border: 3px solid rgba(255, 255, 255, 0.8);
364
+ transition: left 0.8s cubic-bezier(0.4, 0, 0.2, 1), top 0.8s cubic-bezier(0.4, 0, 0.2, 1);
365
+
366
+ // Add a white glow
367
+ &::before {
368
+ content: '';
369
+ position: absolute;
370
+ top: 50%;
371
+ left: 50%;
372
+ transform: translate(-50%, -50%);
373
+ width: 50px;
374
+ height: 50px;
375
+ border-radius: 50%;
376
+ background: radial-gradient(circle, rgba(255, 68, 68, 0.3) 0%, transparent 70%);
377
+ animation: dotGlow 1s ease-in-out infinite;
378
+ }
379
+ }
380
+
381
+ .capturing-loader {
382
+ position: absolute;
383
+ top: 0;
384
+ left: 0;
385
+ right: 0;
386
+ bottom: 0;
387
+ background: rgba(0, 0, 0, 0.7);
388
+ display: flex;
389
+ align-items: center;
390
+ justify-content: center;
391
+ z-index: 100;
392
+ animation: fadeIn 0.3s ease-in-out;
393
+
394
+ .loader-content {
395
+ display: flex;
396
+ flex-direction: column;
397
+ align-items: center;
398
+ gap: 16px;
399
+
400
+ ion-spinner {
401
+ width: 60px;
402
+ height: 60px;
403
+ --color: #fff;
404
+ }
405
+
406
+ .loader-text {
407
+ color: #fff;
408
+ font-size: 18px;
409
+ font-weight: 600;
410
+ margin: 0;
411
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
412
+ }
413
+ }
414
+ }
415
+
416
+ .capture-button-container {
417
+ position: absolute;
418
+ bottom: 40px;
419
+ left: 50%;
420
+ transform: translateX(-50%);
421
+ pointer-events: all;
422
+ z-index: 2;
423
+
424
+ .capture-btn {
425
+ width: 72px;
426
+ height: 72px;
427
+ border-radius: 50%;
428
+ background: linear-gradient(135deg, var(--ion-color-primary, #fe3c72), var(--ion-color-primary-shade, #e0365f));
429
+ border: 4px solid rgba(255, 255, 255, 0.9);
430
+ box-shadow: 0 4px 24px rgba(254, 60, 114, 0.5);
431
+ display: flex;
432
+ align-items: center;
433
+ justify-content: center;
434
+ cursor: pointer;
435
+ transition: all 0.2s ease;
436
+
437
+ ion-icon {
438
+ font-size: 32px;
439
+ color: #fff;
440
+ }
441
+
442
+ &:active {
443
+ transform: scale(0.92);
444
+ }
445
+
446
+ &:disabled {
447
+ opacity: 0.5;
448
+ cursor: not-allowed;
449
+ }
450
+
451
+ &:not(:disabled):hover {
452
+ box-shadow: 0 6px 32px rgba(254, 60, 114, 0.7);
453
+ transform: scale(1.05);
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+
460
+ @keyframes pulse {
461
+ 0%, 100% {
462
+ border-color: rgba(255, 255, 255, 0.95);
463
+ transform: scale(1);
464
+ }
465
+ 50% {
466
+ border-color: rgba(var(--ion-color-success-rgb, 16, 220, 96), 0.95);
467
+ transform: scale(1.02);
468
+ }
469
+ }
470
+
471
+ @keyframes rippleGuide {
472
+ 0% {
473
+ transform: scale(1);
474
+ opacity: 0.5;
475
+ }
476
+ 100% {
477
+ transform: scale(1.15);
478
+ opacity: 0;
479
+ }
480
+ }
481
+
482
+ @keyframes progressPulse {
483
+ 0%, 100% {
484
+ opacity: 1;
485
+ transform: scaleY(1);
486
+ }
487
+ 50% {
488
+ opacity: 0.8;
489
+ transform: scaleY(1.1);
490
+ }
491
+ }
492
+
493
+ @keyframes fadeInOut {
494
+ 0%, 100% {
495
+ opacity: 0.4;
496
+ }
497
+ 50% {
498
+ opacity: 0.5;
499
+ }
500
+ }
501
+
502
+ @keyframes fadeIn {
503
+ from {
504
+ opacity: 0;
505
+ transform: translate(-50%, -50%) scale(0.8);
506
+ }
507
+ to {
508
+ opacity: 1;
509
+ transform: translate(-50%, -50%) scale(1);
510
+ }
511
+ }
512
+
513
+ @keyframes slideInLeft {
514
+ from {
515
+ opacity: 0;
516
+ transform: translateX(-100px);
517
+ }
518
+ to {
519
+ opacity: 1;
520
+ transform: translateX(0);
521
+ }
522
+ }
523
+
524
+ @keyframes smilePulse {
525
+ 0%, 100% {
526
+ transform: scale(1);
527
+ opacity: 0.9;
528
+ }
529
+ 50% {
530
+ transform: scale(1.1);
531
+ opacity: 1;
532
+ }
533
+ }
534
+
535
+ @keyframes thumbsPulse {
536
+ 0%, 100% {
537
+ transform: scale(1) rotate(0deg);
538
+ opacity: 0.9;
539
+ }
540
+ 50% {
541
+ transform: scale(1.15) rotate(5deg);
542
+ opacity: 1;
543
+ }
544
+ }
545
+
546
+ @keyframes warningPulse {
547
+ 0%, 100% {
548
+ opacity: 0.9;
549
+ transform: scale(1);
550
+ }
551
+ 50% {
552
+ opacity: 1;
553
+ transform: scale(1.02);
554
+ }
555
+ }
556
+
557
+ @keyframes dotPulse {
558
+ 0%, 100% {
559
+ transform: translate(-50%, -50%) scale(1);
560
+ opacity: 1;
561
+ }
562
+ 50% {
563
+ transform: translate(-50%, -50%) scale(1.2);
564
+ opacity: 0.8;
565
+ }
566
+ }
567
+
568
+ @keyframes dotGlow {
569
+ 0%, 100% {
570
+ opacity: 0.6;
571
+ transform: translate(-50%, -50%) scale(1);
572
+ }
573
+ 50% {
574
+ opacity: 1;
575
+ transform: translate(-50%, -50%) scale(1.3);
576
+ }
577
+ }
578
+
579
+ @media (max-width: 768px) {
580
+ .status-bar {
581
+ padding: 18px 18px;
582
+
583
+ .status-message p {
584
+ font-size: 16px;
585
+ }
586
+ }
587
+ }
588
+
589
+ @media (max-width: 480px) {
590
+ .status-bar {
591
+ padding: 16px 16px;
592
+ padding-bottom: max(16px, calc(env(safe-area-inset-bottom) + 8px));
593
+
594
+ .status-message {
595
+ margin-bottom: 14px;
596
+
597
+ p {
598
+ font-size: 15px;
599
+ }
600
+ }
601
+
602
+ ion-progress-bar {
603
+ margin-bottom: 14px;
604
+ height: 5px;
605
+ }
606
+
607
+ .capture-button {
608
+ margin-top: 14px;
609
+ }
610
+ }
611
+ }