@samanhappy/mcphub 1.1.6 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/openapi.js +2 -1
- package/dist/clients/openapi.js.map +1 -1
- package/dist/controllers/authController.js +27 -1
- package/dist/controllers/authController.js.map +1 -1
- package/dist/controllers/configController.js +4 -1
- package/dist/controllers/configController.js.map +1 -1
- package/dist/controllers/groupController.js +21 -6
- package/dist/controllers/groupController.js.map +1 -1
- package/dist/controllers/metricsController.js +33 -0
- package/dist/controllers/metricsController.js.map +1 -0
- package/dist/controllers/oauthServerController.js +12 -14
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/controllers/serverController.js +117 -11
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/dao/GroupDaoDbImpl.js +9 -0
- package/dist/dao/GroupDaoDbImpl.js.map +1 -1
- package/dist/dao/OAuthTokenDaoDbImpl.js +2 -0
- package/dist/dao/OAuthTokenDaoDbImpl.js.map +1 -1
- package/dist/dao/ServerDao.js.map +1 -1
- package/dist/dao/ServerDaoDbImpl.js.map +1 -1
- package/dist/db/entities/Group.js +8 -0
- package/dist/db/entities/Group.js.map +1 -1
- package/dist/db/entities/OAuthToken.js +4 -0
- package/dist/db/entities/OAuthToken.js.map +1 -1
- package/dist/db/entities/Server.js +4 -0
- package/dist/db/entities/Server.js.map +1 -1
- package/dist/middlewares/auth.js +7 -25
- package/dist/middlewares/auth.js.map +1 -1
- package/dist/middlewares/toolCallGuard.js +499 -0
- package/dist/middlewares/toolCallGuard.js.map +1 -0
- package/dist/middlewares/userContext.js +6 -34
- package/dist/middlewares/userContext.js.map +1 -1
- package/dist/models/OAuth.js +14 -93
- package/dist/models/OAuth.js.map +1 -1
- package/dist/routes/index.js +4 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/services/betterAuthConfig.js +1 -0
- package/dist/services/betterAuthConfig.js.map +1 -1
- package/dist/services/contextCostService.js +3 -1
- package/dist/services/contextCostService.js.map +1 -1
- package/dist/services/groupService.js +1 -0
- package/dist/services/groupService.js.map +1 -1
- package/dist/services/mcpOAuthProvider.js +0 -2
- package/dist/services/mcpOAuthProvider.js.map +1 -1
- package/dist/services/mcpService.js +120 -45
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/metricsService.js +54 -0
- package/dist/services/metricsService.js.map +1 -0
- package/dist/services/oauthClientRegistration.js +1 -1
- package/dist/services/oauthClientRegistration.js.map +1 -1
- package/dist/services/oauthServerService.js +15 -1
- package/dist/services/oauthServerService.js.map +1 -1
- package/dist/services/openApiGeneratorService.js +3 -1
- package/dist/services/openApiGeneratorService.js.map +1 -1
- package/dist/services/personalOAuthService.js +70 -8
- package/dist/services/personalOAuthService.js.map +1 -1
- package/dist/services/registrationService.js +28 -0
- package/dist/services/registrationService.js.map +1 -0
- package/dist/services/smartRoutingService.js +7 -6
- package/dist/services/smartRoutingService.js.map +1 -1
- package/dist/services/templateService.js +3 -1
- package/dist/services/templateService.js.map +1 -1
- package/dist/services/toolResultCompressionService.js +26 -1
- package/dist/services/toolResultCompressionService.js.map +1 -1
- package/dist/services/userService.js +22 -4
- package/dist/services/userService.js.map +1 -1
- package/dist/utils/migration.js +4 -2
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/oauthBearer.js +4 -2
- package/dist/utils/oauthBearer.js.map +1 -1
- package/dist/utils/oauthRedirectUri.js +3 -11
- package/dist/utils/oauthRedirectUri.js.map +1 -1
- package/dist/utils/parameterConversion.js +9 -4
- package/dist/utils/parameterConversion.js.map +1 -1
- package/dist/utils/passthroughHeaders.js +17 -0
- package/dist/utils/passthroughHeaders.js.map +1 -0
- package/dist/utils/rateLimit.js +1 -1
- package/dist/utils/rateLimit.js.map +1 -1
- package/dist/utils/serialization.js +2 -5
- package/dist/utils/serialization.js.map +1 -1
- package/dist/utils/serverConfigValidation.js +2 -1
- package/dist/utils/serverConfigValidation.js.map +1 -1
- package/dist/utils/settingsSync.js +58 -5
- package/dist/utils/settingsSync.js.map +1 -1
- package/dist/utils/tokenTruncation.js +1 -1
- package/dist/utils/tokenTruncation.js.map +1 -1
- package/dist/utils/toolConfig.js +93 -0
- package/dist/utils/toolConfig.js.map +1 -0
- package/dist/utils/userSession.js +29 -0
- package/dist/utils/userSession.js.map +1 -0
- package/frontend/dist/assets/{ActivityPage-e2s2j32V.js → ActivityPage-CJdAfOUF.js} +2 -2
- package/frontend/dist/assets/{ActivityPage-e2s2j32V.js.map → ActivityPage-CJdAfOUF.js.map} +1 -1
- package/frontend/dist/assets/{CopyClientConfigDialog-B71Cl89b.js → CopyClientConfigDialog-DKktm8jj.js} +2 -2
- package/frontend/dist/assets/{CopyClientConfigDialog-B71Cl89b.js.map → CopyClientConfigDialog-DKktm8jj.js.map} +1 -1
- package/frontend/dist/assets/{CredentialsPage-BnA17pRJ.js → CredentialsPage-CPyZrp4Z.js} +2 -2
- package/frontend/dist/assets/{CredentialsPage-BnA17pRJ.js.map → CredentialsPage-CPyZrp4Z.js.map} +1 -1
- package/frontend/dist/assets/{Dashboard-gC_Z286J.js → Dashboard-DM_IiBIT.js} +2 -2
- package/frontend/dist/assets/{Dashboard-gC_Z286J.js.map → Dashboard-DM_IiBIT.js.map} +1 -1
- package/frontend/dist/assets/{EndpointCopy-BjD8ehcn.js → EndpointCopy-DHQjJesJ.js} +2 -2
- package/frontend/dist/assets/{EndpointCopy-BjD8ehcn.js.map → EndpointCopy-DHQjJesJ.js.map} +1 -1
- package/frontend/dist/assets/{GroupsPage-DiT_skCf.js → GroupsPage-VKHjil-L.js} +4 -4
- package/frontend/dist/assets/GroupsPage-VKHjil-L.js.map +1 -0
- package/frontend/dist/assets/LoginPage-CKrI0By4.js +2 -0
- package/frontend/dist/assets/LoginPage-CKrI0By4.js.map +1 -0
- package/frontend/dist/assets/{LogsPage-BzI3IAHO.js → LogsPage-Dh8gRpEH.js} +2 -2
- package/frontend/dist/assets/{LogsPage-BzI3IAHO.js.map → LogsPage-Dh8gRpEH.js.map} +1 -1
- package/frontend/dist/assets/{MarketPage-DVo32QTs.js → MarketPage-BN4qL8L9.js} +2 -2
- package/frontend/dist/assets/{MarketPage-DVo32QTs.js.map → MarketPage-BN4qL8L9.js.map} +1 -1
- package/frontend/dist/assets/{OAuthConsentPage-DUapnxQ9.js → OAuthConsentPage-Cyj-rrA4.js} +2 -2
- package/frontend/dist/assets/{OAuthConsentPage-DUapnxQ9.js.map → OAuthConsentPage-Cyj-rrA4.js.map} +1 -1
- package/frontend/dist/assets/{PromptsPage-BAqJay5m.js → PromptsPage-YWD04XeI.js} +2 -2
- package/frontend/dist/assets/{PromptsPage-BAqJay5m.js.map → PromptsPage-YWD04XeI.js.map} +1 -1
- package/frontend/dist/assets/{ResourcesPage-kIOm5X1A.js → ResourcesPage-CVRzHCf4.js} +2 -2
- package/frontend/dist/assets/{ResourcesPage-kIOm5X1A.js.map → ResourcesPage-CVRzHCf4.js.map} +1 -1
- package/frontend/dist/assets/ServersPage-DJBurfOe.js +39 -0
- package/frontend/dist/assets/ServersPage-DJBurfOe.js.map +1 -0
- package/frontend/dist/assets/{SettingsPage-DkMmUgCh.js → SettingsPage-3sK6NJRn.js} +6 -6
- package/frontend/dist/assets/SettingsPage-3sK6NJRn.js.map +1 -0
- package/frontend/dist/assets/{StatusDot-Bm_C7v3r.js → StatusDot-CLZidCyq.js} +2 -2
- package/frontend/dist/assets/{StatusDot-Bm_C7v3r.js.map → StatusDot-CLZidCyq.js.map} +1 -1
- package/frontend/dist/assets/{ToggleGroup-DcOtP3Gf.js → ToggleGroup-Dfh4jKpP.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-DcOtP3Gf.js.map → ToggleGroup-Dfh4jKpP.js.map} +1 -1
- package/frontend/dist/assets/{UsersPage-DpcbXD3K.js → UsersPage-DfFqSRVb.js} +2 -2
- package/frontend/dist/assets/{UsersPage-DpcbXD3K.js.map → UsersPage-DfFqSRVb.js.map} +1 -1
- package/frontend/dist/assets/{clipboard-CvokTzlX.js → clipboard-wUZFI68F.js} +2 -2
- package/frontend/dist/assets/{clipboard-CvokTzlX.js.map → clipboard-wUZFI68F.js.map} +1 -1
- package/frontend/dist/assets/framework-vendor-CQFm9vKd.js.map +1 -1
- package/frontend/dist/assets/index-BbogfcdA.js +3 -0
- package/frontend/dist/assets/index-BbogfcdA.js.map +1 -0
- package/frontend/dist/assets/{resourceService-CbZwkCgS.js → resourceService-D7yitP7i.js} +2 -2
- package/frontend/dist/assets/{resourceService-CbZwkCgS.js.map → resourceService-D7yitP7i.js.map} +1 -1
- package/frontend/dist/assets/{useCostData-DZ5NdhVp.js → useCostData-33G6s4EW.js} +2 -2
- package/frontend/dist/assets/{useCostData-DZ5NdhVp.js.map → useCostData-33G6s4EW.js.map} +1 -1
- package/frontend/dist/assets/{variableDetection-SMtrW-P5.js → variableDetection-BVSe56ia.js} +2 -2
- package/frontend/dist/assets/{variableDetection-SMtrW-P5.js.map → variableDetection-BVSe56ia.js.map} +1 -1
- package/frontend/dist/index.html +1 -1
- package/package.json +3 -2
- package/frontend/dist/assets/GroupsPage-DiT_skCf.js.map +0 -1
- package/frontend/dist/assets/LoginPage-DK3WmTV9.js +0 -2
- package/frontend/dist/assets/LoginPage-DK3WmTV9.js.map +0 -1
- package/frontend/dist/assets/ServersPage-CkUdGq0R.js +0 -39
- package/frontend/dist/assets/ServersPage-CkUdGq0R.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-DkMmUgCh.js.map +0 -1
- package/frontend/dist/assets/index-DkQidC_d.js +0 -3
- package/frontend/dist/assets/index-DkQidC_d.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogsPage-BzI3IAHO.js","sources":["../../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.5_@types+react@19.2.16_react@19.2.7/node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-slot@1.3.3_@types+react@19.2.16_react@19.2.7/node_modules/@radix-ui/react-slot/dist/index.mjs","../../src/components/ui/Button.tsx","../../src/components/ui/Badge.tsx","../../src/components/LogViewer.tsx","../../src/pages/LogsPage.tsx"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/compose-refs.tsx\nimport * as React from \"react\";\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\n__name(setRef, \"setRef\");\nfunction composeRefs(...refs) {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup == \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup == \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n__name(composeRefs, \"composeRefs\");\nfunction useComposedRefs(...refs) {\n return React.useCallback(composeRefs(...refs), refs);\n}\n__name(useComposedRefs, \"useComposedRefs\");\nexport {\n composeRefs,\n useComposedRefs\n};\n//# sourceMappingURL=index.mjs.map\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/slot.tsx\nimport * as React from \"react\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\n// @__NO_SIDE_EFFECTS__\nfunction createSlot(ownerName) {\n const Slot2 = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n let slottableElement = null;\n let hasSlottable = false;\n const newChildren = [];\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n React.Children.forEach(children, (maybeSlottable) => {\n if (isSlottable(maybeSlottable)) {\n hasSlottable = true;\n const slottable = maybeSlottable;\n let child = \"child\" in slottable.props ? slottable.props.child : slottable.props.children;\n if (isLazyComponent(child) && typeof use === \"function\") {\n child = use(child._payload);\n }\n slottableElement = getSlottableElementFromSlottable(slottable, child);\n newChildren.push(slottableElement?.props?.children);\n } else {\n newChildren.push(maybeSlottable);\n }\n });\n if (slottableElement) {\n slottableElement = React.cloneElement(slottableElement, void 0, newChildren);\n } else if (\n // A `Slottable` was found but it didn't resolve to a single element (e.g.\n // it wrapped multiple elements, text, or a render-prop `child` that\n // wasn't an element). Don't fall back to treating the `Slottable` wrapper\n // itself as the slot target — throw a descriptive error below instead.\n !hasSlottable && React.Children.count(children) === 1 && React.isValidElement(children)\n ) {\n slottableElement = children;\n }\n const slottableElementRef = slottableElement ? getElementRef(slottableElement) : void 0;\n const composedRef = useComposedRefs(forwardedRef, slottableElementRef);\n if (!slottableElement) {\n if (children || children === 0) {\n throw new Error(\n hasSlottable ? createSlottableError(ownerName) : createSlotError(ownerName)\n );\n }\n return children;\n }\n const mergedProps = mergeProps(slotProps, slottableElement.props ?? {});\n if (slottableElement.type !== React.Fragment) {\n mergedProps.ref = forwardedRef ? composedRef : slottableElementRef;\n }\n return React.cloneElement(slottableElement, mergedProps);\n });\n Slot2.displayName = `${ownerName}.Slot`;\n return Slot2;\n}\n__name(createSlot, \"createSlot\");\nvar Slot = /* @__PURE__ */ createSlot(\"Slot\");\nvar SLOTTABLE_IDENTIFIER = Symbol.for(\"radix.slottable\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlottable(ownerName) {\n const Slottable2 = /* @__PURE__ */ __name((props) => \"child\" in props ? props.children(props.child) : props.children, \"Slottable\");\n Slottable2.displayName = `${ownerName}.Slottable`;\n Slottable2.__radixId = SLOTTABLE_IDENTIFIER;\n return Slottable2;\n}\n__name(createSlottable, \"createSlottable\");\nvar Slottable = /* @__PURE__ */ createSlottable(\"Slottable\");\nvar getSlottableElementFromSlottable = /* @__PURE__ */ __name((slottable, child) => {\n if (\"child\" in slottable.props) {\n const child2 = slottable.props.child;\n if (!React.isValidElement(child2)) return null;\n return React.cloneElement(child2, void 0, slottable.props.children(child2.props.children));\n }\n return React.isValidElement(child) ? child : null;\n}, \"getSlottableElementFromSlottable\");\nfunction mergeProps(slotProps, childProps) {\n const overrideProps = { ...childProps };\n for (const propName in childProps) {\n const slotPropValue = slotProps[propName];\n const childPropValue = childProps[propName];\n const isHandler = /^on[A-Z]/.test(propName);\n if (isHandler) {\n if (slotPropValue && childPropValue) {\n overrideProps[propName] = (...args) => {\n const result = childPropValue(...args);\n slotPropValue(...args);\n return result;\n };\n } else if (slotPropValue) {\n overrideProps[propName] = slotPropValue;\n }\n } else if (propName === \"style\") {\n overrideProps[propName] = { ...slotPropValue, ...childPropValue };\n } else if (propName === \"className\") {\n overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(\" \");\n }\n }\n return { ...slotProps, ...overrideProps };\n}\n__name(mergeProps, \"mergeProps\");\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\n__name(getElementRef, \"getElementRef\");\nfunction isSlottable(child) {\n return React.isValidElement(child) && typeof child.type === \"function\" && \"__radixId\" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;\n}\n__name(isSlottable, \"isSlottable\");\nvar REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nfunction isLazyComponent(element) {\n return element != null && typeof element === \"object\" && \"$$typeof\" in element && element.$$typeof === REACT_LAZY_TYPE && \"_payload\" in element && isPromiseLike(element._payload);\n}\n__name(isLazyComponent, \"isLazyComponent\");\nfunction isPromiseLike(value) {\n return typeof value === \"object\" && value !== null && \"then\" in value;\n}\n__name(isPromiseLike, \"isPromiseLike\");\nvar createSlotError = /* @__PURE__ */ __name((ownerName) => {\n return `${ownerName} failed to slot onto its children. Expected a single React element child or \\`Slottable\\`.`;\n}, \"createSlotError\");\nvar createSlottableError = /* @__PURE__ */ __name((ownerName) => {\n return `${ownerName} failed to slot onto its \\`Slottable\\`. Expected \\`Slottable\\` to receive a single React element child.`;\n}, \"createSlottableError\");\nvar use = React[\" use \".trim().toString()];\nexport {\n Slot as Root,\n Slot,\n Slottable,\n createSlot,\n createSlottable\n};\n//# sourceMappingURL=index.mjs.map\n","import React, { useState } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '../../utils/cn';\n\ntype ButtonVariant = 'default' | 'outline' | 'ghost' | 'link' | 'destructive';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n asChild?: boolean;\n loading?: boolean;\n children: React.ReactNode;\n // Allow async handlers: Button detects a returned promise and shows the\n // loading state for the duration of the call.\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void | Promise<void>;\n}\n\nconst variantStyles: Record<ButtonVariant, string> = {\n default: 'bg-blue-500 text-white hover:bg-blue-600 focus:ring-blue-500',\n outline: 'border border-gray-300 dark:border-gray-700 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300',\n ghost: 'bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300',\n link: 'bg-transparent underline-offset-4 hover:underline text-blue-500 hover:text-blue-600',\n destructive: 'bg-red-500 text-white hover:bg-red-600 focus:ring-red-500',\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n default: 'h-10 py-2 px-4',\n sm: 'h-8 px-3 text-sm',\n lg: 'h-12 px-6',\n icon: 'h-10 w-10 p-0 text-center',\n};\n\nexport function Button({\n variant = 'default',\n size = 'default',\n className,\n disabled,\n loading: externalLoading = false,\n asChild = false,\n children,\n onClick,\n ...props\n}: ButtonProps) {\n const [internalLoading, setInternalLoading] = useState(false);\n const isLoading = externalLoading || internalLoading;\n\n const handleClick = async (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onClick) return;\n \n try {\n const result = onClick(e);\n if (result && typeof (result as any).then === 'function') {\n setInternalLoading(true);\n await result;\n }\n } finally {\n if (internalLoading) {\n // Need to check if component unmounted?\n // It's a standard pattern, state update on unmounted is no longer an error in React 18+\n }\n setInternalLoading(false);\n }\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n className={cn(\n 'rounded-md inline-flex items-center justify-center font-medium transition-all duration-200 active:scale-95 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none relative',\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n disabled={disabled || isLoading}\n onClick={handleClick}\n {...props}\n >\n {asChild ? (\n children\n ) : (\n <>\n <span className={cn('flex items-center justify-center', isLoading && 'invisible')}>\n {children}\n </span>\n {isLoading && (\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <svg className=\"animate-spin h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <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\"></path>\n </svg>\n </span>\n )}\n </>\n )}\n </Comp>\n );\n}","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '../../utils/cn';\n\ntype BadgeVariant = 'default' | 'secondary' | 'outline' | 'destructive';\n\ntype BadgeProps = {\n children: React.ReactNode;\n variant?: BadgeVariant;\n className?: string;\n onClick?: () => void;\n};\n\nconst badgeVariants = {\n default: 'bg-blue-500 text-white hover:bg-blue-600',\n secondary:\n 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600',\n outline:\n 'bg-transparent border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800',\n destructive: 'bg-red-500 text-white hover:bg-red-600',\n};\n\nexport function Badge({ children, variant = 'default', className, onClick }: BadgeProps) {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors',\n badgeVariants[variant],\n onClick ? 'cursor-pointer' : '',\n className,\n )}\n onClick={onClick}\n >\n {children}\n </span>\n );\n}\n\n// For backward compatibility with existing code\nexport const StatusBadge = ({\n status,\n onAuthClick,\n}: {\n status: 'connected' | 'disconnected' | 'connecting' | 'oauth_required';\n onAuthClick?: (e: React.MouseEvent) => void;\n}) => {\n const { t } = useTranslation();\n\n const colors = {\n connecting: 'status-badge-connecting',\n connected: 'status-badge-online',\n disconnected: 'status-badge-offline',\n oauth_required: 'status-badge-oauth-required',\n };\n\n // Map status to translation keys\n const statusTranslations = {\n connected: 'status.online',\n disconnected: 'status.offline',\n connecting: 'status.connecting',\n oauth_required: 'status.oauthRequired',\n };\n\n const isOAuthRequired = status === 'oauth_required';\n\n return (\n <span\n className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${colors[status]} ${isOAuthRequired && onAuthClick ? 'cursor-pointer hover:opacity-80' : ''}`}\n onClick={isOAuthRequired && onAuthClick ? (e) => onAuthClick(e) : undefined}\n title={isOAuthRequired ? t('status.clickToAuthorize') : undefined}\n >\n {isOAuthRequired && '🔐 '}\n {t(statusTranslations[status] || status)}\n </span>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport { LogEntry } from '../services/logService';\nimport { Button } from './ui/Button';\nimport { Badge } from './ui/Badge';\nimport { useTranslation } from 'react-i18next';\n\ninterface LogViewerProps {\n logs: LogEntry[];\n isLoading?: boolean;\n error?: Error | null;\n onClear?: () => void;\n}\n\nconst LogViewer: React.FC<LogViewerProps> = ({ logs, isLoading = false, error = null, onClear }) => {\n const { t } = useTranslation();\n const logContainerRef = useRef<HTMLDivElement>(null);\n const [autoScroll, setAutoScroll] = useState(true);\n const [filter, setFilter] = useState<string>('');\n const [typeFilter, setTypeFilter] = useState<Array<'info' | 'error' | 'warn' | 'debug'>>(['info', 'error', 'warn', 'debug']);\n const [sourceFilter, setSourceFilter] = useState<Array<'main' | 'child'>>(['main', 'child']);\n\n // Auto scroll to bottom when new logs come in if autoScroll is enabled\n useEffect(() => {\n if (autoScroll && logContainerRef.current) {\n logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight;\n }\n }, [logs, autoScroll]);\n\n // Filter logs based on current filter settings\n const filteredLogs = logs.filter(log => {\n const matchesText = filter ? log.message.toLowerCase().includes(filter.toLowerCase()) : true;\n const matchesType = typeFilter.includes(log.type);\n const matchesSource = sourceFilter.includes(log.source as 'main' | 'child');\n return matchesText && matchesType && matchesSource;\n });\n\n // Format timestamp to readable format\n const formatTimestamp = (timestamp: number) => {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n };\n\n // Get badge color based on log type\n const getLogTypeColor = (type: string) => {\n switch (type) {\n case 'error': return 'bg-red-400/80 text-white';\n case 'warn': return 'bg-yellow-400/80 text-gray-900';\n case 'debug': return 'bg-purple-400/80 text-white';\n case 'info': return 'bg-blue-400/80 text-white';\n default: return 'bg-blue-400/80 text-white';\n }\n };\n\n // Get badge color based on log source\n const getSourceColor = (source: string) => {\n switch (source) {\n case 'main': return 'bg-green-400/80 text-white';\n case 'child': return 'bg-orange-400/80 text-white';\n default: return 'bg-gray-400/80 text-white';\n }\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"bg-card p-3 rounded-t-md flex flex-wrap items-center justify-between gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-semibold text-sm\">{t('logs.filters')}:</span>\n\n {/* Text search filter */}\n <input\n type=\"text\"\n placeholder={t('logs.search')}\n className=\"shadow appearance-none border border-gray-200 dark:border-gray-700 rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline form-input\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n />\n\n {/* Log type filters */}\n <div className=\"flex gap-1 items-center\">\n {(['debug', 'info', 'error', 'warn'] as const).map(type => (\n <Badge\n key={type}\n variant={typeFilter.includes(type) ? 'default' : 'outline'}\n className={`cursor-pointer ${typeFilter.includes(type) ? getLogTypeColor(type) : ''}`}\n onClick={() => {\n if (typeFilter.includes(type)) {\n setTypeFilter(prev => prev.filter(t => t !== type));\n } else {\n setTypeFilter(prev => [...prev, type]);\n }\n }}\n >\n {type}\n </Badge>\n ))}\n </div>\n\n {/* Log source filters */}\n <div className=\"flex gap-1 items-center ml-2\">\n {(['main', 'child'] as const).map(source => (\n <Badge\n key={source}\n variant={sourceFilter.includes(source) ? 'default' : 'outline'}\n className={`cursor-pointer ${sourceFilter.includes(source) ? getSourceColor(source) : ''}`}\n onClick={() => {\n if (sourceFilter.includes(source)) {\n setSourceFilter(prev => prev.filter(s => s !== source));\n } else {\n setSourceFilter(prev => [...prev, source]);\n }\n }}\n >\n {source === 'main' ? t('logs.mainProcess') : t('logs.childProcess')}\n </Badge>\n ))}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1 text-sm\">\n <input\n type=\"checkbox\"\n checked={autoScroll}\n onChange={() => setAutoScroll(!autoScroll)}\n className=\"form-checkbox h-4 w-4\"\n />\n {t('logs.autoScroll')}\n </label>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={onClear}\n className='btn-secondary'\n disabled={isLoading || logs.length === 0}\n >\n {t('logs.clearLogs')}\n </Button>\n </div>\n </div>\n\n <div\n ref={logContainerRef}\n className=\"flex-grow p-2 overflow-auto bg-card rounded-b-md font-mono text-sm\"\n style={{ maxHeight: 'calc(100vh - 300px)' }}\n >\n {isLoading ? (\n <div className=\"flex justify-center items-center h-full\">\n <span>{t('logs.loading')}</span>\n </div>\n ) : error ? (\n <div className=\"text-red-500 p-2\">\n {error.message}\n </div>\n ) : filteredLogs.length === 0 ? (\n <div className=\"text-center text-muted-foreground p-8\">\n {filter || typeFilter.length < 4 || sourceFilter.length < 2\n ? t('logs.noMatch')\n : t('logs.noLogs')}\n </div>\n ) : (\n filteredLogs.map((log, index) => (\n <div\n key={`${log.timestamp}-${index}`}\n className={`py-1 ${log.type === 'error' ? 'text-red-500' :\n log.type === 'warn' ? 'text-yellow-500' : ''\n }`}\n >\n <span className=\"text-gray-400\">[{formatTimestamp(log.timestamp)}]</span>\n <Badge className={`ml-2 mr-1 ${getLogTypeColor(log.type)}`}>\n {log.type}\n </Badge>\n <Badge\n variant=\"default\"\n className={`mr-2 ${getSourceColor(log.source)}`}\n >\n {log.source === 'main' ? t('logs.main') : t('logs.child')}\n {log.processId ? ` (${log.processId})` : ''}\n </Badge>\n <span className=\"whitespace-pre-wrap\">{log.message}</span>\n </div>\n ))\n )}\n </div>\n </div>\n );\n};\n\nexport default LogViewer;","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport LogViewer from '../components/LogViewer';\nimport { useLogs } from '../services/logService';\n\nconst LogsPage: React.FC = () => {\n const { t } = useTranslation();\n const { logs, loading, error, clearLogs } = useLogs();\n\n return (\n <div>\n <div className=\"mb-6\">\n <h1 className=\"hub-h1\">{t('pages.logs.title')}</h1>\n <p className=\"hub-sub\">\n <span className=\"hub-num\">{logs.length}</span> entries\n </p>\n </div>\n <div className=\"hub-card overflow-hidden\">\n <LogViewer logs={logs} isLoading={loading} error={error} onClear={clearLogs} />\n </div>\n </div>\n );\n};\n\nexport default LogsPage;\n"],"names":["__defProp","__name","target","value","setRef","ref","composeRefs","refs","node","hasCleanup","cleanups","cleanup","i","useComposedRefs","React.useCallback","createSlot","ownerName","Slot2","React.forwardRef","props","forwardedRef","children","slotProps","slottableElement","hasSlottable","newChildren","isLazyComponent","use","React.Children","maybeSlottable","isSlottable","slottable","child","getSlottableElementFromSlottable","_a","React.cloneElement","React.isValidElement","slottableElementRef","getElementRef","composedRef","createSlottableError","createSlotError","mergedProps","mergeProps","React.Fragment","Slot","SLOTTABLE_IDENTIFIER","createSlottable","Slottable2","child2","childProps","overrideProps","propName","slotPropValue","childPropValue","args","result","element","getter","mayWarn","_b","REACT_LAZY_TYPE","isPromiseLike","React","variantStyles","sizeStyles","Button","variant","size","className","disabled","externalLoading","asChild","onClick","internalLoading","setInternalLoading","useState","isLoading","handleClick","e","Comp","jsx","cn","jsxs","Fragment","badgeVariants","Badge","LogViewer","logs","error","onClear","useTranslation","logContainerRef","useRef","autoScroll","setAutoScroll","filter","setFilter","typeFilter","setTypeFilter","sourceFilter","setSourceFilter","useEffect","filteredLogs","log","matchesText","matchesType","matchesSource","formatTimestamp","timestamp","getLogTypeColor","type","getSourceColor","source","prev","t","s","index","LogsPage","loading","clearLogs","useLogs"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"LogsPage-Dh8gRpEH.js","sources":["../../../node_modules/.pnpm/@radix-ui+react-compose-refs@1.1.5_@types+react@19.2.16_react@19.2.7/node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../../../node_modules/.pnpm/@radix-ui+react-slot@1.3.3_@types+react@19.2.16_react@19.2.7/node_modules/@radix-ui/react-slot/dist/index.mjs","../../src/components/ui/Button.tsx","../../src/components/ui/Badge.tsx","../../src/components/LogViewer.tsx","../../src/pages/LogsPage.tsx"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/compose-refs.tsx\nimport * as React from \"react\";\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\n__name(setRef, \"setRef\");\nfunction composeRefs(...refs) {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup == \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup == \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\n__name(composeRefs, \"composeRefs\");\nfunction useComposedRefs(...refs) {\n return React.useCallback(composeRefs(...refs), refs);\n}\n__name(useComposedRefs, \"useComposedRefs\");\nexport {\n composeRefs,\n useComposedRefs\n};\n//# sourceMappingURL=index.mjs.map\n","var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/slot.tsx\nimport * as React from \"react\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\n// @__NO_SIDE_EFFECTS__\nfunction createSlot(ownerName) {\n const Slot2 = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n let slottableElement = null;\n let hasSlottable = false;\n const newChildren = [];\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n React.Children.forEach(children, (maybeSlottable) => {\n if (isSlottable(maybeSlottable)) {\n hasSlottable = true;\n const slottable = maybeSlottable;\n let child = \"child\" in slottable.props ? slottable.props.child : slottable.props.children;\n if (isLazyComponent(child) && typeof use === \"function\") {\n child = use(child._payload);\n }\n slottableElement = getSlottableElementFromSlottable(slottable, child);\n newChildren.push(slottableElement?.props?.children);\n } else {\n newChildren.push(maybeSlottable);\n }\n });\n if (slottableElement) {\n slottableElement = React.cloneElement(slottableElement, void 0, newChildren);\n } else if (\n // A `Slottable` was found but it didn't resolve to a single element (e.g.\n // it wrapped multiple elements, text, or a render-prop `child` that\n // wasn't an element). Don't fall back to treating the `Slottable` wrapper\n // itself as the slot target — throw a descriptive error below instead.\n !hasSlottable && React.Children.count(children) === 1 && React.isValidElement(children)\n ) {\n slottableElement = children;\n }\n const slottableElementRef = slottableElement ? getElementRef(slottableElement) : void 0;\n const composedRef = useComposedRefs(forwardedRef, slottableElementRef);\n if (!slottableElement) {\n if (children || children === 0) {\n throw new Error(\n hasSlottable ? createSlottableError(ownerName) : createSlotError(ownerName)\n );\n }\n return children;\n }\n const mergedProps = mergeProps(slotProps, slottableElement.props ?? {});\n if (slottableElement.type !== React.Fragment) {\n mergedProps.ref = forwardedRef ? composedRef : slottableElementRef;\n }\n return React.cloneElement(slottableElement, mergedProps);\n });\n Slot2.displayName = `${ownerName}.Slot`;\n return Slot2;\n}\n__name(createSlot, \"createSlot\");\nvar Slot = /* @__PURE__ */ createSlot(\"Slot\");\nvar SLOTTABLE_IDENTIFIER = Symbol.for(\"radix.slottable\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlottable(ownerName) {\n const Slottable2 = /* @__PURE__ */ __name((props) => \"child\" in props ? props.children(props.child) : props.children, \"Slottable\");\n Slottable2.displayName = `${ownerName}.Slottable`;\n Slottable2.__radixId = SLOTTABLE_IDENTIFIER;\n return Slottable2;\n}\n__name(createSlottable, \"createSlottable\");\nvar Slottable = /* @__PURE__ */ createSlottable(\"Slottable\");\nvar getSlottableElementFromSlottable = /* @__PURE__ */ __name((slottable, child) => {\n if (\"child\" in slottable.props) {\n const child2 = slottable.props.child;\n if (!React.isValidElement(child2)) return null;\n return React.cloneElement(child2, void 0, slottable.props.children(child2.props.children));\n }\n return React.isValidElement(child) ? child : null;\n}, \"getSlottableElementFromSlottable\");\nfunction mergeProps(slotProps, childProps) {\n const overrideProps = { ...childProps };\n for (const propName in childProps) {\n const slotPropValue = slotProps[propName];\n const childPropValue = childProps[propName];\n const isHandler = /^on[A-Z]/.test(propName);\n if (isHandler) {\n if (slotPropValue && childPropValue) {\n overrideProps[propName] = (...args) => {\n const result = childPropValue(...args);\n slotPropValue(...args);\n return result;\n };\n } else if (slotPropValue) {\n overrideProps[propName] = slotPropValue;\n }\n } else if (propName === \"style\") {\n overrideProps[propName] = { ...slotPropValue, ...childPropValue };\n } else if (propName === \"className\") {\n overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(\" \");\n }\n }\n return { ...slotProps, ...overrideProps };\n}\n__name(mergeProps, \"mergeProps\");\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\n__name(getElementRef, \"getElementRef\");\nfunction isSlottable(child) {\n return React.isValidElement(child) && typeof child.type === \"function\" && \"__radixId\" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;\n}\n__name(isSlottable, \"isSlottable\");\nvar REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nfunction isLazyComponent(element) {\n return element != null && typeof element === \"object\" && \"$$typeof\" in element && element.$$typeof === REACT_LAZY_TYPE && \"_payload\" in element && isPromiseLike(element._payload);\n}\n__name(isLazyComponent, \"isLazyComponent\");\nfunction isPromiseLike(value) {\n return typeof value === \"object\" && value !== null && \"then\" in value;\n}\n__name(isPromiseLike, \"isPromiseLike\");\nvar createSlotError = /* @__PURE__ */ __name((ownerName) => {\n return `${ownerName} failed to slot onto its children. Expected a single React element child or \\`Slottable\\`.`;\n}, \"createSlotError\");\nvar createSlottableError = /* @__PURE__ */ __name((ownerName) => {\n return `${ownerName} failed to slot onto its \\`Slottable\\`. Expected \\`Slottable\\` to receive a single React element child.`;\n}, \"createSlottableError\");\nvar use = React[\" use \".trim().toString()];\nexport {\n Slot as Root,\n Slot,\n Slottable,\n createSlot,\n createSlottable\n};\n//# sourceMappingURL=index.mjs.map\n","import React, { useState } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '../../utils/cn';\n\ntype ButtonVariant = 'default' | 'outline' | 'ghost' | 'link' | 'destructive';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\ninterface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n asChild?: boolean;\n loading?: boolean;\n children: React.ReactNode;\n // Allow async handlers: Button detects a returned promise and shows the\n // loading state for the duration of the call.\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void | Promise<void>;\n}\n\nconst variantStyles: Record<ButtonVariant, string> = {\n default: 'bg-blue-500 text-white hover:bg-blue-600 focus:ring-blue-500',\n outline: 'border border-gray-300 dark:border-gray-700 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300',\n ghost: 'bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300',\n link: 'bg-transparent underline-offset-4 hover:underline text-blue-500 hover:text-blue-600',\n destructive: 'bg-red-500 text-white hover:bg-red-600 focus:ring-red-500',\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n default: 'h-10 py-2 px-4',\n sm: 'h-8 px-3 text-sm',\n lg: 'h-12 px-6',\n icon: 'h-10 w-10 p-0 text-center',\n};\n\nexport function Button({\n variant = 'default',\n size = 'default',\n className,\n disabled,\n loading: externalLoading = false,\n asChild = false,\n children,\n onClick,\n ...props\n}: ButtonProps) {\n const [internalLoading, setInternalLoading] = useState(false);\n const isLoading = externalLoading || internalLoading;\n\n const handleClick = async (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onClick) return;\n \n try {\n const result = onClick(e);\n if (result && typeof (result as any).then === 'function') {\n setInternalLoading(true);\n await result;\n }\n } finally {\n if (internalLoading) {\n // Need to check if component unmounted?\n // It's a standard pattern, state update on unmounted is no longer an error in React 18+\n }\n setInternalLoading(false);\n }\n };\n\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n className={cn(\n 'rounded-md inline-flex items-center justify-center font-medium transition-all duration-200 active:scale-95 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none relative',\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n disabled={disabled || isLoading}\n onClick={handleClick}\n {...props}\n >\n {asChild ? (\n children\n ) : (\n <>\n <span className={cn('flex items-center justify-center', isLoading && 'invisible')}>\n {children}\n </span>\n {isLoading && (\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <svg className=\"animate-spin h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <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\"></path>\n </svg>\n </span>\n )}\n </>\n )}\n </Comp>\n );\n}","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '../../utils/cn';\n\ntype BadgeVariant = 'default' | 'secondary' | 'outline' | 'destructive';\n\ntype BadgeProps = {\n children: React.ReactNode;\n variant?: BadgeVariant;\n className?: string;\n onClick?: () => void;\n};\n\nconst badgeVariants = {\n default: 'bg-blue-500 text-white hover:bg-blue-600',\n secondary:\n 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600',\n outline:\n 'bg-transparent border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800',\n destructive: 'bg-red-500 text-white hover:bg-red-600',\n};\n\nexport function Badge({ children, variant = 'default', className, onClick }: BadgeProps) {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors',\n badgeVariants[variant],\n onClick ? 'cursor-pointer' : '',\n className,\n )}\n onClick={onClick}\n >\n {children}\n </span>\n );\n}\n\n// For backward compatibility with existing code\nexport const StatusBadge = ({\n status,\n onAuthClick,\n}: {\n status: 'connected' | 'disconnected' | 'connecting' | 'oauth_required';\n onAuthClick?: (e: React.MouseEvent) => void;\n}) => {\n const { t } = useTranslation();\n\n const colors = {\n connecting: 'status-badge-connecting',\n connected: 'status-badge-online',\n disconnected: 'status-badge-offline',\n oauth_required: 'status-badge-oauth-required',\n };\n\n // Map status to translation keys\n const statusTranslations = {\n connected: 'status.online',\n disconnected: 'status.offline',\n connecting: 'status.connecting',\n oauth_required: 'status.oauthRequired',\n };\n\n const isOAuthRequired = status === 'oauth_required';\n\n return (\n <span\n className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${colors[status]} ${isOAuthRequired && onAuthClick ? 'cursor-pointer hover:opacity-80' : ''}`}\n onClick={isOAuthRequired && onAuthClick ? (e) => onAuthClick(e) : undefined}\n title={isOAuthRequired ? t('status.clickToAuthorize') : undefined}\n >\n {isOAuthRequired && '🔐 '}\n {t(statusTranslations[status] || status)}\n </span>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport { LogEntry } from '../services/logService';\nimport { Button } from './ui/Button';\nimport { Badge } from './ui/Badge';\nimport { useTranslation } from 'react-i18next';\n\ninterface LogViewerProps {\n logs: LogEntry[];\n isLoading?: boolean;\n error?: Error | null;\n onClear?: () => void;\n}\n\nconst LogViewer: React.FC<LogViewerProps> = ({ logs, isLoading = false, error = null, onClear }) => {\n const { t } = useTranslation();\n const logContainerRef = useRef<HTMLDivElement>(null);\n const [autoScroll, setAutoScroll] = useState(true);\n const [filter, setFilter] = useState<string>('');\n const [typeFilter, setTypeFilter] = useState<Array<'info' | 'error' | 'warn' | 'debug'>>(['info', 'error', 'warn', 'debug']);\n const [sourceFilter, setSourceFilter] = useState<Array<'main' | 'child'>>(['main', 'child']);\n\n // Auto scroll to bottom when new logs come in if autoScroll is enabled\n useEffect(() => {\n if (autoScroll && logContainerRef.current) {\n logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight;\n }\n }, [logs, autoScroll]);\n\n // Filter logs based on current filter settings\n const filteredLogs = logs.filter(log => {\n const matchesText = filter ? log.message.toLowerCase().includes(filter.toLowerCase()) : true;\n const matchesType = typeFilter.includes(log.type);\n const matchesSource = sourceFilter.includes(log.source as 'main' | 'child');\n return matchesText && matchesType && matchesSource;\n });\n\n // Format timestamp to readable format\n const formatTimestamp = (timestamp: number) => {\n const date = new Date(timestamp);\n return date.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n };\n\n // Get badge color based on log type\n const getLogTypeColor = (type: string) => {\n switch (type) {\n case 'error': return 'bg-red-400/80 text-white';\n case 'warn': return 'bg-yellow-400/80 text-gray-900';\n case 'debug': return 'bg-purple-400/80 text-white';\n case 'info': return 'bg-blue-400/80 text-white';\n default: return 'bg-blue-400/80 text-white';\n }\n };\n\n // Get badge color based on log source\n const getSourceColor = (source: string) => {\n switch (source) {\n case 'main': return 'bg-green-400/80 text-white';\n case 'child': return 'bg-orange-400/80 text-white';\n default: return 'bg-gray-400/80 text-white';\n }\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"bg-card p-3 rounded-t-md flex flex-wrap items-center justify-between gap-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-semibold text-sm\">{t('logs.filters')}:</span>\n\n {/* Text search filter */}\n <input\n type=\"text\"\n placeholder={t('logs.search')}\n className=\"shadow appearance-none border border-gray-200 dark:border-gray-700 rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline form-input\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n />\n\n {/* Log type filters */}\n <div className=\"flex gap-1 items-center\">\n {(['debug', 'info', 'error', 'warn'] as const).map(type => (\n <Badge\n key={type}\n variant={typeFilter.includes(type) ? 'default' : 'outline'}\n className={`cursor-pointer ${typeFilter.includes(type) ? getLogTypeColor(type) : ''}`}\n onClick={() => {\n if (typeFilter.includes(type)) {\n setTypeFilter(prev => prev.filter(t => t !== type));\n } else {\n setTypeFilter(prev => [...prev, type]);\n }\n }}\n >\n {type}\n </Badge>\n ))}\n </div>\n\n {/* Log source filters */}\n <div className=\"flex gap-1 items-center ml-2\">\n {(['main', 'child'] as const).map(source => (\n <Badge\n key={source}\n variant={sourceFilter.includes(source) ? 'default' : 'outline'}\n className={`cursor-pointer ${sourceFilter.includes(source) ? getSourceColor(source) : ''}`}\n onClick={() => {\n if (sourceFilter.includes(source)) {\n setSourceFilter(prev => prev.filter(s => s !== source));\n } else {\n setSourceFilter(prev => [...prev, source]);\n }\n }}\n >\n {source === 'main' ? t('logs.mainProcess') : t('logs.childProcess')}\n </Badge>\n ))}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1 text-sm\">\n <input\n type=\"checkbox\"\n checked={autoScroll}\n onChange={() => setAutoScroll(!autoScroll)}\n className=\"form-checkbox h-4 w-4\"\n />\n {t('logs.autoScroll')}\n </label>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={onClear}\n className='btn-secondary'\n disabled={isLoading || logs.length === 0}\n >\n {t('logs.clearLogs')}\n </Button>\n </div>\n </div>\n\n <div\n ref={logContainerRef}\n className=\"flex-grow p-2 overflow-auto bg-card rounded-b-md font-mono text-sm\"\n style={{ maxHeight: 'calc(100vh - 300px)' }}\n >\n {isLoading ? (\n <div className=\"flex justify-center items-center h-full\">\n <span>{t('logs.loading')}</span>\n </div>\n ) : error ? (\n <div className=\"text-red-500 p-2\">\n {error.message}\n </div>\n ) : filteredLogs.length === 0 ? (\n <div className=\"text-center text-muted-foreground p-8\">\n {filter || typeFilter.length < 4 || sourceFilter.length < 2\n ? t('logs.noMatch')\n : t('logs.noLogs')}\n </div>\n ) : (\n filteredLogs.map((log, index) => (\n <div\n key={`${log.timestamp}-${index}`}\n className={`py-1 ${log.type === 'error' ? 'text-red-500' :\n log.type === 'warn' ? 'text-yellow-500' : ''\n }`}\n >\n <span className=\"text-gray-400\">[{formatTimestamp(log.timestamp)}]</span>\n <Badge className={`ml-2 mr-1 ${getLogTypeColor(log.type)}`}>\n {log.type}\n </Badge>\n <Badge\n variant=\"default\"\n className={`mr-2 ${getSourceColor(log.source)}`}\n >\n {log.source === 'main' ? t('logs.main') : t('logs.child')}\n {log.processId ? ` (${log.processId})` : ''}\n </Badge>\n <span className=\"whitespace-pre-wrap\">{log.message}</span>\n </div>\n ))\n )}\n </div>\n </div>\n );\n};\n\nexport default LogViewer;","import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport LogViewer from '../components/LogViewer';\nimport { useLogs } from '../services/logService';\n\nconst LogsPage: React.FC = () => {\n const { t } = useTranslation();\n const { logs, loading, error, clearLogs } = useLogs();\n\n return (\n <div>\n <div className=\"mb-6\">\n <h1 className=\"hub-h1\">{t('pages.logs.title')}</h1>\n <p className=\"hub-sub\">\n <span className=\"hub-num\">{logs.length}</span> entries\n </p>\n </div>\n <div className=\"hub-card overflow-hidden\">\n <LogViewer logs={logs} isLoading={loading} error={error} onClear={clearLogs} />\n </div>\n </div>\n );\n};\n\nexport default LogsPage;\n"],"names":["__defProp","__name","target","value","setRef","ref","composeRefs","refs","node","hasCleanup","cleanups","cleanup","i","useComposedRefs","React.useCallback","createSlot","ownerName","Slot2","React.forwardRef","props","forwardedRef","children","slotProps","slottableElement","hasSlottable","newChildren","isLazyComponent","use","React.Children","maybeSlottable","isSlottable","slottable","child","getSlottableElementFromSlottable","_a","React.cloneElement","React.isValidElement","slottableElementRef","getElementRef","composedRef","createSlottableError","createSlotError","mergedProps","mergeProps","React.Fragment","Slot","SLOTTABLE_IDENTIFIER","createSlottable","Slottable2","child2","childProps","overrideProps","propName","slotPropValue","childPropValue","args","result","element","getter","mayWarn","_b","REACT_LAZY_TYPE","isPromiseLike","React","variantStyles","sizeStyles","Button","variant","size","className","disabled","externalLoading","asChild","onClick","internalLoading","setInternalLoading","useState","isLoading","handleClick","e","Comp","jsx","cn","jsxs","Fragment","badgeVariants","Badge","LogViewer","logs","error","onClear","useTranslation","logContainerRef","useRef","autoScroll","setAutoScroll","filter","setFilter","typeFilter","setTypeFilter","sourceFilter","setSourceFilter","useEffect","filteredLogs","log","matchesText","matchesType","matchesSource","formatTimestamp","timestamp","getLogTypeColor","type","getSourceColor","source","prev","t","s","index","LogsPage","loading","clearLogs","useLogs"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as t,j as e,d as He,b as We,i as _e}from"./framework-vendor-CQFm9vKd.js";import{f as J,k as ve,u as je,j as Fe}from"./index-DkQidC_d.js";import{u as ne}from"./i18n-vendor-DVmjrzgW.js";import{g as Ne,a as ke,d as Oe,s as xe}from"./variableDetection-SMtrW-P5.js";import{C as Se,$ as Qe,a5 as qe,a7 as Ge,l as Je,X as Xe,G as Ye,n as Ze}from"./icons-vendor-CkcU1LMA.js";import{P as Ke}from"./Pagination-BRqqU5Ct.js";import"./contextCost-CilWqGWT.js";const es=()=>{const{t:s}=ne(),[p,b]=t.useState([]),[d,m]=t.useState([]),[i,a]=t.useState([]),[A,f]=t.useState([]),[o,D]=t.useState(""),[P,U]=t.useState(""),[M,H]=t.useState(""),[I,C]=t.useState(!0),[F,S]=t.useState(null),[z,O]=t.useState(null),[V,T]=t.useState([]),[Q,$]=t.useState(1),[w,q]=t.useState(9),[k,K]=t.useState(1),B=t.useCallback(async()=>{try{C(!0);const r=await J("/market/servers");r&&r.success&&Array.isArray(r.data)?(m(r.data),E(r.data,Q)):(console.error("Invalid market servers data format",{data:r}),S(s("market.fetchError")))}catch(r){console.error("Error fetching market servers",{err:r}),S(r instanceof Error?r.message:String(r))}finally{C(!1)}},[s]),E=t.useCallback((r,l,G=w)=>{const se=r.length,_=Math.ceil(se/G);K(_);const Y=Math.max(1,Math.min(l,_));Y!==l&&$(Y);const ee=(Y-1)*G,re=r.slice(ee,ee+G);b(re)},[w]),y=t.useCallback(r=>{$(r),E(d,r,w)},[d,E,w]),n=t.useCallback(async()=>{try{const r=await J("/market/categories");r&&r.success&&Array.isArray(r.data)?a(r.data):console.error("Invalid categories data format",{data:r})}catch(r){console.error("Error fetching categories",{err:r})}},[]),h=t.useCallback(async()=>{try{const r=await J("/market/tags");r&&r.success&&Array.isArray(r.data)?f(r.data):console.error("Invalid tags data format",{data:r})}catch(r){console.error("Error fetching tags",{err:r})}},[]),g=t.useCallback(async r=>{try{C(!0);const l=await J(`/market/servers/${r}`);return l&&l.success&&l.data?(O(l.data),l.data):(console.error("Invalid market server data format",{name:r,data:l}),S(s("market.serverNotFound")),null)}catch(l){return console.error("Error fetching market server",{name:r,err:l}),S(l instanceof Error?l.message:String(l)),null}finally{C(!1)}},[s]),N=t.useCallback(async r=>{try{if(C(!0),H(r),!r.trim()){B();return}const l=await J(`/market/servers/search?query=${encodeURIComponent(r)}`);l&&l.success&&Array.isArray(l.data)?(m(l.data),$(1),E(l.data,1)):(console.error("Invalid market search results format",{query:r,data:l}),S(s("market.searchError")))}catch(l){console.error("Error searching market servers",{query:r,err:l}),S(l instanceof Error?l.message:String(l))}finally{C(!1)}},[s,d,E,B]),W=t.useCallback(async r=>{try{if(C(!0),D(r),U(""),!r){B();return}const l=await J(`/market/categories/${encodeURIComponent(r)}`);l&&l.success&&Array.isArray(l.data)?(m(l.data),$(1),E(l.data,1)):(console.error("Invalid market category filter results format",{category:r,data:l}),S(s("market.filterError")))}catch(l){console.error("Error filtering market servers by category",{category:r,err:l}),S(l instanceof Error?l.message:String(l))}finally{C(!1)}},[s,B,E]),R=t.useCallback(async r=>{try{if(C(!0),U(r),D(""),!r){B();return}const l=await J(`/market/tags/${encodeURIComponent(r)}`);l&&l.success&&Array.isArray(l.data)?(m(l.data),$(1),E(l.data,1)):(console.error("Invalid market tag filter results format",{tag:r,data:l}),S(s("market.tagFilterError")))}catch(l){console.error("Error filtering market servers by tag",{tag:r,err:l}),S(l instanceof Error?l.message:String(l))}finally{C(!1)}},[s,B,E]),X=t.useCallback(async()=>{try{const r=await J("/servers");if(r&&r.success&&Array.isArray(r.data)){const l=r.data.map(G=>G.name);T(l)}}catch(r){console.error("Error fetching installed servers",{err:r})}},[]),c=t.useCallback(r=>V.includes(r),[V]),v=t.useCallback(async(r,l)=>{var G,se;try{const _=(G=r.installations)!=null&&G.npm?"npm":Object.keys(r.installations||{}).length>0?Object.keys(r.installations)[0]:null;if(!_||!((se=r.installations)!=null&&se[_]))return S(s("market.noInstallationMethod")),!1;const Y=r.installations[_],ee={name:r.name,config:l.type==="stdio"?{command:l.command||Y.command||"",args:l.args||Y.args||[],env:{...Y.env,...l.env}}:l},re=await ve("/servers",ee);if(!re.success)throw new Error(re.message||"Failed to install server");return await X(),!0}catch(_){return console.error("Error installing market server",{serverName:r.name,err:_}),S(_ instanceof Error?_.message:String(_)),!1}},[s,X]),u=t.useCallback(r=>{q(r),$(1),E(d,1,r)},[d,E]);return t.useEffect(()=>{B(),n(),h(),X()},[B,n,h,X]),{servers:p,allServers:d,categories:i,tags:A,selectedCategory:o,selectedTag:P,searchQuery:M,loading:I,error:F,setError:S,currentServer:z,fetchMarketServers:B,fetchServerByName:g,searchServers:N,filterByCategory:W,filterByTag:R,installServer:v,currentPage:Q,totalPages:k,serversPerPage:w,changePage:y,changeServersPerPage:u,isServerInstalled:c}},ss=()=>{const{t:s}=ne(),[p,b]=t.useState([]),[d,m]=t.useState([]),[i,a]=t.useState(!0),[A,f]=t.useState(null),[o,D]=t.useState(""),[P,U]=t.useState(1),[M,H]=t.useState(9),[I,C]=t.useState(null),[F,S]=t.useState(!1),[z,O]=t.useState([]),[V]=t.useState(1),T=t.useCallback(async(n,h)=>{try{a(!0),f(null);const g=new URLSearchParams;g.append("limit",M.toString()),n&&g.append("cursor",n);const N=h!==void 0?h:o;N.trim()&&g.append("search",N.trim());const W=await J(`/registry/servers?${g.toString()}`);if(W&&W.success&&W.data){const R=W.data;if(R.servers&&Array.isArray(R.servers)){b(R.servers);const X=R.metadata.count===M&&!!R.metadata.nextCursor;S(X),C(R.metadata.nextCursor||null),m(n?c=>[...c,...R.servers]:R.servers)}else console.error("Invalid registry servers data format",{data:R}),f(s("registry.fetchError"))}else f(s("registry.fetchError"))}catch(g){console.error("Error fetching registry servers",{cursor:n,search:h,err:g});const N=g instanceof Error?g.message:String(g);f(N)}finally{a(!1)}},[s,M]),Q=t.useCallback(async()=>{if(!F||!I)return;const n=z[z.length-1]||"";O(h=>[...h,n]),U(h=>h+1),await T(I,o)},[F,I,z,o,T]),$=t.useCallback(async()=>{if(P<=1)return;const n=[...z];n.pop();const h=n[n.length-1];O(n),U(g=>g-1),await T(h||void 0,o)},[P,z,o,T]),w=t.useCallback(async n=>{n!==P&&(n>P&&F?await Q():n<P&&P>1&&await $())},[P,F,Q,$]),q=t.useCallback(async n=>{H(n),U(1),O([]),m([]),await T(void 0,o)},[o,T]),k=t.useCallback(async n=>{try{a(!0),f(null);const h=encodeURIComponent(n),g=await J(`/registry/servers/versions?serverName=${h}`);if(g&&g.success&&g.data){const N=g.data;return N.servers&&Array.isArray(N.servers)&&N.servers.length>0?N.servers[0]:(console.error("Invalid registry server data format",{serverName:n,data:N}),f(s("registry.serverNotFound")),null)}else return f(s("registry.serverNotFound")),null}catch(h){console.error("Error fetching registry server",{serverName:n,err:h});const g=h instanceof Error?h.message:String(h);return f(g),null}finally{a(!1)}},[s]),K=t.useCallback(async n=>{try{f(null);const h=encodeURIComponent(n),g=await J(`/registry/servers/versions?serverName=${h}`);if(g&&g.success&&g.data){const N=g.data;return N.servers&&Array.isArray(N.servers)?N.servers:(console.error("Invalid registry server versions data format",{serverName:n,data:N}),[])}else return[]}catch(h){console.error("Error fetching versions for registry server",{serverName:n,err:h});const g=h instanceof Error?h.message:String(h);return f(g),[]}},[]),B=t.useCallback(async(n,h)=>{try{f(null);const g=encodeURIComponent(n),N=encodeURIComponent(h),W=await J(`/registry/servers/version?serverName=${g}&version=${N}`);if(W&&W.success&&W.data){const R=W.data;return R&&R.server?R:(console.error("Invalid registry server version data format",{serverName:n,version:h,data:R}),null)}else return null}catch(g){console.error("Error fetching specific registry server version",{serverName:n,version:h,err:g});const N=g instanceof Error?g.message:String(g);return f(N),null}},[]),E=t.useCallback(async n=>{console.log("Searching registry servers",{query:n}),D(n),U(1),O([]),m([]),await T(void 0,n)},[T]),y=t.useCallback(async()=>{D(""),U(1),O([]),m([]),await T(void 0,"")},[T]);return t.useEffect(()=>{T(void 0,o)},[]),{servers:p,allServers:d,loading:i,error:A,setError:f,searchQuery:o,searchServers:E,clearSearch:y,fetchServerByName:k,fetchServerVersions:K,fetchServerVersion:B,currentPage:P,totalPages:V,hasNextPage:F,hasPreviousPage:P>1,changePage:w,goToNextPage:Q,goToPreviousPage:$,serversPerPage:M,changeServersPerPage:q}},rs=s=>s.split(" ").map(p=>p.charAt(0)).join("").toUpperCase().slice(0,2),ts=({server:s,onClick:p})=>{var i,a,A;const{t:b}=ne(),d=(s.tags||[]).slice(0,3),m=(i=s.categories)==null?void 0:i[0];return e.jsxs("div",{className:"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden",onClick:()=>p(s),onMouseEnter:f=>f.currentTarget.style.borderColor="var(--hub-ink-2)",onMouseLeave:f=>f.currentTarget.style.borderColor="var(--hub-line)",children:[e.jsxs("div",{className:"p-3.5 flex-1 flex flex-col gap-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"hub-mono",style:{width:28,height:28,borderRadius:7,background:"var(--hub-ink)",color:"var(--hub-bg)",display:"grid",placeItems:"center",fontWeight:600,fontSize:13,flexShrink:0},children:rs(s.display_name||s.name)[0]||"?"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"truncate",style:{fontSize:14,fontWeight:500,letterSpacing:"-0.01em"},children:s.display_name}),s.is_official&&e.jsxs("span",{className:"inline-flex items-center gap-0.5",style:{fontSize:10,color:"var(--hub-accent)",background:"var(--hub-accent-soft)",padding:"0 5px",height:16,borderRadius:3,fontWeight:500},children:[e.jsx(Se,{size:9,strokeWidth:2.5}),b("market.official")]})]}),e.jsxs("div",{className:"hub-mono truncate",style:{fontSize:11,color:"var(--hub-ink-3)"},children:["@",((a=s.author)==null?void 0:a.name)||b("market.unknown")]})]})]}),e.jsx("div",{className:"flex-1 line-clamp-2",style:{fontSize:12.5,color:"var(--hub-ink-2)",lineHeight:1.5},children:s.description}),d.length>0&&e.jsx("div",{className:"flex gap-1 flex-wrap",children:d.map(f=>e.jsxs("span",{className:"hub-tag",style:{background:"oklch(0.96 0.04 145)",color:"oklch(0.4 0.1 145)",border:0},children:["#",f]},f))})]}),e.jsx("div",{className:"flex items-center justify-between px-3.5 py-2",style:{borderTop:"1px solid var(--hub-line-2)",background:"var(--hub-bg-2)"},children:e.jsxs("div",{className:"hub-mono flex items-center gap-3",style:{fontSize:11.5,color:"var(--hub-ink-3)"},children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Qe,{size:11}),((A=s.tools)==null?void 0:A.length)??0," ",b("server.tools").toLowerCase()]}),m&&e.jsx("span",{className:"truncate",children:m})]})})]})},as=({server:s,onBack:p,onInstall:b,installing:d=!1,isInstalled:m=!1})=>{var k,K,B,E;const{t:i}=ne(),{auth:a}=je(),A=Ne({type:"stdio"},(k=a.user)==null?void 0:k.isAdmin),[f,o]=t.useState(!1),[D,P]=t.useState(null),[U,M]=t.useState(!1),[H,I]=t.useState(null),[C,F]=t.useState([]),S=()=>m?{className:"bg-green-600 cursor-default px-4 py-2 rounded text-sm font-medium text-white",disabled:!0,text:i("market.installed")}:d?{className:"bg-gray-400 cursor-not-allowed px-4 py-2 rounded text-sm font-medium text-white",disabled:!0,text:i("market.installing")}:{className:`hub-btn primary ${A?"opacity-50 cursor-not-allowed":""}`,disabled:!!A,text:i("market.install")},z=()=>{o(!f),P(null),M(!1),I(null)},O=async()=>{H&&(await V(H),M(!1),I(null))},V=async y=>{try{P(null),b(s,y.config),o(!1)}catch(n){console.error("Error installing server:",n),P(i("errors.serverInstall"))}},T=()=>{!m&&!A&&z()},Q=()=>{if(!s.installations)return;if(s.installations.npm)return s.installations.npm;if(s.installations.uvx)return s.installations.uvx;if(s.installations.default)return s.installations.default;const y=Object.keys(s.installations);if(y.length>0)return s.installations[y[0]]},$=async y=>{try{const n=Oe(y);n.length>0?(F(n),I(y),M(!0)):await V(y)}catch(n){console.error("Error processing server installation:",n),P(i("errors.serverInstall"))}},w=S(),q=Q();return e.jsxs("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-md p-6",children:[e.jsx("div",{className:"mb-4",children:e.jsxs("button",{onClick:p,className:"text-gray-600 hover:text-gray-900 flex items-center",children:[e.jsx("svg",{className:"h-5 w-5 mr-1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z",clipRule:"evenodd"})}),i("market.backToList")]})}),e.jsxs("div",{className:"flex justify-between items-start mb-4",children:[e.jsx("div",{children:e.jsxs("h2",{className:"text-2xl font-bold text-gray-900 flex items-center flex-wrap",children:[s.display_name,e.jsxs("span",{className:"text-sm font-normal text-gray-500 ml-2",children:["(",s.name,")"]}),e.jsxs("span",{className:"text-sm font-normal text-gray-600 ml-4",children:[i("market.author"),": ",((K=s.author)==null?void 0:K.name)||i("market.unknown")," •"," ",i("market.license"),": ",s.license," •",e.jsx("a",{href:s.repository.url,target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:underline ml-1",children:i("market.repository")})]})]})}),e.jsxs("div",{className:"flex items-center",children:[s.is_official&&e.jsx("span",{className:"bg-blue-100 text-blue-800 dark:text-blue-300 dark:bg-blue-900/40 dark:text-blue-300 text-sm font-normal px-4 py-2 rounded mr-2 flex items-center label-primary",children:i("market.official")}),e.jsx("button",{onClick:T,disabled:w.disabled,className:w.className,children:w.text})]})]}),A&&e.jsx("p",{role:"status",className:"text-sm text-amber-700 dark:text-amber-300 mb-4",children:i(A)}),e.jsx("p",{className:"text-gray-700 mb-6",children:s.description}),e.jsxs("div",{className:"mb-6",children:[e.jsxs("h3",{className:"text-lg font-semibold mb-3",children:[i("market.categories")," & ",i("market.tags")]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[(B=s.categories)==null?void 0:B.map((y,n)=>e.jsx("span",{className:"bg-gray-100 dark:bg-gray-800 text-gray-800 px-3 py-1 rounded",children:y},`cat-${n}`)),s.tags&&s.tags.map((y,n)=>e.jsxs("span",{className:"bg-gray-100 dark:bg-gray-800 text-green-700 dark:text-green-300 px-2 py-1 rounded text-sm",children:["#",y]},`tag-${n}`))]})]}),s.arguments&&Object.keys(s.arguments).length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:i("market.arguments")}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-gray-200 dark:divide-gray-700",children:[e.jsx("thead",{className:"bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.argumentName")}),e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.description")}),e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.required")}),e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.example")})]})}),e.jsx("tbody",{className:"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700",children:Object.entries(s.arguments).map(([y,n],h)=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900",children:y}),e.jsx("td",{className:"px-6 py-4 text-sm text-gray-500",children:n.description}),e.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500",children:n.required?e.jsx("span",{className:"text-green-600",children:"✓"}):e.jsx("span",{className:"text-gray-600",children:"✗"})}),e.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500",children:e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded",children:n.example})})]},h))})]})})]}),e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:i("market.tools")}),e.jsx("div",{className:"space-y-4",children:(E=s.tools)==null?void 0:E.map((y,n)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded p-4",children:[e.jsxs("h4",{className:"font-medium mb-2",children:[y.name,e.jsx("button",{type:"button",onClick:()=>{const h=document.getElementById(`schema-${n}`);h&&h.classList.toggle("hidden")},className:"text-sm text-blue-500 font-normal hover:underline focus:outline-none ml-2",children:i("market.viewSchema")})]}),e.jsx("p",{className:"text-gray-600 mb-2",children:y.description}),e.jsx("div",{className:"mt-2",children:e.jsx("pre",{id:`schema-${n}`,className:"hidden bg-gray-50 dark:bg-gray-800 p-3 rounded text-sm overflow-auto mt-2",children:JSON.stringify(y.inputSchema,null,2)})})]},n))})]}),s.examples&&s.examples.length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:i("market.examples")}),e.jsx("div",{className:"space-y-4",children:s.examples.map((y,n)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded p-4",children:[e.jsx("h4",{className:"font-medium mb-2",children:y.title}),e.jsx("p",{className:"text-gray-600 mb-2",children:y.description}),e.jsx("pre",{className:"bg-gray-50 dark:bg-gray-800 p-3 rounded text-sm overflow-auto",children:y.prompt})]},n))})]}),e.jsx("div",{className:"mt-6 flex justify-end",children:e.jsx("button",{onClick:T,disabled:w.disabled,className:w.className,children:w.text})}),f&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsx(ke,{onSubmit:$,onCancel:z,modalTitle:i("market.installServer",{name:s.display_name}),formError:D,initialData:{name:s.name,status:"disconnected",config:q?{command:q.command||"",args:q.args||[],env:q.env||{}}:void 0}})}),U&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-[60] flex items-center justify-center p-4",children:e.jsxs("div",{className:"hub-card p-6 w-full max-w-md",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:i("server.confirmVariables")}),e.jsx("p",{className:"text-gray-600 mb-4",children:i("server.variablesDetected")}),e.jsx("div",{className:"bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-700/60 rounded p-3 mb-4",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0",children:e.jsx("svg",{className:"h-5 w-5 text-yellow-400",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})})}),e.jsxs("div",{className:"ml-3",children:[e.jsxs("h4",{className:"text-sm font-medium text-yellow-800 dark:text-yellow-300",children:[i("server.detectedVariables"),":"]}),e.jsx("ul",{className:"mt-1 text-sm text-yellow-700 dark:text-yellow-300",children:C.map((y,n)=>e.jsxs("li",{className:"font-mono",children:["$",`{${y}}`]},n))})]})]})}),e.jsx("p",{className:"text-gray-600 text-sm mb-6",children:i("market.confirmVariablesMessage")}),e.jsxs("div",{className:"flex justify-end space-x-3",children:[e.jsx("button",{onClick:()=>{M(!1),I(null)},className:"hub-btn",children:i("common.cancel")}),e.jsx("button",{onClick:O,className:"hub-btn primary",children:i("market.confirmAndInstall")})]})]})})]})},ns=s=>{if(!s)return"";try{const p=new Date(s),b=p.getFullYear(),d=(p.getMonth()+1).toString().padStart(2,"0"),m=p.getDate().toString().padStart(2,"0");return`${b}/${d}/${m}`}catch{return""}},ls=({serverEntry:s,onClick:p})=>{var M,H;const{t:b}=ne(),{server:d,_meta:m}=s,i=m==null?void 0:m["io.modelcontextprotocol.registry/official"],a=i==null?void 0:i.isLatest,A=i==null?void 0:i.publishedAt,f=i==null?void 0:i.updatedAt,o=((M=d.packages)==null?void 0:M.length)||0,D=((H=d.remotes)==null?void 0:H.length)||0,P=d.description?d.description.length<=150?d.description:d.description.slice(0,150)+"...":b("registry.noDescription"),U=d.icons&&d.icons.length>0?d.icons.find(C=>!C.theme||C.theme==="light")||d.icons[0]:null;return e.jsxs("div",{className:"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden",onClick:()=>p(s),onMouseEnter:I=>I.currentTarget.style.borderColor="var(--hub-ink-2)",onMouseLeave:I=>I.currentTarget.style.borderColor="var(--hub-line)",children:[e.jsxs("div",{className:"p-3.5 flex-1 flex flex-col gap-2.5",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[U?e.jsx("img",{src:U.src,alt:d.title||d.name,className:"rounded-md object-cover flex-shrink-0",style:{width:28,height:28},onError:I=>{I.currentTarget.style.display="none"}}):e.jsx("div",{className:"hub-mono flex-shrink-0",style:{width:28,height:28,borderRadius:7,background:"var(--hub-ink)",color:"var(--hub-bg)",display:"grid",placeItems:"center",fontWeight:600,fontSize:13},children:d.name.charAt(0).toUpperCase()}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"truncate",style:{fontSize:14,fontWeight:500,letterSpacing:"-0.01em"},children:d.title||d.name}),a&&e.jsxs("span",{className:"inline-flex items-center gap-0.5 flex-shrink-0",style:{fontSize:10,color:"oklch(0.4 0.13 145)",background:"oklch(0.95 0.05 145)",padding:"0 5px",height:16,borderRadius:3,fontWeight:500},children:[e.jsx(Se,{size:9,strokeWidth:2.5}),b("registry.latest")]})]}),e.jsxs("div",{className:"hub-mono truncate",style:{fontSize:11,color:"var(--hub-ink-3)"},children:[d.name," · v",d.version]})]})]}),e.jsx("div",{className:"flex-1 line-clamp-2",style:{fontSize:12.5,color:"var(--hub-ink-2)",lineHeight:1.5},children:P})]}),e.jsxs("div",{className:"flex items-center justify-between px-3.5 py-2",style:{borderTop:"1px solid var(--hub-line-2)",background:"var(--hub-bg-2)"},children:[e.jsxs("div",{className:"hub-mono flex items-center gap-3",style:{fontSize:11.5,color:"var(--hub-ink-3)"},children:[o>0&&e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(qe,{size:11}),o]}),D>0&&e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ge,{size:11}),D]}),(A||f)&&e.jsx("span",{children:ns(f||A)})]}),e.jsxs("span",{className:"hub-mono",style:{fontSize:11,color:"var(--hub-accent)"},children:[b("registry.viewDetails")," →"]})]})]})},os=({serverEntry:s,onBack:p,onInstall:b,installing:d=!1,isInstalled:m=!1,fetchVersions:i})=>{var X;const{t:a}=ne(),{auth:A}=je(),f=Ne({type:"stdio"},(X=A.user)==null?void 0:X.isAdmin),{server:o,_meta:D}=s,[P,U]=t.useState(o.version),[M,H]=t.useState([]),[I,C]=t.useState(!1),[F,S]=t.useState(!1),[z,O]=t.useState(null),[V,T]=t.useState(null),[Q,$]=t.useState(null),[w,q]=t.useState({packages:!0,remotes:!0,repository:!0}),k=D==null?void 0:D["io.modelcontextprotocol.registry/official"];t.useEffect(()=>{(async()=>{if(i){C(!0);try{const v=await i(o.name);H(v)}catch(v){console.error("Failed to load versions:",v)}finally{C(!1)}}})()},[o.name,i]);const B=o.icons&&o.icons.length>0?o.icons.find(v=>!v.theme||v.theme==="light")||o.icons[0]:null,E=c=>{if(!c)return"";try{return new Date(c).toLocaleDateString()}catch{return""}},y=c=>{q(v=>({...v,[c]:!v[c]}))},n=(c,v)=>{c==="package"&&f||(O(c),T(v),$(null),S(!0))},h=()=>{S(!1),$(null)},g=async c=>{try{if(!b||!V||!z)return;$(null);const v=c.config;b(o,v),S(!1)}catch(v){console.error("Error installing server:",v),$(a("errors.serverInstall"))}},N=()=>{if(!V||!z)return null;if(console.log("Building initial form data for:",V),z==="package"&&"identifier"in V){const c=V,v={};c.environmentVariables&&c.environmentVariables.forEach(r=>{v[r.name]=r.default||""});const u=is(c.registryType);return{name:xe(o.name),status:"disconnected",config:{type:"stdio",command:u,args:cs(u,c),env:Object.keys(v).length>0?v:void 0}}}else if(z==="remote"&&"url"in V){const c=V,v={};c.headers&&c.headers.forEach(r=>{v[r.name]=r.default||r.value||""});const u=c.type==="sse"?"sse":"streamable-http";return{name:xe(o.name),status:"disconnected",config:{type:u,url:c.url,headers:Object.keys(v).length>0?v:void 0}}}return null},W=(c,v)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4 mb-3 hover:border-blue-400 transition-colors",children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium text-gray-900",children:c.identifier}),c.version&&e.jsxs("p",{className:"text-sm text-gray-500",children:["Version: ",c.version]}),c.runtimeHint&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:c.runtimeHint})]}),e.jsx("button",{onClick:()=>n("package",c),disabled:m||d||!!f,className:`px-4 py-2 rounded text-sm font-medium transition-colors ${m?"hub-btn cursor-default":d||f?"hub-btn cursor-not-allowed opacity-50":"hub-btn primary"}`,children:a(m?"registry.installed":d?"registry.installing":"registry.install")})]}),f&&e.jsx("p",{role:"status",className:"text-sm text-amber-700 dark:text-amber-300 mb-3",children:a(f)}),c.registryType&&e.jsxs("div",{className:"text-sm text-gray-600 mb-2",children:[e.jsx("span",{className:"font-medium",children:"Registry:"})," ",c.registryType]}),c.transport&&e.jsxs("div",{className:"text-sm text-gray-600 mb-2",children:[e.jsx("span",{className:"font-medium",children:"Transport:"})," ",c.transport.type,c.transport.url&&e.jsxs("span",{className:"ml-2 text-gray-500",children:["(",c.transport.url,")"]})]}),c.environmentVariables&&c.environmentVariables.length>0&&e.jsxs("div",{className:"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3",children:[e.jsxs("h5",{className:"text-sm font-medium text-gray-700 mb-2",children:[a("registry.environmentVariables"),":"]}),e.jsx("div",{className:"space-y-2",children:c.environmentVariables.map((u,r)=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"flex items-start",children:[e.jsx("span",{className:"font-mono text-gray-900 font-medium",children:u.name}),u.isRequired&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800",children:a("common.required")}),u.isSecret&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800",children:a("common.secret")})]}),u.description&&e.jsx("p",{className:"text-gray-600 mt-1",children:u.description}),u.default&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.default"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.default})]})]},r))})]}),c.packageArguments&&c.packageArguments.length>0&&e.jsxs("div",{className:"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3",children:[e.jsxs("h5",{className:"text-sm font-medium text-gray-700 mb-2",children:[a("registry.packageArguments"),":"]}),e.jsx("div",{className:"space-y-2",children:c.packageArguments.map((u,r)=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"flex items-start",children:[e.jsx("span",{className:"font-mono text-gray-900 font-medium",children:u.name}),u.isRequired&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800",children:a("common.required")}),u.isSecret&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800",children:a("common.secret")}),u.isRepeated&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300",children:a("common.repeated")})]}),u.description&&e.jsx("p",{className:"text-gray-600 mt-1",children:u.description}),u.type&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.type"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.type})]}),u.default&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.default"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.default})]}),u.value&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.value"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.value})]}),u.valueHint&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.valueHint"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.valueHint})]}),u.choices&&u.choices.length>0&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.choices"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.choices.join(", ")})]})]},r))})]})]},v),R=(c,v)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4 mb-3 hover:border-blue-400 transition-colors",children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium text-gray-900",children:c.type}),e.jsx("p",{className:"text-sm text-gray-600 mt-1 break-all",children:c.url})]}),e.jsx("button",{onClick:()=>n("remote",c),disabled:m||d,className:`px-4 py-2 rounded text-sm font-medium transition-colors ${m?"hub-btn cursor-default":d?"hub-btn cursor-not-allowed opacity-50":"hub-btn primary"}`,children:a(m?"registry.installed":d?"registry.installing":"registry.install")})]}),c.headers&&c.headers.length>0&&e.jsxs("div",{className:"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3",children:[e.jsxs("h5",{className:"text-sm font-medium text-gray-700 mb-2",children:[a("registry.headers"),":"]}),e.jsx("div",{className:"space-y-2",children:c.headers.map((u,r)=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"flex items-start",children:[e.jsx("span",{className:"font-mono text-gray-900 font-medium",children:u.name}),u.isRequired&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800",children:a("common.required")}),u.isSecret&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800",children:a("common.secret")})]}),u.description&&e.jsx("p",{className:"text-gray-600 mt-1",children:u.description}),u.value&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.value"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.value})]}),u.default&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.default"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.default})]})]},r))})]})]},v);return e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:p,className:"flex items-center text-blue-600 hover:text-blue-800 mb-4 transition-colors",children:[e.jsx("svg",{className:"w-5 h-5 mr-2",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),a("registry.backToList")]}),e.jsxs("div",{className:"flex items-start space-x-4",children:[B?e.jsx("img",{src:B.src,alt:o.title,className:"w-20 h-20 rounded-lg object-cover flex-shrink-0",onError:c=>{c.currentTarget.style.display="none"}}):e.jsx("div",{className:"w-20 h-20 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center text-white text-3xl font-semibold flex-shrink-0",children:"M"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h1",{className:"text-3xl font-bold text-gray-900 mb-2",children:o.name}),e.jsxs("div",{className:"flex flex-wrap gap-2 mb-3",children:[(k==null?void 0:k.isLatest)&&e.jsx("span",{className:"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800",children:a("registry.latest")}),e.jsxs("span",{className:"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300",children:["v",o.version]}),(k==null?void 0:k.status)&&e.jsx("span",{className:"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-gray-100 dark:bg-gray-800 text-gray-800",children:k.status}),e.jsxs("span",{className:"flex flex-wrap items-center gap-4 text-sm text-gray-600",children:[(k==null?void 0:k.publishedAt)&&e.jsxs("div",{children:[e.jsxs("span",{className:"font-medium",children:[a("registry.published"),":"]})," ",E(k.publishedAt)]}),(k==null?void 0:k.updatedAt)&&e.jsxs("div",{children:[e.jsxs("span",{className:"font-medium",children:[a("registry.updated"),":"]})," ",E(k.updatedAt)]})]})]})]})]})]}),e.jsxs("div",{className:"mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900 mb-3",children:a("registry.description")}),e.jsx("p",{className:"text-gray-700 leading-relaxed whitespace-pre-wrap",children:o.description})]}),o.websiteUrl&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900 mb-3",children:a("registry.website")}),e.jsx("a",{href:o.websiteUrl,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 hover:underline",children:o.websiteUrl})]}),o.packages&&o.packages.length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:()=>y("packages"),className:"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors",children:[e.jsxs("span",{children:[a("registry.packages")," (",o.packages.length,")"]}),e.jsx("svg",{className:`w-5 h-5 transform transition-transform ${w.packages?"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"})})]}),w.packages&&e.jsx("div",{className:"space-y-3",children:o.packages.map(W)})]}),o.remotes&&o.remotes.length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:()=>y("remotes"),className:"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors",children:[e.jsxs("span",{children:[a("registry.remotes")," (",o.remotes.length,")"]}),e.jsx("svg",{className:`w-5 h-5 transform transition-transform ${w.remotes?"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"})})]}),w.remotes&&e.jsx("div",{className:"space-y-3",children:o.remotes.map(R)})]}),o.repository&&e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:()=>y("repository"),className:"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors",children:[e.jsx("span",{children:a("registry.repository")}),e.jsx("svg",{className:`w-5 h-5 transform transition-transform ${w.repository?"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"})})]}),w.repository&&e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:[o.repository.url&&e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"URL:"})," ",e.jsx("a",{href:o.repository.url,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 hover:underline break-all",children:o.repository.url})]}),o.repository.source&&e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"Source:"})," ",o.repository.source]}),o.repository.subfolder&&e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"Subfolder:"})," ",o.repository.subfolder]}),o.repository.id&&e.jsxs("div",{children:[e.jsx("span",{className:"font-medium text-gray-700",children:"ID:"})," ",o.repository.id]})]})]}),F&&V&&z&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsx(ke,{onSubmit:g,onCancel:h,modalTitle:a("registry.installServer",{name:o.title||o.name}),formError:Q,initialData:N()})})]})};function is(s){switch(s.toLowerCase()){case"pypi":case"python":return"uvx";case"npm":case"node":return"npx";case"oci":case"docker":return"docker";default:return""}}function cs(s,p){const b=[p.identifier+(p.version?`@${p.version}`:"")],d=[];switch(p.packageArguments&&p.packageArguments.length>0&&p.packageArguments.forEach(m=>{if(m.isRequired||m.default||m.value){const i=`--${m.name}`,a=m.value||m.default||`\${${m.name.toUpperCase()}}`;d.push(i,a)}}),s.toLowerCase()){case"uvx":return[...b,...d];case"npx":return[...b,...d];case"docker":{const m=[];return p.environmentVariables&&p.environmentVariables.forEach(i=>{m.push("-e",`${i.name}`)}),["run","-i","--rm",...m,...b,...d]}default:return[...b,...d]}}const ds=({currentPage:s,hasNextPage:p,hasPreviousPage:b,onNextPage:d,onPreviousPage:m})=>e.jsxs("div",{className:"flex items-center justify-center space-x-2 my-6",children:[e.jsxs("button",{onClick:m,disabled:!b,className:`px-4 py-2 rounded transition-all duration-200 ${b?"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary":"bg-gray-100 text-gray-400 cursor-not-allowed"}`,children:[e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 inline-block mr-1",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z",clipRule:"evenodd"})}),"Prev"]}),e.jsxs("span",{className:"px-4 py-2 bg-blue-500 text-white rounded btn-primary",children:["Page ",s]}),e.jsxs("button",{onClick:d,disabled:!p,className:`px-4 py-2 rounded transition-all duration-200 ${p?"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary":"bg-gray-100 text-gray-400 cursor-not-allowed"}`,children:["Next",e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 inline-block ml-1",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z",clipRule:"evenodd"})})]})]}),ys=()=>{const{t:s}=ne(),p=He(),{serverName:b}=We(),{showToast:d}=Fe(),[m,i]=_e(),a=m.get("tab")==="registry"?"registry":"local",{servers:A,allServers:f,categories:o,loading:D,error:P,setError:U,searchServers:M,filterByCategory:H,filterByTag:I,selectedCategory:C,selectedTag:F,installServer:S,fetchServerByName:z,isServerInstalled:O,currentPage:V,totalPages:T,changePage:Q,serversPerPage:$,changeServersPerPage:w}=es(),{servers:q,allServers:k,loading:K,error:B,setError:E,searchServers:y,clearSearch:n,fetchServerByName:h,fetchServerVersions:g,currentPage:N,totalPages:W,hasNextPage:R,hasPreviousPage:X,changePage:c,goToNextPage:v,goToPreviousPage:u,serversPerPage:r,changeServersPerPage:l}=ss(),[G,se]=t.useState(null),[_,Y]=t.useState(null),[ee,re]=t.useState(""),[de,he]=t.useState(""),[ge,ce]=t.useState(!1),[we,Ce]=t.useState(new Set);t.useEffect(()=>{(async()=>{if(b)if(a==="registry"){const j=await h(b);j?Y(j):p("/market?tab=registry")}else{const j=await z(b);j?se(j):p("/market?tab=local")}else se(null),Y(null)})()},[b,a,z,h,p]);const Pe=x=>{const j=new URLSearchParams(m);j.set("tab",x),i(j),b&&p("/market?"+j.toString())},Ee=x=>{x.preventDefault(),a==="local"?M(ee):a==="registry"&&y(de)},Re=x=>{a==="local"&&H(x)},Ie=()=>{a==="local"?(re(""),H(""),I("")):a==="registry"&&(he(""),n())},pe=x=>{var j;if(a==="registry"){const ae=(j=x.server)==null?void 0:j.name;ae&&p(`/market/${encodeURIComponent(ae)}?tab=registry`)}else p(`/market/${x.name}?tab=local`)},fe=()=>p(`/market?tab=${a}`),Te=async(x,j)=>{try{ce(!0),await S(x,j)&&d(s("market.installSuccess",{serverName:x.display_name}),"success")}finally{ce(!1)}},Le=async(x,j)=>{try{ce(!0);const Z={name:xe(x.name),config:j},ae=await ve("/servers",Z);if(!ae.success){d((ae==null?void 0:ae.message)||s("server.addError"),"error");return}Ce(Ue=>new Set(Ue).add(x.name)),d(s("registry.installSuccess",{name:x.title||x.name}),"success")}catch(Z){d(s("registry.installError",{error:Z instanceof Error?Z.message:String(Z)}),"error")}finally{ce(!1)}},Ae=x=>{a==="local"?Q(x):c(x),window.scrollTo({top:0,behavior:"smooth"})},ze=x=>{const j=parseInt(x.target.value,10);a==="local"?w(j):l(j)};if(G)return e.jsx(as,{server:G,onBack:fe,onInstall:Te,installing:ge,isInstalled:O(G.name)});if(_)return e.jsx(os,{serverEntry:_,onBack:fe,onInstall:Le,installing:ge,isInstalled:we.has(_.server.name),fetchVersions:g});const L=a==="local",le=a==="registry",me=L?A:q,ue=L?f:k,$e=L?o:[],Be=L?D:K,ye=L?P:B,Ve=L?U:E,te=L?C:"",Me=L?F:"",oe=L?V:N,De=L?T:W,ie=L?$:r,be=[{id:"local",label:s("market.title"),sourceLabel:"MCPM",sourceUrl:"https://mcpm.sh"},{id:"registry",label:s("registry.title"),sourceLabel:s("registry.official"),sourceUrl:"https://registry.modelcontextprotocol.io"}];return e.jsxs("div",{children:[e.jsx("div",{className:"flex items-end justify-between gap-4 mb-6",children:e.jsxs("div",{children:[e.jsx("h1",{className:"hub-h1",children:s("nav.market")}),e.jsx("p",{className:"hub-sub",children:be.map(x=>x.label).join(" · ")})]})}),e.jsx("div",{className:"mb-5",children:e.jsx("div",{style:{borderBottom:"1px solid var(--hub-line)"},children:e.jsx("nav",{className:"flex -mb-px gap-1.5",children:be.map(x=>{const j=a===x.id;return e.jsxs("button",{onClick:()=>Pe(x.id),className:"py-2 px-3 transition-colors text-[14px]",style:{borderBottom:"2px solid "+(j?"var(--hub-ink)":"transparent"),color:j?"var(--hub-ink)":"var(--hub-ink-3)",fontWeight:j?500:400},children:[x.label,e.jsxs("a",{href:x.sourceUrl,target:"_blank",rel:"noopener noreferrer",className:"hub-mono ml-1.5",style:{fontSize:11,color:"var(--hub-ink-3)"},onClick:Z=>Z.stopPropagation(),children:["(",x.sourceLabel,")"]})]},x.id)})})})}),ye&&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(Je,{size:14,className:"flex-shrink-0"}),e.jsx("span",{className:"truncate text-[13px]",children:ye})]}),e.jsx("button",{className:"hub-icon-btn sm",onClick:()=>Ve(null),children:e.jsx(Xe,{size:13})})]}),(L||le)&&e.jsxs("form",{onSubmit:Ee,className:"hub-card flex items-center gap-2 px-3 mb-5",style:{padding:6},children:[e.jsx(Ye,{size:16,style:{color:"var(--hub-ink-3)",margin:"0 6px 0 6px"}}),e.jsx("input",{type:"text",value:le?de:ee,onChange:x=>{le?he(x.target.value):re(x.target.value)},placeholder:s(le?"registry.searchPlaceholder":"market.searchPlaceholder"),className:"flex-1 bg-transparent outline-none",style:{height:32,fontSize:14,color:"var(--hub-ink)"}}),e.jsx("button",{type:"submit",className:"hub-btn",children:s("common.search")}),(L&&(ee||te||Me)||le&&de)&&e.jsx("button",{type:"button",onClick:Ie,className:"hub-btn ghost",children:s("common.clear")})]}),e.jsxs("div",{className:L?"grid gap-5":"",style:L?{gridTemplateColumns:"180px 1fr"}:void 0,children:[L&&e.jsxs("div",{children:[e.jsx("h3",{className:"hub-sect mb-2",children:s("market.categories")}),e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("button",{onClick:()=>H(""),className:"flex items-center justify-between transition-colors text-[13px]",style:{padding:"6px 10px",borderRadius:6,background:te?"transparent":"var(--hub-surface)",color:te?"var(--hub-ink-2)":"var(--hub-ink)",border:"1px solid "+(te?"transparent":"var(--hub-line)")},children:[e.jsx("span",{children:s("common.all")}),e.jsx("span",{className:"hub-mono",style:{fontSize:11,color:"var(--hub-ink-3)"},children:f.length})]}),$e.map(x=>e.jsx("button",{onClick:()=>Re(x),className:"flex items-center justify-between transition-colors text-[13px]",style:{padding:"6px 10px",borderRadius:6,background:te===x?"var(--hub-surface)":"transparent",color:te===x?"var(--hub-ink)":"var(--hub-ink-2)",border:"1px solid "+(te===x?"var(--hub-line)":"transparent")},children:e.jsx("span",{className:"truncate",children:x})},x))]})]}),e.jsx("div",{children:Be?e.jsx("div",{className:"hub-card p-6 text-center",style:{color:"var(--hub-ink-3)"},children:s("app.loading")}):me.length===0?e.jsx("div",{className:"hub-card p-10 text-center",style:{color:"var(--hub-ink-3)"},children:s(L?"market.noServers":"registry.noServers")}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3",children:me.map((x,j)=>L?e.jsx(ts,{server:x,onClick:pe},j):e.jsx(ls,{serverEntry:x,onClick:pe},j))}),e.jsxs("div",{className:"flex items-center mt-4 text-[12px]",style:{color:"var(--hub-ink-3)"},children:[e.jsx("div",{className:"flex-[2]",children:L?s("market.showing",{from:(oe-1)*ie+1,to:Math.min(oe*ie,ue.length),total:ue.length}):s("registry.showing",{from:(oe-1)*ie+1,to:(oe-1)*ie+me.length,total:ue.length+(R?"+":"")})}),e.jsx("div",{className:"flex-[4] flex justify-center",children:le?e.jsx(ds,{currentPage:oe,hasNextPage:R,hasPreviousPage:X,onNextPage:v,onPreviousPage:u}):e.jsx(Ke,{currentPage:oe,totalPages:De,onPageChange:Ae})}),e.jsxs("div",{className:"flex-[2] flex items-center justify-end gap-2",children:[e.jsxs("label",{htmlFor:"perPage",children:[s(L?"market.perPage":"registry.perPage"),":"]}),e.jsxs("div",{className:"relative",children:[e.jsxs("select",{id:"perPage",value:ie,onChange:ze,className:"hub-input pr-7",style:{height:26,width:70,padding:"0 6px",fontSize:12},children:[e.jsx("option",{value:"6",children:"6"}),e.jsx("option",{value:"9",children:"9"}),e.jsx("option",{value:"12",children:"12"}),e.jsx("option",{value:"24",children:"24"})]}),e.jsx(Ze,{size:11,className:"absolute right-1.5 top-1/2 -translate-y-1/2 pointer-events-none",style:{color:"var(--hub-ink-3)"}})]})]})]})]})})]})]})};export{ys as default};
|
|
2
|
-
//# sourceMappingURL=MarketPage-
|
|
1
|
+
import{r as t,j as e,d as He,b as We,i as _e}from"./framework-vendor-CQFm9vKd.js";import{f as J,k as ve,u as je,j as Fe}from"./index-BbogfcdA.js";import{u as ne}from"./i18n-vendor-DVmjrzgW.js";import{g as Ne,a as ke,d as Oe,s as xe}from"./variableDetection-BVSe56ia.js";import{C as Se,$ as Qe,a5 as qe,a7 as Ge,l as Je,X as Xe,G as Ye,n as Ze}from"./icons-vendor-CkcU1LMA.js";import{P as Ke}from"./Pagination-BRqqU5Ct.js";import"./contextCost-CilWqGWT.js";const es=()=>{const{t:s}=ne(),[p,b]=t.useState([]),[d,m]=t.useState([]),[i,a]=t.useState([]),[A,f]=t.useState([]),[o,D]=t.useState(""),[P,U]=t.useState(""),[M,H]=t.useState(""),[I,C]=t.useState(!0),[F,S]=t.useState(null),[z,O]=t.useState(null),[V,T]=t.useState([]),[Q,$]=t.useState(1),[w,q]=t.useState(9),[k,K]=t.useState(1),B=t.useCallback(async()=>{try{C(!0);const r=await J("/market/servers");r&&r.success&&Array.isArray(r.data)?(m(r.data),E(r.data,Q)):(console.error("Invalid market servers data format",{data:r}),S(s("market.fetchError")))}catch(r){console.error("Error fetching market servers",{err:r}),S(r instanceof Error?r.message:String(r))}finally{C(!1)}},[s]),E=t.useCallback((r,l,G=w)=>{const se=r.length,_=Math.ceil(se/G);K(_);const Y=Math.max(1,Math.min(l,_));Y!==l&&$(Y);const ee=(Y-1)*G,re=r.slice(ee,ee+G);b(re)},[w]),y=t.useCallback(r=>{$(r),E(d,r,w)},[d,E,w]),n=t.useCallback(async()=>{try{const r=await J("/market/categories");r&&r.success&&Array.isArray(r.data)?a(r.data):console.error("Invalid categories data format",{data:r})}catch(r){console.error("Error fetching categories",{err:r})}},[]),h=t.useCallback(async()=>{try{const r=await J("/market/tags");r&&r.success&&Array.isArray(r.data)?f(r.data):console.error("Invalid tags data format",{data:r})}catch(r){console.error("Error fetching tags",{err:r})}},[]),g=t.useCallback(async r=>{try{C(!0);const l=await J(`/market/servers/${r}`);return l&&l.success&&l.data?(O(l.data),l.data):(console.error("Invalid market server data format",{name:r,data:l}),S(s("market.serverNotFound")),null)}catch(l){return console.error("Error fetching market server",{name:r,err:l}),S(l instanceof Error?l.message:String(l)),null}finally{C(!1)}},[s]),N=t.useCallback(async r=>{try{if(C(!0),H(r),!r.trim()){B();return}const l=await J(`/market/servers/search?query=${encodeURIComponent(r)}`);l&&l.success&&Array.isArray(l.data)?(m(l.data),$(1),E(l.data,1)):(console.error("Invalid market search results format",{query:r,data:l}),S(s("market.searchError")))}catch(l){console.error("Error searching market servers",{query:r,err:l}),S(l instanceof Error?l.message:String(l))}finally{C(!1)}},[s,d,E,B]),W=t.useCallback(async r=>{try{if(C(!0),D(r),U(""),!r){B();return}const l=await J(`/market/categories/${encodeURIComponent(r)}`);l&&l.success&&Array.isArray(l.data)?(m(l.data),$(1),E(l.data,1)):(console.error("Invalid market category filter results format",{category:r,data:l}),S(s("market.filterError")))}catch(l){console.error("Error filtering market servers by category",{category:r,err:l}),S(l instanceof Error?l.message:String(l))}finally{C(!1)}},[s,B,E]),R=t.useCallback(async r=>{try{if(C(!0),U(r),D(""),!r){B();return}const l=await J(`/market/tags/${encodeURIComponent(r)}`);l&&l.success&&Array.isArray(l.data)?(m(l.data),$(1),E(l.data,1)):(console.error("Invalid market tag filter results format",{tag:r,data:l}),S(s("market.tagFilterError")))}catch(l){console.error("Error filtering market servers by tag",{tag:r,err:l}),S(l instanceof Error?l.message:String(l))}finally{C(!1)}},[s,B,E]),X=t.useCallback(async()=>{try{const r=await J("/servers");if(r&&r.success&&Array.isArray(r.data)){const l=r.data.map(G=>G.name);T(l)}}catch(r){console.error("Error fetching installed servers",{err:r})}},[]),c=t.useCallback(r=>V.includes(r),[V]),v=t.useCallback(async(r,l)=>{var G,se;try{const _=(G=r.installations)!=null&&G.npm?"npm":Object.keys(r.installations||{}).length>0?Object.keys(r.installations)[0]:null;if(!_||!((se=r.installations)!=null&&se[_]))return S(s("market.noInstallationMethod")),!1;const Y=r.installations[_],ee={name:r.name,config:l.type==="stdio"?{command:l.command||Y.command||"",args:l.args||Y.args||[],env:{...Y.env,...l.env}}:l},re=await ve("/servers",ee);if(!re.success)throw new Error(re.message||"Failed to install server");return await X(),!0}catch(_){return console.error("Error installing market server",{serverName:r.name,err:_}),S(_ instanceof Error?_.message:String(_)),!1}},[s,X]),u=t.useCallback(r=>{q(r),$(1),E(d,1,r)},[d,E]);return t.useEffect(()=>{B(),n(),h(),X()},[B,n,h,X]),{servers:p,allServers:d,categories:i,tags:A,selectedCategory:o,selectedTag:P,searchQuery:M,loading:I,error:F,setError:S,currentServer:z,fetchMarketServers:B,fetchServerByName:g,searchServers:N,filterByCategory:W,filterByTag:R,installServer:v,currentPage:Q,totalPages:k,serversPerPage:w,changePage:y,changeServersPerPage:u,isServerInstalled:c}},ss=()=>{const{t:s}=ne(),[p,b]=t.useState([]),[d,m]=t.useState([]),[i,a]=t.useState(!0),[A,f]=t.useState(null),[o,D]=t.useState(""),[P,U]=t.useState(1),[M,H]=t.useState(9),[I,C]=t.useState(null),[F,S]=t.useState(!1),[z,O]=t.useState([]),[V]=t.useState(1),T=t.useCallback(async(n,h)=>{try{a(!0),f(null);const g=new URLSearchParams;g.append("limit",M.toString()),n&&g.append("cursor",n);const N=h!==void 0?h:o;N.trim()&&g.append("search",N.trim());const W=await J(`/registry/servers?${g.toString()}`);if(W&&W.success&&W.data){const R=W.data;if(R.servers&&Array.isArray(R.servers)){b(R.servers);const X=R.metadata.count===M&&!!R.metadata.nextCursor;S(X),C(R.metadata.nextCursor||null),m(n?c=>[...c,...R.servers]:R.servers)}else console.error("Invalid registry servers data format",{data:R}),f(s("registry.fetchError"))}else f(s("registry.fetchError"))}catch(g){console.error("Error fetching registry servers",{cursor:n,search:h,err:g});const N=g instanceof Error?g.message:String(g);f(N)}finally{a(!1)}},[s,M]),Q=t.useCallback(async()=>{if(!F||!I)return;const n=z[z.length-1]||"";O(h=>[...h,n]),U(h=>h+1),await T(I,o)},[F,I,z,o,T]),$=t.useCallback(async()=>{if(P<=1)return;const n=[...z];n.pop();const h=n[n.length-1];O(n),U(g=>g-1),await T(h||void 0,o)},[P,z,o,T]),w=t.useCallback(async n=>{n!==P&&(n>P&&F?await Q():n<P&&P>1&&await $())},[P,F,Q,$]),q=t.useCallback(async n=>{H(n),U(1),O([]),m([]),await T(void 0,o)},[o,T]),k=t.useCallback(async n=>{try{a(!0),f(null);const h=encodeURIComponent(n),g=await J(`/registry/servers/versions?serverName=${h}`);if(g&&g.success&&g.data){const N=g.data;return N.servers&&Array.isArray(N.servers)&&N.servers.length>0?N.servers[0]:(console.error("Invalid registry server data format",{serverName:n,data:N}),f(s("registry.serverNotFound")),null)}else return f(s("registry.serverNotFound")),null}catch(h){console.error("Error fetching registry server",{serverName:n,err:h});const g=h instanceof Error?h.message:String(h);return f(g),null}finally{a(!1)}},[s]),K=t.useCallback(async n=>{try{f(null);const h=encodeURIComponent(n),g=await J(`/registry/servers/versions?serverName=${h}`);if(g&&g.success&&g.data){const N=g.data;return N.servers&&Array.isArray(N.servers)?N.servers:(console.error("Invalid registry server versions data format",{serverName:n,data:N}),[])}else return[]}catch(h){console.error("Error fetching versions for registry server",{serverName:n,err:h});const g=h instanceof Error?h.message:String(h);return f(g),[]}},[]),B=t.useCallback(async(n,h)=>{try{f(null);const g=encodeURIComponent(n),N=encodeURIComponent(h),W=await J(`/registry/servers/version?serverName=${g}&version=${N}`);if(W&&W.success&&W.data){const R=W.data;return R&&R.server?R:(console.error("Invalid registry server version data format",{serverName:n,version:h,data:R}),null)}else return null}catch(g){console.error("Error fetching specific registry server version",{serverName:n,version:h,err:g});const N=g instanceof Error?g.message:String(g);return f(N),null}},[]),E=t.useCallback(async n=>{console.log("Searching registry servers",{query:n}),D(n),U(1),O([]),m([]),await T(void 0,n)},[T]),y=t.useCallback(async()=>{D(""),U(1),O([]),m([]),await T(void 0,"")},[T]);return t.useEffect(()=>{T(void 0,o)},[]),{servers:p,allServers:d,loading:i,error:A,setError:f,searchQuery:o,searchServers:E,clearSearch:y,fetchServerByName:k,fetchServerVersions:K,fetchServerVersion:B,currentPage:P,totalPages:V,hasNextPage:F,hasPreviousPage:P>1,changePage:w,goToNextPage:Q,goToPreviousPage:$,serversPerPage:M,changeServersPerPage:q}},rs=s=>s.split(" ").map(p=>p.charAt(0)).join("").toUpperCase().slice(0,2),ts=({server:s,onClick:p})=>{var i,a,A;const{t:b}=ne(),d=(s.tags||[]).slice(0,3),m=(i=s.categories)==null?void 0:i[0];return e.jsxs("div",{className:"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden",onClick:()=>p(s),onMouseEnter:f=>f.currentTarget.style.borderColor="var(--hub-ink-2)",onMouseLeave:f=>f.currentTarget.style.borderColor="var(--hub-line)",children:[e.jsxs("div",{className:"p-3.5 flex-1 flex flex-col gap-2.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"hub-mono",style:{width:28,height:28,borderRadius:7,background:"var(--hub-ink)",color:"var(--hub-bg)",display:"grid",placeItems:"center",fontWeight:600,fontSize:13,flexShrink:0},children:rs(s.display_name||s.name)[0]||"?"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"truncate",style:{fontSize:14,fontWeight:500,letterSpacing:"-0.01em"},children:s.display_name}),s.is_official&&e.jsxs("span",{className:"inline-flex items-center gap-0.5",style:{fontSize:10,color:"var(--hub-accent)",background:"var(--hub-accent-soft)",padding:"0 5px",height:16,borderRadius:3,fontWeight:500},children:[e.jsx(Se,{size:9,strokeWidth:2.5}),b("market.official")]})]}),e.jsxs("div",{className:"hub-mono truncate",style:{fontSize:11,color:"var(--hub-ink-3)"},children:["@",((a=s.author)==null?void 0:a.name)||b("market.unknown")]})]})]}),e.jsx("div",{className:"flex-1 line-clamp-2",style:{fontSize:12.5,color:"var(--hub-ink-2)",lineHeight:1.5},children:s.description}),d.length>0&&e.jsx("div",{className:"flex gap-1 flex-wrap",children:d.map(f=>e.jsxs("span",{className:"hub-tag",style:{background:"oklch(0.96 0.04 145)",color:"oklch(0.4 0.1 145)",border:0},children:["#",f]},f))})]}),e.jsx("div",{className:"flex items-center justify-between px-3.5 py-2",style:{borderTop:"1px solid var(--hub-line-2)",background:"var(--hub-bg-2)"},children:e.jsxs("div",{className:"hub-mono flex items-center gap-3",style:{fontSize:11.5,color:"var(--hub-ink-3)"},children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Qe,{size:11}),((A=s.tools)==null?void 0:A.length)??0," ",b("server.tools").toLowerCase()]}),m&&e.jsx("span",{className:"truncate",children:m})]})})]})},as=({server:s,onBack:p,onInstall:b,installing:d=!1,isInstalled:m=!1})=>{var k,K,B,E;const{t:i}=ne(),{auth:a}=je(),A=Ne({type:"stdio"},(k=a.user)==null?void 0:k.isAdmin),[f,o]=t.useState(!1),[D,P]=t.useState(null),[U,M]=t.useState(!1),[H,I]=t.useState(null),[C,F]=t.useState([]),S=()=>m?{className:"bg-green-600 cursor-default px-4 py-2 rounded text-sm font-medium text-white",disabled:!0,text:i("market.installed")}:d?{className:"bg-gray-400 cursor-not-allowed px-4 py-2 rounded text-sm font-medium text-white",disabled:!0,text:i("market.installing")}:{className:`hub-btn primary ${A?"opacity-50 cursor-not-allowed":""}`,disabled:!!A,text:i("market.install")},z=()=>{o(!f),P(null),M(!1),I(null)},O=async()=>{H&&(await V(H),M(!1),I(null))},V=async y=>{try{P(null),b(s,y.config),o(!1)}catch(n){console.error("Error installing server:",n),P(i("errors.serverInstall"))}},T=()=>{!m&&!A&&z()},Q=()=>{if(!s.installations)return;if(s.installations.npm)return s.installations.npm;if(s.installations.uvx)return s.installations.uvx;if(s.installations.default)return s.installations.default;const y=Object.keys(s.installations);if(y.length>0)return s.installations[y[0]]},$=async y=>{try{const n=Oe(y);n.length>0?(F(n),I(y),M(!0)):await V(y)}catch(n){console.error("Error processing server installation:",n),P(i("errors.serverInstall"))}},w=S(),q=Q();return e.jsxs("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-md p-6",children:[e.jsx("div",{className:"mb-4",children:e.jsxs("button",{onClick:p,className:"text-gray-600 hover:text-gray-900 flex items-center",children:[e.jsx("svg",{className:"h-5 w-5 mr-1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z",clipRule:"evenodd"})}),i("market.backToList")]})}),e.jsxs("div",{className:"flex justify-between items-start mb-4",children:[e.jsx("div",{children:e.jsxs("h2",{className:"text-2xl font-bold text-gray-900 flex items-center flex-wrap",children:[s.display_name,e.jsxs("span",{className:"text-sm font-normal text-gray-500 ml-2",children:["(",s.name,")"]}),e.jsxs("span",{className:"text-sm font-normal text-gray-600 ml-4",children:[i("market.author"),": ",((K=s.author)==null?void 0:K.name)||i("market.unknown")," •"," ",i("market.license"),": ",s.license," •",e.jsx("a",{href:s.repository.url,target:"_blank",rel:"noopener noreferrer",className:"text-blue-500 hover:underline ml-1",children:i("market.repository")})]})]})}),e.jsxs("div",{className:"flex items-center",children:[s.is_official&&e.jsx("span",{className:"bg-blue-100 text-blue-800 dark:text-blue-300 dark:bg-blue-900/40 dark:text-blue-300 text-sm font-normal px-4 py-2 rounded mr-2 flex items-center label-primary",children:i("market.official")}),e.jsx("button",{onClick:T,disabled:w.disabled,className:w.className,children:w.text})]})]}),A&&e.jsx("p",{role:"status",className:"text-sm text-amber-700 dark:text-amber-300 mb-4",children:i(A)}),e.jsx("p",{className:"text-gray-700 mb-6",children:s.description}),e.jsxs("div",{className:"mb-6",children:[e.jsxs("h3",{className:"text-lg font-semibold mb-3",children:[i("market.categories")," & ",i("market.tags")]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[(B=s.categories)==null?void 0:B.map((y,n)=>e.jsx("span",{className:"bg-gray-100 dark:bg-gray-800 text-gray-800 px-3 py-1 rounded",children:y},`cat-${n}`)),s.tags&&s.tags.map((y,n)=>e.jsxs("span",{className:"bg-gray-100 dark:bg-gray-800 text-green-700 dark:text-green-300 px-2 py-1 rounded text-sm",children:["#",y]},`tag-${n}`))]})]}),s.arguments&&Object.keys(s.arguments).length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:i("market.arguments")}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-gray-200 dark:divide-gray-700",children:[e.jsx("thead",{className:"bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.argumentName")}),e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.description")}),e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.required")}),e.jsx("th",{className:"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap",children:i("market.example")})]})}),e.jsx("tbody",{className:"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700",children:Object.entries(s.arguments).map(([y,n],h)=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900",children:y}),e.jsx("td",{className:"px-6 py-4 text-sm text-gray-500",children:n.description}),e.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500",children:n.required?e.jsx("span",{className:"text-green-600",children:"✓"}):e.jsx("span",{className:"text-gray-600",children:"✗"})}),e.jsx("td",{className:"px-6 py-4 whitespace-nowrap text-sm text-gray-500",children:e.jsx("code",{className:"bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded",children:n.example})})]},h))})]})})]}),e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:i("market.tools")}),e.jsx("div",{className:"space-y-4",children:(E=s.tools)==null?void 0:E.map((y,n)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded p-4",children:[e.jsxs("h4",{className:"font-medium mb-2",children:[y.name,e.jsx("button",{type:"button",onClick:()=>{const h=document.getElementById(`schema-${n}`);h&&h.classList.toggle("hidden")},className:"text-sm text-blue-500 font-normal hover:underline focus:outline-none ml-2",children:i("market.viewSchema")})]}),e.jsx("p",{className:"text-gray-600 mb-2",children:y.description}),e.jsx("div",{className:"mt-2",children:e.jsx("pre",{id:`schema-${n}`,className:"hidden bg-gray-50 dark:bg-gray-800 p-3 rounded text-sm overflow-auto mt-2",children:JSON.stringify(y.inputSchema,null,2)})})]},n))})]}),s.examples&&s.examples.length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h3",{className:"text-lg font-semibold mb-3",children:i("market.examples")}),e.jsx("div",{className:"space-y-4",children:s.examples.map((y,n)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded p-4",children:[e.jsx("h4",{className:"font-medium mb-2",children:y.title}),e.jsx("p",{className:"text-gray-600 mb-2",children:y.description}),e.jsx("pre",{className:"bg-gray-50 dark:bg-gray-800 p-3 rounded text-sm overflow-auto",children:y.prompt})]},n))})]}),e.jsx("div",{className:"mt-6 flex justify-end",children:e.jsx("button",{onClick:T,disabled:w.disabled,className:w.className,children:w.text})}),f&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsx(ke,{onSubmit:$,onCancel:z,modalTitle:i("market.installServer",{name:s.display_name}),formError:D,initialData:{name:s.name,status:"disconnected",config:q?{command:q.command||"",args:q.args||[],env:q.env||{}}:void 0}})}),U&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-[60] flex items-center justify-center p-4",children:e.jsxs("div",{className:"hub-card p-6 w-full max-w-md",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:i("server.confirmVariables")}),e.jsx("p",{className:"text-gray-600 mb-4",children:i("server.variablesDetected")}),e.jsx("div",{className:"bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-700/60 rounded p-3 mb-4",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:"flex-shrink-0",children:e.jsx("svg",{className:"h-5 w-5 text-yellow-400",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})})}),e.jsxs("div",{className:"ml-3",children:[e.jsxs("h4",{className:"text-sm font-medium text-yellow-800 dark:text-yellow-300",children:[i("server.detectedVariables"),":"]}),e.jsx("ul",{className:"mt-1 text-sm text-yellow-700 dark:text-yellow-300",children:C.map((y,n)=>e.jsxs("li",{className:"font-mono",children:["$",`{${y}}`]},n))})]})]})}),e.jsx("p",{className:"text-gray-600 text-sm mb-6",children:i("market.confirmVariablesMessage")}),e.jsxs("div",{className:"flex justify-end space-x-3",children:[e.jsx("button",{onClick:()=>{M(!1),I(null)},className:"hub-btn",children:i("common.cancel")}),e.jsx("button",{onClick:O,className:"hub-btn primary",children:i("market.confirmAndInstall")})]})]})})]})},ns=s=>{if(!s)return"";try{const p=new Date(s),b=p.getFullYear(),d=(p.getMonth()+1).toString().padStart(2,"0"),m=p.getDate().toString().padStart(2,"0");return`${b}/${d}/${m}`}catch{return""}},ls=({serverEntry:s,onClick:p})=>{var M,H;const{t:b}=ne(),{server:d,_meta:m}=s,i=m==null?void 0:m["io.modelcontextprotocol.registry/official"],a=i==null?void 0:i.isLatest,A=i==null?void 0:i.publishedAt,f=i==null?void 0:i.updatedAt,o=((M=d.packages)==null?void 0:M.length)||0,D=((H=d.remotes)==null?void 0:H.length)||0,P=d.description?d.description.length<=150?d.description:d.description.slice(0,150)+"...":b("registry.noDescription"),U=d.icons&&d.icons.length>0?d.icons.find(C=>!C.theme||C.theme==="light")||d.icons[0]:null;return e.jsxs("div",{className:"hub-card flex flex-col cursor-pointer transition-colors h-full overflow-hidden",onClick:()=>p(s),onMouseEnter:I=>I.currentTarget.style.borderColor="var(--hub-ink-2)",onMouseLeave:I=>I.currentTarget.style.borderColor="var(--hub-line)",children:[e.jsxs("div",{className:"p-3.5 flex-1 flex flex-col gap-2.5",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[U?e.jsx("img",{src:U.src,alt:d.title||d.name,className:"rounded-md object-cover flex-shrink-0",style:{width:28,height:28},onError:I=>{I.currentTarget.style.display="none"}}):e.jsx("div",{className:"hub-mono flex-shrink-0",style:{width:28,height:28,borderRadius:7,background:"var(--hub-ink)",color:"var(--hub-bg)",display:"grid",placeItems:"center",fontWeight:600,fontSize:13},children:d.name.charAt(0).toUpperCase()}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"truncate",style:{fontSize:14,fontWeight:500,letterSpacing:"-0.01em"},children:d.title||d.name}),a&&e.jsxs("span",{className:"inline-flex items-center gap-0.5 flex-shrink-0",style:{fontSize:10,color:"oklch(0.4 0.13 145)",background:"oklch(0.95 0.05 145)",padding:"0 5px",height:16,borderRadius:3,fontWeight:500},children:[e.jsx(Se,{size:9,strokeWidth:2.5}),b("registry.latest")]})]}),e.jsxs("div",{className:"hub-mono truncate",style:{fontSize:11,color:"var(--hub-ink-3)"},children:[d.name," · v",d.version]})]})]}),e.jsx("div",{className:"flex-1 line-clamp-2",style:{fontSize:12.5,color:"var(--hub-ink-2)",lineHeight:1.5},children:P})]}),e.jsxs("div",{className:"flex items-center justify-between px-3.5 py-2",style:{borderTop:"1px solid var(--hub-line-2)",background:"var(--hub-bg-2)"},children:[e.jsxs("div",{className:"hub-mono flex items-center gap-3",style:{fontSize:11.5,color:"var(--hub-ink-3)"},children:[o>0&&e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(qe,{size:11}),o]}),D>0&&e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(Ge,{size:11}),D]}),(A||f)&&e.jsx("span",{children:ns(f||A)})]}),e.jsxs("span",{className:"hub-mono",style:{fontSize:11,color:"var(--hub-accent)"},children:[b("registry.viewDetails")," →"]})]})]})},os=({serverEntry:s,onBack:p,onInstall:b,installing:d=!1,isInstalled:m=!1,fetchVersions:i})=>{var X;const{t:a}=ne(),{auth:A}=je(),f=Ne({type:"stdio"},(X=A.user)==null?void 0:X.isAdmin),{server:o,_meta:D}=s,[P,U]=t.useState(o.version),[M,H]=t.useState([]),[I,C]=t.useState(!1),[F,S]=t.useState(!1),[z,O]=t.useState(null),[V,T]=t.useState(null),[Q,$]=t.useState(null),[w,q]=t.useState({packages:!0,remotes:!0,repository:!0}),k=D==null?void 0:D["io.modelcontextprotocol.registry/official"];t.useEffect(()=>{(async()=>{if(i){C(!0);try{const v=await i(o.name);H(v)}catch(v){console.error("Failed to load versions:",v)}finally{C(!1)}}})()},[o.name,i]);const B=o.icons&&o.icons.length>0?o.icons.find(v=>!v.theme||v.theme==="light")||o.icons[0]:null,E=c=>{if(!c)return"";try{return new Date(c).toLocaleDateString()}catch{return""}},y=c=>{q(v=>({...v,[c]:!v[c]}))},n=(c,v)=>{c==="package"&&f||(O(c),T(v),$(null),S(!0))},h=()=>{S(!1),$(null)},g=async c=>{try{if(!b||!V||!z)return;$(null);const v=c.config;b(o,v),S(!1)}catch(v){console.error("Error installing server:",v),$(a("errors.serverInstall"))}},N=()=>{if(!V||!z)return null;if(console.log("Building initial form data for:",V),z==="package"&&"identifier"in V){const c=V,v={};c.environmentVariables&&c.environmentVariables.forEach(r=>{v[r.name]=r.default||""});const u=is(c.registryType);return{name:xe(o.name),status:"disconnected",config:{type:"stdio",command:u,args:cs(u,c),env:Object.keys(v).length>0?v:void 0}}}else if(z==="remote"&&"url"in V){const c=V,v={};c.headers&&c.headers.forEach(r=>{v[r.name]=r.default||r.value||""});const u=c.type==="sse"?"sse":"streamable-http";return{name:xe(o.name),status:"disconnected",config:{type:u,url:c.url,headers:Object.keys(v).length>0?v:void 0}}}return null},W=(c,v)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4 mb-3 hover:border-blue-400 transition-colors",children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium text-gray-900",children:c.identifier}),c.version&&e.jsxs("p",{className:"text-sm text-gray-500",children:["Version: ",c.version]}),c.runtimeHint&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:c.runtimeHint})]}),e.jsx("button",{onClick:()=>n("package",c),disabled:m||d||!!f,className:`px-4 py-2 rounded text-sm font-medium transition-colors ${m?"hub-btn cursor-default":d||f?"hub-btn cursor-not-allowed opacity-50":"hub-btn primary"}`,children:a(m?"registry.installed":d?"registry.installing":"registry.install")})]}),f&&e.jsx("p",{role:"status",className:"text-sm text-amber-700 dark:text-amber-300 mb-3",children:a(f)}),c.registryType&&e.jsxs("div",{className:"text-sm text-gray-600 mb-2",children:[e.jsx("span",{className:"font-medium",children:"Registry:"})," ",c.registryType]}),c.transport&&e.jsxs("div",{className:"text-sm text-gray-600 mb-2",children:[e.jsx("span",{className:"font-medium",children:"Transport:"})," ",c.transport.type,c.transport.url&&e.jsxs("span",{className:"ml-2 text-gray-500",children:["(",c.transport.url,")"]})]}),c.environmentVariables&&c.environmentVariables.length>0&&e.jsxs("div",{className:"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3",children:[e.jsxs("h5",{className:"text-sm font-medium text-gray-700 mb-2",children:[a("registry.environmentVariables"),":"]}),e.jsx("div",{className:"space-y-2",children:c.environmentVariables.map((u,r)=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"flex items-start",children:[e.jsx("span",{className:"font-mono text-gray-900 font-medium",children:u.name}),u.isRequired&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800",children:a("common.required")}),u.isSecret&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800",children:a("common.secret")})]}),u.description&&e.jsx("p",{className:"text-gray-600 mt-1",children:u.description}),u.default&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.default"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.default})]})]},r))})]}),c.packageArguments&&c.packageArguments.length>0&&e.jsxs("div",{className:"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3",children:[e.jsxs("h5",{className:"text-sm font-medium text-gray-700 mb-2",children:[a("registry.packageArguments"),":"]}),e.jsx("div",{className:"space-y-2",children:c.packageArguments.map((u,r)=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"flex items-start",children:[e.jsx("span",{className:"font-mono text-gray-900 font-medium",children:u.name}),u.isRequired&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800",children:a("common.required")}),u.isSecret&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800",children:a("common.secret")}),u.isRepeated&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300",children:a("common.repeated")})]}),u.description&&e.jsx("p",{className:"text-gray-600 mt-1",children:u.description}),u.type&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.type"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.type})]}),u.default&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.default"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.default})]}),u.value&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.value"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.value})]}),u.valueHint&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.valueHint"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.valueHint})]}),u.choices&&u.choices.length>0&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.choices"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.choices.join(", ")})]})]},r))})]})]},v),R=(c,v)=>e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4 mb-3 hover:border-blue-400 transition-colors",children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium text-gray-900",children:c.type}),e.jsx("p",{className:"text-sm text-gray-600 mt-1 break-all",children:c.url})]}),e.jsx("button",{onClick:()=>n("remote",c),disabled:m||d,className:`px-4 py-2 rounded text-sm font-medium transition-colors ${m?"hub-btn cursor-default":d?"hub-btn cursor-not-allowed opacity-50":"hub-btn primary"}`,children:a(m?"registry.installed":d?"registry.installing":"registry.install")})]}),c.headers&&c.headers.length>0&&e.jsxs("div",{className:"mt-3 border-t border-gray-200 dark:border-gray-700 pt-3",children:[e.jsxs("h5",{className:"text-sm font-medium text-gray-700 mb-2",children:[a("registry.headers"),":"]}),e.jsx("div",{className:"space-y-2",children:c.headers.map((u,r)=>e.jsxs("div",{className:"text-sm",children:[e.jsxs("div",{className:"flex items-start",children:[e.jsx("span",{className:"font-mono text-gray-900 font-medium",children:u.name}),u.isRequired&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800",children:a("common.required")}),u.isSecret&&e.jsx("span",{className:"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800",children:a("common.secret")})]}),u.description&&e.jsx("p",{className:"text-gray-600 mt-1",children:u.description}),u.value&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.value"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.value})]}),u.default&&e.jsxs("p",{className:"text-gray-500 mt-1",children:[e.jsxs("span",{className:"font-medium",children:[a("common.default"),":"]})," ",e.jsx("span",{className:"font-mono",children:u.default})]})]},r))})]})]},v);return e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:p,className:"flex items-center text-blue-600 hover:text-blue-800 mb-4 transition-colors",children:[e.jsx("svg",{className:"w-5 h-5 mr-2",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 19l-7-7 7-7"})}),a("registry.backToList")]}),e.jsxs("div",{className:"flex items-start space-x-4",children:[B?e.jsx("img",{src:B.src,alt:o.title,className:"w-20 h-20 rounded-lg object-cover flex-shrink-0",onError:c=>{c.currentTarget.style.display="none"}}):e.jsx("div",{className:"w-20 h-20 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center text-white text-3xl font-semibold flex-shrink-0",children:"M"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h1",{className:"text-3xl font-bold text-gray-900 mb-2",children:o.name}),e.jsxs("div",{className:"flex flex-wrap gap-2 mb-3",children:[(k==null?void 0:k.isLatest)&&e.jsx("span",{className:"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800",children:a("registry.latest")}),e.jsxs("span",{className:"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300",children:["v",o.version]}),(k==null?void 0:k.status)&&e.jsx("span",{className:"inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-gray-100 dark:bg-gray-800 text-gray-800",children:k.status}),e.jsxs("span",{className:"flex flex-wrap items-center gap-4 text-sm text-gray-600",children:[(k==null?void 0:k.publishedAt)&&e.jsxs("div",{children:[e.jsxs("span",{className:"font-medium",children:[a("registry.published"),":"]})," ",E(k.publishedAt)]}),(k==null?void 0:k.updatedAt)&&e.jsxs("div",{children:[e.jsxs("span",{className:"font-medium",children:[a("registry.updated"),":"]})," ",E(k.updatedAt)]})]})]})]})]})]}),e.jsxs("div",{className:"mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900 mb-3",children:a("registry.description")}),e.jsx("p",{className:"text-gray-700 leading-relaxed whitespace-pre-wrap",children:o.description})]}),o.websiteUrl&&e.jsxs("div",{className:"mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900 mb-3",children:a("registry.website")}),e.jsx("a",{href:o.websiteUrl,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 hover:underline",children:o.websiteUrl})]}),o.packages&&o.packages.length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:()=>y("packages"),className:"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors",children:[e.jsxs("span",{children:[a("registry.packages")," (",o.packages.length,")"]}),e.jsx("svg",{className:`w-5 h-5 transform transition-transform ${w.packages?"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"})})]}),w.packages&&e.jsx("div",{className:"space-y-3",children:o.packages.map(W)})]}),o.remotes&&o.remotes.length>0&&e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:()=>y("remotes"),className:"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors",children:[e.jsxs("span",{children:[a("registry.remotes")," (",o.remotes.length,")"]}),e.jsx("svg",{className:`w-5 h-5 transform transition-transform ${w.remotes?"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"})})]}),w.remotes&&e.jsx("div",{className:"space-y-3",children:o.remotes.map(R)})]}),o.repository&&e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{onClick:()=>y("repository"),className:"flex items-center justify-between w-full text-xl font-semibold text-gray-900 mb-3 hover:text-blue-600 transition-colors",children:[e.jsx("span",{children:a("registry.repository")}),e.jsx("svg",{className:`w-5 h-5 transform transition-transform ${w.repository?"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"})})]}),w.repository&&e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4",children:[o.repository.url&&e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"URL:"})," ",e.jsx("a",{href:o.repository.url,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:text-blue-800 hover:underline break-all",children:o.repository.url})]}),o.repository.source&&e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"Source:"})," ",o.repository.source]}),o.repository.subfolder&&e.jsxs("div",{className:"mb-2",children:[e.jsx("span",{className:"font-medium text-gray-700",children:"Subfolder:"})," ",o.repository.subfolder]}),o.repository.id&&e.jsxs("div",{children:[e.jsx("span",{className:"font-medium text-gray-700",children:"ID:"})," ",o.repository.id]})]})]}),F&&V&&z&&e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsx(ke,{onSubmit:g,onCancel:h,modalTitle:a("registry.installServer",{name:o.title||o.name}),formError:Q,initialData:N()})})]})};function is(s){switch(s.toLowerCase()){case"pypi":case"python":return"uvx";case"npm":case"node":return"npx";case"oci":case"docker":return"docker";default:return""}}function cs(s,p){const b=[p.identifier+(p.version?`@${p.version}`:"")],d=[];switch(p.packageArguments&&p.packageArguments.length>0&&p.packageArguments.forEach(m=>{if(m.isRequired||m.default||m.value){const i=`--${m.name}`,a=m.value||m.default||`\${${m.name.toUpperCase()}}`;d.push(i,a)}}),s.toLowerCase()){case"uvx":return[...b,...d];case"npx":return[...b,...d];case"docker":{const m=[];return p.environmentVariables&&p.environmentVariables.forEach(i=>{m.push("-e",`${i.name}`)}),["run","-i","--rm",...m,...b,...d]}default:return[...b,...d]}}const ds=({currentPage:s,hasNextPage:p,hasPreviousPage:b,onNextPage:d,onPreviousPage:m})=>e.jsxs("div",{className:"flex items-center justify-center space-x-2 my-6",children:[e.jsxs("button",{onClick:m,disabled:!b,className:`px-4 py-2 rounded transition-all duration-200 ${b?"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary":"bg-gray-100 text-gray-400 cursor-not-allowed"}`,children:[e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 inline-block mr-1",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z",clipRule:"evenodd"})}),"Prev"]}),e.jsxs("span",{className:"px-4 py-2 bg-blue-500 text-white rounded btn-primary",children:["Page ",s]}),e.jsxs("button",{onClick:d,disabled:!p,className:`px-4 py-2 rounded transition-all duration-200 ${p?"bg-gray-200 hover:bg-gray-300 text-gray-700 btn-secondary":"bg-gray-100 text-gray-400 cursor-not-allowed"}`,children:["Next",e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 inline-block ml-1",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z",clipRule:"evenodd"})})]})]}),ys=()=>{const{t:s}=ne(),p=He(),{serverName:b}=We(),{showToast:d}=Fe(),[m,i]=_e(),a=m.get("tab")==="registry"?"registry":"local",{servers:A,allServers:f,categories:o,loading:D,error:P,setError:U,searchServers:M,filterByCategory:H,filterByTag:I,selectedCategory:C,selectedTag:F,installServer:S,fetchServerByName:z,isServerInstalled:O,currentPage:V,totalPages:T,changePage:Q,serversPerPage:$,changeServersPerPage:w}=es(),{servers:q,allServers:k,loading:K,error:B,setError:E,searchServers:y,clearSearch:n,fetchServerByName:h,fetchServerVersions:g,currentPage:N,totalPages:W,hasNextPage:R,hasPreviousPage:X,changePage:c,goToNextPage:v,goToPreviousPage:u,serversPerPage:r,changeServersPerPage:l}=ss(),[G,se]=t.useState(null),[_,Y]=t.useState(null),[ee,re]=t.useState(""),[de,he]=t.useState(""),[ge,ce]=t.useState(!1),[we,Ce]=t.useState(new Set);t.useEffect(()=>{(async()=>{if(b)if(a==="registry"){const j=await h(b);j?Y(j):p("/market?tab=registry")}else{const j=await z(b);j?se(j):p("/market?tab=local")}else se(null),Y(null)})()},[b,a,z,h,p]);const Pe=x=>{const j=new URLSearchParams(m);j.set("tab",x),i(j),b&&p("/market?"+j.toString())},Ee=x=>{x.preventDefault(),a==="local"?M(ee):a==="registry"&&y(de)},Re=x=>{a==="local"&&H(x)},Ie=()=>{a==="local"?(re(""),H(""),I("")):a==="registry"&&(he(""),n())},pe=x=>{var j;if(a==="registry"){const ae=(j=x.server)==null?void 0:j.name;ae&&p(`/market/${encodeURIComponent(ae)}?tab=registry`)}else p(`/market/${x.name}?tab=local`)},fe=()=>p(`/market?tab=${a}`),Te=async(x,j)=>{try{ce(!0),await S(x,j)&&d(s("market.installSuccess",{serverName:x.display_name}),"success")}finally{ce(!1)}},Le=async(x,j)=>{try{ce(!0);const Z={name:xe(x.name),config:j},ae=await ve("/servers",Z);if(!ae.success){d((ae==null?void 0:ae.message)||s("server.addError"),"error");return}Ce(Ue=>new Set(Ue).add(x.name)),d(s("registry.installSuccess",{name:x.title||x.name}),"success")}catch(Z){d(s("registry.installError",{error:Z instanceof Error?Z.message:String(Z)}),"error")}finally{ce(!1)}},Ae=x=>{a==="local"?Q(x):c(x),window.scrollTo({top:0,behavior:"smooth"})},ze=x=>{const j=parseInt(x.target.value,10);a==="local"?w(j):l(j)};if(G)return e.jsx(as,{server:G,onBack:fe,onInstall:Te,installing:ge,isInstalled:O(G.name)});if(_)return e.jsx(os,{serverEntry:_,onBack:fe,onInstall:Le,installing:ge,isInstalled:we.has(_.server.name),fetchVersions:g});const L=a==="local",le=a==="registry",me=L?A:q,ue=L?f:k,$e=L?o:[],Be=L?D:K,ye=L?P:B,Ve=L?U:E,te=L?C:"",Me=L?F:"",oe=L?V:N,De=L?T:W,ie=L?$:r,be=[{id:"local",label:s("market.title"),sourceLabel:"MCPM",sourceUrl:"https://mcpm.sh"},{id:"registry",label:s("registry.title"),sourceLabel:s("registry.official"),sourceUrl:"https://registry.modelcontextprotocol.io"}];return e.jsxs("div",{children:[e.jsx("div",{className:"flex items-end justify-between gap-4 mb-6",children:e.jsxs("div",{children:[e.jsx("h1",{className:"hub-h1",children:s("nav.market")}),e.jsx("p",{className:"hub-sub",children:be.map(x=>x.label).join(" · ")})]})}),e.jsx("div",{className:"mb-5",children:e.jsx("div",{style:{borderBottom:"1px solid var(--hub-line)"},children:e.jsx("nav",{className:"flex -mb-px gap-1.5",children:be.map(x=>{const j=a===x.id;return e.jsxs("button",{onClick:()=>Pe(x.id),className:"py-2 px-3 transition-colors text-[14px]",style:{borderBottom:"2px solid "+(j?"var(--hub-ink)":"transparent"),color:j?"var(--hub-ink)":"var(--hub-ink-3)",fontWeight:j?500:400},children:[x.label,e.jsxs("a",{href:x.sourceUrl,target:"_blank",rel:"noopener noreferrer",className:"hub-mono ml-1.5",style:{fontSize:11,color:"var(--hub-ink-3)"},onClick:Z=>Z.stopPropagation(),children:["(",x.sourceLabel,")"]})]},x.id)})})})}),ye&&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(Je,{size:14,className:"flex-shrink-0"}),e.jsx("span",{className:"truncate text-[13px]",children:ye})]}),e.jsx("button",{className:"hub-icon-btn sm",onClick:()=>Ve(null),children:e.jsx(Xe,{size:13})})]}),(L||le)&&e.jsxs("form",{onSubmit:Ee,className:"hub-card flex items-center gap-2 px-3 mb-5",style:{padding:6},children:[e.jsx(Ye,{size:16,style:{color:"var(--hub-ink-3)",margin:"0 6px 0 6px"}}),e.jsx("input",{type:"text",value:le?de:ee,onChange:x=>{le?he(x.target.value):re(x.target.value)},placeholder:s(le?"registry.searchPlaceholder":"market.searchPlaceholder"),className:"flex-1 bg-transparent outline-none",style:{height:32,fontSize:14,color:"var(--hub-ink)"}}),e.jsx("button",{type:"submit",className:"hub-btn",children:s("common.search")}),(L&&(ee||te||Me)||le&&de)&&e.jsx("button",{type:"button",onClick:Ie,className:"hub-btn ghost",children:s("common.clear")})]}),e.jsxs("div",{className:L?"grid gap-5":"",style:L?{gridTemplateColumns:"180px 1fr"}:void 0,children:[L&&e.jsxs("div",{children:[e.jsx("h3",{className:"hub-sect mb-2",children:s("market.categories")}),e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsxs("button",{onClick:()=>H(""),className:"flex items-center justify-between transition-colors text-[13px]",style:{padding:"6px 10px",borderRadius:6,background:te?"transparent":"var(--hub-surface)",color:te?"var(--hub-ink-2)":"var(--hub-ink)",border:"1px solid "+(te?"transparent":"var(--hub-line)")},children:[e.jsx("span",{children:s("common.all")}),e.jsx("span",{className:"hub-mono",style:{fontSize:11,color:"var(--hub-ink-3)"},children:f.length})]}),$e.map(x=>e.jsx("button",{onClick:()=>Re(x),className:"flex items-center justify-between transition-colors text-[13px]",style:{padding:"6px 10px",borderRadius:6,background:te===x?"var(--hub-surface)":"transparent",color:te===x?"var(--hub-ink)":"var(--hub-ink-2)",border:"1px solid "+(te===x?"var(--hub-line)":"transparent")},children:e.jsx("span",{className:"truncate",children:x})},x))]})]}),e.jsx("div",{children:Be?e.jsx("div",{className:"hub-card p-6 text-center",style:{color:"var(--hub-ink-3)"},children:s("app.loading")}):me.length===0?e.jsx("div",{className:"hub-card p-10 text-center",style:{color:"var(--hub-ink-3)"},children:s(L?"market.noServers":"registry.noServers")}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3",children:me.map((x,j)=>L?e.jsx(ts,{server:x,onClick:pe},j):e.jsx(ls,{serverEntry:x,onClick:pe},j))}),e.jsxs("div",{className:"flex items-center mt-4 text-[12px]",style:{color:"var(--hub-ink-3)"},children:[e.jsx("div",{className:"flex-[2]",children:L?s("market.showing",{from:(oe-1)*ie+1,to:Math.min(oe*ie,ue.length),total:ue.length}):s("registry.showing",{from:(oe-1)*ie+1,to:(oe-1)*ie+me.length,total:ue.length+(R?"+":"")})}),e.jsx("div",{className:"flex-[4] flex justify-center",children:le?e.jsx(ds,{currentPage:oe,hasNextPage:R,hasPreviousPage:X,onNextPage:v,onPreviousPage:u}):e.jsx(Ke,{currentPage:oe,totalPages:De,onPageChange:Ae})}),e.jsxs("div",{className:"flex-[2] flex items-center justify-end gap-2",children:[e.jsxs("label",{htmlFor:"perPage",children:[s(L?"market.perPage":"registry.perPage"),":"]}),e.jsxs("div",{className:"relative",children:[e.jsxs("select",{id:"perPage",value:ie,onChange:ze,className:"hub-input pr-7",style:{height:26,width:70,padding:"0 6px",fontSize:12},children:[e.jsx("option",{value:"6",children:"6"}),e.jsx("option",{value:"9",children:"9"}),e.jsx("option",{value:"12",children:"12"}),e.jsx("option",{value:"24",children:"24"})]}),e.jsx(Ze,{size:11,className:"absolute right-1.5 top-1/2 -translate-y-1/2 pointer-events-none",style:{color:"var(--hub-ink-3)"}})]})]})]})]})})]})]})};export{ys as default};
|
|
2
|
+
//# sourceMappingURL=MarketPage-BN4qL8L9.js.map
|