nfx-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +235 -0
  2. package/dist/animations.cjs +3 -0
  3. package/dist/animations.d.ts +102 -0
  4. package/dist/animations.mjs +14 -0
  5. package/dist/apis.cjs +5 -0
  6. package/dist/apis.cjs.map +1 -0
  7. package/dist/apis.d.ts +7 -0
  8. package/dist/apis.mjs +18 -0
  9. package/dist/apis.mjs.map +1 -0
  10. package/dist/chunk-BounceLoading-B54QEw0n.mjs +244 -0
  11. package/dist/chunk-BounceLoading-B54QEw0n.mjs.map +1 -0
  12. package/dist/chunk-BounceLoading-C6n4BZVJ.cjs +11 -0
  13. package/dist/chunk-BounceLoading-C6n4BZVJ.cjs.map +1 -0
  14. package/dist/chunk-animations-Brp-bsaE.mjs +1243 -0
  15. package/dist/chunk-animations-Brp-bsaE.mjs.map +1 -0
  16. package/dist/chunk-animations-e2F3zuP9.cjs +190 -0
  17. package/dist/chunk-animations-e2F3zuP9.cjs.map +1 -0
  18. package/dist/chunk-chunk-BFrxaqQT.cjs +1 -0
  19. package/dist/chunk-i18n-Bp6pPM9n.mjs +207 -0
  20. package/dist/chunk-i18n-Bp6pPM9n.mjs.map +1 -0
  21. package/dist/chunk-i18n-_7W7guSV.cjs +3 -0
  22. package/dist/chunk-i18n-_7W7guSV.cjs.map +1 -0
  23. package/dist/chunk-lstorage-BVCD00Ow.mjs +27 -0
  24. package/dist/chunk-lstorage-BVCD00Ow.mjs.map +1 -0
  25. package/dist/chunk-lstorage-BnxLXHgH.cjs +3 -0
  26. package/dist/chunk-lstorage-BnxLXHgH.cjs.map +1 -0
  27. package/dist/chunk-lucide-BhgnmTNo.mjs +158 -0
  28. package/dist/chunk-lucide-BhgnmTNo.mjs.map +1 -0
  29. package/dist/chunk-lucide-CP2lvOPY.cjs +3 -0
  30. package/dist/chunk-lucide-CP2lvOPY.cjs.map +1 -0
  31. package/dist/chunk-preference-CYl68oeU.cjs +3 -0
  32. package/dist/chunk-preference-CYl68oeU.cjs.map +1 -0
  33. package/dist/chunk-preference-DImtu5jI.mjs +51 -0
  34. package/dist/chunk-preference-DImtu5jI.mjs.map +1 -0
  35. package/dist/chunk-types-BE3JCLff.cjs +3 -0
  36. package/dist/chunk-types-BE3JCLff.cjs.map +1 -0
  37. package/dist/chunk-types-BkFxelHl.mjs +20 -0
  38. package/dist/chunk-types-BkFxelHl.mjs.map +1 -0
  39. package/dist/chunk-types-C_opkZGr.cjs +3 -0
  40. package/dist/chunk-types-C_opkZGr.cjs.map +1 -0
  41. package/dist/chunk-types-CkbZrFqZ.cjs +3 -0
  42. package/dist/chunk-types-CkbZrFqZ.cjs.map +1 -0
  43. package/dist/chunk-types-DNPBKfmx.mjs +11 -0
  44. package/dist/chunk-types-DNPBKfmx.mjs.map +1 -0
  45. package/dist/chunk-types-SD4MzUGp.mjs +11 -0
  46. package/dist/chunk-types-SD4MzUGp.mjs.map +1 -0
  47. package/dist/chunk-useLayout-BAJHOIL3.cjs +3 -0
  48. package/dist/chunk-useLayout-BAJHOIL3.cjs.map +1 -0
  49. package/dist/chunk-useLayout-DPxlynT-.mjs +12 -0
  50. package/dist/chunk-useLayout-DPxlynT-.mjs.map +1 -0
  51. package/dist/chunk-useTheme-DgleVMMh.cjs +3 -0
  52. package/dist/chunk-useTheme-DgleVMMh.cjs.map +1 -0
  53. package/dist/chunk-useTheme-oHcq3d0o.mjs +13 -0
  54. package/dist/chunk-useTheme-oHcq3d0o.mjs.map +1 -0
  55. package/dist/components.cjs +8 -0
  56. package/dist/components.cjs.map +1 -0
  57. package/dist/components.d.ts +411 -0
  58. package/dist/components.mjs +1688 -0
  59. package/dist/components.mjs.map +1 -0
  60. package/dist/constants.cjs +5 -0
  61. package/dist/constants.cjs.map +1 -0
  62. package/dist/constants.d.ts +130 -0
  63. package/dist/constants.mjs +85 -0
  64. package/dist/constants.mjs.map +1 -0
  65. package/dist/events.cjs +5 -0
  66. package/dist/events.cjs.map +1 -0
  67. package/dist/events.d.ts +66 -0
  68. package/dist/events.mjs +31 -0
  69. package/dist/events.mjs.map +1 -0
  70. package/dist/hooks.cjs +5 -0
  71. package/dist/hooks.cjs.map +1 -0
  72. package/dist/hooks.d.ts +316 -0
  73. package/dist/hooks.mjs +107 -0
  74. package/dist/hooks.mjs.map +1 -0
  75. package/dist/icons.cjs +3 -0
  76. package/dist/icons.d.ts +218 -0
  77. package/dist/icons.mjs +76 -0
  78. package/dist/languages.cjs +5 -0
  79. package/dist/languages.cjs.map +1 -0
  80. package/dist/languages.d.ts +174 -0
  81. package/dist/languages.mjs +112 -0
  82. package/dist/languages.mjs.map +1 -0
  83. package/dist/layouts.cjs +5 -0
  84. package/dist/layouts.cjs.map +1 -0
  85. package/dist/layouts.d.ts +209 -0
  86. package/dist/layouts.mjs +460 -0
  87. package/dist/layouts.mjs.map +1 -0
  88. package/dist/navigations.cjs +5 -0
  89. package/dist/navigations.cjs.map +1 -0
  90. package/dist/navigations.d.ts +72 -0
  91. package/dist/navigations.mjs +30 -0
  92. package/dist/navigations.mjs.map +1 -0
  93. package/dist/preference.cjs +3 -0
  94. package/dist/preference.d.ts +94 -0
  95. package/dist/preference.mjs +14 -0
  96. package/dist/services.cjs +5 -0
  97. package/dist/services.cjs.map +1 -0
  98. package/dist/services.d.ts +8 -0
  99. package/dist/services.mjs +26 -0
  100. package/dist/services.mjs.map +1 -0
  101. package/dist/stores.cjs +5 -0
  102. package/dist/stores.cjs.map +1 -0
  103. package/dist/stores.d.ts +101 -0
  104. package/dist/stores.mjs +167 -0
  105. package/dist/stores.mjs.map +1 -0
  106. package/dist/themes.cjs +5 -0
  107. package/dist/themes.cjs.map +1 -0
  108. package/dist/themes.d.ts +229 -0
  109. package/dist/themes.mjs +894 -0
  110. package/dist/themes.mjs.map +1 -0
  111. package/dist/types.cjs +2 -0
  112. package/dist/types.d.ts +147 -0
  113. package/dist/types.mjs +2 -0
  114. package/dist/utils.cjs +5 -0
  115. package/dist/utils.cjs.map +1 -0
  116. package/dist/utils.d.ts +374 -0
  117. package/dist/utils.mjs +293 -0
  118. package/dist/utils.mjs.map +1 -0
  119. package/package.json +196 -0
