@nocios/crudify-components 2.0.61 → 2.0.81

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 (363) hide show
  1. package/.scannerwork/.sonar_lock +0 -0
  2. package/.scannerwork/report-task.txt +6 -0
  3. package/coverage/components/CrudiaAutoGenerate.tsx.html +616 -0
  4. package/coverage/components/CrudiaFileField/CrudiaFileField.tsx.html +1312 -0
  5. package/coverage/components/CrudiaFileField/components/DeleteConfirmationDialog.tsx.html +355 -0
  6. package/coverage/components/CrudiaFileField/components/DropZone.tsx.html +523 -0
  7. package/coverage/components/CrudiaFileField/components/FileItemRow.tsx.html +835 -0
  8. package/coverage/components/CrudiaFileField/components/FileThumbnail.tsx.html +1585 -0
  9. package/coverage/components/CrudiaFileField/components/index.html +176 -0
  10. package/coverage/components/CrudiaFileField/components/index.ts.html +115 -0
  11. package/coverage/components/CrudiaFileField/hooks/index.html +146 -0
  12. package/coverage/components/CrudiaFileField/hooks/index.ts.html +112 -0
  13. package/coverage/components/CrudiaFileField/hooks/useDeleteConfirmation.ts.html +433 -0
  14. package/coverage/components/CrudiaFileField/hooks/useDragDrop.ts.html +409 -0
  15. package/coverage/components/CrudiaFileField/index.html +131 -0
  16. package/coverage/components/CrudiaFileField/index.ts.html +112 -0
  17. package/coverage/components/CrudiaFileField/utils/formatters.ts.html +169 -0
  18. package/coverage/components/CrudiaFileField/utils/icons.tsx.html +253 -0
  19. package/coverage/components/CrudiaFileField/utils/index.html +146 -0
  20. package/coverage/components/CrudiaFileField/utils/index.ts.html +103 -0
  21. package/coverage/components/CrudiaMarkdownField.tsx.html +676 -0
  22. package/coverage/components/CrudifyInitializer.tsx.html +712 -0
  23. package/coverage/components/CrudifyLogin/Forms/CheckCodeForm.tsx.html +640 -0
  24. package/coverage/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx.html +730 -0
  25. package/coverage/components/CrudifyLogin/Forms/LoginForm.tsx.html +892 -0
  26. package/coverage/components/CrudifyLogin/Forms/ResetPasswordForm.tsx.html +1219 -0
  27. package/coverage/components/CrudifyLogin/Forms/components/CodeInput.tsx.html +289 -0
  28. package/coverage/components/CrudifyLogin/Forms/components/FormAlert.tsx.html +202 -0
  29. package/coverage/components/CrudifyLogin/Forms/components/PasswordInput.tsx.html +346 -0
  30. package/coverage/components/CrudifyLogin/Forms/components/index.html +161 -0
  31. package/coverage/components/CrudifyLogin/Forms/components/index.ts.html +106 -0
  32. package/coverage/components/CrudifyLogin/Forms/index.html +176 -0
  33. package/coverage/components/CrudifyLogin/Forms/index.ts.html +145 -0
  34. package/coverage/components/CrudifyLogin/Forms/utils/errorTranslation.ts.html +268 -0
  35. package/coverage/components/CrudifyLogin/Forms/utils/index.html +161 -0
  36. package/coverage/components/CrudifyLogin/Forms/utils/index.ts.html +121 -0
  37. package/coverage/components/CrudifyLogin/Forms/utils/paramUtils.ts.html +496 -0
  38. package/coverage/components/CrudifyLogin/Forms/utils/validation.ts.html +307 -0
  39. package/coverage/components/CrudifyLogin/components/CrudifyInitializer.tsx.html +268 -0
  40. package/coverage/components/CrudifyLogin/components/index.html +116 -0
  41. package/coverage/components/CrudifyLogin/context/CrudifyProvider.tsx.html +409 -0
  42. package/coverage/components/CrudifyLogin/context/I18nProvider.tsx.html +430 -0
  43. package/coverage/components/CrudifyLogin/context/LoginStateProvider.tsx.html +1261 -0
  44. package/coverage/components/CrudifyLogin/context/index.html +161 -0
  45. package/coverage/components/CrudifyLogin/context/index.ts.html +91 -0
  46. package/coverage/components/CrudifyLogin/hooks/index.html +131 -0
  47. package/coverage/components/CrudifyLogin/hooks/useCrudifyLogin.ts.html +463 -0
  48. package/coverage/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts.html +391 -0
  49. package/coverage/components/CrudifyLogin/index.html +116 -0
  50. package/coverage/components/CrudifyLogin/index.tsx.html +466 -0
  51. package/coverage/components/CrudifyLogin/utils/index.html +116 -0
  52. package/coverage/components/CrudifyLogin/utils/secureStorage.ts.html +859 -0
  53. package/coverage/components/GlobalNotificationProvider.tsx.html +844 -0
  54. package/coverage/components/LoginComponent.tsx.html +676 -0
  55. package/coverage/components/PasswordRequirements/index.html +116 -0
  56. package/coverage/components/PasswordRequirements/index.tsx.html +232 -0
  57. package/coverage/components/PublicPolicies/FieldSelector/FieldSelector.tsx.html +1078 -0
  58. package/coverage/components/PublicPolicies/FieldSelector/index.html +131 -0
  59. package/coverage/components/PublicPolicies/FieldSelector/index.ts.html +88 -0
  60. package/coverage/components/PublicPolicies/Policies.tsx.html +625 -0
  61. package/coverage/components/PublicPolicies/PolicyItem/PolicyItem.tsx.html +886 -0
  62. package/coverage/components/PublicPolicies/PolicyItem/index.html +131 -0
  63. package/coverage/components/PublicPolicies/PolicyItem/index.ts.html +88 -0
  64. package/coverage/components/PublicPolicies/constants.ts.html +106 -0
  65. package/coverage/components/PublicPolicies/index.html +146 -0
  66. package/coverage/components/PublicPolicies/index.ts.html +88 -0
  67. package/coverage/components/Routing/AuthRoute.tsx.html +382 -0
  68. package/coverage/components/Routing/GuestRoute.tsx.html +352 -0
  69. package/coverage/components/Routing/ProtectedRoute.tsx.html +316 -0
  70. package/coverage/components/Routing/index.html +161 -0
  71. package/coverage/components/Routing/index.ts.html +109 -0
  72. package/coverage/components/SessionLoadingScreen/index.html +116 -0
  73. package/coverage/components/SessionLoadingScreen/index.tsx.html +379 -0
  74. package/coverage/components/SessionTimeIndicator/index.html +116 -0
  75. package/coverage/components/SessionTimeIndicator/index.tsx.html +523 -0
  76. package/coverage/components/UserProfile/UserProfileDisplay.tsx.html +931 -0
  77. package/coverage/components/UserProfile/index.html +131 -0
  78. package/coverage/components/UserProfile/index.ts.html +88 -0
  79. package/coverage/components/index.html +191 -0
  80. package/coverage/components/index.ts.html +178 -0
  81. package/coverage/core/CrossTabSyncManager.ts.html +853 -0
  82. package/coverage/core/CrudifyInitializationManager.ts.html +1279 -0
  83. package/coverage/core/SessionManager.ts.html +3064 -0
  84. package/coverage/core/index.html +146 -0
  85. package/coverage/coverage-final.json +74 -77
  86. package/coverage/hooks/index.html +191 -0
  87. package/coverage/hooks/index.ts.html +136 -0
  88. package/coverage/hooks/useAuth.ts.html +529 -0
  89. package/coverage/hooks/useAutoGenerate.ts.html +571 -0
  90. package/coverage/hooks/useCrudifyWithNotifications/constants.ts.html +247 -0
  91. package/coverage/hooks/useCrudifyWithNotifications/hooks/index.html +116 -0
  92. package/coverage/hooks/useCrudifyWithNotifications/hooks/useCrudOperations.ts.html +820 -0
  93. package/coverage/hooks/useCrudifyWithNotifications/index.html +146 -0
  94. package/coverage/hooks/useCrudifyWithNotifications/index.ts.html +118 -0
  95. package/coverage/hooks/useCrudifyWithNotifications/useCrudifyWithNotifications.ts.html +565 -0
  96. package/coverage/hooks/useCrudifyWithNotifications/utils/errorMessageResolver.ts.html +847 -0
  97. package/coverage/hooks/useCrudifyWithNotifications/utils/index.html +146 -0
  98. package/coverage/hooks/useCrudifyWithNotifications/utils/notificationFilters.ts.html +313 -0
  99. package/coverage/hooks/useCrudifyWithNotifications/utils/successMessageResolver.ts.html +265 -0
  100. package/coverage/hooks/useData.ts.html +829 -0
  101. package/coverage/hooks/useFileUpload/index.html +131 -0
  102. package/coverage/hooks/useFileUpload/index.ts.html +112 -0
  103. package/coverage/hooks/useFileUpload/services/index.html +131 -0
  104. package/coverage/hooks/useFileUpload/services/index.ts.html +106 -0
  105. package/coverage/hooks/useFileUpload/services/uploadService.ts.html +610 -0
  106. package/coverage/hooks/useFileUpload/useFileUpload.ts.html +2092 -0
  107. package/coverage/hooks/useFileUpload/utils/fileUtils.ts.html +271 -0
  108. package/coverage/hooks/useFileUpload/utils/index.html +161 -0
  109. package/coverage/hooks/useFileUpload/utils/index.ts.html +109 -0
  110. package/coverage/hooks/useFileUpload/utils/mimeTypes.ts.html +235 -0
  111. package/coverage/hooks/useFileUpload/utils/validation.ts.html +403 -0
  112. package/coverage/hooks/useSession/constants.ts.html +217 -0
  113. package/coverage/hooks/useSession/hooks/index.html +176 -0
  114. package/coverage/hooks/useSession/hooks/useAuthEventSubscriber.ts.html +331 -0
  115. package/coverage/hooks/useSession/hooks/useCrossTabSync.ts.html +535 -0
  116. package/coverage/hooks/useSession/hooks/useSessionActions.ts.html +664 -0
  117. package/coverage/hooks/useSession/hooks/useSessionState.ts.html +295 -0
  118. package/coverage/hooks/useSession/hooks/useTokenRefreshScheduler.ts.html +535 -0
  119. package/coverage/hooks/useSession/index.html +161 -0
  120. package/coverage/hooks/useSession/index.ts.html +127 -0
  121. package/coverage/hooks/useSession/types.ts.html +427 -0
  122. package/coverage/hooks/useSession/useSession.ts.html +526 -0
  123. package/coverage/hooks/useSession/utils/index.html +131 -0
  124. package/coverage/hooks/useSession/utils/initializeSession.ts.html +424 -0
  125. package/coverage/hooks/useSession/utils/tokenUtils.ts.html +298 -0
  126. package/coverage/hooks/useUserData.ts.html +1210 -0
  127. package/coverage/hooks/useUserProfile.ts.html +820 -0
  128. package/coverage/index.html +205 -235
  129. package/coverage/lcov-report/components/CrudiaAutoGenerate.tsx.html +616 -0
  130. package/coverage/lcov-report/components/CrudiaFileField/CrudiaFileField.tsx.html +1312 -0
  131. package/coverage/lcov-report/components/CrudiaFileField/components/DeleteConfirmationDialog.tsx.html +355 -0
  132. package/coverage/lcov-report/components/CrudiaFileField/components/DropZone.tsx.html +523 -0
  133. package/coverage/lcov-report/components/CrudiaFileField/components/FileItemRow.tsx.html +835 -0
  134. package/coverage/lcov-report/components/CrudiaFileField/components/FileThumbnail.tsx.html +1585 -0
  135. package/coverage/lcov-report/components/CrudiaFileField/components/index.html +176 -0
  136. package/coverage/lcov-report/components/CrudiaFileField/components/index.ts.html +115 -0
  137. package/coverage/lcov-report/components/CrudiaFileField/hooks/index.html +146 -0
  138. package/coverage/lcov-report/components/CrudiaFileField/hooks/index.ts.html +112 -0
  139. package/coverage/lcov-report/components/CrudiaFileField/hooks/useDeleteConfirmation.ts.html +433 -0
  140. package/coverage/lcov-report/components/CrudiaFileField/hooks/useDragDrop.ts.html +409 -0
  141. package/coverage/lcov-report/components/CrudiaFileField/index.html +131 -0
  142. package/coverage/lcov-report/components/CrudiaFileField/index.ts.html +112 -0
  143. package/coverage/lcov-report/components/CrudiaFileField/utils/formatters.ts.html +169 -0
  144. package/coverage/lcov-report/components/CrudiaFileField/utils/icons.tsx.html +253 -0
  145. package/coverage/lcov-report/components/CrudiaFileField/utils/index.html +146 -0
  146. package/coverage/lcov-report/components/CrudiaFileField/utils/index.ts.html +103 -0
  147. package/coverage/lcov-report/components/CrudiaMarkdownField.tsx.html +676 -0
  148. package/coverage/lcov-report/components/CrudifyInitializer.tsx.html +712 -0
  149. package/coverage/lcov-report/components/CrudifyLogin/Forms/CheckCodeForm.tsx.html +640 -0
  150. package/coverage/lcov-report/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx.html +730 -0
  151. package/coverage/lcov-report/components/CrudifyLogin/Forms/LoginForm.tsx.html +892 -0
  152. package/coverage/lcov-report/components/CrudifyLogin/Forms/ResetPasswordForm.tsx.html +1219 -0
  153. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/CodeInput.tsx.html +289 -0
  154. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/FormAlert.tsx.html +202 -0
  155. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/PasswordInput.tsx.html +346 -0
  156. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/index.html +161 -0
  157. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/index.ts.html +106 -0
  158. package/coverage/lcov-report/components/CrudifyLogin/Forms/index.html +176 -0
  159. package/coverage/lcov-report/components/CrudifyLogin/Forms/index.ts.html +145 -0
  160. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/errorTranslation.ts.html +268 -0
  161. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/index.html +161 -0
  162. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/index.ts.html +121 -0
  163. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/paramUtils.ts.html +496 -0
  164. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/validation.ts.html +307 -0
  165. package/coverage/lcov-report/components/CrudifyLogin/components/CrudifyInitializer.tsx.html +268 -0
  166. package/coverage/lcov-report/components/CrudifyLogin/components/index.html +116 -0
  167. package/coverage/lcov-report/components/CrudifyLogin/context/CrudifyProvider.tsx.html +409 -0
  168. package/coverage/lcov-report/components/CrudifyLogin/context/I18nProvider.tsx.html +430 -0
  169. package/coverage/lcov-report/components/CrudifyLogin/context/LoginStateProvider.tsx.html +1261 -0
  170. package/coverage/lcov-report/components/CrudifyLogin/context/index.html +161 -0
  171. package/coverage/lcov-report/components/CrudifyLogin/context/index.ts.html +91 -0
  172. package/coverage/lcov-report/components/CrudifyLogin/hooks/index.html +131 -0
  173. package/coverage/lcov-report/components/CrudifyLogin/hooks/useCrudifyLogin.ts.html +463 -0
  174. package/coverage/lcov-report/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts.html +391 -0
  175. package/coverage/lcov-report/components/CrudifyLogin/index.html +116 -0
  176. package/coverage/lcov-report/components/CrudifyLogin/index.tsx.html +466 -0
  177. package/coverage/lcov-report/components/CrudifyLogin/utils/index.html +116 -0
  178. package/coverage/lcov-report/components/CrudifyLogin/utils/secureStorage.ts.html +859 -0
  179. package/coverage/lcov-report/components/GlobalNotificationProvider.tsx.html +844 -0
  180. package/coverage/lcov-report/components/LoginComponent.tsx.html +676 -0
  181. package/coverage/lcov-report/components/PasswordRequirements/index.html +116 -0
  182. package/coverage/lcov-report/components/PasswordRequirements/index.tsx.html +232 -0
  183. package/coverage/lcov-report/components/PublicPolicies/FieldSelector/FieldSelector.tsx.html +1078 -0
  184. package/coverage/lcov-report/components/PublicPolicies/FieldSelector/index.html +131 -0
  185. package/coverage/lcov-report/components/PublicPolicies/FieldSelector/index.ts.html +88 -0
  186. package/coverage/lcov-report/components/PublicPolicies/Policies.tsx.html +625 -0
  187. package/coverage/lcov-report/components/PublicPolicies/PolicyItem/PolicyItem.tsx.html +886 -0
  188. package/coverage/lcov-report/components/PublicPolicies/PolicyItem/index.html +131 -0
  189. package/coverage/lcov-report/components/PublicPolicies/PolicyItem/index.ts.html +88 -0
  190. package/coverage/lcov-report/components/PublicPolicies/constants.ts.html +106 -0
  191. package/coverage/lcov-report/components/PublicPolicies/index.html +146 -0
  192. package/coverage/lcov-report/components/PublicPolicies/index.ts.html +88 -0
  193. package/coverage/lcov-report/components/Routing/AuthRoute.tsx.html +382 -0
  194. package/coverage/lcov-report/components/Routing/GuestRoute.tsx.html +352 -0
  195. package/coverage/lcov-report/components/Routing/ProtectedRoute.tsx.html +316 -0
  196. package/coverage/lcov-report/components/Routing/index.html +161 -0
  197. package/coverage/lcov-report/components/Routing/index.ts.html +109 -0
  198. package/coverage/lcov-report/components/SessionLoadingScreen/index.html +116 -0
  199. package/coverage/lcov-report/components/SessionLoadingScreen/index.tsx.html +379 -0
  200. package/coverage/lcov-report/components/SessionTimeIndicator/index.html +116 -0
  201. package/coverage/lcov-report/components/SessionTimeIndicator/index.tsx.html +523 -0
  202. package/coverage/lcov-report/components/UserProfile/UserProfileDisplay.tsx.html +931 -0
  203. package/coverage/lcov-report/components/UserProfile/index.html +131 -0
  204. package/coverage/lcov-report/components/UserProfile/index.ts.html +88 -0
  205. package/coverage/lcov-report/components/index.html +191 -0
  206. package/coverage/lcov-report/components/index.ts.html +178 -0
  207. package/coverage/lcov-report/core/CrossTabSyncManager.ts.html +853 -0
  208. package/coverage/lcov-report/core/CrudifyInitializationManager.ts.html +1279 -0
  209. package/coverage/lcov-report/core/SessionManager.ts.html +3064 -0
  210. package/coverage/lcov-report/core/index.html +146 -0
  211. package/coverage/lcov-report/hooks/index.html +191 -0
  212. package/coverage/lcov-report/hooks/index.ts.html +136 -0
  213. package/coverage/lcov-report/hooks/useAuth.ts.html +529 -0
  214. package/coverage/lcov-report/hooks/useAutoGenerate.ts.html +571 -0
  215. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/constants.ts.html +247 -0
  216. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/hooks/index.html +116 -0
  217. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/hooks/useCrudOperations.ts.html +820 -0
  218. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/index.html +146 -0
  219. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/index.ts.html +118 -0
  220. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/useCrudifyWithNotifications.ts.html +565 -0
  221. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/errorMessageResolver.ts.html +847 -0
  222. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/index.html +146 -0
  223. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/notificationFilters.ts.html +313 -0
  224. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/successMessageResolver.ts.html +265 -0
  225. package/coverage/lcov-report/hooks/useData.ts.html +829 -0
  226. package/coverage/lcov-report/hooks/useFileUpload/index.html +131 -0
  227. package/coverage/lcov-report/hooks/useFileUpload/index.ts.html +112 -0
  228. package/coverage/lcov-report/hooks/useFileUpload/services/index.html +131 -0
  229. package/coverage/lcov-report/hooks/useFileUpload/services/index.ts.html +106 -0
  230. package/coverage/lcov-report/hooks/useFileUpload/services/uploadService.ts.html +610 -0
  231. package/coverage/lcov-report/hooks/useFileUpload/useFileUpload.ts.html +2092 -0
  232. package/coverage/lcov-report/hooks/useFileUpload/utils/fileUtils.ts.html +271 -0
  233. package/coverage/lcov-report/hooks/useFileUpload/utils/index.html +161 -0
  234. package/coverage/lcov-report/hooks/useFileUpload/utils/index.ts.html +109 -0
  235. package/coverage/lcov-report/hooks/useFileUpload/utils/mimeTypes.ts.html +235 -0
  236. package/coverage/lcov-report/hooks/useFileUpload/utils/validation.ts.html +403 -0
  237. package/coverage/lcov-report/hooks/useSession/constants.ts.html +217 -0
  238. package/coverage/lcov-report/hooks/useSession/hooks/index.html +176 -0
  239. package/coverage/lcov-report/hooks/useSession/hooks/useAuthEventSubscriber.ts.html +331 -0
  240. package/coverage/lcov-report/hooks/useSession/hooks/useCrossTabSync.ts.html +535 -0
  241. package/coverage/lcov-report/hooks/useSession/hooks/useSessionActions.ts.html +664 -0
  242. package/coverage/lcov-report/hooks/useSession/hooks/useSessionState.ts.html +295 -0
  243. package/coverage/lcov-report/hooks/useSession/hooks/useTokenRefreshScheduler.ts.html +535 -0
  244. package/coverage/lcov-report/hooks/useSession/index.html +161 -0
  245. package/coverage/lcov-report/hooks/useSession/index.ts.html +127 -0
  246. package/coverage/lcov-report/hooks/useSession/types.ts.html +427 -0
  247. package/coverage/lcov-report/hooks/useSession/useSession.ts.html +526 -0
  248. package/coverage/lcov-report/hooks/useSession/utils/index.html +131 -0
  249. package/coverage/lcov-report/hooks/useSession/utils/initializeSession.ts.html +424 -0
  250. package/coverage/lcov-report/hooks/useSession/utils/tokenUtils.ts.html +298 -0
  251. package/coverage/lcov-report/hooks/useUserData.ts.html +1210 -0
  252. package/coverage/lcov-report/hooks/useUserProfile.ts.html +820 -0
  253. package/coverage/lcov-report/index.html +205 -235
  254. package/coverage/lcov-report/providers/CrudifyThemeProvider.tsx.html +316 -0
  255. package/coverage/lcov-report/providers/SessionProvider.tsx.html +1120 -0
  256. package/coverage/lcov-report/providers/TranslationsProvider.tsx.html +1756 -0
  257. package/coverage/lcov-report/providers/index.html +146 -0
  258. package/coverage/lcov-report/services/credentialsEventBus.ts.html +319 -0
  259. package/coverage/lcov-report/services/crudifyAdminWrapper.ts.html +754 -0
  260. package/coverage/lcov-report/services/index.html +146 -0
  261. package/coverage/lcov-report/services/translationService.ts.html +1558 -0
  262. package/coverage/lcov-report/translations/critical.ts.html +1216 -0
  263. package/coverage/lcov-report/translations/index.html +116 -0
  264. package/coverage/lcov-report/types/index.html +116 -0
  265. package/coverage/lcov-report/types/password.ts.html +178 -0
  266. package/coverage/lcov-report/utils/authErrorDetector.ts.html +793 -0
  267. package/coverage/lcov-report/utils/authEventBus.ts.html +454 -0
  268. package/coverage/lcov-report/utils/configResolver.ts.html +460 -0
  269. package/coverage/lcov-report/utils/cookieSync.ts.html +595 -0
  270. package/coverage/lcov-report/utils/errorHandler.ts.html +1480 -0
  271. package/coverage/lcov-report/utils/errorTranslation.ts.html +868 -0
  272. package/coverage/lcov-report/utils/index.html +341 -0
  273. package/coverage/lcov-report/utils/index.ts.html +193 -0
  274. package/coverage/lcov-report/utils/jwtUtils.ts.html +325 -0
  275. package/coverage/lcov-report/utils/logger.ts.html +952 -0
  276. package/coverage/lcov-report/utils/navigationTracker.ts.html +562 -0
  277. package/coverage/lcov-report/utils/passwordValidation.ts.html +259 -0
  278. package/coverage/lcov-report/utils/preAuthCheck.ts.html +442 -0
  279. package/coverage/lcov-report/utils/redirectSecurity.ts.html +733 -0
  280. package/coverage/lcov-report/utils/tenantConfig.ts.html +712 -0
  281. package/coverage/lcov-report/utils/tokenStorage.ts.html +1825 -0
  282. package/coverage/lcov-report/utils/webCrypto.ts.html +490 -0
  283. package/coverage/lcov.info +14988 -14009
  284. package/coverage/providers/CrudifyThemeProvider.tsx.html +316 -0
  285. package/coverage/providers/SessionProvider.tsx.html +1120 -0
  286. package/coverage/providers/TranslationsProvider.tsx.html +1756 -0
  287. package/coverage/providers/index.html +146 -0
  288. package/coverage/services/credentialsEventBus.ts.html +319 -0
  289. package/coverage/services/crudifyAdminWrapper.ts.html +754 -0
  290. package/coverage/services/index.html +146 -0
  291. package/coverage/services/translationService.ts.html +1558 -0
  292. package/coverage/translations/critical.ts.html +1216 -0
  293. package/coverage/translations/index.html +116 -0
  294. package/coverage/types/index.html +116 -0
  295. package/coverage/types/password.ts.html +178 -0
  296. package/coverage/utils/authErrorDetector.ts.html +793 -0
  297. package/coverage/utils/authEventBus.ts.html +454 -0
  298. package/coverage/utils/configResolver.ts.html +460 -0
  299. package/coverage/utils/cookieSync.ts.html +595 -0
  300. package/coverage/utils/errorHandler.ts.html +1480 -0
  301. package/coverage/utils/errorTranslation.ts.html +868 -0
  302. package/coverage/utils/index.html +341 -0
  303. package/coverage/utils/index.ts.html +193 -0
  304. package/coverage/utils/jwtUtils.ts.html +325 -0
  305. package/coverage/utils/logger.ts.html +952 -0
  306. package/coverage/utils/navigationTracker.ts.html +562 -0
  307. package/coverage/utils/passwordValidation.ts.html +259 -0
  308. package/coverage/utils/preAuthCheck.ts.html +442 -0
  309. package/coverage/utils/redirectSecurity.ts.html +733 -0
  310. package/coverage/utils/tenantConfig.ts.html +712 -0
  311. package/coverage/utils/tokenStorage.ts.html +1825 -0
  312. package/coverage/utils/webCrypto.ts.html +490 -0
  313. package/dist/{CrudiaMarkdownField-CkiBwG-U.d.ts → CrudiaMarkdownField-DM6NR8zw.d.mts} +22 -22
  314. package/dist/{CrudiaMarkdownField-D-DqiXMQ.d.mts → CrudiaMarkdownField-UJaiSq9_.d.ts} +22 -22
  315. package/dist/{GlobalNotificationProvider-CdwdNv_8.d.mts → GlobalNotificationProvider-Cx540WKg.d.mts} +15 -15
  316. package/dist/{GlobalNotificationProvider-CdwdNv_8.d.ts → GlobalNotificationProvider-Cx540WKg.d.ts} +15 -15
  317. package/dist/chunk-2DXLCBOT.mjs +1 -0
  318. package/dist/chunk-DYRZIARH.js +1 -0
  319. package/dist/chunk-GCSJXEGT.mjs +1 -0
  320. package/dist/chunk-GJUZD5ZN.js +1 -0
  321. package/dist/chunk-K47I475N.js +1 -0
  322. package/dist/chunk-OCYZGEM5.mjs +1 -0
  323. package/dist/chunk-PI7HPRDB.js +1 -0
  324. package/dist/chunk-QVEUGJBY.mjs +1 -0
  325. package/dist/chunk-UROR7G7N.mjs +1 -0
  326. package/dist/chunk-XFT47DEL.js +1 -0
  327. package/dist/components.d.mts +8 -8
  328. package/dist/components.d.ts +8 -8
  329. package/dist/components.js +1 -1
  330. package/dist/components.mjs +1 -1
  331. package/dist/{errorTranslation-CF-5JClP.d.ts → errorTranslation-BEWwDbCH.d.ts} +1 -1
  332. package/dist/{errorTranslation-BcX8AaK7.d.mts → errorTranslation-DsGZon0M.d.mts} +1 -1
  333. package/dist/hooks.d.mts +3 -3
  334. package/dist/hooks.d.ts +3 -3
  335. package/dist/hooks.js +1 -1
  336. package/dist/hooks.mjs +1 -1
  337. package/dist/{index-DEDnmsdO.d.ts → index-Dnmttf62.d.ts} +131 -114
  338. package/dist/{index-D06kTP0C.d.mts → index-ZcF6nJt4.d.mts} +131 -114
  339. package/dist/index.d.mts +153 -106
  340. package/dist/index.d.ts +153 -106
  341. package/dist/index.js +2 -2
  342. package/dist/index.mjs +2 -2
  343. package/dist/{tenantConfig-CYnS9TPV.d.mts → tenantConfig-DxpfrAof.d.mts} +1 -1
  344. package/dist/{tenantConfig-CYnS9TPV.d.ts → tenantConfig-DxpfrAof.d.ts} +1 -1
  345. package/dist/utils.d.mts +25 -25
  346. package/dist/utils.d.ts +25 -25
  347. package/dist/utils.js +1 -1
  348. package/dist/utils.mjs +1 -1
  349. package/eslint.config.mjs +2 -2
  350. package/package.json +1 -1
  351. package/tests/helpers/mockFactories.ts +218 -0
  352. package/tests/helpers/testUtils.tsx +66 -1
  353. package/vitest.config.ts +1 -0
  354. package/dist/chunk-2WAUZ6KI.js +0 -1
  355. package/dist/chunk-3IGZNZCT.mjs +0 -1
  356. package/dist/chunk-43L2PP77.mjs +0 -1
  357. package/dist/chunk-6VS5OT3A.mjs +0 -1
  358. package/dist/chunk-BWJTTMKS.js +0 -1
  359. package/dist/chunk-EMPPCCVU.js +0 -1
  360. package/dist/chunk-J43UPGBE.js +0 -1
  361. package/dist/chunk-K6ZRXOJ7.mjs +0 -1
  362. package/dist/chunk-RYQQZTEP.js +0 -1
  363. package/dist/chunk-VTMSOK4V.mjs +0 -1
