@alfadocs/ui-kit-debug 1.6.0 → 1.7.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.
- package/dist/_chunks/{actions-cell-renderer-BD-jruqA.js → actions-cell-renderer-ALEAGO3j.js} +6 -6
- package/dist/_chunks/{actions-cell-renderer-BD-jruqA.js.map → actions-cell-renderer-ALEAGO3j.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-CYR-znfE.js → agenda-tray-BweO8pDo.js} +3 -3
- package/dist/_chunks/{agenda-tray-CYR-znfE.js.map → agenda-tray-BweO8pDo.js.map} +1 -1
- package/dist/_chunks/{ai-consent-banner-DLF6FNXv.js → ai-consent-banner-OggpS5hW.js} +2 -2
- package/dist/_chunks/{ai-consent-banner-DLF6FNXv.js.map → ai-consent-banner-OggpS5hW.js.map} +1 -1
- package/dist/_chunks/{ai-prompt-input-BgAubYKd.js → ai-prompt-input-DnbfEJnr.js} +2 -2
- package/dist/_chunks/{ai-prompt-input-BgAubYKd.js.map → ai-prompt-input-DnbfEJnr.js.map} +1 -1
- package/dist/_chunks/{alia-sidebar-Bg53-ZOT.js → alia-sidebar-BWcWZivN.js} +7 -7
- package/dist/_chunks/{alia-sidebar-Bg53-ZOT.js.map → alia-sidebar-BWcWZivN.js.map} +1 -1
- package/dist/_chunks/{anamnesis-card-BylMLHYj.js → anamnesis-card-NTi4LLzI.js} +2 -2
- package/dist/_chunks/{anamnesis-card-BylMLHYj.js.map → anamnesis-card-NTi4LLzI.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-BpYztFUv.js → anamnesis-summary-rows-F-cCmFAn.js} +7 -7
- package/dist/_chunks/{anamnesis-summary-rows-BpYztFUv.js.map → anamnesis-summary-rows-F-cCmFAn.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-DT1uFp8z.js → appointment-timeline-CMPvzlGZ.js} +4 -4
- package/dist/_chunks/{appointment-timeline-DT1uFp8z.js.map → appointment-timeline-CMPvzlGZ.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-DvyVK7um.js → appointment-tray-3c_FLxXJ.js} +3 -3
- package/dist/_chunks/{appointment-tray-DvyVK7um.js.map → appointment-tray-3c_FLxXJ.js.map} +1 -1
- package/dist/_chunks/{audio-recorder-nVRN4PSK.js → audio-recorder-EWBCNIsd.js} +3 -3
- package/dist/_chunks/{audio-recorder-nVRN4PSK.js.map → audio-recorder-EWBCNIsd.js.map} +1 -1
- package/dist/_chunks/{bishop-score-BV1JAEMV.js → bishop-score-Cnu0xs-z.js} +2 -2
- package/dist/_chunks/{bishop-score-BV1JAEMV.js.map → bishop-score-Cnu0xs-z.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-CdR-RLFj.js → bmi-calculator-CcH6upht.js} +2 -2
- package/dist/_chunks/{bmi-calculator-CdR-RLFj.js.map → bmi-calculator-CcH6upht.js.map} +1 -1
- package/dist/_chunks/{booking-D84O6H2X.js → booking-CQMJUFG-.js} +5 -5
- package/dist/_chunks/{booking-D84O6H2X.js.map → booking-CQMJUFG-.js.map} +1 -1
- package/dist/_chunks/{button-group-Be_In68J.js → button-group-CaxRJsNG.js} +2 -2
- package/dist/_chunks/{button-group-Be_In68J.js.map → button-group-CaxRJsNG.js.map} +1 -1
- package/dist/_chunks/{button-BvNtqHAS.js → button-nJaPh_HC.js} +68 -38
- package/dist/_chunks/button-nJaPh_HC.js.map +1 -0
- package/dist/_chunks/{care-plan-card-CehAU7F_.js → care-plan-card-DQjVRDxO.js} +2 -2
- package/dist/_chunks/{care-plan-card-CehAU7F_.js.map → care-plan-card-DQjVRDxO.js.map} +1 -1
- package/dist/_chunks/{care-plan-entry-card-ChWRMfMw.js → care-plan-entry-card-CMpoeNkb.js} +2 -2
- package/dist/_chunks/{care-plan-entry-card-ChWRMfMw.js.map → care-plan-entry-card-CMpoeNkb.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-_B0TTWT1.js → care-plan-header-CxYoq23f.js} +2 -2
- package/dist/_chunks/{care-plan-header-_B0TTWT1.js.map → care-plan-header-CxYoq23f.js.map} +1 -1
- package/dist/_chunks/{carousel.agent-pjORsMS8.js → carousel.agent-CLxdHEBP.js} +2 -2
- package/dist/_chunks/{carousel.agent-pjORsMS8.js.map → carousel.agent-CLxdHEBP.js.map} +1 -1
- package/dist/_chunks/{chart-Y-gso_Uz.js → chart-Bkr1Sh4o.js} +3 -3
- package/dist/_chunks/{chart-Y-gso_Uz.js.map → chart-Bkr1Sh4o.js.map} +1 -1
- package/dist/_chunks/{chat-input-BqI9GXQh.js → chat-input-BsB5Umpj.js} +2 -2
- package/dist/_chunks/{chat-input-BqI9GXQh.js.map → chat-input-BsB5Umpj.js.map} +1 -1
- package/dist/_chunks/{chat-message-DHNUbjXA.js → chat-message-DBQu10rs.js} +3 -3
- package/dist/_chunks/{chat-message-DHNUbjXA.js.map → chat-message-DBQu10rs.js.map} +1 -1
- package/dist/_chunks/{code-block-BONe9fJi.js → code-block-BIkpRLkl.js} +2 -2
- package/dist/_chunks/{code-block-BONe9fJi.js.map → code-block-BIkpRLkl.js.map} +1 -1
- package/dist/_chunks/{connection-status-NT8hUtYl.js → connection-status-DRZIcMqM.js} +3 -3
- package/dist/_chunks/{connection-status-NT8hUtYl.js.map → connection-status-DRZIcMqM.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-BxHiG8e6.js → contact-profile-card-CE9OJKcl.js} +2 -2
- package/dist/_chunks/{contact-profile-card-BxHiG8e6.js.map → contact-profile-card-CE9OJKcl.js.map} +1 -1
- package/dist/_chunks/{control-room-rail-DDyPDBji.js → control-room-rail-IH1eBjrK.js} +3 -3
- package/dist/_chunks/{control-room-rail-DDyPDBji.js.map → control-room-rail-IH1eBjrK.js.map} +1 -1
- package/dist/_chunks/{copy-field-B-DoMBH_.js → copy-field-fYKpl6aN.js} +2 -2
- package/dist/_chunks/{copy-field-B-DoMBH_.js.map → copy-field-fYKpl6aN.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-DJZYvNhw.js → cycle-calculator-DzgO1vzP.js} +2 -2
- package/dist/_chunks/{cycle-calculator-DJZYvNhw.js.map → cycle-calculator-DzgO1vzP.js.map} +1 -1
- package/dist/_chunks/{dashboard-grid-bd0QW2a8.js → dashboard-grid-BFtdHqfn.js} +2 -2
- package/dist/_chunks/{dashboard-grid-bd0QW2a8.js.map → dashboard-grid-BFtdHqfn.js.map} +1 -1
- package/dist/_chunks/{data-table-tabs-C8uDThT3.js → data-table-tabs-C1kRUzat.js} +3 -3
- package/dist/_chunks/{data-table-tabs-C8uDThT3.js.map → data-table-tabs-C1kRUzat.js.map} +1 -1
- package/dist/_chunks/{description-list-Ck7fKdt5.js → description-list-CjJqR8WK.js} +2 -2
- package/dist/_chunks/{description-list-Ck7fKdt5.js.map → description-list-CjJqR8WK.js.map} +1 -1
- package/dist/_chunks/{document-preview-Aae2yKvY.js → document-preview-oyx9RhCo.js} +2 -2
- package/dist/_chunks/{document-preview-Aae2yKvY.js.map → document-preview-oyx9RhCo.js.map} +1 -1
- package/dist/_chunks/{document-scanner-qNZLhH_r.js → document-scanner-C5Vrbu21.js} +2 -2
- package/dist/_chunks/{document-scanner-qNZLhH_r.js.map → document-scanner-C5Vrbu21.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-ajaQ4ya5.js → due-date-calculator-wK8Tajzz.js} +2 -2
- package/dist/_chunks/{due-date-calculator-ajaQ4ya5.js.map → due-date-calculator-wK8Tajzz.js.map} +1 -1
- package/dist/_chunks/{editable-currency-cell-renderer-DyMbSyDK.js → editable-currency-cell-renderer-DYdzKpjL.js} +3 -3
- package/dist/_chunks/{editable-currency-cell-renderer-DyMbSyDK.js.map → editable-currency-cell-renderer-DYdzKpjL.js.map} +1 -1
- package/dist/_chunks/{editor-overlay-DE-gxj9L.js → editor-overlay-DEc5yYwo.js} +2 -2
- package/dist/_chunks/{editor-overlay-DE-gxj9L.js.map → editor-overlay-DEc5yYwo.js.map} +1 -1
- package/dist/_chunks/{empty-state-Df0tM6Kn.js → empty-state-X0sVPfVo.js} +2 -2
- package/dist/_chunks/{empty-state-Df0tM6Kn.js.map → empty-state-X0sVPfVo.js.map} +1 -1
- package/dist/_chunks/{entity-summary-DBOI5di6.js → entity-summary-B_vO5Ur4.js} +3 -3
- package/dist/_chunks/{entity-summary-DBOI5di6.js.map → entity-summary-B_vO5Ur4.js.map} +1 -1
- package/dist/_chunks/{face-scheme-D7Pub04e.js → face-scheme-BfDi4YkW.js} +5 -5
- package/dist/_chunks/{face-scheme-D7Pub04e.js.map → face-scheme-BfDi4YkW.js.map} +1 -1
- package/dist/_chunks/{fetal-weight-jon6GIfQ.js → fetal-weight-Dqy0T1fP.js} +2 -2
- package/dist/_chunks/{fetal-weight-jon6GIfQ.js.map → fetal-weight-Dqy0T1fP.js.map} +1 -1
- package/dist/_chunks/{field-array-BQFX5OYi.js → field-array-BjkXZzSr.js} +3 -3
- package/dist/_chunks/{field-array-BQFX5OYi.js.map → field-array-BjkXZzSr.js.map} +1 -1
- package/dist/_chunks/{field-value-BbiDRyNh.js → field-value-DG8zaZvo.js} +4 -4
- package/dist/_chunks/{field-value-BbiDRyNh.js.map → field-value-DG8zaZvo.js.map} +1 -1
- package/dist/_chunks/{file-manager-CML_C6_h.js → file-manager-Cc_upjZX.js} +6 -6
- package/dist/_chunks/{file-manager-CML_C6_h.js.map → file-manager-Cc_upjZX.js.map} +1 -1
- package/dist/_chunks/{finished-terminal-BWNVh7Y8.js → finished-terminal-Br61Ip4e.js} +2 -2
- package/dist/_chunks/{finished-terminal-BWNVh7Y8.js.map → finished-terminal-Br61Ip4e.js.map} +1 -1
- package/dist/_chunks/{fiscal-code-input-Nx1N9r72.js → fiscal-code-input-B_nYMSEM.js} +2 -2
- package/dist/_chunks/{fiscal-code-input-Nx1N9r72.js.map → fiscal-code-input-B_nYMSEM.js.map} +1 -1
- package/dist/_chunks/{freemium-paywall-HG3pFvMp.js → freemium-paywall-DrXzYfv-.js} +2 -2
- package/dist/_chunks/{freemium-paywall-HG3pFvMp.js.map → freemium-paywall-DrXzYfv-.js.map} +1 -1
- package/dist/_chunks/{gestational-age-calculator-dEpQDWcb.js → gestational-age-calculator-C_uDAeP_.js} +2 -2
- package/dist/_chunks/{gestational-age-calculator-dEpQDWcb.js.map → gestational-age-calculator-C_uDAeP_.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-CC6TLtHd.js → hcg-doubling-BaXkJhT-.js} +2 -2
- package/dist/_chunks/{hcg-doubling-CC6TLtHd.js.map → hcg-doubling-BaXkJhT-.js.map} +1 -1
- package/dist/_chunks/{header-CimZS-J9.js → header-DUXRIPyM.js} +2 -2
- package/dist/_chunks/{header-CimZS-J9.js.map → header-DUXRIPyM.js.map} +1 -1
- package/dist/_chunks/{header-settings-C0zHLXJE.js → header-settings-CVC_davE.js} +4 -4
- package/dist/_chunks/{header-settings-C0zHLXJE.js.map → header-settings-CVC_davE.js.map} +1 -1
- package/dist/_chunks/{icon-button-9c9Gp41m.js → icon-button-DA2CAGHZ.js} +2 -2
- package/dist/_chunks/{icon-button-9c9Gp41m.js.map → icon-button-DA2CAGHZ.js.map} +1 -1
- package/dist/_chunks/{icon-button-group-DrvuWPGJ.js → icon-button-group-D6SVMteH.js} +2 -2
- package/dist/_chunks/{icon-button-group-DrvuWPGJ.js.map → icon-button-group-D6SVMteH.js.map} +1 -1
- package/dist/_chunks/{icon-picker-DXV3sDp1.js → icon-picker-ChzpCnZ-.js} +3 -3
- package/dist/_chunks/{icon-picker-DXV3sDp1.js.map → icon-picker-ChzpCnZ-.js.map} +1 -1
- package/dist/_chunks/{image-cropper-DWSnyLwW.js → image-cropper-C84NDTB7.js} +2 -2
- package/dist/_chunks/{image-cropper-DWSnyLwW.js.map → image-cropper-C84NDTB7.js.map} +1 -1
- package/dist/_chunks/{info-tip-C4mPSJbS.js → info-tip-C119cwQl.js} +2 -2
- package/dist/_chunks/{info-tip-C4mPSJbS.js.map → info-tip-C119cwQl.js.map} +1 -1
- package/dist/_chunks/{insert-result-98J1QEp7.js → insert-result-LCNTskNJ.js} +2 -2
- package/dist/_chunks/{insert-result-98J1QEp7.js.map → insert-result-LCNTskNJ.js.map} +1 -1
- package/dist/_chunks/{key-value-pair-DGkGlgCF.js → key-value-pair-BubG4fUa.js} +2 -2
- package/dist/_chunks/{key-value-pair-DGkGlgCF.js.map → key-value-pair-BubG4fUa.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-D3IsW_2R.js → link-cell-renderer-DH4JYpKU.js} +2 -2
- package/dist/_chunks/{link-cell-renderer-D3IsW_2R.js.map → link-cell-renderer-DH4JYpKU.js.map} +1 -1
- package/dist/_chunks/{locale-picker-sI0HWgZy.js → locale-picker-BvbVjDQ-.js} +3 -3
- package/dist/_chunks/{locale-picker-sI0HWgZy.js.map → locale-picker-BvbVjDQ-.js.map} +1 -1
- package/dist/_chunks/{map-view-iwSDRW3t.js → map-view-CCAlC9IL.js} +2 -2
- package/dist/_chunks/{map-view-iwSDRW3t.js.map → map-view-CCAlC9IL.js.map} +1 -1
- package/dist/_chunks/{marketplace-app-shell-b5hN-Q0m.js → marketplace-app-shell-Chfdia7m.js} +4 -4
- package/dist/_chunks/{marketplace-app-shell-b5hN-Q0m.js.map → marketplace-app-shell-Chfdia7m.js.map} +1 -1
- package/dist/_chunks/{message-card-BCJ-Jgs6.js → message-card-D8GB4FdF.js} +3 -3
- package/dist/_chunks/{message-card-BCJ-Jgs6.js.map → message-card-D8GB4FdF.js.map} +1 -1
- package/dist/_chunks/{message-tray-DHtm_WaF.js → message-tray-CGIRQjx5.js} +4 -4
- package/dist/_chunks/{message-tray-DHtm_WaF.js.map → message-tray-CGIRQjx5.js.map} +1 -1
- package/dist/_chunks/{notes-panel-D6HKLLS-.js → notes-panel-DlnENphf.js} +3 -3
- package/dist/_chunks/{notes-panel-D6HKLLS-.js.map → notes-panel-DlnENphf.js.map} +1 -1
- package/dist/_chunks/{notification-card-CcMQn2RX.js → notification-card-CtrzoTUO.js} +3 -3
- package/dist/_chunks/{notification-card-CcMQn2RX.js.map → notification-card-CtrzoTUO.js.map} +1 -1
- package/dist/_chunks/{notification-tray-nr7dv-Q8.js → notification-tray-BiRzXHDf.js} +4 -4
- package/dist/_chunks/{notification-tray-nr7dv-Q8.js.map → notification-tray-BiRzXHDf.js.map} +1 -1
- package/dist/_chunks/{optical-prescription-DtzEqFQm.js → optical-prescription-Dj3Eh5Ok.js} +2 -2
- package/dist/_chunks/{optical-prescription-DtzEqFQm.js.map → optical-prescription-Dj3Eh5Ok.js.map} +1 -1
- package/dist/_chunks/{patient-details-rENrE_qY.js → patient-details-qnsqYBGQ.js} +5 -5
- package/dist/_chunks/{patient-details-rENrE_qY.js.map → patient-details-qnsqYBGQ.js.map} +1 -1
- package/dist/_chunks/{patient-search-NQemeJlL.js → patient-search-D5ufYoRc.js} +2 -2
- package/dist/_chunks/{patient-search-NQemeJlL.js.map → patient-search-D5ufYoRc.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-DQJgOOrA.js → patient-summary-card-CBfuDvJ5.js} +3 -3
- package/dist/_chunks/{patient-summary-card-DQJgOOrA.js.map → patient-summary-card-CBfuDvJ5.js.map} +1 -1
- package/dist/_chunks/{patient-table-BubxfOWL.js → patient-table-DwshfVsQ.js} +3 -3
- package/dist/_chunks/{patient-table-BubxfOWL.js.map → patient-table-DwshfVsQ.js.map} +1 -1
- package/dist/_chunks/{payment-automation-upsell-CnaBPt5e.js → payment-automation-upsell-BBIG7NFL.js} +2 -2
- package/dist/_chunks/{payment-automation-upsell-CnaBPt5e.js.map → payment-automation-upsell-BBIG7NFL.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-CvhDzDNk.js → payment-request-card-BjjBMdsp.js} +3 -3
- package/dist/_chunks/{payment-request-card-CvhDzDNk.js.map → payment-request-card-BjjBMdsp.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-C0nNQKKK.js → periodontal-chart-BatZEFar.js} +2 -2
- package/dist/_chunks/{periodontal-chart-C0nNQKKK.js.map → periodontal-chart-BatZEFar.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-card-Bz-ebteE.js → periodontal-chart-card-BBpY_rBc.js} +2 -2
- package/dist/_chunks/{periodontal-chart-card-Bz-ebteE.js.map → periodontal-chart-card-BBpY_rBc.js.map} +1 -1
- package/dist/_chunks/{popover-Btj6N25H.js → popover-Cqcjx-Ny.js} +2 -2
- package/dist/_chunks/{popover-Btj6N25H.js.map → popover-Cqcjx-Ny.js.map} +1 -1
- package/dist/_chunks/{practice-results-CKoLD_x5.js → practice-results-BEsAdW-B.js} +719 -633
- package/dist/_chunks/practice-results-BEsAdW-B.js.map +1 -0
- package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js → pregnancy-dating-BVS_9YU2.js} +2 -2
- package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js.map → pregnancy-dating-BVS_9YU2.js.map} +1 -1
- package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js → pregnancy-weight-gain-CJwbs9W-.js} +2 -2
- package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js.map → pregnancy-weight-gain-CJwbs9W-.js.map} +1 -1
- package/dist/_chunks/{privacy-lock-SQYFRSuH.js → privacy-lock-CkAUo6Dz.js} +3 -3
- package/dist/_chunks/{privacy-lock-SQYFRSuH.js.map → privacy-lock-CkAUo6Dz.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-BjnD9pdl.js → product-hub-panel-BScCotGD.js} +3 -3
- package/dist/_chunks/{product-hub-panel-BjnD9pdl.js.map → product-hub-panel-BScCotGD.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-DseNK2NQ.js → public-header.agent-kth2SdXn.js} +3 -3
- package/dist/_chunks/{public-header.agent-DseNK2NQ.js.map → public-header.agent-kth2SdXn.js.map} +1 -1
- package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js → radiograph-panel.agent-CiHwgISa.js} +4 -4
- package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js.map → radiograph-panel.agent-CiHwgISa.js.map} +1 -1
- package/dist/_chunks/{reviews-panel-Cd3SxJdW.js → reviews-panel-BKHEfqVQ.js} +4 -4
- package/dist/_chunks/{reviews-panel-Cd3SxJdW.js.map → reviews-panel-BKHEfqVQ.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-DGtn_4sb.js → rich-text-editor-DARnq_6N.js} +5 -5
- package/dist/_chunks/{rich-text-editor-DGtn_4sb.js.map → rich-text-editor-DARnq_6N.js.map} +1 -1
- package/dist/_chunks/{session-countdown-q4r5TlCo.js → session-countdown-QMsnRa1x.js} +2 -2
- package/dist/_chunks/{session-countdown-q4r5TlCo.js.map → session-countdown-QMsnRa1x.js.map} +1 -1
- package/dist/_chunks/{sheet-CD99CdXr.js → sheet-BSznOyJs.js} +2 -2
- package/dist/_chunks/{sheet-CD99CdXr.js.map → sheet-BSznOyJs.js.map} +1 -1
- package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js → sign-in-with-alfadocs-button-BLe_quy5.js} +2 -2
- package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js.map → sign-in-with-alfadocs-button-BLe_quy5.js.map} +1 -1
- package/dist/_chunks/{signature-request-C4UBfVRZ.js → signature-request-DXhpphlp.js} +4 -4
- package/dist/_chunks/{signature-request-C4UBfVRZ.js.map → signature-request-DXhpphlp.js.map} +1 -1
- package/dist/_chunks/{slot-grid-P_e9p5t5.js → slot-grid-BuZOKfcd.js} +4 -4
- package/dist/_chunks/{slot-grid-P_e9p5t5.js.map → slot-grid-BuZOKfcd.js.map} +1 -1
- package/dist/_chunks/{streaming-text-BuW7I0Zu.js → streaming-text-CvsjIQ7S.js} +2 -2
- package/dist/_chunks/{streaming-text-BuW7I0Zu.js.map → streaming-text-CvsjIQ7S.js.map} +1 -1
- package/dist/_chunks/{task-tray-BT288xoM.js → task-tray-CYG6rj2s.js} +3 -3
- package/dist/_chunks/{task-tray-BT288xoM.js.map → task-tray-CYG6rj2s.js.map} +1 -1
- package/dist/_chunks/{tasks-panel-BBkZuejF.js → tasks-panel-Do5SFp-j.js} +5 -5
- package/dist/_chunks/{tasks-panel-BBkZuejF.js.map → tasks-panel-Do5SFp-j.js.map} +1 -1
- package/dist/_chunks/{theme-toggle-Bi-CmV6M.js → theme-toggle-DuMhQNFS.js} +3 -3
- package/dist/_chunks/{theme-toggle-Bi-CmV6M.js.map → theme-toggle-DuMhQNFS.js.map} +1 -1
- package/dist/_chunks/{toast.agent-C44mtGrW.js → toast.agent-D1tdg6DS.js} +2 -2
- package/dist/_chunks/{toast.agent-C44mtGrW.js.map → toast.agent-D1tdg6DS.js.map} +1 -1
- package/dist/_chunks/{token-insert-menu-D8FgXl33.js → token-insert-menu-9Um0JinI.js} +2 -2
- package/dist/_chunks/{token-insert-menu-D8FgXl33.js.map → token-insert-menu-9Um0JinI.js.map} +1 -1
- package/dist/_chunks/{tool-rail-BF3F2Ihq.js → tool-rail-CHyUmulN.js} +2 -2
- package/dist/_chunks/{tool-rail-BF3F2Ihq.js.map → tool-rail-CHyUmulN.js.map} +1 -1
- package/dist/_chunks/{tooth-scheme-BPXE1_3N.js → tooth-scheme-WdyVymQ1.js} +3 -3
- package/dist/_chunks/{tooth-scheme-BPXE1_3N.js.map → tooth-scheme-WdyVymQ1.js.map} +1 -1
- package/dist/_chunks/{unit-converter-iDxlxKmm.js → unit-converter-BPumXMA6.js} +2 -2
- package/dist/_chunks/{unit-converter-iDxlxKmm.js.map → unit-converter-BPumXMA6.js.map} +1 -1
- package/dist/_chunks/{warning-stack-nczJf52p.js → warning-stack-DQz0Jyir.js} +3 -3
- package/dist/_chunks/{warning-stack-nczJf52p.js.map → warning-stack-DQz0Jyir.js.map} +1 -1
- package/dist/_chunks/{workflow-map-BVofnDYh.js → workflow-map-DE_ribRM.js} +5 -5
- package/dist/_chunks/{workflow-map-BVofnDYh.js.map → workflow-map-DE_ribRM.js.map} +1 -1
- package/dist/agent-catalog.json +2 -2
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/ai-consent-banner/index.js +1 -1
- package/dist/components/ai-prompt-input/index.js +1 -1
- package/dist/components/anamnesis-card/index.js +1 -1
- package/dist/components/appointment-card/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/audio-recorder/index.js +1 -1
- package/dist/components/bishop-score/index.js +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/button/button.d.ts +10 -0
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/index.js +2 -2
- package/dist/components/button-group/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-entry-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/carousel/index.js +1 -1
- package/dist/components/chart/index.js +1 -1
- package/dist/components/chat-input/index.js +1 -1
- package/dist/components/chat-message/index.js +1 -1
- package/dist/components/connection-status/index.js +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/control-room-rail/index.js +1 -1
- package/dist/components/copy-field/index.js +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/dashboard-grid/index.js +1 -1
- package/dist/components/data-table/index.js +3 -3
- package/dist/components/data-table-tabs/index.js +1 -1
- package/dist/components/description-list/index.js +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/document-scanner/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/editor-overlay/index.js +1 -1
- package/dist/components/empty-state/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/face-scheme/index.js +1 -1
- package/dist/components/fetal-weight/index.js +1 -1
- package/dist/components/field-array/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/finished-terminal/index.js +1 -1
- package/dist/components/fiscal-code-input/index.js +1 -1
- package/dist/components/freemium-paywall/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/hcg-doubling/index.js +1 -1
- package/dist/components/header/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/icon-button/index.js +1 -1
- package/dist/components/icon-button-group/index.js +1 -1
- package/dist/components/icon-picker/index.js +1 -1
- package/dist/components/image-cropper/index.js +1 -1
- package/dist/components/info-tip/index.js +1 -1
- package/dist/components/key-value-pair/index.js +1 -1
- package/dist/components/locale-picker/index.js +1 -1
- package/dist/components/map-view/index.js +1 -1
- package/dist/components/matrix-rain/matrix-rain.d.ts +1 -1
- package/dist/components/message-card/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notification-card/index.js +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/optical-prescription/index.js +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/periodontal-chart/index.js +1 -1
- package/dist/components/periodontal-chart-card/index.js +1 -1
- package/dist/components/popover/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/practice-results/practice-results.d.ts +47 -7
- package/dist/components/practice-results/practice-results.d.ts.map +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/privacy-lock/index.js +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/public-header/public-header.d.ts +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/reviews-panel/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/session-countdown/index.js +1 -1
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/components/streaming-text/index.js +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/toast/index.js +1 -1
- package/dist/components/token-insert-menu/index.js +1 -1
- package/dist/components/tool-rail/index.js +1 -1
- package/dist/components/tooth-scheme/index.js +1 -1
- package/dist/components/unit-converter/index.js +1 -1
- package/dist/components/warning-stack/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +1 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +2 -1
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +1 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +2 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +1 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +2 -1
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +1 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +2 -1
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +1 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +2 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +1 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +2 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +1 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +2 -1
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +1 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +2 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +1 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +2 -1
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +1 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +2 -1
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +1 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +2 -1
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +1 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +2 -1
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +1 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +2 -1
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +1 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +2 -1
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +1 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +2 -1
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +1 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +2 -1
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +1 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +2 -1
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +1 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +2 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +96 -96
- package/dist/locales/ar.json +2 -1
- package/dist/locales/de.json +2 -1
- package/dist/locales/el.json +2 -1
- package/dist/locales/en.json +2 -1
- package/dist/locales/es.json +2 -1
- package/dist/locales/fr.json +2 -1
- package/dist/locales/hi.json +2 -1
- package/dist/locales/it.json +2 -1
- package/dist/locales/ja.json +2 -1
- package/dist/locales/nl.json +2 -1
- package/dist/locales/pl.json +2 -1
- package/dist/locales/pt.json +2 -1
- package/dist/locales/ro.json +2 -1
- package/dist/locales/ru.json +2 -1
- package/dist/locales/sq.json +2 -1
- package/dist/locales/sv.json +2 -1
- package/dist/locales/tr.json +2 -1
- package/dist/locales/zh.json +2 -1
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/payment-automation-upsell/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/button-BvNtqHAS.js.map +0 -1
- package/dist/_chunks/practice-results-CKoLD_x5.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming-text-BuW7I0Zu.js","sources":["../../src/components/streaming-text/streaming-text.tsx"],"sourcesContent":["import {\n forwardRef,\n Fragment,\n useEffect,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { CodeBlock, splitCodeFences } from '../_shared/code-block';\n\nconst containerVariants = cva(\n 'type-body ds:block ds:whitespace-pre-wrap ds:break-words',\n {\n variants: {\n // Family, weight, tracking, line-height all come from `.type-body` on the base.\n // Size variants override --type-body-size to shift the ramp step.\n size: {\n sm: 'ds:[--type-body-size:var(--font-size-sm)]',\n md: '',\n lg: 'ds:[--type-body-size:var(--font-size-lg)]',\n },\n density: {\n default: '',\n compact: 'ds:[--type-body-size:var(--font-size-sm)] ds:leading-snug',\n },\n },\n defaultVariants: { size: 'md', density: 'default' },\n },\n);\n\ntype NativeProps = Omit<\n HTMLAttributes<HTMLSpanElement>,\n 'children' | 'aria-busy' | 'aria-live'\n>;\n\nexport interface StreamingTextProps\n extends NativeProps, VariantProps<typeof containerVariants> {\n /** Accumulated plain-text content. Parent appends tokens as they arrive. */\n content: string;\n /** While true the blinking cursor is shown and aria-busy is set. */\n isStreaming: boolean;\n /** When true, parse a small, safe subset of markdown (bold, inline code, line-breaks).\n * No HTML passes through; no dangerouslySetInnerHTML is ever used. */\n renderMarkdown?: boolean;\n /** Announce updates more aggressively when the streamed content is primary\n * (not wrapped by a higher-level log region). Defaults to 'polite'; never\n * set to 'assertive' for streamed output. */\n ariaLive?: 'polite' | 'off';\n}\n\n/* ------------------------------------------------------------------ */\n/* Safe, dependency-free markdown-ish renderer. */\n/* Handles **bold**, `inline code`, and newlines. Anything that looks */\n/* like HTML stays as text — no dangerouslySetInnerHTML. */\n/* ------------------------------------------------------------------ */\n\ntype Token =\n | { type: 'text'; value: string }\n | { type: 'bold'; value: string }\n | { type: 'code'; value: string }\n | { type: 'br' };\n\nfunction tokenize(input: string): Token[] {\n // Single-pass O(n) scanner. Avoids regex backtracking on `***` triples.\n const tokens: Token[] = [];\n const len = input.length;\n const STAR = 42; // '*'\n const BACKTICK = 96; // '`'\n const LF = 10; // '\\n'\n let textStart = 0;\n let i = 0;\n\n const flushText = (end: number) => {\n if (end > textStart) {\n tokens.push({ type: 'text', value: input.slice(textStart, end) });\n }\n };\n\n while (i < len) {\n const c = input.charCodeAt(i);\n\n if (c === STAR && i + 1 < len && input.charCodeAt(i + 1) === STAR) {\n // Look for closing `**`; inner content must not contain `*`.\n let j = i + 2;\n while (j < len && input.charCodeAt(j) !== STAR) j++;\n if (j < len - 1 && input.charCodeAt(j + 1) === STAR && j > i + 2) {\n flushText(i);\n tokens.push({ type: 'bold', value: input.slice(i + 2, j) });\n i = j + 2;\n textStart = i;\n continue;\n }\n i += 2;\n continue;\n }\n\n if (c === BACKTICK) {\n let j = i + 1;\n while (j < len && input.charCodeAt(j) !== BACKTICK) j++;\n if (j < len && j > i + 1) {\n flushText(i);\n tokens.push({ type: 'code', value: input.slice(i + 1, j) });\n i = j + 1;\n textStart = i;\n continue;\n }\n i += 1;\n continue;\n }\n\n if (c === LF) {\n flushText(i);\n tokens.push({ type: 'br' });\n i += 1;\n textStart = i;\n continue;\n }\n\n i += 1;\n }\n\n flushText(len);\n return tokens;\n}\n\nfunction renderInline(input: string): ReactNode {\n return tokenize(input).map((tok, i) => {\n if (tok.type === 'bold') return <strong key={i}>{tok.value}</strong>;\n if (tok.type === 'code') {\n return (\n <code\n key={i}\n dir=\"ltr\"\n className=\"ds:rounded-[var(--radius-sm)] ds:bg-muted/20 ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:font-[family-name:var(--font-mono)] ds:text-[length:0.95em]\"\n >\n {tok.value}\n </code>\n );\n }\n if (tok.type === 'br') return <br key={i} />;\n return <Fragment key={i}>{tok.value}</Fragment>;\n });\n}\n\n/**\n * Render the streamed body: split fenced code blocks out to `<CodeBlock>` and\n * run the inline tokenizer over the surrounding text. Tolerates an open fence\n * (closing ``` not yet streamed) — the prompt renders as a code block live.\n */\nfunction renderTokens(input: string): ReactNode {\n return splitCodeFences(input).map((seg, i) => {\n if (seg.type === 'code') {\n return <CodeBlock key={i} code={seg.value} language={seg.lang} />;\n }\n return <Fragment key={i}>{renderInline(seg.value)}</Fragment>;\n });\n}\n\nexport const StreamingText = forwardRef<HTMLSpanElement, StreamingTextProps>(\n (\n {\n content,\n isStreaming,\n renderMarkdown = false,\n ariaLive = 'polite',\n size = 'md',\n density = 'default',\n className,\n ...rest\n },\n ref,\n ) => {\n // Throttle visible content to at most ~10 updates per second so assistive\n // tech doesn't receive one announcement per token. We keep the full text in\n // a ref and push it to state on a timer.\n const [visible, setVisible] = useState<string>(content);\n\n useEffect(() => {\n if (!isStreaming) {\n // Streaming ended — flush immediately.\n setVisible(content);\n return;\n }\n // Global `setTimeout` works in both Node and browsers — avoid the\n // `window.` prefix so SSR (Next.js App Router, Remix) doesn't throw.\n const handle = setTimeout(() => setVisible(content), 100);\n return () => clearTimeout(handle);\n }, [content, isStreaming]);\n\n const body = renderMarkdown ? renderTokens(visible) : visible;\n\n return (\n <span\n ref={ref}\n aria-live={ariaLive}\n aria-busy={isStreaming ? true : false}\n data-component=\"streaming-text\"\n className={containerVariants({ size, density, className })}\n {...rest}\n >\n {body}\n {isStreaming ? (\n <span\n aria-hidden=\"true\"\n className={[\n 'ds:inline-block ds:align-baseline',\n 'ds:text-[color:var(--primary)]',\n 'ds:motion-safe:animate-[streaming-cursor-blink_1s_step-end_infinite]',\n 'ds:motion-reduce:opacity-100',\n 'ds:[.theme-accessible_&]:animate-none',\n 'ds:forced-colors:text-[CanvasText]',\n 'ds:ms-[1px]',\n ].join(' ')}\n >\n {'\\u258D'}\n </span>\n ) : null}\n </span>\n );\n },\n);\n\nStreamingText.displayName = 'StreamingText';\n"],"names":["containerVariants","cva","tokenize","input","tokens","len","STAR","BACKTICK","LF","textStart","i","flushText","end","c","j","renderInline","tok","jsx","Fragment","renderTokens","splitCodeFences","seg","CodeBlock","StreamingText","forwardRef","content","isStreaming","renderMarkdown","ariaLive","size","density","className","rest","ref","visible","setVisible","useState","useEffect","handle","body","jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"streaming-text-CvsjIQ7S.js","sources":["../../src/components/streaming-text/streaming-text.tsx"],"sourcesContent":["import {\n forwardRef,\n Fragment,\n useEffect,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { CodeBlock, splitCodeFences } from '../_shared/code-block';\n\nconst containerVariants = cva(\n 'type-body ds:block ds:whitespace-pre-wrap ds:break-words',\n {\n variants: {\n // Family, weight, tracking, line-height all come from `.type-body` on the base.\n // Size variants override --type-body-size to shift the ramp step.\n size: {\n sm: 'ds:[--type-body-size:var(--font-size-sm)]',\n md: '',\n lg: 'ds:[--type-body-size:var(--font-size-lg)]',\n },\n density: {\n default: '',\n compact: 'ds:[--type-body-size:var(--font-size-sm)] ds:leading-snug',\n },\n },\n defaultVariants: { size: 'md', density: 'default' },\n },\n);\n\ntype NativeProps = Omit<\n HTMLAttributes<HTMLSpanElement>,\n 'children' | 'aria-busy' | 'aria-live'\n>;\n\nexport interface StreamingTextProps\n extends NativeProps, VariantProps<typeof containerVariants> {\n /** Accumulated plain-text content. Parent appends tokens as they arrive. */\n content: string;\n /** While true the blinking cursor is shown and aria-busy is set. */\n isStreaming: boolean;\n /** When true, parse a small, safe subset of markdown (bold, inline code, line-breaks).\n * No HTML passes through; no dangerouslySetInnerHTML is ever used. */\n renderMarkdown?: boolean;\n /** Announce updates more aggressively when the streamed content is primary\n * (not wrapped by a higher-level log region). Defaults to 'polite'; never\n * set to 'assertive' for streamed output. */\n ariaLive?: 'polite' | 'off';\n}\n\n/* ------------------------------------------------------------------ */\n/* Safe, dependency-free markdown-ish renderer. */\n/* Handles **bold**, `inline code`, and newlines. Anything that looks */\n/* like HTML stays as text — no dangerouslySetInnerHTML. */\n/* ------------------------------------------------------------------ */\n\ntype Token =\n | { type: 'text'; value: string }\n | { type: 'bold'; value: string }\n | { type: 'code'; value: string }\n | { type: 'br' };\n\nfunction tokenize(input: string): Token[] {\n // Single-pass O(n) scanner. Avoids regex backtracking on `***` triples.\n const tokens: Token[] = [];\n const len = input.length;\n const STAR = 42; // '*'\n const BACKTICK = 96; // '`'\n const LF = 10; // '\\n'\n let textStart = 0;\n let i = 0;\n\n const flushText = (end: number) => {\n if (end > textStart) {\n tokens.push({ type: 'text', value: input.slice(textStart, end) });\n }\n };\n\n while (i < len) {\n const c = input.charCodeAt(i);\n\n if (c === STAR && i + 1 < len && input.charCodeAt(i + 1) === STAR) {\n // Look for closing `**`; inner content must not contain `*`.\n let j = i + 2;\n while (j < len && input.charCodeAt(j) !== STAR) j++;\n if (j < len - 1 && input.charCodeAt(j + 1) === STAR && j > i + 2) {\n flushText(i);\n tokens.push({ type: 'bold', value: input.slice(i + 2, j) });\n i = j + 2;\n textStart = i;\n continue;\n }\n i += 2;\n continue;\n }\n\n if (c === BACKTICK) {\n let j = i + 1;\n while (j < len && input.charCodeAt(j) !== BACKTICK) j++;\n if (j < len && j > i + 1) {\n flushText(i);\n tokens.push({ type: 'code', value: input.slice(i + 1, j) });\n i = j + 1;\n textStart = i;\n continue;\n }\n i += 1;\n continue;\n }\n\n if (c === LF) {\n flushText(i);\n tokens.push({ type: 'br' });\n i += 1;\n textStart = i;\n continue;\n }\n\n i += 1;\n }\n\n flushText(len);\n return tokens;\n}\n\nfunction renderInline(input: string): ReactNode {\n return tokenize(input).map((tok, i) => {\n if (tok.type === 'bold') return <strong key={i}>{tok.value}</strong>;\n if (tok.type === 'code') {\n return (\n <code\n key={i}\n dir=\"ltr\"\n className=\"ds:rounded-[var(--radius-sm)] ds:bg-muted/20 ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:font-[family-name:var(--font-mono)] ds:text-[length:0.95em]\"\n >\n {tok.value}\n </code>\n );\n }\n if (tok.type === 'br') return <br key={i} />;\n return <Fragment key={i}>{tok.value}</Fragment>;\n });\n}\n\n/**\n * Render the streamed body: split fenced code blocks out to `<CodeBlock>` and\n * run the inline tokenizer over the surrounding text. Tolerates an open fence\n * (closing ``` not yet streamed) — the prompt renders as a code block live.\n */\nfunction renderTokens(input: string): ReactNode {\n return splitCodeFences(input).map((seg, i) => {\n if (seg.type === 'code') {\n return <CodeBlock key={i} code={seg.value} language={seg.lang} />;\n }\n return <Fragment key={i}>{renderInline(seg.value)}</Fragment>;\n });\n}\n\nexport const StreamingText = forwardRef<HTMLSpanElement, StreamingTextProps>(\n (\n {\n content,\n isStreaming,\n renderMarkdown = false,\n ariaLive = 'polite',\n size = 'md',\n density = 'default',\n className,\n ...rest\n },\n ref,\n ) => {\n // Throttle visible content to at most ~10 updates per second so assistive\n // tech doesn't receive one announcement per token. We keep the full text in\n // a ref and push it to state on a timer.\n const [visible, setVisible] = useState<string>(content);\n\n useEffect(() => {\n if (!isStreaming) {\n // Streaming ended — flush immediately.\n setVisible(content);\n return;\n }\n // Global `setTimeout` works in both Node and browsers — avoid the\n // `window.` prefix so SSR (Next.js App Router, Remix) doesn't throw.\n const handle = setTimeout(() => setVisible(content), 100);\n return () => clearTimeout(handle);\n }, [content, isStreaming]);\n\n const body = renderMarkdown ? renderTokens(visible) : visible;\n\n return (\n <span\n ref={ref}\n aria-live={ariaLive}\n aria-busy={isStreaming ? true : false}\n data-component=\"streaming-text\"\n className={containerVariants({ size, density, className })}\n {...rest}\n >\n {body}\n {isStreaming ? (\n <span\n aria-hidden=\"true\"\n className={[\n 'ds:inline-block ds:align-baseline',\n 'ds:text-[color:var(--primary)]',\n 'ds:motion-safe:animate-[streaming-cursor-blink_1s_step-end_infinite]',\n 'ds:motion-reduce:opacity-100',\n 'ds:[.theme-accessible_&]:animate-none',\n 'ds:forced-colors:text-[CanvasText]',\n 'ds:ms-[1px]',\n ].join(' ')}\n >\n {'\\u258D'}\n </span>\n ) : null}\n </span>\n );\n },\n);\n\nStreamingText.displayName = 'StreamingText';\n"],"names":["containerVariants","cva","tokenize","input","tokens","len","STAR","BACKTICK","LF","textStart","i","flushText","end","c","j","renderInline","tok","jsx","Fragment","renderTokens","splitCodeFences","seg","CodeBlock","StreamingText","forwardRef","content","isStreaming","renderMarkdown","ariaLive","size","density","className","rest","ref","visible","setVisible","useState","useEffect","handle","body","jsxs"],"mappings":"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"}
|
|
@@ -2,9 +2,9 @@ import { jsx as t, jsxs as v } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as B, useRef as N, useMemo as E, useImperativeHandle as P } from "react";
|
|
3
3
|
import { c as H } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as M } from "react-i18next";
|
|
5
|
-
import { I as A } from "./icon-button-
|
|
5
|
+
import { I as A } from "./icon-button-DA2CAGHZ.js";
|
|
6
6
|
import { S as V } from "./skeleton-CZbwyJAA.js";
|
|
7
|
-
import { E as F } from "./empty-state-
|
|
7
|
+
import { E as F } from "./empty-state-X0sVPfVo.js";
|
|
8
8
|
import { T as G } from "./task-card-BUgK6yZT.js";
|
|
9
9
|
import { u as J } from "./registry-DvAUVLHh.js";
|
|
10
10
|
import { S as L } from "./square-check-big-dj0o8yA3.js";
|
|
@@ -236,4 +236,4 @@ export {
|
|
|
236
236
|
X as T,
|
|
237
237
|
U as t
|
|
238
238
|
};
|
|
239
|
-
//# sourceMappingURL=task-tray-
|
|
239
|
+
//# sourceMappingURL=task-tray-CYG6rj2s.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-tray-BT288xoM.js","sources":["../../src/components/task-tray/task-tray.agent.ts","../../src/components/task-tray/task-tray.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — TaskTray. */\n/* */\n/* Tray-level surface: read the current task ids + status, route a */\n/* `select_item` activation, and `toggle_done` / `dismiss` per task */\n/* through the curated handle. TaskTray is in-page (no open/close), */\n/* so it declares neither `open` nor `close`. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TaskTrayHandle } from './task-tray';\n\nexport const taskTrayAgent: AgentAdapter<TaskTrayHandle> = {\n id: 'task-tray',\n capabilities: ['select_single', 'dismiss'],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.taskTray.state.items',\n description:\n 'Currently-displayed tasks. Ids + status only — never task title / patient.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\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.taskTray.actions.selectItem',\n description: 'Activate the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n toggle_done: {\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n descriptionKey: 'ui.agent.taskTray.actions.toggleDone',\n description: 'Request the host to toggle the done state of a task.',\n invoke: (handle, args: { id: string }) => {\n handle.toggleDone(args.id);\n },\n },\n dismiss: {\n safety: 'destructive',\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.taskTray.actions.dismiss',\n description:\n 'Request the host to dismiss / remove the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.dismiss(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'task-tray',\n description: 'Marks the TaskTray wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific tray from the agent.',\n },\n item: {\n attr: 'data-task-id',\n description:\n 'Stable task id emitted on each rendered TaskCard inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { SquareCheckBig, Plus } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { TaskCard, type TaskItem } from '../task-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { taskTrayAgent } from './task-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst taskTrayVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-md)] ds:shadow-[var(--shadow-card)]',\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:overflow-hidden',\n ].join(' '),\n {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * Curated imperative handle for TaskTray. Exposed as the forwardRef\n * target so a future agent / MCP UI bridge can drive the tray without\n * touching the DOM. See `task-tray.agent.ts`.\n */\nexport interface TaskTrayHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n toggleDone: (id: string) => void;\n dismiss: (id: string) => void;\n}\n\nexport interface TaskTrayProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'onClick' | 'id'>,\n VariantProps<typeof taskTrayVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific tray.\n */\n id?: string;\n /** Tasks rendered inside the panel. */\n items: TaskItem[];\n /** Section title — rendered in the header. Localised by the consumer. */\n title?: string;\n /** Visual density forwarded to each TaskCard. */\n size?: 'sm' | 'md';\n /** Fires when the user activates a task (click / Enter / Space). */\n onOpenTask?: (item: TaskItem) => void;\n /** Fires when the host should toggle the done state of a task. Used by agent integration. */\n onToggleDone?: (item: TaskItem) => void;\n /** Fires when the host should dismiss / remove a task. Used by agent integration. */\n onDismissTask?: (item: TaskItem) => void;\n /** Fires when the user activates the header \"Add\" affordance. */\n onAddTask?: () => void;\n /** Localised label for the \"Add\" affordance. Defaults to `ui.taskTray.add`. */\n addLabel?: string;\n /** When true the panel renders skeleton placeholders. */\n loading?: boolean;\n /** Render an empty state when `items` is empty and `loading` is false. */\n emptyTitle?: string;\n emptyDescription?: string;\n /** Optional CTA wired into the empty state (EmptyState primaryAction). */\n emptyAction?: { label: string; onClick: () => void };\n /**\n * Pinned footer link (e.g. \"All my undone tasks (12)\"). Localised by\n * the consumer; rendered after the list, before the section closes.\n */\n viewAllLabel?: string;\n /** Fires when the footer link is activated. Required to render it. */\n onViewAll?: () => void;\n /**\n * Per-row trailing action toolbar, forwarded to each TaskCard's\n * `actions` slot.\n */\n renderItemActions?: (item: TaskItem) => ReactNode;\n /**\n * Constrain the list to the tray's own height and scroll inside it —\n * pair with a height/max-height on `className`. The scroll region is\n * keyboard-focusable so it stays operable without a pointer.\n */\n scrollable?: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const TaskTray = forwardRef<HTMLElement, TaskTrayProps>(\n (\n {\n id,\n items,\n title,\n size = 'sm',\n onOpenTask,\n onToggleDone,\n onDismissTask,\n onAddTask,\n addLabel,\n loading = false,\n emptyTitle,\n emptyDescription,\n emptyAction,\n viewAllLabel,\n onViewAll,\n renderItemActions,\n scrollable = false,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const heading = title ?? t('taskTray.title', 'Tasks');\n const resolvedAddLabel = addLabel ?? t('taskTray.add', 'Add task');\n const isEmpty = !loading && items.length === 0;\n\n let body: ReactNode;\n if (loading) {\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n {[0, 1, 2].map((i) => (\n <Skeleton key={i} variant=\"rectangular\" height=\"2.5rem\" />\n ))}\n </div>\n );\n } else if (isEmpty) {\n body = (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('taskTray.empty.title', 'No tasks yet')}\n description={\n emptyDescription ??\n t('taskTray.empty.description', 'New tasks will appear here.')\n }\n primaryAction={emptyAction}\n />\n </div>\n );\n } else {\n body = (\n <ul\n className={[\n // flex-1 unconditionally so a footer pins to the tray's\n // bottom edge in equal-height grid rows.\n 'ds:flex ds:list-none ds:flex-col ds:flex-1 ds:min-h-0',\n // Keyboard-focusable when it scrolls (axe\n // scrollable-region-focusable) — pair with a height on the\n // tray's className.\n scrollable ? 'ds:overflow-y-auto' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- scrollable list must be keyboard focusable (axe scrollable-region-focusable)\n tabIndex={scrollable ? 0 : undefined}\n aria-label={scrollable ? heading : undefined}\n >\n {items.map((item) => (\n <TaskCard\n key={item.id}\n item={item}\n size={size}\n onActivate={onOpenTask}\n actions={renderItemActions?.(item)}\n data-task-id={item.id}\n />\n ))}\n </ul>\n );\n }\n\n /* Curated imperative handle for agent integration. See\n * task-tray.agent.ts. */\n const itemsRef = useRef<TaskItem[]>(items);\n itemsRef.current = items;\n\n const handle = useMemo<TaskTrayHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenTask?.(found);\n },\n toggleDone: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onToggleDone?.(found);\n },\n dismiss: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismissTask?.(found);\n },\n }),\n [onOpenTask, onToggleDone, onDismissTask],\n );\n\n const rootRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLElement, []);\n useAgentRegistration(taskTrayAgent, handle, id);\n\n return (\n <section\n ref={rootRef}\n aria-label={heading}\n data-component=\"task-tray\"\n data-component-id={id}\n className={taskTrayVariants({ size, className })}\n {...rest}\n >\n <header className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n <h3 className=\"ds:m-0 ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-title-card\">\n <SquareCheckBig aria-hidden=\"true\" className=\"ds:size-4\" />\n {heading}\n </h3>\n {onAddTask ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={resolvedAddLabel}\n onClick={onAddTask}\n />\n ) : null}\n </header>\n {body}\n {viewAllLabel && onViewAll && !isEmpty && !loading ? (\n <footer className=\"ds:[border-block-start:var(--border-width-sm)_solid_var(--card-border)] ds:p-[var(--spacing-sm)]\">\n <button\n type=\"button\"\n onClick={onViewAll}\n className={[\n 'type-label ds:text-[color:var(--link)] ds:underline ds:underline-offset-2 ds:hover:no-underline',\n 'ds:rounded-[var(--radius-sm)] ds:min-h-[var(--min-target-size)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\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 {viewAllLabel}\n </button>\n </footer>\n ) : null}\n </section>\n );\n },\n);\n\nTaskTray.displayName = 'TaskTray';\n"],"names":["taskTrayAgent","handle","args","taskTrayVariants","cva","TaskTray","forwardRef","id","items","title","size","onOpenTask","onToggleDone","onDismissTask","onAddTask","addLabel","loading","emptyTitle","emptyDescription","emptyAction","viewAllLabel","onViewAll","renderItemActions","scrollable","className","rest","ref","t","useTranslation","heading","resolvedAddLabel","isEmpty","body","jsx","i","Skeleton","EmptyState","item","TaskCard","itemsRef","useRef","useMemo","targetId","found","rootRef","useImperativeHandle","useAgentRegistration","jsxs","SquareCheckBig","IconButton","Plus"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"task-tray-CYG6rj2s.js","sources":["../../src/components/task-tray/task-tray.agent.ts","../../src/components/task-tray/task-tray.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — TaskTray. */\n/* */\n/* Tray-level surface: read the current task ids + status, route a */\n/* `select_item` activation, and `toggle_done` / `dismiss` per task */\n/* through the curated handle. TaskTray is in-page (no open/close), */\n/* so it declares neither `open` nor `close`. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TaskTrayHandle } from './task-tray';\n\nexport const taskTrayAgent: AgentAdapter<TaskTrayHandle> = {\n id: 'task-tray',\n capabilities: ['select_single', 'dismiss'],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.taskTray.state.items',\n description:\n 'Currently-displayed tasks. Ids + status only — never task title / patient.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\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.taskTray.actions.selectItem',\n description: 'Activate the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n toggle_done: {\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n descriptionKey: 'ui.agent.taskTray.actions.toggleDone',\n description: 'Request the host to toggle the done state of a task.',\n invoke: (handle, args: { id: string }) => {\n handle.toggleDone(args.id);\n },\n },\n dismiss: {\n safety: 'destructive',\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.taskTray.actions.dismiss',\n description:\n 'Request the host to dismiss / remove the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.dismiss(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'task-tray',\n description: 'Marks the TaskTray wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific tray from the agent.',\n },\n item: {\n attr: 'data-task-id',\n description:\n 'Stable task id emitted on each rendered TaskCard inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { SquareCheckBig, Plus } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { TaskCard, type TaskItem } from '../task-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { taskTrayAgent } from './task-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst taskTrayVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-md)] ds:shadow-[var(--shadow-card)]',\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:overflow-hidden',\n ].join(' '),\n {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * Curated imperative handle for TaskTray. Exposed as the forwardRef\n * target so a future agent / MCP UI bridge can drive the tray without\n * touching the DOM. See `task-tray.agent.ts`.\n */\nexport interface TaskTrayHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n toggleDone: (id: string) => void;\n dismiss: (id: string) => void;\n}\n\nexport interface TaskTrayProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'onClick' | 'id'>,\n VariantProps<typeof taskTrayVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific tray.\n */\n id?: string;\n /** Tasks rendered inside the panel. */\n items: TaskItem[];\n /** Section title — rendered in the header. Localised by the consumer. */\n title?: string;\n /** Visual density forwarded to each TaskCard. */\n size?: 'sm' | 'md';\n /** Fires when the user activates a task (click / Enter / Space). */\n onOpenTask?: (item: TaskItem) => void;\n /** Fires when the host should toggle the done state of a task. Used by agent integration. */\n onToggleDone?: (item: TaskItem) => void;\n /** Fires when the host should dismiss / remove a task. Used by agent integration. */\n onDismissTask?: (item: TaskItem) => void;\n /** Fires when the user activates the header \"Add\" affordance. */\n onAddTask?: () => void;\n /** Localised label for the \"Add\" affordance. Defaults to `ui.taskTray.add`. */\n addLabel?: string;\n /** When true the panel renders skeleton placeholders. */\n loading?: boolean;\n /** Render an empty state when `items` is empty and `loading` is false. */\n emptyTitle?: string;\n emptyDescription?: string;\n /** Optional CTA wired into the empty state (EmptyState primaryAction). */\n emptyAction?: { label: string; onClick: () => void };\n /**\n * Pinned footer link (e.g. \"All my undone tasks (12)\"). Localised by\n * the consumer; rendered after the list, before the section closes.\n */\n viewAllLabel?: string;\n /** Fires when the footer link is activated. Required to render it. */\n onViewAll?: () => void;\n /**\n * Per-row trailing action toolbar, forwarded to each TaskCard's\n * `actions` slot.\n */\n renderItemActions?: (item: TaskItem) => ReactNode;\n /**\n * Constrain the list to the tray's own height and scroll inside it —\n * pair with a height/max-height on `className`. The scroll region is\n * keyboard-focusable so it stays operable without a pointer.\n */\n scrollable?: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const TaskTray = forwardRef<HTMLElement, TaskTrayProps>(\n (\n {\n id,\n items,\n title,\n size = 'sm',\n onOpenTask,\n onToggleDone,\n onDismissTask,\n onAddTask,\n addLabel,\n loading = false,\n emptyTitle,\n emptyDescription,\n emptyAction,\n viewAllLabel,\n onViewAll,\n renderItemActions,\n scrollable = false,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const heading = title ?? t('taskTray.title', 'Tasks');\n const resolvedAddLabel = addLabel ?? t('taskTray.add', 'Add task');\n const isEmpty = !loading && items.length === 0;\n\n let body: ReactNode;\n if (loading) {\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n {[0, 1, 2].map((i) => (\n <Skeleton key={i} variant=\"rectangular\" height=\"2.5rem\" />\n ))}\n </div>\n );\n } else if (isEmpty) {\n body = (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('taskTray.empty.title', 'No tasks yet')}\n description={\n emptyDescription ??\n t('taskTray.empty.description', 'New tasks will appear here.')\n }\n primaryAction={emptyAction}\n />\n </div>\n );\n } else {\n body = (\n <ul\n className={[\n // flex-1 unconditionally so a footer pins to the tray's\n // bottom edge in equal-height grid rows.\n 'ds:flex ds:list-none ds:flex-col ds:flex-1 ds:min-h-0',\n // Keyboard-focusable when it scrolls (axe\n // scrollable-region-focusable) — pair with a height on the\n // tray's className.\n scrollable ? 'ds:overflow-y-auto' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- scrollable list must be keyboard focusable (axe scrollable-region-focusable)\n tabIndex={scrollable ? 0 : undefined}\n aria-label={scrollable ? heading : undefined}\n >\n {items.map((item) => (\n <TaskCard\n key={item.id}\n item={item}\n size={size}\n onActivate={onOpenTask}\n actions={renderItemActions?.(item)}\n data-task-id={item.id}\n />\n ))}\n </ul>\n );\n }\n\n /* Curated imperative handle for agent integration. See\n * task-tray.agent.ts. */\n const itemsRef = useRef<TaskItem[]>(items);\n itemsRef.current = items;\n\n const handle = useMemo<TaskTrayHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenTask?.(found);\n },\n toggleDone: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onToggleDone?.(found);\n },\n dismiss: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismissTask?.(found);\n },\n }),\n [onOpenTask, onToggleDone, onDismissTask],\n );\n\n const rootRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLElement, []);\n useAgentRegistration(taskTrayAgent, handle, id);\n\n return (\n <section\n ref={rootRef}\n aria-label={heading}\n data-component=\"task-tray\"\n data-component-id={id}\n className={taskTrayVariants({ size, className })}\n {...rest}\n >\n <header className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n <h3 className=\"ds:m-0 ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-title-card\">\n <SquareCheckBig aria-hidden=\"true\" className=\"ds:size-4\" />\n {heading}\n </h3>\n {onAddTask ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={resolvedAddLabel}\n onClick={onAddTask}\n />\n ) : null}\n </header>\n {body}\n {viewAllLabel && onViewAll && !isEmpty && !loading ? (\n <footer className=\"ds:[border-block-start:var(--border-width-sm)_solid_var(--card-border)] ds:p-[var(--spacing-sm)]\">\n <button\n type=\"button\"\n onClick={onViewAll}\n className={[\n 'type-label ds:text-[color:var(--link)] ds:underline ds:underline-offset-2 ds:hover:no-underline',\n 'ds:rounded-[var(--radius-sm)] ds:min-h-[var(--min-target-size)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\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 {viewAllLabel}\n </button>\n </footer>\n ) : null}\n </section>\n );\n },\n);\n\nTaskTray.displayName = 'TaskTray';\n"],"names":["taskTrayAgent","handle","args","taskTrayVariants","cva","TaskTray","forwardRef","id","items","title","size","onOpenTask","onToggleDone","onDismissTask","onAddTask","addLabel","loading","emptyTitle","emptyDescription","emptyAction","viewAllLabel","onViewAll","renderItemActions","scrollable","className","rest","ref","t","useTranslation","heading","resolvedAddLabel","isEmpty","body","jsx","i","Skeleton","EmptyState","item","TaskCard","itemsRef","useRef","useMemo","targetId","found","rootRef","useImperativeHandle","useAgentRegistration","jsxs","SquareCheckBig","IconButton","Plus"],"mappings":"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"}
|
|
@@ -3,14 +3,14 @@ import { forwardRef as pt, useId as ge, useMemo as V, useState as h, useCallback
|
|
|
3
3
|
import { c as ft } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as mt } from "react-i18next";
|
|
5
5
|
import { B as kt } from "./badge-sTusUqZD.js";
|
|
6
|
-
import { B as ae } from "./button-
|
|
7
|
-
import { I as $ } from "./icon-button-
|
|
8
|
-
import { B as he } from "./button-group-
|
|
6
|
+
import { B as ae } from "./button-nJaPh_HC.js";
|
|
7
|
+
import { I as $ } from "./icon-button-DA2CAGHZ.js";
|
|
8
|
+
import { B as he } from "./button-group-CaxRJsNG.js";
|
|
9
9
|
import { P as gt } from "./panel-header-D313n_9-.js";
|
|
10
10
|
import { S as ve } from "./select-BW5ecXlX.js";
|
|
11
11
|
import { S as ht } from "./switch-OILsBLWo.js";
|
|
12
12
|
import { S as vt } from "./skeleton-CZbwyJAA.js";
|
|
13
|
-
import { E as ne } from "./empty-state-
|
|
13
|
+
import { E as ne } from "./empty-state-X0sVPfVo.js";
|
|
14
14
|
import { T as yt } from "./task-card-BUgK6yZT.js";
|
|
15
15
|
import { u as ye } from "./use-isomorphic-layout-effect-BGfaCOP1.js";
|
|
16
16
|
import { u as bt } from "./registry-DvAUVLHh.js";
|
|
@@ -754,4 +754,4 @@ export {
|
|
|
754
754
|
Gt as T,
|
|
755
755
|
qt as t
|
|
756
756
|
};
|
|
757
|
-
//# sourceMappingURL=tasks-panel-
|
|
757
|
+
//# sourceMappingURL=tasks-panel-Do5SFp-j.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks-panel-BBkZuejF.js","sources":["../../node_modules/lucide-react/dist/esm/icons/coins.mjs","../../node_modules/lucide-react/dist/esm/icons/gem.mjs","../../node_modules/lucide-react/dist/esm/icons/megaphone.mjs","../../node_modules/lucide-react/dist/esm/icons/tag.mjs","../../src/components/tasks-panel/tasks-panel.agent.ts","../../src/components/tasks-panel/tasks-panel.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M13.744 17.736a6 6 0 1 1-7.48-7.48\", key: \"bq4yh3\" }],\n [\"path\", { d: \"M15 6h1v4\", key: \"11y1tn\" }],\n [\"path\", { d: \"m6.134 14.768.866-.5 2 3.464\", key: \"17snzx\" }],\n [\"circle\", { cx: \"16\", cy: \"8\", r: \"6\", key: \"14bfc9\" }]\n];\nconst Coins = createLucideIcon(\"coins\", __iconNode);\n\nexport { __iconNode, Coins as default };\n//# sourceMappingURL=coins.mjs.map\n","/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10.5 3 8 9l4 13 4-13-2.5-6\", key: \"b3dvk1\" }],\n [\n \"path\",\n {\n d: \"M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z\",\n key: \"7w4byz\"\n }\n ],\n [\"path\", { d: \"M2 9h20\", key: \"16fsjt\" }]\n];\nconst Gem = createLucideIcon(\"gem\", __iconNode);\n\nexport { __iconNode, Gem as default };\n//# sourceMappingURL=gem.mjs.map\n","/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z\",\n key: \"q8bfy3\"\n }\n ],\n [\"path\", { d: \"M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14\", key: \"1853fq\" }],\n [\"path\", { d: \"M8 6v8\", key: \"15ugcq\" }]\n];\nconst Megaphone = createLucideIcon(\"megaphone\", __iconNode);\n\nexport { __iconNode, Megaphone as default };\n//# sourceMappingURL=megaphone.mjs.map\n","/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\",\n key: \"vktsd0\"\n }\n ],\n [\"circle\", { cx: \"7.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"kqv944\" }]\n];\nconst Tag = createLucideIcon(\"tag\", __iconNode);\n\nexport { __iconNode, Tag as default };\n//# sourceMappingURL=tag.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — TasksPanel. */\n/* */\n/* Rail Tasks surface: read task ids + status (never note / patient), */\n/* activate a row, toggle done / dismiss a task, re-anchor the scroll on */\n/* the overdue bucket, and drive the filter bar — all through the curated */\n/* handle. In-page within the rail panel (no open/close — the rail owns */\n/* panel open state). Mirrors taskTrayAgent's safety mapping (select=read, */\n/* toggle_done=write, dismiss=destructive) plus AppointmentTimeline's */\n/* scroll capability; the stateful filter bar adds the `filter` capability */\n/* backed by `set_filter`. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TasksPanelHandle } from './tasks-panel';\n\nexport const tasksPanelAgent: AgentAdapter<TasksPanelHandle> = {\n id: 'tasks-panel',\n // 'pick' backs select_item (non-persisting activation, matching\n // AppointmentTimeline); 'dismiss' backs dismiss; 'scroll' backs\n // jump_to_overdue (re-anchors the viewport); 'filter' backs set_filter (the\n // status / type / assignee / overdue filter bar is genuinely stateful);\n // 'view_change' backs change_scope (the patient ↔ mine segment); 'paginate'\n // backs load_more (append the next page of tasks).\n capabilities: [\n 'pick',\n 'dismiss',\n 'scroll',\n 'filter',\n 'view_change',\n 'paginate',\n ],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.tasksPanel.state.items',\n description:\n 'Currently-rendered tasks. Ids + status only — never task note / patient.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\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.tasksPanel.actions.selectItem',\n description: 'Activate the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n toggle_done: {\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n descriptionKey: 'ui.agent.tasksPanel.actions.toggleDone',\n description: 'Request the host to toggle the done state of a task.',\n invoke: (handle, args: { id: string }) => {\n handle.toggleDone(args.id);\n },\n },\n dismiss: {\n safety: 'destructive',\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.tasksPanel.actions.dismiss',\n description:\n 'Request the host to dismiss / remove the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.dismiss(args.id);\n },\n },\n jump_to_overdue: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.jumpToOverdue',\n description: 'Re-anchor the panel scroll on the overdue tasks.',\n invoke: (handle) => {\n handle.jumpToOverdue();\n },\n },\n set_filter: {\n safety: 'read',\n argsType:\n \"{ status?: 'todo' | 'done' | 'all'; type?: string | null; assignee?: string | null; overdueOnly?: boolean }\",\n argsSchema: {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['todo', 'done', 'all'] },\n type: { type: ['string', 'null'] },\n assignee: { type: ['string', 'null'] },\n overdueOnly: { type: 'boolean' },\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.setFilter',\n description:\n 'Set the task filters (status segment, type, assignee, overdue-only). Omitted keys are left unchanged.',\n invoke: (\n handle,\n args: {\n status?: 'todo' | 'done' | 'all';\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n },\n ) => {\n handle.setFilter(args);\n },\n },\n change_scope: {\n safety: 'read',\n argsType: \"{ scope: 'patient' | 'mine' }\",\n argsSchema: {\n type: 'object',\n properties: { scope: { type: 'string', enum: ['patient', 'mine'] } },\n required: ['scope'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.changeScope',\n description:\n \"Switch the task scope segment between this patient ('patient') and the operator's own tasks ('mine'). The host re-feeds the items.\",\n invoke: (handle, args: { scope: 'patient' | 'mine' }) => {\n handle.changeScope(args.scope);\n },\n },\n load_more: {\n safety: 'read',\n // Requests the host to append the next page — not idempotent (each call\n // advances the page) and reaches the host data source.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.loadMore',\n description: 'Request the host to append the next page of tasks.',\n invoke: (handle) => {\n handle.loadMore();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'tasks-panel',\n description: 'Marks the TasksPanel wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific panel from the agent.',\n },\n item: {\n attr: 'data-task-id',\n description:\n 'Stable task id emitted on each rendered TaskCard inside the panel.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n SquareCheckBig,\n Coins,\n Gem,\n ClipboardCheck,\n Megaphone,\n Pencil,\n Plus,\n Square,\n Tag,\n X,\n} from 'lucide-react';\nimport { Badge, type BadgeProps } from '../badge';\nimport { Button } from '../button';\nimport { IconButton } from '../button/icon-button';\nimport { ButtonGroup } from '../button-group';\nimport { PanelHeader } from '../panel-header';\nimport { Select } from '../select';\nimport { Switch } from '../switch';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { TaskCard, type TaskItem } from '../task-card';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { tasksPanelAgent } from './tasks-panel.agent';\n\n/* -------------------------------------------------------------------- */\n/* TasksPanel */\n/* */\n/* The Tasks tool for the Control Room rail — the next surface after */\n/* AppointmentTimeline (Appointments) and NotesPanel (Notes). It is the */\n/* rail equivalent of the in-page TaskTray: a fill-mode panel that owns */\n/* its own scroll, groups a flat task list into DUE-DATE buckets */\n/* (Overdue / Today / Tomorrow / This week / Later, with Done sunk to */\n/* the bottom), pins a filter header + per-bucket headers, and fades at */\n/* each scroll edge. Unlike AppointmentTimeline it does NOT scroll a */\n/* continuous calendar stream — platform tasks are a bounded, date-ASC */\n/* list — so there is no bidirectional infinite scroll or today-anchor, */\n/* only an optional one-way `onLoadMore`. */\n/* */\n/* Each row reuses TaskCard (no reinvention); the panel adds a coloured */\n/* type Badge (the platform's primary per-task signal) + elevation via */\n/* the card's className. All visible text flows through */\n/* useTranslation('ui') against `tasksPanel.*`; only ids + status reach */\n/* the agent adapter (no PHI). */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to the bottom edge before `onLoadMore` fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Which set of tasks the panel shows — the host owns the actual feed. */\nexport type TasksPanelScope = 'patient' | 'mine';\n\n/** Status segment value. Mirrors the platform `done` filter (default `todo`). */\nexport type TasksPanelStatusFilter = 'todo' | 'done' | 'all';\n\n/**\n * Panel-local extension of the card's `TaskItem`. The extra fields here drive\n * bucketing + filtering; the row's display fields (the typed link via\n * `linkType` + `linkedLabel`, the `assigneeLabel`, `dueLabel`) live on\n * `TaskItem` and are rendered by `TaskCard` itself. The host maps the platform\n * `DoctorReminder` → this shape — composing `title` (a summary, NOT the bare\n * type), `note`, the linked entity, the assignee, and `dueLabel`.\n */\nexport interface TasksPanelItem extends TaskItem {\n /** ISO-8601 due/scheduled instant (platform `DoctorReminder.date`). Buckets + orders the list. */\n dueIso: string;\n /** System or custom task-type key (`recall` | `payment` | `collection` | `other` | `custom-*`). Drives the type filter + badge. */\n type?: string;\n /**\n * Localised type label, required for CUSTOM types (the panel resolves system\n * keys itself). Falls back to the system label for the four known keys.\n */\n typeLabel?: string;\n /**\n * Assignee id (the platform `practiceUser`). Omit ⇒ unassigned; give pool\n * tasks a shared sentinel value (e.g. `'unassigned'`) if you want the pool\n * itself filterable. Drives the assignee FILTER (exact match); the displayed\n * name is `TaskItem.assigneeLabel`.\n */\n assignee?: string;\n /** Provenance — manual vs workflow-created. Filter only. */\n createdBy?: 'user' | 'workflow';\n}\n\n/** Curated imperative handle — identifiers + structural state only, no PHI. */\nexport interface TasksPanelHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n toggleDone: (id: string) => void;\n dismiss: (id: string) => void;\n jumpToOverdue: () => void;\n setFilter: (next: {\n status?: TasksPanelStatusFilter;\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n }) => void;\n /** Switch the task scope segment (patient ↔ mine). The host re-feeds items. */\n changeScope: (next: TasksPanelScope) => void;\n /** Request the host to append the next page of tasks (mirrors onLoadMore). */\n loadMore: () => void;\n}\n\ninterface FilterOption {\n /** Stable value passed back through the matching `on…Change`. */\n value: string;\n /** Localised label. */\n label: string;\n}\n\nexport interface TasksPanelProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Tasks to render — any order; bucketed + sorted internally (due ASC, Done last). */\n items: TasksPanelItem[];\n /** ISO-8601 \"now\" anchor — buckets + overdue compute against it. Defaults to the current instant; stories pass a fixed value. */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Tasks\". */\n title?: string;\n /** Visual density forwarded to each TaskCard. Defaults to `xs` — the compact rail row. */\n size?: 'xs' | 'sm' | 'md';\n /** Fires when a row is activated. */\n onOpenTask?: (item: TasksPanelItem) => void;\n /** Fires when the host should toggle a task's done state. */\n onToggleDone?: (item: TasksPanelItem) => void;\n /** Fires when the host should open the task editor. Omit to hide the per-row edit action. */\n onEditTask?: (item: TasksPanelItem) => void;\n /** Fires when the host should dismiss / remove a task. Omit to hide the per-row dismiss action. */\n onDismissTask?: (item: TasksPanelItem) => void;\n /** Fires when the header \"Add\" affordance is activated. Omit to hide it. */\n onAddTask?: () => void;\n /**\n * Read-only mode — hides every write affordance (toggle / edit / dismiss /\n * add). Mirrors the platform gating writes behind `practice_task_edit`.\n */\n readOnly?: boolean;\n /**\n * Per-row trailing action toolbar, forwarded to each TaskCard's `actions`\n * slot. Overrides the default toggle / edit / dismiss buttons (the type Badge\n * is always prepended by the panel). Ignored when `readOnly`.\n */\n renderItemActions?: (item: TasksPanelItem) => ReactNode;\n\n /* ----- Scope (host-driven feed switch) ----- */\n /** Controlled scope segment. */\n scope?: TasksPanelScope;\n /** Uncontrolled initial scope. Default `'patient'` when both scopes are available, else the only one. */\n defaultScope?: TasksPanelScope;\n /** Fires when the user switches scope — the host re-feeds `items`. */\n onScopeChange?: (next: TasksPanelScope) => void;\n /** Which scopes the segment offers. Omit ⇒ no scope segment (single-scope panel). */\n availableScopes?: TasksPanelScope[];\n\n /* ----- One-way pagination ----- */\n /** Load the next page — fired when the bottom edge is reached and via the footer button. */\n onLoadMore?: () => void;\n /** Whether more tasks exist. Defaults to `true` when `onLoadMore` is set. */\n hasMore?: boolean;\n /** Show the bottom loading row while the next page is fetched. */\n loadingMore?: boolean;\n /** Full-panel initial loading state (skeleton rows in the body). */\n loading?: boolean;\n /** Error surface — `true` for the default error EmptyState, or a custom node. */\n error?: boolean | ReactNode;\n\n /* ----- Filters (mirror platform TaskFilterType) ----- */\n /** Show the filter header (status segment + type / assignee selects + overdue toggle). Default `true`. */\n showFilters?: boolean;\n /** Controlled status segment. */\n statusFilter?: TasksPanelStatusFilter;\n /** Uncontrolled initial status segment. Default `'todo'` (the platform default). */\n defaultStatusFilter?: TasksPanelStatusFilter;\n onStatusFilterChange?: (next: TasksPanelStatusFilter) => void;\n /** Task types for the type filter. Omit ⇒ no type filter. */\n typeOptions?: FilterOption[];\n /** Controlled type filter (`null`/empty ⇒ all). */\n typeFilter?: string | null;\n onTypeFilterChange?: (next: string | null) => void;\n /** Assignees for the assignee filter. Pass an explicit Unassigned option if wanted. Omit ⇒ no assignee filter. */\n assigneeOptions?: FilterOption[];\n /** Controlled assignee filter (`null`/empty ⇒ anyone). */\n assigneeFilter?: string | null;\n onAssigneeFilterChange?: (next: string | null) => void;\n /** Controlled overdue-only toggle. */\n overdueOnly?: boolean;\n /** Uncontrolled initial overdue-only state. Default `false`. */\n defaultOverdueOnly?: boolean;\n onOverdueOnlyChange?: (next: boolean) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n /** CTA wired into the first-use empty state (e.g. Create task). */\n emptyAction?: { label: string; onClick: () => void };\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n {\n variants: { size: { xs: '', sm: '', md: '' } },\n defaultVariants: { size: 'xs' },\n },\n);\n\n/* Scroll region with a block-axis fade mask — identical technique to\n AppointmentTimeline, single-direction load. Disabled under reduced-motion,\n the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-md)]',\n 'ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:[--tpl-mask-top:black] ds:[--tpl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--tpl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--tpl-mask-bottom:transparent]',\n 'ds:[mask-image:linear-gradient(to_bottom,var(--tpl-mask-top)_0,black_var(--tpl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--tpl-fade-distance,var(--spacing-lg))),var(--tpl-mask-bottom)_100%)]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:[.theme-accessible_&]:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\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:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* Elevation for each reused TaskCard row — a subtle lift over the panel\n surface so rows read as raised. TaskCard owns its own border + radius.\n Uses `--shadow-sm` (not the heavier `--shadow-card`/`--shadow-lg`): the\n scroll region is `overflow-y:auto` (so `overflow-x` computes to `auto` and\n clips) with only an `--spacing-sm` gutter, and a wide 30px-blur card shadow\n gets sliced with a hard edge at that gutter. A small row shadow fits. */\nconst rowElevationClass =\n 'ds:shadow-[var(--shadow-sm)] ds:bg-[color:var(--card)]';\n\n/* -------------------------------------------------------------------- */\n/* Type → Badge variant + icon (system keys only; custom ⇒ neutral) */\n/* -------------------------------------------------------------------- */\n\nconst SYSTEM_TYPE_META: Record<\n string,\n { variant: NonNullable<BadgeProps['variant']>; Icon: typeof Tag }\n> = {\n recall: { variant: 'info', Icon: Megaphone },\n payment: { variant: 'warning', Icon: Gem },\n collection: { variant: 'error', Icon: Coins },\n other: { variant: 'neutral', Icon: Tag },\n};\n\n/* -------------------------------------------------------------------- */\n/* Due-bucket grouping */\n/* -------------------------------------------------------------------- */\n\ntype BucketKey =\n | 'overdue'\n | 'today'\n | 'tomorrow'\n | 'thisWeek'\n | 'later'\n | 'done';\n\nconst BUCKET_ORDER: BucketKey[] = [\n 'overdue',\n 'today',\n 'tomorrow',\n 'thisWeek',\n 'later',\n 'done',\n];\n\ninterface Bucket {\n key: BucketKey;\n items: TasksPanelItem[];\n}\n\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/** Boundary timestamps the buckets + the overdue notion are computed against. */\nfunction dayBoundaries(now: Date) {\n const today = startOfDay(now);\n const tomorrow = new Date(today);\n tomorrow.setDate(today.getDate() + 1);\n const dayAfter = new Date(today);\n dayAfter.setDate(today.getDate() + 2);\n // Monday-based week — start of NEXT week is the upper bound of \"This week\".\n const dow = (today.getDay() + 6) % 7;\n const nextWeek = new Date(today);\n nextWeek.setDate(today.getDate() + (7 - dow));\n return {\n startOfToday: +today,\n startOfTomorrow: +tomorrow,\n startOfDayAfter: +dayAfter,\n startOfNextWeek: +nextWeek,\n };\n}\n\nfunction bucketFor(item: TasksPanelItem, now: Date): BucketKey {\n if (item.status === 'done') return 'done';\n const { startOfToday, startOfTomorrow, startOfDayAfter, startOfNextWeek } =\n dayBoundaries(now);\n const due = +new Date(item.dueIso);\n if (due < startOfToday) return 'overdue';\n if (due < startOfTomorrow) return 'today';\n if (due < startOfDayAfter) return 'tomorrow';\n if (due < startOfNextWeek) return 'thisWeek';\n return 'later';\n}\n\n/** A task is overdue when it is not done and due before tomorrow (platform notion). */\nfunction isOverdue(item: TasksPanelItem, now: Date): boolean {\n if (item.status === 'done') return false;\n return +new Date(item.dueIso) < dayBoundaries(now).startOfTomorrow;\n}\n\nfunction groupByDueBucket(items: TasksPanelItem[], now: Date): Bucket[] {\n const map = new Map<BucketKey, TasksPanelItem[]>();\n for (const item of items) {\n const key = bucketFor(item, now);\n const list = map.get(key);\n if (list) list.push(item);\n else map.set(key, [item]);\n }\n const buckets: Bucket[] = [];\n for (const key of BUCKET_ORDER) {\n const list = map.get(key);\n if (!list || list.length === 0) continue;\n // Due ASC (most-overdue-first), mirroring the platform's ORDER BY date ASC.\n list.sort((a, b) => +new Date(a.dueIso) - +new Date(b.dueIso));\n buckets.push({ key, items: list });\n }\n return buckets;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const TasksPanel = forwardRef<HTMLElement, TasksPanelProps>(\n (\n {\n id,\n items,\n nowIso,\n title,\n size = 'xs',\n onOpenTask,\n onToggleDone,\n onEditTask,\n onDismissTask,\n onAddTask,\n readOnly = false,\n renderItemActions,\n scope,\n defaultScope,\n onScopeChange,\n availableScopes,\n onLoadMore,\n hasMore,\n loadingMore = false,\n loading = false,\n error = false,\n showFilters = true,\n statusFilter,\n defaultStatusFilter,\n onStatusFilterChange,\n typeOptions,\n typeFilter,\n onTypeFilterChange,\n assigneeOptions,\n assigneeFilter,\n onAssigneeFilterChange,\n overdueOnly,\n defaultOverdueOnly,\n onOverdueOnlyChange,\n emptyTitle,\n emptyDescription,\n emptyAction,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const headingId = useId();\n const overdueSwitchId = useId();\n const heading = title ?? t('tasksPanel.title');\n\n // Static key lookups — every label is a literal `t()` call so the i18n\n // coverage gate can see each key (template-literal keys are invisible to it).\n const statusLabels: Record<TasksPanelStatusFilter, string> = {\n todo: t('tasksPanel.status.todo'),\n done: t('tasksPanel.status.done'),\n all: t('tasksPanel.status.all'),\n };\n const scopeLabels: Record<TasksPanelScope, string> = {\n patient: t('tasksPanel.scope.patient'),\n mine: t('tasksPanel.scope.mine'),\n };\n const bucketLabels: Record<BucketKey, string> = {\n overdue: t('tasksPanel.buckets.overdue'),\n today: t('tasksPanel.buckets.today'),\n tomorrow: t('tasksPanel.buckets.tomorrow'),\n thisWeek: t('tasksPanel.buckets.thisWeek'),\n later: t('tasksPanel.buckets.later'),\n done: t('tasksPanel.buckets.done'),\n };\n const systemTypeLabels: Record<string, string> = {\n recall: t('tasksPanel.types.recall'),\n payment: t('tasksPanel.types.payment'),\n collection: t('tasksPanel.types.collection'),\n other: t('tasksPanel.types.other'),\n };\n\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n /* ----- Controlled / uncontrolled filter + scope state ----- */\n const [scopeState, setScopeState] = useState<TasksPanelScope>(\n defaultScope ?? availableScopes?.[0] ?? 'patient',\n );\n const currentScope = scope ?? scopeState;\n const changeScope = useCallback(\n (next: TasksPanelScope) => {\n if (scope === undefined) setScopeState(next);\n onScopeChange?.(next);\n },\n [scope, onScopeChange],\n );\n\n const [statusState, setStatusState] = useState<TasksPanelStatusFilter>(\n defaultStatusFilter ?? 'todo',\n );\n const currentStatus = statusFilter ?? statusState;\n const changeStatus = useCallback(\n (next: TasksPanelStatusFilter) => {\n if (statusFilter === undefined) setStatusState(next);\n onStatusFilterChange?.(next);\n },\n [statusFilter, onStatusFilterChange],\n );\n\n const [typeState, setTypeState] = useState<string | null>(null);\n const currentType = typeFilter !== undefined ? typeFilter : typeState;\n const changeType = useCallback(\n (next: string | null) => {\n if (typeFilter === undefined) setTypeState(next);\n onTypeFilterChange?.(next);\n },\n [typeFilter, onTypeFilterChange],\n );\n\n const [assigneeState, setAssigneeState] = useState<string | null>(null);\n const currentAssignee =\n assigneeFilter !== undefined ? assigneeFilter : assigneeState;\n const changeAssignee = useCallback(\n (next: string | null) => {\n if (assigneeFilter === undefined) setAssigneeState(next);\n onAssigneeFilterChange?.(next);\n },\n [assigneeFilter, onAssigneeFilterChange],\n );\n\n const [overdueState, setOverdueState] = useState<boolean>(\n defaultOverdueOnly ?? false,\n );\n const currentOverdueOnly = overdueOnly ?? overdueState;\n const changeOverdueOnly = useCallback(\n (next: boolean) => {\n if (overdueOnly === undefined) setOverdueState(next);\n onOverdueOnlyChange?.(next);\n },\n [overdueOnly, onOverdueOnlyChange],\n );\n\n const clearFilters = useCallback(() => {\n changeStatus('todo');\n changeType(null);\n changeAssignee(null);\n changeOverdueOnly(false);\n }, [changeStatus, changeType, changeAssignee, changeOverdueOnly]);\n\n /* ----- Filter → bucket ----- */\n const visible = useMemo(() => {\n return items.filter((item) => {\n const isDone = item.status === 'done';\n if (currentStatus === 'todo' && isDone) return false;\n if (currentStatus === 'done' && !isDone) return false;\n if (currentType && item.type !== currentType) return false;\n if (currentAssignee) {\n const assignee = item.assignee ?? '';\n if (assignee !== currentAssignee) return false;\n }\n if (currentOverdueOnly && !isOverdue(item, now)) return false;\n return true;\n });\n }, [\n items,\n currentStatus,\n currentType,\n currentAssignee,\n currentOverdueOnly,\n now,\n ]);\n\n const buckets = useMemo(\n () => groupByDueBucket(visible, now),\n [visible, now],\n );\n\n /* ----- Scroll region: edge fades + one-way load-more ----- */\n const scrollRef = useRef<HTMLDivElement>(null);\n const overdueHeaderRef = useRef<HTMLElement | null>(null);\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n updateEdges();\n }, [buckets, updateEdges]);\n\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n const moreAvailable = hasMore ?? !!onLoadMore;\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadMore &&\n moreAvailable &&\n !loadingMore &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadMore();\n }\n }, [updateEdges, onLoadMore, moreAvailable, loadingMore]);\n\n const jumpToOverdue = useCallback(() => {\n const region = scrollRef.current;\n const el = overdueHeaderRef.current;\n if (!region || !el) {\n region?.scrollTo({ top: 0 });\n return;\n }\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({ top: region.scrollTop + delta });\n }, []);\n\n /* ----- Agent handle ----- */\n const itemsRef = useRef<TasksPanelItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<TasksPanelHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n })),\n selectItem: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenTask?.(found);\n },\n toggleDone: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onToggleDone?.(found);\n },\n dismiss: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismissTask?.(found);\n },\n jumpToOverdue,\n setFilter: (next) => {\n if (next.status !== undefined) changeStatus(next.status);\n if (next.type !== undefined) changeType(next.type);\n if (next.assignee !== undefined) changeAssignee(next.assignee);\n if (next.overdueOnly !== undefined)\n changeOverdueOnly(next.overdueOnly);\n },\n changeScope,\n loadMore: () => onLoadMore?.(),\n }),\n [\n onOpenTask,\n onToggleDone,\n onDismissTask,\n jumpToOverdue,\n changeStatus,\n changeType,\n changeAssignee,\n changeOverdueOnly,\n changeScope,\n onLoadMore,\n ],\n );\n useAgentRegistration(tasksPanelAgent, handle, id);\n\n /* ----- Row rendering ----- */\n const renderTypeBadge = (item: TasksPanelItem): ReactNode => {\n if (!item.type) return null;\n const meta = SYSTEM_TYPE_META[item.type];\n const variant = meta?.variant ?? 'neutral';\n const Icon = meta?.Icon ?? Tag;\n const label = item.typeLabel ?? systemTypeLabels[item.type] ?? item.type;\n return (\n <Badge\n variant={variant}\n size=\"sm\"\n leading={<Icon aria-hidden=\"true\" />}\n >\n {label}\n </Badge>\n );\n };\n\n const defaultActions = (item: TasksPanelItem): ReactNode => {\n if (readOnly) return null;\n const done = item.status === 'done';\n return (\n <>\n {onToggleDone ? (\n <IconButton\n icon={done ? <SquareCheckBig /> : <Square />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t(\n done ? 'tasksPanel.markNotDone' : 'tasksPanel.markDone',\n )}\n onClick={() => onToggleDone(item)}\n />\n ) : null}\n {onEditTask ? (\n <IconButton\n icon={<Pencil />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.edit')}\n onClick={() => onEditTask(item)}\n />\n ) : null}\n {onDismissTask ? (\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.dismiss')}\n onClick={() => onDismissTask(item)}\n />\n ) : null}\n </>\n );\n };\n\n const renderRowActions = (item: TasksPanelItem): ReactNode => {\n const custom = !readOnly ? renderItemActions?.(item) : null;\n const trailing = custom ?? defaultActions(item);\n const badge = renderTypeBadge(item);\n if (!badge && !trailing) return undefined;\n return (\n <>\n {badge}\n {trailing}\n </>\n );\n };\n\n /* ----- Body branches ----- */\n const isFirstUseEmpty = !loading && !error && items.length === 0;\n const isFilteredEmpty =\n !loading && !error && items.length > 0 && visible.length === 0;\n\n const skeletonRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n let body: ReactNode;\n if (error) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n {typeof error === 'boolean' ? (\n <EmptyState\n variant=\"error\"\n size=\"sm\"\n title={t('tasksPanel.error.title')}\n description={t('tasksPanel.error.description')}\n />\n ) : (\n error\n )}\n </div>\n );\n } else if (loading) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {[0, 1, 2, 3].map((i) => skeletonRow(`skeleton-${i}`))}\n </div>\n );\n } else if (isFirstUseEmpty) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('tasksPanel.empty.title')}\n description={emptyDescription ?? t('tasksPanel.empty.description')}\n primaryAction={emptyAction}\n />\n </div>\n );\n } else if (isFilteredEmpty) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"no-results\"\n size=\"sm\"\n title={t('tasksPanel.filteredEmpty.title')}\n description={t('tasksPanel.filteredEmpty.description')}\n primaryAction={{\n label: t('tasksPanel.filteredEmpty.clear'),\n onClick: clearFilters,\n }}\n />\n </div>\n );\n } else {\n body = (\n <div\n ref={scrollRef}\n // The scroll region must be keyboard-focusable so arrow / Home / End\n // can drive it (axe scrollable-region-focusable).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n <ol className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\">\n {buckets.map((bucket) => (\n <li\n key={bucket.key}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <BucketHeader\n bucketKey={bucket.key}\n count={bucket.items.length}\n label={bucketLabels[bucket.key]}\n headerRef={\n bucket.key === 'overdue' ? overdueHeaderRef : undefined\n }\n />\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\">\n {bucket.items.map((item) => (\n <TaskCard\n key={item.id}\n item={item}\n size={size}\n onActivate={\n onOpenTask ? () => onOpenTask(item) : undefined\n }\n actions={renderRowActions(item)}\n className={rowElevationClass}\n data-task-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingMore ? skeletonRow('loading-more') : null}\n {!loadingMore && moreAvailable && onLoadMore ? (\n <div className=\"ds:flex ds:justify-center ds:py-[var(--spacing-sm)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={onLoadMore}>\n {t('tasksPanel.loadMore')}\n </Button>\n </div>\n ) : null}\n </div>\n );\n }\n\n /* ----- Filter header ----- */\n const showScopeSegment = (availableScopes?.length ?? 0) > 1;\n const statusValues: TasksPanelStatusFilter[] = ['todo', 'done', 'all'];\n\n // Add-task affordance lives in the PanelHeader action cluster (inline-end of\n // the title row); the rail injects the favourite / close after it.\n const headerActions =\n onAddTask && !readOnly ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={t('tasksPanel.add')}\n onClick={onAddTask}\n />\n ) : undefined;\n\n // Scope segment + filter controls share the PanelHeader filters row, stacked\n // so the scope segment keeps its own line above the filter cluster.\n const headerFilters =\n showScopeSegment || showFilters ? (\n <div className=\"ds:flex ds:w-full ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {showScopeSegment ? (\n <ButtonGroup label={t('tasksPanel.scope.label')}>\n {availableScopes!.map((value) => {\n const active = currentScope === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n onClick={() => changeScope(value)}\n >\n {scopeLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n ) : null}\n\n {showFilters ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n <ButtonGroup label={t('tasksPanel.status.label')}>\n {statusValues.map((value) => {\n const active = currentStatus === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n onClick={() => changeStatus(value)}\n >\n {statusLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n\n {typeOptions && typeOptions.length > 0 ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.type.label')}\n placeholder={t('tasksPanel.type.placeholder')}\n options={typeOptions}\n value={currentType ?? ''}\n onValueChange={(value) => changeType(value || null)}\n />\n ) : null}\n\n {assigneeOptions && assigneeOptions.length > 0 ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.assignee.label')}\n placeholder={t('tasksPanel.assignee.placeholder')}\n options={assigneeOptions}\n value={currentAssignee ?? ''}\n onValueChange={(value) => changeAssignee(value || null)}\n />\n ) : null}\n\n <Switch\n id={overdueSwitchId}\n size=\"sm\"\n label={t('tasksPanel.overdueOnly')}\n checked={currentOverdueOnly}\n onCheckedChange={changeOverdueOnly}\n />\n </div>\n ) : null}\n </div>\n ) : undefined;\n\n return (\n <section\n ref={innerRef}\n data-component=\"tasks-panel\"\n data-component-id={id}\n aria-labelledby={ariaLabel ? undefined : headingId}\n aria-label={ariaLabel}\n className={rootVariants({ size, className })}\n {...rest}\n >\n <PanelHeader\n title={heading}\n icon={<ClipboardCheck />}\n headingId={headingId}\n actions={headerActions}\n filters={headerFilters}\n />\n\n {body}\n </section>\n );\n },\n);\n\nTasksPanel.displayName = 'TasksPanel';\n\n/* -------------------------------------------------------------------- */\n/* Bucket header — sticky label per due bucket */\n/* -------------------------------------------------------------------- */\n\ninterface BucketHeaderProps {\n bucketKey: BucketKey;\n count: number;\n label: string;\n headerRef?: React.MutableRefObject<HTMLElement | null>;\n}\n\nfunction BucketHeader({\n bucketKey,\n count,\n label,\n headerRef,\n}: BucketHeaderProps): ReactNode {\n // Overdue is tinted destructive, Today brand (+ a decorative leading dot);\n // both clear AA on the --card surface in every theme (verified via axe on the\n // stories). z-[2] sits ABOVE the reused TaskCard's z-[1] action overlay so the\n // sticky header is never painted under a card scrolling beneath it.\n const tone =\n bucketKey === 'overdue'\n ? 'ds:text-[color:var(--destructive)] ds:font-semibold'\n : bucketKey === 'today'\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]';\n return (\n <div\n ref={headerRef as React.Ref<HTMLDivElement>}\n data-bucket={bucketKey}\n className={[\n 'ds:sticky ds:top-0 ds:z-[2] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n tone,\n ].join(' ')}\n >\n {bucketKey === 'today' ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n <span className=\"ds:text-[color:var(--muted-foreground)]\">\n {`(${count})`}\n </span>\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type TasksPanelSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["__iconNode","Coins","createLucideIcon","Gem","Megaphone","Tag","tasksPanelAgent","handle","args","EDGE_LOAD_THRESHOLD","rootVariants","cva","scrollRegionClasses","rowElevationClass","SYSTEM_TYPE_META","BUCKET_ORDER","startOfDay","d","dayBoundaries","now","today","tomorrow","dayAfter","dow","nextWeek","bucketFor","item","startOfToday","startOfTomorrow","startOfDayAfter","startOfNextWeek","due","isOverdue","groupByDueBucket","items","map","key","list","buckets","a","b","TasksPanel","forwardRef","id","nowIso","title","size","onOpenTask","onToggleDone","onEditTask","onDismissTask","onAddTask","readOnly","renderItemActions","scope","defaultScope","onScopeChange","availableScopes","onLoadMore","hasMore","loadingMore","loading","error","showFilters","statusFilter","defaultStatusFilter","onStatusFilterChange","typeOptions","typeFilter","onTypeFilterChange","assigneeOptions","assigneeFilter","onAssigneeFilterChange","overdueOnly","defaultOverdueOnly","onOverdueOnlyChange","emptyTitle","emptyDescription","emptyAction","className","ariaLabel","rest","ref","t","useTranslation","headingId","useId","overdueSwitchId","heading","statusLabels","scopeLabels","bucketLabels","systemTypeLabels","useMemo","scopeState","setScopeState","useState","currentScope","changeScope","useCallback","next","statusState","setStatusState","currentStatus","changeStatus","typeState","setTypeState","currentType","changeType","assigneeState","setAssigneeState","currentAssignee","changeAssignee","overdueState","setOverdueState","currentOverdueOnly","changeOverdueOnly","clearFilters","visible","isDone","scrollRef","useRef","overdueHeaderRef","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","region","scrollTop","scrollHeight","clientHeight","useIsomorphicLayoutEffect","observer","moreAvailable","handleScroll","jumpToOverdue","el","delta","itemsRef","innerRef","useImperativeHandle","i","targetId","found","useAgentRegistration","renderTypeBadge","meta","variant","Icon","label","jsx","Badge","defaultActions","done","jsxs","Fragment","IconButton","SquareCheckBig","Square","Pencil","X","renderRowActions","trailing","badge","isFirstUseEmpty","isFilteredEmpty","skeletonRow","Skeleton","body","EmptyState","bucket","BucketHeader","TaskCard","Button","showScopeSegment","statusValues","headerActions","Plus","headerFilters","ButtonGroup","value","active","Select","Switch","PanelHeader","ClipboardCheck","bucketKey","count","headerRef"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,KAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,sCAAsC,KAAK,SAAQ,CAAE;AAAA,EACnE,CAAC,QAAQ,EAAE,GAAG,aAAa,KAAK,SAAQ,CAAE;AAAA,EAC1C,CAAC,QAAQ,EAAE,GAAG,gCAAgC,KAAK,SAAQ,CAAE;AAAA,EAC7D,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,SAAQ,CAAE;AACzD,GACMC,KAAQC,EAAiB,SAASF,EAAU;ACflD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,KAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,+BAA+B,KAAK,SAAQ,CAAE;AAAA,EAC5D;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAC1C,GACMG,KAAMD,EAAiB,OAAOF,EAAU;ACpB9C;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,KAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,+DAA+D,KAAK,SAAQ,CAAE;AAAA,EAC5F,CAAC,QAAQ,EAAE,GAAG,UAAU,KAAK,SAAQ,CAAE;AACzC,GACMI,KAAYF,EAAiB,aAAaF,EAAU;ACpB1D;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,KAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,UAAU,EAAE,IAAI,OAAO,IAAI,OAAO,GAAG,MAAM,MAAM,gBAAgB,KAAK,SAAQ,CAAE;AACnF,GACMK,KAAMH,EAAiB,OAAOF,EAAU,GCHjCM,KAAkD;AAAA,EAC7D,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOJ,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,OAAO;AAAA,IACL,OAAO;AAAA,MACL,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,MAAM,CAACC,MAAWA,EAAO,SAAA;AAAA,IAAS;AAAA,EACpC;AAAA,EAEF,SAAS;AAAA,IACP,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAI,EAAE,MAAM,WAAS;AAAA,QACnC,UAAU,CAAC,IAAI;AAAA,MAAA;AAAA,MAEjB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACA,GAAQC,MAAyB;AACxC,QAAAD,EAAO,WAAWC,EAAK,EAAE;AAAA,MAC3B;AAAA,IAAA;AAAA,IAEF,aAAa;AAAA,MACX,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAI,EAAE,MAAM,WAAS;AAAA,QACnC,UAAU,CAAC,IAAI;AAAA,MAAA;AAAA,MAEjB,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACD,GAAQC,MAAyB;AACxC,QAAAD,EAAO,WAAWC,EAAK,EAAE;AAAA,MAC3B;AAAA,IAAA;AAAA,IAEF,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,IAAI,EAAE,MAAM,WAAS;AAAA,QACnC,UAAU,CAAC,IAAI;AAAA,MAAA;AAAA,MAEjB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,QAAQ,CAACD,GAAQC,MAAyB;AACxC,QAAAD,EAAO,QAAQC,EAAK,EAAE;AAAA,MACxB;AAAA,IAAA;AAAA,IAEF,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACD,MAAW;AAClB,QAAAA,EAAO,cAAA;AAAA,MACT;AAAA,IAAA;AAAA,IAEF,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,UACE;AAAA,MACF,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,QAAQ,QAAQ,KAAK,EAAA;AAAA,UACtD,MAAM,EAAE,MAAM,CAAC,UAAU,MAAM,EAAA;AAAA,UAC/B,UAAU,EAAE,MAAM,CAAC,UAAU,MAAM,EAAA;AAAA,UACnC,aAAa,EAAE,MAAM,UAAA;AAAA,QAAU;AAAA,MACjC;AAAA,MAEF,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,QAAQ,CACNA,GACAC,MAMG;AACH,QAAAD,EAAO,UAAUC,CAAI;AAAA,MACvB;AAAA,IAAA;AAAA,IAEF,cAAc;AAAA,MACZ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,MAAM,CAAC,WAAW,MAAM,IAAE;AAAA,QACjE,UAAU,CAAC,OAAO;AAAA,MAAA;AAAA,MAEpB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,QAAQ,CAACD,GAAQC,MAAwC;AACvD,QAAAD,EAAO,YAAYC,EAAK,KAAK;AAAA,MAC/B;AAAA,IAAA;AAAA,IAEF,WAAW;AAAA,MACT,QAAQ;AAAA;AAAA;AAAA,MAGR,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,QAAQ,CAACD,MAAW;AAClB,QAAAA,EAAO,SAAA;AAAA,MACT;AAAA,IAAA;AAAA,EACF;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,IAAA;AAAA,IAEf,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,aACE;AAAA,IAAA;AAAA,IAEJ,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,aACE;AAAA,IAAA;AAAA,EACJ;AAEJ,GC9GME,KAAsB,IAmKtBC,KAAeC;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU,EAAE,MAAM,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,KAAG;AAAA,IAC3C,iBAAiB,EAAE,MAAM,KAAA;AAAA,EAAK;AAElC,GAKMC,KAAsB;AAAA,EAC1B;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,EAAE,KAAK,GAAG,GAQJC,KACJ,0DAMIC,KAGF;AAAA,EACF,QAAQ,EAAE,SAAS,QAAQ,MAAMV,GAAA;AAAA,EACjC,SAAS,EAAE,SAAS,WAAW,MAAMD,GAAA;AAAA,EACrC,YAAY,EAAE,SAAS,SAAS,MAAMF,GAAA;AAAA,EACtC,OAAO,EAAE,SAAS,WAAW,MAAMI,GAAA;AACrC,GAcMU,KAA4B;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOA,SAASC,GAAWC,GAAe;AACjC,SAAO,IAAI,KAAKA,EAAE,YAAA,GAAeA,EAAE,SAAA,GAAYA,EAAE,SAAS;AAC5D;AAGA,SAASC,GAAcC,GAAW;AAChC,QAAMC,IAAQJ,GAAWG,CAAG,GACtBE,IAAW,IAAI,KAAKD,CAAK;AAC/B,EAAAC,EAAS,QAAQD,EAAM,QAAA,IAAY,CAAC;AACpC,QAAME,IAAW,IAAI,KAAKF,CAAK;AAC/B,EAAAE,EAAS,QAAQF,EAAM,QAAA,IAAY,CAAC;AAEpC,QAAMG,KAAOH,EAAM,OAAA,IAAW,KAAK,GAC7BI,IAAW,IAAI,KAAKJ,CAAK;AAC/B,SAAAI,EAAS,QAAQJ,EAAM,QAAA,KAAa,IAAIG,EAAI,GACrC;AAAA,IACL,cAAc,CAACH;AAAA,IACf,iBAAiB,CAACC;AAAA,IAClB,iBAAiB,CAACC;AAAA,IAClB,iBAAiB,CAACE;AAAA,EAAA;AAEtB;AAEA,SAASC,GAAUC,GAAsBP,GAAsB;AAC7D,MAAIO,EAAK,WAAW,OAAQ,QAAO;AACnC,QAAM,EAAE,cAAAC,GAAc,iBAAAC,GAAiB,iBAAAC,GAAiB,iBAAAC,EAAA,IACtDZ,GAAcC,CAAG,GACbY,IAAM,CAAC,IAAI,KAAKL,EAAK,MAAM;AACjC,SAAIK,IAAMJ,IAAqB,YAC3BI,IAAMH,IAAwB,UAC9BG,IAAMF,IAAwB,aAC9BE,IAAMD,IAAwB,aAC3B;AACT;AAGA,SAASE,GAAUN,GAAsBP,GAAoB;AAC3D,SAAIO,EAAK,WAAW,SAAe,KAC5B,CAAC,IAAI,KAAKA,EAAK,MAAM,IAAIR,GAAcC,CAAG,EAAE;AACrD;AAEA,SAASc,GAAiBC,GAAyBf,GAAqB;AACtE,QAAMgB,wBAAU,IAAA;AAChB,aAAWT,KAAQQ,GAAO;AACxB,UAAME,IAAMX,GAAUC,GAAMP,CAAG,GACzBkB,IAAOF,EAAI,IAAIC,CAAG;AACxB,IAAIC,IAAMA,EAAK,KAAKX,CAAI,IACnBS,EAAI,IAAIC,GAAK,CAACV,CAAI,CAAC;AAAA,EAC1B;AACA,QAAMY,IAAoB,CAAA;AAC1B,aAAWF,KAAOrB,IAAc;AAC9B,UAAMsB,IAAOF,EAAI,IAAIC,CAAG;AACxB,IAAI,CAACC,KAAQA,EAAK,WAAW,MAE7BA,EAAK,KAAK,CAACE,GAAGC,MAAM,CAAC,IAAI,KAAKD,EAAE,MAAM,IAAI,CAAC,IAAI,KAAKC,EAAE,MAAM,CAAC,GAC7DF,EAAQ,KAAK,EAAE,KAAAF,GAAK,OAAOC,GAAM;AAAA,EACnC;AACA,SAAOC;AACT;AAMO,MAAMG,KAAaC;AAAA,EACxB,CACE;AAAA,IACE,IAAAC;AAAA,IACA,OAAAT;AAAA,IACA,QAAAU;AAAA,IACA,OAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,YAAAC;AAAA,IACA,cAAAC;AAAA,IACA,YAAAC;AAAA,IACA,eAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,mBAAAC;AAAA,IACA,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,eAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,SAAAC;AAAA,IACA,aAAAC,IAAc;AAAA,IACd,SAAAC,IAAU;AAAA,IACV,OAAAC,IAAQ;AAAA,IACR,aAAAC,KAAc;AAAA,IACd,cAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,YAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,wBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,WAAAC;AAAA,IACA,cAAcC;AAAA,IACd,GAAGC;AAAA,EAAA,GAELC,OACG;AACH,UAAM,EAAE,GAAAC,EAAA,IAAMC,GAAA,GACRC,KAAYC,GAAA,GACZC,KAAkBD,GAAA,GAClBE,KAAU3C,KAASsC,EAAE,kBAAkB,GAIvCM,KAAuD;AAAA,MAC3D,MAAMN,EAAE,wBAAwB;AAAA,MAChC,MAAMA,EAAE,wBAAwB;AAAA,MAChC,KAAKA,EAAE,uBAAuB;AAAA,IAAA,GAE1BO,KAA+C;AAAA,MACnD,SAASP,EAAE,0BAA0B;AAAA,MACrC,MAAMA,EAAE,uBAAuB;AAAA,IAAA,GAE3BQ,KAA0C;AAAA,MAC9C,SAASR,EAAE,4BAA4B;AAAA,MACvC,OAAOA,EAAE,0BAA0B;AAAA,MACnC,UAAUA,EAAE,6BAA6B;AAAA,MACzC,UAAUA,EAAE,6BAA6B;AAAA,MACzC,OAAOA,EAAE,0BAA0B;AAAA,MACnC,MAAMA,EAAE,yBAAyB;AAAA,IAAA,GAE7BS,KAA2C;AAAA,MAC/C,QAAQT,EAAE,yBAAyB;AAAA,MACnC,SAASA,EAAE,0BAA0B;AAAA,MACrC,YAAYA,EAAE,6BAA6B;AAAA,MAC3C,OAAOA,EAAE,wBAAwB;AAAA,IAAA,GAG7BhE,IAAM0E;AAAA,MACV,MAAOjD,IAAS,IAAI,KAAKA,CAAM,wBAAQ,KAAA;AAAA,MACvC,CAACA,CAAM;AAAA,IAAA,GAIH,CAACkD,IAAYC,EAAa,IAAIC;AAAA,MAClCzC,OAAgBE,KAAA,gBAAAA,EAAkB,OAAM;AAAA,IAAA,GAEpCwC,KAAe3C,KAASwC,IACxBI,IAAcC;AAAA,MAClB,CAACC,MAA0B;AACzB,QAAI9C,MAAU,UAAWyC,GAAcK,CAAI,GAC3C5C,KAAA,QAAAA,EAAgB4C;AAAA,MAClB;AAAA,MACA,CAAC9C,GAAOE,CAAa;AAAA,IAAA,GAGjB,CAAC6C,IAAaC,EAAc,IAAIN;AAAA,MACpC/B,MAAuB;AAAA,IAAA,GAEnBsC,IAAgBvC,KAAgBqC,IAChCG,IAAeL;AAAA,MACnB,CAACC,MAAiC;AAChC,QAAIpC,MAAiB,UAAWsC,GAAeF,CAAI,GACnDlC,KAAA,QAAAA,EAAuBkC;AAAA,MACzB;AAAA,MACA,CAACpC,GAAcE,CAAoB;AAAA,IAAA,GAG/B,CAACuC,IAAWC,EAAY,IAAIV,EAAwB,IAAI,GACxDW,IAAcvC,MAAe,SAAYA,IAAaqC,IACtDG,IAAaT;AAAA,MACjB,CAACC,MAAwB;AACvB,QAAIhC,MAAe,UAAWsC,GAAaN,CAAI,GAC/C/B,KAAA,QAAAA,EAAqB+B;AAAA,MACvB;AAAA,MACA,CAAChC,GAAYC,CAAkB;AAAA,IAAA,GAG3B,CAACwC,IAAeC,EAAgB,IAAId,EAAwB,IAAI,GAChEe,IACJxC,MAAmB,SAAYA,IAAiBsC,IAC5CG,IAAiBb;AAAA,MACrB,CAACC,MAAwB;AACvB,QAAI7B,MAAmB,UAAWuC,GAAiBV,CAAI,GACvD5B,KAAA,QAAAA,EAAyB4B;AAAA,MAC3B;AAAA,MACA,CAAC7B,GAAgBC,CAAsB;AAAA,IAAA,GAGnC,CAACyC,IAAcC,EAAe,IAAIlB;AAAA,MACtCtB,MAAsB;AAAA,IAAA,GAElByC,KAAqB1C,KAAewC,IACpCG,IAAoBjB;AAAA,MACxB,CAACC,MAAkB;AACjB,QAAI3B,MAAgB,UAAWyC,GAAgBd,CAAI,GACnDzB,KAAA,QAAAA,EAAsByB;AAAA,MACxB;AAAA,MACA,CAAC3B,GAAaE,CAAmB;AAAA,IAAA,GAG7B0C,KAAelB,EAAY,MAAM;AACrC,MAAAK,EAAa,MAAM,GACnBI,EAAW,IAAI,GACfI,EAAe,IAAI,GACnBI,EAAkB,EAAK;AAAA,IACzB,GAAG,CAACZ,GAAcI,GAAYI,GAAgBI,CAAiB,CAAC,GAG1DE,KAAUzB,EAAQ,MACf3D,EAAM,OAAO,CAACR,MAAS;AAC5B,YAAM6F,IAAS7F,EAAK,WAAW;AAQ/B,aAPI,EAAA6E,MAAkB,UAAUgB,KAC5BhB,MAAkB,UAAU,CAACgB,KAC7BZ,KAAejF,EAAK,SAASiF,KAC7BI,MACerF,EAAK,YAAY,QACjBqF,KAEfI,MAAsB,CAACnF,GAAUN,GAAMP,CAAG;AAAA,IAEhD,CAAC,GACA;AAAA,MACDe;AAAA,MACAqE;AAAA,MACAI;AAAA,MACAI;AAAA,MACAI;AAAA,MACAhG;AAAA,IAAA,CACD,GAEKmB,KAAUuD;AAAA,MACd,MAAM5D,GAAiBqF,IAASnG,CAAG;AAAA,MACnC,CAACmG,IAASnG,CAAG;AAAA,IAAA,GAITqG,IAAYC,EAAuB,IAAI,GACvCC,KAAmBD,EAA2B,IAAI,GAClD,CAACE,IAASC,EAAU,IAAI5B,EAAS,EAAK,GACtC,CAAC6B,IAAYC,EAAa,IAAI9B,EAAS,EAAK,GAE5C+B,IAAc5B,EAAY,MAAM;AACpC,YAAM6B,IAASR,EAAU;AACzB,UAAI,CAACQ,EAAQ;AACb,YAAM,EAAE,WAAAC,GAAW,cAAAC,GAAc,cAAAC,EAAA,IAAiBH;AAClD,MAAAJ,GAAWK,IAAY,CAAC,GACxBH,GAAcG,IAAYE,IAAeD,IAAe,CAAC;AAAA,IAC3D,GAAG,CAAA,CAAE;AAEL,IAAAE,GAA0B,MAAM;AAC9B,MAAAL,EAAA;AAAA,IACF,GAAG,CAACzF,IAASyF,CAAW,CAAC,GAEzBK,GAA0B,MAAM;AAC9B,YAAMJ,IAASR,EAAU;AACzB,UAAI,CAACQ,KAAU,OAAO,iBAAmB,IAAa;AACtD,YAAMK,IAAW,IAAI,eAAeN,CAAW;AAC/C,aAAAM,EAAS,QAAQL,CAAM,GAChB,MAAMK,EAAS,WAAA;AAAA,IACxB,GAAG,CAACN,CAAW,CAAC;AAEhB,UAAMO,KAAgB3E,MAAW,CAAC,CAACD,GAC7B6E,KAAepC,EAAY,MAAM;AACrC,MAAA4B,EAAA;AACA,YAAMC,IAASR,EAAU;AACzB,UAAI,CAACQ,EAAQ;AACb,YAAM,EAAE,WAAAC,GAAW,cAAAC,GAAc,cAAAC,EAAA,IAAiBH;AAClD,MACEtE,KACA4E,MACA,CAAC1E,KACDsE,IAAeD,IAAYE,KAAgB1H,MAE3CiD,EAAA;AAAA,IAEJ,GAAG,CAACqE,GAAarE,GAAY4E,IAAe1E,CAAW,CAAC,GAElD4E,KAAgBrC,EAAY,MAAM;AACtC,YAAM6B,IAASR,EAAU,SACnBiB,IAAKf,GAAiB;AAC5B,UAAI,CAACM,KAAU,CAACS,GAAI;AAClB,QAAAT,KAAA,QAAAA,EAAQ,SAAS,EAAE,KAAK,EAAA;AACxB;AAAA,MACF;AACA,YAAMU,IACJD,EAAG,sBAAA,EAAwB,MAAMT,EAAO,wBAAwB;AAClE,MAAAA,EAAO,SAAS,EAAE,KAAKA,EAAO,YAAYU,GAAO;AAAA,IACnD,GAAG,CAAA,CAAE,GAGCC,IAAWlB,EAAyBvF,CAAK;AAC/C,IAAAyG,EAAS,UAAUzG;AACnB,UAAM0G,KAAWnB,EAAoB,IAAI;AACzC,IAAAoB,GAAoB3D,IAAK,MAAM0D,GAAS,SAAwB,CAAA,CAAE;AAElE,UAAMrI,KAASsF;AAAA,MACb,OAAO;AAAA,QACL,UAAU,MACR8C,EAAS,QAAQ,IAAI,CAACG,OAAO;AAAA,UAC3B,IAAIA,EAAE;AAAA,UACN,QAAQA,EAAE,UAAU;AAAA,QAAA,EACpB;AAAA,QACJ,YAAY,CAACC,MAAa;AACxB,gBAAMC,IAAQL,EAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAOI,CAAQ;AAC5D,UAAIC,qBAAoBA;AAAA,QAC1B;AAAA,QACA,YAAY,CAACD,MAAa;AACxB,gBAAMC,IAAQL,EAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAOI,CAAQ;AAC5D,UAAIC,qBAAsBA;AAAA,QAC5B;AAAA,QACA,SAAS,CAACD,MAAa;AACrB,gBAAMC,IAAQL,EAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAOI,CAAQ;AAC5D,UAAIC,qBAAuBA;AAAA,QAC7B;AAAA,QACA,eAAAR;AAAA,QACA,WAAW,CAACpC,MAAS;AACnB,UAAIA,EAAK,WAAW,UAAWI,EAAaJ,EAAK,MAAM,GACnDA,EAAK,SAAS,UAAWQ,EAAWR,EAAK,IAAI,GAC7CA,EAAK,aAAa,UAAWY,EAAeZ,EAAK,QAAQ,GACzDA,EAAK,gBAAgB,UACvBgB,EAAkBhB,EAAK,WAAW;AAAA,QACtC;AAAA,QACA,aAAAF;AAAA,QACA,UAAU,MAAMxC,KAAA,gBAAAA;AAAA,MAAa;AAAA,MAE/B;AAAA,QACEX;AAAA,QACAC;AAAA,QACAE;AAAA,QACAsF;AAAA,QACAhC;AAAA,QACAI;AAAA,QACAI;AAAA,QACAI;AAAA,QACAlB;AAAA,QACAxC;AAAA,MAAA;AAAA,IACF;AAEF,IAAAuF,GAAqB3I,IAAiBC,IAAQoC,CAAE;AAGhD,UAAMuG,KAAkB,CAACxH,MAAoC;AAC3D,UAAI,CAACA,EAAK,KAAM,QAAO;AACvB,YAAMyH,IAAOrI,GAAiBY,EAAK,IAAI,GACjC0H,KAAUD,KAAA,gBAAAA,EAAM,YAAW,WAC3BE,KAAOF,KAAA,gBAAAA,EAAM,SAAQ9I,IACrBiJ,KAAQ5H,EAAK,aAAakE,GAAiBlE,EAAK,IAAI,KAAKA,EAAK;AACpE,aACE,gBAAA6H;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,SAAAJ;AAAA,UACA,MAAK;AAAA,UACL,SAAS,gBAAAG,EAACF,GAAA,EAAK,eAAY,OAAA,CAAO;AAAA,UAEjC,UAAAC;AAAA,QAAA;AAAA,MAAA;AAAA,IAGP,GAEMG,KAAiB,CAAC/H,MAAoC;AAC1D,UAAI0B,EAAU,QAAO;AACrB,YAAMsG,IAAOhI,EAAK,WAAW;AAC7B,aACE,gBAAAiI,EAAAC,IAAA,EACG,UAAA;AAAA,QAAA5G,IACC,gBAAAuG;AAAA,UAACM;AAAA,UAAA;AAAA,YACC,MAAMH,IAAO,gBAAAH,EAACO,IAAA,CAAA,CAAe,sBAAMC,IAAA,EAAO;AAAA,YAC1C,QAAO;AAAA,YACP,MAAK;AAAA,YACL,cAAY5E;AAAA,cACVuE,IAAO,2BAA2B;AAAA,YAAA;AAAA,YAEpC,SAAS,MAAM1G,EAAatB,CAAI;AAAA,UAAA;AAAA,QAAA,IAEhC;AAAA,QACHuB,IACC,gBAAAsG;AAAA,UAACM;AAAA,UAAA;AAAA,YACC,wBAAOG,IAAA,EAAO;AAAA,YACd,QAAO;AAAA,YACP,MAAK;AAAA,YACL,cAAY7E,EAAE,iBAAiB;AAAA,YAC/B,SAAS,MAAMlC,EAAWvB,CAAI;AAAA,UAAA;AAAA,QAAA,IAE9B;AAAA,QACHwB,IACC,gBAAAqG;AAAA,UAACM;AAAA,UAAA;AAAA,YACC,wBAAOI,IAAA,EAAE;AAAA,YACT,QAAO;AAAA,YACP,MAAK;AAAA,YACL,cAAY9E,EAAE,oBAAoB;AAAA,YAClC,SAAS,MAAMjC,EAAcxB,CAAI;AAAA,UAAA;AAAA,QAAA,IAEjC;AAAA,MAAA,GACN;AAAA,IAEJ,GAEMwI,KAAmB,CAACxI,MAAoC;AAE5D,YAAMyI,KADU/G,IAAuC,OAA5BC,KAAA,gBAAAA,EAAoB3B,OACpB+H,GAAe/H,CAAI,GACxC0I,IAAQlB,GAAgBxH,CAAI;AAClC,UAAI,GAAC0I,KAAS,CAACD;AACf,eACE,gBAAAR,EAAAC,IAAA,EACG,UAAA;AAAA,UAAAQ;AAAA,UACAD;AAAA,QAAA,GACH;AAAA,IAEJ,GAGME,KAAkB,CAACxG,KAAW,CAACC,KAAS5B,EAAM,WAAW,GACzDoI,KACJ,CAACzG,KAAW,CAACC,KAAS5B,EAAM,SAAS,KAAKoF,GAAQ,WAAW,GAEzDiD,KAAc,CAACnI,MACnB,gBAAAmH;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,eAAY;AAAA,QACZ,WAAU;AAAA,QAEV,UAAA,gBAAAA,EAACiB,IAAA,EAAS,SAAQ,eAAc,QAAO,SAAA,CAAS;AAAA,MAAA;AAAA,MAJ3CpI;AAAA,IAAA;AAQT,QAAIqI;AACJ,IAAI3G,IACF2G,sBACG,OAAA,EAAI,WAAU,iDACZ,UAAA,OAAO3G,KAAU,YAChB,gBAAAyF;AAAA,MAACmB;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAOvF,EAAE,wBAAwB;AAAA,QACjC,aAAaA,EAAE,8BAA8B;AAAA,MAAA;AAAA,IAAA,IAG/CrB,EAAA,CAEJ,IAEOD,IACT4G,sBACG,OAAA,EAAI,WAAU,uEACZ,UAAA,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC3B,MAAMyB,GAAY,YAAYzB,CAAC,EAAE,CAAC,GACvD,IAEOuB,KACTI,IACE,gBAAAlB,EAAC,OAAA,EAAI,WAAU,iDACb,UAAA,gBAAAA;AAAA,MAACmB;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAO9F,MAAcO,EAAE,wBAAwB;AAAA,QAC/C,aAAaN,MAAoBM,EAAE,8BAA8B;AAAA,QACjE,eAAeL;AAAA,MAAA;AAAA,IAAA,GAEnB,IAEOwF,KACTG,IACE,gBAAAlB,EAAC,OAAA,EAAI,WAAU,iDACb,UAAA,gBAAAA;AAAA,MAACmB;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAOvF,EAAE,gCAAgC;AAAA,QACzC,aAAaA,EAAE,sCAAsC;AAAA,QACrD,eAAe;AAAA,UACb,OAAOA,EAAE,gCAAgC;AAAA,UACzC,SAASkC;AAAA,QAAA;AAAA,MACX;AAAA,IAAA,GAEJ,IAGFoD,IACE,gBAAAd;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKnC;AAAA,QAIL,UAAU;AAAA,QACV,UAAUe;AAAA,QACV,iBAAeZ,KAAU,SAAS;AAAA,QAClC,oBAAkBE,KAAa,SAAS;AAAA,QACxC,WAAWjH;AAAA,QAEX,UAAA;AAAA,UAAA,gBAAA2I,EAAC,QAAG,WAAU,6EACX,UAAAjH,GAAQ,IAAI,CAACqI,MACZ,gBAAAhB;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,WAAU;AAAA,cAEV,UAAA;AAAA,gBAAA,gBAAAJ;AAAA,kBAACqB;AAAA,kBAAA;AAAA,oBACC,WAAWD,EAAO;AAAA,oBAClB,OAAOA,EAAO,MAAM;AAAA,oBACpB,OAAOhF,GAAagF,EAAO,GAAG;AAAA,oBAC9B,WACEA,EAAO,QAAQ,YAAYjD,KAAmB;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGlD,gBAAA6B,EAAC,QAAG,WAAU,6EACX,YAAO,MAAM,IAAI,CAAC7H,MACjB,gBAAA6H;AAAA,kBAACsB;AAAA,kBAAA;AAAA,oBAEC,MAAAnJ;AAAA,oBACA,MAAAoB;AAAA,oBACA,YACEC,IAAa,MAAMA,EAAWrB,CAAI,IAAI;AAAA,oBAExC,SAASwI,GAAiBxI,CAAI;AAAA,oBAC9B,WAAWb;AAAA,oBACX,gBAAca,EAAK;AAAA,kBAAA;AAAA,kBARdA,EAAK;AAAA,gBAAA,CAUb,EAAA,CACH;AAAA,cAAA;AAAA,YAAA;AAAA,YAzBKiJ,EAAO;AAAA,UAAA,CA2Bf,GACH;AAAA,UACC/G,IAAc2G,GAAY,cAAc,IAAI;AAAA,UAC5C,CAAC3G,KAAe0E,MAAiB5E,sBAC/B,OAAA,EAAI,WAAU,uDACb,UAAA,gBAAA6F,EAACuB,IAAA,EAAO,QAAO,SAAQ,MAAK,MAAK,SAASpH,GACvC,YAAE,qBAAqB,EAAA,CAC1B,GACF,IACE;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAMV,UAAMqH,OAAoBtH,KAAA,gBAAAA,EAAiB,WAAU,KAAK,GACpDuH,KAAyC,CAAC,QAAQ,QAAQ,KAAK,GAI/DC,KACJ9H,MAAa,CAACC,IACZ,gBAAAmG;AAAA,MAACM;AAAA,MAAA;AAAA,QACC,wBAAOqB,IAAA,EAAK;AAAA,QACZ,QAAO;AAAA,QACP,MAAK;AAAA,QACL,cAAY/F,EAAE,gBAAgB;AAAA,QAC9B,SAAShC;AAAA,MAAA;AAAA,IAAA,IAET,QAIAgI,KACJJ,MAAoBhH,KAClB,gBAAA4F,EAAC,OAAA,EAAI,WAAU,4DACZ,UAAA;AAAA,MAAAoB,KACC,gBAAAxB,EAAC6B,MAAY,OAAOjG,EAAE,wBAAwB,GAC3C,UAAA1B,EAAiB,IAAI,CAAC4H,MAAU;AAC/B,cAAMC,IAASrF,OAAiBoF;AAChC,eACE,gBAAA9B;AAAA,UAACuB;AAAA,UAAA;AAAA,YAEC,QAAQQ,IAAS,YAAY;AAAA,YAC7B,MAAK;AAAA,YACL,gBAAcA;AAAA,YACd,SAAS,MAAMpF,EAAYmF,CAAK;AAAA,YAE/B,aAAYA,CAAK;AAAA,UAAA;AAAA,UANbA;AAAA,QAAA;AAAA,MASX,CAAC,GACH,IACE;AAAA,MAEHtH,KACC,gBAAA4F,EAAC,OAAA,EAAI,WAAU,mEACb,UAAA;AAAA,QAAA,gBAAAJ,EAAC6B,IAAA,EAAY,OAAOjG,EAAE,yBAAyB,GAC5C,UAAA6F,GAAa,IAAI,CAACK,MAAU;AAC3B,gBAAMC,IAAS/E,MAAkB8E;AACjC,iBACE,gBAAA9B;AAAA,YAACuB;AAAA,YAAA;AAAA,cAEC,QAAQQ,IAAS,YAAY;AAAA,cAC7B,MAAK;AAAA,cACL,gBAAcA;AAAA,cACd,SAAS,MAAM9E,EAAa6E,CAAK;AAAA,cAEhC,aAAaA,CAAK;AAAA,YAAA;AAAA,YANdA;AAAA,UAAA;AAAA,QASX,CAAC,EAAA,CACH;AAAA,QAEClH,KAAeA,EAAY,SAAS,IACnC,gBAAAoF;AAAA,UAACgC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAS;AAAA,YACT,cAAYpG,EAAE,uBAAuB;AAAA,YACrC,aAAaA,EAAE,6BAA6B;AAAA,YAC5C,SAAShB;AAAA,YACT,OAAOwC,KAAe;AAAA,YACtB,eAAe,CAAC0E,MAAUzE,EAAWyE,KAAS,IAAI;AAAA,UAAA;AAAA,QAAA,IAElD;AAAA,QAEH/G,KAAmBA,EAAgB,SAAS,IAC3C,gBAAAiF;AAAA,UAACgC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAS;AAAA,YACT,cAAYpG,EAAE,2BAA2B;AAAA,YACzC,aAAaA,EAAE,iCAAiC;AAAA,YAChD,SAASb;AAAA,YACT,OAAOyC,KAAmB;AAAA,YAC1B,eAAe,CAACsE,MAAUrE,EAAeqE,KAAS,IAAI;AAAA,UAAA;AAAA,QAAA,IAEtD;AAAA,QAEJ,gBAAA9B;AAAA,UAACiC;AAAA,UAAA;AAAA,YACC,IAAIjG;AAAA,YACJ,MAAK;AAAA,YACL,OAAOJ,EAAE,wBAAwB;AAAA,YACjC,SAASgC;AAAA,YACT,iBAAiBC;AAAA,UAAA;AAAA,QAAA;AAAA,MACnB,EAAA,CACF,IACE;AAAA,IAAA,EAAA,CACN,IACE;AAEN,WACE,gBAAAuC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKf;AAAA,QACL,kBAAe;AAAA,QACf,qBAAmBjG;AAAA,QACnB,mBAAiBqC,KAAY,SAAYK;AAAA,QACzC,cAAYL;AAAA,QACZ,WAAWtE,GAAa,EAAE,MAAAoC,GAAM,WAAAiC,IAAW;AAAA,QAC1C,GAAGE;AAAA,QAEJ,UAAA;AAAA,UAAA,gBAAAsE;AAAA,YAACkC;AAAA,YAAA;AAAA,cACC,OAAOjG;AAAA,cACP,wBAAOkG,IAAA,EAAe;AAAA,cACtB,WAAArG;AAAA,cACA,SAAS4F;AAAA,cACT,SAASE;AAAA,YAAA;AAAA,UAAA;AAAA,UAGVV;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEAhI,GAAW,cAAc;AAazB,SAASmI,GAAa;AAAA,EACpB,WAAAe;AAAA,EACA,OAAAC;AAAA,EACA,OAAAtC;AAAA,EACA,WAAAuC;AACF,GAAiC;AAW/B,SACE,gBAAAlC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKkC;AAAA,MACL,eAAaF;AAAA,MACb,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QAXJA,MAAc,YACV,wDACAA,MAAc,UACZ,oDACA;AAAA,MAQF,EACA,KAAK,GAAG;AAAA,MAET,UAAA;AAAA,QAAAA,MAAc,UACb,gBAAApC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA,UAAA;AAAA,QAAA,IAEV;AAAA,QACHD;AAAA,0BACA,QAAA,EAAK,WAAU,2CACb,UAAA,IAAIsC,CAAK,IAAA,CACZ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;","x_google_ignoreList":[0,1,2,3]}
|
|
1
|
+
{"version":3,"file":"tasks-panel-Do5SFp-j.js","sources":["../../node_modules/lucide-react/dist/esm/icons/coins.mjs","../../node_modules/lucide-react/dist/esm/icons/gem.mjs","../../node_modules/lucide-react/dist/esm/icons/megaphone.mjs","../../node_modules/lucide-react/dist/esm/icons/tag.mjs","../../src/components/tasks-panel/tasks-panel.agent.ts","../../src/components/tasks-panel/tasks-panel.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M13.744 17.736a6 6 0 1 1-7.48-7.48\", key: \"bq4yh3\" }],\n [\"path\", { d: \"M15 6h1v4\", key: \"11y1tn\" }],\n [\"path\", { d: \"m6.134 14.768.866-.5 2 3.464\", key: \"17snzx\" }],\n [\"circle\", { cx: \"16\", cy: \"8\", r: \"6\", key: \"14bfc9\" }]\n];\nconst Coins = createLucideIcon(\"coins\", __iconNode);\n\nexport { __iconNode, Coins as default };\n//# sourceMappingURL=coins.mjs.map\n","/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M10.5 3 8 9l4 13 4-13-2.5-6\", key: \"b3dvk1\" }],\n [\n \"path\",\n {\n d: \"M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z\",\n key: \"7w4byz\"\n }\n ],\n [\"path\", { d: \"M2 9h20\", key: \"16fsjt\" }]\n];\nconst Gem = createLucideIcon(\"gem\", __iconNode);\n\nexport { __iconNode, Gem as default };\n//# sourceMappingURL=gem.mjs.map\n","/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z\",\n key: \"q8bfy3\"\n }\n ],\n [\"path\", { d: \"M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14\", key: \"1853fq\" }],\n [\"path\", { d: \"M8 6v8\", key: \"15ugcq\" }]\n];\nconst Megaphone = createLucideIcon(\"megaphone\", __iconNode);\n\nexport { __iconNode, Megaphone as default };\n//# sourceMappingURL=megaphone.mjs.map\n","/**\n * @license lucide-react v1.22.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.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\",\n key: \"vktsd0\"\n }\n ],\n [\"circle\", { cx: \"7.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"kqv944\" }]\n];\nconst Tag = createLucideIcon(\"tag\", __iconNode);\n\nexport { __iconNode, Tag as default };\n//# sourceMappingURL=tag.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — TasksPanel. */\n/* */\n/* Rail Tasks surface: read task ids + status (never note / patient), */\n/* activate a row, toggle done / dismiss a task, re-anchor the scroll on */\n/* the overdue bucket, and drive the filter bar — all through the curated */\n/* handle. In-page within the rail panel (no open/close — the rail owns */\n/* panel open state). Mirrors taskTrayAgent's safety mapping (select=read, */\n/* toggle_done=write, dismiss=destructive) plus AppointmentTimeline's */\n/* scroll capability; the stateful filter bar adds the `filter` capability */\n/* backed by `set_filter`. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { TasksPanelHandle } from './tasks-panel';\n\nexport const tasksPanelAgent: AgentAdapter<TasksPanelHandle> = {\n id: 'tasks-panel',\n // 'pick' backs select_item (non-persisting activation, matching\n // AppointmentTimeline); 'dismiss' backs dismiss; 'scroll' backs\n // jump_to_overdue (re-anchors the viewport); 'filter' backs set_filter (the\n // status / type / assignee / overdue filter bar is genuinely stateful);\n // 'view_change' backs change_scope (the patient ↔ mine segment); 'paginate'\n // backs load_more (append the next page of tasks).\n capabilities: [\n 'pick',\n 'dismiss',\n 'scroll',\n 'filter',\n 'view_change',\n 'paginate',\n ],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.tasksPanel.state.items',\n description:\n 'Currently-rendered tasks. Ids + status only — never task note / patient.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\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.tasksPanel.actions.selectItem',\n description: 'Activate the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n toggle_done: {\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n descriptionKey: 'ui.agent.tasksPanel.actions.toggleDone',\n description: 'Request the host to toggle the done state of a task.',\n invoke: (handle, args: { id: string }) => {\n handle.toggleDone(args.id);\n },\n },\n dismiss: {\n safety: 'destructive',\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.tasksPanel.actions.dismiss',\n description:\n 'Request the host to dismiss / remove the task with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.dismiss(args.id);\n },\n },\n jump_to_overdue: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.jumpToOverdue',\n description: 'Re-anchor the panel scroll on the overdue tasks.',\n invoke: (handle) => {\n handle.jumpToOverdue();\n },\n },\n set_filter: {\n safety: 'read',\n argsType:\n \"{ status?: 'todo' | 'done' | 'all'; type?: string | null; assignee?: string | null; overdueOnly?: boolean }\",\n argsSchema: {\n type: 'object',\n properties: {\n status: { type: 'string', enum: ['todo', 'done', 'all'] },\n type: { type: ['string', 'null'] },\n assignee: { type: ['string', 'null'] },\n overdueOnly: { type: 'boolean' },\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.setFilter',\n description:\n 'Set the task filters (status segment, type, assignee, overdue-only). Omitted keys are left unchanged.',\n invoke: (\n handle,\n args: {\n status?: 'todo' | 'done' | 'all';\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n },\n ) => {\n handle.setFilter(args);\n },\n },\n change_scope: {\n safety: 'read',\n argsType: \"{ scope: 'patient' | 'mine' }\",\n argsSchema: {\n type: 'object',\n properties: { scope: { type: 'string', enum: ['patient', 'mine'] } },\n required: ['scope'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.changeScope',\n description:\n \"Switch the task scope segment between this patient ('patient') and the operator's own tasks ('mine'). The host re-feeds the items.\",\n invoke: (handle, args: { scope: 'patient' | 'mine' }) => {\n handle.changeScope(args.scope);\n },\n },\n load_more: {\n safety: 'read',\n // Requests the host to append the next page — not idempotent (each call\n // advances the page) and reaches the host data source.\n openWorld: true,\n descriptionKey: 'ui.agent.tasksPanel.actions.loadMore',\n description: 'Request the host to append the next page of tasks.',\n invoke: (handle) => {\n handle.loadMore();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'tasks-panel',\n description: 'Marks the TasksPanel wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific panel from the agent.',\n },\n item: {\n attr: 'data-task-id',\n description:\n 'Stable task id emitted on each rendered TaskCard inside the panel.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n SquareCheckBig,\n Coins,\n Gem,\n ClipboardCheck,\n Megaphone,\n Pencil,\n Plus,\n Square,\n Tag,\n X,\n} from 'lucide-react';\nimport { Badge, type BadgeProps } from '../badge';\nimport { Button } from '../button';\nimport { IconButton } from '../button/icon-button';\nimport { ButtonGroup } from '../button-group';\nimport { PanelHeader } from '../panel-header';\nimport { Select } from '../select';\nimport { Switch } from '../switch';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { TaskCard, type TaskItem } from '../task-card';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { tasksPanelAgent } from './tasks-panel.agent';\n\n/* -------------------------------------------------------------------- */\n/* TasksPanel */\n/* */\n/* The Tasks tool for the Control Room rail — the next surface after */\n/* AppointmentTimeline (Appointments) and NotesPanel (Notes). It is the */\n/* rail equivalent of the in-page TaskTray: a fill-mode panel that owns */\n/* its own scroll, groups a flat task list into DUE-DATE buckets */\n/* (Overdue / Today / Tomorrow / This week / Later, with Done sunk to */\n/* the bottom), pins a filter header + per-bucket headers, and fades at */\n/* each scroll edge. Unlike AppointmentTimeline it does NOT scroll a */\n/* continuous calendar stream — platform tasks are a bounded, date-ASC */\n/* list — so there is no bidirectional infinite scroll or today-anchor, */\n/* only an optional one-way `onLoadMore`. */\n/* */\n/* Each row reuses TaskCard (no reinvention); the panel adds a coloured */\n/* type Badge (the platform's primary per-task signal) + elevation via */\n/* the card's className. All visible text flows through */\n/* useTranslation('ui') against `tasksPanel.*`; only ids + status reach */\n/* the agent adapter (no PHI). */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to the bottom edge before `onLoadMore` fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Which set of tasks the panel shows — the host owns the actual feed. */\nexport type TasksPanelScope = 'patient' | 'mine';\n\n/** Status segment value. Mirrors the platform `done` filter (default `todo`). */\nexport type TasksPanelStatusFilter = 'todo' | 'done' | 'all';\n\n/**\n * Panel-local extension of the card's `TaskItem`. The extra fields here drive\n * bucketing + filtering; the row's display fields (the typed link via\n * `linkType` + `linkedLabel`, the `assigneeLabel`, `dueLabel`) live on\n * `TaskItem` and are rendered by `TaskCard` itself. The host maps the platform\n * `DoctorReminder` → this shape — composing `title` (a summary, NOT the bare\n * type), `note`, the linked entity, the assignee, and `dueLabel`.\n */\nexport interface TasksPanelItem extends TaskItem {\n /** ISO-8601 due/scheduled instant (platform `DoctorReminder.date`). Buckets + orders the list. */\n dueIso: string;\n /** System or custom task-type key (`recall` | `payment` | `collection` | `other` | `custom-*`). Drives the type filter + badge. */\n type?: string;\n /**\n * Localised type label, required for CUSTOM types (the panel resolves system\n * keys itself). Falls back to the system label for the four known keys.\n */\n typeLabel?: string;\n /**\n * Assignee id (the platform `practiceUser`). Omit ⇒ unassigned; give pool\n * tasks a shared sentinel value (e.g. `'unassigned'`) if you want the pool\n * itself filterable. Drives the assignee FILTER (exact match); the displayed\n * name is `TaskItem.assigneeLabel`.\n */\n assignee?: string;\n /** Provenance — manual vs workflow-created. Filter only. */\n createdBy?: 'user' | 'workflow';\n}\n\n/** Curated imperative handle — identifiers + structural state only, no PHI. */\nexport interface TasksPanelHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n toggleDone: (id: string) => void;\n dismiss: (id: string) => void;\n jumpToOverdue: () => void;\n setFilter: (next: {\n status?: TasksPanelStatusFilter;\n type?: string | null;\n assignee?: string | null;\n overdueOnly?: boolean;\n }) => void;\n /** Switch the task scope segment (patient ↔ mine). The host re-feeds items. */\n changeScope: (next: TasksPanelScope) => void;\n /** Request the host to append the next page of tasks (mirrors onLoadMore). */\n loadMore: () => void;\n}\n\ninterface FilterOption {\n /** Stable value passed back through the matching `on…Change`. */\n value: string;\n /** Localised label. */\n label: string;\n}\n\nexport interface TasksPanelProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Tasks to render — any order; bucketed + sorted internally (due ASC, Done last). */\n items: TasksPanelItem[];\n /** ISO-8601 \"now\" anchor — buckets + overdue compute against it. Defaults to the current instant; stories pass a fixed value. */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Tasks\". */\n title?: string;\n /** Visual density forwarded to each TaskCard. Defaults to `xs` — the compact rail row. */\n size?: 'xs' | 'sm' | 'md';\n /** Fires when a row is activated. */\n onOpenTask?: (item: TasksPanelItem) => void;\n /** Fires when the host should toggle a task's done state. */\n onToggleDone?: (item: TasksPanelItem) => void;\n /** Fires when the host should open the task editor. Omit to hide the per-row edit action. */\n onEditTask?: (item: TasksPanelItem) => void;\n /** Fires when the host should dismiss / remove a task. Omit to hide the per-row dismiss action. */\n onDismissTask?: (item: TasksPanelItem) => void;\n /** Fires when the header \"Add\" affordance is activated. Omit to hide it. */\n onAddTask?: () => void;\n /**\n * Read-only mode — hides every write affordance (toggle / edit / dismiss /\n * add). Mirrors the platform gating writes behind `practice_task_edit`.\n */\n readOnly?: boolean;\n /**\n * Per-row trailing action toolbar, forwarded to each TaskCard's `actions`\n * slot. Overrides the default toggle / edit / dismiss buttons (the type Badge\n * is always prepended by the panel). Ignored when `readOnly`.\n */\n renderItemActions?: (item: TasksPanelItem) => ReactNode;\n\n /* ----- Scope (host-driven feed switch) ----- */\n /** Controlled scope segment. */\n scope?: TasksPanelScope;\n /** Uncontrolled initial scope. Default `'patient'` when both scopes are available, else the only one. */\n defaultScope?: TasksPanelScope;\n /** Fires when the user switches scope — the host re-feeds `items`. */\n onScopeChange?: (next: TasksPanelScope) => void;\n /** Which scopes the segment offers. Omit ⇒ no scope segment (single-scope panel). */\n availableScopes?: TasksPanelScope[];\n\n /* ----- One-way pagination ----- */\n /** Load the next page — fired when the bottom edge is reached and via the footer button. */\n onLoadMore?: () => void;\n /** Whether more tasks exist. Defaults to `true` when `onLoadMore` is set. */\n hasMore?: boolean;\n /** Show the bottom loading row while the next page is fetched. */\n loadingMore?: boolean;\n /** Full-panel initial loading state (skeleton rows in the body). */\n loading?: boolean;\n /** Error surface — `true` for the default error EmptyState, or a custom node. */\n error?: boolean | ReactNode;\n\n /* ----- Filters (mirror platform TaskFilterType) ----- */\n /** Show the filter header (status segment + type / assignee selects + overdue toggle). Default `true`. */\n showFilters?: boolean;\n /** Controlled status segment. */\n statusFilter?: TasksPanelStatusFilter;\n /** Uncontrolled initial status segment. Default `'todo'` (the platform default). */\n defaultStatusFilter?: TasksPanelStatusFilter;\n onStatusFilterChange?: (next: TasksPanelStatusFilter) => void;\n /** Task types for the type filter. Omit ⇒ no type filter. */\n typeOptions?: FilterOption[];\n /** Controlled type filter (`null`/empty ⇒ all). */\n typeFilter?: string | null;\n onTypeFilterChange?: (next: string | null) => void;\n /** Assignees for the assignee filter. Pass an explicit Unassigned option if wanted. Omit ⇒ no assignee filter. */\n assigneeOptions?: FilterOption[];\n /** Controlled assignee filter (`null`/empty ⇒ anyone). */\n assigneeFilter?: string | null;\n onAssigneeFilterChange?: (next: string | null) => void;\n /** Controlled overdue-only toggle. */\n overdueOnly?: boolean;\n /** Uncontrolled initial overdue-only state. Default `false`. */\n defaultOverdueOnly?: boolean;\n onOverdueOnlyChange?: (next: boolean) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n /** CTA wired into the first-use empty state (e.g. Create task). */\n emptyAction?: { label: string; onClick: () => void };\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n {\n variants: { size: { xs: '', sm: '', md: '' } },\n defaultVariants: { size: 'xs' },\n },\n);\n\n/* Scroll region with a block-axis fade mask — identical technique to\n AppointmentTimeline, single-direction load. Disabled under reduced-motion,\n the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-md)]',\n 'ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:[--tpl-mask-top:black] ds:[--tpl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--tpl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--tpl-mask-bottom:transparent]',\n 'ds:[mask-image:linear-gradient(to_bottom,var(--tpl-mask-top)_0,black_var(--tpl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--tpl-fade-distance,var(--spacing-lg))),var(--tpl-mask-bottom)_100%)]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:[.theme-accessible_&]:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\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:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* Elevation for each reused TaskCard row — a subtle lift over the panel\n surface so rows read as raised. TaskCard owns its own border + radius.\n Uses `--shadow-sm` (not the heavier `--shadow-card`/`--shadow-lg`): the\n scroll region is `overflow-y:auto` (so `overflow-x` computes to `auto` and\n clips) with only an `--spacing-sm` gutter, and a wide 30px-blur card shadow\n gets sliced with a hard edge at that gutter. A small row shadow fits. */\nconst rowElevationClass =\n 'ds:shadow-[var(--shadow-sm)] ds:bg-[color:var(--card)]';\n\n/* -------------------------------------------------------------------- */\n/* Type → Badge variant + icon (system keys only; custom ⇒ neutral) */\n/* -------------------------------------------------------------------- */\n\nconst SYSTEM_TYPE_META: Record<\n string,\n { variant: NonNullable<BadgeProps['variant']>; Icon: typeof Tag }\n> = {\n recall: { variant: 'info', Icon: Megaphone },\n payment: { variant: 'warning', Icon: Gem },\n collection: { variant: 'error', Icon: Coins },\n other: { variant: 'neutral', Icon: Tag },\n};\n\n/* -------------------------------------------------------------------- */\n/* Due-bucket grouping */\n/* -------------------------------------------------------------------- */\n\ntype BucketKey =\n | 'overdue'\n | 'today'\n | 'tomorrow'\n | 'thisWeek'\n | 'later'\n | 'done';\n\nconst BUCKET_ORDER: BucketKey[] = [\n 'overdue',\n 'today',\n 'tomorrow',\n 'thisWeek',\n 'later',\n 'done',\n];\n\ninterface Bucket {\n key: BucketKey;\n items: TasksPanelItem[];\n}\n\nfunction startOfDay(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\n/** Boundary timestamps the buckets + the overdue notion are computed against. */\nfunction dayBoundaries(now: Date) {\n const today = startOfDay(now);\n const tomorrow = new Date(today);\n tomorrow.setDate(today.getDate() + 1);\n const dayAfter = new Date(today);\n dayAfter.setDate(today.getDate() + 2);\n // Monday-based week — start of NEXT week is the upper bound of \"This week\".\n const dow = (today.getDay() + 6) % 7;\n const nextWeek = new Date(today);\n nextWeek.setDate(today.getDate() + (7 - dow));\n return {\n startOfToday: +today,\n startOfTomorrow: +tomorrow,\n startOfDayAfter: +dayAfter,\n startOfNextWeek: +nextWeek,\n };\n}\n\nfunction bucketFor(item: TasksPanelItem, now: Date): BucketKey {\n if (item.status === 'done') return 'done';\n const { startOfToday, startOfTomorrow, startOfDayAfter, startOfNextWeek } =\n dayBoundaries(now);\n const due = +new Date(item.dueIso);\n if (due < startOfToday) return 'overdue';\n if (due < startOfTomorrow) return 'today';\n if (due < startOfDayAfter) return 'tomorrow';\n if (due < startOfNextWeek) return 'thisWeek';\n return 'later';\n}\n\n/** A task is overdue when it is not done and due before tomorrow (platform notion). */\nfunction isOverdue(item: TasksPanelItem, now: Date): boolean {\n if (item.status === 'done') return false;\n return +new Date(item.dueIso) < dayBoundaries(now).startOfTomorrow;\n}\n\nfunction groupByDueBucket(items: TasksPanelItem[], now: Date): Bucket[] {\n const map = new Map<BucketKey, TasksPanelItem[]>();\n for (const item of items) {\n const key = bucketFor(item, now);\n const list = map.get(key);\n if (list) list.push(item);\n else map.set(key, [item]);\n }\n const buckets: Bucket[] = [];\n for (const key of BUCKET_ORDER) {\n const list = map.get(key);\n if (!list || list.length === 0) continue;\n // Due ASC (most-overdue-first), mirroring the platform's ORDER BY date ASC.\n list.sort((a, b) => +new Date(a.dueIso) - +new Date(b.dueIso));\n buckets.push({ key, items: list });\n }\n return buckets;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const TasksPanel = forwardRef<HTMLElement, TasksPanelProps>(\n (\n {\n id,\n items,\n nowIso,\n title,\n size = 'xs',\n onOpenTask,\n onToggleDone,\n onEditTask,\n onDismissTask,\n onAddTask,\n readOnly = false,\n renderItemActions,\n scope,\n defaultScope,\n onScopeChange,\n availableScopes,\n onLoadMore,\n hasMore,\n loadingMore = false,\n loading = false,\n error = false,\n showFilters = true,\n statusFilter,\n defaultStatusFilter,\n onStatusFilterChange,\n typeOptions,\n typeFilter,\n onTypeFilterChange,\n assigneeOptions,\n assigneeFilter,\n onAssigneeFilterChange,\n overdueOnly,\n defaultOverdueOnly,\n onOverdueOnlyChange,\n emptyTitle,\n emptyDescription,\n emptyAction,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const headingId = useId();\n const overdueSwitchId = useId();\n const heading = title ?? t('tasksPanel.title');\n\n // Static key lookups — every label is a literal `t()` call so the i18n\n // coverage gate can see each key (template-literal keys are invisible to it).\n const statusLabels: Record<TasksPanelStatusFilter, string> = {\n todo: t('tasksPanel.status.todo'),\n done: t('tasksPanel.status.done'),\n all: t('tasksPanel.status.all'),\n };\n const scopeLabels: Record<TasksPanelScope, string> = {\n patient: t('tasksPanel.scope.patient'),\n mine: t('tasksPanel.scope.mine'),\n };\n const bucketLabels: Record<BucketKey, string> = {\n overdue: t('tasksPanel.buckets.overdue'),\n today: t('tasksPanel.buckets.today'),\n tomorrow: t('tasksPanel.buckets.tomorrow'),\n thisWeek: t('tasksPanel.buckets.thisWeek'),\n later: t('tasksPanel.buckets.later'),\n done: t('tasksPanel.buckets.done'),\n };\n const systemTypeLabels: Record<string, string> = {\n recall: t('tasksPanel.types.recall'),\n payment: t('tasksPanel.types.payment'),\n collection: t('tasksPanel.types.collection'),\n other: t('tasksPanel.types.other'),\n };\n\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n /* ----- Controlled / uncontrolled filter + scope state ----- */\n const [scopeState, setScopeState] = useState<TasksPanelScope>(\n defaultScope ?? availableScopes?.[0] ?? 'patient',\n );\n const currentScope = scope ?? scopeState;\n const changeScope = useCallback(\n (next: TasksPanelScope) => {\n if (scope === undefined) setScopeState(next);\n onScopeChange?.(next);\n },\n [scope, onScopeChange],\n );\n\n const [statusState, setStatusState] = useState<TasksPanelStatusFilter>(\n defaultStatusFilter ?? 'todo',\n );\n const currentStatus = statusFilter ?? statusState;\n const changeStatus = useCallback(\n (next: TasksPanelStatusFilter) => {\n if (statusFilter === undefined) setStatusState(next);\n onStatusFilterChange?.(next);\n },\n [statusFilter, onStatusFilterChange],\n );\n\n const [typeState, setTypeState] = useState<string | null>(null);\n const currentType = typeFilter !== undefined ? typeFilter : typeState;\n const changeType = useCallback(\n (next: string | null) => {\n if (typeFilter === undefined) setTypeState(next);\n onTypeFilterChange?.(next);\n },\n [typeFilter, onTypeFilterChange],\n );\n\n const [assigneeState, setAssigneeState] = useState<string | null>(null);\n const currentAssignee =\n assigneeFilter !== undefined ? assigneeFilter : assigneeState;\n const changeAssignee = useCallback(\n (next: string | null) => {\n if (assigneeFilter === undefined) setAssigneeState(next);\n onAssigneeFilterChange?.(next);\n },\n [assigneeFilter, onAssigneeFilterChange],\n );\n\n const [overdueState, setOverdueState] = useState<boolean>(\n defaultOverdueOnly ?? false,\n );\n const currentOverdueOnly = overdueOnly ?? overdueState;\n const changeOverdueOnly = useCallback(\n (next: boolean) => {\n if (overdueOnly === undefined) setOverdueState(next);\n onOverdueOnlyChange?.(next);\n },\n [overdueOnly, onOverdueOnlyChange],\n );\n\n const clearFilters = useCallback(() => {\n changeStatus('todo');\n changeType(null);\n changeAssignee(null);\n changeOverdueOnly(false);\n }, [changeStatus, changeType, changeAssignee, changeOverdueOnly]);\n\n /* ----- Filter → bucket ----- */\n const visible = useMemo(() => {\n return items.filter((item) => {\n const isDone = item.status === 'done';\n if (currentStatus === 'todo' && isDone) return false;\n if (currentStatus === 'done' && !isDone) return false;\n if (currentType && item.type !== currentType) return false;\n if (currentAssignee) {\n const assignee = item.assignee ?? '';\n if (assignee !== currentAssignee) return false;\n }\n if (currentOverdueOnly && !isOverdue(item, now)) return false;\n return true;\n });\n }, [\n items,\n currentStatus,\n currentType,\n currentAssignee,\n currentOverdueOnly,\n now,\n ]);\n\n const buckets = useMemo(\n () => groupByDueBucket(visible, now),\n [visible, now],\n );\n\n /* ----- Scroll region: edge fades + one-way load-more ----- */\n const scrollRef = useRef<HTMLDivElement>(null);\n const overdueHeaderRef = useRef<HTMLElement | null>(null);\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n updateEdges();\n }, [buckets, updateEdges]);\n\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n const moreAvailable = hasMore ?? !!onLoadMore;\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadMore &&\n moreAvailable &&\n !loadingMore &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadMore();\n }\n }, [updateEdges, onLoadMore, moreAvailable, loadingMore]);\n\n const jumpToOverdue = useCallback(() => {\n const region = scrollRef.current;\n const el = overdueHeaderRef.current;\n if (!region || !el) {\n region?.scrollTo({ top: 0 });\n return;\n }\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({ top: region.scrollTop + delta });\n }, []);\n\n /* ----- Agent handle ----- */\n const itemsRef = useRef<TasksPanelItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<TasksPanelHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'open',\n })),\n selectItem: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenTask?.(found);\n },\n toggleDone: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onToggleDone?.(found);\n },\n dismiss: (targetId) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismissTask?.(found);\n },\n jumpToOverdue,\n setFilter: (next) => {\n if (next.status !== undefined) changeStatus(next.status);\n if (next.type !== undefined) changeType(next.type);\n if (next.assignee !== undefined) changeAssignee(next.assignee);\n if (next.overdueOnly !== undefined)\n changeOverdueOnly(next.overdueOnly);\n },\n changeScope,\n loadMore: () => onLoadMore?.(),\n }),\n [\n onOpenTask,\n onToggleDone,\n onDismissTask,\n jumpToOverdue,\n changeStatus,\n changeType,\n changeAssignee,\n changeOverdueOnly,\n changeScope,\n onLoadMore,\n ],\n );\n useAgentRegistration(tasksPanelAgent, handle, id);\n\n /* ----- Row rendering ----- */\n const renderTypeBadge = (item: TasksPanelItem): ReactNode => {\n if (!item.type) return null;\n const meta = SYSTEM_TYPE_META[item.type];\n const variant = meta?.variant ?? 'neutral';\n const Icon = meta?.Icon ?? Tag;\n const label = item.typeLabel ?? systemTypeLabels[item.type] ?? item.type;\n return (\n <Badge\n variant={variant}\n size=\"sm\"\n leading={<Icon aria-hidden=\"true\" />}\n >\n {label}\n </Badge>\n );\n };\n\n const defaultActions = (item: TasksPanelItem): ReactNode => {\n if (readOnly) return null;\n const done = item.status === 'done';\n return (\n <>\n {onToggleDone ? (\n <IconButton\n icon={done ? <SquareCheckBig /> : <Square />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t(\n done ? 'tasksPanel.markNotDone' : 'tasksPanel.markDone',\n )}\n onClick={() => onToggleDone(item)}\n />\n ) : null}\n {onEditTask ? (\n <IconButton\n icon={<Pencil />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.edit')}\n onClick={() => onEditTask(item)}\n />\n ) : null}\n {onDismissTask ? (\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('tasksPanel.dismiss')}\n onClick={() => onDismissTask(item)}\n />\n ) : null}\n </>\n );\n };\n\n const renderRowActions = (item: TasksPanelItem): ReactNode => {\n const custom = !readOnly ? renderItemActions?.(item) : null;\n const trailing = custom ?? defaultActions(item);\n const badge = renderTypeBadge(item);\n if (!badge && !trailing) return undefined;\n return (\n <>\n {badge}\n {trailing}\n </>\n );\n };\n\n /* ----- Body branches ----- */\n const isFirstUseEmpty = !loading && !error && items.length === 0;\n const isFilteredEmpty =\n !loading && !error && items.length > 0 && visible.length === 0;\n\n const skeletonRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n let body: ReactNode;\n if (error) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n {typeof error === 'boolean' ? (\n <EmptyState\n variant=\"error\"\n size=\"sm\"\n title={t('tasksPanel.error.title')}\n description={t('tasksPanel.error.description')}\n />\n ) : (\n error\n )}\n </div>\n );\n } else if (loading) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {[0, 1, 2, 3].map((i) => skeletonRow(`skeleton-${i}`))}\n </div>\n );\n } else if (isFirstUseEmpty) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('tasksPanel.empty.title')}\n description={emptyDescription ?? t('tasksPanel.empty.description')}\n primaryAction={emptyAction}\n />\n </div>\n );\n } else if (isFilteredEmpty) {\n body = (\n <div className=\"ds:flex-1 ds:min-h-0 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"no-results\"\n size=\"sm\"\n title={t('tasksPanel.filteredEmpty.title')}\n description={t('tasksPanel.filteredEmpty.description')}\n primaryAction={{\n label: t('tasksPanel.filteredEmpty.clear'),\n onClick: clearFilters,\n }}\n />\n </div>\n );\n } else {\n body = (\n <div\n ref={scrollRef}\n // The scroll region must be keyboard-focusable so arrow / Home / End\n // can drive it (axe scrollable-region-focusable).\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n <ol className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\">\n {buckets.map((bucket) => (\n <li\n key={bucket.key}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <BucketHeader\n bucketKey={bucket.key}\n count={bucket.items.length}\n label={bucketLabels[bucket.key]}\n headerRef={\n bucket.key === 'overdue' ? overdueHeaderRef : undefined\n }\n />\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\">\n {bucket.items.map((item) => (\n <TaskCard\n key={item.id}\n item={item}\n size={size}\n onActivate={\n onOpenTask ? () => onOpenTask(item) : undefined\n }\n actions={renderRowActions(item)}\n className={rowElevationClass}\n data-task-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingMore ? skeletonRow('loading-more') : null}\n {!loadingMore && moreAvailable && onLoadMore ? (\n <div className=\"ds:flex ds:justify-center ds:py-[var(--spacing-sm)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={onLoadMore}>\n {t('tasksPanel.loadMore')}\n </Button>\n </div>\n ) : null}\n </div>\n );\n }\n\n /* ----- Filter header ----- */\n const showScopeSegment = (availableScopes?.length ?? 0) > 1;\n const statusValues: TasksPanelStatusFilter[] = ['todo', 'done', 'all'];\n\n // Add-task affordance lives in the PanelHeader action cluster (inline-end of\n // the title row); the rail injects the favourite / close after it.\n const headerActions =\n onAddTask && !readOnly ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={t('tasksPanel.add')}\n onClick={onAddTask}\n />\n ) : undefined;\n\n // Scope segment + filter controls share the PanelHeader filters row, stacked\n // so the scope segment keeps its own line above the filter cluster.\n const headerFilters =\n showScopeSegment || showFilters ? (\n <div className=\"ds:flex ds:w-full ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {showScopeSegment ? (\n <ButtonGroup label={t('tasksPanel.scope.label')}>\n {availableScopes!.map((value) => {\n const active = currentScope === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n onClick={() => changeScope(value)}\n >\n {scopeLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n ) : null}\n\n {showFilters ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n <ButtonGroup label={t('tasksPanel.status.label')}>\n {statusValues.map((value) => {\n const active = currentStatus === value;\n return (\n <Button\n key={value}\n intent={active ? 'primary' : 'outline'}\n size=\"sm\"\n aria-pressed={active}\n onClick={() => changeStatus(value)}\n >\n {statusLabels[value]}\n </Button>\n );\n })}\n </ButtonGroup>\n\n {typeOptions && typeOptions.length > 0 ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.type.label')}\n placeholder={t('tasksPanel.type.placeholder')}\n options={typeOptions}\n value={currentType ?? ''}\n onValueChange={(value) => changeType(value || null)}\n />\n ) : null}\n\n {assigneeOptions && assigneeOptions.length > 0 ? (\n <Select\n size=\"sm\"\n clearable\n aria-label={t('tasksPanel.assignee.label')}\n placeholder={t('tasksPanel.assignee.placeholder')}\n options={assigneeOptions}\n value={currentAssignee ?? ''}\n onValueChange={(value) => changeAssignee(value || null)}\n />\n ) : null}\n\n <Switch\n id={overdueSwitchId}\n size=\"sm\"\n label={t('tasksPanel.overdueOnly')}\n checked={currentOverdueOnly}\n onCheckedChange={changeOverdueOnly}\n />\n </div>\n ) : null}\n </div>\n ) : undefined;\n\n return (\n <section\n ref={innerRef}\n data-component=\"tasks-panel\"\n data-component-id={id}\n aria-labelledby={ariaLabel ? undefined : headingId}\n aria-label={ariaLabel}\n className={rootVariants({ size, className })}\n {...rest}\n >\n <PanelHeader\n title={heading}\n icon={<ClipboardCheck />}\n headingId={headingId}\n actions={headerActions}\n filters={headerFilters}\n />\n\n {body}\n </section>\n );\n },\n);\n\nTasksPanel.displayName = 'TasksPanel';\n\n/* -------------------------------------------------------------------- */\n/* Bucket header — sticky label per due bucket */\n/* -------------------------------------------------------------------- */\n\ninterface BucketHeaderProps {\n bucketKey: BucketKey;\n count: number;\n label: string;\n headerRef?: React.MutableRefObject<HTMLElement | null>;\n}\n\nfunction BucketHeader({\n bucketKey,\n count,\n label,\n headerRef,\n}: BucketHeaderProps): ReactNode {\n // Overdue is tinted destructive, Today brand (+ a decorative leading dot);\n // both clear AA on the --card surface in every theme (verified via axe on the\n // stories). z-[2] sits ABOVE the reused TaskCard's z-[1] action overlay so the\n // sticky header is never painted under a card scrolling beneath it.\n const tone =\n bucketKey === 'overdue'\n ? 'ds:text-[color:var(--destructive)] ds:font-semibold'\n : bucketKey === 'today'\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]';\n return (\n <div\n ref={headerRef as React.Ref<HTMLDivElement>}\n data-bucket={bucketKey}\n className={[\n 'ds:sticky ds:top-0 ds:z-[2] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n tone,\n ].join(' ')}\n >\n {bucketKey === 'today' ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n <span className=\"ds:text-[color:var(--muted-foreground)]\">\n {`(${count})`}\n </span>\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type TasksPanelSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["__iconNode","Coins","createLucideIcon","Gem","Megaphone","Tag","tasksPanelAgent","handle","args","EDGE_LOAD_THRESHOLD","rootVariants","cva","scrollRegionClasses","rowElevationClass","SYSTEM_TYPE_META","BUCKET_ORDER","startOfDay","d","dayBoundaries","now","today","tomorrow","dayAfter","dow","nextWeek","bucketFor","item","startOfToday","startOfTomorrow","startOfDayAfter","startOfNextWeek","due","isOverdue","groupByDueBucket","items","map","key","list","buckets","a","b","TasksPanel","forwardRef","id","nowIso","title","size","onOpenTask","onToggleDone","onEditTask","onDismissTask","onAddTask","readOnly","renderItemActions","scope","defaultScope","onScopeChange","availableScopes","onLoadMore","hasMore","loadingMore","loading","error","showFilters","statusFilter","defaultStatusFilter","onStatusFilterChange","typeOptions","typeFilter","onTypeFilterChange","assigneeOptions","assigneeFilter","onAssigneeFilterChange","overdueOnly","defaultOverdueOnly","onOverdueOnlyChange","emptyTitle","emptyDescription","emptyAction","className","ariaLabel","rest","ref","t","useTranslation","headingId","useId","overdueSwitchId","heading","statusLabels","scopeLabels","bucketLabels","systemTypeLabels","useMemo","scopeState","setScopeState","useState","currentScope","changeScope","useCallback","next","statusState","setStatusState","currentStatus","changeStatus","typeState","setTypeState","currentType","changeType","assigneeState","setAssigneeState","currentAssignee","changeAssignee","overdueState","setOverdueState","currentOverdueOnly","changeOverdueOnly","clearFilters","visible","isDone","scrollRef","useRef","overdueHeaderRef","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","region","scrollTop","scrollHeight","clientHeight","useIsomorphicLayoutEffect","observer","moreAvailable","handleScroll","jumpToOverdue","el","delta","itemsRef","innerRef","useImperativeHandle","i","targetId","found","useAgentRegistration","renderTypeBadge","meta","variant","Icon","label","jsx","Badge","defaultActions","done","jsxs","Fragment","IconButton","SquareCheckBig","Square","Pencil","X","renderRowActions","trailing","badge","isFirstUseEmpty","isFilteredEmpty","skeletonRow","Skeleton","body","EmptyState","bucket","BucketHeader","TaskCard","Button","showScopeSegment","statusValues","headerActions","Plus","headerFilters","ButtonGroup","value","active","Select","Switch","PanelHeader","ClipboardCheck","bucketKey","count","headerRef"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
@@ -2,8 +2,8 @@ import { jsx as t, jsxs as m, Fragment as V } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as M, useRef as k, useImperativeHandle as N, useMemo as _, useCallback as S } from "react";
|
|
3
3
|
import { c as P } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as g } from "react-i18next";
|
|
5
|
-
import { I as y } from "./icon-button-
|
|
6
|
-
import { I as j } from "./icon-button-group-
|
|
5
|
+
import { I as y } from "./icon-button-DA2CAGHZ.js";
|
|
6
|
+
import { I as j } from "./icon-button-group-D6SVMteH.js";
|
|
7
7
|
import { S as K } from "./switch-OILsBLWo.js";
|
|
8
8
|
import { D as o } from "./dropdown-menu-DU-Hrf33.js";
|
|
9
9
|
import { u as x } from "./use-theme-CAuo6EYT.js";
|
|
@@ -364,4 +364,4 @@ export {
|
|
|
364
364
|
F as T,
|
|
365
365
|
D as t
|
|
366
366
|
};
|
|
367
|
-
//# sourceMappingURL=theme-toggle-
|
|
367
|
+
//# sourceMappingURL=theme-toggle-DuMhQNFS.js.map
|