@alfadocs/ui-kit-debug 0.69.0 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (788) hide show
  1. package/dist/_chunks/address-fields-CPbFJ8e8.js +246 -0
  2. package/dist/_chunks/address-fields-CPbFJ8e8.js.map +1 -0
  3. package/dist/_chunks/{agenda-card-BxSFkqgY.js → agenda-card-BQ-IKAru.js} +2 -2
  4. package/dist/_chunks/{agenda-card-BxSFkqgY.js.map → agenda-card-BQ-IKAru.js.map} +1 -1
  5. package/dist/_chunks/{agenda-tray-g0kg7HwB.js → agenda-tray-CGXRk58j.js} +2 -2
  6. package/dist/_chunks/{agenda-tray-g0kg7HwB.js.map → agenda-tray-CGXRk58j.js.map} +1 -1
  7. package/dist/_chunks/{ai-consent-banner-CXlsNX1c.js → ai-consent-banner-Be-h9mRI.js} +3 -3
  8. package/dist/_chunks/{ai-consent-banner-CXlsNX1c.js.map → ai-consent-banner-Be-h9mRI.js.map} +1 -1
  9. package/dist/_chunks/{ai-prompt-input-CuhTo9mh.js → ai-prompt-input-V4DdOeqv.js} +2 -2
  10. package/dist/_chunks/{ai-prompt-input-CuhTo9mh.js.map → ai-prompt-input-V4DdOeqv.js.map} +1 -1
  11. package/dist/_chunks/{alert-_mUKLmwA.js → alert-CHYZ96tR.js} +150 -96
  12. package/dist/_chunks/alert-CHYZ96tR.js.map +1 -0
  13. package/dist/_chunks/{alia-sidebar-B47qRQb5.js → alia-sidebar-DvIUzIX9.js} +107 -106
  14. package/dist/_chunks/alia-sidebar-DvIUzIX9.js.map +1 -0
  15. package/dist/_chunks/{anamnesis-card-DRmE24OQ.js → anamnesis-card-DvYCa16e.js} +2 -2
  16. package/dist/_chunks/{anamnesis-card-DRmE24OQ.js.map → anamnesis-card-DvYCa16e.js.map} +1 -1
  17. package/dist/_chunks/anatomy-scheme-CXSk11UJ.js +2445 -0
  18. package/dist/_chunks/anatomy-scheme-CXSk11UJ.js.map +1 -0
  19. package/dist/_chunks/annotation-marker-qt5R9WZX.js +120 -0
  20. package/dist/_chunks/annotation-marker-qt5R9WZX.js.map +1 -0
  21. package/dist/_chunks/{antenatal-schedule-timeline-35ebkcZT.js → antenatal-schedule-timeline-CwXrQRm1.js} +2 -2
  22. package/dist/_chunks/{antenatal-schedule-timeline-35ebkcZT.js.map → antenatal-schedule-timeline-CwXrQRm1.js.map} +1 -1
  23. package/dist/_chunks/{app-frame-BYx1gcV7.js → app-frame-DIEMIC5V.js} +67 -56
  24. package/dist/_chunks/app-frame-DIEMIC5V.js.map +1 -0
  25. package/dist/_chunks/appointment-card-DVaeJNVB.js +294 -0
  26. package/dist/_chunks/appointment-card-DVaeJNVB.js.map +1 -0
  27. package/dist/_chunks/appointment-timeline-PJgnrjFb.js +388 -0
  28. package/dist/_chunks/appointment-timeline-PJgnrjFb.js.map +1 -0
  29. package/dist/_chunks/appointment-tray-B16QPGbm.js +193 -0
  30. package/dist/_chunks/appointment-tray-B16QPGbm.js.map +1 -0
  31. package/dist/_chunks/{audio-recorder-DYXXnGug.js → audio-recorder-DNDsOLqO.js} +3 -3
  32. package/dist/_chunks/{audio-recorder-DYXXnGug.js.map → audio-recorder-DNDsOLqO.js.map} +1 -1
  33. package/dist/_chunks/{autocomplete-DOeGouCL.js → autocomplete-BrONKN8l.js} +168 -146
  34. package/dist/_chunks/autocomplete-BrONKN8l.js.map +1 -0
  35. package/dist/_chunks/{badge-CqGsX32l.js → badge-DCOqV9mI.js} +32 -27
  36. package/dist/_chunks/badge-DCOqV9mI.js.map +1 -0
  37. package/dist/_chunks/{bishop-score-PJI3AXzA.js → bishop-score-Cym_TeQY.js} +3 -3
  38. package/dist/_chunks/{bishop-score-PJI3AXzA.js.map → bishop-score-Cym_TeQY.js.map} +1 -1
  39. package/dist/_chunks/{bmi-calculator-BZtIJ53x.js → bmi-calculator-zjeY4E7J.js} +2 -2
  40. package/dist/_chunks/{bmi-calculator-BZtIJ53x.js.map → bmi-calculator-zjeY4E7J.js.map} +1 -1
  41. package/dist/_chunks/{booking-C3VqFReX.js → booking-C7do4vaR.js} +7 -7
  42. package/dist/_chunks/{booking-C3VqFReX.js.map → booking-C7do4vaR.js.map} +1 -1
  43. package/dist/_chunks/{button-group-Ciq6J4IW.js → button-group-CvEnVzY7.js} +32 -35
  44. package/dist/_chunks/{button-group-Ciq6J4IW.js.map → button-group-CvEnVzY7.js.map} +1 -1
  45. package/dist/_chunks/{care-plan-card-CvFGXa2z.js → care-plan-card-DzPDYgtK.js} +5 -5
  46. package/dist/_chunks/{care-plan-card-CvFGXa2z.js.map → care-plan-card-DzPDYgtK.js.map} +1 -1
  47. package/dist/_chunks/{care-plan-entry-card-C3E_gClk.js → care-plan-entry-card-CEnQy7YP.js} +5 -5
  48. package/dist/_chunks/{care-plan-entry-card-C3E_gClk.js.map → care-plan-entry-card-CEnQy7YP.js.map} +1 -1
  49. package/dist/_chunks/care-plan-header-DcXFXWit.js +198 -0
  50. package/dist/_chunks/care-plan-header-DcXFXWit.js.map +1 -0
  51. package/dist/_chunks/{chat-message-3V54YipB.js → chat-message-DzpcJR-q.js} +25 -23
  52. package/dist/_chunks/chat-message-DzpcJR-q.js.map +1 -0
  53. package/dist/_chunks/city-input-Dkgaak7I.js +169 -0
  54. package/dist/_chunks/city-input-Dkgaak7I.js.map +1 -0
  55. package/dist/_chunks/clinical-note-card-BUvNMNGL.js +436 -0
  56. package/dist/_chunks/clinical-note-card-BUvNMNGL.js.map +1 -0
  57. package/dist/_chunks/clipboard-list-S7s-MXQq.js +25 -0
  58. package/dist/_chunks/clipboard-list-S7s-MXQq.js.map +1 -0
  59. package/dist/_chunks/{combobox-Clum7gJ1.js → combobox-DnqSF0IH.js} +131 -114
  60. package/dist/_chunks/combobox-DnqSF0IH.js.map +1 -0
  61. package/dist/_chunks/connection-status-CY1HV8Wg.js +108 -0
  62. package/dist/_chunks/connection-status-CY1HV8Wg.js.map +1 -0
  63. package/dist/_chunks/{contact-profile-card-Dramqa9C.js → contact-profile-card-DDPwRFiP.js} +2 -2
  64. package/dist/_chunks/{contact-profile-card-Dramqa9C.js.map → contact-profile-card-DDPwRFiP.js.map} +1 -1
  65. package/dist/_chunks/control-room-rail-FAQZrGVL.js +333 -0
  66. package/dist/_chunks/control-room-rail-FAQZrGVL.js.map +1 -0
  67. package/dist/_chunks/country-select-BwUZQvTa.js +709 -0
  68. package/dist/_chunks/country-select-BwUZQvTa.js.map +1 -0
  69. package/dist/_chunks/{cycle-calculator-DmRGJNaT.js → cycle-calculator-CCmPwcBl.js} +2 -2
  70. package/dist/_chunks/{cycle-calculator-DmRGJNaT.js.map → cycle-calculator-CCmPwcBl.js.map} +1 -1
  71. package/dist/_chunks/{dependent-selector-CG_FOHya.js → dependent-selector-DUV4thxX.js} +2 -2
  72. package/dist/_chunks/{dependent-selector-CG_FOHya.js.map → dependent-selector-DUV4thxX.js.map} +1 -1
  73. package/dist/_chunks/{document-scanner-CTubA0-N.js → document-scanner-C_AxLooF.js} +3 -3
  74. package/dist/_chunks/{document-scanner-CTubA0-N.js.map → document-scanner-C_AxLooF.js.map} +1 -1
  75. package/dist/_chunks/{due-date-calculator-BTmsIQqD.js → due-date-calculator-Brdj-euS.js} +3 -3
  76. package/dist/_chunks/{due-date-calculator-BTmsIQqD.js.map → due-date-calculator-Brdj-euS.js.map} +1 -1
  77. package/dist/_chunks/editable-currency-cell-renderer-CGELrkIj.js +410 -0
  78. package/dist/_chunks/editable-currency-cell-renderer-CGELrkIj.js.map +1 -0
  79. package/dist/_chunks/email-input-DJ7EXklP.js +397 -0
  80. package/dist/_chunks/{email-input-B_Y55f5G.js.map → email-input-DJ7EXklP.js.map} +1 -1
  81. package/dist/_chunks/{entity-card-COhmqHly.js → entity-card-DmrgYSEX.js} +38 -20
  82. package/dist/_chunks/{entity-card-COhmqHly.js.map → entity-card-DmrgYSEX.js.map} +1 -1
  83. package/dist/_chunks/entity-summary-CaM1Y-xE.js +291 -0
  84. package/dist/_chunks/entity-summary-CaM1Y-xE.js.map +1 -0
  85. package/dist/_chunks/{fetal-weight-CRz7KE2D.js → fetal-weight-DNCkyeVo.js} +2 -2
  86. package/dist/_chunks/{fetal-weight-CRz7KE2D.js.map → fetal-weight-DNCkyeVo.js.map} +1 -1
  87. package/dist/_chunks/field-array-siUZzfYe.js +146 -0
  88. package/dist/_chunks/field-array-siUZzfYe.js.map +1 -0
  89. package/dist/_chunks/field-value-3jMM0uDx.js +415 -0
  90. package/dist/_chunks/field-value-3jMM0uDx.js.map +1 -0
  91. package/dist/_chunks/{file-upload-5ScQd4fE.js → file-upload-DwZcAK8D.js} +2 -1
  92. package/dist/_chunks/{file-upload-5ScQd4fE.js.map → file-upload-DwZcAK8D.js.map} +1 -1
  93. package/dist/_chunks/{freemium-paywall-DZ2mBS3w.js → freemium-paywall-WYlNO7yT.js} +2 -2
  94. package/dist/_chunks/{freemium-paywall-DZ2mBS3w.js.map → freemium-paywall-WYlNO7yT.js.map} +1 -1
  95. package/dist/_chunks/{gestational-age-calculator-BleUdhbI.js → gestational-age-calculator-DKzEV5Qi.js} +4 -4
  96. package/dist/_chunks/{gestational-age-calculator-BleUdhbI.js.map → gestational-age-calculator-DKzEV5Qi.js.map} +1 -1
  97. package/dist/_chunks/hash-CysBBS_N.js +17 -0
  98. package/dist/_chunks/hash-CysBBS_N.js.map +1 -0
  99. package/dist/_chunks/{hcg-doubling-CnjDXX6U.js → hcg-doubling-C7bmuaU3.js} +2 -2
  100. package/dist/_chunks/{hcg-doubling-CnjDXX6U.js.map → hcg-doubling-C7bmuaU3.js.map} +1 -1
  101. package/dist/_chunks/iban-input-B0TWzR1R.js +436 -0
  102. package/dist/_chunks/iban-input-B0TWzR1R.js.map +1 -0
  103. package/dist/_chunks/icon-picker-0B7KhrF1.js +272 -0
  104. package/dist/_chunks/icon-picker-0B7KhrF1.js.map +1 -0
  105. package/dist/_chunks/image-cropper-D9jqJy19.js +367 -0
  106. package/dist/_chunks/image-cropper-D9jqJy19.js.map +1 -0
  107. package/dist/_chunks/{actions-cell-renderer-DrcaxB0w.js → link-cell-renderer-De_SLjSq.js} +792 -668
  108. package/dist/_chunks/link-cell-renderer-De_SLjSq.js.map +1 -0
  109. package/dist/_chunks/list-checks-BUs75d_o.js +18 -0
  110. package/dist/_chunks/list-checks-BUs75d_o.js.map +1 -0
  111. package/dist/_chunks/lock-CKOIn0IK.js +15 -0
  112. package/dist/_chunks/lock-CKOIn0IK.js.map +1 -0
  113. package/dist/_chunks/{marketplace-app-shell-6T9W4Knl.js → marketplace-app-shell-BGqkywsi.js} +5 -5
  114. package/dist/_chunks/{marketplace-app-shell-6T9W4Knl.js.map → marketplace-app-shell-BGqkywsi.js.map} +1 -1
  115. package/dist/_chunks/message-card-DsHFFiL1.js +319 -0
  116. package/dist/_chunks/message-card-DsHFFiL1.js.map +1 -0
  117. package/dist/_chunks/{message-tray-DwrBLJlf.js → message-tray-C0a6CL1_.js} +172 -135
  118. package/dist/_chunks/message-tray-C0a6CL1_.js.map +1 -0
  119. package/dist/_chunks/{multi-select-BdHHDrRN.js → multi-select-WE4S9FIF.js} +75 -63
  120. package/dist/_chunks/{multi-select-BdHHDrRN.js.map → multi-select-WE4S9FIF.js.map} +1 -1
  121. package/dist/_chunks/nav-grid-9xphY3FM.js +169 -0
  122. package/dist/_chunks/nav-grid-9xphY3FM.js.map +1 -0
  123. package/dist/_chunks/notes-panel-DXiMfuvp.js +320 -0
  124. package/dist/_chunks/notes-panel-DXiMfuvp.js.map +1 -0
  125. package/dist/_chunks/notification-card-BMqNzCIt.js +290 -0
  126. package/dist/_chunks/notification-card-BMqNzCIt.js.map +1 -0
  127. package/dist/_chunks/{notification-tray-Btb9oQeZ.js → notification-tray-BmUlCx3g.js} +201 -166
  128. package/dist/_chunks/notification-tray-BmUlCx3g.js.map +1 -0
  129. package/dist/_chunks/{operator-hero-CP2Nhupm.js → operator-hero-BO8TqzX2.js} +3 -3
  130. package/dist/_chunks/{operator-hero-CP2Nhupm.js.map → operator-hero-BO8TqzX2.js.map} +1 -1
  131. package/dist/_chunks/panel-header-D313n_9-.js +105 -0
  132. package/dist/_chunks/panel-header-D313n_9-.js.map +1 -0
  133. package/dist/_chunks/patient-details-DgfTJimE.js +759 -0
  134. package/dist/_chunks/patient-details-DgfTJimE.js.map +1 -0
  135. package/dist/_chunks/{patient-search-CBC_ySF6.js → patient-search-CSWQKOSP.js} +3 -3
  136. package/dist/_chunks/{patient-search-CBC_ySF6.js.map → patient-search-CSWQKOSP.js.map} +1 -1
  137. package/dist/_chunks/{patient-shell-DV3XEtIB.js → patient-shell-BMwsIKlW.js} +3 -3
  138. package/dist/_chunks/{patient-shell-DV3XEtIB.js.map → patient-shell-BMwsIKlW.js.map} +1 -1
  139. package/dist/_chunks/patient-summary-card-D4NdgYJB.js +452 -0
  140. package/dist/_chunks/patient-summary-card-D4NdgYJB.js.map +1 -0
  141. package/dist/_chunks/patient-table-CERknpd8.js +1110 -0
  142. package/dist/_chunks/patient-table-CERknpd8.js.map +1 -0
  143. package/dist/_chunks/{payment-form-DvjwYVIT.js → payment-form-CxqIXqw7.js} +2 -2
  144. package/dist/_chunks/{payment-form-DvjwYVIT.js.map → payment-form-CxqIXqw7.js.map} +1 -1
  145. package/dist/_chunks/{payment-request-card-DioWKBUq.js → payment-request-card-Blf-MFNY.js} +125 -136
  146. package/dist/_chunks/payment-request-card-Blf-MFNY.js.map +1 -0
  147. package/dist/_chunks/{pdf-viewer-D6BPfW2D.js → pdf-viewer-QfebdLOd.js} +192 -214
  148. package/dist/_chunks/pdf-viewer-QfebdLOd.js.map +1 -0
  149. package/dist/_chunks/{periodontal-chart-card-BuDEMbHE.js → periodontal-chart-card-hRRJY1NN.js} +2 -2
  150. package/dist/_chunks/{periodontal-chart-card-BuDEMbHE.js.map → periodontal-chart-card-hRRJY1NN.js.map} +1 -1
  151. package/dist/_chunks/permission-matrix-Bw5oexUt.js +174 -0
  152. package/dist/_chunks/permission-matrix-Bw5oexUt.js.map +1 -0
  153. package/dist/_chunks/position-grid-CcvqHaKN.js +169 -0
  154. package/dist/_chunks/position-grid-CcvqHaKN.js.map +1 -0
  155. package/dist/_chunks/postal-code-input-UCOYuRY2.js +192 -0
  156. package/dist/_chunks/postal-code-input-UCOYuRY2.js.map +1 -0
  157. package/dist/_chunks/{practice-results-KrTHqZua.js → practice-results-El5Z-oVp.js} +4 -4
  158. package/dist/_chunks/{practice-results-KrTHqZua.js.map → practice-results-El5Z-oVp.js.map} +1 -1
  159. package/dist/_chunks/{pregnancy-dating-DORUAOHB.js → pregnancy-dating-CunHrOpO.js} +4 -4
  160. package/dist/_chunks/{pregnancy-dating-DORUAOHB.js.map → pregnancy-dating-CunHrOpO.js.map} +1 -1
  161. package/dist/_chunks/{pregnancy-weight-gain-DVz4rr7-.js → pregnancy-weight-gain-BUNpTsH-.js} +2 -2
  162. package/dist/_chunks/{pregnancy-weight-gain-DVz4rr7-.js.map → pregnancy-weight-gain-BUNpTsH-.js.map} +1 -1
  163. package/dist/_chunks/{product-hub-panel-e6pW220e.js → product-hub-panel-DtU7KXxm.js} +257 -217
  164. package/dist/_chunks/product-hub-panel-DtU7KXxm.js.map +1 -0
  165. package/dist/_chunks/province-select-D_TZvix3.js +261 -0
  166. package/dist/_chunks/province-select-D_TZvix3.js.map +1 -0
  167. package/dist/_chunks/{public-header.agent-DqkqA-ca.js → public-header.agent-TxmC_x1I.js} +2 -2
  168. package/dist/_chunks/{public-header.agent-DqkqA-ca.js.map → public-header.agent-TxmC_x1I.js.map} +1 -1
  169. package/dist/_chunks/radiograph-panel.agent-tWjN2nHX.js +553 -0
  170. package/dist/_chunks/radiograph-panel.agent-tWjN2nHX.js.map +1 -0
  171. package/dist/_chunks/reviews-panel-DxkSrgMl.js +559 -0
  172. package/dist/_chunks/reviews-panel-DxkSrgMl.js.map +1 -0
  173. package/dist/_chunks/rich-text-editor-C8tyGjfb.js +2621 -0
  174. package/dist/_chunks/rich-text-editor-C8tyGjfb.js.map +1 -0
  175. package/dist/_chunks/{scroll-area-5wNK0Cyz.js → scroll-area-BZOvUhwQ.js} +2 -2
  176. package/dist/_chunks/scroll-area-BZOvUhwQ.js.map +1 -0
  177. package/dist/_chunks/{select-DMLG44F5.js → select-KsyRr8WH.js} +114 -102
  178. package/dist/_chunks/select-KsyRr8WH.js.map +1 -0
  179. package/dist/_chunks/{sheet-BxsE7eQm.js → sheet-umkfZjF6.js} +53 -42
  180. package/dist/_chunks/sheet-umkfZjF6.js.map +1 -0
  181. package/dist/_chunks/{sidebar-DY9jGjgt.js → sidebar-QCp9wHNP.js} +125 -113
  182. package/dist/_chunks/sidebar-QCp9wHNP.js.map +1 -0
  183. package/dist/_chunks/{sign-document-B4DeRhTe.js → sign-document-By6hMOra.js} +2 -2
  184. package/dist/_chunks/{sign-document-B4DeRhTe.js.map → sign-document-By6hMOra.js.map} +1 -1
  185. package/dist/_chunks/{stepper-accordion-Dki6r9ZE.js → stepper-accordion-DC-H-8v4.js} +38 -48
  186. package/dist/_chunks/stepper-accordion-DC-H-8v4.js.map +1 -0
  187. package/dist/_chunks/tab-bar-Bv9nGNdO.js +262 -0
  188. package/dist/_chunks/tab-bar-Bv9nGNdO.js.map +1 -0
  189. package/dist/_chunks/{tabs-BxcOziCo.js → tabs-CYZVKKDl.js} +2 -2
  190. package/dist/_chunks/{tabs-BxcOziCo.js.map → tabs-CYZVKKDl.js.map} +1 -1
  191. package/dist/_chunks/task-card-DCdsI0ZT.js +189 -0
  192. package/dist/_chunks/task-card-DCdsI0ZT.js.map +1 -0
  193. package/dist/_chunks/{task-tray-qOEQflu4.js → task-tray-DNVejijD.js} +2 -2
  194. package/dist/_chunks/{task-tray-qOEQflu4.js.map → task-tray-DNVejijD.js.map} +1 -1
  195. package/dist/_chunks/tasks-panel-C9odmawT.js +757 -0
  196. package/dist/_chunks/tasks-panel-C9odmawT.js.map +1 -0
  197. package/dist/_chunks/token-insert-menu-CFQqTe_n.js +147 -0
  198. package/dist/_chunks/token-insert-menu-CFQqTe_n.js.map +1 -0
  199. package/dist/_chunks/tool-rail-BZx0-yIr.js +524 -0
  200. package/dist/_chunks/tool-rail-BZx0-yIr.js.map +1 -0
  201. package/dist/_chunks/tooth-scheme-DJZtzfeY.js +2133 -0
  202. package/dist/_chunks/tooth-scheme-DJZtzfeY.js.map +1 -0
  203. package/dist/_chunks/{transaction-chip-DK84XCBU.js → transaction-chip-CscoQbxF.js} +88 -61
  204. package/dist/_chunks/transaction-chip-CscoQbxF.js.map +1 -0
  205. package/dist/_chunks/{transcript-panel-3THQX6nJ.js → transcript-panel-CHGHHHdT.js} +95 -83
  206. package/dist/_chunks/transcript-panel-CHGHHHdT.js.map +1 -0
  207. package/dist/_chunks/{unit-converter-YEpD9evj.js → unit-converter-CwlZbfdn.js} +2 -2
  208. package/dist/_chunks/{unit-converter-YEpD9evj.js.map → unit-converter-CwlZbfdn.js.map} +1 -1
  209. package/dist/_chunks/use-clamp-overflow-DQE2kwZ9.js +20 -0
  210. package/dist/_chunks/use-clamp-overflow-DQE2kwZ9.js.map +1 -0
  211. package/dist/_chunks/use-edge-resize-ZnGG7gyO.js.map +1 -1
  212. package/dist/_chunks/use-overflow-collapse-BIOzKbni.js +32 -0
  213. package/dist/_chunks/use-overflow-collapse-BIOzKbni.js.map +1 -0
  214. package/dist/_chunks/use-persistent-state-nZwZAnE9.js +24 -0
  215. package/dist/_chunks/use-persistent-state-nZwZAnE9.js.map +1 -0
  216. package/dist/_chunks/{warning-stack-BsgaEbL8.js → warning-stack--sTrrBDA.js} +86 -101
  217. package/dist/_chunks/warning-stack--sTrrBDA.js.map +1 -0
  218. package/dist/_chunks/{workflow-map-Bdam9pGp.js → workflow-map-M8MBBHQm.js} +107 -119
  219. package/dist/_chunks/workflow-map-M8MBBHQm.js.map +1 -0
  220. package/dist/_chunks/zoom-out-CgVtf2Wx.js +29 -0
  221. package/dist/_chunks/zoom-out-CgVtf2Wx.js.map +1 -0
  222. package/dist/agent/index.js +5 -4
  223. package/dist/agent/index.js.map +1 -1
  224. package/dist/agent/types.d.ts +19 -2
  225. package/dist/agent/types.d.ts.map +1 -1
  226. package/dist/agent-catalog.json +3325 -322
  227. package/dist/agent-i18n/en.json +314 -14
  228. package/dist/components/_shared/entity-card/entity-card.d.ts +6 -0
  229. package/dist/components/_shared/entity-card/entity-card.d.ts.map +1 -1
  230. package/dist/components/_shared/entity-card/index.d.ts +1 -1
  231. package/dist/components/_shared/entity-card/index.d.ts.map +1 -1
  232. package/dist/components/_shared/field-value.d.ts +21 -0
  233. package/dist/components/_shared/field-value.d.ts.map +1 -0
  234. package/dist/components/_shared/field-visibility-cog.d.ts +20 -0
  235. package/dist/components/_shared/field-visibility-cog.d.ts.map +1 -0
  236. package/dist/components/_shared/field-visibility.d.ts +36 -0
  237. package/dist/components/_shared/field-visibility.d.ts.map +1 -0
  238. package/dist/components/_shared/option.d.ts +2 -0
  239. package/dist/components/_shared/option.d.ts.map +1 -1
  240. package/dist/components/_shared/patient-fields.d.ts +119 -0
  241. package/dist/components/_shared/patient-fields.d.ts.map +1 -0
  242. package/dist/components/address-fields/address-fields.agent.d.ts +9 -0
  243. package/dist/components/address-fields/address-fields.agent.d.ts.map +1 -0
  244. package/dist/components/address-fields/address-fields.d.ts +29 -0
  245. package/dist/components/address-fields/address-fields.d.ts.map +1 -0
  246. package/dist/components/address-fields/index.d.ts +5 -0
  247. package/dist/components/address-fields/index.d.ts.map +1 -0
  248. package/dist/components/address-fields/index.js +6 -0
  249. package/dist/components/agenda-card/index.js +1 -1
  250. package/dist/components/agenda-tray/index.js +1 -1
  251. package/dist/components/ai-consent-banner/index.js +1 -1
  252. package/dist/components/ai-prompt-input/index.js +1 -1
  253. package/dist/components/alert/alert.d.ts +5 -0
  254. package/dist/components/alert/alert.d.ts.map +1 -1
  255. package/dist/components/alert/index.js +1 -1
  256. package/dist/components/anamnesis-card/index.js +1 -1
  257. package/dist/components/anatomy-scheme/anatomy-face-paths.d.ts +15 -0
  258. package/dist/components/anatomy-scheme/anatomy-face-paths.d.ts.map +1 -0
  259. package/dist/components/anatomy-scheme/anatomy-muscle-paths.d.ts +20 -0
  260. package/dist/components/anatomy-scheme/anatomy-muscle-paths.d.ts.map +1 -0
  261. package/dist/components/anatomy-scheme/anatomy-scheme-data.d.ts +121 -0
  262. package/dist/components/anatomy-scheme/anatomy-scheme-data.d.ts.map +1 -0
  263. package/dist/components/anatomy-scheme/anatomy-scheme.agent.d.ts +6 -0
  264. package/dist/components/anatomy-scheme/anatomy-scheme.agent.d.ts.map +1 -0
  265. package/dist/components/anatomy-scheme/anatomy-scheme.d.ts +69 -0
  266. package/dist/components/anatomy-scheme/anatomy-scheme.d.ts.map +1 -0
  267. package/dist/components/anatomy-scheme/index.d.ts +6 -0
  268. package/dist/components/anatomy-scheme/index.d.ts.map +1 -0
  269. package/dist/components/anatomy-scheme/index.js +17 -0
  270. package/dist/components/anatomy-scheme/index.js.map +1 -0
  271. package/dist/components/annotation-marker/annotation-marker.d.ts +33 -0
  272. package/dist/components/annotation-marker/annotation-marker.d.ts.map +1 -0
  273. package/dist/components/annotation-marker/index.d.ts +3 -0
  274. package/dist/components/annotation-marker/index.d.ts.map +1 -0
  275. package/dist/components/annotation-marker/index.js +7 -0
  276. package/dist/components/annotation-marker/index.js.map +1 -0
  277. package/dist/components/app-frame/app-frame.d.ts +2 -2
  278. package/dist/components/app-frame/app-frame.d.ts.map +1 -1
  279. package/dist/components/app-frame/index.js +1 -1
  280. package/dist/components/appointment-card/appointment-card.d.ts +25 -1
  281. package/dist/components/appointment-card/appointment-card.d.ts.map +1 -1
  282. package/dist/components/appointment-card/index.js +6 -5
  283. package/dist/components/appointment-card/index.js.map +1 -1
  284. package/dist/components/appointment-timeline/appointment-timeline.agent.d.ts +4 -0
  285. package/dist/components/appointment-timeline/appointment-timeline.agent.d.ts.map +1 -0
  286. package/dist/components/appointment-timeline/appointment-timeline.d.ts +66 -0
  287. package/dist/components/appointment-timeline/appointment-timeline.d.ts.map +1 -0
  288. package/dist/components/appointment-timeline/index.d.ts +4 -0
  289. package/dist/components/appointment-timeline/index.d.ts.map +1 -0
  290. package/dist/components/appointment-timeline/index.js +6 -0
  291. package/dist/components/appointment-timeline/index.js.map +1 -0
  292. package/dist/components/audio-recorder/index.js +1 -1
  293. package/dist/components/autocomplete/autocomplete.d.ts +10 -0
  294. package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
  295. package/dist/components/autocomplete/index.js +1 -1
  296. package/dist/components/badge/badge.d.ts +6 -2
  297. package/dist/components/badge/badge.d.ts.map +1 -1
  298. package/dist/components/badge/index.js +1 -1
  299. package/dist/components/bishop-score/index.js +1 -1
  300. package/dist/components/bmi-calculator/index.js +1 -1
  301. package/dist/components/booking/index.js +1 -1
  302. package/dist/components/button-group/button-group.d.ts.map +1 -1
  303. package/dist/components/button-group/index.js +1 -1
  304. package/dist/components/care-plan-card/index.js +1 -1
  305. package/dist/components/care-plan-entry-card/index.js +1 -1
  306. package/dist/components/care-plan-header/care-plan-header.agent.d.ts +4 -0
  307. package/dist/components/care-plan-header/care-plan-header.agent.d.ts.map +1 -0
  308. package/dist/components/care-plan-header/care-plan-header.d.ts +111 -0
  309. package/dist/components/care-plan-header/care-plan-header.d.ts.map +1 -0
  310. package/dist/components/care-plan-header/index.d.ts +4 -0
  311. package/dist/components/care-plan-header/index.d.ts.map +1 -0
  312. package/dist/components/care-plan-header/index.js +6 -0
  313. package/dist/components/care-plan-header/index.js.map +1 -0
  314. package/dist/components/chat-message/chat-message.d.ts.map +1 -1
  315. package/dist/components/chat-message/index.js +1 -1
  316. package/dist/components/city-input/city-input.agent.d.ts +8 -0
  317. package/dist/components/city-input/city-input.agent.d.ts.map +1 -0
  318. package/dist/components/city-input/city-input.d.ts +57 -0
  319. package/dist/components/city-input/city-input.d.ts.map +1 -0
  320. package/dist/components/city-input/index.d.ts +5 -0
  321. package/dist/components/city-input/index.d.ts.map +1 -0
  322. package/dist/components/city-input/index.js +6 -0
  323. package/dist/components/city-input/index.js.map +1 -0
  324. package/dist/components/clinical-note-card/clinical-note-card.d.ts +21 -1
  325. package/dist/components/clinical-note-card/clinical-note-card.d.ts.map +1 -1
  326. package/dist/components/clinical-note-card/index.js +1 -1
  327. package/dist/components/combobox/combobox.d.ts +17 -0
  328. package/dist/components/combobox/combobox.d.ts.map +1 -1
  329. package/dist/components/combobox/index.js +1 -1
  330. package/dist/components/connection-status/connection-status.agent.d.ts +4 -0
  331. package/dist/components/connection-status/connection-status.agent.d.ts.map +1 -0
  332. package/dist/components/connection-status/connection-status.d.ts +36 -0
  333. package/dist/components/connection-status/connection-status.d.ts.map +1 -0
  334. package/dist/components/connection-status/index.d.ts +4 -0
  335. package/dist/components/connection-status/index.d.ts.map +1 -0
  336. package/dist/components/connection-status/index.js +6 -0
  337. package/dist/components/connection-status/index.js.map +1 -0
  338. package/dist/components/contact-profile-card/index.js +1 -1
  339. package/dist/components/control-room-rail/control-room-context.d.ts +53 -0
  340. package/dist/components/control-room-rail/control-room-context.d.ts.map +1 -0
  341. package/dist/components/control-room-rail/control-room-rail.agent.d.ts +4 -0
  342. package/dist/components/control-room-rail/control-room-rail.agent.d.ts.map +1 -0
  343. package/dist/components/control-room-rail/control-room-rail.d.ts +35 -0
  344. package/dist/components/control-room-rail/control-room-rail.d.ts.map +1 -0
  345. package/dist/components/control-room-rail/index.d.ts +6 -0
  346. package/dist/components/control-room-rail/index.d.ts.map +1 -0
  347. package/dist/components/control-room-rail/index.js +10 -0
  348. package/dist/components/control-room-rail/index.js.map +1 -0
  349. package/dist/components/counter/counter.d.ts +1 -1
  350. package/dist/components/country-select/country-select.agent.d.ts +8 -0
  351. package/dist/components/country-select/country-select.agent.d.ts.map +1 -0
  352. package/dist/components/country-select/country-select.d.ts +51 -0
  353. package/dist/components/country-select/country-select.d.ts.map +1 -0
  354. package/dist/components/country-select/index.d.ts +6 -0
  355. package/dist/components/country-select/index.d.ts.map +1 -0
  356. package/dist/components/country-select/index.js +9 -0
  357. package/dist/components/country-select/index.js.map +1 -0
  358. package/dist/components/country-select/iso-3166.d.ts +15 -0
  359. package/dist/components/country-select/iso-3166.d.ts.map +1 -0
  360. package/dist/components/cycle-calculator/index.js +1 -1
  361. package/dist/components/data-table/cell-renderers/actions-cell-renderer.d.ts +18 -0
  362. package/dist/components/data-table/cell-renderers/actions-cell-renderer.d.ts.map +1 -1
  363. package/dist/components/data-table/cell-renderers/reorder-cell-renderer.d.ts +34 -0
  364. package/dist/components/data-table/cell-renderers/reorder-cell-renderer.d.ts.map +1 -0
  365. package/dist/components/data-table/filters/select-filter.d.ts.map +1 -1
  366. package/dist/components/data-table/index.d.ts +3 -1
  367. package/dist/components/data-table/index.d.ts.map +1 -1
  368. package/dist/components/data-table/index.js +35 -32
  369. package/dist/components/dependent-selector/index.js +1 -1
  370. package/dist/components/document-scanner/index.js +1 -1
  371. package/dist/components/due-date-calculator/index.js +2 -2
  372. package/dist/components/email-input/email-input.d.ts.map +1 -1
  373. package/dist/components/email-input/index.js +1 -1
  374. package/dist/components/entity-summary/entity-summary.agent.d.ts +4 -0
  375. package/dist/components/entity-summary/entity-summary.agent.d.ts.map +1 -0
  376. package/dist/components/entity-summary/entity-summary.d.ts +92 -0
  377. package/dist/components/entity-summary/entity-summary.d.ts.map +1 -0
  378. package/dist/components/entity-summary/index.d.ts +3 -0
  379. package/dist/components/entity-summary/index.d.ts.map +1 -0
  380. package/dist/components/entity-summary/index.js +5 -0
  381. package/dist/components/entity-summary/index.js.map +1 -0
  382. package/dist/components/fetal-weight/index.js +1 -1
  383. package/dist/components/field-array/field-array.agent.d.ts +4 -0
  384. package/dist/components/field-array/field-array.agent.d.ts.map +1 -0
  385. package/dist/components/field-array/field-array.d.ts +45 -0
  386. package/dist/components/field-array/field-array.d.ts.map +1 -0
  387. package/dist/components/field-array/index.d.ts +4 -0
  388. package/dist/components/field-array/index.d.ts.map +1 -0
  389. package/dist/components/field-array/index.js +6 -0
  390. package/dist/components/field-array/index.js.map +1 -0
  391. package/dist/components/file-upload/index.js +1 -1
  392. package/dist/components/freemium-paywall/freemium-paywall.d.ts +1 -1
  393. package/dist/components/freemium-paywall/index.js +1 -1
  394. package/dist/components/gestational-age-calculator/index.js +1 -1
  395. package/dist/components/hcg-doubling/index.js +1 -1
  396. package/dist/components/iban-input/iban-input.agent.d.ts +4 -0
  397. package/dist/components/iban-input/iban-input.agent.d.ts.map +1 -0
  398. package/dist/components/iban-input/iban-input.d.ts +51 -0
  399. package/dist/components/iban-input/iban-input.d.ts.map +1 -0
  400. package/dist/components/iban-input/index.d.ts +5 -0
  401. package/dist/components/iban-input/index.d.ts.map +1 -0
  402. package/dist/components/iban-input/index.js +13 -0
  403. package/dist/components/iban-input/index.js.map +1 -0
  404. package/dist/components/iban-input/is-valid-iban.d.ts +31 -0
  405. package/dist/components/iban-input/is-valid-iban.d.ts.map +1 -0
  406. package/dist/components/icon-picker/icon-picker.agent.d.ts +4 -0
  407. package/dist/components/icon-picker/icon-picker.agent.d.ts.map +1 -0
  408. package/dist/components/icon-picker/icon-picker.d.ts +41 -0
  409. package/dist/components/icon-picker/icon-picker.d.ts.map +1 -0
  410. package/dist/components/icon-picker/index.d.ts +4 -0
  411. package/dist/components/icon-picker/index.d.ts.map +1 -0
  412. package/dist/components/icon-picker/index.js +6 -0
  413. package/dist/components/icon-picker/index.js.map +1 -0
  414. package/dist/components/image-cropper/crop-geometry.d.ts +30 -0
  415. package/dist/components/image-cropper/crop-geometry.d.ts.map +1 -0
  416. package/dist/components/image-cropper/image-cropper.agent.d.ts +4 -0
  417. package/dist/components/image-cropper/image-cropper.agent.d.ts.map +1 -0
  418. package/dist/components/image-cropper/image-cropper.d.ts +32 -0
  419. package/dist/components/image-cropper/image-cropper.d.ts.map +1 -0
  420. package/dist/components/image-cropper/index.d.ts +5 -0
  421. package/dist/components/image-cropper/index.d.ts.map +1 -0
  422. package/dist/components/image-cropper/index.js +11 -0
  423. package/dist/components/image-cropper/index.js.map +1 -0
  424. package/dist/components/index.d.ts +25 -1
  425. package/dist/components/index.d.ts.map +1 -1
  426. package/dist/components/message-card/index.js +1 -1
  427. package/dist/components/message-card/message-card.d.ts +14 -0
  428. package/dist/components/message-card/message-card.d.ts.map +1 -1
  429. package/dist/components/message-tray/index.js +1 -1
  430. package/dist/components/message-tray/message-tray.agent.d.ts.map +1 -1
  431. package/dist/components/message-tray/message-tray.d.ts +4 -0
  432. package/dist/components/message-tray/message-tray.d.ts.map +1 -1
  433. package/dist/components/multi-select/index.js +1 -1
  434. package/dist/components/multi-select/multi-select.d.ts.map +1 -1
  435. package/dist/components/nav-grid/index.d.ts +4 -0
  436. package/dist/components/nav-grid/index.d.ts.map +1 -0
  437. package/dist/components/nav-grid/index.js +7 -0
  438. package/dist/components/nav-grid/index.js.map +1 -0
  439. package/dist/components/nav-grid/nav-grid.agent.d.ts +4 -0
  440. package/dist/components/nav-grid/nav-grid.agent.d.ts.map +1 -0
  441. package/dist/components/nav-grid/nav-grid.d.ts +41 -0
  442. package/dist/components/nav-grid/nav-grid.d.ts.map +1 -0
  443. package/dist/components/notes-panel/index.d.ts +3 -0
  444. package/dist/components/notes-panel/index.d.ts.map +1 -0
  445. package/dist/components/notes-panel/index.js +5 -0
  446. package/dist/components/notes-panel/index.js.map +1 -0
  447. package/dist/components/notes-panel/notes-panel.agent.d.ts +4 -0
  448. package/dist/components/notes-panel/notes-panel.agent.d.ts.map +1 -0
  449. package/dist/components/notes-panel/notes-panel.d.ts +94 -0
  450. package/dist/components/notes-panel/notes-panel.d.ts.map +1 -0
  451. package/dist/components/notification-card/index.js +1 -1
  452. package/dist/components/notification-card/notification-card.d.ts +15 -0
  453. package/dist/components/notification-card/notification-card.d.ts.map +1 -1
  454. package/dist/components/notification-tray/index.js +1 -1
  455. package/dist/components/notification-tray/notification-tray.agent.d.ts.map +1 -1
  456. package/dist/components/notification-tray/notification-tray.d.ts +4 -0
  457. package/dist/components/notification-tray/notification-tray.d.ts.map +1 -1
  458. package/dist/components/operator-hero/index.js +1 -1
  459. package/dist/components/panel-header/index.d.ts +3 -0
  460. package/dist/components/panel-header/index.d.ts.map +1 -0
  461. package/dist/components/panel-header/index.js +7 -0
  462. package/dist/components/panel-header/index.js.map +1 -0
  463. package/dist/components/panel-header/panel-header.d.ts +41 -0
  464. package/dist/components/panel-header/panel-header.d.ts.map +1 -0
  465. package/dist/components/patient-details/index.d.ts +5 -0
  466. package/dist/components/patient-details/index.d.ts.map +1 -0
  467. package/dist/components/patient-details/index.js +6 -0
  468. package/dist/components/patient-details/index.js.map +1 -0
  469. package/dist/components/patient-details/patient-details.agent.d.ts +4 -0
  470. package/dist/components/patient-details/patient-details.agent.d.ts.map +1 -0
  471. package/dist/components/patient-details/patient-details.d.ts +96 -0
  472. package/dist/components/patient-details/patient-details.d.ts.map +1 -0
  473. package/dist/components/patient-search/index.js +1 -1
  474. package/dist/components/patient-summary-card/index.js +1 -1
  475. package/dist/components/patient-summary-card/patient-summary-card.agent.d.ts.map +1 -1
  476. package/dist/components/patient-summary-card/patient-summary-card.d.ts +40 -1
  477. package/dist/components/patient-summary-card/patient-summary-card.d.ts.map +1 -1
  478. package/dist/components/patient-table/columns.d.ts +69 -40
  479. package/dist/components/patient-table/columns.d.ts.map +1 -1
  480. package/dist/components/patient-table/index.d.ts +2 -6
  481. package/dist/components/patient-table/index.d.ts.map +1 -1
  482. package/dist/components/patient-table/index.js +8 -9
  483. package/dist/components/patient-table/patient-table.d.ts +38 -4
  484. package/dist/components/patient-table/patient-table.d.ts.map +1 -1
  485. package/dist/components/patient-table/types.d.ts +52 -2
  486. package/dist/components/patient-table/types.d.ts.map +1 -1
  487. package/dist/components/patient-table/use-responsive-columns.d.ts +8 -6
  488. package/dist/components/patient-table/use-responsive-columns.d.ts.map +1 -1
  489. package/dist/components/payment-card/index.js +1 -1
  490. package/dist/components/payment-form/index.js +1 -1
  491. package/dist/components/pdf-viewer/index.js +1 -1
  492. package/dist/components/periodontal-chart-card/index.js +1 -1
  493. package/dist/components/permission-matrix/index.d.ts +4 -0
  494. package/dist/components/permission-matrix/index.d.ts.map +1 -0
  495. package/dist/components/permission-matrix/index.js +7 -0
  496. package/dist/components/permission-matrix/index.js.map +1 -0
  497. package/dist/components/permission-matrix/permission-matrix.agent.d.ts +4 -0
  498. package/dist/components/permission-matrix/permission-matrix.agent.d.ts.map +1 -0
  499. package/dist/components/permission-matrix/permission-matrix.d.ts +47 -0
  500. package/dist/components/permission-matrix/permission-matrix.d.ts.map +1 -0
  501. package/dist/components/position-grid/index.d.ts +4 -0
  502. package/dist/components/position-grid/index.d.ts.map +1 -0
  503. package/dist/components/position-grid/index.js +7 -0
  504. package/dist/components/position-grid/index.js.map +1 -0
  505. package/dist/components/position-grid/position-grid.agent.d.ts +4 -0
  506. package/dist/components/position-grid/position-grid.agent.d.ts.map +1 -0
  507. package/dist/components/position-grid/position-grid.d.ts +39 -0
  508. package/dist/components/position-grid/position-grid.d.ts.map +1 -0
  509. package/dist/components/postal-code-input/index.d.ts +5 -0
  510. package/dist/components/postal-code-input/index.d.ts.map +1 -0
  511. package/dist/components/postal-code-input/index.js +6 -0
  512. package/dist/components/postal-code-input/index.js.map +1 -0
  513. package/dist/components/postal-code-input/postal-code-input.agent.d.ts +8 -0
  514. package/dist/components/postal-code-input/postal-code-input.agent.d.ts.map +1 -0
  515. package/dist/components/postal-code-input/postal-code-input.d.ts +27 -0
  516. package/dist/components/postal-code-input/postal-code-input.d.ts.map +1 -0
  517. package/dist/components/practice-results/index.js +1 -1
  518. package/dist/components/pregnancy-dating/index.js +1 -1
  519. package/dist/components/pregnancy-weight-gain/index.js +1 -1
  520. package/dist/components/product-hub-tray/index.js +1 -1
  521. package/dist/components/product-hub-tray/product-hub-tray.d.ts +13 -1
  522. package/dist/components/product-hub-tray/product-hub-tray.d.ts.map +1 -1
  523. package/dist/components/province-select/index.d.ts +6 -0
  524. package/dist/components/province-select/index.d.ts.map +1 -0
  525. package/dist/components/province-select/index.js +7 -0
  526. package/dist/components/province-select/index.js.map +1 -0
  527. package/dist/components/province-select/it-provinces.d.ts +8 -0
  528. package/dist/components/province-select/it-provinces.d.ts.map +1 -0
  529. package/dist/components/province-select/province-select.agent.d.ts +8 -0
  530. package/dist/components/province-select/province-select.agent.d.ts.map +1 -0
  531. package/dist/components/province-select/province-select.d.ts +38 -0
  532. package/dist/components/province-select/province-select.d.ts.map +1 -0
  533. package/dist/components/public-footer/public-footer.d.ts +1 -1
  534. package/dist/components/public-header/index.js +1 -1
  535. package/dist/components/radiograph-panel/index.d.ts +4 -0
  536. package/dist/components/radiograph-panel/index.d.ts.map +1 -0
  537. package/dist/components/radiograph-panel/index.js +7 -0
  538. package/dist/components/radiograph-panel/index.js.map +1 -0
  539. package/dist/components/radiograph-panel/radiograph-panel.agent.d.ts +13 -0
  540. package/dist/components/radiograph-panel/radiograph-panel.agent.d.ts.map +1 -0
  541. package/dist/components/radiograph-panel/radiograph-panel.d.ts +36 -0
  542. package/dist/components/radiograph-panel/radiograph-panel.d.ts.map +1 -0
  543. package/dist/components/reviews-panel/index.js +1 -1
  544. package/dist/components/reviews-panel/reviews-panel.d.ts.map +1 -1
  545. package/dist/components/rich-text-editor/editor-toolbar.d.ts +17 -0
  546. package/dist/components/rich-text-editor/editor-toolbar.d.ts.map +1 -1
  547. package/dist/components/rich-text-editor/index.js +1 -1
  548. package/dist/components/rich-text-editor/rich-text-editor.agent.d.ts.map +1 -1
  549. package/dist/components/rich-text-editor/rich-text-editor.d.ts.map +1 -1
  550. package/dist/components/scroll-area/index.js +1 -1
  551. package/dist/components/select/index.js +1 -1
  552. package/dist/components/select/select.d.ts +8 -2
  553. package/dist/components/select/select.d.ts.map +1 -1
  554. package/dist/components/sheet/index.js +1 -1
  555. package/dist/components/sheet/sheet.d.ts.map +1 -1
  556. package/dist/components/sidebar/index.js +2 -2
  557. package/dist/components/sidebar/sidebar.d.ts.map +1 -1
  558. package/dist/components/sign-document/index.js +1 -1
  559. package/dist/components/skeleton/skeleton.d.ts +1 -1
  560. package/dist/components/stepper-accordion/index.js +1 -1
  561. package/dist/components/tab-bar/index.js +1 -1
  562. package/dist/components/tab-bar/tab-bar.d.ts +18 -1
  563. package/dist/components/tab-bar/tab-bar.d.ts.map +1 -1
  564. package/dist/components/tabs/index.js +1 -1
  565. package/dist/components/task-card/index.js +1 -1
  566. package/dist/components/task-card/task-card.d.ts +14 -6
  567. package/dist/components/task-card/task-card.d.ts.map +1 -1
  568. package/dist/components/task-tray/index.js +1 -1
  569. package/dist/components/tasks-panel/index.d.ts +4 -0
  570. package/dist/components/tasks-panel/index.d.ts.map +1 -0
  571. package/dist/components/tasks-panel/index.js +6 -0
  572. package/dist/components/tasks-panel/index.js.map +1 -0
  573. package/dist/components/tasks-panel/tasks-panel.agent.d.ts +4 -0
  574. package/dist/components/tasks-panel/tasks-panel.agent.d.ts.map +1 -0
  575. package/dist/components/tasks-panel/tasks-panel.d.ts +152 -0
  576. package/dist/components/tasks-panel/tasks-panel.d.ts.map +1 -0
  577. package/dist/components/token-insert-menu/index.d.ts +4 -0
  578. package/dist/components/token-insert-menu/index.d.ts.map +1 -0
  579. package/dist/components/token-insert-menu/index.js +6 -0
  580. package/dist/components/token-insert-menu/index.js.map +1 -0
  581. package/dist/components/token-insert-menu/token-insert-menu.agent.d.ts +4 -0
  582. package/dist/components/token-insert-menu/token-insert-menu.agent.d.ts.map +1 -0
  583. package/dist/components/token-insert-menu/token-insert-menu.d.ts +33 -0
  584. package/dist/components/token-insert-menu/token-insert-menu.d.ts.map +1 -0
  585. package/dist/components/tool-rail/index.d.ts +4 -0
  586. package/dist/components/tool-rail/index.d.ts.map +1 -0
  587. package/dist/components/tool-rail/index.js +6 -0
  588. package/dist/components/tool-rail/index.js.map +1 -0
  589. package/dist/components/tool-rail/tool-rail.agent.d.ts +4 -0
  590. package/dist/components/tool-rail/tool-rail.agent.d.ts.map +1 -0
  591. package/dist/components/tool-rail/tool-rail.d.ts +160 -0
  592. package/dist/components/tool-rail/tool-rail.d.ts.map +1 -0
  593. package/dist/components/tooth-scheme/index.d.ts +2 -2
  594. package/dist/components/tooth-scheme/index.d.ts.map +1 -1
  595. package/dist/components/tooth-scheme/index.js +30 -23
  596. package/dist/components/tooth-scheme/tooth-data.d.ts +112 -1
  597. package/dist/components/tooth-scheme/tooth-data.d.ts.map +1 -1
  598. package/dist/components/tooth-scheme/tooth-scheme.agent.d.ts +2 -2
  599. package/dist/components/tooth-scheme/tooth-scheme.agent.d.ts.map +1 -1
  600. package/dist/components/tooth-scheme/tooth-scheme.d.ts +84 -11
  601. package/dist/components/tooth-scheme/tooth-scheme.d.ts.map +1 -1
  602. package/dist/components/transaction-chip/index.js +1 -1
  603. package/dist/components/transaction-chip/transaction-chip.d.ts +2 -2
  604. package/dist/components/transaction-chip/transaction-chip.d.ts.map +1 -1
  605. package/dist/components/transcript-panel/index.js +1 -1
  606. package/dist/components/transcript-panel/transcript-panel.d.ts +2 -2
  607. package/dist/components/transcript-panel/transcript-panel.d.ts.map +1 -1
  608. package/dist/components/unit-converter/index.js +1 -1
  609. package/dist/components/warning-stack/index.js +1 -1
  610. package/dist/components/warning-stack/warning-stack.d.ts +10 -7
  611. package/dist/components/warning-stack/warning-stack.d.ts.map +1 -1
  612. package/dist/components/workflow/index.js +1 -1
  613. package/dist/hooks/index.d.ts +1 -0
  614. package/dist/hooks/index.d.ts.map +1 -1
  615. package/dist/hooks/index.js +24 -22
  616. package/dist/hooks/index.js.map +1 -1
  617. package/dist/hooks/use-clamp-overflow.d.ts +19 -0
  618. package/dist/hooks/use-clamp-overflow.d.ts.map +1 -0
  619. package/dist/hooks/use-edge-resize.d.ts +2 -2
  620. package/dist/hooks/use-overflow-collapse.d.ts +46 -0
  621. package/dist/hooks/use-overflow-collapse.d.ts.map +1 -0
  622. package/dist/hooks/use-persistent-state.d.ts +7 -1
  623. package/dist/hooks/use-persistent-state.d.ts.map +1 -1
  624. package/dist/hooks/use-scroll-overflow.d.ts +36 -0
  625. package/dist/hooks/use-scroll-overflow.d.ts.map +1 -0
  626. package/dist/i18n/locales/ar.d.ts +475 -26
  627. package/dist/i18n/locales/ar.d.ts.map +1 -1
  628. package/dist/i18n/locales/ar.js +478 -31
  629. package/dist/i18n/locales/ar.js.map +1 -1
  630. package/dist/i18n/locales/de.d.ts +475 -26
  631. package/dist/i18n/locales/de.d.ts.map +1 -1
  632. package/dist/i18n/locales/de.js +480 -31
  633. package/dist/i18n/locales/de.js.map +1 -1
  634. package/dist/i18n/locales/el.d.ts +475 -26
  635. package/dist/i18n/locales/el.d.ts.map +1 -1
  636. package/dist/i18n/locales/el.js +485 -31
  637. package/dist/i18n/locales/el.js.map +1 -1
  638. package/dist/i18n/locales/en.d.ts +476 -34
  639. package/dist/i18n/locales/en.d.ts.map +1 -1
  640. package/dist/i18n/locales/en.js +492 -39
  641. package/dist/i18n/locales/en.js.map +1 -1
  642. package/dist/i18n/locales/es.d.ts +475 -26
  643. package/dist/i18n/locales/es.d.ts.map +1 -1
  644. package/dist/i18n/locales/es.js +477 -31
  645. package/dist/i18n/locales/es.js.map +1 -1
  646. package/dist/i18n/locales/fr.d.ts +475 -26
  647. package/dist/i18n/locales/fr.d.ts.map +1 -1
  648. package/dist/i18n/locales/fr.js +480 -31
  649. package/dist/i18n/locales/fr.js.map +1 -1
  650. package/dist/i18n/locales/hi.d.ts +475 -26
  651. package/dist/i18n/locales/hi.d.ts.map +1 -1
  652. package/dist/i18n/locales/hi.js +476 -31
  653. package/dist/i18n/locales/hi.js.map +1 -1
  654. package/dist/i18n/locales/it.d.ts +475 -26
  655. package/dist/i18n/locales/it.d.ts.map +1 -1
  656. package/dist/i18n/locales/it.js +480 -31
  657. package/dist/i18n/locales/it.js.map +1 -1
  658. package/dist/i18n/locales/ja.d.ts +475 -26
  659. package/dist/i18n/locales/ja.d.ts.map +1 -1
  660. package/dist/i18n/locales/ja.js +481 -31
  661. package/dist/i18n/locales/ja.js.map +1 -1
  662. package/dist/i18n/locales/nl.d.ts +475 -26
  663. package/dist/i18n/locales/nl.d.ts.map +1 -1
  664. package/dist/i18n/locales/nl.js +473 -31
  665. package/dist/i18n/locales/nl.js.map +1 -1
  666. package/dist/i18n/locales/pl.d.ts +475 -26
  667. package/dist/i18n/locales/pl.d.ts.map +1 -1
  668. package/dist/i18n/locales/pl.js +481 -31
  669. package/dist/i18n/locales/pl.js.map +1 -1
  670. package/dist/i18n/locales/pt.d.ts +475 -26
  671. package/dist/i18n/locales/pt.d.ts.map +1 -1
  672. package/dist/i18n/locales/pt.js +485 -31
  673. package/dist/i18n/locales/pt.js.map +1 -1
  674. package/dist/i18n/locales/ro.d.ts +475 -26
  675. package/dist/i18n/locales/ro.d.ts.map +1 -1
  676. package/dist/i18n/locales/ro.js +485 -31
  677. package/dist/i18n/locales/ro.js.map +1 -1
  678. package/dist/i18n/locales/ru.d.ts +475 -26
  679. package/dist/i18n/locales/ru.d.ts.map +1 -1
  680. package/dist/i18n/locales/ru.js +478 -31
  681. package/dist/i18n/locales/ru.js.map +1 -1
  682. package/dist/i18n/locales/sq.d.ts +475 -26
  683. package/dist/i18n/locales/sq.d.ts.map +1 -1
  684. package/dist/i18n/locales/sq.js +482 -31
  685. package/dist/i18n/locales/sq.js.map +1 -1
  686. package/dist/i18n/locales/sv.d.ts +475 -26
  687. package/dist/i18n/locales/sv.d.ts.map +1 -1
  688. package/dist/i18n/locales/sv.js +480 -31
  689. package/dist/i18n/locales/sv.js.map +1 -1
  690. package/dist/i18n/locales/tr.d.ts +475 -26
  691. package/dist/i18n/locales/tr.d.ts.map +1 -1
  692. package/dist/i18n/locales/tr.js +478 -31
  693. package/dist/i18n/locales/tr.js.map +1 -1
  694. package/dist/i18n/locales/zh.d.ts +475 -26
  695. package/dist/i18n/locales/zh.d.ts.map +1 -1
  696. package/dist/i18n/locales/zh.js +473 -31
  697. package/dist/i18n/locales/zh.js.map +1 -1
  698. package/dist/index.js +826 -709
  699. package/dist/index.js.map +1 -1
  700. package/dist/locales/ar.json +480 -31
  701. package/dist/locales/de.json +480 -31
  702. package/dist/locales/el.json +480 -31
  703. package/dist/locales/en.json +480 -31
  704. package/dist/locales/es.json +480 -31
  705. package/dist/locales/fr.json +480 -31
  706. package/dist/locales/hi.json +480 -31
  707. package/dist/locales/it.json +480 -31
  708. package/dist/locales/ja.json +480 -31
  709. package/dist/locales/nl.json +480 -31
  710. package/dist/locales/pl.json +480 -31
  711. package/dist/locales/pt.json +480 -31
  712. package/dist/locales/ro.json +480 -31
  713. package/dist/locales/ru.json +480 -31
  714. package/dist/locales/sq.json +480 -31
  715. package/dist/locales/sv.json +480 -31
  716. package/dist/locales/tr.json +480 -31
  717. package/dist/locales/zh.json +480 -31
  718. package/dist/patterns/alia-assistant/alia-chat-surface.d.ts.map +1 -1
  719. package/dist/patterns/alia-assistant/alia-types.d.ts +9 -0
  720. package/dist/patterns/alia-assistant/alia-types.d.ts.map +1 -1
  721. package/dist/patterns/alia-assistant/index.js +1 -1
  722. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  723. package/dist/patterns/patient-shell/index.js +1 -1
  724. package/dist/tokens.css +9 -1
  725. package/package.json +101 -5
  726. package/dist/_chunks/actions-cell-renderer-DrcaxB0w.js.map +0 -1
  727. package/dist/_chunks/ai-tools-rail-BA_sqy1A.js +0 -373
  728. package/dist/_chunks/ai-tools-rail-BA_sqy1A.js.map +0 -1
  729. package/dist/_chunks/alert-_mUKLmwA.js.map +0 -1
  730. package/dist/_chunks/alia-sidebar-B47qRQb5.js.map +0 -1
  731. package/dist/_chunks/app-frame-BYx1gcV7.js.map +0 -1
  732. package/dist/_chunks/appointment-tray-CZtvtaH-.js +0 -431
  733. package/dist/_chunks/appointment-tray-CZtvtaH-.js.map +0 -1
  734. package/dist/_chunks/autocomplete-DOeGouCL.js.map +0 -1
  735. package/dist/_chunks/badge-CqGsX32l.js.map +0 -1
  736. package/dist/_chunks/chat-message-3V54YipB.js.map +0 -1
  737. package/dist/_chunks/clinical-note-card-DqQYf_D4.js +0 -333
  738. package/dist/_chunks/clinical-note-card-DqQYf_D4.js.map +0 -1
  739. package/dist/_chunks/combobox-Clum7gJ1.js.map +0 -1
  740. package/dist/_chunks/editable-currency-cell-renderer-kgqp_mIw.js +0 -448
  741. package/dist/_chunks/editable-currency-cell-renderer-kgqp_mIw.js.map +0 -1
  742. package/dist/_chunks/email-input-B_Y55f5G.js +0 -396
  743. package/dist/_chunks/message-card-Bx4GmLvf.js +0 -277
  744. package/dist/_chunks/message-card-Bx4GmLvf.js.map +0 -1
  745. package/dist/_chunks/message-tray-DwrBLJlf.js.map +0 -1
  746. package/dist/_chunks/notification-card-BiESdm8q.js +0 -255
  747. package/dist/_chunks/notification-card-BiESdm8q.js.map +0 -1
  748. package/dist/_chunks/notification-tray-Btb9oQeZ.js.map +0 -1
  749. package/dist/_chunks/patient-summary-card-B836_fDB.js +0 -435
  750. package/dist/_chunks/patient-summary-card-B836_fDB.js.map +0 -1
  751. package/dist/_chunks/patient-table-CDuosVru.js +0 -889
  752. package/dist/_chunks/patient-table-CDuosVru.js.map +0 -1
  753. package/dist/_chunks/payment-request-card-DioWKBUq.js.map +0 -1
  754. package/dist/_chunks/pdf-viewer-D6BPfW2D.js.map +0 -1
  755. package/dist/_chunks/product-hub-panel-e6pW220e.js.map +0 -1
  756. package/dist/_chunks/reviews-panel-Dq7LMDcH.js +0 -555
  757. package/dist/_chunks/reviews-panel-Dq7LMDcH.js.map +0 -1
  758. package/dist/_chunks/rich-text-editor-BsV7zUdg.js +0 -2142
  759. package/dist/_chunks/rich-text-editor-BsV7zUdg.js.map +0 -1
  760. package/dist/_chunks/scroll-area-5wNK0Cyz.js.map +0 -1
  761. package/dist/_chunks/select-DMLG44F5.js.map +0 -1
  762. package/dist/_chunks/sheet-BxsE7eQm.js.map +0 -1
  763. package/dist/_chunks/sidebar-DY9jGjgt.js.map +0 -1
  764. package/dist/_chunks/stepper-accordion-Dki6r9ZE.js.map +0 -1
  765. package/dist/_chunks/tab-bar-B1ovILzh.js +0 -105
  766. package/dist/_chunks/tab-bar-B1ovILzh.js.map +0 -1
  767. package/dist/_chunks/task-card-BwY9jaV1.js +0 -124
  768. package/dist/_chunks/task-card-BwY9jaV1.js.map +0 -1
  769. package/dist/_chunks/tooth-scheme-yBr53cvv.js +0 -1330
  770. package/dist/_chunks/tooth-scheme-yBr53cvv.js.map +0 -1
  771. package/dist/_chunks/transaction-chip-DK84XCBU.js.map +0 -1
  772. package/dist/_chunks/transcript-panel-3THQX6nJ.js.map +0 -1
  773. package/dist/_chunks/use-persistent-state-i23OWy6G.js +0 -24
  774. package/dist/_chunks/use-persistent-state-i23OWy6G.js.map +0 -1
  775. package/dist/_chunks/warning-stack-BsgaEbL8.js.map +0 -1
  776. package/dist/_chunks/workflow-map-Bdam9pGp.js.map +0 -1
  777. package/dist/components/ai-tools-rail/ai-tools-rail.agent.d.ts +0 -4
  778. package/dist/components/ai-tools-rail/ai-tools-rail.agent.d.ts.map +0 -1
  779. package/dist/components/ai-tools-rail/ai-tools-rail.d.ts +0 -68
  780. package/dist/components/ai-tools-rail/ai-tools-rail.d.ts.map +0 -1
  781. package/dist/components/ai-tools-rail/index.d.ts +0 -4
  782. package/dist/components/ai-tools-rail/index.d.ts.map +0 -1
  783. package/dist/components/ai-tools-rail/index.js +0 -6
  784. package/dist/components/patient-table/cell-renderers/contact-cell.d.ts +0 -45
  785. package/dist/components/patient-table/cell-renderers/contact-cell.d.ts.map +0 -1
  786. package/dist/components/patient-table/cell-renderers/patient-identity-cell.d.ts +0 -26
  787. package/dist/components/patient-table/cell-renderers/patient-identity-cell.d.ts.map +0 -1
  788. /package/dist/components/{ai-tools-rail → address-fields}/index.js.map +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"tooth-scheme-yBr53cvv.js","sources":["../../src/components/tooth-scheme/tooth-scheme.agent.ts","../../src/components/tooth-scheme/tooth-data.ts","../../src/components/tooth-scheme/tooth-scheme.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { ToothSchemeHandle } from './tooth-scheme';\nimport type { Surface, ToothCondition } from './tooth-data';\n\ntype FdiId = Parameters<ToothSchemeHandle['focusTooth']>[0];\n\n// JSON-Schema fragments derived from the tooth-data type unions. Kept inline so\n// the adapter stays a pure module with no runtime import of the unions.\nconst FDI_SCHEMA = {\n type: 'string',\n description: \"FDI tooth id, e.g. '11'–'48' permanent, '51'–'85' primary.\",\n} as const;\nconst CONDITION_SCHEMA = {\n enum: [\n 'caries',\n 'filled',\n 'crowned',\n 'temporaryCrown',\n 'bridge',\n 'missing',\n 'implant',\n 'implantExtraction',\n 'stub',\n 'destroyed',\n 'rootCanal',\n ],\n} as const;\nconst SURFACE_SCHEMA = {\n enum: ['mesial', 'distal', 'occlusal', 'buccal', 'lingual'],\n} as const;\n\nexport const toothSchemeAgent: AgentAdapter<ToothSchemeHandle> = {\n id: 'tooth-scheme',\n // pick — focus/select a tooth (`focus_tooth`, transient, not persisted);\n // set_value / edit_inline — `set_finding` records a finding and marks the\n // affected surfaces (set-surface), `remove_finding` clears one;\n // view_change — the side/plan projection + dentition are view props.\n capabilities: ['pick', 'set_value', 'edit_inline', 'view_change'],\n state: {\n chart: {\n type: 'object',\n descriptionKey: 'ui.agent.toothScheme.state.chart',\n description:\n 'Current dental chart — findings (and marked surfaces) keyed by FDI id.',\n read: (handle) => handle.getChart(),\n },\n chartedTeeth: {\n type: 'string[]',\n descriptionKey: 'ui.agent.toothScheme.state.chartedTeeth',\n description: 'FDI ids of every tooth carrying at least one finding.',\n read: (handle) => Object.keys(handle.getChart()),\n },\n },\n actions: {\n focus_tooth: {\n safety: 'read',\n argsType: '{ id: FdiId }',\n argsSchema: {\n type: 'object',\n properties: { id: FDI_SCHEMA },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.toothScheme.actions.focusTooth',\n description: 'Move focus to a specific tooth by FDI id.',\n invoke: (handle, args: { id: FdiId }) => {\n handle.focusTooth(args.id);\n },\n },\n get_tooth: {\n safety: 'read',\n argsType: '{ id: FdiId }',\n argsSchema: {\n type: 'object',\n properties: { id: FDI_SCHEMA },\n required: ['id'],\n },\n returns: 'ToothCondition[]',\n returnsSchema: { type: 'array', items: CONDITION_SCHEMA },\n idempotent: true,\n descriptionKey: 'ui.agent.toothScheme.actions.getTooth',\n description: 'Read the findings recorded on one tooth (FDI id).',\n invoke: (handle, args: { id: FdiId }) => handle.getTooth(args.id),\n },\n teeth_with: {\n safety: 'read',\n argsType: '{ condition: ToothCondition }',\n argsSchema: {\n type: 'object',\n properties: { condition: CONDITION_SCHEMA },\n required: ['condition'],\n },\n returns: 'FdiId[]',\n returnsSchema: { type: 'array', items: FDI_SCHEMA },\n idempotent: true,\n descriptionKey: 'ui.agent.toothScheme.actions.teethWith',\n description:\n 'List the FDI ids of every tooth carrying a given finding (e.g. all teeth with caries).',\n invoke: (handle, args: { condition: ToothCondition }) =>\n handle.teethWith(args.condition),\n },\n set_finding: {\n safety: 'write',\n argsType:\n '{ id: FdiId; condition: ToothCondition; surfaces?: Surface[] }',\n argsSchema: {\n type: 'object',\n properties: {\n id: FDI_SCHEMA,\n condition: CONDITION_SCHEMA,\n surfaces: { type: 'array', items: SURFACE_SCHEMA },\n },\n required: ['id', 'condition'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.toothScheme.actions.setFinding',\n description:\n 'Record a finding on a tooth (crown, implant, root canal, caries, …). Optionally mark the affected surfaces for a surface finding.',\n invoke: (\n handle,\n args: { id: FdiId; condition: ToothCondition; surfaces?: Surface[] },\n ) => {\n handle.setFinding(args.id, args.condition, args.surfaces);\n },\n },\n remove_finding: {\n safety: 'write',\n argsType: '{ id: FdiId; condition: ToothCondition }',\n argsSchema: {\n type: 'object',\n properties: { id: FDI_SCHEMA, condition: CONDITION_SCHEMA },\n required: ['id', 'condition'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.toothScheme.actions.removeFinding',\n description: 'Remove a single finding from a tooth.',\n invoke: (handle, args: { id: FdiId; condition: ToothCondition }) => {\n handle.removeFinding(args.id, args.condition);\n },\n },\n clear_tooth: {\n safety: 'destructive',\n argsType: '{ id: FdiId }',\n argsSchema: {\n type: 'object',\n properties: { id: FDI_SCHEMA },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.toothScheme.actions.clearTooth',\n description: 'Clear every finding from a tooth.',\n invoke: (handle, args: { id: FdiId }) => {\n handle.clearTooth(args.id);\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'tooth-scheme' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-fdi',\n description:\n 'Each rendered tooth `<g>` carries its FDI id as `data-fdi`. The `data-projection` attribute on the root exposes the side/plan view.',\n },\n },\n};\n\n// Re-exported for callers building typed args against the adapter.\nexport type { Surface, ToothCondition };\n","/* ------------------------------------------------------------------ */\n/* ToothScheme — data model + lookup tables. */\n/* */\n/* FDI ISO 3950 is the canonical internal id. This module exposes */\n/* conversion tables to Universal (ADA) and a simplified Palmer-style */\n/* quadrant+position string so consuming UIs can toggle numbering. */\n/* */\n/* Why simplified Palmer? True Palmer notation uses quadrant bracket */\n/* glyphs (\"⌐\", \"¬\", \"L\", \"J\") that do not render reliably in every */\n/* browser/font combination. We emit a readable `UR3` / `LL6` form */\n/* instead and document the deviation in the component MDX. */\n/* ------------------------------------------------------------------ */\n\n/* ------------------------------------------------------------------ */\n/* Core types */\n/* ------------------------------------------------------------------ */\n\nexport type FdiId = string; // '11'–'48' permanent, '51'–'85' primary\n\nexport type Dentition = 'permanent' | 'primary' | 'mixed';\nexport type Numbering = 'fdi' | 'universal' | 'palmer';\nexport type ToothMode = 'interactive' | 'display';\nexport type Surface = 'mesial' | 'distal' | 'occlusal' | 'buccal' | 'lingual';\nexport type ToothCondition =\n | 'caries'\n | 'filled'\n | 'crowned'\n | 'temporaryCrown'\n | 'bridge'\n | 'missing'\n | 'implant'\n | 'implantExtraction'\n | 'stub'\n | 'destroyed'\n | 'rootCanal';\n\nexport interface ToothState {\n conditions: ToothCondition[];\n surfaces: Surface[];\n notes?: string;\n}\n\nexport type ToothChart = Record<FdiId, ToothState>;\n\nexport type Anatomy = 'incisor' | 'canine' | 'premolar' | 'molar';\nexport type Arch = 'upper' | 'lower';\nexport type Side = 'right' | 'left'; // patient's side (NOT viewer's)\nexport type Quadrant = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;\n\nexport interface ToothMeta {\n fdi: FdiId;\n /** '1'–'32' for permanent, 'A'–'T' for primary. */\n universal: string;\n /** Simplified Palmer quadrant-and-position string, e.g. 'UR3', 'LL6'. */\n palmer: string;\n quadrant: Quadrant;\n /** 1–8 (permanent) or 1–5 (primary), counted from the midline outward. */\n positionInQuadrant: number;\n anatomy: Anatomy;\n arch: Arch;\n side: Side;\n dentition: 'permanent' | 'primary';\n}\n\n/* ------------------------------------------------------------------ */\n/* Layout orders */\n/* */\n/* Layout reads from the viewer's perspective, top-left to bottom- */\n/* right. The chart is FIXED in clinical convention: the patient's */\n/* right side sits on the viewer's left, regardless of document `dir`. */\n/* ------------------------------------------------------------------ */\n\n/**\n * 32 permanent teeth in visual layout order:\n * upper row: 18..11 (patient upper-right, outermost → midline), then 21..28 (upper-left, midline → outermost)\n * lower row: 48..41 (patient lower-right, outermost → midline), then 31..38 (lower-left, midline → outermost)\n */\nexport const PERMANENT_TEETH: FdiId[] = [\n // upper\n '18',\n '17',\n '16',\n '15',\n '14',\n '13',\n '12',\n '11',\n '21',\n '22',\n '23',\n '24',\n '25',\n '26',\n '27',\n '28',\n // lower\n '48',\n '47',\n '46',\n '45',\n '44',\n '43',\n '42',\n '41',\n '31',\n '32',\n '33',\n '34',\n '35',\n '36',\n '37',\n '38',\n];\n\n/**\n * 20 primary teeth in visual layout order:\n * upper row: 55..51 (upper-right outermost → midline), then 61..65\n * lower row: 85..81, then 71..75\n */\nexport const PRIMARY_TEETH: FdiId[] = [\n // upper\n '55',\n '54',\n '53',\n '52',\n '51',\n '61',\n '62',\n '63',\n '64',\n '65',\n // lower\n '85',\n '84',\n '83',\n '82',\n '81',\n '71',\n '72',\n '73',\n '74',\n '75',\n];\n\n/* ------------------------------------------------------------------ */\n/* Anatomy by position */\n/* ------------------------------------------------------------------ */\n\nfunction permanentAnatomy(positionInQuadrant: number): Anatomy {\n if (positionInQuadrant <= 2) return 'incisor';\n if (positionInQuadrant === 3) return 'canine';\n if (positionInQuadrant <= 5) return 'premolar';\n return 'molar';\n}\n\nfunction primaryAnatomy(positionInQuadrant: number): Anatomy {\n if (positionInQuadrant <= 2) return 'incisor';\n if (positionInQuadrant === 3) return 'canine';\n // Primary dentition has no premolars — positions 4 & 5 are molars.\n return 'molar';\n}\n\n/* ------------------------------------------------------------------ */\n/* Palmer helper */\n/* ------------------------------------------------------------------ */\n\nfunction palmerCode(quadrant: Quadrant, position: number): string {\n // Permanent: 1=UR, 2=UL, 3=LL, 4=LR. Primary: 5=UR, 6=UL, 7=LL, 8=LR.\n // Mapping is identical within each dentition ring; the number is what\n // changes, so we fold 5→1, 6→2, 7→3, 8→4 to derive the quadrant code.\n const normalised = ((quadrant - 1) % 4) + 1;\n const code =\n normalised === 1\n ? 'UR'\n : normalised === 2\n ? 'UL'\n : normalised === 3\n ? 'LL'\n : 'LR';\n return `${code}${position}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Universal (ADA) conversion */\n/* */\n/* Permanent — Universal numbers 1..32 run clockwise from the */\n/* patient's upper-right 3rd molar (FDI 18 = Universal 1), across */\n/* the upper arch (18→11 = 1→8, 21→28 = 9→16), then down the left */\n/* lower arch (38→31 = 17→24) and across the right lower (41→48 = */\n/* 25→32). */\n/* */\n/* Primary — Universal letters A..T walk the same path: */\n/* 55→51 = A→E, 61→65 = F→J, 75→71 = K→O, 81→85 = P→T. */\n/* ------------------------------------------------------------------ */\n\nfunction permanentUniversal(quadrant: Quadrant, position: number): string {\n switch (quadrant) {\n case 1:\n // 18→1, 17→2, …, 11→8\n return String(1 + (8 - position));\n case 2:\n // 21→9, 22→10, …, 28→16\n return String(8 + position);\n case 3:\n // 38→17, 37→18, …, 31→24\n return String(17 + (8 - position));\n case 4:\n // 41→25, 42→26, …, 48→32\n return String(24 + position);\n default:\n return '';\n }\n}\n\nfunction primaryUniversal(quadrant: Quadrant, position: number): string {\n const letters = 'ABCDEFGHIJKLMNOPQRST';\n let index = -1;\n switch (quadrant) {\n case 5:\n // 55→A, 54→B, 53→C, 52→D, 51→E\n index = 0 + (5 - position);\n break;\n case 6:\n // 61→F, 62→G, 63→H, 64→I, 65→J\n index = 5 + (position - 1);\n break;\n case 7:\n // 75→K, 74→L, 73→M, 72→N, 71→O\n index = 10 + (5 - position);\n break;\n case 8:\n // 81→P, 82→Q, 83→R, 84→S, 85→T\n index = 15 + (position - 1);\n break;\n default:\n index = -1;\n }\n return index >= 0 ? letters[index] : '';\n}\n\n/* ------------------------------------------------------------------ */\n/* Meta builder */\n/* ------------------------------------------------------------------ */\n\nfunction buildMeta(fdi: FdiId): ToothMeta {\n const quadrant = Number(fdi[0]) as Quadrant;\n const position = Number(fdi[1]);\n const isPrimary = quadrant >= 5;\n const anatomy = isPrimary\n ? primaryAnatomy(position)\n : permanentAnatomy(position);\n const arch: Arch =\n quadrant === 1 || quadrant === 2 || quadrant === 5 || quadrant === 6\n ? 'upper'\n : 'lower';\n const side: Side =\n quadrant === 1 || quadrant === 4 || quadrant === 5 || quadrant === 8\n ? 'right'\n : 'left';\n const universal = isPrimary\n ? primaryUniversal(quadrant, position)\n : permanentUniversal(quadrant, position);\n const palmer = palmerCode(quadrant, position);\n return {\n fdi,\n universal,\n palmer,\n quadrant,\n positionInQuadrant: position,\n anatomy,\n arch,\n side,\n dentition: isPrimary ? 'primary' : 'permanent',\n };\n}\n\nexport const FDI_TO_META: Record<FdiId, ToothMeta> = [\n ...PERMANENT_TEETH,\n ...PRIMARY_TEETH,\n].reduce<Record<FdiId, ToothMeta>>((acc, fdi) => {\n acc[fdi] = buildMeta(fdi);\n return acc;\n}, {});\n\nexport const FDI_TO_UNIVERSAL: Record<FdiId, string> = Object.fromEntries(\n Object.entries(FDI_TO_META).map(([fdi, meta]) => [fdi, meta.universal]),\n);\n\nexport const FDI_TO_PALMER: Record<FdiId, string> = Object.fromEntries(\n Object.entries(FDI_TO_META).map(([fdi, meta]) => [fdi, meta.palmer]),\n);\n\n/**\n * FDI used to resolve a tooth's RENDER. There are no separate deciduous\n * renders — primary teeth reuse the permanent image of the same position\n * (quadrant 5→1, 6→2, 7→3, 8→4; position digit unchanged), scaled down by\n * the renderer. Permanent teeth resolve to themselves.\n */\nexport function assetFdi(meta: ToothMeta): FdiId {\n if (meta.dentition !== 'primary') return meta.fdi;\n return `${meta.quadrant - 4}${meta.positionInQuadrant}`;\n}\n\n/** Render scale applied to a tooth image (primary teeth are smaller). */\nexport const PRIMARY_TOOTH_SCALE = 0.72;\n\n/* ------------------------------------------------------------------ */\n/* Condition → token + pattern */\n/* */\n/* Every condition carries BOTH a colour AND a fill pattern so */\n/* colour-blind clinicians can distinguish states in the SVG (and in */\n/* black-and-white prints) — colour is never the sole channel. */\n/* ------------------------------------------------------------------ */\n\n/** CSS variable name (without the leading `var(...)`) that drives a condition's colour. */\nexport const CONDITION_TOKENS: Record<ToothCondition, string> = {\n caries: '--destructive',\n filled: '--info',\n crowned: '--warning',\n temporaryCrown: '--warning',\n bridge: '--primary',\n missing: '--muted-foreground',\n implant: '--accent',\n implantExtraction: '--accent',\n stub: '--muted-foreground',\n destroyed: '--destructive',\n rootCanal: '--primary',\n};\n\n/**\n * Convenience: the `fill=\"var(--destructive)\"` string ready to paste onto\n * an SVG attribute. Kept in sync with `CONDITION_TOKENS`. Used for the legend\n * swatch + the surface-condition ring; whole-tooth conditions render a\n * distinct symbol image (the glyph is the colour-independent channel).\n */\nexport const CONDITION_COLORS: Record<ToothCondition, string> = {\n caries: 'var(--destructive)',\n filled: 'var(--info)',\n crowned: 'var(--warning)',\n temporaryCrown: 'var(--warning)',\n bridge: 'var(--primary)',\n missing: 'var(--muted-foreground)',\n implant: 'var(--accent)',\n implantExtraction: 'var(--accent)',\n stub: 'var(--muted-foreground)',\n destroyed: 'var(--destructive)',\n rootCanal: 'var(--primary)',\n};\n\n/* ------------------------------------------------------------------ */\n/* Condition → side-view symbol overlay */\n/* */\n/* Whole-tooth findings overlay a photoreal symbol render on the */\n/* facial tooth. `caries` / `filled` are per-surface findings shown */\n/* in the plan (occlusal) view and carry no side symbol here. The */\n/* folder layout is `{symbol}/{top|bottom}/...` under `side/`. */\n/* ------------------------------------------------------------------ */\n\nexport interface SideSymbolSpec {\n /** Asset folder under `side/`. */\n folder: string;\n /** How the file resolves inside `{folder}/{view}/`. */\n resolve: 'per-fdi' | 'general' | 'rct';\n}\n\nexport const CONDITION_SIDE_SYMBOL: Partial<\n Record<ToothCondition, SideSymbolSpec>\n> = {\n crowned: { folder: 'crown', resolve: 'per-fdi' },\n temporaryCrown: { folder: 'temporaryCrown', resolve: 'per-fdi' },\n bridge: { folder: 'replacement', resolve: 'per-fdi' },\n destroyed: { folder: 'destroyed', resolve: 'per-fdi' },\n implant: { folder: 'implant', resolve: 'general' },\n implantExtraction: { folder: 'implantExtraction', resolve: 'general' },\n stub: { folder: 'stub', resolve: 'general' },\n rootCanal: { folder: 'rootTreatment', resolve: 'rct' },\n};\n\n/** Resolve the side-view symbol overlay URL for a condition on a tooth. */\nexport function conditionSymbolUrl(\n meta: ToothMeta,\n assetBaseUrl: string,\n spec: SideSymbolSpec,\n): string {\n const view = meta.arch === 'upper' ? 'top' : 'bottom';\n const base = `${assetBaseUrl}/side/${spec.folder}/${view}`;\n if (spec.resolve === 'general') return `${base}/general.webp`;\n const fdi = assetFdi(meta);\n if (spec.resolve === 'rct') return `${base}/${fdi}/full.webp`;\n return `${base}/${fdi}.webp`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Plan (occlusal) view — per-surface findings */\n/* */\n/* The \"Stato dentale\" / Findings surface marks caries & fillings on */\n/* individual tooth surfaces in the occlusal (plan) view. The asset */\n/* surface names differ from the clinical `Surface` enum: buccal → */\n/* vestibular (cheek/lip side), lingual → oral (tongue side). */\n/* ------------------------------------------------------------------ */\n\nexport type Projection = 'side' | 'plan';\n/** The user-selectable view: a single projection, or both stacked together. */\nexport type ViewMode = Projection | 'both';\n\n/** Map the clinical `Surface` enum to the asset surface filename token. */\nexport const SURFACE_ASSET_NAME: Record<Surface, string> = {\n mesial: 'mesial',\n distal: 'distal',\n occlusal: 'occlusal',\n buccal: 'vestibular',\n lingual: 'oral',\n};\n\n/** Conditions that render as per-surface fills in the plan view. */\nexport const CONDITION_PLAN_FOLDER: Partial<Record<ToothCondition, string>> = {\n caries: 'caries',\n filled: 'filling',\n};\n\n/** Resolve a per-surface plan-view overlay URL (e.g. caries on the distal). */\nexport function surfaceSymbolUrl(\n meta: ToothMeta,\n assetBaseUrl: string,\n folder: string,\n surface: Surface,\n): string {\n const view = meta.arch === 'upper' ? 'top' : 'bottom';\n return `${assetBaseUrl}/plan/${folder}/${view}/${assetFdi(meta)}-${SURFACE_ASSET_NAME[surface]}.webp`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Surface zones — interactive per-surface picking (plan view) */\n/* ------------------------------------------------------------------ */\n\n/**\n * Clickable surface regions of a plan-view tooth, named by SCREEN position.\n * `zoneSurface()` resolves each to the anatomical `Surface` per quadrant.\n */\nexport type SurfaceZone = 'top' | 'bottom' | 'left' | 'right' | 'center';\n\n/**\n * Which zones a tooth exposes. Molars & premolars have a central occlusal\n * table (5 zones); incisors & canines have no occlusal surface to mark, so\n * their crown splits into 4 directional zones.\n */\nexport function zonesForTooth(meta: ToothMeta): SurfaceZone[] {\n const fiveZone = meta.anatomy === 'molar' || meta.anatomy === 'premolar';\n return fiveZone\n ? ['top', 'bottom', 'left', 'right', 'center']\n : ['top', 'bottom', 'left', 'right'];\n}\n\n/**\n * Map a screen zone to the anatomical surface, QUADRANT-AWARE. Two flips make\n * this non-trivial (ported from the platform odontogram's `_getAreaBySide`, so\n * a finding always lands on the correct surface wherever the tooth sits):\n *\n * - mesial / distal (left & right zones) flip between the patient's right\n * quadrants {1,4} and left quadrants {2,3} — \"toward the midline\" reverses.\n * - buccal(vestibular) / lingual(oral) (top & bottom zones) flip between the\n * upper and lower arch.\n * - centre is always occlusal.\n *\n * Primary quadrants (5-8) normalise to their permanent counterpart (1-4).\n */\nexport function zoneSurface(meta: ToothMeta, zone: SurfaceZone): Surface {\n if (zone === 'center') return 'occlusal';\n if (zone === 'top') return meta.arch === 'upper' ? 'buccal' : 'lingual';\n if (zone === 'bottom') return meta.arch === 'upper' ? 'lingual' : 'buccal';\n // left / right → mesial / distal, by quadrant.\n const q = meta.quadrant <= 4 ? meta.quadrant : meta.quadrant - 4;\n const leftIsDistal = q === 1 || q === 4; // Q1 (upper-right) & Q4 (lower-left)\n if (zone === 'left') return leftIsDistal ? 'distal' : 'mesial';\n return leftIsDistal ? 'mesial' : 'distal';\n}\n\nconst r2 = (n: number) => Math.round(n * 100) / 100;\n\n/**\n * SVG `d` path for a clickable surface zone within a tooth's local box.\n * 5-zone teeth frame a central occlusal rect with four edge trapezoids;\n * 4-zone teeth split the box along both diagonals into four triangles meeting\n * at the centre.\n */\nexport function zonePath(\n zone: SurfaceZone,\n rect: { x: number; y: number; w: number; h: number },\n hasCenter: boolean,\n): string {\n const { x, y, w, h } = rect;\n const x1 = x + w;\n const y1 = y + h;\n const p = (px: number, py: number) => `${r2(px)} ${r2(py)}`;\n if (!hasCenter) {\n const cx = x + w / 2;\n const cy = y + h / 2;\n switch (zone) {\n case 'top':\n return `M ${p(x, y)} L ${p(x1, y)} L ${p(cx, cy)} Z`;\n case 'bottom':\n return `M ${p(x, y1)} L ${p(x1, y1)} L ${p(cx, cy)} Z`;\n case 'left':\n return `M ${p(x, y)} L ${p(cx, cy)} L ${p(x, y1)} Z`;\n case 'right':\n return `M ${p(x1, y)} L ${p(cx, cy)} L ${p(x1, y1)} Z`;\n default:\n return '';\n }\n }\n // 5-zone: central occlusal rect inset 30% on each axis, four trapezoids.\n const ix = x + w * 0.3;\n const iy = y + h * 0.3;\n const ix1 = x + w * 0.7;\n const iy1 = y + h * 0.7;\n switch (zone) {\n case 'center':\n return `M ${p(ix, iy)} L ${p(ix1, iy)} L ${p(ix1, iy1)} L ${p(ix, iy1)} Z`;\n case 'top':\n return `M ${p(x, y)} L ${p(x1, y)} L ${p(ix1, iy)} L ${p(ix, iy)} Z`;\n case 'bottom':\n return `M ${p(x, y1)} L ${p(x1, y1)} L ${p(ix1, iy1)} L ${p(ix, iy1)} Z`;\n case 'left':\n return `M ${p(x, y)} L ${p(ix, iy)} L ${p(ix, iy1)} L ${p(x, y1)} Z`;\n case 'right':\n return `M ${p(x1, y)} L ${p(ix1, iy)} L ${p(ix1, iy1)} L ${p(x1, y1)} Z`;\n default:\n return '';\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Viewport layout helpers */\n/* */\n/* Image-based rendering: every photoreal render shares a fixed canvas */\n/* (375×808 facial, 328×328 occlusal), so relative tooth size is baked */\n/* into the artwork. The chart lays teeth out in UNIFORM slots and lets */\n/* each image carry its own anatomy. */\n/* ------------------------------------------------------------------ */\n\nexport const TOOTH_GAP = 5;\nexport const TOOTH_ROW_GAP = 40;\nexport const TOOTH_HIT_PAD = 4;\nexport const TOOTH_SLOT_WIDTH = 36;\n/** Facial-view slot block-size; the plan/occlusal view uses a shorter slot. */\nexport const TOOTH_SLOT_HEIGHT = 62;\n\n/**\n * Resolve a tooth render URL. `view` follows the arch (`top` = upper,\n * `bottom` = lower); `symbol` selects the artwork layer (`default` is the\n * healthy tooth; condition/finding overlays use their symbol folder).\n */\nexport function toothImageUrl(\n meta: ToothMeta,\n assetBaseUrl: string,\n symbol = 'default',\n projection: 'side' | 'plan' = 'side',\n): string {\n const view = meta.arch === 'upper' ? 'top' : 'bottom';\n return `${assetBaseUrl}/${projection}/${symbol}/${view}/${assetFdi(meta)}.webp`;\n}\n\nexport interface PositionedTooth {\n fdi: FdiId;\n meta: ToothMeta;\n x: number;\n y: number;\n}\n\n/**\n * Produce the positioned list of teeth for a given dentition. The layout\n * is a two-row grid reading viewer-left-to-right across the upper arch,\n * then viewer-left-to-right across the lower arch. Clinical convention\n * is preserved: the patient's right sits on the viewer's left in both\n * arches, regardless of document direction.\n */\nexport function layoutTeeth(\n dentition: Dentition,\n slotHeight: number = TOOTH_SLOT_HEIGHT,\n): {\n teeth: PositionedTooth[];\n width: number;\n height: number;\n} {\n const ids: FdiId[] =\n dentition === 'primary'\n ? PRIMARY_TEETH\n : dentition === 'mixed'\n ? [...PERMANENT_TEETH, ...PRIMARY_TEETH]\n : PERMANENT_TEETH;\n\n // Upper / lower partition is inferred from meta.arch.\n const upper: FdiId[] = [];\n const lower: FdiId[] = [];\n for (const id of ids) {\n const meta = FDI_TO_META[id];\n if (meta.arch === 'upper') upper.push(id);\n else lower.push(id);\n }\n\n // Uniform slots — relative tooth size is baked into each render, so every\n // tooth occupies the same slot and the artwork carries the anatomy.\n const slot = TOOTH_SLOT_WIDTH + TOOTH_GAP;\n const maxCount = Math.max(upper.length, lower.length);\n const maxRowWidth = maxCount > 0 ? maxCount * slot - TOOTH_GAP : 0;\n\n function positionRow(row: FdiId[], yOffset: number): PositionedTooth[] {\n const rowWidth = row.length > 0 ? row.length * slot - TOOTH_GAP : 0;\n const startX = (maxRowWidth - rowWidth) / 2;\n return row.map((id, i) => {\n const meta = FDI_TO_META[id];\n return {\n fdi: id,\n meta,\n x: startX + i * slot,\n y: yOffset,\n };\n });\n }\n\n const upperRow = positionRow(upper, 0);\n const lowerRow = positionRow(lower, slotHeight + TOOTH_ROW_GAP);\n\n const width = maxRowWidth > 0 ? maxRowWidth : maxCount * slot;\n const height = slotHeight * 2 + TOOTH_ROW_GAP;\n\n return { teeth: [...upperRow, ...lowerRow], width, height };\n}\n\n/* ------------------------------------------------------------------ */\n/* Labels by numbering */\n/* ------------------------------------------------------------------ */\n\nexport function labelFor(id: FdiId, numbering: Numbering): string {\n switch (numbering) {\n case 'universal':\n return FDI_TO_UNIVERSAL[id] ?? id;\n case 'palmer':\n return FDI_TO_PALMER[id] ?? id;\n case 'fdi':\n default:\n return id;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Chart helpers */\n/* ------------------------------------------------------------------ */\n\nexport function emptyChart(): ToothChart {\n return {};\n}\n\nexport function chartFromConditions(\n conditions: Partial<Record<FdiId, ToothCondition[]>>,\n): ToothChart {\n const chart: ToothChart = {};\n for (const [id, list] of Object.entries(conditions)) {\n if (!list || list.length === 0) continue;\n chart[id] = { conditions: list, surfaces: [] };\n }\n return chart;\n}\n","/* ------------------------------------------------------------------ */\n/* ToothScheme — the consolidated AlfaDocs odontogram. */\n/* */\n/* - Image-base + SVG overlay: each tooth is a photoreal CGI render */\n/* (`<image>`, served from `assetBaseUrl`); the SVG layer on top */\n/* carries findings, selection, keyboard nav and a11y. No third-party */\n/* engine — `src/docs/08-third-party.mdx §Dental chart` rejected the */\n/* candidates (jQuery, abandoned, poor a11y). */\n/* */\n/* - Colour-not-alone: whole-tooth findings render a DISTINCT symbol */\n/* glyph image (the shape is the channel) + the tooth's accessible */\n/* name + tooltip; surface findings (caries / filled) render a */\n/* per-surface fill in the plan view, or a distinguished ring (solid */\n/* = caries, dashed = filled) + legend + tooltip in the side view. */\n/* */\n/* - Two projections: `side` (facial — whole-tooth findings) and */\n/* `plan` (occlusal — per-surface caries / fillings, the \"Stato */\n/* dentale\" marking). Per-arch orientation comes from the top/bottom */\n/* view folders, so the SVG never mirrors. */\n/* */\n/* - Chart orientation is FIXED to clinical convention: the patient's */\n/* right sits on the viewer's left in both arches regardless of */\n/* `dir`. A mirrored chart would invert every recorded diagnosis. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n} from 'react';\nimport * as RadixTooltip from '@radix-ui/react-tooltip';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Settings } from 'lucide-react';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { IconButton } from '../button';\nimport { Popover } from '../popover';\nimport { Select } from '../select';\nimport { Switch } from '../switch';\nimport { toothSchemeAgent } from './tooth-scheme.agent';\n\nimport {\n CONDITION_COLORS,\n CONDITION_SIDE_SYMBOL,\n CONDITION_PLAN_FOLDER,\n conditionSymbolUrl,\n surfaceSymbolUrl,\n zonesForTooth,\n zoneSurface,\n zonePath,\n FDI_TO_META,\n PERMANENT_TEETH,\n PRIMARY_TEETH,\n TOOTH_HIT_PAD,\n TOOTH_SLOT_WIDTH,\n TOOTH_SLOT_HEIGHT,\n PRIMARY_TOOTH_SCALE,\n chartFromConditions,\n labelFor,\n layoutTeeth,\n toothImageUrl,\n type Projection,\n type ViewMode,\n type Dentition,\n type FdiId,\n type Numbering,\n type Surface,\n type SurfaceZone,\n type ToothChart,\n type ToothCondition,\n type ToothMode,\n type ToothState,\n} from './tooth-data';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface ToothSchemeProps {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Which teeth to render. Default `'permanent'`. */\n dentition?: Dentition;\n /** Numbering system shown on each tooth label. Default `'fdi'`. */\n numbering?: Numbering;\n /** `'interactive'` enables selection + keyboard nav; `'display'` is read-only. Default `'interactive'`. */\n mode?: ToothMode;\n /**\n * `'side'` shows the facial view (whole-tooth findings); `'plan'` shows the\n * occlusal view (per-surface caries / fillings); `'both'` stacks the side\n * chart above an interactive occlusal companion that shares the chart data.\n * Default `'side'`.\n */\n projection?: ViewMode;\n /** Controlled chart state — the full `Record<FdiId, ToothState>`. */\n value?: ToothChart;\n /** Uncontrolled initial chart state. */\n defaultValue?: ToothChart;\n /** Fired whenever the chart changes — always emits FDI ids. */\n onChange?: (next: ToothChart) => void;\n /** Fired when a tooth is focused or clicked. */\n onSelect?: (toothId: FdiId) => void;\n /** Shortcut for pre-populating conditions: `{ '16': ['caries'], '36': ['filled'] }`. */\n conditions?: Partial<Record<FdiId, ToothCondition[]>>;\n /**\n * The finding a tooth-click applies in interactive mode (the selected\n * tool in a Findings / \"Stato dentale\" panel). Clicking a tooth toggles\n * this condition. When unset, clicking cycles caries on/off.\n */\n activeCondition?: ToothCondition;\n /**\n * Base URL the photoreal tooth renders are served from. Resolves to\n * `${assetBaseUrl}/{side|plan}/{symbol}/{top|bottom}/{fdi}.webp`. Defaults\n * to the kit's bundled static path; host the `toothscheme/teeth` set\n * elsewhere (CDN) by overriding this. Trusted developer-controlled value —\n * interpolated into an SVG `<image href>` (which cannot execute scripts),\n * not user input; intentionally not runtime-validated.\n */\n assetBaseUrl?: string;\n /**\n * Show the finding-colour legend below the chart. Default `false` — findings\n * render as distinct symbol glyphs (self-describing) + tooltips, so the\n * colour key is opt-in; a consuming \"Stato dentale\" surface uses a\n * finding-type panel as its key instead.\n */\n legend?: boolean;\n /**\n * Render a built-in options affordance: a gear button that opens a popover\n * letting the END USER toggle the legend and switch dentition / numbering /\n * projection. Opt-in — when on, those four become user-overridable (seeded\n * from the props); when off, the props drive the chart directly. Default\n * `false`.\n */\n controls?: boolean;\n /** Accessible label override for the chart region. */\n ariaLabel?: string;\n /** Extra class names on the wrapper. */\n className?: string;\n}\n\nexport interface ToothSchemeHandle {\n /** Programmatically focus a tooth by FDI id. */\n focusTooth: (id: FdiId) => void;\n /** Read the current chart state. */\n getChart: () => ToothChart;\n /** Read the findings recorded on one tooth (empty array if none). */\n getTooth: (id: FdiId) => ToothCondition[];\n /** Read the FDI ids of every tooth carrying a given finding. */\n teethWith: (condition: ToothCondition) => FdiId[];\n /** Add a finding to a tooth (no-op if already present). Optionally mark surfaces. */\n setFinding: (\n id: FdiId,\n condition: ToothCondition,\n surfaces?: Surface[],\n ) => void;\n /** Remove a finding from a tooth (no-op if absent). */\n removeFinding: (id: FdiId, condition: ToothCondition) => void;\n /** Clear every finding from a tooth. */\n clearTooth: (id: FdiId) => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst rootVariants = cva(\n [\n 'ds:tooth-scheme-alfadocs',\n 'ds:flex ds:flex-col',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n // Block-level flex column so the SVG's w-full can grow to fill the frame.\n // min-w-fit on the SVG floors it at natural size, so narrow frames scroll\n // here rather than shrinking the per-tooth hit target below the 44px floor.\n 'ds:max-w-full ds:overflow-x-auto',\n // When the scroll container itself is the tab stop (display mode, see\n // scrollTabIndex) it needs a focus ring. Use an outline (not box-shadow):\n // forced-colors / high-contrast mode zeroes box-shadow, which would leave\n // HCM keyboard users with no visible focus. outline survives, and the\n // CanvasText fallback repaints it in the system palette.\n 'ds:outline-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\n// The SVG renders at its natural pixel size (set via width/height below) so\n// Responsive: the SVG grows to FILL a wider frame (w-full) but never scales\n// below its natural size (min-w-fit floors it at the viewBox's intrinsic\n// width), so the per-tooth target keeps its ≥44px floor and the root scrolls on\n// narrow frames instead of shrinking. h-auto preserves the viewBox aspect.\nconst svgVariants = cva(\n [\n 'ds:block',\n 'ds:w-full ds:min-w-fit ds:h-auto',\n 'ds:text-[var(--foreground)]',\n ].join(' '),\n);\n\n// `group` here is load-bearing — the focus-ring <rect> below uses\n// `group-focus-visible:opacity-100` to appear when the parent <g> takes\n// focus. Without this class the selector never fires and keyboard users\n// see no focus indicator (a11y-critical-fixes.mdx).\nconst toothGroupVariants = cva(\n [\n 'ds:group ds:cursor-pointer',\n 'ds:focus:outline-none',\n 'ds:transition-[fill,stroke,opacity] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n ].join(' '),\n);\n\nconst legendVariants = cva(\n [\n 'ds:flex ds:flex-wrap ds:items-center',\n 'ds:gap-[var(--spacing-sm)]',\n 'type-meta ds:text-[var(--muted-foreground)]',\n ].join(' '),\n);\n\nconst legendItemVariants = cva(\n ['ds:inline-flex ds:items-center', 'ds:gap-[var(--spacing-xs)]'].join(' '),\n);\n\nconst liveRegionVariants = cva(['ds:sr-only'].join(' '));\n\n// Surface-zone affordance (plan view, interactive surface-picking). Invisible\n// until hovered (pointer) or focused (keyboard, drilled-in) — the marked\n// surface itself is shown by the photoreal per-surface overlay underneath.\nconst zoneVariants = cva(\n [\n 'ds:cursor-pointer ds:outline-none',\n 'ds:fill-transparent ds:stroke-transparent',\n 'ds:transition-[fill] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:hover:fill-[color-mix(in_srgb,var(--accent)_18%,transparent)]',\n 'ds:focus-visible:fill-[color-mix(in_srgb,var(--accent)_22%,transparent)]',\n 'ds:focus-visible:stroke-[var(--ring)]',\n 'ds:forced-colors:focus-visible:stroke-[CanvasText]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction isControlled(props: Pick<ToothSchemeProps, 'value'>): boolean {\n return props.value !== undefined;\n}\n\nfunction emptyState(): ToothState {\n return { conditions: [], surfaces: [] };\n}\n\nfunction cycleCondition(\n current: ToothCondition[] | undefined,\n active?: ToothCondition,\n): ToothCondition[] {\n const list = current ?? [];\n // No tool selected → cycle caries on/off (legacy demo behaviour).\n if (!active) return list.length === 0 ? ['caries'] : [];\n // A finding tool is selected → toggle it on this tooth.\n return list.includes(active)\n ? list.filter((condition) => condition !== active)\n : [...list, active];\n}\n\n/**\n * Drill-in arrow navigation between a tooth's surface zones. 4-zone teeth map\n * each arrow straight to its zone; 5-zone teeth pivot through the occlusal\n * centre (every edge connects only to the centre, the centre to all edges).\n */\nfunction nextZone(\n zone: SurfaceZone,\n key: string,\n hasCenter: boolean,\n): SurfaceZone {\n if (!hasCenter) {\n if (key === 'ArrowUp') return 'top';\n if (key === 'ArrowDown') return 'bottom';\n if (key === 'ArrowLeft') return 'left';\n if (key === 'ArrowRight') return 'right';\n return zone;\n }\n const hub: Record<SurfaceZone, Partial<Record<string, SurfaceZone>>> = {\n top: { ArrowDown: 'center' },\n bottom: { ArrowUp: 'center' },\n left: { ArrowRight: 'center' },\n right: { ArrowLeft: 'center' },\n center: {\n ArrowUp: 'top',\n ArrowDown: 'bottom',\n ArrowLeft: 'left',\n ArrowRight: 'right',\n },\n };\n return hub[zone]?.[key] ?? zone;\n}\n\n/* ------------------------------------------------------------------ */\n/* Legend */\n/* */\n/* Each entry shows the finding EXACTLY as it renders on the chart — a */\n/* mini tooth (the upper-right molar) carrying that finding's symbol */\n/* glyph, surface ring, or missing-X — so the key actually maps to the */\n/* scheme rather than to an abstract colour swatch. */\n/* ------------------------------------------------------------------ */\n\nconst ALL_CONDITIONS: ToothCondition[] = [\n 'caries',\n 'filled',\n 'crowned',\n 'temporaryCrown',\n 'bridge',\n 'rootCanal',\n 'implant',\n 'implantExtraction',\n 'stub',\n 'destroyed',\n 'missing',\n];\n\n/** A 36×62 mini tooth rendering one finding, mirroring the chart's visuals. */\nfunction LegendSymbol({\n condition,\n assetBaseUrl,\n}: {\n condition: ToothCondition;\n assetBaseUrl: string;\n}): ReactElement {\n const meta = FDI_TO_META['16'];\n const spec = CONDITION_SIDE_SYMBOL[condition];\n const isMissing = condition === 'missing';\n const isSurface = condition === 'caries' || condition === 'filled';\n // Match the chart: the render is inset (scaled 0.9) so the surface ring and\n // missing-X never touch the tooth — the same fix applied to the live teeth.\n const w = 36 * 0.9;\n const h = 62 * 0.9;\n const x = (36 - w) / 2;\n const y = (62 - h) / 2;\n return (\n <svg\n width=\"22\"\n height=\"38\"\n viewBox=\"0 0 36 62\"\n aria-hidden=\"true\"\n className=\"ds:block ds:shrink-0\"\n >\n <image\n href={toothImageUrl(meta, assetBaseUrl)}\n x={x}\n y={y}\n width={w}\n height={h}\n preserveAspectRatio=\"xMidYMid meet\"\n opacity={isMissing ? 0.25 : 1}\n />\n {spec ? (\n <image\n href={conditionSymbolUrl(meta, assetBaseUrl, spec)}\n x={x}\n y={y}\n width={w}\n height={h}\n preserveAspectRatio=\"xMidYMid meet\"\n />\n ) : null}\n {isSurface ? (\n <rect\n x={3}\n y={2}\n width={30}\n height={58}\n fill=\"none\"\n stroke={CONDITION_COLORS[condition]}\n strokeWidth={2}\n strokeDasharray={condition === 'filled' ? '4 2' : undefined}\n rx={6}\n />\n ) : null}\n {isMissing ? (\n <path\n d=\"M7 9 L29 53 M29 9 L7 53\"\n stroke={CONDITION_COLORS.missing}\n strokeWidth={2}\n fill=\"none\"\n />\n ) : null}\n </svg>\n );\n}\n\nfunction Legend({ assetBaseUrl }: { assetBaseUrl: string }): ReactElement {\n const { t } = useTranslation();\n return (\n <section\n aria-label={t('toothScheme.legendLabel')}\n data-testid=\"tooth-scheme-legend\"\n // Matches the Card `elevated` variant exactly: --card surface, a subtle\n // --card-border, --shadow-card, and the thicker border in the accessible\n // theme. --muted-foreground on --card stays a validated pair.\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:rounded-[var(--radius-md)] ds:bg-[var(--card)] ds:border ds:border-[color:var(--card-border)] ds:p-[var(--spacing-sm)] ds:shadow-[var(--shadow-card)] ds:[.theme-accessible_&]:border-2\"\n >\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)]\">\n {t('toothScheme.legendLabel')}\n </span>\n <ul className={legendVariants()}>\n {ALL_CONDITIONS.map((condition) => (\n <li\n key={condition}\n className={legendItemVariants()}\n data-condition={condition}\n data-testid={`tooth-scheme-legend-item-${condition}`}\n >\n <LegendSymbol condition={condition} assetBaseUrl={assetBaseUrl} />\n <span>{t(`toothScheme.condition.${condition}`)}</span>\n </li>\n ))}\n </ul>\n </section>\n );\n}\n\n// One labelled Select row inside the options popover. The label stacks ABOVE a\n// full-width Select so long option values (e.g. \"Permanent dentition\") fit on\n// one line. The visible label is `aria-hidden` (sighted-only) and duplicated as\n// the Select's `aria-label`, so screen-reader users get the name once.\nfunction OptionRow({\n label,\n value,\n options,\n onValueChange,\n container,\n}: {\n label: string;\n value: string;\n options: { value: string; label: string }[];\n onValueChange: (value: string) => void;\n container?: HTMLElement | null;\n}): ReactElement {\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <span\n aria-hidden=\"true\"\n className=\"type-label ds:text-[color:var(--muted-foreground)]\"\n >\n {label}\n </span>\n <Select\n size=\"md\"\n aria-label={label}\n value={value}\n options={options}\n onValueChange={onValueChange}\n // Portal the listbox into the popover so it renders above it (the\n // global z-scale puts --z-dropdown below --z-popover).\n container={container}\n />\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const ToothScheme = forwardRef<ToothSchemeHandle, ToothSchemeProps>(\n (\n {\n id,\n dentition: dentitionProp = 'permanent',\n numbering: numberingProp = 'fdi',\n mode = 'interactive',\n projection: projectionProp = 'side',\n value,\n defaultValue,\n onChange,\n onSelect,\n conditions,\n activeCondition,\n assetBaseUrl = '/toothscheme/teeth',\n legend: legendProp = false,\n controls = false,\n ariaLabel,\n className,\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n // User-facing options (the gear popover). When `controls` is on, the\n // chart's dentition / numbering / projection / legend become\n // user-overridable: internal state is seeded from the props and the popover\n // updates it. When `controls` is off, the props drive the chart directly\n // (the component stays fully controlled for consumers who don't want it).\n const [uiDentition, setUiDentition] = useState<Dentition>(dentitionProp);\n const [uiNumbering, setUiNumbering] = useState<Numbering>(numberingProp);\n const [uiProjection, setUiProjection] = useState<ViewMode>(projectionProp);\n const [uiLegend, setUiLegend] = useState<boolean>(legendProp);\n\n // Portal target for the option selects, captured from the popover content\n // so their listboxes render above the popover (not behind it).\n const [optionsPopoverEl, setOptionsPopoverEl] =\n useState<HTMLElement | null>(null);\n\n const dentition = controls ? uiDentition : dentitionProp;\n const numbering = controls ? uiNumbering : numberingProp;\n const legend = controls ? uiLegend : legendProp;\n // The View select can pick a single projection or 'both'. The main chart\n // renders one projection; 'both' additionally renders an occlusal companion\n // (a nested ToothScheme sharing the chart data) so both stay interactive.\n const viewMode: ViewMode = controls ? uiProjection : projectionProp;\n const projection: Projection = viewMode === 'plan' ? 'plan' : 'side';\n const showCompanion = viewMode === 'both';\n\n // The `ui*` seeds above only run once (at mount). If `controls` flips on\n // later, re-seed from the current props so the popover opens from the\n // consumer's latest values rather than the stale mount-time snapshot.\n const controlsWasOn = useRef(controls);\n useEffect(() => {\n if (controls && !controlsWasOn.current) {\n setUiDentition(dentitionProp);\n setUiNumbering(numberingProp);\n setUiProjection(projectionProp);\n setUiLegend(legendProp);\n }\n controlsWasOn.current = controls;\n }, [controls, dentitionProp, numberingProp, projectionProp, legendProp]);\n\n // Chart state — controlled / uncontrolled.\n const [internalChart, setInternalChart] = useState<ToothChart>(() => {\n if (value !== undefined) return value;\n if (defaultValue !== undefined) return defaultValue;\n if (conditions) return chartFromConditions(conditions);\n return {};\n });\n\n const chart: ToothChart = isControlled({ value })\n ? (value as ToothChart)\n : internalChart;\n\n // Keep uncontrolled chart in sync when `conditions` shortcut updates.\n useEffect(() => {\n if (isControlled({ value })) return;\n if (conditions === undefined) return;\n setInternalChart(chartFromConditions(conditions));\n // Intentionally depend on a stable key — swapping the entire prop\n // snapshot is the consumer's signal to reset.\n }, [conditions, value]);\n\n // Plan (occlusal) teeth are square; facial teeth are tall (crown + root).\n const slotHeight = projection === 'plan' ? 44 : TOOTH_SLOT_HEIGHT;\n\n // Layout.\n const layout = useMemo(\n () => layoutTeeth(dentition, slotHeight),\n [dentition, slotHeight],\n );\n const visibleIds = useMemo(() => layout.teeth.map((t) => t.fdi), [layout]);\n\n // Roving tabindex: which tooth owns `tabindex=\"0\"`.\n const firstId: FdiId | undefined = visibleIds[0];\n const [focusedId, setFocusedId] = useState<FdiId | undefined>(firstId);\n useEffect(() => {\n if (!focusedId || !visibleIds.includes(focusedId)) {\n setFocusedId(firstId);\n }\n }, [firstId, focusedId, visibleIds]);\n\n // Live-region announcement text.\n const [announcement, setAnnouncement] = useState<string>('');\n\n const svgRef = useRef<SVGSVGElement>(null);\n\n const commitChart = useCallback(\n (next: ToothChart) => {\n if (!isControlled({ value })) {\n setInternalChart(next);\n }\n onChange?.(next);\n },\n [onChange, value],\n );\n\n const focusToothById = useCallback((id: FdiId) => {\n const svg = svgRef.current;\n if (!svg) return;\n const node = svg.querySelector<SVGGElement>(`g[data-fdi=\"${id}\"]`);\n if (node) {\n node.focus();\n setFocusedId(id);\n }\n }, []);\n\n /* ------------------------------------------------------------- */\n /* Per-surface picking (plan view, caries / filling) */\n /* ------------------------------------------------------------- */\n\n // Live only in the occlusal (plan) view while a surface finding\n // (caries / filling) is the active tool.\n const surfacePicking =\n projection === 'plan' &&\n mode === 'interactive' &&\n (activeCondition === 'caries' || activeCondition === 'filled');\n\n // Drill-in state: the tooth + zone the keyboard is currently inside\n // (null = tooth-level navigation, the default).\n const [drilled, setDrilled] = useState<{\n fdi: FdiId;\n zone: SurfaceZone;\n } | null>(null);\n\n // End the drill if surface-picking turns off (tool / view change) OR the\n // drilled tooth leaves the layout (e.g. the dentition changes mid-drill) —\n // a stale drill would leave every tooth tabIndex=-1 and lock out keyboard.\n useEffect(() => {\n if (!surfacePicking || (drilled && !visibleIds.includes(drilled.fdi))) {\n setDrilled(null);\n }\n }, [surfacePicking, drilled, visibleIds]);\n\n const focusZone = useCallback((fdi: FdiId, zone: SurfaceZone) => {\n const node = svgRef.current?.querySelector<SVGPathElement>(\n `path[data-fdi=\"${fdi}\"][data-zone=\"${zone}\"]`,\n );\n node?.focus();\n }, []);\n\n // Move DOM focus onto the drilled zone when it changes; restore focus to\n // the tooth when the drill ends (Escape).\n const prevDrilled = useRef<{ fdi: FdiId; zone: SurfaceZone } | null>(null);\n useEffect(() => {\n if (drilled) {\n focusZone(drilled.fdi, drilled.zone);\n } else if (prevDrilled.current) {\n focusToothById(prevDrilled.current.fdi);\n }\n prevDrilled.current = drilled;\n }, [drilled, focusZone, focusToothById]);\n\n const isSurfaceMarked = useCallback(\n (fdi: FdiId, surface: Surface): boolean => {\n const state = chart[fdi];\n return Boolean(\n state &&\n state.surfaces.includes(surface) &&\n state.conditions.includes(activeCondition as ToothCondition),\n );\n },\n [chart, activeCondition],\n );\n\n const announceTooth = useCallback(\n (fdi: FdiId, state: ToothState | undefined) => {\n if (state && state.conditions.length > 0) {\n setAnnouncement(\n t('toothScheme.selected', {\n id: fdi,\n conditions: state.conditions\n .map((c) => t(`toothScheme.condition.${c}`))\n .join(', '),\n }),\n );\n } else {\n setAnnouncement(t('toothScheme.deselected', { id: fdi }));\n }\n },\n [t],\n );\n\n const toggleSurface = useCallback(\n (fdi: FdiId, surface: Surface) => {\n if (!surfacePicking) return;\n const cond = activeCondition as ToothCondition;\n const prev = chart[fdi] ?? emptyState();\n const hadSurface = prev.surfaces.includes(surface);\n const hadCond = prev.conditions.includes(cond);\n let surfaces: Surface[];\n let conditions: ToothCondition[];\n if (hadSurface && hadCond) {\n surfaces = prev.surfaces.filter((s) => s !== surface);\n conditions =\n surfaces.length === 0\n ? prev.conditions.filter((c) => c !== cond)\n : prev.conditions;\n } else {\n surfaces = hadSurface ? prev.surfaces : [...prev.surfaces, surface];\n conditions = hadCond ? prev.conditions : [...prev.conditions, cond];\n }\n const next: ToothChart = { ...chart };\n if (conditions.length === 0 && surfaces.length === 0) {\n delete next[fdi];\n } else {\n next[fdi] = { ...prev, conditions, surfaces };\n }\n commitChart(next);\n announceTooth(fdi, next[fdi]);\n onSelect?.(fdi);\n },\n [\n surfacePicking,\n activeCondition,\n chart,\n commitChart,\n announceTooth,\n onSelect,\n ],\n );\n\n const drillInto = useCallback((fdi: FdiId) => {\n const meta = FDI_TO_META[fdi];\n if (!meta) return;\n setFocusedId(fdi);\n setDrilled({ fdi, zone: zonesForTooth(meta)[0] });\n }, []);\n\n const handleSurfaceKeyDown = useCallback(\n (event: KeyboardEvent<SVGPathElement>, fdi: FdiId, zone: SurfaceZone) => {\n const meta = FDI_TO_META[fdi];\n if (!meta) return;\n switch (event.key) {\n case 'ArrowUp':\n case 'ArrowDown':\n case 'ArrowLeft':\n case 'ArrowRight': {\n event.preventDefault();\n event.stopPropagation();\n const hasCenter = zonesForTooth(meta).includes('center');\n const nz = nextZone(zone, event.key, hasCenter);\n if (nz !== zone) setDrilled({ fdi, zone: nz });\n return;\n }\n case ' ':\n case 'Enter': {\n event.preventDefault();\n event.stopPropagation();\n toggleSurface(fdi, zoneSurface(meta, zone));\n return;\n }\n case 'Escape': {\n event.preventDefault();\n event.stopPropagation();\n setDrilled(null);\n return;\n }\n default:\n return;\n }\n },\n [toggleSurface],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n\n const agentHandle = useMemo<ToothSchemeHandle>(\n () => ({\n focusTooth: (id: FdiId) => {\n focusToothById(id);\n },\n getChart: () => chart,\n getTooth: (id: FdiId) => chart[id]?.conditions ?? [],\n teethWith: (condition: ToothCondition) =>\n Object.entries(chart)\n .filter(([, state]) => state.conditions.includes(condition))\n .map(([fdi]) => fdi),\n setFinding: (\n id: FdiId,\n condition: ToothCondition,\n surfaces?: Surface[],\n ) => {\n const prev = chart[id] ?? emptyState();\n if (prev.conditions.includes(condition) && !surfaces) return;\n const next: ToothChart = {\n ...chart,\n [id]: {\n ...prev,\n conditions: prev.conditions.includes(condition)\n ? prev.conditions\n : [...prev.conditions, condition],\n surfaces: surfaces ?? prev.surfaces,\n },\n };\n commitChart(next);\n },\n removeFinding: (id: FdiId, condition: ToothCondition) => {\n const prev = chart[id];\n if (!prev || !prev.conditions.includes(condition)) return;\n const conditions = prev.conditions.filter((c) => c !== condition);\n const next: ToothChart = { ...chart };\n if (conditions.length === 0) {\n delete next[id];\n } else {\n next[id] = { ...prev, conditions };\n }\n commitChart(next);\n },\n clearTooth: (id: FdiId) => {\n if (!chart[id]) return;\n const next: ToothChart = { ...chart };\n delete next[id];\n commitChart(next);\n },\n }),\n [chart, commitChart, focusToothById],\n );\n useImperativeHandle(ref, () => agentHandle, [agentHandle]);\n useAgentRegistration(toothSchemeAgent, agentHandle, id);\n\n /* ------------------------------------------------------------- */\n /* Keyboard navigation */\n /* ------------------------------------------------------------- */\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<SVGGElement>, id: FdiId) => {\n if (mode !== 'interactive') return;\n const meta = FDI_TO_META[id];\n if (!meta) return;\n\n // Resolve the ordered list of visible ids for Left/Right.\n const order = visibleIds;\n const currentIndex = order.indexOf(id);\n\n switch (event.key) {\n case 'ArrowRight': {\n event.preventDefault();\n const nextIndex = Math.min(order.length - 1, currentIndex + 1);\n focusToothById(order[nextIndex]);\n return;\n }\n case 'ArrowLeft': {\n event.preventDefault();\n const nextIndex = Math.max(0, currentIndex - 1);\n focusToothById(order[nextIndex]);\n return;\n }\n case 'ArrowUp':\n case 'ArrowDown': {\n event.preventDefault();\n // Map to the opposing arch, same FDI position where possible.\n // Permanent: 1 ↔ 4, 2 ↔ 3. Primary: 5 ↔ 8, 6 ↔ 7.\n const quadrantMap: Record<number, number> = {\n 1: 4,\n 4: 1,\n 2: 3,\n 3: 2,\n 5: 8,\n 8: 5,\n 6: 7,\n 7: 6,\n };\n const targetQuadrant = quadrantMap[meta.quadrant];\n if (!targetQuadrant) return;\n const candidate = `${targetQuadrant}${meta.positionInQuadrant}`;\n if (order.includes(candidate)) {\n focusToothById(candidate);\n }\n return;\n }\n case 'Home': {\n event.preventDefault();\n // First tooth in the same quadrant (visible).\n const inQuadrant = order.filter(\n (other) => FDI_TO_META[other].quadrant === meta.quadrant,\n );\n if (inQuadrant.length > 0) {\n focusToothById(inQuadrant[0]);\n }\n return;\n }\n case 'End': {\n event.preventDefault();\n const inQuadrant = order.filter(\n (other) => FDI_TO_META[other].quadrant === meta.quadrant,\n );\n if (inQuadrant.length > 0) {\n focusToothById(inQuadrant[inQuadrant.length - 1]);\n }\n return;\n }\n case ' ':\n case 'Enter': {\n event.preventDefault();\n // In surface-picking mode, Enter drills into the tooth's surfaces\n // rather than toggling the whole tooth.\n if (surfacePicking) {\n drillInto(id);\n return;\n }\n const prev = chart[id]?.conditions;\n const nextConditions = cycleCondition(prev, activeCondition);\n const next: ToothChart = { ...chart };\n if (nextConditions.length === 0) {\n delete next[id];\n setAnnouncement(t('toothScheme.deselected', { id }));\n } else {\n next[id] = {\n ...(chart[id] ?? emptyState()),\n conditions: nextConditions,\n };\n setAnnouncement(\n t('toothScheme.selected', {\n id,\n conditions: nextConditions\n .map((c) => t(`toothScheme.condition.${c}`))\n .join(', '),\n }),\n );\n }\n commitChart(next);\n onSelect?.(id);\n return;\n }\n default:\n return;\n }\n },\n [\n activeCondition,\n chart,\n commitChart,\n drillInto,\n focusToothById,\n mode,\n onSelect,\n surfacePicking,\n t,\n visibleIds,\n ],\n );\n\n const handleClick = useCallback(\n (id: FdiId) => {\n if (mode !== 'interactive') return;\n setFocusedId(id);\n const prev = chart[id]?.conditions;\n const nextConditions = cycleCondition(prev, activeCondition);\n const next: ToothChart = { ...chart };\n if (nextConditions.length === 0) {\n delete next[id];\n setAnnouncement(t('toothScheme.deselected', { id }));\n } else {\n next[id] = {\n ...(chart[id] ?? emptyState()),\n conditions: nextConditions,\n };\n setAnnouncement(\n t('toothScheme.selected', {\n id,\n conditions: nextConditions\n .map((c) => t(`toothScheme.condition.${c}`))\n .join(', '),\n }),\n );\n }\n commitChart(next);\n onSelect?.(id);\n },\n [activeCondition, chart, commitChart, mode, onSelect, t],\n );\n\n /* ------------------------------------------------------------- */\n /* Rendering */\n /* ------------------------------------------------------------- */\n\n const viewBoxWidth = layout.width + 4; // small padding for stroke\n const viewBoxHeight = layout.height + 4;\n\n const baseLabel = ariaLabel ?? t('toothScheme.ariaLabel');\n // When both views show, name each region by its projection so the two\n // landmarks stay distinguishable (landmark-unique).\n const regionLabel = showCompanion\n ? `${baseLabel} — ${t('toothScheme.view.side')}`\n : baseLabel;\n\n // The root is horizontally scrollable (`overflow-x-auto`), so it needs\n // keyboard access. In interactive mode the roving-tabindex teeth supply\n // it; in display mode nothing inside is focusable, so the scroll\n // container itself becomes the tab stop (WCAG 2.1.1 / axe\n // scrollable-region-focusable).\n const scrollTabIndex = mode === 'interactive' ? undefined : 0;\n\n return (\n <RadixTooltip.Provider delayDuration={200}>\n <div\n ref={rootRef}\n role=\"region\"\n aria-label={regionLabel}\n tabIndex={scrollTabIndex}\n className={[rootVariants(), className].filter(Boolean).join(' ')}\n data-component=\"tooth-scheme\"\n data-component-id={id}\n data-testid=\"tooth-scheme-root\"\n data-dentition={dentition}\n data-numbering={numbering}\n data-mode={mode}\n data-projection={projection}\n data-view-mode={viewMode}\n >\n {/* User-facing options: a gear button opening a popover to toggle the\n legend and switch dentition / numbering / projection. */}\n {controls ? (\n <div\n className=\"ds:flex ds:w-full ds:justify-end\"\n data-testid=\"tooth-scheme-controls\"\n >\n <Popover.Root>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"outline\"\n icon={<Settings aria-hidden=\"true\" />}\n aria-label={t('toothScheme.options.label')}\n tooltip={t('toothScheme.options.label')}\n />\n </Popover.Trigger>\n <Popover.Content\n ref={setOptionsPopoverEl}\n align=\"end\"\n size=\"md\"\n aria-label={t('toothScheme.options.label')}\n >\n <div className=\"ds:flex ds:w-[var(--popover-size-sm)] ds:max-w-full ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Stretch the Switch row full-width so the toggle aligns\n to the inline-end edge like the selects below. */}\n <div className=\"ds:flex ds:border-b ds:border-[color:var(--border)] ds:pb-[var(--spacing-sm)] ds:[&>*]:w-full ds:[&>*]:justify-between\">\n <Switch\n label={t('toothScheme.options.legend')}\n labelSide=\"start\"\n checked={legend}\n onCheckedChange={setUiLegend}\n />\n </div>\n <OptionRow\n container={optionsPopoverEl}\n label={t('toothScheme.options.dentition')}\n value={dentition}\n onValueChange={(v) => setUiDentition(v as Dentition)}\n options={[\n {\n value: 'permanent',\n label: t('toothScheme.dentition.permanent'),\n },\n {\n value: 'primary',\n label: t('toothScheme.dentition.primary'),\n },\n {\n value: 'mixed',\n label: t('toothScheme.dentition.mixed'),\n },\n ]}\n />\n <OptionRow\n container={optionsPopoverEl}\n label={t('toothScheme.options.numbering')}\n value={numbering}\n onValueChange={(v) => setUiNumbering(v as Numbering)}\n options={[\n {\n value: 'fdi',\n label: t('toothScheme.numbering.fdi'),\n },\n {\n value: 'universal',\n label: t('toothScheme.numbering.universal'),\n },\n {\n value: 'palmer',\n label: t('toothScheme.numbering.palmer'),\n },\n ]}\n />\n <OptionRow\n container={optionsPopoverEl}\n label={t('toothScheme.options.view')}\n value={viewMode}\n onValueChange={(v) => setUiProjection(v as ViewMode)}\n options={[\n {\n value: 'side',\n label: t('toothScheme.view.side'),\n },\n {\n value: 'plan',\n label: t('toothScheme.view.occlusal'),\n },\n {\n value: 'both',\n label: t('toothScheme.view.both'),\n },\n ]}\n />\n </div>\n </Popover.Content>\n </Popover.Root>\n </div>\n ) : null}\n <svg\n ref={svgRef}\n viewBox={`0 0 ${viewBoxWidth} ${viewBoxHeight}`}\n width={viewBoxWidth}\n height={viewBoxHeight}\n className={svgVariants()}\n role=\"group\"\n aria-label={regionLabel}\n // Never a tab stop itself — keyboard focus lives on the teeth\n // (interactive) or the scroll container (display). Legacy engines\n // make a labelled SVG focusable without this.\n focusable=\"false\"\n data-testid=\"tooth-scheme-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {layout.teeth.map((tooth) => {\n const state = chart[tooth.fdi];\n const primaryCondition: ToothCondition | undefined =\n state?.conditions?.[0];\n\n const anatomyLabel = t(\n `toothScheme.anatomy.${tooth.meta.anatomy}`,\n );\n const conditionSuffix = primaryCondition\n ? `, ${t(`toothScheme.condition.${primaryCondition}`)}`\n : '';\n const label = t('toothScheme.toothLabel', {\n id: labelFor(tooth.fdi, numbering),\n anatomy: anatomyLabel,\n conditionSuffix,\n });\n\n const tabIndex =\n mode === 'interactive'\n ? drilled\n ? -1\n : tooth.fdi === focusedId\n ? 0\n : -1\n : undefined;\n\n const conditions = state?.conditions ?? [];\n const isMissing = conditions.includes('missing');\n // Whole-tooth findings (crown, implant, RCT…) overlay a photoreal\n // symbol render on the facial tooth.\n const symbolOverlays = conditions\n .map((condition) => ({\n condition,\n spec: CONDITION_SIDE_SYMBOL[condition],\n }))\n .filter(\n (\n entry,\n ): entry is {\n condition: ToothCondition;\n spec: NonNullable<typeof entry.spec>;\n } => Boolean(entry.spec),\n );\n // Surface findings (caries / filled) have no side symbol — flag\n // them with a token-coloured ring until the plan view lands.\n const surfaceCondition = conditions.find(\n (condition) =>\n condition !== 'missing' && !CONDITION_SIDE_SYMBOL[condition],\n );\n const ringColour = surfaceCondition\n ? CONDITION_COLORS[surfaceCondition]\n : undefined;\n\n const tooltipContent = primaryCondition\n ? `${anatomyLabel} · ${t(`toothScheme.condition.${primaryCondition}`)}`\n : anatomyLabel;\n\n const labelText = labelFor(tooth.fdi, numbering);\n const imageUrl = toothImageUrl(\n tooth.meta,\n assetBaseUrl,\n 'default',\n projection,\n );\n // Plan (occlusal) view: per-surface caries / filling overlays —\n // the \"Stato dentale\" surface marking.\n const surfaceOverlays =\n projection === 'plan'\n ? conditions.flatMap((condition) => {\n const folder = CONDITION_PLAN_FOLDER[condition];\n if (!folder) return [];\n return (state?.surfaces ?? []).map((surface) => ({\n key: `${condition}-${surface}`,\n url: surfaceSymbolUrl(\n tooth.meta,\n assetBaseUrl,\n folder,\n surface,\n ),\n }));\n })\n : [];\n\n // Primary teeth reuse the permanent render scaled down. A small\n // inset on every tooth keeps the render off the slot edges so\n // the focus ring + labels never crowd or touch it.\n const imgScale =\n (tooth.meta.dentition === 'primary' ? PRIMARY_TOOTH_SCALE : 1) *\n 0.9;\n const imgW = TOOTH_SLOT_WIDTH * imgScale;\n const imgH = slotHeight * imgScale;\n const imgX = (TOOTH_SLOT_WIDTH - imgW) / 2;\n const imgY = (slotHeight - imgH) / 2;\n\n // Surface-picking zones (plan view). When drilled into THIS\n // tooth, its zones become the focusable buttons and the tooth\n // group steps back to a plain container (no nested interactive).\n const isDrilled = surfacePicking && drilled?.fdi === tooth.fdi;\n const toothZones = surfacePicking\n ? zonesForTooth(tooth.meta)\n : [];\n const hasCenter = toothZones.includes('center');\n\n return (\n <RadixTooltip.Root key={tooth.fdi}>\n <RadixTooltip.Trigger asChild>\n <g\n data-fdi={tooth.fdi}\n data-anatomy={tooth.meta.anatomy}\n data-arch={tooth.meta.arch}\n data-side={tooth.meta.side}\n data-quadrant={tooth.meta.quadrant}\n data-condition={primaryCondition ?? 'none'}\n data-testid={`tooth-${tooth.fdi}`}\n transform={`translate(${tooth.x}, ${tooth.y})`}\n tabIndex={tabIndex}\n // SVG `<g>` has no implicit role, so `aria-label`\n // would be rejected by axe's `aria-prohibited-attr`\n // rule. Give it an explicit role: `button` in\n // interactive mode, `img` in display mode. When drilled\n // into for surface picking it becomes a `group` so its\n // focusable surface zones aren't nested in a button.\n role={\n isDrilled\n ? 'group'\n : mode === 'interactive'\n ? 'button'\n : 'img'\n }\n aria-label={label}\n aria-pressed={\n isDrilled\n ? undefined\n : mode === 'interactive'\n ? primaryCondition !== undefined\n : undefined\n }\n className={toothGroupVariants()}\n onClick={\n isDrilled\n ? undefined\n : mode === 'interactive'\n ? surfacePicking\n ? () => drillInto(tooth.fdi)\n : () => handleClick(tooth.fdi)\n : undefined\n }\n onFocus={() => setFocusedId(tooth.fdi)}\n onKeyDown={\n isDrilled\n ? undefined\n : (event) => handleKeyDown(event, tooth.fdi)\n }\n >\n {/* Invisible ≥44px hit target (WCAG 2.5.5). */}\n <rect\n x={-TOOTH_HIT_PAD}\n y={-TOOTH_HIT_PAD}\n width={TOOTH_SLOT_WIDTH + TOOTH_HIT_PAD * 2}\n height={slotHeight + TOOTH_HIT_PAD * 2}\n fill=\"transparent\"\n />\n {/* Photoreal tooth render (side = facial, plan =\n occlusal). The upper/lower view folders are\n pre-oriented, so no mirroring is needed. Decorative —\n the parent <g> carries the accessible name. */}\n <image\n href={imageUrl}\n x={imgX}\n y={imgY}\n width={imgW}\n height={imgH}\n preserveAspectRatio=\"xMidYMid meet\"\n opacity={isMissing ? 0.25 : 1}\n aria-hidden=\"true\"\n />\n {/* Side view: whole-tooth symbol overlays (crown,\n implant, RCT, bridge…) composited on the facial\n tooth. The distinct glyph is the colour-independent\n channel; the group's accessible name names it. */}\n {projection === 'side'\n ? symbolOverlays.map(({ condition, spec }) => (\n <image\n key={condition}\n href={conditionSymbolUrl(\n tooth.meta,\n assetBaseUrl,\n spec,\n )}\n x={imgX}\n y={imgY}\n width={imgW}\n height={imgH}\n preserveAspectRatio=\"xMidYMid meet\"\n aria-hidden=\"true\"\n pointerEvents=\"none\"\n />\n ))\n : null}\n {/* Plan view: per-surface caries / filling overlays —\n the \"Stato dentale\" surface marking. */}\n {projection === 'plan'\n ? surfaceOverlays.map(({ key, url }) => (\n <image\n key={key}\n href={url}\n x={imgX}\n y={imgY}\n width={imgW}\n height={imgH}\n preserveAspectRatio=\"xMidYMid meet\"\n aria-hidden=\"true\"\n pointerEvents=\"none\"\n />\n ))\n : null}\n {/* Plan view: interactive surface-picking zones. Pointer\n clicks mark a surface directly; keyboard users drill\n in (Enter) then pick a zone (arrows), so the zones are\n focusable buttons only while THIS tooth is drilled. */}\n {surfacePicking\n ? toothZones.map((zone) => {\n const surface = zoneSurface(tooth.meta, zone);\n const marked = isSurfaceMarked(tooth.fdi, surface);\n return (\n <path\n key={zone}\n d={zonePath(\n zone,\n { x: imgX, y: imgY, w: imgW, h: imgH },\n hasCenter,\n )}\n data-fdi={tooth.fdi}\n data-zone={zone}\n data-surface={surface}\n data-testid={`tooth-${tooth.fdi}-zone-${zone}`}\n role={isDrilled ? 'button' : undefined}\n tabIndex={\n isDrilled\n ? drilled?.zone === zone\n ? 0\n : -1\n : undefined\n }\n aria-label={\n isDrilled\n ? t('toothScheme.toothLabel', {\n id: labelText,\n anatomy: t(\n `toothScheme.surface.${surface}`,\n ),\n conditionSuffix: '',\n })\n : undefined\n }\n aria-pressed={isDrilled ? marked : undefined}\n strokeWidth=\"var(--focus-ring-width)\"\n className={zoneVariants()}\n onClick={(event) => {\n event.stopPropagation();\n if (!isDrilled) setFocusedId(tooth.fdi);\n toggleSurface(tooth.fdi, surface);\n }}\n onKeyDown={\n isDrilled\n ? (event) =>\n handleSurfaceKeyDown(\n event,\n tooth.fdi,\n zone,\n )\n : undefined\n }\n onFocus={\n isDrilled\n ? () =>\n setDrilled((d) =>\n d &&\n d.fdi === tooth.fdi &&\n d.zone === zone\n ? d\n : { fdi: tooth.fdi, zone },\n )\n : undefined\n }\n />\n );\n })\n : null}\n {/* Side view: surface-finding ring (caries / filled)\n stands in until the plan view marks the surface. */}\n {projection === 'side' && ringColour ? (\n <rect\n x={3}\n y={2}\n width={TOOTH_SLOT_WIDTH - 6}\n height={slotHeight - 4}\n fill=\"none\"\n stroke={ringColour}\n strokeWidth=\"2\"\n // Distinguish caries (solid) from filled (dashed) by\n // line style, not colour alone (WCAG 1.4.1).\n strokeDasharray={\n surfaceCondition === 'filled' ? '4 2' : undefined\n }\n rx=\"6\"\n pointerEvents=\"none\"\n />\n ) : null}\n {/* Missing-tooth X glyph over the faded render. */}\n {isMissing ? (\n <path\n d={`M7 9 L${TOOTH_SLOT_WIDTH - 7} ${slotHeight - 9} M${TOOTH_SLOT_WIDTH - 7} 9 L7 ${slotHeight - 9}`}\n stroke={CONDITION_COLORS.missing}\n strokeWidth=\"2\"\n fill=\"none\"\n pointerEvents=\"none\"\n />\n ) : null}\n {/* Focus ring — drawn as a rect so it tracks the hit\n area. `group` on the parent <g> makes this\n group-focus-visible selector fire when a keyboard\n user focuses the tooth. In forced-colors mode the\n ring falls back to `CanvasText` so it stays visible\n when `var(--ring)` is remapped. */}\n <rect\n x={-TOOTH_HIT_PAD}\n y={-TOOTH_HIT_PAD}\n width={TOOTH_SLOT_WIDTH + TOOTH_HIT_PAD * 2}\n height={slotHeight + TOOTH_HIT_PAD * 2}\n fill=\"none\"\n stroke=\"var(--ring)\"\n strokeWidth=\"var(--focus-ring-width)\"\n className={[\n 'ds:opacity-0',\n 'ds:group-focus-visible:opacity-100',\n 'ds:forced-colors:stroke-[CanvasText]',\n ].join(' ')}\n data-testid={`tooth-${tooth.fdi}-focus-ring`}\n pointerEvents=\"none\"\n rx=\"4\"\n />\n {/* Tooth number label — sits below (upper arch) or above (lower) the crown. */}\n <text\n x={TOOTH_SLOT_WIDTH / 2}\n y={tooth.meta.arch === 'upper' ? slotHeight + 12 : -4}\n textAnchor=\"middle\"\n fontSize=\"10\"\n fill=\"var(--muted-foreground)\"\n className=\"ds:select-none\"\n aria-hidden=\"true\"\n >\n {labelText}\n </text>\n </g>\n </RadixTooltip.Trigger>\n <RadixTooltip.Portal>\n <RadixTooltip.Content\n side=\"top\"\n sideOffset={6}\n className=\"ds:z-[var(--z-tooltip)] ds:rounded-[var(--radius-sm)] ds:bg-[var(--foreground)] ds:text-[var(--background)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:pt-[calc(var(--spacing-xs)/2)] ds:pb-[calc(var(--spacing-xs)/2)] ds:text-[length:var(--font-size-xs)]\"\n >\n {tooltipContent}\n <RadixTooltip.Arrow className=\"ds:fill-[var(--foreground)]\" />\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n </RadixTooltip.Root>\n );\n })}\n </svg>\n\n {/* \"Both\" view: an occlusal companion that shares this chart's data,\n so the side chart (above) and the occlusal chart (here) are both\n interactive — edits in either propagate through `value`/`onChange`. */}\n {showCompanion ? (\n <ToothScheme\n projection=\"plan\"\n dentition={dentition}\n numbering={numbering}\n mode={mode}\n value={chart}\n onChange={commitChart}\n activeCondition={activeCondition}\n assetBaseUrl={assetBaseUrl}\n ariaLabel={`${baseLabel} — ${t('toothScheme.view.occlusal')}`}\n />\n ) : null}\n\n {legend ? <Legend assetBaseUrl={assetBaseUrl} /> : null}\n\n <div\n className={liveRegionVariants()}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"tooth-scheme-live\"\n >\n {announcement}\n </div>\n </div>\n </RadixTooltip.Provider>\n );\n },\n);\n\nToothScheme.displayName = 'ToothScheme';\n\n/* ------------------------------------------------------------------ */\n/* Re-exports */\n/* ------------------------------------------------------------------ */\n\nexport { rootVariants as toothSchemeVariants, PERMANENT_TEETH, PRIMARY_TEETH };\nexport type {\n Dentition,\n FdiId,\n Numbering,\n ToothChart,\n ToothCondition,\n ToothMode,\n ToothState,\n} from './tooth-data';\n"],"names":["FDI_SCHEMA","CONDITION_SCHEMA","SURFACE_SCHEMA","toothSchemeAgent","handle","args","PERMANENT_TEETH","PRIMARY_TEETH","permanentAnatomy","positionInQuadrant","primaryAnatomy","palmerCode","quadrant","position","normalised","permanentUniversal","primaryUniversal","letters","index","buildMeta","fdi","isPrimary","anatomy","arch","side","universal","palmer","FDI_TO_META","acc","FDI_TO_UNIVERSAL","meta","FDI_TO_PALMER","assetFdi","PRIMARY_TOOTH_SCALE","CONDITION_TOKENS","CONDITION_COLORS","CONDITION_SIDE_SYMBOL","conditionSymbolUrl","assetBaseUrl","spec","view","base","SURFACE_ASSET_NAME","CONDITION_PLAN_FOLDER","surfaceSymbolUrl","folder","surface","zonesForTooth","zoneSurface","zone","q","leftIsDistal","r2","n","zonePath","rect","hasCenter","x","y","w","h","x1","y1","p","px","py","cx","cy","ix","iy","ix1","iy1","TOOTH_GAP","TOOTH_ROW_GAP","TOOTH_HIT_PAD","TOOTH_SLOT_WIDTH","TOOTH_SLOT_HEIGHT","toothImageUrl","symbol","projection","layoutTeeth","dentition","slotHeight","ids","upper","lower","id","slot","maxCount","maxRowWidth","positionRow","row","yOffset","rowWidth","startX","i","upperRow","lowerRow","width","height","labelFor","numbering","emptyChart","chartFromConditions","conditions","chart","list","rootVariants","cva","svgVariants","toothGroupVariants","legendVariants","legendItemVariants","liveRegionVariants","zoneVariants","isControlled","props","emptyState","cycleCondition","current","active","condition","nextZone","key","_a","ALL_CONDITIONS","LegendSymbol","isMissing","isSurface","jsxs","jsx","Legend","t","useTranslation","OptionRow","label","value","options","onValueChange","container","Select","ToothScheme","forwardRef","dentitionProp","numberingProp","mode","projectionProp","defaultValue","onChange","onSelect","activeCondition","legendProp","controls","ariaLabel","className","ref","uiDentition","setUiDentition","useState","uiNumbering","setUiNumbering","uiProjection","setUiProjection","uiLegend","setUiLegend","optionsPopoverEl","setOptionsPopoverEl","legend","viewMode","showCompanion","controlsWasOn","useRef","useEffect","internalChart","setInternalChart","layout","useMemo","visibleIds","firstId","focusedId","setFocusedId","announcement","setAnnouncement","svgRef","commitChart","useCallback","next","focusToothById","svg","node","surfacePicking","drilled","setDrilled","focusZone","prevDrilled","isSurfaceMarked","state","announceTooth","c","toggleSurface","cond","prev","hadSurface","hadCond","surfaces","s","drillInto","handleSurfaceKeyDown","event","nz","rootRef","agentHandle","useImperativeHandle","useAgentRegistration","handleKeyDown","order","currentIndex","nextIndex","targetQuadrant","candidate","inQuadrant","other","nextConditions","handleClick","viewBoxWidth","viewBoxHeight","baseLabel","regionLabel","scrollTabIndex","RadixTooltip","Popover","IconButton","Settings","Switch","v","tooth","primaryCondition","anatomyLabel","conditionSuffix","tabIndex","symbolOverlays","entry","surfaceCondition","ringColour","tooltipContent","labelText","imageUrl","surfaceOverlays","imgScale","imgW","imgH","imgX","imgY","isDrilled","toothZones","url","marked","d"],"mappings":";;;;;;;;;;;AAQA,MAAMA,IAAa;AAAA,EACjB,MAAM;AAAA,EACN,aAAa;AACf,GACMC,KAAmB;AAAA,EACvB,MAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ,GACMC,KAAiB;AAAA,EACrB,MAAM,CAAC,UAAU,UAAU,YAAY,UAAU,SAAS;AAC5D,GAEaC,KAAoD;AAAA,EAC/D,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKJ,cAAc,CAAC,QAAQ,aAAa,eAAe,aAAa;AAAA,EAChE,OAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,MAAM,CAACC,MAAWA,EAAO,SAAA;AAAA,IAAS;AAAA,IAEpC,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM,CAACA,MAAW,OAAO,KAAKA,EAAO,UAAU;AAAA,IAAA;AAAA,EACjD;AAAA,EAEF,SAAS;AAAA,IACP,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAIJ,EAAA;AAAA,QAClB,UAAU,CAAC,IAAI;AAAA,MAAA;AAAA,MAEjB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACI,GAAQC,MAAwB;AACvC,QAAAD,EAAO,WAAWC,EAAK,EAAE;AAAA,MAC3B;AAAA,IAAA;AAAA,IAEF,WAAW;AAAA,MACT,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAIL,EAAA;AAAA,QAClB,UAAU,CAAC,IAAI;AAAA,MAAA;AAAA,MAEjB,SAAS;AAAA,MACT,eAAe,EAAE,MAAM,SAAS,OAAOC,GAAA;AAAA,MACvC,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACG,GAAQC,MAAwBD,EAAO,SAASC,EAAK,EAAE;AAAA,IAAA;AAAA,IAElE,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,WAAWJ,GAAA;AAAA,QACzB,UAAU,CAAC,WAAW;AAAA,MAAA;AAAA,MAExB,SAAS;AAAA,MACT,eAAe,EAAE,MAAM,SAAS,OAAOD,EAAA;AAAA,MACvC,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,QAAQ,CAACI,GAAQC,MACfD,EAAO,UAAUC,EAAK,SAAS;AAAA,IAAA;AAAA,IAEnC,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,UACE;AAAA,MACF,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY;AAAA,UACV,IAAIL;AAAA,UACJ,WAAWC;AAAA,UACX,UAAU,EAAE,MAAM,SAAS,OAAOC,GAAA;AAAA,QAAe;AAAA,QAEnD,UAAU,CAAC,MAAM,WAAW;AAAA,MAAA;AAAA,MAE9B,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,QAAQ,CACNE,GACAC,MACG;AACH,QAAAD,EAAO,WAAWC,EAAK,IAAIA,EAAK,WAAWA,EAAK,QAAQ;AAAA,MAC1D;AAAA,IAAA;AAAA,IAEF,gBAAgB;AAAA,MACd,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAIL,GAAY,WAAWC,GAAA;AAAA,QACzC,UAAU,CAAC,MAAM,WAAW;AAAA,MAAA;AAAA,MAE9B,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACG,GAAQC,MAAmD;AAClE,QAAAD,EAAO,cAAcC,EAAK,IAAIA,EAAK,SAAS;AAAA,MAC9C;AAAA,IAAA;AAAA,IAEF,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAIL,EAAA;AAAA,QAClB,UAAU,CAAC,IAAI;AAAA,MAAA;AAAA,MAEjB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACI,GAAQC,MAAwB;AACvC,QAAAD,EAAO,WAAWC,EAAK,EAAE;AAAA,MAC3B;AAAA,IAAA;AAAA,EACF;AAAA,EAEF,UAAU;AAAA,IACR,MAAM,EAAE,MAAM,kBAAkB,OAAO,eAAA;AAAA,IACvC,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,aAAa;AAAA,IAAA;AAAA,IAEf,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aACE;AAAA,IAAA;AAAA,EACJ;AAEJ,GC5FaC,KAA2B;AAAA;AAAA,EAEtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOaC,KAAyB;AAAA;AAAA,EAEpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMA,SAASC,GAAiBC,GAAqC;AAC7D,SAAIA,KAAsB,IAAU,YAChCA,MAAuB,IAAU,WACjCA,KAAsB,IAAU,aAC7B;AACT;AAEA,SAASC,GAAeD,GAAqC;AAC3D,SAAIA,KAAsB,IAAU,YAChCA,MAAuB,IAAU,WAE9B;AACT;AAMA,SAASE,GAAWC,GAAoBC,GAA0B;AAIhE,QAAMC,KAAeF,IAAW,KAAK,IAAK;AAS1C,SAAO,GAPLE,MAAe,IACX,OACAA,MAAe,IACb,OACAA,MAAe,IACb,OACA,IACI,GAAGD,CAAQ;AAC3B;AAeA,SAASE,GAAmBH,GAAoBC,GAA0B;AACxE,UAAQD,GAAA;AAAA,IACN,KAAK;AAEH,aAAO,OAAO,KAAK,IAAIC,EAAS;AAAA,IAClC,KAAK;AAEH,aAAO,OAAO,IAAIA,CAAQ;AAAA,IAC5B,KAAK;AAEH,aAAO,OAAO,MAAM,IAAIA,EAAS;AAAA,IACnC,KAAK;AAEH,aAAO,OAAO,KAAKA,CAAQ;AAAA,IAC7B;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,SAASG,GAAiBJ,GAAoBC,GAA0B;AACtE,QAAMI,IAAU;AAChB,MAAIC,IAAQ;AACZ,UAAQN,GAAA;AAAA,IACN,KAAK;AAEH,MAAAM,IAAQ,KAAK,IAAIL;AACjB;AAAA,IACF,KAAK;AAEH,MAAAK,IAAQ,KAAKL,IAAW;AACxB;AAAA,IACF,KAAK;AAEH,MAAAK,IAAQ,MAAM,IAAIL;AAClB;AAAA,IACF,KAAK;AAEH,MAAAK,IAAQ,MAAML,IAAW;AACzB;AAAA,IACF;AACE,MAAAK,IAAQ;AAAA,EAAA;AAEZ,SAAOA,KAAS,IAAID,EAAQC,CAAK,IAAI;AACvC;AAMA,SAASC,GAAUC,GAAuB;AACxC,QAAMR,IAAW,OAAOQ,EAAI,CAAC,CAAC,GACxBP,IAAW,OAAOO,EAAI,CAAC,CAAC,GACxBC,IAAYT,KAAY,GACxBU,IAAUD,IACZX,GAAeG,CAAQ,IACvBL,GAAiBK,CAAQ,GACvBU,IACJX,MAAa,KAAKA,MAAa,KAAKA,MAAa,KAAKA,MAAa,IAC/D,UACA,SACAY,IACJZ,MAAa,KAAKA,MAAa,KAAKA,MAAa,KAAKA,MAAa,IAC/D,UACA,QACAa,IAAYJ,IACdL,GAAiBJ,GAAUC,CAAQ,IACnCE,GAAmBH,GAAUC,CAAQ,GACnCa,IAASf,GAAWC,GAAUC,CAAQ;AAC5C,SAAO;AAAA,IACL,KAAAO;AAAA,IACA,WAAAK;AAAA,IACA,QAAAC;AAAA,IACA,UAAAd;AAAA,IACA,oBAAoBC;AAAA,IACpB,SAAAS;AAAA,IACA,MAAAC;AAAA,IACA,MAAAC;AAAA,IACA,WAAWH,IAAY,YAAY;AAAA,EAAA;AAEvC;AAEO,MAAMM,IAAwC;AAAA,EACnD,GAAGrB;AAAA,EACH,GAAGC;AACL,EAAE,OAAiC,CAACqB,GAAKR,OACvCQ,EAAIR,CAAG,IAAID,GAAUC,CAAG,GACjBQ,IACN,CAAA,CAAE,GAEQC,KAA0C,OAAO;AAAA,EAC5D,OAAO,QAAQF,CAAW,EAAE,IAAI,CAAC,CAACP,GAAKU,CAAI,MAAM,CAACV,GAAKU,EAAK,SAAS,CAAC;AACxE,GAEaC,KAAuC,OAAO;AAAA,EACzD,OAAO,QAAQJ,CAAW,EAAE,IAAI,CAAC,CAACP,GAAKU,CAAI,MAAM,CAACV,GAAKU,EAAK,MAAM,CAAC;AACrE;AAQO,SAASE,GAASF,GAAwB;AAC/C,SAAIA,EAAK,cAAc,YAAkBA,EAAK,MACvC,GAAGA,EAAK,WAAW,CAAC,GAAGA,EAAK,kBAAkB;AACvD;AAGO,MAAMG,KAAsB,MAWtBC,KAAmD;AAAA,EAC9D,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AACb,GAQaC,KAAmD;AAAA,EAC9D,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AACb,GAkBaC,KAET;AAAA,EACF,SAAS,EAAE,QAAQ,SAAS,SAAS,UAAA;AAAA,EACrC,gBAAgB,EAAE,QAAQ,kBAAkB,SAAS,UAAA;AAAA,EACrD,QAAQ,EAAE,QAAQ,eAAe,SAAS,UAAA;AAAA,EAC1C,WAAW,EAAE,QAAQ,aAAa,SAAS,UAAA;AAAA,EAC3C,SAAS,EAAE,QAAQ,WAAW,SAAS,UAAA;AAAA,EACvC,mBAAmB,EAAE,QAAQ,qBAAqB,SAAS,UAAA;AAAA,EAC3D,MAAM,EAAE,QAAQ,QAAQ,SAAS,UAAA;AAAA,EACjC,WAAW,EAAE,QAAQ,iBAAiB,SAAS,MAAA;AACjD;AAGO,SAASC,GACdP,GACAQ,GACAC,GACQ;AACR,QAAMC,IAAOV,EAAK,SAAS,UAAU,QAAQ,UACvCW,IAAO,GAAGH,CAAY,SAASC,EAAK,MAAM,IAAIC,CAAI;AACxD,MAAID,EAAK,YAAY,UAAW,QAAO,GAAGE,CAAI;AAC9C,QAAMrB,IAAMY,GAASF,CAAI;AACzB,SAAIS,EAAK,YAAY,QAAc,GAAGE,CAAI,IAAIrB,CAAG,eAC1C,GAAGqB,CAAI,IAAIrB,CAAG;AACvB;AAgBO,MAAMsB,KAA8C;AAAA,EACzD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AACX,GAGaC,KAAiE;AAAA,EAC5E,QAAQ;AAAA,EACR,QAAQ;AACV;AAGO,SAASC,GACdd,GACAQ,GACAO,GACAC,GACQ;AACR,QAAMN,IAAOV,EAAK,SAAS,UAAU,QAAQ;AAC7C,SAAO,GAAGQ,CAAY,SAASO,CAAM,IAAIL,CAAI,IAAIR,GAASF,CAAI,CAAC,IAAIY,GAAmBI,CAAO,CAAC;AAChG;AAiBO,SAASC,GAAcjB,GAAgC;AAE5D,SADiBA,EAAK,YAAY,WAAWA,EAAK,YAAY,aAE1D,CAAC,OAAO,UAAU,QAAQ,SAAS,QAAQ,IAC3C,CAAC,OAAO,UAAU,QAAQ,OAAO;AACvC;AAeO,SAASkB,GAAYlB,GAAiBmB,GAA4B;AACvE,MAAIA,MAAS,SAAU,QAAO;AAC9B,MAAIA,MAAS,MAAO,QAAOnB,EAAK,SAAS,UAAU,WAAW;AAC9D,MAAImB,MAAS,SAAU,QAAOnB,EAAK,SAAS,UAAU,YAAY;AAElE,QAAMoB,IAAIpB,EAAK,YAAY,IAAIA,EAAK,WAAWA,EAAK,WAAW,GACzDqB,IAAeD,MAAM,KAAKA,MAAM;AACtC,SAAID,MAAS,SAAeE,IAAe,WAAW,WAC/CA,IAAe,WAAW;AACnC;AAEA,MAAMC,KAAK,CAACC,MAAc,KAAK,MAAMA,IAAI,GAAG,IAAI;AAQzC,SAASC,GACdL,GACAM,GACAC,GACQ;AACR,QAAM,EAAE,GAAAC,GAAG,GAAAC,GAAG,GAAAC,GAAG,GAAAC,MAAML,GACjBM,IAAKJ,IAAIE,GACTG,IAAKJ,IAAIE,GACTG,IAAI,CAACC,GAAYC,MAAe,GAAGb,GAAGY,CAAE,CAAC,IAAIZ,GAAGa,CAAE,CAAC;AACzD,MAAI,CAACT,GAAW;AACd,UAAMU,IAAKT,IAAIE,IAAI,GACbQ,IAAKT,IAAIE,IAAI;AACnB,YAAQX,GAAA;AAAA,MACN,KAAK;AACH,eAAO,KAAKc,EAAEN,GAAGC,CAAC,CAAC,MAAMK,EAAEF,GAAIH,CAAC,CAAC,MAAMK,EAAEG,GAAIC,CAAE,CAAC;AAAA,MAClD,KAAK;AACH,eAAO,KAAKJ,EAAEN,GAAGK,CAAE,CAAC,MAAMC,EAAEF,GAAIC,CAAE,CAAC,MAAMC,EAAEG,GAAIC,CAAE,CAAC;AAAA,MACpD,KAAK;AACH,eAAO,KAAKJ,EAAEN,GAAGC,CAAC,CAAC,MAAMK,EAAEG,GAAIC,CAAE,CAAC,MAAMJ,EAAEN,GAAGK,CAAE,CAAC;AAAA,MAClD,KAAK;AACH,eAAO,KAAKC,EAAEF,GAAIH,CAAC,CAAC,MAAMK,EAAEG,GAAIC,CAAE,CAAC,MAAMJ,EAAEF,GAAIC,CAAE,CAAC;AAAA,MACpD;AACE,eAAO;AAAA,IAAA;AAAA,EAEb;AAEA,QAAMM,IAAKX,IAAIE,IAAI,KACbU,IAAKX,IAAIE,IAAI,KACbU,IAAMb,IAAIE,IAAI,KACdY,IAAMb,IAAIE,IAAI;AACpB,UAAQX,GAAA;AAAA,IACN,KAAK;AACH,aAAO,KAAKc,EAAEK,GAAIC,CAAE,CAAC,MAAMN,EAAEO,GAAKD,CAAE,CAAC,MAAMN,EAAEO,GAAKC,CAAG,CAAC,MAAMR,EAAEK,GAAIG,CAAG,CAAC;AAAA,IACxE,KAAK;AACH,aAAO,KAAKR,EAAEN,GAAGC,CAAC,CAAC,MAAMK,EAAEF,GAAIH,CAAC,CAAC,MAAMK,EAAEO,GAAKD,CAAE,CAAC,MAAMN,EAAEK,GAAIC,CAAE,CAAC;AAAA,IAClE,KAAK;AACH,aAAO,KAAKN,EAAEN,GAAGK,CAAE,CAAC,MAAMC,EAAEF,GAAIC,CAAE,CAAC,MAAMC,EAAEO,GAAKC,CAAG,CAAC,MAAMR,EAAEK,GAAIG,CAAG,CAAC;AAAA,IACtE,KAAK;AACH,aAAO,KAAKR,EAAEN,GAAGC,CAAC,CAAC,MAAMK,EAAEK,GAAIC,CAAE,CAAC,MAAMN,EAAEK,GAAIG,CAAG,CAAC,MAAMR,EAAEN,GAAGK,CAAE,CAAC;AAAA,IAClE,KAAK;AACH,aAAO,KAAKC,EAAEF,GAAIH,CAAC,CAAC,MAAMK,EAAEO,GAAKD,CAAE,CAAC,MAAMN,EAAEO,GAAKC,CAAG,CAAC,MAAMR,EAAEF,GAAIC,CAAE,CAAC;AAAA,IACtE;AACE,aAAO;AAAA,EAAA;AAEb;AAWO,MAAMU,KAAY,GACZC,KAAgB,IAChBC,IAAgB,GAChBC,IAAmB,IAEnBC,KAAoB;AAO1B,SAASC,GACd/C,GACAQ,GACAwC,IAAS,WACTC,IAA8B,QACtB;AACR,QAAMvC,IAAOV,EAAK,SAAS,UAAU,QAAQ;AAC7C,SAAO,GAAGQ,CAAY,IAAIyC,CAAU,IAAID,CAAM,IAAItC,CAAI,IAAIR,GAASF,CAAI,CAAC;AAC1E;AAgBO,SAASkD,GACdC,GACAC,IAAqBN,IAKrB;AACA,QAAMO,IACJF,MAAc,YACV1E,KACA0E,MAAc,UACZ,CAAC,GAAG3E,IAAiB,GAAGC,EAAa,IACrCD,IAGF8E,IAAiB,CAAA,GACjBC,IAAiB,CAAA;AACvB,aAAWC,KAAMH;AAEf,IADaxD,EAAY2D,CAAE,EAClB,SAAS,UAASF,EAAM,KAAKE,CAAE,IACnCD,EAAM,KAAKC,CAAE;AAKpB,QAAMC,IAAOZ,IAAmBH,IAC1BgB,IAAW,KAAK,IAAIJ,EAAM,QAAQC,EAAM,MAAM,GAC9CI,IAAcD,IAAW,IAAIA,IAAWD,IAAOf,KAAY;AAEjE,WAASkB,EAAYC,GAAcC,GAAoC;AACrE,UAAMC,IAAWF,EAAI,SAAS,IAAIA,EAAI,SAASJ,IAAOf,KAAY,GAC5DsB,MAAUL,IAAcI,KAAY;AAC1C,WAAOF,EAAI,IAAI,CAACL,GAAIS,OAAM;AACxB,YAAMjE,KAAOH,EAAY2D,CAAE;AAC3B,aAAO;AAAA,QACL,KAAKA;AAAA,QACL,MAAAxD;AAAA,QACA,GAAGgE,KAASC,KAAIR;AAAA,QAChB,GAAGK;AAAA,MAAA;AAAA,IAEP,CAAC;AAAA,EACH;AAEA,QAAMI,IAAWN,EAAYN,GAAO,CAAC,GAC/Ba,IAAWP,EAAYL,GAAOH,IAAaT,EAAa,GAExDyB,IAAQT,IAAc,IAAIA,IAAcD,IAAWD,GACnDY,IAASjB,IAAa,IAAIT;AAEhC,SAAO,EAAE,OAAO,CAAC,GAAGuB,GAAU,GAAGC,CAAQ,GAAG,OAAAC,GAAO,QAAAC,EAAA;AACrD;AAMO,SAASC,GAASd,GAAWe,GAA8B;AAChE,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAOxE,GAAiByD,CAAE,KAAKA;AAAA,IACjC,KAAK;AACH,aAAOvD,GAAcuD,CAAE,KAAKA;AAAA,IAC9B,KAAK;AAAA,IACL;AACE,aAAOA;AAAA,EAAA;AAEb;AAMO,SAASgB,KAAyB;AACvC,SAAO,CAAA;AACT;AAEO,SAASC,GACdC,GACY;AACZ,QAAMC,IAAoB,CAAA;AAC1B,aAAW,CAACnB,GAAIoB,CAAI,KAAK,OAAO,QAAQF,CAAU;AAChD,IAAI,CAACE,KAAQA,EAAK,WAAW,MAC7BD,EAAMnB,CAAE,IAAI,EAAE,YAAYoB,GAAM,UAAU,GAAC;AAE7C,SAAOD;AACT;AC3eA,MAAME,KAAeC;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAOMC,KAAcD;AAAA,EAClB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAMME,KAAqBF;AAAA,EACzB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMG,KAAiBH;AAAA,EACrB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMI,KAAqBJ;AAAA,EACzB,CAAC,kCAAkC,4BAA4B,EAAE,KAAK,GAAG;AAC3E,GAEMK,KAAqBL,EAAI,CAAC,YAAY,EAAE,KAAK,GAAG,CAAC,GAKjDM,KAAeN;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ;AAMA,SAASO,GAAaC,GAAiD;AACrE,SAAOA,EAAM,UAAU;AACzB;AAEA,SAASC,KAAyB;AAChC,SAAO,EAAE,YAAY,IAAI,UAAU,CAAA,EAAC;AACtC;AAEA,SAASC,GACPC,GACAC,GACkB;AAClB,QAAMd,IAAOa,KAAW,CAAA;AAExB,SAAKC,IAEEd,EAAK,SAASc,CAAM,IACvBd,EAAK,OAAO,CAACe,MAAcA,MAAcD,CAAM,IAC/C,CAAC,GAAGd,GAAMc,CAAM,IAJAd,EAAK,WAAW,IAAI,CAAC,QAAQ,IAAI,CAAA;AAKvD;AAOA,SAASgB,GACPzE,GACA0E,GACAnE,GACa;;AACb,SAAKA,MAmBEoE,IAZgE;AAAA,IACrE,KAAK,EAAE,WAAW,SAAA;AAAA,IAClB,QAAQ,EAAE,SAAS,SAAA;AAAA,IACnB,MAAM,EAAE,YAAY,SAAA;AAAA,IACpB,OAAO,EAAE,WAAW,SAAA;AAAA,IACpB,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,MACX,YAAY;AAAA,IAAA;AAAA,EACd,EAES3E,CAAI,MAAR,gBAAA2E,EAAYD,OAAQ1E,IAlBrB0E,MAAQ,YAAkB,QAC1BA,MAAQ,cAAoB,WAC5BA,MAAQ,cAAoB,SAC5BA,MAAQ,eAAqB,UAC1B1E;AAeX;AAWA,MAAM4E,KAAmC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,SAASC,GAAa;AAAA,EACpB,WAAAL;AAAA,EACA,cAAAnF;AACF,GAGiB;AACf,QAAMR,IAAOH,EAAY,EAAI,GACvBY,IAAOH,GAAsBqF,CAAS,GACtCM,IAAYN,MAAc,WAC1BO,IAAYP,MAAc,YAAYA,MAAc,UAGpD9D,IAAI,KAAK,KACTC,IAAI,KAAK,KACTH,KAAK,KAAKE,KAAK,GACfD,KAAK,KAAKE,KAAK;AACrB,SACE,gBAAAqE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,eAAY;AAAA,MACZ,WAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAMrD,GAAc/C,GAAMQ,CAAY;AAAA,YACtC,GAAAmB;AAAA,YACA,GAAAC;AAAA,YACA,OAAOC;AAAA,YACP,QAAQC;AAAA,YACR,qBAAoB;AAAA,YACpB,SAASmE,IAAY,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,QAE7BxF,IACC,gBAAA2F;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM7F,GAAmBP,GAAMQ,GAAcC,CAAI;AAAA,YACjD,GAAAkB;AAAA,YACA,GAAAC;AAAA,YACA,OAAOC;AAAA,YACP,QAAQC;AAAA,YACR,qBAAoB;AAAA,UAAA;AAAA,QAAA,IAEpB;AAAA,QACHoE,IACC,gBAAAE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,GAAG;AAAA,YACH,GAAG;AAAA,YACH,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAK;AAAA,YACL,QAAQ/F,GAAiBsF,CAAS;AAAA,YAClC,aAAa;AAAA,YACb,iBAAiBA,MAAc,WAAW,QAAQ;AAAA,YAClD,IAAI;AAAA,UAAA;AAAA,QAAA,IAEJ;AAAA,QACHM,IACC,gBAAAG;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,GAAE;AAAA,YACF,QAAQ/F,GAAiB;AAAA,YACzB,aAAa;AAAA,YACb,MAAK;AAAA,UAAA;AAAA,QAAA,IAEL;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGV;AAEA,SAASgG,GAAO,EAAE,cAAA7F,KAAwD;AACxE,QAAM,EAAE,GAAA8F,EAAA,IAAMC,GAAA;AACd,SACE,gBAAAJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,cAAYG,EAAE,yBAAyB;AAAA,MACvC,eAAY;AAAA,MAIZ,WAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAF,EAAC,QAAA,EAAK,WAAU,wDACb,UAAAE,EAAE,yBAAyB,GAC9B;AAAA,QACA,gBAAAF,EAAC,QAAG,WAAWnB,GAAA,GACZ,UAAAc,GAAe,IAAI,CAACJ,MACnB,gBAAAQ;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,WAAWjB,GAAA;AAAA,YACX,kBAAgBS;AAAA,YAChB,eAAa,4BAA4BA,CAAS;AAAA,YAElD,UAAA;AAAA,cAAA,gBAAAS,EAACJ,IAAA,EAAa,WAAAL,GAAsB,cAAAnF,EAAA,CAA4B;AAAA,gCAC/D,QAAA,EAAM,UAAA8F,EAAE,yBAAyBX,CAAS,EAAE,EAAA,CAAE;AAAA,YAAA;AAAA,UAAA;AAAA,UAN1CA;AAAA,QAAA,CAQR,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAMA,SAASa,GAAU;AAAA,EACjB,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,SAAAC;AAAA,EACA,eAAAC;AAAA,EACA,WAAAC;AACF,GAMiB;AACf,SACE,gBAAAV,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAU;AAAA,QAET,UAAAK;AAAA,MAAA;AAAA,IAAA;AAAA,IAEH,gBAAAL;AAAA,MAACU;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAYL;AAAA,QACZ,OAAAC;AAAA,QACA,SAAAC;AAAA,QACA,eAAAC;AAAA,QAGA,WAAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAMO,MAAME,KAAcC;AAAA,EACzB,CACE;AAAA,IACE,IAAAxD;AAAA,IACA,WAAWyD,IAAgB;AAAA,IAC3B,WAAWC,IAAgB;AAAA,IAC3B,MAAAC,IAAO;AAAA,IACP,YAAYC,IAAiB;AAAA,IAC7B,OAAAV;AAAA,IACA,cAAAW;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,YAAA7C;AAAA,IACA,iBAAA8C;AAAA,IACA,cAAAhH,IAAe;AAAA,IACf,QAAQiH,IAAa;AAAA,IACrB,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,WAAAC;AAAA,EAAA,GAEFC,OACG;AACH,UAAM,EAAE,GAAAvB,EAAA,IAAMC,GAAA,GAOR,CAACuB,IAAaC,EAAc,IAAIC,EAAoBf,CAAa,GACjE,CAACgB,IAAaC,EAAc,IAAIF,EAAoBd,CAAa,GACjE,CAACiB,IAAcC,EAAe,IAAIJ,EAAmBZ,CAAc,GACnE,CAACiB,IAAUC,EAAW,IAAIN,EAAkBP,CAAU,GAItD,CAACc,IAAkBC,EAAmB,IAC1CR,EAA6B,IAAI,GAE7B7E,IAAYuE,IAAWI,KAAcb,GACrC1C,IAAYmD,IAAWO,KAAcf,GACrCuB,KAASf,IAAWW,KAAWZ,GAI/BiB,KAAqBhB,IAAWS,KAAef,GAC/CnE,IAAyByF,OAAa,SAAS,SAAS,QACxDC,KAAgBD,OAAa,QAK7BE,KAAgBC,GAAOnB,CAAQ;AACrC,IAAAoB,GAAU,MAAM;AACd,MAAIpB,KAAY,CAACkB,GAAc,YAC7Bb,GAAed,CAAa,GAC5BiB,GAAehB,CAAa,GAC5BkB,GAAgBhB,CAAc,GAC9BkB,GAAYb,CAAU,IAExBmB,GAAc,UAAUlB;AAAA,IAC1B,GAAG,CAACA,GAAUT,GAAeC,GAAeE,GAAgBK,CAAU,CAAC;AAGvE,UAAM,CAACsB,IAAeC,EAAgB,IAAIhB,EAAqB,MACzDtB,MAAU,SAAkBA,IAC5BW,MAAiB,SAAkBA,IACnC3C,IAAmBD,GAAoBC,CAAU,IAC9C,CAAA,CACR,GAEKC,IAAoBU,GAAa,EAAE,OAAAqB,EAAA,CAAO,IAC3CA,IACDqC;AAGJ,IAAAD,GAAU,MAAM;AACd,MAAIzD,GAAa,EAAE,OAAAqB,EAAA,CAAO,KACtBhC,MAAe,UACnBsE,GAAiBvE,GAAoBC,CAAU,CAAC;AAAA,IAGlD,GAAG,CAACA,GAAYgC,CAAK,CAAC;AAGtB,UAAMtD,IAAaH,MAAe,SAAS,KAAKH,IAG1CmG,IAASC;AAAA,MACb,MAAMhG,GAAYC,GAAWC,CAAU;AAAA,MACvC,CAACD,GAAWC,CAAU;AAAA,IAAA,GAElB+F,IAAaD,GAAQ,MAAMD,EAAO,MAAM,IAAI,CAAC3C,MAAMA,EAAE,GAAG,GAAG,CAAC2C,CAAM,CAAC,GAGnEG,KAA6BD,EAAW,CAAC,GACzC,CAACE,IAAWC,CAAY,IAAItB,EAA4BoB,EAAO;AACrE,IAAAN,GAAU,MAAM;AACd,OAAI,CAACO,MAAa,CAACF,EAAW,SAASE,EAAS,MAC9CC,EAAaF,EAAO;AAAA,IAExB,GAAG,CAACA,IAASC,IAAWF,CAAU,CAAC;AAGnC,UAAM,CAACI,IAAcC,CAAe,IAAIxB,EAAiB,EAAE,GAErDyB,KAASZ,GAAsB,IAAI,GAEnCa,IAAcC;AAAA,MAClB,CAACC,MAAqB;AACpB,QAAKvE,GAAa,EAAE,OAAAqB,EAAA,CAAO,KACzBsC,GAAiBY,CAAI,GAEvBtC,KAAA,QAAAA,EAAWsC;AAAA,MACb;AAAA,MACA,CAACtC,GAAUZ,CAAK;AAAA,IAAA,GAGZmD,IAAiBF,EAAY,CAACnG,MAAc;AAChD,YAAMsG,IAAML,GAAO;AACnB,UAAI,CAACK,EAAK;AACV,YAAMC,IAAOD,EAAI,cAA2B,eAAetG,CAAE,IAAI;AACjE,MAAIuG,MACFA,EAAK,MAAA,GACLT,EAAa9F,CAAE;AAAA,IAEnB,GAAG,CAAA,CAAE,GAQCwG,IACJ/G,MAAe,UACfkE,MAAS,kBACRK,MAAoB,YAAYA,MAAoB,WAIjD,CAACyC,GAASC,EAAU,IAAIlC,EAGpB,IAAI;AAKd,IAAAc,GAAU,MAAM;AACd,OAAI,CAACkB,KAAmBC,KAAW,CAACd,EAAW,SAASc,EAAQ,GAAG,MACjEC,GAAW,IAAI;AAAA,IAEnB,GAAG,CAACF,GAAgBC,GAASd,CAAU,CAAC;AAExC,UAAMgB,KAAYR,EAAY,CAACrK,GAAY6B,MAAsB;;AAC/D,YAAM4I,KAAOjE,IAAA2D,GAAO,YAAP,gBAAA3D,EAAgB;AAAA,QAC3B,kBAAkBxG,CAAG,iBAAiB6B,CAAI;AAAA;AAE5C,MAAA4I,KAAA,QAAAA,EAAM;AAAA,IACR,GAAG,CAAA,CAAE,GAICK,KAAcvB,GAAiD,IAAI;AACzE,IAAAC,GAAU,MAAM;AACd,MAAImB,IACFE,GAAUF,EAAQ,KAAKA,EAAQ,IAAI,IAC1BG,GAAY,WACrBP,EAAeO,GAAY,QAAQ,GAAG,GAExCA,GAAY,UAAUH;AAAA,IACxB,GAAG,CAACA,GAASE,IAAWN,CAAc,CAAC;AAEvC,UAAMQ,KAAkBV;AAAA,MACtB,CAACrK,GAAY0B,MAA8B;AACzC,cAAMsJ,IAAQ3F,EAAMrF,CAAG;AACvB,eAAO,GACLgL,KACAA,EAAM,SAAS,SAAStJ,CAAO,KAC/BsJ,EAAM,WAAW,SAAS9C,CAAiC;AAAA,MAE/D;AAAA,MACA,CAAC7C,GAAO6C,CAAe;AAAA,IAAA,GAGnB+C,KAAgBZ;AAAA,MACpB,CAACrK,GAAYgL,MAAkC;AAC7C,QAAIA,KAASA,EAAM,WAAW,SAAS,IACrCd;AAAA,UACElD,EAAE,wBAAwB;AAAA,YACxB,IAAIhH;AAAA,YACJ,YAAYgL,EAAM,WACf,IAAI,CAACE,MAAMlE,EAAE,yBAAyBkE,CAAC,EAAE,CAAC,EAC1C,KAAK,IAAI;AAAA,UAAA,CACb;AAAA,QAAA,IAGHhB,EAAgBlD,EAAE,0BAA0B,EAAE,IAAIhH,EAAA,CAAK,CAAC;AAAA,MAE5D;AAAA,MACA,CAACgH,CAAC;AAAA,IAAA,GAGEmE,KAAgBd;AAAA,MACpB,CAACrK,GAAY0B,MAAqB;AAChC,YAAI,CAACgJ,EAAgB;AACrB,cAAMU,IAAOlD,GACPmD,IAAOhG,EAAMrF,CAAG,KAAKiG,GAAA,GACrBqF,IAAaD,EAAK,SAAS,SAAS3J,CAAO,GAC3C6J,IAAUF,EAAK,WAAW,SAASD,CAAI;AAC7C,YAAII,GACApG;AACJ,QAAIkG,KAAcC,KAChBC,IAAWH,EAAK,SAAS,OAAO,CAACI,MAAMA,MAAM/J,CAAO,GACpD0D,IACEoG,EAAS,WAAW,IAChBH,EAAK,WAAW,OAAO,CAACH,MAAMA,MAAME,CAAI,IACxCC,EAAK,eAEXG,IAAWF,IAAaD,EAAK,WAAW,CAAC,GAAGA,EAAK,UAAU3J,CAAO,GAClE0D,IAAamG,IAAUF,EAAK,aAAa,CAAC,GAAGA,EAAK,YAAYD,CAAI;AAEpE,cAAMd,IAAmB,EAAE,GAAGjF,EAAA;AAC9B,QAAID,EAAW,WAAW,KAAKoG,EAAS,WAAW,IACjD,OAAOlB,EAAKtK,CAAG,IAEfsK,EAAKtK,CAAG,IAAI,EAAE,GAAGqL,GAAM,YAAAjG,GAAY,UAAAoG,EAAA,GAErCpB,EAAYE,CAAI,GAChBW,GAAcjL,GAAKsK,EAAKtK,CAAG,CAAC,GAC5BiI,KAAA,QAAAA,EAAWjI;AAAA,MACb;AAAA,MACA;AAAA,QACE0K;AAAA,QACAxC;AAAA,QACA7C;AAAA,QACA+E;AAAA,QACAa;AAAA,QACAhD;AAAA,MAAA;AAAA,IACF,GAGIyD,KAAYrB,EAAY,CAACrK,MAAe;AAC5C,YAAMU,IAAOH,EAAYP,CAAG;AAC5B,MAAKU,MACLsJ,EAAahK,CAAG,GAChB4K,GAAW,EAAE,KAAA5K,GAAK,MAAM2B,GAAcjB,CAAI,EAAE,CAAC,GAAG;AAAA,IAClD,GAAG,CAAA,CAAE,GAECiL,KAAuBtB;AAAA,MAC3B,CAACuB,GAAsC5L,GAAY6B,MAAsB;AACvE,cAAMnB,IAAOH,EAAYP,CAAG;AAC5B,YAAKU;AACL,kBAAQkL,EAAM,KAAA;AAAA,YACZ,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK,cAAc;AACjB,cAAAA,EAAM,eAAA,GACNA,EAAM,gBAAA;AACN,oBAAMxJ,IAAYT,GAAcjB,CAAI,EAAE,SAAS,QAAQ,GACjDmL,IAAKvF,GAASzE,GAAM+J,EAAM,KAAKxJ,CAAS;AAC9C,cAAIyJ,MAAOhK,KAAM+I,GAAW,EAAE,KAAA5K,GAAK,MAAM6L,GAAI;AAC7C;AAAA,YACF;AAAA,YACA,KAAK;AAAA,YACL,KAAK,SAAS;AACZ,cAAAD,EAAM,eAAA,GACNA,EAAM,gBAAA,GACNT,GAAcnL,GAAK4B,GAAYlB,GAAMmB,CAAI,CAAC;AAC1C;AAAA,YACF;AAAA,YACA,KAAK,UAAU;AACb,cAAA+J,EAAM,eAAA,GACNA,EAAM,gBAAA,GACNhB,GAAW,IAAI;AACf;AAAA,YACF;AAAA,YACA;AACE;AAAA,UAAA;AAAA,MAEN;AAAA,MACA,CAACO,EAAa;AAAA,IAAA,GAGVW,KAAUvC,GAAuB,IAAI,GAErCwC,KAAcnC;AAAA,MAClB,OAAO;AAAA,QACL,YAAY,CAAC1F,MAAc;AACzB,UAAAqG,EAAerG,CAAE;AAAA,QACnB;AAAA,QACA,UAAU,MAAMmB;AAAA,QAChB,UAAU,CAACnB,MAAAA;;AAAc,mBAAAsC,IAAAnB,EAAMnB,CAAE,MAAR,gBAAAsC,EAAW,eAAc,CAAA;AAAA;AAAA,QAClD,WAAW,CAACH,MACV,OAAO,QAAQhB,CAAK,EACjB,OAAO,CAAC,GAAG2F,CAAK,MAAMA,EAAM,WAAW,SAAS3E,CAAS,CAAC,EAC1D,IAAI,CAAC,CAACrG,CAAG,MAAMA,CAAG;AAAA,QACvB,YAAY,CACVkE,GACAmC,GACAmF,MACG;AACH,gBAAMH,IAAOhG,EAAMnB,CAAE,KAAK+B,GAAA;AAC1B,cAAIoF,EAAK,WAAW,SAAShF,CAAS,KAAK,CAACmF,EAAU;AACtD,gBAAMlB,IAAmB;AAAA,YACvB,GAAGjF;AAAA,YACH,CAACnB,CAAE,GAAG;AAAA,cACJ,GAAGmH;AAAA,cACH,YAAYA,EAAK,WAAW,SAAShF,CAAS,IAC1CgF,EAAK,aACL,CAAC,GAAGA,EAAK,YAAYhF,CAAS;AAAA,cAClC,UAAUmF,KAAYH,EAAK;AAAA,YAAA;AAAA,UAC7B;AAEF,UAAAjB,EAAYE,CAAI;AAAA,QAClB;AAAA,QACA,eAAe,CAACpG,GAAWmC,MAA8B;AACvD,gBAAMgF,IAAOhG,EAAMnB,CAAE;AACrB,cAAI,CAACmH,KAAQ,CAACA,EAAK,WAAW,SAAShF,CAAS,EAAG;AACnD,gBAAMjB,IAAaiG,EAAK,WAAW,OAAO,CAACH,MAAMA,MAAM7E,CAAS,GAC1DiE,IAAmB,EAAE,GAAGjF,EAAA;AAC9B,UAAID,EAAW,WAAW,IACxB,OAAOkF,EAAKpG,CAAE,IAEdoG,EAAKpG,CAAE,IAAI,EAAE,GAAGmH,GAAM,YAAAjG,EAAAA,GAExBgF,EAAYE,CAAI;AAAA,QAClB;AAAA,QACA,YAAY,CAACpG,MAAc;AACzB,cAAI,CAACmB,EAAMnB,CAAE,EAAG;AAChB,gBAAMoG,IAAmB,EAAE,GAAGjF,EAAA;AAC9B,iBAAOiF,EAAKpG,CAAE,GACdkG,EAAYE,CAAI;AAAA,QAClB;AAAA,MAAA;AAAA,MAEF,CAACjF,GAAO+E,GAAaG,CAAc;AAAA,IAAA;AAErC,IAAAyB,GAAoBzD,IAAK,MAAMwD,IAAa,CAACA,EAAW,CAAC,GACzDE,GAAqBlN,IAAkBgN,IAAa7H,CAAE;AAMtD,UAAMgI,KAAgB7B;AAAA,MACpB,CAACuB,GAAmC1H,MAAc;;AAChD,YAAI2D,MAAS,cAAe;AAC5B,cAAMnH,IAAOH,EAAY2D,CAAE;AAC3B,YAAI,CAACxD,EAAM;AAGX,cAAMyL,IAAQtC,GACRuC,IAAeD,EAAM,QAAQjI,CAAE;AAErC,gBAAQ0H,EAAM,KAAA;AAAA,UACZ,KAAK,cAAc;AACjB,YAAAA,EAAM,eAAA;AACN,kBAAMS,IAAY,KAAK,IAAIF,EAAM,SAAS,GAAGC,IAAe,CAAC;AAC7D,YAAA7B,EAAe4B,EAAME,CAAS,CAAC;AAC/B;AAAA,UACF;AAAA,UACA,KAAK,aAAa;AAChB,YAAAT,EAAM,eAAA;AACN,kBAAMS,IAAY,KAAK,IAAI,GAAGD,IAAe,CAAC;AAC9C,YAAA7B,EAAe4B,EAAME,CAAS,CAAC;AAC/B;AAAA,UACF;AAAA,UACA,KAAK;AAAA,UACL,KAAK,aAAa;AAChB,YAAAT,EAAM,eAAA;AAaN,kBAAMU,IAVsC;AAAA,cAC1C,GAAG;AAAA,cACH,GAAG;AAAA,cACH,GAAG;AAAA,cACH,GAAG;AAAA,cACH,GAAG;AAAA,cACH,GAAG;AAAA,cACH,GAAG;AAAA,cACH,GAAG;AAAA,YAAA,EAE8B5L,EAAK,QAAQ;AAChD,gBAAI,CAAC4L,EAAgB;AACrB,kBAAMC,IAAY,GAAGD,CAAc,GAAG5L,EAAK,kBAAkB;AAC7D,YAAIyL,EAAM,SAASI,CAAS,KAC1BhC,EAAegC,CAAS;AAE1B;AAAA,UACF;AAAA,UACA,KAAK,QAAQ;AACX,YAAAX,EAAM,eAAA;AAEN,kBAAMY,IAAaL,EAAM;AAAA,cACvB,CAACM,MAAUlM,EAAYkM,CAAK,EAAE,aAAa/L,EAAK;AAAA,YAAA;AAElD,YAAI8L,EAAW,SAAS,KACtBjC,EAAeiC,EAAW,CAAC,CAAC;AAE9B;AAAA,UACF;AAAA,UACA,KAAK,OAAO;AACV,YAAAZ,EAAM,eAAA;AACN,kBAAMY,IAAaL,EAAM;AAAA,cACvB,CAACM,MAAUlM,EAAYkM,CAAK,EAAE,aAAa/L,EAAK;AAAA,YAAA;AAElD,YAAI8L,EAAW,SAAS,KACtBjC,EAAeiC,EAAWA,EAAW,SAAS,CAAC,CAAC;AAElD;AAAA,UACF;AAAA,UACA,KAAK;AAAA,UACL,KAAK,SAAS;AAIZ,gBAHAZ,EAAM,eAAA,GAGFlB,GAAgB;AAClB,cAAAgB,GAAUxH,CAAE;AACZ;AAAA,YACF;AACA,kBAAMmH,KAAO7E,IAAAnB,EAAMnB,CAAE,MAAR,gBAAAsC,EAAW,YAClBkG,IAAiBxG,GAAemF,GAAMnD,CAAe,GACrDoC,IAAmB,EAAE,GAAGjF,EAAA;AAC9B,YAAIqH,EAAe,WAAW,KAC5B,OAAOpC,EAAKpG,CAAE,GACdgG,EAAgBlD,EAAE,0BAA0B,EAAE,IAAA9C,EAAAA,CAAI,CAAC,MAEnDoG,EAAKpG,CAAE,IAAI;AAAA,cACT,GAAImB,EAAMnB,CAAE,KAAK+B,GAAA;AAAA,cACjB,YAAYyG;AAAA,YAAA,GAEdxC;AAAA,cACElD,EAAE,wBAAwB;AAAA,gBACxB,IAAA9C;AAAAA,gBACA,YAAYwI,EACT,IAAI,CAACxB,MAAMlE,EAAE,yBAAyBkE,CAAC,EAAE,CAAC,EAC1C,KAAK,IAAI;AAAA,cAAA,CACb;AAAA,YAAA,IAGLd,EAAYE,CAAI,GAChBrC,KAAA,QAAAA,EAAW/D;AACX;AAAA,UACF;AAAA,UACA;AACE;AAAA,QAAA;AAAA,MAEN;AAAA,MACA;AAAA,QACEgE;AAAA,QACA7C;AAAA,QACA+E;AAAA,QACAsB;AAAA,QACAnB;AAAA,QACA1C;AAAA,QACAI;AAAA,QACAyC;AAAA,QACA1D;AAAA,QACA6C;AAAA,MAAA;AAAA,IACF,GAGI8C,KAActC;AAAA,MAClB,CAACnG,MAAc;;AACb,YAAI2D,MAAS,cAAe;AAC5B,QAAAmC,EAAa9F,CAAE;AACf,cAAMmH,KAAO7E,IAAAnB,EAAMnB,CAAE,MAAR,gBAAAsC,EAAW,YAClBkG,IAAiBxG,GAAemF,GAAMnD,CAAe,GACrDoC,IAAmB,EAAE,GAAGjF,EAAA;AAC9B,QAAIqH,EAAe,WAAW,KAC5B,OAAOpC,EAAKpG,CAAE,GACdgG,EAAgBlD,EAAE,0BAA0B,EAAE,IAAA9C,EAAAA,CAAI,CAAC,MAEnDoG,EAAKpG,CAAE,IAAI;AAAA,UACT,GAAImB,EAAMnB,CAAE,KAAK+B,GAAA;AAAA,UACjB,YAAYyG;AAAA,QAAA,GAEdxC;AAAA,UACElD,EAAE,wBAAwB;AAAA,YACxB,IAAA9C;AAAAA,YACA,YAAYwI,EACT,IAAI,CAACxB,MAAMlE,EAAE,yBAAyBkE,CAAC,EAAE,CAAC,EAC1C,KAAK,IAAI;AAAA,UAAA,CACb;AAAA,QAAA,IAGLd,EAAYE,CAAI,GAChBrC,KAAA,QAAAA,EAAW/D;AAAAA,MACb;AAAA,MACA,CAACgE,GAAiB7C,GAAO+E,GAAavC,GAAMI,GAAUjB,CAAC;AAAA,IAAA,GAOnD4F,KAAejD,EAAO,QAAQ,GAC9BkD,KAAgBlD,EAAO,SAAS,GAEhCmD,KAAYzE,KAAarB,EAAE,uBAAuB,GAGlD+F,KAAc1D,KAChB,GAAGyD,EAAS,MAAM9F,EAAE,uBAAuB,CAAC,KAC5C8F,IAOEE,KAAiBnF,MAAS,gBAAgB,SAAY;AAE5D,WACE,gBAAAf,EAACmG,EAAa,UAAb,EAAsB,eAAe,KACpC,UAAA,gBAAApG;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKiF;AAAA,QACL,MAAK;AAAA,QACL,cAAYiB;AAAA,QACZ,UAAUC;AAAA,QACV,WAAW,CAACzH,GAAA,GAAgB+C,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAC/D,kBAAe;AAAA,QACf,qBAAmBpE;AAAA,QACnB,eAAY;AAAA,QACZ,kBAAgBL;AAAA,QAChB,kBAAgBoB;AAAA,QAChB,aAAW4C;AAAA,QACX,mBAAiBlE;AAAA,QACjB,kBAAgByF;AAAA,QAIf,UAAA;AAAA,UAAAhB,IACC,gBAAAtB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAY;AAAA,cAEZ,UAAA,gBAAAD,EAACqG,GAAQ,MAAR,EACC,UAAA;AAAA,gBAAA,gBAAApG,EAACoG,GAAQ,SAAR,EAAgB,SAAO,IACtB,UAAA,gBAAApG;AAAA,kBAACqG;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,QAAO;AAAA,oBACP,MAAM,gBAAArG,EAACsG,IAAA,EAAS,eAAY,OAAA,CAAO;AAAA,oBACnC,cAAYpG,EAAE,2BAA2B;AAAA,oBACzC,SAASA,EAAE,2BAA2B;AAAA,kBAAA;AAAA,gBAAA,GAE1C;AAAA,gBACA,gBAAAF;AAAA,kBAACoG,GAAQ;AAAA,kBAAR;AAAA,oBACC,KAAKhE;AAAA,oBACL,OAAM;AAAA,oBACN,MAAK;AAAA,oBACL,cAAYlC,EAAE,2BAA2B;AAAA,oBAEzC,UAAA,gBAAAH,EAAC,OAAA,EAAI,WAAU,8FAGb,UAAA;AAAA,sBAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,0HACb,UAAA,gBAAAA;AAAA,wBAACuG;AAAA,wBAAA;AAAA,0BACC,OAAOrG,EAAE,4BAA4B;AAAA,0BACrC,WAAU;AAAA,0BACV,SAASmC;AAAA,0BACT,iBAAiBH;AAAA,wBAAA;AAAA,sBAAA,GAErB;AAAA,sBACA,gBAAAlC;AAAA,wBAACI;AAAA,wBAAA;AAAA,0BACC,WAAW+B;AAAA,0BACX,OAAOjC,EAAE,+BAA+B;AAAA,0BACxC,OAAOnD;AAAA,0BACP,eAAe,CAACyJ,MAAM7E,GAAe6E,CAAc;AAAA,0BACnD,SAAS;AAAA,4BACP;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOtG,EAAE,iCAAiC;AAAA,4BAAA;AAAA,4BAE5C;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOA,EAAE,+BAA+B;AAAA,4BAAA;AAAA,4BAE1C;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOA,EAAE,6BAA6B;AAAA,4BAAA;AAAA,0BACxC;AAAA,wBACF;AAAA,sBAAA;AAAA,sBAEF,gBAAAF;AAAA,wBAACI;AAAA,wBAAA;AAAA,0BACC,WAAW+B;AAAA,0BACX,OAAOjC,EAAE,+BAA+B;AAAA,0BACxC,OAAO/B;AAAA,0BACP,eAAe,CAACqI,MAAM1E,GAAe0E,CAAc;AAAA,0BACnD,SAAS;AAAA,4BACP;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOtG,EAAE,2BAA2B;AAAA,4BAAA;AAAA,4BAEtC;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOA,EAAE,iCAAiC;AAAA,4BAAA;AAAA,4BAE5C;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOA,EAAE,8BAA8B;AAAA,4BAAA;AAAA,0BACzC;AAAA,wBACF;AAAA,sBAAA;AAAA,sBAEF,gBAAAF;AAAA,wBAACI;AAAA,wBAAA;AAAA,0BACC,WAAW+B;AAAA,0BACX,OAAOjC,EAAE,0BAA0B;AAAA,0BACnC,OAAOoC;AAAA,0BACP,eAAe,CAACkE,MAAMxE,GAAgBwE,CAAa;AAAA,0BACnD,SAAS;AAAA,4BACP;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOtG,EAAE,uBAAuB;AAAA,4BAAA;AAAA,4BAElC;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOA,EAAE,2BAA2B;AAAA,4BAAA;AAAA,4BAEtC;AAAA,8BACE,OAAO;AAAA,8BACP,OAAOA,EAAE,uBAAuB;AAAA,4BAAA;AAAA,0BAClC;AAAA,wBACF;AAAA,sBAAA;AAAA,oBACF,EAAA,CACF;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACF,EAAA,CACF;AAAA,YAAA;AAAA,UAAA,IAEA;AAAA,UACJ,gBAAAF;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKqD;AAAA,cACL,SAAS,OAAOyC,EAAY,IAAIC,EAAa;AAAA,cAC7C,OAAOD;AAAA,cACP,QAAQC;AAAA,cACR,WAAWpH,GAAA;AAAA,cACX,MAAK;AAAA,cACL,cAAYsH;AAAA,cAIZ,WAAU;AAAA,cACV,eAAY;AAAA,cACZ,OAAM;AAAA,cAEL,UAAApD,EAAO,MAAM,IAAI,CAAC4D,MAAU;;AAC3B,sBAAMvC,IAAQ3F,EAAMkI,EAAM,GAAG,GACvBC,KACJhH,KAAAwE,KAAA,gBAAAA,EAAO,eAAP,gBAAAxE,GAAoB,IAEhBiH,IAAezG;AAAA,kBACnB,uBAAuBuG,EAAM,KAAK,OAAO;AAAA,gBAAA,GAErCG,IAAkBF,IACpB,KAAKxG,EAAE,yBAAyBwG,CAAgB,EAAE,CAAC,KACnD,IACErG,IAAQH,EAAE,0BAA0B;AAAA,kBACxC,IAAIhC,GAASuI,EAAM,KAAKtI,CAAS;AAAA,kBACjC,SAASwI;AAAA,kBACT,iBAAAC;AAAA,gBAAA,CACD,GAEKC,IACJ9F,MAAS,gBACL8C,IACE,KACA4C,EAAM,QAAQxD,KACZ,IACA,KACJ,QAEA3E,KAAa4F,KAAA,gBAAAA,EAAO,eAAc,CAAA,GAClCrE,IAAYvB,EAAW,SAAS,SAAS,GAGzCwI,IAAiBxI,EACpB,IAAI,CAACiB,OAAe;AAAA,kBACnB,WAAAA;AAAA,kBACA,MAAMrF,GAAsBqF,CAAS;AAAA,gBAAA,EACrC,EACD;AAAA,kBACC,CACEwH,MAIG,EAAQA,EAAM;AAAA,gBAAI,GAIrBC,KAAmB1I,EAAW;AAAA,kBAClC,CAACiB,MACCA,MAAc,aAAa,CAACrF,GAAsBqF,CAAS;AAAA,gBAAA,GAEzD0H,KAAaD,KACf/M,GAAiB+M,EAAgB,IACjC,QAEEE,KAAiBR,IACnB,GAAGC,CAAY,MAAMzG,EAAE,yBAAyBwG,CAAgB,EAAE,CAAC,KACnEC,GAEEQ,KAAYjJ,GAASuI,EAAM,KAAKtI,CAAS,GACzCiJ,KAAWzK;AAAA,kBACf8J,EAAM;AAAA,kBACNrM;AAAA,kBACA;AAAA,kBACAyC;AAAA,gBAAA,GAIIwK,KACJxK,MAAe,SACXyB,EAAW,QAAQ,CAACiB,MAAc;AAChC,wBAAM5E,IAASF,GAAsB8E,CAAS;AAC9C,yBAAK5E,MACGuJ,KAAA,gBAAAA,EAAO,aAAY,CAAA,GAAI,IAAI,CAACtJ,QAAa;AAAA,oBAC/C,KAAK,GAAG2E,CAAS,IAAI3E,EAAO;AAAA,oBAC5B,KAAKF;AAAA,sBACH+L,EAAM;AAAA,sBACNrM;AAAA,sBACAO;AAAA,sBACAC;AAAA,oBAAA;AAAA,kBACF,EACA,IATkB,CAAA;AAAA,gBAUtB,CAAC,IACD,CAAA,GAKA0M,MACHb,EAAM,KAAK,cAAc,YAAY1M,KAAsB,KAC5D,KACIwN,KAAO9K,IAAmB6K,IAC1BE,KAAOxK,IAAasK,IACpBG,MAAQhL,IAAmB8K,MAAQ,GACnCG,MAAQ1K,IAAawK,MAAQ,GAK7BG,IAAY/D,MAAkBC,KAAA,gBAAAA,EAAS,SAAQ4C,EAAM,KACrDmB,KAAahE,IACf/I,GAAc4L,EAAM,IAAI,IACxB,CAAA,GACEnL,KAAYsM,GAAW,SAAS,QAAQ;AAE9C,uBACE,gBAAA7H,EAACoG,EAAa,MAAb,EACC,UAAA;AAAA,kBAAA,gBAAAnG,EAACmG,EAAa,SAAb,EAAqB,SAAO,IAC3B,UAAA,gBAAApG;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,YAAU0G,EAAM;AAAA,sBAChB,gBAAcA,EAAM,KAAK;AAAA,sBACzB,aAAWA,EAAM,KAAK;AAAA,sBACtB,aAAWA,EAAM,KAAK;AAAA,sBACtB,iBAAeA,EAAM,KAAK;AAAA,sBAC1B,kBAAgBC,KAAoB;AAAA,sBACpC,eAAa,SAASD,EAAM,GAAG;AAAA,sBAC/B,WAAW,aAAaA,EAAM,CAAC,KAAKA,EAAM,CAAC;AAAA,sBAC3C,UAAAI;AAAA,sBAOA,MACEc,IACI,UACA5G,MAAS,gBACP,WACA;AAAA,sBAER,cAAYV;AAAA,sBACZ,gBACEsH,IACI,SACA5G,MAAS,gBACP2F,MAAqB,SACrB;AAAA,sBAER,WAAW9H,GAAA;AAAA,sBACX,SACE+I,IACI,SACA5G,MAAS,gBACP6C,IACE,MAAMgB,GAAU6B,EAAM,GAAG,IACzB,MAAMZ,GAAYY,EAAM,GAAG,IAC7B;AAAA,sBAER,SAAS,MAAMvD,EAAauD,EAAM,GAAG;AAAA,sBACrC,WACEkB,IACI,SACA,CAAC7C,MAAUM,GAAcN,GAAO2B,EAAM,GAAG;AAAA,sBAI/C,UAAA;AAAA,wBAAA,gBAAAzG;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,GAAG,CAACxD;AAAA,4BACJ,GAAG,CAACA;AAAA,4BACJ,OAAOC,IAAmBD,IAAgB;AAAA,4BAC1C,QAAQQ,IAAaR,IAAgB;AAAA,4BACrC,MAAK;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAMP,gBAAAwD;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,MAAMoH;AAAA,4BACN,GAAGK;AAAA,4BACH,GAAGC;AAAA,4BACH,OAAOH;AAAA,4BACP,QAAQC;AAAA,4BACR,qBAAoB;AAAA,4BACpB,SAAS3H,IAAY,OAAO;AAAA,4BAC5B,eAAY;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAMbhD,MAAe,SACZiK,EAAe,IAAI,CAAC,EAAE,WAAAvH,GAAW,MAAAlF,QAC/B,gBAAA2F;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BAEC,MAAM7F;AAAA,8BACJsM,EAAM;AAAA,8BACNrM;AAAA,8BACAC;AAAA,4BAAA;AAAA,4BAEF,GAAGoN;AAAA,4BACH,GAAGC;AAAA,4BACH,OAAOH;AAAA,4BACP,QAAQC;AAAA,4BACR,qBAAoB;AAAA,4BACpB,eAAY;AAAA,4BACZ,eAAc;AAAA,0BAAA;AAAA,0BAZTjI;AAAA,wBAAA,CAcR,IACD;AAAA,wBAGH1C,MAAe,SACZwK,GAAgB,IAAI,CAAC,EAAE,KAAA5H,GAAK,KAAAoI,QAC1B,gBAAA7H;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BAEC,MAAM6H;AAAA,4BACN,GAAGJ;AAAA,4BACH,GAAGC;AAAA,4BACH,OAAOH;AAAA,4BACP,QAAQC;AAAA,4BACR,qBAAoB;AAAA,4BACpB,eAAY;AAAA,4BACZ,eAAc;AAAA,0BAAA;AAAA,0BART/H;AAAA,wBAAA,CAUR,IACD;AAAA,wBAKHmE,IACGgE,GAAW,IAAI,CAAC7M,MAAS;AACvB,gCAAMH,IAAUE,GAAY2L,EAAM,MAAM1L,CAAI,GACtC+M,KAAS7D,GAAgBwC,EAAM,KAAK7L,CAAO;AACjD,iCACE,gBAAAoF;AAAA,4BAAC;AAAA,4BAAA;AAAA,8BAEC,GAAG5E;AAAA,gCACDL;AAAA,gCACA,EAAE,GAAG0M,IAAM,GAAGC,IAAM,GAAGH,IAAM,GAAGC,GAAA;AAAA,gCAChClM;AAAA,8BAAA;AAAA,8BAEF,YAAUmL,EAAM;AAAA,8BAChB,aAAW1L;AAAA,8BACX,gBAAcH;AAAA,8BACd,eAAa,SAAS6L,EAAM,GAAG,SAAS1L,CAAI;AAAA,8BAC5C,MAAM4M,IAAY,WAAW;AAAA,8BAC7B,UACEA,KACI9D,KAAA,gBAAAA,EAAS,UAAS9I,IAChB,IACA,KACF;AAAA,8BAEN,cACE4M,IACIzH,EAAE,0BAA0B;AAAA,gCAC1B,IAAIiH;AAAA,gCACJ,SAASjH;AAAA,kCACP,uBAAuBtF,CAAO;AAAA,gCAAA;AAAA,gCAEhC,iBAAiB;AAAA,8BAAA,CAClB,IACD;AAAA,8BAEN,gBAAc+M,IAAYG,KAAS;AAAA,8BACnC,aAAY;AAAA,8BACZ,WAAW9I,GAAA;AAAA,8BACX,SAAS,CAAC8F,MAAU;AAClB,gCAAAA,EAAM,gBAAA,GACD6C,KAAWzE,EAAauD,EAAM,GAAG,GACtCpC,GAAcoC,EAAM,KAAK7L,CAAO;AAAA,8BAClC;AAAA,8BACA,WACE+M,IACI,CAAC7C,MACCD;AAAA,gCACEC;AAAA,gCACA2B,EAAM;AAAA,gCACN1L;AAAA,8BAAA,IAEJ;AAAA,8BAEN,SACE4M,IACI,MACE7D;AAAA,gCAAW,CAACiE,MACVA,KACAA,EAAE,QAAQtB,EAAM,OAChBsB,EAAE,SAAShN,IACPgN,IACA,EAAE,KAAKtB,EAAM,KAAK,MAAA1L,EAAA;AAAA,8BAAK,IAE/B;AAAA,4BAAA;AAAA,4BAzDDA;AAAA,0BAAA;AAAA,wBA6DX,CAAC,IACD;AAAA,wBAGH8B,MAAe,UAAUoK,KACxB,gBAAAjH;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,GAAG;AAAA,4BACH,GAAG;AAAA,4BACH,OAAOvD,IAAmB;AAAA,4BAC1B,QAAQO,IAAa;AAAA,4BACrB,MAAK;AAAA,4BACL,QAAQiK;AAAA,4BACR,aAAY;AAAA,4BAGZ,iBACED,OAAqB,WAAW,QAAQ;AAAA,4BAE1C,IAAG;AAAA,4BACH,eAAc;AAAA,0BAAA;AAAA,wBAAA,IAEd;AAAA,wBAEHnH,IACC,gBAAAG;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,GAAG,SAASvD,IAAmB,CAAC,IAAIO,IAAa,CAAC,KAAKP,IAAmB,CAAC,SAASO,IAAa,CAAC;AAAA,4BAClG,QAAQ/C,GAAiB;AAAA,4BACzB,aAAY;AAAA,4BACZ,MAAK;AAAA,4BACL,eAAc;AAAA,0BAAA;AAAA,wBAAA,IAEd;AAAA,wBAOJ,gBAAA+F;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,GAAG,CAACxD;AAAA,4BACJ,GAAG,CAACA;AAAA,4BACJ,OAAOC,IAAmBD,IAAgB;AAAA,4BAC1C,QAAQQ,IAAaR,IAAgB;AAAA,4BACrC,MAAK;AAAA,4BACL,QAAO;AAAA,4BACP,aAAY;AAAA,4BACZ,WAAW;AAAA,8BACT;AAAA,8BACA;AAAA,8BACA;AAAA,4BAAA,EACA,KAAK,GAAG;AAAA,4BACV,eAAa,SAASiK,EAAM,GAAG;AAAA,4BAC/B,eAAc;AAAA,4BACd,IAAG;AAAA,0BAAA;AAAA,wBAAA;AAAA,wBAGL,gBAAAzG;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,GAAGvD,IAAmB;AAAA,4BACtB,GAAGgK,EAAM,KAAK,SAAS,UAAUzJ,IAAa,KAAK;AAAA,4BACnD,YAAW;AAAA,4BACX,UAAS;AAAA,4BACT,MAAK;AAAA,4BACL,WAAU;AAAA,4BACV,eAAY;AAAA,4BAEX,UAAAmK;AAAA,0BAAA;AAAA,wBAAA;AAAA,sBACH;AAAA,oBAAA;AAAA,kBAAA,GAEJ;AAAA,kBACA,gBAAAnH,EAACmG,EAAa,QAAb,EACC,UAAA,gBAAApG;AAAA,oBAACoG,EAAa;AAAA,oBAAb;AAAA,sBACC,MAAK;AAAA,sBACL,YAAY;AAAA,sBACZ,WAAU;AAAA,sBAET,UAAA;AAAA,wBAAAe;AAAA,wBACD,gBAAAlH,EAACmG,EAAa,OAAb,EAAmB,WAAU,8BAAA,CAA8B;AAAA,sBAAA;AAAA,oBAAA;AAAA,kBAAA,EAC9D,CACF;AAAA,gBAAA,EAAA,GArQsBM,EAAM,GAsQ9B;AAAA,cAEJ,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,UAMFlE,KACC,gBAAAvC;AAAA,YAACW;AAAA,YAAA;AAAA,cACC,YAAW;AAAA,cACX,WAAA5D;AAAA,cACA,WAAAoB;AAAA,cACA,MAAA4C;AAAA,cACA,OAAOxC;AAAA,cACP,UAAU+E;AAAA,cACV,iBAAAlC;AAAA,cACA,cAAAhH;AAAA,cACA,WAAW,GAAG4L,EAAS,MAAM9F,EAAE,2BAA2B,CAAC;AAAA,YAAA;AAAA,UAAA,IAE3D;AAAA,UAEHmC,KAAS,gBAAArC,EAACC,IAAA,EAAO,cAAA7F,EAAA,CAA4B,IAAK;AAAA,UAEnD,gBAAA4F;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWjB,GAAA;AAAA,cACX,aAAU;AAAA,cACV,eAAY;AAAA,cACZ,eAAY;AAAA,cAEX,UAAAoE;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA,GAEJ;AAAA,EAEJ;AACF;AAEAxC,GAAY,cAAc;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"transaction-chip-DK84XCBU.js","sources":["../../node_modules/lucide-react/dist/esm/icons/arrow-down-left.js","../../node_modules/lucide-react/dist/esm/icons/arrow-up-right.js","../../src/components/transaction-chip/transaction-chip.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M17 7 7 17\", key: \"15tmo1\" }],\n [\"path\", { d: \"M17 17H7V7\", key: \"1org7z\" }]\n];\nconst ArrowDownLeft = createLucideIcon(\"arrow-down-left\", __iconNode);\n\nexport { __iconNode, ArrowDownLeft as default };\n//# sourceMappingURL=arrow-down-left.js.map\n","/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M7 7h10v10\", key: \"1tivn9\" }],\n [\"path\", { d: \"M7 17 17 7\", key: \"1vkiza\" }]\n];\nconst ArrowUpRight = createLucideIcon(\"arrow-up-right\", __iconNode);\n\nexport { __iconNode, ArrowUpRight as default };\n//# sourceMappingURL=arrow-up-right.js.map\n","import { forwardRef, type HTMLAttributes } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n ArrowDownLeft,\n ArrowUpRight,\n CalendarClock,\n Check,\n FileText,\n type LucideIcon,\n} from 'lucide-react';\n\n/* ------------------------------------------------------------------ */\n/* State vocabulary */\n/* ------------------------------------------------------------------ */\n\nexport type TransactionState =\n | 'debt'\n | 'credit'\n | 'to-invoice'\n | 'to-deliver'\n | 'settled';\n\n// State → translation-key segment. Hyphenated state names are flattened to\n// camelCase so the i18next bundle stays consistent with the rest of `ui.*`.\nconst STATE_KEY: Record<TransactionState, string> = {\n debt: 'debt',\n credit: 'credit',\n 'to-invoice': 'toInvoice',\n 'to-deliver': 'toDeliver',\n settled: 'settled',\n};\n\nconst STATE_ICON: Record<TransactionState, LucideIcon> = {\n debt: ArrowDownLeft,\n credit: ArrowUpRight,\n 'to-invoice': FileText,\n 'to-deliver': CalendarClock,\n settled: Check,\n};\n\n// U+2212 MINUS SIGN — matches PR alfadocs/platform#523's typographic minus.\n// Hyphen-minus would render visually narrower next to the currency glyph.\nconst STATE_SIGN: Record<TransactionState, '' | '+' | '−'> = {\n debt: '−',\n credit: '+',\n 'to-invoice': '',\n 'to-deliver': '',\n settled: '',\n};\n\n// Multiplier used when composing the screen-reader announcement so SR users\n// hear the signed amount Intl produces (\"minus one thousand…\") rather than\n// the magnitude plus a separate sign glyph.\nconst SIGN_MULTIPLIER: Record<TransactionState, -1 | 1> = {\n debt: -1,\n credit: 1,\n 'to-invoice': 1,\n 'to-deliver': 1,\n settled: 1,\n};\n\nconst DEFAULT_CURRENCY = 'EUR';\n\n/* ------------------------------------------------------------------ */\n/* CVA — chip root */\n/* ------------------------------------------------------------------ */\n\nconst chipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-full)] ds:border',\n 'ds:whitespace-nowrap ds:align-middle',\n 'ds:focus-visible:outline-none',\n 'ds:focus-visible:ring-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:ring-[color:var(--ring)]',\n 'ds:focus-visible:ring-offset-[length:var(--focus-ring-offset)]',\n ].join(' '),\n {\n variants: {\n state: {\n // Text uses the deeper `*-foreground` token (matching Badge / Tag) so\n // small chip text clears WCAG AA (4.5:1) against the 10% tinted\n // background. The surface and border use the lighter alias.\n debt: 'ds:bg-destructive/10 ds:text-[color:var(--error-foreground)] ds:border-[color:var(--error-foreground)]',\n credit:\n 'ds:bg-success/10 ds:text-[color:var(--success-foreground)] ds:border-[color:var(--success-foreground)]',\n // The orange \"to-invoice\" tint has no kit-wide semantic alias — see\n // src/tokens/index.css §Transaction-chip-scoped tokens. The component\n // owns the alias because the customer-anchored \"Da fatturare\" orange\n // is distinct from `--warning` (yellow) and from `--destructive`.\n 'to-invoice':\n 'ds:bg-transaction-chip-to-invoice/10 ds:text-[color:var(--transaction-chip-to-invoice-foreground)] ds:border-[color:var(--transaction-chip-to-invoice-foreground)]',\n 'to-deliver':\n 'ds:bg-info/10 ds:text-[color:var(--info-foreground)] ds:border-[color:var(--info-foreground)]',\n settled:\n 'ds:bg-muted/30 ds:text-muted-foreground ds:border-[color:var(--border)]',\n },\n size: {\n // Heights tuned for table-cell density (sm), default app surfaces (md),\n // and header / summary cards (lg). `--type-eyebrow-size` flows into the\n // optional label span, keeping its typography in step with the chip.\n sm: 'ds:h-5 ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-sm)] ds:text-[length:var(--font-size-2xs)] ds:[--type-eyebrow-size:var(--font-size-2xs)]',\n md: 'ds:h-6 ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:text-[length:var(--font-size-xs)] ds:[--type-eyebrow-size:var(--font-size-2xs)]',\n lg: 'ds:h-7 ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-sm)] ds:[--type-eyebrow-size:var(--font-size-xs)]',\n },\n bold: {\n // `settled` is the terminal resting state — see compound variant below.\n true: 'ds:font-semibold',\n false: 'ds:font-medium',\n },\n },\n defaultVariants: {\n state: 'debt',\n size: 'md',\n bold: true,\n },\n compoundVariants: [\n // `settled` always renders at the lighter weight, regardless of the\n // resolved default. Mirrors PR #523's follow-up where the resting branch\n // dropped from bold to medium to recede visually.\n { state: 'settled', class: 'ds:font-medium' },\n ],\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* CVA — icon wrapper */\n/* ------------------------------------------------------------------ */\n\n// `ArrowDownLeft` (debt) and `ArrowUpRight` (credit) are direction-encoded\n// glyphs — their physical orientation carries the semantic (\"money coming\n// in\" / \"money going out\"). PRS §05 RTL: directional icons flip in RTL.\n// The non-directional glyphs (FileText, CalendarClock, Check) are unaffected.\nconst iconWrapperVariants = cva('ds:shrink-0 ds:[&>svg]:block', {\n variants: {\n size: {\n sm: 'ds:[&>svg]:size-3',\n md: 'ds:[&>svg]:size-3.5',\n lg: 'ds:[&>svg]:size-4',\n },\n // Only the direction-encoded debt/credit arrows flip in RTL; the\n // non-directional glyphs (FileText, CalendarClock, Check) must not mirror.\n directional: {\n true: 'ds:rtl:[&>svg]:-scale-x-100',\n false: '',\n },\n },\n defaultVariants: { size: 'md', directional: false },\n});\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\nexport interface TransactionChipProps\n extends\n Omit<HTMLAttributes<HTMLSpanElement>, 'children'>,\n Pick<VariantProps<typeof chipVariants>, 'size'> {\n /** Financial state — drives colour, icon, sign, and label. */\n state: TransactionState;\n /**\n * Magnitude of the amount as a non-negative number. The sign is rendered\n * separately based on `state` — callers must never pass a negative value.\n */\n amount: number;\n /**\n * ISO 4217 currency code. Defaults to `EUR` for the Italian-anchored\n * release. Required at the type level so consumers can't silently render\n * a different currency than they intended.\n */\n currency?: string;\n /** BCP 47 locale override. Defaults to the active i18next language. */\n locale?: string;\n /** Render the state label (e.g. \"Da incassare\") before the amount. */\n showLabel?: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const TransactionChip = forwardRef<\n HTMLSpanElement,\n TransactionChipProps\n>(\n (\n {\n state,\n amount,\n currency = DEFAULT_CURRENCY,\n locale,\n size = 'md',\n showLabel = false,\n className,\n 'aria-label': ariaLabelProp,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const activeLocale = locale ?? i18n.language ?? 'en';\n\n const StateIcon = STATE_ICON[state];\n const sign = STATE_SIGN[state];\n const magnitude = Math.abs(amount);\n\n // The visible amount is rendered without a sign; the leading sign glyph\n // (or its absence) is owned by the state, not the formatter.\n const formattedAmount = new Intl.NumberFormat(activeLocale, {\n style: 'currency',\n currency,\n signDisplay: 'never',\n }).format(magnitude);\n\n // The accessible name uses Intl's own signed output so screen readers\n // announce the locale-correct \"minus\" / \"negative\" phrasing instead of\n // skipping the U+2212 glyph or speaking it as \"hyphen\".\n const stateLabel = t(`financial.state.${STATE_KEY[state]}`);\n const signedAmountForSR = new Intl.NumberFormat(activeLocale, {\n style: 'currency',\n currency,\n signDisplay: state === 'debt' ? 'always' : 'auto',\n }).format(magnitude * SIGN_MULTIPLIER[state]);\n const ariaLabel =\n ariaLabelProp ??\n t('financial.aria.label', {\n state: stateLabel,\n amount: signedAmountForSR,\n });\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={ariaLabel}\n data-component=\"transaction-chip\"\n data-state={state}\n className={chipVariants({\n state,\n size,\n bold: state !== 'settled',\n className,\n })}\n {...rest}\n >\n <span\n aria-hidden=\"true\"\n className={iconWrapperVariants({\n size,\n directional: state === 'debt' || state === 'credit',\n })}\n >\n <StateIcon />\n </span>\n {showLabel && (\n <span aria-hidden=\"true\" className=\"type-eyebrow\">\n {stateLabel}\n </span>\n )}\n {sign && (\n <span\n aria-hidden=\"true\"\n className=\"ds:[font-variant-numeric:var(--font-feature-tabular)]\"\n >\n {sign}\n </span>\n )}\n <span\n aria-hidden=\"true\"\n className=\"ds:[font-variant-numeric:var(--font-feature-tabular)]\"\n >\n {formattedAmount}\n </span>\n </span>\n );\n },\n);\n\nTransactionChip.displayName = 'TransactionChip';\n"],"names":["__iconNode","ArrowDownLeft","createLucideIcon","ArrowUpRight","STATE_KEY","STATE_ICON","FileText","CalendarClock","Check","STATE_SIGN","SIGN_MULTIPLIER","DEFAULT_CURRENCY","chipVariants","cva","iconWrapperVariants","TransactionChip","forwardRef","state","amount","currency","locale","size","showLabel","className","ariaLabelProp","rest","ref","t","i18n","useTranslation","activeLocale","StateIcon","sign","magnitude","formattedAmount","stateLabel","signedAmountForSR","ariaLabel","jsxs","jsx"],"mappings":"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","x_google_ignoreList":[0,1]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcript-panel-3THQX6nJ.js","sources":["../../src/components/transcript-panel/transcript-panel.agent.ts","../../src/components/transcript-panel/transcript-panel.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — TranscriptPanel. */\n/* */\n/* `data-turn-id` carries the line's stable index (opaque id) — never */\n/* the dictated text. Transcript content frequently contains PHI; the */\n/* DOM hook MUST NOT leak it. See PRS §26 §6.1. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TranscriptPanelHandle } from './transcript-panel';\n\nexport const transcriptPanelAgent: AgentAdapter<TranscriptPanelHandle> = {\n id: 'transcript-panel',\n capabilities: ['select_single', 'copy'],\n state: {\n selectedTurn: {\n type: 'string | null',\n descriptionKey: 'ui.agent.transcriptPanel.state.selectedTurn',\n description:\n 'Opaque id (line index) of the currently-active turn, or null when none is active.',\n read: (handle) => handle.getSelectedTurn(),\n },\n },\n actions: {\n focus_turn: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.transcriptPanel.actions.focusTurn',\n description: 'Scroll the given turn into view and focus its seek button.',\n invoke: (handle, args: { id: string }) => {\n handle.focusTurn(args.id);\n },\n },\n copy_turn: {\n // Clipboard write of dictated PHI text — write + reaches the system\n // clipboard (openWorld).\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n openWorld: true,\n descriptionKey: 'ui.agent.transcriptPanel.actions.copyTurn',\n description: \"Copy the given turn's text to the clipboard.\",\n invoke: (handle, args: { id: string }) => handle.copyTurn(args.id),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'transcript-panel',\n description: 'Marks the TranscriptPanel wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-turn-id',\n description:\n \"Stable opaque turn id (line index). Never carries the turn's dictated text.\",\n },\n },\n};\n","import {\n forwardRef,\n Fragment,\n useCallback,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { transcriptPanelAgent } from './transcript-panel.agent';\nimport { useVirtualizer } from '@tanstack/react-virtual';\nimport { SearchInput } from '../search-input';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface TranscriptLine {\n speaker: string;\n text: string;\n /** Seconds, floating-point — matches HTMLMediaElement.currentTime. */\n start: number;\n end: number;\n /** 0..1 — rendered with a dotted underline when below 0.6. */\n confidence?: number;\n}\n\n/** Curated imperative handle for agent / external automation. */\nexport interface TranscriptPanelHandle {\n /** Opaque id (line index) of the active turn, or null. */\n getSelectedTurn: () => string | null;\n /** Scroll the turn with the given id into view and focus its seek button. */\n focusTurn: (id: string) => void;\n /** Copy the turn's text to the clipboard. */\n copyTurn: (id: string) => Promise<void> | void;\n}\n\nexport interface TranscriptPanelProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>,\n VariantProps<typeof rootVariants> {\n lines: TranscriptLine[];\n /** Current playback time in seconds — drives the active line highlight. */\n currentTime?: number;\n onSeek?: (seconds: number) => void;\n /** Show the search bar. */\n searchable?: boolean;\n}\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:w-full ds:min-h-0',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--card-border)]',\n 'ds:shadow-[var(--shadow-card)] ds:[.theme-accessible_&]:border-2',\n 'ds:bg-background',\n 'ds:focus-within:border-[color:var(--primary)]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:text-[length:var(--font-size-sm)]',\n md: 'ds:text-[length:var(--font-size-base)]',\n lg: 'ds:text-[length:var(--font-size-lg)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst VIRTUALIZATION_THRESHOLD = 100;\nconst SPEAKER_SLOT_COUNT = 8;\n\nfunction formatTime(seconds: number, locale: string): string {\n const total = Math.max(0, Math.floor(seconds));\n const m = Math.floor(total / 60);\n const s = total % 60;\n const fmt = (n: number) =>\n new Intl.NumberFormat(locale, { minimumIntegerDigits: 2 }).format(n);\n return `${fmt(m)}:${fmt(s)}`;\n}\n\n/** ISO-8601 duration (PT#M#S) for <time datetime=\"...\">. */\nfunction secondsToIsoDuration(seconds: number): string {\n const total = Math.max(0, Math.floor(seconds));\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `PT${m}M${s}S`;\n}\n\n/** Deterministic speaker slot (0..7) based on name hash. */\nfunction speakerSlot(name: string): number {\n let hash = 0;\n for (let i = 0; i < name.length; i += 1) {\n hash = (hash * 31 + name.charCodeAt(i)) | 0;\n }\n return Math.abs(hash) % SPEAKER_SLOT_COUNT;\n}\n\n/** Per-slot background classes. Indices align with the speaker palette tokens\n * in tokens/index.css. Static strings so Tailwind can pick them up at build. */\nconst SPEAKER_BG_CLASSES = [\n 'ds:bg-[color:var(--transcript-speaker-1)]',\n 'ds:bg-[color:var(--transcript-speaker-2)]',\n 'ds:bg-[color:var(--transcript-speaker-3)]',\n 'ds:bg-[color:var(--transcript-speaker-4)]',\n 'ds:bg-[color:var(--transcript-speaker-5)]',\n 'ds:bg-[color:var(--transcript-speaker-6)]',\n 'ds:bg-[color:var(--transcript-speaker-7)]',\n 'ds:bg-[color:var(--transcript-speaker-8)]',\n] as const;\n\n/** Escape a literal string for safe use inside a RegExp. */\nfunction escapeRegExp(input: string): string {\n return input.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\ninterface HighlightedTextProps {\n text: string;\n query: string;\n}\n\n/** Renders text with <mark> wrapping around case-insensitive matches.\n * No dangerouslySetInnerHTML — splits text nodes only. */\nfunction HighlightedText({ text, query }: HighlightedTextProps): ReactNode {\n if (!query) return text;\n const escaped = escapeRegExp(query);\n const parts = text.split(new RegExp(`(${escaped})`, 'gi'));\n return parts.map((part, i) =>\n part.toLocaleLowerCase() === query.toLocaleLowerCase() ? (\n <mark\n key={i}\n className=\"ds:bg-[color:var(--warning)]/30 ds:text-[color:var(--foreground)] ds:rounded-[var(--radius-sm)]\"\n >\n {part}\n </mark>\n ) : (\n <Fragment key={i}>{part}</Fragment>\n ),\n );\n}\n\nexport const TranscriptPanel = forwardRef<HTMLDivElement, TranscriptPanelProps>(\n (\n {\n lines,\n currentTime = 0,\n onSeek,\n searchable = true,\n size = 'md',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const [query, setQuery] = useState('');\n const scrollRef = useRef<HTMLDivElement | null>(null);\n const searchInputRef = useRef<HTMLInputElement | null>(null);\n const searchId = useId();\n\n /* Active-line index */\n const activeIndex = useMemo(() => {\n if (!Number.isFinite(currentTime)) return -1;\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (line.start <= currentTime && currentTime < line.end) return i;\n }\n return -1;\n }, [lines, currentTime]);\n\n /* Match count for search */\n const matchCount = useMemo(() => {\n if (!query) return 0;\n let count = 0;\n const needle = query.toLocaleLowerCase();\n for (const line of lines) {\n const hay = line.text.toLocaleLowerCase();\n let idx = hay.indexOf(needle);\n while (idx !== -1) {\n count += 1;\n idx = hay.indexOf(needle, idx + needle.length);\n }\n }\n return count;\n }, [lines, query]);\n\n /* Ctrl/Cmd+F shortcut — focuses the search field when focus is within. */\n const handleRootKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (\n (e.metaKey || e.ctrlKey) &&\n e.key.toLowerCase() === 'f' &&\n searchable\n ) {\n e.preventDefault();\n searchInputRef.current?.focus();\n }\n },\n [searchable],\n );\n\n /* Virtualisation above 100 lines */\n const virtualized = lines.length > VIRTUALIZATION_THRESHOLD;\n const virtualizer = useVirtualizer({\n count: virtualized ? lines.length : 0,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => 48,\n overscan: 8,\n getItemKey: (i) => i,\n });\n\n /* Auto-scroll active line into view when it changes. */\n useIsomorphicLayoutEffect(() => {\n if (activeIndex < 0) return;\n const scroller = scrollRef.current;\n if (!scroller) return;\n const target = scroller.querySelector(\n `[data-line-index=\"${activeIndex}\"]`,\n ) as HTMLElement | null;\n if (!target) return;\n const prefersReducedMotion =\n typeof window !== 'undefined' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n target.scrollIntoView({\n block: 'center',\n behavior: prefersReducedMotion ? 'auto' : 'smooth',\n });\n }, [activeIndex]);\n\n const renderLine = useCallback(\n (\n line: TranscriptLine,\n index: number,\n extras?: {\n liRef?: (node: HTMLLIElement | null) => void;\n dataIndex?: number;\n // Style is an inline-style escape hatch — virtualizer offsets\n // cannot be expressed as static Tailwind. See 23-constraints §4.\n style?: CSSProperties;\n absolutePositioning?: boolean;\n },\n ) => {\n const isActive = index === activeIndex;\n const slot = speakerSlot(line.speaker);\n const lowConfidence =\n typeof line.confidence === 'number' && line.confidence < 0.6;\n return (\n <li\n key={index}\n ref={extras?.liRef}\n data-line-index={index}\n data-turn-id={String(index)}\n data-index={extras?.dataIndex}\n aria-current={isActive ? 'true' : undefined}\n // eslint-disable-next-line react/forbid-dom-props -- virtualizer translateY offset, runtime-computed\n style={extras?.style}\n className={[\n 'ds:flex ds:items-start ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]',\n isActive\n ? 'ds:bg-[color:var(--accent)]/12 ds:border-s-[3px] ds:border-[color:var(--primary)]'\n : 'ds:border-s-[3px] ds:border-transparent',\n extras?.absolutePositioning\n ? 'ds:absolute ds:start-0 ds:end-0 ds:top-0 ds:w-full'\n : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <button\n type=\"button\"\n onClick={() => onSeek?.(line.start)}\n aria-label={t('chat.transcript.seekTo', {\n time: formatTime(line.start, i18n.language),\n })}\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:font-[family-name:var(--font-mono)]',\n 'type-meta',\n 'ds:tabular-nums',\n 'ds:text-[color:var(--muted-foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-xs)]',\n // WCAG 2.5.5 target size: 44×44 default, 48×48 in accessible\n // themes — matches the DS `--min-target-size` token.\n 'ds:min-h-[var(--min-target-size)] ds:min-w-[var(--min-target-size)]',\n 'ds:hover:bg-muted/20',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' ')}\n >\n <time dir=\"ltr\" dateTime={secondsToIsoDuration(line.start)}>\n {formatTime(line.start, i18n.language)}\n </time>\n </button>\n <div className=\"ds:flex-1 ds:min-w-0\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={`ds:inline-block ds:size-2 ds:rounded-[var(--radius-full)] ${SPEAKER_BG_CLASSES[slot]}`}\n />\n <strong className=\"type-title-item\">\n {t('chat.transcript.speaker', { name: line.speaker })}\n </strong>\n {lowConfidence ? (\n <span className=\"type-meta ds:italic ds:text-[color:var(--muted-foreground)]\">\n ({t('chat.transcript.lowConfidence')})\n </span>\n ) : null}\n </div>\n <span\n dir=\"auto\"\n className={[\n 'ds:block',\n lowConfidence\n ? 'ds:underline ds:decoration-dotted ds:decoration-[color:var(--muted-foreground)]'\n : '',\n ].join(' ')}\n >\n <HighlightedText text={line.text} query={query} />\n </span>\n </div>\n </li>\n );\n },\n [activeIndex, i18n.language, onSeek, query, t],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLDivElement, []);\n\n const agentHandle = useMemo<TranscriptPanelHandle>(\n () => ({\n getSelectedTurn: () => (activeIndex >= 0 ? String(activeIndex) : null),\n focusTurn: (id: string) => {\n const target = scrollRef.current?.querySelector(\n `[data-turn-id=\"${id}\"]`,\n ) as HTMLElement | null;\n if (!target) return;\n target.scrollIntoView({ block: 'center', behavior: 'auto' });\n const btn = target.querySelector(\n 'button',\n ) as HTMLButtonElement | null;\n btn?.focus();\n },\n copyTurn: (id: string) => {\n const index = Number.parseInt(id, 10);\n if (!Number.isFinite(index)) return;\n const line = lines[index];\n if (!line) return;\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n return navigator.clipboard.writeText(line.text);\n }\n },\n }),\n [activeIndex, lines],\n );\n useAgentRegistration(\n transcriptPanelAgent,\n agentHandle,\n rest.id as string | undefined,\n );\n\n return (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- root keyboard shortcuts (j/k navigation, /) bubble up from focused descendants\n <div\n ref={rootRef}\n onKeyDown={handleRootKeyDown}\n data-component=\"transcript-panel\"\n data-component-id={rest.id}\n className={rootVariants({ size, className })}\n {...rest}\n >\n {searchable ? (\n <div className=\"ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-xs)] ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:border-b ds:border-border\">\n <SearchInput\n ref={searchInputRef}\n id={searchId}\n placeholder={t('chat.transcript.search')}\n aria-label={t('chat.transcript.search')}\n aria-keyshortcuts=\"Meta+F Control+F\"\n debounceMs={150}\n onChange={(v) => setQuery(v)}\n size=\"sm\"\n />\n {query ? (\n <span\n role=\"status\"\n aria-live=\"polite\"\n className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:tabular-nums\"\n >\n {matchCount === 0\n ? t('chat.transcript.noMatches')\n : t('chat.transcript.matchCount', { count: matchCount })}\n </span>\n ) : null}\n </div>\n ) : null}\n\n <div\n ref={scrollRef}\n className=\"ds:flex-1 ds:min-h-0 ds:overflow-y-auto ds:overflow-x-hidden\"\n >\n {virtualized ? (\n <ol\n className=\"ds:relative ds:list-none ds:ps-0 ds:m-0\"\n // eslint-disable-next-line react/forbid-dom-props -- virtualizer total size, runtime-computed\n style={{ blockSize: `${virtualizer.getTotalSize()}px` }}\n >\n {virtualizer.getVirtualItems().map((vi) => {\n const line = lines[vi.index];\n if (!line) return null;\n // Put the measureElement ref on the <li> directly — a <div>\n // child of <ol> is invalid and breaks list semantics for\n // assistive tech.\n return renderLine(line, vi.index, {\n liRef: virtualizer.measureElement,\n dataIndex: vi.index,\n style: { transform: `translateY(${vi.start}px)` },\n absolutePositioning: true,\n });\n })}\n </ol>\n ) : (\n <ol className=\"ds:list-none ds:ps-0 ds:m-0\">\n {lines.map((line, index) => renderLine(line, index))}\n </ol>\n )}\n </div>\n </div>\n );\n },\n);\n\nTranscriptPanel.displayName = 'TranscriptPanel';\n"],"names":["transcriptPanelAgent","handle","args","rootVariants","cva","VIRTUALIZATION_THRESHOLD","SPEAKER_SLOT_COUNT","formatTime","seconds","locale","total","m","s","fmt","n","secondsToIsoDuration","speakerSlot","name","hash","i","SPEAKER_BG_CLASSES","escapeRegExp","input","HighlightedText","text","query","escaped","part","jsx","Fragment","TranscriptPanel","forwardRef","lines","currentTime","onSeek","searchable","size","className","rest","ref","t","i18n","useTranslation","setQuery","useState","scrollRef","useRef","searchInputRef","searchId","useId","activeIndex","useMemo","line","matchCount","count","needle","hay","idx","handleRootKeyDown","useCallback","_a","virtualized","virtualizer","useVirtualizer","useIsomorphicLayoutEffect","scroller","target","prefersReducedMotion","renderLine","index","extras","isActive","slot","lowConfidence","jsxs","rootRef","useImperativeHandle","agentHandle","id","btn","useAgentRegistration","SearchInput","v","vi"],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- import { useState as u, useEffect as f } from "react";