@@ -0,0 +1,2092 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for hooks/useFileUpload/useFileUpload.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">hooks/useFileUpload</a> useFileUpload.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">95.81% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>641/669</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">92.46% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>135/146</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>3/3</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">95.81% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>641/669</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a>
521
+ <a name='L456'></a><a href='#L456'>456</a>
522
+ <a name='L457'></a><a href='#L457'>457</a>
523
+ <a name='L458'></a><a href='#L458'>458</a>
524
+ <a name='L459'></a><a href='#L459'>459</a>
525
+ <a name='L460'></a><a href='#L460'>460</a>
526
+ <a name='L461'></a><a href='#L461'>461</a>
527
+ <a name='L462'></a><a href='#L462'>462</a>
528
+ <a name='L463'></a><a href='#L463'>463</a>
529
+ <a name='L464'></a><a href='#L464'>464</a>
530
+ <a name='L465'></a><a href='#L465'>465</a>
531
+ <a name='L466'></a><a href='#L466'>466</a>
532
+ <a name='L467'></a><a href='#L467'>467</a>
533
+ <a name='L468'></a><a href='#L468'>468</a>
534
+ <a name='L469'></a><a href='#L469'>469</a>
535
+ <a name='L470'></a><a href='#L470'>470</a>
536
+ <a name='L471'></a><a href='#L471'>471</a>
537
+ <a name='L472'></a><a href='#L472'>472</a>
538
+ <a name='L473'></a><a href='#L473'>473</a>
539
+ <a name='L474'></a><a href='#L474'>474</a>
540
+ <a name='L475'></a><a href='#L475'>475</a>
541
+ <a name='L476'></a><a href='#L476'>476</a>
542
+ <a name='L477'></a><a href='#L477'>477</a>
543
+ <a name='L478'></a><a href='#L478'>478</a>
544
+ <a name='L479'></a><a href='#L479'>479</a>
545
+ <a name='L480'></a><a href='#L480'>480</a>
546
+ <a name='L481'></a><a href='#L481'>481</a>
547
+ <a name='L482'></a><a href='#L482'>482</a>
548
+ <a name='L483'></a><a href='#L483'>483</a>
549
+ <a name='L484'></a><a href='#L484'>484</a>
550
+ <a name='L485'></a><a href='#L485'>485</a>
551
+ <a name='L486'></a><a href='#L486'>486</a>
552
+ <a name='L487'></a><a href='#L487'>487</a>
553
+ <a name='L488'></a><a href='#L488'>488</a>
554
+ <a name='L489'></a><a href='#L489'>489</a>
555
+ <a name='L490'></a><a href='#L490'>490</a>
556
+ <a name='L491'></a><a href='#L491'>491</a>
557
+ <a name='L492'></a><a href='#L492'>492</a>
558
+ <a name='L493'></a><a href='#L493'>493</a>
559
+ <a name='L494'></a><a href='#L494'>494</a>
560
+ <a name='L495'></a><a href='#L495'>495</a>
561
+ <a name='L496'></a><a href='#L496'>496</a>
562
+ <a name='L497'></a><a href='#L497'>497</a>
563
+ <a name='L498'></a><a href='#L498'>498</a>
564
+ <a name='L499'></a><a href='#L499'>499</a>
565
+ <a name='L500'></a><a href='#L500'>500</a>
566
+ <a name='L501'></a><a href='#L501'>501</a>
567
+ <a name='L502'></a><a href='#L502'>502</a>
568
+ <a name='L503'></a><a href='#L503'>503</a>
569
+ <a name='L504'></a><a href='#L504'>504</a>
570
+ <a name='L505'></a><a href='#L505'>505</a>
571
+ <a name='L506'></a><a href='#L506'>506</a>
572
+ <a name='L507'></a><a href='#L507'>507</a>
573
+ <a name='L508'></a><a href='#L508'>508</a>
574
+ <a name='L509'></a><a href='#L509'>509</a>
575
+ <a name='L510'></a><a href='#L510'>510</a>
576
+ <a name='L511'></a><a href='#L511'>511</a>
577
+ <a name='L512'></a><a href='#L512'>512</a>
578
+ <a name='L513'></a><a href='#L513'>513</a>
579
+ <a name='L514'></a><a href='#L514'>514</a>
580
+ <a name='L515'></a><a href='#L515'>515</a>
581
+ <a name='L516'></a><a href='#L516'>516</a>
582
+ <a name='L517'></a><a href='#L517'>517</a>
583
+ <a name='L518'></a><a href='#L518'>518</a>
584
+ <a name='L519'></a><a href='#L519'>519</a>
585
+ <a name='L520'></a><a href='#L520'>520</a>
586
+ <a name='L521'></a><a href='#L521'>521</a>
587
+ <a name='L522'></a><a href='#L522'>522</a>
588
+ <a name='L523'></a><a href='#L523'>523</a>
589
+ <a name='L524'></a><a href='#L524'>524</a>
590
+ <a name='L525'></a><a href='#L525'>525</a>
591
+ <a name='L526'></a><a href='#L526'>526</a>
592
+ <a name='L527'></a><a href='#L527'>527</a>
593
+ <a name='L528'></a><a href='#L528'>528</a>
594
+ <a name='L529'></a><a href='#L529'>529</a>
595
+ <a name='L530'></a><a href='#L530'>530</a>
596
+ <a name='L531'></a><a href='#L531'>531</a>
597
+ <a name='L532'></a><a href='#L532'>532</a>
598
+ <a name='L533'></a><a href='#L533'>533</a>
599
+ <a name='L534'></a><a href='#L534'>534</a>
600
+ <a name='L535'></a><a href='#L535'>535</a>
601
+ <a name='L536'></a><a href='#L536'>536</a>
602
+ <a name='L537'></a><a href='#L537'>537</a>
603
+ <a name='L538'></a><a href='#L538'>538</a>
604
+ <a name='L539'></a><a href='#L539'>539</a>
605
+ <a name='L540'></a><a href='#L540'>540</a>
606
+ <a name='L541'></a><a href='#L541'>541</a>
607
+ <a name='L542'></a><a href='#L542'>542</a>
608
+ <a name='L543'></a><a href='#L543'>543</a>
609
+ <a name='L544'></a><a href='#L544'>544</a>
610
+ <a name='L545'></a><a href='#L545'>545</a>
611
+ <a name='L546'></a><a href='#L546'>546</a>
612
+ <a name='L547'></a><a href='#L547'>547</a>
613
+ <a name='L548'></a><a href='#L548'>548</a>
614
+ <a name='L549'></a><a href='#L549'>549</a>
615
+ <a name='L550'></a><a href='#L550'>550</a>
616
+ <a name='L551'></a><a href='#L551'>551</a>
617
+ <a name='L552'></a><a href='#L552'>552</a>
618
+ <a name='L553'></a><a href='#L553'>553</a>
619
+ <a name='L554'></a><a href='#L554'>554</a>
620
+ <a name='L555'></a><a href='#L555'>555</a>
621
+ <a name='L556'></a><a href='#L556'>556</a>
622
+ <a name='L557'></a><a href='#L557'>557</a>
623
+ <a name='L558'></a><a href='#L558'>558</a>
624
+ <a name='L559'></a><a href='#L559'>559</a>
625
+ <a name='L560'></a><a href='#L560'>560</a>
626
+ <a name='L561'></a><a href='#L561'>561</a>
627
+ <a name='L562'></a><a href='#L562'>562</a>
628
+ <a name='L563'></a><a href='#L563'>563</a>
629
+ <a name='L564'></a><a href='#L564'>564</a>
630
+ <a name='L565'></a><a href='#L565'>565</a>
631
+ <a name='L566'></a><a href='#L566'>566</a>
632
+ <a name='L567'></a><a href='#L567'>567</a>
633
+ <a name='L568'></a><a href='#L568'>568</a>
634
+ <a name='L569'></a><a href='#L569'>569</a>
635
+ <a name='L570'></a><a href='#L570'>570</a>
636
+ <a name='L571'></a><a href='#L571'>571</a>
637
+ <a name='L572'></a><a href='#L572'>572</a>
638
+ <a name='L573'></a><a href='#L573'>573</a>
639
+ <a name='L574'></a><a href='#L574'>574</a>
640
+ <a name='L575'></a><a href='#L575'>575</a>
641
+ <a name='L576'></a><a href='#L576'>576</a>
642
+ <a name='L577'></a><a href='#L577'>577</a>
643
+ <a name='L578'></a><a href='#L578'>578</a>
644
+ <a name='L579'></a><a href='#L579'>579</a>
645
+ <a name='L580'></a><a href='#L580'>580</a>
646
+ <a name='L581'></a><a href='#L581'>581</a>
647
+ <a name='L582'></a><a href='#L582'>582</a>
648
+ <a name='L583'></a><a href='#L583'>583</a>
649
+ <a name='L584'></a><a href='#L584'>584</a>
650
+ <a name='L585'></a><a href='#L585'>585</a>
651
+ <a name='L586'></a><a href='#L586'>586</a>
652
+ <a name='L587'></a><a href='#L587'>587</a>
653
+ <a name='L588'></a><a href='#L588'>588</a>
654
+ <a name='L589'></a><a href='#L589'>589</a>
655
+ <a name='L590'></a><a href='#L590'>590</a>
656
+ <a name='L591'></a><a href='#L591'>591</a>
657
+ <a name='L592'></a><a href='#L592'>592</a>
658
+ <a name='L593'></a><a href='#L593'>593</a>
659
+ <a name='L594'></a><a href='#L594'>594</a>
660
+ <a name='L595'></a><a href='#L595'>595</a>
661
+ <a name='L596'></a><a href='#L596'>596</a>
662
+ <a name='L597'></a><a href='#L597'>597</a>
663
+ <a name='L598'></a><a href='#L598'>598</a>
664
+ <a name='L599'></a><a href='#L599'>599</a>
665
+ <a name='L600'></a><a href='#L600'>600</a>
666
+ <a name='L601'></a><a href='#L601'>601</a>
667
+ <a name='L602'></a><a href='#L602'>602</a>
668
+ <a name='L603'></a><a href='#L603'>603</a>
669
+ <a name='L604'></a><a href='#L604'>604</a>
670
+ <a name='L605'></a><a href='#L605'>605</a>
671
+ <a name='L606'></a><a href='#L606'>606</a>
672
+ <a name='L607'></a><a href='#L607'>607</a>
673
+ <a name='L608'></a><a href='#L608'>608</a>
674
+ <a name='L609'></a><a href='#L609'>609</a>
675
+ <a name='L610'></a><a href='#L610'>610</a>
676
+ <a name='L611'></a><a href='#L611'>611</a>
677
+ <a name='L612'></a><a href='#L612'>612</a>
678
+ <a name='L613'></a><a href='#L613'>613</a>
679
+ <a name='L614'></a><a href='#L614'>614</a>
680
+ <a name='L615'></a><a href='#L615'>615</a>
681
+ <a name='L616'></a><a href='#L616'>616</a>
682
+ <a name='L617'></a><a href='#L617'>617</a>
683
+ <a name='L618'></a><a href='#L618'>618</a>
684
+ <a name='L619'></a><a href='#L619'>619</a>
685
+ <a name='L620'></a><a href='#L620'>620</a>
686
+ <a name='L621'></a><a href='#L621'>621</a>
687
+ <a name='L622'></a><a href='#L622'>622</a>
688
+ <a name='L623'></a><a href='#L623'>623</a>
689
+ <a name='L624'></a><a href='#L624'>624</a>
690
+ <a name='L625'></a><a href='#L625'>625</a>
691
+ <a name='L626'></a><a href='#L626'>626</a>
692
+ <a name='L627'></a><a href='#L627'>627</a>
693
+ <a name='L628'></a><a href='#L628'>628</a>
694
+ <a name='L629'></a><a href='#L629'>629</a>
695
+ <a name='L630'></a><a href='#L630'>630</a>
696
+ <a name='L631'></a><a href='#L631'>631</a>
697
+ <a name='L632'></a><a href='#L632'>632</a>
698
+ <a name='L633'></a><a href='#L633'>633</a>
699
+ <a name='L634'></a><a href='#L634'>634</a>
700
+ <a name='L635'></a><a href='#L635'>635</a>
701
+ <a name='L636'></a><a href='#L636'>636</a>
702
+ <a name='L637'></a><a href='#L637'>637</a>
703
+ <a name='L638'></a><a href='#L638'>638</a>
704
+ <a name='L639'></a><a href='#L639'>639</a>
705
+ <a name='L640'></a><a href='#L640'>640</a>
706
+ <a name='L641'></a><a href='#L641'>641</a>
707
+ <a name='L642'></a><a href='#L642'>642</a>
708
+ <a name='L643'></a><a href='#L643'>643</a>
709
+ <a name='L644'></a><a href='#L644'>644</a>
710
+ <a name='L645'></a><a href='#L645'>645</a>
711
+ <a name='L646'></a><a href='#L646'>646</a>
712
+ <a name='L647'></a><a href='#L647'>647</a>
713
+ <a name='L648'></a><a href='#L648'>648</a>
714
+ <a name='L649'></a><a href='#L649'>649</a>
715
+ <a name='L650'></a><a href='#L650'>650</a>
716
+ <a name='L651'></a><a href='#L651'>651</a>
717
+ <a name='L652'></a><a href='#L652'>652</a>
718
+ <a name='L653'></a><a href='#L653'>653</a>
719
+ <a name='L654'></a><a href='#L654'>654</a>
720
+ <a name='L655'></a><a href='#L655'>655</a>
721
+ <a name='L656'></a><a href='#L656'>656</a>
722
+ <a name='L657'></a><a href='#L657'>657</a>
723
+ <a name='L658'></a><a href='#L658'>658</a>
724
+ <a name='L659'></a><a href='#L659'>659</a>
725
+ <a name='L660'></a><a href='#L660'>660</a>
726
+ <a name='L661'></a><a href='#L661'>661</a>
727
+ <a name='L662'></a><a href='#L662'>662</a>
728
+ <a name='L663'></a><a href='#L663'>663</a>
729
+ <a name='L664'></a><a href='#L664'>664</a>
730
+ <a name='L665'></a><a href='#L665'>665</a>
731
+ <a name='L666'></a><a href='#L666'>666</a>
732
+ <a name='L667'></a><a href='#L667'>667</a>
733
+ <a name='L668'></a><a href='#L668'>668</a>
734
+ <a name='L669'></a><a href='#L669'>669</a>
735
+ <a name='L670'></a><a href='#L670'>670</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
736
+ <span class="cline-any cline-yes">1x</span>
737
+ <span class="cline-any cline-yes">1x</span>
738
+ <span class="cline-any cline-yes">1x</span>
739
+ <span class="cline-any cline-yes">1x</span>
740
+ <span class="cline-any cline-yes">1x</span>
741
+ <span class="cline-any cline-yes">1x</span>
742
+ <span class="cline-any cline-yes">1x</span>
743
+ <span class="cline-any cline-yes">1x</span>
744
+ <span class="cline-any cline-yes">1x</span>
745
+ <span class="cline-any cline-yes">1x</span>
746
+ <span class="cline-any cline-yes">1x</span>
747
+ <span class="cline-any cline-yes">1x</span>
748
+ <span class="cline-any cline-yes">1x</span>
749
+ <span class="cline-any cline-yes">1x</span>
750
+ <span class="cline-any cline-yes">1x</span>
751
+ <span class="cline-any cline-yes">1x</span>
752
+ <span class="cline-any cline-yes">1x</span>
753
+ <span class="cline-any cline-yes">1x</span>
754
+ <span class="cline-any cline-yes">1x</span>
755
+ <span class="cline-any cline-yes">1x</span>
756
+ <span class="cline-any cline-yes">1x</span>
757
+ <span class="cline-any cline-yes">1x</span>
758
+ <span class="cline-any cline-yes">1x</span>
759
+ <span class="cline-any cline-yes">1x</span>
760
+ <span class="cline-any cline-yes">1x</span>
761
+ <span class="cline-any cline-yes">1x</span>
762
+ <span class="cline-any cline-yes">1x</span>
763
+ <span class="cline-any cline-yes">1x</span>
764
+ <span class="cline-any cline-yes">1x</span>
765
+ <span class="cline-any cline-yes">1x</span>
766
+ <span class="cline-any cline-yes">1x</span>
767
+ <span class="cline-any cline-yes">141x</span>
768
+ <span class="cline-any cline-yes">141x</span>
769
+ <span class="cline-any cline-yes">1x</span>
770
+ <span class="cline-any cline-yes">1x</span>
771
+ <span class="cline-any cline-yes">1x</span>
772
+ <span class="cline-any cline-yes">1x</span>
773
+ <span class="cline-any cline-yes">1x</span>
774
+ <span class="cline-any cline-yes">1x</span>
775
+ <span class="cline-any cline-yes">1x</span>
776
+ <span class="cline-any cline-yes">1x</span>
777
+ <span class="cline-any cline-yes">1x</span>
778
+ <span class="cline-any cline-yes">1x</span>
779
+ <span class="cline-any cline-yes">1x</span>
780
+ <span class="cline-any cline-yes">1x</span>
781
+ <span class="cline-any cline-yes">1x</span>
782
+ <span class="cline-any cline-yes">1x</span>
783
+ <span class="cline-any cline-yes">1x</span>
784
+ <span class="cline-any cline-yes">1x</span>
785
+ <span class="cline-any cline-yes">1x</span>
786
+ <span class="cline-any cline-yes">1x</span>
787
+ <span class="cline-any cline-yes">1x</span>
788
+ <span class="cline-any cline-yes">1x</span>
789
+ <span class="cline-any cline-yes">1x</span>
790
+ <span class="cline-any cline-yes">1x</span>
791
+ <span class="cline-any cline-yes">1x</span>
792
+ <span class="cline-any cline-yes">1x</span>
793
+ <span class="cline-any cline-yes">1x</span>
794
+ <span class="cline-any cline-yes">1x</span>
795
+ <span class="cline-any cline-yes">1x</span>
796
+ <span class="cline-any cline-yes">1x</span>
797
+ <span class="cline-any cline-yes">1x</span>
798
+ <span class="cline-any cline-yes">1x</span>
799
+ <span class="cline-any cline-yes">1x</span>
800
+ <span class="cline-any cline-yes">1x</span>
801
+ <span class="cline-any cline-yes">284x</span>
802
+ <span class="cline-any cline-yes">284x</span>
803
+ <span class="cline-any cline-yes">284x</span>
804
+ <span class="cline-any cline-yes">284x</span>
805
+ <span class="cline-any cline-yes">284x</span>
806
+ <span class="cline-any cline-yes">284x</span>
807
+ <span class="cline-any cline-yes">284x</span>
808
+ <span class="cline-any cline-yes">284x</span>
809
+ <span class="cline-any cline-yes">284x</span>
810
+ <span class="cline-any cline-yes">284x</span>
811
+ <span class="cline-any cline-yes">284x</span>
812
+ <span class="cline-any cline-yes">284x</span>
813
+ <span class="cline-any cline-yes">284x</span>
814
+ <span class="cline-any cline-yes">284x</span>
815
+ <span class="cline-any cline-yes">284x</span>
816
+ <span class="cline-any cline-yes">284x</span>
817
+ <span class="cline-any cline-yes">284x</span>
818
+ <span class="cline-any cline-yes">284x</span>
819
+ <span class="cline-any cline-yes">284x</span>
820
+ <span class="cline-any cline-yes">284x</span>
821
+ <span class="cline-any cline-yes">284x</span>
822
+ <span class="cline-any cline-yes">284x</span>
823
+ <span class="cline-any cline-yes">284x</span>
824
+ <span class="cline-any cline-yes">7x</span>
825
+ <span class="cline-any cline-yes">284x</span>
826
+ <span class="cline-any cline-yes">284x</span>
827
+ <span class="cline-any cline-yes">284x</span>
828
+ <span class="cline-any cline-yes">284x</span>
829
+ <span class="cline-any cline-yes">284x</span>
830
+ <span class="cline-any cline-yes">284x</span>
831
+ <span class="cline-any cline-yes">1x</span>
832
+ <span class="cline-any cline-yes">1x</span>
833
+ <span class="cline-any cline-yes">284x</span>
834
+ <span class="cline-any cline-yes">284x</span>
835
+ <span class="cline-any cline-yes">284x</span>
836
+ <span class="cline-any cline-yes">284x</span>
837
+ <span class="cline-any cline-yes">284x</span>
838
+ <span class="cline-any cline-yes">284x</span>
839
+ <span class="cline-any cline-yes">58x</span>
840
+ <span class="cline-any cline-yes">54x</span>
841
+ <span class="cline-any cline-yes">54x</span>
842
+ <span class="cline-any cline-yes">58x</span>
843
+ <span class="cline-any cline-yes">284x</span>
844
+ <span class="cline-any cline-yes">284x</span>
845
+ <span class="cline-any cline-yes">284x</span>
846
+ <span class="cline-any cline-yes">284x</span>
847
+ <span class="cline-any cline-yes">284x</span>
848
+ <span class="cline-any cline-yes">284x</span>
849
+ <span class="cline-any cline-yes">284x</span>
850
+ <span class="cline-any cline-yes">133x</span>
851
+ <span class="cline-any cline-yes">133x</span>
852
+ <span class="cline-any cline-yes">284x</span>
853
+ <span class="cline-any cline-yes">284x</span>
854
+ <span class="cline-any cline-yes">284x</span>
855
+ <span class="cline-any cline-yes">284x</span>
856
+ <span class="cline-any cline-yes">284x</span>
857
+ <span class="cline-any cline-yes">284x</span>
858
+ <span class="cline-any cline-yes">284x</span>
859
+ <span class="cline-any cline-yes">284x</span>
860
+ <span class="cline-any cline-yes">284x</span>
861
+ <span class="cline-any cline-yes">284x</span>
862
+ <span class="cline-any cline-yes">284x</span>
863
+ <span class="cline-any cline-yes">284x</span>
864
+ <span class="cline-any cline-yes">284x</span>
865
+ <span class="cline-any cline-yes">284x</span>
866
+ <span class="cline-any cline-yes">284x</span>
867
+ <span class="cline-any cline-yes">284x</span>
868
+ <span class="cline-any cline-yes">21x</span>
869
+ <span class="cline-any cline-yes">19x</span>
870
+ <span class="cline-any cline-yes">19x</span>
871
+ <span class="cline-any cline-yes">19x</span>
872
+ <span class="cline-any cline-yes">19x</span>
873
+ <span class="cline-any cline-yes">19x</span>
874
+ <span class="cline-any cline-yes">19x</span>
875
+ <span class="cline-any cline-yes">19x</span>
876
+ <span class="cline-any cline-yes">21x</span>
877
+ <span class="cline-any cline-yes">21x</span>
878
+ <span class="cline-any cline-yes">284x</span>
879
+ <span class="cline-any cline-yes">284x</span>
880
+ <span class="cline-any cline-yes">284x</span>
881
+ <span class="cline-any cline-yes">284x</span>
882
+ <span class="cline-any cline-yes">284x</span>
883
+ <span class="cline-any cline-yes">284x</span>
884
+ <span class="cline-any cline-yes">284x</span>
885
+ <span class="cline-any cline-yes">284x</span>
886
+ <span class="cline-any cline-yes">7x</span>
887
+ <span class="cline-any cline-yes">5x</span>
888
+ <span class="cline-any cline-yes">5x</span>
889
+ <span class="cline-any cline-yes">5x</span>
890
+ <span class="cline-any cline-yes">5x</span>
891
+ <span class="cline-any cline-yes">5x</span>
892
+ <span class="cline-any cline-yes">7x</span>
893
+ <span class="cline-any cline-yes">7x</span>
894
+ <span class="cline-any cline-yes">284x</span>
895
+ <span class="cline-any cline-yes">284x</span>
896
+ <span class="cline-any cline-yes">284x</span>
897
+ <span class="cline-any cline-yes">284x</span>
898
+ <span class="cline-any cline-yes">284x</span>
899
+ <span class="cline-any cline-yes">284x</span>
900
+ <span class="cline-any cline-yes">284x</span>
901
+ <span class="cline-any cline-yes">284x</span>
902
+ <span class="cline-any cline-yes">29x</span>
903
+ <span class="cline-any cline-yes">29x</span>
904
+ <span class="cline-any cline-yes">29x</span>
905
+ <span class="cline-any cline-yes">23x</span>
906
+ <span class="cline-any cline-yes">23x</span>
907
+ <span class="cline-any cline-yes">23x</span>
908
+ <span class="cline-any cline-yes">23x</span>
909
+ <span class="cline-any cline-yes">23x</span>
910
+ <span class="cline-any cline-yes">23x</span>
911
+ <span class="cline-any cline-yes">23x</span>
912
+ <span class="cline-any cline-yes">23x</span>
913
+ <span class="cline-any cline-yes">21x</span>
914
+ <span class="cline-any cline-yes">21x</span>
915
+ <span class="cline-any cline-yes">21x</span>
916
+ <span class="cline-any cline-yes">21x</span>
917
+ <span class="cline-any cline-yes">21x</span>
918
+ <span class="cline-any cline-yes">21x</span>
919
+ <span class="cline-any cline-yes">21x</span>
920
+ <span class="cline-any cline-yes">21x</span>
921
+ <span class="cline-any cline-yes">21x</span>
922
+ <span class="cline-any cline-yes">21x</span>
923
+ <span class="cline-any cline-yes">29x</span>
924
+ <span class="cline-any cline-yes">7x</span>
925
+ <span class="cline-any cline-yes">7x</span>
926
+ <span class="cline-any cline-yes">7x</span>
927
+ <span class="cline-any cline-yes">7x</span>
928
+ <span class="cline-any cline-yes">7x</span>
929
+ <span class="cline-any cline-yes">7x</span>
930
+ <span class="cline-any cline-yes">7x</span>
931
+ <span class="cline-any cline-yes">7x</span>
932
+ <span class="cline-any cline-yes">7x</span>
933
+ <span class="cline-any cline-yes">7x</span>
934
+ <span class="cline-any cline-yes">29x</span>
935
+ <span class="cline-any cline-yes">284x</span>
936
+ <span class="cline-any cline-yes">284x</span>
937
+ <span class="cline-any cline-yes">284x</span>
938
+ <span class="cline-any cline-yes">284x</span>
939
+ <span class="cline-any cline-yes">284x</span>
940
+ <span class="cline-any cline-yes">284x</span>
941
+ <span class="cline-any cline-yes">284x</span>
942
+ <span class="cline-any cline-yes">284x</span>
943
+ <span class="cline-any cline-yes">284x</span>
944
+ <span class="cline-any cline-yes">35x</span>
945
+ <span class="cline-any cline-yes">27x</span>
946
+ <span class="cline-any cline-yes">27x</span>
947
+ <span class="cline-any cline-yes">8x</span>
948
+ <span class="cline-any cline-yes">8x</span>
949
+ <span class="cline-any cline-yes">35x</span>
950
+ <span class="cline-any cline-no">&nbsp;</span>
951
+ <span class="cline-any cline-no">&nbsp;</span>
952
+ <span class="cline-any cline-no">&nbsp;</span>
953
+ <span class="cline-any cline-yes">8x</span>
954
+ <span class="cline-any cline-yes">30x</span>
955
+ <span class="cline-any cline-yes">2x</span>
956
+ <span class="cline-any cline-yes">2x</span>
957
+ <span class="cline-any cline-yes">2x</span>
958
+ <span class="cline-any cline-yes">6x</span>
959
+ <span class="cline-any cline-yes">6x</span>
960
+ <span class="cline-any cline-yes">35x</span>
961
+ <span class="cline-any cline-yes">284x</span>
962
+ <span class="cline-any cline-yes">284x</span>
963
+ <span class="cline-any cline-yes">284x</span>
964
+ <span class="cline-any cline-yes">284x</span>
965
+ <span class="cline-any cline-yes">284x</span>
966
+ <span class="cline-any cline-yes">284x</span>
967
+ <span class="cline-any cline-yes">284x</span>
968
+ <span class="cline-any cline-yes">284x</span>
969
+ <span class="cline-any cline-yes">35x</span>
970
+ <span class="cline-any cline-yes">38x</span>
971
+ <span class="cline-any cline-yes">38x</span>
972
+ <span class="cline-any cline-yes">38x</span>
973
+ <span class="cline-any cline-yes">38x</span>
974
+ <span class="cline-any cline-yes">38x</span>
975
+ <span class="cline-any cline-yes">38x</span>
976
+ <span class="cline-any cline-yes">38x</span>
977
+ <span class="cline-any cline-yes">38x</span>
978
+ <span class="cline-any cline-yes">38x</span>
979
+ <span class="cline-any cline-yes">38x</span>
980
+ <span class="cline-any cline-yes">38x</span>
981
+ <span class="cline-any cline-yes">38x</span>
982
+ <span class="cline-any cline-yes">38x</span>
983
+ <span class="cline-any cline-yes">35x</span>
984
+ <span class="cline-any cline-yes">35x</span>
985
+ <span class="cline-any cline-yes">284x</span>
986
+ <span class="cline-any cline-yes">284x</span>
987
+ <span class="cline-any cline-yes">284x</span>
988
+ <span class="cline-any cline-yes">284x</span>
989
+ <span class="cline-any cline-yes">284x</span>
990
+ <span class="cline-any cline-yes">284x</span>
991
+ <span class="cline-any cline-yes">284x</span>
992
+ <span class="cline-any cline-yes">284x</span>
993
+ <span class="cline-any cline-yes">33x</span>
994
+ <span class="cline-any cline-yes">33x</span>
995
+ <span class="cline-any cline-yes">33x</span>
996
+ <span class="cline-any cline-yes">28x</span>
997
+ <span class="cline-any cline-yes">28x</span>
998
+ <span class="cline-any cline-yes">28x</span>
999
+ <span class="cline-any cline-yes">28x</span>
1000
+ <span class="cline-any cline-yes">28x</span>
1001
+ <span class="cline-any cline-yes">28x</span>
1002
+ <span class="cline-any cline-yes">27x</span>
1003
+ <span class="cline-any cline-yes">28x</span>
1004
+ <span class="cline-any cline-yes">28x</span>
1005
+ <span class="cline-any cline-yes">28x</span>
1006
+ <span class="cline-any cline-yes">33x</span>
1007
+ <span class="cline-any cline-yes">284x</span>
1008
+ <span class="cline-any cline-yes">284x</span>
1009
+ <span class="cline-any cline-yes">284x</span>
1010
+ <span class="cline-any cline-yes">284x</span>
1011
+ <span class="cline-any cline-yes">284x</span>
1012
+ <span class="cline-any cline-yes">284x</span>
1013
+ <span class="cline-any cline-yes">284x</span>
1014
+ <span class="cline-any cline-yes">284x</span>
1015
+ <span class="cline-any cline-yes">35x</span>
1016
+ <span class="cline-any cline-yes">35x</span>
1017
+ <span class="cline-any cline-yes">35x</span>
1018
+ <span class="cline-any cline-yes">35x</span>
1019
+ <span class="cline-any cline-yes">35x</span>
1020
+ <span class="cline-any cline-yes">35x</span>
1021
+ <span class="cline-any cline-yes">35x</span>
1022
+ <span class="cline-any cline-yes">35x</span>
1023
+ <span class="cline-any cline-yes">35x</span>
1024
+ <span class="cline-any cline-no">&nbsp;</span>
1025
+ <span class="cline-any cline-no">&nbsp;</span>
1026
+ <span class="cline-any cline-yes">35x</span>
1027
+ <span class="cline-any cline-yes">35x</span>
1028
+ <span class="cline-any cline-yes">35x</span>
1029
+ <span class="cline-any cline-yes">35x</span>
1030
+ <span class="cline-any cline-yes">35x</span>
1031
+ <span class="cline-any cline-yes">35x</span>
1032
+ <span class="cline-any cline-yes">35x</span>
1033
+ <span class="cline-any cline-yes">35x</span>
1034
+ <span class="cline-any cline-yes">35x</span>
1035
+ <span class="cline-any cline-yes">35x</span>
1036
+ <span class="cline-any cline-yes">35x</span>
1037
+ <span class="cline-any cline-yes">35x</span>
1038
+ <span class="cline-any cline-yes">35x</span>
1039
+ <span class="cline-any cline-yes">284x</span>
1040
+ <span class="cline-any cline-yes">284x</span>
1041
+ <span class="cline-any cline-yes">284x</span>
1042
+ <span class="cline-any cline-yes">284x</span>
1043
+ <span class="cline-any cline-yes">284x</span>
1044
+ <span class="cline-any cline-yes">284x</span>
1045
+ <span class="cline-any cline-yes">284x</span>
1046
+ <span class="cline-any cline-yes">284x</span>
1047
+ <span class="cline-any cline-yes">284x</span>
1048
+ <span class="cline-any cline-yes">284x</span>
1049
+ <span class="cline-any cline-yes">284x</span>
1050
+ <span class="cline-any cline-yes">20x</span>
1051
+ <span class="cline-any cline-yes">20x</span>
1052
+ <span class="cline-any cline-no">&nbsp;</span>
1053
+ <span class="cline-any cline-no">&nbsp;</span>
1054
+ <span class="cline-any cline-yes">20x</span>
1055
+ <span class="cline-any cline-yes">20x</span>
1056
+ <span class="cline-any cline-yes">20x</span>
1057
+ <span class="cline-any cline-yes">20x</span>
1058
+ <span class="cline-any cline-yes">20x</span>
1059
+ <span class="cline-any cline-yes">20x</span>
1060
+ <span class="cline-any cline-yes">20x</span>
1061
+ <span class="cline-any cline-yes">20x</span>
1062
+ <span class="cline-any cline-yes">20x</span>
1063
+ <span class="cline-any cline-yes">5x</span>
1064
+ <span class="cline-any cline-yes">5x</span>
1065
+ <span class="cline-any cline-yes">5x</span>
1066
+ <span class="cline-any cline-yes">15x</span>
1067
+ <span class="cline-any cline-yes">15x</span>
1068
+ <span class="cline-any cline-yes">15x</span>
1069
+ <span class="cline-any cline-yes">15x</span>
1070
+ <span class="cline-any cline-yes">15x</span>
1071
+ <span class="cline-any cline-yes">15x</span>
1072
+ <span class="cline-any cline-yes">15x</span>
1073
+ <span class="cline-any cline-yes">15x</span>
1074
+ <span class="cline-any cline-yes">15x</span>
1075
+ <span class="cline-any cline-yes">15x</span>
1076
+ <span class="cline-any cline-yes">15x</span>
1077
+ <span class="cline-any cline-yes">15x</span>
1078
+ <span class="cline-any cline-yes">15x</span>
1079
+ <span class="cline-any cline-yes">15x</span>
1080
+ <span class="cline-any cline-yes">20x</span>
1081
+ <span class="cline-any cline-yes">284x</span>
1082
+ <span class="cline-any cline-yes">284x</span>
1083
+ <span class="cline-any cline-yes">284x</span>
1084
+ <span class="cline-any cline-yes">284x</span>
1085
+ <span class="cline-any cline-yes">284x</span>
1086
+ <span class="cline-any cline-yes">284x</span>
1087
+ <span class="cline-any cline-yes">284x</span>
1088
+ <span class="cline-any cline-yes">284x</span>
1089
+ <span class="cline-any cline-yes">284x</span>
1090
+ <span class="cline-any cline-yes">5x</span>
1091
+ <span class="cline-any cline-yes">5x</span>
1092
+ <span class="cline-any cline-yes">1x</span>
1093
+ <span class="cline-any cline-yes">1x</span>
1094
+ <span class="cline-any cline-yes">4x</span>
1095
+ <span class="cline-any cline-yes">4x</span>
1096
+ <span class="cline-any cline-yes">5x</span>
1097
+ <span class="cline-any cline-yes">1x</span>
1098
+ <span class="cline-any cline-yes">1x</span>
1099
+ <span class="cline-any cline-yes">1x</span>
1100
+ <span class="cline-any cline-yes">1x</span>
1101
+ <span class="cline-any cline-yes">1x</span>
1102
+ <span class="cline-any cline-yes">1x</span>
1103
+ <span class="cline-any cline-yes">1x</span>
1104
+ <span class="cline-any cline-yes">3x</span>
1105
+ <span class="cline-any cline-yes">3x</span>
1106
+ <span class="cline-any cline-yes">3x</span>
1107
+ <span class="cline-any cline-yes">3x</span>
1108
+ <span class="cline-any cline-yes">3x</span>
1109
+ <span class="cline-any cline-yes">3x</span>
1110
+ <span class="cline-any cline-yes">3x</span>
1111
+ <span class="cline-any cline-yes">3x</span>
1112
+ <span class="cline-any cline-yes">3x</span>
1113
+ <span class="cline-any cline-yes">3x</span>
1114
+ <span class="cline-any cline-yes">3x</span>
1115
+ <span class="cline-any cline-yes">3x</span>
1116
+ <span class="cline-any cline-yes">3x</span>
1117
+ <span class="cline-any cline-yes">5x</span>
1118
+ <span class="cline-any cline-yes">5x</span>
1119
+ <span class="cline-any cline-yes">284x</span>
1120
+ <span class="cline-any cline-yes">284x</span>
1121
+ <span class="cline-any cline-yes">284x</span>
1122
+ <span class="cline-any cline-yes">284x</span>
1123
+ <span class="cline-any cline-yes">284x</span>
1124
+ <span class="cline-any cline-yes">284x</span>
1125
+ <span class="cline-any cline-yes">284x</span>
1126
+ <span class="cline-any cline-yes">284x</span>
1127
+ <span class="cline-any cline-yes">284x</span>
1128
+ <span class="cline-any cline-yes">4x</span>
1129
+ <span class="cline-any cline-yes">4x</span>
1130
+ <span class="cline-any cline-yes">4x</span>
1131
+ <span class="cline-any cline-yes">2x</span>
1132
+ <span class="cline-any cline-yes">2x</span>
1133
+ <span class="cline-any cline-yes">2x</span>
1134
+ <span class="cline-any cline-yes">2x</span>
1135
+ <span class="cline-any cline-yes">2x</span>
1136
+ <span class="cline-any cline-yes">2x</span>
1137
+ <span class="cline-any cline-yes">2x</span>
1138
+ <span class="cline-any cline-yes">2x</span>
1139
+ <span class="cline-any cline-yes">2x</span>
1140
+ <span class="cline-any cline-yes">2x</span>
1141
+ <span class="cline-any cline-yes">2x</span>
1142
+ <span class="cline-any cline-yes">2x</span>
1143
+ <span class="cline-any cline-yes">2x</span>
1144
+ <span class="cline-any cline-yes">2x</span>
1145
+ <span class="cline-any cline-yes">4x</span>
1146
+ <span class="cline-any cline-yes">284x</span>
1147
+ <span class="cline-any cline-yes">284x</span>
1148
+ <span class="cline-any cline-yes">284x</span>
1149
+ <span class="cline-any cline-yes">284x</span>
1150
+ <span class="cline-any cline-yes">284x</span>
1151
+ <span class="cline-any cline-yes">284x</span>
1152
+ <span class="cline-any cline-yes">284x</span>
1153
+ <span class="cline-any cline-yes">2x</span>
1154
+ <span class="cline-any cline-yes">1x</span>
1155
+ <span class="cline-any cline-yes">1x</span>
1156
+ <span class="cline-any cline-yes">1x</span>
1157
+ <span class="cline-any cline-yes">1x</span>
1158
+ <span class="cline-any cline-yes">1x</span>
1159
+ <span class="cline-any cline-yes">2x</span>
1160
+ <span class="cline-any cline-yes">1x</span>
1161
+ <span class="cline-any cline-yes">1x</span>
1162
+ <span class="cline-any cline-yes">1x</span>
1163
+ <span class="cline-any cline-yes">1x</span>
1164
+ <span class="cline-any cline-yes">1x</span>
1165
+ <span class="cline-any cline-yes">284x</span>
1166
+ <span class="cline-any cline-yes">284x</span>
1167
+ <span class="cline-any cline-yes">284x</span>
1168
+ <span class="cline-any cline-yes">284x</span>
1169
+ <span class="cline-any cline-yes">284x</span>
1170
+ <span class="cline-any cline-yes">284x</span>
1171
+ <span class="cline-any cline-yes">284x</span>
1172
+ <span class="cline-any cline-yes">3x</span>
1173
+ <span class="cline-any cline-yes">1x</span>
1174
+ <span class="cline-any cline-yes">1x</span>
1175
+ <span class="cline-any cline-yes">2x</span>
1176
+ <span class="cline-any cline-yes">2x</span>
1177
+ <span class="cline-any cline-yes">2x</span>
1178
+ <span class="cline-any cline-yes">2x</span>
1179
+ <span class="cline-any cline-yes">3x</span>
1180
+ <span class="cline-any cline-yes">4x</span>
1181
+ <span class="cline-any cline-yes">4x</span>
1182
+ <span class="cline-any cline-no">&nbsp;</span>
1183
+ <span class="cline-any cline-no">&nbsp;</span>
1184
+ <span class="cline-any cline-no">&nbsp;</span>
1185
+ <span class="cline-any cline-no">&nbsp;</span>
1186
+ <span class="cline-any cline-yes">4x</span>
1187
+ <span class="cline-any cline-yes">4x</span>
1188
+ <span class="cline-any cline-yes">4x</span>
1189
+ <span class="cline-any cline-yes">4x</span>
1190
+ <span class="cline-any cline-yes">4x</span>
1191
+ <span class="cline-any cline-yes">3x</span>
1192
+ <span class="cline-any cline-yes">3x</span>
1193
+ <span class="cline-any cline-yes">4x</span>
1194
+ <span class="cline-any cline-yes">1x</span>
1195
+ <span class="cline-any cline-yes">1x</span>
1196
+ <span class="cline-any cline-yes">4x</span>
1197
+ <span class="cline-any cline-yes">2x</span>
1198
+ <span class="cline-any cline-yes">2x</span>
1199
+ <span class="cline-any cline-yes">2x</span>
1200
+ <span class="cline-any cline-yes">2x</span>
1201
+ <span class="cline-any cline-yes">2x</span>
1202
+ <span class="cline-any cline-yes">2x</span>
1203
+ <span class="cline-any cline-yes">2x</span>
1204
+ <span class="cline-any cline-yes">2x</span>
1205
+ <span class="cline-any cline-yes">2x</span>
1206
+ <span class="cline-any cline-yes">2x</span>
1207
+ <span class="cline-any cline-yes">2x</span>
1208
+ <span class="cline-any cline-yes">284x</span>
1209
+ <span class="cline-any cline-yes">284x</span>
1210
+ <span class="cline-any cline-yes">284x</span>
1211
+ <span class="cline-any cline-yes">284x</span>
1212
+ <span class="cline-any cline-yes">284x</span>
1213
+ <span class="cline-any cline-yes">284x</span>
1214
+ <span class="cline-any cline-yes">2x</span>
1215
+ <span class="cline-any cline-yes">2x</span>
1216
+ <span class="cline-any cline-yes">284x</span>
1217
+ <span class="cline-any cline-yes">284x</span>
1218
+ <span class="cline-any cline-yes">284x</span>
1219
+ <span class="cline-any cline-yes">284x</span>
1220
+ <span class="cline-any cline-yes">284x</span>
1221
+ <span class="cline-any cline-yes">284x</span>
1222
+ <span class="cline-any cline-yes">284x</span>
1223
+ <span class="cline-any cline-yes">2x</span>
1224
+ <span class="cline-any cline-yes">2x</span>
1225
+ <span class="cline-any cline-yes">1x</span>
1226
+ <span class="cline-any cline-yes">1x</span>
1227
+ <span class="cline-any cline-yes">1x</span>
1228
+ <span class="cline-any cline-yes">1x</span>
1229
+ <span class="cline-any cline-yes">1x</span>
1230
+ <span class="cline-any cline-yes">1x</span>
1231
+ <span class="cline-any cline-yes">1x</span>
1232
+ <span class="cline-any cline-yes">1x</span>
1233
+ <span class="cline-any cline-yes">1x</span>
1234
+ <span class="cline-any cline-yes">1x</span>
1235
+ <span class="cline-any cline-yes">1x</span>
1236
+ <span class="cline-any cline-yes">1x</span>
1237
+ <span class="cline-any cline-yes">1x</span>
1238
+ <span class="cline-any cline-yes">1x</span>
1239
+ <span class="cline-any cline-yes">2x</span>
1240
+ <span class="cline-any cline-yes">284x</span>
1241
+ <span class="cline-any cline-yes">284x</span>
1242
+ <span class="cline-any cline-yes">284x</span>
1243
+ <span class="cline-any cline-yes">284x</span>
1244
+ <span class="cline-any cline-yes">284x</span>
1245
+ <span class="cline-any cline-yes">284x</span>
1246
+ <span class="cline-any cline-yes">284x</span>
1247
+ <span class="cline-any cline-yes">284x</span>
1248
+ <span class="cline-any cline-no">&nbsp;</span>
1249
+ <span class="cline-any cline-no">&nbsp;</span>
1250
+ <span class="cline-any cline-no">&nbsp;</span>
1251
+ <span class="cline-any cline-no">&nbsp;</span>
1252
+ <span class="cline-any cline-no">&nbsp;</span>
1253
+ <span class="cline-any cline-yes">284x</span>
1254
+ <span class="cline-any cline-yes">284x</span>
1255
+ <span class="cline-any cline-yes">284x</span>
1256
+ <span class="cline-any cline-yes">284x</span>
1257
+ <span class="cline-any cline-yes">284x</span>
1258
+ <span class="cline-any cline-yes">284x</span>
1259
+ <span class="cline-any cline-yes">284x</span>
1260
+ <span class="cline-any cline-yes">284x</span>
1261
+ <span class="cline-any cline-no">&nbsp;</span>
1262
+ <span class="cline-any cline-no">&nbsp;</span>
1263
+ <span class="cline-any cline-no">&nbsp;</span>
1264
+ <span class="cline-any cline-no">&nbsp;</span>
1265
+ <span class="cline-any cline-no">&nbsp;</span>
1266
+ <span class="cline-any cline-no">&nbsp;</span>
1267
+ <span class="cline-any cline-no">&nbsp;</span>
1268
+ <span class="cline-any cline-no">&nbsp;</span>
1269
+ <span class="cline-any cline-no">&nbsp;</span>
1270
+ <span class="cline-any cline-no">&nbsp;</span>
1271
+ <span class="cline-any cline-yes">284x</span>
1272
+ <span class="cline-any cline-yes">284x</span>
1273
+ <span class="cline-any cline-yes">284x</span>
1274
+ <span class="cline-any cline-yes">284x</span>
1275
+ <span class="cline-any cline-yes">284x</span>
1276
+ <span class="cline-any cline-yes">284x</span>
1277
+ <span class="cline-any cline-yes">284x</span>
1278
+ <span class="cline-any cline-yes">284x</span>
1279
+ <span class="cline-any cline-yes">284x</span>
1280
+ <span class="cline-any cline-yes">55x</span>
1281
+ <span class="cline-any cline-yes">55x</span>
1282
+ <span class="cline-any cline-yes">55x</span>
1283
+ <span class="cline-any cline-yes">55x</span>
1284
+ <span class="cline-any cline-yes">69x</span>
1285
+ <span class="cline-any cline-yes">69x</span>
1286
+ <span class="cline-any cline-yes">69x</span>
1287
+ <span class="cline-any cline-yes">69x</span>
1288
+ <span class="cline-any cline-yes">69x</span>
1289
+ <span class="cline-any cline-yes">69x</span>
1290
+ <span class="cline-any cline-yes">69x</span>
1291
+ <span class="cline-any cline-yes">69x</span>
1292
+ <span class="cline-any cline-yes">69x</span>
1293
+ <span class="cline-any cline-yes">69x</span>
1294
+ <span class="cline-any cline-yes">69x</span>
1295
+ <span class="cline-any cline-yes">69x</span>
1296
+ <span class="cline-any cline-yes">69x</span>
1297
+ <span class="cline-any cline-yes">69x</span>
1298
+ <span class="cline-any cline-yes">69x</span>
1299
+ <span class="cline-any cline-yes">69x</span>
1300
+ <span class="cline-any cline-yes">69x</span>
1301
+ <span class="cline-any cline-yes">69x</span>
1302
+ <span class="cline-any cline-yes">69x</span>
1303
+ <span class="cline-any cline-yes">69x</span>
1304
+ <span class="cline-any cline-yes">69x</span>
1305
+ <span class="cline-any cline-yes">69x</span>
1306
+ <span class="cline-any cline-yes">69x</span>
1307
+ <span class="cline-any cline-yes">69x</span>
1308
+ <span class="cline-any cline-yes">55x</span>
1309
+ <span class="cline-any cline-yes">55x</span>
1310
+ <span class="cline-any cline-yes">55x</span>
1311
+ <span class="cline-any cline-yes">55x</span>
1312
+ <span class="cline-any cline-yes">55x</span>
1313
+ <span class="cline-any cline-yes">284x</span>
1314
+ <span class="cline-any cline-yes">284x</span>
1315
+ <span class="cline-any cline-yes">284x</span>
1316
+ <span class="cline-any cline-yes">284x</span>
1317
+ <span class="cline-any cline-yes">284x</span>
1318
+ <span class="cline-any cline-yes">284x</span>
1319
+ <span class="cline-any cline-yes">284x</span>
1320
+ <span class="cline-any cline-yes">284x</span>
1321
+ <span class="cline-any cline-yes">284x</span>
1322
+ <span class="cline-any cline-yes">284x</span>
1323
+ <span class="cline-any cline-yes">6x</span>
1324
+ <span class="cline-any cline-yes">6x</span>
1325
+ <span class="cline-any cline-yes">2x</span>
1326
+ <span class="cline-any cline-yes">2x</span>
1327
+ <span class="cline-any cline-yes">4x</span>
1328
+ <span class="cline-any cline-yes">4x</span>
1329
+ <span class="cline-any cline-yes">6x</span>
1330
+ <span class="cline-any cline-no">&nbsp;</span>
1331
+ <span class="cline-any cline-no">&nbsp;</span>
1332
+ <span class="cline-any cline-yes">4x</span>
1333
+ <span class="cline-any cline-yes">4x</span>
1334
+ <span class="cline-any cline-yes">4x</span>
1335
+ <span class="cline-any cline-yes">6x</span>
1336
+ <span class="cline-any cline-yes">284x</span>
1337
+ <span class="cline-any cline-yes">284x</span>
1338
+ <span class="cline-any cline-yes">284x</span>
1339
+ <span class="cline-any cline-yes">284x</span>
1340
+ <span class="cline-any cline-yes">284x</span>
1341
+ <span class="cline-any cline-yes">276x</span>
1342
+ <span class="cline-any cline-yes">284x</span>
1343
+ <span class="cline-any cline-yes">284x</span>
1344
+ <span class="cline-any cline-yes">284x</span>
1345
+ <span class="cline-any cline-yes">276x</span>
1346
+ <span class="cline-any cline-yes">284x</span>
1347
+ <span class="cline-any cline-yes">284x</span>
1348
+ <span class="cline-any cline-yes">284x</span>
1349
+ <span class="cline-any cline-yes">276x</span>
1350
+ <span class="cline-any cline-yes">284x</span>
1351
+ <span class="cline-any cline-yes">284x</span>
1352
+ <span class="cline-any cline-yes">284x</span>
1353
+ <span class="cline-any cline-yes">284x</span>
1354
+ <span class="cline-any cline-yes">276x</span>
1355
+ <span class="cline-any cline-yes">284x</span>
1356
+ <span class="cline-any cline-yes">284x</span>
1357
+ <span class="cline-any cline-yes">284x</span>
1358
+ <span class="cline-any cline-yes">284x</span>
1359
+ <span class="cline-any cline-yes">276x</span>
1360
+ <span class="cline-any cline-yes">276x</span>
1361
+ <span class="cline-any cline-yes">284x</span>
1362
+ <span class="cline-any cline-yes">284x</span>
1363
+ <span class="cline-any cline-yes">284x</span>
1364
+ <span class="cline-any cline-yes">284x</span>
1365
+ <span class="cline-any cline-yes">284x</span>
1366
+ <span class="cline-any cline-yes">284x</span>
1367
+ <span class="cline-any cline-yes">284x</span>
1368
+ <span class="cline-any cline-yes">284x</span>
1369
+ <span class="cline-any cline-yes">284x</span>
1370
+ <span class="cline-any cline-yes">284x</span>
1371
+ <span class="cline-any cline-yes">284x</span>
1372
+ <span class="cline-any cline-yes">284x</span>
1373
+ <span class="cline-any cline-yes">284x</span>
1374
+ <span class="cline-any cline-yes">284x</span>
1375
+ <span class="cline-any cline-yes">284x</span>
1376
+ <span class="cline-any cline-yes">284x</span>
1377
+ <span class="cline-any cline-yes">284x</span>
1378
+ <span class="cline-any cline-yes">284x</span>
1379
+ <span class="cline-any cline-yes">284x</span>
1380
+ <span class="cline-any cline-yes">284x</span>
1381
+ <span class="cline-any cline-yes">284x</span>
1382
+ <span class="cline-any cline-yes">284x</span>
1383
+ <span class="cline-any cline-yes">284x</span>
1384
+ <span class="cline-any cline-yes">284x</span>
1385
+ <span class="cline-any cline-yes">284x</span>
1386
+ <span class="cline-any cline-yes">284x</span>
1387
+ <span class="cline-any cline-yes">284x</span>
1388
+ <span class="cline-any cline-yes">284x</span>
1389
+ <span class="cline-any cline-yes">284x</span>
1390
+ <span class="cline-any cline-yes">284x</span>
1391
+ <span class="cline-any cline-yes">284x</span>
1392
+ <span class="cline-any cline-yes">284x</span>
1393
+ <span class="cline-any cline-yes">284x</span>
1394
+ <span class="cline-any cline-yes">284x</span>
1395
+ <span class="cline-any cline-yes">284x</span>
1396
+ <span class="cline-any cline-yes">284x</span>
1397
+ <span class="cline-any cline-yes">284x</span>
1398
+ <span class="cline-any cline-yes">284x</span>
1399
+ <span class="cline-any cline-yes">284x</span>
1400
+ <span class="cline-any cline-yes">284x</span>
1401
+ <span class="cline-any cline-yes">284x</span>
1402
+ <span class="cline-any cline-yes">1x</span>
1403
+ <span class="cline-any cline-yes">1x</span>
1404
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/**
1405
+ * Complete hook for file handling with:
1406
+ * - Progressive upload to S3 with pre-signed URLs
1407
+ * - Per-file progress tracking
1408
+ * - Type and size validation
1409
+ * - Soft delete (disableFile)
1410
+ * - Multiple file support
1411
+ */
1412
+ &nbsp;
1413
+ import { useState, useCallback, useRef, useMemo } from 'react';
1414
+ import { logger } from '../../utils/logger';
1415
+ &nbsp;
1416
+ // Import types from dedicated types file
1417
+ import type { FileStatus, FileItem, UseFileUploadOptions, UseFileUploadReturn } from './types';
1418
+ &nbsp;
1419
+ // Import utilities
1420
+ import { generateFileId, extractRelativePath } from './utils/fileUtils';
1421
+ import { inferContentType } from './utils/mimeTypes';
1422
+ import { validateFile as validateFileUtil, validateFileCounts } from './utils/validation';
1423
+ &nbsp;
1424
+ // Import services
1425
+ import {
1426
+ generateSignedUploadUrl,
1427
+ uploadToSignedUrl,
1428
+ deleteFile as deleteFileService,
1429
+ getSignedPreviewUrl,
1430
+ } from './services/uploadService';
1431
+ &nbsp;
1432
+ // Re-export types for backwards compatibility
1433
+ export type { FileStatus, FileItem, UseFileUploadOptions, UseFileUploadReturn } from './types';
1434
+ &nbsp;
1435
+ const hasCompletedFilePath = (file: FileItem): file is FileItem &amp; { filePath: string } =&gt; {
1436
+ return file.status === 'completed' &amp;&amp; typeof file.filePath === 'string' &amp;&amp; file.filePath.length &gt; 0;
1437
+ };
1438
+ &nbsp;
1439
+ /**
1440
+ * Hook for complete file handling with S3 upload
1441
+ *
1442
+ * @example
1443
+ * ```tsx
1444
+ * const {
1445
+ * files,
1446
+ * addFiles,
1447
+ * removeFile,
1448
+ * isUploading,
1449
+ * isValid,
1450
+ * completedS3Keys
1451
+ * } = useFileUpload({
1452
+ * acceptedTypes: ["image/png", "image/jpeg", "application/pdf"],
1453
+ * maxFileSize: 5 * 1024 * 1024, // 5MB
1454
+ * maxFiles: 3,
1455
+ * minFiles: 1
1456
+ * });
1457
+ *
1458
+ * // In form submit
1459
+ * const handleSubmit = async () =&gt; {
1460
+ * await waitForUploads(); // Wait for pending uploads
1461
+ * if (!isValid) return;
1462
+ *
1463
+ * await crudify.createItem("documents", {
1464
+ * files: completedS3Keys
1465
+ * });
1466
+ * };
1467
+ * ```
1468
+ */
1469
+ export const useFileUpload = (options: UseFileUploadOptions = {}): UseFileUploadReturn =&gt; {
1470
+ const {
1471
+ acceptedTypes,
1472
+ maxFileSize = 10 * 1024 * 1024, // 10MB default
1473
+ maxFiles,
1474
+ minFiles = 0,
1475
+ visibility = 'private',
1476
+ onUploadComplete,
1477
+ onUploadError,
1478
+ onFileRemoved,
1479
+ onFilesChange,
1480
+ mode = 'edit', // Default to edit mode for backwards compatibility
1481
+ } = options;
1482
+ &nbsp;
1483
+ const [files, setFiles] = useState&lt;FileItem[]&gt;([]);
1484
+ const [isTouched, setIsTouched] = useState(false);
1485
+ const [isSubmitted, setIsSubmitted] = useState(false);
1486
+ const [pendingDeletions, setPendingDeletions] = useState&lt;string[]&gt;([]);
1487
+ const uploadPromisesRef = useRef&lt;Map&lt;string, Promise&lt;void&gt;&gt;&gt;(new Map());
1488
+ &nbsp;
1489
+ /**
1490
+ * Marks the field as touched (to show validation errors)
1491
+ */
1492
+ const markAsTouched = useCallback(() =&gt; {
1493
+ setIsTouched(true);
1494
+ }, []);
1495
+ &nbsp;
1496
+ /**
1497
+ * Marks the form as submitted (to show all validation errors)
1498
+ */
1499
+ const markAsSubmitted = useCallback(() =&gt; {
1500
+ setIsSubmitted(true);
1501
+ setIsTouched(true);
1502
+ }, []);
1503
+ &nbsp;
1504
+ /**
1505
+ * Updates a file in the list
1506
+ */
1507
+ const updateFile = useCallback((fileId: string, updates: Partial&lt;FileItem&gt;) =&gt; {
1508
+ setFiles((prev) =&gt; {
1509
+ const updated = prev.map((f) =&gt; (f.id === fileId ? { ...f, ...updates } : f));
1510
+ return updated;
1511
+ });
1512
+ }, []);
1513
+ &nbsp;
1514
+ /**
1515
+ * Notifies file changes
1516
+ */
1517
+ const notifyFilesChange = useCallback(
1518
+ (newFiles: FileItem[]) =&gt; {
1519
+ onFilesChange?.(newFiles);
1520
+ },
1521
+ [onFilesChange]
1522
+ );
1523
+ &nbsp;
1524
+ /**
1525
+ * Validates a file before upload - using extracted utility
1526
+ */
1527
+ const validateFile = useCallback(
1528
+ (file: File) =&gt; validateFileUtil(file, acceptedTypes, maxFileSize),
1529
+ [acceptedTypes, maxFileSize]
1530
+ );
1531
+ &nbsp;
1532
+ /**
1533
+ * Apply completed status to a file in the list and notify listeners.
1534
+ */
1535
+ const applyUploadSuccess = useCallback(
1536
+ (fileId: string, completedFile: Partial&lt;FileItem&gt;) =&gt; {
1537
+ setFiles((prev) =&gt; {
1538
+ const updated = prev.map((f) =&gt; (f.id === fileId ? { ...f, ...completedFile } : f));
1539
+ notifyFilesChange(updated);
1540
+ const updatedFile = updated.find((f) =&gt; f.id === fileId);
1541
+ if (updatedFile) {
1542
+ onUploadComplete?.(updatedFile);
1543
+ }
1544
+ return updated;
1545
+ });
1546
+ },
1547
+ [notifyFilesChange, onUploadComplete]
1548
+ );
1549
+ &nbsp;
1550
+ /**
1551
+ * Notify error callback for a failed upload.
1552
+ */
1553
+ const notifyUploadError = useCallback(
1554
+ (fileId: string, errorMessage: string) =&gt; {
1555
+ setFiles((prev) =&gt; {
1556
+ const updatedFile = prev.find((f) =&gt; f.id === fileId);
1557
+ if (updatedFile) {
1558
+ onUploadError?.(updatedFile, errorMessage);
1559
+ }
1560
+ return prev;
1561
+ });
1562
+ },
1563
+ [onUploadError]
1564
+ );
1565
+ &nbsp;
1566
+ /**
1567
+ * Uploads a single file to S3 - using extracted service
1568
+ */
1569
+ const uploadFile = useCallback(
1570
+ async (fileItem: FileItem, file: File): Promise&lt;void&gt; =&gt; {
1571
+ try {
1572
+ // Get pre-signed URL using service
1573
+ const { uploadUrl, filePath, publicUrl } = await generateSignedUploadUrl(file.name, file.type, visibility);
1574
+ &nbsp;
1575
+ // Update state to uploading
1576
+ updateFile(fileItem.id, { status: 'uploading', progress: 0 });
1577
+ &nbsp;
1578
+ // Perform upload using service with progress callback
1579
+ await uploadToSignedUrl(file, uploadUrl, {
1580
+ onProgress: (progress) =&gt; updateFile(fileItem.id, { progress }),
1581
+ });
1582
+ &nbsp;
1583
+ // Mark as completed and notify
1584
+ applyUploadSuccess(fileItem.id, {
1585
+ status: 'completed',
1586
+ progress: 100,
1587
+ filePath,
1588
+ visibility,
1589
+ publicUrl,
1590
+ file: undefined, // Clear File reference
1591
+ });
1592
+ } catch (error) {
1593
+ const errorMessage = error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : 'Unknown error';</span>
1594
+ &nbsp;
1595
+ updateFile(fileItem.id, {
1596
+ status: 'error',
1597
+ progress: 0,
1598
+ errorMessage,
1599
+ });
1600
+ &nbsp;
1601
+ notifyUploadError(fileItem.id, errorMessage);
1602
+ }
1603
+ },
1604
+ [updateFile, applyUploadSuccess, notifyUploadError, visibility]
1605
+ );
1606
+ &nbsp;
1607
+ /**
1608
+ * Enforce maxFiles limit, trimming fileArray if needed.
1609
+ * Returns the (possibly trimmed) file array, or null if no slots remain.
1610
+ */
1611
+ const enforceFileLimit = useCallback(
1612
+ (fileArray: File[], activeCount: number): File[] | null =&gt; {
1613
+ if (maxFiles === undefined) {
1614
+ return fileArray;
1615
+ }
1616
+ const remainingSlots = maxFiles - activeCount;
1617
+ &nbsp;
1618
+ if (remainingSlots &lt;= 0) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1619
+ <span class="cstat-no" title="statement not covered" > logger.warn(`File limit of ${maxFiles} already reached`);</span>
1620
+ <span class="cstat-no" title="statement not covered" > return null;</span>
1621
+ <span class="cstat-no" title="statement not covered" > }</span>
1622
+ &nbsp;
1623
+ if (fileArray.length &gt; remainingSlots) {
1624
+ logger.warn(`Only ${remainingSlots} files will be added to not exceed limit`);
1625
+ return fileArray.slice(0, remainingSlots);
1626
+ }
1627
+ &nbsp;
1628
+ return fileArray;
1629
+ },
1630
+ [maxFiles]
1631
+ );
1632
+ &nbsp;
1633
+ /**
1634
+ * Create FileItem objects from validated files.
1635
+ */
1636
+ const createFileItems = useCallback(
1637
+ (fileArray: File[]): FileItem[] =&gt; {
1638
+ return fileArray.map((file) =&gt; {
1639
+ const validation = validateFile(file);
1640
+ return {
1641
+ id: generateFileId(),
1642
+ name: file.name,
1643
+ size: file.size,
1644
+ contentType: file.type,
1645
+ status: validation.valid ? ('pending' as FileStatus) : ('error' as FileStatus),
1646
+ progress: 0,
1647
+ createdAt: Date.now(),
1648
+ file: validation.valid ? file : undefined,
1649
+ errorMessage: validation.error,
1650
+ isExisting: false, // Mark as new file (not from server)
1651
+ };
1652
+ });
1653
+ },
1654
+ [validateFile]
1655
+ );
1656
+ &nbsp;
1657
+ /**
1658
+ * Start uploads for valid pending files and track their promises.
1659
+ */
1660
+ const startUploadsForFiles = useCallback(
1661
+ (filesToAdd: FileItem[]) =&gt; {
1662
+ const validFiles = filesToAdd.filter((f) =&gt; f.status === 'pending' &amp;&amp; f.file);
1663
+ &nbsp;
1664
+ for (const fileItem of validFiles) {
1665
+ if (fileItem.file) {
1666
+ const uploadPromise = uploadFile(fileItem, fileItem.file);
1667
+ uploadPromisesRef.current.set(fileItem.id, uploadPromise);
1668
+ &nbsp;
1669
+ // Clean from list when finished
1670
+ uploadPromise.finally(() =&gt; {
1671
+ uploadPromisesRef.current.delete(fileItem.id);
1672
+ });
1673
+ }
1674
+ }
1675
+ },
1676
+ [uploadFile]
1677
+ );
1678
+ &nbsp;
1679
+ /**
1680
+ * Add files and start upload
1681
+ */
1682
+ const addFiles = useCallback(
1683
+ async (newFiles: FileList | File[]): Promise&lt;void&gt; =&gt; {
1684
+ let fileArray = Array.from(newFiles);
1685
+ &nbsp;
1686
+ // Use functional update to get current file count and avoid stale closure
1687
+ let filesToAdd: FileItem[] = [];
1688
+ &nbsp;
1689
+ setFiles((prevFiles) =&gt; {
1690
+ const activeCount = prevFiles.filter((f) =&gt; f.status !== 'pendingDeletion' &amp;&amp; f.status !== 'error').length;
1691
+ const trimmedFiles = enforceFileLimit(fileArray, activeCount);
1692
+ if (!trimmedFiles) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1693
+ <span class="cstat-no" title="statement not covered" > return prevFiles;</span>
1694
+ <span class="cstat-no" title="statement not covered" > }</span>
1695
+ fileArray = trimmedFiles;
1696
+ &nbsp;
1697
+ const newFileItems = createFileItems(fileArray);
1698
+ filesToAdd = newFileItems;
1699
+ const updated = [...prevFiles, ...newFileItems];
1700
+ notifyFilesChange(updated);
1701
+ return updated;
1702
+ });
1703
+ &nbsp;
1704
+ // Start uploads in parallel for valid files (after state update)
1705
+ // Use setTimeout to ensure state has been updated
1706
+ setTimeout(() =&gt; startUploadsForFiles(filesToAdd), 0);
1707
+ },
1708
+ [enforceFileLimit, createFileItems, startUploadsForFiles, notifyFilesChange]
1709
+ );
1710
+ &nbsp;
1711
+ /**
1712
+ * Remove file - behavior depends on mode and whether file is existing
1713
+ * - CREATE mode: always needs confirmation, then delete immediately
1714
+ * - EDIT mode + existing file: mark as pendingDeletion (delete on form success)
1715
+ * - EDIT mode + new file: needs confirmation, then delete immediately
1716
+ */
1717
+ const removeFile = useCallback(
1718
+ async (fileId: string): Promise&lt;{ needsConfirmation: boolean; isExisting: boolean }&gt; =&gt; {
1719
+ const file = files.find((f) =&gt; f.id === fileId);
1720
+ if (!file) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1721
+ <span class="cstat-no" title="statement not covered" > return { needsConfirmation: false, isExisting: false };</span>
1722
+ <span class="cstat-no" title="statement not covered" > }</span>
1723
+ &nbsp;
1724
+ // Determine if this is an existing file (loaded from server)
1725
+ const isExisting = file.isExisting === true;
1726
+ &nbsp;
1727
+ // In CREATE mode: always need confirmation, then delete immediately
1728
+ // In EDIT mode:
1729
+ // - Existing file: mark as pendingDeletion (no confirmation needed, can restore)
1730
+ // - New file: needs confirmation, then delete immediately
1731
+ if (mode === 'create' || !isExisting) {
1732
+ // Return that confirmation is needed - component will show popup
1733
+ return { needsConfirmation: true, isExisting };
1734
+ }
1735
+ &nbsp;
1736
+ // EDIT mode with existing file: mark as pendingDeletion
1737
+ setPendingDeletions((prev) =&gt; [...prev, fileId]);
1738
+ &nbsp;
1739
+ // Update file status to pendingDeletion
1740
+ setFiles((prev) =&gt; {
1741
+ const updated = prev.map((f) =&gt; (f.id === fileId ? { ...f, status: 'pendingDeletion' as FileStatus } : f));
1742
+ // Notify change - exclude files pending deletion from the list
1743
+ const activeFilesFiltered = updated.filter((f) =&gt; f.status !== 'pendingDeletion');
1744
+ notifyFilesChange(activeFilesFiltered);
1745
+ return updated;
1746
+ });
1747
+ &nbsp;
1748
+ return { needsConfirmation: false, isExisting };
1749
+ },
1750
+ [files, mode, notifyFilesChange]
1751
+ );
1752
+ &nbsp;
1753
+ /**
1754
+ * Delete a file immediately from the server - using extracted service
1755
+ * Used for new files (not yet saved in DB) or in CREATE mode
1756
+ */
1757
+ const deleteFileImmediately = useCallback(
1758
+ async (fileId: string): Promise&lt;{ success: boolean; error?: string }&gt; =&gt; {
1759
+ const file = files.find((f) =&gt; f.id === fileId);
1760
+ if (!file) {
1761
+ return { success: false, error: 'File not found' };
1762
+ }
1763
+ &nbsp;
1764
+ // If file has no filePath (never uploaded), just remove from state
1765
+ if (!file.filePath) {
1766
+ setFiles((prev) =&gt; {
1767
+ const updated = prev.filter((f) =&gt; f.id !== fileId);
1768
+ notifyFilesChange(updated);
1769
+ return updated;
1770
+ });
1771
+ return { success: true };
1772
+ }
1773
+ &nbsp;
1774
+ // Delete from server using service
1775
+ const result = await deleteFileService(file.filePath);
1776
+ &nbsp;
1777
+ if (result.success) {
1778
+ setFiles((prev) =&gt; {
1779
+ const updated = prev.filter((f) =&gt; f.id !== fileId);
1780
+ notifyFilesChange(updated);
1781
+ return updated;
1782
+ });
1783
+ onFileRemoved?.(file);
1784
+ return { success: true };
1785
+ <span class="branch-0 cbranch-no" title="branch not covered" > }</span>
1786
+ return { success: false, error: result.error || 'Failed to delete file' };
1787
+ },
1788
+ [files, notifyFilesChange, onFileRemoved]
1789
+ );
1790
+ &nbsp;
1791
+ /**
1792
+ * Restore a single file that was marked for deletion
1793
+ * Only allows restoring existing files (files loaded from server)
1794
+ */
1795
+ const restoreFile = useCallback(
1796
+ (fileId: string): boolean =&gt; {
1797
+ const file = files.find((f) =&gt; f.id === fileId);
1798
+ // Only allow restoring existing files
1799
+ if (!file?.isExisting) {
1800
+ return false;
1801
+ }
1802
+ &nbsp;
1803
+ // Remove from pending deletions
1804
+ setPendingDeletions((prev) =&gt; prev.filter((id) =&gt; id !== fileId));
1805
+ &nbsp;
1806
+ // Restore file status to completed
1807
+ setFiles((prev) =&gt; {
1808
+ const updated = prev.map((f) =&gt; (f.id === fileId ? { ...f, status: 'completed' as FileStatus <span class="branch-0 cbranch-no" title="branch not covered" >} : f))</span>;
1809
+ notifyFilesChange(updated);
1810
+ return updated;
1811
+ });
1812
+ &nbsp;
1813
+ return true;
1814
+ },
1815
+ [files, notifyFilesChange]
1816
+ );
1817
+ &nbsp;
1818
+ /**
1819
+ * Restore all files that were marked for deletion
1820
+ */
1821
+ const restorePendingDeletions = useCallback(() =&gt; {
1822
+ if (pendingDeletions.length === 0) {
1823
+ return;
1824
+ }
1825
+ &nbsp;
1826
+ setFiles((prev) =&gt; {
1827
+ const updated = prev.map((f) =&gt;
1828
+ pendingDeletions.includes(f.id) ? { ...f, status: 'completed' as FileStatus <span class="branch-0 cbranch-no" title="branch not covered" >} : f</span>
1829
+ );
1830
+ notifyFilesChange(updated);
1831
+ return updated;
1832
+ });
1833
+ setPendingDeletions([]);
1834
+ }, [pendingDeletions, notifyFilesChange]);
1835
+ &nbsp;
1836
+ /**
1837
+ * Execute all pending deletions (call this on form submit) - using extracted service
1838
+ * This actually deletes the files from the server
1839
+ */
1840
+ const commitDeletions = useCallback(async (): Promise&lt;{ success: boolean; errors: string[] }&gt; =&gt; {
1841
+ if (pendingDeletions.length === 0) {
1842
+ return { success: true, errors: [] };
1843
+ }
1844
+ &nbsp;
1845
+ const errors: string[] = [];
1846
+ const successfulDeletions: string[] = [];
1847
+ &nbsp;
1848
+ for (const fileId of pendingDeletions) {
1849
+ const file = files.find((f) =&gt; f.id === fileId);
1850
+ if (!file?.filePath) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1851
+ <span class="cstat-no" title="statement not covered" > // File without filePath (never uploaded) - just mark as successful</span>
1852
+ <span class="cstat-no" title="statement not covered" > successfulDeletions.push(fileId);</span>
1853
+ <span class="cstat-no" title="statement not covered" > continue;</span>
1854
+ <span class="cstat-no" title="statement not covered" > }</span>
1855
+ &nbsp;
1856
+ // Use service for deletion
1857
+ const result = await deleteFileService(file.filePath);
1858
+ &nbsp;
1859
+ if (result.success) {
1860
+ successfulDeletions.push(fileId);
1861
+ <span class="branch-0 cbranch-no" title="branch not covered" > onFileRemoved?.(file);</span>
1862
+ } else {
1863
+ errors.push(result.<span class="branch-0 cbranch-no" title="branch not covered" >error || `Failed to delete ${file.name}`)</span>;
1864
+ }
1865
+ }
1866
+ &nbsp;
1867
+ // Remove successfully deleted files from state
1868
+ if (successfulDeletions.length &gt; 0) {
1869
+ setFiles((prev) =&gt; {
1870
+ const updated = prev.filter((f) =&gt; !successfulDeletions.includes(f.id));
1871
+ return updated;
1872
+ });
1873
+ setPendingDeletions((prev) =&gt; prev.filter((id) =&gt; !successfulDeletions.includes(id)));
1874
+ }
1875
+ &nbsp;
1876
+ return { success: errors.length === 0, errors };
1877
+ }, [files, pendingDeletions, onFileRemoved]);
1878
+ &nbsp;
1879
+ /**
1880
+ * Clear all files
1881
+ */
1882
+ const clearFiles = useCallback(() =&gt; {
1883
+ setFiles([]);
1884
+ notifyFilesChange([]);
1885
+ }, [notifyFilesChange]);
1886
+ &nbsp;
1887
+ /**
1888
+ * Retry upload for failed file
1889
+ */
1890
+ const retryUpload = useCallback(
1891
+ async (fileId: string): Promise&lt;void&gt; =&gt; {
1892
+ const file = files.find((f) =&gt; f.id === fileId);
1893
+ if (file?.status !== 'error' || !file?.file) {
1894
+ logger.warn('Cannot retry: file not found or no original file');
1895
+ return;
1896
+ }
1897
+ &nbsp;
1898
+ // Reset state
1899
+ updateFile(fileId, { status: 'pending', progress: 0, errorMessage: undefined });
1900
+ &nbsp;
1901
+ // Restart upload
1902
+ const uploadPromise = uploadFile(file, file.file);
1903
+ uploadPromisesRef.current.set(fileId, uploadPromise);
1904
+ &nbsp;
1905
+ uploadPromise.finally(() =&gt; {
1906
+ uploadPromisesRef.current.delete(fileId);
1907
+ });
1908
+ },
1909
+ [files, updateFile, uploadFile]
1910
+ );
1911
+ &nbsp;
1912
+ /**
1913
+ * Reads completed file paths from current state and resolves the given callback.
1914
+ * Used by waitForUploads to extract paths after React state updates.
1915
+ */
1916
+ const extractCompletedPaths = useCallback((resolve: (paths: string[]) =&gt; void) =&gt; {
1917
+ <span class="cstat-no" title="statement not covered" > setFiles((currentFiles) =&gt; {</span>
1918
+ <span class="cstat-no" title="statement not covered" > const paths = currentFiles.filter(hasCompletedFilePath).map((f) =&gt; f.filePath);</span>
1919
+ <span class="cstat-no" title="statement not covered" > resolve(paths);</span>
1920
+ <span class="cstat-no" title="statement not covered" > return currentFiles; // Don't modify state, just read it</span>
1921
+ <span class="cstat-no" title="statement not covered" > });</span>
1922
+ }, []);
1923
+ &nbsp;
1924
+ /**
1925
+ * Wait for all uploads to complete
1926
+ * Returns a promise that resolves with the completed file paths
1927
+ * This ensures the caller gets the actual file paths without relying on React state timing
1928
+ */
1929
+ const waitForUploads = useCallback(async (): Promise&lt;string[]&gt; =&gt; {
1930
+ <span class="cstat-no" title="statement not covered" > const promises = Array.from(uploadPromisesRef.current.values());</span>
1931
+ <span class="cstat-no" title="statement not covered" > if (promises.length &gt; 0) {</span>
1932
+ <span class="cstat-no" title="statement not covered" > await Promise.allSettled(promises);</span>
1933
+ <span class="cstat-no" title="statement not covered" > }</span>
1934
+ <span class="cstat-no" title="statement not covered" > // Return current completed file paths directly from files state</span>
1935
+ <span class="cstat-no" title="statement not covered" > // We need to get the latest state, so we use a promise that resolves after state update</span>
1936
+ <span class="cstat-no" title="statement not covered" > return new Promise((resolve) =&gt; {</span>
1937
+ <span class="cstat-no" title="statement not covered" > // Use setTimeout to ensure we get the state after React has processed updates</span>
1938
+ <span class="cstat-no" title="statement not covered" > setTimeout(() =&gt; extractCompletedPaths(resolve), 0);</span>
1939
+ <span class="cstat-no" title="statement not covered" > });</span>
1940
+ }, [extractCompletedPaths]);
1941
+ &nbsp;
1942
+ /**
1943
+ * Initialize with existing files (for editing)
1944
+ * @param existingFiles - Array of files with filePath (can be relative or full URL with baseUrl)
1945
+ * @param baseUrl - Optional baseUrl to strip from file paths
1946
+ */
1947
+ const initializeFiles = useCallback(
1948
+ (
1949
+ existingFiles: Array&lt;{ filePath: string; name: string; size?: number; contentType?: string }&gt;,
1950
+ baseUrl?: string
1951
+ ) =&gt; {
1952
+ const fileItems: FileItem[] = existingFiles.map((ef) =&gt; {
1953
+ // IMPORTANT: Extract relative path if it comes with baseUrl
1954
+ // This ensures we always store the relative path (e.g., "public/file.jpg")
1955
+ // and not the full URL (e.g., "https://cdn.example.com/public/file.jpg")
1956
+ const relativePath = extractRelativePath(ef.filePath, baseUrl);
1957
+ &nbsp;
1958
+ // Extract visibility from the relative path
1959
+ const fileVisibility =
1960
+ relativePath.includes('/public/') || relativePath.startsWith('public/') ? 'public' : 'private';
1961
+ &nbsp;
1962
+ // Infer contentType from extension if not provided
1963
+ const contentType = ef.contentType || inferContentType(ef.name);
1964
+ &nbsp;
1965
+ return {
1966
+ id: generateFileId(),
1967
+ name: ef.name,
1968
+ size: ef.size || 0,
1969
+ contentType,
1970
+ status: 'completed' as FileStatus,
1971
+ progress: 100,
1972
+ filePath: relativePath, // Always store relative path
1973
+ visibility: fileVisibility,
1974
+ createdAt: Date.now(),
1975
+ isExisting: true, // Mark as existing file (loaded from server)
1976
+ };
1977
+ });
1978
+ &nbsp;
1979
+ setFiles(fileItems);
1980
+ notifyFilesChange(fileItems);
1981
+ },
1982
+ [notifyFilesChange]
1983
+ );
1984
+ &nbsp;
1985
+ /**
1986
+ * Gets URL for file preview - using extracted service
1987
+ * - Public: returns publicUrl directly
1988
+ * - Private: requests signed URL from backend
1989
+ */
1990
+ const getPreviewUrl = useCallback(
1991
+ async (fileId: string): Promise&lt;string | null&gt; =&gt; {
1992
+ const file = files.find((f) =&gt; f.id === fileId);
1993
+ if (!file?.filePath) {
1994
+ return null;
1995
+ }
1996
+ &nbsp;
1997
+ // If public and already has publicUrl, use it
1998
+ if (file.visibility === 'public' &amp;&amp; file.publicUrl) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
1999
+ <span class="cstat-no" title="statement not covered" > return file.publicUrl;</span>
2000
+ <span class="cstat-no" title="statement not covered" > }</span>
2001
+ &nbsp;
2002
+ // Request URL from backend using service
2003
+ return getSignedPreviewUrl(file.filePath, 3600);
2004
+ },
2005
+ [files]
2006
+ );
2007
+ &nbsp;
2008
+ // Derived values with memoization
2009
+ const isUploading = useMemo(() =&gt; {
2010
+ return files.some((f) =&gt; f.status === 'uploading' || f.status === 'pending');
2011
+ }, [files]);
2012
+ &nbsp;
2013
+ const pendingCount = useMemo(() =&gt; {
2014
+ return files.filter((f) =&gt; f.status === 'uploading' || f.status === 'pending').length;
2015
+ }, [files]);
2016
+ &nbsp;
2017
+ const completedFilePaths = useMemo(() =&gt; {
2018
+ return files.filter(hasCompletedFilePath).map((f) =&gt; f.filePath);
2019
+ }, [files]);
2020
+ &nbsp;
2021
+ // Active files (excluding pendingDeletion)
2022
+ const activeFiles = useMemo(() =&gt; {
2023
+ return files.filter((f) =&gt; f.status !== 'pendingDeletion');
2024
+ }, [files]);
2025
+ &nbsp;
2026
+ // Count of active files (completed, pending, or uploading)
2027
+ const activeFileCount = useMemo(() =&gt; {
2028
+ return activeFiles.filter((f) =&gt; f.status === 'completed' || f.status === 'pending' || f.status === 'uploading')
2029
+ .length;
2030
+ }, [activeFiles]);
2031
+ &nbsp;
2032
+ // Validation with i18n keys - using extracted utility
2033
+ const { isValid, validationError, validationErrorKey, validationErrorParams } = useMemo(
2034
+ () =&gt; validateFileCounts(activeFiles, minFiles, maxFiles),
2035
+ [activeFiles, minFiles, maxFiles]
2036
+ );
2037
+ &nbsp;
2038
+ // Computed value for hasPendingDeletions
2039
+ const hasPendingDeletions = pendingDeletions.length &gt; 0;
2040
+ &nbsp;
2041
+ return {
2042
+ files,
2043
+ activeFiles,
2044
+ activeFileCount,
2045
+ isUploading,
2046
+ pendingCount,
2047
+ addFiles,
2048
+ removeFile,
2049
+ deleteFileImmediately,
2050
+ restoreFile,
2051
+ clearFiles,
2052
+ retryUpload,
2053
+ isValid,
2054
+ validationError,
2055
+ validationErrorKey,
2056
+ validationErrorParams,
2057
+ waitForUploads,
2058
+ completedFilePaths,
2059
+ initializeFiles,
2060
+ isTouched,
2061
+ markAsTouched,
2062
+ isSubmitted,
2063
+ markAsSubmitted,
2064
+ getPreviewUrl,
2065
+ pendingDeletions,
2066
+ hasPendingDeletions,
2067
+ commitDeletions,
2068
+ restorePendingDeletions,
2069
+ };
2070
+ };
2071
+ &nbsp;
2072
+ export default useFileUpload;
2073
+ &nbsp;</pre></td></tr></table></pre>
2074
+
2075
+ <div class='push'></div><!-- for sticky footer -->
2076
+ </div><!-- /wrapper -->
2077
+ <div class='footer quiet pad2 space-top1 center small'>
2078
+ Code coverage generated by
2079
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
2080
+ at 2026-02-07T06:55:20.810Z
2081
+ </div>
2082
+ <script src="../../prettify.js"></script>
2083
+ <script>
2084
+ window.onload = function () {
2085
+ prettyPrint();
2086
+ };
2087
+ </script>
2088
+ <script src="../../sorter.js"></script>
2089
+ <script src="../../block-navigation.js"></script>
2090
+ </body>
2091
+ </html>
2092
+