@samanhappy/mcphub 1.1.13 → 1.1.15

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 (228) hide show
  1. package/README.fr.md +1 -1
  2. package/README.md +1 -1
  3. package/README.zh.md +1 -1
  4. package/dist/betterAuth.js +3 -3
  5. package/dist/betterAuth.js.map +1 -1
  6. package/dist/cli/commands/keys.js +22 -3
  7. package/dist/cli/commands/keys.js.map +1 -1
  8. package/dist/clients/mcpSdkClient.js +2667 -1448
  9. package/dist/clients/mcpSdkClient.js.map +4 -4
  10. package/dist/config/index.js +1 -1
  11. package/dist/config/index.js.map +1 -1
  12. package/dist/controllers/bearerKeyController.js +49 -3
  13. package/dist/controllers/bearerKeyController.js.map +1 -1
  14. package/dist/controllers/configController.js +1 -0
  15. package/dist/controllers/configController.js.map +1 -1
  16. package/dist/controllers/credentialBindingController.js +36 -12
  17. package/dist/controllers/credentialBindingController.js.map +1 -1
  18. package/dist/controllers/groupController.js +12 -5
  19. package/dist/controllers/groupController.js.map +1 -1
  20. package/dist/controllers/oauthRelayController.js +65 -0
  21. package/dist/controllers/oauthRelayController.js.map +1 -0
  22. package/dist/controllers/personalOAuthController.js +10 -1
  23. package/dist/controllers/personalOAuthController.js.map +1 -1
  24. package/dist/controllers/serverController.js +52 -18
  25. package/dist/controllers/serverController.js.map +1 -1
  26. package/dist/controllers/userController.js +11 -1
  27. package/dist/controllers/userController.js.map +1 -1
  28. package/dist/dao/ActivityDao.js +2 -0
  29. package/dist/dao/ActivityDao.js.map +1 -1
  30. package/dist/dao/BearerKeyDao.js +10 -5
  31. package/dist/dao/BearerKeyDao.js.map +1 -1
  32. package/dist/dao/BearerKeyDaoDbImpl.js +16 -5
  33. package/dist/dao/BearerKeyDaoDbImpl.js.map +1 -1
  34. package/dist/dao/GroupDao.js +24 -0
  35. package/dist/dao/GroupDao.js.map +1 -1
  36. package/dist/dao/GroupDaoDbImpl.js +34 -0
  37. package/dist/dao/GroupDaoDbImpl.js.map +1 -1
  38. package/dist/dao/ServerDao.js +10 -1
  39. package/dist/dao/ServerDao.js.map +1 -1
  40. package/dist/dao/ServerDaoDbImpl.js +4 -0
  41. package/dist/dao/ServerDaoDbImpl.js.map +1 -1
  42. package/dist/dao/SystemConfigDao.js +5 -2
  43. package/dist/dao/SystemConfigDao.js.map +1 -1
  44. package/dist/dao/SystemConfigDaoDbImpl.js +11 -0
  45. package/dist/dao/SystemConfigDaoDbImpl.js.map +1 -1
  46. package/dist/dao/UserDaoDbImpl.js +4 -0
  47. package/dist/dao/UserDaoDbImpl.js.map +1 -1
  48. package/dist/dao/base/JsonFileBaseDao.js +17 -2
  49. package/dist/dao/base/JsonFileBaseDao.js.map +1 -1
  50. package/dist/db/entities/Activity.js +4 -0
  51. package/dist/db/entities/Activity.js.map +1 -1
  52. package/dist/db/entities/BearerKey.js +8 -0
  53. package/dist/db/entities/BearerKey.js.map +1 -1
  54. package/dist/db/entities/Group.js +4 -0
  55. package/dist/db/entities/Group.js.map +1 -1
  56. package/dist/db/entities/Server.js +4 -0
  57. package/dist/db/entities/Server.js.map +1 -1
  58. package/dist/db/entities/SystemConfig.js +8 -0
  59. package/dist/db/entities/SystemConfig.js.map +1 -1
  60. package/dist/db/entities/User.js +4 -0
  61. package/dist/db/entities/User.js.map +1 -1
  62. package/dist/db/repositories/GroupRepository.js +36 -0
  63. package/dist/db/repositories/GroupRepository.js.map +1 -1
  64. package/dist/db/repositories/ServerRepository.js +1 -0
  65. package/dist/db/repositories/ServerRepository.js.map +1 -1
  66. package/dist/db/repositories/VectorEmbeddingRepository.js +11 -1
  67. package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
  68. package/dist/middlewares/auth.js +7 -1
  69. package/dist/middlewares/auth.js.map +1 -1
  70. package/dist/routes/index.js +6 -1
  71. package/dist/routes/index.js.map +1 -1
  72. package/dist/server.js +2 -0
  73. package/dist/server.js.map +1 -1
  74. package/dist/services/activityLoggingService.js +1 -0
  75. package/dist/services/activityLoggingService.js.map +1 -1
  76. package/dist/services/authorizationService.js.map +1 -1
  77. package/dist/services/capabilitySnapshotService.js +2 -1
  78. package/dist/services/capabilitySnapshotService.js.map +1 -1
  79. package/dist/services/contextCostService.js +2 -2
  80. package/dist/services/contextCostService.js.map +1 -1
  81. package/dist/services/credentialBindingService.js +9 -1
  82. package/dist/services/credentialBindingService.js.map +1 -1
  83. package/dist/services/dataService.js +4 -2
  84. package/dist/services/dataService.js.map +1 -1
  85. package/dist/services/groupService.js +21 -8
  86. package/dist/services/groupService.js.map +1 -1
  87. package/dist/services/mcpEventBus.js +6 -0
  88. package/dist/services/mcpEventBus.js.map +1 -0
  89. package/dist/services/mcpService.js +153 -6
  90. package/dist/services/mcpService.js.map +1 -1
  91. package/dist/services/personalOAuthService.js +2 -0
  92. package/dist/services/personalOAuthService.js.map +1 -1
  93. package/dist/services/principalRuntimeService.js +19 -0
  94. package/dist/services/principalRuntimeService.js.map +1 -1
  95. package/dist/services/requestContextService.js +15 -0
  96. package/dist/services/requestContextService.js.map +1 -1
  97. package/dist/services/serverConfigEnvironment.js +2 -1
  98. package/dist/services/serverConfigEnvironment.js.map +1 -1
  99. package/dist/services/smartRoutingService.js +20 -2
  100. package/dist/services/smartRoutingService.js.map +1 -1
  101. package/dist/services/sseService.js +58 -6
  102. package/dist/services/sseService.js.map +1 -1
  103. package/dist/services/templateService.js +11 -5
  104. package/dist/services/templateService.js.map +1 -1
  105. package/dist/services/toolPolicyDiagnostics.js +27 -0
  106. package/dist/services/toolPolicyDiagnostics.js.map +1 -0
  107. package/dist/services/toolPolicyService.js +41 -0
  108. package/dist/services/toolPolicyService.js.map +1 -0
  109. package/dist/services/userService.js +5 -1
  110. package/dist/services/userService.js.map +1 -1
  111. package/dist/services/vectorSearchService.js +4 -2
  112. package/dist/services/vectorSearchService.js.map +1 -1
  113. package/dist/types/toolPolicy.js +2 -0
  114. package/dist/types/toolPolicy.js.map +1 -0
  115. package/dist/utils/groupAccess.js +6 -4
  116. package/dist/utils/groupAccess.js.map +1 -1
  117. package/dist/utils/groupKeyScope.js +34 -0
  118. package/dist/utils/groupKeyScope.js.map +1 -0
  119. package/dist/utils/migration.js +10 -1
  120. package/dist/utils/migration.js.map +1 -1
  121. package/dist/utils/oauthBearer.js +1 -0
  122. package/dist/utils/oauthBearer.js.map +1 -1
  123. package/dist/utils/oauthServerMetadata.js +21 -0
  124. package/dist/utils/oauthServerMetadata.js.map +1 -1
  125. package/dist/utils/serverConfigPersistence.js +16 -1
  126. package/dist/utils/serverConfigPersistence.js.map +1 -1
  127. package/dist/utils/serverConfigValidation.js +1 -0
  128. package/dist/utils/serverConfigValidation.js.map +1 -1
  129. package/dist/utils/serverIdentity.js +7 -0
  130. package/dist/utils/serverIdentity.js.map +1 -0
  131. package/dist/utils/settingsSync.js +14 -1
  132. package/dist/utils/settingsSync.js.map +1 -1
  133. package/dist/utils/systemConfigCache.js +1 -1
  134. package/dist/utils/systemConfigCache.js.map +1 -1
  135. package/dist/utils/tokenCost.js +35 -3
  136. package/dist/utils/tokenCost.js.map +1 -1
  137. package/dist/utils/toolPolicy.js +42 -0
  138. package/dist/utils/toolPolicy.js.map +1 -0
  139. package/frontend/dist/assets/{ActivityPage-C68nRD4J.js → ActivityPage-Bi-TjKez.js} +2 -2
  140. package/frontend/dist/assets/{ActivityPage-C68nRD4J.js.map → ActivityPage-Bi-TjKez.js.map} +1 -1
  141. package/frontend/dist/assets/{ConfirmDialog-BYdfb115.js → ConfirmDialog-BJpzQmMw.js} +2 -2
  142. package/frontend/dist/assets/{ConfirmDialog-BYdfb115.js.map → ConfirmDialog-BJpzQmMw.js.map} +1 -1
  143. package/frontend/dist/assets/CredentialsPage-C4Ucer3d.js +2 -0
  144. package/frontend/dist/assets/CredentialsPage-C4Ucer3d.js.map +1 -0
  145. package/frontend/dist/assets/{Dashboard-CyTt5-52.js → Dashboard-C_2KkuoD.js} +2 -2
  146. package/frontend/dist/assets/{Dashboard-CyTt5-52.js.map → Dashboard-C_2KkuoD.js.map} +1 -1
  147. package/frontend/dist/assets/{DeleteDialog-BaCsEkJA.js → DeleteDialog-BoMYLx3J.js} +2 -2
  148. package/frontend/dist/assets/{DeleteDialog-BaCsEkJA.js.map → DeleteDialog-BoMYLx3J.js.map} +1 -1
  149. package/frontend/dist/assets/EndpointCopy-DITVC2YQ.js +2 -0
  150. package/frontend/dist/assets/{EndpointCopy-DxCJY8u6.js.map → EndpointCopy-DITVC2YQ.js.map} +1 -1
  151. package/frontend/dist/assets/GroupsPage-sE6YJyuK.js +33 -0
  152. package/frontend/dist/assets/GroupsPage-sE6YJyuK.js.map +1 -0
  153. package/frontend/dist/assets/LoginPage-CFsd_nY-.js +2 -0
  154. package/frontend/dist/assets/LoginPage-CFsd_nY-.js.map +1 -0
  155. package/frontend/dist/assets/{LogsPage-D3CAJzpq.js → LogsPage-BxZuGDuc.js} +2 -2
  156. package/frontend/dist/assets/LogsPage-BxZuGDuc.js.map +1 -0
  157. package/frontend/dist/assets/MarketPage-CDBs4vMb.js +2 -0
  158. package/frontend/dist/assets/{MarketPage-DsyVFNai.js.map → MarketPage-CDBs4vMb.js.map} +1 -1
  159. package/frontend/dist/assets/{OAuthConsentPage-go6iV2rX.js → OAuthConsentPage-BN_ucViM.js} +2 -2
  160. package/frontend/dist/assets/{OAuthConsentPage-go6iV2rX.js.map → OAuthConsentPage-BN_ucViM.js.map} +1 -1
  161. package/frontend/dist/assets/Pagination-S-7lzy59.js +2 -0
  162. package/frontend/dist/assets/Pagination-S-7lzy59.js.map +1 -0
  163. package/frontend/dist/assets/{PromptsPage-TJYCppKD.js → PromptsPage-Bl3ySXGK.js} +2 -2
  164. package/frontend/dist/assets/{PromptsPage-TJYCppKD.js.map → PromptsPage-Bl3ySXGK.js.map} +1 -1
  165. package/frontend/dist/assets/{ResourcesPage-B9ucLCSU.js → ResourcesPage-BOzQkQ92.js} +2 -2
  166. package/frontend/dist/assets/{ResourcesPage-B9ucLCSU.js.map → ResourcesPage-BOzQkQ92.js.map} +1 -1
  167. package/frontend/dist/assets/ServersPage-DHYwQ5AM.js +39 -0
  168. package/frontend/dist/assets/ServersPage-DHYwQ5AM.js.map +1 -0
  169. package/frontend/dist/assets/SettingsPage-CSJ35jlM.js +14 -0
  170. package/frontend/dist/assets/SettingsPage-CSJ35jlM.js.map +1 -0
  171. package/frontend/dist/assets/{StatusDot-hrwd7ElQ.js → StatusDot-NSjojGCy.js} +2 -2
  172. package/frontend/dist/assets/{StatusDot-hrwd7ElQ.js.map → StatusDot-NSjojGCy.js.map} +1 -1
  173. package/frontend/dist/assets/{ToggleGroup-BXCGM08S.js → ToggleGroup-BIZWpNzm.js} +2 -2
  174. package/frontend/dist/assets/{ToggleGroup-BXCGM08S.js.map → ToggleGroup-BIZWpNzm.js.map} +1 -1
  175. package/frontend/dist/assets/UserGroupSelection-CN0weGXJ.js +2 -0
  176. package/frontend/dist/assets/UserGroupSelection-CN0weGXJ.js.map +1 -0
  177. package/frontend/dist/assets/UsersPage-DC51v2b8.js +2 -0
  178. package/frontend/dist/assets/UsersPage-DC51v2b8.js.map +1 -0
  179. package/frontend/dist/assets/clipboard-ik5YV95M.js +2 -0
  180. package/frontend/dist/assets/{clipboard-CoLstiwP.js.map → clipboard-ik5YV95M.js.map} +1 -1
  181. package/frontend/dist/assets/{CopyClientConfigDialog-Clr8hk1S.js → costRevision-Bxov9_vH.js} +4 -4
  182. package/frontend/dist/assets/costRevision-Bxov9_vH.js.map +1 -0
  183. package/frontend/dist/assets/framework-vendor-D0S_ys6r.js +61 -0
  184. package/frontend/dist/assets/framework-vendor-D0S_ys6r.js.map +1 -0
  185. package/frontend/dist/assets/{i18n-vendor-DVmjrzgW.js → i18n-vendor-COTriSc6.js} +2 -2
  186. package/frontend/dist/assets/{i18n-vendor-DVmjrzgW.js.map → i18n-vendor-COTriSc6.js.map} +1 -1
  187. package/frontend/dist/assets/{icons-vendor-CkcU1LMA.js → icons-vendor-DZjjGrOu.js} +3 -3
  188. package/frontend/dist/assets/{icons-vendor-CkcU1LMA.js.map → icons-vendor-DZjjGrOu.js.map} +1 -1
  189. package/frontend/dist/assets/index-6AyPtx0A.js +3 -0
  190. package/frontend/dist/assets/index-6AyPtx0A.js.map +1 -0
  191. package/frontend/dist/assets/index-DrHctFvx.css +1 -0
  192. package/frontend/dist/assets/{resourceService-DXuM3elu.js → resourceService-DMzCAZ0B.js} +2 -2
  193. package/frontend/dist/assets/{resourceService-DXuM3elu.js.map → resourceService-DMzCAZ0B.js.map} +1 -1
  194. package/frontend/dist/assets/useCostData-CcFSYViI.js +2 -0
  195. package/frontend/dist/assets/useCostData-CcFSYViI.js.map +1 -0
  196. package/frontend/dist/assets/variableDetection-CbYSa1ka.js +80 -0
  197. package/frontend/dist/assets/variableDetection-CbYSa1ka.js.map +1 -0
  198. package/frontend/dist/index.html +5 -5
  199. package/mcp_settings.json +2 -0
  200. package/package.json +2 -2
  201. package/frontend/dist/assets/CopyClientConfigDialog-Clr8hk1S.js.map +0 -1
  202. package/frontend/dist/assets/CredentialsPage-WxYmPkS2.js +0 -2
  203. package/frontend/dist/assets/CredentialsPage-WxYmPkS2.js.map +0 -1
  204. package/frontend/dist/assets/EndpointCopy-DxCJY8u6.js +0 -2
  205. package/frontend/dist/assets/GroupsPage-C9uf7qRF.js +0 -33
  206. package/frontend/dist/assets/GroupsPage-C9uf7qRF.js.map +0 -1
  207. package/frontend/dist/assets/LoginPage-CfljHYdH.js +0 -2
  208. package/frontend/dist/assets/LoginPage-CfljHYdH.js.map +0 -1
  209. package/frontend/dist/assets/LogsPage-D3CAJzpq.js.map +0 -1
  210. package/frontend/dist/assets/MarketPage-DsyVFNai.js +0 -2
  211. package/frontend/dist/assets/Pagination-BRqqU5Ct.js +0 -2
  212. package/frontend/dist/assets/Pagination-BRqqU5Ct.js.map +0 -1
  213. package/frontend/dist/assets/ServersPage-BO1e0GJ4.js +0 -39
  214. package/frontend/dist/assets/ServersPage-BO1e0GJ4.js.map +0 -1
  215. package/frontend/dist/assets/SettingsPage-_LJt6T_U.js +0 -14
  216. package/frontend/dist/assets/SettingsPage-_LJt6T_U.js.map +0 -1
  217. package/frontend/dist/assets/UsersPage-CLPsZo0-.js +0 -2
  218. package/frontend/dist/assets/UsersPage-CLPsZo0-.js.map +0 -1
  219. package/frontend/dist/assets/clipboard-CoLstiwP.js +0 -2
  220. package/frontend/dist/assets/framework-vendor-CQFm9vKd.js +0 -61
  221. package/frontend/dist/assets/framework-vendor-CQFm9vKd.js.map +0 -1
  222. package/frontend/dist/assets/index-BE6bm3KN.css +0 -1
  223. package/frontend/dist/assets/index-CKByfAIo.js +0 -3
  224. package/frontend/dist/assets/index-CKByfAIo.js.map +0 -1
  225. package/frontend/dist/assets/useCostData-Br7dI3R9.js +0 -2
  226. package/frontend/dist/assets/useCostData-Br7dI3R9.js.map +0 -1
  227. package/frontend/dist/assets/variableDetection-Civ1fQ-c.js +0 -18
  228. package/frontend/dist/assets/variableDetection-Civ1fQ-c.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{r as y,j as o}from"./framework-vendor-D0S_ys6r.js";import{k as h,o as r}from"./index-6AyPtx0A.js";import{c as x}from"./clipboard-ik5YV95M.js";import{u as C}from"./i18n-vendor-COTriSc6.js";import{C as b,r as j}from"./icons-vendor-DZjjGrOu.js";const g=({url:s,label:e,prefix:a,className:p,copyValue:m,ariaLabel:l})=>{const{t}=C(),{showToast:c}=h(),[n,i]=y.useState(!1),d=async u=>{if(u.stopPropagation(),!await x(m??s)){c(t("common.copyFailed")||"Copy failed","error");return}i(!0),c(t("common.copySuccess")||"Copied to clipboard","success"),setTimeout(()=>i(!1),1200)};return o.jsxs("div",{className:r("hub-endpoint",p),role:"group","aria-label":l||s,children:[e&&o.jsx("div",{className:"hub-endpoint-label",children:e}),o.jsxs("div",{className:"hub-endpoint-url",title:s,children:[a&&o.jsx("span",{style:{color:"var(--hub-ink-3)"},children:a}),s]}),o.jsx("button",{type:"button",onClick:d,className:r("hub-endpoint-copy",n?"copied":""),title:t("common.copy")||"Copy","aria-label":t("common.copy")||"Copy",children:n?o.jsx(b,{size:13}):o.jsx(j,{size:13})})]})};export{g as E};
