@nocios/crudify-components 2.0.60 → 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 (362) hide show
  1. package/.scannerwork/report-task.txt +2 -2
  2. package/coverage/components/CrudiaAutoGenerate.tsx.html +616 -0
  3. package/coverage/components/CrudiaFileField/CrudiaFileField.tsx.html +1312 -0
  4. package/coverage/components/CrudiaFileField/components/DeleteConfirmationDialog.tsx.html +355 -0
  5. package/coverage/components/CrudiaFileField/components/DropZone.tsx.html +523 -0
  6. package/coverage/components/CrudiaFileField/components/FileItemRow.tsx.html +835 -0
  7. package/coverage/components/CrudiaFileField/components/FileThumbnail.tsx.html +1585 -0
  8. package/coverage/components/CrudiaFileField/components/index.html +176 -0
  9. package/coverage/components/CrudiaFileField/components/index.ts.html +115 -0
  10. package/coverage/components/CrudiaFileField/hooks/index.html +146 -0
  11. package/coverage/components/CrudiaFileField/hooks/index.ts.html +112 -0
  12. package/coverage/components/CrudiaFileField/hooks/useDeleteConfirmation.ts.html +433 -0
  13. package/coverage/components/CrudiaFileField/hooks/useDragDrop.ts.html +409 -0
  14. package/coverage/components/CrudiaFileField/index.html +131 -0
  15. package/coverage/components/CrudiaFileField/index.ts.html +112 -0
  16. package/coverage/components/CrudiaFileField/utils/formatters.ts.html +169 -0
  17. package/coverage/components/CrudiaFileField/utils/icons.tsx.html +253 -0
  18. package/coverage/components/CrudiaFileField/utils/index.html +146 -0
  19. package/coverage/components/CrudiaFileField/utils/index.ts.html +103 -0
  20. package/coverage/components/CrudiaMarkdownField.tsx.html +676 -0
  21. package/coverage/components/CrudifyInitializer.tsx.html +712 -0
  22. package/coverage/components/CrudifyLogin/Forms/CheckCodeForm.tsx.html +640 -0
  23. package/coverage/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx.html +730 -0
  24. package/coverage/components/CrudifyLogin/Forms/LoginForm.tsx.html +892 -0
  25. package/coverage/components/CrudifyLogin/Forms/ResetPasswordForm.tsx.html +1219 -0
  26. package/coverage/components/CrudifyLogin/Forms/components/CodeInput.tsx.html +289 -0
  27. package/coverage/components/CrudifyLogin/Forms/components/FormAlert.tsx.html +202 -0
  28. package/coverage/components/CrudifyLogin/Forms/components/PasswordInput.tsx.html +346 -0
  29. package/coverage/components/CrudifyLogin/Forms/components/index.html +161 -0
  30. package/coverage/components/CrudifyLogin/Forms/components/index.ts.html +106 -0
  31. package/coverage/components/CrudifyLogin/Forms/index.html +176 -0
  32. package/coverage/components/CrudifyLogin/Forms/index.ts.html +145 -0
  33. package/coverage/components/CrudifyLogin/Forms/utils/errorTranslation.ts.html +268 -0
  34. package/coverage/components/CrudifyLogin/Forms/utils/index.html +161 -0
  35. package/coverage/components/CrudifyLogin/Forms/utils/index.ts.html +121 -0
  36. package/coverage/components/CrudifyLogin/Forms/utils/paramUtils.ts.html +496 -0
  37. package/coverage/components/CrudifyLogin/Forms/utils/validation.ts.html +307 -0
  38. package/coverage/components/CrudifyLogin/components/CrudifyInitializer.tsx.html +268 -0
  39. package/coverage/components/CrudifyLogin/components/index.html +116 -0
  40. package/coverage/components/CrudifyLogin/context/CrudifyProvider.tsx.html +409 -0
  41. package/coverage/components/CrudifyLogin/context/I18nProvider.tsx.html +430 -0
  42. package/coverage/components/CrudifyLogin/context/LoginStateProvider.tsx.html +1261 -0
  43. package/coverage/components/CrudifyLogin/context/index.html +161 -0
  44. package/coverage/components/CrudifyLogin/context/index.ts.html +91 -0
  45. package/coverage/components/CrudifyLogin/hooks/index.html +131 -0
  46. package/coverage/components/CrudifyLogin/hooks/useCrudifyLogin.ts.html +463 -0
  47. package/coverage/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts.html +391 -0
  48. package/coverage/components/CrudifyLogin/index.html +116 -0
  49. package/coverage/components/CrudifyLogin/index.tsx.html +466 -0
  50. package/coverage/components/CrudifyLogin/utils/index.html +116 -0
  51. package/coverage/components/CrudifyLogin/utils/secureStorage.ts.html +859 -0
  52. package/coverage/components/GlobalNotificationProvider.tsx.html +844 -0
  53. package/coverage/components/LoginComponent.tsx.html +676 -0
  54. package/coverage/components/PasswordRequirements/index.html +116 -0
  55. package/coverage/components/PasswordRequirements/index.tsx.html +232 -0
  56. package/coverage/components/PublicPolicies/FieldSelector/FieldSelector.tsx.html +1078 -0
  57. package/coverage/components/PublicPolicies/FieldSelector/index.html +131 -0
  58. package/coverage/components/PublicPolicies/FieldSelector/index.ts.html +88 -0
  59. package/coverage/components/PublicPolicies/Policies.tsx.html +625 -0
  60. package/coverage/components/PublicPolicies/PolicyItem/PolicyItem.tsx.html +886 -0
  61. package/coverage/components/PublicPolicies/PolicyItem/index.html +131 -0
  62. package/coverage/components/PublicPolicies/PolicyItem/index.ts.html +88 -0
  63. package/coverage/components/PublicPolicies/constants.ts.html +106 -0
  64. package/coverage/components/PublicPolicies/index.html +146 -0
  65. package/coverage/components/PublicPolicies/index.ts.html +88 -0
  66. package/coverage/components/Routing/AuthRoute.tsx.html +382 -0
  67. package/coverage/components/Routing/GuestRoute.tsx.html +352 -0
  68. package/coverage/components/Routing/ProtectedRoute.tsx.html +316 -0
  69. package/coverage/components/Routing/index.html +161 -0
  70. package/coverage/components/Routing/index.ts.html +109 -0
  71. package/coverage/components/SessionLoadingScreen/index.html +116 -0
  72. package/coverage/components/SessionLoadingScreen/index.tsx.html +379 -0
  73. package/coverage/components/SessionTimeIndicator/index.html +116 -0
  74. package/coverage/components/SessionTimeIndicator/index.tsx.html +523 -0
  75. package/coverage/components/UserProfile/UserProfileDisplay.tsx.html +931 -0
  76. package/coverage/components/UserProfile/index.html +131 -0
  77. package/coverage/components/UserProfile/index.ts.html +88 -0
  78. package/coverage/components/index.html +191 -0
  79. package/coverage/components/index.ts.html +178 -0
  80. package/coverage/core/CrossTabSyncManager.ts.html +853 -0
  81. package/coverage/core/CrudifyInitializationManager.ts.html +1279 -0
  82. package/coverage/core/SessionManager.ts.html +3064 -0
  83. package/coverage/core/index.html +146 -0
  84. package/coverage/coverage-final.json +76 -79
  85. package/coverage/hooks/index.html +191 -0
  86. package/coverage/hooks/index.ts.html +136 -0
  87. package/coverage/hooks/useAuth.ts.html +529 -0
  88. package/coverage/hooks/useAutoGenerate.ts.html +571 -0
  89. package/coverage/hooks/useCrudifyWithNotifications/constants.ts.html +247 -0
  90. package/coverage/hooks/useCrudifyWithNotifications/hooks/index.html +116 -0
  91. package/coverage/hooks/useCrudifyWithNotifications/hooks/useCrudOperations.ts.html +820 -0
  92. package/coverage/hooks/useCrudifyWithNotifications/index.html +146 -0
  93. package/coverage/hooks/useCrudifyWithNotifications/index.ts.html +118 -0
  94. package/coverage/hooks/useCrudifyWithNotifications/useCrudifyWithNotifications.ts.html +565 -0
  95. package/coverage/hooks/useCrudifyWithNotifications/utils/errorMessageResolver.ts.html +847 -0
  96. package/coverage/hooks/useCrudifyWithNotifications/utils/index.html +146 -0
  97. package/coverage/hooks/useCrudifyWithNotifications/utils/notificationFilters.ts.html +313 -0
  98. package/coverage/hooks/useCrudifyWithNotifications/utils/successMessageResolver.ts.html +265 -0
  99. package/coverage/hooks/useData.ts.html +829 -0
  100. package/coverage/hooks/useFileUpload/index.html +131 -0
  101. package/coverage/hooks/useFileUpload/index.ts.html +112 -0
  102. package/coverage/hooks/useFileUpload/services/index.html +131 -0
  103. package/coverage/hooks/useFileUpload/services/index.ts.html +106 -0
  104. package/coverage/hooks/useFileUpload/services/uploadService.ts.html +610 -0
  105. package/coverage/hooks/useFileUpload/useFileUpload.ts.html +2092 -0
  106. package/coverage/hooks/useFileUpload/utils/fileUtils.ts.html +271 -0
  107. package/coverage/hooks/useFileUpload/utils/index.html +161 -0
  108. package/coverage/hooks/useFileUpload/utils/index.ts.html +109 -0
  109. package/coverage/hooks/useFileUpload/utils/mimeTypes.ts.html +235 -0
  110. package/coverage/hooks/useFileUpload/utils/validation.ts.html +403 -0
  111. package/coverage/hooks/useSession/constants.ts.html +217 -0
  112. package/coverage/hooks/useSession/hooks/index.html +176 -0
  113. package/coverage/hooks/useSession/hooks/useAuthEventSubscriber.ts.html +331 -0
  114. package/coverage/hooks/useSession/hooks/useCrossTabSync.ts.html +535 -0
  115. package/coverage/hooks/useSession/hooks/useSessionActions.ts.html +664 -0
  116. package/coverage/hooks/useSession/hooks/useSessionState.ts.html +295 -0
  117. package/coverage/hooks/useSession/hooks/useTokenRefreshScheduler.ts.html +535 -0
  118. package/coverage/hooks/useSession/index.html +161 -0
  119. package/coverage/hooks/useSession/index.ts.html +127 -0
  120. package/coverage/hooks/useSession/types.ts.html +427 -0
  121. package/coverage/hooks/useSession/useSession.ts.html +526 -0
  122. package/coverage/hooks/useSession/utils/index.html +131 -0
  123. package/coverage/hooks/useSession/utils/initializeSession.ts.html +424 -0
  124. package/coverage/hooks/useSession/utils/tokenUtils.ts.html +298 -0
  125. package/coverage/hooks/useUserData.ts.html +1210 -0
  126. package/coverage/hooks/useUserProfile.ts.html +820 -0
  127. package/coverage/index.html +205 -235
  128. package/coverage/lcov-report/components/CrudiaAutoGenerate.tsx.html +616 -0
  129. package/coverage/lcov-report/components/CrudiaFileField/CrudiaFileField.tsx.html +1312 -0
  130. package/coverage/lcov-report/components/CrudiaFileField/components/DeleteConfirmationDialog.tsx.html +355 -0
  131. package/coverage/lcov-report/components/CrudiaFileField/components/DropZone.tsx.html +523 -0
  132. package/coverage/lcov-report/components/CrudiaFileField/components/FileItemRow.tsx.html +835 -0
  133. package/coverage/lcov-report/components/CrudiaFileField/components/FileThumbnail.tsx.html +1585 -0
  134. package/coverage/lcov-report/components/CrudiaFileField/components/index.html +176 -0
  135. package/coverage/lcov-report/components/CrudiaFileField/components/index.ts.html +115 -0
  136. package/coverage/lcov-report/components/CrudiaFileField/hooks/index.html +146 -0
  137. package/coverage/lcov-report/components/CrudiaFileField/hooks/index.ts.html +112 -0
  138. package/coverage/lcov-report/components/CrudiaFileField/hooks/useDeleteConfirmation.ts.html +433 -0
  139. package/coverage/lcov-report/components/CrudiaFileField/hooks/useDragDrop.ts.html +409 -0
  140. package/coverage/lcov-report/components/CrudiaFileField/index.html +131 -0
  141. package/coverage/lcov-report/components/CrudiaFileField/index.ts.html +112 -0
  142. package/coverage/lcov-report/components/CrudiaFileField/utils/formatters.ts.html +169 -0
  143. package/coverage/lcov-report/components/CrudiaFileField/utils/icons.tsx.html +253 -0
  144. package/coverage/lcov-report/components/CrudiaFileField/utils/index.html +146 -0
  145. package/coverage/lcov-report/components/CrudiaFileField/utils/index.ts.html +103 -0
  146. package/coverage/lcov-report/components/CrudiaMarkdownField.tsx.html +676 -0
  147. package/coverage/lcov-report/components/CrudifyInitializer.tsx.html +712 -0
  148. package/coverage/lcov-report/components/CrudifyLogin/Forms/CheckCodeForm.tsx.html +640 -0
  149. package/coverage/lcov-report/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx.html +730 -0
  150. package/coverage/lcov-report/components/CrudifyLogin/Forms/LoginForm.tsx.html +892 -0
  151. package/coverage/lcov-report/components/CrudifyLogin/Forms/ResetPasswordForm.tsx.html +1219 -0
  152. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/CodeInput.tsx.html +289 -0
  153. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/FormAlert.tsx.html +202 -0
  154. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/PasswordInput.tsx.html +346 -0
  155. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/index.html +161 -0
  156. package/coverage/lcov-report/components/CrudifyLogin/Forms/components/index.ts.html +106 -0
  157. package/coverage/lcov-report/components/CrudifyLogin/Forms/index.html +176 -0
  158. package/coverage/lcov-report/components/CrudifyLogin/Forms/index.ts.html +145 -0
  159. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/errorTranslation.ts.html +268 -0
  160. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/index.html +161 -0
  161. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/index.ts.html +121 -0
  162. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/paramUtils.ts.html +496 -0
  163. package/coverage/lcov-report/components/CrudifyLogin/Forms/utils/validation.ts.html +307 -0
  164. package/coverage/lcov-report/components/CrudifyLogin/components/CrudifyInitializer.tsx.html +268 -0
  165. package/coverage/lcov-report/components/CrudifyLogin/components/index.html +116 -0
  166. package/coverage/lcov-report/components/CrudifyLogin/context/CrudifyProvider.tsx.html +409 -0
  167. package/coverage/lcov-report/components/CrudifyLogin/context/I18nProvider.tsx.html +430 -0
  168. package/coverage/lcov-report/components/CrudifyLogin/context/LoginStateProvider.tsx.html +1261 -0
  169. package/coverage/lcov-report/components/CrudifyLogin/context/index.html +161 -0
  170. package/coverage/lcov-report/components/CrudifyLogin/context/index.ts.html +91 -0
  171. package/coverage/lcov-report/components/CrudifyLogin/hooks/index.html +131 -0
  172. package/coverage/lcov-report/components/CrudifyLogin/hooks/useCrudifyLogin.ts.html +463 -0
  173. package/coverage/lcov-report/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts.html +391 -0
  174. package/coverage/lcov-report/components/CrudifyLogin/index.html +116 -0
  175. package/coverage/lcov-report/components/CrudifyLogin/index.tsx.html +466 -0
  176. package/coverage/lcov-report/components/CrudifyLogin/utils/index.html +116 -0
  177. package/coverage/lcov-report/components/CrudifyLogin/utils/secureStorage.ts.html +859 -0
  178. package/coverage/lcov-report/components/GlobalNotificationProvider.tsx.html +844 -0
  179. package/coverage/lcov-report/components/LoginComponent.tsx.html +676 -0
  180. package/coverage/lcov-report/components/PasswordRequirements/index.html +116 -0
  181. package/coverage/lcov-report/components/PasswordRequirements/index.tsx.html +232 -0
  182. package/coverage/lcov-report/components/PublicPolicies/FieldSelector/FieldSelector.tsx.html +1078 -0
  183. package/coverage/lcov-report/components/PublicPolicies/FieldSelector/index.html +131 -0
  184. package/coverage/lcov-report/components/PublicPolicies/FieldSelector/index.ts.html +88 -0
  185. package/coverage/lcov-report/components/PublicPolicies/Policies.tsx.html +625 -0
  186. package/coverage/lcov-report/components/PublicPolicies/PolicyItem/PolicyItem.tsx.html +886 -0
  187. package/coverage/lcov-report/components/PublicPolicies/PolicyItem/index.html +131 -0
  188. package/coverage/lcov-report/components/PublicPolicies/PolicyItem/index.ts.html +88 -0
  189. package/coverage/lcov-report/components/PublicPolicies/constants.ts.html +106 -0
  190. package/coverage/lcov-report/components/PublicPolicies/index.html +146 -0
  191. package/coverage/lcov-report/components/PublicPolicies/index.ts.html +88 -0
  192. package/coverage/lcov-report/components/Routing/AuthRoute.tsx.html +382 -0
  193. package/coverage/lcov-report/components/Routing/GuestRoute.tsx.html +352 -0
  194. package/coverage/lcov-report/components/Routing/ProtectedRoute.tsx.html +316 -0
  195. package/coverage/lcov-report/components/Routing/index.html +161 -0
  196. package/coverage/lcov-report/components/Routing/index.ts.html +109 -0
  197. package/coverage/lcov-report/components/SessionLoadingScreen/index.html +116 -0
  198. package/coverage/lcov-report/components/SessionLoadingScreen/index.tsx.html +379 -0
  199. package/coverage/lcov-report/components/SessionTimeIndicator/index.html +116 -0
  200. package/coverage/lcov-report/components/SessionTimeIndicator/index.tsx.html +523 -0
  201. package/coverage/lcov-report/components/UserProfile/UserProfileDisplay.tsx.html +931 -0
  202. package/coverage/lcov-report/components/UserProfile/index.html +131 -0
  203. package/coverage/lcov-report/components/UserProfile/index.ts.html +88 -0
  204. package/coverage/lcov-report/components/index.html +191 -0
  205. package/coverage/lcov-report/components/index.ts.html +178 -0
  206. package/coverage/lcov-report/core/CrossTabSyncManager.ts.html +853 -0
  207. package/coverage/lcov-report/core/CrudifyInitializationManager.ts.html +1279 -0
  208. package/coverage/lcov-report/core/SessionManager.ts.html +3064 -0
  209. package/coverage/lcov-report/core/index.html +146 -0
  210. package/coverage/lcov-report/hooks/index.html +191 -0
  211. package/coverage/lcov-report/hooks/index.ts.html +136 -0
  212. package/coverage/lcov-report/hooks/useAuth.ts.html +529 -0
  213. package/coverage/lcov-report/hooks/useAutoGenerate.ts.html +571 -0
  214. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/constants.ts.html +247 -0
  215. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/hooks/index.html +116 -0
  216. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/hooks/useCrudOperations.ts.html +820 -0
  217. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/index.html +146 -0
  218. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/index.ts.html +118 -0
  219. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/useCrudifyWithNotifications.ts.html +565 -0
  220. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/errorMessageResolver.ts.html +847 -0
  221. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/index.html +146 -0
  222. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/notificationFilters.ts.html +313 -0
  223. package/coverage/lcov-report/hooks/useCrudifyWithNotifications/utils/successMessageResolver.ts.html +265 -0
  224. package/coverage/lcov-report/hooks/useData.ts.html +829 -0
  225. package/coverage/lcov-report/hooks/useFileUpload/index.html +131 -0
  226. package/coverage/lcov-report/hooks/useFileUpload/index.ts.html +112 -0
  227. package/coverage/lcov-report/hooks/useFileUpload/services/index.html +131 -0
  228. package/coverage/lcov-report/hooks/useFileUpload/services/index.ts.html +106 -0
  229. package/coverage/lcov-report/hooks/useFileUpload/services/uploadService.ts.html +610 -0
  230. package/coverage/lcov-report/hooks/useFileUpload/useFileUpload.ts.html +2092 -0
  231. package/coverage/lcov-report/hooks/useFileUpload/utils/fileUtils.ts.html +271 -0
  232. package/coverage/lcov-report/hooks/useFileUpload/utils/index.html +161 -0
  233. package/coverage/lcov-report/hooks/useFileUpload/utils/index.ts.html +109 -0
  234. package/coverage/lcov-report/hooks/useFileUpload/utils/mimeTypes.ts.html +235 -0
  235. package/coverage/lcov-report/hooks/useFileUpload/utils/validation.ts.html +403 -0
  236. package/coverage/lcov-report/hooks/useSession/constants.ts.html +217 -0
  237. package/coverage/lcov-report/hooks/useSession/hooks/index.html +176 -0
  238. package/coverage/lcov-report/hooks/useSession/hooks/useAuthEventSubscriber.ts.html +331 -0
  239. package/coverage/lcov-report/hooks/useSession/hooks/useCrossTabSync.ts.html +535 -0
  240. package/coverage/lcov-report/hooks/useSession/hooks/useSessionActions.ts.html +664 -0
  241. package/coverage/lcov-report/hooks/useSession/hooks/useSessionState.ts.html +295 -0
  242. package/coverage/lcov-report/hooks/useSession/hooks/useTokenRefreshScheduler.ts.html +535 -0
  243. package/coverage/lcov-report/hooks/useSession/index.html +161 -0
  244. package/coverage/lcov-report/hooks/useSession/index.ts.html +127 -0
  245. package/coverage/lcov-report/hooks/useSession/types.ts.html +427 -0
  246. package/coverage/lcov-report/hooks/useSession/useSession.ts.html +526 -0
  247. package/coverage/lcov-report/hooks/useSession/utils/index.html +131 -0
  248. package/coverage/lcov-report/hooks/useSession/utils/initializeSession.ts.html +424 -0
  249. package/coverage/lcov-report/hooks/useSession/utils/tokenUtils.ts.html +298 -0
  250. package/coverage/lcov-report/hooks/useUserData.ts.html +1210 -0
  251. package/coverage/lcov-report/hooks/useUserProfile.ts.html +820 -0
  252. package/coverage/lcov-report/index.html +205 -235
  253. package/coverage/lcov-report/providers/CrudifyThemeProvider.tsx.html +316 -0
  254. package/coverage/lcov-report/providers/SessionProvider.tsx.html +1120 -0
  255. package/coverage/lcov-report/providers/TranslationsProvider.tsx.html +1756 -0
  256. package/coverage/lcov-report/providers/index.html +146 -0
  257. package/coverage/lcov-report/services/credentialsEventBus.ts.html +319 -0
  258. package/coverage/lcov-report/services/crudifyAdminWrapper.ts.html +754 -0
  259. package/coverage/lcov-report/services/index.html +146 -0
  260. package/coverage/lcov-report/services/translationService.ts.html +1558 -0
  261. package/coverage/lcov-report/translations/critical.ts.html +1216 -0
  262. package/coverage/lcov-report/translations/index.html +116 -0
  263. package/coverage/lcov-report/types/index.html +116 -0
  264. package/coverage/lcov-report/types/password.ts.html +178 -0
  265. package/coverage/lcov-report/utils/authErrorDetector.ts.html +793 -0
  266. package/coverage/lcov-report/utils/authEventBus.ts.html +454 -0
  267. package/coverage/lcov-report/utils/configResolver.ts.html +460 -0
  268. package/coverage/lcov-report/utils/cookieSync.ts.html +595 -0
  269. package/coverage/lcov-report/utils/errorHandler.ts.html +1480 -0
  270. package/coverage/lcov-report/utils/errorTranslation.ts.html +868 -0
  271. package/coverage/lcov-report/utils/index.html +341 -0
  272. package/coverage/lcov-report/utils/index.ts.html +193 -0
  273. package/coverage/lcov-report/utils/jwtUtils.ts.html +325 -0
  274. package/coverage/lcov-report/utils/logger.ts.html +952 -0
  275. package/coverage/lcov-report/utils/navigationTracker.ts.html +562 -0
  276. package/coverage/lcov-report/utils/passwordValidation.ts.html +259 -0
  277. package/coverage/lcov-report/utils/preAuthCheck.ts.html +442 -0
  278. package/coverage/lcov-report/utils/redirectSecurity.ts.html +733 -0
  279. package/coverage/lcov-report/utils/tenantConfig.ts.html +712 -0
  280. package/coverage/lcov-report/utils/tokenStorage.ts.html +1825 -0
  281. package/coverage/lcov-report/utils/webCrypto.ts.html +490 -0
  282. package/coverage/lcov.info +15262 -14283
  283. package/coverage/providers/CrudifyThemeProvider.tsx.html +316 -0
  284. package/coverage/providers/SessionProvider.tsx.html +1120 -0
  285. package/coverage/providers/TranslationsProvider.tsx.html +1756 -0
  286. package/coverage/providers/index.html +146 -0
  287. package/coverage/services/credentialsEventBus.ts.html +319 -0
  288. package/coverage/services/crudifyAdminWrapper.ts.html +754 -0
  289. package/coverage/services/index.html +146 -0
  290. package/coverage/services/translationService.ts.html +1558 -0
  291. package/coverage/translations/critical.ts.html +1216 -0
  292. package/coverage/translations/index.html +116 -0
  293. package/coverage/types/index.html +116 -0
  294. package/coverage/types/password.ts.html +178 -0
  295. package/coverage/utils/authErrorDetector.ts.html +793 -0
  296. package/coverage/utils/authEventBus.ts.html +454 -0
  297. package/coverage/utils/configResolver.ts.html +460 -0
  298. package/coverage/utils/cookieSync.ts.html +595 -0
  299. package/coverage/utils/errorHandler.ts.html +1480 -0
  300. package/coverage/utils/errorTranslation.ts.html +868 -0
  301. package/coverage/utils/index.html +341 -0
  302. package/coverage/utils/index.ts.html +193 -0
  303. package/coverage/utils/jwtUtils.ts.html +325 -0
  304. package/coverage/utils/logger.ts.html +952 -0
  305. package/coverage/utils/navigationTracker.ts.html +562 -0
  306. package/coverage/utils/passwordValidation.ts.html +259 -0
  307. package/coverage/utils/preAuthCheck.ts.html +442 -0
  308. package/coverage/utils/redirectSecurity.ts.html +733 -0
  309. package/coverage/utils/tenantConfig.ts.html +712 -0
  310. package/coverage/utils/tokenStorage.ts.html +1825 -0
  311. package/coverage/utils/webCrypto.ts.html +490 -0
  312. package/dist/{CrudiaMarkdownField-CkiBwG-U.d.ts → CrudiaMarkdownField-DM6NR8zw.d.mts} +22 -22
  313. package/dist/{CrudiaMarkdownField-D-DqiXMQ.d.mts → CrudiaMarkdownField-UJaiSq9_.d.ts} +22 -22
  314. package/dist/{GlobalNotificationProvider-CdwdNv_8.d.mts → GlobalNotificationProvider-Cx540WKg.d.mts} +15 -15
  315. package/dist/{GlobalNotificationProvider-CdwdNv_8.d.ts → GlobalNotificationProvider-Cx540WKg.d.ts} +15 -15
  316. package/dist/chunk-2DXLCBOT.mjs +1 -0
  317. package/dist/chunk-DYRZIARH.js +1 -0
  318. package/dist/chunk-GCSJXEGT.mjs +1 -0
  319. package/dist/chunk-GJUZD5ZN.js +1 -0
  320. package/dist/chunk-K47I475N.js +1 -0
  321. package/dist/chunk-OCYZGEM5.mjs +1 -0
  322. package/dist/chunk-PI7HPRDB.js +1 -0
  323. package/dist/chunk-QVEUGJBY.mjs +1 -0
  324. package/dist/chunk-UROR7G7N.mjs +1 -0
  325. package/dist/chunk-XFT47DEL.js +1 -0
  326. package/dist/components.d.mts +8 -8
  327. package/dist/components.d.ts +8 -8
  328. package/dist/components.js +1 -1
  329. package/dist/components.mjs +1 -1
  330. package/dist/{errorTranslation-CF-5JClP.d.ts → errorTranslation-BEWwDbCH.d.ts} +1 -1
  331. package/dist/{errorTranslation-BcX8AaK7.d.mts → errorTranslation-DsGZon0M.d.mts} +1 -1
  332. package/dist/hooks.d.mts +3 -3
  333. package/dist/hooks.d.ts +3 -3
  334. package/dist/hooks.js +1 -1
  335. package/dist/hooks.mjs +1 -1
  336. package/dist/{index-DEDnmsdO.d.ts → index-Dnmttf62.d.ts} +131 -114
  337. package/dist/{index-D06kTP0C.d.mts → index-ZcF6nJt4.d.mts} +131 -114
  338. package/dist/index.d.mts +153 -106
  339. package/dist/index.d.ts +153 -106
  340. package/dist/index.js +2 -2
  341. package/dist/index.mjs +2 -2
  342. package/dist/{tenantConfig-CYnS9TPV.d.mts → tenantConfig-DxpfrAof.d.mts} +1 -1
  343. package/dist/{tenantConfig-CYnS9TPV.d.ts → tenantConfig-DxpfrAof.d.ts} +1 -1
  344. package/dist/utils.d.mts +25 -25
  345. package/dist/utils.d.ts +25 -25
  346. package/dist/utils.js +1 -1
  347. package/dist/utils.mjs +1 -1
  348. package/eslint.config.mjs +2 -2
  349. package/package.json +3 -3
  350. package/tests/helpers/mockFactories.ts +218 -0
  351. package/tests/helpers/testUtils.tsx +66 -1
  352. package/vitest.config.ts +1 -0
  353. package/dist/chunk-2WAUZ6KI.js +0 -1
  354. package/dist/chunk-3IGZNZCT.mjs +0 -1
  355. package/dist/chunk-43L2PP77.mjs +0 -1
  356. package/dist/chunk-6VS5OT3A.mjs +0 -1
  357. package/dist/chunk-BWJTTMKS.js +0 -1
  358. package/dist/chunk-EMPPCCVU.js +0 -1
  359. package/dist/chunk-J43UPGBE.js +0 -1
  360. package/dist/chunk-K6ZRXOJ7.mjs +0 -1
  361. package/dist/chunk-RYQQZTEP.js +0 -1
  362. package/dist/chunk-VTMSOK4V.mjs +0 -1
