@patroltech/agent-capabilities 0.0.0-stage → 0.2.0

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 (439) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -2
  3. package/dist/actions/alerts.d.ts +3 -0
  4. package/dist/actions/alerts.d.ts.map +1 -0
  5. package/dist/actions/alerts.js +90 -0
  6. package/dist/actions/alerts.js.map +1 -0
  7. package/dist/actions/batch-policy.d.ts +67 -0
  8. package/dist/actions/batch-policy.d.ts.map +1 -0
  9. package/dist/actions/batch-policy.js +73 -0
  10. package/dist/actions/batch-policy.js.map +1 -0
  11. package/dist/actions/checkpoint-archive.d.ts +3 -0
  12. package/dist/actions/checkpoint-archive.d.ts.map +1 -0
  13. package/dist/actions/checkpoint-archive.js +173 -0
  14. package/dist/actions/checkpoint-archive.js.map +1 -0
  15. package/dist/actions/checkpoint-geo.d.ts +4 -0
  16. package/dist/actions/checkpoint-geo.d.ts.map +1 -0
  17. package/dist/actions/checkpoint-geo.js +286 -0
  18. package/dist/actions/checkpoint-geo.js.map +1 -0
  19. package/dist/actions/checkpoints.d.ts +10 -0
  20. package/dist/actions/checkpoints.d.ts.map +1 -0
  21. package/dist/actions/checkpoints.js +222 -0
  22. package/dist/actions/checkpoints.js.map +1 -0
  23. package/dist/actions/guard.d.ts +13 -0
  24. package/dist/actions/guard.d.ts.map +1 -0
  25. package/dist/actions/guard.js +30 -0
  26. package/dist/actions/guard.js.map +1 -0
  27. package/dist/actions/incidents.d.ts +3 -0
  28. package/dist/actions/incidents.d.ts.map +1 -0
  29. package/dist/actions/incidents.js +260 -0
  30. package/dist/actions/incidents.js.map +1 -0
  31. package/dist/actions/index.d.ts +20 -0
  32. package/dist/actions/index.d.ts.map +1 -0
  33. package/dist/actions/index.js +60 -0
  34. package/dist/actions/index.js.map +1 -0
  35. package/dist/actions/locations.d.ts +4 -0
  36. package/dist/actions/locations.d.ts.map +1 -0
  37. package/dist/actions/locations.js +202 -0
  38. package/dist/actions/locations.js.map +1 -0
  39. package/dist/actions/names.d.ts +27 -0
  40. package/dist/actions/names.d.ts.map +1 -0
  41. package/dist/actions/names.js +48 -0
  42. package/dist/actions/names.js.map +1 -0
  43. package/dist/actions/patrollers.d.ts +6 -0
  44. package/dist/actions/patrollers.d.ts.map +1 -0
  45. package/dist/actions/patrollers.js +172 -0
  46. package/dist/actions/patrollers.js.map +1 -0
  47. package/dist/actions/route-schedules.d.ts +4 -0
  48. package/dist/actions/route-schedules.d.ts.map +1 -0
  49. package/dist/actions/route-schedules.js +110 -0
  50. package/dist/actions/route-schedules.js.map +1 -0
  51. package/dist/actions/routes.d.ts +5 -0
  52. package/dist/actions/routes.d.ts.map +1 -0
  53. package/dist/actions/routes.js +348 -0
  54. package/dist/actions/routes.js.map +1 -0
  55. package/dist/actions/support/antifraud-rules.d.ts +53 -0
  56. package/dist/actions/support/antifraud-rules.d.ts.map +1 -0
  57. package/dist/actions/support/antifraud-rules.js +121 -0
  58. package/dist/actions/support/antifraud-rules.js.map +1 -0
  59. package/dist/actions/support/elegir-ubicacion.d.ts +31 -0
  60. package/dist/actions/support/elegir-ubicacion.d.ts.map +1 -0
  61. package/dist/actions/support/elegir-ubicacion.js +42 -0
  62. package/dist/actions/support/elegir-ubicacion.js.map +1 -0
  63. package/dist/actions/support/next-step.d.ts +26 -0
  64. package/dist/actions/support/next-step.d.ts.map +1 -0
  65. package/dist/actions/support/next-step.js +55 -0
  66. package/dist/actions/support/next-step.js.map +1 -0
  67. package/dist/actions/support/route-impact.d.ts +25 -0
  68. package/dist/actions/support/route-impact.d.ts.map +1 -0
  69. package/dist/actions/support/route-impact.js +76 -0
  70. package/dist/actions/support/route-impact.js.map +1 -0
  71. package/dist/actions/support/route-lookup.d.ts +27 -0
  72. package/dist/actions/support/route-lookup.d.ts.map +1 -0
  73. package/dist/actions/support/route-lookup.js +44 -0
  74. package/dist/actions/support/route-lookup.js.map +1 -0
  75. package/dist/actions/support/schedule.d.ts +38 -0
  76. package/dist/actions/support/schedule.d.ts.map +1 -0
  77. package/dist/actions/support/schedule.js +62 -0
  78. package/dist/actions/support/schedule.js.map +1 -0
  79. package/dist/actions/support/shared.d.ts +112 -0
  80. package/dist/actions/support/shared.d.ts.map +1 -0
  81. package/dist/actions/support/shared.js +171 -0
  82. package/dist/actions/support/shared.js.map +1 -0
  83. package/dist/actions/support/texts.d.ts +47 -0
  84. package/dist/actions/support/texts.d.ts.map +1 -0
  85. package/dist/actions/support/texts.js +134 -0
  86. package/dist/actions/support/texts.js.map +1 -0
  87. package/dist/actions/support/turno.d.ts +16 -0
  88. package/dist/actions/support/turno.d.ts.map +1 -0
  89. package/dist/actions/support/turno.js +35 -0
  90. package/dist/actions/support/turno.js.map +1 -0
  91. package/dist/actions/support/user-access.d.ts +72 -0
  92. package/dist/actions/support/user-access.d.ts.map +1 -0
  93. package/dist/actions/support/user-access.js +194 -0
  94. package/dist/actions/support/user-access.js.map +1 -0
  95. package/dist/actions/types.d.ts +130 -0
  96. package/dist/actions/types.d.ts.map +1 -0
  97. package/dist/actions/types.js +20 -0
  98. package/dist/actions/types.js.map +1 -0
  99. package/dist/actions/user-roles.d.ts +4 -0
  100. package/dist/actions/user-roles.d.ts.map +1 -0
  101. package/dist/actions/user-roles.js +195 -0
  102. package/dist/actions/user-roles.js.map +1 -0
  103. package/dist/actions/users.d.ts +3 -0
  104. package/dist/actions/users.d.ts.map +1 -0
  105. package/dist/actions/users.js +146 -0
  106. package/dist/actions/users.js.map +1 -0
  107. package/dist/catalog/buildCatalog.d.ts +19 -0
  108. package/dist/catalog/buildCatalog.d.ts.map +1 -0
  109. package/dist/catalog/buildCatalog.js +38 -0
  110. package/dist/catalog/buildCatalog.js.map +1 -0
  111. package/dist/catalog/english.d.ts +14 -0
  112. package/dist/catalog/english.d.ts.map +1 -0
  113. package/dist/catalog/english.js +368 -0
  114. package/dist/catalog/english.js.map +1 -0
  115. package/dist/catalog/entries.d.ts +6 -0
  116. package/dist/catalog/entries.d.ts.map +1 -0
  117. package/dist/catalog/entries.js +610 -0
  118. package/dist/catalog/entries.js.map +1 -0
  119. package/dist/catalog/types.d.ts +61 -0
  120. package/dist/catalog/types.d.ts.map +1 -0
  121. package/dist/catalog/types.js +2 -0
  122. package/dist/catalog/types.js.map +1 -0
  123. package/dist/context.d.ts +37 -0
  124. package/dist/context.d.ts.map +1 -0
  125. package/dist/context.js +11 -0
  126. package/dist/context.js.map +1 -0
  127. package/dist/deps.d.ts +23 -0
  128. package/dist/deps.d.ts.map +1 -0
  129. package/dist/deps.js +12 -0
  130. package/dist/deps.js.map +1 -0
  131. package/dist/domain/access-logs-csv.d.ts +25 -0
  132. package/dist/domain/access-logs-csv.d.ts.map +1 -0
  133. package/dist/domain/access-logs-csv.js +36 -0
  134. package/dist/domain/access-logs-csv.js.map +1 -0
  135. package/dist/domain/backend-errors.d.ts +54 -0
  136. package/dist/domain/backend-errors.d.ts.map +1 -0
  137. package/dist/domain/backend-errors.js +364 -0
  138. package/dist/domain/backend-errors.js.map +1 -0
  139. package/dist/domain/country.d.ts +9 -0
  140. package/dist/domain/country.d.ts.map +1 -0
  141. package/dist/domain/country.js +13 -0
  142. package/dist/domain/country.js.map +1 -0
  143. package/dist/domain/date-range.d.ts +33 -0
  144. package/dist/domain/date-range.d.ts.map +1 -0
  145. package/dist/domain/date-range.js +110 -0
  146. package/dist/domain/date-range.js.map +1 -0
  147. package/dist/domain/geo.d.ts +14 -0
  148. package/dist/domain/geo.d.ts.map +1 -0
  149. package/dist/domain/geo.js +22 -0
  150. package/dist/domain/geo.js.map +1 -0
  151. package/dist/domain/guard-app-message.d.ts +15 -0
  152. package/dist/domain/guard-app-message.d.ts.map +1 -0
  153. package/dist/domain/guard-app-message.js +39 -0
  154. package/dist/domain/guard-app-message.js.map +1 -0
  155. package/dist/domain/incident-status.d.ts +29 -0
  156. package/dist/domain/incident-status.d.ts.map +1 -0
  157. package/dist/domain/incident-status.js +44 -0
  158. package/dist/domain/incident-status.js.map +1 -0
  159. package/dist/domain/language.d.ts +39 -0
  160. package/dist/domain/language.d.ts.map +1 -0
  161. package/dist/domain/language.js +112 -0
  162. package/dist/domain/language.js.map +1 -0
  163. package/dist/domain/money.d.ts +3 -0
  164. package/dist/domain/money.d.ts.map +1 -0
  165. package/dist/domain/money.js +12 -0
  166. package/dist/domain/money.js.map +1 -0
  167. package/dist/domain/puesta-en-marcha.d.ts +47 -0
  168. package/dist/domain/puesta-en-marcha.d.ts.map +1 -0
  169. package/dist/domain/puesta-en-marcha.js +22 -0
  170. package/dist/domain/puesta-en-marcha.js.map +1 -0
  171. package/dist/domain/qr-image.d.ts +25 -0
  172. package/dist/domain/qr-image.d.ts.map +1 -0
  173. package/dist/domain/qr-image.js +28 -0
  174. package/dist/domain/qr-image.js.map +1 -0
  175. package/dist/domain/resolve-by-name.d.ts +32 -0
  176. package/dist/domain/resolve-by-name.d.ts.map +1 -0
  177. package/dist/domain/resolve-by-name.js +40 -0
  178. package/dist/domain/resolve-by-name.js.map +1 -0
  179. package/dist/domain/route-checkpoints.d.ts +31 -0
  180. package/dist/domain/route-checkpoints.d.ts.map +1 -0
  181. package/dist/domain/route-checkpoints.js +27 -0
  182. package/dist/domain/route-checkpoints.js.map +1 -0
  183. package/dist/domain/route-schedule.d.ts +88 -0
  184. package/dist/domain/route-schedule.d.ts.map +1 -0
  185. package/dist/domain/route-schedule.js +203 -0
  186. package/dist/domain/route-schedule.js.map +1 -0
  187. package/dist/domain/scan-explanation.d.ts +25 -0
  188. package/dist/domain/scan-explanation.d.ts.map +1 -0
  189. package/dist/domain/scan-explanation.js +99 -0
  190. package/dist/domain/scan-explanation.js.map +1 -0
  191. package/dist/domain/scans-csv.d.ts +37 -0
  192. package/dist/domain/scans-csv.d.ts.map +1 -0
  193. package/dist/domain/scans-csv.js +67 -0
  194. package/dist/domain/scans-csv.js.map +1 -0
  195. package/dist/domain/timezone.d.ts +61 -0
  196. package/dist/domain/timezone.d.ts.map +1 -0
  197. package/dist/domain/timezone.js +113 -0
  198. package/dist/domain/timezone.js.map +1 -0
  199. package/dist/domain/tool-result.d.ts +55 -0
  200. package/dist/domain/tool-result.d.ts.map +1 -0
  201. package/dist/domain/tool-result.js +47 -0
  202. package/dist/domain/tool-result.js.map +1 -0
  203. package/dist/domain/urls.d.ts +33 -0
  204. package/dist/domain/urls.d.ts.map +1 -0
  205. package/dist/domain/urls.js +20 -0
  206. package/dist/domain/urls.js.map +1 -0
  207. package/dist/gateway/PatrolTechGateway.d.ts +195 -0
  208. package/dist/gateway/PatrolTechGateway.d.ts.map +1 -0
  209. package/dist/gateway/PatrolTechGateway.js +2 -0
  210. package/dist/gateway/PatrolTechGateway.js.map +1 -0
  211. package/dist/gateway/index.d.ts +4 -0
  212. package/dist/gateway/index.d.ts.map +1 -0
  213. package/dist/gateway/index.js +4 -0
  214. package/dist/gateway/index.js.map +1 -0
  215. package/dist/gateway/sdk/SdkPatrolTechGateway.d.ts +145 -0
  216. package/dist/gateway/sdk/SdkPatrolTechGateway.d.ts.map +1 -0
  217. package/dist/gateway/sdk/SdkPatrolTechGateway.js +101 -0
  218. package/dist/gateway/sdk/SdkPatrolTechGateway.js.map +1 -0
  219. package/dist/gateway/sdk/access.d.ts +8 -0
  220. package/dist/gateway/sdk/access.d.ts.map +1 -0
  221. package/dist/gateway/sdk/access.js +39 -0
  222. package/dist/gateway/sdk/access.js.map +1 -0
  223. package/dist/gateway/sdk/billing.d.ts +7 -0
  224. package/dist/gateway/sdk/billing.d.ts.map +1 -0
  225. package/dist/gateway/sdk/billing.js +92 -0
  226. package/dist/gateway/sdk/billing.js.map +1 -0
  227. package/dist/gateway/sdk/checkpoint-mappers.d.ts +23 -0
  228. package/dist/gateway/sdk/checkpoint-mappers.d.ts.map +1 -0
  229. package/dist/gateway/sdk/checkpoint-mappers.js +59 -0
  230. package/dist/gateway/sdk/checkpoint-mappers.js.map +1 -0
  231. package/dist/gateway/sdk/checkpoints.d.ts +33 -0
  232. package/dist/gateway/sdk/checkpoints.d.ts.map +1 -0
  233. package/dist/gateway/sdk/checkpoints.js +163 -0
  234. package/dist/gateway/sdk/checkpoints.js.map +1 -0
  235. package/dist/gateway/sdk/errors.d.ts +10 -0
  236. package/dist/gateway/sdk/errors.d.ts.map +1 -0
  237. package/dist/gateway/sdk/errors.js +46 -0
  238. package/dist/gateway/sdk/errors.js.map +1 -0
  239. package/dist/gateway/sdk/incidents.d.ts +18 -0
  240. package/dist/gateway/sdk/incidents.d.ts.map +1 -0
  241. package/dist/gateway/sdk/incidents.js +98 -0
  242. package/dist/gateway/sdk/incidents.js.map +1 -0
  243. package/dist/gateway/sdk/index.d.ts +4 -0
  244. package/dist/gateway/sdk/index.d.ts.map +1 -0
  245. package/dist/gateway/sdk/index.js +4 -0
  246. package/dist/gateway/sdk/index.js.map +1 -0
  247. package/dist/gateway/sdk/list.d.ts +15 -0
  248. package/dist/gateway/sdk/list.d.ts.map +1 -0
  249. package/dist/gateway/sdk/list.js +12 -0
  250. package/dist/gateway/sdk/list.js.map +1 -0
  251. package/dist/gateway/sdk/locations.d.ts +24 -0
  252. package/dist/gateway/sdk/locations.d.ts.map +1 -0
  253. package/dist/gateway/sdk/locations.js +44 -0
  254. package/dist/gateway/sdk/locations.js.map +1 -0
  255. package/dist/gateway/sdk/patrollers.d.ts +26 -0
  256. package/dist/gateway/sdk/patrollers.d.ts.map +1 -0
  257. package/dist/gateway/sdk/patrollers.js +132 -0
  258. package/dist/gateway/sdk/patrollers.js.map +1 -0
  259. package/dist/gateway/sdk/rounds.d.ts +15 -0
  260. package/dist/gateway/sdk/rounds.d.ts.map +1 -0
  261. package/dist/gateway/sdk/rounds.js +142 -0
  262. package/dist/gateway/sdk/rounds.js.map +1 -0
  263. package/dist/gateway/sdk/routes.d.ts +18 -0
  264. package/dist/gateway/sdk/routes.d.ts.map +1 -0
  265. package/dist/gateway/sdk/routes.js +74 -0
  266. package/dist/gateway/sdk/routes.js.map +1 -0
  267. package/dist/gateway/sdk/scans.d.ts +4 -0
  268. package/dist/gateway/sdk/scans.d.ts.map +1 -0
  269. package/dist/gateway/sdk/scans.js +72 -0
  270. package/dist/gateway/sdk/scans.js.map +1 -0
  271. package/dist/gateway/sdk/transport.d.ts +77 -0
  272. package/dist/gateway/sdk/transport.d.ts.map +1 -0
  273. package/dist/gateway/sdk/transport.js +81 -0
  274. package/dist/gateway/sdk/transport.js.map +1 -0
  275. package/dist/gateway/sdk/users.d.ts +15 -0
  276. package/dist/gateway/sdk/users.d.ts.map +1 -0
  277. package/dist/gateway/sdk/users.js +49 -0
  278. package/dist/gateway/sdk/users.js.map +1 -0
  279. package/dist/gateway/types/access.d.ts +32 -0
  280. package/dist/gateway/types/access.d.ts.map +1 -0
  281. package/dist/gateway/types/access.js +2 -0
  282. package/dist/gateway/types/access.js.map +1 -0
  283. package/dist/gateway/types/billing.d.ts +60 -0
  284. package/dist/gateway/types/billing.d.ts.map +1 -0
  285. package/dist/gateway/types/billing.js +2 -0
  286. package/dist/gateway/types/billing.js.map +1 -0
  287. package/dist/gateway/types/checkpoints.d.ts +84 -0
  288. package/dist/gateway/types/checkpoints.d.ts.map +1 -0
  289. package/dist/gateway/types/checkpoints.js +2 -0
  290. package/dist/gateway/types/checkpoints.js.map +1 -0
  291. package/dist/gateway/types/common.d.ts +13 -0
  292. package/dist/gateway/types/common.d.ts.map +1 -0
  293. package/dist/gateway/types/common.js +2 -0
  294. package/dist/gateway/types/common.js.map +1 -0
  295. package/dist/gateway/types/incidents.d.ts +53 -0
  296. package/dist/gateway/types/incidents.d.ts.map +1 -0
  297. package/dist/gateway/types/incidents.js +2 -0
  298. package/dist/gateway/types/incidents.js.map +1 -0
  299. package/dist/gateway/types/index.d.ts +12 -0
  300. package/dist/gateway/types/index.d.ts.map +1 -0
  301. package/dist/gateway/types/index.js +12 -0
  302. package/dist/gateway/types/index.js.map +1 -0
  303. package/dist/gateway/types/locations.d.ts +7 -0
  304. package/dist/gateway/types/locations.d.ts.map +1 -0
  305. package/dist/gateway/types/locations.js +2 -0
  306. package/dist/gateway/types/locations.js.map +1 -0
  307. package/dist/gateway/types/patrollers.d.ts +68 -0
  308. package/dist/gateway/types/patrollers.d.ts.map +1 -0
  309. package/dist/gateway/types/patrollers.js +15 -0
  310. package/dist/gateway/types/patrollers.js.map +1 -0
  311. package/dist/gateway/types/rounds.d.ts +89 -0
  312. package/dist/gateway/types/rounds.d.ts.map +1 -0
  313. package/dist/gateway/types/rounds.js +2 -0
  314. package/dist/gateway/types/rounds.js.map +1 -0
  315. package/dist/gateway/types/routes.d.ts +48 -0
  316. package/dist/gateway/types/routes.d.ts.map +1 -0
  317. package/dist/gateway/types/routes.js +2 -0
  318. package/dist/gateway/types/routes.js.map +1 -0
  319. package/dist/gateway/types/scans.d.ts +44 -0
  320. package/dist/gateway/types/scans.d.ts.map +1 -0
  321. package/dist/gateway/types/scans.js +2 -0
  322. package/dist/gateway/types/scans.js.map +1 -0
  323. package/dist/gateway/types/users.d.ts +32 -0
  324. package/dist/gateway/types/users.d.ts.map +1 -0
  325. package/dist/gateway/types/users.js +2 -0
  326. package/dist/gateway/types/users.js.map +1 -0
  327. package/dist/index.d.ts +32 -0
  328. package/dist/index.d.ts.map +1 -0
  329. package/dist/index.js +40 -0
  330. package/dist/index.js.map +1 -0
  331. package/dist/ports/FileSink.d.ts +20 -0
  332. package/dist/ports/FileSink.d.ts.map +1 -0
  333. package/dist/ports/FileSink.js +2 -0
  334. package/dist/ports/FileSink.js.map +1 -0
  335. package/dist/ports/Logger.d.ts +16 -0
  336. package/dist/ports/Logger.d.ts.map +1 -0
  337. package/dist/ports/Logger.js +7 -0
  338. package/dist/ports/Logger.js.map +1 -0
  339. package/dist/ports/PendingActionStore.d.ts +84 -0
  340. package/dist/ports/PendingActionStore.d.ts.map +1 -0
  341. package/dist/ports/PendingActionStore.js +16 -0
  342. package/dist/ports/PendingActionStore.js.map +1 -0
  343. package/dist/reads/access.d.ts +4 -0
  344. package/dist/reads/access.d.ts.map +1 -0
  345. package/dist/reads/access.js +129 -0
  346. package/dist/reads/access.js.map +1 -0
  347. package/dist/reads/checkpoints.d.ts +4 -0
  348. package/dist/reads/checkpoints.d.ts.map +1 -0
  349. package/dist/reads/checkpoints.js +152 -0
  350. package/dist/reads/checkpoints.js.map +1 -0
  351. package/dist/reads/files.d.ts +9 -0
  352. package/dist/reads/files.d.ts.map +1 -0
  353. package/dist/reads/files.js +222 -0
  354. package/dist/reads/files.js.map +1 -0
  355. package/dist/reads/incidents.d.ts +4 -0
  356. package/dist/reads/incidents.d.ts.map +1 -0
  357. package/dist/reads/incidents.js +164 -0
  358. package/dist/reads/incidents.js.map +1 -0
  359. package/dist/reads/index.d.ts +11 -0
  360. package/dist/reads/index.d.ts.map +1 -0
  361. package/dist/reads/index.js +51 -0
  362. package/dist/reads/index.js.map +1 -0
  363. package/dist/reads/onboarding.d.ts +4 -0
  364. package/dist/reads/onboarding.d.ts.map +1 -0
  365. package/dist/reads/onboarding.js +41 -0
  366. package/dist/reads/onboarding.js.map +1 -0
  367. package/dist/reads/organization.d.ts +26 -0
  368. package/dist/reads/organization.d.ts.map +1 -0
  369. package/dist/reads/organization.js +45 -0
  370. package/dist/reads/organization.js.map +1 -0
  371. package/dist/reads/patrollers.d.ts +4 -0
  372. package/dist/reads/patrollers.d.ts.map +1 -0
  373. package/dist/reads/patrollers.js +156 -0
  374. package/dist/reads/patrollers.js.map +1 -0
  375. package/dist/reads/plan.d.ts +4 -0
  376. package/dist/reads/plan.d.ts.map +1 -0
  377. package/dist/reads/plan.js +195 -0
  378. package/dist/reads/plan.js.map +1 -0
  379. package/dist/reads/rounds.d.ts +4 -0
  380. package/dist/reads/rounds.d.ts.map +1 -0
  381. package/dist/reads/rounds.js +160 -0
  382. package/dist/reads/rounds.js.map +1 -0
  383. package/dist/reads/routes.d.ts +4 -0
  384. package/dist/reads/routes.d.ts.map +1 -0
  385. package/dist/reads/routes.js +34 -0
  386. package/dist/reads/routes.js.map +1 -0
  387. package/dist/reads/support/access-locations.d.ts +22 -0
  388. package/dist/reads/support/access-locations.d.ts.map +1 -0
  389. package/dist/reads/support/access-locations.js +55 -0
  390. package/dist/reads/support/access-locations.js.map +1 -0
  391. package/dist/reads/support/excel.d.ts +10 -0
  392. package/dist/reads/support/excel.d.ts.map +1 -0
  393. package/dist/reads/support/excel.js +35 -0
  394. package/dist/reads/support/excel.js.map +1 -0
  395. package/dist/reads/support/params.d.ts +50 -0
  396. package/dist/reads/support/params.d.ts.map +1 -0
  397. package/dist/reads/support/params.js +73 -0
  398. package/dist/reads/support/params.js.map +1 -0
  399. package/dist/reads/support/resolve.d.ts +17 -0
  400. package/dist/reads/support/resolve.d.ts.map +1 -0
  401. package/dist/reads/support/resolve.js +33 -0
  402. package/dist/reads/support/resolve.js.map +1 -0
  403. package/dist/reads/support/results.d.ts +22 -0
  404. package/dist/reads/support/results.d.ts.map +1 -0
  405. package/dist/reads/support/results.js +41 -0
  406. package/dist/reads/support/results.js.map +1 -0
  407. package/dist/reads/support/roles.d.ts +13 -0
  408. package/dist/reads/support/roles.d.ts.map +1 -0
  409. package/dist/reads/support/roles.js +27 -0
  410. package/dist/reads/support/roles.js.map +1 -0
  411. package/dist/reads/support/scans.d.ts +31 -0
  412. package/dist/reads/support/scans.d.ts.map +1 -0
  413. package/dist/reads/support/scans.js +66 -0
  414. package/dist/reads/support/scans.js.map +1 -0
  415. package/dist/reads/types.d.ts +48 -0
  416. package/dist/reads/types.d.ts.map +1 -0
  417. package/dist/reads/types.js +5 -0
  418. package/dist/reads/types.js.map +1 -0
  419. package/dist/reads/users.d.ts +4 -0
  420. package/dist/reads/users.d.ts.map +1 -0
  421. package/dist/reads/users.js +57 -0
  422. package/dist/reads/users.js.map +1 -0
  423. package/dist/testing/FakePatrolTechGateway.d.ts +212 -0
  424. package/dist/testing/FakePatrolTechGateway.d.ts.map +1 -0
  425. package/dist/testing/FakePatrolTechGateway.js +712 -0
  426. package/dist/testing/FakePatrolTechGateway.js.map +1 -0
  427. package/dist/testing/RecordingFileSink.d.ts +12 -0
  428. package/dist/testing/RecordingFileSink.d.ts.map +1 -0
  429. package/dist/testing/RecordingFileSink.js +12 -0
  430. package/dist/testing/RecordingFileSink.js.map +1 -0
  431. package/dist/testing/index.d.ts +4 -0
  432. package/dist/testing/index.d.ts.map +1 -0
  433. package/dist/testing/index.js +4 -0
  434. package/dist/testing/index.js.map +1 -0
  435. package/dist/testing/reads.d.ts +34 -0
  436. package/dist/testing/reads.d.ts.map +1 -0
  437. package/dist/testing/reads.js +39 -0
  438. package/dist/testing/reads.js.map +1 -0
  439. package/package.json +76 -4
