@rebasepro/server-core 0.0.1-canary.4d4fb3e

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 (254) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +40 -0
  3. package/build-errors.txt +52 -0
  4. package/coverage/clover.xml +3739 -0
  5. package/coverage/coverage-final.json +31 -0
  6. package/coverage/lcov-report/base.css +224 -0
  7. package/coverage/lcov-report/block-navigation.js +87 -0
  8. package/coverage/lcov-report/favicon.png +0 -0
  9. package/coverage/lcov-report/index.html +266 -0
  10. package/coverage/lcov-report/prettify.css +1 -0
  11. package/coverage/lcov-report/prettify.js +2 -0
  12. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  13. package/coverage/lcov-report/sorter.js +210 -0
  14. package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +952 -0
  15. package/coverage/lcov-report/src/api/errors.ts.html +472 -0
  16. package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +1069 -0
  17. package/coverage/lcov-report/src/api/graphql/index.html +116 -0
  18. package/coverage/lcov-report/src/api/index.html +176 -0
  19. package/coverage/lcov-report/src/api/openapi-generator.ts.html +565 -0
  20. package/coverage/lcov-report/src/api/rest/api-generator.ts.html +994 -0
  21. package/coverage/lcov-report/src/api/rest/index.html +131 -0
  22. package/coverage/lcov-report/src/api/rest/query-parser.ts.html +550 -0
  23. package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +202 -0
  24. package/coverage/lcov-report/src/api/server.ts.html +823 -0
  25. package/coverage/lcov-report/src/auth/admin-routes.ts.html +973 -0
  26. package/coverage/lcov-report/src/auth/index.html +176 -0
  27. package/coverage/lcov-report/src/auth/jwt.ts.html +574 -0
  28. package/coverage/lcov-report/src/auth/middleware.ts.html +745 -0
  29. package/coverage/lcov-report/src/auth/password.ts.html +310 -0
  30. package/coverage/lcov-report/src/auth/services.ts.html +2074 -0
  31. package/coverage/lcov-report/src/collections/index.html +116 -0
  32. package/coverage/lcov-report/src/collections/loader.ts.html +232 -0
  33. package/coverage/lcov-report/src/db/auth-schema.ts.html +523 -0
  34. package/coverage/lcov-report/src/db/data-transformer.ts.html +1753 -0
  35. package/coverage/lcov-report/src/db/entityService.ts.html +700 -0
  36. package/coverage/lcov-report/src/db/index.html +146 -0
  37. package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +4048 -0
  38. package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +883 -0
  39. package/coverage/lcov-report/src/db/services/RelationService.ts.html +3121 -0
  40. package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +442 -0
  41. package/coverage/lcov-report/src/db/services/index.html +176 -0
  42. package/coverage/lcov-report/src/db/services/index.ts.html +124 -0
  43. package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +1960 -0
  44. package/coverage/lcov-report/src/index.html +116 -0
  45. package/coverage/lcov-report/src/services/driver-registry.ts.html +631 -0
  46. package/coverage/lcov-report/src/services/index.html +131 -0
  47. package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +3025 -0
  48. package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +1189 -0
  49. package/coverage/lcov-report/src/storage/S3StorageController.ts.html +970 -0
  50. package/coverage/lcov-report/src/storage/index.html +161 -0
  51. package/coverage/lcov-report/src/storage/storage-registry.ts.html +646 -0
  52. package/coverage/lcov-report/src/storage/types.ts.html +451 -0
  53. package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +3082 -0
  54. package/coverage/lcov-report/src/utils/index.html +116 -0
  55. package/coverage/lcov.info +7179 -0
  56. package/dist/common/src/collections/CollectionRegistry.d.ts +48 -0
  57. package/dist/common/src/collections/index.d.ts +1 -0
  58. package/dist/common/src/data/buildRebaseData.d.ts +14 -0
  59. package/dist/common/src/index.d.ts +3 -0
  60. package/dist/common/src/util/builders.d.ts +57 -0
  61. package/dist/common/src/util/callbacks.d.ts +6 -0
  62. package/dist/common/src/util/collections.d.ts +11 -0
  63. package/dist/common/src/util/common.d.ts +2 -0
  64. package/dist/common/src/util/conditions.d.ts +26 -0
  65. package/dist/common/src/util/entities.d.ts +36 -0
  66. package/dist/common/src/util/enums.d.ts +3 -0
  67. package/dist/common/src/util/index.d.ts +16 -0
  68. package/dist/common/src/util/navigation_from_path.d.ts +34 -0
  69. package/dist/common/src/util/navigation_utils.d.ts +20 -0
  70. package/dist/common/src/util/parent_references_from_path.d.ts +6 -0
  71. package/dist/common/src/util/paths.d.ts +14 -0
  72. package/dist/common/src/util/permissions.d.ts +5 -0
  73. package/dist/common/src/util/references.d.ts +2 -0
  74. package/dist/common/src/util/relations.d.ts +12 -0
  75. package/dist/common/src/util/resolutions.d.ts +72 -0
  76. package/dist/common/src/util/storage.d.ts +24 -0
  77. package/dist/index-BeMqpmfQ.js +239 -0
  78. package/dist/index-BeMqpmfQ.js.map +1 -0
  79. package/dist/index-bl4J3lNb.js +55823 -0
  80. package/dist/index-bl4J3lNb.js.map +1 -0
  81. package/dist/index.es.js +58 -0
  82. package/dist/index.es.js.map +1 -0
  83. package/dist/index.umd.js +56062 -0
  84. package/dist/index.umd.js.map +1 -0
  85. package/dist/server-core/src/api/ast-schema-editor.d.ts +21 -0
  86. package/dist/server-core/src/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
  87. package/dist/server-core/src/api/errors.d.ts +35 -0
  88. package/dist/server-core/src/api/graphql/graphql-schema-generator.d.ts +35 -0
  89. package/dist/server-core/src/api/graphql/index.d.ts +1 -0
  90. package/dist/server-core/src/api/index.d.ts +9 -0
  91. package/dist/server-core/src/api/openapi-generator.d.ts +2 -0
  92. package/dist/server-core/src/api/rest/api-generator.d.ts +64 -0
  93. package/dist/server-core/src/api/rest/index.d.ts +1 -0
  94. package/dist/server-core/src/api/rest/query-parser.d.ts +9 -0
  95. package/dist/server-core/src/api/schema-editor-routes.d.ts +3 -0
  96. package/dist/server-core/src/api/server.d.ts +40 -0
  97. package/dist/server-core/src/api/types.d.ts +90 -0
  98. package/dist/server-core/src/auth/admin-routes.d.ts +7 -0
  99. package/dist/server-core/src/auth/google-oauth.d.ts +20 -0
  100. package/dist/server-core/src/auth/index.d.ts +12 -0
  101. package/dist/server-core/src/auth/interfaces.d.ts +270 -0
  102. package/dist/server-core/src/auth/jwt.d.ts +42 -0
  103. package/dist/server-core/src/auth/middleware.d.ts +56 -0
  104. package/dist/server-core/src/auth/password.d.ts +22 -0
  105. package/dist/server-core/src/auth/rate-limiter.d.ts +31 -0
  106. package/dist/server-core/src/auth/routes.d.ts +17 -0
  107. package/dist/server-core/src/bootstrappers/index.d.ts +0 -0
  108. package/dist/server-core/src/collections/BackendCollectionRegistry.d.ts +13 -0
  109. package/dist/server-core/src/collections/loader.d.ts +5 -0
  110. package/dist/server-core/src/db/interfaces.d.ts +18 -0
  111. package/dist/server-core/src/email/index.d.ts +6 -0
  112. package/dist/server-core/src/email/smtp-email-service.d.ts +25 -0
  113. package/dist/server-core/src/email/templates.d.ts +33 -0
  114. package/dist/server-core/src/email/types.d.ts +110 -0
  115. package/dist/server-core/src/functions/function-loader.d.ts +17 -0
  116. package/dist/server-core/src/functions/function-routes.d.ts +10 -0
  117. package/dist/server-core/src/functions/index.d.ts +3 -0
  118. package/dist/server-core/src/history/history-routes.d.ts +23 -0
  119. package/dist/server-core/src/history/index.d.ts +1 -0
  120. package/dist/server-core/src/index.d.ts +24 -0
  121. package/dist/server-core/src/init.d.ts +49 -0
  122. package/dist/server-core/src/serve-spa.d.ts +30 -0
  123. package/dist/server-core/src/services/driver-registry.d.ts +78 -0
  124. package/dist/server-core/src/storage/LocalStorageController.d.ts +46 -0
  125. package/dist/server-core/src/storage/S3StorageController.d.ts +36 -0
  126. package/dist/server-core/src/storage/index.d.ts +18 -0
  127. package/dist/server-core/src/storage/routes.d.ts +38 -0
  128. package/dist/server-core/src/storage/storage-registry.d.ts +78 -0
  129. package/dist/server-core/src/storage/types.d.ts +91 -0
  130. package/dist/server-core/src/types/index.d.ts +11 -0
  131. package/dist/server-core/src/utils/logging.d.ts +9 -0
  132. package/dist/server-core/src/utils/sql.d.ts +27 -0
  133. package/dist/types/src/controllers/analytics_controller.d.ts +7 -0
  134. package/dist/types/src/controllers/auth.d.ts +117 -0
  135. package/dist/types/src/controllers/client.d.ts +58 -0
  136. package/dist/types/src/controllers/collection_registry.d.ts +44 -0
  137. package/dist/types/src/controllers/customization_controller.d.ts +54 -0
  138. package/dist/types/src/controllers/data.d.ts +141 -0
  139. package/dist/types/src/controllers/data_driver.d.ts +168 -0
  140. package/dist/types/src/controllers/database_admin.d.ts +11 -0
  141. package/dist/types/src/controllers/dialogs_controller.d.ts +36 -0
  142. package/dist/types/src/controllers/effective_role.d.ts +4 -0
  143. package/dist/types/src/controllers/index.d.ts +17 -0
  144. package/dist/types/src/controllers/local_config_persistence.d.ts +20 -0
  145. package/dist/types/src/controllers/navigation.d.ts +213 -0
  146. package/dist/types/src/controllers/registry.d.ts +51 -0
  147. package/dist/types/src/controllers/side_dialogs_controller.d.ts +67 -0
  148. package/dist/types/src/controllers/side_entity_controller.d.ts +89 -0
  149. package/dist/types/src/controllers/snackbar.d.ts +24 -0
  150. package/dist/types/src/controllers/storage.d.ts +173 -0
  151. package/dist/types/src/index.d.ts +4 -0
  152. package/dist/types/src/rebase_context.d.ts +101 -0
  153. package/dist/types/src/types/backend.d.ts +533 -0
  154. package/dist/types/src/types/builders.d.ts +14 -0
  155. package/dist/types/src/types/chips.d.ts +5 -0
  156. package/dist/types/src/types/collections.d.ts +812 -0
  157. package/dist/types/src/types/data_source.d.ts +64 -0
  158. package/dist/types/src/types/entities.d.ts +145 -0
  159. package/dist/types/src/types/entity_actions.d.ts +98 -0
  160. package/dist/types/src/types/entity_callbacks.d.ts +173 -0
  161. package/dist/types/src/types/entity_link_builder.d.ts +7 -0
  162. package/dist/types/src/types/entity_overrides.d.ts +9 -0
  163. package/dist/types/src/types/entity_views.d.ts +61 -0
  164. package/dist/types/src/types/export_import.d.ts +21 -0
  165. package/dist/types/src/types/index.d.ts +22 -0
  166. package/dist/types/src/types/locales.d.ts +4 -0
  167. package/dist/types/src/types/modify_collections.d.ts +5 -0
  168. package/dist/types/src/types/plugins.d.ts +225 -0
  169. package/dist/types/src/types/properties.d.ts +1091 -0
  170. package/dist/types/src/types/property_config.d.ts +70 -0
  171. package/dist/types/src/types/relations.d.ts +336 -0
  172. package/dist/types/src/types/slots.d.ts +228 -0
  173. package/dist/types/src/types/translations.d.ts +826 -0
  174. package/dist/types/src/types/user_management_delegate.d.ts +120 -0
  175. package/dist/types/src/types/websockets.d.ts +78 -0
  176. package/dist/types/src/users/index.d.ts +2 -0
  177. package/dist/types/src/users/roles.d.ts +22 -0
  178. package/dist/types/src/users/user.d.ts +46 -0
  179. package/history_diff.log +385 -0
  180. package/jest.config.cjs +16 -0
  181. package/package.json +86 -0
  182. package/scratch.ts +8 -0
  183. package/src/api/ast-schema-editor.ts +289 -0
  184. package/src/api/collections_for_test/callbacks_test_collection.ts +57 -0
  185. package/src/api/errors.ts +155 -0
  186. package/src/api/graphql/graphql-schema-generator.ts +334 -0
  187. package/src/api/graphql/index.ts +2 -0
  188. package/src/api/index.ts +11 -0
  189. package/src/api/openapi-generator.ts +160 -0
  190. package/src/api/rest/api-generator.ts +466 -0
  191. package/src/api/rest/index.ts +2 -0
  192. package/src/api/rest/query-parser.ts +155 -0
  193. package/src/api/schema-editor-routes.ts +39 -0
  194. package/src/api/server.ts +245 -0
  195. package/src/api/types.ts +90 -0
  196. package/src/auth/admin-routes.ts +488 -0
  197. package/src/auth/google-oauth.ts +60 -0
  198. package/src/auth/index.ts +21 -0
  199. package/src/auth/interfaces.ts +316 -0
  200. package/src/auth/jwt.ts +164 -0
  201. package/src/auth/middleware.ts +235 -0
  202. package/src/auth/password.ts +75 -0
  203. package/src/auth/rate-limiter.ts +129 -0
  204. package/src/auth/routes.ts +730 -0
  205. package/src/bootstrappers/index.ts +1 -0
  206. package/src/collections/BackendCollectionRegistry.ts +20 -0
  207. package/src/collections/loader.ts +49 -0
  208. package/src/db/interfaces.ts +60 -0
  209. package/src/email/index.ts +17 -0
  210. package/src/email/smtp-email-service.ts +88 -0
  211. package/src/email/templates.ts +301 -0
  212. package/src/email/types.ts +112 -0
  213. package/src/functions/function-loader.ts +91 -0
  214. package/src/functions/function-routes.ts +31 -0
  215. package/src/functions/index.ts +3 -0
  216. package/src/history/history-routes.ts +128 -0
  217. package/src/history/index.ts +2 -0
  218. package/src/index.ts +56 -0
  219. package/src/init.ts +309 -0
  220. package/src/serve-spa.ts +81 -0
  221. package/src/services/driver-registry.ts +182 -0
  222. package/src/storage/LocalStorageController.ts +368 -0
  223. package/src/storage/S3StorageController.ts +295 -0
  224. package/src/storage/index.ts +32 -0
  225. package/src/storage/routes.ts +247 -0
  226. package/src/storage/storage-registry.ts +187 -0
  227. package/src/storage/types.ts +122 -0
  228. package/src/types/index.ts +27 -0
  229. package/src/utils/logging.ts +35 -0
  230. package/src/utils/sql.ts +38 -0
  231. package/test/admin-routes.test.ts +591 -0
  232. package/test/api-generator.test.ts +458 -0
  233. package/test/ast-schema-editor.test.ts +61 -0
  234. package/test/auth-middleware-hono.test.ts +321 -0
  235. package/test/auth-routes.test.ts +868 -0
  236. package/test/driver-registry.test.ts +280 -0
  237. package/test/errors-hono.test.ts +133 -0
  238. package/test/errors.test.ts +150 -0
  239. package/test/jwt-security.test.ts +173 -0
  240. package/test/jwt.test.ts +311 -0
  241. package/test/middleware.test.ts +295 -0
  242. package/test/password.test.ts +165 -0
  243. package/test/query-parser.test.ts +258 -0
  244. package/test/rate-limiter.test.ts +102 -0
  245. package/test/storage-local.test.ts +278 -0
  246. package/test/storage-registry.test.ts +280 -0
  247. package/test/storage-routes.test.ts +218 -0
  248. package/test/storage-s3.test.ts +301 -0
  249. package/test-ast.ts +28 -0
  250. package/test_output.txt +1133 -0
  251. package/tsconfig.json +49 -0
  252. package/tsconfig.prod.json +20 -0
  253. package/vite.config.ts +78 -0
  254. package/vite.config.ts.timestamp-1775065397568-8a853255edf6e.mjs +46 -0
