@mistriwork/mistri 1.0.0-rc.12 → 1.0.0-rc.13

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 (221) hide show
  1. package/README.md +4 -3
  2. package/dist/client/assets/LayoutBuilder-MPzkVU2e.js.map +1 -1
  3. package/dist/client/assets/index-D2dHI6hR.js.map +1 -1
  4. package/dist/client/assets/shell-TreN_uLs.js.map +1 -1
  5. package/dist/docs/access-model.md +1 -1
  6. package/dist/docs/build-and-deploy.md +0 -1
  7. package/dist/docs/cli.md +1 -1
  8. package/dist/docs/glossary.md +3 -3
  9. package/dist/docs/query.md +9 -21
  10. package/dist/docs/status.md +3 -3
  11. package/dist/embed/react/chunks/LayoutBuilder-Cbxa_wve.js.map +1 -1
  12. package/dist/embed/react/chunks/app-0UZ1Re1k.js.map +1 -1
  13. package/dist/embed/react/chunks/page-Bx4o1kpQ.js.map +1 -1
  14. package/dist/embed/react/chunks/palette-Bb7Lf6eo.js.map +1 -1
  15. package/dist/embed/react/chunks/shell-DZRACiB9.js.map +1 -1
  16. package/dist/embed/react/chunks/write-BQO4CFc9.js.map +1 -1
  17. package/dist/embed/react/index.js +1 -1
  18. package/dist/server/build/dockerfile.js +1 -1
  19. package/dist/server/cli/usage.js +2 -2
  20. package/dist/ui/index.js +2 -2
  21. package/dist/ui/page.js +2 -2
  22. package/dist/ui/{shared-N4Ej8yRD.js → shared-1PD7TOTJ.js} +5 -5
  23. package/dist/ui/{shared-N4Ej8yRD.js.map → shared-1PD7TOTJ.js.map} +1 -1
  24. package/dist/ui/{shared-D5m86-4o.js → shared-1gMnOu9J.js} +6 -6
  25. package/dist/ui/{shared-D5m86-4o.js.map → shared-1gMnOu9J.js.map} +1 -1
  26. package/dist/ui/{shared-Ctaj8mR2.js → shared-5RQMi4BR.js} +3 -3
  27. package/dist/ui/{shared-Ctaj8mR2.js.map → shared-5RQMi4BR.js.map} +1 -1
  28. package/dist/ui/{shared-DpLeIATZ.js → shared-B-BUF9fx.js} +2 -2
  29. package/dist/ui/{shared-DpLeIATZ.js.map → shared-B-BUF9fx.js.map} +1 -1
  30. package/dist/ui/{shared-DWYnjItP.js → shared-B-MhiPIN.js} +9 -9
  31. package/dist/ui/{shared-DWYnjItP.js.map → shared-B-MhiPIN.js.map} +1 -1
  32. package/dist/ui/{shared-0fNuhSbG.js → shared-B07qIMlE.js} +5 -5
  33. package/dist/ui/{shared-0fNuhSbG.js.map → shared-B07qIMlE.js.map} +1 -1
  34. package/dist/ui/{shared-lYtMadRU.js → shared-B1SAS_J-.js} +3 -3
  35. package/dist/ui/{shared-lYtMadRU.js.map → shared-B1SAS_J-.js.map} +1 -1
  36. package/dist/ui/{shared-CpI0Y8M5.js → shared-B4jgU8h9.js} +6 -6
  37. package/dist/ui/{shared-CpI0Y8M5.js.map → shared-B4jgU8h9.js.map} +1 -1
  38. package/dist/ui/{shared-Cxu1c35l.js → shared-B5aBCUi7.js} +30 -30
  39. package/dist/ui/{shared-Cxu1c35l.js.map → shared-B5aBCUi7.js.map} +1 -1
  40. package/dist/ui/{shared-CAe-US1q.js → shared-B9H7_Pji.js} +5 -5
  41. package/dist/ui/{shared-CAe-US1q.js.map → shared-B9H7_Pji.js.map} +1 -1
  42. package/dist/ui/{shared-Q2bgBaYo.js → shared-BAXr20S-.js} +4 -4
  43. package/dist/ui/{shared-Q2bgBaYo.js.map → shared-BAXr20S-.js.map} +1 -1
  44. package/dist/ui/{shared-CyEefFFb.js → shared-BDDUzH-f.js} +19 -19
  45. package/dist/ui/{shared-CyEefFFb.js.map → shared-BDDUzH-f.js.map} +1 -1
  46. package/dist/ui/{shared-BdhPI6dq.js → shared-BGmkeDeW.js} +3 -3
  47. package/dist/ui/{shared-BdhPI6dq.js.map → shared-BGmkeDeW.js.map} +1 -1
  48. package/dist/ui/{shared-DONIpq2q.js → shared-BHCQ60yN.js} +2 -2
  49. package/dist/ui/{shared-DONIpq2q.js.map → shared-BHCQ60yN.js.map} +1 -1
  50. package/dist/ui/{shared-CNmaAv64.js → shared-BHsjawAG.js} +8 -8
  51. package/dist/ui/{shared-CNmaAv64.js.map → shared-BHsjawAG.js.map} +1 -1
  52. package/dist/ui/{shared-DgjU9kOy.js → shared-BIQuK_nq.js} +4 -4
  53. package/dist/ui/{shared-DgjU9kOy.js.map → shared-BIQuK_nq.js.map} +1 -1
  54. package/dist/ui/{shared-icSQAj21.js → shared-BOe4W2FI.js} +3 -3
  55. package/dist/ui/{shared-icSQAj21.js.map → shared-BOe4W2FI.js.map} +1 -1
  56. package/dist/ui/{shared-BlxoOJSk.js → shared-BPpC08ip.js} +3 -3
  57. package/dist/ui/{shared-BlxoOJSk.js.map → shared-BPpC08ip.js.map} +1 -1
  58. package/dist/ui/{shared-BtiFL37J.js → shared-BdA3LPCB.js} +2 -2
  59. package/dist/ui/{shared-BtiFL37J.js.map → shared-BdA3LPCB.js.map} +1 -1
  60. package/dist/ui/{shared-CvR94vn4.js → shared-Be3nbWsd.js} +11 -11
  61. package/dist/ui/{shared-CvR94vn4.js.map → shared-Be3nbWsd.js.map} +1 -1
  62. package/dist/ui/{shared-Bl_nF_IH.js → shared-Bf30ZLoS.js} +8 -4
  63. package/dist/ui/shared-Bf30ZLoS.js.map +1 -0
  64. package/dist/ui/{shared-DijrJ_V-.js → shared-BguP_BaR.js} +7 -7
  65. package/dist/ui/{shared-DijrJ_V-.js.map → shared-BguP_BaR.js.map} +1 -1
  66. package/dist/ui/{shared-DPAVoWY0.js → shared-BoLbc2WD.js} +17 -2
  67. package/dist/ui/{shared-DPAVoWY0.js.map → shared-BoLbc2WD.js.map} +1 -1
  68. package/dist/ui/{shared-BkdBTYwx.js → shared-BttyOW4W.js} +3 -3
  69. package/dist/ui/{shared-BkdBTYwx.js.map → shared-BttyOW4W.js.map} +1 -1
  70. package/dist/ui/{shared-CQWLz8uT.js → shared-BumxsBlA.js} +10 -10
  71. package/dist/ui/{shared-CQWLz8uT.js.map → shared-BumxsBlA.js.map} +1 -1
  72. package/dist/ui/{shared-Dzu7tFiC.js → shared-Bw73ktBk.js} +3 -3
  73. package/dist/ui/{shared-Dzu7tFiC.js.map → shared-Bw73ktBk.js.map} +1 -1
  74. package/dist/ui/{shared-BhAYErSx.js → shared-C1B0GH0e.js} +4 -4
  75. package/dist/ui/{shared-BhAYErSx.js.map → shared-C1B0GH0e.js.map} +1 -1
  76. package/dist/ui/{shared-BQJQcGgj.js → shared-C2FsyYr7.js} +4 -4
  77. package/dist/ui/{shared-BQJQcGgj.js.map → shared-C2FsyYr7.js.map} +1 -1
  78. package/dist/ui/{shared-B9lw2Ryh.js → shared-C2RU1qjv.js} +4 -4
  79. package/dist/ui/{shared-B9lw2Ryh.js.map → shared-C2RU1qjv.js.map} +1 -1
  80. package/dist/ui/{shared-DQYNI9wO.js → shared-C42f07hJ.js} +5 -5
  81. package/dist/ui/{shared-DQYNI9wO.js.map → shared-C42f07hJ.js.map} +1 -1
  82. package/dist/ui/{shared-CqCZ8wMY.js → shared-C4LkPCU4.js} +3 -3
  83. package/dist/ui/{shared-CqCZ8wMY.js.map → shared-C4LkPCU4.js.map} +1 -1
  84. package/dist/ui/{shared-BhtpgOpa.js → shared-C4wSfz6k.js} +9 -9
  85. package/dist/ui/{shared-BhtpgOpa.js.map → shared-C4wSfz6k.js.map} +1 -1
  86. package/dist/ui/{shared-BHc2Izkj.js → shared-C9DZtSFH.js} +2 -2
  87. package/dist/ui/{shared-BHc2Izkj.js.map → shared-C9DZtSFH.js.map} +1 -1
  88. package/dist/ui/{shared-DW1YuiNS.js → shared-CA52ClGo.js} +2 -2
  89. package/dist/ui/{shared-DW1YuiNS.js.map → shared-CA52ClGo.js.map} +1 -1
  90. package/dist/ui/{shared-BbSbilkh.js → shared-CBciTwm6.js} +9 -9
  91. package/dist/ui/{shared-BbSbilkh.js.map → shared-CBciTwm6.js.map} +1 -1
  92. package/dist/ui/{shared-C-J32eBn.js → shared-CL3RLKDA.js} +16 -16
  93. package/dist/ui/{shared-C-J32eBn.js.map → shared-CL3RLKDA.js.map} +1 -1
  94. package/dist/ui/{shared-Ck8S4OxW.js → shared-CLq3-_hW.js} +3 -3
  95. package/dist/ui/{shared-Ck8S4OxW.js.map → shared-CLq3-_hW.js.map} +1 -1
  96. package/dist/ui/{shared-Q5WefT7G.js → shared-CMjK-Ucd.js} +3 -3
  97. package/dist/ui/{shared-Q5WefT7G.js.map → shared-CMjK-Ucd.js.map} +1 -1
  98. package/dist/ui/{shared-D3MAuEA3.js → shared-CPjpSFGh.js} +2 -2
  99. package/dist/ui/{shared-D3MAuEA3.js.map → shared-CPjpSFGh.js.map} +1 -1
  100. package/dist/ui/{shared-VshXGwXP.js → shared-CSPhENq3.js} +2 -2
  101. package/dist/ui/{shared-VshXGwXP.js.map → shared-CSPhENq3.js.map} +1 -1
  102. package/dist/ui/{shared-DJrJaE73.js → shared-CZJE4Bmp.js} +3 -3
  103. package/dist/ui/{shared-DJrJaE73.js.map → shared-CZJE4Bmp.js.map} +1 -1
  104. package/dist/ui/{shared-D7ONOwI7.js → shared-C_BhUL2I.js} +7 -7
  105. package/dist/ui/{shared-D7ONOwI7.js.map → shared-C_BhUL2I.js.map} +1 -1
  106. package/dist/ui/{shared-j-2peBIB.js → shared-CbeujwdU.js} +4 -4
  107. package/dist/ui/{shared-j-2peBIB.js.map → shared-CbeujwdU.js.map} +1 -1
  108. package/dist/ui/{shared-D5GrOEa2.js → shared-Cbf-o4Dt.js} +4 -4
  109. package/dist/ui/{shared-D5GrOEa2.js.map → shared-Cbf-o4Dt.js.map} +1 -1
  110. package/dist/ui/{shared-HwiPIajr.js → shared-CdNmeNHh.js} +3 -3
  111. package/dist/ui/{shared-HwiPIajr.js.map → shared-CdNmeNHh.js.map} +1 -1
  112. package/dist/ui/{shared-ZCFt-CPb.js → shared-CdQOMD8J.js} +3 -3
  113. package/dist/ui/{shared-ZCFt-CPb.js.map → shared-CdQOMD8J.js.map} +1 -1
  114. package/dist/ui/{shared-ClhXSGGK.js → shared-CdiPYlTh.js} +2 -2
  115. package/dist/ui/{shared-ClhXSGGK.js.map → shared-CdiPYlTh.js.map} +1 -1
  116. package/dist/ui/{shared-DA8_pVRZ.js → shared-CepLAhwm.js} +2 -2
  117. package/dist/ui/{shared-DA8_pVRZ.js.map → shared-CepLAhwm.js.map} +1 -1
  118. package/dist/ui/{shared-BrYKjrnM.js → shared-Ch82h_Fu.js} +6 -6
  119. package/dist/ui/{shared-BrYKjrnM.js.map → shared-Ch82h_Fu.js.map} +1 -1
  120. package/dist/ui/{shared-C4UrE8Fb.js → shared-Chp88all.js} +3 -3
  121. package/dist/ui/{shared-C4UrE8Fb.js.map → shared-Chp88all.js.map} +1 -1
  122. package/dist/ui/{shared-CWa80DTO.js → shared-Ci16s2rN.js} +9 -9
  123. package/dist/ui/{shared-CWa80DTO.js.map → shared-Ci16s2rN.js.map} +1 -1
  124. package/dist/ui/{shared-tksTLD6Q.js → shared-CiqNkoE1.js} +5 -5
  125. package/dist/ui/{shared-tksTLD6Q.js.map → shared-CiqNkoE1.js.map} +1 -1
  126. package/dist/ui/{shared-yt7DjSrq.js → shared-CpMhOq8F.js} +2 -2
  127. package/dist/ui/{shared-yt7DjSrq.js.map → shared-CpMhOq8F.js.map} +1 -1
  128. package/dist/ui/{shared-Dm0z5WUl.js → shared-CrWv5JKH.js} +6 -6
  129. package/dist/ui/{shared-Dm0z5WUl.js.map → shared-CrWv5JKH.js.map} +1 -1
  130. package/dist/ui/{shared-CQL3FGHc.js → shared-Csfi3Pti.js} +2 -2
  131. package/dist/ui/{shared-CQL3FGHc.js.map → shared-Csfi3Pti.js.map} +1 -1
  132. package/dist/ui/{shared-BKNRbm-V.js → shared-CuZt26rm.js} +2 -2
  133. package/dist/ui/{shared-BKNRbm-V.js.map → shared-CuZt26rm.js.map} +1 -1
  134. package/dist/ui/{shared-Guq3upiR.js → shared-Cws_z-TS.js} +2 -2
  135. package/dist/ui/{shared-Guq3upiR.js.map → shared-Cws_z-TS.js.map} +1 -1
  136. package/dist/ui/{shared-Bw_qZeIj.js → shared-D1KWuCg6.js} +2 -2
  137. package/dist/ui/{shared-Bw_qZeIj.js.map → shared-D1KWuCg6.js.map} +1 -1
  138. package/dist/ui/{shared-CuCZKwXW.js → shared-D66ju_Cb.js} +23 -23
  139. package/dist/ui/{shared-CuCZKwXW.js.map → shared-D66ju_Cb.js.map} +1 -1
  140. package/dist/ui/{shared-DYfX7NSM.js → shared-DGaQZXnw.js} +2 -2
  141. package/dist/ui/{shared-DYfX7NSM.js.map → shared-DGaQZXnw.js.map} +1 -1
  142. package/dist/ui/{shared-B3Hp8tOv.js → shared-DHy41sET.js} +6 -6
  143. package/dist/ui/{shared-B3Hp8tOv.js.map → shared-DHy41sET.js.map} +1 -1
  144. package/dist/ui/{shared-CXyd7IKi.js → shared-DKEOMQ6l.js} +2 -2
  145. package/dist/ui/{shared-CXyd7IKi.js.map → shared-DKEOMQ6l.js.map} +1 -1
  146. package/dist/ui/{shared-Ccmc8YO0.js → shared-DSUICuaJ.js} +33 -33
  147. package/dist/ui/{shared-Ccmc8YO0.js.map → shared-DSUICuaJ.js.map} +1 -1
  148. package/dist/ui/{shared-CL2iw_js.js → shared-DUPMRoO0.js} +13 -13
  149. package/dist/ui/{shared-CL2iw_js.js.map → shared-DUPMRoO0.js.map} +1 -1
  150. package/dist/ui/{shared-Dtp4eRul.js → shared-DVfdm6ah.js} +2 -2
  151. package/dist/ui/{shared-Dtp4eRul.js.map → shared-DVfdm6ah.js.map} +1 -1
  152. package/dist/ui/{shared-BJ5Ex32G.js → shared-DXM7d7lJ.js} +3 -3
  153. package/dist/ui/{shared-BJ5Ex32G.js.map → shared-DXM7d7lJ.js.map} +1 -1
  154. package/dist/ui/{shared-BFr6ld0e.js → shared-DXbMlcev.js} +2 -2
  155. package/dist/ui/{shared-BFr6ld0e.js.map → shared-DXbMlcev.js.map} +1 -1
  156. package/dist/ui/{shared-BUp3jv-N.js → shared-D_SkPtJ9.js} +6 -6
  157. package/dist/ui/{shared-BUp3jv-N.js.map → shared-D_SkPtJ9.js.map} +1 -1
  158. package/dist/ui/{shared-CdNomVzH.js → shared-Dd21k2ic.js} +4 -4
  159. package/dist/ui/{shared-CdNomVzH.js.map → shared-Dd21k2ic.js.map} +1 -1
  160. package/dist/ui/{shared-gRMbxmpu.js → shared-Dh0nHtLZ.js} +8 -8
  161. package/dist/ui/{shared-gRMbxmpu.js.map → shared-Dh0nHtLZ.js.map} +1 -1
  162. package/dist/ui/{shared-BKGJgjog.js → shared-DkOdSpSK.js} +3 -3
  163. package/dist/ui/{shared-BKGJgjog.js.map → shared-DkOdSpSK.js.map} +1 -1
  164. package/dist/ui/{shared-BMsh72Uq.js → shared-Dkph5ckT.js} +2 -2
  165. package/dist/ui/{shared-BMsh72Uq.js.map → shared-Dkph5ckT.js.map} +1 -1
  166. package/dist/ui/{shared-Be1HpDOB.js → shared-Dl1_Nx--.js} +3 -3
  167. package/dist/ui/{shared-Be1HpDOB.js.map → shared-Dl1_Nx--.js.map} +1 -1
  168. package/dist/ui/{shared-BQIZWOoJ.js → shared-Dm0IGbAf.js} +2 -2
  169. package/dist/ui/{shared-BQIZWOoJ.js.map → shared-Dm0IGbAf.js.map} +1 -1
  170. package/dist/ui/{shared-DSUtcU5S.js → shared-DnIkTpPr.js} +5 -5
  171. package/dist/ui/{shared-DSUtcU5S.js.map → shared-DnIkTpPr.js.map} +1 -1
  172. package/dist/ui/{shared-DsxGbYlV.js → shared-Docl_0tq.js} +3 -3
  173. package/dist/ui/{shared-DsxGbYlV.js.map → shared-Docl_0tq.js.map} +1 -1
  174. package/dist/ui/{shared-DZskrV26.js → shared-DprrHC72.js} +2 -2
  175. package/dist/ui/{shared-DZskrV26.js.map → shared-DprrHC72.js.map} +1 -1
  176. package/dist/ui/{shared-Bmw43Hwf.js → shared-DyKsJTZs.js} +2 -2
  177. package/dist/ui/{shared-Bmw43Hwf.js.map → shared-DyKsJTZs.js.map} +1 -1
  178. package/dist/ui/{shared-BLG88Pya.js → shared-FO7vfI3F.js} +4 -4
  179. package/dist/ui/{shared-BLG88Pya.js.map → shared-FO7vfI3F.js.map} +1 -1
  180. package/dist/ui/{shared-DLSd80D1.js → shared-HalAVHjv.js} +3 -3
  181. package/dist/ui/{shared-DLSd80D1.js.map → shared-HalAVHjv.js.map} +1 -1
  182. package/dist/ui/{shared-D1mMBLdj.js → shared-JvcI-LWp.js} +15 -15
  183. package/dist/ui/{shared-D1mMBLdj.js.map → shared-JvcI-LWp.js.map} +1 -1
  184. package/dist/ui/{shared-C6Hv_4O0.js → shared-K7Ym27yg.js} +2 -2
  185. package/dist/ui/{shared-C6Hv_4O0.js.map → shared-K7Ym27yg.js.map} +1 -1
  186. package/dist/ui/{shared-B39ln7oi.js → shared-SzlnwfJO.js} +3 -3
  187. package/dist/ui/{shared-B39ln7oi.js.map → shared-SzlnwfJO.js.map} +1 -1
  188. package/dist/ui/{shared-DgPn_Jll.js → shared-TrGbd1FY.js} +3 -3
  189. package/dist/ui/{shared-DgPn_Jll.js.map → shared-TrGbd1FY.js.map} +1 -1
  190. package/dist/ui/{shared-DrFb-XtA.js → shared-WhbuObEW.js} +2 -2
  191. package/dist/ui/{shared-DrFb-XtA.js.map → shared-WhbuObEW.js.map} +1 -1
  192. package/dist/ui/{shared-DiFQljcq.js → shared-XcSKDp6N.js} +11 -11
  193. package/dist/ui/{shared-DiFQljcq.js.map → shared-XcSKDp6N.js.map} +1 -1
  194. package/dist/ui/{shared-CMAg58rY.js → shared-Z4uBJU6I.js} +7 -6
  195. package/dist/ui/shared-Z4uBJU6I.js.map +1 -0
  196. package/dist/ui/{shared-BnUptuUp.js → shared-bAgeiRa5.js} +2 -2
  197. package/dist/ui/{shared-BnUptuUp.js.map → shared-bAgeiRa5.js.map} +1 -1
  198. package/dist/ui/{shared-BxMvSjey.js → shared-cgXG7OgZ.js} +5 -5
  199. package/dist/ui/{shared-BxMvSjey.js.map → shared-cgXG7OgZ.js.map} +1 -1
  200. package/dist/ui/{shared-u4CG2kQJ.js → shared-eZ0SB_zm.js} +2 -2
  201. package/dist/ui/{shared-u4CG2kQJ.js.map → shared-eZ0SB_zm.js.map} +1 -1
  202. package/dist/ui/{shared-L90bWW8e.js → shared-frKFb79C.js} +2 -2
  203. package/dist/ui/{shared-L90bWW8e.js.map → shared-frKFb79C.js.map} +1 -1
  204. package/dist/ui/{shared-Dd34nhkw.js → shared-hAayNSRA.js} +3 -3
  205. package/dist/ui/{shared-Dd34nhkw.js.map → shared-hAayNSRA.js.map} +1 -1
  206. package/dist/ui/{shared-DzC64cpp.js → shared-j_J16p2B.js} +2 -2
  207. package/dist/ui/{shared-DzC64cpp.js.map → shared-j_J16p2B.js.map} +1 -1
  208. package/dist/ui/{shared-DX7HRIV-.js → shared-tqpl5N3g.js} +6 -6
  209. package/dist/ui/{shared-DX7HRIV-.js.map → shared-tqpl5N3g.js.map} +1 -1
  210. package/dist/ui/{shared-BS5dBMpA.js → shared-y-6_ZDts.js} +2 -2
  211. package/dist/ui/{shared-BS5dBMpA.js.map → shared-y-6_ZDts.js.map} +1 -1
  212. package/dist/ui/{shared-Cv5v_MP1.js → shared-zG6e1Rhz.js} +13 -13
  213. package/dist/ui/{shared-Cv5v_MP1.js.map → shared-zG6e1Rhz.js.map} +1 -1
  214. package/dist/ui/testing.js +1 -1
  215. package/package.json +4 -4
  216. package/dist/docs/cli-browser.md +0 -232
  217. package/dist/docs/database-browser.md +0 -115
  218. package/dist/docs/keyboard.md +0 -63
  219. package/dist/docs/mcp.md +0 -86
  220. package/dist/ui/shared-Bl_nF_IH.js.map +0 -1
  221. package/dist/ui/shared-CMAg58rY.js.map +0 -1
