claude-code-workflow 7.2.19 → 7.2.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/.claude/commands/workflow/analyze-with-file.md +58 -20
  2. package/.codex/skills/analyze-with-file/SKILL.md +55 -8
  3. package/.codex/skills/team-arch-opt/SKILL.md +24 -0
  4. package/.codex/skills/team-arch-opt/roles/coordinator/role.md +22 -0
  5. package/.codex/skills/team-brainstorm/SKILL.md +24 -0
  6. package/.codex/skills/team-brainstorm/roles/coordinator/role.md +20 -0
  7. package/.codex/skills/team-coordinate/SKILL.md +24 -0
  8. package/.codex/skills/team-coordinate/roles/coordinator/role.md +40 -12
  9. package/.codex/skills/team-frontend/SKILL.md +24 -0
  10. package/.codex/skills/team-frontend/roles/coordinator/role.md +20 -0
  11. package/.codex/skills/team-frontend-debug/SKILL.md +24 -0
  12. package/.codex/skills/team-frontend-debug/roles/coordinator/role.md +21 -0
  13. package/.codex/skills/team-issue/SKILL.md +24 -0
  14. package/.codex/skills/team-issue/roles/coordinator/role.md +19 -0
  15. package/.codex/skills/team-iterdev/SKILL.md +24 -0
  16. package/.codex/skills/team-iterdev/roles/coordinator/role.md +20 -0
  17. package/.codex/skills/team-lifecycle-v4/SKILL.md +24 -0
  18. package/.codex/skills/team-lifecycle-v4/roles/coordinator/role.md +28 -2
  19. package/.codex/skills/team-perf-opt/SKILL.md +24 -0
  20. package/.codex/skills/team-perf-opt/roles/coordinator/role.md +20 -0
  21. package/.codex/skills/team-planex/SKILL.md +24 -0
  22. package/.codex/skills/team-planex/roles/coordinator/role.md +19 -0
  23. package/.codex/skills/team-quality-assurance/SKILL.md +24 -0
  24. package/.codex/skills/team-quality-assurance/roles/coordinator/role.md +21 -0
  25. package/.codex/skills/team-review/SKILL.md +24 -0
  26. package/.codex/skills/team-review/roles/coordinator/role.md +21 -0
  27. package/.codex/skills/team-roadmap-dev/SKILL.md +24 -0
  28. package/.codex/skills/team-roadmap-dev/roles/coordinator/role.md +19 -0
  29. package/.codex/skills/team-tech-debt/SKILL.md +24 -0
  30. package/.codex/skills/team-tech-debt/roles/coordinator/role.md +19 -0
  31. package/.codex/skills/team-testing/SKILL.md +24 -0
  32. package/.codex/skills/team-testing/roles/coordinator/role.md +21 -0
  33. package/.codex/skills/team-uidesign/SKILL.md +24 -0
  34. package/.codex/skills/team-uidesign/roles/coordinator/role.md +20 -0
  35. package/.codex/skills/team-ultra-analyze/SKILL.md +24 -0
  36. package/.codex/skills/team-ultra-analyze/roles/coordinator/role.md +20 -0
  37. package/.codex/skills/team-ux-improve/SKILL.md +24 -0
  38. package/.codex/skills/team-ux-improve/roles/coordinator/role.md +20 -0
  39. package/ccw/frontend/dist/assets/{AlertDialog-zDuLRyN3.js → AlertDialog-Cukb0xv2.js} +2 -2
  40. package/ccw/frontend/dist/assets/{AlertDialog-zDuLRyN3.js.map → AlertDialog-Cukb0xv2.js.map} +1 -1
  41. package/ccw/frontend/dist/assets/{AnalysisPage-DGCGwIZY.js → AnalysisPage-Ddmv0J4x.js} +2 -2
  42. package/ccw/frontend/dist/assets/{AnalysisPage-DGCGwIZY.js.map → AnalysisPage-Ddmv0J4x.js.map} +1 -1
  43. package/ccw/frontend/dist/assets/{ApiSettingsPage-CgclCqmv.js → ApiSettingsPage-DMkrTZDX.js} +2 -2
  44. package/ccw/frontend/dist/assets/{ApiSettingsPage-CgclCqmv.js.map → ApiSettingsPage-DMkrTZDX.js.map} +1 -1
  45. package/ccw/frontend/dist/assets/{CliModeToggle-CbGH7qO4.js → CliModeToggle-DXenjpbe.js} +2 -2
  46. package/ccw/frontend/dist/assets/{CliModeToggle-CbGH7qO4.js.map → CliModeToggle-DXenjpbe.js.map} +1 -1
  47. package/ccw/frontend/dist/assets/{CliSessionSharePage-CJGlwyDw.js → CliSessionSharePage-B-ZIMqmX.js} +2 -2
  48. package/ccw/frontend/dist/assets/{CliSessionSharePage-CJGlwyDw.js.map → CliSessionSharePage-B-ZIMqmX.js.map} +1 -1
  49. package/ccw/frontend/dist/assets/{CliViewerPage-D-MHYyDt.js → CliViewerPage-9YxGyLxh.js} +2 -2
  50. package/ccw/frontend/dist/assets/{CliViewerPage-D-MHYyDt.js.map → CliViewerPage-9YxGyLxh.js.map} +1 -1
  51. package/ccw/frontend/dist/assets/{CodexLensPage-z6miX68P.js → CodexLensPage-B_uv5wdn.js} +2 -2
  52. package/ccw/frontend/dist/assets/{CodexLensPage-z6miX68P.js.map → CodexLensPage-B_uv5wdn.js.map} +1 -1
  53. package/ccw/frontend/dist/assets/{Collapsible-D5zS2wef.js → Collapsible-C2qk3yV0.js} +2 -2
  54. package/ccw/frontend/dist/assets/{Collapsible-D5zS2wef.js.map → Collapsible-C2qk3yV0.js.map} +1 -1
  55. package/ccw/frontend/dist/assets/{CommandsManagerPage-ChcTwmAn.js → CommandsManagerPage-DBtaWxLB.js} +2 -2
  56. package/ccw/frontend/dist/assets/{CommandsManagerPage-ChcTwmAn.js.map → CommandsManagerPage-DBtaWxLB.js.map} +1 -1
  57. package/ccw/frontend/dist/assets/{DeepWikiPage-Cv5LifSi.js → DeepWikiPage-d9K4_TgG.js} +2 -2
  58. package/ccw/frontend/dist/assets/{DeepWikiPage-Cv5LifSi.js.map → DeepWikiPage-d9K4_TgG.js.map} +1 -1
  59. package/ccw/frontend/dist/assets/{EndpointsPage-BcyNmqIa.js → EndpointsPage-DhW6hYrI.js} +2 -2
  60. package/ccw/frontend/dist/assets/{EndpointsPage-BcyNmqIa.js.map → EndpointsPage-DhW6hYrI.js.map} +1 -1
  61. package/ccw/frontend/dist/assets/{ExplorerPage-DfHtqeQM.js → ExplorerPage-DYYpCvtB.js} +2 -2
  62. package/ccw/frontend/dist/assets/{ExplorerPage-DfHtqeQM.js.map → ExplorerPage-DYYpCvtB.js.map} +1 -1
  63. package/ccw/frontend/dist/assets/{FixSessionPage-CbvZApeF.js → FixSessionPage-CSmiT5SE.js} +2 -2
  64. package/ccw/frontend/dist/assets/{FixSessionPage-CbvZApeF.js.map → FixSessionPage-CSmiT5SE.js.map} +1 -1
  65. package/ccw/frontend/dist/assets/{FloatingFileBrowser-DLz85cw9.js → FloatingFileBrowser-DvMsXLdP.js} +2 -2
  66. package/ccw/frontend/dist/assets/{FloatingFileBrowser-DLz85cw9.js.map → FloatingFileBrowser-DvMsXLdP.js.map} +1 -1
  67. package/ccw/frontend/dist/assets/{FloatingPanel-DrUTmgtV.js → FloatingPanel-sqezhSI8.js} +2 -2
  68. package/ccw/frontend/dist/assets/{FloatingPanel-DrUTmgtV.js.map → FloatingPanel-sqezhSI8.js.map} +1 -1
  69. package/ccw/frontend/dist/assets/{GraphExplorerPage-C439yLvH.js → GraphExplorerPage-DS8ghMFM.js} +2 -2
  70. package/ccw/frontend/dist/assets/{GraphExplorerPage-C439yLvH.js.map → GraphExplorerPage-DS8ghMFM.js.map} +1 -1
  71. package/ccw/frontend/dist/assets/{HistoryPage-BClJJMEy.js → HistoryPage-B-x1RyHu.js} +2 -2
  72. package/ccw/frontend/dist/assets/{HistoryPage-BClJJMEy.js.map → HistoryPage-B-x1RyHu.js.map} +1 -1
  73. package/ccw/frontend/dist/assets/{HookManagerPage-DI-2QDLJ.js → HookManagerPage-BbxpDb68.js} +2 -2
  74. package/ccw/frontend/dist/assets/{HookManagerPage-DI-2QDLJ.js.map → HookManagerPage-BbxpDb68.js.map} +1 -1
  75. package/ccw/frontend/dist/assets/{InstallationsPage-DKlz1ypL.js → InstallationsPage-3bShz_Ai.js} +2 -2
  76. package/ccw/frontend/dist/assets/{InstallationsPage-DKlz1ypL.js.map → InstallationsPage-3bShz_Ai.js.map} +1 -1
  77. package/ccw/frontend/dist/assets/{IssueHubPage--6DduN4j.js → IssueHubPage-BQY_Hh3e.js} +2 -2
  78. package/ccw/frontend/dist/assets/{IssueHubPage--6DduN4j.js.map → IssueHubPage-BQY_Hh3e.js.map} +1 -1
  79. package/ccw/frontend/dist/assets/{LiteTasksPage-39j6xEeL.js → LiteTasksPage-vD_8fQcR.js} +2 -2
  80. package/ccw/frontend/dist/assets/{LiteTasksPage-39j6xEeL.js.map → LiteTasksPage-vD_8fQcR.js.map} +1 -1
  81. package/ccw/frontend/dist/assets/{McpManagerPage-D00C9RVN.js → McpManagerPage-CI5ZzB8A.js} +2 -2
  82. package/ccw/frontend/dist/assets/{McpManagerPage-D00C9RVN.js.map → McpManagerPage-CI5ZzB8A.js.map} +1 -1
  83. package/ccw/frontend/dist/assets/{MemoryPage-BXWKdTyM.js → MemoryPage-CNuj2eNg.js} +2 -2
  84. package/ccw/frontend/dist/assets/{MemoryPage-BXWKdTyM.js.map → MemoryPage-CNuj2eNg.js.map} +1 -1
  85. package/ccw/frontend/dist/assets/{NotFoundPage-h5o3I7cF.js → NotFoundPage-BrnAXkb1.js} +2 -2
  86. package/ccw/frontend/dist/assets/{NotFoundPage-h5o3I7cF.js.map → NotFoundPage-BrnAXkb1.js.map} +1 -1
  87. package/ccw/frontend/dist/assets/{OrchestratorPage-jkyjmiI1.js → OrchestratorPage-CH81PGt4.js} +2 -2
  88. package/ccw/frontend/dist/assets/{OrchestratorPage-jkyjmiI1.js.map → OrchestratorPage-CH81PGt4.js.map} +1 -1
  89. package/ccw/frontend/dist/assets/{ProjectOverviewPage-C2bE5eb2.js → ProjectOverviewPage-dwiEXl2O.js} +2 -2
  90. package/ccw/frontend/dist/assets/{ProjectOverviewPage-C2bE5eb2.js.map → ProjectOverviewPage-dwiEXl2O.js.map} +1 -1
  91. package/ccw/frontend/dist/assets/{PromptHistoryPage-DzmPK4GZ.js → PromptHistoryPage-CabgLjJU.js} +2 -2
  92. package/ccw/frontend/dist/assets/{PromptHistoryPage-DzmPK4GZ.js.map → PromptHistoryPage-CabgLjJU.js.map} +1 -1
  93. package/ccw/frontend/dist/assets/{ReviewSessionPage-CVMH1K6G.js → ReviewSessionPage-DAMrNFn8.js} +2 -2
  94. package/ccw/frontend/dist/assets/{ReviewSessionPage-CVMH1K6G.js.map → ReviewSessionPage-DAMrNFn8.js.map} +1 -1
  95. package/ccw/frontend/dist/assets/{RulesManagerPage-BDZco-r2.js → RulesManagerPage-4jzmxPn0.js} +2 -2
  96. package/ccw/frontend/dist/assets/{RulesManagerPage-BDZco-r2.js.map → RulesManagerPage-4jzmxPn0.js.map} +1 -1
  97. package/ccw/frontend/dist/assets/{SessionDetailPage-D5cM-8Kk.js → SessionDetailPage-C5Btktmp.js} +2 -2
  98. package/ccw/frontend/dist/assets/{SessionDetailPage-D5cM-8Kk.js.map → SessionDetailPage-C5Btktmp.js.map} +1 -1
  99. package/ccw/frontend/dist/assets/{SessionsPage-BFy74ye3.js → SessionsPage-CQIB4E8m.js} +2 -2
  100. package/ccw/frontend/dist/assets/{SessionsPage-BFy74ye3.js.map → SessionsPage-CQIB4E8m.js.map} +1 -1
  101. package/ccw/frontend/dist/assets/SettingsPage-Yi9UAfm7.js +150 -0
  102. package/ccw/frontend/dist/assets/SettingsPage-Yi9UAfm7.js.map +1 -0
  103. package/ccw/frontend/dist/assets/{SkillsManagerPage-8Dsq4AUD.js → SkillsManagerPage-BqfvYSkT.js} +2 -2
  104. package/ccw/frontend/dist/assets/{SkillsManagerPage-8Dsq4AUD.js.map → SkillsManagerPage-BqfvYSkT.js.map} +1 -1
  105. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CG77iAYQ.js → SpecsSettingsPage-BdVPM5R6.js} +2 -2
  106. package/ccw/frontend/dist/assets/{SpecsSettingsPage-CG77iAYQ.js.map → SpecsSettingsPage-BdVPM5R6.js.map} +1 -1
  107. package/ccw/frontend/dist/assets/{Switch-BbuvVsX-.js → Switch-BG929kV0.js} +2 -2
  108. package/ccw/frontend/dist/assets/{Switch-BbuvVsX-.js.map → Switch-BG929kV0.js.map} +1 -1
  109. package/ccw/frontend/dist/assets/{TabsNavigation-SGJhC8-P.js → TabsNavigation-Bol1y09b.js} +2 -2
  110. package/ccw/frontend/dist/assets/{TabsNavigation-SGJhC8-P.js.map → TabsNavigation-Bol1y09b.js.map} +1 -1
  111. package/ccw/frontend/dist/assets/{TaskDrawer-p51jeScU.js → TaskDrawer-Dwutrn8_.js} +2 -2
  112. package/ccw/frontend/dist/assets/{TaskDrawer-p51jeScU.js.map → TaskDrawer-Dwutrn8_.js.map} +1 -1
  113. package/ccw/frontend/dist/assets/{TeamPage-CvZBThbr.js → TeamPage-CpCSwpxD.js} +2 -2
  114. package/ccw/frontend/dist/assets/{TeamPage-CvZBThbr.js.map → TeamPage-CpCSwpxD.js.map} +1 -1
  115. package/ccw/frontend/dist/assets/{TerminalDashboardPage-uhM7kGKI.js → TerminalDashboardPage-DODKjOeK.js} +2 -2
  116. package/ccw/frontend/dist/assets/{TerminalDashboardPage-uhM7kGKI.js.map → TerminalDashboardPage-DODKjOeK.js.map} +1 -1
  117. package/ccw/frontend/dist/assets/{archive-D6ySrtHC.js → archive-CQw634kD.js} +2 -2
  118. package/ccw/frontend/dist/assets/{archive-D6ySrtHC.js.map → archive-CQw634kD.js.map} +1 -1
  119. package/ccw/frontend/dist/assets/{archive-restore-C1uI-5TY.js → archive-restore-B-_EG6wE.js} +2 -2
  120. package/ccw/frontend/dist/assets/{archive-restore-C1uI-5TY.js.map → archive-restore-B-_EG6wE.js.map} +1 -1
  121. package/ccw/frontend/dist/assets/{arrow-right-qE5-FMG8.js → arrow-right-CcQtxBrU.js} +2 -2
  122. package/ccw/frontend/dist/assets/{arrow-right-qE5-FMG8.js.map → arrow-right-CcQtxBrU.js.map} +1 -1
  123. package/ccw/frontend/dist/assets/{bookmark-plus-DL4iL38T.js → bookmark-plus-Cl-BbcpR.js} +2 -2
  124. package/ccw/frontend/dist/assets/{bookmark-plus-DL4iL38T.js.map → bookmark-plus-Cl-BbcpR.js.map} +1 -1
  125. package/ccw/frontend/dist/assets/{bot-CZzIeEkg.js → bot-CLSNSkW_.js} +2 -2
  126. package/ccw/frontend/dist/assets/{bot-CZzIeEkg.js.map → bot-CLSNSkW_.js.map} +1 -1
  127. package/ccw/frontend/dist/assets/{braces-MEPRT2LN.js → braces-DWwkaDS6.js} +2 -2
  128. package/ccw/frontend/dist/assets/{braces-MEPRT2LN.js.map → braces-DWwkaDS6.js.map} +1 -1
  129. package/ccw/frontend/dist/assets/{circle-stop-GQcecSUg.js → circle-stop-DiS7e6ma.js} +2 -2
  130. package/ccw/frontend/dist/assets/{circle-stop-GQcecSUg.js.map → circle-stop-DiS7e6ma.js.map} +1 -1
  131. package/ccw/frontend/dist/assets/{cpu-CzxYMs1Y.js → cpu-CuvHUVXO.js} +2 -2
  132. package/ccw/frontend/dist/assets/{cpu-CzxYMs1Y.js.map → cpu-CuvHUVXO.js.map} +1 -1
  133. package/ccw/frontend/dist/assets/{ellipsis-vertical-DZMfiFKo.js → ellipsis-vertical-BoVlINSw.js} +2 -2
  134. package/ccw/frontend/dist/assets/{ellipsis-vertical-DZMfiFKo.js.map → ellipsis-vertical-BoVlINSw.js.map} +1 -1
  135. package/ccw/frontend/dist/assets/{eye-BXfPoClW.js → eye-BEMOdcAN.js} +2 -2
  136. package/ccw/frontend/dist/assets/{eye-BXfPoClW.js.map → eye-BEMOdcAN.js.map} +1 -1
  137. package/ccw/frontend/dist/assets/{eye-off-CyaKXmAk.js → eye-off-C5HS4Ytm.js} +2 -2
  138. package/ccw/frontend/dist/assets/{eye-off-CyaKXmAk.js.map → eye-off-C5HS4Ytm.js.map} +1 -1
  139. package/ccw/frontend/dist/assets/{file-json-B4LbFfTU.js → file-json-DQ9XLq0B.js} +2 -2
  140. package/ccw/frontend/dist/assets/{file-json-B4LbFfTU.js.map → file-json-DQ9XLq0B.js.map} +1 -1
  141. package/ccw/frontend/dist/assets/{file-text-CIWG7Xgj.js → file-text-TGs_qCbw.js} +2 -2
  142. package/ccw/frontend/dist/assets/{file-text-CIWG7Xgj.js.map → file-text-TGs_qCbw.js.map} +1 -1
  143. package/ccw/frontend/dist/assets/{filter-CNBjjvBX.js → filter-CIuCqnDB.js} +2 -2
  144. package/ccw/frontend/dist/assets/{filter-CNBjjvBX.js.map → filter-CIuCqnDB.js.map} +1 -1
  145. package/ccw/frontend/dist/assets/{folder-DT_XOYw9.js → folder-BkivHBwn.js} +2 -2
  146. package/ccw/frontend/dist/assets/{folder-DT_XOYw9.js.map → folder-BkivHBwn.js.map} +1 -1
  147. package/ccw/frontend/dist/assets/{gauge-mvQWOG3S.js → gauge-CtM68fVY.js} +2 -2
  148. package/ccw/frontend/dist/assets/{gauge-mvQWOG3S.js.map → gauge-CtM68fVY.js.map} +1 -1
  149. package/ccw/frontend/dist/assets/{globe-B25jraBz.js → globe-DpnrINqP.js} +2 -2
  150. package/ccw/frontend/dist/assets/{globe-B25jraBz.js.map → globe-DpnrINqP.js.map} +1 -1
  151. package/ccw/frontend/dist/assets/{grid-3x3-CptugI_Z.js → grid-3x3-SjX0a5JH.js} +2 -2
  152. package/ccw/frontend/dist/assets/{grid-3x3-CptugI_Z.js.map → grid-3x3-SjX0a5JH.js.map} +1 -1
  153. package/ccw/frontend/dist/assets/{hard-drive-BUK9Wcoz.js → hard-drive-ByAmnoEg.js} +2 -2
  154. package/ccw/frontend/dist/assets/{hard-drive-BUK9Wcoz.js.map → hard-drive-ByAmnoEg.js.map} +1 -1
  155. package/ccw/frontend/dist/assets/{hash-dddMDYK7.js → hash-DbLc3VOZ.js} +2 -2
  156. package/ccw/frontend/dist/assets/{hash-dddMDYK7.js.map → hash-DbLc3VOZ.js.map} +1 -1
  157. package/ccw/frontend/dist/assets/{history-BdDj8MtC.js → history-Botz5Z5d.js} +2 -2
  158. package/ccw/frontend/dist/assets/{history-BdDj8MtC.js.map → history-Botz5Z5d.js.map} +1 -1
  159. package/ccw/frontend/dist/assets/{index-CcxBnbbQ.js → index-BGvyf4-9.js} +2 -2
  160. package/ccw/frontend/dist/assets/{index-CcxBnbbQ.js.map → index-BGvyf4-9.js.map} +1 -1
  161. package/ccw/frontend/dist/assets/index-BoqylFO4.css +39 -0
  162. package/ccw/frontend/dist/assets/{index-DZGHdspr.js → index-DP_mTJI8.js} +3 -3
  163. package/ccw/frontend/dist/assets/{index-DZGHdspr.js.map → index-DP_mTJI8.js.map} +1 -1
  164. package/ccw/frontend/dist/assets/{index-B6UfIzhR.js → index-MkgdhX7a.js} +2 -2
  165. package/ccw/frontend/dist/assets/{index-B6UfIzhR.js.map → index-MkgdhX7a.js.map} +1 -1
  166. package/ccw/frontend/dist/assets/{index-EFcT7h67.js → index-ni-tG9rm.js} +2 -2
  167. package/ccw/frontend/dist/assets/{index-EFcT7h67.js.map → index-ni-tG9rm.js.map} +1 -1
  168. package/ccw/frontend/dist/assets/{layout-grid-BVlT1oI7.js → layout-grid-11E4bGJz.js} +2 -2
  169. package/ccw/frontend/dist/assets/{layout-grid-BVlT1oI7.js.map → layout-grid-11E4bGJz.js.map} +1 -1
  170. package/ccw/frontend/dist/assets/{lightbulb-Mt3Tlwh4.js → lightbulb-8KrKY82b.js} +2 -2
  171. package/ccw/frontend/dist/assets/{lightbulb-Mt3Tlwh4.js.map → lightbulb-8KrKY82b.js.map} +1 -1
  172. package/ccw/frontend/dist/assets/{link-2-DXqT64qo.js → link-2-BUn6RILb.js} +2 -2
  173. package/ccw/frontend/dist/assets/{link-2-DXqT64qo.js.map → link-2-BUn6RILb.js.map} +1 -1
  174. package/ccw/frontend/dist/assets/{link-CBMtrpcI.js → link-CmP254Ai.js} +2 -2
  175. package/ccw/frontend/dist/assets/{link-CBMtrpcI.js.map → link-CmP254Ai.js.map} +1 -1
  176. package/ccw/frontend/dist/assets/{list-DDyEM4AO.js → list-BAwzl4a2.js} +2 -2
  177. package/ccw/frontend/dist/assets/{list-DDyEM4AO.js.map → list-BAwzl4a2.js.map} +1 -1
  178. package/ccw/frontend/dist/assets/{map-pin-B2FxBKfk.js → map-pin-gi342rqk.js} +2 -2
  179. package/ccw/frontend/dist/assets/{map-pin-B2FxBKfk.js.map → map-pin-gi342rqk.js.map} +1 -1
  180. package/ccw/frontend/dist/assets/{messages-square-zJfTY9pq.js → messages-square-C1Lh8q8b.js} +2 -2
  181. package/ccw/frontend/dist/assets/{messages-square-zJfTY9pq.js.map → messages-square-C1Lh8q8b.js.map} +1 -1
  182. package/ccw/frontend/dist/assets/{minimize-2-DnhGZj79.js → minimize-2-OgWNLKdq.js} +2 -2
  183. package/ccw/frontend/dist/assets/{minimize-2-DnhGZj79.js.map → minimize-2-OgWNLKdq.js.map} +1 -1
  184. package/ccw/frontend/dist/assets/{package-DYzAybhU.js → package-Djsvs5qp.js} +2 -2
  185. package/ccw/frontend/dist/assets/{package-DYzAybhU.js.map → package-Djsvs5qp.js.map} +1 -1
  186. package/ccw/frontend/dist/assets/{plug-B3kKHsu1.js → plug-DvSZP2cp.js} +2 -2
  187. package/ccw/frontend/dist/assets/{plug-B3kKHsu1.js.map → plug-DvSZP2cp.js.map} +1 -1
  188. package/ccw/frontend/dist/assets/{power-BPNNZgLy.js → power-BY7vTLmU.js} +2 -2
  189. package/ccw/frontend/dist/assets/{power-BPNNZgLy.js.map → power-BY7vTLmU.js.map} +1 -1
  190. package/ccw/frontend/dist/assets/{save-Cwry93p-.js → save-DXfqv84T.js} +2 -2
  191. package/ccw/frontend/dist/assets/{save-Cwry93p-.js.map → save-DXfqv84T.js.map} +1 -1
  192. package/ccw/frontend/dist/assets/{send-DuWWy2J8.js → send-E2o2LZSX.js} +2 -2
  193. package/ccw/frontend/dist/assets/{send-DuWWy2J8.js.map → send-E2o2LZSX.js.map} +1 -1
  194. package/ccw/frontend/dist/assets/{settings-2-C3U1eSK6.js → settings-2-ChD1LFHH.js} +2 -2
  195. package/ccw/frontend/dist/assets/{settings-2-C3U1eSK6.js.map → settings-2-ChD1LFHH.js.map} +1 -1
  196. package/ccw/frontend/dist/assets/{square-check-big-CrG1ejFB.js → square-check-big-CBymuqmD.js} +2 -2
  197. package/ccw/frontend/dist/assets/{square-check-big-CrG1ejFB.js.map → square-check-big-CBymuqmD.js.map} +1 -1
  198. package/ccw/frontend/dist/assets/{square-pen-eLWlCgZ5.js → square-pen-BfaiJgOX.js} +2 -2
  199. package/ccw/frontend/dist/assets/{square-pen-eLWlCgZ5.js.map → square-pen-BfaiJgOX.js.map} +1 -1
  200. package/ccw/frontend/dist/assets/{star-sveo4KRn.js → star-DHMWqZ09.js} +2 -2
  201. package/ccw/frontend/dist/assets/{star-sveo4KRn.js.map → star-DHMWqZ09.js.map} +1 -1
  202. package/ccw/frontend/dist/assets/{style-CRdAX7Cu.js → style-wvcOEAiM.js} +2 -2
  203. package/ccw/frontend/dist/assets/{style-CRdAX7Cu.js.map → style-wvcOEAiM.js.map} +1 -1
  204. package/ccw/frontend/dist/assets/{target-Oz1-z8Zu.js → target-B8AMmf_N.js} +2 -2
  205. package/ccw/frontend/dist/assets/{target-Oz1-z8Zu.js.map → target-B8AMmf_N.js.map} +1 -1
  206. package/ccw/frontend/dist/assets/{test-tube-BozkZKD6.js → test-tube-BpDeTJi1.js} +2 -2
  207. package/ccw/frontend/dist/assets/{test-tube-BozkZKD6.js.map → test-tube-BpDeTJi1.js.map} +1 -1
  208. package/ccw/frontend/dist/assets/{upload-CTlUsxyh.js → upload-pflkdIDG.js} +2 -2
  209. package/ccw/frontend/dist/assets/{upload-CTlUsxyh.js.map → upload-pflkdIDG.js.map} +1 -1
  210. package/ccw/frontend/dist/assets/{useApiSettings-D6WfgFYj.js → useApiSettings-BPx4DyKT.js} +2 -2
  211. package/ccw/frontend/dist/assets/{useApiSettings-D6WfgFYj.js.map → useApiSettings-BPx4DyKT.js.map} +1 -1
  212. package/ccw/frontend/dist/assets/{useCli-CgGVNN5I.js → useCli-D1jfH3XA.js} +2 -2
  213. package/ccw/frontend/dist/assets/{useCli-CgGVNN5I.js.map → useCli-D1jfH3XA.js.map} +1 -1
  214. package/ccw/frontend/dist/assets/{useCommands-o5CKv-10.js → useCommands-DhR71vpa.js} +2 -2
  215. package/ccw/frontend/dist/assets/{useCommands-o5CKv-10.js.map → useCommands-DhR71vpa.js.map} +1 -1
  216. package/ccw/frontend/dist/assets/{useDebounce-rKo_bCBK.js → useDebounce-a6Yyer3m.js} +2 -2
  217. package/ccw/frontend/dist/assets/{useDebounce-rKo_bCBK.js.map → useDebounce-a6Yyer3m.js.map} +1 -1
  218. package/ccw/frontend/dist/assets/{useFileExplorer-WeE4t9Hg.js → useFileExplorer-B8W2JTj2.js} +2 -2
  219. package/ccw/frontend/dist/assets/{useFileExplorer-WeE4t9Hg.js.map → useFileExplorer-B8W2JTj2.js.map} +1 -1
  220. package/ccw/frontend/dist/assets/{useLocale-BS0tTC-_.js → useLocale-aMHdQIL_.js} +2 -2
  221. package/ccw/frontend/dist/assets/{useLocale-BS0tTC-_.js.map → useLocale-aMHdQIL_.js.map} +1 -1
  222. package/ccw/frontend/dist/assets/{useSkills-BUgAhw6r.js → useSkills-BHpc2LtN.js} +3 -3
  223. package/ccw/frontend/dist/assets/{useSkills-BUgAhw6r.js.map → useSkills-BHpc2LtN.js.map} +1 -1
  224. package/ccw/frontend/dist/assets/{useSystemSettings-CLhmINg1.js → useSystemSettings-BFD0SvEF.js} +2 -2
  225. package/ccw/frontend/dist/assets/{useSystemSettings-CLhmINg1.js.map → useSystemSettings-BFD0SvEF.js.map} +1 -1
  226. package/ccw/frontend/dist/assets/{wand-sparkles-BUHKJH1X.js → wand-sparkles-dYtI2IKM.js} +2 -2
  227. package/ccw/frontend/dist/assets/{wand-sparkles-BUHKJH1X.js.map → wand-sparkles-dYtI2IKM.js.map} +1 -1
  228. package/ccw/frontend/dist/index.html +2 -2
  229. package/package.json +1 -1
  230. package/ccw/frontend/dist/assets/SettingsPage-Qj0fFDjX.js +0 -150
  231. package/ccw/frontend/dist/assets/SettingsPage-Qj0fFDjX.js.map +0 -1
  232. package/ccw/frontend/dist/assets/index-nU0QYi1y.css +0 -39
@@ -1 +1 @@
1
- {"version":3,"file":"McpManagerPage-D00C9RVN.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/files.js","../../../../node_modules/lucide-react/dist/esm/icons/folder-tree.js","../../../../node_modules/lucide-react/dist/esm/icons/key.js","../../../../node_modules/lucide-react/dist/esm/icons/message-circle-question.js","../../../../node_modules/lucide-react/dist/esm/icons/pen-line.js","../../src/hooks/useMcpServers.ts","../../src/components/mcp/ConfigTypeToggle.tsx","../../src/components/mcp/McpServerDialog.tsx","../../src/components/mcp/CodexMcpEditableCard.tsx","../../src/components/mcp/CcwToolsMcpCard.tsx","../../src/components/mcp/McpTemplatesSection.tsx","../../src/components/mcp/RecommendedMcpWizard.tsx","../../src/components/mcp/RecommendedMcpSection.tsx","../../src/components/mcp/WindowsCompatibilityWarning.tsx","../../src/components/mcp/CrossCliSyncPanel.tsx","../../src/components/mcp/AllProjectsTable.tsx","../../src/components/mcp/OtherProjectsSection.tsx","../../src/pages/McpManagerPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Files = createLucideIcon(\"Files\", [\n [\"path\", { d: \"M20 7h-3a2 2 0 0 1-2-2V2\", key: \"x099mo\" }],\n [\"path\", { d: \"M9 18a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h7l4 4v10a2 2 0 0 1-2 2Z\", key: \"18t6ie\" }],\n [\"path\", { d: \"M3 7.6v12.8A1.6 1.6 0 0 0 4.6 22h9.8\", key: \"1nja0z\" }]\n]);\n\nexport { Files as default };\n//# sourceMappingURL=files.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FolderTree = createLucideIcon(\"FolderTree\", [\n [\n \"path\",\n {\n d: \"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z\",\n key: \"hod4my\"\n }\n ],\n [\n \"path\",\n {\n d: \"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z\",\n key: \"w4yl2u\"\n }\n ],\n [\"path\", { d: \"M3 5a2 2 0 0 0 2 2h3\", key: \"f2jnh7\" }],\n [\"path\", { d: \"M3 3v13a2 2 0 0 0 2 2h3\", key: \"k8epm1\" }]\n]);\n\nexport { FolderTree as default };\n//# sourceMappingURL=folder-tree.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Key = createLucideIcon(\"Key\", [\n [\"path\", { d: \"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\", key: \"g0fldk\" }],\n [\"path\", { d: \"m21 2-9.6 9.6\", key: \"1j0ho8\" }],\n [\"circle\", { cx: \"7.5\", cy: \"15.5\", r: \"5.5\", key: \"yqb3hr\" }]\n]);\n\nexport { Key as default };\n//# sourceMappingURL=key.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MessageCircleQuestion = createLucideIcon(\"MessageCircleQuestion\", [\n [\"path\", { d: \"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\", key: \"vv11sd\" }],\n [\"path\", { d: \"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\", key: \"1u773s\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n]);\n\nexport { MessageCircleQuestion as default };\n//# sourceMappingURL=message-circle-question.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst PenLine = createLucideIcon(\"PenLine\", [\n [\"path\", { d: \"M12 20h9\", key: \"t2du7b\" }],\n [\n \"path\",\n {\n d: \"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z\",\n key: \"1ykcvy\"\n }\n ]\n]);\n\nexport { PenLine as default };\n//# sourceMappingURL=pen-line.js.map\n","// ========================================\r\n// useMcpServers Hook\r\n// ========================================\r\n// TanStack Query hooks for MCP server management\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport {\r\n fetchMcpServers,\r\n updateMcpServer,\r\n createMcpServer,\r\n deleteMcpServer,\r\n toggleMcpServer,\r\n fetchMcpTemplates,\r\n saveMcpTemplate,\r\n deleteMcpTemplate,\r\n installMcpTemplate,\r\n codexRemoveServer,\r\n codexToggleServer,\r\n fetchAllProjects,\r\n fetchOtherProjectsServers,\r\n crossCliCopy,\r\n type McpServer,\r\n type McpServersResponse,\r\n type McpServerConflict,\r\n type McpProjectConfigType,\r\n type McpTemplate,\r\n type McpTemplateInstallRequest,\r\n type OtherProjectsServersResponse,\r\n type CrossCliCopyRequest,\r\n type CrossCliCopyResponse,\r\n} from '../lib/api';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// Query key factory\r\nexport const mcpServersKeys = {\r\n all: ['mcpServers'] as const,\r\n lists: () => [...mcpServersKeys.all, 'list'] as const,\r\n list: (scope?: 'project' | 'global') => [...mcpServersKeys.lists(), scope] as const,\r\n};\r\n\r\n// Query key factory for MCP templates\r\nexport const mcpTemplatesKeys = {\r\n all: ['mcpTemplates'] as const,\r\n lists: () => [...mcpTemplatesKeys.all, 'list'] as const,\r\n list: (category?: string) => [...mcpTemplatesKeys.lists(), category] as const,\r\n search: (query: string) => [...mcpTemplatesKeys.all, 'search', query] as const,\r\n categories: () => [...mcpTemplatesKeys.all, 'categories'] as const,\r\n};\r\n\r\n// Query key factory for projects\r\nexport const projectsKeys = {\r\n all: ['projects'] as const,\r\n list: () => [...projectsKeys.all, 'list'] as const,\r\n servers: (paths?: string[]) => [...projectsKeys.all, 'servers', ...(paths ?? [])] as const,\r\n};\r\n\r\n// Default stale time: 2 minutes (MCP servers change occasionally)\r\nconst STALE_TIME = 2 * 60 * 1000;\r\n\r\nexport interface UseMcpServersOptions {\r\n scope?: 'project' | 'global';\r\n staleTime?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseMcpServersReturn {\r\n servers: McpServer[];\r\n projectServers: McpServer[];\r\n globalServers: McpServer[];\r\n conflicts: McpServerConflict[];\r\n totalCount: number;\r\n enabledCount: number;\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n invalidate: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching MCP servers\r\n */\r\nexport function useMcpServers(options: UseMcpServersOptions = {}): UseMcpServersReturn {\r\n const { scope, staleTime = STALE_TIME, enabled = true } = options;\r\n const queryClient = useQueryClient();\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n const query = useQuery({\r\n queryKey: mcpServersKeys.list(scope),\r\n queryFn: () => fetchMcpServers(projectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n\r\n const projectServers = query.data?.project ?? [];\r\n const globalServers = query.data?.global ?? [];\r\n const conflicts = query.data?.conflicts ?? [];\r\n const allServers = scope === 'project' ? projectServers : scope === 'global' ? globalServers : [...projectServers, ...globalServers];\r\n\r\n const enabledServers = allServers.filter((s) => s.enabled);\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const invalidate = async () => {\r\n await queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n };\r\n\r\n return {\r\n servers: allServers,\r\n projectServers,\r\n globalServers,\r\n conflicts,\r\n totalCount: allServers.length,\r\n enabledCount: enabledServers.length,\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n invalidate,\r\n };\r\n}\r\n\r\n// ========== Mutations ==========\r\n\r\nexport interface UseUpdateMcpServerReturn {\r\n updateServer: (serverName: string, config: Partial<McpServer>, configType?: McpProjectConfigType) => Promise<McpServer>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useUpdateMcpServer(): UseUpdateMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ serverName, config, configType }: { serverName: string; config: Partial<McpServer>; configType?: McpProjectConfigType }) =>\r\n updateMcpServer(serverName, config, { projectPath: projectPath ?? undefined, configType }),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n updateServer: (serverName, config, configType) => mutation.mutateAsync({ serverName, config, configType }),\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseCreateMcpServerReturn {\r\n createServer: (server: McpServer, configType?: McpProjectConfigType) => Promise<McpServer>;\r\n isCreating: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useCreateMcpServer(): UseCreateMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ server, configType }: { server: McpServer; configType?: McpProjectConfigType }) =>\r\n createMcpServer(server, { projectPath: projectPath ?? undefined, configType }),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n createServer: (server, configType) => mutation.mutateAsync({ server, configType }),\r\n isCreating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteMcpServerReturn {\r\n deleteServer: (serverName: string, scope: 'project' | 'global') => Promise<void>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useDeleteMcpServer(): UseDeleteMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ serverName, scope }: { serverName: string; scope: 'project' | 'global' }) =>\r\n deleteMcpServer(serverName, scope, { projectPath: projectPath ?? undefined }),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n },\r\n });\r\n\r\n return {\r\n deleteServer: (serverName, scope) => mutation.mutateAsync({ serverName, scope }),\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseToggleMcpServerReturn {\r\n toggleServer: (serverName: string, enabled: boolean) => Promise<McpServer>;\r\n isToggling: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useToggleMcpServer(): UseToggleMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ serverName, enabled }: { serverName: string; enabled: boolean }) =>\r\n toggleMcpServer(serverName, enabled, { projectPath: projectPath ?? undefined }),\r\n onMutate: async ({ serverName, enabled }) => {\r\n await queryClient.cancelQueries({ queryKey: mcpServersKeys.all });\r\n const previousServers = queryClient.getQueryData<McpServersResponse>(mcpServersKeys.list());\r\n\r\n // Optimistic update\r\n queryClient.setQueryData<McpServersResponse>(mcpServersKeys.list(), (old) => {\r\n if (!old) return old;\r\n const updateServer = (servers: McpServer[]) =>\r\n servers.map((s) => (s.name === serverName ? { ...s, enabled } : s));\r\n return {\r\n project: updateServer(old.project),\r\n global: updateServer(old.global),\r\n conflicts: old.conflicts ?? [],\r\n };\r\n });\r\n\r\n return { previousServers };\r\n },\r\n onError: (_error, _vars, context) => {\r\n if (context?.previousServers) {\r\n queryClient.setQueryData(mcpServersKeys.list(), context.previousServers);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n toggleServer: (serverName, enabled) => mutation.mutateAsync({ serverName, enabled }),\r\n isToggling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Combined hook for all MCP server mutations\r\n */\r\nexport function useMcpServerMutations() {\r\n const update = useUpdateMcpServer();\r\n const create = useCreateMcpServer();\r\n const remove = useDeleteMcpServer();\r\n const toggle = useToggleMcpServer();\r\n\r\n return {\r\n updateServer: update.updateServer,\r\n isUpdating: update.isUpdating,\r\n createServer: create.createServer,\r\n isCreating: create.isCreating,\r\n deleteServer: remove.deleteServer,\r\n isDeleting: remove.isDeleting,\r\n toggleServer: toggle.toggleServer,\r\n isToggling: toggle.isToggling,\r\n isMutating: update.isUpdating || create.isCreating || remove.isDeleting || toggle.isToggling,\r\n };\r\n}\r\n\r\n// ========================================\r\n// MCP Template Hooks\r\n// ========================================\r\n\r\n// Default stale time for templates: 5 minutes (templates change rarely)\r\nconst TEMPLATES_STALE_TIME = 5 * 60 * 1000;\r\n\r\nexport interface UseMcpTemplatesOptions {\r\n category?: string;\r\n staleTime?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseMcpTemplatesReturn {\r\n templates: McpTemplate[];\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n invalidate: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching MCP templates with optional category filter\r\n */\r\nexport function useMcpTemplates(options: UseMcpTemplatesOptions = {}): UseMcpTemplatesReturn {\r\n const { category, staleTime = TEMPLATES_STALE_TIME, enabled = true } = options;\r\n const queryClient = useQueryClient();\r\n\r\n const query = useQuery({\r\n queryKey: mcpTemplatesKeys.list(category),\r\n queryFn: () => fetchMcpTemplates(),\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const invalidate = async () => {\r\n await queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n };\r\n\r\n return {\r\n templates: category\r\n ? query.data?.filter((t) => t.category === category) ?? []\r\n : query.data ?? [],\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n invalidate,\r\n };\r\n}\r\n\r\nexport interface UseCreateTemplateReturn {\r\n createTemplate: (template: Omit<McpTemplate, 'id' | 'createdAt' | 'updatedAt'>) => Promise<{ success: boolean; id?: number; error?: string }>;\r\n isCreating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for creating or updating MCP templates\r\n */\r\nexport function useCreateTemplate(): UseCreateTemplateReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (template: Omit<McpTemplate, 'id' | 'createdAt' | 'updatedAt'>) =>\r\n saveMcpTemplate(template),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n createTemplate: mutation.mutateAsync,\r\n isCreating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteTemplateReturn {\r\n deleteTemplate: (templateName: string) => Promise<{ success: boolean; error?: string }>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for deleting MCP templates\r\n */\r\nexport function useDeleteTemplate(): UseDeleteTemplateReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (templateName: string) => deleteMcpTemplate(templateName),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n deleteTemplate: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseInstallTemplateReturn {\r\n installTemplate: (request: McpTemplateInstallRequest) => Promise<{ success: boolean; serverName?: string; error?: string }>;\r\n isInstalling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for installing MCP templates to project or global scope\r\n */\r\nexport function useInstallTemplate(): UseInstallTemplateReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (request: McpTemplateInstallRequest) => installMcpTemplate(request),\r\n onSettled: () => {\r\n // Invalidate both templates and servers since installation affects both\r\n queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n installTemplate: mutation.mutateAsync,\r\n isInstalling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n// ========================================\r\n// Codex MCP Hooks\r\n// ========================================\r\n\r\nexport interface UseCodexMutationsReturn {\r\n removeServer: (serverName: string) => Promise<{ success: boolean; error?: string }>;\r\n toggleServer: (serverName: string, enabled: boolean) => Promise<{ success: boolean; error?: string }>;\r\n isRemoving: boolean;\r\n isToggling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Combined hook for Codex MCP mutations (remove and toggle)\r\n */\r\nexport function useCodexMutations(): UseCodexMutationsReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const removeMutation = useMutation({\r\n mutationFn: (serverName: string) => codexRemoveServer(serverName),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n const toggleMutation = useMutation({\r\n mutationFn: ({ serverName, enabled }: { serverName: string; enabled: boolean }) =>\r\n codexToggleServer(serverName, enabled),\r\n onMutate: async ({ serverName, enabled }) => {\r\n // Optimistic update could be added here if needed\r\n return { serverName, enabled };\r\n },\r\n onError: (_error, _vars, _context) => {\r\n // Rollback on error\r\n console.error('Failed to toggle Codex MCP server:', _error);\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n removeServer: removeMutation.mutateAsync,\r\n isRemoving: removeMutation.isPending,\r\n toggleServer: (serverName, enabled) => toggleMutation.mutateAsync({ serverName, enabled }),\r\n isToggling: toggleMutation.isPending,\r\n error: removeMutation.error || toggleMutation.error,\r\n };\r\n}\r\n\r\n// ========================================\r\n// Project Operations Hooks\r\n// ========================================\r\n\r\nexport interface UseProjectOperationsReturn {\r\n projects: string[];\r\n currentProject?: string;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n copyToCodex: (request: CrossCliCopyRequest) => Promise<CrossCliCopyResponse>;\r\n copyFromCodex: (request: CrossCliCopyRequest) => Promise<CrossCliCopyResponse>;\r\n isCopying: boolean;\r\n fetchOtherServers: (projectPaths?: string[]) => Promise<OtherProjectsServersResponse>;\r\n isFetchingServers: boolean;\r\n}\r\n\r\nconst EMPTY_PROJECTS: string[] = [];\r\n\r\n/**\r\n * Combined hook for project operations (all projects, cross-CLI copy, other projects' servers)\r\n */\r\nexport function useProjectOperations(): UseProjectOperationsReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Fetch all projects\r\n const projectsQuery = useQuery({\r\n queryKey: projectsKeys.list(),\r\n queryFn: () => fetchAllProjects(),\r\n staleTime: STALE_TIME,\r\n enabled: true,\r\n retry: 2,\r\n });\r\n\r\n // Cross-CLI copy mutation\r\n const copyMutation = useMutation({\r\n mutationFn: (request: CrossCliCopyRequest) => crossCliCopy(request),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n // Other projects servers query\r\n const serversQuery = useQuery({\r\n queryKey: projectsKeys.servers(),\r\n queryFn: () => fetchOtherProjectsServers(),\r\n staleTime: STALE_TIME,\r\n enabled: false, // Manual trigger only\r\n retry: 1,\r\n });\r\n\r\n const refetch = async () => {\r\n await projectsQuery.refetch();\r\n };\r\n\r\n const fetchOtherServers = async (projectPaths?: string[]) => {\r\n return await queryClient.fetchQuery({\r\n queryKey: projectsKeys.servers(projectPaths),\r\n queryFn: () => fetchOtherProjectsServers(projectPaths),\r\n staleTime: STALE_TIME,\r\n });\r\n };\r\n\r\n return {\r\n projects: projectsQuery.data?.projects ?? EMPTY_PROJECTS,\r\n currentProject: projectsQuery.data?.currentProject ?? projectPath ?? undefined,\r\n isLoading: projectsQuery.isLoading,\r\n error: projectsQuery.error,\r\n refetch,\r\n copyToCodex: (request) => copyMutation.mutateAsync({\r\n ...request,\r\n source: 'claude',\r\n target: 'codex',\r\n projectPath: request.projectPath ?? projectPath ?? undefined,\r\n }),\r\n copyFromCodex: (request) => copyMutation.mutateAsync({\r\n ...request,\r\n source: 'codex',\r\n target: 'claude',\r\n projectPath: request.projectPath ?? projectPath ?? undefined,\r\n }),\r\n isCopying: copyMutation.isPending,\r\n fetchOtherServers,\r\n isFetchingServers: serversQuery.isFetching,\r\n };\r\n}\r\n","// ========================================\n// Config Type Toggle Component\n// ========================================\n// Toggle between .mcp.json and .claude.json config storage formats with localStorage persistence\n\nimport { useEffect, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@/components/ui/AlertDialog';\nimport { cn } from '@/lib/utils';\n\n// ========== Types ==========\n\n/**\n * MCP config file type\n */\nexport type McpConfigType = 'mcp-json' | 'claude-json';\n\n/**\n * Props for ConfigTypeToggle component\n */\nexport interface ConfigTypeToggleProps {\n /** Current config type */\n currentType: McpConfigType;\n /** Callback when config type changes */\n onTypeChange: (type: McpConfigType) => void;\n /** Whether to show warning when switching (default: true) */\n showWarning?: boolean;\n /** Number of existing servers in current config (for warning message) */\n existingServersCount?: number;\n}\n\n// ========== Constants ==========\n\n/**\n * localStorage key for config type persistence\n */\nconst CONFIG_TYPE_STORAGE_KEY = 'mcp-config-type';\n\n/**\n * Default config type\n */\nconst DEFAULT_CONFIG_TYPE: McpConfigType = 'mcp-json';\n\n// ========== Helper Functions ==========\n\n/**\n * Load config type from localStorage\n */\nexport function loadConfigType(): McpConfigType {\n try {\n const stored = localStorage.getItem(CONFIG_TYPE_STORAGE_KEY);\n if (stored === 'mcp-json' || stored === 'claude-json') {\n return stored;\n }\n } catch {\n // Ignore localStorage errors\n }\n return DEFAULT_CONFIG_TYPE;\n}\n\n/**\n * Save config type to localStorage\n */\nexport function saveConfigType(type: McpConfigType): void {\n try {\n localStorage.setItem(CONFIG_TYPE_STORAGE_KEY, type);\n } catch {\n // Ignore localStorage errors\n }\n}\n\n/**\n * Get file extension for config type\n */\nexport function getConfigFileExtension(type: McpConfigType): string {\n switch (type) {\n case 'mcp-json':\n return '.mcp.json';\n case 'claude-json':\n return '.claude.json';\n default:\n return '.json';\n }\n}\n\n// ========== Component ==========\n\n/**\n * Config type toggle segmented control\n */\nexport function ConfigTypeToggle({\n currentType,\n onTypeChange,\n showWarning = true,\n existingServersCount = 0,\n}: ConfigTypeToggleProps) {\n const { formatMessage } = useIntl();\n const [internalType, setInternalType] = useState<McpConfigType>(currentType);\n const [showWarningDialog, setShowWarningDialog] = useState(false);\n const [pendingType, setPendingType] = useState<McpConfigType | null>(null);\n\n // Sync internal state with prop changes\n useEffect(() => {\n setInternalType(currentType);\n }, [currentType]);\n\n // Load saved preference on mount (only if no current type is set)\n useEffect(() => {\n if (!currentType || currentType === DEFAULT_CONFIG_TYPE) {\n const savedType = loadConfigType();\n if (savedType !== currentType) {\n setInternalType(savedType);\n onTypeChange(savedType);\n }\n }\n }, []); // Run once on mount\n\n // Handle type toggle click\n const handleTypeClick = (type: McpConfigType) => {\n if (type === internalType) return;\n\n if (showWarning && existingServersCount > 0) {\n setPendingType(type);\n setShowWarningDialog(true);\n } else {\n applyTypeChange(type);\n }\n };\n\n // Apply the type change\n const applyTypeChange = (type: McpConfigType) => {\n setInternalType(type);\n saveConfigType(type);\n onTypeChange(type);\n setShowWarningDialog(false);\n setPendingType(null);\n };\n\n // Handle warning dialog confirm\n const handleWarningConfirm = () => {\n if (pendingType) {\n applyTypeChange(pendingType);\n }\n };\n\n // Handle warning dialog cancel\n const handleWarningCancel = () => {\n setShowWarningDialog(false);\n setPendingType(null);\n };\n\n return (\n <>\n {/* Compact inline toggle */}\n <div className=\"flex items-center gap-1.5 p-0.5 bg-muted rounded-md h-9\">\n <button\n type=\"button\"\n onClick={() => handleTypeClick('mcp-json')}\n className={cn(\n 'px-2.5 py-1 text-xs font-medium rounded transition-all',\n internalType === 'mcp-json'\n ? 'bg-primary text-primary-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n )}\n >\n .mcp.json\n </button>\n <button\n type=\"button\"\n onClick={() => handleTypeClick('claude-json')}\n className={cn(\n 'px-2.5 py-1 text-xs font-medium rounded transition-all',\n internalType === 'claude-json'\n ? 'bg-primary text-primary-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n )}\n >\n .claude.json\n </button>\n </div>\n\n {/* Warning Dialog */}\n <AlertDialog open={showWarningDialog} onOpenChange={setShowWarningDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {formatMessage({ id: 'mcp.configType.switchConfirm' })}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {formatMessage({ id: 'mcp.configType.switchWarning' })}\n {existingServersCount > 0 && (\n <span className=\"block mt-2 text-amber-600 dark:text-amber-400\">\n {existingServersCount} {formatMessage({ id: 'mcp.stats.total' }).toLowerCase()}\n </span>\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel onClick={handleWarningCancel}>\n {formatMessage({ id: 'mcp.configType.switchCancel' })}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleWarningConfirm}>\n {formatMessage({ id: 'mcp.configType.switchConfirm' })}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n\nexport default ConfigTypeToggle;\n","// ========================================\r\n// MCP Server Dialog Component\r\n// ========================================\r\n// Add/Edit dialog for MCP server configuration with dynamic template loading\r\n// Supports both STDIO and HTTP transport types\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { Eye, EyeOff, Plus, Trash2, Globe, Terminal } from 'lucide-react';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n createMcpServer,\r\n updateMcpServer,\r\n fetchMcpServers,\r\n saveMcpTemplate,\r\n type McpServer,\r\n type McpProjectConfigType,\r\n isStdioMcpServer,\r\n isHttpMcpServer,\r\n} from '@/lib/api';\r\nimport { mcpServersKeys, useMcpTemplates, useNotifications } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport { ConfigTypeToggle, type McpConfigType } from './ConfigTypeToggle';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// ========== Types ==========\r\n\r\nexport type McpTransportType = 'stdio' | 'http';\r\n\r\nexport interface HttpHeader {\r\n id: string;\r\n name: string;\r\n value: string;\r\n isEnvVar: boolean;\r\n}\r\n\r\nexport interface McpServerDialogProps {\r\n mode: 'add' | 'edit';\r\n server?: McpServer;\r\n open: boolean;\r\n onClose: () => void;\r\n onSave?: () => void;\r\n}\r\n\r\n// Re-export McpTemplate for convenience\r\nexport type { McpTemplate } from '@/types/store';\r\n\r\ninterface McpServerFormData {\r\n name: string;\r\n // STDIO fields\r\n command: string;\r\n args: string[];\r\n env: Record<string, string>;\r\n // HTTP fields\r\n url: string;\r\n headers: HttpHeader[];\r\n bearerTokenEnvVar: string;\r\n // Common fields\r\n scope: 'project' | 'global';\r\n enabled: boolean;\r\n}\r\n\r\ninterface FormErrors {\r\n name?: string;\r\n command?: string;\r\n args?: string;\r\n env?: string;\r\n url?: string;\r\n headers?: string;\r\n}\r\n\r\n// ========== Helper Component: HttpHeadersInput ==========\r\n\r\ninterface HttpHeadersInputProps {\r\n headers: HttpHeader[];\r\n onChange: (headers: HttpHeader[]) => void;\r\n disabled?: boolean;\r\n}\r\n\r\nfunction HttpHeadersInput({ headers, onChange, disabled }: HttpHeadersInputProps) {\r\n const { formatMessage } = useIntl();\r\n const [revealedIds, setRevealedIds] = useState<Set<string>>(new Set());\r\n\r\n const generateId = () => `header-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n\r\n const handleAdd = () => {\r\n onChange([...headers, { id: generateId(), name: '', value: '', isEnvVar: false }]);\r\n };\r\n\r\n const handleRemove = (id: string) => {\r\n onChange(headers.filter((h) => h.id !== id));\r\n };\r\n\r\n const handleUpdate = (id: string, field: keyof HttpHeader, value: string | boolean) => {\r\n onChange(headers.map((h) => (h.id === id ? { ...h, [field]: value } : h)));\r\n };\r\n\r\n const toggleReveal = (id: string) => {\r\n setRevealedIds((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(id)) {\r\n next.delete(id);\r\n } else {\r\n next.add(id);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"space-y-2\">\r\n {headers.map((header) => (\r\n <div key={header.id} className=\"flex items-center gap-2\">\r\n {/* Header Name */}\r\n <Input\r\n value={header.name}\r\n onChange={(e) => handleUpdate(header.id, 'name', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.headerName' })}\r\n className=\"flex-1\"\r\n disabled={disabled}\r\n />\r\n {/* Header Value */}\r\n <div className=\"relative flex-1\">\r\n <Input\r\n type={revealedIds.has(header.id) ? 'text' : 'password'}\r\n value={header.value}\r\n onChange={(e) => handleUpdate(header.id, 'value', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.headerValue' })}\r\n className=\"pr-8\"\r\n disabled={disabled}\r\n />\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"absolute right-0 top-0 h-full px-2\"\r\n onClick={() => toggleReveal(header.id)}\r\n disabled={disabled}\r\n >\r\n {revealedIds.has(header.id) ? (\r\n <EyeOff className=\"w-4 h-4\" />\r\n ) : (\r\n <Eye className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n {/* Env Var Toggle */}\r\n <label className=\"flex items-center gap-1 text-xs text-muted-foreground whitespace-nowrap\">\r\n <input\r\n type=\"checkbox\"\r\n checked={header.isEnvVar}\r\n onChange={(e) => handleUpdate(header.id, 'isEnvVar', e.target.checked)}\r\n className=\"w-3 h-3\"\r\n disabled={disabled}\r\n />\r\n {formatMessage({ id: 'mcp.dialog.form.http.isEnvVar' })}\r\n </label>\r\n {/* Delete Button */}\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n onClick={() => handleRemove(header.id)}\r\n disabled={disabled}\r\n className=\"text-destructive\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n ))}\r\n <Button\r\n type=\"button\"\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleAdd}\r\n disabled={disabled}\r\n className=\"w-full\"\r\n >\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.dialog.form.http.addHeader' })}\r\n </Button>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function McpServerDialog({\r\n mode,\r\n server,\r\n open,\r\n onClose,\r\n onSave,\r\n}: McpServerDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const { error: showError, success: showSuccess } = useNotifications();\r\n\r\n // Fetch templates from backend\r\n const { templates, isLoading: templatesLoading } = useMcpTemplates();\r\n\r\n // Transport type state\r\n const [transportType, setTransportType] = useState<McpTransportType>('stdio');\r\n\r\n // Form state\r\n const [formData, setFormData] = useState<McpServerFormData>({\r\n name: '',\r\n command: '',\r\n args: [],\r\n env: {},\r\n url: '',\r\n headers: [],\r\n bearerTokenEnvVar: '',\r\n scope: 'project',\r\n enabled: true,\r\n });\r\n\r\n const [selectedTemplate, setSelectedTemplate] = useState<string>('');\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n const [argsInput, setArgsInput] = useState('');\r\n const [envInput, setEnvInput] = useState('');\r\n const [configType, setConfigType] = useState<McpConfigType>('mcp-json');\r\n const [saveAsTemplate, setSaveAsTemplate] = useState(false);\r\n const projectConfigType: McpProjectConfigType = configType === 'claude-json' ? 'claude' : 'mcp';\r\n\r\n // JSON import mode state\r\n const [inputMode, setInputMode] = useState<'form' | 'json'>('form');\r\n const [jsonInput, setJsonInput] = useState('');\r\n\r\n // Helper to detect transport type from server data\r\n const detectTransportType = useCallback((serverData: McpServer | undefined): McpTransportType => {\r\n if (!serverData) return 'stdio';\r\n // Use type guard to check for HTTP server\r\n if (isHttpMcpServer(serverData)) return 'http';\r\n return 'stdio';\r\n }, []);\r\n\r\n // Parse JSON config and populate form\r\n const parseJsonConfig = useCallback(() => {\r\n try {\r\n let config = JSON.parse(jsonInput);\r\n let extractedServerName = '';\r\n\r\n // Auto-detect mcpServers wrapper format (Claude Code config format)\r\n // Supports both: { \"mcpServers\": { \"name\": {...} } } and direct { \"command\": ... }\r\n if (config.mcpServers && typeof config.mcpServers === 'object' && !Array.isArray(config.mcpServers)) {\r\n const serverNames = Object.keys(config.mcpServers);\r\n if (serverNames.length > 0) {\r\n extractedServerName = serverNames[0];\r\n const serverConfig = config.mcpServers[extractedServerName];\r\n if (serverConfig && typeof serverConfig === 'object') {\r\n config = serverConfig;\r\n }\r\n }\r\n }\r\n\r\n // Detect transport type based on config structure\r\n if (config.url) {\r\n // HTTP transport\r\n setTransportType('http');\r\n \r\n // Parse headers\r\n const headers: HttpHeader[] = [];\r\n if (config.headers && typeof config.headers === 'object') {\r\n Object.entries(config.headers).forEach(([name, value], idx) => {\r\n headers.push({\r\n id: `header-${Date.now()}-${idx}`,\r\n name,\r\n value: String(value),\r\n isEnvVar: false,\r\n });\r\n });\r\n }\r\n \r\n setFormData(prev => ({\r\n ...prev,\r\n name: extractedServerName || prev.name,\r\n url: config.url || '',\r\n headers,\r\n bearerTokenEnvVar: config.bearer_token_env_var || config.bearerTokenEnvVar || '',\r\n }));\r\n } else {\r\n // STDIO transport\r\n setTransportType('stdio');\r\n \r\n const args = Array.isArray(config.args) ? config.args : [];\r\n const env = config.env && typeof config.env === 'object' ? config.env : {};\r\n \r\n setFormData(prev => ({\r\n ...prev,\r\n name: extractedServerName || prev.name,\r\n command: config.command || '',\r\n args,\r\n env,\r\n }));\r\n \r\n setArgsInput(args.join(', '));\r\n setEnvInput(\r\n Object.entries(env)\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('\\n')\r\n );\r\n }\r\n \r\n // Switch to form mode to show parsed data\r\n setInputMode('form');\r\n setErrors({});\r\n showSuccess(\r\n formatMessage({ id: 'mcp.dialog.json.parseSuccess' }),\r\n formatMessage({ id: 'mcp.dialog.json.parseSuccessDesc' })\r\n );\r\n } catch (error) {\r\n setErrors({ \r\n name: formatMessage({ id: 'mcp.dialog.json.parseError' }, { \r\n error: error instanceof Error ? error.message : 'Invalid JSON' \r\n })\r\n });\r\n }\r\n }, [jsonInput, formatMessage, showSuccess]);\r\n\r\n // Initialize form from server prop (edit mode)\r\n useEffect(() => {\r\n if (server && mode === 'edit') {\r\n const detectedType = detectTransportType(server);\r\n setTransportType(detectedType);\r\n\r\n // Parse HTTP headers if present (for HTTP servers)\r\n const httpHeaders: HttpHeader[] = [];\r\n if (isHttpMcpServer(server)) {\r\n // HTTP server - extract headers\r\n if (server.httpHeaders) {\r\n Object.entries(server.httpHeaders).forEach(([name, value], idx) => {\r\n httpHeaders.push({\r\n id: `header-http-${idx}`,\r\n name,\r\n value,\r\n isEnvVar: false,\r\n });\r\n });\r\n }\r\n if (server.envHttpHeaders) {\r\n // envHttpHeaders is an array of header names that get values from env vars\r\n server.envHttpHeaders.forEach((headerName, idx) => {\r\n httpHeaders.push({\r\n id: `header-env-${idx}`,\r\n name: headerName,\r\n value: '', // Env var name is not stored in value\r\n isEnvVar: true,\r\n });\r\n });\r\n }\r\n }\r\n\r\n // Get STDIO fields safely using type guard\r\n const stdioCommand = isStdioMcpServer(server) ? server.command : '';\r\n const stdioArgs = isStdioMcpServer(server) ? (server.args || []) : [];\r\n const stdioEnv = isStdioMcpServer(server) ? (server.env || {}) : {};\r\n\r\n // Get HTTP fields safely using type guard\r\n const httpUrl = isHttpMcpServer(server) ? server.url : '';\r\n const httpBearerToken = isHttpMcpServer(server) ? (server.bearerTokenEnvVar || '') : '';\r\n\r\n setFormData({\r\n name: server.name,\r\n command: stdioCommand,\r\n args: stdioArgs,\r\n env: stdioEnv,\r\n url: httpUrl,\r\n headers: httpHeaders,\r\n bearerTokenEnvVar: httpBearerToken,\r\n scope: server.scope,\r\n enabled: server.enabled,\r\n });\r\n setArgsInput(stdioArgs.join(', '));\r\n setEnvInput(\r\n Object.entries(stdioEnv)\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('\\n')\r\n );\r\n } else {\r\n // Reset form for add mode\r\n setTransportType('stdio');\r\n setFormData({\r\n name: '',\r\n command: '',\r\n args: [],\r\n env: {},\r\n url: '',\r\n headers: [],\r\n bearerTokenEnvVar: '',\r\n scope: 'project',\r\n enabled: true,\r\n });\r\n setArgsInput('');\r\n setEnvInput('');\r\n }\r\n setSelectedTemplate('');\r\n setSaveAsTemplate(false);\r\n setErrors({});\r\n }, [server, mode, open, detectTransportType]);\r\n\r\n // Mutations\r\n const createMutation = useMutation({\r\n mutationFn: ({ server, configType }: { server: McpServer; configType?: McpProjectConfigType }) =>\r\n createMcpServer(server, { projectPath: projectPath ?? undefined, configType }),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n const updateMutation = useMutation({\r\n mutationFn: ({ serverName, config, configType }: { serverName: string; config: Partial<McpServer>; configType?: McpProjectConfigType }) =>\r\n updateMcpServer(serverName, config, { projectPath: projectPath ?? undefined, configType }),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n // Handlers\r\n const handleClose = () => {\r\n setErrors({});\r\n onClose();\r\n };\r\n\r\n const handleTemplateSelect = (templateId: string) => {\r\n const template = templates.find((t) => t.name === templateId);\r\n if (template) {\r\n setFormData((prev) => ({\r\n ...prev,\r\n command: template.serverConfig.command,\r\n args: template.serverConfig.args || [],\r\n env: template.serverConfig.env || {},\r\n }));\r\n setArgsInput((template.serverConfig.args || []).join(', '));\r\n setEnvInput(\r\n Object.entries(template.serverConfig.env || {})\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('\\n')\r\n );\r\n setSelectedTemplate(templateId);\r\n }\r\n };\r\n\r\n const handleFieldChange = (\r\n field: keyof McpServerFormData,\r\n value: string | boolean | string[] | Record<string, string> | HttpHeader[]\r\n ) => {\r\n setFormData((prev) => ({ ...prev, [field]: value }));\r\n // Clear error for this field\r\n if (errors[field as keyof FormErrors]) {\r\n setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n }\r\n };\r\n\r\n const handleArgsChange = (value: string) => {\r\n setArgsInput(value);\r\n const argsArray = value\r\n .split(',')\r\n .map((a) => a.trim())\r\n .filter((a) => a.length > 0);\r\n setFormData((prev) => ({ ...prev, args: argsArray }));\r\n if (errors.args) {\r\n setErrors((prev) => ({ ...prev, args: undefined }));\r\n }\r\n };\r\n\r\n const handleEnvChange = (value: string) => {\r\n setEnvInput(value);\r\n const envObj: Record<string, string> = {};\r\n const lines = value.split('\\n');\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (trimmed && trimmed.includes('=')) {\r\n const [key, ...valParts] = trimmed.split('=');\r\n const val = valParts.join('=');\r\n if (key) {\r\n envObj[key.trim()] = val.trim();\r\n }\r\n }\r\n }\r\n setFormData((prev) => ({ ...prev, env: envObj }));\r\n if (errors.env) {\r\n setErrors((prev) => ({ ...prev, env: undefined }));\r\n }\r\n };\r\n\r\n const handleHeadersChange = (headers: HttpHeader[]) => {\r\n setFormData((prev) => ({ ...prev, headers }));\r\n if (errors.headers) {\r\n setErrors((prev) => ({ ...prev, headers: undefined }));\r\n }\r\n };\r\n\r\n const handleTransportTypeChange = (type: McpTransportType) => {\r\n setTransportType(type);\r\n // Clear relevant errors when switching\r\n setErrors((prev) => ({\r\n ...prev,\r\n command: undefined,\r\n url: undefined,\r\n }));\r\n };\r\n\r\n const validateForm = (): boolean => {\r\n const newErrors: FormErrors = {};\r\n\r\n // Name required\r\n if (!formData.name.trim()) {\r\n newErrors.name = formatMessage({ id: 'mcp.dialog.validation.nameRequired' });\r\n }\r\n\r\n // Transport-specific validation\r\n if (transportType === 'stdio') {\r\n // Command required for STDIO\r\n if (!formData.command.trim()) {\r\n newErrors.command = formatMessage({ id: 'mcp.dialog.validation.commandRequired' });\r\n }\r\n } else {\r\n // URL required for HTTP\r\n if (!formData.url.trim()) {\r\n newErrors.url = formatMessage({ id: 'mcp.dialog.validation.urlRequired' });\r\n }\r\n // Validate URL format\r\n try {\r\n new URL(formData.url);\r\n } catch {\r\n newErrors.url = formatMessage({ id: 'mcp.dialog.validation.urlInvalid' });\r\n }\r\n }\r\n\r\n setErrors(newErrors);\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const checkNameExists = async (name: string): Promise<boolean> => {\r\n try {\r\n const data = await fetchMcpServers(projectPath ?? undefined);\r\n const allServers = [...data.project, ...data.global];\r\n // In edit mode, exclude current server\r\n return allServers.some(\r\n (s) => s.name === name && (mode === 'edit' ? s.name !== server?.name : true)\r\n );\r\n } catch {\r\n return false;\r\n }\r\n };\r\n\r\n const handleSubmit = async () => {\r\n if (!validateForm()) {\r\n return;\r\n }\r\n\r\n // Check name uniqueness\r\n if (await checkNameExists(formData.name)) {\r\n setErrors({ name: formatMessage({ id: 'mcp.dialog.validation.nameExists' }) });\r\n return;\r\n }\r\n\r\n // Build server config based on transport type using discriminated union\r\n let serverConfig: McpServer;\r\n\r\n if (transportType === 'stdio') {\r\n serverConfig = {\r\n name: formData.name,\r\n transport: 'stdio',\r\n command: formData.command,\r\n args: formData.args.length > 0 ? formData.args : undefined,\r\n env: Object.keys(formData.env).length > 0 ? formData.env : undefined,\r\n scope: formData.scope,\r\n enabled: formData.enabled,\r\n };\r\n } else {\r\n // HTTP transport - separate headers into static and env-based\r\n const httpHeaders: Record<string, string> = {};\r\n const envHttpHeaders: string[] = [];\r\n\r\n formData.headers.forEach((h) => {\r\n if (h.name.trim()) {\r\n if (h.isEnvVar) {\r\n // For env-based headers, store the header name that will be populated from env var\r\n envHttpHeaders.push(h.name.trim());\r\n } else {\r\n httpHeaders[h.name.trim()] = h.value.trim();\r\n }\r\n }\r\n });\r\n\r\n serverConfig = {\r\n name: formData.name,\r\n transport: 'http',\r\n url: formData.url,\r\n headers: Object.keys(httpHeaders).length > 0 ? httpHeaders : undefined,\r\n httpHeaders: Object.keys(httpHeaders).length > 0 ? httpHeaders : undefined,\r\n envHttpHeaders: envHttpHeaders.length > 0 ? envHttpHeaders : undefined,\r\n bearerTokenEnvVar: formData.bearerTokenEnvVar.trim() || undefined,\r\n scope: formData.scope,\r\n enabled: formData.enabled,\r\n };\r\n }\r\n\r\n // Save as template if checked (only for STDIO)\r\n if (saveAsTemplate && transportType === 'stdio') {\r\n try {\r\n await saveMcpTemplate({\r\n name: formData.name,\r\n category: 'custom',\r\n serverConfig: {\r\n command: formData.command,\r\n args: formData.args.length > 0 ? formData.args : undefined,\r\n env: Object.keys(formData.env).length > 0 ? formData.env : undefined,\r\n },\r\n });\r\n } catch (err) {\r\n showError(formatMessage({ id: 'mcp.templates.feedback.saveError' }), err instanceof Error ? err.message : String(err));\r\n // Template save failure should not block server creation\r\n }\r\n }\r\n\r\n if (mode === 'add') {\r\n createMutation.mutate({\r\n server: serverConfig,\r\n configType: formData.scope === 'project' ? projectConfigType : undefined,\r\n });\r\n } else {\r\n updateMutation.mutate({\r\n serverName: server!.name,\r\n config: serverConfig,\r\n configType: formData.scope === 'project' ? projectConfigType : undefined,\r\n });\r\n }\r\n };\r\n\r\n const isPending = createMutation.isPending || updateMutation.isPending;\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleClose}>\r\n <DialogContent className=\"max-w-2xl max-h-[90vh] overflow-y-auto\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {mode === 'add'\r\n ? formatMessage({ id: 'mcp.dialog.addTitle' })\r\n : formatMessage({ id: 'mcp.dialog.editTitle' }, { name: server?.name })}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n {/* Input Mode Switcher - Only in add mode */}\r\n {mode === 'add' && (\r\n <div className=\"flex gap-2 border-b pb-3\">\r\n <Button\r\n type=\"button\"\r\n variant={inputMode === 'form' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setInputMode('form')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.dialog.mode.form' })}\r\n </Button>\r\n <Button\r\n type=\"button\"\r\n variant={inputMode === 'json' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setInputMode('json')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.dialog.mode.json' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n <div className=\"space-y-4\">\r\n {/* JSON Input Mode */}\r\n {inputMode === 'json' ? (\r\n <div className=\"space-y-4\">\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.json.label' })}\r\n </label>\r\n <textarea\r\n value={jsonInput}\r\n onChange={(e) => setJsonInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.json.placeholder' })}\r\n className={cn(\r\n 'flex min-h-[300px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 font-mono',\r\n errors.name && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.json.hint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Example JSON */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.json.example' })}\r\n </label>\r\n <div className=\"bg-muted p-3 rounded-md\">\r\n <p className=\"text-xs font-medium mb-2\">STDIO:</p>\r\n <pre className=\"text-xs overflow-x-auto\">\r\n{`{\r\n \"command\": \"npx\",\r\n \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/path\"],\r\n \"env\": {\r\n \"API_KEY\": \"your-key\"\r\n }\r\n}`}\r\n </pre>\r\n <p className=\"text-xs font-medium mt-3 mb-2\">HTTP:</p>\r\n <pre className=\"text-xs overflow-x-auto\">\r\n{`{\r\n \"url\": \"http://localhost:3000\",\r\n \"headers\": {\r\n \"Authorization\": \"Bearer token\"\r\n }\r\n}`}\r\n </pre>\r\n </div>\r\n </div>\r\n\r\n <Button\r\n type=\"button\"\r\n onClick={parseJsonConfig}\r\n disabled={!jsonInput.trim()}\r\n className=\"w-full\"\r\n >\r\n {formatMessage({ id: 'mcp.dialog.json.parse' })}\r\n </Button>\r\n </div>\r\n ) : (\r\n <>\r\n {/* Template Selector - Only for STDIO */}\r\n {transportType === 'stdio' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.template' })}\r\n </label>\r\n <Select value={selectedTemplate} onValueChange={handleTemplateSelect} disabled={templatesLoading}>\r\n <SelectTrigger className=\"w-full\">\r\n <SelectValue\r\n placeholder={templatesLoading\r\n ? formatMessage({ id: 'mcp.templates.loading' })\r\n : formatMessage({ id: 'mcp.dialog.form.templatePlaceholder' })\r\n }\r\n />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {templates.length === 0 ? (\r\n <SelectItem value=\"__empty__\" disabled>\r\n {formatMessage({ id: 'mcp.templates.empty.title' })}\r\n </SelectItem>\r\n ) : (\r\n templates.map((template) => (\r\n <SelectItem key={template.name} value={template.name}>\r\n <div className=\"flex flex-col\">\r\n <span className=\"font-medium\">{template.name}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {template.description || formatMessage({ id: 'mcp.dialog.form.templatePlaceholder' })}\r\n </span>\r\n </div>\r\n </SelectItem>\r\n ))\r\n )}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n )}\r\n\r\n {/* Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.name' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.name}\r\n onChange={(e) => handleFieldChange('name', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.namePlaceholder' })}\r\n error={!!errors.name}\r\n disabled={mode === 'edit'} // Name cannot be changed in edit mode\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n </div>\r\n\r\n {/* Transport Type Selector */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportType' })}\r\n </label>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"transportType\"\r\n value=\"stdio\"\r\n checked={transportType === 'stdio'}\r\n onChange={() => handleTransportTypeChange('stdio')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <Terminal className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportStdio' })}\r\n </span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"transportType\"\r\n value=\"http\"\r\n checked={transportType === 'http'}\r\n onChange={() => handleTransportTypeChange('http')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <Globe className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportHttp' })}\r\n </span>\r\n </label>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* STDIO Fields */}\r\n {transportType === 'stdio' && (\r\n <>\r\n {/* Command */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.command' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.command}\r\n onChange={(e) => handleFieldChange('command', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.commandPlaceholder' })}\r\n error={!!errors.command}\r\n />\r\n {errors.command && (\r\n <p className=\"text-sm text-destructive\">{errors.command}</p>\r\n )}\r\n </div>\r\n\r\n {/* Args */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.args' })}\r\n </label>\r\n <Input\r\n value={argsInput}\r\n onChange={(e) => handleArgsChange(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.argsPlaceholder' })}\r\n error={!!errors.args}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.argsHint' })}\r\n </p>\r\n {formData.args.length > 0 && (\r\n <div className=\"flex flex-wrap gap-1 mt-2\">\r\n {formData.args.map((arg, idx) => (\r\n <Badge key={idx} variant=\"secondary\" className=\"font-mono text-xs\">\r\n {arg}\r\n </Badge>\r\n ))}\r\n </div>\r\n )}\r\n {errors.args && (\r\n <p className=\"text-sm text-destructive\">{errors.args}</p>\r\n )}\r\n </div>\r\n\r\n {/* Environment Variables */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.env' })}\r\n </label>\r\n <textarea\r\n value={envInput}\r\n onChange={(e) => handleEnvChange(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.envPlaceholder' })}\r\n className={cn(\r\n 'flex min-h-[100px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\r\n errors.env && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.envHint' })}\r\n </p>\r\n {Object.keys(formData.env).length > 0 && (\r\n <div className=\"space-y-1 mt-2\">\r\n {Object.entries(formData.env).map(([key, value]) => (\r\n <div key={key} className=\"flex items-center gap-2 text-sm\">\r\n <Badge variant=\"outline\" className=\"font-mono\">\r\n {key}\r\n </Badge>\r\n <span className=\"text-muted-foreground\">=</span>\r\n <code className=\"text-xs bg-muted px-2 py-1 rounded flex-1 overflow-x-auto\">\r\n {value}\r\n </code>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n {errors.env && (\r\n <p className=\"text-sm text-destructive\">{errors.env}</p>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* HTTP Fields */}\r\n {transportType === 'http' && (\r\n <>\r\n {/* URL */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.url' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.url}\r\n onChange={(e) => handleFieldChange('url', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.urlPlaceholder' })}\r\n error={!!errors.url}\r\n />\r\n {errors.url && (\r\n <p className=\"text-sm text-destructive\">{errors.url}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.urlHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Bearer Token Env Var */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.bearerToken' })}\r\n </label>\r\n <Input\r\n value={formData.bearerTokenEnvVar}\r\n onChange={(e) => handleFieldChange('bearerTokenEnvVar', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.bearerTokenPlaceholder' })}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.bearerTokenHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* HTTP Headers */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.headers' })}\r\n </label>\r\n <HttpHeadersInput\r\n headers={formData.headers}\r\n onChange={handleHeadersChange}\r\n disabled={isPending}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.headersHint' })}\r\n </p>\r\n {errors.headers && (\r\n <p className=\"text-sm text-destructive\">{errors.headers}</p>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* Scope */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.scope' })}\r\n </label>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"scope\"\r\n value=\"project\"\r\n checked={formData.scope === 'project'}\r\n onChange={(e) => handleFieldChange('scope', e.target.value as 'project' | 'global')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.scope.project' })}\r\n </span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"scope\"\r\n value=\"global\"\r\n checked={formData.scope === 'global'}\r\n onChange={(e) => handleFieldChange('scope', e.target.value as 'project' | 'global')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.scope.global' })}\r\n </span>\r\n </label>\r\n </div>\r\n\r\n {/* Config Type Toggle - Only for project scope */}\r\n {formData.scope === 'project' && (\r\n <div className=\"flex items-center gap-2 mt-2 pl-6\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.configType.format' })}:\r\n </span>\r\n <ConfigTypeToggle\r\n currentType={configType}\r\n onTypeChange={setConfigType}\r\n showWarning={false}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Enabled */}\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"enabled\"\r\n checked={formData.enabled}\r\n onChange={(e) => handleFieldChange('enabled', e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <label htmlFor=\"enabled\" className=\"text-sm font-medium text-foreground cursor-pointer\">\r\n {formatMessage({ id: 'mcp.dialog.form.enabled' })}\r\n </label>\r\n </div>\r\n\r\n {/* Save as Template - Only for STDIO */}\r\n {transportType === 'stdio' && (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"save-as-template\"\r\n checked={saveAsTemplate}\r\n onChange={(e) => setSaveAsTemplate(e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <label htmlFor=\"save-as-template\" className=\"text-sm font-medium text-foreground cursor-pointer\">\r\n {formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}\r\n </label>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleClose}\r\n disabled={isPending}\r\n >\r\n {formatMessage({ id: 'mcp.dialog.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n disabled={isPending}\r\n >\r\n {isPending\r\n ? formatMessage({ id: 'mcp.dialog.actions.saving' })\r\n : formatMessage({ id: 'mcp.dialog.actions.save' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default McpServerDialog;\r\n","// ========================================\r\n// Codex MCP Editable Card Component\r\n// ========================================\r\n// Editable Codex MCP server card with remove and toggle actions\r\n// Extends CodexMcpCard with additional action buttons when editing is enabled\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Server,\r\n Power,\r\n PowerOff,\r\n ChevronDown,\r\n ChevronUp,\r\n Edit3,\r\n Trash2,\r\n Lock,\r\n Link,\r\n Eye,\r\n EyeOff,\r\n} from 'lucide-react';\r\nimport {\r\n AlertDialog,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n AlertDialogContent,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogTrigger,\r\n} from '@/components/ui/AlertDialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { McpServer } from '@/lib/api';\r\nimport { isHttpMcpServer, isStdioMcpServer } from '@/lib/api';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface CodexMcpEditableCardProps {\r\n server: McpServer;\r\n enabled: boolean;\r\n isExpanded: boolean;\r\n onToggleExpand: () => void;\r\n /** When enabled, shows remove/toggle buttons instead of read-only badge */\r\n isEditable?: boolean;\r\n /** Callback when server is removed (after confirmation) */\r\n onRemove?: (serverName: string) => void | Promise<void>;\r\n /** Callback when server is toggled */\r\n onToggle?: (serverName: string, enabled: boolean) => void | Promise<void>;\r\n /** Whether remove operation is in progress */\r\n isRemoving?: boolean;\r\n /** Whether toggle operation is in progress */\r\n isToggling?: boolean;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\n/**\r\n * Mask a header value for display (show first 4 chars + ***)\r\n */\r\nfunction maskHeaderValue(value: string): string {\r\n if (!value || value.length <= 4) return '****';\r\n return value.substring(0, 4) + '****';\r\n}\r\n\r\nexport function CodexMcpEditableCard({\r\n server,\r\n enabled,\r\n isExpanded,\r\n onToggleExpand,\r\n isEditable = false,\r\n onRemove,\r\n onToggle,\r\n isRemoving = false,\r\n isToggling = false,\r\n}: CodexMcpEditableCardProps) {\r\n const { formatMessage } = useIntl();\r\n const [isConfirmDeleteOpen, setIsConfirmDeleteOpen] = useState(false);\r\n const [showHeaderValues, setShowHeaderValues] = useState<Record<string, boolean>>({});\r\n\r\n const isHttp = isHttpMcpServer(server);\r\n const isStdio = isStdioMcpServer(server);\r\n\r\n // Get display text for server summary line\r\n const getServerSummary = () => {\r\n if (isHttp) {\r\n return server.url;\r\n }\r\n return `${server.command || ''} ${server.args?.join(' ') || ''}`.trim();\r\n };\r\n\r\n // Get all headers for HTTP server (Codex format: http_headers, env_http_headers, bearerTokenEnvVar)\r\n const getHttpHeaders = (): Array<{ name: string; value: string; isEnvVar?: boolean }> => {\r\n if (!isHttp) return [];\r\n\r\n const headers: Array<{ name: string; value: string; isEnvVar?: boolean }> = [];\r\n\r\n // Codex format: httpHeaders object\r\n if (server.httpHeaders) {\r\n Object.entries(server.httpHeaders).forEach(([name, value]) => {\r\n headers.push({ name, value });\r\n });\r\n }\r\n\r\n // Codex format: bearerTokenEnvVar (adds Authorization header)\r\n if (server.bearerTokenEnvVar) {\r\n headers.push({\r\n name: 'Authorization',\r\n value: `Bearer $${server.bearerTokenEnvVar}`,\r\n isEnvVar: true,\r\n });\r\n }\r\n\r\n // Claude format: headers object (for compatibility)\r\n if (server.headers) {\r\n Object.entries(server.headers).forEach(([name, value]) => {\r\n headers.push({ name, value });\r\n });\r\n }\r\n\r\n return headers;\r\n };\r\n\r\n // Toggle header value visibility\r\n const toggleHeaderValue = (headerName: string) => {\r\n setShowHeaderValues(prev => ({\r\n ...prev,\r\n [headerName]: !prev[headerName]\r\n }));\r\n };\r\n\r\n // Handle toggle with optimistic update\r\n const handleToggle = async () => {\r\n if (onToggle) {\r\n await onToggle(server.name, !enabled);\r\n }\r\n };\r\n\r\n // Handle remove with confirmation\r\n const handleRemove = async () => {\r\n if (onRemove) {\r\n await onRemove(server.name);\r\n setIsConfirmDeleteOpen(false);\r\n }\r\n };\r\n\r\n // Prevent click propagation when clicking action buttons\r\n const stopPropagation = (e: React.MouseEvent) => {\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <Card className={cn('overflow-hidden', !enabled && 'opacity-60')}>\r\n {/* Header */}\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={onToggleExpand}\r\n >\r\n <div className=\"flex items-start justify-between gap-2\">\r\n <div className=\"flex items-start gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n enabled ? 'bg-primary/10' : 'bg-muted'\r\n )}>\r\n <Server className={cn(\r\n 'w-5 h-5',\r\n enabled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {server.name}\r\n </span>\r\n {/* Transport type badge */}\r\n {isHttp && (\r\n <Badge variant=\"outline\" className=\"text-xs text-blue-600 border-blue-300\">\r\n <Link className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.transport.http' })}\r\n </Badge>\r\n )}\r\n {isEditable ? (\r\n <>\r\n {/* Editable badge with actions */}\r\n <Badge variant=\"secondary\" className=\"text-xs flex items-center gap-1\">\r\n <Edit3 className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.codex.editable' })}\r\n </Badge>\r\n {enabled && (\r\n <Badge variant=\"outline\" className=\"text-xs text-green-600\">\r\n <Power className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n {/* Read-only badge */}\r\n <Badge variant=\"secondary\" className=\"text-xs flex items-center gap-1\">\r\n <Lock className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.codex.readOnly' })}\r\n </Badge>\r\n {enabled && (\r\n <Badge variant=\"outline\" className=\"text-xs text-green-600\">\r\n <Power className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1 font-mono truncate max-w-md\" title={getServerSummary()}>\r\n {getServerSummary()}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n {isEditable ? (\r\n <>\r\n {/* Toggle button (active in editable mode) */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={(e) => {\r\n stopPropagation(e);\r\n handleToggle();\r\n }}\r\n disabled={isToggling}\r\n >\r\n {enabled ? (\r\n <Power className=\"w-4 h-4 text-green-600\" />\r\n ) : (\r\n <PowerOff className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </Button>\r\n\r\n {/* Remove button with confirmation */}\r\n <AlertDialog open={isConfirmDeleteOpen} onOpenChange={setIsConfirmDeleteOpen}>\r\n <AlertDialogTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={stopPropagation}\r\n disabled={isRemoving}\r\n >\r\n <Trash2 className=\"w-4 h-4 text-destructive\" />\r\n </Button>\r\n </AlertDialogTrigger>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.title' }, { name: server.name })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.description' }, { name: server.name })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel disabled={isRemoving}>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n onClick={handleRemove}\r\n disabled={isRemoving}\r\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n >\r\n {isRemoving ? (\r\n <>\r\n <span className=\"animate-spin mr-2\">◌</span>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.deleting' })}\r\n </>\r\n ) : (\r\n formatMessage({ id: 'mcp.codex.deleteConfirm.confirm' })\r\n )}\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </>\r\n ) : (\r\n <>\r\n {/* Disabled toggle button (visual only, no edit capability) */}\r\n <div className={cn(\r\n 'w-8 h-8 rounded-md flex items-center justify-center',\r\n enabled ? 'bg-green-100 text-green-600' : 'bg-muted text-muted-foreground'\r\n )}>\r\n {enabled ? <Power className=\"w-4 h-4\" /> : <PowerOff className=\"w-4 h-4\" />}\r\n </div>\r\n </>\r\n )}\r\n {isExpanded ? (\r\n <ChevronUp className=\"w-5 h-5 text-muted-foreground\" />\r\n ) : (\r\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border p-4 space-y-3 bg-muted/30\">\r\n {/* HTTP Server Details */}\r\n {isHttp && (\r\n <>\r\n {/* URL */}\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.url' })}</p>\r\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto break-all\">\r\n {server.url}\r\n </code>\r\n </div>\r\n\r\n {/* HTTP Headers */}\r\n {getHttpHeaders().length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.headers' })}</p>\r\n <div className=\"space-y-1\">\r\n {getHttpHeaders().map((header) => (\r\n <div key={header.name} className=\"flex items-center gap-2 text-sm\">\r\n <Badge variant=\"secondary\" className=\"font-mono\">{header.name}</Badge>\r\n <span className=\"text-muted-foreground\">=</span>\r\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\r\n {showHeaderValues[header.name] ? header.value : maskHeaderValue(header.value)}\r\n </code>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-6 w-6 p-0\"\r\n onClick={() => toggleHeaderValue(header.name)}\r\n title={showHeaderValues[header.name]\r\n ? formatMessage({ id: 'mcp.http.hideValue' })\r\n : formatMessage({ id: 'mcp.http.showValue' })}\r\n >\r\n {showHeaderValues[header.name] ? (\r\n <EyeOff className=\"w-3 h-3 text-muted-foreground\" />\r\n ) : (\r\n <Eye className=\"w-3 h-3 text-muted-foreground\" />\r\n )}\r\n </Button>\r\n {header.isEnvVar && (\r\n <Badge variant=\"outline\" className=\"text-xs text-blue-500\">\r\n {formatMessage({ id: 'mcp.http.envVar' })}\r\n </Badge>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* STDIO Server Details */}\r\n {isStdio && (\r\n <>\r\n {/* Command details */}\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.command' })}</p>\r\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto\">\r\n {server.command}\r\n </code>\r\n </div>\r\n\r\n {/* Args */}\r\n {server.args && server.args.length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.args' })}</p>\r\n <div className=\"flex flex-wrap gap-1\">\r\n {server.args.map((arg, idx) => (\r\n <Badge key={idx} variant=\"outline\" className=\"font-mono text-xs\">\r\n {arg}\r\n </Badge>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Environment variables */}\r\n {server.env && Object.keys(server.env).length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.env' })}</p>\r\n <div className=\"space-y-1\">\r\n {Object.entries(server.env).map(([key, value]) => (\r\n <div key={key} className=\"flex items-center gap-2 text-sm\">\r\n <Badge variant=\"secondary\" className=\"font-mono\">{key}</Badge>\r\n <span className=\"text-muted-foreground\">=</span>\r\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\r\n {value as string}\r\n </code>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* Notice based on editable state */}\r\n <div className={cn(\r\n 'flex items-center gap-2 px-3 py-2 rounded-md border',\r\n isEditable\r\n ? 'bg-info/10 border-info/20'\r\n : 'bg-muted/50 border-border'\r\n )}>\r\n {isEditable ? (\r\n <>\r\n <Edit3 className=\"w-4 h-4 text-info\" />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.codex.editableNotice' })}\r\n </p>\r\n </>\r\n ) : (\r\n <>\r\n <Lock className=\"w-4 h-4 text-muted-foreground\" />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.codex.readOnlyNotice' })}\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\nexport default CodexMcpEditableCard;\r\n","// ========================================\r\n// CCW Tools MCP Card Component\r\n// ========================================\r\n// Special card component for CCW Tools MCP server configuration\r\n// Displays tool checkboxes, path settings, and install/uninstall actions\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation } from '@tanstack/react-query';\r\nimport {\r\n Settings,\r\n Check,\r\n FolderTree,\r\n FolderOpen,\r\n Database,\r\n FileText,\r\n Files,\r\n HardDrive,\r\n MessageCircleQuestion,\r\n MessagesSquare,\r\n ChevronDown,\r\n ChevronRight,\r\n Globe,\r\n Folder,\r\n AlertTriangle,\r\n Save,\r\n Download,\r\n Trash2,\r\n} from 'lucide-react';\r\nimport { FloatingFileBrowser } from '@/components/terminal-dashboard/FloatingFileBrowser';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n installCcwMcp,\r\n uninstallCcwMcp,\r\n updateCcwConfig,\r\n installCcwMcpToCodex,\r\n uninstallCcwMcpFromCodex,\r\n updateCcwConfigForCodex,\r\n} from '@/lib/api';\r\nimport { mcpServersKeys, useNotifications } from '@/hooks';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport { cn } from '@/lib/utils';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * CCW Tool definition with name, description, and core flag\r\n */\r\nexport interface CcwTool {\r\n name: string;\r\n desc: string;\r\n core: boolean;\r\n}\r\n\r\n/**\r\n * CCW MCP configuration interface\r\n */\r\nexport interface CcwConfig {\r\n enabledTools: string[];\r\n projectRoot?: string;\r\n allowedDirs?: string;\r\n enableSandbox?: boolean;\r\n}\r\n\r\n/**\r\n * Props for CcwToolsMcpCard component\r\n */\r\nexport interface CcwToolsMcpCardProps {\r\n /** Whether CCW MCP is installed */\r\n isInstalled: boolean;\r\n /** List of enabled tool names */\r\n enabledTools: string[];\r\n /** Project root path */\r\n projectRoot?: string;\r\n /** Comma-separated list of allowed directories */\r\n allowedDirs?: string;\r\n /** Whether sandbox is disabled */\r\n enableSandbox?: boolean;\r\n /** Callback when a tool is toggled */\r\n onToggleTool: (tool: string, enabled: boolean) => void;\r\n /** Callback when configuration is updated */\r\n onUpdateConfig: (config: Partial<CcwConfig>) => void;\r\n /** Callback when install/uninstall is triggered */\r\n onInstall: () => void;\r\n /** Installation target: Claude or Codex */\r\n target?: 'claude' | 'codex';\r\n /** Scopes where CCW MCP is currently installed */\r\n installedScopes?: ('global' | 'project')[];\r\n /** Callback to uninstall from a specific scope */\r\n onUninstallScope?: (scope: 'global' | 'project') => void;\r\n /** Callback to install to an additional scope */\r\n onInstallToScope?: (scope: 'global' | 'project') => void;\r\n}\r\n\r\n// ========== Constants ==========\r\n\r\n/**\r\n * CCW MCP Tools definition\r\n * Available tools that can be enabled/disabled in CCW MCP server\r\n */\r\nexport const CCW_MCP_TOOLS: CcwTool[] = [\r\n { name: 'write_file', desc: 'Write/create files', core: true },\r\n { name: 'edit_file', desc: 'Edit/replace content', core: true },\r\n { name: 'read_file', desc: 'Read single file', core: true },\r\n { name: 'read_many_files', desc: 'Read multiple files/dirs', core: true },\r\n { name: 'core_memory', desc: 'Core memory management', core: true },\r\n { name: 'ask_question', desc: 'Interactive questions (A2UI)', core: false },\r\n { name: 'team_msg', desc: 'Agent team message bus', core: false },\r\n];\r\n\r\n// ========== Component ==========\r\n\r\nexport function CcwToolsMcpCard({\r\n isInstalled,\r\n enabledTools,\r\n projectRoot,\r\n allowedDirs,\r\n enableSandbox,\r\n onToggleTool,\r\n onUpdateConfig,\r\n onInstall,\r\n target = 'claude',\r\n installedScopes = [],\r\n onUninstallScope,\r\n}: CcwToolsMcpCardProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const { success: notifySuccess, error: notifyError } = useNotifications();\r\n const currentProjectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Local state for config inputs\r\n const [projectRootInput, setProjectRootInput] = useState(projectRoot || '');\r\n const [allowedDirsInput, setAllowedDirsInput] = useState(allowedDirs || '');\r\n const [enableSandboxInput, setEnableSandboxInput] = useState(enableSandbox || false);\r\n void setEnableSandboxInput; // reserved for future sandbox toggle UI\r\n const [isExpanded, setIsExpanded] = useState(false);\r\n const [installScope, setInstallScope] = useState<'global' | 'project'>('global');\r\n const [isPathPickerOpen, setIsPathPickerOpen] = useState(false);\r\n const [pathPickerTarget, setPathPickerTarget] = useState<'projectRoot' | 'allowedDirs' | null>(null);\r\n\r\n const isCodex = target === 'codex';\r\n\r\n // Mutations for install/uninstall\r\n const installMutation = useMutation({\r\n mutationFn: isCodex\r\n ? () => installCcwMcpToCodex()\r\n : (params: { scope: 'global' | 'project'; projectPath?: string }) =>\r\n installCcwMcp(params.scope, params.projectPath),\r\n onSuccess: () => {\r\n if (isCodex) {\r\n queryClient.invalidateQueries({ queryKey: ['codexMcpServers'] });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfigCodex'] });\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n }\r\n onInstall();\r\n },\r\n });\r\n\r\n const uninstallMutation = useMutation({\r\n mutationFn: isCodex ? uninstallCcwMcpFromCodex : uninstallCcwMcp,\r\n onSuccess: () => {\r\n if (isCodex) {\r\n queryClient.invalidateQueries({ queryKey: ['codexMcpServers'] });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfigCodex'] });\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n }\r\n onInstall();\r\n },\r\n onError: (error) => {\r\n console.error('Failed to uninstall CCW MCP:', error);\r\n },\r\n });\r\n\r\n const updateConfigMutation = useMutation({\r\n mutationFn: isCodex ? updateCcwConfigForCodex : updateCcwConfig,\r\n onSuccess: () => {\r\n if (isCodex) {\r\n queryClient.invalidateQueries({ queryKey: ['codexMcpServers'] });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfigCodex'] });\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n }\r\n notifySuccess(formatMessage({ id: 'mcp.ccw.feedback.saveSuccess' }));\r\n },\r\n onError: (error) => {\r\n console.error('Failed to update CCW config:', error);\r\n notifyError(\r\n formatMessage({ id: 'mcp.ccw.feedback.saveError' }),\r\n error instanceof Error ? error.message : String(error)\r\n );\r\n },\r\n });\r\n\r\n // Handlers\r\n const handleToggleTool = (toolName: string, enabled: boolean) => {\r\n onToggleTool(toolName, enabled);\r\n };\r\n\r\n const handleEnableAll = () => {\r\n const allToolNames = CCW_MCP_TOOLS.map((t) => t.name);\r\n onUpdateConfig({ enabledTools: allToolNames });\r\n };\r\n\r\n const handleDisableAll = () => {\r\n onUpdateConfig({ enabledTools: [] });\r\n };\r\n\r\n const handleConfigSave = () => {\r\n updateConfigMutation.mutate({\r\n enabledTools,\r\n projectRoot: projectRootInput || undefined,\r\n allowedDirs: allowedDirsInput || undefined,\r\n enableSandbox: enableSandboxInput,\r\n });\r\n };\r\n\r\n const handleInstallClick = () => {\r\n if (isCodex) {\r\n (installMutation as any).mutate(undefined);\r\n } else {\r\n (installMutation as any).mutate({\r\n scope: installScope,\r\n projectPath: installScope === 'project' ? currentProjectPath : undefined,\r\n });\r\n }\r\n };\r\n\r\n const handleUninstallClick = () => {\r\n if (confirm(formatMessage({ id: 'mcp.ccw.actions.uninstallConfirm' }))) {\r\n uninstallMutation.mutate();\r\n }\r\n };\r\n\r\n const isPending = installMutation.isPending || uninstallMutation.isPending || updateConfigMutation.isPending;\r\n\r\n return (\r\n <Card className={cn(\r\n 'overflow-hidden border-2',\r\n isInstalled ? 'border-primary/50 bg-primary/5' : 'border-dashed'\r\n )}>\r\n {/* Header */}\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={() => setIsExpanded(!isExpanded)}\r\n >\r\n <div className=\"flex items-start justify-between gap-2\">\r\n <div className=\"flex items-start gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n isInstalled ? 'bg-primary/20' : 'bg-muted'\r\n )}>\r\n <Settings className={cn(\r\n 'w-5 h-5',\r\n isInstalled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.ccw.title' })}\r\n </span>\r\n {isInstalled && installedScopes.length > 0 ? (\r\n <>\r\n {installedScopes.map((s) => (\r\n <Badge key={s} variant=\"default\" className=\"text-xs\">\r\n {s === 'global' ? <Globe className=\"w-3 h-3 mr-1\" /> : <Folder className=\"w-3 h-3 mr-1\" />}\r\n {formatMessage({ id: `mcp.ccw.scope.${s}` })}\r\n </Badge>\r\n ))}\r\n {installedScopes.length >= 2 && (\r\n <Badge variant=\"outline\" className=\"text-xs text-orange-500 border-orange-300\">\r\n <AlertTriangle className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.conflict.badge' })}\r\n </Badge>\r\n )}\r\n </>\r\n ) : (\r\n <Badge variant={isInstalled ? 'default' : 'secondary'} className=\"text-xs\">\r\n {isInstalled ? formatMessage({ id: 'mcp.ccw.status.installed' }) : formatMessage({ id: 'mcp.ccw.status.notInstalled' })}\r\n </Badge>\r\n )}\r\n {isCodex && (\r\n <Badge variant=\"outline\" className=\"text-xs text-blue-500\">\r\n Codex\r\n </Badge>\r\n )}\r\n {isInstalled && (\r\n <Badge variant=\"outline\" className=\"text-xs text-info\">\r\n {formatMessage({ id: 'mcp.ccw.status.special' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'mcp.ccw.description' })}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\r\n ) : (\r\n <ChevronRight className=\"w-5 h-5 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border p-4 space-y-4 bg-muted/30\">\r\n {/* Quick Select Buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleEnableAll}\r\n disabled={!isInstalled}\r\n >\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.enableAll' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleDisableAll}\r\n disabled={!isInstalled}\r\n >\r\n {formatMessage({ id: 'mcp.ccw.actions.disableAll' })}\r\n </Button>\r\n </div>\r\n\r\n {/* Tool Checkboxes */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <p className=\"text-xs font-medium text-muted-foreground uppercase\">\r\n {formatMessage({ id: 'mcp.ccw.tools.label' })}\r\n </p>\r\n {!isInstalled && (\r\n <p className=\"text-xs text-amber-600 dark:text-amber-500\">\r\n {formatMessage({ id: 'mcp.ccw.tools.hint' })}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"grid grid-cols-2 gap-2\">\r\n {CCW_MCP_TOOLS.map((tool) => {\r\n const isEnabled = enabledTools.includes(tool.name);\r\n const icon = getToolIcon(tool.name);\r\n\r\n return (\r\n <div\r\n key={tool.name}\r\n className={cn(\r\n 'flex items-center gap-3 p-2 rounded-lg transition-colors border',\r\n isEnabled ? 'bg-background border-primary/40' : 'bg-background border-border'\r\n )}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n id={`ccw-tool-${tool.name}`}\r\n checked={isEnabled}\r\n onChange={(e) => handleToggleTool(tool.name, e.target.checked)}\r\n disabled={!isInstalled}\r\n className=\"w-4 h-4\"\r\n />\r\n <label\r\n htmlFor={`ccw-tool-${tool.name}`}\r\n className=\"flex items-center gap-2 flex-1 cursor-pointer\"\r\n >\r\n {icon}\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: `mcp.ccw.tools.${tool.name}.name` })}\r\n </span>\r\n {tool.core && (\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.ccw.tools.core' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: `mcp.ccw.tools.${tool.name}.desc` })}\r\n </p>\r\n </div>\r\n </label>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Project Root */}\r\n <div className=\"space-y-1\">\r\n <label className=\"text-sm text-foreground flex items-center gap-1\">\r\n <FolderTree className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'mcp.ccw.paths.projectRoot' })}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n <Input\r\n value={projectRootInput}\r\n onChange={(e) => setProjectRootInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.ccw.paths.projectRootPlaceholder' })}\r\n disabled={!isInstalled}\r\n className=\"font-mono text-sm\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n onClick={() => {\r\n setPathPickerTarget('projectRoot');\r\n setIsPathPickerOpen(true);\r\n }}\r\n disabled={!isInstalled}\r\n title=\"Browse for project root\"\r\n >\r\n <FolderOpen className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Allowed Dirs */}\r\n <div className=\"space-y-1\">\r\n <label className=\"text-sm text-foreground flex items-center gap-1\">\r\n <HardDrive className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'mcp.ccw.paths.allowedDirs' })}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n <Input\r\n value={allowedDirsInput}\r\n onChange={(e) => setAllowedDirsInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.ccw.paths.allowedDirsPlaceholder' })}\r\n disabled={!isInstalled}\r\n className=\"font-mono text-sm\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n onClick={() => {\r\n setPathPickerTarget('allowedDirs');\r\n setIsPathPickerOpen(true);\r\n }}\r\n disabled={!isInstalled}\r\n title=\"Browse for allowed directories\"\r\n >\r\n <FolderOpen className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.ccw.paths.allowedDirsHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Save Config Button */}\r\n {isInstalled && (\r\n <div className=\"flex justify-end\">\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={handleConfigSave}\r\n disabled={isPending}\r\n >\r\n <Save className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.saveConfig' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Install / Uninstall Section */}\r\n <div className=\"border-t border-border pt-4 space-y-2\">\r\n {!isInstalled ? (\r\n <div className=\"flex items-center gap-2\">\r\n {!isCodex && (\r\n <select\r\n value={installScope}\r\n onChange={(e) => setInstallScope(e.target.value as 'global' | 'project')}\r\n className=\"text-sm border border-border rounded px-2 py-1 bg-background text-foreground\"\r\n >\r\n <option value=\"global\">{formatMessage({ id: 'mcp.ccw.scope.global' })}</option>\r\n <option value=\"project\">{formatMessage({ id: 'mcp.ccw.scope.project' })}</option>\r\n </select>\r\n )}\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={handleInstallClick}\r\n disabled={isPending}\r\n >\r\n <Download className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.install' })}\r\n </Button>\r\n </div>\r\n ) : (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n {installedScopes.length > 0 && onUninstallScope ? (\r\n installedScopes.map((s) => (\r\n <Button\r\n key={s}\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => onUninstallScope(s)}\r\n disabled={isPending}\r\n className=\"text-destructive border-destructive/50 hover:bg-destructive/10\"\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.uninstallScope' }, { scope: s })}\r\n </Button>\r\n ))\r\n ) : (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleUninstallClick}\r\n disabled={isPending}\r\n className=\"text-destructive border-destructive/50 hover:bg-destructive/10\"\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.uninstall' })}\r\n </Button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <FloatingFileBrowser\r\n isOpen={isPathPickerOpen}\r\n onClose={() => setIsPathPickerOpen(false)}\r\n rootPath={currentProjectPath || '/'}\r\n onInsertPath={(path) => {\r\n if (pathPickerTarget === 'projectRoot') {\r\n setProjectRootInput(path);\r\n } else if (pathPickerTarget === 'allowedDirs') {\r\n setAllowedDirsInput((prev) => (prev ? `${prev},${path}` : path));\r\n }\r\n setIsPathPickerOpen(false);\r\n }}\r\n />\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\n/**\r\n * Get icon component for a tool name\r\n */\r\nfunction getToolIcon(toolName: string): React.ReactElement {\r\n const iconProps = { className: 'w-4 h-4 text-muted-foreground' };\r\n\r\n switch (toolName) {\r\n case 'write_file':\r\n return <FileText {...iconProps} />;\r\n case 'edit_file':\r\n return <Check {...iconProps} />;\r\n case 'read_file':\r\n return <Database {...iconProps} />;\r\n case 'read_many_files':\r\n return <Files {...iconProps} />;\r\n case 'core_memory':\r\n return <Settings {...iconProps} />;\r\n case 'ask_question':\r\n return <MessageCircleQuestion {...iconProps} />;\r\n case 'team_msg':\r\n return <MessagesSquare {...iconProps} />;\r\n default:\r\n return <Settings {...iconProps} />;\r\n }\r\n}\r\n\r\nexport default CcwToolsMcpCard;\r\n","// ========================================\r\n// MCP Templates Section Component\r\n// ========================================\r\n// Template management component with card/list view, search input, category filter, save/delete/install actions\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport {\r\n Copy,\r\n Trash2,\r\n Download,\r\n Search,\r\n Filter,\r\n Plus,\r\n FileCode,\r\n Folder,\r\n Globe,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport {\r\n AlertDialog,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n AlertDialogContent,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n} from '@/components/ui/AlertDialog';\r\nimport {\r\n fetchMcpTemplateCategories,\r\n searchMcpTemplates,\r\n fetchMcpTemplatesByCategory,\r\n} from '@/lib/api';\r\nimport { mcpTemplatesKeys, useDeleteTemplate, useInstallTemplate } from '@/hooks';\r\nimport type { McpTemplate } from '@/types/store';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface McpTemplatesSectionProps {\r\n /** Callback when template is installed (opens McpServerDialog) */\r\n onInstallTemplate?: (template: McpTemplate) => void;\r\n /** Callback when saving a new template */\r\n onSaveAsTemplate?: (name: string, category: string, description: string, serverConfig: { command: string; args: string[]; env: Record<string, string> }) => void;\r\n}\r\n\r\ninterface TemplateSaveDialogProps {\r\n open: boolean;\r\n onClose: () => void;\r\n onSave: (name: string, category: string, description: string, serverConfig: { command: string; args: string[]; env: Record<string, string> }) => void;\r\n defaultName?: string;\r\n defaultCommand?: string;\r\n defaultArgs?: string[];\r\n defaultEnv?: Record<string, string>;\r\n}\r\n\r\ninterface TemplateCardProps {\r\n template: McpTemplate;\r\n onInstall: (template: McpTemplate) => void;\r\n onDelete: (templateName: string) => void;\r\n isInstalling: boolean;\r\n isDeleting: boolean;\r\n}\r\n\r\n// ========== Constants ==========\r\n\r\nconst SEARCH_DEBOUNCE_MS = 300;\r\n\r\n// ========== Helper Components ==========\r\n\r\n/**\r\n * Template Card Component - Display single template with actions\r\n */\r\nfunction TemplateCard({ template, onInstall, onDelete, isInstalling, isDeleting }: TemplateCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const handleInstall = () => {\r\n onInstall(template);\r\n };\r\n\r\n const handleDelete = () => {\r\n onDelete(template.name);\r\n };\r\n\r\n // Get icon based on category\r\n const getCategoryIcon = () => {\r\n const iconProps = { className: 'w-4 h-4' };\r\n switch (template.category?.toLowerCase()) {\r\n case 'stdio':\r\n case 'transport':\r\n return <FileCode {...iconProps} />;\r\n case 'language':\r\n case 'python':\r\n case 'node':\r\n return <Folder {...iconProps} />;\r\n case 'official':\r\n case 'builtin':\r\n return <Globe {...iconProps} />;\r\n default:\r\n return <Copy {...iconProps} />;\r\n }\r\n };\r\n\r\n return (\r\n <Card className=\"p-4 hover:border-primary/50 transition-colors\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\r\n <div className=\"p-2 rounded-lg bg-muted flex-shrink-0\">\r\n {getCategoryIcon()}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {template.name}\r\n </span>\r\n {template.category && (\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {template.category}\r\n </Badge>\r\n )}\r\n </div>\r\n {template.description && (\r\n <p className=\"text-xs text-muted-foreground mt-1 line-clamp-2\">\r\n {template.description}\r\n </p>\r\n )}\r\n <div className=\"flex items-center gap-2 mt-2\">\r\n <code className=\"text-xs bg-muted px-2 py-1 rounded font-mono truncate max-w-[150px]\">\r\n {template.serverConfig.command}\r\n </code>\r\n {template.serverConfig.args && template.serverConfig.args.length > 0 && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {template.serverConfig.args.length} args\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-1 flex-shrink-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={handleInstall}\r\n disabled={isInstalling}\r\n title={formatMessage({ id: 'mcp.templates.actions.install' })}\r\n >\r\n <Download className=\"w-4 h-4\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={handleDelete}\r\n disabled={isDeleting}\r\n title={formatMessage({ id: 'mcp.templates.actions.delete' })}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Template Save Dialog - Save current server configuration as template\r\n */\r\nexport function TemplateSaveDialog({\r\n open,\r\n onClose,\r\n onSave,\r\n defaultName = '',\r\n defaultCommand = '',\r\n defaultArgs = [],\r\n defaultEnv = {},\r\n}: TemplateSaveDialogProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const [name, setName] = useState(defaultName);\r\n const [category, setCategory] = useState('');\r\n const [description, setDescription] = useState('');\r\n const [command, setCommand] = useState(defaultCommand);\r\n const [argsInput, setArgsInput] = useState(defaultArgs.join(', '));\r\n const [envInput, setEnvInput] = useState(\r\n Object.entries(defaultEnv).map(([k, v]) => `${k}=${v}`).join('\\n')\r\n );\r\n const [errors, setErrors] = useState<{ name?: string; command?: string }>({});\r\n\r\n // Reset form when dialog opens\r\n useEffect(() => {\r\n if (open) {\r\n setName(defaultName || '');\r\n setCategory('');\r\n setDescription('');\r\n setCommand(defaultCommand || '');\r\n setArgsInput((defaultArgs || []).join(', '));\r\n setEnvInput(\r\n Object.entries(defaultEnv || {}).map(([k, v]) => `${k}=${v}`).join('\\n')\r\n );\r\n setErrors({});\r\n }\r\n }, [open, defaultName, defaultCommand, defaultArgs, defaultEnv]);\r\n\r\n const handleSave = () => {\r\n const newErrors: { name?: string; command?: string } = {};\r\n if (!name.trim()) {\r\n newErrors.name = formatMessage({ id: 'mcp.templates.saveDialog.validation.nameRequired' });\r\n }\r\n if (!command.trim()) {\r\n newErrors.command = formatMessage({ id: 'mcp.dialog.validation.commandRequired' });\r\n }\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n const args = argsInput\r\n .split(',')\r\n .map((a) => a.trim())\r\n .filter((a) => a.length > 0);\r\n\r\n const env: Record<string, string> = {};\r\n for (const line of envInput.split('\\n')) {\r\n const trimmed = line.trim();\r\n if (trimmed && trimmed.includes('=')) {\r\n const [key, ...valParts] = trimmed.split('=');\r\n if (key) env[key.trim()] = valParts.join('=').trim();\r\n }\r\n }\r\n\r\n onSave(name.trim(), category.trim(), description.trim(), {\r\n command: command.trim(),\r\n args,\r\n env,\r\n });\r\n };\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={onClose}>\r\n <DialogContent className=\"max-w-md max-h-[85vh] overflow-y-auto\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {formatMessage({ id: 'mcp.templates.saveDialog.title' })}\r\n </DialogTitle>\r\n </DialogHeader>\r\n <div className=\"space-y-4\">\r\n {/* Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.templates.saveDialog.name' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={name}\r\n onChange={(e) => {\r\n setName(e.target.value);\r\n if (errors.name) setErrors((prev) => ({ ...prev, name: undefined }));\r\n }}\r\n placeholder={formatMessage({ id: 'mcp.templates.saveDialog.namePlaceholder' })}\r\n error={!!errors.name}\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n </div>\r\n\r\n {/* Command */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.command' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={command}\r\n onChange={(e) => {\r\n setCommand(e.target.value);\r\n if (errors.command) setErrors((prev) => ({ ...prev, command: undefined }));\r\n }}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.commandPlaceholder' })}\r\n error={!!errors.command}\r\n />\r\n {errors.command && (\r\n <p className=\"text-sm text-destructive\">{errors.command}</p>\r\n )}\r\n </div>\r\n\r\n {/* Args */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.args' })}\r\n </label>\r\n <Input\r\n value={argsInput}\r\n onChange={(e) => setArgsInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.argsPlaceholder' })}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.argsHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Environment Variables */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.env' })}\r\n </label>\r\n <textarea\r\n value={envInput}\r\n onChange={(e) => setEnvInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.envPlaceholder' })}\r\n className=\"flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\r\n />\r\n </div>\r\n\r\n {/* Category */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.templates.saveDialog.category' })}\r\n </label>\r\n <Select value={category} onValueChange={setCategory}>\r\n <SelectTrigger className=\"w-full\">\r\n <SelectValue placeholder={formatMessage({ id: 'mcp.templates.saveDialog.categoryPlaceholder' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"stdio\">STDIO</SelectItem>\r\n <SelectItem value=\"sse\">SSE</SelectItem>\r\n <SelectItem value=\"language\">Language</SelectItem>\r\n <SelectItem value=\"official\">Official</SelectItem>\r\n <SelectItem value=\"custom\">Custom</SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Description */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.templates.saveDialog.description' })}\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.templates.saveDialog.descriptionPlaceholder' })}\r\n className=\"flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\r\n />\r\n </div>\r\n </div>\r\n <DialogFooter>\r\n <Button variant=\"outline\" onClick={onClose}>\r\n {formatMessage({ id: 'mcp.templates.saveDialog.cancel' })}\r\n </Button>\r\n <Button onClick={handleSave}>\r\n {formatMessage({ id: 'mcp.templates.saveDialog.save' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * McpTemplatesSection - Main template management component\r\n *\r\n * Features:\r\n * - Template list view with search and category filter\r\n * - Install template action (populates McpServerDialog)\r\n * - Delete template with confirmation\r\n * - Save current server as template\r\n */\r\nexport function McpTemplatesSection({ onInstallTemplate, onSaveAsTemplate }: McpTemplatesSectionProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // State\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [debouncedSearch, setDebouncedSearch] = useState('');\r\n const [selectedCategory, setSelectedCategory] = useState<string>('all');\r\n const [saveDialogOpen, setSaveDialogOpen] = useState(false);\r\n const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);\r\n const [templateToDelete, setTemplateToDelete] = useState<string | null>(null);\r\n\r\n // Fetch categories for filter dropdown\r\n const { data: categories = [], isLoading: categoriesLoading } = useQuery({\r\n queryKey: mcpTemplatesKeys.categories(),\r\n queryFn: fetchMcpTemplateCategories,\r\n staleTime: 10 * 60 * 1000, // 10 minutes\r\n });\r\n\r\n // Mutations\r\n const deleteMutation = useDeleteTemplate();\r\n const installMutation = useInstallTemplate();\r\n\r\n // Debounced search\r\n useEffect(() => {\r\n const timer = setTimeout(() => {\r\n setDebouncedSearch(searchQuery);\r\n }, SEARCH_DEBOUNCE_MS);\r\n return () => clearTimeout(timer);\r\n }, [searchQuery]);\r\n\r\n // Fetch templates based on search and category filter\r\n const { data: templates = [], isLoading: templatesLoading } = useQuery({\r\n queryKey: mcpTemplatesKeys.list(selectedCategory === 'all' ? undefined : selectedCategory),\r\n queryFn: async () => {\r\n if (debouncedSearch.trim()) {\r\n return searchMcpTemplates(debouncedSearch.trim());\r\n } else if (selectedCategory === 'all') {\r\n // Fetch all templates by iterating categories\r\n const allTemplates: McpTemplate[] = [];\r\n for (const category of categories) {\r\n const categoryTemplates = await fetchMcpTemplatesByCategory(category);\r\n allTemplates.push(...categoryTemplates);\r\n }\r\n return allTemplates;\r\n } else {\r\n return fetchMcpTemplatesByCategory(selectedCategory);\r\n }\r\n },\r\n staleTime: 5 * 60 * 1000, // 5 minutes\r\n enabled: !categoriesLoading,\r\n });\r\n\r\n // Handlers\r\n const handleInstallTemplate = useCallback((template: McpTemplate) => {\r\n // Call parent callback to open McpServerDialog with template data\r\n onInstallTemplate?.(template);\r\n }, [onInstallTemplate]);\r\n\r\n const handleDeleteClick = useCallback((templateName: string) => {\r\n setTemplateToDelete(templateName);\r\n setDeleteConfirmOpen(true);\r\n }, []);\r\n\r\n const handleDeleteConfirm = useCallback(async () => {\r\n if (!templateToDelete) return;\r\n\r\n const result = await deleteMutation.deleteTemplate(templateToDelete);\r\n if (result.success) {\r\n setDeleteConfirmOpen(false);\r\n setTemplateToDelete(null);\r\n }\r\n }, [templateToDelete, deleteMutation]);\r\n\r\n const handleSaveTemplate = useCallback((_name: string, _category: string, _description: string, _serverConfig: { command: string; args: string[]; env: Record<string, string> }) => {\r\n onSaveAsTemplate?.(_name, _category, _description, _serverConfig);\r\n setSaveDialogOpen(false);\r\n }, [onSaveAsTemplate]);\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header with search and filter */}\r\n <div className=\"flex items-center justify-between gap-3\">\r\n <div className=\"flex items-center gap-2 flex-1\">\r\n {/* Search Input */}\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <Input\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.templates.searchPlaceholder' })}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n\r\n {/* Category Filter */}\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-muted-foreground\" />\r\n <Select value={selectedCategory} onValueChange={setSelectedCategory}>\r\n <SelectTrigger className=\"w-[150px]\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"all\">\r\n {formatMessage({ id: 'mcp.templates.filter.allCategories' })}\r\n </SelectItem>\r\n {categories.map((category) => (\r\n <SelectItem key={category} value={category}>\r\n {category}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n </div>\r\n\r\n {/* Save Template Button */}\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => setSaveDialogOpen(true)}\r\n >\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}\r\n </Button>\r\n </div>\r\n\r\n {/* Template List */}\r\n {templatesLoading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.templates.loading' })}\r\n </p>\r\n </div>\r\n ) : templates.length === 0 ? (\r\n <Card className=\"p-12 text-center\">\r\n <Copy className=\"w-12 h-12 mx-auto text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-2\">\r\n {formatMessage({ id: 'mcp.templates.empty.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'mcp.templates.empty.message' })}\r\n </p>\r\n <Button onClick={() => setSaveDialogOpen(true)}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.templates.empty.createFirst' })}\r\n </Button>\r\n </Card>\r\n ) : (\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-3\">\r\n {templates.map((template) => (\r\n <TemplateCard\r\n key={template.name}\r\n template={template}\r\n onInstall={handleInstallTemplate}\r\n onDelete={handleDeleteClick}\r\n isInstalling={installMutation.isInstalling}\r\n isDeleting={deleteMutation.isDeleting}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Save Template Dialog */}\r\n <TemplateSaveDialog\r\n open={saveDialogOpen}\r\n onClose={() => setSaveDialogOpen(false)}\r\n onSave={handleSaveTemplate}\r\n />\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>\r\n {formatMessage({ id: 'mcp.templates.deleteDialog.title' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage(\r\n { id: 'mcp.templates.deleteDialog.message' },\r\n { name: templateToDelete }\r\n )}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel>\r\n {formatMessage({ id: 'mcp.templates.deleteDialog.cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n onClick={handleDeleteConfirm}\r\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n >\r\n {deleteMutation.isDeleting\r\n ? formatMessage({ id: 'mcp.templates.deleteDialog.deleting' })\r\n : formatMessage({ id: 'mcp.templates.deleteDialog.delete' })\r\n }\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n );\r\n}\r\n\r\nexport default McpTemplatesSection;\r\n","// ========================================\r\n// Recommended MCP Wizard Component\r\n// ========================================\r\n// Dynamic configuration wizard for recommended MCP servers\r\n// Supports text, password, and multi-select field types\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { Download, Loader2, Search, Globe, Sparkles, Settings } from 'lucide-react';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Label } from '@/components/ui/Label';\r\nimport {\n addGlobalMcpServer,\n copyMcpServerToProject,\n} from '@/lib/api';\nimport { mcpServersKeys } from '@/hooks';\nimport { useNotifications } from '@/hooks/useNotifications';\nimport { cn } from '@/lib/utils';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\n\r\n// Icon map for MCP definitions\r\nconst ICON_MAP: Record<string, React.ComponentType<{ className?: string }>> = {\r\n 'search-code': Search,\r\n 'chrome': Globe,\r\n 'globe-2': Sparkles,\r\n 'code-2': Settings,\r\n};\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Field definition for wizard\r\n */\r\nexport interface WizardField {\r\n key: string;\r\n labelKey: string;\r\n descKey?: string;\r\n type: 'text' | 'password' | 'multi-select';\r\n default?: string | string[];\r\n placeholder?: string;\r\n required?: boolean;\r\n options?: Array<{\r\n value: string;\r\n label: string;\r\n desc?: string;\r\n }>;\r\n}\r\n\r\n/**\r\n * Recommended MCP server definition\r\n */\r\nexport interface RecommendedMcpDefinition {\r\n id: string;\r\n nameKey: string;\r\n descKey: string;\r\n icon: string;\r\n category: string;\r\n fields: WizardField[];\r\n buildConfig: (values: Record<string, any>) => {\r\n command: string;\r\n args: string[];\r\n env?: Record<string, string>;\r\n type?: string;\r\n };\r\n}\r\n\r\n/**\r\n * Props for RecommendedMcpWizard component\r\n */\r\nexport interface RecommendedMcpWizardProps {\r\n open: boolean;\r\n onClose: () => void;\r\n mcpDefinition: RecommendedMcpDefinition | null;\r\n onInstallComplete?: () => void;\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * Wizard for installing recommended MCP servers with configuration\r\n */\r\nexport function RecommendedMcpWizard({\r\n open,\r\n onClose,\r\n mcpDefinition,\r\n onInstallComplete,\r\n}: RecommendedMcpWizardProps) {\r\n const { formatMessage } = useIntl();\n const queryClient = useQueryClient();\n const { success: showSuccess, error: showError } = useNotifications();\n const projectPath = useWorkflowStore(selectProjectPath);\n\r\n // State for field values\r\n const [fieldValues, setFieldValues] = useState<Record<string, any>>({});\r\n const [selectedScope, setSelectedScope] = useState<'project' | 'global'>('global');\r\n\r\n // Initialize field values when dialog opens\r\n const initializeFieldValues = () => {\r\n if (!mcpDefinition) return;\r\n\r\n const initialValues: Record<string, any> = {};\r\n for (const field of mcpDefinition.fields) {\r\n if (field.default !== undefined) {\r\n initialValues[field.key] = field.default;\r\n } else if (field.type === 'multi-select') {\r\n initialValues[field.key] = [];\r\n } else {\r\n initialValues[field.key] = '';\r\n }\r\n }\r\n setFieldValues(initialValues);\r\n };\r\n\r\n // Reset on open/close\r\n const handleOpenChange = (newOpen: boolean) => {\r\n if (newOpen && mcpDefinition) {\r\n initializeFieldValues();\r\n } else {\r\n setFieldValues({});\r\n onClose();\r\n }\r\n };\r\n\r\n // Install mutation\r\n const installMutation = useMutation({\r\n mutationFn: async () => {\r\n if (!mcpDefinition) throw new Error('No MCP definition');\r\n\r\n const serverConfig = mcpDefinition.buildConfig(fieldValues);\r\n\r\n if (selectedScope === 'global') {\n return addGlobalMcpServer(mcpDefinition.id, serverConfig);\n } else {\n if (!projectPath) {\n throw new Error('Project path is required to install to project scope');\n }\n return copyMcpServerToProject(mcpDefinition.id, serverConfig, projectPath);\n }\n },\n onSuccess: (result) => {\r\n if (result.success) {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n showSuccess(\r\n formatMessage({ id: 'mcp.wizard.installSuccess' }),\r\n formatMessage({ id: mcpDefinition!.nameKey })\r\n );\r\n handleOpenChange(false);\r\n onInstallComplete?.();\r\n } else {\r\n showError(\r\n formatMessage({ id: 'mcp.wizard.installError' }),\r\n result.error || 'Unknown error'\r\n );\r\n }\r\n },\r\n onError: (err: Error) => {\r\n showError(\r\n formatMessage({ id: 'mcp.wizard.installError' }),\r\n err.message\r\n );\r\n },\r\n });\r\n\r\n // Handle field value change\r\n const handleFieldChange = (key: string, value: any) => {\r\n setFieldValues(prev => ({\r\n ...prev,\r\n [key]: value,\r\n }));\r\n };\r\n\r\n // Handle multi-select toggle\r\n const handleMultiSelectToggle = (key: string, value: string) => {\r\n const current = fieldValues[key] || [];\r\n const newValue = current.includes(value)\r\n ? current.filter((v: string) => v !== value)\r\n : [...current, value];\r\n handleFieldChange(key, newValue);\r\n };\r\n\r\n // Validate required fields\r\n const validateFields = (): boolean => {\r\n if (!mcpDefinition) return false;\r\n\r\n for (const field of mcpDefinition.fields) {\r\n if (field.required) {\r\n const value = fieldValues[field.key];\r\n if (field.type === 'multi-select') {\r\n if (!value || value.length === 0) return false;\r\n } else {\r\n if (!value || value.trim() === '') return false;\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n\r\n // Handle submit\r\n const handleSubmit = () => {\r\n if (!validateFields()) {\r\n showError(\r\n formatMessage({ id: 'mcp.wizard.validation' }),\r\n formatMessage({ id: 'mcp.wizard.requiredFields' })\r\n );\r\n return;\r\n }\r\n installMutation.mutate();\r\n };\r\n\r\n if (!mcpDefinition) return null;\r\n\r\n const hasFields = mcpDefinition.fields.length > 0;\r\n const Icon = ICON_MAP[mcpDefinition.icon] || Settings;\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleOpenChange}>\r\n <DialogContent className=\"max-w-lg max-h-[90vh] overflow-y-auto\">\r\n {/* Header */}\r\n <DialogHeader>\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center\">\r\n <Icon className=\"w-5 h-5 text-primary\" />\r\n </div>\r\n <div>\r\n <DialogTitle>\r\n {formatMessage({ id: 'mcp.wizard.install' })} {formatMessage({ id: mcpDefinition.nameKey })}\r\n </DialogTitle>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: mcpDefinition.descKey })}\r\n </p>\r\n </div>\r\n </div>\r\n </DialogHeader>\r\n\r\n {/* Content */}\r\n <div className=\"space-y-4 py-4\">\r\n {/* Fields */}\r\n {hasFields && (\r\n <div className=\"space-y-3\">\r\n {mcpDefinition.fields.map((field) => (\r\n <div key={field.key} className=\"space-y-1.5\">\r\n <Label className=\"flex items-center gap-1.5 text-sm font-medium\">\r\n {formatMessage({ id: field.labelKey })}\r\n {field.required && <span className=\"text-destructive\">*</span>}\r\n </Label>\r\n {field.descKey && (\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: field.descKey })}\r\n </p>\r\n )}\r\n\r\n {/* Text/Password Input */}\r\n {(field.type === 'text' || field.type === 'password') && (\r\n <Input\r\n type={field.type}\r\n value={fieldValues[field.key] || ''}\r\n onChange={(e) => handleFieldChange(field.key, e.target.value)}\r\n placeholder={field.placeholder}\r\n className=\"font-mono text-sm\"\r\n />\r\n )}\r\n\r\n {/* Multi-Select */}\r\n {field.type === 'multi-select' && field.options && (\r\n <div className=\"space-y-2 p-2 bg-muted/30 border border-border rounded-lg max-h-48 overflow-y-auto\">\r\n {field.options.map((option) => {\r\n const isSelected = (fieldValues[field.key] || []).includes(option.value);\r\n return (\r\n <div\r\n key={option.value}\r\n className={cn(\r\n 'flex items-start gap-2 p-2 rounded transition-colors cursor-pointer',\r\n isSelected ? 'bg-primary/10' : 'hover:bg-muted/50'\r\n )}\r\n onClick={() => handleMultiSelectToggle(field.key, option.value)}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={isSelected}\r\n onChange={() => {}}\r\n className=\"mt-0.5 w-4 h-4\"\r\n />\r\n <div className=\"flex-1\">\r\n <div className=\"text-sm font-medium text-foreground\">\r\n {option.label}\r\n </div>\r\n {option.desc && (\r\n <div className=\"text-xs text-muted-foreground\">\r\n {option.desc}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Scope Selection */}\r\n <div className=\"space-y-2 pt-3 border-t border-border\">\r\n <Label className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'mcp.wizard.scope' })}\r\n </Label>\r\n <div className=\"flex gap-2\">\r\n <Button\r\n variant={selectedScope === 'global' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setSelectedScope('global')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.wizard.scope.global' })}\r\n </Button>\r\n <Button\r\n variant={selectedScope === 'project' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setSelectedScope('project')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.wizard.scope.project' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* No Configuration Needed Message */}\r\n {!hasFields && (\r\n <div className=\"p-3 bg-success/10 border border-success/20 rounded-lg text-sm text-success\">\r\n {formatMessage({ id: 'mcp.noConfigNeeded' })}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Footer */}\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => handleOpenChange(false)}\r\n disabled={installMutation.isPending}\r\n >\r\n {formatMessage({ id: 'mcp.dialog.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n disabled={installMutation.isPending}\r\n >\r\n {installMutation.isPending ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-1 animate-spin\" />\r\n {formatMessage({ id: 'mcp.wizard.installing' })}\r\n </>\r\n ) : (\r\n <>\r\n <Download className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.wizard.install' })}\r\n </>\r\n )}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default RecommendedMcpWizard;\r\n","// ========================================\r\n// Recommended MCP Section Component\r\n// ========================================\r\n// Display recommended MCP servers with wizard-based install functionality\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Search,\r\n Globe,\r\n Sparkles,\r\n Download,\r\n Settings,\r\n Key,\r\n Zap,\r\n Code2,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { RecommendedMcpWizard, RecommendedMcpDefinition } from './RecommendedMcpWizard';\r\nimport { fetchMcpConfig } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Props for RecommendedMcpSection component\r\n */\r\nexport interface RecommendedMcpSectionProps {\r\n /** Callback when server is installed */\r\n onInstallComplete?: () => void;\r\n}\r\n\r\n// ========== Platform Detection ==========\r\nconst isWindows = typeof navigator !== 'undefined' && navigator.platform?.toLowerCase().includes('win');\r\n\r\n/**\r\n * Build cross-platform MCP config\r\n * On Windows, wraps npx/node/python commands with cmd /c for proper execution\r\n */\r\nfunction buildCrossPlatformMcpConfig(\r\n command: string,\r\n args: string[] = [],\r\n options: { env?: Record<string, string>; type?: string } = {}\r\n) {\r\n const { env, type } = options;\r\n\r\n const windowsWrappedCommands = ['npx', 'npm', 'node', 'python', 'python3', 'pip', 'pip3', 'pnpm', 'yarn', 'bun'];\r\n const needsWindowsWrapper = isWindows && windowsWrappedCommands.includes(command.toLowerCase());\r\n\r\n const config: { command: string; args: string[]; env?: Record<string, string>; type?: string } = needsWindowsWrapper\r\n ? { command: 'cmd', args: ['/c', command, ...args] }\r\n : { command, args };\r\n\r\n if (type) config.type = type;\r\n if (env && Object.keys(env).length > 0) config.env = env;\r\n\r\n return config;\r\n}\r\n\r\n// ========== Recommended MCP Definitions ==========\r\n\r\n/**\r\n * Pre-configured recommended MCP servers with field definitions\r\n * Matches original JS version structure for full wizard support\r\n */\r\nconst RECOMMENDED_MCP_DEFINITIONS: RecommendedMcpDefinition[] = [\r\n {\r\n id: 'ace-tool',\r\n nameKey: 'mcp.ace-tool.name',\r\n descKey: 'mcp.ace-tool.desc',\r\n icon: 'search-code',\r\n category: 'search',\r\n fields: [\r\n {\r\n key: 'baseUrl',\r\n labelKey: 'mcp.ace-tool.field.baseUrl',\r\n type: 'text',\r\n default: 'https://acemcp.heroman.wtf/relay/',\r\n placeholder: 'https://acemcp.heroman.wtf/relay/',\r\n required: true,\r\n descKey: 'mcp.ace-tool.field.baseUrl.desc',\r\n },\r\n {\r\n key: 'token',\r\n labelKey: 'mcp.ace-tool.field.token',\r\n type: 'password',\r\n default: '',\r\n placeholder: 'ace_xxxxxxxxxxxxxxxx',\r\n required: true,\r\n descKey: 'mcp.ace-tool.field.token.desc',\r\n },\r\n ],\r\n buildConfig: (values) => buildCrossPlatformMcpConfig('npx', [\r\n 'ace-tool',\r\n '--base-url',\r\n values.baseUrl || 'https://acemcp.heroman.wtf/relay/',\r\n '--token',\r\n values.token,\r\n ]),\r\n },\r\n {\r\n id: 'chrome-devtools',\r\n nameKey: 'mcp.chrome-devtools.name',\r\n descKey: 'mcp.chrome-devtools.desc',\r\n icon: 'chrome',\r\n category: 'browser',\r\n fields: [],\r\n buildConfig: () => buildCrossPlatformMcpConfig('npx', ['chrome-devtools-mcp@latest'], { type: 'stdio' }),\r\n },\r\n {\r\n id: 'exa',\r\n nameKey: 'mcp.exa.name',\r\n descKey: 'mcp.exa.desc',\r\n icon: 'globe-2',\r\n category: 'search',\r\n fields: [\r\n {\r\n key: 'apiKey',\r\n labelKey: 'mcp.exa.field.apiKey',\r\n type: 'password',\r\n default: '',\r\n placeholder: 'your-exa-api-key',\r\n required: false,\r\n descKey: 'mcp.exa.field.apiKey.desc',\r\n },\r\n ],\r\n buildConfig: (values) => {\r\n const baseUrl = 'https://mcp.exa.ai/mcp';\r\n const url = values.apiKey ? `${baseUrl}?exaApiKey=${values.apiKey}` : baseUrl;\r\n return buildCrossPlatformMcpConfig('npx', ['-y', 'mcp-remote', url]);\r\n },\r\n },\r\n];\r\n\r\n// ========== Icon Map ==========\r\n\r\nconst ICON_MAP: Record<string, React.ComponentType<{ className?: string }>> = {\r\n 'search-code': Search,\r\n 'chrome': Globe,\r\n 'globe-2': Sparkles,\r\n 'code-2': Code2,\r\n};\r\n\r\n// ========== Helper Component ==========\r\n\r\ninterface RecommendedServerCardProps {\r\n definition: RecommendedMcpDefinition;\r\n isInstalled: boolean;\r\n onInstall: (definition: RecommendedMcpDefinition) => void;\r\n}\r\n\r\n/**\r\n * Individual recommended server card\r\n */\r\nfunction RecommendedServerCard({\r\n definition,\r\n isInstalled,\r\n onInstall,\r\n}: RecommendedServerCardProps) {\r\n const { formatMessage } = useIntl();\r\n const Icon = ICON_MAP[definition.icon] || Settings;\r\n const hasFields = definition.fields.length > 0;\r\n\r\n return (\r\n <Card className=\"p-4 hover:shadow-md transition-shadow\">\r\n <div className=\"flex items-start gap-3\">\r\n {/* Icon */}\r\n <div className={cn(\r\n 'p-2.5 rounded-lg',\r\n isInstalled ? 'bg-primary/20' : 'bg-muted'\r\n )}>\r\n <Icon className={cn(\r\n 'w-5 h-5',\r\n isInstalled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n\r\n {/* Content */}\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <h4 className=\"text-sm font-medium text-foreground truncate\">\r\n {formatMessage({ id: definition.nameKey })}\r\n </h4>\r\n {isInstalled && (\r\n <Badge variant=\"default\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.recommended.actions.installed' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground line-clamp-2 mb-3\">\r\n {formatMessage({ id: definition.descKey })}\r\n </p>\r\n\r\n {/* Config info + Install */}\r\n <div className=\"flex items-center justify-between\">\r\n {hasFields ? (\r\n <span className=\"text-xs text-muted-foreground flex items-center gap-1\">\r\n <Key className=\"w-3 h-3\" />\r\n {definition.fields.length} {formatMessage({ id: 'mcp.configRequired' })}\r\n </span>\r\n ) : (\r\n <span className=\"text-xs text-green-600 dark:text-green-400 flex items-center gap-1\">\r\n <Zap className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.noConfigNeeded' })}\r\n </span>\r\n )}\r\n <Button\r\n variant={isInstalled ? 'outline' : 'default'}\r\n size=\"sm\"\r\n onClick={() => onInstall(definition)}\r\n >\r\n {isInstalled ? (\r\n <>\r\n <Settings className=\"w-3.5 h-3.5 mr-1\" />\r\n {formatMessage({ id: 'mcp.reconfigure' })}\r\n </>\r\n ) : (\r\n <>\r\n <Download className=\"w-3.5 h-3.5 mr-1\" />\r\n {formatMessage({ id: 'mcp.recommended.actions.install' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * Recommended MCP servers section with wizard-based install\r\n */\r\nexport function RecommendedMcpSection({\r\n onInstallComplete,\r\n}: RecommendedMcpSectionProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const [wizardOpen, setWizardOpen] = useState(false);\r\n const [selectedDefinition, setSelectedDefinition] = useState<RecommendedMcpDefinition | null>(null);\r\n const [installedServerIds, setInstalledServerIds] = useState<Set<string>>(new Set());\r\n\r\n // Check which servers are already installed\r\n const checkInstalledServers = async () => {\r\n try {\r\n const data = await fetchMcpConfig();\r\n const installedIds = new Set<string>();\r\n\r\n const globalServers = data.globalServers || {};\r\n const userServers = data.userServers || {};\r\n for (const name of Object.keys(globalServers)) installedIds.add(name);\r\n for (const name of Object.keys(userServers)) installedIds.add(name);\r\n\r\n const projects = data.projects || {};\r\n for (const proj of Object.values(projects)) {\r\n const servers = (proj as any).mcpServers || {};\r\n for (const name of Object.keys(servers)) installedIds.add(name);\r\n }\r\n\r\n if ((data as any).codex?.servers) {\r\n for (const name of Object.keys((data as any).codex.servers)) installedIds.add(name);\r\n }\r\n\r\n setInstalledServerIds(installedIds);\r\n } catch {\r\n // Ignore errors during check\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n checkInstalledServers();\r\n }, []);\r\n\r\n // Handle install click - open wizard\r\n const handleInstallClick = (definition: RecommendedMcpDefinition) => {\r\n setSelectedDefinition(definition);\r\n setWizardOpen(true);\r\n };\r\n\r\n // Handle wizard close\r\n const handleWizardClose = () => {\r\n setWizardOpen(false);\r\n setSelectedDefinition(null);\r\n };\r\n\r\n // Handle install complete\r\n const handleInstallComplete = () => {\r\n checkInstalledServers();\r\n onInstallComplete?.();\r\n };\r\n\r\n return (\r\n <>\r\n <section className=\"space-y-4\">\r\n {/* Header */}\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'mcp.recommended.title' })}\r\n </h2>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.recommended.description' })}\r\n </p>\r\n </div>\r\n\r\n {/* Server Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-3\">\r\n {RECOMMENDED_MCP_DEFINITIONS.map((definition) => (\r\n <RecommendedServerCard\r\n key={definition.id}\r\n definition={definition}\r\n isInstalled={installedServerIds.has(definition.id)}\r\n onInstall={handleInstallClick}\r\n />\r\n ))}\r\n </div>\r\n </section>\r\n\r\n {/* Wizard Dialog */}\r\n <RecommendedMcpWizard\r\n open={wizardOpen}\r\n onClose={handleWizardClose}\r\n mcpDefinition={selectedDefinition}\r\n onInstallComplete={handleInstallComplete}\r\n />\r\n </>\r\n );\r\n}\r\n\r\nexport default RecommendedMcpSection;\r\n","// ========================================\r\n// Windows Compatibility Warning Component\r\n// ========================================\r\n// Windows-specific warning banner with command detection and auto-fix functionality\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { AlertTriangle, Download, CheckCircle, XCircle, Loader2 } from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface WindowsCompatibilityWarningProps {\r\n /** Optional: Project path to check commands against */\r\n projectPath?: string;\r\n /** Optional: Callback when compatibility check completes */\r\n onComplete?: (result: CompatibilityCheckResult) => void;\r\n}\r\n\r\nexport interface CommandDetectionResult {\r\n command: string;\r\n available: boolean;\r\n installUrl?: string;\r\n}\r\n\r\nexport interface CompatibilityCheckResult {\r\n isWindows: boolean;\r\n missingCommands: string[];\r\n commands: CommandDetectionResult[];\r\n canAutoFix: boolean;\r\n}\r\n\r\n// ========== Constants ==========\r\n\r\nconst COMMON_COMMANDS = [\r\n { name: 'npm', installUrl: 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm' },\r\n { name: 'node', installUrl: 'https://nodejs.org/' },\r\n { name: 'python', installUrl: 'https://www.python.org/downloads/' },\r\n { name: 'npx', installUrl: 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm' },\r\n];\r\n\r\n// Helper function to check if a command can be auto-fixed\r\nfunction canAutoFixCommand(command: string): boolean {\r\n return COMMON_COMMANDS.some((cmd) => cmd.name === command);\r\n}\r\n\r\n// ========== API Functions ==========\r\n\r\nasync function detectWindowsCommands(projectPath?: string): Promise<CommandDetectionResult[]> {\r\n const response = await fetch('/api/mcp/detect-commands', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ projectPath }),\r\n });\r\n if (!response.ok) {\r\n throw new Error('Failed to detect commands');\r\n }\r\n return response.json();\r\n}\r\n\r\nasync function applyWindowsAutoFix(projectPath?: string): Promise<{ success: boolean; message: string }> {\r\n const response = await fetch('/api/mcp/apply-windows-fix', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ projectPath }),\r\n });\r\n if (!response.ok) {\r\n throw new Error('Failed to apply Windows fix');\r\n }\r\n return response.json();\r\n}\r\n\r\n// ========== Sub-Components ==========\r\n\r\ninterface CommandDetectionListProps {\r\n commands: CommandDetectionResult[];\r\n}\r\n\r\nfunction CommandDetectionList({ commands }: CommandDetectionListProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"space-y-2 mt-3\">\r\n {commands.map((cmd) => (\r\n <div\r\n key={cmd.command}\r\n className={cn(\r\n 'flex items-center gap-2 text-sm p-2 rounded-md',\r\n cmd.available ? 'bg-success/10' : 'bg-destructive/10'\r\n )}\r\n >\r\n {cmd.available ? (\r\n <CheckCircle className=\"w-4 h-4 text-success\" />\r\n ) : (\r\n <XCircle className=\"w-4 h-4 text-destructive\" />\r\n )}\r\n <code className=\"font-mono flex-1\">{cmd.command}</code>\r\n {!cmd.available && cmd.installUrl && (\r\n <a\r\n href={cmd.installUrl}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"text-xs text-primary hover:underline flex items-center gap-1\"\r\n >\r\n <Download className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.windows.install' })}\r\n </a>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function WindowsCompatibilityWarning({\r\n projectPath,\r\n onComplete,\r\n}: WindowsCompatibilityWarningProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n\r\n const [checkResult, setCheckResult] = useState<CompatibilityCheckResult | null>(null);\r\n const [isChecking, setIsChecking] = useState(false);\r\n const [dismissed, setDismissed] = useState(false);\r\n\r\n // Detect Windows platform\r\n const isWindows = typeof window !== 'undefined' && window.navigator.platform.toLowerCase().includes('win');\r\n\r\n // Mutation for auto-fix\r\n const autoFixMutation = useMutation({\r\n mutationFn: () => applyWindowsAutoFix(projectPath),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: ['mcpServers'] });\r\n if (onComplete && checkResult) {\r\n onComplete({ ...checkResult, canAutoFix: false });\r\n }\r\n },\r\n });\r\n\r\n // Check compatibility on mount (Windows only)\r\n useEffect(() => {\r\n if (!isWindows || dismissed) return;\r\n\r\n const checkCompatibility = async () => {\r\n setIsChecking(true);\r\n try {\r\n const results = await detectWindowsCommands(projectPath);\r\n const missingCommands = results.filter((r) => !r.available).map((r) => r.command);\r\n const canAutoFix = missingCommands.length > 0 && missingCommands.every(canAutoFixCommand);\r\n\r\n const result: CompatibilityCheckResult = {\r\n isWindows: true,\r\n missingCommands,\r\n commands: results,\r\n canAutoFix,\r\n };\r\n\r\n setCheckResult(result);\r\n if (onComplete) {\r\n onComplete(result);\r\n }\r\n } catch (error) {\r\n console.error('Failed to check Windows compatibility:', error);\r\n } finally {\r\n setIsChecking(false);\r\n }\r\n };\r\n\r\n checkCompatibility();\r\n }, [isWindows, dismissed, projectPath, onComplete]);\r\n\r\n // Don't render if not Windows, dismissed, or still checking without errors\r\n if (!isWindows || dismissed || (isChecking && !checkResult)) {\r\n return null;\r\n }\r\n\r\n // Don't show warning if all commands are available\r\n if (checkResult && checkResult.missingCommands.length === 0) {\r\n return null;\r\n }\r\n\r\n const handleAutoFix = async () => {\r\n autoFixMutation.mutate();\r\n };\r\n\r\n const handleDismiss = () => {\r\n setDismissed(true);\r\n };\r\n\r\n return (\r\n <div className=\"border border-warning/50 bg-warning/5 rounded-lg p-4 mb-4\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-warning flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1 space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h4 className=\"text-sm font-semibold text-foreground\">\r\n {formatMessage({ id: 'mcp.windows.title' })}\r\n </h4>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'mcp.windows.description' })}\r\n </p>\r\n </div>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-6 w-6 p-0\"\r\n onClick={handleDismiss}\r\n >\r\n ×\r\n </Button>\r\n </div>\r\n\r\n {checkResult && (\r\n <>\r\n {checkResult.missingCommands.length > 0 && (\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"warning\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.windows.missingCount' }, { count: checkResult.missingCommands.length })}\r\n </Badge>\r\n </div>\r\n )}\r\n\r\n <CommandDetectionList commands={checkResult.commands} />\r\n\r\n {checkResult.canAutoFix && (\r\n <div className=\"flex items-center gap-2 pt-2 border-t border-warning/20\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleAutoFix}\r\n disabled={autoFixMutation.isPending}\r\n className=\"text-xs\"\r\n >\r\n {autoFixMutation.isPending ? (\r\n <>\r\n <Loader2 className=\"w-3 h-3 mr-1 animate-spin\" />\r\n {formatMessage({ id: 'mcp.windows.fixing' })}\r\n </>\r\n ) : (\r\n <>\r\n <CheckCircle className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.windows.autoFix' })}\r\n </>\r\n )}\r\n </Button>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.windows.autoFixHint' })}\r\n </span>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {isChecking && (\r\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {formatMessage({ id: 'mcp.windows.checking' })}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default WindowsCompatibilityWarning;\r\n","// ========================================\r\n// Cross-CLI Sync Panel Component\r\n// ========================================\r\n// Inline panel for synchronizing MCP servers between Claude and Codex\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { ArrowRight, ArrowLeft, CheckCircle2, AlertCircle, Loader2 } from 'lucide-react';\r\nimport { Checkbox } from '@/components/ui/Checkbox';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { useMcpServers } from '@/hooks';\r\nimport { crossCliCopy, fetchCodexMcpServers, isHttpMcpServer, isStdioMcpServer } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface CrossCliSyncPanelProps {\r\n /** Callback when copy is successful */\r\n onSuccess?: (copiedCount: number, direction: 'to-codex' | 'from-codex') => void;\r\n /** Additional class name */\r\n className?: string;\r\n}\r\n\r\ninterface ServerCheckboxItem {\r\n name: string;\r\n /** Display text - command for STDIO, URL for HTTP */\r\n displayText: string;\r\n enabled: boolean;\r\n selected: boolean;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function CrossCliSyncPanel({ onSuccess, className }: CrossCliSyncPanelProps) {\r\n const { formatMessage } = useIntl();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Claude servers state\r\n const { servers: claudeServers } = useMcpServers();\r\n const [selectedClaude, setSelectedClaude] = useState<Set<string>>(new Set());\r\n\r\n // Codex servers state\r\n const [codexServers, setCodexServers] = useState<ServerCheckboxItem[]>([]);\r\n const [selectedCodex, setSelectedCodex] = useState<Set<string>>(new Set());\r\n const [isLoadingCodex, setIsLoadingCodex] = useState(false);\r\n const [codexError, setCodexError] = useState<string | null>(null);\r\n\r\n // Copy operation state\r\n const [isCopying, setIsCopying] = useState(false);\r\n const [copyResult, setCopyResult] = useState<{\r\n type: 'success' | 'partial' | null;\r\n copied: number;\r\n failed: number;\r\n }>({ type: null, copied: 0, failed: 0 });\r\n\r\n // Load Codex servers on mount\r\n useEffect(() => {\r\n const loadCodexServers = async () => {\r\n setIsLoadingCodex(true);\r\n setCodexError(null);\r\n try {\r\n const codex = await fetchCodexMcpServers();\r\n setCodexServers(\r\n (codex.servers ?? []).map((s) => ({\r\n name: s.name,\r\n displayText: isHttpMcpServer(s) ? s.url : (isStdioMcpServer(s) ? s.command : ''),\r\n enabled: s.enabled,\r\n selected: false,\r\n }))\r\n );\r\n } catch (error) {\r\n console.error('Failed to load Codex MCP servers:', error);\r\n setCodexError(formatMessage({ id: 'mcp.sync.codexLoadError' }));\r\n setCodexServers([]);\r\n } finally {\r\n setIsLoadingCodex(false);\r\n }\r\n };\r\n\r\n void loadCodexServers();\r\n }, [formatMessage]);\r\n\r\n // Claude server handlers\r\n const toggleClaudeServer = (name: string) => {\r\n setSelectedClaude((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(name)) {\r\n next.delete(name);\r\n } else {\r\n next.add(name);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const selectAllClaude = () => {\r\n setSelectedClaude(new Set(claudeServers.map((s) => s.name)));\r\n };\r\n\r\n const clearAllClaude = () => {\r\n setSelectedClaude(new Set());\r\n };\r\n\r\n // Codex server handlers\r\n const toggleCodexServer = (name: string) => {\r\n setSelectedCodex((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(name)) {\r\n next.delete(name);\r\n } else {\r\n next.add(name);\r\n }\r\n return next;\r\n });\r\n setCodexServers((prev) =>\r\n prev.map((s) => (s.name === name ? { ...s, selected: !s.selected } : s))\r\n );\r\n };\r\n\r\n const selectAllCodex = () => {\r\n const allNames = codexServers.map((s) => s.name);\r\n setSelectedCodex(new Set(allNames));\r\n setCodexServers((prev) => prev.map((s) => ({ ...s, selected: true })));\r\n };\r\n\r\n const clearAllCodex = () => {\r\n setSelectedCodex(new Set());\r\n setCodexServers((prev) => prev.map((s) => ({ ...s, selected: false })));\r\n };\r\n\r\n // Copy handlers\r\n const handleCopyToCodex = async () => {\r\n if (selectedClaude.size === 0) return;\r\n\r\n setIsCopying(true);\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n\r\n try {\r\n const result = await crossCliCopy({\r\n source: 'claude',\r\n target: 'codex',\r\n serverNames: Array.from(selectedClaude),\r\n projectPath: projectPath ?? undefined,\r\n });\r\n\r\n if (result.success) {\r\n const failedCount = result.failed.length;\r\n const copiedCount = result.copied.length;\r\n\r\n setCopyResult({\r\n type: failedCount > 0 ? 'partial' : 'success',\r\n copied: copiedCount,\r\n failed: failedCount,\r\n });\r\n\r\n onSuccess?.(copiedCount, 'to-codex');\r\n\r\n // Clear selection after successful copy\r\n setSelectedClaude(new Set());\r\n\r\n // Auto-hide result after 3 seconds\r\n setTimeout(() => {\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n }, 3000);\r\n }\r\n } catch (error) {\r\n console.error('Failed to copy to Codex:', error);\r\n setCopyResult({ type: 'partial', copied: 0, failed: selectedClaude.size });\r\n } finally {\r\n setIsCopying(false);\r\n }\r\n };\r\n\r\n const handleCopyFromCodex = async () => {\r\n if (selectedCodex.size === 0 || !projectPath) {\r\n return;\r\n }\r\n\r\n setIsCopying(true);\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n\r\n try {\r\n const result = await crossCliCopy({\r\n source: 'codex',\r\n target: 'claude',\r\n serverNames: Array.from(selectedCodex),\r\n projectPath,\r\n });\r\n\r\n if (result.success) {\r\n const failedCount = result.failed.length;\r\n const copiedCount = result.copied.length;\r\n\r\n setCopyResult({\r\n type: failedCount > 0 ? 'partial' : 'success',\r\n copied: copiedCount,\r\n failed: failedCount,\r\n });\r\n\r\n onSuccess?.(copiedCount, 'from-codex');\r\n\r\n // Clear selection after successful copy\r\n setSelectedCodex(new Set());\r\n setCodexServers((prev) => prev.map((s) => ({ ...s, selected: false })));\r\n\r\n // Auto-hide result after 3 seconds\r\n setTimeout(() => {\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n }, 3000);\r\n }\r\n } catch (error) {\r\n console.error('Failed to copy from Codex:', error);\r\n setCopyResult({ type: 'partial', copied: 0, failed: selectedCodex.size });\r\n } finally {\r\n setIsCopying(false);\r\n }\r\n };\r\n\r\n // Computed values\r\n const claudeTotal = claudeServers.length;\r\n const claudeSelected = selectedClaude.size;\r\n const codexTotal = codexServers.length;\r\n const codexSelected = selectedCodex.size;\r\n\r\n return (\r\n <div className={cn('space-y-4', className)}>\r\n {/* Header */}\r\n <div className=\"text-center\">\r\n <h3 className=\"text-base font-semibold text-foreground\">\r\n {formatMessage({ id: 'mcp.sync.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'mcp.sync.description' })}\r\n </p>\r\n </div>\r\n\r\n {/* Result Message */}\r\n {copyResult.type !== null && (\r\n <div\r\n className={cn(\r\n 'flex items-center gap-2 p-3 rounded-lg border',\r\n copyResult.type === 'success'\r\n ? 'bg-success/10 border-success/30 text-success'\r\n : 'bg-warning/10 border-warning/30 text-warning'\r\n )}\r\n >\r\n {copyResult.type === 'success' ? (\r\n <CheckCircle2 className=\"w-4 h-4 flex-shrink-0\" />\r\n ) : (\r\n <AlertCircle className=\"w-4 h-4 flex-shrink-0\" />\r\n )}\r\n <span className=\"text-sm\">\r\n {copyResult.type === 'success'\r\n ? formatMessage(\r\n { id: 'mcp.sync.copySuccess' },\r\n { count: copyResult.copied }\r\n )\r\n : formatMessage(\r\n { id: 'mcp.sync.copyPartial' },\r\n { copied: copyResult.copied, failed: copyResult.failed }\r\n )}\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Two-column layout */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {/* Claude Column */}\r\n <div className=\"border border-border rounded-lg overflow-hidden\">\r\n {/* Column Header */}\r\n <div className=\"bg-muted/50 px-4 py-3 border-b border-border\">\r\n <div className=\"flex items-center justify-between\">\r\n <h4 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.sync.claudeColumn' })}\r\n </h4>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage(\r\n { id: 'mcp.sync.selectedCount' },\r\n { count: claudeSelected, total: claudeTotal }\r\n )}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Claude Server List */}\r\n <div className=\"p-2 max-h-64 overflow-y-auto\">\r\n {claudeTotal === 0 ? (\r\n <div className=\"py-8 text-center text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.sync.noServers' })}\r\n </div>\r\n ) : (\r\n <div className=\"space-y-1\">\r\n {claudeServers.map((server) => (\r\n <div\r\n key={server.name}\r\n className={cn(\r\n 'flex items-start gap-2 p-2 rounded cursor-pointer transition-colors',\r\n selectedClaude.has(server.name)\r\n ? 'bg-primary/10'\r\n : 'hover:bg-muted/50'\r\n )}\r\n onClick={() => toggleClaudeServer(server.name)}\r\n >\r\n <Checkbox\r\n id={`claude-${server.name}`}\r\n checked={selectedClaude.has(server.name)}\r\n onChange={() => toggleClaudeServer(server.name)}\r\n className=\"w-4 h-4 mt-0.5\"\r\n />\r\n <label\r\n htmlFor={`claude-${server.name}`}\r\n className=\"flex-1 min-w-0 cursor-pointer\"\r\n >\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {server.name}\r\n </span>\r\n {server.enabled && (\r\n <Badge variant=\"success\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </div>\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\n {isHttpMcpServer(server)\n ? server.url\n : (isStdioMcpServer(server) ? server.command : '')}\n </p>\n </label>\n </div>\n ))}\n </div>\n )}\r\n </div>\r\n\r\n {/* Claude Footer Actions */}\r\n {claudeTotal > 0 && (\r\n <div className=\"px-2 py-2 bg-muted/30 border-t border-border flex gap-1\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={selectAllClaude}\r\n className=\"flex-1 text-xs\"\r\n >\r\n {formatMessage({ id: 'mcp.sync.selectAll' })}\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={clearAllClaude}\r\n className=\"flex-1 text-xs\"\r\n disabled={claudeSelected === 0}\r\n >\r\n {formatMessage({ id: 'mcp.sync.clearAll' })}\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Codex Column */}\r\n <div className=\"border border-border rounded-lg overflow-hidden\">\r\n {/* Column Header */}\r\n <div className=\"bg-muted/50 px-4 py-3 border-b border-border\">\r\n <div className=\"flex items-center justify-between\">\r\n <h4 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.sync.codexColumn' })}\r\n </h4>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage(\r\n { id: 'mcp.sync.selectedCount' },\r\n { count: codexSelected, total: codexTotal }\r\n )}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Codex Server List */}\r\n <div className=\"p-2 max-h-64 overflow-y-auto\">\r\n {isLoadingCodex ? (\r\n <div className=\"py-8 flex items-center justify-center\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-muted-foreground\" />\r\n </div>\r\n ) : codexError ? (\r\n <div className=\"py-8 text-center text-sm text-destructive\">\r\n {codexError}\r\n </div>\r\n ) : codexTotal === 0 ? (\r\n <div className=\"py-8 text-center text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.sync.noServers' })}\r\n </div>\r\n ) : (\r\n <div className=\"space-y-1\">\r\n {codexServers.map((server) => (\r\n <div\r\n key={server.name}\r\n className={cn(\r\n 'flex items-start gap-2 p-2 rounded cursor-pointer transition-colors',\r\n server.selected\r\n ? 'bg-primary/10'\r\n : 'hover:bg-muted/50'\r\n )}\r\n onClick={() => toggleCodexServer(server.name)}\r\n >\r\n <Checkbox\r\n id={`codex-${server.name}`}\r\n checked={server.selected}\r\n onChange={() => toggleCodexServer(server.name)}\r\n className=\"w-4 h-4 mt-0.5\"\r\n />\r\n <label\r\n htmlFor={`codex-${server.name}`}\r\n className=\"flex-1 min-w-0 cursor-pointer\"\r\n >\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {server.name}\r\n </span>\r\n {server.enabled && (\r\n <Badge variant=\"success\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </div>\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\n {server.displayText}\n </p>\n </label>\n </div>\n ))}\n </div>\n )}\r\n </div>\r\n\r\n {/* Codex Footer Actions */}\r\n {codexTotal > 0 && (\r\n <div className=\"px-2 py-2 bg-muted/30 border-t border-border flex gap-1\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={selectAllCodex}\r\n className=\"flex-1 text-xs\"\r\n >\r\n {formatMessage({ id: 'mcp.sync.selectAll' })}\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={clearAllCodex}\r\n className=\"flex-1 text-xs\"\r\n disabled={codexSelected === 0}\r\n >\r\n {formatMessage({ id: 'mcp.sync.clearAll' })}\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Copy Buttons */}\r\n <div className=\"flex items-center justify-center gap-3\">\r\n <Button\r\n onClick={handleCopyToCodex}\r\n disabled={claudeSelected === 0 || isCopying}\r\n variant=\"default\"\r\n className=\"min-w-40\"\r\n >\r\n {isCopying ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\r\n {formatMessage({ id: 'mcp.sync.syncInProgress' })}\r\n </>\r\n ) : (\r\n <>\r\n <ArrowRight className=\"w-4 h-4 mr-2\" />\r\n {formatMessage(\r\n { id: 'mcp.sync.copyToCodex' },\r\n { count: claudeSelected }\r\n )}\r\n </>\r\n )}\r\n </Button>\r\n\r\n <Button\r\n onClick={handleCopyFromCodex}\r\n disabled={codexSelected === 0 || isCopying || !projectPath}\r\n variant=\"default\"\r\n className=\"min-w-40\"\r\n >\r\n {isCopying ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\r\n {formatMessage({ id: 'mcp.sync.syncInProgress' })}\r\n </>\r\n ) : (\r\n <>\r\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\r\n {formatMessage(\r\n { id: 'mcp.sync.copyFromCodex' },\r\n { count: codexSelected }\r\n )}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CrossCliSyncPanel;\r\n","// ========================================\r\n// All Projects Table Component\r\n// ========================================\r\n// Table component displaying all recent projects with MCP server statistics\r\n\r\nimport { useState, useEffect, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Folder, Clock, Database, ExternalLink } from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { useProjectOperations } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport { formatDistanceToNow } from 'date-fns';\r\nimport { fetchOtherProjectsServers } from '@/lib/api';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface ProjectServerStats {\r\n name: string;\r\n path: string;\r\n serverCount: number;\r\n enabledCount: number;\r\n lastModified?: string;\r\n isCurrent?: boolean;\r\n}\r\n\r\nexport interface AllProjectsTableProps {\r\n /** Callback when a project is clicked */\r\n onProjectClick?: (projectPath: string) => void;\r\n /** Callback when open in new window is clicked */\r\n onOpenNewWindow?: (projectPath: string) => void;\r\n /** Additional class name */\r\n className?: string;\r\n /** Maximum number of projects to display */\r\n maxProjects?: number;\r\n /** Project paths to display (if not provided, fetches from useProjectOperations) */\r\n projectPaths?: string[];\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function AllProjectsTable({\r\n onProjectClick,\r\n onOpenNewWindow,\r\n className,\r\n maxProjects,\r\n projectPaths: propProjectPaths,\r\n}: AllProjectsTableProps) {\r\n const { formatMessage } = useIntl();\r\n const [sortField, setSortField] = useState<'name' | 'serverCount' | 'lastModified'>('lastModified');\r\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');\r\n const [projectStats, setProjectStats] = useState<ProjectServerStats[]>([]);\r\n const [isStatsLoading, setIsStatsLoading] = useState(false);\r\n\r\n const { projects, currentProject, isLoading } = useProjectOperations();\r\n\r\n // Use provided project paths or default to all projects\r\n // Memoize to stabilize the array reference and prevent useEffect infinite loops\r\n const displayProjects = useMemo(() => {\r\n const target = propProjectPaths ?? projects;\r\n return maxProjects ? target.slice(0, maxProjects) : target;\r\n }, [propProjectPaths, projects, maxProjects]);\r\n\r\n // Fetch real project server stats on mount\r\n useEffect(() => {\r\n const fetchStats = async () => {\r\n if (displayProjects.length === 0) {\r\n setProjectStats([]);\r\n return;\r\n }\r\n\r\n setIsStatsLoading(true);\r\n try {\r\n const response = await fetchOtherProjectsServers(displayProjects);\r\n const stats: ProjectServerStats[] = displayProjects.map((path) => {\r\n const isCurrent = path === currentProject;\r\n const name = path.split(/[/\\\\]/).filter(Boolean).pop() || path;\r\n const servers = response.servers[path] ?? [];\r\n\r\n return {\r\n name,\r\n path,\r\n serverCount: servers.length,\r\n enabledCount: servers.filter((s) => s.enabled).length,\r\n lastModified: undefined, // Backend doesn't provide this yet\r\n isCurrent,\r\n };\r\n });\r\n setProjectStats(stats);\r\n } catch (error) {\r\n console.error('Failed to fetch project server stats:', error);\r\n // Fallback to empty stats on error\r\n setProjectStats(\r\n displayProjects.map((path) => ({\r\n name: path.split(/[/\\\\]/).filter(Boolean).pop() || path,\r\n path,\r\n serverCount: 0,\r\n enabledCount: 0,\r\n isCurrent: path === currentProject,\r\n }))\r\n );\r\n } finally {\r\n setIsStatsLoading(false);\r\n }\r\n };\r\n\r\n void fetchStats();\r\n }, [displayProjects, currentProject]);\r\n\r\n // Sort projects\r\n const sortedProjects = [...projectStats].sort((a, b) => {\r\n let comparison = 0;\r\n\r\n switch (sortField) {\r\n case 'name':\r\n comparison = a.name.localeCompare(b.name);\r\n break;\r\n case 'serverCount':\r\n comparison = a.serverCount - b.serverCount;\r\n break;\r\n case 'lastModified':\r\n comparison = a.lastModified && b.lastModified\r\n ? new Date(a.lastModified).getTime() - new Date(b.lastModified).getTime()\r\n : 0;\r\n break;\r\n }\r\n\r\n return sortDirection === 'asc' ? comparison : -comparison;\r\n });\r\n\r\n // Handle sort\r\n const handleSort = (field: typeof sortField) => {\r\n if (sortField === field) {\r\n setSortDirection((prev) => (prev === 'asc' ? 'desc' : 'asc'));\r\n } else {\r\n setSortField(field);\r\n setSortDirection('desc');\r\n }\r\n };\r\n\r\n // Handle project click\r\n const handleProjectClick = (projectPath: string) => {\r\n onProjectClick?.(projectPath);\r\n };\r\n\r\n // Handle open in new window\r\n const handleOpenNewWindow = (e: React.MouseEvent, projectPath: string) => {\r\n e.stopPropagation();\r\n onOpenNewWindow?.(projectPath);\r\n };\r\n\r\n if (isLoading || isStatsLoading) {\r\n return (\r\n <Card className={cn('p-8', className)}>\r\n <div className=\"flex items-center justify-center\">\r\n <div className=\"animate-spin text-muted-foreground\">-</div>\r\n <span className=\"ml-2 text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'common.actions.loading' })}\r\n </span>\r\n </div>\r\n </Card>\r\n );\r\n }\r\n\r\n if (sortedProjects.length === 0) {\r\n return (\r\n <Card className={cn('p-8', className)}>\r\n <div className=\"text-center\">\r\n <Folder className=\"w-12 h-12 mx-auto text-muted-foreground/50 mb-3\" />\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.allProjects.empty' })}\r\n </p>\r\n </div>\r\n </Card>\r\n );\r\n }\r\n\r\n return (\r\n <Card className={cn('overflow-hidden', className)}>\r\n {/* Table Header */}\r\n <div className=\"grid grid-cols-12 gap-2 px-4 py-3 bg-muted/50 border-b border-border text-xs font-medium text-muted-foreground uppercase\">\r\n <div className=\"col-span-4\">\r\n <button\r\n onClick={() => handleSort('name')}\r\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\r\n >\r\n {formatMessage({ id: 'mcp.allProjects.name' })}\r\n {sortField === 'name' && (\r\n <span className=\"text-foreground\">{sortDirection === 'asc' ? '↑' : '↓'}</span>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"col-span-3\">\r\n <button\r\n onClick={() => handleSort('serverCount')}\r\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\r\n >\r\n {formatMessage({ id: 'mcp.allProjects.servers' })}\r\n {sortField === 'serverCount' && (\r\n <span className=\"text-foreground\">{sortDirection === 'asc' ? '↑' : '↓'}</span>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"col-span-3\">\r\n <button\r\n onClick={() => handleSort('lastModified')}\r\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\r\n >\r\n {formatMessage({ id: 'mcp.allProjects.lastModified' })}\r\n {sortField === 'lastModified' && (\r\n <span className=\"text-foreground\">{sortDirection === 'asc' ? '↑' : '↓'}</span>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"col-span-2 text-right\">\r\n {formatMessage({ id: 'mcp.allProjects.actions' })}\r\n </div>\r\n </div>\r\n\r\n {/* Table Rows */}\r\n <div className=\"divide-y divide-border\">\r\n {sortedProjects.map((project) => (\r\n <div\r\n key={project.path}\r\n onClick={() => handleProjectClick(project.path)}\r\n className={cn(\r\n 'grid grid-cols-12 gap-2 px-4 py-3 items-center transition-colors cursor-pointer hover:bg-muted/50',\r\n project.isCurrent && 'bg-primary/5 hover:bg-primary/10'\r\n )}\r\n >\r\n {/* Project Name */}\r\n <div className=\"col-span-4 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <Folder className=\"w-4 h-4 text-muted-foreground flex-shrink-0\" />\r\n <div className=\"min-w-0 flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {project.name}\r\n </span>\r\n {project.isCurrent && (\r\n <Badge variant=\"default\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.allProjects.current' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\r\n {project.path}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Server Count */}\r\n <div className=\"col-span-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Database className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm text-foreground\">\r\n {project.serverCount} {formatMessage({ id: 'mcp.allProjects.servers' })}\r\n </span>\r\n <Badge\r\n variant=\"outline\"\r\n className={cn(\r\n 'text-xs',\r\n project.enabledCount > 0 ? 'text-success border-success/30' : 'text-muted-foreground'\r\n )}\r\n >\r\n {project.enabledCount} {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Last Modified */}\r\n <div className=\"col-span-3\">\r\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\r\n <Clock className=\"w-4 h-4\" />\r\n <span>\r\n {project.lastModified\r\n ? formatDistanceToNow(new Date(project.lastModified), { addSuffix: true })\r\n : '-'}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Actions */}\r\n <div className=\"col-span-2 flex justify-end gap-1\">\r\n <button\r\n onClick={(e) => handleOpenNewWindow(e, project.path)}\r\n className=\"p-1.5 rounded hover:bg-muted transition-colors\"\r\n title={formatMessage({ id: 'mcp.allProjects.openNewWindow' })}\r\n >\r\n <ExternalLink className=\"w-4 h-4 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"px-4 py-2 bg-muted/30 border-t border-border text-xs text-muted-foreground\">\r\n {formatMessage(\r\n { id: 'mcp.allProjects.summary' },\r\n { count: sortedProjects.length }\r\n )}\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\nexport default AllProjectsTable;\r\n","// ========================================\r\n// Other Projects Section Component\r\n// ========================================\r\n// Section for discovering and importing servers from other projects\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { FolderOpen, Copy, ChevronRight, RefreshCw } from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport { useProjectOperations, useMcpServerMutations } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport type { McpServer } from '@/lib/api';\r\nimport { isHttpMcpServer, isStdioMcpServer } from '@/lib/api';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Server from another project\r\n * Contains base server fields plus project metadata\r\n */\r\nexport interface OtherProjectServer {\r\n name: string;\r\n enabled: boolean;\r\n /** Display text - command for STDIO, URL for HTTP */\r\n displayText: string;\r\n /** Transport type */\r\n transport: 'stdio' | 'http';\r\n /** Project path */\r\n projectPath: string;\r\n /** Project name */\r\n projectName: string;\r\n /** Original server data */\r\n originalServer: McpServer;\r\n}\r\n\r\nexport interface OtherProjectsSectionProps {\r\n /** Callback when server is successfully imported */\r\n onImportSuccess?: (serverName: string, sourceProject: string) => void;\r\n /** Additional class name */\r\n className?: string;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function OtherProjectsSection({\r\n onImportSuccess,\r\n className,\r\n}: OtherProjectsSectionProps) {\r\n const { formatMessage } = useIntl();\r\n const [selectedProjectPath, setSelectedProjectPath] = useState<string | null>(null);\r\n const [otherServers, setOtherServers] = useState<OtherProjectServer[]>([]);\r\n const [isFetchingServers, setIsFetchingServers] = useState(false);\r\n\r\n const { projects, currentProject, fetchOtherServers, isFetchingServers: isGlobalFetching } =\r\n useProjectOperations();\r\n const { createServer, isCreating } = useMcpServerMutations();\r\n\r\n // Get available projects (excluding current)\r\n const availableProjects = projects.filter((p) => p !== currentProject);\r\n\r\n // Handle project selection\r\n const handleProjectSelect = async (projectPath: string) => {\r\n setSelectedProjectPath(projectPath);\r\n setIsFetchingServers(true);\r\n\r\n try {\r\n const response = await fetchOtherServers([projectPath]);\r\n const servers: OtherProjectServer[] = [];\r\n\r\n for (const [path, serverList] of Object.entries(response.servers)) {\r\n const projectName = path.split(/[/\\\\]/).filter(Boolean).pop() || path;\r\n for (const server of (serverList as McpServer[])) {\r\n servers.push({\r\n name: server.name,\r\n enabled: server.enabled,\r\n displayText: isHttpMcpServer(server)\r\n ? server.url\r\n : (isStdioMcpServer(server) ? server.command : ''),\r\n transport: server.transport,\r\n projectPath: path,\r\n projectName,\r\n originalServer: server,\r\n });\r\n }\r\n }\r\n\r\n setOtherServers(servers);\r\n } catch (error) {\r\n console.error('Failed to fetch other projects servers:', error);\r\n setOtherServers([]);\r\n } finally {\r\n setIsFetchingServers(false);\r\n }\r\n };\r\n\r\n // Handle server import\r\n const handleImportServer = async (server: OtherProjectServer) => {\r\n try {\r\n // Generate a unique name by combining project name and server name\r\n const uniqueName = `${server.projectName}-${server.name}`.toLowerCase().replace(/\\s+/g, '-');\r\n\r\n // Create server based on transport type\r\n const serverToCreate: McpServer = {\r\n ...server.originalServer,\r\n name: uniqueName,\r\n scope: 'project',\r\n };\r\n\r\n await createServer(serverToCreate);\r\n\r\n onImportSuccess?.(uniqueName, server.projectPath);\r\n } catch (error) {\r\n console.error('Failed to import server:', error);\r\n }\r\n };\r\n\r\n const isLoading = isFetchingServers || isGlobalFetching || isCreating;\r\n const selectedProjectName = selectedProjectPath\r\n ? selectedProjectPath.split(/[/\\\\]/).filter(Boolean).pop()\r\n : null;\r\n\r\n return (\r\n <Card className={cn('p-4', className)}>\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <FolderOpen className=\"w-5 h-5 text-primary\" />\r\n <h3 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.otherProjects.title' })}\r\n </h3>\r\n </div>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => selectedProjectPath && handleProjectSelect(selectedProjectPath)}\r\n disabled={!selectedProjectPath || isLoading}\r\n className=\"h-8\"\r\n >\r\n <RefreshCw className={cn('w-4 h-4', isLoading && 'animate-spin')} />\r\n </Button>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-xs text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'mcp.otherProjects.description' })}\r\n </p>\r\n\r\n {/* Project Selector */}\r\n <div className=\"mb-4\">\r\n <label className=\"text-sm font-medium text-foreground mb-2 block\">\r\n {formatMessage({ id: 'mcp.otherProjects.selectProject' })}\r\n </label>\r\n <Select value={selectedProjectPath ?? ''} onValueChange={handleProjectSelect}>\r\n <SelectTrigger className=\"w-full\">\r\n <SelectValue\r\n placeholder={formatMessage({ id: 'mcp.otherProjects.selectProjectPlaceholder' })}\r\n />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {availableProjects.length === 0 ? (\r\n <div className=\"p-2 text-sm text-muted-foreground text-center\">\r\n {formatMessage({ id: 'mcp.otherProjects.noProjects' })}\r\n </div>\r\n ) : (\r\n availableProjects.map((path) => {\r\n const name = path.split(/[/\\\\]/).filter(Boolean).pop() || path;\r\n return (\r\n <SelectItem key={path} value={path}>\r\n <div className=\"flex items-center gap-2\">\r\n <FolderOpen className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"truncate\">{name}</span>\r\n </div>\r\n </SelectItem>\r\n );\r\n })\r\n )}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Servers List */}\r\n {selectedProjectPath && (\r\n <div className=\"space-y-2\">\r\n {isFetchingServers ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <div className=\"animate-spin text-muted-foreground\">-</div>\r\n <span className=\"ml-2 text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'common.actions.loading' })}\r\n </span>\r\n </div>\r\n ) : otherServers.length === 0 ? (\r\n <div className=\"p-4 text-center text-sm text-muted-foreground border border-dashed rounded-lg\">\r\n {formatMessage(\r\n { id: 'mcp.otherProjects.noServers' },\r\n { project: selectedProjectName }\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-60 overflow-y-auto\">\r\n {otherServers.map((server) => (\r\n <div\r\n key={`${server.projectPath}-${server.name}`}\r\n className=\"flex items-center gap-3 p-3 rounded-lg bg-muted/30 hover:bg-muted/50 transition-colors\"\r\n >\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {server.name}\r\n </span>\r\n {server.enabled && (\r\n <Badge variant=\"success\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\r\n {server.displayText}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground truncate\">\r\n <span className=\"font-medium\">{server.projectName}</span>\r\n <ChevronRight className=\"inline w-3 h-3 mx-1\" />\r\n <span className=\"font-mono\">{server.projectPath}</span>\r\n </p>\r\n </div>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => handleImportServer(server)}\r\n disabled={isCreating}\r\n className=\"flex-shrink-0\"\r\n >\r\n <Copy className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.otherProjects.import' })}\r\n </Button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Hint */}\r\n {selectedProjectPath && otherServers.length > 0 && (\r\n <p className=\"text-xs text-muted-foreground mt-3\">\r\n {formatMessage({ id: 'mcp.otherProjects.hint' })}\r\n </p>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\nexport default OtherProjectsSection;\r\n","// ========================================\n// MCP Manager Page\n// ========================================\n// Manage MCP servers (Model Context Protocol) with tabbed interface\n// Supports Templates, Servers, and Cross-CLI tabs\n\nimport { useState, useMemo } from 'react';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport {\n Server,\n Plus,\n Search,\n RefreshCw,\n Globe,\n Folder,\n Power,\n PowerOff,\n Edit,\n Trash2,\n ChevronDown,\n ChevronUp,\n BookmarkPlus,\n AlertTriangle,\n Link,\n Eye,\n EyeOff,\n} from 'lucide-react';\nimport { Card } from '@/components/ui/Card';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Badge } from '@/components/ui/Badge';\nimport { McpServerDialog } from '@/components/mcp/McpServerDialog';\nimport { CliModeToggle, type CliMode } from '@/components/mcp/CliModeToggle';\nimport { CodexMcpEditableCard } from '@/components/mcp/CodexMcpEditableCard';\nimport { CcwToolsMcpCard } from '@/components/mcp/CcwToolsMcpCard';\nimport { McpTemplatesSection, TemplateSaveDialog } from '@/components/mcp/McpTemplatesSection';\nimport { RecommendedMcpSection } from '@/components/mcp/RecommendedMcpSection';\nimport { WindowsCompatibilityWarning } from '@/components/mcp/WindowsCompatibilityWarning';\nimport { CrossCliSyncPanel } from '@/components/mcp/CrossCliSyncPanel';\nimport { AllProjectsTable } from '@/components/mcp/AllProjectsTable';\nimport { OtherProjectsSection } from '@/components/mcp/OtherProjectsSection';\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\nimport { useMcpServers, useMcpServerMutations, useNotifications } from '@/hooks';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport {\n fetchCodexMcpServers,\n fetchCcwMcpConfig,\n fetchCcwMcpConfigForCodex,\n updateCcwConfig,\n updateCcwConfigForCodex,\n installCcwMcp,\n uninstallCcwMcpFromScope,\n codexRemoveServer,\n codexToggleServer,\n saveMcpTemplate,\n type McpServer,\n type McpServerConflict,\n type CcwMcpConfig,\n isHttpMcpServer,\n isStdioMcpServer,\n} from '@/lib/api';\nimport { cn } from '@/lib/utils';\n\n// ========== MCP Server Card Component ==========\n\ninterface McpServerCardProps {\n server: McpServer;\n isExpanded: boolean;\n onToggleExpand: () => void;\n onToggle: (serverName: string, enabled: boolean) => void;\n onEdit: (server: McpServer) => void;\n onDelete: (server: McpServer) => void;\n onSaveAsTemplate: (server: McpServer) => void;\n conflictInfo?: McpServerConflict;\n}\n\n/**\n * Mask a header value for display (show first 4 chars + ***)\n */\nfunction maskHeaderValue(value: string): string {\n if (!value || value.length <= 4) return '****';\n return value.substring(0, 4) + '****';\n}\n\nfunction McpServerCard({ server, isExpanded, onToggleExpand, onToggle, onEdit, onDelete, onSaveAsTemplate, conflictInfo }: McpServerCardProps) {\n const { formatMessage } = useIntl();\n const [showHeaderValues, setShowHeaderValues] = useState<Record<string, boolean>>({});\n\n const isHttp = isHttpMcpServer(server);\n const isStdio = isStdioMcpServer(server);\n\n // Get display text for server summary line\n const getServerSummary = () => {\n if (isHttp) {\n return server.url;\n }\n return `${server.command} ${server.args?.join(' ') || ''}`.trim();\n };\n\n // Get all headers for HTTP server (combine Claude + Codex formats)\n const getHttpHeaders = (): Array<{ name: string; value: string; isEnvVar?: boolean }> => {\n if (!isHttp) return [];\n\n const headers: Array<{ name: string; value: string; isEnvVar?: boolean }> = [];\n\n // Claude format: headers object\n if (server.headers) {\n Object.entries(server.headers).forEach(([name, value]) => {\n headers.push({ name, value });\n });\n }\n\n // Codex format: httpHeaders object\n if (server.httpHeaders) {\n Object.entries(server.httpHeaders).forEach(([name, value]) => {\n headers.push({ name, value });\n });\n }\n\n // Codex format: bearerTokenEnvVar (adds Authorization header)\n if (server.bearerTokenEnvVar) {\n headers.push({\n name: 'Authorization',\n value: `Bearer $${server.bearerTokenEnvVar}`,\n isEnvVar: true,\n });\n }\n\n return headers;\n };\n\n // Toggle header value visibility\n const toggleHeaderValue = (headerName: string) => {\n setShowHeaderValues(prev => ({\n ...prev,\n [headerName]: !prev[headerName]\n }));\n };\n\n return (\n <Card className={cn('overflow-hidden', !server.enabled && 'opacity-60')}>\n {/* Header */}\n <div\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\n onClick={onToggleExpand}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-start gap-3\">\n <div className={cn(\n 'p-2 rounded-lg',\n server.enabled ? 'bg-primary/10' : 'bg-muted'\n )}>\n <Server className={cn(\n 'w-5 h-5',\n server.enabled ? 'text-primary' : 'text-muted-foreground'\n )} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {server.name}\n </span>\n {/* Transport type badge */}\n {isHttp && (\n <Badge variant=\"outline\" className=\"text-xs text-blue-600 border-blue-300\">\n <Link className=\"w-3 h-3 mr-1\" />\n {formatMessage({ id: 'mcp.transport.http' })}\n </Badge>\n )}\n <Badge variant={server.scope === 'global' ? 'default' : 'secondary'} className=\"text-xs\">\n {server.scope === 'global' ? (\n <><Globe className=\"w-3 h-3 mr-1\" />{formatMessage({ id: 'mcp.scope.global' })}</>\n ) : (\n <><Folder className=\"w-3 h-3 mr-1\" />{formatMessage({ id: 'mcp.scope.project' })}</>\n )}\n </Badge>\n {conflictInfo && (\n <Badge variant=\"outline\" className=\"text-xs text-orange-500 border-orange-300\">\n <AlertTriangle className=\"w-3 h-3 mr-1\" />\n {formatMessage({ id: 'mcp.conflict.badge' })}\n </Badge>\n )}\n {server.enabled && (\n <Badge variant=\"outline\" className=\"text-xs text-green-600\">\n {formatMessage({ id: 'mcp.status.enabled' })}\n </Badge>\n )}\n </div>\n <p className=\"text-sm text-muted-foreground mt-1 font-mono truncate max-w-md\" title={getServerSummary()}>\n {getServerSummary()}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onToggle(server.name, !server.enabled);\n }}\n >\n {server.enabled ? <Power className=\"w-4 h-4 text-green-600\" /> : <PowerOff className=\"w-4 h-4\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onSaveAsTemplate(server);\n }}\n title={formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}\n >\n <BookmarkPlus className=\"w-4 h-4 text-primary\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(server);\n }}\n >\n <Edit className=\"w-4 h-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(server);\n }}\n >\n <Trash2 className=\"w-4 h-4 text-destructive\" />\n </Button>\n {isExpanded ? (\n <ChevronUp className=\"w-5 h-5 text-muted-foreground\" />\n ) : (\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\n )}\n </div>\n </div>\n </div>\n\n {/* Expanded Content */}\n {isExpanded && (\n <div className=\"border-t border-border p-4 space-y-3 bg-muted/30\">\n {/* HTTP Server Details */}\n {isHttp && (\n <>\n {/* URL */}\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.url' })}</p>\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto break-all\">\n {server.url}\n </code>\n </div>\n\n {/* HTTP Headers */}\n {getHttpHeaders().length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.headers' })}</p>\n <div className=\"space-y-1\">\n {getHttpHeaders().map((header) => (\n <div key={header.name} className=\"flex items-center gap-2 text-sm\">\n <Badge variant=\"secondary\" className=\"font-mono\">{header.name}</Badge>\n <span className=\"text-muted-foreground\">=</span>\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\n {showHeaderValues[header.name] ? header.value : maskHeaderValue(header.value)}\n </code>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={() => toggleHeaderValue(header.name)}\n title={showHeaderValues[header.name]\n ? formatMessage({ id: 'mcp.http.hideValue' })\n : formatMessage({ id: 'mcp.http.showValue' })}\n >\n {showHeaderValues[header.name] ? (\n <EyeOff className=\"w-3 h-3 text-muted-foreground\" />\n ) : (\n <Eye className=\"w-3 h-3 text-muted-foreground\" />\n )}\n </Button>\n {header.isEnvVar && (\n <Badge variant=\"outline\" className=\"text-xs text-blue-500\">\n {formatMessage({ id: 'mcp.http.envVar' })}\n </Badge>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </>\n )}\n\n {/* STDIO Server Details */}\n {isStdio && (\n <>\n {/* Command details */}\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.command' })}</p>\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto\">\n {server.command}\n </code>\n </div>\n\n {/* Args */}\n {server.args && server.args.length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.args' })}</p>\n <div className=\"flex flex-wrap gap-1\">\n {server.args.map((arg, idx) => (\n <Badge key={idx} variant=\"outline\" className=\"font-mono text-xs\">\n {arg}\n </Badge>\n ))}\n </div>\n </div>\n )}\n\n {/* Environment variables */}\n {server.env && Object.keys(server.env).length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.env' })}</p>\n <div className=\"space-y-1\">\n {Object.entries(server.env).map(([key, value]) => (\n <div key={key} className=\"flex items-center gap-2 text-sm\">\n <Badge variant=\"secondary\" className=\"font-mono\">{key}</Badge>\n <span className=\"text-muted-foreground\">=</span>\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\n {value as string}\n </code>\n </div>\n ))}\n </div>\n </div>\n )}\n </>\n )}\n\n {/* Conflict warning panel */}\n {conflictInfo && (\n <div className=\"p-3 bg-orange-50 dark:bg-orange-950/30 border border-orange-200 dark:border-orange-800 rounded-lg space-y-1\">\n <div className=\"flex items-center gap-2 text-orange-700 dark:text-orange-400\">\n <AlertTriangle className=\"w-4 h-4\" />\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'mcp.conflict.title' })}</span>\n </div>\n <p className=\"text-xs text-orange-600 dark:text-orange-400/80\">\n {formatMessage({ id: 'mcp.conflict.description' }, { scope: formatMessage({ id: `mcp.scope.${conflictInfo.effectiveScope}` }) })}\n </p>\n <p className=\"text-xs text-orange-600 dark:text-orange-400/80\">\n {formatMessage({ id: 'mcp.conflict.resolution' })}\n </p>\n </div>\n )}\n </div>\n )}\n </Card>\n );\n}\n\n// ========== Main Page Component ==========\n\nexport function McpManagerPage() {\n const { formatMessage } = useIntl();\n const [activeTab, setActiveTab] = useState<'templates' | 'servers' | 'cross-cli'>('servers');\n const [searchQuery, setSearchQuery] = useState('');\n const [scopeFilter, setScopeFilter] = useState<'all' | 'project' | 'global'>('all');\n const [expandedServers, setExpandedServers] = useState<Set<string>>(new Set());\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editingServer, setEditingServer] = useState<McpServer | undefined>(undefined);\n const [cliMode, setCliMode] = useState<CliMode>('claude');\n const [codexExpandedServers, setCodexExpandedServers] = useState<Set<string>>(new Set());\n const [saveTemplateDialogOpen, setSaveTemplateDialogOpen] = useState(false);\n const [serverToSaveAsTemplate, setServerToSaveAsTemplate] = useState<McpServer | undefined>(undefined);\n\n const queryClient = useQueryClient();\n const notifications = useNotifications();\n\n const {\n servers,\n projectServers,\n globalServers,\n conflicts,\n totalCount,\n enabledCount,\n isLoading,\n isFetching,\n refetch,\n } = useMcpServers({\n scope: scopeFilter === 'all' ? undefined : scopeFilter,\n });\n\n // Fetch Codex MCP servers when in codex mode\n const codexQuery = useQuery({\n queryKey: ['codexMcpServers'],\n queryFn: fetchCodexMcpServers,\n enabled: cliMode === 'codex',\n staleTime: 2 * 60 * 1000, // 2 minutes\n });\n\n const projectPath = useWorkflowStore(selectProjectPath);\n\n // Fetch CCW Tools MCP configuration (Claude mode only)\n const ccwMcpQuery = useQuery({\n queryKey: ['ccwMcpConfig', projectPath],\n queryFn: () => fetchCcwMcpConfig(projectPath ?? undefined),\n enabled: cliMode === 'claude',\n staleTime: 5 * 60 * 1000, // 5 minutes\n });\n\n // Fetch CCW Tools MCP configuration (Codex mode only)\n const ccwMcpCodexQuery = useQuery({\n queryKey: ['ccwMcpConfigCodex'],\n queryFn: fetchCcwMcpConfigForCodex,\n enabled: cliMode === 'codex',\n staleTime: 5 * 60 * 1000, // 5 minutes\n });\n\n const {\n toggleServer,\n deleteServer,\n } = useMcpServerMutations();\n\n const toggleExpand = (serverName: string) => {\n setExpandedServers((prev) => {\n const next = new Set(prev);\n if (next.has(serverName)) {\n next.delete(serverName);\n } else {\n next.add(serverName);\n }\n return next;\n });\n };\n\n const toggleCodexExpand = (serverName: string) => {\n setCodexExpandedServers((prev) => {\n const next = new Set(prev);\n if (next.has(serverName)) {\n next.delete(serverName);\n } else {\n next.add(serverName);\n }\n return next;\n });\n };\n\n const handleToggle = (serverName: string, enabled: boolean) => {\n toggleServer(serverName, enabled);\n };\n\n const handleDelete = async (server: McpServer) => {\n if (confirm(formatMessage({ id: 'mcp.deleteConfirm' }, { name: server.name }))) {\n try {\n await deleteServer(server.name, server.scope);\n notifications.success(\n formatMessage({ id: 'mcp.actions.delete' }),\n server.name\n );\n refetch();\n } catch (error) {\n console.error('Failed to delete MCP server:', error);\n notifications.error(\n formatMessage({ id: 'mcp.actions.delete' }),\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n };\n\n const handleEdit = (server: McpServer) => {\n setEditingServer(server);\n setDialogOpen(true);\n };\n\n const handleAddClick = () => {\n setEditingServer(undefined);\n setDialogOpen(true);\n };\n\n const handleDialogClose = () => {\n setDialogOpen(false);\n setEditingServer(undefined);\n };\n\n const handleDialogSave = () => {\n setDialogOpen(false);\n setEditingServer(undefined);\n refetch();\n };\n\n const handleModeChange = (mode: CliMode) => {\n setCliMode(mode);\n };\n\n // CCW MCP handlers\n const ccwConfig = ccwMcpQuery.data ?? {\n isInstalled: false,\n enabledTools: [],\n projectRoot: undefined,\n allowedDirs: undefined,\n enableSandbox: undefined,\n installedScopes: [] as ('global' | 'project')[],\n };\n\n const ccwMcpQueryKey = ['ccwMcpConfig', projectPath];\n\n const handleToggleCcwTool = async (tool: string, enabled: boolean) => {\n // Read latest from cache to avoid stale closures\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey) ?? ccwConfig;\n const currentTools = currentConfig.enabledTools;\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey);\n\n const updatedTools = enabled\n ? (currentTools.includes(tool) ? currentTools : [...currentTools, tool])\n : currentTools.filter((t) => t !== tool);\n\n // Optimistic cache update for immediate UI response\n queryClient.setQueryData(ccwMcpQueryKey, (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, enabledTools: updatedTools };\n });\n\n try {\n await updateCcwConfig({ ...currentConfig, enabledTools: updatedTools });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.toggle.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to toggle CCW tool:', error);\n queryClient.setQueryData(ccwMcpQueryKey, previousConfig);\n }\n ccwMcpQuery.refetch();\n };\n\n const handleUpdateCcwConfig = async (config: Partial<CcwMcpConfig>) => {\n // Read BEFORE optimistic update to capture previous state for rollback\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey);\n\n // Optimistic cache update for immediate UI response\n queryClient.setQueryData(ccwMcpQueryKey, (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, ...config };\n });\n\n // Read AFTER optimistic update to get the latest merged state\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey) ?? ccwConfig;\n\n try {\n // Only pass the fields that updateCcwConfig expects\n await updateCcwConfig({\n enabledTools: currentConfig.enabledTools,\n projectRoot: currentConfig.projectRoot,\n allowedDirs: currentConfig.allowedDirs,\n enableSandbox: currentConfig.enableSandbox,\n });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.update.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to update CCW config:', error);\n queryClient.setQueryData(ccwMcpQueryKey, previousConfig);\n }\n ccwMcpQuery.refetch();\n };\n\n const handleCcwInstall = () => {\n ccwMcpQuery.refetch();\n };\n\n // Build conflict map for quick lookup\n const conflictMap = useMemo(() => {\n const map = new Map<string, McpServerConflict>();\n for (const c of conflicts) map.set(c.name, c);\n return map;\n }, [conflicts]);\n\n // CCW scope-specific handlers\n const handleCcwInstallToScope = async (scope: 'global' | 'project') => {\n try {\n await installCcwMcp(scope, scope === 'project' ? projectPath ?? undefined : undefined);\n ccwMcpQuery.refetch();\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.install.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to install CCW MCP to scope:', error);\n }\n };\n\n const handleCcwUninstallFromScope = async (scope: 'global' | 'project') => {\n try {\n await uninstallCcwMcpFromScope(scope, scope === 'project' ? projectPath ?? undefined : undefined);\n ccwMcpQuery.refetch();\n queryClient.invalidateQueries({ queryKey: ['mcpServers'] });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.uninstall.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to uninstall CCW MCP from scope:', error);\n }\n };\n\n // CCW MCP handlers for Codex mode\n const ccwCodexConfig = ccwMcpCodexQuery.data ?? {\n isInstalled: false,\n enabledTools: [] as string[],\n projectRoot: undefined,\n allowedDirs: undefined,\n enableSandbox: undefined,\n installedScopes: [] as ('global' | 'project')[],\n };\n\n const handleToggleCcwToolCodex = async (tool: string, enabled: boolean) => {\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']) ?? ccwCodexConfig;\n const currentTools = currentConfig.enabledTools;\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']);\n\n const updatedTools = enabled\n ? (currentTools.includes(tool) ? currentTools : [...currentTools, tool])\n : currentTools.filter((t) => t !== tool);\n\n queryClient.setQueryData(['ccwMcpConfigCodex'], (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, enabledTools: updatedTools };\n });\n\n try {\n await updateCcwConfigForCodex({ ...currentConfig, enabledTools: updatedTools });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.toggle.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to toggle CCW tool (Codex):', error);\n queryClient.setQueryData(['ccwMcpConfigCodex'], previousConfig);\n }\n ccwMcpCodexQuery.refetch();\n };\n\n const handleUpdateCcwConfigCodex = async (config: Partial<CcwMcpConfig>) => {\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']) ?? ccwCodexConfig;\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']);\n\n queryClient.setQueryData(['ccwMcpConfigCodex'], (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, ...config };\n });\n\n try {\n await updateCcwConfigForCodex({ ...currentConfig, ...config });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.update.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to update CCW config (Codex):', error);\n queryClient.setQueryData(['ccwMcpConfigCodex'], previousConfig);\n }\n ccwMcpCodexQuery.refetch();\n };\n\n const handleCcwInstallCodex = () => {\n ccwMcpCodexQuery.refetch();\n };\n\n // Template handlers\n const handleInstallTemplate = (template: any) => {\n const serverConfig = template?.serverConfig ?? {};\n const isHttp =\n serverConfig.type === 'http' ||\n serverConfig.transport === 'http' ||\n typeof serverConfig.url === 'string';\n\n if (isHttp) {\n setEditingServer({\n name: template.name,\n transport: 'http',\n url: serverConfig.url ?? '',\n scope: 'project',\n enabled: true,\n });\n } else {\n setEditingServer({\n name: template.name,\n transport: 'stdio',\n command: serverConfig.command,\n args: serverConfig.args || [],\n env: serverConfig.env,\n scope: 'project',\n enabled: true,\n });\n }\n setDialogOpen(true);\n };\n\n const handleSaveServerAsTemplate = (server: McpServer) => {\n setServerToSaveAsTemplate(server);\n setSaveTemplateDialogOpen(true);\n };\n\n const handleSaveAsTemplate = async (\n name: string,\n category: string,\n description: string,\n serverConfig: { command: string; args: string[]; env: Record<string, string> },\n ) => {\n try {\n const result = await saveMcpTemplate({\n name,\n description: description || undefined,\n category: category || 'custom',\n serverConfig: {\n command: serverConfig.command,\n args: serverConfig.args.length > 0 ? serverConfig.args : undefined,\n env: Object.keys(serverConfig.env).length > 0 ? serverConfig.env : undefined,\n },\n });\n if (result.success) {\n notifications.success(\n formatMessage({ id: 'mcp.templates.feedback.saveSuccess' }),\n name\n );\n setSaveTemplateDialogOpen(false);\n setServerToSaveAsTemplate(undefined);\n } else {\n notifications.error(\n formatMessage({ id: 'mcp.templates.feedback.saveError' }),\n result.error || ''\n );\n }\n } catch (error) {\n notifications.error(\n formatMessage({ id: 'mcp.templates.feedback.saveError' }),\n error instanceof Error ? error.message : String(error)\n );\n }\n };\n\n // Codex MCP handlers\n const handleCodexRemove = async (serverName: string) => {\n try {\n await codexRemoveServer(serverName);\n notifications.success(\n formatMessage({ id: 'mcp.actions.delete' }),\n serverName\n );\n codexQuery.refetch();\n } catch (error) {\n console.error('Failed to remove Codex MCP server:', error);\n notifications.error(\n formatMessage({ id: 'mcp.actions.delete' }),\n error instanceof Error ? error.message : String(error)\n );\n }\n };\n\n const handleCodexToggle = async (serverName: string, enabled: boolean) => {\n try {\n await codexToggleServer(serverName, enabled);\n codexQuery.refetch();\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.toggle.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to toggle Codex MCP server:', error);\n }\n };\n\n // Filter servers by search query\n const filteredServers = servers.filter((s) => {\n const query = searchQuery.toLowerCase();\n const nameMatch = s.name.toLowerCase().includes(query);\n // For STDIO servers, search in command; for HTTP servers, search in url\n const transportMatch = isHttpMcpServer(s)\n ? s.url?.toLowerCase().includes(query)\n : s.command?.toLowerCase().includes(query);\n return nameMatch || transportMatch;\n });\n\n // Filter Codex servers by search query\n const codexServers = codexQuery.data?.servers ?? [];\n const codexConfigPath = codexQuery.data?.configPath ?? '';\n const filteredCodexServers = codexServers.filter((s) => {\n const query = searchQuery.toLowerCase();\n const nameMatch = s.name.toLowerCase().includes(query);\n // For STDIO servers, search in command; for HTTP servers, search in url\n const transportMatch = isHttpMcpServer(s)\n ? s.url?.toLowerCase().includes(query)\n : s.command?.toLowerCase().includes(query);\n return nameMatch || transportMatch;\n });\n\n const currentServers = cliMode === 'codex' ? filteredCodexServers : filteredServers;\n const currentExpanded = cliMode === 'codex' ? codexExpandedServers : expandedServers;\n const currentToggleExpand = cliMode === 'codex' ? toggleCodexExpand : toggleExpand;\n const currentIsLoading = cliMode === 'codex' ? codexQuery.isLoading : isLoading;\n const currentIsFetching = cliMode === 'codex' ? codexQuery.isFetching : isFetching;\n const currentRefetch = cliMode === 'codex' ? (() => codexQuery.refetch()) : refetch;\n\n return (\n <div className=\"space-y-6\">\n {/* Page Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\n <div className=\"flex items-center gap-3\">\n <div>\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\n <Server className=\"w-6 h-6 text-primary\" />\n {formatMessage({ id: 'mcp.title' })}\n </h1>\n <p className=\"text-muted-foreground mt-1\">\n {formatMessage({ id: 'mcp.description' })}\n </p>\n </div>\n {/* CLI Mode Badge Switcher */}\n <div className=\"ml-3 flex-shrink-0\">\n <CliModeToggle\n currentMode={cliMode}\n onModeChange={handleModeChange}\n codexConfigPath={codexConfigPath}\n />\n </div>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => currentRefetch()} disabled={currentIsFetching}>\n <RefreshCw className={cn('w-4 h-4 mr-2', currentIsFetching && 'animate-spin')} />\n {formatMessage({ id: 'common.actions.refresh' })}\n </Button>\n {cliMode === 'claude' && (\n <Button onClick={handleAddClick}>\n <Plus className=\"w-4 h-4 mr-2\" />\n {formatMessage({ id: 'mcp.actions.add' })}\n </Button>\n )}\n </div>\n </div>\n\n {/* Tabbed Interface */}\n <TabsNavigation\n value={activeTab}\n onValueChange={(value) => setActiveTab(value as 'templates' | 'servers' | 'cross-cli')}\n tabs={[\n { value: 'templates', label: formatMessage({ id: 'mcp.tabs.templates' }) },\n { value: 'servers', label: formatMessage({ id: 'mcp.tabs.servers' }) },\n { value: 'cross-cli', label: formatMessage({ id: 'mcp.tabs.crossCli' }) },\n ]}\n />\n\n {/* Tab Content: Templates */}\n {activeTab === 'templates' && (\n <div className=\"mt-4 space-y-4\">\n {/* Recommended MCP Servers */}\n <RecommendedMcpSection onInstallComplete={() => refetch()} />\n\n {/* Templates Section */}\n <McpTemplatesSection\n onInstallTemplate={handleInstallTemplate}\n onSaveAsTemplate={handleSaveAsTemplate}\n />\n </div>\n )}\n\n {/* Tab Content: Servers */}\n {activeTab === 'servers' && (\n <div className=\"mt-4 space-y-4\">\n {/* Windows Compatibility Warning */}\n <WindowsCompatibilityWarning />\n\n {/* Stats Cards - Claude mode only */}\n {cliMode === 'claude' && (\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Server className=\"w-5 h-5 text-primary\" />\n <span className=\"text-2xl font-bold\">{totalCount}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.total' })}</p>\n </Card>\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Power className=\"w-5 h-5 text-green-600\" />\n <span className=\"text-2xl font-bold\">{enabledCount}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.enabled' })}</p>\n </Card>\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Globe className=\"w-5 h-5 text-info\" />\n <span className=\"text-2xl font-bold\">{globalServers.length}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.global' })}</p>\n </Card>\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Folder className=\"w-5 h-5 text-warning\" />\n <span className=\"text-2xl font-bold\">{projectServers.length}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.project' })}</p>\n </Card>\n </div>\n )}\n\n {/* Filters and Search - Claude mode only */}\n {cliMode === 'claude' && (\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\n <Input\n placeholder={formatMessage({ id: 'mcp.filters.searchPlaceholder' })}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant={scopeFilter === 'all' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setScopeFilter('all')}\n >\n {formatMessage({ id: 'mcp.filters.all' })}\n </Button>\n <Button\n variant={scopeFilter === 'global' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setScopeFilter('global')}\n >\n <Globe className=\"w-4 h-4 mr-1\" />\n {formatMessage({ id: 'mcp.scope.global' })}\n </Button>\n <Button\n variant={scopeFilter === 'project' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setScopeFilter('project')}\n >\n <Folder className=\"w-4 h-4 mr-1\" />\n {formatMessage({ id: 'mcp.scope.project' })}\n </Button>\n </div>\n </div>\n )}\n\n {/* Codex mode search only */}\n {cliMode === 'codex' && (\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\n <Input\n placeholder={formatMessage({ id: 'mcp.filters.searchPlaceholder' })}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n )}\n\n {/* CCW Tools MCP Card */}\n {cliMode === 'claude' && (\n <CcwToolsMcpCard\n isInstalled={ccwConfig.isInstalled}\n enabledTools={ccwConfig.enabledTools}\n projectRoot={ccwConfig.projectRoot}\n allowedDirs={ccwConfig.allowedDirs}\n enableSandbox={ccwConfig.enableSandbox}\n onToggleTool={handleToggleCcwTool}\n onUpdateConfig={handleUpdateCcwConfig}\n onInstall={handleCcwInstall}\n installedScopes={ccwConfig.installedScopes}\n onInstallToScope={handleCcwInstallToScope}\n onUninstallScope={handleCcwUninstallFromScope}\n />\n )}\n {cliMode === 'codex' && (\n <CcwToolsMcpCard\n target=\"codex\"\n isInstalled={ccwCodexConfig.isInstalled}\n enabledTools={ccwCodexConfig.enabledTools}\n projectRoot={ccwCodexConfig.projectRoot}\n allowedDirs={ccwCodexConfig.allowedDirs}\n enableSandbox={ccwCodexConfig.enableSandbox}\n onToggleTool={handleToggleCcwToolCodex}\n onUpdateConfig={handleUpdateCcwConfigCodex}\n onInstall={handleCcwInstallCodex}\n />\n )}\n\n {/* Servers List */}\n {currentIsLoading ? (\n <div className=\"space-y-3\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className=\"h-24 bg-muted animate-pulse rounded-lg\" />\n ))}\n </div>\n ) : currentServers.length === 0 ? (\n <Card className=\"p-8 text-center\">\n <Server className=\"w-12 h-12 mx-auto text-muted-foreground/50\" />\n <h3 className=\"mt-4 text-lg font-medium text-foreground\">{formatMessage({ id: 'mcp.emptyState.title' })}</h3>\n <p className=\"mt-2 text-muted-foreground\">\n {formatMessage({ id: 'mcp.emptyState.message' })}\n </p>\n </Card>\n ) : (\n <div className=\"space-y-3\">\n {currentServers.map((server) => (\n cliMode === 'codex' ? (\n <CodexMcpEditableCard\n key={`${server.name}-${server.scope}`}\n server={server as McpServer}\n enabled={server.enabled}\n isExpanded={currentExpanded.has(server.name)}\n onToggleExpand={() => currentToggleExpand(server.name)}\n isEditable={true}\n onRemove={handleCodexRemove}\n onToggle={handleCodexToggle}\n />\n ) : (\n <McpServerCard\n key={`${server.name}-${server.scope}`}\n server={server}\n isExpanded={currentExpanded.has(`${server.name}-${server.scope}`)}\n onToggleExpand={() => currentToggleExpand(`${server.name}-${server.scope}`)}\n onToggle={handleToggle}\n onEdit={handleEdit}\n onDelete={handleDelete}\n onSaveAsTemplate={handleSaveServerAsTemplate}\n conflictInfo={conflictMap.get(server.name)}\n />\n )\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Tab Content: Cross-CLI */}\n {activeTab === 'cross-cli' && (\n <div className=\"mt-4 space-y-6\">\n {/* Section 1: Claude ↔ Codex 同步 */}\n <section>\n <div className=\"flex items-center gap-2 mb-3\">\n <RefreshCw className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'mcp.sync.title' })}\n </h3>\n </div>\n <Card className=\"p-4\">\n <CrossCliSyncPanel onSuccess={() => refetch()} />\n </Card>\n </section>\n\n {/* Section 2: 项目概览 */}\n <section>\n <div className=\"flex items-center gap-2 mb-3\">\n <Folder className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'mcp.projects.title' })}\n </h3>\n </div>\n <p className=\"text-xs text-muted-foreground mb-3\">\n {formatMessage({ id: 'mcp.projects.description' })}\n </p>\n <AllProjectsTable\n maxProjects={10}\n onProjectClick={(path) => console.log('Open project:', path)}\n onOpenNewWindow={(path) => window.open(`/?project=${encodeURIComponent(path)}`, '_blank')}\n />\n </section>\n\n {/* Section 3: 跨项目导入 */}\n <section>\n <div className=\"flex items-center gap-2 mb-3\">\n <Globe className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'mcp.crossProject.title' })}\n </h3>\n </div>\n <p className=\"text-xs text-muted-foreground mb-3\">\n {formatMessage({ id: 'mcp.crossProject.description' })}\n </p>\n <OtherProjectsSection\n onImportSuccess={(serverName, sourceProject) => {\n console.log('Imported server:', serverName, 'from:', sourceProject);\n refetch();\n }}\n />\n </section>\n </div>\n )}\n\n {/* Add/Edit Dialog - Claude mode only (shared across tabs) */}\n {cliMode === 'claude' && (\n <McpServerDialog\n mode={editingServer ? 'edit' : 'add'}\n server={editingServer}\n open={dialogOpen}\n onClose={handleDialogClose}\n onSave={handleDialogSave}\n />\n )}\n\n {/* Save as Template Dialog */}\n <TemplateSaveDialog\n open={saveTemplateDialogOpen}\n onClose={() => {\n setSaveTemplateDialogOpen(false);\n setServerToSaveAsTemplate(undefined);\n }}\n onSave={handleSaveAsTemplate}\n defaultName={serverToSaveAsTemplate?.name}\n defaultCommand={\n serverToSaveAsTemplate && isStdioMcpServer(serverToSaveAsTemplate)\n ? serverToSaveAsTemplate.command\n : undefined\n }\n defaultArgs={\n serverToSaveAsTemplate && isStdioMcpServer(serverToSaveAsTemplate)\n ? serverToSaveAsTemplate.args\n : undefined\n }\n defaultEnv={\n serverToSaveAsTemplate && isStdioMcpServer(serverToSaveAsTemplate)\n ? (serverToSaveAsTemplate.env as Record<string, string>)\n : undefined\n }\n />\n </div>\n );\n}\n\nexport default McpManagerPage;\n"],"names":["Files","createLucideIcon","FolderTree","Key","MessageCircleQuestion","PenLine","mcpServersKeys","scope","mcpTemplatesKeys","category","query","projectsKeys","paths","STALE_TIME","useMcpServers","options","staleTime","enabled","queryClient","useQueryClient","projectPath","useWorkflowStore","selectProjectPath","queryEnabled","useQuery","fetchMcpServers","projectServers","_a","globalServers","_b","conflicts","_c","allServers","enabledServers","s","refetch","invalidate","useUpdateMcpServer","mutation","useMutation","serverName","config","configType","updateMcpServer","useCreateMcpServer","server","createMcpServer","useDeleteMcpServer","deleteMcpServer","useToggleMcpServer","toggleMcpServer","previousServers","old","updateServer","servers","_error","_vars","context","useMcpServerMutations","update","create","remove","toggle","TEMPLATES_STALE_TIME","useMcpTemplates","fetchMcpTemplates","t","useDeleteTemplate","templateName","deleteMcpTemplate","useInstallTemplate","request","installMcpTemplate","EMPTY_PROJECTS","useProjectOperations","projectsQuery","fetchAllProjects","copyMutation","crossCliCopy","serversQuery","fetchOtherProjectsServers","fetchOtherServers","projectPaths","CONFIG_TYPE_STORAGE_KEY","DEFAULT_CONFIG_TYPE","loadConfigType","stored","saveConfigType","type","ConfigTypeToggle","currentType","onTypeChange","showWarning","existingServersCount","formatMessage","useIntl","internalType","setInternalType","useState","showWarningDialog","setShowWarningDialog","pendingType","setPendingType","useEffect","savedType","handleTypeClick","applyTypeChange","handleWarningConfirm","handleWarningCancel","jsxs","Fragment","jsx","cn","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","HttpHeadersInput","headers","onChange","disabled","revealedIds","setRevealedIds","generateId","handleAdd","handleRemove","id","h","handleUpdate","field","value","toggleReveal","prev","next","header","Input","e","Button","EyeOff","Eye","Trash2","Plus","McpServerDialog","mode","open","onClose","onSave","showError","showSuccess","useNotifications","templates","templatesLoading","transportType","setTransportType","formData","setFormData","selectedTemplate","setSelectedTemplate","errors","setErrors","argsInput","setArgsInput","envInput","setEnvInput","setConfigType","saveAsTemplate","setSaveAsTemplate","projectConfigType","inputMode","setInputMode","jsonInput","setJsonInput","detectTransportType","useCallback","serverData","isHttpMcpServer","parseJsonConfig","extractedServerName","serverNames","serverConfig","name","idx","args","env","k","v","error","detectedType","httpHeaders","headerName","stdioCommand","isStdioMcpServer","stdioArgs","stdioEnv","httpUrl","httpBearerToken","createMutation","handleClose","updateMutation","handleTemplateSelect","templateId","template","handleFieldChange","handleArgsChange","argsArray","a","handleEnvChange","envObj","lines","line","trimmed","key","valParts","val","handleHeadersChange","handleTransportTypeChange","validateForm","newErrors","checkNameExists","data","handleSubmit","envHttpHeaders","saveMcpTemplate","err","isPending","Dialog","DialogContent","DialogHeader","DialogTitle","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Terminal","Globe","arg","Badge","DialogFooter","maskHeaderValue","CodexMcpEditableCard","isExpanded","onToggleExpand","isEditable","onRemove","onToggle","isRemoving","isToggling","isConfirmDeleteOpen","setIsConfirmDeleteOpen","showHeaderValues","setShowHeaderValues","isHttp","isStdio","getServerSummary","getHttpHeaders","toggleHeaderValue","handleToggle","stopPropagation","Card","Server","Link","Edit3","Power","Lock","PowerOff","AlertDialogTrigger","ChevronUp","ChevronDown","CCW_MCP_TOOLS","CcwToolsMcpCard","isInstalled","enabledTools","projectRoot","allowedDirs","enableSandbox","onToggleTool","onUpdateConfig","onInstall","target","installedScopes","onUninstallScope","notifySuccess","notifyError","currentProjectPath","projectRootInput","setProjectRootInput","allowedDirsInput","setAllowedDirsInput","enableSandboxInput","setEnableSandboxInput","setIsExpanded","installScope","setInstallScope","isPathPickerOpen","setIsPathPickerOpen","pathPickerTarget","setPathPickerTarget","isCodex","installMutation","installCcwMcpToCodex","params","installCcwMcp","uninstallMutation","uninstallCcwMcpFromCodex","uninstallCcwMcp","updateConfigMutation","updateCcwConfigForCodex","updateCcwConfig","handleToggleTool","toolName","handleEnableAll","allToolNames","handleDisableAll","handleConfigSave","handleInstallClick","handleUninstallClick","Settings","Folder","AlertTriangle","ChevronRight","Check","tool","isEnabled","icon","getToolIcon","FolderOpen","HardDrive","Save","Download","FloatingFileBrowser","path","iconProps","FileText","Database","MessagesSquare","SEARCH_DEBOUNCE_MS","TemplateCard","onDelete","isInstalling","isDeleting","handleInstall","handleDelete","getCategoryIcon","FileCode","Copy","TemplateSaveDialog","defaultName","defaultCommand","defaultArgs","defaultEnv","setName","setCategory","description","setDescription","command","setCommand","handleSave","McpTemplatesSection","onInstallTemplate","onSaveAsTemplate","searchQuery","setSearchQuery","debouncedSearch","setDebouncedSearch","selectedCategory","setSelectedCategory","saveDialogOpen","setSaveDialogOpen","deleteConfirmOpen","setDeleteConfirmOpen","templateToDelete","setTemplateToDelete","categories","categoriesLoading","fetchMcpTemplateCategories","deleteMutation","timer","searchMcpTemplates","allTemplates","categoryTemplates","fetchMcpTemplatesByCategory","handleInstallTemplate","handleDeleteClick","handleDeleteConfirm","handleSaveTemplate","_name","_category","_description","_serverConfig","Search","Filter","ICON_MAP","Sparkles","RecommendedMcpWizard","mcpDefinition","onInstallComplete","fieldValues","setFieldValues","selectedScope","setSelectedScope","initializeFieldValues","initialValues","handleOpenChange","newOpen","addGlobalMcpServer","copyMcpServerToProject","result","handleMultiSelectToggle","current","newValue","validateFields","hasFields","Icon","Label","option","isSelected","Loader2","isWindows","buildCrossPlatformMcpConfig","RECOMMENDED_MCP_DEFINITIONS","values","baseUrl","url","Code2","RecommendedServerCard","definition","Zap","RecommendedMcpSection","wizardOpen","setWizardOpen","selectedDefinition","setSelectedDefinition","installedServerIds","setInstalledServerIds","checkInstalledServers","fetchMcpConfig","installedIds","userServers","projects","proj","handleWizardClose","handleInstallComplete","COMMON_COMMANDS","canAutoFixCommand","cmd","detectWindowsCommands","response","applyWindowsAutoFix","CommandDetectionList","commands","CheckCircle","XCircle","WindowsCompatibilityWarning","onComplete","checkResult","setCheckResult","isChecking","setIsChecking","dismissed","setDismissed","autoFixMutation","results","missingCommands","r","canAutoFix","handleAutoFix","handleDismiss","CrossCliSyncPanel","onSuccess","className","claudeServers","selectedClaude","setSelectedClaude","codexServers","setCodexServers","selectedCodex","setSelectedCodex","isLoadingCodex","setIsLoadingCodex","codexError","setCodexError","isCopying","setIsCopying","copyResult","setCopyResult","codex","fetchCodexMcpServers","toggleClaudeServer","selectAllClaude","clearAllClaude","toggleCodexServer","selectAllCodex","allNames","clearAllCodex","handleCopyToCodex","failedCount","copiedCount","handleCopyFromCodex","claudeTotal","claudeSelected","codexTotal","codexSelected","CheckCircle2","AlertCircle","Checkbox","ArrowRight","ArrowLeft","AllProjectsTable","onProjectClick","onOpenNewWindow","maxProjects","propProjectPaths","sortField","setSortField","sortDirection","setSortDirection","projectStats","setProjectStats","isStatsLoading","setIsStatsLoading","currentProject","isLoading","displayProjects","useMemo","stats","isCurrent","sortedProjects","b","comparison","handleSort","handleProjectClick","handleOpenNewWindow","project","Clock","formatDistanceToNow","ExternalLink","OtherProjectsSection","onImportSuccess","selectedProjectPath","setSelectedProjectPath","otherServers","setOtherServers","isFetchingServers","setIsFetchingServers","isGlobalFetching","createServer","isCreating","availableProjects","p","handleProjectSelect","serverList","projectName","handleImportServer","uniqueName","serverToCreate","selectedProjectName","RefreshCw","McpServerCard","onEdit","conflictInfo","BookmarkPlus","Edit","McpManagerPage","activeTab","setActiveTab","scopeFilter","setScopeFilter","expandedServers","setExpandedServers","dialogOpen","setDialogOpen","editingServer","setEditingServer","cliMode","setCliMode","codexExpandedServers","setCodexExpandedServers","saveTemplateDialogOpen","setSaveTemplateDialogOpen","serverToSaveAsTemplate","setServerToSaveAsTemplate","notifications","totalCount","enabledCount","isFetching","codexQuery","ccwMcpQuery","fetchCcwMcpConfig","ccwMcpCodexQuery","fetchCcwMcpConfigForCodex","toggleServer","deleteServer","toggleExpand","toggleCodexExpand","handleEdit","handleAddClick","handleDialogClose","handleDialogSave","handleModeChange","ccwConfig","ccwMcpQueryKey","handleToggleCcwTool","currentConfig","currentTools","previousConfig","updatedTools","handleUpdateCcwConfig","handleCcwInstall","conflictMap","map","c","handleCcwInstallToScope","handleCcwUninstallFromScope","uninstallCcwMcpFromScope","ccwCodexConfig","handleToggleCcwToolCodex","handleUpdateCcwConfigCodex","handleCcwInstallCodex","handleSaveServerAsTemplate","handleSaveAsTemplate","handleCodexRemove","codexRemoveServer","handleCodexToggle","codexToggleServer","filteredServers","nameMatch","transportMatch","codexConfigPath","filteredCodexServers","currentServers","currentExpanded","currentToggleExpand","currentIsLoading","currentIsFetching","currentRefetch","CliModeToggle","TabsNavigation","sourceProject"],"mappings":"qyDAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,GAAQC,GAAiB,QAAS,CACtC,CAAC,OAAQ,CAAE,EAAG,2BAA4B,IAAK,QAAQ,CAAE,EACzD,CAAC,OAAQ,CAAE,EAAG,8DAA+D,IAAK,QAAQ,CAAE,EAC5F,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,CACvE,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,GAAaD,GAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,qHACH,IAAK,QACX,CACA,EACE,CACE,OACA,CACE,EAAG,2HACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,uBAAwB,IAAK,QAAQ,CAAE,EACrD,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,CAC1D,CAAC,EC1BD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAME,GAAMF,GAAiB,MAAO,CAClC,CAAC,OAAQ,CAAE,EAAG,iEAAkE,IAAK,QAAQ,CAAE,EAC/F,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAQ,CAAE,EAC9C,CAAC,SAAU,CAAE,GAAI,MAAO,GAAI,OAAQ,EAAG,MAAO,IAAK,QAAQ,CAAE,CAC/D,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMG,GAAwBH,GAAiB,wBAAyB,CACtE,CAAC,OAAQ,CAAE,EAAG,iCAAkC,IAAK,QAAQ,CAAE,EAC/D,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,EACrE,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMI,GAAUJ,GAAiB,UAAW,CAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CACE,OACA,CACE,EAAG,oIACH,IAAK,QACX,CACA,CACA,CAAC,ECgBYK,EAAiB,CAC5B,IAAK,CAAC,YAAY,EAClB,MAAO,IAAM,CAAC,GAAGA,EAAe,IAAK,MAAM,EAC3C,KAAOC,GAAiC,CAAC,GAAGD,EAAe,MAAA,EAASC,CAAK,CAC3E,EAGaC,GAAmB,CAC9B,IAAK,CAAC,cAAc,EACpB,MAAO,IAAM,CAAC,GAAGA,GAAiB,IAAK,MAAM,EAC7C,KAAOC,GAAsB,CAAC,GAAGD,GAAiB,MAAA,EAASC,CAAQ,EACnE,OAASC,GAAkB,CAAC,GAAGF,GAAiB,IAAK,SAAUE,CAAK,EACpE,WAAY,IAAM,CAAC,GAAGF,GAAiB,IAAK,YAAY,CAC1D,EAGaG,GAAe,CAC1B,IAAK,CAAC,UAAU,EAChB,KAAM,IAAM,CAAC,GAAGA,GAAa,IAAK,MAAM,EACxC,QAAUC,GAAqB,CAAC,GAAGD,GAAa,IAAK,UAAW,GAAIC,GAAS,CAAA,CAAG,CAClF,EAGMC,GAAa,IAAS,IAyBrB,SAASC,GAAcC,EAAgC,GAAyB,WACrF,KAAM,CAAE,MAAAR,EAAO,UAAAS,EAAYH,GAAY,QAAAI,EAAU,IAASF,EACpDG,EAAcC,GAAA,EAEdC,EAAcC,GAAiBC,EAAiB,EAChDC,EAAeN,GAAW,CAAC,CAACG,EAE5BV,EAAQc,GAAS,CACrB,SAAUlB,EAAe,KAAKC,CAAK,EACnC,QAAS,IAAMkB,GAAgBL,CAAW,EAC1C,UAAAJ,EACA,QAASO,EACT,MAAO,CAAA,CACR,EAEKG,IAAiBC,EAAAjB,EAAM,OAAN,YAAAiB,EAAY,UAAW,CAAA,EACxCC,IAAgBC,EAAAnB,EAAM,OAAN,YAAAmB,EAAY,SAAU,CAAA,EACtCC,IAAYC,EAAArB,EAAM,OAAN,YAAAqB,EAAY,YAAa,CAAA,EACrCC,EAAazB,IAAU,UAAYmB,EAAiBnB,IAAU,SAAWqB,EAAgB,CAAC,GAAGF,EAAgB,GAAGE,CAAa,EAE7HK,EAAiBD,EAAW,OAAQE,GAAMA,EAAE,OAAO,EAEnDC,EAAU,SAAY,CAC1B,MAAMzB,EAAM,QAAA,CACd,EAEM0B,EAAa,SAAY,CAC7B,MAAMlB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CACtE,EAEA,MAAO,CACL,QAAS0B,EACT,eAAAN,EACA,cAAAE,EACA,UAAAE,EACA,WAAYE,EAAW,OACvB,aAAcC,EAAe,OAC7B,UAAWvB,EAAM,UACjB,WAAYA,EAAM,WAClB,MAAOA,EAAM,MACb,QAAAyB,EACA,WAAAC,CAAA,CAEJ,CAUO,SAASC,IAA+C,CAC7D,MAAMnB,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,WAAAC,EAAY,OAAAC,EAAQ,WAAAC,CAAA,IACjCC,GAAgBH,EAAYC,EAAQ,CAAE,YAAarB,GAAe,OAAW,WAAAsB,EAAY,EAC3F,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACkC,EAAYC,EAAQC,IAAeJ,EAAS,YAAY,CAAE,WAAAE,EAAY,OAAAC,EAAQ,WAAAC,EAAY,EACzG,WAAYJ,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAQO,SAASM,IAA+C,CAC7D,MAAM1B,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,OAAAM,EAAQ,WAAAH,CAAA,IACrBI,GAAgBD,EAAQ,CAAE,YAAazB,GAAe,OAAW,WAAAsB,EAAY,EAC/E,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACuC,EAAQH,IAAeJ,EAAS,YAAY,CAAE,OAAAO,EAAQ,WAAAH,EAAY,EACjF,WAAYJ,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAQO,SAASS,IAA+C,CAC7D,MAAM7B,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,WAAAC,EAAY,MAAAjC,CAAA,IACzByC,GAAgBR,EAAYjC,EAAO,CAAE,YAAaa,GAAe,OAAW,EAC9E,UAAW,IAAM,CACfF,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,CAC9D,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACsB,EAAYjC,IAAU+B,EAAS,YAAY,CAAE,WAAAE,EAAY,MAAAjC,EAAO,EAC/E,WAAY+B,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAQO,SAASW,IAA+C,CAC7D,MAAM/B,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,WAAAC,EAAY,QAAAvB,CAAA,IACzBiC,GAAgBV,EAAYvB,EAAS,CAAE,YAAaG,GAAe,OAAW,EAChF,SAAU,MAAO,CAAE,WAAAoB,EAAY,QAAAvB,KAAc,CAC3C,MAAMC,EAAY,cAAc,CAAE,SAAUZ,EAAe,IAAK,EAChE,MAAM6C,EAAkBjC,EAAY,aAAiCZ,EAAe,MAAM,EAG1F,OAAAY,EAAY,aAAiCZ,EAAe,KAAA,EAAS8C,GAAQ,CAC3E,GAAI,CAACA,EAAK,OAAOA,EACjB,MAAMC,EAAgBC,GACpBA,EAAQ,IAAKpB,GAAOA,EAAE,OAASM,EAAa,CAAE,GAAGN,EAAG,QAAAjB,CAAA,EAAYiB,CAAE,EACpE,MAAO,CACL,QAASmB,EAAaD,EAAI,OAAO,EACjC,OAAQC,EAAaD,EAAI,MAAM,EAC/B,UAAWA,EAAI,WAAa,CAAA,CAAC,CAEjC,CAAC,EAEM,CAAE,gBAAAD,CAAA,CACX,EACA,QAAS,CAACI,EAAQC,EAAOC,IAAY,CAC/BA,GAAA,MAAAA,EAAS,iBACXvC,EAAY,aAAaZ,EAAe,KAAA,EAAQmD,EAAQ,eAAe,CAE3E,EACA,UAAW,IAAM,CACfvC,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACkC,EAAYvB,IAAYqB,EAAS,YAAY,CAAE,WAAAE,EAAY,QAAAvB,EAAS,EACnF,WAAYqB,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAKO,SAASoB,IAAwB,CACtC,MAAMC,EAAStB,GAAA,EACTuB,EAAShB,GAAA,EACTiB,EAASd,GAAA,EACTe,EAASb,GAAA,EAEf,MAAO,CACL,aAAcU,EAAO,aACrB,WAAYA,EAAO,WACnB,aAAcC,EAAO,aACrB,WAAYA,EAAO,WACnB,aAAcC,EAAO,aACrB,WAAYA,EAAO,WACnB,aAAcC,EAAO,aACrB,WAAYA,EAAO,WACnB,WAAYH,EAAO,YAAcC,EAAO,YAAcC,EAAO,YAAcC,EAAO,UAAA,CAEtF,CAOA,MAAMC,GAAuB,IAAS,IAoB/B,SAASC,GAAgBjD,EAAkC,GAA2B,OAC3F,KAAM,CAAE,SAAAN,EAAU,UAAAO,EAAY+C,GAAsB,QAAA9C,EAAU,IAASF,EACjEG,EAAcC,GAAA,EAEdT,EAAQc,GAAS,CACrB,SAAUhB,GAAiB,KAAKC,CAAQ,EACxC,QAAS,IAAMwD,GAAA,EACf,UAAAjD,EACA,QAAAC,EACA,MAAO,CAAA,CACR,EAEKkB,EAAU,SAAY,CAC1B,MAAMzB,EAAM,QAAA,CACd,EAEM0B,EAAa,SAAY,CAC7B,MAAMlB,EAAY,kBAAkB,CAAE,SAAUV,GAAiB,IAAK,CACxE,EAEA,MAAO,CACL,UAAWC,IACPkB,EAAAjB,EAAM,OAAN,YAAAiB,EAAY,OAAQuC,GAAMA,EAAE,WAAazD,KAAa,CAAA,EACtDC,EAAM,MAAQ,CAAA,EAClB,UAAWA,EAAM,UACjB,WAAYA,EAAM,WAClB,MAAOA,EAAM,MACb,QAAAyB,EACA,WAAAC,CAAA,CAEJ,CAsCO,SAAS+B,IAA6C,CAC3D,MAAMjD,EAAcC,GAAA,EAEdmB,EAAWC,GAAY,CAC3B,WAAa6B,GAAyBC,GAAkBD,CAAY,EACpE,UAAW,IAAM,CACflD,EAAY,kBAAkB,CAAE,SAAUV,GAAiB,IAAK,CAClE,CAAA,CACD,EAED,MAAO,CACL,eAAgB8B,EAAS,YACzB,WAAYA,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAWO,SAASgC,IAA+C,CAC7D,MAAMpD,EAAcC,GAAA,EAEdmB,EAAWC,GAAY,CAC3B,WAAagC,GAAuCC,GAAmBD,CAAO,EAC9E,UAAW,IAAM,CAEfrD,EAAY,kBAAkB,CAAE,SAAUV,GAAiB,IAAK,EAChEU,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,gBAAiBgC,EAAS,YAC1B,aAAcA,EAAS,UACvB,MAAOA,EAAS,KAAA,CAEpB,CAqEA,MAAMmC,GAA2B,CAAA,EAK1B,SAASC,IAAmD,SACjE,MAAMxD,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAGhDqD,EAAgBnD,GAAS,CAC7B,SAAUb,GAAa,KAAA,EACvB,QAAS,IAAMiE,GAAA,EACf,UAAW/D,GACX,QAAS,GACT,MAAO,CAAA,CACR,EAGKgE,EAAetC,GAAY,CAC/B,WAAagC,GAAiCO,GAAaP,CAAO,EAClE,UAAW,IAAM,CACfrD,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAGKyE,EAAevD,GAAS,CAC5B,SAAUb,GAAa,QAAA,EACvB,QAAS,IAAMqE,GAAA,EACf,UAAWnE,GACX,QAAS,GACT,MAAO,CAAA,CACR,EAEKsB,EAAU,SAAY,CAC1B,MAAMwC,EAAc,QAAA,CACtB,EAEMM,EAAoB,MAAOC,GACxB,MAAMhE,EAAY,WAAW,CAClC,SAAUP,GAAa,QAAQuE,CAAY,EAC3C,QAAS,IAAMF,GAA0BE,CAAY,EACrD,UAAWrE,EAAA,CACZ,EAGH,MAAO,CACL,WAAUc,EAAAgD,EAAc,OAAd,YAAAhD,EAAoB,WAAY8C,GAC1C,iBAAgB5C,EAAA8C,EAAc,OAAd,YAAA9C,EAAoB,iBAAkBT,GAAe,OACrE,UAAWuD,EAAc,UACzB,MAAOA,EAAc,MACrB,QAAAxC,EACA,YAAcoC,GAAYM,EAAa,YAAY,CACjD,GAAGN,EACH,OAAQ,SACR,OAAQ,QACR,YAAaA,EAAQ,aAAenD,GAAe,MAAA,CACpD,EACD,cAAgBmD,GAAYM,EAAa,YAAY,CACnD,GAAGN,EACH,OAAQ,QACR,OAAQ,SACR,YAAaA,EAAQ,aAAenD,GAAe,MAAA,CACpD,EACD,UAAWyD,EAAa,UACxB,kBAAAI,EACA,kBAAmBF,EAAa,UAAA,CAEpC,CCxfA,MAAMI,GAA0B,kBAK1BC,GAAqC,WAOpC,SAASC,IAAgC,CAC9C,GAAI,CACF,MAAMC,EAAS,aAAa,QAAQH,EAAuB,EAC3D,GAAIG,IAAW,YAAcA,IAAW,cACtC,OAAOA,CAEX,MAAQ,CAER,CACA,OAAOF,EACT,CAKO,SAASG,GAAeC,EAA2B,CACxD,GAAI,CACF,aAAa,QAAQL,GAAyBK,CAAI,CACpD,MAAQ,CAER,CACF,CAqBO,SAASC,GAAiB,CAC/B,YAAAC,EACA,aAAAC,EACA,YAAAC,EAAc,GACd,qBAAAC,EAAuB,CACzB,EAA0B,CACxB,KAAM,CAAE,cAAAC,CAAA,EAAkBC,EAAA,EACpB,CAACC,EAAcC,CAAe,EAAIC,EAAAA,SAAwBR,CAAW,EACrE,CAACS,EAAmBC,CAAoB,EAAIF,EAAAA,SAAS,EAAK,EAC1D,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAA+B,IAAI,EAGzEK,EAAAA,UAAU,IAAM,CACdN,EAAgBP,CAAW,CAC7B,EAAG,CAACA,CAAW,CAAC,EAGhBa,EAAAA,UAAU,IAAM,CACd,GAAI,CAACb,GAAeA,IAAgBN,GAAqB,CACvD,MAAMoB,EAAYnB,GAAA,EACdmB,IAAcd,IAChBO,EAAgBO,CAAS,EACzBb,EAAaa,CAAS,EAE1B,CACF,EAAG,CAAA,CAAE,EAGL,MAAMC,EAAmBjB,GAAwB,CAC3CA,IAASQ,IAETJ,GAAeC,EAAuB,GACxCS,EAAed,CAAI,EACnBY,EAAqB,EAAI,GAEzBM,EAAgBlB,CAAI,EAExB,EAGMkB,EAAmBlB,GAAwB,CAC/CS,EAAgBT,CAAI,EACpBD,GAAeC,CAAI,EACnBG,EAAaH,CAAI,EACjBY,EAAqB,EAAK,EAC1BE,EAAe,IAAI,CACrB,EAGMK,EAAuB,IAAM,CAC7BN,GACFK,EAAgBL,CAAW,CAE/B,EAGMO,EAAsB,IAAM,CAChCR,EAAqB,EAAK,EAC1BE,EAAe,IAAI,CACrB,EAEA,OACEO,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMN,EAAgB,UAAU,EACzC,UAAWO,EACT,yDACAhB,IAAiB,WACb,+CACA,6CAAA,EAEP,SAAA,WAAA,CAAA,EAGDe,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMN,EAAgB,aAAa,EAC5C,UAAWO,EACT,yDACAhB,IAAiB,cACb,+CACA,6CAAA,EAEP,SAAA,cAAA,CAAA,CAED,EACF,QAGCiB,GAAA,CAAY,KAAMd,EAAmB,aAAcC,EAClD,gBAACc,GAAA,CACC,SAAA,CAAAL,OAACM,GAAA,CACC,SAAA,CAAAJ,MAACK,IACE,SAAAtB,EAAc,CAAE,GAAI,8BAAA,CAAgC,EACvD,SACCuB,GAAA,CACE,SAAA,CAAAvB,EAAc,CAAE,GAAI,+BAAgC,EACpDD,EAAuB,GACtBgB,OAAC,OAAA,CAAK,UAAU,gDACb,SAAA,CAAAhB,EAAqB,IAAEC,EAAc,CAAE,GAAI,iBAAA,CAAmB,EAAE,YAAA,CAAY,CAAA,CAC/E,CAAA,CAAA,CAEJ,CAAA,EACF,SACCwB,GAAA,CACC,SAAA,CAAAP,EAAAA,IAACQ,GAAA,CAAkB,QAASX,EACzB,SAAAd,EAAc,CAAE,GAAI,6BAAA,CAA+B,EACtD,EACAiB,MAACS,IAAkB,QAASb,EACzB,WAAc,CAAE,GAAI,8BAAA,CAAgC,CAAA,CACvD,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,CAEJ,CC1HA,SAASc,GAAiB,CAAE,QAAAC,EAAS,SAAAC,EAAU,SAAAC,GAAmC,CAChF,KAAM,CAAE,cAAA9B,CAAA,EAAkBC,EAAA,EACpB,CAAC8B,EAAaC,CAAc,EAAI5B,EAAAA,SAAsB,IAAI,GAAK,EAE/D6B,EAAa,IAAM,UAAU,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,GAEjFC,EAAY,IAAM,CACtBL,EAAS,CAAC,GAAGD,EAAS,CAAE,GAAIK,EAAA,EAAc,KAAM,GAAI,MAAO,GAAI,SAAU,EAAA,CAAO,CAAC,CACnF,EAEME,EAAgBC,GAAe,CACnCP,EAASD,EAAQ,OAAQS,GAAMA,EAAE,KAAOD,CAAE,CAAC,CAC7C,EAEME,EAAe,CAACF,EAAYG,EAAyBC,IAA4B,CACrFX,EAASD,EAAQ,IAAKS,GAAOA,EAAE,KAAOD,EAAK,CAAE,GAAGC,EAAG,CAACE,CAAK,EAAGC,CAAA,EAAUH,CAAE,CAAC,CAC3E,EAEMI,EAAgBL,GAAe,CACnCJ,EAAgBU,GAAS,CACvB,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAIP,CAAE,EACbO,EAAK,OAAOP,CAAE,EAEdO,EAAK,IAAIP,CAAE,EAENO,CACT,CAAC,CACH,EAEA,OACE5B,EAAAA,KAAC,MAAA,CAAI,UAAU,YACZ,SAAA,CAAAa,EAAQ,IAAKgB,GACZ7B,EAAAA,KAAC,MAAA,CAAoB,UAAU,0BAE7B,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,MAAOD,EAAO,KACd,SAAWE,GAAMR,EAAaM,EAAO,GAAI,OAAQE,EAAE,OAAO,KAAK,EAC/D,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,UAAU,SACV,SAAA8B,CAAA,CAAA,EAGFf,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,KAAMd,EAAY,IAAIa,EAAO,EAAE,EAAI,OAAS,WAC5C,MAAOA,EAAO,MACd,SAAWE,GAAMR,EAAaM,EAAO,GAAI,QAASE,EAAE,OAAO,KAAK,EAChE,YAAa9C,EAAc,CAAE,GAAI,mCAAoC,EACrE,UAAU,OACV,SAAA8B,CAAA,CAAA,EAEFb,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAQ,QACR,KAAK,OACL,UAAU,qCACV,QAAS,IAAMN,EAAaG,EAAO,EAAE,EACrC,SAAAd,EAEC,SAAAC,EAAY,IAAIa,EAAO,EAAE,EACxB3B,EAAAA,IAAC+B,GAAA,CAAO,UAAU,SAAA,CAAU,EAE5B/B,EAAAA,IAACgC,GAAA,CAAI,UAAU,SAAA,CAAU,CAAA,CAAA,CAE7B,EACF,EAEAlC,EAAAA,KAAC,QAAA,CAAM,UAAU,0EACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAAS2B,EAAO,SAChB,SAAWE,GAAMR,EAAaM,EAAO,GAAI,WAAYE,EAAE,OAAO,OAAO,EACrE,UAAU,UACV,SAAAhB,CAAA,CAAA,EAED9B,EAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,EACxD,EAEAiB,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAQ,QACR,KAAK,OACL,QAAS,IAAMZ,EAAaS,EAAO,EAAE,EACrC,SAAAd,EACA,UAAU,mBAEV,SAAAb,EAAAA,IAACiC,GAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,CAC9B,GAvDQN,EAAO,EAwDjB,CACD,EACD7B,EAAAA,KAACgC,EAAA,CACC,KAAK,SACL,QAAQ,UACR,KAAK,KACL,QAASb,EACT,SAAAJ,EACA,UAAU,SAEV,SAAA,CAAAb,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CAAA,CAAA,CACzD,EACF,CAEJ,CAIO,SAASoD,GAAgB,CAC9B,KAAAC,EACA,OAAAtG,EACA,KAAAuG,EACA,QAAAC,EACA,OAAAC,CACF,EAAyB,CACvB,KAAM,CAAE,cAAAxD,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAChD,CAAE,MAAOiI,EAAW,QAASC,CAAA,EAAgBC,GAAA,EAG7C,CAAE,UAAAC,EAAW,UAAWC,CAAA,EAAqB3F,GAAA,EAG7C,CAAC4F,EAAeC,CAAgB,EAAI3D,EAAAA,SAA2B,OAAO,EAGtE,CAAC4D,EAAUC,CAAW,EAAI7D,WAA4B,CAC1D,KAAM,GACN,QAAS,GACT,KAAM,CAAA,EACN,IAAK,CAAA,EACL,IAAK,GACL,QAAS,CAAA,EACT,kBAAmB,GACnB,MAAO,UACP,QAAS,EAAA,CACV,EAEK,CAAC8D,EAAkBC,CAAmB,EAAI/D,EAAAA,SAAiB,EAAE,EAC7D,CAACgE,EAAQC,CAAS,EAAIjE,EAAAA,SAAqB,CAAA,CAAE,EAC7C,CAACkE,EAAWC,CAAY,EAAInE,EAAAA,SAAS,EAAE,EACvC,CAACoE,EAAUC,CAAW,EAAIrE,EAAAA,SAAS,EAAE,EACrC,CAACxD,EAAY8H,CAAa,EAAItE,EAAAA,SAAwB,UAAU,EAChE,CAACuE,EAAgBC,CAAiB,EAAIxE,EAAAA,SAAS,EAAK,EACpDyE,EAA0CjI,IAAe,cAAgB,SAAW,MAGpF,CAACkI,EAAWC,CAAY,EAAI3E,EAAAA,SAA0B,MAAM,EAC5D,CAAC4E,EAAWC,CAAY,EAAI7E,EAAAA,SAAS,EAAE,EAGvC8E,EAAsBC,cAAaC,GAClCA,GAEDC,GAAgBD,CAAU,EAAU,OAFhB,QAIvB,CAAA,CAAE,EAGCE,GAAkBH,EAAAA,YAAY,IAAM,CACxC,GAAI,CACF,IAAIxI,EAAS,KAAK,MAAMqI,CAAS,EAC7BO,EAAsB,GAI1B,GAAI5I,EAAO,YAAc,OAAOA,EAAO,YAAe,UAAY,CAAC,MAAM,QAAQA,EAAO,UAAU,EAAG,CACnG,MAAM6I,EAAc,OAAO,KAAK7I,EAAO,UAAU,EACjD,GAAI6I,EAAY,OAAS,EAAG,CAC1BD,EAAsBC,EAAY,CAAC,EACnC,MAAMC,EAAe9I,EAAO,WAAW4I,CAAmB,EACtDE,GAAgB,OAAOA,GAAiB,WAC1C9I,EAAS8I,EAEb,CACF,CAGA,GAAI9I,EAAO,IAAK,CAEdoH,EAAiB,MAAM,EAGvB,MAAMnC,EAAwB,CAAA,EAC1BjF,EAAO,SAAW,OAAOA,EAAO,SAAY,UAC9C,OAAO,QAAQA,EAAO,OAAO,EAAE,QAAQ,CAAC,CAAC+I,EAAMlD,EAAK,EAAGmD,KAAQ,CAC7D/D,EAAQ,KAAK,CACX,GAAI,UAAU,KAAK,IAAA,CAAK,IAAI+D,EAAG,GAC/B,KAAAD,EACA,MAAO,OAAOlD,EAAK,EACnB,SAAU,EAAA,CACX,CACH,CAAC,EAGHyB,EAAYvB,IAAS,CACnB,GAAGA,EACH,KAAM6C,GAAuB7C,EAAK,KAClC,IAAK/F,EAAO,KAAO,GACnB,QAAAiF,EACA,kBAAmBjF,EAAO,sBAAwBA,EAAO,mBAAqB,EAAA,EAC9E,CACJ,KAAO,CAELoH,EAAiB,OAAO,EAExB,MAAM6B,EAAO,MAAM,QAAQjJ,EAAO,IAAI,EAAIA,EAAO,KAAO,CAAA,EAClDkJ,EAAMlJ,EAAO,KAAO,OAAOA,EAAO,KAAQ,SAAWA,EAAO,IAAM,CAAA,EAExEsH,EAAYvB,KAAS,CACnB,GAAGA,GACH,KAAM6C,GAAuB7C,GAAK,KAClC,QAAS/F,EAAO,SAAW,GAC3B,KAAAiJ,EACA,IAAAC,CAAA,EACA,EAEFtB,EAAaqB,EAAK,KAAK,IAAI,CAAC,EAC5BnB,EACE,OAAO,QAAQoB,CAAG,EACf,IAAI,CAAC,CAACC,GAAGC,EAAC,IAAM,GAAGD,EAAC,IAAIC,EAAC,EAAE,EAC3B,KAAK;AAAA,CAAI,CAAA,CAEhB,CAGAhB,EAAa,MAAM,EACnBV,EAAU,CAAA,CAAE,EACZX,EACE1D,EAAc,CAAE,GAAI,+BAAgC,EACpDA,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAA,CAE5D,OAASgG,EAAO,CACd3B,EAAU,CACR,KAAMrE,EAAc,CAAE,GAAI,8BAAgC,CACxD,MAAOgG,aAAiB,MAAQA,EAAM,QAAU,cAAA,CACjD,CAAA,CACF,CACH,CACF,EAAG,CAAChB,EAAWhF,EAAe0D,CAAW,CAAC,EAG1CjD,EAAAA,UAAU,IAAM,CACd,GAAI1D,GAAUsG,IAAS,OAAQ,CAC7B,MAAM4C,EAAef,EAAoBnI,CAAM,EAC/CgH,EAAiBkC,CAAY,EAG7B,MAAMC,EAA4B,CAAA,EAC9Bb,GAAgBtI,CAAM,IAEpBA,EAAO,aACT,OAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAAC2I,GAAMlD,EAAK,EAAGmD,KAAQ,CACjEO,EAAY,KAAK,CACf,GAAI,eAAeP,EAAG,GACtB,KAAAD,GACA,MAAAlD,GACA,SAAU,EAAA,CACX,CACH,CAAC,EAECzF,EAAO,gBAETA,EAAO,eAAe,QAAQ,CAACoJ,GAAYR,KAAQ,CACjDO,EAAY,KAAK,CACf,GAAI,cAAcP,EAAG,GACrB,KAAMQ,GACN,MAAO,GACP,SAAU,EAAA,CACX,CACH,CAAC,GAKL,MAAMC,EAAeC,GAAiBtJ,CAAM,EAAIA,EAAO,QAAU,GAC3DuJ,EAAYD,GAAiBtJ,CAAM,EAAKA,EAAO,MAAQ,CAAA,EAAM,CAAA,EAC7DwJ,GAAWF,GAAiBtJ,CAAM,EAAKA,EAAO,KAAO,CAAA,EAAM,CAAA,EAG3DyJ,GAAUnB,GAAgBtI,CAAM,EAAIA,EAAO,IAAM,GACjD0J,GAAkBpB,GAAgBtI,CAAM,GAAKA,EAAO,mBAAqB,GAE/EkH,EAAY,CACV,KAAMlH,EAAO,KACb,QAASqJ,EACT,KAAME,EACN,IAAKC,GACL,IAAKC,GACL,QAASN,EACT,kBAAmBO,GACnB,MAAO1J,EAAO,MACd,QAASA,EAAO,OAAA,CACjB,EACDwH,EAAa+B,EAAU,KAAK,IAAI,CAAC,EACjC7B,EACE,OAAO,QAAQ8B,EAAQ,EACpB,IAAI,CAAC,CAACT,GAAGC,EAAC,IAAM,GAAGD,EAAC,IAAIC,EAAC,EAAE,EAC3B,KAAK;AAAA,CAAI,CAAA,CAEhB,MAEEhC,EAAiB,OAAO,EACxBE,EAAY,CACV,KAAM,GACN,QAAS,GACT,KAAM,CAAA,EACN,IAAK,CAAA,EACL,IAAK,GACL,QAAS,CAAA,EACT,kBAAmB,GACnB,MAAO,UACP,QAAS,EAAA,CACV,EACDM,EAAa,EAAE,EACfE,EAAY,EAAE,EAEhBN,EAAoB,EAAE,EACtBS,EAAkB,EAAK,EACvBP,EAAU,CAAA,CAAE,CACd,EAAG,CAACtH,EAAQsG,EAAMC,EAAM4B,CAAmB,CAAC,EAG5C,MAAMwB,GAAiBjK,GAAY,CACjC,WAAY,CAAC,CAAE,OAAAM,EAAQ,WAAAH,CAAAA,IACrBI,GAAgBD,EAAQ,CAAE,YAAazB,GAAe,OAAW,WAAAsB,EAAY,EAC/E,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DmM,GAAA,EACAnD,GAAA,MAAAA,GACF,CAAA,CACD,EAEKoD,GAAiBnK,GAAY,CACjC,WAAY,CAAC,CAAE,WAAAC,EAAY,OAAAC,EAAQ,WAAAC,CAAAA,IACjCC,GAAgBH,EAAYC,EAAQ,CAAE,YAAarB,GAAe,OAAW,WAAAsB,EAAY,EAC3F,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DmM,GAAA,EACAnD,GAAA,MAAAA,GACF,CAAA,CACD,EAGKmD,GAAc,IAAM,CACxBtC,EAAU,CAAA,CAAE,EACZd,EAAA,CACF,EAEMsD,GAAwBC,GAAuB,CACnD,MAAMC,EAAWnD,EAAU,KAAMxF,GAAMA,EAAE,OAAS0I,CAAU,EACxDC,IACF9C,EAAavB,IAAU,CACrB,GAAGA,EACH,QAASqE,EAAS,aAAa,QAC/B,KAAMA,EAAS,aAAa,MAAQ,CAAA,EACpC,IAAKA,EAAS,aAAa,KAAO,CAAA,CAAC,EACnC,EACFxC,GAAcwC,EAAS,aAAa,MAAQ,IAAI,KAAK,IAAI,CAAC,EAC1DtC,EACE,OAAO,QAAQsC,EAAS,aAAa,KAAO,CAAA,CAAE,EAC3C,IAAI,CAAC,CAACjB,EAAGC,CAAC,IAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAC3B,KAAK;AAAA,CAAI,CAAA,EAEd5B,EAAoB2C,CAAU,EAElC,EAEME,GAAoB,CACxBzE,EACAC,IACG,CACHyB,EAAavB,IAAU,CAAE,GAAGA,EAAM,CAACH,CAAK,EAAGC,CAAA,EAAQ,EAE/C4B,EAAO7B,CAAyB,GAClC8B,EAAW3B,IAAU,CAAE,GAAGA,EAAM,CAACH,CAAK,EAAG,MAAA,EAAY,CAEzD,EAEM0E,GAAoBzE,GAAkB,CAC1C+B,EAAa/B,CAAK,EAClB,MAAM0E,EAAY1E,EACf,MAAM,GAAG,EACT,IAAK2E,GAAMA,EAAE,KAAA,CAAM,EACnB,OAAQA,GAAMA,EAAE,OAAS,CAAC,EAC7BlD,EAAavB,IAAU,CAAE,GAAGA,EAAM,KAAMwE,GAAY,EAChD9C,EAAO,MACTC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,KAAM,QAAY,CAEtD,EAEM0E,EAAmB5E,GAAkB,CACzCiC,EAAYjC,CAAK,EACjB,MAAM6E,EAAiC,CAAA,EACjCC,EAAQ9E,EAAM,MAAM;AAAA,CAAI,EAC9B,UAAW+E,KAAQD,EAAO,CACxB,MAAME,GAAUD,EAAK,KAAA,EACrB,GAAIC,IAAWA,GAAQ,SAAS,GAAG,EAAG,CACpC,KAAM,CAACC,GAAK,GAAGC,EAAQ,EAAIF,GAAQ,MAAM,GAAG,EACtCG,GAAMD,GAAS,KAAK,GAAG,EACzBD,KACFJ,EAAOI,GAAI,KAAA,CAAM,EAAIE,GAAI,KAAA,EAE7B,CACF,CACA1D,EAAavB,IAAU,CAAE,GAAGA,EAAM,IAAK2E,GAAS,EAC5CjD,EAAO,KACTC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,IAAK,QAAY,CAErD,EAEMkF,GAAuBhG,GAA0B,CACrDqC,EAAavB,IAAU,CAAE,GAAGA,EAAM,QAAAd,GAAU,EACxCwC,EAAO,SACTC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,QAAS,QAAY,CAEzD,EAEMmF,GAA6BnI,GAA2B,CAC5DqE,EAAiBrE,CAAI,EAErB2E,EAAW3B,IAAU,CACnB,GAAGA,EACH,QAAS,OACT,IAAK,MAAA,EACL,CACJ,EAEMoF,GAAe,IAAe,CAClC,MAAMC,EAAwB,CAAA,EAQ9B,GALK/D,EAAS,KAAK,SACjB+D,EAAU,KAAO/H,EAAc,CAAE,GAAI,qCAAsC,GAIzE8D,IAAkB,QAEfE,EAAS,QAAQ,SACpB+D,EAAU,QAAU/H,EAAc,CAAE,GAAI,wCAAyC,OAE9E,CAEAgE,EAAS,IAAI,SAChB+D,EAAU,IAAM/H,EAAc,CAAE,GAAI,oCAAqC,GAG3E,GAAI,CACF,IAAI,IAAIgE,EAAS,GAAG,CACtB,MAAQ,CACN+D,EAAU,IAAM/H,EAAc,CAAE,GAAI,mCAAoC,CAC1E,CACF,CAEA,OAAAqE,EAAU0D,CAAS,EACZ,OAAO,KAAKA,CAAS,EAAE,SAAW,CAC3C,EAEMC,GAAkB,MAAOtC,GAAmC,CAChE,GAAI,CACF,MAAMuC,EAAO,MAAMtM,GAAgBL,GAAe,MAAS,EAG3D,MAFmB,CAAC,GAAG2M,EAAK,QAAS,GAAGA,EAAK,MAAM,EAEjC,KACf7L,GAAMA,EAAE,OAASsJ,IAASrC,IAAS,OAASjH,EAAE,QAASW,GAAA,YAAAA,EAAQ,MAAO,GAAA,CAE3E,MAAQ,CACN,MAAO,EACT,CACF,EAEMmL,GAAe,SAAY,CAC/B,GAAI,CAACJ,KACH,OAIF,GAAI,MAAME,GAAgBhE,EAAS,IAAI,EAAG,CACxCK,EAAU,CAAE,KAAMrE,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAG,EAC7E,MACF,CAGA,IAAIyF,EAEJ,GAAI3B,IAAkB,QACpB2B,EAAe,CACb,KAAMzB,EAAS,KACf,UAAW,QACX,QAASA,EAAS,QAClB,KAAMA,EAAS,KAAK,OAAS,EAAIA,EAAS,KAAO,OACjD,IAAK,OAAO,KAAKA,EAAS,GAAG,EAAE,OAAS,EAAIA,EAAS,IAAM,OAC3D,MAAOA,EAAS,MAChB,QAASA,EAAS,OAAA,MAEf,CAEL,MAAMkC,EAAsC,CAAA,EACtCiC,EAA2B,CAAA,EAEjCnE,EAAS,QAAQ,QAAS3B,GAAM,CAC1BA,EAAE,KAAK,SACLA,EAAE,SAEJ8F,EAAe,KAAK9F,EAAE,KAAK,KAAA,CAAM,EAEjC6D,EAAY7D,EAAE,KAAK,KAAA,CAAM,EAAIA,EAAE,MAAM,KAAA,EAG3C,CAAC,EAEDoD,EAAe,CACb,KAAMzB,EAAS,KACf,UAAW,OACX,IAAKA,EAAS,IACd,QAAS,OAAO,KAAKkC,CAAW,EAAE,OAAS,EAAIA,EAAc,OAC7D,YAAa,OAAO,KAAKA,CAAW,EAAE,OAAS,EAAIA,EAAc,OACjE,eAAgBiC,EAAe,OAAS,EAAIA,EAAiB,OAC7D,kBAAmBnE,EAAS,kBAAkB,KAAA,GAAU,OACxD,MAAOA,EAAS,MAChB,QAASA,EAAS,OAAA,CAEtB,CAGA,GAAIW,GAAkBb,IAAkB,QACtC,GAAI,CACF,MAAMsE,GAAgB,CACpB,KAAMpE,EAAS,KACf,SAAU,SACV,aAAc,CACZ,QAASA,EAAS,QAClB,KAAMA,EAAS,KAAK,OAAS,EAAIA,EAAS,KAAO,OACjD,IAAK,OAAO,KAAKA,EAAS,GAAG,EAAE,OAAS,EAAIA,EAAS,IAAM,MAAA,CAC7D,CACD,CACH,OAASqE,EAAK,CACZ5E,EAAUzD,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAGqI,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAEvH,CAGEhF,IAAS,MACXqD,GAAe,OAAO,CACpB,OAAQjB,EACR,WAAYzB,EAAS,QAAU,UAAYa,EAAoB,MAAA,CAChE,EAED+B,GAAe,OAAO,CACpB,WAAY7J,EAAQ,KACpB,OAAQ0I,EACR,WAAYzB,EAAS,QAAU,UAAYa,EAAoB,MAAA,CAChE,CAEL,EAEMyD,GAAY5B,GAAe,WAAaE,GAAe,UAE7D,OACE3F,EAAAA,IAACsH,IAAO,KAAAjF,EAAY,aAAcqD,GAChC,SAAA5F,EAAAA,KAACyH,GAAA,CAAc,UAAU,yCACvB,SAAA,CAAAvH,EAAAA,IAACwH,GAAA,CACC,eAACC,GAAA,CACE,SAAArF,IAAS,MACNrD,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC3CA,EAAc,CAAE,GAAI,wBAA0B,CAAE,KAAMjD,GAAA,YAAAA,EAAQ,KAAM,CAAA,CAC1E,CAAA,CACF,EAGCsG,IAAS,OACRtC,OAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAS+B,IAAc,OAAS,UAAY,UAC5C,KAAK,KACL,QAAS,IAAMC,EAAa,MAAM,EAClC,UAAU,SAET,SAAA/E,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,EAE/CiB,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAS+B,IAAc,OAAS,UAAY,UAC5C,KAAK,KACL,QAAS,IAAMC,EAAa,MAAM,EAClC,UAAU,SAET,SAAA/E,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,CAC/C,EACF,EAGFiB,EAAAA,IAAC,OAAI,UAAU,YAEZ,aAAc,OACbF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAO+D,EACP,SAAWlC,GAAMmC,EAAanC,EAAE,OAAO,KAAK,EAC5C,YAAa9C,EAAc,CAAE,GAAI,8BAA+B,EAChE,UAAWkB,EACT,kTACAkD,EAAO,MAAQ,mDAAA,CACjB,CAAA,EAEDA,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,KAAK,EAEvDA,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAC/C,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,yBAAA,CAA2B,EAClD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,2BAA2B,SAAA,SAAM,EAC9CA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BAChC,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOiB,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,gCAAgC,SAAA,QAAK,EAClDA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BAChC,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAMiB,CAAA,CAAA,CACF,CAAA,EACF,EAEAA,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAASuC,GACT,SAAU,CAACN,EAAU,KAAA,EACrB,UAAU,SAET,SAAAhF,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,CAChD,CAAA,CACF,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CAEG,SAAA,CAAA8C,IAAkB,SACrB/C,OAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,0BAAA,CAA4B,EACnD,SACC2I,GAAA,CAAO,MAAOzE,EAAkB,cAAe2C,GAAsB,SAAUhD,EAC9E,SAAA,CAAA5C,EAAAA,IAAC2H,GAAA,CAAc,UAAU,SACvB,SAAA3H,EAAAA,IAAC4H,GAAA,CACC,YACI7I,EADS6D,EACK,CAAE,GAAI,uBAAA,EACN,CAAE,GAAI,qCAAA,CADyB,CACc,CAAA,EAGnE,EACA5C,EAAAA,IAAC6H,GAAA,CACE,SAAAlF,EAAU,SAAW,EACpB3C,MAAC8H,GAAA,CAAW,MAAM,YAAY,SAAQ,GACnC,SAAA/I,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CACpD,EAEA4D,EAAU,IAAKmD,GACb9F,EAAAA,IAAC8H,GAAA,CAA+B,MAAOhC,EAAS,KAC9C,SAAAhG,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,SAAA8F,EAAS,KAAK,EAC7C9F,EAAAA,IAAC,OAAA,CAAK,UAAU,gCACb,SAAA8F,EAAS,aAAe/G,EAAc,CAAE,GAAI,qCAAA,CAAuC,CAAA,CACtF,CAAA,CAAA,CACF,CAAA,EANe+G,EAAS,IAO1B,CACD,CAAA,CAEL,CAAA,CAAA,CACF,CAAA,EACF,EAIFhG,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,uBAAwB,EAC7CiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,KAChB,SAAWlB,GAAMkE,GAAkB,OAAQlE,EAAE,OAAO,KAAK,EACzD,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,MAAO,CAAC,CAACoE,EAAO,KAChB,SAAUf,IAAS,MAAA,CAAA,EAEpBe,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,+BAAA,CAAiC,EACxD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,gBACL,MAAM,QACN,QAAS6C,IAAkB,QAC3B,SAAU,IAAM+D,GAA0B,OAAO,EACjD,UAAU,UACV,SAAUxE,IAAS,MAAA,CAAA,EAErBpC,EAAAA,IAAC+H,GAAA,CAAS,UAAU,+BAAA,CAAgC,EACpD/H,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CACzD,CAAA,EACF,EACAF,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,gBACL,MAAM,OACN,QAAS6C,IAAkB,OAC3B,SAAU,IAAM+D,GAA0B,MAAM,EAChD,UAAU,UACV,SAAUxE,IAAS,MAAA,CAAA,EAErBpC,EAAAA,IAACgI,GAAA,CAAM,UAAU,+BAAA,CAAgC,EACjDhI,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,CAAA,CACF,CAAA,EACF,EACAA,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,EACF,EAGC6C,IAAkB,SACjB/C,EAAAA,KAAAC,EAAAA,SAAA,CAEE,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,0BAA2B,EAChDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,QAChB,SAAWlB,GAAMkE,GAAkB,UAAWlE,EAAE,OAAO,KAAK,EAC5D,YAAa9C,EAAc,CAAE,GAAI,qCAAsC,EACvE,MAAO,CAAC,CAACoE,EAAO,OAAA,CAAA,EAEjBA,EAAO,SACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,EAE5D,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAC/C,EACAiB,EAAAA,IAAC4B,EAAA,CACC,MAAOyB,EACP,SAAWxB,GAAMmE,GAAiBnE,EAAE,OAAO,KAAK,EAChD,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,MAAO,CAAC,CAACoE,EAAO,IAAA,CAAA,EAElBnD,EAAAA,IAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,EACnD,EACC+C,EAAS,KAAK,OAAS,SACrB,MAAA,CAAI,UAAU,4BACZ,SAAAA,EAAS,KAAK,IAAI,CAACkF,EAAKvD,IACvB1E,EAAAA,IAACkI,EAAA,CAAgB,QAAQ,YAAY,UAAU,oBAC5C,SAAAD,CAAA,EADSvD,CAEZ,CACD,CAAA,CACH,EAEDvB,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC9C,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAOuD,EACP,SAAW1B,GAAMsE,EAAgBtE,EAAE,OAAO,KAAK,EAC/C,YAAa9C,EAAc,CAAE,GAAI,iCAAkC,EACnE,UAAWkB,EACT,wSACAkD,EAAO,KAAO,mDAAA,CAChB,CAAA,EAEFnD,EAAAA,IAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,yBAAA,CAA2B,EAClD,EACC,OAAO,KAAK+C,EAAS,GAAG,EAAE,OAAS,GAClC/C,EAAAA,IAAC,MAAA,CAAI,UAAU,iBACZ,SAAA,OAAO,QAAQ+C,EAAS,GAAG,EAAE,IAAI,CAAC,CAACyD,EAAKjF,CAAK,IAC5CzB,EAAAA,KAAC,MAAA,CAAc,UAAU,kCACvB,SAAA,CAAAE,MAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,YAChC,SAAA1B,EACH,EACAxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,4DACb,SAAAuB,CAAA,CACH,CAAA,GAPQiF,CAQV,CACD,EACH,EAEDrD,EAAO,KACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,GAAA,CAAI,CAAA,CAAA,CAExD,CAAA,EACF,EAID6C,IAAkB,QACjB/C,EAAAA,KAAAC,EAAAA,SAAA,CAEE,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,2BAA4B,EACjDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,IAChB,SAAWlB,GAAMkE,GAAkB,MAAOlE,EAAE,OAAO,KAAK,EACxD,YAAa9C,EAAc,CAAE,GAAI,sCAAuC,EACxE,MAAO,CAAC,CAACoE,EAAO,GAAA,CAAA,EAEjBA,EAAO,KACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAI,EAEtDA,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,8BAAA,CAAgC,CAAA,CACvD,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAC3D,EACAiB,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,kBAChB,SAAWlB,GAAMkE,GAAkB,oBAAqBlE,EAAE,OAAO,KAAK,EACtE,YAAa9C,EAAc,CAAE,GAAI,8CAA+C,CAAA,CAAA,EAElFiB,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,sCAAA,CAAwC,CAAA,CAC/D,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,8BAAA,CAAgC,EACvD,EACAiB,EAAAA,IAACU,GAAA,CACC,QAASqC,EAAS,QAClB,SAAU4D,GACV,SAAUU,EAAA,CAAA,EAEZrH,EAAAA,IAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,kCAAA,CAAoC,EAC3D,EACCmD,EAAO,SACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,CAAA,CAE5D,CAAA,EACF,EAIFF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,QACL,MAAM,UACN,QAAS+C,EAAS,QAAU,UAC5B,SAAWlB,GAAMkE,GAAkB,QAASlE,EAAE,OAAO,KAA6B,EAClF,UAAU,UACV,SAAUO,IAAS,MAAA,CAAA,EAErBpC,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAC5C,CAAA,EACF,EACAF,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,QACL,MAAM,SACN,QAAS+C,EAAS,QAAU,SAC5B,SAAWlB,GAAMkE,GAAkB,QAASlE,EAAE,OAAO,KAA6B,EAClF,UAAU,UACV,SAAUO,IAAS,MAAA,CAAA,EAErBpC,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAC3C,CAAA,CAAA,CACF,CAAA,EACF,EAGC+C,EAAS,QAAU,WAClBjD,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,gCACb,SAAA,CAAAf,EAAc,CAAE,GAAI,wBAAyB,EAAE,GAAA,EAClD,EACAiB,EAAAA,IAACtB,GAAA,CACC,YAAa/C,EACb,aAAc8H,EACd,YAAa,EAAA,CAAA,CACf,CAAA,CACF,CAAA,EAEJ,EAGA3D,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAG,UACH,QAAS+C,EAAS,QAClB,SAAWlB,GAAMkE,GAAkB,UAAWlE,EAAE,OAAO,OAAO,EAC9D,UAAU,SAAA,CAAA,EAEZ7B,EAAAA,IAAC,QAAA,CAAM,QAAQ,UAAU,UAAU,qDAChC,SAAAjB,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EAGC8D,IAAkB,SACjB/C,OAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAG,mBACH,QAAS0D,EACT,SAAW7B,GAAM8B,EAAkB9B,EAAE,OAAO,OAAO,EACnD,UAAU,SAAA,CAAA,EAEZ7B,EAAAA,IAAC,QAAA,CAAM,QAAQ,mBAAmB,UAAU,qDACzC,SAAAjB,EAAc,CAAE,GAAI,sCAAA,CAAwC,CAAA,CAC/D,CAAA,CAAA,CACF,CAAA,CAAA,CAEF,CAAA,CAEF,SAECoJ,GAAA,CACC,SAAA,CAAAnI,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,QAAS4D,GACT,SAAU2B,GAET,SAAAtI,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,EAEpDiB,EAAAA,IAAC8B,EAAA,CACC,QAASmF,GACT,SAAUI,GAET,SACGtI,EADHsI,GACiB,CAAE,GAAI,2BAAA,EACN,CAAE,GAAI,yBAAA,CAD6B,CACF,CAAA,CACrD,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CC9gCA,SAASe,GAAgB7G,EAAuB,CAC9C,MAAI,CAACA,GAASA,EAAM,QAAU,EAAU,OACjCA,EAAM,UAAU,EAAG,CAAC,EAAI,MACjC,CAEO,SAAS8G,GAAqB,CACnC,OAAAvM,EACA,QAAA5B,EACA,WAAAoO,EACA,eAAAC,EACA,WAAAC,EAAa,GACb,SAAAC,EACA,SAAAC,EACA,WAAAC,EAAa,GACb,WAAAC,EAAa,EACf,EAA8B,CAC5B,KAAM,CAAE,cAAA7J,CAAA,EAAkBC,EAAA,EACpB,CAAC6J,EAAqBC,CAAsB,EAAI3J,EAAAA,SAAS,EAAK,EAC9D,CAAC4J,EAAkBC,CAAmB,EAAI7J,EAAAA,SAAkC,CAAA,CAAE,EAE9E8J,EAAS7E,GAAgBtI,CAAM,EAC/BoN,EAAU9D,GAAiBtJ,CAAM,EAGjCqN,EAAmB,IAAM,OAC7B,OAAIF,EACKnN,EAAO,IAET,GAAGA,EAAO,SAAW,EAAE,MAAIlB,EAAAkB,EAAO,OAAP,YAAAlB,EAAa,KAAK,OAAQ,EAAE,GAAG,KAAA,CACnE,EAGMwO,EAAiB,IAAkE,CACvF,GAAI,CAACH,EAAQ,MAAO,CAAA,EAEpB,MAAMtI,EAAsE,CAAA,EAG5E,OAAI7E,EAAO,aACT,OAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CAC5DZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAICzF,EAAO,mBACT6E,EAAQ,KAAK,CACX,KAAM,gBACN,MAAO,WAAW7E,EAAO,iBAAiB,GAC1C,SAAU,EAAA,CACX,EAICA,EAAO,SACT,OAAO,QAAQA,EAAO,OAAO,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CACxDZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAGIZ,CACT,EAGM0I,EAAqBnE,GAAuB,CAChD8D,EAAoBvH,IAAS,CAC3B,GAAGA,EACH,CAACyD,CAAU,EAAG,CAACzD,EAAKyD,CAAU,CAAA,EAC9B,CACJ,EAGMoE,EAAe,SAAY,CAC3BZ,GACF,MAAMA,EAAS5M,EAAO,KAAM,CAAC5B,CAAO,CAExC,EAGMgH,EAAe,SAAY,CAC3BuH,IACF,MAAMA,EAAS3M,EAAO,IAAI,EAC1BgN,EAAuB,EAAK,EAEhC,EAGMS,EAAmB1H,GAAwB,CAC/CA,EAAE,gBAAA,CACJ,EAEA,OACE/B,EAAAA,KAAC0J,GAAK,UAAWvJ,EAAG,kBAAmB,CAAC/F,GAAW,YAAY,EAE7D,SAAA,CAAA8F,EAAAA,IAAC,MAAA,CACC,UAAU,yDACV,QAASuI,EAET,SAAAzI,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,iBACA/F,EAAU,gBAAkB,UAAA,EAE5B,SAAA8F,EAAAA,IAACyJ,GAAA,CAAO,UAAWxJ,EACjB,UACA/F,EAAU,eAAiB,uBAAA,EAC1B,CAAA,CACL,SACC,MAAA,CACC,SAAA,CAAA4F,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAlE,EAAO,KACV,EAECmN,GACCnJ,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,wCACjC,SAAA,CAAAlI,EAAAA,IAAC0J,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B3K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEDyJ,EACC1I,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,EAAAA,KAACoI,EAAA,CAAM,QAAQ,YAAY,UAAU,kCACnC,SAAA,CAAAlI,EAAAA,IAAC2J,GAAA,CAAM,UAAU,SAAA,CAAU,EAC1B5K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EACC7E,GACC4F,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,yBACjC,SAAA,CAAAlI,EAAAA,IAAC4J,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/B7K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CAEE,SAAA,CAAAD,EAAAA,KAACoI,EAAA,CAAM,QAAQ,YAAY,UAAU,kCACnC,SAAA,CAAAlI,EAAAA,IAAC6J,GAAA,CAAK,UAAU,SAAA,CAAU,EACzB9K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EACC7E,GACC4F,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,yBACjC,SAAA,CAAAlI,EAAAA,IAAC4J,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/B7K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,CAAA,EAEJ,EACAiB,MAAC,KAAE,UAAU,iEAAiE,MAAOmJ,EAAA,EAClF,YAAiB,CACpB,CAAA,CAAA,CACF,CAAA,EACF,EACArJ,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACZ,SAAA,CAAA0I,EACC1I,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAC,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACd0H,EAAgB1H,CAAC,EACjByH,EAAA,CACF,EACA,SAAUV,EAET,SAAA1O,QACE0P,GAAA,CAAM,UAAU,yBAAyB,EAE1C5J,EAAAA,IAAC8J,GAAA,CAAS,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAKxDhK,EAAAA,KAACI,GAAA,CAAY,KAAM2I,EAAqB,aAAcC,EACpD,SAAA,CAAA9I,EAAAA,IAAC+J,GAAA,CAAmB,QAAO,GACzB,SAAA/J,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAASyH,EACT,SAAUZ,EAEV,SAAA3I,EAAAA,IAACiC,GAAA,CAAO,UAAU,0BAAA,CAA2B,CAAA,CAAA,EAEjD,SACC9B,GAAA,CACC,SAAA,CAAAL,OAACM,GAAA,CACC,SAAA,CAAAJ,EAAAA,IAACK,GAAA,CACE,SAAAtB,EAAc,CAAE,GAAI,+BAAA,EAAmC,CAAE,KAAMjD,EAAO,IAAA,CAAM,CAAA,CAC/E,EACAkE,EAAAA,IAACM,GAAA,CACE,SAAAvB,EAAc,CAAE,GAAI,qCAAA,EAAyC,CAAE,KAAMjD,EAAO,IAAA,CAAM,CAAA,CACrF,CAAA,EACF,SACCyE,GAAA,CACC,SAAA,CAAAP,EAAAA,IAACQ,GAAA,CAAkB,SAAUmI,EAC1B,SAAA5J,EAAc,CAAE,GAAI,gCAAA,CAAkC,EACzD,EACAiB,EAAAA,IAACS,GAAA,CACC,QAASS,EACT,SAAUyH,EACV,UAAU,qEAET,WACC7I,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,oBAAoB,SAAA,IAAC,EACpCjB,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAA,CAAA,CAC3D,EAEAA,EAAc,CAAE,GAAI,kCAAmC,CAAA,CAAA,CAE3D,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,EAEAiB,EAAAA,IAAAD,WAAA,CAEE,SAAAC,MAAC,MAAA,CAAI,UAAWC,EACd,sDACA/F,EAAU,8BAAgC,gCAAA,EAEzC,SAAAA,EAAU8F,EAAAA,IAAC4J,GAAA,CAAM,UAAU,SAAA,CAAU,EAAK5J,EAAAA,IAAC8J,GAAA,CAAS,UAAU,SAAA,CAAU,CAAA,CAC3E,EACF,EAEDxB,QACE0B,GAAA,CAAU,UAAU,gCAAgC,EAErDhK,MAACiK,GAAA,CAAY,UAAU,+BAAA,CAAgC,CAAA,CAAA,CAE3D,CAAA,CAAA,CACF,CAAA,CAAA,EAID3B,GACCxI,EAAAA,KAAC,MAAA,CAAI,UAAU,mDAEZ,SAAA,CAAAmJ,GACCnJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,cAAA,CAAgB,EAAE,EACzFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,0EACb,WAAO,GAAA,CACV,CAAA,EACF,EAGCoJ,EAAA,EAAiB,OAAS,UACxB,MAAA,CACC,SAAA,CAAApJ,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,kBAAA,CAAoB,EAAE,EAC7FiB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAAoJ,EAAA,EAAiB,IAAKzH,GACrB7B,EAAAA,KAAC,MAAA,CAAsB,UAAU,kCAC/B,SAAA,CAAAE,MAACkI,GAAM,QAAQ,YAAY,UAAU,YAAa,WAAO,KAAK,EAC9DlI,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAA+I,EAAiBpH,EAAO,IAAI,EAAIA,EAAO,MAAQyG,GAAgBzG,EAAO,KAAK,EAC9E,EACA3B,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS,IAAMuH,EAAkB1H,EAAO,IAAI,EAC5C,MAAOoH,EAAiBpH,EAAO,IAAI,EAC/B5C,EAAc,CAAE,GAAI,oBAAA,CAAsB,EAC1CA,EAAc,CAAE,GAAI,qBAAsB,EAE7C,SAAAgK,EAAiBpH,EAAO,IAAI,EAC3B3B,EAAAA,IAAC+B,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAElD/B,EAAAA,IAACgC,GAAA,CAAI,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAGlDL,EAAO,UACN3B,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAChC,SAAAnJ,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAC1C,CAAA,GAxBM4C,EAAO,IA0BjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAIDuH,GACCpJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,aAAA,CAAe,EAAE,EACxFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,gEACb,WAAO,OAAA,CACV,CAAA,EACF,EAGClE,EAAO,MAAQA,EAAO,KAAK,OAAS,UAClC,MAAA,CACC,SAAA,CAAAkE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,UAAA,CAAY,EAAE,QACpF,MAAA,CAAI,UAAU,uBACZ,SAAAjD,EAAO,KAAK,IAAI,CAACmM,EAAKvD,IACrB1E,EAAAA,IAACkI,EAAA,CAAgB,QAAQ,UAAU,UAAU,oBAC1C,SAAAD,CAAA,EADSvD,CAEZ,CACD,CAAA,CACH,CAAA,EACF,EAID5I,EAAO,KAAO,OAAO,KAAKA,EAAO,GAAG,EAAE,OAAS,GAC9CgE,EAAAA,KAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,SAAA,CAAW,EAAE,QACnF,MAAA,CAAI,UAAU,YACZ,SAAA,OAAO,QAAQjD,EAAO,GAAG,EAAE,IAAI,CAAC,CAAC0K,EAAKjF,CAAK,IAC1CzB,EAAAA,KAAC,MAAA,CAAc,UAAU,kCACvB,SAAA,CAAAE,MAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,YAAa,SAAA1B,EAAI,EACtDxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAAuB,CAAA,CACH,CAAA,CAAA,EALQiF,CAMV,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAIFxG,MAAC,OAAI,UAAWC,EACd,sDACAuI,EACI,4BACA,2BAAA,EAEH,WACC1I,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC2J,GAAA,CAAM,UAAU,mBAAA,CAAoB,EACrC3J,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,CAAA,CACF,EAEAF,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC6J,GAAA,CAAK,UAAU,+BAAA,CAAgC,EAChD7J,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,CAAA,CACF,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,EAEJ,CAEJ,CCtUO,MAAMkK,GAA2B,CACtC,CAAE,KAAM,aAAc,KAAM,qBAAsB,KAAM,EAAA,EACxD,CAAE,KAAM,YAAa,KAAM,uBAAwB,KAAM,EAAA,EACzD,CAAE,KAAM,YAAa,KAAM,mBAAoB,KAAM,EAAA,EACrD,CAAE,KAAM,kBAAmB,KAAM,2BAA4B,KAAM,EAAA,EACnE,CAAE,KAAM,cAAe,KAAM,yBAA0B,KAAM,EAAA,EAC7D,CAAE,KAAM,eAAgB,KAAM,+BAAgC,KAAM,EAAA,EACpE,CAAE,KAAM,WAAY,KAAM,yBAA0B,KAAM,EAAA,CAC5D,EAIO,SAASC,GAAgB,CAC9B,YAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,cAAAC,EACA,aAAAC,EACA,eAAAC,EACA,UAAAC,EACA,OAAAC,EAAS,SACT,gBAAAC,EAAkB,CAAA,EAClB,iBAAAC,CACF,EAAyB,CACvB,KAAM,CAAE,cAAA/L,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EACd,CAAE,QAAS2Q,EAAe,MAAOC,CAAA,EAAgBtI,GAAA,EACjDuI,EAAqB3Q,GAAiBC,EAAiB,EAGvD,CAAC2Q,EAAkBC,CAAmB,EAAIhM,EAAAA,SAASmL,GAAe,EAAE,EACpE,CAACc,EAAkBC,CAAmB,EAAIlM,EAAAA,SAASoL,GAAe,EAAE,EACpE,CAACe,EAAoBC,CAAqB,EAAIpM,EAAAA,SAASqL,GAAiB,EAAK,EAE7E,CAAClC,EAAYkD,CAAa,EAAIrM,EAAAA,SAAS,EAAK,EAC5C,CAACsM,EAAcC,CAAe,EAAIvM,EAAAA,SAA+B,QAAQ,EACzE,CAACwM,EAAkBC,CAAmB,EAAIzM,EAAAA,SAAS,EAAK,EACxD,CAAC0M,EAAkBC,CAAmB,EAAI3M,EAAAA,SAA+C,IAAI,EAE7F4M,EAAUnB,IAAW,QAGrBoB,EAAkBxQ,GAAY,CAClC,WAAYuQ,EACR,IAAME,GAAA,EACLC,GACCC,GAAcD,EAAO,MAAOA,EAAO,WAAW,EACpD,UAAW,IAAM,CACXH,GACF5R,EAAY,kBAAkB,CAAE,SAAU,CAAC,iBAAiB,EAAG,EAC/DA,EAAY,kBAAkB,CAAE,SAAU,CAAC,mBAAmB,EAAG,IAEjEA,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,GAE9DwQ,EAAA,CACF,CAAA,CACD,EAEKyB,EAAoB5Q,GAAY,CACpC,WAAYuQ,EAAUM,GAA2BC,GACjD,UAAW,IAAM,CACXP,GACF5R,EAAY,kBAAkB,CAAE,SAAU,CAAC,iBAAiB,EAAG,EAC/DA,EAAY,kBAAkB,CAAE,SAAU,CAAC,mBAAmB,EAAG,IAEjEA,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,GAE9DwQ,EAAA,CACF,EACA,QAAU5F,GAAU,CAClB,QAAQ,MAAM,+BAAgCA,CAAK,CACrD,CAAA,CACD,EAEKwH,EAAuB/Q,GAAY,CACvC,WAAYuQ,EAAUS,GAA0BC,GAChD,UAAW,IAAM,CACXV,GACF5R,EAAY,kBAAkB,CAAE,SAAU,CAAC,iBAAiB,EAAG,EAC/DA,EAAY,kBAAkB,CAAE,SAAU,CAAC,mBAAmB,EAAG,IAEjEA,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,GAE9D4Q,EAAchM,EAAc,CAAE,GAAI,8BAAA,CAAgC,CAAC,CACrE,EACA,QAAUgG,GAAU,CAClB,QAAQ,MAAM,+BAAgCA,CAAK,EACnDiG,EACEjM,EAAc,CAAE,GAAI,6BAA8B,EAClDgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CAAA,CACD,EAGK2H,GAAmB,CAACC,EAAkBzS,KAAqB,CAC/DuQ,EAAakC,EAAUzS,EAAO,CAChC,EAEM0S,GAAkB,IAAM,CAC5B,MAAMC,EAAe3C,GAAc,IAAK/M,IAAMA,GAAE,IAAI,EACpDuN,EAAe,CAAE,aAAcmC,EAAc,CAC/C,EAEMC,GAAmB,IAAM,CAC7BpC,EAAe,CAAE,aAAc,CAAA,EAAI,CACrC,EAEMqC,GAAmB,IAAM,CAC7BR,EAAqB,OAAO,CAC1B,aAAAlC,EACA,YAAaa,GAAoB,OACjC,YAAaE,GAAoB,OACjC,cAAeE,CAAA,CAChB,CACH,EAEM0B,GAAqB,IAAM,CAC3BjB,EACDC,EAAwB,OAAO,MAAS,EAExCA,EAAwB,OAAO,CAC9B,MAAOP,EACP,YAAaA,IAAiB,UAAYR,EAAqB,MAAA,CAChE,CAEL,EAEMgC,GAAuB,IAAM,CAC7B,QAAQlO,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAC,GACnEqN,EAAkB,OAAA,CAEtB,EAEM/E,GAAY2E,EAAgB,WAAaI,EAAkB,WAAaG,EAAqB,UAEnG,OACEzM,OAAC0J,GAAK,UAAWvJ,EACf,2BACAmK,EAAc,iCAAmC,eAAA,EAGjD,SAAA,CAAApK,EAAAA,IAAC,MAAA,CACC,UAAU,yDACV,QAAS,IAAMwL,EAAc,CAAClD,CAAU,EAExC,SAAAxI,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,iBACAmK,EAAc,gBAAkB,UAAA,EAEhC,SAAApK,EAAAA,IAACkN,GAAA,CAAS,UAAWjN,EACnB,UACAmK,EAAc,eAAiB,uBAAA,EAC9B,CAAA,CACL,SACC,MAAA,CACC,SAAA,CAAAtK,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAjB,EAAc,CAAE,GAAI,eAAA,CAAiB,EACxC,EACCqL,GAAeS,EAAgB,OAAS,EACvC/K,EAAAA,KAAAC,EAAAA,SAAA,CACG,SAAA,CAAA8K,EAAgB,IAAK1P,GACpB2E,OAACoI,GAAc,QAAQ,UAAU,UAAU,UACxC,SAAA,CAAA/M,IAAM,eAAY6M,GAAA,CAAM,UAAU,eAAe,EAAKhI,EAAAA,IAACmN,GAAA,CAAO,UAAU,cAAA,CAAe,EACvFpO,EAAc,CAAE,GAAI,iBAAiB5D,CAAC,GAAI,CAAA,CAAA,EAFjCA,CAGZ,CACD,EACA0P,EAAgB,QAAU,GACzB/K,EAAAA,KAACoI,GAAM,QAAQ,UAAU,UAAU,4CACjC,SAAA,CAAAlI,EAAAA,IAACoN,GAAA,CAAc,UAAU,cAAA,CAAe,EACvCrO,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,EAEJ,QAECmJ,EAAA,CAAM,QAASkC,EAAc,UAAY,YAAa,UAAU,UAC9D,SAAcrL,EAAdqL,EAA4B,CAAE,GAAI,4BAA8C,CAAE,GAAI,6BAAA,CAAxB,EACjE,EAED2B,GACC/L,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAAwB,SAAA,QAE3D,EAEDkC,GACCpK,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,oBAChC,SAAAnJ,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EAEJ,EACAiB,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAC9C,CAAA,CAAA,CACF,CAAA,EACF,EACAA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BACZ,WACCA,EAAAA,IAACiK,GAAA,CAAY,UAAU,+BAAA,CAAgC,EAEvDjK,EAAAA,IAACqN,GAAA,CAAa,UAAU,gCAAgC,CAAA,CAE5D,CAAA,CAAA,CACF,CAAA,CAAA,EAID/E,GACCxI,EAAAA,KAAC,MAAA,CAAI,UAAU,mDAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS8K,GACT,SAAU,CAACxC,EAEX,SAAA,CAAApK,EAAAA,IAACsN,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/BvO,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,CAAA,EAEpDiB,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASgL,GACT,SAAU,CAAC1C,EAEV,SAAArL,EAAc,CAAE,GAAI,4BAAA,CAA8B,CAAA,CAAA,CACrD,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,sDACV,SAAAjB,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC9C,EACC,CAACqL,GACApK,EAAAA,IAAC,IAAA,CAAE,UAAU,6CACV,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,QACC,MAAA,CAAI,UAAU,yBACZ,SAAAmL,GAAc,IAAKqD,GAAS,CAC3B,MAAMC,GAAYnD,EAAa,SAASkD,EAAK,IAAI,EAC3CE,GAAOC,GAAYH,EAAK,IAAI,EAElC,OACEzN,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,kEACAuN,GAAY,kCAAoC,6BAAA,EAGlD,SAAA,CAAAxN,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAI,YAAYuN,EAAK,IAAI,GACzB,QAASC,GACT,SAAW3L,IAAM6K,GAAiBa,EAAK,KAAM1L,GAAE,OAAO,OAAO,EAC7D,SAAU,CAACuI,EACX,UAAU,SAAA,CAAA,EAEZtK,EAAAA,KAAC,QAAA,CACC,QAAS,YAAYyN,EAAK,IAAI,GAC9B,UAAU,gDAET,SAAA,CAAAE,GACD3N,EAAAA,KAAC,MAAA,CAAI,UAAU,SACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAjB,EAAc,CAAE,GAAI,iBAAiBwO,EAAK,IAAI,OAAA,CAAS,CAAA,CAC1D,EACCA,EAAK,MACJvN,EAAAA,IAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,UAClC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAI,iBAAiBwO,EAAK,IAAI,OAAA,CAAS,CAAA,CAC1D,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CACF,CAAA,EAlCKA,EAAK,IAAA,CAqChB,CAAC,CAAA,CACH,CAAA,EACF,EAGAzN,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,kDACf,SAAA,CAAAE,EAAAA,IAAC7G,GAAA,CAAW,UAAU,SAAA,CAAU,EAC/B4F,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,EACpD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,MAAOsJ,EACP,SAAWrJ,GAAMsJ,EAAoBtJ,EAAE,OAAO,KAAK,EACnD,YAAa9C,EAAc,CAAE,GAAI,uCAAwC,EACzE,SAAU,CAACqL,EACX,UAAU,mBAAA,CAAA,EAEZpK,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAM,CACbgK,EAAoB,aAAa,EACjCF,EAAoB,EAAI,CAC1B,EACA,SAAU,CAACxB,EACX,MAAM,0BAEN,SAAApK,EAAAA,IAAC2N,GAAA,CAAW,UAAU,SAAA,CAAU,CAAA,CAAA,CAClC,CAAA,CACF,CAAA,EACF,EAGA7N,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,kDACf,SAAA,CAAAE,EAAAA,IAAC4N,GAAA,CAAU,UAAU,SAAA,CAAU,EAC9B7O,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,EACpD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,MAAOwJ,EACP,SAAWvJ,GAAMwJ,EAAoBxJ,EAAE,OAAO,KAAK,EACnD,YAAa9C,EAAc,CAAE,GAAI,uCAAwC,EACzE,SAAU,CAACqL,EACX,UAAU,mBAAA,CAAA,EAEZpK,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAM,CACbgK,EAAoB,aAAa,EACjCF,EAAoB,EAAI,CAC1B,EACA,SAAU,CAACxB,EACX,MAAM,iCAEN,SAAApK,EAAAA,IAAC2N,GAAA,CAAW,UAAU,SAAA,CAAU,CAAA,CAAA,CAClC,EACF,EACA3N,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,EACF,EAGCoK,GACCpK,EAAAA,IAAC,MAAA,CAAI,UAAU,mBACb,SAAAF,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASiL,GACT,SAAU1F,GAEV,SAAA,CAAArH,EAAAA,IAAC6N,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B9O,EAAc,CAAE,GAAI,4BAAA,CAA8B,CAAA,CAAA,CAAA,EAEvD,EAIFiB,EAAAA,IAAC,OAAI,UAAU,wCACZ,SAACoK,EAuBApK,EAAAA,IAAC,MAAA,CAAI,UAAU,oCACZ,SAAA6K,EAAgB,OAAS,GAAKC,EAC7BD,EAAgB,IAAK1P,GACnB2E,EAAAA,KAACgC,EAAA,CAEC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMgJ,EAAiB3P,CAAC,EACjC,SAAUkM,GACV,UAAU,iEAEV,SAAA,CAAArH,EAAAA,IAACiC,GAAA,CAAO,UAAU,cAAA,CAAe,EAChClD,EAAc,CAAE,GAAI,gCAAA,EAAoC,CAAE,MAAO5D,EAAG,CAAA,CAAA,EARhEA,CAAA,CAUR,EAED2E,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASmL,GACT,SAAU5F,GACV,UAAU,iEAEV,SAAA,CAAArH,EAAAA,IAACiC,GAAA,CAAO,UAAU,cAAA,CAAe,EAChClD,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,CAAA,EAGxD,EAjDAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACZ,SAAA,CAAA,CAACiM,GACAjM,EAAAA,KAAC,SAAA,CACC,MAAO2L,EACP,SAAW5J,GAAM6J,EAAgB7J,EAAE,OAAO,KAA6B,EACvE,UAAU,+EAEV,SAAA,CAAA7B,EAAAA,IAAC,SAAA,CAAO,MAAM,SAAU,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAAE,EACtEiB,MAAC,UAAO,MAAM,UAAW,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAE,CAAA,CAAA,CAAA,EAG5EF,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASkL,GACT,SAAU3F,GAEV,SAAA,CAAArH,EAAAA,IAAC8N,GAAA,CAAS,UAAU,cAAA,CAAe,EAClC/O,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAAA,CAClD,CAAA,CACF,CA6BA,CAEJ,CAAA,EACF,EAGFiB,EAAAA,IAAC+N,GAAA,CACC,OAAQpC,EACR,QAAS,IAAMC,EAAoB,EAAK,EACxC,SAAUX,GAAsB,IAChC,aAAe+C,GAAS,CAClBnC,IAAqB,cACvBV,EAAoB6C,CAAI,EACfnC,IAAqB,eAC9BR,EAAqB5J,IAAUA,GAAO,GAAGA,EAAI,IAAIuM,CAAI,GAAKA,CAAK,EAEjEpC,EAAoB,EAAK,CAC3B,CAAA,CAAA,CACF,EACF,CAEJ,CAOA,SAAS8B,GAAYf,EAAsC,CACzD,MAAMsB,EAAY,CAAE,UAAW,+BAAA,EAE/B,OAAQtB,EAAA,CACN,IAAK,aACH,OAAO3M,MAACkO,GAAA,CAAU,GAAGD,CAAA,CAAW,EAClC,IAAK,YACH,OAAOjO,MAACsN,GAAA,CAAO,GAAGW,CAAA,CAAW,EAC/B,IAAK,YACH,OAAOjO,MAACmO,GAAA,CAAU,GAAGF,CAAA,CAAW,EAClC,IAAK,kBACH,OAAOjO,MAAC/G,GAAA,CAAO,GAAGgV,CAAA,CAAW,EAC/B,IAAK,cACH,OAAOjO,MAACkN,GAAA,CAAU,GAAGe,CAAA,CAAW,EAClC,IAAK,eACH,OAAOjO,MAAC3G,GAAA,CAAuB,GAAG4U,CAAA,CAAW,EAC/C,IAAK,WACH,OAAOjO,MAACoO,GAAA,CAAgB,GAAGH,CAAA,CAAW,EACxC,QACE,OAAOjO,MAACkN,GAAA,CAAU,GAAGe,CAAA,CAAW,CAAA,CAEtC,CC7eA,MAAMI,GAAqB,IAO3B,SAASC,GAAa,CAAE,SAAAxI,EAAU,UAAA6E,EAAW,SAAA4D,EAAU,aAAAC,EAAc,WAAAC,GAAiC,CACpG,KAAM,CAAE,cAAA1P,CAAA,EAAkBC,EAAA,EAEpB0P,EAAgB,IAAM,CAC1B/D,EAAU7E,CAAQ,CACpB,EAEM6I,EAAe,IAAM,CACzBJ,EAASzI,EAAS,IAAI,CACxB,EAGM8I,EAAkB,IAAM,OAC5B,MAAMX,EAAY,CAAE,UAAW,SAAA,EAC/B,QAAQrT,EAAAkL,EAAS,WAAT,YAAAlL,EAAmB,cAAY,CACrC,IAAK,QACL,IAAK,YACH,OAAOoF,MAAC6O,GAAA,CAAU,GAAGZ,CAAA,CAAW,EAClC,IAAK,WACL,IAAK,SACL,IAAK,OACH,OAAOjO,MAACmN,GAAA,CAAQ,GAAGc,CAAA,CAAW,EAChC,IAAK,WACL,IAAK,UACH,OAAOjO,MAACgI,GAAA,CAAO,GAAGiG,CAAA,CAAW,EAC/B,QACE,OAAOjO,MAAC8O,GAAA,CAAM,GAAGb,CAAA,CAAW,CAAA,CAElC,EAEA,aACGzE,EAAA,CAAK,UAAU,gDACd,SAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,wCACZ,SAAA4O,EAAA,EACH,EACA9O,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAA8F,EAAS,KACZ,EACCA,EAAS,UACR9F,MAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,UAClC,SAAApC,EAAS,QAAA,CACZ,CAAA,EAEJ,EACCA,EAAS,aACR9F,EAAAA,IAAC,KAAE,UAAU,kDACV,WAAS,YACZ,EAEFF,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,MAAC,OAAA,CAAK,UAAU,sEACb,SAAA8F,EAAS,aAAa,QACzB,EACCA,EAAS,aAAa,MAAQA,EAAS,aAAa,KAAK,OAAS,GACjEhG,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAA,CAAApC,EAAS,aAAa,KAAK,OAAO,OAAA,CAAA,CACrC,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,EACF,EACAhG,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS4M,EACT,SAAUF,EACV,MAAOzP,EAAc,CAAE,GAAI,gCAAiC,EAE5D,SAAAiB,EAAAA,IAAC8N,GAAA,CAAS,UAAU,SAAA,CAAU,CAAA,CAAA,EAEhC9N,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS6M,EACT,SAAUF,EACV,MAAO1P,EAAc,CAAE,GAAI,+BAAgC,EAE3D,SAAAiB,EAAAA,IAACiC,GAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,CAC9B,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAKO,SAAS8M,GAAmB,CACjC,KAAA1M,EACA,QAAAC,EACA,OAAAC,EACA,YAAAyM,EAAc,GACd,eAAAC,EAAiB,GACjB,YAAAC,EAAc,CAAA,EACd,WAAAC,EAAa,CAAA,CACf,EAA4B,CAC1B,KAAM,CAAE,cAAApQ,CAAA,EAAkBC,EAAA,EAEpB,CAACyF,EAAM2K,CAAO,EAAIjQ,EAAAA,SAAS6P,CAAW,EACtC,CAACtV,EAAU2V,CAAW,EAAIlQ,EAAAA,SAAS,EAAE,EACrC,CAACmQ,EAAaC,CAAc,EAAIpQ,EAAAA,SAAS,EAAE,EAC3C,CAACqQ,EAASC,CAAU,EAAItQ,EAAAA,SAAS8P,CAAc,EAC/C,CAAC5L,EAAWC,CAAY,EAAInE,EAAAA,SAAS+P,EAAY,KAAK,IAAI,CAAC,EAC3D,CAAC3L,EAAUC,CAAW,EAAIrE,EAAAA,SAC9B,OAAO,QAAQgQ,CAAU,EAAE,IAAI,CAAC,CAACtK,EAAGC,CAAC,IAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,CAAA,EAE7D,CAAC3B,EAAQC,CAAS,EAAIjE,EAAAA,SAA8C,CAAA,CAAE,EAG5EK,EAAAA,UAAU,IAAM,CACV6C,IACF+M,EAAQJ,GAAe,EAAE,EACzBK,EAAY,EAAE,EACdE,EAAe,EAAE,EACjBE,EAAWR,GAAkB,EAAE,EAC/B3L,GAAc4L,GAAe,CAAA,GAAI,KAAK,IAAI,CAAC,EAC3C1L,EACE,OAAO,QAAQ2L,GAAc,CAAA,CAAE,EAAE,IAAI,CAAC,CAACtK,EAAGC,CAAC,IAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,CAAA,EAEzE1B,EAAU,CAAA,CAAE,EAEhB,EAAG,CAACf,EAAM2M,EAAaC,EAAgBC,EAAaC,CAAU,CAAC,EAE/D,MAAMO,EAAa,IAAM,CACvB,MAAM5I,EAAiD,CAAA,EAOvD,GANKrC,EAAK,SACRqC,EAAU,KAAO/H,EAAc,CAAE,GAAI,mDAAoD,GAEtFyQ,EAAQ,SACX1I,EAAU,QAAU/H,EAAc,CAAE,GAAI,wCAAyC,GAE/E,OAAO,KAAK+H,CAAS,EAAE,OAAS,EAAG,CACrC1D,EAAU0D,CAAS,EACnB,MACF,CAEA,MAAMnC,EAAOtB,EACV,MAAM,GAAG,EACT,IAAK6C,GAAMA,EAAE,KAAA,CAAM,EACnB,OAAQA,GAAMA,EAAE,OAAS,CAAC,EAEvBtB,EAA8B,CAAA,EACpC,UAAW0B,KAAQ/C,EAAS,MAAM;AAAA,CAAI,EAAG,CACvC,MAAMgD,EAAUD,EAAK,KAAA,EACrB,GAAIC,GAAWA,EAAQ,SAAS,GAAG,EAAG,CACpC,KAAM,CAACC,EAAK,GAAGC,CAAQ,EAAIF,EAAQ,MAAM,GAAG,EACxCC,IAAK5B,EAAI4B,EAAI,KAAA,CAAM,EAAIC,EAAS,KAAK,GAAG,EAAE,KAAA,EAChD,CACF,CAEAlE,EAAOkC,EAAK,OAAQ/K,EAAS,OAAQ4V,EAAY,OAAQ,CACvD,QAASE,EAAQ,KAAA,EACjB,KAAA7K,EACA,IAAAC,CAAA,CACD,CACH,EAEA,OACE5E,EAAAA,IAACsH,IAAO,KAAAjF,EAAY,aAAcC,EAChC,SAAAxC,EAAAA,KAACyH,GAAA,CAAc,UAAU,wCACvB,SAAA,CAAAvH,EAAAA,IAACwH,GAAA,CACC,eAACC,GAAA,CACE,SAAA1I,EAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CACzD,CAAA,CACF,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,gCAAiC,EACtDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAO6C,EACP,SAAW5C,GAAM,CACfuN,EAAQvN,EAAE,OAAO,KAAK,EAClBsB,EAAO,MAAMC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,KAAM,MAAA,EAAY,CACrE,EACA,YAAa1C,EAAc,CAAE,GAAI,2CAA4C,EAC7E,MAAO,CAAC,CAACoE,EAAO,IAAA,CAAA,EAEjBA,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,0BAA2B,EAChDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAO4N,EACP,SAAW3N,GAAM,CACf4N,EAAW5N,EAAE,OAAO,KAAK,EACrBsB,EAAO,SAASC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,QAAS,MAAA,EAAY,CAC3E,EACA,YAAa1C,EAAc,CAAE,GAAI,qCAAsC,EACvE,MAAO,CAAC,CAACoE,EAAO,OAAA,CAAA,EAEjBA,EAAO,SACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,EAE5D,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAC/C,EACAiB,EAAAA,IAAC4B,EAAA,CACC,MAAOyB,EACP,SAAWxB,GAAMyB,EAAazB,EAAE,OAAO,KAAK,EAC5C,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,CAAA,CAAA,EAEtEiB,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC9C,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAOuD,EACP,SAAW1B,GAAM2B,EAAY3B,EAAE,OAAO,KAAK,EAC3C,YAAa9C,EAAc,CAAE,GAAI,iCAAkC,EACnE,UAAU,gQAAA,CAAA,CACZ,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,mCAAA,CAAqC,EAC5D,EACAe,EAAAA,KAAC4H,GAAA,CAAO,MAAOhO,EAAU,cAAe2V,EACtC,SAAA,CAAArP,EAAAA,IAAC2H,GAAA,CAAc,UAAU,SACvB,SAAA3H,EAAAA,IAAC4H,GAAA,CAAY,YAAa7I,EAAc,CAAE,GAAI,8CAAA,CAAgD,CAAA,CAAG,EACnG,SACC8I,GAAA,CACC,SAAA,CAAA7H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,QAAQ,SAAA,QAAK,EAC/B9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,MAAM,SAAA,MAAG,EAC3B9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,WAAW,SAAA,WAAQ,EACrC9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,WAAW,SAAA,WAAQ,EACrC9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,SAAS,SAAA,QAAA,CAAM,CAAA,CAAA,CACnC,CAAA,CAAA,CACF,CAAA,EACF,EAGAhI,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,sCAAA,CAAwC,EAC/D,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAOsP,EACP,SAAWzN,GAAM0N,EAAe1N,EAAE,OAAO,KAAK,EAC9C,YAAa9C,EAAc,CAAE,GAAI,kDAAmD,EACpF,UAAU,sPAAA,CAAA,CACZ,CAAA,CACF,CAAA,EACF,SACCoJ,GAAA,CACC,SAAA,CAAAnI,EAAAA,IAAC8B,EAAA,CAAO,QAAQ,UAAU,QAASQ,EAChC,WAAc,CAAE,GAAI,iCAAA,CAAmC,CAAA,CAC1D,EACAtC,MAAC8B,GAAO,QAAS4N,EACd,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAaO,SAASC,GAAoB,CAAE,kBAAAC,EAAmB,iBAAAC,GAA8C,CACrG,KAAM,CAAE,cAAA9Q,CAAA,EAAkBC,EAAA,EAGpB,CAAC8Q,EAAaC,CAAc,EAAI5Q,EAAAA,SAAS,EAAE,EAC3C,CAAC6Q,EAAiBC,CAAkB,EAAI9Q,EAAAA,SAAS,EAAE,EACnD,CAAC+Q,EAAkBC,CAAmB,EAAIhR,EAAAA,SAAiB,KAAK,EAChE,CAACiR,EAAgBC,CAAiB,EAAIlR,EAAAA,SAAS,EAAK,EACpD,CAACmR,EAAmBC,CAAoB,EAAIpR,EAAAA,SAAS,EAAK,EAC1D,CAACqR,EAAkBC,CAAmB,EAAItR,EAAAA,SAAwB,IAAI,EAGtE,CAAE,KAAMuR,EAAa,CAAA,EAAI,UAAWC,CAAA,EAAsBlW,GAAS,CACvE,SAAUhB,GAAiB,WAAA,EAC3B,QAASmX,GACT,UAAW,IAAU,GAAA,CACtB,EAGKC,EAAiBzT,GAAA,EACjB4O,EAAkBzO,GAAA,EAGxBiC,EAAAA,UAAU,IAAM,CACd,MAAMsR,EAAQ,WAAW,IAAM,CAC7Bb,EAAmBH,CAAW,CAChC,EAAGzB,EAAkB,EACrB,MAAO,IAAM,aAAayC,CAAK,CACjC,EAAG,CAAChB,CAAW,CAAC,EAGhB,KAAM,CAAE,KAAMnN,EAAY,CAAA,EAAI,UAAWC,CAAA,EAAqBnI,GAAS,CACrE,SAAUhB,GAAiB,KAAKyW,IAAqB,MAAQ,OAAYA,CAAgB,EACzF,QAAS,SAAY,CACnB,GAAIF,EAAgB,OAClB,OAAOe,GAAmBf,EAAgB,MAAM,EAClD,GAAWE,IAAqB,MAAO,CAErC,MAAMc,EAA8B,CAAA,EACpC,UAAWtX,KAAYgX,EAAY,CACjC,MAAMO,EAAoB,MAAMC,GAA4BxX,CAAQ,EACpEsX,EAAa,KAAK,GAAGC,CAAiB,CACxC,CACA,OAAOD,CACT,KACE,QAAOE,GAA4BhB,CAAgB,CAEvD,EACA,UAAW,IAAS,IACpB,QAAS,CAACS,CAAA,CACX,EAGKQ,EAAwBjN,cAAa4B,GAA0B,CAEnE8J,GAAA,MAAAA,EAAoB9J,EACtB,EAAG,CAAC8J,CAAiB,CAAC,EAEhBwB,EAAoBlN,cAAa7G,GAAyB,CAC9DoT,EAAoBpT,CAAY,EAChCkT,EAAqB,EAAI,CAC3B,EAAG,CAAA,CAAE,EAECc,EAAsBnN,EAAAA,YAAY,SAAY,CAClD,GAAI,CAACsM,EAAkB,QAER,MAAMK,EAAe,eAAeL,CAAgB,GACxD,UACTD,EAAqB,EAAK,EAC1BE,EAAoB,IAAI,EAE5B,EAAG,CAACD,EAAkBK,CAAc,CAAC,EAE/BS,EAAqBpN,EAAAA,YAAY,CAACqN,EAAeC,EAAmBC,EAAsBC,IAAoF,CAClL7B,GAAA,MAAAA,EAAmB0B,EAAOC,EAAWC,EAAcC,GACnDrB,EAAkB,EAAK,CACzB,EAAG,CAACR,CAAgB,CAAC,EAErB,OACE/P,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0CACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iCAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAAE,EAAAA,IAAC2R,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3F3R,EAAAA,IAAC4B,EAAA,CACC,MAAOkO,EACP,SAAWjO,GAAMkO,EAAelO,EAAE,OAAO,KAAK,EAC9C,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,UAAU,MAAA,CAAA,CACZ,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4R,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAClD9R,EAAAA,KAAC4H,GAAA,CAAO,MAAOwI,EAAkB,cAAeC,EAC9C,SAAA,CAAAnQ,MAAC2H,GAAA,CAAc,UAAU,YACvB,SAAA3H,MAAC4H,KAAY,EACf,SACCC,GAAA,CACC,SAAA,CAAA7H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,MACf,SAAA/I,EAAc,CAAE,GAAI,oCAAA,CAAsC,EAC7D,EACC2R,EAAW,IAAKhX,GACfsG,EAAAA,IAAC8H,IAA0B,MAAOpO,EAC/B,SAAAA,CAAA,EADcA,CAEjB,CACD,CAAA,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,EAGAoG,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMuO,EAAkB,EAAI,EAErC,SAAA,CAAArQ,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,sCAAA,CAAwC,CAAA,CAAA,CAAA,CAC/D,EACF,EAGC6D,QACE,MAAA,CAAI,UAAU,yCACb,SAAA5C,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAChD,CAAA,CACF,EACE4D,EAAU,SAAW,EACvB7C,EAAAA,KAAC0J,EAAA,CAAK,UAAU,mBACd,SAAA,CAAAxJ,EAAAA,IAAC8O,GAAA,CAAK,UAAU,8CAAA,CAA+C,EAC/D9O,EAAAA,IAAC,MAAG,UAAU,2CACX,WAAc,CAAE,GAAI,2BAAA,CAA6B,EACpD,EACAA,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,6BAAA,CAA+B,EACtD,SACC8B,EAAA,CAAO,QAAS,IAAMuO,EAAkB,EAAI,EAC3C,SAAA,CAAArQ,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,iCAAA,CAAmC,CAAA,CAAA,CAC1D,CAAA,CAAA,CACF,QAEC,MAAA,CAAI,UAAU,wCACZ,SAAA4D,EAAU,IAAKmD,GACd9F,EAAAA,IAACsO,GAAA,CAEC,SAAAxI,EACA,UAAWqL,EACX,SAAUC,EACV,aAAcpF,EAAgB,aAC9B,WAAY6E,EAAe,UAAA,EALtB/K,EAAS,IAAA,CAOjB,EACH,EAIF9F,EAAAA,IAAC+O,GAAA,CACC,KAAMqB,EACN,QAAS,IAAMC,EAAkB,EAAK,EACtC,OAAQiB,CAAA,CAAA,QAITpR,GAAA,CAAY,KAAMoQ,EAAmB,aAAcC,EAClD,gBAACpQ,GAAA,CACC,SAAA,CAAAL,OAACM,GAAA,CACC,SAAA,CAAAJ,MAACK,IACE,SAAAtB,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAC3D,QACCuB,GAAA,CACE,SAAAvB,EACC,CAAE,GAAI,oCAAA,EACN,CAAE,KAAMyR,CAAA,CAAiB,CAC3B,CACF,CAAA,EACF,SACCjQ,GAAA,CACC,SAAA,CAAAP,MAACQ,IACE,SAAAzB,EAAc,CAAE,GAAI,mCAAA,CAAqC,EAC5D,EACAiB,EAAAA,IAACS,GAAA,CACC,QAAS4Q,EACT,UAAU,qEAET,SAAAR,EAAe,WACZ9R,EAAc,CAAE,GAAI,qCAAA,CAAuC,EAC3DA,EAAc,CAAE,GAAI,mCAAA,CAAqC,CAAA,CAAA,CAE/D,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,CAEJ,CC9iBA,MAAM8S,GAAwE,CAC5E,cAAeF,GACf,OAAU3J,GACV,UAAW8J,GACX,SAAU5E,EACZ,EAuDO,SAAS6E,GAAqB,CACnC,KAAA1P,EACA,QAAAC,EACA,cAAA0P,EACA,kBAAAC,CACF,EAA8B,CAC5B,KAAM,CAAE,cAAAlT,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EACd,CAAE,QAASqI,EAAa,MAAOD,CAAA,EAAcE,GAAA,EAC7CrI,EAAcC,GAAiBC,EAAiB,EAGhD,CAAC2X,EAAaC,CAAc,EAAIhT,EAAAA,SAA8B,CAAA,CAAE,EAChE,CAACiT,EAAeC,CAAgB,EAAIlT,EAAAA,SAA+B,QAAQ,EAG3EmT,EAAwB,IAAM,CAClC,GAAI,CAACN,EAAe,OAEpB,MAAMO,EAAqC,CAAA,EAC3C,UAAWjR,KAAS0Q,EAAc,OAC5B1Q,EAAM,UAAY,OACpBiR,EAAcjR,EAAM,GAAG,EAAIA,EAAM,QACxBA,EAAM,OAAS,eACxBiR,EAAcjR,EAAM,GAAG,EAAI,CAAA,EAE3BiR,EAAcjR,EAAM,GAAG,EAAI,GAG/B6Q,EAAeI,CAAa,CAC9B,EAGMC,EAAoBC,GAAqB,CACzCA,GAAWT,EACbM,EAAA,GAEAH,EAAe,CAAA,CAAE,EACjB7P,EAAA,EAEJ,EAGM0J,EAAkBxQ,GAAY,CAClC,WAAY,SAAY,CACtB,GAAI,CAACwW,EAAe,MAAM,IAAI,MAAM,mBAAmB,EAEvD,MAAMxN,EAAewN,EAAc,YAAYE,CAAW,EAE1D,GAAIE,IAAkB,SACpB,OAAOM,GAAmBV,EAAc,GAAIxN,CAAY,EAExD,GAAI,CAACnK,EACH,MAAM,IAAI,MAAM,sDAAsD,EAExE,OAAOsY,GAAuBX,EAAc,GAAIxN,EAAcnK,CAAW,CAE7E,EACA,UAAYuY,GAAW,CACjBA,EAAO,SACTzY,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DkJ,EACE1D,EAAc,CAAE,GAAI,4BAA6B,EACjDA,EAAc,CAAE,GAAIiT,EAAe,QAAS,CAAA,EAE9CQ,EAAiB,EAAK,EACtBP,GAAA,MAAAA,KAEAzP,EACEzD,EAAc,CAAE,GAAI,0BAA2B,EAC/C6T,EAAO,OAAS,eAAA,CAGtB,EACA,QAAUxL,GAAe,CACvB5E,EACEzD,EAAc,CAAE,GAAI,0BAA2B,EAC/CqI,EAAI,OAAA,CAER,CAAA,CACD,EAGKrB,EAAoB,CAACS,EAAajF,IAAe,CACrD4Q,EAAe1Q,IAAS,CACtB,GAAGA,EACH,CAAC+E,CAAG,EAAGjF,CAAA,EACP,CACJ,EAGMsR,EAA0B,CAACrM,EAAajF,IAAkB,CAC9D,MAAMuR,EAAUZ,EAAY1L,CAAG,GAAK,CAAA,EAC9BuM,EAAWD,EAAQ,SAASvR,CAAK,EACnCuR,EAAQ,OAAQhO,GAAcA,IAAMvD,CAAK,EACzC,CAAC,GAAGuR,EAASvR,CAAK,EACtBwE,EAAkBS,EAAKuM,CAAQ,CACjC,EAGMC,EAAiB,IAAe,CACpC,GAAI,CAAChB,EAAe,MAAO,GAE3B,UAAW1Q,KAAS0Q,EAAc,OAChC,GAAI1Q,EAAM,SAAU,CAClB,MAAMC,EAAQ2Q,EAAY5Q,EAAM,GAAG,EACnC,GAAIA,EAAM,OAAS,gBACjB,GAAI,CAACC,GAASA,EAAM,SAAW,EAAG,MAAO,WAErC,CAACA,GAASA,EAAM,KAAA,IAAW,GAAI,MAAO,EAE9C,CAEF,MAAO,EACT,EAGM0F,EAAe,IAAM,CACzB,GAAI,CAAC+L,IAAkB,CACrBxQ,EACEzD,EAAc,CAAE,GAAI,wBAAyB,EAC7CA,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,EAEnD,MACF,CACAiN,EAAgB,OAAA,CAClB,EAEA,GAAI,CAACgG,EAAe,OAAO,KAE3B,MAAMiB,EAAYjB,EAAc,OAAO,OAAS,EAC1CkB,EAAOrB,GAASG,EAAc,IAAI,GAAK9E,GAE7C,OACElN,EAAAA,IAACsH,IAAO,KAAAjF,EAAY,aAAcmQ,EAChC,SAAA1S,EAAAA,KAACyH,GAAA,CAAc,UAAU,wCAEvB,SAAA,CAAAvH,MAACwH,GAAA,CACC,SAAA1H,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAI,UAAU,sEACb,eAACkT,EAAA,CAAK,UAAU,uBAAuB,CAAA,CACzC,SACC,MAAA,CACC,SAAA,CAAApT,OAAC2H,GAAA,CACE,SAAA,CAAA1I,EAAc,CAAE,GAAI,qBAAsB,EAAE,IAAEA,EAAc,CAAE,GAAIiT,EAAc,QAAS,CAAA,EAC5F,EACAhS,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAIiT,EAAc,OAAA,CAAS,CAAA,CAC9C,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAGAlS,EAAAA,KAAC,MAAA,CAAI,UAAU,iBAEZ,SAAA,CAAAmT,GACCjT,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAAgS,EAAc,OAAO,IAAK1Q,GACzBxB,OAAC,MAAA,CAAoB,UAAU,cAC7B,SAAA,CAAAA,EAAAA,KAACqT,GAAA,CAAM,UAAU,gDACd,SAAA,CAAApU,EAAc,CAAE,GAAIuC,EAAM,QAAA,CAAU,EACpCA,EAAM,UAAYtB,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAmB,SAAA,GAAA,CAAC,CAAA,EACzD,EACCsB,EAAM,SACLtB,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAIuC,EAAM,OAAA,CAAS,CAAA,CACtC,GAIAA,EAAM,OAAS,QAAUA,EAAM,OAAS,aACxCtB,EAAAA,IAAC4B,EAAA,CACC,KAAMN,EAAM,KACZ,MAAO4Q,EAAY5Q,EAAM,GAAG,GAAK,GACjC,SAAWO,GAAMkE,EAAkBzE,EAAM,IAAKO,EAAE,OAAO,KAAK,EAC5D,YAAaP,EAAM,YACnB,UAAU,mBAAA,CAAA,EAKbA,EAAM,OAAS,gBAAkBA,EAAM,SACtCtB,EAAAA,IAAC,MAAA,CAAI,UAAU,qFACZ,SAAAsB,EAAM,QAAQ,IAAK8R,GAAW,CAC7B,MAAMC,GAAcnB,EAAY5Q,EAAM,GAAG,GAAK,IAAI,SAAS8R,EAAO,KAAK,EACvE,OACEtT,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,sEACAoT,EAAa,gBAAkB,mBAAA,EAEjC,QAAS,IAAMR,EAAwBvR,EAAM,IAAK8R,EAAO,KAAK,EAE9D,SAAA,CAAApT,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAASqT,EACT,SAAU,IAAM,CAAC,EACjB,UAAU,gBAAA,CAAA,EAEZvT,EAAAA,KAAC,MAAA,CAAI,UAAU,SACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,sCACZ,SAAAoT,EAAO,MACV,EACCA,EAAO,MACNpT,EAAAA,IAAC,OAAI,UAAU,gCACZ,WAAO,IAAA,CACV,CAAA,CAAA,CAEJ,CAAA,CAAA,EAtBKoT,EAAO,KAAA,CAyBlB,CAAC,CAAA,CACH,CAAA,CAAA,EAvDM9R,EAAM,GAyDhB,CACD,EACH,EAIFxB,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAACmT,GAAA,CAAM,UAAU,sBACd,SAAApU,EAAc,CAAE,GAAI,kBAAA,CAAoB,EAC3C,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAASsQ,IAAkB,SAAW,UAAY,UAClD,KAAK,KACL,QAAS,IAAMC,EAAiB,QAAQ,EACxC,UAAU,SAET,SAAAtT,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,EAElDiB,EAAAA,IAAC8B,EAAA,CACC,QAASsQ,IAAkB,UAAY,UAAY,UACnD,KAAK,KACL,QAAS,IAAMC,EAAiB,SAAS,EACzC,UAAU,SAET,SAAAtT,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CAAA,CACnD,CAAA,CACF,CAAA,EACF,EAGC,CAACkU,GACAjT,EAAAA,IAAC,MAAA,CAAI,UAAU,6EACZ,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,SAGCoJ,GAAA,CACC,SAAA,CAAAnI,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,QAAS,IAAM0Q,EAAiB,EAAK,EACrC,SAAUxG,EAAgB,UAEzB,SAAAjN,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,EAEpDiB,EAAAA,IAAC8B,EAAA,CACC,QAASmF,EACT,SAAU+E,EAAgB,UAEzB,SAAAA,EAAgB,UACflM,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,CAChD,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC8N,GAAA,CAAS,UAAU,cAAA,CAAe,EAClC/O,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,QClVA,MAAMwU,GAAY,OAAO,UAAc,OAAe3Y,GAAA,UAAU,WAAV,YAAAA,GAAoB,cAAc,SAAS,QAMjG,SAAS4Y,GACPhE,EACA7K,EAAiB,CAAA,EACjB3K,EAA2D,CAAA,EAC3D,CACA,KAAM,CAAE,IAAA4K,EAAK,KAAAnG,CAAA,EAASzE,EAKhB0B,EAFsB6X,IADG,CAAC,MAAO,MAAO,OAAQ,SAAU,UAAW,MAAO,OAAQ,OAAQ,OAAQ,KAAK,EAC/C,SAAS/D,EAAQ,aAAa,EAG1F,CAAE,QAAS,MAAO,KAAM,CAAC,KAAMA,EAAS,GAAG7K,CAAI,CAAA,EAC/C,CAAE,QAAA6K,EAAS,KAAA7K,CAAA,EAEf,OAAIlG,MAAa,KAAOA,GACpBmG,GAAO,OAAO,KAAKA,CAAG,EAAE,OAAS,MAAU,IAAMA,GAE9ClJ,CACT,CAQA,MAAM+X,GAA0D,CAC9D,CACE,GAAI,WACJ,QAAS,oBACT,QAAS,oBACT,KAAM,cACN,SAAU,SACV,OAAQ,CACN,CACE,IAAK,UACL,SAAU,6BACV,KAAM,OACN,QAAS,oCACT,YAAa,oCACb,SAAU,GACV,QAAS,iCAAA,EAEX,CACE,IAAK,QACL,SAAU,2BACV,KAAM,WACN,QAAS,GACT,YAAa,uBACb,SAAU,GACV,QAAS,+BAAA,CACX,EAEF,YAAcC,GAAWF,GAA4B,MAAO,CAC1D,WACA,aACAE,EAAO,SAAW,oCAClB,UACAA,EAAO,KAAA,CACR,CAAA,EAEH,CACE,GAAI,kBACJ,QAAS,2BACT,QAAS,2BACT,KAAM,SACN,SAAU,UACV,OAAQ,CAAA,EACR,YAAa,IAAMF,GAA4B,MAAO,CAAC,4BAA4B,EAAG,CAAE,KAAM,OAAA,CAAS,CAAA,EAEzG,CACE,GAAI,MACJ,QAAS,eACT,QAAS,eACT,KAAM,UACN,SAAU,SACV,OAAQ,CACN,CACE,IAAK,SACL,SAAU,uBACV,KAAM,WACN,QAAS,GACT,YAAa,mBACb,SAAU,GACV,QAAS,2BAAA,CACX,EAEF,YAAcE,GAAW,CACvB,MAAMC,EAAU,yBACVC,EAAMF,EAAO,OAAS,GAAGC,CAAO,cAAcD,EAAO,MAAM,GAAKC,EACtE,OAAOH,GAA4B,MAAO,CAAC,KAAM,aAAcI,CAAG,CAAC,CACrE,CAAA,CAEJ,EAIM/B,GAAwE,CAC5E,cAAeF,GACf,OAAU3J,GACV,UAAW8J,GACX,SAAU+B,EACZ,EAaA,SAASC,GAAsB,CAC7B,WAAAC,EACA,YAAA3J,EACA,UAAAO,CACF,EAA+B,CAC7B,KAAM,CAAE,cAAA5L,CAAA,EAAkBC,EAAA,EACpBkU,EAAOrB,GAASkC,EAAW,IAAI,GAAK7G,GACpC+F,EAAYc,EAAW,OAAO,OAAS,EAE7C,aACGvK,EAAA,CAAK,UAAU,wCACd,SAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,yBAEb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,mBACAmK,EAAc,gBAAkB,UAAA,EAEhC,SAAApK,EAAAA,IAACkT,EAAA,CAAK,UAAWjT,EACf,UACAmK,EAAc,eAAiB,uBAAA,EAC9B,CAAA,CACL,EAGAtK,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,+CACX,SAAAjB,EAAc,CAAE,GAAIgV,EAAW,OAAA,CAAS,CAAA,CAC3C,EACC3J,GACCpK,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,mCAAA,CAAqC,CAAA,CAC5D,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,kDACV,SAAAjB,EAAc,CAAE,GAAIgV,EAAW,OAAA,CAAS,CAAA,CAC3C,EAGAjU,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACZ,SAAA,CAAAmT,EACCnT,EAAAA,KAAC,OAAA,CAAK,UAAU,wDACd,SAAA,CAAAE,EAAAA,IAAC5G,GAAA,CAAI,UAAU,SAAA,CAAU,EACxB2a,EAAW,OAAO,OAAO,IAAEhV,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CACxE,EAEAe,EAAAA,KAAC,OAAA,CAAK,UAAU,qEACd,SAAA,CAAAE,EAAAA,IAACgU,GAAA,CAAI,UAAU,SAAA,CAAU,EACxBjV,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEFiB,EAAAA,IAAC8B,EAAA,CACC,QAASsI,EAAc,UAAY,UACnC,KAAK,KACL,QAAS,IAAMO,EAAUoJ,CAAU,EAElC,WACCjU,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACkN,GAAA,CAAS,UAAU,kBAAA,CAAmB,EACtCnO,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAA,CAC1C,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC8N,GAAA,CAAS,UAAU,kBAAA,CAAmB,EACtC/O,EAAc,CAAE,GAAI,iCAAA,CAAmC,CAAA,CAAA,CAC1D,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAOO,SAASkV,GAAsB,CACpC,kBAAAhC,CACF,EAA+B,CAC7B,KAAM,CAAE,cAAAlT,CAAA,EAAkBC,EAAA,EAEpB,CAACkV,EAAYC,CAAa,EAAIhV,EAAAA,SAAS,EAAK,EAC5C,CAACiV,EAAoBC,CAAqB,EAAIlV,EAAAA,SAA0C,IAAI,EAC5F,CAACmV,EAAoBC,CAAqB,EAAIpV,EAAAA,SAAsB,IAAI,GAAK,EAG7EqV,EAAwB,SAAY,OACxC,GAAI,CACF,MAAMxN,EAAO,MAAMyN,GAAA,EACbC,MAAmB,IAEnB7Z,EAAgBmM,EAAK,eAAiB,CAAA,EACtC2N,EAAc3N,EAAK,aAAe,CAAA,EACxC,UAAWvC,KAAQ,OAAO,KAAK5J,CAAa,EAAG6Z,EAAa,IAAIjQ,CAAI,EACpE,UAAWA,KAAQ,OAAO,KAAKkQ,CAAW,EAAGD,EAAa,IAAIjQ,CAAI,EAElE,MAAMmQ,EAAW5N,EAAK,UAAY,CAAA,EAClC,UAAW6N,KAAQ,OAAO,OAAOD,CAAQ,EAAG,CAC1C,MAAMrY,EAAWsY,EAAa,YAAc,CAAA,EAC5C,UAAWpQ,KAAQ,OAAO,KAAKlI,CAAO,EAAGmY,EAAa,IAAIjQ,CAAI,CAChE,CAEA,IAAK7J,EAAAoM,EAAa,QAAb,MAAApM,EAAoB,QACvB,UAAW6J,KAAQ,OAAO,KAAMuC,EAAa,MAAM,OAAO,EAAG0N,EAAa,IAAIjQ,CAAI,EAGpF8P,EAAsBG,CAAY,CACpC,MAAQ,CAER,CACF,EAEAlV,EAAAA,UAAU,IAAM,CACdgV,EAAA,CACF,EAAG,CAAA,CAAE,EAGL,MAAMxH,EAAsB+G,GAAyC,CACnEM,EAAsBN,CAAU,EAChCI,EAAc,EAAI,CACpB,EAGMW,EAAoB,IAAM,CAC9BX,EAAc,EAAK,EACnBE,EAAsB,IAAI,CAC5B,EAGMU,EAAwB,IAAM,CAClCP,EAAA,EACAvC,GAAA,MAAAA,GACF,EAEA,OACEnS,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAD,EAAAA,KAAC,UAAA,CAAQ,UAAU,YAEjB,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,wCACX,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAiB,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,6BAAA,CAA+B,CAAA,CACtD,CAAA,EACF,QAGC,MAAA,CAAI,UAAU,wCACZ,SAAAyT,GAA4B,IAAKM,GAChC/T,EAAAA,IAAC8T,GAAA,CAEC,WAAAC,EACA,YAAaO,EAAmB,IAAIP,EAAW,EAAE,EACjD,UAAW/G,CAAA,EAHN+G,EAAW,EAAA,CAKnB,CAAA,CACH,CAAA,EACF,EAGA/T,EAAAA,IAAC+R,GAAA,CACC,KAAMmC,EACN,QAASY,EACT,cAAeV,EACf,kBAAmBW,CAAA,CAAA,CACrB,EACF,CAEJ,CCrSA,MAAMC,GAAkB,CACtB,CAAE,KAAM,MAAO,WAAY,mEAAA,EAC3B,CAAE,KAAM,OAAQ,WAAY,qBAAA,EAC5B,CAAE,KAAM,SAAU,WAAY,mCAAA,EAC9B,CAAE,KAAM,MAAO,WAAY,mEAAA,CAC7B,EAGA,SAASC,GAAkBzF,EAA0B,CACnD,OAAOwF,GAAgB,KAAME,GAAQA,EAAI,OAAS1F,CAAO,CAC3D,CAIA,eAAe2F,GAAsB9a,EAAyD,CAC5F,MAAM+a,EAAW,MAAM,MAAM,2BAA4B,CACvD,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,YAAA/a,EAAa,CAAA,CACrC,EACD,GAAI,CAAC+a,EAAS,GACZ,MAAM,IAAI,MAAM,2BAA2B,EAE7C,OAAOA,EAAS,KAAA,CAClB,CAEA,eAAeC,GAAoBhb,EAAsE,CACvG,MAAM+a,EAAW,MAAM,MAAM,6BAA8B,CACzD,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,YAAA/a,EAAa,CAAA,CACrC,EACD,GAAI,CAAC+a,EAAS,GACZ,MAAM,IAAI,MAAM,6BAA6B,EAE/C,OAAOA,EAAS,KAAA,CAClB,CAQA,SAASE,GAAqB,CAAE,SAAAC,GAAuC,CACrE,KAAM,CAAE,cAAAxW,CAAA,EAAkBC,EAAA,EAE1B,aACG,MAAA,CAAI,UAAU,iBACZ,SAAAuW,EAAS,IAAKL,GACbpV,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,iDACAiV,EAAI,UAAY,gBAAkB,mBAAA,EAGnC,SAAA,CAAAA,EAAI,gBACFM,GAAA,CAAY,UAAU,uBAAuB,EAE9CxV,EAAAA,IAACyV,GAAA,CAAQ,UAAU,0BAAA,CAA2B,EAEhDzV,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,WAAI,QAAQ,EAC/C,CAACkV,EAAI,WAAaA,EAAI,YACrBpV,EAAAA,KAAC,IAAA,CACC,KAAMoV,EAAI,WACV,OAAO,SACP,IAAI,sBACJ,UAAU,+DAEV,SAAA,CAAAlV,EAAAA,IAAC8N,GAAA,CAAS,UAAU,SAAA,CAAU,EAC7B/O,EAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAA,CAAA,CAC9C,CAAA,EArBGmW,EAAI,OAAA,CAwBZ,EACH,CAEJ,CAIO,SAASQ,GAA4B,CAC1C,YAAArb,EACA,WAAAsb,CACF,EAAqC,CACnC,KAAM,CAAE,cAAA5W,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EAEd,CAACwb,EAAaC,CAAc,EAAI1W,EAAAA,SAA0C,IAAI,EAC9E,CAAC2W,EAAYC,CAAa,EAAI5W,EAAAA,SAAS,EAAK,EAC5C,CAAC6W,EAAWC,CAAY,EAAI9W,EAAAA,SAAS,EAAK,EAG1CoU,EAAY,OAAO,OAAW,KAAe,OAAO,UAAU,SAAS,YAAA,EAAc,SAAS,KAAK,EAGnG2C,EAAkB1a,GAAY,CAClC,WAAY,IAAM6Z,GAAoBhb,CAAW,EACjD,UAAW,IAAM,CACfF,EAAY,kBAAkB,CAAE,SAAU,CAAC,YAAY,EAAG,EACtDwb,GAAcC,GAChBD,EAAW,CAAE,GAAGC,EAAa,WAAY,GAAO,CAEpD,CAAA,CACD,EAwCD,GArCApW,EAAAA,UAAU,IAAM,CACd,GAAI,CAAC+T,GAAayC,EAAW,QAEF,SAAY,CACrCD,EAAc,EAAI,EAClB,GAAI,CACF,MAAMI,EAAU,MAAMhB,GAAsB9a,CAAW,EACjD+b,EAAkBD,EAAQ,OAAQE,GAAM,CAACA,EAAE,SAAS,EAAE,IAAKA,GAAMA,EAAE,OAAO,EAC1EC,EAAaF,EAAgB,OAAS,GAAKA,EAAgB,MAAMnB,EAAiB,EAElFrC,EAAmC,CACvC,UAAW,GACX,gBAAAwD,EACA,SAAUD,EACV,WAAAG,CAAA,EAGFT,EAAejD,CAAM,EACjB+C,GACFA,EAAW/C,CAAM,CAErB,OAAS7N,EAAO,CACd,QAAQ,MAAM,yCAA0CA,CAAK,CAC/D,QAAA,CACEgR,EAAc,EAAK,CACrB,CACF,GAEA,CACF,EAAG,CAACxC,EAAWyC,EAAW3b,EAAasb,CAAU,CAAC,EAG9C,CAACpC,GAAayC,GAAcF,GAAc,CAACF,GAK3CA,GAAeA,EAAY,gBAAgB,SAAW,EACxD,OAAO,KAGT,MAAMW,EAAgB,SAAY,CAChCL,EAAgB,OAAA,CAClB,EAEMM,EAAgB,IAAM,CAC1BP,EAAa,EAAI,CACnB,EAEA,aACG,MAAA,CAAI,UAAU,4DACb,SAAAnW,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,EAAAA,IAACoN,GAAA,CAAc,UAAU,2CAAA,CAA4C,EACrEtN,EAAAA,KAAC,MAAA,CAAI,UAAU,mBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,wCACX,SAAAjB,EAAc,CAAE,GAAI,mBAAA,CAAqB,EAC5C,EACAiB,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EACAA,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS0U,EACV,SAAA,GAAA,CAAA,CAED,EACF,EAECZ,GACC9V,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAA6V,EAAY,gBAAgB,OAAS,GACpC5V,EAAAA,IAAC,MAAA,CAAI,UAAU,0BACb,SAAAA,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,0BAAA,EAA8B,CAAE,MAAO6W,EAAY,gBAAgB,MAAA,CAAQ,CAAA,CAClG,CAAA,CACF,EAGF5V,EAAAA,IAACsV,GAAA,CAAqB,SAAUM,EAAY,QAAA,CAAU,EAErDA,EAAY,YACX9V,OAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASyU,EACT,SAAUL,EAAgB,UAC1B,UAAU,UAET,SAAAA,EAAgB,UACfpW,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACwV,GAAA,CAAY,UAAU,cAAA,CAAe,EACrCzW,EAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAA,CAC9C,CAAA,CAAA,EAGJiB,MAAC,QAAK,UAAU,gCACb,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,CAAA,CACF,CAAA,EAEJ,EAGD8V,GACChW,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAAE,EAAAA,IAACsT,GAAA,CAAQ,UAAU,sBAAA,CAAuB,EACzCvU,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,CAC/C,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CC1OO,SAAS0X,GAAkB,CAAE,UAAAC,EAAW,UAAAC,GAAqC,CAClF,KAAM,CAAE,cAAA5X,CAAA,EAAkBC,EAAA,EACpB3E,EAAcC,GAAiBC,EAAiB,EAGhD,CAAE,QAASqc,CAAA,EAAkB7c,GAAA,EAC7B,CAAC8c,EAAgBC,CAAiB,EAAI3X,EAAAA,SAAsB,IAAI,GAAK,EAGrE,CAAC4X,EAAcC,CAAe,EAAI7X,EAAAA,SAA+B,CAAA,CAAE,EACnE,CAAC8X,EAAeC,CAAgB,EAAI/X,EAAAA,SAAsB,IAAI,GAAK,EACnE,CAACgY,EAAgBC,CAAiB,EAAIjY,EAAAA,SAAS,EAAK,EACpD,CAACkY,EAAYC,CAAa,EAAInY,EAAAA,SAAwB,IAAI,EAG1D,CAACoY,EAAWC,CAAY,EAAIrY,EAAAA,SAAS,EAAK,EAC1C,CAACsY,EAAYC,CAAa,EAAIvY,EAAAA,SAIjC,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,CAAA,CAAG,EAGvCK,EAAAA,UAAU,IAAM,EACW,SAAY,CACnC4X,EAAkB,EAAI,EACtBE,EAAc,IAAI,EAClB,GAAI,CACF,MAAMK,EAAQ,MAAMC,GAAA,EACpBZ,GACGW,EAAM,SAAW,CAAA,GAAI,IAAKxc,IAAO,CAChC,KAAMA,EAAE,KACR,YAAaiJ,GAAgBjJ,CAAC,EAAIA,EAAE,IAAOiK,GAAiBjK,CAAC,EAAIA,EAAE,QAAU,GAC7E,QAASA,EAAE,QACX,SAAU,EAAA,EACV,CAAA,CAEN,OAAS4J,EAAO,CACd,QAAQ,MAAM,oCAAqCA,CAAK,EACxDuS,EAAcvY,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAC,EAC9DiY,EAAgB,CAAA,CAAE,CACpB,QAAA,CACEI,EAAkB,EAAK,CACzB,CACF,GAEK,CACP,EAAG,CAACrY,CAAa,CAAC,EAGlB,MAAM8Y,EAAsBpT,GAAiB,CAC3CqS,EAAmBrV,GAAS,CAC1B,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAI+C,CAAI,EACf/C,EAAK,OAAO+C,CAAI,EAEhB/C,EAAK,IAAI+C,CAAI,EAER/C,CACT,CAAC,CACH,EAEMoW,EAAkB,IAAM,CAC5BhB,EAAkB,IAAI,IAAIF,EAAc,IAAKzb,GAAMA,EAAE,IAAI,CAAC,CAAC,CAC7D,EAEM4c,EAAiB,IAAM,CAC3BjB,EAAkB,IAAI,GAAK,CAC7B,EAGMkB,EAAqBvT,GAAiB,CAC1CyS,EAAkBzV,GAAS,CACzB,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAI+C,CAAI,EACf/C,EAAK,OAAO+C,CAAI,EAEhB/C,EAAK,IAAI+C,CAAI,EAER/C,CACT,CAAC,EACDsV,EAAiBvV,GACfA,EAAK,IAAKtG,GAAOA,EAAE,OAASsJ,EAAO,CAAE,GAAGtJ,EAAG,SAAU,CAACA,EAAE,QAAA,EAAaA,CAAE,CAAA,CAE3E,EAEM8c,EAAiB,IAAM,CAC3B,MAAMC,EAAWnB,EAAa,IAAK5b,GAAMA,EAAE,IAAI,EAC/C+b,EAAiB,IAAI,IAAIgB,CAAQ,CAAC,EAClClB,EAAiBvV,GAASA,EAAK,IAAKtG,IAAO,CAAE,GAAGA,EAAG,SAAU,EAAA,EAAO,CAAC,CACvE,EAEMgd,EAAgB,IAAM,CAC1BjB,EAAiB,IAAI,GAAK,EAC1BF,EAAiBvV,GAASA,EAAK,IAAKtG,IAAO,CAAE,GAAGA,EAAG,SAAU,EAAA,EAAQ,CAAC,CACxE,EAGMid,EAAoB,SAAY,CACpC,GAAIvB,EAAe,OAAS,EAE5B,CAAAW,EAAa,EAAI,EACjBE,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,EAElD,GAAI,CACF,MAAM9E,EAAS,MAAM7U,GAAa,CAChC,OAAQ,SACR,OAAQ,QACR,YAAa,MAAM,KAAK8Y,CAAc,EACtC,YAAaxc,GAAe,MAAA,CAC7B,EAED,GAAIuY,EAAO,QAAS,CAClB,MAAMyF,EAAczF,EAAO,OAAO,OAC5B0F,EAAc1F,EAAO,OAAO,OAElC8E,EAAc,CACZ,KAAMW,EAAc,EAAI,UAAY,UACpC,OAAQC,EACR,OAAQD,CAAA,CACT,EAED3B,GAAA,MAAAA,EAAY4B,EAAa,YAGzBxB,EAAkB,IAAI,GAAK,EAG3B,WAAW,IAAM,CACfY,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,CACpD,EAAG,GAAI,CACT,CACF,OAAS3S,EAAO,CACd,QAAQ,MAAM,2BAA4BA,CAAK,EAC/C2S,EAAc,CAAE,KAAM,UAAW,OAAQ,EAAG,OAAQb,EAAe,KAAM,CAC3E,QAAA,CACEW,EAAa,EAAK,CACpB,EACF,EAEMe,EAAsB,SAAY,CACtC,GAAI,EAAAtB,EAAc,OAAS,GAAK,CAAC5c,GAIjC,CAAAmd,EAAa,EAAI,EACjBE,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,EAElD,GAAI,CACF,MAAM9E,EAAS,MAAM7U,GAAa,CAChC,OAAQ,QACR,OAAQ,SACR,YAAa,MAAM,KAAKkZ,CAAa,EACrC,YAAA5c,CAAA,CACD,EAED,GAAIuY,EAAO,QAAS,CAClB,MAAMyF,EAAczF,EAAO,OAAO,OAC5B0F,EAAc1F,EAAO,OAAO,OAElC8E,EAAc,CACZ,KAAMW,EAAc,EAAI,UAAY,UACpC,OAAQC,EACR,OAAQD,CAAA,CACT,EAED3B,GAAA,MAAAA,EAAY4B,EAAa,cAGzBpB,EAAiB,IAAI,GAAK,EAC1BF,EAAiBvV,IAASA,GAAK,IAAKtG,KAAO,CAAE,GAAGA,GAAG,SAAU,EAAA,EAAQ,CAAC,EAGtE,WAAW,IAAM,CACfuc,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,CACpD,EAAG,GAAI,CACT,CACF,OAAS3S,EAAO,CACd,QAAQ,MAAM,6BAA8BA,CAAK,EACjD2S,EAAc,CAAE,KAAM,UAAW,OAAQ,EAAG,OAAQT,EAAc,KAAM,CAC1E,QAAA,CACEO,EAAa,EAAK,CACpB,EACF,EAGMgB,EAAc5B,EAAc,OAC5B6B,EAAiB5B,EAAe,KAChC6B,EAAa3B,EAAa,OAC1B4B,EAAgB1B,EAAc,KAEpC,cACG,MAAA,CAAI,UAAWhX,EAAG,YAAa0W,CAAS,EAEvC,SAAA,CAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,0CACX,SAAAjB,EAAc,CAAE,GAAI,gBAAA,CAAkB,EACzC,EACAiB,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAC/C,CAAA,EACF,EAGCyX,EAAW,OAAS,MACnB3X,EAAAA,KAAC,MAAA,CACC,UAAWG,EACT,gDACAwX,EAAW,OAAS,UAChB,+CACA,8CAAA,EAGL,SAAA,CAAAA,EAAW,OAAS,UACnBzX,EAAAA,IAAC4Y,GAAA,CAAa,UAAU,wBAAwB,EAEhD5Y,EAAAA,IAAC6Y,GAAA,CAAY,UAAU,uBAAA,CAAwB,QAEhD,OAAA,CAAK,UAAU,UACb,SAAApB,EAAW,OAAS,UACjB1Y,EACE,CAAE,GAAI,sBAAA,EACN,CAAE,MAAO0Y,EAAW,MAAA,CAAO,EAE7B1Y,EACE,CAAE,GAAI,sBAAA,EACN,CAAE,OAAQ0Y,EAAW,OAAQ,OAAQA,EAAW,MAAA,CAAO,CACzD,CACN,CAAA,CAAA,CAAA,EAKJ3X,EAAAA,KAAC,MAAA,CAAI,UAAU,wCAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,kDAEb,SAAA,CAAAE,EAAAA,IAAC,OAAI,UAAU,+CACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,sCACX,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAiB,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EACC,CAAE,GAAI,wBAAA,EACN,CAAE,MAAO0Z,EAAgB,MAAOD,CAAA,CAAY,CAC9C,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAGAxY,EAAAA,IAAC,MAAA,CAAI,UAAU,+BACZ,SAAAwY,IAAgB,EACfxY,EAAAA,IAAC,MAAA,CAAI,UAAU,iDACZ,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,EAEAiB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAA4W,EAAc,IAAK9a,GAClBgE,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,sEACA4W,EAAe,IAAI/a,EAAO,IAAI,EAC1B,gBACA,mBAAA,EAEN,QAAS,IAAM+b,EAAmB/b,EAAO,IAAI,EAE7C,SAAA,CAAAkE,EAAAA,IAAC8Y,GAAA,CACC,GAAI,UAAUhd,EAAO,IAAI,GACzB,QAAS+a,EAAe,IAAI/a,EAAO,IAAI,EACvC,SAAU,IAAM+b,EAAmB/b,EAAO,IAAI,EAC9C,UAAU,gBAAA,CAAA,EAEZgE,EAAAA,KAAC,QAAA,CACC,QAAS,UAAUhE,EAAO,IAAI,GAC9B,UAAU,gCAEV,SAAA,CAAAgE,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAAlE,EAAO,KACV,EACCA,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,YAAgBlE,CAAM,EACnBA,EAAO,IACNsJ,GAAiBtJ,CAAM,EAAIA,EAAO,QAAU,EAAA,CACnD,CAAA,CAAA,CAAA,CACF,CAAA,EAlCKA,EAAO,IAAA,CAoCf,EACH,CAAA,CAEJ,EAGC0c,EAAc,GACb1Y,OAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASgW,EACT,UAAU,iBAET,SAAA/Y,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,EAE7CiB,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASiW,EACT,UAAU,iBACV,SAAUU,IAAmB,EAE5B,SAAA1Z,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAC5C,CAAA,CACF,CAAA,EAEJ,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,kDAEb,SAAA,CAAAE,EAAAA,IAAC,OAAI,UAAU,+CACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,sCACX,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAC/C,EACAiB,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EACC,CAAE,GAAI,wBAAA,EACN,CAAE,MAAO4Z,EAAe,MAAOD,CAAA,CAAW,CAC5C,CACF,CAAA,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,+BACZ,SAAAvB,EACCnX,MAAC,OAAI,UAAU,wCACb,eAACsT,GAAA,CAAQ,UAAU,6CAA6C,CAAA,CAClE,EACE+D,EACFrX,MAAC,MAAA,CAAI,UAAU,4CACZ,SAAAqX,CAAA,CACH,EACEqB,IAAe,EACjB1Y,MAAC,MAAA,CAAI,UAAU,iDACZ,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,EAC7C,QAEC,MAAA,CAAI,UAAU,YACZ,SAAAgY,EAAa,IAAKjb,GACjBgE,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,sEACAnE,EAAO,SACH,gBACA,mBAAA,EAEN,QAAS,IAAMkc,EAAkBlc,EAAO,IAAI,EAE5C,SAAA,CAAAkE,EAAAA,IAAC8Y,GAAA,CACC,GAAI,SAAShd,EAAO,IAAI,GACxB,QAASA,EAAO,SAChB,SAAU,IAAMkc,EAAkBlc,EAAO,IAAI,EAC7C,UAAU,gBAAA,CAAA,EAEZgE,EAAAA,KAAC,QAAA,CACC,QAAS,SAAShE,EAAO,IAAI,GAC7B,UAAU,gCAEV,SAAA,CAAAgE,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAAlE,EAAO,KACV,EACCA,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,WAAO,WAAA,CACV,CAAA,CAAA,CAAA,CACF,CAAA,EAhCKlE,EAAO,IAAA,CAkCf,EACH,CAAA,CAEJ,EAGC4c,EAAa,GACZ5Y,OAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASmW,EACT,UAAU,iBAET,SAAAlZ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,EAE7CiB,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASqW,EACT,UAAU,iBACV,SAAUQ,IAAkB,EAE3B,SAAA5Z,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAC5C,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAASsW,EACT,SAAUK,IAAmB,GAAKlB,EAClC,QAAQ,UACR,UAAU,WAET,WACCzX,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAClD,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC+Y,GAAA,CAAW,UAAU,cAAA,CAAe,EACpCha,EACC,CAAE,GAAI,sBAAA,EACN,CAAE,MAAO0Z,CAAA,CAAe,CAC1B,CAAA,CACF,CAAA,CAAA,EAIJzY,EAAAA,IAAC8B,EAAA,CACC,QAASyW,EACT,SAAUI,IAAkB,GAAKpB,GAAa,CAACld,EAC/C,QAAQ,UACR,UAAU,WAET,WACCyF,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAClD,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACgZ,GAAA,CAAU,UAAU,cAAA,CAAe,EACnCja,EACC,CAAE,GAAI,wBAAA,EACN,CAAE,MAAO4Z,CAAA,CAAc,CACzB,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,EACF,CAEJ,CCndO,SAASM,GAAiB,CAC/B,eAAAC,EACA,gBAAAC,EACA,UAAAxC,EACA,YAAAyC,EACA,aAAcC,CAChB,EAA0B,CACxB,KAAM,CAAE,cAAAta,CAAA,EAAkBC,EAAA,EACpB,CAACsa,EAAWC,CAAY,EAAIpa,EAAAA,SAAkD,cAAc,EAC5F,CAACqa,EAAeC,CAAgB,EAAIta,EAAAA,SAAyB,MAAM,EACnE,CAACua,EAAcC,CAAe,EAAIxa,EAAAA,SAA+B,CAAA,CAAE,EACnE,CAACya,EAAgBC,CAAiB,EAAI1a,EAAAA,SAAS,EAAK,EAEpD,CAAE,SAAAyV,EAAU,eAAAkF,EAAgB,UAAAC,CAAA,EAAcpc,GAAA,EAI1Cqc,EAAkBC,EAAAA,QAAQ,IAAM,CACpC,MAAMrP,EAASyO,GAAoBzE,EACnC,OAAOwE,EAAcxO,EAAO,MAAM,EAAGwO,CAAW,EAAIxO,CACtD,EAAG,CAACyO,EAAkBzE,EAAUwE,CAAW,CAAC,EAG5C5Z,EAAAA,UAAU,IAAM,EACK,SAAY,CAC7B,GAAIwa,EAAgB,SAAW,EAAG,CAChCL,EAAgB,CAAA,CAAE,EAClB,MACF,CAEAE,EAAkB,EAAI,EACtB,GAAI,CACF,MAAMzE,EAAW,MAAMnX,GAA0B+b,CAAe,EAC1DE,EAA8BF,EAAgB,IAAKhM,GAAS,CAChE,MAAMmM,EAAYnM,IAAS8L,EACrBrV,EAAOuJ,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EACpDzR,EAAU6Y,EAAS,QAAQpH,CAAI,GAAK,CAAA,EAE1C,MAAO,CACL,KAAAvJ,EACA,KAAAuJ,EACA,YAAazR,EAAQ,OACrB,aAAcA,EAAQ,OAAQpB,GAAMA,EAAE,OAAO,EAAE,OAC/C,aAAc,OACd,UAAAgf,CAAA,CAEJ,CAAC,EACDR,EAAgBO,CAAK,CACvB,OAASnV,EAAO,CACd,QAAQ,MAAM,wCAAyCA,CAAK,EAE5D4U,EACEK,EAAgB,IAAKhM,IAAU,CAC7B,KAAMA,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EACnD,KAAAA,EACA,YAAa,EACb,aAAc,EACd,UAAWA,IAAS8L,CAAA,EACpB,CAAA,CAEN,QAAA,CACED,EAAkB,EAAK,CACzB,CACF,GAEK,CACP,EAAG,CAACG,EAAiBF,CAAc,CAAC,EAGpC,MAAMM,EAAiB,CAAC,GAAGV,CAAY,EAAE,KAAK,CAACxT,EAAGmU,IAAM,CACtD,IAAIC,EAAa,EAEjB,OAAQhB,EAAA,CACN,IAAK,OACHgB,EAAapU,EAAE,KAAK,cAAcmU,EAAE,IAAI,EACxC,MACF,IAAK,cACHC,EAAapU,EAAE,YAAcmU,EAAE,YAC/B,MACF,IAAK,eACHC,EAAapU,EAAE,cAAgBmU,EAAE,aAC7B,IAAI,KAAKnU,EAAE,YAAY,EAAE,QAAA,EAAY,IAAI,KAAKmU,EAAE,YAAY,EAAE,UAC9D,EACJ,KAAA,CAGJ,OAAOb,IAAkB,MAAQc,EAAa,CAACA,CACjD,CAAC,EAGKC,EAAcjZ,GAA4B,CAC1CgY,IAAchY,EAChBmY,EAAkBhY,GAAUA,IAAS,MAAQ,OAAS,KAAM,GAE5D8X,EAAajY,CAAK,EAClBmY,EAAiB,MAAM,EAE3B,EAGMe,EAAsBngB,GAAwB,CAClD6e,GAAA,MAAAA,EAAiB7e,EACnB,EAGMogB,EAAsB,CAAC5Y,EAAqBxH,IAAwB,CACxEwH,EAAE,gBAAA,EACFsX,GAAA,MAAAA,EAAkB9e,EACpB,EAEA,OAAI0f,GAAaH,EAEb5Z,EAAAA,IAACwJ,EAAA,CAAK,UAAWvJ,EAAG,MAAO0W,CAAS,EAClC,SAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,qCAAqC,SAAA,IAAC,EACrDA,MAAC,QAAK,UAAU,qCACb,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,CAAA,CACF,CAAA,CACF,EAIAoa,EAAe,SAAW,EAE1Bpa,EAAAA,IAACwJ,EAAA,CAAK,UAAWvJ,EAAG,MAAO0W,CAAS,EAClC,SAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,iDAAA,CAAkD,EACpEnN,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAChD,CAAA,CAAA,CACF,CAAA,CACF,SAKDwJ,EAAA,CAAK,UAAWvJ,EAAG,kBAAmB0W,CAAS,EAE9C,SAAA,CAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,2HACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMya,EAAW,MAAM,EAChC,UAAU,kEAET,SAAA,CAAAxb,EAAc,CAAE,GAAI,uBAAwB,EAC5Cua,IAAc,QACbtZ,MAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAwZ,IAAkB,MAAQ,IAAM,GAAA,CAAI,CAAA,CAAA,CAAA,EAG7E,EACAxZ,EAAAA,IAAC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMya,EAAW,aAAa,EACvC,UAAU,kEAET,SAAA,CAAAxb,EAAc,CAAE,GAAI,0BAA2B,EAC/Cua,IAAc,eACbtZ,MAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAwZ,IAAkB,MAAQ,IAAM,GAAA,CAAI,CAAA,CAAA,CAAA,EAG7E,EACAxZ,EAAAA,IAAC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMya,EAAW,cAAc,EACxC,UAAU,kEAET,SAAA,CAAAxb,EAAc,CAAE,GAAI,+BAAgC,EACpDua,IAAc,gBACbtZ,MAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAwZ,IAAkB,MAAQ,IAAM,GAAA,CAAI,CAAA,CAAA,CAAA,EAG7E,EACAxZ,MAAC,OAAI,UAAU,wBACZ,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,QAGC,MAAA,CAAI,UAAU,yBACZ,SAAAoa,EAAe,IAAKM,GACnB5a,EAAAA,KAAC,MAAA,CAEC,QAAS,IAAM0a,EAAmBE,EAAQ,IAAI,EAC9C,UAAWza,EACT,oGACAya,EAAQ,WAAa,kCAAA,EAIvB,SAAA,CAAA1a,EAAAA,IAAC,OAAI,UAAU,qBACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,6CAAA,CAA8C,EAChErN,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAA0a,EAAQ,KACX,EACCA,EAAQ,WACP1a,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,WAAQ,IAAA,CACX,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACmO,GAAA,CAAS,UAAU,+BAAA,CAAgC,EACpDrO,EAAAA,KAAC,OAAA,CAAK,UAAU,0BACb,SAAA,CAAA4a,EAAQ,YAAY,IAAE3b,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,EACxE,EACAe,EAAAA,KAACoI,EAAA,CACC,QAAQ,UACR,UAAWjI,EACT,UACAya,EAAQ,aAAe,EAAI,iCAAmC,uBAAA,EAG/D,SAAA,CAAAA,EAAQ,aAAa,IAAE3b,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAAA,CACpE,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,aACb,SAAAe,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAAE,EAAAA,IAAC2a,GAAA,CAAM,UAAU,SAAA,CAAU,EAC3B3a,EAAAA,IAAC,OAAA,CACE,SAAA0a,EAAQ,aACLE,GAAoB,IAAI,KAAKF,EAAQ,YAAY,EAAG,CAAE,UAAW,EAAA,CAAM,EACvE,GAAA,CACN,CAAA,CAAA,CACF,CAAA,CACF,EAGA1a,EAAAA,IAAC,MAAA,CAAI,UAAU,oCACb,SAAAA,EAAAA,IAAC,SAAA,CACC,QAAU6B,GAAM4Y,EAAoB5Y,EAAG6Y,EAAQ,IAAI,EACnD,UAAU,iDACV,MAAO3b,EAAc,CAAE,GAAI,gCAAiC,EAE5D,SAAAiB,EAAAA,IAAC6a,GAAA,CAAa,UAAU,+BAAA,CAAgC,CAAA,CAAA,CAC1D,CACF,CAAA,CAAA,EArEKH,EAAQ,IAAA,CAuEhB,EACH,EAGA1a,EAAAA,IAAC,MAAA,CAAI,UAAU,6EACZ,SAAAjB,EACC,CAAE,GAAI,yBAAA,EACN,CAAE,MAAOqb,EAAe,MAAA,CAAO,CACjC,CACF,CAAA,EACF,CAEJ,CC7PO,SAASU,GAAqB,CACnC,gBAAAC,EACA,UAAApE,CACF,EAA8B,CAC5B,KAAM,CAAE,cAAA5X,CAAA,EAAkBC,EAAA,EACpB,CAACgc,EAAqBC,CAAsB,EAAI9b,EAAAA,SAAwB,IAAI,EAC5E,CAAC+b,EAAcC,CAAe,EAAIhc,EAAAA,SAA+B,CAAA,CAAE,EACnE,CAACic,EAAmBC,CAAoB,EAAIlc,EAAAA,SAAS,EAAK,EAE1D,CAAE,SAAAyV,EAAU,eAAAkF,EAAgB,kBAAA5b,EAAmB,kBAAmBod,CAAA,EACtE3d,GAAA,EACI,CAAE,aAAA4d,EAAc,WAAAC,CAAA,EAAe7e,GAAA,EAG/B8e,EAAoB7G,EAAS,OAAQ8G,GAAMA,IAAM5B,CAAc,EAG/D6B,EAAsB,MAAOthB,GAAwB,CACzD4gB,EAAuB5gB,CAAW,EAClCghB,EAAqB,EAAI,EAEzB,GAAI,CACF,MAAMjG,EAAW,MAAMlX,EAAkB,CAAC7D,CAAW,CAAC,EAChDkC,EAAgC,CAAA,EAEtC,SAAW,CAACyR,EAAM4N,CAAU,IAAK,OAAO,QAAQxG,EAAS,OAAO,EAAG,CACjE,MAAMyG,EAAc7N,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EACjE,UAAWlS,KAAW8f,EACpBrf,EAAQ,KAAK,CACX,KAAMT,EAAO,KACb,QAASA,EAAO,QAChB,YAAasI,GAAgBtI,CAAM,EAC/BA,EAAO,IACNsJ,GAAiBtJ,CAAM,EAAIA,EAAO,QAAU,GACjD,UAAWA,EAAO,UAClB,YAAakS,EACb,YAAA6N,EACA,eAAgB/f,CAAA,CACjB,CAEL,CAEAqf,EAAgB5e,CAAO,CACzB,OAASwI,EAAO,CACd,QAAQ,MAAM,0CAA2CA,CAAK,EAC9DoW,EAAgB,CAAA,CAAE,CACpB,QAAA,CACEE,EAAqB,EAAK,CAC5B,CACF,EAGMS,EAAqB,MAAOhgB,GAA+B,CAC/D,GAAI,CAEF,MAAMigB,EAAa,GAAGjgB,EAAO,WAAW,IAAIA,EAAO,IAAI,GAAG,YAAA,EAAc,QAAQ,OAAQ,GAAG,EAGrFkgB,EAA4B,CAChC,GAAGlgB,EAAO,eACV,KAAMigB,EACN,MAAO,SAAA,EAGT,MAAMR,EAAaS,CAAc,EAEjCjB,GAAA,MAAAA,EAAkBgB,EAAYjgB,EAAO,YACvC,OAASiJ,EAAO,CACd,QAAQ,MAAM,2BAA4BA,CAAK,CACjD,CACF,EAEMgV,EAAYqB,GAAqBE,GAAoBE,EACrDS,EAAsBjB,EACxBA,EAAoB,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,EACnD,KAEJ,cACGxR,EAAA,CAAK,UAAWvJ,EAAG,MAAO0W,CAAS,EAElC,SAAA,CAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC2N,GAAA,CAAW,UAAU,sBAAA,CAAuB,EAC7C3N,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EACAA,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS,IAAMkZ,GAAuBW,EAAoBX,CAAmB,EAC7E,SAAU,CAACA,GAAuBjB,EAClC,UAAU,MAEV,eAACmC,GAAA,CAAU,UAAWjc,EAAG,UAAW8Z,GAAa,cAAc,CAAA,CAAG,CAAA,CAAA,CACpE,EACF,EAGA/Z,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,+BAAA,CAAiC,EACxD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,OACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,iDACd,SAAAjB,EAAc,CAAE,GAAI,iCAAA,CAAmC,EAC1D,SACC2I,GAAA,CAAO,MAAOsT,GAAuB,GAAI,cAAeW,EACvD,SAAA,CAAA3b,EAAAA,IAAC2H,GAAA,CAAc,UAAU,SACvB,SAAA3H,EAAAA,IAAC4H,GAAA,CACC,YAAa7I,EAAc,CAAE,GAAI,6CAA8C,CAAA,CAAA,EAEnF,QACC8I,GAAA,CACE,SAAA4T,EAAkB,SAAW,EAC5Bzb,EAAAA,IAAC,OAAI,UAAU,gDACZ,WAAc,CAAE,GAAI,+BAAgC,CAAA,CACvD,EAEAyb,EAAkB,IAAKzN,GAAS,CAC9B,MAAMvJ,EAAOuJ,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EAC1D,aACGlG,GAAA,CAAsB,MAAOkG,EAC5B,SAAAlO,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC2N,GAAA,CAAW,UAAU,+BAAA,CAAgC,EACtD3N,EAAAA,IAAC,OAAA,CAAK,UAAU,WAAY,SAAAyE,CAAA,CAAK,CAAA,CAAA,CACnC,GAJeuJ,CAKjB,CAEJ,CAAC,CAAA,CAEL,CAAA,CAAA,CACF,CAAA,EACF,EAGCgN,SACE,MAAA,CAAI,UAAU,YACZ,SAAAI,EACCtb,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,qCAAqC,SAAA,IAAC,EACrDA,MAAC,QAAK,UAAU,qCACb,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,CAAA,CACF,EACEkb,EAAa,SAAW,EAC1Blb,EAAAA,IAAC,MAAA,CAAI,UAAU,gFACZ,SAAAjB,EACC,CAAE,GAAI,6BAAA,EACN,CAAE,QAASkd,CAAA,CAAoB,CACjC,CACF,EAEAjc,EAAAA,IAAC,MAAA,CAAI,UAAU,qCACZ,SAAAkb,EAAa,IAAKpf,GACjBgE,EAAAA,KAAC,MAAA,CAEC,UAAU,yFAEV,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAAlE,EAAO,KACV,EACCA,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,WAAO,YACV,EACAF,EAAAA,KAAC,IAAA,CAAE,UAAU,yCACX,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,SAAAlE,EAAO,YAAY,EAClDkE,EAAAA,IAACqN,GAAA,CAAa,UAAU,qBAAA,CAAsB,EAC9CrN,EAAAA,IAAC,OAAA,CAAK,UAAU,YAAa,WAAO,WAAA,CAAY,CAAA,CAAA,CAClD,CAAA,EACF,EACAF,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMga,EAAmBhgB,CAAM,EACxC,SAAU0f,EACV,UAAU,gBAEV,SAAA,CAAAxb,EAAAA,IAAC8O,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B/P,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CAAA,CAAA,CACnD,CAAA,EAhCK,GAAGjD,EAAO,WAAW,IAAIA,EAAO,IAAI,EAAA,CAkC5C,EACH,CAAA,CAEJ,EAIDkf,GAAuBE,EAAa,OAAS,GAC5Clb,EAAAA,IAAC,IAAA,CAAE,UAAU,qCACV,SAAAjB,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EAEJ,CAEJ,CClLA,SAASqJ,GAAgB7G,EAAuB,CAC9C,MAAI,CAACA,GAASA,EAAM,QAAU,EAAU,OACjCA,EAAM,UAAU,EAAG,CAAC,EAAI,MACjC,CAEA,SAAS4a,GAAc,CAAE,OAAArgB,EAAQ,WAAAwM,EAAY,eAAAC,EAAgB,SAAAG,EAAU,OAAA0T,EAAQ,SAAA7N,EAAU,iBAAAsB,EAAkB,aAAAwM,GAAoC,CAC7I,KAAM,CAAE,cAAAtd,CAAA,EAAkBC,EAAA,EACpB,CAAC+J,EAAkBC,CAAmB,EAAI7J,EAAAA,SAAkC,CAAA,CAAE,EAE9E8J,EAAS7E,GAAgBtI,CAAM,EAC/BoN,EAAU9D,GAAiBtJ,CAAM,EAGjCqN,EAAmB,IAAM,OAC7B,OAAIF,EACKnN,EAAO,IAET,GAAGA,EAAO,OAAO,MAAIlB,EAAAkB,EAAO,OAAP,YAAAlB,EAAa,KAAK,OAAQ,EAAE,GAAG,KAAA,CAC7D,EAGMwO,EAAiB,IAAkE,CACvF,GAAI,CAACH,EAAQ,MAAO,CAAA,EAEpB,MAAMtI,EAAsE,CAAA,EAG5E,OAAI7E,EAAO,SACT,OAAO,QAAQA,EAAO,OAAO,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CACxDZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAICzF,EAAO,aACT,OAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CAC5DZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAICzF,EAAO,mBACT6E,EAAQ,KAAK,CACX,KAAM,gBACN,MAAO,WAAW7E,EAAO,iBAAiB,GAC1C,SAAU,EAAA,CACX,EAGI6E,CACT,EAGM0I,EAAqBnE,GAAuB,CAChD8D,EAAoBvH,IAAS,CAC3B,GAAGA,EACH,CAACyD,CAAU,EAAG,CAACzD,EAAKyD,CAAU,CAAA,EAC9B,CACJ,EAEA,OACEpF,OAAC0J,GAAK,UAAWvJ,EAAG,kBAAmB,CAACnE,EAAO,SAAW,YAAY,EAEpE,SAAA,CAAAkE,EAAAA,IAAC,MAAA,CACC,UAAU,yDACV,QAASuI,EAET,SAAAzI,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,iBACAnE,EAAO,QAAU,gBAAkB,UAAA,EAEnC,SAAAkE,EAAAA,IAACyJ,GAAA,CAAO,UAAWxJ,EACjB,UACAnE,EAAO,QAAU,eAAiB,uBAAA,EACjC,CAAA,CACL,SACC,MAAA,CACC,SAAA,CAAAgE,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAlE,EAAO,KACV,EAECmN,GACCnJ,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,wCACjC,SAAA,CAAAlI,EAAAA,IAAC0J,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B3K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEFiB,EAAAA,IAACkI,EAAA,CAAM,QAASpM,EAAO,QAAU,SAAW,UAAY,YAAa,UAAU,UAC5E,SAAAA,EAAO,QAAU,SAChBgE,OAAAC,EAAAA,SAAA,CAAE,SAAA,CAAAC,EAAAA,IAACgI,GAAA,CAAM,UAAU,cAAA,CAAe,EAAGjJ,EAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAAA,CAAE,EAE/Ee,EAAAA,KAAAC,EAAAA,SAAA,CAAE,SAAA,CAAAC,EAAAA,IAACmN,GAAA,CAAO,UAAU,cAAA,CAAe,EAAGpO,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAAE,CAAA,CAErF,EACCsd,GACCvc,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,4CACjC,SAAA,CAAAlI,EAAAA,IAACoN,GAAA,CAAc,UAAU,cAAA,CAAe,EACvCrO,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEDjD,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,yBAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,MAAC,KAAE,UAAU,iEAAiE,MAAOmJ,EAAA,EAClF,YAAiB,CACpB,CAAA,CAAA,CACF,CAAA,EACF,EACArJ,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACF6G,EAAS5M,EAAO,KAAM,CAACA,EAAO,OAAO,CACvC,EAEC,SAAAA,EAAO,QAAUkE,EAAAA,IAAC4J,GAAA,CAAM,UAAU,yBAAyB,EAAK5J,EAAAA,IAAC8J,GAAA,CAAS,UAAU,SAAA,CAAU,CAAA,CAAA,EAEjG9J,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACFgO,EAAiB/T,CAAM,CACzB,EACA,MAAOiD,EAAc,CAAE,GAAI,uCAAwC,EAEnE,SAAAiB,EAAAA,IAACsc,GAAA,CAAa,UAAU,sBAAA,CAAuB,CAAA,CAAA,EAEjDtc,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACFua,EAAOtgB,CAAM,CACf,EAEA,SAAAkE,EAAAA,IAACuc,GAAA,CAAK,UAAU,SAAA,CAAU,CAAA,CAAA,EAE5Bvc,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACF0M,EAASzS,CAAM,CACjB,EAEA,SAAAkE,EAAAA,IAACiC,GAAA,CAAO,UAAU,0BAAA,CAA2B,CAAA,CAAA,EAE9CqG,QACE0B,GAAA,CAAU,UAAU,gCAAgC,EAErDhK,MAACiK,GAAA,CAAY,UAAU,+BAAA,CAAgC,CAAA,CAAA,CAE3D,CAAA,CAAA,CACF,CAAA,CAAA,EAID3B,GACCxI,EAAAA,KAAC,MAAA,CAAI,UAAU,mDAEZ,SAAA,CAAAmJ,GACCnJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,cAAA,CAAgB,EAAE,EACzFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,0EACb,WAAO,GAAA,CACV,CAAA,EACF,EAGCoJ,EAAA,EAAiB,OAAS,UACxB,MAAA,CACC,SAAA,CAAApJ,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,kBAAA,CAAoB,EAAE,EAC7FiB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAAoJ,EAAA,EAAiB,IAAKzH,GACrB7B,EAAAA,KAAC,MAAA,CAAsB,UAAU,kCAC/B,SAAA,CAAAE,MAACkI,GAAM,QAAQ,YAAY,UAAU,YAAa,WAAO,KAAK,EAC9DlI,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAA+I,EAAiBpH,EAAO,IAAI,EAAIA,EAAO,MAAQyG,GAAgBzG,EAAO,KAAK,EAC9E,EACA3B,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS,IAAMuH,EAAkB1H,EAAO,IAAI,EAC5C,MAAOoH,EAAiBpH,EAAO,IAAI,EAC/B5C,EAAc,CAAE,GAAI,oBAAA,CAAsB,EAC1CA,EAAc,CAAE,GAAI,qBAAsB,EAE7C,SAAAgK,EAAiBpH,EAAO,IAAI,EAC3B3B,EAAAA,IAAC+B,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAElD/B,EAAAA,IAACgC,GAAA,CAAI,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAGlDL,EAAO,UACN3B,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAChC,SAAAnJ,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAC1C,CAAA,GAxBM4C,EAAO,IA0BjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAIDuH,GACCpJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,aAAA,CAAe,EAAE,EACxFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,gEACb,WAAO,OAAA,CACV,CAAA,EACF,EAGClE,EAAO,MAAQA,EAAO,KAAK,OAAS,UAClC,MAAA,CACC,SAAA,CAAAkE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,UAAA,CAAY,EAAE,QACpF,MAAA,CAAI,UAAU,uBACZ,SAAAjD,EAAO,KAAK,IAAI,CAACmM,EAAKvD,IACrB1E,EAAAA,IAACkI,EAAA,CAAgB,QAAQ,UAAU,UAAU,oBAC1C,SAAAD,CAAA,EADSvD,CAEZ,CACD,CAAA,CACH,CAAA,EACF,EAID5I,EAAO,KAAO,OAAO,KAAKA,EAAO,GAAG,EAAE,OAAS,GAC9CgE,EAAAA,KAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,SAAA,CAAW,EAAE,QACnF,MAAA,CAAI,UAAU,YACZ,SAAA,OAAO,QAAQjD,EAAO,GAAG,EAAE,IAAI,CAAC,CAAC0K,EAAKjF,CAAK,IAC1CzB,EAAAA,KAAC,MAAA,CAAc,UAAU,kCACvB,SAAA,CAAAE,MAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,YAAa,SAAA1B,EAAI,EACtDxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAAuB,CAAA,CACH,CAAA,CAAA,EALQiF,CAMV,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAID6V,GACCvc,EAAAA,KAAC,MAAA,CAAI,UAAU,8GACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+DACb,SAAA,CAAAE,EAAAA,IAACoN,GAAA,CAAc,UAAU,SAAA,CAAU,EACnCpN,MAAC,QAAK,UAAU,sBAAuB,WAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAE,CAAA,EACrF,EACAA,MAAC,KAAE,UAAU,kDACV,WAAc,CAAE,GAAI,4BAA8B,CAAE,MAAOjB,EAAc,CAAE,GAAI,aAAasd,EAAa,cAAc,EAAA,CAAI,CAAA,CAAG,EACjI,EACArc,MAAC,KAAE,UAAU,kDACV,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EAEJ,CAEJ,CAIO,SAASwc,IAAiB,WAC/B,KAAM,CAAE,cAAAzd,CAAA,EAAkBC,EAAA,EACpB,CAACyd,EAAWC,CAAY,EAAIvd,EAAAA,SAAgD,SAAS,EACrF,CAAC2Q,EAAaC,CAAc,EAAI5Q,EAAAA,SAAS,EAAE,EAC3C,CAACwd,EAAaC,CAAc,EAAIzd,EAAAA,SAAuC,KAAK,EAC5E,CAAC0d,EAAiBC,CAAkB,EAAI3d,EAAAA,SAAsB,IAAI,GAAK,EACvE,CAAC4d,EAAYC,CAAa,EAAI7d,EAAAA,SAAS,EAAK,EAC5C,CAAC8d,EAAeC,CAAgB,EAAI/d,EAAAA,SAAgC,MAAS,EAC7E,CAACge,EAASC,CAAU,EAAIje,EAAAA,SAAkB,QAAQ,EAClD,CAACke,EAAsBC,CAAuB,EAAIne,EAAAA,SAAsB,IAAI,GAAK,EACjF,CAACoe,EAAwBC,CAAyB,EAAIre,EAAAA,SAAS,EAAK,EACpE,CAACse,EAAwBC,CAAyB,EAAIve,EAAAA,SAAgC,MAAS,EAE/FhF,EAAcC,GAAA,EACdujB,EAAgBjb,GAAA,EAEhB,CACJ,QAAAnG,EACA,eAAA5B,EACA,cAAAE,EACA,UAAAE,EACA,WAAA6iB,EACA,aAAAC,EACA,UAAA9D,EACA,WAAA+D,EACA,QAAA1iB,CAAA,EACErB,GAAc,CAChB,MAAO4iB,IAAgB,MAAQ,OAAYA,CAAA,CAC5C,EAGKoB,EAAatjB,GAAS,CAC1B,SAAU,CAAC,iBAAiB,EAC5B,QAASmd,GACT,QAASuF,IAAY,QACrB,UAAW,IAAS,GAAA,CACrB,EAEK9iB,EAAcC,GAAiBC,EAAiB,EAGhDyjB,GAAcvjB,GAAS,CAC3B,SAAU,CAAC,eAAgBJ,CAAW,EACtC,QAAS,IAAM4jB,GAAkB5jB,GAAe,MAAS,EACzD,QAAS8iB,IAAY,SACrB,UAAW,IAAS,GAAA,CACrB,EAGKe,GAAmBzjB,GAAS,CAChC,SAAU,CAAC,mBAAmB,EAC9B,QAAS0jB,GACT,QAAShB,IAAY,QACrB,UAAW,IAAS,GAAA,CACrB,EAEK,CACJ,aAAAiB,GACA,aAAAC,EAAA,EACE1hB,GAAA,EAEE2hB,GAAgB7iB,GAAuB,CAC3CqhB,EAAoBrb,GAAS,CAC3B,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAIjG,CAAU,EACrBiG,EAAK,OAAOjG,CAAU,EAEtBiG,EAAK,IAAIjG,CAAU,EAEdiG,CACT,CAAC,CACH,EAEM6c,GAAqB9iB,GAAuB,CAChD6hB,EAAyB7b,GAAS,CAChC,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAIjG,CAAU,EACrBiG,EAAK,OAAOjG,CAAU,EAEtBiG,EAAK,IAAIjG,CAAU,EAEdiG,CACT,CAAC,CACH,EAEM4H,GAAe,CAAC7N,EAAoBvB,IAAqB,CAC7DkkB,GAAa3iB,EAAYvB,CAAO,CAClC,EAEMyU,EAAe,MAAO7S,GAAsB,CAChD,GAAI,QAAQiD,EAAc,CAAE,GAAI,mBAAA,EAAuB,CAAE,KAAMjD,EAAO,IAAA,CAAM,CAAC,EAC3E,GAAI,CACF,MAAMuiB,GAAaviB,EAAO,KAAMA,EAAO,KAAK,EAC5C6hB,EAAc,QACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CjD,EAAO,IAAA,EAETV,EAAA,CACF,OAAS2J,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,EACnD4Y,EAAc,MACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CAEJ,EAEMyZ,GAAc1iB,GAAsB,CACxCohB,EAAiBphB,CAAM,EACvBkhB,EAAc,EAAI,CACpB,EAEMyB,GAAiB,IAAM,CAC3BvB,EAAiB,MAAS,EAC1BF,EAAc,EAAI,CACpB,EAEM0B,GAAoB,IAAM,CAC9B1B,EAAc,EAAK,EACnBE,EAAiB,MAAS,CAC5B,EAEMyB,GAAmB,IAAM,CAC7B3B,EAAc,EAAK,EACnBE,EAAiB,MAAS,EAC1B9hB,EAAA,CACF,EAEMwjB,GAAoBxc,GAAkB,CAC1Cgb,EAAWhb,CAAI,CACjB,EAGMyc,GAAYb,GAAY,MAAQ,CACpC,YAAa,GACb,aAAc,CAAA,EACd,YAAa,OACb,YAAa,OACb,cAAe,OACf,gBAAiB,CAAA,CAAC,EAGdc,EAAiB,CAAC,eAAgBzkB,CAAW,EAE7C0kB,EAAsB,MAAOxR,EAAcrT,IAAqB,CAEpE,MAAM8kB,EAAgB7kB,EAAY,aAA2B2kB,CAAc,GAAKD,GAC1EI,EAAeD,EAAc,aAC7BE,EAAiB/kB,EAAY,aAA2B2kB,CAAc,EAEtEK,GAAejlB,EAChB+kB,EAAa,SAAS1R,CAAI,EAAI0R,EAAe,CAAC,GAAGA,EAAc1R,CAAI,EACpE0R,EAAa,OAAQ9hB,GAAMA,IAAMoQ,CAAI,EAGzCpT,EAAY,aAAa2kB,EAAiBziB,GACnCA,GACE,CAAE,GAAGA,EAAK,aAAc8iB,EAAA,CAChC,EAED,GAAI,CACF,MAAM1S,GAAgB,CAAE,GAAGuS,EAAe,aAAcG,GAAc,CACxE,OAASpa,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,6BAA8BA,CAAK,EACjD5K,EAAY,aAAa2kB,EAAgBI,CAAc,CACzD,CACAlB,GAAY,QAAA,CACd,EAEMoB,EAAwB,MAAO1jB,GAAkC,CAErE,MAAMwjB,EAAiB/kB,EAAY,aAA2B2kB,CAAc,EAG5E3kB,EAAY,aAAa2kB,EAAiBziB,GACnCA,GACE,CAAE,GAAGA,EAAK,GAAGX,CAAA,CACrB,EAGD,MAAMsjB,EAAgB7kB,EAAY,aAA2B2kB,CAAc,GAAKD,GAEhF,GAAI,CAEF,MAAMpS,GAAgB,CACpB,aAAcuS,EAAc,aAC5B,YAAaA,EAAc,YAC3B,YAAaA,EAAc,YAC3B,cAAeA,EAAc,aAAA,CAC9B,CACH,OAASja,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,+BAAgCA,CAAK,EACnD5K,EAAY,aAAa2kB,EAAgBI,CAAc,CACzD,CACAlB,GAAY,QAAA,CACd,EAEMqB,EAAmB,IAAM,CAC7BrB,GAAY,QAAA,CACd,EAGMsB,GAAcrF,EAAAA,QAAQ,IAAM,CAChC,MAAMsF,MAAU,IAChB,UAAWC,KAAKzkB,EAAWwkB,EAAI,IAAIC,EAAE,KAAMA,CAAC,EAC5C,OAAOD,CACT,EAAG,CAACxkB,CAAS,CAAC,EAGR0kB,GAA0B,MAAOjmB,GAAgC,CACrE,GAAI,CACF,MAAM2S,GAAc3S,EAAOA,IAAU,UAAYa,GAAe,OAAY,MAAS,EACrF2jB,GAAY,QAAA,CACd,OAASjZ,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,2BAAA,CAA6B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC9H,QAAQ,MAAM,sCAAuCA,CAAK,CAC5D,CACF,EAEM2a,GAA8B,MAAOlmB,GAAgC,CACzE,GAAI,CACF,MAAMmmB,GAAyBnmB,EAAOA,IAAU,UAAYa,GAAe,OAAY,MAAS,EAChG2jB,GAAY,QAAA,EACZ7jB,EAAY,kBAAkB,CAAE,SAAU,CAAC,YAAY,EAAG,CAC5D,OAAS4K,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,6BAAA,CAA+B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAChI,QAAQ,MAAM,0CAA2CA,CAAK,CAChE,CACF,EAGM6a,GAAiB1B,GAAiB,MAAQ,CAC9C,YAAa,GACb,aAAc,CAAA,EACd,YAAa,OACb,YAAa,OACb,cAAe,OACf,gBAAiB,CAAA,CAAC,EAGd2B,GAA2B,MAAOtS,EAAcrT,IAAqB,CACzE,MAAM8kB,EAAgB7kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,GAAKylB,GACjFX,EAAeD,EAAc,aAC7BE,EAAiB/kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,EAE7EglB,GAAejlB,EAChB+kB,EAAa,SAAS1R,CAAI,EAAI0R,EAAe,CAAC,GAAGA,EAAc1R,CAAI,EACpE0R,EAAa,OAAQ9hB,GAAMA,IAAMoQ,CAAI,EAEzCpT,EAAY,aAAa,CAAC,mBAAmB,EAAIkC,GAC1CA,GACE,CAAE,GAAGA,EAAK,aAAc8iB,EAAA,CAChC,EAED,GAAI,CACF,MAAM3S,GAAwB,CAAE,GAAGwS,EAAe,aAAcG,GAAc,CAChF,OAASpa,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,qCAAsCA,CAAK,EACzD5K,EAAY,aAAa,CAAC,mBAAmB,EAAG+kB,CAAc,CAChE,CACAhB,GAAiB,QAAA,CACnB,EAEM4B,GAA6B,MAAOpkB,GAAkC,CAC1E,MAAMsjB,EAAgB7kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,GAAKylB,GACjFV,EAAiB/kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,EAEnFA,EAAY,aAAa,CAAC,mBAAmB,EAAIkC,GAC1CA,GACE,CAAE,GAAGA,EAAK,GAAGX,CAAA,CACrB,EAED,GAAI,CACF,MAAM8Q,GAAwB,CAAE,GAAGwS,EAAe,GAAGtjB,EAAQ,CAC/D,OAASqJ,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,uCAAwCA,CAAK,EAC3D5K,EAAY,aAAa,CAAC,mBAAmB,EAAG+kB,CAAc,CAChE,CACAhB,GAAiB,QAAA,CACnB,EAEM6B,GAAwB,IAAM,CAClC7B,GAAiB,QAAA,CACnB,EAGM/M,GAAyBrL,GAAkB,CAC/C,MAAMtB,GAAesB,GAAA,YAAAA,EAAU,eAAgB,CAAA,EACzCmD,EACJzE,EAAa,OAAS,QACtBA,EAAa,YAAc,QAC3B,OAAOA,EAAa,KAAQ,SAG5B0Y,EADEjU,EACe,CACf,KAAMnD,EAAS,KACf,UAAW,OACX,IAAKtB,EAAa,KAAO,GACzB,MAAO,UACP,QAAS,EAAA,EAGM,CACf,KAAMsB,EAAS,KACf,UAAW,QACX,QAAStB,EAAa,QACtB,KAAMA,EAAa,MAAQ,CAAA,EAC3B,IAAKA,EAAa,IAClB,MAAO,UACP,QAAS,EAAA,CATV,EAYHwY,EAAc,EAAI,CACpB,EAEMgD,GAA8BlkB,GAAsB,CACxD4hB,EAA0B5hB,CAAM,EAChC0hB,EAA0B,EAAI,CAChC,EAEMyC,GAAuB,MAC3Bxb,EACA/K,EACA4V,EACA9K,IACG,CACH,GAAI,CACF,MAAMoO,EAAS,MAAMzL,GAAgB,CACnC,KAAA1C,EACA,YAAa6K,GAAe,OAC5B,SAAU5V,GAAY,SACtB,aAAc,CACZ,QAAS8K,EAAa,QACtB,KAAMA,EAAa,KAAK,OAAS,EAAIA,EAAa,KAAO,OACzD,IAAK,OAAO,KAAKA,EAAa,GAAG,EAAE,OAAS,EAAIA,EAAa,IAAM,MAAA,CACrE,CACD,EACGoO,EAAO,SACT+K,EAAc,QACZ5e,EAAc,CAAE,GAAI,qCAAsC,EAC1D0F,CAAA,EAEF+Y,EAA0B,EAAK,EAC/BE,EAA0B,MAAS,GAEnCC,EAAc,MACZ5e,EAAc,CAAE,GAAI,mCAAoC,EACxD6T,EAAO,OAAS,EAAA,CAGtB,OAAS7N,EAAO,CACd4Y,EAAc,MACZ5e,EAAc,CAAE,GAAI,mCAAoC,EACxDgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CACF,EAGMmb,GAAoB,MAAOzkB,GAAuB,CACtD,GAAI,CACF,MAAM0kB,GAAkB1kB,CAAU,EAClCkiB,EAAc,QACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CtD,CAAA,EAEFsiB,EAAW,QAAA,CACb,OAAShZ,EAAO,CACd,QAAQ,MAAM,qCAAsCA,CAAK,EACzD4Y,EAAc,MACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CACF,EAEMqb,GAAoB,MAAO3kB,EAAoBvB,IAAqB,CACxE,GAAI,CACF,MAAMmmB,GAAkB5kB,EAAYvB,CAAO,EAC3C6jB,EAAW,QAAA,CACb,OAAShZ,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,qCAAsCA,CAAK,CAC3D,CACF,EAGMub,GAAkB/jB,EAAQ,OAAQpB,GAAM,UAC5C,MAAMxB,EAAQmW,EAAY,YAAA,EACpByQ,EAAYplB,EAAE,KAAK,YAAA,EAAc,SAASxB,CAAK,EAE/C6mB,EAAiBpc,GAAgBjJ,CAAC,GACpCP,EAAAO,EAAE,MAAF,YAAAP,EAAO,cAAc,SAASjB,IAC9BmB,GAAAK,EAAE,UAAF,YAAAL,GAAW,cAAc,SAASnB,GACtC,OAAO4mB,GAAaC,CACtB,CAAC,EAGKzJ,KAAenc,GAAAmjB,EAAW,OAAX,YAAAnjB,GAAiB,UAAW,CAAA,EAC3C6lB,KAAkB3lB,GAAAijB,EAAW,OAAX,YAAAjjB,GAAiB,aAAc,GACjD4lB,GAAuB3J,GAAa,OAAQ5b,GAAM,UACtD,MAAMxB,EAAQmW,EAAY,YAAA,EACpByQ,EAAYplB,EAAE,KAAK,YAAA,EAAc,SAASxB,CAAK,EAE/C6mB,EAAiBpc,GAAgBjJ,CAAC,GACpCP,EAAAO,EAAE,MAAF,YAAAP,EAAO,cAAc,SAASjB,IAC9BmB,GAAAK,EAAE,UAAF,YAAAL,GAAW,cAAc,SAASnB,GACtC,OAAO4mB,GAAaC,CACtB,CAAC,EAEKG,GAAiBxD,IAAY,QAAUuD,GAAuBJ,GAC9DM,GAAkBzD,IAAY,QAAUE,EAAuBR,EAC/DgE,GAAsB1D,IAAY,QAAUoB,GAAoBD,GAChEwC,GAAmB3D,IAAY,QAAUY,EAAW,UAAYhE,EAChEgH,GAAoB5D,IAAY,QAAUY,EAAW,WAAaD,EAClEkD,GAAiB7D,IAAY,SAAW,IAAMY,EAAW,WAAa3iB,EAE5E,OACE0E,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,qEACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,6DACZ,SAAA,CAAAE,EAAAA,IAACyJ,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACxC1K,EAAc,CAAE,GAAI,WAAA,CAAa,CAAA,EACpC,EACAiB,MAAC,KAAE,UAAU,6BACV,WAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAC1C,CAAA,EACF,EAEAA,EAAAA,IAAC,MAAA,CAAI,UAAU,qBACb,SAAAA,EAAAA,IAACihB,GAAA,CACC,YAAa9D,EACb,aAAcyB,GACd,gBAAA6B,EAAA,CAAA,CACF,CACF,CAAA,EACF,EACA3gB,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAACgC,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAMkf,KAAkB,SAAUD,GACnE,SAAA,CAAA/gB,MAACkc,IAAU,UAAWjc,EAAG,eAAgB8gB,IAAqB,cAAc,EAAG,EAC9EhiB,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,EACjD,EACCoe,IAAY,UACXrd,OAACgC,EAAA,CAAO,QAAS2c,GACf,SAAA,CAAAze,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAA,CAC1C,CAAA,CAAA,CAEJ,CAAA,EACF,EAGAiB,EAAAA,IAACkhB,GAAA,CACC,MAAOzE,EACP,cAAgBlb,GAAUmb,EAAanb,CAA8C,EACrF,KAAM,CACJ,CAAE,MAAO,YAAa,MAAOxC,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EACvE,CAAE,MAAO,UAAW,MAAOA,EAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,EACnE,CAAE,MAAO,YAAa,MAAOA,EAAc,CAAE,GAAI,oBAAqB,CAAA,CAAE,CAC1E,CAAA,EAID0d,IAAc,aACb3c,OAAC,MAAA,CAAI,UAAU,iBAEb,SAAA,CAAAE,EAAAA,IAACiU,GAAA,CAAsB,kBAAmB,IAAM7Y,EAAA,CAAQ,CAAG,EAG3D4E,EAAAA,IAAC2P,GAAA,CACC,kBAAmBwB,GACnB,iBAAkB8O,EAAA,CAAA,CACpB,EACF,EAIDxD,IAAc,WACb3c,OAAC,MAAA,CAAI,UAAU,iBAEb,SAAA,CAAAE,EAAAA,IAAC0V,GAAA,EAA4B,EAGhCyH,IAAY,UACXrd,OAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACyJ,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACzCzJ,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,SAAA4d,CAAA,CAAW,CAAA,EACnD,EACA5d,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAE,CAAA,EAC9F,EACAF,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4J,GAAA,CAAM,UAAU,wBAAA,CAAyB,EAC1C5J,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,SAAA6d,CAAA,CAAa,CAAA,EACrD,EACA7d,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAE,CAAA,EAChG,EACAF,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACgI,GAAA,CAAM,UAAU,mBAAA,CAAoB,EACrChI,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,WAAc,MAAA,CAAO,CAAA,EAC7D,EACAA,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAAE,CAAA,EAC/F,EACAF,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACzCnN,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,WAAe,MAAA,CAAO,CAAA,EAC9D,EACAA,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAE,CAAA,CAAA,CAChG,CAAA,EACF,EAIDmd,IAAY,UACXrd,OAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAE,EAAAA,IAAC2R,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3F3R,EAAAA,IAAC4B,EAAA,CACC,YAAa7C,EAAc,CAAE,GAAI,gCAAiC,EAClE,MAAO+Q,EACP,SAAWjO,GAAMkO,EAAelO,EAAE,OAAO,KAAK,EAC9C,UAAU,MAAA,CAAA,CACZ,EACF,EACA/B,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAS6a,IAAgB,MAAQ,UAAY,UAC7C,KAAK,KACL,QAAS,IAAMC,EAAe,KAAK,EAElC,SAAA7d,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAA,EAE1Ce,EAAAA,KAACgC,EAAA,CACC,QAAS6a,IAAgB,SAAW,UAAY,UAChD,KAAK,KACL,QAAS,IAAMC,EAAe,QAAQ,EAEtC,SAAA,CAAA5c,EAAAA,IAACgI,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/BjJ,EAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAAA,CAAA,EAE3Ce,EAAAA,KAACgC,EAAA,CACC,QAAS6a,IAAgB,UAAY,UAAY,UACjD,KAAK,KACL,QAAS,IAAMC,EAAe,SAAS,EAEvC,SAAA,CAAA5c,EAAAA,IAACmN,GAAA,CAAO,UAAU,cAAA,CAAe,EAChCpO,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAAA,CAC5C,CAAA,CACF,CAAA,EACF,EAIDoe,IAAY,SACXrd,OAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAE,EAAAA,IAAC2R,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3F3R,EAAAA,IAAC4B,EAAA,CACC,YAAa7C,EAAc,CAAE,GAAI,gCAAiC,EAClE,MAAO+Q,EACP,SAAWjO,GAAMkO,EAAelO,EAAE,OAAO,KAAK,EAC9C,UAAU,MAAA,CAAA,CACZ,EACF,EAIDsb,IAAY,UACXnd,EAAAA,IAACmK,GAAA,CACC,YAAa0U,GAAU,YACvB,aAAcA,GAAU,aACxB,YAAaA,GAAU,YACvB,YAAaA,GAAU,YACvB,cAAeA,GAAU,cACzB,aAAcE,EACd,eAAgBK,EAChB,UAAWC,EACX,gBAAiBR,GAAU,gBAC3B,iBAAkBY,GAClB,iBAAkBC,EAAA,CAAA,EAGrBvC,IAAY,SACXnd,EAAAA,IAACmK,GAAA,CACC,OAAO,QACP,YAAayV,GAAe,YAC5B,aAAcA,GAAe,aAC7B,YAAaA,GAAe,YAC5B,YAAaA,GAAe,YAC5B,cAAeA,GAAe,cAC9B,aAAcC,GACd,eAAgBC,GAChB,UAAWC,EAAA,CAAA,EAKde,GACC9gB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAA,CAAC,EAAG,EAAG,EAAG,CAAC,EAAE,IAAK,GACjBA,EAAAA,IAAC,MAAA,CAAY,UAAU,wCAAA,EAAb,CAAsD,CACjE,CAAA,CACH,EACE2gB,GAAe,SAAW,EAC5B7gB,EAAAA,KAAC0J,EAAA,CAAK,UAAU,kBACd,SAAA,CAAAxJ,EAAAA,IAACyJ,GAAA,CAAO,UAAU,4CAAA,CAA6C,EAC/DzJ,EAAAA,IAAC,MAAG,UAAU,2CAA4C,WAAc,CAAE,GAAI,sBAAA,CAAwB,EAAE,EACxGA,MAAC,KAAE,UAAU,6BACV,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,CAAA,CACF,EAEAA,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,YAAe,IAAKlE,GACnBqhB,IAAY,QACVnd,EAAAA,IAACqI,GAAA,CAEC,OAAAvM,EACA,QAASA,EAAO,QAChB,WAAY8kB,GAAgB,IAAI9kB,EAAO,IAAI,EAC3C,eAAgB,IAAM+kB,GAAoB/kB,EAAO,IAAI,EACrD,WAAY,GACZ,SAAUokB,GACV,SAAUE,EAAA,EAPL,GAAGtkB,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAA,EAUrCkE,EAAAA,IAACmc,GAAA,CAEC,OAAArgB,EACA,WAAY8kB,GAAgB,IAAI,GAAG9kB,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAE,EAChE,eAAgB,IAAM+kB,GAAoB,GAAG/kB,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAE,EAC1E,SAAUwN,GACV,OAAQkV,GACR,SAAU7P,EACV,iBAAkBqR,GAClB,aAAcV,GAAY,IAAIxjB,EAAO,IAAI,CAAA,EARpC,GAAGA,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAA,CAWxC,CAAA,CACH,CAAA,EAEA,EAID2gB,IAAc,aACb3c,OAAC,MAAA,CAAI,UAAU,iBAEb,SAAA,CAAAA,OAAC,UAAA,CACC,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAACkc,GAAA,CAAU,UAAU,+BAAA,CAAgC,EACrDlc,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,gBAAA,CAAkB,CAAA,CACzC,CAAA,EACF,EACAA,EAAAA,IAACwJ,EAAA,CAAK,UAAU,MACd,SAAAxJ,MAACyW,IAAkB,UAAW,IAAMrb,EAAA,CAAQ,CAAG,CAAA,CACjD,CAAA,EACF,SAGC,UAAA,CACC,SAAA,CAAA0E,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAClDnN,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EACF,EACAA,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,EACnD,EACAA,EAAAA,IAACiZ,GAAA,CACC,YAAa,GACb,eAAiBjL,GAAS,QAAQ,IAAI,gBAAiBA,CAAI,EAC3D,gBAAkBA,GAAS,OAAO,KAAK,aAAa,mBAAmBA,CAAI,CAAC,GAAI,QAAQ,CAAA,CAAA,CAC1F,EACF,SAGC,UAAA,CACC,SAAA,CAAAlO,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAACgI,GAAA,CAAM,UAAU,+BAAA,CAAgC,EACjDhI,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EACF,EACAA,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,8BAAA,CAAgC,EACvD,EACAA,EAAAA,IAAC8a,GAAA,CACC,gBAAiB,CAACrf,EAAY0lB,IAAkB,CAC9C,QAAQ,IAAI,mBAAoB1lB,EAAY,QAAS0lB,CAAa,EAClE/lB,EAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,EAID+hB,IAAY,UACXnd,EAAAA,IAACmC,GAAA,CACC,KAAM8a,EAAgB,OAAS,MAC/B,OAAQA,EACR,KAAMF,EACN,QAAS2B,GACT,OAAQC,EAAA,CAAA,EAKZ3e,EAAAA,IAAC+O,GAAA,CACC,KAAMwO,EACN,QAAS,IAAM,CACbC,EAA0B,EAAK,EAC/BE,EAA0B,MAAS,CACrC,EACA,OAAQuC,GACR,YAAaxC,GAAA,YAAAA,EAAwB,KACrC,eACEA,GAA0BrY,GAAiBqY,CAAsB,EAC7DA,EAAuB,QACvB,OAEN,YACEA,GAA0BrY,GAAiBqY,CAAsB,EAC7DA,EAAuB,KACvB,OAEN,WACEA,GAA0BrY,GAAiBqY,CAAsB,EAC5DA,EAAuB,IACxB,MAAA,CAAA,CAER,EACF,CAEJ","x_google_ignoreList":[0,1,2,3,4]}
1
+ {"version":3,"file":"McpManagerPage-CI5ZzB8A.js","sources":["../../../../node_modules/lucide-react/dist/esm/icons/files.js","../../../../node_modules/lucide-react/dist/esm/icons/folder-tree.js","../../../../node_modules/lucide-react/dist/esm/icons/key.js","../../../../node_modules/lucide-react/dist/esm/icons/message-circle-question.js","../../../../node_modules/lucide-react/dist/esm/icons/pen-line.js","../../src/hooks/useMcpServers.ts","../../src/components/mcp/ConfigTypeToggle.tsx","../../src/components/mcp/McpServerDialog.tsx","../../src/components/mcp/CodexMcpEditableCard.tsx","../../src/components/mcp/CcwToolsMcpCard.tsx","../../src/components/mcp/McpTemplatesSection.tsx","../../src/components/mcp/RecommendedMcpWizard.tsx","../../src/components/mcp/RecommendedMcpSection.tsx","../../src/components/mcp/WindowsCompatibilityWarning.tsx","../../src/components/mcp/CrossCliSyncPanel.tsx","../../src/components/mcp/AllProjectsTable.tsx","../../src/components/mcp/OtherProjectsSection.tsx","../../src/pages/McpManagerPage.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Files = createLucideIcon(\"Files\", [\n [\"path\", { d: \"M20 7h-3a2 2 0 0 1-2-2V2\", key: \"x099mo\" }],\n [\"path\", { d: \"M9 18a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h7l4 4v10a2 2 0 0 1-2 2Z\", key: \"18t6ie\" }],\n [\"path\", { d: \"M3 7.6v12.8A1.6 1.6 0 0 0 4.6 22h9.8\", key: \"1nja0z\" }]\n]);\n\nexport { Files as default };\n//# sourceMappingURL=files.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FolderTree = createLucideIcon(\"FolderTree\", [\n [\n \"path\",\n {\n d: \"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z\",\n key: \"hod4my\"\n }\n ],\n [\n \"path\",\n {\n d: \"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z\",\n key: \"w4yl2u\"\n }\n ],\n [\"path\", { d: \"M3 5a2 2 0 0 0 2 2h3\", key: \"f2jnh7\" }],\n [\"path\", { d: \"M3 3v13a2 2 0 0 0 2 2h3\", key: \"k8epm1\" }]\n]);\n\nexport { FolderTree as default };\n//# sourceMappingURL=folder-tree.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Key = createLucideIcon(\"Key\", [\n [\"path\", { d: \"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\", key: \"g0fldk\" }],\n [\"path\", { d: \"m21 2-9.6 9.6\", key: \"1j0ho8\" }],\n [\"circle\", { cx: \"7.5\", cy: \"15.5\", r: \"5.5\", key: \"yqb3hr\" }]\n]);\n\nexport { Key as default };\n//# sourceMappingURL=key.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MessageCircleQuestion = createLucideIcon(\"MessageCircleQuestion\", [\n [\"path\", { d: \"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\", key: \"vv11sd\" }],\n [\"path\", { d: \"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\", key: \"1u773s\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n]);\n\nexport { MessageCircleQuestion as default };\n//# sourceMappingURL=message-circle-question.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst PenLine = createLucideIcon(\"PenLine\", [\n [\"path\", { d: \"M12 20h9\", key: \"t2du7b\" }],\n [\n \"path\",\n {\n d: \"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z\",\n key: \"1ykcvy\"\n }\n ]\n]);\n\nexport { PenLine as default };\n//# sourceMappingURL=pen-line.js.map\n","// ========================================\r\n// useMcpServers Hook\r\n// ========================================\r\n// TanStack Query hooks for MCP server management\r\n\r\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport {\r\n fetchMcpServers,\r\n updateMcpServer,\r\n createMcpServer,\r\n deleteMcpServer,\r\n toggleMcpServer,\r\n fetchMcpTemplates,\r\n saveMcpTemplate,\r\n deleteMcpTemplate,\r\n installMcpTemplate,\r\n codexRemoveServer,\r\n codexToggleServer,\r\n fetchAllProjects,\r\n fetchOtherProjectsServers,\r\n crossCliCopy,\r\n type McpServer,\r\n type McpServersResponse,\r\n type McpServerConflict,\r\n type McpProjectConfigType,\r\n type McpTemplate,\r\n type McpTemplateInstallRequest,\r\n type OtherProjectsServersResponse,\r\n type CrossCliCopyRequest,\r\n type CrossCliCopyResponse,\r\n} from '../lib/api';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// Query key factory\r\nexport const mcpServersKeys = {\r\n all: ['mcpServers'] as const,\r\n lists: () => [...mcpServersKeys.all, 'list'] as const,\r\n list: (scope?: 'project' | 'global') => [...mcpServersKeys.lists(), scope] as const,\r\n};\r\n\r\n// Query key factory for MCP templates\r\nexport const mcpTemplatesKeys = {\r\n all: ['mcpTemplates'] as const,\r\n lists: () => [...mcpTemplatesKeys.all, 'list'] as const,\r\n list: (category?: string) => [...mcpTemplatesKeys.lists(), category] as const,\r\n search: (query: string) => [...mcpTemplatesKeys.all, 'search', query] as const,\r\n categories: () => [...mcpTemplatesKeys.all, 'categories'] as const,\r\n};\r\n\r\n// Query key factory for projects\r\nexport const projectsKeys = {\r\n all: ['projects'] as const,\r\n list: () => [...projectsKeys.all, 'list'] as const,\r\n servers: (paths?: string[]) => [...projectsKeys.all, 'servers', ...(paths ?? [])] as const,\r\n};\r\n\r\n// Default stale time: 2 minutes (MCP servers change occasionally)\r\nconst STALE_TIME = 2 * 60 * 1000;\r\n\r\nexport interface UseMcpServersOptions {\r\n scope?: 'project' | 'global';\r\n staleTime?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseMcpServersReturn {\r\n servers: McpServer[];\r\n projectServers: McpServer[];\r\n globalServers: McpServer[];\r\n conflicts: McpServerConflict[];\r\n totalCount: number;\r\n enabledCount: number;\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n invalidate: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching MCP servers\r\n */\r\nexport function useMcpServers(options: UseMcpServersOptions = {}): UseMcpServersReturn {\r\n const { scope, staleTime = STALE_TIME, enabled = true } = options;\r\n const queryClient = useQueryClient();\r\n\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const queryEnabled = enabled && !!projectPath;\r\n\r\n const query = useQuery({\r\n queryKey: mcpServersKeys.list(scope),\r\n queryFn: () => fetchMcpServers(projectPath),\r\n staleTime,\r\n enabled: queryEnabled,\r\n retry: 2,\r\n });\r\n\r\n const projectServers = query.data?.project ?? [];\r\n const globalServers = query.data?.global ?? [];\r\n const conflicts = query.data?.conflicts ?? [];\r\n const allServers = scope === 'project' ? projectServers : scope === 'global' ? globalServers : [...projectServers, ...globalServers];\r\n\r\n const enabledServers = allServers.filter((s) => s.enabled);\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const invalidate = async () => {\r\n await queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n };\r\n\r\n return {\r\n servers: allServers,\r\n projectServers,\r\n globalServers,\r\n conflicts,\r\n totalCount: allServers.length,\r\n enabledCount: enabledServers.length,\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n invalidate,\r\n };\r\n}\r\n\r\n// ========== Mutations ==========\r\n\r\nexport interface UseUpdateMcpServerReturn {\r\n updateServer: (serverName: string, config: Partial<McpServer>, configType?: McpProjectConfigType) => Promise<McpServer>;\r\n isUpdating: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useUpdateMcpServer(): UseUpdateMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ serverName, config, configType }: { serverName: string; config: Partial<McpServer>; configType?: McpProjectConfigType }) =>\r\n updateMcpServer(serverName, config, { projectPath: projectPath ?? undefined, configType }),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n updateServer: (serverName, config, configType) => mutation.mutateAsync({ serverName, config, configType }),\r\n isUpdating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseCreateMcpServerReturn {\r\n createServer: (server: McpServer, configType?: McpProjectConfigType) => Promise<McpServer>;\r\n isCreating: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useCreateMcpServer(): UseCreateMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ server, configType }: { server: McpServer; configType?: McpProjectConfigType }) =>\r\n createMcpServer(server, { projectPath: projectPath ?? undefined, configType }),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n createServer: (server, configType) => mutation.mutateAsync({ server, configType }),\r\n isCreating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteMcpServerReturn {\r\n deleteServer: (serverName: string, scope: 'project' | 'global') => Promise<void>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useDeleteMcpServer(): UseDeleteMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ serverName, scope }: { serverName: string; scope: 'project' | 'global' }) =>\r\n deleteMcpServer(serverName, scope, { projectPath: projectPath ?? undefined }),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n },\r\n });\r\n\r\n return {\r\n deleteServer: (serverName, scope) => mutation.mutateAsync({ serverName, scope }),\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseToggleMcpServerReturn {\r\n toggleServer: (serverName: string, enabled: boolean) => Promise<McpServer>;\r\n isToggling: boolean;\r\n error: Error | null;\r\n}\r\n\r\nexport function useToggleMcpServer(): UseToggleMcpServerReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n const mutation = useMutation({\r\n mutationFn: ({ serverName, enabled }: { serverName: string; enabled: boolean }) =>\r\n toggleMcpServer(serverName, enabled, { projectPath: projectPath ?? undefined }),\r\n onMutate: async ({ serverName, enabled }) => {\r\n await queryClient.cancelQueries({ queryKey: mcpServersKeys.all });\r\n const previousServers = queryClient.getQueryData<McpServersResponse>(mcpServersKeys.list());\r\n\r\n // Optimistic update\r\n queryClient.setQueryData<McpServersResponse>(mcpServersKeys.list(), (old) => {\r\n if (!old) return old;\r\n const updateServer = (servers: McpServer[]) =>\r\n servers.map((s) => (s.name === serverName ? { ...s, enabled } : s));\r\n return {\r\n project: updateServer(old.project),\r\n global: updateServer(old.global),\r\n conflicts: old.conflicts ?? [],\r\n };\r\n });\r\n\r\n return { previousServers };\r\n },\r\n onError: (_error, _vars, context) => {\r\n if (context?.previousServers) {\r\n queryClient.setQueryData(mcpServersKeys.list(), context.previousServers);\r\n }\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n toggleServer: (serverName, enabled) => mutation.mutateAsync({ serverName, enabled }),\r\n isToggling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n/**\r\n * Combined hook for all MCP server mutations\r\n */\r\nexport function useMcpServerMutations() {\r\n const update = useUpdateMcpServer();\r\n const create = useCreateMcpServer();\r\n const remove = useDeleteMcpServer();\r\n const toggle = useToggleMcpServer();\r\n\r\n return {\r\n updateServer: update.updateServer,\r\n isUpdating: update.isUpdating,\r\n createServer: create.createServer,\r\n isCreating: create.isCreating,\r\n deleteServer: remove.deleteServer,\r\n isDeleting: remove.isDeleting,\r\n toggleServer: toggle.toggleServer,\r\n isToggling: toggle.isToggling,\r\n isMutating: update.isUpdating || create.isCreating || remove.isDeleting || toggle.isToggling,\r\n };\r\n}\r\n\r\n// ========================================\r\n// MCP Template Hooks\r\n// ========================================\r\n\r\n// Default stale time for templates: 5 minutes (templates change rarely)\r\nconst TEMPLATES_STALE_TIME = 5 * 60 * 1000;\r\n\r\nexport interface UseMcpTemplatesOptions {\r\n category?: string;\r\n staleTime?: number;\r\n enabled?: boolean;\r\n}\r\n\r\nexport interface UseMcpTemplatesReturn {\r\n templates: McpTemplate[];\r\n isLoading: boolean;\r\n isFetching: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n invalidate: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Hook for fetching MCP templates with optional category filter\r\n */\r\nexport function useMcpTemplates(options: UseMcpTemplatesOptions = {}): UseMcpTemplatesReturn {\r\n const { category, staleTime = TEMPLATES_STALE_TIME, enabled = true } = options;\r\n const queryClient = useQueryClient();\r\n\r\n const query = useQuery({\r\n queryKey: mcpTemplatesKeys.list(category),\r\n queryFn: () => fetchMcpTemplates(),\r\n staleTime,\r\n enabled,\r\n retry: 2,\r\n });\r\n\r\n const refetch = async () => {\r\n await query.refetch();\r\n };\r\n\r\n const invalidate = async () => {\r\n await queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n };\r\n\r\n return {\r\n templates: category\r\n ? query.data?.filter((t) => t.category === category) ?? []\r\n : query.data ?? [],\r\n isLoading: query.isLoading,\r\n isFetching: query.isFetching,\r\n error: query.error,\r\n refetch,\r\n invalidate,\r\n };\r\n}\r\n\r\nexport interface UseCreateTemplateReturn {\r\n createTemplate: (template: Omit<McpTemplate, 'id' | 'createdAt' | 'updatedAt'>) => Promise<{ success: boolean; id?: number; error?: string }>;\r\n isCreating: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for creating or updating MCP templates\r\n */\r\nexport function useCreateTemplate(): UseCreateTemplateReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (template: Omit<McpTemplate, 'id' | 'createdAt' | 'updatedAt'>) =>\r\n saveMcpTemplate(template),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n createTemplate: mutation.mutateAsync,\r\n isCreating: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseDeleteTemplateReturn {\r\n deleteTemplate: (templateName: string) => Promise<{ success: boolean; error?: string }>;\r\n isDeleting: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for deleting MCP templates\r\n */\r\nexport function useDeleteTemplate(): UseDeleteTemplateReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (templateName: string) => deleteMcpTemplate(templateName),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n deleteTemplate: mutation.mutateAsync,\r\n isDeleting: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\nexport interface UseInstallTemplateReturn {\r\n installTemplate: (request: McpTemplateInstallRequest) => Promise<{ success: boolean; serverName?: string; error?: string }>;\r\n isInstalling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Hook for installing MCP templates to project or global scope\r\n */\r\nexport function useInstallTemplate(): UseInstallTemplateReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const mutation = useMutation({\r\n mutationFn: (request: McpTemplateInstallRequest) => installMcpTemplate(request),\r\n onSettled: () => {\r\n // Invalidate both templates and servers since installation affects both\r\n queryClient.invalidateQueries({ queryKey: mcpTemplatesKeys.all });\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n installTemplate: mutation.mutateAsync,\r\n isInstalling: mutation.isPending,\r\n error: mutation.error,\r\n };\r\n}\r\n\r\n// ========================================\r\n// Codex MCP Hooks\r\n// ========================================\r\n\r\nexport interface UseCodexMutationsReturn {\r\n removeServer: (serverName: string) => Promise<{ success: boolean; error?: string }>;\r\n toggleServer: (serverName: string, enabled: boolean) => Promise<{ success: boolean; error?: string }>;\r\n isRemoving: boolean;\r\n isToggling: boolean;\r\n error: Error | null;\r\n}\r\n\r\n/**\r\n * Combined hook for Codex MCP mutations (remove and toggle)\r\n */\r\nexport function useCodexMutations(): UseCodexMutationsReturn {\r\n const queryClient = useQueryClient();\r\n\r\n const removeMutation = useMutation({\r\n mutationFn: (serverName: string) => codexRemoveServer(serverName),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n const toggleMutation = useMutation({\r\n mutationFn: ({ serverName, enabled }: { serverName: string; enabled: boolean }) =>\r\n codexToggleServer(serverName, enabled),\r\n onMutate: async ({ serverName, enabled }) => {\r\n // Optimistic update could be added here if needed\r\n return { serverName, enabled };\r\n },\r\n onError: (_error, _vars, _context) => {\r\n // Rollback on error\r\n console.error('Failed to toggle Codex MCP server:', _error);\r\n },\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n return {\r\n removeServer: removeMutation.mutateAsync,\r\n isRemoving: removeMutation.isPending,\r\n toggleServer: (serverName, enabled) => toggleMutation.mutateAsync({ serverName, enabled }),\r\n isToggling: toggleMutation.isPending,\r\n error: removeMutation.error || toggleMutation.error,\r\n };\r\n}\r\n\r\n// ========================================\r\n// Project Operations Hooks\r\n// ========================================\r\n\r\nexport interface UseProjectOperationsReturn {\r\n projects: string[];\r\n currentProject?: string;\r\n isLoading: boolean;\r\n error: Error | null;\r\n refetch: () => Promise<void>;\r\n copyToCodex: (request: CrossCliCopyRequest) => Promise<CrossCliCopyResponse>;\r\n copyFromCodex: (request: CrossCliCopyRequest) => Promise<CrossCliCopyResponse>;\r\n isCopying: boolean;\r\n fetchOtherServers: (projectPaths?: string[]) => Promise<OtherProjectsServersResponse>;\r\n isFetchingServers: boolean;\r\n}\r\n\r\nconst EMPTY_PROJECTS: string[] = [];\r\n\r\n/**\r\n * Combined hook for project operations (all projects, cross-CLI copy, other projects' servers)\r\n */\r\nexport function useProjectOperations(): UseProjectOperationsReturn {\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Fetch all projects\r\n const projectsQuery = useQuery({\r\n queryKey: projectsKeys.list(),\r\n queryFn: () => fetchAllProjects(),\r\n staleTime: STALE_TIME,\r\n enabled: true,\r\n retry: 2,\r\n });\r\n\r\n // Cross-CLI copy mutation\r\n const copyMutation = useMutation({\r\n mutationFn: (request: CrossCliCopyRequest) => crossCliCopy(request),\r\n onSettled: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n },\r\n });\r\n\r\n // Other projects servers query\r\n const serversQuery = useQuery({\r\n queryKey: projectsKeys.servers(),\r\n queryFn: () => fetchOtherProjectsServers(),\r\n staleTime: STALE_TIME,\r\n enabled: false, // Manual trigger only\r\n retry: 1,\r\n });\r\n\r\n const refetch = async () => {\r\n await projectsQuery.refetch();\r\n };\r\n\r\n const fetchOtherServers = async (projectPaths?: string[]) => {\r\n return await queryClient.fetchQuery({\r\n queryKey: projectsKeys.servers(projectPaths),\r\n queryFn: () => fetchOtherProjectsServers(projectPaths),\r\n staleTime: STALE_TIME,\r\n });\r\n };\r\n\r\n return {\r\n projects: projectsQuery.data?.projects ?? EMPTY_PROJECTS,\r\n currentProject: projectsQuery.data?.currentProject ?? projectPath ?? undefined,\r\n isLoading: projectsQuery.isLoading,\r\n error: projectsQuery.error,\r\n refetch,\r\n copyToCodex: (request) => copyMutation.mutateAsync({\r\n ...request,\r\n source: 'claude',\r\n target: 'codex',\r\n projectPath: request.projectPath ?? projectPath ?? undefined,\r\n }),\r\n copyFromCodex: (request) => copyMutation.mutateAsync({\r\n ...request,\r\n source: 'codex',\r\n target: 'claude',\r\n projectPath: request.projectPath ?? projectPath ?? undefined,\r\n }),\r\n isCopying: copyMutation.isPending,\r\n fetchOtherServers,\r\n isFetchingServers: serversQuery.isFetching,\r\n };\r\n}\r\n","// ========================================\n// Config Type Toggle Component\n// ========================================\n// Toggle between .mcp.json and .claude.json config storage formats with localStorage persistence\n\nimport { useEffect, useState } from 'react';\nimport { useIntl } from 'react-intl';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@/components/ui/AlertDialog';\nimport { cn } from '@/lib/utils';\n\n// ========== Types ==========\n\n/**\n * MCP config file type\n */\nexport type McpConfigType = 'mcp-json' | 'claude-json';\n\n/**\n * Props for ConfigTypeToggle component\n */\nexport interface ConfigTypeToggleProps {\n /** Current config type */\n currentType: McpConfigType;\n /** Callback when config type changes */\n onTypeChange: (type: McpConfigType) => void;\n /** Whether to show warning when switching (default: true) */\n showWarning?: boolean;\n /** Number of existing servers in current config (for warning message) */\n existingServersCount?: number;\n}\n\n// ========== Constants ==========\n\n/**\n * localStorage key for config type persistence\n */\nconst CONFIG_TYPE_STORAGE_KEY = 'mcp-config-type';\n\n/**\n * Default config type\n */\nconst DEFAULT_CONFIG_TYPE: McpConfigType = 'mcp-json';\n\n// ========== Helper Functions ==========\n\n/**\n * Load config type from localStorage\n */\nexport function loadConfigType(): McpConfigType {\n try {\n const stored = localStorage.getItem(CONFIG_TYPE_STORAGE_KEY);\n if (stored === 'mcp-json' || stored === 'claude-json') {\n return stored;\n }\n } catch {\n // Ignore localStorage errors\n }\n return DEFAULT_CONFIG_TYPE;\n}\n\n/**\n * Save config type to localStorage\n */\nexport function saveConfigType(type: McpConfigType): void {\n try {\n localStorage.setItem(CONFIG_TYPE_STORAGE_KEY, type);\n } catch {\n // Ignore localStorage errors\n }\n}\n\n/**\n * Get file extension for config type\n */\nexport function getConfigFileExtension(type: McpConfigType): string {\n switch (type) {\n case 'mcp-json':\n return '.mcp.json';\n case 'claude-json':\n return '.claude.json';\n default:\n return '.json';\n }\n}\n\n// ========== Component ==========\n\n/**\n * Config type toggle segmented control\n */\nexport function ConfigTypeToggle({\n currentType,\n onTypeChange,\n showWarning = true,\n existingServersCount = 0,\n}: ConfigTypeToggleProps) {\n const { formatMessage } = useIntl();\n const [internalType, setInternalType] = useState<McpConfigType>(currentType);\n const [showWarningDialog, setShowWarningDialog] = useState(false);\n const [pendingType, setPendingType] = useState<McpConfigType | null>(null);\n\n // Sync internal state with prop changes\n useEffect(() => {\n setInternalType(currentType);\n }, [currentType]);\n\n // Load saved preference on mount (only if no current type is set)\n useEffect(() => {\n if (!currentType || currentType === DEFAULT_CONFIG_TYPE) {\n const savedType = loadConfigType();\n if (savedType !== currentType) {\n setInternalType(savedType);\n onTypeChange(savedType);\n }\n }\n }, []); // Run once on mount\n\n // Handle type toggle click\n const handleTypeClick = (type: McpConfigType) => {\n if (type === internalType) return;\n\n if (showWarning && existingServersCount > 0) {\n setPendingType(type);\n setShowWarningDialog(true);\n } else {\n applyTypeChange(type);\n }\n };\n\n // Apply the type change\n const applyTypeChange = (type: McpConfigType) => {\n setInternalType(type);\n saveConfigType(type);\n onTypeChange(type);\n setShowWarningDialog(false);\n setPendingType(null);\n };\n\n // Handle warning dialog confirm\n const handleWarningConfirm = () => {\n if (pendingType) {\n applyTypeChange(pendingType);\n }\n };\n\n // Handle warning dialog cancel\n const handleWarningCancel = () => {\n setShowWarningDialog(false);\n setPendingType(null);\n };\n\n return (\n <>\n {/* Compact inline toggle */}\n <div className=\"flex items-center gap-1.5 p-0.5 bg-muted rounded-md h-9\">\n <button\n type=\"button\"\n onClick={() => handleTypeClick('mcp-json')}\n className={cn(\n 'px-2.5 py-1 text-xs font-medium rounded transition-all',\n internalType === 'mcp-json'\n ? 'bg-primary text-primary-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n )}\n >\n .mcp.json\n </button>\n <button\n type=\"button\"\n onClick={() => handleTypeClick('claude-json')}\n className={cn(\n 'px-2.5 py-1 text-xs font-medium rounded transition-all',\n internalType === 'claude-json'\n ? 'bg-primary text-primary-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n )}\n >\n .claude.json\n </button>\n </div>\n\n {/* Warning Dialog */}\n <AlertDialog open={showWarningDialog} onOpenChange={setShowWarningDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {formatMessage({ id: 'mcp.configType.switchConfirm' })}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {formatMessage({ id: 'mcp.configType.switchWarning' })}\n {existingServersCount > 0 && (\n <span className=\"block mt-2 text-amber-600 dark:text-amber-400\">\n {existingServersCount} {formatMessage({ id: 'mcp.stats.total' }).toLowerCase()}\n </span>\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel onClick={handleWarningCancel}>\n {formatMessage({ id: 'mcp.configType.switchCancel' })}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleWarningConfirm}>\n {formatMessage({ id: 'mcp.configType.switchConfirm' })}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n\nexport default ConfigTypeToggle;\n","// ========================================\r\n// MCP Server Dialog Component\r\n// ========================================\r\n// Add/Edit dialog for MCP server configuration with dynamic template loading\r\n// Supports both STDIO and HTTP transport types\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { Eye, EyeOff, Plus, Trash2, Globe, Terminal } from 'lucide-react';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n createMcpServer,\r\n updateMcpServer,\r\n fetchMcpServers,\r\n saveMcpTemplate,\r\n type McpServer,\r\n type McpProjectConfigType,\r\n isStdioMcpServer,\r\n isHttpMcpServer,\r\n} from '@/lib/api';\r\nimport { mcpServersKeys, useMcpTemplates, useNotifications } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport { ConfigTypeToggle, type McpConfigType } from './ConfigTypeToggle';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// ========== Types ==========\r\n\r\nexport type McpTransportType = 'stdio' | 'http';\r\n\r\nexport interface HttpHeader {\r\n id: string;\r\n name: string;\r\n value: string;\r\n isEnvVar: boolean;\r\n}\r\n\r\nexport interface McpServerDialogProps {\r\n mode: 'add' | 'edit';\r\n server?: McpServer;\r\n open: boolean;\r\n onClose: () => void;\r\n onSave?: () => void;\r\n}\r\n\r\n// Re-export McpTemplate for convenience\r\nexport type { McpTemplate } from '@/types/store';\r\n\r\ninterface McpServerFormData {\r\n name: string;\r\n // STDIO fields\r\n command: string;\r\n args: string[];\r\n env: Record<string, string>;\r\n // HTTP fields\r\n url: string;\r\n headers: HttpHeader[];\r\n bearerTokenEnvVar: string;\r\n // Common fields\r\n scope: 'project' | 'global';\r\n enabled: boolean;\r\n}\r\n\r\ninterface FormErrors {\r\n name?: string;\r\n command?: string;\r\n args?: string;\r\n env?: string;\r\n url?: string;\r\n headers?: string;\r\n}\r\n\r\n// ========== Helper Component: HttpHeadersInput ==========\r\n\r\ninterface HttpHeadersInputProps {\r\n headers: HttpHeader[];\r\n onChange: (headers: HttpHeader[]) => void;\r\n disabled?: boolean;\r\n}\r\n\r\nfunction HttpHeadersInput({ headers, onChange, disabled }: HttpHeadersInputProps) {\r\n const { formatMessage } = useIntl();\r\n const [revealedIds, setRevealedIds] = useState<Set<string>>(new Set());\r\n\r\n const generateId = () => `header-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\r\n\r\n const handleAdd = () => {\r\n onChange([...headers, { id: generateId(), name: '', value: '', isEnvVar: false }]);\r\n };\r\n\r\n const handleRemove = (id: string) => {\r\n onChange(headers.filter((h) => h.id !== id));\r\n };\r\n\r\n const handleUpdate = (id: string, field: keyof HttpHeader, value: string | boolean) => {\r\n onChange(headers.map((h) => (h.id === id ? { ...h, [field]: value } : h)));\r\n };\r\n\r\n const toggleReveal = (id: string) => {\r\n setRevealedIds((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(id)) {\r\n next.delete(id);\r\n } else {\r\n next.add(id);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n return (\r\n <div className=\"space-y-2\">\r\n {headers.map((header) => (\r\n <div key={header.id} className=\"flex items-center gap-2\">\r\n {/* Header Name */}\r\n <Input\r\n value={header.name}\r\n onChange={(e) => handleUpdate(header.id, 'name', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.headerName' })}\r\n className=\"flex-1\"\r\n disabled={disabled}\r\n />\r\n {/* Header Value */}\r\n <div className=\"relative flex-1\">\r\n <Input\r\n type={revealedIds.has(header.id) ? 'text' : 'password'}\r\n value={header.value}\r\n onChange={(e) => handleUpdate(header.id, 'value', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.headerValue' })}\r\n className=\"pr-8\"\r\n disabled={disabled}\r\n />\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"absolute right-0 top-0 h-full px-2\"\r\n onClick={() => toggleReveal(header.id)}\r\n disabled={disabled}\r\n >\r\n {revealedIds.has(header.id) ? (\r\n <EyeOff className=\"w-4 h-4\" />\r\n ) : (\r\n <Eye className=\"w-4 h-4\" />\r\n )}\r\n </Button>\r\n </div>\r\n {/* Env Var Toggle */}\r\n <label className=\"flex items-center gap-1 text-xs text-muted-foreground whitespace-nowrap\">\r\n <input\r\n type=\"checkbox\"\r\n checked={header.isEnvVar}\r\n onChange={(e) => handleUpdate(header.id, 'isEnvVar', e.target.checked)}\r\n className=\"w-3 h-3\"\r\n disabled={disabled}\r\n />\r\n {formatMessage({ id: 'mcp.dialog.form.http.isEnvVar' })}\r\n </label>\r\n {/* Delete Button */}\r\n <Button\r\n type=\"button\"\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n onClick={() => handleRemove(header.id)}\r\n disabled={disabled}\r\n className=\"text-destructive\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n ))}\r\n <Button\r\n type=\"button\"\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleAdd}\r\n disabled={disabled}\r\n className=\"w-full\"\r\n >\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.dialog.form.http.addHeader' })}\r\n </Button>\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function McpServerDialog({\r\n mode,\r\n server,\r\n open,\r\n onClose,\r\n onSave,\r\n}: McpServerDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n const { error: showError, success: showSuccess } = useNotifications();\r\n\r\n // Fetch templates from backend\r\n const { templates, isLoading: templatesLoading } = useMcpTemplates();\r\n\r\n // Transport type state\r\n const [transportType, setTransportType] = useState<McpTransportType>('stdio');\r\n\r\n // Form state\r\n const [formData, setFormData] = useState<McpServerFormData>({\r\n name: '',\r\n command: '',\r\n args: [],\r\n env: {},\r\n url: '',\r\n headers: [],\r\n bearerTokenEnvVar: '',\r\n scope: 'project',\r\n enabled: true,\r\n });\r\n\r\n const [selectedTemplate, setSelectedTemplate] = useState<string>('');\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n const [argsInput, setArgsInput] = useState('');\r\n const [envInput, setEnvInput] = useState('');\r\n const [configType, setConfigType] = useState<McpConfigType>('mcp-json');\r\n const [saveAsTemplate, setSaveAsTemplate] = useState(false);\r\n const projectConfigType: McpProjectConfigType = configType === 'claude-json' ? 'claude' : 'mcp';\r\n\r\n // JSON import mode state\r\n const [inputMode, setInputMode] = useState<'form' | 'json'>('form');\r\n const [jsonInput, setJsonInput] = useState('');\r\n\r\n // Helper to detect transport type from server data\r\n const detectTransportType = useCallback((serverData: McpServer | undefined): McpTransportType => {\r\n if (!serverData) return 'stdio';\r\n // Use type guard to check for HTTP server\r\n if (isHttpMcpServer(serverData)) return 'http';\r\n return 'stdio';\r\n }, []);\r\n\r\n // Parse JSON config and populate form\r\n const parseJsonConfig = useCallback(() => {\r\n try {\r\n let config = JSON.parse(jsonInput);\r\n let extractedServerName = '';\r\n\r\n // Auto-detect mcpServers wrapper format (Claude Code config format)\r\n // Supports both: { \"mcpServers\": { \"name\": {...} } } and direct { \"command\": ... }\r\n if (config.mcpServers && typeof config.mcpServers === 'object' && !Array.isArray(config.mcpServers)) {\r\n const serverNames = Object.keys(config.mcpServers);\r\n if (serverNames.length > 0) {\r\n extractedServerName = serverNames[0];\r\n const serverConfig = config.mcpServers[extractedServerName];\r\n if (serverConfig && typeof serverConfig === 'object') {\r\n config = serverConfig;\r\n }\r\n }\r\n }\r\n\r\n // Detect transport type based on config structure\r\n if (config.url) {\r\n // HTTP transport\r\n setTransportType('http');\r\n \r\n // Parse headers\r\n const headers: HttpHeader[] = [];\r\n if (config.headers && typeof config.headers === 'object') {\r\n Object.entries(config.headers).forEach(([name, value], idx) => {\r\n headers.push({\r\n id: `header-${Date.now()}-${idx}`,\r\n name,\r\n value: String(value),\r\n isEnvVar: false,\r\n });\r\n });\r\n }\r\n \r\n setFormData(prev => ({\r\n ...prev,\r\n name: extractedServerName || prev.name,\r\n url: config.url || '',\r\n headers,\r\n bearerTokenEnvVar: config.bearer_token_env_var || config.bearerTokenEnvVar || '',\r\n }));\r\n } else {\r\n // STDIO transport\r\n setTransportType('stdio');\r\n \r\n const args = Array.isArray(config.args) ? config.args : [];\r\n const env = config.env && typeof config.env === 'object' ? config.env : {};\r\n \r\n setFormData(prev => ({\r\n ...prev,\r\n name: extractedServerName || prev.name,\r\n command: config.command || '',\r\n args,\r\n env,\r\n }));\r\n \r\n setArgsInput(args.join(', '));\r\n setEnvInput(\r\n Object.entries(env)\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('\\n')\r\n );\r\n }\r\n \r\n // Switch to form mode to show parsed data\r\n setInputMode('form');\r\n setErrors({});\r\n showSuccess(\r\n formatMessage({ id: 'mcp.dialog.json.parseSuccess' }),\r\n formatMessage({ id: 'mcp.dialog.json.parseSuccessDesc' })\r\n );\r\n } catch (error) {\r\n setErrors({ \r\n name: formatMessage({ id: 'mcp.dialog.json.parseError' }, { \r\n error: error instanceof Error ? error.message : 'Invalid JSON' \r\n })\r\n });\r\n }\r\n }, [jsonInput, formatMessage, showSuccess]);\r\n\r\n // Initialize form from server prop (edit mode)\r\n useEffect(() => {\r\n if (server && mode === 'edit') {\r\n const detectedType = detectTransportType(server);\r\n setTransportType(detectedType);\r\n\r\n // Parse HTTP headers if present (for HTTP servers)\r\n const httpHeaders: HttpHeader[] = [];\r\n if (isHttpMcpServer(server)) {\r\n // HTTP server - extract headers\r\n if (server.httpHeaders) {\r\n Object.entries(server.httpHeaders).forEach(([name, value], idx) => {\r\n httpHeaders.push({\r\n id: `header-http-${idx}`,\r\n name,\r\n value,\r\n isEnvVar: false,\r\n });\r\n });\r\n }\r\n if (server.envHttpHeaders) {\r\n // envHttpHeaders is an array of header names that get values from env vars\r\n server.envHttpHeaders.forEach((headerName, idx) => {\r\n httpHeaders.push({\r\n id: `header-env-${idx}`,\r\n name: headerName,\r\n value: '', // Env var name is not stored in value\r\n isEnvVar: true,\r\n });\r\n });\r\n }\r\n }\r\n\r\n // Get STDIO fields safely using type guard\r\n const stdioCommand = isStdioMcpServer(server) ? server.command : '';\r\n const stdioArgs = isStdioMcpServer(server) ? (server.args || []) : [];\r\n const stdioEnv = isStdioMcpServer(server) ? (server.env || {}) : {};\r\n\r\n // Get HTTP fields safely using type guard\r\n const httpUrl = isHttpMcpServer(server) ? server.url : '';\r\n const httpBearerToken = isHttpMcpServer(server) ? (server.bearerTokenEnvVar || '') : '';\r\n\r\n setFormData({\r\n name: server.name,\r\n command: stdioCommand,\r\n args: stdioArgs,\r\n env: stdioEnv,\r\n url: httpUrl,\r\n headers: httpHeaders,\r\n bearerTokenEnvVar: httpBearerToken,\r\n scope: server.scope,\r\n enabled: server.enabled,\r\n });\r\n setArgsInput(stdioArgs.join(', '));\r\n setEnvInput(\r\n Object.entries(stdioEnv)\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('\\n')\r\n );\r\n } else {\r\n // Reset form for add mode\r\n setTransportType('stdio');\r\n setFormData({\r\n name: '',\r\n command: '',\r\n args: [],\r\n env: {},\r\n url: '',\r\n headers: [],\r\n bearerTokenEnvVar: '',\r\n scope: 'project',\r\n enabled: true,\r\n });\r\n setArgsInput('');\r\n setEnvInput('');\r\n }\r\n setSelectedTemplate('');\r\n setSaveAsTemplate(false);\r\n setErrors({});\r\n }, [server, mode, open, detectTransportType]);\r\n\r\n // Mutations\r\n const createMutation = useMutation({\r\n mutationFn: ({ server, configType }: { server: McpServer; configType?: McpProjectConfigType }) =>\r\n createMcpServer(server, { projectPath: projectPath ?? undefined, configType }),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n const updateMutation = useMutation({\r\n mutationFn: ({ serverName, config, configType }: { serverName: string; config: Partial<McpServer>; configType?: McpProjectConfigType }) =>\r\n updateMcpServer(serverName, config, { projectPath: projectPath ?? undefined, configType }),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n // Handlers\r\n const handleClose = () => {\r\n setErrors({});\r\n onClose();\r\n };\r\n\r\n const handleTemplateSelect = (templateId: string) => {\r\n const template = templates.find((t) => t.name === templateId);\r\n if (template) {\r\n setFormData((prev) => ({\r\n ...prev,\r\n command: template.serverConfig.command,\r\n args: template.serverConfig.args || [],\r\n env: template.serverConfig.env || {},\r\n }));\r\n setArgsInput((template.serverConfig.args || []).join(', '));\r\n setEnvInput(\r\n Object.entries(template.serverConfig.env || {})\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('\\n')\r\n );\r\n setSelectedTemplate(templateId);\r\n }\r\n };\r\n\r\n const handleFieldChange = (\r\n field: keyof McpServerFormData,\r\n value: string | boolean | string[] | Record<string, string> | HttpHeader[]\r\n ) => {\r\n setFormData((prev) => ({ ...prev, [field]: value }));\r\n // Clear error for this field\r\n if (errors[field as keyof FormErrors]) {\r\n setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n }\r\n };\r\n\r\n const handleArgsChange = (value: string) => {\r\n setArgsInput(value);\r\n const argsArray = value\r\n .split(',')\r\n .map((a) => a.trim())\r\n .filter((a) => a.length > 0);\r\n setFormData((prev) => ({ ...prev, args: argsArray }));\r\n if (errors.args) {\r\n setErrors((prev) => ({ ...prev, args: undefined }));\r\n }\r\n };\r\n\r\n const handleEnvChange = (value: string) => {\r\n setEnvInput(value);\r\n const envObj: Record<string, string> = {};\r\n const lines = value.split('\\n');\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (trimmed && trimmed.includes('=')) {\r\n const [key, ...valParts] = trimmed.split('=');\r\n const val = valParts.join('=');\r\n if (key) {\r\n envObj[key.trim()] = val.trim();\r\n }\r\n }\r\n }\r\n setFormData((prev) => ({ ...prev, env: envObj }));\r\n if (errors.env) {\r\n setErrors((prev) => ({ ...prev, env: undefined }));\r\n }\r\n };\r\n\r\n const handleHeadersChange = (headers: HttpHeader[]) => {\r\n setFormData((prev) => ({ ...prev, headers }));\r\n if (errors.headers) {\r\n setErrors((prev) => ({ ...prev, headers: undefined }));\r\n }\r\n };\r\n\r\n const handleTransportTypeChange = (type: McpTransportType) => {\r\n setTransportType(type);\r\n // Clear relevant errors when switching\r\n setErrors((prev) => ({\r\n ...prev,\r\n command: undefined,\r\n url: undefined,\r\n }));\r\n };\r\n\r\n const validateForm = (): boolean => {\r\n const newErrors: FormErrors = {};\r\n\r\n // Name required\r\n if (!formData.name.trim()) {\r\n newErrors.name = formatMessage({ id: 'mcp.dialog.validation.nameRequired' });\r\n }\r\n\r\n // Transport-specific validation\r\n if (transportType === 'stdio') {\r\n // Command required for STDIO\r\n if (!formData.command.trim()) {\r\n newErrors.command = formatMessage({ id: 'mcp.dialog.validation.commandRequired' });\r\n }\r\n } else {\r\n // URL required for HTTP\r\n if (!formData.url.trim()) {\r\n newErrors.url = formatMessage({ id: 'mcp.dialog.validation.urlRequired' });\r\n }\r\n // Validate URL format\r\n try {\r\n new URL(formData.url);\r\n } catch {\r\n newErrors.url = formatMessage({ id: 'mcp.dialog.validation.urlInvalid' });\r\n }\r\n }\r\n\r\n setErrors(newErrors);\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const checkNameExists = async (name: string): Promise<boolean> => {\r\n try {\r\n const data = await fetchMcpServers(projectPath ?? undefined);\r\n const allServers = [...data.project, ...data.global];\r\n // In edit mode, exclude current server\r\n return allServers.some(\r\n (s) => s.name === name && (mode === 'edit' ? s.name !== server?.name : true)\r\n );\r\n } catch {\r\n return false;\r\n }\r\n };\r\n\r\n const handleSubmit = async () => {\r\n if (!validateForm()) {\r\n return;\r\n }\r\n\r\n // Check name uniqueness\r\n if (await checkNameExists(formData.name)) {\r\n setErrors({ name: formatMessage({ id: 'mcp.dialog.validation.nameExists' }) });\r\n return;\r\n }\r\n\r\n // Build server config based on transport type using discriminated union\r\n let serverConfig: McpServer;\r\n\r\n if (transportType === 'stdio') {\r\n serverConfig = {\r\n name: formData.name,\r\n transport: 'stdio',\r\n command: formData.command,\r\n args: formData.args.length > 0 ? formData.args : undefined,\r\n env: Object.keys(formData.env).length > 0 ? formData.env : undefined,\r\n scope: formData.scope,\r\n enabled: formData.enabled,\r\n };\r\n } else {\r\n // HTTP transport - separate headers into static and env-based\r\n const httpHeaders: Record<string, string> = {};\r\n const envHttpHeaders: string[] = [];\r\n\r\n formData.headers.forEach((h) => {\r\n if (h.name.trim()) {\r\n if (h.isEnvVar) {\r\n // For env-based headers, store the header name that will be populated from env var\r\n envHttpHeaders.push(h.name.trim());\r\n } else {\r\n httpHeaders[h.name.trim()] = h.value.trim();\r\n }\r\n }\r\n });\r\n\r\n serverConfig = {\r\n name: formData.name,\r\n transport: 'http',\r\n url: formData.url,\r\n headers: Object.keys(httpHeaders).length > 0 ? httpHeaders : undefined,\r\n httpHeaders: Object.keys(httpHeaders).length > 0 ? httpHeaders : undefined,\r\n envHttpHeaders: envHttpHeaders.length > 0 ? envHttpHeaders : undefined,\r\n bearerTokenEnvVar: formData.bearerTokenEnvVar.trim() || undefined,\r\n scope: formData.scope,\r\n enabled: formData.enabled,\r\n };\r\n }\r\n\r\n // Save as template if checked (only for STDIO)\r\n if (saveAsTemplate && transportType === 'stdio') {\r\n try {\r\n await saveMcpTemplate({\r\n name: formData.name,\r\n category: 'custom',\r\n serverConfig: {\r\n command: formData.command,\r\n args: formData.args.length > 0 ? formData.args : undefined,\r\n env: Object.keys(formData.env).length > 0 ? formData.env : undefined,\r\n },\r\n });\r\n } catch (err) {\r\n showError(formatMessage({ id: 'mcp.templates.feedback.saveError' }), err instanceof Error ? err.message : String(err));\r\n // Template save failure should not block server creation\r\n }\r\n }\r\n\r\n if (mode === 'add') {\r\n createMutation.mutate({\r\n server: serverConfig,\r\n configType: formData.scope === 'project' ? projectConfigType : undefined,\r\n });\r\n } else {\r\n updateMutation.mutate({\r\n serverName: server!.name,\r\n config: serverConfig,\r\n configType: formData.scope === 'project' ? projectConfigType : undefined,\r\n });\r\n }\r\n };\r\n\r\n const isPending = createMutation.isPending || updateMutation.isPending;\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleClose}>\r\n <DialogContent className=\"max-w-2xl max-h-[90vh] overflow-y-auto\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {mode === 'add'\r\n ? formatMessage({ id: 'mcp.dialog.addTitle' })\r\n : formatMessage({ id: 'mcp.dialog.editTitle' }, { name: server?.name })}\r\n </DialogTitle>\r\n </DialogHeader>\r\n\r\n {/* Input Mode Switcher - Only in add mode */}\r\n {mode === 'add' && (\r\n <div className=\"flex gap-2 border-b pb-3\">\r\n <Button\r\n type=\"button\"\r\n variant={inputMode === 'form' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setInputMode('form')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.dialog.mode.form' })}\r\n </Button>\r\n <Button\r\n type=\"button\"\r\n variant={inputMode === 'json' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setInputMode('json')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.dialog.mode.json' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n <div className=\"space-y-4\">\r\n {/* JSON Input Mode */}\r\n {inputMode === 'json' ? (\r\n <div className=\"space-y-4\">\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.json.label' })}\r\n </label>\r\n <textarea\r\n value={jsonInput}\r\n onChange={(e) => setJsonInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.json.placeholder' })}\r\n className={cn(\r\n 'flex min-h-[300px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 font-mono',\r\n errors.name && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.json.hint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Example JSON */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.json.example' })}\r\n </label>\r\n <div className=\"bg-muted p-3 rounded-md\">\r\n <p className=\"text-xs font-medium mb-2\">STDIO:</p>\r\n <pre className=\"text-xs overflow-x-auto\">\r\n{`{\r\n \"command\": \"npx\",\r\n \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/path\"],\r\n \"env\": {\r\n \"API_KEY\": \"your-key\"\r\n }\r\n}`}\r\n </pre>\r\n <p className=\"text-xs font-medium mt-3 mb-2\">HTTP:</p>\r\n <pre className=\"text-xs overflow-x-auto\">\r\n{`{\r\n \"url\": \"http://localhost:3000\",\r\n \"headers\": {\r\n \"Authorization\": \"Bearer token\"\r\n }\r\n}`}\r\n </pre>\r\n </div>\r\n </div>\r\n\r\n <Button\r\n type=\"button\"\r\n onClick={parseJsonConfig}\r\n disabled={!jsonInput.trim()}\r\n className=\"w-full\"\r\n >\r\n {formatMessage({ id: 'mcp.dialog.json.parse' })}\r\n </Button>\r\n </div>\r\n ) : (\r\n <>\r\n {/* Template Selector - Only for STDIO */}\r\n {transportType === 'stdio' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.template' })}\r\n </label>\r\n <Select value={selectedTemplate} onValueChange={handleTemplateSelect} disabled={templatesLoading}>\r\n <SelectTrigger className=\"w-full\">\r\n <SelectValue\r\n placeholder={templatesLoading\r\n ? formatMessage({ id: 'mcp.templates.loading' })\r\n : formatMessage({ id: 'mcp.dialog.form.templatePlaceholder' })\r\n }\r\n />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {templates.length === 0 ? (\r\n <SelectItem value=\"__empty__\" disabled>\r\n {formatMessage({ id: 'mcp.templates.empty.title' })}\r\n </SelectItem>\r\n ) : (\r\n templates.map((template) => (\r\n <SelectItem key={template.name} value={template.name}>\r\n <div className=\"flex flex-col\">\r\n <span className=\"font-medium\">{template.name}</span>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {template.description || formatMessage({ id: 'mcp.dialog.form.templatePlaceholder' })}\r\n </span>\r\n </div>\r\n </SelectItem>\r\n ))\r\n )}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n )}\r\n\r\n {/* Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.name' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.name}\r\n onChange={(e) => handleFieldChange('name', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.namePlaceholder' })}\r\n error={!!errors.name}\r\n disabled={mode === 'edit'} // Name cannot be changed in edit mode\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n </div>\r\n\r\n {/* Transport Type Selector */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportType' })}\r\n </label>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"transportType\"\r\n value=\"stdio\"\r\n checked={transportType === 'stdio'}\r\n onChange={() => handleTransportTypeChange('stdio')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <Terminal className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportStdio' })}\r\n </span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"transportType\"\r\n value=\"http\"\r\n checked={transportType === 'http'}\r\n onChange={() => handleTransportTypeChange('http')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <Globe className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportHttp' })}\r\n </span>\r\n </label>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.transportHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* STDIO Fields */}\r\n {transportType === 'stdio' && (\r\n <>\r\n {/* Command */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.command' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.command}\r\n onChange={(e) => handleFieldChange('command', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.commandPlaceholder' })}\r\n error={!!errors.command}\r\n />\r\n {errors.command && (\r\n <p className=\"text-sm text-destructive\">{errors.command}</p>\r\n )}\r\n </div>\r\n\r\n {/* Args */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.args' })}\r\n </label>\r\n <Input\r\n value={argsInput}\r\n onChange={(e) => handleArgsChange(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.argsPlaceholder' })}\r\n error={!!errors.args}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.argsHint' })}\r\n </p>\r\n {formData.args.length > 0 && (\r\n <div className=\"flex flex-wrap gap-1 mt-2\">\r\n {formData.args.map((arg, idx) => (\r\n <Badge key={idx} variant=\"secondary\" className=\"font-mono text-xs\">\r\n {arg}\r\n </Badge>\r\n ))}\r\n </div>\r\n )}\r\n {errors.args && (\r\n <p className=\"text-sm text-destructive\">{errors.args}</p>\r\n )}\r\n </div>\r\n\r\n {/* Environment Variables */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.env' })}\r\n </label>\r\n <textarea\r\n value={envInput}\r\n onChange={(e) => handleEnvChange(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.envPlaceholder' })}\r\n className={cn(\r\n 'flex min-h-[100px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\r\n errors.env && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.envHint' })}\r\n </p>\r\n {Object.keys(formData.env).length > 0 && (\r\n <div className=\"space-y-1 mt-2\">\r\n {Object.entries(formData.env).map(([key, value]) => (\r\n <div key={key} className=\"flex items-center gap-2 text-sm\">\r\n <Badge variant=\"outline\" className=\"font-mono\">\r\n {key}\r\n </Badge>\r\n <span className=\"text-muted-foreground\">=</span>\r\n <code className=\"text-xs bg-muted px-2 py-1 rounded flex-1 overflow-x-auto\">\r\n {value}\r\n </code>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n {errors.env && (\r\n <p className=\"text-sm text-destructive\">{errors.env}</p>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* HTTP Fields */}\r\n {transportType === 'http' && (\r\n <>\r\n {/* URL */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.url' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.url}\r\n onChange={(e) => handleFieldChange('url', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.urlPlaceholder' })}\r\n error={!!errors.url}\r\n />\r\n {errors.url && (\r\n <p className=\"text-sm text-destructive\">{errors.url}</p>\r\n )}\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.urlHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Bearer Token Env Var */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.bearerToken' })}\r\n </label>\r\n <Input\r\n value={formData.bearerTokenEnvVar}\r\n onChange={(e) => handleFieldChange('bearerTokenEnvVar', e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.http.bearerTokenPlaceholder' })}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.bearerTokenHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* HTTP Headers */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.headers' })}\r\n </label>\r\n <HttpHeadersInput\r\n headers={formData.headers}\r\n onChange={handleHeadersChange}\r\n disabled={isPending}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.http.headersHint' })}\r\n </p>\r\n {errors.headers && (\r\n <p className=\"text-sm text-destructive\">{errors.headers}</p>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n\r\n {/* Scope */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.scope' })}\r\n </label>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"scope\"\r\n value=\"project\"\r\n checked={formData.scope === 'project'}\r\n onChange={(e) => handleFieldChange('scope', e.target.value as 'project' | 'global')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.scope.project' })}\r\n </span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"scope\"\r\n value=\"global\"\r\n checked={formData.scope === 'global'}\r\n onChange={(e) => handleFieldChange('scope', e.target.value as 'project' | 'global')}\r\n className=\"w-4 h-4\"\r\n disabled={mode === 'edit'}\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'mcp.scope.global' })}\r\n </span>\r\n </label>\r\n </div>\r\n\r\n {/* Config Type Toggle - Only for project scope */}\r\n {formData.scope === 'project' && (\r\n <div className=\"flex items-center gap-2 mt-2 pl-6\">\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.configType.format' })}:\r\n </span>\r\n <ConfigTypeToggle\r\n currentType={configType}\r\n onTypeChange={setConfigType}\r\n showWarning={false}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Enabled */}\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"enabled\"\r\n checked={formData.enabled}\r\n onChange={(e) => handleFieldChange('enabled', e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <label htmlFor=\"enabled\" className=\"text-sm font-medium text-foreground cursor-pointer\">\r\n {formatMessage({ id: 'mcp.dialog.form.enabled' })}\r\n </label>\r\n </div>\r\n\r\n {/* Save as Template - Only for STDIO */}\r\n {transportType === 'stdio' && (\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"save-as-template\"\r\n checked={saveAsTemplate}\r\n onChange={(e) => setSaveAsTemplate(e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <label htmlFor=\"save-as-template\" className=\"text-sm font-medium text-foreground cursor-pointer\">\r\n {formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}\r\n </label>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleClose}\r\n disabled={isPending}\r\n >\r\n {formatMessage({ id: 'mcp.dialog.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n disabled={isPending}\r\n >\r\n {isPending\r\n ? formatMessage({ id: 'mcp.dialog.actions.saving' })\r\n : formatMessage({ id: 'mcp.dialog.actions.save' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default McpServerDialog;\r\n","// ========================================\r\n// Codex MCP Editable Card Component\r\n// ========================================\r\n// Editable Codex MCP server card with remove and toggle actions\r\n// Extends CodexMcpCard with additional action buttons when editing is enabled\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Server,\r\n Power,\r\n PowerOff,\r\n ChevronDown,\r\n ChevronUp,\r\n Edit3,\r\n Trash2,\r\n Lock,\r\n Link,\r\n Eye,\r\n EyeOff,\r\n} from 'lucide-react';\r\nimport {\r\n AlertDialog,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n AlertDialogContent,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n AlertDialogTrigger,\r\n} from '@/components/ui/AlertDialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\nimport type { McpServer } from '@/lib/api';\r\nimport { isHttpMcpServer, isStdioMcpServer } from '@/lib/api';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface CodexMcpEditableCardProps {\r\n server: McpServer;\r\n enabled: boolean;\r\n isExpanded: boolean;\r\n onToggleExpand: () => void;\r\n /** When enabled, shows remove/toggle buttons instead of read-only badge */\r\n isEditable?: boolean;\r\n /** Callback when server is removed (after confirmation) */\r\n onRemove?: (serverName: string) => void | Promise<void>;\r\n /** Callback when server is toggled */\r\n onToggle?: (serverName: string, enabled: boolean) => void | Promise<void>;\r\n /** Whether remove operation is in progress */\r\n isRemoving?: boolean;\r\n /** Whether toggle operation is in progress */\r\n isToggling?: boolean;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\n/**\r\n * Mask a header value for display (show first 4 chars + ***)\r\n */\r\nfunction maskHeaderValue(value: string): string {\r\n if (!value || value.length <= 4) return '****';\r\n return value.substring(0, 4) + '****';\r\n}\r\n\r\nexport function CodexMcpEditableCard({\r\n server,\r\n enabled,\r\n isExpanded,\r\n onToggleExpand,\r\n isEditable = false,\r\n onRemove,\r\n onToggle,\r\n isRemoving = false,\r\n isToggling = false,\r\n}: CodexMcpEditableCardProps) {\r\n const { formatMessage } = useIntl();\r\n const [isConfirmDeleteOpen, setIsConfirmDeleteOpen] = useState(false);\r\n const [showHeaderValues, setShowHeaderValues] = useState<Record<string, boolean>>({});\r\n\r\n const isHttp = isHttpMcpServer(server);\r\n const isStdio = isStdioMcpServer(server);\r\n\r\n // Get display text for server summary line\r\n const getServerSummary = () => {\r\n if (isHttp) {\r\n return server.url;\r\n }\r\n return `${server.command || ''} ${server.args?.join(' ') || ''}`.trim();\r\n };\r\n\r\n // Get all headers for HTTP server (Codex format: http_headers, env_http_headers, bearerTokenEnvVar)\r\n const getHttpHeaders = (): Array<{ name: string; value: string; isEnvVar?: boolean }> => {\r\n if (!isHttp) return [];\r\n\r\n const headers: Array<{ name: string; value: string; isEnvVar?: boolean }> = [];\r\n\r\n // Codex format: httpHeaders object\r\n if (server.httpHeaders) {\r\n Object.entries(server.httpHeaders).forEach(([name, value]) => {\r\n headers.push({ name, value });\r\n });\r\n }\r\n\r\n // Codex format: bearerTokenEnvVar (adds Authorization header)\r\n if (server.bearerTokenEnvVar) {\r\n headers.push({\r\n name: 'Authorization',\r\n value: `Bearer $${server.bearerTokenEnvVar}`,\r\n isEnvVar: true,\r\n });\r\n }\r\n\r\n // Claude format: headers object (for compatibility)\r\n if (server.headers) {\r\n Object.entries(server.headers).forEach(([name, value]) => {\r\n headers.push({ name, value });\r\n });\r\n }\r\n\r\n return headers;\r\n };\r\n\r\n // Toggle header value visibility\r\n const toggleHeaderValue = (headerName: string) => {\r\n setShowHeaderValues(prev => ({\r\n ...prev,\r\n [headerName]: !prev[headerName]\r\n }));\r\n };\r\n\r\n // Handle toggle with optimistic update\r\n const handleToggle = async () => {\r\n if (onToggle) {\r\n await onToggle(server.name, !enabled);\r\n }\r\n };\r\n\r\n // Handle remove with confirmation\r\n const handleRemove = async () => {\r\n if (onRemove) {\r\n await onRemove(server.name);\r\n setIsConfirmDeleteOpen(false);\r\n }\r\n };\r\n\r\n // Prevent click propagation when clicking action buttons\r\n const stopPropagation = (e: React.MouseEvent) => {\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <Card className={cn('overflow-hidden', !enabled && 'opacity-60')}>\r\n {/* Header */}\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={onToggleExpand}\r\n >\r\n <div className=\"flex items-start justify-between gap-2\">\r\n <div className=\"flex items-start gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n enabled ? 'bg-primary/10' : 'bg-muted'\r\n )}>\r\n <Server className={cn(\r\n 'w-5 h-5',\r\n enabled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {server.name}\r\n </span>\r\n {/* Transport type badge */}\r\n {isHttp && (\r\n <Badge variant=\"outline\" className=\"text-xs text-blue-600 border-blue-300\">\r\n <Link className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.transport.http' })}\r\n </Badge>\r\n )}\r\n {isEditable ? (\r\n <>\r\n {/* Editable badge with actions */}\r\n <Badge variant=\"secondary\" className=\"text-xs flex items-center gap-1\">\r\n <Edit3 className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.codex.editable' })}\r\n </Badge>\r\n {enabled && (\r\n <Badge variant=\"outline\" className=\"text-xs text-green-600\">\r\n <Power className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n {/* Read-only badge */}\r\n <Badge variant=\"secondary\" className=\"text-xs flex items-center gap-1\">\r\n <Lock className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.codex.readOnly' })}\r\n </Badge>\r\n {enabled && (\r\n <Badge variant=\"outline\" className=\"text-xs text-green-600\">\r\n <Power className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1 font-mono truncate max-w-md\" title={getServerSummary()}>\r\n {getServerSummary()}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n {isEditable ? (\r\n <>\r\n {/* Toggle button (active in editable mode) */}\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={(e) => {\r\n stopPropagation(e);\r\n handleToggle();\r\n }}\r\n disabled={isToggling}\r\n >\r\n {enabled ? (\r\n <Power className=\"w-4 h-4 text-green-600\" />\r\n ) : (\r\n <PowerOff className=\"w-4 h-4 text-muted-foreground\" />\r\n )}\r\n </Button>\r\n\r\n {/* Remove button with confirmation */}\r\n <AlertDialog open={isConfirmDeleteOpen} onOpenChange={setIsConfirmDeleteOpen}>\r\n <AlertDialogTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-8 w-8 p-0\"\r\n onClick={stopPropagation}\r\n disabled={isRemoving}\r\n >\r\n <Trash2 className=\"w-4 h-4 text-destructive\" />\r\n </Button>\r\n </AlertDialogTrigger>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.title' }, { name: server.name })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.description' }, { name: server.name })}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel disabled={isRemoving}>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n onClick={handleRemove}\r\n disabled={isRemoving}\r\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n >\r\n {isRemoving ? (\r\n <>\r\n <span className=\"animate-spin mr-2\">◌</span>\r\n {formatMessage({ id: 'mcp.codex.deleteConfirm.deleting' })}\r\n </>\r\n ) : (\r\n formatMessage({ id: 'mcp.codex.deleteConfirm.confirm' })\r\n )}\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </>\r\n ) : (\r\n <>\r\n {/* Disabled toggle button (visual only, no edit capability) */}\r\n <div className={cn(\r\n 'w-8 h-8 rounded-md flex items-center justify-center',\r\n enabled ? 'bg-green-100 text-green-600' : 'bg-muted text-muted-foreground'\r\n )}>\r\n {enabled ? <Power className=\"w-4 h-4\" /> : <PowerOff className=\"w-4 h-4\" />}\r\n </div>\r\n </>\r\n )}\r\n {isExpanded ? (\r\n <ChevronUp className=\"w-5 h-5 text-muted-foreground\" />\r\n ) : (\r\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border p-4 space-y-3 bg-muted/30\">\r\n {/* HTTP Server Details */}\r\n {isHttp && (\r\n <>\r\n {/* URL */}\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.url' })}</p>\r\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto break-all\">\r\n {server.url}\r\n </code>\r\n </div>\r\n\r\n {/* HTTP Headers */}\r\n {getHttpHeaders().length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.headers' })}</p>\r\n <div className=\"space-y-1\">\r\n {getHttpHeaders().map((header) => (\r\n <div key={header.name} className=\"flex items-center gap-2 text-sm\">\r\n <Badge variant=\"secondary\" className=\"font-mono\">{header.name}</Badge>\r\n <span className=\"text-muted-foreground\">=</span>\r\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\r\n {showHeaderValues[header.name] ? header.value : maskHeaderValue(header.value)}\r\n </code>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-6 w-6 p-0\"\r\n onClick={() => toggleHeaderValue(header.name)}\r\n title={showHeaderValues[header.name]\r\n ? formatMessage({ id: 'mcp.http.hideValue' })\r\n : formatMessage({ id: 'mcp.http.showValue' })}\r\n >\r\n {showHeaderValues[header.name] ? (\r\n <EyeOff className=\"w-3 h-3 text-muted-foreground\" />\r\n ) : (\r\n <Eye className=\"w-3 h-3 text-muted-foreground\" />\r\n )}\r\n </Button>\r\n {header.isEnvVar && (\r\n <Badge variant=\"outline\" className=\"text-xs text-blue-500\">\r\n {formatMessage({ id: 'mcp.http.envVar' })}\r\n </Badge>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* STDIO Server Details */}\r\n {isStdio && (\r\n <>\r\n {/* Command details */}\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.command' })}</p>\r\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto\">\r\n {server.command}\r\n </code>\r\n </div>\r\n\r\n {/* Args */}\r\n {server.args && server.args.length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.args' })}</p>\r\n <div className=\"flex flex-wrap gap-1\">\r\n {server.args.map((arg, idx) => (\r\n <Badge key={idx} variant=\"outline\" className=\"font-mono text-xs\">\r\n {arg}\r\n </Badge>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Environment variables */}\r\n {server.env && Object.keys(server.env).length > 0 && (\r\n <div>\r\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.env' })}</p>\r\n <div className=\"space-y-1\">\r\n {Object.entries(server.env).map(([key, value]) => (\r\n <div key={key} className=\"flex items-center gap-2 text-sm\">\r\n <Badge variant=\"secondary\" className=\"font-mono\">{key}</Badge>\r\n <span className=\"text-muted-foreground\">=</span>\r\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\r\n {value as string}\r\n </code>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* Notice based on editable state */}\r\n <div className={cn(\r\n 'flex items-center gap-2 px-3 py-2 rounded-md border',\r\n isEditable\r\n ? 'bg-info/10 border-info/20'\r\n : 'bg-muted/50 border-border'\r\n )}>\r\n {isEditable ? (\r\n <>\r\n <Edit3 className=\"w-4 h-4 text-info\" />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.codex.editableNotice' })}\r\n </p>\r\n </>\r\n ) : (\r\n <>\r\n <Lock className=\"w-4 h-4 text-muted-foreground\" />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.codex.readOnlyNotice' })}\r\n </p>\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\nexport default CodexMcpEditableCard;\r\n","// ========================================\r\n// CCW Tools MCP Card Component\r\n// ========================================\r\n// Special card component for CCW Tools MCP server configuration\r\n// Displays tool checkboxes, path settings, and install/uninstall actions\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation } from '@tanstack/react-query';\r\nimport {\r\n Settings,\r\n Check,\r\n FolderTree,\r\n FolderOpen,\r\n Database,\r\n FileText,\r\n Files,\r\n HardDrive,\r\n MessageCircleQuestion,\r\n MessagesSquare,\r\n ChevronDown,\r\n ChevronRight,\r\n Globe,\r\n Folder,\r\n AlertTriangle,\r\n Save,\r\n Download,\r\n Trash2,\r\n} from 'lucide-react';\r\nimport { FloatingFileBrowser } from '@/components/terminal-dashboard/FloatingFileBrowser';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n installCcwMcp,\r\n uninstallCcwMcp,\r\n updateCcwConfig,\r\n installCcwMcpToCodex,\r\n uninstallCcwMcpFromCodex,\r\n updateCcwConfigForCodex,\r\n} from '@/lib/api';\r\nimport { mcpServersKeys, useNotifications } from '@/hooks';\r\nimport { useQueryClient } from '@tanstack/react-query';\r\nimport { cn } from '@/lib/utils';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * CCW Tool definition with name, description, and core flag\r\n */\r\nexport interface CcwTool {\r\n name: string;\r\n desc: string;\r\n core: boolean;\r\n}\r\n\r\n/**\r\n * CCW MCP configuration interface\r\n */\r\nexport interface CcwConfig {\r\n enabledTools: string[];\r\n projectRoot?: string;\r\n allowedDirs?: string;\r\n enableSandbox?: boolean;\r\n}\r\n\r\n/**\r\n * Props for CcwToolsMcpCard component\r\n */\r\nexport interface CcwToolsMcpCardProps {\r\n /** Whether CCW MCP is installed */\r\n isInstalled: boolean;\r\n /** List of enabled tool names */\r\n enabledTools: string[];\r\n /** Project root path */\r\n projectRoot?: string;\r\n /** Comma-separated list of allowed directories */\r\n allowedDirs?: string;\r\n /** Whether sandbox is disabled */\r\n enableSandbox?: boolean;\r\n /** Callback when a tool is toggled */\r\n onToggleTool: (tool: string, enabled: boolean) => void;\r\n /** Callback when configuration is updated */\r\n onUpdateConfig: (config: Partial<CcwConfig>) => void;\r\n /** Callback when install/uninstall is triggered */\r\n onInstall: () => void;\r\n /** Installation target: Claude or Codex */\r\n target?: 'claude' | 'codex';\r\n /** Scopes where CCW MCP is currently installed */\r\n installedScopes?: ('global' | 'project')[];\r\n /** Callback to uninstall from a specific scope */\r\n onUninstallScope?: (scope: 'global' | 'project') => void;\r\n /** Callback to install to an additional scope */\r\n onInstallToScope?: (scope: 'global' | 'project') => void;\r\n}\r\n\r\n// ========== Constants ==========\r\n\r\n/**\r\n * CCW MCP Tools definition\r\n * Available tools that can be enabled/disabled in CCW MCP server\r\n */\r\nexport const CCW_MCP_TOOLS: CcwTool[] = [\r\n { name: 'write_file', desc: 'Write/create files', core: true },\r\n { name: 'edit_file', desc: 'Edit/replace content', core: true },\r\n { name: 'read_file', desc: 'Read single file', core: true },\r\n { name: 'read_many_files', desc: 'Read multiple files/dirs', core: true },\r\n { name: 'core_memory', desc: 'Core memory management', core: true },\r\n { name: 'ask_question', desc: 'Interactive questions (A2UI)', core: false },\r\n { name: 'team_msg', desc: 'Agent team message bus', core: false },\r\n];\r\n\r\n// ========== Component ==========\r\n\r\nexport function CcwToolsMcpCard({\r\n isInstalled,\r\n enabledTools,\r\n projectRoot,\r\n allowedDirs,\r\n enableSandbox,\r\n onToggleTool,\r\n onUpdateConfig,\r\n onInstall,\r\n target = 'claude',\r\n installedScopes = [],\r\n onUninstallScope,\r\n}: CcwToolsMcpCardProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n const { success: notifySuccess, error: notifyError } = useNotifications();\r\n const currentProjectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Local state for config inputs\r\n const [projectRootInput, setProjectRootInput] = useState(projectRoot || '');\r\n const [allowedDirsInput, setAllowedDirsInput] = useState(allowedDirs || '');\r\n const [enableSandboxInput, setEnableSandboxInput] = useState(enableSandbox || false);\r\n void setEnableSandboxInput; // reserved for future sandbox toggle UI\r\n const [isExpanded, setIsExpanded] = useState(false);\r\n const [installScope, setInstallScope] = useState<'global' | 'project'>('global');\r\n const [isPathPickerOpen, setIsPathPickerOpen] = useState(false);\r\n const [pathPickerTarget, setPathPickerTarget] = useState<'projectRoot' | 'allowedDirs' | null>(null);\r\n\r\n const isCodex = target === 'codex';\r\n\r\n // Mutations for install/uninstall\r\n const installMutation = useMutation({\r\n mutationFn: isCodex\r\n ? () => installCcwMcpToCodex()\r\n : (params: { scope: 'global' | 'project'; projectPath?: string }) =>\r\n installCcwMcp(params.scope, params.projectPath),\r\n onSuccess: () => {\r\n if (isCodex) {\r\n queryClient.invalidateQueries({ queryKey: ['codexMcpServers'] });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfigCodex'] });\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n }\r\n onInstall();\r\n },\r\n });\r\n\r\n const uninstallMutation = useMutation({\r\n mutationFn: isCodex ? uninstallCcwMcpFromCodex : uninstallCcwMcp,\r\n onSuccess: () => {\r\n if (isCodex) {\r\n queryClient.invalidateQueries({ queryKey: ['codexMcpServers'] });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfigCodex'] });\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n }\r\n onInstall();\r\n },\r\n onError: (error) => {\r\n console.error('Failed to uninstall CCW MCP:', error);\r\n },\r\n });\r\n\r\n const updateConfigMutation = useMutation({\r\n mutationFn: isCodex ? updateCcwConfigForCodex : updateCcwConfig,\r\n onSuccess: () => {\r\n if (isCodex) {\r\n queryClient.invalidateQueries({ queryKey: ['codexMcpServers'] });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfigCodex'] });\r\n } else {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n queryClient.invalidateQueries({ queryKey: ['ccwMcpConfig'] });\r\n }\r\n notifySuccess(formatMessage({ id: 'mcp.ccw.feedback.saveSuccess' }));\r\n },\r\n onError: (error) => {\r\n console.error('Failed to update CCW config:', error);\r\n notifyError(\r\n formatMessage({ id: 'mcp.ccw.feedback.saveError' }),\r\n error instanceof Error ? error.message : String(error)\r\n );\r\n },\r\n });\r\n\r\n // Handlers\r\n const handleToggleTool = (toolName: string, enabled: boolean) => {\r\n onToggleTool(toolName, enabled);\r\n };\r\n\r\n const handleEnableAll = () => {\r\n const allToolNames = CCW_MCP_TOOLS.map((t) => t.name);\r\n onUpdateConfig({ enabledTools: allToolNames });\r\n };\r\n\r\n const handleDisableAll = () => {\r\n onUpdateConfig({ enabledTools: [] });\r\n };\r\n\r\n const handleConfigSave = () => {\r\n updateConfigMutation.mutate({\r\n enabledTools,\r\n projectRoot: projectRootInput || undefined,\r\n allowedDirs: allowedDirsInput || undefined,\r\n enableSandbox: enableSandboxInput,\r\n });\r\n };\r\n\r\n const handleInstallClick = () => {\r\n if (isCodex) {\r\n (installMutation as any).mutate(undefined);\r\n } else {\r\n (installMutation as any).mutate({\r\n scope: installScope,\r\n projectPath: installScope === 'project' ? currentProjectPath : undefined,\r\n });\r\n }\r\n };\r\n\r\n const handleUninstallClick = () => {\r\n if (confirm(formatMessage({ id: 'mcp.ccw.actions.uninstallConfirm' }))) {\r\n uninstallMutation.mutate();\r\n }\r\n };\r\n\r\n const isPending = installMutation.isPending || uninstallMutation.isPending || updateConfigMutation.isPending;\r\n\r\n return (\r\n <Card className={cn(\r\n 'overflow-hidden border-2',\r\n isInstalled ? 'border-primary/50 bg-primary/5' : 'border-dashed'\r\n )}>\r\n {/* Header */}\r\n <div\r\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\r\n onClick={() => setIsExpanded(!isExpanded)}\r\n >\r\n <div className=\"flex items-start justify-between gap-2\">\r\n <div className=\"flex items-start gap-3\">\r\n <div className={cn(\r\n 'p-2 rounded-lg',\r\n isInstalled ? 'bg-primary/20' : 'bg-muted'\r\n )}>\r\n <Settings className={cn(\r\n 'w-5 h-5',\r\n isInstalled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.ccw.title' })}\r\n </span>\r\n {isInstalled && installedScopes.length > 0 ? (\r\n <>\r\n {installedScopes.map((s) => (\r\n <Badge key={s} variant=\"default\" className=\"text-xs\">\r\n {s === 'global' ? <Globe className=\"w-3 h-3 mr-1\" /> : <Folder className=\"w-3 h-3 mr-1\" />}\r\n {formatMessage({ id: `mcp.ccw.scope.${s}` })}\r\n </Badge>\r\n ))}\r\n {installedScopes.length >= 2 && (\r\n <Badge variant=\"outline\" className=\"text-xs text-orange-500 border-orange-300\">\r\n <AlertTriangle className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.conflict.badge' })}\r\n </Badge>\r\n )}\r\n </>\r\n ) : (\r\n <Badge variant={isInstalled ? 'default' : 'secondary'} className=\"text-xs\">\r\n {isInstalled ? formatMessage({ id: 'mcp.ccw.status.installed' }) : formatMessage({ id: 'mcp.ccw.status.notInstalled' })}\r\n </Badge>\r\n )}\r\n {isCodex && (\r\n <Badge variant=\"outline\" className=\"text-xs text-blue-500\">\r\n Codex\r\n </Badge>\r\n )}\r\n {isInstalled && (\r\n <Badge variant=\"outline\" className=\"text-xs text-info\">\r\n {formatMessage({ id: 'mcp.ccw.status.special' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'mcp.ccw.description' })}\r\n </p>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n {isExpanded ? (\r\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\r\n ) : (\r\n <ChevronRight className=\"w-5 h-5 text-muted-foreground\" />\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Expanded Content */}\r\n {isExpanded && (\r\n <div className=\"border-t border-border p-4 space-y-4 bg-muted/30\">\r\n {/* Quick Select Buttons */}\r\n <div className=\"flex items-center gap-2\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleEnableAll}\r\n disabled={!isInstalled}\r\n >\r\n <Check className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.enableAll' })}\r\n </Button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleDisableAll}\r\n disabled={!isInstalled}\r\n >\r\n {formatMessage({ id: 'mcp.ccw.actions.disableAll' })}\r\n </Button>\r\n </div>\r\n\r\n {/* Tool Checkboxes */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <p className=\"text-xs font-medium text-muted-foreground uppercase\">\r\n {formatMessage({ id: 'mcp.ccw.tools.label' })}\r\n </p>\r\n {!isInstalled && (\r\n <p className=\"text-xs text-amber-600 dark:text-amber-500\">\r\n {formatMessage({ id: 'mcp.ccw.tools.hint' })}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"grid grid-cols-2 gap-2\">\r\n {CCW_MCP_TOOLS.map((tool) => {\r\n const isEnabled = enabledTools.includes(tool.name);\r\n const icon = getToolIcon(tool.name);\r\n\r\n return (\r\n <div\r\n key={tool.name}\r\n className={cn(\r\n 'flex items-center gap-3 p-2 rounded-lg transition-colors border',\r\n isEnabled ? 'bg-background border-primary/40' : 'bg-background border-border'\r\n )}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n id={`ccw-tool-${tool.name}`}\r\n checked={isEnabled}\r\n onChange={(e) => handleToggleTool(tool.name, e.target.checked)}\r\n disabled={!isInstalled}\r\n className=\"w-4 h-4\"\r\n />\r\n <label\r\n htmlFor={`ccw-tool-${tool.name}`}\r\n className=\"flex items-center gap-2 flex-1 cursor-pointer\"\r\n >\r\n {icon}\r\n <div className=\"flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: `mcp.ccw.tools.${tool.name}.name` })}\r\n </span>\r\n {tool.core && (\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.ccw.tools.core' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: `mcp.ccw.tools.${tool.name}.desc` })}\r\n </p>\r\n </div>\r\n </label>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n {/* Project Root */}\r\n <div className=\"space-y-1\">\r\n <label className=\"text-sm text-foreground flex items-center gap-1\">\r\n <FolderTree className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'mcp.ccw.paths.projectRoot' })}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n <Input\r\n value={projectRootInput}\r\n onChange={(e) => setProjectRootInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.ccw.paths.projectRootPlaceholder' })}\r\n disabled={!isInstalled}\r\n className=\"font-mono text-sm\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n onClick={() => {\r\n setPathPickerTarget('projectRoot');\r\n setIsPathPickerOpen(true);\r\n }}\r\n disabled={!isInstalled}\r\n title=\"Browse for project root\"\r\n >\r\n <FolderOpen className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Allowed Dirs */}\r\n <div className=\"space-y-1\">\r\n <label className=\"text-sm text-foreground flex items-center gap-1\">\r\n <HardDrive className=\"w-4 h-4\" />\r\n {formatMessage({ id: 'mcp.ccw.paths.allowedDirs' })}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n <Input\r\n value={allowedDirsInput}\r\n onChange={(e) => setAllowedDirsInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.ccw.paths.allowedDirsPlaceholder' })}\r\n disabled={!isInstalled}\r\n className=\"font-mono text-sm\"\r\n />\r\n <Button\r\n variant=\"outline\"\r\n size=\"icon\"\r\n onClick={() => {\r\n setPathPickerTarget('allowedDirs');\r\n setIsPathPickerOpen(true);\r\n }}\r\n disabled={!isInstalled}\r\n title=\"Browse for allowed directories\"\r\n >\r\n <FolderOpen className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.ccw.paths.allowedDirsHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Save Config Button */}\r\n {isInstalled && (\r\n <div className=\"flex justify-end\">\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={handleConfigSave}\r\n disabled={isPending}\r\n >\r\n <Save className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.saveConfig' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Install / Uninstall Section */}\r\n <div className=\"border-t border-border pt-4 space-y-2\">\r\n {!isInstalled ? (\r\n <div className=\"flex items-center gap-2\">\r\n {!isCodex && (\r\n <select\r\n value={installScope}\r\n onChange={(e) => setInstallScope(e.target.value as 'global' | 'project')}\r\n className=\"text-sm border border-border rounded px-2 py-1 bg-background text-foreground\"\r\n >\r\n <option value=\"global\">{formatMessage({ id: 'mcp.ccw.scope.global' })}</option>\r\n <option value=\"project\">{formatMessage({ id: 'mcp.ccw.scope.project' })}</option>\r\n </select>\r\n )}\r\n <Button\r\n variant=\"default\"\r\n size=\"sm\"\r\n onClick={handleInstallClick}\r\n disabled={isPending}\r\n >\r\n <Download className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.install' })}\r\n </Button>\r\n </div>\r\n ) : (\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n {installedScopes.length > 0 && onUninstallScope ? (\r\n installedScopes.map((s) => (\r\n <Button\r\n key={s}\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => onUninstallScope(s)}\r\n disabled={isPending}\r\n className=\"text-destructive border-destructive/50 hover:bg-destructive/10\"\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.uninstallScope' }, { scope: s })}\r\n </Button>\r\n ))\r\n ) : (\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleUninstallClick}\r\n disabled={isPending}\r\n className=\"text-destructive border-destructive/50 hover:bg-destructive/10\"\r\n >\r\n <Trash2 className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.ccw.actions.uninstall' })}\r\n </Button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <FloatingFileBrowser\r\n isOpen={isPathPickerOpen}\r\n onClose={() => setIsPathPickerOpen(false)}\r\n rootPath={currentProjectPath || '/'}\r\n onInsertPath={(path) => {\r\n if (pathPickerTarget === 'projectRoot') {\r\n setProjectRootInput(path);\r\n } else if (pathPickerTarget === 'allowedDirs') {\r\n setAllowedDirsInput((prev) => (prev ? `${prev},${path}` : path));\r\n }\r\n setIsPathPickerOpen(false);\r\n }}\r\n />\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Helper Functions ==========\r\n\r\n/**\r\n * Get icon component for a tool name\r\n */\r\nfunction getToolIcon(toolName: string): React.ReactElement {\r\n const iconProps = { className: 'w-4 h-4 text-muted-foreground' };\r\n\r\n switch (toolName) {\r\n case 'write_file':\r\n return <FileText {...iconProps} />;\r\n case 'edit_file':\r\n return <Check {...iconProps} />;\r\n case 'read_file':\r\n return <Database {...iconProps} />;\r\n case 'read_many_files':\r\n return <Files {...iconProps} />;\r\n case 'core_memory':\r\n return <Settings {...iconProps} />;\r\n case 'ask_question':\r\n return <MessageCircleQuestion {...iconProps} />;\r\n case 'team_msg':\r\n return <MessagesSquare {...iconProps} />;\r\n default:\r\n return <Settings {...iconProps} />;\r\n }\r\n}\r\n\r\nexport default CcwToolsMcpCard;\r\n","// ========================================\r\n// MCP Templates Section Component\r\n// ========================================\r\n// Template management component with card/list view, search input, category filter, save/delete/install actions\r\n\r\nimport { useState, useEffect, useCallback } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useQuery } from '@tanstack/react-query';\r\nimport {\r\n Copy,\r\n Trash2,\r\n Download,\r\n Search,\r\n Filter,\r\n Plus,\r\n FileCode,\r\n Folder,\r\n Globe,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport {\r\n AlertDialog,\r\n AlertDialogAction,\r\n AlertDialogCancel,\r\n AlertDialogContent,\r\n AlertDialogDescription,\r\n AlertDialogFooter,\r\n AlertDialogHeader,\r\n AlertDialogTitle,\r\n} from '@/components/ui/AlertDialog';\r\nimport {\r\n fetchMcpTemplateCategories,\r\n searchMcpTemplates,\r\n fetchMcpTemplatesByCategory,\r\n} from '@/lib/api';\r\nimport { mcpTemplatesKeys, useDeleteTemplate, useInstallTemplate } from '@/hooks';\r\nimport type { McpTemplate } from '@/types/store';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface McpTemplatesSectionProps {\r\n /** Callback when template is installed (opens McpServerDialog) */\r\n onInstallTemplate?: (template: McpTemplate) => void;\r\n /** Callback when saving a new template */\r\n onSaveAsTemplate?: (name: string, category: string, description: string, serverConfig: { command: string; args: string[]; env: Record<string, string> }) => void;\r\n}\r\n\r\ninterface TemplateSaveDialogProps {\r\n open: boolean;\r\n onClose: () => void;\r\n onSave: (name: string, category: string, description: string, serverConfig: { command: string; args: string[]; env: Record<string, string> }) => void;\r\n defaultName?: string;\r\n defaultCommand?: string;\r\n defaultArgs?: string[];\r\n defaultEnv?: Record<string, string>;\r\n}\r\n\r\ninterface TemplateCardProps {\r\n template: McpTemplate;\r\n onInstall: (template: McpTemplate) => void;\r\n onDelete: (templateName: string) => void;\r\n isInstalling: boolean;\r\n isDeleting: boolean;\r\n}\r\n\r\n// ========== Constants ==========\r\n\r\nconst SEARCH_DEBOUNCE_MS = 300;\r\n\r\n// ========== Helper Components ==========\r\n\r\n/**\r\n * Template Card Component - Display single template with actions\r\n */\r\nfunction TemplateCard({ template, onInstall, onDelete, isInstalling, isDeleting }: TemplateCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const handleInstall = () => {\r\n onInstall(template);\r\n };\r\n\r\n const handleDelete = () => {\r\n onDelete(template.name);\r\n };\r\n\r\n // Get icon based on category\r\n const getCategoryIcon = () => {\r\n const iconProps = { className: 'w-4 h-4' };\r\n switch (template.category?.toLowerCase()) {\r\n case 'stdio':\r\n case 'transport':\r\n return <FileCode {...iconProps} />;\r\n case 'language':\r\n case 'python':\r\n case 'node':\r\n return <Folder {...iconProps} />;\r\n case 'official':\r\n case 'builtin':\r\n return <Globe {...iconProps} />;\r\n default:\r\n return <Copy {...iconProps} />;\r\n }\r\n };\r\n\r\n return (\r\n <Card className=\"p-4 hover:border-primary/50 transition-colors\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"flex items-start gap-3 flex-1 min-w-0\">\r\n <div className=\"p-2 rounded-lg bg-muted flex-shrink-0\">\r\n {getCategoryIcon()}\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {template.name}\r\n </span>\r\n {template.category && (\r\n <Badge variant=\"secondary\" className=\"text-xs\">\r\n {template.category}\r\n </Badge>\r\n )}\r\n </div>\r\n {template.description && (\r\n <p className=\"text-xs text-muted-foreground mt-1 line-clamp-2\">\r\n {template.description}\r\n </p>\r\n )}\r\n <div className=\"flex items-center gap-2 mt-2\">\r\n <code className=\"text-xs bg-muted px-2 py-1 rounded font-mono truncate max-w-[150px]\">\r\n {template.serverConfig.command}\r\n </code>\r\n {template.serverConfig.args && template.serverConfig.args.length > 0 && (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {template.serverConfig.args.length} args\r\n </Badge>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"flex items-center gap-1 flex-shrink-0\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={handleInstall}\r\n disabled={isInstalling}\r\n title={formatMessage({ id: 'mcp.templates.actions.install' })}\r\n >\r\n <Download className=\"w-4 h-4\" />\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={handleDelete}\r\n disabled={isDeleting}\r\n title={formatMessage({ id: 'mcp.templates.actions.delete' })}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </Button>\r\n </div>\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Template Save Dialog - Save current server configuration as template\r\n */\r\nexport function TemplateSaveDialog({\r\n open,\r\n onClose,\r\n onSave,\r\n defaultName = '',\r\n defaultCommand = '',\r\n defaultArgs = [],\r\n defaultEnv = {},\r\n}: TemplateSaveDialogProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const [name, setName] = useState(defaultName);\r\n const [category, setCategory] = useState('');\r\n const [description, setDescription] = useState('');\r\n const [command, setCommand] = useState(defaultCommand);\r\n const [argsInput, setArgsInput] = useState(defaultArgs.join(', '));\r\n const [envInput, setEnvInput] = useState(\r\n Object.entries(defaultEnv).map(([k, v]) => `${k}=${v}`).join('\\n')\r\n );\r\n const [errors, setErrors] = useState<{ name?: string; command?: string }>({});\r\n\r\n // Reset form when dialog opens\r\n useEffect(() => {\r\n if (open) {\r\n setName(defaultName || '');\r\n setCategory('');\r\n setDescription('');\r\n setCommand(defaultCommand || '');\r\n setArgsInput((defaultArgs || []).join(', '));\r\n setEnvInput(\r\n Object.entries(defaultEnv || {}).map(([k, v]) => `${k}=${v}`).join('\\n')\r\n );\r\n setErrors({});\r\n }\r\n }, [open, defaultName, defaultCommand, defaultArgs, defaultEnv]);\r\n\r\n const handleSave = () => {\r\n const newErrors: { name?: string; command?: string } = {};\r\n if (!name.trim()) {\r\n newErrors.name = formatMessage({ id: 'mcp.templates.saveDialog.validation.nameRequired' });\r\n }\r\n if (!command.trim()) {\r\n newErrors.command = formatMessage({ id: 'mcp.dialog.validation.commandRequired' });\r\n }\r\n if (Object.keys(newErrors).length > 0) {\r\n setErrors(newErrors);\r\n return;\r\n }\r\n\r\n const args = argsInput\r\n .split(',')\r\n .map((a) => a.trim())\r\n .filter((a) => a.length > 0);\r\n\r\n const env: Record<string, string> = {};\r\n for (const line of envInput.split('\\n')) {\r\n const trimmed = line.trim();\r\n if (trimmed && trimmed.includes('=')) {\r\n const [key, ...valParts] = trimmed.split('=');\r\n if (key) env[key.trim()] = valParts.join('=').trim();\r\n }\r\n }\r\n\r\n onSave(name.trim(), category.trim(), description.trim(), {\r\n command: command.trim(),\r\n args,\r\n env,\r\n });\r\n };\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={onClose}>\r\n <DialogContent className=\"max-w-md max-h-[85vh] overflow-y-auto\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {formatMessage({ id: 'mcp.templates.saveDialog.title' })}\r\n </DialogTitle>\r\n </DialogHeader>\r\n <div className=\"space-y-4\">\r\n {/* Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.templates.saveDialog.name' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={name}\r\n onChange={(e) => {\r\n setName(e.target.value);\r\n if (errors.name) setErrors((prev) => ({ ...prev, name: undefined }));\r\n }}\r\n placeholder={formatMessage({ id: 'mcp.templates.saveDialog.namePlaceholder' })}\r\n error={!!errors.name}\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n </div>\r\n\r\n {/* Command */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.command' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={command}\r\n onChange={(e) => {\r\n setCommand(e.target.value);\r\n if (errors.command) setErrors((prev) => ({ ...prev, command: undefined }));\r\n }}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.commandPlaceholder' })}\r\n error={!!errors.command}\r\n />\r\n {errors.command && (\r\n <p className=\"text-sm text-destructive\">{errors.command}</p>\r\n )}\r\n </div>\r\n\r\n {/* Args */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.args' })}\r\n </label>\r\n <Input\r\n value={argsInput}\r\n onChange={(e) => setArgsInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.argsPlaceholder' })}\r\n />\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.argsHint' })}\r\n </p>\r\n </div>\r\n\r\n {/* Environment Variables */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.dialog.form.env' })}\r\n </label>\r\n <textarea\r\n value={envInput}\r\n onChange={(e) => setEnvInput(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.dialog.form.envPlaceholder' })}\r\n className=\"flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\r\n />\r\n </div>\r\n\r\n {/* Category */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.templates.saveDialog.category' })}\r\n </label>\r\n <Select value={category} onValueChange={setCategory}>\r\n <SelectTrigger className=\"w-full\">\r\n <SelectValue placeholder={formatMessage({ id: 'mcp.templates.saveDialog.categoryPlaceholder' })} />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"stdio\">STDIO</SelectItem>\r\n <SelectItem value=\"sse\">SSE</SelectItem>\r\n <SelectItem value=\"language\">Language</SelectItem>\r\n <SelectItem value=\"official\">Official</SelectItem>\r\n <SelectItem value=\"custom\">Custom</SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Description */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.templates.saveDialog.description' })}\r\n </label>\r\n <textarea\r\n value={description}\r\n onChange={(e) => setDescription(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.templates.saveDialog.descriptionPlaceholder' })}\r\n className=\"flex min-h-[60px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\r\n />\r\n </div>\r\n </div>\r\n <DialogFooter>\r\n <Button variant=\"outline\" onClick={onClose}>\r\n {formatMessage({ id: 'mcp.templates.saveDialog.cancel' })}\r\n </Button>\r\n <Button onClick={handleSave}>\r\n {formatMessage({ id: 'mcp.templates.saveDialog.save' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * McpTemplatesSection - Main template management component\r\n *\r\n * Features:\r\n * - Template list view with search and category filter\r\n * - Install template action (populates McpServerDialog)\r\n * - Delete template with confirmation\r\n * - Save current server as template\r\n */\r\nexport function McpTemplatesSection({ onInstallTemplate, onSaveAsTemplate }: McpTemplatesSectionProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n // State\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [debouncedSearch, setDebouncedSearch] = useState('');\r\n const [selectedCategory, setSelectedCategory] = useState<string>('all');\r\n const [saveDialogOpen, setSaveDialogOpen] = useState(false);\r\n const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);\r\n const [templateToDelete, setTemplateToDelete] = useState<string | null>(null);\r\n\r\n // Fetch categories for filter dropdown\r\n const { data: categories = [], isLoading: categoriesLoading } = useQuery({\r\n queryKey: mcpTemplatesKeys.categories(),\r\n queryFn: fetchMcpTemplateCategories,\r\n staleTime: 10 * 60 * 1000, // 10 minutes\r\n });\r\n\r\n // Mutations\r\n const deleteMutation = useDeleteTemplate();\r\n const installMutation = useInstallTemplate();\r\n\r\n // Debounced search\r\n useEffect(() => {\r\n const timer = setTimeout(() => {\r\n setDebouncedSearch(searchQuery);\r\n }, SEARCH_DEBOUNCE_MS);\r\n return () => clearTimeout(timer);\r\n }, [searchQuery]);\r\n\r\n // Fetch templates based on search and category filter\r\n const { data: templates = [], isLoading: templatesLoading } = useQuery({\r\n queryKey: mcpTemplatesKeys.list(selectedCategory === 'all' ? undefined : selectedCategory),\r\n queryFn: async () => {\r\n if (debouncedSearch.trim()) {\r\n return searchMcpTemplates(debouncedSearch.trim());\r\n } else if (selectedCategory === 'all') {\r\n // Fetch all templates by iterating categories\r\n const allTemplates: McpTemplate[] = [];\r\n for (const category of categories) {\r\n const categoryTemplates = await fetchMcpTemplatesByCategory(category);\r\n allTemplates.push(...categoryTemplates);\r\n }\r\n return allTemplates;\r\n } else {\r\n return fetchMcpTemplatesByCategory(selectedCategory);\r\n }\r\n },\r\n staleTime: 5 * 60 * 1000, // 5 minutes\r\n enabled: !categoriesLoading,\r\n });\r\n\r\n // Handlers\r\n const handleInstallTemplate = useCallback((template: McpTemplate) => {\r\n // Call parent callback to open McpServerDialog with template data\r\n onInstallTemplate?.(template);\r\n }, [onInstallTemplate]);\r\n\r\n const handleDeleteClick = useCallback((templateName: string) => {\r\n setTemplateToDelete(templateName);\r\n setDeleteConfirmOpen(true);\r\n }, []);\r\n\r\n const handleDeleteConfirm = useCallback(async () => {\r\n if (!templateToDelete) return;\r\n\r\n const result = await deleteMutation.deleteTemplate(templateToDelete);\r\n if (result.success) {\r\n setDeleteConfirmOpen(false);\r\n setTemplateToDelete(null);\r\n }\r\n }, [templateToDelete, deleteMutation]);\r\n\r\n const handleSaveTemplate = useCallback((_name: string, _category: string, _description: string, _serverConfig: { command: string; args: string[]; env: Record<string, string> }) => {\r\n onSaveAsTemplate?.(_name, _category, _description, _serverConfig);\r\n setSaveDialogOpen(false);\r\n }, [onSaveAsTemplate]);\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header with search and filter */}\r\n <div className=\"flex items-center justify-between gap-3\">\r\n <div className=\"flex items-center gap-2 flex-1\">\r\n {/* Search Input */}\r\n <div className=\"relative flex-1 max-w-md\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <Input\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n placeholder={formatMessage({ id: 'mcp.templates.searchPlaceholder' })}\r\n className=\"pl-9\"\r\n />\r\n </div>\r\n\r\n {/* Category Filter */}\r\n <div className=\"flex items-center gap-2\">\r\n <Filter className=\"w-4 h-4 text-muted-foreground\" />\r\n <Select value={selectedCategory} onValueChange={setSelectedCategory}>\r\n <SelectTrigger className=\"w-[150px]\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"all\">\r\n {formatMessage({ id: 'mcp.templates.filter.allCategories' })}\r\n </SelectItem>\r\n {categories.map((category) => (\r\n <SelectItem key={category} value={category}>\r\n {category}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n </div>\r\n\r\n {/* Save Template Button */}\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => setSaveDialogOpen(true)}\r\n >\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}\r\n </Button>\r\n </div>\r\n\r\n {/* Template List */}\r\n {templatesLoading ? (\r\n <div className=\"flex items-center justify-center py-12\">\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.templates.loading' })}\r\n </p>\r\n </div>\r\n ) : templates.length === 0 ? (\r\n <Card className=\"p-12 text-center\">\r\n <Copy className=\"w-12 h-12 mx-auto text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-2\">\r\n {formatMessage({ id: 'mcp.templates.empty.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'mcp.templates.empty.message' })}\r\n </p>\r\n <Button onClick={() => setSaveDialogOpen(true)}>\r\n <Plus className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.templates.empty.createFirst' })}\r\n </Button>\r\n </Card>\r\n ) : (\r\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-3\">\r\n {templates.map((template) => (\r\n <TemplateCard\r\n key={template.name}\r\n template={template}\r\n onInstall={handleInstallTemplate}\r\n onDelete={handleDeleteClick}\r\n isInstalling={installMutation.isInstalling}\r\n isDeleting={deleteMutation.isDeleting}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Save Template Dialog */}\r\n <TemplateSaveDialog\r\n open={saveDialogOpen}\r\n onClose={() => setSaveDialogOpen(false)}\r\n onSave={handleSaveTemplate}\r\n />\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>\r\n <AlertDialogContent>\r\n <AlertDialogHeader>\r\n <AlertDialogTitle>\r\n {formatMessage({ id: 'mcp.templates.deleteDialog.title' })}\r\n </AlertDialogTitle>\r\n <AlertDialogDescription>\r\n {formatMessage(\r\n { id: 'mcp.templates.deleteDialog.message' },\r\n { name: templateToDelete }\r\n )}\r\n </AlertDialogDescription>\r\n </AlertDialogHeader>\r\n <AlertDialogFooter>\r\n <AlertDialogCancel>\r\n {formatMessage({ id: 'mcp.templates.deleteDialog.cancel' })}\r\n </AlertDialogCancel>\r\n <AlertDialogAction\r\n onClick={handleDeleteConfirm}\r\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\r\n >\r\n {deleteMutation.isDeleting\r\n ? formatMessage({ id: 'mcp.templates.deleteDialog.deleting' })\r\n : formatMessage({ id: 'mcp.templates.deleteDialog.delete' })\r\n }\r\n </AlertDialogAction>\r\n </AlertDialogFooter>\r\n </AlertDialogContent>\r\n </AlertDialog>\r\n </div>\r\n );\r\n}\r\n\r\nexport default McpTemplatesSection;\r\n","// ========================================\r\n// Recommended MCP Wizard Component\r\n// ========================================\r\n// Dynamic configuration wizard for recommended MCP servers\r\n// Supports text, password, and multi-select field types\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { Download, Loader2, Search, Globe, Sparkles, Settings } from 'lucide-react';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Label } from '@/components/ui/Label';\r\nimport {\n addGlobalMcpServer,\n copyMcpServerToProject,\n} from '@/lib/api';\nimport { mcpServersKeys } from '@/hooks';\nimport { useNotifications } from '@/hooks/useNotifications';\nimport { cn } from '@/lib/utils';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\n\r\n// Icon map for MCP definitions\r\nconst ICON_MAP: Record<string, React.ComponentType<{ className?: string }>> = {\r\n 'search-code': Search,\r\n 'chrome': Globe,\r\n 'globe-2': Sparkles,\r\n 'code-2': Settings,\r\n};\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Field definition for wizard\r\n */\r\nexport interface WizardField {\r\n key: string;\r\n labelKey: string;\r\n descKey?: string;\r\n type: 'text' | 'password' | 'multi-select';\r\n default?: string | string[];\r\n placeholder?: string;\r\n required?: boolean;\r\n options?: Array<{\r\n value: string;\r\n label: string;\r\n desc?: string;\r\n }>;\r\n}\r\n\r\n/**\r\n * Recommended MCP server definition\r\n */\r\nexport interface RecommendedMcpDefinition {\r\n id: string;\r\n nameKey: string;\r\n descKey: string;\r\n icon: string;\r\n category: string;\r\n fields: WizardField[];\r\n buildConfig: (values: Record<string, any>) => {\r\n command: string;\r\n args: string[];\r\n env?: Record<string, string>;\r\n type?: string;\r\n };\r\n}\r\n\r\n/**\r\n * Props for RecommendedMcpWizard component\r\n */\r\nexport interface RecommendedMcpWizardProps {\r\n open: boolean;\r\n onClose: () => void;\r\n mcpDefinition: RecommendedMcpDefinition | null;\r\n onInstallComplete?: () => void;\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * Wizard for installing recommended MCP servers with configuration\r\n */\r\nexport function RecommendedMcpWizard({\r\n open,\r\n onClose,\r\n mcpDefinition,\r\n onInstallComplete,\r\n}: RecommendedMcpWizardProps) {\r\n const { formatMessage } = useIntl();\n const queryClient = useQueryClient();\n const { success: showSuccess, error: showError } = useNotifications();\n const projectPath = useWorkflowStore(selectProjectPath);\n\r\n // State for field values\r\n const [fieldValues, setFieldValues] = useState<Record<string, any>>({});\r\n const [selectedScope, setSelectedScope] = useState<'project' | 'global'>('global');\r\n\r\n // Initialize field values when dialog opens\r\n const initializeFieldValues = () => {\r\n if (!mcpDefinition) return;\r\n\r\n const initialValues: Record<string, any> = {};\r\n for (const field of mcpDefinition.fields) {\r\n if (field.default !== undefined) {\r\n initialValues[field.key] = field.default;\r\n } else if (field.type === 'multi-select') {\r\n initialValues[field.key] = [];\r\n } else {\r\n initialValues[field.key] = '';\r\n }\r\n }\r\n setFieldValues(initialValues);\r\n };\r\n\r\n // Reset on open/close\r\n const handleOpenChange = (newOpen: boolean) => {\r\n if (newOpen && mcpDefinition) {\r\n initializeFieldValues();\r\n } else {\r\n setFieldValues({});\r\n onClose();\r\n }\r\n };\r\n\r\n // Install mutation\r\n const installMutation = useMutation({\r\n mutationFn: async () => {\r\n if (!mcpDefinition) throw new Error('No MCP definition');\r\n\r\n const serverConfig = mcpDefinition.buildConfig(fieldValues);\r\n\r\n if (selectedScope === 'global') {\n return addGlobalMcpServer(mcpDefinition.id, serverConfig);\n } else {\n if (!projectPath) {\n throw new Error('Project path is required to install to project scope');\n }\n return copyMcpServerToProject(mcpDefinition.id, serverConfig, projectPath);\n }\n },\n onSuccess: (result) => {\r\n if (result.success) {\r\n queryClient.invalidateQueries({ queryKey: mcpServersKeys.all });\r\n showSuccess(\r\n formatMessage({ id: 'mcp.wizard.installSuccess' }),\r\n formatMessage({ id: mcpDefinition!.nameKey })\r\n );\r\n handleOpenChange(false);\r\n onInstallComplete?.();\r\n } else {\r\n showError(\r\n formatMessage({ id: 'mcp.wizard.installError' }),\r\n result.error || 'Unknown error'\r\n );\r\n }\r\n },\r\n onError: (err: Error) => {\r\n showError(\r\n formatMessage({ id: 'mcp.wizard.installError' }),\r\n err.message\r\n );\r\n },\r\n });\r\n\r\n // Handle field value change\r\n const handleFieldChange = (key: string, value: any) => {\r\n setFieldValues(prev => ({\r\n ...prev,\r\n [key]: value,\r\n }));\r\n };\r\n\r\n // Handle multi-select toggle\r\n const handleMultiSelectToggle = (key: string, value: string) => {\r\n const current = fieldValues[key] || [];\r\n const newValue = current.includes(value)\r\n ? current.filter((v: string) => v !== value)\r\n : [...current, value];\r\n handleFieldChange(key, newValue);\r\n };\r\n\r\n // Validate required fields\r\n const validateFields = (): boolean => {\r\n if (!mcpDefinition) return false;\r\n\r\n for (const field of mcpDefinition.fields) {\r\n if (field.required) {\r\n const value = fieldValues[field.key];\r\n if (field.type === 'multi-select') {\r\n if (!value || value.length === 0) return false;\r\n } else {\r\n if (!value || value.trim() === '') return false;\r\n }\r\n }\r\n }\r\n return true;\r\n };\r\n\r\n // Handle submit\r\n const handleSubmit = () => {\r\n if (!validateFields()) {\r\n showError(\r\n formatMessage({ id: 'mcp.wizard.validation' }),\r\n formatMessage({ id: 'mcp.wizard.requiredFields' })\r\n );\r\n return;\r\n }\r\n installMutation.mutate();\r\n };\r\n\r\n if (!mcpDefinition) return null;\r\n\r\n const hasFields = mcpDefinition.fields.length > 0;\r\n const Icon = ICON_MAP[mcpDefinition.icon] || Settings;\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleOpenChange}>\r\n <DialogContent className=\"max-w-lg max-h-[90vh] overflow-y-auto\">\r\n {/* Header */}\r\n <DialogHeader>\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center\">\r\n <Icon className=\"w-5 h-5 text-primary\" />\r\n </div>\r\n <div>\r\n <DialogTitle>\r\n {formatMessage({ id: 'mcp.wizard.install' })} {formatMessage({ id: mcpDefinition.nameKey })}\r\n </DialogTitle>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: mcpDefinition.descKey })}\r\n </p>\r\n </div>\r\n </div>\r\n </DialogHeader>\r\n\r\n {/* Content */}\r\n <div className=\"space-y-4 py-4\">\r\n {/* Fields */}\r\n {hasFields && (\r\n <div className=\"space-y-3\">\r\n {mcpDefinition.fields.map((field) => (\r\n <div key={field.key} className=\"space-y-1.5\">\r\n <Label className=\"flex items-center gap-1.5 text-sm font-medium\">\r\n {formatMessage({ id: field.labelKey })}\r\n {field.required && <span className=\"text-destructive\">*</span>}\r\n </Label>\r\n {field.descKey && (\r\n <p className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: field.descKey })}\r\n </p>\r\n )}\r\n\r\n {/* Text/Password Input */}\r\n {(field.type === 'text' || field.type === 'password') && (\r\n <Input\r\n type={field.type}\r\n value={fieldValues[field.key] || ''}\r\n onChange={(e) => handleFieldChange(field.key, e.target.value)}\r\n placeholder={field.placeholder}\r\n className=\"font-mono text-sm\"\r\n />\r\n )}\r\n\r\n {/* Multi-Select */}\r\n {field.type === 'multi-select' && field.options && (\r\n <div className=\"space-y-2 p-2 bg-muted/30 border border-border rounded-lg max-h-48 overflow-y-auto\">\r\n {field.options.map((option) => {\r\n const isSelected = (fieldValues[field.key] || []).includes(option.value);\r\n return (\r\n <div\r\n key={option.value}\r\n className={cn(\r\n 'flex items-start gap-2 p-2 rounded transition-colors cursor-pointer',\r\n isSelected ? 'bg-primary/10' : 'hover:bg-muted/50'\r\n )}\r\n onClick={() => handleMultiSelectToggle(field.key, option.value)}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={isSelected}\r\n onChange={() => {}}\r\n className=\"mt-0.5 w-4 h-4\"\r\n />\r\n <div className=\"flex-1\">\r\n <div className=\"text-sm font-medium text-foreground\">\r\n {option.label}\r\n </div>\r\n {option.desc && (\r\n <div className=\"text-xs text-muted-foreground\">\r\n {option.desc}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Scope Selection */}\r\n <div className=\"space-y-2 pt-3 border-t border-border\">\r\n <Label className=\"text-sm font-medium\">\r\n {formatMessage({ id: 'mcp.wizard.scope' })}\r\n </Label>\r\n <div className=\"flex gap-2\">\r\n <Button\r\n variant={selectedScope === 'global' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setSelectedScope('global')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.wizard.scope.global' })}\r\n </Button>\r\n <Button\r\n variant={selectedScope === 'project' ? 'default' : 'outline'}\r\n size=\"sm\"\r\n onClick={() => setSelectedScope('project')}\r\n className=\"flex-1\"\r\n >\r\n {formatMessage({ id: 'mcp.wizard.scope.project' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* No Configuration Needed Message */}\r\n {!hasFields && (\r\n <div className=\"p-3 bg-success/10 border border-success/20 rounded-lg text-sm text-success\">\r\n {formatMessage({ id: 'mcp.noConfigNeeded' })}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Footer */}\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => handleOpenChange(false)}\r\n disabled={installMutation.isPending}\r\n >\r\n {formatMessage({ id: 'mcp.dialog.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n disabled={installMutation.isPending}\r\n >\r\n {installMutation.isPending ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-1 animate-spin\" />\r\n {formatMessage({ id: 'mcp.wizard.installing' })}\r\n </>\r\n ) : (\r\n <>\r\n <Download className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.wizard.install' })}\r\n </>\r\n )}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default RecommendedMcpWizard;\r\n","// ========================================\r\n// Recommended MCP Section Component\r\n// ========================================\r\n// Display recommended MCP servers with wizard-based install functionality\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Search,\r\n Globe,\r\n Sparkles,\r\n Download,\r\n Settings,\r\n Key,\r\n Zap,\r\n Code2,\r\n} from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { RecommendedMcpWizard, RecommendedMcpDefinition } from './RecommendedMcpWizard';\r\nimport { fetchMcpConfig } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Props for RecommendedMcpSection component\r\n */\r\nexport interface RecommendedMcpSectionProps {\r\n /** Callback when server is installed */\r\n onInstallComplete?: () => void;\r\n}\r\n\r\n// ========== Platform Detection ==========\r\nconst isWindows = typeof navigator !== 'undefined' && navigator.platform?.toLowerCase().includes('win');\r\n\r\n/**\r\n * Build cross-platform MCP config\r\n * On Windows, wraps npx/node/python commands with cmd /c for proper execution\r\n */\r\nfunction buildCrossPlatformMcpConfig(\r\n command: string,\r\n args: string[] = [],\r\n options: { env?: Record<string, string>; type?: string } = {}\r\n) {\r\n const { env, type } = options;\r\n\r\n const windowsWrappedCommands = ['npx', 'npm', 'node', 'python', 'python3', 'pip', 'pip3', 'pnpm', 'yarn', 'bun'];\r\n const needsWindowsWrapper = isWindows && windowsWrappedCommands.includes(command.toLowerCase());\r\n\r\n const config: { command: string; args: string[]; env?: Record<string, string>; type?: string } = needsWindowsWrapper\r\n ? { command: 'cmd', args: ['/c', command, ...args] }\r\n : { command, args };\r\n\r\n if (type) config.type = type;\r\n if (env && Object.keys(env).length > 0) config.env = env;\r\n\r\n return config;\r\n}\r\n\r\n// ========== Recommended MCP Definitions ==========\r\n\r\n/**\r\n * Pre-configured recommended MCP servers with field definitions\r\n * Matches original JS version structure for full wizard support\r\n */\r\nconst RECOMMENDED_MCP_DEFINITIONS: RecommendedMcpDefinition[] = [\r\n {\r\n id: 'ace-tool',\r\n nameKey: 'mcp.ace-tool.name',\r\n descKey: 'mcp.ace-tool.desc',\r\n icon: 'search-code',\r\n category: 'search',\r\n fields: [\r\n {\r\n key: 'baseUrl',\r\n labelKey: 'mcp.ace-tool.field.baseUrl',\r\n type: 'text',\r\n default: 'https://acemcp.heroman.wtf/relay/',\r\n placeholder: 'https://acemcp.heroman.wtf/relay/',\r\n required: true,\r\n descKey: 'mcp.ace-tool.field.baseUrl.desc',\r\n },\r\n {\r\n key: 'token',\r\n labelKey: 'mcp.ace-tool.field.token',\r\n type: 'password',\r\n default: '',\r\n placeholder: 'ace_xxxxxxxxxxxxxxxx',\r\n required: true,\r\n descKey: 'mcp.ace-tool.field.token.desc',\r\n },\r\n ],\r\n buildConfig: (values) => buildCrossPlatformMcpConfig('npx', [\r\n 'ace-tool',\r\n '--base-url',\r\n values.baseUrl || 'https://acemcp.heroman.wtf/relay/',\r\n '--token',\r\n values.token,\r\n ]),\r\n },\r\n {\r\n id: 'chrome-devtools',\r\n nameKey: 'mcp.chrome-devtools.name',\r\n descKey: 'mcp.chrome-devtools.desc',\r\n icon: 'chrome',\r\n category: 'browser',\r\n fields: [],\r\n buildConfig: () => buildCrossPlatformMcpConfig('npx', ['chrome-devtools-mcp@latest'], { type: 'stdio' }),\r\n },\r\n {\r\n id: 'exa',\r\n nameKey: 'mcp.exa.name',\r\n descKey: 'mcp.exa.desc',\r\n icon: 'globe-2',\r\n category: 'search',\r\n fields: [\r\n {\r\n key: 'apiKey',\r\n labelKey: 'mcp.exa.field.apiKey',\r\n type: 'password',\r\n default: '',\r\n placeholder: 'your-exa-api-key',\r\n required: false,\r\n descKey: 'mcp.exa.field.apiKey.desc',\r\n },\r\n ],\r\n buildConfig: (values) => {\r\n const baseUrl = 'https://mcp.exa.ai/mcp';\r\n const url = values.apiKey ? `${baseUrl}?exaApiKey=${values.apiKey}` : baseUrl;\r\n return buildCrossPlatformMcpConfig('npx', ['-y', 'mcp-remote', url]);\r\n },\r\n },\r\n];\r\n\r\n// ========== Icon Map ==========\r\n\r\nconst ICON_MAP: Record<string, React.ComponentType<{ className?: string }>> = {\r\n 'search-code': Search,\r\n 'chrome': Globe,\r\n 'globe-2': Sparkles,\r\n 'code-2': Code2,\r\n};\r\n\r\n// ========== Helper Component ==========\r\n\r\ninterface RecommendedServerCardProps {\r\n definition: RecommendedMcpDefinition;\r\n isInstalled: boolean;\r\n onInstall: (definition: RecommendedMcpDefinition) => void;\r\n}\r\n\r\n/**\r\n * Individual recommended server card\r\n */\r\nfunction RecommendedServerCard({\r\n definition,\r\n isInstalled,\r\n onInstall,\r\n}: RecommendedServerCardProps) {\r\n const { formatMessage } = useIntl();\r\n const Icon = ICON_MAP[definition.icon] || Settings;\r\n const hasFields = definition.fields.length > 0;\r\n\r\n return (\r\n <Card className=\"p-4 hover:shadow-md transition-shadow\">\r\n <div className=\"flex items-start gap-3\">\r\n {/* Icon */}\r\n <div className={cn(\r\n 'p-2.5 rounded-lg',\r\n isInstalled ? 'bg-primary/20' : 'bg-muted'\r\n )}>\r\n <Icon className={cn(\r\n 'w-5 h-5',\r\n isInstalled ? 'text-primary' : 'text-muted-foreground'\r\n )} />\r\n </div>\r\n\r\n {/* Content */}\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2 mb-1\">\r\n <h4 className=\"text-sm font-medium text-foreground truncate\">\r\n {formatMessage({ id: definition.nameKey })}\r\n </h4>\r\n {isInstalled && (\r\n <Badge variant=\"default\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.recommended.actions.installed' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground line-clamp-2 mb-3\">\r\n {formatMessage({ id: definition.descKey })}\r\n </p>\r\n\r\n {/* Config info + Install */}\r\n <div className=\"flex items-center justify-between\">\r\n {hasFields ? (\r\n <span className=\"text-xs text-muted-foreground flex items-center gap-1\">\r\n <Key className=\"w-3 h-3\" />\r\n {definition.fields.length} {formatMessage({ id: 'mcp.configRequired' })}\r\n </span>\r\n ) : (\r\n <span className=\"text-xs text-green-600 dark:text-green-400 flex items-center gap-1\">\r\n <Zap className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.noConfigNeeded' })}\r\n </span>\r\n )}\r\n <Button\r\n variant={isInstalled ? 'outline' : 'default'}\r\n size=\"sm\"\r\n onClick={() => onInstall(definition)}\r\n >\r\n {isInstalled ? (\r\n <>\r\n <Settings className=\"w-3.5 h-3.5 mr-1\" />\r\n {formatMessage({ id: 'mcp.reconfigure' })}\r\n </>\r\n ) : (\r\n <>\r\n <Download className=\"w-3.5 h-3.5 mr-1\" />\r\n {formatMessage({ id: 'mcp.recommended.actions.install' })}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\n/**\r\n * Recommended MCP servers section with wizard-based install\r\n */\r\nexport function RecommendedMcpSection({\r\n onInstallComplete,\r\n}: RecommendedMcpSectionProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const [wizardOpen, setWizardOpen] = useState(false);\r\n const [selectedDefinition, setSelectedDefinition] = useState<RecommendedMcpDefinition | null>(null);\r\n const [installedServerIds, setInstalledServerIds] = useState<Set<string>>(new Set());\r\n\r\n // Check which servers are already installed\r\n const checkInstalledServers = async () => {\r\n try {\r\n const data = await fetchMcpConfig();\r\n const installedIds = new Set<string>();\r\n\r\n const globalServers = data.globalServers || {};\r\n const userServers = data.userServers || {};\r\n for (const name of Object.keys(globalServers)) installedIds.add(name);\r\n for (const name of Object.keys(userServers)) installedIds.add(name);\r\n\r\n const projects = data.projects || {};\r\n for (const proj of Object.values(projects)) {\r\n const servers = (proj as any).mcpServers || {};\r\n for (const name of Object.keys(servers)) installedIds.add(name);\r\n }\r\n\r\n if ((data as any).codex?.servers) {\r\n for (const name of Object.keys((data as any).codex.servers)) installedIds.add(name);\r\n }\r\n\r\n setInstalledServerIds(installedIds);\r\n } catch {\r\n // Ignore errors during check\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n checkInstalledServers();\r\n }, []);\r\n\r\n // Handle install click - open wizard\r\n const handleInstallClick = (definition: RecommendedMcpDefinition) => {\r\n setSelectedDefinition(definition);\r\n setWizardOpen(true);\r\n };\r\n\r\n // Handle wizard close\r\n const handleWizardClose = () => {\r\n setWizardOpen(false);\r\n setSelectedDefinition(null);\r\n };\r\n\r\n // Handle install complete\r\n const handleInstallComplete = () => {\r\n checkInstalledServers();\r\n onInstallComplete?.();\r\n };\r\n\r\n return (\r\n <>\r\n <section className=\"space-y-4\">\r\n {/* Header */}\r\n <div>\r\n <h2 className=\"text-lg font-semibold text-foreground\">\r\n {formatMessage({ id: 'mcp.recommended.title' })}\r\n </h2>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.recommended.description' })}\r\n </p>\r\n </div>\r\n\r\n {/* Server Cards */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-3\">\r\n {RECOMMENDED_MCP_DEFINITIONS.map((definition) => (\r\n <RecommendedServerCard\r\n key={definition.id}\r\n definition={definition}\r\n isInstalled={installedServerIds.has(definition.id)}\r\n onInstall={handleInstallClick}\r\n />\r\n ))}\r\n </div>\r\n </section>\r\n\r\n {/* Wizard Dialog */}\r\n <RecommendedMcpWizard\r\n open={wizardOpen}\r\n onClose={handleWizardClose}\r\n mcpDefinition={selectedDefinition}\r\n onInstallComplete={handleInstallComplete}\r\n />\r\n </>\r\n );\r\n}\r\n\r\nexport default RecommendedMcpSection;\r\n","// ========================================\r\n// Windows Compatibility Warning Component\r\n// ========================================\r\n// Windows-specific warning banner with command detection and auto-fix functionality\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport { AlertTriangle, Download, CheckCircle, XCircle, Loader2 } from 'lucide-react';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface WindowsCompatibilityWarningProps {\r\n /** Optional: Project path to check commands against */\r\n projectPath?: string;\r\n /** Optional: Callback when compatibility check completes */\r\n onComplete?: (result: CompatibilityCheckResult) => void;\r\n}\r\n\r\nexport interface CommandDetectionResult {\r\n command: string;\r\n available: boolean;\r\n installUrl?: string;\r\n}\r\n\r\nexport interface CompatibilityCheckResult {\r\n isWindows: boolean;\r\n missingCommands: string[];\r\n commands: CommandDetectionResult[];\r\n canAutoFix: boolean;\r\n}\r\n\r\n// ========== Constants ==========\r\n\r\nconst COMMON_COMMANDS = [\r\n { name: 'npm', installUrl: 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm' },\r\n { name: 'node', installUrl: 'https://nodejs.org/' },\r\n { name: 'python', installUrl: 'https://www.python.org/downloads/' },\r\n { name: 'npx', installUrl: 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm' },\r\n];\r\n\r\n// Helper function to check if a command can be auto-fixed\r\nfunction canAutoFixCommand(command: string): boolean {\r\n return COMMON_COMMANDS.some((cmd) => cmd.name === command);\r\n}\r\n\r\n// ========== API Functions ==========\r\n\r\nasync function detectWindowsCommands(projectPath?: string): Promise<CommandDetectionResult[]> {\r\n const response = await fetch('/api/mcp/detect-commands', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ projectPath }),\r\n });\r\n if (!response.ok) {\r\n throw new Error('Failed to detect commands');\r\n }\r\n return response.json();\r\n}\r\n\r\nasync function applyWindowsAutoFix(projectPath?: string): Promise<{ success: boolean; message: string }> {\r\n const response = await fetch('/api/mcp/apply-windows-fix', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ projectPath }),\r\n });\r\n if (!response.ok) {\r\n throw new Error('Failed to apply Windows fix');\r\n }\r\n return response.json();\r\n}\r\n\r\n// ========== Sub-Components ==========\r\n\r\ninterface CommandDetectionListProps {\r\n commands: CommandDetectionResult[];\r\n}\r\n\r\nfunction CommandDetectionList({ commands }: CommandDetectionListProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n return (\r\n <div className=\"space-y-2 mt-3\">\r\n {commands.map((cmd) => (\r\n <div\r\n key={cmd.command}\r\n className={cn(\r\n 'flex items-center gap-2 text-sm p-2 rounded-md',\r\n cmd.available ? 'bg-success/10' : 'bg-destructive/10'\r\n )}\r\n >\r\n {cmd.available ? (\r\n <CheckCircle className=\"w-4 h-4 text-success\" />\r\n ) : (\r\n <XCircle className=\"w-4 h-4 text-destructive\" />\r\n )}\r\n <code className=\"font-mono flex-1\">{cmd.command}</code>\r\n {!cmd.available && cmd.installUrl && (\r\n <a\r\n href={cmd.installUrl}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n className=\"text-xs text-primary hover:underline flex items-center gap-1\"\r\n >\r\n <Download className=\"w-3 h-3\" />\r\n {formatMessage({ id: 'mcp.windows.install' })}\r\n </a>\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n\r\n// ========== Main Component ==========\r\n\r\nexport function WindowsCompatibilityWarning({\r\n projectPath,\r\n onComplete,\r\n}: WindowsCompatibilityWarningProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n\r\n const [checkResult, setCheckResult] = useState<CompatibilityCheckResult | null>(null);\r\n const [isChecking, setIsChecking] = useState(false);\r\n const [dismissed, setDismissed] = useState(false);\r\n\r\n // Detect Windows platform\r\n const isWindows = typeof window !== 'undefined' && window.navigator.platform.toLowerCase().includes('win');\r\n\r\n // Mutation for auto-fix\r\n const autoFixMutation = useMutation({\r\n mutationFn: () => applyWindowsAutoFix(projectPath),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: ['mcpServers'] });\r\n if (onComplete && checkResult) {\r\n onComplete({ ...checkResult, canAutoFix: false });\r\n }\r\n },\r\n });\r\n\r\n // Check compatibility on mount (Windows only)\r\n useEffect(() => {\r\n if (!isWindows || dismissed) return;\r\n\r\n const checkCompatibility = async () => {\r\n setIsChecking(true);\r\n try {\r\n const results = await detectWindowsCommands(projectPath);\r\n const missingCommands = results.filter((r) => !r.available).map((r) => r.command);\r\n const canAutoFix = missingCommands.length > 0 && missingCommands.every(canAutoFixCommand);\r\n\r\n const result: CompatibilityCheckResult = {\r\n isWindows: true,\r\n missingCommands,\r\n commands: results,\r\n canAutoFix,\r\n };\r\n\r\n setCheckResult(result);\r\n if (onComplete) {\r\n onComplete(result);\r\n }\r\n } catch (error) {\r\n console.error('Failed to check Windows compatibility:', error);\r\n } finally {\r\n setIsChecking(false);\r\n }\r\n };\r\n\r\n checkCompatibility();\r\n }, [isWindows, dismissed, projectPath, onComplete]);\r\n\r\n // Don't render if not Windows, dismissed, or still checking without errors\r\n if (!isWindows || dismissed || (isChecking && !checkResult)) {\r\n return null;\r\n }\r\n\r\n // Don't show warning if all commands are available\r\n if (checkResult && checkResult.missingCommands.length === 0) {\r\n return null;\r\n }\r\n\r\n const handleAutoFix = async () => {\r\n autoFixMutation.mutate();\r\n };\r\n\r\n const handleDismiss = () => {\r\n setDismissed(true);\r\n };\r\n\r\n return (\r\n <div className=\"border border-warning/50 bg-warning/5 rounded-lg p-4 mb-4\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-warning flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1 space-y-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h4 className=\"text-sm font-semibold text-foreground\">\r\n {formatMessage({ id: 'mcp.windows.title' })}\r\n </h4>\r\n <p className=\"text-xs text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'mcp.windows.description' })}\r\n </p>\r\n </div>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n className=\"h-6 w-6 p-0\"\r\n onClick={handleDismiss}\r\n >\r\n ×\r\n </Button>\r\n </div>\r\n\r\n {checkResult && (\r\n <>\r\n {checkResult.missingCommands.length > 0 && (\r\n <div className=\"flex items-center gap-2\">\r\n <Badge variant=\"warning\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.windows.missingCount' }, { count: checkResult.missingCommands.length })}\r\n </Badge>\r\n </div>\r\n )}\r\n\r\n <CommandDetectionList commands={checkResult.commands} />\r\n\r\n {checkResult.canAutoFix && (\r\n <div className=\"flex items-center gap-2 pt-2 border-t border-warning/20\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleAutoFix}\r\n disabled={autoFixMutation.isPending}\r\n className=\"text-xs\"\r\n >\r\n {autoFixMutation.isPending ? (\r\n <>\r\n <Loader2 className=\"w-3 h-3 mr-1 animate-spin\" />\r\n {formatMessage({ id: 'mcp.windows.fixing' })}\r\n </>\r\n ) : (\r\n <>\r\n <CheckCircle className=\"w-3 h-3 mr-1\" />\r\n {formatMessage({ id: 'mcp.windows.autoFix' })}\r\n </>\r\n )}\r\n </Button>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.windows.autoFixHint' })}\r\n </span>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {isChecking && (\r\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n {formatMessage({ id: 'mcp.windows.checking' })}\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default WindowsCompatibilityWarning;\r\n","// ========================================\r\n// Cross-CLI Sync Panel Component\r\n// ========================================\r\n// Inline panel for synchronizing MCP servers between Claude and Codex\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { ArrowRight, ArrowLeft, CheckCircle2, AlertCircle, Loader2 } from 'lucide-react';\r\nimport { Checkbox } from '@/components/ui/Checkbox';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { useMcpServers } from '@/hooks';\r\nimport { crossCliCopy, fetchCodexMcpServers, isHttpMcpServer, isStdioMcpServer } from '@/lib/api';\r\nimport { cn } from '@/lib/utils';\r\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface CrossCliSyncPanelProps {\r\n /** Callback when copy is successful */\r\n onSuccess?: (copiedCount: number, direction: 'to-codex' | 'from-codex') => void;\r\n /** Additional class name */\r\n className?: string;\r\n}\r\n\r\ninterface ServerCheckboxItem {\r\n name: string;\r\n /** Display text - command for STDIO, URL for HTTP */\r\n displayText: string;\r\n enabled: boolean;\r\n selected: boolean;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function CrossCliSyncPanel({ onSuccess, className }: CrossCliSyncPanelProps) {\r\n const { formatMessage } = useIntl();\r\n const projectPath = useWorkflowStore(selectProjectPath);\r\n\r\n // Claude servers state\r\n const { servers: claudeServers } = useMcpServers();\r\n const [selectedClaude, setSelectedClaude] = useState<Set<string>>(new Set());\r\n\r\n // Codex servers state\r\n const [codexServers, setCodexServers] = useState<ServerCheckboxItem[]>([]);\r\n const [selectedCodex, setSelectedCodex] = useState<Set<string>>(new Set());\r\n const [isLoadingCodex, setIsLoadingCodex] = useState(false);\r\n const [codexError, setCodexError] = useState<string | null>(null);\r\n\r\n // Copy operation state\r\n const [isCopying, setIsCopying] = useState(false);\r\n const [copyResult, setCopyResult] = useState<{\r\n type: 'success' | 'partial' | null;\r\n copied: number;\r\n failed: number;\r\n }>({ type: null, copied: 0, failed: 0 });\r\n\r\n // Load Codex servers on mount\r\n useEffect(() => {\r\n const loadCodexServers = async () => {\r\n setIsLoadingCodex(true);\r\n setCodexError(null);\r\n try {\r\n const codex = await fetchCodexMcpServers();\r\n setCodexServers(\r\n (codex.servers ?? []).map((s) => ({\r\n name: s.name,\r\n displayText: isHttpMcpServer(s) ? s.url : (isStdioMcpServer(s) ? s.command : ''),\r\n enabled: s.enabled,\r\n selected: false,\r\n }))\r\n );\r\n } catch (error) {\r\n console.error('Failed to load Codex MCP servers:', error);\r\n setCodexError(formatMessage({ id: 'mcp.sync.codexLoadError' }));\r\n setCodexServers([]);\r\n } finally {\r\n setIsLoadingCodex(false);\r\n }\r\n };\r\n\r\n void loadCodexServers();\r\n }, [formatMessage]);\r\n\r\n // Claude server handlers\r\n const toggleClaudeServer = (name: string) => {\r\n setSelectedClaude((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(name)) {\r\n next.delete(name);\r\n } else {\r\n next.add(name);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const selectAllClaude = () => {\r\n setSelectedClaude(new Set(claudeServers.map((s) => s.name)));\r\n };\r\n\r\n const clearAllClaude = () => {\r\n setSelectedClaude(new Set());\r\n };\r\n\r\n // Codex server handlers\r\n const toggleCodexServer = (name: string) => {\r\n setSelectedCodex((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(name)) {\r\n next.delete(name);\r\n } else {\r\n next.add(name);\r\n }\r\n return next;\r\n });\r\n setCodexServers((prev) =>\r\n prev.map((s) => (s.name === name ? { ...s, selected: !s.selected } : s))\r\n );\r\n };\r\n\r\n const selectAllCodex = () => {\r\n const allNames = codexServers.map((s) => s.name);\r\n setSelectedCodex(new Set(allNames));\r\n setCodexServers((prev) => prev.map((s) => ({ ...s, selected: true })));\r\n };\r\n\r\n const clearAllCodex = () => {\r\n setSelectedCodex(new Set());\r\n setCodexServers((prev) => prev.map((s) => ({ ...s, selected: false })));\r\n };\r\n\r\n // Copy handlers\r\n const handleCopyToCodex = async () => {\r\n if (selectedClaude.size === 0) return;\r\n\r\n setIsCopying(true);\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n\r\n try {\r\n const result = await crossCliCopy({\r\n source: 'claude',\r\n target: 'codex',\r\n serverNames: Array.from(selectedClaude),\r\n projectPath: projectPath ?? undefined,\r\n });\r\n\r\n if (result.success) {\r\n const failedCount = result.failed.length;\r\n const copiedCount = result.copied.length;\r\n\r\n setCopyResult({\r\n type: failedCount > 0 ? 'partial' : 'success',\r\n copied: copiedCount,\r\n failed: failedCount,\r\n });\r\n\r\n onSuccess?.(copiedCount, 'to-codex');\r\n\r\n // Clear selection after successful copy\r\n setSelectedClaude(new Set());\r\n\r\n // Auto-hide result after 3 seconds\r\n setTimeout(() => {\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n }, 3000);\r\n }\r\n } catch (error) {\r\n console.error('Failed to copy to Codex:', error);\r\n setCopyResult({ type: 'partial', copied: 0, failed: selectedClaude.size });\r\n } finally {\r\n setIsCopying(false);\r\n }\r\n };\r\n\r\n const handleCopyFromCodex = async () => {\r\n if (selectedCodex.size === 0 || !projectPath) {\r\n return;\r\n }\r\n\r\n setIsCopying(true);\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n\r\n try {\r\n const result = await crossCliCopy({\r\n source: 'codex',\r\n target: 'claude',\r\n serverNames: Array.from(selectedCodex),\r\n projectPath,\r\n });\r\n\r\n if (result.success) {\r\n const failedCount = result.failed.length;\r\n const copiedCount = result.copied.length;\r\n\r\n setCopyResult({\r\n type: failedCount > 0 ? 'partial' : 'success',\r\n copied: copiedCount,\r\n failed: failedCount,\r\n });\r\n\r\n onSuccess?.(copiedCount, 'from-codex');\r\n\r\n // Clear selection after successful copy\r\n setSelectedCodex(new Set());\r\n setCodexServers((prev) => prev.map((s) => ({ ...s, selected: false })));\r\n\r\n // Auto-hide result after 3 seconds\r\n setTimeout(() => {\r\n setCopyResult({ type: null, copied: 0, failed: 0 });\r\n }, 3000);\r\n }\r\n } catch (error) {\r\n console.error('Failed to copy from Codex:', error);\r\n setCopyResult({ type: 'partial', copied: 0, failed: selectedCodex.size });\r\n } finally {\r\n setIsCopying(false);\r\n }\r\n };\r\n\r\n // Computed values\r\n const claudeTotal = claudeServers.length;\r\n const claudeSelected = selectedClaude.size;\r\n const codexTotal = codexServers.length;\r\n const codexSelected = selectedCodex.size;\r\n\r\n return (\r\n <div className={cn('space-y-4', className)}>\r\n {/* Header */}\r\n <div className=\"text-center\">\r\n <h3 className=\"text-base font-semibold text-foreground\">\r\n {formatMessage({ id: 'mcp.sync.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'mcp.sync.description' })}\r\n </p>\r\n </div>\r\n\r\n {/* Result Message */}\r\n {copyResult.type !== null && (\r\n <div\r\n className={cn(\r\n 'flex items-center gap-2 p-3 rounded-lg border',\r\n copyResult.type === 'success'\r\n ? 'bg-success/10 border-success/30 text-success'\r\n : 'bg-warning/10 border-warning/30 text-warning'\r\n )}\r\n >\r\n {copyResult.type === 'success' ? (\r\n <CheckCircle2 className=\"w-4 h-4 flex-shrink-0\" />\r\n ) : (\r\n <AlertCircle className=\"w-4 h-4 flex-shrink-0\" />\r\n )}\r\n <span className=\"text-sm\">\r\n {copyResult.type === 'success'\r\n ? formatMessage(\r\n { id: 'mcp.sync.copySuccess' },\r\n { count: copyResult.copied }\r\n )\r\n : formatMessage(\r\n { id: 'mcp.sync.copyPartial' },\r\n { copied: copyResult.copied, failed: copyResult.failed }\r\n )}\r\n </span>\r\n </div>\r\n )}\r\n\r\n {/* Two-column layout */}\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n {/* Claude Column */}\r\n <div className=\"border border-border rounded-lg overflow-hidden\">\r\n {/* Column Header */}\r\n <div className=\"bg-muted/50 px-4 py-3 border-b border-border\">\r\n <div className=\"flex items-center justify-between\">\r\n <h4 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.sync.claudeColumn' })}\r\n </h4>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage(\r\n { id: 'mcp.sync.selectedCount' },\r\n { count: claudeSelected, total: claudeTotal }\r\n )}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Claude Server List */}\r\n <div className=\"p-2 max-h-64 overflow-y-auto\">\r\n {claudeTotal === 0 ? (\r\n <div className=\"py-8 text-center text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.sync.noServers' })}\r\n </div>\r\n ) : (\r\n <div className=\"space-y-1\">\r\n {claudeServers.map((server) => (\r\n <div\r\n key={server.name}\r\n className={cn(\r\n 'flex items-start gap-2 p-2 rounded cursor-pointer transition-colors',\r\n selectedClaude.has(server.name)\r\n ? 'bg-primary/10'\r\n : 'hover:bg-muted/50'\r\n )}\r\n onClick={() => toggleClaudeServer(server.name)}\r\n >\r\n <Checkbox\r\n id={`claude-${server.name}`}\r\n checked={selectedClaude.has(server.name)}\r\n onChange={() => toggleClaudeServer(server.name)}\r\n className=\"w-4 h-4 mt-0.5\"\r\n />\r\n <label\r\n htmlFor={`claude-${server.name}`}\r\n className=\"flex-1 min-w-0 cursor-pointer\"\r\n >\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {server.name}\r\n </span>\r\n {server.enabled && (\r\n <Badge variant=\"success\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </div>\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\n {isHttpMcpServer(server)\n ? server.url\n : (isStdioMcpServer(server) ? server.command : '')}\n </p>\n </label>\n </div>\n ))}\n </div>\n )}\r\n </div>\r\n\r\n {/* Claude Footer Actions */}\r\n {claudeTotal > 0 && (\r\n <div className=\"px-2 py-2 bg-muted/30 border-t border-border flex gap-1\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={selectAllClaude}\r\n className=\"flex-1 text-xs\"\r\n >\r\n {formatMessage({ id: 'mcp.sync.selectAll' })}\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={clearAllClaude}\r\n className=\"flex-1 text-xs\"\r\n disabled={claudeSelected === 0}\r\n >\r\n {formatMessage({ id: 'mcp.sync.clearAll' })}\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Codex Column */}\r\n <div className=\"border border-border rounded-lg overflow-hidden\">\r\n {/* Column Header */}\r\n <div className=\"bg-muted/50 px-4 py-3 border-b border-border\">\r\n <div className=\"flex items-center justify-between\">\r\n <h4 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.sync.codexColumn' })}\r\n </h4>\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {formatMessage(\r\n { id: 'mcp.sync.selectedCount' },\r\n { count: codexSelected, total: codexTotal }\r\n )}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Codex Server List */}\r\n <div className=\"p-2 max-h-64 overflow-y-auto\">\r\n {isLoadingCodex ? (\r\n <div className=\"py-8 flex items-center justify-center\">\r\n <Loader2 className=\"w-5 h-5 animate-spin text-muted-foreground\" />\r\n </div>\r\n ) : codexError ? (\r\n <div className=\"py-8 text-center text-sm text-destructive\">\r\n {codexError}\r\n </div>\r\n ) : codexTotal === 0 ? (\r\n <div className=\"py-8 text-center text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.sync.noServers' })}\r\n </div>\r\n ) : (\r\n <div className=\"space-y-1\">\r\n {codexServers.map((server) => (\r\n <div\r\n key={server.name}\r\n className={cn(\r\n 'flex items-start gap-2 p-2 rounded cursor-pointer transition-colors',\r\n server.selected\r\n ? 'bg-primary/10'\r\n : 'hover:bg-muted/50'\r\n )}\r\n onClick={() => toggleCodexServer(server.name)}\r\n >\r\n <Checkbox\r\n id={`codex-${server.name}`}\r\n checked={server.selected}\r\n onChange={() => toggleCodexServer(server.name)}\r\n className=\"w-4 h-4 mt-0.5\"\r\n />\r\n <label\r\n htmlFor={`codex-${server.name}`}\r\n className=\"flex-1 min-w-0 cursor-pointer\"\r\n >\r\n <div className=\"flex items-center gap-2 flex-wrap\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {server.name}\r\n </span>\r\n {server.enabled && (\r\n <Badge variant=\"success\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </div>\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\n {server.displayText}\n </p>\n </label>\n </div>\n ))}\n </div>\n )}\r\n </div>\r\n\r\n {/* Codex Footer Actions */}\r\n {codexTotal > 0 && (\r\n <div className=\"px-2 py-2 bg-muted/30 border-t border-border flex gap-1\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={selectAllCodex}\r\n className=\"flex-1 text-xs\"\r\n >\r\n {formatMessage({ id: 'mcp.sync.selectAll' })}\r\n </Button>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={clearAllCodex}\r\n className=\"flex-1 text-xs\"\r\n disabled={codexSelected === 0}\r\n >\r\n {formatMessage({ id: 'mcp.sync.clearAll' })}\r\n </Button>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Copy Buttons */}\r\n <div className=\"flex items-center justify-center gap-3\">\r\n <Button\r\n onClick={handleCopyToCodex}\r\n disabled={claudeSelected === 0 || isCopying}\r\n variant=\"default\"\r\n className=\"min-w-40\"\r\n >\r\n {isCopying ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\r\n {formatMessage({ id: 'mcp.sync.syncInProgress' })}\r\n </>\r\n ) : (\r\n <>\r\n <ArrowRight className=\"w-4 h-4 mr-2\" />\r\n {formatMessage(\r\n { id: 'mcp.sync.copyToCodex' },\r\n { count: claudeSelected }\r\n )}\r\n </>\r\n )}\r\n </Button>\r\n\r\n <Button\r\n onClick={handleCopyFromCodex}\r\n disabled={codexSelected === 0 || isCopying || !projectPath}\r\n variant=\"default\"\r\n className=\"min-w-40\"\r\n >\r\n {isCopying ? (\r\n <>\r\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\r\n {formatMessage({ id: 'mcp.sync.syncInProgress' })}\r\n </>\r\n ) : (\r\n <>\r\n <ArrowLeft className=\"w-4 h-4 mr-2\" />\r\n {formatMessage(\r\n { id: 'mcp.sync.copyFromCodex' },\r\n { count: codexSelected }\r\n )}\r\n </>\r\n )}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nexport default CrossCliSyncPanel;\r\n","// ========================================\r\n// All Projects Table Component\r\n// ========================================\r\n// Table component displaying all recent projects with MCP server statistics\r\n\r\nimport { useState, useEffect, useMemo } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { Folder, Clock, Database, ExternalLink } from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { useProjectOperations } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport { formatDistanceToNow } from 'date-fns';\r\nimport { fetchOtherProjectsServers } from '@/lib/api';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface ProjectServerStats {\r\n name: string;\r\n path: string;\r\n serverCount: number;\r\n enabledCount: number;\r\n lastModified?: string;\r\n isCurrent?: boolean;\r\n}\r\n\r\nexport interface AllProjectsTableProps {\r\n /** Callback when a project is clicked */\r\n onProjectClick?: (projectPath: string) => void;\r\n /** Callback when open in new window is clicked */\r\n onOpenNewWindow?: (projectPath: string) => void;\r\n /** Additional class name */\r\n className?: string;\r\n /** Maximum number of projects to display */\r\n maxProjects?: number;\r\n /** Project paths to display (if not provided, fetches from useProjectOperations) */\r\n projectPaths?: string[];\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function AllProjectsTable({\r\n onProjectClick,\r\n onOpenNewWindow,\r\n className,\r\n maxProjects,\r\n projectPaths: propProjectPaths,\r\n}: AllProjectsTableProps) {\r\n const { formatMessage } = useIntl();\r\n const [sortField, setSortField] = useState<'name' | 'serverCount' | 'lastModified'>('lastModified');\r\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');\r\n const [projectStats, setProjectStats] = useState<ProjectServerStats[]>([]);\r\n const [isStatsLoading, setIsStatsLoading] = useState(false);\r\n\r\n const { projects, currentProject, isLoading } = useProjectOperations();\r\n\r\n // Use provided project paths or default to all projects\r\n // Memoize to stabilize the array reference and prevent useEffect infinite loops\r\n const displayProjects = useMemo(() => {\r\n const target = propProjectPaths ?? projects;\r\n return maxProjects ? target.slice(0, maxProjects) : target;\r\n }, [propProjectPaths, projects, maxProjects]);\r\n\r\n // Fetch real project server stats on mount\r\n useEffect(() => {\r\n const fetchStats = async () => {\r\n if (displayProjects.length === 0) {\r\n setProjectStats([]);\r\n return;\r\n }\r\n\r\n setIsStatsLoading(true);\r\n try {\r\n const response = await fetchOtherProjectsServers(displayProjects);\r\n const stats: ProjectServerStats[] = displayProjects.map((path) => {\r\n const isCurrent = path === currentProject;\r\n const name = path.split(/[/\\\\]/).filter(Boolean).pop() || path;\r\n const servers = response.servers[path] ?? [];\r\n\r\n return {\r\n name,\r\n path,\r\n serverCount: servers.length,\r\n enabledCount: servers.filter((s) => s.enabled).length,\r\n lastModified: undefined, // Backend doesn't provide this yet\r\n isCurrent,\r\n };\r\n });\r\n setProjectStats(stats);\r\n } catch (error) {\r\n console.error('Failed to fetch project server stats:', error);\r\n // Fallback to empty stats on error\r\n setProjectStats(\r\n displayProjects.map((path) => ({\r\n name: path.split(/[/\\\\]/).filter(Boolean).pop() || path,\r\n path,\r\n serverCount: 0,\r\n enabledCount: 0,\r\n isCurrent: path === currentProject,\r\n }))\r\n );\r\n } finally {\r\n setIsStatsLoading(false);\r\n }\r\n };\r\n\r\n void fetchStats();\r\n }, [displayProjects, currentProject]);\r\n\r\n // Sort projects\r\n const sortedProjects = [...projectStats].sort((a, b) => {\r\n let comparison = 0;\r\n\r\n switch (sortField) {\r\n case 'name':\r\n comparison = a.name.localeCompare(b.name);\r\n break;\r\n case 'serverCount':\r\n comparison = a.serverCount - b.serverCount;\r\n break;\r\n case 'lastModified':\r\n comparison = a.lastModified && b.lastModified\r\n ? new Date(a.lastModified).getTime() - new Date(b.lastModified).getTime()\r\n : 0;\r\n break;\r\n }\r\n\r\n return sortDirection === 'asc' ? comparison : -comparison;\r\n });\r\n\r\n // Handle sort\r\n const handleSort = (field: typeof sortField) => {\r\n if (sortField === field) {\r\n setSortDirection((prev) => (prev === 'asc' ? 'desc' : 'asc'));\r\n } else {\r\n setSortField(field);\r\n setSortDirection('desc');\r\n }\r\n };\r\n\r\n // Handle project click\r\n const handleProjectClick = (projectPath: string) => {\r\n onProjectClick?.(projectPath);\r\n };\r\n\r\n // Handle open in new window\r\n const handleOpenNewWindow = (e: React.MouseEvent, projectPath: string) => {\r\n e.stopPropagation();\r\n onOpenNewWindow?.(projectPath);\r\n };\r\n\r\n if (isLoading || isStatsLoading) {\r\n return (\r\n <Card className={cn('p-8', className)}>\r\n <div className=\"flex items-center justify-center\">\r\n <div className=\"animate-spin text-muted-foreground\">-</div>\r\n <span className=\"ml-2 text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'common.actions.loading' })}\r\n </span>\r\n </div>\r\n </Card>\r\n );\r\n }\r\n\r\n if (sortedProjects.length === 0) {\r\n return (\r\n <Card className={cn('p-8', className)}>\r\n <div className=\"text-center\">\r\n <Folder className=\"w-12 h-12 mx-auto text-muted-foreground/50 mb-3\" />\r\n <p className=\"text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'mcp.allProjects.empty' })}\r\n </p>\r\n </div>\r\n </Card>\r\n );\r\n }\r\n\r\n return (\r\n <Card className={cn('overflow-hidden', className)}>\r\n {/* Table Header */}\r\n <div className=\"grid grid-cols-12 gap-2 px-4 py-3 bg-muted/50 border-b border-border text-xs font-medium text-muted-foreground uppercase\">\r\n <div className=\"col-span-4\">\r\n <button\r\n onClick={() => handleSort('name')}\r\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\r\n >\r\n {formatMessage({ id: 'mcp.allProjects.name' })}\r\n {sortField === 'name' && (\r\n <span className=\"text-foreground\">{sortDirection === 'asc' ? '↑' : '↓'}</span>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"col-span-3\">\r\n <button\r\n onClick={() => handleSort('serverCount')}\r\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\r\n >\r\n {formatMessage({ id: 'mcp.allProjects.servers' })}\r\n {sortField === 'serverCount' && (\r\n <span className=\"text-foreground\">{sortDirection === 'asc' ? '↑' : '↓'}</span>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"col-span-3\">\r\n <button\r\n onClick={() => handleSort('lastModified')}\r\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\r\n >\r\n {formatMessage({ id: 'mcp.allProjects.lastModified' })}\r\n {sortField === 'lastModified' && (\r\n <span className=\"text-foreground\">{sortDirection === 'asc' ? '↑' : '↓'}</span>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"col-span-2 text-right\">\r\n {formatMessage({ id: 'mcp.allProjects.actions' })}\r\n </div>\r\n </div>\r\n\r\n {/* Table Rows */}\r\n <div className=\"divide-y divide-border\">\r\n {sortedProjects.map((project) => (\r\n <div\r\n key={project.path}\r\n onClick={() => handleProjectClick(project.path)}\r\n className={cn(\r\n 'grid grid-cols-12 gap-2 px-4 py-3 items-center transition-colors cursor-pointer hover:bg-muted/50',\r\n project.isCurrent && 'bg-primary/5 hover:bg-primary/10'\r\n )}\r\n >\r\n {/* Project Name */}\r\n <div className=\"col-span-4 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <Folder className=\"w-4 h-4 text-muted-foreground flex-shrink-0\" />\r\n <div className=\"min-w-0 flex-1\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {project.name}\r\n </span>\r\n {project.isCurrent && (\r\n <Badge variant=\"default\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.allProjects.current' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\r\n {project.path}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Server Count */}\r\n <div className=\"col-span-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Database className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"text-sm text-foreground\">\r\n {project.serverCount} {formatMessage({ id: 'mcp.allProjects.servers' })}\r\n </span>\r\n <Badge\r\n variant=\"outline\"\r\n className={cn(\r\n 'text-xs',\r\n project.enabledCount > 0 ? 'text-success border-success/30' : 'text-muted-foreground'\r\n )}\r\n >\r\n {project.enabledCount} {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n </div>\r\n </div>\r\n\r\n {/* Last Modified */}\r\n <div className=\"col-span-3\">\r\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\r\n <Clock className=\"w-4 h-4\" />\r\n <span>\r\n {project.lastModified\r\n ? formatDistanceToNow(new Date(project.lastModified), { addSuffix: true })\r\n : '-'}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Actions */}\r\n <div className=\"col-span-2 flex justify-end gap-1\">\r\n <button\r\n onClick={(e) => handleOpenNewWindow(e, project.path)}\r\n className=\"p-1.5 rounded hover:bg-muted transition-colors\"\r\n title={formatMessage({ id: 'mcp.allProjects.openNewWindow' })}\r\n >\r\n <ExternalLink className=\"w-4 h-4 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Footer */}\r\n <div className=\"px-4 py-2 bg-muted/30 border-t border-border text-xs text-muted-foreground\">\r\n {formatMessage(\r\n { id: 'mcp.allProjects.summary' },\r\n { count: sortedProjects.length }\r\n )}\r\n </div>\r\n </Card>\r\n );\r\n}\r\n\r\nexport default AllProjectsTable;\r\n","// ========================================\r\n// Other Projects Section Component\r\n// ========================================\r\n// Section for discovering and importing servers from other projects\r\n\r\nimport { useState } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { FolderOpen, Copy, ChevronRight, RefreshCw } from 'lucide-react';\r\nimport { Card } from '@/components/ui/Card';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport { useProjectOperations, useMcpServerMutations } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\nimport type { McpServer } from '@/lib/api';\r\nimport { isHttpMcpServer, isStdioMcpServer } from '@/lib/api';\r\n\r\n// ========== Types ==========\r\n\r\n/**\r\n * Server from another project\r\n * Contains base server fields plus project metadata\r\n */\r\nexport interface OtherProjectServer {\r\n name: string;\r\n enabled: boolean;\r\n /** Display text - command for STDIO, URL for HTTP */\r\n displayText: string;\r\n /** Transport type */\r\n transport: 'stdio' | 'http';\r\n /** Project path */\r\n projectPath: string;\r\n /** Project name */\r\n projectName: string;\r\n /** Original server data */\r\n originalServer: McpServer;\r\n}\r\n\r\nexport interface OtherProjectsSectionProps {\r\n /** Callback when server is successfully imported */\r\n onImportSuccess?: (serverName: string, sourceProject: string) => void;\r\n /** Additional class name */\r\n className?: string;\r\n}\r\n\r\n// ========== Component ==========\r\n\r\nexport function OtherProjectsSection({\r\n onImportSuccess,\r\n className,\r\n}: OtherProjectsSectionProps) {\r\n const { formatMessage } = useIntl();\r\n const [selectedProjectPath, setSelectedProjectPath] = useState<string | null>(null);\r\n const [otherServers, setOtherServers] = useState<OtherProjectServer[]>([]);\r\n const [isFetchingServers, setIsFetchingServers] = useState(false);\r\n\r\n const { projects, currentProject, fetchOtherServers, isFetchingServers: isGlobalFetching } =\r\n useProjectOperations();\r\n const { createServer, isCreating } = useMcpServerMutations();\r\n\r\n // Get available projects (excluding current)\r\n const availableProjects = projects.filter((p) => p !== currentProject);\r\n\r\n // Handle project selection\r\n const handleProjectSelect = async (projectPath: string) => {\r\n setSelectedProjectPath(projectPath);\r\n setIsFetchingServers(true);\r\n\r\n try {\r\n const response = await fetchOtherServers([projectPath]);\r\n const servers: OtherProjectServer[] = [];\r\n\r\n for (const [path, serverList] of Object.entries(response.servers)) {\r\n const projectName = path.split(/[/\\\\]/).filter(Boolean).pop() || path;\r\n for (const server of (serverList as McpServer[])) {\r\n servers.push({\r\n name: server.name,\r\n enabled: server.enabled,\r\n displayText: isHttpMcpServer(server)\r\n ? server.url\r\n : (isStdioMcpServer(server) ? server.command : ''),\r\n transport: server.transport,\r\n projectPath: path,\r\n projectName,\r\n originalServer: server,\r\n });\r\n }\r\n }\r\n\r\n setOtherServers(servers);\r\n } catch (error) {\r\n console.error('Failed to fetch other projects servers:', error);\r\n setOtherServers([]);\r\n } finally {\r\n setIsFetchingServers(false);\r\n }\r\n };\r\n\r\n // Handle server import\r\n const handleImportServer = async (server: OtherProjectServer) => {\r\n try {\r\n // Generate a unique name by combining project name and server name\r\n const uniqueName = `${server.projectName}-${server.name}`.toLowerCase().replace(/\\s+/g, '-');\r\n\r\n // Create server based on transport type\r\n const serverToCreate: McpServer = {\r\n ...server.originalServer,\r\n name: uniqueName,\r\n scope: 'project',\r\n };\r\n\r\n await createServer(serverToCreate);\r\n\r\n onImportSuccess?.(uniqueName, server.projectPath);\r\n } catch (error) {\r\n console.error('Failed to import server:', error);\r\n }\r\n };\r\n\r\n const isLoading = isFetchingServers || isGlobalFetching || isCreating;\r\n const selectedProjectName = selectedProjectPath\r\n ? selectedProjectPath.split(/[/\\\\]/).filter(Boolean).pop()\r\n : null;\r\n\r\n return (\r\n <Card className={cn('p-4', className)}>\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <FolderOpen className=\"w-5 h-5 text-primary\" />\r\n <h3 className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'mcp.otherProjects.title' })}\r\n </h3>\r\n </div>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n onClick={() => selectedProjectPath && handleProjectSelect(selectedProjectPath)}\r\n disabled={!selectedProjectPath || isLoading}\r\n className=\"h-8\"\r\n >\r\n <RefreshCw className={cn('w-4 h-4', isLoading && 'animate-spin')} />\r\n </Button>\r\n </div>\r\n\r\n {/* Description */}\r\n <p className=\"text-xs text-muted-foreground mb-4\">\r\n {formatMessage({ id: 'mcp.otherProjects.description' })}\r\n </p>\r\n\r\n {/* Project Selector */}\r\n <div className=\"mb-4\">\r\n <label className=\"text-sm font-medium text-foreground mb-2 block\">\r\n {formatMessage({ id: 'mcp.otherProjects.selectProject' })}\r\n </label>\r\n <Select value={selectedProjectPath ?? ''} onValueChange={handleProjectSelect}>\r\n <SelectTrigger className=\"w-full\">\r\n <SelectValue\r\n placeholder={formatMessage({ id: 'mcp.otherProjects.selectProjectPlaceholder' })}\r\n />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {availableProjects.length === 0 ? (\r\n <div className=\"p-2 text-sm text-muted-foreground text-center\">\r\n {formatMessage({ id: 'mcp.otherProjects.noProjects' })}\r\n </div>\r\n ) : (\r\n availableProjects.map((path) => {\r\n const name = path.split(/[/\\\\]/).filter(Boolean).pop() || path;\r\n return (\r\n <SelectItem key={path} value={path}>\r\n <div className=\"flex items-center gap-2\">\r\n <FolderOpen className=\"w-4 h-4 text-muted-foreground\" />\r\n <span className=\"truncate\">{name}</span>\r\n </div>\r\n </SelectItem>\r\n );\r\n })\r\n )}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Servers List */}\r\n {selectedProjectPath && (\r\n <div className=\"space-y-2\">\r\n {isFetchingServers ? (\r\n <div className=\"flex items-center justify-center py-8\">\r\n <div className=\"animate-spin text-muted-foreground\">-</div>\r\n <span className=\"ml-2 text-sm text-muted-foreground\">\r\n {formatMessage({ id: 'common.actions.loading' })}\r\n </span>\r\n </div>\r\n ) : otherServers.length === 0 ? (\r\n <div className=\"p-4 text-center text-sm text-muted-foreground border border-dashed rounded-lg\">\r\n {formatMessage(\r\n { id: 'mcp.otherProjects.noServers' },\r\n { project: selectedProjectName }\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"space-y-2 max-h-60 overflow-y-auto\">\r\n {otherServers.map((server) => (\r\n <div\r\n key={`${server.projectPath}-${server.name}`}\r\n className=\"flex items-center gap-3 p-3 rounded-lg bg-muted/30 hover:bg-muted/50 transition-colors\"\r\n >\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {server.name}\r\n </span>\r\n {server.enabled && (\r\n <Badge variant=\"success\" className=\"text-xs\">\r\n {formatMessage({ id: 'mcp.status.enabled' })}\r\n </Badge>\r\n )}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground font-mono truncate\">\r\n {server.displayText}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground truncate\">\r\n <span className=\"font-medium\">{server.projectName}</span>\r\n <ChevronRight className=\"inline w-3 h-3 mx-1\" />\r\n <span className=\"font-mono\">{server.projectPath}</span>\r\n </p>\r\n </div>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => handleImportServer(server)}\r\n disabled={isCreating}\r\n className=\"flex-shrink-0\"\r\n >\r\n <Copy className=\"w-4 h-4 mr-1\" />\r\n {formatMessage({ id: 'mcp.otherProjects.import' })}\r\n </Button>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Hint */}\r\n {selectedProjectPath && otherServers.length > 0 && (\r\n <p className=\"text-xs text-muted-foreground mt-3\">\r\n {formatMessage({ id: 'mcp.otherProjects.hint' })}\r\n </p>\r\n )}\r\n </Card>\r\n );\r\n}\r\n\r\nexport default OtherProjectsSection;\r\n","// ========================================\n// MCP Manager Page\n// ========================================\n// Manage MCP servers (Model Context Protocol) with tabbed interface\n// Supports Templates, Servers, and Cross-CLI tabs\n\nimport { useState, useMemo } from 'react';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useQueryClient } from '@tanstack/react-query';\nimport {\n Server,\n Plus,\n Search,\n RefreshCw,\n Globe,\n Folder,\n Power,\n PowerOff,\n Edit,\n Trash2,\n ChevronDown,\n ChevronUp,\n BookmarkPlus,\n AlertTriangle,\n Link,\n Eye,\n EyeOff,\n} from 'lucide-react';\nimport { Card } from '@/components/ui/Card';\nimport { Button } from '@/components/ui/Button';\nimport { Input } from '@/components/ui/Input';\nimport { Badge } from '@/components/ui/Badge';\nimport { McpServerDialog } from '@/components/mcp/McpServerDialog';\nimport { CliModeToggle, type CliMode } from '@/components/mcp/CliModeToggle';\nimport { CodexMcpEditableCard } from '@/components/mcp/CodexMcpEditableCard';\nimport { CcwToolsMcpCard } from '@/components/mcp/CcwToolsMcpCard';\nimport { McpTemplatesSection, TemplateSaveDialog } from '@/components/mcp/McpTemplatesSection';\nimport { RecommendedMcpSection } from '@/components/mcp/RecommendedMcpSection';\nimport { WindowsCompatibilityWarning } from '@/components/mcp/WindowsCompatibilityWarning';\nimport { CrossCliSyncPanel } from '@/components/mcp/CrossCliSyncPanel';\nimport { AllProjectsTable } from '@/components/mcp/AllProjectsTable';\nimport { OtherProjectsSection } from '@/components/mcp/OtherProjectsSection';\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\nimport { useMcpServers, useMcpServerMutations, useNotifications } from '@/hooks';\nimport { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';\nimport {\n fetchCodexMcpServers,\n fetchCcwMcpConfig,\n fetchCcwMcpConfigForCodex,\n updateCcwConfig,\n updateCcwConfigForCodex,\n installCcwMcp,\n uninstallCcwMcpFromScope,\n codexRemoveServer,\n codexToggleServer,\n saveMcpTemplate,\n type McpServer,\n type McpServerConflict,\n type CcwMcpConfig,\n isHttpMcpServer,\n isStdioMcpServer,\n} from '@/lib/api';\nimport { cn } from '@/lib/utils';\n\n// ========== MCP Server Card Component ==========\n\ninterface McpServerCardProps {\n server: McpServer;\n isExpanded: boolean;\n onToggleExpand: () => void;\n onToggle: (serverName: string, enabled: boolean) => void;\n onEdit: (server: McpServer) => void;\n onDelete: (server: McpServer) => void;\n onSaveAsTemplate: (server: McpServer) => void;\n conflictInfo?: McpServerConflict;\n}\n\n/**\n * Mask a header value for display (show first 4 chars + ***)\n */\nfunction maskHeaderValue(value: string): string {\n if (!value || value.length <= 4) return '****';\n return value.substring(0, 4) + '****';\n}\n\nfunction McpServerCard({ server, isExpanded, onToggleExpand, onToggle, onEdit, onDelete, onSaveAsTemplate, conflictInfo }: McpServerCardProps) {\n const { formatMessage } = useIntl();\n const [showHeaderValues, setShowHeaderValues] = useState<Record<string, boolean>>({});\n\n const isHttp = isHttpMcpServer(server);\n const isStdio = isStdioMcpServer(server);\n\n // Get display text for server summary line\n const getServerSummary = () => {\n if (isHttp) {\n return server.url;\n }\n return `${server.command} ${server.args?.join(' ') || ''}`.trim();\n };\n\n // Get all headers for HTTP server (combine Claude + Codex formats)\n const getHttpHeaders = (): Array<{ name: string; value: string; isEnvVar?: boolean }> => {\n if (!isHttp) return [];\n\n const headers: Array<{ name: string; value: string; isEnvVar?: boolean }> = [];\n\n // Claude format: headers object\n if (server.headers) {\n Object.entries(server.headers).forEach(([name, value]) => {\n headers.push({ name, value });\n });\n }\n\n // Codex format: httpHeaders object\n if (server.httpHeaders) {\n Object.entries(server.httpHeaders).forEach(([name, value]) => {\n headers.push({ name, value });\n });\n }\n\n // Codex format: bearerTokenEnvVar (adds Authorization header)\n if (server.bearerTokenEnvVar) {\n headers.push({\n name: 'Authorization',\n value: `Bearer $${server.bearerTokenEnvVar}`,\n isEnvVar: true,\n });\n }\n\n return headers;\n };\n\n // Toggle header value visibility\n const toggleHeaderValue = (headerName: string) => {\n setShowHeaderValues(prev => ({\n ...prev,\n [headerName]: !prev[headerName]\n }));\n };\n\n return (\n <Card className={cn('overflow-hidden', !server.enabled && 'opacity-60')}>\n {/* Header */}\n <div\n className=\"p-4 cursor-pointer hover:bg-muted/50 transition-colors\"\n onClick={onToggleExpand}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex items-start gap-3\">\n <div className={cn(\n 'p-2 rounded-lg',\n server.enabled ? 'bg-primary/10' : 'bg-muted'\n )}>\n <Server className={cn(\n 'w-5 h-5',\n server.enabled ? 'text-primary' : 'text-muted-foreground'\n )} />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-foreground\">\n {server.name}\n </span>\n {/* Transport type badge */}\n {isHttp && (\n <Badge variant=\"outline\" className=\"text-xs text-blue-600 border-blue-300\">\n <Link className=\"w-3 h-3 mr-1\" />\n {formatMessage({ id: 'mcp.transport.http' })}\n </Badge>\n )}\n <Badge variant={server.scope === 'global' ? 'default' : 'secondary'} className=\"text-xs\">\n {server.scope === 'global' ? (\n <><Globe className=\"w-3 h-3 mr-1\" />{formatMessage({ id: 'mcp.scope.global' })}</>\n ) : (\n <><Folder className=\"w-3 h-3 mr-1\" />{formatMessage({ id: 'mcp.scope.project' })}</>\n )}\n </Badge>\n {conflictInfo && (\n <Badge variant=\"outline\" className=\"text-xs text-orange-500 border-orange-300\">\n <AlertTriangle className=\"w-3 h-3 mr-1\" />\n {formatMessage({ id: 'mcp.conflict.badge' })}\n </Badge>\n )}\n {server.enabled && (\n <Badge variant=\"outline\" className=\"text-xs text-green-600\">\n {formatMessage({ id: 'mcp.status.enabled' })}\n </Badge>\n )}\n </div>\n <p className=\"text-sm text-muted-foreground mt-1 font-mono truncate max-w-md\" title={getServerSummary()}>\n {getServerSummary()}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onToggle(server.name, !server.enabled);\n }}\n >\n {server.enabled ? <Power className=\"w-4 h-4 text-green-600\" /> : <PowerOff className=\"w-4 h-4\" />}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onSaveAsTemplate(server);\n }}\n title={formatMessage({ id: 'mcp.templates.actions.saveAsTemplate' })}\n >\n <BookmarkPlus className=\"w-4 h-4 text-primary\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit(server);\n }}\n >\n <Edit className=\"w-4 h-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-8 p-0\"\n onClick={(e) => {\n e.stopPropagation();\n onDelete(server);\n }}\n >\n <Trash2 className=\"w-4 h-4 text-destructive\" />\n </Button>\n {isExpanded ? (\n <ChevronUp className=\"w-5 h-5 text-muted-foreground\" />\n ) : (\n <ChevronDown className=\"w-5 h-5 text-muted-foreground\" />\n )}\n </div>\n </div>\n </div>\n\n {/* Expanded Content */}\n {isExpanded && (\n <div className=\"border-t border-border p-4 space-y-3 bg-muted/30\">\n {/* HTTP Server Details */}\n {isHttp && (\n <>\n {/* URL */}\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.url' })}</p>\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto break-all\">\n {server.url}\n </code>\n </div>\n\n {/* HTTP Headers */}\n {getHttpHeaders().length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.http.headers' })}</p>\n <div className=\"space-y-1\">\n {getHttpHeaders().map((header) => (\n <div key={header.name} className=\"flex items-center gap-2 text-sm\">\n <Badge variant=\"secondary\" className=\"font-mono\">{header.name}</Badge>\n <span className=\"text-muted-foreground\">=</span>\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\n {showHeaderValues[header.name] ? header.value : maskHeaderValue(header.value)}\n </code>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 p-0\"\n onClick={() => toggleHeaderValue(header.name)}\n title={showHeaderValues[header.name]\n ? formatMessage({ id: 'mcp.http.hideValue' })\n : formatMessage({ id: 'mcp.http.showValue' })}\n >\n {showHeaderValues[header.name] ? (\n <EyeOff className=\"w-3 h-3 text-muted-foreground\" />\n ) : (\n <Eye className=\"w-3 h-3 text-muted-foreground\" />\n )}\n </Button>\n {header.isEnvVar && (\n <Badge variant=\"outline\" className=\"text-xs text-blue-500\">\n {formatMessage({ id: 'mcp.http.envVar' })}\n </Badge>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </>\n )}\n\n {/* STDIO Server Details */}\n {isStdio && (\n <>\n {/* Command details */}\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.command' })}</p>\n <code className=\"text-sm bg-background px-2 py-1 rounded block overflow-x-auto\">\n {server.command}\n </code>\n </div>\n\n {/* Args */}\n {server.args && server.args.length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.args' })}</p>\n <div className=\"flex flex-wrap gap-1\">\n {server.args.map((arg, idx) => (\n <Badge key={idx} variant=\"outline\" className=\"font-mono text-xs\">\n {arg}\n </Badge>\n ))}\n </div>\n </div>\n )}\n\n {/* Environment variables */}\n {server.env && Object.keys(server.env).length > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">{formatMessage({ id: 'mcp.env' })}</p>\n <div className=\"space-y-1\">\n {Object.entries(server.env).map(([key, value]) => (\n <div key={key} className=\"flex items-center gap-2 text-sm\">\n <Badge variant=\"secondary\" className=\"font-mono\">{key}</Badge>\n <span className=\"text-muted-foreground\">=</span>\n <code className=\"text-xs bg-background px-2 py-1 rounded flex-1 overflow-x-auto\">\n {value as string}\n </code>\n </div>\n ))}\n </div>\n </div>\n )}\n </>\n )}\n\n {/* Conflict warning panel */}\n {conflictInfo && (\n <div className=\"p-3 bg-orange-50 dark:bg-orange-950/30 border border-orange-200 dark:border-orange-800 rounded-lg space-y-1\">\n <div className=\"flex items-center gap-2 text-orange-700 dark:text-orange-400\">\n <AlertTriangle className=\"w-4 h-4\" />\n <span className=\"text-sm font-medium\">{formatMessage({ id: 'mcp.conflict.title' })}</span>\n </div>\n <p className=\"text-xs text-orange-600 dark:text-orange-400/80\">\n {formatMessage({ id: 'mcp.conflict.description' }, { scope: formatMessage({ id: `mcp.scope.${conflictInfo.effectiveScope}` }) })}\n </p>\n <p className=\"text-xs text-orange-600 dark:text-orange-400/80\">\n {formatMessage({ id: 'mcp.conflict.resolution' })}\n </p>\n </div>\n )}\n </div>\n )}\n </Card>\n );\n}\n\n// ========== Main Page Component ==========\n\nexport function McpManagerPage() {\n const { formatMessage } = useIntl();\n const [activeTab, setActiveTab] = useState<'templates' | 'servers' | 'cross-cli'>('servers');\n const [searchQuery, setSearchQuery] = useState('');\n const [scopeFilter, setScopeFilter] = useState<'all' | 'project' | 'global'>('all');\n const [expandedServers, setExpandedServers] = useState<Set<string>>(new Set());\n const [dialogOpen, setDialogOpen] = useState(false);\n const [editingServer, setEditingServer] = useState<McpServer | undefined>(undefined);\n const [cliMode, setCliMode] = useState<CliMode>('claude');\n const [codexExpandedServers, setCodexExpandedServers] = useState<Set<string>>(new Set());\n const [saveTemplateDialogOpen, setSaveTemplateDialogOpen] = useState(false);\n const [serverToSaveAsTemplate, setServerToSaveAsTemplate] = useState<McpServer | undefined>(undefined);\n\n const queryClient = useQueryClient();\n const notifications = useNotifications();\n\n const {\n servers,\n projectServers,\n globalServers,\n conflicts,\n totalCount,\n enabledCount,\n isLoading,\n isFetching,\n refetch,\n } = useMcpServers({\n scope: scopeFilter === 'all' ? undefined : scopeFilter,\n });\n\n // Fetch Codex MCP servers when in codex mode\n const codexQuery = useQuery({\n queryKey: ['codexMcpServers'],\n queryFn: fetchCodexMcpServers,\n enabled: cliMode === 'codex',\n staleTime: 2 * 60 * 1000, // 2 minutes\n });\n\n const projectPath = useWorkflowStore(selectProjectPath);\n\n // Fetch CCW Tools MCP configuration (Claude mode only)\n const ccwMcpQuery = useQuery({\n queryKey: ['ccwMcpConfig', projectPath],\n queryFn: () => fetchCcwMcpConfig(projectPath ?? undefined),\n enabled: cliMode === 'claude',\n staleTime: 5 * 60 * 1000, // 5 minutes\n });\n\n // Fetch CCW Tools MCP configuration (Codex mode only)\n const ccwMcpCodexQuery = useQuery({\n queryKey: ['ccwMcpConfigCodex'],\n queryFn: fetchCcwMcpConfigForCodex,\n enabled: cliMode === 'codex',\n staleTime: 5 * 60 * 1000, // 5 minutes\n });\n\n const {\n toggleServer,\n deleteServer,\n } = useMcpServerMutations();\n\n const toggleExpand = (serverName: string) => {\n setExpandedServers((prev) => {\n const next = new Set(prev);\n if (next.has(serverName)) {\n next.delete(serverName);\n } else {\n next.add(serverName);\n }\n return next;\n });\n };\n\n const toggleCodexExpand = (serverName: string) => {\n setCodexExpandedServers((prev) => {\n const next = new Set(prev);\n if (next.has(serverName)) {\n next.delete(serverName);\n } else {\n next.add(serverName);\n }\n return next;\n });\n };\n\n const handleToggle = (serverName: string, enabled: boolean) => {\n toggleServer(serverName, enabled);\n };\n\n const handleDelete = async (server: McpServer) => {\n if (confirm(formatMessage({ id: 'mcp.deleteConfirm' }, { name: server.name }))) {\n try {\n await deleteServer(server.name, server.scope);\n notifications.success(\n formatMessage({ id: 'mcp.actions.delete' }),\n server.name\n );\n refetch();\n } catch (error) {\n console.error('Failed to delete MCP server:', error);\n notifications.error(\n formatMessage({ id: 'mcp.actions.delete' }),\n error instanceof Error ? error.message : String(error)\n );\n }\n }\n };\n\n const handleEdit = (server: McpServer) => {\n setEditingServer(server);\n setDialogOpen(true);\n };\n\n const handleAddClick = () => {\n setEditingServer(undefined);\n setDialogOpen(true);\n };\n\n const handleDialogClose = () => {\n setDialogOpen(false);\n setEditingServer(undefined);\n };\n\n const handleDialogSave = () => {\n setDialogOpen(false);\n setEditingServer(undefined);\n refetch();\n };\n\n const handleModeChange = (mode: CliMode) => {\n setCliMode(mode);\n };\n\n // CCW MCP handlers\n const ccwConfig = ccwMcpQuery.data ?? {\n isInstalled: false,\n enabledTools: [],\n projectRoot: undefined,\n allowedDirs: undefined,\n enableSandbox: undefined,\n installedScopes: [] as ('global' | 'project')[],\n };\n\n const ccwMcpQueryKey = ['ccwMcpConfig', projectPath];\n\n const handleToggleCcwTool = async (tool: string, enabled: boolean) => {\n // Read latest from cache to avoid stale closures\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey) ?? ccwConfig;\n const currentTools = currentConfig.enabledTools;\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey);\n\n const updatedTools = enabled\n ? (currentTools.includes(tool) ? currentTools : [...currentTools, tool])\n : currentTools.filter((t) => t !== tool);\n\n // Optimistic cache update for immediate UI response\n queryClient.setQueryData(ccwMcpQueryKey, (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, enabledTools: updatedTools };\n });\n\n try {\n await updateCcwConfig({ ...currentConfig, enabledTools: updatedTools });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.toggle.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to toggle CCW tool:', error);\n queryClient.setQueryData(ccwMcpQueryKey, previousConfig);\n }\n ccwMcpQuery.refetch();\n };\n\n const handleUpdateCcwConfig = async (config: Partial<CcwMcpConfig>) => {\n // Read BEFORE optimistic update to capture previous state for rollback\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey);\n\n // Optimistic cache update for immediate UI response\n queryClient.setQueryData(ccwMcpQueryKey, (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, ...config };\n });\n\n // Read AFTER optimistic update to get the latest merged state\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(ccwMcpQueryKey) ?? ccwConfig;\n\n try {\n // Only pass the fields that updateCcwConfig expects\n await updateCcwConfig({\n enabledTools: currentConfig.enabledTools,\n projectRoot: currentConfig.projectRoot,\n allowedDirs: currentConfig.allowedDirs,\n enableSandbox: currentConfig.enableSandbox,\n });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.update.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to update CCW config:', error);\n queryClient.setQueryData(ccwMcpQueryKey, previousConfig);\n }\n ccwMcpQuery.refetch();\n };\n\n const handleCcwInstall = () => {\n ccwMcpQuery.refetch();\n };\n\n // Build conflict map for quick lookup\n const conflictMap = useMemo(() => {\n const map = new Map<string, McpServerConflict>();\n for (const c of conflicts) map.set(c.name, c);\n return map;\n }, [conflicts]);\n\n // CCW scope-specific handlers\n const handleCcwInstallToScope = async (scope: 'global' | 'project') => {\n try {\n await installCcwMcp(scope, scope === 'project' ? projectPath ?? undefined : undefined);\n ccwMcpQuery.refetch();\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.install.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to install CCW MCP to scope:', error);\n }\n };\n\n const handleCcwUninstallFromScope = async (scope: 'global' | 'project') => {\n try {\n await uninstallCcwMcpFromScope(scope, scope === 'project' ? projectPath ?? undefined : undefined);\n ccwMcpQuery.refetch();\n queryClient.invalidateQueries({ queryKey: ['mcpServers'] });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.uninstall.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to uninstall CCW MCP from scope:', error);\n }\n };\n\n // CCW MCP handlers for Codex mode\n const ccwCodexConfig = ccwMcpCodexQuery.data ?? {\n isInstalled: false,\n enabledTools: [] as string[],\n projectRoot: undefined,\n allowedDirs: undefined,\n enableSandbox: undefined,\n installedScopes: [] as ('global' | 'project')[],\n };\n\n const handleToggleCcwToolCodex = async (tool: string, enabled: boolean) => {\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']) ?? ccwCodexConfig;\n const currentTools = currentConfig.enabledTools;\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']);\n\n const updatedTools = enabled\n ? (currentTools.includes(tool) ? currentTools : [...currentTools, tool])\n : currentTools.filter((t) => t !== tool);\n\n queryClient.setQueryData(['ccwMcpConfigCodex'], (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, enabledTools: updatedTools };\n });\n\n try {\n await updateCcwConfigForCodex({ ...currentConfig, enabledTools: updatedTools });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.toggle.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to toggle CCW tool (Codex):', error);\n queryClient.setQueryData(['ccwMcpConfigCodex'], previousConfig);\n }\n ccwMcpCodexQuery.refetch();\n };\n\n const handleUpdateCcwConfigCodex = async (config: Partial<CcwMcpConfig>) => {\n const currentConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']) ?? ccwCodexConfig;\n const previousConfig = queryClient.getQueryData<CcwMcpConfig>(['ccwMcpConfigCodex']);\n\n queryClient.setQueryData(['ccwMcpConfigCodex'], (old: CcwMcpConfig | undefined) => {\n if (!old) return old;\n return { ...old, ...config };\n });\n\n try {\n await updateCcwConfigForCodex({ ...currentConfig, ...config });\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.update.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to update CCW config (Codex):', error);\n queryClient.setQueryData(['ccwMcpConfigCodex'], previousConfig);\n }\n ccwMcpCodexQuery.refetch();\n };\n\n const handleCcwInstallCodex = () => {\n ccwMcpCodexQuery.refetch();\n };\n\n // Template handlers\n const handleInstallTemplate = (template: any) => {\n const serverConfig = template?.serverConfig ?? {};\n const isHttp =\n serverConfig.type === 'http' ||\n serverConfig.transport === 'http' ||\n typeof serverConfig.url === 'string';\n\n if (isHttp) {\n setEditingServer({\n name: template.name,\n transport: 'http',\n url: serverConfig.url ?? '',\n scope: 'project',\n enabled: true,\n });\n } else {\n setEditingServer({\n name: template.name,\n transport: 'stdio',\n command: serverConfig.command,\n args: serverConfig.args || [],\n env: serverConfig.env,\n scope: 'project',\n enabled: true,\n });\n }\n setDialogOpen(true);\n };\n\n const handleSaveServerAsTemplate = (server: McpServer) => {\n setServerToSaveAsTemplate(server);\n setSaveTemplateDialogOpen(true);\n };\n\n const handleSaveAsTemplate = async (\n name: string,\n category: string,\n description: string,\n serverConfig: { command: string; args: string[]; env: Record<string, string> },\n ) => {\n try {\n const result = await saveMcpTemplate({\n name,\n description: description || undefined,\n category: category || 'custom',\n serverConfig: {\n command: serverConfig.command,\n args: serverConfig.args.length > 0 ? serverConfig.args : undefined,\n env: Object.keys(serverConfig.env).length > 0 ? serverConfig.env : undefined,\n },\n });\n if (result.success) {\n notifications.success(\n formatMessage({ id: 'mcp.templates.feedback.saveSuccess' }),\n name\n );\n setSaveTemplateDialogOpen(false);\n setServerToSaveAsTemplate(undefined);\n } else {\n notifications.error(\n formatMessage({ id: 'mcp.templates.feedback.saveError' }),\n result.error || ''\n );\n }\n } catch (error) {\n notifications.error(\n formatMessage({ id: 'mcp.templates.feedback.saveError' }),\n error instanceof Error ? error.message : String(error)\n );\n }\n };\n\n // Codex MCP handlers\n const handleCodexRemove = async (serverName: string) => {\n try {\n await codexRemoveServer(serverName);\n notifications.success(\n formatMessage({ id: 'mcp.actions.delete' }),\n serverName\n );\n codexQuery.refetch();\n } catch (error) {\n console.error('Failed to remove Codex MCP server:', error);\n notifications.error(\n formatMessage({ id: 'mcp.actions.delete' }),\n error instanceof Error ? error.message : String(error)\n );\n }\n };\n\n const handleCodexToggle = async (serverName: string, enabled: boolean) => {\n try {\n await codexToggleServer(serverName, enabled);\n codexQuery.refetch();\n } catch (error) {\n notifications.error(formatMessage({ id: 'mcp.actions.toggle.error' }), error instanceof Error ? error.message : String(error));\n console.error('Failed to toggle Codex MCP server:', error);\n }\n };\n\n // Filter servers by search query\n const filteredServers = servers.filter((s) => {\n const query = searchQuery.toLowerCase();\n const nameMatch = s.name.toLowerCase().includes(query);\n // For STDIO servers, search in command; for HTTP servers, search in url\n const transportMatch = isHttpMcpServer(s)\n ? s.url?.toLowerCase().includes(query)\n : s.command?.toLowerCase().includes(query);\n return nameMatch || transportMatch;\n });\n\n // Filter Codex servers by search query\n const codexServers = codexQuery.data?.servers ?? [];\n const codexConfigPath = codexQuery.data?.configPath ?? '';\n const filteredCodexServers = codexServers.filter((s) => {\n const query = searchQuery.toLowerCase();\n const nameMatch = s.name.toLowerCase().includes(query);\n // For STDIO servers, search in command; for HTTP servers, search in url\n const transportMatch = isHttpMcpServer(s)\n ? s.url?.toLowerCase().includes(query)\n : s.command?.toLowerCase().includes(query);\n return nameMatch || transportMatch;\n });\n\n const currentServers = cliMode === 'codex' ? filteredCodexServers : filteredServers;\n const currentExpanded = cliMode === 'codex' ? codexExpandedServers : expandedServers;\n const currentToggleExpand = cliMode === 'codex' ? toggleCodexExpand : toggleExpand;\n const currentIsLoading = cliMode === 'codex' ? codexQuery.isLoading : isLoading;\n const currentIsFetching = cliMode === 'codex' ? codexQuery.isFetching : isFetching;\n const currentRefetch = cliMode === 'codex' ? (() => codexQuery.refetch()) : refetch;\n\n return (\n <div className=\"space-y-6\">\n {/* Page Header */}\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\n <div className=\"flex items-center gap-3\">\n <div>\n <h1 className=\"text-2xl font-bold text-foreground flex items-center gap-2\">\n <Server className=\"w-6 h-6 text-primary\" />\n {formatMessage({ id: 'mcp.title' })}\n </h1>\n <p className=\"text-muted-foreground mt-1\">\n {formatMessage({ id: 'mcp.description' })}\n </p>\n </div>\n {/* CLI Mode Badge Switcher */}\n <div className=\"ml-3 flex-shrink-0\">\n <CliModeToggle\n currentMode={cliMode}\n onModeChange={handleModeChange}\n codexConfigPath={codexConfigPath}\n />\n </div>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" onClick={() => currentRefetch()} disabled={currentIsFetching}>\n <RefreshCw className={cn('w-4 h-4 mr-2', currentIsFetching && 'animate-spin')} />\n {formatMessage({ id: 'common.actions.refresh' })}\n </Button>\n {cliMode === 'claude' && (\n <Button onClick={handleAddClick}>\n <Plus className=\"w-4 h-4 mr-2\" />\n {formatMessage({ id: 'mcp.actions.add' })}\n </Button>\n )}\n </div>\n </div>\n\n {/* Tabbed Interface */}\n <TabsNavigation\n value={activeTab}\n onValueChange={(value) => setActiveTab(value as 'templates' | 'servers' | 'cross-cli')}\n tabs={[\n { value: 'templates', label: formatMessage({ id: 'mcp.tabs.templates' }) },\n { value: 'servers', label: formatMessage({ id: 'mcp.tabs.servers' }) },\n { value: 'cross-cli', label: formatMessage({ id: 'mcp.tabs.crossCli' }) },\n ]}\n />\n\n {/* Tab Content: Templates */}\n {activeTab === 'templates' && (\n <div className=\"mt-4 space-y-4\">\n {/* Recommended MCP Servers */}\n <RecommendedMcpSection onInstallComplete={() => refetch()} />\n\n {/* Templates Section */}\n <McpTemplatesSection\n onInstallTemplate={handleInstallTemplate}\n onSaveAsTemplate={handleSaveAsTemplate}\n />\n </div>\n )}\n\n {/* Tab Content: Servers */}\n {activeTab === 'servers' && (\n <div className=\"mt-4 space-y-4\">\n {/* Windows Compatibility Warning */}\n <WindowsCompatibilityWarning />\n\n {/* Stats Cards - Claude mode only */}\n {cliMode === 'claude' && (\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Server className=\"w-5 h-5 text-primary\" />\n <span className=\"text-2xl font-bold\">{totalCount}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.total' })}</p>\n </Card>\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Power className=\"w-5 h-5 text-green-600\" />\n <span className=\"text-2xl font-bold\">{enabledCount}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.enabled' })}</p>\n </Card>\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Globe className=\"w-5 h-5 text-info\" />\n <span className=\"text-2xl font-bold\">{globalServers.length}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.global' })}</p>\n </Card>\n <Card className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <Folder className=\"w-5 h-5 text-warning\" />\n <span className=\"text-2xl font-bold\">{projectServers.length}</span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">{formatMessage({ id: 'mcp.stats.project' })}</p>\n </Card>\n </div>\n )}\n\n {/* Filters and Search - Claude mode only */}\n {cliMode === 'claude' && (\n <div className=\"flex flex-col sm:flex-row gap-3\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\n <Input\n placeholder={formatMessage({ id: 'mcp.filters.searchPlaceholder' })}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant={scopeFilter === 'all' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setScopeFilter('all')}\n >\n {formatMessage({ id: 'mcp.filters.all' })}\n </Button>\n <Button\n variant={scopeFilter === 'global' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setScopeFilter('global')}\n >\n <Globe className=\"w-4 h-4 mr-1\" />\n {formatMessage({ id: 'mcp.scope.global' })}\n </Button>\n <Button\n variant={scopeFilter === 'project' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setScopeFilter('project')}\n >\n <Folder className=\"w-4 h-4 mr-1\" />\n {formatMessage({ id: 'mcp.scope.project' })}\n </Button>\n </div>\n </div>\n )}\n\n {/* Codex mode search only */}\n {cliMode === 'codex' && (\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\n <Input\n placeholder={formatMessage({ id: 'mcp.filters.searchPlaceholder' })}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n )}\n\n {/* CCW Tools MCP Card */}\n {cliMode === 'claude' && (\n <CcwToolsMcpCard\n isInstalled={ccwConfig.isInstalled}\n enabledTools={ccwConfig.enabledTools}\n projectRoot={ccwConfig.projectRoot}\n allowedDirs={ccwConfig.allowedDirs}\n enableSandbox={ccwConfig.enableSandbox}\n onToggleTool={handleToggleCcwTool}\n onUpdateConfig={handleUpdateCcwConfig}\n onInstall={handleCcwInstall}\n installedScopes={ccwConfig.installedScopes}\n onInstallToScope={handleCcwInstallToScope}\n onUninstallScope={handleCcwUninstallFromScope}\n />\n )}\n {cliMode === 'codex' && (\n <CcwToolsMcpCard\n target=\"codex\"\n isInstalled={ccwCodexConfig.isInstalled}\n enabledTools={ccwCodexConfig.enabledTools}\n projectRoot={ccwCodexConfig.projectRoot}\n allowedDirs={ccwCodexConfig.allowedDirs}\n enableSandbox={ccwCodexConfig.enableSandbox}\n onToggleTool={handleToggleCcwToolCodex}\n onUpdateConfig={handleUpdateCcwConfigCodex}\n onInstall={handleCcwInstallCodex}\n />\n )}\n\n {/* Servers List */}\n {currentIsLoading ? (\n <div className=\"space-y-3\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className=\"h-24 bg-muted animate-pulse rounded-lg\" />\n ))}\n </div>\n ) : currentServers.length === 0 ? (\n <Card className=\"p-8 text-center\">\n <Server className=\"w-12 h-12 mx-auto text-muted-foreground/50\" />\n <h3 className=\"mt-4 text-lg font-medium text-foreground\">{formatMessage({ id: 'mcp.emptyState.title' })}</h3>\n <p className=\"mt-2 text-muted-foreground\">\n {formatMessage({ id: 'mcp.emptyState.message' })}\n </p>\n </Card>\n ) : (\n <div className=\"space-y-3\">\n {currentServers.map((server) => (\n cliMode === 'codex' ? (\n <CodexMcpEditableCard\n key={`${server.name}-${server.scope}`}\n server={server as McpServer}\n enabled={server.enabled}\n isExpanded={currentExpanded.has(server.name)}\n onToggleExpand={() => currentToggleExpand(server.name)}\n isEditable={true}\n onRemove={handleCodexRemove}\n onToggle={handleCodexToggle}\n />\n ) : (\n <McpServerCard\n key={`${server.name}-${server.scope}`}\n server={server}\n isExpanded={currentExpanded.has(`${server.name}-${server.scope}`)}\n onToggleExpand={() => currentToggleExpand(`${server.name}-${server.scope}`)}\n onToggle={handleToggle}\n onEdit={handleEdit}\n onDelete={handleDelete}\n onSaveAsTemplate={handleSaveServerAsTemplate}\n conflictInfo={conflictMap.get(server.name)}\n />\n )\n ))}\n </div>\n )}\n </div>\n )}\n\n {/* Tab Content: Cross-CLI */}\n {activeTab === 'cross-cli' && (\n <div className=\"mt-4 space-y-6\">\n {/* Section 1: Claude ↔ Codex 同步 */}\n <section>\n <div className=\"flex items-center gap-2 mb-3\">\n <RefreshCw className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'mcp.sync.title' })}\n </h3>\n </div>\n <Card className=\"p-4\">\n <CrossCliSyncPanel onSuccess={() => refetch()} />\n </Card>\n </section>\n\n {/* Section 2: 项目概览 */}\n <section>\n <div className=\"flex items-center gap-2 mb-3\">\n <Folder className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'mcp.projects.title' })}\n </h3>\n </div>\n <p className=\"text-xs text-muted-foreground mb-3\">\n {formatMessage({ id: 'mcp.projects.description' })}\n </p>\n <AllProjectsTable\n maxProjects={10}\n onProjectClick={(path) => console.log('Open project:', path)}\n onOpenNewWindow={(path) => window.open(`/?project=${encodeURIComponent(path)}`, '_blank')}\n />\n </section>\n\n {/* Section 3: 跨项目导入 */}\n <section>\n <div className=\"flex items-center gap-2 mb-3\">\n <Globe className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-medium text-foreground\">\n {formatMessage({ id: 'mcp.crossProject.title' })}\n </h3>\n </div>\n <p className=\"text-xs text-muted-foreground mb-3\">\n {formatMessage({ id: 'mcp.crossProject.description' })}\n </p>\n <OtherProjectsSection\n onImportSuccess={(serverName, sourceProject) => {\n console.log('Imported server:', serverName, 'from:', sourceProject);\n refetch();\n }}\n />\n </section>\n </div>\n )}\n\n {/* Add/Edit Dialog - Claude mode only (shared across tabs) */}\n {cliMode === 'claude' && (\n <McpServerDialog\n mode={editingServer ? 'edit' : 'add'}\n server={editingServer}\n open={dialogOpen}\n onClose={handleDialogClose}\n onSave={handleDialogSave}\n />\n )}\n\n {/* Save as Template Dialog */}\n <TemplateSaveDialog\n open={saveTemplateDialogOpen}\n onClose={() => {\n setSaveTemplateDialogOpen(false);\n setServerToSaveAsTemplate(undefined);\n }}\n onSave={handleSaveAsTemplate}\n defaultName={serverToSaveAsTemplate?.name}\n defaultCommand={\n serverToSaveAsTemplate && isStdioMcpServer(serverToSaveAsTemplate)\n ? serverToSaveAsTemplate.command\n : undefined\n }\n defaultArgs={\n serverToSaveAsTemplate && isStdioMcpServer(serverToSaveAsTemplate)\n ? serverToSaveAsTemplate.args\n : undefined\n }\n defaultEnv={\n serverToSaveAsTemplate && isStdioMcpServer(serverToSaveAsTemplate)\n ? (serverToSaveAsTemplate.env as Record<string, string>)\n : undefined\n }\n />\n </div>\n );\n}\n\nexport default McpManagerPage;\n"],"names":["Files","createLucideIcon","FolderTree","Key","MessageCircleQuestion","PenLine","mcpServersKeys","scope","mcpTemplatesKeys","category","query","projectsKeys","paths","STALE_TIME","useMcpServers","options","staleTime","enabled","queryClient","useQueryClient","projectPath","useWorkflowStore","selectProjectPath","queryEnabled","useQuery","fetchMcpServers","projectServers","_a","globalServers","_b","conflicts","_c","allServers","enabledServers","s","refetch","invalidate","useUpdateMcpServer","mutation","useMutation","serverName","config","configType","updateMcpServer","useCreateMcpServer","server","createMcpServer","useDeleteMcpServer","deleteMcpServer","useToggleMcpServer","toggleMcpServer","previousServers","old","updateServer","servers","_error","_vars","context","useMcpServerMutations","update","create","remove","toggle","TEMPLATES_STALE_TIME","useMcpTemplates","fetchMcpTemplates","t","useDeleteTemplate","templateName","deleteMcpTemplate","useInstallTemplate","request","installMcpTemplate","EMPTY_PROJECTS","useProjectOperations","projectsQuery","fetchAllProjects","copyMutation","crossCliCopy","serversQuery","fetchOtherProjectsServers","fetchOtherServers","projectPaths","CONFIG_TYPE_STORAGE_KEY","DEFAULT_CONFIG_TYPE","loadConfigType","stored","saveConfigType","type","ConfigTypeToggle","currentType","onTypeChange","showWarning","existingServersCount","formatMessage","useIntl","internalType","setInternalType","useState","showWarningDialog","setShowWarningDialog","pendingType","setPendingType","useEffect","savedType","handleTypeClick","applyTypeChange","handleWarningConfirm","handleWarningCancel","jsxs","Fragment","jsx","cn","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","AlertDialogDescription","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","HttpHeadersInput","headers","onChange","disabled","revealedIds","setRevealedIds","generateId","handleAdd","handleRemove","id","h","handleUpdate","field","value","toggleReveal","prev","next","header","Input","e","Button","EyeOff","Eye","Trash2","Plus","McpServerDialog","mode","open","onClose","onSave","showError","showSuccess","useNotifications","templates","templatesLoading","transportType","setTransportType","formData","setFormData","selectedTemplate","setSelectedTemplate","errors","setErrors","argsInput","setArgsInput","envInput","setEnvInput","setConfigType","saveAsTemplate","setSaveAsTemplate","projectConfigType","inputMode","setInputMode","jsonInput","setJsonInput","detectTransportType","useCallback","serverData","isHttpMcpServer","parseJsonConfig","extractedServerName","serverNames","serverConfig","name","idx","args","env","k","v","error","detectedType","httpHeaders","headerName","stdioCommand","isStdioMcpServer","stdioArgs","stdioEnv","httpUrl","httpBearerToken","createMutation","handleClose","updateMutation","handleTemplateSelect","templateId","template","handleFieldChange","handleArgsChange","argsArray","a","handleEnvChange","envObj","lines","line","trimmed","key","valParts","val","handleHeadersChange","handleTransportTypeChange","validateForm","newErrors","checkNameExists","data","handleSubmit","envHttpHeaders","saveMcpTemplate","err","isPending","Dialog","DialogContent","DialogHeader","DialogTitle","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Terminal","Globe","arg","Badge","DialogFooter","maskHeaderValue","CodexMcpEditableCard","isExpanded","onToggleExpand","isEditable","onRemove","onToggle","isRemoving","isToggling","isConfirmDeleteOpen","setIsConfirmDeleteOpen","showHeaderValues","setShowHeaderValues","isHttp","isStdio","getServerSummary","getHttpHeaders","toggleHeaderValue","handleToggle","stopPropagation","Card","Server","Link","Edit3","Power","Lock","PowerOff","AlertDialogTrigger","ChevronUp","ChevronDown","CCW_MCP_TOOLS","CcwToolsMcpCard","isInstalled","enabledTools","projectRoot","allowedDirs","enableSandbox","onToggleTool","onUpdateConfig","onInstall","target","installedScopes","onUninstallScope","notifySuccess","notifyError","currentProjectPath","projectRootInput","setProjectRootInput","allowedDirsInput","setAllowedDirsInput","enableSandboxInput","setEnableSandboxInput","setIsExpanded","installScope","setInstallScope","isPathPickerOpen","setIsPathPickerOpen","pathPickerTarget","setPathPickerTarget","isCodex","installMutation","installCcwMcpToCodex","params","installCcwMcp","uninstallMutation","uninstallCcwMcpFromCodex","uninstallCcwMcp","updateConfigMutation","updateCcwConfigForCodex","updateCcwConfig","handleToggleTool","toolName","handleEnableAll","allToolNames","handleDisableAll","handleConfigSave","handleInstallClick","handleUninstallClick","Settings","Folder","AlertTriangle","ChevronRight","Check","tool","isEnabled","icon","getToolIcon","FolderOpen","HardDrive","Save","Download","FloatingFileBrowser","path","iconProps","FileText","Database","MessagesSquare","SEARCH_DEBOUNCE_MS","TemplateCard","onDelete","isInstalling","isDeleting","handleInstall","handleDelete","getCategoryIcon","FileCode","Copy","TemplateSaveDialog","defaultName","defaultCommand","defaultArgs","defaultEnv","setName","setCategory","description","setDescription","command","setCommand","handleSave","McpTemplatesSection","onInstallTemplate","onSaveAsTemplate","searchQuery","setSearchQuery","debouncedSearch","setDebouncedSearch","selectedCategory","setSelectedCategory","saveDialogOpen","setSaveDialogOpen","deleteConfirmOpen","setDeleteConfirmOpen","templateToDelete","setTemplateToDelete","categories","categoriesLoading","fetchMcpTemplateCategories","deleteMutation","timer","searchMcpTemplates","allTemplates","categoryTemplates","fetchMcpTemplatesByCategory","handleInstallTemplate","handleDeleteClick","handleDeleteConfirm","handleSaveTemplate","_name","_category","_description","_serverConfig","Search","Filter","ICON_MAP","Sparkles","RecommendedMcpWizard","mcpDefinition","onInstallComplete","fieldValues","setFieldValues","selectedScope","setSelectedScope","initializeFieldValues","initialValues","handleOpenChange","newOpen","addGlobalMcpServer","copyMcpServerToProject","result","handleMultiSelectToggle","current","newValue","validateFields","hasFields","Icon","Label","option","isSelected","Loader2","isWindows","buildCrossPlatformMcpConfig","RECOMMENDED_MCP_DEFINITIONS","values","baseUrl","url","Code2","RecommendedServerCard","definition","Zap","RecommendedMcpSection","wizardOpen","setWizardOpen","selectedDefinition","setSelectedDefinition","installedServerIds","setInstalledServerIds","checkInstalledServers","fetchMcpConfig","installedIds","userServers","projects","proj","handleWizardClose","handleInstallComplete","COMMON_COMMANDS","canAutoFixCommand","cmd","detectWindowsCommands","response","applyWindowsAutoFix","CommandDetectionList","commands","CheckCircle","XCircle","WindowsCompatibilityWarning","onComplete","checkResult","setCheckResult","isChecking","setIsChecking","dismissed","setDismissed","autoFixMutation","results","missingCommands","r","canAutoFix","handleAutoFix","handleDismiss","CrossCliSyncPanel","onSuccess","className","claudeServers","selectedClaude","setSelectedClaude","codexServers","setCodexServers","selectedCodex","setSelectedCodex","isLoadingCodex","setIsLoadingCodex","codexError","setCodexError","isCopying","setIsCopying","copyResult","setCopyResult","codex","fetchCodexMcpServers","toggleClaudeServer","selectAllClaude","clearAllClaude","toggleCodexServer","selectAllCodex","allNames","clearAllCodex","handleCopyToCodex","failedCount","copiedCount","handleCopyFromCodex","claudeTotal","claudeSelected","codexTotal","codexSelected","CheckCircle2","AlertCircle","Checkbox","ArrowRight","ArrowLeft","AllProjectsTable","onProjectClick","onOpenNewWindow","maxProjects","propProjectPaths","sortField","setSortField","sortDirection","setSortDirection","projectStats","setProjectStats","isStatsLoading","setIsStatsLoading","currentProject","isLoading","displayProjects","useMemo","stats","isCurrent","sortedProjects","b","comparison","handleSort","handleProjectClick","handleOpenNewWindow","project","Clock","formatDistanceToNow","ExternalLink","OtherProjectsSection","onImportSuccess","selectedProjectPath","setSelectedProjectPath","otherServers","setOtherServers","isFetchingServers","setIsFetchingServers","isGlobalFetching","createServer","isCreating","availableProjects","p","handleProjectSelect","serverList","projectName","handleImportServer","uniqueName","serverToCreate","selectedProjectName","RefreshCw","McpServerCard","onEdit","conflictInfo","BookmarkPlus","Edit","McpManagerPage","activeTab","setActiveTab","scopeFilter","setScopeFilter","expandedServers","setExpandedServers","dialogOpen","setDialogOpen","editingServer","setEditingServer","cliMode","setCliMode","codexExpandedServers","setCodexExpandedServers","saveTemplateDialogOpen","setSaveTemplateDialogOpen","serverToSaveAsTemplate","setServerToSaveAsTemplate","notifications","totalCount","enabledCount","isFetching","codexQuery","ccwMcpQuery","fetchCcwMcpConfig","ccwMcpCodexQuery","fetchCcwMcpConfigForCodex","toggleServer","deleteServer","toggleExpand","toggleCodexExpand","handleEdit","handleAddClick","handleDialogClose","handleDialogSave","handleModeChange","ccwConfig","ccwMcpQueryKey","handleToggleCcwTool","currentConfig","currentTools","previousConfig","updatedTools","handleUpdateCcwConfig","handleCcwInstall","conflictMap","map","c","handleCcwInstallToScope","handleCcwUninstallFromScope","uninstallCcwMcpFromScope","ccwCodexConfig","handleToggleCcwToolCodex","handleUpdateCcwConfigCodex","handleCcwInstallCodex","handleSaveServerAsTemplate","handleSaveAsTemplate","handleCodexRemove","codexRemoveServer","handleCodexToggle","codexToggleServer","filteredServers","nameMatch","transportMatch","codexConfigPath","filteredCodexServers","currentServers","currentExpanded","currentToggleExpand","currentIsLoading","currentIsFetching","currentRefetch","CliModeToggle","TabsNavigation","sourceProject"],"mappings":"qyDAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,GAAQC,GAAiB,QAAS,CACtC,CAAC,OAAQ,CAAE,EAAG,2BAA4B,IAAK,QAAQ,CAAE,EACzD,CAAC,OAAQ,CAAE,EAAG,8DAA+D,IAAK,QAAQ,CAAE,EAC5F,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,CACvE,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,GAAaD,GAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,qHACH,IAAK,QACX,CACA,EACE,CACE,OACA,CACE,EAAG,2HACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,uBAAwB,IAAK,QAAQ,CAAE,EACrD,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,CAC1D,CAAC,EC1BD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAME,GAAMF,GAAiB,MAAO,CAClC,CAAC,OAAQ,CAAE,EAAG,iEAAkE,IAAK,QAAQ,CAAE,EAC/F,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAQ,CAAE,EAC9C,CAAC,SAAU,CAAE,GAAI,MAAO,GAAI,OAAQ,EAAG,MAAO,IAAK,QAAQ,CAAE,CAC/D,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMG,GAAwBH,GAAiB,wBAAyB,CACtE,CAAC,OAAQ,CAAE,EAAG,iCAAkC,IAAK,QAAQ,CAAE,EAC/D,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,EACrE,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMI,GAAUJ,GAAiB,UAAW,CAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CACE,OACA,CACE,EAAG,oIACH,IAAK,QACX,CACA,CACA,CAAC,ECgBYK,EAAiB,CAC5B,IAAK,CAAC,YAAY,EAClB,MAAO,IAAM,CAAC,GAAGA,EAAe,IAAK,MAAM,EAC3C,KAAOC,GAAiC,CAAC,GAAGD,EAAe,MAAA,EAASC,CAAK,CAC3E,EAGaC,GAAmB,CAC9B,IAAK,CAAC,cAAc,EACpB,MAAO,IAAM,CAAC,GAAGA,GAAiB,IAAK,MAAM,EAC7C,KAAOC,GAAsB,CAAC,GAAGD,GAAiB,MAAA,EAASC,CAAQ,EACnE,OAASC,GAAkB,CAAC,GAAGF,GAAiB,IAAK,SAAUE,CAAK,EACpE,WAAY,IAAM,CAAC,GAAGF,GAAiB,IAAK,YAAY,CAC1D,EAGaG,GAAe,CAC1B,IAAK,CAAC,UAAU,EAChB,KAAM,IAAM,CAAC,GAAGA,GAAa,IAAK,MAAM,EACxC,QAAUC,GAAqB,CAAC,GAAGD,GAAa,IAAK,UAAW,GAAIC,GAAS,CAAA,CAAG,CAClF,EAGMC,GAAa,IAAS,IAyBrB,SAASC,GAAcC,EAAgC,GAAyB,WACrF,KAAM,CAAE,MAAAR,EAAO,UAAAS,EAAYH,GAAY,QAAAI,EAAU,IAASF,EACpDG,EAAcC,GAAA,EAEdC,EAAcC,GAAiBC,EAAiB,EAChDC,EAAeN,GAAW,CAAC,CAACG,EAE5BV,EAAQc,GAAS,CACrB,SAAUlB,EAAe,KAAKC,CAAK,EACnC,QAAS,IAAMkB,GAAgBL,CAAW,EAC1C,UAAAJ,EACA,QAASO,EACT,MAAO,CAAA,CACR,EAEKG,IAAiBC,EAAAjB,EAAM,OAAN,YAAAiB,EAAY,UAAW,CAAA,EACxCC,IAAgBC,EAAAnB,EAAM,OAAN,YAAAmB,EAAY,SAAU,CAAA,EACtCC,IAAYC,EAAArB,EAAM,OAAN,YAAAqB,EAAY,YAAa,CAAA,EACrCC,EAAazB,IAAU,UAAYmB,EAAiBnB,IAAU,SAAWqB,EAAgB,CAAC,GAAGF,EAAgB,GAAGE,CAAa,EAE7HK,EAAiBD,EAAW,OAAQE,GAAMA,EAAE,OAAO,EAEnDC,EAAU,SAAY,CAC1B,MAAMzB,EAAM,QAAA,CACd,EAEM0B,EAAa,SAAY,CAC7B,MAAMlB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CACtE,EAEA,MAAO,CACL,QAAS0B,EACT,eAAAN,EACA,cAAAE,EACA,UAAAE,EACA,WAAYE,EAAW,OACvB,aAAcC,EAAe,OAC7B,UAAWvB,EAAM,UACjB,WAAYA,EAAM,WAClB,MAAOA,EAAM,MACb,QAAAyB,EACA,WAAAC,CAAA,CAEJ,CAUO,SAASC,IAA+C,CAC7D,MAAMnB,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,WAAAC,EAAY,OAAAC,EAAQ,WAAAC,CAAA,IACjCC,GAAgBH,EAAYC,EAAQ,CAAE,YAAarB,GAAe,OAAW,WAAAsB,EAAY,EAC3F,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACkC,EAAYC,EAAQC,IAAeJ,EAAS,YAAY,CAAE,WAAAE,EAAY,OAAAC,EAAQ,WAAAC,EAAY,EACzG,WAAYJ,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAQO,SAASM,IAA+C,CAC7D,MAAM1B,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,OAAAM,EAAQ,WAAAH,CAAA,IACrBI,GAAgBD,EAAQ,CAAE,YAAazB,GAAe,OAAW,WAAAsB,EAAY,EAC/E,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACuC,EAAQH,IAAeJ,EAAS,YAAY,CAAE,OAAAO,EAAQ,WAAAH,EAAY,EACjF,WAAYJ,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAQO,SAASS,IAA+C,CAC7D,MAAM7B,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,WAAAC,EAAY,MAAAjC,CAAA,IACzByC,GAAgBR,EAAYjC,EAAO,CAAE,YAAaa,GAAe,OAAW,EAC9E,UAAW,IAAM,CACfF,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,CAC9D,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACsB,EAAYjC,IAAU+B,EAAS,YAAY,CAAE,WAAAE,EAAY,MAAAjC,EAAO,EAC/E,WAAY+B,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAQO,SAASW,IAA+C,CAC7D,MAAM/B,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAEhDgB,EAAWC,GAAY,CAC3B,WAAY,CAAC,CAAE,WAAAC,EAAY,QAAAvB,CAAA,IACzBiC,GAAgBV,EAAYvB,EAAS,CAAE,YAAaG,GAAe,OAAW,EAChF,SAAU,MAAO,CAAE,WAAAoB,EAAY,QAAAvB,KAAc,CAC3C,MAAMC,EAAY,cAAc,CAAE,SAAUZ,EAAe,IAAK,EAChE,MAAM6C,EAAkBjC,EAAY,aAAiCZ,EAAe,MAAM,EAG1F,OAAAY,EAAY,aAAiCZ,EAAe,KAAA,EAAS8C,GAAQ,CAC3E,GAAI,CAACA,EAAK,OAAOA,EACjB,MAAMC,EAAgBC,GACpBA,EAAQ,IAAKpB,GAAOA,EAAE,OAASM,EAAa,CAAE,GAAGN,EAAG,QAAAjB,CAAA,EAAYiB,CAAE,EACpE,MAAO,CACL,QAASmB,EAAaD,EAAI,OAAO,EACjC,OAAQC,EAAaD,EAAI,MAAM,EAC/B,UAAWA,EAAI,WAAa,CAAA,CAAC,CAEjC,CAAC,EAEM,CAAE,gBAAAD,CAAA,CACX,EACA,QAAS,CAACI,EAAQC,EAAOC,IAAY,CAC/BA,GAAA,MAAAA,EAAS,iBACXvC,EAAY,aAAaZ,EAAe,KAAA,EAAQmD,EAAQ,eAAe,CAE3E,EACA,UAAW,IAAM,CACfvC,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,aAAc,CAACkC,EAAYvB,IAAYqB,EAAS,YAAY,CAAE,WAAAE,EAAY,QAAAvB,EAAS,EACnF,WAAYqB,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAKO,SAASoB,IAAwB,CACtC,MAAMC,EAAStB,GAAA,EACTuB,EAAShB,GAAA,EACTiB,EAASd,GAAA,EACTe,EAASb,GAAA,EAEf,MAAO,CACL,aAAcU,EAAO,aACrB,WAAYA,EAAO,WACnB,aAAcC,EAAO,aACrB,WAAYA,EAAO,WACnB,aAAcC,EAAO,aACrB,WAAYA,EAAO,WACnB,aAAcC,EAAO,aACrB,WAAYA,EAAO,WACnB,WAAYH,EAAO,YAAcC,EAAO,YAAcC,EAAO,YAAcC,EAAO,UAAA,CAEtF,CAOA,MAAMC,GAAuB,IAAS,IAoB/B,SAASC,GAAgBjD,EAAkC,GAA2B,OAC3F,KAAM,CAAE,SAAAN,EAAU,UAAAO,EAAY+C,GAAsB,QAAA9C,EAAU,IAASF,EACjEG,EAAcC,GAAA,EAEdT,EAAQc,GAAS,CACrB,SAAUhB,GAAiB,KAAKC,CAAQ,EACxC,QAAS,IAAMwD,GAAA,EACf,UAAAjD,EACA,QAAAC,EACA,MAAO,CAAA,CACR,EAEKkB,EAAU,SAAY,CAC1B,MAAMzB,EAAM,QAAA,CACd,EAEM0B,EAAa,SAAY,CAC7B,MAAMlB,EAAY,kBAAkB,CAAE,SAAUV,GAAiB,IAAK,CACxE,EAEA,MAAO,CACL,UAAWC,IACPkB,EAAAjB,EAAM,OAAN,YAAAiB,EAAY,OAAQuC,GAAMA,EAAE,WAAazD,KAAa,CAAA,EACtDC,EAAM,MAAQ,CAAA,EAClB,UAAWA,EAAM,UACjB,WAAYA,EAAM,WAClB,MAAOA,EAAM,MACb,QAAAyB,EACA,WAAAC,CAAA,CAEJ,CAsCO,SAAS+B,IAA6C,CAC3D,MAAMjD,EAAcC,GAAA,EAEdmB,EAAWC,GAAY,CAC3B,WAAa6B,GAAyBC,GAAkBD,CAAY,EACpE,UAAW,IAAM,CACflD,EAAY,kBAAkB,CAAE,SAAUV,GAAiB,IAAK,CAClE,CAAA,CACD,EAED,MAAO,CACL,eAAgB8B,EAAS,YACzB,WAAYA,EAAS,UACrB,MAAOA,EAAS,KAAA,CAEpB,CAWO,SAASgC,IAA+C,CAC7D,MAAMpD,EAAcC,GAAA,EAEdmB,EAAWC,GAAY,CAC3B,WAAagC,GAAuCC,GAAmBD,CAAO,EAC9E,UAAW,IAAM,CAEfrD,EAAY,kBAAkB,CAAE,SAAUV,GAAiB,IAAK,EAChEU,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAED,MAAO,CACL,gBAAiBgC,EAAS,YAC1B,aAAcA,EAAS,UACvB,MAAOA,EAAS,KAAA,CAEpB,CAqEA,MAAMmC,GAA2B,CAAA,EAK1B,SAASC,IAAmD,SACjE,MAAMxD,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAGhDqD,EAAgBnD,GAAS,CAC7B,SAAUb,GAAa,KAAA,EACvB,QAAS,IAAMiE,GAAA,EACf,UAAW/D,GACX,QAAS,GACT,MAAO,CAAA,CACR,EAGKgE,EAAetC,GAAY,CAC/B,WAAagC,GAAiCO,GAAaP,CAAO,EAClE,UAAW,IAAM,CACfrD,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,CAChE,CAAA,CACD,EAGKyE,EAAevD,GAAS,CAC5B,SAAUb,GAAa,QAAA,EACvB,QAAS,IAAMqE,GAAA,EACf,UAAWnE,GACX,QAAS,GACT,MAAO,CAAA,CACR,EAEKsB,EAAU,SAAY,CAC1B,MAAMwC,EAAc,QAAA,CACtB,EAEMM,EAAoB,MAAOC,GACxB,MAAMhE,EAAY,WAAW,CAClC,SAAUP,GAAa,QAAQuE,CAAY,EAC3C,QAAS,IAAMF,GAA0BE,CAAY,EACrD,UAAWrE,EAAA,CACZ,EAGH,MAAO,CACL,WAAUc,EAAAgD,EAAc,OAAd,YAAAhD,EAAoB,WAAY8C,GAC1C,iBAAgB5C,EAAA8C,EAAc,OAAd,YAAA9C,EAAoB,iBAAkBT,GAAe,OACrE,UAAWuD,EAAc,UACzB,MAAOA,EAAc,MACrB,QAAAxC,EACA,YAAcoC,GAAYM,EAAa,YAAY,CACjD,GAAGN,EACH,OAAQ,SACR,OAAQ,QACR,YAAaA,EAAQ,aAAenD,GAAe,MAAA,CACpD,EACD,cAAgBmD,GAAYM,EAAa,YAAY,CACnD,GAAGN,EACH,OAAQ,QACR,OAAQ,SACR,YAAaA,EAAQ,aAAenD,GAAe,MAAA,CACpD,EACD,UAAWyD,EAAa,UACxB,kBAAAI,EACA,kBAAmBF,EAAa,UAAA,CAEpC,CCxfA,MAAMI,GAA0B,kBAK1BC,GAAqC,WAOpC,SAASC,IAAgC,CAC9C,GAAI,CACF,MAAMC,EAAS,aAAa,QAAQH,EAAuB,EAC3D,GAAIG,IAAW,YAAcA,IAAW,cACtC,OAAOA,CAEX,MAAQ,CAER,CACA,OAAOF,EACT,CAKO,SAASG,GAAeC,EAA2B,CACxD,GAAI,CACF,aAAa,QAAQL,GAAyBK,CAAI,CACpD,MAAQ,CAER,CACF,CAqBO,SAASC,GAAiB,CAC/B,YAAAC,EACA,aAAAC,EACA,YAAAC,EAAc,GACd,qBAAAC,EAAuB,CACzB,EAA0B,CACxB,KAAM,CAAE,cAAAC,CAAA,EAAkBC,EAAA,EACpB,CAACC,EAAcC,CAAe,EAAIC,EAAAA,SAAwBR,CAAW,EACrE,CAACS,EAAmBC,CAAoB,EAAIF,EAAAA,SAAS,EAAK,EAC1D,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAA+B,IAAI,EAGzEK,EAAAA,UAAU,IAAM,CACdN,EAAgBP,CAAW,CAC7B,EAAG,CAACA,CAAW,CAAC,EAGhBa,EAAAA,UAAU,IAAM,CACd,GAAI,CAACb,GAAeA,IAAgBN,GAAqB,CACvD,MAAMoB,EAAYnB,GAAA,EACdmB,IAAcd,IAChBO,EAAgBO,CAAS,EACzBb,EAAaa,CAAS,EAE1B,CACF,EAAG,CAAA,CAAE,EAGL,MAAMC,EAAmBjB,GAAwB,CAC3CA,IAASQ,IAETJ,GAAeC,EAAuB,GACxCS,EAAed,CAAI,EACnBY,EAAqB,EAAI,GAEzBM,EAAgBlB,CAAI,EAExB,EAGMkB,EAAmBlB,GAAwB,CAC/CS,EAAgBT,CAAI,EACpBD,GAAeC,CAAI,EACnBG,EAAaH,CAAI,EACjBY,EAAqB,EAAK,EAC1BE,EAAe,IAAI,CACrB,EAGMK,EAAuB,IAAM,CAC7BN,GACFK,EAAgBL,CAAW,CAE/B,EAGMO,EAAsB,IAAM,CAChCR,EAAqB,EAAK,EAC1BE,EAAe,IAAI,CACrB,EAEA,OACEO,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMN,EAAgB,UAAU,EACzC,UAAWO,EACT,yDACAhB,IAAiB,WACb,+CACA,6CAAA,EAEP,SAAA,WAAA,CAAA,EAGDe,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAAS,IAAMN,EAAgB,aAAa,EAC5C,UAAWO,EACT,yDACAhB,IAAiB,cACb,+CACA,6CAAA,EAEP,SAAA,cAAA,CAAA,CAED,EACF,QAGCiB,GAAA,CAAY,KAAMd,EAAmB,aAAcC,EAClD,gBAACc,GAAA,CACC,SAAA,CAAAL,OAACM,GAAA,CACC,SAAA,CAAAJ,MAACK,IACE,SAAAtB,EAAc,CAAE,GAAI,8BAAA,CAAgC,EACvD,SACCuB,GAAA,CACE,SAAA,CAAAvB,EAAc,CAAE,GAAI,+BAAgC,EACpDD,EAAuB,GACtBgB,OAAC,OAAA,CAAK,UAAU,gDACb,SAAA,CAAAhB,EAAqB,IAAEC,EAAc,CAAE,GAAI,iBAAA,CAAmB,EAAE,YAAA,CAAY,CAAA,CAC/E,CAAA,CAAA,CAEJ,CAAA,EACF,SACCwB,GAAA,CACC,SAAA,CAAAP,EAAAA,IAACQ,GAAA,CAAkB,QAASX,EACzB,SAAAd,EAAc,CAAE,GAAI,6BAAA,CAA+B,EACtD,EACAiB,MAACS,IAAkB,QAASb,EACzB,WAAc,CAAE,GAAI,8BAAA,CAAgC,CAAA,CACvD,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,CAEJ,CC1HA,SAASc,GAAiB,CAAE,QAAAC,EAAS,SAAAC,EAAU,SAAAC,GAAmC,CAChF,KAAM,CAAE,cAAA9B,CAAA,EAAkBC,EAAA,EACpB,CAAC8B,EAAaC,CAAc,EAAI5B,EAAAA,SAAsB,IAAI,GAAK,EAE/D6B,EAAa,IAAM,UAAU,KAAK,IAAA,CAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,EAAG,CAAC,CAAC,GAEjFC,EAAY,IAAM,CACtBL,EAAS,CAAC,GAAGD,EAAS,CAAE,GAAIK,EAAA,EAAc,KAAM,GAAI,MAAO,GAAI,SAAU,EAAA,CAAO,CAAC,CACnF,EAEME,EAAgBC,GAAe,CACnCP,EAASD,EAAQ,OAAQS,GAAMA,EAAE,KAAOD,CAAE,CAAC,CAC7C,EAEME,EAAe,CAACF,EAAYG,EAAyBC,IAA4B,CACrFX,EAASD,EAAQ,IAAKS,GAAOA,EAAE,KAAOD,EAAK,CAAE,GAAGC,EAAG,CAACE,CAAK,EAAGC,CAAA,EAAUH,CAAE,CAAC,CAC3E,EAEMI,EAAgBL,GAAe,CACnCJ,EAAgBU,GAAS,CACvB,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAIP,CAAE,EACbO,EAAK,OAAOP,CAAE,EAEdO,EAAK,IAAIP,CAAE,EAENO,CACT,CAAC,CACH,EAEA,OACE5B,EAAAA,KAAC,MAAA,CAAI,UAAU,YACZ,SAAA,CAAAa,EAAQ,IAAKgB,GACZ7B,EAAAA,KAAC,MAAA,CAAoB,UAAU,0BAE7B,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,MAAOD,EAAO,KACd,SAAWE,GAAMR,EAAaM,EAAO,GAAI,OAAQE,EAAE,OAAO,KAAK,EAC/D,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,UAAU,SACV,SAAA8B,CAAA,CAAA,EAGFf,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,KAAMd,EAAY,IAAIa,EAAO,EAAE,EAAI,OAAS,WAC5C,MAAOA,EAAO,MACd,SAAWE,GAAMR,EAAaM,EAAO,GAAI,QAASE,EAAE,OAAO,KAAK,EAChE,YAAa9C,EAAc,CAAE,GAAI,mCAAoC,EACrE,UAAU,OACV,SAAA8B,CAAA,CAAA,EAEFb,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAQ,QACR,KAAK,OACL,UAAU,qCACV,QAAS,IAAMN,EAAaG,EAAO,EAAE,EACrC,SAAAd,EAEC,SAAAC,EAAY,IAAIa,EAAO,EAAE,EACxB3B,EAAAA,IAAC+B,GAAA,CAAO,UAAU,SAAA,CAAU,EAE5B/B,EAAAA,IAACgC,GAAA,CAAI,UAAU,SAAA,CAAU,CAAA,CAAA,CAE7B,EACF,EAEAlC,EAAAA,KAAC,QAAA,CAAM,UAAU,0EACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAAS2B,EAAO,SAChB,SAAWE,GAAMR,EAAaM,EAAO,GAAI,WAAYE,EAAE,OAAO,OAAO,EACrE,UAAU,UACV,SAAAhB,CAAA,CAAA,EAED9B,EAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,EACxD,EAEAiB,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAQ,QACR,KAAK,OACL,QAAS,IAAMZ,EAAaS,EAAO,EAAE,EACrC,SAAAd,EACA,UAAU,mBAEV,SAAAb,EAAAA,IAACiC,GAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,CAC9B,GAvDQN,EAAO,EAwDjB,CACD,EACD7B,EAAAA,KAACgC,EAAA,CACC,KAAK,SACL,QAAQ,UACR,KAAK,KACL,QAASb,EACT,SAAAJ,EACA,UAAU,SAEV,SAAA,CAAAb,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CAAA,CAAA,CACzD,EACF,CAEJ,CAIO,SAASoD,GAAgB,CAC9B,KAAAC,EACA,OAAAtG,EACA,KAAAuG,EACA,QAAAC,EACA,OAAAC,CACF,EAAyB,CACvB,KAAM,CAAE,cAAAxD,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EACdC,EAAcC,GAAiBC,EAAiB,EAChD,CAAE,MAAOiI,EAAW,QAASC,CAAA,EAAgBC,GAAA,EAG7C,CAAE,UAAAC,EAAW,UAAWC,CAAA,EAAqB3F,GAAA,EAG7C,CAAC4F,EAAeC,CAAgB,EAAI3D,EAAAA,SAA2B,OAAO,EAGtE,CAAC4D,EAAUC,CAAW,EAAI7D,WAA4B,CAC1D,KAAM,GACN,QAAS,GACT,KAAM,CAAA,EACN,IAAK,CAAA,EACL,IAAK,GACL,QAAS,CAAA,EACT,kBAAmB,GACnB,MAAO,UACP,QAAS,EAAA,CACV,EAEK,CAAC8D,EAAkBC,CAAmB,EAAI/D,EAAAA,SAAiB,EAAE,EAC7D,CAACgE,EAAQC,CAAS,EAAIjE,EAAAA,SAAqB,CAAA,CAAE,EAC7C,CAACkE,EAAWC,CAAY,EAAInE,EAAAA,SAAS,EAAE,EACvC,CAACoE,EAAUC,CAAW,EAAIrE,EAAAA,SAAS,EAAE,EACrC,CAACxD,EAAY8H,CAAa,EAAItE,EAAAA,SAAwB,UAAU,EAChE,CAACuE,EAAgBC,CAAiB,EAAIxE,EAAAA,SAAS,EAAK,EACpDyE,EAA0CjI,IAAe,cAAgB,SAAW,MAGpF,CAACkI,EAAWC,CAAY,EAAI3E,EAAAA,SAA0B,MAAM,EAC5D,CAAC4E,EAAWC,CAAY,EAAI7E,EAAAA,SAAS,EAAE,EAGvC8E,EAAsBC,cAAaC,GAClCA,GAEDC,GAAgBD,CAAU,EAAU,OAFhB,QAIvB,CAAA,CAAE,EAGCE,GAAkBH,EAAAA,YAAY,IAAM,CACxC,GAAI,CACF,IAAIxI,EAAS,KAAK,MAAMqI,CAAS,EAC7BO,EAAsB,GAI1B,GAAI5I,EAAO,YAAc,OAAOA,EAAO,YAAe,UAAY,CAAC,MAAM,QAAQA,EAAO,UAAU,EAAG,CACnG,MAAM6I,EAAc,OAAO,KAAK7I,EAAO,UAAU,EACjD,GAAI6I,EAAY,OAAS,EAAG,CAC1BD,EAAsBC,EAAY,CAAC,EACnC,MAAMC,EAAe9I,EAAO,WAAW4I,CAAmB,EACtDE,GAAgB,OAAOA,GAAiB,WAC1C9I,EAAS8I,EAEb,CACF,CAGA,GAAI9I,EAAO,IAAK,CAEdoH,EAAiB,MAAM,EAGvB,MAAMnC,EAAwB,CAAA,EAC1BjF,EAAO,SAAW,OAAOA,EAAO,SAAY,UAC9C,OAAO,QAAQA,EAAO,OAAO,EAAE,QAAQ,CAAC,CAAC+I,EAAMlD,EAAK,EAAGmD,KAAQ,CAC7D/D,EAAQ,KAAK,CACX,GAAI,UAAU,KAAK,IAAA,CAAK,IAAI+D,EAAG,GAC/B,KAAAD,EACA,MAAO,OAAOlD,EAAK,EACnB,SAAU,EAAA,CACX,CACH,CAAC,EAGHyB,EAAYvB,IAAS,CACnB,GAAGA,EACH,KAAM6C,GAAuB7C,EAAK,KAClC,IAAK/F,EAAO,KAAO,GACnB,QAAAiF,EACA,kBAAmBjF,EAAO,sBAAwBA,EAAO,mBAAqB,EAAA,EAC9E,CACJ,KAAO,CAELoH,EAAiB,OAAO,EAExB,MAAM6B,EAAO,MAAM,QAAQjJ,EAAO,IAAI,EAAIA,EAAO,KAAO,CAAA,EAClDkJ,EAAMlJ,EAAO,KAAO,OAAOA,EAAO,KAAQ,SAAWA,EAAO,IAAM,CAAA,EAExEsH,EAAYvB,KAAS,CACnB,GAAGA,GACH,KAAM6C,GAAuB7C,GAAK,KAClC,QAAS/F,EAAO,SAAW,GAC3B,KAAAiJ,EACA,IAAAC,CAAA,EACA,EAEFtB,EAAaqB,EAAK,KAAK,IAAI,CAAC,EAC5BnB,EACE,OAAO,QAAQoB,CAAG,EACf,IAAI,CAAC,CAACC,GAAGC,EAAC,IAAM,GAAGD,EAAC,IAAIC,EAAC,EAAE,EAC3B,KAAK;AAAA,CAAI,CAAA,CAEhB,CAGAhB,EAAa,MAAM,EACnBV,EAAU,CAAA,CAAE,EACZX,EACE1D,EAAc,CAAE,GAAI,+BAAgC,EACpDA,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAA,CAE5D,OAASgG,EAAO,CACd3B,EAAU,CACR,KAAMrE,EAAc,CAAE,GAAI,8BAAgC,CACxD,MAAOgG,aAAiB,MAAQA,EAAM,QAAU,cAAA,CACjD,CAAA,CACF,CACH,CACF,EAAG,CAAChB,EAAWhF,EAAe0D,CAAW,CAAC,EAG1CjD,EAAAA,UAAU,IAAM,CACd,GAAI1D,GAAUsG,IAAS,OAAQ,CAC7B,MAAM4C,EAAef,EAAoBnI,CAAM,EAC/CgH,EAAiBkC,CAAY,EAG7B,MAAMC,EAA4B,CAAA,EAC9Bb,GAAgBtI,CAAM,IAEpBA,EAAO,aACT,OAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAAC2I,GAAMlD,EAAK,EAAGmD,KAAQ,CACjEO,EAAY,KAAK,CACf,GAAI,eAAeP,EAAG,GACtB,KAAAD,GACA,MAAAlD,GACA,SAAU,EAAA,CACX,CACH,CAAC,EAECzF,EAAO,gBAETA,EAAO,eAAe,QAAQ,CAACoJ,GAAYR,KAAQ,CACjDO,EAAY,KAAK,CACf,GAAI,cAAcP,EAAG,GACrB,KAAMQ,GACN,MAAO,GACP,SAAU,EAAA,CACX,CACH,CAAC,GAKL,MAAMC,EAAeC,GAAiBtJ,CAAM,EAAIA,EAAO,QAAU,GAC3DuJ,EAAYD,GAAiBtJ,CAAM,EAAKA,EAAO,MAAQ,CAAA,EAAM,CAAA,EAC7DwJ,GAAWF,GAAiBtJ,CAAM,EAAKA,EAAO,KAAO,CAAA,EAAM,CAAA,EAG3DyJ,GAAUnB,GAAgBtI,CAAM,EAAIA,EAAO,IAAM,GACjD0J,GAAkBpB,GAAgBtI,CAAM,GAAKA,EAAO,mBAAqB,GAE/EkH,EAAY,CACV,KAAMlH,EAAO,KACb,QAASqJ,EACT,KAAME,EACN,IAAKC,GACL,IAAKC,GACL,QAASN,EACT,kBAAmBO,GACnB,MAAO1J,EAAO,MACd,QAASA,EAAO,OAAA,CACjB,EACDwH,EAAa+B,EAAU,KAAK,IAAI,CAAC,EACjC7B,EACE,OAAO,QAAQ8B,EAAQ,EACpB,IAAI,CAAC,CAACT,GAAGC,EAAC,IAAM,GAAGD,EAAC,IAAIC,EAAC,EAAE,EAC3B,KAAK;AAAA,CAAI,CAAA,CAEhB,MAEEhC,EAAiB,OAAO,EACxBE,EAAY,CACV,KAAM,GACN,QAAS,GACT,KAAM,CAAA,EACN,IAAK,CAAA,EACL,IAAK,GACL,QAAS,CAAA,EACT,kBAAmB,GACnB,MAAO,UACP,QAAS,EAAA,CACV,EACDM,EAAa,EAAE,EACfE,EAAY,EAAE,EAEhBN,EAAoB,EAAE,EACtBS,EAAkB,EAAK,EACvBP,EAAU,CAAA,CAAE,CACd,EAAG,CAACtH,EAAQsG,EAAMC,EAAM4B,CAAmB,CAAC,EAG5C,MAAMwB,GAAiBjK,GAAY,CACjC,WAAY,CAAC,CAAE,OAAAM,EAAQ,WAAAH,CAAAA,IACrBI,GAAgBD,EAAQ,CAAE,YAAazB,GAAe,OAAW,WAAAsB,EAAY,EAC/E,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DmM,GAAA,EACAnD,GAAA,MAAAA,GACF,CAAA,CACD,EAEKoD,GAAiBnK,GAAY,CACjC,WAAY,CAAC,CAAE,WAAAC,EAAY,OAAAC,EAAQ,WAAAC,CAAAA,IACjCC,GAAgBH,EAAYC,EAAQ,CAAE,YAAarB,GAAe,OAAW,WAAAsB,EAAY,EAC3F,UAAW,IAAM,CACfxB,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DmM,GAAA,EACAnD,GAAA,MAAAA,GACF,CAAA,CACD,EAGKmD,GAAc,IAAM,CACxBtC,EAAU,CAAA,CAAE,EACZd,EAAA,CACF,EAEMsD,GAAwBC,GAAuB,CACnD,MAAMC,EAAWnD,EAAU,KAAMxF,GAAMA,EAAE,OAAS0I,CAAU,EACxDC,IACF9C,EAAavB,IAAU,CACrB,GAAGA,EACH,QAASqE,EAAS,aAAa,QAC/B,KAAMA,EAAS,aAAa,MAAQ,CAAA,EACpC,IAAKA,EAAS,aAAa,KAAO,CAAA,CAAC,EACnC,EACFxC,GAAcwC,EAAS,aAAa,MAAQ,IAAI,KAAK,IAAI,CAAC,EAC1DtC,EACE,OAAO,QAAQsC,EAAS,aAAa,KAAO,CAAA,CAAE,EAC3C,IAAI,CAAC,CAACjB,EAAGC,CAAC,IAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAC3B,KAAK;AAAA,CAAI,CAAA,EAEd5B,EAAoB2C,CAAU,EAElC,EAEME,GAAoB,CACxBzE,EACAC,IACG,CACHyB,EAAavB,IAAU,CAAE,GAAGA,EAAM,CAACH,CAAK,EAAGC,CAAA,EAAQ,EAE/C4B,EAAO7B,CAAyB,GAClC8B,EAAW3B,IAAU,CAAE,GAAGA,EAAM,CAACH,CAAK,EAAG,MAAA,EAAY,CAEzD,EAEM0E,GAAoBzE,GAAkB,CAC1C+B,EAAa/B,CAAK,EAClB,MAAM0E,EAAY1E,EACf,MAAM,GAAG,EACT,IAAK2E,GAAMA,EAAE,KAAA,CAAM,EACnB,OAAQA,GAAMA,EAAE,OAAS,CAAC,EAC7BlD,EAAavB,IAAU,CAAE,GAAGA,EAAM,KAAMwE,GAAY,EAChD9C,EAAO,MACTC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,KAAM,QAAY,CAEtD,EAEM0E,EAAmB5E,GAAkB,CACzCiC,EAAYjC,CAAK,EACjB,MAAM6E,EAAiC,CAAA,EACjCC,EAAQ9E,EAAM,MAAM;AAAA,CAAI,EAC9B,UAAW+E,KAAQD,EAAO,CACxB,MAAME,GAAUD,EAAK,KAAA,EACrB,GAAIC,IAAWA,GAAQ,SAAS,GAAG,EAAG,CACpC,KAAM,CAACC,GAAK,GAAGC,EAAQ,EAAIF,GAAQ,MAAM,GAAG,EACtCG,GAAMD,GAAS,KAAK,GAAG,EACzBD,KACFJ,EAAOI,GAAI,KAAA,CAAM,EAAIE,GAAI,KAAA,EAE7B,CACF,CACA1D,EAAavB,IAAU,CAAE,GAAGA,EAAM,IAAK2E,GAAS,EAC5CjD,EAAO,KACTC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,IAAK,QAAY,CAErD,EAEMkF,GAAuBhG,GAA0B,CACrDqC,EAAavB,IAAU,CAAE,GAAGA,EAAM,QAAAd,GAAU,EACxCwC,EAAO,SACTC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,QAAS,QAAY,CAEzD,EAEMmF,GAA6BnI,GAA2B,CAC5DqE,EAAiBrE,CAAI,EAErB2E,EAAW3B,IAAU,CACnB,GAAGA,EACH,QAAS,OACT,IAAK,MAAA,EACL,CACJ,EAEMoF,GAAe,IAAe,CAClC,MAAMC,EAAwB,CAAA,EAQ9B,GALK/D,EAAS,KAAK,SACjB+D,EAAU,KAAO/H,EAAc,CAAE,GAAI,qCAAsC,GAIzE8D,IAAkB,QAEfE,EAAS,QAAQ,SACpB+D,EAAU,QAAU/H,EAAc,CAAE,GAAI,wCAAyC,OAE9E,CAEAgE,EAAS,IAAI,SAChB+D,EAAU,IAAM/H,EAAc,CAAE,GAAI,oCAAqC,GAG3E,GAAI,CACF,IAAI,IAAIgE,EAAS,GAAG,CACtB,MAAQ,CACN+D,EAAU,IAAM/H,EAAc,CAAE,GAAI,mCAAoC,CAC1E,CACF,CAEA,OAAAqE,EAAU0D,CAAS,EACZ,OAAO,KAAKA,CAAS,EAAE,SAAW,CAC3C,EAEMC,GAAkB,MAAOtC,GAAmC,CAChE,GAAI,CACF,MAAMuC,EAAO,MAAMtM,GAAgBL,GAAe,MAAS,EAG3D,MAFmB,CAAC,GAAG2M,EAAK,QAAS,GAAGA,EAAK,MAAM,EAEjC,KACf7L,GAAMA,EAAE,OAASsJ,IAASrC,IAAS,OAASjH,EAAE,QAASW,GAAA,YAAAA,EAAQ,MAAO,GAAA,CAE3E,MAAQ,CACN,MAAO,EACT,CACF,EAEMmL,GAAe,SAAY,CAC/B,GAAI,CAACJ,KACH,OAIF,GAAI,MAAME,GAAgBhE,EAAS,IAAI,EAAG,CACxCK,EAAU,CAAE,KAAMrE,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAG,EAC7E,MACF,CAGA,IAAIyF,EAEJ,GAAI3B,IAAkB,QACpB2B,EAAe,CACb,KAAMzB,EAAS,KACf,UAAW,QACX,QAASA,EAAS,QAClB,KAAMA,EAAS,KAAK,OAAS,EAAIA,EAAS,KAAO,OACjD,IAAK,OAAO,KAAKA,EAAS,GAAG,EAAE,OAAS,EAAIA,EAAS,IAAM,OAC3D,MAAOA,EAAS,MAChB,QAASA,EAAS,OAAA,MAEf,CAEL,MAAMkC,EAAsC,CAAA,EACtCiC,EAA2B,CAAA,EAEjCnE,EAAS,QAAQ,QAAS3B,GAAM,CAC1BA,EAAE,KAAK,SACLA,EAAE,SAEJ8F,EAAe,KAAK9F,EAAE,KAAK,KAAA,CAAM,EAEjC6D,EAAY7D,EAAE,KAAK,KAAA,CAAM,EAAIA,EAAE,MAAM,KAAA,EAG3C,CAAC,EAEDoD,EAAe,CACb,KAAMzB,EAAS,KACf,UAAW,OACX,IAAKA,EAAS,IACd,QAAS,OAAO,KAAKkC,CAAW,EAAE,OAAS,EAAIA,EAAc,OAC7D,YAAa,OAAO,KAAKA,CAAW,EAAE,OAAS,EAAIA,EAAc,OACjE,eAAgBiC,EAAe,OAAS,EAAIA,EAAiB,OAC7D,kBAAmBnE,EAAS,kBAAkB,KAAA,GAAU,OACxD,MAAOA,EAAS,MAChB,QAASA,EAAS,OAAA,CAEtB,CAGA,GAAIW,GAAkBb,IAAkB,QACtC,GAAI,CACF,MAAMsE,GAAgB,CACpB,KAAMpE,EAAS,KACf,SAAU,SACV,aAAc,CACZ,QAASA,EAAS,QAClB,KAAMA,EAAS,KAAK,OAAS,EAAIA,EAAS,KAAO,OACjD,IAAK,OAAO,KAAKA,EAAS,GAAG,EAAE,OAAS,EAAIA,EAAS,IAAM,MAAA,CAC7D,CACD,CACH,OAASqE,EAAK,CACZ5E,EAAUzD,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAAGqI,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAEvH,CAGEhF,IAAS,MACXqD,GAAe,OAAO,CACpB,OAAQjB,EACR,WAAYzB,EAAS,QAAU,UAAYa,EAAoB,MAAA,CAChE,EAED+B,GAAe,OAAO,CACpB,WAAY7J,EAAQ,KACpB,OAAQ0I,EACR,WAAYzB,EAAS,QAAU,UAAYa,EAAoB,MAAA,CAChE,CAEL,EAEMyD,GAAY5B,GAAe,WAAaE,GAAe,UAE7D,OACE3F,EAAAA,IAACsH,IAAO,KAAAjF,EAAY,aAAcqD,GAChC,SAAA5F,EAAAA,KAACyH,GAAA,CAAc,UAAU,yCACvB,SAAA,CAAAvH,EAAAA,IAACwH,GAAA,CACC,eAACC,GAAA,CACE,SAAArF,IAAS,MACNrD,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC3CA,EAAc,CAAE,GAAI,wBAA0B,CAAE,KAAMjD,GAAA,YAAAA,EAAQ,KAAM,CAAA,CAC1E,CAAA,CACF,EAGCsG,IAAS,OACRtC,OAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAS+B,IAAc,OAAS,UAAY,UAC5C,KAAK,KACL,QAAS,IAAMC,EAAa,MAAM,EAClC,UAAU,SAET,SAAA/E,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,EAE/CiB,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAAS+B,IAAc,OAAS,UAAY,UAC5C,KAAK,KACL,QAAS,IAAMC,EAAa,MAAM,EAClC,UAAU,SAET,SAAA/E,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,CAC/C,EACF,EAGFiB,EAAAA,IAAC,OAAI,UAAU,YAEZ,aAAc,OACbF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAO+D,EACP,SAAWlC,GAAMmC,EAAanC,EAAE,OAAO,KAAK,EAC5C,YAAa9C,EAAc,CAAE,GAAI,8BAA+B,EAChE,UAAWkB,EACT,kTACAkD,EAAO,MAAQ,mDAAA,CACjB,CAAA,EAEDA,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,KAAK,EAEvDA,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAC/C,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,yBAAA,CAA2B,EAClD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,2BAA2B,SAAA,SAAM,EAC9CA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BAChC,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOiB,EACAA,EAAAA,IAAC,IAAA,CAAE,UAAU,gCAAgC,SAAA,QAAK,EAClDA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BAChC,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAMiB,CAAA,CAAA,CACF,CAAA,EACF,EAEAA,EAAAA,IAAC8B,EAAA,CACC,KAAK,SACL,QAASuC,GACT,SAAU,CAACN,EAAU,KAAA,EACrB,UAAU,SAET,SAAAhF,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,CAChD,CAAA,CACF,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CAEG,SAAA,CAAA8C,IAAkB,SACrB/C,OAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,0BAAA,CAA4B,EACnD,SACC2I,GAAA,CAAO,MAAOzE,EAAkB,cAAe2C,GAAsB,SAAUhD,EAC9E,SAAA,CAAA5C,EAAAA,IAAC2H,GAAA,CAAc,UAAU,SACvB,SAAA3H,EAAAA,IAAC4H,GAAA,CACC,YACI7I,EADS6D,EACK,CAAE,GAAI,uBAAA,EACN,CAAE,GAAI,qCAAA,CADyB,CACc,CAAA,EAGnE,EACA5C,EAAAA,IAAC6H,GAAA,CACE,SAAAlF,EAAU,SAAW,EACpB3C,MAAC8H,GAAA,CAAW,MAAM,YAAY,SAAQ,GACnC,SAAA/I,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CACpD,EAEA4D,EAAU,IAAKmD,GACb9F,EAAAA,IAAC8H,GAAA,CAA+B,MAAOhC,EAAS,KAC9C,SAAAhG,EAAAA,KAAC,MAAA,CAAI,UAAU,gBACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,SAAA8F,EAAS,KAAK,EAC7C9F,EAAAA,IAAC,OAAA,CAAK,UAAU,gCACb,SAAA8F,EAAS,aAAe/G,EAAc,CAAE,GAAI,qCAAA,CAAuC,CAAA,CACtF,CAAA,CAAA,CACF,CAAA,EANe+G,EAAS,IAO1B,CACD,CAAA,CAEL,CAAA,CAAA,CACF,CAAA,EACF,EAIFhG,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,uBAAwB,EAC7CiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,KAChB,SAAWlB,GAAMkE,GAAkB,OAAQlE,EAAE,OAAO,KAAK,EACzD,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,MAAO,CAAC,CAACoE,EAAO,KAChB,SAAUf,IAAS,MAAA,CAAA,EAEpBe,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,+BAAA,CAAiC,EACxD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,gBACL,MAAM,QACN,QAAS6C,IAAkB,QAC3B,SAAU,IAAM+D,GAA0B,OAAO,EACjD,UAAU,UACV,SAAUxE,IAAS,MAAA,CAAA,EAErBpC,EAAAA,IAAC+H,GAAA,CAAS,UAAU,+BAAA,CAAgC,EACpD/H,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CACzD,CAAA,EACF,EACAF,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,gBACL,MAAM,OACN,QAAS6C,IAAkB,OAC3B,SAAU,IAAM+D,GAA0B,MAAM,EAChD,UAAU,UACV,SAAUxE,IAAS,MAAA,CAAA,EAErBpC,EAAAA,IAACgI,GAAA,CAAM,UAAU,+BAAA,CAAgC,EACjDhI,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,CAAA,CACF,CAAA,EACF,EACAA,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,EACF,EAGC6C,IAAkB,SACjB/C,EAAAA,KAAAC,EAAAA,SAAA,CAEE,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,0BAA2B,EAChDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,QAChB,SAAWlB,GAAMkE,GAAkB,UAAWlE,EAAE,OAAO,KAAK,EAC5D,YAAa9C,EAAc,CAAE,GAAI,qCAAsC,EACvE,MAAO,CAAC,CAACoE,EAAO,OAAA,CAAA,EAEjBA,EAAO,SACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,EAE5D,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAC/C,EACAiB,EAAAA,IAAC4B,EAAA,CACC,MAAOyB,EACP,SAAWxB,GAAMmE,GAAiBnE,EAAE,OAAO,KAAK,EAChD,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,MAAO,CAAC,CAACoE,EAAO,IAAA,CAAA,EAElBnD,EAAAA,IAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,EACnD,EACC+C,EAAS,KAAK,OAAS,SACrB,MAAA,CAAI,UAAU,4BACZ,SAAAA,EAAS,KAAK,IAAI,CAACkF,EAAKvD,IACvB1E,EAAAA,IAACkI,EAAA,CAAgB,QAAQ,YAAY,UAAU,oBAC5C,SAAAD,CAAA,EADSvD,CAEZ,CACD,CAAA,CACH,EAEDvB,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC9C,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAOuD,EACP,SAAW1B,GAAMsE,EAAgBtE,EAAE,OAAO,KAAK,EAC/C,YAAa9C,EAAc,CAAE,GAAI,iCAAkC,EACnE,UAAWkB,EACT,wSACAkD,EAAO,KAAO,mDAAA,CAChB,CAAA,EAEFnD,EAAAA,IAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,yBAAA,CAA2B,EAClD,EACC,OAAO,KAAK+C,EAAS,GAAG,EAAE,OAAS,GAClC/C,EAAAA,IAAC,MAAA,CAAI,UAAU,iBACZ,SAAA,OAAO,QAAQ+C,EAAS,GAAG,EAAE,IAAI,CAAC,CAACyD,EAAKjF,CAAK,IAC5CzB,EAAAA,KAAC,MAAA,CAAc,UAAU,kCACvB,SAAA,CAAAE,MAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,YAChC,SAAA1B,EACH,EACAxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,4DACb,SAAAuB,CAAA,CACH,CAAA,GAPQiF,CAQV,CACD,EACH,EAEDrD,EAAO,KACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,GAAA,CAAI,CAAA,CAAA,CAExD,CAAA,EACF,EAID6C,IAAkB,QACjB/C,EAAAA,KAAAC,EAAAA,SAAA,CAEE,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,2BAA4B,EACjDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,IAChB,SAAWlB,GAAMkE,GAAkB,MAAOlE,EAAE,OAAO,KAAK,EACxD,YAAa9C,EAAc,CAAE,GAAI,sCAAuC,EACxE,MAAO,CAAC,CAACoE,EAAO,GAAA,CAAA,EAEjBA,EAAO,KACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAI,EAEtDA,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,8BAAA,CAAgC,CAAA,CACvD,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAC3D,EACAiB,EAAAA,IAAC4B,EAAA,CACC,MAAOmB,EAAS,kBAChB,SAAWlB,GAAMkE,GAAkB,oBAAqBlE,EAAE,OAAO,KAAK,EACtE,YAAa9C,EAAc,CAAE,GAAI,8CAA+C,CAAA,CAAA,EAElFiB,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,sCAAA,CAAwC,CAAA,CAC/D,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,8BAAA,CAAgC,EACvD,EACAiB,EAAAA,IAACU,GAAA,CACC,QAASqC,EAAS,QAClB,SAAU4D,GACV,SAAUU,EAAA,CAAA,EAEZrH,EAAAA,IAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,kCAAA,CAAoC,EAC3D,EACCmD,EAAO,SACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,CAAA,CAE5D,CAAA,EACF,EAIFF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,QACL,MAAM,UACN,QAAS+C,EAAS,QAAU,UAC5B,SAAWlB,GAAMkE,GAAkB,QAASlE,EAAE,OAAO,KAA6B,EAClF,UAAU,UACV,SAAUO,IAAS,MAAA,CAAA,EAErBpC,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAC5C,CAAA,EACF,EACAF,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,QACL,MAAM,SACN,QAAS+C,EAAS,QAAU,SAC5B,SAAWlB,GAAMkE,GAAkB,QAASlE,EAAE,OAAO,KAA6B,EAClF,UAAU,UACV,SAAUO,IAAS,MAAA,CAAA,EAErBpC,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAC3C,CAAA,CAAA,CACF,CAAA,EACF,EAGC+C,EAAS,QAAU,WAClBjD,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,gCACb,SAAA,CAAAf,EAAc,CAAE,GAAI,wBAAyB,EAAE,GAAA,EAClD,EACAiB,EAAAA,IAACtB,GAAA,CACC,YAAa/C,EACb,aAAc8H,EACd,YAAa,EAAA,CAAA,CACf,CAAA,CACF,CAAA,EAEJ,EAGA3D,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAG,UACH,QAAS+C,EAAS,QAClB,SAAWlB,GAAMkE,GAAkB,UAAWlE,EAAE,OAAO,OAAO,EAC9D,UAAU,SAAA,CAAA,EAEZ7B,EAAAA,IAAC,QAAA,CAAM,QAAQ,UAAU,UAAU,qDAChC,SAAAjB,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EAGC8D,IAAkB,SACjB/C,OAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAG,mBACH,QAAS0D,EACT,SAAW7B,GAAM8B,EAAkB9B,EAAE,OAAO,OAAO,EACnD,UAAU,SAAA,CAAA,EAEZ7B,EAAAA,IAAC,QAAA,CAAM,QAAQ,mBAAmB,UAAU,qDACzC,SAAAjB,EAAc,CAAE,GAAI,sCAAA,CAAwC,CAAA,CAC/D,CAAA,CAAA,CACF,CAAA,CAAA,CAEF,CAAA,CAEF,SAECoJ,GAAA,CACC,SAAA,CAAAnI,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,QAAS4D,GACT,SAAU2B,GAET,SAAAtI,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,EAEpDiB,EAAAA,IAAC8B,EAAA,CACC,QAASmF,GACT,SAAUI,GAET,SACGtI,EADHsI,GACiB,CAAE,GAAI,2BAAA,EACN,CAAE,GAAI,yBAAA,CAD6B,CACF,CAAA,CACrD,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CC9gCA,SAASe,GAAgB7G,EAAuB,CAC9C,MAAI,CAACA,GAASA,EAAM,QAAU,EAAU,OACjCA,EAAM,UAAU,EAAG,CAAC,EAAI,MACjC,CAEO,SAAS8G,GAAqB,CACnC,OAAAvM,EACA,QAAA5B,EACA,WAAAoO,EACA,eAAAC,EACA,WAAAC,EAAa,GACb,SAAAC,EACA,SAAAC,EACA,WAAAC,EAAa,GACb,WAAAC,EAAa,EACf,EAA8B,CAC5B,KAAM,CAAE,cAAA7J,CAAA,EAAkBC,EAAA,EACpB,CAAC6J,EAAqBC,CAAsB,EAAI3J,EAAAA,SAAS,EAAK,EAC9D,CAAC4J,EAAkBC,CAAmB,EAAI7J,EAAAA,SAAkC,CAAA,CAAE,EAE9E8J,EAAS7E,GAAgBtI,CAAM,EAC/BoN,EAAU9D,GAAiBtJ,CAAM,EAGjCqN,EAAmB,IAAM,OAC7B,OAAIF,EACKnN,EAAO,IAET,GAAGA,EAAO,SAAW,EAAE,MAAIlB,EAAAkB,EAAO,OAAP,YAAAlB,EAAa,KAAK,OAAQ,EAAE,GAAG,KAAA,CACnE,EAGMwO,EAAiB,IAAkE,CACvF,GAAI,CAACH,EAAQ,MAAO,CAAA,EAEpB,MAAMtI,EAAsE,CAAA,EAG5E,OAAI7E,EAAO,aACT,OAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CAC5DZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAICzF,EAAO,mBACT6E,EAAQ,KAAK,CACX,KAAM,gBACN,MAAO,WAAW7E,EAAO,iBAAiB,GAC1C,SAAU,EAAA,CACX,EAICA,EAAO,SACT,OAAO,QAAQA,EAAO,OAAO,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CACxDZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAGIZ,CACT,EAGM0I,EAAqBnE,GAAuB,CAChD8D,EAAoBvH,IAAS,CAC3B,GAAGA,EACH,CAACyD,CAAU,EAAG,CAACzD,EAAKyD,CAAU,CAAA,EAC9B,CACJ,EAGMoE,EAAe,SAAY,CAC3BZ,GACF,MAAMA,EAAS5M,EAAO,KAAM,CAAC5B,CAAO,CAExC,EAGMgH,EAAe,SAAY,CAC3BuH,IACF,MAAMA,EAAS3M,EAAO,IAAI,EAC1BgN,EAAuB,EAAK,EAEhC,EAGMS,EAAmB1H,GAAwB,CAC/CA,EAAE,gBAAA,CACJ,EAEA,OACE/B,EAAAA,KAAC0J,GAAK,UAAWvJ,EAAG,kBAAmB,CAAC/F,GAAW,YAAY,EAE7D,SAAA,CAAA8F,EAAAA,IAAC,MAAA,CACC,UAAU,yDACV,QAASuI,EAET,SAAAzI,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,iBACA/F,EAAU,gBAAkB,UAAA,EAE5B,SAAA8F,EAAAA,IAACyJ,GAAA,CAAO,UAAWxJ,EACjB,UACA/F,EAAU,eAAiB,uBAAA,EAC1B,CAAA,CACL,SACC,MAAA,CACC,SAAA,CAAA4F,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAlE,EAAO,KACV,EAECmN,GACCnJ,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,wCACjC,SAAA,CAAAlI,EAAAA,IAAC0J,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B3K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEDyJ,EACC1I,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,EAAAA,KAACoI,EAAA,CAAM,QAAQ,YAAY,UAAU,kCACnC,SAAA,CAAAlI,EAAAA,IAAC2J,GAAA,CAAM,UAAU,SAAA,CAAU,EAC1B5K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EACC7E,GACC4F,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,yBACjC,SAAA,CAAAlI,EAAAA,IAAC4J,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/B7K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CAEE,SAAA,CAAAD,EAAAA,KAACoI,EAAA,CAAM,QAAQ,YAAY,UAAU,kCACnC,SAAA,CAAAlI,EAAAA,IAAC6J,GAAA,CAAK,UAAU,SAAA,CAAU,EACzB9K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EACC7E,GACC4F,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,yBACjC,SAAA,CAAAlI,EAAAA,IAAC4J,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/B7K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,CAAA,EAEJ,EACAiB,MAAC,KAAE,UAAU,iEAAiE,MAAOmJ,EAAA,EAClF,YAAiB,CACpB,CAAA,CAAA,CACF,CAAA,EACF,EACArJ,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACZ,SAAA,CAAA0I,EACC1I,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAC,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACd0H,EAAgB1H,CAAC,EACjByH,EAAA,CACF,EACA,SAAUV,EAET,SAAA1O,QACE0P,GAAA,CAAM,UAAU,yBAAyB,EAE1C5J,EAAAA,IAAC8J,GAAA,CAAS,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAKxDhK,EAAAA,KAACI,GAAA,CAAY,KAAM2I,EAAqB,aAAcC,EACpD,SAAA,CAAA9I,EAAAA,IAAC+J,GAAA,CAAmB,QAAO,GACzB,SAAA/J,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAASyH,EACT,SAAUZ,EAEV,SAAA3I,EAAAA,IAACiC,GAAA,CAAO,UAAU,0BAAA,CAA2B,CAAA,CAAA,EAEjD,SACC9B,GAAA,CACC,SAAA,CAAAL,OAACM,GAAA,CACC,SAAA,CAAAJ,EAAAA,IAACK,GAAA,CACE,SAAAtB,EAAc,CAAE,GAAI,+BAAA,EAAmC,CAAE,KAAMjD,EAAO,IAAA,CAAM,CAAA,CAC/E,EACAkE,EAAAA,IAACM,GAAA,CACE,SAAAvB,EAAc,CAAE,GAAI,qCAAA,EAAyC,CAAE,KAAMjD,EAAO,IAAA,CAAM,CAAA,CACrF,CAAA,EACF,SACCyE,GAAA,CACC,SAAA,CAAAP,EAAAA,IAACQ,GAAA,CAAkB,SAAUmI,EAC1B,SAAA5J,EAAc,CAAE,GAAI,gCAAA,CAAkC,EACzD,EACAiB,EAAAA,IAACS,GAAA,CACC,QAASS,EACT,SAAUyH,EACV,UAAU,qEAET,WACC7I,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,oBAAoB,SAAA,IAAC,EACpCjB,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAA,CAAA,CAC3D,EAEAA,EAAc,CAAE,GAAI,kCAAmC,CAAA,CAAA,CAE3D,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,EAEAiB,EAAAA,IAAAD,WAAA,CAEE,SAAAC,MAAC,MAAA,CAAI,UAAWC,EACd,sDACA/F,EAAU,8BAAgC,gCAAA,EAEzC,SAAAA,EAAU8F,EAAAA,IAAC4J,GAAA,CAAM,UAAU,SAAA,CAAU,EAAK5J,EAAAA,IAAC8J,GAAA,CAAS,UAAU,SAAA,CAAU,CAAA,CAC3E,EACF,EAEDxB,QACE0B,GAAA,CAAU,UAAU,gCAAgC,EAErDhK,MAACiK,GAAA,CAAY,UAAU,+BAAA,CAAgC,CAAA,CAAA,CAE3D,CAAA,CAAA,CACF,CAAA,CAAA,EAID3B,GACCxI,EAAAA,KAAC,MAAA,CAAI,UAAU,mDAEZ,SAAA,CAAAmJ,GACCnJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,cAAA,CAAgB,EAAE,EACzFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,0EACb,WAAO,GAAA,CACV,CAAA,EACF,EAGCoJ,EAAA,EAAiB,OAAS,UACxB,MAAA,CACC,SAAA,CAAApJ,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,kBAAA,CAAoB,EAAE,EAC7FiB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAAoJ,EAAA,EAAiB,IAAKzH,GACrB7B,EAAAA,KAAC,MAAA,CAAsB,UAAU,kCAC/B,SAAA,CAAAE,MAACkI,GAAM,QAAQ,YAAY,UAAU,YAAa,WAAO,KAAK,EAC9DlI,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAA+I,EAAiBpH,EAAO,IAAI,EAAIA,EAAO,MAAQyG,GAAgBzG,EAAO,KAAK,EAC9E,EACA3B,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS,IAAMuH,EAAkB1H,EAAO,IAAI,EAC5C,MAAOoH,EAAiBpH,EAAO,IAAI,EAC/B5C,EAAc,CAAE,GAAI,oBAAA,CAAsB,EAC1CA,EAAc,CAAE,GAAI,qBAAsB,EAE7C,SAAAgK,EAAiBpH,EAAO,IAAI,EAC3B3B,EAAAA,IAAC+B,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAElD/B,EAAAA,IAACgC,GAAA,CAAI,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAGlDL,EAAO,UACN3B,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAChC,SAAAnJ,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAC1C,CAAA,GAxBM4C,EAAO,IA0BjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAIDuH,GACCpJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,aAAA,CAAe,EAAE,EACxFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,gEACb,WAAO,OAAA,CACV,CAAA,EACF,EAGClE,EAAO,MAAQA,EAAO,KAAK,OAAS,UAClC,MAAA,CACC,SAAA,CAAAkE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,UAAA,CAAY,EAAE,QACpF,MAAA,CAAI,UAAU,uBACZ,SAAAjD,EAAO,KAAK,IAAI,CAACmM,EAAKvD,IACrB1E,EAAAA,IAACkI,EAAA,CAAgB,QAAQ,UAAU,UAAU,oBAC1C,SAAAD,CAAA,EADSvD,CAEZ,CACD,CAAA,CACH,CAAA,EACF,EAID5I,EAAO,KAAO,OAAO,KAAKA,EAAO,GAAG,EAAE,OAAS,GAC9CgE,EAAAA,KAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,SAAA,CAAW,EAAE,QACnF,MAAA,CAAI,UAAU,YACZ,SAAA,OAAO,QAAQjD,EAAO,GAAG,EAAE,IAAI,CAAC,CAAC0K,EAAKjF,CAAK,IAC1CzB,EAAAA,KAAC,MAAA,CAAc,UAAU,kCACvB,SAAA,CAAAE,MAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,YAAa,SAAA1B,EAAI,EACtDxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAAuB,CAAA,CACH,CAAA,CAAA,EALQiF,CAMV,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAIFxG,MAAC,OAAI,UAAWC,EACd,sDACAuI,EACI,4BACA,2BAAA,EAEH,WACC1I,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC2J,GAAA,CAAM,UAAU,mBAAA,CAAoB,EACrC3J,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,CAAA,CACF,EAEAF,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC6J,GAAA,CAAK,UAAU,+BAAA,CAAgC,EAChD7J,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,CAAA,CACF,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,EAEJ,CAEJ,CCtUO,MAAMkK,GAA2B,CACtC,CAAE,KAAM,aAAc,KAAM,qBAAsB,KAAM,EAAA,EACxD,CAAE,KAAM,YAAa,KAAM,uBAAwB,KAAM,EAAA,EACzD,CAAE,KAAM,YAAa,KAAM,mBAAoB,KAAM,EAAA,EACrD,CAAE,KAAM,kBAAmB,KAAM,2BAA4B,KAAM,EAAA,EACnE,CAAE,KAAM,cAAe,KAAM,yBAA0B,KAAM,EAAA,EAC7D,CAAE,KAAM,eAAgB,KAAM,+BAAgC,KAAM,EAAA,EACpE,CAAE,KAAM,WAAY,KAAM,yBAA0B,KAAM,EAAA,CAC5D,EAIO,SAASC,GAAgB,CAC9B,YAAAC,EACA,aAAAC,EACA,YAAAC,EACA,YAAAC,EACA,cAAAC,EACA,aAAAC,EACA,eAAAC,EACA,UAAAC,EACA,OAAAC,EAAS,SACT,gBAAAC,EAAkB,CAAA,EAClB,iBAAAC,CACF,EAAyB,CACvB,KAAM,CAAE,cAAA/L,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EACd,CAAE,QAAS2Q,EAAe,MAAOC,CAAA,EAAgBtI,GAAA,EACjDuI,EAAqB3Q,GAAiBC,EAAiB,EAGvD,CAAC2Q,EAAkBC,CAAmB,EAAIhM,EAAAA,SAASmL,GAAe,EAAE,EACpE,CAACc,EAAkBC,CAAmB,EAAIlM,EAAAA,SAASoL,GAAe,EAAE,EACpE,CAACe,EAAoBC,CAAqB,EAAIpM,EAAAA,SAASqL,GAAiB,EAAK,EAE7E,CAAClC,EAAYkD,CAAa,EAAIrM,EAAAA,SAAS,EAAK,EAC5C,CAACsM,EAAcC,CAAe,EAAIvM,EAAAA,SAA+B,QAAQ,EACzE,CAACwM,EAAkBC,CAAmB,EAAIzM,EAAAA,SAAS,EAAK,EACxD,CAAC0M,EAAkBC,CAAmB,EAAI3M,EAAAA,SAA+C,IAAI,EAE7F4M,EAAUnB,IAAW,QAGrBoB,EAAkBxQ,GAAY,CAClC,WAAYuQ,EACR,IAAME,GAAA,EACLC,GACCC,GAAcD,EAAO,MAAOA,EAAO,WAAW,EACpD,UAAW,IAAM,CACXH,GACF5R,EAAY,kBAAkB,CAAE,SAAU,CAAC,iBAAiB,EAAG,EAC/DA,EAAY,kBAAkB,CAAE,SAAU,CAAC,mBAAmB,EAAG,IAEjEA,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,GAE9DwQ,EAAA,CACF,CAAA,CACD,EAEKyB,EAAoB5Q,GAAY,CACpC,WAAYuQ,EAAUM,GAA2BC,GACjD,UAAW,IAAM,CACXP,GACF5R,EAAY,kBAAkB,CAAE,SAAU,CAAC,iBAAiB,EAAG,EAC/DA,EAAY,kBAAkB,CAAE,SAAU,CAAC,mBAAmB,EAAG,IAEjEA,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,GAE9DwQ,EAAA,CACF,EACA,QAAU5F,GAAU,CAClB,QAAQ,MAAM,+BAAgCA,CAAK,CACrD,CAAA,CACD,EAEKwH,EAAuB/Q,GAAY,CACvC,WAAYuQ,EAAUS,GAA0BC,GAChD,UAAW,IAAM,CACXV,GACF5R,EAAY,kBAAkB,CAAE,SAAU,CAAC,iBAAiB,EAAG,EAC/DA,EAAY,kBAAkB,CAAE,SAAU,CAAC,mBAAmB,EAAG,IAEjEA,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DY,EAAY,kBAAkB,CAAE,SAAU,CAAC,cAAc,EAAG,GAE9D4Q,EAAchM,EAAc,CAAE,GAAI,8BAAA,CAAgC,CAAC,CACrE,EACA,QAAUgG,GAAU,CAClB,QAAQ,MAAM,+BAAgCA,CAAK,EACnDiG,EACEjM,EAAc,CAAE,GAAI,6BAA8B,EAClDgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CAAA,CACD,EAGK2H,GAAmB,CAACC,EAAkBzS,KAAqB,CAC/DuQ,EAAakC,EAAUzS,EAAO,CAChC,EAEM0S,GAAkB,IAAM,CAC5B,MAAMC,EAAe3C,GAAc,IAAK/M,IAAMA,GAAE,IAAI,EACpDuN,EAAe,CAAE,aAAcmC,EAAc,CAC/C,EAEMC,GAAmB,IAAM,CAC7BpC,EAAe,CAAE,aAAc,CAAA,EAAI,CACrC,EAEMqC,GAAmB,IAAM,CAC7BR,EAAqB,OAAO,CAC1B,aAAAlC,EACA,YAAaa,GAAoB,OACjC,YAAaE,GAAoB,OACjC,cAAeE,CAAA,CAChB,CACH,EAEM0B,GAAqB,IAAM,CAC3BjB,EACDC,EAAwB,OAAO,MAAS,EAExCA,EAAwB,OAAO,CAC9B,MAAOP,EACP,YAAaA,IAAiB,UAAYR,EAAqB,MAAA,CAChE,CAEL,EAEMgC,GAAuB,IAAM,CAC7B,QAAQlO,EAAc,CAAE,GAAI,kCAAA,CAAoC,CAAC,GACnEqN,EAAkB,OAAA,CAEtB,EAEM/E,GAAY2E,EAAgB,WAAaI,EAAkB,WAAaG,EAAqB,UAEnG,OACEzM,OAAC0J,GAAK,UAAWvJ,EACf,2BACAmK,EAAc,iCAAmC,eAAA,EAGjD,SAAA,CAAApK,EAAAA,IAAC,MAAA,CACC,UAAU,yDACV,QAAS,IAAMwL,EAAc,CAAClD,CAAU,EAExC,SAAAxI,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,iBACAmK,EAAc,gBAAkB,UAAA,EAEhC,SAAApK,EAAAA,IAACkN,GAAA,CAAS,UAAWjN,EACnB,UACAmK,EAAc,eAAiB,uBAAA,EAC9B,CAAA,CACL,SACC,MAAA,CACC,SAAA,CAAAtK,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAjB,EAAc,CAAE,GAAI,eAAA,CAAiB,EACxC,EACCqL,GAAeS,EAAgB,OAAS,EACvC/K,EAAAA,KAAAC,EAAAA,SAAA,CACG,SAAA,CAAA8K,EAAgB,IAAK1P,GACpB2E,OAACoI,GAAc,QAAQ,UAAU,UAAU,UACxC,SAAA,CAAA/M,IAAM,eAAY6M,GAAA,CAAM,UAAU,eAAe,EAAKhI,EAAAA,IAACmN,GAAA,CAAO,UAAU,cAAA,CAAe,EACvFpO,EAAc,CAAE,GAAI,iBAAiB5D,CAAC,GAAI,CAAA,CAAA,EAFjCA,CAGZ,CACD,EACA0P,EAAgB,QAAU,GACzB/K,EAAAA,KAACoI,GAAM,QAAQ,UAAU,UAAU,4CACjC,SAAA,CAAAlI,EAAAA,IAACoN,GAAA,CAAc,UAAU,cAAA,CAAe,EACvCrO,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,EAEJ,QAECmJ,EAAA,CAAM,QAASkC,EAAc,UAAY,YAAa,UAAU,UAC9D,SAAcrL,EAAdqL,EAA4B,CAAE,GAAI,4BAA8C,CAAE,GAAI,6BAAA,CAAxB,EACjE,EAED2B,GACC/L,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAAwB,SAAA,QAE3D,EAEDkC,GACCpK,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,oBAChC,SAAAnJ,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EAEJ,EACAiB,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAC9C,CAAA,CAAA,CACF,CAAA,EACF,EACAA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BACZ,WACCA,EAAAA,IAACiK,GAAA,CAAY,UAAU,+BAAA,CAAgC,EAEvDjK,EAAAA,IAACqN,GAAA,CAAa,UAAU,gCAAgC,CAAA,CAE5D,CAAA,CAAA,CACF,CAAA,CAAA,EAID/E,GACCxI,EAAAA,KAAC,MAAA,CAAI,UAAU,mDAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS8K,GACT,SAAU,CAACxC,EAEX,SAAA,CAAApK,EAAAA,IAACsN,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/BvO,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,CAAA,EAEpDiB,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASgL,GACT,SAAU,CAAC1C,EAEV,SAAArL,EAAc,CAAE,GAAI,4BAAA,CAA8B,CAAA,CAAA,CACrD,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,sDACV,SAAAjB,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC9C,EACC,CAACqL,GACApK,EAAAA,IAAC,IAAA,CAAE,UAAU,6CACV,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,QACC,MAAA,CAAI,UAAU,yBACZ,SAAAmL,GAAc,IAAKqD,GAAS,CAC3B,MAAMC,GAAYnD,EAAa,SAASkD,EAAK,IAAI,EAC3CE,GAAOC,GAAYH,EAAK,IAAI,EAElC,OACEzN,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,kEACAuN,GAAY,kCAAoC,6BAAA,EAGlD,SAAA,CAAAxN,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAI,YAAYuN,EAAK,IAAI,GACzB,QAASC,GACT,SAAW3L,IAAM6K,GAAiBa,EAAK,KAAM1L,GAAE,OAAO,OAAO,EAC7D,SAAU,CAACuI,EACX,UAAU,SAAA,CAAA,EAEZtK,EAAAA,KAAC,QAAA,CACC,QAAS,YAAYyN,EAAK,IAAI,GAC9B,UAAU,gDAET,SAAA,CAAAE,GACD3N,EAAAA,KAAC,MAAA,CAAI,UAAU,SACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAjB,EAAc,CAAE,GAAI,iBAAiBwO,EAAK,IAAI,OAAA,CAAS,CAAA,CAC1D,EACCA,EAAK,MACJvN,EAAAA,IAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,UAClC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAI,iBAAiBwO,EAAK,IAAI,OAAA,CAAS,CAAA,CAC1D,CAAA,CAAA,CACF,CAAA,CAAA,CAAA,CACF,CAAA,EAlCKA,EAAK,IAAA,CAqChB,CAAC,CAAA,CACH,CAAA,EACF,EAGAzN,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,kDACf,SAAA,CAAAE,EAAAA,IAAC7G,GAAA,CAAW,UAAU,SAAA,CAAU,EAC/B4F,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,EACpD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,MAAOsJ,EACP,SAAWrJ,GAAMsJ,EAAoBtJ,EAAE,OAAO,KAAK,EACnD,YAAa9C,EAAc,CAAE,GAAI,uCAAwC,EACzE,SAAU,CAACqL,EACX,UAAU,mBAAA,CAAA,EAEZpK,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAM,CACbgK,EAAoB,aAAa,EACjCF,EAAoB,EAAI,CAC1B,EACA,SAAU,CAACxB,EACX,MAAM,0BAEN,SAAApK,EAAAA,IAAC2N,GAAA,CAAW,UAAU,SAAA,CAAU,CAAA,CAAA,CAClC,CAAA,CACF,CAAA,EACF,EAGA7N,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,kDACf,SAAA,CAAAE,EAAAA,IAAC4N,GAAA,CAAU,UAAU,SAAA,CAAU,EAC9B7O,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,EACpD,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4B,EAAA,CACC,MAAOwJ,EACP,SAAWvJ,GAAMwJ,EAAoBxJ,EAAE,OAAO,KAAK,EACnD,YAAa9C,EAAc,CAAE,GAAI,uCAAwC,EACzE,SAAU,CAACqL,EACX,UAAU,mBAAA,CAAA,EAEZpK,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAM,CACbgK,EAAoB,aAAa,EACjCF,EAAoB,EAAI,CAC1B,EACA,SAAU,CAACxB,EACX,MAAM,iCAEN,SAAApK,EAAAA,IAAC2N,GAAA,CAAW,UAAU,SAAA,CAAU,CAAA,CAAA,CAClC,EACF,EACA3N,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,EACF,EAGCoK,GACCpK,EAAAA,IAAC,MAAA,CAAI,UAAU,mBACb,SAAAF,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASiL,GACT,SAAU1F,GAEV,SAAA,CAAArH,EAAAA,IAAC6N,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B9O,EAAc,CAAE,GAAI,4BAAA,CAA8B,CAAA,CAAA,CAAA,EAEvD,EAIFiB,EAAAA,IAAC,OAAI,UAAU,wCACZ,SAACoK,EAuBApK,EAAAA,IAAC,MAAA,CAAI,UAAU,oCACZ,SAAA6K,EAAgB,OAAS,GAAKC,EAC7BD,EAAgB,IAAK1P,GACnB2E,EAAAA,KAACgC,EAAA,CAEC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMgJ,EAAiB3P,CAAC,EACjC,SAAUkM,GACV,UAAU,iEAEV,SAAA,CAAArH,EAAAA,IAACiC,GAAA,CAAO,UAAU,cAAA,CAAe,EAChClD,EAAc,CAAE,GAAI,gCAAA,EAAoC,CAAE,MAAO5D,EAAG,CAAA,CAAA,EARhEA,CAAA,CAUR,EAED2E,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASmL,GACT,SAAU5F,GACV,UAAU,iEAEV,SAAA,CAAArH,EAAAA,IAACiC,GAAA,CAAO,UAAU,cAAA,CAAe,EAChClD,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,CAAA,EAGxD,EAjDAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACZ,SAAA,CAAA,CAACiM,GACAjM,EAAAA,KAAC,SAAA,CACC,MAAO2L,EACP,SAAW5J,GAAM6J,EAAgB7J,EAAE,OAAO,KAA6B,EACvE,UAAU,+EAEV,SAAA,CAAA7B,EAAAA,IAAC,SAAA,CAAO,MAAM,SAAU,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAAE,EACtEiB,MAAC,UAAO,MAAM,UAAW,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAE,CAAA,CAAA,CAAA,EAG5EF,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASkL,GACT,SAAU3F,GAEV,SAAA,CAAArH,EAAAA,IAAC8N,GAAA,CAAS,UAAU,cAAA,CAAe,EAClC/O,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAAA,CAClD,CAAA,CACF,CA6BA,CAEJ,CAAA,EACF,EAGFiB,EAAAA,IAAC+N,GAAA,CACC,OAAQpC,EACR,QAAS,IAAMC,EAAoB,EAAK,EACxC,SAAUX,GAAsB,IAChC,aAAe+C,GAAS,CAClBnC,IAAqB,cACvBV,EAAoB6C,CAAI,EACfnC,IAAqB,eAC9BR,EAAqB5J,IAAUA,GAAO,GAAGA,EAAI,IAAIuM,CAAI,GAAKA,CAAK,EAEjEpC,EAAoB,EAAK,CAC3B,CAAA,CAAA,CACF,EACF,CAEJ,CAOA,SAAS8B,GAAYf,EAAsC,CACzD,MAAMsB,EAAY,CAAE,UAAW,+BAAA,EAE/B,OAAQtB,EAAA,CACN,IAAK,aACH,OAAO3M,MAACkO,GAAA,CAAU,GAAGD,CAAA,CAAW,EAClC,IAAK,YACH,OAAOjO,MAACsN,GAAA,CAAO,GAAGW,CAAA,CAAW,EAC/B,IAAK,YACH,OAAOjO,MAACmO,GAAA,CAAU,GAAGF,CAAA,CAAW,EAClC,IAAK,kBACH,OAAOjO,MAAC/G,GAAA,CAAO,GAAGgV,CAAA,CAAW,EAC/B,IAAK,cACH,OAAOjO,MAACkN,GAAA,CAAU,GAAGe,CAAA,CAAW,EAClC,IAAK,eACH,OAAOjO,MAAC3G,GAAA,CAAuB,GAAG4U,CAAA,CAAW,EAC/C,IAAK,WACH,OAAOjO,MAACoO,GAAA,CAAgB,GAAGH,CAAA,CAAW,EACxC,QACE,OAAOjO,MAACkN,GAAA,CAAU,GAAGe,CAAA,CAAW,CAAA,CAEtC,CC7eA,MAAMI,GAAqB,IAO3B,SAASC,GAAa,CAAE,SAAAxI,EAAU,UAAA6E,EAAW,SAAA4D,EAAU,aAAAC,EAAc,WAAAC,GAAiC,CACpG,KAAM,CAAE,cAAA1P,CAAA,EAAkBC,EAAA,EAEpB0P,EAAgB,IAAM,CAC1B/D,EAAU7E,CAAQ,CACpB,EAEM6I,EAAe,IAAM,CACzBJ,EAASzI,EAAS,IAAI,CACxB,EAGM8I,EAAkB,IAAM,OAC5B,MAAMX,EAAY,CAAE,UAAW,SAAA,EAC/B,QAAQrT,EAAAkL,EAAS,WAAT,YAAAlL,EAAmB,cAAY,CACrC,IAAK,QACL,IAAK,YACH,OAAOoF,MAAC6O,GAAA,CAAU,GAAGZ,CAAA,CAAW,EAClC,IAAK,WACL,IAAK,SACL,IAAK,OACH,OAAOjO,MAACmN,GAAA,CAAQ,GAAGc,CAAA,CAAW,EAChC,IAAK,WACL,IAAK,UACH,OAAOjO,MAACgI,GAAA,CAAO,GAAGiG,CAAA,CAAW,EAC/B,QACE,OAAOjO,MAAC8O,GAAA,CAAM,GAAGb,CAAA,CAAW,CAAA,CAElC,EAEA,aACGzE,EAAA,CAAK,UAAU,gDACd,SAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,wCACZ,SAAA4O,EAAA,EACH,EACA9O,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAA8F,EAAS,KACZ,EACCA,EAAS,UACR9F,MAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,UAClC,SAAApC,EAAS,QAAA,CACZ,CAAA,EAEJ,EACCA,EAAS,aACR9F,EAAAA,IAAC,KAAE,UAAU,kDACV,WAAS,YACZ,EAEFF,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,MAAC,OAAA,CAAK,UAAU,sEACb,SAAA8F,EAAS,aAAa,QACzB,EACCA,EAAS,aAAa,MAAQA,EAAS,aAAa,KAAK,OAAS,GACjEhG,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAA,CAAApC,EAAS,aAAa,KAAK,OAAO,OAAA,CAAA,CACrC,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,EACF,EACAhG,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS4M,EACT,SAAUF,EACV,MAAOzP,EAAc,CAAE,GAAI,gCAAiC,EAE5D,SAAAiB,EAAAA,IAAC8N,GAAA,CAAS,UAAU,SAAA,CAAU,CAAA,CAAA,EAEhC9N,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS6M,EACT,SAAUF,EACV,MAAO1P,EAAc,CAAE,GAAI,+BAAgC,EAE3D,SAAAiB,EAAAA,IAACiC,GAAA,CAAO,UAAU,SAAA,CAAU,CAAA,CAAA,CAC9B,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAKO,SAAS8M,GAAmB,CACjC,KAAA1M,EACA,QAAAC,EACA,OAAAC,EACA,YAAAyM,EAAc,GACd,eAAAC,EAAiB,GACjB,YAAAC,EAAc,CAAA,EACd,WAAAC,EAAa,CAAA,CACf,EAA4B,CAC1B,KAAM,CAAE,cAAApQ,CAAA,EAAkBC,EAAA,EAEpB,CAACyF,EAAM2K,CAAO,EAAIjQ,EAAAA,SAAS6P,CAAW,EACtC,CAACtV,EAAU2V,CAAW,EAAIlQ,EAAAA,SAAS,EAAE,EACrC,CAACmQ,EAAaC,CAAc,EAAIpQ,EAAAA,SAAS,EAAE,EAC3C,CAACqQ,EAASC,CAAU,EAAItQ,EAAAA,SAAS8P,CAAc,EAC/C,CAAC5L,EAAWC,CAAY,EAAInE,EAAAA,SAAS+P,EAAY,KAAK,IAAI,CAAC,EAC3D,CAAC3L,EAAUC,CAAW,EAAIrE,EAAAA,SAC9B,OAAO,QAAQgQ,CAAU,EAAE,IAAI,CAAC,CAACtK,EAAGC,CAAC,IAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,CAAA,EAE7D,CAAC3B,EAAQC,CAAS,EAAIjE,EAAAA,SAA8C,CAAA,CAAE,EAG5EK,EAAAA,UAAU,IAAM,CACV6C,IACF+M,EAAQJ,GAAe,EAAE,EACzBK,EAAY,EAAE,EACdE,EAAe,EAAE,EACjBE,EAAWR,GAAkB,EAAE,EAC/B3L,GAAc4L,GAAe,CAAA,GAAI,KAAK,IAAI,CAAC,EAC3C1L,EACE,OAAO,QAAQ2L,GAAc,CAAA,CAAE,EAAE,IAAI,CAAC,CAACtK,EAAGC,CAAC,IAAM,GAAGD,CAAC,IAAIC,CAAC,EAAE,EAAE,KAAK;AAAA,CAAI,CAAA,EAEzE1B,EAAU,CAAA,CAAE,EAEhB,EAAG,CAACf,EAAM2M,EAAaC,EAAgBC,EAAaC,CAAU,CAAC,EAE/D,MAAMO,EAAa,IAAM,CACvB,MAAM5I,EAAiD,CAAA,EAOvD,GANKrC,EAAK,SACRqC,EAAU,KAAO/H,EAAc,CAAE,GAAI,mDAAoD,GAEtFyQ,EAAQ,SACX1I,EAAU,QAAU/H,EAAc,CAAE,GAAI,wCAAyC,GAE/E,OAAO,KAAK+H,CAAS,EAAE,OAAS,EAAG,CACrC1D,EAAU0D,CAAS,EACnB,MACF,CAEA,MAAMnC,EAAOtB,EACV,MAAM,GAAG,EACT,IAAK6C,GAAMA,EAAE,KAAA,CAAM,EACnB,OAAQA,GAAMA,EAAE,OAAS,CAAC,EAEvBtB,EAA8B,CAAA,EACpC,UAAW0B,KAAQ/C,EAAS,MAAM;AAAA,CAAI,EAAG,CACvC,MAAMgD,EAAUD,EAAK,KAAA,EACrB,GAAIC,GAAWA,EAAQ,SAAS,GAAG,EAAG,CACpC,KAAM,CAACC,EAAK,GAAGC,CAAQ,EAAIF,EAAQ,MAAM,GAAG,EACxCC,IAAK5B,EAAI4B,EAAI,KAAA,CAAM,EAAIC,EAAS,KAAK,GAAG,EAAE,KAAA,EAChD,CACF,CAEAlE,EAAOkC,EAAK,OAAQ/K,EAAS,OAAQ4V,EAAY,OAAQ,CACvD,QAASE,EAAQ,KAAA,EACjB,KAAA7K,EACA,IAAAC,CAAA,CACD,CACH,EAEA,OACE5E,EAAAA,IAACsH,IAAO,KAAAjF,EAAY,aAAcC,EAChC,SAAAxC,EAAAA,KAACyH,GAAA,CAAc,UAAU,wCACvB,SAAA,CAAAvH,EAAAA,IAACwH,GAAA,CACC,eAACC,GAAA,CACE,SAAA1I,EAAc,CAAE,GAAI,gCAAA,CAAkC,CAAA,CACzD,CAAA,CACF,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,gCAAiC,EACtDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAO6C,EACP,SAAW5C,GAAM,CACfuN,EAAQvN,EAAE,OAAO,KAAK,EAClBsB,EAAO,MAAMC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,KAAM,MAAA,EAAY,CACrE,EACA,YAAa1C,EAAc,CAAE,GAAI,2CAA4C,EAC7E,MAAO,CAAC,CAACoE,EAAO,IAAA,CAAA,EAEjBA,EAAO,MACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,0BAA2B,EAChDiB,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC4B,EAAA,CACC,MAAO4N,EACP,SAAW3N,GAAM,CACf4N,EAAW5N,EAAE,OAAO,KAAK,EACrBsB,EAAO,SAASC,EAAW3B,IAAU,CAAE,GAAGA,EAAM,QAAS,MAAA,EAAY,CAC3E,EACA,YAAa1C,EAAc,CAAE,GAAI,qCAAsC,EACvE,MAAO,CAAC,CAACoE,EAAO,OAAA,CAAA,EAEjBA,EAAO,SACNnD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,EAE5D,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAC/C,EACAiB,EAAAA,IAAC4B,EAAA,CACC,MAAOyB,EACP,SAAWxB,GAAMyB,EAAazB,EAAE,OAAO,KAAK,EAC5C,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,CAAA,CAAA,EAEtEiB,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,EACF,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,qBAAA,CAAuB,EAC9C,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAOuD,EACP,SAAW1B,GAAM2B,EAAY3B,EAAE,OAAO,KAAK,EAC3C,YAAa9C,EAAc,CAAE,GAAI,iCAAkC,EACnE,UAAU,gQAAA,CAAA,CACZ,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,mCAAA,CAAqC,EAC5D,EACAe,EAAAA,KAAC4H,GAAA,CAAO,MAAOhO,EAAU,cAAe2V,EACtC,SAAA,CAAArP,EAAAA,IAAC2H,GAAA,CAAc,UAAU,SACvB,SAAA3H,EAAAA,IAAC4H,GAAA,CAAY,YAAa7I,EAAc,CAAE,GAAI,8CAAA,CAAgD,CAAA,CAAG,EACnG,SACC8I,GAAA,CACC,SAAA,CAAA7H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,QAAQ,SAAA,QAAK,EAC/B9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,MAAM,SAAA,MAAG,EAC3B9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,WAAW,SAAA,WAAQ,EACrC9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,WAAW,SAAA,WAAQ,EACrC9H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,SAAS,SAAA,QAAA,CAAM,CAAA,CAAA,CACnC,CAAA,CAAA,CACF,CAAA,EACF,EAGAhI,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAjB,EAAc,CAAE,GAAI,sCAAA,CAAwC,EAC/D,EACAiB,EAAAA,IAAC,WAAA,CACC,MAAOsP,EACP,SAAWzN,GAAM0N,EAAe1N,EAAE,OAAO,KAAK,EAC9C,YAAa9C,EAAc,CAAE,GAAI,kDAAmD,EACpF,UAAU,sPAAA,CAAA,CACZ,CAAA,CACF,CAAA,EACF,SACCoJ,GAAA,CACC,SAAA,CAAAnI,EAAAA,IAAC8B,EAAA,CAAO,QAAQ,UAAU,QAASQ,EAChC,WAAc,CAAE,GAAI,iCAAA,CAAmC,CAAA,CAC1D,EACAtC,MAAC8B,GAAO,QAAS4N,EACd,WAAc,CAAE,GAAI,+BAAA,CAAiC,CAAA,CACxD,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAaO,SAASC,GAAoB,CAAE,kBAAAC,EAAmB,iBAAAC,GAA8C,CACrG,KAAM,CAAE,cAAA9Q,CAAA,EAAkBC,EAAA,EAGpB,CAAC8Q,EAAaC,CAAc,EAAI5Q,EAAAA,SAAS,EAAE,EAC3C,CAAC6Q,EAAiBC,CAAkB,EAAI9Q,EAAAA,SAAS,EAAE,EACnD,CAAC+Q,EAAkBC,CAAmB,EAAIhR,EAAAA,SAAiB,KAAK,EAChE,CAACiR,EAAgBC,CAAiB,EAAIlR,EAAAA,SAAS,EAAK,EACpD,CAACmR,EAAmBC,CAAoB,EAAIpR,EAAAA,SAAS,EAAK,EAC1D,CAACqR,EAAkBC,CAAmB,EAAItR,EAAAA,SAAwB,IAAI,EAGtE,CAAE,KAAMuR,EAAa,CAAA,EAAI,UAAWC,CAAA,EAAsBlW,GAAS,CACvE,SAAUhB,GAAiB,WAAA,EAC3B,QAASmX,GACT,UAAW,IAAU,GAAA,CACtB,EAGKC,EAAiBzT,GAAA,EACjB4O,EAAkBzO,GAAA,EAGxBiC,EAAAA,UAAU,IAAM,CACd,MAAMsR,EAAQ,WAAW,IAAM,CAC7Bb,EAAmBH,CAAW,CAChC,EAAGzB,EAAkB,EACrB,MAAO,IAAM,aAAayC,CAAK,CACjC,EAAG,CAAChB,CAAW,CAAC,EAGhB,KAAM,CAAE,KAAMnN,EAAY,CAAA,EAAI,UAAWC,CAAA,EAAqBnI,GAAS,CACrE,SAAUhB,GAAiB,KAAKyW,IAAqB,MAAQ,OAAYA,CAAgB,EACzF,QAAS,SAAY,CACnB,GAAIF,EAAgB,OAClB,OAAOe,GAAmBf,EAAgB,MAAM,EAClD,GAAWE,IAAqB,MAAO,CAErC,MAAMc,EAA8B,CAAA,EACpC,UAAWtX,KAAYgX,EAAY,CACjC,MAAMO,EAAoB,MAAMC,GAA4BxX,CAAQ,EACpEsX,EAAa,KAAK,GAAGC,CAAiB,CACxC,CACA,OAAOD,CACT,KACE,QAAOE,GAA4BhB,CAAgB,CAEvD,EACA,UAAW,IAAS,IACpB,QAAS,CAACS,CAAA,CACX,EAGKQ,EAAwBjN,cAAa4B,GAA0B,CAEnE8J,GAAA,MAAAA,EAAoB9J,EACtB,EAAG,CAAC8J,CAAiB,CAAC,EAEhBwB,EAAoBlN,cAAa7G,GAAyB,CAC9DoT,EAAoBpT,CAAY,EAChCkT,EAAqB,EAAI,CAC3B,EAAG,CAAA,CAAE,EAECc,EAAsBnN,EAAAA,YAAY,SAAY,CAClD,GAAI,CAACsM,EAAkB,QAER,MAAMK,EAAe,eAAeL,CAAgB,GACxD,UACTD,EAAqB,EAAK,EAC1BE,EAAoB,IAAI,EAE5B,EAAG,CAACD,EAAkBK,CAAc,CAAC,EAE/BS,EAAqBpN,EAAAA,YAAY,CAACqN,EAAeC,EAAmBC,EAAsBC,IAAoF,CAClL7B,GAAA,MAAAA,EAAmB0B,EAAOC,EAAWC,EAAcC,GACnDrB,EAAkB,EAAK,CACzB,EAAG,CAACR,CAAgB,CAAC,EAErB,OACE/P,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0CACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iCAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAAE,EAAAA,IAAC2R,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3F3R,EAAAA,IAAC4B,EAAA,CACC,MAAOkO,EACP,SAAWjO,GAAMkO,EAAelO,EAAE,OAAO,KAAK,EAC9C,YAAa9C,EAAc,CAAE,GAAI,kCAAmC,EACpE,UAAU,MAAA,CAAA,CACZ,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4R,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAClD9R,EAAAA,KAAC4H,GAAA,CAAO,MAAOwI,EAAkB,cAAeC,EAC9C,SAAA,CAAAnQ,MAAC2H,GAAA,CAAc,UAAU,YACvB,SAAA3H,MAAC4H,KAAY,EACf,SACCC,GAAA,CACC,SAAA,CAAA7H,EAAAA,IAAC8H,GAAA,CAAW,MAAM,MACf,SAAA/I,EAAc,CAAE,GAAI,oCAAA,CAAsC,EAC7D,EACC2R,EAAW,IAAKhX,GACfsG,EAAAA,IAAC8H,IAA0B,MAAOpO,EAC/B,SAAAA,CAAA,EADcA,CAEjB,CACD,CAAA,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,EACF,EAGAoG,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMuO,EAAkB,EAAI,EAErC,SAAA,CAAArQ,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,sCAAA,CAAwC,CAAA,CAAA,CAAA,CAC/D,EACF,EAGC6D,QACE,MAAA,CAAI,UAAU,yCACb,SAAA5C,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAChD,CAAA,CACF,EACE4D,EAAU,SAAW,EACvB7C,EAAAA,KAAC0J,EAAA,CAAK,UAAU,mBACd,SAAA,CAAAxJ,EAAAA,IAAC8O,GAAA,CAAK,UAAU,8CAAA,CAA+C,EAC/D9O,EAAAA,IAAC,MAAG,UAAU,2CACX,WAAc,CAAE,GAAI,2BAAA,CAA6B,EACpD,EACAA,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,6BAAA,CAA+B,EACtD,SACC8B,EAAA,CAAO,QAAS,IAAMuO,EAAkB,EAAI,EAC3C,SAAA,CAAArQ,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,iCAAA,CAAmC,CAAA,CAAA,CAC1D,CAAA,CAAA,CACF,QAEC,MAAA,CAAI,UAAU,wCACZ,SAAA4D,EAAU,IAAKmD,GACd9F,EAAAA,IAACsO,GAAA,CAEC,SAAAxI,EACA,UAAWqL,EACX,SAAUC,EACV,aAAcpF,EAAgB,aAC9B,WAAY6E,EAAe,UAAA,EALtB/K,EAAS,IAAA,CAOjB,EACH,EAIF9F,EAAAA,IAAC+O,GAAA,CACC,KAAMqB,EACN,QAAS,IAAMC,EAAkB,EAAK,EACtC,OAAQiB,CAAA,CAAA,QAITpR,GAAA,CAAY,KAAMoQ,EAAmB,aAAcC,EAClD,gBAACpQ,GAAA,CACC,SAAA,CAAAL,OAACM,GAAA,CACC,SAAA,CAAAJ,MAACK,IACE,SAAAtB,EAAc,CAAE,GAAI,kCAAA,CAAoC,EAC3D,QACCuB,GAAA,CACE,SAAAvB,EACC,CAAE,GAAI,oCAAA,EACN,CAAE,KAAMyR,CAAA,CAAiB,CAC3B,CACF,CAAA,EACF,SACCjQ,GAAA,CACC,SAAA,CAAAP,MAACQ,IACE,SAAAzB,EAAc,CAAE,GAAI,mCAAA,CAAqC,EAC5D,EACAiB,EAAAA,IAACS,GAAA,CACC,QAAS4Q,EACT,UAAU,qEAET,SAAAR,EAAe,WACZ9R,EAAc,CAAE,GAAI,qCAAA,CAAuC,EAC3DA,EAAc,CAAE,GAAI,mCAAA,CAAqC,CAAA,CAAA,CAE/D,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,CAEJ,CC9iBA,MAAM8S,GAAwE,CAC5E,cAAeF,GACf,OAAU3J,GACV,UAAW8J,GACX,SAAU5E,EACZ,EAuDO,SAAS6E,GAAqB,CACnC,KAAA1P,EACA,QAAAC,EACA,cAAA0P,EACA,kBAAAC,CACF,EAA8B,CAC5B,KAAM,CAAE,cAAAlT,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EACd,CAAE,QAASqI,EAAa,MAAOD,CAAA,EAAcE,GAAA,EAC7CrI,EAAcC,GAAiBC,EAAiB,EAGhD,CAAC2X,EAAaC,CAAc,EAAIhT,EAAAA,SAA8B,CAAA,CAAE,EAChE,CAACiT,EAAeC,CAAgB,EAAIlT,EAAAA,SAA+B,QAAQ,EAG3EmT,EAAwB,IAAM,CAClC,GAAI,CAACN,EAAe,OAEpB,MAAMO,EAAqC,CAAA,EAC3C,UAAWjR,KAAS0Q,EAAc,OAC5B1Q,EAAM,UAAY,OACpBiR,EAAcjR,EAAM,GAAG,EAAIA,EAAM,QACxBA,EAAM,OAAS,eACxBiR,EAAcjR,EAAM,GAAG,EAAI,CAAA,EAE3BiR,EAAcjR,EAAM,GAAG,EAAI,GAG/B6Q,EAAeI,CAAa,CAC9B,EAGMC,EAAoBC,GAAqB,CACzCA,GAAWT,EACbM,EAAA,GAEAH,EAAe,CAAA,CAAE,EACjB7P,EAAA,EAEJ,EAGM0J,EAAkBxQ,GAAY,CAClC,WAAY,SAAY,CACtB,GAAI,CAACwW,EAAe,MAAM,IAAI,MAAM,mBAAmB,EAEvD,MAAMxN,EAAewN,EAAc,YAAYE,CAAW,EAE1D,GAAIE,IAAkB,SACpB,OAAOM,GAAmBV,EAAc,GAAIxN,CAAY,EAExD,GAAI,CAACnK,EACH,MAAM,IAAI,MAAM,sDAAsD,EAExE,OAAOsY,GAAuBX,EAAc,GAAIxN,EAAcnK,CAAW,CAE7E,EACA,UAAYuY,GAAW,CACjBA,EAAO,SACTzY,EAAY,kBAAkB,CAAE,SAAUZ,EAAe,IAAK,EAC9DkJ,EACE1D,EAAc,CAAE,GAAI,4BAA6B,EACjDA,EAAc,CAAE,GAAIiT,EAAe,QAAS,CAAA,EAE9CQ,EAAiB,EAAK,EACtBP,GAAA,MAAAA,KAEAzP,EACEzD,EAAc,CAAE,GAAI,0BAA2B,EAC/C6T,EAAO,OAAS,eAAA,CAGtB,EACA,QAAUxL,GAAe,CACvB5E,EACEzD,EAAc,CAAE,GAAI,0BAA2B,EAC/CqI,EAAI,OAAA,CAER,CAAA,CACD,EAGKrB,EAAoB,CAACS,EAAajF,IAAe,CACrD4Q,EAAe1Q,IAAS,CACtB,GAAGA,EACH,CAAC+E,CAAG,EAAGjF,CAAA,EACP,CACJ,EAGMsR,EAA0B,CAACrM,EAAajF,IAAkB,CAC9D,MAAMuR,EAAUZ,EAAY1L,CAAG,GAAK,CAAA,EAC9BuM,EAAWD,EAAQ,SAASvR,CAAK,EACnCuR,EAAQ,OAAQhO,GAAcA,IAAMvD,CAAK,EACzC,CAAC,GAAGuR,EAASvR,CAAK,EACtBwE,EAAkBS,EAAKuM,CAAQ,CACjC,EAGMC,EAAiB,IAAe,CACpC,GAAI,CAAChB,EAAe,MAAO,GAE3B,UAAW1Q,KAAS0Q,EAAc,OAChC,GAAI1Q,EAAM,SAAU,CAClB,MAAMC,EAAQ2Q,EAAY5Q,EAAM,GAAG,EACnC,GAAIA,EAAM,OAAS,gBACjB,GAAI,CAACC,GAASA,EAAM,SAAW,EAAG,MAAO,WAErC,CAACA,GAASA,EAAM,KAAA,IAAW,GAAI,MAAO,EAE9C,CAEF,MAAO,EACT,EAGM0F,EAAe,IAAM,CACzB,GAAI,CAAC+L,IAAkB,CACrBxQ,EACEzD,EAAc,CAAE,GAAI,wBAAyB,EAC7CA,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,EAEnD,MACF,CACAiN,EAAgB,OAAA,CAClB,EAEA,GAAI,CAACgG,EAAe,OAAO,KAE3B,MAAMiB,EAAYjB,EAAc,OAAO,OAAS,EAC1CkB,EAAOrB,GAASG,EAAc,IAAI,GAAK9E,GAE7C,OACElN,EAAAA,IAACsH,IAAO,KAAAjF,EAAY,aAAcmQ,EAChC,SAAA1S,EAAAA,KAACyH,GAAA,CAAc,UAAU,wCAEvB,SAAA,CAAAvH,MAACwH,GAAA,CACC,SAAA1H,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAI,UAAU,sEACb,eAACkT,EAAA,CAAK,UAAU,uBAAuB,CAAA,CACzC,SACC,MAAA,CACC,SAAA,CAAApT,OAAC2H,GAAA,CACE,SAAA,CAAA1I,EAAc,CAAE,GAAI,qBAAsB,EAAE,IAAEA,EAAc,CAAE,GAAIiT,EAAc,QAAS,CAAA,EAC5F,EACAhS,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAIiT,EAAc,OAAA,CAAS,CAAA,CAC9C,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAGAlS,EAAAA,KAAC,MAAA,CAAI,UAAU,iBAEZ,SAAA,CAAAmT,GACCjT,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAAgS,EAAc,OAAO,IAAK1Q,GACzBxB,OAAC,MAAA,CAAoB,UAAU,cAC7B,SAAA,CAAAA,EAAAA,KAACqT,GAAA,CAAM,UAAU,gDACd,SAAA,CAAApU,EAAc,CAAE,GAAIuC,EAAM,QAAA,CAAU,EACpCA,EAAM,UAAYtB,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAmB,SAAA,GAAA,CAAC,CAAA,EACzD,EACCsB,EAAM,SACLtB,EAAAA,IAAC,IAAA,CAAE,UAAU,gCACV,SAAAjB,EAAc,CAAE,GAAIuC,EAAM,OAAA,CAAS,CAAA,CACtC,GAIAA,EAAM,OAAS,QAAUA,EAAM,OAAS,aACxCtB,EAAAA,IAAC4B,EAAA,CACC,KAAMN,EAAM,KACZ,MAAO4Q,EAAY5Q,EAAM,GAAG,GAAK,GACjC,SAAWO,GAAMkE,EAAkBzE,EAAM,IAAKO,EAAE,OAAO,KAAK,EAC5D,YAAaP,EAAM,YACnB,UAAU,mBAAA,CAAA,EAKbA,EAAM,OAAS,gBAAkBA,EAAM,SACtCtB,EAAAA,IAAC,MAAA,CAAI,UAAU,qFACZ,SAAAsB,EAAM,QAAQ,IAAK8R,GAAW,CAC7B,MAAMC,GAAcnB,EAAY5Q,EAAM,GAAG,GAAK,IAAI,SAAS8R,EAAO,KAAK,EACvE,OACEtT,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,sEACAoT,EAAa,gBAAkB,mBAAA,EAEjC,QAAS,IAAMR,EAAwBvR,EAAM,IAAK8R,EAAO,KAAK,EAE9D,SAAA,CAAApT,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAASqT,EACT,SAAU,IAAM,CAAC,EACjB,UAAU,gBAAA,CAAA,EAEZvT,EAAAA,KAAC,MAAA,CAAI,UAAU,SACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,sCACZ,SAAAoT,EAAO,MACV,EACCA,EAAO,MACNpT,EAAAA,IAAC,OAAI,UAAU,gCACZ,WAAO,IAAA,CACV,CAAA,CAAA,CAEJ,CAAA,CAAA,EAtBKoT,EAAO,KAAA,CAyBlB,CAAC,CAAA,CACH,CAAA,CAAA,EAvDM9R,EAAM,GAyDhB,CACD,EACH,EAIFxB,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAACmT,GAAA,CAAM,UAAU,sBACd,SAAApU,EAAc,CAAE,GAAI,kBAAA,CAAoB,EAC3C,EACAe,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAASsQ,IAAkB,SAAW,UAAY,UAClD,KAAK,KACL,QAAS,IAAMC,EAAiB,QAAQ,EACxC,UAAU,SAET,SAAAtT,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,EAElDiB,EAAAA,IAAC8B,EAAA,CACC,QAASsQ,IAAkB,UAAY,UAAY,UACnD,KAAK,KACL,QAAS,IAAMC,EAAiB,SAAS,EACzC,UAAU,SAET,SAAAtT,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CAAA,CACnD,CAAA,CACF,CAAA,EACF,EAGC,CAACkU,GACAjT,EAAAA,IAAC,MAAA,CAAI,UAAU,6EACZ,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,SAGCoJ,GAAA,CACC,SAAA,CAAAnI,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,QAAS,IAAM0Q,EAAiB,EAAK,EACrC,SAAUxG,EAAgB,UAEzB,SAAAjN,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CAAA,EAEpDiB,EAAAA,IAAC8B,EAAA,CACC,QAASmF,EACT,SAAU+E,EAAgB,UAEzB,SAAAA,EAAgB,UACflM,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,CAChD,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC8N,GAAA,CAAS,UAAU,cAAA,CAAe,EAClC/O,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,QClVA,MAAMwU,GAAY,OAAO,UAAc,OAAe3Y,GAAA,UAAU,WAAV,YAAAA,GAAoB,cAAc,SAAS,QAMjG,SAAS4Y,GACPhE,EACA7K,EAAiB,CAAA,EACjB3K,EAA2D,CAAA,EAC3D,CACA,KAAM,CAAE,IAAA4K,EAAK,KAAAnG,CAAA,EAASzE,EAKhB0B,EAFsB6X,IADG,CAAC,MAAO,MAAO,OAAQ,SAAU,UAAW,MAAO,OAAQ,OAAQ,OAAQ,KAAK,EAC/C,SAAS/D,EAAQ,aAAa,EAG1F,CAAE,QAAS,MAAO,KAAM,CAAC,KAAMA,EAAS,GAAG7K,CAAI,CAAA,EAC/C,CAAE,QAAA6K,EAAS,KAAA7K,CAAA,EAEf,OAAIlG,MAAa,KAAOA,GACpBmG,GAAO,OAAO,KAAKA,CAAG,EAAE,OAAS,MAAU,IAAMA,GAE9ClJ,CACT,CAQA,MAAM+X,GAA0D,CAC9D,CACE,GAAI,WACJ,QAAS,oBACT,QAAS,oBACT,KAAM,cACN,SAAU,SACV,OAAQ,CACN,CACE,IAAK,UACL,SAAU,6BACV,KAAM,OACN,QAAS,oCACT,YAAa,oCACb,SAAU,GACV,QAAS,iCAAA,EAEX,CACE,IAAK,QACL,SAAU,2BACV,KAAM,WACN,QAAS,GACT,YAAa,uBACb,SAAU,GACV,QAAS,+BAAA,CACX,EAEF,YAAcC,GAAWF,GAA4B,MAAO,CAC1D,WACA,aACAE,EAAO,SAAW,oCAClB,UACAA,EAAO,KAAA,CACR,CAAA,EAEH,CACE,GAAI,kBACJ,QAAS,2BACT,QAAS,2BACT,KAAM,SACN,SAAU,UACV,OAAQ,CAAA,EACR,YAAa,IAAMF,GAA4B,MAAO,CAAC,4BAA4B,EAAG,CAAE,KAAM,OAAA,CAAS,CAAA,EAEzG,CACE,GAAI,MACJ,QAAS,eACT,QAAS,eACT,KAAM,UACN,SAAU,SACV,OAAQ,CACN,CACE,IAAK,SACL,SAAU,uBACV,KAAM,WACN,QAAS,GACT,YAAa,mBACb,SAAU,GACV,QAAS,2BAAA,CACX,EAEF,YAAcE,GAAW,CACvB,MAAMC,EAAU,yBACVC,EAAMF,EAAO,OAAS,GAAGC,CAAO,cAAcD,EAAO,MAAM,GAAKC,EACtE,OAAOH,GAA4B,MAAO,CAAC,KAAM,aAAcI,CAAG,CAAC,CACrE,CAAA,CAEJ,EAIM/B,GAAwE,CAC5E,cAAeF,GACf,OAAU3J,GACV,UAAW8J,GACX,SAAU+B,EACZ,EAaA,SAASC,GAAsB,CAC7B,WAAAC,EACA,YAAA3J,EACA,UAAAO,CACF,EAA+B,CAC7B,KAAM,CAAE,cAAA5L,CAAA,EAAkBC,EAAA,EACpBkU,EAAOrB,GAASkC,EAAW,IAAI,GAAK7G,GACpC+F,EAAYc,EAAW,OAAO,OAAS,EAE7C,aACGvK,EAAA,CAAK,UAAU,wCACd,SAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,yBAEb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,mBACAmK,EAAc,gBAAkB,UAAA,EAEhC,SAAApK,EAAAA,IAACkT,EAAA,CAAK,UAAWjT,EACf,UACAmK,EAAc,eAAiB,uBAAA,EAC9B,CAAA,CACL,EAGAtK,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,+CACX,SAAAjB,EAAc,CAAE,GAAIgV,EAAW,OAAA,CAAS,CAAA,CAC3C,EACC3J,GACCpK,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,mCAAA,CAAqC,CAAA,CAC5D,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,kDACV,SAAAjB,EAAc,CAAE,GAAIgV,EAAW,OAAA,CAAS,CAAA,CAC3C,EAGAjU,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACZ,SAAA,CAAAmT,EACCnT,EAAAA,KAAC,OAAA,CAAK,UAAU,wDACd,SAAA,CAAAE,EAAAA,IAAC5G,GAAA,CAAI,UAAU,SAAA,CAAU,EACxB2a,EAAW,OAAO,OAAO,IAAEhV,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CACxE,EAEAe,EAAAA,KAAC,OAAA,CAAK,UAAU,qEACd,SAAA,CAAAE,EAAAA,IAACgU,GAAA,CAAI,UAAU,SAAA,CAAU,EACxBjV,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEFiB,EAAAA,IAAC8B,EAAA,CACC,QAASsI,EAAc,UAAY,UACnC,KAAK,KACL,QAAS,IAAMO,EAAUoJ,CAAU,EAElC,WACCjU,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACkN,GAAA,CAAS,UAAU,kBAAA,CAAmB,EACtCnO,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAA,CAC1C,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC8N,GAAA,CAAS,UAAU,kBAAA,CAAmB,EACtC/O,EAAc,CAAE,GAAI,iCAAA,CAAmC,CAAA,CAAA,CAC1D,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAOO,SAASkV,GAAsB,CACpC,kBAAAhC,CACF,EAA+B,CAC7B,KAAM,CAAE,cAAAlT,CAAA,EAAkBC,EAAA,EAEpB,CAACkV,EAAYC,CAAa,EAAIhV,EAAAA,SAAS,EAAK,EAC5C,CAACiV,EAAoBC,CAAqB,EAAIlV,EAAAA,SAA0C,IAAI,EAC5F,CAACmV,EAAoBC,CAAqB,EAAIpV,EAAAA,SAAsB,IAAI,GAAK,EAG7EqV,EAAwB,SAAY,OACxC,GAAI,CACF,MAAMxN,EAAO,MAAMyN,GAAA,EACbC,MAAmB,IAEnB7Z,EAAgBmM,EAAK,eAAiB,CAAA,EACtC2N,EAAc3N,EAAK,aAAe,CAAA,EACxC,UAAWvC,KAAQ,OAAO,KAAK5J,CAAa,EAAG6Z,EAAa,IAAIjQ,CAAI,EACpE,UAAWA,KAAQ,OAAO,KAAKkQ,CAAW,EAAGD,EAAa,IAAIjQ,CAAI,EAElE,MAAMmQ,EAAW5N,EAAK,UAAY,CAAA,EAClC,UAAW6N,KAAQ,OAAO,OAAOD,CAAQ,EAAG,CAC1C,MAAMrY,EAAWsY,EAAa,YAAc,CAAA,EAC5C,UAAWpQ,KAAQ,OAAO,KAAKlI,CAAO,EAAGmY,EAAa,IAAIjQ,CAAI,CAChE,CAEA,IAAK7J,EAAAoM,EAAa,QAAb,MAAApM,EAAoB,QACvB,UAAW6J,KAAQ,OAAO,KAAMuC,EAAa,MAAM,OAAO,EAAG0N,EAAa,IAAIjQ,CAAI,EAGpF8P,EAAsBG,CAAY,CACpC,MAAQ,CAER,CACF,EAEAlV,EAAAA,UAAU,IAAM,CACdgV,EAAA,CACF,EAAG,CAAA,CAAE,EAGL,MAAMxH,EAAsB+G,GAAyC,CACnEM,EAAsBN,CAAU,EAChCI,EAAc,EAAI,CACpB,EAGMW,EAAoB,IAAM,CAC9BX,EAAc,EAAK,EACnBE,EAAsB,IAAI,CAC5B,EAGMU,EAAwB,IAAM,CAClCP,EAAA,EACAvC,GAAA,MAAAA,GACF,EAEA,OACEnS,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAD,EAAAA,KAAC,UAAA,CAAQ,UAAU,YAEjB,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,wCACX,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAiB,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,6BAAA,CAA+B,CAAA,CACtD,CAAA,EACF,QAGC,MAAA,CAAI,UAAU,wCACZ,SAAAyT,GAA4B,IAAKM,GAChC/T,EAAAA,IAAC8T,GAAA,CAEC,WAAAC,EACA,YAAaO,EAAmB,IAAIP,EAAW,EAAE,EACjD,UAAW/G,CAAA,EAHN+G,EAAW,EAAA,CAKnB,CAAA,CACH,CAAA,EACF,EAGA/T,EAAAA,IAAC+R,GAAA,CACC,KAAMmC,EACN,QAASY,EACT,cAAeV,EACf,kBAAmBW,CAAA,CAAA,CACrB,EACF,CAEJ,CCrSA,MAAMC,GAAkB,CACtB,CAAE,KAAM,MAAO,WAAY,mEAAA,EAC3B,CAAE,KAAM,OAAQ,WAAY,qBAAA,EAC5B,CAAE,KAAM,SAAU,WAAY,mCAAA,EAC9B,CAAE,KAAM,MAAO,WAAY,mEAAA,CAC7B,EAGA,SAASC,GAAkBzF,EAA0B,CACnD,OAAOwF,GAAgB,KAAME,GAAQA,EAAI,OAAS1F,CAAO,CAC3D,CAIA,eAAe2F,GAAsB9a,EAAyD,CAC5F,MAAM+a,EAAW,MAAM,MAAM,2BAA4B,CACvD,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,YAAA/a,EAAa,CAAA,CACrC,EACD,GAAI,CAAC+a,EAAS,GACZ,MAAM,IAAI,MAAM,2BAA2B,EAE7C,OAAOA,EAAS,KAAA,CAClB,CAEA,eAAeC,GAAoBhb,EAAsE,CACvG,MAAM+a,EAAW,MAAM,MAAM,6BAA8B,CACzD,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,YAAA/a,EAAa,CAAA,CACrC,EACD,GAAI,CAAC+a,EAAS,GACZ,MAAM,IAAI,MAAM,6BAA6B,EAE/C,OAAOA,EAAS,KAAA,CAClB,CAQA,SAASE,GAAqB,CAAE,SAAAC,GAAuC,CACrE,KAAM,CAAE,cAAAxW,CAAA,EAAkBC,EAAA,EAE1B,aACG,MAAA,CAAI,UAAU,iBACZ,SAAAuW,EAAS,IAAKL,GACbpV,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,iDACAiV,EAAI,UAAY,gBAAkB,mBAAA,EAGnC,SAAA,CAAAA,EAAI,gBACFM,GAAA,CAAY,UAAU,uBAAuB,EAE9CxV,EAAAA,IAACyV,GAAA,CAAQ,UAAU,0BAAA,CAA2B,EAEhDzV,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,WAAI,QAAQ,EAC/C,CAACkV,EAAI,WAAaA,EAAI,YACrBpV,EAAAA,KAAC,IAAA,CACC,KAAMoV,EAAI,WACV,OAAO,SACP,IAAI,sBACJ,UAAU,+DAEV,SAAA,CAAAlV,EAAAA,IAAC8N,GAAA,CAAS,UAAU,SAAA,CAAU,EAC7B/O,EAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAA,CAAA,CAC9C,CAAA,EArBGmW,EAAI,OAAA,CAwBZ,EACH,CAEJ,CAIO,SAASQ,GAA4B,CAC1C,YAAArb,EACA,WAAAsb,CACF,EAAqC,CACnC,KAAM,CAAE,cAAA5W,CAAA,EAAkBC,EAAA,EACpB7E,EAAcC,GAAA,EAEd,CAACwb,EAAaC,CAAc,EAAI1W,EAAAA,SAA0C,IAAI,EAC9E,CAAC2W,EAAYC,CAAa,EAAI5W,EAAAA,SAAS,EAAK,EAC5C,CAAC6W,EAAWC,CAAY,EAAI9W,EAAAA,SAAS,EAAK,EAG1CoU,EAAY,OAAO,OAAW,KAAe,OAAO,UAAU,SAAS,YAAA,EAAc,SAAS,KAAK,EAGnG2C,EAAkB1a,GAAY,CAClC,WAAY,IAAM6Z,GAAoBhb,CAAW,EACjD,UAAW,IAAM,CACfF,EAAY,kBAAkB,CAAE,SAAU,CAAC,YAAY,EAAG,EACtDwb,GAAcC,GAChBD,EAAW,CAAE,GAAGC,EAAa,WAAY,GAAO,CAEpD,CAAA,CACD,EAwCD,GArCApW,EAAAA,UAAU,IAAM,CACd,GAAI,CAAC+T,GAAayC,EAAW,QAEF,SAAY,CACrCD,EAAc,EAAI,EAClB,GAAI,CACF,MAAMI,EAAU,MAAMhB,GAAsB9a,CAAW,EACjD+b,EAAkBD,EAAQ,OAAQE,GAAM,CAACA,EAAE,SAAS,EAAE,IAAKA,GAAMA,EAAE,OAAO,EAC1EC,EAAaF,EAAgB,OAAS,GAAKA,EAAgB,MAAMnB,EAAiB,EAElFrC,EAAmC,CACvC,UAAW,GACX,gBAAAwD,EACA,SAAUD,EACV,WAAAG,CAAA,EAGFT,EAAejD,CAAM,EACjB+C,GACFA,EAAW/C,CAAM,CAErB,OAAS7N,EAAO,CACd,QAAQ,MAAM,yCAA0CA,CAAK,CAC/D,QAAA,CACEgR,EAAc,EAAK,CACrB,CACF,GAEA,CACF,EAAG,CAACxC,EAAWyC,EAAW3b,EAAasb,CAAU,CAAC,EAG9C,CAACpC,GAAayC,GAAcF,GAAc,CAACF,GAK3CA,GAAeA,EAAY,gBAAgB,SAAW,EACxD,OAAO,KAGT,MAAMW,EAAgB,SAAY,CAChCL,EAAgB,OAAA,CAClB,EAEMM,EAAgB,IAAM,CAC1BP,EAAa,EAAI,CACnB,EAEA,aACG,MAAA,CAAI,UAAU,4DACb,SAAAnW,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,EAAAA,IAACoN,GAAA,CAAc,UAAU,2CAAA,CAA4C,EACrEtN,EAAAA,KAAC,MAAA,CAAI,UAAU,mBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,wCACX,SAAAjB,EAAc,CAAE,GAAI,mBAAA,CAAqB,EAC5C,EACAiB,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EACAA,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS0U,EACV,SAAA,GAAA,CAAA,CAED,EACF,EAECZ,GACC9V,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAA6V,EAAY,gBAAgB,OAAS,GACpC5V,EAAAA,IAAC,MAAA,CAAI,UAAU,0BACb,SAAAA,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,0BAAA,EAA8B,CAAE,MAAO6W,EAAY,gBAAgB,MAAA,CAAQ,CAAA,CAClG,CAAA,CACF,EAGF5V,EAAAA,IAACsV,GAAA,CAAqB,SAAUM,EAAY,QAAA,CAAU,EAErDA,EAAY,YACX9V,OAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASyU,EACT,SAAUL,EAAgB,UAC1B,UAAU,UAET,SAAAA,EAAgB,UACfpW,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACwV,GAAA,CAAY,UAAU,cAAA,CAAe,EACrCzW,EAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAA,CAC9C,CAAA,CAAA,EAGJiB,MAAC,QAAK,UAAU,gCACb,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,CAAA,CACF,CAAA,EAEJ,EAGD8V,GACChW,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAAE,EAAAA,IAACsT,GAAA,CAAQ,UAAU,sBAAA,CAAuB,EACzCvU,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,CAC/C,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CC1OO,SAAS0X,GAAkB,CAAE,UAAAC,EAAW,UAAAC,GAAqC,CAClF,KAAM,CAAE,cAAA5X,CAAA,EAAkBC,EAAA,EACpB3E,EAAcC,GAAiBC,EAAiB,EAGhD,CAAE,QAASqc,CAAA,EAAkB7c,GAAA,EAC7B,CAAC8c,EAAgBC,CAAiB,EAAI3X,EAAAA,SAAsB,IAAI,GAAK,EAGrE,CAAC4X,EAAcC,CAAe,EAAI7X,EAAAA,SAA+B,CAAA,CAAE,EACnE,CAAC8X,EAAeC,CAAgB,EAAI/X,EAAAA,SAAsB,IAAI,GAAK,EACnE,CAACgY,EAAgBC,CAAiB,EAAIjY,EAAAA,SAAS,EAAK,EACpD,CAACkY,EAAYC,CAAa,EAAInY,EAAAA,SAAwB,IAAI,EAG1D,CAACoY,EAAWC,CAAY,EAAIrY,EAAAA,SAAS,EAAK,EAC1C,CAACsY,EAAYC,CAAa,EAAIvY,EAAAA,SAIjC,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,CAAA,CAAG,EAGvCK,EAAAA,UAAU,IAAM,EACW,SAAY,CACnC4X,EAAkB,EAAI,EACtBE,EAAc,IAAI,EAClB,GAAI,CACF,MAAMK,EAAQ,MAAMC,GAAA,EACpBZ,GACGW,EAAM,SAAW,CAAA,GAAI,IAAKxc,IAAO,CAChC,KAAMA,EAAE,KACR,YAAaiJ,GAAgBjJ,CAAC,EAAIA,EAAE,IAAOiK,GAAiBjK,CAAC,EAAIA,EAAE,QAAU,GAC7E,QAASA,EAAE,QACX,SAAU,EAAA,EACV,CAAA,CAEN,OAAS4J,EAAO,CACd,QAAQ,MAAM,oCAAqCA,CAAK,EACxDuS,EAAcvY,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAC,EAC9DiY,EAAgB,CAAA,CAAE,CACpB,QAAA,CACEI,EAAkB,EAAK,CACzB,CACF,GAEK,CACP,EAAG,CAACrY,CAAa,CAAC,EAGlB,MAAM8Y,EAAsBpT,GAAiB,CAC3CqS,EAAmBrV,GAAS,CAC1B,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAI+C,CAAI,EACf/C,EAAK,OAAO+C,CAAI,EAEhB/C,EAAK,IAAI+C,CAAI,EAER/C,CACT,CAAC,CACH,EAEMoW,EAAkB,IAAM,CAC5BhB,EAAkB,IAAI,IAAIF,EAAc,IAAKzb,GAAMA,EAAE,IAAI,CAAC,CAAC,CAC7D,EAEM4c,EAAiB,IAAM,CAC3BjB,EAAkB,IAAI,GAAK,CAC7B,EAGMkB,EAAqBvT,GAAiB,CAC1CyS,EAAkBzV,GAAS,CACzB,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAI+C,CAAI,EACf/C,EAAK,OAAO+C,CAAI,EAEhB/C,EAAK,IAAI+C,CAAI,EAER/C,CACT,CAAC,EACDsV,EAAiBvV,GACfA,EAAK,IAAKtG,GAAOA,EAAE,OAASsJ,EAAO,CAAE,GAAGtJ,EAAG,SAAU,CAACA,EAAE,QAAA,EAAaA,CAAE,CAAA,CAE3E,EAEM8c,EAAiB,IAAM,CAC3B,MAAMC,EAAWnB,EAAa,IAAK5b,GAAMA,EAAE,IAAI,EAC/C+b,EAAiB,IAAI,IAAIgB,CAAQ,CAAC,EAClClB,EAAiBvV,GAASA,EAAK,IAAKtG,IAAO,CAAE,GAAGA,EAAG,SAAU,EAAA,EAAO,CAAC,CACvE,EAEMgd,EAAgB,IAAM,CAC1BjB,EAAiB,IAAI,GAAK,EAC1BF,EAAiBvV,GAASA,EAAK,IAAKtG,IAAO,CAAE,GAAGA,EAAG,SAAU,EAAA,EAAQ,CAAC,CACxE,EAGMid,EAAoB,SAAY,CACpC,GAAIvB,EAAe,OAAS,EAE5B,CAAAW,EAAa,EAAI,EACjBE,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,EAElD,GAAI,CACF,MAAM9E,EAAS,MAAM7U,GAAa,CAChC,OAAQ,SACR,OAAQ,QACR,YAAa,MAAM,KAAK8Y,CAAc,EACtC,YAAaxc,GAAe,MAAA,CAC7B,EAED,GAAIuY,EAAO,QAAS,CAClB,MAAMyF,EAAczF,EAAO,OAAO,OAC5B0F,EAAc1F,EAAO,OAAO,OAElC8E,EAAc,CACZ,KAAMW,EAAc,EAAI,UAAY,UACpC,OAAQC,EACR,OAAQD,CAAA,CACT,EAED3B,GAAA,MAAAA,EAAY4B,EAAa,YAGzBxB,EAAkB,IAAI,GAAK,EAG3B,WAAW,IAAM,CACfY,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,CACpD,EAAG,GAAI,CACT,CACF,OAAS3S,EAAO,CACd,QAAQ,MAAM,2BAA4BA,CAAK,EAC/C2S,EAAc,CAAE,KAAM,UAAW,OAAQ,EAAG,OAAQb,EAAe,KAAM,CAC3E,QAAA,CACEW,EAAa,EAAK,CACpB,EACF,EAEMe,EAAsB,SAAY,CACtC,GAAI,EAAAtB,EAAc,OAAS,GAAK,CAAC5c,GAIjC,CAAAmd,EAAa,EAAI,EACjBE,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,EAElD,GAAI,CACF,MAAM9E,EAAS,MAAM7U,GAAa,CAChC,OAAQ,QACR,OAAQ,SACR,YAAa,MAAM,KAAKkZ,CAAa,EACrC,YAAA5c,CAAA,CACD,EAED,GAAIuY,EAAO,QAAS,CAClB,MAAMyF,EAAczF,EAAO,OAAO,OAC5B0F,EAAc1F,EAAO,OAAO,OAElC8E,EAAc,CACZ,KAAMW,EAAc,EAAI,UAAY,UACpC,OAAQC,EACR,OAAQD,CAAA,CACT,EAED3B,GAAA,MAAAA,EAAY4B,EAAa,cAGzBpB,EAAiB,IAAI,GAAK,EAC1BF,EAAiBvV,IAASA,GAAK,IAAKtG,KAAO,CAAE,GAAGA,GAAG,SAAU,EAAA,EAAQ,CAAC,EAGtE,WAAW,IAAM,CACfuc,EAAc,CAAE,KAAM,KAAM,OAAQ,EAAG,OAAQ,EAAG,CACpD,EAAG,GAAI,CACT,CACF,OAAS3S,EAAO,CACd,QAAQ,MAAM,6BAA8BA,CAAK,EACjD2S,EAAc,CAAE,KAAM,UAAW,OAAQ,EAAG,OAAQT,EAAc,KAAM,CAC1E,QAAA,CACEO,EAAa,EAAK,CACpB,EACF,EAGMgB,EAAc5B,EAAc,OAC5B6B,EAAiB5B,EAAe,KAChC6B,EAAa3B,EAAa,OAC1B4B,EAAgB1B,EAAc,KAEpC,cACG,MAAA,CAAI,UAAWhX,EAAG,YAAa0W,CAAS,EAEvC,SAAA,CAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,0CACX,SAAAjB,EAAc,CAAE,GAAI,gBAAA,CAAkB,EACzC,EACAiB,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAC/C,CAAA,EACF,EAGCyX,EAAW,OAAS,MACnB3X,EAAAA,KAAC,MAAA,CACC,UAAWG,EACT,gDACAwX,EAAW,OAAS,UAChB,+CACA,8CAAA,EAGL,SAAA,CAAAA,EAAW,OAAS,UACnBzX,EAAAA,IAAC4Y,GAAA,CAAa,UAAU,wBAAwB,EAEhD5Y,EAAAA,IAAC6Y,GAAA,CAAY,UAAU,uBAAA,CAAwB,QAEhD,OAAA,CAAK,UAAU,UACb,SAAApB,EAAW,OAAS,UACjB1Y,EACE,CAAE,GAAI,sBAAA,EACN,CAAE,MAAO0Y,EAAW,MAAA,CAAO,EAE7B1Y,EACE,CAAE,GAAI,sBAAA,EACN,CAAE,OAAQ0Y,EAAW,OAAQ,OAAQA,EAAW,MAAA,CAAO,CACzD,CACN,CAAA,CAAA,CAAA,EAKJ3X,EAAAA,KAAC,MAAA,CAAI,UAAU,wCAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,kDAEb,SAAA,CAAAE,EAAAA,IAAC,OAAI,UAAU,+CACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,sCACX,SAAAjB,EAAc,CAAE,GAAI,uBAAA,CAAyB,EAChD,EACAiB,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EACC,CAAE,GAAI,wBAAA,EACN,CAAE,MAAO0Z,EAAgB,MAAOD,CAAA,CAAY,CAC9C,CACF,CAAA,CAAA,CACF,CAAA,CACF,EAGAxY,EAAAA,IAAC,MAAA,CAAI,UAAU,+BACZ,SAAAwY,IAAgB,EACfxY,EAAAA,IAAC,MAAA,CAAI,UAAU,iDACZ,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,EAEAiB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAA4W,EAAc,IAAK9a,GAClBgE,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,sEACA4W,EAAe,IAAI/a,EAAO,IAAI,EAC1B,gBACA,mBAAA,EAEN,QAAS,IAAM+b,EAAmB/b,EAAO,IAAI,EAE7C,SAAA,CAAAkE,EAAAA,IAAC8Y,GAAA,CACC,GAAI,UAAUhd,EAAO,IAAI,GACzB,QAAS+a,EAAe,IAAI/a,EAAO,IAAI,EACvC,SAAU,IAAM+b,EAAmB/b,EAAO,IAAI,EAC9C,UAAU,gBAAA,CAAA,EAEZgE,EAAAA,KAAC,QAAA,CACC,QAAS,UAAUhE,EAAO,IAAI,GAC9B,UAAU,gCAEV,SAAA,CAAAgE,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAAlE,EAAO,KACV,EACCA,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,YAAgBlE,CAAM,EACnBA,EAAO,IACNsJ,GAAiBtJ,CAAM,EAAIA,EAAO,QAAU,EAAA,CACnD,CAAA,CAAA,CAAA,CACF,CAAA,EAlCKA,EAAO,IAAA,CAoCf,EACH,CAAA,CAEJ,EAGC0c,EAAc,GACb1Y,OAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASgW,EACT,UAAU,iBAET,SAAA/Y,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,EAE7CiB,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASiW,EACT,UAAU,iBACV,SAAUU,IAAmB,EAE5B,SAAA1Z,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAC5C,CAAA,CACF,CAAA,EAEJ,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,kDAEb,SAAA,CAAAE,EAAAA,IAAC,OAAI,UAAU,+CACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,UAAU,sCACX,SAAAjB,EAAc,CAAE,GAAI,sBAAA,CAAwB,EAC/C,EACAiB,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EACC,CAAE,GAAI,wBAAA,EACN,CAAE,MAAO4Z,EAAe,MAAOD,CAAA,CAAW,CAC5C,CACF,CAAA,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,+BACZ,SAAAvB,EACCnX,MAAC,OAAI,UAAU,wCACb,eAACsT,GAAA,CAAQ,UAAU,6CAA6C,CAAA,CAClE,EACE+D,EACFrX,MAAC,MAAA,CAAI,UAAU,4CACZ,SAAAqX,CAAA,CACH,EACEqB,IAAe,EACjB1Y,MAAC,MAAA,CAAI,UAAU,iDACZ,SAAAjB,EAAc,CAAE,GAAI,oBAAA,CAAsB,EAC7C,QAEC,MAAA,CAAI,UAAU,YACZ,SAAAgY,EAAa,IAAKjb,GACjBgE,EAAAA,KAAC,MAAA,CAEC,UAAWG,EACT,sEACAnE,EAAO,SACH,gBACA,mBAAA,EAEN,QAAS,IAAMkc,EAAkBlc,EAAO,IAAI,EAE5C,SAAA,CAAAkE,EAAAA,IAAC8Y,GAAA,CACC,GAAI,SAAShd,EAAO,IAAI,GACxB,QAASA,EAAO,SAChB,SAAU,IAAMkc,EAAkBlc,EAAO,IAAI,EAC7C,UAAU,gBAAA,CAAA,EAEZgE,EAAAA,KAAC,QAAA,CACC,QAAS,SAAShE,EAAO,IAAI,GAC7B,UAAU,gCAEV,SAAA,CAAAgE,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAAlE,EAAO,KACV,EACCA,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,WAAO,WAAA,CACV,CAAA,CAAA,CAAA,CACF,CAAA,EAhCKlE,EAAO,IAAA,CAkCf,EACH,CAAA,CAEJ,EAGC4c,EAAa,GACZ5Y,OAAC,MAAA,CAAI,UAAU,0DACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASmW,EACT,UAAU,iBAET,SAAAlZ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,EAE7CiB,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAASqW,EACT,UAAU,iBACV,SAAUQ,IAAkB,EAE3B,SAAA5Z,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAC5C,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAASsW,EACT,SAAUK,IAAmB,GAAKlB,EAClC,QAAQ,UACR,UAAU,WAET,WACCzX,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAClD,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAAC+Y,GAAA,CAAW,UAAU,cAAA,CAAe,EACpCha,EACC,CAAE,GAAI,sBAAA,EACN,CAAE,MAAO0Z,CAAA,CAAe,CAC1B,CAAA,CACF,CAAA,CAAA,EAIJzY,EAAAA,IAAC8B,EAAA,CACC,QAASyW,EACT,SAAUI,IAAkB,GAAKpB,GAAa,CAACld,EAC/C,QAAQ,UACR,UAAU,WAET,WACCyF,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACsT,GAAA,CAAQ,UAAU,2BAAA,CAA4B,EAC9CvU,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAAA,CAClD,EAEAe,EAAAA,KAAAC,EAAAA,SAAA,CACE,SAAA,CAAAC,EAAAA,IAACgZ,GAAA,CAAU,UAAU,cAAA,CAAe,EACnCja,EACC,CAAE,GAAI,wBAAA,EACN,CAAE,MAAO4Z,CAAA,CAAc,CACzB,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,CACF,CAAA,EACF,CAEJ,CCndO,SAASM,GAAiB,CAC/B,eAAAC,EACA,gBAAAC,EACA,UAAAxC,EACA,YAAAyC,EACA,aAAcC,CAChB,EAA0B,CACxB,KAAM,CAAE,cAAAta,CAAA,EAAkBC,EAAA,EACpB,CAACsa,EAAWC,CAAY,EAAIpa,EAAAA,SAAkD,cAAc,EAC5F,CAACqa,EAAeC,CAAgB,EAAIta,EAAAA,SAAyB,MAAM,EACnE,CAACua,EAAcC,CAAe,EAAIxa,EAAAA,SAA+B,CAAA,CAAE,EACnE,CAACya,EAAgBC,CAAiB,EAAI1a,EAAAA,SAAS,EAAK,EAEpD,CAAE,SAAAyV,EAAU,eAAAkF,EAAgB,UAAAC,CAAA,EAAcpc,GAAA,EAI1Cqc,EAAkBC,EAAAA,QAAQ,IAAM,CACpC,MAAMrP,EAASyO,GAAoBzE,EACnC,OAAOwE,EAAcxO,EAAO,MAAM,EAAGwO,CAAW,EAAIxO,CACtD,EAAG,CAACyO,EAAkBzE,EAAUwE,CAAW,CAAC,EAG5C5Z,EAAAA,UAAU,IAAM,EACK,SAAY,CAC7B,GAAIwa,EAAgB,SAAW,EAAG,CAChCL,EAAgB,CAAA,CAAE,EAClB,MACF,CAEAE,EAAkB,EAAI,EACtB,GAAI,CACF,MAAMzE,EAAW,MAAMnX,GAA0B+b,CAAe,EAC1DE,EAA8BF,EAAgB,IAAKhM,GAAS,CAChE,MAAMmM,EAAYnM,IAAS8L,EACrBrV,EAAOuJ,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EACpDzR,EAAU6Y,EAAS,QAAQpH,CAAI,GAAK,CAAA,EAE1C,MAAO,CACL,KAAAvJ,EACA,KAAAuJ,EACA,YAAazR,EAAQ,OACrB,aAAcA,EAAQ,OAAQpB,GAAMA,EAAE,OAAO,EAAE,OAC/C,aAAc,OACd,UAAAgf,CAAA,CAEJ,CAAC,EACDR,EAAgBO,CAAK,CACvB,OAASnV,EAAO,CACd,QAAQ,MAAM,wCAAyCA,CAAK,EAE5D4U,EACEK,EAAgB,IAAKhM,IAAU,CAC7B,KAAMA,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EACnD,KAAAA,EACA,YAAa,EACb,aAAc,EACd,UAAWA,IAAS8L,CAAA,EACpB,CAAA,CAEN,QAAA,CACED,EAAkB,EAAK,CACzB,CACF,GAEK,CACP,EAAG,CAACG,EAAiBF,CAAc,CAAC,EAGpC,MAAMM,EAAiB,CAAC,GAAGV,CAAY,EAAE,KAAK,CAACxT,EAAGmU,IAAM,CACtD,IAAIC,EAAa,EAEjB,OAAQhB,EAAA,CACN,IAAK,OACHgB,EAAapU,EAAE,KAAK,cAAcmU,EAAE,IAAI,EACxC,MACF,IAAK,cACHC,EAAapU,EAAE,YAAcmU,EAAE,YAC/B,MACF,IAAK,eACHC,EAAapU,EAAE,cAAgBmU,EAAE,aAC7B,IAAI,KAAKnU,EAAE,YAAY,EAAE,QAAA,EAAY,IAAI,KAAKmU,EAAE,YAAY,EAAE,UAC9D,EACJ,KAAA,CAGJ,OAAOb,IAAkB,MAAQc,EAAa,CAACA,CACjD,CAAC,EAGKC,EAAcjZ,GAA4B,CAC1CgY,IAAchY,EAChBmY,EAAkBhY,GAAUA,IAAS,MAAQ,OAAS,KAAM,GAE5D8X,EAAajY,CAAK,EAClBmY,EAAiB,MAAM,EAE3B,EAGMe,EAAsBngB,GAAwB,CAClD6e,GAAA,MAAAA,EAAiB7e,EACnB,EAGMogB,EAAsB,CAAC5Y,EAAqBxH,IAAwB,CACxEwH,EAAE,gBAAA,EACFsX,GAAA,MAAAA,EAAkB9e,EACpB,EAEA,OAAI0f,GAAaH,EAEb5Z,EAAAA,IAACwJ,EAAA,CAAK,UAAWvJ,EAAG,MAAO0W,CAAS,EAClC,SAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,qCAAqC,SAAA,IAAC,EACrDA,MAAC,QAAK,UAAU,qCACb,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,CAAA,CACF,CAAA,CACF,EAIAoa,EAAe,SAAW,EAE1Bpa,EAAAA,IAACwJ,EAAA,CAAK,UAAWvJ,EAAG,MAAO0W,CAAS,EAClC,SAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,cACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,iDAAA,CAAkD,EACpEnN,MAAC,KAAE,UAAU,gCACV,WAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAChD,CAAA,CAAA,CACF,CAAA,CACF,SAKDwJ,EAAA,CAAK,UAAWvJ,EAAG,kBAAmB0W,CAAS,EAE9C,SAAA,CAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,2HACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMya,EAAW,MAAM,EAChC,UAAU,kEAET,SAAA,CAAAxb,EAAc,CAAE,GAAI,uBAAwB,EAC5Cua,IAAc,QACbtZ,MAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAwZ,IAAkB,MAAQ,IAAM,GAAA,CAAI,CAAA,CAAA,CAAA,EAG7E,EACAxZ,EAAAA,IAAC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMya,EAAW,aAAa,EACvC,UAAU,kEAET,SAAA,CAAAxb,EAAc,CAAE,GAAI,0BAA2B,EAC/Cua,IAAc,eACbtZ,MAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAwZ,IAAkB,MAAQ,IAAM,GAAA,CAAI,CAAA,CAAA,CAAA,EAG7E,EACAxZ,EAAAA,IAAC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,SAAA,CACC,QAAS,IAAMya,EAAW,cAAc,EACxC,UAAU,kEAET,SAAA,CAAAxb,EAAc,CAAE,GAAI,+BAAgC,EACpDua,IAAc,gBACbtZ,MAAC,OAAA,CAAK,UAAU,kBAAmB,SAAAwZ,IAAkB,MAAQ,IAAM,GAAA,CAAI,CAAA,CAAA,CAAA,EAG7E,EACAxZ,MAAC,OAAI,UAAU,wBACZ,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,QAGC,MAAA,CAAI,UAAU,yBACZ,SAAAoa,EAAe,IAAKM,GACnB5a,EAAAA,KAAC,MAAA,CAEC,QAAS,IAAM0a,EAAmBE,EAAQ,IAAI,EAC9C,UAAWza,EACT,oGACAya,EAAQ,WAAa,kCAAA,EAIvB,SAAA,CAAA1a,EAAAA,IAAC,OAAI,UAAU,qBACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,6CAAA,CAA8C,EAChErN,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAA0a,EAAQ,KACX,EACCA,EAAQ,WACP1a,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,WAAQ,IAAA,CACX,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,aACb,SAAAF,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACmO,GAAA,CAAS,UAAU,+BAAA,CAAgC,EACpDrO,EAAAA,KAAC,OAAA,CAAK,UAAU,0BACb,SAAA,CAAA4a,EAAQ,YAAY,IAAE3b,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,EACxE,EACAe,EAAAA,KAACoI,EAAA,CACC,QAAQ,UACR,UAAWjI,EACT,UACAya,EAAQ,aAAe,EAAI,iCAAmC,uBAAA,EAG/D,SAAA,CAAAA,EAAQ,aAAa,IAAE3b,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAAA,CACpE,CAAA,CACF,CAAA,CACF,QAGC,MAAA,CAAI,UAAU,aACb,SAAAe,EAAAA,KAAC,MAAA,CAAI,UAAU,wDACb,SAAA,CAAAE,EAAAA,IAAC2a,GAAA,CAAM,UAAU,SAAA,CAAU,EAC3B3a,EAAAA,IAAC,OAAA,CACE,SAAA0a,EAAQ,aACLE,GAAoB,IAAI,KAAKF,EAAQ,YAAY,EAAG,CAAE,UAAW,EAAA,CAAM,EACvE,GAAA,CACN,CAAA,CAAA,CACF,CAAA,CACF,EAGA1a,EAAAA,IAAC,MAAA,CAAI,UAAU,oCACb,SAAAA,EAAAA,IAAC,SAAA,CACC,QAAU6B,GAAM4Y,EAAoB5Y,EAAG6Y,EAAQ,IAAI,EACnD,UAAU,iDACV,MAAO3b,EAAc,CAAE,GAAI,gCAAiC,EAE5D,SAAAiB,EAAAA,IAAC6a,GAAA,CAAa,UAAU,+BAAA,CAAgC,CAAA,CAAA,CAC1D,CACF,CAAA,CAAA,EArEKH,EAAQ,IAAA,CAuEhB,EACH,EAGA1a,EAAAA,IAAC,MAAA,CAAI,UAAU,6EACZ,SAAAjB,EACC,CAAE,GAAI,yBAAA,EACN,CAAE,MAAOqb,EAAe,MAAA,CAAO,CACjC,CACF,CAAA,EACF,CAEJ,CC7PO,SAASU,GAAqB,CACnC,gBAAAC,EACA,UAAApE,CACF,EAA8B,CAC5B,KAAM,CAAE,cAAA5X,CAAA,EAAkBC,EAAA,EACpB,CAACgc,EAAqBC,CAAsB,EAAI9b,EAAAA,SAAwB,IAAI,EAC5E,CAAC+b,EAAcC,CAAe,EAAIhc,EAAAA,SAA+B,CAAA,CAAE,EACnE,CAACic,EAAmBC,CAAoB,EAAIlc,EAAAA,SAAS,EAAK,EAE1D,CAAE,SAAAyV,EAAU,eAAAkF,EAAgB,kBAAA5b,EAAmB,kBAAmBod,CAAA,EACtE3d,GAAA,EACI,CAAE,aAAA4d,EAAc,WAAAC,CAAA,EAAe7e,GAAA,EAG/B8e,EAAoB7G,EAAS,OAAQ8G,GAAMA,IAAM5B,CAAc,EAG/D6B,EAAsB,MAAOthB,GAAwB,CACzD4gB,EAAuB5gB,CAAW,EAClCghB,EAAqB,EAAI,EAEzB,GAAI,CACF,MAAMjG,EAAW,MAAMlX,EAAkB,CAAC7D,CAAW,CAAC,EAChDkC,EAAgC,CAAA,EAEtC,SAAW,CAACyR,EAAM4N,CAAU,IAAK,OAAO,QAAQxG,EAAS,OAAO,EAAG,CACjE,MAAMyG,EAAc7N,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EACjE,UAAWlS,KAAW8f,EACpBrf,EAAQ,KAAK,CACX,KAAMT,EAAO,KACb,QAASA,EAAO,QAChB,YAAasI,GAAgBtI,CAAM,EAC/BA,EAAO,IACNsJ,GAAiBtJ,CAAM,EAAIA,EAAO,QAAU,GACjD,UAAWA,EAAO,UAClB,YAAakS,EACb,YAAA6N,EACA,eAAgB/f,CAAA,CACjB,CAEL,CAEAqf,EAAgB5e,CAAO,CACzB,OAASwI,EAAO,CACd,QAAQ,MAAM,0CAA2CA,CAAK,EAC9DoW,EAAgB,CAAA,CAAE,CACpB,QAAA,CACEE,EAAqB,EAAK,CAC5B,CACF,EAGMS,EAAqB,MAAOhgB,GAA+B,CAC/D,GAAI,CAEF,MAAMigB,EAAa,GAAGjgB,EAAO,WAAW,IAAIA,EAAO,IAAI,GAAG,YAAA,EAAc,QAAQ,OAAQ,GAAG,EAGrFkgB,EAA4B,CAChC,GAAGlgB,EAAO,eACV,KAAMigB,EACN,MAAO,SAAA,EAGT,MAAMR,EAAaS,CAAc,EAEjCjB,GAAA,MAAAA,EAAkBgB,EAAYjgB,EAAO,YACvC,OAASiJ,EAAO,CACd,QAAQ,MAAM,2BAA4BA,CAAK,CACjD,CACF,EAEMgV,EAAYqB,GAAqBE,GAAoBE,EACrDS,EAAsBjB,EACxBA,EAAoB,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,EACnD,KAEJ,cACGxR,EAAA,CAAK,UAAWvJ,EAAG,MAAO0W,CAAS,EAElC,SAAA,CAAA7W,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC2N,GAAA,CAAW,UAAU,sBAAA,CAAuB,EAC7C3N,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EACAA,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS,IAAMkZ,GAAuBW,EAAoBX,CAAmB,EAC7E,SAAU,CAACA,GAAuBjB,EAClC,UAAU,MAEV,eAACmC,GAAA,CAAU,UAAWjc,EAAG,UAAW8Z,GAAa,cAAc,CAAA,CAAG,CAAA,CAAA,CACpE,EACF,EAGA/Z,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,+BAAA,CAAiC,EACxD,EAGAF,EAAAA,KAAC,MAAA,CAAI,UAAU,OACb,SAAA,CAAAE,EAAAA,IAAC,QAAA,CAAM,UAAU,iDACd,SAAAjB,EAAc,CAAE,GAAI,iCAAA,CAAmC,EAC1D,SACC2I,GAAA,CAAO,MAAOsT,GAAuB,GAAI,cAAeW,EACvD,SAAA,CAAA3b,EAAAA,IAAC2H,GAAA,CAAc,UAAU,SACvB,SAAA3H,EAAAA,IAAC4H,GAAA,CACC,YAAa7I,EAAc,CAAE,GAAI,6CAA8C,CAAA,CAAA,EAEnF,QACC8I,GAAA,CACE,SAAA4T,EAAkB,SAAW,EAC5Bzb,EAAAA,IAAC,OAAI,UAAU,gDACZ,WAAc,CAAE,GAAI,+BAAgC,CAAA,CACvD,EAEAyb,EAAkB,IAAKzN,GAAS,CAC9B,MAAMvJ,EAAOuJ,EAAK,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAA,GAASA,EAC1D,aACGlG,GAAA,CAAsB,MAAOkG,EAC5B,SAAAlO,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC2N,GAAA,CAAW,UAAU,+BAAA,CAAgC,EACtD3N,EAAAA,IAAC,OAAA,CAAK,UAAU,WAAY,SAAAyE,CAAA,CAAK,CAAA,CAAA,CACnC,GAJeuJ,CAKjB,CAEJ,CAAC,CAAA,CAEL,CAAA,CAAA,CACF,CAAA,EACF,EAGCgN,SACE,MAAA,CAAI,UAAU,YACZ,SAAAI,EACCtb,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,UAAU,qCAAqC,SAAA,IAAC,EACrDA,MAAC,QAAK,UAAU,qCACb,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,CAAA,CACF,EACEkb,EAAa,SAAW,EAC1Blb,EAAAA,IAAC,MAAA,CAAI,UAAU,gFACZ,SAAAjB,EACC,CAAE,GAAI,6BAAA,EACN,CAAE,QAASkd,CAAA,CAAoB,CACjC,CACF,EAEAjc,EAAAA,IAAC,MAAA,CAAI,UAAU,qCACZ,SAAAkb,EAAa,IAAKpf,GACjBgE,EAAAA,KAAC,MAAA,CAEC,UAAU,yFAEV,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,+CACb,SAAAlE,EAAO,KACV,EACCA,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,UAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mDACV,WAAO,YACV,EACAF,EAAAA,KAAC,IAAA,CAAE,UAAU,yCACX,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,SAAAlE,EAAO,YAAY,EAClDkE,EAAAA,IAACqN,GAAA,CAAa,UAAU,qBAAA,CAAsB,EAC9CrN,EAAAA,IAAC,OAAA,CAAK,UAAU,YAAa,WAAO,WAAA,CAAY,CAAA,CAAA,CAClD,CAAA,EACF,EACAF,EAAAA,KAACgC,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMga,EAAmBhgB,CAAM,EACxC,SAAU0f,EACV,UAAU,gBAEV,SAAA,CAAAxb,EAAAA,IAAC8O,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B/P,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CAAA,CAAA,CACnD,CAAA,EAhCK,GAAGjD,EAAO,WAAW,IAAIA,EAAO,IAAI,EAAA,CAkC5C,EACH,CAAA,CAEJ,EAIDkf,GAAuBE,EAAa,OAAS,GAC5Clb,EAAAA,IAAC,IAAA,CAAE,UAAU,qCACV,SAAAjB,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EAEJ,CAEJ,CClLA,SAASqJ,GAAgB7G,EAAuB,CAC9C,MAAI,CAACA,GAASA,EAAM,QAAU,EAAU,OACjCA,EAAM,UAAU,EAAG,CAAC,EAAI,MACjC,CAEA,SAAS4a,GAAc,CAAE,OAAArgB,EAAQ,WAAAwM,EAAY,eAAAC,EAAgB,SAAAG,EAAU,OAAA0T,EAAQ,SAAA7N,EAAU,iBAAAsB,EAAkB,aAAAwM,GAAoC,CAC7I,KAAM,CAAE,cAAAtd,CAAA,EAAkBC,EAAA,EACpB,CAAC+J,EAAkBC,CAAmB,EAAI7J,EAAAA,SAAkC,CAAA,CAAE,EAE9E8J,EAAS7E,GAAgBtI,CAAM,EAC/BoN,EAAU9D,GAAiBtJ,CAAM,EAGjCqN,EAAmB,IAAM,OAC7B,OAAIF,EACKnN,EAAO,IAET,GAAGA,EAAO,OAAO,MAAIlB,EAAAkB,EAAO,OAAP,YAAAlB,EAAa,KAAK,OAAQ,EAAE,GAAG,KAAA,CAC7D,EAGMwO,EAAiB,IAAkE,CACvF,GAAI,CAACH,EAAQ,MAAO,CAAA,EAEpB,MAAMtI,EAAsE,CAAA,EAG5E,OAAI7E,EAAO,SACT,OAAO,QAAQA,EAAO,OAAO,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CACxDZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAICzF,EAAO,aACT,OAAO,QAAQA,EAAO,WAAW,EAAE,QAAQ,CAAC,CAAC2I,EAAMlD,CAAK,IAAM,CAC5DZ,EAAQ,KAAK,CAAE,KAAA8D,EAAM,MAAAlD,CAAA,CAAO,CAC9B,CAAC,EAICzF,EAAO,mBACT6E,EAAQ,KAAK,CACX,KAAM,gBACN,MAAO,WAAW7E,EAAO,iBAAiB,GAC1C,SAAU,EAAA,CACX,EAGI6E,CACT,EAGM0I,EAAqBnE,GAAuB,CAChD8D,EAAoBvH,IAAS,CAC3B,GAAGA,EACH,CAACyD,CAAU,EAAG,CAACzD,EAAKyD,CAAU,CAAA,EAC9B,CACJ,EAEA,OACEpF,OAAC0J,GAAK,UAAWvJ,EAAG,kBAAmB,CAACnE,EAAO,SAAW,YAAY,EAEpE,SAAA,CAAAkE,EAAAA,IAAC,MAAA,CACC,UAAU,yDACV,QAASuI,EAET,SAAAzI,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAE,MAAC,OAAI,UAAWC,EACd,iBACAnE,EAAO,QAAU,gBAAkB,UAAA,EAEnC,SAAAkE,EAAAA,IAACyJ,GAAA,CAAO,UAAWxJ,EACjB,UACAnE,EAAO,QAAU,eAAiB,uBAAA,EACjC,CAAA,CACL,SACC,MAAA,CACC,SAAA,CAAAgE,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,UAAU,sCACb,SAAAlE,EAAO,KACV,EAECmN,GACCnJ,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,wCACjC,SAAA,CAAAlI,EAAAA,IAAC0J,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9B3K,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEFiB,EAAAA,IAACkI,EAAA,CAAM,QAASpM,EAAO,QAAU,SAAW,UAAY,YAAa,UAAU,UAC5E,SAAAA,EAAO,QAAU,SAChBgE,OAAAC,EAAAA,SAAA,CAAE,SAAA,CAAAC,EAAAA,IAACgI,GAAA,CAAM,UAAU,cAAA,CAAe,EAAGjJ,EAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAAA,CAAE,EAE/Ee,EAAAA,KAAAC,EAAAA,SAAA,CAAE,SAAA,CAAAC,EAAAA,IAACmN,GAAA,CAAO,UAAU,cAAA,CAAe,EAAGpO,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAAE,CAAA,CAErF,EACCsd,GACCvc,EAAAA,KAACoI,EAAA,CAAM,QAAQ,UAAU,UAAU,4CACjC,SAAA,CAAAlI,EAAAA,IAACoN,GAAA,CAAc,UAAU,cAAA,CAAe,EACvCrO,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,EAEDjD,EAAO,SACNkE,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,yBAChC,SAAAnJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EAEJ,EACAiB,MAAC,KAAE,UAAU,iEAAiE,MAAOmJ,EAAA,EAClF,YAAiB,CACpB,CAAA,CAAA,CACF,CAAA,EACF,EACArJ,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACF6G,EAAS5M,EAAO,KAAM,CAACA,EAAO,OAAO,CACvC,EAEC,SAAAA,EAAO,QAAUkE,EAAAA,IAAC4J,GAAA,CAAM,UAAU,yBAAyB,EAAK5J,EAAAA,IAAC8J,GAAA,CAAS,UAAU,SAAA,CAAU,CAAA,CAAA,EAEjG9J,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACFgO,EAAiB/T,CAAM,CACzB,EACA,MAAOiD,EAAc,CAAE,GAAI,uCAAwC,EAEnE,SAAAiB,EAAAA,IAACsc,GAAA,CAAa,UAAU,sBAAA,CAAuB,CAAA,CAAA,EAEjDtc,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACFua,EAAOtgB,CAAM,CACf,EAEA,SAAAkE,EAAAA,IAACuc,GAAA,CAAK,UAAU,SAAA,CAAU,CAAA,CAAA,EAE5Bvc,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAUD,GAAM,CACdA,EAAE,gBAAA,EACF0M,EAASzS,CAAM,CACjB,EAEA,SAAAkE,EAAAA,IAACiC,GAAA,CAAO,UAAU,0BAAA,CAA2B,CAAA,CAAA,EAE9CqG,QACE0B,GAAA,CAAU,UAAU,gCAAgC,EAErDhK,MAACiK,GAAA,CAAY,UAAU,+BAAA,CAAgC,CAAA,CAAA,CAE3D,CAAA,CAAA,CACF,CAAA,CAAA,EAID3B,GACCxI,EAAAA,KAAC,MAAA,CAAI,UAAU,mDAEZ,SAAA,CAAAmJ,GACCnJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,cAAA,CAAgB,EAAE,EACzFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,0EACb,WAAO,GAAA,CACV,CAAA,EACF,EAGCoJ,EAAA,EAAiB,OAAS,UACxB,MAAA,CACC,SAAA,CAAApJ,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,kBAAA,CAAoB,EAAE,EAC7FiB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAAoJ,EAAA,EAAiB,IAAKzH,GACrB7B,EAAAA,KAAC,MAAA,CAAsB,UAAU,kCAC/B,SAAA,CAAAE,MAACkI,GAAM,QAAQ,YAAY,UAAU,YAAa,WAAO,KAAK,EAC9DlI,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAA+I,EAAiBpH,EAAO,IAAI,EAAIA,EAAO,MAAQyG,GAAgBzG,EAAO,KAAK,EAC9E,EACA3B,EAAAA,IAAC8B,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,cACV,QAAS,IAAMuH,EAAkB1H,EAAO,IAAI,EAC5C,MAAOoH,EAAiBpH,EAAO,IAAI,EAC/B5C,EAAc,CAAE,GAAI,oBAAA,CAAsB,EAC1CA,EAAc,CAAE,GAAI,qBAAsB,EAE7C,SAAAgK,EAAiBpH,EAAO,IAAI,EAC3B3B,EAAAA,IAAC+B,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAElD/B,EAAAA,IAACgC,GAAA,CAAI,UAAU,+BAAA,CAAgC,CAAA,CAAA,EAGlDL,EAAO,UACN3B,EAAAA,IAACkI,EAAA,CAAM,QAAQ,UAAU,UAAU,wBAChC,SAAAnJ,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAC1C,CAAA,GAxBM4C,EAAO,IA0BjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAIDuH,GACCpJ,EAAAA,KAAAC,WAAA,CAEE,SAAA,CAAAD,OAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,aAAA,CAAe,EAAE,EACxFiB,EAAAA,IAAC,OAAA,CAAK,UAAU,gEACb,WAAO,OAAA,CACV,CAAA,EACF,EAGClE,EAAO,MAAQA,EAAO,KAAK,OAAS,UAClC,MAAA,CACC,SAAA,CAAAkE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,UAAA,CAAY,EAAE,QACpF,MAAA,CAAI,UAAU,uBACZ,SAAAjD,EAAO,KAAK,IAAI,CAACmM,EAAKvD,IACrB1E,EAAAA,IAACkI,EAAA,CAAgB,QAAQ,UAAU,UAAU,oBAC1C,SAAAD,CAAA,EADSvD,CAEZ,CACD,CAAA,CACH,CAAA,EACF,EAID5I,EAAO,KAAO,OAAO,KAAKA,EAAO,GAAG,EAAE,OAAS,GAC9CgE,EAAAA,KAAC,MAAA,CACC,SAAA,CAAAE,EAAAA,IAAC,IAAA,CAAE,UAAU,qCAAsC,SAAAjB,EAAc,CAAE,GAAI,SAAA,CAAW,EAAE,QACnF,MAAA,CAAI,UAAU,YACZ,SAAA,OAAO,QAAQjD,EAAO,GAAG,EAAE,IAAI,CAAC,CAAC0K,EAAKjF,CAAK,IAC1CzB,EAAAA,KAAC,MAAA,CAAc,UAAU,kCACvB,SAAA,CAAAE,MAACkI,EAAA,CAAM,QAAQ,YAAY,UAAU,YAAa,SAAA1B,EAAI,EACtDxG,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,IAAC,EACzCA,EAAAA,IAAC,OAAA,CAAK,UAAU,iEACb,SAAAuB,CAAA,CACH,CAAA,CAAA,EALQiF,CAMV,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EAEJ,EAID6V,GACCvc,EAAAA,KAAC,MAAA,CAAI,UAAU,8GACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+DACb,SAAA,CAAAE,EAAAA,IAACoN,GAAA,CAAc,UAAU,SAAA,CAAU,EACnCpN,MAAC,QAAK,UAAU,sBAAuB,WAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAE,CAAA,EACrF,EACAA,MAAC,KAAE,UAAU,kDACV,WAAc,CAAE,GAAI,4BAA8B,CAAE,MAAOjB,EAAc,CAAE,GAAI,aAAasd,EAAa,cAAc,EAAA,CAAI,CAAA,CAAG,EACjI,EACArc,MAAC,KAAE,UAAU,kDACV,WAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EAEJ,CAEJ,CAIO,SAASwc,IAAiB,WAC/B,KAAM,CAAE,cAAAzd,CAAA,EAAkBC,EAAA,EACpB,CAACyd,EAAWC,CAAY,EAAIvd,EAAAA,SAAgD,SAAS,EACrF,CAAC2Q,EAAaC,CAAc,EAAI5Q,EAAAA,SAAS,EAAE,EAC3C,CAACwd,EAAaC,CAAc,EAAIzd,EAAAA,SAAuC,KAAK,EAC5E,CAAC0d,EAAiBC,CAAkB,EAAI3d,EAAAA,SAAsB,IAAI,GAAK,EACvE,CAAC4d,EAAYC,CAAa,EAAI7d,EAAAA,SAAS,EAAK,EAC5C,CAAC8d,EAAeC,CAAgB,EAAI/d,EAAAA,SAAgC,MAAS,EAC7E,CAACge,EAASC,CAAU,EAAIje,EAAAA,SAAkB,QAAQ,EAClD,CAACke,EAAsBC,CAAuB,EAAIne,EAAAA,SAAsB,IAAI,GAAK,EACjF,CAACoe,EAAwBC,CAAyB,EAAIre,EAAAA,SAAS,EAAK,EACpE,CAACse,EAAwBC,CAAyB,EAAIve,EAAAA,SAAgC,MAAS,EAE/FhF,EAAcC,GAAA,EACdujB,EAAgBjb,GAAA,EAEhB,CACJ,QAAAnG,EACA,eAAA5B,EACA,cAAAE,EACA,UAAAE,EACA,WAAA6iB,EACA,aAAAC,EACA,UAAA9D,EACA,WAAA+D,EACA,QAAA1iB,CAAA,EACErB,GAAc,CAChB,MAAO4iB,IAAgB,MAAQ,OAAYA,CAAA,CAC5C,EAGKoB,EAAatjB,GAAS,CAC1B,SAAU,CAAC,iBAAiB,EAC5B,QAASmd,GACT,QAASuF,IAAY,QACrB,UAAW,IAAS,GAAA,CACrB,EAEK9iB,EAAcC,GAAiBC,EAAiB,EAGhDyjB,GAAcvjB,GAAS,CAC3B,SAAU,CAAC,eAAgBJ,CAAW,EACtC,QAAS,IAAM4jB,GAAkB5jB,GAAe,MAAS,EACzD,QAAS8iB,IAAY,SACrB,UAAW,IAAS,GAAA,CACrB,EAGKe,GAAmBzjB,GAAS,CAChC,SAAU,CAAC,mBAAmB,EAC9B,QAAS0jB,GACT,QAAShB,IAAY,QACrB,UAAW,IAAS,GAAA,CACrB,EAEK,CACJ,aAAAiB,GACA,aAAAC,EAAA,EACE1hB,GAAA,EAEE2hB,GAAgB7iB,GAAuB,CAC3CqhB,EAAoBrb,GAAS,CAC3B,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAIjG,CAAU,EACrBiG,EAAK,OAAOjG,CAAU,EAEtBiG,EAAK,IAAIjG,CAAU,EAEdiG,CACT,CAAC,CACH,EAEM6c,GAAqB9iB,GAAuB,CAChD6hB,EAAyB7b,GAAS,CAChC,MAAMC,EAAO,IAAI,IAAID,CAAI,EACzB,OAAIC,EAAK,IAAIjG,CAAU,EACrBiG,EAAK,OAAOjG,CAAU,EAEtBiG,EAAK,IAAIjG,CAAU,EAEdiG,CACT,CAAC,CACH,EAEM4H,GAAe,CAAC7N,EAAoBvB,IAAqB,CAC7DkkB,GAAa3iB,EAAYvB,CAAO,CAClC,EAEMyU,EAAe,MAAO7S,GAAsB,CAChD,GAAI,QAAQiD,EAAc,CAAE,GAAI,mBAAA,EAAuB,CAAE,KAAMjD,EAAO,IAAA,CAAM,CAAC,EAC3E,GAAI,CACF,MAAMuiB,GAAaviB,EAAO,KAAMA,EAAO,KAAK,EAC5C6hB,EAAc,QACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CjD,EAAO,IAAA,EAETV,EAAA,CACF,OAAS2J,EAAO,CACd,QAAQ,MAAM,+BAAgCA,CAAK,EACnD4Y,EAAc,MACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CAEJ,EAEMyZ,GAAc1iB,GAAsB,CACxCohB,EAAiBphB,CAAM,EACvBkhB,EAAc,EAAI,CACpB,EAEMyB,GAAiB,IAAM,CAC3BvB,EAAiB,MAAS,EAC1BF,EAAc,EAAI,CACpB,EAEM0B,GAAoB,IAAM,CAC9B1B,EAAc,EAAK,EACnBE,EAAiB,MAAS,CAC5B,EAEMyB,GAAmB,IAAM,CAC7B3B,EAAc,EAAK,EACnBE,EAAiB,MAAS,EAC1B9hB,EAAA,CACF,EAEMwjB,GAAoBxc,GAAkB,CAC1Cgb,EAAWhb,CAAI,CACjB,EAGMyc,GAAYb,GAAY,MAAQ,CACpC,YAAa,GACb,aAAc,CAAA,EACd,YAAa,OACb,YAAa,OACb,cAAe,OACf,gBAAiB,CAAA,CAAC,EAGdc,EAAiB,CAAC,eAAgBzkB,CAAW,EAE7C0kB,EAAsB,MAAOxR,EAAcrT,IAAqB,CAEpE,MAAM8kB,EAAgB7kB,EAAY,aAA2B2kB,CAAc,GAAKD,GAC1EI,EAAeD,EAAc,aAC7BE,EAAiB/kB,EAAY,aAA2B2kB,CAAc,EAEtEK,GAAejlB,EAChB+kB,EAAa,SAAS1R,CAAI,EAAI0R,EAAe,CAAC,GAAGA,EAAc1R,CAAI,EACpE0R,EAAa,OAAQ9hB,GAAMA,IAAMoQ,CAAI,EAGzCpT,EAAY,aAAa2kB,EAAiBziB,GACnCA,GACE,CAAE,GAAGA,EAAK,aAAc8iB,EAAA,CAChC,EAED,GAAI,CACF,MAAM1S,GAAgB,CAAE,GAAGuS,EAAe,aAAcG,GAAc,CACxE,OAASpa,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,6BAA8BA,CAAK,EACjD5K,EAAY,aAAa2kB,EAAgBI,CAAc,CACzD,CACAlB,GAAY,QAAA,CACd,EAEMoB,EAAwB,MAAO1jB,GAAkC,CAErE,MAAMwjB,EAAiB/kB,EAAY,aAA2B2kB,CAAc,EAG5E3kB,EAAY,aAAa2kB,EAAiBziB,GACnCA,GACE,CAAE,GAAGA,EAAK,GAAGX,CAAA,CACrB,EAGD,MAAMsjB,EAAgB7kB,EAAY,aAA2B2kB,CAAc,GAAKD,GAEhF,GAAI,CAEF,MAAMpS,GAAgB,CACpB,aAAcuS,EAAc,aAC5B,YAAaA,EAAc,YAC3B,YAAaA,EAAc,YAC3B,cAAeA,EAAc,aAAA,CAC9B,CACH,OAASja,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,+BAAgCA,CAAK,EACnD5K,EAAY,aAAa2kB,EAAgBI,CAAc,CACzD,CACAlB,GAAY,QAAA,CACd,EAEMqB,EAAmB,IAAM,CAC7BrB,GAAY,QAAA,CACd,EAGMsB,GAAcrF,EAAAA,QAAQ,IAAM,CAChC,MAAMsF,MAAU,IAChB,UAAWC,KAAKzkB,EAAWwkB,EAAI,IAAIC,EAAE,KAAMA,CAAC,EAC5C,OAAOD,CACT,EAAG,CAACxkB,CAAS,CAAC,EAGR0kB,GAA0B,MAAOjmB,GAAgC,CACrE,GAAI,CACF,MAAM2S,GAAc3S,EAAOA,IAAU,UAAYa,GAAe,OAAY,MAAS,EACrF2jB,GAAY,QAAA,CACd,OAASjZ,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,2BAAA,CAA6B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC9H,QAAQ,MAAM,sCAAuCA,CAAK,CAC5D,CACF,EAEM2a,GAA8B,MAAOlmB,GAAgC,CACzE,GAAI,CACF,MAAMmmB,GAAyBnmB,EAAOA,IAAU,UAAYa,GAAe,OAAY,MAAS,EAChG2jB,GAAY,QAAA,EACZ7jB,EAAY,kBAAkB,CAAE,SAAU,CAAC,YAAY,EAAG,CAC5D,OAAS4K,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,6BAAA,CAA+B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAChI,QAAQ,MAAM,0CAA2CA,CAAK,CAChE,CACF,EAGM6a,GAAiB1B,GAAiB,MAAQ,CAC9C,YAAa,GACb,aAAc,CAAA,EACd,YAAa,OACb,YAAa,OACb,cAAe,OACf,gBAAiB,CAAA,CAAC,EAGd2B,GAA2B,MAAOtS,EAAcrT,IAAqB,CACzE,MAAM8kB,EAAgB7kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,GAAKylB,GACjFX,EAAeD,EAAc,aAC7BE,EAAiB/kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,EAE7EglB,GAAejlB,EAChB+kB,EAAa,SAAS1R,CAAI,EAAI0R,EAAe,CAAC,GAAGA,EAAc1R,CAAI,EACpE0R,EAAa,OAAQ9hB,GAAMA,IAAMoQ,CAAI,EAEzCpT,EAAY,aAAa,CAAC,mBAAmB,EAAIkC,GAC1CA,GACE,CAAE,GAAGA,EAAK,aAAc8iB,EAAA,CAChC,EAED,GAAI,CACF,MAAM3S,GAAwB,CAAE,GAAGwS,EAAe,aAAcG,GAAc,CAChF,OAASpa,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,qCAAsCA,CAAK,EACzD5K,EAAY,aAAa,CAAC,mBAAmB,EAAG+kB,CAAc,CAChE,CACAhB,GAAiB,QAAA,CACnB,EAEM4B,GAA6B,MAAOpkB,GAAkC,CAC1E,MAAMsjB,EAAgB7kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,GAAKylB,GACjFV,EAAiB/kB,EAAY,aAA2B,CAAC,mBAAmB,CAAC,EAEnFA,EAAY,aAAa,CAAC,mBAAmB,EAAIkC,GAC1CA,GACE,CAAE,GAAGA,EAAK,GAAGX,CAAA,CACrB,EAED,GAAI,CACF,MAAM8Q,GAAwB,CAAE,GAAGwS,EAAe,GAAGtjB,EAAQ,CAC/D,OAASqJ,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,uCAAwCA,CAAK,EAC3D5K,EAAY,aAAa,CAAC,mBAAmB,EAAG+kB,CAAc,CAChE,CACAhB,GAAiB,QAAA,CACnB,EAEM6B,GAAwB,IAAM,CAClC7B,GAAiB,QAAA,CACnB,EAGM/M,GAAyBrL,GAAkB,CAC/C,MAAMtB,GAAesB,GAAA,YAAAA,EAAU,eAAgB,CAAA,EACzCmD,EACJzE,EAAa,OAAS,QACtBA,EAAa,YAAc,QAC3B,OAAOA,EAAa,KAAQ,SAG5B0Y,EADEjU,EACe,CACf,KAAMnD,EAAS,KACf,UAAW,OACX,IAAKtB,EAAa,KAAO,GACzB,MAAO,UACP,QAAS,EAAA,EAGM,CACf,KAAMsB,EAAS,KACf,UAAW,QACX,QAAStB,EAAa,QACtB,KAAMA,EAAa,MAAQ,CAAA,EAC3B,IAAKA,EAAa,IAClB,MAAO,UACP,QAAS,EAAA,CATV,EAYHwY,EAAc,EAAI,CACpB,EAEMgD,GAA8BlkB,GAAsB,CACxD4hB,EAA0B5hB,CAAM,EAChC0hB,EAA0B,EAAI,CAChC,EAEMyC,GAAuB,MAC3Bxb,EACA/K,EACA4V,EACA9K,IACG,CACH,GAAI,CACF,MAAMoO,EAAS,MAAMzL,GAAgB,CACnC,KAAA1C,EACA,YAAa6K,GAAe,OAC5B,SAAU5V,GAAY,SACtB,aAAc,CACZ,QAAS8K,EAAa,QACtB,KAAMA,EAAa,KAAK,OAAS,EAAIA,EAAa,KAAO,OACzD,IAAK,OAAO,KAAKA,EAAa,GAAG,EAAE,OAAS,EAAIA,EAAa,IAAM,MAAA,CACrE,CACD,EACGoO,EAAO,SACT+K,EAAc,QACZ5e,EAAc,CAAE,GAAI,qCAAsC,EAC1D0F,CAAA,EAEF+Y,EAA0B,EAAK,EAC/BE,EAA0B,MAAS,GAEnCC,EAAc,MACZ5e,EAAc,CAAE,GAAI,mCAAoC,EACxD6T,EAAO,OAAS,EAAA,CAGtB,OAAS7N,EAAO,CACd4Y,EAAc,MACZ5e,EAAc,CAAE,GAAI,mCAAoC,EACxDgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CACF,EAGMmb,GAAoB,MAAOzkB,GAAuB,CACtD,GAAI,CACF,MAAM0kB,GAAkB1kB,CAAU,EAClCkiB,EAAc,QACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CtD,CAAA,EAEFsiB,EAAW,QAAA,CACb,OAAShZ,EAAO,CACd,QAAQ,MAAM,qCAAsCA,CAAK,EACzD4Y,EAAc,MACZ5e,EAAc,CAAE,GAAI,qBAAsB,EAC1CgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAA,CAEzD,CACF,EAEMqb,GAAoB,MAAO3kB,EAAoBvB,IAAqB,CACxE,GAAI,CACF,MAAMmmB,GAAkB5kB,EAAYvB,CAAO,EAC3C6jB,EAAW,QAAA,CACb,OAAShZ,EAAO,CACd4Y,EAAc,MAAM5e,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAGgG,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAC,EAC7H,QAAQ,MAAM,qCAAsCA,CAAK,CAC3D,CACF,EAGMub,GAAkB/jB,EAAQ,OAAQpB,GAAM,UAC5C,MAAMxB,EAAQmW,EAAY,YAAA,EACpByQ,EAAYplB,EAAE,KAAK,YAAA,EAAc,SAASxB,CAAK,EAE/C6mB,EAAiBpc,GAAgBjJ,CAAC,GACpCP,EAAAO,EAAE,MAAF,YAAAP,EAAO,cAAc,SAASjB,IAC9BmB,GAAAK,EAAE,UAAF,YAAAL,GAAW,cAAc,SAASnB,GACtC,OAAO4mB,GAAaC,CACtB,CAAC,EAGKzJ,KAAenc,GAAAmjB,EAAW,OAAX,YAAAnjB,GAAiB,UAAW,CAAA,EAC3C6lB,KAAkB3lB,GAAAijB,EAAW,OAAX,YAAAjjB,GAAiB,aAAc,GACjD4lB,GAAuB3J,GAAa,OAAQ5b,GAAM,UACtD,MAAMxB,EAAQmW,EAAY,YAAA,EACpByQ,EAAYplB,EAAE,KAAK,YAAA,EAAc,SAASxB,CAAK,EAE/C6mB,EAAiBpc,GAAgBjJ,CAAC,GACpCP,EAAAO,EAAE,MAAF,YAAAP,EAAO,cAAc,SAASjB,IAC9BmB,GAAAK,EAAE,UAAF,YAAAL,GAAW,cAAc,SAASnB,GACtC,OAAO4mB,GAAaC,CACtB,CAAC,EAEKG,GAAiBxD,IAAY,QAAUuD,GAAuBJ,GAC9DM,GAAkBzD,IAAY,QAAUE,EAAuBR,EAC/DgE,GAAsB1D,IAAY,QAAUoB,GAAoBD,GAChEwC,GAAmB3D,IAAY,QAAUY,EAAW,UAAYhE,EAChEgH,GAAoB5D,IAAY,QAAUY,EAAW,WAAaD,EAClEkD,GAAiB7D,IAAY,SAAW,IAAMY,EAAW,WAAa3iB,EAE5E,OACE0E,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,qEACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAA,EAAAA,KAAC,KAAA,CAAG,UAAU,6DACZ,SAAA,CAAAE,EAAAA,IAACyJ,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACxC1K,EAAc,CAAE,GAAI,WAAA,CAAa,CAAA,EACpC,EACAiB,MAAC,KAAE,UAAU,6BACV,WAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAC1C,CAAA,EACF,EAEAA,EAAAA,IAAC,MAAA,CAAI,UAAU,qBACb,SAAAA,EAAAA,IAACihB,GAAA,CACC,YAAa9D,EACb,aAAcyB,GACd,gBAAA6B,EAAA,CAAA,CACF,CACF,CAAA,EACF,EACA3gB,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAACgC,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAMkf,KAAkB,SAAUD,GACnE,SAAA,CAAA/gB,MAACkc,IAAU,UAAWjc,EAAG,eAAgB8gB,IAAqB,cAAc,EAAG,EAC9EhiB,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,EACjD,EACCoe,IAAY,UACXrd,OAACgC,EAAA,CAAO,QAAS2c,GACf,SAAA,CAAAze,EAAAA,IAACkC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BnD,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAA,CAC1C,CAAA,CAAA,CAEJ,CAAA,EACF,EAGAiB,EAAAA,IAACkhB,GAAA,CACC,MAAOzE,EACP,cAAgBlb,GAAUmb,EAAanb,CAA8C,EACrF,KAAM,CACJ,CAAE,MAAO,YAAa,MAAOxC,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EACvE,CAAE,MAAO,UAAW,MAAOA,EAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,EACnE,CAAE,MAAO,YAAa,MAAOA,EAAc,CAAE,GAAI,oBAAqB,CAAA,CAAE,CAC1E,CAAA,EAID0d,IAAc,aACb3c,OAAC,MAAA,CAAI,UAAU,iBAEb,SAAA,CAAAE,EAAAA,IAACiU,GAAA,CAAsB,kBAAmB,IAAM7Y,EAAA,CAAQ,CAAG,EAG3D4E,EAAAA,IAAC2P,GAAA,CACC,kBAAmBwB,GACnB,iBAAkB8O,EAAA,CAAA,CACpB,EACF,EAIDxD,IAAc,WACb3c,OAAC,MAAA,CAAI,UAAU,iBAEb,SAAA,CAAAE,EAAAA,IAAC0V,GAAA,EAA4B,EAGhCyH,IAAY,UACXrd,OAAC,MAAA,CAAI,UAAU,wCACb,SAAA,CAAAA,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACyJ,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACzCzJ,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,SAAA4d,CAAA,CAAW,CAAA,EACnD,EACA5d,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAE,CAAA,EAC9F,EACAF,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAAC4J,GAAA,CAAM,UAAU,wBAAA,CAAyB,EAC1C5J,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,SAAA6d,CAAA,CAAa,CAAA,EACrD,EACA7d,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAE,CAAA,EAChG,EACAF,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACgI,GAAA,CAAM,UAAU,mBAAA,CAAoB,EACrChI,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,WAAc,MAAA,CAAO,CAAA,EAC7D,EACAA,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAAE,CAAA,EAC/F,EACAF,EAAAA,KAAC0J,EAAA,CAAK,UAAU,MACd,SAAA,CAAA1J,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,sBAAA,CAAuB,EACzCnN,EAAAA,IAAC,OAAA,CAAK,UAAU,qBAAsB,WAAe,MAAA,CAAO,CAAA,EAC9D,EACAA,MAAC,KAAE,UAAU,qCAAsC,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAE,CAAA,CAAA,CAChG,CAAA,EACF,EAIDmd,IAAY,UACXrd,OAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAE,EAAAA,IAAC2R,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3F3R,EAAAA,IAAC4B,EAAA,CACC,YAAa7C,EAAc,CAAE,GAAI,gCAAiC,EAClE,MAAO+Q,EACP,SAAWjO,GAAMkO,EAAelO,EAAE,OAAO,KAAK,EAC9C,UAAU,MAAA,CAAA,CACZ,EACF,EACA/B,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAE,EAAAA,IAAC8B,EAAA,CACC,QAAS6a,IAAgB,MAAQ,UAAY,UAC7C,KAAK,KACL,QAAS,IAAMC,EAAe,KAAK,EAElC,SAAA7d,EAAc,CAAE,GAAI,iBAAA,CAAmB,CAAA,CAAA,EAE1Ce,EAAAA,KAACgC,EAAA,CACC,QAAS6a,IAAgB,SAAW,UAAY,UAChD,KAAK,KACL,QAAS,IAAMC,EAAe,QAAQ,EAEtC,SAAA,CAAA5c,EAAAA,IAACgI,GAAA,CAAM,UAAU,cAAA,CAAe,EAC/BjJ,EAAc,CAAE,GAAI,kBAAA,CAAoB,CAAA,CAAA,CAAA,EAE3Ce,EAAAA,KAACgC,EAAA,CACC,QAAS6a,IAAgB,UAAY,UAAY,UACjD,KAAK,KACL,QAAS,IAAMC,EAAe,SAAS,EAEvC,SAAA,CAAA5c,EAAAA,IAACmN,GAAA,CAAO,UAAU,cAAA,CAAe,EAChCpO,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAAA,CAAA,CAC5C,CAAA,CACF,CAAA,EACF,EAIDoe,IAAY,SACXrd,OAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAAE,EAAAA,IAAC2R,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3F3R,EAAAA,IAAC4B,EAAA,CACC,YAAa7C,EAAc,CAAE,GAAI,gCAAiC,EAClE,MAAO+Q,EACP,SAAWjO,GAAMkO,EAAelO,EAAE,OAAO,KAAK,EAC9C,UAAU,MAAA,CAAA,CACZ,EACF,EAIDsb,IAAY,UACXnd,EAAAA,IAACmK,GAAA,CACC,YAAa0U,GAAU,YACvB,aAAcA,GAAU,aACxB,YAAaA,GAAU,YACvB,YAAaA,GAAU,YACvB,cAAeA,GAAU,cACzB,aAAcE,EACd,eAAgBK,EAChB,UAAWC,EACX,gBAAiBR,GAAU,gBAC3B,iBAAkBY,GAClB,iBAAkBC,EAAA,CAAA,EAGrBvC,IAAY,SACXnd,EAAAA,IAACmK,GAAA,CACC,OAAO,QACP,YAAayV,GAAe,YAC5B,aAAcA,GAAe,aAC7B,YAAaA,GAAe,YAC5B,YAAaA,GAAe,YAC5B,cAAeA,GAAe,cAC9B,aAAcC,GACd,eAAgBC,GAChB,UAAWC,EAAA,CAAA,EAKde,GACC9gB,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,SAAA,CAAC,EAAG,EAAG,EAAG,CAAC,EAAE,IAAK,GACjBA,EAAAA,IAAC,MAAA,CAAY,UAAU,wCAAA,EAAb,CAAsD,CACjE,CAAA,CACH,EACE2gB,GAAe,SAAW,EAC5B7gB,EAAAA,KAAC0J,EAAA,CAAK,UAAU,kBACd,SAAA,CAAAxJ,EAAAA,IAACyJ,GAAA,CAAO,UAAU,4CAAA,CAA6C,EAC/DzJ,EAAAA,IAAC,MAAG,UAAU,2CAA4C,WAAc,CAAE,GAAI,sBAAA,CAAwB,EAAE,EACxGA,MAAC,KAAE,UAAU,6BACV,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,CAAA,CACF,EAEAA,EAAAA,IAAC,MAAA,CAAI,UAAU,YACZ,YAAe,IAAKlE,GACnBqhB,IAAY,QACVnd,EAAAA,IAACqI,GAAA,CAEC,OAAAvM,EACA,QAASA,EAAO,QAChB,WAAY8kB,GAAgB,IAAI9kB,EAAO,IAAI,EAC3C,eAAgB,IAAM+kB,GAAoB/kB,EAAO,IAAI,EACrD,WAAY,GACZ,SAAUokB,GACV,SAAUE,EAAA,EAPL,GAAGtkB,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAA,EAUrCkE,EAAAA,IAACmc,GAAA,CAEC,OAAArgB,EACA,WAAY8kB,GAAgB,IAAI,GAAG9kB,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAE,EAChE,eAAgB,IAAM+kB,GAAoB,GAAG/kB,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAE,EAC1E,SAAUwN,GACV,OAAQkV,GACR,SAAU7P,EACV,iBAAkBqR,GAClB,aAAcV,GAAY,IAAIxjB,EAAO,IAAI,CAAA,EARpC,GAAGA,EAAO,IAAI,IAAIA,EAAO,KAAK,EAAA,CAWxC,CAAA,CACH,CAAA,EAEA,EAID2gB,IAAc,aACb3c,OAAC,MAAA,CAAI,UAAU,iBAEb,SAAA,CAAAA,OAAC,UAAA,CACC,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAACkc,GAAA,CAAU,UAAU,+BAAA,CAAgC,EACrDlc,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,gBAAA,CAAkB,CAAA,CACzC,CAAA,EACF,EACAA,EAAAA,IAACwJ,EAAA,CAAK,UAAU,MACd,SAAAxJ,MAACyW,IAAkB,UAAW,IAAMrb,EAAA,CAAQ,CAAG,CAAA,CACjD,CAAA,EACF,SAGC,UAAA,CACC,SAAA,CAAA0E,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAACmN,GAAA,CAAO,UAAU,+BAAA,CAAgC,EAClDnN,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAC7C,CAAA,EACF,EACAA,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,0BAAA,CAA4B,EACnD,EACAA,EAAAA,IAACiZ,GAAA,CACC,YAAa,GACb,eAAiBjL,GAAS,QAAQ,IAAI,gBAAiBA,CAAI,EAC3D,gBAAkBA,GAAS,OAAO,KAAK,aAAa,mBAAmBA,CAAI,CAAC,GAAI,QAAQ,CAAA,CAAA,CAC1F,EACF,SAGC,UAAA,CACC,SAAA,CAAAlO,EAAAA,KAAC,MAAA,CAAI,UAAU,+BACb,SAAA,CAAAE,EAAAA,IAACgI,GAAA,CAAM,UAAU,+BAAA,CAAgC,EACjDhI,MAAC,MAAG,UAAU,sCACX,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EACF,EACAA,EAAAA,IAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,8BAAA,CAAgC,EACvD,EACAA,EAAAA,IAAC8a,GAAA,CACC,gBAAiB,CAACrf,EAAY0lB,IAAkB,CAC9C,QAAQ,IAAI,mBAAoB1lB,EAAY,QAAS0lB,CAAa,EAClE/lB,EAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,EAID+hB,IAAY,UACXnd,EAAAA,IAACmC,GAAA,CACC,KAAM8a,EAAgB,OAAS,MAC/B,OAAQA,EACR,KAAMF,EACN,QAAS2B,GACT,OAAQC,EAAA,CAAA,EAKZ3e,EAAAA,IAAC+O,GAAA,CACC,KAAMwO,EACN,QAAS,IAAM,CACbC,EAA0B,EAAK,EAC/BE,EAA0B,MAAS,CACrC,EACA,OAAQuC,GACR,YAAaxC,GAAA,YAAAA,EAAwB,KACrC,eACEA,GAA0BrY,GAAiBqY,CAAsB,EAC7DA,EAAuB,QACvB,OAEN,YACEA,GAA0BrY,GAAiBqY,CAAsB,EAC7DA,EAAuB,KACvB,OAEN,WACEA,GAA0BrY,GAAiBqY,CAAsB,EAC5DA,EAAuB,IACxB,MAAA,CAAA,CAER,EACF,CAEJ","x_google_ignoreList":[0,1,2,3,4]}