@@ -0,0 +1,195 @@
1
+ import { z } from 'zod';
2
+ import { backendErrorCode, PatrolTechApiError, translateBackendError, } from '../domain/backend-errors.js';
3
+ import { FALTA_PAIS, normalizeCountry } from '../domain/country.js';
4
+ import { importe } from '../domain/money.js';
5
+ import { fail, ok } from '../domain/tool-result.js';
6
+ import { ROL_LABEL } from './support/roles.js';
7
+ import { defineRead } from './types.js';
8
+ const usoPlanDesc = 'Consulta el plan de la organización y su uso frente a los límites: checkpoints usados/incluidos (y extra facturados), ubicaciones y gestores usados/límite. Límite null = sin tope. Úsala para «¿cuántos checkpoints me quedan?», «¿qué plan tengo?» o antes de proponer crear algo que cuenta para el plan.';
9
+ const contratarPlanDesc = 'Genera el enlace de pago para contratar un plan, igual que el botón de Licencia del panel: el cliente paga en la página segura de Stripe (generar el enlace no cobra nada, así que no pide confirmación). Úsala cuando quiera contratar Pro o Business o subir de plan. Si no ha dicho plan, la recomendación es Business; si no ha dicho periodo, propón mensual; pregunta solo si duda. El cliente elige: si pide Pro o anual, dale ese. Solo un Admin de toda la organización puede contratar: si no lo es, la herramienta lo dice. Si la organización ya paga un plan, devuelve el enlace de su portal de suscripción en vez de un pago nuevo. Enterprise no tiene enlace: es a medida. Da el `enlace` completo, tal cual.';
10
+ const gestionarSuscripcionDesc = 'Genera el enlace al portal de suscripción de Stripe de la organización (solo si ya paga): facturas, cambiar la tarjeta, datos de facturación, cancelar o cambiar de plan. Solo un Admin de toda la organización. Úsala cuando pida sus facturas, cambiar la tarjeta o gestionar la suscripción. Da el `enlace` completo, tal cual. Para BAJAR de plan, la base de conocimiento manda escalar: lo gestiona el equipo.';
11
+ const ENLACE_NO_STRIPE = 'El panel ha devuelto un enlace de pago que no es de Stripe: no lo des. Escala al equipo.';
12
+ /**
13
+ * ¿Es Admin de TODA la organización? Es lo que exige la API para contratar y
14
+ * abrir el portal (rol ADMIN de organización, no de una ubicación). null si la
15
+ * sesión no trae el rol: entonces decide la API.
16
+ */
17
+ function esAdminDeOrganizacion(org) {
18
+ if (!org.roleType)
19
+ return null;
20
+ return org.roleType.toUpperCase() === 'ADMIN' && org.scope !== 'location';
21
+ }
22
+ function soloAdmin(org) {
23
+ const rol = ROL_LABEL[org.roleType?.toUpperCase() ?? ''] ?? org.roleType ?? 'desconocido';
24
+ const ambito = org.scope === 'location' ? ' solo de una ubicación' : '';
25
+ return fail(`Solo un Admin de toda la organización «${org.name}» puede contratar, cambiar o gestionar el plan y la suscripción; este usuario es ${rol}${ambito}. ` +
26
+ 'No escales ni inventes quién es el Admin: dile que se lo pida a un Admin de su cuenta, que puede hacerlo en el panel (Licencia) o pedirme el enlace por WhatsApp desde su propio teléfono.');
27
+ }
28
+ /** El enlace que devuelve el backend solo se da si es de Stripe (el mismo guardia que el panel antes de redirigir). */
29
+ function esUrlDeStripe(url) {
30
+ try {
31
+ const host = new URL(url).hostname;
32
+ return host === 'stripe.com' || host.endsWith('.stripe.com');
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ /** Traduce un rechazo del backend al pedir un enlace de pago; lo demás (red, timeout) sigue su camino. */
39
+ function falloEnlace(err, language, policy) {
40
+ if (err instanceof PatrolTechApiError) {
41
+ return fail(translateBackendError(err, language, policy).mensajeCliente);
42
+ }
43
+ throw err;
44
+ }
45
+ /** Los enlaces de pago: la vuelta desde Stripe es la página Licencia del panel. */
46
+ function billingLinks(gateway, policy) {
47
+ const licensePageUrl = policy.urls.license;
48
+ const checkoutSuccessUrl = `${licensePageUrl}/callback?status=success`;
49
+ const checkoutCancelUrl = `${licensePageUrl}/callback?status=cancel`;
50
+ async function enlacePortal(ctx) {
51
+ let enlace;
52
+ try {
53
+ enlace = await gateway.createCustomerPortalLink(ctx.org.orgId, licensePageUrl, ctx.token);
54
+ }
55
+ catch (err) {
56
+ return falloEnlace(err, ctx.language, policy);
57
+ }
58
+ return esUrlDeStripe(enlace) ? enlace : fail(ENLACE_NO_STRIPE);
59
+ }
60
+ /** Quien ya paga cambia de plan en su portal de suscripción, no con un pago nuevo. */
61
+ async function portalDeQuienYaPaga(ctx, planActual) {
62
+ const enlace = await enlacePortal(ctx);
63
+ if (typeof enlace !== 'string')
64
+ return enlace;
65
+ return ok({ enlace, tipo: 'portal_suscripcion', planActual }, {
66
+ avisos: [
67
+ `La organización ya paga el plan ${planActual}: no se contrata otro (serían dos cobros). Este enlace es su portal de suscripción de Stripe, donde cambia de plan, ve sus facturas y cambia la tarjeta. Si en el portal no le aparece el cambio de plan, se hace en el panel: Licencia → «Pasar a {plan}» (se aplica al momento y se cobra la parte proporcional).`,
68
+ ],
69
+ });
70
+ }
71
+ async function contratar(ctx, args) {
72
+ if (args.plan === 'enterprise') {
73
+ return ok({ plan: 'Enterprise', aMedida: true }, {
74
+ avisos: [
75
+ 'Enterprise es una oferta a medida que gestiona el equipo: no tiene enlace de pago. Antes de ofrecerlo, comprueba con consultar_precios (checkpoints incluidos y precio del extra) y consultar_uso_plan (sus límites y uso) si Business le cubre, sin dar límites de memoria: si le cubre, ofrécele Business con su enlace. Si de verdad necesita Enterprise, ofrécele una llamada con el equipo: acuerda día y hora y usa escalar_a_humano con `cita` (y programar_recordatorio).',
76
+ ],
77
+ });
78
+ }
79
+ if (esAdminDeOrganizacion(ctx.org) === false)
80
+ return soloAdmin(ctx.org);
81
+ const orgId = ctx.org.orgId;
82
+ const uso = await gateway.getPlanUsage(orgId, ctx.token);
83
+ // NUNCA un checkout para quien ya paga: crearía una segunda suscripción cobrando a la vez.
84
+ if (uso.pagaSuscripcion)
85
+ return portalDeQuienYaPaga(ctx, uso.plan);
86
+ if (!args.periodo) {
87
+ return fail('Falta el periodo: si no lo ha dicho, propón mensual; pregunta solo si duda. Vuelve a llamarla con periodo mensual (o anual si lo pide o quiere ahorrar: el anual son 10 mensualidades, 2 meses gratis).');
88
+ }
89
+ // El backend decide la moneda; aquí solo se le pasa el país (el que diga el cliente o el del contexto).
90
+ const pais = normalizeCountry(args.pais) ?? ctx.country;
91
+ if (!pais)
92
+ return fail(FALTA_PAIS);
93
+ const plan = (await gateway.getPlans(orgId, ctx.token, pais)).find((p) => p.identificador === args.plan);
94
+ if (!plan) {
95
+ return fail(`El plan ${args.plan} no está disponible ahora mismo en el panel: no des precio ni enlace. Escala al equipo.`);
96
+ }
97
+ const anual = args.periodo === 'anual';
98
+ let enlace;
99
+ try {
100
+ enlace = await gateway.createCheckoutLink(orgId, {
101
+ tierId: plan.tierId,
102
+ interval: anual ? 'year' : 'month',
103
+ successUrl: checkoutSuccessUrl,
104
+ cancelUrl: checkoutCancelUrl,
105
+ country: pais,
106
+ }, ctx.token);
107
+ }
108
+ catch (err) {
109
+ // Si no se sabía que ya paga, lo dice el backend al negarse a abrir otro checkout.
110
+ if (err instanceof PatrolTechApiError && backendErrorCode(err) === 'ALREADY_SUBSCRIBED') {
111
+ return portalDeQuienYaPaga(ctx, uso.plan);
112
+ }
113
+ return falloEnlace(err, ctx.language, policy);
114
+ }
115
+ if (!esUrlDeStripe(enlace))
116
+ return fail(ENLACE_NO_STRIPE);
117
+ const precios = anual ? plan.anual : plan.mensual;
118
+ const cada = anual ? 'al año' : 'al mes';
119
+ return ok({
120
+ enlace,
121
+ plan: plan.nombre,
122
+ periodo: args.periodo,
123
+ precio: `${importe(precios.base, plan.moneda)} ${cada}`,
124
+ moneda: plan.moneda,
125
+ checkpointsIncluidos: plan.checkpointsIncluidos,
126
+ checkpointExtra: `${importe(precios.extra, plan.moneda)} ${cada} por cada checkpoint por encima de ${plan.checkpointsIncluidos}`,
127
+ }, {
128
+ avisos: [
129
+ 'Precio y moneda son los que cobra Stripe a esta organización (la moneda la decide el sistema por su país): dalos tal cual. Generar el enlace no cobra nada: paga en la página segura de Stripe, donde ve el total (con impuestos y, si ya tiene más checkpoints de los incluidos, los extra) antes de confirmar. El enlace caduca a los 45 minutos: si caduca, se genera otro. Al pagar, el plan se activa solo.',
130
+ ],
131
+ });
132
+ }
133
+ async function gestionar(ctx) {
134
+ if (esAdminDeOrganizacion(ctx.org) === false)
135
+ return soloAdmin(ctx.org);
136
+ const uso = await gateway.getPlanUsage(ctx.org.orgId, ctx.token);
137
+ const enlace = await enlacePortal(ctx);
138
+ if (typeof enlace !== 'string') {
139
+ // Sin cliente de Stripe (nunca ha pagado) el backend no abre el portal.
140
+ return uso.pagaSuscripcion === false
141
+ ? fail(`La organización no tiene suscripción de pago (plan ${uso.plan}): no hay facturas ni tarjeta que gestionar. Si quiere contratar un plan, usa enlace_contratar_plan.`)
142
+ : enlace;
143
+ }
144
+ return ok({ enlace, planActual: uso.plan });
145
+ }
146
+ return { contratar, gestionar };
147
+ }
148
+ /**
149
+ * Sin upsell (MCP) solo el consumo frente a los límites: ni el nombre del plan,
150
+ * ni su estado de pago, ni los checkpoints extra facturados.
151
+ */
152
+ function usoSinFacturacion(uso) {
153
+ const { usados, incluidos } = uso.checkpoints;
154
+ return { ...uso, checkpoints: { usados, incluidos } };
155
+ }
156
+ /** Plan y suscripción: uso frente a los límites y enlaces de pago de Stripe. */
157
+ export function planReads({ gateway, urls, upsell }) {
158
+ const enlaces = billingLinks(gateway, { urls, upsell });
159
+ return [
160
+ defineRead({
161
+ name: 'consultar_uso_plan',
162
+ description: usoPlanDesc,
163
+ params: {},
164
+ call: async ({ org, token }) => {
165
+ const usage = await gateway.getPlanUsage(org.orgId, token);
166
+ return ok(upsell ? usage : { uso: usage.uso && usoSinFacturacion(usage.uso) });
167
+ },
168
+ }),
169
+ defineRead({
170
+ name: 'enlace_contratar_plan',
171
+ description: contratarPlanDesc,
172
+ params: {
173
+ plan: z
174
+ .enum(['pro', 'business', 'enterprise'])
175
+ .describe('Plan que quiere contratar (si no lo ha dicho, la recomendación es business)'),
176
+ periodo: z
177
+ .enum(['mensual', 'anual'])
178
+ .optional()
179
+ .describe('Facturación mensual o anual (anual = 10 mensualidades, 2 meses gratis). Si no lo ha dicho, propón mensual; pregunta solo si duda. Anual solo si lo pide o pregunta cómo ahorrar.'),
180
+ pais: z
181
+ .string()
182
+ .optional()
183
+ .describe('Código ISO-2 del país del cliente (p. ej. MX, ES). Solo si el cliente lo ha dicho o si la herramienta te lo pide; si no, omítelo.'),
184
+ },
185
+ call: async (ctx, args) => enlaces.contratar(ctx, args),
186
+ }),
187
+ defineRead({
188
+ name: 'enlace_gestionar_suscripcion',
189
+ description: gestionarSuscripcionDesc,
190
+ params: {},
191
+ call: async (ctx) => enlaces.gestionar(ctx),
192
+ }),
193
+ ];
194
+ }
195
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/reads/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type ReadCapability, type ReadEnv } from './types.js';
2
+ /** Rondas: estado general, detalle por ruta, checkpoints de la última y una ronda concreta. */
3
+ export declare function roundReads({ gateway }: ReadEnv): ReadCapability[];
4
+ //# sourceMappingURL=rounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rounds.d.ts","sourceRoot":"","sources":["../../src/reads/rounds.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAuJ3E,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,GAAG,cAAc,EAAE,CAmCjE"}
@@ -0,0 +1,160 @@
1
+ import { z } from 'zod';
2
+ import { localToUtc } from '../domain/timezone.js';
3
+ import { fail, ok } from '../domain/tool-result.js';
4
+ import { rutaParamSchema } from './support/params.js';
5
+ import { resolveRuta } from './support/resolve.js';
6
+ import { failAmbigua, failNoEncontrado, isFail, okLista, TRUNCADO_HINT, } from './support/results.js';
7
+ import { defineRead } from './types.js';
8
+ const rondasDesc = 'Consulta el estado de las rondas de la cuenta del usuario (abiertas, completadas, incompletas) de los últimos `windowDays` días.';
9
+ const rondasDetalleDesc = 'Consulta el detalle de las rondas/rutas de la organización: cada ruta con sus rondas recientes (estado, vigilante, checkpoints completados de total, horas). Úsala cuando el usuario pida ver el detalle de las rondas, cómo van las rutas, o el estado de rondas concretas. Si una ruta trae `error`, sus rondas NO se pudieron leer: no digas que no tiene rondas.' +
10
+ TRUNCADO_HINT;
11
+ const checkpointsRondaDesc = 'Consulta el detalle por punto de control de la ÚLTIMA ronda de una ruta: qué checkpoints se escanearon (con hora) y cuáles faltan. Úsala cuando el usuario pregunte qué puntos faltan/se hicieron en una ronda, o el detalle de checkpoints de una ruta concreta. Si el usuario NO indica la ruta, llámala igualmente SIN el parámetro `ruta`: si solo hay una ruta activa la usará, y si hay varias devolverá la lista de rutas para que el usuario elija (no le pidas la ruta a ciegas).';
12
+ const rondaDesc = 'Consulta UNA ronda concreta de una ruta: estado, vigilante, inicio y fin, y qué checkpoints se hicieron (con hora) y cuáles quedaron pendientes. Sin `fecha` devuelve la ÚLTIMA ronda. Para una ronda concreta pasa `fecha` (día del cliente) y, si lo sabes, `hora` aproximada: «anoche» → fecha de ayer y hora 23:00; «esta mañana» → hoy y 08:00. Si ese día hubo más rondas, vienen en `otrasRondasCercanas`. Si el usuario no dice la ruta, llámala sin `ruta`: si hay varias, devuelve la lista para preguntar. Las horas vienen en UTC.';
13
+ const rondaParamSchema = {
14
+ ruta: rutaParamSchema.ruta,
15
+ fecha: z
16
+ .string()
17
+ .regex(/^\d{4}-\d{2}-\d{2}$/, 'Usa exactamente YYYY-MM-DD')
18
+ .optional()
19
+ .describe('Día de la ronda en el calendario del cliente, YYYY-MM-DD. OMÍTELO para la última ronda.'),
20
+ hora: z
21
+ .string()
22
+ .regex(/^\d{2}:\d{2}$/, 'Usa exactamente HH:mm')
23
+ .optional()
24
+ .describe('Hora aproximada de inicio, HH:mm en la hora del cliente. Solo junto con `fecha`.'),
25
+ };
26
+ const ROUNDS_PAGE_SIZE = 50;
27
+ // Hasta 300 rondas hacia atrás: el backend no filtra rondas por fecha, hay que paginar.
28
+ const MAX_ROUND_PAGES = 6;
29
+ const HORA_MS = 3600_000;
30
+ const MAX_RONDAS_CERCANAS = 5;
31
+ /** Avisos de las rutas cuyas rondas no se pudieron leer (no son "rutas sin rondas"). */
32
+ const avisosRutasConError = (rutas) => {
33
+ const conError = rutas.filter((r) => r.error).map((r) => r.routeName);
34
+ return conError.length > 0
35
+ ? [
36
+ `No se pudieron leer las rondas de: ${conError.join(', ')}. NO digas que esas rutas no tienen rondas.`,
37
+ ]
38
+ : [];
39
+ };
40
+ /** Traduce el resultado del gateway: solo `found` y "no hay rondas" son respuestas con datos. */
41
+ function checkpointsRondaResult(result) {
42
+ if (result.found)
43
+ return ok(result);
44
+ if (result.reason === 'route_ambiguous') {
45
+ return failAmbigua('el nombre indicado', 'rutas', result.opciones);
46
+ }
47
+ if (result.reason === 'route_not_found')
48
+ return failNoEncontrado('ruta', result.opciones);
49
+ if (result.reason === 'route_not_specified') {
50
+ return fail('ruta no indicada: hay varias, pregunta al usuario cuál de estas quiere', result.opciones);
51
+ }
52
+ // no_rondas: es un hecho, no un fallo (la ruta existe y no tiene rondas aún).
53
+ return ok(result);
54
+ }
55
+ async function rondaConDetalle(gateway, token, ruta, ronda) {
56
+ const detalle = await gateway.getRoundDetail(ruta.id, ronda.id, token);
57
+ return {
58
+ ruta: ruta.name,
59
+ estado: detalle.status,
60
+ vigilante: ronda.patrollerName,
61
+ inicio: ronda.startTime,
62
+ fin: ronda.endTime,
63
+ escaneados: detalle.scannedCount,
64
+ total: detalle.totalCount,
65
+ hechos: detalle.checkpoints
66
+ .filter((c) => c.scanned)
67
+ .map((c) => ({ checkpoint: c.checkpointName, hora: c.scanTime })),
68
+ pendientes: detalle.checkpoints.filter((c) => !c.scanned).map((c) => c.checkpointName),
69
+ };
70
+ }
71
+ /**
72
+ * La ronda pedida con sus puntos hechos y pendientes. Sin `cuando`, la última;
73
+ * con fecha, la que empezó más cerca de esa fecha y hora (mediodía si no hay
74
+ * hora), dentro de ±6 h con hora o ±12 h sin ella. Las rondas no se filtran
75
+ * por fecha en el backend: se pagina hacia atrás hasta pasar la ventana.
76
+ */
77
+ async function consultarRonda(gateway, token, ruta, cuando) {
78
+ if (!cuando) {
79
+ const { items } = await gateway.getRouteRounds(ruta.id, token, { page: 1, limit: 1 });
80
+ if (!items[0]) {
81
+ return ok({ ruta: ruta.name, ronda: null, motivo: 'esta ruta todavía no tiene rondas' });
82
+ }
83
+ return ok(await rondaConDetalle(gateway, token, ruta, items[0]));
84
+ }
85
+ const objetivo = localToUtc(`${cuando.fecha}T${cuando.hora ?? '12:00'}`, cuando.tz).getTime();
86
+ const tolerancia = (cuando.hora ? 6 : 12) * HORA_MS;
87
+ const vistas = [];
88
+ let agotado = false;
89
+ for (let page = 1;; page++) {
90
+ const { items, totalPages } = await gateway.getRouteRounds(ruta.id, token, {
91
+ page,
92
+ limit: ROUNDS_PAGE_SIZE,
93
+ });
94
+ vistas.push(...items);
95
+ const masAntigua = items.at(-1);
96
+ if (!masAntigua ||
97
+ Date.parse(masAntigua.startTime) < objetivo - tolerancia ||
98
+ page >= totalPages) {
99
+ break;
100
+ }
101
+ if (page >= MAX_ROUND_PAGES) {
102
+ agotado = true;
103
+ break;
104
+ }
105
+ }
106
+ const distancia = (r) => Math.abs(Date.parse(r.startTime) - objetivo);
107
+ const cercanas = [...vistas].sort((a, b) => distancia(a) - distancia(b));
108
+ const enVentana = cercanas.filter((r) => distancia(r) <= tolerancia);
109
+ if (enVentana.length === 0) {
110
+ if (agotado) {
111
+ return fail(`No he encontrado esa ronda entre las ${vistas.length} más recientes de «${ruta.name}»: es demasiado antigua para consultarla desde aquí; puede verla en el panel (Rutas).`);
112
+ }
113
+ return fail(`No hay ninguna ronda de «${ruta.name}» cerca de esa fecha. Estas son las más próximas (hora de inicio en UTC); pregunta cuál quiere:`, cercanas.slice(0, MAX_RONDAS_CERCANAS).map((r) => r.startTime));
114
+ }
115
+ const [elegida, ...resto] = enVentana;
116
+ const otrasRondasCercanas = resto.slice(0, MAX_RONDAS_CERCANAS).map((r) => ({
117
+ inicio: r.startTime,
118
+ estado: r.status,
119
+ vigilante: r.patrollerName,
120
+ }));
121
+ return ok({ ...(await rondaConDetalle(gateway, token, ruta, elegida)), otrasRondasCercanas });
122
+ }
123
+ /** Rondas: estado general, detalle por ruta, checkpoints de la última y una ronda concreta. */
124
+ export function roundReads({ gateway }) {
125
+ return [
126
+ defineRead({
127
+ name: 'consultar_estado_rondas',
128
+ description: rondasDesc,
129
+ params: {},
130
+ call: async ({ org, token }) => ok(await gateway.getRoundsStatus(org.orgId, token)),
131
+ }),
132
+ defineRead({
133
+ name: 'consultar_detalles_rondas',
134
+ description: rondasDetalleDesc,
135
+ params: {},
136
+ call: async ({ org, token }) => {
137
+ const rutas = await gateway.getRoundsDetail(org.orgId, token);
138
+ return okLista(rutas, 'rutas', avisosRutasConError(rutas.items));
139
+ },
140
+ }),
141
+ defineRead({
142
+ name: 'consultar_checkpoints_ronda',
143
+ description: checkpointsRondaDesc,
144
+ params: rutaParamSchema,
145
+ call: async ({ org, token }, { ruta }) => checkpointsRondaResult(await gateway.getRoundCheckpoints(org.orgId, token, ruta)),
146
+ }),
147
+ defineRead({
148
+ name: 'consultar_ronda',
149
+ description: rondaDesc,
150
+ params: rondaParamSchema,
151
+ call: async ({ org, token, tz }, { ruta, fecha, hora }) => {
152
+ const r = resolveRuta(ruta, (await gateway.listRoutes(org.orgId, token)).items);
153
+ if (isFail(r))
154
+ return r;
155
+ return consultarRonda(gateway, token, r.item, fecha ? { fecha, hora, tz } : undefined);
156
+ },
157
+ }),
158
+ ];
159
+ }
160
+ //# sourceMappingURL=rounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rounds.js","sourceRoot":"","sources":["../../src/reads/rounds.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type ReadCapability, type ReadEnv } from './types.js';
2
+ /** Rutas: sus horarios en la hora del cliente. */
3
+ export declare function routeReads({ gateway }: ReadEnv): ReadCapability[];
4
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/reads/routes.ts"],"names":[],"mappings":"AAMA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAK3E,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,GAAG,cAAc,EAAE,CAqBjE"}
@@ -0,0 +1,34 @@
1
+ import { listarHorarios } from '../domain/route-schedule.js';
2
+ import { utcOffsetMinutes } from '../domain/timezone.js';
3
+ import { fail, ok } from '../domain/tool-result.js';
4
+ import { rutaParamSchema } from './support/params.js';
5
+ import { resolveRuta } from './support/resolve.js';
6
+ import { isFail } from './support/results.js';
7
+ import { defineRead } from './types.js';
8
+ const horariosRutaDesc = 'Lista los horarios de una ruta en la hora LOCAL del cliente, numerados («1. lun, mar 20:00-21:00»), y si la ruta está activa. Cada horario es una ronda: días en los que empieza y franja (si acaba antes de empezar, cruza la medianoche). Úsala para «¿qué horarios tiene la ruta?» o antes de borrar uno. Si el usuario no dice la ruta, llámala sin `ruta`.';
9
+ /** Rutas: sus horarios en la hora del cliente. */
10
+ export function routeReads({ gateway }) {
11
+ return [
12
+ defineRead({
13
+ name: 'consultar_horarios_ruta',
14
+ description: horariosRutaDesc,
15
+ params: rutaParamSchema,
16
+ call: async ({ org, token, tz }, { ruta }) => {
17
+ const r = resolveRuta(ruta, (await gateway.listRoutes(org.orgId, token)).items);
18
+ if (isFail(r))
19
+ return r;
20
+ const detalle = await gateway.getRouteDetails(r.item.id, token);
21
+ if (!detalle)
22
+ return fail(`No he podido leer la ruta «${r.item.name}».`);
23
+ const horarios = listarHorarios(detalle.timeWindows, utcOffsetMinutes(tz));
24
+ return ok({
25
+ ruta: r.item.name,
26
+ activa: r.item.isActive,
27
+ zonaHoraria: tz,
28
+ horarios: horarios.map((h, i) => `${i + 1}. ${h.texto}`),
29
+ });
30
+ },
31
+ }),
32
+ ];
33
+ }
34
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/reads/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAqC,MAAM,YAAY,CAAC;AAE3E,MAAM,gBAAgB,GACpB,iWAAiW,CAAC;AAEpW,kDAAkD;AAClD,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAW;IAC7C,OAAO;QACL,UAAU,CAAC;YACT,IAAI,EAAE,yBAAyB;YAC/B,WAAW,EAAE,gBAAgB;YAC7B,MAAM,EAAE,eAAe;YACvB,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;gBAC3C,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBAChF,IAAI,MAAM,CAAC,CAAC,CAAC;oBAAE,OAAO,CAAC,CAAC;gBACxB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;gBAChE,IAAI,CAAC,OAAO;oBAAE,OAAO,IAAI,CAAC,8BAA8B,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;gBACzE,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC3E,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI;oBACjB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ;oBACvB,WAAW,EAAE,EAAE;oBACf,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;iBACzD,CAAC,CAAC;YACL,CAAC;SACF,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type ToolResult } from '../../domain/tool-result.js';
2
+ import type { LocationRef, PatrolTechGateway } from '../../gateway/index.js';
3
+ /** Recorrido de las ubicaciones del Control de Acceso (el backend exige una por consulta). */
4
+ export declare const TIPO_PARAM: {
5
+ readonly entrada: "ENTRY";
6
+ readonly salida: "EXIT";
7
+ };
8
+ /** Las ubicaciones a recorrer: la pedida o todas. */
9
+ export declare function ubicacionesAccesos(gateway: PatrolTechGateway, orgId: string, token: string, ubicacion: string | undefined): Promise<{
10
+ ubicaciones: LocationRef[];
11
+ avisos: string[];
12
+ } | ToolResult<never>>;
13
+ /** Recorre las ubicaciones con `leer`; un 403 del gate es la App apagada y corta. Las demás caídas se cuentan. */
14
+ export declare function porUbicacion<T>(ubicaciones: LocationRef[], leer: (u: LocationRef) => Promise<T>): Promise<{
15
+ resultados: {
16
+ ubicacion: LocationRef;
17
+ valor: T;
18
+ }[];
19
+ conError: number;
20
+ } | ToolResult<never>>;
21
+ export declare function avisoUbicacionesSinLeer(conError: number): string[];
22
+ //# sourceMappingURL=access-locations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-locations.d.ts","sourceRoot":"","sources":["../../../src/reads/support/access-locations.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAI7E,8FAA8F;AAE9F,eAAO,MAAM,UAAU;;;CAAgD,CAAC;AAOxE,qDAAqD;AACrD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC;IAAE,WAAW,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAc/E;AAED,kHAAkH;AAClH,wBAAsB,YAAY,CAAC,CAAC,EAClC,WAAW,EAAE,WAAW,EAAE,EAC1B,IAAI,EAAE,CAAC,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GACnC,OAAO,CACR;IAAE,UAAU,EAAE;QAAE,SAAS,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAC7F,CAiBA;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlE"}
@@ -0,0 +1,55 @@
1
+ import { isFeatureDisabled, PatrolTechApiError } from '../../domain/backend-errors.js';
2
+ import { fail } from '../../domain/tool-result.js';
3
+ import { isFail } from './results.js';
4
+ import { resolveNamed, UBICACION } from './resolve.js';
5
+ /** Recorrido de las ubicaciones del Control de Acceso (el backend exige una por consulta). */
6
+ export const TIPO_PARAM = { entrada: 'ENTRY', salida: 'EXIT' };
7
+ // Como mucho 20 ubicaciones por consulta (dos llamadas por ubicación);
8
+ // una organización con más tiene que acotar con `ubicacion`.
9
+ const MAX_UBICACIONES_ACCESOS = 20;
10
+ const CONTROL_ACCESO_APAGADO = 'El Control de Acceso no está activo en esta organización: no hay registros de entradas y salidas. Lo activa un Admin en el panel, en Apps → Control de Acceso.';
11
+ /** Las ubicaciones a recorrer: la pedida o todas. */
12
+ export async function ubicacionesAccesos(gateway, orgId, token, ubicacion) {
13
+ const todas = await gateway.listLocations(orgId, token);
14
+ if (ubicacion) {
15
+ const r = resolveNamed(ubicacion, todas, (l) => l.name, UBICACION);
16
+ if (isFail(r))
17
+ return r;
18
+ return { ubicaciones: [r.item], avisos: [] };
19
+ }
20
+ const avisos = todas.length > MAX_UBICACIONES_ACCESOS
21
+ ? [
22
+ `La organización tiene ${todas.length} ubicaciones: solo se han consultado ${MAX_UBICACIONES_ACCESOS}. Pide la ubicación para ver las demás.`,
23
+ ]
24
+ : [];
25
+ return { ubicaciones: todas.slice(0, MAX_UBICACIONES_ACCESOS), avisos };
26
+ }
27
+ /** Recorre las ubicaciones con `leer`; un 403 del gate es la App apagada y corta. Las demás caídas se cuentan. */
28
+ export async function porUbicacion(ubicaciones, leer) {
29
+ const resultados = [];
30
+ let conError = 0;
31
+ for (const u of ubicaciones) {
32
+ try {
33
+ resultados.push({ ubicacion: u, valor: await leer(u) });
34
+ }
35
+ catch (err) {
36
+ if (isFeatureDisabled(err))
37
+ return fail(CONTROL_ACCESO_APAGADO);
38
+ // Un rol solo de otra ubicación da 403 en esta: se cuenta y se sigue.
39
+ if (err instanceof PatrolTechApiError) {
40
+ conError += 1;
41
+ continue;
42
+ }
43
+ throw err;
44
+ }
45
+ }
46
+ return { resultados, conError };
47
+ }
48
+ export function avisoUbicacionesSinLeer(conError) {
49
+ return conError > 0
50
+ ? [
51
+ `${conError} ubicación(es) no se pudieron consultar (permisos o error): sus accesos faltan. No afirmes que allí no ha entrado nadie.`,
52
+ ]
53
+ : [];
54
+ }
55
+ //# sourceMappingURL=access-locations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-locations.js","sourceRoot":"","sources":["../../../src/reads/support/access-locations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACvF,OAAO,EAAE,IAAI,EAAmB,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEvD,8FAA8F;AAE9F,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAW,CAAC;AACxE,uEAAuE;AACvE,6DAA6D;AAC7D,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,sBAAsB,GAC1B,gKAAgK,CAAC;AAEnK,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAA0B,EAC1B,KAAa,EACb,KAAa,EACb,SAA6B;IAE7B,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACxD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QACxB,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC/C,CAAC;IACD,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,GAAG,uBAAuB;QACpC,CAAC,CAAC;YACE,yBAAyB,KAAK,CAAC,MAAM,wCAAwC,uBAAuB,yCAAyC;SAC9I;QACH,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;AAC1E,CAAC;AAED,kHAAkH;AAClH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAA0B,EAC1B,IAAoC;IAIpC,MAAM,UAAU,GAA2C,EAAE,CAAC;IAC9D,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,iBAAiB,CAAC,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAChE,sEAAsE;YACtE,IAAI,GAAG,YAAY,kBAAkB,EAAE,CAAC;gBACtC,QAAQ,IAAI,CAAC,CAAC;gBACd,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,OAAO,QAAQ,GAAG,CAAC;QACjB,CAAC,CAAC;YACE,GAAG,QAAQ,0HAA0H;SACtI;QACH,CAAC,CAAC,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type ToolResult } from '../../domain/tool-result.js';
2
+ import type { FileSink } from '../../ports/FileSink.js';
3
+ /** Comprueba el periodo de un Excel (fechas YYYY-MM-DD, en orden y de 31 días como mucho); null si vale. */
4
+ export declare function validarPeriodoExcel(desdeYmd: string, hastaYmd: string): ToolResult<never> | null;
5
+ /**
6
+ * Envía un CSV como documento que se abre con Excel. Va declarado como lo que es
7
+ * (`text/csv`): el adaptador de cada canal lo cambia si su plataforma no lo admite.
8
+ */
9
+ export declare function enviarCsv(files: FileSink, bytes: Uint8Array, filename: string, caption: string): Promise<void>;
10
+ //# sourceMappingURL=excel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"excel.d.ts","sourceRoot":"","sources":["../../../src/reads/support/excel.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAOxD,4GAA4G;AAC5G,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,IAAI,CAYhG;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,35 @@
1
+ import { parseLocalDate } from '../../domain/date-range.js';
2
+ import { fail } from '../../domain/tool-result.js';
3
+ import { DIA_MS } from './scans.js';
4
+ /** Lo común de los Excel que se envían: el periodo admitido y cómo sale el fichero. */
5
+ const MAX_DIAS = 31;
6
+ /** Comprueba el periodo de un Excel (fechas YYYY-MM-DD, en orden y de 31 días como mucho); null si vale. */
7
+ export function validarPeriodoExcel(desdeYmd, hastaYmd) {
8
+ const desde = parseLocalDate(desdeYmd);
9
+ const hasta = parseLocalDate(hastaYmd);
10
+ if (!desde || !hasta)
11
+ return fail('Fechas no válidas: usa YYYY-MM-DD en «desde» y «hasta».');
12
+ const dias = (Date.UTC(hasta.y, hasta.m - 1, hasta.d) - Date.UTC(desde.y, desde.m - 1, desde.d)) / DIA_MS +
13
+ 1;
14
+ if (dias < 1)
15
+ return fail('«desde» es posterior a «hasta»: corrige las fechas.');
16
+ if (dias > MAX_DIAS) {
17
+ return fail(`El periodo máximo es de ${MAX_DIAS} días: pídelo por meses o acota las fechas.`);
18
+ }
19
+ return null;
20
+ }
21
+ /**
22
+ * Envía un CSV como documento que se abre con Excel. Va declarado como lo que es
23
+ * (`text/csv`): el adaptador de cada canal lo cambia si su plataforma no lo admite.
24
+ */
25
+ export async function enviarCsv(files, bytes, filename, caption) {
26
+ await files.sendDocument({
27
+ bytes,
28
+ filename,
29
+ // Un canal que no admita `text/csv` puede subirlo como `application/vnd.ms-excel` (el nombre
30
+ // sigue siendo .csv).
31
+ mimeType: 'text/csv',
32
+ caption,
33
+ });
34
+ }
35
+ //# sourceMappingURL=excel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"excel.js","sourceRoot":"","sources":["../../../src/reads/support/excel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAmB,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,uFAAuF;AAEvF,MAAM,QAAQ,GAAG,EAAE,CAAC;AAEpB,4GAA4G;AAC5G,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,QAAgB;IACpE,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,yDAAyD,CAAC,CAAC;IAC7F,MAAM,IAAI,GACR,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM;QAC5F,CAAC,CAAC;IACJ,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,qDAAqD,CAAC,CAAC;IACjF,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,2BAA2B,QAAQ,6CAA6C,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAe,EACf,KAAiB,EACjB,QAAgB,EAChB,OAAe;IAEf,MAAM,KAAK,CAAC,YAAY,CAAC;QACvB,KAAK;QACL,QAAQ;QACR,6FAA6F;QAC7F,sBAAsB;QACtB,QAAQ,EAAE,UAAU;QACpB,OAAO;KACR,CAAC,CAAC;AACL,CAAC"}