@@ -2,7 +2,7 @@ import { nt as Button } from "./shared-poc11xxo.js";
2
2
  import { gt as defineMessages } from "./shared-DJZjSi3J.js";
3
3
  import { t as Field } from "./shared-CERG8O1B.js";
4
4
  import { a as claimFound, i as checkStatus, l as myApplications, r as askStepUpCode, s as foundByEmail, t as addByStatus, u as openStepUp } from "./shared-CKKduWQD.js";
5
- import "./shared-CpI0Y8M5.js";
5
+ import "./shared-B4jgU8h9.js";
6
6
  import { useEffect, useId, useState } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  // packages/mistri/src/client/copy/public/components/FormStatusSurface.ts
@@ -409,4 +409,4 @@ function FormStatusSurface({ form, appName, onSignIn }) {
409
409
  }
410
410
  export { FormStatusSurface };
411
411
 
412
- //# sourceMappingURL=shared-C6Hv_4O0.js.map
412
+ //# sourceMappingURL=shared-K7Ym27yg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-C6Hv_4O0.js","names":["_Fragment"],"sources":["../../src/client/copy/public/components/FormStatusSurface.ts","../../src/client/components/FormStatusSurface.tsx"],"sourcesContent":["/** What FormStatusSurface says, in the public pages room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n signIn: 'Sign in',\n moreDetails: 'More details',\n weCanEmailACode: 'We can email a code to the address on this application. It opens its details once, for 10 minutes.',\n emailMeACode: 'Email me a code',\n codeFromTheEmail: 'Code from the email',\n showDetails: 'Show details',\n sendAnotherCode: 'Send another code',\n confirmYourAccountsEmail: 'Confirm your account’s email with the link we sent you, and applications submitted with it are found here.',\n addedToYourAccount: 'Added to your account, submitted with your email: {linked}.',\n weFound1Application: 'We found 1 application submitted with this email — is this yours?',\n weFoundApplicationsSubmitted: 'We found {openCount} applications submitted with this email — are these yours?',\n sayYesOnlyToOne: 'Say yes only to one you made: it is added to your account, where its status is shown.',\n yesItsMine: 'Yes, it’s mine',\n reference: 'Reference',\n enter: 'Enter your {label}.',\n isNowInYourAccount: '{reference} is now in your account.',\n checkYourApplication: 'Check your application',\n enterTheReferenceYouWereGiven: '{label}: enter the reference you were given and the details below. Only its status is shown.',\n yourApplications: 'Your applications',\n checkStatus: 'Check status',\n signInToAdd: 'Sign in to add it to your account and follow it there.',\n addToMyAccount: 'Add to my account',\n});\n","/**\n * A saved form's status check, as a page of its own (`/{app}/form/{key}/status`):\n * the receipt and the details that confirm it, and the state it answers.\n *\n * The server answers every wrong detail with one sentence in one time\n * (server/forms/statusCheck.ts); the page keeps it that way. It never says\n * which detail was wrong — no field turns red for a refusal, nothing typed\n * is cleared or kept selectively, and the only per-field word is \"enter it\"\n * for one left blank, which knows nothing of the application. What it shows\n * back is the state, never an input: the details stay in the fields they\n * were typed in, and in this page's memory while an \"Add to my account\"\n * may need them again.\n *\n * Signed in, a form that allows it adds the application to the account\n * (formLinkHttp.ts), and the account's own applications are listed above.\n * Where the form links by email, the applications that captured the\n * account's verified address are offered — each added only by its own Yes.\n * A step-up (statusStepUp.ts) opens more than the state: a code to the email\n * on the application, then the details the form declares.\n */\nimport { useEffect, useId, useState, type FormEvent } from 'react';\nimport { Button } from '@mistriwork/ui/Button.js';\nimport { Field } from '@mistriwork/ui/Field.js';\nimport type { FormPresentation } from './FormSurface.js';\nimport {\n addByStatus,\n askStepUpCode,\n checkStatus,\n claimFound,\n foundByEmail,\n myApplications,\n openStepUp,\n type ApplicationStatus,\n type SavedFormFailure,\n} from './savedFormApi.js';\nimport './FormSurface.css';\nimport { say } from '../copy/public/components/FormStatusSurface.js';\n\n/** A form with a status check: the details it asks, and whether a signed-in check may add the application to the account. */\nexport type StatusFormPresentation = FormPresentation & {\n save: {\n statusCheck: { confirm: Array<{ name: string; label: string }>; stepUp?: true };\n link?: { sameDevice?: true; statusCheck?: true; email?: { prove?: string } };\n };\n};\n\nconst RECEIPT = 'receipt';\nconst said = (name: string) => name.replace(/_/g, ' ').replace(/^./, (first) => first.toUpperCase());\n\n/** The state, as the check answered it: each shown column in the author's words. */\nfunction Status({ status }: { status: ApplicationStatus }) {\n return (\n <dl className=\"form-status\">\n {Object.entries(status).map(([name, words]) => (\n <div key={name}>\n <dt>{said(name)}</dt>\n <dd>{words ?? '—'}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\n/** More than the state: a code to the email on the application, then the details the form declares. */\nfunction StepUp({ form, details }: { form: string; details: () => { receipt: string; confirm: Record<string, string> } }) {\n const id = useId();\n const [sent, setSent] = useState(false);\n const [code, setCode] = useState('');\n const [shown, setShown] = useState<ApplicationStatus | null>(null);\n const [failure, setFailure] = useState('');\n const [pending, setPending] = useState(false);\n const run = async (work: () => Promise<void>) => {\n if (pending) return;\n setPending(true);\n setFailure('');\n try {\n await work();\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n const ask = () =>\n run(async () => {\n await askStepUpCode(form, details());\n setSent(true);\n setCode('');\n });\n const open = (event: FormEvent) => {\n event.preventDefault();\n void run(async () => {\n setShown((await openStepUp(form, details(), code.trim())).details);\n });\n };\n return (\n <section aria-labelledby={`${id}-more`} className=\"form-status-more\">\n <h2 id={`${id}-more`}>{say('moreDetails')}</h2>\n {shown ? (\n <Status status={shown} />\n ) : !sent ? (\n <>\n <p className=\"form-page-done-message\">{say('weCanEmailACode')}</p>\n <div>\n <Button intent=\"secondary\" onClick={() => void ask()} busy={pending}>\n {say('emailMeACode')}\n </Button>\n </div>\n </>\n ) : (\n <form noValidate onSubmit={open} className=\"command-fields\">\n <Field label={say('codeFromTheEmail')} required>\n <input\n className=\"field-control\"\n name=\"code\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n maxLength={6}\n value={code}\n onChange={(event) => setCode(event.currentTarget.value)}\n />\n </Field>\n <div className=\"form-claim-actions\">\n <Button intent=\"primary\" type=\"submit\" busy={pending}>\n {say('showDetails')}\n </Button>\n <Button intent=\"quiet\" size=\"compact\" onClick={() => void ask()}>\n {say('sendAnotherCode')}\n </Button>\n </div>\n </form>\n )}\n <p className=\"form-page-failure\" role=\"alert\" hidden={!failure}>\n {failure}\n </p>\n </section>\n );\n}\n\n/** Signed in: the applications that captured the account's verified email, each added only by its own Yes. */\nfunction FoundByEmail({ form, onAdded }: { form: string; onAdded: () => void }) {\n const id = useId();\n const [found, setFound] = useState<{ linked: string[]; found: string[]; verify: boolean } | null>(null);\n const [declined, setDeclined] = useState<string[]>([]);\n const [failure, setFailure] = useState('');\n const [pending, setPending] = useState('');\n useEffect(() => {\n let live = true;\n foundByEmail(form).then(\n (answer) => {\n if (!live) return;\n setFound(answer);\n if (answer?.linked.length) onAdded();\n },\n () => {},\n );\n return () => {\n live = false;\n };\n }, [form]);\n if (!found) return null;\n if (found.verify) return <p className=\"form-page-done-message\">{say('confirmYourAccountsEmail')}</p>;\n const open = found.found.filter((reference) => !declined.includes(reference));\n const yes = async (reference: string) => {\n setPending(reference);\n setFailure('');\n try {\n await claimFound(form, reference);\n setFound(\n (before) =>\n before && { ...before, linked: [...before.linked, reference], found: before.found.filter((item) => item !== reference) },\n );\n onAdded();\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending('');\n }\n };\n return (\n <>\n {found.linked.length > 0 && (\n <p className=\"form-page-done-message\" role=\"status\">\n {say('addedToYourAccount', { linked: found.linked.join(', ') })}\n </p>\n )}\n {open.length > 0 && (\n <section className=\"form-account\" aria-labelledby={`${id}-found`}>\n <h2 id={`${id}-found`}>\n {open.length === 1 ? say('weFound1Application') : say('weFoundApplicationsSubmitted', { openCount: open.length })}\n </h2>\n <p className=\"form-page-done-message\">{say('sayYesOnlyToOne')}</p>\n <ul>\n {open.map((reference) => (\n <li key={reference}>\n <strong>{reference}</strong>\n <span className=\"form-claim-actions\">\n <Button intent=\"secondary\" size=\"compact\" busy={pending === reference} onClick={() => void yes(reference)}>\n {say('yesItsMine')}\n </Button>\n <Button intent=\"quiet\" size=\"compact\" onClick={() => setDeclined((before) => [...before, reference])}>\n {say('common.no')}\n </Button>\n </span>\n </li>\n ))}\n </ul>\n </section>\n )}\n <p className=\"form-page-failure\" role=\"alert\" hidden={!failure}>\n {failure}\n </p>\n </>\n );\n}\n\nexport function FormStatusSurface({\n form,\n appName,\n onSignIn,\n}: {\n form: StatusFormPresentation;\n appName: string;\n /** Draw the App's sign-in here; after it the page comes back to this check. */\n onSignIn?: () => void;\n}) {\n const id = useId();\n const asked = [{ name: RECEIPT, label: say('reference') }, ...form.save.statusCheck.confirm];\n const [values, setValues] = useState<Record<string, string>>({});\n const [blank, setBlank] = useState<Record<string, string>>({});\n const [failure, setFailure] = useState('');\n const [answer, setAnswer] = useState<ApplicationStatus | null>(null);\n const [pending, setPending] = useState(false);\n const [added, setAdded] = useState('');\n /** The account's own applications: undefined until asked, null when nobody is signed in. */\n const [mine, setMine] = useState<Array<{ reference: string; status: ApplicationStatus }> | null | undefined>(\n form.save.link ? undefined : null,\n );\n const linkable = Boolean(form.save.link?.statusCheck);\n // Already the account's own: nothing to add.\n const owned = (reference: string) => Boolean(mine?.some((item) => item.reference === reference));\n\n useEffect(() => {\n if (!form.save.link) return;\n let live = true;\n myApplications(form.id).then(\n (list) => {\n if (live) setMine(list);\n },\n () => {\n if (live) setMine(null);\n },\n );\n return () => {\n live = false;\n };\n }, [form.id, form.save.link]);\n\n const details = () => ({\n receipt: (values[RECEIPT] ?? '').trim(),\n confirm: Object.fromEntries(form.save.statusCheck.confirm.map((item) => [item.name, (values[item.name] ?? '').trim()])),\n });\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n if (pending) return;\n const missing = Object.fromEntries(\n asked\n .filter((item) => !(values[item.name] ?? '').trim())\n .map((item) => [item.name, say('enter', { label: item.label.toLowerCase() })]),\n );\n setBlank(missing);\n if (Object.keys(missing).length) return;\n setPending(true);\n setFailure('');\n setAnswer(null);\n setAdded('');\n try {\n setAnswer(await checkStatus(form.id, details()));\n }\n // The server's one sentence, whichever detail it was: never a field of its own.\n catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n\n const add = async () => {\n if (pending) return;\n setPending(true);\n setFailure('');\n try {\n const reference = await addByStatus(form.id, details());\n setAdded(say('isNowInYourAccount', { reference }));\n setMine(await myApplications(form.id).catch(() => mine ?? null));\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n\n return (\n <section className=\"form-page\" aria-labelledby={`${id}-title`}>\n <p className=\"eyebrow\">{appName}</p>\n <h1 id={`${id}-title`}>{say('checkYourApplication')}</h1>\n <p className=\"form-page-description\">{say('enterTheReferenceYouWereGiven', { label: form.label })}</p>\n {form.save.link?.email && mine !== null && (\n <FoundByEmail\n form={form.id}\n onAdded={() => {\n myApplications(form.id).then(setMine, () => {});\n }}\n />\n )}\n {mine && mine.length > 0 && (\n <section className=\"form-account\" aria-labelledby={`${id}-mine`}>\n <h2 id={`${id}-mine`}>{say('yourApplications')}</h2>\n <ul>\n {mine.map((item) => (\n <li key={item.reference}>\n <strong>{item.reference}</strong>\n <Status status={item.status} />\n </li>\n ))}\n </ul>\n </section>\n )}\n <form noValidate onSubmit={submit} className=\"command-fields\">\n {asked.map((item) => (\n <Field key={item.name} label={item.label} problem={blank[item.name]} required>\n <input\n className=\"field-control\"\n name={item.name}\n autoComplete=\"off\"\n spellCheck={false}\n value={values[item.name] ?? ''}\n onChange={(event) => {\n const value = event.currentTarget.value;\n setValues((before) => ({ ...before, [item.name]: value }));\n setBlank((before) => {\n const { [item.name]: _gone, ...rest } = before;\n return rest;\n });\n }}\n />\n </Field>\n ))}\n <div>\n <Button intent=\"primary\" type=\"submit\" busy={pending && !answer}>\n {say('checkStatus')}\n </Button>\n </div>\n </form>\n <p className=\"form-page-failure\" role=\"alert\" aria-live=\"assertive\" hidden={!failure}>\n {failure}\n </p>\n {answer && (\n <section aria-labelledby={`${id}-answer`} className=\"form-status-answer\">\n <h2 id={`${id}-answer`}>{say('common.status')}</h2>\n <Status status={answer} />\n {linkable &&\n !added &&\n !owned((values[RECEIPT] ?? '').trim()) &&\n (mine === null\n ? onSignIn && (\n <p className=\"form-page-done-message\">\n {say('signInToAdd')}{' '}\n <Button intent=\"quiet\" size=\"compact\" onClick={onSignIn}>\n {say('signIn')}\n </Button>\n </p>\n )\n : mine !== undefined && (\n <div>\n <Button intent=\"secondary\" onClick={add} busy={pending}>\n {say('addToMyAccount')}\n </Button>\n </div>\n ))}\n {added && (\n <p className=\"form-page-done-message\" role=\"status\">\n {added}\n </p>\n )}\n </section>\n )}\n {answer && form.save.statusCheck.stepUp && <StepUp form={form.id} details={details} />}\n </section>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-K7Ym27yg.js","names":["_Fragment"],"sources":["../../src/client/copy/public/components/FormStatusSurface.ts","../../src/client/components/FormStatusSurface.tsx"],"sourcesContent":["/** What FormStatusSurface says, in the public pages room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n signIn: 'Sign in',\n moreDetails: 'More details',\n weCanEmailACode: 'We can email a code to the address on this application. It opens its details once, for 10 minutes.',\n emailMeACode: 'Email me a code',\n codeFromTheEmail: 'Code from the email',\n showDetails: 'Show details',\n sendAnotherCode: 'Send another code',\n confirmYourAccountsEmail: 'Confirm your account’s email with the link we sent you, and applications submitted with it are found here.',\n addedToYourAccount: 'Added to your account, submitted with your email: {linked}.',\n weFound1Application: 'We found 1 application submitted with this email — is this yours?',\n weFoundApplicationsSubmitted: 'We found {openCount} applications submitted with this email — are these yours?',\n sayYesOnlyToOne: 'Say yes only to one you made: it is added to your account, where its status is shown.',\n yesItsMine: 'Yes, it’s mine',\n reference: 'Reference',\n enter: 'Enter your {label}.',\n isNowInYourAccount: '{reference} is now in your account.',\n checkYourApplication: 'Check your application',\n enterTheReferenceYouWereGiven: '{label}: enter the reference you were given and the details below. Only its status is shown.',\n yourApplications: 'Your applications',\n checkStatus: 'Check status',\n signInToAdd: 'Sign in to add it to your account and follow it there.',\n addToMyAccount: 'Add to my account',\n});\n","/**\n * A saved form's status check, as a page of its own (`/{app}/form/{key}/status`):\n * the receipt and the details that confirm it, and the state it answers.\n *\n * The server answers every wrong detail with one sentence in one time\n * (server/forms/statusCheck.ts); the page keeps it that way. It never says\n * which detail was wrong — no field turns red for a refusal, nothing typed\n * is cleared or kept selectively, and the only per-field word is \"enter it\"\n * for one left blank, which knows nothing of the application. What it shows\n * back is the state, never an input: the details stay in the fields they\n * were typed in, and in this page's memory while an \"Add to my account\"\n * may need them again.\n *\n * Signed in, a form that allows it adds the application to the account\n * (formLinkHttp.ts), and the account's own applications are listed above.\n * Where the form links by email, the applications that captured the\n * account's verified address are offered — each added only by its own Yes.\n * A step-up (statusStepUp.ts) opens more than the state: a code to the email\n * on the application, then the details the form declares.\n */\nimport { useEffect, useId, useState, type FormEvent } from 'react';\nimport { Button } from '@mistriwork/ui/Button.js';\nimport { Field } from '@mistriwork/ui/Field.js';\nimport type { FormPresentation } from './FormSurface.js';\nimport {\n addByStatus,\n askStepUpCode,\n checkStatus,\n claimFound,\n foundByEmail,\n myApplications,\n openStepUp,\n type ApplicationStatus,\n type SavedFormFailure,\n} from './savedFormApi.js';\nimport './FormSurface.css';\nimport { say } from '../copy/public/components/FormStatusSurface.js';\n\n/** A form with a status check: the details it asks, and whether a signed-in check may add the application to the account. */\nexport type StatusFormPresentation = FormPresentation & {\n save: {\n statusCheck: { confirm: Array<{ name: string; label: string }>; stepUp?: true };\n link?: { sameDevice?: true; statusCheck?: true; email?: { prove?: string } };\n };\n};\n\nconst RECEIPT = 'receipt';\nconst said = (name: string) => name.replace(/_/g, ' ').replace(/^./, (first) => first.toUpperCase());\n\n/** The state, as the check answered it: each shown column in the author's words. */\nfunction Status({ status }: { status: ApplicationStatus }) {\n return (\n <dl className=\"form-status\">\n {Object.entries(status).map(([name, words]) => (\n <div key={name}>\n <dt>{said(name)}</dt>\n <dd>{words ?? '—'}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\n/** More than the state: a code to the email on the application, then the details the form declares. */\nfunction StepUp({ form, details }: { form: string; details: () => { receipt: string; confirm: Record<string, string> } }) {\n const id = useId();\n const [sent, setSent] = useState(false);\n const [code, setCode] = useState('');\n const [shown, setShown] = useState<ApplicationStatus | null>(null);\n const [failure, setFailure] = useState('');\n const [pending, setPending] = useState(false);\n const run = async (work: () => Promise<void>) => {\n if (pending) return;\n setPending(true);\n setFailure('');\n try {\n await work();\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n const ask = () =>\n run(async () => {\n await askStepUpCode(form, details());\n setSent(true);\n setCode('');\n });\n const open = (event: FormEvent) => {\n event.preventDefault();\n void run(async () => {\n setShown((await openStepUp(form, details(), code.trim())).details);\n });\n };\n return (\n <section aria-labelledby={`${id}-more`} className=\"form-status-more\">\n <h2 id={`${id}-more`}>{say('moreDetails')}</h2>\n {shown ? (\n <Status status={shown} />\n ) : !sent ? (\n <>\n <p className=\"form-page-done-message\">{say('weCanEmailACode')}</p>\n <div>\n <Button intent=\"secondary\" onClick={() => void ask()} busy={pending}>\n {say('emailMeACode')}\n </Button>\n </div>\n </>\n ) : (\n <form noValidate onSubmit={open} className=\"command-fields\">\n <Field label={say('codeFromTheEmail')} required>\n <input\n className=\"field-control\"\n name=\"code\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n maxLength={6}\n value={code}\n onChange={(event) => setCode(event.currentTarget.value)}\n />\n </Field>\n <div className=\"form-claim-actions\">\n <Button intent=\"primary\" type=\"submit\" busy={pending}>\n {say('showDetails')}\n </Button>\n <Button intent=\"quiet\" size=\"compact\" onClick={() => void ask()}>\n {say('sendAnotherCode')}\n </Button>\n </div>\n </form>\n )}\n <p className=\"form-page-failure\" role=\"alert\" hidden={!failure}>\n {failure}\n </p>\n </section>\n );\n}\n\n/** Signed in: the applications that captured the account's verified email, each added only by its own Yes. */\nfunction FoundByEmail({ form, onAdded }: { form: string; onAdded: () => void }) {\n const id = useId();\n const [found, setFound] = useState<{ linked: string[]; found: string[]; verify: boolean } | null>(null);\n const [declined, setDeclined] = useState<string[]>([]);\n const [failure, setFailure] = useState('');\n const [pending, setPending] = useState('');\n useEffect(() => {\n let live = true;\n foundByEmail(form).then(\n (answer) => {\n if (!live) return;\n setFound(answer);\n if (answer?.linked.length) onAdded();\n },\n () => {},\n );\n return () => {\n live = false;\n };\n }, [form]);\n if (!found) return null;\n if (found.verify) return <p className=\"form-page-done-message\">{say('confirmYourAccountsEmail')}</p>;\n const open = found.found.filter((reference) => !declined.includes(reference));\n const yes = async (reference: string) => {\n setPending(reference);\n setFailure('');\n try {\n await claimFound(form, reference);\n setFound(\n (before) =>\n before && { ...before, linked: [...before.linked, reference], found: before.found.filter((item) => item !== reference) },\n );\n onAdded();\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending('');\n }\n };\n return (\n <>\n {found.linked.length > 0 && (\n <p className=\"form-page-done-message\" role=\"status\">\n {say('addedToYourAccount', { linked: found.linked.join(', ') })}\n </p>\n )}\n {open.length > 0 && (\n <section className=\"form-account\" aria-labelledby={`${id}-found`}>\n <h2 id={`${id}-found`}>\n {open.length === 1 ? say('weFound1Application') : say('weFoundApplicationsSubmitted', { openCount: open.length })}\n </h2>\n <p className=\"form-page-done-message\">{say('sayYesOnlyToOne')}</p>\n <ul>\n {open.map((reference) => (\n <li key={reference}>\n <strong>{reference}</strong>\n <span className=\"form-claim-actions\">\n <Button intent=\"secondary\" size=\"compact\" busy={pending === reference} onClick={() => void yes(reference)}>\n {say('yesItsMine')}\n </Button>\n <Button intent=\"quiet\" size=\"compact\" onClick={() => setDeclined((before) => [...before, reference])}>\n {say('common.no')}\n </Button>\n </span>\n </li>\n ))}\n </ul>\n </section>\n )}\n <p className=\"form-page-failure\" role=\"alert\" hidden={!failure}>\n {failure}\n </p>\n </>\n );\n}\n\nexport function FormStatusSurface({\n form,\n appName,\n onSignIn,\n}: {\n form: StatusFormPresentation;\n appName: string;\n /** Draw the App's sign-in here; after it the page comes back to this check. */\n onSignIn?: () => void;\n}) {\n const id = useId();\n const asked = [{ name: RECEIPT, label: say('reference') }, ...form.save.statusCheck.confirm];\n const [values, setValues] = useState<Record<string, string>>({});\n const [blank, setBlank] = useState<Record<string, string>>({});\n const [failure, setFailure] = useState('');\n const [answer, setAnswer] = useState<ApplicationStatus | null>(null);\n const [pending, setPending] = useState(false);\n const [added, setAdded] = useState('');\n /** The account's own applications: undefined until asked, null when nobody is signed in. */\n const [mine, setMine] = useState<Array<{ reference: string; status: ApplicationStatus }> | null | undefined>(\n form.save.link ? undefined : null,\n );\n const linkable = Boolean(form.save.link?.statusCheck);\n // Already the account's own: nothing to add.\n const owned = (reference: string) => Boolean(mine?.some((item) => item.reference === reference));\n\n useEffect(() => {\n if (!form.save.link) return;\n let live = true;\n myApplications(form.id).then(\n (list) => {\n if (live) setMine(list);\n },\n () => {\n if (live) setMine(null);\n },\n );\n return () => {\n live = false;\n };\n }, [form.id, form.save.link]);\n\n const details = () => ({\n receipt: (values[RECEIPT] ?? '').trim(),\n confirm: Object.fromEntries(form.save.statusCheck.confirm.map((item) => [item.name, (values[item.name] ?? '').trim()])),\n });\n\n const submit = async (event: FormEvent) => {\n event.preventDefault();\n if (pending) return;\n const missing = Object.fromEntries(\n asked\n .filter((item) => !(values[item.name] ?? '').trim())\n .map((item) => [item.name, say('enter', { label: item.label.toLowerCase() })]),\n );\n setBlank(missing);\n if (Object.keys(missing).length) return;\n setPending(true);\n setFailure('');\n setAnswer(null);\n setAdded('');\n try {\n setAnswer(await checkStatus(form.id, details()));\n }\n // The server's one sentence, whichever detail it was: never a field of its own.\n catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n\n const add = async () => {\n if (pending) return;\n setPending(true);\n setFailure('');\n try {\n const reference = await addByStatus(form.id, details());\n setAdded(say('isNowInYourAccount', { reference }));\n setMine(await myApplications(form.id).catch(() => mine ?? null));\n } catch (error) {\n setFailure((error as SavedFormFailure).message);\n } finally {\n setPending(false);\n }\n };\n\n return (\n <section className=\"form-page\" aria-labelledby={`${id}-title`}>\n <p className=\"eyebrow\">{appName}</p>\n <h1 id={`${id}-title`}>{say('checkYourApplication')}</h1>\n <p className=\"form-page-description\">{say('enterTheReferenceYouWereGiven', { label: form.label })}</p>\n {form.save.link?.email && mine !== null && (\n <FoundByEmail\n form={form.id}\n onAdded={() => {\n myApplications(form.id).then(setMine, () => {});\n }}\n />\n )}\n {mine && mine.length > 0 && (\n <section className=\"form-account\" aria-labelledby={`${id}-mine`}>\n <h2 id={`${id}-mine`}>{say('yourApplications')}</h2>\n <ul>\n {mine.map((item) => (\n <li key={item.reference}>\n <strong>{item.reference}</strong>\n <Status status={item.status} />\n </li>\n ))}\n </ul>\n </section>\n )}\n <form noValidate onSubmit={submit} className=\"command-fields\">\n {asked.map((item) => (\n <Field key={item.name} label={item.label} problem={blank[item.name]} required>\n <input\n className=\"field-control\"\n name={item.name}\n autoComplete=\"off\"\n spellCheck={false}\n value={values[item.name] ?? ''}\n onChange={(event) => {\n const value = event.currentTarget.value;\n setValues((before) => ({ ...before, [item.name]: value }));\n setBlank((before) => {\n const { [item.name]: _gone, ...rest } = before;\n return rest;\n });\n }}\n />\n </Field>\n ))}\n <div>\n <Button intent=\"primary\" type=\"submit\" busy={pending && !answer}>\n {say('checkStatus')}\n </Button>\n </div>\n </form>\n <p className=\"form-page-failure\" role=\"alert\" aria-live=\"assertive\" hidden={!failure}>\n {failure}\n </p>\n {answer && (\n <section aria-labelledby={`${id}-answer`} className=\"form-status-answer\">\n <h2 id={`${id}-answer`}>{say('common.status')}</h2>\n <Status status={answer} />\n {linkable &&\n !added &&\n !owned((values[RECEIPT] ?? '').trim()) &&\n (mine === null\n ? onSignIn && (\n <p className=\"form-page-done-message\">\n {say('signInToAdd')}{' '}\n <Button intent=\"quiet\" size=\"compact\" onClick={onSignIn}>\n {say('signIn')}\n </Button>\n </p>\n )\n : mine !== undefined && (\n <div>\n <Button intent=\"secondary\" onClick={add} busy={pending}>\n {say('addToMyAccount')}\n </Button>\n </div>\n ))}\n {added && (\n <p className=\"form-page-done-message\" role=\"status\">\n {added}\n </p>\n )}\n </section>\n )}\n {answer && form.save.statusCheck.stepUp && <StepUp form={form.id} details={details} />}\n </section>\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { x as fetchServer } from "./shared-poc11xxo.js";
2
2
  import { gt as defineMessages, ut as humanName } from "./shared-DJZjSi3J.js";