@@ -0,0 +1,3121 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/db/services/RelationService.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">src/db/services</a> RelationService.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">1.71% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>8/467</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/233</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">3.22% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>1/31</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">1.56% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>7/446</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 low'></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>
1060
+ <a name='L995'></a><a href='#L995'>995</a>
1061
+ <a name='L996'></a><a href='#L996'>996</a>
1062
+ <a name='L997'></a><a href='#L997'>997</a>
1063
+ <a name='L998'></a><a href='#L998'>998</a>
1064
+ <a name='L999'></a><a href='#L999'>999</a>
1065
+ <a name='L1000'></a><a href='#L1000'>1000</a>
1066
+ <a name='L1001'></a><a href='#L1001'>1001</a>
1067
+ <a name='L1002'></a><a href='#L1002'>1002</a>
1068
+ <a name='L1003'></a><a href='#L1003'>1003</a>
1069
+ <a name='L1004'></a><a href='#L1004'>1004</a>
1070
+ <a name='L1005'></a><a href='#L1005'>1005</a>
1071
+ <a name='L1006'></a><a href='#L1006'>1006</a>
1072
+ <a name='L1007'></a><a href='#L1007'>1007</a>
1073
+ <a name='L1008'></a><a href='#L1008'>1008</a>
1074
+ <a name='L1009'></a><a href='#L1009'>1009</a>
1075
+ <a name='L1010'></a><a href='#L1010'>1010</a>
1076
+ <a name='L1011'></a><a href='#L1011'>1011</a>
1077
+ <a name='L1012'></a><a href='#L1012'>1012</a>
1078
+ <a name='L1013'></a><a href='#L1013'>1013</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">3x</span>
1079
+ <span class="cline-any cline-neutral">&nbsp;</span>
1080
+ <span class="cline-any cline-neutral">&nbsp;</span>
1081
+ <span class="cline-any cline-neutral">&nbsp;</span>
1082
+ <span class="cline-any cline-yes">3x</span>
1083
+ <span class="cline-any cline-yes">3x</span>
1084
+ <span class="cline-any cline-yes">3x</span>
1085
+ <span class="cline-any cline-neutral">&nbsp;</span>
1086
+ <span class="cline-any cline-neutral">&nbsp;</span>
1087
+ <span class="cline-any cline-neutral">&nbsp;</span>
1088
+ <span class="cline-any cline-neutral">&nbsp;</span>
1089
+ <span class="cline-any cline-neutral">&nbsp;</span>
1090
+ <span class="cline-any cline-neutral">&nbsp;</span>
1091
+ <span class="cline-any cline-yes">3x</span>
1092
+ <span class="cline-any cline-neutral">&nbsp;</span>
1093
+ <span class="cline-any cline-neutral">&nbsp;</span>
1094
+ <span class="cline-any cline-neutral">&nbsp;</span>
1095
+ <span class="cline-any cline-neutral">&nbsp;</span>
1096
+ <span class="cline-any cline-neutral">&nbsp;</span>
1097
+ <span class="cline-any cline-neutral">&nbsp;</span>
1098
+ <span class="cline-any cline-yes">3x</span>
1099
+ <span class="cline-any cline-yes">219x</span>
1100
+ <span class="cline-any cline-neutral">&nbsp;</span>
1101
+ <span class="cline-any cline-neutral">&nbsp;</span>
1102
+ <span class="cline-any cline-neutral">&nbsp;</span>
1103
+ <span class="cline-any cline-neutral">&nbsp;</span>
1104
+ <span class="cline-any cline-neutral">&nbsp;</span>
1105
+ <span class="cline-any cline-neutral">&nbsp;</span>
1106
+ <span class="cline-any cline-neutral">&nbsp;</span>
1107
+ <span class="cline-any cline-neutral">&nbsp;</span>
1108
+ <span class="cline-any cline-neutral">&nbsp;</span>
1109
+ <span class="cline-any cline-neutral">&nbsp;</span>
1110
+ <span class="cline-any cline-neutral">&nbsp;</span>
1111
+ <span class="cline-any cline-neutral">&nbsp;</span>
1112
+ <span class="cline-any cline-neutral">&nbsp;</span>
1113
+ <span class="cline-any cline-neutral">&nbsp;</span>
1114
+ <span class="cline-any cline-neutral">&nbsp;</span>
1115
+ <span class="cline-any cline-neutral">&nbsp;</span>
1116
+ <span class="cline-any cline-neutral">&nbsp;</span>
1117
+ <span class="cline-any cline-neutral">&nbsp;</span>
1118
+ <span class="cline-any cline-no">&nbsp;</span>
1119
+ <span class="cline-any cline-no">&nbsp;</span>
1120
+ <span class="cline-any cline-no">&nbsp;</span>
1121
+ <span class="cline-any cline-neutral">&nbsp;</span>
1122
+ <span class="cline-any cline-no">&nbsp;</span>
1123
+ <span class="cline-any cline-no">&nbsp;</span>
1124
+ <span class="cline-any cline-neutral">&nbsp;</span>
1125
+ <span class="cline-any cline-neutral">&nbsp;</span>
1126
+ <span class="cline-any cline-no">&nbsp;</span>
1127
+ <span class="cline-any cline-neutral">&nbsp;</span>
1128
+ <span class="cline-any cline-neutral">&nbsp;</span>
1129
+ <span class="cline-any cline-neutral">&nbsp;</span>
1130
+ <span class="cline-any cline-neutral">&nbsp;</span>
1131
+ <span class="cline-any cline-neutral">&nbsp;</span>
1132
+ <span class="cline-any cline-neutral">&nbsp;</span>
1133
+ <span class="cline-any cline-neutral">&nbsp;</span>
1134
+ <span class="cline-any cline-neutral">&nbsp;</span>
1135
+ <span class="cline-any cline-neutral">&nbsp;</span>
1136
+ <span class="cline-any cline-neutral">&nbsp;</span>
1137
+ <span class="cline-any cline-neutral">&nbsp;</span>
1138
+ <span class="cline-any cline-neutral">&nbsp;</span>
1139
+ <span class="cline-any cline-neutral">&nbsp;</span>
1140
+ <span class="cline-any cline-neutral">&nbsp;</span>
1141
+ <span class="cline-any cline-neutral">&nbsp;</span>
1142
+ <span class="cline-any cline-neutral">&nbsp;</span>
1143
+ <span class="cline-any cline-neutral">&nbsp;</span>
1144
+ <span class="cline-any cline-neutral">&nbsp;</span>
1145
+ <span class="cline-any cline-neutral">&nbsp;</span>
1146
+ <span class="cline-any cline-no">&nbsp;</span>
1147
+ <span class="cline-any cline-no">&nbsp;</span>
1148
+ <span class="cline-any cline-no">&nbsp;</span>
1149
+ <span class="cline-any cline-no">&nbsp;</span>
1150
+ <span class="cline-any cline-neutral">&nbsp;</span>
1151
+ <span class="cline-any cline-no">&nbsp;</span>
1152
+ <span class="cline-any cline-no">&nbsp;</span>
1153
+ <span class="cline-any cline-no">&nbsp;</span>
1154
+ <span class="cline-any cline-no">&nbsp;</span>
1155
+ <span class="cline-any cline-no">&nbsp;</span>
1156
+ <span class="cline-any cline-no">&nbsp;</span>
1157
+ <span class="cline-any cline-no">&nbsp;</span>
1158
+ <span class="cline-any cline-neutral">&nbsp;</span>
1159
+ <span class="cline-any cline-neutral">&nbsp;</span>
1160
+ <span class="cline-any cline-no">&nbsp;</span>
1161
+ <span class="cline-any cline-no">&nbsp;</span>
1162
+ <span class="cline-any cline-no">&nbsp;</span>
1163
+ <span class="cline-any cline-neutral">&nbsp;</span>
1164
+ <span class="cline-any cline-neutral">&nbsp;</span>
1165
+ <span class="cline-any cline-no">&nbsp;</span>
1166
+ <span class="cline-any cline-no">&nbsp;</span>
1167
+ <span class="cline-any cline-no">&nbsp;</span>
1168
+ <span class="cline-any cline-no">&nbsp;</span>
1169
+ <span class="cline-any cline-neutral">&nbsp;</span>
1170
+ <span class="cline-any cline-neutral">&nbsp;</span>
1171
+ <span class="cline-any cline-no">&nbsp;</span>
1172
+ <span class="cline-any cline-no">&nbsp;</span>
1173
+ <span class="cline-any cline-neutral">&nbsp;</span>
1174
+ <span class="cline-any cline-no">&nbsp;</span>
1175
+ <span class="cline-any cline-no">&nbsp;</span>
1176
+ <span class="cline-any cline-neutral">&nbsp;</span>
1177
+ <span class="cline-any cline-no">&nbsp;</span>
1178
+ <span class="cline-any cline-no">&nbsp;</span>
1179
+ <span class="cline-any cline-neutral">&nbsp;</span>
1180
+ <span class="cline-any cline-no">&nbsp;</span>
1181
+ <span class="cline-any cline-no">&nbsp;</span>
1182
+ <span class="cline-any cline-neutral">&nbsp;</span>
1183
+ <span class="cline-any cline-no">&nbsp;</span>
1184
+ <span class="cline-any cline-no">&nbsp;</span>
1185
+ <span class="cline-any cline-neutral">&nbsp;</span>
1186
+ <span class="cline-any cline-neutral">&nbsp;</span>
1187
+ <span class="cline-any cline-neutral">&nbsp;</span>
1188
+ <span class="cline-any cline-no">&nbsp;</span>
1189
+ <span class="cline-any cline-no">&nbsp;</span>
1190
+ <span class="cline-any cline-neutral">&nbsp;</span>
1191
+ <span class="cline-any cline-neutral">&nbsp;</span>
1192
+ <span class="cline-any cline-neutral">&nbsp;</span>
1193
+ <span class="cline-any cline-no">&nbsp;</span>
1194
+ <span class="cline-any cline-no">&nbsp;</span>
1195
+ <span class="cline-any cline-neutral">&nbsp;</span>
1196
+ <span class="cline-any cline-no">&nbsp;</span>
1197
+ <span class="cline-any cline-no">&nbsp;</span>
1198
+ <span class="cline-any cline-neutral">&nbsp;</span>
1199
+ <span class="cline-any cline-neutral">&nbsp;</span>
1200
+ <span class="cline-any cline-no">&nbsp;</span>
1201
+ <span class="cline-any cline-no">&nbsp;</span>
1202
+ <span class="cline-any cline-neutral">&nbsp;</span>
1203
+ <span class="cline-any cline-neutral">&nbsp;</span>
1204
+ <span class="cline-any cline-no">&nbsp;</span>
1205
+ <span class="cline-any cline-no">&nbsp;</span>
1206
+ <span class="cline-any cline-no">&nbsp;</span>
1207
+ <span class="cline-any cline-no">&nbsp;</span>
1208
+ <span class="cline-any cline-no">&nbsp;</span>
1209
+ <span class="cline-any cline-neutral">&nbsp;</span>
1210
+ <span class="cline-any cline-no">&nbsp;</span>
1211
+ <span class="cline-any cline-neutral">&nbsp;</span>
1212
+ <span class="cline-any cline-neutral">&nbsp;</span>
1213
+ <span class="cline-any cline-neutral">&nbsp;</span>
1214
+ <span class="cline-any cline-neutral">&nbsp;</span>
1215
+ <span class="cline-any cline-neutral">&nbsp;</span>
1216
+ <span class="cline-any cline-neutral">&nbsp;</span>
1217
+ <span class="cline-any cline-no">&nbsp;</span>
1218
+ <span class="cline-any cline-neutral">&nbsp;</span>
1219
+ <span class="cline-any cline-neutral">&nbsp;</span>
1220
+ <span class="cline-any cline-neutral">&nbsp;</span>
1221
+ <span class="cline-any cline-no">&nbsp;</span>
1222
+ <span class="cline-any cline-neutral">&nbsp;</span>
1223
+ <span class="cline-any cline-neutral">&nbsp;</span>
1224
+ <span class="cline-any cline-no">&nbsp;</span>
1225
+ <span class="cline-any cline-neutral">&nbsp;</span>
1226
+ <span class="cline-any cline-neutral">&nbsp;</span>
1227
+ <span class="cline-any cline-no">&nbsp;</span>
1228
+ <span class="cline-any cline-no">&nbsp;</span>
1229
+ <span class="cline-any cline-neutral">&nbsp;</span>
1230
+ <span class="cline-any cline-neutral">&nbsp;</span>
1231
+ <span class="cline-any cline-neutral">&nbsp;</span>
1232
+ <span class="cline-any cline-neutral">&nbsp;</span>
1233
+ <span class="cline-any cline-neutral">&nbsp;</span>
1234
+ <span class="cline-any cline-no">&nbsp;</span>
1235
+ <span class="cline-any cline-neutral">&nbsp;</span>
1236
+ <span class="cline-any cline-no">&nbsp;</span>
1237
+ <span class="cline-any cline-neutral">&nbsp;</span>
1238
+ <span class="cline-any cline-neutral">&nbsp;</span>
1239
+ <span class="cline-any cline-no">&nbsp;</span>
1240
+ <span class="cline-any cline-no">&nbsp;</span>
1241
+ <span class="cline-any cline-no">&nbsp;</span>
1242
+ <span class="cline-any cline-neutral">&nbsp;</span>
1243
+ <span class="cline-any cline-neutral">&nbsp;</span>
1244
+ <span class="cline-any cline-neutral">&nbsp;</span>
1245
+ <span class="cline-any cline-neutral">&nbsp;</span>
1246
+ <span class="cline-any cline-neutral">&nbsp;</span>
1247
+ <span class="cline-any cline-no">&nbsp;</span>
1248
+ <span class="cline-any cline-neutral">&nbsp;</span>
1249
+ <span class="cline-any cline-neutral">&nbsp;</span>
1250
+ <span class="cline-any cline-neutral">&nbsp;</span>
1251
+ <span class="cline-any cline-neutral">&nbsp;</span>
1252
+ <span class="cline-any cline-neutral">&nbsp;</span>
1253
+ <span class="cline-any cline-neutral">&nbsp;</span>
1254
+ <span class="cline-any cline-neutral">&nbsp;</span>
1255
+ <span class="cline-any cline-neutral">&nbsp;</span>
1256
+ <span class="cline-any cline-neutral">&nbsp;</span>
1257
+ <span class="cline-any cline-neutral">&nbsp;</span>
1258
+ <span class="cline-any cline-neutral">&nbsp;</span>
1259
+ <span class="cline-any cline-no">&nbsp;</span>
1260
+ <span class="cline-any cline-no">&nbsp;</span>
1261
+ <span class="cline-any cline-neutral">&nbsp;</span>
1262
+ <span class="cline-any cline-neutral">&nbsp;</span>
1263
+ <span class="cline-any cline-no">&nbsp;</span>
1264
+ <span class="cline-any cline-neutral">&nbsp;</span>
1265
+ <span class="cline-any cline-neutral">&nbsp;</span>
1266
+ <span class="cline-any cline-no">&nbsp;</span>
1267
+ <span class="cline-any cline-no">&nbsp;</span>
1268
+ <span class="cline-any cline-neutral">&nbsp;</span>
1269
+ <span class="cline-any cline-neutral">&nbsp;</span>
1270
+ <span class="cline-any cline-no">&nbsp;</span>
1271
+ <span class="cline-any cline-no">&nbsp;</span>
1272
+ <span class="cline-any cline-no">&nbsp;</span>
1273
+ <span class="cline-any cline-no">&nbsp;</span>
1274
+ <span class="cline-any cline-no">&nbsp;</span>
1275
+ <span class="cline-any cline-neutral">&nbsp;</span>
1276
+ <span class="cline-any cline-no">&nbsp;</span>
1277
+ <span class="cline-any cline-neutral">&nbsp;</span>
1278
+ <span class="cline-any cline-neutral">&nbsp;</span>
1279
+ <span class="cline-any cline-neutral">&nbsp;</span>
1280
+ <span class="cline-any cline-neutral">&nbsp;</span>
1281
+ <span class="cline-any cline-neutral">&nbsp;</span>
1282
+ <span class="cline-any cline-neutral">&nbsp;</span>
1283
+ <span class="cline-any cline-no">&nbsp;</span>
1284
+ <span class="cline-any cline-neutral">&nbsp;</span>
1285
+ <span class="cline-any cline-neutral">&nbsp;</span>
1286
+ <span class="cline-any cline-neutral">&nbsp;</span>
1287
+ <span class="cline-any cline-neutral">&nbsp;</span>
1288
+ <span class="cline-any cline-neutral">&nbsp;</span>
1289
+ <span class="cline-any cline-neutral">&nbsp;</span>
1290
+ <span class="cline-any cline-neutral">&nbsp;</span>
1291
+ <span class="cline-any cline-neutral">&nbsp;</span>
1292
+ <span class="cline-any cline-neutral">&nbsp;</span>
1293
+ <span class="cline-any cline-neutral">&nbsp;</span>
1294
+ <span class="cline-any cline-neutral">&nbsp;</span>
1295
+ <span class="cline-any cline-no">&nbsp;</span>
1296
+ <span class="cline-any cline-no">&nbsp;</span>
1297
+ <span class="cline-any cline-no">&nbsp;</span>
1298
+ <span class="cline-any cline-no">&nbsp;</span>
1299
+ <span class="cline-any cline-neutral">&nbsp;</span>
1300
+ <span class="cline-any cline-no">&nbsp;</span>
1301
+ <span class="cline-any cline-no">&nbsp;</span>
1302
+ <span class="cline-any cline-no">&nbsp;</span>
1303
+ <span class="cline-any cline-no">&nbsp;</span>
1304
+ <span class="cline-any cline-no">&nbsp;</span>
1305
+ <span class="cline-any cline-neutral">&nbsp;</span>
1306
+ <span class="cline-any cline-no">&nbsp;</span>
1307
+ <span class="cline-any cline-no">&nbsp;</span>
1308
+ <span class="cline-any cline-no">&nbsp;</span>
1309
+ <span class="cline-any cline-no">&nbsp;</span>
1310
+ <span class="cline-any cline-no">&nbsp;</span>
1311
+ <span class="cline-any cline-no">&nbsp;</span>
1312
+ <span class="cline-any cline-no">&nbsp;</span>
1313
+ <span class="cline-any cline-neutral">&nbsp;</span>
1314
+ <span class="cline-any cline-neutral">&nbsp;</span>
1315
+ <span class="cline-any cline-no">&nbsp;</span>
1316
+ <span class="cline-any cline-neutral">&nbsp;</span>
1317
+ <span class="cline-any cline-neutral">&nbsp;</span>
1318
+ <span class="cline-any cline-no">&nbsp;</span>
1319
+ <span class="cline-any cline-neutral">&nbsp;</span>
1320
+ <span class="cline-any cline-neutral">&nbsp;</span>
1321
+ <span class="cline-any cline-no">&nbsp;</span>
1322
+ <span class="cline-any cline-neutral">&nbsp;</span>
1323
+ <span class="cline-any cline-neutral">&nbsp;</span>
1324
+ <span class="cline-any cline-neutral">&nbsp;</span>
1325
+ <span class="cline-any cline-neutral">&nbsp;</span>
1326
+ <span class="cline-any cline-neutral">&nbsp;</span>
1327
+ <span class="cline-any cline-neutral">&nbsp;</span>
1328
+ <span class="cline-any cline-neutral">&nbsp;</span>
1329
+ <span class="cline-any cline-neutral">&nbsp;</span>
1330
+ <span class="cline-any cline-neutral">&nbsp;</span>
1331
+ <span class="cline-any cline-neutral">&nbsp;</span>
1332
+ <span class="cline-any cline-neutral">&nbsp;</span>
1333
+ <span class="cline-any cline-no">&nbsp;</span>
1334
+ <span class="cline-any cline-no">&nbsp;</span>
1335
+ <span class="cline-any cline-neutral">&nbsp;</span>
1336
+ <span class="cline-any cline-neutral">&nbsp;</span>
1337
+ <span class="cline-any cline-neutral">&nbsp;</span>
1338
+ <span class="cline-any cline-neutral">&nbsp;</span>
1339
+ <span class="cline-any cline-neutral">&nbsp;</span>
1340
+ <span class="cline-any cline-neutral">&nbsp;</span>
1341
+ <span class="cline-any cline-neutral">&nbsp;</span>
1342
+ <span class="cline-any cline-neutral">&nbsp;</span>
1343
+ <span class="cline-any cline-neutral">&nbsp;</span>
1344
+ <span class="cline-any cline-neutral">&nbsp;</span>
1345
+ <span class="cline-any cline-neutral">&nbsp;</span>
1346
+ <span class="cline-any cline-no">&nbsp;</span>
1347
+ <span class="cline-any cline-neutral">&nbsp;</span>
1348
+ <span class="cline-any cline-no">&nbsp;</span>
1349
+ <span class="cline-any cline-no">&nbsp;</span>
1350
+ <span class="cline-any cline-no">&nbsp;</span>
1351
+ <span class="cline-any cline-no">&nbsp;</span>
1352
+ <span class="cline-any cline-no">&nbsp;</span>
1353
+ <span class="cline-any cline-no">&nbsp;</span>
1354
+ <span class="cline-any cline-neutral">&nbsp;</span>
1355
+ <span class="cline-any cline-no">&nbsp;</span>
1356
+ <span class="cline-any cline-no">&nbsp;</span>
1357
+ <span class="cline-any cline-no">&nbsp;</span>
1358
+ <span class="cline-any cline-no">&nbsp;</span>
1359
+ <span class="cline-any cline-no">&nbsp;</span>
1360
+ <span class="cline-any cline-neutral">&nbsp;</span>
1361
+ <span class="cline-any cline-neutral">&nbsp;</span>
1362
+ <span class="cline-any cline-no">&nbsp;</span>
1363
+ <span class="cline-any cline-neutral">&nbsp;</span>
1364
+ <span class="cline-any cline-neutral">&nbsp;</span>
1365
+ <span class="cline-any cline-no">&nbsp;</span>
1366
+ <span class="cline-any cline-no">&nbsp;</span>
1367
+ <span class="cline-any cline-no">&nbsp;</span>
1368
+ <span class="cline-any cline-neutral">&nbsp;</span>
1369
+ <span class="cline-any cline-neutral">&nbsp;</span>
1370
+ <span class="cline-any cline-no">&nbsp;</span>
1371
+ <span class="cline-any cline-no">&nbsp;</span>
1372
+ <span class="cline-any cline-no">&nbsp;</span>
1373
+ <span class="cline-any cline-no">&nbsp;</span>
1374
+ <span class="cline-any cline-neutral">&nbsp;</span>
1375
+ <span class="cline-any cline-neutral">&nbsp;</span>
1376
+ <span class="cline-any cline-no">&nbsp;</span>
1377
+ <span class="cline-any cline-no">&nbsp;</span>
1378
+ <span class="cline-any cline-neutral">&nbsp;</span>
1379
+ <span class="cline-any cline-no">&nbsp;</span>
1380
+ <span class="cline-any cline-no">&nbsp;</span>
1381
+ <span class="cline-any cline-neutral">&nbsp;</span>
1382
+ <span class="cline-any cline-no">&nbsp;</span>
1383
+ <span class="cline-any cline-no">&nbsp;</span>
1384
+ <span class="cline-any cline-neutral">&nbsp;</span>
1385
+ <span class="cline-any cline-no">&nbsp;</span>
1386
+ <span class="cline-any cline-no">&nbsp;</span>
1387
+ <span class="cline-any cline-neutral">&nbsp;</span>
1388
+ <span class="cline-any cline-no">&nbsp;</span>
1389
+ <span class="cline-any cline-no">&nbsp;</span>
1390
+ <span class="cline-any cline-neutral">&nbsp;</span>
1391
+ <span class="cline-any cline-neutral">&nbsp;</span>
1392
+ <span class="cline-any cline-neutral">&nbsp;</span>
1393
+ <span class="cline-any cline-no">&nbsp;</span>
1394
+ <span class="cline-any cline-no">&nbsp;</span>
1395
+ <span class="cline-any cline-neutral">&nbsp;</span>
1396
+ <span class="cline-any cline-neutral">&nbsp;</span>
1397
+ <span class="cline-any cline-neutral">&nbsp;</span>
1398
+ <span class="cline-any cline-no">&nbsp;</span>
1399
+ <span class="cline-any cline-no">&nbsp;</span>
1400
+ <span class="cline-any cline-neutral">&nbsp;</span>
1401
+ <span class="cline-any cline-no">&nbsp;</span>
1402
+ <span class="cline-any cline-no">&nbsp;</span>
1403
+ <span class="cline-any cline-no">&nbsp;</span>
1404
+ <span class="cline-any cline-neutral">&nbsp;</span>
1405
+ <span class="cline-any cline-neutral">&nbsp;</span>
1406
+ <span class="cline-any cline-no">&nbsp;</span>
1407
+ <span class="cline-any cline-no">&nbsp;</span>
1408
+ <span class="cline-any cline-no">&nbsp;</span>
1409
+ <span class="cline-any cline-no">&nbsp;</span>
1410
+ <span class="cline-any cline-neutral">&nbsp;</span>
1411
+ <span class="cline-any cline-no">&nbsp;</span>
1412
+ <span class="cline-any cline-neutral">&nbsp;</span>
1413
+ <span class="cline-any cline-neutral">&nbsp;</span>
1414
+ <span class="cline-any cline-neutral">&nbsp;</span>
1415
+ <span class="cline-any cline-neutral">&nbsp;</span>
1416
+ <span class="cline-any cline-neutral">&nbsp;</span>
1417
+ <span class="cline-any cline-neutral">&nbsp;</span>
1418
+ <span class="cline-any cline-no">&nbsp;</span>
1419
+ <span class="cline-any cline-neutral">&nbsp;</span>
1420
+ <span class="cline-any cline-neutral">&nbsp;</span>
1421
+ <span class="cline-any cline-neutral">&nbsp;</span>
1422
+ <span class="cline-any cline-no">&nbsp;</span>
1423
+ <span class="cline-any cline-neutral">&nbsp;</span>
1424
+ <span class="cline-any cline-neutral">&nbsp;</span>
1425
+ <span class="cline-any cline-neutral">&nbsp;</span>
1426
+ <span class="cline-any cline-no">&nbsp;</span>
1427
+ <span class="cline-any cline-neutral">&nbsp;</span>
1428
+ <span class="cline-any cline-neutral">&nbsp;</span>
1429
+ <span class="cline-any cline-neutral">&nbsp;</span>
1430
+ <span class="cline-any cline-neutral">&nbsp;</span>
1431
+ <span class="cline-any cline-neutral">&nbsp;</span>
1432
+ <span class="cline-any cline-neutral">&nbsp;</span>
1433
+ <span class="cline-any cline-neutral">&nbsp;</span>
1434
+ <span class="cline-any cline-neutral">&nbsp;</span>
1435
+ <span class="cline-any cline-neutral">&nbsp;</span>
1436
+ <span class="cline-any cline-neutral">&nbsp;</span>
1437
+ <span class="cline-any cline-neutral">&nbsp;</span>
1438
+ <span class="cline-any cline-no">&nbsp;</span>
1439
+ <span class="cline-any cline-no">&nbsp;</span>
1440
+ <span class="cline-any cline-neutral">&nbsp;</span>
1441
+ <span class="cline-any cline-neutral">&nbsp;</span>
1442
+ <span class="cline-any cline-no">&nbsp;</span>
1443
+ <span class="cline-any cline-no">&nbsp;</span>
1444
+ <span class="cline-any cline-neutral">&nbsp;</span>
1445
+ <span class="cline-any cline-neutral">&nbsp;</span>
1446
+ <span class="cline-any cline-neutral">&nbsp;</span>
1447
+ <span class="cline-any cline-neutral">&nbsp;</span>
1448
+ <span class="cline-any cline-no">&nbsp;</span>
1449
+ <span class="cline-any cline-no">&nbsp;</span>
1450
+ <span class="cline-any cline-no">&nbsp;</span>
1451
+ <span class="cline-any cline-no">&nbsp;</span>
1452
+ <span class="cline-any cline-no">&nbsp;</span>
1453
+ <span class="cline-any cline-no">&nbsp;</span>
1454
+ <span class="cline-any cline-no">&nbsp;</span>
1455
+ <span class="cline-any cline-no">&nbsp;</span>
1456
+ <span class="cline-any cline-no">&nbsp;</span>
1457
+ <span class="cline-any cline-no">&nbsp;</span>
1458
+ <span class="cline-any cline-neutral">&nbsp;</span>
1459
+ <span class="cline-any cline-neutral">&nbsp;</span>
1460
+ <span class="cline-any cline-neutral">&nbsp;</span>
1461
+ <span class="cline-any cline-neutral">&nbsp;</span>
1462
+ <span class="cline-any cline-no">&nbsp;</span>
1463
+ <span class="cline-any cline-no">&nbsp;</span>
1464
+ <span class="cline-any cline-neutral">&nbsp;</span>
1465
+ <span class="cline-any cline-neutral">&nbsp;</span>
1466
+ <span class="cline-any cline-neutral">&nbsp;</span>
1467
+ <span class="cline-any cline-neutral">&nbsp;</span>
1468
+ <span class="cline-any cline-neutral">&nbsp;</span>
1469
+ <span class="cline-any cline-neutral">&nbsp;</span>
1470
+ <span class="cline-any cline-neutral">&nbsp;</span>
1471
+ <span class="cline-any cline-no">&nbsp;</span>
1472
+ <span class="cline-any cline-neutral">&nbsp;</span>
1473
+ <span class="cline-any cline-neutral">&nbsp;</span>
1474
+ <span class="cline-any cline-neutral">&nbsp;</span>
1475
+ <span class="cline-any cline-neutral">&nbsp;</span>
1476
+ <span class="cline-any cline-neutral">&nbsp;</span>
1477
+ <span class="cline-any cline-neutral">&nbsp;</span>
1478
+ <span class="cline-any cline-neutral">&nbsp;</span>
1479
+ <span class="cline-any cline-neutral">&nbsp;</span>
1480
+ <span class="cline-any cline-neutral">&nbsp;</span>
1481
+ <span class="cline-any cline-neutral">&nbsp;</span>
1482
+ <span class="cline-any cline-neutral">&nbsp;</span>
1483
+ <span class="cline-any cline-no">&nbsp;</span>
1484
+ <span class="cline-any cline-neutral">&nbsp;</span>
1485
+ <span class="cline-any cline-no">&nbsp;</span>
1486
+ <span class="cline-any cline-no">&nbsp;</span>
1487
+ <span class="cline-any cline-no">&nbsp;</span>
1488
+ <span class="cline-any cline-neutral">&nbsp;</span>
1489
+ <span class="cline-any cline-no">&nbsp;</span>
1490
+ <span class="cline-any cline-no">&nbsp;</span>
1491
+ <span class="cline-any cline-neutral">&nbsp;</span>
1492
+ <span class="cline-any cline-neutral">&nbsp;</span>
1493
+ <span class="cline-any cline-no">&nbsp;</span>
1494
+ <span class="cline-any cline-no">&nbsp;</span>
1495
+ <span class="cline-any cline-no">&nbsp;</span>
1496
+ <span class="cline-any cline-neutral">&nbsp;</span>
1497
+ <span class="cline-any cline-no">&nbsp;</span>
1498
+ <span class="cline-any cline-no">&nbsp;</span>
1499
+ <span class="cline-any cline-no">&nbsp;</span>
1500
+ <span class="cline-any cline-neutral">&nbsp;</span>
1501
+ <span class="cline-any cline-no">&nbsp;</span>
1502
+ <span class="cline-any cline-no">&nbsp;</span>
1503
+ <span class="cline-any cline-neutral">&nbsp;</span>
1504
+ <span class="cline-any cline-neutral">&nbsp;</span>
1505
+ <span class="cline-any cline-no">&nbsp;</span>
1506
+ <span class="cline-any cline-no">&nbsp;</span>
1507
+ <span class="cline-any cline-neutral">&nbsp;</span>
1508
+ <span class="cline-any cline-no">&nbsp;</span>
1509
+ <span class="cline-any cline-no">&nbsp;</span>
1510
+ <span class="cline-any cline-no">&nbsp;</span>
1511
+ <span class="cline-any cline-no">&nbsp;</span>
1512
+ <span class="cline-any cline-neutral">&nbsp;</span>
1513
+ <span class="cline-any cline-no">&nbsp;</span>
1514
+ <span class="cline-any cline-no">&nbsp;</span>
1515
+ <span class="cline-any cline-no">&nbsp;</span>
1516
+ <span class="cline-any cline-no">&nbsp;</span>
1517
+ <span class="cline-any cline-no">&nbsp;</span>
1518
+ <span class="cline-any cline-no">&nbsp;</span>
1519
+ <span class="cline-any cline-neutral">&nbsp;</span>
1520
+ <span class="cline-any cline-neutral">&nbsp;</span>
1521
+ <span class="cline-any cline-no">&nbsp;</span>
1522
+ <span class="cline-any cline-no">&nbsp;</span>
1523
+ <span class="cline-any cline-no">&nbsp;</span>
1524
+ <span class="cline-any cline-no">&nbsp;</span>
1525
+ <span class="cline-any cline-no">&nbsp;</span>
1526
+ <span class="cline-any cline-no">&nbsp;</span>
1527
+ <span class="cline-any cline-neutral">&nbsp;</span>
1528
+ <span class="cline-any cline-neutral">&nbsp;</span>
1529
+ <span class="cline-any cline-neutral">&nbsp;</span>
1530
+ <span class="cline-any cline-neutral">&nbsp;</span>
1531
+ <span class="cline-any cline-neutral">&nbsp;</span>
1532
+ <span class="cline-any cline-no">&nbsp;</span>
1533
+ <span class="cline-any cline-no">&nbsp;</span>
1534
+ <span class="cline-any cline-no">&nbsp;</span>
1535
+ <span class="cline-any cline-neutral">&nbsp;</span>
1536
+ <span class="cline-any cline-neutral">&nbsp;</span>
1537
+ <span class="cline-any cline-no">&nbsp;</span>
1538
+ <span class="cline-any cline-no">&nbsp;</span>
1539
+ <span class="cline-any cline-no">&nbsp;</span>
1540
+ <span class="cline-any cline-no">&nbsp;</span>
1541
+ <span class="cline-any cline-neutral">&nbsp;</span>
1542
+ <span class="cline-any cline-neutral">&nbsp;</span>
1543
+ <span class="cline-any cline-no">&nbsp;</span>
1544
+ <span class="cline-any cline-neutral">&nbsp;</span>
1545
+ <span class="cline-any cline-no">&nbsp;</span>
1546
+ <span class="cline-any cline-no">&nbsp;</span>
1547
+ <span class="cline-any cline-no">&nbsp;</span>
1548
+ <span class="cline-any cline-no">&nbsp;</span>
1549
+ <span class="cline-any cline-neutral">&nbsp;</span>
1550
+ <span class="cline-any cline-no">&nbsp;</span>
1551
+ <span class="cline-any cline-neutral">&nbsp;</span>
1552
+ <span class="cline-any cline-neutral">&nbsp;</span>
1553
+ <span class="cline-any cline-neutral">&nbsp;</span>
1554
+ <span class="cline-any cline-neutral">&nbsp;</span>
1555
+ <span class="cline-any cline-no">&nbsp;</span>
1556
+ <span class="cline-any cline-no">&nbsp;</span>
1557
+ <span class="cline-any cline-neutral">&nbsp;</span>
1558
+ <span class="cline-any cline-neutral">&nbsp;</span>
1559
+ <span class="cline-any cline-no">&nbsp;</span>
1560
+ <span class="cline-any cline-neutral">&nbsp;</span>
1561
+ <span class="cline-any cline-no">&nbsp;</span>
1562
+ <span class="cline-any cline-no">&nbsp;</span>
1563
+ <span class="cline-any cline-no">&nbsp;</span>
1564
+ <span class="cline-any cline-no">&nbsp;</span>
1565
+ <span class="cline-any cline-neutral">&nbsp;</span>
1566
+ <span class="cline-any cline-neutral">&nbsp;</span>
1567
+ <span class="cline-any cline-no">&nbsp;</span>
1568
+ <span class="cline-any cline-no">&nbsp;</span>
1569
+ <span class="cline-any cline-neutral">&nbsp;</span>
1570
+ <span class="cline-any cline-no">&nbsp;</span>
1571
+ <span class="cline-any cline-no">&nbsp;</span>
1572
+ <span class="cline-any cline-no">&nbsp;</span>
1573
+ <span class="cline-any cline-neutral">&nbsp;</span>
1574
+ <span class="cline-any cline-neutral">&nbsp;</span>
1575
+ <span class="cline-any cline-no">&nbsp;</span>
1576
+ <span class="cline-any cline-no">&nbsp;</span>
1577
+ <span class="cline-any cline-no">&nbsp;</span>
1578
+ <span class="cline-any cline-no">&nbsp;</span>
1579
+ <span class="cline-any cline-neutral">&nbsp;</span>
1580
+ <span class="cline-any cline-neutral">&nbsp;</span>
1581
+ <span class="cline-any cline-no">&nbsp;</span>
1582
+ <span class="cline-any cline-neutral">&nbsp;</span>
1583
+ <span class="cline-any cline-no">&nbsp;</span>
1584
+ <span class="cline-any cline-no">&nbsp;</span>
1585
+ <span class="cline-any cline-no">&nbsp;</span>
1586
+ <span class="cline-any cline-no">&nbsp;</span>
1587
+ <span class="cline-any cline-neutral">&nbsp;</span>
1588
+ <span class="cline-any cline-no">&nbsp;</span>
1589
+ <span class="cline-any cline-neutral">&nbsp;</span>
1590
+ <span class="cline-any cline-neutral">&nbsp;</span>
1591
+ <span class="cline-any cline-neutral">&nbsp;</span>
1592
+ <span class="cline-any cline-neutral">&nbsp;</span>
1593
+ <span class="cline-any cline-no">&nbsp;</span>
1594
+ <span class="cline-any cline-no">&nbsp;</span>
1595
+ <span class="cline-any cline-neutral">&nbsp;</span>
1596
+ <span class="cline-any cline-neutral">&nbsp;</span>
1597
+ <span class="cline-any cline-no">&nbsp;</span>
1598
+ <span class="cline-any cline-neutral">&nbsp;</span>
1599
+ <span class="cline-any cline-no">&nbsp;</span>
1600
+ <span class="cline-any cline-no">&nbsp;</span>
1601
+ <span class="cline-any cline-no">&nbsp;</span>
1602
+ <span class="cline-any cline-no">&nbsp;</span>
1603
+ <span class="cline-any cline-no">&nbsp;</span>
1604
+ <span class="cline-any cline-neutral">&nbsp;</span>
1605
+ <span class="cline-any cline-no">&nbsp;</span>
1606
+ <span class="cline-any cline-no">&nbsp;</span>
1607
+ <span class="cline-any cline-no">&nbsp;</span>
1608
+ <span class="cline-any cline-neutral">&nbsp;</span>
1609
+ <span class="cline-any cline-neutral">&nbsp;</span>
1610
+ <span class="cline-any cline-no">&nbsp;</span>
1611
+ <span class="cline-any cline-no">&nbsp;</span>
1612
+ <span class="cline-any cline-no">&nbsp;</span>
1613
+ <span class="cline-any cline-no">&nbsp;</span>
1614
+ <span class="cline-any cline-neutral">&nbsp;</span>
1615
+ <span class="cline-any cline-neutral">&nbsp;</span>
1616
+ <span class="cline-any cline-no">&nbsp;</span>
1617
+ <span class="cline-any cline-no">&nbsp;</span>
1618
+ <span class="cline-any cline-no">&nbsp;</span>
1619
+ <span class="cline-any cline-neutral">&nbsp;</span>
1620
+ <span class="cline-any cline-neutral">&nbsp;</span>
1621
+ <span class="cline-any cline-neutral">&nbsp;</span>
1622
+ <span class="cline-any cline-neutral">&nbsp;</span>
1623
+ <span class="cline-any cline-neutral">&nbsp;</span>
1624
+ <span class="cline-any cline-no">&nbsp;</span>
1625
+ <span class="cline-any cline-neutral">&nbsp;</span>
1626
+ <span class="cline-any cline-neutral">&nbsp;</span>
1627
+ <span class="cline-any cline-neutral">&nbsp;</span>
1628
+ <span class="cline-any cline-neutral">&nbsp;</span>
1629
+ <span class="cline-any cline-neutral">&nbsp;</span>
1630
+ <span class="cline-any cline-no">&nbsp;</span>
1631
+ <span class="cline-any cline-neutral">&nbsp;</span>
1632
+ <span class="cline-any cline-neutral">&nbsp;</span>
1633
+ <span class="cline-any cline-neutral">&nbsp;</span>
1634
+ <span class="cline-any cline-neutral">&nbsp;</span>
1635
+ <span class="cline-any cline-neutral">&nbsp;</span>
1636
+ <span class="cline-any cline-no">&nbsp;</span>
1637
+ <span class="cline-any cline-neutral">&nbsp;</span>
1638
+ <span class="cline-any cline-neutral">&nbsp;</span>
1639
+ <span class="cline-any cline-neutral">&nbsp;</span>
1640
+ <span class="cline-any cline-neutral">&nbsp;</span>
1641
+ <span class="cline-any cline-neutral">&nbsp;</span>
1642
+ <span class="cline-any cline-neutral">&nbsp;</span>
1643
+ <span class="cline-any cline-neutral">&nbsp;</span>
1644
+ <span class="cline-any cline-neutral">&nbsp;</span>
1645
+ <span class="cline-any cline-neutral">&nbsp;</span>
1646
+ <span class="cline-any cline-neutral">&nbsp;</span>
1647
+ <span class="cline-any cline-neutral">&nbsp;</span>
1648
+ <span class="cline-any cline-neutral">&nbsp;</span>
1649
+ <span class="cline-any cline-neutral">&nbsp;</span>
1650
+ <span class="cline-any cline-neutral">&nbsp;</span>
1651
+ <span class="cline-any cline-neutral">&nbsp;</span>
1652
+ <span class="cline-any cline-neutral">&nbsp;</span>
1653
+ <span class="cline-any cline-neutral">&nbsp;</span>
1654
+ <span class="cline-any cline-neutral">&nbsp;</span>
1655
+ <span class="cline-any cline-no">&nbsp;</span>
1656
+ <span class="cline-any cline-no">&nbsp;</span>
1657
+ <span class="cline-any cline-neutral">&nbsp;</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-no">&nbsp;</span>
1661
+ <span class="cline-any cline-no">&nbsp;</span>
1662
+ <span class="cline-any cline-no">&nbsp;</span>
1663
+ <span class="cline-any cline-no">&nbsp;</span>
1664
+ <span class="cline-any cline-no">&nbsp;</span>
1665
+ <span class="cline-any cline-neutral">&nbsp;</span>
1666
+ <span class="cline-any cline-neutral">&nbsp;</span>
1667
+ <span class="cline-any cline-no">&nbsp;</span>
1668
+ <span class="cline-any cline-no">&nbsp;</span>
1669
+ <span class="cline-any cline-neutral">&nbsp;</span>
1670
+ <span class="cline-any cline-neutral">&nbsp;</span>
1671
+ <span class="cline-any cline-neutral">&nbsp;</span>
1672
+ <span class="cline-any cline-neutral">&nbsp;</span>
1673
+ <span class="cline-any cline-neutral">&nbsp;</span>
1674
+ <span class="cline-any cline-neutral">&nbsp;</span>
1675
+ <span class="cline-any cline-neutral">&nbsp;</span>
1676
+ <span class="cline-any cline-no">&nbsp;</span>
1677
+ <span class="cline-any cline-neutral">&nbsp;</span>
1678
+ <span class="cline-any cline-neutral">&nbsp;</span>
1679
+ <span class="cline-any cline-neutral">&nbsp;</span>
1680
+ <span class="cline-any cline-no">&nbsp;</span>
1681
+ <span class="cline-any cline-no">&nbsp;</span>
1682
+ <span class="cline-any cline-no">&nbsp;</span>
1683
+ <span class="cline-any cline-neutral">&nbsp;</span>
1684
+ <span class="cline-any cline-no">&nbsp;</span>
1685
+ <span class="cline-any cline-no">&nbsp;</span>
1686
+ <span class="cline-any cline-neutral">&nbsp;</span>
1687
+ <span class="cline-any cline-neutral">&nbsp;</span>
1688
+ <span class="cline-any cline-neutral">&nbsp;</span>
1689
+ <span class="cline-any cline-no">&nbsp;</span>
1690
+ <span class="cline-any cline-neutral">&nbsp;</span>
1691
+ <span class="cline-any cline-neutral">&nbsp;</span>
1692
+ <span class="cline-any cline-neutral">&nbsp;</span>
1693
+ <span class="cline-any cline-neutral">&nbsp;</span>
1694
+ <span class="cline-any cline-no">&nbsp;</span>
1695
+ <span class="cline-any cline-neutral">&nbsp;</span>
1696
+ <span class="cline-any cline-neutral">&nbsp;</span>
1697
+ <span class="cline-any cline-neutral">&nbsp;</span>
1698
+ <span class="cline-any cline-no">&nbsp;</span>
1699
+ <span class="cline-any cline-no">&nbsp;</span>
1700
+ <span class="cline-any cline-neutral">&nbsp;</span>
1701
+ <span class="cline-any cline-neutral">&nbsp;</span>
1702
+ <span class="cline-any cline-neutral">&nbsp;</span>
1703
+ <span class="cline-any cline-neutral">&nbsp;</span>
1704
+ <span class="cline-any cline-neutral">&nbsp;</span>
1705
+ <span class="cline-any cline-neutral">&nbsp;</span>
1706
+ <span class="cline-any cline-neutral">&nbsp;</span>
1707
+ <span class="cline-any cline-neutral">&nbsp;</span>
1708
+ <span class="cline-any cline-no">&nbsp;</span>
1709
+ <span class="cline-any cline-neutral">&nbsp;</span>
1710
+ <span class="cline-any cline-neutral">&nbsp;</span>
1711
+ <span class="cline-any cline-neutral">&nbsp;</span>
1712
+ <span class="cline-any cline-neutral">&nbsp;</span>
1713
+ <span class="cline-any cline-no">&nbsp;</span>
1714
+ <span class="cline-any cline-no">&nbsp;</span>
1715
+ <span class="cline-any cline-no">&nbsp;</span>
1716
+ <span class="cline-any cline-neutral">&nbsp;</span>
1717
+ <span class="cline-any cline-neutral">&nbsp;</span>
1718
+ <span class="cline-any cline-no">&nbsp;</span>
1719
+ <span class="cline-any cline-no">&nbsp;</span>
1720
+ <span class="cline-any cline-no">&nbsp;</span>
1721
+ <span class="cline-any cline-no">&nbsp;</span>
1722
+ <span class="cline-any cline-neutral">&nbsp;</span>
1723
+ <span class="cline-any cline-neutral">&nbsp;</span>
1724
+ <span class="cline-any cline-no">&nbsp;</span>
1725
+ <span class="cline-any cline-no">&nbsp;</span>
1726
+ <span class="cline-any cline-neutral">&nbsp;</span>
1727
+ <span class="cline-any cline-no">&nbsp;</span>
1728
+ <span class="cline-any cline-no">&nbsp;</span>
1729
+ <span class="cline-any cline-neutral">&nbsp;</span>
1730
+ <span class="cline-any cline-neutral">&nbsp;</span>
1731
+ <span class="cline-any cline-neutral">&nbsp;</span>
1732
+ <span class="cline-any cline-neutral">&nbsp;</span>
1733
+ <span class="cline-any cline-no">&nbsp;</span>
1734
+ <span class="cline-any cline-no">&nbsp;</span>
1735
+ <span class="cline-any cline-no">&nbsp;</span>
1736
+ <span class="cline-any cline-neutral">&nbsp;</span>
1737
+ <span class="cline-any cline-neutral">&nbsp;</span>
1738
+ <span class="cline-any cline-no">&nbsp;</span>
1739
+ <span class="cline-any cline-neutral">&nbsp;</span>
1740
+ <span class="cline-any cline-neutral">&nbsp;</span>
1741
+ <span class="cline-any cline-neutral">&nbsp;</span>
1742
+ <span class="cline-any cline-neutral">&nbsp;</span>
1743
+ <span class="cline-any cline-neutral">&nbsp;</span>
1744
+ <span class="cline-any cline-no">&nbsp;</span>
1745
+ <span class="cline-any cline-neutral">&nbsp;</span>
1746
+ <span class="cline-any cline-neutral">&nbsp;</span>
1747
+ <span class="cline-any cline-neutral">&nbsp;</span>
1748
+ <span class="cline-any cline-neutral">&nbsp;</span>
1749
+ <span class="cline-any cline-neutral">&nbsp;</span>
1750
+ <span class="cline-any cline-no">&nbsp;</span>
1751
+ <span class="cline-any cline-neutral">&nbsp;</span>
1752
+ <span class="cline-any cline-neutral">&nbsp;</span>
1753
+ <span class="cline-any cline-neutral">&nbsp;</span>
1754
+ <span class="cline-any cline-neutral">&nbsp;</span>
1755
+ <span class="cline-any cline-neutral">&nbsp;</span>
1756
+ <span class="cline-any cline-neutral">&nbsp;</span>
1757
+ <span class="cline-any cline-neutral">&nbsp;</span>
1758
+ <span class="cline-any cline-neutral">&nbsp;</span>
1759
+ <span class="cline-any cline-neutral">&nbsp;</span>
1760
+ <span class="cline-any cline-neutral">&nbsp;</span>
1761
+ <span class="cline-any cline-neutral">&nbsp;</span>
1762
+ <span class="cline-any cline-neutral">&nbsp;</span>
1763
+ <span class="cline-any cline-neutral">&nbsp;</span>
1764
+ <span class="cline-any cline-neutral">&nbsp;</span>
1765
+ <span class="cline-any cline-neutral">&nbsp;</span>
1766
+ <span class="cline-any cline-no">&nbsp;</span>
1767
+ <span class="cline-any cline-no">&nbsp;</span>
1768
+ <span class="cline-any cline-no">&nbsp;</span>
1769
+ <span class="cline-any cline-no">&nbsp;</span>
1770
+ <span class="cline-any cline-neutral">&nbsp;</span>
1771
+ <span class="cline-any cline-neutral">&nbsp;</span>
1772
+ <span class="cline-any cline-no">&nbsp;</span>
1773
+ <span class="cline-any cline-no">&nbsp;</span>
1774
+ <span class="cline-any cline-neutral">&nbsp;</span>
1775
+ <span class="cline-any cline-neutral">&nbsp;</span>
1776
+ <span class="cline-any cline-no">&nbsp;</span>
1777
+ <span class="cline-any cline-no">&nbsp;</span>
1778
+ <span class="cline-any cline-no">&nbsp;</span>
1779
+ <span class="cline-any cline-neutral">&nbsp;</span>
1780
+ <span class="cline-any cline-neutral">&nbsp;</span>
1781
+ <span class="cline-any cline-no">&nbsp;</span>
1782
+ <span class="cline-any cline-no">&nbsp;</span>
1783
+ <span class="cline-any cline-no">&nbsp;</span>
1784
+ <span class="cline-any cline-neutral">&nbsp;</span>
1785
+ <span class="cline-any cline-no">&nbsp;</span>
1786
+ <span class="cline-any cline-no">&nbsp;</span>
1787
+ <span class="cline-any cline-no">&nbsp;</span>
1788
+ <span class="cline-any cline-neutral">&nbsp;</span>
1789
+ <span class="cline-any cline-neutral">&nbsp;</span>
1790
+ <span class="cline-any cline-no">&nbsp;</span>
1791
+ <span class="cline-any cline-no">&nbsp;</span>
1792
+ <span class="cline-any cline-neutral">&nbsp;</span>
1793
+ <span class="cline-any cline-no">&nbsp;</span>
1794
+ <span class="cline-any cline-no">&nbsp;</span>
1795
+ <span class="cline-any cline-no">&nbsp;</span>
1796
+ <span class="cline-any cline-no">&nbsp;</span>
1797
+ <span class="cline-any cline-no">&nbsp;</span>
1798
+ <span class="cline-any cline-neutral">&nbsp;</span>
1799
+ <span class="cline-any cline-no">&nbsp;</span>
1800
+ <span class="cline-any cline-no">&nbsp;</span>
1801
+ <span class="cline-any cline-no">&nbsp;</span>
1802
+ <span class="cline-any cline-no">&nbsp;</span>
1803
+ <span class="cline-any cline-neutral">&nbsp;</span>
1804
+ <span class="cline-any cline-no">&nbsp;</span>
1805
+ <span class="cline-any cline-no">&nbsp;</span>
1806
+ <span class="cline-any cline-no">&nbsp;</span>
1807
+ <span class="cline-any cline-no">&nbsp;</span>
1808
+ <span class="cline-any cline-no">&nbsp;</span>
1809
+ <span class="cline-any cline-neutral">&nbsp;</span>
1810
+ <span class="cline-any cline-neutral">&nbsp;</span>
1811
+ <span class="cline-any cline-neutral">&nbsp;</span>
1812
+ <span class="cline-any cline-neutral">&nbsp;</span>
1813
+ <span class="cline-any cline-neutral">&nbsp;</span>
1814
+ <span class="cline-any cline-no">&nbsp;</span>
1815
+ <span class="cline-any cline-no">&nbsp;</span>
1816
+ <span class="cline-any cline-no">&nbsp;</span>
1817
+ <span class="cline-any cline-neutral">&nbsp;</span>
1818
+ <span class="cline-any cline-neutral">&nbsp;</span>
1819
+ <span class="cline-any cline-neutral">&nbsp;</span>
1820
+ <span class="cline-any cline-no">&nbsp;</span>
1821
+ <span class="cline-any cline-no">&nbsp;</span>
1822
+ <span class="cline-any cline-no">&nbsp;</span>
1823
+ <span class="cline-any cline-no">&nbsp;</span>
1824
+ <span class="cline-any cline-neutral">&nbsp;</span>
1825
+ <span class="cline-any cline-neutral">&nbsp;</span>
1826
+ <span class="cline-any cline-no">&nbsp;</span>
1827
+ <span class="cline-any cline-neutral">&nbsp;</span>
1828
+ <span class="cline-any cline-neutral">&nbsp;</span>
1829
+ <span class="cline-any cline-no">&nbsp;</span>
1830
+ <span class="cline-any cline-no">&nbsp;</span>
1831
+ <span class="cline-any cline-no">&nbsp;</span>
1832
+ <span class="cline-any cline-no">&nbsp;</span>
1833
+ <span class="cline-any cline-no">&nbsp;</span>
1834
+ <span class="cline-any cline-neutral">&nbsp;</span>
1835
+ <span class="cline-any cline-no">&nbsp;</span>
1836
+ <span class="cline-any cline-neutral">&nbsp;</span>
1837
+ <span class="cline-any cline-neutral">&nbsp;</span>
1838
+ <span class="cline-any cline-neutral">&nbsp;</span>
1839
+ <span class="cline-any cline-neutral">&nbsp;</span>
1840
+ <span class="cline-any cline-no">&nbsp;</span>
1841
+ <span class="cline-any cline-no">&nbsp;</span>
1842
+ <span class="cline-any cline-neutral">&nbsp;</span>
1843
+ <span class="cline-any cline-no">&nbsp;</span>
1844
+ <span class="cline-any cline-neutral">&nbsp;</span>
1845
+ <span class="cline-any cline-no">&nbsp;</span>
1846
+ <span class="cline-any cline-no">&nbsp;</span>
1847
+ <span class="cline-any cline-no">&nbsp;</span>
1848
+ <span class="cline-any cline-no">&nbsp;</span>
1849
+ <span class="cline-any cline-no">&nbsp;</span>
1850
+ <span class="cline-any cline-neutral">&nbsp;</span>
1851
+ <span class="cline-any cline-no">&nbsp;</span>
1852
+ <span class="cline-any cline-neutral">&nbsp;</span>
1853
+ <span class="cline-any cline-neutral">&nbsp;</span>
1854
+ <span class="cline-any cline-neutral">&nbsp;</span>
1855
+ <span class="cline-any cline-neutral">&nbsp;</span>
1856
+ <span class="cline-any cline-no">&nbsp;</span>
1857
+ <span class="cline-any cline-neutral">&nbsp;</span>
1858
+ <span class="cline-any cline-neutral">&nbsp;</span>
1859
+ <span class="cline-any cline-neutral">&nbsp;</span>
1860
+ <span class="cline-any cline-no">&nbsp;</span>
1861
+ <span class="cline-any cline-no">&nbsp;</span>
1862
+ <span class="cline-any cline-neutral">&nbsp;</span>
1863
+ <span class="cline-any cline-neutral">&nbsp;</span>
1864
+ <span class="cline-any cline-neutral">&nbsp;</span>
1865
+ <span class="cline-any cline-neutral">&nbsp;</span>
1866
+ <span class="cline-any cline-neutral">&nbsp;</span>
1867
+ <span class="cline-any cline-neutral">&nbsp;</span>
1868
+ <span class="cline-any cline-neutral">&nbsp;</span>
1869
+ <span class="cline-any cline-neutral">&nbsp;</span>
1870
+ <span class="cline-any cline-neutral">&nbsp;</span>
1871
+ <span class="cline-any cline-neutral">&nbsp;</span>
1872
+ <span class="cline-any cline-neutral">&nbsp;</span>
1873
+ <span class="cline-any cline-neutral">&nbsp;</span>
1874
+ <span class="cline-any cline-neutral">&nbsp;</span>
1875
+ <span class="cline-any cline-neutral">&nbsp;</span>
1876
+ <span class="cline-any cline-neutral">&nbsp;</span>
1877
+ <span class="cline-any cline-no">&nbsp;</span>
1878
+ <span class="cline-any cline-no">&nbsp;</span>
1879
+ <span class="cline-any cline-no">&nbsp;</span>
1880
+ <span class="cline-any cline-no">&nbsp;</span>
1881
+ <span class="cline-any cline-no">&nbsp;</span>
1882
+ <span class="cline-any cline-neutral">&nbsp;</span>
1883
+ <span class="cline-any cline-neutral">&nbsp;</span>
1884
+ <span class="cline-any cline-no">&nbsp;</span>
1885
+ <span class="cline-any cline-no">&nbsp;</span>
1886
+ <span class="cline-any cline-neutral">&nbsp;</span>
1887
+ <span class="cline-any cline-no">&nbsp;</span>
1888
+ <span class="cline-any cline-no">&nbsp;</span>
1889
+ <span class="cline-any cline-no">&nbsp;</span>
1890
+ <span class="cline-any cline-neutral">&nbsp;</span>
1891
+ <span class="cline-any cline-neutral">&nbsp;</span>
1892
+ <span class="cline-any cline-no">&nbsp;</span>
1893
+ <span class="cline-any cline-no">&nbsp;</span>
1894
+ <span class="cline-any cline-no">&nbsp;</span>
1895
+ <span class="cline-any cline-no">&nbsp;</span>
1896
+ <span class="cline-any cline-neutral">&nbsp;</span>
1897
+ <span class="cline-any cline-neutral">&nbsp;</span>
1898
+ <span class="cline-any cline-no">&nbsp;</span>
1899
+ <span class="cline-any cline-neutral">&nbsp;</span>
1900
+ <span class="cline-any cline-neutral">&nbsp;</span>
1901
+ <span class="cline-any cline-no">&nbsp;</span>
1902
+ <span class="cline-any cline-no">&nbsp;</span>
1903
+ <span class="cline-any cline-no">&nbsp;</span>
1904
+ <span class="cline-any cline-no">&nbsp;</span>
1905
+ <span class="cline-any cline-no">&nbsp;</span>
1906
+ <span class="cline-any cline-neutral">&nbsp;</span>
1907
+ <span class="cline-any cline-no">&nbsp;</span>
1908
+ <span class="cline-any cline-neutral">&nbsp;</span>
1909
+ <span class="cline-any cline-neutral">&nbsp;</span>
1910
+ <span class="cline-any cline-neutral">&nbsp;</span>
1911
+ <span class="cline-any cline-neutral">&nbsp;</span>
1912
+ <span class="cline-any cline-no">&nbsp;</span>
1913
+ <span class="cline-any cline-no">&nbsp;</span>
1914
+ <span class="cline-any cline-neutral">&nbsp;</span>
1915
+ <span class="cline-any cline-neutral">&nbsp;</span>
1916
+ <span class="cline-any cline-neutral">&nbsp;</span>
1917
+ <span class="cline-any cline-no">&nbsp;</span>
1918
+ <span class="cline-any cline-no">&nbsp;</span>
1919
+ <span class="cline-any cline-neutral">&nbsp;</span>
1920
+ <span class="cline-any cline-neutral">&nbsp;</span>
1921
+ <span class="cline-any cline-neutral">&nbsp;</span>
1922
+ <span class="cline-any cline-neutral">&nbsp;</span>
1923
+ <span class="cline-any cline-neutral">&nbsp;</span>
1924
+ <span class="cline-any cline-neutral">&nbsp;</span>
1925
+ <span class="cline-any cline-neutral">&nbsp;</span>
1926
+ <span class="cline-any cline-neutral">&nbsp;</span>
1927
+ <span class="cline-any cline-neutral">&nbsp;</span>
1928
+ <span class="cline-any cline-neutral">&nbsp;</span>
1929
+ <span class="cline-any cline-neutral">&nbsp;</span>
1930
+ <span class="cline-any cline-neutral">&nbsp;</span>
1931
+ <span class="cline-any cline-neutral">&nbsp;</span>
1932
+ <span class="cline-any cline-neutral">&nbsp;</span>
1933
+ <span class="cline-any cline-neutral">&nbsp;</span>
1934
+ <span class="cline-any cline-neutral">&nbsp;</span>
1935
+ <span class="cline-any cline-no">&nbsp;</span>
1936
+ <span class="cline-any cline-no">&nbsp;</span>
1937
+ <span class="cline-any cline-no">&nbsp;</span>
1938
+ <span class="cline-any cline-no">&nbsp;</span>
1939
+ <span class="cline-any cline-no">&nbsp;</span>
1940
+ <span class="cline-any cline-no">&nbsp;</span>
1941
+ <span class="cline-any cline-no">&nbsp;</span>
1942
+ <span class="cline-any cline-neutral">&nbsp;</span>
1943
+ <span class="cline-any cline-neutral">&nbsp;</span>
1944
+ <span class="cline-any cline-no">&nbsp;</span>
1945
+ <span class="cline-any cline-no">&nbsp;</span>
1946
+ <span class="cline-any cline-no">&nbsp;</span>
1947
+ <span class="cline-any cline-no">&nbsp;</span>
1948
+ <span class="cline-any cline-no">&nbsp;</span>
1949
+ <span class="cline-any cline-no">&nbsp;</span>
1950
+ <span class="cline-any cline-neutral">&nbsp;</span>
1951
+ <span class="cline-any cline-no">&nbsp;</span>
1952
+ <span class="cline-any cline-no">&nbsp;</span>
1953
+ <span class="cline-any cline-no">&nbsp;</span>
1954
+ <span class="cline-any cline-neutral">&nbsp;</span>
1955
+ <span class="cline-any cline-no">&nbsp;</span>
1956
+ <span class="cline-any cline-no">&nbsp;</span>
1957
+ <span class="cline-any cline-no">&nbsp;</span>
1958
+ <span class="cline-any cline-neutral">&nbsp;</span>
1959
+ <span class="cline-any cline-no">&nbsp;</span>
1960
+ <span class="cline-any cline-no">&nbsp;</span>
1961
+ <span class="cline-any cline-no">&nbsp;</span>
1962
+ <span class="cline-any cline-neutral">&nbsp;</span>
1963
+ <span class="cline-any cline-neutral">&nbsp;</span>
1964
+ <span class="cline-any cline-neutral">&nbsp;</span>
1965
+ <span class="cline-any cline-no">&nbsp;</span>
1966
+ <span class="cline-any cline-neutral">&nbsp;</span>
1967
+ <span class="cline-any cline-neutral">&nbsp;</span>
1968
+ <span class="cline-any cline-neutral">&nbsp;</span>
1969
+ <span class="cline-any cline-neutral">&nbsp;</span>
1970
+ <span class="cline-any cline-no">&nbsp;</span>
1971
+ <span class="cline-any cline-no">&nbsp;</span>
1972
+ <span class="cline-any cline-neutral">&nbsp;</span>
1973
+ <span class="cline-any cline-no">&nbsp;</span>
1974
+ <span class="cline-any cline-neutral">&nbsp;</span>
1975
+ <span class="cline-any cline-no">&nbsp;</span>
1976
+ <span class="cline-any cline-no">&nbsp;</span>
1977
+ <span class="cline-any cline-neutral">&nbsp;</span>
1978
+ <span class="cline-any cline-neutral">&nbsp;</span>
1979
+ <span class="cline-any cline-neutral">&nbsp;</span>
1980
+ <span class="cline-any cline-no">&nbsp;</span>
1981
+ <span class="cline-any cline-neutral">&nbsp;</span>
1982
+ <span class="cline-any cline-neutral">&nbsp;</span>
1983
+ <span class="cline-any cline-neutral">&nbsp;</span>
1984
+ <span class="cline-any cline-no">&nbsp;</span>
1985
+ <span class="cline-any cline-no">&nbsp;</span>
1986
+ <span class="cline-any cline-neutral">&nbsp;</span>
1987
+ <span class="cline-any cline-neutral">&nbsp;</span>
1988
+ <span class="cline-any cline-no">&nbsp;</span>
1989
+ <span class="cline-any cline-no">&nbsp;</span>
1990
+ <span class="cline-any cline-neutral">&nbsp;</span>
1991
+ <span class="cline-any cline-neutral">&nbsp;</span>
1992
+ <span class="cline-any cline-neutral">&nbsp;</span>
1993
+ <span class="cline-any cline-no">&nbsp;</span>
1994
+ <span class="cline-any cline-no">&nbsp;</span>
1995
+ <span class="cline-any cline-neutral">&nbsp;</span>
1996
+ <span class="cline-any cline-neutral">&nbsp;</span>
1997
+ <span class="cline-any cline-neutral">&nbsp;</span>
1998
+ <span class="cline-any cline-no">&nbsp;</span>
1999
+ <span class="cline-any cline-neutral">&nbsp;</span>
2000
+ <span class="cline-any cline-neutral">&nbsp;</span>
2001
+ <span class="cline-any cline-neutral">&nbsp;</span>
2002
+ <span class="cline-any cline-neutral">&nbsp;</span>
2003
+ <span class="cline-any cline-neutral">&nbsp;</span>
2004
+ <span class="cline-any cline-neutral">&nbsp;</span>
2005
+ <span class="cline-any cline-neutral">&nbsp;</span>
2006
+ <span class="cline-any cline-neutral">&nbsp;</span>
2007
+ <span class="cline-any cline-neutral">&nbsp;</span>
2008
+ <span class="cline-any cline-neutral">&nbsp;</span>
2009
+ <span class="cline-any cline-neutral">&nbsp;</span>
2010
+ <span class="cline-any cline-neutral">&nbsp;</span>
2011
+ <span class="cline-any cline-no">&nbsp;</span>
2012
+ <span class="cline-any cline-no">&nbsp;</span>
2013
+ <span class="cline-any cline-neutral">&nbsp;</span>
2014
+ <span class="cline-any cline-no">&nbsp;</span>
2015
+ <span class="cline-any cline-no">&nbsp;</span>
2016
+ <span class="cline-any cline-no">&nbsp;</span>
2017
+ <span class="cline-any cline-no">&nbsp;</span>
2018
+ <span class="cline-any cline-neutral">&nbsp;</span>
2019
+ <span class="cline-any cline-no">&nbsp;</span>
2020
+ <span class="cline-any cline-no">&nbsp;</span>
2021
+ <span class="cline-any cline-no">&nbsp;</span>
2022
+ <span class="cline-any cline-no">&nbsp;</span>
2023
+ <span class="cline-any cline-no">&nbsp;</span>
2024
+ <span class="cline-any cline-neutral">&nbsp;</span>
2025
+ <span class="cline-any cline-no">&nbsp;</span>
2026
+ <span class="cline-any cline-no">&nbsp;</span>
2027
+ <span class="cline-any cline-no">&nbsp;</span>
2028
+ <span class="cline-any cline-neutral">&nbsp;</span>
2029
+ <span class="cline-any cline-no">&nbsp;</span>
2030
+ <span class="cline-any cline-no">&nbsp;</span>
2031
+ <span class="cline-any cline-neutral">&nbsp;</span>
2032
+ <span class="cline-any cline-no">&nbsp;</span>
2033
+ <span class="cline-any cline-neutral">&nbsp;</span>
2034
+ <span class="cline-any cline-no">&nbsp;</span>
2035
+ <span class="cline-any cline-no">&nbsp;</span>
2036
+ <span class="cline-any cline-neutral">&nbsp;</span>
2037
+ <span class="cline-any cline-neutral">&nbsp;</span>
2038
+ <span class="cline-any cline-neutral">&nbsp;</span>
2039
+ <span class="cline-any cline-neutral">&nbsp;</span>
2040
+ <span class="cline-any cline-neutral">&nbsp;</span>
2041
+ <span class="cline-any cline-neutral">&nbsp;</span>
2042
+ <span class="cline-any cline-neutral">&nbsp;</span>
2043
+ <span class="cline-any cline-neutral">&nbsp;</span>
2044
+ <span class="cline-any cline-neutral">&nbsp;</span>
2045
+ <span class="cline-any cline-neutral">&nbsp;</span>
2046
+ <span class="cline-any cline-neutral">&nbsp;</span>
2047
+ <span class="cline-any cline-neutral">&nbsp;</span>
2048
+ <span class="cline-any cline-neutral">&nbsp;</span>
2049
+ <span class="cline-any cline-neutral">&nbsp;</span>
2050
+ <span class="cline-any cline-neutral">&nbsp;</span>
2051
+ <span class="cline-any cline-no">&nbsp;</span>
2052
+ <span class="cline-any cline-no">&nbsp;</span>
2053
+ <span class="cline-any cline-neutral">&nbsp;</span>
2054
+ <span class="cline-any cline-no">&nbsp;</span>
2055
+ <span class="cline-any cline-no">&nbsp;</span>
2056
+ <span class="cline-any cline-no">&nbsp;</span>
2057
+ <span class="cline-any cline-no">&nbsp;</span>
2058
+ <span class="cline-any cline-no">&nbsp;</span>
2059
+ <span class="cline-any cline-neutral">&nbsp;</span>
2060
+ <span class="cline-any cline-neutral">&nbsp;</span>
2061
+ <span class="cline-any cline-no">&nbsp;</span>
2062
+ <span class="cline-any cline-no">&nbsp;</span>
2063
+ <span class="cline-any cline-neutral">&nbsp;</span>
2064
+ <span class="cline-any cline-no">&nbsp;</span>
2065
+ <span class="cline-any cline-no">&nbsp;</span>
2066
+ <span class="cline-any cline-no">&nbsp;</span>
2067
+ <span class="cline-any cline-neutral">&nbsp;</span>
2068
+ <span class="cline-any cline-neutral">&nbsp;</span>
2069
+ <span class="cline-any cline-neutral">&nbsp;</span>
2070
+ <span class="cline-any cline-no">&nbsp;</span>
2071
+ <span class="cline-any cline-no">&nbsp;</span>
2072
+ <span class="cline-any cline-no">&nbsp;</span>
2073
+ <span class="cline-any cline-no">&nbsp;</span>
2074
+ <span class="cline-any cline-neutral">&nbsp;</span>
2075
+ <span class="cline-any cline-neutral">&nbsp;</span>
2076
+ <span class="cline-any cline-no">&nbsp;</span>
2077
+ <span class="cline-any cline-neutral">&nbsp;</span>
2078
+ <span class="cline-any cline-neutral">&nbsp;</span>
2079
+ <span class="cline-any cline-neutral">&nbsp;</span>
2080
+ <span class="cline-any cline-neutral">&nbsp;</span>
2081
+ <span class="cline-any cline-no">&nbsp;</span>
2082
+ <span class="cline-any cline-neutral">&nbsp;</span>
2083
+ <span class="cline-any cline-no">&nbsp;</span>
2084
+ <span class="cline-any cline-neutral">&nbsp;</span>
2085
+ <span class="cline-any cline-no">&nbsp;</span>
2086
+ <span class="cline-any cline-no">&nbsp;</span>
2087
+ <span class="cline-any cline-neutral">&nbsp;</span>
2088
+ <span class="cline-any cline-neutral">&nbsp;</span>
2089
+ <span class="cline-any cline-neutral">&nbsp;</span>
2090
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import { and, eq, inArray, sql, SQL } from "drizzle-orm";
2091
+ import { AnyPgColumn, PgTable } from "drizzle-orm/pg-core";
2092
+ import { DrizzleClient } from "../interfaces";
2093
+ import { Entity, EntityCollection, FilterValues, Relation } from "@rebasepro/types";
2094
+ import { getTableName, resolveCollectionRelations } from "@rebasepro/common";
2095
+ import { DrizzleConditionBuilder } from "../../utils/drizzle-conditions";
2096
+ import {
2097
+ getCollectionByPath,
2098
+ getTableForCollection,
2099
+ getPrimaryKeys,
2100
+ parseIdValues,
2101
+ buildCompositeId
2102
+ } from "./entity-helpers";
2103
+ import { parseDataFromServer } from "../data-transformer";
2104
+ import { BackendCollectionRegistry } from "../../collections/BackendCollectionRegistry";
2105
+ &nbsp;
2106
+ /**
2107
+ * Service for handling all relation-related operations.
2108
+ * Handles fetching, updating, and managing entity relations.
2109
+ */
2110
+ export class RelationService {
2111
+ constructor(private db: DrizzleClient, private registry: BackendCollectionRegistry) { }
2112
+ &nbsp;
2113
+ /**
2114
+ * Fetch entities related to a parent entity through a specific relation
2115
+ */
2116
+ <span class="fstat-no" title="function not covered" > async </span>fetchRelatedEntities&lt;M extends Record&lt;string, any&gt;&gt;(
2117
+ parentCollectionPath: string,
2118
+ parentEntityId: string | number,
2119
+ relationKey: string,
2120
+ options: {
2121
+ filter?: FilterValues&lt;Extract&lt;keyof M, string&gt;&gt;;
2122
+ orderBy?: string;
2123
+ order?: "desc" | "asc";
2124
+ limit?: number;
2125
+ startAfter?: Record&lt;string, unknown&gt;;
2126
+ searchString?: string;
2127
+ databaseId?: string;
2128
+ } = <span class="branch-0 cbranch-no" title="branch not covered" >{}</span>
2129
+ ): Promise&lt;Entity&lt;M&gt;[]&gt; {
2130
+ const parentCollection = <span class="cstat-no" title="statement not covered" >getCollectionByPath(parentCollectionPath, this.registry);</span>
2131
+ const resolvedRelations = <span class="cstat-no" title="statement not covered" >resolveCollectionRelations(parentCollection);</span>
2132
+ const relation = <span class="cstat-no" title="statement not covered" >resolvedRelations[relationKey];</span>
2133
+ &nbsp;
2134
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!relation) {</span>
2135
+ <span class="cstat-no" title="statement not covered" > throw new Error(`Relation '${relationKey}' not found in collection '${parentCollectionPath}'`);</span>
2136
+ }
2137
+ &nbsp;
2138
+ <span class="cstat-no" title="statement not covered" > return this.fetchEntitiesUsingJoins&lt;M&gt;(parentCollection, parentEntityId, relation, options);</span>
2139
+ }
2140
+ &nbsp;
2141
+ /**
2142
+ * Fetch entities using join paths for complex relations
2143
+ */
2144
+ <span class="fstat-no" title="function not covered" > async </span>fetchEntitiesUsingJoins&lt;M extends Record&lt;string, any&gt;&gt;(
2145
+ parentCollection: EntityCollection,
2146
+ parentEntityId: string | number,
2147
+ relation: Relation,
2148
+ options: {
2149
+ filter?: FilterValues&lt;Extract&lt;keyof M, string&gt;&gt;;
2150
+ orderBy?: string;
2151
+ order?: "desc" | "asc";
2152
+ limit?: number;
2153
+ startAfter?: Record&lt;string, unknown&gt;;
2154
+ searchString?: string;
2155
+ databaseId?: string;
2156
+ } = <span class="branch-0 cbranch-no" title="branch not covered" >{}</span>
2157
+ ): Promise&lt;Entity&lt;M&gt;[]&gt; {
2158
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
2159
+ const targetTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(targetCollection, this.registry);</span>
2160
+ const idInfo = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2161
+ const idField = <span class="cstat-no" title="statement not covered" >targetTable[idInfo[0].fieldName as keyof typeof targetTable] as AnyPgColumn;</span>
2162
+ &nbsp;
2163
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(parentCollection, this.registry);</span>
2164
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2165
+ const parsedParentIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(parentEntityId, parentPks);</span>
2166
+ const parsedParentId = <span class="cstat-no" title="statement not covered" >parsedParentIdObj[parentIdInfo.fieldName];</span>
2167
+ const parentTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(getTableName(parentCollection));</span>
2168
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!parentTable) <span class="cstat-no" title="statement not covered" >throw new Error("Parent table not found");</span></span>
2169
+ const parentIdCol = <span class="cstat-no" title="statement not covered" >parentTable[parentIdInfo.fieldName as keyof typeof parentTable] as AnyPgColumn;</span>
2170
+ &nbsp;
2171
+ // Handle join path relations
2172
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (relation.joinPath &amp;&amp; relation.joinPath.length &gt; 0) {</span>
2173
+ let query = <span class="cstat-no" title="statement not covered" >this.db.select().from(parentTable).$dynamic();</span>
2174
+ let currentTable = <span class="cstat-no" title="statement not covered" >parentTable;</span>
2175
+ &nbsp;
2176
+ // Apply each join in the path
2177
+ <span class="cstat-no" title="statement not covered" > for (const join of relation.joinPath) {</span>
2178
+ const joinTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(join.table);</span>
2179
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!joinTable) {</span>
2180
+ <span class="cstat-no" title="statement not covered" > throw new Error(`Join table not found: ${join.table}`);</span>
2181
+ }
2182
+ &nbsp;
2183
+ const fromColumn = <span class="cstat-no" title="statement not covered" >Array.isArray(join.on.from) ? join.on.from[0] : join.on.from;</span>
2184
+ const toColumn = <span class="cstat-no" title="statement not covered" >Array.isArray(join.on.to) ? join.on.to[0] : join.on.to;</span>
2185
+ &nbsp;
2186
+ const fromParts = <span class="cstat-no" title="statement not covered" >fromColumn.split(".");</span>
2187
+ const toParts = <span class="cstat-no" title="statement not covered" >toColumn.split(".");</span>
2188
+ &nbsp;
2189
+ const fromColName = <span class="cstat-no" title="statement not covered" >fromParts[fromParts.length - 1];</span>
2190
+ const toColName = <span class="cstat-no" title="statement not covered" >toParts[toParts.length - 1];</span>
2191
+ &nbsp;
2192
+ const fromCol = <span class="cstat-no" title="statement not covered" >currentTable[fromColName as keyof typeof currentTable] as AnyPgColumn;</span>
2193
+ const toCol = <span class="cstat-no" title="statement not covered" >joinTable[toColName as keyof typeof joinTable] as AnyPgColumn;</span>
2194
+ &nbsp;
2195
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fromCol || !toCol) {</span>
2196
+ <span class="cstat-no" title="statement not covered" > throw new Error(`Join columns not found: ${fromColumn} -&gt; ${toColumn}`);</span>
2197
+ }
2198
+ &nbsp;
2199
+ // @ts-expect-error Drizzle mutates base query generic on innerJoin
2200
+ <span class="cstat-no" title="statement not covered" > query = query.innerJoin(joinTable, eq(fromCol, toCol));</span>
2201
+ <span class="cstat-no" title="statement not covered" > currentTable = joinTable;</span>
2202
+ }
2203
+ &nbsp;
2204
+ // Add where condition for the parent entity
2205
+ const parentIdField = <span class="cstat-no" title="statement not covered" >parentTable[getPrimaryKeys(parentCollection, this.registry)[0].fieldName as keyof typeof parentTable] as AnyPgColumn;</span>
2206
+ <span class="cstat-no" title="statement not covered" > query = query.where(eq(parentIdField, parsedParentId));</span>
2207
+ &nbsp;
2208
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (options.limit) {</span>
2209
+ <span class="cstat-no" title="statement not covered" > query = query.limit(options.limit);</span>
2210
+ }
2211
+ &nbsp;
2212
+ const results = <span class="cstat-no" title="statement not covered" >await query;</span>
2213
+ const targetTableName = <span class="cstat-no" title="statement not covered" >relation.joinPath[relation.joinPath.length - 1].table;</span>
2214
+ &nbsp;
2215
+ // Process results
2216
+ const entities: Entity&lt;M&gt;[] = <span class="cstat-no" title="statement not covered" >[];</span>
2217
+ <span class="cstat-no" title="statement not covered" > for (const row of results as Array&lt;Record&lt;string, unknown&gt;&gt;) {</span>
2218
+ const targetEntity = (<span class="cstat-no" title="statement not covered" >row[targetTableName] as Record&lt;string, unknown&gt;) || row;</span>
2219
+ const entityId = <span class="cstat-no" title="statement not covered" >targetEntity[idInfo[0].fieldName as string];</span>
2220
+ const parsedValues = <span class="cstat-no" title="statement not covered" >await parseDataFromServer(targetEntity, targetCollection, this.db, this.registry);</span>
2221
+ &nbsp;
2222
+ <span class="cstat-no" title="statement not covered" > entities.push({</span>
2223
+ id: entityId?.toString() || "",
2224
+ path: targetCollection.slug ?? targetCollection.dbPath,
2225
+ values: parsedValues as M
2226
+ });
2227
+ }
2228
+ &nbsp;
2229
+ <span class="cstat-no" title="statement not covered" > return entities;</span>
2230
+ }
2231
+ &nbsp;
2232
+ // Handle other relation types
2233
+ let query = <span class="cstat-no" title="statement not covered" >this.db.select().from(targetTable).$dynamic();</span>
2234
+ &nbsp;
2235
+ // Build additional filter conditions
2236
+ const additionalFilters: SQL[] = <span class="cstat-no" title="statement not covered" >[];</span>
2237
+ &nbsp;
2238
+ // Handle search conditions if searchString is provided
2239
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (options.searchString) {</span>
2240
+ const searchConditions = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.buildSearchConditions(</span>
2241
+ options.searchString,
2242
+ targetCollection.properties,
2243
+ targetTable
2244
+ );
2245
+ &nbsp;
2246
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (searchConditions.length === 0) {</span>
2247
+ // No searchable fields found, return empty results
2248
+ <span class="cstat-no" title="statement not covered" > return [];</span>
2249
+ }
2250
+ &nbsp;
2251
+ const searchCombined = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.combineConditionsWithOr(searchConditions);</span>
2252
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (searchCombined) {</span>
2253
+ <span class="cstat-no" title="statement not covered" > additionalFilters.push(searchCombined);</span>
2254
+ }
2255
+ }
2256
+ &nbsp;
2257
+ // Use unified relation query builder
2258
+ // @ts-expect-error buildRelationQuery uses dynamic queries
2259
+ <span class="cstat-no" title="statement not covered" > query = DrizzleConditionBuilder.buildRelationQuery(</span>
2260
+ query,
2261
+ relation,
2262
+ parsedParentId,
2263
+ targetTable,
2264
+ parentTable,
2265
+ parentIdCol,
2266
+ idField,
2267
+ this.registry,
2268
+ additionalFilters
2269
+ );
2270
+ &nbsp;
2271
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (options.limit) {</span>
2272
+ <span class="cstat-no" title="statement not covered" > query = query.limit(options.limit);</span>
2273
+ }
2274
+ &nbsp;
2275
+ const results = <span class="cstat-no" title="statement not covered" >await query;</span>
2276
+ &nbsp;
2277
+ // Process results - ensure results is iterable
2278
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!results || !Array.isArray(results)) {</span>
2279
+ <span class="cstat-no" title="statement not covered" > return [];</span>
2280
+ }
2281
+ &nbsp;
2282
+ const entities: Entity&lt;M&gt;[] = <span class="cstat-no" title="statement not covered" >[];</span>
2283
+ <span class="cstat-no" title="statement not covered" > for (const row of results) {</span>
2284
+ const targetEntity = <span class="cstat-no" title="statement not covered" >row[getTableName(targetCollection)] || row;</span>
2285
+ const entityId = <span class="cstat-no" title="statement not covered" >targetEntity[idInfo[0].fieldName];</span>
2286
+ const parsedValues = <span class="cstat-no" title="statement not covered" >await parseDataFromServer(targetEntity, targetCollection, this.db, this.registry);</span>
2287
+ &nbsp;
2288
+ <span class="cstat-no" title="statement not covered" > entities.push({</span>
2289
+ id: entityId?.toString() || "",
2290
+ path: targetCollection.slug ?? targetCollection.dbPath,
2291
+ values: parsedValues as M
2292
+ });
2293
+ }
2294
+ &nbsp;
2295
+ <span class="cstat-no" title="statement not covered" > return entities;</span>
2296
+ }
2297
+ &nbsp;
2298
+ /**
2299
+ * Count related entities for a parent entity
2300
+ */
2301
+ <span class="fstat-no" title="function not covered" > async </span>countRelatedEntities&lt;M extends Record&lt;string, any&gt;&gt;(
2302
+ parentCollectionPath: string,
2303
+ parentEntityId: string | number,
2304
+ relationKey: string,
2305
+ options: { filter?: FilterValues&lt;Extract&lt;keyof M, string&gt;&gt;; databaseId?: string } = <span class="branch-0 cbranch-no" title="branch not covered" >{}</span>
2306
+ ): Promise&lt;number&gt; {
2307
+ const parentCollection = <span class="cstat-no" title="statement not covered" >getCollectionByPath(parentCollectionPath, this.registry);</span>
2308
+ const resolvedRelations = <span class="cstat-no" title="statement not covered" >resolveCollectionRelations(parentCollection);</span>
2309
+ const relation = <span class="cstat-no" title="statement not covered" >resolvedRelations[relationKey];</span>
2310
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!relation) <span class="cstat-no" title="statement not covered" >throw new Error(`Relation '${relationKey}' not found in collection '${parentCollectionPath}'`);</span></span>
2311
+ &nbsp;
2312
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
2313
+ const targetTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(targetCollection, this.registry);</span>
2314
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2315
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2316
+ const targetIdField = <span class="cstat-no" title="statement not covered" >targetTable[targetIdInfo.fieldName as keyof typeof targetTable] as AnyPgColumn;</span>
2317
+ &nbsp;
2318
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(parentCollection, this.registry);</span>
2319
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2320
+ const parsedParentIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(parentEntityId, parentPks);</span>
2321
+ const parsedParentId = <span class="cstat-no" title="statement not covered" >parsedParentIdObj[parentIdInfo.fieldName];</span>
2322
+ const parentTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(getTableName(parentCollection));</span>
2323
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!parentTable) <span class="cstat-no" title="statement not covered" >throw new Error("Parent table not found");</span></span>
2324
+ const parentIdCol = <span class="cstat-no" title="statement not covered" >parentTable[parentIdInfo.fieldName as keyof typeof parentTable] as AnyPgColumn;</span>
2325
+ &nbsp;
2326
+ // Start count with distinct to avoid duplicates from junction tables
2327
+ let query = <span class="cstat-no" title="statement not covered" >this.db.select({ count: sql&lt;number&gt;`count(distinct ${targetIdField})` }).from(targetTable).$dynamic();</span>
2328
+ &nbsp;
2329
+ // Build additional filter conditions
2330
+ const additionalFilters: SQL[] = <span class="cstat-no" title="statement not covered" >[];</span>
2331
+ &nbsp;
2332
+ // Use unified count query builder from DrizzleConditionBuilder
2333
+ <span class="cstat-no" title="statement not covered" > query = DrizzleConditionBuilder.buildRelationCountQuery(</span>
2334
+ query,
2335
+ relation,
2336
+ parsedParentId,
2337
+ targetTable,
2338
+ parentTable,
2339
+ parentIdCol,
2340
+ targetIdField,
2341
+ this.registry,
2342
+ additionalFilters
2343
+ );
2344
+ &nbsp;
2345
+ const result = <span class="cstat-no" title="statement not covered" >await query;</span>
2346
+ <span class="cstat-no" title="statement not covered" > return Number(result[0]?.count || 0);</span>
2347
+ }
2348
+ &nbsp;
2349
+ /**
2350
+ * Batch fetch related entities for multiple parent entities to avoid N+1 queries
2351
+ */
2352
+ <span class="fstat-no" title="function not covered" > async </span>batchFetchRelatedEntities(
2353
+ parentCollectionPath: string,
2354
+ parentEntityIds: (string | number)[],
2355
+ _relationKey: string,
2356
+ relation: Relation
2357
+ ): Promise&lt;Map&lt;string | number, Entity&lt;Record&lt;string, unknown&gt;&gt;&gt;&gt; {
2358
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (parentEntityIds.length === 0) <span class="cstat-no" title="statement not covered" >return new Map();</span></span>
2359
+ &nbsp;
2360
+ const parentCollection = <span class="cstat-no" title="statement not covered" >getCollectionByPath(parentCollectionPath, this.registry);</span>
2361
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
2362
+ const targetTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(targetCollection, this.registry);</span>
2363
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2364
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2365
+ const targetIdField = <span class="cstat-no" title="statement not covered" >targetTable[targetIdInfo.fieldName as keyof typeof targetTable] as AnyPgColumn;</span>
2366
+ &nbsp;
2367
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(parentCollection, this.registry);</span>
2368
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2369
+ const parentTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(getTableName(parentCollection));</span>
2370
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!parentTable) <span class="cstat-no" title="statement not covered" >throw new Error("Parent table not found");</span></span>
2371
+ const parentIdCol = <span class="cstat-no" title="statement not covered" >parentTable[parentIdInfo.fieldName as keyof typeof parentTable] as AnyPgColumn;</span>
2372
+ &nbsp;
2373
+ // Parse all parent IDs once
2374
+ const parsedParentIds = <span class="cstat-no" title="statement not covered" >parentEntityIds.map(<span class="fstat-no" title="function not covered" >id </span>=&gt; <span class="cstat-no" title="statement not covered" >parseIdValues(id, parentPks)[parentIdInfo.fieldName])</span>;</span>
2375
+ &nbsp;
2376
+ // Handle join path relations with batching
2377
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (relation.joinPath &amp;&amp; relation.joinPath.length &gt; 0) {</span>
2378
+ let query = <span class="cstat-no" title="statement not covered" >this.db.select().from(parentTable).$dynamic();</span>
2379
+ let currentTable = <span class="cstat-no" title="statement not covered" >parentTable;</span>
2380
+ &nbsp;
2381
+ // Apply each join in the path
2382
+ <span class="cstat-no" title="statement not covered" > for (const join of relation.joinPath) {</span>
2383
+ const joinTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(join.table);</span>
2384
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!joinTable) {</span>
2385
+ <span class="cstat-no" title="statement not covered" > throw new Error(`Join table not found: ${join.table}`);</span>
2386
+ }
2387
+ &nbsp;
2388
+ const fromColumn = <span class="cstat-no" title="statement not covered" >Array.isArray(join.on.from) ? join.on.from[0] : join.on.from;</span>
2389
+ const toColumn = <span class="cstat-no" title="statement not covered" >Array.isArray(join.on.to) ? join.on.to[0] : join.on.to;</span>
2390
+ &nbsp;
2391
+ const fromParts = <span class="cstat-no" title="statement not covered" >fromColumn.split(".");</span>
2392
+ const toParts = <span class="cstat-no" title="statement not covered" >toColumn.split(".");</span>
2393
+ &nbsp;
2394
+ const fromColName = <span class="cstat-no" title="statement not covered" >fromParts[fromParts.length - 1];</span>
2395
+ const toColName = <span class="cstat-no" title="statement not covered" >toParts[toParts.length - 1];</span>
2396
+ &nbsp;
2397
+ const fromCol = <span class="cstat-no" title="statement not covered" >currentTable[fromColName as keyof typeof currentTable] as AnyPgColumn;</span>
2398
+ const toCol = <span class="cstat-no" title="statement not covered" >joinTable[toColName as keyof typeof joinTable] as AnyPgColumn;</span>
2399
+ &nbsp;
2400
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fromCol || !toCol) {</span>
2401
+ <span class="cstat-no" title="statement not covered" > throw new Error(`Join columns not found: ${fromColumn} -&gt; ${toColumn}`);</span>
2402
+ }
2403
+ &nbsp;
2404
+ // @ts-expect-error Drizzle mutates base query generic on innerJoin
2405
+ <span class="cstat-no" title="statement not covered" > query = query.innerJoin(joinTable, eq(fromCol, toCol));</span>
2406
+ <span class="cstat-no" title="statement not covered" > currentTable = joinTable;</span>
2407
+ }
2408
+ &nbsp;
2409
+ // Add where condition for ALL parent entities at once
2410
+ const parentIdField = <span class="cstat-no" title="statement not covered" >parentTable[getPrimaryKeys(parentCollection, this.registry)[0].fieldName as keyof typeof parentTable] as AnyPgColumn;</span>
2411
+ <span class="cstat-no" title="statement not covered" > query = query.where(inArray(parentIdField, parsedParentIds));</span>
2412
+ &nbsp;
2413
+ const results = <span class="cstat-no" title="statement not covered" >await query;</span>
2414
+ const targetTableName = <span class="cstat-no" title="statement not covered" >relation.joinPath[relation.joinPath.length - 1].table;</span>
2415
+ const resultMap = <span class="cstat-no" title="statement not covered" >new Map&lt;string | number, Entity&lt;Record&lt;string, unknown&gt;&gt;&gt;();</span>
2416
+ &nbsp;
2417
+ // Group results by parent ID
2418
+ <span class="cstat-no" title="statement not covered" > results.forEach(<span class="fstat-no" title="function not covered" >(r</span>ow: Record&lt;string, unknown&gt;) =&gt; {</span>
2419
+ const parentEntity = (<span class="cstat-no" title="statement not covered" >row[getTableName(parentCollection)] || row)</span> as Record&lt;string, unknown&gt;;
2420
+ const targetEntity = (<span class="cstat-no" title="statement not covered" >row[targetTableName] || row)</span> as Record&lt;string, unknown&gt;;
2421
+ const parentId = <span class="cstat-no" title="statement not covered" >parentEntity[parentIdInfo.fieldName] as string | number;</span>
2422
+ &nbsp;
2423
+ <span class="cstat-no" title="statement not covered" > resultMap.set(parentId, {</span>
2424
+ id: String(targetEntity[targetIdInfo.fieldName]),
2425
+ path: targetCollection.slug ?? targetCollection.dbPath,
2426
+ values: targetEntity
2427
+ });
2428
+ });
2429
+ &nbsp;
2430
+ <span class="cstat-no" title="statement not covered" > return resultMap;</span>
2431
+ }
2432
+ &nbsp;
2433
+ // Handle other relation types with batching
2434
+ let query = <span class="cstat-no" title="statement not covered" >this.db.select().from(targetTable).$dynamic();</span>
2435
+ &nbsp;
2436
+ // Build the relation query with ALL parent IDs
2437
+ // @ts-expect-error buildRelationQuery uses dynamic queries
2438
+ <span class="cstat-no" title="statement not covered" > query = DrizzleConditionBuilder.buildRelationQuery(</span>
2439
+ query,
2440
+ relation,
2441
+ parsedParentIds, // Pass array instead of single ID
2442
+ targetTable,
2443
+ parentTable,
2444
+ parentIdCol,
2445
+ targetIdField,
2446
+ this.registry,
2447
+ []
2448
+ );
2449
+ &nbsp;
2450
+ const results = <span class="cstat-no" title="statement not covered" >await query;</span>
2451
+ const resultMap = <span class="cstat-no" title="statement not covered" >new Map&lt;string | number, Entity&lt;Record&lt;string, unknown&gt;&gt;&gt;();</span>
2452
+ &nbsp;
2453
+ // Map results back to parent entities
2454
+ <span class="cstat-no" title="statement not covered" > results.forEach(<span class="fstat-no" title="function not covered" >(r</span>ow: Record&lt;string, unknown&gt;) =&gt; {</span>
2455
+ const targetEntity = (<span class="cstat-no" title="statement not covered" >row[getTableName(targetCollection)] || row)</span> as Record&lt;string, unknown&gt;;
2456
+ &nbsp;
2457
+ // Determine the parent ID this result belongs to based on the relation type
2458
+ let parentId: string | number | undefined;
2459
+ &nbsp;
2460
+ <span class="cstat-no" title="statement not covered" > if (relation.direction === "inverse" &amp;&amp; relation.foreignKeyOnTarget) {</span>
2461
+ <span class="cstat-no" title="statement not covered" > parentId = targetEntity[relation.foreignKeyOnTarget] as string | number | undefined;</span>
2462
+ } else <span class="cstat-no" title="statement not covered" >if (relation.direction === "inverse" &amp;&amp; relation.cardinality === "one" &amp;&amp; relation.inverseRelationName) {</span>
2463
+ const inferredForeignKeyName = <span class="cstat-no" title="statement not covered" >`${relation.inverseRelationName}_id`;</span>
2464
+ <span class="cstat-no" title="statement not covered" > parentId = targetEntity[inferredForeignKeyName] as string | number | undefined;</span>
2465
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span>if (relation.direction === "owning" &amp;&amp; relation.localKey) {</span>
2466
+ <span class="cstat-no" title="statement not covered" > for (const parsedParentId of parsedParentIds) {</span>
2467
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!resultMap.has(parsedParentId)) {</span>
2468
+ <span class="cstat-no" title="statement not covered" > parentId = parsedParentId;</span>
2469
+ <span class="cstat-no" title="statement not covered" > break;</span>
2470
+ }
2471
+ }
2472
+ }
2473
+ &nbsp;
2474
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (parentId !== undefined &amp;&amp; parsedParentIds.includes(parentId)) {</span>
2475
+ <span class="cstat-no" title="statement not covered" > resultMap.set(parentId, {</span>
2476
+ id: String(targetEntity[targetIdInfo.fieldName]),
2477
+ path: targetCollection.slug ?? targetCollection.dbPath,
2478
+ values: targetEntity
2479
+ });
2480
+ }
2481
+ });
2482
+ &nbsp;
2483
+ <span class="cstat-no" title="statement not covered" > return resultMap;</span>
2484
+ }
2485
+ &nbsp;
2486
+ /**
2487
+ * Update many-to-many and junction relations
2488
+ */
2489
+ <span class="fstat-no" title="function not covered" > async </span>updateRelationsUsingJoins&lt;M extends Record&lt;string, any&gt;&gt;(
2490
+ tx: DrizzleClient,
2491
+ collection: EntityCollection,
2492
+ entityId: string | number,
2493
+ relationValues: Partial&lt;M&gt;
2494
+ ) {
2495
+ const resolvedRelations = <span class="cstat-no" title="statement not covered" >resolveCollectionRelations(collection);</span>
2496
+ &nbsp;
2497
+ <span class="cstat-no" title="statement not covered" > for (const [key, value] of Object.entries(relationValues)) {</span>
2498
+ const relation = <span class="cstat-no" title="statement not covered" >resolvedRelations[key];</span>
2499
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!relation || relation.cardinality !== "many") <span class="cstat-no" title="statement not covered" >continue;</span></span>
2500
+ &nbsp;
2501
+ const targetEntityIds = <span class="cstat-no" title="statement not covered" >(value &amp;&amp; Array.isArray(value)) ? value.map(<span class="fstat-no" title="function not covered" >(r</span>el: { id: string | number }) =&gt; <span class="cstat-no" title="statement not covered" >rel.id)</span> : [];</span>
2502
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
2503
+ &nbsp;
2504
+ // Use joinPath if available
2505
+ <span class="cstat-no" title="statement not covered" > if (relation.joinPath &amp;&amp; relation.joinPath.length &gt; 0) {</span>
2506
+ const parentTableName = <span class="cstat-no" title="statement not covered" >getTableName(collection);</span>
2507
+ const targetTableName = <span class="cstat-no" title="statement not covered" >getTableName(targetCollection);</span>
2508
+ &nbsp;
2509
+ let junctionTable: PgTable | undefined = <span class="cstat-no" title="statement not covered" >undefined;</span>
2510
+ let sourceJunctionColumn: AnyPgColumn | null = <span class="cstat-no" title="statement not covered" >null;</span>
2511
+ let targetJunctionColumn: AnyPgColumn | null = <span class="cstat-no" title="statement not covered" >null;</span>
2512
+ &nbsp;
2513
+ const junctionTableName = <span class="cstat-no" title="statement not covered" >relation.joinPath.find(<span class="fstat-no" title="function not covered" >step </span>=&gt;</span>
2514
+ <span class="cstat-no" title="statement not covered" > step.table !== parentTableName &amp;&amp; step.table !== targetTableName</span>
2515
+ )?.table;
2516
+ &nbsp;
2517
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (junctionTableName) {</span>
2518
+ <span class="cstat-no" title="statement not covered" > junctionTable = this.registry.getTable(junctionTableName);</span>
2519
+ &nbsp;
2520
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (junctionTable) {</span>
2521
+ <span class="cstat-no" title="statement not covered" > for (const joinStep of relation.joinPath) {</span>
2522
+ const fromTable = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getTableNamesFromColumns(joinStep.on.from)[0];</span>
2523
+ const toTable = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getTableNamesFromColumns(joinStep.on.to)[0];</span>
2524
+ &nbsp;
2525
+ <span class="cstat-no" title="statement not covered" > if (fromTable === parentTableName &amp;&amp; toTable === junctionTableName) {</span>
2526
+ const columnNames = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(joinStep.on.to);</span>
2527
+ <span class="cstat-no" title="statement not covered" > sourceJunctionColumn = junctionTable[columnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2528
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span>if (fromTable === junctionTableName &amp;&amp; toTable === parentTableName) {</span>
2529
+ const columnNames = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(joinStep.on.from);</span>
2530
+ <span class="cstat-no" title="statement not covered" > sourceJunctionColumn = junctionTable[columnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2531
+ }
2532
+ &nbsp;
2533
+ <span class="cstat-no" title="statement not covered" > if (fromTable === junctionTableName &amp;&amp; toTable === targetTableName) {</span>
2534
+ const columnNames = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(joinStep.on.from);</span>
2535
+ <span class="cstat-no" title="statement not covered" > targetJunctionColumn = junctionTable[columnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2536
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span>if (fromTable === targetTableName &amp;&amp; toTable === junctionTableName) {</span>
2537
+ const columnNames = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(joinStep.on.to);</span>
2538
+ <span class="cstat-no" title="statement not covered" > targetJunctionColumn = junctionTable[columnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2539
+ }
2540
+ }
2541
+ }
2542
+ }
2543
+ &nbsp;
2544
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!junctionTable || !sourceJunctionColumn || !targetJunctionColumn) {</span>
2545
+ <span class="cstat-no" title="statement not covered" > console.warn(`Could not determine junction table for relation '${key}' in collection '${collection.slug || collection.dbPath}'`);</span>
2546
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2547
+ }
2548
+ &nbsp;
2549
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(collection, this.registry);</span>
2550
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2551
+ const parsedParentIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(entityId, parentPks);</span>
2552
+ const parsedParentId = <span class="cstat-no" title="statement not covered" >parsedParentIdObj[parentIdInfo.fieldName];</span>
2553
+ &nbsp;
2554
+ // Delete existing relations for this entity
2555
+ <span class="cstat-no" title="statement not covered" > await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedParentId));</span>
2556
+ &nbsp;
2557
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (targetEntityIds.length &gt; 0) {</span>
2558
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2559
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2560
+ const parsedTargetIds = <span class="cstat-no" title="statement not covered" >targetEntityIds.map(<span class="fstat-no" title="function not covered" >id </span>=&gt; <span class="cstat-no" title="statement not covered" >parseIdValues(id, targetPks)[targetIdInfo.fieldName])</span>;</span>
2561
+ &nbsp;
2562
+ const newLinks = <span class="cstat-no" title="statement not covered" >parsedTargetIds.map(<span class="fstat-no" title="function not covered" >targetId </span>=&gt; (<span class="cstat-no" title="statement not covered" >{</span></span>
2563
+ [sourceJunctionColumn.name]: parsedParentId,
2564
+ [targetJunctionColumn.name]: targetId
2565
+ }));
2566
+ &nbsp;
2567
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (newLinks.length &gt; 0) {</span>
2568
+ <span class="cstat-no" title="statement not covered" > await tx.insert(junctionTable).values(newLinks);</span>
2569
+ }
2570
+ }
2571
+ } else <span class="cstat-no" title="statement not covered" >if (relation.through &amp;&amp; relation.cardinality === "many" &amp;&amp; relation.direction === "owning") {</span>
2572
+ // Handle many-to-many relations with junction table using 'through' property
2573
+ const junctionTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(relation.through.table);</span>
2574
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!junctionTable) {</span>
2575
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction table '${relation.through.table}' not found for relation '${key}' in collection '${collection.slug || collection.dbPath}'`);</span>
2576
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2577
+ }
2578
+ &nbsp;
2579
+ const sourceJunctionColumn = <span class="cstat-no" title="statement not covered" >junctionTable[relation.through.sourceColumn as keyof typeof junctionTable] as AnyPgColumn;</span>
2580
+ const targetJunctionColumn = <span class="cstat-no" title="statement not covered" >junctionTable[relation.through.targetColumn as keyof typeof junctionTable] as AnyPgColumn;</span>
2581
+ &nbsp;
2582
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!sourceJunctionColumn || !targetJunctionColumn) {</span>
2583
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction columns not found for relation '${key}'`);</span>
2584
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2585
+ }
2586
+ &nbsp;
2587
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(collection, this.registry);</span>
2588
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2589
+ const parsedParentIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(entityId, parentPks);</span>
2590
+ const parsedParentId = <span class="cstat-no" title="statement not covered" >parsedParentIdObj[parentIdInfo.fieldName];</span>
2591
+ &nbsp;
2592
+ // Delete existing relations for this entity
2593
+ <span class="cstat-no" title="statement not covered" > await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedParentId));</span>
2594
+ &nbsp;
2595
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (targetEntityIds.length &gt; 0) {</span>
2596
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2597
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2598
+ const parsedTargetIds = <span class="cstat-no" title="statement not covered" >targetEntityIds.map(<span class="fstat-no" title="function not covered" >id </span>=&gt; <span class="cstat-no" title="statement not covered" >parseIdValues(id, targetPks)[targetIdInfo.fieldName])</span>;</span>
2599
+ &nbsp;
2600
+ const newLinks = <span class="cstat-no" title="statement not covered" >parsedTargetIds.map(<span class="fstat-no" title="function not covered" >targetId </span>=&gt; (<span class="cstat-no" title="statement not covered" >{</span></span>
2601
+ [sourceJunctionColumn.name]: parsedParentId,
2602
+ [targetJunctionColumn.name]: targetId
2603
+ }));
2604
+ &nbsp;
2605
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (newLinks.length &gt; 0) {</span>
2606
+ <span class="cstat-no" title="statement not covered" > await tx.insert(junctionTable).values(newLinks);</span>
2607
+ }
2608
+ }
2609
+ } else <span class="cstat-no" title="statement not covered" >if (relation.cardinality === "many" &amp;&amp; relation.direction === "inverse" &amp;&amp; relation.foreignKeyOnTarget) {</span>
2610
+ // Handle one-to-many (inverse) by updating target FK to point to parent
2611
+ const targetTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(targetCollection, this.registry);</span>
2612
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2613
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2614
+ const targetIdCol = <span class="cstat-no" title="statement not covered" >targetTable[targetIdInfo.fieldName as keyof typeof targetTable] as AnyPgColumn;</span>
2615
+ const fkCol = <span class="cstat-no" title="statement not covered" >targetTable[relation.foreignKeyOnTarget as keyof typeof targetTable] as AnyPgColumn;</span>
2616
+ &nbsp;
2617
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!fkCol || !targetIdCol) {</span>
2618
+ <span class="cstat-no" title="statement not covered" > console.warn(`Invalid inverse-many config for relation '${key}' in collection '${collection.slug || collection.dbPath}'`);</span>
2619
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2620
+ }
2621
+ &nbsp;
2622
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(collection, this.registry);</span>
2623
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2624
+ const parsedParentIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(entityId, parentPks);</span>
2625
+ const parsedParentId = <span class="cstat-no" title="statement not covered" >parsedParentIdObj[parentIdInfo.fieldName];</span>
2626
+ &nbsp;
2627
+ // Clear existing links not in the new set
2628
+ <span class="cstat-no" title="statement not covered" > if (targetEntityIds.length &gt; 0) {</span>
2629
+ const parsedTargetIds = <span class="cstat-no" title="statement not covered" >targetEntityIds.map(<span class="fstat-no" title="function not covered" >id </span>=&gt; <span class="cstat-no" title="statement not covered" >parseIdValues(id, targetPks)[targetIdInfo.fieldName])</span>;</span>
2630
+ <span class="cstat-no" title="statement not covered" > await tx</span>
2631
+ .update(targetTable)
2632
+ .set({ [relation.foreignKeyOnTarget]: null })
2633
+ .where(and(eq(fkCol, parsedParentId), sql`${targetIdCol} NOT IN (${sql.join(parsedTargetIds)})`));
2634
+ &nbsp;
2635
+ // Set FK for the provided targets
2636
+ <span class="cstat-no" title="statement not covered" > await tx</span>
2637
+ .update(targetTable)
2638
+ .set({ [relation.foreignKeyOnTarget]: parsedParentId })
2639
+ .where(inArray(targetIdCol as AnyPgColumn, parsedTargetIds as unknown[]));
2640
+ } else {
2641
+ // If empty array provided, clear all existing links for this parent
2642
+ <span class="cstat-no" title="statement not covered" > await tx</span>
2643
+ .update(targetTable)
2644
+ .set({ [relation.foreignKeyOnTarget]: null })
2645
+ .where(eq(fkCol, parsedParentId));
2646
+ }
2647
+ } else {
2648
+ <span class="cstat-no" title="statement not covered" > console.warn(`Many relation '${key}' in collection '${collection.slug || collection.dbPath}' lacks write configuration and will be skipped during save.`);</span>
2649
+ }
2650
+ }
2651
+ }
2652
+ &nbsp;
2653
+ /**
2654
+ * Update inverse relations (where FK is on the target table)
2655
+ */
2656
+ <span class="fstat-no" title="function not covered" > async </span>updateInverseRelations(
2657
+ tx: DrizzleClient,
2658
+ sourceCollection: EntityCollection,
2659
+ sourceEntityId: string | number,
2660
+ inverseRelationUpdates: Array&lt;{
2661
+ relationKey: string;
2662
+ relation: Relation;
2663
+ newValue: unknown;
2664
+ currentEntityId?: string | number;
2665
+ }&gt;
2666
+ ) {
2667
+ <span class="cstat-no" title="statement not covered" > for (const update of inverseRelationUpdates) {</span>
2668
+ const { relation, newValue } = <span class="cstat-no" title="statement not covered" >update;</span>
2669
+ &nbsp;
2670
+ <span class="cstat-no" title="statement not covered" > try {</span>
2671
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
2672
+ const targetTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(targetCollection, this.registry);</span>
2673
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2674
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2675
+ const sourcePks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(sourceCollection, this.registry);</span>
2676
+ const sourceIdInfo = <span class="cstat-no" title="statement not covered" >sourcePks[0];</span>
2677
+ &nbsp;
2678
+ // Handle inverse relations with joinPath
2679
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (relation.direction === "inverse" &amp;&amp; relation.joinPath &amp;&amp; relation.joinPath.length &gt; 0) {</span>
2680
+ <span class="cstat-no" title="statement not covered" > await this.updateInverseJoinPathRelation(</span>
2681
+ tx,
2682
+ sourceCollection,
2683
+ sourceEntityId,
2684
+ targetCollection,
2685
+ relation,
2686
+ newValue
2687
+ );
2688
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2689
+ }
2690
+ &nbsp;
2691
+ // Check if this is a many-to-many inverse relation
2692
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (relation.cardinality === "many" &amp;&amp; relation.direction === "inverse") {</span>
2693
+ const targetCollectionRelations = <span class="cstat-no" title="statement not covered" >resolveCollectionRelations(targetCollection);</span>
2694
+ let junctionInfo: { table: string; sourceColumn: string; targetColumn: string } | null = <span class="cstat-no" title="statement not covered" >null;</span>
2695
+ &nbsp;
2696
+ <span class="cstat-no" title="statement not covered" > for (const [relationKey, targetRelation] of Object.entries(targetCollectionRelations)) {</span>
2697
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (targetRelation.cardinality === "many" &amp;&amp;</span>
2698
+ targetRelation.direction === "owning" &amp;&amp;
2699
+ targetRelation.through &amp;&amp;
2700
+ (targetRelation.relationName === relation.inverseRelationName || relationKey === relation.inverseRelationName)) {
2701
+ <span class="cstat-no" title="statement not covered" > junctionInfo = {</span>
2702
+ table: targetRelation.through.table,
2703
+ sourceColumn: targetRelation.through.targetColumn,
2704
+ targetColumn: targetRelation.through.sourceColumn
2705
+ };
2706
+ <span class="cstat-no" title="statement not covered" > break;</span>
2707
+ }
2708
+ }
2709
+ &nbsp;
2710
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (junctionInfo) {</span>
2711
+ <span class="cstat-no" title="statement not covered" > await this.updateManyToManyInverseRelation(</span>
2712
+ tx,
2713
+ sourceCollection,
2714
+ sourceEntityId,
2715
+ targetCollection,
2716
+ relation,
2717
+ newValue,
2718
+ junctionInfo
2719
+ );
2720
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2721
+ }
2722
+ }
2723
+ &nbsp;
2724
+ // Handle simple inverse relations
2725
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!relation.foreignKeyOnTarget) {</span>
2726
+ <span class="cstat-no" title="statement not covered" > console.warn(`Inverse relation '${relation.relationName}' is missing foreignKeyOnTarget property. Skipping.`);</span>
2727
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2728
+ }
2729
+ &nbsp;
2730
+ const foreignKeyColumn = <span class="cstat-no" title="statement not covered" >targetTable[relation.foreignKeyOnTarget! as keyof typeof targetTable] as AnyPgColumn;</span>
2731
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!foreignKeyColumn) {</span>
2732
+ <span class="cstat-no" title="statement not covered" > console.warn(`Foreign key column '${relation.foreignKeyOnTarget}' not found in target table for relation '${relation.relationName}'`);</span>
2733
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2734
+ }
2735
+ &nbsp;
2736
+ const parsedSourceIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(sourceEntityId, sourcePks);</span>
2737
+ const parsedSourceId = <span class="cstat-no" title="statement not covered" >parsedSourceIdObj[sourceIdInfo.fieldName];</span>
2738
+ &nbsp;
2739
+ <span class="cstat-no" title="statement not covered" > if (newValue === null || newValue === undefined) {</span>
2740
+ <span class="cstat-no" title="statement not covered" > await tx</span>
2741
+ .update(targetTable)
2742
+ .set({ [relation.foreignKeyOnTarget!]: null })
2743
+ .where(eq(foreignKeyColumn, parsedSourceId));
2744
+ } else {
2745
+ const parsedNewTargetIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(newValue as string | number, targetPks);</span>
2746
+ const parsedNewTargetId = <span class="cstat-no" title="statement not covered" >parsedNewTargetIdObj[targetIdInfo.fieldName];</span>
2747
+ const targetIdField = <span class="cstat-no" title="statement not covered" >targetTable[targetIdInfo.fieldName as keyof typeof targetTable] as AnyPgColumn;</span>
2748
+ &nbsp;
2749
+ // First, clear any existing FK that points to this source entity
2750
+ <span class="cstat-no" title="statement not covered" > await tx</span>
2751
+ .update(targetTable)
2752
+ .set({ [relation.foreignKeyOnTarget!]: null })
2753
+ .where(eq(foreignKeyColumn, parsedSourceId));
2754
+ &nbsp;
2755
+ // Then, update the new target entity to point to this source entity
2756
+ <span class="cstat-no" title="statement not covered" > await tx</span>
2757
+ .update(targetTable)
2758
+ .set({ [relation.foreignKeyOnTarget!]: parsedSourceId })
2759
+ .where(eq(targetIdField, parsedNewTargetId));
2760
+ }
2761
+ } catch (e) {
2762
+ <span class="cstat-no" title="statement not covered" > console.warn(`Failed to update inverse relation '${relation.relationName}':`, e);</span>
2763
+ }
2764
+ }
2765
+ }
2766
+ &nbsp;
2767
+ /**
2768
+ * Handle inverse relations with joinPath
2769
+ */
2770
+ private <span class="fstat-no" title="function not covered" >async </span>updateInverseJoinPathRelation(
2771
+ tx: DrizzleClient,
2772
+ sourceCollection: EntityCollection,
2773
+ sourceEntityId: string | number,
2774
+ targetCollection: EntityCollection,
2775
+ relation: Relation,
2776
+ newValue: unknown
2777
+ ) {
2778
+ <span class="cstat-no" title="statement not covered" > try {</span>
2779
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!relation.joinPath || relation.joinPath.length === 0) {</span>
2780
+ <span class="cstat-no" title="statement not covered" > console.warn(`Inverse relation '${relation.relationName}' missing joinPath`);</span>
2781
+ <span class="cstat-no" title="statement not covered" > return;</span>
2782
+ }
2783
+ &nbsp;
2784
+ const sourceTableName = <span class="cstat-no" title="statement not covered" >getTableName(sourceCollection);</span>
2785
+ const targetTableName = <span class="cstat-no" title="statement not covered" >getTableName(targetCollection);</span>
2786
+ &nbsp;
2787
+ // Find intermediate tables that are neither source nor target
2788
+ const intermediateTables = <span class="cstat-no" title="statement not covered" >relation.joinPath</span>
2789
+ .map(<span class="fstat-no" title="function not covered" >step </span>=&gt; <span class="cstat-no" title="statement not covered" >step.table)</span>
2790
+ .filter(<span class="fstat-no" title="function not covered" >table </span>=&gt; <span class="cstat-no" title="statement not covered" >table !== sourceTableName &amp;&amp; table !== targetTableName)</span>;
2791
+ &nbsp;
2792
+ // If there's exactly one intermediate table, it's likely a junction table for many-to-many
2793
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (intermediateTables.length === 1 &amp;&amp; relation.cardinality === "many") {</span>
2794
+ const junctionTableName = <span class="cstat-no" title="statement not covered" >intermediateTables[0];</span>
2795
+ const junctionTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(junctionTableName);</span>
2796
+ &nbsp;
2797
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!junctionTable) {</span>
2798
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction table '${junctionTableName}' not found for inverse joinPath relation '${relation.relationName}'`);</span>
2799
+ <span class="cstat-no" title="statement not covered" > return;</span>
2800
+ }
2801
+ &nbsp;
2802
+ let sourceJunctionColumn: AnyPgColumn | null = <span class="cstat-no" title="statement not covered" >null;</span>
2803
+ let targetJunctionColumn: AnyPgColumn | null = <span class="cstat-no" title="statement not covered" >null;</span>
2804
+ &nbsp;
2805
+ <span class="cstat-no" title="statement not covered" > for (const step of relation.joinPath) {</span>
2806
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (step.table === junctionTableName) {</span>
2807
+ const fromTable = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getTableNamesFromColumns(step.on.from)[0];</span>
2808
+ const toColumnNames = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(step.on.to);</span>
2809
+ const fromColumnNames = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(step.on.from);</span>
2810
+ &nbsp;
2811
+ <span class="cstat-no" title="statement not covered" > if (fromTable === sourceTableName) {</span>
2812
+ <span class="cstat-no" title="statement not covered" > sourceJunctionColumn = junctionTable[toColumnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2813
+ } else <span class="cstat-no" title="statement not covered" >if (fromTable === targetTableName) {</span>
2814
+ <span class="cstat-no" title="statement not covered" > targetJunctionColumn = junctionTable[toColumnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2815
+ } else {
2816
+ const toTable = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getTableNamesFromColumns(step.on.to)[0];</span>
2817
+ <span class="cstat-no" title="statement not covered" > if (toTable === sourceTableName) {</span>
2818
+ <span class="cstat-no" title="statement not covered" > sourceJunctionColumn = junctionTable[fromColumnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2819
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span>if (toTable === targetTableName) {</span>
2820
+ <span class="cstat-no" title="statement not covered" > targetJunctionColumn = junctionTable[fromColumnNames[0] as keyof typeof junctionTable] as AnyPgColumn;</span>
2821
+ }
2822
+ }
2823
+ }
2824
+ }
2825
+ &nbsp;
2826
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!sourceJunctionColumn || !targetJunctionColumn) {</span>
2827
+ <span class="cstat-no" title="statement not covered" > console.warn(`Could not determine junction columns for inverse joinPath relation '${relation.relationName}'`);</span>
2828
+ <span class="cstat-no" title="statement not covered" > return;</span>
2829
+ }
2830
+ &nbsp;
2831
+ // Perform the junction table update
2832
+ const sourcePks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(sourceCollection, this.registry);</span>
2833
+ const sourceIdInfo = <span class="cstat-no" title="statement not covered" >sourcePks[0];</span>
2834
+ const parsedSourceIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(sourceEntityId, sourcePks);</span>
2835
+ const parsedSourceId = <span class="cstat-no" title="statement not covered" >parsedSourceIdObj[sourceIdInfo.fieldName];</span>
2836
+ &nbsp;
2837
+ // Clear existing entries for this source entity
2838
+ <span class="cstat-no" title="statement not covered" > await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedSourceId));</span>
2839
+ &nbsp;
2840
+ // Add new entries if newValue is provided
2841
+ <span class="cstat-no" title="statement not covered" > if (newValue &amp;&amp; Array.isArray(newValue) &amp;&amp; newValue.length &gt; 0) {</span>
2842
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2843
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2844
+ const targetEntityIds = (<span class="cstat-no" title="statement not covered" >newValue as Array&lt;{ id: string | number } | string | number&gt;).map(<span class="fstat-no" title="function not covered" >(r</span>el) =&gt; <span class="cstat-no" title="statement not covered" >typeof rel === 'object' &amp;&amp; rel !== null ? rel.id : rel)</span>;</span>
2845
+ const parsedTargetIds = <span class="cstat-no" title="statement not covered" >targetEntityIds.map(<span class="fstat-no" title="function not covered" >id </span>=&gt; <span class="cstat-no" title="statement not covered" >parseIdValues(id, targetPks)[targetIdInfo.fieldName])</span>;</span>
2846
+ &nbsp;
2847
+ const newLinks = <span class="cstat-no" title="statement not covered" >parsedTargetIds.map(<span class="fstat-no" title="function not covered" >targetId </span>=&gt; (<span class="cstat-no" title="statement not covered" >{</span></span>
2848
+ [sourceJunctionColumn!.name]: parsedSourceId,
2849
+ [targetJunctionColumn!.name]: targetId
2850
+ }));
2851
+ &nbsp;
2852
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (newLinks.length &gt; 0) {</span>
2853
+ <span class="cstat-no" title="statement not covered" > await tx.insert(junctionTable).values(newLinks);</span>
2854
+ }
2855
+ } else <span class="cstat-no" title="statement not covered" ><span class="missing-if-branch" title="if path not taken" >I</span>if (newValue &amp;&amp; !Array.isArray(newValue)) {</span>
2856
+ // Single value for one-to-one
2857
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2858
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2859
+ const targetId = <span class="cstat-no" title="statement not covered" >typeof newValue === 'object' &amp;&amp; newValue !== null ? (newValue as Record&lt;string, unknown&gt;).id as string | number : newValue as string | number;</span>
2860
+ const parsedTargetIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(targetId, targetPks);</span>
2861
+ const parsedTargetId = <span class="cstat-no" title="statement not covered" >parsedTargetIdObj[targetIdInfo.fieldName];</span>
2862
+ &nbsp;
2863
+ const newLink = <span class="cstat-no" title="statement not covered" >{</span>
2864
+ [sourceJunctionColumn.name]: parsedSourceId,
2865
+ [targetJunctionColumn.name]: parsedTargetId
2866
+ };
2867
+ &nbsp;
2868
+ <span class="cstat-no" title="statement not covered" > await tx.insert(junctionTable).values(newLink);</span>
2869
+ }
2870
+ }
2871
+ } catch (error) {
2872
+ <span class="cstat-no" title="statement not covered" > console.error(`Failed to update inverse joinPath relation '${relation.relationName}':`, error);</span>
2873
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
2874
+ }
2875
+ }
2876
+ &nbsp;
2877
+ /**
2878
+ * Handle many-to-many inverse relation updates using junction tables
2879
+ */
2880
+ private <span class="fstat-no" title="function not covered" >async </span>updateManyToManyInverseRelation(
2881
+ tx: DrizzleClient,
2882
+ sourceCollection: EntityCollection,
2883
+ sourceEntityId: string | number,
2884
+ targetCollection: EntityCollection,
2885
+ relation: Relation,
2886
+ newValue: unknown,
2887
+ junctionInfo: { table: string; sourceColumn: string; targetColumn: string }
2888
+ ) {
2889
+ <span class="cstat-no" title="statement not covered" > try {</span>
2890
+ const junctionTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(junctionInfo.table);</span>
2891
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!junctionTable) {</span>
2892
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction table '${junctionInfo.table}' not found for many-to-many inverse relation '${relation.relationName}'`);</span>
2893
+ <span class="cstat-no" title="statement not covered" > return;</span>
2894
+ }
2895
+ &nbsp;
2896
+ const sourceJunctionColumn = <span class="cstat-no" title="statement not covered" >junctionTable[junctionInfo.sourceColumn as keyof typeof junctionTable] as AnyPgColumn;</span>
2897
+ const targetJunctionColumn = <span class="cstat-no" title="statement not covered" >junctionTable[junctionInfo.targetColumn as keyof typeof junctionTable] as AnyPgColumn;</span>
2898
+ &nbsp;
2899
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!sourceJunctionColumn || !targetJunctionColumn) {</span>
2900
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction columns not found for relation '${relation.relationName}'`);</span>
2901
+ <span class="cstat-no" title="statement not covered" > return;</span>
2902
+ }
2903
+ &nbsp;
2904
+ const sourcePks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(sourceCollection, this.registry);</span>
2905
+ const sourceIdInfo = <span class="cstat-no" title="statement not covered" >sourcePks[0];</span>
2906
+ const parsedSourceIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(sourceEntityId, sourcePks);</span>
2907
+ const parsedSourceId = <span class="cstat-no" title="statement not covered" >parsedSourceIdObj[sourceIdInfo.fieldName];</span>
2908
+ &nbsp;
2909
+ // Clear existing entries for this source entity
2910
+ <span class="cstat-no" title="statement not covered" > await tx.delete(junctionTable).where(eq(sourceJunctionColumn, parsedSourceId));</span>
2911
+ &nbsp;
2912
+ // Add new entries if newValue is provided
2913
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (newValue &amp;&amp; Array.isArray(newValue) &amp;&amp; newValue.length &gt; 0) {</span>
2914
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2915
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2916
+ const targetEntityIds = (<span class="cstat-no" title="statement not covered" >newValue as Array&lt;{ id: string | number }&gt;).map(<span class="fstat-no" title="function not covered" >(r</span>el) =&gt; <span class="cstat-no" title="statement not covered" >rel.id)</span>;</span>
2917
+ const parsedTargetIds = <span class="cstat-no" title="statement not covered" >targetEntityIds.map(<span class="fstat-no" title="function not covered" >id </span>=&gt; <span class="cstat-no" title="statement not covered" >parseIdValues(id, targetPks)[targetIdInfo.fieldName])</span>;</span>
2918
+ &nbsp;
2919
+ const newLinks = <span class="cstat-no" title="statement not covered" >parsedTargetIds.map(<span class="fstat-no" title="function not covered" >targetId </span>=&gt; (<span class="cstat-no" title="statement not covered" >{</span></span>
2920
+ [sourceJunctionColumn.name]: parsedSourceId,
2921
+ [targetJunctionColumn.name]: targetId
2922
+ }));
2923
+ &nbsp;
2924
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (newLinks.length &gt; 0) {</span>
2925
+ <span class="cstat-no" title="statement not covered" > await tx.insert(junctionTable).values(newLinks);</span>
2926
+ }
2927
+ }
2928
+ } catch (error) {
2929
+ <span class="cstat-no" title="statement not covered" > console.error(`Failed to update many-to-many inverse relation '${relation.relationName}':`, error);</span>
2930
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
2931
+ }
2932
+ }
2933
+ &nbsp;
2934
+ /**
2935
+ * Update one-to-one relations that use joinPath
2936
+ */
2937
+ <span class="fstat-no" title="function not covered" > async </span>updateJoinPathOneToOneRelations(
2938
+ tx: DrizzleClient,
2939
+ parentCollection: EntityCollection,
2940
+ parentEntityId: string | number,
2941
+ updates: Array&lt;{
2942
+ relationKey: string;
2943
+ relation: Relation;
2944
+ newTargetId: string | number | null;
2945
+ }&gt;
2946
+ ) {
2947
+ <span class="cstat-no" title="statement not covered" > for (const upd of updates) {</span>
2948
+ const { relation, newTargetId } = <span class="cstat-no" title="statement not covered" >upd;</span>
2949
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
2950
+ const targetTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(targetCollection, this.registry);</span>
2951
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
2952
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
2953
+ const targetIdCol = <span class="cstat-no" title="statement not covered" >targetTable[targetIdInfo.fieldName as keyof typeof targetTable] as AnyPgColumn;</span>
2954
+ &nbsp;
2955
+ // Determine mapping of columns
2956
+ const { targetFKColName, parentSourceColName } = <span class="cstat-no" title="statement not covered" >this.resolveJoinPathWriteMapping(parentCollection, relation);</span>
2957
+ const parentTable = <span class="cstat-no" title="statement not covered" >getTableForCollection(parentCollection, this.registry);</span>
2958
+ const parentPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(parentCollection, this.registry);</span>
2959
+ const parentIdInfo = <span class="cstat-no" title="statement not covered" >parentPks[0];</span>
2960
+ const parsedParentIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(parentEntityId, parentPks);</span>
2961
+ const parsedParentId = <span class="cstat-no" title="statement not covered" >parsedParentIdObj[parentIdInfo.fieldName];</span>
2962
+ &nbsp;
2963
+ const parentIdCol = <span class="cstat-no" title="statement not covered" >parentTable[parentIdInfo.fieldName as keyof typeof parentTable] as AnyPgColumn;</span>
2964
+ const parentSourceCol = <span class="cstat-no" title="statement not covered" >parentTable[parentSourceColName as keyof typeof parentTable] as AnyPgColumn;</span>
2965
+ const targetFKCol = <span class="cstat-no" title="statement not covered" >targetTable[targetFKColName as keyof typeof targetTable] as AnyPgColumn;</span>
2966
+ &nbsp;
2967
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!parentSourceCol) {</span>
2968
+ <span class="cstat-no" title="statement not covered" > console.warn(`Parent source column '${parentSourceColName}' not found for joinPath relation '${relation.relationName}'`);</span>
2969
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2970
+ }
2971
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!targetFKCol) {</span>
2972
+ <span class="cstat-no" title="statement not covered" > console.warn(`Target FK column '${targetFKColName}' not found for joinPath relation '${relation.relationName}'`);</span>
2973
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2974
+ }
2975
+ &nbsp;
2976
+ // Fetch the parent row to obtain the value for parentSourceCol
2977
+ const parentRows = <span class="cstat-no" title="statement not covered" >await tx</span>
2978
+ .select({ val: parentSourceCol })
2979
+ .from(parentTable)
2980
+ .where(eq(parentIdCol, parsedParentId))
2981
+ .limit(1);
2982
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (parentRows.length === 0) <span class="cstat-no" title="statement not covered" >continue;</span></span>
2983
+ const parentFKValue = <span class="cstat-no" title="statement not covered" >parentRows[0].val as string | number | null;</span>
2984
+ &nbsp;
2985
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (newTargetId === null || newTargetId === undefined) {</span>
2986
+ // Clear any target rows currently linked to this parent via the FK
2987
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (parentFKValue !== null &amp;&amp; parentFKValue !== undefined) {</span>
2988
+ <span class="cstat-no" title="statement not covered" > await tx.update(targetTable)</span>
2989
+ .set({ [targetFKColName]: null })
2990
+ .where(eq(targetFKCol, parentFKValue as unknown as string));
2991
+ }
2992
+ <span class="cstat-no" title="statement not covered" > continue;</span>
2993
+ }
2994
+ &nbsp;
2995
+ // Parse the new target id
2996
+ const parsedTargetIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(newTargetId, targetPks);</span>
2997
+ const parsedTargetId = <span class="cstat-no" title="statement not covered" >parsedTargetIdObj[targetIdInfo.fieldName];</span>
2998
+ &nbsp;
2999
+ // Ensure one-to-one by clearing existing link from any target rows with this parent FK
3000
+ <span class="cstat-no" title="statement not covered" > if (parentFKValue !== null &amp;&amp; parentFKValue !== undefined) {</span>
3001
+ <span class="cstat-no" title="statement not covered" > await tx.update(targetTable)</span>
3002
+ .set({ [targetFKColName]: null })
3003
+ .where(eq(targetFKCol, parentFKValue as unknown as string));
3004
+ } else {
3005
+ <span class="cstat-no" title="statement not covered" > console.warn(`Cannot set joinPath relation '${relation.relationName}' because parent FK value is null/undefined`);</span>
3006
+ <span class="cstat-no" title="statement not covered" > continue;</span>
3007
+ }
3008
+ &nbsp;
3009
+ // Now set the FK on the target entity
3010
+ <span class="cstat-no" title="statement not covered" > await tx.update(targetTable)</span>
3011
+ .set({ [targetFKColName]: parentFKValue })
3012
+ .where(eq(targetIdCol, parsedTargetId));
3013
+ }
3014
+ }
3015
+ &nbsp;
3016
+ /**
3017
+ * Resolve joinPath write mapping for one-to-one relations
3018
+ */
3019
+ <span class="fstat-no" title="function not covered" > resolveJoinPathWriteMapping(</span>
3020
+ parentCollection: EntityCollection,
3021
+ relation: Relation
3022
+ ): { targetFKColName: string; parentSourceColName: string } {
3023
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!relation.joinPath || relation.joinPath.length === 0) {</span>
3024
+ <span class="cstat-no" title="statement not covered" > throw new Error("resolveJoinPathWriteMapping requires a joinPath relation");</span>
3025
+ }
3026
+ const parentTableName = <span class="cstat-no" title="statement not covered" >getTableName(parentCollection);</span>
3027
+ const lastStep = <span class="cstat-no" title="statement not covered" >relation.joinPath[relation.joinPath.length - 1];</span>
3028
+ const targetFKColName = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(lastStep.on.to)[0];</span>
3029
+ let currentFrom = <span class="cstat-no" title="statement not covered" >lastStep.on.from;</span>
3030
+ &nbsp;
3031
+ let safety = <span class="cstat-no" title="statement not covered" >0;</span>
3032
+ <span class="cstat-no" title="statement not covered" > while (safety++ &lt; 10) {</span>
3033
+ const currentFromTable = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getTableNamesFromColumns(currentFrom)[0];</span>
3034
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (currentFromTable === parentTableName) {</span>
3035
+ <span class="cstat-no" title="statement not covered" > break;</span>
3036
+ }
3037
+ const prevStep = <span class="cstat-no" title="statement not covered" >relation.joinPath.find(<span class="fstat-no" title="function not covered" >(s</span>) =&gt; {</span>
3038
+ const to = <span class="cstat-no" title="statement not covered" >Array.isArray(s.on.to) ? s.on.to[0] : s.on.to;</span>
3039
+ <span class="cstat-no" title="statement not covered" > return to === currentFrom;</span>
3040
+ });
3041
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!prevStep) {</span>
3042
+ <span class="cstat-no" title="statement not covered" > throw new Error(`Could not resolve parent source column for joinPath relation '${relation.relationName}'`);</span>
3043
+ }
3044
+ <span class="cstat-no" title="statement not covered" > currentFrom = prevStep.on.from;</span>
3045
+ }
3046
+ const parentSourceColName = <span class="cstat-no" title="statement not covered" >DrizzleConditionBuilder.getColumnNamesFromColumns(currentFrom)[0];</span>
3047
+ <span class="cstat-no" title="statement not covered" > return { targetFKColName, parentSourceColName };</span>
3048
+ }
3049
+ &nbsp;
3050
+ /**
3051
+ * Handle junction table creation for many-to-many path-based saves
3052
+ */
3053
+ <span class="fstat-no" title="function not covered" > async </span>handleJunctionTableCreation(
3054
+ tx: DrizzleClient,
3055
+ newEntityId: string | number,
3056
+ junctionTableInfo: {
3057
+ parentCollection: EntityCollection;
3058
+ parentId: string | number;
3059
+ relation: Relation;
3060
+ relationKey: string;
3061
+ }
3062
+ ) {
3063
+ const { parentCollection, parentId, relation, relationKey } = <span class="cstat-no" title="statement not covered" >junctionTableInfo;</span>
3064
+ const targetCollection = <span class="cstat-no" title="statement not covered" >relation.target();</span>
3065
+ &nbsp;
3066
+ <span class="cstat-no" title="statement not covered" > try {</span>
3067
+ const junctionTable = <span class="cstat-no" title="statement not covered" >this.registry.getTable(relation.through!.table);</span>
3068
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!junctionTable) {</span>
3069
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction table '${relation.through!.table}' not found for relation '${relationKey}'`);</span>
3070
+ <span class="cstat-no" title="statement not covered" > return;</span>
3071
+ }
3072
+ &nbsp;
3073
+ const sourceJunctionColumn = <span class="cstat-no" title="statement not covered" >junctionTable[relation.through!.sourceColumn as keyof typeof junctionTable] as AnyPgColumn;</span>
3074
+ const targetJunctionColumn = <span class="cstat-no" title="statement not covered" >junctionTable[relation.through!.targetColumn as keyof typeof junctionTable] as AnyPgColumn;</span>
3075
+ &nbsp;
3076
+ <span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (!sourceJunctionColumn || !targetJunctionColumn) {</span>
3077
+ <span class="cstat-no" title="statement not covered" > console.warn(`Junction columns not found for relation '${relationKey}'`);</span>
3078
+ <span class="cstat-no" title="statement not covered" > return;</span>
3079
+ }
3080
+ &nbsp;
3081
+ // Parse the new entity ID to the correct type
3082
+ const targetPks = <span class="cstat-no" title="statement not covered" >getPrimaryKeys(targetCollection, this.registry);</span>
3083
+ const targetIdInfo = <span class="cstat-no" title="statement not covered" >targetPks[0];</span>
3084
+ const parsedNewEntityIdObj = <span class="cstat-no" title="statement not covered" >parseIdValues(newEntityId, targetPks);</span>
3085
+ const parsedNewEntityId = <span class="cstat-no" title="statement not covered" >parsedNewEntityIdObj[targetIdInfo.fieldName];</span>
3086
+ &nbsp;
3087
+ // Create the junction table entry linking parent to the new entity
3088
+ const junctionData = <span class="cstat-no" title="statement not covered" >{</span>
3089
+ [sourceJunctionColumn.name]: parentId,
3090
+ [targetJunctionColumn.name]: parsedNewEntityId
3091
+ };
3092
+ &nbsp;
3093
+ <span class="cstat-no" title="statement not covered" > await tx.insert(junctionTable).values(junctionData);</span>
3094
+ &nbsp;
3095
+ <span class="cstat-no" title="statement not covered" > console.log(`Created junction table entry for many-to-many relation '${relationKey}': ${JSON.stringify(junctionData)}`);</span>
3096
+ } catch (error) {
3097
+ <span class="cstat-no" title="statement not covered" > console.error(`Failed to create junction table entry for relation '${relationKey}':`, error);</span>
3098
+ <span class="cstat-no" title="statement not covered" > throw error;</span>
3099
+ }
3100
+ }
3101
+ }
3102
+ &nbsp;</pre></td></tr></table></pre>
3103
+
3104
+ <div class='push'></div><!-- for sticky footer -->
3105
+ </div><!-- /wrapper -->
3106
+ <div class='footer quiet pad2 space-top1 center small'>
3107
+ Code coverage generated by
3108
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
3109
+ at 2026-04-06T04:35:23.770Z
3110
+ </div>
3111
+ <script src="../../../prettify.js"></script>
3112
+ <script>
3113
+ window.onload = function () {
3114
+ prettyPrint();
3115
+ };
3116
+ </script>
3117
+ <script src="../../../sorter.js"></script>
3118
+ <script src="../../../block-navigation.js"></script>
3119
+ </body>
3120
+ </html>
3121
+