nfx-ui 0.16.0 → 0.16.1
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/animations.cjs +2 -3
- package/dist/animations.mjs +3 -4
- package/dist/apis.cjs +1 -2
- package/dist/apis.cjs.map +1 -1
- package/dist/apis.mjs +1 -2
- package/dist/apis.mjs.map +1 -1
- package/dist/{chunk-BounceLoading-C5XE8DKc.mjs → chunk-BounceLoading-C-gq-XVr.mjs} +1 -1
- package/dist/{chunk-BounceLoading-C5XE8DKc.mjs.map → chunk-BounceLoading-C-gq-XVr.mjs.map} +1 -1
- package/dist/chunk-BounceLoading-CkxvzNz8.cjs +11 -0
- package/dist/{chunk-BounceLoading-CwvDT5HF.cjs.map → chunk-BounceLoading-CkxvzNz8.cjs.map} +1 -1
- package/dist/{chunk-animations-Do1xZdGL.mjs → chunk-animations-CiJbVYGC.mjs} +2 -2
- package/dist/{chunk-animations-Do1xZdGL.mjs.map → chunk-animations-CiJbVYGC.mjs.map} +1 -1
- package/dist/{chunk-animations-DOdfS0n5.cjs → chunk-animations-i85rn79V.cjs} +2 -2
- package/dist/{chunk-animations-DOdfS0n5.cjs.map → chunk-animations-i85rn79V.cjs.map} +1 -1
- package/dist/{chunk-i18n--XStRXog.cjs → chunk-i18n-2-xL4pEi.cjs} +2 -2
- package/dist/{chunk-i18n--XStRXog.cjs.map → chunk-i18n-2-xL4pEi.cjs.map} +1 -1
- package/dist/{chunk-i18n-ly0gkdrE.mjs → chunk-i18n-DgaoEbGL.mjs} +3 -3
- package/dist/{chunk-i18n-ly0gkdrE.mjs.map → chunk-i18n-DgaoEbGL.mjs.map} +1 -1
- package/dist/{chunk-language-b-WaFsLY.cjs → chunk-language-2r4uKROB.cjs} +2 -2
- package/dist/{chunk-language-b-WaFsLY.cjs.map → chunk-language-2r4uKROB.cjs.map} +1 -1
- package/dist/{chunk-language-BKIy1ot4.mjs → chunk-language-JRs5UIa2.mjs} +2 -2
- package/dist/{chunk-language-BKIy1ot4.mjs.map → chunk-language-JRs5UIa2.mjs.map} +1 -1
- package/dist/chunk-layout-BEAgFhif.mjs +11 -0
- package/dist/{chunk-layout-C2uqDEMJ.mjs.map → chunk-layout-BEAgFhif.mjs.map} +1 -1
- package/dist/{chunk-layout-D728gccQ.cjs → chunk-layout-mMQXuBLE.cjs} +2 -2
- package/dist/{chunk-layout-D728gccQ.cjs.map → chunk-layout-mMQXuBLE.cjs.map} +1 -1
- package/dist/{chunk-lstorage-BVCD00Ow.mjs → chunk-lstorage-WwyI7gQN.mjs} +1 -1
- package/dist/{chunk-lstorage-BVCD00Ow.mjs.map → chunk-lstorage-WwyI7gQN.mjs.map} +1 -1
- package/dist/{chunk-lstorage-BnxLXHgH.cjs → chunk-lstorage-_yGQsIQ9.cjs} +1 -1
- package/dist/{chunk-lstorage-BnxLXHgH.cjs.map → chunk-lstorage-_yGQsIQ9.cjs.map} +1 -1
- package/dist/{chunk-lucide-C54WenI6.mjs → chunk-lucide-B99NZWfa.mjs} +1 -1
- package/dist/{chunk-lucide-C54WenI6.mjs.map → chunk-lucide-B99NZWfa.mjs.map} +1 -1
- package/dist/{chunk-lucide-CP2lvOPY.cjs → chunk-lucide-XL6d5__j.cjs} +2 -2
- package/dist/{chunk-lucide-CP2lvOPY.cjs.map → chunk-lucide-XL6d5__j.cjs.map} +1 -1
- package/dist/{chunk-preference-Bs5zQSRc.mjs → chunk-preference-DMhhY1Pl.mjs} +15 -15
- package/dist/{chunk-preference-Bs5zQSRc.mjs.map → chunk-preference-DMhhY1Pl.mjs.map} +1 -1
- package/dist/{chunk-preference-DE8Jp2f5.cjs → chunk-preference-DbNgeGhx.cjs} +2 -2
- package/dist/{chunk-preference-DE8Jp2f5.cjs.map → chunk-preference-DbNgeGhx.cjs.map} +1 -1
- package/dist/{chunk-theme-9dcwRKw8.mjs → chunk-theme-CINVDd47.mjs} +8 -8
- package/dist/{chunk-theme-9dcwRKw8.mjs.map → chunk-theme-CINVDd47.mjs.map} +1 -1
- package/dist/{chunk-theme-BFvDRCYS.cjs → chunk-theme-D49XQfXe.cjs} +2 -2
- package/dist/{chunk-theme-BFvDRCYS.cjs.map → chunk-theme-D49XQfXe.cjs.map} +1 -1
- package/dist/chunk-useLayout-BAIFfydj.cjs +3 -0
- package/dist/{chunk-useLayout-BAJHOIL3.cjs.map → chunk-useLayout-BAIFfydj.cjs.map} +1 -1
- package/dist/{chunk-useLayout-DPxlynT-.mjs → chunk-useLayout-BXsJlpcb.mjs} +1 -1
- package/dist/{chunk-useLayout-DPxlynT-.mjs.map → chunk-useLayout-BXsJlpcb.mjs.map} +1 -1
- package/dist/{chunk-useTheme-oHcq3d0o.mjs → chunk-useTheme-BY1_pW9y.mjs} +1 -1
- package/dist/{chunk-useTheme-oHcq3d0o.mjs.map → chunk-useTheme-BY1_pW9y.mjs.map} +1 -1
- package/dist/chunk-useTheme-Tw_7_cQf.cjs +3 -0
- package/dist/{chunk-useTheme-DgleVMMh.cjs.map → chunk-useTheme-Tw_7_cQf.cjs.map} +1 -1
- package/dist/components.cjs +3 -4
- package/dist/components.cjs.map +1 -1
- package/dist/components.mjs +1299 -1094
- package/dist/components.mjs.map +1 -1
- package/dist/constants.cjs +1 -2
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.mjs +1 -2
- package/dist/constants.mjs.map +1 -1
- package/dist/events.cjs +1 -2
- package/dist/events.cjs.map +1 -1
- package/dist/events.mjs +1 -2
- package/dist/events.mjs.map +1 -1
- package/dist/hooks.cjs +2 -3
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.mjs +1 -2
- package/dist/hooks.mjs.map +1 -1
- package/dist/icons.cjs +2 -3
- package/dist/icons.mjs +2 -3
- package/dist/languages.cjs +2 -3
- package/dist/languages.cjs.map +1 -1
- package/dist/languages.mjs +35 -36
- package/dist/languages.mjs.map +1 -1
- package/dist/layouts.cjs +2 -3
- package/dist/layouts.cjs.map +1 -1
- package/dist/layouts.mjs +7 -8
- package/dist/layouts.mjs.map +1 -1
- package/dist/navigations.cjs +1 -2
- package/dist/navigations.cjs.map +1 -1
- package/dist/navigations.mjs +1 -2
- package/dist/navigations.mjs.map +1 -1
- package/dist/pixel-blast.cjs +2 -3
- package/dist/pixel-blast.cjs.map +1 -1
- package/dist/pixel-blast.mjs +2 -3
- package/dist/pixel-blast.mjs.map +1 -1
- package/dist/preference.cjs +2 -3
- package/dist/preference.mjs +2 -3
- package/dist/services.cjs +1 -2
- package/dist/services.cjs.map +1 -1
- package/dist/services.mjs +1 -2
- package/dist/services.mjs.map +1 -1
- package/dist/src/designs/animations/BounceLoading/index.d.ts +1 -1
- package/dist/src/designs/animations/BounceLoading/index.d.ts.map +1 -1
- package/dist/src/designs/animations/ECGLoading/index.d.ts +1 -1
- package/dist/src/designs/animations/ECGLoading/index.d.ts.map +1 -1
- package/dist/src/designs/animations/TruckLoading/index.d.ts +1 -1
- package/dist/src/designs/animations/TruckLoading/index.d.ts.map +1 -1
- package/dist/src/designs/components/Icon/index.d.ts +1 -1
- package/dist/src/designs/components/Icon/index.d.ts.map +1 -1
- package/dist/src/designs/components/KeyValueEditor/index.d.ts +1 -1
- package/dist/src/designs/components/KeyValueEditor/index.d.ts.map +1 -1
- package/dist/src/designs/components/LayoutSwitcher/index.d.ts +1 -1
- package/dist/src/designs/components/LayoutSwitcher/index.d.ts.map +1 -1
- package/dist/src/designs/components/SearchInput/index.d.ts +1 -1
- package/dist/src/designs/components/SearchInput/index.d.ts.map +1 -1
- package/dist/src/designs/components/ShowFilter/index.d.ts +1 -1
- package/dist/src/designs/components/ShowFilter/index.d.ts.map +1 -1
- package/dist/src/designs/components/SlideDownSwitcher/index.d.ts +1 -1
- package/dist/src/designs/components/SlideDownSwitcher/index.d.ts.map +1 -1
- package/dist/src/designs/components/Suspense/index.d.ts +1 -1
- package/dist/src/designs/components/Suspense/index.d.ts.map +1 -1
- package/dist/src/designs/components/ThemeSwitcher/index.d.ts +1 -1
- package/dist/src/designs/components/ThemeSwitcher/index.d.ts.map +1 -1
- package/dist/src/designs/components/VirtualList/index.d.ts +1 -1
- package/dist/src/designs/components/VirtualList/index.d.ts.map +1 -1
- package/dist/src/designs/components/VirtualWindowList/index.d.ts +1 -1
- package/dist/src/designs/components/VirtualWindowList/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/Background/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/Background/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/Footer/index.d.ts +2 -2
- package/dist/src/designs/layouts/components/Footer/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/Header/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/Header/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/LayoutFrame/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/LayoutFrame/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/MainWrapper/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/MainWrapper/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/SideHideLayout/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/SideHideLayout/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/SideShowLayout/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/SideShowLayout/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/components/Sidebar/index.d.ts +1 -1
- package/dist/src/designs/layouts/components/Sidebar/index.d.ts.map +1 -1
- package/dist/src/designs/layouts/providers/index.d.ts +1 -1
- package/dist/src/designs/layouts/providers/index.d.ts.map +1 -1
- package/dist/src/languages/providers/index.d.ts +1 -1
- package/dist/src/languages/providers/index.d.ts.map +1 -1
- package/dist/src/themes/providers/index.d.ts +1 -1
- package/dist/src/themes/providers/index.d.ts.map +1 -1
- package/dist/stores.cjs +2 -3
- package/dist/stores.cjs.map +1 -1
- package/dist/stores.mjs +1 -2
- package/dist/stores.mjs.map +1 -1
- package/dist/themes.cjs +2 -3
- package/dist/themes.cjs.map +1 -1
- package/dist/themes.mjs +4 -5
- package/dist/themes.mjs.map +1 -1
- package/dist/types.cjs +1 -2
- package/dist/types.mjs +1 -2
- package/dist/utils.cjs +2 -3
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.mjs +3 -4
- package/dist/utils.mjs.map +1 -1
- package/package.json +21 -21
- package/dist/chunk-BounceLoading-CwvDT5HF.cjs +0 -11
- package/dist/chunk-layout-C2uqDEMJ.mjs +0 -11
- package/dist/chunk-useLayout-BAJHOIL3.cjs +0 -3
- package/dist/chunk-useTheme-DgleVMMh.cjs +0 -3
- /package/dist/{chunk-chunk-BFrxaqQT.cjs → chunk-chunk-D-Fg7nx1.cjs} +0 -0
package/dist/components.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.mjs","names":["memo","memo"],"sources":["../src/designs/components/Button/styles.module.css","../src/designs/components/Button/index.tsx","../src/designs/components/Dropdown/Dropdown.module.css","../src/designs/components/Dropdown/index.tsx","../src/designs/components/Icon/index.tsx","../src/designs/components/Input/styles.module.css","../src/designs/components/Input/index.tsx","../src/designs/components/KeyValueEditor/styles.module.css","../src/designs/components/KeyValueEditor/index.tsx","../src/designs/components/SearchInput/styles.module.css","../src/designs/components/SearchInput/index.tsx","../src/designs/components/ShowFilter/styles.module.css","../src/designs/components/ShowFilter/index.tsx","../src/designs/components/SlideDownSwitcher/styles.module.css","../src/designs/components/SlideDownSwitcher/index.tsx","../src/designs/components/ThemeSwitcher/index.tsx","../src/designs/components/LayoutSwitcher/index.tsx","../src/designs/components/Slider/styles.module.css","../src/designs/components/Slider/index.tsx","../src/designs/components/Suspense/styles.module.css","../src/designs/components/Suspense/SuspenseErrorBoundary.ts","../src/designs/components/Suspense/index.tsx","../src/designs/components/Textarea/styles.module.css","../src/designs/components/Textarea/index.tsx","../node_modules/@tanstack/virtual-core/dist/esm/utils.js","../node_modules/@tanstack/virtual-core/dist/esm/index.js","../node_modules/@tanstack/react-virtual/dist/esm/index.js","../src/designs/components/VirtualList/styles.module.css","../src/designs/components/VirtualList/index.tsx","../src/designs/components/VirtualWindowList/styles.module.css","../src/designs/components/VirtualWindowList/index.tsx"],"sourcesContent":[".button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n border: 1px solid transparent;\n border-radius: var(--radius-button);\n font-family: inherit;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n outline: none;\n position: relative;\n}\n\n.button:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n.button:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n/* Size variants */\n.button.small {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n min-height: 2rem;\n}\n\n.button.medium {\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n min-height: 2.5rem;\n}\n\n.button.large {\n padding: 1rem 2rem;\n font-size: 1rem;\n min-height: 3rem;\n}\n\n/* Variant styles */\n.button.primary {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-primary-fg);\n}\n\n.button.primary:hover:not(:disabled) {\n background: var(--color-primary-light);\n border-color: var(--color-primary-light);\n transform: translateY(-1px);\n}\n\n.button.primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.button.secondary {\n background: var(--color-bg-2);\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.button.secondary:hover:not(:disabled) {\n background: var(--color-bg-3);\n border-color: var(--color-primary);\n}\n\n.button.outline {\n background: transparent;\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.button.outline:hover:not(:disabled) {\n background: var(--color-bg-2);\n border-color: var(--color-primary);\n}\n\n.button.ghost {\n background: transparent;\n border-color: transparent;\n color: var(--color-fg-text);\n}\n\n.button.ghost:hover:not(:disabled) {\n background: var(--color-bg-2);\n}\n\n.button.danger {\n background: var(--color-danger);\n border-color: var(--color-danger);\n /* 与 Modal 等危险操作区一致:用 danger 专用前景,勿用 primary-fg(主题下易为深色) */\n color: var(--color-danger-fg, #ffffff);\n}\n\n.button.danger:hover:not(:disabled) {\n background: var(--color-danger-light);\n border-color: var(--color-danger-light);\n color: var(--color-danger-fg, #ffffff);\n transform: translateY(-1px);\n}\n\n.button.danger:active:not(:disabled) {\n transform: translateY(0);\n}\n\n/* Full width */\n.button.fullWidth {\n width: 100%;\n}\n\n/* Loading state */\n.button.loading {\n pointer-events: none;\n}\n\n.spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n flex-shrink: 0;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.button.small .spinner {\n width: 0.875rem;\n height: 0.875rem;\n border-width: 1.5px;\n}\n\n.button.large .spinner {\n width: 1.25rem;\n height: 1.25rem;\n border-width: 2.5px;\n}\n\n.content {\n display: flex;\n align-items: center;\n}\n\n.leftIcon,\n.rightIcon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n.leftIcon {\n margin-right: -0.25rem;\n}\n\n.rightIcon {\n margin-left: -0.25rem;\n}\n\n/* Icon-only (square) */\n.button.iconOnly {\n aspect-ratio: 1;\n padding: 0;\n min-width: 2.5rem;\n min-height: 2.5rem;\n}\n\n.button.iconOnly.small {\n min-width: 2rem;\n min-height: 2rem;\n}\n\n.button.iconOnly.large {\n min-width: 3rem;\n min-height: 3rem;\n}\n\n.iconContainer {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.layout {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.25rem;\n width: 100%;\n}\n\n.horizontal {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n width: 100%;\n}\n\n.topIcon,\n.bottomIcon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.iconOnly .iconContainer .leftIcon,\n.iconOnly .iconContainer .rightIcon {\n margin: 0;\n}\n","/**\n * 按钮组件:支持 variant、size、四向图标、iconOnly、loading、fullWidth。\n * Button with variant, size, top/right/bottom/left icon, iconOnly, loading, fullWidth.\n *\n * @example\n * ```tsx\n * <Button>保存</Button>\n * <Button leftIcon={<Save size={16} />} loading={isSubmitting}>提交</Button>\n * <Button leftIcon={<Trash2 size={16} />} iconOnly aria-label=\"删除\" />\n * ```\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nimport { cloneElement, forwardRef, isValidElement } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"size\"> {\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"ghost\" | \"danger\";\n size?: \"small\" | \"medium\" | \"large\";\n fullWidth?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /** 上方图标。Top icon. */\n topIcon?: ReactNode;\n /** 下方图标。Bottom icon. */\n bottomIcon?: ReactNode;\n /** 仅图标无文案。Icon only, no text. */\n iconOnly?: boolean;\n /** 图标尺寸覆盖。Override icon size. */\n iconSize?: number;\n loading?: boolean;\n children?: ReactNode;\n}\n\nfunction renderIcon(icon: ReactNode, iconSize?: number): ReactNode {\n if (!icon) return null;\n if (iconSize && isValidElement(icon) && typeof icon.type !== \"string\") {\n const existingProps = icon.props && typeof icon.props === \"object\" ? icon.props : {};\n return cloneElement(icon as React.ReactElement<{ size?: number }>, { ...existingProps, size: iconSize });\n }\n return icon;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"medium\",\n fullWidth = false,\n leftIcon,\n rightIcon,\n topIcon,\n bottomIcon,\n iconOnly = false,\n iconSize,\n loading = false,\n disabled,\n children,\n className = \"\",\n ...props\n },\n ref,\n ) => {\n const hasIcons = leftIcon || rightIcon || topIcon || bottomIcon;\n const hasContent = !iconOnly && children;\n const useIconOnlyLayout = iconOnly && hasIcons && !hasContent;\n const useLayout = topIcon || bottomIcon || useIconOnlyLayout;\n\n const buttonClasses = [\n styles.button,\n styles[variant],\n styles[size],\n fullWidth && styles.fullWidth,\n loading && styles.loading,\n useIconOnlyLayout && styles.iconOnly,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n if (useIconOnlyLayout) {\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n <span className={styles.iconContainer}>\n {topIcon && <span className={styles.topIcon}>{renderIcon(topIcon, iconSize)}</span>}\n {leftIcon && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {rightIcon && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n {bottomIcon && <span className={styles.bottomIcon}>{renderIcon(bottomIcon, iconSize)}</span>}\n </span>\n </button>\n );\n }\n\n if (useLayout) {\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n {loading && <span className={styles.spinner} />}\n {!loading && (\n <span className={styles.layout}>\n {topIcon && <span className={styles.topIcon}>{renderIcon(topIcon, iconSize)}</span>}\n <span className={styles.horizontal}>\n {leftIcon && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {hasContent && <span className={styles.content}>{children}</span>}\n {rightIcon && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n </span>\n {bottomIcon && <span className={styles.bottomIcon}>{renderIcon(bottomIcon, iconSize)}</span>}\n </span>\n )}\n </button>\n );\n }\n\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n {loading && <span className={styles.spinner} />}\n {leftIcon && !loading && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {children && <span className={styles.content}>{children}</span>}\n {rightIcon && !loading && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n </button>\n );\n },\n);\n\nButton.displayName = \"Button\";\n\nexport default Button;\n","/* ===== Dropdown 基础样式 ===== */\r\n.dropdown {\r\n position: relative;\r\n display: inline-block;\r\n width: 100%;\r\n}\r\n\r\n.dropdownButton {\r\n position: relative;\r\n width: 100%;\r\n padding: 0.75rem 1rem;\r\n padding-right: 2.5rem;\r\n border: 1px solid var(--color-separator);\r\n border-radius: var(--radius-card);\r\n cursor: pointer;\r\n outline: none;\r\n transition: all 0.2s ease-in-out;\r\n text-align: left;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n font-family: inherit;\r\n font-size: 1rem;\r\n font-weight: 400;\r\n line-height: 1.5rem;\r\n background: var(--color-bg-2);\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.dropdownButton:hover:not(:disabled) {\r\n border-color: var(--color-primary);\r\n background: var(--color-bg-1);\r\n}\r\n\r\n.dropdownButton:focus {\r\n border-color: var(--color-primary);\r\n background: var(--color-bg-1);\r\n box-shadow: 0 0 0 2px var(--color-primary-transparent);\r\n}\r\n\r\n.dropdownButton.disabled {\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n background: var(--color-bg-3);\r\n}\r\n\r\n.dropdownButton.error {\r\n border-color: var(--color-danger);\r\n}\r\n\r\n.buttonText {\r\n flex: 1;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n}\r\n\r\n.chevronIcon {\r\n position: absolute;\r\n right: 1rem;\r\n transition: transform 0.15s ease;\r\n flex-shrink: 0;\r\n color: var(--color-fg-highlight);\r\n}\r\n\r\n.chevronIcon.open {\r\n transform: rotate(180deg);\r\n}\r\n\r\n/* ===== 下拉菜单 ===== */\r\n.dropdownMenu {\r\n position: absolute;\r\n top: calc(100% + 0.5rem);\r\n left: 0;\r\n right: 0;\r\n min-width: 100%;\r\n background: var(--color-bg);\r\n border: 1px solid var(--color-border-4);\r\n border-radius: var(--radius-card);\r\n box-shadow: 0 0.5rem 1rem var(--color-shadow);\r\n z-index: 1000;\r\n overflow: hidden;\r\n animation: slideDown 0.15s ease-out;\r\n}\r\n\r\n@keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-0.5rem);\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n}\r\n\r\n.optionsList {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0.5rem 0;\r\n}\r\n\r\n.option {\r\n padding: 0.75rem 1rem;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n}\r\n\r\n.option:hover {\r\n background-color: var(--color-bg-2);\r\n}\r\n\r\n.option.selected {\r\n background-color: var(--color-bg-3);\r\n color: var(--color-fg-highlight);\r\n font-weight: 600;\r\n}\r\n\r\n/* ===== 响应式 ===== */\r\n@media (max-width: 768px) {\r\n .dropdownButton {\r\n padding: 0.625rem 0.875rem;\r\n padding-right: 2.25rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .chevronIcon {\r\n right: 0.875rem;\r\n }\r\n\r\n .option {\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.8125rem;\r\n }\r\n}","/**\n * 下拉选择:options 为 { value, label } 列表,受控 value/onChange。Dropdown select; options as { value, label }, controlled value/onChange.\n *\n * @example\n * ```tsx\n * * 受控选择\n * const [value, setValue] = useState(\"\");\n * <Dropdown\n * options={[{ value: \"a\", label: \"选项 A\" }, { value: \"b\", label: \"选项 B\" }]}\n * value={value}\n * onChange={setValue}\n * placeholder=\"请选择\"\n * />\n * ```\n */\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport { ChevronDown } from \"@/icons/lucide\";\n\nimport styles from \"./Dropdown.module.css\";\n\nexport interface DropdownOption {\n /** 选项值。Option value. */\n value: string;\n /** 选项展示文案。Option label. */\n label: string;\n}\n\nexport interface DropdownProps {\n /** 选项列表。Options list. */\n options: DropdownOption[];\n /** 当前选中值。Current value. */\n value: string;\n /** 选中回调。Change callback. */\n onChange: (value: string) => void;\n /** 占位符。Placeholder. */\n placeholder?: string;\n /** 是否禁用。Disabled. */\n disabled?: boolean;\n /** 是否错误态。Error state. */\n error?: boolean;\n /** 容器 className。Container className. */\n className?: string;\n}\n\nconst Dropdown = memo<DropdownProps>(({ options, value, onChange, placeholder = \"Select an option\", disabled = false, error = false, className = \"\" }) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n // 点击外部关闭下拉菜单\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n const selectedOption = options.find((option) => option.value === value);\n const displayText = selectedOption ? selectedOption.label : placeholder;\n\n const handleOptionClick = (optionValue: string) => {\n onChange(optionValue);\n setIsOpen(false);\n };\n\n return (\n <div className={`${styles.dropdown} ${className}`} ref={dropdownRef}>\n <button\n type=\"button\"\n className={`${styles.dropdownButton} ${error ? styles.error : \"\"} ${disabled ? styles.disabled : \"\"}`}\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n <span className={styles.buttonText}>{displayText}</span>\n <ChevronDown size={16} className={`${styles.chevronIcon} ${isOpen ? styles.open : \"\"}`} />\n </button>\n\n {isOpen && !disabled && (\n <div className={styles.dropdownMenu}>\n <ul className={styles.optionsList} role=\"listbox\">\n {options.map((option) => (\n <li\n key={option.value}\n className={`${styles.option} ${option.value === value ? styles.selected : \"\"}`}\n onClick={() => handleOptionClick(option.value)}\n role=\"option\"\n aria-selected={option.value === value}\n >\n {option.label}\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n});\n\nDropdown.displayName = \"Dropdown\";\n\nexport default Dropdown;\n","/**\n * 图标组件:基于 lucide-react,通过 name 渲染对应图标。Icon component; renders lucide icon by name.\n *\n * @example\n * ```tsx\n * * 使用已注册的图标名\n * <Icon name=\"ChevronDown\" size={20} />\n * * 带 className\n * <Icon name=\"Search\" className={styles.searchIcon} />\n * ```\n */\nimport type { LucideProps } from \"lucide-react\";\n\nimport { memo } from \"react\";\n\nimport * as LucideIcons from \"@/icons/lucide\";\n\nexport type IconName = keyof Omit<typeof LucideIcons, \"LucideIcon\">;\n\nexport interface IconProps extends LucideProps {\n /** 图标名(lucide 注册名)。Icon name (lucide registered name). */\n name: IconName;\n}\n\nconst Icon = memo(({ name, ...props }: IconProps) => {\n const LucideIcon = LucideIcons[name] as React.ComponentType<LucideProps> | undefined;\n\n if (!LucideIcon) {\n console.warn(`Icon \"${name}\" not found in lucide-react`);\n return null;\n }\n\n return <LucideIcon {...props} />;\n});\n\nIcon.displayName = \"Icon\";\n\nexport default Icon;\n",".wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.wrapper.fullWidth {\n width: 100%;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-heading);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.required {\n color: var(--color-danger);\n}\n\n.inputContainer {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n border: 1px solid var(--color-border-4);\n border-radius: var(--radius-input);\n background: var(--color-bg);\n color: var(--color-fg-text);\n font-size: 0.875rem;\n font-family: inherit;\n transition: all 0.2s ease;\n outline: none;\n}\n\n/* 隐藏浏览器默认的密码可见性切换图标 */\n/* Chrome/Edge/Safari: 隐藏密码可见性切换按钮 */\n.input[type=\"password\"]::-webkit-credentials-auto-fill-button {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n.input[type=\"password\"]::-webkit-strong-password-toggle-button {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n margin: 0 !important;\n padding: 0 !important;\n width: 0 !important;\n height: 0 !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n/* Edge 浏览器额外处理 */\n.input[type=\"password\"]::-ms-reveal,\n.input[type=\"password\"]::-ms-clear {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n width: 0 !important;\n height: 0 !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n.input:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);\n}\n\n.input::placeholder {\n color: var(--color-fg-muted);\n opacity: 0.5;\n}\n\n/* Size variants */\n.input.small {\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n}\n\n.input.medium {\n padding: 0.75rem;\n font-size: 0.875rem;\n}\n\n.input.large {\n padding: 1rem;\n font-size: 1rem;\n}\n\n/* Variant styles */\n.input.default {\n background: var(--color-bg);\n border-color: var(--color-border-4);\n}\n\n.input.filled {\n background: var(--color-bg-2);\n border-color: var(--color-border-3);\n}\n\n/* With icons - handled via className in component */\n.inputContainer.withLeftIcon .input {\n padding-left: 2.5rem;\n}\n\n.inputContainer.withRightIcon .input {\n padding-right: 2.5rem;\n}\n\n.inputContainer.withLeftIcon .input.small {\n padding-left: 2rem;\n}\n\n.inputContainer.withRightIcon .input.small {\n padding-right: 2rem;\n}\n\n.inputContainer.withLeftIcon .input.large {\n padding-left: 3rem;\n}\n\n.inputContainer.withRightIcon .input.large {\n padding-right: 3rem;\n}\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted);\n pointer-events: none;\n z-index: 1;\n}\n\n.leftIcon {\n left: 0.75rem;\n}\n\n.rightIcon {\n right: 0.75rem;\n}\n\n.rightIcon.rightIconInteractive {\n pointer-events: auto;\n}\n\n.inputContainer.containerSmall .leftIcon {\n left: 0.5rem;\n}\n\n.inputContainer.containerSmall .rightIcon {\n right: 0.5rem;\n}\n\n.inputContainer.containerLarge .leftIcon {\n left: 1rem;\n}\n\n.inputContainer.containerLarge .rightIcon {\n right: 1rem;\n}\n\n/* Error state */\n.input.error {\n border-color: var(--color-danger);\n}\n\n.input.error:focus {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb), 0.1);\n}\n\n/* Disabled state */\n.input.disabled {\n background: var(--color-bg-3);\n border-color: var(--color-border-5);\n color: var(--color-fg-muted);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.errorMessage {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 输入框:支持 label、error、helperText、左右图标与 rightIconInteractive。Input with label, error, helperText, left/right icon.\n *\n * @example\n * ```tsx\n * * 带标签与错误态\n * <Input label=\"用户名\" error={errors.name} value={name} onChange={(e) => setName(e.target.value)} />\n * * 右侧可点击图标(如清除)\n * <Input rightIcon={<X size={16} />} rightIconInteractive onRightIconClick={clear} />\n * ```\n */\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\n\nimport { forwardRef } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n /** 标签文案。Label text. */\n label?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n /** 辅助说明。Helper text. */\n helperText?: ReactNode;\n /** 左侧图标。Left icon. */\n leftIcon?: ReactNode;\n /** 右侧图标。Right icon. */\n rightIcon?: ReactNode;\n /** 为 true 时 rightIcon 可点击(如密码切换、清除按钮)。When true, right icon is clickable (e.g. password toggle, clear). */\n rightIconInteractive?: boolean;\n /** 尺寸。Size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** 视觉变体。Variant. */\n variant?: \"default\" | \"filled\";\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n}\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n error,\n helperText,\n leftIcon,\n rightIcon,\n rightIconInteractive = false,\n size = \"medium\",\n variant = \"default\",\n fullWidth = false,\n className = \"\",\n disabled,\n ...props\n },\n ref,\n ) => {\n const inputClasses = [styles.input, styles[size], styles[variant], error && styles.error, disabled && styles.disabled, className].filter(Boolean).join(\" \");\n\n const wrapperClasses = [styles.wrapper, fullWidth && styles.fullWidth].filter(Boolean).join(\" \");\n\n const containerClasses = [\n styles.inputContainer,\n leftIcon && styles.withLeftIcon,\n rightIcon && styles.withRightIcon,\n size && styles[`container${size.charAt(0).toUpperCase() + size.slice(1)}`],\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={wrapperClasses}>\n {label && (\n <label className={styles.label}>\n {label}\n {props.required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={containerClasses}>\n {leftIcon && <div className={styles.leftIcon}>{leftIcon}</div>}\n <input ref={ref} className={inputClasses} disabled={disabled} {...props} />\n {rightIcon && <div className={`${styles.rightIcon} ${rightIconInteractive ? styles.rightIconInteractive : \"\"}`}>{rightIcon}</div>}\n </div>\n {error && <p className={styles.errorMessage}>{error}</p>}\n {helperText && !error && <p className={styles.helperText}>{helperText}</p>}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport default Input;\n",".container {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-text);\n}\n\n.error {\n font-size: 0.875rem;\n color: var(--color-error);\n}\n\n.pairs {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.pair {\n display: grid;\n grid-template-columns: 1fr 2fr auto;\n gap: 0.75rem;\n align-items: start;\n}\n\n.keyInput,\n.valueInput {\n flex: 1;\n}\n\n.removeButton {\n padding: 0.5rem;\n min-width: auto;\n color: var(--color-error);\n}\n\n.removeButton:hover {\n background-color: var(--color-error);\n color: var(--color-primary-fg);\n}\n\n.addButton {\n align-self: flex-start;\n}\n\n@media (max-width: 768px) {\n .pair {\n grid-template-columns: 1fr;\n }\n\n .removeButton {\n align-self: flex-end;\n }\n}\n","/**\n * 键值对编辑器:动态增删 key-value 行,支持 string 或 array 值类型。Key-value pair editor; add/remove rows, valueType string or array.\n *\n * @example\n * ```tsx\n * * 字符串值\n * const [pairs, setPairs] = useState<KeyValuePair[]>([{ key: \"env\", value: \"prod\" }]);\n * <KeyValueEditor label=\"环境变量\" pairs={pairs} onChange={setPairs} />\n * * 数组值(逗号分隔)\n * <KeyValueEditor label=\"标签\" pairs={pairs} onChange={setPairs} valueType=\"array\" />\n * ```\n */\nimport type { ReactNode } from \"react\";\n\nimport { memo, useEffect, useState } from \"react\";\n\nimport Button from \"@/designs/components/Button\";\nimport Input from \"@/designs/components/Input\";\nimport { Plus, Trash2 } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface KeyValuePair {\n /** 键。Key. */\n key: string;\n /** 值(字符串或字符串数组)。Value (string or string[]). */\n value: string | string[];\n}\n\nexport interface KeyValueEditorProps {\n /** 表单项标签。Field label. */\n label: ReactNode;\n /** 键值对列表。Key-value pairs. */\n pairs: KeyValuePair[];\n /** 列表变化回调。Change callback. */\n onChange: (pairs: KeyValuePair[]) => void;\n /** 值类型:string 或 array。Value type: string or array. */\n valueType?: \"string\" | \"array\";\n /** 键占位符。Key placeholder. */\n keyPlaceholder?: string;\n /** 值占位符(string 模式)。Value placeholder (string mode). */\n valuePlaceholder?: string;\n /** 值占位符(array 模式)。Value placeholder (array mode). */\n valueArrayPlaceholder?: string;\n /** 删除按钮 aria-label。Remove button aria-label. */\n removeAriaLabel?: string;\n /** 新增按钮文案。Add button label. */\n addLabel?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n}\n\nconst KeyValueEditor = memo(\n ({\n label,\n pairs,\n onChange,\n valueType = \"string\",\n keyPlaceholder = \"Key\",\n valuePlaceholder = \"Value\",\n valueArrayPlaceholder = \"Value (comma-separated)\",\n removeAriaLabel = \"Remove row\",\n addLabel = \"Add\",\n error,\n }: KeyValueEditorProps) => {\n const effectiveValuePlaceholder = valueType === \"array\" ? valueArrayPlaceholder : valuePlaceholder;\n const [localPairs, setLocalPairs] = useState<KeyValuePair[]>(pairs);\n\n // Sync with external pairs changes\n useEffect(() => {\n setLocalPairs(pairs);\n }, [pairs]);\n\n const handleAdd = () => {\n const newPairs = [...localPairs, { key: \"\", value: valueType === \"array\" ? [] : \"\" }];\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleRemove = (index: number) => {\n const newPairs = localPairs.filter((_, i) => i !== index);\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleKeyChange = (index: number, key: string) => {\n const newPairs = [...localPairs];\n newPairs[index] = { ...newPairs[index], key };\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleValueChange = (index: number, value: string) => {\n const newPairs = [...localPairs];\n if (valueType === \"array\") {\n // Split by comma and trim\n const arrayValue = value\n .split(\",\")\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n newPairs[index] = { ...newPairs[index], value: arrayValue };\n } else {\n newPairs[index] = { ...newPairs[index], value };\n }\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const getDisplayValue = (value: string | string[]): string => {\n if (Array.isArray(value)) {\n return value.join(\", \");\n }\n return value;\n };\n\n return (\n <div className={styles.container}>\n <label className={styles.label}>{label}</label>\n {error && <div className={styles.error}>{error}</div>}\n <div className={styles.pairs}>\n {localPairs.map((pair, index) => (\n <div key={index} className={styles.pair}>\n <Input placeholder={keyPlaceholder} value={pair.key} onChange={(e) => handleKeyChange(index, e.target.value)} className={styles.keyInput} />\n <Input\n placeholder={effectiveValuePlaceholder}\n value={getDisplayValue(pair.value)}\n onChange={(e) => handleValueChange(index, e.target.value)}\n className={styles.valueInput}\n />\n <Button type=\"button\" variant=\"ghost\" onClick={() => handleRemove(index)} className={styles.removeButton} aria-label={removeAriaLabel}>\n <Trash2 size={16} />\n </Button>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"secondary\" onClick={handleAdd} className={styles.addButton}>\n <Plus size={16} />\n {addLabel}\n </Button>\n </div>\n );\n },\n);\n\nKeyValueEditor.displayName = \"KeyValueEditor\";\n\nexport default KeyValueEditor;\n",".searchContainer {\r\n position: relative;\r\n width: 100%;\r\n max-width: 400px;\r\n}\r\n\r\n/** 占满父级(如 dialog / modal 内容区),不受 400px 上限 */\r\n.searchContainerFull {\r\n max-width: none;\r\n}\r\n\r\n.searchIcon {\r\n position: absolute;\r\n left: 1rem;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n color: var(--color-fg-muted);\r\n pointer-events: none;\r\n}\r\n\r\n.searchInput {\r\n width: 100%;\r\n padding: 0.75rem 3rem 0.75rem 3rem;\r\n border: 1px solid var(--color-border);\r\n border-radius: var(--radius-input);\r\n font-size: 1rem;\r\n color: var(--color-fg-text);\r\n background: var(--color-bg-2);\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.searchInput:focus {\r\n outline: none;\r\n border-color: var(--color-primary);\r\n box-shadow: 0 0 0 3px var(--color-primary-bg);\r\n}\r\n\r\n.searchInput::placeholder {\r\n color: var(--color-fg-muted);\r\n}\r\n\r\n.clearBtn {\r\n position: absolute;\r\n right: 0.75rem;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 1.5rem;\r\n height: 1.5rem;\r\n padding: 0;\r\n background: none;\r\n border: none;\r\n color: var(--color-fg-muted);\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.clearBtn:hover {\r\n color: var(--color-fg-text);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .searchContainer {\r\n max-width: 100%;\r\n }\r\n}\r\n\r\n","/**\n * 搜索输入框:带搜索图标与清除按钮;文案由调用方传入。Search input with search icon and clear button; labels passed as props.\n *\n * @example\n * ```tsx\n * * 受控,文案由上层 i18n 传入\n * const { t } = useTranslation(\"components\");\n * <SearchInput value={keyword} onChange={setKeyword} placeholder={t(\"searchInput.placeholder\")} clearButtonAriaLabel={t(\"searchInput.clearSearch\")} />\n * ```\n */\nimport { memo } from \"react\";\n\nimport { Search, X } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface SearchInputProps {\n /** 当前输入值。Current value. */\n value: string;\n /** 值变化回调。Change callback. */\n onChange: (value: string) => void;\n /** 占位符,由调用方传入。Placeholder; pass from caller. */\n placeholder?: string;\n /** 清除按钮 aria-label;由调用方传入(可来自 i18n)。Clear button aria-label; pass from caller. */\n clearButtonAriaLabel?: string;\n /** 为 true 时占满父级宽度并去掉 400px 上限(如模态内);列表顶栏保持默认。 */\n fullWidth?: boolean;\n}\n\nconst SearchInput = memo(\n ({ value, onChange, placeholder, clearButtonAriaLabel = \"Clear search\", fullWidth = false }: SearchInputProps) => {\n const handleClear = () => onChange(\"\");\n\n return (\n <div className={`${styles.searchContainer} ${fullWidth ? styles.searchContainerFull : \"\"}`.trim()}>\n <Search size={18} className={styles.searchIcon} />\n <input type=\"text\" value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} className={styles.searchInput} />\n {value && (\n <button onClick={handleClear} className={styles.clearBtn} aria-label={clearButtonAriaLabel}>\n <X size={16} />\n </button>\n )}\n </div>\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nexport default SearchInput;\n",".container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.75rem;\r\n}\r\n\r\n.toggleContainer {\r\n display: flex;\r\n align-items: center;\r\n}\r\n\r\n.toggleButton {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n padding: 0.5rem 1rem;\r\n border: 1px solid var(--color-border-4);\r\n border-radius: var(--radius-button);\r\n background: var(--color-bg);\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.toggleButton:hover {\r\n background: var(--color-bg-2);\r\n border-color: var(--color-border-3);\r\n}\r\n\r\n.toggleButton.enabled {\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border-color: var(--color-primary);\r\n}\r\n\r\n.toggleButton.enabled:hover {\r\n background: var(--color-primary-hover);\r\n border-color: var(--color-primary-hover);\r\n color: var(--color-primary-fg);\r\n}\r\n\r\n.optionsContainer {\r\n display: flex;\r\n gap: 0.5rem;\r\n padding: 0.5rem;\r\n background: var(--color-bg-2);\r\n border-radius: var(--radius-card);\r\n border: 1px solid var(--color-border-4);\r\n}\r\n\r\n.option {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.375rem;\r\n padding: 0.5rem 0.875rem;\r\n border: 1px solid var(--color-border-4);\r\n border-radius: var(--radius-button);\r\n background: var(--color-bg);\r\n color: var(--color-fg);\r\n font-size: 0.875rem;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n flex: 1;\r\n justify-content: center;\r\n}\r\n\r\n.option:hover {\r\n background: var(--color-bg-3);\r\n border-color: var(--color-border-3);\r\n}\r\n\r\n.option.active {\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border-color: var(--color-primary);\r\n}\r\n\r\n.option.active:hover {\r\n background: var(--color-primary-hover);\r\n border-color: var(--color-primary-hover);\r\n color: var(--color-primary-fg);\r\n}\r\n\r\n","/**\n * 显示/隐藏筛选器:开关 + 全部/显示/隐藏选项;文案由调用方传入。Show/hide filter; labels passed as props.\n *\n * @example\n * ```tsx\n * * 受控,不传文案则用默认英文;可传 i18n\n * <ShowFilter value={filter} onChange={setFilter} />\n * <ShowFilter value={filter} onChange={setFilter} all={t(\"showFilter.all\")} show={t(\"showFilter.show\")} hide={t(\"showFilter.hide\")} />\n * ```\n */\nimport type { ReactNode } from \"react\";\n\nimport { memo } from \"react\";\n\nimport { Eye, EyeOff, Filter } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface ShowFilterValue {\n /** 筛选是否启用。Whether filter is enabled. */\n enabled: boolean;\n /** 显示/隐藏:null=全部,true=显示,false=隐藏。Show/hide: null=all, true=show, false=hide. */\n value: boolean | null;\n}\n\nexport interface ShowFilterProps {\n /** 当前值。Current value. */\n value: ShowFilterValue;\n /** 值变化回调。Change callback. */\n onChange: (value: ShowFilterValue) => void;\n /** 筛选开启时的按钮文案。Label when filter enabled. */\n filterEnabled?: ReactNode;\n /** 筛选关闭时的按钮文案。Label when filter disabled. */\n filterDisabled?: ReactNode;\n /** 开启筛选按钮的 aria-label。Aria-label for enable filter button. */\n enableFilterAriaLabel?: string;\n /** 关闭筛选按钮的 aria-label。Aria-label for disable filter button. */\n disableFilterAriaLabel?: string;\n /** 「全部」选项文案。Label for \"all\" option. */\n all?: ReactNode;\n /** 「显示」选项文案。Label for \"show\" option. */\n show?: ReactNode;\n /** 「隐藏」选项文案。Label for \"hide\" option. */\n hide?: ReactNode;\n}\n\nconst ShowFilter = memo(\n ({\n value,\n onChange,\n filterEnabled = \"Filter on\",\n filterDisabled = \"Filter\",\n enableFilterAriaLabel = \"Enable filter\",\n disableFilterAriaLabel = \"Disable filter\",\n all = \"All\",\n show = \"Show\",\n hide = \"Hide\",\n }: ShowFilterProps) => {\n const handleToggleEnabled = () => {\n onChange({ ...value, enabled: !value.enabled });\n };\n\n const handleSelectValue = (filterValue: boolean | null) => {\n onChange({ ...value, value: filterValue });\n };\n\n return (\n <div className={styles.container}>\n <div className={styles.toggleContainer}>\n <button\n type=\"button\"\n className={`${styles.toggleButton} ${value.enabled ? styles.enabled : \"\"}`}\n onClick={handleToggleEnabled}\n aria-label={value.enabled ? disableFilterAriaLabel : enableFilterAriaLabel}\n >\n <Filter size={16} />\n <span>{value.enabled ? filterEnabled : filterDisabled}</span>\n </button>\n </div>\n\n {value.enabled && (\n <div className={styles.optionsContainer}>\n <button type=\"button\" className={`${styles.option} ${value.value === null ? styles.active : \"\"}`} onClick={() => handleSelectValue(null)}>\n {all}\n </button>\n <button type=\"button\" className={`${styles.option} ${value.value === true ? styles.active : \"\"}`} onClick={() => handleSelectValue(true)}>\n <Eye size={16} />\n <span>{show}</span>\n </button>\n <button type=\"button\" className={`${styles.option} ${value.value === false ? styles.active : \"\"}`} onClick={() => handleSelectValue(false)}>\n <EyeOff size={16} />\n <span>{hide}</span>\n </button>\n </div>\n )}\n </div>\n );\n },\n);\n\nShowFilter.displayName = \"ShowFilter\";\n\nexport default ShowFilter;\n","/* ===== Nebular Select 样式模仿(下拉滑出) ===== */\n\n.nbSelect {\n display: inline-block;\n position: relative;\n font-family: inherit;\n font-size: 0.9375rem;\n line-height: 1.5rem;\n font-weight: 600;\n}\n\n.selectButton {\n position: relative;\n width: 100%;\n min-width: 8rem;\n padding: 0.4375rem 2.2rem 0.4375rem 1.125rem;\n border: 1px solid;\n border-radius: var(--radius-button);\n cursor: pointer;\n outline: none;\n transition: all 0.15s ease-in-out;\n text-align: left;\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n line-height: inherit;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n}\n\n.selectButton.primary {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-primary-fg);\n}\n\n.selectButton.primary:hover:not(:disabled) {\n background-color: var(--color-primary-light);\n border-color: var(--color-primary-light);\n}\n\n.selectButton.primary:focus,\n.selectButton.primary.open {\n background-color: var(--color-primary-light);\n border-color: var(--color-primary-light);\n box-shadow: 0 0 0 0.125rem rgba(var(--color-primary-rgb), 0.25);\n}\n\n.selectButton.default {\n background-color: var(--color-bg);\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.selectButton.default:hover:not(:disabled) {\n background-color: var(--color-bg-2);\n border-color: var(--color-primary);\n}\n\n.selectButton.default:focus,\n.selectButton.default.open {\n background-color: var(--color-bg-2);\n border-color: var(--color-primary);\n box-shadow: 0 0 0 0.125rem rgba(var(--color-primary-rgb), 0.25);\n}\n\n.selectButton:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.buttonText {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.chevronIcon {\n position: absolute;\n right: 0.41rem;\n width: 1.5rem;\n height: 1.5rem;\n transition: transform 0.15s ease;\n flex-shrink: 0;\n}\n\n.selectButton.primary .chevronIcon {\n color: var(--color-primary-fg);\n}\n\n.selectButton.default .chevronIcon {\n color: var(--color-fg);\n}\n\n.chevronIcon.open {\n transform: rotate(180deg);\n}\n\n.optionsPanel {\n position: absolute;\n top: calc(100% + 0.5rem);\n left: 0;\n right: 0;\n min-width: 100%;\n background-color: var(--color-bg);\n border: 1px solid var(--color-border-4);\n border-radius: var(--radius-button);\n box-shadow: 0 0.5rem 1rem var(--color-shadow);\n z-index: 1000;\n overflow: hidden;\n transform-origin: top;\n visibility: hidden;\n pointer-events: none;\n}\n\n.optionsPanel.open {\n visibility: visible;\n pointer-events: auto;\n animation: expandDown 0.25s ease-out;\n}\n\n.optionsPanel.closed {\n visibility: hidden;\n pointer-events: none;\n animation: collapseUp 0.25s ease-out;\n}\n\n@keyframes expandDown {\n from {\n opacity: 0;\n transform: scaleY(0);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n@keyframes collapseUp {\n from {\n opacity: 1;\n transform: scaleY(1);\n }\n to {\n opacity: 0;\n transform: scaleY(0);\n }\n}\n\n.optionsPanel.primary {\n border-color: var(--color-primary);\n}\n\n.optionsPanel.default {\n border-color: var(--color-border-4);\n}\n\n.optionsList {\n list-style: none;\n margin: 0;\n padding: 0.5rem 0;\n}\n\n.option {\n padding: 0.75rem 1.125rem;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: var(--color-fg-text);\n}\n\n.option:hover {\n background-color: var(--color-bg-2);\n}\n\n.option.selected {\n background-color: var(--color-primary);\n color: var(--color-primary-fg);\n font-weight: 700;\n}\n\n@media (prefers-color-scheme: dark) {\n .optionsPanel {\n box-shadow: 0 0.5rem 1rem var(--color-shadow);\n }\n}\n","/**\n * 下滑切换器:选项列表下拉选择,支持泛型 T(如 enum)。Dropdown switcher with options; generic T (e.g. enum).\n *\n * @example\n * ```tsx\n * * 与 enum 配合\n * type Status = \"all\" | \"active\" | \"archived\";\n * <SlideDownSwitcher<Status>\n * value={filter}\n * options={[\"all\", \"active\", \"archived\"]}\n * getDisplayName={(v) => ({ all: \"全部\", active: \"启用\", archived: \"归档\" }[v])}\n * onChange={setFilter}\n * />\n * ```\n */\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface SlideDownSwitcherProps<T extends string> {\n /** 当前选中的值(enum 或 string) */\n value: T;\n /** 可选项列表(如 Object.values(SomeEnum)) */\n options: readonly T[];\n /** 选项展示文案 */\n getDisplayName: (value: T) => string;\n /** 选中后回调 */\n onChange: (value: T) => void;\n status?: \"primary\" | \"default\";\n}\n\nconst SlideDownSwitcherInner = <T extends string>({ value, options, getDisplayName, onChange, status = \"primary\" }: SlideDownSwitcherProps<T>) => {\n const [isOpen, setIsOpen] = useState(false);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n const handleSelect = (option: T) => {\n onChange(option);\n setIsOpen(false);\n };\n\n return (\n <div className={styles.nbSelect} ref={wrapperRef}>\n <button\n type=\"button\"\n className={`${styles.selectButton} ${styles[status]}`}\n onClick={() => setIsOpen(!isOpen)}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n <span className={styles.buttonText}>{getDisplayName(value)}</span>\n <svg\n className={`${styles.chevronIcon} ${isOpen ? styles.open : \"\"}`}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"m6 9 6 6 6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n <div className={`${styles.optionsPanel} ${styles[status]} ${isOpen ? styles.open : styles.closed}`} role=\"listbox\">\n <ul className={styles.optionsList}>\n {options.map((option) => (\n <li\n key={option}\n className={`${styles.option} ${option === value ? styles.selected : \"\"}`}\n onClick={() => handleSelect(option)}\n role=\"option\"\n aria-selected={option === value}\n >\n <span>{getDisplayName(option)}</span>\n {option === value && (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M20 6L9 17l-5-5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </li>\n ))}\n </ul>\n </div>\n </div>\n );\n};\n\nconst SlideDownSwitcher = memo(SlideDownSwitcherInner) as typeof SlideDownSwitcherInner & {\n displayName?: string;\n};\nSlideDownSwitcher.displayName = \"SlideDownSwitcher\";\n\nexport default SlideDownSwitcher;\n","import type { ThemeEnum, ThemeSwitcherProps } from \"@/themes/types\";\n\nimport { memo } from \"react\";\n\nimport { useTheme } from \"@/themes/hooks/useTheme\";\n\nimport SlideDownSwitcher from \"../SlideDownSwitcher\";\n\nconst ThemeSwitcher = memo(({ status = \"primary\", getThemeDisplayName, handleChangeTheme }: ThemeSwitcherProps) => {\n const { themeName, setTheme, availableThemes } = useTheme();\n\n const getDisplayName = getThemeDisplayName ?? ((theme: ThemeEnum) => theme);\n\n const handleChange = (theme: ThemeEnum) => {\n setTheme(theme);\n handleChangeTheme?.(theme);\n };\n\n return <SlideDownSwitcher value={themeName} options={availableThemes} getDisplayName={getDisplayName} onChange={handleChange} status={status} />;\n});\n\nThemeSwitcher.displayName = \"ThemeSwitcher\";\n\nexport default ThemeSwitcher;\n","import type { LayoutSwitcherProps } from \"@/designs/layouts/types\";\n\nimport { memo } from \"react\";\n\nimport useLayout from \"@/designs/layouts/hooks/useLayout\";\nimport { LAYOUT_MODE_VALUES, LayoutModeEnum } from \"@/designs/layouts/types\";\n\nimport SlideDownSwitcher from \"../SlideDownSwitcher\";\n\nconst LayoutSwitcher = memo(({ status = \"primary\", getLayoutDisplayName, handleChangeLayoutMode }: LayoutSwitcherProps) => {\n const { layoutMode, setLayoutMode } = useLayout();\n\n const getDisplayName = getLayoutDisplayName ?? ((mode: LayoutModeEnum) => mode);\n\n const handleChange = (mode: LayoutModeEnum) => {\n setLayoutMode(mode);\n handleChangeLayoutMode?.(mode);\n };\n\n return <SlideDownSwitcher value={layoutMode} options={LAYOUT_MODE_VALUES} getDisplayName={getDisplayName} onChange={handleChange} status={status} />;\n});\n\nLayoutSwitcher.displayName = \"LayoutSwitcher\";\n\nexport default LayoutSwitcher;\n",".sliderContainer {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.sliderContainer.fullWidth {\n width: 100%;\n}\n\n.labelRow {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n min-height: 1.5rem;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-text);\n}\n\n.required {\n color: var(--color-danger);\n margin-left: 0.25rem;\n}\n\n.sliderWrapper {\n display: flex;\n width: 100%;\n touch-action: none;\n user-select: none;\n align-items: center;\n justify-content: center;\n gap: 0.75rem;\n}\n\n.sliderRoot {\n position: relative;\n display: flex;\n width: 100%;\n flex-grow: 1;\n cursor: grab;\n touch-action: none;\n user-select: none;\n align-items: center;\n padding: 0.75rem 0;\n}\n\n.sliderRoot:active {\n cursor: grabbing;\n}\n\n.sliderTrackWrapper {\n display: flex;\n flex-grow: 1;\n position: relative;\n}\n\n.sliderTrack {\n position: relative;\n height: 0.375rem;\n width: 100%;\n overflow: hidden;\n border-radius: var(--radius-badge);\n background-color: var(--color-bg-3);\n}\n\n.sliderRange {\n position: absolute;\n height: 100%;\n background-color: var(--color-primary);\n border-radius: var(--radius-badge);\n}\n\n.valueIndicator {\n color: var(--color-primary);\n font-size: 0.875rem;\n font-weight: 600;\n min-width: 2rem;\n text-align: center;\n flex-shrink: 0;\n line-height: 1;\n}\n\n.iconWrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.icon {\n width: 20px;\n height: 20px;\n color: var(--color-fg-muted);\n}\n\n.errorMessage {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 滑块:受控 value/onChange,支持 min/max/step、label、error、overflow 动效。Slider; controlled value/onChange, min/max/step, label, error.\n *\n * @example\n * ```tsx\n * * 基础\n * <Slider value={volume} onChange={setVolume} min={0} max={100} />\n * * 带标签与辅助文案\n * <Slider label=\"音量\" value={volume} onChange={setVolume} showValue helperText=\"0-100\" />\n * ```\n */\nimport type { ReactNode } from \"react\";\n\nimport { forwardRef, memo, useEffect, useRef, useState } from \"react\";\nimport { animate, motion, useMotionValue, useMotionValueEvent, useTransform } from \"motion/react\";\n\nimport { ChevronLeft, ChevronRight } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nconst MAX_OVERFLOW = 50;\n\nexport interface SliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 当前值。Current value. */\n value: number;\n /** 值变化回调。Change callback. */\n onChange: (value: number) => void;\n /** 最小值。Minimum. */\n min?: number;\n /** 最大值。Maximum. */\n max?: number;\n /** 步长。Step. */\n step?: number;\n /** 是否显示数值。Show value. */\n showValue?: boolean;\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n /** 标签文案。Label text. */\n label?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n /** 辅助说明。Helper text. */\n helperText?: ReactNode;\n /** 是否必填。Required. */\n required?: boolean;\n}\n\nconst Slider = memo(\n forwardRef<HTMLDivElement, SliderProps>(\n (\n {\n value: controlledValue,\n onChange,\n min = 0,\n max = 10,\n step = 1,\n showValue = true,\n fullWidth = false,\n label,\n error,\n helperText,\n required = false,\n className = \"\",\n ...props\n },\n ref,\n ) => {\n const [value, setValue] = useState<number>(controlledValue);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [region, setRegion] = useState<\"left\" | \"middle\" | \"right\">(\"middle\");\n const clientX = useMotionValue(0);\n const overflow = useMotionValue(0);\n\n useEffect(() => {\n setValue(controlledValue);\n }, [controlledValue]);\n\n useMotionValueEvent(clientX, \"change\", (latest: number) => {\n if (sliderRef.current) {\n const { left, right } = sliderRef.current.getBoundingClientRect();\n let newValue: number;\n if (latest < left) {\n setRegion(\"left\");\n newValue = left - latest;\n } else if (latest > right) {\n setRegion(\"right\");\n newValue = latest - right;\n } else {\n setRegion(\"middle\");\n newValue = 0;\n }\n overflow.jump(decay(newValue, MAX_OVERFLOW));\n }\n });\n\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.buttons > 0 && sliderRef.current) {\n const { left, width } = sliderRef.current.getBoundingClientRect();\n let newValue = min + ((e.clientX - left) / width) * (max - min);\n if (step > 0) {\n newValue = Math.round(newValue / step) * step;\n }\n newValue = Math.min(Math.max(newValue, min), max);\n setValue(newValue);\n onChange(newValue);\n clientX.jump(e.clientX);\n }\n };\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n handlePointerMove(e);\n e.currentTarget.setPointerCapture(e.pointerId);\n };\n\n const handlePointerUp = () => {\n animate(overflow, 0, { type: \"spring\", bounce: 0.5 });\n };\n\n const getRangePercentage = (): number => {\n const totalRange = max - min;\n if (totalRange === 0) return 0;\n return ((value - min) / totalRange) * 100;\n };\n\n const wrapperClasses = [styles.sliderContainer, fullWidth && styles.fullWidth, className].filter(Boolean).join(\" \");\n\n return (\n <div ref={ref} className={wrapperClasses} {...props}>\n {label && (\n <div className={styles.labelRow}>\n <label className={styles.label}>\n {label}\n {required && <span className={styles.required}>*</span>}\n </label>\n </div>\n )}\n <motion.div className={styles.sliderWrapper}>\n <motion.div\n animate={{\n scale: region === \"left\" ? [1, 1.4, 1] : 1,\n transition: { duration: 0.25 },\n }}\n style={{\n x: useTransform(() => (region === \"left\" ? -overflow.get() : 0)),\n }}\n className={styles.iconWrapper}\n >\n <ChevronLeft size={20} className={styles.icon} />\n </motion.div>\n\n <div\n ref={sliderRef}\n className={styles.sliderRoot}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n >\n <motion.div\n style={{\n scaleX: useTransform(() => {\n if (sliderRef.current) {\n const { width } = sliderRef.current.getBoundingClientRect();\n return 1 + overflow.get() / width;\n }\n return 1;\n }),\n scaleY: useTransform(overflow, [0, MAX_OVERFLOW], [1, 0.8]),\n transformOrigin: useTransform(() => {\n if (sliderRef.current) {\n const { left, width } = sliderRef.current.getBoundingClientRect();\n return clientX.get() < left + width / 2 ? \"right\" : \"left\";\n }\n return \"center\";\n }),\n }}\n className={styles.sliderTrackWrapper}\n >\n <div className={styles.sliderTrack}>\n <motion.div\n className={styles.sliderRange}\n initial={false}\n animate={{ width: `${getRangePercentage()}%` }}\n transition={{ type: \"spring\", stiffness: 300, damping: 30 }}\n />\n </div>\n </motion.div>\n </div>\n\n <motion.div\n animate={{\n scale: region === \"right\" ? [1, 1.4, 1] : 1,\n transition: { duration: 0.25 },\n }}\n style={{\n x: useTransform(() => (region === \"right\" ? overflow.get() : 0)),\n }}\n className={styles.iconWrapper}\n >\n <ChevronRight size={20} className={styles.icon} />\n </motion.div>\n {showValue && !label && <span className={styles.valueIndicator}>{Math.round(value)}</span>}\n </motion.div>\n {error && <p className={styles.errorMessage}>{error}</p>}\n {helperText && !error && <p className={styles.helperText}>{helperText}</p>}\n </div>\n );\n },\n ),\n);\n\nfunction decay(value: number, max: number): number {\n if (max === 0) {\n return 0;\n }\n const entry = value / max;\n const sigmoid = 2 * (1 / (1 + Math.exp(-entry)) - 0.5);\n return sigmoid * max;\n}\n\nSlider.displayName = \"Slider\";\n\nexport default Slider;\n",".loadingContainer {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 60vh;\r\n gap: 1.5rem;\r\n}\r\n\r\n.loadingText {\r\n color: var(--color-fg-muted);\r\n font-size: 1rem;\r\n}\r\n\r\n.errorContainer {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 60vh;\r\n gap: 2rem;\r\n padding: 3rem 2rem;\r\n text-align: center;\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.errorIconWrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 120px;\r\n height: 120px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, rgba(var(--color-error-rgb), 0.1), rgba(var(--color-error-rgb), 0.05));\r\n border: 2px solid rgba(var(--color-error-rgb), 0.2);\r\n animation: pulse 2s ease-in-out infinite;\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n 50% {\r\n transform: scale(1.05);\r\n opacity: 0.9;\r\n }\r\n}\r\n\r\n.errorIcon {\r\n color: var(--color-error);\r\n stroke-width: 1.5;\r\n}\r\n\r\n.errorContent {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1rem;\r\n max-width: 600px;\r\n width: 100%;\r\n}\r\n\r\n.errorTitle {\r\n margin: 0;\r\n font-size: 1.75rem;\r\n font-weight: 700;\r\n color: var(--color-fg-heading);\r\n letter-spacing: -0.02em;\r\n line-height: 1.2;\r\n}\r\n\r\n.errorDescription {\r\n margin: 0;\r\n color: var(--color-fg-muted);\r\n font-size: 1rem;\r\n line-height: 1.6;\r\n max-width: 480px;\r\n}\r\n\r\n.errorDetailsWrapper {\r\n width: 100%;\r\n max-width: 600px;\r\n margin-top: 0.5rem;\r\n}\r\n\r\n.errorDetailsContainer {\r\n width: 100%;\r\n text-align: left;\r\n border: 1px solid var(--color-border);\r\n border-radius: var(--radius-card);\r\n background: var(--color-bg-2);\r\n overflow: hidden;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.errorDetailsContainer:hover {\r\n border-color: var(--color-border-hover);\r\n background: var(--color-bg-3);\r\n}\r\n\r\n.errorDetailsSummary {\r\n padding: 0.875rem 1.25rem;\r\n cursor: pointer;\r\n font-size: 0.875rem;\r\n font-weight: 500;\r\n color: var(--color-fg-muted);\r\n user-select: none;\r\n list-style: none;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.errorDetailsSummary:hover {\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.errorDetailsSummary::-webkit-details-marker {\r\n display: none;\r\n}\r\n\r\n.errorDetailsSummary::before {\r\n content: \"▶\";\r\n display: inline-block;\r\n margin-right: 0.5rem;\r\n font-size: 0.75rem;\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.errorDetailsContainer[open] .errorDetailsSummary::before {\r\n transform: rotate(90deg);\r\n}\r\n\r\n.errorDetails {\r\n max-width: 100%;\r\n padding: 1rem 1.25rem;\r\n margin: 0;\r\n background: var(--color-bg-3);\r\n border-top: 1px solid var(--color-border);\r\n color: var(--color-fg-muted);\r\n font-size: 0.8125rem;\r\n font-family: \"Monaco\", \"Menlo\", \"Ubuntu Mono\", \"Consolas\", \"source-code-pro\", monospace;\r\n line-height: 1.6;\r\n overflow-x: auto;\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n.errorActions {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n margin-top: 1rem;\r\n}\r\n\r\n.retryButton {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.5rem;\r\n padding: 0.75rem 2rem;\r\n border-radius: var(--radius-button);\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border: none;\r\n cursor: pointer;\r\n font-size: 0.9375rem;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n box-shadow: 0 2px 8px var(--color-shadow);\r\n}\r\n\r\n.retryButton:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 16px var(--color-shadow);\r\n background: var(--color-primary-light);\r\n color: var(--color-primary-fg);\r\n}\r\n\r\n.retryButton:active {\r\n transform: translateY(0);\r\n box-shadow: 0 2px 8px var(--color-shadow);\r\n}\r\n\r\n.retryButtonIcon {\r\n display: inline-block;\r\n font-size: 1.125rem;\r\n line-height: 1;\r\n transition: transform 0.3s ease;\r\n}\r\n\r\n.retryButton:hover .retryButtonIcon {\r\n transform: rotate(180deg);\r\n}\r\n\r\n.clearLocalDataButton {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 0.75rem 1.5rem;\r\n border-radius: var(--radius-button);\r\n background: transparent;\r\n color: var(--color-fg-muted);\r\n border: 1px solid var(--color-border-4);\r\n cursor: pointer;\r\n font-size: 0.9375rem;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.clearLocalDataButton:hover {\r\n color: var(--color-fg-text);\r\n border-color: var(--color-border-3);\r\n background: var(--color-bg-secondary);\r\n}","import type { ReactNode } from \"react\";\n\nimport { Component } from \"react\";\n\ninterface SuspenseErrorBoundaryProps {\n children: ReactNode;\n fallbackRender: (args: { error: Error | null; retry: () => void }) => ReactNode;\n onReset?: () => void;\n}\n\ninterface SuspenseErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nclass SuspenseErrorBoundary extends Component<SuspenseErrorBoundaryProps, SuspenseErrorBoundaryState> {\n state: SuspenseErrorBoundaryState = {\n hasError: false,\n error: null,\n };\n\n static getDerivedStateFromError(error: Error): SuspenseErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error) {\n if (import.meta.env.DEV) {\n console.error(\"SuspenseErrorBoundary captured error:\", error);\n }\n }\n\n private handleReset = () => {\n this.setState({ hasError: false, error: null }, () => {\n this.props.onReset?.();\n });\n };\n\n render() {\n if (this.state.hasError) {\n return this.props.fallbackRender({ error: this.state.error, retry: this.handleReset });\n }\n\n return this.props.children;\n }\n}\n\nexport default SuspenseErrorBoundary;\n","/**\n * 统一 Suspense 包装:QueryErrorResetBoundary + 自定义 Loading/Error 样式,支持 loadingType、errorFallback。Suspense wrapper with QueryErrorResetBoundary, custom loading/error UI.\n *\n * @example\n * ```tsx\n * * 包裹懒加载内容\n * <Suspense fallback={null}>\n * <LazyPage />\n * </Suspense>\n * * 自定义 loading 类型\n * <Suspense loadingType=\"bounce\" loadingShape=\"circle\">...</Suspense>\n * ```\n */\nimport type { QueryErrorResetBoundaryProps } from \"@tanstack/react-query\";\nimport type { ReactNode, SuspenseProps as ReactSuspenseProps } from \"react\";\n\nimport { memo, Suspense as ReactSuspense } from \"react\";\nimport { QueryErrorResetBoundary } from \"@tanstack/react-query\";\n\nimport BounceLoading from \"@/designs/animations/BounceLoading\";\nimport ECGLoading from \"@/designs/animations/ECGLoading\";\nimport TruckLoading from \"@/designs/animations/TruckLoading\";\nimport { AlertCircle } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\nimport SuspenseErrorBoundary from \"./SuspenseErrorBoundary\";\n\ninterface LoadingFallbackProps {\n /** 自定义 fallback 节点。Custom fallback node. */\n fallback?: ReactNode;\n /** 加载动画类型。Loading animation type. */\n loadingType?: \"ecg\" | \"truck\" | \"bounce\";\n /** 加载图形形状。Loading shape. */\n loadingShape?: \"square\" | \"circle\";\n /** 加载中文案。Loading text. */\n loadingText?: ReactNode;\n /** 加载图尺寸。Loading size. */\n loadingSize?: \"small\" | \"medium\" | \"large\";\n /** 容器 className。Container className. */\n loadingContainerClassName?: string;\n /** 文案 className。Text className. */\n loadingTextClassName?: string;\n /** 加载图 className。Loading className. */\n loadingClassName?: string;\n}\n\ninterface ErrorFallbackProps {\n /** 错误对象。Error object. */\n error: Error | null;\n /** 重试函数。Retry function. */\n retry: () => void;\n /** 自定义错误 UI。Custom error UI. */\n errorFallback?: (args: { error: Error | null; retry: () => void }) => ReactNode;\n /** 错误标题。Error title. */\n errorTitle?: ReactNode;\n /** 错误描述。Error description. */\n errorDescription?: ReactNode;\n /** 重试按钮文案。Retry button text. */\n retryText?: ReactNode;\n /** 详情折叠文案。Error details summary text. */\n errorDetailsText?: ReactNode;\n /** 清除本地数据按钮文案。Clear local data button text. */\n clearLocalDataText?: ReactNode;\n /** 点击「清除本地数据」后执行(如跳转登录页),由调用方传入。Called after clear local data (e.g. navigate to login); pass from caller. */\n onClearLocalData?: () => void;\n /** 错误容器 className。Error container className. */\n errorContainerClassName?: string;\n /** 错误详情 className。Error details className. */\n errorDetailsClassName?: string;\n /** 是否展示错误详情。Show error details. */\n showErrorDetails?: boolean;\n}\n\nexport interface SuspenseProps extends Omit<ReactSuspenseProps, \"fallback\">, Omit<QueryErrorResetBoundaryProps, \"children\"> {\n /** 自定义 fallback。Custom fallback. */\n fallback?: ReactNode;\n /** 测试用:始终挂起。Test: always suspend. */\n test?: boolean;\n /** 加载动画类型。Loading type. */\n loadingType?: \"ecg\" | \"truck\" | \"bounce\";\n /** 加载图形形状。Loading shape. */\n loadingShape?: \"square\" | \"circle\";\n /** 加载中文案,由调用方传入。Loading text; pass from caller (e.g. i18n). */\n loadingText?: ReactNode;\n /** 加载图尺寸。Loading size. */\n loadingSize?: \"small\" | \"medium\" | \"large\";\n /** 加载容器 className。Loading container className. */\n loadingContainerClassName?: string;\n /** 加载文案 className。Loading text className. */\n loadingTextClassName?: string;\n /** 加载图 className。Loading className. */\n loadingClassName?: string;\n /** 自定义错误 UI。Custom error fallback. */\n errorFallback?: (args: { error: Error | null; retry: () => void }) => ReactNode;\n /** 错误标题,由调用方传入。Error title; pass from caller. */\n errorTitle?: ReactNode;\n /** 错误描述,由调用方传入。Error description; pass from caller. */\n errorDescription?: ReactNode;\n /** 重试按钮文案,由调用方传入。Retry text; pass from caller. */\n retryText?: ReactNode;\n /** 错误详情折叠文案。Error details text. */\n errorDetailsText?: ReactNode;\n /** 清除本地数据按钮文案。Clear local data text. */\n clearLocalDataText?: ReactNode;\n /** 点击「清除本地数据」后执行(如跳转登录页),由调用方传入。Called after clear local data (e.g. navigate to login); pass from caller. */\n onClearLocalData?: () => void;\n /** 错误容器 className。Error container className. */\n errorContainerClassName?: string;\n /** 错误详情 className。Error details className. */\n errorDetailsClassName?: string;\n /** 是否展示错误详情。Show error details. */\n showErrorDetails?: boolean;\n}\n\nconst LoadingFallback = memo(\n ({\n fallback,\n loadingType = \"ecg\",\n loadingShape = \"square\",\n loadingText = \"Loading...\",\n loadingSize = \"medium\",\n loadingContainerClassName,\n loadingTextClassName,\n loadingClassName,\n }: LoadingFallbackProps) => {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n const renderLoading = () => {\n switch (loadingType) {\n case \"ecg\":\n return <ECGLoading size={loadingSize} className={loadingClassName} />;\n case \"truck\":\n return <TruckLoading size={loadingSize} className={loadingClassName} />;\n case \"bounce\":\n return <BounceLoading size={loadingSize} shape={loadingShape} className={loadingClassName} />;\n default:\n return <ECGLoading size={loadingSize} className={loadingClassName} />;\n }\n };\n\n return (\n <div className={`${styles.loadingContainer} ${loadingContainerClassName || \"\"}`}>\n {renderLoading()}\n <p className={`${styles.loadingText} ${loadingTextClassName || \"\"}`}>{loadingText}</p>\n </div>\n );\n },\n);\n\nLoadingFallback.displayName = \"LoadingFallback\";\n\nconst ErrorFallback = memo(\n ({\n error,\n retry,\n errorFallback,\n errorTitle = \"Error\",\n errorDescription = \"Something went wrong. Please try again.\",\n retryText = \"Retry\",\n errorDetailsText = \"Details\",\n clearLocalDataText = \"Clear local data\",\n onClearLocalData,\n errorContainerClassName,\n errorDetailsClassName,\n showErrorDetails = import.meta.env.DEV,\n }: ErrorFallbackProps) => {\n const handleClearLocalData = () => {\n try {\n sessionStorage.clear();\n } catch {\n // ignore\n } finally {\n onClearLocalData?.();\n }\n };\n\n if (errorFallback) {\n return <>{errorFallback({ error, retry })}</>;\n }\n\n return (\n <div className={`${styles.errorContainer} ${errorContainerClassName || \"\"}`}>\n <div className={styles.errorIconWrapper}>\n <AlertCircle className={styles.errorIcon} size={64} />\n </div>\n <div className={styles.errorContent}>\n <h3 className={styles.errorTitle}>{errorTitle}</h3>\n <p className={styles.errorDescription}>{errorDescription}</p>\n {showErrorDetails && error && (\n <div className={styles.errorDetailsWrapper}>\n <details className={styles.errorDetailsContainer}>\n <summary className={styles.errorDetailsSummary}>{errorDetailsText}</summary>\n <pre className={`${styles.errorDetails} ${errorDetailsClassName || \"\"}`}>{error.message}</pre>\n </details>\n </div>\n )}\n <div className={styles.errorActions}>\n <button type=\"button\" className={styles.retryButton} onClick={retry}>\n <span className={styles.retryButtonIcon}>↻</span>\n <span>{retryText}</span>\n </button>\n <button type=\"button\" className={styles.clearLocalDataButton} onClick={handleClearLocalData}>\n <span>{clearLocalDataText}</span>\n </button>\n </div>\n </div>\n </div>\n );\n },\n);\n\nErrorFallback.displayName = \"ErrorFallback\";\n\nconst Suspense = memo(\n ({\n fallback,\n test,\n loadingType = \"ecg\",\n loadingShape = \"square\",\n loadingClassName,\n loadingText,\n loadingSize = \"medium\",\n loadingContainerClassName,\n loadingTextClassName,\n children,\n errorFallback,\n errorTitle,\n errorDescription,\n retryText,\n errorDetailsText,\n clearLocalDataText,\n onClearLocalData,\n errorContainerClassName,\n errorDetailsClassName,\n showErrorDetails = import.meta.env.DEV,\n ...restProps\n }: SuspenseProps) => {\n return (\n <QueryErrorResetBoundary {...restProps}>\n {({ reset }) => (\n <SuspenseErrorBoundary\n onReset={reset}\n fallbackRender={({ error, retry }) => (\n <ErrorFallback\n error={error}\n retry={retry}\n errorFallback={errorFallback}\n errorTitle={errorTitle}\n errorDescription={errorDescription}\n retryText={retryText}\n errorDetailsText={errorDetailsText}\n clearLocalDataText={clearLocalDataText}\n onClearLocalData={onClearLocalData}\n errorContainerClassName={errorContainerClassName}\n errorDetailsClassName={errorDetailsClassName}\n showErrorDetails={showErrorDetails}\n />\n )}\n >\n <ReactSuspense\n fallback={\n <LoadingFallback\n fallback={fallback}\n loadingType={loadingType}\n loadingShape={loadingShape}\n loadingText={loadingText}\n loadingSize={loadingSize}\n loadingContainerClassName={loadingContainerClassName}\n loadingTextClassName={loadingTextClassName}\n loadingClassName={loadingClassName}\n />\n }\n {...restProps}\n >\n {test ? <AlwaysPending /> : children}\n </ReactSuspense>\n </SuspenseErrorBoundary>\n )}\n </QueryErrorResetBoundary>\n );\n },\n);\n\nSuspense.displayName = \"Suspense\";\nexport default Suspense;\n\nconst AlwaysPending = () => {\n throw new Promise(() => {}); // 永不 resolve 的 Promise\n};\n",".wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.wrapper.fullWidth {\n width: 100%;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-heading);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.required {\n color: var(--color-danger);\n}\n\n.inputContainer {\n position: relative;\n display: flex;\n align-items: flex-start;\n width: 100%;\n}\n\n.textarea {\n width: 100%;\n border: 1px solid var(--color-border-4);\n border-radius: var(--radius-input);\n background: var(--color-bg);\n color: var(--color-fg-text);\n font-size: 0.875rem;\n font-family: inherit;\n transition: all 0.2s ease;\n outline: none;\n resize: vertical;\n min-height: 4rem;\n}\n\n.textarea:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);\n}\n\n.textarea::placeholder {\n color: var(--color-fg-muted);\n opacity: 0.5;\n}\n\n/* Size variants */\n.textarea.small {\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n min-height: 3rem;\n}\n\n.textarea.medium {\n padding: 0.75rem;\n font-size: 0.875rem;\n min-height: 4rem;\n}\n\n.textarea.large {\n padding: 1rem;\n font-size: 1rem;\n min-height: 5rem;\n}\n\n/* Variant styles */\n.textarea.default {\n background: var(--color-bg);\n border-color: var(--color-border-4);\n}\n\n.textarea.filled {\n background: var(--color-bg-2);\n border-color: var(--color-border-3);\n}\n\n/* With icons */\n.inputContainer .leftIcon {\n position: absolute;\n left: 0.75rem;\n top: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted);\n pointer-events: none;\n z-index: 1;\n}\n\n.inputContainer .rightIcon {\n position: absolute;\n right: 0.75rem;\n top: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted);\n pointer-events: none;\n z-index: 1;\n}\n\n.inputContainer .textarea.small + .leftIcon,\n.inputContainer .textarea.small + .rightIcon {\n top: 0.5rem;\n}\n\n.inputContainer .textarea.large + .leftIcon,\n.inputContainer .textarea.large + .rightIcon {\n top: 1rem;\n}\n\n/* Error state */\n.textarea.error {\n border-color: var(--color-danger);\n}\n\n.textarea.error:focus {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb), 0.1);\n}\n\n/* Disabled state */\n.textarea.disabled {\n background: var(--color-bg-3);\n border-color: var(--color-border-5);\n color: var(--color-fg-muted);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.errorText {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 多行文本框:支持 label、error、helperText、左右图标与 size/variant。Textarea with label, error, helperText, left/right icon.\n *\n * @example\n * ```tsx\n * * 基础用法\n * <Textarea label=\"备注\" value={note} onChange={(e) => setNote(e.target.value)} rows={4} />\n * * 错误态\n * <Textarea error={errors.note} helperText=\"选填\" />\n * ```\n */\nimport type { ReactNode, TextareaHTMLAttributes } from \"react\";\n\nimport { forwardRef } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"size\"> {\n /** 标签文案。Label text. */\n label?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n /** 辅助说明。Helper text. */\n helperText?: ReactNode;\n /** 左侧图标。Left icon. */\n leftIcon?: ReactNode;\n /** 右侧图标。Right icon. */\n rightIcon?: ReactNode;\n /** 尺寸。Size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** 视觉变体。Variant. */\n variant?: \"default\" | \"filled\";\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n}\n\nconst Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ label, error, helperText, leftIcon, rightIcon, size = \"medium\", variant = \"default\", fullWidth = false, className = \"\", disabled, ...props }, ref) => {\n const textareaClasses = [styles.textarea, styles[size], styles[variant], error && styles.error, disabled && styles.disabled, className]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperClasses = [styles.wrapper, fullWidth && styles.fullWidth].filter(Boolean).join(\" \");\n\n return (\n <div className={wrapperClasses}>\n {label && (\n <label className={styles.label}>\n {label}\n {props.required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={styles.inputContainer}>\n {leftIcon && <div className={styles.leftIcon}>{leftIcon}</div>}\n <textarea ref={ref} className={textareaClasses} disabled={disabled} {...props} />\n {rightIcon && <div className={styles.rightIcon}>{rightIcon}</div>}\n </div>\n {error && <span className={styles.errorText}>{error}</span>}\n {helperText && !error && <span className={styles.helperText}>{helperText}</span>}\n </div>\n );\n },\n);\n\nTextarea.displayName = \"Textarea\";\n\nexport default Textarea;\n","function memo(getDeps, fn, opts) {\n let deps = opts.initialDeps ?? [];\n let result;\n let isInitial = true;\n function memoizedFunction() {\n var _a, _b, _c;\n let depTime;\n if (opts.key && ((_a = opts.debug) == null ? void 0 : _a.call(opts))) depTime = Date.now();\n const newDeps = getDeps();\n const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);\n if (!depsChanged) {\n return result;\n }\n deps = newDeps;\n let resultTime;\n if (opts.key && ((_b = opts.debug) == null ? void 0 : _b.call(opts))) resultTime = Date.now();\n result = fn(...newDeps);\n if (opts.key && ((_c = opts.debug) == null ? void 0 : _c.call(opts))) {\n const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;\n const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;\n const resultFpsPercentage = resultEndTime / 16;\n const pad = (str, num) => {\n str = String(str);\n while (str.length < num) {\n str = \" \" + str;\n }\n return str;\n };\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120)\n )}deg 100% 31%);`,\n opts == null ? void 0 : opts.key\n );\n }\n if ((opts == null ? void 0 : opts.onChange) && !(isInitial && opts.skipInitialOnChange)) {\n opts.onChange(result);\n }\n isInitial = false;\n return result;\n }\n memoizedFunction.updateDeps = (newDeps) => {\n deps = newDeps;\n };\n return memoizedFunction;\n}\nfunction notUndefined(value, msg) {\n if (value === void 0) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : \"\"}`);\n } else {\n return value;\n }\n}\nconst approxEqual = (a, b) => Math.abs(a - b) < 1.01;\nconst debounce = (targetWindow, fn, ms) => {\n let timeoutId;\n return function(...args) {\n targetWindow.clearTimeout(timeoutId);\n timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);\n };\n};\nexport {\n approxEqual,\n debounce,\n memo,\n notUndefined\n};\n//# sourceMappingURL=utils.js.map\n","import { debounce, memo, notUndefined, approxEqual } from \"./utils.js\";\nconst getRect = (element) => {\n const { offsetWidth, offsetHeight } = element;\n return { width: offsetWidth, height: offsetHeight };\n};\nconst defaultKeyExtractor = (index) => index;\nconst defaultRangeExtractor = (range) => {\n const start = Math.max(range.startIndex - range.overscan, 0);\n const end = Math.min(range.endIndex + range.overscan, range.count - 1);\n const arr = [];\n for (let i = start; i <= end; i++) {\n arr.push(i);\n }\n return arr;\n};\nconst observeElementRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n const handler = (rect) => {\n const { width, height } = rect;\n cb({ width: Math.round(width), height: Math.round(height) });\n };\n handler(getRect(element));\n if (!targetWindow.ResizeObserver) {\n return () => {\n };\n }\n const observer = new targetWindow.ResizeObserver((entries) => {\n const run = () => {\n const entry = entries[0];\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize });\n return;\n }\n }\n handler(getRect(element));\n };\n instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n observer.observe(element, { box: \"border-box\" });\n return () => {\n observer.unobserve(element);\n };\n};\nconst addEventListenerOptions = {\n passive: true\n};\nconst observeWindowRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const handler = () => {\n cb({ width: element.innerWidth, height: element.innerHeight });\n };\n handler();\n element.addEventListener(\"resize\", handler, addEventListenerOptions);\n return () => {\n element.removeEventListener(\"resize\", handler);\n };\n};\nconst supportsScrollend = typeof window == \"undefined\" ? true : \"onscrollend\" in window;\nconst observeElementOffset = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n let offset = 0;\n const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(\n targetWindow,\n () => {\n cb(offset, false);\n },\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n const { horizontal, isRtl } = instance.options;\n offset = horizontal ? element[\"scrollLeft\"] * (isRtl && -1 || 1) : element[\"scrollTop\"];\n fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst observeWindowOffset = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n let offset = 0;\n const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(\n targetWindow,\n () => {\n cb(offset, false);\n },\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n offset = element[instance.options.horizontal ? \"scrollX\" : \"scrollY\"];\n fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst measureElement = (element, entry, instance) => {\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? \"inlineSize\" : \"blockSize\"]\n );\n return size;\n }\n }\n return element[instance.options.horizontal ? \"offsetWidth\" : \"offsetHeight\"];\n};\nconst windowScroll = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n const toOffset = offset + adjustments;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: toOffset,\n behavior\n });\n};\nconst elementScroll = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n const toOffset = offset + adjustments;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: toOffset,\n behavior\n });\n};\nclass Virtualizer {\n constructor(opts) {\n this.unsubs = [];\n this.scrollElement = null;\n this.targetWindow = null;\n this.isScrolling = false;\n this.scrollState = null;\n this.measurementsCache = [];\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.laneAssignments = /* @__PURE__ */ new Map();\n this.pendingMeasuredCacheIndexes = [];\n this.prevLanes = void 0;\n this.lanesChangedFlag = false;\n this.lanesSettling = false;\n this.scrollRect = null;\n this.scrollOffset = null;\n this.scrollDirection = null;\n this.scrollAdjustments = 0;\n this.elementsCache = /* @__PURE__ */ new Map();\n this.now = () => {\n var _a, _b, _c;\n return ((_c = (_b = (_a = this.targetWindow) == null ? void 0 : _a.performance) == null ? void 0 : _b.now) == null ? void 0 : _c.call(_b)) ?? Date.now();\n };\n this.observer = /* @__PURE__ */ (() => {\n let _ro = null;\n const get = () => {\n if (_ro) {\n return _ro;\n }\n if (!this.targetWindow || !this.targetWindow.ResizeObserver) {\n return null;\n }\n return _ro = new this.targetWindow.ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const run = () => {\n const node = entry.target;\n const index = this.indexFromElement(node);\n if (!node.isConnected) {\n this.observer.unobserve(node);\n return;\n }\n if (this.shouldMeasureDuringScroll(index)) {\n this.resizeItem(\n index,\n this.options.measureElement(node, entry, this)\n );\n }\n };\n this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n });\n };\n return {\n disconnect: () => {\n var _a;\n (_a = get()) == null ? void 0 : _a.disconnect();\n _ro = null;\n },\n observe: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.observe(target, { box: \"border-box\" });\n },\n unobserve: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.unobserve(target);\n }\n };\n })();\n this.range = null;\n this.setOptions = (opts2) => {\n Object.entries(opts2).forEach(([key, value]) => {\n if (typeof value === \"undefined\") delete opts2[key];\n });\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {\n },\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n gap: 0,\n indexAttribute: \"data-index\",\n initialMeasurementsCache: [],\n lanes: 1,\n isScrollingResetDelay: 150,\n enabled: true,\n isRtl: false,\n useScrollendEvent: false,\n useAnimationFrameWithResizeObserver: false,\n laneAssignmentMode: \"estimate\",\n ...opts2\n };\n };\n this.notify = (sync) => {\n var _a, _b;\n (_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);\n };\n this.maybeNotify = memo(\n () => {\n this.calculateRange();\n return [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ];\n },\n (isScrolling) => {\n this.notify(isScrolling);\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"maybeNotify\",\n debug: () => this.options.debug,\n initialDeps: [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ]\n }\n );\n this.cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d());\n this.unsubs = [];\n this.observer.disconnect();\n if (this.rafId != null && this.targetWindow) {\n this.targetWindow.cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.scrollState = null;\n this.scrollElement = null;\n this.targetWindow = null;\n };\n this._didMount = () => {\n return () => {\n this.cleanup();\n };\n };\n this._willUpdate = () => {\n var _a;\n const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;\n if (this.scrollElement !== scrollElement) {\n this.cleanup();\n if (!scrollElement) {\n this.maybeNotify();\n return;\n }\n this.scrollElement = scrollElement;\n if (this.scrollElement && \"ownerDocument\" in this.scrollElement) {\n this.targetWindow = this.scrollElement.ownerDocument.defaultView;\n } else {\n this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;\n }\n this.elementsCache.forEach((cached) => {\n this.observer.observe(cached);\n });\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect;\n this.maybeNotify();\n })\n );\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset, isScrolling) => {\n this.scrollAdjustments = 0;\n this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? \"forward\" : \"backward\" : null;\n this.scrollOffset = offset;\n this.isScrolling = isScrolling;\n if (this.scrollState) {\n this.scheduleScrollReconcile();\n }\n this.maybeNotify();\n })\n );\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: void 0,\n behavior: void 0\n });\n }\n };\n this.rafId = null;\n this.getSize = () => {\n if (!this.options.enabled) {\n this.scrollRect = null;\n return 0;\n }\n this.scrollRect = this.scrollRect ?? this.options.initialRect;\n return this.scrollRect[this.options.horizontal ? \"width\" : \"height\"];\n };\n this.getScrollOffset = () => {\n if (!this.options.enabled) {\n this.scrollOffset = null;\n return 0;\n }\n this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === \"function\" ? this.options.initialOffset() : this.options.initialOffset);\n return this.scrollOffset;\n };\n this.getFurthestMeasurement = (measurements, index) => {\n const furthestMeasurementsFound = /* @__PURE__ */ new Map();\n const furthestMeasurements = /* @__PURE__ */ new Map();\n for (let m = index - 1; m >= 0; m--) {\n const measurement = measurements[m];\n if (furthestMeasurementsFound.has(measurement.lane)) {\n continue;\n }\n const previousFurthestMeasurement = furthestMeasurements.get(\n measurement.lane\n );\n if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) {\n furthestMeasurements.set(measurement.lane, measurement);\n } else if (measurement.end < previousFurthestMeasurement.end) {\n furthestMeasurementsFound.set(measurement.lane, true);\n }\n if (furthestMeasurementsFound.size === this.options.lanes) {\n break;\n }\n }\n return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {\n if (a.end === b.end) {\n return a.index - b.index;\n }\n return a.end - b.end;\n })[0] : void 0;\n };\n this.getMeasurementOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.options.enabled,\n this.options.lanes,\n this.options.laneAssignmentMode\n ],\n (count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode) => {\n const lanesChanged = this.prevLanes !== void 0 && this.prevLanes !== lanes;\n if (lanesChanged) {\n this.lanesChangedFlag = true;\n }\n this.prevLanes = lanes;\n this.pendingMeasuredCacheIndexes = [];\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode\n };\n },\n {\n key: false\n }\n );\n this.getMeasurements = memo(\n () => [this.getMeasurementOptions(), this.itemSizeCache],\n ({\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode\n }, itemSizeCache) => {\n if (!enabled) {\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n return [];\n }\n if (this.laneAssignments.size > count) {\n for (const index of this.laneAssignments.keys()) {\n if (index >= count) {\n this.laneAssignments.delete(index);\n }\n }\n }\n if (this.lanesChangedFlag) {\n this.lanesChangedFlag = false;\n this.lanesSettling = true;\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n this.pendingMeasuredCacheIndexes = [];\n }\n if (this.measurementsCache.length === 0 && !this.lanesSettling) {\n this.measurementsCache = this.options.initialMeasurementsCache;\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache.set(item.key, item.size);\n });\n }\n const min = this.lanesSettling ? 0 : this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0;\n this.pendingMeasuredCacheIndexes = [];\n if (this.lanesSettling && this.measurementsCache.length === count) {\n this.lanesSettling = false;\n }\n const measurements = this.measurementsCache.slice(0, min);\n const laneLastIndex = new Array(lanes).fill(\n void 0\n );\n for (let m = 0; m < min; m++) {\n const item = measurements[m];\n if (item) {\n laneLastIndex[item.lane] = m;\n }\n }\n for (let i = min; i < count; i++) {\n const key = getItemKey(i);\n const cachedLane = this.laneAssignments.get(i);\n let lane;\n let start;\n const shouldCacheLane = laneAssignmentMode === \"estimate\" || itemSizeCache.has(key);\n if (cachedLane !== void 0 && this.options.lanes > 1) {\n lane = cachedLane;\n const prevIndex = laneLastIndex[lane];\n const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;\n start = prevInLane ? prevInLane.end + this.options.gap : paddingStart + scrollMargin;\n } else {\n const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);\n start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;\n lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;\n if (this.options.lanes > 1 && shouldCacheLane) {\n this.laneAssignments.set(i, lane);\n }\n }\n const measuredSize = itemSizeCache.get(key);\n const size = typeof measuredSize === \"number\" ? measuredSize : this.options.estimateSize(i);\n const end = start + size;\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane\n };\n laneLastIndex[lane] = i;\n }\n this.measurementsCache = measurements;\n return measurements;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getMeasurements\",\n debug: () => this.options.debug\n }\n );\n this.calculateRange = memo(\n () => [\n this.getMeasurements(),\n this.getSize(),\n this.getScrollOffset(),\n this.options.lanes\n ],\n (measurements, outerSize, scrollOffset, lanes) => {\n return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes\n }) : null;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"calculateRange\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualIndexes = memo(\n () => {\n let startIndex = null;\n let endIndex = null;\n const range = this.calculateRange();\n if (range) {\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n }\n this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);\n return [\n this.options.rangeExtractor,\n this.options.overscan,\n this.options.count,\n startIndex,\n endIndex\n ];\n },\n (rangeExtractor, overscan, count, startIndex, endIndex) => {\n return startIndex === null || endIndex === null ? [] : rangeExtractor({\n startIndex,\n endIndex,\n overscan,\n count\n });\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualIndexes\",\n debug: () => this.options.debug\n }\n );\n this.indexFromElement = (node) => {\n const attributeName = this.options.indexAttribute;\n const indexStr = node.getAttribute(attributeName);\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`\n );\n return -1;\n }\n return parseInt(indexStr, 10);\n };\n this.shouldMeasureDuringScroll = (index) => {\n var _a;\n if (!this.scrollState || this.scrollState.behavior !== \"smooth\") {\n return true;\n }\n const scrollIndex = this.scrollState.index ?? ((_a = this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)) == null ? void 0 : _a.index);\n if (scrollIndex !== void 0 && this.range) {\n const bufferSize = Math.max(\n this.options.overscan,\n Math.ceil((this.range.endIndex - this.range.startIndex) / 2)\n );\n const minIndex = Math.max(0, scrollIndex - bufferSize);\n const maxIndex = Math.min(\n this.options.count - 1,\n scrollIndex + bufferSize\n );\n return index >= minIndex && index <= maxIndex;\n }\n return true;\n };\n this.measureElement = (node) => {\n if (!node) {\n this.elementsCache.forEach((cached, key2) => {\n if (!cached.isConnected) {\n this.observer.unobserve(cached);\n this.elementsCache.delete(key2);\n }\n });\n return;\n }\n const index = this.indexFromElement(node);\n const key = this.options.getItemKey(index);\n const prevNode = this.elementsCache.get(key);\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode);\n }\n this.observer.observe(node);\n this.elementsCache.set(key, node);\n }\n if ((!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) {\n this.resizeItem(index, this.options.measureElement(node, void 0, this));\n }\n };\n this.resizeItem = (index, size) => {\n var _a;\n const item = this.measurementsCache[index];\n if (!item) return;\n const itemSize = this.itemSizeCache.get(item.key) ?? item.size;\n const delta = size - itemSize;\n if (delta !== 0) {\n if (((_a = this.scrollState) == null ? void 0 : _a.behavior) !== \"smooth\" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(item, delta, this) : item.start < this.getScrollOffset() + this.scrollAdjustments)) {\n if (process.env.NODE_ENV !== \"production\" && this.options.debug) {\n console.info(\"correction\", delta);\n }\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: this.scrollAdjustments += delta,\n behavior: void 0\n });\n }\n this.pendingMeasuredCacheIndexes.push(item.index);\n this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size));\n this.notify(false);\n }\n };\n this.getVirtualItems = memo(\n () => [this.getVirtualIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems = [];\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k];\n const measurement = measurements[i];\n virtualItems.push(measurement);\n }\n return virtualItems;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualItems\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualItemForOffset = (offset) => {\n const measurements = this.getMeasurements();\n if (measurements.length === 0) {\n return void 0;\n }\n return notUndefined(\n measurements[findNearestBinarySearch(\n 0,\n measurements.length - 1,\n (index) => notUndefined(measurements[index]).start,\n offset\n )]\n );\n };\n this.getMaxScrollOffset = () => {\n if (!this.scrollElement) return 0;\n if (\"scrollHeight\" in this.scrollElement) {\n return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;\n } else {\n const doc = this.scrollElement.document.documentElement;\n return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;\n }\n };\n this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {\n if (!this.scrollElement) return 0;\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n if (align === \"auto\") {\n align = toOffset >= scrollOffset + size ? \"end\" : \"start\";\n }\n if (align === \"center\") {\n toOffset += (itemSize - size) / 2;\n } else if (align === \"end\") {\n toOffset -= size;\n }\n const maxOffset = this.getMaxScrollOffset();\n return Math.max(Math.min(maxOffset, toOffset), 0);\n };\n this.getOffsetForIndex = (index, align = \"auto\") => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n const item = this.measurementsCache[index];\n if (!item) return;\n if (align === \"auto\") {\n if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {\n align = \"end\";\n } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {\n align = \"start\";\n } else {\n return [scrollOffset, align];\n }\n }\n if (align === \"end\" && index === this.options.count - 1) {\n return [this.getMaxScrollOffset(), align];\n }\n const toOffset = align === \"end\" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;\n return [\n this.getOffsetForAlignment(toOffset, align, item.size),\n align\n ];\n };\n this.scrollToOffset = (toOffset, { align = \"start\", behavior = \"auto\" } = {}) => {\n const offset = this.getOffsetForAlignment(toOffset, align);\n const now = this.now();\n this.scrollState = {\n index: null,\n align,\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0\n };\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.scheduleScrollReconcile();\n };\n this.scrollToIndex = (index, {\n align: initialAlign = \"auto\",\n behavior = \"auto\"\n } = {}) => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n const offsetInfo = this.getOffsetForIndex(index, initialAlign);\n if (!offsetInfo) {\n return;\n }\n const [offset, align] = offsetInfo;\n const now = this.now();\n this.scrollState = {\n index,\n align,\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0\n };\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.scheduleScrollReconcile();\n };\n this.scrollBy = (delta, { behavior = \"auto\" } = {}) => {\n const offset = this.getScrollOffset() + delta;\n const now = this.now();\n this.scrollState = {\n index: null,\n align: \"start\",\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0\n };\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.scheduleScrollReconcile();\n };\n this.getTotalSize = () => {\n var _a;\n const measurements = this.getMeasurements();\n let end;\n if (measurements.length === 0) {\n end = this.options.paddingStart;\n } else if (this.options.lanes === 1) {\n end = ((_a = measurements[measurements.length - 1]) == null ? void 0 : _a.end) ?? 0;\n } else {\n const endByLane = Array(this.options.lanes).fill(null);\n let endIndex = measurements.length - 1;\n while (endIndex >= 0 && endByLane.some((val) => val === null)) {\n const item = measurements[endIndex];\n if (endByLane[item.lane] === null) {\n endByLane[item.lane] = item.end;\n }\n endIndex--;\n }\n end = Math.max(...endByLane.filter((val) => val !== null));\n }\n return Math.max(\n end - this.options.scrollMargin + this.options.paddingEnd,\n 0\n );\n };\n this._scrollToOffset = (offset, {\n adjustments,\n behavior\n }) => {\n this.options.scrollToFn(offset, { behavior, adjustments }, this);\n };\n this.measure = () => {\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.laneAssignments = /* @__PURE__ */ new Map();\n this.notify(false);\n };\n this.setOptions(opts);\n }\n scheduleScrollReconcile() {\n if (!this.targetWindow) {\n this.scrollState = null;\n return;\n }\n if (this.rafId != null) return;\n this.rafId = this.targetWindow.requestAnimationFrame(() => {\n this.rafId = null;\n this.reconcileScroll();\n });\n }\n reconcileScroll() {\n if (!this.scrollState) return;\n const el = this.scrollElement;\n if (!el) return;\n const MAX_RECONCILE_MS = 5e3;\n if (this.now() - this.scrollState.startedAt > MAX_RECONCILE_MS) {\n this.scrollState = null;\n return;\n }\n const offsetInfo = this.scrollState.index != null ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align) : void 0;\n const targetOffset = offsetInfo ? offsetInfo[0] : this.scrollState.lastTargetOffset;\n const STABLE_FRAMES = 1;\n const targetChanged = targetOffset !== this.scrollState.lastTargetOffset;\n if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {\n this.scrollState.stableFrames++;\n if (this.scrollState.stableFrames >= STABLE_FRAMES) {\n this.scrollState = null;\n return;\n }\n } else {\n this.scrollState.stableFrames = 0;\n if (targetChanged) {\n this.scrollState.lastTargetOffset = targetOffset;\n this.scrollState.behavior = \"auto\";\n this._scrollToOffset(targetOffset, {\n adjustments: void 0,\n behavior: \"auto\"\n });\n }\n }\n this.scheduleScrollReconcile();\n }\n}\nconst findNearestBinarySearch = (low, high, getCurrentValue, value) => {\n while (low <= high) {\n const middle = (low + high) / 2 | 0;\n const currentValue = getCurrentValue(middle);\n if (currentValue < value) {\n low = middle + 1;\n } else if (currentValue > value) {\n high = middle - 1;\n } else {\n return middle;\n }\n }\n if (low > 0) {\n return low - 1;\n } else {\n return 0;\n }\n};\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes\n}) {\n const lastIndex = measurements.length - 1;\n const getOffset = (index) => measurements[index].start;\n if (measurements.length <= lanes) {\n return {\n startIndex: 0,\n endIndex: lastIndex\n };\n }\n let startIndex = findNearestBinarySearch(\n 0,\n lastIndex,\n getOffset,\n scrollOffset\n );\n let endIndex = startIndex;\n if (lanes === 1) {\n while (endIndex < lastIndex && measurements[endIndex].end < scrollOffset + outerSize) {\n endIndex++;\n }\n } else if (lanes > 1) {\n const endPerLane = Array(lanes).fill(0);\n while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {\n const item = measurements[endIndex];\n endPerLane[item.lane] = item.end;\n endIndex++;\n }\n const startPerLane = Array(lanes).fill(scrollOffset + outerSize);\n while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {\n const item = measurements[startIndex];\n startPerLane[item.lane] = item.start;\n startIndex--;\n }\n startIndex = Math.max(0, startIndex - startIndex % lanes);\n endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));\n }\n return { startIndex, endIndex };\n}\nexport {\n Virtualizer,\n approxEqual,\n debounce,\n defaultKeyExtractor,\n defaultRangeExtractor,\n elementScroll,\n measureElement,\n memo,\n notUndefined,\n observeElementOffset,\n observeElementRect,\n observeWindowOffset,\n observeWindowRect,\n windowScroll\n};\n//# sourceMappingURL=index.js.map\n","import * as React from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { Virtualizer, elementScroll, observeElementOffset, observeElementRect, windowScroll, observeWindowOffset, observeWindowRect } from \"@tanstack/virtual-core\";\nexport * from \"@tanstack/virtual-core\";\nconst useIsomorphicLayoutEffect = typeof document !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\nfunction useVirtualizerBase({\n useFlushSync = true,\n ...options\n}) {\n const rerender = React.useReducer(() => ({}), {})[1];\n const resolvedOptions = {\n ...options,\n onChange: (instance2, sync) => {\n var _a;\n if (useFlushSync && sync) {\n flushSync(rerender);\n } else {\n rerender();\n }\n (_a = options.onChange) == null ? void 0 : _a.call(options, instance2, sync);\n }\n };\n const [instance] = React.useState(\n () => new Virtualizer(resolvedOptions)\n );\n instance.setOptions(resolvedOptions);\n useIsomorphicLayoutEffect(() => {\n return instance._didMount();\n }, []);\n useIsomorphicLayoutEffect(() => {\n return instance._willUpdate();\n });\n return instance;\n}\nfunction useVirtualizer(options) {\n return useVirtualizerBase({\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll,\n ...options\n });\n}\nfunction useWindowVirtualizer(options) {\n return useVirtualizerBase({\n getScrollElement: () => typeof document !== \"undefined\" ? window : null,\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => typeof document !== \"undefined\" ? window.scrollY : 0,\n ...options\n });\n}\nexport {\n useVirtualizer,\n useWindowVirtualizer\n};\n//# sourceMappingURL=index.js.map\n","/* Virtual List Container */\r\n.virtualList {\r\n position: relative;\r\n overflow: auto;\r\n contain: strict;\r\n width: 100%;\r\n padding-bottom: 300px;\r\n}\r\n\r\n/* Empty State Container */\r\n.emptyContainer {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--color-fg-muted);\r\n}\r\n\r\n/* Virtual List Inner Container */\r\n.virtualListInner {\r\n width: 100%;\r\n position: relative;\r\n}\r\n\r\n/* Virtual List Items Wrapper */\r\n.virtualListItems {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n}\r\n\r\n/* Loading More Indicator */\r\n.loadingMore {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n}\r\n\r\n/* End of List Indicator */\r\n.endOfList {\r\n display: flex;\r\n justify-content: center;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n border-top: 1px solid var(--color-border-3);\r\n margin-top: 1rem;\r\n}\r\n\r\n.endOfList span {\r\n padding: 0.5rem 1rem;\r\n background-color: var(--color-bg-2);\r\n border-radius: var(--radius-button);\r\n}","/**\n * 虚拟列表:基于 @tanstack/react-virtual,支持无限滚动 fetchNextPage。Virtual list; @tanstack/react-virtual, fetchNextPage.\n *\n * @example\n * ```tsx\n * * 与 useInfiniteQuery 配合,data 为 pages 拍平后的 items\n * <VirtualList data={items} getItemKey={(i) => i.id} renderItem={(i) => <Row item={i} />} hasNextPage fetchNextPage={fetchNextPage} />\n * ```\n */\nimport type { VirtualizerOptions } from \"@tanstack/react-virtual\";\nimport type { ReactNode } from \"react\";\n\nimport { memo, useCallback, useEffect, useRef } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface VirtualListProps<T> extends Partial<\n Omit<\n VirtualizerOptions<HTMLDivElement, Element>,\n \"count\" | \"getScrollElement\" | \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"getItemKey\" | \"estimateSize\"\n >\n> {\n /** 数据列表。Data array. */\n data: T[];\n /** 是否有下一页。Has next page. */\n hasNextPage?: boolean;\n /** 是否正在拉取下一页。Is fetching next page. */\n isFetchingNextPage?: boolean;\n /** 拉取下一页。Fetch next page. */\n fetchNextPage?: () => void;\n /** 单项渲染。Render item. */\n renderItem: (item: T, index: number) => ReactNode;\n /** 单项高度估计。Estimate item size. */\n estimateSize?: number | ((index: number) => number);\n /** 列表高度。List height. */\n height?: string | number;\n /** 单项 key。Get item key. */\n getItemKey: (item: T, index: number) => string | number;\n /** 空状态自定义节点。Empty state node. */\n emptyState?: ReactNode;\n /** 加载更多指示器。Loading indicator node. */\n loadingIndicator?: ReactNode;\n /** 列表底指示器。End of list indicator node. */\n endOfListIndicator?: ReactNode;\n /** 当未提供 emptyState 时使用的文案,由调用方传入。Text when no data; used when emptyState not provided. */\n emptyText?: ReactNode;\n /** 当未提供 loadingIndicator 时使用的文案。Text when loading more. */\n loadingMoreText?: ReactNode;\n /** 当未提供 endOfListIndicator 时使用的文案。Text at end of list. */\n endOfListText?: ReactNode;\n /** 列表项容器 className。Flex container class. */\n flexClass?: string;\n /** 外层容器 className。Outer class. */\n outerClass?: string;\n /** 内层容器 className。Inner class. */\n innerClass?: string;\n}\n\nfunction VirtualListComponent<T>({\n data,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n renderItem,\n estimateSize = 200,\n overscan = 5,\n height = \"600px\",\n getItemKey,\n emptyState,\n loadingIndicator,\n endOfListIndicator,\n emptyText = \"No data\",\n loadingMoreText = \"Loading more...\",\n endOfListText = \"No more items\",\n flexClass,\n outerClass,\n innerClass,\n ...virtualizerOptions\n}: VirtualListProps<T>) {\n const parentRef = useRef<HTMLDivElement>(null);\n\n // 防御性检查:确保 data 是数组\n const safeData = Array.isArray(data) ? data : [];\n const dataLength = safeData.length;\n\n // Setup virtualizer\n // eslint-disable-next-line react-hooks/incompatible-library\n const rowVirtualizer = useVirtualizer({\n count: hasNextPage ? dataLength + 1 : dataLength,\n getScrollElement: () => parentRef.current,\n estimateSize: typeof estimateSize === \"number\" ? () => estimateSize : estimateSize,\n overscan,\n ...virtualizerOptions,\n });\n\n const items = rowVirtualizer.getVirtualItems();\n\n // Auto-fetch when scrolling near bottom (following official pattern)\n useEffect(() => {\n const [lastItem] = [...items].reverse();\n\n if (!lastItem) {\n return;\n }\n\n if (lastItem.index >= dataLength - 1 && hasNextPage && !isFetchingNextPage && fetchNextPage) {\n fetchNextPage();\n }\n }, [hasNextPage, fetchNextPage, dataLength, isFetchingNextPage, items]);\n\n const renderEmptyState = useCallback(() => {\n return (\n <div\n className={styles.virtualList}\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n }}\n >\n {emptyState ?? (\n <div className={styles.emptyContainer}>\n <span>{emptyText}</span>\n </div>\n )}\n </div>\n );\n }, [emptyState, height, emptyText]);\n\n const renderLoadingIndicator = useCallback(() => {\n if (loadingIndicator) return loadingIndicator;\n return (\n <div className={styles.loadingMore}>\n <span>{loadingMoreText}</span>\n </div>\n );\n }, [loadingIndicator, loadingMoreText]);\n\n const renderEndOfListIndicator = useCallback(() => {\n if (endOfListIndicator) return endOfListIndicator;\n return (\n <div className={styles.endOfList}>\n <span>{endOfListText}</span>\n </div>\n );\n }, [endOfListIndicator, endOfListText]);\n\n // Show empty state if no data\n if (dataLength === 0) return renderEmptyState();\n\n return (\n <div\n ref={parentRef}\n className={`${styles.virtualList} ${outerClass ?? \"\"}`}\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n }}\n >\n <div\n className={`${styles.virtualListInner} ${innerClass ?? \"\"}`}\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n }}\n >\n <div\n className={`${styles.virtualListItems} ${flexClass ?? \"\"}`}\n style={{\n transform: `translateY(${items[0]?.start ?? 0}px)`,\n paddingTop: `2px`,\n }}\n >\n {items.map((virtualRow) => {\n const isLoaderRow = virtualRow.index > dataLength - 1;\n const item = safeData[virtualRow.index];\n\n return (\n <div key={virtualRow.key} data-index={virtualRow.index} ref={rowVirtualizer.measureElement}>\n {isLoaderRow ? (\n hasNextPage ? (\n renderLoadingIndicator()\n ) : (\n renderEndOfListIndicator()\n )\n ) : (\n <div key={getItemKey(item, virtualRow.index)}>{renderItem(item, virtualRow.index)}</div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\n// Use memo with generic type\nconst VirtualList = memo(VirtualListComponent) as typeof VirtualListComponent;\nexport default VirtualList;\n","/* 外层容器 */\r\n.virtualList {\r\n width: 100%;\r\n position: relative;\r\n overflow: visible; /* ✅ window 滚动,不是列表滚动 */\r\n padding-bottom: 300px;\r\n }\r\n \r\n /* 内层:撑出总高度 */\r\n .virtualListInner {\r\n width: 100%;\r\n position: relative;\r\n }\r\n \r\n /* 基于 translateY 的内容容器 */\r\n .virtualListItems {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n }\r\n \r\n /* 行样式(你不一定用得上,但可选) */\r\n .virtualListRow {\r\n width: 100%;\r\n }\r\n \r\n /* 无数据 */\r\n .emptyContainer {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n }\r\n \r\n /* 加载中 */\r\n .loadingMore {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 1.5rem 0;\r\n color: var(--color-fg-muted);\r\n }\r\n \r\n /* 末尾提示 */\r\n .endOfList {\r\n display: flex;\r\n justify-content: center;\r\n padding: 1.5rem 0;\r\n color: var(--color-fg-muted);\r\n border-top: 1px solid var(--color-border-3);\r\n }\r\n ","/**\n * 窗口虚拟列表:基于 useWindowVirtualizer,相对视口滚动。Window virtual list; uses useWindowVirtualizer, scroll relative to viewport.\n *\n * @example\n * ```tsx\n * * 与无限列表数据配合\n * <VirtualWindowList\n * data={items}\n * getItemKey={(item) => item.id}\n * renderItem={(item) => <Row item={item} />}\n * hasNextPage={hasNextPage}\n * fetchNextPage={fetchNextPage}\n * />\n * ```\n */\nimport type { VirtualizerOptions } from \"@tanstack/react-virtual\";\nimport type { ReactNode } from \"react\";\n\nimport { memo, useCallback, useEffect } from \"react\";\nimport { useWindowVirtualizer } from \"@tanstack/react-virtual\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface VirtualWindowListProps<T> extends Partial<\n Omit<\n VirtualizerOptions<Window, Element>,\n \"count\" | \"getScrollElement\" | \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"estimateSize\" | \"getItemKey\"\n >\n> {\n /** 数据列表。Data array. */\n data: T[];\n /** 是否有下一页。Has next page. */\n hasNextPage?: boolean;\n /** 是否正在拉取下一页。Is fetching next page. */\n isFetchingNextPage?: boolean;\n /** 拉取下一页。Fetch next page. */\n fetchNextPage?: () => void;\n /** 单项渲染。Render item. */\n renderItem: (item: T, index: number) => ReactNode;\n /** 单项高度估计。Estimate item size. */\n estimateSize?: number | ((index: number) => number);\n /** 列表高度。List height. */\n height?: string | number;\n /** 单项 key。Get item key. */\n getItemKey: (item: T, index: number) => string | number;\n /** 空状态自定义节点。Empty state node. */\n emptyState?: ReactNode;\n /** 加载更多指示器。Loading indicator node. */\n loadingIndicator?: ReactNode;\n /** 列表底指示器。End of list indicator node. */\n endOfListIndicator?: ReactNode;\n /** 空状态文案(未提供 emptyState 时)。Empty text. */\n emptyText?: ReactNode;\n /** 加载更多文案。Loading more text. */\n loadingMoreText?: ReactNode;\n /** 列表底文案。End of list text. */\n endOfListText?: ReactNode;\n /** 列表项容器 className。Flex container class. */\n flexClass?: string;\n /** 外层容器 className。Outer class. */\n outerClass?: string;\n /** 内层容器 className。Inner class. */\n innerClass?: string;\n}\n\n/* -------------------------------------------\n ✅ MAIN COMPONENT\n-------------------------------------------- */\nfunction VirtualWindowListComponent<T>({\n data,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n renderItem,\n estimateSize = 200,\n overscan = 5,\n height,\n getItemKey,\n\n emptyState,\n loadingIndicator,\n endOfListIndicator,\n emptyText = \"No data\",\n loadingMoreText = \"Loading more...\",\n endOfListText = \"No more items\",\n flexClass,\n outerClass,\n innerClass,\n ...virtualizerOptions\n}: VirtualWindowListProps<T>) {\n /* ✅ 防御性检查:确保 data 是数组 */\n const safeData = Array.isArray(data) ? data : [];\n const dataLength = safeData.length;\n\n /* ✅ 真正的 window 虚拟滚动器 */\n const virtualizer = useWindowVirtualizer({\n count: hasNextPage ? dataLength + 1 : dataLength,\n estimateSize: typeof estimateSize === \"number\" ? () => estimateSize : estimateSize,\n overscan,\n ...virtualizerOptions,\n });\n\n const items = virtualizer.getVirtualItems();\n\n /* ✅ 自动加载更多 */\n useEffect(() => {\n const last = items[items.length - 1];\n if (!last) return;\n\n const isLoaderRow = last.index >= dataLength;\n\n if (isLoaderRow && hasNextPage && !isFetchingNextPage && fetchNextPage) {\n fetchNextPage();\n }\n }, [items, hasNextPage, isFetchingNextPage, fetchNextPage, dataLength]);\n\n const renderEmptyState = useCallback(() => {\n return (\n <div\n className={styles.virtualList}\n style={{\n height: typeof height === \"number\" ? `${height}px` : (height ?? \"auto\"),\n }}\n >\n {emptyState ?? (\n <div className={styles.emptyContainer}>\n <span>{emptyText}</span>\n </div>\n )}\n </div>\n );\n }, [emptyState, height, emptyText]);\n\n const renderLoadingIndicator = useCallback(() => {\n return (\n loadingIndicator ?? (\n <div className={styles.loadingMore}>\n <span>{loadingMoreText}</span>\n </div>\n )\n );\n }, [loadingIndicator, loadingMoreText]);\n\n const renderEndOfListIndicator = useCallback(() => {\n return (\n endOfListIndicator ?? (\n <div className={styles.endOfList}>\n <span>{endOfListText}</span>\n </div>\n )\n );\n }, [endOfListIndicator, endOfListText]);\n\n /* ✅ 无数据情况 */\n if (dataLength === 0) return renderEmptyState();\n\n /* ✅ 正常渲染 */\n return (\n <div className={`${styles.virtualList} ${outerClass ?? \"\"}`}>\n <div\n className={`${styles.virtualListInner} ${innerClass ?? \"\"}`}\n style={{\n height: virtualizer.getTotalSize(),\n }}\n >\n <div\n className={`${styles.virtualListItems} ${flexClass ?? \"\"}`}\n style={{\n transform: `translateY(${items[0]?.start ?? 0}px)`,\n }}\n >\n {items.map((row) => {\n const isLoaderRow = row.index >= dataLength;\n const item = safeData[row.index];\n\n return (\n <div key={row.key} data-index={row.index} ref={virtualizer.measureElement}>\n {isLoaderRow ? (\n hasNextPage ? (\n renderLoadingIndicator()\n ) : (\n renderEndOfListIndicator()\n )\n ) : item == null ? (\n <div key={`missing-${row.index}`} />\n ) : (\n <div key={getItemKey(item, row.index)}>{renderItem(item, row.index)}</div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\nconst VirtualWindowList = memo(VirtualWindowListComponent) as typeof VirtualWindowListComponent;\n\nexport default VirtualWindowList;\n"],"x_google_ignoreList":[24,25,26],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACmCA,SAAS,EAAW,GAAiB,GAA8B;AACjE,SAAK,IACD,KAAY,GAAe,CAAA,KAAS,OAAO,EAAK,QAAS,WAEpD,GAAa,GAA+C;AAAA,IAAE,GAD/C,EAAK,SAAS,OAAO,EAAK,SAAU,WAAW,EAAK,QAAQ,CAAA;AAAA,IACK,MAAM;AAAA,GAAU,IAElG,IALW;;AAQpB,IAAM,KAAS,GAAA,CAEX,EACE,SAAA,IAAU,WACV,MAAA,IAAO,UACP,WAAA,IAAY,IACZ,UAAA,GACA,WAAA,GACA,SAAA,GACA,YAAA,GACA,UAAA,IAAW,IACX,UAAA,GACA,SAAA,IAAU,IACV,UAAA,GACA,UAAA,GACA,WAAA,IAAY,IACZ,GAAG,EAAA,GAEL,MACG;AACH,QAAM,IAAW,KAAY,KAAa,KAAW,GAC/C,IAAa,CAAC,KAAY,GAC1B,IAAoB,KAAY,KAAY,CAAC,GAC7C,IAAY,KAAW,KAAc,GAErC,IAAgB;AAAA,IACpB,EAAO;AAAA,IACP,EAAO,CAAA;AAAA,IACP,EAAO,CAAA;AAAA,IACP,KAAa,EAAO;AAAA,IACpB,KAAW,EAAO;AAAA,IAClB,KAAqB,EAAO;AAAA,IAC5B;AAAA,IAEC,OAAO,OAAA,EACP,KAAK,GAAA;AAER,SAAI,IAEA,gBAAA,EAAC,UAAD;AAAA,IAAa,KAAA;AAAA,IAAK,MAAK;AAAA,IAAS,WAAW;AAAA,IAAe,UAAU,KAAY;AAAA,IAAS,GAAI;AAAA,cAC3F,gBAAA,EAAC,QAAD;AAAA,MAAM,WAAW,EAAO;AAAA,gBAAxB;AAAA,QACG,KAAW,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAU,EAAW,GAAS,CAAA;AAAA,SAAiB;AAAA,QAClF,KAAY,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAW,EAAW,GAAU,CAAA;AAAA,SAAiB;AAAA,QACrF,KAAa,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAY,EAAW,GAAW,CAAA;AAAA,SAAiB;AAAA,QACxF,KAAc,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAa,EAAW,GAAY,CAAA;AAAA,SAAiB;AAAA;;GAEvF,IAIT,IAEA,gBAAA,EAAC,UAAD;AAAA,IAAa,KAAA;AAAA,IAAK,MAAK;AAAA,IAAS,WAAW;AAAA,IAAe,UAAU,KAAY;AAAA,IAAS,GAAI;AAAA,cAA7F,CACG,KAAW,gBAAA,EAAC,QAAD,EAAM,WAAW,EAAO,QAAA,CAAW,GAC9C,CAAC,KACA,gBAAA,EAAC,QAAD;AAAA,MAAM,WAAW,EAAO;AAAA,gBAAxB;AAAA,QACG,KAAW,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAU,EAAW,GAAS,CAAA;AAAA,SAAiB;AAAA,QACnF,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAxB;AAAA,YACG,KAAY,gBAAA,EAAC,QAAD;AAAA,cAAM,WAAW,EAAO;AAAA,wBAAW,EAAW,GAAU,CAAA;AAAA,aAAiB;AAAA,YACrF,KAAc,gBAAA,EAAC,QAAD;AAAA,cAAM,WAAW,EAAO;AAAA,cAAU,UAAA;AAAA,aAAgB;AAAA,YAChE,KAAa,gBAAA,EAAC,QAAD;AAAA,cAAM,WAAW,EAAO;AAAA,wBAAY,EAAW,GAAW,CAAA;AAAA,aAAiB;AAAA;;QAE1F,KAAc,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAa,EAAW,GAAY,CAAA;AAAA,SAAiB;AAAA;;OAQpG,gBAAA,EAAC,UAAD;AAAA,IAAa,KAAA;AAAA,IAAK,MAAK;AAAA,IAAS,WAAW;AAAA,IAAe,UAAU,KAAY;AAAA,IAAS,GAAI;AAAA,cAA7F;AAAA,MACG,KAAW,gBAAA,EAAC,QAAD,EAAM,WAAW,EAAO,QAAA,CAAW;AAAA,MAC9C,KAAY,CAAC,KAAW,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,kBAAW,EAAW,GAAU,CAAA;AAAA,OAAiB;AAAA,MACjG,KAAY,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,QAAU,UAAA;AAAA,OAAgB;AAAA,MAC9D,KAAa,CAAC,KAAW,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,kBAAY,EAAW,GAAW,CAAA;AAAA,OAAiB;AAAA;;;AAM7G,GAAO,cAAc;;;;;;;;;;;;;;GE/Ef,KAAW,EAAA,CAAqB,EAAE,SAAA,GAAS,OAAA,GAAO,UAAA,GAAU,aAAA,IAAc,oBAAoB,UAAA,IAAW,IAAO,OAAA,IAAQ,IAAO,WAAA,IAAY,GAAA,MAAS;AACxJ,QAAM,CAAC,GAAQ,CAAA,IAAa,EAAS,EAAA,GAC/B,IAAc,GAAuB,IAAA;AAG3C,EAAA,EAAA,MAAgB;AACd,UAAM,IAAA,CAAsB,MAAsB;AAChD,MAAI,EAAY,WAAW,CAAC,EAAY,QAAQ,SAAS,EAAM,MAAA,KAC7D,EAAU,EAAA;AAAA;AAId,oBAAS,iBAAiB,aAAa,CAAA,GACvC,MAAa;AACX,eAAS,oBAAoB,aAAa,CAAA;AAAA;KAE3C,CAAA,CAAE;AAEL,QAAM,IAAiB,EAAQ,KAAA,CAAM,MAAW,EAAO,UAAU,CAAA,GAC3D,IAAc,IAAiB,EAAe,QAAQ,GAEtD,IAAA,CAAqB,MAAwB;AACjD,IAAA,EAAS,CAAA,GACT,EAAU,EAAA;AAAA;AAGZ,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,GAAG,EAAO,QAAA,IAAY,CAAA;AAAA,IAAa,KAAK;AAAA,cAAxD,CACE,gBAAA,EAAC,UAAD;AAAA,MACE,MAAK;AAAA,MACL,WAAW,GAAG,EAAO,cAAA,IAAkB,IAAQ,EAAO,QAAQ,EAAA,IAAM,IAAW,EAAO,WAAW,EAAA;AAAA,MACjG,SAAA,MAAe,CAAC,KAAY,EAAU,CAAC,CAAA;AAAA,MAC7B,UAAA;AAAA,MACV,iBAAe;AAAA,MACf,iBAAc;AAAA,gBANhB,CAQE,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,kBAAa;AAAA,OAAmB,GACxD,gBAAA,EAAC,IAAD;AAAA,QAAa,MAAM;AAAA,QAAI,WAAW,GAAG,EAAO,WAAA,IAAe,IAAS,EAAO,OAAO,EAAA;AAAA,OAAQ,CAAA;AAAA,QAG3F,KAAU,CAAC,KACV,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBACrB,gBAAA,EAAC,MAAD;AAAA,QAAI,WAAW,EAAO;AAAA,QAAa,MAAK;AAAA,kBACrC,EAAQ,IAAA,CAAK,MACZ,gBAAA,EAAC,MAAD;AAAA,UAEE,WAAW,GAAG,EAAO,MAAA,IAAU,EAAO,UAAU,IAAQ,EAAO,WAAW,EAAA;AAAA,UAC1E,SAAA,MAAe,EAAkB,EAAO,KAAA;AAAA,UACxC,MAAK;AAAA,UACL,iBAAe,EAAO,UAAU;AAAA,oBAE/B,EAAO;AAAA,WANH,EAAO,KAAA,CAOT;AAAA,OAEJ;AAAA,KACD,CAAA;AAAA;;AAMd,GAAS,cAAc;AClFvB,IAAM,KAAO,EAAA,CAAM,EAAE,MAAA,GAAM,GAAG,EAAA,MAAuB;AACnD,QAAM,IAAa,GAAY,CAAA;AAE/B,SAAK,IAKE,gBAAA,EAAC,GAAD,EAAY,GAAI,EAAA,CAAS,KAJ9B,QAAQ,KAAK,SAAS,CAAA,6BAAK,GACpB;;AAMX,GAAK,cAAc;;;;;;;;;;;;;;;;;;;;;;;;GEGb,KAAQ,GAAA,CAEV,EACE,OAAA,GACA,OAAA,GACA,YAAA,GACA,UAAA,GACA,WAAA,GACA,sBAAA,IAAuB,IACvB,MAAA,IAAO,UACP,SAAA,IAAU,WACV,WAAA,IAAY,IACZ,WAAA,IAAY,IACZ,UAAA,GACA,GAAG,EAAA,GAEL,MACG;AACH,QAAM,IAAe;AAAA,IAAC,EAAO;AAAA,IAAO,EAAO,CAAA;AAAA,IAAO,EAAO,CAAA;AAAA,IAAU,KAAS,EAAO;AAAA,IAAO,KAAY,EAAO;AAAA,IAAU;AAAA,IAAW,OAAO,OAAA,EAAS,KAAK,GAAA,GAEjJ,IAAiB,CAAC,EAAO,SAAS,KAAa,EAAO,SAAA,EAAW,OAAO,OAAA,EAAS,KAAK,GAAA,GAEtF,IAAmB;AAAA,IACvB,EAAO;AAAA,IACP,KAAY,EAAO;AAAA,IACnB,KAAa,EAAO;AAAA,IACpB,KAAQ,EAAO,YAAY,EAAK,OAAO,CAAA,EAAG,YAAA,IAAgB,EAAK,MAAM,CAAA,CAAE,EAAA;AAAA,IAEtE,OAAO,OAAA,EACP,KAAK,GAAA;AAER,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW;AAAA,cAAhB;AAAA,MACG,KACC,gBAAA,EAAC,SAAD;AAAA,QAAO,WAAW,EAAO;AAAA,kBAAzB,CACG,GACA,EAAM,YAAY,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAU;AAAA,SAAQ,CAAA;AAAA;MAGjE,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAW;AAAA,kBAAhB;AAAA,UACG,KAAY,gBAAA,EAAC,OAAD;AAAA,YAAK,WAAW,EAAO;AAAA,sBAAW;AAAA,WAAe;AAAA,UAC9D,gBAAA,EAAC,SAAD;AAAA,YAAY,KAAA;AAAA,YAAK,WAAW;AAAA,YAAwB,UAAA;AAAA,YAAU,GAAI;AAAA,WAAS;AAAA,UAC1E,KAAa,gBAAA,EAAC,OAAD;AAAA,YAAK,WAAW,GAAG,EAAO,SAAA,IAAa,IAAuB,EAAO,uBAAuB,EAAA;AAAA,sBAAO;AAAA,WAAgB;AAAA;;MAElI,KAAS,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAW,EAAO;AAAA,kBAAe;AAAA,OAAU;AAAA,MACvD,KAAc,CAAC,KAAS,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAW,EAAO;AAAA,kBAAa;AAAA,OAAe;AAAA;;;AAMlF,GAAM,cAAc;;;;;;;;;;;GErCd,KAAiB,EAAA,CACpB,EACC,OAAA,GACA,OAAA,GACA,UAAA,GACA,WAAA,IAAY,UACZ,gBAAA,IAAiB,OACjB,kBAAA,IAAmB,SACnB,uBAAA,IAAwB,2BACxB,iBAAA,IAAkB,cAClB,UAAA,IAAW,OACX,OAAA,EAAA,MACyB;AACzB,QAAM,IAA4B,MAAc,UAAU,IAAwB,GAC5E,CAAC,GAAY,CAAA,IAAiB,EAAyB,CAAA;AAG7D,EAAA,EAAA,MAAgB;AACd,IAAA,EAAc,CAAA;AAAA,KACb,CAAC,CAAA,CAAM;AAEV,QAAM,IAAA,MAAkB;AACtB,UAAM,IAAW,CAAC,GAAG,GAAY;AAAA,MAAE,KAAK;AAAA,MAAI,OAAO,MAAc,UAAU,CAAA,IAAK;AAAA,KAAI;AACpF,IAAA,EAAc,CAAA,GACd,EAAS,CAAA;AAAA,KAGL,IAAA,CAAgB,MAAkB;AACtC,UAAM,IAAW,EAAW,OAAA,CAAQ,GAAG,MAAM,MAAM,CAAA;AACnD,IAAA,EAAc,CAAA,GACd,EAAS,CAAA;AAAA,KAGL,IAAA,CAAmB,GAAe,MAAgB;AACtD,UAAM,IAAW,CAAC,GAAG,CAAA;AACrB,IAAA,EAAS,CAAA,IAAS;AAAA,MAAE,GAAG,EAAS,CAAA;AAAA,MAAQ,KAAA;AAAA,OACxC,EAAc,CAAA,GACd,EAAS,CAAA;AAAA,KAGL,IAAA,CAAqB,GAAe,MAAkB;AAC1D,UAAM,IAAW,CAAC,GAAG,CAAA;AACrB,QAAI,MAAc,SAAS;AAEzB,YAAM,IAAa,EAChB,MAAM,GAAA,EACN,IAAA,CAAK,MAAM,EAAE,KAAA,CAAM,EACnB,OAAA,CAAQ,MAAM,EAAE,SAAS,CAAA;AAC5B,MAAA,EAAS,CAAA,IAAS;AAAA,QAAE,GAAG,EAAS,CAAA;AAAA,QAAQ,OAAO;AAAA;UAE/C,CAAA,EAAS,CAAA,IAAS;AAAA,MAAE,GAAG,EAAS,CAAA;AAAA,MAAQ,OAAA;AAAA;AAE1C,IAAA,EAAc,CAAA,GACd,EAAS,CAAA;AAAA,KAGL,IAAA,CAAmB,MACnB,MAAM,QAAQ,CAAA,IACT,EAAM,KAAK,IAAA,IAEb;AAGT,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,cAAvB;AAAA,MACE,gBAAA,EAAC,SAAD;AAAA,QAAO,WAAW,EAAO;AAAA,kBAAQ;AAAA,OAAc;AAAA,MAC9C,KAAS,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAW,EAAO;AAAA,kBAAQ;AAAA,OAAY;AAAA,MACrD,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAW,EAAO;AAAA,kBACpB,EAAW,IAAA,CAAK,GAAM,MACrB,gBAAA,EAAC,OAAD;AAAA,UAAiB,WAAW,EAAO;AAAA,oBAAnC;AAAA,YACE,gBAAA,EAAC,IAAD;AAAA,cAAO,aAAa;AAAA,cAAgB,OAAO,EAAK;AAAA,cAAK,UAAA,CAAW,MAAM,EAAgB,GAAO,EAAE,OAAO,KAAA;AAAA,cAAQ,WAAW,EAAO;AAAA,aAAY;AAAA,YAC5I,gBAAA,EAAC,IAAD;AAAA,cACE,aAAa;AAAA,cACb,OAAO,EAAgB,EAAK,KAAA;AAAA,cAC5B,UAAA,CAAW,MAAM,EAAkB,GAAO,EAAE,OAAO,KAAA;AAAA,cACnD,WAAW,EAAO;AAAA,aAClB;AAAA,YACF,gBAAA,EAAC,IAAD;AAAA,cAAQ,MAAK;AAAA,cAAS,SAAQ;AAAA,cAAQ,SAAA,MAAe,EAAa,CAAA;AAAA,cAAQ,WAAW,EAAO;AAAA,cAAc,cAAY;AAAA,wBACpH,gBAAA,EAAC,IAAD,EAAQ,MAAM,GAAA,CAAM;AAAA,aACb;AAAA;WAVD,CAAA,CAWJ;AAAA,OAEJ;AAAA,MACN,gBAAA,EAAC,IAAD;AAAA,QAAQ,MAAK;AAAA,QAAS,SAAQ;AAAA,QAAY,SAAS;AAAA,QAAW,WAAW,EAAO;AAAA,kBAAhF,CACE,gBAAA,EAAC,IAAD,EAAM,MAAM,GAAA,CAAM,GACjB,CAAA;AAAA;;;;AAOX,GAAe,cAAc;;;;;;;GEnHvB,KAAc,EAAA,CACjB,EAAE,OAAA,GAAO,UAAA,GAAU,aAAA,GAAa,sBAAA,IAAuB,gBAAgB,WAAA,IAAY,GAAA,MAA8B;AAClH,QAAM,IAAA,MAAoB,EAAS,EAAA;AAEnC,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,GAAG,EAAO,eAAA,IAAmB,IAAY,EAAO,sBAAsB,EAAA,GAAK,KAAA;AAAA,cAA3F;AAAA,MACE,gBAAA,EAAC,IAAD;AAAA,QAAQ,MAAM;AAAA,QAAI,WAAW,EAAO;AAAA,OAAc;AAAA,MAClD,gBAAA,EAAC,SAAD;AAAA,QAAO,MAAK;AAAA,QAAc,OAAA;AAAA,QAAO,UAAA,CAAW,MAAM,EAAS,EAAE,OAAO,KAAA;AAAA,QAAqB,aAAA;AAAA,QAAa,WAAW,EAAO;AAAA,OAAe;AAAA,MACtI,KACC,gBAAA,EAAC,UAAD;AAAA,QAAQ,SAAS;AAAA,QAAa,WAAW,EAAO;AAAA,QAAU,cAAY;AAAA,kBACpE,gBAAA,EAAC,IAAD,EAAG,MAAM,GAAA,CAAM;AAAA,OACR;AAAA;;;AAOjB,GAAY,cAAc;;;;;;;;;GEDpB,KAAa,EAAA,CAChB,EACC,OAAA,GACA,UAAA,GACA,eAAA,IAAgB,aAChB,gBAAA,IAAiB,UACjB,uBAAA,IAAwB,iBACxB,wBAAA,IAAyB,kBACzB,KAAA,IAAM,OACN,MAAA,IAAO,QACP,MAAA,IAAO,OAAA,MACc;AACrB,QAAM,IAAA,MAA4B;AAChC,IAAA,EAAS;AAAA,MAAE,GAAG;AAAA,MAAO,SAAS,CAAC,EAAM;AAAA,KAAS;AAAA,KAG1C,IAAA,CAAqB,MAAgC;AACzD,IAAA,EAAS;AAAA,MAAE,GAAG;AAAA,MAAO,OAAO;AAAA,KAAa;AAAA;AAG3C,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,cAAvB,CACE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBACrB,gBAAA,EAAC,UAAD;AAAA,QACE,MAAK;AAAA,QACL,WAAW,GAAG,EAAO,YAAA,IAAgB,EAAM,UAAU,EAAO,UAAU,EAAA;AAAA,QACtE,SAAS;AAAA,QACT,cAAY,EAAM,UAAU,IAAyB;AAAA,kBAJvD,CAME,gBAAA,EAAC,IAAD,EAAQ,MAAM,GAAA,CAAM,GACpB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAM,UAAU,IAAgB,EAAA,CAAsB,CAAA;AAAA;KAE3D,GAEL,EAAM,WACL,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBAAvB;AAAA,QACE,gBAAA,EAAC,UAAD;AAAA,UAAQ,MAAK;AAAA,UAAS,WAAW,GAAG,EAAO,MAAA,IAAU,EAAM,UAAU,OAAO,EAAO,SAAS,EAAA;AAAA,UAAM,SAAA,MAAe,EAAkB,IAAA;AAAA,oBAChI;AAAA,SACM;AAAA,QACT,gBAAA,EAAC,UAAD;AAAA,UAAQ,MAAK;AAAA,UAAS,WAAW,GAAG,EAAO,MAAA,IAAU,EAAM,UAAU,KAAO,EAAO,SAAS,EAAA;AAAA,UAAM,SAAA,MAAe,EAAkB,EAAA;AAAA,oBAAnI,CACE,gBAAA,EAAC,IAAD,EAAK,MAAM,GAAA,CAAM,GACjB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAY,CAAA;AAAA;QAErB,gBAAA,EAAC,UAAD;AAAA,UAAQ,MAAK;AAAA,UAAS,WAAW,GAAG,EAAO,MAAA,IAAU,EAAM,UAAU,KAAQ,EAAO,SAAS,EAAA;AAAA,UAAM,SAAA,MAAe,EAAkB,EAAA;AAAA,oBAApI,CACE,gBAAA,EAAC,IAAD,EAAQ,MAAM,GAAA,CAAM,GACpB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAY,CAAA;AAAA;;;;;AASjC,GAAW,cAAc;;;;;;;;;;;;;;;;GErEnB,KAAA,CAA4C,EAAE,OAAA,GAAO,SAAA,GAAS,gBAAA,GAAgB,UAAA,GAAU,QAAA,IAAS,UAAA,MAA2C;AAChJ,QAAM,CAAC,GAAQ,CAAA,IAAa,EAAS,EAAA,GAC/B,IAAa,GAAuB,IAAA;AAE1C,EAAA,EAAA,MAAgB;AACd,UAAM,IAAA,CAAsB,MAAsB;AAChD,MAAI,EAAW,WAAW,CAAC,EAAW,QAAQ,SAAS,EAAM,MAAA,KAC3D,EAAU,EAAA;AAAA;AAGd,oBAAS,iBAAiB,aAAa,CAAA,GACvC,MAAa,SAAS,oBAAoB,aAAa,CAAA;AAAA,KACtD,CAAA,CAAE;AAEL,QAAM,IAAA,CAAgB,MAAc;AAClC,IAAA,EAAS,CAAA,GACT,EAAU,EAAA;AAAA;AAGZ,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,IAAU,KAAK;AAAA,cAAtC,CACE,gBAAA,EAAC,UAAD;AAAA,MACE,MAAK;AAAA,MACL,WAAW,GAAG,EAAO,YAAA,IAAgB,EAAO,CAAA,CAAA;AAAA,MAC5C,SAAA,MAAe,EAAU,CAAC,CAAA;AAAA,MAC1B,iBAAe;AAAA,MACf,iBAAc;AAAA,gBALhB,CAOE,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,kBAAa,EAAe,CAAA;AAAA,OAAc,GAClE,gBAAA,EAAC,OAAD;AAAA,QACE,WAAW,GAAG,EAAO,WAAA,IAAe,IAAS,EAAO,OAAO,EAAA;AAAA,QAC3D,OAAM;AAAA,QACN,QAAO;AAAA,QACP,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,QAAO;AAAA,QACP,aAAY;AAAA,kBAEZ,gBAAA,EAAC,QAAD;AAAA,UAAM,GAAE;AAAA,UAAe,eAAc;AAAA,UAAQ,gBAAe;AAAA,SAAU;AAAA,OAClE,CAAA;AAAA,QAGR,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,GAAG,EAAO,YAAA,IAAgB,EAAO,CAAA,CAAA,IAAW,IAAS,EAAO,OAAO,EAAO,MAAA;AAAA,MAAU,MAAK;AAAA,gBACvG,gBAAA,EAAC,MAAD;AAAA,QAAI,WAAW,EAAO;AAAA,kBACnB,EAAQ,IAAA,CAAK,MACZ,gBAAA,EAAC,MAAD;AAAA,UAEE,WAAW,GAAG,EAAO,MAAA,IAAU,MAAW,IAAQ,EAAO,WAAW,EAAA;AAAA,UACpE,SAAA,MAAe,EAAa,CAAA;AAAA,UAC5B,MAAK;AAAA,UACL,iBAAe,MAAW;AAAA,oBAL5B,CAOE,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAe,CAAA,EAAO,CAAQ,GACpC,MAAW,KACV,gBAAA,EAAC,OAAD;AAAA,YAAK,OAAM;AAAA,YAAK,QAAO;AAAA,YAAK,SAAQ;AAAA,YAAY,MAAK;AAAA,YAAO,QAAO;AAAA,YAAe,aAAY;AAAA,sBAC5F,gBAAA,EAAC,QAAD;AAAA,cAAM,GAAE;AAAA,cAAkB,eAAc;AAAA,cAAQ,gBAAe;AAAA,aAAU;AAAA,WACrE,CAAA;AAAA,WAVH,CAAA,CAYF;AAAA,OAEJ;AAAA,KACD,CAAA;AAAA;GAKN,KAAoB,EAAK,EAAA;AAG/B,GAAkB,cAAc;AC5FhC,IAAM,KAAgB,EAAA,CAAM,EAAE,QAAA,IAAS,WAAW,qBAAA,GAAqB,mBAAA,EAAA,MAA4C;AACjH,QAAM,EAAE,WAAA,GAAW,UAAA,GAAU,iBAAA,EAAA,IAAoB,GAAA;AASjD,SAAO,gBAAA,EAAC,IAAD;AAAA,IAAmB,OAAO;AAAA,IAAW,SAAS;AAAA,IAAiC,gBAP/D,MAAA,CAAyB,MAAqB;AAAA,IAOiC,UALhG,CAAgB,MAAqB;AACzC,MAAA,EAAS,CAAA,GACT,IAAoB,CAAA;AAAA;IAGgH,QAAA;AAAA,GAAU;;AAGlJ,GAAc,cAAc;ACZ5B,IAAM,KAAiB,EAAA,CAAM,EAAE,QAAA,IAAS,WAAW,sBAAA,GAAsB,wBAAA,EAAA,MAAkD;AACzH,QAAM,EAAE,YAAA,GAAY,eAAA,EAAA,IAAkB,GAAA;AAStC,SAAO,gBAAA,EAAC,IAAD;AAAA,IAAmB,OAAO;AAAA,IAAY,SAAS;AAAA,IAAoC,gBAPnE,MAAA,CAA0B,MAAyB;AAAA,IAOgC,UALpG,CAAgB,MAAyB;AAC7C,MAAA,EAAc,CAAA,GACd,IAAyB,CAAA;AAAA;IAG+G,QAAA;AAAA,GAAU;;AAGtJ,GAAe,cAAc;;;;;;;;;;;;;;;;;GEFvB,KAAe,IA2Bf,KAAS,EACb,GAAA,CAEI,EACE,OAAO,GACP,UAAA,GACA,KAAA,IAAM,GACN,KAAA,IAAM,IACN,MAAA,IAAO,GACP,WAAA,IAAY,IACZ,WAAA,IAAY,IACZ,OAAA,GACA,OAAA,GACA,YAAA,GACA,UAAA,IAAW,IACX,WAAA,IAAY,IACZ,GAAG,EAAA,GAEL,MACG;AACH,QAAM,CAAC,GAAO,CAAA,IAAY,EAAiB,CAAA,GACrC,IAAY,GAAuB,IAAA,GACnC,CAAC,GAAQ,CAAA,IAAa,EAAsC,QAAA,GAC5D,IAAU,GAAe,CAAA,GACzB,IAAW,GAAe,CAAA;AAEhC,EAAA,EAAA,MAAgB;AACd,IAAA,EAAS,CAAA;AAAA,KACR,CAAC,CAAA,CAAgB,GAEpB,GAAoB,GAAS,UAAA,CAAW,MAAmB;AACzD,QAAI,EAAU,SAAS;AACrB,YAAM,EAAE,MAAA,GAAM,OAAA,EAAA,IAAU,EAAU,QAAQ,sBAAA;AAC1C,UAAI;AACJ,MAAI,IAAS,KACX,EAAU,MAAA,GACV,IAAW,IAAO,KACT,IAAS,KAClB,EAAU,OAAA,GACV,IAAW,IAAS,MAEpB,EAAU,QAAA,GACV,IAAW,IAEb,EAAS,KAAK,GAAM,GAAU,EAAA,CAAa;AAAA;;AAI/C,QAAM,IAAA,CAAqB,MAA0C;AACnE,QAAI,EAAE,UAAU,KAAK,EAAU,SAAS;AACtC,YAAM,EAAE,MAAA,GAAM,OAAA,EAAA,IAAU,EAAU,QAAQ,sBAAA;AAC1C,UAAI,IAAW,KAAQ,EAAE,UAAU,KAAQ,KAAU,IAAM;AAC3D,MAAI,IAAO,MACT,IAAW,KAAK,MAAM,IAAW,CAAA,IAAQ,IAE3C,IAAW,KAAK,IAAI,KAAK,IAAI,GAAU,CAAA,GAAM,CAAA,GAC7C,EAAS,CAAA,GACT,EAAS,CAAA,GACT,EAAQ,KAAK,EAAE,OAAA;AAAA;KAIb,IAAA,CAAqB,MAA0C;AACnE,IAAA,EAAkB,CAAA,GAClB,EAAE,cAAc,kBAAkB,EAAE,SAAA;AAAA,KAGhC,IAAA,MAAwB;AAC5B,IAAA,GAAQ,GAAU,GAAG;AAAA,MAAE,MAAM;AAAA,MAAU,QAAQ;AAAA,KAAK;AAAA,KAGhD,IAAA,MAAmC;AACvC,UAAM,IAAa,IAAM;AACzB,WAAI,MAAe,IAAU,KACpB,IAAQ,KAAO,IAAc;AAAA;AAKxC,SACE,gBAAA,EAAC,OAAD;AAAA,IAAU,KAAA;AAAA,IAAK,WAHM;AAAA,MAAC,EAAO;AAAA,MAAiB,KAAa,EAAO;AAAA,MAAW;AAAA,MAAW,OAAO,OAAA,EAAS,KAAK,GAAA;AAAA,IAGnE,GAAI;AAAA,cAA9C;AAAA,MACG,KACC,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAW,EAAO;AAAA,kBACrB,gBAAA,EAAC,SAAD;AAAA,UAAO,WAAW,EAAO;AAAA,oBAAzB,CACG,GACA,KAAY,gBAAA,EAAC,QAAD;AAAA,YAAM,WAAW,EAAO;AAAA,sBAAU;AAAA,WAAQ,CAAA;AAAA;OAErD;AAAA,MAER,gBAAA,EAAC,EAAO,KAAR;AAAA,QAAY,WAAW,EAAO;AAAA,kBAA9B;AAAA,UACE,gBAAA,EAAC,EAAO,KAAR;AAAA,YACE,SAAS;AAAA,cACP,OAAO,MAAW,SAAS;AAAA,gBAAC;AAAA,gBAAG;AAAA,gBAAK;AAAA,kBAAK;AAAA,cACzC,YAAY,EAAE,UAAU,KAAA;AAAA;YAE1B,OAAO,EACL,GAAG,EAAA,MAAoB,MAAW,SAAS,CAAC,EAAS,IAAA,IAAQ,CAAA,EAAG;AAAA,YAElE,WAAW,EAAO;AAAA,sBAElB,gBAAA,EAAC,IAAD;AAAA,cAAa,MAAM;AAAA,cAAI,WAAW,EAAO;AAAA,aAAQ;AAAA,WACtC;AAAA,UAEb,gBAAA,EAAC,OAAD;AAAA,YACE,KAAK;AAAA,YACL,WAAW,EAAO;AAAA,YAClB,eAAe;AAAA,YACf,eAAe;AAAA,YACf,aAAa;AAAA,sBAEb,gBAAA,EAAC,EAAO,KAAR;AAAA,cACE,OAAO;AAAA,gBACL,QAAQ,EAAA,MAAmB;AACzB,sBAAI,EAAU,SAAS;AACrB,0BAAM,EAAE,OAAA,EAAA,IAAU,EAAU,QAAQ,sBAAA;AACpC,2BAAO,IAAI,EAAS,IAAA,IAAQ;AAAA;AAE9B,yBAAO;AAAA;gBAET,QAAQ,EAAa,GAAU,CAAC,GAAG,EAAA,GAAe,CAAC,GAAG,GAAA,CAAI;AAAA,gBAC1D,iBAAiB,EAAA,MAAmB;AAClC,sBAAI,EAAU,SAAS;AACrB,0BAAM,EAAE,MAAA,GAAM,OAAA,EAAA,IAAU,EAAU,QAAQ,sBAAA;AAC1C,2BAAO,EAAQ,IAAA,IAAQ,IAAO,IAAQ,IAAI,UAAU;AAAA;AAEtD,yBAAO;AAAA;;cAGX,WAAW,EAAO;AAAA,wBAElB,gBAAA,EAAC,OAAD;AAAA,gBAAK,WAAW,EAAO;AAAA,0BACrB,gBAAA,EAAC,EAAO,KAAR;AAAA,kBACE,WAAW,EAAO;AAAA,kBAClB,SAAS;AAAA,kBACT,SAAS,EAAE,OAAO,GAAG,EAAA,CAAoB,IAAC;AAAA,kBAC1C,YAAY;AAAA,oBAAE,MAAM;AAAA,oBAAU,WAAW;AAAA,oBAAK,SAAS;AAAA;iBACvD;AAAA,eACE;AAAA,aACK;AAAA,WACT;AAAA,UAEN,gBAAA,EAAC,EAAO,KAAR;AAAA,YACE,SAAS;AAAA,cACP,OAAO,MAAW,UAAU;AAAA,gBAAC;AAAA,gBAAG;AAAA,gBAAK;AAAA,kBAAK;AAAA,cAC1C,YAAY,EAAE,UAAU,KAAA;AAAA;YAE1B,OAAO,EACL,GAAG,EAAA,MAAoB,MAAW,UAAU,EAAS,IAAA,IAAQ,CAAA,EAAG;AAAA,YAElE,WAAW,EAAO;AAAA,sBAElB,gBAAA,EAAC,IAAD;AAAA,cAAc,MAAM;AAAA,cAAI,WAAW,EAAO;AAAA,aAAQ;AAAA,WACvC;AAAA,UACZ,KAAa,CAAC,KAAS,gBAAA,EAAC,QAAD;AAAA,YAAM,WAAW,EAAO;AAAA,sBAAiB,KAAK,MAAM,CAAA;AAAA,WAAc;AAAA;;MAE3F,KAAS,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAW,EAAO;AAAA,kBAAe;AAAA,OAAU;AAAA,MACvD,KAAc,CAAC,KAAS,gBAAA,EAAC,KAAD;AAAA,QAAG,WAAW,EAAO;AAAA,kBAAa;AAAA,OAAe;AAAA;;EAIjF;AAGH,SAAS,GAAM,GAAe,GAAqB;AACjD,MAAI,MAAQ,EACV,QAAO;AAET,QAAM,IAAQ,IAAQ;AAEtB,SADgB,KAAK,KAAK,IAAI,KAAK,IAAI,CAAC,CAAA,KAAU,OACjC;;AAGnB,GAAO,cAAc;;;;;;;;;;;;;;;;;;;GE5Mf,KAAN,cAAoC,GAAkE;AAAA,EACpG,QAAoC;AAAA,IAClC,UAAU;AAAA,IACV,OAAO;AAAA;EAGT,OAAO,yBAAyB,GAA0C;AACxE,WAAO;AAAA,MAAE,UAAU;AAAA,MAAM,OAAA;AAAA;;EAG3B,kBAAkB,GAAc;AAAA,EAAA;AAAA,EAMhC,cAAA,MAA4B;AAC1B,SAAK,SAAS;AAAA,MAAE,UAAU;AAAA,MAAO,OAAO;AAAA,OAAM,MAAQ;AACpD,WAAK,MAAM,UAAA;AAAA;;EAIf,SAAS;AACP,WAAI,KAAK,MAAM,WACN,KAAK,MAAM,eAAe;AAAA,MAAE,OAAO,KAAK,MAAM;AAAA,MAAO,OAAO,KAAK;AAAA,KAAa,IAGhF,KAAK,MAAM;AAAA;GCwEhB,KAAkB,EAAA,CACrB,EACC,UAAA,GACA,aAAA,IAAc,OACd,cAAA,IAAe,UACf,aAAA,IAAc,cACd,aAAA,IAAc,UACd,2BAAA,GACA,sBAAA,GACA,kBAAA,EAAA,MAC0B;AAC1B,MAAI,EACF,QAAO,gBAAA,EAAA,IAAA,EAAA,UAAG,EAAA,CAAY;AAGxB,QAAM,IAAA,MAAsB;AAC1B,YAAQ,GAAR;AAAA,MACE,KAAK;AACH,eAAO,gBAAA,EAAC,IAAD;AAAA,UAAY,MAAM;AAAA,UAAa,WAAW;AAAA,SAAoB;AAAA,MACvE,KAAK;AACH,eAAO,gBAAA,EAAC,IAAD;AAAA,UAAc,MAAM;AAAA,UAAa,WAAW;AAAA,SAAoB;AAAA,MACzE,KAAK;AACH,eAAO,gBAAA,EAAC,IAAD;AAAA,UAAe,MAAM;AAAA,UAAa,OAAO;AAAA,UAAc,WAAW;AAAA,SAAoB;AAAA,MAC/F;AACE,eAAO,gBAAA,EAAC,IAAD;AAAA,UAAY,MAAM;AAAA,UAAa,WAAW;AAAA,SAAoB;AAAA;;AAI3E,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,GAAG,EAAO,gBAAA,IAAoB,KAA6B,EAAA;AAAA,cAA3E,CACG,EAAA,GACD,gBAAA,EAAC,KAAD;AAAA,MAAG,WAAW,GAAG,EAAO,WAAA,IAAe,KAAwB,EAAA;AAAA,gBAAO;AAAA,KAAgB,CAAA;AAAA;;AAM9F,GAAgB,cAAc;AAE9B,IAAM,KAAgB,EAAA,CACnB,EACC,OAAA,GACA,OAAA,GACA,eAAA,GACA,YAAA,IAAa,SACb,kBAAA,IAAmB,2CACnB,WAAA,IAAY,SACZ,kBAAA,IAAmB,WACnB,oBAAA,IAAqB,oBACrB,kBAAA,GACA,yBAAA,GACA,uBAAA,GACA,kBAAA,IAAA,GAAA,MACwB;AACxB,QAAM,IAAA,MAA6B;AACjC,QAAI;AACF,qBAAe,MAAA;AAAA,YACT;AAAA,IAAA,UAAA;AAGN,MAAA,IAAA;AAAA;;AAIJ,SAAI,IACK,gBAAA,EAAA,IAAA,EAAA,UAAG,EAAc;AAAA,IAAE,OAAA;AAAA,IAAO,OAAA;AAAA,GAAO,EAAC,CAAI,IAI7C,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,GAAG,EAAO,cAAA,IAAkB,KAA2B,EAAA;AAAA,cAAvE,CACE,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBACrB,gBAAA,EAAC,IAAD;AAAA,QAAa,WAAW,EAAO;AAAA,QAAW,MAAM;AAAA,OAAM;AAAA,KAClD,GACN,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBAAvB;AAAA,QACE,gBAAA,EAAC,MAAD;AAAA,UAAI,WAAW,EAAO;AAAA,oBAAa;AAAA,SAAgB;AAAA,QACnD,gBAAA,EAAC,KAAD;AAAA,UAAG,WAAW,EAAO;AAAA,oBAAmB;AAAA,SAAqB;AAAA,QAC5D,KAAoB,KACnB,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAW,EAAO;AAAA,oBACrB,gBAAA,EAAC,WAAD;AAAA,YAAS,WAAW,EAAO;AAAA,sBAA3B,CACE,gBAAA,EAAC,WAAD;AAAA,cAAS,WAAW,EAAO;AAAA,wBAAsB;AAAA,aAA2B,GAC5E,gBAAA,EAAC,OAAD;AAAA,cAAK,WAAW,GAAG,EAAO,YAAA,IAAgB,KAAyB,EAAA;AAAA,wBAAO,EAAM;AAAA,aAAc,CAAA;AAAA;SAE5F;AAAA,QAER,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAW,EAAO;AAAA,oBAAvB,CACE,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAW,EAAO;AAAA,YAAa,SAAS;AAAA,sBAA9D,CACE,gBAAA,EAAC,QAAD;AAAA,cAAM,WAAW,EAAO;AAAA,wBAAiB;AAAA,aAAQ,GACjD,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAiB,CAAA;AAAA,cAE1B,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAW,EAAO;AAAA,YAAsB,SAAS;AAAA,sBACrE,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAA0B;AAAA,WAC1B,CAAA;AAAA;;;;;AAQrB,GAAc,cAAc;AAE5B,IAAM,KAAW,EAAA,CACd,EACC,UAAA,GACA,MAAA,GACA,aAAA,IAAc,OACd,cAAA,IAAe,UACf,kBAAA,GACA,aAAA,GACA,aAAA,IAAc,UACd,2BAAA,GACA,sBAAA,GACA,UAAA,GACA,eAAA,GACA,YAAA,GACA,kBAAA,GACA,WAAA,GACA,kBAAA,GACA,oBAAA,GACA,kBAAA,GACA,yBAAA,GACA,uBAAA,GACA,kBAAA,IAAA,IACA,GAAG,EAAA,MAGD,gBAAA,EAAC,IAAD;AAAA,EAAyB,GAAI;AAAA,aACzB,EAAE,OAAA,EAAA,MACF,gBAAA,EAAC,IAAD;AAAA,IACE,SAAS;AAAA,IACT,gBAAA,CAAiB,EAAE,OAAA,GAAO,OAAA,EAAA,MACxB,gBAAA,EAAC,IAAD;AAAA,MACS,OAAA;AAAA,MACA,OAAA;AAAA,MACQ,eAAA;AAAA,MACH,YAAA;AAAA,MACM,kBAAA;AAAA,MACP,WAAA;AAAA,MACO,kBAAA;AAAA,MACE,oBAAA;AAAA,MACF,kBAAA;AAAA,MACO,yBAAA;AAAA,MACF,uBAAA;AAAA,MACL,kBAAA;AAAA,KAClB;AAAA,cAGJ,gBAAA,EAAC,IAAD;AAAA,MACE,UACE,gBAAA,EAAC,IAAD;AAAA,QACY,UAAA;AAAA,QACG,aAAA;AAAA,QACC,cAAA;AAAA,QACD,aAAA;AAAA,QACA,aAAA;AAAA,QACc,2BAAA;AAAA,QACL,sBAAA;AAAA,QACJ,kBAAA;AAAA,OAClB;AAAA,MAEJ,GAAI;AAAA,gBAEH,IAAO,gBAAA,EAAC,IAAD,CAAA,CAAiB,IAAG;AAAA,KACd;AAAA,GACM;CAEF;AAKhC,GAAS,cAAc;AAGvB,IAAM,KAAA,MAAsB;AAC1B,QAAM,IAAI,QAAA,MAAc;AAAA,EAAA,CAAA;;;;;;;;;;;;;;;;;;;GE7PpB,KAAW,GAAA,CACd,EAAE,OAAA,GAAO,OAAA,GAAO,YAAA,GAAY,UAAA,GAAU,WAAA,GAAW,MAAA,IAAO,UAAU,SAAA,IAAU,WAAW,WAAA,IAAY,IAAO,WAAA,IAAY,IAAI,UAAA,GAAU,GAAG,EAAA,GAAS,MAAQ;AACvJ,QAAM,IAAkB;AAAA,IAAC,EAAO;AAAA,IAAU,EAAO,CAAA;AAAA,IAAO,EAAO,CAAA;AAAA,IAAU,KAAS,EAAO;AAAA,IAAO,KAAY,EAAO;AAAA,IAAU;AAAA,IAC1H,OAAO,OAAA,EACP,KAAK,GAAA;AAIR,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAHgB,CAAC,EAAO,SAAS,KAAa,EAAO,SAAA,EAAW,OAAO,OAAA,EAAS,KAAK,GAAA;AAAA,cAG1F;AAAA,MACG,KACC,gBAAA,EAAC,SAAD;AAAA,QAAO,WAAW,EAAO;AAAA,kBAAzB,CACG,GACA,EAAM,YAAY,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAW,EAAO;AAAA,oBAAU;AAAA,SAAQ,CAAA;AAAA;MAGjE,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAW,EAAO;AAAA,kBAAvB;AAAA,UACG,KAAY,gBAAA,EAAC,OAAD;AAAA,YAAK,WAAW,EAAO;AAAA,sBAAW;AAAA,WAAe;AAAA,UAC9D,gBAAA,EAAC,YAAD;AAAA,YAAe,KAAA;AAAA,YAAK,WAAW;AAAA,YAA2B,UAAA;AAAA,YAAU,GAAI;AAAA,WAAS;AAAA,UAChF,KAAa,gBAAA,EAAC,OAAD;AAAA,YAAK,WAAW,EAAO;AAAA,sBAAY;AAAA,WAAgB;AAAA;;MAElE,KAAS,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,kBAAY;AAAA,OAAa;AAAA,MAC1D,KAAc,CAAC,KAAS,gBAAA,EAAC,QAAD;AAAA,QAAM,WAAW,EAAO;AAAA,kBAAa;AAAA,OAAkB;AAAA;;;AAMxF,GAAS,cAAc;AChEvB,SAASA,EAAK,GAAS,GAAI,GAAM;AAC/B,MAAI,IAAO,EAAK,eAAe,CAAA,GAC3B,GACA,IAAY;AAChB,WAAS,IAAmB;AAC1B,QAAI,GAAI,GAAI;AACZ,QAAI;AACJ,IAAI,EAAK,SAAS,IAAK,EAAK,UAAU,QAAgB,EAAG,KAAK,CAAA,OAAQ,IAAU,KAAK,IAAA;AACrF,UAAM,IAAU,EAAA;AAEhB,QAAI,EADgB,EAAQ,WAAW,EAAK,UAAU,EAAQ,KAAA,CAAM,GAAK,MAAU,EAAK,CAAA,MAAW,CAAA,GAEjG,QAAO;AAET,IAAA,IAAO;AACP,QAAI;AAGJ,QAFI,EAAK,SAAS,IAAK,EAAK,UAAU,QAAgB,EAAG,KAAK,CAAA,OAAQ,IAAa,KAAK,IAAA,IACxF,IAAS,EAAG,GAAG,CAAA,GACX,EAAK,SAAS,IAAK,EAAK,UAAU,QAAgB,EAAG,KAAK,CAAA,IAAQ;AACpE,YAAM,IAAa,KAAK,OAAO,KAAK,IAAA,IAAQ,KAAW,GAAA,IAAO,KACxD,IAAgB,KAAK,OAAO,KAAK,IAAA,IAAQ,KAAc,GAAA,IAAO,KAC9D,IAAsB,IAAgB,IACtC,IAAA,CAAO,GAAK,MAAQ;AAExB,aADA,IAAM,OAAO,CAAA,GACN,EAAI,SAAS,IAClB,CAAA,IAAM,MAAM;AAEd,eAAO;AAAA;AAET,cAAQ,KACN,OAAO,EAAI,GAAe,CAAA,CAAE,KAAK,EAAI,GAAY,CAAA,CAAE,OACnD;AAAA;AAAA;AAAA,yBAGiB,KAAK,IACpB,GACA,KAAK,IAAI,MAAM,MAAM,GAAqB,GAAA,CAAI,CAC/C,kBACuB,GAAK,GAAA;AAAA;AAGjC,WAA6B,GAAK,YAAa,EAAE,KAAa,EAAK,wBACjE,EAAK,SAAS,CAAA,GAEhB,IAAY,IACL;AAAA;AAET,SAAA,EAAiB,aAAA,CAAc,MAAY;AACzC,IAAA,IAAO;AAAA,KAEF;;AAET,SAAS,GAAa,GAAO,GAAK;AAChC,MAAI,MAAU,OACZ,OAAM,IAAI,MAAM,uBAAuB,IAAM,KAAK,CAAA,KAAQ,EAAA,EAAA;AAE1D,SAAO;;AAGX,IAAM,KAAA,CAAe,GAAG,MAAM,KAAK,IAAI,IAAI,CAAA,IAAK,MAC1C,KAAA,CAAY,GAAc,GAAI,MAAO;AACzC,MAAI;AACJ,SAAO,YAAY,GAAM;AACvB,IAAA,EAAa,aAAa,CAAA,GAC1B,IAAY,EAAa,WAAA,MAAiB,EAAG,MAAM,MAAM,CAAA,GAAO,CAAA;AAAA;GC9D9D,KAAA,CAAW,MAAY;AAC3B,QAAM,EAAE,aAAA,GAAa,cAAA,EAAA,IAAiB;AACtC,SAAO;AAAA,IAAE,OAAO;AAAA,IAAa,QAAQ;AAAA;GAEjC,KAAA,CAAuB,MAAU,GACjC,KAAA,CAAyB,MAAU;AACvC,QAAM,IAAQ,KAAK,IAAI,EAAM,aAAa,EAAM,UAAU,CAAA,GACpD,IAAM,KAAK,IAAI,EAAM,WAAW,EAAM,UAAU,EAAM,QAAQ,CAAA,GAC9D,IAAM,CAAA;AACZ,WAAS,IAAI,GAAO,KAAK,GAAK,IAC5B,CAAA,EAAI,KAAK,CAAA;AAEX,SAAO;GAEH,KAAA,CAAsB,GAAU,MAAO;AAC3C,QAAM,IAAU,EAAS;AACzB,MAAI,CAAC,EACH;AAEF,QAAM,IAAe,EAAS;AAC9B,MAAI,CAAC,EACH;AAEF,QAAM,IAAA,CAAW,MAAS;AACxB,UAAM,EAAE,OAAA,GAAO,QAAA,EAAA,IAAW;AAC1B,IAAA,EAAG;AAAA,MAAE,OAAO,KAAK,MAAM,CAAA;AAAA,MAAQ,QAAQ,KAAK,MAAM,CAAA;AAAA,KAAS;AAAA;AAG7D,MADA,EAAQ,GAAQ,CAAA,CAAQ,GACpB,CAAC,EAAa,eAChB,QAAA,MAAa;AAAA,EAAA;AAGf,QAAM,IAAW,IAAI,EAAa,eAAA,CAAgB,MAAY;AAC5D,UAAM,IAAA,MAAY;AAChB,YAAM,IAAQ,EAAQ,CAAA;AACtB,UAA6B,GAAM,eAAe;AAChD,cAAM,IAAM,EAAM,cAAc,CAAA;AAChC,YAAI,GAAK;AACP,UAAA,EAAQ;AAAA,YAAE,OAAO,EAAI;AAAA,YAAY,QAAQ,EAAI;AAAA,WAAW;AACxD;AAAA;;AAGJ,MAAA,EAAQ,GAAQ,CAAA,CAAQ;AAAA;AAE1B,IAAA,EAAS,QAAQ,sCAAsC,sBAAsB,CAAA,IAAO,EAAA;AAAA;AAEtF,SAAA,EAAS,QAAQ,GAAS,EAAE,KAAK,aAAA,CAAc,GAC/C,MAAa;AACX,IAAA,EAAS,UAAU,CAAA;AAAA;GAGjB,IAA0B,EAC9B,SAAS,GAAA,GAEL,KAAA,CAAqB,GAAU,MAAO;AAC1C,QAAM,IAAU,EAAS;AACzB,MAAI,CAAC,EACH;AAEF,QAAM,IAAA,MAAgB;AACpB,IAAA,EAAG;AAAA,MAAE,OAAO,EAAQ;AAAA,MAAY,QAAQ,EAAQ;AAAA,KAAa;AAAA;AAE/D,SAAA,EAAA,GACA,EAAQ,iBAAiB,UAAU,GAAS,CAAA,GAC5C,MAAa;AACX,IAAA,EAAQ,oBAAoB,UAAU,CAAA;AAAA;GAGpC,IAAoB,OAAO,SAAU,MAAc,KAAO,iBAAiB,QAC3E,KAAA,CAAwB,GAAU,MAAO;AAC7C,QAAM,IAAU,EAAS;AACzB,MAAI,CAAC,EACH;AAEF,QAAM,IAAe,EAAS;AAC9B,MAAI,CAAC,EACH;AAEF,MAAI,IAAS;AACb,QAAM,IAAW,EAAS,QAAQ,qBAAqB,IAAA,MAAA;AAAA,MAAmC,GACxF,GAAA,MACM;AACJ,IAAA,EAAG,GAAQ,EAAA;AAAA,KAEb,EAAS,QAAQ,qBAAA,GAEb,IAAA,CAAiB,MAAA,MAAsB;AAC3C,UAAM,EAAE,YAAA,GAAY,OAAA,EAAA,IAAU,EAAS;AACvC,IAAA,IAAS,IAAa,EAAQ,cAAiB,KAAS,MAAM,KAAK,EAAQ,WAC3E,EAAA,GACA,EAAG,GAAQ,CAAA;AAAA,KAEP,IAAU,EAAc,EAAA,GACxB,IAAa,EAAc,EAAA;AACjC,EAAA,EAAQ,iBAAiB,UAAU,GAAS,CAAA;AAC5C,QAAM,IAAyB,EAAS,QAAQ,qBAAqB;AACrE,SAAI,KACF,EAAQ,iBAAiB,aAAa,GAAY,CAAA,GAEpD,MAAa;AACX,IAAA,EAAQ,oBAAoB,UAAU,CAAA,GAClC,KACF,EAAQ,oBAAoB,aAAa,CAAA;AAAA;GAIzC,KAAA,CAAuB,GAAU,MAAO;AAC5C,QAAM,IAAU,EAAS;AACzB,MAAI,CAAC,EACH;AAEF,QAAM,IAAe,EAAS;AAC9B,MAAI,CAAC,EACH;AAEF,MAAI,IAAS;AACb,QAAM,IAAW,EAAS,QAAQ,qBAAqB,IAAA,MAAA;AAAA,MAAmC,GACxF,GAAA,MACM;AACJ,IAAA,EAAG,GAAQ,EAAA;AAAA,KAEb,EAAS,QAAQ,qBAAA,GAEb,IAAA,CAAiB,MAAA,MAAsB;AAC3C,IAAA,IAAS,EAAQ,EAAS,QAAQ,aAAa,YAAY,SAAA,GAC3D,EAAA,GACA,EAAG,GAAQ,CAAA;AAAA,KAEP,IAAU,EAAc,EAAA,GACxB,IAAa,EAAc,EAAA;AACjC,EAAA,EAAQ,iBAAiB,UAAU,GAAS,CAAA;AAC5C,QAAM,IAAyB,EAAS,QAAQ,qBAAqB;AACrE,SAAI,KACF,EAAQ,iBAAiB,aAAa,GAAY,CAAA,GAEpD,MAAa;AACX,IAAA,EAAQ,oBAAoB,UAAU,CAAA,GAClC,KACF,EAAQ,oBAAoB,aAAa,CAAA;AAAA;GAIzC,KAAA,CAAkB,GAAS,GAAO,MAAa;AACnD,MAA6B,GAAM,eAAe;AAChD,UAAM,IAAM,EAAM,cAAc,CAAA;AAChC,QAAI,EAIF,QAHa,KAAK,MAChB,EAAI,EAAS,QAAQ,aAAa,eAAe,WAAA,CAAA;AAAA;AAKvD,SAAO,EAAQ,EAAS,QAAQ,aAAa,gBAAgB,cAAA;GAEzD,KAAA,CAAgB,GAAQ,EAC5B,aAAA,IAAc,GACd,UAAA,EAAA,GACC,MAAa;AACd,MAAI,GAAI;AACR,QAAM,IAAW,IAAS;AAC1B,GAAC,KAAM,IAAK,EAAS,kBAAkB,OAAO,SAAS,EAAG,aAAa,QAAgB,EAAG,KAAK,GAAI;AAAA,KAChG,EAAS,QAAQ,aAAa,SAAS,KAAA,GAAQ;AAAA,IAChD,UAAA;AAAA,GACD;GAEG,KAAA,CAAiB,GAAQ,EAC7B,aAAA,IAAc,GACd,UAAA,EAAA,GACC,MAAa;AACd,MAAI,GAAI;AACR,QAAM,IAAW,IAAS;AAC1B,GAAC,KAAM,IAAK,EAAS,kBAAkB,OAAO,SAAS,EAAG,aAAa,QAAgB,EAAG,KAAK,GAAI;AAAA,KAChG,EAAS,QAAQ,aAAa,SAAS,KAAA,GAAQ;AAAA,IAChD,UAAA;AAAA,GACD;GAEG,KAAN,MAAkB;AAAA,EAChB,YAAY,GAAM;AAChB,SAAK,SAAS,CAAA,GACd,KAAK,gBAAgB,MACrB,KAAK,eAAe,MACpB,KAAK,cAAc,IACnB,KAAK,cAAc,MACnB,KAAK,oBAAoB,CAAA,GACzB,KAAK,gBAAgC,oBAAI,IAAA,GACzC,KAAK,kBAAkC,oBAAI,IAAA,GAC3C,KAAK,8BAA8B,CAAA,GACnC,KAAK,YAAY,QACjB,KAAK,mBAAmB,IACxB,KAAK,gBAAgB,IACrB,KAAK,aAAa,MAClB,KAAK,eAAe,MACpB,KAAK,kBAAkB,MACvB,KAAK,oBAAoB,GACzB,KAAK,gBAAgC,oBAAI,IAAA,GACzC,KAAK,MAAA,MAAY;AACf,UAAI,GAAI,GAAI;AACZ,eAAS,KAAM,KAAM,IAAK,KAAK,iBAAiB,OAAO,SAAS,EAAG,gBAAgB,OAAO,SAAS,EAAG,QAAQ,OAAO,SAAS,EAAG,KAAK,CAAA,MAAQ,KAAK,IAAA;AAAA,OAErJ,KAAK,WAA2B,uBAAO;AACrC,UAAI,IAAM;AACV,YAAM,IAAA,MACA,MAGA,CAAC,KAAK,gBAAgB,CAAC,KAAK,aAAa,iBACpC,OAEF,IAAM,IAAI,KAAK,aAAa,eAAA,CAAgB,MAAY;AAC7D,QAAA,EAAQ,QAAA,CAAS,MAAU;AACzB,gBAAM,IAAA,MAAY;AAChB,kBAAM,IAAO,EAAM,QACb,IAAQ,KAAK,iBAAiB,CAAA;AACpC,gBAAI,CAAC,EAAK,aAAa;AACrB,mBAAK,SAAS,UAAU,CAAA;AACxB;AAAA;AAEF,YAAI,KAAK,0BAA0B,CAAA,KACjC,KAAK,WACH,GACA,KAAK,QAAQ,eAAe,GAAM,GAAO,IAAA,CAAK;AAAA;AAIpD,eAAK,QAAQ,sCAAsC,sBAAsB,CAAA,IAAO,EAAA;AAAA;;AAItF,aAAO;AAAA,QACL,YAAA,MAAkB;AAChB,cAAI;AACJ,WAAC,IAAK,EAAA,MAAU,QAAgB,EAAG,WAAA,GACnC,IAAM;AAAA;QAER,SAAA,CAAU,MAAW;AACnB,cAAI;AACJ,kBAAQ,IAAK,EAAA,MAAU,OAAO,SAAS,EAAG,QAAQ,GAAQ,EAAE,KAAK,aAAA,CAAc;AAAA;QAEjF,WAAA,CAAY,MAAW;AACrB,cAAI;AACJ,kBAAQ,IAAK,EAAA,MAAU,OAAO,SAAS,EAAG,UAAU,CAAA;AAAA;;UAI1D,KAAK,QAAQ,MACb,KAAK,aAAA,CAAc,MAAU;AAC3B,aAAO,QAAQ,CAAA,EAAO,QAAA,CAAS,CAAC,GAAK,CAAA,MAAW;AAC9C,QAAI,OAAO,IAAU,OAAa,OAAO,EAAM,CAAA;AAAA,UAEjD,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,eAAe;AAAA,QACf,UAAU;AAAA,QACV,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,oBAAoB;AAAA,QACpB,kBAAkB;AAAA,QAClB,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,UAAA,MAAgB;AAAA,QAAA;AAAA,QAEhB,gBAAA;AAAA,QACA,aAAa;AAAA,UAAE,OAAO;AAAA,UAAG,QAAQ;AAAA;QACjC,cAAc;AAAA,QACd,KAAK;AAAA,QACL,gBAAgB;AAAA,QAChB,0BAA0B,CAAA;AAAA,QAC1B,OAAO;AAAA,QACP,uBAAuB;AAAA,QACvB,SAAS;AAAA,QACT,OAAO;AAAA,QACP,mBAAmB;AAAA,QACnB,qCAAqC;AAAA,QACrC,oBAAoB;AAAA,QACpB,GAAG;AAAA;OAGP,KAAK,SAAA,CAAU,MAAS;AACtB,UAAI,GAAI;AACR,OAAC,KAAM,IAAK,KAAK,SAAS,aAAa,QAAgB,EAAG,KAAK,GAAI,MAAM,CAAA;AAAA,OAE3E,KAAK,cAAcC,EAAAA,OAEf,KAAK,eAAA,GACE;AAAA,MACL,KAAK;AAAA,MACL,KAAK,QAAQ,KAAK,MAAM,aAAa;AAAA,MACrC,KAAK,QAAQ,KAAK,MAAM,WAAW;AAAA,SAGtC,MAAgB;AACf,WAAK,OAAO,CAAA;AAAA,OAEd;AAAA,MACE,KAAA,QAAA,IAAA,aAA8B,gBAAgB;AAAA,MAC9C,OAAA,MAAa,KAAK,QAAQ;AAAA,MAC1B,aAAa;AAAA,QACX,KAAK;AAAA,QACL,KAAK,QAAQ,KAAK,MAAM,aAAa;AAAA,QACrC,KAAK,QAAQ,KAAK,MAAM,WAAW;AAAA;KAEtC,GAEH,KAAK,UAAA,MAAgB;AACnB,WAAK,OAAO,OAAO,OAAA,EAAS,QAAA,CAAS,MAAM,EAAA,CAAG,GAC9C,KAAK,SAAS,CAAA,GACd,KAAK,SAAS,WAAA,GACV,KAAK,SAAS,QAAQ,KAAK,iBAC7B,KAAK,aAAa,qBAAqB,KAAK,KAAA,GAC5C,KAAK,QAAQ,OAEf,KAAK,cAAc,MACnB,KAAK,gBAAgB,MACrB,KAAK,eAAe;AAAA,OAEtB,KAAK,YAAA,MACH,MAAa;AACX,WAAK,QAAA;AAAA,OAGT,KAAK,cAAA,MAAoB;AACvB,UAAI;AACJ,YAAM,IAAgB,KAAK,QAAQ,UAAU,KAAK,QAAQ,iBAAA,IAAqB;AAC/E,UAAI,KAAK,kBAAkB,GAAe;AAExC,YADA,KAAK,QAAA,GACD,CAAC,GAAe;AAClB,eAAK,YAAA;AACL;AAAA;AAEF,aAAK,gBAAgB,GACjB,KAAK,iBAAiB,mBAAmB,KAAK,gBAChD,KAAK,eAAe,KAAK,cAAc,cAAc,cAErD,KAAK,iBAAiB,IAAK,KAAK,kBAAkB,OAAO,SAAS,EAAG,WAAW,MAElF,KAAK,cAAc,QAAA,CAAS,MAAW;AACrC,eAAK,SAAS,QAAQ,CAAA;AAAA,YAExB,KAAK,OAAO,KACV,KAAK,QAAQ,mBAAmB,MAAA,CAAO,MAAS;AAC9C,eAAK,aAAa,GAClB,KAAK,YAAA;AAAA,UACL,GAEJ,KAAK,OAAO,KACV,KAAK,QAAQ,qBAAqB,MAAA,CAAO,GAAQ,MAAgB;AAC/D,eAAK,oBAAoB,GACzB,KAAK,kBAAkB,IAAc,KAAK,gBAAA,IAAoB,IAAS,YAAY,aAAa,MAChG,KAAK,eAAe,GACpB,KAAK,cAAc,GACf,KAAK,eACP,KAAK,wBAAA,GAEP,KAAK,YAAA;AAAA,UACL,GAEJ,KAAK,gBAAgB,KAAK,gBAAA,GAAmB;AAAA,UAC3C,aAAa;AAAA,UACb,UAAU;AAAA,SACX;AAAA;OAGL,KAAK,QAAQ,MACb,KAAK,UAAA,MACE,KAAK,QAAQ,WAIlB,KAAK,aAAa,KAAK,cAAc,KAAK,QAAQ,aAC3C,KAAK,WAAW,KAAK,QAAQ,aAAa,UAAU,QAAA,MAJzD,KAAK,aAAa,MACX,IAKX,KAAK,kBAAA,MACE,KAAK,QAAQ,WAIlB,KAAK,eAAe,KAAK,iBAAiB,OAAO,KAAK,QAAQ,iBAAkB,aAAa,KAAK,QAAQ,cAAA,IAAkB,KAAK,QAAQ,gBAClI,KAAK,iBAJV,KAAK,eAAe,MACb,IAKX,KAAK,yBAAA,CAA0B,GAAc,MAAU;AACrD,YAAM,IAA4C,oBAAI,IAAA,GAChD,IAAuC,oBAAI,IAAA;AACjD,eAAS,IAAI,IAAQ,GAAG,KAAK,GAAG,KAAK;AACnC,cAAM,IAAc,EAAa,CAAA;AACjC,YAAI,EAA0B,IAAI,EAAY,IAAA,EAC5C;AAEF,cAAM,IAA8B,EAAqB,IACvD,EAAY,IAAA;AAOd,YALI,KAA+B,QAAQ,EAAY,MAAM,EAA4B,MACvF,EAAqB,IAAI,EAAY,MAAM,CAAA,IAClC,EAAY,MAAM,EAA4B,OACvD,EAA0B,IAAI,EAAY,MAAM,EAAA,GAE9C,EAA0B,SAAS,KAAK,QAAQ,MAClD;AAAA;AAGJ,aAAO,EAAqB,SAAS,KAAK,QAAQ,QAAQ,MAAM,KAAK,EAAqB,OAAA,CAAQ,EAAE,KAAA,CAAM,GAAG,MACvG,EAAE,QAAQ,EAAE,MACP,EAAE,QAAQ,EAAE,QAEd,EAAE,MAAM,EAAE,KAChB,CAAA,IAAK;AAAA,OAEV,KAAK,wBAAwBA,EAAAA,MACrB;AAAA,MACJ,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,OACd,CACA,GAAO,GAAc,GAAc,GAAY,GAAS,GAAO,OACzC,KAAK,cAAc,UAAU,KAAK,cAAc,MAEnE,KAAK,mBAAmB,KAE1B,KAAK,YAAY,GACjB,KAAK,8BAA8B,CAAA,GAC5B;AAAA,MACL,OAAA;AAAA,MACA,cAAA;AAAA,MACA,cAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAA;AAAA,MACA,oBAAA;AAAA,QAGJ,EACE,KAAK,GAAA,CACN,GAEH,KAAK,kBAAkBA,EAAAA,MACf,CAAC,KAAK,sBAAA,GAAyB,KAAK,aAAA,GAAc,CACvD,EACC,OAAA,GACA,cAAA,GACA,cAAA,GACA,YAAA,GACA,SAAA,GACA,OAAA,GACA,oBAAA,EAAA,GACC,MAAkB;AACnB,UAAI,CAAC;AACH,oBAAK,oBAAoB,CAAA,GACzB,KAAK,cAAc,MAAA,GACnB,KAAK,gBAAgB,MAAA,GACd,CAAA;AAET,UAAI,KAAK,gBAAgB,OAAO;mBACnB,KAAS,KAAK,gBAAgB,KAAA,EACvC,CAAI,KAAS,KACX,KAAK,gBAAgB,OAAO,CAAA;AAIlC,MAAI,KAAK,qBACP,KAAK,mBAAmB,IACxB,KAAK,gBAAgB,IACrB,KAAK,oBAAoB,CAAA,GACzB,KAAK,cAAc,MAAA,GACnB,KAAK,gBAAgB,MAAA,GACrB,KAAK,8BAA8B,CAAA,IAEjC,KAAK,kBAAkB,WAAW,KAAK,CAAC,KAAK,kBAC/C,KAAK,oBAAoB,KAAK,QAAQ,0BACtC,KAAK,kBAAkB,QAAA,CAAS,MAAS;AACvC,aAAK,cAAc,IAAI,EAAK,KAAK,EAAK,IAAA;AAAA;AAG1C,YAAM,IAAM,KAAK,gBAAgB,IAAI,KAAK,4BAA4B,SAAS,IAAI,KAAK,IAAI,GAAG,KAAK,2BAAA,IAA+B;AACnI,WAAK,8BAA8B,CAAA,GAC/B,KAAK,iBAAiB,KAAK,kBAAkB,WAAW,MAC1D,KAAK,gBAAgB;AAEvB,YAAM,IAAe,KAAK,kBAAkB,MAAM,GAAG,CAAA,GAC/C,IAAgB,IAAI,MAAM,CAAA,EAAO,KACrC,MAAK;AAEP,eAAS,IAAI,GAAG,IAAI,GAAK,KAAK;AAC5B,cAAM,IAAO,EAAa,CAAA;AAC1B,QAAI,MACF,EAAc,EAAK,IAAA,IAAQ;AAAA;AAG/B,eAAS,IAAI,GAAK,IAAI,GAAO,KAAK;AAChC,cAAM,IAAM,EAAW,CAAA,GACjB,IAAa,KAAK,gBAAgB,IAAI,CAAA;AAC5C,YAAI,GACA;AACJ,cAAM,IAAkB,MAAuB,cAAc,EAAc,IAAI,CAAA;AAC/E,YAAI,MAAe,UAAU,KAAK,QAAQ,QAAQ,GAAG;AACnD,UAAA,IAAO;AACP,gBAAM,IAAY,EAAc,CAAA,GAC1B,IAAa,MAAc,SAAS,EAAa,CAAA,IAAa;AACpE,UAAA,IAAQ,IAAa,EAAW,MAAM,KAAK,QAAQ,MAAM,IAAe;AAAA,eACnE;AACL,gBAAM,IAAsB,KAAK,QAAQ,UAAU,IAAI,EAAa,IAAI,CAAA,IAAK,KAAK,uBAAuB,GAAc,CAAA;AACvH,UAAA,IAAQ,IAAsB,EAAoB,MAAM,KAAK,QAAQ,MAAM,IAAe,GAC1F,IAAO,IAAsB,EAAoB,OAAO,IAAI,KAAK,QAAQ,OACrE,KAAK,QAAQ,QAAQ,KAAK,KAC5B,KAAK,gBAAgB,IAAI,GAAG,CAAA;AAAA;AAGhC,cAAM,IAAe,EAAc,IAAI,CAAA,GACjC,IAAO,OAAO,KAAiB,WAAW,IAAe,KAAK,QAAQ,aAAa,CAAA,GACnF,IAAM,IAAQ;AACpB,QAAA,EAAa,CAAA,IAAK;AAAA,UAChB,OAAO;AAAA,UACP,OAAA;AAAA,UACA,MAAA;AAAA,UACA,KAAA;AAAA,UACA,KAAA;AAAA,UACA,MAAA;AAAA,WAEF,EAAc,CAAA,IAAQ;AAAA;AAExB,kBAAK,oBAAoB,GAClB;AAAA,OAET;AAAA,MACE,KAAA,QAAA,IAAA,aAA8B,gBAAgB;AAAA,MAC9C,OAAA,MAAa,KAAK,QAAQ;AAAA,KAC3B,GAEH,KAAK,iBAAiBA,EAAAA,MACd;AAAA,MACJ,KAAK,gBAAA;AAAA,MACL,KAAK,QAAA;AAAA,MACL,KAAK,gBAAA;AAAA,MACL,KAAK,QAAQ;AAAA,OACd,CACA,GAAc,GAAW,GAAc,MAC/B,KAAK,QAAQ,EAAa,SAAS,KAAK,IAAY,IAAI,GAAe;AAAA,MAC5E,cAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,OAAA;AAAA,KACD,IAAI,MAEP;AAAA,MACE,KAAA,QAAA,IAAA,aAA8B,gBAAgB;AAAA,MAC9C,OAAA,MAAa,KAAK,QAAQ;AAAA,KAC3B,GAEH,KAAK,oBAAoBA,EAAAA,MACjB;AACJ,UAAI,IAAa,MACb,IAAW;AACf,YAAM,IAAQ,KAAK,eAAA;AACnB,aAAI,MACF,IAAa,EAAM,YACnB,IAAW,EAAM,WAEnB,KAAK,YAAY,WAAW;AAAA,QAAC,KAAK;AAAA,QAAa;AAAA,QAAY;AAAA,OAAS,GAC7D;AAAA,QACL,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ;AAAA,QACb;AAAA,QACA;AAAA;QAGH,GAAgB,GAAU,GAAO,GAAY,MACrC,MAAe,QAAQ,MAAa,OAAO,CAAA,IAAK,EAAe;AAAA,MACpE,YAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,KACD,GAEH;AAAA,MACE,KAAA,QAAA,IAAA,aAA8B,gBAAgB;AAAA,MAC9C,OAAA,MAAa,KAAK,QAAQ;AAAA,KAC3B,GAEH,KAAK,mBAAA,CAAoB,MAAS;AAChC,YAAM,IAAgB,KAAK,QAAQ,gBAC7B,IAAW,EAAK,aAAa,CAAA;AACnC,aAAK,IAME,SAAS,GAAU,EAAA,KALxB,QAAQ,KACN,2BAA2B,CAAA,gCAAc,GAEpC;AAAA,OAIX,KAAK,4BAAA,CAA6B,MAAU;AAC1C,UAAI;AACJ,UAAI,CAAC,KAAK,eAAe,KAAK,YAAY,aAAa,SACrD,QAAO;AAET,YAAM,IAAc,KAAK,YAAY,WAAW,IAAK,KAAK,wBAAwB,KAAK,YAAY,gBAAA,MAAsB,OAAO,SAAS,EAAG;AAC5I,UAAI,MAAgB,UAAU,KAAK,OAAO;AACxC,cAAM,IAAa,KAAK,IACtB,KAAK,QAAQ,UACb,KAAK,MAAM,KAAK,MAAM,WAAW,KAAK,MAAM,cAAc,CAAA,CAAE,GAExD,IAAW,KAAK,IAAI,GAAG,IAAc,CAAA,GACrC,IAAW,KAAK,IACpB,KAAK,QAAQ,QAAQ,GACrB,IAAc,CAAA;AAEhB,eAAO,KAAS,KAAY,KAAS;AAAA;AAEvC,aAAO;AAAA,OAET,KAAK,iBAAA,CAAkB,MAAS;AAC9B,UAAI,CAAC,GAAM;AACT,aAAK,cAAc,QAAA,CAAS,GAAQ,MAAS;AAC3C,UAAK,EAAO,gBACV,KAAK,SAAS,UAAU,CAAA,GACxB,KAAK,cAAc,OAAO,CAAA;AAAA;AAG9B;AAAA;AAEF,YAAM,IAAQ,KAAK,iBAAiB,CAAA,GAC9B,IAAM,KAAK,QAAQ,WAAW,CAAA,GAC9B,IAAW,KAAK,cAAc,IAAI,CAAA;AACxC,MAAI,MAAa,MACX,KACF,KAAK,SAAS,UAAU,CAAA,GAE1B,KAAK,SAAS,QAAQ,CAAA,GACtB,KAAK,cAAc,IAAI,GAAK,CAAA,KAEzB,CAAC,KAAK,eAAe,KAAK,gBAAgB,KAAK,0BAA0B,CAAA,KAC5E,KAAK,WAAW,GAAO,KAAK,QAAQ,eAAe,GAAM,QAAQ,IAAA,CAAK;AAAA,OAG1E,KAAK,aAAA,CAAc,GAAO,MAAS;AACjC,UAAI;AACJ,YAAM,IAAO,KAAK,kBAAkB,CAAA;AACpC,UAAI,CAAC,EAAM;AAEX,YAAM,IAAQ,KADG,KAAK,cAAc,IAAI,EAAK,GAAA,KAAQ,EAAK;AAE1D,MAAI,MAAU,QACN,IAAK,KAAK,gBAAgB,OAAO,SAAS,EAAG,cAAc,aAAa,KAAK,+CAA+C,SAAS,KAAK,2CAA2C,GAAM,GAAO,IAAA,IAAQ,EAAK,QAAQ,KAAK,gBAAA,IAAoB,KAAK,uBACzP,QAAA,IAAA,aAA6B,gBAAgB,KAAK,QAAQ,SACxD,QAAQ,KAAK,cAAc,CAAA,GAE7B,KAAK,gBAAgB,KAAK,gBAAA,GAAmB;AAAA,QAC3C,aAAa,KAAK,qBAAqB;AAAA,QACvC,UAAU;AAAA,OACX,IAEH,KAAK,4BAA4B,KAAK,EAAK,KAAA,GAC3C,KAAK,gBAAgB,IAAI,IAAI,KAAK,cAAc,IAAI,EAAK,KAAK,CAAA,CAAK,GACnE,KAAK,OAAO,EAAA;AAAA,OAGhB,KAAK,kBAAkBA,EAAAA,MACf,CAAC,KAAK,kBAAA,GAAqB,KAAK,gBAAA,CAAiB,GAAC,CACvD,GAAS,MAAiB;AACzB,YAAM,IAAe,CAAA;AACrB,eAAS,IAAI,GAAG,IAAM,EAAQ,QAAQ,IAAI,GAAK,KAAK;AAElD,cAAM,IAAc,EADV,EAAQ,CAAA,CAAA;AAElB,QAAA,EAAa,KAAK,CAAA;AAAA;AAEpB,aAAO;AAAA,OAET;AAAA,MACE,KAAA,QAAA,IAAA,aAA8B,gBAAgB;AAAA,MAC9C,OAAA,MAAa,KAAK,QAAQ;AAAA,KAC3B,GAEH,KAAK,0BAAA,CAA2B,MAAW;AACzC,YAAM,IAAe,KAAK,gBAAA;AAC1B,UAAI,EAAa,WAAW;AAG5B,eAAO,GACL,EAAa,GACX,GACA,EAAa,SAAS,GAAA,CACrB,MAAU,GAAa,EAAa,CAAA,CAAA,EAAQ,OAC7C,CAAA,CACD,CAAA;AAAA,OAGL,KAAK,qBAAA,MAA2B;AAC9B,UAAI,CAAC,KAAK,cAAe,QAAO;AAChC,UAAI,kBAAkB,KAAK,cACzB,QAAO,KAAK,QAAQ,aAAa,KAAK,cAAc,cAAc,KAAK,cAAc,cAAc,KAAK,cAAc,eAAe,KAAK,cAAc;AACnJ;AACL,cAAM,IAAM,KAAK,cAAc,SAAS;AACxC,eAAO,KAAK,QAAQ,aAAa,EAAI,cAAc,KAAK,cAAc,aAAa,EAAI,eAAe,KAAK,cAAc;AAAA;OAG7H,KAAK,wBAAA,CAAyB,GAAU,GAAO,IAAW,MAAM;AAC9D,UAAI,CAAC,KAAK,cAAe,QAAO;AAChC,YAAM,IAAO,KAAK,QAAA,GACZ,IAAe,KAAK,gBAAA;AAC1B,MAAI,MAAU,WACZ,IAAQ,KAAY,IAAe,IAAO,QAAQ,UAEhD,MAAU,WACZ,MAAa,IAAW,KAAQ,IACvB,MAAU,UACnB,KAAY;AAEd,YAAM,IAAY,KAAK,mBAAA;AACvB,aAAO,KAAK,IAAI,KAAK,IAAI,GAAW,CAAA,GAAW,CAAA;AAAA,OAEjD,KAAK,oBAAA,CAAqB,GAAO,IAAQ,WAAW;AAClD,MAAA,IAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAO,KAAK,QAAQ,QAAQ,CAAA,CAAE;AAC3D,YAAM,IAAO,KAAK,QAAA,GACZ,IAAe,KAAK,gBAAA,GACpB,IAAO,KAAK,kBAAkB,CAAA;AACpC,UAAI,CAAC,EAAM;AACX,UAAI,MAAU,OACZ,KAAI,EAAK,OAAO,IAAe,IAAO,KAAK,QAAQ,iBACjD,CAAA,IAAQ;AAAA,eACC,EAAK,SAAS,IAAe,KAAK,QAAQ,mBACnD,CAAA,IAAQ;AAAA,UAER,QAAO,CAAC,GAAc,CAAA;AAG1B,UAAI,MAAU,SAAS,MAAU,KAAK,QAAQ,QAAQ,EACpD,QAAO,CAAC,KAAK,mBAAA,GAAsB,CAAA;AAErC,YAAM,IAAW,MAAU,QAAQ,EAAK,MAAM,KAAK,QAAQ,mBAAmB,EAAK,QAAQ,KAAK,QAAQ;AACxG,aAAO,CACL,KAAK,sBAAsB,GAAU,GAAO,EAAK,IAAA,GACjD,CAAA;AAAA,OAGJ,KAAK,iBAAA,CAAkB,GAAU,EAAE,OAAA,IAAQ,SAAS,UAAA,IAAW,OAAA,IAAW,CAAA,MAAO;AAC/E,YAAM,IAAS,KAAK,sBAAsB,GAAU,CAAA,GAC9C,IAAM,KAAK,IAAA;AACjB,WAAK,cAAc;AAAA,QACjB,OAAO;AAAA,QACP,OAAA;AAAA,QACA,UAAA;AAAA,QACA,WAAW;AAAA,QACX,kBAAkB;AAAA,QAClB,cAAc;AAAA,SAEhB,KAAK,gBAAgB,GAAQ;AAAA,QAAE,aAAa;AAAA,QAAQ,UAAA;AAAA,OAAU,GAC9D,KAAK,wBAAA;AAAA,OAEP,KAAK,gBAAA,CAAiB,GAAO,EAC3B,OAAO,IAAe,QACtB,UAAA,IAAW,OAAA,IACT,CAAA,MAAO;AACT,MAAA,IAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAO,KAAK,QAAQ,QAAQ,CAAA,CAAE;AAC3D,YAAM,IAAa,KAAK,kBAAkB,GAAO,CAAA;AACjD,UAAI,CAAC,EACH;AAEF,YAAM,CAAC,GAAQ,CAAA,IAAS,GAClB,IAAM,KAAK,IAAA;AACjB,WAAK,cAAc;AAAA,QACjB,OAAA;AAAA,QACA,OAAA;AAAA,QACA,UAAA;AAAA,QACA,WAAW;AAAA,QACX,kBAAkB;AAAA,QAClB,cAAc;AAAA,SAEhB,KAAK,gBAAgB,GAAQ;AAAA,QAAE,aAAa;AAAA,QAAQ,UAAA;AAAA,OAAU,GAC9D,KAAK,wBAAA;AAAA,OAEP,KAAK,WAAA,CAAY,GAAO,EAAE,UAAA,IAAW,OAAA,IAAW,CAAA,MAAO;AACrD,YAAM,IAAS,KAAK,gBAAA,IAAoB,GAClC,IAAM,KAAK,IAAA;AACjB,WAAK,cAAc;AAAA,QACjB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,UAAA;AAAA,QACA,WAAW;AAAA,QACX,kBAAkB;AAAA,QAClB,cAAc;AAAA,SAEhB,KAAK,gBAAgB,GAAQ;AAAA,QAAE,aAAa;AAAA,QAAQ,UAAA;AAAA,OAAU,GAC9D,KAAK,wBAAA;AAAA,OAEP,KAAK,eAAA,MAAqB;AACxB,UAAI;AACJ,YAAM,IAAe,KAAK,gBAAA;AAC1B,UAAI;AACJ,UAAI,EAAa,WAAW,EAC1B,CAAA,IAAM,KAAK,QAAQ;AAAA,eACV,KAAK,QAAQ,UAAU,EAChC,CAAA,MAAQ,IAAK,EAAa,EAAa,SAAS,CAAA,MAAO,OAAO,SAAS,EAAG,QAAQ;AAAA,WAC7E;AACL,cAAM,IAAY,MAAM,KAAK,QAAQ,KAAA,EAAO,KAAK,IAAA;AACjD,YAAI,IAAW,EAAa,SAAS;AACrC,eAAO,KAAY,KAAK,EAAU,KAAA,CAAM,MAAQ,MAAQ,IAAA,KAAO;AAC7D,gBAAM,IAAO,EAAa,CAAA;AAC1B,UAAI,EAAU,EAAK,IAAA,MAAU,SAC3B,EAAU,EAAK,IAAA,IAAQ,EAAK,MAE9B;AAAA;AAEF,QAAA,IAAM,KAAK,IAAI,GAAG,EAAU,OAAA,CAAQ,MAAQ,MAAQ,IAAA,CAAK;AAAA;AAE3D,aAAO,KAAK,IACV,IAAM,KAAK,QAAQ,eAAe,KAAK,QAAQ,YAC/C,CAAA;AAAA,OAGJ,KAAK,kBAAA,CAAmB,GAAQ,EAC9B,aAAA,GACA,UAAA,EAAA,MACI;AACJ,WAAK,QAAQ,WAAW,GAAQ;AAAA,QAAE,UAAA;AAAA,QAAU,aAAA;AAAA,SAAe,IAAA;AAAA,OAE7D,KAAK,UAAA,MAAgB;AACnB,WAAK,gBAAgC,oBAAI,IAAA,GACzC,KAAK,kBAAkC,oBAAI,IAAA,GAC3C,KAAK,OAAO,EAAA;AAAA,OAEd,KAAK,WAAW,CAAA;AAAA;EAElB,0BAA0B;AACxB,QAAI,CAAC,KAAK,cAAc;AACtB,WAAK,cAAc;AACnB;AAAA;AAEF,IAAI,KAAK,SAAS,SAClB,KAAK,QAAQ,KAAK,aAAa,sBAAA,MAA4B;AACzD,WAAK,QAAQ,MACb,KAAK,gBAAA;AAAA;;EAGT,kBAAkB;AAGhB,QAFI,CAAC,KAAK,eAEN,CADO,KAAK,cACP;AAET,QAAI,KAAK,IAAA,IAAQ,KAAK,YAAY,YAAY,KAAkB;AAC9D,WAAK,cAAc;AACnB;AAAA;AAEF,UAAM,IAAa,KAAK,YAAY,SAAS,OAAO,KAAK,kBAAkB,KAAK,YAAY,OAAO,KAAK,YAAY,KAAA,IAAS,QACvH,IAAe,IAAa,EAAW,CAAA,IAAK,KAAK,YAAY,kBAC7D,IAAgB,GAChB,IAAgB,MAAiB,KAAK,YAAY;AACxD,QAAI,CAAC,KAAiB,GAAY,GAAc,KAAK,gBAAA,CAAiB;AAEpE,UADA,KAAK,YAAY,gBACb,KAAK,YAAY,gBAAgB,GAAe;AAClD,aAAK,cAAc;AACnB;AAAA;;AAGF,WAAK,YAAY,eAAe,GAC5B,MACF,KAAK,YAAY,mBAAmB,GACpC,KAAK,YAAY,WAAW,QAC5B,KAAK,gBAAgB,GAAc;AAAA,QACjC,aAAa;AAAA,QACb,UAAU;AAAA,OACX;AAGL,SAAK,wBAAA;AAAA;GAGH,KAAA,CAA2B,GAAK,GAAM,GAAiB,MAAU;AACrE,SAAO,KAAO,KAAM;AAClB,UAAM,KAAU,IAAM,KAAQ,IAAI,GAC5B,IAAe,EAAgB,CAAA;AACrC,QAAI,IAAe,EACjB,CAAA,IAAM,IAAS;AAAA,aACN,IAAe,EACxB,CAAA,IAAO,IAAS;AAAA,QAEhB,QAAO;AAAA;AAGX,SAAI,IAAM,IACD,IAAM,IAEN;;AAGX,SAAS,GAAe,EACtB,cAAA,GACA,WAAA,GACA,cAAA,GACA,OAAA,EAAA,GACC;AACD,QAAM,IAAY,EAAa,SAAS,GAClC,IAAA,CAAa,MAAU,EAAa,CAAA,EAAO;AACjD,MAAI,EAAa,UAAU,EACzB,QAAO;AAAA,IACL,YAAY;AAAA,IACZ,UAAU;AAAA;AAGd,MAAI,IAAa,GACf,GACA,GACA,GACA,CAAA,GAEE,IAAW;AACf,MAAI,MAAU,EACZ,QAAO,IAAW,KAAa,EAAa,CAAA,EAAU,MAAM,IAAe,IACzE,CAAA;AAAA,WAEO,IAAQ,GAAG;AACpB,UAAM,IAAa,MAAM,CAAA,EAAO,KAAK,CAAA;AACrC,WAAO,IAAW,KAAa,EAAW,KAAA,CAAM,MAAQ,IAAM,IAAe,CAAA,KAAY;AACvF,YAAM,IAAO,EAAa,CAAA;AAC1B,MAAA,EAAW,EAAK,IAAA,IAAQ,EAAK,KAC7B;AAAA;AAEF,UAAM,IAAe,MAAM,CAAA,EAAO,KAAK,IAAe,CAAA;AACtD,WAAO,KAAc,KAAK,EAAa,KAAA,CAAM,MAAQ,KAAO,CAAA,KAAe;AACzE,YAAM,IAAO,EAAa,CAAA;AAC1B,MAAA,EAAa,EAAK,IAAA,IAAQ,EAAK,OAC/B;AAAA;AAEF,IAAA,IAAa,KAAK,IAAI,GAAG,IAAa,IAAa,CAAA,GACnD,IAAW,KAAK,IAAI,GAAW,KAAY,IAAQ,IAAI,IAAW,EAAA;AAAA;AAEpE,SAAO;AAAA,IAAE,YAAA;AAAA,IAAY,UAAA;AAAA;;AC55BvB,IAAM,KAA4B,OAAO,WAAa,MAAc,EAAM,kBAAkB,EAAM;AAClG,SAAS,GAAmB,EAC1B,cAAA,IAAe,IACf,GAAG,EAAA,GACF;AACD,QAAM,IAAW,EAAM,WAAA,OAAkB,CAAA,IAAK,CAAA,CAAE,EAAE,CAAA,GAC5C,IAAkB;AAAA,IACtB,GAAG;AAAA,IACH,UAAA,CAAW,GAAW,MAAS;AAC7B,UAAI;AACJ,MAAI,KAAgB,IAClB,GAAU,CAAA,IAEV,EAAA,IAED,IAAK,EAAQ,aAAa,QAAgB,EAAG,KAAK,GAAS,GAAW,CAAA;AAAA;KAGrE,CAAC,CAAA,IAAY,EAAM,SAAA,MACjB,IAAI,GAAY,CAAA,CAAgB;AAExC,SAAA,EAAS,WAAW,CAAA,GACpB,GAAA,MACS,EAAS,UAAA,GACf,CAAA,CAAE,GACL,GAAA,MACS,EAAS,YAAA,IAEX;;AAET,SAAS,GAAe,GAAS;AAC/B,SAAO,GAAmB;AAAA,IACxB,oBAAA;AAAA,IACA,sBAAA;AAAA,IACA,YAAY;AAAA,IACZ,GAAG;AAAA,GACJ;;AAEH,SAAS,GAAqB,GAAS;AACrC,SAAO,GAAmB;AAAA,IACxB,kBAAA,MAAwB,OAAO,WAAa,MAAc,SAAS;AAAA,IACnE,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,YAAY;AAAA,IACZ,eAAA,MAAqB,OAAO,WAAa,MAAc,OAAO,UAAU;AAAA,IACxE,GAAG;AAAA,GACJ;;;;;;;;;;AESH,SAAS,GAAwB,EAC/B,MAAA,GACA,aAAA,GACA,oBAAA,GACA,eAAA,GACA,YAAA,GACA,cAAA,IAAe,KACf,UAAA,IAAW,GACX,QAAA,IAAS,SACT,YAAA,GACA,YAAA,GACA,kBAAA,GACA,oBAAA,GACA,WAAA,IAAY,WACZ,iBAAA,IAAkB,mBAClB,eAAA,IAAgB,iBAChB,WAAA,GACA,YAAA,GACA,YAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAY,GAAuB,IAAA,GAGnC,IAAW,MAAM,QAAQ,CAAA,IAAQ,IAAO,CAAA,GACxC,IAAa,EAAS,QAItB,IAAiB,GAAe;AAAA,IACpC,OAAO,IAAc,IAAa,IAAI;AAAA,IACtC,kBAAA,MAAwB,EAAU;AAAA,IAClC,cAAc,OAAO,KAAiB,WAAA,MAAiB,IAAe;AAAA,IACtE,UAAA;AAAA,IACA,GAAG;AAAA,GACJ,GAEK,IAAQ,EAAe,gBAAA;AAG7B,EAAA,EAAA,MAAgB;AACd,UAAM,CAAC,CAAA,IAAY,CAAC,GAAG,CAAA,EAAO,QAAA;AAE9B,IAAK,KAID,EAAS,SAAS,IAAa,KAAK,KAAe,CAAC,KAAsB,KAC5E,EAAA;AAAA,KAED;AAAA,IAAC;AAAA,IAAa;AAAA,IAAe;AAAA,IAAY;AAAA,IAAoB;AAAA,GAAM;AAEtE,QAAM,IAAmB,EAAA,MAErB,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EAAO;AAAA,IAClB,OAAO,EACL,QAAQ,OAAO,KAAW,WAAW,GAAG,CAAA,OAAa,EAAA;AAAA,cAGtD,KACC,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBACrB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAiB;AAAA,KACpB;AAAA,GAEJ,GAEP;AAAA,IAAC;AAAA,IAAY;AAAA,IAAQ;AAAA,GAAU,GAE5B,IAAyB,EAAA,MACzB,KAEF,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,cACrB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAuB;AAAA,GAC1B,GAEP,CAAC,GAAkB,CAAA,CAAgB,GAEhC,IAA2B,EAAA,MAC3B,KAEF,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,cACrB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAqB;AAAA,GACxB,GAEP,CAAC,GAAoB,CAAA,CAAc;AAGtC,SAAI,MAAe,IAAU,EAAA,IAG3B,gBAAA,EAAC,OAAD;AAAA,IACE,KAAK;AAAA,IACL,WAAW,GAAG,EAAO,WAAA,IAAe,KAAc,EAAA;AAAA,IAClD,OAAO,EACL,QAAQ,OAAO,KAAW,WAAW,GAAG,CAAA,OAAa,EAAA;AAAA,cAGvD,gBAAA,EAAC,OAAD;AAAA,MACE,WAAW,GAAG,EAAO,gBAAA,IAAoB,KAAc,EAAA;AAAA,MACvD,OAAO,EACL,QAAQ,GAAG,EAAe,aAAA,CAAc,KAAC;AAAA,gBAG3C,gBAAA,EAAC,OAAD;AAAA,QACE,WAAW,GAAG,EAAO,gBAAA,IAAoB,KAAa,EAAA;AAAA,QACtD,OAAO;AAAA,UACL,WAAW,cAAc,EAAM,CAAA,GAAI,SAAS,CAAA;AAAA,UAC5C,YAAY;AAAA;kBAGb,EAAM,IAAA,CAAK,MAAe;AACzB,gBAAM,IAAc,EAAW,QAAQ,IAAa,GAC9C,KAAO,EAAS,EAAW,KAAA;AAEjC,iBACE,gBAAA,EAAC,OAAD;AAAA,YAA0B,cAAY,EAAW;AAAA,YAAO,KAAK,EAAe;AAAA,sBACzE,IACC,IACE,EAAA,IAEA,EAAA,IAGF,gBAAA,EAAC,OAAD,EAAA,UAA+C,EAAW,IAAM,EAAW,KAAA,EAAM,GAAvE,EAAW,IAAM,EAAW,KAAA,CAAM;AAAA,aARtC,EAAW,GAAA;AAAA;OAarB;AAAA,KACF;AAAA,GACF;;AAKV,IAAM,KAAc,EAAK,EAAA;;;;;;;;;AE/HzB,SAAS,GAA8B,EACrC,MAAA,GACA,aAAA,GACA,oBAAA,GACA,eAAA,GACA,YAAA,GACA,cAAA,IAAe,KACf,UAAA,IAAW,GACX,QAAA,GACA,YAAA,GAEA,YAAA,GACA,kBAAA,GACA,oBAAA,GACA,WAAA,IAAY,WACZ,iBAAA,IAAkB,mBAClB,eAAA,IAAgB,iBAChB,WAAA,GACA,YAAA,GACA,YAAA,GACA,GAAG,EAAA,GACyB;AAE5B,QAAM,IAAW,MAAM,QAAQ,CAAA,IAAQ,IAAO,CAAA,GACxC,IAAa,EAAS,QAGtB,IAAc,GAAqB;AAAA,IACvC,OAAO,IAAc,IAAa,IAAI;AAAA,IACtC,cAAc,OAAO,KAAiB,WAAA,MAAiB,IAAe;AAAA,IACtE,UAAA;AAAA,IACA,GAAG;AAAA,GACJ,GAEK,IAAQ,EAAY,gBAAA;AAG1B,EAAA,EAAA,MAAgB;AACd,UAAM,IAAO,EAAM,EAAM,SAAS,CAAA;AAClC,IAAK,KAEe,EAAK,SAAS,KAEf,KAAe,CAAC,KAAsB,KACvD,EAAA;AAAA,KAED;AAAA,IAAC;AAAA,IAAO;AAAA,IAAa;AAAA,IAAoB;AAAA,IAAe;AAAA,GAAW;AAEtE,QAAM,IAAmB,EAAA,MAErB,gBAAA,EAAC,OAAD;AAAA,IACE,WAAW,EAAO;AAAA,IAClB,OAAO,EACL,QAAQ,OAAO,KAAW,WAAW,GAAG,CAAA,OAAc,KAAU,OAAA;AAAA,cAGjE,KACC,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAW,EAAO;AAAA,gBACrB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAiB;AAAA,KACpB;AAAA,GAEJ,GAEP;AAAA,IAAC;AAAA,IAAY;AAAA,IAAQ;AAAA,GAAU,GAE5B,IAAyB,EAAA,MAE3B,KACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,cACrB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAuB;AAAA,GAC1B,GAGT,CAAC,GAAkB,CAAA,CAAgB,GAEhC,IAA2B,EAAA,MAE7B,KACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAO;AAAA,cACrB,gBAAA,EAAC,QAAD,EAAA,UAAO,EAAA,CAAqB;AAAA,GACxB,GAGT,CAAC,GAAoB,CAAA,CAAc;AAGtC,SAAI,MAAe,IAAU,EAAA,IAI3B,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,GAAG,EAAO,WAAA,IAAe,KAAc,EAAA;AAAA,cACrD,gBAAA,EAAC,OAAD;AAAA,MACE,WAAW,GAAG,EAAO,gBAAA,IAAoB,KAAc,EAAA;AAAA,MACvD,OAAO,EACL,QAAQ,EAAY,aAAA,EAAc;AAAA,gBAGpC,gBAAA,EAAC,OAAD;AAAA,QACE,WAAW,GAAG,EAAO,gBAAA,IAAoB,KAAa,EAAA;AAAA,QACtD,OAAO,EACL,WAAW,cAAc,EAAM,CAAA,GAAI,SAAS,CAAA,MAAE;AAAA,kBAG/C,EAAM,IAAA,CAAK,MAAQ;AAClB,gBAAM,IAAc,EAAI,SAAS,GAC3B,IAAO,EAAS,EAAI,KAAA;AAE1B,iBACE,gBAAA,EAAC,OAAD;AAAA,YAAmB,cAAY,EAAI;AAAA,YAAO,KAAK,EAAY;AAAA,sBACxD,IACC,IACE,EAAA,IAEA,EAAA,IAEA,KAAQ,OACV,gBAAA,EAAC,OAAD,CAAA,GAAU,WAAW,EAAI,KAAA,EAAA,IAEzB,gBAAA,EAAC,OAAD,EAAA,UAAwC,EAAW,GAAM,EAAI,KAAA,EAAM,GAAzD,EAAW,GAAM,EAAI,KAAA,CAAM;AAAA,aAV/B,EAAI,GAAA;AAAA;OAed;AAAA,KACF;AAAA,GACF;;AAIV,IAAM,KAAoB,EAAK,EAAA"}
|
|
1
|
+
{"version":3,"file":"components.mjs","names":["memo","memo"],"sources":["../src/designs/components/Button/styles.module.css","../src/designs/components/Button/index.tsx","../src/designs/components/Dropdown/Dropdown.module.css","../src/designs/components/Dropdown/index.tsx","../src/designs/components/Icon/index.tsx","../src/designs/components/Input/styles.module.css","../src/designs/components/Input/index.tsx","../src/designs/components/KeyValueEditor/styles.module.css","../src/designs/components/KeyValueEditor/index.tsx","../src/designs/components/SearchInput/styles.module.css","../src/designs/components/SearchInput/index.tsx","../src/designs/components/ShowFilter/styles.module.css","../src/designs/components/ShowFilter/index.tsx","../src/designs/components/SlideDownSwitcher/styles.module.css","../src/designs/components/SlideDownSwitcher/index.tsx","../src/designs/components/ThemeSwitcher/index.tsx","../src/designs/components/LayoutSwitcher/index.tsx","../src/designs/components/Slider/styles.module.css","../src/designs/components/Slider/index.tsx","../src/designs/components/Suspense/styles.module.css","../src/designs/components/Suspense/SuspenseErrorBoundary.ts","../src/designs/components/Suspense/index.tsx","../src/designs/components/Textarea/styles.module.css","../src/designs/components/Textarea/index.tsx","../node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js","../node_modules/@tanstack/virtual-core/dist/esm/utils.js","../node_modules/@tanstack/virtual-core/dist/esm/index.js","../node_modules/@tanstack/react-virtual/dist/esm/index.js","../src/designs/components/VirtualList/styles.module.css","../src/designs/components/VirtualList/index.tsx","../src/designs/components/VirtualWindowList/styles.module.css","../src/designs/components/VirtualWindowList/index.tsx"],"sourcesContent":[".button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n border: 1px solid transparent;\n border-radius: var(--radius-button);\n font-family: inherit;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n outline: none;\n position: relative;\n}\n\n.button:focus-visible {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n}\n\n.button:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n/* Size variants */\n.button.small {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n min-height: 2rem;\n}\n\n.button.medium {\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n min-height: 2.5rem;\n}\n\n.button.large {\n padding: 1rem 2rem;\n font-size: 1rem;\n min-height: 3rem;\n}\n\n/* Variant styles */\n.button.primary {\n background: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-primary-fg);\n}\n\n.button.primary:hover:not(:disabled) {\n background: var(--color-primary-light);\n border-color: var(--color-primary-light);\n transform: translateY(-1px);\n}\n\n.button.primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.button.secondary {\n background: var(--color-bg-2);\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.button.secondary:hover:not(:disabled) {\n background: var(--color-bg-3);\n border-color: var(--color-primary);\n}\n\n.button.outline {\n background: transparent;\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.button.outline:hover:not(:disabled) {\n background: var(--color-bg-2);\n border-color: var(--color-primary);\n}\n\n.button.ghost {\n background: transparent;\n border-color: transparent;\n color: var(--color-fg-text);\n}\n\n.button.ghost:hover:not(:disabled) {\n background: var(--color-bg-2);\n}\n\n.button.danger {\n background: var(--color-danger);\n border-color: var(--color-danger);\n /* 与 Modal 等危险操作区一致:用 danger 专用前景,勿用 primary-fg(主题下易为深色) */\n color: var(--color-danger-fg, #ffffff);\n}\n\n.button.danger:hover:not(:disabled) {\n background: var(--color-danger-light);\n border-color: var(--color-danger-light);\n color: var(--color-danger-fg, #ffffff);\n transform: translateY(-1px);\n}\n\n.button.danger:active:not(:disabled) {\n transform: translateY(0);\n}\n\n/* Full width */\n.button.fullWidth {\n width: 100%;\n}\n\n/* Loading state */\n.button.loading {\n pointer-events: none;\n}\n\n.spinner {\n width: 1rem;\n height: 1rem;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.6s linear infinite;\n flex-shrink: 0;\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.button.small .spinner {\n width: 0.875rem;\n height: 0.875rem;\n border-width: 1.5px;\n}\n\n.button.large .spinner {\n width: 1.25rem;\n height: 1.25rem;\n border-width: 2.5px;\n}\n\n.content {\n display: flex;\n align-items: center;\n}\n\n.leftIcon,\n.rightIcon {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n.leftIcon {\n margin-right: -0.25rem;\n}\n\n.rightIcon {\n margin-left: -0.25rem;\n}\n\n/* Icon-only (square) */\n.button.iconOnly {\n aspect-ratio: 1;\n padding: 0;\n min-width: 2.5rem;\n min-height: 2.5rem;\n}\n\n.button.iconOnly.small {\n min-width: 2rem;\n min-height: 2rem;\n}\n\n.button.iconOnly.large {\n min-width: 3rem;\n min-height: 3rem;\n}\n\n.iconContainer {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.layout {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.25rem;\n width: 100%;\n}\n\n.horizontal {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n width: 100%;\n}\n\n.topIcon,\n.bottomIcon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.iconOnly .iconContainer .leftIcon,\n.iconOnly .iconContainer .rightIcon {\n margin: 0;\n}\n","/**\n * 按钮组件:支持 variant、size、四向图标、iconOnly、loading、fullWidth。\n * Button with variant, size, top/right/bottom/left icon, iconOnly, loading, fullWidth.\n *\n * @example\n * ```tsx\n * <Button>保存</Button>\n * <Button leftIcon={<Save size={16} />} loading={isSubmitting}>提交</Button>\n * <Button leftIcon={<Trash2 size={16} />} iconOnly aria-label=\"删除\" />\n * ```\n */\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\n\nimport { cloneElement, forwardRef, isValidElement } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"size\"> {\n variant?: \"primary\" | \"secondary\" | \"outline\" | \"ghost\" | \"danger\";\n size?: \"small\" | \"medium\" | \"large\";\n fullWidth?: boolean;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n /** 上方图标。Top icon. */\n topIcon?: ReactNode;\n /** 下方图标。Bottom icon. */\n bottomIcon?: ReactNode;\n /** 仅图标无文案。Icon only, no text. */\n iconOnly?: boolean;\n /** 图标尺寸覆盖。Override icon size. */\n iconSize?: number;\n loading?: boolean;\n children?: ReactNode;\n}\n\nfunction renderIcon(icon: ReactNode, iconSize?: number): ReactNode {\n if (!icon) return null;\n if (iconSize && isValidElement(icon) && typeof icon.type !== \"string\") {\n const existingProps = icon.props && typeof icon.props === \"object\" ? icon.props : {};\n return cloneElement(icon as React.ReactElement<{ size?: number }>, { ...existingProps, size: iconSize });\n }\n return icon;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"medium\",\n fullWidth = false,\n leftIcon,\n rightIcon,\n topIcon,\n bottomIcon,\n iconOnly = false,\n iconSize,\n loading = false,\n disabled,\n children,\n className = \"\",\n ...props\n },\n ref,\n ) => {\n const hasIcons = leftIcon || rightIcon || topIcon || bottomIcon;\n const hasContent = !iconOnly && children;\n const useIconOnlyLayout = iconOnly && hasIcons && !hasContent;\n const useLayout = topIcon || bottomIcon || useIconOnlyLayout;\n\n const buttonClasses = [\n styles.button,\n styles[variant],\n styles[size],\n fullWidth && styles.fullWidth,\n loading && styles.loading,\n useIconOnlyLayout && styles.iconOnly,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n if (useIconOnlyLayout) {\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n <span className={styles.iconContainer}>\n {topIcon && <span className={styles.topIcon}>{renderIcon(topIcon, iconSize)}</span>}\n {leftIcon && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {rightIcon && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n {bottomIcon && <span className={styles.bottomIcon}>{renderIcon(bottomIcon, iconSize)}</span>}\n </span>\n </button>\n );\n }\n\n if (useLayout) {\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n {loading && <span className={styles.spinner} />}\n {!loading && (\n <span className={styles.layout}>\n {topIcon && <span className={styles.topIcon}>{renderIcon(topIcon, iconSize)}</span>}\n <span className={styles.horizontal}>\n {leftIcon && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {hasContent && <span className={styles.content}>{children}</span>}\n {rightIcon && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n </span>\n {bottomIcon && <span className={styles.bottomIcon}>{renderIcon(bottomIcon, iconSize)}</span>}\n </span>\n )}\n </button>\n );\n }\n\n return (\n <button ref={ref} type=\"button\" className={buttonClasses} disabled={disabled || loading} {...props}>\n {loading && <span className={styles.spinner} />}\n {leftIcon && !loading && <span className={styles.leftIcon}>{renderIcon(leftIcon, iconSize)}</span>}\n {children && <span className={styles.content}>{children}</span>}\n {rightIcon && !loading && <span className={styles.rightIcon}>{renderIcon(rightIcon, iconSize)}</span>}\n </button>\n );\n },\n);\n\nButton.displayName = \"Button\";\n\nexport default Button;\n","/* ===== Dropdown 基础样式 ===== */\r\n.dropdown {\r\n position: relative;\r\n display: inline-block;\r\n width: 100%;\r\n}\r\n\r\n.dropdownButton {\r\n position: relative;\r\n width: 100%;\r\n padding: 0.75rem 1rem;\r\n padding-right: 2.5rem;\r\n border: 1px solid var(--color-separator);\r\n border-radius: var(--radius-card);\r\n cursor: pointer;\r\n outline: none;\r\n transition: all 0.2s ease-in-out;\r\n text-align: left;\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n font-family: inherit;\r\n font-size: 1rem;\r\n font-weight: 400;\r\n line-height: 1.5rem;\r\n background: var(--color-bg-2);\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.dropdownButton:hover:not(:disabled) {\r\n border-color: var(--color-primary);\r\n background: var(--color-bg-1);\r\n}\r\n\r\n.dropdownButton:focus {\r\n border-color: var(--color-primary);\r\n background: var(--color-bg-1);\r\n box-shadow: 0 0 0 2px var(--color-primary-transparent);\r\n}\r\n\r\n.dropdownButton.disabled {\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n background: var(--color-bg-3);\r\n}\r\n\r\n.dropdownButton.error {\r\n border-color: var(--color-danger);\r\n}\r\n\r\n.buttonText {\r\n flex: 1;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n}\r\n\r\n.chevronIcon {\r\n position: absolute;\r\n right: 1rem;\r\n transition: transform 0.15s ease;\r\n flex-shrink: 0;\r\n color: var(--color-fg-highlight);\r\n}\r\n\r\n.chevronIcon.open {\r\n transform: rotate(180deg);\r\n}\r\n\r\n/* ===== 下拉菜单 ===== */\r\n.dropdownMenu {\r\n position: absolute;\r\n top: calc(100% + 0.5rem);\r\n left: 0;\r\n right: 0;\r\n min-width: 100%;\r\n background: var(--color-bg);\r\n border: 1px solid var(--color-border-4);\r\n border-radius: var(--radius-card);\r\n box-shadow: 0 0.5rem 1rem var(--color-shadow);\r\n z-index: 1000;\r\n overflow: hidden;\r\n animation: slideDown 0.15s ease-out;\r\n}\r\n\r\n@keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-0.5rem);\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n}\r\n\r\n.optionsList {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0.5rem 0;\r\n}\r\n\r\n.option {\r\n padding: 0.75rem 1rem;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-fg-text);\r\n font-size: 0.875rem;\r\n}\r\n\r\n.option:hover {\r\n background-color: var(--color-bg-2);\r\n}\r\n\r\n.option.selected {\r\n background-color: var(--color-bg-3);\r\n color: var(--color-fg-highlight);\r\n font-weight: 600;\r\n}\r\n\r\n/* ===== 响应式 ===== */\r\n@media (max-width: 768px) {\r\n .dropdownButton {\r\n padding: 0.625rem 0.875rem;\r\n padding-right: 2.25rem;\r\n font-size: 0.875rem;\r\n }\r\n\r\n .chevronIcon {\r\n right: 0.875rem;\r\n }\r\n\r\n .option {\r\n padding: 0.625rem 0.875rem;\r\n font-size: 0.8125rem;\r\n }\r\n}","/**\n * 下拉选择:options 为 { value, label } 列表,受控 value/onChange。Dropdown select; options as { value, label }, controlled value/onChange.\n *\n * @example\n * ```tsx\n * * 受控选择\n * const [value, setValue] = useState(\"\");\n * <Dropdown\n * options={[{ value: \"a\", label: \"选项 A\" }, { value: \"b\", label: \"选项 B\" }]}\n * value={value}\n * onChange={setValue}\n * placeholder=\"请选择\"\n * />\n * ```\n */\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport { ChevronDown } from \"@/icons/lucide\";\n\nimport styles from \"./Dropdown.module.css\";\n\nexport interface DropdownOption {\n /** 选项值。Option value. */\n value: string;\n /** 选项展示文案。Option label. */\n label: string;\n}\n\nexport interface DropdownProps {\n /** 选项列表。Options list. */\n options: DropdownOption[];\n /** 当前选中值。Current value. */\n value: string;\n /** 选中回调。Change callback. */\n onChange: (value: string) => void;\n /** 占位符。Placeholder. */\n placeholder?: string;\n /** 是否禁用。Disabled. */\n disabled?: boolean;\n /** 是否错误态。Error state. */\n error?: boolean;\n /** 容器 className。Container className. */\n className?: string;\n}\n\nconst Dropdown = memo<DropdownProps>(({ options, value, onChange, placeholder = \"Select an option\", disabled = false, error = false, className = \"\" }) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n // 点击外部关闭下拉菜单\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, []);\n\n const selectedOption = options.find((option) => option.value === value);\n const displayText = selectedOption ? selectedOption.label : placeholder;\n\n const handleOptionClick = (optionValue: string) => {\n onChange(optionValue);\n setIsOpen(false);\n };\n\n return (\n <div className={`${styles.dropdown} ${className}`} ref={dropdownRef}>\n <button\n type=\"button\"\n className={`${styles.dropdownButton} ${error ? styles.error : \"\"} ${disabled ? styles.disabled : \"\"}`}\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n <span className={styles.buttonText}>{displayText}</span>\n <ChevronDown size={16} className={`${styles.chevronIcon} ${isOpen ? styles.open : \"\"}`} />\n </button>\n\n {isOpen && !disabled && (\n <div className={styles.dropdownMenu}>\n <ul className={styles.optionsList} role=\"listbox\">\n {options.map((option) => (\n <li\n key={option.value}\n className={`${styles.option} ${option.value === value ? styles.selected : \"\"}`}\n onClick={() => handleOptionClick(option.value)}\n role=\"option\"\n aria-selected={option.value === value}\n >\n {option.label}\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n});\n\nDropdown.displayName = \"Dropdown\";\n\nexport default Dropdown;\n","/**\n * 图标组件:基于 lucide-react,通过 name 渲染对应图标。Icon component; renders lucide icon by name.\n *\n * @example\n * ```tsx\n * * 使用已注册的图标名\n * <Icon name=\"ChevronDown\" size={20} />\n * * 带 className\n * <Icon name=\"Search\" className={styles.searchIcon} />\n * ```\n */\nimport type { LucideProps } from \"lucide-react\";\n\nimport { memo } from \"react\";\n\nimport * as LucideIcons from \"@/icons/lucide\";\n\nexport type IconName = keyof Omit<typeof LucideIcons, \"LucideIcon\">;\n\nexport interface IconProps extends LucideProps {\n /** 图标名(lucide 注册名)。Icon name (lucide registered name). */\n name: IconName;\n}\n\nconst Icon = memo(({ name, ...props }: IconProps) => {\n const LucideIcon = LucideIcons[name] as React.ComponentType<LucideProps> | undefined;\n\n if (!LucideIcon) {\n console.warn(`Icon \"${name}\" not found in lucide-react`);\n return null;\n }\n\n return <LucideIcon {...props} />;\n});\n\nIcon.displayName = \"Icon\";\n\nexport default Icon;\n",".wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.wrapper.fullWidth {\n width: 100%;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-heading);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.required {\n color: var(--color-danger);\n}\n\n.inputContainer {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n}\n\n.input {\n width: 100%;\n border: 1px solid var(--color-border-4);\n border-radius: var(--radius-input);\n background: var(--color-bg);\n color: var(--color-fg-text);\n font-size: 0.875rem;\n font-family: inherit;\n transition: all 0.2s ease;\n outline: none;\n}\n\n/* 隐藏浏览器默认的密码可见性切换图标 */\n/* Chrome/Edge/Safari: 隐藏密码可见性切换按钮 */\n.input[type=\"password\"]::-webkit-credentials-auto-fill-button {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n.input[type=\"password\"]::-webkit-strong-password-toggle-button {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n -webkit-appearance: none !important;\n appearance: none !important;\n margin: 0 !important;\n padding: 0 !important;\n width: 0 !important;\n height: 0 !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n/* Edge 浏览器额外处理 */\n.input[type=\"password\"]::-ms-reveal,\n.input[type=\"password\"]::-ms-clear {\n display: none !important;\n visibility: hidden !important;\n opacity: 0 !important;\n pointer-events: none !important;\n width: 0 !important;\n height: 0 !important;\n position: absolute !important;\n left: -9999px !important;\n}\n\n.input:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);\n}\n\n.input::placeholder {\n color: var(--color-fg-muted);\n opacity: 0.5;\n}\n\n/* Size variants */\n.input.small {\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n}\n\n.input.medium {\n padding: 0.75rem;\n font-size: 0.875rem;\n}\n\n.input.large {\n padding: 1rem;\n font-size: 1rem;\n}\n\n/* Variant styles */\n.input.default {\n background: var(--color-bg);\n border-color: var(--color-border-4);\n}\n\n.input.filled {\n background: var(--color-bg-2);\n border-color: var(--color-border-3);\n}\n\n/* With icons - handled via className in component */\n.inputContainer.withLeftIcon .input {\n padding-left: 2.5rem;\n}\n\n.inputContainer.withRightIcon .input {\n padding-right: 2.5rem;\n}\n\n.inputContainer.withLeftIcon .input.small {\n padding-left: 2rem;\n}\n\n.inputContainer.withRightIcon .input.small {\n padding-right: 2rem;\n}\n\n.inputContainer.withLeftIcon .input.large {\n padding-left: 3rem;\n}\n\n.inputContainer.withRightIcon .input.large {\n padding-right: 3rem;\n}\n\n.leftIcon,\n.rightIcon {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted);\n pointer-events: none;\n z-index: 1;\n}\n\n.leftIcon {\n left: 0.75rem;\n}\n\n.rightIcon {\n right: 0.75rem;\n}\n\n.rightIcon.rightIconInteractive {\n pointer-events: auto;\n}\n\n.inputContainer.containerSmall .leftIcon {\n left: 0.5rem;\n}\n\n.inputContainer.containerSmall .rightIcon {\n right: 0.5rem;\n}\n\n.inputContainer.containerLarge .leftIcon {\n left: 1rem;\n}\n\n.inputContainer.containerLarge .rightIcon {\n right: 1rem;\n}\n\n/* Error state */\n.input.error {\n border-color: var(--color-danger);\n}\n\n.input.error:focus {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb), 0.1);\n}\n\n/* Disabled state */\n.input.disabled {\n background: var(--color-bg-3);\n border-color: var(--color-border-5);\n color: var(--color-fg-muted);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.errorMessage {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 输入框:支持 label、error、helperText、左右图标与 rightIconInteractive。Input with label, error, helperText, left/right icon.\n *\n * @example\n * ```tsx\n * * 带标签与错误态\n * <Input label=\"用户名\" error={errors.name} value={name} onChange={(e) => setName(e.target.value)} />\n * * 右侧可点击图标(如清除)\n * <Input rightIcon={<X size={16} />} rightIconInteractive onRightIconClick={clear} />\n * ```\n */\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\n\nimport { forwardRef } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n /** 标签文案。Label text. */\n label?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n /** 辅助说明。Helper text. */\n helperText?: ReactNode;\n /** 左侧图标。Left icon. */\n leftIcon?: ReactNode;\n /** 右侧图标。Right icon. */\n rightIcon?: ReactNode;\n /** 为 true 时 rightIcon 可点击(如密码切换、清除按钮)。When true, right icon is clickable (e.g. password toggle, clear). */\n rightIconInteractive?: boolean;\n /** 尺寸。Size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** 视觉变体。Variant. */\n variant?: \"default\" | \"filled\";\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n}\n\nconst Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n error,\n helperText,\n leftIcon,\n rightIcon,\n rightIconInteractive = false,\n size = \"medium\",\n variant = \"default\",\n fullWidth = false,\n className = \"\",\n disabled,\n ...props\n },\n ref,\n ) => {\n const inputClasses = [styles.input, styles[size], styles[variant], error && styles.error, disabled && styles.disabled, className].filter(Boolean).join(\" \");\n\n const wrapperClasses = [styles.wrapper, fullWidth && styles.fullWidth].filter(Boolean).join(\" \");\n\n const containerClasses = [\n styles.inputContainer,\n leftIcon && styles.withLeftIcon,\n rightIcon && styles.withRightIcon,\n size && styles[`container${size.charAt(0).toUpperCase() + size.slice(1)}`],\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={wrapperClasses}>\n {label && (\n <label className={styles.label}>\n {label}\n {props.required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={containerClasses}>\n {leftIcon && <div className={styles.leftIcon}>{leftIcon}</div>}\n <input ref={ref} className={inputClasses} disabled={disabled} {...props} />\n {rightIcon && <div className={`${styles.rightIcon} ${rightIconInteractive ? styles.rightIconInteractive : \"\"}`}>{rightIcon}</div>}\n </div>\n {error && <p className={styles.errorMessage}>{error}</p>}\n {helperText && !error && <p className={styles.helperText}>{helperText}</p>}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport default Input;\n",".container {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-text);\n}\n\n.error {\n font-size: 0.875rem;\n color: var(--color-error);\n}\n\n.pairs {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.pair {\n display: grid;\n grid-template-columns: 1fr 2fr auto;\n gap: 0.75rem;\n align-items: start;\n}\n\n.keyInput,\n.valueInput {\n flex: 1;\n}\n\n.removeButton {\n padding: 0.5rem;\n min-width: auto;\n color: var(--color-error);\n}\n\n.removeButton:hover {\n background-color: var(--color-error);\n color: var(--color-primary-fg);\n}\n\n.addButton {\n align-self: flex-start;\n}\n\n@media (max-width: 768px) {\n .pair {\n grid-template-columns: 1fr;\n }\n\n .removeButton {\n align-self: flex-end;\n }\n}\n","/**\n * 键值对编辑器:动态增删 key-value 行,支持 string 或 array 值类型。Key-value pair editor; add/remove rows, valueType string or array.\n *\n * @example\n * ```tsx\n * * 字符串值\n * const [pairs, setPairs] = useState<KeyValuePair[]>([{ key: \"env\", value: \"prod\" }]);\n * <KeyValueEditor label=\"环境变量\" pairs={pairs} onChange={setPairs} />\n * * 数组值(逗号分隔)\n * <KeyValueEditor label=\"标签\" pairs={pairs} onChange={setPairs} valueType=\"array\" />\n * ```\n */\nimport type { ReactNode } from \"react\";\n\nimport { memo, useEffect, useState } from \"react\";\n\nimport Button from \"@/designs/components/Button\";\nimport Input from \"@/designs/components/Input\";\nimport { Plus, Trash2 } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface KeyValuePair {\n /** 键。Key. */\n key: string;\n /** 值(字符串或字符串数组)。Value (string or string[]). */\n value: string | string[];\n}\n\nexport interface KeyValueEditorProps {\n /** 表单项标签。Field label. */\n label: ReactNode;\n /** 键值对列表。Key-value pairs. */\n pairs: KeyValuePair[];\n /** 列表变化回调。Change callback. */\n onChange: (pairs: KeyValuePair[]) => void;\n /** 值类型:string 或 array。Value type: string or array. */\n valueType?: \"string\" | \"array\";\n /** 键占位符。Key placeholder. */\n keyPlaceholder?: string;\n /** 值占位符(string 模式)。Value placeholder (string mode). */\n valuePlaceholder?: string;\n /** 值占位符(array 模式)。Value placeholder (array mode). */\n valueArrayPlaceholder?: string;\n /** 删除按钮 aria-label。Remove button aria-label. */\n removeAriaLabel?: string;\n /** 新增按钮文案。Add button label. */\n addLabel?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n}\n\nconst KeyValueEditor = memo(\n ({\n label,\n pairs,\n onChange,\n valueType = \"string\",\n keyPlaceholder = \"Key\",\n valuePlaceholder = \"Value\",\n valueArrayPlaceholder = \"Value (comma-separated)\",\n removeAriaLabel = \"Remove row\",\n addLabel = \"Add\",\n error,\n }: KeyValueEditorProps) => {\n const effectiveValuePlaceholder = valueType === \"array\" ? valueArrayPlaceholder : valuePlaceholder;\n const [localPairs, setLocalPairs] = useState<KeyValuePair[]>(pairs);\n\n // Sync with external pairs changes\n useEffect(() => {\n setLocalPairs(pairs);\n }, [pairs]);\n\n const handleAdd = () => {\n const newPairs = [...localPairs, { key: \"\", value: valueType === \"array\" ? [] : \"\" }];\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleRemove = (index: number) => {\n const newPairs = localPairs.filter((_, i) => i !== index);\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleKeyChange = (index: number, key: string) => {\n const newPairs = [...localPairs];\n newPairs[index] = { ...newPairs[index], key };\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const handleValueChange = (index: number, value: string) => {\n const newPairs = [...localPairs];\n if (valueType === \"array\") {\n // Split by comma and trim\n const arrayValue = value\n .split(\",\")\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n newPairs[index] = { ...newPairs[index], value: arrayValue };\n } else {\n newPairs[index] = { ...newPairs[index], value };\n }\n setLocalPairs(newPairs);\n onChange(newPairs);\n };\n\n const getDisplayValue = (value: string | string[]): string => {\n if (Array.isArray(value)) {\n return value.join(\", \");\n }\n return value;\n };\n\n return (\n <div className={styles.container}>\n <label className={styles.label}>{label}</label>\n {error && <div className={styles.error}>{error}</div>}\n <div className={styles.pairs}>\n {localPairs.map((pair, index) => (\n <div key={index} className={styles.pair}>\n <Input placeholder={keyPlaceholder} value={pair.key} onChange={(e) => handleKeyChange(index, e.target.value)} className={styles.keyInput} />\n <Input\n placeholder={effectiveValuePlaceholder}\n value={getDisplayValue(pair.value)}\n onChange={(e) => handleValueChange(index, e.target.value)}\n className={styles.valueInput}\n />\n <Button type=\"button\" variant=\"ghost\" onClick={() => handleRemove(index)} className={styles.removeButton} aria-label={removeAriaLabel}>\n <Trash2 size={16} />\n </Button>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"secondary\" onClick={handleAdd} className={styles.addButton}>\n <Plus size={16} />\n {addLabel}\n </Button>\n </div>\n );\n },\n);\n\nKeyValueEditor.displayName = \"KeyValueEditor\";\n\nexport default KeyValueEditor;\n",".searchContainer {\r\n position: relative;\r\n width: 100%;\r\n max-width: 400px;\r\n}\r\n\r\n/** 占满父级(如 dialog / modal 内容区),不受 400px 上限 */\r\n.searchContainerFull {\r\n max-width: none;\r\n}\r\n\r\n.searchIcon {\r\n position: absolute;\r\n left: 1rem;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n color: var(--color-fg-muted);\r\n pointer-events: none;\r\n}\r\n\r\n.searchInput {\r\n width: 100%;\r\n padding: 0.75rem 3rem 0.75rem 3rem;\r\n border: 1px solid var(--color-border);\r\n border-radius: var(--radius-input);\r\n font-size: 1rem;\r\n color: var(--color-fg-text);\r\n background: var(--color-bg-2);\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.searchInput:focus {\r\n outline: none;\r\n border-color: var(--color-primary);\r\n box-shadow: 0 0 0 3px var(--color-primary-bg);\r\n}\r\n\r\n.searchInput::placeholder {\r\n color: var(--color-fg-muted);\r\n}\r\n\r\n.clearBtn {\r\n position: absolute;\r\n right: 0.75rem;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 1.5rem;\r\n height: 1.5rem;\r\n padding: 0;\r\n background: none;\r\n border: none;\r\n color: var(--color-fg-muted);\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.clearBtn:hover {\r\n color: var(--color-fg-text);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .searchContainer {\r\n max-width: 100%;\r\n }\r\n}\r\n\r\n","/**\n * 搜索输入框:带搜索图标与清除按钮;文案由调用方传入。Search input with search icon and clear button; labels passed as props.\n *\n * @example\n * ```tsx\n * * 受控,文案由上层 i18n 传入\n * const { t } = useTranslation(\"components\");\n * <SearchInput value={keyword} onChange={setKeyword} placeholder={t(\"searchInput.placeholder\")} clearButtonAriaLabel={t(\"searchInput.clearSearch\")} />\n * ```\n */\nimport { memo } from \"react\";\n\nimport { Search, X } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface SearchInputProps {\n /** 当前输入值。Current value. */\n value: string;\n /** 值变化回调。Change callback. */\n onChange: (value: string) => void;\n /** 占位符,由调用方传入。Placeholder; pass from caller. */\n placeholder?: string;\n /** 清除按钮 aria-label;由调用方传入(可来自 i18n)。Clear button aria-label; pass from caller. */\n clearButtonAriaLabel?: string;\n /** 为 true 时占满父级宽度并去掉 400px 上限(如模态内);列表顶栏保持默认。 */\n fullWidth?: boolean;\n}\n\nconst SearchInput = memo(\n ({ value, onChange, placeholder, clearButtonAriaLabel = \"Clear search\", fullWidth = false }: SearchInputProps) => {\n const handleClear = () => onChange(\"\");\n\n return (\n <div className={`${styles.searchContainer} ${fullWidth ? styles.searchContainerFull : \"\"}`.trim()}>\n <Search size={18} className={styles.searchIcon} />\n <input type=\"text\" value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} className={styles.searchInput} />\n {value && (\n <button onClick={handleClear} className={styles.clearBtn} aria-label={clearButtonAriaLabel}>\n <X size={16} />\n </button>\n )}\n </div>\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nexport default SearchInput;\n",".container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0.75rem;\r\n}\r\n\r\n.toggleContainer {\r\n display: flex;\r\n align-items: center;\r\n}\r\n\r\n.toggleButton {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.5rem;\r\n padding: 0.5rem 1rem;\r\n border: 1px solid var(--color-border-4);\r\n border-radius: var(--radius-button);\r\n background: var(--color-bg);\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.toggleButton:hover {\r\n background: var(--color-bg-2);\r\n border-color: var(--color-border-3);\r\n}\r\n\r\n.toggleButton.enabled {\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border-color: var(--color-primary);\r\n}\r\n\r\n.toggleButton.enabled:hover {\r\n background: var(--color-primary-hover);\r\n border-color: var(--color-primary-hover);\r\n color: var(--color-primary-fg);\r\n}\r\n\r\n.optionsContainer {\r\n display: flex;\r\n gap: 0.5rem;\r\n padding: 0.5rem;\r\n background: var(--color-bg-2);\r\n border-radius: var(--radius-card);\r\n border: 1px solid var(--color-border-4);\r\n}\r\n\r\n.option {\r\n display: flex;\r\n align-items: center;\r\n gap: 0.375rem;\r\n padding: 0.5rem 0.875rem;\r\n border: 1px solid var(--color-border-4);\r\n border-radius: var(--radius-button);\r\n background: var(--color-bg);\r\n color: var(--color-fg);\r\n font-size: 0.875rem;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n flex: 1;\r\n justify-content: center;\r\n}\r\n\r\n.option:hover {\r\n background: var(--color-bg-3);\r\n border-color: var(--color-border-3);\r\n}\r\n\r\n.option.active {\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border-color: var(--color-primary);\r\n}\r\n\r\n.option.active:hover {\r\n background: var(--color-primary-hover);\r\n border-color: var(--color-primary-hover);\r\n color: var(--color-primary-fg);\r\n}\r\n\r\n","/**\n * 显示/隐藏筛选器:开关 + 全部/显示/隐藏选项;文案由调用方传入。Show/hide filter; labels passed as props.\n *\n * @example\n * ```tsx\n * * 受控,不传文案则用默认英文;可传 i18n\n * <ShowFilter value={filter} onChange={setFilter} />\n * <ShowFilter value={filter} onChange={setFilter} all={t(\"showFilter.all\")} show={t(\"showFilter.show\")} hide={t(\"showFilter.hide\")} />\n * ```\n */\nimport type { ReactNode } from \"react\";\n\nimport { memo } from \"react\";\n\nimport { Eye, EyeOff, Filter } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface ShowFilterValue {\n /** 筛选是否启用。Whether filter is enabled. */\n enabled: boolean;\n /** 显示/隐藏:null=全部,true=显示,false=隐藏。Show/hide: null=all, true=show, false=hide. */\n value: boolean | null;\n}\n\nexport interface ShowFilterProps {\n /** 当前值。Current value. */\n value: ShowFilterValue;\n /** 值变化回调。Change callback. */\n onChange: (value: ShowFilterValue) => void;\n /** 筛选开启时的按钮文案。Label when filter enabled. */\n filterEnabled?: ReactNode;\n /** 筛选关闭时的按钮文案。Label when filter disabled. */\n filterDisabled?: ReactNode;\n /** 开启筛选按钮的 aria-label。Aria-label for enable filter button. */\n enableFilterAriaLabel?: string;\n /** 关闭筛选按钮的 aria-label。Aria-label for disable filter button. */\n disableFilterAriaLabel?: string;\n /** 「全部」选项文案。Label for \"all\" option. */\n all?: ReactNode;\n /** 「显示」选项文案。Label for \"show\" option. */\n show?: ReactNode;\n /** 「隐藏」选项文案。Label for \"hide\" option. */\n hide?: ReactNode;\n}\n\nconst ShowFilter = memo(\n ({\n value,\n onChange,\n filterEnabled = \"Filter on\",\n filterDisabled = \"Filter\",\n enableFilterAriaLabel = \"Enable filter\",\n disableFilterAriaLabel = \"Disable filter\",\n all = \"All\",\n show = \"Show\",\n hide = \"Hide\",\n }: ShowFilterProps) => {\n const handleToggleEnabled = () => {\n onChange({ ...value, enabled: !value.enabled });\n };\n\n const handleSelectValue = (filterValue: boolean | null) => {\n onChange({ ...value, value: filterValue });\n };\n\n return (\n <div className={styles.container}>\n <div className={styles.toggleContainer}>\n <button\n type=\"button\"\n className={`${styles.toggleButton} ${value.enabled ? styles.enabled : \"\"}`}\n onClick={handleToggleEnabled}\n aria-label={value.enabled ? disableFilterAriaLabel : enableFilterAriaLabel}\n >\n <Filter size={16} />\n <span>{value.enabled ? filterEnabled : filterDisabled}</span>\n </button>\n </div>\n\n {value.enabled && (\n <div className={styles.optionsContainer}>\n <button type=\"button\" className={`${styles.option} ${value.value === null ? styles.active : \"\"}`} onClick={() => handleSelectValue(null)}>\n {all}\n </button>\n <button type=\"button\" className={`${styles.option} ${value.value === true ? styles.active : \"\"}`} onClick={() => handleSelectValue(true)}>\n <Eye size={16} />\n <span>{show}</span>\n </button>\n <button type=\"button\" className={`${styles.option} ${value.value === false ? styles.active : \"\"}`} onClick={() => handleSelectValue(false)}>\n <EyeOff size={16} />\n <span>{hide}</span>\n </button>\n </div>\n )}\n </div>\n );\n },\n);\n\nShowFilter.displayName = \"ShowFilter\";\n\nexport default ShowFilter;\n","/* ===== Nebular Select 样式模仿(下拉滑出) ===== */\n\n.nbSelect {\n display: inline-block;\n position: relative;\n font-family: inherit;\n font-size: 0.9375rem;\n line-height: 1.5rem;\n font-weight: 600;\n}\n\n.selectButton {\n position: relative;\n width: 100%;\n min-width: 8rem;\n padding: 0.4375rem 2.2rem 0.4375rem 1.125rem;\n border: 1px solid;\n border-radius: var(--radius-button);\n cursor: pointer;\n outline: none;\n transition: all 0.15s ease-in-out;\n text-align: left;\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n line-height: inherit;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n}\n\n.selectButton.primary {\n background-color: var(--color-primary);\n border-color: var(--color-primary);\n color: var(--color-primary-fg);\n}\n\n.selectButton.primary:hover:not(:disabled) {\n background-color: var(--color-primary-light);\n border-color: var(--color-primary-light);\n}\n\n.selectButton.primary:focus,\n.selectButton.primary.open {\n background-color: var(--color-primary-light);\n border-color: var(--color-primary-light);\n box-shadow: 0 0 0 0.125rem rgba(var(--color-primary-rgb), 0.25);\n}\n\n.selectButton.default {\n background-color: var(--color-bg);\n border-color: var(--color-border-4);\n color: var(--color-fg-text);\n}\n\n.selectButton.default:hover:not(:disabled) {\n background-color: var(--color-bg-2);\n border-color: var(--color-primary);\n}\n\n.selectButton.default:focus,\n.selectButton.default.open {\n background-color: var(--color-bg-2);\n border-color: var(--color-primary);\n box-shadow: 0 0 0 0.125rem rgba(var(--color-primary-rgb), 0.25);\n}\n\n.selectButton:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.buttonText {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.chevronIcon {\n position: absolute;\n right: 0.41rem;\n width: 1.5rem;\n height: 1.5rem;\n transition: transform 0.15s ease;\n flex-shrink: 0;\n}\n\n.selectButton.primary .chevronIcon {\n color: var(--color-primary-fg);\n}\n\n.selectButton.default .chevronIcon {\n color: var(--color-fg);\n}\n\n.chevronIcon.open {\n transform: rotate(180deg);\n}\n\n.optionsPanel {\n position: absolute;\n top: calc(100% + 0.5rem);\n left: 0;\n right: 0;\n min-width: 100%;\n background-color: var(--color-bg);\n border: 1px solid var(--color-border-4);\n border-radius: var(--radius-button);\n box-shadow: 0 0.5rem 1rem var(--color-shadow);\n z-index: 1000;\n overflow: hidden;\n transform-origin: top;\n visibility: hidden;\n pointer-events: none;\n}\n\n.optionsPanel.open {\n visibility: visible;\n pointer-events: auto;\n animation: expandDown 0.25s ease-out;\n}\n\n.optionsPanel.closed {\n visibility: hidden;\n pointer-events: none;\n animation: collapseUp 0.25s ease-out;\n}\n\n@keyframes expandDown {\n from {\n opacity: 0;\n transform: scaleY(0);\n }\n to {\n opacity: 1;\n transform: scaleY(1);\n }\n}\n\n@keyframes collapseUp {\n from {\n opacity: 1;\n transform: scaleY(1);\n }\n to {\n opacity: 0;\n transform: scaleY(0);\n }\n}\n\n.optionsPanel.primary {\n border-color: var(--color-primary);\n}\n\n.optionsPanel.default {\n border-color: var(--color-border-4);\n}\n\n.optionsList {\n list-style: none;\n margin: 0;\n padding: 0.5rem 0;\n}\n\n.option {\n padding: 0.75rem 1.125rem;\n cursor: pointer;\n transition: all 0.15s ease;\n display: flex;\n align-items: center;\n justify-content: space-between;\n color: var(--color-fg-text);\n}\n\n.option:hover {\n background-color: var(--color-bg-2);\n}\n\n.option.selected {\n background-color: var(--color-primary);\n color: var(--color-primary-fg);\n font-weight: 700;\n}\n\n@media (prefers-color-scheme: dark) {\n .optionsPanel {\n box-shadow: 0 0.5rem 1rem var(--color-shadow);\n }\n}\n","/**\n * 下滑切换器:选项列表下拉选择,支持泛型 T(如 enum)。Dropdown switcher with options; generic T (e.g. enum).\n *\n * @example\n * ```tsx\n * * 与 enum 配合\n * type Status = \"all\" | \"active\" | \"archived\";\n * <SlideDownSwitcher<Status>\n * value={filter}\n * options={[\"all\", \"active\", \"archived\"]}\n * getDisplayName={(v) => ({ all: \"全部\", active: \"启用\", archived: \"归档\" }[v])}\n * onChange={setFilter}\n * />\n * ```\n */\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface SlideDownSwitcherProps<T extends string> {\n /** 当前选中的值(enum 或 string) */\n value: T;\n /** 可选项列表(如 Object.values(SomeEnum)) */\n options: readonly T[];\n /** 选项展示文案 */\n getDisplayName: (value: T) => string;\n /** 选中后回调 */\n onChange: (value: T) => void;\n status?: \"primary\" | \"default\";\n}\n\nconst SlideDownSwitcherInner = <T extends string>({ value, options, getDisplayName, onChange, status = \"primary\" }: SlideDownSwitcherProps<T>) => {\n const [isOpen, setIsOpen] = useState(false);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n const handleSelect = (option: T) => {\n onChange(option);\n setIsOpen(false);\n };\n\n return (\n <div className={styles.nbSelect} ref={wrapperRef}>\n <button\n type=\"button\"\n className={`${styles.selectButton} ${styles[status]}`}\n onClick={() => setIsOpen(!isOpen)}\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n >\n <span className={styles.buttonText}>{getDisplayName(value)}</span>\n <svg\n className={`${styles.chevronIcon} ${isOpen ? styles.open : \"\"}`}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"m6 9 6 6 6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n\n <div className={`${styles.optionsPanel} ${styles[status]} ${isOpen ? styles.open : styles.closed}`} role=\"listbox\">\n <ul className={styles.optionsList}>\n {options.map((option) => (\n <li\n key={option}\n className={`${styles.option} ${option === value ? styles.selected : \"\"}`}\n onClick={() => handleSelect(option)}\n role=\"option\"\n aria-selected={option === value}\n >\n <span>{getDisplayName(option)}</span>\n {option === value && (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M20 6L9 17l-5-5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )}\n </li>\n ))}\n </ul>\n </div>\n </div>\n );\n};\n\nconst SlideDownSwitcher = memo(SlideDownSwitcherInner) as typeof SlideDownSwitcherInner & {\n displayName?: string;\n};\nSlideDownSwitcher.displayName = \"SlideDownSwitcher\";\n\nexport default SlideDownSwitcher;\n","import type { ThemeEnum, ThemeSwitcherProps } from \"@/themes/types\";\n\nimport { memo } from \"react\";\n\nimport { useTheme } from \"@/themes/hooks/useTheme\";\n\nimport SlideDownSwitcher from \"../SlideDownSwitcher\";\n\nconst ThemeSwitcher = memo(({ status = \"primary\", getThemeDisplayName, handleChangeTheme }: ThemeSwitcherProps) => {\n const { themeName, setTheme, availableThemes } = useTheme();\n\n const getDisplayName = getThemeDisplayName ?? ((theme: ThemeEnum) => theme);\n\n const handleChange = (theme: ThemeEnum) => {\n setTheme(theme);\n handleChangeTheme?.(theme);\n };\n\n return <SlideDownSwitcher value={themeName} options={availableThemes} getDisplayName={getDisplayName} onChange={handleChange} status={status} />;\n});\n\nThemeSwitcher.displayName = \"ThemeSwitcher\";\n\nexport default ThemeSwitcher;\n","import type { LayoutSwitcherProps } from \"@/designs/layouts/types\";\n\nimport { memo } from \"react\";\n\nimport useLayout from \"@/designs/layouts/hooks/useLayout\";\nimport { LAYOUT_MODE_VALUES, LayoutModeEnum } from \"@/designs/layouts/types\";\n\nimport SlideDownSwitcher from \"../SlideDownSwitcher\";\n\nconst LayoutSwitcher = memo(({ status = \"primary\", getLayoutDisplayName, handleChangeLayoutMode }: LayoutSwitcherProps) => {\n const { layoutMode, setLayoutMode } = useLayout();\n\n const getDisplayName = getLayoutDisplayName ?? ((mode: LayoutModeEnum) => mode);\n\n const handleChange = (mode: LayoutModeEnum) => {\n setLayoutMode(mode);\n handleChangeLayoutMode?.(mode);\n };\n\n return <SlideDownSwitcher value={layoutMode} options={LAYOUT_MODE_VALUES} getDisplayName={getDisplayName} onChange={handleChange} status={status} />;\n});\n\nLayoutSwitcher.displayName = \"LayoutSwitcher\";\n\nexport default LayoutSwitcher;\n",".sliderContainer {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.sliderContainer.fullWidth {\n width: 100%;\n}\n\n.labelRow {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n min-height: 1.5rem;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-text);\n}\n\n.required {\n color: var(--color-danger);\n margin-left: 0.25rem;\n}\n\n.sliderWrapper {\n display: flex;\n width: 100%;\n touch-action: none;\n user-select: none;\n align-items: center;\n justify-content: center;\n gap: 0.75rem;\n}\n\n.sliderRoot {\n position: relative;\n display: flex;\n width: 100%;\n flex-grow: 1;\n cursor: grab;\n touch-action: none;\n user-select: none;\n align-items: center;\n padding: 0.75rem 0;\n}\n\n.sliderRoot:active {\n cursor: grabbing;\n}\n\n.sliderTrackWrapper {\n display: flex;\n flex-grow: 1;\n position: relative;\n}\n\n.sliderTrack {\n position: relative;\n height: 0.375rem;\n width: 100%;\n overflow: hidden;\n border-radius: var(--radius-badge);\n background-color: var(--color-bg-3);\n}\n\n.sliderRange {\n position: absolute;\n height: 100%;\n background-color: var(--color-primary);\n border-radius: var(--radius-badge);\n}\n\n.valueIndicator {\n color: var(--color-primary);\n font-size: 0.875rem;\n font-weight: 600;\n min-width: 2rem;\n text-align: center;\n flex-shrink: 0;\n line-height: 1;\n}\n\n.iconWrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.icon {\n width: 20px;\n height: 20px;\n color: var(--color-fg-muted);\n}\n\n.errorMessage {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 滑块:受控 value/onChange,支持 min/max/step、label、error、overflow 动效。Slider; controlled value/onChange, min/max/step, label, error.\n *\n * @example\n * ```tsx\n * * 基础\n * <Slider value={volume} onChange={setVolume} min={0} max={100} />\n * * 带标签与辅助文案\n * <Slider label=\"音量\" value={volume} onChange={setVolume} showValue helperText=\"0-100\" />\n * ```\n */\nimport type { ReactNode } from \"react\";\n\nimport { forwardRef, memo, useEffect, useRef, useState } from \"react\";\nimport { animate, motion, useMotionValue, useMotionValueEvent, useTransform } from \"motion/react\";\n\nimport { ChevronLeft, ChevronRight } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\n\nconst MAX_OVERFLOW = 50;\n\nexport interface SliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 当前值。Current value. */\n value: number;\n /** 值变化回调。Change callback. */\n onChange: (value: number) => void;\n /** 最小值。Minimum. */\n min?: number;\n /** 最大值。Maximum. */\n max?: number;\n /** 步长。Step. */\n step?: number;\n /** 是否显示数值。Show value. */\n showValue?: boolean;\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n /** 标签文案。Label text. */\n label?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n /** 辅助说明。Helper text. */\n helperText?: ReactNode;\n /** 是否必填。Required. */\n required?: boolean;\n}\n\nconst Slider = memo(\n forwardRef<HTMLDivElement, SliderProps>(\n (\n {\n value: controlledValue,\n onChange,\n min = 0,\n max = 10,\n step = 1,\n showValue = true,\n fullWidth = false,\n label,\n error,\n helperText,\n required = false,\n className = \"\",\n ...props\n },\n ref,\n ) => {\n const [value, setValue] = useState<number>(controlledValue);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [region, setRegion] = useState<\"left\" | \"middle\" | \"right\">(\"middle\");\n const clientX = useMotionValue(0);\n const overflow = useMotionValue(0);\n\n useEffect(() => {\n setValue(controlledValue);\n }, [controlledValue]);\n\n useMotionValueEvent(clientX, \"change\", (latest: number) => {\n if (sliderRef.current) {\n const { left, right } = sliderRef.current.getBoundingClientRect();\n let newValue: number;\n if (latest < left) {\n setRegion(\"left\");\n newValue = left - latest;\n } else if (latest > right) {\n setRegion(\"right\");\n newValue = latest - right;\n } else {\n setRegion(\"middle\");\n newValue = 0;\n }\n overflow.jump(decay(newValue, MAX_OVERFLOW));\n }\n });\n\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (e.buttons > 0 && sliderRef.current) {\n const { left, width } = sliderRef.current.getBoundingClientRect();\n let newValue = min + ((e.clientX - left) / width) * (max - min);\n if (step > 0) {\n newValue = Math.round(newValue / step) * step;\n }\n newValue = Math.min(Math.max(newValue, min), max);\n setValue(newValue);\n onChange(newValue);\n clientX.jump(e.clientX);\n }\n };\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n handlePointerMove(e);\n e.currentTarget.setPointerCapture(e.pointerId);\n };\n\n const handlePointerUp = () => {\n animate(overflow, 0, { type: \"spring\", bounce: 0.5 });\n };\n\n const getRangePercentage = (): number => {\n const totalRange = max - min;\n if (totalRange === 0) return 0;\n return ((value - min) / totalRange) * 100;\n };\n\n const wrapperClasses = [styles.sliderContainer, fullWidth && styles.fullWidth, className].filter(Boolean).join(\" \");\n\n return (\n <div ref={ref} className={wrapperClasses} {...props}>\n {label && (\n <div className={styles.labelRow}>\n <label className={styles.label}>\n {label}\n {required && <span className={styles.required}>*</span>}\n </label>\n </div>\n )}\n <motion.div className={styles.sliderWrapper}>\n <motion.div\n animate={{\n scale: region === \"left\" ? [1, 1.4, 1] : 1,\n transition: { duration: 0.25 },\n }}\n style={{\n x: useTransform(() => (region === \"left\" ? -overflow.get() : 0)),\n }}\n className={styles.iconWrapper}\n >\n <ChevronLeft size={20} className={styles.icon} />\n </motion.div>\n\n <div\n ref={sliderRef}\n className={styles.sliderRoot}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n >\n <motion.div\n style={{\n scaleX: useTransform(() => {\n if (sliderRef.current) {\n const { width } = sliderRef.current.getBoundingClientRect();\n return 1 + overflow.get() / width;\n }\n return 1;\n }),\n scaleY: useTransform(overflow, [0, MAX_OVERFLOW], [1, 0.8]),\n transformOrigin: useTransform(() => {\n if (sliderRef.current) {\n const { left, width } = sliderRef.current.getBoundingClientRect();\n return clientX.get() < left + width / 2 ? \"right\" : \"left\";\n }\n return \"center\";\n }),\n }}\n className={styles.sliderTrackWrapper}\n >\n <div className={styles.sliderTrack}>\n <motion.div\n className={styles.sliderRange}\n initial={false}\n animate={{ width: `${getRangePercentage()}%` }}\n transition={{ type: \"spring\", stiffness: 300, damping: 30 }}\n />\n </div>\n </motion.div>\n </div>\n\n <motion.div\n animate={{\n scale: region === \"right\" ? [1, 1.4, 1] : 1,\n transition: { duration: 0.25 },\n }}\n style={{\n x: useTransform(() => (region === \"right\" ? overflow.get() : 0)),\n }}\n className={styles.iconWrapper}\n >\n <ChevronRight size={20} className={styles.icon} />\n </motion.div>\n {showValue && !label && <span className={styles.valueIndicator}>{Math.round(value)}</span>}\n </motion.div>\n {error && <p className={styles.errorMessage}>{error}</p>}\n {helperText && !error && <p className={styles.helperText}>{helperText}</p>}\n </div>\n );\n },\n ),\n);\n\nfunction decay(value: number, max: number): number {\n if (max === 0) {\n return 0;\n }\n const entry = value / max;\n const sigmoid = 2 * (1 / (1 + Math.exp(-entry)) - 0.5);\n return sigmoid * max;\n}\n\nSlider.displayName = \"Slider\";\n\nexport default Slider;\n",".loadingContainer {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 60vh;\r\n gap: 1.5rem;\r\n}\r\n\r\n.loadingText {\r\n color: var(--color-fg-muted);\r\n font-size: 1rem;\r\n}\r\n\r\n.errorContainer {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 60vh;\r\n gap: 2rem;\r\n padding: 3rem 2rem;\r\n text-align: center;\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.errorIconWrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 120px;\r\n height: 120px;\r\n border-radius: 50%;\r\n background: linear-gradient(135deg, rgba(var(--color-error-rgb), 0.1), rgba(var(--color-error-rgb), 0.05));\r\n border: 2px solid rgba(var(--color-error-rgb), 0.2);\r\n animation: pulse 2s ease-in-out infinite;\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% {\r\n transform: scale(1);\r\n opacity: 1;\r\n }\r\n 50% {\r\n transform: scale(1.05);\r\n opacity: 0.9;\r\n }\r\n}\r\n\r\n.errorIcon {\r\n color: var(--color-error);\r\n stroke-width: 1.5;\r\n}\r\n\r\n.errorContent {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 1rem;\r\n max-width: 600px;\r\n width: 100%;\r\n}\r\n\r\n.errorTitle {\r\n margin: 0;\r\n font-size: 1.75rem;\r\n font-weight: 700;\r\n color: var(--color-fg-heading);\r\n letter-spacing: -0.02em;\r\n line-height: 1.2;\r\n}\r\n\r\n.errorDescription {\r\n margin: 0;\r\n color: var(--color-fg-muted);\r\n font-size: 1rem;\r\n line-height: 1.6;\r\n max-width: 480px;\r\n}\r\n\r\n.errorDetailsWrapper {\r\n width: 100%;\r\n max-width: 600px;\r\n margin-top: 0.5rem;\r\n}\r\n\r\n.errorDetailsContainer {\r\n width: 100%;\r\n text-align: left;\r\n border: 1px solid var(--color-border);\r\n border-radius: var(--radius-card);\r\n background: var(--color-bg-2);\r\n overflow: hidden;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.errorDetailsContainer:hover {\r\n border-color: var(--color-border-hover);\r\n background: var(--color-bg-3);\r\n}\r\n\r\n.errorDetailsSummary {\r\n padding: 0.875rem 1.25rem;\r\n cursor: pointer;\r\n font-size: 0.875rem;\r\n font-weight: 500;\r\n color: var(--color-fg-muted);\r\n user-select: none;\r\n list-style: none;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.errorDetailsSummary:hover {\r\n color: var(--color-fg-text);\r\n}\r\n\r\n.errorDetailsSummary::-webkit-details-marker {\r\n display: none;\r\n}\r\n\r\n.errorDetailsSummary::before {\r\n content: \"▶\";\r\n display: inline-block;\r\n margin-right: 0.5rem;\r\n font-size: 0.75rem;\r\n transition: transform 0.2s ease;\r\n}\r\n\r\n.errorDetailsContainer[open] .errorDetailsSummary::before {\r\n transform: rotate(90deg);\r\n}\r\n\r\n.errorDetails {\r\n max-width: 100%;\r\n padding: 1rem 1.25rem;\r\n margin: 0;\r\n background: var(--color-bg-3);\r\n border-top: 1px solid var(--color-border);\r\n color: var(--color-fg-muted);\r\n font-size: 0.8125rem;\r\n font-family: \"Monaco\", \"Menlo\", \"Ubuntu Mono\", \"Consolas\", \"source-code-pro\", monospace;\r\n line-height: 1.6;\r\n overflow-x: auto;\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n.errorActions {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n margin-top: 1rem;\r\n}\r\n\r\n.retryButton {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.5rem;\r\n padding: 0.75rem 2rem;\r\n border-radius: var(--radius-button);\r\n background: var(--color-primary);\r\n color: var(--color-primary-fg);\r\n border: none;\r\n cursor: pointer;\r\n font-size: 0.9375rem;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n box-shadow: 0 2px 8px var(--color-shadow);\r\n}\r\n\r\n.retryButton:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 16px var(--color-shadow);\r\n background: var(--color-primary-light);\r\n color: var(--color-primary-fg);\r\n}\r\n\r\n.retryButton:active {\r\n transform: translateY(0);\r\n box-shadow: 0 2px 8px var(--color-shadow);\r\n}\r\n\r\n.retryButtonIcon {\r\n display: inline-block;\r\n font-size: 1.125rem;\r\n line-height: 1;\r\n transition: transform 0.3s ease;\r\n}\r\n\r\n.retryButton:hover .retryButtonIcon {\r\n transform: rotate(180deg);\r\n}\r\n\r\n.clearLocalDataButton {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 0.75rem 1.5rem;\r\n border-radius: var(--radius-button);\r\n background: transparent;\r\n color: var(--color-fg-muted);\r\n border: 1px solid var(--color-border-4);\r\n cursor: pointer;\r\n font-size: 0.9375rem;\r\n font-weight: 500;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.clearLocalDataButton:hover {\r\n color: var(--color-fg-text);\r\n border-color: var(--color-border-3);\r\n background: var(--color-bg-secondary);\r\n}","import type { ReactNode } from \"react\";\n\nimport { Component } from \"react\";\n\ninterface SuspenseErrorBoundaryProps {\n children: ReactNode;\n fallbackRender: (args: { error: Error | null; retry: () => void }) => ReactNode;\n onReset?: () => void;\n}\n\ninterface SuspenseErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nclass SuspenseErrorBoundary extends Component<SuspenseErrorBoundaryProps, SuspenseErrorBoundaryState> {\n state: SuspenseErrorBoundaryState = {\n hasError: false,\n error: null,\n };\n\n static getDerivedStateFromError(error: Error): SuspenseErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error) {\n if (import.meta.env.DEV) {\n console.error(\"SuspenseErrorBoundary captured error:\", error);\n }\n }\n\n private handleReset = () => {\n this.setState({ hasError: false, error: null }, () => {\n this.props.onReset?.();\n });\n };\n\n render() {\n if (this.state.hasError) {\n return this.props.fallbackRender({ error: this.state.error, retry: this.handleReset });\n }\n\n return this.props.children;\n }\n}\n\nexport default SuspenseErrorBoundary;\n","/**\n * 统一 Suspense 包装:QueryErrorResetBoundary + 自定义 Loading/Error 样式,支持 loadingType、errorFallback。Suspense wrapper with QueryErrorResetBoundary, custom loading/error UI.\n *\n * @example\n * ```tsx\n * * 包裹懒加载内容\n * <Suspense fallback={null}>\n * <LazyPage />\n * </Suspense>\n * * 自定义 loading 类型\n * <Suspense loadingType=\"bounce\" loadingShape=\"circle\">...</Suspense>\n * ```\n */\nimport type { QueryErrorResetBoundaryProps } from \"@tanstack/react-query\";\nimport type { ReactNode, SuspenseProps as ReactSuspenseProps } from \"react\";\n\nimport { memo, Suspense as ReactSuspense } from \"react\";\nimport { QueryErrorResetBoundary } from \"@tanstack/react-query\";\n\nimport BounceLoading from \"@/designs/animations/BounceLoading\";\nimport ECGLoading from \"@/designs/animations/ECGLoading\";\nimport TruckLoading from \"@/designs/animations/TruckLoading\";\nimport { AlertCircle } from \"@/icons/lucide\";\n\nimport styles from \"./styles.module.css\";\nimport SuspenseErrorBoundary from \"./SuspenseErrorBoundary\";\n\ninterface LoadingFallbackProps {\n /** 自定义 fallback 节点。Custom fallback node. */\n fallback?: ReactNode;\n /** 加载动画类型。Loading animation type. */\n loadingType?: \"ecg\" | \"truck\" | \"bounce\";\n /** 加载图形形状。Loading shape. */\n loadingShape?: \"square\" | \"circle\";\n /** 加载中文案。Loading text. */\n loadingText?: ReactNode;\n /** 加载图尺寸。Loading size. */\n loadingSize?: \"small\" | \"medium\" | \"large\";\n /** 容器 className。Container className. */\n loadingContainerClassName?: string;\n /** 文案 className。Text className. */\n loadingTextClassName?: string;\n /** 加载图 className。Loading className. */\n loadingClassName?: string;\n}\n\ninterface ErrorFallbackProps {\n /** 错误对象。Error object. */\n error: Error | null;\n /** 重试函数。Retry function. */\n retry: () => void;\n /** 自定义错误 UI。Custom error UI. */\n errorFallback?: (args: { error: Error | null; retry: () => void }) => ReactNode;\n /** 错误标题。Error title. */\n errorTitle?: ReactNode;\n /** 错误描述。Error description. */\n errorDescription?: ReactNode;\n /** 重试按钮文案。Retry button text. */\n retryText?: ReactNode;\n /** 详情折叠文案。Error details summary text. */\n errorDetailsText?: ReactNode;\n /** 清除本地数据按钮文案。Clear local data button text. */\n clearLocalDataText?: ReactNode;\n /** 点击「清除本地数据」后执行(如跳转登录页),由调用方传入。Called after clear local data (e.g. navigate to login); pass from caller. */\n onClearLocalData?: () => void;\n /** 错误容器 className。Error container className. */\n errorContainerClassName?: string;\n /** 错误详情 className。Error details className. */\n errorDetailsClassName?: string;\n /** 是否展示错误详情。Show error details. */\n showErrorDetails?: boolean;\n}\n\nexport interface SuspenseProps extends Omit<ReactSuspenseProps, \"fallback\">, Omit<QueryErrorResetBoundaryProps, \"children\"> {\n /** 自定义 fallback。Custom fallback. */\n fallback?: ReactNode;\n /** 测试用:始终挂起。Test: always suspend. */\n test?: boolean;\n /** 加载动画类型。Loading type. */\n loadingType?: \"ecg\" | \"truck\" | \"bounce\";\n /** 加载图形形状。Loading shape. */\n loadingShape?: \"square\" | \"circle\";\n /** 加载中文案,由调用方传入。Loading text; pass from caller (e.g. i18n). */\n loadingText?: ReactNode;\n /** 加载图尺寸。Loading size. */\n loadingSize?: \"small\" | \"medium\" | \"large\";\n /** 加载容器 className。Loading container className. */\n loadingContainerClassName?: string;\n /** 加载文案 className。Loading text className. */\n loadingTextClassName?: string;\n /** 加载图 className。Loading className. */\n loadingClassName?: string;\n /** 自定义错误 UI。Custom error fallback. */\n errorFallback?: (args: { error: Error | null; retry: () => void }) => ReactNode;\n /** 错误标题,由调用方传入。Error title; pass from caller. */\n errorTitle?: ReactNode;\n /** 错误描述,由调用方传入。Error description; pass from caller. */\n errorDescription?: ReactNode;\n /** 重试按钮文案,由调用方传入。Retry text; pass from caller. */\n retryText?: ReactNode;\n /** 错误详情折叠文案。Error details text. */\n errorDetailsText?: ReactNode;\n /** 清除本地数据按钮文案。Clear local data text. */\n clearLocalDataText?: ReactNode;\n /** 点击「清除本地数据」后执行(如跳转登录页),由调用方传入。Called after clear local data (e.g. navigate to login); pass from caller. */\n onClearLocalData?: () => void;\n /** 错误容器 className。Error container className. */\n errorContainerClassName?: string;\n /** 错误详情 className。Error details className. */\n errorDetailsClassName?: string;\n /** 是否展示错误详情。Show error details. */\n showErrorDetails?: boolean;\n}\n\nconst LoadingFallback = memo(\n ({\n fallback,\n loadingType = \"ecg\",\n loadingShape = \"square\",\n loadingText = \"Loading...\",\n loadingSize = \"medium\",\n loadingContainerClassName,\n loadingTextClassName,\n loadingClassName,\n }: LoadingFallbackProps) => {\n if (fallback) {\n return <>{fallback}</>;\n }\n\n const renderLoading = () => {\n switch (loadingType) {\n case \"ecg\":\n return <ECGLoading size={loadingSize} className={loadingClassName} />;\n case \"truck\":\n return <TruckLoading size={loadingSize} className={loadingClassName} />;\n case \"bounce\":\n return <BounceLoading size={loadingSize} shape={loadingShape} className={loadingClassName} />;\n default:\n return <ECGLoading size={loadingSize} className={loadingClassName} />;\n }\n };\n\n return (\n <div className={`${styles.loadingContainer} ${loadingContainerClassName || \"\"}`}>\n {renderLoading()}\n <p className={`${styles.loadingText} ${loadingTextClassName || \"\"}`}>{loadingText}</p>\n </div>\n );\n },\n);\n\nLoadingFallback.displayName = \"LoadingFallback\";\n\nconst ErrorFallback = memo(\n ({\n error,\n retry,\n errorFallback,\n errorTitle = \"Error\",\n errorDescription = \"Something went wrong. Please try again.\",\n retryText = \"Retry\",\n errorDetailsText = \"Details\",\n clearLocalDataText = \"Clear local data\",\n onClearLocalData,\n errorContainerClassName,\n errorDetailsClassName,\n showErrorDetails = import.meta.env.DEV,\n }: ErrorFallbackProps) => {\n const handleClearLocalData = () => {\n try {\n sessionStorage.clear();\n } catch {\n // ignore\n } finally {\n onClearLocalData?.();\n }\n };\n\n if (errorFallback) {\n return <>{errorFallback({ error, retry })}</>;\n }\n\n return (\n <div className={`${styles.errorContainer} ${errorContainerClassName || \"\"}`}>\n <div className={styles.errorIconWrapper}>\n <AlertCircle className={styles.errorIcon} size={64} />\n </div>\n <div className={styles.errorContent}>\n <h3 className={styles.errorTitle}>{errorTitle}</h3>\n <p className={styles.errorDescription}>{errorDescription}</p>\n {showErrorDetails && error && (\n <div className={styles.errorDetailsWrapper}>\n <details className={styles.errorDetailsContainer}>\n <summary className={styles.errorDetailsSummary}>{errorDetailsText}</summary>\n <pre className={`${styles.errorDetails} ${errorDetailsClassName || \"\"}`}>{error.message}</pre>\n </details>\n </div>\n )}\n <div className={styles.errorActions}>\n <button type=\"button\" className={styles.retryButton} onClick={retry}>\n <span className={styles.retryButtonIcon}>↻</span>\n <span>{retryText}</span>\n </button>\n <button type=\"button\" className={styles.clearLocalDataButton} onClick={handleClearLocalData}>\n <span>{clearLocalDataText}</span>\n </button>\n </div>\n </div>\n </div>\n );\n },\n);\n\nErrorFallback.displayName = \"ErrorFallback\";\n\nconst Suspense = memo(\n ({\n fallback,\n test,\n loadingType = \"ecg\",\n loadingShape = \"square\",\n loadingClassName,\n loadingText,\n loadingSize = \"medium\",\n loadingContainerClassName,\n loadingTextClassName,\n children,\n errorFallback,\n errorTitle,\n errorDescription,\n retryText,\n errorDetailsText,\n clearLocalDataText,\n onClearLocalData,\n errorContainerClassName,\n errorDetailsClassName,\n showErrorDetails = import.meta.env.DEV,\n ...restProps\n }: SuspenseProps) => {\n return (\n <QueryErrorResetBoundary {...restProps}>\n {({ reset }) => (\n <SuspenseErrorBoundary\n onReset={reset}\n fallbackRender={({ error, retry }) => (\n <ErrorFallback\n error={error}\n retry={retry}\n errorFallback={errorFallback}\n errorTitle={errorTitle}\n errorDescription={errorDescription}\n retryText={retryText}\n errorDetailsText={errorDetailsText}\n clearLocalDataText={clearLocalDataText}\n onClearLocalData={onClearLocalData}\n errorContainerClassName={errorContainerClassName}\n errorDetailsClassName={errorDetailsClassName}\n showErrorDetails={showErrorDetails}\n />\n )}\n >\n <ReactSuspense\n fallback={\n <LoadingFallback\n fallback={fallback}\n loadingType={loadingType}\n loadingShape={loadingShape}\n loadingText={loadingText}\n loadingSize={loadingSize}\n loadingContainerClassName={loadingContainerClassName}\n loadingTextClassName={loadingTextClassName}\n loadingClassName={loadingClassName}\n />\n }\n {...restProps}\n >\n {test ? <AlwaysPending /> : children}\n </ReactSuspense>\n </SuspenseErrorBoundary>\n )}\n </QueryErrorResetBoundary>\n );\n },\n);\n\nSuspense.displayName = \"Suspense\";\nexport default Suspense;\n\nconst AlwaysPending = () => {\n throw new Promise(() => {}); // 永不 resolve 的 Promise\n};\n",".wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.wrapper.fullWidth {\n width: 100%;\n}\n\n.label {\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--color-fg-heading);\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.required {\n color: var(--color-danger);\n}\n\n.inputContainer {\n position: relative;\n display: flex;\n align-items: flex-start;\n width: 100%;\n}\n\n.textarea {\n width: 100%;\n border: 1px solid var(--color-border-4);\n border-radius: var(--radius-input);\n background: var(--color-bg);\n color: var(--color-fg-text);\n font-size: 0.875rem;\n font-family: inherit;\n transition: all 0.2s ease;\n outline: none;\n resize: vertical;\n min-height: 4rem;\n}\n\n.textarea:focus {\n border-color: var(--color-primary);\n box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);\n}\n\n.textarea::placeholder {\n color: var(--color-fg-muted);\n opacity: 0.5;\n}\n\n/* Size variants */\n.textarea.small {\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n min-height: 3rem;\n}\n\n.textarea.medium {\n padding: 0.75rem;\n font-size: 0.875rem;\n min-height: 4rem;\n}\n\n.textarea.large {\n padding: 1rem;\n font-size: 1rem;\n min-height: 5rem;\n}\n\n/* Variant styles */\n.textarea.default {\n background: var(--color-bg);\n border-color: var(--color-border-4);\n}\n\n.textarea.filled {\n background: var(--color-bg-2);\n border-color: var(--color-border-3);\n}\n\n/* With icons */\n.inputContainer .leftIcon {\n position: absolute;\n left: 0.75rem;\n top: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted);\n pointer-events: none;\n z-index: 1;\n}\n\n.inputContainer .rightIcon {\n position: absolute;\n right: 0.75rem;\n top: 0.75rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-fg-muted);\n pointer-events: none;\n z-index: 1;\n}\n\n.inputContainer .textarea.small + .leftIcon,\n.inputContainer .textarea.small + .rightIcon {\n top: 0.5rem;\n}\n\n.inputContainer .textarea.large + .leftIcon,\n.inputContainer .textarea.large + .rightIcon {\n top: 1rem;\n}\n\n/* Error state */\n.textarea.error {\n border-color: var(--color-danger);\n}\n\n.textarea.error:focus {\n border-color: var(--color-danger);\n box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb), 0.1);\n}\n\n/* Disabled state */\n.textarea.disabled {\n background: var(--color-bg-3);\n border-color: var(--color-border-5);\n color: var(--color-fg-muted);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.errorText {\n font-size: 0.75rem;\n color: var(--color-danger);\n margin: 0;\n}\n\n.helperText {\n font-size: 0.75rem;\n color: var(--color-fg-muted);\n margin: 0;\n}\n","/**\n * 多行文本框:支持 label、error、helperText、左右图标与 size/variant。Textarea with label, error, helperText, left/right icon.\n *\n * @example\n * ```tsx\n * * 基础用法\n * <Textarea label=\"备注\" value={note} onChange={(e) => setNote(e.target.value)} rows={4} />\n * * 错误态\n * <Textarea error={errors.note} helperText=\"选填\" />\n * ```\n */\nimport type { ReactNode, TextareaHTMLAttributes } from \"react\";\n\nimport { forwardRef } from \"react\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"size\"> {\n /** 标签文案。Label text. */\n label?: ReactNode;\n /** 错误信息。Error message. */\n error?: ReactNode;\n /** 辅助说明。Helper text. */\n helperText?: ReactNode;\n /** 左侧图标。Left icon. */\n leftIcon?: ReactNode;\n /** 右侧图标。Right icon. */\n rightIcon?: ReactNode;\n /** 尺寸。Size. */\n size?: \"small\" | \"medium\" | \"large\";\n /** 视觉变体。Variant. */\n variant?: \"default\" | \"filled\";\n /** 是否占满宽度。Full width. */\n fullWidth?: boolean;\n}\n\nconst Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ label, error, helperText, leftIcon, rightIcon, size = \"medium\", variant = \"default\", fullWidth = false, className = \"\", disabled, ...props }, ref) => {\n const textareaClasses = [styles.textarea, styles[size], styles[variant], error && styles.error, disabled && styles.disabled, className]\n .filter(Boolean)\n .join(\" \");\n\n const wrapperClasses = [styles.wrapper, fullWidth && styles.fullWidth].filter(Boolean).join(\" \");\n\n return (\n <div className={wrapperClasses}>\n {label && (\n <label className={styles.label}>\n {label}\n {props.required && <span className={styles.required}>*</span>}\n </label>\n )}\n <div className={styles.inputContainer}>\n {leftIcon && <div className={styles.leftIcon}>{leftIcon}</div>}\n <textarea ref={ref} className={textareaClasses} disabled={disabled} {...props} />\n {rightIcon && <div className={styles.rightIcon}>{rightIcon}</div>}\n </div>\n {error && <span className={styles.errorText}>{error}</span>}\n {helperText && !error && <span className={styles.helperText}>{helperText}</span>}\n </div>\n );\n },\n);\n\nTextarea.displayName = \"Textarea\";\n\nexport default Textarea;\n","function createLazyMeasurementsView(count, flat, getItemKey) {\n const cache = new Array(count);\n return new Proxy(cache, {\n get(target, prop, receiver) {\n if (typeof prop === \"string\") {\n const c = prop.charCodeAt(0);\n if (c >= 48 && c <= 57) {\n const i = +prop;\n if (Number.isInteger(i) && i >= 0 && i < count) {\n let v = target[i];\n if (!v) {\n const s = flat[i * 2];\n v = target[i] = {\n index: i,\n key: getItemKey(i),\n start: s,\n size: flat[i * 2 + 1],\n end: s + flat[i * 2 + 1],\n lane: 0\n };\n }\n return v;\n }\n }\n if (prop === \"length\") return count;\n }\n return Reflect.get(target, prop, receiver);\n }\n });\n}\nexport {\n createLazyMeasurementsView\n};\n//# sourceMappingURL=lazy-measurements.js.map\n","function memo(getDeps, fn, opts) {\n let deps = opts.initialDeps ?? [];\n let result;\n let isInitial = true;\n function memoizedFunction() {\n var _a;\n const debugEnabled = process.env.NODE_ENV !== \"production\" && !!opts.key && !!((_a = opts.debug) == null ? void 0 : _a.call(opts));\n let depTime = 0;\n if (debugEnabled) depTime = Date.now();\n const newDeps = getDeps();\n const depsChanged = newDeps.length !== deps.length || newDeps.some((dep, index) => deps[index] !== dep);\n if (!depsChanged) {\n return result;\n }\n deps = newDeps;\n let resultTime = 0;\n if (debugEnabled) resultTime = Date.now();\n result = fn(...newDeps);\n if (debugEnabled) {\n const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;\n const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;\n const resultFpsPercentage = resultEndTime / 16;\n const pad = (str, num) => {\n str = String(str);\n while (str.length < num) {\n str = \" \" + str;\n }\n return str;\n };\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120)\n )}deg 100% 31%);`,\n opts == null ? void 0 : opts.key\n );\n }\n if ((opts == null ? void 0 : opts.onChange) && !(isInitial && opts.skipInitialOnChange)) {\n opts.onChange(result);\n }\n isInitial = false;\n return result;\n }\n memoizedFunction.updateDeps = (newDeps) => {\n deps = newDeps;\n };\n return memoizedFunction;\n}\nfunction notUndefined(value, msg) {\n if (value === void 0) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : \"\"}`);\n } else {\n return value;\n }\n}\nconst approxEqual = (a, b) => Math.abs(a - b) < 1.01;\nconst debounce = (targetWindow, fn, ms) => {\n let timeoutId;\n return function(...args) {\n targetWindow.clearTimeout(timeoutId);\n timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);\n };\n};\nexport {\n approxEqual,\n debounce,\n memo,\n notUndefined\n};\n//# sourceMappingURL=utils.js.map\n","import { createLazyMeasurementsView } from \"./lazy-measurements.js\";\nimport { memo, notUndefined, approxEqual, debounce } from \"./utils.js\";\nlet _isIOSResult;\nconst isIOSWebKit = () => {\n if (_isIOSResult !== void 0) return _isIOSResult;\n if (typeof navigator === \"undefined\") return _isIOSResult = false;\n if (/iP(hone|od|ad)/.test(navigator.userAgent)) return _isIOSResult = true;\n const mtp = navigator.maxTouchPoints;\n return _isIOSResult = navigator.platform === \"MacIntel\" && mtp !== void 0 && mtp > 0;\n};\nconst _resetIOSDetectionForTests = () => {\n _isIOSResult = void 0;\n};\nconst getRect = (element) => {\n const { offsetWidth, offsetHeight } = element;\n return { width: offsetWidth, height: offsetHeight };\n};\nconst defaultKeyExtractor = (index) => index;\nconst defaultRangeExtractor = (range) => {\n const start = Math.max(range.startIndex - range.overscan, 0);\n const end = Math.min(range.endIndex + range.overscan, range.count - 1);\n const len = end - start + 1;\n const arr = new Array(len);\n for (let i = 0; i < len; i++) {\n arr[i] = start + i;\n }\n return arr;\n};\nconst observeElementRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n const handler = (rect) => {\n const { width, height } = rect;\n cb({ width: Math.round(width), height: Math.round(height) });\n };\n handler(getRect(element));\n if (!targetWindow.ResizeObserver) {\n return () => {\n };\n }\n const observer = new targetWindow.ResizeObserver((entries) => {\n const run = () => {\n const entry = entries[0];\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize });\n return;\n }\n }\n handler(getRect(element));\n };\n instance.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n observer.observe(element, { box: \"border-box\" });\n return () => {\n observer.unobserve(element);\n };\n};\nconst addEventListenerOptions = {\n passive: true\n};\nconst observeWindowRect = (instance, cb) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const handler = () => {\n cb({ width: element.innerWidth, height: element.innerHeight });\n };\n handler();\n element.addEventListener(\"resize\", handler, addEventListenerOptions);\n return () => {\n element.removeEventListener(\"resize\", handler);\n };\n};\nconst supportsScrollend = typeof window == \"undefined\" ? true : \"onscrollend\" in window;\nconst observeOffset = (instance, cb, readOffset) => {\n const element = instance.scrollElement;\n if (!element) {\n return;\n }\n const targetWindow = instance.targetWindow;\n if (!targetWindow) {\n return;\n }\n const registerScrollendEvent = instance.options.useScrollendEvent && supportsScrollend;\n let offset = 0;\n const fallback = registerScrollendEvent ? null : debounce(\n targetWindow,\n () => cb(offset, false),\n instance.options.isScrollingResetDelay\n );\n const createHandler = (isScrolling) => () => {\n offset = readOffset(element);\n fallback == null ? void 0 : fallback();\n cb(offset, isScrolling);\n };\n const handler = createHandler(true);\n const endHandler = createHandler(false);\n element.addEventListener(\"scroll\", handler, addEventListenerOptions);\n if (registerScrollendEvent) {\n element.addEventListener(\"scrollend\", endHandler, addEventListenerOptions);\n }\n return () => {\n element.removeEventListener(\"scroll\", handler);\n if (registerScrollendEvent) {\n element.removeEventListener(\"scrollend\", endHandler);\n }\n };\n};\nconst observeElementOffset = (instance, cb) => observeOffset(instance, cb, (el) => {\n const { horizontal, isRtl } = instance.options;\n return horizontal ? el.scrollLeft * (isRtl && -1 || 1) : el.scrollTop;\n});\nconst observeWindowOffset = (instance, cb) => observeOffset(\n instance,\n cb,\n (win) => instance.options.horizontal ? win.scrollX : win.scrollY\n);\nconst measureElement = (element, entry, instance) => {\n if (instance.options.useCachedMeasurements) {\n const index = instance.indexFromElement(element);\n const key = instance.options.getItemKey(index);\n return instance.itemSizeCache.get(key) ?? instance.options.estimateSize(index);\n }\n if (entry == null ? void 0 : entry.borderBoxSize) {\n const box = entry.borderBoxSize[0];\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? \"inlineSize\" : \"blockSize\"]\n );\n return size;\n }\n }\n if (!entry) {\n const index = instance.indexFromElement(element);\n const key = instance.options.getItemKey(index);\n const cachedSize = instance.itemSizeCache.get(key);\n if (cachedSize !== void 0) {\n return cachedSize;\n }\n }\n return element[instance.options.horizontal ? \"offsetWidth\" : \"offsetHeight\"];\n};\nconst scrollWithAdjustments = (offset, {\n adjustments = 0,\n behavior\n}, instance) => {\n var _a, _b;\n (_b = (_a = instance.scrollElement) == null ? void 0 : _a.scrollTo) == null ? void 0 : _b.call(_a, {\n [instance.options.horizontal ? \"left\" : \"top\"]: offset + adjustments,\n behavior\n });\n};\nconst windowScroll = scrollWithAdjustments;\nconst elementScroll = scrollWithAdjustments;\nclass Virtualizer {\n constructor(opts) {\n this.unsubs = [];\n this.scrollElement = null;\n this.targetWindow = null;\n this.isScrolling = false;\n this.scrollState = null;\n this.measurementsCache = [];\n this._flatMeasurements = null;\n this.itemSizeCache = /* @__PURE__ */ new Map();\n this.itemSizeCacheVersion = 0;\n this.laneAssignments = /* @__PURE__ */ new Map();\n this.pendingMin = null;\n this.prevLanes = void 0;\n this.lanesChangedFlag = false;\n this.lanesSettling = false;\n this.pendingScrollAnchor = null;\n this.scrollRect = null;\n this.scrollOffset = null;\n this.scrollDirection = null;\n this.scrollAdjustments = 0;\n this._iosDeferredAdjustment = 0;\n this._iosTouching = false;\n this._iosJustTouchEnded = false;\n this._iosTouchEndTimerId = null;\n this._intendedScrollOffset = null;\n this.elementsCache = /* @__PURE__ */ new Map();\n this.now = () => {\n var _a, _b, _c;\n return ((_c = (_b = (_a = this.targetWindow) == null ? void 0 : _a.performance) == null ? void 0 : _b.now) == null ? void 0 : _c.call(_b)) ?? Date.now();\n };\n this.observer = /* @__PURE__ */ (() => {\n let _ro = null;\n const get = () => {\n if (_ro) {\n return _ro;\n }\n if (!this.targetWindow || !this.targetWindow.ResizeObserver) {\n return null;\n }\n return _ro = new this.targetWindow.ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const run = () => {\n const node = entry.target;\n const index = this.indexFromElement(node);\n if (!node.isConnected) {\n this.observer.unobserve(node);\n for (const [cacheKey, cachedNode] of this.elementsCache) {\n if (cachedNode === node) {\n this.elementsCache.delete(cacheKey);\n break;\n }\n }\n return;\n }\n if (this.shouldMeasureDuringScroll(index)) {\n this.resizeItem(\n index,\n this.options.measureElement(node, entry, this)\n );\n }\n };\n this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();\n });\n });\n };\n return {\n disconnect: () => {\n var _a;\n (_a = get()) == null ? void 0 : _a.disconnect();\n _ro = null;\n },\n observe: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.observe(target, { box: \"border-box\" });\n },\n unobserve: (target) => {\n var _a;\n return (_a = get()) == null ? void 0 : _a.unobserve(target);\n }\n };\n })();\n this.range = null;\n this.setOptions = (opts2) => {\n var _a, _b;\n const merged = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {\n },\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n gap: 0,\n indexAttribute: \"data-index\",\n initialMeasurementsCache: [],\n lanes: 1,\n anchorTo: \"start\",\n followOnAppend: false,\n scrollEndThreshold: 1,\n isScrollingResetDelay: 150,\n enabled: true,\n isRtl: false,\n useScrollendEvent: false,\n useAnimationFrameWithResizeObserver: false,\n laneAssignmentMode: \"estimate\",\n useCachedMeasurements: false\n };\n for (const key in opts2) {\n const v = opts2[key];\n if (v !== void 0) merged[key] = v;\n }\n const prevOptions = this.options;\n let anchor = null;\n let followOnAppend = null;\n let edgeKeysChanged = false;\n if (prevOptions !== void 0 && prevOptions.enabled && merged.enabled && merged.anchorTo === \"end\" && this.scrollElement !== null) {\n const prevCount = prevOptions.count;\n const nextCount = merged.count;\n const measurements = this.getMeasurements();\n const prevFirstKey = prevCount > 0 ? ((_a = measurements[0]) == null ? void 0 : _a.key) ?? prevOptions.getItemKey(0) : null;\n const prevLastKey = prevCount > 0 ? ((_b = measurements[prevCount - 1]) == null ? void 0 : _b.key) ?? prevOptions.getItemKey(prevCount - 1) : null;\n const didCountChange = nextCount !== prevCount;\n const didEdgeKeysChange = didCountChange || prevCount > 0 && nextCount > 0 && (merged.getItemKey(0) !== prevFirstKey || merged.getItemKey(nextCount - 1) !== prevLastKey);\n if (didEdgeKeysChange) {\n edgeKeysChanged = true;\n const item = prevCount > 0 ? this.getVirtualItemForOffset(this.getScrollOffset()) ?? measurements[0] : null;\n if (item) {\n anchor = [item.key, this.getScrollOffset() - item.start];\n }\n const behavior = merged.followOnAppend === true ? \"auto\" : merged.followOnAppend || null;\n if (behavior && nextCount > prevCount && this.isAtEnd(prevOptions.scrollEndThreshold) && (prevCount === 0 || merged.getItemKey(nextCount - 1) !== prevLastKey)) {\n followOnAppend = behavior;\n }\n }\n }\n this.options = merged;\n if (edgeKeysChanged) {\n this.pendingMin = 0;\n this.itemSizeCacheVersion++;\n }\n let anchorResolved = false;\n let anchorDelta = 0;\n if (anchor && this.scrollOffset !== null) {\n const [anchorKey, anchorOffset] = anchor;\n const newMeasurements = this.getMeasurements();\n const { count, getItemKey } = this.options;\n let idx = 0;\n while (idx < count && getItemKey(idx) !== anchorKey) {\n idx++;\n }\n if (idx < count) {\n const anchorItem = newMeasurements[idx];\n if (anchorItem) {\n const newOffset = anchorItem.start + anchorOffset;\n if (newOffset !== this.scrollOffset) {\n anchorDelta = newOffset - this.scrollOffset;\n this.scrollOffset = newOffset;\n anchorResolved = true;\n }\n }\n }\n }\n if (anchorResolved || followOnAppend) {\n this.pendingScrollAnchor = [\n anchorResolved ? anchor[0] : null,\n anchorResolved ? anchor[1] : 0,\n followOnAppend,\n anchorDelta\n ];\n }\n };\n this.notify = (sync) => {\n var _a, _b;\n (_b = (_a = this.options).onChange) == null ? void 0 : _b.call(_a, this, sync);\n };\n this.maybeNotify = memo(\n () => {\n this.calculateRange();\n return [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ];\n },\n (isScrolling) => {\n this.notify(isScrolling);\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"maybeNotify\",\n debug: () => this.options.debug,\n initialDeps: [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null\n ]\n }\n );\n this.cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d());\n this.unsubs = [];\n this.observer.disconnect();\n if (this.rafId != null && this.targetWindow) {\n this.targetWindow.cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n this.scrollState = null;\n this.scrollElement = null;\n this.targetWindow = null;\n };\n this._didMount = () => {\n return () => {\n this.cleanup();\n };\n };\n this._willUpdate = () => {\n var _a;\n const scrollElement = this.options.enabled ? this.options.getScrollElement() : null;\n if (this.scrollElement !== scrollElement) {\n this.cleanup();\n if (!scrollElement) {\n this.maybeNotify();\n return;\n }\n this.scrollElement = scrollElement;\n if (this.scrollElement && \"ownerDocument\" in this.scrollElement) {\n this.targetWindow = this.scrollElement.ownerDocument.defaultView;\n } else {\n this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;\n }\n this.elementsCache.forEach((cached) => {\n this.observer.observe(cached);\n });\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect;\n this.maybeNotify();\n })\n );\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset, isScrolling) => {\n if (this._intendedScrollOffset !== null && Math.abs(offset - this._intendedScrollOffset) < 1.5) {\n offset = this._intendedScrollOffset;\n }\n this._intendedScrollOffset = null;\n this.scrollAdjustments = 0;\n this.scrollDirection = isScrolling ? this.getScrollOffset() < offset ? \"forward\" : \"backward\" : null;\n this.scrollOffset = offset;\n this.isScrolling = isScrolling;\n this._flushIosDeferredIfReady();\n if (this.scrollState) {\n this.scheduleScrollReconcile();\n }\n this.maybeNotify();\n })\n );\n if (\"addEventListener\" in this.scrollElement) {\n const scrollEl = this.scrollElement;\n const onTouchStart = () => {\n this._iosTouching = true;\n this._iosJustTouchEnded = false;\n if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {\n this.targetWindow.clearTimeout(this._iosTouchEndTimerId);\n this._iosTouchEndTimerId = null;\n }\n };\n const onTouchEnd = () => {\n this._iosTouching = false;\n if (!isIOSWebKit() || this.targetWindow == null) {\n return;\n }\n this._iosJustTouchEnded = true;\n this._iosTouchEndTimerId = this.targetWindow.setTimeout(() => {\n this._iosJustTouchEnded = false;\n this._iosTouchEndTimerId = null;\n this._flushIosDeferredIfReady();\n }, 150);\n };\n scrollEl.addEventListener(\n \"touchstart\",\n onTouchStart,\n addEventListenerOptions\n );\n scrollEl.addEventListener(\n \"touchend\",\n onTouchEnd,\n addEventListenerOptions\n );\n this.unsubs.push(() => {\n scrollEl.removeEventListener(\"touchstart\", onTouchStart);\n scrollEl.removeEventListener(\"touchend\", onTouchEnd);\n if (this._iosTouchEndTimerId !== null && this.targetWindow != null) {\n this.targetWindow.clearTimeout(this._iosTouchEndTimerId);\n this._iosTouchEndTimerId = null;\n }\n });\n }\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: void 0,\n behavior: void 0\n });\n }\n const anchor = this.pendingScrollAnchor;\n this.pendingScrollAnchor = null;\n if (anchor && this.scrollElement && this.options.enabled) {\n const [key, _offset, followOnAppend, anchorDelta] = anchor;\n if (key !== null && !followOnAppend) {\n if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {\n if (anchorDelta !== 0) {\n this._iosDeferredAdjustment += anchorDelta;\n }\n } else {\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: void 0,\n behavior: void 0\n });\n }\n }\n if (followOnAppend) {\n this.scrollToEnd({ behavior: followOnAppend });\n }\n }\n };\n this._flushIosDeferredIfReady = () => {\n if (this._iosDeferredAdjustment === 0) return;\n if (this.isScrolling) return;\n if (this._iosTouching) return;\n if (this._iosJustTouchEnded) return;\n const cur = this.getScrollOffset();\n const max = this.getMaxScrollOffset();\n if (cur < 0 || cur > max) return;\n const delta = this._iosDeferredAdjustment;\n this._iosDeferredAdjustment = 0;\n this._scrollToOffset(cur, {\n adjustments: this.scrollAdjustments += delta,\n behavior: void 0\n });\n };\n this.rafId = null;\n this.getSize = () => {\n if (!this.options.enabled) {\n this.scrollRect = null;\n return 0;\n }\n this.scrollRect = this.scrollRect ?? this.options.initialRect;\n return this.scrollRect[this.options.horizontal ? \"width\" : \"height\"];\n };\n this.getScrollOffset = () => {\n if (!this.options.enabled) {\n this.scrollOffset = null;\n return 0;\n }\n this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset === \"function\" ? this.options.initialOffset() : this.options.initialOffset);\n return this.scrollOffset;\n };\n this.getFurthestMeasurement = (measurements, index) => {\n const furthestMeasurementsFound = /* @__PURE__ */ new Map();\n const furthestMeasurements = /* @__PURE__ */ new Map();\n for (let m = index - 1; m >= 0; m--) {\n const measurement = measurements[m];\n if (furthestMeasurementsFound.has(measurement.lane)) {\n continue;\n }\n const previousFurthestMeasurement = furthestMeasurements.get(\n measurement.lane\n );\n if (previousFurthestMeasurement == null || measurement.end > previousFurthestMeasurement.end) {\n furthestMeasurements.set(measurement.lane, measurement);\n } else if (measurement.end < previousFurthestMeasurement.end) {\n furthestMeasurementsFound.set(measurement.lane, true);\n }\n if (furthestMeasurementsFound.size === this.options.lanes) {\n break;\n }\n }\n return furthestMeasurements.size === this.options.lanes ? Array.from(furthestMeasurements.values()).sort((a, b) => {\n if (a.end === b.end) {\n return a.index - b.index;\n }\n return a.end - b.end;\n })[0] : void 0;\n };\n this.getMeasurementOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.options.enabled,\n this.options.lanes,\n this.options.laneAssignmentMode\n ],\n (count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode) => {\n const lanesChanged = this.prevLanes !== void 0 && this.prevLanes !== lanes;\n if (lanesChanged) {\n this.lanesChangedFlag = true;\n }\n this.prevLanes = lanes;\n this.pendingMin = null;\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode\n };\n },\n {\n key: false\n }\n );\n this.getMeasurements = memo(\n () => [this.getMeasurementOptions(), this.itemSizeCacheVersion],\n ({\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n enabled,\n lanes,\n laneAssignmentMode\n }, _itemSizeCacheVersion) => {\n const itemSizeCache = this.itemSizeCache;\n if (!enabled) {\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n return [];\n }\n if (this.laneAssignments.size > count) {\n for (const index of this.laneAssignments.keys()) {\n if (index >= count) {\n this.laneAssignments.delete(index);\n }\n }\n }\n if (this.lanesChangedFlag) {\n this.lanesChangedFlag = false;\n this.lanesSettling = true;\n this.measurementsCache = [];\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n this.pendingMin = null;\n }\n if (this.measurementsCache.length === 0 && !this.lanesSettling) {\n this.measurementsCache = this.options.initialMeasurementsCache;\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache.set(item.key, item.size);\n });\n }\n const min = this.lanesSettling ? 0 : this.pendingMin ?? 0;\n this.pendingMin = null;\n if (this.lanesSettling && this.measurementsCache.length === count) {\n this.lanesSettling = false;\n }\n if (lanes === 1) {\n const gap = this.options.gap;\n const need = count * 2;\n let flat = this._flatMeasurements;\n if (!flat || flat.length < need) {\n const next = new Float64Array(need);\n if (flat && min > 0) next.set(flat.subarray(0, min * 2));\n flat = next;\n this._flatMeasurements = flat;\n }\n let runningStart;\n if (min === 0) {\n runningStart = paddingStart + scrollMargin;\n } else {\n const prevIdx = min - 1;\n runningStart = flat[prevIdx * 2] + flat[prevIdx * 2 + 1] + gap;\n }\n for (let i = min; i < count; i++) {\n const key = getItemKey(i);\n const measuredSize = itemSizeCache.get(key);\n const size = typeof measuredSize === \"number\" ? measuredSize : this.options.estimateSize(i);\n flat[i * 2] = runningStart;\n flat[i * 2 + 1] = size;\n runningStart += size + gap;\n }\n const view = createLazyMeasurementsView(count, flat, getItemKey);\n this.measurementsCache = view;\n return view;\n }\n const measurements = this.measurementsCache.slice(0, min);\n const laneLastIndex = new Array(lanes).fill(\n void 0\n );\n for (let m = 0; m < min; m++) {\n const item = measurements[m];\n if (item) {\n laneLastIndex[item.lane] = m;\n }\n }\n for (let i = min; i < count; i++) {\n const key = getItemKey(i);\n const cachedLane = this.laneAssignments.get(i);\n let lane;\n let start;\n const shouldCacheLane = laneAssignmentMode === \"estimate\" || itemSizeCache.has(key);\n if (cachedLane !== void 0 && this.options.lanes > 1) {\n lane = cachedLane;\n const prevIndex = laneLastIndex[lane];\n const prevInLane = prevIndex !== void 0 ? measurements[prevIndex] : void 0;\n start = prevInLane ? prevInLane.end + this.options.gap : paddingStart + scrollMargin;\n } else {\n const furthestMeasurement = this.options.lanes === 1 ? measurements[i - 1] : this.getFurthestMeasurement(measurements, i);\n start = furthestMeasurement ? furthestMeasurement.end + this.options.gap : paddingStart + scrollMargin;\n lane = furthestMeasurement ? furthestMeasurement.lane : i % this.options.lanes;\n if (this.options.lanes > 1 && shouldCacheLane) {\n this.laneAssignments.set(i, lane);\n }\n }\n const measuredSize = itemSizeCache.get(key);\n const size = typeof measuredSize === \"number\" ? measuredSize : this.options.estimateSize(i);\n const end = start + size;\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane\n };\n laneLastIndex[lane] = i;\n }\n this.measurementsCache = measurements;\n return measurements;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getMeasurements\",\n debug: () => this.options.debug\n }\n );\n this.calculateRange = memo(\n () => [\n this.getMeasurements(),\n this.getSize(),\n this.getScrollOffset(),\n this.options.lanes\n ],\n (measurements, outerSize, scrollOffset, lanes) => {\n return this.range = measurements.length > 0 && outerSize > 0 ? calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes,\n // Pass the typed array so binary search + forward-walk can\n // read start/end directly from Float64Array, skipping the\n // Proxy traps that materialize a full VirtualItem per probe.\n flat: lanes === 1 && this._flatMeasurements != null ? this._flatMeasurements : null\n }) : null;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"calculateRange\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualIndexes = memo(\n () => {\n let startIndex = null;\n let endIndex = null;\n const range = this.calculateRange();\n if (range) {\n startIndex = range.startIndex;\n endIndex = range.endIndex;\n }\n this.maybeNotify.updateDeps([this.isScrolling, startIndex, endIndex]);\n return [\n this.options.rangeExtractor,\n this.options.overscan,\n this.options.count,\n startIndex,\n endIndex\n ];\n },\n (rangeExtractor, overscan, count, startIndex, endIndex) => {\n return startIndex === null || endIndex === null ? [] : rangeExtractor({\n startIndex,\n endIndex,\n overscan,\n count\n });\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualIndexes\",\n debug: () => this.options.debug\n }\n );\n this.indexFromElement = (node) => {\n const attributeName = this.options.indexAttribute;\n const indexStr = node.getAttribute(attributeName);\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`\n );\n return -1;\n }\n return parseInt(indexStr, 10);\n };\n this.shouldMeasureDuringScroll = (index) => {\n var _a;\n if (!this.scrollState || this.scrollState.behavior !== \"smooth\") {\n return true;\n }\n const scrollIndex = this.scrollState.index ?? ((_a = this.getVirtualItemForOffset(this.scrollState.lastTargetOffset)) == null ? void 0 : _a.index);\n if (scrollIndex !== void 0 && this.range) {\n const bufferSize = Math.max(\n this.options.overscan,\n Math.ceil((this.range.endIndex - this.range.startIndex) / 2)\n );\n const minIndex = Math.max(0, scrollIndex - bufferSize);\n const maxIndex = Math.min(\n this.options.count - 1,\n scrollIndex + bufferSize\n );\n return index >= minIndex && index <= maxIndex;\n }\n return true;\n };\n this.measureElement = (node) => {\n if (!node) {\n this.elementsCache.forEach((cached, key2) => {\n if (!cached.isConnected) {\n this.observer.unobserve(cached);\n this.elementsCache.delete(key2);\n }\n });\n return;\n }\n const index = this.indexFromElement(node);\n const key = this.options.getItemKey(index);\n const prevNode = this.elementsCache.get(key);\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode);\n }\n this.observer.observe(node);\n this.elementsCache.set(key, node);\n }\n if ((!this.isScrolling || this.scrollState) && this.shouldMeasureDuringScroll(index)) {\n this.resizeItem(index, this.options.measureElement(node, void 0, this));\n }\n };\n this.resizeItem = (index, size) => {\n var _a, _b;\n if (index < 0 || index >= this.options.count) return;\n let cachedSize;\n let itemStart;\n let key;\n const flat = this._flatMeasurements;\n if (this.options.lanes === 1 && flat !== null) {\n key = this.options.getItemKey(index);\n itemStart = flat[index * 2];\n cachedSize = flat[index * 2 + 1];\n } else {\n const item = this.measurementsCache[index];\n if (!item) return;\n key = item.key;\n itemStart = item.start;\n cachedSize = item.size;\n }\n const itemSize = this.itemSizeCache.get(key) ?? cachedSize;\n const delta = size - itemSize;\n if (delta !== 0) {\n const wasAtEnd = this.options.anchorTo === \"end\" && ((_a = this.scrollState) == null ? void 0 : _a.behavior) !== \"smooth\" && this.getVirtualDistanceFromEnd() <= this.options.scrollEndThreshold;\n const prevTotalSize = wasAtEnd ? this.getTotalSize() : 0;\n const shouldAdjustScroll = ((_b = this.scrollState) == null ? void 0 : _b.behavior) !== \"smooth\" && (this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(\n // The callback expects a VirtualItem; build one lazily only\n // when the consumer actually supplied a custom predicate.\n this.measurementsCache[index] ?? {\n index,\n key,\n start: itemStart,\n size: cachedSize,\n end: itemStart + cachedSize,\n lane: 0\n },\n delta,\n this\n ) : (\n // Default: adjust scrollTop only when the resize is an above-\n // viewport item AND we're not actively scrolling backward.\n // Adjusting during backward scroll fights the user's scroll\n // direction and produces the \"items jump while scrolling up\"\n // jank reported across many issues. Users who want the old\n // behavior can pass shouldAdjustScrollPositionOnItemSizeChange.\n itemStart < this.getScrollOffset() + this.scrollAdjustments && this.scrollDirection !== \"backward\"\n ));\n if (this.pendingMin === null || index < this.pendingMin) {\n this.pendingMin = index;\n }\n this.itemSizeCache.set(key, size);\n this.itemSizeCacheVersion++;\n if (wasAtEnd) {\n this.applyScrollAdjustment(this.getTotalSize() - prevTotalSize);\n } else if (shouldAdjustScroll) {\n this.applyScrollAdjustment(delta);\n }\n this.notify(false);\n }\n };\n this.getVirtualItems = memo(\n () => [this.getVirtualIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems = [];\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k];\n const measurement = measurements[i];\n virtualItems.push(measurement);\n }\n return virtualItems;\n },\n {\n key: process.env.NODE_ENV !== \"production\" && \"getVirtualItems\",\n debug: () => this.options.debug\n }\n );\n this.getVirtualItemForOffset = (offset) => {\n const measurements = this.getMeasurements();\n if (measurements.length === 0) {\n return void 0;\n }\n const flat = this._flatMeasurements;\n const useFlat = this.options.lanes === 1 && flat != null;\n const idx = findNearestBinarySearch(\n 0,\n measurements.length - 1,\n useFlat ? (i) => flat[i * 2] : (i) => notUndefined(measurements[i]).start,\n offset\n );\n return notUndefined(measurements[idx]);\n };\n this.getMaxScrollOffset = () => {\n if (!this.scrollElement) return 0;\n if (\"scrollHeight\" in this.scrollElement) {\n return this.options.horizontal ? this.scrollElement.scrollWidth - this.scrollElement.clientWidth : this.scrollElement.scrollHeight - this.scrollElement.clientHeight;\n } else {\n const doc = this.scrollElement.document.documentElement;\n return this.options.horizontal ? doc.scrollWidth - this.scrollElement.innerWidth : doc.scrollHeight - this.scrollElement.innerHeight;\n }\n };\n this.getVirtualDistanceFromEnd = () => {\n return Math.max(\n this.getTotalSize() - this.getSize() - this.getScrollOffset(),\n 0\n );\n };\n this.getDistanceFromEnd = () => {\n return Math.max(this.getMaxScrollOffset() - this.getScrollOffset(), 0);\n };\n this.isAtEnd = (threshold = this.options.scrollEndThreshold) => {\n return this.getDistanceFromEnd() <= threshold;\n };\n this.getOffsetForAlignment = (toOffset, align, itemSize = 0) => {\n if (!this.scrollElement) return 0;\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n if (align === \"auto\") {\n align = toOffset >= scrollOffset + size ? \"end\" : \"start\";\n }\n if (align === \"center\") {\n toOffset += (itemSize - size) / 2;\n } else if (align === \"end\") {\n toOffset -= size;\n }\n const maxOffset = this.getMaxScrollOffset();\n return Math.max(Math.min(maxOffset, toOffset), 0);\n };\n this.getOffsetForIndex = (index, align = \"auto\") => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\n const item = this.measurementsCache[index];\n if (!item) return;\n if (align === \"auto\") {\n if (item.end >= scrollOffset + size - this.options.scrollPaddingEnd) {\n align = \"end\";\n } else if (item.start <= scrollOffset + this.options.scrollPaddingStart) {\n align = \"start\";\n } else {\n return [scrollOffset, align];\n }\n }\n if (align === \"end\" && index === this.options.count - 1) {\n return [this.getMaxScrollOffset(), align];\n }\n const toOffset = align === \"end\" ? item.end + this.options.scrollPaddingEnd : item.start - this.options.scrollPaddingStart;\n return [\n this.getOffsetForAlignment(toOffset, align, item.size),\n align\n ];\n };\n this.scrollToOffset = (toOffset, { align = \"start\", behavior = \"auto\" } = {}) => {\n const offset = this.getOffsetForAlignment(toOffset, align);\n const now = this.now();\n this.scrollState = {\n index: null,\n align,\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0\n };\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.scheduleScrollReconcile();\n };\n this.scrollToIndex = (index, {\n align: initialAlign = \"auto\",\n behavior = \"auto\"\n } = {}) => {\n index = Math.max(0, Math.min(index, this.options.count - 1));\n const offsetInfo = this.getOffsetForIndex(index, initialAlign);\n if (!offsetInfo) {\n return;\n }\n const [offset, align] = offsetInfo;\n const now = this.now();\n this.scrollState = {\n index,\n align,\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0\n };\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.scheduleScrollReconcile();\n };\n this.scrollBy = (delta, { behavior = \"auto\" } = {}) => {\n const offset = this.getScrollOffset() + delta;\n const now = this.now();\n this.scrollState = {\n index: null,\n align: \"start\",\n behavior,\n startedAt: now,\n lastTargetOffset: offset,\n stableFrames: 0\n };\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.scheduleScrollReconcile();\n };\n this.scrollToEnd = ({ behavior = \"auto\" } = {}) => {\n if (this.options.count > 0) {\n this.scrollToIndex(this.options.count - 1, {\n align: \"end\",\n behavior\n });\n return;\n }\n this.scrollToOffset(Math.max(this.getTotalSize() - this.getSize(), 0), {\n behavior\n });\n };\n this.getTotalSize = () => {\n var _a;\n const measurements = this.getMeasurements();\n let end;\n if (measurements.length === 0) {\n end = this.options.paddingStart;\n } else if (this.options.lanes === 1) {\n const lastIdx = measurements.length - 1;\n const flat = this._flatMeasurements;\n if (flat != null) {\n end = flat[lastIdx * 2] + flat[lastIdx * 2 + 1];\n } else {\n end = ((_a = measurements[lastIdx]) == null ? void 0 : _a.end) ?? 0;\n }\n } else {\n const endByLane = Array(this.options.lanes).fill(null);\n let endIndex = measurements.length - 1;\n while (endIndex >= 0 && endByLane.some((val) => val === null)) {\n const item = measurements[endIndex];\n if (endByLane[item.lane] === null) {\n endByLane[item.lane] = item.end;\n }\n endIndex--;\n }\n end = Math.max(...endByLane.filter((val) => val !== null));\n }\n return Math.max(\n end - this.options.scrollMargin + this.options.paddingEnd,\n 0\n );\n };\n this.takeSnapshot = () => {\n const snapshot = [];\n if (this.itemSizeCache.size === 0) return snapshot;\n const m = this.getMeasurements();\n for (const item of m) {\n if (item && this.itemSizeCache.has(item.key)) {\n snapshot.push({\n index: item.index,\n key: item.key,\n start: item.start,\n size: item.size,\n end: item.end,\n lane: item.lane\n });\n }\n }\n return snapshot;\n };\n this._scrollToOffset = (offset, {\n adjustments,\n behavior\n }) => {\n this._intendedScrollOffset = offset + (adjustments ?? 0);\n this.options.scrollToFn(offset, { behavior, adjustments }, this);\n };\n this.measure = () => {\n this.pendingMin = null;\n this.itemSizeCache.clear();\n this.laneAssignments.clear();\n this.itemSizeCacheVersion++;\n this.notify(false);\n };\n this.setOptions(opts);\n }\n applyScrollAdjustment(delta, behavior) {\n if (delta === 0) return;\n if (process.env.NODE_ENV !== \"production\" && this.options.debug) {\n console.info(\"correction\", delta);\n }\n if (isIOSWebKit() && (this.isScrolling || this._iosTouching || this._iosJustTouchEnded)) {\n this._iosDeferredAdjustment += delta;\n } else {\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: this.scrollAdjustments += delta,\n behavior\n });\n }\n }\n scheduleScrollReconcile() {\n if (!this.targetWindow) {\n this.scrollState = null;\n return;\n }\n if (this.rafId != null) return;\n this.rafId = this.targetWindow.requestAnimationFrame(() => {\n this.rafId = null;\n this.reconcileScroll();\n });\n }\n reconcileScroll() {\n if (!this.scrollState) return;\n const el = this.scrollElement;\n if (!el) return;\n const MAX_RECONCILE_MS = 5e3;\n if (this.now() - this.scrollState.startedAt > MAX_RECONCILE_MS) {\n this.scrollState = null;\n return;\n }\n const offsetInfo = this.scrollState.index != null ? this.getOffsetForIndex(this.scrollState.index, this.scrollState.align) : void 0;\n const targetOffset = offsetInfo ? offsetInfo[0] : this.scrollState.lastTargetOffset;\n const STABLE_FRAMES = 1;\n const targetChanged = targetOffset !== this.scrollState.lastTargetOffset;\n if (!targetChanged && approxEqual(targetOffset, this.getScrollOffset())) {\n this.scrollState.stableFrames++;\n if (this.scrollState.stableFrames >= STABLE_FRAMES) {\n if (this.getScrollOffset() !== targetOffset) {\n this._scrollToOffset(targetOffset, {\n adjustments: void 0,\n behavior: \"auto\"\n });\n }\n this.scrollState = null;\n return;\n }\n } else {\n this.scrollState.stableFrames = 0;\n if (targetChanged) {\n const viewport = this.getSize() || 600;\n const distance = Math.abs(targetOffset - this.getScrollOffset());\n const keepSmooth = this.scrollState.behavior === \"smooth\" && distance > viewport;\n this.scrollState.lastTargetOffset = targetOffset;\n if (!keepSmooth) {\n this.scrollState.behavior = \"auto\";\n }\n this._scrollToOffset(targetOffset, {\n adjustments: void 0,\n behavior: keepSmooth ? \"smooth\" : \"auto\"\n });\n }\n }\n this.scheduleScrollReconcile();\n }\n}\nconst findNearestBinarySearch = (low, high, getCurrentValue, value) => {\n while (low <= high) {\n const middle = (low + high) / 2 | 0;\n const currentValue = getCurrentValue(middle);\n if (currentValue < value) {\n low = middle + 1;\n } else if (currentValue > value) {\n high = middle - 1;\n } else {\n return middle;\n }\n }\n if (low > 0) {\n return low - 1;\n } else {\n return 0;\n }\n};\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n lanes,\n flat\n}) {\n const lastIndex = measurements.length - 1;\n const getStart = flat ? (index) => flat[index * 2] : (index) => measurements[index].start;\n const getEnd = flat ? (index) => flat[index * 2] + flat[index * 2 + 1] : (index) => measurements[index].end;\n if (measurements.length <= lanes) {\n return {\n startIndex: 0,\n endIndex: lastIndex\n };\n }\n let startIndex = findNearestBinarySearch(0, lastIndex, getStart, scrollOffset);\n let endIndex = startIndex;\n if (lanes === 1) {\n while (endIndex < lastIndex && getEnd(endIndex) < scrollOffset + outerSize) {\n endIndex++;\n }\n } else if (lanes > 1) {\n const endPerLane = Array(lanes).fill(0);\n while (endIndex < lastIndex && endPerLane.some((pos) => pos < scrollOffset + outerSize)) {\n const item = measurements[endIndex];\n endPerLane[item.lane] = item.end;\n endIndex++;\n }\n const startPerLane = Array(lanes).fill(scrollOffset + outerSize);\n while (startIndex >= 0 && startPerLane.some((pos) => pos >= scrollOffset)) {\n const item = measurements[startIndex];\n startPerLane[item.lane] = item.start;\n startIndex--;\n }\n startIndex = Math.max(0, startIndex - startIndex % lanes);\n endIndex = Math.min(lastIndex, endIndex + (lanes - 1 - endIndex % lanes));\n }\n return { startIndex, endIndex };\n}\nexport {\n Virtualizer,\n _resetIOSDetectionForTests,\n approxEqual,\n debounce,\n defaultKeyExtractor,\n defaultRangeExtractor,\n elementScroll,\n measureElement,\n memo,\n notUndefined,\n observeElementOffset,\n observeElementRect,\n observeWindowOffset,\n observeWindowRect,\n windowScroll\n};\n//# sourceMappingURL=index.js.map\n","import * as React from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { Virtualizer, elementScroll, observeElementOffset, observeElementRect, windowScroll, observeWindowOffset, observeWindowRect } from \"@tanstack/virtual-core\";\nexport * from \"@tanstack/virtual-core\";\nconst useIsomorphicLayoutEffect = typeof document !== \"undefined\" ? React.useLayoutEffect : React.useEffect;\nfunction useVirtualizerBase({\n useFlushSync = true,\n directDomUpdates = false,\n directDomUpdatesMode = \"transform\",\n ...options\n}) {\n const rerender = React.useReducer((x) => x + 1, 0)[1];\n const directRef = React.useRef({\n enabled: directDomUpdates,\n mode: directDomUpdatesMode,\n container: null,\n lastSize: null,\n // Keyed by the element itself so a remounted node (same key, new DOM\n // node — e.g. when `enabled` is toggled off then on) is treated as fresh\n // and gets its style written.\n lastPositions: /* @__PURE__ */ new WeakMap(),\n prevRange: null\n });\n directRef.current.enabled = directDomUpdates;\n directRef.current.mode = directDomUpdatesMode;\n const applyDirectStyles = (instance2) => {\n const state = directRef.current;\n if (!state.enabled) return;\n const totalSize = instance2.getTotalSize();\n if (state.container && totalSize !== state.lastSize) {\n state.lastSize = totalSize;\n const sizeAxis = instance2.options.horizontal ? \"width\" : \"height\";\n state.container.style[sizeAxis] = `${totalSize}px`;\n }\n const horizontal = !!instance2.options.horizontal;\n const useTransform = state.mode === \"transform\";\n const posAxis = horizontal ? \"left\" : \"top\";\n const scrollMargin = instance2.options.scrollMargin;\n const items = instance2.getVirtualItems();\n for (const item of items) {\n const next = item.start - scrollMargin;\n const el = instance2.elementsCache.get(item.key);\n if (!el) continue;\n if (state.lastPositions.get(el) === next) continue;\n state.lastPositions.set(el, next);\n if (useTransform) {\n el.style.transform = horizontal ? `translate3d(${next}px, 0, 0)` : `translate3d(0, ${next}px, 0)`;\n } else {\n el.style[posAxis] = `${next}px`;\n }\n }\n };\n const resolvedOptions = {\n ...options,\n onChange: (instance2, sync) => {\n var _a;\n const state = directRef.current;\n let shouldRerender = true;\n if (state.enabled) {\n applyDirectStyles(instance2);\n const range = instance2.range;\n const prev = state.prevRange;\n shouldRerender = !prev || prev.isScrolling !== instance2.isScrolling || prev.startIndex !== (range == null ? void 0 : range.startIndex) || prev.endIndex !== (range == null ? void 0 : range.endIndex);\n if (shouldRerender) {\n state.prevRange = range ? {\n startIndex: range.startIndex,\n endIndex: range.endIndex,\n isScrolling: instance2.isScrolling\n } : null;\n }\n }\n if (shouldRerender) {\n if (useFlushSync && sync) {\n flushSync(rerender);\n } else {\n rerender();\n }\n }\n (_a = options.onChange) == null ? void 0 : _a.call(options, instance2, sync);\n }\n };\n const [instance] = React.useState(() => {\n const v = new Virtualizer(resolvedOptions);\n return Object.assign(v, {\n containerRef: (node) => {\n const state = directRef.current;\n state.container = node;\n state.lastSize = null;\n if (node && state.enabled) {\n const total = v.getTotalSize();\n state.lastSize = total;\n const axis = v.options.horizontal ? \"width\" : \"height\";\n node.style[axis] = `${total}px`;\n }\n }\n });\n });\n instance.setOptions(resolvedOptions);\n useIsomorphicLayoutEffect(() => {\n return instance._didMount();\n }, []);\n useIsomorphicLayoutEffect(() => {\n return instance._willUpdate();\n });\n useIsomorphicLayoutEffect(() => {\n applyDirectStyles(instance);\n });\n return instance;\n}\nfunction useVirtualizer(options) {\n return useVirtualizerBase({\n observeElementRect,\n observeElementOffset,\n scrollToFn: elementScroll,\n ...options\n });\n}\nfunction useWindowVirtualizer(options) {\n return useVirtualizerBase({\n getScrollElement: () => typeof document !== \"undefined\" ? window : null,\n observeElementRect: observeWindowRect,\n observeElementOffset: observeWindowOffset,\n scrollToFn: windowScroll,\n initialOffset: () => typeof document !== \"undefined\" ? window.scrollY : 0,\n ...options\n });\n}\nexport {\n useVirtualizer,\n useWindowVirtualizer\n};\n//# sourceMappingURL=index.js.map\n","/* Virtual List Container */\r\n.virtualList {\r\n position: relative;\r\n overflow: auto;\r\n contain: strict;\r\n width: 100%;\r\n padding-bottom: 300px;\r\n}\r\n\r\n/* Empty State Container */\r\n.emptyContainer {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100%;\r\n color: var(--color-fg-muted);\r\n}\r\n\r\n/* Virtual List Inner Container */\r\n.virtualListInner {\r\n width: 100%;\r\n position: relative;\r\n}\r\n\r\n/* Virtual List Items Wrapper */\r\n.virtualListItems {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n}\r\n\r\n/* Loading More Indicator */\r\n.loadingMore {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 0.75rem;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n}\r\n\r\n/* End of List Indicator */\r\n.endOfList {\r\n display: flex;\r\n justify-content: center;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n font-size: 0.875rem;\r\n border-top: 1px solid var(--color-border-3);\r\n margin-top: 1rem;\r\n}\r\n\r\n.endOfList span {\r\n padding: 0.5rem 1rem;\r\n background-color: var(--color-bg-2);\r\n border-radius: var(--radius-button);\r\n}","/**\n * 虚拟列表:基于 @tanstack/react-virtual,支持无限滚动 fetchNextPage。Virtual list; @tanstack/react-virtual, fetchNextPage.\n *\n * @example\n * ```tsx\n * * 与 useInfiniteQuery 配合,data 为 pages 拍平后的 items\n * <VirtualList data={items} getItemKey={(i) => i.id} renderItem={(i) => <Row item={i} />} hasNextPage fetchNextPage={fetchNextPage} />\n * ```\n */\nimport type { VirtualizerOptions } from \"@tanstack/react-virtual\";\nimport type { ReactNode } from \"react\";\n\nimport { memo, useCallback, useEffect, useRef } from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface VirtualListProps<T> extends Partial<\n Omit<\n VirtualizerOptions<HTMLDivElement, Element>,\n \"count\" | \"getScrollElement\" | \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"getItemKey\" | \"estimateSize\"\n >\n> {\n /** 数据列表。Data array. */\n data: T[];\n /** 是否有下一页。Has next page. */\n hasNextPage?: boolean;\n /** 是否正在拉取下一页。Is fetching next page. */\n isFetchingNextPage?: boolean;\n /** 拉取下一页。Fetch next page. */\n fetchNextPage?: () => void;\n /** 单项渲染。Render item. */\n renderItem: (item: T, index: number) => ReactNode;\n /** 单项高度估计。Estimate item size. */\n estimateSize?: number | ((index: number) => number);\n /** 列表高度。List height. */\n height?: string | number;\n /** 单项 key。Get item key. */\n getItemKey: (item: T, index: number) => string | number;\n /** 空状态自定义节点。Empty state node. */\n emptyState?: ReactNode;\n /** 加载更多指示器。Loading indicator node. */\n loadingIndicator?: ReactNode;\n /** 列表底指示器。End of list indicator node. */\n endOfListIndicator?: ReactNode;\n /** 当未提供 emptyState 时使用的文案,由调用方传入。Text when no data; used when emptyState not provided. */\n emptyText?: ReactNode;\n /** 当未提供 loadingIndicator 时使用的文案。Text when loading more. */\n loadingMoreText?: ReactNode;\n /** 当未提供 endOfListIndicator 时使用的文案。Text at end of list. */\n endOfListText?: ReactNode;\n /** 列表项容器 className。Flex container class. */\n flexClass?: string;\n /** 外层容器 className。Outer class. */\n outerClass?: string;\n /** 内层容器 className。Inner class. */\n innerClass?: string;\n}\n\nfunction VirtualListComponent<T>({\n data,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n renderItem,\n estimateSize = 200,\n overscan = 5,\n height = \"600px\",\n getItemKey,\n emptyState,\n loadingIndicator,\n endOfListIndicator,\n emptyText = \"No data\",\n loadingMoreText = \"Loading more...\",\n endOfListText = \"No more items\",\n flexClass,\n outerClass,\n innerClass,\n ...virtualizerOptions\n}: VirtualListProps<T>) {\n const parentRef = useRef<HTMLDivElement>(null);\n\n // 防御性检查:确保 data 是数组\n const safeData = Array.isArray(data) ? data : [];\n const dataLength = safeData.length;\n\n // Setup virtualizer\n // eslint-disable-next-line react-hooks/incompatible-library\n const rowVirtualizer = useVirtualizer({\n count: hasNextPage ? dataLength + 1 : dataLength,\n getScrollElement: () => parentRef.current,\n estimateSize: typeof estimateSize === \"number\" ? () => estimateSize : estimateSize,\n overscan,\n ...virtualizerOptions,\n });\n\n const items = rowVirtualizer.getVirtualItems();\n\n // Auto-fetch when scrolling near bottom (following official pattern)\n useEffect(() => {\n const [lastItem] = [...items].reverse();\n\n if (!lastItem) {\n return;\n }\n\n if (lastItem.index >= dataLength - 1 && hasNextPage && !isFetchingNextPage && fetchNextPage) {\n fetchNextPage();\n }\n }, [hasNextPage, fetchNextPage, dataLength, isFetchingNextPage, items]);\n\n const renderEmptyState = useCallback(() => {\n return (\n <div\n className={styles.virtualList}\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n }}\n >\n {emptyState ?? (\n <div className={styles.emptyContainer}>\n <span>{emptyText}</span>\n </div>\n )}\n </div>\n );\n }, [emptyState, height, emptyText]);\n\n const renderLoadingIndicator = useCallback(() => {\n if (loadingIndicator) return loadingIndicator;\n return (\n <div className={styles.loadingMore}>\n <span>{loadingMoreText}</span>\n </div>\n );\n }, [loadingIndicator, loadingMoreText]);\n\n const renderEndOfListIndicator = useCallback(() => {\n if (endOfListIndicator) return endOfListIndicator;\n return (\n <div className={styles.endOfList}>\n <span>{endOfListText}</span>\n </div>\n );\n }, [endOfListIndicator, endOfListText]);\n\n // Show empty state if no data\n if (dataLength === 0) return renderEmptyState();\n\n return (\n <div\n ref={parentRef}\n className={`${styles.virtualList} ${outerClass ?? \"\"}`}\n style={{\n height: typeof height === \"number\" ? `${height}px` : height,\n }}\n >\n <div\n className={`${styles.virtualListInner} ${innerClass ?? \"\"}`}\n style={{\n height: `${rowVirtualizer.getTotalSize()}px`,\n }}\n >\n <div\n className={`${styles.virtualListItems} ${flexClass ?? \"\"}`}\n style={{\n transform: `translateY(${items[0]?.start ?? 0}px)`,\n paddingTop: `2px`,\n }}\n >\n {items.map((virtualRow) => {\n const isLoaderRow = virtualRow.index > dataLength - 1;\n const item = safeData[virtualRow.index];\n\n return (\n <div key={virtualRow.key} data-index={virtualRow.index} ref={rowVirtualizer.measureElement}>\n {isLoaderRow ? (\n hasNextPage ? (\n renderLoadingIndicator()\n ) : (\n renderEndOfListIndicator()\n )\n ) : (\n <div key={getItemKey(item, virtualRow.index)}>{renderItem(item, virtualRow.index)}</div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\n// Use memo with generic type\nconst VirtualList = memo(VirtualListComponent) as typeof VirtualListComponent;\nexport default VirtualList;\n","/* 外层容器 */\r\n.virtualList {\r\n width: 100%;\r\n position: relative;\r\n overflow: visible; /* ✅ window 滚动,不是列表滚动 */\r\n padding-bottom: 300px;\r\n }\r\n \r\n /* 内层:撑出总高度 */\r\n .virtualListInner {\r\n width: 100%;\r\n position: relative;\r\n }\r\n \r\n /* 基于 translateY 的内容容器 */\r\n .virtualListItems {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n }\r\n \r\n /* 行样式(你不一定用得上,但可选) */\r\n .virtualListRow {\r\n width: 100%;\r\n }\r\n \r\n /* 无数据 */\r\n .emptyContainer {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 2rem 0;\r\n color: var(--color-fg-muted);\r\n }\r\n \r\n /* 加载中 */\r\n .loadingMore {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 1.5rem 0;\r\n color: var(--color-fg-muted);\r\n }\r\n \r\n /* 末尾提示 */\r\n .endOfList {\r\n display: flex;\r\n justify-content: center;\r\n padding: 1.5rem 0;\r\n color: var(--color-fg-muted);\r\n border-top: 1px solid var(--color-border-3);\r\n }\r\n ","/**\n * 窗口虚拟列表:基于 useWindowVirtualizer,相对视口滚动。Window virtual list; uses useWindowVirtualizer, scroll relative to viewport.\n *\n * @example\n * ```tsx\n * * 与无限列表数据配合\n * <VirtualWindowList\n * data={items}\n * getItemKey={(item) => item.id}\n * renderItem={(item) => <Row item={item} />}\n * hasNextPage={hasNextPage}\n * fetchNextPage={fetchNextPage}\n * />\n * ```\n */\nimport type { VirtualizerOptions } from \"@tanstack/react-virtual\";\nimport type { ReactNode } from \"react\";\n\nimport { memo, useCallback, useEffect } from \"react\";\nimport { useWindowVirtualizer } from \"@tanstack/react-virtual\";\n\nimport styles from \"./styles.module.css\";\n\nexport interface VirtualWindowListProps<T> extends Partial<\n Omit<\n VirtualizerOptions<Window, Element>,\n \"count\" | \"getScrollElement\" | \"observeElementRect\" | \"observeElementOffset\" | \"scrollToFn\" | \"estimateSize\" | \"getItemKey\"\n >\n> {\n /** 数据列表。Data array. */\n data: T[];\n /** 是否有下一页。Has next page. */\n hasNextPage?: boolean;\n /** 是否正在拉取下一页。Is fetching next page. */\n isFetchingNextPage?: boolean;\n /** 拉取下一页。Fetch next page. */\n fetchNextPage?: () => void;\n /** 单项渲染。Render item. */\n renderItem: (item: T, index: number) => ReactNode;\n /** 单项高度估计。Estimate item size. */\n estimateSize?: number | ((index: number) => number);\n /** 列表高度。List height. */\n height?: string | number;\n /** 单项 key。Get item key. */\n getItemKey: (item: T, index: number) => string | number;\n /** 空状态自定义节点。Empty state node. */\n emptyState?: ReactNode;\n /** 加载更多指示器。Loading indicator node. */\n loadingIndicator?: ReactNode;\n /** 列表底指示器。End of list indicator node. */\n endOfListIndicator?: ReactNode;\n /** 空状态文案(未提供 emptyState 时)。Empty text. */\n emptyText?: ReactNode;\n /** 加载更多文案。Loading more text. */\n loadingMoreText?: ReactNode;\n /** 列表底文案。End of list text. */\n endOfListText?: ReactNode;\n /** 列表项容器 className。Flex container class. */\n flexClass?: string;\n /** 外层容器 className。Outer class. */\n outerClass?: string;\n /** 内层容器 className。Inner class. */\n innerClass?: string;\n}\n\n/* -------------------------------------------\n ✅ MAIN COMPONENT\n-------------------------------------------- */\nfunction VirtualWindowListComponent<T>({\n data,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n renderItem,\n estimateSize = 200,\n overscan = 5,\n height,\n getItemKey,\n\n emptyState,\n loadingIndicator,\n endOfListIndicator,\n emptyText = \"No data\",\n loadingMoreText = \"Loading more...\",\n endOfListText = \"No more items\",\n flexClass,\n outerClass,\n innerClass,\n ...virtualizerOptions\n}: VirtualWindowListProps<T>) {\n /* ✅ 防御性检查:确保 data 是数组 */\n const safeData = Array.isArray(data) ? data : [];\n const dataLength = safeData.length;\n\n /* ✅ 真正的 window 虚拟滚动器 */\n const virtualizer = useWindowVirtualizer({\n count: hasNextPage ? dataLength + 1 : dataLength,\n estimateSize: typeof estimateSize === \"number\" ? () => estimateSize : estimateSize,\n overscan,\n ...virtualizerOptions,\n });\n\n const items = virtualizer.getVirtualItems();\n\n /* ✅ 自动加载更多 */\n useEffect(() => {\n const last = items[items.length - 1];\n if (!last) return;\n\n const isLoaderRow = last.index >= dataLength;\n\n if (isLoaderRow && hasNextPage && !isFetchingNextPage && fetchNextPage) {\n fetchNextPage();\n }\n }, [items, hasNextPage, isFetchingNextPage, fetchNextPage, dataLength]);\n\n const renderEmptyState = useCallback(() => {\n return (\n <div\n className={styles.virtualList}\n style={{\n height: typeof height === \"number\" ? `${height}px` : (height ?? \"auto\"),\n }}\n >\n {emptyState ?? (\n <div className={styles.emptyContainer}>\n <span>{emptyText}</span>\n </div>\n )}\n </div>\n );\n }, [emptyState, height, emptyText]);\n\n const renderLoadingIndicator = useCallback(() => {\n return (\n loadingIndicator ?? (\n <div className={styles.loadingMore}>\n <span>{loadingMoreText}</span>\n </div>\n )\n );\n }, [loadingIndicator, loadingMoreText]);\n\n const renderEndOfListIndicator = useCallback(() => {\n return (\n endOfListIndicator ?? (\n <div className={styles.endOfList}>\n <span>{endOfListText}</span>\n </div>\n )\n );\n }, [endOfListIndicator, endOfListText]);\n\n /* ✅ 无数据情况 */\n if (dataLength === 0) return renderEmptyState();\n\n /* ✅ 正常渲染 */\n return (\n <div className={`${styles.virtualList} ${outerClass ?? \"\"}`}>\n <div\n className={`${styles.virtualListInner} ${innerClass ?? \"\"}`}\n style={{\n height: virtualizer.getTotalSize(),\n }}\n >\n <div\n className={`${styles.virtualListItems} ${flexClass ?? \"\"}`}\n style={{\n transform: `translateY(${items[0]?.start ?? 0}px)`,\n }}\n >\n {items.map((row) => {\n const isLoaderRow = row.index >= dataLength;\n const item = safeData[row.index];\n\n return (\n <div key={row.key} data-index={row.index} ref={virtualizer.measureElement}>\n {isLoaderRow ? (\n hasNextPage ? (\n renderLoadingIndicator()\n ) : (\n renderEndOfListIndicator()\n )\n ) : item == null ? (\n <div key={`missing-${row.index}`} />\n ) : (\n <div key={getItemKey(item, row.index)}>{renderItem(item, row.index)}</div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n );\n}\n\nconst VirtualWindowList = memo(VirtualWindowListComponent) as typeof VirtualWindowListComponent;\n\nexport default VirtualWindowList;\n"],"x_google_ignoreList":[24,25,26,27],"mappings":"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"}
|