@@ -0,0 +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: 0.5rem;\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, #ffffff);\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 color: #ffffff;\n}\n\n.button.danger:hover:not(:disabled) {\n background: var(--color-danger-light);\n border-color: var(--color-danger-light);\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: 8px;\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: #ef4444;\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: 8px;\r\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.175);\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: 0.5rem;\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, 102, 126, 234), 0.1);\n}\n\n.input::placeholder {\n color: var(--color-fg-muted, var(--color-fg-text));\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, var(--color-fg-text));\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, 244, 67, 54), 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?: string;\n /** 错误信息。Error message. */\n error?: string;\n /** 辅助说明。Helper text. */\n helperText?: string;\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: white;\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 { 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: string;\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?: string;\n /** 错误信息。Error message. */\n error?: string;\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.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: 0.5rem;\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}\n\nconst SearchInput = memo(({ value, onChange, placeholder, clearButtonAriaLabel = \"Clear search\" }: SearchInputProps) => {\n const handleClear = () => onChange(\"\");\n\n return (\n <div className={styles.searchContainer}>\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\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: 0.5rem;\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: white;\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}\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: 0.5rem;\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: 0.375rem;\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: white;\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}\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 { 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?: string;\n /** 筛选关闭时的按钮文案。Label when filter disabled. */\n filterDisabled?: string;\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?: string;\n /** 「显示」选项文案。Label for \"show\" option. */\n show?: string;\n /** 「隐藏」选项文案。Label for \"hide\" option. */\n hide?: string;\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: 0.25rem;\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(143, 155, 179, 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(143, 155, 179, 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: 0.25rem;\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\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 rgba(0, 0, 0, 0.3);\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: 9999px;\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: 9999px;\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 { 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?: string;\n /** 错误信息。Error message. */\n error?: string;\n /** 辅助说明。Helper text. */\n helperText?: string;\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, 239, 68, 68), 0.1), rgba(var(--color-error-rgb, 239, 68, 68), 0.05));\r\n border: 2px solid rgba(var(--color-error-rgb, 239, 68, 68), 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, #ef4444);\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, rgba(0, 0, 0, 0.1));\r\n border-radius: 0.75rem;\r\n background: var(--color-bg-2, rgba(0, 0, 0, 0.02));\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, rgba(0, 0, 0, 0.15));\r\n background: var(--color-bg-3, rgba(0, 0, 0, 0.03));\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, rgba(0, 0, 0, 0.03));\r\n border-top: 1px solid var(--color-border, rgba(0, 0, 0, 0.1));\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: 0.5rem;\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 rgba(0, 0, 0, 0.08);\r\n}\r\n\r\n.retryButton:hover {\r\n transform: translateY(-2px);\r\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\r\n background: var(--color-primary-hover, var(--color-primary));\r\n}\r\n\r\n.retryButton:active {\r\n transform: translateY(0);\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\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: 0.5rem;\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?: string;\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?: string;\n /** 错误描述。Error description. */\n errorDescription?: string;\n /** 重试按钮文案。Retry button text. */\n retryText?: string;\n /** 详情折叠文案。Error details summary text. */\n errorDetailsText?: string;\n /** 清除本地数据按钮文案。Clear local data button text. */\n clearLocalDataText?: string;\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?: string;\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?: string;\n /** 错误描述,由调用方传入。Error description; pass from caller. */\n errorDescription?: string;\n /** 重试按钮文案,由调用方传入。Retry text; pass from caller. */\n retryText?: string;\n /** 错误详情折叠文案。Error details text. */\n errorDetailsText?: string;\n /** 清除本地数据按钮文案。Clear local data text. */\n clearLocalDataText?: string;\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: 0.5rem;\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, 102, 126, 234), 0.1);\n}\n\n.textarea::placeholder {\n color: var(--color-fg-muted, var(--color-fg-text));\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, var(--color-fg-text));\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, var(--color-fg-text));\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, 244, 67, 54), 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?: string;\n /** 错误信息。Error message. */\n error?: string;\n /** 辅助说明。Helper text. */\n helperText?: string;\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.currentScrollToIndex = 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.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 this._measureElement(entry.target, entry);\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 ...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 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 this.maybeNotify();\n })\n );\n this._scrollToOffset(this.getScrollOffset(), {\n adjustments: void 0,\n behavior: void 0\n });\n }\n };\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 ],\n (count, paddingStart, scrollMargin, getItemKey, enabled, lanes) => {\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 };\n },\n {\n key: false\n }\n );\n this.getMeasurements = memo(\n () => [this.getMeasurementOptions(), this.itemSizeCache],\n ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes }, 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 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) {\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._measureElement = (node, entry) => {\n const index = this.indexFromElement(node);\n const item = this.measurementsCache[index];\n if (!item) {\n return;\n }\n const key = item.key;\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 (node.isConnected) {\n this.resizeItem(index, this.options.measureElement(node, entry, this));\n }\n };\n this.resizeItem = (index, size) => {\n const item = this.measurementsCache[index];\n if (!item) {\n return;\n }\n const itemSize = this.itemSizeCache.get(item.key) ?? item.size;\n const delta = size - itemSize;\n if (delta !== 0) {\n if (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.measureElement = (node) => {\n if (!node) {\n this.elementsCache.forEach((cached, key) => {\n if (!cached.isConnected) {\n this.observer.unobserve(cached);\n this.elementsCache.delete(key);\n }\n });\n return;\n }\n this._measureElement(node, void 0);\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 item = this.measurementsCache[index];\n if (!item) {\n return void 0;\n }\n const size = this.getSize();\n const scrollOffset = this.getScrollOffset();\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.isDynamicMode = () => this.elementsCache.size > 0;\n this.scrollToOffset = (toOffset, { align = \"start\", behavior } = {}) => {\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {\n adjustments: void 0,\n behavior\n });\n };\n this.scrollToIndex = (index, { align: initialAlign = \"auto\", behavior } = {}) => {\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n index = Math.max(0, Math.min(index, this.options.count - 1));\n this.currentScrollToIndex = index;\n let attempts = 0;\n const maxAttempts = 10;\n const tryScroll = (currentAlign) => {\n if (!this.targetWindow) return;\n const offsetInfo = this.getOffsetForIndex(index, currentAlign);\n if (!offsetInfo) {\n console.warn(\"Failed to get offset for index:\", index);\n return;\n }\n const [offset, align] = offsetInfo;\n this._scrollToOffset(offset, { adjustments: void 0, behavior });\n this.targetWindow.requestAnimationFrame(() => {\n if (!this.targetWindow) return;\n const verify = () => {\n if (this.currentScrollToIndex !== index) return;\n const currentOffset = this.getScrollOffset();\n const afterInfo = this.getOffsetForIndex(index, align);\n if (!afterInfo) {\n console.warn(\"Failed to get offset for index:\", index);\n return;\n }\n if (!approxEqual(afterInfo[0], currentOffset)) {\n scheduleRetry(align);\n }\n };\n if (this.isDynamicMode()) {\n this.targetWindow.requestAnimationFrame(verify);\n } else {\n verify();\n }\n });\n };\n const scheduleRetry = (align) => {\n if (!this.targetWindow) return;\n if (this.currentScrollToIndex !== index) return;\n attempts++;\n if (attempts < maxAttempts) {\n if (process.env.NODE_ENV !== \"production\" && this.options.debug) {\n console.info(\"Schedule retry\", attempts, maxAttempts);\n }\n this.targetWindow.requestAnimationFrame(() => tryScroll(align));\n } else {\n console.warn(\n `Failed to scroll to index ${index} after ${maxAttempts} attempts.`\n );\n }\n };\n tryScroll(initialAlign);\n };\n this.scrollBy = (delta, { behavior } = {}) => {\n if (behavior === \"smooth\" && this.isDynamicMode()) {\n console.warn(\n \"The `smooth` scroll behavior is not fully supported with dynamic size.\"\n );\n }\n this._scrollToOffset(this.getScrollOffset() + delta, {\n adjustments: void 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 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}\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: 0.25rem;\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?: string;\n /** 当未提供 loadingIndicator 时使用的文案。Text when loading more. */\n loadingMoreText?: string;\n /** 当未提供 endOfListIndicator 时使用的文案。Text at end of list. */\n endOfListText?: string;\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?: string;\n /** 加载更多文案。Loading more text. */\n loadingMoreText?: string;\n /** 列表底文案。End of list text. */\n endOfListText?: string;\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":"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"}
@@ -0,0 +1,5 @@
1
+ (function(){try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(`.styles-module__loading___bgEAk{justify-content:center;align-items:center;display:inline-flex}.styles-module__loading___bgEAk svg polyline{fill:none;stroke-width:3px;stroke-linecap:round;stroke-linejoin:round}.styles-module__loading___bgEAk svg polyline.styles-module__back___XLPvD{fill:none;stroke:var(--color-primary-alpha,#ff4d5033)}.styles-module__loading___bgEAk svg polyline.styles-module__front___hSxig{fill:none;stroke:var(--color-primary,#ff4d4f);stroke-dasharray:48 144;stroke-dashoffset:192px;animation:1.4s linear infinite styles-module__dash_682___AQzo6}@keyframes styles-module__dash_682___AQzo6{72.5%{opacity:0}to{stroke-dashoffset:0}}.styles-module__loader___E7OIM{justify-content:center;align-items:center;width:fit-content;height:fit-content;display:flex}.styles-module__truckWrapper___Sk4zX{flex-direction:column;justify-content:flex-end;align-items:center;width:100%;height:100%;display:flex;position:relative;overflow-x:hidden}.styles-module__truckBody___j7w2C{width:65%;height:fit-content;margin-bottom:6px;animation:1s linear infinite styles-module__motion___IiNlW}@keyframes styles-module__motion___IiNlW{0%{transform:translateY(0)}50%{transform:translateY(3px)}to{transform:translateY(0)}}.styles-module__truckTires___4ncTl{justify-content:space-between;align-items:center;width:65%;height:fit-content;padding:0 10px 0 15px;display:flex;position:absolute;bottom:0}.styles-module__tiresvg___IBQcN{width:24px}.styles-module__road___sxx-E{background-color:var(--color-fg-heading);border-radius:3px;align-self:flex-end;width:100%;height:1.5px;position:relative;bottom:0}.styles-module__road___sxx-E:before{content:"";background-color:var(--color-fg-heading);border-left:10px solid var(--color-bg);border-radius:3px;width:20px;height:100%;animation:1.4s linear infinite styles-module__roadAnimation___yvrHP;position:absolute;right:-50%}.styles-module__road___sxx-E:after{content:"";background-color:var(--color-fg-heading);border-left:4px solid var(--color-bg);border-radius:3px;width:10px;height:100%;animation:1.4s linear infinite styles-module__roadAnimation___yvrHP;position:absolute;right:-65%}.styles-module__lampPost___okcN5{height:45%;animation:1.4s linear infinite styles-module__roadAnimation___yvrHP;position:absolute;bottom:0;right:-90%}@keyframes styles-module__roadAnimation___yvrHP{0%{transform:translate(0)}to{transform:translate(-350px)}}.styles-module__loader___pFUzL{justify-content:center;align-items:center;display:inline-flex;position:relative}.styles-module__loader___pFUzL:before{content:"";background:var(--color-primary);opacity:.3;border-radius:50%;width:100%;height:5px;animation:.5s linear infinite styles-module__shadow324___sutUe;position:absolute;top:calc(100% + 12px);left:0}.styles-module__loader___pFUzL:after{content:"";background:var(--color-primary);width:100%;height:100%;position:absolute;top:0;left:0}.styles-module__square___GKjhm:after{border-radius:4px;animation:.5s linear infinite styles-module__jump7456Square___Z-D9b}.styles-module__circle___bUpSN:after{border-radius:50%;animation:.5s linear infinite styles-module__jump7456Circle___2AfF7}@keyframes styles-module__jump7456Square___Z-D9b{15%{border-bottom-right-radius:3px}25%{transform:translateY(9px)rotate(22.5deg)}50%{border-bottom-right-radius:40px;transform:translateY(18px)scaleY(.9)rotate(45deg)}75%{transform:translateY(9px)rotate(67.5deg)}to{transform:translateY(0)rotate(90deg)}}@keyframes styles-module__jump7456Circle___2AfF7{15%{border-bottom-right-radius:50%}25%{transform:translateY(9px)rotate(22.5deg)}50%{border-bottom-right-radius:40px;transform:translateY(18px)scaleY(.9)rotate(45deg)}75%{transform:translateY(9px)rotate(67.5deg)}to{transform:translateY(0)rotate(90deg)}}@keyframes styles-module__shadow324___sutUe{0%,to{transform:scale(1)}50%{transform:scaleX(1.2)}}.style-module__waves___oR3u7{width:100%;height:100%;margin:0;padding:0;position:absolute;top:0;left:0;overflow:hidden}.style-module__waves___oR3u7:before{content:"";width:.5rem;height:.5rem;transform:translate3d(calc(var(--x) - 50%), calc(var(--y) - 50%), 0);will-change:transform;background:#160000;border-radius:50%;position:absolute;top:0;left:0}.style-module__wavesCanvas___zkhTC{width:100%;height:100%;display:block}.style-module__squaresCanvas___22kMc{border:none;width:100%;height:100%;display:block}.style-module__container___HkxIe{background-color:#000;width:100%;height:100%;position:relative;overflow:hidden}.style-module__canvas___MR9JX{width:100%;height:100%;display:block}.style-module__outerVignette___i75nw{pointer-events:none;background:radial-gradient(circle,#0000 60%,#000 100%);width:100%;height:100%;position:absolute;top:0;left:0}.style-module__centerVignette___n9uVG{pointer-events:none;background:radial-gradient(circle,#000c 0%,#0000 60%);width:100%;height:100%;position:absolute;top:0;left:0}.style-module__container___Hh3-c{width:100%;height:100%;position:relative;overflow:hidden}.styles-module__button___RbliA{cursor:pointer;border:1px solid #0000;border-radius:.5rem;outline:none;justify-content:center;align-items:center;gap:.5rem;font-family:inherit;font-weight:500;transition:all .2s;display:inline-flex;position:relative}.styles-module__button___RbliA:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.styles-module__button___RbliA:disabled{cursor:not-allowed;opacity:.6}.styles-module__button___RbliA.styles-module__small___yK0Yp{min-height:2rem;padding:.5rem 1rem;font-size:.8125rem}.styles-module__button___RbliA.styles-module__medium___eBTch{min-height:2.5rem;padding:.75rem 1.5rem;font-size:.875rem}.styles-module__button___RbliA.styles-module__large___pIZkl{min-height:3rem;padding:1rem 2rem;font-size:1rem}.styles-module__button___RbliA.styles-module__primary___qsZpA{background:var(--color-primary);border-color:var(--color-primary);color:var(--color-primary-fg,#fff)}.styles-module__button___RbliA.styles-module__primary___qsZpA:hover:not(:disabled){background:var(--color-primary-light);border-color:var(--color-primary-light);transform:translateY(-1px)}.styles-module__button___RbliA.styles-module__primary___qsZpA:active:not(:disabled){transform:translateY(0)}.styles-module__button___RbliA.styles-module__secondary___SCpPv{background:var(--color-bg-2);border-color:var(--color-border-4);color:var(--color-fg-text)}.styles-module__button___RbliA.styles-module__secondary___SCpPv:hover:not(:disabled){background:var(--color-bg-3);border-color:var(--color-primary)}.styles-module__button___RbliA.styles-module__outline___rrlk9{border-color:var(--color-border-4);color:var(--color-fg-text);background:0 0}.styles-module__button___RbliA.styles-module__outline___rrlk9:hover:not(:disabled){background:var(--color-bg-2);border-color:var(--color-primary)}.styles-module__button___RbliA.styles-module__ghost___QMoiH{color:var(--color-fg-text);background:0 0;border-color:#0000}.styles-module__button___RbliA.styles-module__ghost___QMoiH:hover:not(:disabled){background:var(--color-bg-2)}.styles-module__button___RbliA.styles-module__danger___MW-pg{background:var(--color-danger);border-color:var(--color-danger);color:#fff}.styles-module__button___RbliA.styles-module__danger___MW-pg:hover:not(:disabled){background:var(--color-danger-light);border-color:var(--color-danger-light);transform:translateY(-1px)}.styles-module__button___RbliA.styles-module__danger___MW-pg:active:not(:disabled){transform:translateY(0)}.styles-module__button___RbliA.styles-module__fullWidth___-dXBR{width:100%}.styles-module__button___RbliA.styles-module__loading___UWw6V{pointer-events:none}.styles-module__spinner___KpJ-L{border:2px solid;border-top-color:#0000;border-radius:50%;flex-shrink:0;width:1rem;height:1rem;animation:.6s linear infinite styles-module__spin___ntZKM}@keyframes styles-module__spin___ntZKM{to{transform:rotate(360deg)}}.styles-module__button___RbliA.styles-module__small___yK0Yp .styles-module__spinner___KpJ-L{border-width:1.5px;width:.875rem;height:.875rem}.styles-module__button___RbliA.styles-module__large___pIZkl .styles-module__spinner___KpJ-L{border-width:2.5px;width:1.25rem;height:1.25rem}.styles-module__content___oyZRO{align-items:center;display:flex}.styles-module__leftIcon___cDktv,.styles-module__rightIcon___1mpk0{flex-shrink:0;align-items:center;display:flex}.styles-module__leftIcon___cDktv{margin-right:-.25rem}.styles-module__rightIcon___1mpk0{margin-left:-.25rem}.styles-module__button___RbliA.styles-module__iconOnly___iOv-U{aspect-ratio:1;min-width:2.5rem;min-height:2.5rem;padding:0}.styles-module__button___RbliA.styles-module__iconOnly___iOv-U.styles-module__small___yK0Yp{min-width:2rem;min-height:2rem}.styles-module__button___RbliA.styles-module__iconOnly___iOv-U.styles-module__large___pIZkl{min-width:3rem;min-height:3rem}.styles-module__iconContainer___bwvE3{justify-content:center;align-items:center;width:100%;height:100%;display:flex}.styles-module__layout___WaGy9{flex-direction:column;justify-content:center;align-items:center;gap:.25rem;width:100%;display:flex}.styles-module__horizontal___lKpGq{justify-content:center;align-items:center;gap:.5rem;width:100%;display:flex}.styles-module__topIcon___bzw6s,.styles-module__bottomIcon___suPfa{flex-shrink:0;justify-content:center;align-items:center;display:flex}.styles-module__iconOnly___iOv-U .styles-module__iconContainer___bwvE3 .styles-module__leftIcon___cDktv,.styles-module__iconOnly___iOv-U .styles-module__iconContainer___bwvE3 .styles-module__rightIcon___1mpk0{margin:0}.Dropdown-module__dropdown___c9wIp{width:100%;display:inline-block;position:relative}.Dropdown-module__dropdownButton___suNh-{border:1px solid var(--color-separator);cursor:pointer;text-align:left;background:var(--color-bg-2);width:100%;color:var(--color-fg-text);border-radius:8px;outline:none;justify-content:space-between;align-items:center;padding:.75rem 2.5rem .75rem 1rem;font-family:inherit;font-size:1rem;font-weight:400;line-height:1.5rem;transition:all .2s ease-in-out;display:flex;position:relative}.Dropdown-module__dropdownButton___suNh-:hover:not(:disabled){border-color:var(--color-primary);background:var(--color-bg-1)}.Dropdown-module__dropdownButton___suNh-:focus{border-color:var(--color-primary);background:var(--color-bg-1);box-shadow:0 0 0 2px var(--color-primary-transparent)}.Dropdown-module__dropdownButton___suNh-.Dropdown-module__disabled___Rz0pX{cursor:not-allowed;opacity:.6;background:var(--color-bg-3)}.Dropdown-module__dropdownButton___suNh-.Dropdown-module__error___F7dDu{border-color:#ef4444}.Dropdown-module__buttonText___D2zxn{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.Dropdown-module__chevronIcon___uyawp{color:var(--color-fg-highlight);flex-shrink:0;transition:transform .15s;position:absolute;right:1rem}.Dropdown-module__chevronIcon___uyawp.Dropdown-module__open___APoXd{transform:rotate(180deg)}.Dropdown-module__dropdownMenu___WJ-QO{background:var(--color-bg);border:1px solid var(--color-border-4);z-index:1000;border-radius:8px;min-width:100%;animation:.15s ease-out Dropdown-module__slideDown___sRCmO;position:absolute;top:calc(100% + .5rem);left:0;right:0;overflow:hidden;box-shadow:0 .5rem 1rem #0000002d}@keyframes Dropdown-module__slideDown___sRCmO{0%{opacity:0;transform:translateY(-.5rem)}to{opacity:1;transform:translateY(0)}}.Dropdown-module__optionsList___Be6RN{margin:0;padding:.5rem 0;list-style:none}.Dropdown-module__option___q-NgT{cursor:pointer;color:var(--color-fg-text);align-items:center;padding:.75rem 1rem;font-size:.875rem;transition:all .15s;display:flex}.Dropdown-module__option___q-NgT:hover{background-color:var(--color-bg-2)}.Dropdown-module__option___q-NgT.Dropdown-module__selected___-OTW-{background-color:var(--color-bg-3);color:var(--color-fg-highlight);font-weight:600}@media (width<=768px){.Dropdown-module__dropdownButton___suNh-{padding:.625rem 2.25rem .625rem .875rem;font-size:.875rem}.Dropdown-module__chevronIcon___uyawp{right:.875rem}.Dropdown-module__option___q-NgT{padding:.625rem .875rem;font-size:.8125rem}}.styles-module__wrapper___COeGm{flex-direction:column;gap:.5rem;display:flex}.styles-module__wrapper___COeGm.styles-module__fullWidth___lVU49{width:100%}.styles-module__label___gfOA7{color:var(--color-fg-heading);align-items:center;gap:.25rem;font-size:.875rem;font-weight:500;display:flex}.styles-module__required___-zOy5{color:var(--color-danger)}.styles-module__inputContainer___wXY53{align-items:center;width:100%;display:flex;position:relative}.styles-module__input___IZDc3{border:1px solid var(--color-border-4);background:var(--color-bg);width:100%;color:var(--color-fg-text);border-radius:.5rem;outline:none;font-family:inherit;font-size:.875rem;transition:all .2s}.styles-module__input___IZDc3[type=password]::-webkit-credentials-auto-fill-button{visibility:hidden!important;opacity:0!important;pointer-events:none!important;appearance:none!important;display:none!important;position:absolute!important;left:-9999px!important}.styles-module__input___IZDc3[type=password]::-webkit-strong-password-toggle-button{visibility:hidden!important;opacity:0!important;pointer-events:none!important;appearance:none!important;width:0!important;height:0!important;margin:0!important;padding:0!important;display:none!important;position:absolute!important;left:-9999px!important}.styles-module__input___IZDc3[type=password]::-ms-reveal{visibility:hidden!important;opacity:0!important;pointer-events:none!important;width:0!important;height:0!important;display:none!important;position:absolute!important;left:-9999px!important}.styles-module__input___IZDc3[type=password]::-ms-clear{visibility:hidden!important;opacity:0!important;pointer-events:none!important;width:0!important;height:0!important;display:none!important;position:absolute!important;left:-9999px!important}.styles-module__input___IZDc3:focus{border-color:var(--color-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb,102, 126, 234), .1)}.styles-module__input___IZDc3::placeholder{color:var(--color-fg-muted,var(--color-fg-text));opacity:.5}.styles-module__input___IZDc3.styles-module__small___cuGyE{padding:.5rem .75rem;font-size:.8125rem}.styles-module__input___IZDc3.styles-module__medium___JdDPu{padding:.75rem;font-size:.875rem}.styles-module__input___IZDc3.styles-module__large___fMmiG{padding:1rem;font-size:1rem}.styles-module__input___IZDc3.styles-module__default___-eZTG{background:var(--color-bg);border-color:var(--color-border-4)}.styles-module__input___IZDc3.styles-module__filled___EQ5PQ{background:var(--color-bg-2);border-color:var(--color-border-3)}.styles-module__inputContainer___wXY53.styles-module__withLeftIcon___NFn6- .styles-module__input___IZDc3{padding-left:2.5rem}.styles-module__inputContainer___wXY53.styles-module__withRightIcon___mz-hn .styles-module__input___IZDc3{padding-right:2.5rem}.styles-module__inputContainer___wXY53.styles-module__withLeftIcon___NFn6- .styles-module__input___IZDc3.styles-module__small___cuGyE{padding-left:2rem}.styles-module__inputContainer___wXY53.styles-module__withRightIcon___mz-hn .styles-module__input___IZDc3.styles-module__small___cuGyE{padding-right:2rem}.styles-module__inputContainer___wXY53.styles-module__withLeftIcon___NFn6- .styles-module__input___IZDc3.styles-module__large___fMmiG{padding-left:3rem}.styles-module__inputContainer___wXY53.styles-module__withRightIcon___mz-hn .styles-module__input___IZDc3.styles-module__large___fMmiG{padding-right:3rem}.styles-module__leftIcon___jEW5H,.styles-module__rightIcon___bA3Eo{color:var(--color-fg-muted,var(--color-fg-text));pointer-events:none;z-index:1;justify-content:center;align-items:center;display:flex;position:absolute}.styles-module__leftIcon___jEW5H{left:.75rem}.styles-module__rightIcon___bA3Eo{right:.75rem}.styles-module__rightIcon___bA3Eo.styles-module__rightIconInteractive___ccypw{pointer-events:auto}.styles-module__inputContainer___wXY53.styles-module__containerSmall___20ICq .styles-module__leftIcon___jEW5H{left:.5rem}.styles-module__inputContainer___wXY53.styles-module__containerSmall___20ICq .styles-module__rightIcon___bA3Eo{right:.5rem}.styles-module__inputContainer___wXY53.styles-module__containerLarge___IztuN .styles-module__leftIcon___jEW5H{left:1rem}.styles-module__inputContainer___wXY53.styles-module__containerLarge___IztuN .styles-module__rightIcon___bA3Eo{right:1rem}.styles-module__input___IZDc3.styles-module__error___946qV{border-color:var(--color-danger)}.styles-module__input___IZDc3.styles-module__error___946qV:focus{border-color:var(--color-danger);box-shadow:0 0 0 3px rgba(var(--color-danger-rgb,244, 67, 54), .1)}.styles-module__input___IZDc3.styles-module__disabled___sJvLd{background:var(--color-bg-3);border-color:var(--color-border-5);color:var(--color-fg-muted);cursor:not-allowed;opacity:.6}.styles-module__errorMessage___5Mn22{color:var(--color-danger);margin:0;font-size:.75rem}.styles-module__helperText___T2eui{color:var(--color-fg-muted);margin:0;font-size:.75rem}.styles-module__container___xeg8O{flex-direction:column;gap:1rem;display:flex}.styles-module__label___qhbKe{color:var(--color-fg-text);font-size:.875rem;font-weight:500}.styles-module__error___O-7AY{color:var(--color-error);font-size:.875rem}.styles-module__pairs___owGV3{flex-direction:column;gap:.75rem;display:flex}.styles-module__pair___G4WFY{grid-template-columns:1fr 2fr auto;align-items:start;gap:.75rem;display:grid}.styles-module__keyInput___wl1M1,.styles-module__valueInput___HiwJ5{flex:1}.styles-module__removeButton___4-X0b{min-width:auto;color:var(--color-error);padding:.5rem}.styles-module__removeButton___4-X0b:hover{background-color:var(--color-error);color:#fff}.styles-module__addButton___QFljt{align-self:flex-start}@media (width<=768px){.styles-module__pair___G4WFY{grid-template-columns:1fr}.styles-module__removeButton___4-X0b{align-self:flex-end}}.styles-module__searchContainer___86TGN{width:100%;max-width:400px;position:relative}.styles-module__searchIcon___ZInry{color:var(--color-fg-muted);pointer-events:none;position:absolute;top:50%;left:1rem;transform:translateY(-50%)}.styles-module__searchInput___SqZXQ{border:1px solid var(--color-border);width:100%;color:var(--color-fg-text);background:var(--color-bg-2);border-radius:.5rem;padding:.75rem 3rem;font-size:1rem;transition:all .2s}.styles-module__searchInput___SqZXQ:focus{border-color:var(--color-primary);box-shadow:0 0 0 3px var(--color-primary-bg);outline:none}.styles-module__searchInput___SqZXQ::placeholder{color:var(--color-fg-muted)}.styles-module__clearBtn___7jExr{width:1.5rem;height:1.5rem;color:var(--color-fg-muted);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;transition:all .2s;display:flex;position:absolute;top:50%;right:.75rem;transform:translateY(-50%)}.styles-module__clearBtn___7jExr:hover{color:var(--color-fg-text)}@media (width<=768px){.styles-module__searchContainer___86TGN{max-width:100%}}.styles-module__container___nGxdM{flex-direction:column;gap:.75rem;display:flex}.styles-module__toggleContainer___VrsKI{align-items:center;display:flex}.styles-module__toggleButton___IzD6Z{border:1px solid var(--color-border-4);background:var(--color-bg);color:var(--color-fg-muted);cursor:pointer;border-radius:.5rem;align-items:center;gap:.5rem;padding:.5rem 1rem;font-size:.875rem;transition:all .2s;display:flex}.styles-module__toggleButton___IzD6Z:hover{background:var(--color-bg-2);border-color:var(--color-border-3)}.styles-module__toggleButton___IzD6Z.styles-module__enabled___cao0G{background:var(--color-primary);color:#fff;border-color:var(--color-primary)}.styles-module__toggleButton___IzD6Z.styles-module__enabled___cao0G:hover{background:var(--color-primary-hover);border-color:var(--color-primary-hover)}.styles-module__optionsContainer___LOzlO{background:var(--color-bg-2);border:1px solid var(--color-border-4);border-radius:.5rem;gap:.5rem;padding:.5rem;display:flex}.styles-module__option___abhnC{border:1px solid var(--color-border-4);background:var(--color-bg);color:var(--color-fg);cursor:pointer;border-radius:.375rem;flex:1;justify-content:center;align-items:center;gap:.375rem;padding:.5rem .875rem;font-size:.875rem;font-weight:500;transition:all .2s;display:flex}.styles-module__option___abhnC:hover{background:var(--color-bg-3);border-color:var(--color-border-3)}.styles-module__option___abhnC.styles-module__active___pqmSi{background:var(--color-primary);color:#fff;border-color:var(--color-primary)}.styles-module__option___abhnC.styles-module__active___pqmSi:hover{background:var(--color-primary-hover);border-color:var(--color-primary-hover)}.styles-module__nbSelect___KjxSc{font-family:inherit;font-size:.9375rem;font-weight:600;line-height:1.5rem;display:inline-block;position:relative}.styles-module__selectButton___AKZe4{cursor:pointer;text-align:left;width:100%;min-width:8rem;font-family:inherit;font-size:inherit;font-weight:inherit;line-height:inherit;appearance:none;border:1px solid;border-radius:.25rem;outline:none;justify-content:space-between;align-items:center;padding:.4375rem 2.2rem .4375rem 1.125rem;transition:all .15s ease-in-out;display:flex;position:relative}.styles-module__selectButton___AKZe4.styles-module__primary___HU36a{background-color:var(--color-primary);border-color:var(--color-primary);color:var(--color-primary-fg)}.styles-module__selectButton___AKZe4.styles-module__primary___HU36a:hover:not(:disabled){background-color:var(--color-primary-light);border-color:var(--color-primary-light)}.styles-module__selectButton___AKZe4.styles-module__primary___HU36a:focus,.styles-module__selectButton___AKZe4.styles-module__primary___HU36a.styles-module__open___9AKMb{background-color:var(--color-primary-light);border-color:var(--color-primary-light);box-shadow:0 0 0 .125rem #8f9bb340}.styles-module__selectButton___AKZe4.styles-module__default___LedYP{background-color:var(--color-bg);border-color:var(--color-border-4);color:var(--color-fg-text)}.styles-module__selectButton___AKZe4.styles-module__default___LedYP:hover:not(:disabled){background-color:var(--color-bg-2);border-color:var(--color-primary)}.styles-module__selectButton___AKZe4.styles-module__default___LedYP:focus,.styles-module__selectButton___AKZe4.styles-module__default___LedYP.styles-module__open___9AKMb{background-color:var(--color-bg-2);border-color:var(--color-primary);box-shadow:0 0 0 .125rem #8f9bb340}.styles-module__selectButton___AKZe4:disabled{cursor:not-allowed;opacity:.6}.styles-module__buttonText___QSLO1{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.styles-module__chevronIcon___qAHaD{flex-shrink:0;width:1.5rem;height:1.5rem;transition:transform .15s;position:absolute;right:.41rem}.styles-module__selectButton___AKZe4.styles-module__primary___HU36a .styles-module__chevronIcon___qAHaD{color:var(--color-primary-fg)}.styles-module__selectButton___AKZe4.styles-module__default___LedYP .styles-module__chevronIcon___qAHaD{color:var(--color-fg)}.styles-module__chevronIcon___qAHaD.styles-module__open___9AKMb{transform:rotate(180deg)}.styles-module__optionsPanel___NWAp3{background-color:var(--color-bg);border:1px solid var(--color-border-4);z-index:1000;transform-origin:top;visibility:hidden;pointer-events:none;border-radius:.25rem;min-width:100%;position:absolute;top:calc(100% + .5rem);left:0;right:0;overflow:hidden;box-shadow:0 .5rem 1rem #00000026}.styles-module__optionsPanel___NWAp3.styles-module__open___9AKMb{visibility:visible;pointer-events:auto;animation:.25s ease-out styles-module__expandDown___eD4lh}.styles-module__optionsPanel___NWAp3.styles-module__closed___bez-q{visibility:hidden;pointer-events:none;animation:.25s ease-out styles-module__collapseUp___dt1E7}@keyframes styles-module__expandDown___eD4lh{0%{opacity:0;transform:scaleY(0)}to{opacity:1;transform:scaleY(1)}}@keyframes styles-module__collapseUp___dt1E7{0%{opacity:1;transform:scaleY(1)}to{opacity:0;transform:scaleY(0)}}.styles-module__optionsPanel___NWAp3.styles-module__primary___HU36a{border-color:var(--color-primary)}.styles-module__optionsPanel___NWAp3.styles-module__default___LedYP{border-color:var(--color-border-4)}.styles-module__optionsList___AxhVp{margin:0;padding:.5rem 0;list-style:none}.styles-module__option___t1SSw{cursor:pointer;color:var(--color-fg-text);justify-content:space-between;align-items:center;padding:.75rem 1.125rem;transition:all .15s;display:flex}.styles-module__option___t1SSw:hover{background-color:var(--color-bg-2)}.styles-module__option___t1SSw.styles-module__selected___azD4A{background-color:var(--color-primary);color:var(--color-primary-fg);font-weight:700}@media (prefers-color-scheme:dark){.styles-module__optionsPanel___NWAp3{box-shadow:0 .5rem 1rem #0000004d}}.styles-module__sliderContainer___lgpaD{flex-direction:column;gap:.5rem;display:flex}.styles-module__sliderContainer___lgpaD.styles-module__fullWidth___ZS8W5{width:100%}.styles-module__labelRow___dkVVM{justify-content:space-between;align-items:center;min-height:1.5rem;margin-bottom:.5rem;display:flex}.styles-module__label___bXGZs{color:var(--color-fg-text);font-size:.875rem;font-weight:500}.styles-module__required___FuyfE{color:var(--color-danger);margin-left:.25rem}.styles-module__sliderWrapper___1Wdti{touch-action:none;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;gap:.75rem;width:100%;display:flex}.styles-module__sliderRoot___yzOjR{cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;flex-grow:1;align-items:center;width:100%;padding:.75rem 0;display:flex;position:relative}.styles-module__sliderRoot___yzOjR:active{cursor:grabbing}.styles-module__sliderTrackWrapper___N72WQ{flex-grow:1;display:flex;position:relative}.styles-module__sliderTrack___AltcD{background-color:var(--color-bg-3);border-radius:9999px;width:100%;height:.375rem;position:relative;overflow:hidden}.styles-module__sliderRange___U3g0-{background-color:var(--color-primary);border-radius:9999px;height:100%;position:absolute}.styles-module__valueIndicator___aLf0I{color:var(--color-primary);text-align:center;flex-shrink:0;min-width:2rem;font-size:.875rem;font-weight:600;line-height:1}.styles-module__iconWrapper___wL-b8{flex-shrink:0;justify-content:center;align-items:center;display:flex}.styles-module__icon___vHsID{width:20px;height:20px;color:var(--color-fg-muted)}.styles-module__errorMessage___qFgGe{color:var(--color-danger);margin:0;font-size:.75rem}.styles-module__helperText___tgBGl{color:var(--color-fg-muted);margin:0;font-size:.75rem}.styles-module__loadingContainer___OMgwS{flex-direction:column;justify-content:center;align-items:center;gap:1.5rem;min-height:60vh;display:flex}.styles-module__loadingText___KRZqR{color:var(--color-fg-muted);font-size:1rem}.styles-module__errorContainer___qhAg2{text-align:center;min-height:60vh;color:var(--color-fg-text);flex-direction:column;justify-content:center;align-items:center;gap:2rem;padding:3rem 2rem;display:flex}.styles-module__errorIconWrapper___IHZrN{background:linear-gradient(135deg, rgba(var(--color-error-rgb,239, 68, 68), .1), rgba(var(--color-error-rgb,239, 68, 68), .05));border:2px solid rgba(var(--color-error-rgb,239, 68, 68), .2);border-radius:50%;justify-content:center;align-items:center;width:120px;height:120px;animation:2s ease-in-out infinite styles-module__pulse___Lju-z;display:flex}@keyframes styles-module__pulse___Lju-z{0%,to{opacity:1;transform:scale(1)}50%{opacity:.9;transform:scale(1.05)}}.styles-module__errorIcon___oGDIP{color:var(--color-error,#ef4444);stroke-width:1.5px}.styles-module__errorContent___F55rQ{flex-direction:column;align-items:center;gap:1rem;width:100%;max-width:600px;display:flex}.styles-module__errorTitle___hC8D-{color:var(--color-fg-heading);letter-spacing:-.02em;margin:0;font-size:1.75rem;font-weight:700;line-height:1.2}.styles-module__errorDescription___hZtuP{color:var(--color-fg-muted);max-width:480px;margin:0;font-size:1rem;line-height:1.6}.styles-module__errorDetailsWrapper___-sp8b{width:100%;max-width:600px;margin-top:.5rem}.styles-module__errorDetailsContainer___eywMo{text-align:left;border:1px solid var(--color-border,#0000001a);background:var(--color-bg-2,#00000005);border-radius:.75rem;width:100%;transition:all .2s;overflow:hidden}.styles-module__errorDetailsContainer___eywMo:hover{border-color:var(--color-border-hover,#00000026);background:var(--color-bg-3,#00000008)}.styles-module__errorDetailsSummary___hGEoD{cursor:pointer;color:var(--color-fg-muted);-webkit-user-select:none;user-select:none;padding:.875rem 1.25rem;font-size:.875rem;font-weight:500;list-style:none;transition:color .2s}.styles-module__errorDetailsSummary___hGEoD:hover{color:var(--color-fg-text)}.styles-module__errorDetailsSummary___hGEoD::-webkit-details-marker{display:none}.styles-module__errorDetailsSummary___hGEoD:before{content:"▶";margin-right:.5rem;font-size:.75rem;transition:transform .2s;display:inline-block}.styles-module__errorDetailsContainer___eywMo[open] .styles-module__errorDetailsSummary___hGEoD:before{transform:rotate(90deg)}.styles-module__errorDetails___tzCT-{background:var(--color-bg-3,#00000008);border-top:1px solid var(--color-border,#0000001a);max-width:100%;color:var(--color-fg-muted);white-space:pre-wrap;word-break:break-word;margin:0;padding:1rem 1.25rem;font-family:Monaco,Menlo,Ubuntu Mono,Consolas,source-code-pro,monospace;font-size:.8125rem;line-height:1.6;overflow-x:auto}.styles-module__errorActions___gtqYw{flex-wrap:wrap;justify-content:center;align-items:center;gap:.75rem;margin-top:1rem;display:flex}.styles-module__retryButton___TA4jm{background:var(--color-primary);color:var(--color-primary-fg);cursor:pointer;border:none;border-radius:.5rem;justify-content:center;align-items:center;gap:.5rem;padding:.75rem 2rem;font-size:.9375rem;font-weight:500;transition:all .2s;display:inline-flex;box-shadow:0 2px 8px #00000014}.styles-module__retryButton___TA4jm:hover{background:var(--color-primary-hover,var(--color-primary));transform:translateY(-2px);box-shadow:0 4px 16px #0000001f}.styles-module__retryButton___TA4jm:active{transform:translateY(0);box-shadow:0 2px 8px #00000014}.styles-module__retryButtonIcon___vzfp-{font-size:1.125rem;line-height:1;transition:transform .3s;display:inline-block}.styles-module__retryButton___TA4jm:hover .styles-module__retryButtonIcon___vzfp-{transform:rotate(180deg)}.styles-module__clearLocalDataButton___T3B-K{color:var(--color-fg-muted);border:1px solid var(--color-border-4);cursor:pointer;background:0 0;border-radius:.5rem;justify-content:center;align-items:center;padding:.75rem 1.5rem;font-size:.9375rem;font-weight:500;transition:all .2s;display:inline-flex}.styles-module__clearLocalDataButton___T3B-K:hover{color:var(--color-fg-text);border-color:var(--color-border-3);background:var(--color-bg-secondary)}.styles-module__wrapper___jXPV3{flex-direction:column;gap:.5rem;display:flex}.styles-module__wrapper___jXPV3.styles-module__fullWidth___eKyGB{width:100%}.styles-module__label___MyTeo{color:var(--color-fg-heading);align-items:center;gap:.25rem;font-size:.875rem;font-weight:500;display:flex}.styles-module__required___TV-m8{color:var(--color-danger)}.styles-module__inputContainer___VvGBl{align-items:flex-start;width:100%;display:flex;position:relative}.styles-module__textarea___AjX9N{border:1px solid var(--color-border-4);background:var(--color-bg);width:100%;color:var(--color-fg-text);resize:vertical;border-radius:.5rem;outline:none;min-height:4rem;font-family:inherit;font-size:.875rem;transition:all .2s}.styles-module__textarea___AjX9N:focus{border-color:var(--color-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb,102, 126, 234), .1)}.styles-module__textarea___AjX9N::placeholder{color:var(--color-fg-muted,var(--color-fg-text));opacity:.5}.styles-module__textarea___AjX9N.styles-module__small___zMx0G{min-height:3rem;padding:.5rem .75rem;font-size:.8125rem}.styles-module__textarea___AjX9N.styles-module__medium___tO2Lb{min-height:4rem;padding:.75rem;font-size:.875rem}.styles-module__textarea___AjX9N.styles-module__large___3eU2g{min-height:5rem;padding:1rem;font-size:1rem}.styles-module__textarea___AjX9N.styles-module__default___vsSxX{background:var(--color-bg);border-color:var(--color-border-4)}.styles-module__textarea___AjX9N.styles-module__filled___TPQgI{background:var(--color-bg-2);border-color:var(--color-border-3)}.styles-module__inputContainer___VvGBl .styles-module__leftIcon___FHp2R{color:var(--color-fg-muted,var(--color-fg-text));pointer-events:none;z-index:1;justify-content:center;align-items:center;display:flex;position:absolute;top:.75rem;left:.75rem}.styles-module__inputContainer___VvGBl .styles-module__rightIcon___dkyvP{color:var(--color-fg-muted,var(--color-fg-text));pointer-events:none;z-index:1;justify-content:center;align-items:center;display:flex;position:absolute;top:.75rem;right:.75rem}.styles-module__inputContainer___VvGBl .styles-module__textarea___AjX9N.styles-module__small___zMx0G+.styles-module__leftIcon___FHp2R,.styles-module__inputContainer___VvGBl .styles-module__textarea___AjX9N.styles-module__small___zMx0G+.styles-module__rightIcon___dkyvP{top:.5rem}.styles-module__inputContainer___VvGBl .styles-module__textarea___AjX9N.styles-module__large___3eU2g+.styles-module__leftIcon___FHp2R,.styles-module__inputContainer___VvGBl .styles-module__textarea___AjX9N.styles-module__large___3eU2g+.styles-module__rightIcon___dkyvP{top:1rem}.styles-module__textarea___AjX9N.styles-module__error___d8gLK{border-color:var(--color-danger)}.styles-module__textarea___AjX9N.styles-module__error___d8gLK:focus{border-color:var(--color-danger);box-shadow:0 0 0 3px rgba(var(--color-danger-rgb,244, 67, 54), .1)}.styles-module__textarea___AjX9N.styles-module__disabled___IzbfE{background:var(--color-bg-3);border-color:var(--color-border-5);color:var(--color-fg-muted);cursor:not-allowed;opacity:.6}.styles-module__errorText___Nom7x{color:var(--color-danger);margin:0;font-size:.75rem}.styles-module__helperText___97Def{color:var(--color-fg-muted);margin:0;font-size:.75rem}.styles-module__virtualList___pM6rN{contain:strict;width:100%;padding-bottom:300px;position:relative;overflow:auto}.styles-module__emptyContainer___rm938{height:100%;color:var(--color-fg-muted);justify-content:center;align-items:center;display:flex}.styles-module__virtualListInner___HxRzc{width:100%;position:relative}.styles-module__virtualListItems___p19-a{width:100%;position:absolute;top:0;left:0}.styles-module__loadingMore___zAdLM{color:var(--color-fg-muted);justify-content:center;align-items:center;gap:.75rem;padding:2rem 0;font-size:.875rem;display:flex}.styles-module__endOfList___5cYFh{color:var(--color-fg-muted);border-top:1px solid var(--color-border-3);justify-content:center;margin-top:1rem;padding:2rem 0;font-size:.875rem;display:flex}.styles-module__endOfList___5cYFh span{background-color:var(--color-bg-2);border-radius:.25rem;padding:.5rem 1rem}.styles-module__virtualList___xmj2v{width:100%;padding-bottom:300px;position:relative;overflow:visible}.styles-module__virtualListInner___quD74{width:100%;position:relative}.styles-module__virtualListItems___-Muml{width:100%;position:absolute;top:0;left:0}.styles-module__virtualListRow___h3pzX{width:100%}.styles-module__emptyContainer___LIy8r{color:var(--color-fg-muted);justify-content:center;align-items:center;padding:2rem 0;display:flex}.styles-module__loadingMore___Mzf-p{color:var(--color-fg-muted);justify-content:center;align-items:center;padding:1.5rem 0;display:flex}.styles-module__endOfList___g5G--{color:var(--color-fg-muted);border-top:1px solid var(--color-border-3);justify-content:center;padding:1.5rem 0;display:flex}.styles-module__sidebar___BMt0j{flex-direction:column;height:100%;min-height:0;display:flex;overflow:hidden}.styles-module__sidebarContent___iAwiw{flex-direction:column;height:100%;min-height:0;padding-top:1rem;display:flex;overflow:hidden}.styles-module__menuWrapper___DKuEv{flex:1;min-height:0;overflow:hidden auto}.styles-module__sidebarContent___iAwiw::-webkit-scrollbar{width:0}.styles-module__sidebarContent___iAwiw::-webkit-scrollbar-track{background:0 0}.styles-module__sidebarContent___iAwiw::-webkit-scrollbar-thumb{background:0 0}.styles-module__sidebarContent___iAwiw::-webkit-scrollbar-thumb:hover{background:0 0}.styles-module__sidebar___BMt0j a{margin-left:0}.styles-module__sidebar___BMt0j .ps-sidebar-root{background-color:var(--color-bg-2)!important;border-right:1px solid var(--color-separator)!important;flex-direction:column!important;height:100%!important;min-height:0!important;display:flex!important;overflow:hidden!important}.styles-module__sidebar___BMt0j .ps-sidebar-container{background-color:var(--color-bg-2)!important;height:100%!important;min-height:0!important;color:var(--color-fg-text)!important;flex-direction:column!important;flex:1!important;display:flex!important;overflow:hidden!important}.styles-module__sidebar___BMt0j .ps-menu-button{color:var(--color-fg-text)!important;border-radius:.375rem!important;margin:.125rem .5rem!important;padding:.5rem .75rem!important;font-size:.875rem!important;transition:all .2s!important}.styles-module__sidebar___BMt0j .ps-menu-button:hover{background-color:var(--color-bg-3)!important;color:var(--color-fg-text)!important}.styles-module__sidebar___BMt0j .ps-menu-button.ps-active{background-color:var(--color-primary)!important;color:#fff!important}.styles-module__sidebar___BMt0j .ps-menu-button.ps-active *,.styles-module__sidebar___BMt0j .ps-menu-button.ps-active .ps-menu-icon,.styles-module__sidebar___BMt0j .ps-menu-button.ps-active .ps-menu-label{color:#fff!important}.styles-module__sidebar___BMt0j .ps-menu-icon{width:1.25rem!important;height:1.25rem!important;color:var(--color-fg-text)!important;margin-right:.5rem!important}.styles-module__sidebar___BMt0j .ps-submenu-content{background-color:var(--color-bg-3)!important;padding-left:.5rem!important;overflow:hidden!important}.styles-module__sidebar___BMt0j .ps-submenu-content .ps-menu-button{margin:.125rem .25rem!important;padding:.375rem .5rem!important;font-size:.8125rem!important;transition:all .2s!important}.styles-module__sidebar___BMt0j .ps-menu-label{color:var(--color-fg-text)!important;font-weight:500!important}.styles-module__sidebar___BMt0j .ps-menu-button.ps-active,.styles-module__sidebar___BMt0j .ps-menu-button.ps-active span,.styles-module__sidebar___BMt0j .ps-menu-button.ps-active div,.styles-module__sidebar___BMt0j .ps-menu-button.ps-active .ps-menu-icon,.styles-module__sidebar___BMt0j .ps-menu-button.ps-active .ps-menu-label{color:#fff!important}.styles-module__logoutContainer___7NwBL{border-top:1px solid var(--color-separator);writing-mode:horizontal-tb;text-orientation:mixed;flex-shrink:0;margin-top:auto;padding:.5rem}.styles-module__logoutButton___rfD6u{width:100%;color:var(--color-fg-text);cursor:pointer;white-space:nowrap;writing-mode:horizontal-tb;text-orientation:mixed;direction:ltr;background:0 0;border:none;border-radius:.375rem;justify-content:flex-start;align-items:center;gap:.5rem;padding:.5rem .75rem;font-size:.875rem;transition:background-color .2s,color .2s;display:flex;overflow:hidden}.styles-module__logoutButton___rfD6u span{opacity:1;max-width:200px;transition:opacity .3s,max-width .3s;display:inline-block;writing-mode:horizontal-tb!important;text-orientation:mixed!important;direction:ltr!important;transform:none!important}.styles-module__logoutButton___rfD6u .styles-module__hiddenText___z183T{opacity:0;width:0;max-width:0;overflow:hidden}.styles-module__logoutButton___rfD6u .styles-module__visibleText___lfsv-{opacity:1;width:auto;max-width:200px}.styles-module__logoutButton___rfD6u:hover{background-color:var(--color-bg-3)}.styles-module__logoutButton___rfD6u:active{transform:scale(.98)}.styles-module__logoutButton___rfD6u svg{color:inherit;flex-shrink:0}.styles-module__footer___g-hY7{background:var(--color-bg-2);width:100%;padding:0 2rem}.styles-module__footerContent___Oen5n{justify-content:space-between;align-items:center;max-width:100%;margin:0 auto;display:flex}.styles-module__copyright___1R2o3{color:var(--color-fg-text);font-size:.875rem}.styles-module__links___dQyvB{gap:1.5rem;display:flex}.styles-module__link___UWfyK{color:var(--color-fg-text);font-size:.875rem;text-decoration:none;transition:color .3s}.styles-module__link___UWfyK:hover{color:var(--color-primary)}@media (width<=768px){.styles-module__footerContent___Oen5n{flex-direction:column;gap:1rem}.styles-module__links___dQyvB{gap:1rem}}.styles-module__header___4Uc8h{width:100%;padding:.5rem 2rem;display:flex}.styles-module__header___4Uc8h>:first-child{flex:1;justify-content:flex-start;align-items:center;display:flex}.styles-module__header___4Uc8h>:last-child{flex:1;justify-content:flex-end;align-items:center;display:flex}.styles-module__layout___ZQKU7{background:var(--color-bg);flex-direction:column;width:100%;height:100vh;display:flex;position:relative}.styles-module__header___XIaFb{z-index:100;background:var(--color-bg);width:100%;position:fixed;top:0;box-shadow:0 .125rem .25rem #2c33491a}.styles-module__footer___r8ASO{z-index:100;width:100%;position:fixed;bottom:0}.styles-module__mainWrapper___i4tEI{flex:1;display:flex;position:relative}.styles-module__sidebar___ij-8-{position:fixed;top:0}.styles-module__content___mTgUr{background:var(--color-bg);flex:1;min-height:calc(100vh - 10rem);margin:0;padding-top:0;padding-bottom:0;overflow:hidden auto}@media (width<=768px){.styles-module__content___mTgUr{width:100%}.styles-module__sidebar___ij-8-{z-index:999;height:100vh;position:fixed;top:0;left:0}}.styles-module__mainWrapper___AiTAw{flex-direction:row;flex:1;display:flex;position:relative}.styles-module__sidebarContainer___X4yj8{z-index:99;flex-direction:column;display:flex;position:fixed;left:0;overflow:hidden}.styles-module__sidebar___VQTlH{flex-shrink:0;top:0;left:0}.styles-module__content___htJlH{background:var(--color-bg);flex:1;margin:0;padding-top:0;padding-bottom:0;overflow:hidden auto}@media (width<=1024px){.styles-module__content___htJlH{padding:1.5rem}}@media (width<=768px){.styles-module__content___htJlH{width:100%}.styles-module__sidebar___VQTlH{z-index:999;height:100vh;position:fixed;top:0;left:0}}.styles-module__wavesWrapper___TK7DI{pointer-events:none;z-index:0;width:100vw;height:100vh;position:fixed;inset:0;overflow:hidden}.styles-module__wavesWrapper___TK7DI>*{pointer-events:auto}.styles-module__squaresWrapper___P25uF{pointer-events:none;z-index:0;width:100vw;height:100vh;position:fixed;inset:0;overflow:hidden}.styles-module__squaresWrapper___P25uF>*{pointer-events:auto}.styles-module__letterGlitchWrapper___KWtWU{pointer-events:none;z-index:0;width:100vw;height:100vh;position:fixed;inset:0;overflow:hidden}.styles-module__letterGlitchWrapper___KWtWU>*{pointer-events:auto}.styles-module__pixelBlastWrapper___YptHh{pointer-events:none;z-index:0;width:100vw;height:100vh;position:fixed;inset:0;overflow:hidden}.styles-module__pixelBlastWrapper___YptHh>*{pointer-events:auto}
2
+ /*$vite$:1*/`)),document.head.appendChild(e)}}catch(o){console.error("vite-plugin-css-injected-by-js",o)}})();
3
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var i="list",f="item";function P(e){const t=Object.keys(e);function r(u){return Object.fromEntries(Object.entries(e).map(([c,C])=>[c,C[u]]))}function n(u){return e[u]}return{Values:t,pickMap:r,get:n}}function b(e,t){return e.pickMap(t)}function y(e,t,r){const n=[...e,t,f,r];return Object.assign((...c)=>[...n,...c],{withPrefix(...c){return y([...c,...e],t,r)},get getPrefix(){return[...n]}})}function a(e,t){return y([],e,t)}function s(e,t,r){const n=[...e,t,i,r];return Object.assign([...n],{withPrefix(...u){return s([...u,...e],t,r)},get getPrefix(){return[...n]}})}function o(e,t){return s([],e,t)}function K(e,t){return{list:e,item:t,withPrefix(...r){return K(e.withPrefix(...r),t.withPrefix(...r))}}}function g(...e){return e}function l(e,t){return K(o(e,t),a(e,t))}exports.CACHE_ITEM=f;exports.CACHE_LIST=i;exports.createItemKey=a;exports.createKey=g;exports.createListKey=o;exports.createQueryKeys=l;exports.defineEnum=P;exports.enumPickMap=b;
4
+
5
+ //# sourceMappingURL=constants.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs","names":[],"sources":["../src/constants/caches.ts","../src/constants/enums.ts","../src/constants/query.itemkeys.ts","../src/constants/query.listkeys.ts","../src/constants/querykeys.ts"],"sourcesContent":["/** 列表 key 片段。List key segment. */\nconst CACHE_LIST = \"list\";\n\n/** 单条 key 片段。Item key segment. */\nconst CACHE_ITEM = \"item\";\n\nexport { CACHE_LIST, CACHE_ITEM };\n","type EnumMetaMap = Record<string, Record<PropertyKey, unknown>>;\n\ntype DefinedEnum<M extends EnumMetaMap> = {\n Values: readonly (keyof M)[];\n pickMap<P extends keyof M[keyof M]>(prop: P): { [K in keyof M]: M[K][P] };\n get<K extends keyof M>(key: K): M[K];\n};\n\ntype EnumInferMeta<E> = E extends DefinedEnum<infer M> ? M : never;\n\ntype EnumValue<E extends { Values: readonly PropertyKey[] }> = E[\"Values\"][number];\n\nfunction defineEnum<const M extends EnumMetaMap>(metaMap: M): DefinedEnum<M> {\n type Key = keyof M;\n const Values = Object.keys(metaMap) as Key[];\n function pickMap<P extends keyof M[Key]>(prop: P) {\n return Object.fromEntries(Object.entries(metaMap).map(([k, v]) => [k, v[prop]])) as {\n [K in Key]: M[K][P];\n };\n }\n function get<K extends Key>(key: K): M[K] {\n return metaMap[key];\n }\n return { Values, pickMap, get };\n}\n\nfunction enumPickMap<M extends EnumMetaMap, P extends keyof M[keyof M]>(e: DefinedEnum<M>, prop: P): { [K in keyof M]: M[K][P] } {\n return e.pickMap(prop) as { [K in keyof M]: M[K][P] };\n}\n\nexport { defineEnum, enumPickMap };\nexport type { EnumMetaMap, DefinedEnum, EnumInferMeta, EnumValue };\n","/**\n * 单条 query key 工厂(支持一个或多个 id,可链式 .withPrefix)\n * Item query key factories (one or more ids, chainable .withPrefix).\n */\nimport type { QueryKey } from \"@tanstack/react-query\";\n\nimport { CACHE_ITEM } from \"./caches\";\n\n/**\n * 链式单条 key 类型:可调用 (...ids) => QueryKey,且带 withPrefix、getPrefix。\n * Chainable item key type: callable (...ids) => QueryKey, with withPrefix() and getPrefix.\n */\ntype ItemKeyChainable = ((...ids: string[]) => QueryKey) & {\n withPrefix(...prefix: unknown[]): ItemKeyChainable;\n /** 不含 id 的前缀,用于 invalidation 等。Prefix without ids, e.g. for invalidation. */\n getPrefix: QueryKey;\n};\n\nfunction buildItemKeyChainable(prefix: unknown[], domain: string, subDomain: string): ItemKeyChainable {\n const base: QueryKey = [...prefix, domain, CACHE_ITEM, subDomain];\n const fn = (...ids: string[]): QueryKey => [...base, ...ids];\n return Object.assign(fn, {\n withPrefix(...more: unknown[]): ItemKeyChainable {\n return buildItemKeyChainable([...more, ...prefix], domain, subDomain);\n },\n get getPrefix(): QueryKey {\n return [...base];\n },\n }) as ItemKeyChainable;\n}\n\n/**\n * 创建「单条」query key 工厂(可链式 .withPrefix):支持传入一个或多个 id,返回 [domain, CACHE_ITEM, subDomain, ...ids]\n * Creates an item query key factory (chainable .withPrefix): accepts one or more ids, returns [domain, CACHE_ITEM, subDomain, ...ids].\n *\n * @param domain - 域名。Domain name (e.g. \"catalog\", \"auth\").\n * @param subDomain - 子域。Sub-domain (e.g. \"category\", \"product\").\n * @returns 可调用的 key 工厂,带 withPrefix 可链式加前缀。Callable key factory with withPrefix for chaining.\n * @example\n * ```ts\n * const getKey = createItemKey(\"catalog\", \"category\");\n * getKey(\"abc\");\n * * => [\"catalog\", \"item\", \"category\", \"abc\"]\n * getKey.getPrefix\n * * => [\"catalog\", \"item\", \"category\"]\n * createItemKey(\"catalog\", \"category\").withPrefix(\"api\").withPrefix(\"v1\").getPrefix;\n * * => [\"v1\", \"api\", \"catalog\", \"item\", \"category\"]\n * ```\n */\nfunction createItemKey(domain: string, subDomain: string): ItemKeyChainable {\n return buildItemKeyChainable([], domain, subDomain);\n}\n\nexport { createItemKey };\nexport type { ItemKeyChainable };\n","/**\n * 列表 query key 工厂(可链式 .withPrefix)\n * List query key factories (chainable .withPrefix).\n */\nimport type { QueryKey } from \"@tanstack/react-query\";\n\nimport { CACHE_LIST } from \"./caches\";\n\n/**\n * 链式列表 key 类型:本身即 QueryKey(数组),且带 withPrefix、getPrefix。\n * Chainable list key type: is a QueryKey (array) and has withPrefix(), getPrefix.\n */\ntype ListKeyChainable = QueryKey & {\n withPrefix(...prefix: unknown[]): ListKeyChainable;\n /** 列表 key 的前缀(即完整 list key,用于 invalidation 等)。Prefix (full list key) for invalidation. */\n getPrefix: QueryKey;\n};\n\nfunction buildListKeyChainable(prefix: unknown[], domain: string, subDomain: string): ListKeyChainable {\n const key: QueryKey = [...prefix, domain, CACHE_LIST, subDomain];\n return Object.assign([...key], {\n withPrefix(...more: unknown[]): ListKeyChainable {\n return buildListKeyChainable([...more, ...prefix], domain, subDomain);\n },\n get getPrefix(): QueryKey {\n return [...key];\n },\n }) as ListKeyChainable;\n}\n\n/**\n * 创建「列表」query key(可链式 .withPrefix):[domain, CACHE_LIST, subDomain]\n * Creates a list query key (chainable .withPrefix): [domain, CACHE_LIST, subDomain].\n *\n * @param domain - 域名。Domain name (e.g. \"catalog\", \"auth\").\n * @param subDomain - 子域。Sub-domain (e.g. \"category\", \"product\").\n * @returns 列表 query key(数组),带 withPrefix 可链式加前缀。List query key (array) with withPrefix for chaining.\n * @example\n * ```ts\n * const key = createListKey(\"catalog\", \"category\");\n * * key => [\"catalog\", \"list\", \"category\"]\n * key.getPrefix\n * * => [\"catalog\", \"list\", \"category\"]\n * createListKey(\"catalog\", \"category\").withPrefix(\"api\").withPrefix(\"v1\").getPrefix;\n * * => [\"v1\", \"api\", \"catalog\", \"list\", \"category\"]\n * ```\n */\nfunction createListKey(domain: string, subDomain: string): ListKeyChainable {\n return buildListKeyChainable([], domain, subDomain);\n}\n\nexport { createListKey };\nexport type { ListKeyChainable };\n","/**\n * 通用 React Query key 工厂(公用包层)\n * Universal React Query key factories for shared use.\n *\n * @example\n * ```ts\n * import { createListKey, createItemKey } from \"@/constants\";\n *\n * const CATALOG_CATEGORY_LIST = createListKey(\"catalog\", \"category\");\n * const CATALOG_CATEGORY = createItemKey(\"catalog\", \"category\");\n *\n * useQuery({ queryKey: CATALOG_CATEGORY_LIST, queryFn: ... });\n * useQuery({ queryKey: CATALOG_CATEGORY(id), queryFn: ... });\n * ```\n */\nimport type { QueryKey } from \"@tanstack/react-query\";\nimport type { ItemKeyChainable } from \"./query.itemkeys\";\nimport type { ListKeyChainable } from \"./query.listkeys\";\n\nimport { createItemKey } from \"./query.itemkeys\";\nimport { createListKey } from \"./query.listkeys\";\n\n/** 含 list / item 且可链式 withPrefix 的 bundle 类型 */\ntype QueryKeysBundle = {\n list: ListKeyChainable;\n item: ItemKeyChainable;\n withPrefix(...prefix: unknown[]): QueryKeysBundle;\n};\n\nfunction createQueryKeysBundle(list: ListKeyChainable, item: ItemKeyChainable): QueryKeysBundle {\n return {\n list,\n item,\n withPrefix(...prefix: unknown[]) {\n return createQueryKeysBundle(list.withPrefix(...prefix), item.withPrefix(...prefix));\n },\n };\n}\n\n/**\n * 创建自定义 query key(任意片段,用于 stats 等)\n * Creates a custom query key from arbitrary segments (e.g. for stats).\n *\n * @param segments - 任意片段(字符串或其它)。Arbitrary segments (strings or other).\n * @returns 由片段组成的 query key。Query key composed of the segments.\n * @example\n * ```ts\n * const key = createKey(\"catalog\", \"stats\", \"category\", \"count\");\n * * key => [\"catalog\", \"stats\", \"category\", \"count\"]\n * ```\n */\nfunction createKey(...segments: unknown[]): QueryKey {\n return segments;\n}\n\n/**\n * 根据同一 domain + subDomain 生成 list key 与 item key 工厂\n * Returns both list key and item key factory for the given domain and subDomain.\n *\n * @param domain - 域名。Domain name (e.g. \"catalog\", \"auth\").\n * @param subDomain - 子域。Sub-domain (e.g. \"category\", \"product\").\n * @returns 含 list、item 及 withPrefix 的 bundle,可链式加前缀。Bundle with list, item, and chainable withPrefix.\n * @example\n * ```ts\n * const { list, item } = createQueryKeys(\"catalog\", \"category\");\n * * list => [\"catalog\", \"list\", \"category\"]\n * * item(\"id-1\") => [\"catalog\", \"item\", \"category\", \"id-1\"]\n * const withApi = createQueryKeys(\"catalog\", \"category\").withPrefix(\"api\");\n * * withApi.list => [\"api\", \"catalog\", \"list\", \"category\"]\n * * withApi.item(\"id-1\") => [\"api\", \"catalog\", \"item\", \"category\", \"id-1\"]\n * ```\n */\nfunction createQueryKeys(domain: string, subDomain: string): QueryKeysBundle {\n return createQueryKeysBundle(createListKey(domain, subDomain), createItemKey(domain, subDomain));\n}\n\nexport { createKey, createQueryKeys };\nexport type { QueryKeysBundle };\n"],"mappings":"mEACA,IAAM,EAAa,OAGb,EAAa,OCQnB,SAAS,EAAwC,EAA4B,CAE3E,MAAM,EAAS,OAAO,KAAK,CAAA,EAC3B,SAAS,EAAgC,EAAS,CAChD,OAAO,OAAO,YAAY,OAAO,QAAQ,CAAA,EAAS,IAAA,CAAK,CAAC,EAAG,CAAA,IAAO,CAAC,EAAG,EAAE,CAAA,CAAA,CAAM,CAAC,EAIjF,SAAS,EAAmB,EAAc,CACxC,OAAO,EAAQ,CAAA,EAEjB,MAAO,CAAE,OAAA,EAAQ,QAAA,EAAS,IAAA,GAG5B,SAAS,EAA+D,EAAmB,EAAsC,CAC/H,OAAO,EAAE,QAAQ,CAAA,ECTnB,SAAS,EAAsB,EAAmB,EAAgB,EAAqC,CACrG,MAAM,EAAiB,CAAC,GAAG,EAAQ,EAAQ,EAAY,GAEvD,OAAO,OAAO,OADR,IAAS,IAA4B,CAAC,GAAG,EAAM,GAAG,CAAA,EAC/B,CACvB,cAAc,EAAmC,CAC/C,OAAO,EAAsB,CAAC,GAAG,EAAM,GAAG,CAAA,EAAS,EAAQ,CAAA,GAE7D,IAAI,WAAsB,CACxB,MAAO,CAAC,GAAG,CAAA,GAEd,EAqBH,SAAS,EAAc,EAAgB,EAAqC,CAC1E,OAAO,EAAsB,CAAA,EAAI,EAAQ,CAAA,EChC3C,SAAS,EAAsB,EAAmB,EAAgB,EAAqC,CACrG,MAAM,EAAgB,CAAC,GAAG,EAAQ,EAAQ,EAAY,GACtD,OAAO,OAAO,OAAO,CAAC,GAAG,CAAA,EAAM,CAC7B,cAAc,EAAmC,CAC/C,OAAO,EAAsB,CAAC,GAAG,EAAM,GAAG,CAAA,EAAS,EAAQ,CAAA,GAE7D,IAAI,WAAsB,CACxB,MAAO,CAAC,GAAG,CAAA,GAEd,EAoBH,SAAS,EAAc,EAAgB,EAAqC,CAC1E,OAAO,EAAsB,CAAA,EAAI,EAAQ,CAAA,ECnB3C,SAAS,EAAsB,EAAwB,EAAyC,CAC9F,MAAO,CACL,KAAA,EACA,KAAA,EACA,cAAc,EAAmB,CAC/B,OAAO,EAAsB,EAAK,WAAW,GAAG,CAAA,EAAS,EAAK,WAAW,GAAG,CAAA,CAAO,IAiBzF,SAAS,KAAa,EAA+B,CACnD,OAAO,EAoBT,SAAS,EAAgB,EAAgB,EAAoC,CAC3E,OAAO,EAAsB,EAAc,EAAQ,CAAA,EAAY,EAAc,EAAQ,CAAA,CAAU"}