2
+ //# sourceMappingURL=EndpointCopy-DITVC2YQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EndpointCopy-DxCJY8u6.js","sources":["../../src/components/ui/EndpointCopy.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useToast } from '@/contexts/ToastContext';\nimport { copyText } from '@/utils/clipboard';\nimport { cn } from '@/utils/cn';\n\ninterface EndpointCopyProps {\n url: string;\n label?: string;\n prefix?: string;\n className?: string;\n /** Optionally override the value placed on the clipboard. */\n copyValue?: string;\n ariaLabel?: string;\n}\n\nexport const EndpointCopy: React.FC<EndpointCopyProps> = ({\n url,\n label,\n prefix,\n className,\n copyValue,\n ariaLabel,\n}) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [copied, setCopied] = useState(false);\n\n const onCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n const ok = await copyText(copyValue ?? url);\n if (!ok) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n return;\n }\n setCopied(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopied(false), 1200);\n };\n\n return (\n <div className={cn('hub-endpoint', className)} role=\"group\" aria-label={ariaLabel || url}>\n {label && <div className=\"hub-endpoint-label\">{label}</div>}\n <div className=\"hub-endpoint-url\" title={url}>\n {prefix && <span style={{ color: 'var(--hub-ink-3)' }}>{prefix}</span>}\n {url}\n </div>\n <button\n type=\"button\"\n onClick={onCopy}\n className={cn('hub-endpoint-copy', copied ? 'copied' : '')}\n title={t('common.copy') || 'Copy'}\n aria-label={t('common.copy') || 'Copy'}\n >\n {copied ? <Check size={13} /> : <Copy size={13} />}\n </button>\n </div>\n );\n};\n\ninterface MonoCopyProps {\n text: string;\n className?: string;\n copyValue?: string;\n title?: string;\n}\n\n/** Inline monospace value with hover-to-copy icon. */\nexport const MonoCopy: React.FC<MonoCopyProps> = ({ text, className, copyValue, title }) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [copied, setCopied] = useState(false);\n\n const onCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n const ok = await copyText(copyValue ?? text);\n if (!ok) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n return;\n }\n setCopied(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopied(false), 1200);\n };\n\n return (\n <span\n className={cn(\n 'hub-mono inline-flex items-center gap-1.5 group cursor-pointer text-[12.5px]',\n className,\n )}\n onClick={onCopy}\n title={title || text}\n role=\"button\"\n >\n <span className=\"truncate\">{text}</span>\n {copied ? (\n <Check size={12} className=\"text-[var(--hub-ok)] flex-shrink-0\" />\n ) : (\n <Copy\n size={12}\n className=\"text-[var(--hub-ink-3)] opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\"\n />\n )}\n </span>\n );\n};\n"],"names":["EndpointCopy","url","label","prefix","className","copyValue","ariaLabel","useTranslation","showToast","useToast","copied","setCopied","useState","onCopy","e","copyText","jsxs","cn","jsx","Check","Copy"],"mappings":"yPAiBO,MAAMA,EAA4C,CAAC,CACxD,IAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,UAAAC,EACA,UAAAC,CACF,IAAM,CACJ,KAAM,CAAE,CAAA,EAAMC,EAAA,EACR,CAAE,UAAAC,CAAA,EAAcC,EAAA,EAChB,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAS,EAAK,EAEpCC,EAAS,MAAOC,GAAwB,CAG5C,GAFAA,EAAE,gBAAA,EAEE,CADO,MAAMC,EAASV,GAAaJ,CAAG,EACjC,CACPO,EAAU,EAAE,mBAAmB,GAAK,cAAe,OAAO,EAC1D,MACF,CACAG,EAAU,EAAI,EACdH,EAAU,EAAE,oBAAoB,GAAK,sBAAuB,SAAS,EACrE,WAAW,IAAMG,EAAU,EAAK,EAAG,IAAI,CACzC,EAEA,OACEK,EAAAA,KAAC,MAAA,CAAI,UAAWC,EAAG,eAAgBb,CAAS,EAAG,KAAK,QAAQ,aAAYE,GAAaL,EAClF,SAAA,CAAAC,GAASgB,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,SAAAhB,EAAM,EACrDc,EAAAA,KAAC,MAAA,CAAI,UAAU,mBAAmB,MAAOf,EACtC,SAAA,CAAAE,SAAW,OAAA,CAAK,MAAO,CAAE,MAAO,kBAAA,EAAuB,SAAAA,EAAO,EAC9DF,CAAA,EACH,EACAiB,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASL,EACT,UAAWI,EAAG,oBAAqBP,EAAS,SAAW,EAAE,EACzD,MAAO,EAAE,aAAa,GAAK,OAC3B,aAAY,EAAE,aAAa,GAAK,OAE/B,SAAAA,QAAUS,EAAA,CAAM,KAAM,GAAI,EAAKD,EAAAA,IAACE,EAAA,CAAK,KAAM,EAAA,CAAI,CAAA,CAAA,CAClD,EACF,CAEJ"}
1
+ {"version":3,"file":"EndpointCopy-DITVC2YQ.js","sources":["../../src/components/ui/EndpointCopy.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useToast } from '@/contexts/ToastContext';\nimport { copyText } from '@/utils/clipboard';\nimport { cn } from '@/utils/cn';\n\ninterface EndpointCopyProps {\n url: string;\n label?: string;\n prefix?: string;\n className?: string;\n /** Optionally override the value placed on the clipboard. */\n copyValue?: string;\n ariaLabel?: string;\n}\n\nexport const EndpointCopy: React.FC<EndpointCopyProps> = ({\n url,\n label,\n prefix,\n className,\n copyValue,\n ariaLabel,\n}) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [copied, setCopied] = useState(false);\n\n const onCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n const ok = await copyText(copyValue ?? url);\n if (!ok) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n return;\n }\n setCopied(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopied(false), 1200);\n };\n\n return (\n <div className={cn('hub-endpoint', className)} role=\"group\" aria-label={ariaLabel || url}>\n {label && <div className=\"hub-endpoint-label\">{label}</div>}\n <div className=\"hub-endpoint-url\" title={url}>\n {prefix && <span style={{ color: 'var(--hub-ink-3)' }}>{prefix}</span>}\n {url}\n </div>\n <button\n type=\"button\"\n onClick={onCopy}\n className={cn('hub-endpoint-copy', copied ? 'copied' : '')}\n title={t('common.copy') || 'Copy'}\n aria-label={t('common.copy') || 'Copy'}\n >\n {copied ? <Check size={13} /> : <Copy size={13} />}\n </button>\n </div>\n );\n};\n\ninterface MonoCopyProps {\n text: string;\n className?: string;\n copyValue?: string;\n title?: string;\n}\n\n/** Inline monospace value with hover-to-copy icon. */\nexport const MonoCopy: React.FC<MonoCopyProps> = ({ text, className, copyValue, title }) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [copied, setCopied] = useState(false);\n\n const onCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n const ok = await copyText(copyValue ?? text);\n if (!ok) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n return;\n }\n setCopied(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopied(false), 1200);\n };\n\n return (\n <span\n className={cn(\n 'hub-mono inline-flex items-center gap-1.5 group cursor-pointer text-[12.5px]',\n className,\n )}\n onClick={onCopy}\n title={title || text}\n role=\"button\"\n >\n <span className=\"truncate\">{text}</span>\n {copied ? (\n <Check size={12} className=\"text-[var(--hub-ok)] flex-shrink-0\" />\n ) : (\n <Copy\n size={12}\n className=\"text-[var(--hub-ink-3)] opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\"\n />\n )}\n </span>\n );\n};\n"],"names":["EndpointCopy","url","label","prefix","className","copyValue","ariaLabel","useTranslation","showToast","useToast","copied","setCopied","useState","onCopy","e","copyText","jsxs","cn","jsx","Check","Copy"],"mappings":"yPAiBO,MAAMA,EAA4C,CAAC,CACxD,IAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,UAAAC,EACA,UAAAC,CACF,IAAM,CACJ,KAAM,CAAE,CAAA,EAAMC,EAAA,EACR,CAAE,UAAAC,CAAA,EAAcC,EAAA,EAChB,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAS,EAAK,EAEpCC,EAAS,MAAOC,GAAwB,CAG5C,GAFAA,EAAE,gBAAA,EAEE,CADO,MAAMC,EAASV,GAAaJ,CAAG,EACjC,CACPO,EAAU,EAAE,mBAAmB,GAAK,cAAe,OAAO,EAC1D,MACF,CACAG,EAAU,EAAI,EACdH,EAAU,EAAE,oBAAoB,GAAK,sBAAuB,SAAS,EACrE,WAAW,IAAMG,EAAU,EAAK,EAAG,IAAI,CACzC,EAEA,OACEK,EAAAA,KAAC,MAAA,CAAI,UAAWC,EAAG,eAAgBb,CAAS,EAAG,KAAK,QAAQ,aAAYE,GAAaL,EAClF,SAAA,CAAAC,GAASgB,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,SAAAhB,EAAM,EACrDc,EAAAA,KAAC,MAAA,CAAI,UAAU,mBAAmB,MAAOf,EACtC,SAAA,CAAAE,SAAW,OAAA,CAAK,MAAO,CAAE,MAAO,kBAAA,EAAuB,SAAAA,EAAO,EAC9DF,CAAA,EACH,EACAiB,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASL,EACT,UAAWI,EAAG,oBAAqBP,EAAS,SAAW,EAAE,EACzD,MAAO,EAAE,aAAa,GAAK,OAC3B,aAAY,EAAE,aAAa,GAAK,OAE/B,SAAAA,QAAUS,EAAA,CAAM,KAAM,GAAI,EAAKD,EAAAA,IAACE,EAAA,CAAK,KAAM,EAAA,CAAI,CAAA,CAAA,CAClD,EACF,CAEJ"}
@@ -0,0 +1,33 @@
1
+ import{r as g,j as e,R as M}from"./framework-vendor-D0S_ys6r.js";import{o as Z,h as fe,e as ee,a as ve,k as je,l as se}from"./index-6AyPtx0A.js";import{u as te,a as re}from"./useCostData-CcFSYViI.js";import{u as $}from"./i18n-vendor-COTriSc6.js";import{u as me,c as ye}from"./clipboard-ik5YV95M.js";import{f as H,p as Ne}from"./contextCost-CilWqGWT.js";import{g as ke,A as Se,C as we,s as Ce}from"./costRevision-Bxov9_vH.js";import{W as Ae,g as Te,F as Ee,H as De,C as Ie,r as Q,J as oe,z as Fe,w as ze,T as Ue,n as Ge,D as ce,N as Pe,P as de,l as Re,X as Le}from"./icons-vendor-DZjjGrOu.js";import{U as We}from"./UserGroupSelection-CN0weGXJ.js";import{D as $e}from"./DeleteDialog-BoMYLx3J.js";const Oe=["read","create","update","delete","other"],Me=a=>{var s,l,b;if(((s=a.annotations)==null?void 0:s.readOnlyHint)===!0)return"read";const d=a.value.toLowerCase();return/^(delete|remove)[_-]/.test(d)?"delete":((l=a.annotations)==null?void 0:l.destructiveHint)===!0?"other":/^(create|add)[_-]/.test(d)?"create":/^(update|set)[_-]/.test(d)?"update":((b=a.annotations)==null?void 0:b.readOnlyHint)!==!1&&/^(get|list|read|search)[_-]/.test(d)?"read":"other"},He=(a,d,s)=>{const l=d.trim().toLowerCase();return a.filter(b=>{var i,u;return(b.value.toLowerCase().includes(l)||((i=b.description)==null?void 0:i.toLowerCase().includes(l)))&&(s==="all"||((u=b.annotations)==null?void 0:u[s])===!0)})},_e=(a,d,s,l)=>{if(s.length===0||a==="all"&&l==="select")return a;const b=new Set(a==="all"?d:a);for(const i of s)l==="deselect"||l==="invert"&&b.has(i)?b.delete(i):b.add(i);return[...b]},Be=({items:a,selection:d,tools:s,label:l,onChange:b,children:i})=>{const{t:u}=$(),[E,F]=g.useState(""),[w,A]=g.useState("all"),[m,j]=g.useState(!1),y=He(a,E,w),T=new Set(d==="all"?a.map(t=>t.value):d),h=(t,o)=>b(_e(d,a.map(v=>v.value),t.map(v=>v.value),o)),x=s&&m?Oe.map(t=>({risk:t,items:y.filter(o=>Me(o)===t)})):[{risk:null,items:y}],p="text-xs text-blue-600 hover:text-blue-800 disabled:opacity-40 disabled:cursor-not-allowed";return e.jsxs("section",{"aria-label":l,children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 mb-2",children:[e.jsx("input",{type:"search","aria-label":u("groups.bulkSearchLabel",{capability:l}),placeholder:u("groups.bulkSearch"),value:E,onChange:t=>F(t.target.value),className:"min-w-0 flex-1 basis-48 rounded border border-gray-300 bg-white dark:bg-gray-800 px-2 py-1 text-sm"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("select",{"aria-label":u("groups.annotationFilter"),value:w,onChange:t=>A(t.target.value),className:"max-w-full rounded border border-gray-300 bg-white dark:bg-gray-800 px-2 py-1 text-sm",children:[e.jsx("option",{value:"all",children:u("groups.allAnnotations")}),["readOnlyHint","destructiveHint","idempotentHint"].map(t=>e.jsx("option",{value:t,children:u(`groups.${t}`)},t))]}),e.jsx("button",{type:"button","aria-pressed":m,onClick:()=>j(!m),className:p,children:u(m?"groups.flatList":"groups.riskGroups")})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 mb-2",children:[e.jsx("span",{className:"text-xs text-gray-500",role:"status",children:u("groups.visibleCount",{count:y.length,total:a.length})}),["select","deselect","invert"].map(t=>e.jsx("button",{type:"button",disabled:!y.length,onClick:()=>h(y,t),className:p,children:u(`groups.${t}Visible`)},t))]}),s&&m&&e.jsx("p",{className:"text-xs text-gray-500 mb-2",children:u("groups.riskHint")}),e.jsxs("div",{className:"grid grid-cols-1 gap-2 max-h-96 overflow-y-auto",children:[y.length===0&&e.jsx("p",{className:"text-sm text-gray-500",children:u("groups.noMatchingItems")}),x.filter(t=>t.items.length>0).map(t=>{const o=t.items.filter(v=>T.has(v.value)).length;return e.jsxs(M.Fragment,{children:[t.risk&&e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 border-b border-gray-200 py-1",children:[e.jsxs("span",{className:"text-xs font-medium",children:[u(`groups.risk_${t.risk}`)," (",o,"/",t.items.length,")"]}),e.jsx("button",{type:"button",className:p,onClick:()=>h(t.items,o===t.items.length?"deselect":"select"),children:u(o===t.items.length?"groups.selectNone":"groups.selectAll")})]}),t.items.map(v=>e.jsx(M.Fragment,{children:i(v)},v.value))]},t.risk??"flat")})]})]})},Ve={tools:[],prompts:[],resources:[]},ue={tools:"all",prompts:"all",resources:"all"},pe=({servers:a,value:d,onChange:s,className:l,serverCosts:b=[]})=>{const{t:i}=$(),u=M.useId(),{nameSeparator:E,smartRoutingConfig:F}=me(),[w,A]=g.useState(new Set),m=M.useMemo(()=>d.map(r=>typeof r=="string"?{name:r,...ue}:{...r,tools:r.tools||"all",prompts:r.prompts||"all",resources:r.resources||"all"}),[d]),j=M.useMemo(()=>a.filter(r=>r.enabled!==!1),[a]);M.useEffect(()=>{const r=new Set(m.map(n=>n.name)),c=new Set(j.map(n=>n.name));A(n=>{const C=new Set;return n.forEach(f=>{(r.has(f)||c.has(f))&&C.add(f)}),C})},[m,j]);const y=r=>{if(m.findIndex(n=>n.name===r)>=0){const n=m.filter(C=>C.name!==r);s(n)}else{const n=[...m,{name:r,...ue}];s(n)}},T=r=>{A(c=>{const n=new Set(c);return n.has(r)?n.delete(r):n.add(r),n})},h=r=>["tools","prompts","resources"].some(c=>{const n=r[c];return n==="all"||Array.isArray(n)&&n.length>0}),x=(r,c,n,C=!1)=>{const f=m.find(S=>S.name===r),z={...f?{...f}:{name:r,...Ve},[c]:n};if(c==="tools"&&Array.isArray(n)&&z.pinnedTools&&(z.pinnedTools=z.pinnedTools.filter(S=>n.includes(S)),z.pinnedTools.length===0&&delete z.pinnedTools),!h(z)){const S=m.filter(N=>N.name!==r);s(S),C||A(N=>{const W=new Set(N);return W.delete(r),W});return}if(f){s(m.map(S=>S.name===r?z:S));return}s([...m,z])},p=(r,c)=>{const n=m.find(f=>f.name===r);if(!n)return;const C={...n};c?C.alias=c:delete C.alias,s(m.map(f=>f.name===r?C:f))},t=(r,c)=>{const n=m.find(G=>G.name===r);if(!n)return;const C=n.pinnedTools??[],f={...n,pinnedTools:C.includes(c)?C.filter(G=>G!==c):[...C,c]};f.pinnedTools.length===0&&delete f.pinnedTools,s(m.map(G=>G.name===r?f:G))},o=(r,c)=>{const n=`${r}${E}`;return c.startsWith(n)?c.slice(n.length):c},v=(r,c)=>c==="tools"?(r.tools||[]).filter(n=>n.enabled!==!1).map(n=>({key:n.name,value:o(r.name,n.name),description:n.description,annotations:n.annotations,defaultDescription:n.defaultDescription,hasDescriptionOverride:n.hasDescriptionOverride})):c==="prompts"?(r.prompts||[]).filter(n=>n.enabled!==!1).map(n=>({key:n.name,value:o(r.name,n.name),description:n.description})):(r.resources||[]).filter(n=>n.enabled!==!1).map(n=>({key:n.uri,value:n.uri,description:n.description})),D=M.useMemo(()=>{const r=new Map;return b.forEach(c=>{const n=new Map;c.items.forEach(C=>n.set(C.name,C.cost)),r.set(c.name,n)}),r},[b]),k=r=>D.get(r)??new Map,U=(r,c)=>{const n=k(r.name);return v(r,c).filter(C=>J(r.name,c,C.value)).reduce((C,f)=>C+(n.get(f.key)??0),0)},_=r=>["tools","prompts","resources"].reduce((c,n)=>c+U(r,n),0),X=(r,c,n)=>{const C=j.find(S=>S.name===r);if(!C)return;const f=v(C,c).map(S=>S.value),G=m.find(S=>S.name===r);if(!G){x(r,c,[n]);return}const z=G[c];if(z==="all"){const S=f.filter(N=>N!==n);x(r,c,S);return}if(Array.isArray(z)){if(z.includes(n)){x(r,c,z.filter(N=>N!==n));return}const S=[...z,n];x(r,c,S.length===f.length?"all":S);return}x(r,c,[n])},O=r=>{const c=m.find(n=>n.name===r);return!!(c&&h(c))},K=r=>{const c=m.find(n=>n.name===r);return c?["tools","prompts","resources"].some(n=>{const C=c[n];return Array.isArray(C)&&C.length>0}):!1},J=(r,c,n)=>{const C=m.find(G=>G.name===r);if(!C)return!1;const f=C[c];return f==="all"?!0:Array.isArray(f)?f.includes(n):!1},B=(r,c)=>{const n=m.find(G=>G.name===r.name);if(!n)return 0;const C=v(r,c),f=n[c];if(f==="all")return C.length;if(Array.isArray(f)){const G=new Set(C.map(z=>z.value));return f.filter(z=>G.has(z)).length}return 0},I=[{key:"tools",titleKey:"groups.toolSelection",countKey:"groups.toolsSelected",allKey:"groups.allTools"},{key:"prompts",titleKey:"groups.promptSelection",countKey:"groups.promptsSelected",allKey:"groups.allPrompts"},{key:"resources",titleKey:"groups.resourceSelection",countKey:"groups.resourcesSelected",allKey:"groups.allResources"}],P=r=>I.map(({key:c})=>({key:c,count:B(r,c)})).filter(c=>c.count>0);return e.jsxs("div",{className:Z("space-y-4",l),children:[e.jsx("div",{className:"space-y-3",children:j.map(r=>{const c=O(r.name),n=K(r.name),C=w.has(r.name),f=m.find(N=>N.name===r.name),G=P(r),z=I.filter(({key:N})=>v(r,N).length>0),S=k(r.name);return e.jsxs("div",{className:"border border-[var(--hub-line)] rounded-lg bg-[var(--hub-surface)] hover:border-[var(--hub-ink-3)] hover:bg-[var(--hub-surface-hover)] transition-colors",children:[e.jsxs("div",{className:"flex items-center justify-between p-3 cursor-pointer rounded-lg transition-colors",onClick:()=>T(r.name),children:[e.jsxs("div",{className:"flex items-center space-x-3",onClick:N=>{N.stopPropagation(),y(r.name)},children:[e.jsx("input",{type:"checkbox",checked:c||n,onChange:()=>y(r.name),className:"w-4 h-4 text-blue-600 accent-[var(--hub-accent)] rounded focus:ring-blue-500"}),e.jsx("span",{className:"font-medium text-[var(--hub-ink)] cursor-pointer select-none",children:r.name})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[_(r)>0&&e.jsxs("span",{className:"text-sm text-[var(--hub-ink-3)] hub-mono",title:i("cost.estimate"),children:["Σ ",H(_(r))]}),G.map(({key:N,count:W})=>e.jsxs("span",{className:"text-sm text-green-600 flex items-center gap-1",children:[N==="tools"?e.jsx(Ae,{size:14}):N==="prompts"?e.jsx(Te,{size:14}):e.jsx(Ee,{size:14})," ",W]},N)),z.length>0&&e.jsx("button",{type:"button",className:"p-1 text-[var(--hub-ink-3)] hover:text-[var(--hub-ink-2)] transition-colors",children:e.jsx("svg",{className:Z("w-5 h-5 transition-transform",C&&"rotate-180"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})})]})]}),C&&z.length>0&&e.jsx("div",{className:"border-t border-[var(--hub-line)] bg-[var(--hub-bg-2)] p-3",children:e.jsxs("div",{className:"space-y-4",children:[f&&e.jsxs("div",{className:"space-y-1",onClick:N=>N.stopPropagation(),children:[e.jsx("label",{htmlFor:`${u}-${r.name}`,className:"block text-xs font-medium text-[var(--hub-ink-2)]",children:i("groups.alias")}),e.jsx("input",{type:"text",id:`${u}-${r.name}`,value:f.alias||"",placeholder:r.name,onChange:N=>p(r.name,N.target.value),className:"hub-input"}),e.jsxs("label",{className:"flex items-center gap-2 text-xs text-[var(--hub-ink-2)]",children:[e.jsx("input",{type:"checkbox",checked:f.preserveToolNames===!0,onChange:N=>s(m.map(W=>W.name===r.name?{...W,preserveToolNames:N.target.checked}:W))}),i("groups.preserveToolNames")]}),e.jsx("p",{className:"text-xs text-[var(--hub-ink-3)]",children:i("groups.preserveToolNamesHint")})]}),z.map(({key:N,titleKey:W,countKey:be,allKey:ge})=>{const V=v(r,N),ae=B(r,N),Y=(f==null?void 0:f[N])==="all"||ae===V.length;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--hub-ink-2)]",children:i(W)}),e.jsxs("div",{className:"flex items-center gap-3",children:[f&&e.jsx("span",{className:"text-xs text-green-600",children:Y?`(${i(ge)} ${V.length}/${V.length})`:`(${i(be)} ${ae}/${V.length})`}),f&&U(r,N)>0&&e.jsxs("span",{className:"text-xs text-[var(--hub-ink-3)] hub-mono",title:i("cost.estimate"),children:["Σ ",H(U(r,N))]}),e.jsx("button",{type:"button",onClick:()=>{x(r.name,N,Y?[]:"all",!0)},className:"text-sm text-blue-600 hover:text-blue-800 transition-colors",children:i(Y?"groups.selectNone":"groups.selectAll")})]})]}),e.jsx(Be,{items:V,selection:(f==null?void 0:f[N])??[],tools:N==="tools",label:i(W),onChange:R=>x(r.name,N,R,!0),children:R=>{var ie;const ne=J(r.name,N,R.value),q=!!((ie=f==null?void 0:f.pinnedTools)!=null&&ie.includes(R.value)),L=N==="tools"?ke({description:R.description,defaultDescription:R.defaultDescription,hasDescriptionOverride:R.hasDescriptionOverride},i("tool.noDescription")):null,le=L!=null&&L.hasDescriptionOverride?i("tool.defaultDescriptionTooltip",{description:L.defaultDescription}):R.description;return e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsxs("label",{className:"flex min-w-0 flex-1 items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:ne,onChange:()=>X(r.name,N,R.value),className:"w-3 h-3 text-blue-600 accent-[var(--hub-accent)] rounded focus:ring-blue-500"}),e.jsx("span",{className:"text-[var(--hub-ink-2)] break-all whitespace-nowrap flex-shrink-0",children:R.value}),(R.description||(L==null?void 0:L.hasDescriptionOverride))&&e.jsxs("span",{className:"min-w-0 flex items-center gap-1 text-[var(--hub-ink-3)] text-xs truncate",children:[e.jsx("span",{className:"truncate",title:le||void 0,children:L?L.currentDescription:R.description}),(L==null?void 0:L.hasDescriptionOverride)&&e.jsx("span",{className:"inline-flex flex-shrink-0 items-center rounded-full border border-amber-200 bg-amber-50 px-1.5 py-0.5 text-[10px] font-medium text-amber-700 dark:border-amber-700/60 dark:bg-amber-900/20 dark:text-amber-300",title:le||void 0,children:i("tool.descriptionModifiedBadge")})]}),S.get(R.key)!=null&&e.jsxs("span",{className:"text-xs text-[var(--hub-ink-3)] hub-mono whitespace-nowrap ml-auto flex-shrink-0",title:i("cost.estimate"),children:["Σ ",H(S.get(R.key))]})]}),N==="tools"&&ne&&(F.enabled||q)&&e.jsx("button",{type:"button",onClick:()=>t(r.name,R.value),title:i(q?"groups.unpinTool":"groups.pinTool"),"aria-label":i("groups.pinToolLabel"),"aria-pressed":q,className:Z("flex-shrink-0 transition-colors",q?"text-blue-600":"text-[var(--hub-ink-3)] hover:text-[var(--hub-ink-2)]"),children:e.jsx(De,{size:12,fill:q?"currentColor":"none"})})]},R.key)}})]},N)})]})})]},r.name)})}),j.length===0&&e.jsx("p",{className:"text-[var(--hub-ink-3)] text-sm",children:i("groups.noServerOptions")})]})};function he({groupId:a,value:d,onChange:s}){const{t:l}=$(),[b,i]=g.useState([]),[u,E]=g.useState(""),[F,w]=g.useState([]),[A,m]=g.useState(!1),[j,y]=g.useState(!1),[T,h]=g.useState(!1);g.useEffect(()=>{if(!a||d.visibility!=="group")return;let k=!1;return m(!0),y(!1),fe(`/groups/${encodeURIComponent(a)}/share-candidates`).then(U=>{k||(U.success&&Array.isArray(U.data)?(i(U.data),w(U.userGroups||[])):y(!0))}).catch(()=>{k||y(!0)}).finally(()=>{k||m(!1)}),()=>{k=!0}},[a,d.visibility]);const x=d.sharedWithUsers||[],p=[...new Set([...b,...x])].sort().filter(k=>k.toLowerCase().includes(u.toLowerCase())),t=new Set(x),o=p.length>0&&p.every(k=>t.has(k)),v=p.length===0||p.every(k=>!t.has(k)),D=k=>{const U=new Set(x);U.has(k)?U.delete(k):U.add(k),s({sharedWithUsers:Array.from(U)})};return e.jsxs("div",{className:"mb-4",children:[e.jsxs("div",{className:"flex items-center justify-between cursor-pointer bg-[var(--hub-bg-2)] hover:bg-[var(--hub-surface-hover)] p-3 rounded border border-[var(--hub-line)]",onClick:()=>h(!T),children:[e.jsx("h3",{className:"text-sm font-semibold text-[var(--hub-ink)]",children:l("server.sectionAdvanced","Advanced Options")}),e.jsx("span",{className:"text-[var(--hub-ink-3)] text-sm",children:T?"▼":"▶"})]}),T&&e.jsxs("div",{className:"border border-[var(--hub-line)] rounded-b p-4 bg-[var(--hub-surface)] border-t-0",children:[e.jsx("label",{htmlFor:"group-visibility",className:"block text-sm font-medium mb-1.5 text-[var(--hub-ink-2)]",children:l("server.visibility")}),e.jsxs("select",{id:"group-visibility",className:"hub-input",value:d.visibility||"",onChange:k=>s({visibility:k.target.value}),children:[!d.visibility&&e.jsx("option",{value:"",disabled:!0,children:l("groups.legacyVisibility")}),e.jsx("option",{value:"private",children:l("server.visibilityPrivate")}),e.jsx("option",{value:"group",children:l("server.visibilityGroup")}),e.jsx("option",{value:"public",children:l("server.visibilityPublic")})]}),e.jsx("p",{className:"text-xs text-[var(--hub-ink-3)] mt-1",children:l("groups.visibilityDescription")}),!d.visibility&&e.jsx("p",{className:"text-sm text-amber-600",children:l("groups.legacyVisibilityHint")}),d.visibility==="group"&&e.jsxs("div",{className:"mt-4 rounded border border-[var(--hub-line)] p-3",children:[e.jsx(We,{options:F,selected:d.sharedWithUserGroups||[],disabled:A||j||!a,onChange:k=>s({sharedWithUserGroups:k})}),e.jsx("div",{className:"text-sm font-medium text-[var(--hub-ink-2)]",children:l("server.shareWithUsers")}),e.jsx("p",{className:"text-xs text-[var(--hub-ink-3)] mt-1 mb-3",children:l("server.shareWithUsersDescription")}),a?e.jsxs(e.Fragment,{children:[A&&e.jsx("p",{className:"text-sm text-[var(--hub-ink-3)]",children:l("server.shareCandidatesLoading")}),j&&e.jsx("p",{role:"alert",className:"text-sm text-red-600 dark:text-red-400",children:l("server.shareCandidatesError")}),!A&&!j&&p.length===0&&e.jsx("p",{className:"text-sm text-[var(--hub-ink-3)]",children:l(u?"server.noMatchingShareUsers":"server.noShareCandidates")}),p.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mb-3 space-y-2",children:[e.jsx("label",{htmlFor:"group-share-search",className:"block text-xs font-medium text-[var(--hub-ink-2)]",children:l("server.shareUserSearchLabel")}),e.jsx("input",{id:"group-share-search",type:"search",value:u,onChange:k=>E(k.target.value),placeholder:l("server.shareUserSearchPlaceholder"),className:"hub-input text-sm"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",onClick:()=>s({sharedWithUsers:[...new Set([...x,...p])]}),disabled:o,className:"hub-btn text-sm",children:l("server.selectAllShareUsers")}),e.jsx("button",{type:"button",onClick:()=>s({sharedWithUsers:x.filter(k=>!p.includes(k))}),disabled:v,className:"hub-btn text-sm",children:l("server.deselectAllShareUsers")})]})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2",children:p.map(k=>e.jsxs("label",{className:"flex items-center gap-2 rounded border border-[var(--hub-line)] px-3 py-2 text-sm text-[var(--hub-ink-2)]",children:[e.jsx("input",{type:"checkbox",checked:t.has(k),onChange:()=>D(k)}),e.jsx("span",{children:k})]},k))})]})]}):e.jsx("p",{className:"text-sm text-[var(--hub-ink-3)]",children:l("groups.shareAfterCreate")})]})]})]})}const qe=({onAdd:a,onCancel:d})=>{const{t:s}=$(),{createGroup:l}=ee(),{allServers:b}=te(),{serverCosts:i}=re(),[u,E]=g.useState([]),[F,w]=g.useState(null),[A,m]=g.useState(!1),[j,y]=g.useState({visibility:"private",sharedWithUserGroups:[],sharedWithUsers:[],name:"",description:"",instructions:"",servers:[]});g.useEffect(()=>{E(b.filter(x=>x.enabled!==!1))},[b]);const T=x=>{const{name:p,value:t}=x.target;y(o=>({...o,[p]:t}))},h=async x=>{x.preventDefault(),m(!0),w(null);try{if(!j.name.trim()){w(s("groups.nameRequired")),m(!1);return}const p=await l(j.name,j.description,j.servers,{visibility:j.visibility,sharedWithUserGroups:j.sharedWithUserGroups,sharedWithUsers:j.sharedWithUsers,instructions:j.instructions});if(!p||!p.success){w((p==null?void 0:p.message)||s("groups.createError")),m(!1);return}a()}catch(p){w(p instanceof Error?p.message:String(p)),m(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"hub-card shadow-lg max-w-3xl w-full max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"p-6 flex-shrink-0",children:[e.jsx("h2",{className:"text-xl font-semibold text-[var(--hub-ink)] mb-4",children:s("groups.addNew")}),F&&e.jsx("div",{className:"mb-4 p-3 bg-red-100 text-red-700 rounded-md border border-[var(--hub-line)]",children:F})]}),e.jsxs("form",{onSubmit:h,className:"flex flex-col flex-1 min-h-0",children:[e.jsx("div",{className:"flex-1 overflow-y-auto px-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-[var(--hub-ink-2)] text-sm font-bold mb-2",htmlFor:"name",children:[s("groups.name")," *"]}),e.jsx("input",{type:"text",id:"name",name:"name",value:j.name,onChange:T,className:"w-full border border-[var(--hub-line)] bg-[var(--hub-surface)] rounded-md px-3 py-2 text-[var(--hub-ink)] placeholder:text-[var(--hub-ink-3)] focus:outline-none focus:border-[var(--hub-ink-2)]",placeholder:s("groups.namePlaceholder"),required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[var(--hub-ink-2)] text-sm font-bold mb-2",htmlFor:"instructions",children:s("groups.instructions")}),e.jsx("textarea",{id:"instructions",name:"instructions",value:j.instructions,onChange:T,rows:3,className:"w-full border border-[var(--hub-line)] bg-[var(--hub-surface)] rounded-md px-3 py-2 text-[var(--hub-ink)] placeholder:text-[var(--hub-ink-3)] focus:outline-none focus:border-[var(--hub-ink-2)]",placeholder:s("groups.instructionsPlaceholder")}),e.jsx("p",{className:"text-xs text-[var(--hub-ink-3)] mt-1",children:s("groups.instructionsHelp")})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[var(--hub-ink-2)] text-sm font-bold mb-2",children:s("groups.configureCapabilities")}),e.jsx(pe,{servers:u,value:j.servers,onChange:x=>y(p=>({...p,servers:x})),className:"border border-[var(--hub-line)] rounded-lg p-4 bg-[var(--hub-bg-2)]",serverCosts:i})]}),e.jsx(he,{value:j,onChange:x=>y(p=>({...p,...x}))})]})}),e.jsxs("div",{className:"flex justify-end space-x-2 p-5 pt-3 border-t border-[var(--hub-line-2)] flex-shrink-0",children:[e.jsx("button",{type:"button",onClick:d,className:"hub-btn",disabled:A,children:s("common.cancel")}),e.jsx("button",{type:"submit",className:"hub-btn primary",disabled:A,children:s(A?"common.submitting":"common.create")})]})]})]})})},Ke=({group:a,onEdit:d,onCancel:s})=>{const{t:l}=$(),{updateGroup:b}=ee(),{allServers:i}=te(),{serverCosts:u}=re(),[E,F]=g.useState([]),[w,A]=g.useState(null),[m,j]=g.useState(!1),[y,T]=g.useState({visibility:a.visibility,sharedWithUserGroups:a.sharedWithUserGroups||[],sharedWithUsers:a.sharedWithUsers||[],name:a.name,description:a.description||"",instructions:a.instructions||"",servers:a.servers||[]});g.useEffect(()=>{F(i.filter(p=>p.enabled!==!1))},[i]);const h=p=>{const{name:t,value:o}=p.target;T(v=>({...v,[t]:o}))},x=async p=>{p.preventDefault(),j(!0),A(null);try{if(!y.name.trim()){A(l("groups.nameRequired")),j(!1);return}const t=await b(a.id,{visibility:y.visibility,sharedWithUserGroups:y.sharedWithUserGroups,sharedWithUsers:y.sharedWithUsers,name:y.name,description:y.description,instructions:y.instructions,servers:y.servers});if(!t||!t.success){A((t==null?void 0:t.message)||l("groups.updateError")),j(!1);return}d()}catch(t){A(t instanceof Error?t.message:String(t)),j(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"hub-card shadow-lg max-w-3xl w-full max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"p-6 flex-shrink-0",children:[e.jsx("h2",{className:"text-xl font-semibold text-[var(--hub-ink)] mb-4",children:l("groups.edit")}),w&&e.jsx("div",{className:"mb-4 p-3 bg-red-100 text-red-700 rounded-md border border-[var(--hub-line)]",children:w})]}),e.jsxs("form",{onSubmit:x,className:"flex flex-col flex-1 min-h-0",children:[e.jsx("div",{className:"flex-1 overflow-y-auto px-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-[var(--hub-ink-2)] text-sm font-bold mb-2",htmlFor:"name",children:[l("groups.name")," *"]}),e.jsx("input",{type:"text",id:"name",name:"name",value:y.name,onChange:h,className:"w-full border border-[var(--hub-line)] bg-[var(--hub-surface)] rounded-md px-3 py-2 text-[var(--hub-ink)] placeholder:text-[var(--hub-ink-3)] focus:outline-none focus:border-[var(--hub-ink-2)]",placeholder:l("groups.namePlaceholder"),required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[var(--hub-ink-2)] text-sm font-bold mb-2",htmlFor:"instructions",children:l("groups.instructions")}),e.jsx("textarea",{id:"instructions",name:"instructions",value:y.instructions,onChange:h,rows:3,className:"w-full border border-[var(--hub-line)] bg-[var(--hub-surface)] rounded-md px-3 py-2 text-[var(--hub-ink)] placeholder:text-[var(--hub-ink-3)] focus:outline-none focus:border-[var(--hub-ink-2)]",placeholder:l("groups.instructionsPlaceholder")}),e.jsx("p",{className:"text-xs text-[var(--hub-ink-3)] mt-1",children:l("groups.instructionsHelp")})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[var(--hub-ink-2)] text-sm font-bold mb-2",children:l("groups.configureCapabilities")}),e.jsx(pe,{servers:E,value:y.servers,onChange:p=>T(t=>({...t,servers:p})),className:"border border-[var(--hub-line)] rounded-lg p-4 bg-[var(--hub-bg-2)]",serverCosts:u})]}),e.jsx(he,{groupId:a.id,value:y,onChange:p=>T(t=>({...t,...p}))})]})}),e.jsxs("div",{className:"flex justify-end space-x-2 p-5 pt-3 border-t border-[var(--hub-line-2)] flex-shrink-0",children:[e.jsx("button",{type:"button",onClick:s,className:"hub-btn",disabled:m,children:l("common.cancel")}),e.jsx("button",{type:"submit",className:"hub-btn primary",disabled:m,children:l(m?"common.submitting":"common.save")})]})]})]})})},Je=a=>a.map(d=>typeof d=="string"?d:d.name),xe=(a,d)=>{const s=a.servers.find(l=>typeof l=="string"?l===d:l.name===d);return s?typeof s=="string"?{name:s,tools:"all",prompts:"all",resources:"all"}:s:{name:d,tools:"all",prompts:"all",resources:"all"}},Qe=(a,d)=>{var l;return((l=xe(a,d).alias)==null?void 0:l.trim())||d},Xe=({group:a,servers:d,onEdit:s,onDelete:l,cost:b})=>{var B;const{t:i}=$(),{auth:u}=ve(),E=!!u.user&&(u.user.isAdmin||u.user.username===a.owner),{showToast:F}=je(),{installConfig:w,nameSeparator:A}=me(),m=((B=w==null?void 0:w.baseUrl)==null?void 0:B.replace(/\/+$/,""))||"",[j,y]=g.useState(!1),[T,h]=g.useState(null),[x,p]=g.useState(!1),[t,o]=g.useState(!1),v=g.useRef(null);g.useEffect(()=>{const I=P=>{v.current&&!v.current.contains(P.target)&&o(!1)};return document.addEventListener("mousedown",I),()=>document.removeEventListener("mousedown",I)},[]);const D=async I=>{await ye(I)?(p(!0),o(!1),F(i("common.copySuccess")||"Copied","success"),setTimeout(()=>p(!1),1500)):F(i("common.copyFailed")||"Copy failed","error")},k=`${m}/mcp/${a.name}`,U=`${m}/mcp/${encodeURIComponent(a.name)}`,_=`${m}/api/${a.name}`,X=Je(a.servers),O=d.filter(I=>X.includes(I.name)),K=I=>{const P=xe(a,I.name),r=`${I.name}${A}`,c=I.tools||[],n=I.prompts||[],C=I.resources||[],f=Array.isArray(P.tools)?c.filter(S=>{if(S.enabled===!1)return!1;const N=S.name.startsWith(r)?S.name.slice(r.length):S.name;return P.tools.includes(N)}).length:c.filter(S=>S.enabled!==!1).length,G=Array.isArray(P.prompts)?n.filter(S=>{if(S.enabled===!1)return!1;const N=S.name.startsWith(r)?S.name.slice(r.length):S.name;return P.prompts.includes(N)}).length:n.filter(S=>S.enabled!==!1).length,z=Array.isArray(P.resources)?C.filter(S=>S.enabled!==!1&&P.resources.includes(S.uri)).length:C.filter(S=>S.enabled!==!1).length;return{visibleTools:f,totalTools:c.length,visiblePrompts:G,totalPrompts:n.length,visibleResources:z,totalResources:C.length}},J=O.reduce((I,P)=>I+K(P).visibleTools,0);return e.jsxs("div",{className:"hub-card flex h-full flex-col overflow-visible",children:[e.jsxs("div",{className:"flex items-start gap-3 px-4 py-3",style:{borderBottom:"1px solid var(--hub-line-2)"},children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{style:{fontSize:15,fontWeight:600,letterSpacing:"-0.015em"},children:a.name}),e.jsx("span",{className:"hub-mono",style:{fontSize:11,color:"var(--hub-ink-3)",padding:"0 6px",border:"1px solid var(--hub-line)",borderRadius:4,height:18,display:"inline-flex",alignItems:"center"},title:a.id,children:a.id})]}),e.jsx("div",{className:"mt-1 text-xs text-[var(--hub-ink-3)]",children:a.visibility?i(`server.visibility${a.visibility==="group"?"Group":a.visibility==="public"?"Public":"Private"}`):i("groups.legacyVisibility")}),a.description&&e.jsx("div",{style:{fontSize:12.5,color:"var(--hub-ink-3)",marginTop:2},children:a.description})]}),e.jsxs("div",{className:"flex items-center gap-1",ref:v,children:[e.jsxs("div",{className:"relative",children:[e.jsx("button",{onClick:()=>o(I=>!I),className:"hub-icon-btn sm",title:i("common.copy"),children:x?e.jsx(Ie,{size:13,className:"text-[var(--hub-ok)]"}):e.jsx(Q,{size:13})}),t&&e.jsxs("div",{className:"absolute top-full right-0 mt-1 z-20 hub-card",style:{minWidth:160,padding:4},children:[e.jsxs("button",{onClick:()=>D(a.id),className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(Q,{size:12})," ",i("common.copyId")]}),e.jsxs("button",{onClick:()=>D(k),className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(oe,{size:12})," ",i("common.copyUrl")]}),e.jsxs("button",{onClick:()=>D(_),className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(oe,{size:12})," ",i("common.copyOpenApiUrl")]}),e.jsxs("button",{onClick:()=>{o(!1),h({name:a.name,url:U,headers:{Authorization:`Bearer ${Se}`}})},className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(Fe,{size:12})," ",i("clientConfig.menuItem")]})]})]}),E&&e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:()=>s(a),className:"hub-icon-btn sm",title:i("groups.edit"),children:e.jsx(ze,{size:13})}),e.jsx("button",{onClick:()=>y(!0),className:"hub-icon-btn sm",title:i("groups.delete"),style:{color:"var(--hub-ink-3)"},children:e.jsx(Ue,{size:13})})]})]})]}),e.jsxs("div",{className:"grid flex-1 items-center gap-3 px-4 py-3",style:{gridTemplateColumns:"1fr 80px 1fr",minHeight:180},children:[e.jsx("div",{className:"flex flex-col gap-1.5",children:O.length===0?e.jsx("div",{style:{fontSize:12,color:"var(--hub-ink-3)"},children:i("groups.noServers")}):O.map(I=>{const P=K(I);return e.jsxs("div",{className:"flex items-center gap-2.5 px-2.5 py-1.5 rounded-md",style:{background:"var(--hub-bg-2)",border:"1px solid var(--hub-line-2)"},children:[e.jsx("span",{className:"inline-block flex-shrink-0",style:{width:6,height:6,borderRadius:50,background:I.status==="connected"?"var(--hub-ok)":I.status==="connecting"?"var(--hub-warn)":"var(--hub-err)"}}),e.jsx("span",{className:"hub-mono truncate flex-1",style:{fontSize:12.5},children:e.jsx("span",{title:I.name,children:Qe(a,I.name)})}),e.jsxs("span",{className:"hub-mono hub-num flex-shrink-0",style:{fontSize:11,color:"var(--hub-ink-3)"},children:[P.visibleTools,"/",P.totalTools," tools"]})]},I.name)})}),e.jsxs("svg",{width:"80",height:"80",viewBox:"0 0 80 80",className:"self-center",children:[O.length===0?e.jsx("path",{d:"M0,40 C30,40 50,40 80,40",stroke:"var(--hub-line)",strokeWidth:"1",fill:"none",strokeDasharray:"3 3"}):O.map((I,P)=>{const r=12+60/Math.max(O.length,1)*(P+.5);return e.jsx("path",{d:`M0,${r} C 30,${r} 50,40 80,40`,stroke:"var(--hub-line)",strokeWidth:"1",fill:"none",strokeDasharray:"3 3"},P)}),e.jsx("circle",{cx:"80",cy:"40",r:"4",fill:"var(--hub-ink)"})]}),e.jsxs("div",{className:"px-3 py-2.5 rounded-md",style:{border:"1px solid var(--hub-line)",background:"var(--hub-bg-2)"},children:[e.jsx("div",{className:"hub-sect",style:{marginBottom:4},children:"endpoint"}),e.jsxs("div",{className:"hub-mono break-all",style:{fontSize:12,color:"var(--hub-ink-2)",lineHeight:1.4},children:[e.jsx("span",{style:{color:"var(--hub-ink-3)"},children:"/mcp/"}),e.jsx("b",{style:{color:"var(--hub-ink)",fontWeight:600},children:a.name})]}),e.jsxs("div",{className:"hub-mono break-all",style:{fontSize:12,color:"var(--hub-ink-2)",lineHeight:1.4},children:[e.jsx("span",{style:{color:"var(--hub-ink-3)"},children:"/api/"}),e.jsx("b",{style:{color:"var(--hub-ink)",fontWeight:600},children:a.name})]}),e.jsxs("div",{className:"flex gap-1.5 mt-2",children:[e.jsxs("button",{className:"hub-btn sm flex-1 justify-center",onClick:()=>D(k),title:i("common.copyUrl"),children:[e.jsx(Q,{size:11})," MCP"]}),e.jsxs("button",{className:"hub-btn sm flex-1 justify-center",onClick:()=>D(_),title:i("common.copyOpenApiUrl"),children:[e.jsx(Q,{size:11})," OpenAPI"]})]})]})]}),e.jsxs("div",{className:"flex justify-between items-center px-4 py-2",style:{borderTop:"1px solid var(--hub-line-2)",background:"var(--hub-bg-2)",fontSize:12,color:"var(--hub-ink-3)"},children:[e.jsxs("div",{children:[e.jsxs("div",{className:"hub-mono",children:[e.jsx("span",{style:{color:"var(--hub-ink-2)"},children:O.length})," ",i("nav.servers").toLowerCase()," ·"," ",e.jsx("span",{style:{color:"var(--hub-ink-2)"},children:J})," ",i("server.tools").toLowerCase()]}),b&&e.jsxs("div",{className:"hub-mono mt-1",style:{fontSize:11.5,color:"var(--hub-ink-3)"},children:[e.jsxs("div",{title:i("cost.estimate"),children:[i("cost.totalFootprint"),": ",H(b.direct.exposed),"/",H(b.direct.gross)]}),b.smartRouting&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[i("cost.smartRouting"),": ",H(b.smartRouting.base)," (",i("cost.saved",{percent:Ne(b.direct.exposed,b.smartRouting.base)}),")"]}),e.jsxs("div",{title:i("cost.smartRoutingPdHint"),children:[i("cost.smartRoutingPd"),":"," ",H(b.smartRouting.progressiveDisclosure)]})]}),b.connectedCount<b.totalCount&&e.jsx("div",{children:i("cost.connectedOf",{connected:b.connectedCount,total:b.totalCount})})]})]}),E&&e.jsxs("button",{className:"hub-btn ghost sm",style:{color:"var(--hub-ink-3)"},onClick:()=>s(a),children:[i("groups.configureTools")||i("groups.edit"),e.jsx(Ge,{size:11,style:{transform:"rotate(-90deg)"}})]})]}),e.jsx(we,{isOpen:T!==null,target:T,onClose:()=>h(null)}),e.jsx($e,{isOpen:j,onClose:()=>y(!1),onConfirm:()=>{l(a.id),y(!1)},serverName:a.name,isGroup:!0})]})},Ye=({onSuccess:a,onCancel:d})=>{const{t:s}=$(),[l,b]=g.useState(""),[i,u]=g.useState(null),[E,F]=g.useState(!1),[w,A]=g.useState(null),m=`{
2
+ "groups": [
3
+ {
4
+ "name": "AI Assistants",
5
+ "servers": ["openai-server", "anthropic-server"]
6
+ },
7
+ {
8
+ "name": "Development Tools",
9
+ "servers": [
10
+ {
11
+ "name": "github-server",
12
+ "tools": ["create_issue", "list_repos"],
13
+ "prompts": ["triage_prompt"],
14
+ "resources": ["resource://docs/repo-guide"]
15
+ },
16
+ {
17
+ "name": "gitlab-server",
18
+ "tools": "all",
19
+ "prompts": "all",
20
+ "resources": "all"
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ }
26
+
27
+ Supports:
28
+ - Simple server list: ["server1", "server2"]
29
+ - Advanced server config: [{"name": "server1", "tools": ["tool1"], "prompts": ["prompt1"], "resources": ["resource://docs/guide"]}]
30
+ - All groups will be imported in a single efficient batch operation.`,j=t=>{try{const o=JSON.parse(t.trim());if(!o.groups||!Array.isArray(o.groups))return u(s("groupImport.invalidFormat")),null;for(const v of o.groups)if(!v.name||typeof v.name!="string")return u(s("groupImport.missingName")),null;return o}catch{return u(s("groupImport.parseError")),null}},y=()=>{u(null);const t=j(l);t&&A(t.groups)},T=async()=>{if(w){F(!0),u(null);try{const t=await se("/groups/batch",{groups:w});if(t.success){const{successCount:o,failureCount:v,results:D}=t;if(v>0){const k=D.filter(U=>!U.success).map(U=>`${U.name}: ${U.message||s("groupImport.addFailed")}`);u(s("groupImport.partialSuccess",{count:o,total:w.length})+`
31
+ `+k.join(`
32
+ `))}o>0&&a()}else u(t.message||s("groupImport.importFailed"))}catch(t){console.error("Import error:",t),u(s("groupImport.importFailed"))}finally{F(!1)}}},h=t=>e.jsx("span",{className:"text-gray-500 ml-2",children:s(`groups.${t}`)}),x=(t,o)=>{if(!o||o==="all")return null;const v=Array.isArray(o)?o.join(", "):o;return e.jsx("span",{className:"text-gray-500 ml-2",children:s(`groups.${t}`,{items:v})})},p=t=>!t||t.length===0?e.jsx("span",{className:"text-gray-500",children:s("groups.noServers")}):e.jsx("div",{className:"space-y-1",children:t.map((o,v)=>typeof o=="string"?e.jsxs("div",{className:"text-sm",children:["• ",o]},v):e.jsxs("div",{className:"text-sm",children:["• ",o.name,o.tools&&o.tools!=="all"&&e.jsxs("span",{className:"text-gray-500 ml-2",children:["(",Array.isArray(o.tools)?o.tools.join(", "):o.tools,")"]}),o.tools==="all"&&h("previewAllTools"),x("previewPrompts",o.prompts),o.prompts==="all"&&h("previewAllPrompts"),x("previewResources",o.resources),o.resources==="all"&&h("previewAllResources")]},v))});return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:s("groupImport.title")}),e.jsx("button",{onClick:d,className:"text-gray-500 hover:text-gray-700",children:"✕"})]}),i&&e.jsx("div",{className:"mb-4 bg-red-50 border-l-4 border-red-500 p-4 rounded",children:e.jsx("p",{className:"text-red-700 whitespace-pre-wrap",children:i})}),w?e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-3",children:s("groupImport.previewTitle")}),e.jsx("div",{className:"space-y-3",children:w.map((t,o)=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700",children:e.jsx("div",{className:"flex items-start justify-between",children:e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium text-gray-900",children:t.name}),t.description&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:t.description}),e.jsxs("div",{className:"mt-2 text-sm text-gray-600",children:[e.jsxs("strong",{children:[s("groups.servers"),":"]}),e.jsx("div",{className:"mt-1",children:p(t.servers)})]})]})})},o))})]}),e.jsxs("div",{className:"flex justify-end space-x-4",children:[e.jsx("button",{onClick:()=>A(null),disabled:E,className:"hub-btn",children:s("common.back")}),e.jsx("button",{onClick:T,disabled:E,className:"hub-btn primary",children:E?e.jsxs(e.Fragment,{children:[e.jsxs("svg",{className:"animate-spin h-4 w-4 mr-2",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),e.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),s("groupImport.importing")]}):s("groupImport.import")})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:s("groupImport.inputLabel")}),e.jsx("textarea",{value:l,onChange:t=>b(t.target.value),className:"w-full h-96 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm",placeholder:m}),e.jsx("p",{className:"text-xs text-gray-500 mt-2",children:s("groupImport.inputHelp")})]}),e.jsxs("div",{className:"flex justify-end space-x-4",children:[e.jsx("button",{onClick:d,className:"hub-btn",children:s("common.cancel")}),e.jsx("button",{onClick:y,disabled:!l.trim(),className:"hub-btn primary",children:s("groupImport.preview")})]})]})]})})},Ze=({groups:a,onCancel:d})=>{const{t:s}=$(),[l,b]=g.useState(""),[i,u]=g.useState(""),[E,F]=g.useState([]),[w,A]=g.useState(!1),[m,j]=g.useState(!1),[y,T]=g.useState(null),h=t=>{F(o=>o.includes(t)?o.filter(v=>v!==t):[...o,t])},x=()=>{E.length===a.length?F([]):F(a.map(t=>t.id))},p=async()=>{if(!l.trim()){T(s("template.nameRequired"));return}j(!0),T(null);try{const t=await se("/templates/export",{name:l.trim(),description:i.trim()||void 0,groupIds:E.length>0?E:void 0,includeDisabledServers:w});if(t.success&&t.data){const o=t.data,v=new Blob([JSON.stringify(o,null,2)],{type:"application/json"}),D=URL.createObjectURL(v),k=document.createElement("a");k.href=D,k.download=`${o.name.replace(/[^a-zA-Z0-9-_]/g,"_")}.mcphub-template.json`,document.body.appendChild(k),k.click(),document.body.removeChild(k),URL.revokeObjectURL(D),d()}else T(t.message||s("template.exportFailed"))}catch(t){console.error("Export error:",t),T(s("template.exportFailed"))}finally{j(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6 w-full max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:s("template.exportTitle")}),e.jsx("button",{onClick:d,className:"text-gray-500 hover:text-gray-700",children:"✕"})]}),y&&e.jsx("div",{className:"mb-4 bg-red-50 dark:bg-red-900/20 border-l-4 border-red-500 p-4 rounded",children:e.jsx("p",{className:"text-red-700 dark:text-red-300",children:y})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:[s("template.name")," *"]}),e.jsx("input",{type:"text",value:l,onChange:t=>b(t.target.value),className:"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:s("template.namePlaceholder")})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:s("template.description")}),e.jsx("input",{type:"text",value:i,onChange:t=>u(t.target.value),className:"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:s("template.descriptionPlaceholder")})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700",children:s("template.selectGroups")}),e.jsx("button",{onClick:x,className:"text-sm text-blue-600 hover:text-blue-800 dark:text-blue-300",children:E.length===a.length?s("template.deselectAll"):s("template.selectAll")})]}),e.jsx("p",{className:"text-xs text-gray-500 mb-2",children:s("template.selectGroupsHelp")}),e.jsx("div",{className:"border border-gray-200 dark:border-gray-700 rounded-md max-h-48 overflow-y-auto",children:a.map(t=>e.jsxs("label",{className:"flex items-center px-3 py-2 hover:bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:E.includes(t.id),onChange:()=>h(t.id),className:"mr-3 h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-gray-900",children:t.name}),t.description&&e.jsx("span",{className:"text-xs text-gray-500 ml-2",children:t.description})]})]},t.id))})]}),e.jsxs("label",{className:"flex items-center space-x-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:w,onChange:t=>A(t.target.checked),className:"h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"}),e.jsx("span",{className:"text-sm text-gray-700",children:s("template.includeDisabled")})]})]}),e.jsx("div",{className:"mt-4 p-3 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-700/60 rounded-md",children:e.jsx("p",{className:"text-sm text-blue-700 dark:text-blue-300",children:s("template.exportNote")})}),e.jsxs("div",{className:"flex justify-end space-x-4 mt-6",children:[e.jsx("button",{onClick:d,className:"hub-btn",children:s("common.cancel")}),e.jsx("button",{onClick:p,disabled:m||!l.trim(),className:"hub-btn primary",children:s(m?"template.exporting":"template.export")})]})]})})},es=({onSuccess:a,onCancel:d})=>{const{t:s}=$(),[l,b]=g.useState(null),[i,u]=g.useState(null),[E,F]=g.useState(!1),[w,A]=g.useState(null),m=g.useRef(null),j=h=>{var t;u(null),b(null),A(null);const x=(t=h.target.files)==null?void 0:t[0];if(!x)return;const p=new FileReader;p.onload=o=>{var v;try{const D=JSON.parse((v=o.target)==null?void 0:v.result);if(!D.version||!D.name||!D.servers||!D.groups){u(s("template.invalidFormat"));return}b(D)}catch{u(s("template.parseError"))}},p.readAsText(x)},y=h=>{if(u(null),b(null),A(null),!!h.trim())try{const x=JSON.parse(h.trim());if(!x.version||!x.name||!x.servers||!x.groups){u(s("template.invalidFormat"));return}b(x)}catch{u(s("template.parseError"))}},T=async()=>{if(l){F(!0),u(null);try{const h=await se("/templates/import",l);h.data?(A(h.data),h.data.success&&a()):u(h.message||s("template.importFailed"))}catch(h){console.error("Import error:",h),u(s("template.importFailed"))}finally{F(!1)}}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:s("template.importTitle")}),e.jsx("button",{onClick:d,className:"text-gray-500 hover:text-gray-700",children:"✕"})]}),i&&e.jsx("div",{className:"mb-4 bg-red-50 dark:bg-red-900/20 border-l-4 border-red-500 p-4 rounded",children:e.jsx("p",{className:"text-red-700 dark:text-red-300",children:i})}),w&&e.jsxs("div",{className:`mb-4 p-4 rounded border-l-4 ${w.success?"bg-green-50 dark:bg-green-900/20 border-green-500":"bg-yellow-50 dark:bg-yellow-900/20 border-yellow-500"}`,children:[e.jsx("p",{className:w.success?"text-green-700 dark:text-green-300":"text-yellow-700 dark:text-yellow-300",children:s("template.importResult",{serversCreated:w.serversCreated,serversSkipped:w.serversSkipped,groupsCreated:w.groupsCreated,groupsSkipped:w.groupsSkipped})}),w.requiredEnvVars.length>0&&e.jsxs("div",{className:"mt-2 p-2 bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-700/60 rounded",children:[e.jsx("p",{className:"text-sm font-medium text-orange-800 dark:text-orange-300",children:s("template.envVarsNeeded")}),e.jsx("ul",{className:"mt-1 text-sm text-orange-700 dark:text-orange-300",children:w.requiredEnvVars.map(h=>e.jsx("li",{className:"font-mono",children:h},h))})]})]}),l?e.jsxs("div",{children:[e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"p-3 bg-gray-50 dark:bg-gray-800 rounded-md",children:[e.jsx("h3",{className:"font-medium text-gray-900",children:l.name}),l.description&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:l.description}),e.jsxs("p",{className:"text-xs text-gray-500 mt-1",children:[s("template.version"),": ",l.version," | ",s("template.createdAt"),":"," ",new Date(l.createdAt).toLocaleDateString()]})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:[s("template.servers")," (",Object.keys(l.servers).length,")"]}),e.jsx("div",{className:"border border-gray-200 dark:border-gray-700 rounded-md divide-y divide-gray-200 dark:divide-gray-700 max-h-40 overflow-y-auto",children:Object.entries(l.servers).map(([h,x])=>e.jsxs("div",{className:"px-3 py-2",children:[e.jsx("span",{className:"text-sm font-medium text-gray-900",children:h}),e.jsx("span",{className:"text-xs text-gray-500 ml-2",children:x.type||"stdio"})]},h))})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:[s("template.groups")," (",l.groups.length,")"]}),e.jsx("div",{className:"border border-gray-200 dark:border-gray-700 rounded-md divide-y divide-gray-200 dark:divide-gray-700 max-h-40 overflow-y-auto",children:l.groups.map((h,x)=>e.jsxs("div",{className:"px-3 py-2",children:[e.jsx("span",{className:"text-sm font-medium text-gray-900",children:h.name}),h.description&&e.jsx("span",{className:"text-xs text-gray-500 ml-2",children:h.description}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1",children:[h.servers.length," ",s("template.serversInGroup")]})]},x))})]}),l.requiredEnvVars.length>0&&e.jsxs("div",{className:"p-3 bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-700/60 rounded-md",children:[e.jsx("h4",{className:"text-sm font-medium text-orange-800 dark:text-orange-300",children:s("template.envVarsNeeded")}),e.jsx("ul",{className:"mt-1 text-sm text-orange-700 dark:text-orange-300 font-mono",children:l.requiredEnvVars.map(h=>e.jsx("li",{children:h},h))})]})]}),e.jsxs("div",{className:"flex justify-end space-x-4 mt-6",children:[e.jsx("button",{onClick:()=>{b(null),A(null),m.current&&(m.current.value="")},className:"hub-btn",children:s("common.back")}),e.jsx("button",{onClick:T,disabled:E,className:"hub-btn primary",children:s(E?"template.importing":"template.import")})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("div",{className:"flex items-center justify-between mb-2",children:e.jsx("label",{className:"block text-sm font-medium text-gray-700",children:s("template.uploadFile")})}),e.jsx("div",{className:"flex items-center space-x-4",children:e.jsx("input",{ref:m,type:"file",accept:".json",onChange:j,className:"block text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"})})]}),e.jsxs("div",{className:"relative my-4",children:[e.jsx("div",{className:"absolute inset-0 flex items-center",children:e.jsx("div",{className:"w-full border-t border-gray-300"})}),e.jsx("div",{className:"relative flex justify-center text-sm",children:e.jsx("span",{className:"bg-white dark:bg-gray-800 px-2 text-gray-500",children:s("template.or")})})]}),e.jsxs("div",{className:"mb-4",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:s("template.pasteJson")}),e.jsx("textarea",{className:"w-full h-64 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm",placeholder:s("template.pastePlaceholder"),onChange:h=>y(h.target.value)})]}),e.jsx("div",{className:"flex justify-end space-x-4",children:e.jsx("button",{onClick:d,className:"hub-btn",children:s("common.cancel")})})]})]})})},us=()=>{const{t:a}=$(),{groups:d,loading:s,error:l,setError:b,deleteGroup:i,triggerRefresh:u}=ee(),{allServers:E}=te({refreshOnMount:!0}),{groupCosts:F}=re(JSON.stringify([d,Ce(E)])),[w,A]=g.useState(null),[m,j]=g.useState(!1),[y,T]=g.useState(!1),[h,x]=g.useState(!1),[p,t]=g.useState(!1),o=async v=>{const D=await i(v);(!D||!D.success)&&b((D==null?void 0:D.message)||a("groups.deleteError"))};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-end justify-between gap-4 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"hub-h1",children:a("pages.groups.title")}),e.jsxs("p",{className:"hub-sub",children:[e.jsx("span",{className:"hub-num",children:d.length})," ",a("nav.groups").toLowerCase()]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{className:"hub-btn",onClick:()=>T(!0),children:[e.jsx(ce,{size:13})," ",a("groupImport.button")]}),e.jsxs("button",{className:"hub-btn",onClick:()=>x(!0),children:[e.jsx(Pe,{size:13})," ",a("template.exportButton")]}),e.jsxs("button",{className:"hub-btn",onClick:()=>t(!0),children:[e.jsx(ce,{size:13})," ",a("template.importButton")]}),e.jsxs("button",{className:"hub-btn primary",onClick:()=>j(!0),children:[e.jsx(de,{size:13})," ",a("groups.add")]})]})]}),l&&e.jsxs("div",{className:"hub-card flex items-center justify-between gap-3 mb-4",style:{padding:"10px 14px",borderColor:"oklch(0.85 0.1 25)",background:"oklch(0.97 0.03 25)",color:"oklch(0.4 0.18 25)"},children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(Re,{size:14,className:"flex-shrink-0"}),e.jsx("span",{className:"truncate text-[13px]",children:l})]}),e.jsx("button",{className:"hub-icon-btn sm",onClick:()=>b(null),children:e.jsx(Le,{size:13})})]}),s?e.jsx("div",{className:"hub-card p-6 text-center",style:{color:"var(--hub-ink-3)"},children:a("app.loading")}):d.length===0?e.jsx("div",{className:"hub-card p-10 text-center",style:{color:"var(--hub-ink-3)"},children:a("groups.noGroups")}):e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3.5",children:[d.map(v=>e.jsx(Xe,{group:v,servers:E,onEdit:A,onDelete:o,cost:F.find(D=>D.id===v.id)},v.id)),e.jsx("button",{onClick:()=>j(!0),className:"flex items-center justify-center text-[var(--hub-ink-3)] hover:text-[var(--hub-ink-2)] transition-colors",style:{border:"1px dashed var(--hub-line)",borderRadius:10,minHeight:200,background:"transparent",cursor:"pointer"},children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"grid place-items-center mx-auto mb-2",style:{width:36,height:36,borderRadius:10,border:"1px solid var(--hub-line)"},children:e.jsx(de,{size:16})}),e.jsx("div",{style:{fontSize:13,fontWeight:500,color:"var(--hub-ink-2)"},children:a("groups.add")}),e.jsx("div",{style:{fontSize:12,marginTop:2},children:a("groups.addNew")})]})})]}),m&&e.jsx(qe,{onAdd:()=>{j(!1),u()},onCancel:()=>j(!1)}),y&&e.jsx(Ye,{onSuccess:()=>{T(!1),u()},onCancel:()=>T(!1)}),w&&e.jsx(Ke,{group:w,onEdit:()=>{A(null),u()},onCancel:()=>A(null)}),h&&e.jsx(Ze,{groups:d,onCancel:()=>x(!1)}),p&&e.jsx(es,{onSuccess:()=>{t(!1),u()},onCancel:()=>t(!1)})]})};export{us as default};
33
+ //# sourceMappingURL=GroupsPage-sE6YJyuK.js.map