2
- function s(t, e) {
3
- const [n, o] = u(() => {
4
- if (typeof window > "u")
5
- return typeof e == "function" ? e() : e;
6
- try {
7
- const r = window.localStorage.getItem(t);
8
- if (r !== null) return JSON.parse(r);
9
- } catch {
10
- }
11
- return typeof e == "function" ? e() : e;
12
- });
13
- return f(() => {
14
- if (!(typeof window > "u"))
15
- try {
16
- window.localStorage.setItem(t, JSON.stringify(n));
17
- } catch {
18
- }
19
- }, [t, n]), [n, o];
20
- }
21
- export {
22
- s as u
23
- };
24
- //# sourceMappingURL=use-persistent-state-i23OWy6G.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-persistent-state-i23OWy6G.js","sources":["../../src/hooks/use-persistent-state.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Drop-in `useState` replacement that mirrors its value to\n * `localStorage` under the given key. Same signature as `useState`, so\n * consumers can wire any state that should survive reloads without\n * plumbing effects by hand:\n *\n * @example\n * const [pinnedIds, setPinnedIds] =\n * usePersistentState<string[]>('ui.sidebar.favorites',\n * ['dashboard', 'calendar']);\n *\n * SSR-safe and quota-safe (swallows serialise / storage errors so a\n * disabled-storage or quota-exceeded write never throws into render).\n */\nexport function usePersistentState<T>(\n storageKey: string,\n initial: T | (() => T),\n): [T, (value: T | ((prev: T) => T)) => void] {\n const [value, setValue] = useState<T>(() => {\n if (typeof window === 'undefined') {\n return typeof initial === 'function' ? (initial as () => T)() : initial;\n }\n try {\n const raw = window.localStorage.getItem(storageKey);\n if (raw !== null) return JSON.parse(raw) as T;\n } catch {\n /* noop */\n }\n return typeof initial === 'function' ? (initial as () => T)() : initial;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n try {\n window.localStorage.setItem(storageKey, JSON.stringify(value));\n } catch {\n /* noop */\n }\n }, [storageKey, value]);\n\n return [value, setValue];\n}\n"],"names":["usePersistentState","storageKey","initial","value","setValue","useState","raw","useEffect"],"mappings":";AAgBO,SAASA,EACdC,GACAC,GAC4C;AAC5C,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAAY,MAAM;AAC1C,QAAI,OAAO,SAAW;AACpB,aAAO,OAAOH,KAAY,aAAcA,EAAA,IAAwBA;AAElE,QAAI;AACF,YAAMI,IAAM,OAAO,aAAa,QAAQL,CAAU;AAClD,UAAIK,MAAQ,KAAM,QAAO,KAAK,MAAMA,CAAG;AAAA,IACzC,QAAQ;AAAA,IAER;AACA,WAAO,OAAOJ,KAAY,aAAcA,EAAA,IAAwBA;AAAA,EAClE,CAAC;AAED,SAAAK,EAAU,MAAM;AACd,QAAI,SAAO,SAAW;AACtB,UAAI;AACF,eAAO,aAAa,QAAQN,GAAY,KAAK,UAAUE,CAAK,CAAC;AAAA,MAC/D,QAAQ;AAAA,MAER;AAAA,EACF,GAAG,CAACF,GAAYE,CAAK,CAAC,GAEf,CAACA,GAAOC,CAAQ;AACzB;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"warning-stack-BsgaEbL8.js","sources":["../../src/components/warning-stack/warning-stack.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronDown, X } from 'lucide-react';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { Alert, type AlertProps } from '../alert/alert';\nimport { Button } from '../button/button';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface WarningStackItem {\n id: string;\n variant?: AlertProps['variant'];\n title: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n actions?: ReactNode;\n dismissible?: boolean;\n}\n\n/** Empty-collapse fold phases (no-`emptyState` path only). See the fold\n * state machine in the component body. */\ntype FoldPhase = 'open' | 'settling' | 'closing' | 'closed';\n\nconst stackVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n 'ds:p-[var(--spacing-md)]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:gap-[var(--spacing-sm)]',\n md: 'ds:gap-[var(--spacing-md)]',\n },\n // `stretch: true` fills the parent layout cell — mirrors the `stretch`\n // prop on `Card` so a WarningStack rendered next to a Card in a grid\n // row ends up at matching height.\n stretch: {\n true: 'ds:h-full ds:self-stretch',\n false: '',\n },\n },\n defaultVariants: {\n size: 'md',\n stretch: false,\n },\n },\n);\n\n// Single column by default; two columns once the stack itself is wide\n// enough (container query — viewport width lies when the stack sits in\n// a narrow grid cell). A trailing odd item spans both columns so the\n// grid never ends on a half-width hole, which also keeps a lone item\n// full-width exactly as before.\nconst listVariants = cva(\n [\n 'ds:grid ds:grid-cols-1',\n 'ds:@3xl/warning-stack:grid-cols-2',\n 'ds:@3xl/warning-stack:[&>li:nth-child(odd):last-child]:col-span-full',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:gap-[var(--spacing-sm)]',\n md: 'ds:gap-[var(--spacing-md)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst TOGGLE_CLASSES = [\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] ds:self-start',\n].join(' ');\n\n/* ------------------------------------------------------------------ */\n/* Empty-collapse animation */\n/* */\n/* When the stack empties (every notice dismissed) and no `emptyState` */\n/* is supplied, the whole region folds away instead of leaving a hole. */\n/* The grid `1fr → 0fr` track is the only CSS-only way to animate to/ */\n/* from `height: auto`; JS-measured `max-height` is barred by the */\n/* no-inline-styles constraint. The outer wrapper owns the height */\n/* track; the inner wrapper owns the cross-fade + overflow clip. */\n/* ------------------------------------------------------------------ */\n\n/** Floor for how long the folding region stays mounted after it empties, so a\n * screen reader can voice the cleared count even when `--animation-duration`\n * is 0ms (accessible themes). The region is already visually collapsed, so\n * this window is imperceptible. */\nconst MIN_FOLD_UNMOUNT_MS = 250;\n\n/** Reads `--animation-duration` (ms) so the unmount timer matches the\n * CSS transition. Falls back to 200ms when it can't be resolved. */\nfunction readAnimationDurationMs(): number {\n if (typeof window === 'undefined') return 200;\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue('--animation-duration');\n const trimmed = raw.trim();\n const n = parseFloat(trimmed);\n if (!Number.isFinite(n)) return 200;\n return trimmed.endsWith('ms') ? n : n * 1000;\n}\n\n/** Outer height-collapse track. Always a grid so the `grid-template-rows`\n * transition has a stable from/to; only the row size flips. */\nfunction collapseTrackClass(collapsed: boolean, stretch: boolean): string {\n return [\n 'ds:grid ds:transition-[grid-template-rows]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n collapsed ? 'ds:grid-rows-[0fr]' : 'ds:grid-rows-[1fr]',\n stretch ? 'ds:h-full ds:self-stretch' : '',\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/** Inner cross-fade layer. `min-h-0` lets the grid item shrink below its\n * content; `overflow-hidden` (only while animating) clips the fold so the\n * card's resting drop-shadow isn't clipped at rest. */\nfunction collapseInnerClass(collapsed: boolean, closing: boolean): string {\n return [\n 'ds:min-h-0',\n 'ds:transition-opacity ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n collapsed ? 'ds:opacity-0 ds:overflow-hidden' : 'ds:opacity-100',\n closing ? 'ds:pointer-events-none' : '',\n ]\n .filter(Boolean)\n .join(' ');\n}\n\nexport interface WarningStackProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'role' | 'title'>,\n VariantProps<typeof stackVariants> {\n /** Items rendered inside the stack. */\n items: WarningStackItem[];\n /** Fill the parent layout cell — use in a dashboard grid row so the\n * stack ends up with matching height to sibling Cards. */\n stretch?: boolean;\n /** Visible title rendered as an `<h2>` above the stack. Also labels the\n * region for assistive tech. When omitted, the region is labelled via a\n * visually hidden heading using `ariaLabel` (or the default \"Warnings\"). */\n title?: ReactNode;\n /** Optional short description rendered under the title. */\n description?: ReactNode;\n /** Cap on visible items before a \"Show N more\" toggle appears. */\n maxVisible?: number;\n /** Whether the stack starts collapsed when items exceed `maxVisible`. */\n defaultCollapsed?: boolean;\n /** Fires when a dismissible item's close control is activated. */\n onDismiss?: (item: WarningStackItem) => void;\n /** When provided, a close control is rendered at the top inline-end of the\n * header that clears the whole stack at once. Activating it dismisses every\n * currently-visible notice (folding the region away) and then fires this\n * callback so the consumer can mirror the bulk dismissal into its store.\n * Opt-in: omit it when the stack carries notices that must not be bulk-cleared. */\n onDismissAll?: () => void;\n /** Accessible label for the whole-stack close control. Defaults to the\n * localised \"Dismiss all notices\". */\n dismissAllLabel?: string;\n /** Accessible label for the region when `title` is not set. */\n ariaLabel?: string;\n /** Optional node rendered when the stack has zero items. */\n emptyState?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport const WarningStack = forwardRef<HTMLDivElement, WarningStackProps>(\n (\n {\n items,\n title,\n description,\n maxVisible,\n defaultCollapsed = true,\n onDismiss,\n onDismissAll,\n dismissAllLabel,\n size = 'md',\n stretch = false,\n ariaLabel,\n emptyState,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const labelId = useId();\n const listId = useId();\n\n // Track dismissed ids internally so the <li> unmounts even when the\n // consumer doesn't mirror dismissal into `items` — otherwise the list\n // keeps a ghost entry (and the two-column grid a blank cell). Pruned\n // when an id leaves `items`, so a re-pushed item renders again.\n const [dismissedIds, setDismissedIds] = useState<ReadonlySet<string>>(\n () => new Set(),\n );\n useEffect(() => {\n setDismissedIds((prev) => {\n if (prev.size === 0) return prev;\n const ids = new Set(items.map((item) => item.id));\n const next = new Set([...prev].filter((id) => ids.has(id)));\n return next.size === prev.size ? prev : next;\n });\n }, [items]);\n\n const liveItems = useMemo(\n () => items.filter((item) => !dismissedIds.has(item.id)),\n [items, dismissedIds],\n );\n\n const overflow = maxVisible !== undefined && liveItems.length > maxVisible;\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n\n // Live-region announces the count when items change.\n const liveRef = useRef<HTMLDivElement>(null);\n const lastCountRef = useRef<number>(liveItems.length);\n\n useEffect(() => {\n if (!liveRef.current) return;\n const prev = lastCountRef.current;\n const next = liveItems.length;\n if (prev !== next) {\n liveRef.current.textContent = t('warningStack.countChanged', {\n count: next,\n defaultValue: '{{count}} warnings to review',\n });\n }\n lastCountRef.current = next;\n }, [liveItems.length, t]);\n\n const visible = useMemo(() => {\n if (!overflow || !collapsed) return liveItems;\n return liveItems.slice(0, maxVisible);\n }, [liveItems, overflow, collapsed, maxVisible]);\n\n const hiddenCount = overflow ? liveItems.length - (maxVisible ?? 0) : 0;\n\n /* ----- Empty-collapse phase ------------------------------------- */\n const hasItems = liveItems.length > 0;\n const hasEmptyState = emptyState != null;\n // There is something to show whenever a live notice remains, or an\n // empty state has been supplied to fill the region in its place.\n const present = hasItems || hasEmptyState;\n\n // Only the no-`emptyState` path animates the fold. It runs in two beats\n // so the height transition has a stable start: a CSS transition can't\n // interpolate when the element's content changes in the same commit as\n // the track flip, so `settling` first re-renders the emptied region at\n // full height (track still open), then `closing` flips the track to 0fr\n // on the next frame — now the browser animates from a real height.\n // open → settling → closing → closed (unmounted, until a notice lands)\n const [phase, setPhase] = useState<FoldPhase>(present ? 'open' : 'closed');\n // Drives the expand-in when a notice lands after the region had folded.\n const [entering, setEntering] = useState(false);\n\n useIsomorphicLayoutEffect(() => {\n if (present) {\n if (phase !== 'open') {\n // Replay the expand only when re-appearing from a collapsed state.\n if (phase === 'closing' || phase === 'closed') setEntering(true);\n setPhase('open');\n }\n } else if (phase === 'open') {\n setPhase('settling');\n }\n }, [present, phase]);\n\n // settling → closing: flip the track shut one frame after the emptied\n // region has painted at full height, so the collapse actually animates.\n useEffect(() => {\n if (phase !== 'settling') return;\n const raf = window.requestAnimationFrame(() => setPhase('closing'));\n return () => window.cancelAnimationFrame(raf);\n }, [phase]);\n\n // closing → closed: unmount once the collapse transition has run. The\n // delay is floored so the polite live region (which lives in this subtree)\n // survives long enough for assistive tech to voice the cleared count\n // before the node is removed — otherwise an accessible theme, where\n // `--animation-duration` is 0ms, would unmount in the same frame and\n // swallow the announcement. The region is already collapsed to zero\n // height by then, so the extra mounted time is invisible.\n useEffect(() => {\n if (phase !== 'closing') return;\n const delay = Math.max(readAnimationDurationMs(), MIN_FOLD_UNMOUNT_MS);\n const id = window.setTimeout(() => setPhase('closed'), delay);\n return () => window.clearTimeout(id);\n }, [phase]);\n\n // Expand-in: clear the collapsed start-state on the next frame so the\n // grid track animates open instead of snapping to full height.\n useEffect(() => {\n if (!entering) return;\n const raf = window.requestAnimationFrame(() => setEntering(false));\n return () => window.cancelAnimationFrame(raf);\n }, [entering]);\n\n const closing = phase === 'closing';\n const animCollapsed = closing || entering;\n const mounted = present || phase === 'settling' || phase === 'closing';\n\n // Focus hand-off: dismissing unmounts the focused close button, which\n // would otherwise drop focus to <body> (WCAG 2.4.3). Aim for the\n // dismiss control now occupying the same list position (the next\n // item), else the last remaining one, else the region itself.\n const sectionRef = useRef<HTMLElement | null>(null);\n const setSectionRef = useCallback(\n (node: HTMLElement | null) => {\n sectionRef.current = node;\n if (typeof ref === 'function') {\n ref(node as HTMLDivElement | null);\n } else if (ref) {\n (ref as MutableRefObject<HTMLDivElement | null>).current =\n node as HTMLDivElement | null;\n }\n },\n [ref],\n );\n const pendingFocusIndexRef = useRef<number | null>(null);\n // No dependency array on purpose: this runs after every render but is\n // gated by `pendingFocusIndexRef`, which is only non-null on the render\n // that immediately follows a dismissal. Don't \"fix\" it to `[liveItems]`.\n useEffect(() => {\n if (pendingFocusIndexRef.current === null) return;\n const index = pendingFocusIndexRef.current;\n pendingFocusIndexRef.current = null;\n const section = sectionRef.current;\n if (!section) return;\n const dismissControls = Array.from(\n section.querySelectorAll<HTMLButtonElement>('[data-alert-dismiss]'),\n );\n const target =\n dismissControls[Math.min(index, dismissControls.length - 1)];\n if (target) target.focus();\n // Last notice gone: only land focus on the region if it survives the\n // dismissal (an emptyState keeps it mounted). When the stack folds\n // away entirely there is no stable target here — the consumer owns\n // re-homing focus (see the dashboard pattern) and the live region\n // announces the cleared count.\n else if (hasEmptyState) section.focus();\n });\n\n const handleDismiss = useCallback(\n (item: WarningStackItem, index: number) => (open: boolean) => {\n if (open) return;\n pendingFocusIndexRef.current = index;\n setDismissedIds((prev) => new Set(prev).add(item.id));\n onDismiss?.(item);\n },\n [onDismiss],\n );\n\n // Whole-stack close: dismiss every currently-visible notice in one go,\n // which empties `liveItems` and folds the region away. Focus re-homing on\n // the fold is the consumer's responsibility (same as the last-item case) —\n // there's no surviving in-component target once the header unmounts.\n const handleDismissAll = useCallback(() => {\n setDismissedIds((prev) => {\n const next = new Set(prev);\n for (const item of liveItems) next.add(item.id);\n return next;\n });\n onDismissAll?.();\n }, [liveItems, onDismissAll]);\n\n const toggle = useCallback(() => setCollapsed((c) => !c), []);\n\n const regionLabel = ariaLabel ?? t('warningStack.regionLabel', 'Warnings');\n\n // Title block: a visible header when `title` is provided; otherwise a\n // visually hidden heading so the region still has a programmatic name.\n // A `<div>` rather than `<header>` wrapper keeps the `<header>` element's\n // implicit banner role from leaking out of the region. The whole-stack\n // close control (when enabled) sits at the inline-end of this row.\n const titleBlock = title ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <h2\n id={labelId}\n className=\"ds:text-start type-title-section ds:text-[var(--foreground)]\"\n >\n {title}\n </h2>\n {description ? (\n <p className=\"ds:text-start type-body-sm ds:text-[var(--muted-foreground)]\">\n {description}\n </p>\n ) : null}\n </div>\n ) : (\n <h2 id={labelId} className=\"ds:sr-only\">\n {regionLabel}\n </h2>\n );\n\n const showStackClose = onDismissAll != null && hasItems;\n const header = showStackClose ? (\n <div className=\"ds:flex ds:items-start ds:justify-between ds:gap-[var(--spacing-sm)]\">\n {titleBlock}\n <IconButton\n type=\"button\"\n icon={<X aria-hidden=\"true\" />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={\n dismissAllLabel ??\n t('warningStack.dismissAll', 'Dismiss all notices')\n }\n onClick={handleDismissAll}\n // Pull flush to the card's inline-end padding edge, and never let\n // the button compress when the title wraps.\n className=\"ds:-me-[var(--spacing-2xs)] ds:shrink-0\"\n />\n </div>\n ) : (\n titleBlock\n );\n\n // Fully folded away (or cold-start empty with no emptyState): render\n // nothing. Matches the long-standing \"empty + no emptyState → null\"\n // contract, now reached via the fold-out animation rather than instantly.\n if (!mounted) return null;\n\n return (\n // Outer: height-collapse track. Carries the bounding marker so it is\n // the cascade-reset boundary even mid-fold.\n <div\n data-component=\"warning-stack\"\n className={collapseTrackClass(animCollapsed, stretch)}\n >\n {/* Inner: cross-fade + overflow clip while folding. */}\n <div className={collapseInnerClass(animCollapsed, closing)}>\n <section\n ref={setSectionRef}\n aria-labelledby={labelId}\n // Programmatically focusable so a surviving region can take the\n // last dismissal's focus (see the focus hand-off above).\n tabIndex={-1}\n className={[stackVariants({ size, stretch }), className]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {header}\n {/* The live region announces the count as it changes. Omitted in\n emptyState mode, where the empty state itself communicates. */}\n {!hasEmptyState ? (\n <div\n ref={liveRef}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"ds:sr-only\"\n />\n ) : null}\n {hasItems ? (\n <>\n {/* Container-type lives on this wrapper (never on the flex\n section itself) so the list can query its own inline size. */}\n <div className=\"ds:@container/warning-stack\">\n <ul\n id={listId}\n className={listVariants({ size })}\n // Neutral wording — the list mixes warnings with info\n // notices and promo offers.\n aria-label={t('warningStack.listLabel', 'Notices')}\n >\n {visible.map((item, index) => {\n const variant = item.variant ?? 'warning';\n return (\n <li key={item.id}>\n <Alert\n variant={variant}\n dismissible={item.dismissible}\n icon={item.icon}\n onOpenChange={handleDismiss(item, index)}\n // Fill the row so side-by-side alerts equalise height.\n className=\"ds:h-full\"\n >\n {/* `as=\"h3\"` keeps a clean heading ladder — the\n stack's h2 labels the region, then each item's\n h3 rises from it. */}\n <Alert.Title as=\"h3\">{item.title}</Alert.Title>\n {item.description ? (\n <Alert.Description>\n {item.description}\n </Alert.Description>\n ) : null}\n {item.actions ? (\n <Alert.Action>{item.actions}</Alert.Action>\n ) : null}\n </Alert>\n </li>\n );\n })}\n </ul>\n </div>\n\n {overflow ? (\n <Button\n type=\"button\"\n intent=\"link\"\n size=\"sm\"\n aria-expanded={!collapsed}\n aria-controls={listId}\n onClick={toggle}\n className={TOGGLE_CLASSES}\n >\n <ChevronDown\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n collapsed ? '' : 'ds:rotate-180',\n ].join(' ')}\n />\n {collapsed\n ? t('warningStack.showMore', {\n count: hiddenCount,\n defaultValue: 'Show {{count}} more warnings',\n })\n : t('warningStack.showLess', 'Show less')}\n </Button>\n ) : null}\n </>\n ) : (\n emptyState\n )}\n </section>\n </div>\n </div>\n );\n },\n);\n\nWarningStack.displayName = 'WarningStack';\n"],"names":["stackVariants","cva","listVariants","TOGGLE_CLASSES","MIN_FOLD_UNMOUNT_MS","readAnimationDurationMs","trimmed","n","collapseTrackClass","collapsed","stretch","collapseInnerClass","closing","WarningStack","forwardRef","items","title","description","maxVisible","defaultCollapsed","onDismiss","onDismissAll","dismissAllLabel","size","ariaLabel","emptyState","className","rest","ref","t","useTranslation","labelId","useId","listId","dismissedIds","setDismissedIds","useState","useEffect","prev","ids","item","next","id","liveItems","useMemo","overflow","setCollapsed","liveRef","useRef","lastCountRef","visible","hiddenCount","hasItems","hasEmptyState","present","phase","setPhase","entering","setEntering","useIsomorphicLayoutEffect","raf","delay","animCollapsed","mounted","sectionRef","setSectionRef","useCallback","node","pendingFocusIndexRef","index","section","dismissControls","target","handleDismiss","open","handleDismissAll","toggle","c","regionLabel","titleBlock","jsxs","jsx","header","IconButton","X","Fragment","variant","Alert","Button","ChevronDown"],"mappings":"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"}