3
- import { a as commandInput, f as readyToJudge, u as prefilledCommandValues } from "./shared-D1mMBLdj.js";
4
- import { attemptKey } from "./shared-lYtMadRU.js";
3
+ import { a as commandInput, f as readyToJudge, u as prefilledCommandValues } from "./shared-JvcI-LWp.js";
4
+ import { attemptKey } from "./shared-B1SAS_J-.js";
5
5
  // packages/mistri/src/client/copy/components/components/sdk/publicPageCommand.ts
6
6
  /** What sdk/publicPageCommand says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */
7
7
  var say = defineMessages({
@@ -130,4 +130,4 @@ function publicPageCommand(page, id, reference) {
130
130
  }
131
131
  export { publicPageCommand };
132
132
 
133
- //# sourceMappingURL=shared-B39ln7oi.js.map
133
+ //# sourceMappingURL=shared-SzlnwfJO.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-B39ln7oi.js","names":[],"sources":["../../src/client/copy/components/components/sdk/publicPageCommand.ts","../../src/client/components/sdk/publicPageCommand.ts"],"sourcesContent":["/** What sdk/publicPageCommand says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n isNotSomethingYouCanDo: '{label} is not something you can do here.',\n publicNotSent: '{label} could not be sent. Check your connection and try again.',\n publicNotKnown: '{label} was sent, and no answer came back. Check before you send it again.',\n});\n","/**\n * A public page's command (`definePage({ public: true, commands })`), as its `useCommand` holds it: run through the\n * page's own door (server http/pageCommandRoutes.ts) as the public principal, whoever is signed in. The input is\n * checked by the command's declaration first, as a form's submit checks it; the page's ticket is asked when the\n * handle is made and sent with the run, held back until it is old enough to be a person's (3 seconds); a refused\n * ticket is asked again once. A challenge's token, where the page draws a human check, is `run(record, input,\n * { challenge })`. The answer is the door's public shape — the reference to quote — never the input. An answer that\n * never came, or a server that could not say, is `unknown`: its `check()` sends the same submission again, which the\n * door answers with the run it already has, so nothing is sent twice under two keys (`attempt` keeps the key across a\n * reload).\n */\nimport type { AppFormCommandReference } from '../../../shared/command.js';\nimport { fetchServer } from '@mistriwork/kit/client/transport.js';\nimport { humanName } from '@mistriwork/engine/shared/model.js';\nimport { commandInput, prefilledCommandValues, readyToJudge } from '../CommandFields.js';\nimport type { UiCommandHandle, UiCommandOptions, UiCommandOutcome } from './context.js';\nimport { attemptKey } from './formCommandRun.js';\nimport { say } from '../../copy/components/components/sdk/publicPageCommand.js';\n\n/* The ticket's floor (server forms/publicTicket.ts), and a margin for the two clocks. */\nconst TICKET_AGE_MS = 3_200;\n\n/* What the door refuses before it runs anything (http/pageCommandRoutes.ts): said again on a check, they prove nothing. */\nconst BEFORE_THE_RUN = new Set(['rate_limited', 'ticket_refused', 'challenge_failed']);\n\nconst wait = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\ninterface Ticket {\n ticket: string;\n at: number;\n}\n\nasync function askTicket(page: string): Promise<Ticket | undefined> {\n try {\n const res = await fetchServer(`/api/pages/${encodeURIComponent(page)}/ticket`, {\n credentials: 'same-origin',\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) return undefined;\n const body = (await res.json()) as { ticket?: unknown };\n return typeof body.ticket === 'string' ? { ticket: body.ticket, at: Date.now() } : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The public command `id` of the public page `page`, served as `reference`. */\nexport function publicPageCommand(page: string, id: string, reference: AppFormCommandReference): UiCommandHandle {\n let ticket: Promise<Ticket | undefined> = askTicket(page);\n const label = humanName(id);\n\n const send = async (input: Record<string, unknown>, submission: string, options: UiCommandOptions) => {\n let held = await ticket;\n if (!held) held = await (ticket = askTicket(page));\n if (!held) return { status: 0, body: {} as Record<string, unknown> };\n const young = TICKET_AGE_MS - (Date.now() - held.at);\n if (young > 0) await wait(young);\n const res = await fetchServer(`/api/pages/${encodeURIComponent(page)}/commands/${encodeURIComponent(id)}`, {\n method: 'POST',\n credentials: 'same-origin',\n signal: AbortSignal.timeout(30_000),\n headers: {\n 'content-type': 'application/json',\n 'x-mistri-ticket': held.ticket,\n ...(options.challenge ? { 'x-mistri-challenge': options.challenge } : {}),\n },\n body: JSON.stringify({ input, submission }),\n });\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n return { status: res.status, body };\n };\n\n /* One run, one submission key: sent again under it, the door answers a run it already has with its receipt. A\n check sends it again, so what the door refuses before any run (this client's budget, a human check's spent token)\n says nothing of the first send: it is still not known. */\n const deliver = async (\n input: Record<string, unknown>,\n submission: string,\n options: UiCommandOptions,\n checking: boolean,\n ): Promise<UiCommandOutcome> => {\n const said = options.label || label;\n const unknown = (message = say('publicNotKnown', { label: said })): UiCommandOutcome => ({\n status: 'unknown',\n message,\n check: (again) => deliver(input, submission, { ...options, ...again }, true),\n });\n let answer: Awaited<ReturnType<typeof send>>;\n try {\n answer = await send(input, submission, options);\n /* A ticket the server no longer takes (a restart, a day open): asked again, and the run sent once more under the\n same submission key, so it can never be two. */\n if (answer.status === 403 && answer.body.code === 'ticket_refused') {\n ticket = askTicket(page);\n answer = await send(input, submission, options);\n }\n } catch {\n // Sent, and no answer came: whether it ran is not known, and only the same submission asked again can say.\n return unknown();\n }\n if (answer.status === 200 && typeof answer.body.reference === 'string')\n return { status: 'applied', output: { reference: answer.body.reference, receipt: answer.body.receipt } };\n // No ticket, so nothing was sent this time: on a first run that is a refusal, on a check the first is still not known.\n if (answer.status === 0) return checking ? unknown() : { status: 'refused', message: say('publicNotSent', { label: said }) };\n if (answer.status >= 500) return unknown();\n const message = typeof answer.body.error === 'string' ? answer.body.error : say('isNotSomethingYouCanDo', { label: said });\n if (checking && BEFORE_THE_RUN.has(String(answer.body.code))) return unknown(message);\n return { status: 'refused', message };\n };\n\n const run = async (\n _record: Readonly<Record<string, unknown>>,\n given?: Readonly<Record<string, unknown>>,\n options: UiCommandOptions = {},\n ): Promise<UiCommandOutcome> => {\n const submission = attemptKey(options);\n // The declaration's own rules, once what judges a `when` is here; the command's rules over the draft are the server's.\n const judging = readyToJudge(reference.input);\n if (judging) await judging;\n let input: Record<string, unknown>;\n try {\n input = commandInput(reference.input, prefilledCommandValues(reference.input, given ?? {}));\n } catch (error) {\n return { status: 'refused', message: (error as Error).message };\n }\n return deliver(input, submission, options, false);\n };\n\n return { label, granted: true, available: async () => true, run, open: run };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-SzlnwfJO.js","names":[],"sources":["../../src/client/copy/components/components/sdk/publicPageCommand.ts","../../src/client/components/sdk/publicPageCommand.ts"],"sourcesContent":["/** What sdk/publicPageCommand says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n isNotSomethingYouCanDo: '{label} is not something you can do here.',\n publicNotSent: '{label} could not be sent. Check your connection and try again.',\n publicNotKnown: '{label} was sent, and no answer came back. Check before you send it again.',\n});\n","/**\n * A public page's command (`definePage({ public: true, commands })`), as its `useCommand` holds it: run through the\n * page's own door (server http/pageCommandRoutes.ts) as the public principal, whoever is signed in. The input is\n * checked by the command's declaration first, as a form's submit checks it; the page's ticket is asked when the\n * handle is made and sent with the run, held back until it is old enough to be a person's (3 seconds); a refused\n * ticket is asked again once. A challenge's token, where the page draws a human check, is `run(record, input,\n * { challenge })`. The answer is the door's public shape — the reference to quote — never the input. An answer that\n * never came, or a server that could not say, is `unknown`: its `check()` sends the same submission again, which the\n * door answers with the run it already has, so nothing is sent twice under two keys (`attempt` keeps the key across a\n * reload).\n */\nimport type { AppFormCommandReference } from '../../../shared/command.js';\nimport { fetchServer } from '@mistriwork/kit/client/transport.js';\nimport { humanName } from '@mistriwork/engine/shared/model.js';\nimport { commandInput, prefilledCommandValues, readyToJudge } from '../CommandFields.js';\nimport type { UiCommandHandle, UiCommandOptions, UiCommandOutcome } from './context.js';\nimport { attemptKey } from './formCommandRun.js';\nimport { say } from '../../copy/components/components/sdk/publicPageCommand.js';\n\n/* The ticket's floor (server forms/publicTicket.ts), and a margin for the two clocks. */\nconst TICKET_AGE_MS = 3_200;\n\n/* What the door refuses before it runs anything (http/pageCommandRoutes.ts): said again on a check, they prove nothing. */\nconst BEFORE_THE_RUN = new Set(['rate_limited', 'ticket_refused', 'challenge_failed']);\n\nconst wait = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));\n\ninterface Ticket {\n ticket: string;\n at: number;\n}\n\nasync function askTicket(page: string): Promise<Ticket | undefined> {\n try {\n const res = await fetchServer(`/api/pages/${encodeURIComponent(page)}/ticket`, {\n credentials: 'same-origin',\n signal: AbortSignal.timeout(15_000),\n });\n if (!res.ok) return undefined;\n const body = (await res.json()) as { ticket?: unknown };\n return typeof body.ticket === 'string' ? { ticket: body.ticket, at: Date.now() } : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The public command `id` of the public page `page`, served as `reference`. */\nexport function publicPageCommand(page: string, id: string, reference: AppFormCommandReference): UiCommandHandle {\n let ticket: Promise<Ticket | undefined> = askTicket(page);\n const label = humanName(id);\n\n const send = async (input: Record<string, unknown>, submission: string, options: UiCommandOptions) => {\n let held = await ticket;\n if (!held) held = await (ticket = askTicket(page));\n if (!held) return { status: 0, body: {} as Record<string, unknown> };\n const young = TICKET_AGE_MS - (Date.now() - held.at);\n if (young > 0) await wait(young);\n const res = await fetchServer(`/api/pages/${encodeURIComponent(page)}/commands/${encodeURIComponent(id)}`, {\n method: 'POST',\n credentials: 'same-origin',\n signal: AbortSignal.timeout(30_000),\n headers: {\n 'content-type': 'application/json',\n 'x-mistri-ticket': held.ticket,\n ...(options.challenge ? { 'x-mistri-challenge': options.challenge } : {}),\n },\n body: JSON.stringify({ input, submission }),\n });\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n return { status: res.status, body };\n };\n\n /* One run, one submission key: sent again under it, the door answers a run it already has with its receipt. A\n check sends it again, so what the door refuses before any run (this client's budget, a human check's spent token)\n says nothing of the first send: it is still not known. */\n const deliver = async (\n input: Record<string, unknown>,\n submission: string,\n options: UiCommandOptions,\n checking: boolean,\n ): Promise<UiCommandOutcome> => {\n const said = options.label || label;\n const unknown = (message = say('publicNotKnown', { label: said })): UiCommandOutcome => ({\n status: 'unknown',\n message,\n check: (again) => deliver(input, submission, { ...options, ...again }, true),\n });\n let answer: Awaited<ReturnType<typeof send>>;\n try {\n answer = await send(input, submission, options);\n /* A ticket the server no longer takes (a restart, a day open): asked again, and the run sent once more under the\n same submission key, so it can never be two. */\n if (answer.status === 403 && answer.body.code === 'ticket_refused') {\n ticket = askTicket(page);\n answer = await send(input, submission, options);\n }\n } catch {\n // Sent, and no answer came: whether it ran is not known, and only the same submission asked again can say.\n return unknown();\n }\n if (answer.status === 200 && typeof answer.body.reference === 'string')\n return { status: 'applied', output: { reference: answer.body.reference, receipt: answer.body.receipt } };\n // No ticket, so nothing was sent this time: on a first run that is a refusal, on a check the first is still not known.\n if (answer.status === 0) return checking ? unknown() : { status: 'refused', message: say('publicNotSent', { label: said }) };\n if (answer.status >= 500) return unknown();\n const message = typeof answer.body.error === 'string' ? answer.body.error : say('isNotSomethingYouCanDo', { label: said });\n if (checking && BEFORE_THE_RUN.has(String(answer.body.code))) return unknown(message);\n return { status: 'refused', message };\n };\n\n const run = async (\n _record: Readonly<Record<string, unknown>>,\n given?: Readonly<Record<string, unknown>>,\n options: UiCommandOptions = {},\n ): Promise<UiCommandOutcome> => {\n const submission = attemptKey(options);\n // The declaration's own rules, once what judges a `when` is here; the command's rules over the draft are the server's.\n const judging = readyToJudge(reference.input);\n if (judging) await judging;\n let input: Record<string, unknown>;\n try {\n input = commandInput(reference.input, prefilledCommandValues(reference.input, given ?? {}));\n } catch (error) {\n return { status: 'refused', message: (error as Error).message };\n }\n return deliver(input, submission, options, false);\n };\n\n return { label, granted: true, available: async () => true, run, open: run };\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { Q as Problem, Z as Empty$1, ht as Icon$1, it as useQuery } from "./shared-poc11xxo.js";
2
2
  import { $t as formatWholeMoney, Jt as formatNumber, K as minorFigure, Rt as defaultCurrency, St as subscribeMessages, Ut as formatDate, Wt as formatDateTime, Xt as formatRelativeDay, Yt as formatPercent, d as dressFor, gt as defineMessages, i as UiSizeContext, o as useUiHost, qt as formatMoney, r as UiPageContext, s as authoredDisplay, vt as messageLanguage, zt as formatAbsolute } from "./shared-DJZjSi3J.js";
3
- import { i as Said, n as Dressed } from "./shared-Q5WefT7G.js";
3
+ import { i as Said, n as Dressed } from "./shared-CMjK-Ucd.js";
4
4
  import { t as Modal } from "./shared-CRr4kJXB.js";
5
- import { i as Sparkline, o as StackedColumns } from "./shared-CXyd7IKi.js";
5
+ import { i as Sparkline, o as StackedColumns } from "./shared-DKEOMQ6l.js";
6
6
  import "./shared-gtzTT5Z7.js";
7
7
  import { t as BesideDetail } from "./shared-DU0gdEdw.js";
8
8
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
@@ -796,4 +796,4 @@ function useSectionSize() {
796
796
  }
797
797
  export { Tone as A, Loaded as C, Stack as D, Segmented as E, SplitListDetail as M, Stat as O, Icon as S, Row as T, useVisitor as _, useComposer as a, Empty as b, useFormat as c, useNavigate as d, useRecord as f, useViewer as g, useToken as h, useCommand as i, Value as j, Table as k, useLook as l, useSectionSize as m, useAnalytics as n, useFile as o, useRows as p, useBreakdown as r, useFlags as s, useAddressState as t, useMessage as u, Card as v, Meter as w, Heading as x, Columns as y };
798
798
 
799
- //# sourceMappingURL=shared-DgPn_Jll.js.map
799
+ //# sourceMappingURL=shared-TrGbd1FY.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared-DgPn_Jll.js","names":["say","say","_Fragment","say","PlatformEmpty","sayKit","_Fragment","PlatformIcon"],"sources":["../../src/client/copy/components/components/sdk/kit.ts","../../src/client/copy/lists/components/SplitListDetail.ts","../../src/client/components/SplitListDetail.tsx","../../src/client/components/sdk/kit.tsx","../../src/client/copy/components/components/sdk/hooks.ts","../../src/client/components/sdk/hooks.ts"],"sourcesContent":["/** What sdk/kit says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n nothingHereYet: 'Nothing here yet.',\n notRead: 'This could not be read.',\n});\n","/** What SplitListDetail says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n close: 'Close {title}',\n details: 'Details',\n list: 'List',\n selectARecordToSee: 'Select a record to see its details.',\n});\n","/**\n * A bounded host for collection workspaces.\n *\n * The list owns selection and navigation; this component owns only the\n * presentation seam around the selected detail. Where the host has room the\n * detail is a sibling pane beside the list, and where it does not (a\n * container query on the host, SplitListDetail.css) the pane goes under it.\n * On a phone the same host falls back to the existing Modal primitive, so\n * callers do not invent a second dialog or focus/escape implementation. One\n * branch is mounted at a time: an editor is never duplicated with two\n * competing owners.\n */\nimport { useCallback, useSyncExternalStore, type ReactNode } from 'react';\nimport { BesideDetail } from '@mistriwork/kit/client/components/besideDetail.js';\nimport { Modal } from '@mistriwork/ui/Modal.js';\nimport { say } from '../copy/lists/components/SplitListDetail.js';\n\nconst MOBILE_QUERY = '(max-width: 760px)';\n\ninterface SplitListDetailProps {\n /** The collection surface. It remains mounted while a detail is open. */\n list: ReactNode;\n /** The selected record surface, usually an owned PageView or RecordModal body. */\n detail?: ReactNode;\n /** The selected record's controls, drawn in the detail's head between its title and Close. */\n detailActions?: ReactNode;\n /** Whether the detail pane should be presented. */\n selected?: boolean;\n /** Stable name for the detail surface and its close control. */\n detailTitle?: string;\n /** Called only while the host's owner is still current. */\n onCloseDetail?: () => void;\n /** Optional lifetime fence supplied by PageRoom/RecordModal hosts. */\n isCurrent?: () => boolean;\n /** Accessible names for the two regions. */\n listLabel?: string;\n detailLabel?: string;\n /** Compact navigation list, with remaining space reserved for the editor. */\n listWidth?: 'balanced' | 'compact';\n /** Use all available space for the collection until a record is selected. */\n expandList?: boolean;\n className?: string;\n /** The detail's title reads as the record's own name, in sentence case, not as the kit's small-caps eyebrow. */\n sentenceTitle?: boolean;\n}\n\nfunction mobileSnapshot(): boolean {\n return typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(MOBILE_QUERY).matches : false;\n}\n\nfunction subscribeMobile(listener: () => void): () => void {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return () => {};\n const query = window.matchMedia(MOBILE_QUERY);\n query.addEventListener?.('change', listener);\n /* Older WebKit has the deprecated listener pair but no addEventListener. */\n if (!query.addEventListener) query.addListener(listener);\n return () => {\n query.removeEventListener?.('change', listener);\n if (!query.removeEventListener) query.removeListener(listener);\n };\n}\n\nfunction DetailContent({\n title,\n detail,\n actions,\n onClose,\n}: {\n title: string;\n detail?: ReactNode;\n actions?: ReactNode;\n onClose: () => void;\n}) {\n return (\n <>\n <div className=\"split-list-detail-head\">\n <h2 className=\"split-list-detail-title\">{title}</h2>\n {actions && <div className=\"split-list-detail-actions\">{actions}</div>}\n <button\n type=\"button\"\n className=\"ghost split-list-detail-close\"\n aria-label={say('close', { title: title.toLowerCase() })}\n onClick={onClose}\n >\n ×\n </button>\n </div>\n <div className=\"split-list-detail-body\">{detail}</div>\n </>\n );\n}\n\nexport function SplitListDetail({\n list,\n detail,\n detailActions,\n selected = false,\n detailTitle = say('details'),\n onCloseDetail,\n isCurrent,\n listLabel = say('list'),\n detailLabel = say('details'),\n listWidth = 'balanced',\n expandList = false,\n className = '',\n sentenceTitle = false,\n}: SplitListDetailProps) {\n const mobile = useSyncExternalStore(subscribeMobile, mobileSnapshot, () => false);\n const close = useCallback(() => {\n if (isCurrent && !isCurrent()) return;\n onCloseDetail?.();\n }, [isCurrent, onCloseDetail]);\n const classes = [\n 'split-list-detail',\n listWidth === 'compact' ? 'split-list-detail-compact' : '',\n expandList ? 'split-list-detail-expand' : '',\n sentenceTitle ? 'split-list-detail-sentence' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className=\"split-list-detail-host\">\n <div className={classes} data-selected={selected ? 'true' : 'false'}>\n <section className=\"split-list-detail-list\" aria-label={listLabel}>\n <BesideDetail.Provider value={selected && !mobile}>{list}</BesideDetail.Provider>\n </section>\n {!mobile && (\n <aside className=\"split-list-detail-pane\" aria-label={detailLabel}>\n {selected ? (\n <DetailContent title={detailTitle} detail={detail} actions={detailActions} onClose={close} />\n ) : (\n <p className=\"split-list-detail-empty\" role=\"status\">\n {say('selectARecordToSee')}\n </p>\n )}\n </aside>\n )}\n {mobile && selected && (\n <Modal\n className={`split-list-detail-modal${sentenceTitle ? ' split-list-detail-sentence' : ''}`}\n fullscreen=\"mobile\"\n ariaLabel={detailLabel}\n onClose={close}\n >\n <DetailContent title={detailTitle} detail={detail} actions={detailActions} onClose={close} />\n </Modal>\n )}\n </div>\n </div>\n );\n}\n","/**\n * The kit a custom component draws with: the platform's own pieces, dressed\n * in the classes every look already dresses, so a component reads as part of\n * the App in all three looks, light and dark, without a colour of its own.\n *\n * Each takes explicit props. The column a `Value` belongs to and how its App\n * dresses it come from the host (context.ts), never from the walk's globals,\n * so the same piece draws in the page and in a component's tests. Layout\n * follows docs/design.md: one box, never a box in a box (a `Card` inside a\n * `Card` draws as a plain group); the 20px field gap and the 40px section\n * seam as `Stack`'s two gaps; a tone is a dot and its word.\n */\nimport {\n createContext,\n useContext,\n useEffect,\n useRef,\n type ComponentProps,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport type { AppIconName } from '@mistriwork/engine/shared/appIcons.js';\nimport { Icon as PlatformIcon } from '@mistriwork/kit/client/components/Icon.js';\nimport { Empty as PlatformEmpty, Problem } from '@mistriwork/kit/client/components/Notes.js';\nimport { Dressed, Said } from '@mistriwork/kit/client/components/Dressed.js';\nimport { authoredDisplay, dressFor, type DisplayRule } from '@mistriwork/kit/client/components/valueModel.js';\nimport { useUiHost } from './context.js';\n/* Named apart: `say` is also Sparkline's prop below, a figure's speaker. */\nimport { say as sayKit } from '../../copy/components/components/sdk/kit.js';\nimport { Sparkline, StackedColumns } from '@mistriwork/kit/client/components/Chart.js';\n\nexport { Button } from '@mistriwork/ui/Button.js';\nexport { Dropdown } from '@mistriwork/kit/client/components/Dropdown.js';\nexport { SplitListDetail } from '../SplitListDetail.js';\n\ntype Gap = 'tight' | 'field' | 'section';\nconst GAPS: Record<Gap, string> = { tight: 'kit-gap-tight', field: 'kit-gap-field', section: 'kit-gap-section' };\n\nconst InCard = createContext(false);\n\n/** One box: a hairline and the surface. A card inside a card is a plain group, as design.md's refusal list asks. */\nexport function Card({ title, children, className }: { title?: ReactNode; children?: ReactNode; className?: string }) {\n const nested = useContext(InCard);\n const classes = [nested ? 'kit-group' : 'kit-card', className].filter(Boolean).join(' ');\n return (\n <div className={classes}>\n {title !== undefined && <h3 className=\"kit-card-title\">{title}</h3>}\n <InCard.Provider value={true}>{children}</InCard.Provider>\n </div>\n );\n}\n\n/** Children one under another, a field's 20px apart (default), a section's 40px, or tight. */\nexport function Stack({\n gap = 'field',\n as: Tag = 'div',\n children,\n className,\n}: {\n gap?: Gap;\n as?: 'div' | 'ul' | 'ol';\n children?: ReactNode;\n className?: string;\n}) {\n return <Tag className={['kit-stack', GAPS[gap], className].filter(Boolean).join(' ')}>{children}</Tag>;\n}\n\n/** Children side by side, wrapping onto a new line where there is no room. `foot` says the row is the page's actions\n at the screen's foot (a sticky row of verbs on a phone): a notice stands above it, as above a record's bar, and\n never over the verbs it reports on. */\nexport function Row({\n gap = 'field',\n align = 'center',\n foot,\n children,\n className,\n}: {\n gap?: Gap;\n align?: 'start' | 'center' | 'baseline' | 'end';\n foot?: boolean;\n children?: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={['kit-row', GAPS[gap], `kit-align-${align}`, className].filter(Boolean).join(' ')}\n {...(foot ? { 'data-foot-actions': '' } : {})}\n >\n {children}\n </div>\n );\n}\n\n/** A heading inside a section: the section's own title is its h2, so this is an h3 by default. */\nexport function Heading({ level = 3, children, className }: { level?: 3 | 4; children?: ReactNode; className?: string }) {\n const Tag = level === 4 ? 'h4' : 'h3';\n return <Tag className={['kit-heading', className].filter(Boolean).join(' ')}>{children}</Tag>;\n}\n\nexport type ToneName = 'good' | 'warn' | 'bad' | 'info' | 'neutral';\n\n/** A meaning as the looks say one: a dot and its word. Earned, like a display rule's tone. */\nexport function Tone({ tone, children }: { tone: ToneName; children?: ReactNode }) {\n return <span className={`tone tone-${tone}`}>{children}</span>;\n}\n\n/**\n * A value, drawn as the App draws it: name the resource and the column and\n * its display rule dresses it (money, a tone, a relative day), or pass\n * `display` to say one here. An id past 2^53 arrives as a string and keeps\n * every digit; nothing here runs it through Number().\n */\nexport function Value({\n value,\n resource,\n column,\n display,\n compact = false,\n}: {\n value: unknown;\n resource?: string;\n column?: string;\n display?: Omit<DisplayRule, 'bar' | 'max'> & { bar?: boolean | number };\n compact?: boolean;\n}) {\n const host = useUiHost();\n const known = resource && column ? host.column(resource, column) : undefined;\n if (value === null || value === undefined || value === '') return <span className=\"null\">—</span>;\n const rule = authoredDisplay(display) ?? known?.rule ?? null;\n const dress = dressFor(rule, value);\n if (dress) return <Dressed dress={dress} compact={compact} />;\n return <Said col={known?.meta} value={value} compact={compact} app={host.app} />;\n}\n\n/** A share of a whole as a bar and its figure: `value` against `max` (100 by default), in a tone when it means something. */\nexport function Meter({ value, max = 100, tone, label }: { value: number; max?: number; tone?: ToneName; label?: ReactNode }) {\n const fill = max > 0 && Number.isFinite(value) ? Math.max(0, Math.min(100, (value / max) * 100)) : 0;\n const style: CSSProperties = { width: `${fill}%` };\n return (\n <span\n className={`meter-wrap${tone ? ` meter-${tone}` : ''}`}\n role=\"meter\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-label={typeof label === 'string' ? label : undefined}\n >\n <span className=\"pct-bar\">\n <span className=\"pct-fill\" style={style} />\n </span>\n {label !== undefined && <span className=\"num-value\">{label}</span>}\n </span>\n );\n}\n\n/** What a component says when it has nothing to draw: the platform's own quiet note. */\nexport function Empty({ title, description, action }: { title: ReactNode; description?: ReactNode; action?: ReactNode }) {\n return <PlatformEmpty text={title} detail={description} action={action} />;\n}\n\n/** What `<Loaded>` reads of a read: a hook's query (`useRows`, `useRecord`, `useBreakdown`) as it stands. */\ninterface LoadedQuery<T> {\n data: T | undefined;\n isError: boolean;\n error: Error | null;\n refetch(): unknown;\n}\n\n/**\n * A read's states before its drawing, said as every section says them: the platform's placeholder while it is asked\n * (at `height`, the size the drawing will take, so nothing under it moves when it lands), `Empty` for no rows or no\n * record (`empty`, or the house sentence), and the house problem with Try again when it could not be read — focus on\n * Try again when the drawing it replaced held it, so focus is never dropped. Then `children(data)`, the App's own.\n * What was read stays drawn when a later refresh fails: a finished screen is never swapped for a note. Domain states\n * (\"not eligible\", \"unavailable\") are the App's to draw inside it.\n */\nexport function Loaded<T>({\n query,\n empty,\n height,\n children,\n}: {\n query: LoadedQuery<T>;\n empty?: ReactNode;\n height?: number | string;\n children: (data: NonNullable<T>) => ReactNode;\n}) {\n const failed = query.data === undefined && query.isError;\n const note = useRef<HTMLDivElement>(null);\n useEffect(() => {\n // The placeholder holds no focus; a drawing that did and went (a refresh that failed once its rows were dropped) left it on the body.\n if (!failed) return;\n const at = document.activeElement;\n if (at === null || at === document.body) note.current?.querySelector<HTMLElement>('.problem-retry')?.focus({ preventScroll: true });\n }, [failed]);\n if (failed)\n return (\n <div ref={note} className=\"kit-loaded\">\n <Problem text={query.error?.message || sayKit('notRead')} retry={() => void query.refetch()} />\n </div>\n );\n if (query.data === undefined)\n return (\n <div\n className=\"sk-bar kit-loading\"\n role=\"status\"\n aria-label={sayKit('common.loading')}\n {...(height === undefined ? {} : { style: { blockSize: height } })}\n />\n );\n if (query.data === null || (Array.isArray(query.data) && query.data.length === 0))\n return <>{empty ?? <Empty title={sayKit('nothingHereYet')} />}</>;\n return <>{children(query.data as NonNullable<T>)}</>;\n}\n\n/** One of the App's curated marks (the names a view's `icon` takes). Decoration unless it has a label. */\nexport function Icon({ name, label, size }: { name: AppIconName; label?: string; size?: number | string }) {\n return <PlatformIcon name={name} label={label} size={size} />;\n}\n\n/**\n * A segmented control: a few exclusive choices said as one row of words, the\n * chosen one filled in the look's tab dress — a filter's All / Needs attention,\n * a range's 7 d / 30 d. A choice may carry a count, a pill beside its word.\n * One target: arrows move the choice, as a radio group's do. Past four or five\n * choices it is a Dropdown's job.\n */\nexport function Segmented<T extends string>({\n label,\n value,\n options,\n onChange,\n size = 'default',\n}: {\n label: string;\n value: T;\n options: ReadonlyArray<{ value: T; label: ReactNode; count?: number; name?: string }>;\n onChange(value: T): void;\n size?: 'default' | 'compact';\n}) {\n const buttons = useRef<Array<HTMLButtonElement | null>>([]);\n const at = Math.max(\n 0,\n options.findIndex((option) => option.value === value),\n );\n const key = (event: KeyboardEvent<HTMLButtonElement>, index: number) => {\n const step =\n event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -1 : 0;\n const next = step\n ? (index + step + options.length) % options.length\n : event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? options.length - 1\n : -1;\n if (next < 0) return;\n event.preventDefault();\n onChange(options[next].value);\n buttons.current[next]?.focus();\n };\n return (\n <div className={`kit-segmented${size === 'compact' ? ' kit-segmented-compact' : ''}`} role=\"radiogroup\" aria-label={label}>\n {options.map((option, index) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={index === at}\n tabIndex={index === at ? 0 : -1}\n aria-label={option.name}\n ref={(node) => {\n buttons.current[index] = node;\n }}\n className=\"kit-segment\"\n onClick={() => onChange(option.value)}\n onKeyDown={(event) => key(event, index)}\n >\n <span>{option.label}</span>\n {option.count !== undefined && <span className=\"kit-segment-count\">{option.count}</span>}\n </button>\n ))}\n </div>\n );\n}\n\n/**\n * A figure and what it counts, as a dashboard's stat card says one: the\n * figure, its label, its change against the period before (in the tone of\n * the news where the caller knows which way is good) and, from four points,\n * its trend. As tall as what it says, so a strip of them stands from one edge.\n */\nexport function Stat({\n label,\n value,\n change,\n trend,\n say = String,\n}: {\n label: ReactNode;\n value: ReactNode;\n change?: { text: ReactNode; tone?: ToneName };\n trend?: ReadonlyArray<number | { key: string; value: number }>;\n say?: (value: unknown) => string;\n}) {\n const points = (trend ?? []).map((point, index) => (typeof point === 'number' ? { key: String(index), value: point } : point));\n return (\n <div className=\"kit-stat\">\n <span className=\"kit-stat-label\">{label}</span>\n {/* The trend rides beside the figure, so a Stat with none is the same height as one with. */}\n <span className=\"kit-stat-row\">\n <span className=\"kit-stat-figure\">{value}</span>\n {points.length >= 4 && (\n <span className={`spark-host kit-stat-spark${change?.tone === 'good' ? ' good' : change?.tone === 'bad' ? ' bad' : ''}`}>\n <Sparkline rows={points} say={say} />\n </span>\n )}\n </span>\n {change && <span className={`kit-stat-change${change.tone ? ` kit-stat-${change.tone}` : ''}`}>{change.text}</span>}\n </div>\n );\n}\n\n/**\n * Columns over periods (or any keys), each divided by series: Tracked and\n * Business events a day, say. Levels on the left, periods along the bottom,\n * the current column's parts in a pill over it, and a legend of the series.\n */\nexport function Columns({\n rows,\n series,\n say,\n height,\n}: {\n rows: ReadonlyArray<{ key: string; values: Record<string, number> }>;\n series: ReadonlyArray<{ key: string; label: string }>;\n say?: (value: unknown) => string;\n height?: number;\n}) {\n return (\n <div className=\"kit-columns\">\n <StackedColumns rows={[...rows]} series={[...series]} say={say} high={height} />\n </div>\n );\n}\n\nexport interface TableColumn<Row> {\n /** The row's field this column reads, and the key a sort names. */\n key: string;\n label: ReactNode;\n align?: 'left' | 'right';\n /** Dress the cell as this resource's column is dressed (money, a tone, a relative day), as `Value` does. */\n resource?: string;\n column?: string;\n display?: ComponentProps<typeof Value>['display'];\n /** Draw the cell yourself; the value, its dress and the row link are then yours. */\n render?: (row: Row) => ReactNode;\n /** Left out of the sort even where the table sorts. */\n sortable?: boolean;\n}\n\n/**\n * Rows the component read, in the look's own table: the head, the hairlines and the row hover are the platform's,\n * and each cell is a `Value`, so a column dressed in the App is dressed here. Sorting is the caller's, as its rows\n * are: a head is a button once `onSort` is given, and the table says which way it stands; it never reorders what it\n * was handed. With `onRowClick` the first cell is the row's link (one target for the keyboard) and the whole row\n * answers a pointer.\n */\nexport function Table<Row extends Record<string, unknown>>({\n label,\n columns,\n rows,\n rowKey,\n sort,\n onSort,\n onRowClick,\n empty,\n}: {\n /** What the table is, for assistive technology: a table of rows has no heading of its own. */\n label: string;\n columns: ReadonlyArray<TableColumn<Row>>;\n rows: ReadonlyArray<Row>;\n rowKey?: (row: Row, index: number) => string | number;\n sort?: { key: string; direction: 'asc' | 'desc' };\n onSort?: (key: string) => void;\n onRowClick?: (row: Row) => void;\n /** Said under the head when there are no rows. */\n empty?: ReactNode;\n}) {\n return (\n <div className=\"table-wrap kit-table\">\n <table aria-label={label}>\n <thead>\n <tr>\n {columns.map((column) => {\n const align = column.align ?? 'left';\n const sorted = sort?.key === column.key ? sort.direction : undefined;\n const sortable = Boolean(onSort) && column.sortable !== false;\n return (\n <th\n key={column.key}\n className={`align-${align}${sorted ? ' sorted' : ''}`}\n aria-sort={sorted ? (sorted === 'asc' ? 'ascending' : 'descending') : undefined}\n >\n {sortable ? (\n <button type=\"button\" className=\"th-sort\" onClick={() => onSort?.(column.key)}>\n {column.label}\n {sorted && <span aria-hidden=\"true\">{sorted === 'asc' ? ' ↑' : ' ↓'}</span>}\n </button>\n ) : (\n <span className=\"th-sort not-sortable\">{column.label}</span>\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, index) => (\n <tr\n key={rowKey ? rowKey(row, index) : index}\n className={onRowClick ? 'clickable' : undefined}\n onClick={onRowClick && (() => onRowClick(row))}\n >\n {columns.map((column, at) => {\n const drawn = column.render ? (\n column.render(row)\n ) : (\n <Value value={row[column.key]} resource={column.resource} column={column.column} display={column.display} compact />\n );\n return (\n <td key={column.key} className={`align-${column.align ?? 'left'}${typeof row[column.key] === 'number' ? ' num' : ''}`}>\n {onRowClick && at === 0 ? (\n <button\n type=\"button\"\n className=\"kit-table-link\"\n onClick={(event) => {\n // The row's own click is the pointer's; this one is the keyboard's, and must not run it twice.\n event.stopPropagation();\n onRowClick(row);\n }}\n >\n {drawn}\n </button>\n ) : (\n drawn\n )}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {rows.length === 0 && empty !== undefined && <div className=\"kit-table-empty\">{empty}</div>}\n </div>\n );\n}\n","/** What sdk/hooks says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n visitorUnavailable: 'Visitor experiments are unavailable in this component host.',\n thePageReadsIsNotOne: 'The page \"{label}\" reads {map}; \"{resource}\" is not one of them. Add it to the page\\'s reads.',\n thePageRunsIsNotOne: 'The page \"{label}\" runs {map}; \"{command}\" is not one of them. Add it to the page\\'s commands.',\n useaddressstateKeepsAPages: \"useAddressState keeps a page's place in its address; it is drawn on a free-form page (definePage).\",\n thePageKeepsInItsAddress: 'The page \"{label}\" keeps {params} in its address; add \"{name}\" to its params.',\n noCommands: 'no commands',\n noParameters: 'no parameters',\n});\n","/**\n * The hooks a custom component reads and moves with. The declared reads of a\n * `custom()` section are the first way to data — checked at load, planned,\n * narrowed by the dashboard's window — and these are the escape hatch for\n * what a component asks for itself: rows, one record or a breakdown of an App\n * resource, by the resource's own name, never a table or SQL.\n *\n * Every read is an ordinary request through the page's session, authorized\n * on the server like any other: role grants, field projection, row policy.\n * These names narrow what a component asks for; they are not the boundary.\n * Reads go through the page's one query cache, keyed by the reader, so a\n * sign-out or a switch of account never serves one reader's rows to another.\n */\nimport { useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport {\n defaultCurrency,\n formatAbsolute,\n formatDate,\n formatDateTime,\n formatMoney,\n formatNumber,\n formatPercent,\n formatRelativeDay,\n formatWholeMoney,\n} from '@mistriwork/kit/client/locale.js';\nimport { minorFigure } from '@mistriwork/engine/shared/money.js';\nimport {\n UiPageContext,\n UiSizeContext,\n useUiHost,\n type OpenMode,\n type UiOpenViewOptions,\n type UiBreakdownOptions,\n type UiChoice,\n type UiCommandOptions,\n type UiCommandOutcome,\n type UiCommandRef,\n type UiLook,\n type UiRow,\n type UiRowsOptions,\n type UiSize,\n type UiViewer,\n} from './context.js';\nimport { say } from '../../copy/components/components/sdk/hooks.js';\nimport { messageLanguage, subscribeMessages } from '@mistriwork/kit/client/messages.js';\nimport type { AppFlagReader, AppFlagValue } from '../../../shared/appFlagValues.js';\n\n/** Reads are render-local until React commits this exact render. Suspended or\n * abandoned renders share no consumption set with the committed tree. No ref or\n * memoized mutable set: concurrent work must not leak reads into another effect. */\nexport function useFlags<V = Readonly<Record<string, AppFlagValue>>>(): AppFlagReader<V> {\n const source = useUiHost().flags;\n const reader = useSyncExternalStore(source.subscribe, source.snapshot, source.snapshot);\n useEffect(() => {\n void source.load();\n }, [source, reader]);\n const used = new Set<string>();\n let committed = false;\n useEffect(() => {\n committed = true;\n if (used.size) source.commitUse?.(reader, [...used]);\n });\n return Object.freeze({\n get ready() {\n return reader.ready;\n },\n get(key: string) {\n const value = reader.get(key);\n if (!committed) used.add(key);\n return value;\n },\n }) as AppFlagReader<V>;\n}\n\n/** Call start from an authored interaction, never an effect or page load.\n * The server cookie is opaque; this does not sign in or grant App access. */\nexport function useVisitor(): { start(selection?: { readonly form?: string; readonly address?: string }): Promise<void> } {\n const source = useUiHost().flags;\n return useMemo(\n () => ({\n async start(selection?: { readonly form?: string; readonly address?: string }) {\n if (!source.establishVisitor) throw new Error(say('visitorUnavailable'));\n await source.establishVisitor(selection);\n },\n }),\n [source],\n );\n}\n\n/** Emit a custom event the App declared in `analytics.events`: `useAnalytics().emit('compare-opened', { vehicleId })`.\n * Fire-and-forget from an event handler. The server keeps only the declared name and fields, and takes who it\n * was from the session or visitor cookie, never from here. */\nexport function useAnalytics(): { emit(name: string, fields?: Readonly<Record<string, string | number | boolean>>): void } {\n const source = useUiHost().analytics;\n return useMemo(\n () => ({ emit: (name: string, fields?: Readonly<Record<string, string | number | boolean>>) => source.emit(name, fields) }),\n [source],\n );\n}\n\n/* A free-form page reads what it declared (definePage, `reads`): any other\n resource is a mistake said here, before the server refuses it as a denial\n for a reader who cannot read it — and it is the page's read, so the\n request says which page asks. Outside a page a component may name any\n resource. */\nfunction useDeclared(resource: string): string | undefined {\n const page = useContext(UiPageContext);\n if (page && !page.reads.includes(resource)) {\n throw new Error(say('thePageReadsIsNotOne', { label: page.label, map: page.reads.map((name) => `\"${name}\"`).join(', '), resource }));\n }\n return page?.view;\n}\n\n/** Rows of one App resource: `useRows('pay_run', { query: 'status = review', show: ['title', 'net_total'], sort: 'pay_date desc', limit: 12 })`. */\nexport function useRows(resource: string, options: UiRowsOptions & { enabled?: boolean } = {}): UseQueryResult<UiRow[]> {\n const host = useUiHost();\n const page = useDeclared(resource);\n const { enabled = true, ...rest } = options;\n const asked = page ? { ...rest, page } : rest;\n return useQuery({\n queryKey: ['mistri-ui', 'rows', ...host.scope, resource, asked],\n queryFn: () => host.rows(resource, asked),\n enabled,\n });\n}\n\n/** One record of an App resource by its key: `useRecord('employee', { id: 4 }, ['name', 'title'])`. */\nexport function useRecord(\n resource: string,\n key: Readonly<Record<string, unknown>> | undefined,\n show?: readonly string[],\n): UseQueryResult<UiRow | null> {\n const host = useUiHost();\n const page = useDeclared(resource);\n return useQuery({\n queryKey: ['mistri-ui', 'record', ...host.scope, resource, key, show, page],\n queryFn: async () => (await host.record(resource, key!, show, page ? { page } : {})) ?? null,\n enabled: key !== undefined,\n });\n}\n\n/**\n * A resource's rows grouped and measured: `useBreakdown('pay_stub', { by: 'status', measure: 'sum net' })`.\n * Each row is keyed as the server names its columns: the groups by their paths (`status`, `day(moved_at)`),\n * the measure as written (`count`, `sum(net)`, `max(on_hand_after)`).\n */\nexport function useBreakdown(resource: string, options: UiBreakdownOptions): UseQueryResult<UiRow[]> {\n const host = useUiHost();\n const page = useDeclared(resource);\n const asked = page ? { ...options, page } : options;\n return useQuery({\n queryKey: ['mistri-ui', 'breakdown', ...host.scope, resource, asked],\n queryFn: () => host.breakdown(resource, asked),\n });\n}\n\n/** Where a component may send the reader: a record (as a page, a peek or a dialog), one of the App's views, or one of its forms in a dialog. */\nexport function useNavigate(): {\n openRecord(resource: string, key: Readonly<Record<string, unknown>>, options?: { mode?: OpenMode; label?: string }): void;\n openView(view: string, options?: UiOpenViewOptions): void;\n openForm(view: string, prefill?: Readonly<Record<string, string | number>>): void;\n publicLink(view: string): string | undefined;\n} {\n const host = useUiHost();\n return {\n openRecord: (resource, key, options) => host.openRecord(resource, key, options),\n openView: (view, options) => host.openView(view, options),\n openForm: (view, prefill) => host.openForm(view, prefill),\n publicLink: (view) => host.publicLink(view),\n };\n}\n\n/** The page's timeline composer, from a custom section beside it: `fill` puts a template's words in the box (and\n chooses Reply or Internal note, where the page offers it) for the reader to edit and send — it never sends. It\n answers false when the page draws no composer. */\nexport function useComposer(): { fill(text: string, options?: { mode?: 'reply' | 'note' }): boolean } {\n const host = useUiHost();\n return { fill: (text, options = {}) => host.fillComposer(text, options.mode) };\n}\n\n/** Where a file resource's row is served, for an `<img>`: `useFile('member_avatar')({ id: 4 }, { thumbnail: true })`. */\nexport function useFile(\n resource: string,\n): (key: Readonly<Record<string, unknown>>, options?: { thumbnail?: boolean }) => string | undefined {\n const host = useUiHost();\n useDeclared(resource);\n return useCallback((key, options) => host.fileAddress(resource, key, options), [host, resource]);\n}\n\n/** Who is reading: signed in or not, and the signed-in account's id. Redraws when that changes. */\nexport function useViewer(): UiViewer {\n const host = useUiHost();\n const said = useSyncExternalStore(\n host.subscribeViewer,\n () => JSON.stringify(host.viewer()),\n () => '',\n );\n return said ? (JSON.parse(said) as UiViewer) : host.viewer();\n}\n\nconst keyText = (key: Readonly<Record<string, unknown>>) =>\n JSON.stringify(\n Object.keys(key)\n .sort()\n .map((column) => [column, String(key[column])]),\n );\n\n/** Why a command cannot be run on a record, before any click (`useCommand(...).reason(record)`). */\nexport type CommandUnavailable = 'signed-out' | 'not-granted' | 'unavailable';\n\n/** A command as a component holds it (`useCommand`). */\ninterface UiCommand {\n label: string;\n granted: boolean;\n /** Whether it is available on this record now; undefined until the server has said. */\n available(record: Readonly<Record<string, unknown>>): boolean | undefined;\n /**\n * Why it cannot be run on this record, said before any click: `'signed-out'`, `'not-granted'` (the\n * reader's role is not granted it), or `'unavailable'` (the server said its `when` does not hold for\n * this record and reader now); undefined while it can be, and until the server has said. Nothing the\n * page did not already know: a precondition only the command's handler checks is the App's to say.\n */\n reason(record: Readonly<Record<string, unknown>>): CommandUnavailable | undefined;\n /** Whether a run on this record is on its way. */\n pending(record: Readonly<Record<string, unknown>>): boolean;\n run(\n record: Readonly<Record<string, unknown>>,\n input?: Readonly<Record<string, unknown>>,\n options?: UiCommandOptions,\n ): Promise<UiCommandOutcome>;\n open(\n record: Readonly<Record<string, unknown>>,\n input?: Readonly<Record<string, unknown>>,\n options?: UiCommandOptions,\n ): Promise<UiCommandOutcome>;\n /**\n * The choices one of its inputs offers, as they were served with the command: a choice's declared options, or a\n * table's rows (`field.choice({ from })`) where they come with it — on a public page, read as the public reads them\n * and kept until a row changes, so the page draws its own select with no read of its own. Undefined for an input\n * that offers none, or whose rows its own form reads.\n */\n choices(field: string): readonly UiChoice[] | undefined;\n}\n\n/**\n * One of the App's commands, as its actions offer it, by name: `useCommand('reactToPost')`.\n * A command no action offers and a signed-in form does names no record: it\n * is sent as its form sends it, and the record handed in is not read.\n *\n * `run(record, input)` sends it when the input is complete and valid, and\n * opens the platform's own form, filled with what was given, when it is not;\n * `open` always opens the form. Either way it is the one command pipeline —\n * prepared for the record's revision, sent once under a request key,\n * refused in the server's words, the page's reads refreshed after it — and\n * nothing a component sends is a write of its own. `available(record)` asks\n * the server whether the command's `when` holds for this record and this\n * reader, once per record, and answers undefined until it has; `reason(record)`\n * says why not in a word. A signed-out reader is granted no command. An applied\n * run resolves with what the command returned (`output`), so a component acts on\n * what it made without looking it up.\n */\nexport function useCommand(ref: UiCommandRef): UiCommand {\n const host = useUiHost();\n /* A free-form page runs what it declared (definePage, `commands`), as it reads what it declared. */\n const page = useContext(UiPageContext);\n if (page && !page.commands.includes(ref)) {\n throw new Error(\n say('thePageRunsIsNotOne', {\n label: page.label,\n map: page.commands.length ? page.commands.map((name) => `\"${name}\"`).join(', ') : say('noCommands'),\n command: ref,\n }),\n );\n }\n const viewer = useViewer();\n const handle = useMemo(() => host.command(ref, page?.view), [host, ref, page?.view, viewer.signedIn, viewer.account]); // eslint-disable-line react-hooks/exhaustive-deps\n const [answers, setAnswers] = useState<ReadonlyMap<string, boolean>>(new Map());\n const [running, setRunning] = useState<ReadonlySet<string>>(new Set());\n const asked = useRef(new Map<string, Readonly<Record<string, unknown>>>());\n const wanted = useRef(new Map<string, Readonly<Record<string, unknown>>>());\n const [round, setRound] = useState(0);\n /* The handle whose answers are wanted: one for another reader or command asks everything again. */\n const current = useRef(handle);\n useEffect(() => {\n if (current.current === handle) return;\n current.current = handle;\n asked.current.clear();\n setAnswers(new Map());\n }, [handle]);\n useEffect(\n () => () => {\n current.current = undefined as unknown as typeof handle;\n },\n [],\n );\n /* The records a draw asked about, asked of the server after it (one batch, commandAvailability.ts). */\n useEffect(() => {\n const ask = [...wanted.current].filter(([text]) => !asked.current.has(text));\n wanted.current.clear();\n if (!ask.length) return;\n for (const [text, key] of ask) asked.current.set(text, key);\n const by = handle;\n void Promise.all(ask.map(async ([text, key]) => [text, by.granted ? await by.available(key).catch(() => false) : false] as const)).then(\n (results) => {\n if (current.current === by) setAnswers((before) => new Map([...before, ...results]));\n },\n );\n });\n /* Asked again after a run, keeping the last answers until the new ones arrive: a chip does not blink. */\n const again = () => {\n asked.current.clear();\n setRound((n) => n + 1);\n };\n const track = (text: string, work: Promise<UiCommandOutcome>) => {\n setRunning((before) => new Set(before).add(text));\n return work.finally(() => {\n setRunning((before) => {\n const next = new Set(before);\n next.delete(text);\n return next;\n });\n /* What a command changed may change what is available: asked again after it settles. */\n again();\n });\n };\n void round;\n const available = (record: Readonly<Record<string, unknown>>) => {\n const text = keyText(record);\n if (!asked.current.has(text)) wanted.current.set(text, record);\n return answers.get(text);\n };\n return {\n label: handle.label,\n granted: handle.granted,\n available,\n reason(record) {\n // A public page's public command is everyone's: granted, signed in or not (publicPageCommand.ts).\n if (!viewer.signedIn && !handle.granted) return 'signed-out';\n if (!handle.granted) return 'not-granted';\n return available(record) === false ? 'unavailable' : undefined;\n },\n pending: (record) => running.has(keyText(record)),\n run: (record, input, options) => track(keyText(record), handle.run(record, input, options)),\n open: (record, input, options) => track(keyText(record), handle.open(record, input, options)),\n choices: (field) => handle.choices?.(field),\n };\n}\n\n/**\n * A free-form page's place, kept in its address: `const [list, setList] = useAddressState('list')` reads and writes\n * `/{app}/pick-walk?list=12`, so a page reached by a link, a reload or Back opens where the reader was.\n * The name is one of the page's declared `params` (a page's `useParam` is this hook). A change refines the place the\n * reader is on, in the address as they go; `{ push: true }` makes it a step Back returns from.\n */\nexport function useAddressState(\n name: string,\n): [string | undefined, (value: string | number | undefined, options?: { push?: boolean }) => void] {\n const page = useContext(UiPageContext);\n if (!page) throw new Error(say('useaddressstateKeepsAPages'));\n if (!page.params.includes(name)) {\n throw new Error(\n say('thePageKeepsInItsAddress', {\n label: page.label,\n params: page.params.length ? page.params.map((param) => `\"${param}\"`).join(', ') : say('noParameters'),\n name,\n }),\n );\n }\n const set = useCallback(\n (value: string | number | undefined, options?: { push?: boolean }) =>\n page.set(name, value === undefined || value === '' ? undefined : String(value), options),\n [page, name],\n );\n return [page.get(name), set];\n}\n\n/**\n * One of the App's messages (`messages/<locale>.ts`) in the reader's\n * language, its `{name}`s filled from `args`: `useMessage('help.title')`,\n * `useMessage('help.results', { count: 3 })`. Redraws when the reader picks\n * another language. A key the catalog lacks is said as itself.\n */\nexport function useMessage(key: string, args?: Readonly<Record<string, string | number | boolean | Date | null | undefined>>): string {\n const host = useUiHost();\n useSyncExternalStore(subscribeMessages, messageLanguage, messageLanguage);\n return host.message(key, args);\n}\n\n/** How `useFormat().money` says a figure: as a column's display rule says one (`format: 'money'`). */\ninterface UiMoneyFormat {\n /** An ISO 4217 code; the App's `ui.currency` when not given. */\n currency?: string;\n /** The value is kept in minor units: 1999 is said as 19.99, exactly. */\n minor?: boolean;\n /** Without the minor digits where they are all zero: \"$24,495\", and \"$24,495.50\" still. */\n whole?: boolean;\n /** Compact from a thousand (\"$27.9K\"), for a figure meant to be glanced at; put the exact one in its title. */\n compact?: boolean;\n}\n\n/* Where a compact figure starts, as a metric card's (dashboardModel.ts CARD_COMPACT). */\nconst COMPACT_FROM = 1000;\n\n/**\n * Money said as the display rules say it: exact to the currency's minor digits, a decimal string past 2^53 digit for\n * digit (never through Number()), minor units read exactly. A currency code alone is `{ currency }`.\n */\nfunction sayMoney(value: number | string, options: string | UiMoneyFormat = {}): string {\n const { currency, minor, whole, compact } = typeof options === 'string' ? { currency: options } : options;\n const code = currency || defaultCurrency();\n const major = minor ? minorFigure(value, code) : value;\n if (major === undefined) return String(value);\n if (compact && Math.abs(Number(major)) >= COMPACT_FROM)\n return formatMoney(Number(major), code, { notation: 'compact', maximumFractionDigits: 1 });\n return whole ? formatWholeMoney(major, code) : formatMoney(major, code);\n}\n\n/** Figures in the App's locale, currency and timezone (`ui.locale`, `ui.currency`, `ui.timezone`), as every built-in section says them. */\nexport function useFormat() {\n return {\n number: (value: number | string, options?: Intl.NumberFormatOptions) => formatNumber(value, options),\n money: (value: number | string, options?: string | UiMoneyFormat) => sayMoney(value, options),\n percent: (value: number) => formatPercent(value),\n date: (value: string) => formatDate(value),\n /** A moment as the App's clock says it; with `timezone`, the instant said in that zone with its name (\"2:30 PM PDT\"). */\n dateTime: (value: string, options?: { timezone?: string }) =>\n options?.timezone ? formatAbsolute(value, { time: true, zone: options.timezone }) : formatDateTime(value),\n /** \"in 3 days\", \"yesterday\"; undefined for a value that is not a date. */\n relative: (value: string) => formatRelativeDay(value) ?? undefined,\n };\n}\n\n/** The look the App wears for this reader, light or dark, and the density. */\nexport function useLook(): UiLook {\n const host = useUiHost();\n const said = useSyncExternalStore(\n host.subscribeLook,\n () => JSON.stringify(host.look()),\n () => '',\n );\n return said ? (JSON.parse(said) as UiLook) : host.look();\n}\n\n/** One design token's value as the look resolves it — `useToken('--accent')` — for a canvas or an SVG attribute. CSS can say `var(--accent)` itself. */\nexport function useToken(name: `--${string}`): string {\n const host = useUiHost();\n return useSyncExternalStore(\n host.subscribeLook,\n () => host.token(name),\n () => '',\n );\n}\n\n/** The section's measured width, and whether it is phone-narrow: a component lays itself out for the room it has. */\nexport function useSectionSize(): UiSize {\n return useContext(UiSizeContext);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shared-TrGbd1FY.js","names":["say","say","_Fragment","say","PlatformEmpty","sayKit","_Fragment","PlatformIcon"],"sources":["../../src/client/copy/components/components/sdk/kit.ts","../../src/client/copy/lists/components/SplitListDetail.ts","../../src/client/components/SplitListDetail.tsx","../../src/client/components/sdk/kit.tsx","../../src/client/copy/components/components/sdk/hooks.ts","../../src/client/components/sdk/hooks.ts"],"sourcesContent":["/** What sdk/kit says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n nothingHereYet: 'Nothing here yet.',\n notRead: 'This could not be read.',\n});\n","/** What SplitListDetail says, in the lists and grid room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n close: 'Close {title}',\n details: 'Details',\n list: 'List',\n selectARecordToSee: 'Select a record to see its details.',\n});\n","/**\n * A bounded host for collection workspaces.\n *\n * The list owns selection and navigation; this component owns only the\n * presentation seam around the selected detail. Where the host has room the\n * detail is a sibling pane beside the list, and where it does not (a\n * container query on the host, SplitListDetail.css) the pane goes under it.\n * On a phone the same host falls back to the existing Modal primitive, so\n * callers do not invent a second dialog or focus/escape implementation. One\n * branch is mounted at a time: an editor is never duplicated with two\n * competing owners.\n */\nimport { useCallback, useSyncExternalStore, type ReactNode } from 'react';\nimport { BesideDetail } from '@mistriwork/kit/client/components/besideDetail.js';\nimport { Modal } from '@mistriwork/ui/Modal.js';\nimport { say } from '../copy/lists/components/SplitListDetail.js';\n\nconst MOBILE_QUERY = '(max-width: 760px)';\n\ninterface SplitListDetailProps {\n /** The collection surface. It remains mounted while a detail is open. */\n list: ReactNode;\n /** The selected record surface, usually an owned PageView or RecordModal body. */\n detail?: ReactNode;\n /** The selected record's controls, drawn in the detail's head between its title and Close. */\n detailActions?: ReactNode;\n /** Whether the detail pane should be presented. */\n selected?: boolean;\n /** Stable name for the detail surface and its close control. */\n detailTitle?: string;\n /** Called only while the host's owner is still current. */\n onCloseDetail?: () => void;\n /** Optional lifetime fence supplied by PageRoom/RecordModal hosts. */\n isCurrent?: () => boolean;\n /** Accessible names for the two regions. */\n listLabel?: string;\n detailLabel?: string;\n /** Compact navigation list, with remaining space reserved for the editor. */\n listWidth?: 'balanced' | 'compact';\n /** Use all available space for the collection until a record is selected. */\n expandList?: boolean;\n className?: string;\n /** The detail's title reads as the record's own name, in sentence case, not as the kit's small-caps eyebrow. */\n sentenceTitle?: boolean;\n}\n\nfunction mobileSnapshot(): boolean {\n return typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(MOBILE_QUERY).matches : false;\n}\n\nfunction subscribeMobile(listener: () => void): () => void {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return () => {};\n const query = window.matchMedia(MOBILE_QUERY);\n query.addEventListener?.('change', listener);\n /* Older WebKit has the deprecated listener pair but no addEventListener. */\n if (!query.addEventListener) query.addListener(listener);\n return () => {\n query.removeEventListener?.('change', listener);\n if (!query.removeEventListener) query.removeListener(listener);\n };\n}\n\nfunction DetailContent({\n title,\n detail,\n actions,\n onClose,\n}: {\n title: string;\n detail?: ReactNode;\n actions?: ReactNode;\n onClose: () => void;\n}) {\n return (\n <>\n <div className=\"split-list-detail-head\">\n <h2 className=\"split-list-detail-title\">{title}</h2>\n {actions && <div className=\"split-list-detail-actions\">{actions}</div>}\n <button\n type=\"button\"\n className=\"ghost split-list-detail-close\"\n aria-label={say('close', { title: title.toLowerCase() })}\n onClick={onClose}\n >\n ×\n </button>\n </div>\n <div className=\"split-list-detail-body\">{detail}</div>\n </>\n );\n}\n\nexport function SplitListDetail({\n list,\n detail,\n detailActions,\n selected = false,\n detailTitle = say('details'),\n onCloseDetail,\n isCurrent,\n listLabel = say('list'),\n detailLabel = say('details'),\n listWidth = 'balanced',\n expandList = false,\n className = '',\n sentenceTitle = false,\n}: SplitListDetailProps) {\n const mobile = useSyncExternalStore(subscribeMobile, mobileSnapshot, () => false);\n const close = useCallback(() => {\n if (isCurrent && !isCurrent()) return;\n onCloseDetail?.();\n }, [isCurrent, onCloseDetail]);\n const classes = [\n 'split-list-detail',\n listWidth === 'compact' ? 'split-list-detail-compact' : '',\n expandList ? 'split-list-detail-expand' : '',\n sentenceTitle ? 'split-list-detail-sentence' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div className=\"split-list-detail-host\">\n <div className={classes} data-selected={selected ? 'true' : 'false'}>\n <section className=\"split-list-detail-list\" aria-label={listLabel}>\n <BesideDetail.Provider value={selected && !mobile}>{list}</BesideDetail.Provider>\n </section>\n {!mobile && (\n <aside className=\"split-list-detail-pane\" aria-label={detailLabel}>\n {selected ? (\n <DetailContent title={detailTitle} detail={detail} actions={detailActions} onClose={close} />\n ) : (\n <p className=\"split-list-detail-empty\" role=\"status\">\n {say('selectARecordToSee')}\n </p>\n )}\n </aside>\n )}\n {mobile && selected && (\n <Modal\n className={`split-list-detail-modal${sentenceTitle ? ' split-list-detail-sentence' : ''}`}\n fullscreen=\"mobile\"\n ariaLabel={detailLabel}\n onClose={close}\n >\n <DetailContent title={detailTitle} detail={detail} actions={detailActions} onClose={close} />\n </Modal>\n )}\n </div>\n </div>\n );\n}\n","/**\n * The kit a custom component draws with: the platform's own pieces, dressed\n * in the classes every look already dresses, so a component reads as part of\n * the App in all three looks, light and dark, without a colour of its own.\n *\n * Each takes explicit props. The column a `Value` belongs to and how its App\n * dresses it come from the host (context.ts), never from the walk's globals,\n * so the same piece draws in the page and in a component's tests. Layout\n * follows docs/design.md: one box, never a box in a box (a `Card` inside a\n * `Card` draws as a plain group); the 20px field gap and the 40px section\n * seam as `Stack`'s two gaps; a tone is a dot and its word.\n */\nimport {\n createContext,\n useContext,\n useEffect,\n useRef,\n type ComponentProps,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport type { AppIconName } from '@mistriwork/engine/shared/appIcons.js';\nimport { Icon as PlatformIcon } from '@mistriwork/kit/client/components/Icon.js';\nimport { Empty as PlatformEmpty, Problem } from '@mistriwork/kit/client/components/Notes.js';\nimport { Dressed, Said } from '@mistriwork/kit/client/components/Dressed.js';\nimport { authoredDisplay, dressFor, type DisplayRule } from '@mistriwork/kit/client/components/valueModel.js';\nimport { useUiHost } from './context.js';\n/* Named apart: `say` is also Sparkline's prop below, a figure's speaker. */\nimport { say as sayKit } from '../../copy/components/components/sdk/kit.js';\nimport { Sparkline, StackedColumns } from '@mistriwork/kit/client/components/Chart.js';\n\nexport { Button } from '@mistriwork/ui/Button.js';\nexport { Dropdown } from '@mistriwork/kit/client/components/Dropdown.js';\nexport { SplitListDetail } from '../SplitListDetail.js';\n\ntype Gap = 'tight' | 'field' | 'section';\nconst GAPS: Record<Gap, string> = { tight: 'kit-gap-tight', field: 'kit-gap-field', section: 'kit-gap-section' };\n\nconst InCard = createContext(false);\n\n/** One box: a hairline and the surface. A card inside a card is a plain group, as design.md's refusal list asks. */\nexport function Card({ title, children, className }: { title?: ReactNode; children?: ReactNode; className?: string }) {\n const nested = useContext(InCard);\n const classes = [nested ? 'kit-group' : 'kit-card', className].filter(Boolean).join(' ');\n return (\n <div className={classes}>\n {title !== undefined && <h3 className=\"kit-card-title\">{title}</h3>}\n <InCard.Provider value={true}>{children}</InCard.Provider>\n </div>\n );\n}\n\n/** Children one under another, a field's 20px apart (default), a section's 40px, or tight. */\nexport function Stack({\n gap = 'field',\n as: Tag = 'div',\n children,\n className,\n}: {\n gap?: Gap;\n as?: 'div' | 'ul' | 'ol';\n children?: ReactNode;\n className?: string;\n}) {\n return <Tag className={['kit-stack', GAPS[gap], className].filter(Boolean).join(' ')}>{children}</Tag>;\n}\n\n/** Children side by side, wrapping onto a new line where there is no room. `foot` says the row is the page's actions\n at the screen's foot (a sticky row of verbs on a phone): a notice stands above it, as above a record's bar, and\n never over the verbs it reports on. */\nexport function Row({\n gap = 'field',\n align = 'center',\n foot,\n children,\n className,\n}: {\n gap?: Gap;\n align?: 'start' | 'center' | 'baseline' | 'end';\n foot?: boolean;\n children?: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={['kit-row', GAPS[gap], `kit-align-${align}`, className].filter(Boolean).join(' ')}\n {...(foot ? { 'data-foot-actions': '' } : {})}\n >\n {children}\n </div>\n );\n}\n\n/** A heading inside a section: the section's own title is its h2, so this is an h3 by default. */\nexport function Heading({ level = 3, children, className }: { level?: 3 | 4; children?: ReactNode; className?: string }) {\n const Tag = level === 4 ? 'h4' : 'h3';\n return <Tag className={['kit-heading', className].filter(Boolean).join(' ')}>{children}</Tag>;\n}\n\nexport type ToneName = 'good' | 'warn' | 'bad' | 'info' | 'neutral';\n\n/** A meaning as the looks say one: a dot and its word. Earned, like a display rule's tone. */\nexport function Tone({ tone, children }: { tone: ToneName; children?: ReactNode }) {\n return <span className={`tone tone-${tone}`}>{children}</span>;\n}\n\n/**\n * A value, drawn as the App draws it: name the resource and the column and\n * its display rule dresses it (money, a tone, a relative day), or pass\n * `display` to say one here. An id past 2^53 arrives as a string and keeps\n * every digit; nothing here runs it through Number().\n */\nexport function Value({\n value,\n resource,\n column,\n display,\n compact = false,\n}: {\n value: unknown;\n resource?: string;\n column?: string;\n display?: Omit<DisplayRule, 'bar' | 'max'> & { bar?: boolean | number };\n compact?: boolean;\n}) {\n const host = useUiHost();\n const known = resource && column ? host.column(resource, column) : undefined;\n if (value === null || value === undefined || value === '') return <span className=\"null\">—</span>;\n const rule = authoredDisplay(display) ?? known?.rule ?? null;\n const dress = dressFor(rule, value);\n if (dress) return <Dressed dress={dress} compact={compact} />;\n return <Said col={known?.meta} value={value} compact={compact} app={host.app} />;\n}\n\n/** A share of a whole as a bar and its figure: `value` against `max` (100 by default), in a tone when it means something. */\nexport function Meter({ value, max = 100, tone, label }: { value: number; max?: number; tone?: ToneName; label?: ReactNode }) {\n const fill = max > 0 && Number.isFinite(value) ? Math.max(0, Math.min(100, (value / max) * 100)) : 0;\n const style: CSSProperties = { width: `${fill}%` };\n return (\n <span\n className={`meter-wrap${tone ? ` meter-${tone}` : ''}`}\n role=\"meter\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-label={typeof label === 'string' ? label : undefined}\n >\n <span className=\"pct-bar\">\n <span className=\"pct-fill\" style={style} />\n </span>\n {label !== undefined && <span className=\"num-value\">{label}</span>}\n </span>\n );\n}\n\n/** What a component says when it has nothing to draw: the platform's own quiet note. */\nexport function Empty({ title, description, action }: { title: ReactNode; description?: ReactNode; action?: ReactNode }) {\n return <PlatformEmpty text={title} detail={description} action={action} />;\n}\n\n/** What `<Loaded>` reads of a read: a hook's query (`useRows`, `useRecord`, `useBreakdown`) as it stands. */\ninterface LoadedQuery<T> {\n data: T | undefined;\n isError: boolean;\n error: Error | null;\n refetch(): unknown;\n}\n\n/**\n * A read's states before its drawing, said as every section says them: the platform's placeholder while it is asked\n * (at `height`, the size the drawing will take, so nothing under it moves when it lands), `Empty` for no rows or no\n * record (`empty`, or the house sentence), and the house problem with Try again when it could not be read — focus on\n * Try again when the drawing it replaced held it, so focus is never dropped. Then `children(data)`, the App's own.\n * What was read stays drawn when a later refresh fails: a finished screen is never swapped for a note. Domain states\n * (\"not eligible\", \"unavailable\") are the App's to draw inside it.\n */\nexport function Loaded<T>({\n query,\n empty,\n height,\n children,\n}: {\n query: LoadedQuery<T>;\n empty?: ReactNode;\n height?: number | string;\n children: (data: NonNullable<T>) => ReactNode;\n}) {\n const failed = query.data === undefined && query.isError;\n const note = useRef<HTMLDivElement>(null);\n useEffect(() => {\n // The placeholder holds no focus; a drawing that did and went (a refresh that failed once its rows were dropped) left it on the body.\n if (!failed) return;\n const at = document.activeElement;\n if (at === null || at === document.body) note.current?.querySelector<HTMLElement>('.problem-retry')?.focus({ preventScroll: true });\n }, [failed]);\n if (failed)\n return (\n <div ref={note} className=\"kit-loaded\">\n <Problem text={query.error?.message || sayKit('notRead')} retry={() => void query.refetch()} />\n </div>\n );\n if (query.data === undefined)\n return (\n <div\n className=\"sk-bar kit-loading\"\n role=\"status\"\n aria-label={sayKit('common.loading')}\n {...(height === undefined ? {} : { style: { blockSize: height } })}\n />\n );\n if (query.data === null || (Array.isArray(query.data) && query.data.length === 0))\n return <>{empty ?? <Empty title={sayKit('nothingHereYet')} />}</>;\n return <>{children(query.data as NonNullable<T>)}</>;\n}\n\n/** One of the App's curated marks (the names a view's `icon` takes). Decoration unless it has a label. */\nexport function Icon({ name, label, size }: { name: AppIconName; label?: string; size?: number | string }) {\n return <PlatformIcon name={name} label={label} size={size} />;\n}\n\n/**\n * A segmented control: a few exclusive choices said as one row of words, the\n * chosen one filled in the look's tab dress — a filter's All / Needs attention,\n * a range's 7 d / 30 d. A choice may carry a count, a pill beside its word.\n * One target: arrows move the choice, as a radio group's do. Past four or five\n * choices it is a Dropdown's job.\n */\nexport function Segmented<T extends string>({\n label,\n value,\n options,\n onChange,\n size = 'default',\n}: {\n label: string;\n value: T;\n options: ReadonlyArray<{ value: T; label: ReactNode; count?: number; name?: string }>;\n onChange(value: T): void;\n size?: 'default' | 'compact';\n}) {\n const buttons = useRef<Array<HTMLButtonElement | null>>([]);\n const at = Math.max(\n 0,\n options.findIndex((option) => option.value === value),\n );\n const key = (event: KeyboardEvent<HTMLButtonElement>, index: number) => {\n const step =\n event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -1 : 0;\n const next = step\n ? (index + step + options.length) % options.length\n : event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? options.length - 1\n : -1;\n if (next < 0) return;\n event.preventDefault();\n onChange(options[next].value);\n buttons.current[next]?.focus();\n };\n return (\n <div className={`kit-segmented${size === 'compact' ? ' kit-segmented-compact' : ''}`} role=\"radiogroup\" aria-label={label}>\n {options.map((option, index) => (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={index === at}\n tabIndex={index === at ? 0 : -1}\n aria-label={option.name}\n ref={(node) => {\n buttons.current[index] = node;\n }}\n className=\"kit-segment\"\n onClick={() => onChange(option.value)}\n onKeyDown={(event) => key(event, index)}\n >\n <span>{option.label}</span>\n {option.count !== undefined && <span className=\"kit-segment-count\">{option.count}</span>}\n </button>\n ))}\n </div>\n );\n}\n\n/**\n * A figure and what it counts, as a dashboard's stat card says one: the\n * figure, its label, its change against the period before (in the tone of\n * the news where the caller knows which way is good) and, from four points,\n * its trend. As tall as what it says, so a strip of them stands from one edge.\n */\nexport function Stat({\n label,\n value,\n change,\n trend,\n say = String,\n}: {\n label: ReactNode;\n value: ReactNode;\n change?: { text: ReactNode; tone?: ToneName };\n trend?: ReadonlyArray<number | { key: string; value: number }>;\n say?: (value: unknown) => string;\n}) {\n const points = (trend ?? []).map((point, index) => (typeof point === 'number' ? { key: String(index), value: point } : point));\n return (\n <div className=\"kit-stat\">\n <span className=\"kit-stat-label\">{label}</span>\n {/* The trend rides beside the figure, so a Stat with none is the same height as one with. */}\n <span className=\"kit-stat-row\">\n <span className=\"kit-stat-figure\">{value}</span>\n {points.length >= 4 && (\n <span className={`spark-host kit-stat-spark${change?.tone === 'good' ? ' good' : change?.tone === 'bad' ? ' bad' : ''}`}>\n <Sparkline rows={points} say={say} />\n </span>\n )}\n </span>\n {change && <span className={`kit-stat-change${change.tone ? ` kit-stat-${change.tone}` : ''}`}>{change.text}</span>}\n </div>\n );\n}\n\n/**\n * Columns over periods (or any keys), each divided by series: Tracked and\n * Business events a day, say. Levels on the left, periods along the bottom,\n * the current column's parts in a pill over it, and a legend of the series.\n */\nexport function Columns({\n rows,\n series,\n say,\n height,\n}: {\n rows: ReadonlyArray<{ key: string; values: Record<string, number> }>;\n series: ReadonlyArray<{ key: string; label: string }>;\n say?: (value: unknown) => string;\n height?: number;\n}) {\n return (\n <div className=\"kit-columns\">\n <StackedColumns rows={[...rows]} series={[...series]} say={say} high={height} />\n </div>\n );\n}\n\nexport interface TableColumn<Row> {\n /** The row's field this column reads, and the key a sort names. */\n key: string;\n label: ReactNode;\n align?: 'left' | 'right';\n /** Dress the cell as this resource's column is dressed (money, a tone, a relative day), as `Value` does. */\n resource?: string;\n column?: string;\n display?: ComponentProps<typeof Value>['display'];\n /** Draw the cell yourself; the value, its dress and the row link are then yours. */\n render?: (row: Row) => ReactNode;\n /** Left out of the sort even where the table sorts. */\n sortable?: boolean;\n}\n\n/**\n * Rows the component read, in the look's own table: the head, the hairlines and the row hover are the platform's,\n * and each cell is a `Value`, so a column dressed in the App is dressed here. Sorting is the caller's, as its rows\n * are: a head is a button once `onSort` is given, and the table says which way it stands; it never reorders what it\n * was handed. With `onRowClick` the first cell is the row's link (one target for the keyboard) and the whole row\n * answers a pointer.\n */\nexport function Table<Row extends Record<string, unknown>>({\n label,\n columns,\n rows,\n rowKey,\n sort,\n onSort,\n onRowClick,\n empty,\n}: {\n /** What the table is, for assistive technology: a table of rows has no heading of its own. */\n label: string;\n columns: ReadonlyArray<TableColumn<Row>>;\n rows: ReadonlyArray<Row>;\n rowKey?: (row: Row, index: number) => string | number;\n sort?: { key: string; direction: 'asc' | 'desc' };\n onSort?: (key: string) => void;\n onRowClick?: (row: Row) => void;\n /** Said under the head when there are no rows. */\n empty?: ReactNode;\n}) {\n return (\n <div className=\"table-wrap kit-table\">\n <table aria-label={label}>\n <thead>\n <tr>\n {columns.map((column) => {\n const align = column.align ?? 'left';\n const sorted = sort?.key === column.key ? sort.direction : undefined;\n const sortable = Boolean(onSort) && column.sortable !== false;\n return (\n <th\n key={column.key}\n className={`align-${align}${sorted ? ' sorted' : ''}`}\n aria-sort={sorted ? (sorted === 'asc' ? 'ascending' : 'descending') : undefined}\n >\n {sortable ? (\n <button type=\"button\" className=\"th-sort\" onClick={() => onSort?.(column.key)}>\n {column.label}\n {sorted && <span aria-hidden=\"true\">{sorted === 'asc' ? ' ↑' : ' ↓'}</span>}\n </button>\n ) : (\n <span className=\"th-sort not-sortable\">{column.label}</span>\n )}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, index) => (\n <tr\n key={rowKey ? rowKey(row, index) : index}\n className={onRowClick ? 'clickable' : undefined}\n onClick={onRowClick && (() => onRowClick(row))}\n >\n {columns.map((column, at) => {\n const drawn = column.render ? (\n column.render(row)\n ) : (\n <Value value={row[column.key]} resource={column.resource} column={column.column} display={column.display} compact />\n );\n return (\n <td key={column.key} className={`align-${column.align ?? 'left'}${typeof row[column.key] === 'number' ? ' num' : ''}`}>\n {onRowClick && at === 0 ? (\n <button\n type=\"button\"\n className=\"kit-table-link\"\n onClick={(event) => {\n // The row's own click is the pointer's; this one is the keyboard's, and must not run it twice.\n event.stopPropagation();\n onRowClick(row);\n }}\n >\n {drawn}\n </button>\n ) : (\n drawn\n )}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {rows.length === 0 && empty !== undefined && <div className=\"kit-table-empty\">{empty}</div>}\n </div>\n );\n}\n","/** What sdk/hooks says, in the custom components room (packages/kit/src/client/messages.ts says how the catalog is split). */\nimport { defineMessages } from '@mistriwork/kit/client/messages.js';\n\nexport const say = defineMessages({\n visitorUnavailable: 'Visitor experiments are unavailable in this component host.',\n thePageReadsIsNotOne: 'The page \"{label}\" reads {map}; \"{resource}\" is not one of them. Add it to the page\\'s reads.',\n thePageRunsIsNotOne: 'The page \"{label}\" runs {map}; \"{command}\" is not one of them. Add it to the page\\'s commands.',\n useaddressstateKeepsAPages: \"useAddressState keeps a page's place in its address; it is drawn on a free-form page (definePage).\",\n thePageKeepsInItsAddress: 'The page \"{label}\" keeps {params} in its address; add \"{name}\" to its params.',\n noCommands: 'no commands',\n noParameters: 'no parameters',\n});\n","/**\n * The hooks a custom component reads and moves with. The declared reads of a\n * `custom()` section are the first way to data — checked at load, planned,\n * narrowed by the dashboard's window — and these are the escape hatch for\n * what a component asks for itself: rows, one record or a breakdown of an App\n * resource, by the resource's own name, never a table or SQL.\n *\n * Every read is an ordinary request through the page's session, authorized\n * on the server like any other: role grants, field projection, row policy.\n * These names narrow what a component asks for; they are not the boundary.\n * Reads go through the page's one query cache, keyed by the reader, so a\n * sign-out or a switch of account never serves one reader's rows to another.\n */\nimport { useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport {\n defaultCurrency,\n formatAbsolute,\n formatDate,\n formatDateTime,\n formatMoney,\n formatNumber,\n formatPercent,\n formatRelativeDay,\n formatWholeMoney,\n} from '@mistriwork/kit/client/locale.js';\nimport { minorFigure } from '@mistriwork/engine/shared/money.js';\nimport {\n UiPageContext,\n UiSizeContext,\n useUiHost,\n type OpenMode,\n type UiOpenViewOptions,\n type UiBreakdownOptions,\n type UiChoice,\n type UiCommandOptions,\n type UiCommandOutcome,\n type UiCommandRef,\n type UiLook,\n type UiRow,\n type UiRowsOptions,\n type UiSize,\n type UiViewer,\n} from './context.js';\nimport { say } from '../../copy/components/components/sdk/hooks.js';\nimport { messageLanguage, subscribeMessages } from '@mistriwork/kit/client/messages.js';\nimport type { AppFlagReader, AppFlagValue } from '../../../shared/appFlagValues.js';\n\n/** Reads are render-local until React commits this exact render. Suspended or\n * abandoned renders share no consumption set with the committed tree. No ref or\n * memoized mutable set: concurrent work must not leak reads into another effect. */\nexport function useFlags<V = Readonly<Record<string, AppFlagValue>>>(): AppFlagReader<V> {\n const source = useUiHost().flags;\n const reader = useSyncExternalStore(source.subscribe, source.snapshot, source.snapshot);\n useEffect(() => {\n void source.load();\n }, [source, reader]);\n const used = new Set<string>();\n let committed = false;\n useEffect(() => {\n committed = true;\n if (used.size) source.commitUse?.(reader, [...used]);\n });\n return Object.freeze({\n get ready() {\n return reader.ready;\n },\n get(key: string) {\n const value = reader.get(key);\n if (!committed) used.add(key);\n return value;\n },\n }) as AppFlagReader<V>;\n}\n\n/** Call start from an authored interaction, never an effect or page load.\n * The server cookie is opaque; this does not sign in or grant App access. */\nexport function useVisitor(): { start(selection?: { readonly form?: string; readonly address?: string }): Promise<void> } {\n const source = useUiHost().flags;\n return useMemo(\n () => ({\n async start(selection?: { readonly form?: string; readonly address?: string }) {\n if (!source.establishVisitor) throw new Error(say('visitorUnavailable'));\n await source.establishVisitor(selection);\n },\n }),\n [source],\n );\n}\n\n/** Emit a custom event the App declared in `analytics.events`: `useAnalytics().emit('compare-opened', { vehicleId })`.\n * Fire-and-forget from an event handler. The server keeps only the declared name and fields, and takes who it\n * was from the session or visitor cookie, never from here. */\nexport function useAnalytics(): { emit(name: string, fields?: Readonly<Record<string, string | number | boolean>>): void } {\n const source = useUiHost().analytics;\n return useMemo(\n () => ({ emit: (name: string, fields?: Readonly<Record<string, string | number | boolean>>) => source.emit(name, fields) }),\n [source],\n );\n}\n\n/* A free-form page reads what it declared (definePage, `reads`): any other\n resource is a mistake said here, before the server refuses it as a denial\n for a reader who cannot read it — and it is the page's read, so the\n request says which page asks. Outside a page a component may name any\n resource. */\nfunction useDeclared(resource: string): string | undefined {\n const page = useContext(UiPageContext);\n if (page && !page.reads.includes(resource)) {\n throw new Error(say('thePageReadsIsNotOne', { label: page.label, map: page.reads.map((name) => `\"${name}\"`).join(', '), resource }));\n }\n return page?.view;\n}\n\n/** Rows of one App resource: `useRows('pay_run', { query: 'status = review', show: ['title', 'net_total'], sort: 'pay_date desc', limit: 12 })`. */\nexport function useRows(resource: string, options: UiRowsOptions & { enabled?: boolean } = {}): UseQueryResult<UiRow[]> {\n const host = useUiHost();\n const page = useDeclared(resource);\n const { enabled = true, ...rest } = options;\n const asked = page ? { ...rest, page } : rest;\n return useQuery({\n queryKey: ['mistri-ui', 'rows', ...host.scope, resource, asked],\n queryFn: () => host.rows(resource, asked),\n enabled,\n });\n}\n\n/** One record of an App resource by its key: `useRecord('employee', { id: 4 }, ['name', 'title'])`. */\nexport function useRecord(\n resource: string,\n key: Readonly<Record<string, unknown>> | undefined,\n show?: readonly string[],\n): UseQueryResult<UiRow | null> {\n const host = useUiHost();\n const page = useDeclared(resource);\n return useQuery({\n queryKey: ['mistri-ui', 'record', ...host.scope, resource, key, show, page],\n queryFn: async () => (await host.record(resource, key!, show, page ? { page } : {})) ?? null,\n enabled: key !== undefined,\n });\n}\n\n/**\n * A resource's rows grouped and measured: `useBreakdown('pay_stub', { by: 'status', measure: 'sum net' })`.\n * Each row is keyed as the server names its columns: the groups by their paths (`status`, `day(moved_at)`),\n * the measure as written (`count`, `sum(net)`, `max(on_hand_after)`).\n */\nexport function useBreakdown(resource: string, options: UiBreakdownOptions): UseQueryResult<UiRow[]> {\n const host = useUiHost();\n const page = useDeclared(resource);\n const asked = page ? { ...options, page } : options;\n return useQuery({\n queryKey: ['mistri-ui', 'breakdown', ...host.scope, resource, asked],\n queryFn: () => host.breakdown(resource, asked),\n });\n}\n\n/** Where a component may send the reader: a record (as a page, a peek or a dialog), one of the App's views, or one of its forms in a dialog. */\nexport function useNavigate(): {\n openRecord(resource: string, key: Readonly<Record<string, unknown>>, options?: { mode?: OpenMode; label?: string }): void;\n openView(view: string, options?: UiOpenViewOptions): void;\n openForm(view: string, prefill?: Readonly<Record<string, string | number>>): void;\n publicLink(view: string): string | undefined;\n} {\n const host = useUiHost();\n return {\n openRecord: (resource, key, options) => host.openRecord(resource, key, options),\n openView: (view, options) => host.openView(view, options),\n openForm: (view, prefill) => host.openForm(view, prefill),\n publicLink: (view) => host.publicLink(view),\n };\n}\n\n/** The page's timeline composer, from a custom section beside it: `fill` puts a template's words in the box (and\n chooses Reply or Internal note, where the page offers it) for the reader to edit and send — it never sends. It\n answers false when the page draws no composer. */\nexport function useComposer(): { fill(text: string, options?: { mode?: 'reply' | 'note' }): boolean } {\n const host = useUiHost();\n return { fill: (text, options = {}) => host.fillComposer(text, options.mode) };\n}\n\n/** Where a file resource's row is served, for an `<img>`: `useFile('member_avatar')({ id: 4 }, { thumbnail: true })`. */\nexport function useFile(\n resource: string,\n): (key: Readonly<Record<string, unknown>>, options?: { thumbnail?: boolean }) => string | undefined {\n const host = useUiHost();\n useDeclared(resource);\n return useCallback((key, options) => host.fileAddress(resource, key, options), [host, resource]);\n}\n\n/** Who is reading: signed in or not, and the signed-in account's id. Redraws when that changes. */\nexport function useViewer(): UiViewer {\n const host = useUiHost();\n const said = useSyncExternalStore(\n host.subscribeViewer,\n () => JSON.stringify(host.viewer()),\n () => '',\n );\n return said ? (JSON.parse(said) as UiViewer) : host.viewer();\n}\n\nconst keyText = (key: Readonly<Record<string, unknown>>) =>\n JSON.stringify(\n Object.keys(key)\n .sort()\n .map((column) => [column, String(key[column])]),\n );\n\n/** Why a command cannot be run on a record, before any click (`useCommand(...).reason(record)`). */\nexport type CommandUnavailable = 'signed-out' | 'not-granted' | 'unavailable';\n\n/** A command as a component holds it (`useCommand`). */\ninterface UiCommand {\n label: string;\n granted: boolean;\n /** Whether it is available on this record now; undefined until the server has said. */\n available(record: Readonly<Record<string, unknown>>): boolean | undefined;\n /**\n * Why it cannot be run on this record, said before any click: `'signed-out'`, `'not-granted'` (the\n * reader's role is not granted it), or `'unavailable'` (the server said its `when` does not hold for\n * this record and reader now); undefined while it can be, and until the server has said. Nothing the\n * page did not already know: a precondition only the command's handler checks is the App's to say.\n */\n reason(record: Readonly<Record<string, unknown>>): CommandUnavailable | undefined;\n /** Whether a run on this record is on its way. */\n pending(record: Readonly<Record<string, unknown>>): boolean;\n run(\n record: Readonly<Record<string, unknown>>,\n input?: Readonly<Record<string, unknown>>,\n options?: UiCommandOptions,\n ): Promise<UiCommandOutcome>;\n open(\n record: Readonly<Record<string, unknown>>,\n input?: Readonly<Record<string, unknown>>,\n options?: UiCommandOptions,\n ): Promise<UiCommandOutcome>;\n /**\n * The choices one of its inputs offers, as they were served with the command: a choice's declared options, or a\n * table's rows (`field.choice({ from })`) where they come with it — on a public page, read as the public reads them\n * and kept until a row changes, so the page draws its own select with no read of its own. Undefined for an input\n * that offers none, or whose rows its own form reads.\n */\n choices(field: string): readonly UiChoice[] | undefined;\n}\n\n/**\n * One of the App's commands, as its actions offer it, by name: `useCommand('reactToPost')`.\n * A command no action offers and a signed-in form does names no record: it\n * is sent as its form sends it, and the record handed in is not read.\n *\n * `run(record, input)` sends it when the input is complete and valid, and\n * opens the platform's own form, filled with what was given, when it is not;\n * `open` always opens the form. Either way it is the one command pipeline —\n * prepared for the record's revision, sent once under a request key,\n * refused in the server's words, the page's reads refreshed after it — and\n * nothing a component sends is a write of its own. `available(record)` asks\n * the server whether the command's `when` holds for this record and this\n * reader, once per record, and answers undefined until it has; `reason(record)`\n * says why not in a word. A signed-out reader is granted no command. An applied\n * run resolves with what the command returned (`output`), so a component acts on\n * what it made without looking it up.\n */\nexport function useCommand(ref: UiCommandRef): UiCommand {\n const host = useUiHost();\n /* A free-form page runs what it declared (definePage, `commands`), as it reads what it declared. */\n const page = useContext(UiPageContext);\n if (page && !page.commands.includes(ref)) {\n throw new Error(\n say('thePageRunsIsNotOne', {\n label: page.label,\n map: page.commands.length ? page.commands.map((name) => `\"${name}\"`).join(', ') : say('noCommands'),\n command: ref,\n }),\n );\n }\n const viewer = useViewer();\n const handle = useMemo(() => host.command(ref, page?.view), [host, ref, page?.view, viewer.signedIn, viewer.account]); // eslint-disable-line react-hooks/exhaustive-deps\n const [answers, setAnswers] = useState<ReadonlyMap<string, boolean>>(new Map());\n const [running, setRunning] = useState<ReadonlySet<string>>(new Set());\n const asked = useRef(new Map<string, Readonly<Record<string, unknown>>>());\n const wanted = useRef(new Map<string, Readonly<Record<string, unknown>>>());\n const [round, setRound] = useState(0);\n /* The handle whose answers are wanted: one for another reader or command asks everything again. */\n const current = useRef(handle);\n useEffect(() => {\n if (current.current === handle) return;\n current.current = handle;\n asked.current.clear();\n setAnswers(new Map());\n }, [handle]);\n useEffect(\n () => () => {\n current.current = undefined as unknown as typeof handle;\n },\n [],\n );\n /* The records a draw asked about, asked of the server after it (one batch, commandAvailability.ts). */\n useEffect(() => {\n const ask = [...wanted.current].filter(([text]) => !asked.current.has(text));\n wanted.current.clear();\n if (!ask.length) return;\n for (const [text, key] of ask) asked.current.set(text, key);\n const by = handle;\n void Promise.all(ask.map(async ([text, key]) => [text, by.granted ? await by.available(key).catch(() => false) : false] as const)).then(\n (results) => {\n if (current.current === by) setAnswers((before) => new Map([...before, ...results]));\n },\n );\n });\n /* Asked again after a run, keeping the last answers until the new ones arrive: a chip does not blink. */\n const again = () => {\n asked.current.clear();\n setRound((n) => n + 1);\n };\n const track = (text: string, work: Promise<UiCommandOutcome>) => {\n setRunning((before) => new Set(before).add(text));\n return work.finally(() => {\n setRunning((before) => {\n const next = new Set(before);\n next.delete(text);\n return next;\n });\n /* What a command changed may change what is available: asked again after it settles. */\n again();\n });\n };\n void round;\n const available = (record: Readonly<Record<string, unknown>>) => {\n const text = keyText(record);\n if (!asked.current.has(text)) wanted.current.set(text, record);\n return answers.get(text);\n };\n return {\n label: handle.label,\n granted: handle.granted,\n available,\n reason(record) {\n // A public page's public command is everyone's: granted, signed in or not (publicPageCommand.ts).\n if (!viewer.signedIn && !handle.granted) return 'signed-out';\n if (!handle.granted) return 'not-granted';\n return available(record) === false ? 'unavailable' : undefined;\n },\n pending: (record) => running.has(keyText(record)),\n run: (record, input, options) => track(keyText(record), handle.run(record, input, options)),\n open: (record, input, options) => track(keyText(record), handle.open(record, input, options)),\n choices: (field) => handle.choices?.(field),\n };\n}\n\n/**\n * A free-form page's place, kept in its address: `const [list, setList] = useAddressState('list')` reads and writes\n * `/{app}/pick-walk?list=12`, so a page reached by a link, a reload or Back opens where the reader was.\n * The name is one of the page's declared `params` (a page's `useParam` is this hook). A change refines the place the\n * reader is on, in the address as they go; `{ push: true }` makes it a step Back returns from.\n */\nexport function useAddressState(\n name: string,\n): [string | undefined, (value: string | number | undefined, options?: { push?: boolean }) => void] {\n const page = useContext(UiPageContext);\n if (!page) throw new Error(say('useaddressstateKeepsAPages'));\n if (!page.params.includes(name)) {\n throw new Error(\n say('thePageKeepsInItsAddress', {\n label: page.label,\n params: page.params.length ? page.params.map((param) => `\"${param}\"`).join(', ') : say('noParameters'),\n name,\n }),\n );\n }\n const set = useCallback(\n (value: string | number | undefined, options?: { push?: boolean }) =>\n page.set(name, value === undefined || value === '' ? undefined : String(value), options),\n [page, name],\n );\n return [page.get(name), set];\n}\n\n/**\n * One of the App's messages (`messages/<locale>.ts`) in the reader's\n * language, its `{name}`s filled from `args`: `useMessage('help.title')`,\n * `useMessage('help.results', { count: 3 })`. Redraws when the reader picks\n * another language. A key the catalog lacks is said as itself.\n */\nexport function useMessage(key: string, args?: Readonly<Record<string, string | number | boolean | Date | null | undefined>>): string {\n const host = useUiHost();\n useSyncExternalStore(subscribeMessages, messageLanguage, messageLanguage);\n return host.message(key, args);\n}\n\n/** How `useFormat().money` says a figure: as a column's display rule says one (`format: 'money'`). */\ninterface UiMoneyFormat {\n /** An ISO 4217 code; the App's `ui.currency` when not given. */\n currency?: string;\n /** The value is kept in minor units: 1999 is said as 19.99, exactly. */\n minor?: boolean;\n /** Without the minor digits where they are all zero: \"$24,495\", and \"$24,495.50\" still. */\n whole?: boolean;\n /** Compact from a thousand (\"$27.9K\"), for a figure meant to be glanced at; put the exact one in its title. */\n compact?: boolean;\n}\n\n/* Where a compact figure starts, as a metric card's (dashboardModel.ts CARD_COMPACT). */\nconst COMPACT_FROM = 1000;\n\n/**\n * Money said as the display rules say it: exact to the currency's minor digits, a decimal string past 2^53 digit for\n * digit (never through Number()), minor units read exactly. A currency code alone is `{ currency }`.\n */\nfunction sayMoney(value: number | string, options: string | UiMoneyFormat = {}): string {\n const { currency, minor, whole, compact } = typeof options === 'string' ? { currency: options } : options;\n const code = currency || defaultCurrency();\n const major = minor ? minorFigure(value, code) : value;\n if (major === undefined) return String(value);\n if (compact && Math.abs(Number(major)) >= COMPACT_FROM)\n return formatMoney(Number(major), code, { notation: 'compact', maximumFractionDigits: 1 });\n return whole ? formatWholeMoney(major, code) : formatMoney(major, code);\n}\n\n/** Figures in the App's locale, currency and timezone (`ui.locale`, `ui.currency`, `ui.timezone`), as every built-in section says them. */\nexport function useFormat() {\n return {\n number: (value: number | string, options?: Intl.NumberFormatOptions) => formatNumber(value, options),\n money: (value: number | string, options?: string | UiMoneyFormat) => sayMoney(value, options),\n percent: (value: number) => formatPercent(value),\n date: (value: string) => formatDate(value),\n /** A moment as the App's clock says it; with `timezone`, the instant said in that zone with its name (\"2:30 PM PDT\"). */\n dateTime: (value: string, options?: { timezone?: string }) =>\n options?.timezone ? formatAbsolute(value, { time: true, zone: options.timezone }) : formatDateTime(value),\n /** \"in 3 days\", \"yesterday\"; undefined for a value that is not a date. */\n relative: (value: string) => formatRelativeDay(value) ?? undefined,\n };\n}\n\n/** The look the App wears for this reader, light or dark, and the density. */\nexport function useLook(): UiLook {\n const host = useUiHost();\n const said = useSyncExternalStore(\n host.subscribeLook,\n () => JSON.stringify(host.look()),\n () => '',\n );\n return said ? (JSON.parse(said) as UiLook) : host.look();\n}\n\n/** One design token's value as the look resolves it — `useToken('--accent')` — for a canvas or an SVG attribute. CSS can say `var(--accent)` itself. */\nexport function useToken(name: `--${string}`): string {\n const host = useUiHost();\n return useSyncExternalStore(\n host.subscribeLook,\n () => host.token(name),\n () => '',\n );\n}\n\n/** The section's measured width, and whether it is phone-narrow: a component lays itself out for the room it has. */\nexport function useSectionSize(): UiSize {\n return useContext(UiSizeContext);\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { gt as defineMessages } from "./shared-DJZjSi3J.js";
2
- import { L as state, M as saveJson, h as loadJson } from "./shared-DPAVoWY0.js";
2
+ import { L as state, M as saveJson, h as loadJson } from "./shared-BoLbc2WD.js";
3
3
  import { useSyncExternalStore } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  // packages/kit/src/client/components/favorites.ts
@@ -145,4 +145,4 @@ window too narrow for the column, not only for a handset. */
145
145
  var RAIL_QUERY = "(max-width: 860px)";
146
146
  export { relabelFavorite as a, FavoriteStar as i, RAIL_QUERY as n, useMediaQuery as r, PHONE_QUERY as t };
147
147
 
148
- //# sourceMappingURL=shared-DrFb-XtA.js.map
148
+ //# sourceMappingURL=shared-WhbuObEW.js.map