@hawkeyexl/manni 4.10.0 → 4.12.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 (243) hide show
  1. package/README.md +1 -1
  2. package/dist/batch-EFSFG6GC.js +46 -0
  3. package/dist/build-NIO3UIWJ.js +36 -0
  4. package/dist/calibrate-6VO7URRV.js +41 -0
  5. package/dist/capture-NMBVJO3C.js +38 -0
  6. package/dist/check-SHOYX2B5.js +30 -0
  7. package/dist/check-XMJKH3KV.js +34 -0
  8. package/dist/{check-NLL4NRYA.js → check-Y62BJNC4.js} +35 -31
  9. package/dist/{check-NLL4NRYA.js.map → check-Y62BJNC4.js.map} +1 -1
  10. package/dist/{check-7B77ZD2N.js → check-ZMO3ZLMW.js} +19 -15
  11. package/dist/{chunk-PK7EKJ5T.js → chunk-24AJK2RG.js} +5 -10
  12. package/dist/chunk-24AJK2RG.js.map +1 -0
  13. package/dist/chunk-2OZF2VUB.js +164 -0
  14. package/dist/chunk-2OZF2VUB.js.map +1 -0
  15. package/dist/chunk-2UJZXVHR.js +1868 -0
  16. package/dist/chunk-2UJZXVHR.js.map +1 -0
  17. package/dist/{chunk-DNZUBCGZ.js → chunk-3BRJCQPY.js} +36 -7
  18. package/dist/chunk-3BRJCQPY.js.map +1 -0
  19. package/dist/{chunk-D2UW3ZCK.js → chunk-42VFJOAF.js} +13 -11
  20. package/dist/{chunk-D2UW3ZCK.js.map → chunk-42VFJOAF.js.map} +1 -1
  21. package/dist/{chunk-LQZQ5KGG.js → chunk-4Q24OYI3.js} +7 -7
  22. package/dist/{chunk-XU73V5XT.js → chunk-4WJTURRO.js} +15 -15
  23. package/dist/{chunk-WN47MNSK.js → chunk-5SID2SVL.js} +4 -4
  24. package/dist/{chunk-5REEVKGH.js → chunk-AANUY4BH.js} +2 -2
  25. package/dist/chunk-ANPIIYRH.js +2272 -0
  26. package/dist/chunk-ANPIIYRH.js.map +1 -0
  27. package/dist/{chunk-RZVCWX5R.js → chunk-AYVKN3PG.js} +4 -4
  28. package/dist/{chunk-2UCC26MO.js → chunk-CH6IOGXV.js} +9 -9
  29. package/dist/{chunk-RODZ7MB7.js → chunk-D5Z6B4M7.js} +6 -6
  30. package/dist/{chunk-IJ62BB2T.js → chunk-D6SELXQ2.js} +7 -7
  31. package/dist/{chunk-2JV7C4YV.js → chunk-DDILEF5F.js} +890 -1399
  32. package/dist/chunk-DDILEF5F.js.map +1 -0
  33. package/dist/{chunk-3E2X2RBU.js → chunk-DGRLHDM4.js} +9 -9
  34. package/dist/{chunk-2BV4FBC7.js → chunk-DHGB4JBG.js} +4 -3
  35. package/dist/chunk-DHGB4JBG.js.map +1 -0
  36. package/dist/{chunk-6LR73NMO.js → chunk-DLU5FCFT.js} +30 -28
  37. package/dist/chunk-DLU5FCFT.js.map +1 -0
  38. package/dist/chunk-DSWKBZWW.js +16 -0
  39. package/dist/chunk-DSWKBZWW.js.map +1 -0
  40. package/dist/{chunk-BD7IXBWE.js → chunk-F564FHMQ.js} +8 -8
  41. package/dist/{chunk-ABHG6I3G.js → chunk-FKAZUZQU.js} +469 -85
  42. package/dist/chunk-FKAZUZQU.js.map +1 -0
  43. package/dist/{chunk-DFCQ6BMI.js → chunk-G3MBUL5M.js} +4 -4
  44. package/dist/{chunk-SUTMSDQ2.js → chunk-GQ3KRY3B.js} +3 -3
  45. package/dist/chunk-HDPN46JP.js +393 -0
  46. package/dist/chunk-HDPN46JP.js.map +1 -0
  47. package/dist/{chunk-EAUIQADY.js → chunk-IQQAJROD.js} +6 -6
  48. package/dist/{chunk-ZHRPH52H.js → chunk-IZXN3WI6.js} +2 -2
  49. package/dist/{chunk-NCPWXHDO.js → chunk-JEUFYSFQ.js} +4 -4
  50. package/dist/{chunk-G6FNWRAI.js → chunk-JSSM7VVV.js} +4 -4
  51. package/dist/{chunk-CCWMACJL.js → chunk-KFGZPVFA.js} +229 -821
  52. package/dist/chunk-KFGZPVFA.js.map +1 -0
  53. package/dist/{chunk-H26VDFDS.js → chunk-KGFSPJLD.js} +2 -2
  54. package/dist/{chunk-AO5TSDKT.js → chunk-KMORGMCW.js} +7 -7
  55. package/dist/{chunk-WQWKYAAK.js → chunk-NUQF5F5J.js} +2 -2
  56. package/dist/{chunk-2YJ5H5E6.js → chunk-NZ6KSHFD.js} +23 -21
  57. package/dist/{chunk-2YJ5H5E6.js.map → chunk-NZ6KSHFD.js.map} +1 -1
  58. package/dist/{chunk-7Y3N4Y72.js → chunk-OHUDZRLK.js} +3 -3
  59. package/dist/{chunk-GCKHSBEN.js → chunk-OKMTUAWO.js} +4 -4
  60. package/dist/{chunk-6M5VJOC2.js → chunk-OTJOBZJ5.js} +167 -166
  61. package/dist/chunk-OTJOBZJ5.js.map +1 -0
  62. package/dist/{chunk-2W34HX2U.js → chunk-PS257NIU.js} +288 -373
  63. package/dist/chunk-PS257NIU.js.map +1 -0
  64. package/dist/chunk-QDC7JPFG.js +685 -0
  65. package/dist/chunk-QDC7JPFG.js.map +1 -0
  66. package/dist/chunk-QEAGL4V5.js +3185 -0
  67. package/dist/chunk-QEAGL4V5.js.map +1 -0
  68. package/dist/{chunk-GB2XPITA.js → chunk-QMY57PVW.js} +2 -2
  69. package/dist/{chunk-55GMOVKW.js → chunk-QNDDPXFR.js} +2 -2
  70. package/dist/{chunk-GXN7RRHR.js → chunk-QSIXNTRV.js} +4 -4
  71. package/dist/{chunk-G7XD4QH5.js → chunk-RGLFV4KO.js} +11372 -10218
  72. package/dist/chunk-RGLFV4KO.js.map +1 -0
  73. package/dist/{chunk-QBVP3SQP.js → chunk-SGR7ZAVE.js} +13 -7
  74. package/dist/chunk-SGR7ZAVE.js.map +1 -0
  75. package/dist/{chunk-KBG463UK.js → chunk-SMHAYK6I.js} +2409 -5243
  76. package/dist/chunk-SMHAYK6I.js.map +1 -0
  77. package/dist/{chunk-XG6PVB5S.js → chunk-SSQZB5SQ.js} +1 -11
  78. package/dist/chunk-SSQZB5SQ.js.map +1 -0
  79. package/dist/{chunk-GDLHTI5R.js → chunk-STPGIKPY.js} +8 -2
  80. package/dist/chunk-STPGIKPY.js.map +1 -0
  81. package/dist/{chunk-QJRQ4BRC.js → chunk-U22TOL5Y.js} +17 -17
  82. package/dist/{chunk-NGTVREIH.js → chunk-U6IHLEWT.js} +2 -2
  83. package/dist/{chunk-Z5YHMRLF.js → chunk-UUCCV3SI.js} +2 -2
  84. package/dist/{chunk-ZXXFP2LA.js → chunk-UXMCHBOJ.js} +2 -2
  85. package/dist/{chunk-VZVEP2OZ.js → chunk-VFAKGIDG.js} +2 -2
  86. package/dist/{chunk-QCHVR4ZM.js → chunk-VM7VAFJW.js} +33 -7
  87. package/dist/chunk-VM7VAFJW.js.map +1 -0
  88. package/dist/{chunk-VQK4VHLF.js → chunk-YQV75FIL.js} +2 -2
  89. package/dist/chunk-YUTVAMWW.js +2 -0
  90. package/dist/chunk-ZPLVANY2.js +15 -0
  91. package/dist/chunk-ZPLVANY2.js.map +1 -0
  92. package/dist/{cli-BIIUKPTE.js → cli-4CR7QIOK.js} +26 -22
  93. package/dist/{cli-BIIUKPTE.js.map → cli-4CR7QIOK.js.map} +1 -1
  94. package/dist/{cli-V2DI3K2R.js → cli-6R4W3HAH.js} +37 -33
  95. package/dist/{cli-V2DI3K2R.js.map → cli-6R4W3HAH.js.map} +1 -1
  96. package/dist/{cli-HO62TOM2.js → cli-BOMA2FMP.js} +14 -11
  97. package/dist/{cli-EH3I4IUX.js → cli-EDQPQOCE.js} +47 -41
  98. package/dist/cli-EDQPQOCE.js.map +1 -0
  99. package/dist/{cli-P2X7PNY6.js → cli-GBF76EXT.js} +25 -20
  100. package/dist/{cli-P2X7PNY6.js.map → cli-GBF76EXT.js.map} +1 -1
  101. package/dist/{cli-4YYC6LCY.js → cli-MQYCF3SR.js} +27 -23
  102. package/dist/{cli-4YYC6LCY.js.map → cli-MQYCF3SR.js.map} +1 -1
  103. package/dist/{cli-UETKXHJN.js → cli-OJKFXQOM.js} +9 -9
  104. package/dist/{cli-LWST5FQH.js → cli-PHZAO4LZ.js} +4 -4
  105. package/dist/{cli-TELPAMJO.js → cli-PTKFFNOW.js} +59 -35
  106. package/dist/cli-PTKFFNOW.js.map +1 -0
  107. package/dist/{cli-SGVFZOAW.js → cli-UW2K5Z5J.js} +34 -29
  108. package/dist/{cli-SGVFZOAW.js.map → cli-UW2K5Z5J.js.map} +1 -1
  109. package/dist/cli-XXTNPPKB.js +83 -0
  110. package/dist/cli-XXTNPPKB.js.map +1 -0
  111. package/dist/cli.js +24 -12
  112. package/dist/cli.js.map +1 -1
  113. package/dist/{config-TYXYQK3I.js → config-JJW75SBX.js} +5 -5
  114. package/dist/docmeta.js +13 -10
  115. package/dist/docmeta.js.map +1 -1
  116. package/dist/github-6VQKSB67.js +35 -0
  117. package/dist/github-RBSEM7ZK.js +30 -0
  118. package/dist/graph/runtime.d.ts +4 -1
  119. package/dist/graph/runtime.js +20 -9
  120. package/dist/graph/runtime.js.map +1 -1
  121. package/dist/{host-6GURH5HE.js → host-YSTYO5DX.js} +3 -3
  122. package/dist/index.d.ts +1214 -940
  123. package/dist/index.js +190 -160
  124. package/dist/index.js.map +1 -1
  125. package/dist/{json-QR4G35KA.js → json-PU2HLHDQ.js} +18 -14
  126. package/dist/labels-SJNSOPBI.js +73 -0
  127. package/dist/labels-SJNSOPBI.js.map +1 -0
  128. package/dist/lint-KIVTHLGU.js +34 -0
  129. package/dist/list-RDEJDDJF.js +32 -0
  130. package/dist/list-SUTDWL2J.js +35 -0
  131. package/dist/{page-FSXDXCDD.js → page-UMAA3NCM.js} +18 -13
  132. package/dist/{prepare-UPIBTFNS.js → prepare-3I3LOXXD.js} +24 -20
  133. package/dist/{prepare-UPIBTFNS.js.map → prepare-3I3LOXXD.js.map} +1 -1
  134. package/dist/{pretty-4IONWSEP.js → pretty-ANLRHU4O.js} +18 -14
  135. package/dist/{pretty-R4BQD2VH.js → pretty-Q3ZFKOR7.js} +18 -14
  136. package/dist/{provider-527CO4DM.js → provider-LBX4IXGX.js} +3 -3
  137. package/dist/{release-3D5PK6M7.js → release-VV3UTKE5.js} +3 -3
  138. package/dist/{reporters-M6LJ2IYU.js → reporters-26H3N2KW.js} +3 -3
  139. package/dist/{reporters-DHO2BXAD.js → reporters-ILT36CIH.js} +7 -7
  140. package/dist/{reporters-FPP6JNDP.js → reporters-PNDLWT6K.js} +16 -12
  141. package/dist/run-QXCK33Z4.js +37 -0
  142. package/dist/{term-ASM4LVYC.js → term-D2N7UN4P.js} +981 -138
  143. package/dist/term-D2N7UN4P.js.map +1 -0
  144. package/dist/validate-BRUCOT2O.js +19 -0
  145. package/dist/validate-BRUCOT2O.js.map +1 -0
  146. package/package.json +3 -2
  147. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  148. package/shapes/graph/shapes-1.1.0.ttl +785 -0
  149. package/dist/batch-6NICDKRE.js +0 -41
  150. package/dist/build-3KP2K3XN.js +0 -32
  151. package/dist/calibrate-LUA3DWKD.js +0 -36
  152. package/dist/capture-NETOHCB4.js +0 -34
  153. package/dist/check-E4QCB7LS.js +0 -20
  154. package/dist/check-PTECPIIB.js +0 -26
  155. package/dist/chunk-2BV4FBC7.js.map +0 -1
  156. package/dist/chunk-2JV7C4YV.js.map +0 -1
  157. package/dist/chunk-2W34HX2U.js.map +0 -1
  158. package/dist/chunk-4DLF5SA4.js +0 -392
  159. package/dist/chunk-4DLF5SA4.js.map +0 -1
  160. package/dist/chunk-6AGESHHM.js +0 -387
  161. package/dist/chunk-6AGESHHM.js.map +0 -1
  162. package/dist/chunk-6LR73NMO.js.map +0 -1
  163. package/dist/chunk-6M5VJOC2.js.map +0 -1
  164. package/dist/chunk-ABHG6I3G.js.map +0 -1
  165. package/dist/chunk-CCWMACJL.js.map +0 -1
  166. package/dist/chunk-DNZUBCGZ.js.map +0 -1
  167. package/dist/chunk-G7XD4QH5.js.map +0 -1
  168. package/dist/chunk-GDLHTI5R.js.map +0 -1
  169. package/dist/chunk-KBG463UK.js.map +0 -1
  170. package/dist/chunk-PK7EKJ5T.js.map +0 -1
  171. package/dist/chunk-QBVP3SQP.js.map +0 -1
  172. package/dist/chunk-QCHVR4ZM.js.map +0 -1
  173. package/dist/chunk-VVVKBUBO.js +0 -818
  174. package/dist/chunk-VVVKBUBO.js.map +0 -1
  175. package/dist/chunk-XG6PVB5S.js.map +0 -1
  176. package/dist/cli-EH3I4IUX.js.map +0 -1
  177. package/dist/cli-TELPAMJO.js.map +0 -1
  178. package/dist/github-ESK45CEZ.js +0 -26
  179. package/dist/github-WER7JUTN.js +0 -31
  180. package/dist/lint-QTI7XK2A.js +0 -30
  181. package/dist/list-JO4G3TS3.js +0 -30
  182. package/dist/list-O2MJUP5V.js +0 -28
  183. package/dist/run-YH5Z7RJ7.js +0 -32
  184. package/dist/term-ASM4LVYC.js.map +0 -1
  185. package/dist/validate-7JI3H57P.js +0 -17
  186. /package/dist/{batch-6NICDKRE.js.map → batch-EFSFG6GC.js.map} +0 -0
  187. /package/dist/{build-3KP2K3XN.js.map → build-NIO3UIWJ.js.map} +0 -0
  188. /package/dist/{calibrate-LUA3DWKD.js.map → calibrate-6VO7URRV.js.map} +0 -0
  189. /package/dist/{capture-NETOHCB4.js.map → capture-NMBVJO3C.js.map} +0 -0
  190. /package/dist/{check-7B77ZD2N.js.map → check-SHOYX2B5.js.map} +0 -0
  191. /package/dist/{check-E4QCB7LS.js.map → check-XMJKH3KV.js.map} +0 -0
  192. /package/dist/{check-PTECPIIB.js.map → check-ZMO3ZLMW.js.map} +0 -0
  193. /package/dist/{chunk-LQZQ5KGG.js.map → chunk-4Q24OYI3.js.map} +0 -0
  194. /package/dist/{chunk-XU73V5XT.js.map → chunk-4WJTURRO.js.map} +0 -0
  195. /package/dist/{chunk-WN47MNSK.js.map → chunk-5SID2SVL.js.map} +0 -0
  196. /package/dist/{chunk-5REEVKGH.js.map → chunk-AANUY4BH.js.map} +0 -0
  197. /package/dist/{chunk-RZVCWX5R.js.map → chunk-AYVKN3PG.js.map} +0 -0
  198. /package/dist/{chunk-2UCC26MO.js.map → chunk-CH6IOGXV.js.map} +0 -0
  199. /package/dist/{chunk-RODZ7MB7.js.map → chunk-D5Z6B4M7.js.map} +0 -0
  200. /package/dist/{chunk-IJ62BB2T.js.map → chunk-D6SELXQ2.js.map} +0 -0
  201. /package/dist/{chunk-3E2X2RBU.js.map → chunk-DGRLHDM4.js.map} +0 -0
  202. /package/dist/{chunk-BD7IXBWE.js.map → chunk-F564FHMQ.js.map} +0 -0
  203. /package/dist/{chunk-DFCQ6BMI.js.map → chunk-G3MBUL5M.js.map} +0 -0
  204. /package/dist/{chunk-SUTMSDQ2.js.map → chunk-GQ3KRY3B.js.map} +0 -0
  205. /package/dist/{chunk-EAUIQADY.js.map → chunk-IQQAJROD.js.map} +0 -0
  206. /package/dist/{chunk-ZHRPH52H.js.map → chunk-IZXN3WI6.js.map} +0 -0
  207. /package/dist/{chunk-NCPWXHDO.js.map → chunk-JEUFYSFQ.js.map} +0 -0
  208. /package/dist/{chunk-G6FNWRAI.js.map → chunk-JSSM7VVV.js.map} +0 -0
  209. /package/dist/{chunk-H26VDFDS.js.map → chunk-KGFSPJLD.js.map} +0 -0
  210. /package/dist/{chunk-AO5TSDKT.js.map → chunk-KMORGMCW.js.map} +0 -0
  211. /package/dist/{chunk-WQWKYAAK.js.map → chunk-NUQF5F5J.js.map} +0 -0
  212. /package/dist/{chunk-7Y3N4Y72.js.map → chunk-OHUDZRLK.js.map} +0 -0
  213. /package/dist/{chunk-GCKHSBEN.js.map → chunk-OKMTUAWO.js.map} +0 -0
  214. /package/dist/{chunk-GB2XPITA.js.map → chunk-QMY57PVW.js.map} +0 -0
  215. /package/dist/{chunk-55GMOVKW.js.map → chunk-QNDDPXFR.js.map} +0 -0
  216. /package/dist/{chunk-GXN7RRHR.js.map → chunk-QSIXNTRV.js.map} +0 -0
  217. /package/dist/{chunk-QJRQ4BRC.js.map → chunk-U22TOL5Y.js.map} +0 -0
  218. /package/dist/{chunk-NGTVREIH.js.map → chunk-U6IHLEWT.js.map} +0 -0
  219. /package/dist/{chunk-Z5YHMRLF.js.map → chunk-UUCCV3SI.js.map} +0 -0
  220. /package/dist/{chunk-ZXXFP2LA.js.map → chunk-UXMCHBOJ.js.map} +0 -0
  221. /package/dist/{chunk-VZVEP2OZ.js.map → chunk-VFAKGIDG.js.map} +0 -0
  222. /package/dist/{chunk-VQK4VHLF.js.map → chunk-YQV75FIL.js.map} +0 -0
  223. /package/dist/{cli-HO62TOM2.js.map → chunk-YUTVAMWW.js.map} +0 -0
  224. /package/dist/{config-TYXYQK3I.js.map → cli-BOMA2FMP.js.map} +0 -0
  225. /package/dist/{cli-UETKXHJN.js.map → cli-OJKFXQOM.js.map} +0 -0
  226. /package/dist/{cli-LWST5FQH.js.map → cli-PHZAO4LZ.js.map} +0 -0
  227. /package/dist/{github-ESK45CEZ.js.map → config-JJW75SBX.js.map} +0 -0
  228. /package/dist/{github-WER7JUTN.js.map → github-6VQKSB67.js.map} +0 -0
  229. /package/dist/{host-6GURH5HE.js.map → github-RBSEM7ZK.js.map} +0 -0
  230. /package/dist/{json-QR4G35KA.js.map → host-YSTYO5DX.js.map} +0 -0
  231. /package/dist/{lint-QTI7XK2A.js.map → json-PU2HLHDQ.js.map} +0 -0
  232. /package/dist/{list-JO4G3TS3.js.map → lint-KIVTHLGU.js.map} +0 -0
  233. /package/dist/{list-O2MJUP5V.js.map → list-RDEJDDJF.js.map} +0 -0
  234. /package/dist/{page-FSXDXCDD.js.map → list-SUTDWL2J.js.map} +0 -0
  235. /package/dist/{pretty-4IONWSEP.js.map → page-UMAA3NCM.js.map} +0 -0
  236. /package/dist/{pretty-R4BQD2VH.js.map → pretty-ANLRHU4O.js.map} +0 -0
  237. /package/dist/{provider-527CO4DM.js.map → pretty-Q3ZFKOR7.js.map} +0 -0
  238. /package/dist/{reporters-DHO2BXAD.js.map → provider-LBX4IXGX.js.map} +0 -0
  239. /package/dist/{release-3D5PK6M7.js.map → release-VV3UTKE5.js.map} +0 -0
  240. /package/dist/{reporters-FPP6JNDP.js.map → reporters-26H3N2KW.js.map} +0 -0
  241. /package/dist/{reporters-M6LJ2IYU.js.map → reporters-ILT36CIH.js.map} +0 -0
  242. /package/dist/{run-YH5Z7RJ7.js.map → reporters-PNDLWT6K.js.map} +0 -0
  243. /package/dist/{validate-7JI3H57P.js.map → run-QXCK33Z4.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/meta/cli.ts","../src/meta/reporters/relocate.ts","../src/meta/commands/validate-offer.ts","../src/meta/reporters/infer.ts"],"sourcesContent":["/**\n * docmeta CLI. Thin commander wrapper over the command cores. Follows clig.dev:\n * primary output to stdout, diagnostics to stderr, color only on a TTY (and\n * never when NO_COLOR/--no-color), meaningful exit codes (0 ok, 1 validation\n * failures, 2 operational/usage errors).\n */\nimport { existsSync } from \"node:fs\";\nimport { extname, resolve as resolvePath } from \"node:path\";\nimport { Command, Option } from \"commander\";\nimport picomatch from \"picomatch\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport {\n collect,\n configOption,\n explicitFalse,\n readStdin,\n reportConfig,\n splitList,\n} from \"../shared/cli-options.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice, warn } from \"../shared/warn.js\";\nimport { LOCAL_FLAG_HELP } from \"../shared/providers.js\";\nimport { terminalConfirm } from \"../shared/prompt.js\";\nimport {\n DocmetaError,\n type RunSummary,\n type ValidationResult,\n} from \"./types.js\";\nimport { runValidate } from \"./commands/validate.js\";\nimport { offerRelocation } from \"./commands/validate-offer.js\";\nimport { runGet } from \"./commands/get.js\";\nimport { runQuery } from \"./commands/query.js\";\nimport {\n DEFAULT_VENDOR_DIR,\n getSchemasInfo,\n runInferSchema,\n runVendorSchema,\n} from \"./commands/schemas.js\";\nimport { runFill } from \"./commands/fill.js\";\nimport { deriveFailed, runDerive } from \"./commands/derive.js\";\nimport { supportedExtensions } from \"./extractors/index.js\";\nimport {\n COMMON_FORMATS,\n COMMON_FORMAT_LIST,\n OMITTED_WHEN_CLEAN,\n QUERY_FORMATS,\n QUERY_FORMAT_LIST,\n REPORT_FORMATS,\n REPORT_FORMAT_LIST,\n isCommonFormat,\n isMachineFormat,\n isQueryFindingsFormat,\n isQueryFormat,\n isReportFormat,\n render,\n type CommonFormat,\n type QueryFindingsFormat,\n} from \"./reporters/index.js\";\nimport { rowsToFindings } from \"./core/checks.js\";\nimport { loadConfig } from \"./core/config.js\";\nimport type { RegisteredSchemas } from \"./core/schema-registry.js\";\nimport { isParamName } from \"./core/projection.js\";\nimport type { QueryRun } from \"./commands/query.js\";\nimport {\n FILL_FORMATS,\n FILL_FORMAT_LIST,\n isFillFormat,\n renderFill,\n} from \"./reporters/fill.js\";\nimport {\n DERIVE_FORMATS,\n DERIVE_FORMAT_LIST,\n isDeriveFormat,\n renderDerive,\n} from \"./reporters/derive.js\";\nimport { relocateFailed, runRelocate } from \"./commands/relocate.js\";\nimport {\n RELOCATE_FORMATS,\n isRelocateFormat,\n renderRelocate,\n} from \"./reporters/relocate.js\";\nimport { renderGet } from \"./reporters/get.js\";\nimport { renderQuery, renderQueryCsv } from \"./reporters/query.js\";\nimport { renderInfer } from \"./reporters/infer.js\";\nimport { shouldColor, palette } from \"../shared/color.js\";\n\nfunction resolveColor(program: Command): boolean {\n // commander maps --no-color to opts.color === false.\n const noColor = program.opts().color === false;\n // Passed through uncoerced. `@types/node` declares `isTTY` as `boolean`, but\n // Node leaves it **undefined** on a stream that is not a terminal — it is\n // never `false` — and `shouldColor` already takes `isTTY?` and treats a\n // missing one as \"not a terminal\". A `Boolean()` here only restated that,\n // where the declared type says it restates nothing.\n return shouldColor({ noColor, isTTY: process.stdout.isTTY });\n}\n\n/**\n * The `--format` a subcommand was actually given, when its **parent** also\n * declares one.\n *\n * commander lets an option declared on a parent be written anywhere in the\n * argv, so `manni meta schemas infer -f json` binds `json` to the `schemas`\n * command — `infer`'s own `--format` keeps its default and the run answers in\n * `pretty`. Silently. That is the same false green `schemas -f github` was\n * fixed for: a request docmeta could honor, answered in a format nobody asked\n * for, with exit 0.\n *\n * `getOptionValueSource` is the public way to tell a typed value from a\n * default, so this reads both commands and prefers whichever was actually\n * typed, rather than depending on which one commander happens to bind to.\n */\nfunction formatFor(command: Command, own: unknown): unknown {\n if (command.getOptionValueSource(\"format\") === \"cli\") return own;\n const parent = command.parent;\n if (parent && parent.getOptionValueSource(\"format\") === \"cli\") {\n return parent.opts().format;\n }\n return own;\n}\n\n/** A `--format` value one of the two-format commands (`get`, `schemas`) rejects. */\nfunction assertCommonFormat(value: unknown): CommonFormat {\n const format = String(value);\n if (!isCommonFormat(format)) {\n throw new DocmetaError(\n `Unknown --format \"${format}\". Use ${COMMON_FORMAT_LIST}.`,\n );\n }\n return format;\n}\n\n/** The one input token that is neither a path nor a field: stdin. */\nconst STDIN = \"-\";\n\n/**\n * Does this token name a path rather than a field list?\n *\n * `get`'s field list is positional, so a user who forgets it has their *path*\n * bound to `[fields]`. Since the argument became optional the CLI can say so\n * outright instead of reporting the paths that are left as missing.\n *\n * The four positive tests mirror `suggestCommand`'s, `existsSync` included —\n * that leg is the one that catches a bare directory name (`manni meta get docs`),\n * which has neither a dot, a separator, nor a glob character.\n *\n * `existsSync` alone is too eager for a token with **no path shape at all**,\n * though, because field names collide with directory names constantly: `tags`,\n * `docs`, `type`, `content`. In a site repo holding a `tags/` directory,\n * `manni meta get tags docs/a.md` was refused as a path, and the remedy it\n * suggested (`manni meta get title tags`) was nonsense. So a shapeless token is\n * only read as a path when it is **alone** — nothing else was offered as one,\n * which is the shape of someone who forgot the field list. Give a path *and* a\n * bare name and the bare name is the field list: the only reading that makes\n * sense of both.\n *\n * Two negative tests matter more than any of the shape tests, because a false\n * positive rejects a legal field list:\n *\n * - a **comma** makes it a list, and a path holding one is vanishingly rare;\n * - a **leading `/`** is a JSON Pointer, the documented way to address a nested\n * or dotted key — `manni meta get /author/email page.md` is exactly the usage\n * the separator test would otherwise refuse.\n *\n * They do not run *first*, though, and the distinction is worth stating because\n * the obvious reading of the list above is that they do: a token that names a\n * file which really exists is taken as a path before either is consulted. So a\n * JSON Pointer that happens to match a real absolute path — `/author/email`, on\n * a machine where that file exists — is read as a path. `--fields` is the\n * escape, and is why the guard can afford to be wrong here.\n */\nfunction looksLikePath(token: string, cwd: string, alone: boolean): boolean {\n if (token === STDIN) return false;\n // One scan, used twice: `shaped` needs it, and so does the positive test\n // below when `existsSync` did not settle the question.\n const scan = picomatch.scan(token);\n const shaped = /[\\\\/]/.test(token) || extname(token) !== \"\" || scan.isGlob;\n // A file that really is there settles it — but only when the token looks\n // like a path, or nothing else was offered as one.\n if ((shaped || alone) && existsSync(resolvePath(cwd, token))) return true;\n if (token.includes(\",\") || token.startsWith(\"/\")) return false;\n if (scan.isGlob) return true;\n const ext = extname(token).toLowerCase();\n if (ext !== \"\" && supportedExtensions().includes(ext)) return true;\n return /[\\\\/]/.test(token);\n}\n\n/**\n * `get`'s one input rule: **if `--fields` is present, every positional is a\n * path.** Otherwise the first positional is the field list, exactly as before.\n *\n * The missing-field-list case is handled *here* rather than left to `runGet`.\n * `options.fields ?? fieldsArg` is `undefined` when neither was given, and\n * `String(undefined).split(\",\")` is `[\"undefined\"]` — a field list of length\n * one, so `runGet`'s `fields.length === 0` guard never fires and a bare\n * `manni meta get` in a repo with config `paths:` prints `undefined=(unset)` per\n * file and exits 0. A successful-looking report for a field nobody named is\n * worse than the error it replaced.\n *\n * The positional is folded in on `fieldsArg !== undefined`, not with\n * `.filter(Boolean)`: an empty-string path is a mistake worth reporting, and\n * filtering it would silently drop it instead.\n */\nexport function resolveGetInputs(\n fieldsArg: string | undefined,\n pathsArg: string[],\n fieldsOption: unknown,\n cwd: string,\n): { fields: string[]; paths: string[] } {\n const flag = typeof fieldsOption === \"string\" ? fieldsOption : undefined;\n\n if (\n flag === undefined &&\n fieldsArg !== undefined &&\n looksLikePath(fieldsArg, cwd, pathsArg.length === 0)\n ) {\n throw new DocmetaError(\n `\"${fieldsArg}\" looks like a path, not a field list. Pass fields first (manni meta get title ${fieldsArg}) or use --fields.`,\n );\n }\n\n // `-` is stdin, never a field name. Letting it become one made\n // `manni meta get - --as markdown` print `-=(unset)` for every file in the\n // config's `paths:` and exit 0 — the piped document never read, the run\n // looking entirely successful. Dropping it here leaves `fields` empty, so\n // the missing-field-list error below fires instead.\n const source = flag ?? (fieldsArg === STDIN ? undefined : fieldsArg);\n const fields = source === undefined ? [] : splitList(source);\n if (fields.length === 0) {\n throw new DocmetaError(\n \"Specify at least one field to get. Pass fields first (manni meta get title docs/a.md) or use --fields.\",\n );\n }\n\n const paths =\n fieldsArg !== undefined && (flag !== undefined || fieldsArg === STDIN)\n ? [fieldsArg, ...pathsArg]\n : pathsArg;\n return { fields, paths };\n}\n\n/**\n * `query`'s input rule is `get`'s with SQL in the fields slot: **if `--query`\n * is present, every positional is a path**; otherwise the first positional is\n * the SQL. The same three guards apply and for the same reasons — a token\n * shaped like a path in the SQL slot is a forgotten statement, `-` is stdin\n * and never SQL, and an absent statement is an error rather than a\n * plausible-looking run. Real SQL never trips `looksLikePath`: a statement\n * with a column list contains a comma, and anything else with a space cannot\n * name a file that exists.\n *\n * `--db` relaxes exactly one of those guards: exporting needs no SQL, so with\n * `sqlOptional` a path-shaped first positional is a path and an absent\n * statement means \"just write the database\".\n */\nexport function resolveQueryInputs(\n sqlArg: string | undefined,\n pathsArg: string[],\n queryOption: unknown,\n cwd: string,\n sqlOptional = false,\n): { sql: string; paths: string[] } {\n const flag = typeof queryOption === \"string\" ? queryOption : undefined;\n\n if (\n flag === undefined &&\n sqlArg !== undefined &&\n // A token with whitespace is never a path: every real statement has\n // spaces, and without this test `SELECT count(*) FROM docs` reads as a\n // *glob* — picomatch parses `(*)` as an extglob — the one SQL shape the\n // comma test inside looksLikePath does not catch.\n !/\\s/.test(sqlArg) &&\n // With SQL optional there is no \"forgot the statement\" reading to\n // protect, so a shapeless token that really exists on disk is a path\n // even when other paths follow — hence `alone` is forced on.\n looksLikePath(sqlArg, cwd, sqlOptional || pathsArg.length === 0)\n ) {\n if (sqlOptional) return { sql: \"\", paths: [sqlArg, ...pathsArg] };\n throw new DocmetaError(\n `\"${sqlArg}\" looks like a path, not SQL. Pass the SQL first (manni meta query \"SELECT _path FROM docs\" ${sqlArg}) or use --query.`,\n );\n }\n\n const source = flag ?? (sqlArg === STDIN ? undefined : sqlArg);\n const sql = source?.trim() ?? \"\";\n if (sql === \"\" && !sqlOptional) {\n throw new DocmetaError(\n 'Specify SQL to run. Pass it first (manni meta query \"SELECT _path FROM docs\" docs/) or use --query.',\n );\n }\n\n const paths =\n sqlArg !== undefined && (flag !== undefined || sqlArg === STDIN)\n ? [sqlArg, ...pathsArg]\n : pathsArg;\n return { sql, paths };\n}\n\n/**\n * `--param` values into `QueryOptions.params` (proposal 0029).\n *\n * `name=value` binds the value as a **string** — metadata is mostly strings,\n * and a projection column has no type affinity, so a bound number would\n * silently never equal a stored string. `name:=value` parses the value as\n * JSON for the deliberate typed bind (numbers, booleans, arrays, null) — the\n * httpie/jq convention. `:=` is checked before `=`, the split happens at the\n * first separator, and everything after it is the value verbatim, so values\n * containing `=` need no escaping.\n */\nexport function parseQueryParams(\n raw: readonly string[],\n): Record<string, unknown> {\n // Null prototype: `__proto__` passes the name grammar, so it must land as\n // an ordinary own key rather than silently mutating the prototype.\n const params: Record<string, unknown> = Object.create(null) as Record<\n string,\n unknown\n >;\n for (const item of raw) {\n const typed = item.indexOf(\":=\");\n const plain = item.indexOf(\"=\");\n const useTyped = typed !== -1 && (plain === -1 || typed < plain);\n const at = useTyped ? typed : plain;\n if (at <= 0) {\n throw new DocmetaError(\n `--param \"${item}\" is not name=value. Use name=value to bind a string, or name:=json for a typed value.`,\n );\n }\n const name = item.slice(0, at);\n // Exactly the token grammar `collectNamedParameters` recognizes (an\n // optional $/:/@ prefix tolerated, as the API's key handling does) —\n // `isParamName` is the scan's own predicate, so the two cannot drift.\n // Anything else — a space, a leading digit, an empty name — could never\n // be referenced from the SQL, so the engine would ignore the bind and\n // the unbound-reference guard would never fire: the false-green path\n // this flag's design closes would reopen through a typo.\n const bare = /^[$:@]/.test(name) ? name.slice(1) : name;\n if (!isParamName(bare)) {\n throw new DocmetaError(\n `--param name \"${name}\" cannot be bound: a SQL named parameter is letters, digits, and underscores, starting with a letter or underscore.`,\n );\n }\n const value = item.slice(at + (useTyped ? 2 : 1));\n if (!useTyped) {\n params[name] = value;\n continue;\n }\n try {\n params[name] = JSON.parse(value) as unknown;\n } catch {\n throw new DocmetaError(\n `--param ${name}:=${value} is not valid JSON. Quote a string — --param '${name}:=\"${value}\"' — or drop the colon (--param ${name}=${value}) to bind it as a string.`,\n );\n }\n }\n return params;\n}\n\n/**\n * Render a `query --check` run through a findings format (proposal 0026).\n *\n * The row→finding mapping is the same module `validate`'s named checks use;\n * here the check has no configured name, so its findings carry `check:query`.\n * The `RunSummary` `render()` takes is synthesized from the mapped results —\n * every file present has findings, so passed is zero by construction — and\n * JUnit ships under its own classname rather than validate's.\n *\n * Exit semantics stay `--check`'s own: rows mean findings mean exit 1.\n */\nfunction renderQueryFindings(run: QueryRun, format: QueryFindingsFormat): void {\n if (run.changes) {\n throw new DocmetaError(\n `--format ${format} renders result rows with a \\`path\\` column; this statement produced pending changes, not rows. Use pretty or json for the change preview.`,\n );\n }\n const results: ValidationResult[] = [...rowsToFindings(\n \"query\",\n run.columns,\n run.rows,\n )].map(([file, errors]) => ({\n file,\n format: \"query\",\n ok: false,\n schemas: [],\n errors,\n }));\n const summary: RunSummary = {\n files: results.length,\n passed: 0,\n failed: results.length,\n errors: results.reduce((n, r) => n + r.errors.length, 0),\n };\n const text = render(format, results, summary, {\n frame: run.frame,\n classname: \"manni.query\",\n onNotice: notice,\n });\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) {\n process.stdout.write(`${text}\\n`);\n }\n process.exitCode = run.rows.length > 0 ? 1 : 0;\n}\n\nconst COMMAND_NAMES = [\"validate\", \"get\", \"query\", \"fill\", \"schemas\"];\n\n/** Levenshtein distance. Only used to offer a \"did you mean\" hint. */\nfunction editDistance(a: string, b: string): number {\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n row.push(\n Math.min(\n (row[j - 1] ?? 0) + 1,\n (prev[j] ?? 0) + 1,\n (prev[j - 1] ?? 0) + cost,\n ),\n );\n }\n prev = row;\n }\n return prev[b.length] ?? 0;\n}\n\n/**\n * `validate` is the default command, so an unrecognized first token is parsed as\n * a *path* rather than rejected. Since a named path that does not exist is now\n * an error, `docmeta valdiate docs/` already fails with the right exit code —\n * but it fails as `File not found: \"valdiate\"`, which does not say what went\n * wrong. Upgrade the message when the token is plainly a misspelled command.\n *\n * The guard is deliberately narrow: anything holding a separator or a dot, any\n * glob, and — crucially — anything that actually exists on disk is a path, not a\n * typo. That last check is what makes a false positive impossible.\n */\nfunction suggestCommand(token: string | undefined, cwd: string): void {\n if (token === undefined || token === \"-\") return;\n if (/[\\\\/.]/.test(token)) return;\n if (picomatch.scan(token).isGlob) return;\n if (existsSync(resolvePath(cwd, token))) return;\n\n const near = COMMAND_NAMES.map(\n (name) => [name, editDistance(token.toLowerCase(), name)] as const,\n )\n .filter(([, d]) => d > 0 && d <= 2)\n .sort((x, y) => x[1] - y[1]);\n\n const best = near[0];\n if (!best) return;\n throw new DocmetaError(\n `Unknown command \"${token}\". Did you mean \"${best[0]}\"?`,\n );\n}\n\n/**\n * Range-check a numeric flag. `parseFloat(\"abc\")` is NaN and every comparison\n * against NaN is false, so the finite check has to be explicit or garbage\n * passes silently.\n */\nfunction numeric(\n name: string,\n value: number | undefined,\n min: number,\n max: number,\n): void {\n if (value === undefined) return;\n if (!Number.isFinite(value) || value < min || value > max) {\n throw new DocmetaError(\n `${name} must be a number between ${min} and ${max}, got ${value}.`,\n );\n }\n}\n\n/**\n * Commander hands an `.action()` callback an untyped bag of option values, so\n * each subcommand declares the shape it actually reads.\n *\n * The three-state flags are the reason this is worth writing down rather than\n * coercing at each use site. `-c`/`--no-config`, `--baseline`/`--no-baseline`,\n * `--no-gitignore` and `--no-cache` are only correct while *absent*, *a value*\n * and *an explicit `false`* stay distinguishable — absence leaves config in\n * charge, `false` overrides it. A union that names all three states is the one\n * place a reader finds that out; `String(options.format)` never said anything.\n */\n\n/** The flags the parity rule keeps identical across every input-taking command. */\ninterface InputCliOptions {\n /** `--ext <list>`; the command splits it. */\n ext?: string;\n /** `--exclude <glob>`, repeatable — commander's default value is `[]`. */\n exclude: string[];\n /** `--as <format>`: force an extractor. */\n as?: string;\n /** `-f, --format <format>`. Always a string: every declaration has a default. */\n format: string;\n /**\n * `--collection <name>`, repeatable — commander's default value is `[]`, and\n * that empty array travels to the core unchanged. `selectCollections` reads\n * it as \"every declared collection\", the same as absence, so there is no\n * `undefined` dance here and must not be one: `[]` meaning \"no collections\"\n * would make a plain run validate nothing and exit 0.\n */\n collection: string[];\n /**\n * `-c, --config <path>` and `--no-config` share one commander attribute:\n * `undefined` with neither flag, the path with `-c`, `false` with\n * `--no-config`. Split by `configOption`.\n */\n config?: string | boolean;\n}\n\n/** The rest of what `validate`, `get`, and `fill` share. */\ninterface RunCliOptions extends InputCliOptions {\n quiet?: boolean;\n allowEmpty?: boolean;\n /**\n * `--no-gitignore`. Commander supplies `true` when the flag is absent, so\n * this is `boolean` and never `undefined` — which is exactly why\n * `explicitFalse` exists to turn that default back into \"no opinion\".\n */\n gitignore: boolean;\n offline?: boolean;\n}\n\ninterface ValidateCliOptions extends RunCliOptions {\n /** `-s, --schema <ref>`, repeatable — commander's default value is `[]`. */\n schema: string[];\n /**\n * `--baseline [path]` / `--no-baseline`, the same three-state split as\n * `config`: absent leaves the config in charge, a string names a file, `true`\n * is a bare `--baseline` (the default path), `false` is `--no-baseline`.\n */\n baseline?: string | boolean;\n /** `--write-baseline [path]`; `true` for the bare flag. See `baseline`. */\n writeBaseline?: string | boolean;\n /**\n * `--no-checks`. Commander supplies `true` when the flag is absent — its\n * default, not a choice — so only the explicit `false` travels to the core,\n * the same shape as `gitignore`.\n */\n checks: boolean;\n /**\n * `--no-derive`. The same shape as `checks`: commander's `true` default is\n * not a choice, so only the explicit `false` travels to the core.\n */\n derive: boolean;\n /**\n * `--no-cache`. Commander's `true` default travels straight through: the\n * review cache answers the comparison unless the user said otherwise.\n */\n cache: boolean;\n}\n\ninterface GetCliOptions extends RunCliOptions {\n /** `--fields <list>`; when present, every positional is a path. */\n fields?: string;\n /**\n * `--no-derived` / `--derived`. Both spellings are registered, which is\n * why this is `boolean | undefined` rather than commander's usual `true`\n * default for a `--no-` flag: registering the positive form alongside it\n * removes that default, so the key is absent when neither was given.\n * Only the explicit `false` means anything — derivation is on otherwise,\n * and `--derived` is the no-op kept for scripts written before 0043.\n */\n derived?: boolean;\n /**\n * `--no-cache`. Commander supplies `true` when the flag is absent, so\n * this travels straight through: the review cache answers unless the\n * user said otherwise.\n */\n cache: boolean;\n}\n\n/**\n * Not `RunCliOptions`: `query` declares no `-q/--quiet`. `get` uses it to hide\n * files and `validate` to hide passes; a query result has no analogous noise,\n * and a flag that means nothing is what 0016 says not to declare.\n */\ninterface QueryCliOptions extends InputCliOptions {\n /** `--query <sql>`; when present, every positional is a path. */\n query?: string;\n /** `-s, --schema <ref>`, repeatable — commander's default value is `[]`. */\n schema: string[];\n /** `--check`: any row returned is a finding, so exit 1. */\n check?: boolean;\n /** `--param <name=value>`, repeatable — commander's default value is `[]`. */\n param: string[];\n /** `--db <path>`: also write the built database; SQL becomes optional. */\n db?: string;\n /** `--dry-run`: preview a mutating statement's diff; default applies. */\n dryRun?: boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`; commander's `true` default, see `explicitFalse`. */\n gitignore: boolean;\n offline?: boolean;\n /**\n * `--no-cache`. Commander's `true` default, like `gitignore`: the review\n * cache answers a `derived` build unless the user said otherwise.\n */\n cache: boolean;\n}\n\ninterface FillCliOptions extends RunCliOptions {\n /** `-s, --schema <ref>`, repeatable — commander's default value is `[]`. */\n schema: string[];\n fields?: string;\n /** Parsed by `parseFloat`, so possibly NaN — `numeric` is the range check. */\n confidence?: number;\n dryRun?: boolean;\n provider?: string;\n model?: string;\n /**\n * `--no-cache`. Commander supplies `true` when the flag is absent; unlike\n * `gitignore` that default is passed straight through, because the core's\n * `cache` has no config counterpart for it to override.\n */\n cache: boolean;\n local?: boolean;\n maxTurns?: number;\n chunkChars?: number;\n concurrency?: number;\n}\n\n/**\n * Not `RunCliOptions`: `derive` declares no `-q/--quiet` and no `--offline`.\n * It loads no schema, so there is nothing to fetch, and its report already\n * says `current` in one line per untouched file.\n */\ninterface DeriveCliOptions extends InputCliOptions {\n fields?: string;\n sources?: string;\n dryRun?: boolean;\n /** `--check`: implies `--dry-run`; a stale or unset field is a finding. */\n check?: boolean;\n /** `--no-cache`; commander's `true` default is passed through, as `fill` does. */\n cache: boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`; commander's `true` default, see `explicitFalse`. */\n gitignore: boolean;\n /**\n * `--generated-by <name>` (proposal 0046). No commander default: the core\n * reads `MANNI_GENERATED_BY` when it is absent, so help and the CLI\n * reference stay the same whatever the environment holds.\n */\n generatedBy?: string;\n}\n\n/**\n * Not `RunCliOptions`: `relocate` declares no `-q/--quiet` and no `--offline`.\n * It reads every page it moves, so there is nothing quiet to hide, and it\n * takes `-s` for the marks alone.\n */\ninterface RelocateCliOptions extends InputCliOptions {\n /** `--fields <list>`; the command splits it. */\n fields?: string;\n /** `-s, --schema <ref>`, repeatable — commander's default value is `[]`. */\n schema: string[];\n dryRun?: boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`; commander's `true` default, see `explicitFalse`. */\n gitignore: boolean;\n}\n\ninterface SchemasCliOptions {\n format: string;\n}\n\ninterface InferCliOptions extends InputCliOptions {\n out?: string;\n /** `--min-coverage <pct>`; commander's default value is `0`. */\n minCoverage: number;\n allowEmpty?: boolean;\n /** `--no-gitignore`; commander's `true` default, see `explicitFalse`. */\n gitignore: boolean;\n /** `--offline`; a no-op here by construction, see `InferOptions.offline`. */\n offline?: boolean;\n}\n\ninterface VendorCliOptions {\n /** `--dir <path>`; commander's default value is `DEFAULT_VENDOR_DIR`. */\n dir: string;\n /** `-c, --config <path>`. `vendor` declares no `--no-config`, so no `false`. */\n config?: string;\n}\n\n/**\n * The metadata tool's program. Named `meta` because that is where it is\n * mounted (`manni meta …`); the `docmeta` bin renames it before running it.\n */\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"meta\")\n .description(\n \"Validate the presence and format of document metadata against JSON Schema.\",\n )\n .version(pkg.version, \"-V, --version\")\n .option(\"--no-color\", \"disable colored output\")\n // A pointer, not the whole help screen. Commander appends this after every\n // usage error, and ~40 lines of options per typo is noise in a CI log — the\n // message that precedes it already names the offending flag.\n .showHelpAfterError(\"(add --help for usage)\")\n // MUST come before the `.command()` calls below. `copyInheritedSettings`\n // copies `_exitCallback` **by value** at subcommand-creation time, so an\n // `exitOverride()` installed afterwards (including\n // `buildProgram().exitOverride()` from main) leaves every subcommand still\n // calling `process.exit(1)` while the program-level case looks fixed.\n .exitOverride();\n\n program\n .command(\"validate\", { isDefault: true })\n .description(\"Validate metadata in the given files/dirs/globs\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to validate (use - for stdin)\",\n )\n .option(\n \"-s, --schema <ref>\",\n \"schema to validate against; repeatable; overrides $schema/config\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"-f, --format <format>\",\n `output: ${REPORT_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"-q, --quiet\", \"in pretty output, hide passing files\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"check files .gitignore covers\")\n .option(\n \"--offline\",\n \"never fetch a remote schema; resolve URL refs from the schema cache\",\n )\n // Neither flag carries `.preset()`, and neither carries a `defaultValue`.\n //\n // No `defaultValue`, because that would make the baseline active on runs\n // where the flag was never typed — semantically wrong, and it would oblige\n // the docs to carry a matching Default cell.\n //\n // No `.preset()` either, which is subtler. A preset hands the core the\n // default path as a *string*, making a bare `--baseline` indistinguishable\n // from an explicitly typed `--baseline .docmeta-baseline.json`. A typed path\n // is rightly relative to where the user is standing; an omitted one has to\n // mean \"the file this project's baseline lives in\" — `baseline:` from config\n // when there is one, resolved against the config's directory. Collapsing the\n // two made `--baseline` from a subdirectory look for the file beside the\n // user instead of beside the config, so the ratchet broke the moment anyone\n // ran from `docs/`, and a bare `--write-baseline` in a repo with a custom\n // `baseline:` recorded into a second file nothing reads.\n //\n // Commander hands the core `true` for an omitted value, which is exactly the\n // signal needed to tell the two cases apart.\n .addOption(\n new Option(\n \"--baseline [path]\",\n \"compare against a baseline; fail only on new findings\",\n ),\n )\n .addOption(\n new Option(\n \"--write-baseline [path]\",\n \"record current findings as the baseline, then exit 0 (stdin findings are not recorded and still fail)\",\n ),\n )\n .option(\"--no-baseline\", \"ignore a baseline configured by `baseline:`\")\n .option(\n \"--no-checks\",\n \"skip the corpus checks configured by `checks:` for this run\",\n )\n .option(\"--no-cache\", \"bypass the GitHub or GitLab review cache\")\n .option(\n \"--no-derive\",\n \"skip the derived-value comparison configured by derive:\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta validate docs/ # walk a directory\",\n ' manni meta validate \"**/*.md\" -f github # CI annotations',\n ' manni meta validate \"**/*.md\" -f sarif > o.sarif # code scanning',\n \" manni meta validate page.md -s google:okf:0.1 -s ./my.schema.json\",\n \" cat page.md | manni meta validate - --as markdown\",\n \" manni meta validate --write-baseline # record today's backlog\",\n \" manni meta validate --baseline # fail only on new findings\",\n ].join(\"\\n\"),\n )\n .action(\n async (paths: string[], options: ValidateCliOptions, command: Command) => {\n try {\n // `validate` is the default command, so a misspelled subcommand lands\n // here as a path. Upgrade the message before it becomes \"not found\".\n suggestCommand(paths[0], process.cwd());\n const format = options.format;\n if (!isReportFormat(format)) {\n throw new DocmetaError(\n `Unknown --format \"${format}\". Use ${REPORT_FORMAT_LIST}.`,\n );\n }\n const exts: string[] | undefined = options.ext\n ? splitList(options.ext)\n : undefined;\n const stdinContent = paths.includes(\"-\")\n ? await readStdin()\n : undefined;\n\n const { results, summary, frame } = await runValidate({\n inputs: paths,\n cliSchemas: options.schema,\n exts,\n exclude: options.exclude,\n as: options.as,\n // Straight through: commander gives `[]` when the flag was never\n // typed, and the core reads an empty list as every declared\n // collection. Refusing paths beside it, and refusing it with no\n // config, is `resolveRunConfig`'s job, before the walk.\n collections: options.collection,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(\n !isMachineFormat(format),\n process.cwd(),\n ),\n stdinContent,\n // `undefined` rather than `false` when the flag is absent, so config\n // `allowEmpty:` still wins (the cores do `opts ?? config`).\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n // `undefined` rather than `false` when absent, so config `offline:`\n // still decides.\n offline: options.offline ? true : undefined,\n onNotice: notice,\n // `--baseline` and `--no-baseline` share one commander attribute, the\n // same three-state `undefined | string | false` split as `-c` /\n // `--no-config`: absent leaves the config in charge, a string names a\n // file, `false` suppresses a configured one for this run.\n baseline: options.baseline,\n writeBaseline: options.writeBaseline,\n // Like `gitignore`: only the explicit `--no-checks` travels, so\n // absence stays \"run them when the corpus rule allows\".\n checks: options.checks ? undefined : false,\n // And `--no-derive`, for the managed-field comparison.\n derive: options.derive ? undefined : false,\n // And `--no-cache`, so a wrong cached review answer can be re-asked.\n cache: options.cache,\n });\n\n const color = resolveColor(command.parent ?? command);\n const text = render(format, results, summary, {\n color,\n quiet: Boolean(options.quiet),\n // Non-presentational: SARIF needs to know where the run stood before\n // it can name a file the way the repository does.\n frame,\n onNotice: notice,\n });\n // Only `github` may say nothing on a clean run. Every other format owes\n // its envelope even when it is empty — see `OMITTED_WHEN_CLEAN`.\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) {\n process.stdout.write(`${text}\\n`);\n }\n process.exitCode = summary.failed > 0 ? 1 : 0;\n // P2 (proposal 0047): on a terminal, after the report, offer to move\n // what the location findings named. On stderr, so the report stays\n // machine-readable, and the exit code stays the report's. Never with\n // stdin among the inputs: it is not a terminal to ask on.\n await offerRelocation({\n results,\n inputs: paths,\n cliSchemas: options.schema,\n as: options.as,\n collections: options.collection,\n ...configOption(options.config),\n respectGitignore: explicitFalse(options.gitignore),\n offline: options.offline ? true : undefined,\n confirm: paths.includes(STDIN) ? undefined : terminalConfirm(),\n output: process.stderr,\n color: shouldColor({\n noColor: (command.parent ?? command).opts().color === false,\n isTTY: process.stderr.isTTY,\n }),\n });\n } catch (err) {\n fail(err);\n }\n },\n );\n\n program\n .command(\"get\")\n .description(\"Print metadata field values from the given files/dirs/globs\")\n // Optional, and the flag below is the unambiguous spelling. A required\n // positional ate the user's *path* when the field list was forgotten, and\n // reported the paths — which were never the problem — as missing.\n .argument(\n \"[fields]\",\n \"comma-separated metadata fields to print, unless --fields is given\",\n )\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to read (use - for stdin)\",\n )\n .option(\n \"--fields <list>\",\n \"comma-separated metadata fields to print; every positional is then a path\",\n )\n .option(\n \"--no-derived\",\n \"print only what the document stores, consulting no source\",\n )\n // Registered beside `--no-derived` on purpose. Commander gives a lone\n // `--no-x` the default `true`; declaring `--x` as well removes that\n // default, so \"neither flag\" is `undefined` and stays distinguishable —\n // and the spelling that used to turn derivation on still parses.\n .option(\"--derived\", \"accepted and inert: derivation is already on\")\n .option(\"--no-cache\", \"bypass the GitHub or GitLab review cache\")\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"-f, --format <format>\",\n `output: ${COMMON_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\n \"-q, --quiet\",\n \"in pretty output, hide files where every requested field is unset\",\n )\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"read files .gitignore covers\")\n .option(\n \"--offline\",\n \"accepted and ignored: get loads no schema, so there is nothing to fetch\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta get title,type docs/intro.md\",\n \" manni meta get --fields title,type docs/intro.md\",\n \" manni meta get author.name,/author/email docs/intro.md\",\n ' manni meta get type \"**/*.md\" -f json',\n \" manni meta get owner docs/intro.md --no-derived\",\n \" cat page.md | manni meta get title - --as markdown\",\n ].join(\"\\n\"),\n )\n .action(\n async (\n fieldsArg: string | undefined,\n pathsArg: string[],\n options: GetCliOptions,\n command: Command,\n ) => {\n try {\n const format = assertCommonFormat(options.format);\n const { fields, paths } = resolveGetInputs(\n fieldsArg,\n pathsArg,\n options.fields,\n process.cwd(),\n );\n const exts: string[] | undefined = options.ext\n ? splitList(options.ext)\n : undefined;\n const stdinContent = paths.includes(\"-\")\n ? await readStdin()\n : undefined;\n\n const results = await runGet({\n fields,\n derived: options.derived !== false,\n cache: options.cache,\n inputs: paths,\n as: options.as,\n exclude: options.exclude,\n exts,\n collections: options.collection,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\", process.cwd()),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n offline: options.offline ? true : undefined,\n onNotice: notice,\n });\n switch (format) {\n case \"json\":\n // `--quiet` is a pretty-output affordance; a filtered array would\n // be indistinguishable from an empty run to whatever parses this.\n process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`);\n break;\n case \"pretty\": {\n const text = renderGet(results, fields, {\n color: resolveColor(command.parent ?? command),\n quiet: Boolean(options.quiet),\n });\n if (text.length > 0) process.stdout.write(`${text}\\n`);\n break;\n }\n default: {\n const unreachable: never = format;\n throw new DocmetaError(\n `Unknown --format ${JSON.stringify(unreachable)}. Use ${COMMON_FORMAT_LIST}.`,\n );\n }\n }\n // A document that would not parse is a finding, not an operational\n // failure: the run completed and reported on every file it was given.\n // Set after the report is written, so the values that did resolve are\n // on stdout either way.\n process.exitCode = results.some((r) => r.error !== undefined) ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n },\n );\n\n program\n .command(\"query\")\n .description(\"Run SQL over the metadata of the given files/dirs/globs\")\n // Optional for the same reason `get`'s `[fields]` is: a required\n // positional would eat the user's *path* when the SQL was forgotten.\n .argument(\"[sql]\", \"SQL to run against the `docs` table, unless --query is given\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to load (use - for stdin)\",\n )\n .option(\n \"--query <sql>\",\n \"SQL to run against the `docs` table; every positional is then a path\",\n )\n .option(\n \"-s, --schema <ref>\",\n \"schema set a DDL statement evolves; repeatable; replaces the per-file resolution for the DDL planner only\",\n collect,\n [],\n )\n .option(\n \"--check\",\n \"treat returned rows as findings: exit 1 if the query returns any\",\n )\n .option(\n \"--param <name=value>\",\n \"bind a named SQL parameter ($name/:name/@name) as a string; name:=value parses the value as JSON; repeatable\",\n collect,\n [],\n )\n // The findings formats (github, sarif, junit) are declared in the shared\n // `-f, --format` option below; they are legal only with --check and a\n // `path` result column — see the action's gates.\n .option(\n \"--db <path>\",\n \"also write the built database to this file; SQL is then optional\",\n )\n .option(\n \"--dry-run\",\n \"preview a mutating statement's diff without applying it (--check implies this)\",\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"-f, --format <format>\",\n `output: ${QUERY_FORMATS.join(\" | \")} (github, sarif, junit need --check)`,\n \"pretty\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"load files .gitignore covers\")\n .option(\"--no-cache\", \"bypass the GitHub or GitLab review cache\")\n .option(\n \"--offline\",\n \"accepted and ignored: query resolves schemas from disk and built-ins, never the network\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"One row per file in a table named `docs`: your top-level metadata keys\",\n \"as columns, plus _path, _format, _present, and _data (all metadata as\",\n \"JSON, for json_each/->> reach into nested values).\",\n \"\",\n \"Examples:\",\n ' manni meta query \"SELECT _path, title FROM docs WHERE draft = 1\" docs/',\n ' manni meta query \"SELECT t.value tag, count(*) n FROM docs, json_each(docs.tags) t GROUP BY tag\" docs/',\n ' manni meta query --check \"SELECT slug, count(*) n FROM docs GROUP BY slug HAVING n > 1\" docs/',\n ' manni meta query -f csv \"SELECT _path, title, last_reviewed FROM docs\" docs/ > stale.csv',\n \" manni meta query --param author=\\\"O'Brien\\\" \\\"SELECT _path FROM docs WHERE author = \\\\$author\\\" docs/\",\n ' cat page.md | manni meta query \"SELECT title FROM docs\" - --as markdown',\n \" manni meta query --db docs.db docs/ # export only; open with any SQLite UI\",\n ].join(\"\\n\"),\n )\n .action(\n async (\n sqlArg: string | undefined,\n pathsArg: string[],\n options: QueryCliOptions,\n command: Command,\n ) => {\n try {\n const format = options.format;\n if (!isQueryFormat(format)) {\n throw new DocmetaError(\n `Unknown --format \"${format}\". Use ${QUERY_FORMAT_LIST}.`,\n );\n }\n // The findings formats render findings, and only `--check` produces\n // them. Gated before the run so the refusal costs nothing.\n if (isQueryFindingsFormat(format) && !options.check) {\n throw new DocmetaError(\n `--format ${format} renders findings, which only --check produces. Add --check, or use pretty, json, or csv.`,\n );\n }\n const { sql, paths } = resolveQueryInputs(\n sqlArg,\n pathsArg,\n options.query,\n process.cwd(),\n typeof options.db === \"string\",\n );\n // A `--db`-only export has no result rows to shape into CSV; its\n // summary stays with pretty/json. Refused before the run, like the\n // findings gate above.\n if (format === \"csv\" && sql === \"\") {\n throw new DocmetaError(\n \"--format csv renders result rows, and a --db export without SQL produces none. Use pretty or json for the export summary.\",\n );\n }\n // The findings formats have the same no-rows problem on an\n // export-only run — and silently printing the export summary would\n // be a --check gate that checked nothing.\n if (isQueryFindingsFormat(format) && sql === \"\") {\n throw new DocmetaError(\n `--format ${format} renders findings, which need a statement to produce rows — a --db export without SQL has none. Pass the SQL, or drop --check -f ${format}.`,\n );\n }\n // Ditto --param: with no statement there is nothing to bind into,\n // and silently ignoring the flag would hide a misspelled command.\n if (options.param.length > 0 && sql === \"\") {\n throw new DocmetaError(\n \"--param needs a statement to bind into; a --db export without SQL references no parameters. Pass the SQL, or drop --param.\",\n );\n }\n // And -s (0030): it names the schema set DDL evolves, and with no\n // SQL nothing can evolve it — the same flag-means-nothing seam,\n // refused at the same gate. Worded without naming --db: the gate\n // guards every empty-SQL arrival, not just the export spelling.\n if (options.schema.length > 0 && sql === \"\") {\n throw new DocmetaError(\n \"-s names the schema set DDL evolves; without SQL there is no statement to evolve it. Pass the SQL, or drop -s.\",\n );\n }\n const params = parseQueryParams(options.param);\n const exts: string[] | undefined = options.ext\n ? splitList(options.ext)\n : undefined;\n const stdinContent = paths.includes(STDIN)\n ? await readStdin()\n : undefined;\n\n // `--check` implies a dry run: a check judges and exits, it never\n // mutates — which keeps every CI drift gate a read-only step. So\n // does `-f csv`: csv refuses a changes-producing statement below,\n // and that refusal must land before anything is applied, not after.\n const dryRun =\n Boolean(options.dryRun) || Boolean(options.check) ||\n format === \"csv\";\n const run = await runQuery({\n sql,\n db: options.db,\n dryRun,\n cache: options.cache,\n ...(Object.keys(params).length > 0 ? { params } : {}),\n ...(options.schema.length > 0 ? { schemas: options.schema } : {}),\n inputs: paths,\n as: options.as,\n exclude: options.exclude,\n exts,\n collections: options.collection,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\", process.cwd()),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n offline: options.offline ? true : undefined,\n onNotice: notice,\n // A write to a column marked x-manni-encrypt with no key asks\n // for one on a terminal, and refuses off one (proposal 0045).\n // The same Confirm asks P1 (proposal 0047).\n confirm: terminalConfirm(),\n // An accepted P1 offer prints relocate's report: on stdout\n // beside a pretty report, on stderr when stdout must parse.\n onRelocated: (result) => {\n const text = renderRelocate(result, \"pretty\", {\n color: format === \"pretty\" && resolveColor(command.parent ?? command),\n });\n (format === \"pretty\" ? process.stdout : process.stderr).write(`${text}\\n`);\n },\n });\n // With SQL, the rows own stdout and the export is a diagnostic;\n // export-only, the export summary IS the report.\n if (run.db && sql === \"\") {\n process.stdout.write(\n format === \"json\"\n ? `${JSON.stringify(run.db, null, 2)}\\n`\n : `Wrote ${run.db.path} (${run.db.files} files, ${run.db.columns} columns)\\n`,\n );\n process.exitCode = 0;\n return;\n }\n if (run.db) {\n notice(`wrote ${run.db.path} (${run.db.files} files)`);\n }\n // Narrowing guard: past this return, `format` is\n // `pretty | json | csv`, which is what keeps the switch below\n // compile-time exhaustive.\n if (isQueryFindingsFormat(format)) {\n renderQueryFindings(run, format);\n return;\n }\n switch (format) {\n case \"csv\":\n // CSV describes result rows. Changes are heterogeneous per-file\n // diffs (eight kinds since 0024), not a table — the refusal\n // lives here in the dispatch, where the format is known and the\n // reporter stays presentation-only (proposal 0029). The run was\n // forced dry above, so the refusal is truthful: nothing landed.\n if (run.changes) {\n throw new DocmetaError(\n \"--format csv renders result rows; this statement produced changes, which have no tabular shape — nothing was applied. Use pretty or json to preview them, and run without -f csv to apply.\",\n );\n }\n process.stdout.write(`${renderQueryCsv(run)}\\n`);\n break;\n case \"json\":\n // The bare array, mirroring `get`'s bare result array: changes\n // for a metadata edit, rows for a read. The `--check` verdict\n // travels in the exit code, not the envelope.\n process.stdout.write(\n `${JSON.stringify(run.changes ?? run.rows, null, 2)}\\n`,\n );\n break;\n case \"pretty\": {\n const text = renderQuery(run, {\n color: resolveColor(command.parent ?? command),\n check: Boolean(options.check),\n dryRun,\n });\n if (text.length > 0) process.stdout.write(`${text}\\n`);\n break;\n }\n default: {\n // Exhaustive: the findings formats returned above and narrowed\n // the union, so adding a value to QUERY_FORMATS without a case\n // here (or a findings-format branch) is a compile error. The\n // throw is the runtime half, as in `render`.\n const unreachable: never = format;\n throw new DocmetaError(\n `Unknown --format ${JSON.stringify(unreachable)}. Use ${QUERY_FORMAT_LIST}.`,\n );\n }\n }\n // Rows from a `--check` run are findings, and so are its pending\n // changes — the drift gate (`--check` never applies). An applied\n // statement is the work done, so it succeeds or fails outright.\n const findings = run.changes ? run.changes.length : run.rows.length;\n process.exitCode = options.check && findings > 0 ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n },\n );\n\n program\n .command(\"fill\")\n .description(\n \"Infer missing or invalid metadata and write values above the confidence threshold\",\n )\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to fill (use - for stdin)\",\n )\n .option(\n \"-s, --schema <ref>\",\n \"schema to fill against; repeatable; overrides $schema/config\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\"--fields <list>\", \"comma-separated fields to fill\")\n .option(\"--confidence <n>\", \"minimum confidence to write (0-1)\", parseFloat)\n .option(\"--dry-run\", \"report proposals without writing them\")\n .option(\n \"--provider <name>\",\n \"provider: auto (default), anthropic, openai, claude-cli, llama-cpp\",\n )\n .option(\n \"--model <model>\",\n \"model override; needs a named provider, from here or config\",\n )\n .option(\"--no-cache\", \"bypass the proposal cache\")\n .option(\"--local\", LOCAL_FLAG_HELP)\n .option(\"--max-turns <n>\", \"stop after this many inference calls\", parseFloat)\n .option(\n \"--chunk-chars <n>\",\n \"characters of document per call (default 12000)\",\n parseFloat,\n )\n // parseFloat, not parseInt: parseInt(\"3.5\") silently yields 3, which would\n // defeat runFill's integer check and hide the mistake from the user.\n .option(\"--concurrency <n>\", \"files inferred in parallel\", parseFloat)\n .option(\n \"-f, --format <format>\",\n `output: ${FILL_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\n \"-q, --quiet\",\n \"in pretty output, hide files with nothing written and nothing required left undone\",\n )\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"fill files .gitignore covers\")\n .option(\n \"--offline\",\n \"never fetch a remote schema; resolve URL refs from the schema cache\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta fill docs/ --dry-run # preview proposals\",\n \" manni meta fill docs/ --confidence 0.9 # only near-certain values\",\n \" manni meta fill page.md --fields description\",\n \" manni meta fill docs/ -f github # CI annotations\",\n \" cat page.md | manni meta fill - --as markdown # filled doc to stdout\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: FillCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isFillFormat(format)) {\n throw new DocmetaError(\n `Unknown --format \"${format}\". Use ${FILL_FORMAT_LIST}.`,\n );\n }\n // parseFloat(\"abc\") is NaN, and every comparison against NaN is false,\n // so a bare range check would silently accept garbage.\n numeric(\"--confidence\", options.confidence, 0, 1);\n numeric(\"--max-turns\", options.maxTurns, 1, Number.MAX_SAFE_INTEGER);\n numeric(\n \"--chunk-chars\",\n options.chunkChars,\n 1,\n Number.MAX_SAFE_INTEGER,\n );\n numeric(\"--concurrency\", options.concurrency, 1, 64);\n\n const exts: string[] | undefined = options.ext\n ? splitList(options.ext)\n : undefined;\n const usingStdin = paths.includes(STDIN);\n // With `-` the filled document owns stdout and the report is a\n // diagnostic on stderr — where GitHub never reads `::error`. The\n // annotations would be produced, and nothing would ever render them.\n // Refuse the combination rather than degrade to a silent no-op, which\n // is the exact false green this parity work exists to remove.\n if (usingStdin && format === \"github\") {\n throw new DocmetaError(\n 'Cannot use --format github with stdin (\"-\"): the filled document owns stdout, so the annotations would go to stderr, where GitHub ignores them. Pass file paths instead.',\n );\n }\n const stdinContent = usingStdin ? await readStdin() : undefined;\n\n const run = await runFill({\n inputs: paths,\n cliSchemas: options.schema,\n exts,\n exclude: options.exclude,\n as: options.as,\n collections: options.collection,\n ...configOption(options.config),\n // With `-` the filled document owns stdout, so the notice is a\n // diagnostic there just as the report is.\n onConfigLoaded: reportConfig(\n format === \"pretty\" && !usingStdin,\n process.cwd(),\n ),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n offline: options.offline ? true : undefined,\n onNotice: notice,\n fields: options.fields ? splitList(options.fields) : undefined,\n confidence: options.confidence,\n dryRun: Boolean(options.dryRun),\n provider: options.provider,\n model: options.model,\n cache: options.cache,\n local: Boolean(options.local),\n maxTurns: options.maxTurns,\n chunkChars: options.chunkChars,\n concurrency: options.concurrency,\n includeContent: usingStdin,\n // A field marked x-manni-encrypt with no key asks for one on a\n // terminal, and refuses off one (proposal 0045). Reading the page\n // from stdin leaves no terminal to ask on. The same Confirm asks\n // P1 (proposal 0047).\n confirm: usingStdin ? undefined : terminalConfirm(),\n // An accepted P1 offer prints relocate's report: on stdout beside a\n // pretty report, on stderr when stdout must parse.\n onRelocated: (result) => {\n const text = renderRelocate(result, \"pretty\", {\n color: format === \"pretty\" && resolveColor(command.parent ?? command),\n });\n (format === \"pretty\" ? process.stdout : process.stderr).write(`${text}\\n`);\n },\n });\n\n const color = resolveColor(command.parent ?? command);\n const report = renderFill(format, run, {\n color,\n quiet: Boolean(options.quiet),\n });\n if (usingStdin) {\n // The filled document owns stdout here; the report is a diagnostic.\n const filled = run.results[0]?.content;\n if (filled != null) process.stdout.write(filled);\n if (report.length > 0) process.stderr.write(`${report}\\n`);\n } else if (report.length > 0) {\n process.stdout.write(`${report}\\n`);\n }\n\n // A field the schema requires that could not be filled confidently is\n // work left undone, so CI should see it. Optional fields are not.\n process.exitCode =\n run.summary.requiredSkipped > 0 || run.summary.errors > 0 ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"derive\")\n .description(\n \"Stamp the managed stewardship fields from git history, CODEOWNERS and GitHub or GitLab reviews\",\n )\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to stamp; <path>:L1-L2 names lines for --generated-by\",\n )\n .option(\n \"--fields <list>\",\n \"comma-separated managed fields to stamp; config derive.fields otherwise, else the merge-safe fields each page's schemas claim\",\n )\n .option(\n \"--generated-by <name>\",\n \"attribute uncommitted body lines, or a <path>:L1-L2 range, to this machine in provenance; MANNI_GENERATED_BY otherwise\",\n )\n .option(\n \"--sources <list>\",\n \"comma-separated sources to consult: git, codeowners, github, gitlab, command (default all)\",\n )\n .option(\"--dry-run\", \"report what would change and write nothing\")\n .option(\n \"--check\",\n \"implies --dry-run: a stale or unset managed field is a finding, exit 1 if any\",\n )\n .option(\n \"-f, --format <format>\",\n `output: ${DERIVE_FORMATS.join(\" | \")} (github, sarif, junit need --check)`,\n \"pretty\",\n )\n .option(\"--no-cache\", \"bypass the GitHub or GitLab review cache\")\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"stamp files .gitignore covers\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta derive # stamp the managed fields over every collection\",\n \" manni meta derive --collection guides # stamp one configured collection\",\n \" manni meta derive --dry-run docs/install.md # what would change, nothing written\",\n \" manni meta derive --check -f github # CI: a stale stamp is an annotation, exit 1\",\n \" manni meta derive --fields reviewed-by,last-reviewed\",\n \" manni meta derive --sources git,codeowners # no gh on this machine\",\n \" MANNI_GENERATED_BY=claude-fable-5 manni meta derive --fields provenance\",\n \" manni meta derive docs/limits.md:12-31 --generated-by claude-fable-5\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: DeriveCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isDeriveFormat(format)) {\n throw new DocmetaError(\n `Unknown --format \"${format}\". Use ${DERIVE_FORMAT_LIST}.`,\n );\n }\n // The findings formats render findings, and only `--check` produces\n // them. Gated before the run so the refusal costs nothing — and so\n // nothing is written on a run whose report was never going to render.\n if (\n (format === \"github\" || format === \"sarif\" || format === \"junit\") &&\n !options.check\n ) {\n throw new DocmetaError(\n `${format} is a findings format, which only --check produces`,\n );\n }\n const exts: string[] | undefined = options.ext\n ? splitList(options.ext)\n : undefined;\n\n const run = await runDerive({\n inputs: paths,\n fields: options.fields ? splitList(options.fields) : undefined,\n sources: options.sources ? splitList(options.sources) : undefined,\n ...(options.generatedBy !== undefined ? { generatedBy: options.generatedBy } : {}),\n dryRun: Boolean(options.dryRun),\n check: Boolean(options.check),\n cache: options.cache,\n exts,\n exclude: options.exclude,\n as: options.as,\n collections: options.collection,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(!isMachineFormat(format), process.cwd()),\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n // A field its schema marks x-manni-encrypt (proposal 0045) with no\n // key yet: asked on a terminal, refused off one. The same Confirm\n // asks P1 (proposal 0047).\n confirm: terminalConfirm(),\n // An accepted P1 offer prints relocate's report: on stdout beside a\n // pretty report, on stderr when stdout must parse.\n onRelocated: (result) => {\n const text = renderRelocate(result, \"pretty\", {\n color: format === \"pretty\" && resolveColor(command.parent ?? command),\n });\n (format === \"pretty\" ? process.stdout : process.stderr).write(`${text}\\n`);\n },\n });\n\n const text = renderDerive(run, format, {\n color: resolveColor(command.parent ?? command),\n frame: run.frame,\n onNotice: notice,\n });\n // Only `github` may say nothing on a clean run — see `OMITTED_WHEN_CLEAN`.\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) {\n process.stdout.write(`${text}\\n`);\n }\n // A file error fails any run; a finding fails `--check`. See `deriveFailed`.\n process.exitCode = deriveFailed(run) ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"relocate\")\n .description(\n \"Move each value to where its schema's x-manni-location and the config's manifests say it belongs\",\n )\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to relocate (stdin is refused)\",\n )\n .option(\n \"--fields <list>\",\n \"comma-separated fields to move; each must be marked x-manni-location or manifest-owned\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\n \"-s, --schema <ref>\",\n \"schema to judge preferences against; repeatable; overrides $schema/config\",\n collect,\n [],\n )\n .option(\"--dry-run\", \"report what would move and be created, and write nothing\")\n .option(\n \"-f, --format <format>\",\n `output: ${RELOCATE_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file (refused: relocate writes the config)\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"relocate files .gitignore covers\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta relocate # every collection, as config declares it\",\n \" manni meta relocate --dry-run # what would move and be created\",\n \" manni meta relocate docs/install.md --fields owner\",\n \" manni meta relocate docs/ guides/intro.md # no collections yet: creates collection default\",\n \" manni meta relocate -f json --dry-run # the scripting form\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: RelocateCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isRelocateFormat(format)) {\n throw new DocmetaError(\n `relocate --format must be pretty or json; got \"${format}\".`,\n );\n }\n const result = await runRelocate({\n inputs: paths,\n fields: options.fields ? splitList(options.fields) : undefined,\n collections: options.collection,\n cliSchemas: options.schema,\n dryRun: Boolean(options.dryRun),\n exts: options.ext ? splitList(options.ext) : undefined,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\", process.cwd()),\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n });\n const text = renderRelocate(result, format, {\n color: resolveColor(command.parent ?? command),\n });\n process.stdout.write(`${text}\\n`);\n // A value left on the wrong side is work undone. See `relocateFailed`.\n process.exitCode = relocateFailed(result) ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n // `-f, --format` stays on the parent rather than moving to a `list`\n // subcommand: bare `manni meta schemas` is a *default action*, not group help,\n // and both are part of the documented surface.\n const schemas = program\n .command(\"schemas\")\n .description(\"List built-in schemas and supported input formats\")\n .option(\n \"-f, --format <format>\",\n `output: ${COMMON_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .action(async (options: SchemasCliOptions, command: Command) => {\n try {\n // A closed set, checked like every other command's --format. This used\n // to be a bare `=== \"json\" ? json : pretty`, so `schemas -f github`\n // printed a pretty listing and exited 0 — a request docmeta cannot\n // honor, answered with success in a different format. `github` is the\n // case that matters: it is a real docmeta format, just not one this\n // command produces, so nothing about the invocation looked wrong.\n const format = assertCommonFormat(options.format);\n // The registered schemas come from the config discovery finds. A\n // broken config does not stop the listing of the built-ins, which\n // never depended on it; it is named on stderr instead.\n let registered: RegisteredSchemas | undefined;\n try {\n registered = (await loadConfig(undefined, process.cwd()))?.config.registered;\n } catch (err) {\n if (!(err instanceof DocmetaError)) throw err;\n warn(`${err.message} Registered schemas are not listed.`);\n }\n const info = getSchemasInfo(registered);\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify(info, null, 2)}\\n`);\n return;\n }\n const c = palette(resolveColor(command.parent ?? command));\n const lines: string[] = [c.bold(\"Built-in schemas:\")];\n for (const b of info.builtins) {\n lines.push(` ${c.cyan(b.id)} ${c.dim(\"—\")} ${b.title}`);\n }\n if (info.registered.length > 0) {\n lines.push(\"\", c.bold(\"Registered schemas:\"));\n for (const r of info.registered) {\n lines.push(` ${c.cyan(r.id)} ${c.dim(\"—\")} ${r.file}`);\n }\n }\n lines.push(\"\", c.bold(\"Input formats:\"));\n for (const f of info.formats) {\n const tag = f.writable ? c.green(\"writable\") : c.dim(\"read-only\");\n lines.push(` ${f.name} (${f.extensions.join(\", \")}) [${tag}]`);\n }\n process.stdout.write(`${lines.join(\"\\n\")}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n\n schemas\n .command(\"infer\")\n .description(\n \"Report metadata coverage across a docset, and draft a schema from what is there\",\n )\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to scan (use - for stdin)\",\n )\n .option(\"--out <path>\", \"write the draft schema here\")\n // Default 0, and it must stay 0. A default that hid the long tail would\n // hide exactly the \"3% is one team's convention, not a standard\" signal the\n // report exists to surface.\n .option(\n \"--min-coverage <pct>\",\n \"hide keys below this coverage percentage\",\n parseFloat,\n 0,\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"-f, --format <format>\",\n `output: ${COMMON_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"scan files .gitignore covers\")\n .option(\n \"--offline\",\n \"accepted and ignored: infer loads no schema and no provider\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta schemas infer docs/ # what does this repo have?\",\n \" manni meta schemas infer docs/ --min-coverage 5 # drop the long tail\",\n \" manni meta schemas infer docs/ --out ./schemas/permissive.json\",\n \" manni meta schemas infer docs/ -f json\",\n \"\",\n \"Purely statistical and offline: no provider, no network, no model. The\",\n \"draft never marks anything `required` — coverage is your decision to\",\n \"make, not the tool's.\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: InferCliOptions, command: Command) => {\n try {\n const format = assertCommonFormat(formatFor(command, options.format));\n numeric(\"--min-coverage\", options.minCoverage, 0, 100);\n const exts: string[] | undefined = options.ext\n ? splitList(options.ext)\n : undefined;\n const stdinContent = paths.includes(STDIN)\n ? await readStdin()\n : undefined;\n\n const result = await runInferSchema({\n inputs: paths,\n exts,\n exclude: options.exclude,\n as: options.as,\n collections: options.collection,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\", process.cwd()),\n stdinContent,\n out: options.out,\n minCoverage: options.minCoverage,\n // Same shape as the other four input-taking commands: only an\n // explicit `--allow-empty` / `--no-gitignore` travels, so config\n // `allowEmpty:` and `respectGitignore:` still decide otherwise.\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n // Accepted and ignored — `infer` never fetches. `undefined` rather\n // than `false` all the same, so this stays the same shape as the\n // other four if it ever does gain a meaning.\n offline: options.offline ? true : undefined,\n onNotice: notice,\n });\n\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n return;\n }\n const text = renderInfer(result, {\n color: resolveColor(command.parent?.parent ?? command),\n });\n process.stdout.write(`${text}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n\n schemas\n .command(\"vendor\")\n .description(\n \"Download a remote schema into this repository and pin it in config\",\n )\n .argument(\"<url>\", \"http(s) URL of the schema to vendor\")\n .option(\n \"--dir <path>\",\n \"directory for the committed copy\",\n DEFAULT_VENDOR_DIR,\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni meta schemas vendor https://schemas.example.com/house/2.1.json\",\n \" manni meta schemas vendor https://schemas.example.com/house/2.1.json --dir ./contracts\",\n \"\",\n \"Commit both the downloaded file and the config change: the point of\",\n \"vendoring is that CI validates against a copy in your own history.\",\n ].join(\"\\n\"),\n )\n .action(async (url: string, options: VendorCliOptions) => {\n try {\n const result = await runVendorSchema({\n url,\n dir: options.dir,\n // `typeof === \"string\"`, not `!== undefined`. `vendor` is the one\n // config-taking command with no `--no-config`, and the parity rule in\n // CLAUDE.md points straight at adding one — at which point commander\n // starts passing `false` here. The annotation on `VendorCliOptions`\n // says that cannot happen, so it would not be caught at the point the\n // flag is declared; this test is what keeps a `false` out of a field\n // that must be a path.\n ...(typeof options.config === \"string\"\n ? { configPath: options.config }\n : {}),\n onNotice: notice,\n });\n // Three states, and the operator needs to be able to tell them apart in\n // a diff: a config was created, an existing reference was replaced (the\n // re-vendor and the bare-URL migration both land here), or an entry was\n // added beside what was already there.\n const configNote = result.configCreated\n ? \"created\"\n : result.replaced\n ? \"reference updated\"\n : \"reference added\";\n process.stdout.write(\n [\n `Vendored ${result.url}`,\n ` file ${result.file} (${result.bytes} bytes${result.unchanged ? \", unchanged\" : \"\"})`,\n ` integrity ${result.integrity}`,\n ` config ${result.config} (${configNote})`,\n \"\",\n `Commit ${result.file} and ${result.config} so CI validates against this copy.`,\n ].join(\"\\n\") + \"\\n\",\n );\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n\n// No entry point here. `src/cli.ts` mounts this program as `manni meta` and\n// `src/docmeta.ts` runs it under its old name; both go through `runProgram`\n// in src/shared/run.ts, which owns the exit-code contract.\n","/**\n * Reporter for `relocate` (proposal 0047).\n *\n * `pretty` leads with what the config gains or loses (a created collection or\n * manifest, an appended path, a `keys:` change and the pages it reaches), then\n * each page with a value that moved or stayed, then one summary line. A page\n * reached only through a `keys:` change, outside the paths the run named, is\n * counted rather than listed unless a value on it stayed. `json` is the\n * scripting form: the run's shape minus what only the pretty lines need.\n */\nimport { DocmetaError } from \"../types.js\";\nimport type { RelocateResult } from \"../core/relocation.js\";\nimport { palette } from \"../../shared/color.js\";\nimport { formatList } from \"./index.js\";\n\nexport const RELOCATE_FORMATS = [\"pretty\", \"json\"] as const;\n\nexport type RelocateReportFormat = (typeof RELOCATE_FORMATS)[number];\n\n/** `\"pretty or json\"`, for messages and help text. */\nexport const RELOCATE_FORMAT_LIST = formatList(RELOCATE_FORMATS);\n\nexport function isRelocateFormat(value: string): value is RelocateReportFormat {\n return (RELOCATE_FORMATS as readonly string[]).includes(value);\n}\n\nexport interface RelocateReportOptions {\n color?: boolean;\n}\n\nexport function renderRelocate(\n result: RelocateResult,\n format: RelocateReportFormat,\n opts: RelocateReportOptions = {},\n): string {\n switch (format) {\n case \"json\":\n return JSON.stringify(relocateJson(result), null, 2);\n case \"pretty\":\n return renderRelocatePretty(result, opts);\n default: {\n const unreachable: never = format;\n throw new DocmetaError(\n `relocate --format must be pretty or json; got ${JSON.stringify(unreachable)}.`,\n );\n }\n }\n}\n\n/** The JSON shape: what a script reads, without the pretty reporter's own fields. */\nexport function relocateJson(result: RelocateResult): unknown {\n return {\n dryRun: result.dryRun,\n config: {\n file: result.config.file,\n created: result.config.created,\n collectionsCreated: result.config.collectionsCreated,\n pathsAdded: result.config.pathsAdded,\n },\n manifests: result.manifests.map((m) => ({\n file: m.file,\n collection: m.collection,\n created: m.created,\n keysAdded: m.keysAdded,\n keysRemoved: m.keysRemoved,\n undeclared: m.undeclared,\n })),\n files: result.files.map((f) => ({\n file: f.file,\n moved: f.moved,\n stayed: f.stayed.map((s) => ({ key: s.key, reason: s.reason })),\n })),\n summary: result.summary,\n };\n}\n\nconst plural = (n: number, noun: string): string => `${n} ${noun}${n === 1 ? \"\" : \"s\"}`;\nconst list = (xs: readonly string[]): string => xs.join(\", \");\n\nexport function renderRelocatePretty(result: RelocateResult, opts: RelocateReportOptions = {}): string {\n const c = palette(opts.color ?? false);\n const dry = result.dryRun;\n const lines: string[] = [];\n\n // ---- The config ------------------------------------------------------------\n if (result.config.created && result.config.file !== null) {\n lines.push(dry ? `Would create ${result.config.file}.` : `Created ${result.config.file}.`);\n }\n const pathsOf = (collection: string): string[] =>\n result.config.pathsAdded.filter((p) => p.collection === collection).map((p) => p.path);\n const said = new Set<string>();\n for (const created of result.config.collectionsCreated) {\n said.add(created.name);\n const made = result.manifests.filter((m) => m.collection === created.name && m.created);\n const head = `${dry ? \"Would create\" : \"Created\"} collection ${created.name} (paths: ${list(created.paths)})`;\n if (made.length === 0) {\n lines.push(`${head}.`);\n continue;\n }\n const owns = list(made.flatMap((m) => m.keys));\n lines.push(`${head} and ${list(made.map((m) => m.file))}; it ${dry ? \"would own\" : \"owns\"} ${owns}.`);\n }\n for (const m of result.manifests) {\n if (said.has(m.collection) && m.created) continue;\n const added = said.has(m.collection) ? [] : pathsOf(m.collection);\n if (added.length > 0) said.add(m.collection);\n const keys = list(m.keys);\n if (m.created) {\n if (added.length > 0) {\n lines.push(\n dry\n ? `Would add ${list(added)} to collection ${m.collection}'s paths and create ${m.file}; it would own ${keys}.`\n : `Added ${list(added)} to collection ${m.collection}'s paths and created ${m.file}; it owns ${keys}.`,\n );\n } else {\n lines.push(\n dry\n ? `Would create ${m.file}; collections[${m.collection}].externalMetadata[${m.index}] would own ${keys}.`\n : `Created ${m.file}; collections[${m.collection}].externalMetadata[${m.index}] owns ${keys}.`,\n );\n }\n continue;\n }\n const beyond = m.beyond > 0 ? `, ${m.beyond} beyond the paths you named` : \"\";\n const pronoun = (n: number): string => (n === 1 ? \"it\" : \"them\");\n if (m.keysRemoved.length > 0) {\n const what = `${list(m.keysRemoved)} from ${m.file}'s keys`;\n const it = pronoun(m.keysRemoved.length);\n const where = `into every page in collection ${m.collection}${beyond}`;\n lines.push(dry ? `Would remove ${what}, moving ${it} ${where}.` : `Removing ${what} moves ${it} ${where}.`);\n }\n if (added.length > 0) {\n lines.push(\n dry\n ? `Would add ${list(added)} to collection ${m.collection}'s paths; ${m.file} would own ${keys}.`\n : `Added ${list(added)} to collection ${m.collection}'s paths; ${m.file} now owns ${keys}.`,\n );\n } else if (m.keysAdded.length > 0) {\n const what = `${list(m.keysAdded)} to ${m.file}'s keys`;\n const it = pronoun(m.keysAdded.length);\n const where = `out of every page in collection ${m.collection}${beyond}`;\n lines.push(dry ? `Would add ${what}, moving ${it} ${where}.` : `Adding ${what} moves ${it} ${where}.`);\n }\n if (m.undeclared) {\n lines.push(\n dry\n ? `${m.file} would no longer own any keys and would no longer be declared; delete it when you are ready.`\n : `${m.file} no longer owns any keys and is no longer declared; delete it when you are ready.`,\n );\n }\n }\n for (const p of result.config.pathsAdded) {\n if (said.has(p.collection)) continue;\n said.add(p.collection);\n lines.push(`${dry ? \"Would add\" : \"Added\"} ${list(pathsOf(p.collection))} to collection ${p.collection}'s paths.`);\n }\n\n // ---- The pages ---------------------------------------------------------------\n const width = Math.max(\n 7,\n ...result.files.flatMap((f) => [...f.moved, ...f.stayed].map((v) => v.key.length)),\n );\n const shown = result.files.filter((f) => !f.beyond || f.stayed.length > 0);\n for (const f of shown) {\n lines.push(f.file);\n for (const mv of f.moved) {\n const name = c.cyan(mv.key.padEnd(width));\n if (mv.to === \"page\") {\n lines.push(` ${name} ← ${mv.from}`);\n } else {\n lines.push(` ${name} → ${mv.manifest}${mv.line !== undefined ? `:${mv.line}` : \"\"}`);\n }\n }\n for (const st of f.stayed) {\n lines.push(` ${c.cyan(st.key.padEnd(width))} ${c.yellow(`stays: ${st.detail ?? st.reason}`)}`);\n }\n }\n const hidden = result.files.length - shown.length;\n if (hidden > 0) lines.push(`… (${plural(hidden, \"more file\")})`);\n\n // ---- The summary ---------------------------------------------------------------\n const s = result.summary;\n if (s.files === 0) {\n lines.push(\"0 files, nothing to move\");\n return lines.join(\"\\n\");\n }\n const moves = result.files.flatMap((f) => f.moved);\n const toPage = moves.filter((m) => m.to === \"page\").length;\n const toManifest = moves.flatMap((m) => (m.to === \"manifest\" ? [m.manifest] : []));\n const manifests = plural(new Set(toManifest).size, \"manifest\");\n let footer = `${plural(s.files, \"file\")}, ${plural(s.moved, \"value\")} ${dry ? \"would move\" : \"moved\"}`;\n if (toPage > 0 && toManifest.length > 0) {\n footer += `: ${toPage} into pages, ${toManifest.length} into ${manifests}`;\n } else if (toManifest.length > 0) {\n footer += ` to ${manifests}`;\n } else if (toPage > 0) {\n footer += \" into pages\";\n }\n if (s.stayed > 0) footer += `, ${s.stayed} stayed`;\n lines.push(s.stayed > 0 ? c.yellow(footer) : footer);\n return lines.join(\"\\n\");\n}\n","/**\n * validate's offer to move misplaced values (proposal 0047, prompt P2).\n *\n * After the report is printed, on a terminal, each collection with an\n * unsuppressed `location:external` or `location:page` finding gets one\n * question. A yes runs relocate for the files and keys of those findings (a\n * `keys:` change still reaches every member page, as relocate's does) and\n * prints relocate's pretty output. A no does nothing: the findings already\n * said it.\n *\n * Everything the user reads goes to `output`, which the CLI makes stderr so\n * the report on stdout stays machine-readable. The exit code is never this\n * module's to change: it is the report's.\n *\n * No question is put without a `Confirm` (off a terminal, or a run reading\n * stdin), under `--no-config`, for stdin's own findings, or for a page with no\n * possible home. A baselined finding never reaches here, so a baseline is how\n * someone stops being asked.\n */\nimport type { Confirm } from \"../../shared/prompt.js\";\nimport { programName } from \"../../shared/program-name.js\";\nimport { resolveRunConfig } from \"../core/config.js\";\nimport { STDIN_LABEL } from \"../core/load-files.js\";\nimport { LOCATION_EXTERNAL_SCHEMA, LOCATION_PAGE_SCHEMA } from \"../core/location.js\";\nimport {\n applyRelocation,\n keyHome,\n offerPrompt,\n planRelocation,\n relocationContext,\n type RelocateResult,\n type RelocationContext,\n} from \"../core/relocation.js\";\nimport { collectSchemaPins } from \"../core/resolve-schema.js\";\nimport { schemaLoadOptions } from \"../core/schema-registry.js\";\nimport { Validator } from \"../core/validator.js\";\nimport { renderRelocatePretty } from \"../reporters/relocate.js\";\nimport { DocmetaError, type ValidationResult } from \"../types.js\";\n\nexport interface ValidateOfferOptions {\n /** The results as reported: after the baseline, so a suppressed finding is not offered. */\n results: readonly ValidationResult[];\n /** The run's inputs as validate got them, for the config and a created collection's `paths:`. */\n inputs: string[];\n cwd?: string;\n configPath?: string;\n noConfig?: boolean;\n collections?: string[];\n cliSchemas?: string[];\n as?: string;\n respectGitignore?: boolean;\n offline?: boolean;\n env?: NodeJS.ProcessEnv;\n /** The terminal's `Confirm`; absent means no question is put. */\n confirm?: Confirm;\n /** Where the notice and relocate's output go: stderr, from the CLI. */\n output: { write: (chunk: string) => unknown };\n color?: boolean;\n}\n\n/** The files and keys of one collection's findings. */\ninterface Group {\n files: Set<string>;\n keys: Set<string>;\n}\n\n/**\n * Put P2 once per collection with a location finding, and run relocate for\n * each yes. Returns the applied results, in the order they ran.\n */\nexport async function offerRelocation(opts: ValidateOfferOptions): Promise<RelocateResult[]> {\n const { confirm, output } = opts;\n if (confirm === undefined || opts.noConfig === true) return [];\n const findings = opts.results.flatMap((r) =>\n r.file === STDIN_LABEL\n ? []\n : r.errors\n .filter((e) => e.schema === LOCATION_EXTERNAL_SCHEMA || e.schema === LOCATION_PAGE_SCHEMA)\n .flatMap((e) => (e.subject === undefined ? [] : [{ file: r.file, key: e.subject, schema: e.schema }])),\n );\n if (findings.length === 0) return [];\n\n const cwd = opts.cwd ?? process.cwd();\n const run = await resolveRunConfig({\n cwd,\n ...(opts.configPath !== undefined ? { configPath: opts.configPath } : {}),\n inputs: opts.inputs,\n ...(opts.collections !== undefined ? { collections: opts.collections } : {}),\n });\n const validator = new Validator(\n schemaLoadOptions({\n root: run.configDir ?? cwd,\n fileBase: cwd,\n ttlHours: run.config?.schemaCache?.ttlHours,\n offline: opts.offline ?? run.config?.offline,\n pins: collectSchemaPins(run.config),\n registered: run.config?.registered,\n }),\n );\n const ctx: RelocationContext = relocationContext(run, {\n cwd,\n targets: run.fromCollections ? [] : opts.inputs,\n validator,\n ...(opts.cliSchemas !== undefined && opts.cliSchemas.length > 0 ? { cliSchemas: opts.cliSchemas } : {}),\n ...(opts.as !== undefined ? { as: opts.as } : {}),\n ...(opts.respectGitignore !== undefined ? { respectGitignore: opts.respectGitignore } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n });\n\n // The collection each finding's value would move within: the one whose\n // manifest holds a `location:page` value, or the home §3 picks for a\n // `location:external` one. A page with no possible home is not offered.\n const groups = new Map<string, Group>();\n for (const f of findings) {\n const home = await keyHome(ctx, f.file, {}, f.key);\n let collection: string | undefined;\n if (f.schema === LOCATION_PAGE_SCHEMA) {\n if (home.kind === \"manifest\") collection = home.collection;\n } else if (home.kind === \"unowned\" && home.home.kind === \"collection\") {\n collection = home.home.collection;\n }\n if (collection === undefined) continue;\n const group = groups.get(collection) ?? { files: new Set<string>(), keys: new Set<string>() };\n group.files.add(f.file);\n group.keys.add(f.key);\n groups.set(collection, group);\n }\n\n const applied: RelocateResult[] = [];\n const say = (message: string): void => {\n output.write(`${programName()}: ${message}\\n`);\n };\n for (const [collection, group] of groups) {\n let plan;\n try {\n plan = await planRelocation(ctx, { files: [...group.files], fields: [...group.keys] });\n } catch (err) {\n // A plan that cannot be made (a manifest path that exists undeclared, a\n // single-tool config) is reported and not offered. The report already\n // stands, and its exit code is not this offer's to change.\n if (!(err instanceof DocmetaError)) throw err;\n say(err.message);\n continue;\n }\n if (plan.writes.length === 0) continue;\n // Only this collection's offer: another's would word changes this question does not cover.\n const offer = plan.offers.find((o) => o.collection === collection);\n if (offer === undefined) continue;\n const { notice, question } = offerPrompt(offer, \"validate\");\n say(notice);\n if (!(await confirm(question))) continue;\n const result = await applyRelocation(ctx, plan);\n output.write(`${renderRelocatePretty(result, { color: opts.color ?? false })}\\n`);\n applied.push(result);\n }\n return applied;\n}\n","/**\n * Reporter for `schemas infer`.\n *\n * The report **is** the product of this command, so the columns are chosen to\n * answer exactly one question each (0010 stress test 1):\n *\n * - **coverage** — require it now (~100%), require it behind a\n * `--write-baseline` ratchet (middling), or do not require it at all (low\n * single digits: one team's convention, not a standard).\n * - **types** — a distribution with counts, so a `string ×900, number ×4` split\n * reads as four data errors rather than as a union worth encoding.\n * - **sample** — what the values actually look like, which is what tells you\n * whether the key means what its name suggests.\n *\n * Files with no metadata block are on their own line rather than folded into a\n * denominator: they pass a require-nothing schema and fail the moment any key\n * becomes required, which is the surprise the report exists to prevent.\n */\nimport type { InferKeyReport, InferResult } from \"../commands/schemas.js\";\nimport { toJsonText } from \"../core/json-text.js\";\nimport { palette } from \"../../shared/color.js\";\n\nexport interface InferReportOptions {\n color?: boolean;\n}\n\n/** Outliers listed inline before the report defers to the count. */\nconst OUTLIERS_SHOWN = 5;\n\n/** Enum values listed in the sample column before it elides the rest. */\nconst ENUM_SHOWN = 3;\n\nconst SAMPLE_WIDTH = 46;\n\n/** Thousands separators, pinned to one locale so output is machine-stable. */\nfunction count(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\nfunction percent(n: number): string {\n return `${n.toFixed(1)}%`;\n}\n\nfunction truncate(text: string, width: number): string {\n return text.length <= width ? text : `${text.slice(0, width - 1)}…`;\n}\n\n/** `\"Getting started\"` — JSON spelling, so a string is visibly a string. */\nexport function sampleCell(key: InferKeyReport): string {\n if (key.enumValues) {\n const shown = key.enumValues\n .slice(0, ENUM_SHOWN)\n .map((v) => (typeof v === \"string\" ? v : JSON.stringify(v)));\n if (key.enumValues.length > ENUM_SHOWN) shown.push(\"…\");\n return truncate(shown.join(\" | \"), SAMPLE_WIDTH);\n }\n if (key.sample === undefined) return \"\";\n // `toJsonText`, not `JSON.stringify`, so the `?? \"\"` stays visibly\n // reachable — see there.\n return truncate(toJsonText(key.sample) ?? \"\", SAMPLE_WIDTH);\n}\n\n/** `string`, `string (date)`, `string (7 enum)`, or `string ×900, number ×4`. */\nexport function typesCell(key: InferKeyReport): string {\n if (key.types.length > 1) {\n return key.types.map((t) => `${t.type} ×${count(t.count)}`).join(\", \");\n }\n if (key.enumValues) return `${key.dominantType} (${key.enumValues.length} enum)`;\n if (key.format) return `${key.dominantType} (${key.format})`;\n return key.dominantType;\n}\n\nexport function renderInfer(\n result: InferResult,\n opts: InferReportOptions = {},\n): string {\n const c = palette(opts.color ?? false);\n const lines: string[] = [];\n\n const headline = [\n `${count(result.filesScanned)} file${result.filesScanned === 1 ? \"\" : \"s\"} scanned`,\n ];\n headline.push(\n `${count(result.filesWithoutMetadata)} with no metadata block`,\n );\n if (result.unreadable.length > 0) {\n headline.push(`${count(result.unreadable.length)} unreadable`);\n }\n // Same reason `validate` names it on its summary line: every coverage\n // percentage below is computed over `filesScanned`, so a denominator that\n // quietly shrank moves every number in the report. A key at 100% across the\n // eight files `.gitignore` left is not the same finding as one at 100%\n // across all forty, and the headline is the only place that is visible.\n // Omitted at zero, which is every run in a clean repo.\n if (result.gitignoreSkipped > 0) {\n headline.push(`${count(result.gitignoreSkipped)} skipped by .gitignore`);\n }\n lines.push(headline.join(c.dim(\" · \")));\n\n if (result.keys.length === 0) {\n lines.push(\"\", c.dim(\"No metadata keys found.\"));\n return lines.join(\"\\n\");\n }\n\n const rows = result.keys.map((k) => ({\n key: k.key,\n coverage: percent(k.coverage),\n types: typesCell(k),\n sample: sampleCell(k),\n }));\n const width = (pick: (r: (typeof rows)[number]) => string, head: string) =>\n Math.max(head.length, ...rows.map((r) => pick(r).length));\n const wKey = width((r) => r.key, \"key\");\n const wCov = width((r) => r.coverage, \"coverage\");\n const wTypes = width((r) => r.types, \"types\");\n\n lines.push(\n \"\",\n c.dim(\n `${\"key\".padEnd(wKey)} ${\"coverage\".padStart(wCov)} ${\"types\".padEnd(wTypes)} sample`,\n ),\n );\n for (const r of rows) {\n lines.push(\n `${c.cyan(r.key.padEnd(wKey))} ${r.coverage.padStart(wCov)} ${r.types.padEnd(wTypes)} ${c.dim(r.sample)}`,\n );\n }\n\n if (result.hiddenByMinCoverage > 0) {\n lines.push(\n \"\",\n c.dim(\n `${count(result.hiddenByMinCoverage)} key(s) below --min-coverage are not shown.`,\n ),\n );\n }\n\n const withOutliers = result.keys.filter((k) => k.outlierCount > 0);\n if (withOutliers.length > 0) {\n lines.push(\n \"\",\n c.bold(\"Type outliers — these are data errors, not a union:\"),\n );\n for (const k of withOutliers) {\n for (const o of k.outliers.slice(0, OUTLIERS_SHOWN)) {\n const at = o.line === undefined ? o.file : `${o.file}:${o.line}`;\n lines.push(` ${k.key} ${at} ${o.type} (expected ${k.dominantType})`);\n }\n const rest = k.outlierCount - Math.min(k.outliers.length, OUTLIERS_SHOWN);\n if (rest > 0) lines.push(c.dim(` ${k.key} …and ${count(rest)} more`));\n }\n }\n\n for (const u of result.unreadable) {\n lines.push(\"\", `${c.yellow(\"!\")} ${u.file}: ${u.message}`);\n }\n\n if (result.out !== undefined) {\n const properties = Object.keys(result.draft.properties ?? {}).length;\n lines.push(\n \"\",\n `Wrote a draft schema to ${c.cyan(result.out)} — ${count(properties)} propert${properties === 1 ? \"y\" : \"ies\"}, nothing required.`,\n c.dim(\n \"Nothing is required on purpose: what your docset contains is not the same as what your standard should demand. Promote a key with `validate --write-baseline` behind it.\",\n ),\n );\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,SAAS,kBAAkB;AAC3B,SAAS,SAAS,WAAW,mBAAmB;AAChD,SAAS,SAAS,cAAc;AAChC,OAAO,eAAe;;;ACMf,IAAM,mBAAmB,CAAC,UAAU,MAAM;AAK1C,IAAM,uBAAuB,WAAW,gBAAgB;AAExD,SAAS,iBAAiB,OAA8C;AAC7E,SAAQ,iBAAuC,SAAS,KAAK;AAC/D;AAMO,SAAS,eACd,QACA,QACA,OAA8B,CAAC,GACvB;AACR,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,KAAK,UAAU,aAAa,MAAM,GAAG,MAAM,CAAC;AAAA,IACrD,KAAK;AACH,aAAO,qBAAqB,QAAQ,IAAI;AAAA,IAC1C,SAAS;AACP,YAAM,cAAqB;AAC3B,YAAM,IAAI;AAAA,QACR,iDAAiD,KAAK,UAAU,WAAW,CAAC;AAAA,MAC9E;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,aAAa,QAAiC;AAC5D,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,QAAQ;AAAA,MACN,MAAM,OAAO,OAAO;AAAA,MACpB,SAAS,OAAO,OAAO;AAAA,MACvB,oBAAoB,OAAO,OAAO;AAAA,MAClC,YAAY,OAAO,OAAO;AAAA,IAC5B;AAAA,IACA,WAAW,OAAO,UAAU,IAAI,CAAC,OAAO;AAAA,MACtC,MAAM,EAAE;AAAA,MACR,YAAY,EAAE;AAAA,MACd,SAAS,EAAE;AAAA,MACX,WAAW,EAAE;AAAA,MACb,aAAa,EAAE;AAAA,MACf,YAAY,EAAE;AAAA,IAChB,EAAE;AAAA,IACF,OAAO,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,MAC9B,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,MACT,QAAQ,EAAE,OAAO,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,QAAQ,EAAE,OAAO,EAAE;AAAA,IAChE,EAAE;AAAA,IACF,SAAS,OAAO;AAAA,EAClB;AACF;AAEA,IAAM,SAAS,CAAC,GAAW,SAAyB,GAAG,CAAC,IAAI,IAAI,GAAG,MAAM,IAAI,KAAK,GAAG;AACrF,IAAM,OAAO,CAAC,OAAkC,GAAG,KAAK,IAAI;AAErD,SAAS,qBAAqB,QAAwB,OAA8B,CAAC,GAAW;AACrG,QAAM,IAAI,QAAQ,KAAK,SAAS,KAAK;AACrC,QAAM,MAAM,OAAO;AACnB,QAAM,QAAkB,CAAC;AAGzB,MAAI,OAAO,OAAO,WAAW,OAAO,OAAO,SAAS,MAAM;AACxD,UAAM,KAAK,MAAM,gBAAgB,OAAO,OAAO,IAAI,MAAM,WAAW,OAAO,OAAO,IAAI,GAAG;AAAA,EAC3F;AACA,QAAM,UAAU,CAAC,eACf,OAAO,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,eAAe,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AACvF,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,WAAW,OAAO,OAAO,oBAAoB;AACtD,SAAK,IAAI,QAAQ,IAAI;AACrB,UAAM,OAAO,OAAO,UAAU,OAAO,CAAC,MAAM,EAAE,eAAe,QAAQ,QAAQ,EAAE,OAAO;AACtF,UAAM,OAAO,GAAG,MAAM,iBAAiB,SAAS,eAAe,QAAQ,IAAI,YAAY,KAAK,QAAQ,KAAK,CAAC;AAC1G,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,KAAK,GAAG,IAAI,GAAG;AACrB;AAAA,IACF;AACA,UAAM,OAAO,KAAK,KAAK,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;AAC7C,UAAM,KAAK,GAAG,IAAI,QAAQ,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,MAAM,cAAc,MAAM,IAAI,IAAI,GAAG;AAAA,EACtG;AACA,aAAW,KAAK,OAAO,WAAW;AAChC,QAAI,KAAK,IAAI,EAAE,UAAU,KAAK,EAAE,QAAS;AACzC,UAAM,QAAQ,KAAK,IAAI,EAAE,UAAU,IAAI,CAAC,IAAI,QAAQ,EAAE,UAAU;AAChE,QAAI,MAAM,SAAS,EAAG,MAAK,IAAI,EAAE,UAAU;AAC3C,UAAM,OAAO,KAAK,EAAE,IAAI;AACxB,QAAI,EAAE,SAAS;AACb,UAAI,MAAM,SAAS,GAAG;AACpB,cAAM;AAAA,UACJ,MACI,aAAa,KAAK,KAAK,CAAC,kBAAkB,EAAE,UAAU,uBAAuB,EAAE,IAAI,kBAAkB,IAAI,MACzG,SAAS,KAAK,KAAK,CAAC,kBAAkB,EAAE,UAAU,wBAAwB,EAAE,IAAI,aAAa,IAAI;AAAA,QACvG;AAAA,MACF,OAAO;AACL,cAAM;AAAA,UACJ,MACI,gBAAgB,EAAE,IAAI,iBAAiB,EAAE,UAAU,sBAAsB,EAAE,KAAK,eAAe,IAAI,MACnG,WAAW,EAAE,IAAI,iBAAiB,EAAE,UAAU,sBAAsB,EAAE,KAAK,UAAU,IAAI;AAAA,QAC/F;AAAA,MACF;AACA;AAAA,IACF;AACA,UAAM,SAAS,EAAE,SAAS,IAAI,KAAK,EAAE,MAAM,gCAAgC;AAC3E,UAAM,UAAU,CAAC,MAAuB,MAAM,IAAI,OAAO;AACzD,QAAI,EAAE,YAAY,SAAS,GAAG;AAC5B,YAAM,OAAO,GAAG,KAAK,EAAE,WAAW,CAAC,SAAS,EAAE,IAAI;AAClD,YAAM,KAAK,QAAQ,EAAE,YAAY,MAAM;AACvC,YAAM,QAAQ,iCAAiC,EAAE,UAAU,GAAG,MAAM;AACpE,YAAM,KAAK,MAAM,gBAAgB,IAAI,YAAY,EAAE,IAAI,KAAK,MAAM,YAAY,IAAI,UAAU,EAAE,IAAI,KAAK,GAAG;AAAA,IAC5G;AACA,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM;AAAA,QACJ,MACI,aAAa,KAAK,KAAK,CAAC,kBAAkB,EAAE,UAAU,aAAa,EAAE,IAAI,cAAc,IAAI,MAC3F,SAAS,KAAK,KAAK,CAAC,kBAAkB,EAAE,UAAU,aAAa,EAAE,IAAI,aAAa,IAAI;AAAA,MAC5F;AAAA,IACF,WAAW,EAAE,UAAU,SAAS,GAAG;AACjC,YAAM,OAAO,GAAG,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,IAAI;AAC9C,YAAM,KAAK,QAAQ,EAAE,UAAU,MAAM;AACrC,YAAM,QAAQ,mCAAmC,EAAE,UAAU,GAAG,MAAM;AACtE,YAAM,KAAK,MAAM,aAAa,IAAI,YAAY,EAAE,IAAI,KAAK,MAAM,UAAU,IAAI,UAAU,EAAE,IAAI,KAAK,GAAG;AAAA,IACvG;AACA,QAAI,EAAE,YAAY;AAChB,YAAM;AAAA,QACJ,MACI,GAAG,EAAE,IAAI,iGACT,GAAG,EAAE,IAAI;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACA,aAAW,KAAK,OAAO,OAAO,YAAY;AACxC,QAAI,KAAK,IAAI,EAAE,UAAU,EAAG;AAC5B,SAAK,IAAI,EAAE,UAAU;AACrB,UAAM,KAAK,GAAG,MAAM,cAAc,OAAO,IAAI,KAAK,QAAQ,EAAE,UAAU,CAAC,CAAC,kBAAkB,EAAE,UAAU,WAAW;AAAA,EACnH;AAGA,QAAM,QAAQ,KAAK;AAAA,IACjB;AAAA,IACA,GAAG,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC;AAAA,EACnF;AACA,QAAM,QAAQ,OAAO,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,OAAO,SAAS,CAAC;AACzE,aAAW,KAAK,OAAO;AACrB,UAAM,KAAK,EAAE,IAAI;AACjB,eAAW,MAAM,EAAE,OAAO;AACxB,YAAM,OAAO,EAAE,KAAK,GAAG,IAAI,OAAO,KAAK,CAAC;AACxC,UAAI,GAAG,OAAO,QAAQ;AACpB,cAAM,KAAK,OAAO,IAAI,YAAO,GAAG,IAAI,EAAE;AAAA,MACxC,OAAO;AACL,cAAM,KAAK,OAAO,IAAI,YAAO,GAAG,QAAQ,GAAG,GAAG,SAAS,SAAY,IAAI,GAAG,IAAI,KAAK,EAAE,EAAE;AAAA,MACzF;AAAA,IACF;AACA,eAAW,MAAM,EAAE,QAAQ;AACzB,YAAM,KAAK,OAAO,EAAE,KAAK,GAAG,IAAI,OAAO,KAAK,CAAC,CAAC,KAAK,EAAE,OAAO,UAAU,GAAG,UAAU,GAAG,MAAM,EAAE,CAAC,EAAE;AAAA,IACnG;AAAA,EACF;AACA,QAAM,SAAS,OAAO,MAAM,SAAS,MAAM;AAC3C,MAAI,SAAS,EAAG,OAAM,KAAK,WAAM,OAAO,QAAQ,WAAW,CAAC,GAAG;AAG/D,QAAM,IAAI,OAAO;AACjB,MAAI,EAAE,UAAU,GAAG;AACjB,UAAM,KAAK,0BAA0B;AACrC,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AACA,QAAM,QAAQ,OAAO,MAAM,QAAQ,CAAC,MAAM,EAAE,KAAK;AACjD,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE;AACpD,QAAM,aAAa,MAAM,QAAQ,CAAC,MAAO,EAAE,OAAO,aAAa,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAE;AACjF,QAAM,YAAY,OAAO,IAAI,IAAI,UAAU,EAAE,MAAM,UAAU;AAC7D,MAAI,SAAS,GAAG,OAAO,EAAE,OAAO,MAAM,CAAC,KAAK,OAAO,EAAE,OAAO,OAAO,CAAC,IAAI,MAAM,eAAe,OAAO;AACpG,MAAI,SAAS,KAAK,WAAW,SAAS,GAAG;AACvC,cAAU,KAAK,MAAM,gBAAgB,WAAW,MAAM,SAAS,SAAS;AAAA,EAC1E,WAAW,WAAW,SAAS,GAAG;AAChC,cAAU,OAAO,SAAS;AAAA,EAC5B,WAAW,SAAS,GAAG;AACrB,cAAU;AAAA,EACZ;AACA,MAAI,EAAE,SAAS,EAAG,WAAU,KAAK,EAAE,MAAM;AACzC,QAAM,KAAK,EAAE,SAAS,IAAI,EAAE,OAAO,MAAM,IAAI,MAAM;AACnD,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACnIA,eAAsB,gBAAgB,MAAuD;AAC3F,QAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,MAAI,YAAY,UAAa,KAAK,aAAa,KAAM,QAAO,CAAC;AAC7D,QAAM,WAAW,KAAK,QAAQ;AAAA,IAAQ,CAAC,MACrC,EAAE,SAAS,cACP,CAAC,IACD,EAAE,OACC,OAAO,CAAC,MAAM,EAAE,WAAW,4BAA4B,EAAE,WAAW,oBAAoB,EACxF,QAAQ,CAAC,MAAO,EAAE,YAAY,SAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,EAAE,SAAS,QAAQ,EAAE,OAAO,CAAC,CAAE;AAAA,EAC7G;AACA,MAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AAEnC,QAAM,MAAM,KAAK,OAAO,QAAQ,IAAI;AACpC,QAAM,MAAM,MAAM,iBAAiB;AAAA,IACjC;AAAA,IACA,GAAI,KAAK,eAAe,SAAY,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,IACvE,QAAQ,KAAK;AAAA,IACb,GAAI,KAAK,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,EAC5E,CAAC;AACD,QAAM,YAAY,IAAI;AAAA,IACpB,kBAAkB;AAAA,MAChB,MAAM,IAAI,aAAa;AAAA,MACvB,UAAU;AAAA,MACV,UAAU,IAAI,QAAQ,aAAa;AAAA,MACnC,SAAS,KAAK,WAAW,IAAI,QAAQ;AAAA,MACrC,MAAM,kBAAkB,IAAI,MAAM;AAAA,MAClC,YAAY,IAAI,QAAQ;AAAA,IAC1B,CAAC;AAAA,EACH;AACA,QAAM,MAAyB,kBAAkB,KAAK;AAAA,IACpD;AAAA,IACA,SAAS,IAAI,kBAAkB,CAAC,IAAI,KAAK;AAAA,IACzC;AAAA,IACA,GAAI,KAAK,eAAe,UAAa,KAAK,WAAW,SAAS,IAAI,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,IACrG,GAAI,KAAK,OAAO,SAAY,EAAE,IAAI,KAAK,GAAG,IAAI,CAAC;AAAA,IAC/C,GAAI,KAAK,qBAAqB,SAAY,EAAE,kBAAkB,KAAK,iBAAiB,IAAI,CAAC;AAAA,IACzF,GAAI,KAAK,QAAQ,SAAY,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,EACpD,CAAC;AAKD,QAAM,SAAS,oBAAI,IAAmB;AACtC,aAAW,KAAK,UAAU;AACxB,UAAM,OAAO,MAAM,QAAQ,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,GAAG;AACjD,QAAI;AACJ,QAAI,EAAE,WAAW,sBAAsB;AACrC,UAAI,KAAK,SAAS,WAAY,cAAa,KAAK;AAAA,IAClD,WAAW,KAAK,SAAS,aAAa,KAAK,KAAK,SAAS,cAAc;AACrE,mBAAa,KAAK,KAAK;AAAA,IACzB;AACA,QAAI,eAAe,OAAW;AAC9B,UAAM,QAAQ,OAAO,IAAI,UAAU,KAAK,EAAE,OAAO,oBAAI,IAAY,GAAG,MAAM,oBAAI,IAAY,EAAE;AAC5F,UAAM,MAAM,IAAI,EAAE,IAAI;AACtB,UAAM,KAAK,IAAI,EAAE,GAAG;AACpB,WAAO,IAAI,YAAY,KAAK;AAAA,EAC9B;AAEA,QAAM,UAA4B,CAAC;AACnC,QAAM,MAAM,CAAC,YAA0B;AACrC,WAAO,MAAM,GAAG,YAAY,CAAC,KAAK,OAAO;AAAA,CAAI;AAAA,EAC/C;AACA,aAAW,CAAC,YAAY,KAAK,KAAK,QAAQ;AACxC,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,eAAe,KAAK,EAAE,OAAO,CAAC,GAAG,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;AAAA,IACvF,SAAS,KAAK;AAIZ,UAAI,EAAE,eAAe,cAAe,OAAM;AAC1C,UAAI,IAAI,OAAO;AACf;AAAA,IACF;AACA,QAAI,KAAK,OAAO,WAAW,EAAG;AAE9B,UAAM,QAAQ,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,eAAe,UAAU;AACjE,QAAI,UAAU,OAAW;AACzB,UAAM,EAAE,QAAAA,SAAQ,SAAS,IAAI,YAAY,OAAO,UAAU;AAC1D,QAAIA,OAAM;AACV,QAAI,CAAE,MAAM,QAAQ,QAAQ,EAAI;AAChC,UAAM,SAAS,MAAM,gBAAgB,KAAK,IAAI;AAC9C,WAAO,MAAM,GAAG,qBAAqB,QAAQ,EAAE,OAAO,KAAK,SAAS,MAAM,CAAC,CAAC;AAAA,CAAI;AAChF,YAAQ,KAAK,MAAM;AAAA,EACrB;AACA,SAAO;AACT;;;ACjIA,IAAM,iBAAiB;AAGvB,IAAM,aAAa;AAEnB,IAAM,eAAe;AAGrB,SAAS,MAAM,GAAmB;AAChC,SAAO,EAAE,eAAe,OAAO;AACjC;AAEA,SAAS,QAAQ,GAAmB;AAClC,SAAO,GAAG,EAAE,QAAQ,CAAC,CAAC;AACxB;AAEA,SAAS,SAAS,MAAc,OAAuB;AACrD,SAAO,KAAK,UAAU,QAAQ,OAAO,GAAG,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC;AAClE;AAGO,SAAS,WAAW,KAA6B;AACtD,MAAI,IAAI,YAAY;AAClB,UAAM,QAAQ,IAAI,WACf,MAAM,GAAG,UAAU,EACnB,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,CAAC,CAAE;AAC7D,QAAI,IAAI,WAAW,SAAS,WAAY,OAAM,KAAK,QAAG;AACtD,WAAO,SAAS,MAAM,KAAK,KAAK,GAAG,YAAY;AAAA,EACjD;AACA,MAAI,IAAI,WAAW,OAAW,QAAO;AAGrC,SAAO,SAAS,WAAW,IAAI,MAAM,KAAK,IAAI,YAAY;AAC5D;AAGO,SAAS,UAAU,KAA6B;AACrD,MAAI,IAAI,MAAM,SAAS,GAAG;AACxB,WAAO,IAAI,MAAM,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,QAAK,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAAA,EACvE;AACA,MAAI,IAAI,WAAY,QAAO,GAAG,IAAI,YAAY,KAAK,IAAI,WAAW,MAAM;AACxE,MAAI,IAAI,OAAQ,QAAO,GAAG,IAAI,YAAY,KAAK,IAAI,MAAM;AACzD,SAAO,IAAI;AACb;AAEO,SAAS,YACd,QACA,OAA2B,CAAC,GACpB;AACR,QAAM,IAAI,QAAQ,KAAK,SAAS,KAAK;AACrC,QAAM,QAAkB,CAAC;AAEzB,QAAM,WAAW;AAAA,IACf,GAAG,MAAM,OAAO,YAAY,CAAC,QAAQ,OAAO,iBAAiB,IAAI,KAAK,GAAG;AAAA,EAC3E;AACA,WAAS;AAAA,IACP,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAAA,EACvC;AACA,MAAI,OAAO,WAAW,SAAS,GAAG;AAChC,aAAS,KAAK,GAAG,MAAM,OAAO,WAAW,MAAM,CAAC,aAAa;AAAA,EAC/D;AAOA,MAAI,OAAO,mBAAmB,GAAG;AAC/B,aAAS,KAAK,GAAG,MAAM,OAAO,gBAAgB,CAAC,wBAAwB;AAAA,EACzE;AACA,QAAM,KAAK,SAAS,KAAK,EAAE,IAAI,QAAK,CAAC,CAAC;AAEtC,MAAI,OAAO,KAAK,WAAW,GAAG;AAC5B,UAAM,KAAK,IAAI,EAAE,IAAI,yBAAyB,CAAC;AAC/C,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAEA,QAAM,OAAO,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACnC,KAAK,EAAE;AAAA,IACP,UAAU,QAAQ,EAAE,QAAQ;AAAA,IAC5B,OAAO,UAAU,CAAC;AAAA,IAClB,QAAQ,WAAW,CAAC;AAAA,EACtB,EAAE;AACF,QAAM,QAAQ,CAAC,MAA4C,SACzD,KAAK,IAAI,KAAK,QAAQ,GAAG,KAAK,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,CAAC;AAC1D,QAAM,OAAO,MAAM,CAAC,MAAM,EAAE,KAAK,KAAK;AACtC,QAAM,OAAO,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU;AAChD,QAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,OAAO;AAE5C,QAAM;AAAA,IACJ;AAAA,IACA,EAAE;AAAA,MACA,GAAG,MAAM,OAAO,IAAI,CAAC,KAAK,WAAW,SAAS,IAAI,CAAC,KAAK,QAAQ,OAAO,MAAM,CAAC;AAAA,IAChF;AAAA,EACF;AACA,aAAW,KAAK,MAAM;AACpB,UAAM;AAAA,MACJ,GAAG,EAAE,KAAK,EAAE,IAAI,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,SAAS,SAAS,IAAI,CAAC,KAAK,EAAE,MAAM,OAAO,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC;AAAA,IAC5G;AAAA,EACF;AAEA,MAAI,OAAO,sBAAsB,GAAG;AAClC,UAAM;AAAA,MACJ;AAAA,MACA,EAAE;AAAA,QACA,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC;AACjE,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM;AAAA,MACJ;AAAA,MACA,EAAE,KAAK,0DAAqD;AAAA,IAC9D;AACA,eAAW,KAAK,cAAc;AAC5B,iBAAW,KAAK,EAAE,SAAS,MAAM,GAAG,cAAc,GAAG;AACnD,cAAM,KAAK,EAAE,SAAS,SAAY,EAAE,OAAO,GAAG,EAAE,IAAI,IAAI,EAAE,IAAI;AAC9D,cAAM,KAAK,KAAK,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,IAAI,cAAc,EAAE,YAAY,GAAG;AAAA,MACxE;AACA,YAAM,OAAO,EAAE,eAAe,KAAK,IAAI,EAAE,SAAS,QAAQ,cAAc;AACxE,UAAI,OAAO,EAAG,OAAM,KAAK,EAAE,IAAI,KAAK,EAAE,GAAG,eAAU,MAAM,IAAI,CAAC,OAAO,CAAC;AAAA,IACxE;AAAA,EACF;AAEA,aAAW,KAAK,OAAO,YAAY;AACjC,UAAM,KAAK,IAAI,GAAG,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE;AAAA,EAC3D;AAEA,MAAI,OAAO,QAAQ,QAAW;AAC5B,UAAM,aAAa,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC,CAAC,EAAE;AAC9D,UAAM;AAAA,MACJ;AAAA,MACA,2BAA2B,EAAE,KAAK,OAAO,GAAG,CAAC,WAAM,MAAM,UAAU,CAAC,WAAW,eAAe,IAAI,MAAM,KAAK;AAAA,MAC7G,EAAE;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AHnFA,SAAS,aAAa,SAA2B;AAE/C,QAAM,UAAU,QAAQ,KAAK,EAAE,UAAU;AAMzC,SAAO,YAAY,EAAE,SAAS,OAAO,QAAQ,OAAO,MAAM,CAAC;AAC7D;AAiBA,SAAS,UAAU,SAAkB,KAAuB;AAC1D,MAAI,QAAQ,qBAAqB,QAAQ,MAAM,MAAO,QAAO;AAC7D,QAAM,SAAS,QAAQ;AACvB,MAAI,UAAU,OAAO,qBAAqB,QAAQ,MAAM,OAAO;AAC7D,WAAO,OAAO,KAAK,EAAE;AAAA,EACvB;AACA,SAAO;AACT;AAGA,SAAS,mBAAmB,OAA8B;AACxD,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,CAAC,eAAe,MAAM,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,qBAAqB,MAAM,UAAU,kBAAkB;AAAA,IACzD;AAAA,EACF;AACA,SAAO;AACT;AAGA,IAAM,QAAQ;AAsCd,SAAS,cAAc,OAAe,KAAa,OAAyB;AAC1E,MAAI,UAAU,MAAO,QAAO;AAG5B,QAAM,OAAO,UAAU,KAAK,KAAK;AACjC,QAAM,SAAS,QAAQ,KAAK,KAAK,KAAK,QAAQ,KAAK,MAAM,MAAM,KAAK;AAGpE,OAAK,UAAU,UAAU,WAAW,YAAY,KAAK,KAAK,CAAC,EAAG,QAAO;AACrE,MAAI,MAAM,SAAS,GAAG,KAAK,MAAM,WAAW,GAAG,EAAG,QAAO;AACzD,MAAI,KAAK,OAAQ,QAAO;AACxB,QAAM,MAAM,QAAQ,KAAK,EAAE,YAAY;AACvC,MAAI,QAAQ,MAAM,oBAAoB,EAAE,SAAS,GAAG,EAAG,QAAO;AAC9D,SAAO,QAAQ,KAAK,KAAK;AAC3B;AAkBO,SAAS,iBACd,WACA,UACA,cACA,KACuC;AACvC,QAAM,OAAO,OAAO,iBAAiB,WAAW,eAAe;AAE/D,MACE,SAAS,UACT,cAAc,UACd,cAAc,WAAW,KAAK,SAAS,WAAW,CAAC,GACnD;AACA,UAAM,IAAI;AAAA,MACR,IAAI,SAAS,kFAAkF,SAAS;AAAA,IAC1G;AAAA,EACF;AAOA,QAAM,SAAS,SAAS,cAAc,QAAQ,SAAY;AAC1D,QAAM,SAAS,WAAW,SAAY,CAAC,IAAI,UAAU,MAAM;AAC3D,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QACJ,cAAc,WAAc,SAAS,UAAa,cAAc,SAC5D,CAAC,WAAW,GAAG,QAAQ,IACvB;AACN,SAAO,EAAE,QAAQ,MAAM;AACzB;AAgBO,SAAS,mBACd,QACA,UACA,aACA,KACA,cAAc,OACoB;AAClC,QAAM,OAAO,OAAO,gBAAgB,WAAW,cAAc;AAE7D,MACE,SAAS,UACT,WAAW;AAAA;AAAA;AAAA;AAAA,EAKX,CAAC,KAAK,KAAK,MAAM;AAAA;AAAA;AAAA,EAIjB,cAAc,QAAQ,KAAK,eAAe,SAAS,WAAW,CAAC,GAC/D;AACA,QAAI,YAAa,QAAO,EAAE,KAAK,IAAI,OAAO,CAAC,QAAQ,GAAG,QAAQ,EAAE;AAChE,UAAM,IAAI;AAAA,MACR,IAAI,MAAM,+FAA+F,MAAM;AAAA,IACjH;AAAA,EACF;AAEA,QAAM,SAAS,SAAS,WAAW,QAAQ,SAAY;AACvD,QAAM,MAAM,QAAQ,KAAK,KAAK;AAC9B,MAAI,QAAQ,MAAM,CAAC,aAAa;AAC9B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QACJ,WAAW,WAAc,SAAS,UAAa,WAAW,SACtD,CAAC,QAAQ,GAAG,QAAQ,IACpB;AACN,SAAO,EAAE,KAAK,MAAM;AACtB;AAaO,SAAS,iBACd,KACyB;AAGzB,QAAM,SAAkC,uBAAO,OAAO,IAAI;AAI1D,aAAW,QAAQ,KAAK;AACtB,UAAM,QAAQ,KAAK,QAAQ,IAAI;AAC/B,UAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,UAAM,WAAW,UAAU,OAAO,UAAU,MAAM,QAAQ;AAC1D,UAAM,KAAK,WAAW,QAAQ;AAC9B,QAAI,MAAM,GAAG;AACX,YAAM,IAAI;AAAA,QACR,YAAY,IAAI;AAAA,MAClB;AAAA,IACF;AACA,UAAM,OAAO,KAAK,MAAM,GAAG,EAAE;AAQ7B,UAAM,OAAO,SAAS,KAAK,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI;AACnD,QAAI,CAAC,YAAY,IAAI,GAAG;AACtB,YAAM,IAAI;AAAA,QACR,iBAAiB,IAAI;AAAA,MACvB;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,MAAM,MAAM,WAAW,IAAI,EAAE;AAChD,QAAI,CAAC,UAAU;AACb,aAAO,IAAI,IAAI;AACf;AAAA,IACF;AACA,QAAI;AACF,aAAO,IAAI,IAAI,KAAK,MAAM,KAAK;AAAA,IACjC,QAAQ;AACN,YAAM,IAAI;AAAA,QACR,WAAW,IAAI,KAAK,KAAK,sDAAiD,IAAI,MAAM,KAAK,wCAAmC,IAAI,IAAI,KAAK;AAAA,MAC3I;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAaA,SAAS,oBAAoB,KAAe,QAAmC;AAC7E,MAAI,IAAI,SAAS;AACf,UAAM,IAAI;AAAA,MACR,YAAY,MAAM;AAAA,IACpB;AAAA,EACF;AACA,QAAM,UAA8B,CAAC,GAAG;AAAA,IACtC;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,EACN,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,OAAO;AAAA,IAC1B;AAAA,IACA,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ,SAAS,CAAC;AAAA,IACV;AAAA,EACF,EAAE;AACF,QAAM,UAAsB;AAAA,IAC1B,OAAO,QAAQ;AAAA,IACf,QAAQ;AAAA,IACR,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AAAA,EACzD;AACA,QAAM,OAAO,OAAO,QAAQ,SAAS,SAAS;AAAA,IAC5C,OAAO,IAAI;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,EACZ,CAAC;AACD,MAAI,KAAK,SAAS,KAAK,CAAC,mBAAmB,IAAI,MAAM,GAAG;AACtD,YAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,EAClC;AACA,UAAQ,WAAW,IAAI,KAAK,SAAS,IAAI,IAAI;AAC/C;AAEA,IAAM,gBAAgB,CAAC,YAAY,OAAO,SAAS,QAAQ,SAAS;AAGpE,SAAS,aAAa,GAAW,GAAmB;AAClD,MAAI,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;AAC3D,WAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;AAClC,UAAM,MAAM,CAAC,CAAC;AACd,aAAS,IAAI,GAAG,KAAK,EAAE,QAAQ,KAAK;AAClC,YAAM,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI;AACzC,UAAI;AAAA,QACF,KAAK;AAAA,WACF,IAAI,IAAI,CAAC,KAAK,KAAK;AAAA,WACnB,KAAK,CAAC,KAAK,KAAK;AAAA,WAChB,KAAK,IAAI,CAAC,KAAK,KAAK;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO,KAAK,EAAE,MAAM,KAAK;AAC3B;AAaA,SAAS,eAAe,OAA2B,KAAmB;AACpE,MAAI,UAAU,UAAa,UAAU,IAAK;AAC1C,MAAI,SAAS,KAAK,KAAK,EAAG;AAC1B,MAAI,UAAU,KAAK,KAAK,EAAE,OAAQ;AAClC,MAAI,WAAW,YAAY,KAAK,KAAK,CAAC,EAAG;AAEzC,QAAM,OAAO,cAAc;AAAA,IACzB,CAAC,SAAS,CAAC,MAAM,aAAa,MAAM,YAAY,GAAG,IAAI,CAAC;AAAA,EAC1D,EACG,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,IAAI,KAAK,KAAK,CAAC,EACjC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAE7B,QAAM,OAAO,KAAK,CAAC;AACnB,MAAI,CAAC,KAAM;AACX,QAAM,IAAI;AAAA,IACR,oBAAoB,KAAK,oBAAoB,KAAK,CAAC,CAAC;AAAA,EACtD;AACF;AAOA,SAAS,QACP,MACA,OACA,KACA,KACM;AACN,MAAI,UAAU,OAAW;AACzB,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,OAAO,QAAQ,KAAK;AACzD,UAAM,IAAI;AAAA,MACR,GAAG,IAAI,6BAA6B,GAAG,QAAQ,GAAG,SAAS,KAAK;AAAA,IAClE;AAAA,EACF;AACF;AA0NO,SAAS,eAAwB;AACtC,QAAM,UAAU,IAAI,QAAQ;AAC5B,UACG,KAAK,MAAM,EACX;AAAA,IACC;AAAA,EACF,EACC,QAAQ,gBAAI,SAAS,eAAe,EACpC,OAAO,cAAc,wBAAwB,EAI7C,mBAAmB,wBAAwB,EAM3C,aAAa;AAEhB,UACG,QAAQ,YAAY,EAAE,WAAW,KAAK,CAAC,EACvC,YAAY,iDAAiD,EAC7D;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE;AAAA,IACC;AAAA,IACA,WAAW,eAAe,KAAK,KAAK,CAAC;AAAA,IACrC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,mCAAmC,EACzD,OAAO,eAAe,sCAAsC,EAC5D,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,+BAA+B,EACxD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EAoBC;AAAA,IACC,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF,EACC;AAAA,IACC,IAAI;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF,EACC,OAAO,iBAAiB,6CAA6C,EACrE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,cAAc,0CAA0C,EAC/D;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC;AAAA,IACC,OAAO,OAAiB,SAA6B,YAAqB;AACxE,UAAI;AAGF,uBAAe,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC;AACtC,cAAM,SAAS,QAAQ;AACvB,YAAI,CAAC,eAAe,MAAM,GAAG;AAC3B,gBAAM,IAAI;AAAA,YACR,qBAAqB,MAAM,UAAU,kBAAkB;AAAA,UACzD;AAAA,QACF;AACA,cAAM,OAA6B,QAAQ,MACvC,UAAU,QAAQ,GAAG,IACrB;AACJ,cAAM,eAAe,MAAM,SAAS,GAAG,IACnC,MAAM,UAAU,IAChB;AAEJ,cAAM,EAAE,SAAS,SAAS,MAAM,IAAI,MAAM,YAAY;AAAA,UACpD,QAAQ;AAAA,UACR,YAAY,QAAQ;AAAA,UACpB;AAAA,UACA,SAAS,QAAQ;AAAA,UACjB,IAAI,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,UAKZ,aAAa,QAAQ;AAAA,UACrB,GAAG,aAAa,QAAQ,MAAM;AAAA,UAC9B,gBAAgB;AAAA,YACd,CAAC,gBAAgB,MAAM;AAAA,YACvB,QAAQ,IAAI;AAAA,UACd;AAAA,UACA;AAAA;AAAA;AAAA,UAGA,YAAY,QAAQ,aAAa,OAAO;AAAA,UACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA;AAAA;AAAA,UAGjD,SAAS,QAAQ,UAAU,OAAO;AAAA,UAClC,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,UAKV,UAAU,QAAQ;AAAA,UAClB,eAAe,QAAQ;AAAA;AAAA;AAAA,UAGvB,QAAQ,QAAQ,SAAS,SAAY;AAAA;AAAA,UAErC,QAAQ,QAAQ,SAAS,SAAY;AAAA;AAAA,UAErC,OAAO,QAAQ;AAAA,QACjB,CAAC;AAED,cAAM,QAAQ,aAAa,QAAQ,UAAU,OAAO;AACpD,cAAM,OAAO,OAAO,QAAQ,SAAS,SAAS;AAAA,UAC5C;AAAA,UACA,OAAO,QAAQ,QAAQ,KAAK;AAAA;AAAA;AAAA,UAG5B;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AAGD,YAAI,KAAK,SAAS,KAAK,CAAC,mBAAmB,IAAI,MAAM,GAAG;AACtD,kBAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,QAClC;AACA,gBAAQ,WAAW,QAAQ,SAAS,IAAI,IAAI;AAK5C,cAAM,gBAAgB;AAAA,UACpB;AAAA,UACA,QAAQ;AAAA,UACR,YAAY,QAAQ;AAAA,UACpB,IAAI,QAAQ;AAAA,UACZ,aAAa,QAAQ;AAAA,UACrB,GAAG,aAAa,QAAQ,MAAM;AAAA,UAC9B,kBAAkB,cAAc,QAAQ,SAAS;AAAA,UACjD,SAAS,QAAQ,UAAU,OAAO;AAAA,UAClC,SAAS,MAAM,SAAS,KAAK,IAAI,SAAY,gBAAgB;AAAA,UAC7D,QAAQ,QAAQ;AAAA,UAChB,OAAO,YAAY;AAAA,YACjB,UAAU,QAAQ,UAAU,SAAS,KAAK,EAAE,UAAU;AAAA,YACtD,OAAO,QAAQ,OAAO;AAAA,UACxB,CAAC;AAAA,QACH,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,aAAK,GAAG;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEF,UACG,QAAQ,KAAK,EACb,YAAY,6DAA6D,EAIzE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EAKC,OAAO,aAAa,8CAA8C,EAClE,OAAO,cAAc,0CAA0C,EAC/D,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE;AAAA,IACC;AAAA,IACA,WAAW,eAAe,KAAK,KAAK,CAAC;AAAA,IACrC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,mCAAmC,EACzD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,8BAA8B,EACvD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC;AAAA,IACC,OACE,WACA,UACA,SACA,YACG;AACH,UAAI;AACF,cAAM,SAAS,mBAAmB,QAAQ,MAAM;AAChD,cAAM,EAAE,QAAQ,MAAM,IAAI;AAAA,UACxB;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ,IAAI;AAAA,QACd;AACA,cAAM,OAA6B,QAAQ,MACvC,UAAU,QAAQ,GAAG,IACrB;AACJ,cAAM,eAAe,MAAM,SAAS,GAAG,IACnC,MAAM,UAAU,IAChB;AAEJ,cAAM,UAAU,MAAM,OAAO;AAAA,UAC3B;AAAA,UACA,SAAS,QAAQ,YAAY;AAAA,UAC7B,OAAO,QAAQ;AAAA,UACf,QAAQ;AAAA,UACR,IAAI,QAAQ;AAAA,UACZ,SAAS,QAAQ;AAAA,UACjB;AAAA,UACA,aAAa,QAAQ;AAAA,UACrB,GAAG,aAAa,QAAQ,MAAM;AAAA,UAC9B,gBAAgB,aAAa,WAAW,UAAU,QAAQ,IAAI,CAAC;AAAA,UAC/D;AAAA,UACA,YAAY,QAAQ,aAAa,OAAO;AAAA,UACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA,UACjD,SAAS,QAAQ,UAAU,OAAO;AAAA,UAClC,UAAU;AAAA,QACZ,CAAC;AACD,gBAAQ,QAAQ;AAAA,UACd,KAAK;AAGH,oBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,CAAI;AAC5D;AAAA,UACF,KAAK,UAAU;AACb,kBAAM,OAAO,UAAU,SAAS,QAAQ;AAAA,cACtC,OAAO,aAAa,QAAQ,UAAU,OAAO;AAAA,cAC7C,OAAO,QAAQ,QAAQ,KAAK;AAAA,YAC9B,CAAC;AACD,gBAAI,KAAK,SAAS,EAAG,SAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AACrD;AAAA,UACF;AAAA,UACA,SAAS;AACP,kBAAM,cAAqB;AAC3B,kBAAM,IAAI;AAAA,cACR,oBAAoB,KAAK,UAAU,WAAW,CAAC,SAAS,kBAAkB;AAAA,YAC5E;AAAA,UACF;AAAA,QACF;AAKA,gBAAQ,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,MAAS,IAAI,IAAI;AAAA,MACtE,SAAS,KAAK;AACZ,aAAK,GAAG;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEF,UACG,QAAQ,OAAO,EACf,YAAY,yDAAyD,EAGrE,SAAS,SAAS,8DAA8D,EAChF;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EAIC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE;AAAA,IACC;AAAA,IACA,WAAW,cAAc,KAAK,KAAK,CAAC;AAAA,IACpC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,mCAAmC,EACzD,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,8BAA8B,EACvD,OAAO,cAAc,0CAA0C,EAC/D;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC;AAAA,IACC,OACE,QACA,UACA,SACA,YACG;AACH,UAAI;AACF,cAAM,SAAS,QAAQ;AACvB,YAAI,CAAC,cAAc,MAAM,GAAG;AAC1B,gBAAM,IAAI;AAAA,YACR,qBAAqB,MAAM,UAAU,iBAAiB;AAAA,UACxD;AAAA,QACF;AAGA,YAAI,sBAAsB,MAAM,KAAK,CAAC,QAAQ,OAAO;AACnD,gBAAM,IAAI;AAAA,YACR,YAAY,MAAM;AAAA,UACpB;AAAA,QACF;AACA,cAAM,EAAE,KAAK,MAAM,IAAI;AAAA,UACrB;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ,IAAI;AAAA,UACZ,OAAO,QAAQ,OAAO;AAAA,QACxB;AAIA,YAAI,WAAW,SAAS,QAAQ,IAAI;AAClC,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAIA,YAAI,sBAAsB,MAAM,KAAK,QAAQ,IAAI;AAC/C,gBAAM,IAAI;AAAA,YACR,YAAY,MAAM,yIAAoI,MAAM;AAAA,UAC9J;AAAA,QACF;AAGA,YAAI,QAAQ,MAAM,SAAS,KAAK,QAAQ,IAAI;AAC1C,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAKA,YAAI,QAAQ,OAAO,SAAS,KAAK,QAAQ,IAAI;AAC3C,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,cAAM,SAAS,iBAAiB,QAAQ,KAAK;AAC7C,cAAM,OAA6B,QAAQ,MACvC,UAAU,QAAQ,GAAG,IACrB;AACJ,cAAM,eAAe,MAAM,SAAS,KAAK,IACrC,MAAM,UAAU,IAChB;AAMJ,cAAM,SACJ,QAAQ,QAAQ,MAAM,KAAK,QAAQ,QAAQ,KAAK,KAChD,WAAW;AACb,cAAM,MAAM,MAAM,SAAS;AAAA,UACzB;AAAA,UACA,IAAI,QAAQ;AAAA,UACZ;AAAA,UACA,OAAO,QAAQ;AAAA,UACf,GAAI,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,UACnD,GAAI,QAAQ,OAAO,SAAS,IAAI,EAAE,SAAS,QAAQ,OAAO,IAAI,CAAC;AAAA,UAC/D,QAAQ;AAAA,UACR,IAAI,QAAQ;AAAA,UACZ,SAAS,QAAQ;AAAA,UACjB;AAAA,UACA,aAAa,QAAQ;AAAA,UACrB,GAAG,aAAa,QAAQ,MAAM;AAAA,UAC9B,gBAAgB,aAAa,WAAW,UAAU,QAAQ,IAAI,CAAC;AAAA,UAC/D;AAAA,UACA,YAAY,QAAQ,aAAa,OAAO;AAAA,UACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA,UACjD,SAAS,QAAQ,UAAU,OAAO;AAAA,UAClC,UAAU;AAAA;AAAA;AAAA;AAAA,UAIV,SAAS,gBAAgB;AAAA;AAAA;AAAA,UAGzB,aAAa,CAAC,WAAW;AACvB,kBAAM,OAAO,eAAe,QAAQ,UAAU;AAAA,cAC5C,OAAO,WAAW,YAAY,aAAa,QAAQ,UAAU,OAAO;AAAA,YACtE,CAAC;AACD,aAAC,WAAW,WAAW,QAAQ,SAAS,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,UAC3E;AAAA,QACF,CAAC;AAGD,YAAI,IAAI,MAAM,QAAQ,IAAI;AACxB,kBAAQ,OAAO;AAAA,YACb,WAAW,SACP,GAAG,KAAK,UAAU,IAAI,IAAI,MAAM,CAAC,CAAC;AAAA,IAClC,SAAS,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,OAAO;AAAA;AAAA,UACpE;AACA,kBAAQ,WAAW;AACnB;AAAA,QACF;AACA,YAAI,IAAI,IAAI;AACV,iBAAO,SAAS,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,SAAS;AAAA,QACvD;AAIA,YAAI,sBAAsB,MAAM,GAAG;AACjC,8BAAoB,KAAK,MAAM;AAC/B;AAAA,QACF;AACA,gBAAQ,QAAQ;AAAA,UACd,KAAK;AAMH,gBAAI,IAAI,SAAS;AACf,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AACA,oBAAQ,OAAO,MAAM,GAAG,eAAe,GAAG,CAAC;AAAA,CAAI;AAC/C;AAAA,UACF,KAAK;AAIH,oBAAQ,OAAO;AAAA,cACb,GAAG,KAAK,UAAU,IAAI,WAAW,IAAI,MAAM,MAAM,CAAC,CAAC;AAAA;AAAA,YACrD;AACA;AAAA,UACF,KAAK,UAAU;AACb,kBAAM,OAAO,YAAY,KAAK;AAAA,cAC5B,OAAO,aAAa,QAAQ,UAAU,OAAO;AAAA,cAC7C,OAAO,QAAQ,QAAQ,KAAK;AAAA,cAC5B;AAAA,YACF,CAAC;AACD,gBAAI,KAAK,SAAS,EAAG,SAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AACrD;AAAA,UACF;AAAA,UACA,SAAS;AAKP,kBAAM,cAAqB;AAC3B,kBAAM,IAAI;AAAA,cACR,oBAAoB,KAAK,UAAU,WAAW,CAAC,SAAS,iBAAiB;AAAA,YAC3E;AAAA,UACF;AAAA,QACF;AAIA,cAAM,WAAW,IAAI,UAAU,IAAI,QAAQ,SAAS,IAAI,KAAK;AAC7D,gBAAQ,WAAW,QAAQ,SAAS,WAAW,IAAI,IAAI;AAAA,MACzD,SAAS,KAAK;AACZ,aAAK,GAAG;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEF,UACG,QAAQ,MAAM,EACd;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE,OAAO,mBAAmB,gCAAgC,EAC1D,OAAO,oBAAoB,qCAAqC,UAAU,EAC1E,OAAO,aAAa,uCAAuC,EAC3D;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,cAAc,2BAA2B,EAChD,OAAO,WAAW,eAAe,EACjC,OAAO,mBAAmB,wCAAwC,UAAU,EAC5E;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAGC,OAAO,qBAAqB,8BAA8B,UAAU,EACpE;AAAA,IACC;AAAA,IACA,WAAW,aAAa,KAAK,KAAK,CAAC;AAAA,IACnC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,mCAAmC,EACzD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,8BAA8B,EACvD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,OAAO,OAAO,OAAiB,SAAyB,YAAqB;AAC5E,QAAI;AACF,YAAM,SAAS,QAAQ;AACvB,UAAI,CAAC,aAAa,MAAM,GAAG;AACzB,cAAM,IAAI;AAAA,UACR,qBAAqB,MAAM,UAAU,gBAAgB;AAAA,QACvD;AAAA,MACF;AAGA,cAAQ,gBAAgB,QAAQ,YAAY,GAAG,CAAC;AAChD,cAAQ,eAAe,QAAQ,UAAU,GAAG,OAAO,gBAAgB;AACnE;AAAA,QACE;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA,OAAO;AAAA,MACT;AACA,cAAQ,iBAAiB,QAAQ,aAAa,GAAG,EAAE;AAEnD,YAAM,OAA6B,QAAQ,MACvC,UAAU,QAAQ,GAAG,IACrB;AACJ,YAAM,aAAa,MAAM,SAAS,KAAK;AAMvC,UAAI,cAAc,WAAW,UAAU;AACrC,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,YAAM,eAAe,aAAa,MAAM,UAAU,IAAI;AAEtD,YAAM,MAAM,MAAM,QAAQ;AAAA,QACxB,QAAQ;AAAA,QACR,YAAY,QAAQ;AAAA,QACpB;AAAA,QACA,SAAS,QAAQ;AAAA,QACjB,IAAI,QAAQ;AAAA,QACZ,aAAa,QAAQ;AAAA,QACrB,GAAG,aAAa,QAAQ,MAAM;AAAA;AAAA;AAAA,QAG9B,gBAAgB;AAAA,UACd,WAAW,YAAY,CAAC;AAAA,UACxB,QAAQ,IAAI;AAAA,QACd;AAAA,QACA;AAAA,QACA,YAAY,QAAQ,aAAa,OAAO;AAAA,QACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA,QACjD,SAAS,QAAQ,UAAU,OAAO;AAAA,QAClC,UAAU;AAAA,QACV,QAAQ,QAAQ,SAAS,UAAU,QAAQ,MAAM,IAAI;AAAA,QACrD,YAAY,QAAQ;AAAA,QACpB,QAAQ,QAAQ,QAAQ,MAAM;AAAA,QAC9B,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ;AAAA,QACf,OAAO,QAAQ,QAAQ,KAAK;AAAA,QAC5B,UAAU,QAAQ;AAAA,QAClB,YAAY,QAAQ;AAAA,QACpB,aAAa,QAAQ;AAAA,QACrB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKhB,SAAS,aAAa,SAAY,gBAAgB;AAAA;AAAA;AAAA,QAGlD,aAAa,CAAC,WAAW;AACvB,gBAAM,OAAO,eAAe,QAAQ,UAAU;AAAA,YAC5C,OAAO,WAAW,YAAY,aAAa,QAAQ,UAAU,OAAO;AAAA,UACtE,CAAC;AACD,WAAC,WAAW,WAAW,QAAQ,SAAS,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,QAC3E;AAAA,MACF,CAAC;AAED,YAAM,QAAQ,aAAa,QAAQ,UAAU,OAAO;AACpD,YAAM,SAAS,WAAW,QAAQ,KAAK;AAAA,QACrC;AAAA,QACA,OAAO,QAAQ,QAAQ,KAAK;AAAA,MAC9B,CAAC;AACD,UAAI,YAAY;AAEd,cAAM,SAAS,IAAI,QAAQ,CAAC,GAAG;AAC/B,YAAI,UAAU,KAAM,SAAQ,OAAO,MAAM,MAAM;AAC/C,YAAI,OAAO,SAAS,EAAG,SAAQ,OAAO,MAAM,GAAG,MAAM;AAAA,CAAI;AAAA,MAC3D,WAAW,OAAO,SAAS,GAAG;AAC5B,gBAAQ,OAAO,MAAM,GAAG,MAAM;AAAA,CAAI;AAAA,MACpC;AAIA,cAAQ,WACN,IAAI,QAAQ,kBAAkB,KAAK,IAAI,QAAQ,SAAS,IAAI,IAAI;AAAA,IACpE,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,aAAa,4CAA4C,EAChE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA,WAAW,eAAe,KAAK,KAAK,CAAC;AAAA,IACrC;AAAA,EACF,EACC,OAAO,cAAc,0CAA0C,EAC/D,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,mCAAmC,EACzD,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,+BAA+B,EACxD;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,OAAO,OAAO,OAAiB,SAA2B,YAAqB;AAC9E,QAAI;AACF,YAAM,SAAS,QAAQ;AACvB,UAAI,CAAC,eAAe,MAAM,GAAG;AAC3B,cAAM,IAAI;AAAA,UACR,qBAAqB,MAAM,UAAU,kBAAkB;AAAA,QACzD;AAAA,MACF;AAIA,WACG,WAAW,YAAY,WAAW,WAAW,WAAW,YACzD,CAAC,QAAQ,OACT;AACA,cAAM,IAAI;AAAA,UACR,GAAG,MAAM;AAAA,QACX;AAAA,MACF;AACA,YAAM,OAA6B,QAAQ,MACvC,UAAU,QAAQ,GAAG,IACrB;AAEJ,YAAM,MAAM,MAAM,UAAU;AAAA,QAC1B,QAAQ;AAAA,QACR,QAAQ,QAAQ,SAAS,UAAU,QAAQ,MAAM,IAAI;AAAA,QACrD,SAAS,QAAQ,UAAU,UAAU,QAAQ,OAAO,IAAI;AAAA,QACxD,GAAI,QAAQ,gBAAgB,SAAY,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;AAAA,QAChF,QAAQ,QAAQ,QAAQ,MAAM;AAAA,QAC9B,OAAO,QAAQ,QAAQ,KAAK;AAAA,QAC5B,OAAO,QAAQ;AAAA,QACf;AAAA,QACA,SAAS,QAAQ;AAAA,QACjB,IAAI,QAAQ;AAAA,QACZ,aAAa,QAAQ;AAAA,QACrB,GAAG,aAAa,QAAQ,MAAM;AAAA,QAC9B,gBAAgB,aAAa,CAAC,gBAAgB,MAAM,GAAG,QAAQ,IAAI,CAAC;AAAA,QACpE,YAAY,QAAQ,aAAa,OAAO;AAAA,QACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA,QACjD,UAAU;AAAA;AAAA;AAAA;AAAA,QAIV,SAAS,gBAAgB;AAAA;AAAA;AAAA,QAGzB,aAAa,CAAC,WAAW;AACvB,gBAAMC,QAAO,eAAe,QAAQ,UAAU;AAAA,YAC5C,OAAO,WAAW,YAAY,aAAa,QAAQ,UAAU,OAAO;AAAA,UACtE,CAAC;AACD,WAAC,WAAW,WAAW,QAAQ,SAAS,QAAQ,QAAQ,MAAM,GAAGA,KAAI;AAAA,CAAI;AAAA,QAC3E;AAAA,MACF,CAAC;AAED,YAAM,OAAO,aAAa,KAAK,QAAQ;AAAA,QACrC,OAAO,aAAa,QAAQ,UAAU,OAAO;AAAA,QAC7C,OAAO,IAAI;AAAA,QACX,UAAU;AAAA,MACZ,CAAC;AAED,UAAI,KAAK,SAAS,KAAK,CAAC,mBAAmB,IAAI,MAAM,GAAG;AACtD,gBAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,MAClC;AAEA,cAAQ,WAAW,aAAa,GAAG,IAAI,IAAI;AAAA,IAC7C,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,UAAU,EAClB;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,aAAa,0DAA0D,EAC9E;AAAA,IACC;AAAA,IACA,WAAW,iBAAiB,KAAK,KAAK,CAAC;AAAA,IACvC;AAAA,EACF,EACC,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,yEAAyE,EAC/F,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,kCAAkC,EAC3D;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,OAAO,OAAO,OAAiB,SAA6B,YAAqB;AAChF,QAAI;AACF,YAAM,SAAS,QAAQ;AACvB,UAAI,CAAC,iBAAiB,MAAM,GAAG;AAC7B,cAAM,IAAI;AAAA,UACR,kDAAkD,MAAM;AAAA,QAC1D;AAAA,MACF;AACA,YAAM,SAAS,MAAM,YAAY;AAAA,QAC/B,QAAQ;AAAA,QACR,QAAQ,QAAQ,SAAS,UAAU,QAAQ,MAAM,IAAI;AAAA,QACrD,aAAa,QAAQ;AAAA,QACrB,YAAY,QAAQ;AAAA,QACpB,QAAQ,QAAQ,QAAQ,MAAM;AAAA,QAC9B,MAAM,QAAQ,MAAM,UAAU,QAAQ,GAAG,IAAI;AAAA,QAC7C,SAAS,QAAQ;AAAA,QACjB,IAAI,QAAQ;AAAA,QACZ,GAAG,aAAa,QAAQ,MAAM;AAAA,QAC9B,gBAAgB,aAAa,WAAW,UAAU,QAAQ,IAAI,CAAC;AAAA,QAC/D,YAAY,QAAQ,aAAa,OAAO;AAAA,QACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA,QACjD,UAAU;AAAA,MACZ,CAAC;AACD,YAAM,OAAO,eAAe,QAAQ,QAAQ;AAAA,QAC1C,OAAO,aAAa,QAAQ,UAAU,OAAO;AAAA,MAC/C,CAAC;AACD,cAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAEhC,cAAQ,WAAW,eAAe,MAAM,IAAI,IAAI;AAAA,IAClD,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AAKH,QAAM,UAAU,QACb,QAAQ,SAAS,EACjB,YAAY,mDAAmD,EAC/D;AAAA,IACC;AAAA,IACA,WAAW,eAAe,KAAK,KAAK,CAAC;AAAA,IACrC;AAAA,EACF,EACC,OAAO,OAAO,SAA4B,YAAqB;AAC9D,QAAI;AAOF,YAAM,SAAS,mBAAmB,QAAQ,MAAM;AAIhD,UAAI;AACJ,UAAI;AACF,sBAAc,MAAM,WAAW,QAAW,QAAQ,IAAI,CAAC,IAAI,OAAO;AAAA,MACpE,SAAS,KAAK;AACZ,YAAI,EAAE,eAAe,cAAe,OAAM;AAC1C,aAAK,GAAG,IAAI,OAAO,qCAAqC;AAAA,MAC1D;AACA,YAAM,OAAO,eAAe,UAAU;AACtC,UAAI,WAAW,QAAQ;AACrB,gBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,CAAI;AACzD;AAAA,MACF;AACA,YAAM,IAAI,QAAQ,aAAa,QAAQ,UAAU,OAAO,CAAC;AACzD,YAAM,QAAkB,CAAC,EAAE,KAAK,mBAAmB,CAAC;AACpD,iBAAW,KAAK,KAAK,UAAU;AAC7B,cAAM,KAAK,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,QAAG,CAAC,KAAK,EAAE,KAAK,EAAE;AAAA,MAC3D;AACA,UAAI,KAAK,WAAW,SAAS,GAAG;AAC9B,cAAM,KAAK,IAAI,EAAE,KAAK,qBAAqB,CAAC;AAC5C,mBAAW,KAAK,KAAK,YAAY;AAC/B,gBAAM,KAAK,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,QAAG,CAAC,KAAK,EAAE,IAAI,EAAE;AAAA,QAC1D;AAAA,MACF;AACA,YAAM,KAAK,IAAI,EAAE,KAAK,gBAAgB,CAAC;AACvC,iBAAW,KAAK,KAAK,SAAS;AAC5B,cAAM,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,IAAI,EAAE,IAAI,WAAW;AAChE,cAAM,KAAK,KAAK,EAAE,IAAI,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,OAAO,GAAG,GAAG;AAAA,MACjE;AACA,cAAQ,OAAO,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,IAC9C,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,OAAO,EACf;AAAA,IACC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,gBAAgB,6BAA6B,EAIpD;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC,OAAO,gBAAgB,gDAAgD,EACvE,OAAO,oBAAoB,+BAA+B,SAAS,CAAC,CAAC,EACrE,OAAO,iBAAiB,4CAA4C,EACpE;AAAA,IACC;AAAA,IACA,WAAW,eAAe,KAAK,KAAK,CAAC;AAAA,IACrC;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC;AAAA,EACH,EACC,OAAO,uBAAuB,6BAA6B,EAC3D,OAAO,eAAe,mCAAmC,EACzD,OAAO,iBAAiB,qCAAqC,EAC7D,OAAO,kBAAkB,8BAA8B,EACvD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,OAAO,OAAO,OAAiB,SAA0B,YAAqB;AAC7E,QAAI;AACF,YAAM,SAAS,mBAAmB,UAAU,SAAS,QAAQ,MAAM,CAAC;AACpE,cAAQ,kBAAkB,QAAQ,aAAa,GAAG,GAAG;AACrD,YAAM,OAA6B,QAAQ,MACvC,UAAU,QAAQ,GAAG,IACrB;AACJ,YAAM,eAAe,MAAM,SAAS,KAAK,IACrC,MAAM,UAAU,IAChB;AAEJ,YAAM,SAAS,MAAM,eAAe;AAAA,QAClC,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,QAAQ;AAAA,QACjB,IAAI,QAAQ;AAAA,QACZ,aAAa,QAAQ;AAAA,QACrB,GAAG,aAAa,QAAQ,MAAM;AAAA,QAC9B,gBAAgB,aAAa,WAAW,UAAU,QAAQ,IAAI,CAAC;AAAA,QAC/D;AAAA,QACA,KAAK,QAAQ;AAAA,QACb,aAAa,QAAQ;AAAA;AAAA;AAAA;AAAA,QAIrB,YAAY,QAAQ,aAAa,OAAO;AAAA,QACxC,kBAAkB,cAAc,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,QAIjD,SAAS,QAAQ,UAAU,OAAO;AAAA,QAClC,UAAU;AAAA,MACZ,CAAC;AAED,UAAI,WAAW,QAAQ;AACrB,gBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,CAAI;AAC3D;AAAA,MACF;AACA,YAAM,OAAO,YAAY,QAAQ;AAAA,QAC/B,OAAO,aAAa,QAAQ,QAAQ,UAAU,OAAO;AAAA,MACvD,CAAC;AACD,cAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAAA,IAClC,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB;AAAA,IACC;AAAA,EACF,EACC,SAAS,SAAS,qCAAqC,EACvD;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,EACF,EACC,OAAO,uBAAuB,6BAA6B,EAC3D;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,OAAO,OAAO,KAAa,YAA8B;AACxD,QAAI;AACF,YAAM,SAAS,MAAM,gBAAgB;AAAA,QACnC;AAAA,QACA,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQb,GAAI,OAAO,QAAQ,WAAW,WAC1B,EAAE,YAAY,QAAQ,OAAO,IAC7B,CAAC;AAAA,QACL,UAAU;AAAA,MACZ,CAAC;AAKD,YAAM,aAAa,OAAO,gBACtB,YACA,OAAO,WACL,sBACA;AACN,cAAQ,OAAO;AAAA,QACb;AAAA,UACE,YAAY,OAAO,GAAG;AAAA,UACtB,gBAAgB,OAAO,IAAI,KAAK,OAAO,KAAK,SAAS,OAAO,YAAY,gBAAgB,EAAE;AAAA,UAC1F,gBAAgB,OAAO,SAAS;AAAA,UAChC,gBAAgB,OAAO,MAAM,KAAK,UAAU;AAAA,UAC5C;AAAA,UACA,UAAU,OAAO,IAAI,QAAQ,OAAO,MAAM;AAAA,QAC5C,EAAE,KAAK,IAAI,IAAI;AAAA,MACjB;AAAA,IACF,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AAEH,SAAO;AACT;","names":["notice","text"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shared/encryption.ts","../src/shared/collections.ts","../src/shared/globs.ts","../src/shared/page-manifest.ts","../src/shared/tools.ts","../src/shared/config-file.ts","../src/shared/git-root.ts"],"sourcesContent":["/**\n * The family's value encryption (proposal 0045).\n *\n * One ciphertext format for every tool: meta frontmatter values and cite\n * source paths encrypt the same way, under different contexts, so rotation\n * has one rule. Pure, and `node:crypto` only.\n *\n * The construction is SIV-style on AES-256-GCM, because Node has no SIV mode\n * (`aes-256-gcm-siv` and `aes-*-siv` are unknown ciphers in Node 24):\n *\n * - Three 32-byte subkeys come from the configured key with HKDF-SHA256 and an\n * empty salt, labelled `manni/v1/encrypt`, `manni/v1/nonce` and\n * `manni/v1/pin`. The key is expanded, not stretched: a hand-picked value is\n * only as strong as it is random, which is why `manni key set` generates 256\n * bits.\n * - The plaintext is the value's JSON, padded ISO/IEC 7816-4 style (`0x80`,\n * then `0x00` up to the next multiple of 32, always at least one pad byte),\n * so a token's length reveals a size class, not the value.\n * - The nonce is the first 12 bytes of `HMAC(nonceKey, context ‖ 0x00 ‖\n * padded)`. Equal plaintexts give equal tokens, which is what a join needs;\n * decryption checks the nonce is that HMAC, so every valid token is\n * canonical.\n * - The associated data is `0x01 ‖ context`, so the same text in two contexts\n * never reuses a nonce under different tags. The property name is not\n * bound: a value moved between fields stays readable.\n *\n * A token is `~` then unpadded base64url of `0x01 ‖ nonce ‖ ciphertext ‖\n * tag`: 61 bytes at the smallest, so 82 characters after the `~`.\n */\nimport {\n createCipheriv,\n createDecipheriv,\n createHmac,\n hkdfSync,\n randomBytes,\n timingSafeEqual,\n} from \"node:crypto\";\nimport { TextDecoder } from \"node:util\";\n\n/** Which kind of value a token holds. Bound as associated data. */\nexport type EncryptionContext = \"meta\" | \"cite-src\";\n\n/** An encrypted value: `~` and at least 82 base64url characters. */\nexport const ENCRYPTED_VALUE = /^~[A-Za-z0-9_-]{82,}$/;\n\n/** Whether `value` is shaped like a token. Says nothing about which key. */\nexport function isEncryptedValue(value: unknown): value is string {\n return typeof value === \"string\" && ENCRYPTED_VALUE.test(value);\n}\n\n/** A configured key: hex or base64url, at least 32 characters. */\nexport const ENCRYPTION_KEY_SHAPE = /^[A-Za-z0-9_-]{32,}$/;\n\nexport function isValidEncryptionKey(value: unknown): value is string {\n return typeof value === \"string\" && ENCRYPTION_KEY_SHAPE.test(value);\n}\n\n/** 256 random bits as 64 lowercase hex characters. */\nexport function generateEncryptionKey(): string {\n return randomBytes(32).toString(\"hex\");\n}\n\nconst VERSION = 0x01;\nconst NONCE_BYTES = 12;\nconst TAG_BYTES = 16;\nconst BLOCK = 32;\n/** Version byte, nonce, one padded block, tag. */\nconst MIN_BYTES = 1 + NONCE_BYTES + BLOCK + TAG_BYTES;\n\ninterface Subkeys {\n encrypt: Buffer;\n nonce: Buffer;\n pin: Buffer;\n}\n\n/**\n * Subkeys per configured key. A run sees one key, or two while rotating, so\n * the cache stays tiny; it saves three HKDF calls per value on a large tree.\n */\nconst subkeyCache = new Map<string, Subkeys>();\n\nfunction subkeys(key: string): Subkeys {\n const cached = subkeyCache.get(key);\n if (cached !== undefined) return cached;\n const ikm = Buffer.from(key, \"utf8\");\n const derive = (info: string): Buffer =>\n Buffer.from(hkdfSync(\"sha256\", ikm, Buffer.alloc(0), info, 32));\n const made: Subkeys = {\n encrypt: derive(\"manni/v1/encrypt\"),\n nonce: derive(\"manni/v1/nonce\"),\n pin: derive(\"manni/v1/pin\"),\n };\n subkeyCache.set(key, made);\n return made;\n}\n\nfunction requireKey(key: string, caller: string): void {\n if (!isValidEncryptionKey(key)) {\n // Never echo the value: it is key material.\n throw new Error(\n `${caller}: the key must be at least 32 hex or base64url characters.`,\n );\n }\n}\n\nfunction pad(data: Buffer): Buffer {\n const out = Buffer.alloc((Math.floor(data.length / BLOCK) + 1) * BLOCK);\n data.copy(out);\n out[data.length] = 0x80;\n return out;\n}\n\n/** The data before the padding, or `null` when the padding is not canonical. */\nfunction unpad(padded: Buffer): Buffer | null {\n let i = padded.length - 1;\n while (i >= 0 && padded[i] === 0) i--;\n if (i < 0 || padded[i] !== 0x80) return null;\n // Exactly the padding `pad` would have added: never a spare block.\n if (padded.length !== (Math.floor(i / BLOCK) + 1) * BLOCK) return null;\n return padded.subarray(0, i);\n}\n\nfunction nonceFor(keys: Subkeys, context: Buffer, padded: Buffer): Buffer {\n return createHmac(\"sha256\", keys.nonce)\n .update(context)\n .update(Buffer.from([0x00]))\n .update(padded)\n .digest()\n .subarray(0, NONCE_BYTES);\n}\n\nfunction aad(context: Buffer): Buffer {\n return Buffer.concat([Buffer.from([VERSION]), context]);\n}\n\n/**\n * Encrypt any JSON value. Throws for a value that is not JSON (`undefined`, a\n * function) and for a key that is not key-shaped: both are programming\n * errors, since keys arrive through `resolveEncryptionKey`.\n */\nexport function encryptValue(\n value: unknown,\n key: string,\n context: EncryptionContext,\n): string {\n requireKey(key, \"encryptValue\");\n // lib.d.ts types the result as `string`, but `undefined`, a function or a\n // symbol stringify to `undefined` at run time.\n const json = JSON.stringify(value) as string | undefined;\n if (json === undefined) {\n throw new TypeError(\"encryptValue: the value is not JSON.\");\n }\n const keys = subkeys(key);\n const ctx = Buffer.from(context, \"utf8\");\n const padded = pad(Buffer.from(json, \"utf8\"));\n const nonce = nonceFor(keys, ctx, padded);\n const cipher = createCipheriv(\"aes-256-gcm\", keys.encrypt, nonce, {\n authTagLength: TAG_BYTES,\n });\n cipher.setAAD(aad(ctx));\n const sealed = Buffer.concat([cipher.update(padded), cipher.final()]);\n const tag = cipher.getAuthTag();\n const bytes = Buffer.concat([Buffer.from([VERSION]), nonce, sealed, tag]);\n return `~${bytes.toString(\"base64url\")}`;\n}\n\nconst FAILED = { ok: false } as const;\n\n/**\n * Decrypt a token. `{ ok: false }` for anything that is not a canonical token\n * under this key and context; never throws.\n */\nexport function decryptValue(\n token: string,\n key: string,\n context: EncryptionContext,\n): { ok: true; value: unknown } | { ok: false } {\n try {\n return open(token, key, context);\n } catch {\n return FAILED;\n }\n}\n\nfunction open(\n token: string,\n key: string,\n context: EncryptionContext,\n): { ok: true; value: unknown } | { ok: false } {\n if (!isEncryptedValue(token) || !isValidEncryptionKey(key)) return FAILED;\n const body = token.slice(1);\n const bytes = Buffer.from(body, \"base64url\");\n // Buffer's decoder ignores stray trailing bits; a token is canonical only\n // if it is exactly what the encoder writes for these bytes.\n if (bytes.toString(\"base64url\") !== body) return FAILED;\n if (bytes.length < MIN_BYTES) return FAILED;\n if ((bytes.length - 1 - NONCE_BYTES - TAG_BYTES) % BLOCK !== 0) return FAILED;\n if (bytes[0] !== VERSION) return FAILED;\n\n const nonce = bytes.subarray(1, 1 + NONCE_BYTES);\n const sealed = bytes.subarray(1 + NONCE_BYTES, bytes.length - TAG_BYTES);\n const tag = bytes.subarray(bytes.length - TAG_BYTES);\n const keys = subkeys(key);\n const ctx = Buffer.from(context, \"utf8\");\n const decipher = createDecipheriv(\"aes-256-gcm\", keys.encrypt, nonce, {\n authTagLength: TAG_BYTES,\n });\n decipher.setAAD(aad(ctx));\n decipher.setAuthTag(tag);\n // `final` throws on a bad tag; the caller turns that into `{ ok: false }`.\n const padded = Buffer.concat([decipher.update(sealed), decipher.final()]);\n\n if (!timingSafeEqual(nonceFor(keys, ctx, padded), nonce)) return FAILED;\n const data = unpad(padded);\n if (data === null) return FAILED;\n const json = new TextDecoder(\"utf-8\", { fatal: true }).decode(data);\n const value: unknown = JSON.parse(json);\n return { ok: true, value };\n}\n\n/** The prefix a keyed pin carries, so it never reads as a plain hash of the text. */\nexport const KEYED_PIN_PREFIX = \"hmac-sha256-\";\n\n/**\n * A keyed fingerprint of `text`: `hmac-sha256-` and the hex HMAC-SHA256 under\n * the pin subkey. Stable per key, so it can be compared without being\n * reversible. The prefix says it is an HMAC: hashing the text by hand gives\n * a different value, and the prefix is why.\n */\nexport function keyedPin(text: string, key: string): string {\n requireKey(key, \"keyedPin\");\n const mac = createHmac(\"sha256\", subkeys(key).pin)\n .update(text, \"utf8\")\n .digest(\"hex\");\n return `${KEYED_PIN_PREFIX}${mac}`;\n}\n","/**\n * `collections:`, the family-level home for document sets (proposal 0041).\n *\n * A collection names a set of documents once, at the top level of\n * `manni.config.yaml`, and every tool reads the same declaration: the metadata\n * tool validates its members, `query` exposes it as a view, and `a11y check`\n * seeds from its `url`. Only the *declaration* is shared. Loading a manifest\n * and merging it into `ExtractedMetadata` stays with the metadata tool,\n * because that type is the metadata tool's.\n *\n * Every refusal in this parser is a shape that would otherwise read as\n * configured and do nothing, or do something nobody can see. The manifest\n * rules are 0037's, moved here unchanged in substance: an entry with an empty\n * `keys` list owns nothing, one key under two manifests of a collection would need a\n * tiebreak (0020 refuses tiebreaks), and `$schema` from external metadata\n * would let a private file pick the schema a public document is judged by\n * (0015) with the provenance lost at the merge.\n */\nimport picomatch from \"picomatch\";\nimport { matchesFileGlob } from \"./globs.js\";\nimport { posix, win32 } from \"node:path\";\nimport {\n PAGE_PLACEHOLDER,\n hasPagePlaceholder,\n normalizeManifestPattern,\n} from \"./page-manifest.js\";\n\n/** One external-metadata manifest (proposals 0037, 0038, 0039) joined to a collection. */\nexport interface ExternalMetadataConfig {\n file: string;\n /**\n * The top-level keys the manifest owns. Absent (proposal 0068), it owns\n * what each page's schemas mark `x-manni-location: external`, as `ownsKey`\n * decides.\n */\n keys?: string[];\n tokenEnv?: string;\n join?: string;\n}\n\n/** One named document set, as declared under the top-level `collections:` key. */\nexport interface CollectionConfig {\n name: string;\n paths: string[];\n exclude: string[];\n externalMetadata: ExternalMetadataConfig[];\n /** Where the collection is published; `manni a11y check` seeds from it. */\n url?: string;\n}\n\nconst COLLECTION_KEYS = [\n \"name\",\n \"paths\",\n \"exclude\",\n \"url\",\n \"externalMetadata\",\n] as const;\n\nconst EXTERNAL_METADATA_KEYS = [\"file\", \"keys\", \"tokenEnv\", \"join\"] as const;\n\n/**\n * The join that names documents by path, and the default. The metadata tool\n * spells it `PATH_JOIN` in `src/meta/core/external-metadata.ts`; the literal\n * is repeated here for the same reason as `SCHEMA_KEY` below.\n */\nconst PATH_JOIN = \"path\";\n\n/**\n * The document-level schema key. The metadata tool spells it\n * `FILE_SCHEMA_KEY` in `src/meta/core/resolve-schema.ts`; the literal is\n * repeated here so the shared layer does not import a tool's module. Keep the\n * two in step.\n */\nconst SCHEMA_KEY = \"$schema\";\n\n/**\n * The label `load-files.ts` gives stdin (`STDIN_LABEL`). Repeated as a literal\n * for the same reason as `SCHEMA_KEY`: the shared layer does not depend on the\n * metadata tool. Stdin has no path, so it is a member of nothing.\n */\nconst STDIN = \"<stdin>\";\n\n/** Is this manifest reference a URL? The `url` branch of `classifyRef`. */\nfunction isUrlRef(ref: string): boolean {\n return /^https?:\\/\\//i.test(ref);\n}\n\n/**\n * Whether a URL may name an external-metadata manifest: `https://` anywhere,\n * or `http://` on a loopback host only, where plaintext leaks nothing.\n * Userinfo is refused because the URL is printed in every diagnostic and a\n * secret in it would print too. Returns the reason it may not, or `null`.\n */\nexport function externalMetadataUrlProblem(url: string): string | null {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return \"is not a valid URL\";\n }\n if (parsed.username !== \"\" || parsed.password !== \"\") {\n return 'carries a credential in the URL; put the token in an environment variable and name it with \"tokenEnv\"';\n }\n if (parsed.protocol === \"https:\") return null;\n if (parsed.protocol === \"http:\" && isLoopback(parsed.hostname)) return null;\n if (parsed.protocol === \"http:\") {\n return \"is plain http://; a bearer token over plaintext is a leak, and a public manifest is served over https too\";\n }\n return `has the unsupported scheme \"${parsed.protocol}\"`;\n}\n\nfunction isLoopback(host: string): boolean {\n return (\n host === \"localhost\" ||\n host === \"127.0.0.1\" ||\n host === \"[::1]\" ||\n host === \"::1\" ||\n host.startsWith(\"127.\")\n );\n}\n\nfunction rejectUnknownKeys(\n raw: Record<string, unknown>,\n allowed: readonly string[],\n where: string,\n source: string,\n toError: (message: string) => Error,\n): void {\n for (const key of Object.keys(raw)) {\n if (!allowed.includes(key)) {\n throw toError(\n `${source}: ${where} has unknown key \"${key}\". Supported keys: ${allowed.join(\", \")}.`,\n );\n }\n }\n}\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\n/**\n * Parse the top-level `collections:` value. Errors are built with `toError`,\n * so each tool reports a bad family file in its own error class.\n */\nexport function parseCollections(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): CollectionConfig[] {\n if (!Array.isArray(raw)) {\n throw toError(`${source}: \"collections\" must be a list.`);\n }\n if (raw.length === 0) {\n throw toError(\n `${source}: \"collections\" must name at least one collection; remove the key if there are none.`,\n );\n }\n // Names become SQL view names, and SQLite compares identifiers without\n // regard to case, so two names that differ only in case are one view.\n const taken = new Map<string, number>();\n return raw.map((entry, i) => {\n const where = `collections[${i}]`;\n if (!isMapping(entry)) {\n throw toError(`${source}: ${where} must be a mapping.`);\n }\n rejectUnknownKeys(entry, COLLECTION_KEYS, where, source, toError);\n\n if (!isNonEmptyString(entry.name)) {\n throw toError(`${source}: ${where}.name must be a non-empty string.`);\n }\n const name = entry.name;\n const folded = name.toLowerCase();\n if (folded === \"docs\") {\n throw toError(\n `${source}: ${where}.name \"${name}\" collides with the docs table every query reads. Pick another name, such as \"site\" or \"pages\".`,\n );\n }\n // The derived table (proposal 0040) is a view named `derived` over a\n // backing table named `_derived_rows`, built beside `docs` when a\n // statement asks for it, and `resolved` (proposal 0043) is the view over\n // `docs` and those rows. Any of the three would shadow it the same way.\n if (folded === \"derived\" || folded === \"_derived_rows\" || folded === \"resolved\") {\n throw toError(\n `${source}: ${where}.name \"${name}\" collides with the derived table a query builds beside docs (the derived view, its _derived_rows table, and the resolved view over both). Pick another name.`,\n );\n }\n if (folded.startsWith(\"sqlite_\")) {\n throw toError(\n `${source}: ${where}.name \"${name}\" starts with \"sqlite_\", which SQLite reserves for its own objects. Pick another name.`,\n );\n }\n const owner = taken.get(folded);\n if (owner !== undefined) {\n throw toError(\n `${source}: ${where}.name \"${name}\" is already taken by collections[${owner}]; names are compared case-insensitively because they become SQL views.`,\n );\n }\n taken.set(folded, i);\n\n if (\n !Array.isArray(entry.paths) ||\n entry.paths.length === 0 ||\n entry.paths.some((p) => !isNonEmptyString(p))\n ) {\n throw toError(\n `${source}: ${where}.paths must be a non-empty list of files, directories or globs.`,\n );\n }\n const paths = entry.paths as string[];\n\n let exclude: string[] = [];\n if (entry.exclude !== undefined) {\n if (\n !Array.isArray(entry.exclude) ||\n entry.exclude.some((g) => !isNonEmptyString(g))\n ) {\n throw toError(`${source}: ${where}.exclude must be a list of globs.`);\n }\n exclude = entry.exclude as string[];\n }\n\n let url: string | undefined;\n if (entry.url !== undefined) {\n if (typeof entry.url !== \"string\" || !isHttpUrl(entry.url)) {\n throw toError(`${source}: ${where}.url must be an http(s) URL.`);\n }\n url = entry.url;\n }\n\n let externalMetadata: ExternalMetadataConfig[] = [];\n if (entry.externalMetadata !== undefined) {\n if (!Array.isArray(entry.externalMetadata)) {\n throw toError(`${source}: ${where}.externalMetadata must be a list.`);\n }\n externalMetadata = parseExternalMetadata(\n entry.externalMetadata,\n where,\n source,\n toError,\n );\n }\n\n return {\n name,\n paths,\n exclude,\n externalMetadata,\n ...(url === undefined ? {} : { url }),\n };\n });\n}\n\nfunction isHttpUrl(value: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return false;\n }\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n}\n\n/**\n * Parse one collection's `externalMetadata:`. 0037's rules, with the error\n * path rewritten and the noun changed: ownership is now disjoint within a\n * collection rather than across the whole config, because two collections may\n * each own the same key.\n */\nfunction parseExternalMetadata(\n raw: readonly unknown[],\n collectionWhere: string,\n source: string,\n toError: (message: string) => Error,\n): ExternalMetadataConfig[] {\n const owners = new Map<string, number>();\n const patterns = new Map<string, number>();\n /** The one entry that omits `keys` (proposal 0068), once one does. */\n let keyless: number | undefined;\n const parsedEntries = raw.map((entry, i): ExternalMetadataConfig => {\n const where = `${collectionWhere}.externalMetadata[${i}]`;\n if (!isMapping(entry)) {\n throw toError(`${source}: ${where} must be a mapping.`);\n }\n rejectUnknownKeys(entry, EXTERNAL_METADATA_KEYS, where, source, toError);\n if (!isNonEmptyString(entry.file)) {\n throw toError(\n `${source}: ${where}.file must be a non-empty string naming the manifest, relative to the config file.`,\n );\n }\n const placeholderProblem = pagePlaceholderProblem(entry.file);\n if (placeholderProblem !== null) {\n throw toError(`${source}: ${where}.file ${placeholderProblem}`);\n }\n const perPage = hasPagePlaceholder(entry.file);\n if (perPage && (posix.isAbsolute(entry.file) || win32.isAbsolute(entry.file))) {\n throw toError(\n `${source}: ${where}.file uses ${PAGE_PLACEHOLDER} in an absolute path, so every manifest would sit outside the repository. Make it relative to the config file.`,\n );\n }\n // Absent keys (proposal 0068) is an ownership rule, not an empty list:\n // the manifest owns what each page's schemas mark external. Written, the\n // list still has to name something.\n if (\n entry.keys !== undefined &&\n (!Array.isArray(entry.keys) ||\n entry.keys.length === 0 ||\n entry.keys.some((k) => !isNonEmptyString(k)))\n ) {\n throw toError(\n `${source}: ${where}.keys must be a non-empty list of key names.`,\n );\n }\n if (entry.keys === undefined) {\n if (keyless !== undefined) {\n throw toError(\n `${source}: ${collectionWhere}.externalMetadata: entries ${String(keyless)} and ${String(i)} both omit keys; at most one manifest may own the external-marked fields`,\n );\n }\n keyless = i;\n }\n const isUrl = isUrlRef(entry.file);\n if (isUrl) {\n const problem = externalMetadataUrlProblem(entry.file);\n if (problem !== null) {\n throw toError(`${source}: ${where}.file ${problem}.`);\n }\n if (perPage) {\n throw toError(\n `${source}: ${where}.file uses ${PAGE_PLACEHOLDER} in a URL. A placeholder names a file this run can write, and a URL is not one.`,\n );\n }\n }\n if (entry.tokenEnv !== undefined) {\n if (!isNonEmptyString(entry.tokenEnv)) {\n throw toError(\n `${source}: ${where}.tokenEnv must be the name of an environment variable.`,\n );\n }\n if (!isUrl) {\n throw toError(\n `${source}: ${where}.tokenEnv is set, but \"file\" is a path, so no request is made and the token would go nowhere. Remove it, or make \"file\" a URL.`,\n );\n }\n }\n const keys = entry.keys === undefined ? undefined : (entry.keys as string[]);\n if (entry.join !== undefined) {\n if (!isNonEmptyString(entry.join)) {\n throw toError(\n `${source}: ${where}.join must be \"path\" or the name of a top-level frontmatter field.`,\n );\n }\n if (entry.join === SCHEMA_KEY) {\n throw toError(`${source}: ${where}.join may not be \"${SCHEMA_KEY}\".`);\n }\n if (keys?.includes(entry.join) === true) {\n throw toError(\n `${source}: ${where}.join names \"${entry.join}\", which the same entry owns — the value that selects an entry cannot come from the entry.`,\n );\n }\n }\n // An explicit `join: path` is the default spelled out, and a per-page\n // manifest is found by that path. A field would name the file by one\n // thing and key its entry by another (0058 § 6).\n if (perPage && typeof entry.join === \"string\" && entry.join !== PATH_JOIN) {\n throw toError(\n `${source}: ${where}.file uses ${PAGE_PLACEHOLDER}, and join is \"${entry.join}\". A per-page manifest is found by path, so it cannot be keyed by a field. Remove ${PAGE_PLACEHOLDER}, or remove join.`,\n );\n }\n const seen = new Set<string>();\n for (const key of keys ?? []) {\n if (key === SCHEMA_KEY) {\n throw toError(\n `${source}: ${where}.keys may not include \"${SCHEMA_KEY}\" — a manifest never chooses the schema a document is judged by; use \"overrides\".`,\n );\n }\n if (seen.has(key)) {\n throw toError(`${source}: ${where}.keys lists \"${key}\" twice.`);\n }\n seen.add(key);\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw toError(\n `${source}: ${where}.keys claims \"${key}\", which externalMetadata[${owner}] already owns — a key has exactly one manifest in a collection.`,\n );\n }\n owners.set(key, i);\n }\n // Two spellings of one pattern are one manifest for every page (0058\n // stress test 10), compared once, with no page known yet. Two concrete\n // entries naming one file stay legal, as they were before placeholders.\n if (perPage) {\n const pattern = normalizeManifestPattern(entry.file);\n const first = patterns.get(pattern);\n if (first !== undefined) {\n throw toError(\n `${source}: ${where}.file resolves to the same manifest as externalMetadata[${String(first)}].file for every page. Give each entry its own file name.`,\n );\n }\n patterns.set(pattern, i);\n }\n const parsed: ExternalMetadataConfig = {\n file: entry.file,\n ...(keys === undefined ? {} : { keys }),\n ...(typeof entry.tokenEnv === \"string\" ? { tokenEnv: entry.tokenEnv } : {}),\n ...(typeof entry.join === \"string\" ? { join: entry.join } : {}),\n };\n origins.set(parsed, { source, where });\n return parsed;\n });\n // What each keyless manifest can never own, fixed here against the whole\n // declaration. A caller that narrows a collection to some of its manifests\n // still gets the answer the full collection gives.\n for (const manifest of parsedEntries) {\n if (manifest.keys === undefined) declaredNever.set(manifest, neverOwnedIn(parsedEntries, manifest));\n }\n return parsedEntries;\n}\n\n/**\n * The problem with `file`'s `{page}` placeholder grammar (0058 § 1), as the\n * tail of a sentence that starts with the entry's path, or `null` when there\n * is none. One token, spelled exactly, at most once; every other brace is\n * refused rather than read as a literal.\n */\nfunction pagePlaceholderProblem(file: string): string | null {\n for (const match of file.matchAll(/\\{[^{}]*\\}/g)) {\n if (match[0] !== PAGE_PLACEHOLDER) {\n return `uses \"${match[0]}\", which is not a placeholder. The only placeholder is ${PAGE_PLACEHOLDER}.`;\n }\n }\n const tokens = file.split(PAGE_PLACEHOLDER);\n const stray = /[{}]/.exec(tokens.join(\"\"));\n if (stray !== null) {\n return `contains \"${stray[0]}\" outside a ${PAGE_PLACEHOLDER} placeholder. Remove it, or write ${PAGE_PLACEHOLDER}.`;\n }\n if (tokens.length > 2) {\n return `uses ${PAGE_PLACEHOLDER} twice. One manifest names one page.`;\n }\n return null;\n}\n\n/**\n * Where a parsed `externalMetadata:` entry was declared: the config file as\n * the parse was told to name it, and the entry's\n * `collections[c].externalMetadata[i]` path. Kept beside the entry rather\n * than on it, so the entry's shape, its equality, and anything that\n * serializes it stay what they were. A copy made with a spread has no origin.\n */\nconst origins = new WeakMap<ExternalMetadataConfig, { source: string; where: string }>();\n\n/**\n * The config file and path an entry was parsed from, for a refusal that is\n * known only once a page is: a `{page}` manifest resolving above the config\n * directory. `undefined` for an entry `parseCollections` did not build.\n */\nexport function externalMetadataOrigin(\n entry: ExternalMetadataConfig,\n): { source: string; where: string } | undefined {\n return origins.get(entry);\n}\n\n/**\n * Does `manifest`, one of `collection`'s, own `key` for one page? The one\n * answer every reader and writer asks for (proposal 0068).\n *\n * A manifest with `keys` owns exactly those, for every page. One without owns\n * what `marked` holds: the top-level keys the page's resolved schema set marks\n * `x-manni-location: external`. It never owns a key another manifest of the\n * collection names in its own `keys`, because written keys win. Nor its own\n * join field, which the page carries to name its entry, nor `$schema`. With\n * `marked` undefined, because the page's schemas are not known, a keyless\n * manifest owns nothing.\n */\nexport function ownsKey(\n collection: Pick<CollectionConfig, \"externalMetadata\">,\n manifest: ExternalMetadataConfig,\n key: string,\n marked: ReadonlySet<string> | undefined,\n): boolean {\n if (manifest.keys !== undefined) return manifest.keys.includes(key);\n if (marked === undefined || !marked.has(key)) return false;\n return !neverOwned(collection, manifest).has(key);\n}\n\n/**\n * The keys a keyless manifest never owns, whatever a page marks: the keys\n * the collection's other manifests name, its join field, and `$schema`. An\n * entry setting one of them is refused when the manifest is read.\n */\nexport function neverOwned(\n collection: Pick<CollectionConfig, \"externalMetadata\">,\n manifest: ExternalMetadataConfig,\n): ReadonlySet<string> {\n return declaredNever.get(manifest) ?? neverOwnedIn(collection.externalMetadata, manifest);\n}\n\nfunction neverOwnedIn(\n manifests: readonly ExternalMetadataConfig[],\n manifest: ExternalMetadataConfig,\n): Set<string> {\n const out = new Set<string>([SCHEMA_KEY]);\n if (manifest.join !== undefined && manifest.join !== PATH_JOIN) out.add(manifest.join);\n for (const other of manifests) {\n if (other === manifest) continue;\n for (const key of other.keys ?? []) out.add(key);\n }\n return out;\n}\n\n/**\n * `neverOwned` for each keyless manifest `parseCollections` built, computed\n * over its whole collection. Kept beside the entry, as `origins` is, so a\n * copy of the collection filtered to some of its manifests does not forget a\n * key a manifest it left out names.\n */\nconst declaredNever = new WeakMap<ExternalMetadataConfig, ReadonlySet<string>>();\n\n/**\n * The collections a run covers: every one when `names` is undefined, else the\n * named ones in **declaration** order, however they were named on the command\n * line. Repeats collapse; an unknown name is an error, because a typo that\n * silently narrowed the run to nothing would read as a clean pass.\n */\nexport function selectCollections(\n collections: readonly CollectionConfig[],\n names: readonly string[] | undefined,\n source: string,\n toError: (message: string) => Error,\n): CollectionConfig[] {\n // An empty list means the same as no list: every collection. Commander's\n // repeatable-option collector defaults to `[]`, so \"the user passed no\n // --collection\" reaches this function as an empty array at least as often as\n // it reaches it as `undefined`. Were `[]` to select nothing, a plain\n // `manni meta validate` would validate zero files and exit 0 the moment a\n // caller forwarded the raw commander value — the false green proposal 0014\n // exists to end, and invisible in the exit code. Nothing needs to express\n // \"select no collections\", so the ambiguity is resolved in the safe\n // direction. Do not tighten this back.\n if (names === undefined || names.length === 0) return [...collections];\n const wanted = new Set(names);\n for (const name of wanted) {\n if (!collections.some((c) => c.name === name)) {\n const configured =\n collections.length === 0\n ? \"(none)\"\n : collections.map((c) => c.name).join(\", \");\n // Names are unique case-insensitively (they become SQL views) but are\n // selected by their one spelling. When the miss is only a casing miss,\n // say so — \"Configured: guides\" beside \"Guides\" reads as a contradiction\n // to anyone who does not already know the rule.\n const nearMiss = collections.find(\n (c) => c.name.toLowerCase() === name.toLowerCase(),\n );\n const hint =\n nearMiss === undefined\n ? \"\"\n : ` Names are case-sensitive; did you mean \"${nearMiss.name}\"?`;\n throw toError(\n `no collection named \"${name}\" in ${source}. Configured: ${configured}.${hint}`,\n );\n }\n }\n return collections.filter((c) => wanted.has(c.name));\n}\n\n/**\n * Is this file a member of the collection? `relPath` is posix and already\n * relative to the config file's directory, so this is arithmetic on a string:\n * no `stat`, nothing that can fail, and nothing that costs per file. A path\n * that climbed out of the config directory, and stdin, are members of nothing.\n */\nexport function isMember(\n collection: CollectionConfig,\n relPath: string,\n): boolean {\n if (relPath === STDIN) return false;\n if (relPath.startsWith(\"../\")) return false;\n return matchesCollectionPaths(collection, relPath);\n}\n\n/**\n * Do the collection's `paths:` and `exclude:` claim this path, before the two\n * guards `isMember` adds? Only a caller that has to *say* why a claimed path\n * is not a member needs this: a page above the config directory that a\n * `{page}` manifest would resolve outside the tree (proposal 0058). Everyone\n * else wants `isMember`.\n */\nexport function matchesCollectionPaths(\n collection: CollectionConfig,\n relPath: string,\n): boolean {\n const matched = collection.paths.some((entry) => {\n const normalized = normalizeEntry(entry);\n if (normalized === \"\") return false;\n if (isGlob(normalized)) return matchesFileGlob(relPath, normalized);\n return relPath === normalized || relPath.startsWith(`${normalized}/`);\n });\n if (!matched) return false;\n // `exclude` is globs only, whatever `paths` was written as.\n return !collection.exclude.some((glob) => matchesFileGlob(relPath, glob));\n}\n\n/** A `paths` entry as a posix path with no `./` prefix and no trailing `/`. */\nfunction normalizeEntry(entry: string): string {\n const posix = entry.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n return posix.endsWith(\"/\") ? posix.slice(0, -1) : posix;\n}\n\n/**\n * Is this `paths` entry a glob, by picomatch's own definition, rather than a\n * bare file or directory to match by prefix?\n *\n * picomatch decides, not a character class of our own: an extended glob such\n * as `docs/!(drafts)/**` or `@(a|b)` has no `*`, `?`, `[` or `{` of its own\n * and a hand-rolled test read it as a literal path — matching nothing and\n * excluding nothing, silently. The one cost is that a literal directory whose\n * name carries parentheses, `docs/notes (old)`, is also read as a glob and so\n * matches itself only, not everything beneath it. Spell such a path as\n * `docs/notes (old)/**` to get the prefix behaviour back.\n */\nfunction isGlob(entry: string): boolean {\n return picomatch.scan(entry).isGlob;\n}\n","/**\n * Glob matching, shared by every tool.\n *\n * One matcher, so that the two questions that look alike really are alike: is\n * this file in a collection (proposal 0041), and does it match a schema\n * override's `files:` (0015). It lived in the metadata tool's schema resolver\n * until membership needed it too; a second copy is how the two would start\n * disagreeing about a dot file or a `\\`.\n */\nimport picomatch from \"picomatch\";\n\n/**\n * One compiled matcher per distinct glob, kept for the life of the process.\n * Never evicted, on purpose: the set of globs a run sees is the config's plus\n * a handful of flags, which is dozens at most, and a compile is the expensive\n * step. This module is shared across the family, so if it ever sits inside a\n * long-lived host that feeds it unbounded user globs, this is the line to\n * revisit — bound it, or key it per run. Until then an eviction policy would\n * be machinery for a case that does not exist.\n */\nconst matcherCache = new Map<string, (p: string) => boolean>();\n\n/**\n * Does this file path match the glob — or, for the list form, any of them — by\n * the shared rules (picomatch, dot files included, `\\` normalized to `/`)?\n */\nexport function matchesFileGlob(\n relPath: string,\n glob: string | readonly string[],\n): boolean {\n // picomatch takes a pattern array natively, so the list form needs no loop\n // here — but the cache does need a *string* key. Keyed on the array itself\n // this Map would compare by identity: a hit only for the very same object,\n // and an entry retained for every config ever parsed. JSON.stringify is the\n // key because it separates the two shapes on its own — a lone \"a/**\" and\n // [\"a/**\"] serialize differently — with no separator char to collide with\n // one inside a glob.\n const key = JSON.stringify(glob);\n let m = matcherCache.get(key);\n if (!m) {\n m = picomatch(glob as string | string[], { dot: true });\n matcherCache.set(key, m);\n }\n // Normalize Windows separators so globs written with `/` still match.\n return m(relPath.replace(/\\\\/g, \"/\"));\n}\n","/**\n * The `{page}` placeholder in `externalMetadata[].file` (proposal 0058).\n *\n * A `file` holding `{page}` is a rule rather than a file: each page gets its\n * own manifest, named by substituting the page's path, relative to the config\n * file's directory and without its extension. `\"{page}.citations.yaml\"` puts\n * `docs/x/index.mdx`'s manifest at `docs/x/index.citations.yaml`.\n *\n * One normalization is used wherever a pattern or a page path is compared or\n * substituted (0058 § 1): strip one leading `./`, and write every separator as\n * a forward slash. It is deliberately that small. It is not `path.resolve`, so\n * `./a/../{page}.yaml` stays its own pattern, and it does not fold case.\n *\n * The grammar itself (one token, spelled exactly, never in a URL or an\n * absolute path) is enforced by the config parser in `collections.ts`, so\n * everything here may assume a `file` that passed it.\n *\n * Shared, so it imports nothing from a tool.\n */\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { isAbsolute, posix, relative, resolve, sep } from \"node:path\";\nimport fg from \"fast-glob\";\nimport { LineCounter, isMap, isNode, isScalar, parseDocument } from \"yaml\";\n\n/** The one placeholder `externalMetadata[].file` accepts. */\nexport const PAGE_PLACEHOLDER = \"{page}\";\n\n/** True when `file` contains the {page} token (assumes it already passed parse validation). */\nexport function hasPagePlaceholder(file: string): boolean {\n return file.includes(PAGE_PLACEHOLDER);\n}\n\n/** Every separator written as a forward slash. */\nfunction slashes(path: string): string {\n return path.split(sep).join(\"/\").replace(/\\\\/g, \"/\");\n}\n\n/**\n * 0058 § 1 normalization: strip one leading \"./\", backslashes to \"/\". No case\n * folding, no path.resolve, no \"..\" collapsing.\n */\nexport function normalizeManifestPattern(file: string): string {\n const forward = file.replace(/\\\\/g, \"/\");\n return forward.startsWith(\"./\") ? forward.slice(2) : forward;\n}\n\n/**\n * The manifest a page resolves to. `configDir` absolute; `pageAbs` absolute.\n *\n * `{page}` is `relative(configDir, pageAbs)` with its extension removed,\n * normalized as above, substituted into the normalized pattern. Returns the\n * manifest's absolute path and its posix path relative to `configDir`, or\n * `{ outside: true, pageRel }` when the page is not under the config\n * directory: its relative path climbs with `../`, or, across Windows drives,\n * there is no relative path at all.\n */\nexport function pageManifestPath(\n file: string,\n configDir: string,\n pageAbs: string,\n): { abs: string; rel: string } | { outside: true; pageRel: string } {\n const between = relative(configDir, pageAbs);\n const pageRel = slashes(between);\n if (isAbsolute(between) || pageRel === \"..\" || pageRel.startsWith(\"../\")) {\n return { outside: true, pageRel };\n }\n const ext = posix.extname(pageRel);\n const page = ext === \"\" ? pageRel : pageRel.slice(0, -ext.length);\n const named = normalizeManifestPattern(file).replace(PAGE_PLACEHOLDER, () => page);\n const abs = resolve(configDir, named);\n return { abs, rel: slashes(relative(configDir, abs)) };\n}\n\n/**\n * 0058 § 5: the glob every manifest of a pattern matches. The normalized\n * pattern is split at `{page}` and `**` + `/*` inserted, keeping the prefix\n * and the suffix. No page path reaches it, but the prefix and suffix are the\n * config author's own literal text, and a directory name may hold glob\n * syntax: read raw, `meta (v2)/` is an extglob group that matches nothing. So\n * both are escaped, and only the inserted `**` + `/*` is live.\n * `\"{page}.citations.yaml\"` gives `**` + `/*.citations.yaml`, and\n * `\"./meta/{page}.citations.yaml\"` gives `meta/**` + `/*.citations.yaml`.\n */\nexport function strayManifestGlob(file: string): string {\n const normalized = normalizeManifestPattern(file);\n const at = normalized.indexOf(PAGE_PLACEHOLDER);\n if (at < 0) return literal(normalized);\n const prefix = literal(normalized.slice(0, at));\n const suffix = literal(normalized.slice(at + PAGE_PLACEHOLDER.length));\n return `${prefix}**/*${suffix}`;\n}\n\n/** Text a glob matches exactly. fast-glob refuses to escape an empty string. */\nfunction literal(text: string): string {\n return text === \"\" ? \"\" : fg.escapePath(text);\n}\n\n/** One entry of a per-page manifest found on disk, naming the page it is for. */\nexport interface FoundPageEntry {\n /** The key exactly as the manifest spells it. */\n spelled: string;\n /** The page it names, absolute. */\n pageAbs: string;\n /** 1-based line of the key in the manifest, when known. */\n line?: number;\n}\n\n/** A manifest file a `{page}` pattern names, and the entries it holds for its own page. */\nexport interface FoundPageManifest {\n /** The manifest, absolute. */\n abs: string;\n entries: FoundPageEntry[];\n}\n\n/**\n * The manifests on disk that `file`, a `{page}` pattern, names (0058 § 5):\n * every file the pattern's `strayManifestGlob` matches under `configDir`,\n * kept when it holds an entry the pattern resolves back to that very file,\n * for a page `isMember` claims. `isMember` takes the page's posix path\n * relative to `configDir`. A file with no such entry is not this pattern's\n * manifest, whatever its name: a copy of the tree elsewhere, a fixture, or a\n * file that only looks like one.\n *\n * The walk does not consult `.gitignore`, because a manifest is config named\n * input rather than a discovered document. It skips `node_modules`, `.git`\n * and dot directories, as the document walk does, so a checkout nested under\n * a dot directory is never read as this one's. A file that cannot be read or\n * parsed is not recognizably a manifest, and is skipped.\n *\n * Synchronous, so a synchronous orphan check can call it. It runs once per\n * whole-corpus run, never for a run given paths. A match in `skip` (absolute\n * paths) is neither read nor returned: the orphan check passes the manifests\n * the run already loaded, which would otherwise be parsed a second time.\n */\nexport function findPageManifests(\n file: string,\n configDir: string,\n isMember: (relPath: string) => boolean,\n skip: ReadonlySet<string> = new Set(),\n): FoundPageManifest[] {\n const matched = fg\n .sync(strayManifestGlob(file), {\n cwd: configDir,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\"],\n })\n .map((path) => resolve(path))\n .sort();\n const found: FoundPageManifest[] = [];\n for (const abs of matched) {\n if (skip.has(abs)) continue;\n const entries = ownEntries(abs, file, configDir, isMember);\n if (entries.length > 0) found.push({ abs, entries });\n }\n return found;\n}\n\n/** The entries of the manifest at `abs` that `file` resolves back to `abs`. */\nfunction ownEntries(\n abs: string,\n file: string,\n configDir: string,\n isMember: (relPath: string) => boolean,\n): FoundPageEntry[] {\n let text: string;\n try {\n text = readFileSync(abs, \"utf8\");\n } catch {\n return [];\n }\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const root = doc.contents;\n if (doc.errors.length > 0 || !isMap(root)) return [];\n const entries: FoundPageEntry[] = [];\n for (const pair of root.items) {\n const spelled = isScalar(pair.key) ? String(pair.key.value) : String(pair.key);\n const pageAbs = resolve(configDir, spelled);\n if (!isMember(slashes(relative(configDir, pageAbs)))) continue;\n const resolved = pageManifestPath(file, configDir, pageAbs);\n if (\"outside\" in resolved || !sameFile(resolved.abs, abs)) continue;\n const range = isNode(pair.key) ? pair.key.range : undefined;\n entries.push({\n spelled,\n pageAbs,\n ...(range ? { line: lc.linePos(range[0]).line } : {}),\n });\n }\n return entries;\n}\n\n/**\n * Are these one file, as the filesystem resolves them? Compared as files and\n * not as text (0058 stress test 8), so a case-only difference is one file on\n * a case-insensitive filesystem and two elsewhere.\n */\nexport function sameFile(a: string, b: string): boolean {\n if (a === b) return true;\n try {\n return realpathSync(a) === realpathSync(b);\n } catch {\n return false;\n }\n}\n","/**\n * `tools:`, the family-level home for an outside tool's settings (proposal\n * 0052, in the shape lint's proposal 0050 recorded).\n *\n * An outside tool is not any one domain's, so its settings do not sit under a\n * domain's key. Vale is the case in point: `manni term lint` runs it, and so\n * does a docevals grader. Each should read one description of where Vale's\n * config lives, not two that can disagree.\n *\n * Each tool gets a namespace of its own keys rather than a shared\n * `{tool, config}` shape, because tools do not have the same settings. A\n * lowest-common-denominator shape would either lie or grow a passthrough blob.\n *\n * Only the declaration is shared. Running a tool stays with the domain that\n * runs it. Paths are kept as the user spelled them and resolved on use,\n * against the config file's directory, the way `collections:` keeps its globs;\n * whether the file exists is a question for the run that needs it.\n */\nimport { isAbsolute, resolve } from \"node:path\";\n\n/** Vale's settings under `tools.vale`. */\nexport interface ValeToolConfig {\n /** Vale's config file, as written, relative to `manni.config.yaml`. */\n config?: string;\n}\n\n/** DITA Open Toolkit's settings under `tools.dita-ot`. */\nexport interface DitaOtToolConfig {\n /**\n * DITA-OT's installation directory, as written, relative to\n * `manni.config.yaml`. Unset means the `dita` on PATH.\n *\n * A directory rather than a path to the launcher, because that is the unit\n * DITA-OT is distributed and documented as: the download unpacks to one\n * directory, and `bin/dita` inside it will not run from anywhere else.\n */\n home?: string;\n}\n\n/** The document's top-level `tools:`, one namespace per outside tool. */\nexport interface ToolsConfig {\n vale?: ValeToolConfig;\n \"dita-ot\"?: DitaOtToolConfig;\n}\n\nconst TOOL_KEYS = [\"vale\", \"dita-ot\"] as const;\nconst VALE_KEYS = [\"config\"] as const;\nconst DITA_OT_KEYS = [\"home\"] as const;\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction rejectUnknownKeys(\n raw: Record<string, unknown>,\n allowed: readonly string[],\n where: string,\n source: string,\n toError: (message: string) => Error,\n): void {\n for (const key of Object.keys(raw)) {\n if (!allowed.includes(key)) {\n throw toError(\n `${source}: ${where} has unknown key \"${key}\". Supported keys: ${allowed.join(\", \")}.`,\n );\n }\n }\n}\n\n/**\n * Parse the value under the top-level `tools:` key. A bare `tools:` (YAML\n * null) is no tools. Every refusal is a shape that would otherwise read as\n * configured and do nothing: a misspelled tool, or a key a tool never reads.\n */\nexport function parseTools(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): ToolsConfig {\n if (raw === null || raw === undefined) return {};\n if (!isMapping(raw)) {\n throw toError(`${source}: \"tools\" must be a mapping.`);\n }\n rejectUnknownKeys(raw, TOOL_KEYS, \"tools\", source, toError);\n\n const tools: ToolsConfig = {};\n if (Object.hasOwn(raw, \"vale\")) {\n tools.vale = parseVale(raw[\"vale\"], source, toError);\n }\n if (Object.hasOwn(raw, \"dita-ot\")) {\n tools[\"dita-ot\"] = parseDitaOt(raw[\"dita-ot\"], source, toError);\n }\n return tools;\n}\n\nfunction parseVale(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): ValeToolConfig {\n if (!isMapping(raw)) {\n throw toError(`${source}: tools.vale must be a mapping.`);\n }\n rejectUnknownKeys(raw, VALE_KEYS, \"tools.vale\", source, toError);\n\n const vale: ValeToolConfig = {};\n if (Object.hasOwn(raw, \"config\")) {\n const config = raw[\"config\"];\n if (typeof config !== \"string\" || config.trim() === \"\") {\n throw toError(`${source}: tools.vale.config must be a non-empty string.`);\n }\n vale.config = config;\n }\n return vale;\n}\n\nfunction parseDitaOt(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): DitaOtToolConfig {\n if (!isMapping(raw)) {\n throw toError(`${source}: tools.dita-ot must be a mapping.`);\n }\n rejectUnknownKeys(raw, DITA_OT_KEYS, \"tools.dita-ot\", source, toError);\n\n const ditaOt: DitaOtToolConfig = {};\n if (Object.hasOwn(raw, \"home\")) {\n const home = raw[\"home\"];\n if (typeof home !== \"string\" || home.trim() === \"\") {\n throw toError(`${source}: tools.dita-ot.home must be a non-empty string.`);\n }\n ditaOt.home = home;\n }\n return ditaOt;\n}\n\n/**\n * The absolute path of Vale's config file, resolved against the directory of\n * the config file that declared it. `undefined` when none is set, which means\n * Vale finds its own config, as it does when a person runs it.\n */\nexport function valeConfigPath(tools: ToolsConfig, configDir: string): string | undefined {\n const config = tools.vale?.config;\n if (config === undefined) return undefined;\n return isAbsolute(config) ? config : resolve(configDir, config);\n}\n\n/**\n * The absolute path of DITA-OT's installation directory, resolved against the\n * directory of the config file that declared it. `undefined` when none is set,\n * which means the `dita` on PATH, as when a person runs it.\n */\nexport function ditaOtHome(tools: ToolsConfig, configDir: string): string | undefined {\n const home = tools[\"dita-ot\"]?.home;\n if (home === undefined) return undefined;\n return isAbsolute(home) ? home : resolve(configDir, home);\n}\n","/**\n * The family config file.\n *\n * One file per repository, `manni.config.yaml`, with one top-level key per\n * tool: `meta:` for the metadata tool, `docevals:`, `tracevals:`, `lint:`,\n * `graph:` as each lands. A tool reads its own key and leaves its siblings alone,\n * so adding a tool never invalidates a config that predates it.\n *\n * This module only finds the file and hands a tool its slice. What the slice\n * may contain is the tool's business; it validates the value with its own\n * parser and its own error class, which is why `toError` is an option rather\n * than an import. Four top-level keys belong to the family rather than to a\n * tool, and are parsed here once for every tool. They are `collections:`\n * (proposal 0041), `tools:` (proposal 0052) and `encryptionKey:` (proposal\n * 0045). The fourth is `providers:`, the inference provider settings every\n * tool that sends content to a model reads.\n *\n * One older spelling is still read, with a warning on discovery: each tool's\n * pre-family file (`docmeta.config.yaml` for the metadata tool), whose whole\n * document is the tool's section with no wrapper key.\n *\n * Within one directory the order is manni, then the legacy names, and\n * `.yaml` before `.yml`. A family file that exists but has neither a key for\n * this tool nor a family key is not this tool's config: discovery keeps\n * looking, first at the legacy names beside it (a repository mid-migration,\n * where a sibling tool moved to the family file first) and then up the tree.\n * The walk stops at the nearest `.git` boundary, nearest directory first, and\n * the first hit wins; ancestor files are never merged.\n *\n * An explicit path is read the same way minus the warning: the section key is\n * unwrapped when present, a document carrying a family key is a family file\n * with an empty section, and the whole document is taken otherwise, so a\n * `-c ./anything.yaml` needs no filename sniffing and no flag.\n *\n * The core is synchronous: some tools load config from synchronous library\n * entry points, and one small file read is not worth an `await` through their\n * public API. `findConfigFileSync` and `readConfigFileSync` expose it; the\n * async spellings are wrappers over the same core for callers that await.\n */\nimport { readFileSync } from \"node:fs\";\nimport { basename, dirname, join, relative, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { parseCollections, type CollectionConfig } from \"./collections.js\";\nimport { isValidEncryptionKey } from \"./encryption.js\";\nimport { PROVIDERS_KEY, parseProviders, type ProvidersConfig } from \"./providers.js\";\nimport { searchPath } from \"./git-root.js\";\nimport { parseTools, type ToolsConfig } from \"./tools.js\";\nimport { warn } from \"./warn.js\";\nimport { errorMessage } from \"./errors.js\";\n\n/** The canonical family filenames, in discovery order. */\nexport const FAMILY_CONFIG_NAMES: readonly string[] = [\n \"manni.config.yaml\",\n \"manni.config.yml\",\n];\n\n/** The top-level key holding the family encryption key (proposal 0045). */\nexport const ENCRYPTION_KEY_FIELD = \"encryptionKey\";\n\n/**\n * The top-level key holding the key a rotation is replacing (proposal 0045).\n * Present only while a rotation is unfinished: `manni key rotate` writes it\n * beside the new key before it touches a page, and removes it once every page\n * is written. Read only by `manni key rotate`, which finishes the rotation.\n */\nexport const ENCRYPTION_KEY_PREVIOUS_FIELD = \"encryptionKeyPrevious\";\n\nexport interface ConfigFileOptions {\n /** The tool's key in a family file, e.g. `\"meta\"`. */\n section: string;\n /**\n * The tool's own filenames from before the family file, in discovery order.\n * Their whole document is the tool's section.\n */\n legacyNames: readonly string[];\n /** Build the error for an unreadable document, in the tool's own class. */\n toError: (message: string) => Error;\n}\n\nexport interface ConfigFile {\n /** Absolute path to the file. */\n path: string;\n /** Directory holding it; relative paths in the config resolve from here. */\n dir: string;\n /**\n * The file as the user would name it: relative to `cwd`, posix separators,\n * or the spelling they typed for an explicit path. For error messages.\n */\n source: string;\n /** The file's text, for a tool that rewrites the file in place. */\n text: string;\n /**\n * The tool's slice: the value under `section:` when `wrapped`, otherwise\n * the whole document. `null` for an empty file or an empty section; the\n * tool decides what empty means.\n */\n value: unknown;\n /** Whether `value` came from under `section:`. */\n wrapped: boolean;\n /** How the file was found. Explicit paths are never warned about. */\n kind: \"manni\" | \"legacy\" | \"explicit\";\n /**\n * The document's top-level `collections:` (proposal 0041), parsed once here\n * because every tool reads the same declaration. `[]` when the key is\n * absent, and always `[]` for a `legacy` file: a per-tool file's whole\n * document *is* the tool's section, so it carries no family-wide keys.\n */\n collections: CollectionConfig[];\n /**\n * The document's top-level `tools:` (proposal 0052), an outside tool's\n * settings, parsed once here for the same reason as `collections`. `{}` when\n * the key is absent, and always `{}` for a `legacy` file.\n */\n tools: ToolsConfig;\n /**\n * The document's top-level `encryptionKey:` (proposal 0045), validated\n * here. Absent when the key is, and always absent for a `legacy` file, for\n * the same reason as `collections`. `MANNI_ENCRYPTION_KEY` wins over it;\n * read it through `resolveEncryptionKey`, not directly.\n */\n encryptionKey?: string;\n /**\n * The document's top-level `encryptionKeyPrevious:`, validated here as\n * `encryptionKey` is. Present only while a rotation is unfinished, and read\n * only by `manni key rotate`, which finishes it.\n */\n encryptionKeyPrevious?: string;\n /**\n * The document's top-level `providers:`, parsed here with a relative\n * `llama-cpp.modelsDir` resolved against `dir`. Absent when the key is, and\n * always absent for a `legacy` file, for the same reason as `collections`.\n */\n providers?: ProvidersConfig;\n}\n\ntype ToError = (message: string) => Error;\n\ninterface Document {\n text: string;\n /** Parsed YAML: a mapping, or `null` for an empty file. */\n doc: Record<string, unknown> | null;\n}\n\nfunction readDocument(\n path: string,\n source: string,\n toError: ToError,\n): Document | null {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n return { text, doc: parseMapping(text, source, toError) };\n}\n\n/**\n * Parse outside any \"not found\" handling. A discovered file with a typo must\n * be reported, not skipped: falling through to the next candidate, or to no\n * config at all, would run the tool on defaults and read as a clean pass.\n */\nfunction parseMapping(\n text: string,\n source: string,\n toError: ToError,\n): Record<string, unknown> | null {\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (err) {\n throw toError(`${source}: invalid YAML: ${errorMessage(err)}`);\n }\n if (raw == null) return null;\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n throw toError(`${source}: top level must be a mapping.`);\n }\n return raw as Record<string, unknown>;\n}\n\n/** The top-level key holding the family's document sets. */\nconst COLLECTIONS_KEY = \"collections\";\n\n/** The top-level key holding outside tools' settings (proposal 0052). */\nconst TOOLS_KEY = \"tools\";\n\n/** The keys that belong to the family, not to any one tool. */\nconst FAMILY_KEYS: readonly string[] = [\n COLLECTIONS_KEY,\n TOOLS_KEY,\n ENCRYPTION_KEY_FIELD,\n PROVIDERS_KEY,\n];\n\nfunction slice(\n document: Document,\n opts: ConfigFileOptions,\n): { value: unknown; wrapped: boolean } | null {\n const { doc } = document;\n if (doc !== null && Object.hasOwn(doc, opts.section)) {\n return { value: doc[opts.section] ?? null, wrapped: true };\n }\n // A family file carrying a family key and no section is still this tool's\n // config: the documents are declared (0041), or the key is (0045), or the\n // provider settings are, and the tool just has no options of its own.\n // Handing back an empty section is what stops discovery walking past it.\n // For the key that matters twice: a\n // file the key prompt created holds nothing else, and the next run must\n // find it.\n if (doc !== null && FAMILY_KEYS.some((key) => Object.hasOwn(doc, key))) {\n return { value: null, wrapped: true };\n }\n return null;\n}\n\n/**\n * The document's collections. Parsed with the tool's own `toError`, so a bad\n * `collections:` is reported in the class the tool already catches.\n */\nfunction collectionsOf(\n document: Document,\n source: string,\n toError: ToError,\n): CollectionConfig[] {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, COLLECTIONS_KEY)) return [];\n return parseCollections(doc[COLLECTIONS_KEY], source, toError);\n}\n\n/**\n * The document's outside-tool settings. Parsed with the tool's own `toError`,\n * as `collections:` is.\n */\nfunction toolsOf(document: Document, source: string, toError: ToError): ToolsConfig {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, TOOLS_KEY)) return {};\n return parseTools(doc[TOOLS_KEY], source, toError);\n}\n\n/**\n * The document's encryption key, as a spreadable field. A malformed one is an\n * error in the tool's class, and the message never repeats the value: it is\n * key material, and a CI log is not the place for it.\n */\nfunction encryptionKeyOf(\n document: Document,\n source: string,\n toError: ToError,\n): { encryptionKey?: string; encryptionKeyPrevious?: string } {\n const { doc } = document;\n if (doc === null) return {};\n const keys: { encryptionKey?: string; encryptionKeyPrevious?: string } = {};\n if (Object.hasOwn(doc, ENCRYPTION_KEY_FIELD)) {\n const value = doc[ENCRYPTION_KEY_FIELD];\n if (!isValidEncryptionKey(value)) {\n throw toError(\n `${source}: \"${ENCRYPTION_KEY_FIELD}\" must be at least 32 hex or base64url characters. Run \\`manni key set\\` to generate one.`,\n );\n }\n keys.encryptionKey = value;\n }\n // The key an unfinished rotation is replacing. Key material too, so the\n // same shape rule and the same silence about the value. There is no advice\n // to generate one: `manni key rotate` writes it, and nothing else should.\n if (Object.hasOwn(doc, ENCRYPTION_KEY_PREVIOUS_FIELD)) {\n const value = doc[ENCRYPTION_KEY_PREVIOUS_FIELD];\n if (!isValidEncryptionKey(value)) {\n throw toError(\n `${source}: \"${ENCRYPTION_KEY_PREVIOUS_FIELD}\" must be at least 32 hex or base64url characters.`,\n );\n }\n keys.encryptionKeyPrevious = value;\n }\n return keys;\n}\n\n/**\n * The document's provider settings, as a spreadable field. Parsed with the\n * tool's own `toError`, and a relative path in them resolves from `dir`.\n */\nfunction providersOf(\n document: Document,\n source: string,\n dir: string,\n toError: ToError,\n): { providers?: ProvidersConfig } {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, PROVIDERS_KEY)) return {};\n return { providers: parseProviders(doc[PROVIDERS_KEY], source, dir, toError) };\n}\n\n/**\n * The family keys as `manni key` reads them: only valid ones, and a malformed\n * one is no error, because replacing it is what the caller is for.\n */\nfunction tolerantKeysOf(document: Document): {\n encryptionKey?: string;\n encryptionKeyPrevious?: string;\n} {\n const key = document.doc?.[ENCRYPTION_KEY_FIELD];\n const previous = document.doc?.[ENCRYPTION_KEY_PREVIOUS_FIELD];\n return {\n ...(isValidEncryptionKey(key) ? { encryptionKey: key } : {}),\n ...(isValidEncryptionKey(previous) ? { encryptionKeyPrevious: previous } : {}),\n };\n}\n\nfunction relativeSource(cwd: string, path: string): string {\n return relative(cwd, path).replace(/\\\\/g, \"/\");\n}\n\n/**\n * Discover the tool's config from `cwd` upward. `null` when nothing exists.\n */\nexport function findConfigFileSync(\n cwd: string,\n opts: ConfigFileOptions,\n): ConfigFile | null {\n const start = resolve(cwd);\n for (const dir of searchPath(start)) {\n for (const name of FAMILY_CONFIG_NAMES) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = readDocument(path, source, opts.toError);\n if (document === null) continue;\n const found = slice(document, opts);\n // A family file without this tool's key belongs to a sibling. Keep\n // looking, rather than treating the file as an empty config.\n if (found === null) continue;\n return {\n path,\n dir,\n source,\n text: document.text,\n kind: \"manni\",\n collections: collectionsOf(document, source, opts.toError),\n tools: toolsOf(document, source, opts.toError),\n ...encryptionKeyOf(document, source, opts.toError),\n ...providersOf(document, source, dir, opts.toError),\n ...found,\n };\n }\n for (const name of opts.legacyNames) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = readDocument(path, source, opts.toError);\n if (document === null) continue;\n warn(\n `\"${name}\" is a deprecated config file name. Move its keys under \\`${opts.section}:\\` in \"${FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"}\", and its paths, exclude and sidecars keys to a top-level collections: list, where sidecars becomes externalMetadata.`,\n );\n return {\n path,\n dir,\n source,\n text: document.text,\n value: document.doc,\n wrapped: false,\n kind: \"legacy\",\n collections: [],\n tools: {},\n };\n }\n }\n return null;\n}\n\n/**\n * Read the config at an explicit path. Missing is an error: a `-c` pointing\n * at a file that is not there is a mistake worth failing on, not a reason to\n * quietly run against something else.\n */\nexport function readConfigFileSync(\n explicitPath: string,\n cwd: string,\n opts: ConfigFileOptions,\n): ConfigFile {\n const path = resolve(cwd, explicitPath);\n // Report the spelling the user typed, not the resolved absolute path.\n const document = readDocument(path, explicitPath, opts.toError);\n if (document === null) {\n throw opts.toError(`Config file not found: \"${explicitPath}\".`);\n }\n const found = slice(document, opts) ?? {\n value: document.doc,\n wrapped: false,\n };\n return {\n path,\n dir: dirname(path),\n source: explicitPath,\n text: document.text,\n kind: \"explicit\",\n collections: collectionsOf(document, explicitPath, opts.toError),\n tools: toolsOf(document, explicitPath, opts.toError),\n // An unwrapped document carries no family key (else it would be wrapped),\n // so this only ever reads a family file's key.\n ...encryptionKeyOf(document, explicitPath, opts.toError),\n ...providersOf(document, explicitPath, dirname(path), opts.toError),\n ...found,\n };\n}\n\n/** `findConfigFileSync`, for callers that await. */\nexport function findConfigFile(\n cwd: string,\n opts: ConfigFileOptions,\n): Promise<ConfigFile | null> {\n return Promise.resolve().then(() => findConfigFileSync(cwd, opts));\n}\n\n/** `readConfigFileSync`, for callers that await. */\nexport function readConfigFile(\n explicitPath: string,\n cwd: string,\n opts: ConfigFileOptions,\n): Promise<ConfigFile> {\n return Promise.resolve().then(() =>\n readConfigFileSync(explicitPath, cwd, opts),\n );\n}\n\n/**\n * The nearest family file from `cwd` upward, whatever it carries: any tool's\n * section, a family key, or nothing at all. For `manni key`, which writes the\n * family's key and so belongs to no one tool's section. Never a legacy\n * per-tool file, whose whole document is one tool's section.\n *\n * `value` is `null` and `wrapped` is `true`: no tool's section is handed\n * over. `encryptionKey` is set only when the file holds a valid one. A\n * malformed key is not an error here, unlike in `findConfigFile`, because\n * replacing it is what the caller is for.\n */\nexport function findFamilyConfigFile(\n cwd: string,\n toError: ToError,\n): Promise<ConfigFile | null> {\n return Promise.resolve().then(() => findFamilyConfigFileSync(cwd, toError));\n}\n\nfunction findFamilyConfigFileSync(\n cwd: string,\n toError: ToError,\n): ConfigFile | null {\n const start = resolve(cwd);\n for (const dir of searchPath(start)) {\n for (const name of FAMILY_CONFIG_NAMES) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = readDocument(path, source, toError);\n if (document === null) continue;\n return {\n path,\n dir,\n source,\n text: document.text,\n value: null,\n wrapped: true,\n kind: \"manni\",\n collections: collectionsOf(document, source, toError),\n tools: toolsOf(document, source, toError),\n ...tolerantKeysOf(document),\n };\n }\n }\n return null;\n}\n\n/**\n * Read an explicit path as a family file, for `manni key set -c`, which writes\n * the family's key and so belongs to no one tool's section.\n *\n * The file is a family file when it is empty, carries a family key, or is\n * named as one (`manni.config.yaml`, `manni.config.yml`): its top-level keys\n * are then sections, whatever they are, and `value` is `null`. Anything else\n * is read whole as one tool's section (`wrapped: false`), which the key writer\n * refuses rather than turn into a family file under that tool's feet. Missing\n * is an error, as it is for `readConfigFile`. Keys are carried as\n * `findFamilyConfigFile` carries them.\n */\nexport function readFamilyConfigFile(\n explicitPath: string,\n cwd: string,\n toError: ToError,\n): Promise<ConfigFile> {\n return Promise.resolve().then(() =>\n readFamilyConfigFileSync(explicitPath, cwd, toError),\n );\n}\n\nfunction readFamilyConfigFileSync(\n explicitPath: string,\n cwd: string,\n toError: ToError,\n): ConfigFile {\n const path = resolve(cwd, explicitPath);\n const document = readDocument(path, explicitPath, toError);\n if (document === null) {\n throw toError(`Config file not found: \"${explicitPath}\".`);\n }\n const { doc } = document;\n const named = FAMILY_CONFIG_NAMES.includes(basename(path));\n const family =\n doc === null || named || FAMILY_KEYS.some((key) => Object.hasOwn(doc, key));\n return {\n path,\n dir: dirname(path),\n source: explicitPath,\n text: document.text,\n value: family ? null : doc,\n wrapped: family,\n kind: \"explicit\",\n collections: collectionsOf(document, explicitPath, toError),\n tools: toolsOf(document, explicitPath, toError),\n ...tolerantKeysOf(document),\n };\n}\n","/**\n * The project boundary: the nearest directory at or above `cwd` holding a\n * `.git` entry. A file or a directory, since a worktree's `.git` is a file.\n *\n * Two callers need it for opposite reasons and only one of them wants a\n * chain. Config discovery walks the chain and stops here. The SARIF reporter\n * needs the root itself, and needs \"there is no repository\" to be\n * distinguishable from \"the repository root is where you are standing\" — a\n * one-element chain conflates the two, and getting that wrong means emitting\n * paths GitHub silently drops.\n */\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nexport function findGitRoot(cwd: string): string | null {\n let dir = resolve(cwd);\n for (;;) {\n if (existsSync(join(dir, \".git\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * The directories a discovery walk may look in, nearest first.\n *\n * The walk stops at the project boundary `findGitRoot` reports, which is\n * included in the search. Only that one call touches the filesystem; the chain\n * itself is then assembled from path strings.\n *\n * With **no** boundary anywhere above cwd, only cwd is considered. A\n * project-scoped config has no meaning without a project, and walking on would\n * let a stray config file in a home or temp directory silently govern\n * unrelated runs — including this repo's own tests, which work in OS temp\n * directories under the user's home.\n */\nexport function searchPath(cwd: string): string[] {\n const start = resolve(cwd);\n const root = findGitRoot(start);\n if (root === null) return [start];\n const chain: string[] = [];\n let dir = start;\n for (;;) {\n chain.push(dir);\n if (dir === root) return chain;\n const parent = dirname(dir);\n // `root` is an ancestor of `start` by construction, so this is unreachable\n // — but a filesystem race (the boundary removed mid-walk) must not loop.\n if (parent === dir) return chain;\n dir = parent;\n }\n}\n"],"mappings":"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","names":["picomatch","posix","isMember","posix","picomatch","isAbsolute","resolve","isMapping","rejectUnknownKeys","readFileSync","dirname","join","relative","resolve","resolve","readFileSync","relative","resolve","join","dirname"]}