@@ -0,0 +1,3064 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for core/SessionManager.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">core</a> SessionManager.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">99.19% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>985/993</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">93.69% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>208/222</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'>34/34</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">99.19% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>985/993</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>
736
+ <a name='L671'></a><a href='#L671'>671</a>
737
+ <a name='L672'></a><a href='#L672'>672</a>
738
+ <a name='L673'></a><a href='#L673'>673</a>
739
+ <a name='L674'></a><a href='#L674'>674</a>
740
+ <a name='L675'></a><a href='#L675'>675</a>
741
+ <a name='L676'></a><a href='#L676'>676</a>
742
+ <a name='L677'></a><a href='#L677'>677</a>
743
+ <a name='L678'></a><a href='#L678'>678</a>
744
+ <a name='L679'></a><a href='#L679'>679</a>
745
+ <a name='L680'></a><a href='#L680'>680</a>
746
+ <a name='L681'></a><a href='#L681'>681</a>
747
+ <a name='L682'></a><a href='#L682'>682</a>
748
+ <a name='L683'></a><a href='#L683'>683</a>
749
+ <a name='L684'></a><a href='#L684'>684</a>
750
+ <a name='L685'></a><a href='#L685'>685</a>
751
+ <a name='L686'></a><a href='#L686'>686</a>
752
+ <a name='L687'></a><a href='#L687'>687</a>
753
+ <a name='L688'></a><a href='#L688'>688</a>
754
+ <a name='L689'></a><a href='#L689'>689</a>
755
+ <a name='L690'></a><a href='#L690'>690</a>
756
+ <a name='L691'></a><a href='#L691'>691</a>
757
+ <a name='L692'></a><a href='#L692'>692</a>
758
+ <a name='L693'></a><a href='#L693'>693</a>
759
+ <a name='L694'></a><a href='#L694'>694</a>
760
+ <a name='L695'></a><a href='#L695'>695</a>
761
+ <a name='L696'></a><a href='#L696'>696</a>
762
+ <a name='L697'></a><a href='#L697'>697</a>
763
+ <a name='L698'></a><a href='#L698'>698</a>
764
+ <a name='L699'></a><a href='#L699'>699</a>
765
+ <a name='L700'></a><a href='#L700'>700</a>
766
+ <a name='L701'></a><a href='#L701'>701</a>
767
+ <a name='L702'></a><a href='#L702'>702</a>
768
+ <a name='L703'></a><a href='#L703'>703</a>
769
+ <a name='L704'></a><a href='#L704'>704</a>
770
+ <a name='L705'></a><a href='#L705'>705</a>
771
+ <a name='L706'></a><a href='#L706'>706</a>
772
+ <a name='L707'></a><a href='#L707'>707</a>
773
+ <a name='L708'></a><a href='#L708'>708</a>
774
+ <a name='L709'></a><a href='#L709'>709</a>
775
+ <a name='L710'></a><a href='#L710'>710</a>
776
+ <a name='L711'></a><a href='#L711'>711</a>
777
+ <a name='L712'></a><a href='#L712'>712</a>
778
+ <a name='L713'></a><a href='#L713'>713</a>
779
+ <a name='L714'></a><a href='#L714'>714</a>
780
+ <a name='L715'></a><a href='#L715'>715</a>
781
+ <a name='L716'></a><a href='#L716'>716</a>
782
+ <a name='L717'></a><a href='#L717'>717</a>
783
+ <a name='L718'></a><a href='#L718'>718</a>
784
+ <a name='L719'></a><a href='#L719'>719</a>
785
+ <a name='L720'></a><a href='#L720'>720</a>
786
+ <a name='L721'></a><a href='#L721'>721</a>
787
+ <a name='L722'></a><a href='#L722'>722</a>
788
+ <a name='L723'></a><a href='#L723'>723</a>
789
+ <a name='L724'></a><a href='#L724'>724</a>
790
+ <a name='L725'></a><a href='#L725'>725</a>
791
+ <a name='L726'></a><a href='#L726'>726</a>
792
+ <a name='L727'></a><a href='#L727'>727</a>
793
+ <a name='L728'></a><a href='#L728'>728</a>
794
+ <a name='L729'></a><a href='#L729'>729</a>
795
+ <a name='L730'></a><a href='#L730'>730</a>
796
+ <a name='L731'></a><a href='#L731'>731</a>
797
+ <a name='L732'></a><a href='#L732'>732</a>
798
+ <a name='L733'></a><a href='#L733'>733</a>
799
+ <a name='L734'></a><a href='#L734'>734</a>
800
+ <a name='L735'></a><a href='#L735'>735</a>
801
+ <a name='L736'></a><a href='#L736'>736</a>
802
+ <a name='L737'></a><a href='#L737'>737</a>
803
+ <a name='L738'></a><a href='#L738'>738</a>
804
+ <a name='L739'></a><a href='#L739'>739</a>
805
+ <a name='L740'></a><a href='#L740'>740</a>
806
+ <a name='L741'></a><a href='#L741'>741</a>
807
+ <a name='L742'></a><a href='#L742'>742</a>
808
+ <a name='L743'></a><a href='#L743'>743</a>
809
+ <a name='L744'></a><a href='#L744'>744</a>
810
+ <a name='L745'></a><a href='#L745'>745</a>
811
+ <a name='L746'></a><a href='#L746'>746</a>
812
+ <a name='L747'></a><a href='#L747'>747</a>
813
+ <a name='L748'></a><a href='#L748'>748</a>
814
+ <a name='L749'></a><a href='#L749'>749</a>
815
+ <a name='L750'></a><a href='#L750'>750</a>
816
+ <a name='L751'></a><a href='#L751'>751</a>
817
+ <a name='L752'></a><a href='#L752'>752</a>
818
+ <a name='L753'></a><a href='#L753'>753</a>
819
+ <a name='L754'></a><a href='#L754'>754</a>
820
+ <a name='L755'></a><a href='#L755'>755</a>
821
+ <a name='L756'></a><a href='#L756'>756</a>
822
+ <a name='L757'></a><a href='#L757'>757</a>
823
+ <a name='L758'></a><a href='#L758'>758</a>
824
+ <a name='L759'></a><a href='#L759'>759</a>
825
+ <a name='L760'></a><a href='#L760'>760</a>
826
+ <a name='L761'></a><a href='#L761'>761</a>
827
+ <a name='L762'></a><a href='#L762'>762</a>
828
+ <a name='L763'></a><a href='#L763'>763</a>
829
+ <a name='L764'></a><a href='#L764'>764</a>
830
+ <a name='L765'></a><a href='#L765'>765</a>
831
+ <a name='L766'></a><a href='#L766'>766</a>
832
+ <a name='L767'></a><a href='#L767'>767</a>
833
+ <a name='L768'></a><a href='#L768'>768</a>
834
+ <a name='L769'></a><a href='#L769'>769</a>
835
+ <a name='L770'></a><a href='#L770'>770</a>
836
+ <a name='L771'></a><a href='#L771'>771</a>
837
+ <a name='L772'></a><a href='#L772'>772</a>
838
+ <a name='L773'></a><a href='#L773'>773</a>
839
+ <a name='L774'></a><a href='#L774'>774</a>
840
+ <a name='L775'></a><a href='#L775'>775</a>
841
+ <a name='L776'></a><a href='#L776'>776</a>
842
+ <a name='L777'></a><a href='#L777'>777</a>
843
+ <a name='L778'></a><a href='#L778'>778</a>
844
+ <a name='L779'></a><a href='#L779'>779</a>
845
+ <a name='L780'></a><a href='#L780'>780</a>
846
+ <a name='L781'></a><a href='#L781'>781</a>
847
+ <a name='L782'></a><a href='#L782'>782</a>
848
+ <a name='L783'></a><a href='#L783'>783</a>
849
+ <a name='L784'></a><a href='#L784'>784</a>
850
+ <a name='L785'></a><a href='#L785'>785</a>
851
+ <a name='L786'></a><a href='#L786'>786</a>
852
+ <a name='L787'></a><a href='#L787'>787</a>
853
+ <a name='L788'></a><a href='#L788'>788</a>
854
+ <a name='L789'></a><a href='#L789'>789</a>
855
+ <a name='L790'></a><a href='#L790'>790</a>
856
+ <a name='L791'></a><a href='#L791'>791</a>
857
+ <a name='L792'></a><a href='#L792'>792</a>
858
+ <a name='L793'></a><a href='#L793'>793</a>
859
+ <a name='L794'></a><a href='#L794'>794</a>
860
+ <a name='L795'></a><a href='#L795'>795</a>
861
+ <a name='L796'></a><a href='#L796'>796</a>
862
+ <a name='L797'></a><a href='#L797'>797</a>
863
+ <a name='L798'></a><a href='#L798'>798</a>
864
+ <a name='L799'></a><a href='#L799'>799</a>
865
+ <a name='L800'></a><a href='#L800'>800</a>
866
+ <a name='L801'></a><a href='#L801'>801</a>
867
+ <a name='L802'></a><a href='#L802'>802</a>
868
+ <a name='L803'></a><a href='#L803'>803</a>
869
+ <a name='L804'></a><a href='#L804'>804</a>
870
+ <a name='L805'></a><a href='#L805'>805</a>
871
+ <a name='L806'></a><a href='#L806'>806</a>
872
+ <a name='L807'></a><a href='#L807'>807</a>
873
+ <a name='L808'></a><a href='#L808'>808</a>
874
+ <a name='L809'></a><a href='#L809'>809</a>
875
+ <a name='L810'></a><a href='#L810'>810</a>
876
+ <a name='L811'></a><a href='#L811'>811</a>
877
+ <a name='L812'></a><a href='#L812'>812</a>
878
+ <a name='L813'></a><a href='#L813'>813</a>
879
+ <a name='L814'></a><a href='#L814'>814</a>
880
+ <a name='L815'></a><a href='#L815'>815</a>
881
+ <a name='L816'></a><a href='#L816'>816</a>
882
+ <a name='L817'></a><a href='#L817'>817</a>
883
+ <a name='L818'></a><a href='#L818'>818</a>
884
+ <a name='L819'></a><a href='#L819'>819</a>
885
+ <a name='L820'></a><a href='#L820'>820</a>
886
+ <a name='L821'></a><a href='#L821'>821</a>
887
+ <a name='L822'></a><a href='#L822'>822</a>
888
+ <a name='L823'></a><a href='#L823'>823</a>
889
+ <a name='L824'></a><a href='#L824'>824</a>
890
+ <a name='L825'></a><a href='#L825'>825</a>
891
+ <a name='L826'></a><a href='#L826'>826</a>
892
+ <a name='L827'></a><a href='#L827'>827</a>
893
+ <a name='L828'></a><a href='#L828'>828</a>
894
+ <a name='L829'></a><a href='#L829'>829</a>
895
+ <a name='L830'></a><a href='#L830'>830</a>
896
+ <a name='L831'></a><a href='#L831'>831</a>
897
+ <a name='L832'></a><a href='#L832'>832</a>
898
+ <a name='L833'></a><a href='#L833'>833</a>
899
+ <a name='L834'></a><a href='#L834'>834</a>
900
+ <a name='L835'></a><a href='#L835'>835</a>
901
+ <a name='L836'></a><a href='#L836'>836</a>
902
+ <a name='L837'></a><a href='#L837'>837</a>
903
+ <a name='L838'></a><a href='#L838'>838</a>
904
+ <a name='L839'></a><a href='#L839'>839</a>
905
+ <a name='L840'></a><a href='#L840'>840</a>
906
+ <a name='L841'></a><a href='#L841'>841</a>
907
+ <a name='L842'></a><a href='#L842'>842</a>
908
+ <a name='L843'></a><a href='#L843'>843</a>
909
+ <a name='L844'></a><a href='#L844'>844</a>
910
+ <a name='L845'></a><a href='#L845'>845</a>
911
+ <a name='L846'></a><a href='#L846'>846</a>
912
+ <a name='L847'></a><a href='#L847'>847</a>
913
+ <a name='L848'></a><a href='#L848'>848</a>
914
+ <a name='L849'></a><a href='#L849'>849</a>
915
+ <a name='L850'></a><a href='#L850'>850</a>
916
+ <a name='L851'></a><a href='#L851'>851</a>
917
+ <a name='L852'></a><a href='#L852'>852</a>
918
+ <a name='L853'></a><a href='#L853'>853</a>
919
+ <a name='L854'></a><a href='#L854'>854</a>
920
+ <a name='L855'></a><a href='#L855'>855</a>
921
+ <a name='L856'></a><a href='#L856'>856</a>
922
+ <a name='L857'></a><a href='#L857'>857</a>
923
+ <a name='L858'></a><a href='#L858'>858</a>
924
+ <a name='L859'></a><a href='#L859'>859</a>
925
+ <a name='L860'></a><a href='#L860'>860</a>
926
+ <a name='L861'></a><a href='#L861'>861</a>
927
+ <a name='L862'></a><a href='#L862'>862</a>
928
+ <a name='L863'></a><a href='#L863'>863</a>
929
+ <a name='L864'></a><a href='#L864'>864</a>
930
+ <a name='L865'></a><a href='#L865'>865</a>
931
+ <a name='L866'></a><a href='#L866'>866</a>
932
+ <a name='L867'></a><a href='#L867'>867</a>
933
+ <a name='L868'></a><a href='#L868'>868</a>
934
+ <a name='L869'></a><a href='#L869'>869</a>
935
+ <a name='L870'></a><a href='#L870'>870</a>
936
+ <a name='L871'></a><a href='#L871'>871</a>
937
+ <a name='L872'></a><a href='#L872'>872</a>
938
+ <a name='L873'></a><a href='#L873'>873</a>
939
+ <a name='L874'></a><a href='#L874'>874</a>
940
+ <a name='L875'></a><a href='#L875'>875</a>
941
+ <a name='L876'></a><a href='#L876'>876</a>
942
+ <a name='L877'></a><a href='#L877'>877</a>
943
+ <a name='L878'></a><a href='#L878'>878</a>
944
+ <a name='L879'></a><a href='#L879'>879</a>
945
+ <a name='L880'></a><a href='#L880'>880</a>
946
+ <a name='L881'></a><a href='#L881'>881</a>
947
+ <a name='L882'></a><a href='#L882'>882</a>
948
+ <a name='L883'></a><a href='#L883'>883</a>
949
+ <a name='L884'></a><a href='#L884'>884</a>
950
+ <a name='L885'></a><a href='#L885'>885</a>
951
+ <a name='L886'></a><a href='#L886'>886</a>
952
+ <a name='L887'></a><a href='#L887'>887</a>
953
+ <a name='L888'></a><a href='#L888'>888</a>
954
+ <a name='L889'></a><a href='#L889'>889</a>
955
+ <a name='L890'></a><a href='#L890'>890</a>
956
+ <a name='L891'></a><a href='#L891'>891</a>
957
+ <a name='L892'></a><a href='#L892'>892</a>
958
+ <a name='L893'></a><a href='#L893'>893</a>
959
+ <a name='L894'></a><a href='#L894'>894</a>
960
+ <a name='L895'></a><a href='#L895'>895</a>
961
+ <a name='L896'></a><a href='#L896'>896</a>
962
+ <a name='L897'></a><a href='#L897'>897</a>
963
+ <a name='L898'></a><a href='#L898'>898</a>
964
+ <a name='L899'></a><a href='#L899'>899</a>
965
+ <a name='L900'></a><a href='#L900'>900</a>
966
+ <a name='L901'></a><a href='#L901'>901</a>
967
+ <a name='L902'></a><a href='#L902'>902</a>
968
+ <a name='L903'></a><a href='#L903'>903</a>
969
+ <a name='L904'></a><a href='#L904'>904</a>
970
+ <a name='L905'></a><a href='#L905'>905</a>
971
+ <a name='L906'></a><a href='#L906'>906</a>
972
+ <a name='L907'></a><a href='#L907'>907</a>
973
+ <a name='L908'></a><a href='#L908'>908</a>
974
+ <a name='L909'></a><a href='#L909'>909</a>
975
+ <a name='L910'></a><a href='#L910'>910</a>
976
+ <a name='L911'></a><a href='#L911'>911</a>
977
+ <a name='L912'></a><a href='#L912'>912</a>
978
+ <a name='L913'></a><a href='#L913'>913</a>
979
+ <a name='L914'></a><a href='#L914'>914</a>
980
+ <a name='L915'></a><a href='#L915'>915</a>
981
+ <a name='L916'></a><a href='#L916'>916</a>
982
+ <a name='L917'></a><a href='#L917'>917</a>
983
+ <a name='L918'></a><a href='#L918'>918</a>
984
+ <a name='L919'></a><a href='#L919'>919</a>
985
+ <a name='L920'></a><a href='#L920'>920</a>
986
+ <a name='L921'></a><a href='#L921'>921</a>
987
+ <a name='L922'></a><a href='#L922'>922</a>
988
+ <a name='L923'></a><a href='#L923'>923</a>
989
+ <a name='L924'></a><a href='#L924'>924</a>
990
+ <a name='L925'></a><a href='#L925'>925</a>
991
+ <a name='L926'></a><a href='#L926'>926</a>
992
+ <a name='L927'></a><a href='#L927'>927</a>
993
+ <a name='L928'></a><a href='#L928'>928</a>
994
+ <a name='L929'></a><a href='#L929'>929</a>
995
+ <a name='L930'></a><a href='#L930'>930</a>
996
+ <a name='L931'></a><a href='#L931'>931</a>
997
+ <a name='L932'></a><a href='#L932'>932</a>
998
+ <a name='L933'></a><a href='#L933'>933</a>
999
+ <a name='L934'></a><a href='#L934'>934</a>
1000
+ <a name='L935'></a><a href='#L935'>935</a>
1001
+ <a name='L936'></a><a href='#L936'>936</a>
1002
+ <a name='L937'></a><a href='#L937'>937</a>
1003
+ <a name='L938'></a><a href='#L938'>938</a>
1004
+ <a name='L939'></a><a href='#L939'>939</a>
1005
+ <a name='L940'></a><a href='#L940'>940</a>
1006
+ <a name='L941'></a><a href='#L941'>941</a>
1007
+ <a name='L942'></a><a href='#L942'>942</a>
1008
+ <a name='L943'></a><a href='#L943'>943</a>
1009
+ <a name='L944'></a><a href='#L944'>944</a>
1010
+ <a name='L945'></a><a href='#L945'>945</a>
1011
+ <a name='L946'></a><a href='#L946'>946</a>
1012
+ <a name='L947'></a><a href='#L947'>947</a>
1013
+ <a name='L948'></a><a href='#L948'>948</a>
1014
+ <a name='L949'></a><a href='#L949'>949</a>
1015
+ <a name='L950'></a><a href='#L950'>950</a>
1016
+ <a name='L951'></a><a href='#L951'>951</a>
1017
+ <a name='L952'></a><a href='#L952'>952</a>
1018
+ <a name='L953'></a><a href='#L953'>953</a>
1019
+ <a name='L954'></a><a href='#L954'>954</a>
1020
+ <a name='L955'></a><a href='#L955'>955</a>
1021
+ <a name='L956'></a><a href='#L956'>956</a>
1022
+ <a name='L957'></a><a href='#L957'>957</a>
1023
+ <a name='L958'></a><a href='#L958'>958</a>
1024
+ <a name='L959'></a><a href='#L959'>959</a>
1025
+ <a name='L960'></a><a href='#L960'>960</a>
1026
+ <a name='L961'></a><a href='#L961'>961</a>
1027
+ <a name='L962'></a><a href='#L962'>962</a>
1028
+ <a name='L963'></a><a href='#L963'>963</a>
1029
+ <a name='L964'></a><a href='#L964'>964</a>
1030
+ <a name='L965'></a><a href='#L965'>965</a>
1031
+ <a name='L966'></a><a href='#L966'>966</a>
1032
+ <a name='L967'></a><a href='#L967'>967</a>
1033
+ <a name='L968'></a><a href='#L968'>968</a>
1034
+ <a name='L969'></a><a href='#L969'>969</a>
1035
+ <a name='L970'></a><a href='#L970'>970</a>
1036
+ <a name='L971'></a><a href='#L971'>971</a>
1037
+ <a name='L972'></a><a href='#L972'>972</a>
1038
+ <a name='L973'></a><a href='#L973'>973</a>
1039
+ <a name='L974'></a><a href='#L974'>974</a>
1040
+ <a name='L975'></a><a href='#L975'>975</a>
1041
+ <a name='L976'></a><a href='#L976'>976</a>
1042
+ <a name='L977'></a><a href='#L977'>977</a>
1043
+ <a name='L978'></a><a href='#L978'>978</a>
1044
+ <a name='L979'></a><a href='#L979'>979</a>
1045
+ <a name='L980'></a><a href='#L980'>980</a>
1046
+ <a name='L981'></a><a href='#L981'>981</a>
1047
+ <a name='L982'></a><a href='#L982'>982</a>
1048
+ <a name='L983'></a><a href='#L983'>983</a>
1049
+ <a name='L984'></a><a href='#L984'>984</a>
1050
+ <a name='L985'></a><a href='#L985'>985</a>
1051
+ <a name='L986'></a><a href='#L986'>986</a>
1052
+ <a name='L987'></a><a href='#L987'>987</a>
1053
+ <a name='L988'></a><a href='#L988'>988</a>
1054
+ <a name='L989'></a><a href='#L989'>989</a>
1055
+ <a name='L990'></a><a href='#L990'>990</a>
1056
+ <a name='L991'></a><a href='#L991'>991</a>
1057
+ <a name='L992'></a><a href='#L992'>992</a>
1058
+ <a name='L993'></a><a href='#L993'>993</a>
1059
+ <a name='L994'></a><a href='#L994'>994</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
1060
+ <span class="cline-any cline-yes">1x</span>
1061
+ <span class="cline-any cline-yes">1x</span>
1062
+ <span class="cline-any cline-yes">1x</span>
1063
+ <span class="cline-any cline-yes">1x</span>
1064
+ <span class="cline-any cline-yes">1x</span>
1065
+ <span class="cline-any cline-yes">1x</span>
1066
+ <span class="cline-any cline-yes">1x</span>
1067
+ <span class="cline-any cline-yes">1x</span>
1068
+ <span class="cline-any cline-yes">1x</span>
1069
+ <span class="cline-any cline-yes">1x</span>
1070
+ <span class="cline-any cline-yes">1x</span>
1071
+ <span class="cline-any cline-yes">1x</span>
1072
+ <span class="cline-any cline-yes">1x</span>
1073
+ <span class="cline-any cline-yes">1x</span>
1074
+ <span class="cline-any cline-yes">1x</span>
1075
+ <span class="cline-any cline-yes">1x</span>
1076
+ <span class="cline-any cline-yes">1x</span>
1077
+ <span class="cline-any cline-yes">1x</span>
1078
+ <span class="cline-any cline-yes">1x</span>
1079
+ <span class="cline-any cline-yes">1x</span>
1080
+ <span class="cline-any cline-yes">1x</span>
1081
+ <span class="cline-any cline-yes">1x</span>
1082
+ <span class="cline-any cline-yes">1x</span>
1083
+ <span class="cline-any cline-yes">1x</span>
1084
+ <span class="cline-any cline-yes">1x</span>
1085
+ <span class="cline-any cline-yes">1x</span>
1086
+ <span class="cline-any cline-yes">1x</span>
1087
+ <span class="cline-any cline-yes">1x</span>
1088
+ <span class="cline-any cline-yes">1x</span>
1089
+ <span class="cline-any cline-yes">1x</span>
1090
+ <span class="cline-any cline-yes">1x</span>
1091
+ <span class="cline-any cline-yes">1x</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">1x</span>
1095
+ <span class="cline-any cline-yes">1x</span>
1096
+ <span class="cline-any cline-yes">1x</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">1x</span>
1105
+ <span class="cline-any cline-yes">1x</span>
1106
+ <span class="cline-any cline-yes">1x</span>
1107
+ <span class="cline-any cline-yes">1x</span>
1108
+ <span class="cline-any cline-yes">1x</span>
1109
+ <span class="cline-any cline-yes">1x</span>
1110
+ <span class="cline-any cline-yes">1x</span>
1111
+ <span class="cline-any cline-yes">1x</span>
1112
+ <span class="cline-any cline-yes">1x</span>
1113
+ <span class="cline-any cline-yes">1x</span>
1114
+ <span class="cline-any cline-yes">1x</span>
1115
+ <span class="cline-any cline-yes">1x</span>
1116
+ <span class="cline-any cline-yes">1x</span>
1117
+ <span class="cline-any cline-yes">1x</span>
1118
+ <span class="cline-any cline-yes">1x</span>
1119
+ <span class="cline-any cline-yes">1x</span>
1120
+ <span class="cline-any cline-yes">1x</span>
1121
+ <span class="cline-any cline-yes">1x</span>
1122
+ <span class="cline-any cline-yes">1x</span>
1123
+ <span class="cline-any cline-yes">1x</span>
1124
+ <span class="cline-any cline-yes">1x</span>
1125
+ <span class="cline-any cline-yes">1x</span>
1126
+ <span class="cline-any cline-yes">1x</span>
1127
+ <span class="cline-any cline-yes">1x</span>
1128
+ <span class="cline-any cline-yes">1x</span>
1129
+ <span class="cline-any cline-yes">123x</span>
1130
+ <span class="cline-any cline-yes">1x</span>
1131
+ <span class="cline-any cline-yes">1x</span>
1132
+ <span class="cline-any cline-yes">123x</span>
1133
+ <span class="cline-any cline-yes">123x</span>
1134
+ <span class="cline-any cline-yes">1x</span>
1135
+ <span class="cline-any cline-yes">1x</span>
1136
+ <span class="cline-any cline-yes">1x</span>
1137
+ <span class="cline-any cline-yes">1x</span>
1138
+ <span class="cline-any cline-yes">1x</span>
1139
+ <span class="cline-any cline-yes">65x</span>
1140
+ <span class="cline-any cline-yes">1x</span>
1141
+ <span class="cline-any cline-yes">1x</span>
1142
+ <span class="cline-any cline-yes">64x</span>
1143
+ <span class="cline-any cline-yes">64x</span>
1144
+ <span class="cline-any cline-yes">64x</span>
1145
+ <span class="cline-any cline-yes">64x</span>
1146
+ <span class="cline-any cline-yes">64x</span>
1147
+ <span class="cline-any cline-yes">64x</span>
1148
+ <span class="cline-any cline-yes">64x</span>
1149
+ <span class="cline-any cline-yes">64x</span>
1150
+ <span class="cline-any cline-yes">64x</span>
1151
+ <span class="cline-any cline-yes">65x</span>
1152
+ <span class="cline-any cline-yes">65x</span>
1153
+ <span class="cline-any cline-yes">65x</span>
1154
+ <span class="cline-any cline-yes">65x</span>
1155
+ <span class="cline-any cline-yes">4x</span>
1156
+ <span class="cline-any cline-yes">3x</span>
1157
+ <span class="cline-any cline-yes">63x</span>
1158
+ <span class="cline-any cline-yes">63x</span>
1159
+ <span class="cline-any cline-yes">63x</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">63x</span>
1166
+ <span class="cline-any cline-yes">63x</span>
1167
+ <span class="cline-any cline-yes">63x</span>
1168
+ <span class="cline-any cline-yes">65x</span>
1169
+ <span class="cline-any cline-yes">2x</span>
1170
+ <span class="cline-any cline-yes">2x</span>
1171
+ <span class="cline-any cline-yes">1x</span>
1172
+ <span class="cline-any cline-yes">1x</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">1x</span>
1176
+ <span class="cline-any cline-yes">1x</span>
1177
+ <span class="cline-any cline-yes">1x</span>
1178
+ <span class="cline-any cline-yes">1x</span>
1179
+ <span class="cline-any cline-yes">1x</span>
1180
+ <span class="cline-any cline-yes">1x</span>
1181
+ <span class="cline-any cline-yes">1x</span>
1182
+ <span class="cline-any cline-yes">1x</span>
1183
+ <span class="cline-any cline-yes">1x</span>
1184
+ <span class="cline-any cline-yes">1x</span>
1185
+ <span class="cline-any cline-yes">1x</span>
1186
+ <span class="cline-any cline-yes">2x</span>
1187
+ <span class="cline-any cline-yes">63x</span>
1188
+ <span class="cline-any cline-yes">65x</span>
1189
+ <span class="cline-any cline-yes">2x</span>
1190
+ <span class="cline-any cline-yes">2x</span>
1191
+ <span class="cline-any cline-yes">63x</span>
1192
+ <span class="cline-any cline-yes">63x</span>
1193
+ <span class="cline-any cline-yes">65x</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">1x</span>
1197
+ <span class="cline-any cline-yes">1x</span>
1198
+ <span class="cline-any cline-yes">1x</span>
1199
+ <span class="cline-any cline-yes">25x</span>
1200
+ <span class="cline-any cline-yes">25x</span>
1201
+ <span class="cline-any cline-yes">22x</span>
1202
+ <span class="cline-any cline-yes">25x</span>
1203
+ <span class="cline-any cline-yes">7x</span>
1204
+ <span class="cline-any cline-yes">7x</span>
1205
+ <span class="cline-any cline-yes">7x</span>
1206
+ <span class="cline-any cline-yes">7x</span>
1207
+ <span class="cline-any cline-yes">7x</span>
1208
+ <span class="cline-any cline-yes">7x</span>
1209
+ <span class="cline-any cline-yes">15x</span>
1210
+ <span class="cline-any cline-yes">15x</span>
1211
+ <span class="cline-any cline-yes">15x</span>
1212
+ <span class="cline-any cline-yes">15x</span>
1213
+ <span class="cline-any cline-yes">15x</span>
1214
+ <span class="cline-any cline-yes">15x</span>
1215
+ <span class="cline-any cline-yes">15x</span>
1216
+ <span class="cline-any cline-yes">15x</span>
1217
+ <span class="cline-any cline-yes">15x</span>
1218
+ <span class="cline-any cline-yes">25x</span>
1219
+ <span class="cline-any cline-yes">25x</span>
1220
+ <span class="cline-any cline-yes">25x</span>
1221
+ <span class="cline-any cline-yes">25x</span>
1222
+ <span class="cline-any cline-yes">25x</span>
1223
+ <span class="cline-any cline-yes">15x</span>
1224
+ <span class="cline-any cline-yes">15x</span>
1225
+ <span class="cline-any cline-yes">15x</span>
1226
+ <span class="cline-any cline-yes">15x</span>
1227
+ <span class="cline-any cline-yes">15x</span>
1228
+ <span class="cline-any cline-yes">15x</span>
1229
+ <span class="cline-any cline-yes">15x</span>
1230
+ <span class="cline-any cline-yes">15x</span>
1231
+ <span class="cline-any cline-yes">15x</span>
1232
+ <span class="cline-any cline-yes">15x</span>
1233
+ <span class="cline-any cline-yes">15x</span>
1234
+ <span class="cline-any cline-yes">15x</span>
1235
+ <span class="cline-any cline-yes">15x</span>
1236
+ <span class="cline-any cline-yes">25x</span>
1237
+ <span class="cline-any cline-yes">25x</span>
1238
+ <span class="cline-any cline-yes">25x</span>
1239
+ <span class="cline-any cline-yes">25x</span>
1240
+ <span class="cline-any cline-yes">25x</span>
1241
+ <span class="cline-any cline-yes">25x</span>
1242
+ <span class="cline-any cline-yes">25x</span>
1243
+ <span class="cline-any cline-yes">25x</span>
1244
+ <span class="cline-any cline-yes">3x</span>
1245
+ <span class="cline-any cline-yes">3x</span>
1246
+ <span class="cline-any cline-yes">3x</span>
1247
+ <span class="cline-any cline-yes">3x</span>
1248
+ <span class="cline-any cline-yes">3x</span>
1249
+ <span class="cline-any cline-yes">3x</span>
1250
+ <span class="cline-any cline-yes">25x</span>
1251
+ <span class="cline-any cline-yes">1x</span>
1252
+ <span class="cline-any cline-yes">1x</span>
1253
+ <span class="cline-any cline-yes">1x</span>
1254
+ <span class="cline-any cline-yes">1x</span>
1255
+ <span class="cline-any cline-yes">1x</span>
1256
+ <span class="cline-any cline-yes">10x</span>
1257
+ <span class="cline-any cline-yes">10x</span>
1258
+ <span class="cline-any cline-yes">10x</span>
1259
+ <span class="cline-any cline-yes">10x</span>
1260
+ <span class="cline-any cline-yes">10x</span>
1261
+ <span class="cline-any cline-yes">10x</span>
1262
+ <span class="cline-any cline-yes">10x</span>
1263
+ <span class="cline-any cline-yes">10x</span>
1264
+ <span class="cline-any cline-yes">10x</span>
1265
+ <span class="cline-any cline-yes">10x</span>
1266
+ <span class="cline-any cline-yes">10x</span>
1267
+ <span class="cline-any cline-yes">10x</span>
1268
+ <span class="cline-any cline-yes">10x</span>
1269
+ <span class="cline-any cline-yes">10x</span>
1270
+ <span class="cline-any cline-yes">10x</span>
1271
+ <span class="cline-any cline-yes">10x</span>
1272
+ <span class="cline-any cline-yes">10x</span>
1273
+ <span class="cline-any cline-yes">10x</span>
1274
+ <span class="cline-any cline-yes">8x</span>
1275
+ <span class="cline-any cline-yes">8x</span>
1276
+ <span class="cline-any cline-yes">8x</span>
1277
+ <span class="cline-any cline-yes">8x</span>
1278
+ <span class="cline-any cline-yes">8x</span>
1279
+ <span class="cline-any cline-yes">8x</span>
1280
+ <span class="cline-any cline-yes">8x</span>
1281
+ <span class="cline-any cline-yes">8x</span>
1282
+ <span class="cline-any cline-yes">8x</span>
1283
+ <span class="cline-any cline-yes">8x</span>
1284
+ <span class="cline-any cline-yes">10x</span>
1285
+ <span class="cline-any cline-yes">10x</span>
1286
+ <span class="cline-any cline-yes">2x</span>
1287
+ <span class="cline-any cline-yes">2x</span>
1288
+ <span class="cline-any cline-yes">2x</span>
1289
+ <span class="cline-any cline-yes">2x</span>
1290
+ <span class="cline-any cline-yes">2x</span>
1291
+ <span class="cline-any cline-yes">2x</span>
1292
+ <span class="cline-any cline-yes">10x</span>
1293
+ <span class="cline-any cline-yes">1x</span>
1294
+ <span class="cline-any cline-yes">1x</span>
1295
+ <span class="cline-any cline-yes">1x</span>
1296
+ <span class="cline-any cline-yes">1x</span>
1297
+ <span class="cline-any cline-yes">1x</span>
1298
+ <span class="cline-any cline-yes">1x</span>
1299
+ <span class="cline-any cline-yes">12x</span>
1300
+ <span class="cline-any cline-yes">12x</span>
1301
+ <span class="cline-any cline-yes">12x</span>
1302
+ <span class="cline-any cline-yes">12x</span>
1303
+ <span class="cline-any cline-yes">12x</span>
1304
+ <span class="cline-any cline-yes">12x</span>
1305
+ <span class="cline-any cline-yes">12x</span>
1306
+ <span class="cline-any cline-yes">3x</span>
1307
+ <span class="cline-any cline-yes">3x</span>
1308
+ <span class="cline-any cline-yes">3x</span>
1309
+ <span class="cline-any cline-yes">3x</span>
1310
+ <span class="cline-any cline-yes">8x</span>
1311
+ <span class="cline-any cline-yes">8x</span>
1312
+ <span class="cline-any cline-yes">12x</span>
1313
+ <span class="cline-any cline-yes">1x</span>
1314
+ <span class="cline-any cline-yes">1x</span>
1315
+ <span class="cline-any cline-yes">1x</span>
1316
+ <span class="cline-any cline-yes">1x</span>
1317
+ <span class="cline-any cline-yes">1x</span>
1318
+ <span class="cline-any cline-yes">1x</span>
1319
+ <span class="cline-any cline-yes">7x</span>
1320
+ <span class="cline-any cline-yes">7x</span>
1321
+ <span class="cline-any cline-yes">7x</span>
1322
+ <span class="cline-any cline-yes">7x</span>
1323
+ <span class="cline-any cline-yes">7x</span>
1324
+ <span class="cline-any cline-yes">7x</span>
1325
+ <span class="cline-any cline-yes">7x</span>
1326
+ <span class="cline-any cline-yes">7x</span>
1327
+ <span class="cline-any cline-yes">7x</span>
1328
+ <span class="cline-any cline-yes">7x</span>
1329
+ <span class="cline-any cline-yes">7x</span>
1330
+ <span class="cline-any cline-yes">7x</span>
1331
+ <span class="cline-any cline-yes">12x</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">4x</span>
1336
+ <span class="cline-any cline-yes">4x</span>
1337
+ <span class="cline-any cline-yes">4x</span>
1338
+ <span class="cline-any cline-yes">4x</span>
1339
+ <span class="cline-any cline-yes">4x</span>
1340
+ <span class="cline-any cline-yes">4x</span>
1341
+ <span class="cline-any cline-yes">1x</span>
1342
+ <span class="cline-any cline-yes">1x</span>
1343
+ <span class="cline-any cline-yes">1x</span>
1344
+ <span class="cline-any cline-yes">1x</span>
1345
+ <span class="cline-any cline-yes">1x</span>
1346
+ <span class="cline-any cline-yes">1x</span>
1347
+ <span class="cline-any cline-yes">1x</span>
1348
+ <span class="cline-any cline-yes">1x</span>
1349
+ <span class="cline-any cline-yes">1x</span>
1350
+ <span class="cline-any cline-yes">4x</span>
1351
+ <span class="cline-any cline-yes">3x</span>
1352
+ <span class="cline-any cline-yes">3x</span>
1353
+ <span class="cline-any cline-yes">3x</span>
1354
+ <span class="cline-any cline-yes">3x</span>
1355
+ <span class="cline-any cline-yes">3x</span>
1356
+ <span class="cline-any cline-yes">3x</span>
1357
+ <span class="cline-any cline-yes">3x</span>
1358
+ <span class="cline-any cline-yes">3x</span>
1359
+ <span class="cline-any cline-yes">3x</span>
1360
+ <span class="cline-any cline-yes">3x</span>
1361
+ <span class="cline-any cline-yes">3x</span>
1362
+ <span class="cline-any cline-yes">3x</span>
1363
+ <span class="cline-any cline-yes">3x</span>
1364
+ <span class="cline-any cline-yes">3x</span>
1365
+ <span class="cline-any cline-yes">3x</span>
1366
+ <span class="cline-any cline-yes">3x</span>
1367
+ <span class="cline-any cline-yes">3x</span>
1368
+ <span class="cline-any cline-yes">3x</span>
1369
+ <span class="cline-any cline-yes">3x</span>
1370
+ <span class="cline-any cline-yes">3x</span>
1371
+ <span class="cline-any cline-yes">12x</span>
1372
+ <span class="cline-any cline-yes">12x</span>
1373
+ <span class="cline-any cline-yes">12x</span>
1374
+ <span class="cline-any cline-yes">12x</span>
1375
+ <span class="cline-any cline-yes">1x</span>
1376
+ <span class="cline-any cline-yes">1x</span>
1377
+ <span class="cline-any cline-yes">1x</span>
1378
+ <span class="cline-any cline-yes">1x</span>
1379
+ <span class="cline-any cline-yes">1x</span>
1380
+ <span class="cline-any cline-yes">1x</span>
1381
+ <span class="cline-any cline-yes">1x</span>
1382
+ <span class="cline-any cline-yes">12x</span>
1383
+ <span class="cline-any cline-yes">1x</span>
1384
+ <span class="cline-any cline-yes">1x</span>
1385
+ <span class="cline-any cline-yes">1x</span>
1386
+ <span class="cline-any cline-yes">1x</span>
1387
+ <span class="cline-any cline-yes">1x</span>
1388
+ <span class="cline-any cline-yes">5x</span>
1389
+ <span class="cline-any cline-yes">5x</span>
1390
+ <span class="cline-any cline-yes">1x</span>
1391
+ <span class="cline-any cline-yes">1x</span>
1392
+ <span class="cline-any cline-yes">1x</span>
1393
+ <span class="cline-any cline-yes">1x</span>
1394
+ <span class="cline-any cline-yes">1x</span>
1395
+ <span class="cline-any cline-yes">1x</span>
1396
+ <span class="cline-any cline-yes">1x</span>
1397
+ <span class="cline-any cline-yes">1x</span>
1398
+ <span class="cline-any cline-yes">1x</span>
1399
+ <span class="cline-any cline-yes">1x</span>
1400
+ <span class="cline-any cline-yes">1x</span>
1401
+ <span class="cline-any cline-yes">1x</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-yes">1x</span>
1405
+ <span class="cline-any cline-yes">1x</span>
1406
+ <span class="cline-any cline-yes">1x</span>
1407
+ <span class="cline-any cline-yes">1x</span>
1408
+ <span class="cline-any cline-yes">1x</span>
1409
+ <span class="cline-any cline-yes">1x</span>
1410
+ <span class="cline-any cline-yes">1x</span>
1411
+ <span class="cline-any cline-yes">1x</span>
1412
+ <span class="cline-any cline-yes">1x</span>
1413
+ <span class="cline-any cline-yes">1x</span>
1414
+ <span class="cline-any cline-yes">17x</span>
1415
+ <span class="cline-any cline-yes">17x</span>
1416
+ <span class="cline-any cline-yes">2x</span>
1417
+ <span class="cline-any cline-yes">2x</span>
1418
+ <span class="cline-any cline-yes">2x</span>
1419
+ <span class="cline-any cline-yes">15x</span>
1420
+ <span class="cline-any cline-yes">15x</span>
1421
+ <span class="cline-any cline-yes">15x</span>
1422
+ <span class="cline-any cline-yes">15x</span>
1423
+ <span class="cline-any cline-yes">15x</span>
1424
+ <span class="cline-any cline-yes">15x</span>
1425
+ <span class="cline-any cline-yes">15x</span>
1426
+ <span class="cline-any cline-yes">15x</span>
1427
+ <span class="cline-any cline-yes">15x</span>
1428
+ <span class="cline-any cline-yes">15x</span>
1429
+ <span class="cline-any cline-yes">15x</span>
1430
+ <span class="cline-any cline-yes">15x</span>
1431
+ <span class="cline-any cline-yes">15x</span>
1432
+ <span class="cline-any cline-yes">15x</span>
1433
+ <span class="cline-any cline-yes">15x</span>
1434
+ <span class="cline-any cline-yes">17x</span>
1435
+ <span class="cline-any cline-yes">1x</span>
1436
+ <span class="cline-any cline-yes">1x</span>
1437
+ <span class="cline-any cline-yes">1x</span>
1438
+ <span class="cline-any cline-yes">1x</span>
1439
+ <span class="cline-any cline-yes">1x</span>
1440
+ <span class="cline-any cline-yes">1x</span>
1441
+ <span class="cline-any cline-yes">15x</span>
1442
+ <span class="cline-any cline-yes">15x</span>
1443
+ <span class="cline-any cline-yes">15x</span>
1444
+ <span class="cline-any cline-yes">15x</span>
1445
+ <span class="cline-any cline-yes">14x</span>
1446
+ <span class="cline-any cline-yes">15x</span>
1447
+ <span class="cline-any cline-yes">7x</span>
1448
+ <span class="cline-any cline-yes">7x</span>
1449
+ <span class="cline-any cline-yes">7x</span>
1450
+ <span class="cline-any cline-yes">7x</span>
1451
+ <span class="cline-any cline-yes">7x</span>
1452
+ <span class="cline-any cline-yes">7x</span>
1453
+ <span class="cline-any cline-yes">7x</span>
1454
+ <span class="cline-any cline-yes">4x</span>
1455
+ <span class="cline-any cline-yes">4x</span>
1456
+ <span class="cline-any cline-yes">7x</span>
1457
+ <span class="cline-any cline-yes">7x</span>
1458
+ <span class="cline-any cline-yes">7x</span>
1459
+ <span class="cline-any cline-yes">7x</span>
1460
+ <span class="cline-any cline-yes">7x</span>
1461
+ <span class="cline-any cline-yes">7x</span>
1462
+ <span class="cline-any cline-yes">7x</span>
1463
+ <span class="cline-any cline-yes">7x</span>
1464
+ <span class="cline-any cline-yes">7x</span>
1465
+ <span class="cline-any cline-yes">7x</span>
1466
+ <span class="cline-any cline-yes">7x</span>
1467
+ <span class="cline-any cline-yes">7x</span>
1468
+ <span class="cline-any cline-yes">7x</span>
1469
+ <span class="cline-any cline-yes">7x</span>
1470
+ <span class="cline-any cline-yes">7x</span>
1471
+ <span class="cline-any cline-yes">7x</span>
1472
+ <span class="cline-any cline-yes">7x</span>
1473
+ <span class="cline-any cline-yes">7x</span>
1474
+ <span class="cline-any cline-yes">7x</span>
1475
+ <span class="cline-any cline-yes">7x</span>
1476
+ <span class="cline-any cline-yes">7x</span>
1477
+ <span class="cline-any cline-yes">7x</span>
1478
+ <span class="cline-any cline-yes">7x</span>
1479
+ <span class="cline-any cline-yes">7x</span>
1480
+ <span class="cline-any cline-yes">7x</span>
1481
+ <span class="cline-any cline-yes">7x</span>
1482
+ <span class="cline-any cline-yes">7x</span>
1483
+ <span class="cline-any cline-yes">7x</span>
1484
+ <span class="cline-any cline-yes">15x</span>
1485
+ <span class="cline-any cline-yes">1x</span>
1486
+ <span class="cline-any cline-yes">1x</span>
1487
+ <span class="cline-any cline-yes">1x</span>
1488
+ <span class="cline-any cline-yes">1x</span>
1489
+ <span class="cline-any cline-yes">1x</span>
1490
+ <span class="cline-any cline-no">&nbsp;</span>
1491
+ <span class="cline-any cline-no">&nbsp;</span>
1492
+ <span class="cline-any cline-yes">1x</span>
1493
+ <span class="cline-any cline-yes">1x</span>
1494
+ <span class="cline-any cline-yes">1x</span>
1495
+ <span class="cline-any cline-yes">1x</span>
1496
+ <span class="cline-any cline-yes">1x</span>
1497
+ <span class="cline-any cline-yes">15x</span>
1498
+ <span class="cline-any cline-yes">1x</span>
1499
+ <span class="cline-any cline-yes">1x</span>
1500
+ <span class="cline-any cline-yes">1x</span>
1501
+ <span class="cline-any cline-yes">1x</span>
1502
+ <span class="cline-any cline-yes">1x</span>
1503
+ <span class="cline-any cline-yes">3x</span>
1504
+ <span class="cline-any cline-yes">3x</span>
1505
+ <span class="cline-any cline-yes">1x</span>
1506
+ <span class="cline-any cline-yes">1x</span>
1507
+ <span class="cline-any cline-yes">1x</span>
1508
+ <span class="cline-any cline-yes">1x</span>
1509
+ <span class="cline-any cline-yes">1x</span>
1510
+ <span class="cline-any cline-yes">1x</span>
1511
+ <span class="cline-any cline-yes">12x</span>
1512
+ <span class="cline-any cline-yes">12x</span>
1513
+ <span class="cline-any cline-yes">1x</span>
1514
+ <span class="cline-any cline-yes">1x</span>
1515
+ <span class="cline-any cline-yes">1x</span>
1516
+ <span class="cline-any cline-yes">11x</span>
1517
+ <span class="cline-any cline-yes">11x</span>
1518
+ <span class="cline-any cline-yes">11x</span>
1519
+ <span class="cline-any cline-yes">11x</span>
1520
+ <span class="cline-any cline-yes">11x</span>
1521
+ <span class="cline-any cline-yes">11x</span>
1522
+ <span class="cline-any cline-yes">11x</span>
1523
+ <span class="cline-any cline-yes">11x</span>
1524
+ <span class="cline-any cline-yes">11x</span>
1525
+ <span class="cline-any cline-yes">11x</span>
1526
+ <span class="cline-any cline-yes">12x</span>
1527
+ <span class="cline-any cline-yes">1x</span>
1528
+ <span class="cline-any cline-yes">1x</span>
1529
+ <span class="cline-any cline-yes">1x</span>
1530
+ <span class="cline-any cline-yes">1x</span>
1531
+ <span class="cline-any cline-yes">1x</span>
1532
+ <span class="cline-any cline-yes">1x</span>
1533
+ <span class="cline-any cline-yes">11x</span>
1534
+ <span class="cline-any cline-yes">11x</span>
1535
+ <span class="cline-any cline-yes">11x</span>
1536
+ <span class="cline-any cline-yes">11x</span>
1537
+ <span class="cline-any cline-yes">10x</span>
1538
+ <span class="cline-any cline-yes">11x</span>
1539
+ <span class="cline-any cline-yes">6x</span>
1540
+ <span class="cline-any cline-yes">6x</span>
1541
+ <span class="cline-any cline-yes">6x</span>
1542
+ <span class="cline-any cline-yes">6x</span>
1543
+ <span class="cline-any cline-yes">6x</span>
1544
+ <span class="cline-any cline-yes">4x</span>
1545
+ <span class="cline-any cline-yes">4x</span>
1546
+ <span class="cline-any cline-yes">4x</span>
1547
+ <span class="cline-any cline-yes">4x</span>
1548
+ <span class="cline-any cline-yes">4x</span>
1549
+ <span class="cline-any cline-yes">4x</span>
1550
+ <span class="cline-any cline-yes">4x</span>
1551
+ <span class="cline-any cline-yes">4x</span>
1552
+ <span class="cline-any cline-yes">4x</span>
1553
+ <span class="cline-any cline-yes">4x</span>
1554
+ <span class="cline-any cline-yes">4x</span>
1555
+ <span class="cline-any cline-yes">4x</span>
1556
+ <span class="cline-any cline-yes">4x</span>
1557
+ <span class="cline-any cline-yes">4x</span>
1558
+ <span class="cline-any cline-yes">4x</span>
1559
+ <span class="cline-any cline-yes">4x</span>
1560
+ <span class="cline-any cline-yes">4x</span>
1561
+ <span class="cline-any cline-yes">4x</span>
1562
+ <span class="cline-any cline-yes">4x</span>
1563
+ <span class="cline-any cline-yes">4x</span>
1564
+ <span class="cline-any cline-yes">4x</span>
1565
+ <span class="cline-any cline-yes">4x</span>
1566
+ <span class="cline-any cline-yes">4x</span>
1567
+ <span class="cline-any cline-yes">11x</span>
1568
+ <span class="cline-any cline-yes">1x</span>
1569
+ <span class="cline-any cline-yes">1x</span>
1570
+ <span class="cline-any cline-yes">1x</span>
1571
+ <span class="cline-any cline-yes">1x</span>
1572
+ <span class="cline-any cline-yes">1x</span>
1573
+ <span class="cline-any cline-yes">11x</span>
1574
+ <span class="cline-any cline-yes">1x</span>
1575
+ <span class="cline-any cline-yes">1x</span>
1576
+ <span class="cline-any cline-yes">1x</span>
1577
+ <span class="cline-any cline-yes">1x</span>
1578
+ <span class="cline-any cline-yes">1x</span>
1579
+ <span class="cline-any cline-yes">6x</span>
1580
+ <span class="cline-any cline-yes">6x</span>
1581
+ <span class="cline-any cline-yes">1x</span>
1582
+ <span class="cline-any cline-yes">1x</span>
1583
+ <span class="cline-any cline-yes">1x</span>
1584
+ <span class="cline-any cline-yes">1x</span>
1585
+ <span class="cline-any cline-yes">1x</span>
1586
+ <span class="cline-any cline-yes">1x</span>
1587
+ <span class="cline-any cline-yes">33x</span>
1588
+ <span class="cline-any cline-yes">31x</span>
1589
+ <span class="cline-any cline-yes">31x</span>
1590
+ <span class="cline-any cline-yes">31x</span>
1591
+ <span class="cline-any cline-yes">33x</span>
1592
+ <span class="cline-any cline-yes">33x</span>
1593
+ <span class="cline-any cline-yes">33x</span>
1594
+ <span class="cline-any cline-yes">33x</span>
1595
+ <span class="cline-any cline-yes">1x</span>
1596
+ <span class="cline-any cline-yes">1x</span>
1597
+ <span class="cline-any cline-yes">1x</span>
1598
+ <span class="cline-any cline-yes">1x</span>
1599
+ <span class="cline-any cline-yes">1x</span>
1600
+ <span class="cline-any cline-yes">1x</span>
1601
+ <span class="cline-any cline-yes">31x</span>
1602
+ <span class="cline-any cline-yes">31x</span>
1603
+ <span class="cline-any cline-yes">31x</span>
1604
+ <span class="cline-any cline-yes">31x</span>
1605
+ <span class="cline-any cline-yes">31x</span>
1606
+ <span class="cline-any cline-yes">31x</span>
1607
+ <span class="cline-any cline-yes">31x</span>
1608
+ <span class="cline-any cline-yes">23x</span>
1609
+ <span class="cline-any cline-yes">23x</span>
1610
+ <span class="cline-any cline-yes">23x</span>
1611
+ <span class="cline-any cline-yes">23x</span>
1612
+ <span class="cline-any cline-yes">23x</span>
1613
+ <span class="cline-any cline-yes">23x</span>
1614
+ <span class="cline-any cline-yes">23x</span>
1615
+ <span class="cline-any cline-yes">3x</span>
1616
+ <span class="cline-any cline-yes">3x</span>
1617
+ <span class="cline-any cline-yes">3x</span>
1618
+ <span class="cline-any cline-yes">3x</span>
1619
+ <span class="cline-any cline-yes">3x</span>
1620
+ <span class="cline-any cline-yes">3x</span>
1621
+ <span class="cline-any cline-yes">3x</span>
1622
+ <span class="cline-any cline-yes">3x</span>
1623
+ <span class="cline-any cline-yes">20x</span>
1624
+ <span class="cline-any cline-yes">20x</span>
1625
+ <span class="cline-any cline-yes">20x</span>
1626
+ <span class="cline-any cline-yes">20x</span>
1627
+ <span class="cline-any cline-yes">20x</span>
1628
+ <span class="cline-any cline-yes">20x</span>
1629
+ <span class="cline-any cline-yes">20x</span>
1630
+ <span class="cline-any cline-yes">14x</span>
1631
+ <span class="cline-any cline-yes">14x</span>
1632
+ <span class="cline-any cline-yes">14x</span>
1633
+ <span class="cline-any cline-yes">14x</span>
1634
+ <span class="cline-any cline-yes">14x</span>
1635
+ <span class="cline-any cline-yes">14x</span>
1636
+ <span class="cline-any cline-yes">14x</span>
1637
+ <span class="cline-any cline-yes">14x</span>
1638
+ <span class="cline-any cline-yes">20x</span>
1639
+ <span class="cline-any cline-yes">6x</span>
1640
+ <span class="cline-any cline-yes">6x</span>
1641
+ <span class="cline-any cline-yes">6x</span>
1642
+ <span class="cline-any cline-yes">6x</span>
1643
+ <span class="cline-any cline-yes">6x</span>
1644
+ <span class="cline-any cline-yes">6x</span>
1645
+ <span class="cline-any cline-yes">6x</span>
1646
+ <span class="cline-any cline-yes">6x</span>
1647
+ <span class="cline-any cline-yes">20x</span>
1648
+ <span class="cline-any cline-yes">20x</span>
1649
+ <span class="cline-any cline-yes">23x</span>
1650
+ <span class="cline-any cline-yes">31x</span>
1651
+ <span class="cline-any cline-yes">1x</span>
1652
+ <span class="cline-any cline-yes">1x</span>
1653
+ <span class="cline-any cline-yes">1x</span>
1654
+ <span class="cline-any cline-yes">1x</span>
1655
+ <span class="cline-any cline-yes">1x</span>
1656
+ <span class="cline-any cline-yes">1x</span>
1657
+ <span class="cline-any cline-yes">4x</span>
1658
+ <span class="cline-any cline-no">&nbsp;</span>
1659
+ <span class="cline-any cline-no">&nbsp;</span>
1660
+ <span class="cline-any cline-yes">4x</span>
1661
+ <span class="cline-any cline-yes">4x</span>
1662
+ <span class="cline-any cline-yes">4x</span>
1663
+ <span class="cline-any cline-yes">4x</span>
1664
+ <span class="cline-any cline-yes">4x</span>
1665
+ <span class="cline-any cline-yes">4x</span>
1666
+ <span class="cline-any cline-yes">4x</span>
1667
+ <span class="cline-any cline-yes">1x</span>
1668
+ <span class="cline-any cline-yes">1x</span>
1669
+ <span class="cline-any cline-yes">1x</span>
1670
+ <span class="cline-any cline-yes">1x</span>
1671
+ <span class="cline-any cline-yes">3x</span>
1672
+ <span class="cline-any cline-yes">3x</span>
1673
+ <span class="cline-any cline-yes">4x</span>
1674
+ <span class="cline-any cline-yes">4x</span>
1675
+ <span class="cline-any cline-yes">4x</span>
1676
+ <span class="cline-any cline-yes">4x</span>
1677
+ <span class="cline-any cline-yes">4x</span>
1678
+ <span class="cline-any cline-yes">4x</span>
1679
+ <span class="cline-any cline-yes">4x</span>
1680
+ <span class="cline-any cline-yes">4x</span>
1681
+ <span class="cline-any cline-yes">3x</span>
1682
+ <span class="cline-any cline-yes">3x</span>
1683
+ <span class="cline-any cline-yes">3x</span>
1684
+ <span class="cline-any cline-yes">3x</span>
1685
+ <span class="cline-any cline-yes">3x</span>
1686
+ <span class="cline-any cline-yes">3x</span>
1687
+ <span class="cline-any cline-yes">4x</span>
1688
+ <span class="cline-any cline-yes">1x</span>
1689
+ <span class="cline-any cline-yes">1x</span>
1690
+ <span class="cline-any cline-yes">2x</span>
1691
+ <span class="cline-any cline-yes">2x</span>
1692
+ <span class="cline-any cline-yes">2x</span>
1693
+ <span class="cline-any cline-yes">4x</span>
1694
+ <span class="cline-any cline-yes">1x</span>
1695
+ <span class="cline-any cline-yes">1x</span>
1696
+ <span class="cline-any cline-yes">1x</span>
1697
+ <span class="cline-any cline-yes">1x</span>
1698
+ <span class="cline-any cline-yes">1x</span>
1699
+ <span class="cline-any cline-yes">1x</span>
1700
+ <span class="cline-any cline-yes">4x</span>
1701
+ <span class="cline-any cline-yes">1x</span>
1702
+ <span class="cline-any cline-yes">1x</span>
1703
+ <span class="cline-any cline-yes">1x</span>
1704
+ <span class="cline-any cline-yes">1x</span>
1705
+ <span class="cline-any cline-yes">1x</span>
1706
+ <span class="cline-any cline-yes">31x</span>
1707
+ <span class="cline-any cline-yes">31x</span>
1708
+ <span class="cline-any cline-yes">31x</span>
1709
+ <span class="cline-any cline-yes">31x</span>
1710
+ <span class="cline-any cline-yes">31x</span>
1711
+ <span class="cline-any cline-yes">31x</span>
1712
+ <span class="cline-any cline-yes">31x</span>
1713
+ <span class="cline-any cline-yes">31x</span>
1714
+ <span class="cline-any cline-yes">31x</span>
1715
+ <span class="cline-any cline-yes">31x</span>
1716
+ <span class="cline-any cline-yes">31x</span>
1717
+ <span class="cline-any cline-yes">31x</span>
1718
+ <span class="cline-any cline-yes">31x</span>
1719
+ <span class="cline-any cline-yes">1x</span>
1720
+ <span class="cline-any cline-yes">1x</span>
1721
+ <span class="cline-any cline-yes">1x</span>
1722
+ <span class="cline-any cline-yes">8x</span>
1723
+ <span class="cline-any cline-yes">8x</span>
1724
+ <span class="cline-any cline-yes">5x</span>
1725
+ <span class="cline-any cline-yes">5x</span>
1726
+ <span class="cline-any cline-yes">4x</span>
1727
+ <span class="cline-any cline-yes">4x</span>
1728
+ <span class="cline-any cline-yes">4x</span>
1729
+ <span class="cline-any cline-yes">3x</span>
1730
+ <span class="cline-any cline-yes">3x</span>
1731
+ <span class="cline-any cline-yes">3x</span>
1732
+ <span class="cline-any cline-yes">2x</span>
1733
+ <span class="cline-any cline-yes">8x</span>
1734
+ <span class="cline-any cline-yes">8x</span>
1735
+ <span class="cline-any cline-yes">1x</span>
1736
+ <span class="cline-any cline-yes">1x</span>
1737
+ <span class="cline-any cline-yes">8x</span>
1738
+ <span class="cline-any cline-yes">8x</span>
1739
+ <span class="cline-any cline-yes">8x</span>
1740
+ <span class="cline-any cline-yes">8x</span>
1741
+ <span class="cline-any cline-yes">8x</span>
1742
+ <span class="cline-any cline-yes">8x</span>
1743
+ <span class="cline-any cline-yes">1x</span>
1744
+ <span class="cline-any cline-yes">1x</span>
1745
+ <span class="cline-any cline-yes">7x</span>
1746
+ <span class="cline-any cline-yes">7x</span>
1747
+ <span class="cline-any cline-yes">7x</span>
1748
+ <span class="cline-any cline-yes">7x</span>
1749
+ <span class="cline-any cline-yes">7x</span>
1750
+ <span class="cline-any cline-yes">7x</span>
1751
+ <span class="cline-any cline-yes">7x</span>
1752
+ <span class="cline-any cline-yes">8x</span>
1753
+ <span class="cline-any cline-yes">2x</span>
1754
+ <span class="cline-any cline-yes">2x</span>
1755
+ <span class="cline-any cline-yes">8x</span>
1756
+ <span class="cline-any cline-yes">1x</span>
1757
+ <span class="cline-any cline-yes">1x</span>
1758
+ <span class="cline-any cline-yes">8x</span>
1759
+ <span class="cline-any cline-yes">1x</span>
1760
+ <span class="cline-any cline-yes">1x</span>
1761
+ <span class="cline-any cline-yes">7x</span>
1762
+ <span class="cline-any cline-yes">7x</span>
1763
+ <span class="cline-any cline-yes">7x</span>
1764
+ <span class="cline-any cline-yes">6x</span>
1765
+ <span class="cline-any cline-yes">4x</span>
1766
+ <span class="cline-any cline-yes">3x</span>
1767
+ <span class="cline-any cline-yes">2x</span>
1768
+ <span class="cline-any cline-yes">2x</span>
1769
+ <span class="cline-any cline-yes">2x</span>
1770
+ <span class="cline-any cline-yes">1x</span>
1771
+ <span class="cline-any cline-yes">7x</span>
1772
+ <span class="cline-any cline-yes">7x</span>
1773
+ <span class="cline-any cline-yes">1x</span>
1774
+ <span class="cline-any cline-yes">1x</span>
1775
+ <span class="cline-any cline-yes">7x</span>
1776
+ <span class="cline-any cline-yes">7x</span>
1777
+ <span class="cline-any cline-yes">7x</span>
1778
+ <span class="cline-any cline-yes">7x</span>
1779
+ <span class="cline-any cline-yes">2x</span>
1780
+ <span class="cline-any cline-yes">2x</span>
1781
+ <span class="cline-any cline-yes">2x</span>
1782
+ <span class="cline-any cline-yes">2x</span>
1783
+ <span class="cline-any cline-yes">7x</span>
1784
+ <span class="cline-any cline-yes">2x</span>
1785
+ <span class="cline-any cline-yes">2x</span>
1786
+ <span class="cline-any cline-yes">5x</span>
1787
+ <span class="cline-any cline-yes">1x</span>
1788
+ <span class="cline-any cline-yes">1x</span>
1789
+ <span class="cline-any cline-yes">1x</span>
1790
+ <span class="cline-any cline-yes">3x</span>
1791
+ <span class="cline-any cline-yes">2x</span>
1792
+ <span class="cline-any cline-yes">2x</span>
1793
+ <span class="cline-any cline-yes">7x</span>
1794
+ <span class="cline-any cline-yes">1x</span>
1795
+ <span class="cline-any cline-yes">1x</span>
1796
+ <span class="cline-any cline-yes">7x</span>
1797
+ <span class="cline-any cline-yes">7x</span>
1798
+ <span class="cline-any cline-yes">7x</span>
1799
+ <span class="cline-any cline-yes">7x</span>
1800
+ <span class="cline-any cline-yes">7x</span>
1801
+ <span class="cline-any cline-yes">7x</span>
1802
+ <span class="cline-any cline-yes">7x</span>
1803
+ <span class="cline-any cline-no">&nbsp;</span>
1804
+ <span class="cline-any cline-no">&nbsp;</span>
1805
+ <span class="cline-any cline-yes">7x</span>
1806
+ <span class="cline-any cline-yes">7x</span>
1807
+ <span class="cline-any cline-yes">7x</span>
1808
+ <span class="cline-any cline-yes">7x</span>
1809
+ <span class="cline-any cline-yes">7x</span>
1810
+ <span class="cline-any cline-yes">7x</span>
1811
+ <span class="cline-any cline-yes">7x</span>
1812
+ <span class="cline-any cline-yes">7x</span>
1813
+ <span class="cline-any cline-yes">1x</span>
1814
+ <span class="cline-any cline-yes">1x</span>
1815
+ <span class="cline-any cline-yes">17x</span>
1816
+ <span class="cline-any cline-yes">17x</span>
1817
+ <span class="cline-any cline-yes">17x</span>
1818
+ <span class="cline-any cline-yes">17x</span>
1819
+ <span class="cline-any cline-yes">14x</span>
1820
+ <span class="cline-any cline-yes">14x</span>
1821
+ <span class="cline-any cline-yes">3x</span>
1822
+ <span class="cline-any cline-yes">3x</span>
1823
+ <span class="cline-any cline-yes">17x</span>
1824
+ <span class="cline-any cline-yes">1x</span>
1825
+ <span class="cline-any cline-yes">1x</span>
1826
+ <span class="cline-any cline-yes">2x</span>
1827
+ <span class="cline-any cline-yes">2x</span>
1828
+ <span class="cline-any cline-yes">2x</span>
1829
+ <span class="cline-any cline-yes">2x</span>
1830
+ <span class="cline-any cline-yes">2x</span>
1831
+ <span class="cline-any cline-yes">2x</span>
1832
+ <span class="cline-any cline-yes">2x</span>
1833
+ <span class="cline-any cline-yes">2x</span>
1834
+ <span class="cline-any cline-yes">17x</span>
1835
+ <span class="cline-any cline-yes">1x</span>
1836
+ <span class="cline-any cline-yes">1x</span>
1837
+ <span class="cline-any cline-yes">15x</span>
1838
+ <span class="cline-any cline-yes">15x</span>
1839
+ <span class="cline-any cline-yes">15x</span>
1840
+ <span class="cline-any cline-yes">15x</span>
1841
+ <span class="cline-any cline-yes">11x</span>
1842
+ <span class="cline-any cline-yes">11x</span>
1843
+ <span class="cline-any cline-yes">4x</span>
1844
+ <span class="cline-any cline-yes">4x</span>
1845
+ <span class="cline-any cline-yes">4x</span>
1846
+ <span class="cline-any cline-yes">4x</span>
1847
+ <span class="cline-any cline-yes">3x</span>
1848
+ <span class="cline-any cline-yes">1x</span>
1849
+ <span class="cline-any cline-yes">15x</span>
1850
+ <span class="cline-any cline-yes">15x</span>
1851
+ <span class="cline-any cline-yes">15x</span>
1852
+ <span class="cline-any cline-yes">2x</span>
1853
+ <span class="cline-any cline-yes">1x</span>
1854
+ <span class="cline-any cline-yes">15x</span>
1855
+ <span class="cline-any cline-no">&nbsp;</span>
1856
+ <span class="cline-any cline-no">&nbsp;</span>
1857
+ <span class="cline-any cline-yes">3x</span>
1858
+ <span class="cline-any cline-yes">3x</span>
1859
+ <span class="cline-any cline-yes">3x</span>
1860
+ <span class="cline-any cline-yes">3x</span>
1861
+ <span class="cline-any cline-yes">3x</span>
1862
+ <span class="cline-any cline-yes">3x</span>
1863
+ <span class="cline-any cline-yes">3x</span>
1864
+ <span class="cline-any cline-yes">15x</span>
1865
+ <span class="cline-any cline-yes">1x</span>
1866
+ <span class="cline-any cline-yes">1x</span>
1867
+ <span class="cline-any cline-yes">1x</span>
1868
+ <span class="cline-any cline-yes">15x</span>
1869
+ <span class="cline-any cline-yes">2x</span>
1870
+ <span class="cline-any cline-yes">2x</span>
1871
+ <span class="cline-any cline-yes">2x</span>
1872
+ <span class="cline-any cline-yes">15x</span>
1873
+ <span class="cline-any cline-yes">1x</span>
1874
+ <span class="cline-any cline-yes">1x</span>
1875
+ <span class="cline-any cline-yes">15x</span>
1876
+ <span class="cline-any cline-yes">1x</span>
1877
+ <span class="cline-any cline-yes">1x</span>
1878
+ <span class="cline-any cline-yes">12x</span>
1879
+ <span class="cline-any cline-yes">7x</span>
1880
+ <span class="cline-any cline-yes">7x</span>
1881
+ <span class="cline-any cline-yes">5x</span>
1882
+ <span class="cline-any cline-yes">5x</span>
1883
+ <span class="cline-any cline-yes">5x</span>
1884
+ <span class="cline-any cline-yes">5x</span>
1885
+ <span class="cline-any cline-yes">4x</span>
1886
+ <span class="cline-any cline-yes">3x</span>
1887
+ <span class="cline-any cline-yes">2x</span>
1888
+ <span class="cline-any cline-yes">12x</span>
1889
+ <span class="cline-any cline-yes">1x</span>
1890
+ <span class="cline-any cline-yes">1x</span>
1891
+ <span class="cline-any cline-yes">4x</span>
1892
+ <span class="cline-any cline-yes">4x</span>
1893
+ <span class="cline-any cline-yes">4x</span>
1894
+ <span class="cline-any cline-yes">4x</span>
1895
+ <span class="cline-any cline-yes">4x</span>
1896
+ <span class="cline-any cline-yes">4x</span>
1897
+ <span class="cline-any cline-yes">12x</span>
1898
+ <span class="cline-any cline-yes">1x</span>
1899
+ <span class="cline-any cline-yes">12x</span>
1900
+ <span class="cline-any cline-yes">3x</span>
1901
+ <span class="cline-any cline-yes">3x</span>
1902
+ <span class="cline-any cline-yes">4x</span>
1903
+ <span class="cline-any cline-yes">4x</span>
1904
+ <span class="cline-any cline-yes">12x</span>
1905
+ <span class="cline-any cline-yes">1x</span>
1906
+ <span class="cline-any cline-yes">1x</span>
1907
+ <span class="cline-any cline-yes">1x</span>
1908
+ <span class="cline-any cline-yes">1x</span>
1909
+ <span class="cline-any cline-yes">1x</span>
1910
+ <span class="cline-any cline-yes">1x</span>
1911
+ <span class="cline-any cline-yes">1x</span>
1912
+ <span class="cline-any cline-yes">1x</span>
1913
+ <span class="cline-any cline-yes">1x</span>
1914
+ <span class="cline-any cline-yes">1x</span>
1915
+ <span class="cline-any cline-yes">1x</span>
1916
+ <span class="cline-any cline-yes">1x</span>
1917
+ <span class="cline-any cline-yes">1x</span>
1918
+ <span class="cline-any cline-yes">1x</span>
1919
+ <span class="cline-any cline-yes">1x</span>
1920
+ <span class="cline-any cline-yes">1x</span>
1921
+ <span class="cline-any cline-yes">31x</span>
1922
+ <span class="cline-any cline-yes">31x</span>
1923
+ <span class="cline-any cline-yes">31x</span>
1924
+ <span class="cline-any cline-yes">31x</span>
1925
+ <span class="cline-any cline-yes">8x</span>
1926
+ <span class="cline-any cline-yes">8x</span>
1927
+ <span class="cline-any cline-yes">31x</span>
1928
+ <span class="cline-any cline-yes">31x</span>
1929
+ <span class="cline-any cline-yes">31x</span>
1930
+ <span class="cline-any cline-yes">31x</span>
1931
+ <span class="cline-any cline-yes">24x</span>
1932
+ <span class="cline-any cline-yes">8x</span>
1933
+ <span class="cline-any cline-yes">8x</span>
1934
+ <span class="cline-any cline-yes">31x</span>
1935
+ <span class="cline-any cline-yes">7x</span>
1936
+ <span class="cline-any cline-yes">7x</span>
1937
+ <span class="cline-any cline-yes">31x</span>
1938
+ <span class="cline-any cline-yes">31x</span>
1939
+ <span class="cline-any cline-yes">31x</span>
1940
+ <span class="cline-any cline-yes">17x</span>
1941
+ <span class="cline-any cline-yes">17x</span>
1942
+ <span class="cline-any cline-yes">31x</span>
1943
+ <span class="cline-any cline-yes">31x</span>
1944
+ <span class="cline-any cline-yes">31x</span>
1945
+ <span class="cline-any cline-yes">15x</span>
1946
+ <span class="cline-any cline-yes">15x</span>
1947
+ <span class="cline-any cline-yes">31x</span>
1948
+ <span class="cline-any cline-yes">31x</span>
1949
+ <span class="cline-any cline-yes">31x</span>
1950
+ <span class="cline-any cline-yes">12x</span>
1951
+ <span class="cline-any cline-yes">12x</span>
1952
+ <span class="cline-any cline-yes">31x</span>
1953
+ <span class="cline-any cline-yes">31x</span>
1954
+ <span class="cline-any cline-yes">31x</span>
1955
+ <span class="cline-any cline-yes">1x</span>
1956
+ <span class="cline-any cline-yes">1x</span>
1957
+ <span class="cline-any cline-yes">1x</span>
1958
+ <span class="cline-any cline-yes">1x</span>
1959
+ <span class="cline-any cline-yes">1x</span>
1960
+ <span class="cline-any cline-yes">1x</span>
1961
+ <span class="cline-any cline-yes">38x</span>
1962
+ <span class="cline-any cline-yes">38x</span>
1963
+ <span class="cline-any cline-yes">38x</span>
1964
+ <span class="cline-any cline-yes">1x</span>
1965
+ <span class="cline-any cline-yes">1x</span>
1966
+ <span class="cline-any cline-yes">1x</span>
1967
+ <span class="cline-any cline-yes">1x</span>
1968
+ <span class="cline-any cline-yes">1x</span>
1969
+ <span class="cline-any cline-yes">9x</span>
1970
+ <span class="cline-any cline-yes">3x</span>
1971
+ <span class="cline-any cline-yes">3x</span>
1972
+ <span class="cline-any cline-yes">6x</span>
1973
+ <span class="cline-any cline-yes">9x</span>
1974
+ <span class="cline-any cline-yes">1x</span>
1975
+ <span class="cline-any cline-yes">1x</span>
1976
+ <span class="cline-any cline-yes">1x</span>
1977
+ <span class="cline-any cline-yes">1x</span>
1978
+ <span class="cline-any cline-yes">1x</span>
1979
+ <span class="cline-any cline-yes">1x</span>
1980
+ <span class="cline-any cline-yes">1x</span>
1981
+ <span class="cline-any cline-yes">1x</span>
1982
+ <span class="cline-any cline-yes">3x</span>
1983
+ <span class="cline-any cline-yes">3x</span>
1984
+ <span class="cline-any cline-yes">3x</span>
1985
+ <span class="cline-any cline-yes">3x</span>
1986
+ <span class="cline-any cline-yes">1x</span>
1987
+ <span class="cline-any cline-yes">1x</span>
1988
+ <span class="cline-any cline-yes">2x</span>
1989
+ <span class="cline-any cline-yes">2x</span>
1990
+ <span class="cline-any cline-yes">2x</span>
1991
+ <span class="cline-any cline-yes">2x</span>
1992
+ <span class="cline-any cline-yes">2x</span>
1993
+ <span class="cline-any cline-yes">3x</span>
1994
+ <span class="cline-any cline-yes">1x</span>
1995
+ <span class="cline-any cline-yes">1x</span>
1996
+ <span class="cline-any cline-yes">1x</span>
1997
+ <span class="cline-any cline-yes">1x</span>
1998
+ <span class="cline-any cline-yes">1x</span>
1999
+ <span class="cline-any cline-yes">1x</span>
2000
+ <span class="cline-any cline-yes">3x</span>
2001
+ <span class="cline-any cline-yes">1x</span>
2002
+ <span class="cline-any cline-yes">1x</span>
2003
+ <span class="cline-any cline-yes">1x</span>
2004
+ <span class="cline-any cline-yes">1x</span>
2005
+ <span class="cline-any cline-yes">1x</span>
2006
+ <span class="cline-any cline-yes">2x</span>
2007
+ <span class="cline-any cline-yes">2x</span>
2008
+ <span class="cline-any cline-yes">2x</span>
2009
+ <span class="cline-any cline-yes">2x</span>
2010
+ <span class="cline-any cline-yes">2x</span>
2011
+ <span class="cline-any cline-yes">2x</span>
2012
+ <span class="cline-any cline-yes">1x</span>
2013
+ <span class="cline-any cline-yes">1x</span>
2014
+ <span class="cline-any cline-yes">1x</span>
2015
+ <span class="cline-any cline-yes">1x</span>
2016
+ <span class="cline-any cline-yes">1x</span>
2017
+ <span class="cline-any cline-yes">3x</span>
2018
+ <span class="cline-any cline-yes">1x</span>
2019
+ <span class="cline-any cline-yes">1x</span>
2020
+ <span class="cline-any cline-yes">1x</span>
2021
+ <span class="cline-any cline-yes">1x</span>
2022
+ <span class="cline-any cline-yes">1x</span>
2023
+ <span class="cline-any cline-yes">2x</span>
2024
+ <span class="cline-any cline-yes">2x</span>
2025
+ <span class="cline-any cline-yes">3x</span>
2026
+ <span class="cline-any cline-yes">1x</span>
2027
+ <span class="cline-any cline-yes">1x</span>
2028
+ <span class="cline-any cline-yes">1x</span>
2029
+ <span class="cline-any cline-yes">1x</span>
2030
+ <span class="cline-any cline-yes">235x</span>
2031
+ <span class="cline-any cline-yes">4x</span>
2032
+ <span class="cline-any cline-yes">4x</span>
2033
+ <span class="cline-any cline-yes">235x</span>
2034
+ <span class="cline-any cline-yes">1x</span>
2035
+ <span class="cline-any cline-yes">1x</span>
2036
+ <span class="cline-any cline-yes">7x</span>
2037
+ <span class="cline-any cline-yes">1x</span>
2038
+ <span class="cline-any cline-yes">1x</span>
2039
+ <span class="cline-any cline-yes">6x</span>
2040
+ <span class="cline-any cline-yes">7x</span>
2041
+ <span class="cline-any cline-yes">1x</span>
2042
+ <span class="cline-any cline-yes">1x</span>
2043
+ <span class="cline-any cline-yes">5x</span>
2044
+ <span class="cline-any cline-yes">7x</span>
2045
+ <span class="cline-any cline-yes">4x</span>
2046
+ <span class="cline-any cline-yes">4x</span>
2047
+ <span class="cline-any cline-yes">4x</span>
2048
+ <span class="cline-any cline-yes">1x</span>
2049
+ <span class="cline-any cline-yes">1x</span>
2050
+ <span class="cline-any cline-yes">7x</span>
2051
+ <span class="cline-any cline-yes">1x</span>
2052
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">// =============================
2053
+ // SESSION MANAGER
2054
+ // =============================
2055
+ &nbsp;
2056
+ /**
2057
+ * SessionManager for automatic session handling with Refresh Token Pattern
2058
+ * Provides a simple API for managing authentication with automatic persistence
2059
+ */
2060
+ &nbsp;
2061
+ import { CrudifyInstance } from '@nocios/crudify-sdk';
2062
+ import { TokenStorage, TokenData, StorageType } from '../utils/tokenStorage';
2063
+ import { translateErrorCode } from '../utils/errorTranslation';
2064
+ import { authEventBus } from '../utils/authEventBus'; // ✅ PHASE 3
2065
+ import { crossTabSync } from './CrossTabSyncManager'; // ✅ Cross-tab sync
2066
+ import { logger } from '../utils/logger';
2067
+ import { CookieSync } from '../utils/cookieSync'; // Cookie cross-subdomain for files
2068
+ import type { CrudifyTokenData, CrudifyInitResponse } from '../types/crudify-sdk';
2069
+ &nbsp;
2070
+ export type SessionConfig = {
2071
+ storageType?: StorageType;
2072
+ autoRestore?: boolean;
2073
+ enableLogging?: boolean;
2074
+ onSessionExpired?: () =&gt; void;
2075
+ onSessionRestored?: (tokens: TokenData) =&gt; void;
2076
+ onLoginSuccess?: (tokens: TokenData) =&gt; void;
2077
+ onLogout?: () =&gt; void;
2078
+ showNotification?: (message: string, severity?: 'error' | 'info' | 'success' | 'warning') =&gt; void;
2079
+ translateFn?: (key: string) =&gt; string;
2080
+ apiEndpointAdmin?: string;
2081
+ apiKeyEndpointAdmin?: string;
2082
+ publicApiKey?: string;
2083
+ env?: 'dev' | 'stg' | 'api' | 'prod';
2084
+ };
2085
+ &nbsp;
2086
+ /**
2087
+ * Response data from a successful login
2088
+ */
2089
+ export interface LoginResponseData {
2090
+ token: string;
2091
+ refreshToken: string;
2092
+ expiresAt: number;
2093
+ refreshExpiresAt: number;
2094
+ [key: string]: unknown;
2095
+ }
2096
+ &nbsp;
2097
+ export type LoginResult = {
2098
+ success: boolean;
2099
+ tokens?: TokenData;
2100
+ data?: LoginResponseData; // User data when login is successful
2101
+ error?: string;
2102
+ rawResponse?: Record&lt;string, unknown&gt;; // Raw API response for specific error handling
2103
+ };
2104
+ &nbsp;
2105
+ export class SessionManager {
2106
+ private static instance: SessionManager;
2107
+ private config: SessionConfig = {};
2108
+ private initialized = false;
2109
+ private crudifyInitialized = false;
2110
+ // ✅ PHASE 2: User last activity tracker
2111
+ private lastActivityTime: number = 0;
2112
+ // ✅ PHASE 4: Flags to prevent concurrent refreshes
2113
+ private isRefreshingLocally = false;
2114
+ private refreshPromise: Promise&lt;boolean&gt; | null = null;
2115
+ // ✅ PHASE 5: Flags to distinguish active session vs cold start
2116
+ private isSessionActive = false;
2117
+ private isColdStartRestore = false;
2118
+ &nbsp;
2119
+ private constructor() {}
2120
+ &nbsp;
2121
+ public static getInstance(): SessionManager {
2122
+ if (!SessionManager.instance) {
2123
+ SessionManager.instance = new SessionManager();
2124
+ }
2125
+ return SessionManager.instance;
2126
+ }
2127
+ &nbsp;
2128
+ /**
2129
+ * Initialize SessionManager with configuration
2130
+ */
2131
+ public async initialize(config: SessionConfig = {}): Promise&lt;void&gt; {
2132
+ if (this.initialized) {
2133
+ return;
2134
+ }
2135
+ &nbsp;
2136
+ this.config = {
2137
+ storageType: 'localStorage',
2138
+ autoRestore: true,
2139
+ enableLogging: false,
2140
+ env: 'stg',
2141
+ ...config,
2142
+ };
2143
+ &nbsp;
2144
+ TokenStorage.setStorageType(this.config.<span class="branch-0 cbranch-no" title="branch not covered" >storageType || 'localStorage')</span>;
2145
+ &nbsp;
2146
+ // Initialize crudify SDK if publicApiKey is provided
2147
+ if (this.config.publicApiKey &amp;&amp; !this.crudifyInitialized) {
2148
+ await this.ensureCrudifyInitialized();
2149
+ }
2150
+ &nbsp;
2151
+ // Configure token invalidation callback
2152
+ CrudifyInstance.setTokenInvalidationCallback(() =&gt; {
2153
+ this.log('Tokens invalidated by crudify-core');
2154
+ authEventBus.emit('SESSION_EXPIRED', {
2155
+ message: 'Your session has expired. Please log in again.',
2156
+ source: 'crudify-core.clearTokensAndRefreshState',
2157
+ });
2158
+ });
2159
+ &nbsp;
2160
+ // Store admin credentials if provided
2161
+ if (this.config.apiEndpointAdmin &amp;&amp; this.config.apiKeyEndpointAdmin) {
2162
+ const existingTokens = await TokenStorage.getTokens();
2163
+ if (existingTokens) {
2164
+ await TokenStorage.saveTokens({
2165
+ ...existingTokens,
2166
+ apiEndpointAdmin: this.config.apiEndpointAdmin,
2167
+ apiKeyEndpointAdmin: this.config.apiKeyEndpointAdmin,
2168
+ });
2169
+ } else {
2170
+ await TokenStorage.saveTokens({
2171
+ accessToken: '',
2172
+ refreshToken: '',
2173
+ expiresAt: 0,
2174
+ refreshExpiresAt: 0,
2175
+ apiEndpointAdmin: this.config.apiEndpointAdmin,
2176
+ apiKeyEndpointAdmin: this.config.apiKeyEndpointAdmin,
2177
+ });
2178
+ }
2179
+ }
2180
+ &nbsp;
2181
+ if (this.config.autoRestore) {
2182
+ await this.restoreSession();
2183
+ }
2184
+ &nbsp;
2185
+ this.initialized = true;
2186
+ }
2187
+ &nbsp;
2188
+ /**
2189
+ * Login with automatic token persistence
2190
+ */
2191
+ public async login(email: string, password: string): Promise&lt;LoginResult&gt; {
2192
+ try {
2193
+ const response = await CrudifyInstance.login(email, password);
2194
+ &nbsp;
2195
+ if (!response.success) {
2196
+ return {
2197
+ success: false,
2198
+ error: this.formatError(response.errors),
2199
+ rawResponse: response as Record&lt;string, unknown&gt;,
2200
+ };
2201
+ }
2202
+ &nbsp;
2203
+ const existingTokens = await TokenStorage.getTokens();
2204
+ const loginData = response.data as LoginResponseData;
2205
+ &nbsp;
2206
+ const tokens: TokenData = {
2207
+ accessToken: loginData.token,
2208
+ refreshToken: loginData.refreshToken,
2209
+ expiresAt: loginData.expiresAt,
2210
+ refreshExpiresAt: loginData.refreshExpiresAt,
2211
+ apiEndpointAdmin: existingTokens?.apiEndpointAdmin || this.config.apiEndpointAdmin,
2212
+ apiKeyEndpointAdmin: existingTokens?.apiKeyEndpointAdmin || this.config.apiKeyEndpointAdmin,
2213
+ };
2214
+ &nbsp;
2215
+ await TokenStorage.saveTokens(tokens);
2216
+ TokenStorage.markSuccessfulLogin(); // Start grace period to protect against cross-tab events
2217
+ this.lastActivityTime = Date.now();
2218
+ &nbsp;
2219
+ // ✅ PHASE 5: Mark session as active after successful login
2220
+ this.isSessionActive = true;
2221
+ this.isColdStartRestore = false;
2222
+ &nbsp;
2223
+ // Sync token to cross-subdomain cookie for files.nocios.link
2224
+ CookieSync.setCrossSubdomainCookie(tokens.accessToken, tokens.expiresAt, this.config.env);
2225
+ &nbsp;
2226
+ // ✅ Notify other tabs of successful login
2227
+ crossTabSync.notifyLogin();
2228
+ &nbsp;
2229
+ this.config.onLoginSuccess?.(tokens);
2230
+ &nbsp;
2231
+ return {
2232
+ success: true,
2233
+ tokens,
2234
+ data: loginData,
2235
+ };
2236
+ } catch (error: unknown) {
2237
+ logger.error('[SessionManager] Login error', error instanceof Error ? error : { message: String(error) });
2238
+ return {
2239
+ success: false,
2240
+ error: error instanceof Error ? error.message : 'Unknown error',
2241
+ };
2242
+ }
2243
+ }
2244
+ &nbsp;
2245
+ /**
2246
+ * Logout with token cleanup
2247
+ */
2248
+ public async logout(): Promise&lt;void&gt; {
2249
+ // ✅ PHASE 5: Mark session as inactive at the start of logout
2250
+ this.isSessionActive = false;
2251
+ &nbsp;
2252
+ try {
2253
+ this.log('Logging out...');
2254
+ &nbsp;
2255
+ // Emit LOGOUT event BEFORE clearing tokens to notify subscribers
2256
+ // This allows LoginStateProvider to clear searchParams and formData
2257
+ authEventBus.emit('LOGOUT', {
2258
+ message: 'User logged out',
2259
+ source: 'SessionManager.logout',
2260
+ });
2261
+ &nbsp;
2262
+ // Clear cross-subdomain cookie before logout
2263
+ CookieSync.clearCrossSubdomainCookie(this.config.env);
2264
+ &nbsp;
2265
+ // Logout from crudify
2266
+ await CrudifyInstance.logout();
2267
+ &nbsp;
2268
+ // Clear storage
2269
+ await TokenStorage.clearTokens();
2270
+ &nbsp;
2271
+ // ✅ Notify other tabs of logout
2272
+ crossTabSync.notifyLogout();
2273
+ &nbsp;
2274
+ this.log('Logout successful');
2275
+ &nbsp;
2276
+ // Logout callback
2277
+ this.config.onLogout?.();
2278
+ } catch (error) {
2279
+ this.log('Logout error', { error: error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : String(error) }</span>);
2280
+ // Still clear local tokens
2281
+ await TokenStorage.clearTokens();
2282
+ // ✅ Notify logout even on error
2283
+ crossTabSync.notifyLogout();
2284
+ }
2285
+ }
2286
+ &nbsp;
2287
+ /**
2288
+ * ✅ IMPROVED PHASE 5: Restore session from storage with robust validation
2289
+ * Uses silent refresh to avoid showing notifications during cold start
2290
+ */
2291
+ public async restoreSession(): Promise&lt;boolean&gt; {
2292
+ try {
2293
+ // ✅ PHASE 5: Mark that we are in cold start restore
2294
+ this.isColdStartRestore = true;
2295
+ this.log('Attempting to restore session (cold start)...');
2296
+ &nbsp;
2297
+ const savedTokens = await TokenStorage.getTokens();
2298
+ if (!savedTokens) {
2299
+ this.log('No valid tokens found in storage');
2300
+ this.isColdStartRestore = false;
2301
+ return false;
2302
+ }
2303
+ &nbsp;
2304
+ // Validate that the refresh token is not expired
2305
+ if (Date.now() &gt;= savedTokens.refreshExpiresAt) {
2306
+ this.log('Refresh token expired, clearing storage (cold start - no notification)');
2307
+ await TokenStorage.clearTokens();
2308
+ this.isColdStartRestore = false;
2309
+ // ✅ PHASE 5: Do NOT emit SESSION_EXPIRED - the user was simply away for too long
2310
+ return false;
2311
+ }
2312
+ &nbsp;
2313
+ // Configure tokens in crudify
2314
+ CrudifyInstance.setTokens({
2315
+ accessToken: savedTokens.accessToken,
2316
+ refreshToken: savedTokens.refreshToken,
2317
+ expiresAt: savedTokens.expiresAt,
2318
+ refreshExpiresAt: savedTokens.refreshExpiresAt,
2319
+ });
2320
+ &nbsp;
2321
+ // Validate with improved method
2322
+ const tokenInfo = CrudifyInstance.getTokenData();
2323
+ &nbsp;
2324
+ if (tokenInfo.isValid === false) {
2325
+ this.log('Restored access token is invalid or expired');
2326
+ &nbsp;
2327
+ // If access token expired but refresh is valid, attempt silent refresh
2328
+ if (Date.now() &lt; savedTokens.refreshExpiresAt) {
2329
+ this.log('Access token expired but refresh is valid, attempting silent refresh...');
2330
+ // ✅ PHASE 5: Use SILENT refresh for cold start (no notifications)
2331
+ const refreshSuccess = await this.refreshTokensSilent();
2332
+ &nbsp;
2333
+ if (refreshSuccess) {
2334
+ this.log('Session restored successfully via silent token refresh');
2335
+ this.isSessionActive = true; // ✅ Session is now active
2336
+ this.isColdStartRestore = false;
2337
+ const newTokens = await TokenStorage.getTokens();
2338
+ if (newTokens) {
2339
+ this.config.<span class="branch-0 cbranch-no" title="branch not covered" >onSessionRestored?.(newTokens);</span>
2340
+ }
2341
+ return true;
2342
+ }
2343
+ }
2344
+ &nbsp;
2345
+ // If refresh failed, clear everything WITHOUT emitting events
2346
+ this.log('Could not restore session, clearing tokens (cold start - no notification)');
2347
+ await TokenStorage.clearTokens();
2348
+ await CrudifyInstance.logout();
2349
+ this.isColdStartRestore = false;
2350
+ // ✅ PHASE 5: Do NOT call onSessionExpired or show notification
2351
+ return false;
2352
+ }
2353
+ &nbsp;
2354
+ this.log('Session restored successfully');
2355
+ &nbsp;
2356
+ // ✅ PHASE 5: Mark session as active after successful restoration
2357
+ this.isSessionActive = true;
2358
+ this.isColdStartRestore = false;
2359
+ &nbsp;
2360
+ // Update last activity when restoring session
2361
+ this.lastActivityTime = Date.now();
2362
+ &nbsp;
2363
+ // Restoration callback
2364
+ this.config.onSessionRestored?.(savedTokens);
2365
+ &nbsp;
2366
+ return true;
2367
+ } catch (error) {
2368
+ this.log('Session restore error', { error: error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : String(error) }</span>);
2369
+ await TokenStorage.clearTokens(); // Clear corrupted tokens
2370
+ await CrudifyInstance.logout();
2371
+ this.isColdStartRestore = false;
2372
+ // ✅ PHASE 5: Do NOT emit events on error during cold start
2373
+ return false;
2374
+ }
2375
+ }
2376
+ &nbsp;
2377
+ /**
2378
+ * Check if the user is authenticated
2379
+ */
2380
+ public async isAuthenticated(): Promise&lt;boolean&gt; {
2381
+ return CrudifyInstance.isLogin() || (await TokenStorage.hasValidTokens());
2382
+ }
2383
+ &nbsp;
2384
+ /**
2385
+ * Get current token information
2386
+ */
2387
+ public async getTokenInfo() {
2388
+ const crudifyTokens = CrudifyInstance.getTokenData();
2389
+ const storageInfo = await TokenStorage.getExpirationInfo();
2390
+ const savedTokens = await TokenStorage.getTokens();
2391
+ &nbsp;
2392
+ return {
2393
+ isLoggedIn: await this.isAuthenticated(),
2394
+ crudifyTokens,
2395
+ storageInfo,
2396
+ hasValidTokens: await TokenStorage.hasValidTokens(),
2397
+ // Admin API credentials from storage
2398
+ apiEndpointAdmin: savedTokens?.apiEndpointAdmin,
2399
+ apiKeyEndpointAdmin: savedTokens?.apiKeyEndpointAdmin,
2400
+ };
2401
+ }
2402
+ &nbsp;
2403
+ /**
2404
+ * ✅ PHASE 4: Refresh tokens with concurrency protection
2405
+ */
2406
+ public async refreshTokens(): Promise&lt;boolean&gt; {
2407
+ // ✅ PROTECTION 1: If a refresh is already in progress, return the existing promise
2408
+ if (this.isRefreshingLocally &amp;&amp; this.refreshPromise) {
2409
+ this.log('Refresh already in progress, waiting for existing promise...');
2410
+ return this.refreshPromise;
2411
+ }
2412
+ &nbsp;
2413
+ // ✅ PROTECTION 2: Mark as in progress
2414
+ this.isRefreshingLocally = true;
2415
+ &nbsp;
2416
+ // ✅ PROTECTION 3: Create and store the promise
2417
+ this.refreshPromise = this._performRefresh();
2418
+ &nbsp;
2419
+ try {
2420
+ const result = await this.refreshPromise;
2421
+ return result;
2422
+ } finally {
2423
+ // ✅ PROTECTION 4: Clean up state when finished
2424
+ this.isRefreshingLocally = false;
2425
+ this.refreshPromise = null;
2426
+ }
2427
+ }
2428
+ &nbsp;
2429
+ /**
2430
+ * ✅ PHASE 4 + PHASE 5: Private method that performs the actual refresh
2431
+ * Only shows notification if there was an active session (not on cold start)
2432
+ */
2433
+ private async _performRefresh(): Promise&lt;boolean&gt; {
2434
+ try {
2435
+ this.log('Starting token refresh...');
2436
+ &nbsp;
2437
+ const response = await CrudifyInstance.refreshAccessToken();
2438
+ &nbsp;
2439
+ if (!response.success) {
2440
+ this.log('Token refresh failed', { errors: response.errors });
2441
+ &nbsp;
2442
+ // If refresh fails, clear everything
2443
+ await TokenStorage.clearTokens();
2444
+ &nbsp;
2445
+ // ✅ PHASE 5: Only show notification if there was an active session (not on cold start)
2446
+ if (this.isSessionActive &amp;&amp; !this.isColdStartRestore) {
2447
+ this.config.showNotification?.(this.getSessionExpiredMessage(), 'warning');
2448
+ }
2449
+ &nbsp;
2450
+ this.config.onSessionExpired?.();
2451
+ this.isSessionActive = false;
2452
+ return false;
2453
+ }
2454
+ &nbsp;
2455
+ // Update storage with new tokens
2456
+ const refreshData = response.data as LoginResponseData;
2457
+ const newTokens: TokenData = {
2458
+ accessToken: refreshData.token,
2459
+ refreshToken: refreshData.refreshToken,
2460
+ expiresAt: refreshData.expiresAt,
2461
+ refreshExpiresAt: refreshData.refreshExpiresAt,
2462
+ };
2463
+ &nbsp;
2464
+ await TokenStorage.saveTokens(newTokens);
2465
+ this.log('Tokens refreshed and saved successfully');
2466
+ &nbsp;
2467
+ // Update cross-subdomain cookie with new token
2468
+ CookieSync.setCrossSubdomainCookie(newTokens.accessToken, newTokens.expiresAt, this.config.env);
2469
+ &nbsp;
2470
+ // Update last activity when renewing tokens
2471
+ this.lastActivityTime = Date.now();
2472
+ &nbsp;
2473
+ // Notify other tabs of the token refresh
2474
+ crossTabSync.notifyTokenRefreshed();
2475
+ &nbsp;
2476
+ return true;
2477
+ } catch (error) {
2478
+ this.log('Token refresh error', { error: error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : String(error) }</span>);
2479
+ await TokenStorage.clearTokens();
2480
+ &nbsp;
2481
+ // ✅ PHASE 5: Only show notification if there was an active session (not on cold start)
2482
+ if (this.<span class="branch-0 cbranch-no" title="branch not covered" >isSessionActive &amp;&amp; !this.isColdStartRestore) <span class="branch-0 cbranch-no" title="branch not covered" >{</span></span>
2483
+ <span class="cstat-no" title="statement not covered" > this.config.showNotification?.(this.getSessionExpiredMessage(), 'warning');</span>
2484
+ <span class="cstat-no" title="statement not covered" > }</span>
2485
+ &nbsp;
2486
+ this.config.<span class="branch-0 cbranch-no" title="branch not covered" >onSessionExpired?.();</span>
2487
+ this.isSessionActive = false;
2488
+ return false;
2489
+ }
2490
+ }
2491
+ &nbsp;
2492
+ /**
2493
+ * ✅ PHASE 4: Check if a refresh is in progress
2494
+ */
2495
+ public isRefreshing(): boolean {
2496
+ return this.isRefreshingLocally;
2497
+ }
2498
+ &nbsp;
2499
+ /**
2500
+ * ✅ PHASE 5: Refresh tokens silently (no notifications or events)
2501
+ * Used during cold start restore to avoid showing inappropriate messages
2502
+ */
2503
+ public async refreshTokensSilent(): Promise&lt;boolean&gt; {
2504
+ // PROTECTION: If a refresh is already in progress, return the existing promise
2505
+ if (this.isRefreshingLocally &amp;&amp; this.refreshPromise) {
2506
+ this.log('Silent refresh: waiting for existing refresh promise...');
2507
+ return this.refreshPromise;
2508
+ }
2509
+ &nbsp;
2510
+ this.isRefreshingLocally = true;
2511
+ this.refreshPromise = this._performRefreshSilent();
2512
+ &nbsp;
2513
+ try {
2514
+ return await this.refreshPromise;
2515
+ } finally {
2516
+ this.isRefreshingLocally = false;
2517
+ this.refreshPromise = null;
2518
+ }
2519
+ }
2520
+ &nbsp;
2521
+ /**
2522
+ * ✅ PHASE 5: Internal refresh without notifications or SESSION_EXPIRED events
2523
+ * Only used during cold start restore
2524
+ */
2525
+ private async _performRefreshSilent(): Promise&lt;boolean&gt; {
2526
+ try {
2527
+ this.log('Starting silent token refresh (cold start)...');
2528
+ &nbsp;
2529
+ const response = await CrudifyInstance.refreshAccessToken();
2530
+ &nbsp;
2531
+ if (!response.success) {
2532
+ this.log('Silent token refresh failed', { errors: response.errors });
2533
+ await TokenStorage.clearTokens();
2534
+ // ✅ Do NOT emit notification or onSessionExpired - silent cold start
2535
+ return false;
2536
+ }
2537
+ &nbsp;
2538
+ // Update storage with new tokens
2539
+ const refreshData = response.data as LoginResponseData;
2540
+ const newTokens: TokenData = {
2541
+ accessToken: refreshData.token,
2542
+ refreshToken: refreshData.refreshToken,
2543
+ expiresAt: refreshData.expiresAt,
2544
+ refreshExpiresAt: refreshData.refreshExpiresAt,
2545
+ };
2546
+ &nbsp;
2547
+ await TokenStorage.saveTokens(newTokens);
2548
+ this.log('Tokens refreshed silently and saved successfully');
2549
+ &nbsp;
2550
+ // Update cross-subdomain cookie with new token
2551
+ CookieSync.setCrossSubdomainCookie(newTokens.accessToken, newTokens.expiresAt, this.config.env);
2552
+ &nbsp;
2553
+ // Update last activity
2554
+ this.lastActivityTime = Date.now();
2555
+ &nbsp;
2556
+ // Notify other tabs of the token refresh
2557
+ crossTabSync.notifyTokenRefreshed();
2558
+ &nbsp;
2559
+ return true;
2560
+ } catch (error) {
2561
+ this.log('Silent token refresh error', { error: error instanceof Error ? error.<span class="branch-0 cbranch-no" title="branch not covered" >message : String(error) }</span>);
2562
+ await TokenStorage.clearTokens();
2563
+ // ✅ Do NOT emit notification or event - silent cold start
2564
+ return false;
2565
+ }
2566
+ }
2567
+ &nbsp;
2568
+ /**
2569
+ * ✅ PHASE 5: Check if the session is active (user logged in and using the app)
2570
+ */
2571
+ public getIsSessionActive(): boolean {
2572
+ return this.isSessionActive;
2573
+ }
2574
+ &nbsp;
2575
+ /**
2576
+ * ✅ IMPROVED PHASE 3: Configure NON-BLOCKING response interceptor
2577
+ * The interceptor must NOT await, only detect and emit events
2578
+ */
2579
+ public setupResponseInterceptor(): void {
2580
+ CrudifyInstance.setResponseInterceptor(async (response) =&gt; {
2581
+ // NOSONAR - SDK requires returning the response; side effects are handled in handleInterceptedAuthErrors
2582
+ this.handleInterceptedAuthErrors(response);
2583
+ return response;
2584
+ });
2585
+ &nbsp;
2586
+ this.log('Response interceptor configured (non-blocking mode)');
2587
+ }
2588
+ &nbsp;
2589
+ /**
2590
+ * Handle auth error detection and event emission from intercepted responses.
2591
+ * Extracted from setupResponseInterceptor to isolate side-effect logic.
2592
+ */
2593
+ private handleInterceptedAuthErrors(response: unknown): void {
2594
+ // ✅ PHASE 2: Update activity on every call (both successful and failed, indicates usage)
2595
+ this.updateLastActivity();
2596
+ &nbsp;
2597
+ // ✅ PHASE 3.1: Detect authorization errors with improved detection
2598
+ const authError = this.detectAuthorizationError(response);
2599
+ &nbsp;
2600
+ if (authError.isAuthError) {
2601
+ this.log('🚨 Authorization error detected:', {
2602
+ errorType: authError.errorType,
2603
+ shouldLogout: authError.shouldTriggerLogout,
2604
+ });
2605
+ &nbsp;
2606
+ // ✅ CASE 1: Invalid refresh token → Immediate logout
2607
+ if (authError.isRefreshTokenInvalid || authError.isTokenRefreshFailed) {
2608
+ this.log('Refresh token invalid, emitting TOKEN_REFRESH_FAILED event');
2609
+ authEventBus.emit('TOKEN_REFRESH_FAILED', {
2610
+ message: authError.userFriendlyMessage,
2611
+ error: authError.errorDetails,
2612
+ source: 'SessionManager.setupResponseInterceptor',
2613
+ });
2614
+ return;
2615
+ }
2616
+ &nbsp;
2617
+ // ✅ CASE 2: Expired access token → Attempt refresh
2618
+ if (authError.shouldTriggerLogout) {
2619
+ // Note: hasValidTokens is async but we intentionally fire-and-forget
2620
+ // to keep the interceptor non-blocking
2621
+ TokenStorage.hasValidTokens().then((hasValid) =&gt; {
2622
+ if (hasValid &amp;&amp; !authError.isIrrecoverable) {
2623
+ // ❌ DO NOT: await this.refreshTokens()
2624
+ // ✅ DO: Emit event for useSession to handle
2625
+ this.log('Access token expired, emitting TOKEN_EXPIRED event');
2626
+ authEventBus.emit('TOKEN_EXPIRED', {
2627
+ message: 'Access token expired, refresh needed',
2628
+ error: authError.errorDetails,
2629
+ source: 'SessionManager.setupResponseInterceptor',
2630
+ });
2631
+ } else {
2632
+ // ✅ CASE 3: No valid tokens or irrecoverable error
2633
+ this.log('No valid tokens or irrecoverable error, emitting SESSION_EXPIRED event');
2634
+ authEventBus.emit('SESSION_EXPIRED', {
2635
+ message: authError.userFriendlyMessage,
2636
+ error: authError.errorDetails,
2637
+ source: 'SessionManager.setupResponseInterceptor',
2638
+ });
2639
+ }
2640
+ });
2641
+ }
2642
+ }
2643
+ }
2644
+ &nbsp;
2645
+ /**
2646
+ * Ensure crudify SDK is initialized
2647
+ * Thread-safe: multiple calls will wait for the same initialization
2648
+ */
2649
+ private async ensureCrudifyInitialized(): Promise&lt;void&gt; {
2650
+ if (this.crudifyInitialized) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2651
+ <span class="cstat-no" title="statement not covered" > return;</span>
2652
+ <span class="cstat-no" title="statement not covered" > }</span>
2653
+ &nbsp;
2654
+ try {
2655
+ this.log('Initializing crudify SDK...');
2656
+ &nbsp;
2657
+ // Check if already initialized by another service
2658
+ const tokenData = CrudifyInstance.getTokenData() as CrudifyTokenData | null;
2659
+ if (tokenData?.endpoint) {
2660
+ this.log('Crudify already initialized by another service');
2661
+ this.crudifyInitialized = true;
2662
+ return;
2663
+ }
2664
+ &nbsp;
2665
+ // Configure environment
2666
+ const env = this.config.<span class="branch-0 cbranch-no" title="branch not covered" >env || 'stg';</span>
2667
+ CrudifyInstance.config(env);
2668
+ &nbsp;
2669
+ // Initialize with API key
2670
+ const apiKey = this.config.publicApiKey!;
2671
+ const logLevel = this.config.enableLogging ? 'debug' : 'none';
2672
+ &nbsp;
2673
+ const response = (await CrudifyInstance.init(apiKey, logLevel)) as CrudifyInitResponse;
2674
+ &nbsp;
2675
+ // Check if initialization failed (only check for explicit failure)
2676
+ // CrudifyInstance.init() returns:
2677
+ // - { data: {...} } on first successful init
2678
+ // - { apiEndpointAdmin, apiKeyEndpointAdmin } when already initialized
2679
+ // - { success: false, errors: [...] } on error
2680
+ if (response?.success === false &amp;&amp; response?.errors) {
2681
+ throw new Error(`Failed to initialize crudify: ${JSON.stringify(response.errors)}`);
2682
+ }
2683
+ &nbsp;
2684
+ this.crudifyInitialized = true;
2685
+ this.log('Crudify SDK initialized successfully');
2686
+ } catch (error: unknown) {
2687
+ logger.error(
2688
+ '[SessionManager] Failed to initialize crudify',
2689
+ error instanceof Error ? <span class="branch-0 cbranch-no" title="branch not covered" >error : { message: String(error) }</span>
2690
+ );
2691
+ throw error;
2692
+ }
2693
+ }
2694
+ &nbsp;
2695
+ /**
2696
+ * Result type for detectAuthorizationError
2697
+ */
2698
+ private createDefaultAuthErrorResult() {
2699
+ return {
2700
+ isAuthError: false,
2701
+ isRefreshTokenInvalid: false,
2702
+ isTokenRefreshFailed: false,
2703
+ isTokenExpired: false,
2704
+ isUnauthorized: false,
2705
+ isIrrecoverable: false,
2706
+ shouldTriggerLogout: false,
2707
+ errorType: '',
2708
+ errorDetails: null as unknown,
2709
+ userFriendlyMessage: '',
2710
+ };
2711
+ }
2712
+ &nbsp;
2713
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic GraphQL array error structure
2714
+ private isGraphQLArrayAuthEntry(error: any): boolean {
2715
+ return (
2716
+ error.errorType === 'Unauthorized' ||
2717
+ error.message?.includes('Unauthorized') ||
2718
+ error.message?.includes('Not Authorized') ||
2719
+ error.message?.includes('NOT_AUTHORIZED') ||
2720
+ error.message?.includes('Token') ||
2721
+ error.message?.includes('TOKEN') ||
2722
+ error.message?.includes('Authentication') ||
2723
+ error.message?.includes('UNAUTHENTICATED') ||
2724
+ error.extensions?.code === 'UNAUTHENTICATED' ||
2725
+ error.extensions?.code === 'FORBIDDEN'
2726
+ );
2727
+ }
2728
+ &nbsp;
2729
+ private detectByGraphQLArrayErrors(
2730
+ errors: any[],
2731
+ result: ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt;
2732
+ ): void {
2733
+ const authError = errors.find((error: any) =&gt; this.isGraphQLArrayAuthEntry(error));
2734
+ &nbsp;
2735
+ if (!authError) {
2736
+ return;
2737
+ }
2738
+ &nbsp;
2739
+ result.isAuthError = true;
2740
+ result.errorType = 'GraphQL Array';
2741
+ result.errorDetails = authError;
2742
+ result.shouldTriggerLogout = true;
2743
+ result.userFriendlyMessage = 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
2744
+ &nbsp;
2745
+ if (authError.message?.includes('TOKEN') || authError.message?.includes('Token')) {
2746
+ result.isTokenExpired = true;
2747
+ }
2748
+ if (authError.extensions?.code === 'UNAUTHENTICATED') {
2749
+ result.isUnauthorized = true;
2750
+ }
2751
+ }
2752
+ &nbsp;
2753
+ private isGraphQLObjectAuthMessage(message: unknown): message is string {
2754
+ return (
2755
+ typeof message === 'string' &amp;&amp;
2756
+ (message.includes('NOT_AUTHORIZED') ||
2757
+ message.includes('TOKEN_REFRESH_FAILED') ||
2758
+ message.includes('TOKEN_HAS_EXPIRED') ||
2759
+ message.includes('PLEASE_LOGIN') ||
2760
+ message.includes('Unauthorized') ||
2761
+ message.includes('UNAUTHENTICATED') ||
2762
+ message.includes('SESSION_EXPIRED') ||
2763
+ message.includes('INVALID_TOKEN'))
2764
+ );
2765
+ }
2766
+ &nbsp;
2767
+ private classifyGraphQLObjectAuthError(
2768
+ authErrorMessage: string,
2769
+ result: ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt;
2770
+ ): void {
2771
+ if (authErrorMessage.includes('TOKEN_REFRESH_FAILED')) {
2772
+ result.isTokenRefreshFailed = true;
2773
+ result.isRefreshTokenInvalid = true;
2774
+ result.isIrrecoverable = true;
2775
+ result.userFriendlyMessage = 'Tu sesión ha caducado. Por favor, inicia sesión nuevamente.';
2776
+ } else if (authErrorMessage.includes('TOKEN_HAS_EXPIRED') || authErrorMessage.includes('SESSION_EXPIRED')) {
2777
+ result.isTokenExpired = true;
2778
+ result.userFriendlyMessage = 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
2779
+ } else if (authErrorMessage.includes('INVALID_TOKEN')) {
2780
+ result.isTokenExpired = true;
2781
+ result.isIrrecoverable = true;
2782
+ result.userFriendlyMessage = 'Token inválido. Por favor, inicia sesión nuevamente.';
2783
+ } else {
2784
+ result.userFriendlyMessage = 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
2785
+ }
2786
+ }
2787
+ &nbsp;
2788
+ private detectByGraphQLObjectErrors(
2789
+ errors: Record&lt;string, unknown&gt;,
2790
+ result: ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt;
2791
+ ): void {
2792
+ const errorMessages = Object.values(errors).flat();
2793
+ const authErrorMessage = errorMessages.find((msg) =&gt; this.isGraphQLObjectAuthMessage(msg));
2794
+ &nbsp;
2795
+ if (!authErrorMessage || typeof authErrorMessage !== 'string') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2796
+ <span class="cstat-no" title="statement not covered" > return;</span>
2797
+ <span class="cstat-no" title="statement not covered" > }</span>
2798
+ &nbsp;
2799
+ result.isAuthError = true;
2800
+ result.errorType = 'GraphQL Object';
2801
+ result.errorDetails = errors;
2802
+ result.shouldTriggerLogout = true;
2803
+ &nbsp;
2804
+ this.classifyGraphQLObjectAuthError(authErrorMessage, result);
2805
+ }
2806
+ &nbsp;
2807
+ private detectByResponseStatus(
2808
+ response: any,
2809
+ result: ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt;
2810
+ ): void {
2811
+ if (!response.data?.response?.status) {
2812
+ return;
2813
+ }
2814
+ &nbsp;
2815
+ const status = response.data.response.status.toUpperCase();
2816
+ if (status !== 'UNAUTHORIZED' &amp;&amp; status !== 'UNAUTHENTICATED') {
2817
+ return;
2818
+ }
2819
+ &nbsp;
2820
+ result.isAuthError = true;
2821
+ result.errorType = 'Status';
2822
+ result.errorDetails = response.data.response;
2823
+ result.isUnauthorized = true;
2824
+ result.shouldTriggerLogout = true;
2825
+ result.isIrrecoverable = true;
2826
+ result.userFriendlyMessage = 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
2827
+ }
2828
+ &nbsp;
2829
+ private detectByParsedResponseData(
2830
+ response: any,
2831
+ result: ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt;
2832
+ ): void {
2833
+ if (!response.data?.response?.data) {
2834
+ return;
2835
+ }
2836
+ &nbsp;
2837
+ try {
2838
+ const parsedData =
2839
+ typeof response.data.response.data === 'string'
2840
+ ? JSON.parse(response.data.response.data)
2841
+ : response.data.response.data;
2842
+ &nbsp;
2843
+ if (
2844
+ parsedData.error !== 'REFRESH_TOKEN_INVALID' &amp;&amp;
2845
+ parsedData.error !== 'TOKEN_EXPIRED' &amp;&amp;
2846
+ parsedData.error !== 'INVALID_TOKEN'
2847
+ ) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
2848
+ <span class="cstat-no" title="statement not covered" > return;</span>
2849
+ <span class="cstat-no" title="statement not covered" > }</span>
2850
+ &nbsp;
2851
+ result.isAuthError = true;
2852
+ result.errorType = 'Parsed Data';
2853
+ result.errorDetails = parsedData;
2854
+ result.shouldTriggerLogout = true;
2855
+ result.isIrrecoverable = true;
2856
+ &nbsp;
2857
+ if (parsedData.error === 'REFRESH_TOKEN_INVALID') {
2858
+ result.isRefreshTokenInvalid = true;
2859
+ result.isTokenRefreshFailed = true;
2860
+ result.userFriendlyMessage = 'Tu sesión ha caducado. Por favor, inicia sesión nuevamente.';
2861
+ } else {
2862
+ result.isTokenExpired = true;
2863
+ result.userFriendlyMessage = 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
2864
+ }
2865
+ } catch {
2866
+ // If parsing fails, continue
2867
+ }
2868
+ }
2869
+ &nbsp;
2870
+ private detectByErrorCode(response: any, result: ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt;): void {
2871
+ if (!response.errorCode) {
2872
+ return;
2873
+ }
2874
+ &nbsp;
2875
+ const errorCode = String(response.errorCode).toUpperCase();
2876
+ if (
2877
+ errorCode !== 'UNAUTHORIZED' &amp;&amp;
2878
+ errorCode !== 'UNAUTHENTICATED' &amp;&amp;
2879
+ errorCode !== 'TOKEN_EXPIRED' &amp;&amp;
2880
+ errorCode !== 'INVALID_TOKEN'
2881
+ ) {
2882
+ return;
2883
+ }
2884
+ &nbsp;
2885
+ result.isAuthError = true;
2886
+ result.errorType = 'Error Code';
2887
+ result.errorDetails = { errorCode };
2888
+ result.shouldTriggerLogout = true;
2889
+ &nbsp;
2890
+ if (errorCode === 'TOKEN_EXPIRED') {
2891
+ result.isTokenExpired = true;
2892
+ } else {
2893
+ result.isUnauthorized = true;
2894
+ }
2895
+ &nbsp;
2896
+ result.userFriendlyMessage = 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
2897
+ }
2898
+ &nbsp;
2899
+ /**
2900
+ * ✅ PHASE 3.1: Detect authorization errors across all possible formats (improved)
2901
+ *
2902
+ * JUSTIFICATION FOR `any`:
2903
+ * The backend returns responses in 5 incompatible formats:
2904
+ * 1. GraphQL Array: { errors: [{ errorType?, message?, extensions.code? }] }
2905
+ * 2. GraphQL Object: { errors: { fieldName: [messages] } }
2906
+ * 3. REST Status: { data: { response: { status } } }
2907
+ * 4. Parsed JSON: { data: { response: { data: JSON string } } }
2908
+ * 5. Error Code: { errorCode: "CODE" }
2909
+ *
2910
+ * @param response - API response with dynamic structure that varies by error format
2911
+ */
2912
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- 5 incompatible API formats; see JSDoc
2913
+ private detectAuthorizationError(response: any): ReturnType&lt;SessionManager['createDefaultAuthErrorResult']&gt; {
2914
+ const result = this.createDefaultAuthErrorResult();
2915
+ &nbsp;
2916
+ // FORMAT 1: response.errors (GraphQL Array errors)
2917
+ if (response.errors &amp;&amp; Array.isArray(response.errors)) {
2918
+ this.detectByGraphQLArrayErrors(response.errors, result);
2919
+ }
2920
+ &nbsp;
2921
+ // FORMAT 2: response.errors (GraphQL Object errors)
2922
+ if (
2923
+ !result.isAuthError &amp;&amp;
2924
+ response.errors &amp;&amp;
2925
+ typeof response.errors === 'object' &amp;&amp;
2926
+ !Array.isArray(response.errors)
2927
+ ) {
2928
+ this.detectByGraphQLObjectErrors(response.errors as Record&lt;string, unknown&gt;, result);
2929
+ }
2930
+ &nbsp;
2931
+ // FORMAT 3: response.data.response.status
2932
+ if (!result.isAuthError) {
2933
+ this.detectByResponseStatus(response, result);
2934
+ }
2935
+ &nbsp;
2936
+ // FORMAT 4: response.data.response.data (parsed)
2937
+ if (!result.isAuthError) {
2938
+ this.detectByParsedResponseData(response, result);
2939
+ }
2940
+ &nbsp;
2941
+ // FORMAT 5: response.errorCode
2942
+ if (!result.isAuthError) {
2943
+ this.detectByErrorCode(response, result);
2944
+ }
2945
+ &nbsp;
2946
+ return result;
2947
+ }
2948
+ &nbsp;
2949
+ /**
2950
+ * ✅ PHASE 2: Update the user's last activity timestamp
2951
+ * Should be called when the user performs any action (CRUD, navigation, etc.)
2952
+ */
2953
+ public updateLastActivity(): void {
2954
+ this.lastActivityTime = Date.now();
2955
+ this.log('Last activity updated');
2956
+ }
2957
+ &nbsp;
2958
+ /**
2959
+ * ✅ PHASE 2: Get elapsed time since last activity (in milliseconds)
2960
+ */
2961
+ public getTimeSinceLastActivity(): number {
2962
+ if (this.lastActivityTime === 0) {
2963
+ return 0;
2964
+ }
2965
+ return Date.now() - this.lastActivityTime;
2966
+ }
2967
+ &nbsp;
2968
+ /**
2969
+ * ✅ IMPROVED PHASE 3: Simplified inactivity check
2970
+ * Only checks for absolute inactivity timeout
2971
+ * Token renewal is handled in useSession with TTL logic
2972
+ * @returns 'logout' if should log out due to inactivity, 'none' if no action needed
2973
+ */
2974
+ public checkInactivity(): 'logout' | 'none' {
2975
+ const timeSinceActivity = this.getTimeSinceLastActivity();
2976
+ &nbsp;
2977
+ // If no activity has been recorded, do nothing (first load)
2978
+ if (this.lastActivityTime === 0) {
2979
+ return 'none';
2980
+ }
2981
+ &nbsp;
2982
+ // Inactivity timeout constant
2983
+ const INACTIVITY_TIMEOUT = 30 * 60 * 1000; // 30 minutes
2984
+ &nbsp;
2985
+ // If last activity was more than 30 minutes ago → logout
2986
+ if (timeSinceActivity &gt; INACTIVITY_TIMEOUT) {
2987
+ this.log(`Inactivity timeout: ${Math.floor(timeSinceActivity / 60000)} minutes since last activity`);
2988
+ return 'logout';
2989
+ }
2990
+ &nbsp;
2991
+ // Do nothing (token renewal is handled by useSession with TTL logic)
2992
+ return 'none';
2993
+ }
2994
+ &nbsp;
2995
+ /**
2996
+ * Clear session completely
2997
+ */
2998
+ public async clearSession(): Promise&lt;void&gt; {
2999
+ CookieSync.clearCrossSubdomainCookie(this.config.env);
3000
+ await TokenStorage.clearTokens();
3001
+ await CrudifyInstance.logout();
3002
+ this.lastActivityTime = 0; // Reset last activity
3003
+ this.log('Session cleared completely');
3004
+ }
3005
+ &nbsp;
3006
+ /**
3007
+ * Get translated session expired message
3008
+ */
3009
+ private getSessionExpiredMessage(): string {
3010
+ if (this.config.translateFn) {
3011
+ return translateErrorCode('SESSION_EXPIRED', {
3012
+ translateFn: this.config.translateFn,
3013
+ enableDebug: this.config.enableLogging,
3014
+ });
3015
+ }
3016
+ // Fallback if there is no translation function
3017
+ return 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.';
3018
+ }
3019
+ &nbsp;
3020
+ // Private methods
3021
+ &nbsp;
3022
+ private log(message: string, context?: Record&lt;string, unknown&gt;): void {
3023
+ if (this.config.enableLogging) {
3024
+ logger.debug(`[SessionManager] ${message}`, context);
3025
+ }
3026
+ }
3027
+ &nbsp;
3028
+ private formatError(errors: unknown): string {
3029
+ if (!errors) {
3030
+ return 'Unknown error';
3031
+ }
3032
+ &nbsp;
3033
+ if (typeof errors === 'string') {
3034
+ return errors;
3035
+ }
3036
+ &nbsp;
3037
+ if (typeof errors === 'object') {
3038
+ const errorMessages = Object.values(errors as Record&lt;string, unknown&gt;).flat();
3039
+ return errorMessages.map(String).join(', ');
3040
+ }
3041
+ &nbsp;
3042
+ return 'Authentication failed';
3043
+ }
3044
+ }
3045
+ &nbsp;</pre></td></tr></table></pre>
3046
+
3047
+ <div class='push'></div><!-- for sticky footer -->
3048
+ </div><!-- /wrapper -->
3049
+ <div class='footer quiet pad2 space-top1 center small'>
3050
+ Code coverage generated by
3051
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
3052
+ at 2026-02-07T06:55:20.810Z
3053
+ </div>
3054
+ <script src="../prettify.js"></script>
3055
+ <script>
3056
+ window.onload = function () {
3057
+ prettyPrint();
3058
+ };
3059
+ </script>
3060
+ <script src="../sorter.js"></script>
3061
+ <script src="../block-navigation.js"></script>
3062
+ </body>
3063
+ </html>
3064
+