@likelion-design/ui 1.0.26 → 1.0.28-beta.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.
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +30 -6
- package/dist/index.d.ts +30 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stories/Button/ActionButton/ActionButton.tsx","../src/stories/Typography/Typography.tsx","../src/stories/Button/IconButton/IconButton.tsx","../src/stories/Tab/Tab.tsx","../src/stories/Badge/Badge.tsx","../src/stories/Chip/Chip.tsx","../node_modules/@heroicons/react/24/outline/esm/CheckIcon.js","../node_modules/@heroicons/react/24/outline/esm/XMarkIcon.js","../src/stories/Dialog/Dialog.tsx","../src/shared/hooks/useMediaQuery.ts","../src/stories/Toggle/Toggle.tsx","../src/stories/Checkbox/Checkbox.tsx","../src/stories/Checkbox/useCheckboxGroup.ts","../src/stories/Select/SelectHeader/SelectHeader.tsx","../src/stories/TextField/TextField.tsx","../node_modules/@heroicons/react/20/solid/esm/ExclamationCircleIcon.js","../src/stories/Select/SelectMenu/SelectMenu.tsx","../node_modules/@heroicons/react/24/solid/esm/CheckCircleIcon.js","../node_modules/@heroicons/react/24/solid/esm/ExclamationTriangleIcon.js","../node_modules/@heroicons/react/24/solid/esm/InformationCircleIcon.js","../node_modules/@heroicons/react/24/solid/esm/XCircleIcon.js","../src/stories/Select/SelectBox/SelectBox.tsx","../src/stories/Pagination/Pagination.tsx","../src/stories/RadioButton/RadioButton.tsx","../src/stories/Tag/Tag.tsx","../src/stories/Tooltip/Tooltip.tsx","../src/stories/Toast/Toast.tsx","../src/stories/DatePicker/DatePicker.tsx","../src/stories/DatePicker/Calendar.tsx","../src/stories/DatePicker/DateInput.tsx","../src/stories/DatePicker/TimePicker.tsx","../src/stories/Logo/logo-assets.ts","../src/stories/Logo/Logo.tsx","../src/stories/Screen/index.ts","../src/stories/LDSProvider.tsx"],"sourcesContent":["import React from \"react\";\nimport { Text } from \"@/stories/Typography/Typography\";\nimport \"./action-button.css\";\n\n/** label 내부의 Text를 span으로 렌더링 (p > h3 등 invalid nesting 방지) */\nfunction ensureTextAsSpan(node: React.ReactNode): React.ReactNode {\n if (React.isValidElement(node) && node.type === Text) {\n return React.cloneElement(node as React.ReactElement<{ as?: string }>, { as: \"span\" });\n }\n if (React.isValidElement(node)) {\n const { children, ...rest } = (node.props as { children?: React.ReactNode });\n if (children != null) {\n return React.cloneElement(\n node as React.ReactElement<{ children?: React.ReactNode }>,\n { ...rest, children: React.Children.map(children, ensureTextAsSpan) }\n );\n }\n }\n return node;\n}\n\nexport type ButtonSize = \"xlarge\" | \"large\" | \"medium\" | \"small\";\nexport type ButtonColor = \"primary\" | \"neutral\" | \"secondary\";\nexport type ButtonType = \"solid\" | \"outline\" | \"ghost\" | \"weak\";\nexport interface ActionButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\" // HTML type 속성과 이름 충돌 방지\n> {\n /** 버튼 크기 */\n size?: ButtonSize;\n /** 버튼 색상 (primary, neutral, secondary) */\n color?: ButtonColor;\n /** 버튼 스타일 타입 (solid, outline, ghost, weak) */\n type?: ButtonType;\n /** HTML 버튼 타입 (button, submit, reset) */\n htmlType?: \"button\" | \"submit\" | \"reset\";\n /** 비활성화 */\n disabled?: boolean;\n /** 로딩 상태 */\n loading?: boolean;\n /** 버튼 텍스트 */\n label: React.ReactNode;\n /** Prefix 아이콘 */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n}\n\n/** ActionButton 컴포넌트는 사용자가 어떠한 액션을 트리거하거나 이벤트를 실행할 때 사용한다. */\nexport const ActionButton = React.forwardRef<HTMLButtonElement, ActionButtonProps>(({\n size = \"medium\",\n color = \"primary\",\n type = \"solid\",\n htmlType = \"button\",\n label,\n prefixIcon,\n suffixIcon,\n loading = false,\n className = \"\",\n disabled = false,\n ...props\n}, ref) => {\n const isDisabled = disabled || loading;\n // ghost 타입은 loading 상태를 지원하지 않음\n const isLoading = loading && type !== \"ghost\";\n\n const baseClasses = [\n \"action-button\",\n `action-button--${size}`,\n `action-button--${color}`,\n `action-button--${type}`,\n isLoading && \"action-button--loading\",\n isDisabled && \"action-button--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const textVariant = (() => {\n if (size === \"xlarge\") {\n return \"heading-h6\";\n } else if (size === \"large\" || size === \"medium\") {\n return \"subtitle-p2\";\n } else if (size === \"small\") {\n return \"subtitle-p3\";\n } else {\n return \"subtitle-p3\";\n }\n })();\n\n return (\n <button\n ref={ref}\n type={htmlType}\n className={baseClasses}\n disabled={isDisabled}\n {...props}\n >\n <span className=\"action-button__content\">\n {prefixIcon && (\n <span className=\"action-button__prefix-icon\">{prefixIcon}</span>\n )}\n <span className=\"action-button__label\">\n <Text variant={textVariant} as=\"span\">{ensureTextAsSpan(label)}</Text>\n </span>\n {suffixIcon && (\n <span className=\"action-button__suffix-icon\">{suffixIcon}</span>\n )}\n </span>\n {isLoading && (\n <span className=\"action-button__spinner\" aria-hidden=\"true\">\n <svg\n className=\"action-button__spinner-svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n className=\"action-button__spinner-circle\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"32\"\n strokeDashoffset=\"32\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 40;40 40;0 40\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-40;-80\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n </span>\n )}\n </button>\n );\n});\n\nActionButton.displayName = \"ActionButton\";\n","import React from \"react\";\nimport \"./typography.css\";\n\nexport type TextVariant =\n | \"display-d1\"\n | \"display-d2\"\n | \"display-d3\"\n | \"display-d4\"\n | \"heading-h1\"\n | \"heading-h2\"\n | \"heading-h3\"\n | \"heading-h4\"\n | \"heading-h5\"\n | \"heading-h6\"\n | \"subtitle-p1\"\n | \"subtitle-p2\"\n | \"subtitle-p3\"\n | \"body-p1\"\n | \"body-p2\"\n | \"body-p3\"\n | \"body-p4\"\n | \"body-p5\";\n\nexport type TextDecoration = \"none\" | \"underline\";\n\nexport interface TextProps\n extends React.HTMLAttributes<HTMLElement> {\n /** Text 변형 */\n variant: TextVariant;\n /** 텍스트 장식 (underline 등) */\n decoration?: TextDecoration;\n /** HTML 태그 (기본값: variant에 따라 자동 결정) */\n as?: keyof React.JSX.IntrinsicElements;\n /** 자식 요소 */\n children: React.ReactNode;\n}\n\n/** Text 컴포넌트는 텍스트 스타일을 일관되게 적용하는 컴포넌트입니다. */\nexport const Text = React.forwardRef<HTMLElement, TextProps>(({\n variant,\n decoration = \"none\",\n as,\n children,\n className = \"\",\n ...props\n}, ref) => {\n // variant에 따라 기본 HTML 태그 결정\n const defaultTag = (() => {\n if (variant.startsWith(\"heading-\")) {\n const level = variant.split(\"-\")[1];\n if (level.startsWith(\"d\")) {\n return \"h1\"; // Display는 h1으로\n }\n return level; // h1, h2, h3, h4, h5, h6\n }\n if (variant.startsWith(\"subtitle-\")) {\n return \"h3\";\n }\n return \"p\"; // Body는 p 태그\n })();\n\n const Tag = (as || defaultTag) as keyof React.JSX.IntrinsicElements;\n\n const baseClasses = [\n \"typography\",\n `typography--${variant}`,\n decoration !== \"none\" && `typography--decoration-${decoration}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return React.createElement(Tag, { ref, className: baseClasses, ...props }, children);\n});\n\nText.displayName = \"Text\";\n","import React from \"react\";\n\nexport type IconButtonSize = \"xlarge\" | \"large\" | \"medium\" | \"small\";\n/** 버튼 색상. solid/outline: primary | neutral | secondary. weak: primary | neutral-dark | neutral-light */\nexport type IconButtonColor =\n | \"primary\"\n | \"neutral\"\n | \"secondary\"\n | \"neutral-dark\"\n | \"neutral-light\";\n/** 버튼 타입. weak일 때 color로 primary / neutral-dark / neutral-light 구분 */\nexport type IconButtonType = \"solid\" | \"outline\" | \"weak\";\n/** IconButton 슬롯 */\nexport type IconButtonSlot = \"root\" | \"icon\";\n\nexport interface IconButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n /** 버튼 크기 */\n size?: IconButtonSize;\n /** 버튼 색상. 기본 세트: primary, neutral, secondary 등 */\n color?: IconButtonColor;\n /** 버튼 타입 (solid, outline, weak) */\n type?: IconButtonType;\n /** 비활성화 */\n disabled?: boolean;\n /** 아이콘 (Heroicons 또는 React 컴포넌트) */\n icon: React.ReactNode;\n /** button 요소의 type (submit 등). 기본값 button */\n htmlType?: \"button\" | \"submit\" | \"reset\";\n /** 각 슬롯별 인라인 스타일 (root, icon) */\n styles?: Partial<Record<IconButtonSlot, React.CSSProperties>>;\n}\n\n/** IconButton 컴포넌트는 텍스트 레이블 없이 아이콘만으로 액션을 전달하는 버튼 컴포넌트이다. */\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(({\n size = \"large\",\n color = \"primary\",\n type = \"solid\",\n icon,\n className = \"\",\n disabled = false,\n htmlType = \"button\",\n style: propsStyle,\n styles,\n ...props\n}, ref) => {\n const isWeakType = type === \"weak\";\n\n const colorClass = isWeakType\n ? `icon-button--weak-${color}`\n : `icon-button--${color}`;\n const typeClass = isWeakType ? \"icon-button--weak\" : `icon-button--${type}`;\n\n const baseClasses = [\n \"icon-button\",\n `icon-button--${size}`,\n colorClass,\n typeClass,\n disabled && \"icon-button--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // weak 타입이고 disabled 상태일 때는 미노출 (opacity-0)\n const shouldHide = isWeakType && disabled;\n\n return (\n <button\n ref={ref}\n type={htmlType}\n className={baseClasses}\n disabled={disabled}\n style={{\n ...propsStyle,\n ...styles?.root,\n ...(shouldHide ? { opacity: 0, pointerEvents: \"none\" } : {}),\n }}\n {...props}\n >\n <span className=\"icon-button__icon\" style={styles?.icon}>{icon}</span>\n </button>\n );\n});\n\nIconButton.displayName = \"IconButton\";\n","import React, { useState, forwardRef } from \"react\";\nimport \"./tab.css\";\nimport { Badge } from \"../Badge/Badge\";\n\nexport type TabType = \"round\" | \"text\";\nexport type TabSize = \"large\" | \"medium\";\n\nexport interface TabProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n /** 탭 타입 (round 또는 text) */\n type?: TabType;\n /** 탭 크기 */\n size?: TabSize;\n /** 배지 표시 여부 */\n badge?: boolean;\n /** 탭 라벨 */\n label: React.ReactNode;\n /** 탭 값 (TabGroup에서 사용 시 식별자) */\n value?: string;\n /** 다크 모드 여부 */\n mode?: boolean;\n /** 선택된 상태 (탭 그룹에서 사용 시 부모 컴포넌트가 관리, 예: 기본 탭이 '설명'이면 selected={true}) */\n selected?: boolean;\n /** 비활성화 상태 */\n disabled?: boolean;\n}\n\n/** Tab 컴포넌트는 사용자가 여러 옵션 중 하나를 선택할 때 사용하는 탭 컴포넌트이다. */\nexport const Tab = forwardRef<HTMLButtonElement, TabProps>(({\n type = \"round\",\n size = \"large\",\n badge = false,\n label,\n mode = false,\n className = \"\",\n selected,\n disabled = false,\n onClick,\n ...props\n}, ref) => {\n // selected prop이 제공되면 controlled, 아니면 uncontrolled\n const [internalPressed, setInternalPressed] = useState(false);\n const isControlled = selected !== undefined;\n const isPressed = isControlled ? selected : internalPressed;\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n \n if (!isControlled) {\n // uncontrolled 모드: 내부 상태 토글\n setInternalPressed((prev) => !prev);\n }\n onClick?.(e);\n };\n\n const state = disabled ? \"disabled\" : (isPressed ? \"pressed\" : \"enabled\");\n\n const baseClasses = [\n \"tab\",\n `tab--${type}`,\n `tab--${size}`,\n `tab--${state}`,\n mode && \"tab--dark\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={baseClasses}\n aria-pressed={isPressed}\n disabled={disabled}\n onClick={handleClick}\n {...props}\n >\n <span className=\"tab__label\">{label}</span>\n {badge && (\n <Badge\n type=\"dot\"\n variant=\"primary\"\n className=\"tab__badge\"\n aria-label=\"알림\"\n />\n )}\n </button>\n );\n});\n\nTab.displayName = \"Tab\";\n\n// TabGroup\nexport interface TabItem {\n /** 탭 식별 값 */\n value: string;\n /** 탭 라벨 */\n label: React.ReactNode;\n /** 배지 표시 여부 */\n badge?: boolean;\n /** 개별 탭 비활성화 */\n disabled?: boolean;\n}\n\nexport interface TabGroupProps {\n /** 선택된 탭 값 (controlled) */\n value?: string;\n /** 초기 선택 탭 값 (uncontrolled) */\n defaultValue?: string;\n /** 선택 변경 핸들러 */\n onChange?: (value: string) => void;\n /** 탭 타입 (컨테이너 스타일: Round일 때 gap, Text일 때 하단 보더) */\n type?: TabType;\n /** 탭 크기 (컨테이너 gap 등) */\n size?: TabSize;\n /** 다크 모드 */\n mode?: boolean;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** 탭 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly TabItem[];\n /** 자식 Tab 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n /** 탭 간 간격 (px 또는 CSS 문자열). 미지정 시 기본 gap 적용 */\n gap?: number | string;\n /** 추가 CSS 클래스명 */\n className?: string;\n /** 인라인 스타일 */\n style?: React.CSSProperties;\n}\n\n/** TabGroup은 여러 Tab을 그룹화하여 단일 선택을 관리한다. */\nexport const TabGroup = ({\n value: valueProp,\n defaultValue,\n onChange,\n type = \"round\",\n size = \"large\",\n mode = false,\n disabled = false,\n items,\n children,\n gap,\n className = \"\",\n style,\n}: TabGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string | undefined>(\n defaultValue\n );\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const baseClasses = [\n \"tab-group\",\n `tab-group--${type}`,\n `tab-group--${size}`,\n mode && \"tab-group--dark\",\n disabled && \"tab-group--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const groupStyle: React.CSSProperties | undefined = {\n ...(gap != null && { gap: typeof gap === \"number\" ? `${gap}px` : gap }),\n ...style,\n };\n\n const handleTabClick = (tabValue: string, originalOnClick?: (e: React.MouseEvent<HTMLButtonElement>) => void) =>\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!isControlled) setInternalValue(tabValue);\n onChange?.(tabValue);\n originalOnClick?.(e);\n };\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedTabs = items\n ? items.map((item) => {\n const isSelected = value === item.value;\n return (\n <Tab\n key={item.value}\n value={item.value}\n label={item.label}\n badge={item.badge}\n type={type}\n size={size}\n mode={mode}\n selected={isSelected}\n disabled={disabled || item.disabled}\n role=\"tab\"\n aria-selected={isSelected}\n onClick={handleTabClick(item.value)}\n />\n );\n })\n : React.Children.map(children, (child) => {\n if (React.isValidElement<TabProps>(child) && child.type === Tab) {\n const tabValue = child.props.value;\n if (tabValue === undefined) {\n console.warn(\"TabGroup 내부의 Tab은 value prop이 필요합니다.\");\n return child;\n }\n\n const isSelected = value === tabValue;\n\n return React.cloneElement(child, {\n type: child.props.type ?? type,\n size: child.props.size ?? size,\n mode: child.props.mode ?? mode,\n selected: isSelected,\n disabled: disabled || child.props.disabled,\n role: \"tab\",\n \"aria-selected\": isSelected,\n onClick: handleTabClick(tabValue, child.props.onClick),\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses} style={groupStyle} role=\"tablist\">\n {renderedTabs}\n </div>\n );\n};\n\nTabGroup.displayName = \"TabGroup\";\n\n(Tab as typeof Tab & { Group: typeof TabGroup }).Group = TabGroup;\n\n","import React from \"react\";\nimport \"./badge.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type BadgeVariant =\n | \"primary\"\n | \"secondary\"\n | \"progressing\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"disabled\";\nexport type BadgeType = \"number\" | \"dot\";\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** number: 글자(숫자/문자) 표시, dot: 점만 표시 */\n type?: BadgeType;\n /** Badge variant (primary, secondary, progressing, success, warning, error, disabled) */\n variant?: BadgeVariant;\n /** Badge 값 (type이 number일 때 표시할 숫자 또는 글자) */\n value?: number | string;\n /** 최대 표시 숫자 (숫자일 때 이 값을 넘으면 maxValue+ 형태로 표시) */\n maxValue?: number;\n}\n\n/** Badge 컴포넌트는 알림 카운트, 상태 등을 시각적으로 표현하는 원형 라벨 컴포넌트다. */\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(({\n type = \"number\",\n variant = \"primary\",\n value,\n maxValue = 99,\n className = \"\",\n ...props\n}, ref) => {\n const baseClasses = [\n \"badge\",\n `badge--${variant}`,\n `badge--${type}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const displayValue =\n type === \"number\" && value !== undefined\n ? typeof value === \"number\"\n ? value > maxValue\n ? `${maxValue}+`\n : String(value)\n : String(value)\n : null;\n\n return (\n <span ref={ref} className={baseClasses} {...props}>\n {type === \"number\" && displayValue && (\n <Text variant=\"subtitle-p3\" as=\"span\">\n {displayValue}\n </Text>\n )}\n </span>\n );\n});\n\nBadge.displayName = \"Badge\";\n","import React from \"react\";\nimport { CheckIcon } from \"@heroicons/react/24/outline\";\nimport \"./chip.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type ChipType = \"solid\" | \"outline\" | \"weak\";\nexport type ChipSize = \"medium\" | \"small\";\nexport type ChipVariant = \"primary\" | \"neutral\";\n\nexport interface ChipProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\" | \"onChange\"\n> {\n /** Chip 타입 (solid, outline, weak) */\n type?: ChipType;\n /** Chip 크기 */\n size?: ChipSize;\n /** Chip variant (primary, neutral) */\n variant?: ChipVariant;\n /** Chip 값 (각 Chip을 구분하는 고유 값) */\n value: string;\n /** Chip 클릭 핸들러 (클릭 시 해당 Chip의 value를 전달) */\n onChange?: (value: string) => void;\n /** Chip 선택 상태 (controlled 모드) */\n checked?: boolean;\n /** Chip 초기 선택 상태 (uncontrolled 모드) */\n defaultChecked?: boolean;\n /** 단일 선택 그룹에서 선택된 값 (checked prop이 없을 때 자동으로 checked 계산) */\n selectedValue?: string | null;\n /** 다중 선택 그룹에서 선택된 값들 (checked prop이 없을 때 자동으로 checked 계산) */\n selectedValues?: string[];\n /** Chip 라벨 */\n label: React.ReactNode;\n /** Prefix 아이콘 (항상 표시) */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n /** \n * Checked 상태일 때 체크 아이콘 표시 여부\n * - 기본값: undefined (outline 타입이고 prefixIcon이 없을 때만 자동 표시)\n * - true: 항상 표시 (checked 상태일 때)\n * - false: 표시 안 함\n */\n showCheck?: boolean;\n /** Close 버튼 표시 여부 */\n showClose?: boolean;\n /** Close 버튼 클릭 핸들러 */\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\n/** Chip 컴포넌트는 사용자가 직접 선택, 추가, 삭제할 수 있는 인터랙티브한 컴포넌트다. */\nconst ChipComponent = React.forwardRef<HTMLButtonElement, ChipProps>(({\n type = \"solid\",\n size = \"medium\",\n variant = \"primary\",\n value,\n onChange,\n checked: checkedProp,\n defaultChecked = false,\n selectedValue,\n selectedValues,\n label,\n prefixIcon,\n suffixIcon,\n showCheck,\n showClose = false,\n onClose,\n className = \"\",\n disabled,\n onClick,\n ...props\n}, ref) => {\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] = React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n\n // checked 상태 결정\n const checked = React.useMemo(() => {\n if (isControlled) {\n return checkedProp;\n }\n if (selectedValue !== undefined && selectedValue !== null) {\n return selectedValue === value;\n }\n if (selectedValues !== undefined) {\n return selectedValues.includes(value);\n }\n return internalChecked;\n }, [\n isControlled,\n checkedProp,\n selectedValue,\n selectedValues,\n value,\n internalChecked,\n ]);\n\n // 체크 아이콘 렌더링 결정\n let shouldRenderCheckIcon = false;\n\n if (checked) {\n if (showCheck === true) {\n // 강제 표시\n shouldRenderCheckIcon = true;\n } else if (showCheck === false) {\n // 강제 미표시\n shouldRenderCheckIcon = false;\n } else {\n // 기본 로직: outline 타입이고 prefixIcon이 없을 때만 자동 표시\n shouldRenderCheckIcon = type === \"outline\" && !prefixIcon;\n }\n }\n\n const renderedCheckIcon = shouldRenderCheckIcon ? (\n <CheckIcon\n className=\"chip__check-icon\"\n style={{\n width: size === \"small\" ? \"14px\" : \"16px\",\n height: size === \"small\" ? \"14px\" : \"16px\",\n }}\n />\n ) : null;\n\n // 최종 Prefix 영역: prefixIcon이 있으면 우선, 없으면 체크 아이콘\n // (showCheck={true}일 때도 prefixIcon이 있으면 prefixIcon이 우선시됨)\n const displayLeftIcon = prefixIcon || renderedCheckIcon;\n\n // 아이콘 조합에 따른 패딩 클래스 결정\n const hasPrefix = !!displayLeftIcon;\n const hasSuffix = !!(suffixIcon || showClose);\n\n const paddingClass = (() => {\n if (hasPrefix && hasSuffix) {\n return \"chip--has-prefix-suffix\";\n } else if (hasPrefix) {\n return \"chip--has-prefix\";\n } else if (hasSuffix) {\n return \"chip--has-suffix\";\n }\n return \"chip--no-icon\";\n })();\n\n const baseClasses = [\n \"chip\",\n `chip--${type}`,\n `chip--${size}`,\n `chip--${variant}`,\n paddingClass,\n checked && \"chip--checked\",\n disabled && \"chip--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n\n if (\n !isControlled &&\n selectedValue === undefined &&\n selectedValues === undefined\n ) {\n setInternalChecked((prev) => !prev);\n }\n\n if (onChange) {\n onChange(value);\n }\n\n onClick?.(e);\n };\n\n const handleClose = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (onClose && !disabled) {\n onClose(e);\n }\n };\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={baseClasses}\n disabled={disabled}\n onClick={handleClick}\n aria-pressed={checked}\n {...props}\n >\n {displayLeftIcon && (\n <span className=\"chip__prefix-icon\">{displayLeftIcon}</span>\n )}\n <Text variant={size === \"small\" ? \"body-p3\" : \"body-p2\"}>{label}</Text>\n {suffixIcon && !showClose && (\n <span className=\"chip__suffix-icon\">{suffixIcon}</span>\n )}\n {showClose && (\n <span\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n className=\"chip__close-button\"\n onClick={handleClose}\n onKeyDown={(e) => {\n if (!disabled && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n handleClose(e as unknown as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n aria-label=\"Close\"\n aria-disabled={disabled}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8C1 4.13401 4.13401 1 8 1ZM10.7803 5.21973C10.4874 4.92683 10.0126 4.92683 9.71973 5.21973L8 6.93945L6.28027 5.21973C5.98738 4.92683 5.51262 4.92683 5.21973 5.21973C4.92683 5.51262 4.92683 5.98738 5.21973 6.28027L6.93945 8L5.21973 9.71973C4.92683 10.0126 4.92683 10.4874 5.21973 10.7803C5.51262 11.0732 5.98738 11.0732 6.28027 10.7803L8 9.06055L9.71973 10.7803C10.0126 11.0732 10.4874 11.0732 10.7803 10.7803C11.0732 10.4874 11.0732 10.0126 10.7803 9.71973L9.06055 8L10.7803 6.28027C11.0732 5.98738 11.0732 5.51262 10.7803 5.21973Z\"\n fill=\"currentColor\"\n fillOpacity=\"0.56\"\n />\n </svg>\n </span>\n )}\n </button>\n );\n});\n\n// Chip.Group\nexport interface ChipItem {\n /** Chip 식별 값 */\n value: string;\n /** Chip 라벨 */\n label: React.ReactNode;\n /** Prefix 아이콘 */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n /** 체크 아이콘 표시 여부 */\n showCheck?: boolean;\n /** Close 버튼 표시 여부 */\n showClose?: boolean;\n /** Close 버튼 클릭 핸들러 */\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n /** 개별 Chip 비활성화 */\n disabled?: boolean;\n}\n\nexport interface ChipGroupProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 선택된 값 (controlled) - 단일: string, 다중: string[] */\n value?: string | string[];\n /** 초기 선택 값 (uncontrolled) */\n defaultValue?: string | string[];\n /** 선택 변경 시 호출 (클릭한 Chip의 value 전달) */\n onChange?: (value: string) => void;\n /** 다중 선택 여부 */\n multiple?: boolean;\n /** Chip 타입 */\n type?: ChipType;\n /** Chip 크기 */\n size?: ChipSize;\n /** Chip variant */\n variant?: ChipVariant;\n /** 체크 아이콘 표시 여부 (자식 Chip에 일괄 적용) */\n showCheck?: boolean;\n /** 전체 비활성화 */\n disabled?: boolean;\n /** Chip 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly ChipItem[];\n /** 자식 Chip 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n}\n\n/** ChipGroup은 여러 Chip을 그룹화하여 단일/다중 선택을 관리한다. */\nexport const ChipGroup = ({\n value: valueProp,\n defaultValue,\n onChange,\n multiple = false,\n type = \"solid\",\n size = \"medium\",\n variant = \"primary\",\n showCheck,\n disabled = false,\n items,\n children,\n className = \"\",\n ...rest\n}: ChipGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n () => defaultValue ?? (multiple ? [] : \"\")\n );\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const handleChange = (chipValue: string) => {\n if (multiple) {\n const arr = (Array.isArray(value) ? value : []) as string[];\n const next = arr.includes(chipValue)\n ? arr.filter((v) => v !== chipValue)\n : [...arr, chipValue];\n if (!isControlled) setInternalValue(next);\n onChange?.(chipValue);\n } else {\n if (!isControlled) setInternalValue(chipValue);\n onChange?.(chipValue);\n }\n };\n\n const selectedValue = multiple ? undefined : (value as string);\n const selectedValues = multiple ? (value as string[]) : undefined;\n\n const baseClasses = [\"chip-group\", className].filter(Boolean).join(\" \");\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedChips = items\n ? items.map((item) => (\n <ChipComponent\n key={item.value}\n value={item.value}\n label={item.label}\n type={type}\n size={size}\n variant={variant}\n showCheck={item.showCheck ?? showCheck}\n prefixIcon={item.prefixIcon}\n suffixIcon={item.suffixIcon}\n showClose={item.showClose}\n onClose={item.onClose}\n selectedValue={selectedValue}\n selectedValues={selectedValues}\n onChange={handleChange}\n disabled={disabled || item.disabled}\n />\n ))\n : React.Children.map(children, (child) => {\n if (React.isValidElement<ChipProps>(child) && child.type === Chip) {\n const chipValue = child.props.value;\n if (chipValue === undefined) {\n console.warn(\"ChipGroup 내부의 Chip은 value prop이 필요합니다.\");\n return child;\n }\n\n return React.cloneElement(child, {\n type: child.props.type ?? type,\n size: child.props.size ?? size,\n variant: child.props.variant ?? variant,\n showCheck: child.props.showCheck ?? showCheck,\n selectedValue,\n selectedValues,\n onChange: (v: string) => {\n handleChange(v);\n child.props.onChange?.(v);\n },\n disabled: disabled || child.props.disabled,\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses} {...rest}>\n {renderedChips}\n </div>\n );\n};\n\nChipGroup.displayName = \"ChipGroup\";\nChipComponent.displayName = \"Chip\";\n\nexport const Chip = Object.assign(ChipComponent, {\n Group: ChipGroup,\n});\n","import * as React from \"react\";\nfunction CheckIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m4.5 12.75 6 6 9-13.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(CheckIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction XMarkIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M6 18 18 6M6 6l12 12\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(XMarkIcon);\nexport default ForwardRef;","import React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { XMarkIcon } from \"@heroicons/react/24/outline\";\nimport { ActionButton } from \"../Button/ActionButton/ActionButton\";\nimport type {\n ButtonSize,\n ButtonColor,\n ButtonType,\n} from \"../Button/ActionButton/ActionButton\";\nimport \"./dialog.css\";\nimport \"../Button/ActionButton/action-button.css\";\nimport { useBreakpoint } from \"../../shared/hooks/useMediaQuery\";\nimport { Text } from \"../Typography/Typography\";\nimport \"../Typography/typography.css\";\n\n// -------------------- Contexts --------------------\n\nconst DialogContext = React.createContext<{\n onClose?: () => void;\n variant?: DialogVariant;\n} | null>(null);\n\n// -------------------- Types --------------------\n\nexport type DialogAlign = \"center\" | \"left\";\nexport type DialogFooterLayout = \"horizontal\" | \"vertical\";\nexport type DialogVariant = \"alert\" | \"confirm\";\nexport type DialogActionColor = ButtonColor;\nexport type DialogActionType = ButtonType;\nexport type DialogActionSize = Exclude<ButtonSize, \"xlarge\">;\n\n/** 기존 방식의 Action Item 정의 */\nexport interface DialogActionItem {\n label: string;\n color?: DialogActionColor;\n type?: DialogActionType;\n size?: DialogActionSize;\n prefixIcon?: React.ReactNode;\n suffixIcon?: React.ReactNode;\n loading?: boolean;\n disabled?: boolean;\n onClick?: () => void | Promise<void>;\n /** 클릭 시 다이얼로그 닫기 여부 (기본값: true) */\n closeOnClick?: boolean;\n}\n\nexport interface DialogProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n open?: boolean;\n onClose?: () => void;\n /** 오버레이 클릭 시 닫기 여부 (기본값: true) */\n closeOnOverlayClick?: boolean;\n /** ESC 키로 닫기 여부 (기본값: true) */\n closeOnEsc?: boolean;\n /** 우측 상단 X(닫기) 버튼 표시 여부 (기본값: false) */\n withClose?: boolean;\n /** 다이얼로그 타입 (스타일링용) */\n variant?: DialogVariant;\n /** 정렬 (기본값: variant가 alert면 left, 아니면 center) */\n align?: DialogAlign;\n \n // --- Data-driven Props (편의성 및 하위 호환성) ---\n /** 다이얼로그 제목 */\n title?: React.ReactNode;\n /** 다이얼로그 본문/설명 */\n description?: React.ReactNode;\n /** 다이얼로그 아이콘 */\n icon?: React.ReactNode;\n /** 하단 버튼 목록 (Compound Component 대신 사용 가능) */\n actionItems?: DialogActionItem[];\n /** actionItems 사용 시 버튼 레이아웃 */\n footerLayout?: DialogFooterLayout;\n /** 다이얼로그 너비 (미지정 시 기본 고정 너비 사용) */\n width?: number | string;\n\n className?: string;\n children?: React.ReactNode;\n}\n\n// -------------------- Components --------------------\n\nconst DialogRoot = ({\n open = false,\n onClose,\n closeOnOverlayClick = true,\n closeOnEsc = true,\n withClose = false,\n variant = \"confirm\",\n align,\n \n // Data-driven props\n title,\n description,\n icon,\n actionItems,\n footerLayout = \"horizontal\",\n width,\n\n className = \"\",\n children,\n ...props\n}: DialogProps) => {\n const { isUnderTablet } = useBreakpoint();\n\n // mounted 상태 확인 (SSR 대응)\n const [mounted, setMounted] = React.useState(false);\n React.useEffect(() => {\n setMounted(true);\n return () => setMounted(false);\n }, []);\n\n React.useEffect(() => {\n if (!open) return;\n\n // Body Scroll Lock\n const originalStyle = window.getComputedStyle(document.body).overflow;\n document.body.style.overflow = \"hidden\";\n\n if (closeOnEsc) {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose?.();\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n document.body.style.overflow = originalStyle; // Cleanup 시 복원\n };\n }\n \n return () => {\n document.body.style.overflow = originalStyle; // Cleanup 시 복원\n };\n }, [open, closeOnEsc, onClose]);\n\n if (!open) return null;\n\n const resolvedAlign = align ?? (variant === \"alert\" ? \"left\" : \"center\");\n const baseClasses = [\n \"dialog\",\n `dialog--${variant}`,\n `dialog--${resolvedAlign}`,\n isUnderTablet ? \"is-mobile\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget && closeOnOverlayClick) {\n onClose?.();\n }\n };\n\n // props가 있으면 보이고, children이 있으면 children도 보임\n const contentNode = (\n <>\n {(title || icon) && <DialogHeader title={title} icon={icon} />}\n {description && <DialogBody>{description}</DialogBody>}\n {children}\n {actionItems && actionItems.length > 0 && (\n <DialogFooter layout={footerLayout}>\n {actionItems.map((item, idx) => (\n <DialogButton\n key={`${item.label}-${idx}`}\n label={item.label}\n color={item.color}\n type={item.type}\n size={item.size}\n prefixIcon={item.prefixIcon}\n suffixIcon={item.suffixIcon}\n loading={item.loading}\n disabled={item.disabled}\n onClick={item.onClick}\n closeOnClick={item.closeOnClick ?? true}\n />\n ))}\n </DialogFooter>\n )}\n </>\n );\n\n const dialogOverlay = (\n <div\n className=\"dialog-overlay\"\n role=\"presentation\"\n onClick={handleOverlayClick}\n >\n <div className={baseClasses} role=\"dialog\" aria-modal=\"true\" style={width != null ? { width } : undefined} {...props}>\n <DialogContext.Provider value={{ onClose, variant }}>\n {withClose && (\n <button\n type=\"button\"\n className=\"dialog__close\"\n onClick={onClose}\n aria-label=\"닫기\"\n >\n <XMarkIcon className=\"dialog__close-icon\" />\n </button>\n )}\n {contentNode}\n </DialogContext.Provider>\n </div>\n </div>\n );\n\n // mounted 상태 확인 (SSR 대응) - 상단에서 처리됨\n // const [mounted, setMounted] = React.useState(false);\n // React.useEffect(() => {\n // setMounted(true);\n // return () => setMounted(false);\n // }, []);\n\n if (!mounted) return null;\n\n return createPortal(dialogOverlay, document.body);\n};\n\n// --- Sub Components ---\n\nexport interface DialogHeaderProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: React.ReactNode;\n icon?: React.ReactNode;\n}\n\nconst DialogHeader = ({\n title,\n icon,\n className = \"\",\n children,\n ...props\n}: DialogHeaderProps) => {\n const { isUnderTablet } = useBreakpoint();\n return (\n <div className={`dialog__header ${className}`} {...props}>\n {icon && <span className=\"dialog__icon\">{icon}</span>}\n {title && (\n <Text variant={isUnderTablet ? \"subtitle-p1\" : \"heading-h6\"}>\n {title}\n </Text>\n )}\n {children}\n </div>\n );\n};\n\nexport type DialogBodyProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogBody = ({ className = \"\", children, ...props }: DialogBodyProps) => {\n return (\n <div className={`dialog__body ${className}`} {...props}>\n <div className=\"body-p2 dialog__body-text\">{children}</div>\n </div>\n );\n};\n\nexport interface DialogFooterProps\n extends React.HTMLAttributes<HTMLDivElement> {\n layout?: DialogFooterLayout;\n}\n\nconst DialogFooter = ({\n layout = \"horizontal\",\n className = \"\",\n children,\n ...props\n}: DialogFooterProps) => {\n const layoutClass =\n layout === \"vertical\"\n ? \"dialog__actions--vertical\"\n : \"dialog__actions--horizontal\";\n\n return (\n <div\n className={`dialog__footer dialog__footer--${layout} ${className}`}\n {...props}\n >\n <div className={`dialog__actions ${layoutClass}`}>{children}</div>\n </div>\n );\n};\n\n// DialogButton: ActionButton을 래핑하여 Dialog 컨텍스트와 연동\nexport interface DialogButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n label: string;\n color?: ButtonColor;\n type?: ButtonType;\n size?: Exclude<ButtonSize, \"xlarge\">;\n prefixIcon?: React.ReactNode;\n suffixIcon?: React.ReactNode;\n loading?: boolean;\n disabled?: boolean;\n /** 클릭 시 다이얼로그 닫기 여부 (기본값: false - 명시적으로 닫아야 함) */\n closeOnClick?: boolean;\n}\n\nconst DialogButton = ({\n label,\n color,\n type,\n size,\n prefixIcon,\n suffixIcon,\n loading,\n disabled,\n onClick,\n closeOnClick = false,\n style,\n ...props\n}: DialogButtonProps) => {\n const context = React.useContext(DialogContext);\n const { isUnderTablet } = useBreakpoint();\n\n // 기본 스타일 계산\n const variant = context?.variant ?? \"confirm\";\n const buttonWidth = variant === \"confirm\" ? \"100%\" : \"auto\";\n const defaultSize =\n variant === \"alert\" ? (isUnderTablet ? \"small\" : \"medium\") : \"large\";\n const defaultType = variant === \"alert\" ? \"outline\" : \"solid\";\n const defaultColor = \"neutral\"; \n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (closeOnClick) {\n context?.onClose?.();\n }\n };\n\n return (\n <ActionButton\n label={label}\n size={size ?? defaultSize}\n color={color ?? defaultColor}\n type={type ?? defaultType}\n prefixIcon={prefixIcon}\n suffixIcon={suffixIcon}\n loading={loading}\n disabled={disabled}\n onClick={handleClick}\n style={{ width: buttonWidth, ...style }}\n {...props}\n />\n );\n};\n\n// --- Export with Compound Component Pattern ---\n\nDialogRoot.displayName = \"Dialog\";\n\nexport const Dialog = Object.assign(DialogRoot, {\n Header: DialogHeader,\n Body: DialogBody,\n Footer: DialogFooter,\n Button: DialogButton,\n});\n\n// -------------------- Global Provider & Hook --------------------\n\nexport interface DialogOptions {\n id?: string;\n variant?: DialogVariant;\n align?: DialogAlign;\n title?: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n // Hook에서 사용할 때는 간단한 버튼 정의 (Compound 대신)\n buttons?: DialogActionItem[];\n \n onClose?: () => void;\n closeOnOverlayClick?: boolean;\n closeOnEsc?: boolean;\n withClose?: boolean;\n}\n\nexport interface AlertOptions extends Omit<DialogOptions, \"buttons\"> {\n confirmLabel?: string;\n onConfirm?: () => void | Promise<void>;\n}\n\nexport interface ConfirmOptions extends Omit<DialogOptions, \"buttons\"> {\n confirmLabel?: string;\n cancelLabel?: string;\n onConfirm?: () => void | Promise<void>;\n onCancel?: () => void | Promise<void>;\n}\n\ninterface DialogContextType {\n open: (options: DialogOptions) => string;\n close: (id: string) => void;\n closeAll: () => void;\n alert: (options: AlertOptions) => Promise<void>;\n confirm: (options: ConfirmOptions) => Promise<boolean>;\n}\n\nconst GlobalDialogContext = React.createContext<DialogContextType | undefined>(\n undefined\n);\n\nexport const DialogProvider = ({ children }: { children: React.ReactNode }) => {\n const [dialogs, setDialogs] = React.useState<\n (DialogOptions & { id: string })[]\n >([]);\n\n const close = React.useCallback((id: string) => {\n setDialogs((prev) => prev.filter((d) => d.id !== id));\n }, []);\n\n const closeAll = React.useCallback(() => {\n setDialogs([]);\n }, []);\n\n const open = React.useCallback(\n (options: DialogOptions) => {\n const id = options.id || `dialog-${Date.now()}-${Math.random()}`;\n setDialogs((prev) => [...prev, { ...options, id }]);\n return id;\n },\n []\n );\n\n const alert = React.useCallback(\n (options: AlertOptions) => {\n return new Promise<void>((resolve) => {\n const id = `alert-${Date.now()}`;\n open({\n ...options,\n id,\n variant: options.variant ?? \"alert\",\n buttons: [\n {\n label: options.confirmLabel ?? \"확인\",\n color: \"primary\",\n type: \"solid\",\n closeOnClick: true,\n onClick: async () => {\n await options.onConfirm?.();\n resolve();\n },\n },\n ],\n onClose: () => {\n resolve();\n close(id);\n },\n });\n });\n },\n [open, close]\n );\n\n const confirm = React.useCallback(\n (options: ConfirmOptions) => {\n return new Promise<boolean>((resolve) => {\n const id = `confirm-${Date.now()}`;\n open({\n ...options,\n id,\n variant: options.variant ?? \"confirm\",\n buttons: [\n {\n label: options.cancelLabel ?? \"취소\",\n color: \"neutral\",\n type: \"outline\",\n closeOnClick: true,\n onClick: async () => {\n await options.onCancel?.();\n resolve(false);\n },\n },\n {\n label: options.confirmLabel ?? \"확인\",\n color: \"primary\",\n type: \"solid\",\n closeOnClick: true,\n onClick: async () => {\n await options.onConfirm?.();\n resolve(true);\n },\n },\n ],\n onClose: () => {\n resolve(false);\n close(id);\n },\n });\n });\n },\n [open, close]\n );\n\n return (\n <GlobalDialogContext.Provider\n value={{ open, close, closeAll, alert, confirm }}\n >\n {children}\n {/* DialogRoot 내부에서 이미 createPortal을 사용하므로, 여기서는 그냥 렌더링하면 됨 */}\n {dialogs.map((dialog) => (\n <DialogRoot\n key={dialog.id}\n open={true}\n onClose={() => {\n dialog.onClose?.();\n close(dialog.id);\n }}\n variant={dialog.variant}\n align={dialog.align}\n closeOnOverlayClick={dialog.closeOnOverlayClick}\n closeOnEsc={dialog.closeOnEsc}\n withClose={dialog.withClose}\n // Data-driven props 전달\n title={dialog.title}\n description={dialog.description}\n icon={dialog.icon}\n actionItems={dialog.buttons}\n />\n ))}\n </GlobalDialogContext.Provider>\n );\n};\n\nexport function useDialog() {\n const context = React.useContext(GlobalDialogContext);\n if (!context) {\n throw new Error(\"useDialog must be used within a DialogProvider\");\n }\n return context;\n}\n","import React, { createContext, useContext, useSyncExternalStore } from 'react';\n\n\n// 1. 상태 타입 정의\ninterface BreakpointContextType {\n isMobile?: boolean;\n isTablet?: boolean;\n isDesktop?: boolean;\n isUnderTablet?: boolean;\n }\n \n // 2. Context 생성\n const BreakpointContext = createContext<BreakpointContextType | null>(null);\n \n // 3. Provider (스토리북 등에서 사용)\n export const BreakpointProvider = BreakpointContext.Provider;\n\nexport function useMediaQuery(query: string): boolean {\n // SSR 환경에서는 기본값으로 false를 반환합니다.\n const subscribe = (callback: () => void) => {\n const matchMedia = window.matchMedia(query);\n matchMedia.addEventListener(\"change\", callback);\n return () => matchMedia.removeEventListener(\"change\", callback);\n };\n\n const getSnapshot = () => {\n return window.matchMedia(query).matches;\n };\n\n const getServerSnapshot = () => {\n return false; // 서버 사이드에서는 항상 false (혹은 기본 레이아웃 기준)\n };\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * 프로젝트 브레이크포인트 전용 훅\n */\nexport function useBreakpoint() {\n // Context에 값이 들어있다면 (스토리북에서 강제했다면) 그 값을 우선 사용\n const contextValue = useContext(BreakpointContext);\n \n // 실제 윈도우 미디어 쿼리 구독\n const isMobileQuery = useMediaQuery(\"(min-width: 375px) and (max-width: 743px)\");\n const isTabletQuery = useMediaQuery(\"(min-width: 744px) and (max-width: 1279px)\");\n const isDesktopQuery = useMediaQuery(\"(min-width: 1280px)\");\n const isUnderTabletQuery = useMediaQuery(\"(max-width: 743px)\");\n \n // 수정 포인트: \n // contextValue가 있더라도 내부의 특정 값(예: isMobile)이 없을 수 있으므로 \n // 널 병합 연산자(??)를 사용해 실제 쿼리 결과값을 기본값으로 넣어줍니다.\n return {\n isMobile: contextValue?.isMobile ?? isMobileQuery,\n isTablet: contextValue?.isTablet ?? isTabletQuery,\n isDesktop: contextValue?.isDesktop ?? isDesktopQuery,\n isUnderTablet: contextValue?.isUnderTablet ?? isUnderTabletQuery,\n };\n }","import React from \"react\";\nimport \"./toggle.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type ToggleSize = \"medium\" | \"small\";\nexport type ToggleLabelPosition = \"start\" | \"end\";\n\nexport interface ToggleProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\" | \"onChange\" | \"type\"\n> {\n /** Toggle 크기 */\n size?: ToggleSize;\n /** Toggle 라벨 */\n label?: React.ReactNode;\n /** Toggle 라벨 위치 */\n labelPosition?: ToggleLabelPosition;\n /** Toggle 설명 텍스트 */\n description?: React.ReactNode;\n /** Toggle 상태 변경 핸들러 */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/** Toggle 컴포넌트는 사용자가 on/off 상태를 전환할 수 있는 스위치 컴포넌트다. */\nexport const Toggle = React.forwardRef<HTMLInputElement, ToggleProps>(\n (\n {\n size = \"medium\",\n label,\n labelPosition = \"end\",\n description,\n checked: checkedProp,\n defaultChecked = false,\n onChange,\n disabled,\n className = \"\",\n id,\n ...props\n },\n ref\n ) => {\n const inputRef = React.useRef<HTMLInputElement>(null);\n const combinedRef = React.useMemo(() => {\n if (typeof ref === \"function\") {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n ref(node);\n };\n } else if (ref) {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (ref) ref.current = node;\n };\n }\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n };\n }, [ref]);\n\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] =\n React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n\n onChange?.(e);\n };\n\n const generatedId = React.useId();\n const toggleId = id || generatedId;\n const descriptionId = description ? `${toggleId}-description` : undefined;\n\n const baseClasses = [\n \"toggle\",\n `toggle--${size}`,\n labelPosition === \"start\" && \"toggle--label-start\",\n disabled && \"toggle--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={baseClasses}>\n <div className=\"toggle__wrapper\">\n <input\n ref={combinedRef}\n type=\"checkbox\"\n id={toggleId}\n checked={checked}\n defaultChecked={defaultChecked}\n onChange={handleChange}\n disabled={disabled}\n aria-describedby={descriptionId}\n className=\"toggle__input\"\n role=\"switch\"\n aria-checked={checked}\n {...props}\n />\n <label htmlFor={toggleId} className=\"toggle__label-wrapper\">\n {labelPosition === \"start\" && label && (\n <Text\n variant={size === \"medium\" ? \"body-p2\" : \"body-p3\"}\n as=\"span\"\n >\n {label}\n </Text>\n )}\n <span className=\"toggle__switch\">\n <span className=\"toggle__thumb\" />\n </span>\n {labelPosition === \"end\" && label && (\n <Text\n variant={size === \"medium\" ? \"body-p2\" : \"body-p3\"}\n as=\"span\"\n >\n {label}\n </Text>\n )}\n </label>\n </div>\n {description && (\n <div id={descriptionId} className=\"toggle__description\">\n {description}\n </div>\n )}\n </div>\n );\n }\n);\n\nToggle.displayName = \"Toggle\";\n","import React from \"react\";\nimport \"./checkbox.css\";\nimport {\n RiCheckboxBlankLine,\n RiCheckboxFill,\n RiCheckboxIndeterminateFill,\n} from \"@remixicon/react\";\nimport { Text } from \"../Typography/Typography\";\n\nexport interface CheckboxProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"onChange\"> {\n /** Checkbox 라벨 */\n label?: React.ReactNode;\n /** label 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** Checkbox 설명 텍스트 */\n description?: React.ReactNode;\n /** Checkbox 값 (Checkbox.Group에서 사용) */\n value?: string;\n /** Checkbox 상태 변경 핸들러 */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n /** Indeterminate 상태 (부분 선택 상태) */\n indeterminate?: boolean;\n}\n\n/** Checkbox 컴포넌트는 사용자가 선택/해제할 수 있는 체크박스 입력 컴포넌트다. */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n label,\n labelProps,\n description,\n value,\n checked: checkedProp,\n defaultChecked = false,\n onChange,\n disabled,\n indeterminate = false,\n className = \"\",\n id,\n ...props\n },\n ref\n ) => {\n const inputRef = React.useRef<HTMLInputElement>(null);\n const combinedRef = React.useMemo(() => {\n if (typeof ref === \"function\") {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n ref(node);\n };\n } else if (ref) {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (ref) ref.current = node;\n };\n }\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n };\n }, [ref]);\n\n // Indeterminate 상태 설정\n React.useEffect(() => {\n if (inputRef.current) {\n inputRef.current.indeterminate = indeterminate;\n }\n }, [indeterminate]);\n\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] = React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n\n onChange?.(e);\n };\n\n const generatedId = React.useId();\n const checkboxId = id || generatedId;\n const descriptionId = description ? `${checkboxId}-description` : undefined;\n\n const baseClasses = [\n \"checkbox\",\n disabled && \"checkbox--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const resolvedLabelProps = labelProps ?? {};\n const labelClassName = [\"checkbox__label-text\", resolvedLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={baseClasses}>\n <div className=\"checkbox__wrapper\">\n <input\n ref={combinedRef}\n type=\"checkbox\"\n id={checkboxId}\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n value={value}\n aria-describedby={descriptionId || undefined}\n className=\"checkbox__input\"\n {...props}\n />\n <label htmlFor={checkboxId} className=\"checkbox__label-wrapper\">\n <span className=\"checkbox__icon-wrapper\" aria-hidden=\"true\">\n {indeterminate ? (\n <RiCheckboxIndeterminateFill className=\"checkbox__icon\" />\n ) : checked ? (\n <RiCheckboxFill className=\"checkbox__icon\" />\n ) : (\n <RiCheckboxBlankLine className=\"checkbox__icon\" />\n )}\n </span>\n {label && (\n <Text\n variant={resolvedLabelProps.variant ?? \"body-p2\"}\n as={resolvedLabelProps.as ?? \"span\"}\n {...resolvedLabelProps}\n className={labelClassName}\n >\n {label}\n </Text>\n )}\n </label>\n </div>\n {description && (\n <div id={descriptionId} className=\"checkbox__description\">\n {description}\n </div>\n )}\n </div>\n );\n }\n);\n\nCheckbox.displayName = \"Checkbox\";\n\n// Checkbox.Group 컴포넌트\nexport interface CheckboxItem {\n /** 체크박스 식별 값 */\n value: string;\n /** 체크박스 라벨 */\n label?: React.ReactNode;\n /** 체크박스 설명 텍스트 */\n description?: React.ReactNode;\n /** 개별 체크박스 비활성화 */\n disabled?: boolean;\n}\n\nexport interface CheckboxGroupProps {\n /** 그룹 라벨 */\n label?: React.ReactNode;\n /** 그룹 라벨 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 그룹 설명 */\n description?: React.ReactNode;\n /** 그룹 설명 스타일 오버라이드 (옵션) */\n descriptionProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 복수 선택 허용 여부. false면 단일 선택(라디오처럼 동작) */\n multiple?: boolean;\n /** 선택된 값들 (controlled). multiple=false일 때는 길이 0 또는 1 */\n value?: string[];\n /** 초기 선택된 값들 (uncontrolled) */\n defaultValue?: string[];\n /** 값 변경 핸들러 */\n onChange?: (values: string[]) => void;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** 체크박스 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly CheckboxItem[];\n /** 자식 Checkbox 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n /** 추가 CSS 클래스명 */\n className?: string;\n}\n\n/** CheckboxGroup은 여러 Checkbox를 그룹화하여 관리할 수 있는 컴포넌트다. */\nexport const CheckboxGroup = ({\n label,\n labelProps,\n description,\n descriptionProps,\n multiple = true,\n value: valueProp,\n defaultValue = [],\n onChange,\n disabled,\n items,\n children,\n className = \"\",\n}: CheckboxGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string[]>(defaultValue);\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const handleChange = (checkboxValue: string, checked: boolean) => {\n const newValue = multiple\n ? checked\n ? [...value, checkboxValue]\n : value.filter((v) => v !== checkboxValue)\n : checked\n ? [checkboxValue]\n : [];\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n\n onChange?.(newValue);\n };\n\n const groupId = React.useId();\n const descriptionId = description ? `${groupId}-description` : undefined;\n\n const resolvedGroupLabelProps = labelProps ?? {};\n const resolvedGroupDescriptionProps = descriptionProps ?? {};\n const groupLabelClassName = [\"checkbox-group__label\", resolvedGroupLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n const groupDescriptionClassName = [\n \"checkbox-group__description\",\n resolvedGroupDescriptionProps.className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const baseClasses = [\n \"checkbox-group\",\n disabled && \"checkbox-group--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedContent = items\n ? items.map((item) => (\n <Checkbox\n key={item.value}\n value={item.value}\n label={item.label}\n description={item.description}\n checked={value.includes(item.value)}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(item.value, e.target.checked);\n }}\n disabled={disabled || item.disabled}\n />\n ))\n : React.Children.map(children, (child) => {\n if (React.isValidElement<CheckboxProps>(child) && child.type === Checkbox) {\n const checkboxValue = child.props.value;\n if (checkboxValue === undefined) {\n console.warn(\"CheckboxGroup 내부의 Checkbox는 value prop이 필요합니다.\");\n return child;\n }\n\n const isChecked = value.includes(checkboxValue);\n\n return React.cloneElement(child, {\n checked: isChecked,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(checkboxValue, e.target.checked);\n child.props.onChange?.(e);\n },\n disabled: disabled || child.props.disabled,\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses}>\n {label && (\n <Text\n variant={resolvedGroupLabelProps.variant ?? \"subtitle-p2\"}\n as={resolvedGroupLabelProps.as ?? \"div\"}\n {...resolvedGroupLabelProps}\n className={groupLabelClassName}\n >\n {label}\n </Text>\n )}\n {description && (\n <Text\n id={descriptionId}\n variant={resolvedGroupDescriptionProps.variant ?? \"body-p3\"}\n as={resolvedGroupDescriptionProps.as ?? \"div\"}\n {...resolvedGroupDescriptionProps}\n className={groupDescriptionClassName}\n >\n {description}\n </Text>\n )}\n <div className=\"checkbox-group__content\">\n {renderedContent}\n </div>\n </div>\n );\n};\n\nCheckboxGroup.displayName = \"CheckboxGroup\";\n\n// Checkbox.Group을 Checkbox의 정적 프로퍼티로 추가\n(Checkbox as typeof Checkbox & { Group: typeof CheckboxGroup }).Group = CheckboxGroup;\n","import React from \"react\";\n\nexport interface UseCheckboxGroupOptions {\n /** 선택 가능한 값 목록 (CheckboxGroup 자식들의 value와 일치) */\n options: readonly string[];\n /** 초기 선택 값 (uncontrolled일 때) */\n defaultValue?: string[];\n /** 선택 값 (controlled일 때). 지정하면 onChange와 함께 사용 */\n value?: string[];\n /** 선택 값 변경 핸들러 (controlled일 때 필수) */\n onChange?: (values: string[]) => void;\n}\n\nexport interface UseCheckboxGroupResult {\n /** 현재 선택된 값들. CheckboxGroup의 value에 전달 */\n value: string[];\n /** 선택 변경 핸들러. CheckboxGroup의 onChange에 전달 */\n onChange: (values: string[]) => void;\n /** '전체 선택' 체크박스에 넘길 checked */\n selectAllChecked: boolean;\n /** '전체 선택' 체크박스에 넘길 indeterminate (일부만 선택된 경우) */\n selectAllIndeterminate: boolean;\n /** '전체 선택' 체크박스에 넘길 onChange */\n handleSelectAll: (e: React.ChangeEvent<HTMLInputElement>) => void;\n /** '전체 선택' Checkbox에 그대로 spread 가능한 props (checked, indeterminate, onChange) */\n selectAllProps: {\n checked: boolean;\n indeterminate: boolean;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n };\n}\n\n/**\n * CheckboxGroup + '전체 선택' 체크박스(indeterminate 포함) 상태를 관리하는 훅.\n * options와 동기화된 value/onChange와, 전체 선택용 checked/indeterminate/onChange를 반환한다.\n * 외부에서는 이 훅만 사용하면 된다.\n *\n * @example\n * const options = ['react', 'vue', 'angular'] as const;\n * const { value, onChange, selectAllProps } = useCheckboxGroup({ options });\n *\n * <Checkbox label=\"전체 선택\" {...selectAllProps} />\n * <CheckboxGroup value={value} onChange={onChange} ...>\n * {options.map(v => <Checkbox key={v} value={v} label={v} />)}\n * </CheckboxGroup>\n */\nexport function useCheckboxGroup(\n config: UseCheckboxGroupOptions\n): UseCheckboxGroupResult {\n const {\n options,\n defaultValue = [],\n value: valueProp,\n onChange: onChangeProp,\n } = config;\n\n const [internalValue, setInternalValue] = React.useState<string[]>(\n defaultValue\n );\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const onChange = React.useCallback(\n (newValue: string[]) => {\n if (!isControlled) setInternalValue(newValue);\n onChangeProp?.(newValue);\n },\n [isControlled, onChangeProp]\n );\n\n const allSelected = value.length === options.length;\n const someSelected = value.length > 0;\n const selectAllChecked = allSelected;\n const selectAllIndeterminate = someSelected && !allSelected;\n\n const handleSelectAll = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked ? [...options] : []);\n },\n [options, onChange]\n );\n\n return {\n value,\n onChange,\n selectAllChecked,\n selectAllIndeterminate,\n handleSelectAll,\n selectAllProps: {\n checked: selectAllChecked,\n indeterminate: selectAllIndeterminate,\n onChange: handleSelectAll,\n },\n };\n}\n","import React from \"react\";\nimport { ChevronDownIcon, XMarkIcon } from \"@heroicons/react/24/outline\";\nimport { TextField } from \"../../TextField/TextField\";\nimport {\n SelectMenuOverlay,\n type SelectMenuItem,\n type SelectMenuProps,\n} from \"../SelectMenu/SelectMenu\";\nimport \"./select-header.css\";\nimport { RiArrowUpLine, RiArrowUpSLine } from \"@remixicon/react\";\n\nexport type SelectHeaderType = \"outlined\" | \"underlined\";\nexport type SelectHeaderSize = \"medium\" | \"small\";\n\nexport interface SelectHeaderProps {\n /** SelectHeader 타입 */\n type?: SelectHeaderType;\n /**\n * SelectHeader 사이즈\n * - \"medium\": Web~Tab 권장 사이즈\n * - \"small\": Mo 권장 사이즈\n * - 지정하지 않으면 breakpoint에 따라 자동 결정됨.\n */\n size?: SelectHeaderSize;\n /** Title 텍스트 */\n title?: string;\n /** 필수 필드 표시 여부 */\n required?: boolean;\n /** 선택된 값 표시 (items 없을 때) / 선택된 값 controlled (items 있을 때) */\n value?: string | string[] | null;\n /** 플레이스홀더 텍스트 */\n placeholder?: string;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** 읽기 전용 (값은 표시되지만 변경 불가) */\n readOnly?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** Help text (도움말 텍스트) */\n description?: React.ReactNode;\n /** Help text 아이콘 (true면 기본 아이콘, 노드면 커스텀, false면 아이콘 없음) */\n accentIcon?: boolean | React.ReactNode;\n /** 클릭 핸들러 */\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** 값 클리어 핸들러 */\n onClear?: (event: React.MouseEvent<HTMLElement>) => void;\n /** 왼쪽 prefix 아이콘 (TextField prefixIcon으로 전달) */\n prefixIcon?: React.ReactNode;\n /** 커스텀 아이콘 */\n icon?: React.ReactNode;\n /** SelectMenu 항목들 (있으면 클릭 시 메뉴 열림) */\n items?: SelectMenuItem[];\n /** 초기 선택 값 (uncontrolled, items 있을 때) */\n defaultValue?: string | string[];\n /** 값 변경 핸들러 (items 있을 때) */\n onChange?: (value: string | string[] | undefined) => void;\n /** 다중 선택 허용 여부 (items 있을 때) */\n multiple?: boolean;\n /** 클리어 버튼 표시 여부 (미지정 시 hasValue && !disabled && (onChange|onClear) 기준 자동) */\n showClear?: boolean;\n /** 래퍼(Wrapper)에 적용할 클래스 이름 */\n wrapperClassName?: string;\n /** 래퍼(Wrapper)에 적용할 인라인 스타일 */\n wrapperStyle?: React.CSSProperties;\n /** 너비 설정 (예: \"100%\", \"300px\"). 설정 시 max-width 제한이 해제됨 */\n width?: string | number;\n /** 추가 CSS 클래스명 */\n className?: string;\n /** 요소 ID */\n id?: string;\n /** SelectMenu에 전달: 항목 텍스트 스타일 오버라이드 */\n menuItemTextProps?: SelectMenuProps[\"itemTextProps\"];\n /** SelectMenu에 전달: 선택된 항목 suffix 아이콘 */\n menuSuffixIcon?: SelectMenuProps[\"suffixIcon\"];\n /** SelectMenu에 전달: className */\n menuClassName?: string;\n /** SelectMenu에 전달: style */\n menuStyle?: React.CSSProperties;\n /** SelectMenu에 전달: 최대 표시 행 수 */\n menuMaxRows?: number;\n}\n\n/** SelectHeader 컴포넌트는 선택된 값을 표시하고 드롭다운을 여는 헤더 컴포넌트다. items를 주면 클릭 시 메뉴가 열린다. */\nexport const SelectHeader = ({\n type = \"outlined\",\n title,\n required = false,\n value: valueProp,\n placeholder = \"선택하세요\",\n disabled = false,\n readOnly = false,\n error = false,\n description,\n accentIcon = true,\n onClick,\n onClear,\n prefixIcon,\n icon,\n className = \"\",\n id,\n items,\n defaultValue,\n onChange,\n multiple,\n showClear,\n wrapperClassName = \"\",\n wrapperStyle,\n width,\n size,\n menuItemTextProps,\n menuSuffixIcon,\n menuClassName,\n menuStyle,\n menuMaxRows,\n}: SelectHeaderProps) => {\n const [internalValue, setInternalValue] = React.useState<\n string | string[] | undefined\n >(defaultValue);\n\n const isSelectMode = items != null && items.length > 0;\n const isControlled = valueProp !== undefined;\n\n let currentValueForSelect: string | string[] | undefined = undefined;\n if (isSelectMode) {\n currentValueForSelect = isControlled\n ? valueProp === null\n ? undefined\n : valueProp\n : internalValue;\n }\n\n const handleSelectChange = (next: string | string[] | undefined) => {\n if (!isControlled) setInternalValue(next);\n onChange?.(next);\n };\n\n const displayValue: string | null = (() => {\n if (isSelectMode) {\n const v = currentValueForSelect;\n if (v == null || (Array.isArray(v) && v.length === 0)) return null;\n if (Array.isArray(v)) {\n return v\n .map((value) => items!.find((i) => i.value === value)?.label ?? value)\n .filter(Boolean)\n .join(\", \");\n }\n const found = items!.find((i) => i.value === v)?.label;\n return found != null ? String(found) : v;\n }\n if (valueProp == null) return null;\n if (Array.isArray(valueProp)) return valueProp.join(\", \");\n return typeof valueProp === \"string\" ? valueProp : null;\n })();\n\n const hasValue = Boolean(displayValue);\n const showClearButton =\n hasValue &&\n !disabled &&\n !readOnly &&\n (showClear !== undefined\n ? showClear\n : (isSelectMode ? Boolean(onChange) : Boolean(onClear)));\n\n const handleClear = (e: React.MouseEvent<HTMLElement>) => {\n e.stopPropagation();\n if (isSelectMode) {\n handleSelectChange(undefined);\n } else {\n onClear?.(e as React.MouseEvent<HTMLButtonElement>);\n }\n };\n\n const suffixContent = (\n <span className=\"select-header__actions\">\n {showClearButton && (\n <span\n role=\"button\"\n tabIndex={0}\n className=\"select-header__clear\"\n onClick={handleClear}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleClear(e as unknown as React.MouseEvent<HTMLElement>);\n }\n }}\n aria-label=\"값 지우기\"\n >\n <XMarkIcon className=\"select-header__clear-icon\" />\n </span>\n )}\n <span className=\"select-header__icon\">\n {icon || <RiArrowUpSLine className=\"select-header__chevron\" />}\n </span>\n </span>\n );\n\n const textFieldNode = (\n <TextField\n title={title}\n required={required}\n description={description}\n accentIcon={accentIcon}\n error={error}\n disabled={disabled}\n size={size}\n width={width}\n readOnly\n value={displayValue ?? \"\"}\n placeholder={placeholder}\n prefixIcon={prefixIcon}\n suffixIcon={suffixContent}\n className={[\n \"select-header-field\",\n type === \"underlined\" && \"select-header-field--underlined\",\n wrapperClassName,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={wrapperStyle}\n id={id}\n onClick={onClick as React.MouseEventHandler<HTMLInputElement>}\n />\n );\n\n if (isSelectMode && !disabled && !readOnly) {\n return (\n <SelectMenuOverlay\n items={items!}\n value={currentValueForSelect}\n multiple={multiple}\n size={size}\n onChange={handleSelectChange}\n menuContainerStyle={{ width: \"100%\", marginTop: 8 }}\n itemTextProps={menuItemTextProps}\n suffixIcon={menuSuffixIcon}\n maxRows={menuMaxRows}\n className={menuClassName}\n style={menuStyle}\n >\n <div className=\"select-header-trigger\">{textFieldNode}</div>\n </SelectMenuOverlay>\n );\n }\n\n return textFieldNode;\n};\n\nSelectHeader.displayName = \"SelectHeader\";\n","import React, { useState, useId, forwardRef } from \"react\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport \"./text-field.css\";\nimport { Text } from \"../Typography/Typography\";\n\n// pc/mo는 디바이스 기반, medium/small은 스토리에서 쓰는 사이즈 네이밍\nexport type TextFieldSize = \"pc\" | \"mo\" | \"medium\" | \"small\";\ntype NormalizedTextFieldSize = \"pc\" | \"mo\";\ntype TextFieldState = \"default\" | \"error\";\nexport type TextFieldType = \"input\" | \"area\";\n\n/* ------------------------------------------------------------------ */\n/* 공통 Props */\n/* ------------------------------------------------------------------ */\ninterface TextFieldBaseProps {\n /** Title 텍스트 (있으면 표시) */\n title?: string;\n /** 필수 필드 표시 여부 */\n required?: boolean;\n /**\n * 크기\n * - \"pc\" / \"mo\": 디바이스 기반 네이밍\n * - \"medium\" / \"small\": 스토리/디자인 토큰 기반 네이밍 (pc ↔ medium, mo ↔ small)\n * 미지정 시 breakpoint 기준: tablet 미만 mo(small), 이상 pc(medium). 지정 시 오버라이드\n */\n size?: TextFieldSize;\n /** 에러 상태 */\n error?: boolean;\n /** Help text */\n description?: React.ReactNode;\n /** 컴포넌트 너비 (px 또는 CSS 문자열) */\n width?: number | string;\n /** 최대 문자 수 제한 */\n maxLength?: number;\n /**\n * 글자 수 카운트 표시 여부 (예: \"99/100\")\n * maxLength가 있을 때만 동작하며, 기본값은 true\n * @default true\n */\n showCount?: boolean;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** Help text 아이콘 (true면 기본 아이콘, 노드면 커스텀) */\n accentIcon?: boolean | React.ReactNode;\n\n // 공통 이벤트 핸들러 (Input/Textarea 호환을 위해 타입을 합침)\n onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onFocus?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onBlur?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onCopy?: React.ClipboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onCut?: React.ClipboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onPaste?: React.ClipboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onSelect?: React.ReactEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n}\n\n/* ------------------------------------------------------------------ */\n/* type=\"input\" 전용 Props */\n/* ------------------------------------------------------------------ */\ninterface TextFieldInputProps\n extends TextFieldBaseProps,\n Omit<\n React.InputHTMLAttributes<HTMLElement>,\n \"size\" | \"title\" | \"type\" | keyof TextFieldBaseProps\n > {\n /** 컴포넌트 타입: input (기본) */\n type?: \"input\";\n /** 왼쪽 아이콘 */\n prefixIcon?: React.ReactNode;\n /** 오른쪽 아이콘 */\n suffixIcon?: React.ReactNode;\n /** 오른쪽 단위 (타이머 등) */\n suffixUnit?: React.ReactNode;\n /** HTML input type (text, password, email 등) */\n inputType?: React.HTMLInputTypeAttribute;\n}\n\n/* ------------------------------------------------------------------ */\n/* type=\"area\" 전용 Props */\n/* ------------------------------------------------------------------ */\ninterface TextFieldAreaProps\n extends TextFieldBaseProps,\n Omit<\n React.TextareaHTMLAttributes<HTMLElement>,\n \"size\" | \"title\" | \"type\" | keyof TextFieldBaseProps\n > {\n /** 컴포넌트 타입: textarea */\n type: \"area\";\n /**\n * textarea 높이 (px 또는 CSS 문자열). 고정 높이로 적용되며 내용이 넘치면 스크롤 생성.\n * @default 120\n */\n height?: number | string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Discriminated Union */\n/* ------------------------------------------------------------------ */\nexport type TextFieldProps = TextFieldInputProps | TextFieldAreaProps;\n\n/* ------------------------------------------------------------------ */\n/* Type Guards */\n/* ------------------------------------------------------------------ */\nconst isAreaType = (\n props: TextFieldProps,\n): props is TextFieldAreaProps => props.type === \"area\";\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\n/** TextField 컴포넌트는 사용자로부터 텍스트 입력을 받는 폼 컴포넌트입니다. input과 textarea를 통합합니다. */\nexport const TextField = forwardRef<\n HTMLInputElement | HTMLTextAreaElement,\n TextFieldProps\n>((props, ref) => {\n const {\n type = \"input\",\n required = false,\n size,\n error = false,\n description,\n width,\n maxLength,\n showCount: showCountProp = true,\n title,\n accentIcon = true,\n className = \"\",\n style,\n id,\n value,\n defaultValue,\n readOnly,\n disabled,\n onChange,\n onFocus,\n onBlur,\n ...restProps\n } = props as TextFieldProps & { className?: string; style?: React.CSSProperties };\n\n const generatedId = useId();\n const fieldId = id || `textfield-${generatedId}`;\n const [focused, setFocused] = useState(false);\n\n // size 미지정 시: CSS media query로 해상도별 적용 (responsive). 지정 시: pc/mo\n const effectiveSize: NormalizedTextFieldSize | \"responsive\" =\n size === undefined\n ? \"responsive\"\n : size === \"medium\"\n ? \"pc\"\n : size === \"small\"\n ? \"mo\"\n : size;\n\n // maxLength 글자 수 표시용. value 없으면 uncontrolled → 내부에서만 사용\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? \"\");\n const currentValue = isControlled ? value : internalValue;\n\n const inputState: TextFieldState = error ? \"error\" : \"default\";\n const count = maxLength\n ? `${String(currentValue).length}/${maxLength}`\n : undefined;\n const showCount = showCountProp && Boolean(count);\n const [countValue, countTotal] =\n typeof count === \"string\" && count.includes(\"/\")\n ? count.split(\"/\")\n : [count, undefined];\n const iconNode =\n typeof accentIcon === \"boolean\" ? (\n accentIcon ? (\n <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n ) : null\n ) : (\n accentIcon\n );\n const helpVariant = error ? \"error\" : \"inform\";\n\n const isArea = type === \"area\";\n\n /* ---------- 이벤트 핸들러 ---------- */\n const handleFocus = (\n e: React.FocusEvent<HTMLInputElement> | React.FocusEvent<HTMLTextAreaElement>,\n ) => {\n setFocused(true);\n (onFocus as (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void)?.(e);\n };\n\n const handleBlur = (\n e: React.FocusEvent<HTMLInputElement> | React.FocusEvent<HTMLTextAreaElement>,\n ) => {\n setFocused(false);\n (onBlur as (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void)?.(e);\n };\n\n const handleChange = (\n e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>,\n ) => {\n let next = e.target.value;\n if (maxLength != null && next.length > maxLength) {\n next = next.slice(0, maxLength);\n e.target.value = next;\n }\n if (!isControlled) setInternalValue(next);\n (onChange as (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void)?.(e);\n };\n\n /* ---------- 클래스명 ---------- */\n const fieldClasses = [\n \"text-field__control\",\n `text-field__control--${effectiveSize}`,\n `text-field__control--${inputState}`,\n isArea && \"text-field__control--area\",\n focused && \"text-field__control--focused\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const shellClasses = [\n \"text-field-shell\",\n `text-field-shell--${inputState}`,\n `text-field-shell--${effectiveSize}`,\n readOnly && \"text-field-shell--readonly\",\n isArea && \"text-field-shell--area\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n /* ---------- textarea 스타일 ---------- */\n const getShellAreaStyle = (): React.CSSProperties | undefined => {\n if (!isArea) return undefined;\n const areaProps = props as TextFieldAreaProps;\n if (areaProps.height == null) return { height: \"120px\" };\n const h =\n typeof areaProps.height === \"number\"\n ? `${areaProps.height}px`\n : areaProps.height;\n return { height: h };\n };\n\n /* ---------- Input / Textarea 공통 제외 키 ---------- */\n const excludeKeys = new Set([\n \"type\", \"prefixIcon\", \"suffixIcon\", \"suffixUnit\",\n \"height\", \"width\", \"inputType\", \"showCount\",\n ]);\n const nativeProps = Object.fromEntries(\n Object.entries(restProps).filter(([k]) => !excludeKeys.has(k)),\n );\n\n /* ---------- Render ---------- */\n return (\n <div\n className={`text-field-wrapper text-field-wrapper--${effectiveSize} ${className}`.trim()}\n style={{\n ...style,\n ...(width != null && { width: typeof width === \"number\" ? `${width}px` : width }),\n }}\n >\n {title && (\n <label htmlFor={fieldId} className=\"flex items-center gap-1\">\n <Text variant=\"body-p3\">{title}</Text>\n {required && <span className=\"text-field__required\"> *</span>}\n </label>\n )}\n\n <div className={shellClasses} style={getShellAreaStyle()}>\n <div className={`text-field-container text-field-container--${effectiveSize}`}>\n {/* prefix icon — input only */}\n {!isArea && isInputType(props) && props.prefixIcon && (\n <span className=\"text-field__left-section\">{props.prefixIcon}</span>\n )}\n\n {isArea ? (\n <textarea\n {...(nativeProps as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n ref={ref as React.Ref<HTMLTextAreaElement>}\n id={fieldId}\n readOnly={readOnly}\n disabled={disabled}\n className={fieldClasses}\n style={undefined}\n value={currentValue}\n onChange={handleChange as React.ChangeEventHandler<HTMLTextAreaElement>}\n onFocus={handleFocus as React.FocusEventHandler<HTMLTextAreaElement>}\n onBlur={handleBlur as React.FocusEventHandler<HTMLTextAreaElement>}\n maxLength={maxLength}\n aria-invalid={error}\n aria-describedby={\n description || count ? `${fieldId}-description` : undefined\n }\n />\n ) : (\n <input\n {...(nativeProps as React.InputHTMLAttributes<HTMLInputElement>)}\n ref={ref as React.Ref<HTMLInputElement>}\n type={(props as TextFieldInputProps).inputType}\n id={fieldId}\n readOnly={readOnly}\n disabled={disabled}\n className={fieldClasses}\n value={currentValue}\n onChange={handleChange as React.ChangeEventHandler<HTMLInputElement>}\n onFocus={handleFocus as React.FocusEventHandler<HTMLInputElement>}\n onBlur={handleBlur as React.FocusEventHandler<HTMLInputElement>}\n maxLength={maxLength}\n aria-invalid={error}\n aria-describedby={\n description || count ? `${fieldId}-description` : undefined\n }\n />\n )}\n\n {/* suffix — input only */}\n {!isArea && isInputType(props) && (props.suffixIcon || props.suffixUnit) && (\n <div className=\"text-field__right-section\">\n {props.suffixIcon && <>{props.suffixIcon}</>}\n {props.suffixUnit && <>{props.suffixUnit}</>}\n </div>\n )}\n </div>\n </div>\n\n {/* Footer: help text + character count */}\n {(description || showCount) && (\n <div id={`${fieldId}-description`} className=\"text-field__footer\">\n <div\n className={`help-text-wrapper ${\n description && showCount\n ? \"help-text-wrapper--between\"\n : description\n ? \"help-text-wrapper--start\"\n : \"help-text-wrapper--end\"\n }`}\n >\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {iconNode && (\n <span className=\"help-text__icon\">{iconNode}</span>\n )}\n {typeof description === \"string\" ||\n typeof description === \"number\" ? (\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n ) : (\n <span className=\"help-text__content\">{description}</span>\n )}\n </span>\n )}\n {showCount && (\n <span\n className={`help-text__count help-text__count--${helpVariant}`}\n >\n {countValue && (\n <Text variant=\"body-p3\" className=\"help-text__count-number\">\n {countValue}\n </Text>\n )}\n {countTotal && (\n <Text variant=\"body-p3\" className=\"help-text__count-total\">\n /{countTotal}\n </Text>\n )}\n </span>\n )}\n </div>\n </div>\n )}\n </div>\n );\n});\n\nTextField.displayName = \"TextField\";\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\nfunction isInputType(\n props: TextFieldProps,\n): props is TextFieldInputProps {\n return !isAreaType(props);\n}\n","import * as React from \"react\";\nfunction ExclamationCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-8-5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5A.75.75 0 0 1 10 5Zm0 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ExclamationCircleIcon);\nexport default ForwardRef;","import React from \"react\";\nimport \"./select-menu.css\";\nimport { Text } from \"../../Typography/Typography\";\nimport { useBreakpoint } from \"../../../shared/hooks/useMediaQuery\";\nimport { RiCheckboxCircleFill } from \"@remixicon/react\";\n\nexport interface SelectMenuItem {\n value: string;\n label: React.ReactNode;\n disabled?: boolean;\n /** 항목 왼쪽 아이콘 */\n icon?: React.ReactNode;\n}\n\nexport interface SelectMenuProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 메뉴 항목들 */\n items: SelectMenuItem[];\n /**\n * 메뉴 사이즈\n * - \"medium\": Web~Tab 권장 사이즈\n * - \"small\": Mo 권장 사이즈\n * - 지정하지 않으면 breakpoint에 따라 자동 결정됨.\n */\n size?: \"medium\" | \"small\";\n /** 선택된 값 (controlled) */\n value?: string | string[];\n /** 초기 선택 값 (uncontrolled) */\n defaultValue?: string | string[];\n /** 값 변경 핸들러 */\n onChange?: (value: string | string[] | undefined) => void;\n /** 다중 선택 허용 여부 */\n multiple?: boolean;\n /** 항목 텍스트 스타일 오버라이드 (옵션) */\n itemTextProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 선택된 항목 suffix 아이콘 (기본 체크 아이콘, 함수로 커스터마이즈 가능) */\n suffixIcon?: React.ReactNode | ((item: SelectMenuItem) => React.ReactNode);\n /** 메뉴에 표시할 최대 행 수. 초과 시 스크롤 */\n maxRows?: number;\n}\n\n/** SelectMenu는 옵션 리스트를 표시하고 값을 선택하는 메뉴 컴포넌트다. */\nexport const SelectMenu = React.forwardRef<HTMLDivElement, SelectMenuProps>((props, ref) => {\n const {\n items,\n size,\n value,\n defaultValue,\n onChange,\n multiple,\n itemTextProps,\n suffixIcon,\n maxRows,\n className = \"\",\n style,\n id,\n ...rest\n } = props;\n\n // value prop이 존재하면 (undefined 포함) controlled 로 간주\n const isControlled = Object.prototype.hasOwnProperty.call(props, \"value\");\n const [internalValue, setInternalValue] = React.useState<string | string[] | undefined>(\n defaultValue\n );\n const currentValue = isControlled ? value : internalValue;\n const isMultiple = !!multiple;\n\n const { isUnderTablet } = useBreakpoint();\n // size prop이 우선이며, 없으면 breakpoint 기준 자동 결정\n const resolvedSize: \"medium\" | \"small\" =\n size ?? (isUnderTablet ? \"small\" : \"medium\");\n\n const generatedId = React.useId();\n const menuId = id || `select-menu-${generatedId}`;\n\n const commitValue = (next: string) => {\n let newValue: string | string[] | undefined;\n\n if (isMultiple) {\n const prevArray = Array.isArray(currentValue)\n ? currentValue\n : currentValue\n ? [currentValue]\n : [];\n newValue = prevArray.includes(next)\n ? prevArray.filter((v) => v !== next)\n : [...prevArray, next];\n } else {\n newValue = currentValue === next ? undefined : next;\n }\n\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n };\n\n const baseClasses = [\"select-menu\", `select-menu--${resolvedSize}`, className]\n .filter(Boolean)\n .join(\" \");\n\n const resolvedItemTextProps = itemTextProps ?? {};\n const defaultVariant = resolvedSize === \"medium\" ? \"body-p2\" : \"body-p3\";\n\n const menuRef = React.useRef<HTMLDivElement | null>(null);\n const [computedMaxHeight, setComputedMaxHeight] = React.useState<string | undefined>(undefined);\n\n React.useLayoutEffect(() => {\n const el = menuRef.current;\n if (!el || maxRows == null) return;\n const firstItem = el.querySelector<HTMLElement>(\".select-menu__item\");\n if (!firstItem) return;\n const itemHeight = firstItem.offsetHeight;\n const menuStyle = getComputedStyle(el);\n const gap = parseFloat(menuStyle.gap) || 0;\n const paddingY = parseFloat(menuStyle.paddingTop) + parseFloat(menuStyle.paddingBottom);\n setComputedMaxHeight(`${itemHeight * maxRows + gap * (maxRows - 1) + paddingY}px`);\n }, [maxRows, resolvedSize, items.length]);\n\n const mergedRef = (node: HTMLDivElement | null) => {\n menuRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n };\n\n return (\n <div\n ref={mergedRef}\n id={menuId}\n className={baseClasses}\n role=\"listbox\"\n style={{ ...style, ...(maxRows != null && { maxHeight: computedMaxHeight }) }}\n {...rest}\n >\n {items.map((item, idx) => {\n const isSelected = Array.isArray(currentValue)\n ? currentValue.includes(item.value)\n : currentValue === item.value;\n const optionId = `${menuId}-option-${item.value}`;\n\n const defaultSuffix = <RiCheckboxCircleFill className=\"select-menu__suffix-icon\" />;\n const suffixNode =\n typeof suffixIcon === \"function\" ? suffixIcon(item) : suffixIcon ?? defaultSuffix;\n\n return (\n <button\n key={item.value}\n id={optionId}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n disabled={item.disabled}\n className=\"select-menu__item\"\n onClick={() => !item.disabled && commitValue(item.value)}\n >\n <span className=\"select-menu__item-content\">\n {item.icon && <span className=\"select-menu__prefix\">{item.icon}</span>}\n <Text\n variant={resolvedItemTextProps.variant ?? defaultVariant}\n as={resolvedItemTextProps.as ?? \"span\"}\n {...resolvedItemTextProps}\n className={[\"select-menu__item-text\", resolvedItemTextProps.className]\n .filter(Boolean)\n .join(\" \")}\n >\n {item.label}\n </Text>\n </span>\n {isSelected && <span className=\"select-menu__suffix\">{suffixNode}</span>}\n </button>\n );\n })}\n </div>\n );\n});\n\nSelectMenu.displayName = \"SelectMenu\";\n\nexport interface SelectMenuOverlayProps\n extends Omit<SelectMenuProps, \"onClose\"> {\n /** 메뉴를 열기 위한 트리거 요소 (버튼/텍스트/아이콘 등) */\n children: React.ReactNode;\n /** 열림 상태 (controlled) */\n open?: boolean;\n /** 초기 열림 상태 (uncontrolled) */\n defaultOpen?: boolean;\n /** 열림 상태 변경 핸들러 */\n onOpenChange?: (open: boolean) => void;\n /** 메뉴 컨테이너 스타일 (positioning 커스터마이즈용) */\n menuContainerStyle?: React.CSSProperties;\n}\n\n/** SelectMenuOverlay는 트리거(children)를 감싸고 SelectMenu를 토글하는 래퍼 컴포넌트다. */\nexport const SelectMenuOverlay = ({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n menuContainerStyle,\n ...menuProps\n}: SelectMenuOverlayProps) => {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n const wrapperRef = React.useRef<HTMLDivElement | null>(null);\n\n const setOpen = (next: boolean) => {\n if (!isControlled) {\n setInternalOpen(next);\n }\n onOpenChange?.(next);\n };\n\n // 메뉴 밖을 클릭하면 닫기\n React.useEffect(() => {\n if (!open) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (!wrapperRef.current) return;\n if (!wrapperRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [open, setOpen]);\n\n const handleToggle = () => {\n setOpen(!open);\n };\n\n let triggerNode: React.ReactNode = children;\n\n if (React.isValidElement<React.HTMLAttributes<HTMLElement>>(children)) {\n const originalOnClick = children.props.onClick;\n\n triggerNode = React.cloneElement<React.HTMLAttributes<HTMLElement>>(children, {\n ...children.props,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n originalOnClick?.(event);\n handleToggle();\n },\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": open,\n });\n } else {\n triggerNode = (\n <button\n type=\"button\"\n onClick={handleToggle}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n {children}\n </button>\n );\n }\n\n const handleChange = (value: string | string[] | undefined) => {\n menuProps.onChange?.(value);\n // 싱글 셀렉트: 항목 선택 시 메뉴 닫기\n if (!menuProps.multiple) {\n setOpen(false);\n }\n };\n\n return (\n <div\n ref={wrapperRef}\n className=\"select-menu-overlay\"\n >\n {triggerNode}\n {open && (\n <div\n style={{\n position: \"absolute\",\n top: \"100%\",\n left: 0,\n marginTop: 4,\n zIndex: 1000,\n ...menuContainerStyle,\n }}\n >\n <SelectMenu\n {...menuProps}\n onChange={handleChange}\n style={{\n ...menuProps.style,\n width: \"100%\",\n minWidth: 0,\n }}\n />\n </div>\n )}\n </div>\n );\n};\n\nSelectMenuOverlay.displayName = \"SelectMenuOverlay\";\n\n","import * as React from \"react\";\nfunction CheckCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(CheckCircleIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ExclamationTriangleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75Zm0 8.25a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ExclamationTriangleIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction InformationCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 0 1 .67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 1 1-.671-1.34l.041-.022ZM12 9a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(InformationCircleIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction XCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm-1.72 6.97a.75.75 0 1 0-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 1 0 1.06 1.06L12 13.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L13.06 12l1.72-1.72a.75.75 0 1 0-1.06-1.06L12 10.94l-1.72-1.72Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(XCircleIcon);\nexport default ForwardRef;","import React from \"react\";\nimport {\n SelectHeader,\n type SelectHeaderProps,\n type SelectHeaderType,\n} from \"../SelectHeader\";\nimport type { SelectMenuItem, SelectMenuProps } from \"../SelectMenu/SelectMenu\";\nimport { CheckCircleIcon } from \"@heroicons/react/24/solid\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport { Text } from \"../../Typography/Typography\";\nimport \"../SelectHeader/select-header.css\";\nimport \"../SelectMenu/select-menu.css\";\nimport \"./select-box.css\";\n\nexport type SelectBoxSize = \"small\" | \"medium\";\n\n/** 파트별 className 오버라이드 */\nexport type SelectBoxClassNames = {\n root?: string;\n header?: string;\n menu?: string;\n};\n\n/** 파트별 style 오버라이드 */\nexport type SelectBoxStyles = {\n root?: React.CSSProperties;\n header?: React.CSSProperties;\n menu?: React.CSSProperties;\n};\n\n/** SelectBox 전용 props (label는 SelectHeader title에 매핑) */\ntype SelectBoxSpecificProps = {\n /** SelectBox 사이즈 */\n size?: SelectBoxSize;\n /** 비활성화 */\n disabled?: boolean;\n /** 읽기 전용 (값은 표시되지만 변경 불가) */\n readOnly?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** 성공 상태 */\n success?: boolean;\n /** 로딩 상태 */\n loading?: boolean;\n /** 라벨 텍스트 (SelectHeader title에 매핑) */\n label?: string;\n /** 하단 설명 텍스트 */\n description?: string;\n /**\n * 왼쪽 prefix 아이콘. 미지정 시 단일 선택인 경우 선택된 항목의 icon을 자동 감지.\n * false로 설정하면 자동 감지를 비활성화.\n */\n prefixIcon?: React.ReactNode | false;\n /** root에 적용할 className */\n className?: string;\n /** root에 적용할 인라인 스타일 */\n style?: React.CSSProperties;\n /**\n * 파트별 className 오버라이드\n * @example classNames={{ root: \"w-12\", header: \"border-red-500\", menu: \"bg-gray-50\" }}\n */\n classNames?: SelectBoxClassNames;\n /**\n * 파트별 인라인 스타일 오버라이드\n * @example styles={{ header: { borderColor: \"red\" }, menu: { maxHeight: 200 } }}\n */\n styles?: SelectBoxStyles;\n /** 너비 설정 (예: \"100%\", 300). 미지정 시 CSS 기본 360px */\n width?: string | number;\n};\n\n/** SelectHeader에서 SelectBox가 오버라이드하는 props 제외 */\ntype SelectHeaderPassThrough = Omit<\n SelectHeaderProps,\n | \"type\"\n | \"size\"\n | \"title\"\n | \"disabled\"\n | \"readOnly\"\n | \"error\"\n | \"description\"\n | \"accentIcon\"\n | \"icon\"\n | \"prefixIcon\"\n | \"wrapperClassName\"\n | \"menuClassName\"\n | \"menuStyle\"\n | \"style\"\n | \"className\"\n | \"width\"\n> & {\n /** SelectHeader 타입 (outlined | underlined) */\n headerType?: SelectHeaderType;\n};\n\n/** SelectMenu props (SelectHeader를 통해 SelectMenu로 전달) */\ntype SelectMenuPassThrough = {\n /** 메뉴 항목 텍스트 스타일 오버라이드 */\n itemTextProps?: SelectMenuProps[\"itemTextProps\"];\n /** 선택된 항목의 suffix 아이콘 (기본: 체크 아이콘). false면 숨김 */\n suffixIcon?: SelectMenuProps[\"suffixIcon\"];\n /** 메뉴에 표시할 최대 행 수. 초과 시 스크롤 */\n maxRows?: number;\n};\n\nexport type SelectBoxProps = SelectBoxSpecificProps &\n SelectHeaderPassThrough &\n SelectMenuPassThrough;\n\nconst LoadingSpinner = () => (\n <span className=\"select-box__spinner\" aria-hidden=\"true\">\n <svg\n className=\"select-box__spinner-svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n className=\"select-box__spinner-circle\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"32\"\n strokeDashoffset=\"32\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 40;40 40;0 40\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-40;-80\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n </span>\n);\n\n/** SelectBox는 SelectHeader와 SelectMenu를 하나로 통합한 컴포넌트로, 미리 정의된 목록에서 항목을 선택하도록 돕습니다. */\nexport const SelectBox = ({\n size = \"medium\",\n disabled = false,\n readOnly = false,\n error = false,\n success = false,\n loading = false,\n label,\n required = false,\n placeholder = \"선택하세요\",\n items,\n value,\n defaultValue,\n onChange,\n multiple,\n description,\n prefixIcon,\n className,\n style,\n classNames,\n styles,\n width,\n // SelectHeader pass-through\n headerType = \"outlined\",\n onClear,\n showClear,\n wrapperStyle,\n onClick,\n id,\n itemTextProps,\n suffixIcon,\n maxRows = 3,\n ...restHeaderProps\n}: SelectBoxProps) => {\n const isDisabled = disabled || loading;\n const isInteractive = !isDisabled && !readOnly;\n\n const showLabel = Boolean(label);\n\n const resolvedWidth =\n width !== undefined\n ? typeof width === \"number\"\n ? `${width}px`\n : width\n : undefined;\n\n const iconNode = loading ? <LoadingSpinner /> : undefined;\n\n const rootStyle: React.CSSProperties | undefined = (() => {\n const merged = { ...style, ...styles?.root };\n if (resolvedWidth != null) {\n merged.width = resolvedWidth;\n }\n return Object.keys(merged).length > 0 ? merged : undefined;\n })();\n\n const baseClasses = [\n \"select-box\",\n `select-box--${size}`,\n disabled && \"select-box--disabled\",\n readOnly && \"select-box--readonly\",\n error && \"select-box--error\",\n success && \"select-box--success\",\n className,\n classNames?.root,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // 선택된 아이템의 prefix 아이콘 자동 감지 (단일 선택, controlled 시)\n const resolvedPrefixIcon = (() => {\n if (prefixIcon === false) return undefined;\n if (prefixIcon !== undefined) return prefixIcon;\n if (!items || multiple) return undefined;\n const selectedValue = value ?? defaultValue;\n if (!selectedValue || Array.isArray(selectedValue)) return undefined;\n return items.find((i) => i.value === selectedValue)?.icon;\n })();\n\n // description용 아이콘 결정\n const descriptionIcon = success\n ? <CheckCircleIcon className=\"help-text__icon-svg\" />\n : error\n ? <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n : null;\n\n const helpVariant = error ? \"error\" : \"inform\";\n\n return (\n <div className={baseClasses} style={rootStyle}>\n <SelectHeader\n type={headerType}\n size={size}\n title={showLabel ? label : undefined}\n required={required}\n placeholder={placeholder}\n items={items}\n value={value}\n defaultValue={defaultValue}\n onChange={isInteractive ? onChange : undefined}\n multiple={multiple}\n disabled={isDisabled}\n readOnly={readOnly}\n error={error}\n prefixIcon={resolvedPrefixIcon}\n icon={iconNode}\n onClear={isInteractive ? onClear : undefined}\n showClear={isInteractive ? showClear : false}\n wrapperStyle={\n styles?.header || wrapperStyle\n ? { ...wrapperStyle, ...styles?.header }\n : undefined\n }\n wrapperClassName={[\"select-box__header-wrapper\", classNames?.header].filter(Boolean).join(\" \")}\n menuClassName={classNames?.menu}\n menuStyle={styles?.menu}\n onClick={onClick}\n id={id}\n {...restHeaderProps}\n menuItemTextProps={itemTextProps}\n menuSuffixIcon={suffixIcon}\n menuMaxRows={maxRows}\n width=\"100%\"\n />\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {descriptionIcon && (\n <span className=\"help-text__icon\">{descriptionIcon}</span>\n )}\n {typeof description === \"string\" || typeof description === \"number\" ? (\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n ) : (\n <span className=\"help-text__content\">{description}</span>\n )}\n </span>\n )}\n </div>\n );\n};\n\nSelectBox.displayName = \"SelectBox\";\n","import React from \"react\";\n\nimport \"./pagination.css\";\nimport { Text } from \"../Typography/Typography\";\nimport {\n RiArrowLeftSLine,\n RiArrowRightSLine,\n RiMoreLine,\n} from \"@remixicon/react\";\n\nexport type PaginationType = \"basic\" | \"compact\";\n\ntype PaginationItemType =\n | \"page\"\n | \"ellipsis\"\n | \"prev\"\n | \"next\"\n | \"first\"\n | \"last\";\n\ninterface PaginationItem {\n type: PaginationItemType;\n page?: number;\n key: string;\n disabled?: boolean;\n selected?: boolean;\n}\n\nexport interface PaginationProps {\n /** 총 페이지 수 (1 이상) */\n totalPages: number;\n /** 현재 페이지 (1부터 시작) */\n currentPage: number;\n /** 페이지 변경 핸들러 */\n onChange?: (page: number) => void;\n /** Pagination 타입 (기본형 / 축약형) */\n type?: PaginationType;\n /** 추가 CSS 클래스명 */\n className?: string;\n}\n\nconst range = (start: number, end: number): number[] => {\n const length = end - start + 1;\n return Array.from({ length }, (_, idx) => start + idx);\n};\n\nconst createPaginationItems = ({\n totalPages,\n currentPage,\n siblingCount,\n showEdgeButtons,\n showPrevNext,\n}: {\n totalPages: number;\n currentPage: number;\n siblingCount: number;\n showEdgeButtons: boolean;\n showPrevNext: boolean;\n}): PaginationItem[] => {\n if (totalPages <= 0) return [];\n\n const safeCurrent = Math.min(Math.max(currentPage, 1), totalPages);\n const items: PaginationItem[] = [];\n\n const add = (item: PaginationItem) => items.push(item);\n\n const isFirstPage = safeCurrent === 1;\n const isLastPage = safeCurrent === totalPages;\n\n if (showEdgeButtons) {\n add({\n type: \"first\",\n page: 1,\n key: \"first\",\n disabled: isFirstPage,\n });\n }\n\n if (showPrevNext) {\n add({\n type: \"prev\",\n page: Math.max(1, safeCurrent - 1),\n key: \"prev\",\n disabled: isFirstPage,\n });\n }\n\n // 페이지 번호들 + ... 계산 (MUI Pagination 로직과 유사)\n const totalPageNumbers = siblingCount * 2 + 5; // 1, last, current, 양옆, 그리고 두 개의 ellipsis 자리\n\n if (totalPages <= totalPageNumbers) {\n range(1, totalPages).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-${page}`,\n selected: page === safeCurrent,\n })\n );\n } else {\n const leftSiblingIndex = Math.max(safeCurrent - siblingCount, 2);\n const rightSiblingIndex = Math.min(\n safeCurrent + siblingCount,\n totalPages - 1\n );\n\n const shouldShowLeftEllipsis = leftSiblingIndex > 2;\n const shouldShowRightEllipsis = rightSiblingIndex < totalPages - 1;\n\n // 항상 첫 페이지\n add({\n type: \"page\",\n page: 1,\n key: \"page-1\",\n selected: safeCurrent === 1,\n });\n\n if (!shouldShowLeftEllipsis && shouldShowRightEllipsis) {\n // 왼쪽 ellipsis 없고 오른쪽만 필요\n const leftItemCount = 3 + 2 * siblingCount;\n const leftRange = range(2, leftItemCount);\n\n leftRange.forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n\n add({ type: \"ellipsis\", key: `ellipsis-right-${rightSiblingIndex}` });\n add({\n type: \"page\",\n page: totalPages,\n key: `page-${totalPages}`,\n selected: safeCurrent === totalPages,\n });\n } else if (shouldShowLeftEllipsis && !shouldShowRightEllipsis) {\n // 왼쪽만 필요하고 오른쪽 ellipsis 없음\n add({ type: \"ellipsis\", key: `ellipsis-left-${leftSiblingIndex}` });\n\n const rightItemCount = 3 + 2 * siblingCount;\n const rightRange = range(totalPages - rightItemCount + 1, totalPages - 1);\n\n rightRange.forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n\n add({\n type: \"page\",\n page: totalPages,\n key: `page-${totalPages}`,\n selected: safeCurrent === totalPages,\n });\n } else if (shouldShowLeftEllipsis && shouldShowRightEllipsis) {\n // 양쪽 모두 필요할 때: 1 ... [left~right] ... last\n add({ type: \"ellipsis\", key: `ellipsis-left-${leftSiblingIndex}` });\n\n range(leftSiblingIndex, rightSiblingIndex).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n\n add({ type: \"ellipsis\", key: `ellipsis-right-${rightSiblingIndex}` });\n add({\n type: \"page\",\n page: totalPages,\n key: `page-${totalPages}`,\n selected: safeCurrent === totalPages,\n });\n } else {\n // ellipsis 둘 다 필요 없을 때 (fallback)\n range(1, totalPages).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n }\n }\n\n if (showPrevNext) {\n add({\n type: \"next\",\n page: Math.min(totalPages, safeCurrent + 1),\n key: \"next\",\n disabled: isLastPage,\n });\n }\n\n if (showEdgeButtons) {\n add({\n type: \"last\",\n page: totalPages,\n key: \"last\",\n disabled: isLastPage,\n });\n }\n\n return items;\n};\n\nconst createBasicPaginationItems = ({\n totalPages,\n currentPage,\n}: {\n totalPages: number;\n currentPage: number;\n}): PaginationItem[] => {\n if (totalPages <= 0) return [];\n\n const safeCurrent = Math.min(Math.max(currentPage, 1), totalPages);\n const items: PaginationItem[] = [];\n\n const add = (item: PaginationItem) => items.push(item);\n\n const isFirstPage = safeCurrent === 1;\n const isLastPage = safeCurrent === totalPages;\n\n // 기본형: first/last, ellipsis 없이 이전/다음 + 모든 페이지 번호\n add({\n type: \"prev\",\n page: Math.max(1, safeCurrent - 1),\n key: \"prev\",\n disabled: isFirstPage,\n });\n\n range(1, totalPages).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-${page}`,\n selected: page === safeCurrent,\n })\n );\n\n add({\n type: \"next\",\n page: Math.min(totalPages, safeCurrent + 1),\n key: \"next\",\n disabled: isLastPage,\n });\n\n return items;\n};\n\n/** Pagination 컴포넌트는 리스트/테이블 등에서 여러 페이지를 탐색할 때 사용하는 페이지네이션 컴포넌트다. */\nexport const Pagination = ({\n totalPages,\n currentPage,\n onChange,\n type = \"basic\",\n className = \"\",\n ...rest\n}: PaginationProps) => {\n // 디자인은 데스크탑 기준 단일 사이즈만 사용\n const size = \"web-tab\" as const;\n\n const variant: PaginationType = type ?? \"basic\";\n\n const items = React.useMemo(() => {\n if (variant === \"basic\") {\n return createBasicPaginationItems({\n totalPages,\n currentPage,\n });\n }\n\n // compact: ellipsis + first/last 버튼 포함\n return createPaginationItems({\n totalPages,\n currentPage,\n siblingCount: 1,\n showEdgeButtons: false,\n showPrevNext: true,\n });\n }, [totalPages, currentPage, variant]);\n\n const handleItemClick = React.useCallback(\n (item: PaginationItem) => {\n if (item.disabled) return;\n if (!item.page) return;\n onChange?.(item.page);\n },\n [onChange]\n );\n\n const handleEllipsisClick = React.useCallback(\n (key: string) => {\n if (key === \"ellipsis-left\") {\n // 왼쪽 ellipsis 클릭 → 첫 페이지로 이동\n onChange?.(1);\n } else if (key === \"ellipsis-right\") {\n // 오른쪽 ellipsis 클릭 → 마지막 페이지로 이동\n onChange?.(totalPages);\n }\n },\n [onChange, totalPages]\n );\n\n const rootClasses = [\"pagination\", `pagination--${size}`, className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <nav className={rootClasses} aria-label=\"페이지네이션\" {...rest}>\n <ul className=\"pagination__list\">\n {items.map((item) => {\n const isPage = item.type === \"page\";\n const isSelected = Boolean(item.selected);\n const isDisabled = Boolean(item.disabled);\n\n const itemClasses = [\n \"pagination__button\",\n `pagination__button--${item.type}`,\n isPage && \"pagination__button--page\",\n isSelected && \"pagination__button--selected\",\n isDisabled && \"pagination__button--disabled\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const labelText =\n item.type === \"page\"\n ? String(item.page)\n : item.type === \"prev\"\n ? \"이전 페이지\"\n : item.type === \"next\"\n ? \"다음 페이지\"\n : item.type === \"first\"\n ? \"첫 페이지\"\n : item.type === \"last\"\n ? \"마지막 페이지\"\n : \"\";\n\n const ariaLabel =\n item.type === \"page\" ? `${item.page}페이지` : labelText;\n\n if (item.type === \"ellipsis\") {\n return (\n <li\n key={item.key}\n className=\"pagination__item pagination__item--ellipsis\"\n >\n <button\n type=\"button\"\n className=\"pagination__button pagination__button--ellipsis\"\n onClick={() => handleEllipsisClick(item.key)}\n aria-label={\n item.key === \"ellipsis-left\"\n ? \"첫 페이지로 이동\"\n : \"마지막 페이지로 이동\"\n }\n >\n <RiMoreLine />\n </button>\n </li>\n );\n }\n\n return (\n <li key={item.key} className=\"pagination__item\">\n <button\n type=\"button\"\n className={itemClasses}\n onClick={() => handleItemClick(item)}\n disabled={isDisabled}\n aria-label={ariaLabel}\n aria-current={isPage && isSelected ? \"page\" : undefined}\n >\n {item.type === \"prev\" && (\n <RiArrowLeftSLine className=\"pagination__icon\" />\n )}\n {item.type === \"next\" && (\n <RiArrowRightSLine className=\"pagination__icon\" />\n )}\n {item.type === \"first\" && (\n <>\n <RiArrowLeftSLine className=\"pagination__icon pagination__icon--double\" />\n <RiArrowLeftSLine className=\"pagination__icon pagination__icon--double\" />\n </>\n )}\n {item.type === \"last\" && (\n <>\n <RiArrowRightSLine className=\"pagination__icon pagination__icon--double\" />\n <RiArrowRightSLine className=\"pagination__icon pagination__icon--double\" />\n </>\n )}\n {item.type === \"page\" && (\n <Text\n as=\"span\"\n variant={size === \"web-tab\" ? \"body-p2\" : \"body-p3\"}\n >\n {item.page}\n </Text>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n};\n\nPagination.displayName = \"Pagination\";\n","import React from \"react\";\nimport \"./radio-button.css\";\nimport { RiCircleLine, RiRadioButtonLine } from \"@remixicon/react\";\nimport { Text } from \"../Typography/Typography\";\n\nexport interface RadioButtonProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"type\" | \"size\" | \"onChange\"\n > {\n /** 라디오 라벨 */\n label?: React.ReactNode;\n /** label 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 라디오 설명 텍스트 */\n description?: React.ReactNode;\n /** 라디오 값 (RadioButton.Group에서 사용) */\n value?: string;\n /** 라디오 상태 변경 핸들러 */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/** RadioButton은 단일 선택(라디오) 입력 컴포넌트다. */\nexport const RadioButton = React.forwardRef<HTMLInputElement, RadioButtonProps>(\n (\n {\n label,\n labelProps,\n description,\n value,\n checked: checkedProp,\n defaultChecked = false,\n onChange,\n disabled,\n className = \"\",\n id,\n name,\n onClick,\n ...props\n },\n ref\n ) => {\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] = React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n\n onChange?.(e);\n };\n\n const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {\n if (checked && !disabled) {\n e.preventDefault();\n if (!isControlled) setInternalChecked(false);\n const syntheticEvent = {\n ...e,\n target: { ...e.target, checked: false },\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange?.(syntheticEvent);\n }\n onClick?.(e);\n };\n\n const generatedId = React.useId();\n const radioId = id || generatedId;\n const descriptionId = description ? `${radioId}-description` : undefined;\n\n const [isHovered, setIsHovered] = React.useState(false);\n\n const baseClasses = [\"radio-button\", disabled && \"radio-button--disabled\", className]\n .filter(Boolean)\n .join(\" \");\n\n const labelWrapperClasses = [\n \"radio-button__label-wrapper\",\n isHovered && !checked && !disabled && \"radio-button__label-wrapper--hovered\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const resolvedLabelProps = labelProps ?? {};\n const labelClassName = [\"radio-button__label-text\", resolvedLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={baseClasses} data-checked={checked}>\n <div className=\"radio-button__wrapper\">\n <input\n ref={ref}\n type=\"radio\"\n id={radioId}\n name={name}\n checked={checked}\n onChange={handleChange}\n onClick={handleClick}\n disabled={disabled}\n value={value}\n aria-describedby={descriptionId || undefined}\n className=\"radio-button__input\"\n {...props}\n />\n <label\n htmlFor={radioId}\n className={labelWrapperClasses}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <span className=\"radio-button__icon-wrapper\" aria-hidden=\"true\">\n {checked ? (\n <RiRadioButtonLine className=\"radio-button__icon\" />\n ) : (\n <RiCircleLine className=\"radio-button__icon\" />\n )}\n </span>\n {label && (\n <Text\n variant={resolvedLabelProps.variant ?? \"body-p2\"}\n as={resolvedLabelProps.as ?? \"span\"}\n {...resolvedLabelProps}\n className={labelClassName}\n >\n {label}\n </Text>\n )}\n </label>\n </div>\n {description && (\n <div id={descriptionId} className=\"radio-button__description\">\n {description}\n </div>\n )}\n </div>\n );\n }\n);\n\nRadioButton.displayName = \"RadioButton\";\n\n// RadioButton.Group\nexport interface RadioButtonItem {\n /** 라디오 식별 값 */\n value: string;\n /** 라디오 라벨 */\n label?: React.ReactNode;\n /** 라디오 설명 텍스트 */\n description?: React.ReactNode;\n /** 개별 라디오 비활성화 */\n disabled?: boolean;\n}\n\nexport interface RadioButtonGroupProps {\n /** 그룹 라벨 */\n label?: React.ReactNode;\n /** 그룹 라벨 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 그룹 설명 */\n description?: React.ReactNode;\n /** 그룹 설명 스타일 오버라이드 (옵션) */\n descriptionProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 선택된 값 (controlled) */\n value?: string;\n /** 초기 선택 값 (uncontrolled) */\n defaultValue?: string;\n /** 값 변경 핸들러 (선택 해제 시 value는 undefined) */\n onChange?: (value: string | undefined) => void;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** name (미지정 시 내부 생성) */\n name?: string;\n /** 라디오 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly RadioButtonItem[];\n /** 자식 RadioButton 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n /** 추가 CSS 클래스명 */\n className?: string;\n}\n\n/** RadioButtonGroup은 여러 RadioButton을 그룹화하여 단일 선택을 관리한다. */\nexport const RadioButtonGroup = ({\n label,\n labelProps,\n description,\n descriptionProps,\n value: valueProp,\n defaultValue,\n onChange,\n disabled,\n name,\n items,\n children,\n className = \"\",\n}: RadioButtonGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string | undefined>(defaultValue);\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const groupId = React.useId();\n const groupName = name || `radio-group-${groupId}`;\n const descriptionId = description ? `${groupId}-description` : undefined;\n const resolvedGroupLabelProps = labelProps ?? {};\n const resolvedGroupDescriptionProps = descriptionProps ?? {};\n\n const groupLabelClassName = [\"radio-button-group__label\", resolvedGroupLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n const groupDescriptionClassName = [\n \"radio-button-group__description\",\n resolvedGroupDescriptionProps.className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const baseClasses = [\n \"radio-button-group\",\n disabled && \"radio-button-group--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleRadioChange = (radioValue: string) =>\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.checked) {\n if (!isControlled) setInternalValue(radioValue);\n onChange?.(radioValue);\n } else {\n if (!isControlled) setInternalValue(undefined);\n onChange?.(undefined);\n }\n };\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedContent = items\n ? items.map((item) => (\n <RadioButton\n key={item.value}\n value={item.value}\n label={item.label}\n description={item.description}\n name={groupName}\n checked={value === item.value}\n onChange={handleRadioChange(item.value)}\n disabled={disabled || item.disabled}\n />\n ))\n : React.Children.map(children, (child) => {\n if (React.isValidElement<RadioButtonProps>(child) && child.type === RadioButton) {\n const radioValue = child.props.value;\n if (radioValue === undefined) {\n console.warn(\"RadioButtonGroup 내부의 RadioButton은 value prop이 필요합니다.\");\n return child;\n }\n\n const isChecked = value === radioValue;\n\n return React.cloneElement(child, {\n name: groupName,\n checked: isChecked,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n handleRadioChange(radioValue)(e);\n child.props.onChange?.(e);\n },\n disabled: disabled || child.props.disabled,\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses} role=\"radiogroup\" aria-describedby={descriptionId || undefined}>\n {label && (\n <Text\n variant={resolvedGroupLabelProps.variant ?? \"subtitle-p2\"}\n as={resolvedGroupLabelProps.as ?? \"div\"}\n {...resolvedGroupLabelProps}\n className={groupLabelClassName}\n >\n {label}\n </Text>\n )}\n {description && (\n <Text\n id={descriptionId}\n variant={resolvedGroupDescriptionProps.variant ?? \"body-p3\"}\n as={resolvedGroupDescriptionProps.as ?? \"div\"}\n {...resolvedGroupDescriptionProps}\n className={groupDescriptionClassName}\n >\n {description}\n </Text>\n )}\n <div className=\"radio-button-group__content\">{renderedContent}</div>\n </div>\n );\n};\n\nRadioButtonGroup.displayName = \"RadioButtonGroup\";\n\n// RadioButton.Group을 RadioButton의 정적 프로퍼티로 추가\n(RadioButton as typeof RadioButton & { Group: typeof RadioButtonGroup }).Group = RadioButtonGroup;\n\n","import React from \"react\";\nimport \"./tag.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type TagType = \"solid\" | \"outline\" | \"weak\";\nexport type TagSize = \"medium\" | \"small\";\nexport type TagState = \"enabled\" | \"error\" | \"progressing\" | \"warning\" | \"success\";\n\nexport interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** 태그 타입 (solid, outline, weak) */\n type?: TagType;\n /** 태그 크기 */\n size?: TagSize;\n /** 태그 상태 (type이 weak일 때만 사용 가능) */\n state?: TagState;\n /** 태그 라벨 */\n label: React.ReactNode;\n /** Prefix 아이콘 */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n}\n\n/** Tag 컴포넌트는 콘텐츠의 속성, 상태, 카테고리를 시각적으로 표현하는 읽기 전용 라벨 컴포넌트다. */\nexport const Tag = React.forwardRef<HTMLSpanElement, TagProps>(({\n type = \"solid\",\n size = \"medium\",\n state = \"enabled\",\n label,\n prefixIcon,\n suffixIcon,\n className = \"\",\n ...props\n}, ref) => {\n // type이 weak가 아닐 때는 state를 무시하고 enabled로 처리\n const effectiveState = type === \"weak\" ? state : \"enabled\";\n\n // className은 마지막에 두고, tag.css는 타입/상태를 :where()로 넣어서 전달한 className이 우선 적용되도록 함\n const resolvedClassName = [\n \"tag\",\n `tag--${type}`,\n `tag--${size}`,\n `tag--${effectiveState}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n const textVariant = size === \"medium\" ? \"body-p2\" : \"body-p3\";\n\n return (\n <span ref={ref} {...props} className={resolvedClassName}>\n {prefixIcon && <span className=\"tag__prefix-icon\">{prefixIcon}</span>}\n <Text variant={textVariant}>{label}</Text>\n {suffixIcon && <span className=\"tag__suffix-icon\">{suffixIcon}</span>}\n </span>\n );\n});\n\nTag.displayName = \"Tag\";\n","import React, { useState, useRef, useEffect, useCallback, useLayoutEffect } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { Text } from \"../Typography/Typography\";\nimport \"./tooltip.css\";\n\nexport type TooltipPosition =\n | \"top\"\n | \"top-start\"\n | \"top-end\"\n | \"bottom\"\n | \"bottom-start\"\n | \"bottom-end\"\n | \"left\"\n | \"left-start\"\n | \"left-end\"\n | \"right\"\n | \"right-start\"\n | \"right-end\";\n\nexport type TooltipType = \"word\" | \"sentence\";\n\nexport interface TooltipProps {\n /** 툴팁에 표시할 내용 */\n label: React.ReactNode;\n /** 툴팁 타입 (word: 단어형, sentence: 장문형) */\n type?: TooltipType;\n /** Prefix 아이콘 (왼쪽) */\n prefixIcon?: React.ReactNode;\n /** Close 버튼 클릭 핸들러 (제공 시 닫기 버튼이 표시됨) */\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n /** 툴팁이 표시될 방향 */\n direction?: TooltipPosition;\n /** 화살표 표시 여부 */\n withArrow?: boolean;\n /** 툴팁 열림 상태 (controlled) */\n opened?: boolean;\n /** 툴팁 초기 열림 상태 (uncontrolled) */\n defaultOpened?: boolean;\n /** 툴팁 비활성화 */\n disabled?: boolean;\n /** 툴팁 너비 */\n width?: number | string;\n /** 툴팁 오프셋 (px) */\n offset?: number;\n /** 포털 사용 여부 */\n withinPortal?: boolean;\n /** 툴팁 표시 지연 시간 (ms) */\n openDelay?: number;\n /** 툴팁 숨김 지연 시간 (ms) */\n closeDelay?: number;\n /** 툴팁이 표시될 대상 요소 */\n children: React.ReactElement;\n /** 추가 클래스명 */\n className?: string;\n}\n\n/** 뷰포트 기준 위치 계산 + flip(방향 반전) + shift(가장자리 보정) */\nfunction calcPosition(\n trigger: DOMRect,\n tooltip: { width: number; height: number },\n direction: TooltipPosition,\n offset: number,\n): { top: number; left: number; finalDirection: TooltipPosition } {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const parts = direction.split(\"-\");\n const side = parts[0] as \"top\" | \"bottom\" | \"left\" | \"right\";\n const alignment = parts[1] as \"start\" | \"end\" | undefined;\n\n // Flip: 공간 부족 시 반대쪽으로\n let finalSide = side;\n\n if (side === \"top\" && trigger.top < tooltip.height + offset) {\n if (vh - trigger.bottom >= tooltip.height + offset) finalSide = \"bottom\";\n } else if (side === \"bottom\" && vh - trigger.bottom < tooltip.height + offset) {\n if (trigger.top >= tooltip.height + offset) finalSide = \"top\";\n } else if (side === \"left\" && trigger.left < tooltip.width + offset) {\n if (vw - trigger.right >= tooltip.width + offset) finalSide = \"right\";\n } else if (side === \"right\" && vw - trigger.right < tooltip.width + offset) {\n if (trigger.left >= tooltip.width + offset) finalSide = \"left\";\n }\n\n let top = 0;\n let left = 0;\n\n // Main axis (주축 위치)\n switch (finalSide) {\n case \"top\":\n top = trigger.top - tooltip.height - offset;\n break;\n case \"bottom\":\n top = trigger.bottom + offset;\n break;\n case \"left\":\n left = trigger.left - tooltip.width - offset;\n break;\n case \"right\":\n left = trigger.right + offset;\n break;\n }\n\n // Cross axis (교차축 정렬)\n if (finalSide === \"top\" || finalSide === \"bottom\") {\n switch (alignment) {\n case \"start\":\n left = trigger.left;\n break;\n case \"end\":\n left = trigger.right - tooltip.width;\n break;\n default:\n left = trigger.left + (trigger.width - tooltip.width) / 2;\n break;\n }\n // Shift: 뷰포트 안에 유지\n left = Math.max(4, Math.min(left, vw - tooltip.width - 4));\n } else {\n switch (alignment) {\n case \"start\":\n top = trigger.top;\n break;\n case \"end\":\n top = trigger.bottom - tooltip.height;\n break;\n default:\n top = trigger.top + (trigger.height - tooltip.height) / 2;\n break;\n }\n top = Math.max(4, Math.min(top, vh - tooltip.height - 4));\n }\n\n const finalDirection = (\n alignment ? `${finalSide}-${alignment}` : finalSide\n ) as TooltipPosition;\n\n return { top, left, finalDirection };\n}\n\n/** Tooltip 컴포넌트는 사용자에게 추가 정보나 설명을 제공하는 작은 팝오버입니다. */\nexport const Tooltip = ({\n label,\n type = \"word\",\n prefixIcon,\n onClose,\n direction = \"top\",\n withArrow = true,\n opened: openedProp,\n defaultOpened = false,\n disabled = false,\n width,\n offset = 8,\n withinPortal = true,\n openDelay = 0,\n closeDelay = 0,\n children,\n className = \"\",\n}: TooltipProps) => {\n const [opened, setOpened] = useState(defaultOpened);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const openTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const closeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isControlled = openedProp !== undefined;\n const isOpened = isControlled ? openedProp : opened;\n\n // Portal 위치 상태\n const [portalPos, setPortalPos] = useState<{\n top: number;\n left: number;\n ready: boolean;\n dir: TooltipPosition;\n }>({ top: 0, left: 0, ready: false, dir: direction });\n\n // 타임아웃 정리\n useEffect(() => {\n return () => {\n if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);\n if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);\n };\n }, []);\n\n const handleMouseEnter = () => {\n if (!disabled && !isControlled) {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n if (openDelay > 0) {\n openTimeoutRef.current = setTimeout(() => {\n setOpened(true);\n }, openDelay);\n } else {\n setOpened(true);\n }\n }\n };\n\n const handleMouseLeave = () => {\n if (!disabled && !isControlled) {\n if (openTimeoutRef.current) {\n clearTimeout(openTimeoutRef.current);\n openTimeoutRef.current = null;\n }\n if (closeDelay > 0) {\n closeTimeoutRef.current = setTimeout(() => {\n setOpened(false);\n }, closeDelay);\n } else {\n setOpened(false);\n }\n }\n };\n\n const handleFocus = () => {\n if (!disabled && !isControlled) {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n if (openDelay > 0) {\n openTimeoutRef.current = setTimeout(() => {\n setOpened(true);\n }, openDelay);\n } else {\n setOpened(true);\n }\n }\n };\n\n const handleBlur = () => {\n if (!disabled && !isControlled) {\n if (openTimeoutRef.current) {\n clearTimeout(openTimeoutRef.current);\n openTimeoutRef.current = null;\n }\n if (closeDelay > 0) {\n closeTimeoutRef.current = setTimeout(() => {\n setOpened(false);\n }, closeDelay);\n } else {\n setOpened(false);\n }\n }\n };\n\n const handleCloseClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (onClose) {\n onClose(e);\n }\n if (!disabled && !isControlled) {\n setOpened(false);\n }\n };\n\n // Portal 위치 계산\n const updatePosition = useCallback(() => {\n if (!wrapperRef.current || !tooltipRef.current) return;\n\n const triggerRect = wrapperRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n const result = calcPosition(\n triggerRect,\n { width: tooltipRect.width, height: tooltipRect.height },\n direction,\n offset,\n );\n\n setPortalPos({\n top: result.top,\n left: result.left,\n ready: true,\n dir: result.finalDirection,\n });\n }, [direction, offset]);\n\n // Paint 전에 위치 계산 (깜빡임 방지)\n useLayoutEffect(() => {\n if (isOpened && withinPortal) {\n updatePosition();\n }\n }, [isOpened, withinPortal, updatePosition]);\n\n // Scroll/Resize 대응 (RAF 스로틀링)\n useEffect(() => {\n if (!isOpened || !withinPortal) return;\n\n let rafId = 0;\n const onUpdate = () => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(updatePosition);\n };\n\n // capture: true → 모든 조상의 스크롤 이벤트 감지\n window.addEventListener(\"scroll\", onUpdate, true);\n window.addEventListener(\"resize\", onUpdate);\n\n return () => {\n window.removeEventListener(\"scroll\", onUpdate, true);\n window.removeEventListener(\"resize\", onUpdate);\n cancelAnimationFrame(rafId);\n };\n }, [isOpened, withinPortal, updatePosition]);\n\n // 방향 결정: portal 모드면 계산된 방향, 아니면 prop 그대로\n const displayDirection = withinPortal ? portalPos.dir : direction;\n\n const tooltipContent = (\n <div\n ref={withinPortal ? tooltipRef : undefined}\n className={`tooltip tooltip--${type} tooltip--${displayDirection} ${withArrow ? \"tooltip--with-arrow\" : \"\"} ${className}`}\n style={\n withinPortal\n ? {\n position: \"fixed\" as const,\n top: portalPos.top,\n left: portalPos.left,\n bottom: \"auto\" as const,\n right: \"auto\" as const,\n transform: \"none\",\n margin: 0,\n visibility: portalPos.ready ? (\"visible\" as const) : (\"hidden\" as const),\n ...(width\n ? { width: typeof width === \"number\" ? `${width}px` : width }\n : {}),\n }\n : width\n ? { width: typeof width === \"number\" ? `${width}px` : width }\n : undefined\n }\n role=\"tooltip\"\n >\n <div className=\"tooltip__content\">\n {prefixIcon && (\n <div className=\"tooltip__prefix-icon\">\n {prefixIcon}\n </div>\n )}\n <div className=\"tooltip__label\">\n <Text variant=\"body-p3\">{label}</Text>\n </div>\n {onClose && (\n <button\n type=\"button\"\n className=\"tooltip__close-button\"\n onClick={handleCloseClick}\n aria-label=\"Close tooltip\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 4L4 12M4 4L12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n )}\n </div>\n {withArrow && (\n <div\n className={`tooltip__arrow tooltip__arrow--${displayDirection.split(\"-\")[0]}`}\n />\n )}\n </div>\n );\n\n // Portal 렌더링: body에 직접 렌더링하여 overflow: hidden 회피\n const renderedTooltip =\n isOpened && !disabled\n ? withinPortal\n ? ReactDOM.createPortal(tooltipContent, document.body)\n : tooltipContent\n : null;\n\n return (\n <div\n ref={wrapperRef}\n className=\"tooltip__wrapper\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {children}\n {renderedTooltip}\n </div>\n );\n};\n\nTooltip.displayName = \"Tooltip\";\n","import React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n XCircleIcon,\n ExclamationTriangleIcon,\n CheckCircleIcon,\n InformationCircleIcon,\n} from \"@heroicons/react/24/solid\";\nimport { useBreakpoint } from \"../../shared/hooks/useMediaQuery\";\nimport { Text } from \"../Typography/Typography\";\nimport \"./toast.css\";\n\nexport type ToastSize = \"medium\" | \"small\";\nexport type ToastState =\n | \"default\"\n | \"error\"\n | \"warning\"\n | \"success\"\n | \"information\";\nexport type ToastPosition = \"top\" | \"bottom\";\nexport type ToastHorizontalAlign = \"center\" | \"left\" | \"right\";\n\nexport interface ToastProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"style\"> {\n /** Toast 크기. 미지정 시 breakpoint 기준(tablet 미만: small, 이상: medium). 지정 시 해당 값으로 오버라이드 */\n size?: ToastSize;\n /** Toast 상태 (default, error, warning, success, information) */\n state?: ToastState;\n /** Toast 메시지 */\n label: React.ReactNode;\n /** State 아이콘 (state에 따라 자동으로 표시되지만, 커스텀 아이콘을 전달할 수 있음) */\n icon?: React.ReactNode;\n /** Toast 위치 (top: 상단, bottom: 하단) - 기본값: top */\n position?: ToastPosition;\n /** 수평 정렬 (center: 중앙, left: 왼쪽, right: 오른쪽) - 기본값: center */\n horizontalAlign?: ToastHorizontalAlign;\n /** 상단 여백 (px) - 기본값: medium일 때 60px, small일 때 20px */\n topOffset?: number;\n /** 하단 여백 (px) - 기본값: 20px */\n bottomOffset?: number;\n /** 좌우 여백 (px) - small 사이즈일 때만 적용, 기본값: 16px */\n horizontalPadding?: number;\n /** 추가 스타일 (position이 명시되면 fixed position 로직을 건너뜁니다) */\n style?: React.CSSProperties;\n}\n\n/** Toast 컴포넌트는 화면에 짧은 시간 동안 나타났다가 자동으로 사라지는 경량 알림 컴포넌트다. */\nexport const Toast = (props: ToastProps) => {\n const {\n size: sizeProp,\n state = \"default\",\n label,\n icon,\n position = \"top\",\n horizontalAlign = \"center\",\n topOffset,\n bottomOffset,\n horizontalPadding,\n className = \"\",\n style,\n ...rest\n } = props;\n\n const { isUnderTablet } = useBreakpoint();\n /** breakpoint 우선, size prop 있으면 오버라이드 (Dialog와 동일) */\n const size: ToastSize = sizeProp ?? (isUnderTablet ? \"small\" : \"medium\");\n\n const baseClasses = [\"toast\", `toast--${size}`, `toast--${state}`, className]\n .filter(Boolean)\n .join(\" \");\n\n // 기본 위치 값 계산 (Layout 스펙: desktop/tablet 60px, mobile 20px)\n const defaultTopOffset = size === \"medium\" ? 60 : 20;\n const defaultBottomOffset = size === \"medium\" ? 60 : 20;\n const defaultHorizontalPadding = 16;\n\n // style prop에 position이 명시되어 있으면 fixed position 로직을 건너뜀\n const hasCustomPosition = style?.position !== undefined;\n\n // 위치 스타일 계산\n const positionStyles: React.CSSProperties = hasCustomPosition\n ? {\n // style prop에 position이 있으면 그대로 사용 (문서/스토리북용)\n ...style,\n }\n : {\n // 실제 사용: fixed position\n position: \"fixed\",\n zIndex: 1000,\n ...style,\n };\n\n // 커스텀 position이 없을 때만 위치 스타일 적용\n if (!hasCustomPosition) {\n // 수직 위치\n if (position === \"top\") {\n positionStyles.top = `${topOffset ?? defaultTopOffset}px`;\n positionStyles.bottom = \"auto\";\n } else {\n positionStyles.bottom = `${bottomOffset ?? defaultBottomOffset}px`;\n positionStyles.top = \"auto\";\n }\n\n // 수평 정렬\n if (size === \"small\") {\n // Mobile: 좌우 패딩 적용\n const padding = horizontalPadding ?? defaultHorizontalPadding;\n positionStyles.left = `${padding}px`;\n positionStyles.right = `${padding}px`;\n positionStyles.transform = \"none\";\n positionStyles.width = `calc(100% - ${padding * 2}px)`;\n } else {\n // Desktop/Tablet: 중앙 정렬 또는 좌우 정렬\n if (horizontalAlign === \"center\") {\n positionStyles.left = \"50%\";\n positionStyles.right = \"auto\";\n positionStyles.transform = \"translateX(-50%)\";\n positionStyles.width = \"auto\";\n positionStyles.minWidth = \"540px\";\n positionStyles.maxWidth = \"760px\";\n } else if (horizontalAlign === \"left\") {\n positionStyles.left = \"16px\";\n positionStyles.right = \"auto\";\n positionStyles.transform = \"none\";\n positionStyles.width = \"auto\";\n positionStyles.minWidth = \"540px\";\n positionStyles.maxWidth = \"760px\";\n } else {\n positionStyles.right = \"16px\";\n positionStyles.left = \"auto\";\n positionStyles.transform = \"none\";\n positionStyles.width = \"auto\";\n positionStyles.minWidth = \"540px\";\n positionStyles.maxWidth = \"760px\";\n }\n }\n }\n\n // State에 따른 기본 아이콘 (icon prop이 제공되지 않은 경우)\n const defaultIcon =\n !icon && state !== \"default\" ? (\n <div className=\"toast__icon\">\n {state === \"error\" && (\n <XCircleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n {state === \"warning\" && (\n <ExclamationTriangleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n {state === \"success\" && (\n <CheckCircleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n {state === \"information\" && (\n <InformationCircleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n </div>\n ) : icon ? (\n <div className=\"toast__icon\">{icon}</div>\n ) : null;\n\n return (\n <div className={baseClasses} style={positionStyles} {...rest}>\n {defaultIcon}\n <Text variant={size === \"medium\" ? \"heading-h6\" : \"subtitle-p2\"}>\n {label}\n </Text>\n </div>\n );\n};\n\n// useToast hook 관련 타입 및 인터페이스\nexport interface ToastOptions {\n /** Toast 상태 */\n state?: ToastState;\n /** Toast 크기 */\n size?: ToastSize;\n /** 자동으로 사라지는 시간 (ms) - 기본값: 3000 */\n duration?: number;\n /** Toast 위치 */\n position?: ToastPosition;\n /** 수평 정렬 */\n horizontalAlign?: ToastHorizontalAlign;\n /** 상단 여백 */\n topOffset?: number;\n /** 하단 여백 */\n bottomOffset?: number;\n /** 좌우 여백 */\n horizontalPadding?: number;\n}\n\nconst TOAST_EXIT_MS = 250;\n\ninterface ToastItem {\n id: string;\n message: string;\n state: ToastState;\n /** 미지정 시 Toast 내부에서 breakpoint 기준 적용 */\n size?: ToastSize;\n duration: number;\n position: ToastPosition;\n horizontalAlign: ToastHorizontalAlign;\n topOffset?: number;\n bottomOffset?: number;\n horizontalPadding?: number;\n exiting?: boolean;\n}\n\ninterface ToastContextType {\n showToast: (message: string, options?: ToastOptions) => void;\n hideToast: (id: string) => void;\n}\n\nconst ToastContext = React.createContext<ToastContextType | undefined>(\n undefined\n);\n\n/**\n * ToastProvider\n *\n * 앱의 최상위(Root)에 선언하여 전역 Toast 기능을 제공합니다.\n * Portal을 사용하여 document.body에 Toast를 렌더링합니다.\n */\nexport const ToastProvider = ({ children }: { children: React.ReactNode }) => {\n const [toasts, setToasts] = React.useState<ToastItem[]>([]);\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n const showToast = React.useCallback(\n (message: string, options: ToastOptions = {}) => {\n const id = `toast-${Date.now()}-${Math.random()}`;\n const {\n state = \"default\",\n size,\n duration = 3000,\n position = \"top\",\n horizontalAlign = \"center\",\n topOffset,\n bottomOffset,\n horizontalPadding,\n } = options;\n\n const newToast: ToastItem = {\n id,\n message,\n state,\n ...(size !== undefined && { size }),\n duration,\n position,\n horizontalAlign,\n topOffset,\n bottomOffset,\n horizontalPadding,\n };\n\n setToasts((prev) => [...prev, newToast]);\n\n if (duration > 0) {\n setTimeout(() => {\n setToasts((prev) =>\n prev.map((t) => (t.id === id ? { ...t, exiting: true } : t))\n );\n setTimeout(() => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, TOAST_EXIT_MS);\n }, duration);\n }\n },\n []\n );\n\n const hideToast = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ showToast, hideToast }}>\n {children}\n {mounted &&\n createPortal(\n <>\n {toasts.map((toast) => (\n <Toast\n key={toast.id}\n state={toast.state}\n size={toast.size}\n label={toast.message}\n position={toast.position}\n horizontalAlign={toast.horizontalAlign}\n topOffset={toast.topOffset}\n bottomOffset={toast.bottomOffset}\n horizontalPadding={toast.horizontalPadding}\n {...(toast.exiting && { className: \"toast--exiting\" })}\n />\n ))}\n </>,\n document.body\n )}\n </ToastContext.Provider>\n );\n};\n\n/**\n * useToast Hook\n *\n * ToastProvider 내부의 컴포넌트에서 호출하여 사용합니다.\n * { showToast } 함수를 반환합니다.\n *\n * @example\n * const { showToast } = useToast();\n * showToast(\"메시지\", { state: \"success\" });\n */\nexport function useToast() {\n const context = React.useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nToast.displayName = \"Toast\";\n","import React, { useState, useCallback, useRef, useEffect } from \"react\";\nimport \"./datepicker.css\";\nimport { Calendar } from \"./Calendar\";\nimport type { CalendarProps } from \"./Calendar\";\nimport { DateInput, formatDate, parseDate } from \"./DateInput\";\nimport type { DateInputProps } from \"./DateInput\";\nimport { TimePicker } from \"./TimePicker\";\nimport { ActionButton } from \"@/stories/Button/ActionButton/ActionButton\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport { Text } from \"../Typography/Typography\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DatePickerType = \"single\" | \"range\";\n\n/**\n * DatePicker 내부 서브 컴포넌트 슬롯 이름.\n * classNames / styles 객체의 키로 사용됩니다.\n *\n * - `root` — 최상위 wrapper\n * - `input` — 상단 트리거 인풋 박스 (DateInput의 content 영역)\n * - `popover` — 팝오버 컨테이너\n * - `calendar` — Calendar 컴포넌트 (range 모드일 때 두 캘린더 모두 적용)\n * - `footer` — 푸터 영역 (취소/적용 버튼 영역)\n * - `footerInput` — 푸터 내부 인풋 박스 (range 모드에서만 사용)\n * - `timePicker` — TimePicker 컴포넌트 (showTimeSelect 사용 시)\n *\n * @example\n * <DatePicker\n * styles={{\n * input: { height: 40, borderRadius: 12 },\n * calendar: { background: \"#fafafa\" },\n * popover: { width: 400 },\n * }}\n * classNames={{\n * input: \"my-input\",\n * calendar: \"my-calendar\",\n * }}\n * />\n */\nexport type DatePickerSlot =\n | \"root\"\n | \"input\"\n | \"popover\"\n | \"calendar\"\n | \"footer\"\n | \"footerInput\"\n | \"timePicker\";\n\nexport interface DatePickerSingleProps {\n type?: \"single\";\n /** 선택된 날짜 */\n value?: Date | null;\n /** 날짜 변경 핸들러 */\n onChange?: (date: Date) => void;\n startDate?: never;\n endDate?: never;\n onRangeChange?: never;\n}\n\nexport interface DatePickerRangeProps {\n type: \"range\";\n value?: never;\n onChange?: never;\n /** 시작 날짜 */\n startDate?: Date | null;\n /** 종료 날짜 */\n endDate?: Date | null;\n /** 기간 변경 핸들러 */\n onRangeChange?: (start: Date, end: Date | null) => void;\n}\n\n/** DatePicker가 내부적으로 관리하는 Calendar props (사용자가 오버라이드 불가) */\ntype ManagedCalendarProps =\n | \"year\" | \"month\"\n | \"selectedDate\" | \"startDate\" | \"endDate\" | \"hoverDate\"\n | \"rangeMode\" | \"minDate\" | \"maxDate\"\n | \"onClick\" | \"onHover\" | \"onPrev\" | \"onNext\"\n | \"showPrev\" | \"showNext\" | \"disablePrev\" | \"disableNext\"\n | \"locale\" | \"className\" | \"style\" | \"children\";\n\n/** DatePicker가 내부적으로 관리하는 DateInput props (사용자가 오버라이드 불가) */\ntype ManagedDateInputProps =\n | \"type\" | \"value\" | \"startDate\" | \"endDate\"\n | \"onClick\" | \"onReset\" | \"reset\"\n | \"disabled\" | \"error\" | \"description\"\n | \"locale\" | \"placeholder\" | \"dateFormat\" | \"className\" | \"style\";\n\ntype DatePickerBaseProps = {\n /** 비활성화 */\n disabled?: boolean;\n /** 읽기 전용 (값은 표시되지만 변경 불가) */\n readOnly?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** 도움말 텍스트 */\n description?: string;\n /** 선택 가능한 최소 날짜 */\n minDate?: Date;\n /** 선택 가능한 최대 날짜 */\n maxDate?: Date;\n /** 언어 설정 */\n locale?: string;\n /** 최상위 wrapper에 적용되는 CSS 클래스 (classNames.root의 단축 표현) */\n className?: string;\n /** 플레이스홀더 */\n placeholder?: string;\n /** 이전 버튼 표시 여부 (기본: true) */\n showPrev?: boolean;\n /** 다음 버튼 표시 여부 (기본: true) */\n showNext?: boolean;\n /** 이전 버튼 비활성화 여부 (기본: false) */\n disablePrev?: boolean;\n /** 다음 버튼 비활성화 여부 (기본: false) */\n disableNext?: boolean;\n /** 초기화 버튼 표시 여부 (기본: true, 날짜가 선택되어 있을 때 표시) */\n reset?: boolean;\n /** 시간 선택 패널 표시 여부 (기본: false, single 모드에서만 동작) */\n showTimeSelect?: boolean;\n /** 시간 간격 (분 단위, 기본: 30). showTimeSelect 활성화 시 사용 */\n timeIntervals?: number;\n /**\n * 날짜 표시 포맷.\n * 지원 토큰: yyyy, MM, M, dd, d, HH, mm\n * @default \"yyyy. M. d\" (showTimeSelect 시 \"yyyy. M. d HH:mm\")\n * @example \"yyyy.MM.dd HH:mm\" → \"2026.03.11 14:30\"\n * @example \"yyyy-MM-dd\" → \"2026-03-11\"\n */\n dateFormat?: string;\n /** 적용 버튼 클릭 시 호출되는 콜백 */\n onApply?: () => void;\n /** 취소 버튼 클릭 시 호출되는 콜백 */\n onCancel?: () => void;\n\n /**\n * 각 서브 컴포넌트별 커스텀 CSS 클래스.\n * 기존 컴포넌트의 기본 className에 병합(추가)됩니다.\n *\n * @example\n * classNames={{\n * root: \"my-datepicker\",\n * input: \"my-input\",\n * popover: \"my-popover\",\n * calendar: \"my-calendar\",\n * footer: \"my-footer\",\n * footerInput: \"my-footer-input\",\n * }}\n */\n classNames?: Partial<Record<DatePickerSlot, string>>;\n\n /**\n * 각 서브 컴포넌트별 인라인 스타일.\n * 해당 컴포넌트의 최상위 요소에 style 속성으로 적용됩니다.\n *\n * @example\n * styles={{\n * input: { height: 40, borderRadius: 12 },\n * calendar: { background: \"#f5f5f5\" },\n * popover: { width: 400 },\n * }}\n */\n styles?: Partial<Record<DatePickerSlot, React.CSSProperties>>;\n\n /**\n * Calendar 컴포넌트에 전달할 추가 props.\n * DatePicker가 내부적으로 관리하는 props(year, month, selectedDate 등)는\n * 제외되며, 나머지를 오버라이드할 수 있습니다.\n * range 모드일 경우 두 캘린더 모두에 동일하게 적용됩니다.\n *\n * @example\n * calendarProps={{ disablePrev: true, disableNext: false }}\n */\n calendarProps?: Partial<Omit<CalendarProps, ManagedCalendarProps>>;\n\n /**\n * 트리거 DateInput 컴포넌트에 전달할 추가 props.\n * DatePicker가 내부적으로 관리하는 props(type, value, onClick 등)는\n * 제외되며, 나머지를 오버라이드할 수 있습니다.\n *\n * @example\n * dateInputProps={{\n * prefixIcon: false,\n * startPlaceholder: \"출발일\",\n * endPlaceholder: \"도착일\",\n * }}\n */\n dateInputProps?: Partial<Omit<DateInputProps, ManagedDateInputProps>>;\n};\n\nexport type DatePickerProps = DatePickerBaseProps &\n (DatePickerSingleProps | DatePickerRangeProps);\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nconst toDate = (d: Date | string | number): Date =>\n d instanceof Date ? d : new Date(d);\n\nconst startOf = (d: Date | string | number) => {\n const dt = toDate(d);\n return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());\n};\n\nconst I18N: Record<string, { today: string; cancel: string; apply: string }> = {\n \"ko-KR\": { today: \"오늘\", cancel: \"취소\", apply: \"적용\" },\n \"en-US\": { today: \"Today\", cancel: \"Cancel\", apply: \"Apply\" },\n \"ja-JP\": { today: \"今日\", cancel: \"キャンセル\", apply: \"適用\" },\n};\n\nconst getI18n = (locale: string) =>\n I18N[locale] ?? I18N[\"ko-KR\"];\n\n// ── DatePicker Component ──────────────────────────────────────────────────────\n\n/** DatePicker는 DateInput과 Calendar를 조합한 완성형 날짜 선택 컴포넌트입니다. */\nexport const DatePicker: React.FC<DatePickerProps> = (props) => {\n const {\n type = \"single\",\n disabled = false,\n readOnly = false,\n error = false,\n description,\n minDate,\n maxDate,\n locale = \"ko-KR\",\n className = \"\",\n placeholder,\n showPrev = true,\n showNext = true,\n disablePrev = false,\n disableNext = false,\n reset: resetProp = true,\n showTimeSelect = false,\n timeIntervals = 30,\n dateFormat: dateFormatProp,\n onApply: onApplyProp,\n onCancel: onCancelProp,\n classNames,\n styles,\n calendarProps,\n dateInputProps,\n } = props;\n\n const i18n = getI18n(locale);\n const isRange = type === \"range\";\n const isTimeEnabled = showTimeSelect && !isRange;\n\n // showTimeSelect가 켜져있고 dateFormat이 지정되지 않으면 시간 포함 포맷\n const effectiveDateFormat = dateFormatProp ?? (isTimeEnabled ? \"yyyy. M. d HH:mm\" : undefined);\n const singleValue = !isRange\n ? (props as DatePickerSingleProps).value\n : undefined;\n const singleOnChange = !isRange\n ? (props as DatePickerSingleProps).onChange\n : undefined;\n const extStartDate = isRange\n ? (props as DatePickerRangeProps).startDate\n : undefined;\n const extEndDate = isRange\n ? (props as DatePickerRangeProps).endDate\n : undefined;\n const onRangeChange = isRange\n ? (props as DatePickerRangeProps).onRangeChange\n : undefined;\n\n const [isOpen, setIsOpen] = useState(false);\n const [currentMonth, setCurrentMonth] = useState<Date>(\n singleValue || extStartDate || new Date()\n );\n const [hoverDate, setHoverDate] = useState<Date | null>(null);\n const [internalStart, setInternalStart] = useState<Date | null>(\n extStartDate ?? null\n );\n const [internalEnd, setInternalEnd] = useState<Date | null>(\n extEndDate ?? null\n );\n const [internalSingle, setInternalSingle] = useState<Date | null>(\n singleValue ?? null\n );\n\n // 트리거 인풋에 표시할 확정된 값 (적용 버튼 클릭 시에만 갱신)\n const [committedSingle, setCommittedSingle] = useState<Date | null>(\n singleValue ?? null\n );\n const [committedStart, setCommittedStart] = useState<Date | null>(\n extStartDate ?? null\n );\n const [committedEnd, setCommittedEnd] = useState<Date | null>(\n extEndDate ?? null\n );\n\n // ── Single 캘린더 내부 날짜 입력 편집 상태 ──\n const [isEditingSingleField, setIsEditingSingleField] = useState(false);\n const [singleFieldText, setSingleFieldText] = useState(\"\");\n\n const handleSingleFieldFocus = useCallback(() => {\n setIsEditingSingleField(true);\n setSingleFieldText(formatDate(internalSingle, effectiveDateFormat, locale));\n }, [internalSingle, effectiveDateFormat, locale]);\n\n const handleSingleFieldBlur = useCallback(() => {\n const parsed = parseDate(singleFieldText, internalSingle);\n if (parsed && parsed !== internalSingle) {\n if (isTimeEnabled) {\n // 시간 포함 파싱이 안 됐으면(시간=0:00) 기존 시/분 유지\n const hasTime = parsed.getHours() !== 0 || parsed.getMinutes() !== 0;\n if (!hasTime && internalSingle) {\n parsed.setHours(internalSingle.getHours(), internalSingle.getMinutes(), 0, 0);\n }\n }\n setInternalSingle(parsed);\n setCurrentMonth(new Date(parsed.getFullYear(), parsed.getMonth(), 1));\n }\n setIsEditingSingleField(false);\n }, [singleFieldText, isTimeEnabled, internalSingle]);\n\n const handleSingleFieldKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleSingleFieldBlur();\n (e.target as HTMLInputElement).blur();\n }\n },\n [handleSingleFieldBlur],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n // 외부 클릭 시 취소와 동일하게 draft를 되돌림\n if (isRange) {\n setInternalStart(committedStart);\n setInternalEnd(committedEnd);\n } else {\n setInternalSingle(committedSingle);\n }\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isRange, committedSingle, committedStart, committedEnd]);\n\n // Sync external props\n useEffect(() => {\n if (!isRange && singleValue !== undefined) {\n requestAnimationFrame(() => {\n setInternalSingle(singleValue);\n setCommittedSingle(singleValue);\n });\n }\n }, [singleValue, isRange]);\n\n useEffect(() => {\n if (isRange) {\n requestAnimationFrame(() => {\n if (extStartDate !== undefined) {\n setInternalStart(extStartDate ?? null);\n setCommittedStart(extStartDate ?? null);\n }\n if (extEndDate !== undefined) {\n setInternalEnd(extEndDate ?? null);\n setCommittedEnd(extEndDate ?? null);\n }\n });\n }\n }, [extStartDate, extEndDate, isRange]);\n\n const year = currentMonth.getFullYear();\n const month = currentMonth.getMonth();\n\n const handlePrev = useCallback(\n () => setCurrentMonth(new Date(year, month - 1, 1)),\n [year, month]\n );\n const handleNext = useCallback(\n () => setCurrentMonth(new Date(year, month + 1, 1)),\n [year, month]\n );\n\n const handleSingleDayClick = (date: Date) => {\n if (isTimeEnabled && internalSingle) {\n // 시간 선택 모드: 기존 시/분을 유지하며 날짜만 변경\n const newDate = new Date(date);\n newDate.setHours(internalSingle.getHours(), internalSingle.getMinutes(), 0, 0);\n setInternalSingle(newDate);\n } else {\n setInternalSingle(date);\n }\n };\n\n const handleTimeChange = (date: Date) => {\n setInternalSingle(date);\n };\n\n const handleRangeDayClick = (date: Date) => {\n if (!internalStart || (internalStart && internalEnd)) {\n setInternalStart(date);\n setInternalEnd(null);\n } else {\n const s = startOf(internalStart);\n const e = startOf(date);\n if (e >= s) {\n setInternalEnd(date);\n } else {\n setInternalStart(date);\n setInternalEnd(internalStart);\n }\n }\n };\n\n const handleTodayClick = () => {\n const today = new Date();\n if (isRange) {\n setInternalStart(today);\n setInternalEnd(null);\n } else {\n setInternalSingle(today);\n }\n setCurrentMonth(new Date(today.getFullYear(), today.getMonth(), 1));\n };\n\n const handleCancel = () => {\n setIsOpen(false);\n if (isRange) {\n setInternalStart(committedStart);\n setInternalEnd(committedEnd);\n } else {\n setInternalSingle(committedSingle);\n }\n onCancelProp?.();\n };\n\n const handleApply = () => {\n setIsOpen(false);\n if (isRange && internalStart) {\n setCommittedStart(internalStart);\n setCommittedEnd(internalEnd);\n onRangeChange?.(internalStart, internalEnd ?? null);\n } else if (!isRange && internalSingle) {\n setCommittedSingle(internalSingle);\n singleOnChange?.(internalSingle);\n }\n onApplyProp?.();\n };\n\n const handleReset = () => {\n if (isRange) {\n setInternalStart(null);\n setInternalEnd(null);\n setCommittedStart(null);\n setCommittedEnd(null);\n onRangeChange?.(null as unknown as Date, null);\n } else {\n setInternalSingle(null);\n setCommittedSingle(null);\n singleOnChange?.(null as unknown as Date);\n }\n };\n\n const helpVariant = error ? \"error\" : \"inform\";\n\n return (\n <div\n className={`datepicker-root ${disabled ? \"datepicker-root--disabled\" : \"\"} ${readOnly ? \"datepicker-root--readonly\" : \"\"} ${className} ${classNames?.root ?? \"\"}`.trim()}\n style={styles?.root}\n ref={containerRef}\n >\n <div className=\"datepicker-wrapper\">\n <DateInput\n {...dateInputProps}\n disabled={disabled}\n error={error}\n type={isRange ? \"range\" : \"single\"}\n value={!isRange ? (singleValue ?? committedSingle) : undefined}\n startDate={isRange ? (extStartDate ?? committedStart) : undefined}\n endDate={isRange ? (extEndDate ?? committedEnd) : undefined}\n reset={\n resetProp &&\n !disabled &&\n !readOnly &&\n (isRange\n ? !!(committedStart || committedEnd)\n : !!(singleValue ?? committedSingle))\n }\n locale={locale}\n placeholder={placeholder}\n dateFormat={effectiveDateFormat}\n classNames={{\n ...dateInputProps?.classNames,\n ...(classNames?.input ? { content: [dateInputProps?.classNames?.content, classNames.input].filter(Boolean).join(\" \") || undefined } : {}),\n }}\n styles={{\n ...dateInputProps?.styles,\n ...(styles?.input ? { content: { ...dateInputProps?.styles?.content, ...styles.input } } : {}),\n }}\n onClick={() => !disabled && !readOnly && setIsOpen(!isOpen)}\n onReset={handleReset}\n />\n\n {isOpen && (\n <div\n className={`dp-popover ${isRange ? \"dp-popover--range\" : \"dp-popover--single\"} ${isTimeEnabled ? \"dp-popover--with-time\" : \"\"} ${classNames?.popover ?? \"\"}`.trim()}\n style={styles?.popover}\n >\n {isRange ? (\n <>\n <div className=\"dp-calendars-wrapper\">\n <Calendar\n {...calendarProps}\n year={year}\n month={month}\n locale={locale}\n startDate={internalStart}\n endDate={internalEnd}\n hoverDate={hoverDate}\n rangeMode\n minDate={minDate}\n maxDate={maxDate}\n showPrev={showPrev}\n showNext={false}\n disablePrev={disablePrev}\n disableNext={disableNext}\n className={classNames?.calendar}\n style={styles?.calendar}\n onClick={handleRangeDayClick}\n onHover={setHoverDate}\n onPrev={handlePrev}\n onNext={handleNext}\n />\n <Calendar\n {...calendarProps}\n year={month === 11 ? year + 1 : year}\n month={month === 11 ? 0 : month + 1}\n locale={locale}\n startDate={internalStart}\n endDate={internalEnd}\n hoverDate={hoverDate}\n rangeMode\n minDate={minDate}\n maxDate={maxDate}\n showPrev={false}\n showNext={showNext}\n disablePrev={disablePrev}\n disableNext={disableNext}\n className={classNames?.calendar}\n style={styles?.calendar}\n onClick={handleRangeDayClick}\n onHover={setHoverDate}\n onPrev={handlePrev}\n onNext={handleNext}\n />\n </div>\n\n {/* Range Footer: DateInput(editable) + 취소 + 적용 */}\n <div\n className={`dp-footer ${classNames?.footer ?? \"\"}`.trim()}\n style={styles?.footer}\n >\n <div className=\"dp-footer-input\">\n <DateInput\n type=\"range\"\n startDate={internalStart}\n endDate={internalEnd}\n prefixIcon={false}\n reset={false}\n editable\n locale={locale}\n dateFormat={effectiveDateFormat}\n classNames={classNames?.footerInput ? { content: classNames.footerInput } : undefined}\n styles={styles?.footerInput ? { content: styles.footerInput } : undefined}\n onStartChange={(date) => {\n if (date) {\n setInternalStart(date);\n setCurrentMonth(new Date(date.getFullYear(), date.getMonth(), 1));\n }\n }}\n onEndChange={(date) => {\n if (date) setInternalEnd(date);\n }}\n />\n </div>\n <ActionButton\n type=\"outline\"\n color=\"neutral\"\n size=\"large\"\n label={i18n.cancel}\n className=\"dp-footer__action\"\n onClick={handleCancel}\n />\n <ActionButton\n type=\"solid\"\n color=\"primary\"\n size=\"large\"\n label={i18n.apply}\n className=\"dp-footer__action\"\n onClick={handleApply}\n />\n </div>\n </>\n ) : (\n <>\n <div className={isTimeEnabled ? \"dp-time-wrapper\" : undefined}>\n <Calendar\n {...calendarProps}\n year={year}\n month={month}\n locale={locale}\n selectedDate={internalSingle}\n minDate={minDate}\n maxDate={maxDate}\n showPrev={showPrev}\n showNext={showNext}\n disablePrev={disablePrev}\n disableNext={disableNext}\n className={classNames?.calendar}\n style={styles?.calendar}\n onClick={handleSingleDayClick}\n onPrev={handlePrev}\n onNext={handleNext}\n >\n {/* 날짜 입력 필드 + 오늘 버튼 (헤더와 그리드 사이) */}\n <div className=\"calendar-date-input-row\">\n <div className=\"calendar-date-field\">\n <input\n type=\"text\"\n className=\"calendar-date-field__input\"\n value={\n isEditingSingleField\n ? singleFieldText\n : formatDate(internalSingle, effectiveDateFormat, locale) || \"\"\n }\n placeholder={placeholder || \"날짜 선택\"}\n onFocus={handleSingleFieldFocus}\n onChange={(e) => setSingleFieldText(e.target.value)}\n onBlur={handleSingleFieldBlur}\n onKeyDown={handleSingleFieldKeyDown}\n />\n </div>\n <button\n type=\"button\"\n className=\"calendar-today-btn\"\n onClick={handleTodayClick}\n >\n {i18n.today}\n </button>\n </div>\n </Calendar>\n\n {isTimeEnabled && (\n <TimePicker\n selectedDate={internalSingle}\n onTimeChange={handleTimeChange}\n timeIntervals={timeIntervals}\n className={classNames?.timePicker}\n style={styles?.timePicker}\n />\n )}\n </div>\n\n {/* Single Footer: 취소 + 적용 */}\n <div\n className={`dp-footer dp-footer--single ${classNames?.footer ?? \"\"}`.trim()}\n style={styles?.footer}\n >\n <ActionButton\n type=\"outline\"\n color=\"neutral\"\n size=\"large\"\n label={i18n.cancel}\n className=\"dp-footer__action\"\n onClick={handleCancel}\n />\n <ActionButton\n type=\"solid\"\n color=\"primary\"\n size=\"large\"\n label={i18n.apply}\n className=\"dp-footer__action\"\n onClick={handleApply}\n />\n </div>\n </>\n )}\n </div>\n )}\n </div>\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {error && (\n <span className=\"help-text__icon\">\n <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n </span>\n )}\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n </span>\n )}\n </div>\n );\n};\n\nDatePicker.displayName = \"DatePicker\";\n","import React, { useMemo, useCallback } from \"react\";\nimport \"./calendar.css\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface CalendarProps {\n /** 연도 */\n year?: number;\n /** 월 (0-11) */\n month?: number;\n /** 선택된 날짜 (single 모드) */\n selectedDate?: Date | null;\n /** 시작 날짜 (range 모드) */\n startDate?: Date | null;\n /** 종료 날짜 (range 모드) */\n endDate?: Date | null;\n /** 호버 중인 날짜 (range 모드) */\n hoverDate?: Date | null;\n /** 기간 선택 모드 여부 */\n rangeMode?: boolean;\n /** 선택 가능한 최소 날짜 */\n minDate?: Date;\n /** 선택 가능한 최대 날짜 */\n maxDate?: Date;\n /** 언어 설정 */\n locale?: string;\n /** 날짜 클릭 핸들러 */\n onClick?: (date: Date) => void;\n /** 날짜 호버 핸들러 */\n onHover?: (date: Date | null) => void;\n /** 이전 달 이동 핸들러 */\n onPrev?: () => void;\n /** 다음 달 이동 핸들러 */\n onNext?: () => void;\n /** 이전 버튼 표시 여부 */\n showPrev?: boolean;\n /** 다음 버튼 표시 여부 */\n showNext?: boolean;\n /** 이전 버튼 비활성화 여부 */\n disablePrev?: boolean;\n /** 다음 버튼 비활성화 여부 */\n disableNext?: boolean;\n /** 추가 CSS 클래스 */\n className?: string;\n /** 인라인 스타일 (최상위 calendar 요소에 적용) */\n style?: React.CSSProperties;\n /** 헤더와 그리드 사이에 렌더링할 콘텐츠 */\n children?: React.ReactNode;\n}\n\n// ── Icons ─────────────────────────────────────────────────────────────────────\n\nconst ChevronLeft = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M15 18L9 12L15 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nconst ChevronRight = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M9 18L15 12L9 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// ── Utility helpers ───────────────────────────────────────────────────────────\n\nconst getWeekdays = (locale: string): string[] => {\n const base = new Date(2023, 0, 1); // Sunday\n return Array.from({ length: 7 }, (_, i) => {\n const d = new Date(base);\n d.setDate(base.getDate() + i);\n return d.toLocaleDateString(locale, { weekday: \"short\" }).replace(/요일$/, \"\");\n });\n};\n\nconst getDaysInMonth = (year: number, month: number) =>\n new Date(year, month + 1, 0).getDate();\n\nconst getFirstDayOfMonth = (year: number, month: number) =>\n new Date(year, month, 1).getDay();\n\nconst isSameDay = (a: Date | string | number, b: Date | string | number) => {\n const da = toDate(a);\n const db = toDate(b);\n return (\n da.getFullYear() === db.getFullYear() &&\n da.getMonth() === db.getMonth() &&\n da.getDate() === db.getDate()\n );\n};\n\nconst toDate = (d: Date | string | number): Date =>\n d instanceof Date ? d : new Date(d);\n\nconst startOf = (d: Date | string | number) => {\n const dt = toDate(d);\n return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());\n};\n\ninterface DayItem {\n date: Date;\n isCurrentMonth: boolean;\n}\n\nconst buildDayGrid = (year: number, month: number): DayItem[] => {\n const grid: DayItem[] = [];\n const daysInMonth = getDaysInMonth(year, month);\n const firstDay = getFirstDayOfMonth(year, month);\n\n for (let i = 0; i < firstDay; i++) {\n grid.push({ date: new Date(year, month, -(firstDay - 1 - i)), isCurrentMonth: false });\n }\n for (let i = 1; i <= daysInMonth; i++) {\n grid.push({ date: new Date(year, month, i), isCurrentMonth: true });\n }\n const remaining = 7 - (grid.length % 7);\n if (remaining < 7) {\n for (let i = 1; i <= remaining; i++) {\n grid.push({ date: new Date(year, month + 1, i), isCurrentMonth: false });\n }\n }\n return grid;\n};\n\n// ── Calendar Component ────────────────────────────────────────────────────────\n\n/** Calendar는 단독으로 사용하거나 DatePicker의 일부분으로 사용되는 달력 그리드입니다. */\nexport const Calendar: React.FC<CalendarProps> = ({\n year: yearProp,\n month: monthProp,\n locale = \"ko-KR\",\n selectedDate,\n startDate,\n endDate,\n hoverDate,\n rangeMode = false,\n minDate,\n maxDate,\n onClick,\n onHover,\n onPrev,\n onNext,\n showPrev = true,\n showNext = true,\n disablePrev = false,\n disableNext = false,\n className = \"\",\n style,\n children,\n}) => {\n const now = new Date();\n const year = yearProp ?? now.getFullYear();\n const month = monthProp ?? now.getMonth();\n\n const today = useMemo(() => startOf(new Date()), []);\n const days = useMemo(() => buildDayGrid(year, month), [year, month]);\n const weekdays = useMemo(() => getWeekdays(locale), [locale]);\n const monthLabel = `${year}. ${month + 1}`;\n\n const isDisabled = useCallback(\n (date: Date) => {\n const d = startOf(date);\n if (minDate && d < startOf(minDate)) return true;\n if (maxDate && d > startOf(maxDate)) return true;\n return false;\n },\n [minDate, maxDate]\n );\n\n const getDayClass = (item: DayItem) => {\n const d = startOf(item.date);\n const classes = [\"calendar-day\"];\n if (!item.isCurrentMonth) classes.push(\"calendar-day--outside\");\n if (isDisabled(item.date)) classes.push(\"calendar-day--disabled\");\n\n if (!rangeMode && selectedDate && isSameDay(d, selectedDate)) {\n classes.push(\"calendar-day--selected\");\n }\n\n if (rangeMode && startDate && endDate) {\n const s = startOf(startDate);\n const e = startOf(endDate);\n if (isSameDay(d, s)) classes.push(\"calendar-day--range-start\");\n else if (isSameDay(d, e)) classes.push(\"calendar-day--range-end\");\n else if (d > s && d < e) classes.push(\"calendar-day--in-range\");\n } else if (rangeMode && startDate && !endDate && hoverDate) {\n const s = startOf(startDate);\n const h = startOf(hoverDate);\n if (isSameDay(d, s)) classes.push(\"calendar-day--range-start\");\n else if (h > s && d > s && d <= h) classes.push(\"calendar-day--in-range\");\n else if (h < s && d < s && d >= h) classes.push(\"calendar-day--in-range\");\n } else if (rangeMode && startDate && isSameDay(d, startDate)) {\n classes.push(\"calendar-day--range-start\");\n }\n\n if (isSameDay(d, today)) {\n classes.push(\"calendar-day--today\");\n }\n\n return classes.join(\" \");\n };\n\n return (\n <div className={`calendar ${className}`} style={style}>\n <div className=\"calendar-header\">\n {showPrev ? (\n <button type=\"button\" className=\"calendar-nav-btn\" disabled={disablePrev} onClick={onPrev} aria-label=\"이전 달\">\n <ChevronLeft />\n </button>\n ) : (\n <div className=\"calendar-nav-placeholder\" />\n )}\n <span className=\"calendar-month-label\">{monthLabel}</span>\n {showNext ? (\n <button type=\"button\" className=\"calendar-nav-btn\" disabled={disableNext} onClick={onNext} aria-label=\"다음 달\">\n <ChevronRight />\n </button>\n ) : (\n <div className=\"calendar-nav-placeholder\" />\n )}\n </div>\n\n {children}\n\n <div className=\"calendar-grid\" role=\"grid\" aria-label={monthLabel}>\n {weekdays.map((wd) => (\n <div key={wd} className=\"calendar-weekday\" role=\"columnheader\">\n {wd}\n </div>\n ))}\n {days.map((item, idx) => (\n <button\n key={idx}\n type=\"button\"\n className={getDayClass(item)}\n disabled={isDisabled(item.date) || !item.isCurrentMonth}\n onClick={() => item.isCurrentMonth && onClick?.(item.date)}\n onMouseEnter={() => item.isCurrentMonth && onHover?.(item.date)}\n onMouseLeave={() => onHover?.(null)}\n aria-selected={\n !rangeMode && selectedDate ? isSameDay(item.date, selectedDate) : undefined\n }\n tabIndex={item.isCurrentMonth ? 0 : -1}\n >\n {item.date.getDate()}\n </button>\n ))}\n </div>\n </div>\n );\n};\n\nCalendar.displayName = \"Calendar\";\n","import React, { useState, useCallback } from \"react\";\nimport \"./date-input.css\";\nimport { RiCalendar2Line } from \"@remixicon/react\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport { TextField } from \"../TextField/TextField\";\nimport { Text } from \"../Typography/Typography\";\n\n// ── Icons ────────────────────────────────────────────────────────────────────\n\nconst CloseCircleIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M10 18C14.4183 18 18 14.4183 18 10C18 5.58172 14.4183 2 10 2C5.58172 2 2 5.58172 2 10C2 14.4183 5.58172 18 10 18Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12.5 7.5L7.5 12.5M7.5 7.5L12.5 12.5\"\n stroke=\"white\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DateInputType = \"single\" | \"range\";\n/**\n * DateInput 내부 서브 요소 슬롯 이름.\n * classNames / styles 객체의 키로 사용됩니다.\n *\n * - `root` — 최상위 wrapper (`date-input`)\n * - `content` — 입력 영역\n * - `icon` — prefix 캘린더 아이콘 (range 모드에서만 사용)\n * - `text` — 날짜 텍스트 표시 영역 (range 모드에서만 사용)\n * - `separator` — range 모드 구분자 (`-`)\n * - `reset` — 초기화 버튼 (range 모드에서만 사용)\n */\nexport type DateInputSlot =\n | \"root\"\n | \"content\"\n | \"icon\"\n | \"text\"\n | \"separator\"\n | \"reset\";\n\nexport interface DateInputProps {\n /** 입력 타입: 단일 날짜 또는 기간 */\n type?: DateInputType;\n /** 비활성화 */\n disabled?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** 선택된 날짜 (single 모드) */\n value?: Date | null;\n /** 시작 날짜 (range 모드) */\n startDate?: Date | null;\n /** 종료 날짜 (range 모드) */\n endDate?: Date | null;\n /** prefix 아이콘 표시 여부 */\n prefixIcon?: boolean;\n /** 초기화 버튼 표시 여부 (single / range 모두 지원) */\n reset?: boolean;\n /** 도움말 텍스트 */\n description?: string;\n /** 날짜 표시 포맷 (locale) */\n locale?: string;\n /** 단일 모드 플레이스홀더 */\n placeholder?: string;\n /** 시작일 플레이스홀더 (range 모드) */\n startPlaceholder?: string;\n /** 종료일 플레이스홀더 (range 모드) */\n endPlaceholder?: string;\n /** 날짜 표시 포맷 (기본: \"yyyy. M. d\"). 예: \"yyyy.MM.dd HH:mm\" */\n dateFormat?: string;\n /**\n * 텍스트 입력으로 날짜를 직접 편집할 수 있는지 여부.\n * true이면 날짜 텍스트가 `<input>`으로 렌더링되어 타이핑 입력이 가능합니다.\n */\n editable?: boolean;\n /** 날짜 값 변경 콜백 (single 모드, editable 시 사용) */\n onValueChange?: (date: Date | null) => void;\n /** 시작일 변경 콜백 (range 모드, editable 시 사용) */\n onStartChange?: (date: Date | null) => void;\n /** 종료일 변경 콜백 (range 모드, editable 시 사용) */\n onEndChange?: (date: Date | null) => void;\n /** 클릭 핸들러 */\n onClick?: () => void;\n /** 초기화 클릭 핸들러 */\n onReset?: () => void;\n /** 추가 CSS 클래스 (classNames.root의 단축 표현) */\n className?: string;\n /** 인라인 스타일 (styles.root의 단축 표현) */\n style?: React.CSSProperties;\n\n /**\n * 각 서브 요소별 커스텀 CSS 클래스.\n * 기존 요소의 기본 className에 병합(추가)됩니다.\n */\n classNames?: Partial<Record<DateInputSlot, string>>;\n\n /**\n * 각 서브 요소별 인라인 스타일.\n * 해당 요소에 style 속성으로 적용됩니다.\n */\n styles?: Partial<Record<DateInputSlot, React.CSSProperties>>;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\n/**\n * Date를 포맷 문자열에 따라 변환합니다.\n * 지원 토큰: yyyy, MM, M, dd, d, HH, mm\n * format이 없으면 locale 기반 기본 포맷을 사용합니다.\n */\nexport const formatDate = (\n d: Date | null | undefined,\n format?: string,\n locale?: string,\n): string => {\n if (!d) return \"\";\n\n // 기본 포맷: \"yyyy. M. d\"\n if (!format) {\n return `${d.getFullYear()}. ${d.getMonth() + 1}. ${d.getDate()}`;\n }\n\n const y = d.getFullYear();\n const M = d.getMonth() + 1;\n const day = d.getDate();\n const H = d.getHours();\n const min = d.getMinutes();\n\n return format\n .replace(\"yyyy\", String(y))\n .replace(\"MM\", pad2(M))\n .replace(\"M\", String(M))\n .replace(\"dd\", pad2(day))\n .replace(\"d\", String(day))\n .replace(\"HH\", pad2(H))\n .replace(\"mm\", pad2(min));\n};\n\n/**\n * 날짜 문자열을 Date 객체로 파싱합니다.\n *\n * 지원 포맷:\n * - 구분자 포맷: \"2026.3.11\", \"2026-03-11\", \"2026/03/11\", \"2026. 3. 11\"\n * - 8자리 숫자: \"20260311\"\n * - 시간 포함: \"2026.03.11 14:30\", \"2026-03-11 09:00\"\n *\n * 파싱 실패 시 `fallback`을 반환합니다 (기본: null).\n */\nexport const parseDate = (\n str: string,\n fallback: Date | null = null,\n): Date | null => {\n if (!str || !str.trim()) return fallback;\n const trimmed = str.trim();\n\n let y: number | undefined;\n let m: number | undefined;\n let d: number | undefined;\n let hours = 0;\n let minutes = 0;\n\n // 1) 시간 포함: \"2026.03.11 14:30\", \"2026-03-11 09:00\" 등\n const dtMatch = trimmed.match(\n /^(\\d{4})\\s*[.\\-/]\\s*(\\d{1,2})\\s*[.\\-/]\\s*(\\d{1,2})\\s+(\\d{1,2}):(\\d{2})$/,\n );\n if (dtMatch) {\n y = Number(dtMatch[1]);\n m = Number(dtMatch[2]) - 1;\n d = Number(dtMatch[3]);\n hours = Number(dtMatch[4]);\n minutes = Number(dtMatch[5]);\n }\n\n // 2) 구분자 포맷: \"2026.3.11\", \"2026-03-11\", \"2026/03/11\"\n if (y === undefined) {\n const cleaned = trimmed.replace(/\\s+/g, \"\");\n const dateMatch = cleaned.match(/^(\\d{4})[.\\-/](\\d{1,2})[.\\-/](\\d{1,2})$/);\n if (dateMatch) {\n y = Number(dateMatch[1]);\n m = Number(dateMatch[2]) - 1;\n d = Number(dateMatch[3]);\n }\n }\n\n // 3) 8자리 숫자: \"20260311\"\n if (y === undefined) {\n const cleaned = trimmed.replace(/\\s+/g, \"\");\n const numMatch = cleaned.match(/^(\\d{4})(\\d{2})(\\d{2})$/);\n if (numMatch) {\n y = Number(numMatch[1]);\n m = Number(numMatch[2]) - 1;\n d = Number(numMatch[3]);\n }\n }\n\n if (y === undefined || m === undefined || d === undefined) return fallback;\n\n // 시/분 유효 범위 체크\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return fallback;\n\n const date = new Date(y, m, d, hours, minutes, 0, 0);\n if (\n !isNaN(date.getTime()) &&\n date.getFullYear() === y &&\n date.getMonth() === m &&\n date.getDate() === d\n ) {\n return date;\n }\n return fallback;\n};\n\n// ── Component ────────────────────────────────────────────────────────────────\n\n/** DateInput은 날짜를 표시하고 입력받는 필드 컴포넌트로, single/range 타입을 지원합니다. */\nexport const DateInput: React.FC<DateInputProps> = ({\n type = \"single\",\n disabled = false,\n error = false,\n value,\n startDate,\n endDate,\n prefixIcon = true,\n reset = false,\n description,\n locale = \"ko-KR\",\n placeholder = \"날짜 선택\",\n startPlaceholder = \"시작일\",\n endPlaceholder = \"종료일\",\n dateFormat,\n editable = false,\n onValueChange,\n onStartChange,\n onEndChange,\n onClick,\n onReset,\n className = \"\",\n style,\n classNames,\n styles,\n}) => {\n const isRange = type === \"range\";\n\n // ── Editable state ──\n const [editingField, setEditingField] = useState<\"value\" | \"start\" | \"end\" | null>(null);\n const [editText, setEditText] = useState(\"\");\n\n const handleEditFocus = useCallback(\n (field: \"value\" | \"start\" | \"end\", currentText: string) => {\n setEditingField(field);\n setEditText(currentText);\n },\n [],\n );\n\n const handleEditBlur = useCallback(\n (field: \"value\" | \"start\" | \"end\") => {\n const fallback =\n field === \"value\" ? (value ?? null) :\n field === \"start\" ? (startDate ?? null) :\n (endDate ?? null);\n const parsed = parseDate(editText, fallback);\n if (field === \"value\") onValueChange?.(parsed);\n else if (field === \"start\") onStartChange?.(parsed);\n else if (field === \"end\") onEndChange?.(parsed);\n setEditingField(null);\n },\n [editText, value, startDate, endDate, onValueChange, onStartChange, onEndChange],\n );\n\n const handleEditKeyDown = useCallback(\n (field: \"value\" | \"start\" | \"end\", e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleEditBlur(field);\n (e.target as HTMLInputElement).blur();\n }\n },\n [handleEditBlur],\n );\n\n const handleClick = () => {\n if (!disabled) onClick?.();\n };\n\n const handleResetClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (!disabled) onReset?.();\n };\n\n const wrapperCls = [\n \"date-input\",\n !isRange && \"date-input--single\",\n isRange && \"date-input--range\",\n className,\n classNames?.root,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const mergedRootStyle = style || styles?.root\n ? { ...style, ...styles?.root }\n : undefined;\n\n // ── Single mode → TextField ──\n if (!isRange) {\n const dateStr = formatDate(value, dateFormat, locale);\n\n return (\n <div className={wrapperCls} style={mergedRootStyle} onClick={handleClick}>\n <TextField\n type=\"input\"\n readOnly={!editable}\n value={editable && editingField === \"value\" ? editText : (dateStr || \"\")}\n placeholder={placeholder}\n prefixIcon={prefixIcon ? <RiCalendar2Line /> : undefined}\n suffixIcon={reset ? (\n <button\n type=\"button\"\n className=\"date-input__reset\"\n onClick={handleResetClick}\n disabled={disabled}\n aria-label=\"날짜 초기화\"\n >\n <CloseCircleIcon />\n </button>\n ) : undefined}\n error={error}\n description={description}\n accentIcon={!!error}\n disabled={disabled}\n className={classNames?.content}\n style={styles?.content}\n onFocus={editable ? () => handleEditFocus(\"value\", dateStr) : undefined}\n onChange={editable ? (e) => setEditText(e.target.value) : undefined}\n onBlur={editable ? () => handleEditBlur(\"value\") : undefined}\n />\n </div>\n );\n }\n\n // ── Range mode → custom ──\n const startStr = formatDate(startDate, dateFormat, locale);\n const endStr = formatDate(endDate, dateFormat, locale);\n const showStartPlaceholder = !startStr;\n const showEndPlaceholder = !endStr;\n\n const contentCls = [\n \"date-input__content\",\n \"date-input__content--range\",\n disabled && \"date-input__content--disabled\",\n error && \"date-input__content--error\",\n classNames?.content,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const helpVariant = error ? \"error\" : \"inform\";\n\n return (\n <div className={wrapperCls} style={mergedRootStyle}>\n <div className={contentCls} style={styles?.content} onClick={handleClick}>\n {prefixIcon && (\n <span\n className={`date-input__icon ${classNames?.icon ?? \"\"}`}\n style={styles?.icon}\n >\n <RiCalendar2Line />\n </span>\n )}\n {editable ? (\n <input\n type=\"text\"\n className={`date-input__editable ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n value={editingField === \"start\" ? editText : startStr}\n placeholder={startPlaceholder}\n onFocus={() => handleEditFocus(\"start\", startStr)}\n onChange={(e) => setEditText(e.target.value)}\n onBlur={() => handleEditBlur(\"start\")}\n onKeyDown={(e) => handleEditKeyDown(\"start\", e)}\n />\n ) : (\n <span\n className={`date-input__text ${showStartPlaceholder ? \"date-input__text--placeholder\" : \"\"} ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n >\n {startStr || startPlaceholder}\n </span>\n )}\n <span\n className={`date-input__separator ${classNames?.separator ?? \"\"}`}\n style={styles?.separator}\n >\n -\n </span>\n {editable ? (\n <input\n type=\"text\"\n className={`date-input__editable ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n value={editingField === \"end\" ? editText : endStr}\n placeholder={endPlaceholder}\n onFocus={() => handleEditFocus(\"end\", endStr)}\n onChange={(e) => setEditText(e.target.value)}\n onBlur={() => handleEditBlur(\"end\")}\n onKeyDown={(e) => handleEditKeyDown(\"end\", e)}\n />\n ) : (\n <span\n className={`date-input__text ${showEndPlaceholder ? \"date-input__text--placeholder\" : \"\"} ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n >\n {endStr || endPlaceholder}\n </span>\n )}\n {reset && (\n <button\n type=\"button\"\n className={`date-input__reset ${classNames?.reset ?? \"\"}`}\n style={styles?.reset}\n onClick={handleResetClick}\n aria-label=\"날짜 초기화\"\n disabled={disabled}\n >\n <CloseCircleIcon />\n </button>\n )}\n </div>\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {error && (\n <span className=\"help-text__icon\">\n <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n </span>\n )}\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n </span>\n )}\n </div>\n );\n};\n\nDateInput.displayName = \"DateInput\";\n","import React, { useMemo, useRef, useEffect, useCallback } from \"react\";\nimport \"./time-picker.css\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface TimePickerProps {\n /** 현재 선택된 시간이 포함된 Date */\n selectedDate?: Date | null;\n /** 시간 선택 시 콜백 (시/분이 설정된 새 Date 반환) */\n onTimeChange?: (date: Date) => void;\n /** 시간 간격 (분 단위, 기본: 30) */\n timeIntervals?: number;\n /** 추가 CSS 클래스 */\n className?: string;\n /** 인라인 스타일 */\n style?: React.CSSProperties;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\ninterface TimeSlot {\n hour: number;\n minute: number;\n label: string;\n}\n\nconst pad = (n: number): string => String(n).padStart(2, \"0\");\n\nconst buildTimeSlots = (intervals: number): TimeSlot[] => {\n const slots: TimeSlot[] = [];\n const totalMinutesInDay = 24 * 60;\n\n for (let m = 0; m < totalMinutesInDay; m += intervals) {\n const hour = Math.floor(m / 60);\n const minute = m % 60;\n slots.push({\n hour,\n minute,\n label: `${pad(hour)}:${pad(minute)}`,\n });\n }\n return slots;\n};\n\nconst isSameTime = (\n date: Date | null | undefined,\n hour: number,\n minute: number,\n): boolean => {\n if (!date) return false;\n return date.getHours() === hour && date.getMinutes() === minute;\n};\n\n// ── TimePicker Component ──────────────────────────────────────────────────────\n\n/** TimePicker는 세로 스크롤 리스트로 시간을 선택하는 컴포넌트입니다. */\nexport const TimePicker: React.FC<TimePickerProps> = ({\n selectedDate,\n onTimeChange,\n timeIntervals = 30,\n className = \"\",\n style,\n}) => {\n const listRef = useRef<HTMLDivElement>(null);\n const selectedRef = useRef<HTMLButtonElement>(null);\n\n const slots = useMemo(() => buildTimeSlots(timeIntervals), [timeIntervals]);\n\n // 선택된 시간으로 자동 스크롤\n useEffect(() => {\n if (selectedRef.current && listRef.current) {\n const list = listRef.current;\n const item = selectedRef.current;\n const listRect = list.getBoundingClientRect();\n const itemRect = item.getBoundingClientRect();\n\n // 아이템이 뷰포트 밖에 있을 때만 스크롤\n if (itemRect.top < listRect.top || itemRect.bottom > listRect.bottom) {\n list.scrollTop =\n item.offsetTop -\n list.offsetTop -\n list.clientHeight / 2 +\n item.clientHeight / 2;\n }\n }\n }, [selectedDate]);\n\n const handleTimeClick = useCallback(\n (hour: number, minute: number) => {\n const base = selectedDate ? new Date(selectedDate) : new Date();\n base.setHours(hour, minute, 0, 0);\n onTimeChange?.(new Date(base));\n },\n [selectedDate, onTimeChange],\n );\n\n return (\n <div className={`time-picker ${className}`} style={style}>\n <div className=\"time-picker__header\">시간</div>\n <div className=\"time-picker__list\" ref={listRef}>\n {slots.map((slot) => {\n const isSelected = isSameTime(selectedDate, slot.hour, slot.minute);\n return (\n <button\n key={slot.label}\n ref={isSelected ? selectedRef : undefined}\n type=\"button\"\n className={`time-picker__item ${isSelected ? \"time-picker__item--selected\" : \"\"}`}\n onClick={() => handleTimeClick(slot.hour, slot.minute)}\n >\n {slot.label}\n </button>\n );\n })}\n </div>\n </div>\n );\n};\n\nTimePicker.displayName = \"TimePicker\";\n","/**\n * 로고 SVG 에셋 - 번들에 포함되어 패키지 사용 시 별도 복사 불필요\n */\nimport likelionEngPrimary from \"../assets/logo/likelion-eng-primary.svg\";\nimport likelionEngBlack from \"../assets/logo/likelion-eng-black.svg\";\nimport likelionEngWhite from \"../assets/logo/likelion-eng-white.svg\";\nimport likelionKrPrimary from \"../assets/logo/likelion-kr-primary.svg\";\nimport likelionKrBlack from \"../assets/logo/likelion-kr-black.svg\";\nimport likelionKrWhite from \"../assets/logo/likelion-kr-white.svg\";\nimport bootcampPrimary from \"../assets/logo/bootcamp-primary.svg\";\nimport bootcampBlack from \"../assets/logo/bootcamp-black.svg\";\nimport bootcampWhite from \"../assets/logo/bootcamp-white.svg\";\nimport symbolPrimary from \"../assets/logo/symbol-primary.svg\";\nimport symbolBlack from \"../assets/logo/symbol-black.svg\";\nimport symbolWhite from \"../assets/logo/symbol-white.svg\";\nimport faviconPrimary from \"../assets/logo/favicon-primary.svg\";\nimport faviconBlack from \"../assets/logo/favicon-black.svg\";\n\nexport type LogoColor = \"primary\" | \"black\" | \"white\";\n\n/**\n * Next.js SVG import → { src: string, ... } 객체 또는 plain string.\n * 두 환경 모두 호환되도록 src 프로퍼티를 추출한다.\n */\nconst toUrl = (imported: string | { src: string }): string =>\n typeof imported === \"string\" ? imported : imported.src;\n\nexport const LOGO_URLS: Record<\n string,\n Record<LogoColor, string>\n> = {\n \"likelion-eng\": {\n primary: toUrl(likelionEngPrimary),\n black: toUrl(likelionEngBlack),\n white: toUrl(likelionEngWhite),\n },\n \"likelion-kr\": {\n primary: toUrl(likelionKrPrimary),\n black: toUrl(likelionKrBlack),\n white: toUrl(likelionKrWhite),\n },\n bootcamp: {\n primary: toUrl(bootcampPrimary),\n black: toUrl(bootcampBlack),\n white: toUrl(bootcampWhite),\n },\n symbol: {\n primary: toUrl(symbolPrimary),\n black: toUrl(symbolBlack),\n white: toUrl(symbolWhite),\n },\n favicon: {\n primary: toUrl(faviconPrimary),\n black: toUrl(faviconBlack),\n white: toUrl(faviconPrimary),\n },\n};\n","import React from \"react\";\nimport \"./logo.css\";\nimport { LOGO_URLS } from \"./logo-assets\";\n\nexport type LogoType =\n | \"likelion-eng\"\n | \"likelion-kr\"\n | \"bootcamp\"\n | \"symbol\"\n | \"favicon\"\n | \"og-image\";\n\nexport type LogoColor = \"primary\" | \"black\" | \"white\";\n\nexport type LogoSize = \"large\" | \"medium\" | \"small\" | \"favicon\" | \"og-image\";\n\nexport interface LogoProps extends React.HTMLAttributes<HTMLDivElement> {\n /** 로고 타입 */\n type?: LogoType;\n /** 로고 색상 */\n color?: LogoColor;\n /** 로고 크기 */\n size?: LogoSize;\n /** 서비스 타입 (og-image용) */\n service?: \"likelion\" | \"bootcamp\";\n}\n\nconst getLogoSrc = (type: LogoType, color: LogoColor) => {\n if (type in LOGO_URLS) {\n return LOGO_URLS[type][color];\n }\n return \"\";\n};\n\nconst LionIcon = ({ className: iconClassName }: { className?: string }) => (\n <img\n src={LOGO_URLS.symbol.white}\n alt=\"Lion Icon\"\n className={iconClassName}\n />\n);\n\n/**\n * Logo 컴포넌트는 브랜드 아이덴티티를 표현하는 로고 컴포넌트다.\n * `size` 외에 `className` 또는 `style`로 너비/높이를 직접 지정할 수 있다.\n */\nexport const Logo = ({\n type = \"likelion-kr\",\n color = \"primary\",\n size = \"medium\",\n service = \"likelion\",\n className = \"\",\n style,\n ...props\n}: LogoProps) => {\n const logoClasses = [\n \"logo\",\n `logo--${type}`,\n `logo--${color}`,\n `logo--${size}`,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const hasCustomSize = !!(className || style);\n const rootProps = hasCustomSize\n ? { ...props, className, style }\n : { ...props, className: `${logoClasses} ${className}`.trim(), style };\n\n const imgStyle = hasCustomSize\n ? { width: \"100%\", height: \"100%\", display: \"block\" as const, objectFit: \"contain\" as const }\n : { width: \"100%\", height: \"100%\", display: \"block\" as const };\n const innerStyle = hasCustomSize\n ? { width: \"100%\", height: \"100%\", display: \"flex\" as const, alignItems: \"center\", justifyContent: \"center\" }\n : undefined;\n\n const renderLogo = (content: React.ReactNode) => {\n if (hasCustomSize) {\n return (\n <div {...rootProps}>\n <div className={logoClasses} style={innerStyle}>\n {content}\n </div>\n </div>\n );\n }\n return <div {...rootProps}>{content}</div>;\n };\n\n // 멋쟁이사자처럼_ENG\n if (type === \"likelion-eng\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"likelion-eng\", color)}\n alt=\"멋쟁이사자처럼_ENG\"\n style={imgStyle}\n />\n );\n }\n\n // 멋쟁이사자처럼_KR\n if (type === \"likelion-kr\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"likelion-kr\", color)}\n alt=\"멋쟁이사자처럼_KR\"\n style={imgStyle}\n />\n );\n }\n\n // 멋사 부트캠프\n if (type === \"bootcamp\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"bootcamp\", color)}\n alt=\"멋사 부트캠프\"\n style={imgStyle}\n />\n );\n }\n\n const getText = () => null;\n\n // 심볼\n if (type === \"symbol\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"symbol\", color)}\n alt=\"심볼\"\n style={imgStyle}\n />\n );\n }\n\n // 파비콘\n if (type === \"favicon\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"favicon\", color)}\n alt=\"파비콘\"\n style={imgStyle}\n />\n );\n }\n\n // OG 이미지\n if (type === \"og-image\") {\n const ogText = service === \"likelion\" ? \"멋쟁이사자처럼\" : \"멋사 부트캠프\";\n const ogLogoSrc =\n service === \"likelion\"\n ? getLogoSrc(\"likelion-kr\", \"white\")\n : getLogoSrc(\"bootcamp\", \"white\");\n const ogContent = (\n <div className=\"logo__og-container\">\n <img\n src={ogLogoSrc}\n alt={ogText}\n style={{ width: \"auto\", height: \"37.8px\", display: \"block\" }}\n />\n </div>\n );\n return hasCustomSize ? (\n <div {...rootProps}>\n <div className={logoClasses} style={innerStyle}>\n {ogContent}\n </div>\n </div>\n ) : (\n <div {...rootProps}>{ogContent}</div>\n );\n }\n\n const text = getText();\n const fallbackContent = (\n <>\n <div className=\"logo__icon\">\n <LionIcon />\n </div>\n {text && <span className=\"logo__text\">{text}</span>}\n </>\n );\n return hasCustomSize ? (\n <div {...rootProps}>\n <div className={logoClasses} style={innerStyle}>\n {fallbackContent}\n </div>\n </div>\n ) : (\n <div {...rootProps}>{fallbackContent}</div>\n );\n};\n\nLogo.displayName = \"Logo\";\n","// Screen Foundation - 브레이크포인트 관련 유틸리티 export\nexport { useBreakpoint, useMediaQuery, BreakpointProvider } from \"../../shared/hooks/useMediaQuery\";\n\n// 브레이크포인트 상수 (기본 - Mobile/Tablet/Desktop)\nexport const BREAKPOINTS = {\n mobile: {\n min: 375,\n max: 743,\n },\n tablet: {\n min: 744,\n max: 1279,\n },\n desktop: {\n min: 1280,\n },\n} as const;\n\n// Tailwind Screens 설정 - 주요 브레이크포인트 (mo, tb, pc)\nexport const TAILWIND_SCREENS = {\n mo: \"375px\", // Mobile\n tb: \"744px\", // Tablet\n pc: \"1280px\", // Desktop\n} as const;\n\n// 미디어 쿼리 문자열\nexport const MEDIA_QUERIES = {\n mobile: \"(min-width: 375px) and (max-width: 743px)\",\n tablet: \"(min-width: 744px) and (max-width: 1279px)\",\n desktop: \"(min-width: 1280px)\",\n underTablet: \"(max-width: 743px)\",\n} as const;\n\n// 레이아웃 시스템 (Margin, Column, Gutter)\nexport const LAYOUT_SYSTEM = {\n mobile: {\n margin: 16, // 화면 가장자리 여백\n column: 4, // 컬럼 수\n gutter: 16, // 컬럼 사이 간격\n },\n tablet: {\n margin: 24,\n column: 8,\n gutter: 24,\n },\n desktop: {\n margin: 24,\n column: 12,\n gutter: 24,\n },\n} as const;\n","import React from \"react\";\nimport { DialogProvider } from \"./Dialog\";\nimport { ToastProvider } from \"./Toast\";\n\n/**\n * LIKELION Design System 통합 Provider\n * DialogProvider + ToastProvider를 하나로 감싸줍니다.\n */\nexport const LDSProvider = ({ children }: { children: React.ReactNode }) => {\n return (\n <DialogProvider>\n <ToastProvider>{children}</ToastProvider>\n </DialogProvider>\n );\n};\n"],"mappings":"mmBAAA,OAAOA,OAAW,QCAlB,OAAOC,OAAW,QAsCX,IAAMC,EAAOC,GAAM,WAAmC,CAACC,EAO3DC,IAAQ,CAPmD,IAAAC,EAAAF,EAC5D,SAAAG,EACA,WAAAC,EAAa,OACb,GAAAC,EACA,SAAAC,EACA,UAAAC,EAAY,EA3Cd,EAsC8DL,EAMzDM,EAAAC,EANyDP,EAMzD,CALH,UACA,aACA,KACA,WACA,cAIA,IAAMQ,GAAc,IAAM,CACxB,GAAIP,EAAQ,WAAW,UAAU,EAAG,CAClC,IAAMQ,EAAQR,EAAQ,MAAM,GAAG,EAAE,CAAC,EAClC,OAAIQ,EAAM,WAAW,GAAG,EACf,KAEFA,CACT,CACA,OAAIR,EAAQ,WAAW,WAAW,EACzB,KAEF,GACT,GAAG,EAEGS,EAAOP,GAAMK,EAEbG,EAAc,CAClB,aACA,eAAeV,CAAO,GACtBC,IAAe,QAAU,0BAA0BA,CAAU,GAC7DG,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OAAOR,GAAM,cAAca,EAAKE,EAAA,CAAE,IAAAb,EAAK,UAAWY,GAAgBL,GAASF,CAAQ,CACrF,CAAC,EAEDR,EAAK,YAAc,ODuBb,OAEI,OAAAiB,GAFJ,QAAAC,OAAA,oBA7FN,SAASC,GAAiBC,EAAwC,CAChE,GAAIC,GAAM,eAAeD,CAAI,GAAKA,EAAK,OAASE,EAC9C,OAAOD,GAAM,aAAaD,EAA6C,CAAE,GAAI,MAAO,CAAC,EAEvF,GAAIC,GAAM,eAAeD,CAAI,EAAG,CAC9B,IAA+BG,EAAAH,EAAK,MAA5B,UAAAI,CAVZ,EAUmCD,EAAVE,EAAAC,EAAUH,EAAV,CAAb,aACR,GAAIC,GAAY,KACd,OAAOH,GAAM,aACXD,EACAO,EAAAC,EAAA,GAAKH,GAAL,CAAW,SAAUJ,GAAM,SAAS,IAAIG,EAAUL,EAAgB,CAAE,EACtE,CAEJ,CACA,OAAOC,CACT,CA8BO,IAAMS,GAAeR,GAAM,WAAiD,CAACE,EAYjFO,IAAQ,CAZyE,IAAAC,EAAAR,EAClF,MAAAS,EAAO,SACP,MAAAC,EAAQ,UACR,KAAAC,EAAO,QACP,SAAAC,EAAW,SACX,MAAAC,EACA,WAAAC,EACA,WAAAC,EACA,QAAAC,EAAU,GACV,UAAAC,EAAY,GACZ,SAAAC,EAAW,EA3Db,EAiDoFV,EAW/EW,EAAAhB,EAX+EK,EAW/E,CAVH,OACA,QACA,OACA,WACA,QACA,aACA,aACA,UACA,YACA,aAGA,IAAMY,EAAaF,GAAYF,EAEzBK,EAAYL,GAAWL,IAAS,QAEhCW,EAAc,CAClB,gBACA,kBAAkBb,CAAI,GACtB,kBAAkBC,CAAK,GACvB,kBAAkBC,CAAI,GACtBU,GAAa,yBACbD,GAAc,0BACdH,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELM,EACAd,IAAS,SACJ,aACEA,IAAS,SAAWA,IAAS,SAC/B,cAEA,cAMX,OACEd,GAAC,SAAAS,EAAAC,EAAA,CACC,IAAKE,EACL,KAAMK,EACN,UAAWU,EACX,SAAUF,GACND,GALL,CAOC,UAAAxB,GAAC,QAAK,UAAU,yBACb,UAAAmB,GACCpB,GAAC,QAAK,UAAU,6BAA8B,SAAAoB,EAAW,EAE3DpB,GAAC,QAAK,UAAU,uBACd,SAAAA,GAACK,EAAA,CAAK,QAASwB,EAAa,GAAG,OAAQ,SAAA3B,GAAiBiB,CAAK,EAAE,EACjE,EACCE,GACCrB,GAAC,QAAK,UAAU,6BAA8B,SAAAqB,EAAW,GAE7D,EACCM,GACC3B,GAAC,QAAK,UAAU,yBAAyB,cAAY,OACnD,SAAAA,GAAC,OACC,UAAU,6BACV,QAAQ,YACR,KAAK,OACL,MAAM,6BAEN,SAAAC,GAAC,UACC,UAAU,gCACV,GAAG,KACH,GAAG,KACH,EAAE,KACF,OAAO,eACP,YAAY,IACZ,cAAc,QACd,gBAAgB,KAChB,iBAAiB,KAEjB,UAAAD,GAAC,WACC,cAAc,mBACd,IAAI,KACJ,OAAO,kBACP,YAAY,aACd,EACAA,GAAC,WACC,cAAc,oBACd,IAAI,KACJ,OAAO,YACP,YAAY,aACd,GACF,EACF,EACF,IAEJ,CAEJ,CAAC,EAEDY,GAAa,YAAc,eEpJ3B,OAAOkB,OAAW,QAgFZ,cAAAC,OAAA,oBA9CC,IAAMC,GAAaC,GAAM,WAA+C,CAACC,EAW7EC,IAAQ,CAXqE,IAAAC,EAAAF,EAC9E,MAAAG,EAAO,QACP,MAAAC,EAAQ,UACR,KAAAC,EAAO,QACP,KAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,EAAW,GACX,SAAAC,EAAW,SACX,MAAOC,EACP,OAAAC,CA3CF,EAkCgFT,EAU3EU,EAAAC,EAV2EX,EAU3E,CATH,OACA,QACA,OACA,OACA,YACA,WACA,WACA,QACA,WAGA,IAAMY,EAAaT,IAAS,OAEtBU,EAAaD,EACf,qBAAqBV,CAAK,GAC1B,gBAAgBA,CAAK,GACnBY,EAAYF,EAAa,oBAAsB,gBAAgBT,CAAI,GAEnEY,EAAc,CAClB,cACA,gBAAgBd,CAAI,GACpBY,EACAC,EACAR,GAAY,wBACZD,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAGLW,EAAaJ,GAAcN,EAEjC,OACEX,GAAC,SAAAsB,EAAAC,EAAA,CACC,IAAKnB,EACL,KAAMQ,EACN,UAAWQ,EACX,SAAUT,EACV,MAAOY,MAAA,GACFV,GACAC,GAAA,YAAAA,EAAQ,MACPO,EAAa,CAAE,QAAS,EAAG,cAAe,MAAO,EAAI,CAAC,IAExDN,GAVL,CAYC,SAAAf,GAAC,QAAK,UAAU,oBAAoB,MAAOc,GAAA,YAAAA,EAAQ,KAAO,SAAAL,EAAK,GACjE,CAEJ,CAAC,EAEDR,GAAW,YAAc,aCrFzB,OAAOuB,IAAS,YAAAC,GAAU,cAAAC,OAAkB,QCA5C,OAAOC,OAAW,QAuDV,cAAAC,OAAA,oBA7BD,IAAMC,GAAQC,GAAM,WAAwC,CAACC,EAOjEC,IAAQ,CAPyD,IAAAC,EAAAF,EAClE,MAAAG,EAAO,SACP,QAAAC,EAAU,UACV,MAAAC,EACA,SAAAC,EAAW,GACX,UAAAC,EAAY,EA/Bd,EA0BoEL,EAM/DM,EAAAC,EAN+DP,EAM/D,CALH,OACA,UACA,QACA,WACA,cAGA,IAAMQ,EAAc,CAClB,QACA,UAAUN,CAAO,GACjB,UAAUD,CAAI,GACdI,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELI,EACJR,IAAS,UAAYE,IAAU,OAC3B,OAAOA,GAAU,UACfA,EAAQC,EACN,GAAGA,CAAQ,IAEb,OAAOD,CAAK,EACd,KAEN,OACER,GAAC,OAAAe,EAAAC,EAAA,CAAK,IAAKZ,EAAK,UAAWS,GAAiBF,GAA3C,CACE,SAAAL,IAAS,UAAYQ,GACpBd,GAACiB,EAAA,CAAK,QAAQ,cAAc,GAAG,OAC5B,SAAAH,EACH,GAEJ,CAEJ,CAAC,EAEDb,GAAM,YAAc,QDMhB,OASE,OAAAiB,GATF,QAAAC,OAAA,oBAzCG,IAAMC,GAAMC,GAAwC,CAACC,EAWzDC,IAAQ,CAXiD,IAAAC,EAAAF,EAC1D,MAAAG,EAAO,QACP,KAAAC,EAAO,QACP,MAAAC,EAAQ,GACR,MAAAC,EACA,KAAAC,EAAO,GACP,UAAAC,EAAY,GACZ,SAAAC,EACA,SAAAC,EAAW,GACX,QAAAC,CArCF,EA4B4DT,EAUvDU,EAAAC,EAVuDX,EAUvD,CATH,OACA,OACA,QACA,QACA,OACA,YACA,WACA,WACA,YAIA,GAAM,CAACY,EAAiBC,CAAkB,EAAIC,GAAS,EAAK,EACtDC,EAAeR,IAAa,OAC5BS,EAAYD,EAAeR,EAAWK,EAEtCK,EAAeC,GAA2C,CAC1DV,IAECO,GAEHF,EAAoBM,GAAS,CAACA,CAAI,EAEpCV,GAAA,MAAAA,EAAUS,GACZ,EAEME,EAAQZ,EAAW,WAAcQ,EAAY,UAAY,UAEzDK,EAAc,CAClB,MACA,QAAQpB,CAAI,GACZ,QAAQC,CAAI,GACZ,QAAQkB,CAAK,GACbf,GAAQ,YACRC,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OACEX,GAAC,SAAA2B,EAAAC,EAAA,CACC,IAAKxB,EACL,KAAK,SACL,UAAWsB,EACX,eAAcL,EACd,SAAUR,EACV,QAASS,GACLP,GAPL,CASC,UAAAhB,GAAC,QAAK,UAAU,aAAc,SAAAU,EAAM,EACnCD,GACCT,GAAC8B,GAAA,CACC,KAAK,MACL,QAAQ,UACR,UAAU,aACV,aAAW,eACb,IAEJ,CAEJ,CAAC,EAED5B,GAAI,YAAc,MA0CX,IAAM6B,GAAW,CAAC,CACvB,MAAOC,EACP,aAAAC,EACA,SAAAC,EACA,KAAA3B,EAAO,QACP,KAAAC,EAAO,QACP,KAAAG,EAAO,GACP,SAAAG,EAAW,GACX,MAAAqB,EACA,SAAAC,EACA,IAAAC,EACA,UAAAzB,EAAY,GACZ,MAAA0B,CACF,IAAqB,CACnB,GAAM,CAACC,EAAeC,CAAgB,EAAIC,GAAM,SAC9CR,CACF,EACMZ,EAAeW,IAAc,OAC7BU,EAAQrB,EAAeW,EAAYO,EAEnCZ,EAAc,CAClB,YACA,cAAcpB,CAAI,GAClB,cAAcC,CAAI,GAClBG,GAAQ,kBACRG,GAAY,sBACZF,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL+B,EAA8Cd,IAAA,GAC9CQ,GAAO,MAAQ,CAAE,IAAK,OAAOA,GAAQ,SAAW,GAAGA,CAAG,KAAOA,CAAI,GAClEC,GAGCM,EAAiB,CAACC,EAAkBC,IACvCtB,GAA2C,CACrCH,GAAcmB,EAAiBK,CAAQ,EAC5CX,GAAA,MAAAA,EAAWW,GACXC,GAAA,MAAAA,EAAkBtB,EACpB,EAGIuB,EAAeZ,EACjBA,EAAM,IAAKa,GAAS,CAClB,IAAMC,EAAaP,IAAUM,EAAK,MAClC,OACEhD,GAACE,GAAA,CAEC,MAAO8C,EAAK,MACZ,MAAOA,EAAK,MACZ,MAAOA,EAAK,MACZ,KAAMzC,EACN,KAAMC,EACN,KAAMG,EACN,SAAUsC,EACV,SAAUnC,GAAYkC,EAAK,SAC3B,KAAK,MACL,gBAAeC,EACf,QAASL,EAAeI,EAAK,KAAK,GAX7BA,EAAK,KAYZ,CAEJ,CAAC,EACDP,GAAM,SAAS,IAAIL,EAAWc,GAAU,CArM9C,IAAA9C,EAAAE,EAAA6C,EAsMQ,GAAIV,GAAM,eAAyBS,CAAK,GAAKA,EAAM,OAAShD,GAAK,CAC/D,IAAM2C,EAAWK,EAAM,MAAM,MAC7B,GAAIL,IAAa,OACf,eAAQ,KAAK,wFAAsC,EAC5CK,EAGT,IAAMD,EAAaP,IAAUG,EAE7B,OAAOJ,GAAM,aAAaS,EAAO,CAC/B,MAAM9C,EAAA8C,EAAM,MAAM,OAAZ,KAAA9C,EAAoBG,EAC1B,MAAMD,EAAA4C,EAAM,MAAM,OAAZ,KAAA5C,EAAoBE,EAC1B,MAAM2C,EAAAD,EAAM,MAAM,OAAZ,KAAAC,EAAoBxC,EAC1B,SAAUsC,EACV,SAAUnC,GAAYoC,EAAM,MAAM,SAClC,KAAM,MACN,gBAAiBD,EACjB,QAASL,EAAeC,EAAUK,EAAM,MAAM,OAAO,CACvD,CAAC,CACH,CACA,OAAOA,CACT,CAAC,EAEL,OACElD,GAAC,OAAI,UAAW2B,EAAa,MAAOgB,EAAY,KAAK,UAClD,SAAAI,EACH,CAEJ,EAEAhB,GAAS,YAAc,WAEtB7B,GAAgD,MAAQ6B,GEtOzD,OAAOqB,OAAW,QCAlB,UAAYC,OAAW,QACvB,SAASC,GAAUC,EAIhBC,EAAQ,CAJQ,IAAAC,EAAAF,EACjB,OAAAG,EACA,QAAAC,CAHF,EACmBF,EAGdG,EAAAC,EAHcJ,EAGd,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,KAAM,OACN,QAAS,YACT,YAAa,IACb,OAAQ,eACR,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,cAAe,QACf,eAAgB,QAChB,EAAG,uBACL,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAS,EACpDS,GAAQD,GCzBf,UAAYE,OAAW,QACvB,SAASC,GAAUC,EAIhBC,EAAQ,CAJQ,IAAAC,EAAAF,EACjB,OAAAG,EACA,QAAAC,CAHF,EACmBF,EAGdG,EAAAC,EAHcJ,EAGd,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,KAAM,OACN,QAAS,YACT,YAAa,IACb,OAAQ,eACR,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,cAAe,QACf,eAAgB,QAChB,EAAG,sBACL,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAS,EACpDS,GAAQD,GFyFX,cAAAE,GAmEA,QAAAC,OAnEA,oBA/DJ,IAAMC,GAAgBC,GAAM,WAAyC,CAACC,EAoBnEC,IAAQ,CApB2D,IAAAC,EAAAF,EACpE,MAAAG,EAAO,QACP,KAAAC,EAAO,SACP,QAAAC,EAAU,UACV,MAAAC,EACA,SAAAC,EACA,QAASC,EACT,eAAAC,EAAiB,GACjB,cAAAC,EACA,eAAAC,EACA,MAAAC,EACA,WAAAC,EACA,WAAAC,EACA,UAAAC,EACA,UAAAC,EAAY,GACZ,QAAAC,EACA,UAAAC,EAAY,GACZ,SAAAC,EACA,QAAAC,CArEF,EAmDsElB,EAmBjEmB,EAAAC,EAnBiEpB,EAmBjE,CAlBH,OACA,OACA,UACA,QACA,WACA,UACA,iBACA,gBACA,iBACA,QACA,aACA,aACA,YACA,YACA,UACA,YACA,WACA,YAIA,GAAM,CAACqB,EAAiBC,CAAkB,EAAIzB,GAAM,SAASU,CAAc,EACrEgB,EAAejB,IAAgB,OAG/BkB,EAAU3B,GAAM,QAAQ,IACxB0B,EACKjB,EAE0BE,GAAkB,KAC5CA,IAAkBJ,EAEvBK,IAAmB,OACdA,EAAe,SAASL,CAAK,EAE/BiB,EACN,CACDE,EACAjB,EACAE,EACAC,EACAL,EACAiB,CACF,CAAC,EAGGI,EAAwB,GAExBD,IACEX,IAAc,GAEhBY,EAAwB,GACfZ,IAAc,GAEvBY,EAAwB,GAGxBA,EAAwBxB,IAAS,WAAa,CAACU,GAgBnD,IAAMe,EAAkBf,IAZEc,EACxB/B,GAACiC,GAAA,CACC,UAAU,mBACV,MAAO,CACL,MAAOzB,IAAS,QAAU,OAAS,OACnC,OAAQA,IAAS,QAAU,OAAS,MACtC,EACF,EACE,MAOE0B,EAAY,CAAC,CAACF,EACdG,EAAY,CAAC,EAAEjB,GAAcE,GAE7BgB,EACAF,GAAaC,EACR,0BACED,EACF,mBACEC,EACF,mBAEF,gBAGHE,EAAc,CAClB,OACA,SAAS9B,CAAI,GACb,SAASC,CAAI,GACb,SAASC,CAAO,GAChB2B,EACAN,GAAW,gBACXP,GAAY,iBACZD,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELgB,EAAeC,GAA2C,CAC1DhB,IAGF,CAACM,GACDf,IAAkB,QAClBC,IAAmB,QAEnBa,EAAoBY,GAAS,CAACA,CAAI,EAGhC7B,GACFA,EAASD,CAAK,EAGhBc,GAAA,MAAAA,EAAUe,GACZ,EAEME,EAAeF,GAA2C,CAC9DA,EAAE,gBAAgB,EACdlB,GAAW,CAACE,GACdF,EAAQkB,CAAC,CAEb,EAEA,OACEtC,GAAC,SAAAyC,EAAAC,EAAA,CACC,IAAKtC,EACL,KAAK,SACL,UAAWgC,EACX,SAAUd,EACV,QAASe,EACT,eAAcR,GACVL,GAPL,CASE,UAAAO,GACChC,GAAC,QAAK,UAAU,oBAAqB,SAAAgC,EAAgB,EAEvDhC,GAAC4C,EAAA,CAAK,QAASpC,IAAS,QAAU,UAAY,UAAY,SAAAQ,EAAM,EAC/DE,GAAc,CAACE,GACdpB,GAAC,QAAK,UAAU,oBAAqB,SAAAkB,EAAW,EAEjDE,GACCpB,GAAC,QACC,KAAK,SACL,SAAUuB,EAAW,GAAK,EAC1B,UAAU,qBACV,QAASkB,EACT,UAAYF,GAAM,CACZ,CAAChB,IAAagB,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAC/CA,EAAE,eAAe,EACjBE,EAAYF,CAAmD,EAEnE,EACA,aAAW,QACX,gBAAehB,EAEf,SAAAvB,GAAC,OACC,MAAM,6BACN,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OAEL,SAAAA,GAAC,QACC,EAAE,mmBACF,KAAK,eACL,YAAY,OACd,EACF,EACF,IAEJ,CAEJ,CAAC,EAiDY6C,GAAazC,GAcJ,CAdI,IAAAE,EAAAF,EACxB,OAAO0C,EACP,aAAAC,EACA,SAAApC,EACA,SAAAqC,EAAW,GACX,KAAAzC,EAAO,QACP,KAAAC,EAAO,SACP,QAAAC,EAAU,UACV,UAAAU,EACA,SAAAI,EAAW,GACX,MAAA0B,EACA,SAAAC,EACA,UAAA5B,EAAY,EAlSd,EAsR0BhB,EAarB6C,EAAAzB,EAbqBpB,EAarB,CAZH,QACA,eACA,WACA,WACA,OACA,OACA,UACA,YACA,WACA,QACA,WACA,cAGA,GAAM,CAAC8C,EAAeC,CAAgB,EAAIlD,GAAM,SAC9C,IAAM4C,GAAA,KAAAA,EAAiBC,EAAW,CAAC,EAAI,EACzC,EACMnB,EAAeiB,IAAc,OAC7BpC,EAAQmB,EAAeiB,EAAYM,EAEnCE,EAAgBC,GAAsB,CAC1C,GAAIP,EAAU,CACZ,IAAMQ,EAAO,MAAM,QAAQ9C,CAAK,EAAIA,EAAQ,CAAC,EACvC+C,EAAOD,EAAI,SAASD,CAAS,EAC/BC,EAAI,OAAQE,GAAMA,IAAMH,CAAS,EACjC,CAAC,GAAGC,EAAKD,CAAS,EACjB1B,GAAcwB,EAAiBI,CAAI,EACxC9C,GAAA,MAAAA,EAAW4C,EACb,MACO1B,GAAcwB,EAAiBE,CAAS,EAC7C5C,GAAA,MAAAA,EAAW4C,EAEf,EAEMzC,EAAgBkC,EAAW,OAAatC,EACxCK,EAAiBiC,EAAYtC,EAAqB,OAElD2B,EAAc,CAAC,aAAcf,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAGhEqC,EAAgBV,EAClBA,EAAM,IAAKW,GAAM,CAhUvB,IAAAxD,EAiUQ,OAAAJ,GAACE,GAAA,CAEC,MAAO0D,EAAK,MACZ,MAAOA,EAAK,MACZ,KAAMrD,EACN,KAAMC,EACN,QAASC,EACT,WAAWL,EAAAwD,EAAK,YAAL,KAAAxD,EAAkBe,EAC7B,WAAYyC,EAAK,WACjB,WAAYA,EAAK,WACjB,UAAWA,EAAK,UAChB,QAASA,EAAK,QACd,cAAe9C,EACf,eAAgBC,EAChB,SAAUuC,EACV,SAAU/B,GAAYqC,EAAK,UAdtBA,EAAK,KAeZ,EACD,EACDzD,GAAM,SAAS,IAAI+C,EAAWW,GAAU,CAnV9C,IAAAzD,EAAAE,EAAAwD,EAAAC,EAoVQ,OAAI5D,GAAM,eAA0B0D,CAAK,GAAKA,EAAM,OAASG,GACzCH,EAAM,MAAM,QACZ,QAChB,QAAQ,KAAK,0FAAwC,EAC9CA,GAGF1D,GAAM,aAAa0D,EAAO,CAC/B,MAAMzD,EAAAyD,EAAM,MAAM,OAAZ,KAAAzD,EAAoBG,EAC1B,MAAMD,EAAAuD,EAAM,MAAM,OAAZ,KAAAvD,EAAoBE,EAC1B,SAASsD,EAAAD,EAAM,MAAM,UAAZ,KAAAC,EAAuBrD,EAChC,WAAWsD,EAAAF,EAAM,MAAM,YAAZ,KAAAE,EAAyB5C,EACpC,cAAAL,EACA,eAAAC,EACA,SAAW2C,GAAc,CAlWrC,IAAAtD,EAAAE,EAmWcgD,EAAaI,CAAC,GACdpD,GAAAF,EAAAyD,EAAM,OAAM,WAAZ,MAAAvD,EAAA,KAAAF,EAAuBsD,EACzB,EACA,SAAUnC,GAAYsC,EAAM,MAAM,QACpC,CAAC,EAEIA,CACT,CAAC,EAEL,OACE7D,GAAC,MAAA0C,EAAAC,EAAA,CAAI,UAAWN,GAAiBc,GAAhC,CACE,SAAAQ,GACH,CAEJ,EAEAd,GAAU,YAAc,YACxB3C,GAAc,YAAc,OAErB,IAAM8D,GAAO,OAAO,OAAO9D,GAAe,CAC/C,MAAO2C,EACT,CAAC,EGxXD,OAAOoB,OAAW,QAClB,OAAS,gBAAAC,OAAoB,YCD7B,OAAgB,iBAAAC,GAAe,cAAAC,GAAY,wBAAAC,OAA4B,QAYrE,IAAMC,GAAoBH,GAA4C,IAAI,EAG7DI,GAAqBD,GAAkB,SAE/C,SAASE,GAAcC,EAAwB,CAgBpD,OAAOJ,GAdYK,GAAyB,CAC1C,IAAMC,EAAa,OAAO,WAAWF,CAAK,EAC1C,OAAAE,EAAW,iBAAiB,SAAUD,CAAQ,EACvC,IAAMC,EAAW,oBAAoB,SAAUD,CAAQ,CAChE,EAEoB,IACX,OAAO,WAAWD,CAAK,EAAE,QAGR,IACjB,EAG4D,CACvE,CAKO,SAASG,IAAgB,CAvChC,IAAAC,EAAAC,EAAAC,EAAAC,EAyCI,IAAMC,EAAeb,GAAWE,EAAiB,EAG3CY,EAAgBV,GAAc,2CAA2C,EACzEW,EAAgBX,GAAc,4CAA4C,EAC1EY,EAAiBZ,GAAc,qBAAqB,EACpDa,EAAqBb,GAAc,oBAAoB,EAK7D,MAAO,CACL,UAAUK,EAAAI,GAAA,YAAAA,EAAc,WAAd,KAAAJ,EAA0BK,EACpC,UAAUJ,EAAAG,GAAA,YAAAA,EAAc,WAAd,KAAAH,EAA0BK,EACpC,WAAWJ,EAAAE,GAAA,YAAAA,EAAc,YAAd,KAAAF,EAA2BK,EACtC,eAAeJ,EAAAC,GAAA,YAAAA,EAAc,gBAAd,KAAAD,EAA+BK,CAChD,CACF,CDgGE,mBAAAC,GACsB,OAAAC,GADtB,QAAAC,OAAA,oBAzIJ,IAAMC,GAAgBC,GAAM,cAGlB,IAAI,EA4DRC,GAAcC,GAoBD,CApBC,IAAAC,EAAAD,EAClB,MAAAE,EAAO,GACP,QAAAC,EACA,oBAAAC,EAAsB,GACtB,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,QAAAC,EAAU,UACV,MAAAC,EAGA,MAAAC,EACA,YAAAC,EACA,KAAAC,EACA,YAAAC,EACA,aAAAC,EAAe,aACf,MAAAC,EAEA,UAAAC,EAAY,GACZ,SAAAC,CAlGF,EAgFoBf,EAmBfgB,EAAAC,EAnBejB,EAmBf,CAlBH,OACA,UACA,sBACA,aACA,YACA,UACA,QAGA,QACA,cACA,OACA,cACA,eACA,QAEA,YACA,aAGA,GAAM,CAAE,cAAAkB,CAAc,EAAIC,GAAc,EAGlC,CAACC,EAASC,CAAU,EAAIxB,GAAM,SAAS,EAAK,EA6BlD,GA5BAA,GAAM,UAAU,KACdwB,EAAW,EAAI,EACR,IAAMA,EAAW,EAAK,GAC5B,CAAC,CAAC,EAELxB,GAAM,UAAU,IAAM,CACpB,GAAI,CAACI,EAAM,OAGX,IAAMqB,EAAgB,OAAO,iBAAiB,SAAS,IAAI,EAAE,SAG7D,GAFA,SAAS,KAAK,MAAM,SAAW,SAE3BlB,EAAY,CACd,IAAMmB,EAAiBC,GAAqB,CACtCA,EAAE,MAAQ,WAAUtB,GAAA,MAAAA,IAC1B,EACA,cAAO,iBAAiB,UAAWqB,CAAa,EACzC,IAAM,CACX,OAAO,oBAAoB,UAAWA,CAAa,EACnD,SAAS,KAAK,MAAM,SAAWD,CACjC,CACF,CAEA,MAAO,IAAM,CACX,SAAS,KAAK,MAAM,SAAWA,CACjC,CACF,EAAG,CAACrB,EAAMG,EAAYF,CAAO,CAAC,EAE1B,CAACD,EAAM,OAAO,KAElB,IAAMwB,EAAgBlB,GAAA,KAAAA,EAAUD,IAAY,QAAU,OAAS,SACzDoB,EAAc,CAClB,SACA,WAAWpB,CAAO,GAClB,WAAWmB,CAAa,GACxBP,EAAgB,YAAc,GAC9BJ,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELa,EAAsBH,GAAwC,CAC9DA,EAAE,SAAWA,EAAE,eAAiBrB,IAClCD,GAAA,MAAAA,IAEJ,EAGM0B,EACJjC,GAAAF,GAAA,CACI,WAAAe,GAASE,IAAShB,GAACmC,GAAA,CAAa,MAAOrB,EAAO,KAAME,EAAM,EAC3DD,GAAef,GAACoC,GAAA,CAAY,SAAArB,EAAY,EACxCM,EACAJ,GAAeA,EAAY,OAAS,GACnCjB,GAACqC,GAAA,CAAa,OAAQnB,EACnB,SAAAD,EAAY,IAAI,CAACqB,EAAMC,IAAK,CAhKvC,IAAAlC,EAiKY,OAAAL,GAACwC,GAAA,CAEC,MAAOF,EAAK,MACZ,MAAOA,EAAK,MACZ,KAAMA,EAAK,KACX,KAAMA,EAAK,KACX,WAAYA,EAAK,WACjB,WAAYA,EAAK,WACjB,QAASA,EAAK,QACd,SAAUA,EAAK,SACf,QAASA,EAAK,QACd,cAAcjC,EAAAiC,EAAK,eAAL,KAAAjC,EAAqB,IAV9B,GAAGiC,EAAK,KAAK,IAAIC,CAAG,EAW3B,EACD,EACH,GAEJ,EAGIE,EACJzC,GAAC,OACC,UAAU,iBACV,KAAK,eACL,QAASiC,EAET,SAAAjC,GAAC,MAAA0C,EAAAC,EAAA,CAAI,UAAWX,EAAa,KAAK,SAAS,aAAW,OAAO,MAAOb,GAAS,KAAO,CAAE,MAAAA,CAAM,EAAI,QAAeG,GAA9G,CACC,SAAArB,GAACC,GAAc,SAAd,CAAuB,MAAO,CAAE,QAAAM,EAAS,QAAAI,CAAQ,EAC/C,UAAAD,GACCX,GAAC,UACC,KAAK,SACL,UAAU,gBACV,QAASQ,EACT,aAAW,eAEX,SAAAR,GAAC4C,GAAA,CAAU,UAAU,qBAAqB,EAC5C,EAEDV,GACH,GACF,EACF,EAUF,OAAKR,EAEEmB,GAAaJ,EAAe,SAAS,IAAI,EAF3B,IAGvB,EAUMN,GAAgB9B,GAMG,CANH,IAAAC,EAAAD,EACpB,OAAAS,EACA,KAAAE,EACA,UAAAI,EAAY,GACZ,SAAAC,CApOF,EAgOsBf,EAKjBgB,EAAAC,EALiBjB,EAKjB,CAJH,QACA,OACA,YACA,aAGA,GAAM,CAAE,cAAAkB,CAAc,EAAIC,GAAc,EACxC,OACExB,GAAC,MAAAyC,EAAAC,EAAA,CAAI,UAAW,kBAAkBvB,CAAS,IAAQE,GAAlD,CACE,UAAAN,GAAQhB,GAAC,QAAK,UAAU,eAAgB,SAAAgB,EAAK,EAC7CF,GACCd,GAAC8C,EAAA,CAAK,QAAStB,EAAgB,cAAgB,aAC5C,SAAAV,EACH,EAEDO,IACH,CAEJ,EAIMe,GAAc/B,GAA4D,CAA5D,IAAAC,EAAAD,EAAE,WAAAe,EAAY,GAAI,SAAAC,CAvPtC,EAuPoBf,EAA+BgB,EAAAC,EAA/BjB,EAA+B,CAA7B,YAAgB,aACpC,OACEN,GAAC,MAAA0C,EAAAC,EAAA,CAAI,UAAW,gBAAgBvB,CAAS,IAAQE,GAAhD,CACC,SAAAtB,GAAC,OAAI,UAAU,4BAA6B,SAAAqB,EAAS,GACvD,CAEJ,EAOMgB,GAAgBhC,GAKG,CALH,IAAAC,EAAAD,EACpB,QAAA0C,EAAS,aACT,UAAA3B,EAAY,GACZ,SAAAC,CAvQF,EAoQsBf,EAIjBgB,EAAAC,EAJiBjB,EAIjB,CAHH,SACA,YACA,aAGA,IAAM0C,EACJD,IAAW,WACP,4BACA,8BAEN,OACE/C,GAAC,MAAA0C,EAAAC,EAAA,CACC,UAAW,kCAAkCI,CAAM,IAAI3B,CAAS,IAC5DE,GAFL,CAIC,SAAAtB,GAAC,OAAI,UAAW,mBAAmBgD,CAAW,GAAK,SAAA3B,EAAS,GAC9D,CAEJ,EAiBMmB,GAAgBnC,GAaG,CAbH,IAAAC,EAAAD,EACpB,OAAA4C,EACA,MAAAC,EACA,KAAAC,EACA,KAAAC,EACA,WAAAC,EACA,WAAAC,EACA,QAAAC,EACA,SAAAC,EACA,QAAAC,EACA,aAAAC,EAAe,GACf,MAAAC,CAnTF,EAwSsBrD,EAYjBgB,EAAAC,EAZiBjB,EAYjB,CAXH,QACA,QACA,OACA,OACA,aACA,aACA,UACA,WACA,UACA,eACA,UAnTF,IAAAD,EAsTE,IAAMuD,EAAUzD,GAAM,WAAWD,EAAa,EACxC,CAAE,cAAAsB,CAAc,EAAIC,GAAc,EAGlCb,GAAUP,EAAAuD,GAAA,YAAAA,EAAS,UAAT,KAAAvD,EAAoB,UAC9BwD,EAAcjD,IAAY,UAAY,OAAS,OAC/CkD,EACJlD,IAAY,QAAWY,EAAgB,QAAU,SAAY,QACzDuC,EAAcnD,IAAY,QAAU,UAAY,QAChDoD,EAAe,UAEfC,EAAenC,GAA2C,CAjUlE,IAAAzB,EAkUIoD,GAAA,MAAAA,EAAU3B,GACN4B,KACFrD,EAAAuD,GAAA,YAAAA,EAAS,UAAT,MAAAvD,EAAA,KAAAuD,GAEJ,EAEA,OACE5D,GAACkE,GAAAvB,EAAA,CACC,MAAOM,EACP,KAAMG,GAAA,KAAAA,EAAQU,EACd,MAAOZ,GAAA,KAAAA,EAASc,EAChB,KAAMb,GAAA,KAAAA,EAAQY,EACd,WAAYV,EACZ,WAAYC,EACZ,QAASC,EACT,SAAUC,EACV,QAASS,EACT,MAAOtB,EAAA,CAAE,MAAOkB,GAAgBF,IAC5BrC,EACN,CAEJ,EAIAlB,GAAW,YAAc,SAElB,IAAM+D,GAAS,OAAO,OAAO/D,GAAY,CAC9C,OAAQ+B,GACR,KAAMC,GACN,OAAQC,GACR,OAAQG,EACV,CAAC,EAwCK4B,GAAsBjE,GAAM,cAChC,MACF,EAEakE,GAAiB,CAAC,CAAE,SAAAhD,CAAS,IAAqC,CAC7E,GAAM,CAACiD,EAASC,CAAU,EAAIpE,GAAM,SAElC,CAAC,CAAC,EAEEqE,EAAQrE,GAAM,YAAasE,GAAe,CAC9CF,EAAYG,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAOF,CAAE,CAAC,CACtD,EAAG,CAAC,CAAC,EAECG,EAAWzE,GAAM,YAAY,IAAM,CACvCoE,EAAW,CAAC,CAAC,CACf,EAAG,CAAC,CAAC,EAEChE,EAAOJ,GAAM,YAChB0E,GAA2B,CAC1B,IAAMJ,EAAKI,EAAQ,IAAM,UAAU,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,GAC9D,OAAAN,EAAYG,GAAS,CAAC,GAAGA,EAAMhC,EAAAC,EAAA,GAAKkC,GAAL,CAAc,GAAAJ,CAAG,EAAC,CAAC,EAC3CA,CACT,EACA,CAAC,CACH,EAEMK,EAAQ3E,GAAM,YACjB0E,GACQ,IAAI,QAAeE,GAAY,CAta5C,IAAA1E,EAAAC,EAuaQ,IAAMmE,EAAK,SAAS,KAAK,IAAI,CAAC,GAC9BlE,EAAKmC,EAAAC,EAAA,GACAkC,GADA,CAEH,GAAAJ,EACA,SAASpE,EAAAwE,EAAQ,UAAR,KAAAxE,EAAmB,QAC5B,QAAS,CACP,CACE,OAAOC,EAAAuE,EAAQ,eAAR,KAAAvE,EAAwB,eAC/B,MAAO,UACP,KAAM,QACN,aAAc,GACd,QAAS,SAAY,CAlbnC,IAAAD,EAmbgB,OAAMA,EAAAwE,EAAQ,YAAR,YAAAxE,EAAA,KAAAwE,IACNE,EAAQ,CACV,CACF,CACF,EACA,QAAS,IAAM,CACbA,EAAQ,EACRP,EAAMC,CAAE,CACV,CACF,EAAC,CACH,CAAC,EAEH,CAAClE,EAAMiE,CAAK,CACd,EAEMQ,EAAU7E,GAAM,YACnB0E,GACQ,IAAI,QAAkBE,GAAY,CApc/C,IAAA1E,EAAAC,EAAA2E,EAqcQ,IAAMR,EAAK,WAAW,KAAK,IAAI,CAAC,GAChClE,EAAKmC,EAAAC,EAAA,GACAkC,GADA,CAEH,GAAAJ,EACA,SAASpE,EAAAwE,EAAQ,UAAR,KAAAxE,EAAmB,UAC5B,QAAS,CACP,CACE,OAAOC,EAAAuE,EAAQ,cAAR,KAAAvE,EAAuB,eAC9B,MAAO,UACP,KAAM,UACN,aAAc,GACd,QAAS,SAAY,CAhdnC,IAAAD,EAidgB,OAAMA,EAAAwE,EAAQ,WAAR,YAAAxE,EAAA,KAAAwE,IACNE,EAAQ,EAAK,CACf,CACF,EACA,CACE,OAAOE,EAAAJ,EAAQ,eAAR,KAAAI,EAAwB,eAC/B,MAAO,UACP,KAAM,QACN,aAAc,GACd,QAAS,SAAY,CA1dnC,IAAA5E,EA2dgB,OAAMA,EAAAwE,EAAQ,YAAR,YAAAxE,EAAA,KAAAwE,IACNE,EAAQ,EAAI,CACd,CACF,CACF,EACA,QAAS,IAAM,CACbA,EAAQ,EAAK,EACbP,EAAMC,CAAE,CACV,CACF,EAAC,CACH,CAAC,EAEH,CAAClE,EAAMiE,CAAK,CACd,EAEA,OACEvE,GAACmE,GAAoB,SAApB,CACC,MAAO,CAAE,KAAA7D,EAAM,MAAAiE,EAAO,SAAAI,EAAU,MAAAE,EAAO,QAAAE,CAAQ,EAE9C,UAAA3D,EAEAiD,EAAQ,IAAKY,GACZlF,GAACI,GAAA,CAEC,KAAM,GACN,QAAS,IAAM,CApfzB,IAAAC,GAqfYA,EAAA6E,EAAO,UAAP,MAAA7E,EAAA,KAAA6E,GACAV,EAAMU,EAAO,EAAE,CACjB,EACA,QAASA,EAAO,QAChB,MAAOA,EAAO,MACd,oBAAqBA,EAAO,oBAC5B,WAAYA,EAAO,WACnB,UAAWA,EAAO,UAElB,MAAOA,EAAO,MACd,YAAaA,EAAO,YACpB,KAAMA,EAAO,KACb,YAAaA,EAAO,SAffA,EAAO,EAgBd,CACD,GACH,CAEJ,EAEO,SAASC,IAAY,CAC1B,IAAMvB,EAAUzD,GAAM,WAAWiE,EAAmB,EACpD,GAAI,CAACR,EACH,MAAM,IAAI,MAAM,gDAAgD,EAElE,OAAOA,CACT,CE9gBA,OAAOwB,OAAW,QA4FR,cAAAC,GAcA,QAAAC,OAdA,oBApEH,IAAMC,GAASC,GAAM,WAC1B,CACEC,EAaAC,IACG,CAdH,IAAAC,EAAAF,EACE,MAAAG,EAAO,SACP,MAAAC,EACA,cAAAC,EAAgB,MAChB,YAAAC,EACA,QAASC,EACT,eAAAC,EAAiB,GACjB,SAAAC,EACA,SAAAC,EACA,UAAAC,EAAY,GACZ,GAAAC,CApCN,EA0BIV,EAWKW,EAAAC,EAXLZ,EAWK,CAVH,OACA,QACA,gBACA,cACA,UACA,iBACA,WACA,WACA,YACA,OAKF,IAAMa,EAAWhB,GAAM,OAAyB,IAAI,EAC9CiB,EAAcjB,GAAM,QAAQ,IAC5B,OAAOE,GAAQ,WACTgB,GAAkC,CACxCF,EAAS,QAAUE,EACnBhB,EAAIgB,CAAI,CACV,EACShB,EACDgB,GAAkC,CACxCF,EAAS,QAAUE,EACfhB,IAAKA,EAAI,QAAUgB,EACzB,EAEMA,GAAkC,CACxCF,EAAS,QAAUE,CACrB,EACC,CAAChB,CAAG,CAAC,EAGF,CAACiB,EAAiBC,CAAkB,EACxCpB,GAAM,SAASS,CAAc,EACzBY,EAAeb,IAAgB,OAC/Bc,EAAUD,EAAeb,EAAcW,EAEvCI,EAAgBC,GAA2C,CAC3Db,IAECU,GACHD,EAAmBI,EAAE,OAAO,OAAO,EAGrCd,GAAA,MAAAA,EAAWc,GACb,EAEMC,EAAczB,GAAM,MAAM,EAC1B0B,EAAWb,GAAMY,EACjBE,EAAgBpB,EAAc,GAAGmB,CAAQ,eAAiB,OAE1DE,EAAc,CAClB,SACA,WAAWxB,CAAI,GACfE,IAAkB,SAAW,sBAC7BK,GAAY,mBACZC,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OACEd,GAAC,OAAI,UAAW8B,EACd,UAAA9B,GAAC,OAAI,UAAU,kBACb,UAAAD,GAAC,QAAAgC,EAAA,CACC,IAAKZ,EACL,KAAK,WACL,GAAIS,EACJ,QAASJ,EACT,eAAgBb,EAChB,SAAUc,EACV,SAAUZ,EACV,mBAAkBgB,EAClB,UAAU,gBACV,KAAK,SACL,eAAcL,GACVR,EACN,EACAhB,GAAC,SAAM,QAAS4B,EAAU,UAAU,wBACjC,UAAApB,IAAkB,SAAWD,GAC5BR,GAACiC,EAAA,CACC,QAAS1B,IAAS,SAAW,UAAY,UACzC,GAAG,OAEF,SAAAC,EACH,EAEFR,GAAC,QAAK,UAAU,iBACd,SAAAA,GAAC,QAAK,UAAU,gBAAgB,EAClC,EACCS,IAAkB,OAASD,GAC1BR,GAACiC,EAAA,CACC,QAAS1B,IAAS,SAAW,UAAY,UACzC,GAAG,OAEF,SAAAC,EACH,GAEJ,GACF,EACCE,GACCV,GAAC,OAAI,GAAI8B,EAAe,UAAU,sBAC/B,SAAApB,EACH,GAEJ,CAEJ,CACF,EAEAR,GAAO,YAAc,SC1IrB,OAAOgC,OAAW,QAElB,OACE,uBAAAC,GACA,kBAAAC,GACA,+BAAAC,OACK,mBAoGG,cAAAC,GAYA,QAAAC,OAZA,oBA9EH,IAAMC,GAAWC,GAAM,WAC5B,CACEC,EAcAC,IACG,CAfH,IAAAC,EAAAF,EACE,OAAAG,EACA,WAAAC,EACA,YAAAC,EACA,MAAAC,EACA,QAASC,EACT,eAAAC,EAAiB,GACjB,SAAAC,EACA,SAAAC,EACA,cAAAC,EAAgB,GAChB,UAAAC,EAAY,GACZ,GAAAC,CAzCN,EA8BIX,EAYKY,EAAAC,EAZLb,EAYK,CAXH,QACA,aACA,cACA,QACA,UACA,iBACA,WACA,WACA,gBACA,YACA,OAzCN,IAAAF,EAAAE,EA8CI,IAAMc,EAAWjB,GAAM,OAAyB,IAAI,EAC9CkB,EAAclB,GAAM,QAAQ,IAC5B,OAAOE,GAAQ,WACTiB,GAAkC,CACxCF,EAAS,QAAUE,EACnBjB,EAAIiB,CAAI,CACV,EACSjB,EACDiB,GAAkC,CACxCF,EAAS,QAAUE,EACfjB,IAAKA,EAAI,QAAUiB,EACzB,EAEMA,GAAkC,CACxCF,EAAS,QAAUE,CACrB,EACC,CAACjB,CAAG,CAAC,EAGRF,GAAM,UAAU,IAAM,CAChBiB,EAAS,UACXA,EAAS,QAAQ,cAAgBL,EAErC,EAAG,CAACA,CAAa,CAAC,EAGlB,GAAM,CAACQ,EAAiBC,CAAkB,EAAIrB,GAAM,SAASS,CAAc,EACrEa,EAAed,IAAgB,OAC/Be,EAAUD,EAAed,EAAcY,EAEvCI,EAAgBC,GAA2C,CAC3Dd,IAECW,GACHD,EAAmBI,EAAE,OAAO,OAAO,EAGrCf,GAAA,MAAAA,EAAWe,GACb,EAEMC,EAAc1B,GAAM,MAAM,EAC1B2B,EAAab,GAAMY,EACnBE,EAAgBtB,EAAc,GAAGqB,CAAU,eAAiB,OAE5DE,EAAc,CAClB,WACAlB,GAAY,qBACZE,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELiB,EAAqBzB,GAAA,KAAAA,EAAc,CAAC,EACpC0B,EAAiB,CAAC,uBAAwBD,EAAmB,SAAS,EACzE,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OACEhC,GAAC,OAAI,UAAW+B,EACd,UAAA/B,GAAC,OAAI,UAAU,oBACb,UAAAD,GAAC,QAAAmC,EAAA,CACC,IAAKd,EACL,KAAK,WACL,GAAIS,EACJ,QAASJ,EACT,SAAUC,EACV,SAAUb,EACV,MAAOJ,EACP,mBAAkBqB,GAAiB,OACnC,UAAU,mBACNb,EACN,EACAjB,GAAC,SAAM,QAAS6B,EAAY,UAAU,0BACpC,UAAA9B,GAAC,QAAK,UAAU,yBAAyB,cAAY,OAClD,SAAAe,EACCf,GAACoC,GAAA,CAA4B,UAAU,iBAAiB,EACtDV,EACF1B,GAACqC,GAAA,CAAe,UAAU,iBAAiB,EAE3CrC,GAACsC,GAAA,CAAoB,UAAU,iBAAiB,EAEpD,EACC/B,GACCP,GAACuC,EAAAC,EAAAL,EAAA,CACC,SAAS/B,EAAA6B,EAAmB,UAAnB,KAAA7B,EAA8B,UACvC,IAAIE,EAAA2B,EAAmB,KAAnB,KAAA3B,EAAyB,QACzB2B,GAHL,CAIC,UAAWC,EAEV,SAAA3B,GACH,GAEJ,GACF,EACCE,GACCT,GAAC,OAAI,GAAI+B,EAAe,UAAU,wBAC/B,SAAAtB,EACH,GAEJ,CAEJ,CACF,EAEAP,GAAS,YAAc,WA8ChB,IAAMuC,GAAgB,CAAC,CAC5B,MAAAlC,EACA,WAAAC,EACA,YAAAC,EACA,iBAAAiC,EACA,SAAAC,EAAW,GACX,MAAOC,EACP,aAAAC,EAAe,CAAC,EAChB,SAAAhC,EACA,SAAAC,EACA,MAAAgC,EACA,SAAAC,EACA,UAAA/B,EAAY,EACd,IAA0B,CAjN1B,IAAAZ,EAAAE,EAAA0C,EAAAC,EAkNE,GAAM,CAACC,EAAeC,CAAgB,EAAIhD,GAAM,SAAmB0C,CAAY,EACzEpB,EAAemB,IAAc,OAC7BlC,EAAQe,EAAemB,EAAYM,EAEnCvB,EAAe,CAACyB,EAAuB1B,IAAqB,CAChE,IAAM2B,EAAWV,EACbjB,EACE,CAAC,GAAGhB,EAAO0C,CAAa,EACxB1C,EAAM,OAAQ4C,GAAMA,IAAMF,CAAa,EACzC1B,EACE,CAAC0B,CAAa,EACd,CAAC,EAEF3B,GACH0B,EAAiBE,CAAQ,EAG3BxC,GAAA,MAAAA,EAAWwC,EACb,EAEME,EAAUpD,GAAM,MAAM,EACtB4B,EAAgBtB,EAAc,GAAG8C,CAAO,eAAiB,OAEzDC,EAA0BhD,GAAA,KAAAA,EAAc,CAAC,EACzCiD,EAAgCf,GAAA,KAAAA,EAAoB,CAAC,EACrDgB,EAAsB,CAAC,wBAAyBF,EAAwB,SAAS,EACpF,OAAO,OAAO,EACd,KAAK,GAAG,EACLG,EAA4B,CAChC,8BACAF,EAA8B,SAChC,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELzB,EAAc,CAClB,iBACAlB,GAAY,2BACZE,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAGL4C,EAAkBd,EACpBA,EAAM,IAAKe,GACT7D,GAACE,GAAA,CAEC,MAAO2D,EAAK,MACZ,MAAOA,EAAK,MACZ,YAAaA,EAAK,YAClB,QAASnD,EAAM,SAASmD,EAAK,KAAK,EAClC,SAAWjC,GAA2C,CACpDD,EAAakC,EAAK,MAAOjC,EAAE,OAAO,OAAO,CAC3C,EACA,SAAUd,GAAY+C,EAAK,UARtBA,EAAK,KASZ,CACD,EACD1D,GAAM,SAAS,IAAI4C,EAAWe,GAAU,CACtC,GAAI3D,GAAM,eAA8B2D,CAAK,GAAKA,EAAM,OAAS5D,GAAU,CACzE,IAAMkD,EAAgBU,EAAM,MAAM,MAClC,GAAIV,IAAkB,OACpB,eAAQ,KAAK,kGAAgD,EACtDU,EAGT,IAAMC,EAAYrD,EAAM,SAAS0C,CAAa,EAE9C,OAAOjD,GAAM,aAAa2D,EAAO,CAC/B,QAASC,EACT,SAAWnC,GAA2C,CAxRlE,IAAAxB,EAAAE,EAyRcqB,EAAayB,EAAexB,EAAE,OAAO,OAAO,GAC5CtB,GAAAF,EAAA0D,EAAM,OAAM,WAAZ,MAAAxD,EAAA,KAAAF,EAAuBwB,EACzB,EACA,SAAUd,GAAYgD,EAAM,MAAM,QACpC,CAAC,CACH,CACA,OAAOA,CACT,CAAC,EAEL,OACE7D,GAAC,OAAI,UAAW+B,EACb,UAAAzB,GACCP,GAACuC,EAAAC,EAAAL,EAAA,CACC,SAAS/B,EAAAoD,EAAwB,UAAxB,KAAApD,EAAmC,cAC5C,IAAIE,EAAAkD,EAAwB,KAAxB,KAAAlD,EAA8B,OAC9BkD,GAHL,CAIC,UAAWE,EAEV,SAAAnD,GACH,EAEDE,GACCT,GAACuC,EAAAC,EAAAL,EAAA,CACC,GAAIJ,EACJ,SAASiB,EAAAS,EAA8B,UAA9B,KAAAT,EAAyC,UAClD,IAAIC,EAAAQ,EAA8B,KAA9B,KAAAR,EAAoC,OACpCQ,GAJL,CAKC,UAAWE,EAEV,SAAAlD,GACH,EAEFT,GAAC,OAAI,UAAU,0BACZ,SAAA4D,EACH,GACF,CAEJ,EAEAnB,GAAc,YAAc,gBAG3BvC,GAA+D,MAAQuC,GCnUxE,OAAOuB,OAAW,QA8CX,SAASC,GACdC,EACwB,CACxB,GAAM,CACJ,QAAAC,EACA,aAAAC,EAAe,CAAC,EAChB,MAAOC,EACP,SAAUC,CACZ,EAAIJ,EAEE,CAACK,EAAeC,CAAgB,EAAIR,GAAM,SAC9CI,CACF,EACMK,EAAeJ,IAAc,OAC7BK,EAAQD,EAAeJ,EAAYE,EAEnCI,EAAWX,GAAM,YACpBY,GAAuB,CACjBH,GAAcD,EAAiBI,CAAQ,EAC5CN,GAAA,MAAAA,EAAeM,EACjB,EACA,CAACH,EAAcH,CAAY,CAC7B,EAEMO,EAAcH,EAAM,SAAWP,EAAQ,OACvCW,EAAeJ,EAAM,OAAS,EAC9BK,EAAmBF,EACnBG,EAAyBF,GAAgB,CAACD,EAE1CI,EAAkBjB,GAAM,YAC3BkB,GAA2C,CAC1CP,EAASO,EAAE,OAAO,QAAU,CAAC,GAAGf,CAAO,EAAI,CAAC,CAAC,CAC/C,EACA,CAACA,EAASQ,CAAQ,CACpB,EAEA,MAAO,CACL,MAAAD,EACA,SAAAC,EACA,iBAAAI,EACA,uBAAAC,EACA,gBAAAC,EACA,eAAgB,CACd,QAASF,EACT,cAAeC,EACf,SAAUC,CACZ,CACF,CACF,CC9FA,OAAOE,OAAW,QCAlB,OAAgB,YAAAC,GAAU,SAAAC,GAAO,cAAAC,OAAkB,QCAnD,UAAYC,OAAW,QACvB,SAASC,GAAsBC,EAI5BC,EAAQ,CAJoB,IAAAC,EAAAF,EAC7B,OAAAG,EACA,QAAAC,CAHF,EAC+BF,EAG1BG,EAAAC,EAH0BJ,EAG1B,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,QAAS,YACT,KAAM,eACN,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,SAAU,UACV,EAAG,kJACH,SAAU,SACZ,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAqB,EAChES,GAAQD,GDmJP,OAgJ2B,YAAAE,GAhJ3B,OAAAC,GAwFA,QAAAC,OAxFA,oBApER,IAAMC,GACJC,GACgCA,EAAM,OAAS,OAOpCC,GAAYC,GAGvB,CAACF,EAAOG,IAAQ,CAChB,IAsBIC,GAAAJ,EArBF,MAAAK,EAAO,QACP,SAAAC,EAAW,GACX,KAAAC,EACA,MAAAC,EAAQ,GACR,YAAAC,EACA,MAAAC,EACA,UAAAC,EACA,UAAWC,EAAgB,GAC3B,MAAAC,EACA,WAAAC,EAAa,GACb,UAAAC,EAAY,GACZ,MAAAC,EACA,GAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,SAAAC,EACA,QAAAC,EACA,OAAAC,CAvIJ,EAyIMpB,GADCqB,EAAAC,EACDtB,GADC,CApBH,OACA,WACA,OACA,QACA,cACA,QACA,YACA,YACA,QACA,aACA,YACA,QACA,KACA,QACA,eACA,WACA,WACA,WACA,UACA,WAIIuB,EAAcC,GAAM,EACpBC,EAAUZ,GAAM,aAAaU,CAAW,GACxC,CAACG,EAASC,CAAU,EAAIC,GAAS,EAAK,EAGtCC,EACJ1B,IAAS,OACL,aACAA,IAAS,SACP,KACAA,IAAS,QACP,KACAA,EAGJ2B,EAAehB,IAAU,OACzB,CAACiB,EAAeC,CAAgB,EAAIJ,GAASb,GAAA,KAAAA,EAAgB,EAAE,EAC/DkB,EAAeH,EAAehB,EAAQiB,EAEtCG,EAA6B9B,EAAQ,QAAU,UAC/C+B,EAAQ5B,EACV,GAAG,OAAO0B,CAAY,EAAE,MAAM,IAAI1B,CAAS,GAC3C,OACE6B,EAAY5B,GAAiB,EAAQ2B,EACrC,CAACE,EAAYC,CAAU,EAC3B,OAAOH,GAAU,UAAYA,EAAM,SAAS,GAAG,EAC3CA,EAAM,MAAM,GAAG,EACf,CAACA,EAAO,MAAS,EACjBI,EACJ,OAAO7B,GAAe,UACpBA,EACEjB,GAAC+C,GAAA,CAAsB,UAAU,sBAAsB,EACrD,KAEJ9B,EAEE+B,GAAcrC,EAAQ,QAAU,SAEhCsC,EAASzC,IAAS,OAGlB0C,EACJC,GACG,CACHjB,EAAW,EAAI,EACdR,GAAA,MAAAA,EAAoFyB,EACvF,EAEMC,EACJD,GACG,CACHjB,EAAW,EAAK,EACfP,GAAA,MAAAA,EAAmFwB,EACtF,EAEME,EACJF,GACG,CACH,IAAIG,EAAOH,EAAE,OAAO,MAChBrC,GAAa,MAAQwC,EAAK,OAASxC,IACrCwC,EAAOA,EAAK,MAAM,EAAGxC,CAAS,EAC9BqC,EAAE,OAAO,MAAQG,GAEdjB,GAAcE,EAAiBe,CAAI,EACvC7B,GAAA,MAAAA,EAAsF0B,EACzF,EAGMI,EAAe,CACnB,sBACA,wBAAwBnB,CAAa,GACrC,wBAAwBK,CAAU,GAClCQ,GAAU,4BACVhB,GAAW,8BACb,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELuB,EAAe,CACnB,mBACA,qBAAqBf,CAAU,GAC/B,qBAAqBL,CAAa,GAClCb,GAAY,6BACZ0B,GAAU,wBACZ,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAGLQ,EAAoB,IAAuC,CAC/D,GAAI,CAACR,EAAQ,OACb,IAAMS,EAAYvD,EAClB,OAAIuD,EAAU,QAAU,KAAa,CAAE,OAAQ,OAAQ,EAKhD,CAAE,OAHP,OAAOA,EAAU,QAAW,SACxB,GAAGA,EAAU,MAAM,KACnBA,EAAU,MACG,CACrB,EAGMC,GAAc,IAAI,IAAI,CAC1B,OAAQ,aAAc,aAAc,aACpC,SAAU,QAAS,YAAa,WAClC,CAAC,EACKC,GAAc,OAAO,YACzB,OAAO,QAAQhC,CAAS,EAAE,OAAO,CAAC,CAACiC,CAAC,IAAM,CAACF,GAAY,IAAIE,CAAC,CAAC,CAC/D,EAGA,OACE5D,GAAC,OACC,UAAW,0CAA0CmC,CAAa,IAAIlB,CAAS,GAAG,KAAK,EACvF,MAAO4C,IAAA,GACF3C,GACCN,GAAS,MAAQ,CAAE,MAAO,OAAOA,GAAU,SAAW,GAAGA,CAAK,KAAOA,CAAM,GAGhF,UAAAG,GACCf,GAAC,SAAM,QAAS+B,EAAS,UAAU,0BACjC,UAAAhC,GAAC+D,EAAA,CAAK,QAAQ,UAAW,SAAA/C,EAAM,EAC9BP,GAAYT,GAAC,QAAK,UAAU,uBAAuB,cAAE,GACxD,EAGFA,GAAC,OAAI,UAAWwD,EAAc,MAAOC,EAAkB,EACrD,SAAAxD,GAAC,OAAI,UAAW,8CAA8CmC,CAAa,GAExE,WAACa,GAAUe,GAAY7D,CAAK,GAAKA,EAAM,YACtCH,GAAC,QAAK,UAAU,2BAA4B,SAAAG,EAAM,WAAW,EAG9D8C,EACCjD,GAAC,WAAAiE,EAAAH,EAAA,GACMF,IADN,CAEC,IAAKtD,EACL,GAAI0B,EACJ,SAAUT,EACV,SAAUC,EACV,UAAW+B,EACX,MAAO,OACP,MAAOf,EACP,SAAUa,EACV,QAASH,EACT,OAAQE,EACR,UAAWtC,EACX,eAAcH,EACd,mBACEC,GAAe8B,EAAQ,GAAGV,CAAO,eAAiB,QAEtD,EAEAhC,GAAC,QAAAiE,EAAAH,EAAA,GACMF,IADN,CAEC,IAAKtD,EACL,KAAOH,EAA8B,UACrC,GAAI6B,EACJ,SAAUT,EACV,SAAUC,EACV,UAAW+B,EACX,MAAOf,EACP,SAAUa,EACV,QAASH,EACT,OAAQE,EACR,UAAWtC,EACX,eAAcH,EACd,mBACEC,GAAe8B,EAAQ,GAAGV,CAAO,eAAiB,QAEtD,EAID,CAACiB,GAAUe,GAAY7D,CAAK,IAAMA,EAAM,YAAcA,EAAM,aAC3DF,GAAC,OAAI,UAAU,4BACZ,UAAAE,EAAM,YAAcH,GAAAD,GAAA,CAAG,SAAAI,EAAM,WAAW,EACxCA,EAAM,YAAcH,GAAAD,GAAA,CAAG,SAAAI,EAAM,WAAW,GAC3C,GAEJ,EACF,GAGES,GAAe+B,IACf3C,GAAC,OAAI,GAAI,GAAGgC,CAAO,eAAgB,UAAU,qBAC3C,SAAA/B,GAAC,OACC,UAAW,qBACTW,GAAe+B,EACX,6BACA/B,EACE,2BACA,wBACR,GAEC,UAAAA,GACCX,GAAC,QAAK,UAAW,wBAAwB+C,EAAW,GACjD,UAAAF,GACC9C,GAAC,QAAK,UAAU,kBAAmB,SAAA8C,EAAS,EAE7C,OAAOlC,GAAgB,UACxB,OAAOA,GAAgB,SACrBZ,GAAC+D,EAAA,CAAK,QAAQ,UAAU,UAAU,qBAC/B,SAAAnD,EACH,EAEAZ,GAAC,QAAK,UAAU,qBAAsB,SAAAY,EAAY,GAEtD,EAED+B,GACC1C,GAAC,QACC,UAAW,sCAAsC+C,EAAW,GAE3D,UAAAJ,GACC5C,GAAC+D,EAAA,CAAK,QAAQ,UAAU,UAAU,0BAC/B,SAAAnB,EACH,EAEDC,GACC5C,GAAC8D,EAAA,CAAK,QAAQ,UAAU,UAAU,yBAAyB,cACvDlB,GACJ,GAEJ,GAEJ,EACF,GAEJ,CAEJ,CAAC,EAEDzC,GAAU,YAAc,YAKxB,SAAS4D,GACP7D,EAC8B,CAC9B,MAAO,CAACD,GAAWC,CAAK,CAC1B,CE5XA,OAAO+D,OAAW,QAIlB,OAAS,wBAAAC,OAA4B,mBAwIP,cAAAC,GAelB,QAAAC,OAfkB,oBAhGvB,IAAMC,GAAaC,GAAM,WAA4C,CAACC,EAAOC,IAAQ,CAC1F,IAcIC,EAAAF,EAbF,OAAAG,EACA,KAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,cAAAC,EACA,WAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,GACZ,MAAAC,EACA,GAAAC,CAzDJ,EA2DMZ,EADCa,EAAAC,EACDd,EADC,CAZH,QACA,OACA,QACA,eACA,WACA,WACA,gBACA,aACA,UACA,YACA,QACA,OAKIe,EAAe,OAAO,UAAU,eAAe,KAAKjB,EAAO,OAAO,EAClE,CAACkB,EAAeC,CAAgB,EAAIpB,GAAM,SAC9CO,CACF,EACMc,EAAeH,EAAeZ,EAAQa,EACtCG,EAAa,CAAC,CAACb,EAEf,CAAE,cAAAc,CAAc,EAAIC,GAAc,EAElCC,EACJpB,GAAA,KAAAA,EAASkB,EAAgB,QAAU,SAE/BG,EAAc1B,GAAM,MAAM,EAC1B2B,EAASZ,GAAM,eAAeW,CAAW,GAEzCE,EAAeC,GAAiB,CACpC,IAAIC,EAEJ,GAAIR,EAAY,CACd,IAAMS,EAAY,MAAM,QAAQV,CAAY,EACxCA,EACAA,EACA,CAACA,CAAY,EACb,CAAC,EACLS,EAAWC,EAAU,SAASF,CAAI,EAC9BE,EAAU,OAAQC,GAAMA,IAAMH,CAAI,EAClC,CAAC,GAAGE,EAAWF,CAAI,CACzB,MACEC,EAAWT,IAAiBQ,EAAO,OAAYA,EAG5CX,GAAcE,EAAiBU,CAAQ,EAC5CtB,GAAA,MAAAA,EAAWsB,EACb,EAEMG,EAAc,CAAC,cAAe,gBAAgBR,CAAY,GAAIZ,CAAS,EAC1E,OAAO,OAAO,EACd,KAAK,GAAG,EAELqB,EAAwBxB,GAAA,KAAAA,EAAiB,CAAC,EAC1CyB,EAAiBV,IAAiB,SAAW,UAAY,UAEzDW,EAAUpC,GAAM,OAA8B,IAAI,EAClD,CAACqC,EAAmBC,CAAoB,EAAItC,GAAM,SAA6B,MAAS,EAE9F,OAAAA,GAAM,gBAAgB,IAAM,CAC1B,IAAMuC,EAAKH,EAAQ,QACnB,GAAI,CAACG,GAAM3B,GAAW,KAAM,OAC5B,IAAM4B,EAAYD,EAAG,cAA2B,oBAAoB,EACpE,GAAI,CAACC,EAAW,OAChB,IAAMC,EAAaD,EAAU,aACvBE,EAAY,iBAAiBH,CAAE,EAC/BI,EAAM,WAAWD,EAAU,GAAG,GAAK,EACnCE,GAAW,WAAWF,EAAU,UAAU,EAAI,WAAWA,EAAU,aAAa,EACtFJ,EAAqB,GAAGG,EAAa7B,EAAU+B,GAAO/B,EAAU,GAAKgC,EAAQ,IAAI,CACnF,EAAG,CAAChC,EAASa,EAAcrB,EAAM,MAAM,CAAC,EAStCP,GAAC,MAAAgD,EAAAC,EAAA,CACC,IAReC,GAAgC,CACjDX,EAAQ,QAAUW,EACd,OAAO7C,GAAQ,WAAYA,EAAI6C,CAAI,EAC9B7C,IAAMA,EAAsD,QAAU6C,EACjF,EAKI,GAAIpB,EACJ,UAAWM,EACX,KAAK,UACL,MAAOa,IAAA,GAAKhC,GAAWF,GAAW,MAAQ,CAAE,UAAWyB,CAAkB,IACrErB,GANL,CAQE,SAAAZ,EAAM,IAAI,CAAC4C,EAAMC,IAAQ,CAtIhC,IAAA9C,EAAA+C,EAuIQ,IAAMC,EAAa,MAAM,QAAQ9B,CAAY,EACzCA,EAAa,SAAS2B,EAAK,KAAK,EAChC3B,IAAiB2B,EAAK,MACpBI,EAAW,GAAGzB,CAAM,WAAWqB,EAAK,KAAK,GAEzCK,EAAgBxD,GAACyD,GAAA,CAAqB,UAAU,2BAA2B,EAC3EC,GACJ,OAAO5C,GAAe,WAAaA,EAAWqC,CAAI,EAAIrC,GAAA,KAAAA,EAAc0C,EAEtE,OACEvD,GAAC,UAEC,GAAIsD,EACJ,KAAK,SACL,KAAK,SACL,gBAAeD,EACf,SAAUH,EAAK,SACf,UAAU,oBACV,QAAS,IAAM,CAACA,EAAK,UAAYpB,EAAYoB,EAAK,KAAK,EAEvD,UAAAlD,GAAC,QAAK,UAAU,4BACb,UAAAkD,EAAK,MAAQnD,GAAC,QAAK,UAAU,sBAAuB,SAAAmD,EAAK,KAAK,EAC/DnD,GAAC2D,EAAAX,EAAAC,EAAA,CACC,SAAS3C,EAAA+B,EAAsB,UAAtB,KAAA/B,EAAiCgC,EAC1C,IAAIe,EAAAhB,EAAsB,KAAtB,KAAAgB,EAA4B,QAC5BhB,GAHL,CAIC,UAAW,CAAC,yBAA0BA,EAAsB,SAAS,EAClE,OAAO,OAAO,EACd,KAAK,GAAG,EAEV,SAAAc,EAAK,OACR,GACF,EACCG,GAActD,GAAC,QAAK,UAAU,sBAAuB,SAAA0D,GAAW,IAtB5DP,EAAK,KAuBZ,CAEJ,CAAC,GACH,CAEJ,CAAC,EAEDjD,GAAW,YAAc,aAiBlB,IAAM0D,GAAqBtD,GAOJ,CAPI,IAAA+C,EAAA/C,EAChC,UAAAuD,EACA,KAAMC,EACN,YAAAC,EAAc,GACd,aAAAC,EACA,mBAAAC,CAtMF,EAiMkCZ,EAM7Ba,EAAA9C,EAN6BiC,EAM7B,CALH,WACA,OACA,cACA,eACA,uBAGA,GAAM,CAACc,EAAcC,CAAe,EAAIjE,GAAM,SAAS4D,CAAW,EAC5D1C,EAAeyC,IAAa,OAC5BO,EAAOhD,EAAeyC,EAAWK,EACjCG,EAAanE,GAAM,OAA8B,IAAI,EAErDoE,EAAWvC,GAAkB,CAC5BX,GACH+C,EAAgBpC,CAAI,EAEtBgC,GAAA,MAAAA,EAAehC,EACjB,EAGA7B,GAAM,UAAU,IAAM,CACpB,GAAI,CAACkE,EAAM,OAEX,IAAMG,EAAsBC,GAAsB,CAC3CH,EAAW,UACXA,EAAW,QAAQ,SAASG,EAAM,MAAc,GACnDF,EAAQ,EAAK,EAEjB,EAEA,gBAAS,iBAAiB,YAAaC,CAAkB,EAClD,IAAM,CACX,SAAS,oBAAoB,YAAaA,CAAkB,CAC9D,CACF,EAAG,CAACH,EAAME,CAAO,CAAC,EAElB,IAAMG,EAAe,IAAM,CACzBH,EAAQ,CAACF,CAAI,CACf,EAEIM,EAA+Bd,EAEnC,GAAI1D,GAAM,eAAkD0D,CAAQ,EAAG,CACrE,IAAMe,EAAkBf,EAAS,MAAM,QAEvCc,EAAcxE,GAAM,aAAgD0D,EAAUb,EAAAC,EAAA,GACzEY,EAAS,OADgE,CAE5E,QAAUY,GAAyC,CACjDG,GAAA,MAAAA,EAAkBH,GAClBC,EAAa,CACf,EACA,gBAAiB,UACjB,gBAAiBL,CACnB,EAAC,CACH,MACEM,EACE3E,GAAC,UACC,KAAK,SACL,QAAS0E,EACT,gBAAc,UACd,gBAAeL,EAEd,SAAAR,EACH,EAIJ,IAAMgB,EAAgBpE,GAAyC,CArQjE,IAAAH,GAsQIA,EAAA4D,EAAU,WAAV,MAAA5D,EAAA,KAAA4D,EAAqBzD,GAEhByD,EAAU,UACbK,EAAQ,EAAK,CAEjB,EAEA,OACEtE,GAAC,OACC,IAAKqE,EACL,UAAU,sBAET,UAAAK,EACAN,GACCrE,GAAC,OACC,MAAOiD,EAAA,CACL,SAAU,WACV,IAAK,OACL,KAAM,EACN,UAAW,EACX,OAAQ,KACLgB,GAGL,SAAAjE,GAACE,GAAA8C,EAAAC,EAAA,GACKiB,GADL,CAEC,SAAUW,EACV,MAAO7B,EAAAC,EAAA,GACFiB,EAAU,OADR,CAEL,MAAO,OACP,SAAU,CACZ,IACF,EACF,GAEJ,CAEJ,EAEAN,GAAkB,YAAc,oBHpShC,OAAwB,kBAAAkB,OAAsB,mBAoK1C,OAeM,OAAAC,GAfN,QAAAC,OAAA,oBA1FG,IAAMC,GAAe,CAAC,CAC3B,KAAAC,EAAO,WACP,MAAAC,EACA,SAAAC,EAAW,GACX,MAAOC,EACP,YAAAC,EAAc,iCACd,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,MAAAC,EAAQ,GACR,YAAAC,EACA,WAAAC,EAAa,GACb,QAAAC,EACA,QAAAC,EACA,WAAAC,EACA,KAAAC,EACA,UAAAC,EAAY,GACZ,GAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,iBAAAC,EAAmB,GACnB,aAAAC,EACA,MAAAC,EACA,KAAAC,EACA,kBAAAC,EACA,eAAAC,EACA,cAAAC,EACA,UAAAC,EACA,YAAAC,CACF,IAAyB,CACvB,GAAM,CAACC,EAAeC,CAAgB,EAAIC,GAAM,SAE9Cf,CAAY,EAERgB,EAAejB,GAAS,MAAQA,EAAM,OAAS,EAC/CkB,EAAe/B,IAAc,OAE/BgC,EACAF,IACFE,EAAwBD,EACpB/B,IAAc,KACZ,OACAA,EACF2B,GAGN,IAAMM,EAAsBC,GAAwC,CAC7DH,GAAcH,EAAiBM,CAAI,EACxCnB,GAAA,MAAAA,EAAWmB,EACb,EAEMC,GAA+B,IAAM,CAxI7C,IAAAC,EAyII,GAAIN,EAAc,CAChB,IAAMO,EAAIL,EACV,GAAIK,GAAK,MAAS,MAAM,QAAQA,CAAC,GAAKA,EAAE,SAAW,EAAI,OAAO,KAC9D,GAAI,MAAM,QAAQA,CAAC,EACjB,OAAOA,EACJ,IAAKC,GAAO,CA9IvB,IAAAF,GAAAG,GA8I0B,OAAAA,IAAAH,GAAAvB,EAAO,KAAM2B,IAAMA,GAAE,QAAUF,CAAK,IAApC,YAAAF,GAAuC,QAAvC,KAAAG,GAAgDD,EAAK,EACpE,OAAO,OAAO,EACd,KAAK,IAAI,EAEd,IAAMG,GAAQL,EAAAvB,EAAO,KAAM2B,GAAMA,EAAE,QAAUH,CAAC,IAAhC,YAAAD,EAAmC,MACjD,OAAOK,GAAS,KAAO,OAAOA,CAAK,EAAIJ,CACzC,CACA,OAAIrC,GAAa,KAAa,KAC1B,MAAM,QAAQA,CAAS,EAAUA,EAAU,KAAK,IAAI,EACjD,OAAOA,GAAc,SAAWA,EAAY,IACrD,GAAG,EAGG0C,GADW,EAAQP,GAGvB,CAACjC,GACD,CAACC,IACAc,IAAc,OACXA,EACCa,EAAe,EAAQf,EAAY,EAAQP,GAE5CmC,EAAeC,GAAqC,CACxDA,EAAE,gBAAgB,EACdd,EACFG,EAAmB,MAAS,EAE5BzB,GAAA,MAAAA,EAAUoC,EAEd,EAEMC,EACJlD,GAAC,QAAK,UAAU,yBACb,UAAA+C,IACChD,GAAC,QACC,KAAK,SACL,SAAU,EACV,UAAU,uBACV,QAASiD,EACT,UAAYC,GAAM,EACZA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OACjCA,EAAE,eAAe,EACjBD,EAAYC,CAA6C,EAE7D,EACA,aAAW,4BAEX,SAAAlD,GAACoD,GAAA,CAAU,UAAU,4BAA4B,EACnD,EAEFpD,GAAC,QAAK,UAAU,sBACb,SAAAgB,GAAQhB,GAACD,GAAA,CAAe,UAAU,yBAAyB,EAC9D,GACF,EAGIsD,EACJrD,GAACsD,GAAA,CACC,MAAOlD,EACP,SAAUC,EACV,YAAaM,EACb,WAAYC,EACZ,MAAOF,EACP,SAAUF,EACV,KAAMmB,EACN,MAAOD,EACP,SAAQ,GACR,MAAOe,GAAA,KAAAA,EAAgB,GACvB,YAAalC,EACb,WAAYQ,EACZ,WAAYoC,EACZ,UAAW,CACT,sBACAhD,IAAS,cAAgB,kCACzBqB,EACAP,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACX,MAAOQ,EACP,GAAIP,EACJ,QAASL,EACX,EAGF,OAAIuB,GAAgB,CAAC5B,GAAY,CAACC,EAE9BT,GAACuD,GAAA,CACC,MAAOpC,EACP,MAAOmB,EACP,SAAUhB,EACV,KAAMK,EACN,SAAUY,EACV,mBAAoB,CAAE,MAAO,OAAQ,UAAW,CAAE,EAClD,cAAeX,EACf,WAAYC,EACZ,QAASG,EACT,UAAWF,EACX,MAAOC,EAEP,SAAA/B,GAAC,OAAI,UAAU,wBAAyB,SAAAqD,EAAc,EACxD,EAIGA,CACT,EAEAnD,GAAa,YAAc,eIzP3B,UAAYsD,OAAW,QACvB,SAASC,GAAgBC,EAItBC,EAAQ,CAJc,IAAAC,EAAAF,EACvB,OAAAG,EACA,QAAAC,CAHF,EACyBF,EAGpBG,EAAAC,EAHoBJ,EAGpB,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,QAAS,YACT,KAAM,eACN,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,SAAU,UACV,EAAG,oOACH,SAAU,SACZ,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAe,EAC1DS,GAAQD,GCvBf,UAAYE,OAAW,QACvB,SAASC,GAAwBC,EAI9BC,EAAQ,CAJsB,IAAAC,EAAAF,EAC/B,OAAAG,EACA,QAAAC,CAHF,EACiCF,EAG5BG,EAAAC,EAH4BJ,EAG5B,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,QAAS,YACT,KAAM,eACN,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,SAAU,UACV,EAAG,qPACH,SAAU,SACZ,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAuB,EAClES,GAAQD,GCvBf,UAAYE,OAAW,QACvB,SAASC,GAAsBC,EAI5BC,EAAQ,CAJoB,IAAAC,EAAAF,EAC7B,OAAAG,EACA,QAAAC,CAHF,EAC+BF,EAG1BG,EAAAC,EAH0BJ,EAG1B,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,QAAS,YACT,KAAM,eACN,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,SAAU,UACV,EAAG,wUACH,SAAU,SACZ,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAqB,EAChES,GAAQD,GCvBf,UAAYE,OAAW,QACvB,SAASC,GAAYC,EAIlBC,EAAQ,CAJU,IAAAC,EAAAF,EACnB,OAAAG,EACA,QAAAC,CAHF,EACqBF,EAGhBG,EAAAC,EAHgBJ,EAGhB,CAFH,QACA,YAGA,OAA0B,iBAAc,MAAO,OAAO,OAAO,CAC3D,MAAO,6BACP,QAAS,YACT,KAAM,eACN,cAAe,OACf,YAAa,OACb,IAAKD,EACL,kBAAmBG,CACrB,EAAGC,CAAK,EAAGF,EAA2B,iBAAc,QAAS,CAC3D,GAAIC,CACN,EAAGD,CAAK,EAAI,KAAyB,iBAAc,OAAQ,CACzD,SAAU,UACV,EAAG,8RACH,SAAU,SACZ,CAAC,CAAC,CACJ,CACA,IAAMI,GAAiC,cAAWR,EAAW,EACtDS,GAAQD,GC8FT,OAWE,OAAAE,GAXF,QAAAC,OAAA,oBARN,IAAMC,GAAiB,IACrBF,GAAC,QAAK,UAAU,sBAAsB,cAAY,OAChD,SAAAA,GAAC,OACC,UAAU,0BACV,QAAQ,YACR,KAAK,OACL,MAAM,6BAEN,SAAAC,GAAC,UACC,UAAU,6BACV,GAAG,KACH,GAAG,KACH,EAAE,KACF,OAAO,eACP,YAAY,IACZ,cAAc,QACd,gBAAgB,KAChB,iBAAiB,KAEjB,UAAAD,GAAC,WACC,cAAc,mBACd,IAAI,KACJ,OAAO,kBACP,YAAY,aACd,EACAA,GAAC,WACC,cAAc,oBACd,IAAI,KACJ,OAAO,YACP,YAAY,aACd,GACF,EACF,EACF,EAIWG,GAAaC,GAiCJ,CAjCI,IAAAC,EAAAD,EACxB,MAAAE,EAAO,SACP,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,MAAAC,EAAQ,GACR,QAAAC,EAAU,GACV,QAAAC,EAAU,GACV,MAAAC,EACA,SAAAC,EAAW,GACX,YAAAC,EAAc,iCACd,MAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,SAAAC,EACA,YAAAC,EACA,WAAAC,EACA,UAAAC,EACA,MAAAC,EACA,WAAAC,EACA,OAAAC,EACA,MAAAC,EAEA,WAAAC,EAAa,WACb,QAAAC,EACA,UAAAC,EACA,aAAAC,EACA,QAAAC,EACA,GAAAC,EACA,cAAAC,EACA,WAAAC,EACA,QAAAC,EAAU,CAjLZ,EAkJ0B9B,EAgCrB+B,EAAAC,EAhCqBhC,EAgCrB,CA/BH,OACA,WACA,WACA,QACA,UACA,UACA,QACA,WACA,cACA,QACA,QACA,eACA,WACA,WACA,cACA,aACA,YACA,QACA,aACA,SACA,QAEA,aACA,UACA,YACA,eACA,UACA,KACA,gBACA,aACA,YAGA,IAAMiC,EAAa/B,GAAYI,EACzB4B,EAAgB,CAACD,GAAc,CAAC9B,EAEhCgC,EAAY,EAAQ5B,EAEpB6B,EACJf,IAAU,OACN,OAAOA,GAAU,SACf,GAAGA,CAAK,KACRA,EACF,OAEAgB,EAAW/B,EAAUX,GAACE,GAAA,EAAe,EAAK,OAE1CyC,IAA8C,IAAM,CACxD,IAAMC,EAASC,IAAA,GAAKtB,GAAUE,GAAA,YAAAA,EAAQ,MACtC,OAAIgB,GAAiB,OACnBG,EAAO,MAAQH,GAEV,OAAO,KAAKG,CAAM,EAAE,OAAS,EAAIA,EAAS,MACnD,GAAG,EAEGE,EAAc,CAClB,aACA,eAAexC,CAAI,GACnBC,GAAY,uBACZC,GAAY,uBACZC,GAAS,oBACTC,GAAW,sBACXY,EACAE,GAAA,YAAAA,EAAY,IACd,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAGLuB,GAAsB,IAAM,CAxNpC,IAAA3C,EAyNI,GAAIiB,IAAe,GAAO,OAC1B,GAAIA,IAAe,OAAW,OAAOA,EACrC,GAAI,CAACN,GAASI,EAAU,OACxB,IAAM6B,EAAgBhC,GAAA,KAAAA,EAASC,EAC/B,GAAI,GAAC+B,GAAiB,MAAM,QAAQA,CAAa,GACjD,OAAO5C,EAAAW,EAAM,KAAMkC,GAAMA,EAAE,QAAUD,CAAa,IAA3C,YAAA5C,EAA8C,IACvD,GAAG,EAGG8C,EAAkBxC,EACpBV,GAACmD,GAAA,CAAgB,UAAU,sBAAsB,EACjD1C,EACET,GAACoD,GAAA,CAAsB,UAAU,sBAAsB,EACvD,KAEAC,EAAc5C,EAAQ,QAAU,SAEtC,OACER,GAAC,OAAI,UAAW6C,EAAa,MAAOH,GAClC,UAAA3C,GAACsD,GAAAC,EAAAV,EAAA,CACC,KAAMlB,EACN,KAAMrB,EACN,MAAOkC,EAAY5B,EAAQ,OAC3B,SAAUC,EACV,YAAaC,EACb,MAAOC,EACP,MAAOC,EACP,aAAcC,EACd,SAAUsB,EAAgBrB,EAAW,OACrC,SAAUC,EACV,SAAUmB,EACV,SAAU9B,EACV,MAAOC,EACP,WAAYsC,EACZ,KAAML,EACN,QAASH,EAAgBX,EAAU,OACnC,UAAWW,EAAgBV,EAAY,GACvC,aACEJ,GAAA,MAAAA,EAAQ,QAAUK,EACde,IAAA,GAAKf,GAAiBL,GAAA,YAAAA,EAAQ,QAC9B,OAEN,iBAAkB,CAAC,6BAA8BD,GAAA,YAAAA,EAAY,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAC7F,cAAeA,GAAA,YAAAA,EAAY,KAC3B,UAAWC,GAAA,YAAAA,EAAQ,KACnB,QAASM,EACT,GAAIC,GACAI,GA5BL,CA6BC,kBAAmBH,EACnB,eAAgBC,EAChB,YAAaC,EACb,MAAM,QACR,EACCf,GACCnB,GAAC,QAAK,UAAW,wBAAwBoD,CAAW,GACjD,UAAAH,GACClD,GAAC,QAAK,UAAU,kBAAmB,SAAAkD,EAAgB,EAEpD,OAAO9B,GAAgB,UAAY,OAAOA,GAAgB,SACzDpB,GAACwD,EAAA,CAAK,QAAQ,UAAU,UAAU,qBAC/B,SAAApC,EACH,EAEApB,GAAC,QAAK,UAAU,qBAAsB,SAAAoB,EAAY,GAEtD,GAEJ,CAEJ,EAEAjB,GAAU,YAAc,YChSxB,OAAOsD,OAAW,QAIlB,OACE,oBAAAC,GACA,qBAAAC,GACA,cAAAC,OACK,mBAsWW,OAuBA,YAAAC,GAvBA,OAAAC,GAuBA,QAAAC,OAvBA,oBArUlB,IAAMC,GAAQ,CAACC,EAAeC,IAA0B,CACtD,IAAMC,EAASD,EAAMD,EAAQ,EAC7B,OAAO,MAAM,KAAK,CAAE,OAAAE,CAAO,EAAG,CAACC,EAAGC,IAAQJ,EAAQI,CAAG,CACvD,EAEMC,GAAwB,CAAC,CAC7B,WAAAC,EACA,YAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,aAAAC,CACF,IAMwB,CACtB,GAAIJ,GAAc,EAAG,MAAO,CAAC,EAE7B,IAAMK,EAAc,KAAK,IAAI,KAAK,IAAIJ,EAAa,CAAC,EAAGD,CAAU,EAC3DM,EAA0B,CAAC,EAE3BC,EAAOC,GAAyBF,EAAM,KAAKE,CAAI,EAE/CC,EAAcJ,IAAgB,EAC9BK,EAAaL,IAAgBL,EAE/BG,GACFI,EAAI,CACF,KAAM,QACN,KAAM,EACN,IAAK,QACL,SAAUE,CACZ,CAAC,EAGCL,GACFG,EAAI,CACF,KAAM,OACN,KAAM,KAAK,IAAI,EAAGF,EAAc,CAAC,EACjC,IAAK,OACL,SAAUI,CACZ,CAAC,EAIH,IAAME,EAAmBT,EAAe,EAAI,EAE5C,GAAIF,GAAcW,EAChBlB,GAAM,EAAGO,CAAU,EAAE,QAASY,GAC5BL,EAAI,CACF,KAAM,OACN,KAAAK,EACA,IAAK,QAAQA,CAAI,GACjB,SAAUA,IAASP,CACrB,CAAC,CACH,MACK,CACL,IAAMQ,EAAmB,KAAK,IAAIR,EAAcH,EAAc,CAAC,EACzDY,EAAoB,KAAK,IAC7BT,EAAcH,EACdF,EAAa,CACf,EAEMe,EAAyBF,EAAmB,EAC5CG,EAA0BF,EAAoBd,EAAa,EAUjE,GAPAO,EAAI,CACF,KAAM,OACN,KAAM,EACN,IAAK,SACL,SAAUF,IAAgB,CAC5B,CAAC,EAEG,CAACU,GAA0BC,EAAyB,CAEtD,IAAMC,EAAgB,EAAI,EAAIf,EACZT,GAAM,EAAGwB,CAAa,EAE9B,QAASL,GACjBL,EAAI,CACF,KAAM,OACN,KAAAK,EACA,IAAK,gBAAgBA,CAAI,IAAIP,CAAW,GACxC,SAAUO,IAASP,CACrB,CAAC,CACH,EAEAE,EAAI,CAAE,KAAM,WAAY,IAAK,kBAAkBO,CAAiB,EAAG,CAAC,EACpEP,EAAI,CACF,KAAM,OACN,KAAMP,EACN,IAAK,QAAQA,CAAU,GACvB,SAAUK,IAAgBL,CAC5B,CAAC,CACH,SAAWe,GAA0B,CAACC,EAAyB,CAE7DT,EAAI,CAAE,KAAM,WAAY,IAAK,iBAAiBM,CAAgB,EAAG,CAAC,EAElE,IAAMK,EAAiB,EAAI,EAAIhB,EACZT,GAAMO,EAAakB,EAAiB,EAAGlB,EAAa,CAAC,EAE7D,QAASY,GAClBL,EAAI,CACF,KAAM,OACN,KAAAK,EACA,IAAK,gBAAgBA,CAAI,IAAIP,CAAW,GACxC,SAAUO,IAASP,CACrB,CAAC,CACH,EAEAE,EAAI,CACF,KAAM,OACN,KAAMP,EACN,IAAK,QAAQA,CAAU,GACvB,SAAUK,IAAgBL,CAC5B,CAAC,CACH,MAAWe,GAA0BC,GAEnCT,EAAI,CAAE,KAAM,WAAY,IAAK,iBAAiBM,CAAgB,EAAG,CAAC,EAElEpB,GAAMoB,EAAkBC,CAAiB,EAAE,QAASF,GAClDL,EAAI,CACF,KAAM,OACN,KAAAK,EACA,IAAK,gBAAgBA,CAAI,IAAIP,CAAW,GACxC,SAAUO,IAASP,CACrB,CAAC,CACH,EAEAE,EAAI,CAAE,KAAM,WAAY,IAAK,kBAAkBO,CAAiB,EAAG,CAAC,EACpEP,EAAI,CACF,KAAM,OACN,KAAMP,EACN,IAAK,QAAQA,CAAU,GACvB,SAAUK,IAAgBL,CAC5B,CAAC,GAGDP,GAAM,EAAGO,CAAU,EAAE,QAASY,GAC5BL,EAAI,CACF,KAAM,OACN,KAAAK,EACA,IAAK,gBAAgBA,CAAI,IAAIP,CAAW,GACxC,SAAUO,IAASP,CACrB,CAAC,CACH,CAEJ,CAEA,OAAID,GACFG,EAAI,CACF,KAAM,OACN,KAAM,KAAK,IAAIP,EAAYK,EAAc,CAAC,EAC1C,IAAK,OACL,SAAUK,CACZ,CAAC,EAGCP,GACFI,EAAI,CACF,KAAM,OACN,KAAMP,EACN,IAAK,OACL,SAAUU,CACZ,CAAC,EAGIJ,CACT,EAEMa,GAA6B,CAAC,CAClC,WAAAnB,EACA,YAAAC,CACF,IAGwB,CACtB,GAAID,GAAc,EAAG,MAAO,CAAC,EAE7B,IAAMK,EAAc,KAAK,IAAI,KAAK,IAAIJ,EAAa,CAAC,EAAGD,CAAU,EAC3DM,EAA0B,CAAC,EAE3BC,EAAOC,GAAyBF,EAAM,KAAKE,CAAI,EAE/CC,EAAcJ,IAAgB,EAC9BK,EAAaL,IAAgBL,EAGnC,OAAAO,EAAI,CACF,KAAM,OACN,KAAM,KAAK,IAAI,EAAGF,EAAc,CAAC,EACjC,IAAK,OACL,SAAUI,CACZ,CAAC,EAEDhB,GAAM,EAAGO,CAAU,EAAE,QAASY,GAC5BL,EAAI,CACF,KAAM,OACN,KAAAK,EACA,IAAK,QAAQA,CAAI,GACjB,SAAUA,IAASP,CACrB,CAAC,CACH,EAEAE,EAAI,CACF,KAAM,OACN,KAAM,KAAK,IAAIP,EAAYK,EAAc,CAAC,EAC1C,IAAK,OACL,SAAUK,CACZ,CAAC,EAEMJ,CACT,EAGac,GAAcC,GAOJ,CAPI,IAAAC,EAAAD,EACzB,YAAArB,EACA,YAAAC,EACA,SAAAsB,EACA,KAAAC,EAAO,QACP,UAAAC,EAAY,EAxQd,EAmQ2BH,EAMtBI,EAAAC,EANsBL,EAMtB,CALH,aACA,cACA,WACA,OACA,cAIA,IAAMM,EAAO,UAEPC,EAA0BL,GAAA,KAAAA,EAAQ,QAElClB,EAAQwB,GAAM,QAAQ,IACtBD,IAAY,QACPV,GAA2B,CAChC,WAAAnB,EACA,YAAAC,CACF,CAAC,EAIIF,GAAsB,CAC3B,WAAAC,EACA,YAAAC,EACA,aAAc,EACd,gBAAiB,GACjB,aAAc,EAChB,CAAC,EACA,CAACD,EAAYC,EAAa4B,CAAO,CAAC,EAE/BE,EAAkBD,GAAM,YAC3BtB,GAAyB,CACpBA,EAAK,UACJA,EAAK,OACVe,GAAA,MAAAA,EAAWf,EAAK,MAClB,EACA,CAACe,CAAQ,CACX,EAEMS,EAAsBF,GAAM,YAC/BG,GAAgB,CACXA,IAAQ,gBAEVV,GAAA,MAAAA,EAAW,GACFU,IAAQ,mBAEjBV,GAAA,MAAAA,EAAWvB,GAEf,EACA,CAACuB,EAAUvB,CAAU,CACvB,EAEMkC,EAAc,CAAC,aAAc,eAAeN,CAAI,GAAIH,CAAS,EAChE,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OACElC,GAAC,MAAA4C,EAAAC,EAAA,CAAI,UAAWF,EAAa,aAAW,wCAAaR,GAApD,CACC,SAAAnC,GAAC,MAAG,UAAU,mBACX,SAAAe,EAAM,IAAKE,GAAS,CACnB,IAAM6B,EAAS7B,EAAK,OAAS,OACvB8B,EAAa,EAAQ9B,EAAK,SAC1B+B,EAAa,EAAQ/B,EAAK,SAE1BgC,EAAc,CAClB,qBACA,uBAAuBhC,EAAK,IAAI,GAChC6B,GAAU,2BACVC,GAAc,+BACdC,GAAc,8BAChB,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELE,EACJjC,EAAK,OAAS,OACV,OAAOA,EAAK,IAAI,EAChBA,EAAK,OAAS,OACZ,kCACAA,EAAK,OAAS,OACZ,kCACAA,EAAK,OAAS,QACZ,4BACAA,EAAK,OAAS,OACZ,wCACA,GAERkC,EACJlC,EAAK,OAAS,OAAS,GAAGA,EAAK,IAAI,qBAAQiC,EAE7C,OAAIjC,EAAK,OAAS,WAEdjB,GAAC,MAEC,UAAU,8CAEV,SAAAA,GAAC,UACC,KAAK,SACL,UAAU,kDACV,QAAS,IAAMyC,EAAoBxB,EAAK,GAAG,EAC3C,aACEA,EAAK,MAAQ,gBACT,+CACA,2DAGN,SAAAjB,GAACoD,GAAA,EAAW,EACd,GAdKnC,EAAK,GAeZ,EAKFjB,GAAC,MAAkB,UAAU,mBAC3B,SAAAC,GAAC,UACC,KAAK,SACL,UAAWgD,EACX,QAAS,IAAMT,EAAgBvB,CAAI,EACnC,SAAU+B,EACV,aAAYG,EACZ,eAAcL,GAAUC,EAAa,OAAS,OAE7C,UAAA9B,EAAK,OAAS,QACbjB,GAACqD,GAAA,CAAiB,UAAU,mBAAmB,EAEhDpC,EAAK,OAAS,QACbjB,GAACsD,GAAA,CAAkB,UAAU,mBAAmB,EAEjDrC,EAAK,OAAS,SACbhB,GAAAF,GAAA,CACE,UAAAC,GAACqD,GAAA,CAAiB,UAAU,4CAA4C,EACxErD,GAACqD,GAAA,CAAiB,UAAU,4CAA4C,GAC1E,EAEDpC,EAAK,OAAS,QACbhB,GAAAF,GAAA,CACE,UAAAC,GAACsD,GAAA,CAAkB,UAAU,4CAA4C,EACzEtD,GAACsD,GAAA,CAAkB,UAAU,4CAA4C,GAC3E,EAEDrC,EAAK,OAAS,QACbjB,GAACuD,EAAA,CACC,GAAG,OACH,QAASlB,IAAS,UAAY,UAAY,UAEzC,SAAApB,EAAK,KACR,GAEJ,GAnCOA,EAAK,GAoCd,CAEJ,CAAC,EACH,GACF,CAEJ,EAEAY,GAAW,YAAc,aCjazB,OAAO2B,OAAW,QAElB,OAAS,gBAAAC,GAAc,qBAAAC,OAAyB,mBA+FtC,cAAAC,GAcA,QAAAC,OAdA,oBAxEH,IAAMC,GAAcC,GAAM,WAC/B,CACEC,EAeAC,IACG,CAhBH,IAAAC,EAAAF,EACE,OAAAG,EACA,WAAAC,EACA,YAAAC,EACA,MAAAC,EACA,QAASC,EACT,eAAAC,EAAiB,GACjB,SAAAC,EACA,SAAAC,EACA,UAAAC,EAAY,GACZ,GAAAC,EACA,KAAAC,EACA,QAAAC,CAvCN,EA2BIZ,EAaKa,EAAAC,EAbLd,EAaK,CAZH,QACA,aACA,cACA,QACA,UACA,iBACA,WACA,WACA,YACA,KACA,OACA,YAvCN,IAAAF,EAAAE,EA6CI,GAAM,CAACe,EAAiBC,CAAkB,EAAInB,GAAM,SAASS,CAAc,EACrEW,EAAeZ,IAAgB,OAC/Ba,EAAUD,EAAeZ,EAAcU,EAEvCI,EAAgBC,GAA2C,CAC3DZ,IAECS,GACHD,EAAmBI,EAAE,OAAO,OAAO,EAGrCb,GAAA,MAAAA,EAAWa,GACb,EAEMC,EAAeD,GAA0C,CAC7D,GAAIF,GAAW,CAACV,EAAU,CACxBY,EAAE,eAAe,EACZH,GAAcD,EAAmB,EAAK,EAC3C,IAAMM,EAAiBC,EAAAC,EAAA,GAClBJ,GADkB,CAErB,OAAQG,EAAAC,EAAA,GAAKJ,EAAE,QAAP,CAAe,QAAS,EAAM,EACxC,GACAb,GAAA,MAAAA,EAAWe,EACb,CACAV,GAAA,MAAAA,EAAUQ,EACZ,EAEMK,EAAc5B,GAAM,MAAM,EAC1B6B,EAAUhB,GAAMe,EAChBE,EAAgBxB,EAAc,GAAGuB,CAAO,eAAiB,OAEzD,CAACE,EAAWC,CAAY,EAAIhC,GAAM,SAAS,EAAK,EAEhDiC,EAAc,CAAC,eAAgBtB,GAAY,yBAA0BC,CAAS,EACjF,OAAO,OAAO,EACd,KAAK,GAAG,EAELsB,EAAsB,CAC1B,8BACAH,GAAa,CAACV,GAAW,CAACV,GAAY,sCACxC,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELwB,EAAqB9B,GAAA,KAAAA,EAAc,CAAC,EACpC+B,EAAiB,CAAC,2BAA4BD,EAAmB,SAAS,EAC7E,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OACErC,GAAC,OAAI,UAAWmC,EAAa,eAAcZ,EACzC,UAAAvB,GAAC,OAAI,UAAU,wBACb,UAAAD,GAAC,QAAA8B,EAAA,CACC,IAAKzB,EACL,KAAK,QACL,GAAI2B,EACJ,KAAMf,EACN,QAASO,EACT,SAAUC,EACV,QAASE,EACT,SAAUb,EACV,MAAOJ,EACP,mBAAkBuB,GAAiB,OACnC,UAAU,uBACNd,EACN,EACAlB,GAAC,SACC,QAAS+B,EACT,UAAWK,EACX,aAAc,IAAMF,EAAa,EAAI,EACrC,aAAc,IAAMA,EAAa,EAAK,EAEtC,UAAAnC,GAAC,QAAK,UAAU,6BAA6B,cAAY,OACtD,SAAAwB,EACCxB,GAACwC,GAAA,CAAkB,UAAU,qBAAqB,EAElDxC,GAACyC,GAAA,CAAa,UAAU,qBAAqB,EAEjD,EACClC,GACCP,GAAC0C,EAAAb,EAAAC,EAAA,CACC,SAAS1B,EAAAkC,EAAmB,UAAnB,KAAAlC,EAA8B,UACvC,IAAIE,EAAAgC,EAAmB,KAAnB,KAAAhC,EAAyB,QACzBgC,GAHL,CAIC,UAAWC,EAEV,SAAAhC,GACH,GAEJ,GACF,EACCE,GACCT,GAAC,OAAI,GAAIiC,EAAe,UAAU,4BAC/B,SAAAxB,EACH,GAEJ,CAEJ,CACF,EAEAP,GAAY,YAAc,cA8CnB,IAAMyC,GAAmB,CAAC,CAC/B,MAAApC,EACA,WAAAC,EACA,YAAAC,EACA,iBAAAmC,EACA,MAAOC,EACP,aAAAC,EACA,SAAAjC,EACA,SAAAC,EACA,KAAAG,EACA,MAAA8B,EACA,SAAAC,EACA,UAAAjC,EAAY,EACd,IAA6B,CA7M7B,IAAAX,EAAAE,EAAA2C,EAAAC,EA8ME,GAAM,CAACC,EAAeC,CAAgB,EAAIjD,GAAM,SAA6B2C,CAAY,EACnFvB,EAAesB,IAAc,OAC7BnC,EAAQa,EAAesB,EAAYM,EAEnCE,EAAUlD,GAAM,MAAM,EACtBmD,EAAYrC,GAAQ,eAAeoC,CAAO,GAC1CpB,EAAgBxB,EAAc,GAAG4C,CAAO,eAAiB,OACzDE,EAA0B/C,GAAA,KAAAA,EAAc,CAAC,EACzCgD,EAAgCZ,GAAA,KAAAA,EAAoB,CAAC,EAErDa,EAAsB,CAAC,4BAA6BF,EAAwB,SAAS,EACxF,OAAO,OAAO,EACd,KAAK,GAAG,EACLG,EAA4B,CAChC,kCACAF,EAA8B,SAChC,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELpB,EAAc,CAClB,qBACAtB,GAAY,+BACZC,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL4C,EAAqBC,GACxBlC,GAA2C,CACtCA,EAAE,OAAO,SACNH,GAAc6B,EAAiBQ,CAAU,EAC9C/C,GAAA,MAAAA,EAAW+C,KAENrC,GAAc6B,EAAiB,MAAS,EAC7CvC,GAAA,MAAAA,EAAW,QAEf,EAGIgD,EAAkBd,EACpBA,EAAM,IAAKe,GACT9D,GAACE,GAAA,CAEC,MAAO4D,EAAK,MACZ,MAAOA,EAAK,MACZ,YAAaA,EAAK,YAClB,KAAMR,EACN,QAAS5C,IAAUoD,EAAK,MACxB,SAAUH,EAAkBG,EAAK,KAAK,EACtC,SAAUhD,GAAYgD,EAAK,UAPtBA,EAAK,KAQZ,CACD,EACD3D,GAAM,SAAS,IAAI6C,EAAWe,GAAU,CACtC,GAAI5D,GAAM,eAAiC4D,CAAK,GAAKA,EAAM,OAAS7D,GAAa,CAC/E,IAAM0D,EAAaG,EAAM,MAAM,MAC/B,GAAIH,IAAe,OACjB,eAAQ,KAAK,wGAAsD,EAC5DG,EAGT,IAAMC,EAAYtD,IAAUkD,EAE5B,OAAOzD,GAAM,aAAa4D,EAAO,CAC/B,KAAMT,EACN,QAASU,EACT,SAAWtC,GAA2C,CAhRlE,IAAAtB,EAAAE,EAiRcqD,EAAkBC,CAAU,EAAElC,CAAC,GAC/BpB,GAAAF,EAAA2D,EAAM,OAAM,WAAZ,MAAAzD,EAAA,KAAAF,EAAuBsB,EACzB,EACA,SAAUZ,GAAYiD,EAAM,MAAM,QACpC,CAAC,CACH,CACA,OAAOA,CACT,CAAC,EAEL,OACE9D,GAAC,OAAI,UAAWmC,EAAa,KAAK,aAAa,mBAAkBH,GAAiB,OAC/E,UAAA1B,GACCP,GAAC0C,EAAAb,EAAAC,EAAA,CACC,SAAS1B,EAAAmD,EAAwB,UAAxB,KAAAnD,EAAmC,cAC5C,IAAIE,EAAAiD,EAAwB,KAAxB,KAAAjD,EAA8B,OAC9BiD,GAHL,CAIC,UAAWE,EAEV,SAAAlD,GACH,EAEDE,GACCT,GAAC0C,EAAAb,EAAAC,EAAA,CACC,GAAIG,EACJ,SAASgB,EAAAO,EAA8B,UAA9B,KAAAP,EAAyC,UAClD,IAAIC,EAAAM,EAA8B,KAA9B,KAAAN,EAAoC,OACpCM,GAJL,CAKC,UAAWE,EAEV,SAAAjD,GACH,EAEFT,GAAC,OAAI,UAAU,8BAA+B,SAAA6D,EAAgB,GAChE,CAEJ,EAEAlB,GAAiB,YAAc,mBAG9BzC,GAAwE,MAAQyC,GCzTjF,OAAOsB,OAAW,QAoDd,OACiB,OAAAC,GADjB,QAAAC,OAAA,oBA5BG,IAAMC,GAAMC,GAAM,WAAsC,CAACC,EAS7DC,IAAQ,CATqD,IAAAC,EAAAF,EAC9D,MAAAG,EAAO,QACP,KAAAC,EAAO,SACP,MAAAC,EAAQ,UACR,MAAAC,EACA,WAAAC,EACA,WAAAC,EACA,UAAAC,EAAY,EA/Bd,EAwBgEP,EAQ3DQ,EAAAC,EAR2DT,EAQ3D,CAPH,OACA,OACA,QACA,QACA,aACA,aACA,cAIA,IAAMU,EAAiBT,IAAS,OAASE,EAAQ,UAG3CQ,EAAoB,CACxB,MACA,QAAQV,CAAI,GACZ,QAAQC,CAAI,GACZ,QAAQQ,CAAc,GACtBH,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACR,KAAK,EAEFK,EAAcV,IAAS,SAAW,UAAY,UAEpD,OACEP,GAAC,OAAAkB,EAAAC,EAAA,CAAK,IAAKf,GAASS,GAAnB,CAA0B,UAAWG,EACnC,UAAAN,GAAcX,GAAC,QAAK,UAAU,mBAAoB,SAAAW,EAAW,EAC9DX,GAACqB,EAAA,CAAK,QAASH,EAAc,SAAAR,EAAM,EAClCE,GAAcZ,GAAC,QAAK,UAAU,mBAAoB,SAAAY,EAAW,IAChE,CAEJ,CAAC,EAEDV,GAAI,YAAc,MC5DlB,OAAgB,YAAAoB,GAAU,UAAAC,GAAQ,aAAAC,GAAW,eAAAC,GAAa,mBAAAC,OAAuB,QACjF,OAAOC,OAAc,YA4Uf,OAEI,OAAAC,GAFJ,QAAAC,OAAA,oBApRN,SAASC,GACPC,EACAC,EACAC,EACAC,EACgE,CAChE,IAAMC,EAAK,OAAO,WACZC,EAAK,OAAO,YAEZC,EAAQJ,EAAU,MAAM,GAAG,EAC3BK,EAAOD,EAAM,CAAC,EACdE,EAAYF,EAAM,CAAC,EAGrBG,EAAYF,EAEZA,IAAS,OAASP,EAAQ,IAAMC,EAAQ,OAASE,EAC/CE,EAAKL,EAAQ,QAAUC,EAAQ,OAASE,IAAQM,EAAY,UACvDF,IAAS,UAAYF,EAAKL,EAAQ,OAASC,EAAQ,OAASE,EACjEH,EAAQ,KAAOC,EAAQ,OAASE,IAAQM,EAAY,OAC/CF,IAAS,QAAUP,EAAQ,KAAOC,EAAQ,MAAQE,EACvDC,EAAKJ,EAAQ,OAASC,EAAQ,MAAQE,IAAQM,EAAY,SACrDF,IAAS,SAAWH,EAAKJ,EAAQ,MAAQC,EAAQ,MAAQE,GAC9DH,EAAQ,MAAQC,EAAQ,MAAQE,IAAQM,EAAY,QAG1D,IAAIC,EAAM,EACNC,EAAO,EAGX,OAAQF,EAAW,CACjB,IAAK,MACHC,EAAMV,EAAQ,IAAMC,EAAQ,OAASE,EACrC,MACF,IAAK,SACHO,EAAMV,EAAQ,OAASG,EACvB,MACF,IAAK,OACHQ,EAAOX,EAAQ,KAAOC,EAAQ,MAAQE,EACtC,MACF,IAAK,QACHQ,EAAOX,EAAQ,MAAQG,EACvB,KACJ,CAGA,GAAIM,IAAc,OAASA,IAAc,SAAU,CACjD,OAAQD,EAAW,CACjB,IAAK,QACHG,EAAOX,EAAQ,KACf,MACF,IAAK,MACHW,EAAOX,EAAQ,MAAQC,EAAQ,MAC/B,MACF,QACEU,EAAOX,EAAQ,MAAQA,EAAQ,MAAQC,EAAQ,OAAS,EACxD,KACJ,CAEAU,EAAO,KAAK,IAAI,EAAG,KAAK,IAAIA,EAAMP,EAAKH,EAAQ,MAAQ,CAAC,CAAC,CAC3D,KAAO,CACL,OAAQO,EAAW,CACjB,IAAK,QACHE,EAAMV,EAAQ,IACd,MACF,IAAK,MACHU,EAAMV,EAAQ,OAASC,EAAQ,OAC/B,MACF,QACES,EAAMV,EAAQ,KAAOA,EAAQ,OAASC,EAAQ,QAAU,EACxD,KACJ,CACAS,EAAM,KAAK,IAAI,EAAG,KAAK,IAAIA,EAAKL,EAAKJ,EAAQ,OAAS,CAAC,CAAC,CAC1D,CAEA,IAAMW,EACJJ,EAAY,GAAGC,CAAS,IAAID,CAAS,GAAKC,EAG5C,MAAO,CAAE,IAAAC,EAAK,KAAAC,EAAM,eAAAC,CAAe,CACrC,CAGO,IAAMC,GAAU,CAAC,CACtB,MAAAC,EACA,KAAAC,EAAO,OACP,WAAAC,EACA,QAAAC,EACA,UAAAf,EAAY,MACZ,UAAAgB,EAAY,GACZ,OAAQC,EACR,cAAAC,EAAgB,GAChB,SAAAC,EAAW,GACX,MAAAC,EACA,OAAAnB,EAAS,EACT,aAAAoB,EAAe,GACf,UAAAC,EAAY,EACZ,WAAAC,EAAa,EACb,SAAAC,EACA,UAAAC,EAAY,EACd,IAAoB,CAClB,GAAM,CAACC,EAAQC,CAAS,EAAIC,GAASV,CAAa,EAC5CW,EAAaC,GAAuB,IAAI,EACxCC,EAAaD,GAAuB,IAAI,EACxCE,EAAiBF,GAA8B,IAAI,EACnDG,EAAkBH,GAA8B,IAAI,EACpDI,EAAejB,IAAe,OAC9BkB,EAAWD,EAAejB,EAAaS,EAGvC,CAACU,EAAWC,CAAY,EAAIT,GAK/B,CAAE,IAAK,EAAG,KAAM,EAAG,MAAO,GAAO,IAAK5B,CAAU,CAAC,EAGpDsC,GAAU,IACD,IAAM,CACPN,EAAe,SAAS,aAAaA,EAAe,OAAO,EAC3DC,EAAgB,SAAS,aAAaA,EAAgB,OAAO,CACnE,EACC,CAAC,CAAC,EAEL,IAAMM,EAAmB,IAAM,CACzB,CAACpB,GAAY,CAACe,IACZD,EAAgB,UAClB,aAAaA,EAAgB,OAAO,EACpCA,EAAgB,QAAU,MAExBX,EAAY,EACdU,EAAe,QAAU,WAAW,IAAM,CACxCL,EAAU,EAAI,CAChB,EAAGL,CAAS,EAEZK,EAAU,EAAI,EAGpB,EAEMa,EAAmB,IAAM,CACzB,CAACrB,GAAY,CAACe,IACZF,EAAe,UACjB,aAAaA,EAAe,OAAO,EACnCA,EAAe,QAAU,MAEvBT,EAAa,EACfU,EAAgB,QAAU,WAAW,IAAM,CACzCN,EAAU,EAAK,CACjB,EAAGJ,CAAU,EAEbI,EAAU,EAAK,EAGrB,EAEMc,EAAc,IAAM,CACpB,CAACtB,GAAY,CAACe,IACZD,EAAgB,UAClB,aAAaA,EAAgB,OAAO,EACpCA,EAAgB,QAAU,MAExBX,EAAY,EACdU,EAAe,QAAU,WAAW,IAAM,CACxCL,EAAU,EAAI,CAChB,EAAGL,CAAS,EAEZK,EAAU,EAAI,EAGpB,EAEMe,EAAa,IAAM,CACnB,CAACvB,GAAY,CAACe,IACZF,EAAe,UACjB,aAAaA,EAAe,OAAO,EACnCA,EAAe,QAAU,MAEvBT,EAAa,EACfU,EAAgB,QAAU,WAAW,IAAM,CACzCN,EAAU,EAAK,CACjB,EAAGJ,CAAU,EAEbI,EAAU,EAAK,EAGrB,EAEMgB,EAAoBC,GAA2C,CACnEA,EAAE,gBAAgB,EACd7B,GACFA,EAAQ6B,CAAC,EAEP,CAACzB,GAAY,CAACe,GAChBP,EAAU,EAAK,CAEnB,EAGMkB,EAAiBC,GAAY,IAAM,CACvC,GAAI,CAACjB,EAAW,SAAW,CAACE,EAAW,QAAS,OAEhD,IAAMgB,EAAclB,EAAW,QAAQ,sBAAsB,EACvDmB,EAAcjB,EAAW,QAAQ,sBAAsB,EACvDkB,EAASpD,GACbkD,EACA,CAAE,MAAOC,EAAY,MAAO,OAAQA,EAAY,MAAO,EACvDhD,EACAC,CACF,EAEAoC,EAAa,CACX,IAAKY,EAAO,IACZ,KAAMA,EAAO,KACb,MAAO,GACP,IAAKA,EAAO,cACd,CAAC,CACH,EAAG,CAACjD,EAAWC,CAAM,CAAC,EAGtBiD,GAAgB,IAAM,CAChBf,GAAYd,GACdwB,EAAe,CAEnB,EAAG,CAACV,EAAUd,EAAcwB,CAAc,CAAC,EAG3CP,GAAU,IAAM,CACd,GAAI,CAACH,GAAY,CAACd,EAAc,OAEhC,IAAI8B,EAAQ,EACNC,EAAW,IAAM,CACrB,qBAAqBD,CAAK,EAC1BA,EAAQ,sBAAsBN,CAAc,CAC9C,EAGA,cAAO,iBAAiB,SAAUO,EAAU,EAAI,EAChD,OAAO,iBAAiB,SAAUA,CAAQ,EAEnC,IAAM,CACX,OAAO,oBAAoB,SAAUA,EAAU,EAAI,EACnD,OAAO,oBAAoB,SAAUA,CAAQ,EAC7C,qBAAqBD,CAAK,CAC5B,CACF,EAAG,CAAChB,EAAUd,EAAcwB,CAAc,CAAC,EAG3C,IAAMQ,EAAmBhC,EAAee,EAAU,IAAMpC,EAElDsD,EACJ1D,GAAC,OACC,IAAKyB,EAAeU,EAAa,OACjC,UAAW,oBAAoBlB,CAAI,aAAawC,CAAgB,IAAIrC,EAAY,sBAAwB,EAAE,IAAIS,CAAS,GACvH,MACEJ,EACIkC,EAAA,CACE,SAAU,QACV,IAAKnB,EAAU,IACf,KAAMA,EAAU,KAChB,OAAQ,OACR,MAAO,OACP,UAAW,OACX,OAAQ,EACR,WAAYA,EAAU,MAAS,UAAuB,UAClDhB,EACA,CAAE,MAAO,OAAOA,GAAU,SAAW,GAAGA,CAAK,KAAOA,CAAM,EAC1D,CAAC,GAEPA,EACE,CAAE,MAAO,OAAOA,GAAU,SAAW,GAAGA,CAAK,KAAOA,CAAM,EAC1D,OAER,KAAK,UAEL,UAAAxB,GAAC,OAAI,UAAU,mBACZ,UAAAkB,GACCnB,GAAC,OAAI,UAAU,uBACZ,SAAAmB,EACH,EAEFnB,GAAC,OAAI,UAAU,iBACb,SAAAA,GAAC6D,EAAA,CAAK,QAAQ,UAAW,SAAA5C,EAAM,EACjC,EACCG,GACCpB,GAAC,UACC,KAAK,SACL,UAAU,wBACV,QAASgD,EACT,aAAW,gBAEX,SAAAhD,GAAC,OACC,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,MAAM,6BAEN,SAAAA,GAAC,QACC,EAAE,uBACF,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,QACjB,EACF,EACF,GAEJ,EACCqB,GACCrB,GAAC,OACC,UAAW,kCAAkC0D,EAAiB,MAAM,GAAG,EAAE,CAAC,CAAC,GAC7E,GAEJ,EAIII,EACJtB,GAAY,CAAChB,EACTE,EACEqC,GAAS,aAAaJ,EAAgB,SAAS,IAAI,EACnDA,EACF,KAEN,OACE1D,GAAC,OACC,IAAKiC,EACL,UAAU,mBACV,aAAcU,EACd,aAAcC,EACd,QAASC,EACT,OAAQC,EAEP,UAAAlB,EACAiC,GACH,CAEJ,EAEA9C,GAAQ,YAAc,UC9YtB,OAAOgD,OAAW,QAClB,OAAS,gBAAAC,OAAoB,YA4IvB,OA4II,YAAAC,GA1IA,OAAAC,GAFJ,QAAAC,OAAA,oBA9FC,IAAMC,GAASC,GAAsB,CAC1C,IAaIC,EAAAD,EAZF,MAAME,EACN,MAAAC,EAAQ,UACR,MAAAC,EACA,KAAAC,EACA,SAAAC,EAAW,MACX,gBAAAC,EAAkB,SAClB,UAAAC,EACA,aAAAC,EACA,kBAAAC,EACA,UAAAC,EAAY,GACZ,MAAAC,CA3DJ,EA6DMX,EADCY,EAAAC,EACDb,EADC,CAXH,OACA,QACA,QACA,OACA,WACA,kBACA,YACA,eACA,oBACA,YACA,UAII,CAAE,cAAAc,CAAc,EAAIC,GAAc,EAElCC,EAAkBf,GAAA,KAAAA,EAAaa,EAAgB,QAAU,SAEzDG,EAAc,CAAC,QAAS,UAAUD,CAAI,GAAI,UAAUd,CAAK,GAAIQ,CAAS,EACzE,OAAO,OAAO,EACd,KAAK,GAAG,EAGLQ,EAAmBF,IAAS,SAAW,GAAK,GAC5CG,EAAsBH,IAAS,SAAW,GAAK,GAC/CI,EAA2B,GAG3BC,GAAoBV,GAAA,YAAAA,EAAO,YAAa,OAGxCW,EACFC,EADwCF,EACxC,GAIA,CAEE,SAAU,QACV,OAAQ,KALLV,GAUT,GAAI,CAACU,EAWH,GATIhB,IAAa,OACfiB,EAAe,IAAM,GAAGf,GAAA,KAAAA,EAAaW,CAAgB,KACrDI,EAAe,OAAS,SAExBA,EAAe,OAAS,GAAGd,GAAA,KAAAA,EAAgBW,CAAmB,KAC9DG,EAAe,IAAM,QAInBN,IAAS,QAAS,CAEpB,IAAMQ,EAAUf,GAAA,KAAAA,EAAqBW,EACrCE,EAAe,KAAO,GAAGE,CAAO,KAChCF,EAAe,MAAQ,GAAGE,CAAO,KACjCF,EAAe,UAAY,OAC3BA,EAAe,MAAQ,eAAeE,EAAU,CAAC,KACnD,MAEMlB,IAAoB,UACtBgB,EAAe,KAAO,MACtBA,EAAe,MAAQ,OACvBA,EAAe,UAAY,mBAC3BA,EAAe,MAAQ,OACvBA,EAAe,SAAW,QAC1BA,EAAe,SAAW,SACjBhB,IAAoB,QAC7BgB,EAAe,KAAO,OACtBA,EAAe,MAAQ,OACvBA,EAAe,UAAY,OAC3BA,EAAe,MAAQ,OACvBA,EAAe,SAAW,QAC1BA,EAAe,SAAW,UAE1BA,EAAe,MAAQ,OACvBA,EAAe,KAAO,OACtBA,EAAe,UAAY,OAC3BA,EAAe,MAAQ,OACvBA,EAAe,SAAW,QAC1BA,EAAe,SAAW,SAMhC,IAAMG,EACJ,CAACrB,GAAQF,IAAU,UACjBL,GAAC,OAAI,UAAU,cACZ,UAAAK,IAAU,SACTN,GAAC8B,GAAA,CAAY,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,EAAG,EAExDxB,IAAU,WACTN,GAAC+B,GAAA,CAAwB,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,EAAG,EAEpEzB,IAAU,WACTN,GAACgC,GAAA,CAAgB,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,EAAG,EAE5D1B,IAAU,eACTN,GAACiC,GAAA,CAAsB,MAAO,CAAE,MAAO,OAAQ,OAAQ,MAAO,EAAG,GAErE,EACEzB,EACFR,GAAC,OAAI,UAAU,cAAe,SAAAQ,EAAK,EACjC,KAEN,OACEP,GAAC,MAAAiC,EAAAP,EAAA,CAAI,UAAWN,EAAa,MAAOK,GAAoBV,GAAvD,CACE,UAAAa,EACD7B,GAACmC,EAAA,CAAK,QAASf,IAAS,SAAW,aAAe,cAC/C,SAAAb,EACH,IACF,CAEJ,EAsBM6B,GAAgB,IAsBhBC,GAAeC,GAAM,cACzB,MACF,EAQaC,GAAgB,CAAC,CAAE,SAAAC,CAAS,IAAqC,CAC5E,GAAM,CAACC,EAAQC,CAAS,EAAIJ,GAAM,SAAsB,CAAC,CAAC,EACpD,CAACK,EAASC,CAAU,EAAIN,GAAM,SAAS,EAAK,EAElDA,GAAM,UAAU,IAAM,CACpBM,EAAW,EAAI,CACjB,EAAG,CAAC,CAAC,EAEL,IAAMC,EAAYP,GAAM,YACtB,CAACQ,EAAiBC,EAAwB,CAAC,IAAM,CAC/C,IAAMC,EAAK,SAAS,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,GACzC,CACJ,MAAA1C,EAAQ,UACR,KAAAc,EACA,SAAA6B,EAAW,IACX,SAAAxC,EAAW,MACX,gBAAAC,EAAkB,SAClB,UAAAC,EACA,aAAAC,EACA,kBAAAC,CACF,EAAIkC,EAEEG,EAAsBhB,EAAAP,EAAA,CAC1B,GAAAqB,EACA,QAAAF,EACA,MAAAxC,GACIc,IAAS,QAAa,CAAE,KAAAA,CAAK,GAJP,CAK1B,SAAA6B,EACA,SAAAxC,EACA,gBAAAC,EACA,UAAAC,EACA,aAAAC,EACA,kBAAAC,CACF,GAEA6B,EAAWS,GAAS,CAAC,GAAGA,EAAMD,CAAQ,CAAC,EAEnCD,EAAW,GACb,WAAW,IAAM,CACfP,EAAWS,GACTA,EAAK,IAAKC,GAAOA,EAAE,KAAOJ,EAAKd,EAAAP,EAAA,GAAKyB,GAAL,CAAQ,QAAS,EAAK,GAAIA,CAAE,CAC7D,EACA,WAAW,IAAM,CACfV,EAAWS,GAASA,EAAK,OAAQE,GAAUA,EAAM,KAAOL,CAAE,CAAC,CAC7D,EAAGZ,EAAa,CAClB,EAAGa,CAAQ,CAEf,EACA,CAAC,CACH,EAEMK,EAAYhB,GAAM,YAAaU,GAAe,CAClDN,EAAWS,GAASA,EAAK,OAAQE,GAAUA,EAAM,KAAOL,CAAE,CAAC,CAC7D,EAAG,CAAC,CAAC,EAEL,OACE/C,GAACoC,GAAa,SAAb,CAAsB,MAAO,CAAE,UAAAQ,EAAW,UAAAS,CAAU,EAClD,UAAAd,EACAG,GACCY,GACEvD,GAAAD,GAAA,CACG,SAAA0C,EAAO,IAAKY,GACXrD,GAACE,GAAAyB,EAAA,CAEC,MAAO0B,EAAM,MACb,KAAMA,EAAM,KACZ,MAAOA,EAAM,QACb,SAAUA,EAAM,SAChB,gBAAiBA,EAAM,gBACvB,UAAWA,EAAM,UACjB,aAAcA,EAAM,aACpB,kBAAmBA,EAAM,mBACpBA,EAAM,SAAW,CAAE,UAAW,gBAAiB,GAT/CA,EAAM,EAUb,CACD,EACH,EACA,SAAS,IACX,GACJ,CAEJ,EAYO,SAASG,IAAW,CACzB,IAAMC,EAAUnB,GAAM,WAAWD,EAAY,EAC7C,GAAI,CAACoB,EACH,MAAM,IAAI,MAAM,8CAA8C,EAEhE,OAAOA,CACT,CAEAvD,GAAM,YAAc,QCjUpB,OAAgB,YAAAwD,GAAU,eAAAC,GAAa,UAAAC,GAAQ,aAAAC,OAAiB,QCAhE,OAAgB,WAAAC,GAAS,eAAAC,OAAmB,QAsDxC,cAAAC,GAkKE,QAAAC,OAlKF,oBAFJ,IAAMC,GAAc,IAClBF,GAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,GAAC,QACC,EAAE,mBACF,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,QACjB,EACF,EAGIG,GAAe,IACnBH,GAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,GAAC,QACC,EAAE,kBACF,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,QACjB,EACF,EAKII,GAAeC,GAA6B,CAChD,IAAMC,EAAO,IAAI,KAAK,KAAM,EAAG,CAAC,EAChC,OAAO,MAAM,KAAK,CAAE,OAAQ,CAAE,EAAG,CAACC,EAAGC,IAAM,CACzC,IAAMC,EAAI,IAAI,KAAKH,CAAI,EACvB,OAAAG,EAAE,QAAQH,EAAK,QAAQ,EAAIE,CAAC,EACrBC,EAAE,mBAAmBJ,EAAQ,CAAE,QAAS,OAAQ,CAAC,EAAE,QAAQ,MAAO,EAAE,CAC7E,CAAC,CACH,EAEMK,GAAiB,CAACC,EAAcC,IACpC,IAAI,KAAKD,EAAMC,EAAQ,EAAG,CAAC,EAAE,QAAQ,EAEjCC,GAAqB,CAACF,EAAcC,IACxC,IAAI,KAAKD,EAAMC,EAAO,CAAC,EAAE,OAAO,EAE5BE,GAAY,CAACC,EAA2BC,IAA8B,CAC1E,IAAMC,EAAKC,GAAOH,CAAC,EACbI,EAAKD,GAAOF,CAAC,EACnB,OACEC,EAAG,YAAY,IAAME,EAAG,YAAY,GACpCF,EAAG,SAAS,IAAME,EAAG,SAAS,GAC9BF,EAAG,QAAQ,IAAME,EAAG,QAAQ,CAEhC,EAEMD,GAAUT,GACdA,aAAa,KAAOA,EAAI,IAAI,KAAKA,CAAC,EAE9BW,GAAWX,GAA8B,CAC7C,IAAMY,EAAKH,GAAOT,CAAC,EACnB,OAAO,IAAI,KAAKY,EAAG,YAAY,EAAGA,EAAG,SAAS,EAAGA,EAAG,QAAQ,CAAC,CAC/D,EAOMC,GAAe,CAACX,EAAcC,IAA6B,CAC/D,IAAMW,EAAkB,CAAC,EACnBC,EAAcd,GAAeC,EAAMC,CAAK,EACxCa,EAAWZ,GAAmBF,EAAMC,CAAK,EAE/C,QAASJ,EAAI,EAAGA,EAAIiB,EAAUjB,IAC5Be,EAAK,KAAK,CAAE,KAAM,IAAI,KAAKZ,EAAMC,EAAO,EAAEa,EAAW,EAAIjB,EAAE,EAAG,eAAgB,EAAM,CAAC,EAEvF,QAASA,EAAI,EAAGA,GAAKgB,EAAahB,IAChCe,EAAK,KAAK,CAAE,KAAM,IAAI,KAAKZ,EAAMC,EAAOJ,CAAC,EAAG,eAAgB,EAAK,CAAC,EAEpE,IAAMkB,EAAY,EAAKH,EAAK,OAAS,EACrC,GAAIG,EAAY,EACd,QAASlB,EAAI,EAAGA,GAAKkB,EAAWlB,IAC9Be,EAAK,KAAK,CAAE,KAAM,IAAI,KAAKZ,EAAMC,EAAQ,EAAGJ,CAAC,EAAG,eAAgB,EAAM,CAAC,EAG3E,OAAOe,CACT,EAKaI,GAAoC,CAAC,CAChD,KAAMC,EACN,MAAOC,EACP,OAAAxB,EAAS,QACT,aAAAyB,EACA,UAAAC,EACA,QAAAC,EACA,UAAAC,EACA,UAAAC,EAAY,GACZ,QAAAC,EACA,QAAAC,EACA,QAAAC,EACA,QAAAC,EACA,OAAAC,EACA,OAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,YAAAC,EAAc,GACd,YAAAC,EAAc,GACd,UAAAC,EAAY,GACZ,MAAAC,EACA,SAAAC,CACF,IAAM,CACJ,IAAMC,EAAM,IAAI,KACVrC,EAAOiB,GAAA,KAAAA,EAAYoB,EAAI,YAAY,EACnCpC,EAAQiB,GAAA,KAAAA,EAAamB,EAAI,SAAS,EAElCC,EAAQC,GAAQ,IAAM9B,GAAQ,IAAI,IAAM,EAAG,CAAC,CAAC,EAC7C+B,EAAOD,GAAQ,IAAM5B,GAAaX,EAAMC,CAAK,EAAG,CAACD,EAAMC,CAAK,CAAC,EAC7DwC,EAAWF,GAAQ,IAAM9C,GAAYC,CAAM,EAAG,CAACA,CAAM,CAAC,EACtDgD,EAAa,GAAG1C,CAAI,KAAKC,EAAQ,CAAC,GAElC0C,EAAaC,GAChBC,GAAe,CACd,IAAM/C,EAAIW,GAAQoC,CAAI,EAEtB,MADI,GAAArB,GAAW1B,EAAIW,GAAQe,CAAO,GAC9BC,GAAW3B,EAAIW,GAAQgB,CAAO,EAEpC,EACA,CAACD,EAASC,CAAO,CACnB,EAEMqB,EAAeC,GAAkB,CACrC,IAAMjD,EAAIW,GAAQsC,EAAK,IAAI,EACrBC,EAAU,CAAC,cAAc,EAQ/B,GAPKD,EAAK,gBAAgBC,EAAQ,KAAK,uBAAuB,EAC1DL,EAAWI,EAAK,IAAI,GAAGC,EAAQ,KAAK,wBAAwB,EAE5D,CAACzB,GAAaJ,GAAgBhB,GAAUL,EAAGqB,CAAY,GACzD6B,EAAQ,KAAK,wBAAwB,EAGnCzB,GAAaH,GAAaC,EAAS,CACrC,IAAM4B,EAAIxC,GAAQW,CAAS,EACrB8B,EAAIzC,GAAQY,CAAO,EACrBlB,GAAUL,EAAGmD,CAAC,EAAGD,EAAQ,KAAK,2BAA2B,EACpD7C,GAAUL,EAAGoD,CAAC,EAAGF,EAAQ,KAAK,yBAAyB,EACvDlD,EAAImD,GAAKnD,EAAIoD,GAAGF,EAAQ,KAAK,wBAAwB,CAChE,SAAWzB,GAAaH,GAAa,CAACC,GAAWC,EAAW,CAC1D,IAAM2B,EAAIxC,GAAQW,CAAS,EACrB+B,EAAI1C,GAAQa,CAAS,EACvBnB,GAAUL,EAAGmD,CAAC,EAAGD,EAAQ,KAAK,2BAA2B,GACpDG,EAAIF,GAAKnD,EAAImD,GAAKnD,GAAKqD,GACvBA,EAAIF,GAAKnD,EAAImD,GAAKnD,GAAKqD,IAAGH,EAAQ,KAAK,wBAAwB,CAC1E,MAAWzB,GAAaH,GAAajB,GAAUL,EAAGsB,CAAS,GACzD4B,EAAQ,KAAK,2BAA2B,EAG1C,OAAI7C,GAAUL,EAAGwC,CAAK,GACpBU,EAAQ,KAAK,qBAAqB,EAG7BA,EAAQ,KAAK,GAAG,CACzB,EAEA,OACE1D,GAAC,OAAI,UAAW,YAAY4C,CAAS,GAAI,MAAOC,EAC9C,UAAA7C,GAAC,OAAI,UAAU,kBACZ,UAAAwC,EACCzC,GAAC,UAAO,KAAK,SAAS,UAAU,mBAAmB,SAAU2C,EAAa,QAASJ,EAAQ,aAAW,sBACpG,SAAAvC,GAACE,GAAA,EAAY,EACf,EAEAF,GAAC,OAAI,UAAU,2BAA2B,EAE5CA,GAAC,QAAK,UAAU,uBAAwB,SAAAqD,EAAW,EAClDX,EACC1C,GAAC,UAAO,KAAK,SAAS,UAAU,mBAAmB,SAAU4C,EAAa,QAASJ,EAAQ,aAAW,sBACpG,SAAAxC,GAACG,GAAA,EAAa,EAChB,EAEAH,GAAC,OAAI,UAAU,2BAA2B,GAE9C,EAEC+C,EAED9C,GAAC,OAAI,UAAU,gBAAgB,KAAK,OAAO,aAAYoD,EACpD,UAAAD,EAAS,IAAKW,GACb/D,GAAC,OAAa,UAAU,mBAAmB,KAAK,eAC7C,SAAA+D,GADOA,CAEV,CACD,EACAZ,EAAK,IAAI,CAACO,EAAMM,IACfhE,GAAC,UAEC,KAAK,SACL,UAAWyD,EAAYC,CAAI,EAC3B,SAAUJ,EAAWI,EAAK,IAAI,GAAK,CAACA,EAAK,eACzC,QAAS,IAAMA,EAAK,iBAAkBrB,GAAA,YAAAA,EAAUqB,EAAK,OACrD,aAAc,IAAMA,EAAK,iBAAkBpB,GAAA,YAAAA,EAAUoB,EAAK,OAC1D,aAAc,IAAMpB,GAAA,YAAAA,EAAU,MAC9B,gBACE,CAACJ,GAAaJ,EAAehB,GAAU4C,EAAK,KAAM5B,CAAY,EAAI,OAEpE,SAAU4B,EAAK,eAAiB,EAAI,GAEnC,SAAAA,EAAK,KAAK,QAAQ,GAZdM,CAaP,CACD,GACH,GACF,CAEJ,EAEArC,GAAS,YAAc,WCxQvB,OAAgB,YAAAsC,GAAU,eAAAC,OAAmB,QAE7C,OAAS,mBAAAC,OAAuB,mBAQ9B,OACE,OAAAC,EADF,QAAAC,OAAA,oBADF,IAAMC,GAAkB,IACtBD,GAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,UAAAD,EAAC,QACC,EAAE,oHACF,KAAK,eACP,EACAA,EAAC,QACC,EAAE,uCACF,OAAO,QACP,YAAY,MACZ,cAAc,QACd,eAAe,QACjB,GACF,EAyFIG,GAAQC,GAAsB,OAAOA,CAAC,EAAE,SAAS,EAAG,GAAG,EAOhDC,GAAa,CACxBC,EACAC,EACAC,IACW,CACX,GAAI,CAACF,EAAG,MAAO,GAGf,GAAI,CAACC,EACH,MAAO,GAAGD,EAAE,YAAY,CAAC,KAAKA,EAAE,SAAS,EAAI,CAAC,KAAKA,EAAE,QAAQ,CAAC,GAGhE,IAAMG,EAAIH,EAAE,YAAY,EAClBI,EAAIJ,EAAE,SAAS,EAAI,EACnBK,EAAML,EAAE,QAAQ,EAChBM,EAAIN,EAAE,SAAS,EACfO,EAAMP,EAAE,WAAW,EAEzB,OAAOC,EACJ,QAAQ,OAAQ,OAAOE,CAAC,CAAC,EACzB,QAAQ,KAAMN,GAAKO,CAAC,CAAC,EACrB,QAAQ,IAAK,OAAOA,CAAC,CAAC,EACtB,QAAQ,KAAMP,GAAKQ,CAAG,CAAC,EACvB,QAAQ,IAAK,OAAOA,CAAG,CAAC,EACxB,QAAQ,KAAMR,GAAKS,CAAC,CAAC,EACrB,QAAQ,KAAMT,GAAKU,CAAG,CAAC,CAC5B,EAYaC,GAAY,CACvBC,EACAC,EAAwB,OACR,CAChB,GAAI,CAACD,GAAO,CAACA,EAAI,KAAK,EAAG,OAAOC,EAChC,IAAMC,EAAUF,EAAI,KAAK,EAErBN,EACAS,EACAZ,EACAa,EAAQ,EACRC,EAAU,EAGRC,EAAUJ,EAAQ,MACtB,yEACF,EAUA,GATII,IACFZ,EAAI,OAAOY,EAAQ,CAAC,CAAC,EACrBH,EAAI,OAAOG,EAAQ,CAAC,CAAC,EAAI,EACzBf,EAAI,OAAOe,EAAQ,CAAC,CAAC,EACrBF,EAAQ,OAAOE,EAAQ,CAAC,CAAC,EACzBD,EAAU,OAAOC,EAAQ,CAAC,CAAC,GAIzBZ,IAAM,OAAW,CAEnB,IAAMa,EADUL,EAAQ,QAAQ,OAAQ,EAAE,EAChB,MAAM,yCAAyC,EACrEK,IACFb,EAAI,OAAOa,EAAU,CAAC,CAAC,EACvBJ,EAAI,OAAOI,EAAU,CAAC,CAAC,EAAI,EAC3BhB,EAAI,OAAOgB,EAAU,CAAC,CAAC,EAE3B,CAGA,GAAIb,IAAM,OAAW,CAEnB,IAAMc,EADUN,EAAQ,QAAQ,OAAQ,EAAE,EACjB,MAAM,yBAAyB,EACpDM,IACFd,EAAI,OAAOc,EAAS,CAAC,CAAC,EACtBL,EAAI,OAAOK,EAAS,CAAC,CAAC,EAAI,EAC1BjB,EAAI,OAAOiB,EAAS,CAAC,CAAC,EAE1B,CAKA,GAHId,IAAM,QAAaS,IAAM,QAAaZ,IAAM,QAG5Ca,EAAQ,GAAKA,EAAQ,IAAMC,EAAU,GAAKA,EAAU,GAAI,OAAOJ,EAEnE,IAAMQ,EAAO,IAAI,KAAKf,EAAGS,EAAGZ,EAAGa,EAAOC,EAAS,EAAG,CAAC,EACnD,MACE,CAAC,MAAMI,EAAK,QAAQ,CAAC,GACrBA,EAAK,YAAY,IAAMf,GACvBe,EAAK,SAAS,IAAMN,GACpBM,EAAK,QAAQ,IAAMlB,EAEZkB,EAEFR,CACT,EAKaS,GAAsC,CAAC,CAClD,KAAAC,EAAO,SACP,SAAAC,EAAW,GACX,MAAAC,EAAQ,GACR,MAAAC,EACA,UAAAC,EACA,QAAAC,EACA,WAAAC,EAAa,GACb,MAAAC,EAAQ,GACR,YAAAC,EACA,OAAA1B,EAAS,QACT,YAAA2B,EAAc,4BACd,iBAAAC,EAAmB,qBACnB,eAAAC,EAAiB,qBACjB,WAAAC,EACA,SAAAC,EAAW,GACX,cAAAC,EACA,cAAAC,EACA,YAAAC,EACA,QAAAC,EACA,QAAAC,EACA,UAAAC,EAAY,GACZ,MAAAC,EACA,WAAAC,EACA,OAAAC,CACF,IAAM,CAxPN,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAAC,GAAAC,GAyPE,IAAMC,EAAU9B,IAAS,QAGnB,CAAC+B,EAAcC,CAAe,EAAIC,GAA2C,IAAI,EACjF,CAACC,EAAUC,CAAW,EAAIF,GAAS,EAAE,EAErCG,EAAkBC,GACtB,CAACC,EAAkCC,IAAwB,CACzDP,EAAgBM,CAAK,EACrBH,EAAYI,CAAW,CACzB,EACA,CAAC,CACH,EAEMC,EAAiBH,GACpBC,GAAqC,CACpC,IAAMhD,EACJgD,IAAU,QAAWnC,GAAA,KAAAA,EAAS,KAC9BmC,IAAU,QAAWlC,GAAA,KAAAA,EAAa,KACjCC,GAAA,KAAAA,EAAW,KACRoC,GAASrD,GAAU8C,EAAU5C,CAAQ,EACvCgD,IAAU,QAASxB,GAAA,MAAAA,EAAgB2B,IAC9BH,IAAU,QAASvB,GAAA,MAAAA,EAAgB0B,IACnCH,IAAU,QAAOtB,GAAA,MAAAA,EAAcyB,KACxCT,EAAgB,IAAI,CACtB,EACA,CAACE,EAAU/B,EAAOC,EAAWC,EAASS,EAAeC,EAAeC,CAAW,CACjF,EAEM0B,EAAoBL,GACxB,CAACC,EAAkCK,IAA2B,CACxDA,EAAE,MAAQ,UACZH,EAAeF,CAAK,EACnBK,EAAE,OAA4B,KAAK,EAExC,EACA,CAACH,CAAc,CACjB,EAEMI,EAAc,IAAM,CACnB3C,GAAUgB,GAAA,MAAAA,GACjB,EAEM4B,EAAoBF,GAAwB,CAChDA,EAAE,gBAAgB,EACb1C,GAAUiB,GAAA,MAAAA,GACjB,EAEM4B,EAAa,CACjB,aACA,CAAChB,GAAW,qBACZA,GAAW,oBACXX,EACAE,GAAA,YAAAA,EAAY,IACd,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAEL0B,EAAkB3B,GAASE,GAAA,MAAAA,EAAQ,KACrC0B,IAAA,GAAK5B,GAAUE,GAAA,YAAAA,EAAQ,MACvB,OAGJ,GAAI,CAACQ,EAAS,CACZ,IAAMmB,EAAUtE,GAAWwB,EAAOS,EAAY9B,CAAM,EAEpD,OACER,EAAC,OAAI,UAAWwE,EAAY,MAAOC,EAAiB,QAASH,EAC3D,SAAAtE,EAAC4E,GAAA,CACC,KAAK,QACL,SAAU,CAACrC,EACX,MAAOA,GAAYkB,IAAiB,QAAUG,EAAYe,GAAW,GACrE,YAAaxC,EACb,WAAYH,EAAahC,EAAC6E,GAAA,EAAgB,EAAK,OAC/C,WAAY5C,EACVjC,EAAC,UACC,KAAK,SACL,UAAU,oBACV,QAASuE,EACT,SAAU5C,EACV,aAAW,kCAEX,SAAA3B,EAACE,GAAA,EAAgB,EACnB,EACE,OACJ,MAAO0B,EACP,YAAaM,EACb,WAAY,CAAC,CAACN,EACd,SAAUD,EACV,UAAWoB,GAAA,YAAAA,EAAY,QACvB,MAAOC,GAAA,YAAAA,EAAQ,QACf,QAAST,EAAW,IAAMuB,EAAgB,QAASa,CAAO,EAAI,OAC9D,SAAUpC,EAAY8B,GAAMR,EAAYQ,EAAE,OAAO,KAAK,EAAI,OAC1D,OAAQ9B,EAAW,IAAM2B,EAAe,OAAO,EAAI,OACrD,EACF,CAEJ,CAGA,IAAMY,EAAWzE,GAAWyB,EAAWQ,EAAY9B,CAAM,EACnDuE,EAAS1E,GAAW0B,EAASO,EAAY9B,CAAM,EAC/CwE,GAAuB,CAACF,EACxBG,EAAqB,CAACF,EAEtBG,EAAa,CACjB,sBACA,6BACAvD,GAAY,gCACZC,GAAS,6BACTmB,GAAA,YAAAA,EAAY,OACd,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELoC,EAAcvD,EAAQ,QAAU,SAEtC,OACE3B,GAAC,OAAI,UAAWuE,EAAY,MAAOC,EACjC,UAAAxE,GAAC,OAAI,UAAWiF,EAAY,MAAOlC,GAAA,YAAAA,EAAQ,QAAS,QAASsB,EAC1D,UAAAtC,GACChC,EAAC,QACC,UAAW,qBAAoBiD,EAAAF,GAAA,YAAAA,EAAY,OAAZ,KAAAE,EAAoB,EAAE,GACrD,MAAOD,GAAA,YAAAA,EAAQ,KAEf,SAAAhD,EAAC6E,GAAA,EAAgB,EACnB,EAEDtC,EACCvC,EAAC,SACC,KAAK,OACL,UAAW,yBAAwBkD,EAAAH,GAAA,YAAAA,EAAY,OAAZ,KAAAG,EAAoB,EAAE,GACzD,MAAOF,GAAA,YAAAA,EAAQ,KACf,MAAOS,IAAiB,QAAUG,EAAWkB,EAC7C,YAAa1C,EACb,QAAS,IAAM0B,EAAgB,QAASgB,CAAQ,EAChD,SAAWT,GAAMR,EAAYQ,EAAE,OAAO,KAAK,EAC3C,OAAQ,IAAMH,EAAe,OAAO,EACpC,UAAYG,GAAMD,EAAkB,QAASC,CAAC,EAChD,EAEArE,EAAC,QACC,UAAW,oBAAoBgF,GAAuB,gCAAkC,EAAE,KAAI7B,EAAAJ,GAAA,YAAAA,EAAY,OAAZ,KAAAI,EAAoB,EAAE,GACpH,MAAOH,GAAA,YAAAA,EAAQ,KAEd,SAAA8B,GAAY1C,EACf,EAEFpC,EAAC,QACC,UAAW,0BAAyBoD,EAAAL,GAAA,YAAAA,EAAY,YAAZ,KAAAK,EAAyB,EAAE,GAC/D,MAAOJ,GAAA,YAAAA,EAAQ,UAChB,aAED,EACCT,EACCvC,EAAC,SACC,KAAK,OACL,UAAW,yBAAwBqD,GAAAN,GAAA,YAAAA,EAAY,OAAZ,KAAAM,GAAoB,EAAE,GACzD,MAAOL,GAAA,YAAAA,EAAQ,KACf,MAAOS,IAAiB,MAAQG,EAAWmB,EAC3C,YAAa1C,EACb,QAAS,IAAMyB,EAAgB,MAAOiB,CAAM,EAC5C,SAAWV,GAAMR,EAAYQ,EAAE,OAAO,KAAK,EAC3C,OAAQ,IAAMH,EAAe,KAAK,EAClC,UAAYG,GAAMD,EAAkB,MAAOC,CAAC,EAC9C,EAEArE,EAAC,QACC,UAAW,oBAAoBiF,EAAqB,gCAAkC,EAAE,KAAI3B,GAAAP,GAAA,YAAAA,EAAY,OAAZ,KAAAO,GAAoB,EAAE,GAClH,MAAON,GAAA,YAAAA,EAAQ,KAEd,SAAA+B,GAAU1C,EACb,EAEDJ,GACCjC,EAAC,UACC,KAAK,SACL,UAAW,sBAAqBuD,GAAAR,GAAA,YAAAA,EAAY,QAAZ,KAAAQ,GAAqB,EAAE,GACvD,MAAOP,GAAA,YAAAA,EAAQ,MACf,QAASuB,EACT,aAAW,kCACX,SAAU5C,EAEV,SAAA3B,EAACE,GAAA,EAAgB,EACnB,GAEJ,EACCgC,GACCjC,GAAC,QAAK,UAAW,wBAAwBkF,CAAW,GACjD,UAAAvD,GACC5B,EAAC,QAAK,UAAU,kBACd,SAAAA,EAACoF,GAAA,CAAsB,UAAU,sBAAsB,EACzD,EAEFpF,EAACqF,EAAA,CAAK,QAAQ,UAAU,UAAU,qBAC/B,SAAAnD,EACH,GACF,GAEJ,CAEJ,EAEAT,GAAU,YAAc,YCpcxB,OAAgB,WAAA6D,GAAS,UAAAC,GAAQ,aAAAC,GAAW,eAAAC,OAAmB,QAiG3D,OACE,OAAAC,GADF,QAAAC,OAAA,oBAvEJ,IAAMC,GAAOC,GAAsB,OAAOA,CAAC,EAAE,SAAS,EAAG,GAAG,EAEtDC,GAAkBC,GAAkC,CACxD,IAAMC,EAAoB,CAAC,EAG3B,QAASC,EAAI,EAAGA,EAAI,KAAmBA,GAAKF,EAAW,CACrD,IAAMG,EAAO,KAAK,MAAMD,EAAI,EAAE,EACxBE,EAASF,EAAI,GACnBD,EAAM,KAAK,CACT,KAAAE,EACA,OAAAC,EACA,MAAO,GAAGP,GAAIM,CAAI,CAAC,IAAIN,GAAIO,CAAM,CAAC,EACpC,CAAC,CACH,CACA,OAAOH,CACT,EAEMI,GAAa,CACjBC,EACAH,EACAC,IAEKE,EACEA,EAAK,SAAS,IAAMH,GAAQG,EAAK,WAAW,IAAMF,EADvC,GAOPG,GAAwC,CAAC,CACpD,aAAAC,EACA,aAAAC,EACA,cAAAC,EAAgB,GAChB,UAAAC,EAAY,GACZ,MAAAC,CACF,IAAM,CACJ,IAAMC,EAAUC,GAAuB,IAAI,EACrCC,EAAcD,GAA0B,IAAI,EAE5Cb,EAAQe,GAAQ,IAAMjB,GAAeW,CAAa,EAAG,CAACA,CAAa,CAAC,EAG1EO,GAAU,IAAM,CACd,GAAIF,EAAY,SAAWF,EAAQ,QAAS,CAC1C,IAAMK,EAAOL,EAAQ,QACfM,EAAOJ,EAAY,QACnBK,EAAWF,EAAK,sBAAsB,EACtCG,EAAWF,EAAK,sBAAsB,GAGxCE,EAAS,IAAMD,EAAS,KAAOC,EAAS,OAASD,EAAS,UAC5DF,EAAK,UACHC,EAAK,UACLD,EAAK,UACLA,EAAK,aAAe,EACpBC,EAAK,aAAe,EAE1B,CACF,EAAG,CAACX,CAAY,CAAC,EAEjB,IAAMc,EAAkBC,GACtB,CAACpB,EAAcC,IAAmB,CAChC,IAAMoB,EAAOhB,EAAe,IAAI,KAAKA,CAAY,EAAI,IAAI,KACzDgB,EAAK,SAASrB,EAAMC,EAAQ,EAAG,CAAC,EAChCK,GAAA,MAAAA,EAAe,IAAI,KAAKe,CAAI,EAC9B,EACA,CAAChB,EAAcC,CAAY,CAC7B,EAEA,OACEb,GAAC,OAAI,UAAW,eAAee,CAAS,GAAI,MAAOC,EACjD,UAAAjB,GAAC,OAAI,UAAU,sBAAsB,wBAAE,EACvCA,GAAC,OAAI,UAAU,oBAAoB,IAAKkB,EACrC,SAAAZ,EAAM,IAAKwB,GAAS,CACnB,IAAMC,EAAarB,GAAWG,EAAciB,EAAK,KAAMA,EAAK,MAAM,EAClE,OACE9B,GAAC,UAEC,IAAK+B,EAAaX,EAAc,OAChC,KAAK,SACL,UAAW,qBAAqBW,EAAa,8BAAgC,EAAE,GAC/E,QAAS,IAAMJ,EAAgBG,EAAK,KAAMA,EAAK,MAAM,EAEpD,SAAAA,EAAK,OANDA,EAAK,KAOZ,CAEJ,CAAC,EACH,GACF,CAEJ,EAEAlB,GAAW,YAAc,aHkWjB,OAqCM,YAAAoB,GArCN,OAAAC,GAsCQ,QAAAC,OAtCR,oBAvRR,IAAMC,GAAUC,GACdA,aAAa,KAAOA,EAAI,IAAI,KAAKA,CAAC,EAE9BC,GAAWD,GAA8B,CAC7C,IAAME,EAAKH,GAAOC,CAAC,EACnB,OAAO,IAAI,KAAKE,EAAG,YAAY,EAAGA,EAAG,SAAS,EAAGA,EAAG,QAAQ,CAAC,CAC/D,EAEMC,GAAyE,CAC7E,QAAS,CAAE,MAAO,eAAM,OAAQ,eAAM,MAAO,cAAK,EAClD,QAAS,CAAE,MAAO,QAAS,OAAQ,SAAU,MAAO,OAAQ,EAC5D,QAAS,CAAE,MAAO,eAAM,OAAQ,iCAAS,MAAO,cAAK,CACvD,EAEMC,GAAWC,GAAgB,CAhNjC,IAAAC,EAiNE,OAAAA,EAAAH,GAAKE,CAAM,IAAX,KAAAC,EAAgBH,GAAK,OAAO,GAKjBI,GAAyCC,GAAU,CAtNhE,IAAAF,GAAAG,GAAAC,GAAAC,GAAAC,GAAAC,GAuNE,GAAM,CACJ,KAAAC,EAAO,SACP,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,MAAAC,EAAQ,GACR,YAAAC,EACA,QAAAC,EACA,QAAAC,EACA,OAAAf,EAAS,QACT,UAAAgB,EAAY,GACZ,YAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,GACX,YAAAC,EAAc,GACd,YAAAC,EAAc,GACd,MAAOC,EAAY,GACnB,eAAAC,EAAiB,GACjB,cAAAC,EAAgB,GAChB,WAAYC,EACZ,QAASC,EACT,SAAUC,EACV,WAAAC,EACA,OAAAC,EACA,cAAAC,EACA,eAAAC,CACF,EAAI5B,EAEE6B,EAAOjC,GAAQC,CAAM,EACrBiC,EAAUxB,IAAS,QACnByB,EAAgBX,GAAkB,CAACU,EAGnCE,EAAsBV,GAAA,KAAAA,EAAmBS,EAAgB,mBAAqB,OAC9EE,EAAeH,EAEjB,OADC9B,EAAgC,MAE/BkC,EAAkBJ,EAEpB,OADC9B,EAAgC,SAE/BmC,EAAeL,EAChB9B,EAA+B,UAChC,OACEoC,EAAaN,EACd9B,EAA+B,QAChC,OACEqC,EAAgBP,EACjB9B,EAA+B,cAChC,OAEE,CAACsC,EAAQC,CAAS,EAAIC,GAAS,EAAK,EACpC,CAACC,EAAcC,CAAe,EAAIF,GACtCP,GAAeE,GAAgB,IAAI,IACrC,EACM,CAACQ,GAAWC,CAAY,EAAIJ,GAAsB,IAAI,EACtD,CAACK,EAAeC,CAAgB,EAAIN,GACxCL,GAAA,KAAAA,EAAgB,IAClB,EACM,CAACY,EAAaC,CAAc,EAAIR,GACpCJ,GAAA,KAAAA,EAAc,IAChB,EACM,CAACa,EAAgBC,CAAiB,EAAIV,GAC1CP,GAAA,KAAAA,EAAe,IACjB,EAGM,CAACkB,GAAiBC,EAAkB,EAAIZ,GAC5CP,GAAA,KAAAA,EAAe,IACjB,EACM,CAACoB,GAAgBC,CAAiB,EAAId,GAC1CL,GAAA,KAAAA,EAAgB,IAClB,EACM,CAACoB,EAAcC,EAAe,EAAIhB,GACtCJ,GAAA,KAAAA,EAAc,IAChB,EAGM,CAACqB,GAAsBC,EAAuB,EAAIlB,GAAS,EAAK,EAChE,CAACmB,GAAiBC,EAAkB,EAAIpB,GAAS,EAAE,EAEnDqB,GAAyBC,GAAY,IAAM,CAC/CJ,GAAwB,EAAI,EAC5BE,GAAmBG,GAAWd,EAAgBjB,EAAqBnC,CAAM,CAAC,CAC5E,EAAG,CAACoD,EAAgBjB,EAAqBnC,CAAM,CAAC,EAE1CmE,GAAwBF,GAAY,IAAM,CAC9C,IAAMG,EAASC,GAAUP,GAAiBV,CAAc,EACpDgB,GAAUA,IAAWhB,IACnBlB,GAGE,EADYkC,EAAO,SAAS,IAAM,GAAKA,EAAO,WAAW,IAAM,IACnDhB,GACdgB,EAAO,SAAShB,EAAe,SAAS,EAAGA,EAAe,WAAW,EAAG,EAAG,CAAC,EAGhFC,EAAkBe,CAAM,EACxBvB,EAAgB,IAAI,KAAKuB,EAAO,YAAY,EAAGA,EAAO,SAAS,EAAG,CAAC,CAAC,GAEtEP,GAAwB,EAAK,CAC/B,EAAG,CAACC,GAAiB5B,EAAekB,CAAc,CAAC,EAE7CkB,GAA2BL,GAC9BM,GAA2B,CACtBA,EAAE,MAAQ,UACZJ,GAAsB,EACrBI,EAAE,OAA4B,KAAK,EAExC,EACA,CAACJ,EAAqB,CACxB,EAEMK,GAAeC,GAAuB,IAAI,EAEhDC,GAAU,IAAM,CACd,IAAMC,EAAsBC,IAAsB,CAE9CJ,GAAa,SACb,CAACA,GAAa,QAAQ,SAASI,GAAM,MAAc,IAG/C3C,GACFgB,EAAiBO,EAAc,EAC/BL,EAAeO,CAAY,GAE3BL,EAAkBC,EAAe,EAEnCZ,EAAU,EAAK,EAEnB,EACA,gBAAS,iBAAiB,YAAaiC,CAAkB,EAClD,IAAM,SAAS,oBAAoB,YAAaA,CAAkB,CAC3E,EAAG,CAAC1C,EAASqB,GAAiBE,GAAgBE,CAAY,CAAC,EAG3DgB,GAAU,IAAM,CACV,CAACzC,GAAWG,IAAgB,QAC9B,sBAAsB,IAAM,CAC1BiB,EAAkBjB,CAAW,EAC7BmB,GAAmBnB,CAAW,CAChC,CAAC,CAEL,EAAG,CAACA,EAAaH,CAAO,CAAC,EAEzByC,GAAU,IAAM,CACVzC,GACF,sBAAsB,IAAM,CACtBK,IAAiB,SACnBW,EAAiBX,GAAA,KAAAA,EAAgB,IAAI,EACrCmB,EAAkBnB,GAAA,KAAAA,EAAgB,IAAI,GAEpCC,IAAe,SACjBY,EAAeZ,GAAA,KAAAA,EAAc,IAAI,EACjCoB,GAAgBpB,GAAA,KAAAA,EAAc,IAAI,EAEtC,CAAC,CAEL,EAAG,CAACD,EAAcC,EAAYN,CAAO,CAAC,EAEtC,IAAM4C,GAAOjC,EAAa,YAAY,EAChCkC,GAAQlC,EAAa,SAAS,EAE9BmC,GAAad,GACjB,IAAMpB,EAAgB,IAAI,KAAKgC,GAAMC,GAAQ,EAAG,CAAC,CAAC,EAClD,CAACD,GAAMC,EAAK,CACd,EACME,GAAaf,GACjB,IAAMpB,EAAgB,IAAI,KAAKgC,GAAMC,GAAQ,EAAG,CAAC,CAAC,EAClD,CAACD,GAAMC,EAAK,CACd,EAEMG,GAAwBC,GAAe,CAC3C,GAAIhD,GAAiBkB,EAAgB,CAEnC,IAAM+B,GAAU,IAAI,KAAKD,CAAI,EAC7BC,GAAQ,SAAS/B,EAAe,SAAS,EAAGA,EAAe,WAAW,EAAG,EAAG,CAAC,EAC7EC,EAAkB8B,EAAO,CAC3B,MACE9B,EAAkB6B,CAAI,CAE1B,EAEME,GAAoBF,GAAe,CACvC7B,EAAkB6B,CAAI,CACxB,EAEMG,GAAuBH,GAAe,CAC1C,GAAI,CAAClC,GAAkBA,GAAiBE,EACtCD,EAAiBiC,CAAI,EACrB/B,EAAe,IAAI,MACd,CACL,IAAMmC,GAAI1F,GAAQoD,CAAa,EACrBpD,GAAQsF,CAAI,GACbI,GACPnC,EAAe+B,CAAI,GAEnBjC,EAAiBiC,CAAI,EACrB/B,EAAeH,CAAa,EAEhC,CACF,EAEMuC,GAAmB,IAAM,CAC7B,IAAMC,EAAQ,IAAI,KACdvD,GACFgB,EAAiBuC,CAAK,EACtBrC,EAAe,IAAI,GAEnBE,EAAkBmC,CAAK,EAEzB3C,EAAgB,IAAI,KAAK2C,EAAM,YAAY,EAAGA,EAAM,SAAS,EAAG,CAAC,CAAC,CACpE,EAEMC,GAAe,IAAM,CACzB/C,EAAU,EAAK,EACXT,GACFgB,EAAiBO,EAAc,EAC/BL,EAAeO,CAAY,GAE3BL,EAAkBC,EAAe,EAEnC3B,GAAA,MAAAA,GACF,EAEM+D,GAAc,IAAM,CACxBhD,EAAU,EAAK,EACXT,GAAWe,GACbS,EAAkBT,CAAa,EAC/BW,GAAgBT,CAAW,EAC3BV,GAAA,MAAAA,EAAgBQ,EAAeE,GAAA,KAAAA,EAAe,OACrC,CAACjB,GAAWmB,IACrBG,GAAmBH,CAAc,EACjCf,GAAA,MAAAA,EAAiBe,IAEnB1B,GAAA,MAAAA,GACF,EAEMiE,GAAc,IAAM,CACpB1D,GACFgB,EAAiB,IAAI,EACrBE,EAAe,IAAI,EACnBM,EAAkB,IAAI,EACtBE,GAAgB,IAAI,EACpBnB,GAAA,MAAAA,EAAgB,KAAyB,QAEzCa,EAAkB,IAAI,EACtBE,GAAmB,IAAI,EACvBlB,GAAA,MAAAA,EAAiB,MAErB,EAEMuD,GAAchF,EAAQ,QAAU,SAEtC,OACEnB,GAAC,OACC,UAAW,mBAAmBiB,EAAW,4BAA8B,EAAE,IAAIC,EAAW,4BAA8B,EAAE,IAAIK,CAAS,KAAIf,GAAA2B,GAAA,YAAAA,EAAY,OAAZ,KAAA3B,GAAoB,EAAE,GAAG,KAAK,EACvK,MAAO4B,GAAA,YAAAA,EAAQ,KACf,IAAK2C,GAEL,UAAA/E,GAAC,OAAI,UAAU,qBACb,UAAAD,GAACqG,GAAAC,EAAAC,EAAA,GACKhE,GADL,CAEC,SAAUrB,EACV,MAAOE,EACP,KAAMqB,EAAU,QAAU,SAC1B,MAAQA,EAA6C,OAAlCG,GAAA,KAAAA,EAAekB,GAClC,UAAWrB,EAAWK,GAAA,KAAAA,EAAgBkB,GAAkB,OACxD,QAASvB,EAAWM,GAAA,KAAAA,EAAcmB,EAAgB,OAClD,MACEpC,GACA,CAACZ,GACD,CAACC,IACAsB,EACG,CAAC,EAAEuB,IAAkBE,GACrB,CAAC,EAAEtB,GAAA,KAAAA,EAAekB,KAExB,OAAQtD,EACR,YAAaiB,EACb,WAAYkB,EACZ,WAAY4D,IAAA,GACPhE,GAAA,YAAAA,EAAgB,YACfH,GAAA,MAAAA,EAAY,MAAQ,CAAE,QAAS,EAACxB,GAAA2B,GAAA,YAAAA,EAAgB,aAAhB,YAAA3B,GAA4B,QAASwB,EAAW,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAK,MAAU,EAAI,CAAC,GAEzI,OAAQmE,IAAA,GACHhE,GAAA,YAAAA,EAAgB,QACfF,GAAA,MAAAA,EAAQ,MAAQ,CAAE,QAASkE,IAAA,IAAK1F,GAAA0B,GAAA,YAAAA,EAAgB,SAAhB,YAAA1B,GAAwB,SAAYwB,EAAO,MAAQ,EAAI,CAAC,GAE9F,QAAS,IAAM,CAACnB,GAAY,CAACC,GAAY+B,EAAU,CAACD,CAAM,EAC1D,QAASkD,IACX,EAEClD,GACCjD,GAAC,OACC,UAAW,cAAcyC,EAAU,oBAAsB,oBAAoB,IAAIC,EAAgB,wBAA0B,EAAE,KAAI5B,GAAAsB,GAAA,YAAAA,EAAY,UAAZ,KAAAtB,GAAuB,EAAE,GAAG,KAAK,EAClK,MAAOuB,GAAA,YAAAA,EAAQ,QAEd,SAAAI,EACCxC,GAAAF,GAAA,CACE,UAAAE,GAAC,OAAI,UAAU,uBACb,UAAAD,GAACwG,GAAAF,EAAAC,EAAA,GACGjE,GADH,CAED,KAAM+C,GACN,MAAOC,GACP,OAAQ9E,EACR,UAAWgD,EACX,QAASE,EACT,UAAWJ,GACX,UAAS,GACT,QAAShC,EACT,QAASC,EACT,SAAUG,EACV,SAAU,GACV,YAAaE,EACb,YAAaC,EACb,UAAWO,GAAA,YAAAA,EAAY,SACvB,MAAOC,GAAA,YAAAA,EAAQ,SACf,QAASwD,GACT,QAAStC,EACT,OAAQgC,GACR,OAAQC,IACV,EACAxF,GAACwG,GAAAF,EAAAC,EAAA,GACKjE,GADL,CAEC,KAAMgD,KAAU,GAAKD,GAAO,EAAIA,GAChC,MAAOC,KAAU,GAAK,EAAIA,GAAQ,EAClC,OAAQ9E,EACR,UAAWgD,EACX,QAASE,EACT,UAAWJ,GACX,UAAS,GACT,QAAShC,EACT,QAASC,EACT,SAAU,GACV,SAAUI,EACV,YAAaC,EACb,YAAaC,EACb,UAAWO,GAAA,YAAAA,EAAY,SACvB,MAAOC,GAAA,YAAAA,EAAQ,SACf,QAASwD,GACT,QAAStC,EACT,OAAQgC,GACR,OAAQC,IACV,GACF,EAGAvF,GAAC,OACC,UAAW,cAAac,GAAAqB,GAAA,YAAAA,EAAY,SAAZ,KAAArB,GAAsB,EAAE,GAAG,KAAK,EACxD,MAAOsB,GAAA,YAAAA,EAAQ,OAEf,UAAArC,GAAC,OAAI,UAAU,kBACb,SAAAA,GAACqG,GAAA,CACC,KAAK,QACL,UAAW7C,EACX,QAASE,EACT,WAAY,GACZ,MAAO,GACP,SAAQ,GACR,OAAQlD,EACR,WAAYmC,EACZ,WAAYP,GAAA,MAAAA,EAAY,YAAc,CAAE,QAASA,EAAW,WAAY,EAAI,OAC5E,OAAQC,GAAA,MAAAA,EAAQ,YAAc,CAAE,QAASA,EAAO,WAAY,EAAI,OAChE,cAAgBqD,GAAS,CACnBA,IACFjC,EAAiBiC,CAAI,EACrBrC,EAAgB,IAAI,KAAKqC,EAAK,YAAY,EAAGA,EAAK,SAAS,EAAG,CAAC,CAAC,EAEpE,EACA,YAAcA,GAAS,CACjBA,GAAM/B,EAAe+B,CAAI,CAC/B,EACF,EACF,EACA1F,GAACyG,GAAA,CACC,KAAK,UACL,MAAM,UACN,KAAK,QACL,MAAOjE,EAAK,OACZ,UAAU,oBACV,QAASyD,GACX,EACAjG,GAACyG,GAAA,CACC,KAAK,QACL,MAAM,UACN,KAAK,QACL,MAAOjE,EAAK,MACZ,UAAU,oBACV,QAAS0D,GACX,GACF,GACF,EAEAjG,GAAAF,GAAA,CACE,UAAAE,GAAC,OAAI,UAAWyC,EAAgB,kBAAoB,OAClD,UAAA1C,GAACwG,GAAAF,EAAAC,EAAA,GACKjE,GADL,CAEC,KAAM+C,GACN,MAAOC,GACP,OAAQ9E,EACR,aAAcoD,EACd,QAAStC,EACT,QAASC,EACT,SAAUG,EACV,SAAUC,EACV,YAAaC,EACb,YAAaC,EACb,UAAWO,GAAA,YAAAA,EAAY,SACvB,MAAOC,GAAA,YAAAA,EAAQ,SACf,QAASoD,GACT,OAAQF,GACR,OAAQC,GAGR,SAAAvF,GAAC,OAAI,UAAU,0BACb,UAAAD,GAAC,OAAI,UAAU,sBACb,SAAAA,GAAC,SACC,KAAK,OACL,UAAU,6BACV,MACEoE,GACIE,GACAI,GAAWd,EAAgBjB,EAAqBnC,CAAM,GAAK,GAEjE,YAAaiB,GAAe,4BAC5B,QAAS+C,GACT,SAAWO,GAAMR,GAAmBQ,EAAE,OAAO,KAAK,EAClD,OAAQJ,GACR,UAAWG,GACb,EACF,EACA9E,GAAC,UACC,KAAK,SACL,UAAU,qBACV,QAAS+F,GAER,SAAAvD,EAAK,MACR,GACF,GACF,EAECE,GACC1C,GAAC0G,GAAA,CACC,aAAc9C,EACd,aAAcgC,GACd,cAAe5D,EACf,UAAWI,GAAA,YAAAA,EAAY,WACvB,MAAOC,GAAA,YAAAA,EAAQ,WACjB,GAEJ,EAGApC,GAAC,OACC,UAAW,gCAA+Be,GAAAoB,GAAA,YAAAA,EAAY,SAAZ,KAAApB,GAAsB,EAAE,GAAG,KAAK,EAC1E,MAAOqB,GAAA,YAAAA,EAAQ,OAEf,UAAArC,GAACyG,GAAA,CACC,KAAK,UACL,MAAM,UACN,KAAK,QACL,MAAOjE,EAAK,OACZ,UAAU,oBACV,QAASyD,GACX,EACAjG,GAACyG,GAAA,CACC,KAAK,QACL,MAAM,UACN,KAAK,QACL,MAAOjE,EAAK,MACZ,UAAU,oBACV,QAAS0D,GACX,GACF,GACF,EAEJ,GAEF,EACC7E,GACCpB,GAAC,QAAK,UAAW,wBAAwBmG,EAAW,GACjD,UAAAhF,GACCpB,GAAC,QAAK,UAAU,kBACd,SAAAA,GAAC2G,GAAA,CAAsB,UAAU,sBAAsB,EACzD,EAEF3G,GAAC4G,EAAA,CAAK,QAAQ,UAAU,UAAU,qBAC/B,SAAAvF,EACH,GACF,GAEJ,CAEJ,EAEAX,GAAW,YAAc,a,kzxBI3qBzB,IAAMmG,GAASC,GACb,OAAOA,GAAa,SAAWA,EAAWA,EAAS,IAExCC,GAGT,CACF,eAAgB,CACd,QAASF,GAAMG,EAAkB,EACjC,MAAOH,GAAMI,EAAgB,EAC7B,MAAOJ,GAAMK,EAAgB,CAC/B,EACA,cAAe,CACb,QAASL,GAAMM,EAAiB,EAChC,MAAON,GAAMO,EAAe,EAC5B,MAAOP,GAAMQ,EAAe,CAC9B,EACA,SAAU,CACR,QAASR,GAAMS,EAAe,EAC9B,MAAOT,GAAMU,EAAa,EAC1B,MAAOV,GAAMW,EAAa,CAC5B,EACA,OAAQ,CACN,QAASX,GAAMY,EAAa,EAC5B,MAAOZ,GAAMa,EAAW,EACxB,MAAOb,GAAMc,EAAW,CAC1B,EACA,QAAS,CACP,QAASd,GAAMe,EAAc,EAC7B,MAAOf,GAAMgB,EAAY,EACzB,MAAOhB,GAAMe,EAAc,CAC7B,CACF,ECrBE,OA4IE,YAAAE,GA5IF,OAAAC,EA4IE,QAAAC,OA5IF,oBARF,IAAMC,GAAa,CAACC,EAAgBC,IAC9BD,KAAQE,GACHA,GAAUF,CAAI,EAAEC,CAAK,EAEvB,GAGHE,GAAW,CAAC,CAAE,UAAWC,CAAc,IAC3CP,EAAC,OACC,IAAKK,GAAU,OAAO,MACtB,IAAI,YACJ,UAAWE,EACb,EAOWC,GAAQC,GAQJ,CARI,IAAAC,EAAAD,EACnB,MAAAN,EAAO,cACP,MAAAC,EAAQ,UACR,KAAAO,EAAO,SACP,QAAAC,EAAU,WACV,UAAAC,EAAY,GACZ,MAAAC,CApDF,EA8CqBJ,EAOhBK,EAAAC,EAPgBN,EAOhB,CANH,OACA,QACA,OACA,UACA,YACA,UAGA,IAAMO,EAAc,CAClB,OACA,SAASd,CAAI,GACb,SAASC,CAAK,GACd,SAASO,CAAI,EACf,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EAELO,EAAgB,CAAC,EAAEL,GAAaC,GAChCK,EAAYD,EACdE,EAAAC,EAAA,GAAKN,GAAL,CAAY,UAAAF,EAAW,MAAAC,CAAM,GAC7BM,EAAAC,EAAA,GAAKN,GAAL,CAAY,UAAW,GAAGE,CAAW,IAAIJ,CAAS,GAAG,KAAK,EAAG,MAAAC,CAAM,GAEjEQ,EAAWJ,EACb,CAAE,MAAO,OAAQ,OAAQ,OAAQ,QAAS,QAAkB,UAAW,SAAmB,EAC1F,CAAE,MAAO,OAAQ,OAAQ,OAAQ,QAAS,OAAiB,EACzDK,EAAaL,EACf,CAAE,MAAO,OAAQ,OAAQ,OAAQ,QAAS,OAAiB,WAAY,SAAU,eAAgB,QAAS,EAC1G,OAEEM,EAAcC,GACdP,EAEAlB,EAAC,MAAAoB,EAAAC,EAAA,GAAQF,GAAR,CACC,SAAAnB,EAAC,OAAI,UAAWiB,EAAa,MAAOM,EACjC,SAAAE,EACH,GACF,EAGGzB,EAAC,MAAAoB,EAAAC,EAAA,GAAQF,GAAR,CAAoB,SAAAM,GAAQ,EAItC,GAAItB,IAAS,eACX,OAAOqB,EACLxB,EAAC,OACC,IAAKE,GAAW,eAAgBE,CAAK,EACrC,IAAI,iDACJ,MAAOkB,EACT,CACF,EAIF,GAAInB,IAAS,cACX,OAAOqB,EACLxB,EAAC,OACC,IAAKE,GAAW,cAAeE,CAAK,EACpC,IAAI,gDACJ,MAAOkB,EACT,CACF,EAIF,GAAInB,IAAS,WACX,OAAOqB,EACLxB,EAAC,OACC,IAAKE,GAAW,WAAYE,CAAK,EACjC,IAAI,wCACJ,MAAOkB,EACT,CACF,EAGF,IAAMI,EAAU,IAAM,KAGtB,GAAIvB,IAAS,SACX,OAAOqB,EACLxB,EAAC,OACC,IAAKE,GAAW,SAAUE,CAAK,EAC/B,IAAI,eACJ,MAAOkB,EACT,CACF,EAIF,GAAInB,IAAS,UACX,OAAOqB,EACLxB,EAAC,OACC,IAAKE,GAAW,UAAWE,CAAK,EAChC,IAAI,qBACJ,MAAOkB,EACT,CACF,EAIF,GAAInB,IAAS,WAAY,CACvB,IAAMwB,EAASf,IAAY,WAAa,6CAAY,wCAC9CgB,EAEA1B,GADJU,IAAY,WACG,cACA,WADe,OAAO,EAEjCiB,EACJ7B,EAAC,OAAI,UAAU,qBACb,SAAAA,EAAC,OACC,IAAK4B,EACL,IAAKD,EACL,MAAO,CAAE,MAAO,OAAQ,OAAQ,SAAU,QAAS,OAAQ,EAC7D,EACF,EAEF,OAAOT,EACLlB,EAAC,MAAAoB,EAAAC,EAAA,GAAQF,GAAR,CACC,SAAAnB,EAAC,OAAI,UAAWiB,EAAa,MAAOM,EACjC,SAAAM,EACH,GACF,EAEA7B,EAAC,MAAAoB,EAAAC,EAAA,GAAQF,GAAR,CAAoB,SAAAU,GAAU,CAEnC,CAEA,IAAMC,EAAOJ,EAAQ,EACfK,EACJ9B,GAAAF,GAAA,CACE,UAAAC,EAAC,OAAI,UAAU,aACb,SAAAA,EAACM,GAAA,EAAS,EACZ,EACCwB,GAAQ9B,EAAC,QAAK,UAAU,aAAc,SAAA8B,EAAK,GAC9C,EAEF,OAAOZ,EACLlB,EAAC,MAAAoB,EAAAC,EAAA,GAAQF,GAAR,CACC,SAAAnB,EAAC,OAAI,UAAWiB,EAAa,MAAOM,EACjC,SAAAQ,EACH,GACF,EAEA/B,EAAC,MAAAoB,EAAAC,EAAA,GAAQF,GAAR,CAAoB,SAAAY,GAAgB,CAEzC,EAEAvB,GAAK,YAAc,OC7LZ,IAAMwB,GAAc,CACzB,OAAQ,CACN,IAAK,IACL,IAAK,GACP,EACA,OAAQ,CACN,IAAK,IACL,IAAK,IACP,EACA,QAAS,CACP,IAAK,IACP,CACF,EAGaC,GAAmB,CAC9B,GAAI,QACJ,GAAI,QACJ,GAAI,QACN,EAGaC,GAAgB,CAC3B,OAAQ,4CACR,OAAQ,6CACR,QAAS,sBACT,YAAa,oBACf,EAGaC,GAAgB,CAC3B,OAAQ,CACN,OAAQ,GACR,OAAQ,EACR,OAAQ,EACV,EACA,OAAQ,CACN,OAAQ,GACR,OAAQ,EACR,OAAQ,EACV,EACA,QAAS,CACP,OAAQ,GACR,OAAQ,GACR,OAAQ,EACV,CACF,ECvCM,cAAAC,OAAA,oBAHC,IAAMC,GAAc,CAAC,CAAE,SAAAC,CAAS,IAEnCF,GAACG,GAAA,CACC,SAAAH,GAACI,GAAA,CAAe,SAAAF,EAAS,EAC3B","names":["React","React","Text","React","_a","ref","_b","variant","decoration","as","children","className","props","__objRest","defaultTag","level","Tag","baseClasses","__spreadValues","jsx","jsxs","ensureTextAsSpan","node","React","Text","_a","children","rest","__objRest","__spreadProps","__spreadValues","ActionButton","ref","_b","size","color","type","htmlType","label","prefixIcon","suffixIcon","loading","className","disabled","props","isDisabled","isLoading","baseClasses","textVariant","React","jsx","IconButton","React","_a","ref","_b","size","color","type","icon","className","disabled","htmlType","propsStyle","styles","props","__objRest","isWeakType","colorClass","typeClass","baseClasses","shouldHide","__spreadProps","__spreadValues","React","useState","forwardRef","React","jsx","Badge","React","_a","ref","_b","type","variant","value","maxValue","className","props","__objRest","baseClasses","displayValue","__spreadProps","__spreadValues","Text","jsx","jsxs","Tab","forwardRef","_a","ref","_b","type","size","badge","label","mode","className","selected","disabled","onClick","props","__objRest","internalPressed","setInternalPressed","useState","isControlled","isPressed","handleClick","e","prev","state","baseClasses","__spreadProps","__spreadValues","Badge","TabGroup","valueProp","defaultValue","onChange","items","children","gap","style","internalValue","setInternalValue","React","value","groupStyle","handleTabClick","tabValue","originalOnClick","renderedTabs","item","isSelected","child","_c","React","React","CheckIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","CheckIcon_default","React","XMarkIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","XMarkIcon_default","jsx","jsxs","ChipComponent","React","_a","ref","_b","type","size","variant","value","onChange","checkedProp","defaultChecked","selectedValue","selectedValues","label","prefixIcon","suffixIcon","showCheck","showClose","onClose","className","disabled","onClick","props","__objRest","internalChecked","setInternalChecked","isControlled","checked","shouldRenderCheckIcon","displayLeftIcon","CheckIcon_default","hasPrefix","hasSuffix","paddingClass","baseClasses","handleClick","e","prev","handleClose","__spreadProps","__spreadValues","Text","ChipGroup","valueProp","defaultValue","multiple","items","children","rest","internalValue","setInternalValue","handleChange","chipValue","arr","next","v","renderedChips","item","child","_c","_d","Chip","React","createPortal","createContext","useContext","useSyncExternalStore","BreakpointContext","BreakpointProvider","useMediaQuery","query","callback","matchMedia","useBreakpoint","_a","_b","_c","_d","contextValue","isMobileQuery","isTabletQuery","isDesktopQuery","isUnderTabletQuery","Fragment","jsx","jsxs","DialogContext","React","DialogRoot","_a","_b","open","onClose","closeOnOverlayClick","closeOnEsc","withClose","variant","align","title","description","icon","actionItems","footerLayout","width","className","children","props","__objRest","isUnderTablet","useBreakpoint","mounted","setMounted","originalStyle","handleKeyDown","e","resolvedAlign","baseClasses","handleOverlayClick","contentNode","DialogHeader","DialogBody","DialogFooter","item","idx","DialogButton","dialogOverlay","__spreadProps","__spreadValues","XMarkIcon_default","createPortal","Text","layout","layoutClass","label","color","type","size","prefixIcon","suffixIcon","loading","disabled","onClick","closeOnClick","style","context","buttonWidth","defaultSize","defaultType","defaultColor","handleClick","ActionButton","Dialog","GlobalDialogContext","DialogProvider","dialogs","setDialogs","close","id","prev","d","closeAll","options","alert","resolve","confirm","_c","dialog","useDialog","React","jsx","jsxs","Toggle","React","_a","ref","_b","size","label","labelPosition","description","checkedProp","defaultChecked","onChange","disabled","className","id","props","__objRest","inputRef","combinedRef","node","internalChecked","setInternalChecked","isControlled","checked","handleChange","e","generatedId","toggleId","descriptionId","baseClasses","__spreadValues","Text","React","RiCheckboxBlankLine","RiCheckboxFill","RiCheckboxIndeterminateFill","jsx","jsxs","Checkbox","React","_a","ref","_b","label","labelProps","description","value","checkedProp","defaultChecked","onChange","disabled","indeterminate","className","id","props","__objRest","inputRef","combinedRef","node","internalChecked","setInternalChecked","isControlled","checked","handleChange","e","generatedId","checkboxId","descriptionId","baseClasses","resolvedLabelProps","labelClassName","__spreadValues","RiCheckboxIndeterminateFill","RiCheckboxFill","RiCheckboxBlankLine","Text","__spreadProps","CheckboxGroup","descriptionProps","multiple","valueProp","defaultValue","items","children","_c","_d","internalValue","setInternalValue","checkboxValue","newValue","v","groupId","resolvedGroupLabelProps","resolvedGroupDescriptionProps","groupLabelClassName","groupDescriptionClassName","renderedContent","item","child","isChecked","React","useCheckboxGroup","config","options","defaultValue","valueProp","onChangeProp","internalValue","setInternalValue","isControlled","value","onChange","newValue","allSelected","someSelected","selectAllChecked","selectAllIndeterminate","handleSelectAll","e","React","useState","useId","forwardRef","React","ExclamationCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","ExclamationCircleIcon_default","Fragment","jsx","jsxs","isAreaType","props","TextField","forwardRef","ref","_a","type","required","size","error","description","width","maxLength","showCountProp","title","accentIcon","className","style","id","value","defaultValue","readOnly","disabled","onChange","onFocus","onBlur","restProps","__objRest","generatedId","useId","fieldId","focused","setFocused","useState","effectiveSize","isControlled","internalValue","setInternalValue","currentValue","inputState","count","showCount","countValue","countTotal","iconNode","ExclamationCircleIcon_default","helpVariant","isArea","handleFocus","e","handleBlur","handleChange","next","fieldClasses","shellClasses","getShellAreaStyle","areaProps","excludeKeys","nativeProps","k","__spreadValues","Text","isInputType","__spreadProps","React","RiCheckboxCircleFill","jsx","jsxs","SelectMenu","React","props","ref","_a","items","size","value","defaultValue","onChange","multiple","itemTextProps","suffixIcon","maxRows","className","style","id","rest","__objRest","isControlled","internalValue","setInternalValue","currentValue","isMultiple","isUnderTablet","useBreakpoint","resolvedSize","generatedId","menuId","commitValue","next","newValue","prevArray","v","baseClasses","resolvedItemTextProps","defaultVariant","menuRef","computedMaxHeight","setComputedMaxHeight","el","firstItem","itemHeight","menuStyle","gap","paddingY","__spreadProps","__spreadValues","node","item","idx","_b","isSelected","optionId","defaultSuffix","RiCheckboxCircleFill","suffixNode","Text","SelectMenuOverlay","children","openProp","defaultOpen","onOpenChange","menuContainerStyle","menuProps","internalOpen","setInternalOpen","open","wrapperRef","setOpen","handleClickOutside","event","handleToggle","triggerNode","originalOnClick","handleChange","RiArrowUpSLine","jsx","jsxs","SelectHeader","type","title","required","valueProp","placeholder","disabled","readOnly","error","description","accentIcon","onClick","onClear","prefixIcon","icon","className","id","items","defaultValue","onChange","multiple","showClear","wrapperClassName","wrapperStyle","width","size","menuItemTextProps","menuSuffixIcon","menuClassName","menuStyle","menuMaxRows","internalValue","setInternalValue","React","isSelectMode","isControlled","currentValueForSelect","handleSelectChange","next","displayValue","_a","v","value","_b","i","found","showClearButton","handleClear","e","suffixContent","XMarkIcon_default","textFieldNode","TextField","SelectMenuOverlay","React","CheckCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","CheckCircleIcon_default","React","ExclamationTriangleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","ExclamationTriangleIcon_default","React","InformationCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","InformationCircleIcon_default","React","XCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","XCircleIcon_default","jsx","jsxs","LoadingSpinner","SelectBox","_a","_b","size","disabled","readOnly","error","success","loading","label","required","placeholder","items","value","defaultValue","onChange","multiple","description","prefixIcon","className","style","classNames","styles","width","headerType","onClear","showClear","wrapperStyle","onClick","id","itemTextProps","suffixIcon","maxRows","restHeaderProps","__objRest","isDisabled","isInteractive","showLabel","resolvedWidth","iconNode","rootStyle","merged","__spreadValues","baseClasses","resolvedPrefixIcon","selectedValue","i","descriptionIcon","CheckCircleIcon_default","ExclamationCircleIcon_default","helpVariant","SelectHeader","__spreadProps","Text","React","RiArrowLeftSLine","RiArrowRightSLine","RiMoreLine","Fragment","jsx","jsxs","range","start","end","length","_","idx","createPaginationItems","totalPages","currentPage","siblingCount","showEdgeButtons","showPrevNext","safeCurrent","items","add","item","isFirstPage","isLastPage","totalPageNumbers","page","leftSiblingIndex","rightSiblingIndex","shouldShowLeftEllipsis","shouldShowRightEllipsis","leftItemCount","rightItemCount","createBasicPaginationItems","Pagination","_a","_b","onChange","type","className","rest","__objRest","size","variant","React","handleItemClick","handleEllipsisClick","key","rootClasses","__spreadProps","__spreadValues","isPage","isSelected","isDisabled","itemClasses","labelText","ariaLabel","RiMoreLine","RiArrowLeftSLine","RiArrowRightSLine","Text","React","RiCircleLine","RiRadioButtonLine","jsx","jsxs","RadioButton","React","_a","ref","_b","label","labelProps","description","value","checkedProp","defaultChecked","onChange","disabled","className","id","name","onClick","props","__objRest","internalChecked","setInternalChecked","isControlled","checked","handleChange","e","handleClick","syntheticEvent","__spreadProps","__spreadValues","generatedId","radioId","descriptionId","isHovered","setIsHovered","baseClasses","labelWrapperClasses","resolvedLabelProps","labelClassName","RiRadioButtonLine","RiCircleLine","Text","RadioButtonGroup","descriptionProps","valueProp","defaultValue","items","children","_c","_d","internalValue","setInternalValue","groupId","groupName","resolvedGroupLabelProps","resolvedGroupDescriptionProps","groupLabelClassName","groupDescriptionClassName","handleRadioChange","radioValue","renderedContent","item","child","isChecked","React","jsx","jsxs","Tag","React","_a","ref","_b","type","size","state","label","prefixIcon","suffixIcon","className","props","__objRest","effectiveState","resolvedClassName","textVariant","__spreadProps","__spreadValues","Text","useState","useRef","useEffect","useCallback","useLayoutEffect","ReactDOM","jsx","jsxs","calcPosition","trigger","tooltip","direction","offset","vw","vh","parts","side","alignment","finalSide","top","left","finalDirection","Tooltip","label","type","prefixIcon","onClose","withArrow","openedProp","defaultOpened","disabled","width","withinPortal","openDelay","closeDelay","children","className","opened","setOpened","useState","wrapperRef","useRef","tooltipRef","openTimeoutRef","closeTimeoutRef","isControlled","isOpened","portalPos","setPortalPos","useEffect","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","handleCloseClick","e","updatePosition","useCallback","triggerRect","tooltipRect","result","useLayoutEffect","rafId","onUpdate","displayDirection","tooltipContent","__spreadValues","Text","renderedTooltip","ReactDOM","React","createPortal","Fragment","jsx","jsxs","Toast","props","_a","sizeProp","state","label","icon","position","horizontalAlign","topOffset","bottomOffset","horizontalPadding","className","style","rest","__objRest","isUnderTablet","useBreakpoint","size","baseClasses","defaultTopOffset","defaultBottomOffset","defaultHorizontalPadding","hasCustomPosition","positionStyles","__spreadValues","padding","defaultIcon","XCircleIcon_default","ExclamationTriangleIcon_default","CheckCircleIcon_default","InformationCircleIcon_default","__spreadProps","Text","TOAST_EXIT_MS","ToastContext","React","ToastProvider","children","toasts","setToasts","mounted","setMounted","showToast","message","options","id","duration","newToast","prev","t","toast","hideToast","createPortal","useToast","context","useState","useCallback","useRef","useEffect","useMemo","useCallback","jsx","jsxs","ChevronLeft","ChevronRight","getWeekdays","locale","base","_","i","d","getDaysInMonth","year","month","getFirstDayOfMonth","isSameDay","a","b","da","toDate","db","startOf","dt","buildDayGrid","grid","daysInMonth","firstDay","remaining","Calendar","yearProp","monthProp","selectedDate","startDate","endDate","hoverDate","rangeMode","minDate","maxDate","onClick","onHover","onPrev","onNext","showPrev","showNext","disablePrev","disableNext","className","style","children","now","today","useMemo","days","weekdays","monthLabel","isDisabled","useCallback","date","getDayClass","item","classes","s","e","h","wd","idx","useState","useCallback","RiCalendar2Line","jsx","jsxs","CloseCircleIcon","pad2","n","formatDate","d","format","locale","y","M","day","H","min","parseDate","str","fallback","trimmed","m","hours","minutes","dtMatch","dateMatch","numMatch","date","DateInput","type","disabled","error","value","startDate","endDate","prefixIcon","reset","description","placeholder","startPlaceholder","endPlaceholder","dateFormat","editable","onValueChange","onStartChange","onEndChange","onClick","onReset","className","style","classNames","styles","_a","_b","_c","_d","_e","_f","_g","isRange","editingField","setEditingField","useState","editText","setEditText","handleEditFocus","useCallback","field","currentText","handleEditBlur","parsed","handleEditKeyDown","e","handleClick","handleResetClick","wrapperCls","mergedRootStyle","__spreadValues","dateStr","TextField","RiCalendar2Line","startStr","endStr","showStartPlaceholder","showEndPlaceholder","contentCls","helpVariant","ExclamationCircleIcon_default","Text","useMemo","useRef","useEffect","useCallback","jsx","jsxs","pad","n","buildTimeSlots","intervals","slots","m","hour","minute","isSameTime","date","TimePicker","selectedDate","onTimeChange","timeIntervals","className","style","listRef","useRef","selectedRef","useMemo","useEffect","list","item","listRect","itemRect","handleTimeClick","useCallback","base","slot","isSelected","Fragment","jsx","jsxs","toDate","d","startOf","dt","I18N","getI18n","locale","_a","DatePicker","props","_b","_c","_d","_e","_f","type","disabled","readOnly","error","description","minDate","maxDate","className","placeholder","showPrev","showNext","disablePrev","disableNext","resetProp","showTimeSelect","timeIntervals","dateFormatProp","onApplyProp","onCancelProp","classNames","styles","calendarProps","dateInputProps","i18n","isRange","isTimeEnabled","effectiveDateFormat","singleValue","singleOnChange","extStartDate","extEndDate","onRangeChange","isOpen","setIsOpen","useState","currentMonth","setCurrentMonth","hoverDate","setHoverDate","internalStart","setInternalStart","internalEnd","setInternalEnd","internalSingle","setInternalSingle","committedSingle","setCommittedSingle","committedStart","setCommittedStart","committedEnd","setCommittedEnd","isEditingSingleField","setIsEditingSingleField","singleFieldText","setSingleFieldText","handleSingleFieldFocus","useCallback","formatDate","handleSingleFieldBlur","parsed","parseDate","handleSingleFieldKeyDown","e","containerRef","useRef","useEffect","handleClickOutside","event","year","month","handlePrev","handleNext","handleSingleDayClick","date","newDate","handleTimeChange","handleRangeDayClick","s","handleTodayClick","today","handleCancel","handleApply","handleReset","helpVariant","DateInput","__spreadProps","__spreadValues","Calendar","ActionButton","TimePicker","ExclamationCircleIcon_default","Text","toUrl","imported","LOGO_URLS","likelion_eng_primary_default","likelion_eng_black_default","likelion_eng_white_default","likelion_kr_primary_default","likelion_kr_black_default","likelion_kr_white_default","bootcamp_primary_default","bootcamp_black_default","bootcamp_white_default","symbol_primary_default","symbol_black_default","symbol_white_default","favicon_primary_default","favicon_black_default","Fragment","jsx","jsxs","getLogoSrc","type","color","LOGO_URLS","LionIcon","iconClassName","Logo","_a","_b","size","service","className","style","props","__objRest","logoClasses","hasCustomSize","rootProps","__spreadProps","__spreadValues","imgStyle","innerStyle","renderLogo","content","getText","ogText","ogLogoSrc","ogContent","text","fallbackContent","BREAKPOINTS","TAILWIND_SCREENS","MEDIA_QUERIES","LAYOUT_SYSTEM","jsx","LDSProvider","children","DialogProvider","ToastProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/stories/Button/ActionButton/ActionButton.tsx","../src/stories/Typography/Typography.tsx","../src/stories/Button/IconButton/IconButton.tsx","../src/stories/Tab/Tab.tsx","../src/stories/Badge/Badge.tsx","../src/stories/Chip/Chip.tsx","../node_modules/@heroicons/react/24/outline/esm/CheckIcon.js","../node_modules/@heroicons/react/24/outline/esm/XMarkIcon.js","../src/stories/Dialog/Dialog.tsx","../src/shared/hooks/useMediaQuery.ts","../src/stories/Toggle/Toggle.tsx","../src/stories/Checkbox/Checkbox.tsx","../src/stories/Checkbox/useCheckboxGroup.ts","../src/stories/Select/SelectHeader/SelectHeader.tsx","../src/stories/TextField/TextField.tsx","../node_modules/@heroicons/react/20/solid/esm/ExclamationCircleIcon.js","../src/stories/Select/SelectMenu/SelectMenu.tsx","../node_modules/@heroicons/react/24/solid/esm/CheckCircleIcon.js","../node_modules/@heroicons/react/24/solid/esm/ExclamationTriangleIcon.js","../node_modules/@heroicons/react/24/solid/esm/InformationCircleIcon.js","../node_modules/@heroicons/react/24/solid/esm/XCircleIcon.js","../src/stories/Select/SelectBox/SelectBox.tsx","../src/stories/Pagination/Pagination.tsx","../src/stories/RadioButton/RadioButton.tsx","../src/stories/Tag/Tag.tsx","../src/stories/Tooltip/Tooltip.tsx","../src/stories/Toast/Toast.tsx","../src/stories/DatePicker/DatePicker.tsx","../src/stories/DatePicker/Calendar.tsx","../src/stories/DatePicker/DateInput.tsx","../src/stories/DatePicker/TimePicker.tsx","../src/stories/Logo/logo-assets.ts","../src/stories/Logo/Logo.tsx","../src/stories/Screen/index.ts","../src/stories/LDSProvider.tsx"],"sourcesContent":["import React from \"react\";\nimport { Text } from \"@/stories/Typography/Typography\";\nimport \"./action-button.css\";\n\n/** label 내부의 Text를 span으로 렌더링 (p > h3 등 invalid nesting 방지) */\nfunction ensureTextAsSpan(node: React.ReactNode): React.ReactNode {\n if (React.isValidElement(node) && node.type === Text) {\n return React.cloneElement(node as React.ReactElement<{ as?: string }>, { as: \"span\" });\n }\n if (React.isValidElement(node)) {\n const { children, ...rest } = (node.props as { children?: React.ReactNode });\n if (children != null) {\n return React.cloneElement(\n node as React.ReactElement<{ children?: React.ReactNode }>,\n { ...rest, children: React.Children.map(children, ensureTextAsSpan) }\n );\n }\n }\n return node;\n}\n\nexport type ButtonSize = \"xlarge\" | \"large\" | \"medium\" | \"small\";\nexport type ButtonColor = \"primary\" | \"neutral\" | \"secondary\";\nexport type ButtonType = \"solid\" | \"outline\" | \"ghost\" | \"weak\";\nexport interface ActionButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\" // HTML type 속성과 이름 충돌 방지\n> {\n /** 버튼 크기 */\n size?: ButtonSize;\n /** 버튼 색상 (primary, neutral, secondary) */\n color?: ButtonColor;\n /** 버튼 스타일 타입 (solid, outline, ghost, weak) */\n type?: ButtonType;\n /** HTML 버튼 타입 (button, submit, reset) */\n htmlType?: \"button\" | \"submit\" | \"reset\";\n /** 비활성화 */\n disabled?: boolean;\n /** 로딩 상태 */\n loading?: boolean;\n /** 버튼 텍스트 */\n label: React.ReactNode;\n /** Prefix 아이콘 */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n}\n\n/** ActionButton 컴포넌트는 사용자가 어떠한 액션을 트리거하거나 이벤트를 실행할 때 사용한다. */\nexport const ActionButton = React.forwardRef<HTMLButtonElement, ActionButtonProps>(({\n size = \"medium\",\n color = \"primary\",\n type = \"solid\",\n htmlType = \"button\",\n label,\n prefixIcon,\n suffixIcon,\n loading = false,\n className = \"\",\n disabled = false,\n ...props\n}, ref) => {\n const isDisabled = disabled || loading;\n // ghost 타입은 loading 상태를 지원하지 않음\n const isLoading = loading && type !== \"ghost\";\n\n const baseClasses = [\n \"action-button\",\n `action-button--${size}`,\n `action-button--${color}`,\n `action-button--${type}`,\n isLoading && \"action-button--loading\",\n isDisabled && \"action-button--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const textVariant = (() => {\n if (size === \"xlarge\") {\n return \"heading-h6\";\n } else if (size === \"large\" || size === \"medium\") {\n return \"subtitle-p2\";\n } else if (size === \"small\") {\n return \"subtitle-p3\";\n } else {\n return \"subtitle-p3\";\n }\n })();\n\n return (\n <button\n ref={ref}\n type={htmlType}\n className={baseClasses}\n disabled={isDisabled}\n {...props}\n >\n <span className=\"action-button__content\">\n {prefixIcon && (\n <span className=\"action-button__prefix-icon\">{prefixIcon}</span>\n )}\n <span className=\"action-button__label\">\n <Text variant={textVariant} as=\"span\">{ensureTextAsSpan(label)}</Text>\n </span>\n {suffixIcon && (\n <span className=\"action-button__suffix-icon\">{suffixIcon}</span>\n )}\n </span>\n {isLoading && (\n <span className=\"action-button__spinner\" aria-hidden=\"true\">\n <svg\n className=\"action-button__spinner-svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n className=\"action-button__spinner-circle\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"32\"\n strokeDashoffset=\"32\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 40;40 40;0 40\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-40;-80\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n </span>\n )}\n </button>\n );\n});\n\nActionButton.displayName = \"ActionButton\";\n","import React from \"react\";\nimport \"./typography.css\";\n\nexport type TextVariant =\n | \"display-d1\"\n | \"display-d2\"\n | \"display-d3\"\n | \"display-d4\"\n | \"heading-h1\"\n | \"heading-h2\"\n | \"heading-h3\"\n | \"heading-h4\"\n | \"heading-h5\"\n | \"heading-h6\"\n | \"subtitle-p1\"\n | \"subtitle-p2\"\n | \"subtitle-p3\"\n | \"body-p1\"\n | \"body-p2\"\n | \"body-p3\"\n | \"body-p4\"\n | \"body-p5\";\n\nexport type TextDecoration = \"none\" | \"underline\";\n\nexport interface TextProps\n extends React.HTMLAttributes<HTMLElement> {\n /** Text 변형 */\n variant: TextVariant;\n /** 텍스트 장식 (underline 등) */\n decoration?: TextDecoration;\n /** HTML 태그 (기본값: variant에 따라 자동 결정) */\n as?: keyof React.JSX.IntrinsicElements;\n /** 자식 요소 */\n children: React.ReactNode;\n}\n\n/** Text 컴포넌트는 텍스트 스타일을 일관되게 적용하는 컴포넌트입니다. */\nexport const Text = React.forwardRef<HTMLElement, TextProps>(({\n variant,\n decoration = \"none\",\n as,\n children,\n className = \"\",\n ...props\n}, ref) => {\n // variant에 따라 기본 HTML 태그 결정\n const defaultTag = (() => {\n if (variant.startsWith(\"heading-\")) {\n const level = variant.split(\"-\")[1];\n if (level.startsWith(\"d\")) {\n return \"h1\"; // Display는 h1으로\n }\n return level; // h1, h2, h3, h4, h5, h6\n }\n if (variant.startsWith(\"subtitle-\")) {\n return \"h3\";\n }\n return \"p\"; // Body는 p 태그\n })();\n\n const Tag = (as || defaultTag) as keyof React.JSX.IntrinsicElements;\n\n const baseClasses = [\n \"typography\",\n `typography--${variant}`,\n decoration !== \"none\" && `typography--decoration-${decoration}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return React.createElement(Tag, { ref, className: baseClasses, ...props }, children);\n});\n\nText.displayName = \"Text\";\n","import React from \"react\";\n\nexport type IconButtonSize = \"xlarge\" | \"large\" | \"medium\" | \"small\";\n/** 버튼 색상. solid/outline: primary | neutral | secondary. weak: primary | neutral-dark | neutral-light */\nexport type IconButtonColor =\n | \"primary\"\n | \"neutral\"\n | \"secondary\"\n | \"neutral-dark\"\n | \"neutral-light\";\n/** 버튼 타입. weak일 때 color로 primary / neutral-dark / neutral-light 구분 */\nexport type IconButtonType = \"solid\" | \"outline\" | \"weak\";\n/** IconButton 슬롯 */\nexport type IconButtonSlot = \"root\" | \"icon\";\n\nexport interface IconButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n /** 버튼 크기 */\n size?: IconButtonSize;\n /** 버튼 색상. 기본 세트: primary, neutral, secondary 등 */\n color?: IconButtonColor;\n /** 버튼 타입 (solid, outline, weak) */\n type?: IconButtonType;\n /** 비활성화 */\n disabled?: boolean;\n /** 아이콘 (Heroicons 또는 React 컴포넌트) */\n icon: React.ReactNode;\n /** button 요소의 type (submit 등). 기본값 button */\n htmlType?: \"button\" | \"submit\" | \"reset\";\n /** 각 슬롯별 인라인 스타일 (root, icon) */\n styles?: Partial<Record<IconButtonSlot, React.CSSProperties>>;\n}\n\n/** IconButton 컴포넌트는 텍스트 레이블 없이 아이콘만으로 액션을 전달하는 버튼 컴포넌트이다. */\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(({\n size = \"large\",\n color = \"primary\",\n type = \"solid\",\n icon,\n className = \"\",\n disabled = false,\n htmlType = \"button\",\n style: propsStyle,\n styles,\n ...props\n}, ref) => {\n const isWeakType = type === \"weak\";\n\n const colorClass = isWeakType\n ? `icon-button--weak-${color}`\n : `icon-button--${color}`;\n const typeClass = isWeakType ? \"icon-button--weak\" : `icon-button--${type}`;\n\n const baseClasses = [\n \"icon-button\",\n `icon-button--${size}`,\n colorClass,\n typeClass,\n disabled && \"icon-button--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // weak 타입이고 disabled 상태일 때는 미노출 (opacity-0)\n const shouldHide = isWeakType && disabled;\n\n return (\n <button\n ref={ref}\n type={htmlType}\n className={baseClasses}\n disabled={disabled}\n style={{\n ...propsStyle,\n ...styles?.root,\n ...(shouldHide ? { opacity: 0, pointerEvents: \"none\" } : {}),\n }}\n {...props}\n >\n <span className=\"icon-button__icon\" style={styles?.icon}>{icon}</span>\n </button>\n );\n});\n\nIconButton.displayName = \"IconButton\";\n","import React, { useState, forwardRef } from \"react\";\nimport \"./tab.css\";\nimport { Badge } from \"../Badge/Badge\";\n\nexport type TabType = \"round\" | \"text\";\nexport type TabSize = \"large\" | \"medium\";\n\nexport interface TabProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n /** 탭 타입 (round 또는 text) */\n type?: TabType;\n /** 탭 크기 */\n size?: TabSize;\n /** 배지 표시 여부 */\n badge?: boolean;\n /** 탭 라벨 */\n label: React.ReactNode;\n /** 탭 값 (TabGroup에서 사용 시 식별자) */\n value?: string;\n /** 다크 모드 여부 */\n mode?: boolean;\n /** 선택된 상태 (탭 그룹에서 사용 시 부모 컴포넌트가 관리, 예: 기본 탭이 '설명'이면 selected={true}) */\n selected?: boolean;\n /** 비활성화 상태 */\n disabled?: boolean;\n}\n\n/** Tab 컴포넌트는 사용자가 여러 옵션 중 하나를 선택할 때 사용하는 탭 컴포넌트이다. */\nexport const Tab = forwardRef<HTMLButtonElement, TabProps>(({\n type = \"round\",\n size = \"large\",\n badge = false,\n label,\n mode = false,\n className = \"\",\n selected,\n disabled = false,\n onClick,\n ...props\n}, ref) => {\n // selected prop이 제공되면 controlled, 아니면 uncontrolled\n const [internalPressed, setInternalPressed] = useState(false);\n const isControlled = selected !== undefined;\n const isPressed = isControlled ? selected : internalPressed;\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n \n if (!isControlled) {\n // uncontrolled 모드: 내부 상태 토글\n setInternalPressed((prev) => !prev);\n }\n onClick?.(e);\n };\n\n const state = disabled ? \"disabled\" : (isPressed ? \"pressed\" : \"enabled\");\n\n const baseClasses = [\n \"tab\",\n `tab--${type}`,\n `tab--${size}`,\n `tab--${state}`,\n mode && \"tab--dark\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={baseClasses}\n aria-pressed={isPressed}\n disabled={disabled}\n onClick={handleClick}\n {...props}\n >\n <span className=\"tab__label\">{label}</span>\n {badge && (\n <Badge\n type=\"dot\"\n variant=\"primary\"\n className=\"tab__badge\"\n aria-label=\"알림\"\n />\n )}\n </button>\n );\n});\n\nTab.displayName = \"Tab\";\n\n// TabGroup\nexport interface TabItem {\n /** 탭 식별 값 */\n value: string;\n /** 탭 라벨 */\n label: React.ReactNode;\n /** 배지 표시 여부 */\n badge?: boolean;\n /** 개별 탭 비활성화 */\n disabled?: boolean;\n}\n\nexport interface TabGroupProps {\n /** 선택된 탭 값 (controlled) */\n value?: string;\n /** 초기 선택 탭 값 (uncontrolled) */\n defaultValue?: string;\n /** 선택 변경 핸들러 */\n onChange?: (value: string) => void;\n /** 탭 타입 (컨테이너 스타일: Round일 때 gap, Text일 때 하단 보더) */\n type?: TabType;\n /** 탭 크기 (컨테이너 gap 등) */\n size?: TabSize;\n /** 다크 모드 */\n mode?: boolean;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** 탭 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly TabItem[];\n /** 자식 Tab 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n /** 탭 간 간격 (px 또는 CSS 문자열). 미지정 시 기본 gap 적용 */\n gap?: number | string;\n /** 추가 CSS 클래스명 */\n className?: string;\n /** 인라인 스타일 */\n style?: React.CSSProperties;\n}\n\n/** TabGroup은 여러 Tab을 그룹화하여 단일 선택을 관리한다. */\nexport const TabGroup = ({\n value: valueProp,\n defaultValue,\n onChange,\n type = \"round\",\n size = \"large\",\n mode = false,\n disabled = false,\n items,\n children,\n gap,\n className = \"\",\n style,\n}: TabGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string | undefined>(\n defaultValue\n );\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const baseClasses = [\n \"tab-group\",\n `tab-group--${type}`,\n `tab-group--${size}`,\n mode && \"tab-group--dark\",\n disabled && \"tab-group--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const groupStyle: React.CSSProperties | undefined = {\n ...(gap != null && { gap: typeof gap === \"number\" ? `${gap}px` : gap }),\n ...style,\n };\n\n const handleTabClick = (tabValue: string, originalOnClick?: (e: React.MouseEvent<HTMLButtonElement>) => void) =>\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!isControlled) setInternalValue(tabValue);\n onChange?.(tabValue);\n originalOnClick?.(e);\n };\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedTabs = items\n ? items.map((item) => {\n const isSelected = value === item.value;\n return (\n <Tab\n key={item.value}\n value={item.value}\n label={item.label}\n badge={item.badge}\n type={type}\n size={size}\n mode={mode}\n selected={isSelected}\n disabled={disabled || item.disabled}\n role=\"tab\"\n aria-selected={isSelected}\n onClick={handleTabClick(item.value)}\n />\n );\n })\n : React.Children.map(children, (child) => {\n if (React.isValidElement<TabProps>(child) && child.type === Tab) {\n const tabValue = child.props.value;\n if (tabValue === undefined) {\n console.warn(\"TabGroup 내부의 Tab은 value prop이 필요합니다.\");\n return child;\n }\n\n const isSelected = value === tabValue;\n\n return React.cloneElement(child, {\n type: child.props.type ?? type,\n size: child.props.size ?? size,\n mode: child.props.mode ?? mode,\n selected: isSelected,\n disabled: disabled || child.props.disabled,\n role: \"tab\",\n \"aria-selected\": isSelected,\n onClick: handleTabClick(tabValue, child.props.onClick),\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses} style={groupStyle} role=\"tablist\">\n {renderedTabs}\n </div>\n );\n};\n\nTabGroup.displayName = \"TabGroup\";\n\n(Tab as typeof Tab & { Group: typeof TabGroup }).Group = TabGroup;\n\n","import React from \"react\";\nimport \"./badge.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type BadgeVariant =\n | \"primary\"\n | \"secondary\"\n | \"progressing\"\n | \"success\"\n | \"warning\"\n | \"error\"\n | \"disabled\";\nexport type BadgeType = \"number\" | \"dot\";\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** number: 글자(숫자/문자) 표시, dot: 점만 표시 */\n type?: BadgeType;\n /** Badge variant (primary, secondary, progressing, success, warning, error, disabled) */\n variant?: BadgeVariant;\n /** Badge 값 (type이 number일 때 표시할 숫자 또는 글자) */\n value?: number | string;\n /** 최대 표시 숫자 (숫자일 때 이 값을 넘으면 maxValue+ 형태로 표시) */\n maxValue?: number;\n}\n\n/** Badge 컴포넌트는 알림 카운트, 상태 등을 시각적으로 표현하는 원형 라벨 컴포넌트다. */\nexport const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(({\n type = \"number\",\n variant = \"primary\",\n value,\n maxValue = 99,\n className = \"\",\n ...props\n}, ref) => {\n const baseClasses = [\n \"badge\",\n `badge--${variant}`,\n `badge--${type}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const displayValue =\n type === \"number\" && value !== undefined\n ? typeof value === \"number\"\n ? value > maxValue\n ? `${maxValue}+`\n : String(value)\n : String(value)\n : null;\n\n return (\n <span ref={ref} className={baseClasses} {...props}>\n {type === \"number\" && displayValue && (\n <Text variant=\"subtitle-p3\" as=\"span\">\n {displayValue}\n </Text>\n )}\n </span>\n );\n});\n\nBadge.displayName = \"Badge\";\n","import React from \"react\";\nimport { CheckIcon } from \"@heroicons/react/24/outline\";\nimport \"./chip.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type ChipType = \"solid\" | \"outline\" | \"weak\";\nexport type ChipSize = \"medium\" | \"small\";\nexport type ChipVariant = \"primary\" | \"neutral\";\n\nexport interface ChipProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\" | \"onChange\"\n> {\n /** Chip 타입 (solid, outline, weak) */\n type?: ChipType;\n /** Chip 크기 */\n size?: ChipSize;\n /** Chip variant (primary, neutral) */\n variant?: ChipVariant;\n /** Chip 값 (각 Chip을 구분하는 고유 값) */\n value: string;\n /** Chip 클릭 핸들러 (클릭 시 해당 Chip의 value를 전달) */\n onChange?: (value: string) => void;\n /** Chip 선택 상태 (controlled 모드) */\n checked?: boolean;\n /** Chip 초기 선택 상태 (uncontrolled 모드) */\n defaultChecked?: boolean;\n /** 단일 선택 그룹에서 선택된 값 (checked prop이 없을 때 자동으로 checked 계산) */\n selectedValue?: string | null;\n /** 다중 선택 그룹에서 선택된 값들 (checked prop이 없을 때 자동으로 checked 계산) */\n selectedValues?: string[];\n /** Chip 라벨 */\n label: React.ReactNode;\n /** Prefix 아이콘 (항상 표시) */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n /** \n * Checked 상태일 때 체크 아이콘 표시 여부\n * - 기본값: undefined (outline 타입이고 prefixIcon이 없을 때만 자동 표시)\n * - true: 항상 표시 (checked 상태일 때)\n * - false: 표시 안 함\n */\n showCheck?: boolean;\n /** Close 버튼 표시 여부 */\n showClose?: boolean;\n /** Close 버튼 클릭 핸들러 */\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\n/** Chip 컴포넌트는 사용자가 직접 선택, 추가, 삭제할 수 있는 인터랙티브한 컴포넌트다. */\nconst ChipComponent = React.forwardRef<HTMLButtonElement, ChipProps>(({\n type = \"solid\",\n size = \"medium\",\n variant = \"primary\",\n value,\n onChange,\n checked: checkedProp,\n defaultChecked = false,\n selectedValue,\n selectedValues,\n label,\n prefixIcon,\n suffixIcon,\n showCheck,\n showClose = false,\n onClose,\n className = \"\",\n disabled,\n onClick,\n ...props\n}, ref) => {\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] = React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n\n // checked 상태 결정\n const checked = React.useMemo(() => {\n if (isControlled) {\n return checkedProp;\n }\n if (selectedValue !== undefined && selectedValue !== null) {\n return selectedValue === value;\n }\n if (selectedValues !== undefined) {\n return selectedValues.includes(value);\n }\n return internalChecked;\n }, [\n isControlled,\n checkedProp,\n selectedValue,\n selectedValues,\n value,\n internalChecked,\n ]);\n\n // 체크 아이콘 렌더링 결정\n let shouldRenderCheckIcon = false;\n\n if (checked) {\n if (showCheck === true) {\n // 강제 표시\n shouldRenderCheckIcon = true;\n } else if (showCheck === false) {\n // 강제 미표시\n shouldRenderCheckIcon = false;\n } else {\n // 기본 로직: outline 타입이고 prefixIcon이 없을 때만 자동 표시\n shouldRenderCheckIcon = type === \"outline\" && !prefixIcon;\n }\n }\n\n const renderedCheckIcon = shouldRenderCheckIcon ? (\n <CheckIcon\n className=\"chip__check-icon\"\n style={{\n width: size === \"small\" ? \"14px\" : \"16px\",\n height: size === \"small\" ? \"14px\" : \"16px\",\n }}\n />\n ) : null;\n\n // 최종 Prefix 영역: prefixIcon이 있으면 우선, 없으면 체크 아이콘\n // (showCheck={true}일 때도 prefixIcon이 있으면 prefixIcon이 우선시됨)\n const displayLeftIcon = prefixIcon || renderedCheckIcon;\n\n // 아이콘 조합에 따른 패딩 클래스 결정\n const hasPrefix = !!displayLeftIcon;\n const hasSuffix = !!(suffixIcon || showClose);\n\n const paddingClass = (() => {\n if (hasPrefix && hasSuffix) {\n return \"chip--has-prefix-suffix\";\n } else if (hasPrefix) {\n return \"chip--has-prefix\";\n } else if (hasSuffix) {\n return \"chip--has-suffix\";\n }\n return \"chip--no-icon\";\n })();\n\n const baseClasses = [\n \"chip\",\n `chip--${type}`,\n `chip--${size}`,\n `chip--${variant}`,\n paddingClass,\n checked && \"chip--checked\",\n disabled && \"chip--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n\n if (\n !isControlled &&\n selectedValue === undefined &&\n selectedValues === undefined\n ) {\n setInternalChecked((prev) => !prev);\n }\n\n if (onChange) {\n onChange(value);\n }\n\n onClick?.(e);\n };\n\n const handleClose = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (onClose && !disabled) {\n onClose(e);\n }\n };\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={baseClasses}\n disabled={disabled}\n onClick={handleClick}\n aria-pressed={checked}\n {...props}\n >\n {displayLeftIcon && (\n <span className=\"chip__prefix-icon\">{displayLeftIcon}</span>\n )}\n <Text variant={size === \"small\" ? \"body-p3\" : \"body-p2\"}>{label}</Text>\n {suffixIcon && !showClose && (\n <span className=\"chip__suffix-icon\">{suffixIcon}</span>\n )}\n {showClose && (\n <span\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n className=\"chip__close-button\"\n onClick={handleClose}\n onKeyDown={(e) => {\n if (!disabled && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n handleClose(e as unknown as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n aria-label=\"Close\"\n aria-disabled={disabled}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M8 1C11.866 1 15 4.13401 15 8C15 11.866 11.866 15 8 15C4.13401 15 1 11.866 1 8C1 4.13401 4.13401 1 8 1ZM10.7803 5.21973C10.4874 4.92683 10.0126 4.92683 9.71973 5.21973L8 6.93945L6.28027 5.21973C5.98738 4.92683 5.51262 4.92683 5.21973 5.21973C4.92683 5.51262 4.92683 5.98738 5.21973 6.28027L6.93945 8L5.21973 9.71973C4.92683 10.0126 4.92683 10.4874 5.21973 10.7803C5.51262 11.0732 5.98738 11.0732 6.28027 10.7803L8 9.06055L9.71973 10.7803C10.0126 11.0732 10.4874 11.0732 10.7803 10.7803C11.0732 10.4874 11.0732 10.0126 10.7803 9.71973L9.06055 8L10.7803 6.28027C11.0732 5.98738 11.0732 5.51262 10.7803 5.21973Z\"\n fill=\"currentColor\"\n fillOpacity=\"0.56\"\n />\n </svg>\n </span>\n )}\n </button>\n );\n});\n\n// Chip.Group\nexport interface ChipItem {\n /** Chip 식별 값 */\n value: string;\n /** Chip 라벨 */\n label: React.ReactNode;\n /** Prefix 아이콘 */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n /** 체크 아이콘 표시 여부 */\n showCheck?: boolean;\n /** Close 버튼 표시 여부 */\n showClose?: boolean;\n /** Close 버튼 클릭 핸들러 */\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n /** 개별 Chip 비활성화 */\n disabled?: boolean;\n}\n\nexport interface ChipGroupProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 선택된 값 (controlled) - 단일: string, 다중: string[] */\n value?: string | string[];\n /** 초기 선택 값 (uncontrolled) */\n defaultValue?: string | string[];\n /** 선택 변경 시 호출 (클릭한 Chip의 value 전달) */\n onChange?: (value: string) => void;\n /** 다중 선택 여부 */\n multiple?: boolean;\n /** Chip 타입 */\n type?: ChipType;\n /** Chip 크기 */\n size?: ChipSize;\n /** Chip variant */\n variant?: ChipVariant;\n /** 체크 아이콘 표시 여부 (자식 Chip에 일괄 적용) */\n showCheck?: boolean;\n /** 전체 비활성화 */\n disabled?: boolean;\n /** Chip 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly ChipItem[];\n /** 자식 Chip 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n}\n\n/** ChipGroup은 여러 Chip을 그룹화하여 단일/다중 선택을 관리한다. */\nexport const ChipGroup = ({\n value: valueProp,\n defaultValue,\n onChange,\n multiple = false,\n type = \"solid\",\n size = \"medium\",\n variant = \"primary\",\n showCheck,\n disabled = false,\n items,\n children,\n className = \"\",\n ...rest\n}: ChipGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n () => defaultValue ?? (multiple ? [] : \"\")\n );\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const handleChange = (chipValue: string) => {\n if (multiple) {\n const arr = (Array.isArray(value) ? value : []) as string[];\n const next = arr.includes(chipValue)\n ? arr.filter((v) => v !== chipValue)\n : [...arr, chipValue];\n if (!isControlled) setInternalValue(next);\n onChange?.(chipValue);\n } else {\n if (!isControlled) setInternalValue(chipValue);\n onChange?.(chipValue);\n }\n };\n\n const selectedValue = multiple ? undefined : (value as string);\n const selectedValues = multiple ? (value as string[]) : undefined;\n\n const baseClasses = [\"chip-group\", className].filter(Boolean).join(\" \");\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedChips = items\n ? items.map((item) => (\n <ChipComponent\n key={item.value}\n value={item.value}\n label={item.label}\n type={type}\n size={size}\n variant={variant}\n showCheck={item.showCheck ?? showCheck}\n prefixIcon={item.prefixIcon}\n suffixIcon={item.suffixIcon}\n showClose={item.showClose}\n onClose={item.onClose}\n selectedValue={selectedValue}\n selectedValues={selectedValues}\n onChange={handleChange}\n disabled={disabled || item.disabled}\n />\n ))\n : React.Children.map(children, (child) => {\n if (React.isValidElement<ChipProps>(child) && child.type === Chip) {\n const chipValue = child.props.value;\n if (chipValue === undefined) {\n console.warn(\"ChipGroup 내부의 Chip은 value prop이 필요합니다.\");\n return child;\n }\n\n return React.cloneElement(child, {\n type: child.props.type ?? type,\n size: child.props.size ?? size,\n variant: child.props.variant ?? variant,\n showCheck: child.props.showCheck ?? showCheck,\n selectedValue,\n selectedValues,\n onChange: (v: string) => {\n handleChange(v);\n child.props.onChange?.(v);\n },\n disabled: disabled || child.props.disabled,\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses} {...rest}>\n {renderedChips}\n </div>\n );\n};\n\nChipGroup.displayName = \"ChipGroup\";\nChipComponent.displayName = \"Chip\";\n\nexport const Chip = Object.assign(ChipComponent, {\n Group: ChipGroup,\n});\n","import * as React from \"react\";\nfunction CheckIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"m4.5 12.75 6 6 9-13.5\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(CheckIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction XMarkIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n strokeWidth: 1.5,\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n d: \"M6 18 18 6M6 6l12 12\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(XMarkIcon);\nexport default ForwardRef;","import React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { XMarkIcon } from \"@heroicons/react/24/outline\";\nimport { ActionButton } from \"../Button/ActionButton/ActionButton\";\nimport type {\n ButtonSize,\n ButtonColor,\n ButtonType,\n} from \"../Button/ActionButton/ActionButton\";\nimport \"./dialog.css\";\nimport \"../Button/ActionButton/action-button.css\";\nimport { useBreakpoint } from \"../../shared/hooks/useMediaQuery\";\nimport { Text } from \"../Typography/Typography\";\nimport \"../Typography/typography.css\";\n\n// -------------------- Contexts --------------------\n\nconst DialogContext = React.createContext<{\n onClose?: () => void;\n variant?: DialogVariant;\n} | null>(null);\n\n// -------------------- Types --------------------\n\nexport type DialogAlign = \"center\" | \"left\";\nexport type DialogFooterLayout = \"horizontal\" | \"vertical\";\nexport type DialogVariant = \"alert\" | \"confirm\";\nexport type DialogActionColor = ButtonColor;\nexport type DialogActionType = ButtonType;\nexport type DialogActionSize = Exclude<ButtonSize, \"xlarge\">;\n\n/** 기존 방식의 Action Item 정의 */\nexport interface DialogActionItem {\n label: string;\n color?: DialogActionColor;\n type?: DialogActionType;\n size?: DialogActionSize;\n prefixIcon?: React.ReactNode;\n suffixIcon?: React.ReactNode;\n loading?: boolean;\n disabled?: boolean;\n onClick?: () => void | Promise<void>;\n /** 클릭 시 다이얼로그 닫기 여부 (기본값: true) */\n closeOnClick?: boolean;\n}\n\nexport interface DialogProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n open?: boolean;\n onClose?: () => void;\n /** 오버레이 클릭 시 닫기 여부 (기본값: true) */\n closeOnOverlayClick?: boolean;\n /** ESC 키로 닫기 여부 (기본값: true) */\n closeOnEsc?: boolean;\n /** 우측 상단 X(닫기) 버튼 표시 여부 (기본값: false) */\n withClose?: boolean;\n /** 다이얼로그 타입 (스타일링용) */\n variant?: DialogVariant;\n /** 정렬 (기본값: variant가 alert면 left, 아니면 center) */\n align?: DialogAlign;\n \n // --- Data-driven Props (편의성 및 하위 호환성) ---\n /** 다이얼로그 제목 */\n title?: React.ReactNode;\n /** 다이얼로그 본문/설명 */\n description?: React.ReactNode;\n /** 다이얼로그 아이콘 */\n icon?: React.ReactNode;\n /** 하단 버튼 목록 (Compound Component 대신 사용 가능) */\n actionItems?: DialogActionItem[];\n /** actionItems 사용 시 버튼 레이아웃 */\n footerLayout?: DialogFooterLayout;\n /** 다이얼로그 너비 (미지정 시 기본 고정 너비 사용) */\n width?: number | string;\n\n className?: string;\n children?: React.ReactNode;\n}\n\n// -------------------- Components --------------------\n\nconst DialogRoot = ({\n open = false,\n onClose,\n closeOnOverlayClick = true,\n closeOnEsc = true,\n withClose = false,\n variant = \"confirm\",\n align,\n \n // Data-driven props\n title,\n description,\n icon,\n actionItems,\n footerLayout = \"horizontal\",\n width,\n\n className = \"\",\n children,\n ...props\n}: DialogProps) => {\n const { isUnderTablet } = useBreakpoint();\n\n // mounted 상태 확인 (SSR 대응)\n const [mounted, setMounted] = React.useState(false);\n React.useEffect(() => {\n setMounted(true);\n return () => setMounted(false);\n }, []);\n\n React.useEffect(() => {\n if (!open) return;\n\n // Body Scroll Lock\n const originalStyle = window.getComputedStyle(document.body).overflow;\n document.body.style.overflow = \"hidden\";\n\n if (closeOnEsc) {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose?.();\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n document.body.style.overflow = originalStyle; // Cleanup 시 복원\n };\n }\n \n return () => {\n document.body.style.overflow = originalStyle; // Cleanup 시 복원\n };\n }, [open, closeOnEsc, onClose]);\n\n if (!open) return null;\n\n const resolvedAlign = align ?? (variant === \"alert\" ? \"left\" : \"center\");\n const baseClasses = [\n \"dialog\",\n `dialog--${variant}`,\n `dialog--${resolvedAlign}`,\n isUnderTablet ? \"is-mobile\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget && closeOnOverlayClick) {\n onClose?.();\n }\n };\n\n // props가 있으면 보이고, children이 있으면 children도 보임\n const contentNode = (\n <>\n {(title || icon) && <DialogHeader title={title} icon={icon} />}\n {description && <DialogBody>{description}</DialogBody>}\n {children}\n {actionItems && actionItems.length > 0 && (\n <DialogFooter layout={footerLayout}>\n {actionItems.map((item, idx) => (\n <DialogButton\n key={`${item.label}-${idx}`}\n label={item.label}\n color={item.color}\n type={item.type}\n size={item.size}\n prefixIcon={item.prefixIcon}\n suffixIcon={item.suffixIcon}\n loading={item.loading}\n disabled={item.disabled}\n onClick={item.onClick}\n closeOnClick={item.closeOnClick ?? true}\n />\n ))}\n </DialogFooter>\n )}\n </>\n );\n\n const dialogOverlay = (\n <div\n className=\"dialog-overlay\"\n role=\"presentation\"\n onClick={handleOverlayClick}\n >\n <div className={baseClasses} role=\"dialog\" aria-modal=\"true\" style={width != null ? { width } : undefined} {...props}>\n <DialogContext.Provider value={{ onClose, variant }}>\n {withClose && (\n <button\n type=\"button\"\n className=\"dialog__close\"\n onClick={onClose}\n aria-label=\"닫기\"\n >\n <XMarkIcon className=\"dialog__close-icon\" />\n </button>\n )}\n {contentNode}\n </DialogContext.Provider>\n </div>\n </div>\n );\n\n // mounted 상태 확인 (SSR 대응) - 상단에서 처리됨\n // const [mounted, setMounted] = React.useState(false);\n // React.useEffect(() => {\n // setMounted(true);\n // return () => setMounted(false);\n // }, []);\n\n if (!mounted) return null;\n\n return createPortal(dialogOverlay, document.body);\n};\n\n// --- Sub Components ---\n\nexport interface DialogHeaderProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n title?: React.ReactNode;\n icon?: React.ReactNode;\n}\n\nconst DialogHeader = ({\n title,\n icon,\n className = \"\",\n children,\n ...props\n}: DialogHeaderProps) => {\n const { isUnderTablet } = useBreakpoint();\n return (\n <div className={`dialog__header ${className}`} {...props}>\n {icon && <span className=\"dialog__icon\">{icon}</span>}\n {title && (\n <Text variant={isUnderTablet ? \"subtitle-p1\" : \"heading-h6\"}>\n {title}\n </Text>\n )}\n {children}\n </div>\n );\n};\n\nexport type DialogBodyProps = React.HTMLAttributes<HTMLDivElement>\n\nconst DialogBody = ({ className = \"\", children, ...props }: DialogBodyProps) => {\n return (\n <div className={`dialog__body ${className}`} {...props}>\n <div className=\"body-p2 dialog__body-text\">{children}</div>\n </div>\n );\n};\n\nexport interface DialogFooterProps\n extends React.HTMLAttributes<HTMLDivElement> {\n layout?: DialogFooterLayout;\n}\n\nconst DialogFooter = ({\n layout = \"horizontal\",\n className = \"\",\n children,\n ...props\n}: DialogFooterProps) => {\n const layoutClass =\n layout === \"vertical\"\n ? \"dialog__actions--vertical\"\n : \"dialog__actions--horizontal\";\n\n return (\n <div\n className={`dialog__footer dialog__footer--${layout} ${className}`}\n {...props}\n >\n <div className={`dialog__actions ${layoutClass}`}>{children}</div>\n </div>\n );\n};\n\n// DialogButton: ActionButton을 래핑하여 Dialog 컨텍스트와 연동\nexport interface DialogButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n label: string;\n color?: ButtonColor;\n type?: ButtonType;\n size?: Exclude<ButtonSize, \"xlarge\">;\n prefixIcon?: React.ReactNode;\n suffixIcon?: React.ReactNode;\n loading?: boolean;\n disabled?: boolean;\n /** 클릭 시 다이얼로그 닫기 여부 (기본값: false - 명시적으로 닫아야 함) */\n closeOnClick?: boolean;\n}\n\nconst DialogButton = ({\n label,\n color,\n type,\n size,\n prefixIcon,\n suffixIcon,\n loading,\n disabled,\n onClick,\n closeOnClick = false,\n style,\n ...props\n}: DialogButtonProps) => {\n const context = React.useContext(DialogContext);\n const { isUnderTablet } = useBreakpoint();\n\n // 기본 스타일 계산\n const variant = context?.variant ?? \"confirm\";\n const buttonWidth = variant === \"confirm\" ? \"100%\" : \"auto\";\n const defaultSize =\n variant === \"alert\" ? (isUnderTablet ? \"small\" : \"medium\") : \"large\";\n const defaultType = variant === \"alert\" ? \"outline\" : \"solid\";\n const defaultColor = \"neutral\"; \n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (closeOnClick) {\n context?.onClose?.();\n }\n };\n\n return (\n <ActionButton\n label={label}\n size={size ?? defaultSize}\n color={color ?? defaultColor}\n type={type ?? defaultType}\n prefixIcon={prefixIcon}\n suffixIcon={suffixIcon}\n loading={loading}\n disabled={disabled}\n onClick={handleClick}\n style={{ width: buttonWidth, ...style }}\n {...props}\n />\n );\n};\n\n// --- Export with Compound Component Pattern ---\n\nDialogRoot.displayName = \"Dialog\";\n\nexport const Dialog = Object.assign(DialogRoot, {\n Header: DialogHeader,\n Body: DialogBody,\n Footer: DialogFooter,\n Button: DialogButton,\n});\n\n// -------------------- Global Provider & Hook --------------------\n\nexport interface DialogOptions {\n id?: string;\n variant?: DialogVariant;\n align?: DialogAlign;\n title?: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n // Hook에서 사용할 때는 간단한 버튼 정의 (Compound 대신)\n buttons?: DialogActionItem[];\n \n onClose?: () => void;\n closeOnOverlayClick?: boolean;\n closeOnEsc?: boolean;\n withClose?: boolean;\n}\n\nexport interface AlertOptions extends Omit<DialogOptions, \"buttons\"> {\n confirmLabel?: string;\n onConfirm?: () => void | Promise<void>;\n}\n\nexport interface ConfirmOptions extends Omit<DialogOptions, \"buttons\"> {\n confirmLabel?: string;\n cancelLabel?: string;\n onConfirm?: () => void | Promise<void>;\n onCancel?: () => void | Promise<void>;\n}\n\ninterface DialogContextType {\n open: (options: DialogOptions) => string;\n close: (id: string) => void;\n closeAll: () => void;\n alert: (options: AlertOptions) => Promise<void>;\n confirm: (options: ConfirmOptions) => Promise<boolean>;\n}\n\nconst GlobalDialogContext = React.createContext<DialogContextType | undefined>(\n undefined\n);\n\nexport const DialogProvider = ({ children }: { children: React.ReactNode }) => {\n const [dialogs, setDialogs] = React.useState<\n (DialogOptions & { id: string })[]\n >([]);\n\n const close = React.useCallback((id: string) => {\n setDialogs((prev) => prev.filter((d) => d.id !== id));\n }, []);\n\n const closeAll = React.useCallback(() => {\n setDialogs([]);\n }, []);\n\n const open = React.useCallback(\n (options: DialogOptions) => {\n const id = options.id || `dialog-${Date.now()}-${Math.random()}`;\n setDialogs((prev) => [...prev, { ...options, id }]);\n return id;\n },\n []\n );\n\n const alert = React.useCallback(\n (options: AlertOptions) => {\n return new Promise<void>((resolve) => {\n const id = `alert-${Date.now()}`;\n open({\n ...options,\n id,\n variant: options.variant ?? \"alert\",\n buttons: [\n {\n label: options.confirmLabel ?? \"확인\",\n color: \"primary\",\n type: \"solid\",\n closeOnClick: true,\n onClick: async () => {\n await options.onConfirm?.();\n resolve();\n },\n },\n ],\n onClose: () => {\n resolve();\n close(id);\n },\n });\n });\n },\n [open, close]\n );\n\n const confirm = React.useCallback(\n (options: ConfirmOptions) => {\n return new Promise<boolean>((resolve) => {\n const id = `confirm-${Date.now()}`;\n open({\n ...options,\n id,\n variant: options.variant ?? \"confirm\",\n buttons: [\n {\n label: options.cancelLabel ?? \"취소\",\n color: \"neutral\",\n type: \"outline\",\n closeOnClick: true,\n onClick: async () => {\n await options.onCancel?.();\n resolve(false);\n },\n },\n {\n label: options.confirmLabel ?? \"확인\",\n color: \"primary\",\n type: \"solid\",\n closeOnClick: true,\n onClick: async () => {\n await options.onConfirm?.();\n resolve(true);\n },\n },\n ],\n onClose: () => {\n resolve(false);\n close(id);\n },\n });\n });\n },\n [open, close]\n );\n\n return (\n <GlobalDialogContext.Provider\n value={{ open, close, closeAll, alert, confirm }}\n >\n {children}\n {/* DialogRoot 내부에서 이미 createPortal을 사용하므로, 여기서는 그냥 렌더링하면 됨 */}\n {dialogs.map((dialog) => (\n <DialogRoot\n key={dialog.id}\n open={true}\n onClose={() => {\n dialog.onClose?.();\n close(dialog.id);\n }}\n variant={dialog.variant}\n align={dialog.align}\n closeOnOverlayClick={dialog.closeOnOverlayClick}\n closeOnEsc={dialog.closeOnEsc}\n withClose={dialog.withClose}\n // Data-driven props 전달\n title={dialog.title}\n description={dialog.description}\n icon={dialog.icon}\n actionItems={dialog.buttons}\n />\n ))}\n </GlobalDialogContext.Provider>\n );\n};\n\nexport function useDialog() {\n const context = React.useContext(GlobalDialogContext);\n if (!context) {\n throw new Error(\"useDialog must be used within a DialogProvider\");\n }\n return context;\n}\n","import React, { createContext, useContext, useSyncExternalStore } from 'react';\n\n\n// 1. 상태 타입 정의\ninterface BreakpointContextType {\n isMobile?: boolean;\n isTablet?: boolean;\n isDesktop?: boolean;\n isUnderTablet?: boolean;\n }\n \n // 2. Context 생성\n const BreakpointContext = createContext<BreakpointContextType | null>(null);\n \n // 3. Provider (스토리북 등에서 사용)\n export const BreakpointProvider = BreakpointContext.Provider;\n\nexport function useMediaQuery(query: string): boolean {\n // SSR 환경에서는 기본값으로 false를 반환합니다.\n const subscribe = (callback: () => void) => {\n const matchMedia = window.matchMedia(query);\n matchMedia.addEventListener(\"change\", callback);\n return () => matchMedia.removeEventListener(\"change\", callback);\n };\n\n const getSnapshot = () => {\n return window.matchMedia(query).matches;\n };\n\n const getServerSnapshot = () => {\n return false; // 서버 사이드에서는 항상 false (혹은 기본 레이아웃 기준)\n };\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * 프로젝트 브레이크포인트 전용 훅\n */\nexport function useBreakpoint() {\n // Context에 값이 들어있다면 (스토리북에서 강제했다면) 그 값을 우선 사용\n const contextValue = useContext(BreakpointContext);\n \n // 실제 윈도우 미디어 쿼리 구독\n const isMobileQuery = useMediaQuery(\"(min-width: 375px) and (max-width: 743px)\");\n const isTabletQuery = useMediaQuery(\"(min-width: 744px) and (max-width: 1279px)\");\n const isDesktopQuery = useMediaQuery(\"(min-width: 1280px)\");\n const isUnderTabletQuery = useMediaQuery(\"(max-width: 743px)\");\n \n // 수정 포인트: \n // contextValue가 있더라도 내부의 특정 값(예: isMobile)이 없을 수 있으므로 \n // 널 병합 연산자(??)를 사용해 실제 쿼리 결과값을 기본값으로 넣어줍니다.\n return {\n isMobile: contextValue?.isMobile ?? isMobileQuery,\n isTablet: contextValue?.isTablet ?? isTabletQuery,\n isDesktop: contextValue?.isDesktop ?? isDesktopQuery,\n isUnderTablet: contextValue?.isUnderTablet ?? isUnderTabletQuery,\n };\n }","import React from \"react\";\nimport \"./toggle.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type ToggleSize = \"medium\" | \"small\";\nexport type ToggleLabelPosition = \"start\" | \"end\";\n\nexport interface ToggleProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\" | \"onChange\" | \"type\"\n> {\n /** Toggle 크기 */\n size?: ToggleSize;\n /** Toggle 라벨 */\n label?: React.ReactNode;\n /** Toggle 라벨 위치 */\n labelPosition?: ToggleLabelPosition;\n /** Toggle 설명 텍스트 */\n description?: React.ReactNode;\n /** Toggle 상태 변경 핸들러 */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/** Toggle 컴포넌트는 사용자가 on/off 상태를 전환할 수 있는 스위치 컴포넌트다. */\nexport const Toggle = React.forwardRef<HTMLInputElement, ToggleProps>(\n (\n {\n size = \"medium\",\n label,\n labelPosition = \"end\",\n description,\n checked: checkedProp,\n defaultChecked = false,\n onChange,\n disabled,\n className = \"\",\n id,\n ...props\n },\n ref\n ) => {\n const inputRef = React.useRef<HTMLInputElement>(null);\n const combinedRef = React.useMemo(() => {\n if (typeof ref === \"function\") {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n ref(node);\n };\n } else if (ref) {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (ref) ref.current = node;\n };\n }\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n };\n }, [ref]);\n\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] =\n React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n\n onChange?.(e);\n };\n\n const generatedId = React.useId();\n const toggleId = id || generatedId;\n const descriptionId = description ? `${toggleId}-description` : undefined;\n\n const baseClasses = [\n \"toggle\",\n `toggle--${size}`,\n labelPosition === \"start\" && \"toggle--label-start\",\n disabled && \"toggle--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={baseClasses}>\n <div className=\"toggle__wrapper\">\n <input\n ref={combinedRef}\n type=\"checkbox\"\n id={toggleId}\n checked={checked}\n defaultChecked={defaultChecked}\n onChange={handleChange}\n disabled={disabled}\n aria-describedby={descriptionId}\n className=\"toggle__input\"\n role=\"switch\"\n aria-checked={checked}\n {...props}\n />\n <label htmlFor={toggleId} className=\"toggle__label-wrapper\">\n {labelPosition === \"start\" && label && (\n <Text\n variant={size === \"medium\" ? \"body-p2\" : \"body-p3\"}\n as=\"span\"\n >\n {label}\n </Text>\n )}\n <span className=\"toggle__switch\">\n <span className=\"toggle__thumb\" />\n </span>\n {labelPosition === \"end\" && label && (\n <Text\n variant={size === \"medium\" ? \"body-p2\" : \"body-p3\"}\n as=\"span\"\n >\n {label}\n </Text>\n )}\n </label>\n </div>\n {description && (\n <div id={descriptionId} className=\"toggle__description\">\n {description}\n </div>\n )}\n </div>\n );\n }\n);\n\nToggle.displayName = \"Toggle\";\n","import React from \"react\";\nimport \"./checkbox.css\";\nimport {\n RiCheckboxBlankLine,\n RiCheckboxFill,\n RiCheckboxIndeterminateFill,\n} from \"@remixicon/react\";\nimport { Text } from \"../Typography/Typography\";\n\nexport interface CheckboxProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\" | \"onChange\"> {\n /** Checkbox 라벨 */\n label?: React.ReactNode;\n /** label 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** Checkbox 설명 텍스트 */\n description?: React.ReactNode;\n /** Checkbox 값 (Checkbox.Group에서 사용) */\n value?: string;\n /** Checkbox 상태 변경 핸들러 */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n /** Indeterminate 상태 (부분 선택 상태) */\n indeterminate?: boolean;\n}\n\n/** Checkbox 컴포넌트는 사용자가 선택/해제할 수 있는 체크박스 입력 컴포넌트다. */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n label,\n labelProps,\n description,\n value,\n checked: checkedProp,\n defaultChecked = false,\n onChange,\n disabled,\n indeterminate = false,\n className = \"\",\n id,\n ...props\n },\n ref\n ) => {\n const inputRef = React.useRef<HTMLInputElement>(null);\n const combinedRef = React.useMemo(() => {\n if (typeof ref === \"function\") {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n ref(node);\n };\n } else if (ref) {\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (ref) ref.current = node;\n };\n }\n return (node: HTMLInputElement | null) => {\n inputRef.current = node;\n };\n }, [ref]);\n\n // Indeterminate 상태 설정\n React.useEffect(() => {\n if (inputRef.current) {\n inputRef.current.indeterminate = indeterminate;\n }\n }, [indeterminate]);\n\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] = React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n\n onChange?.(e);\n };\n\n const generatedId = React.useId();\n const checkboxId = id || generatedId;\n const descriptionId = description ? `${checkboxId}-description` : undefined;\n\n const baseClasses = [\n \"checkbox\",\n disabled && \"checkbox--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const resolvedLabelProps = labelProps ?? {};\n const labelClassName = [\"checkbox__label-text\", resolvedLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={baseClasses}>\n <div className=\"checkbox__wrapper\">\n <input\n ref={combinedRef}\n type=\"checkbox\"\n id={checkboxId}\n checked={checked}\n onChange={handleChange}\n disabled={disabled}\n value={value}\n aria-describedby={descriptionId || undefined}\n className=\"checkbox__input\"\n {...props}\n />\n <label htmlFor={checkboxId} className=\"checkbox__label-wrapper\">\n <span className=\"checkbox__icon-wrapper\" aria-hidden=\"true\">\n {indeterminate ? (\n <RiCheckboxIndeterminateFill className=\"checkbox__icon\" />\n ) : checked ? (\n <RiCheckboxFill className=\"checkbox__icon\" />\n ) : (\n <RiCheckboxBlankLine className=\"checkbox__icon\" />\n )}\n </span>\n {label && (\n <Text\n variant={resolvedLabelProps.variant ?? \"body-p2\"}\n as={resolvedLabelProps.as ?? \"span\"}\n {...resolvedLabelProps}\n className={labelClassName}\n >\n {label}\n </Text>\n )}\n </label>\n </div>\n {description && (\n <div id={descriptionId} className=\"checkbox__description\">\n {description}\n </div>\n )}\n </div>\n );\n }\n);\n\nCheckbox.displayName = \"Checkbox\";\n\n// Checkbox.Group 컴포넌트\nexport interface CheckboxItem {\n /** 체크박스 식별 값 */\n value: string;\n /** 체크박스 라벨 */\n label?: React.ReactNode;\n /** 체크박스 설명 텍스트 */\n description?: React.ReactNode;\n /** 개별 체크박스 비활성화 */\n disabled?: boolean;\n}\n\nexport interface CheckboxGroupProps {\n /** 그룹 라벨 */\n label?: React.ReactNode;\n /** 그룹 라벨 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 그룹 설명 */\n description?: React.ReactNode;\n /** 그룹 설명 스타일 오버라이드 (옵션) */\n descriptionProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 복수 선택 허용 여부. false면 단일 선택(라디오처럼 동작) */\n multiple?: boolean;\n /** 선택된 값들 (controlled). multiple=false일 때는 길이 0 또는 1 */\n value?: string[];\n /** 초기 선택된 값들 (uncontrolled) */\n defaultValue?: string[];\n /** 값 변경 핸들러 */\n onChange?: (values: string[]) => void;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** 체크박스 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly CheckboxItem[];\n /** 자식 Checkbox 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n /** 추가 CSS 클래스명 */\n className?: string;\n}\n\n/** CheckboxGroup은 여러 Checkbox를 그룹화하여 관리할 수 있는 컴포넌트다. */\nexport const CheckboxGroup = ({\n label,\n labelProps,\n description,\n descriptionProps,\n multiple = true,\n value: valueProp,\n defaultValue = [],\n onChange,\n disabled,\n items,\n children,\n className = \"\",\n}: CheckboxGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string[]>(defaultValue);\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const handleChange = (checkboxValue: string, checked: boolean) => {\n const newValue = multiple\n ? checked\n ? [...value, checkboxValue]\n : value.filter((v) => v !== checkboxValue)\n : checked\n ? [checkboxValue]\n : [];\n\n if (!isControlled) {\n setInternalValue(newValue);\n }\n\n onChange?.(newValue);\n };\n\n const groupId = React.useId();\n const descriptionId = description ? `${groupId}-description` : undefined;\n\n const resolvedGroupLabelProps = labelProps ?? {};\n const resolvedGroupDescriptionProps = descriptionProps ?? {};\n const groupLabelClassName = [\"checkbox-group__label\", resolvedGroupLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n const groupDescriptionClassName = [\n \"checkbox-group__description\",\n resolvedGroupDescriptionProps.className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const baseClasses = [\n \"checkbox-group\",\n disabled && \"checkbox-group--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedContent = items\n ? items.map((item) => (\n <Checkbox\n key={item.value}\n value={item.value}\n label={item.label}\n description={item.description}\n checked={value.includes(item.value)}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(item.value, e.target.checked);\n }}\n disabled={disabled || item.disabled}\n />\n ))\n : React.Children.map(children, (child) => {\n if (React.isValidElement<CheckboxProps>(child) && child.type === Checkbox) {\n const checkboxValue = child.props.value;\n if (checkboxValue === undefined) {\n console.warn(\"CheckboxGroup 내부의 Checkbox는 value prop이 필요합니다.\");\n return child;\n }\n\n const isChecked = value.includes(checkboxValue);\n\n return React.cloneElement(child, {\n checked: isChecked,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(checkboxValue, e.target.checked);\n child.props.onChange?.(e);\n },\n disabled: disabled || child.props.disabled,\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses}>\n {label && (\n <Text\n variant={resolvedGroupLabelProps.variant ?? \"subtitle-p2\"}\n as={resolvedGroupLabelProps.as ?? \"div\"}\n {...resolvedGroupLabelProps}\n className={groupLabelClassName}\n >\n {label}\n </Text>\n )}\n {description && (\n <Text\n id={descriptionId}\n variant={resolvedGroupDescriptionProps.variant ?? \"body-p3\"}\n as={resolvedGroupDescriptionProps.as ?? \"div\"}\n {...resolvedGroupDescriptionProps}\n className={groupDescriptionClassName}\n >\n {description}\n </Text>\n )}\n <div className=\"checkbox-group__content\">\n {renderedContent}\n </div>\n </div>\n );\n};\n\nCheckboxGroup.displayName = \"CheckboxGroup\";\n\n// Checkbox.Group을 Checkbox의 정적 프로퍼티로 추가\n(Checkbox as typeof Checkbox & { Group: typeof CheckboxGroup }).Group = CheckboxGroup;\n","import React from \"react\";\n\nexport interface UseCheckboxGroupOptions {\n /** 선택 가능한 값 목록 (CheckboxGroup 자식들의 value와 일치) */\n options: readonly string[];\n /** 초기 선택 값 (uncontrolled일 때) */\n defaultValue?: string[];\n /** 선택 값 (controlled일 때). 지정하면 onChange와 함께 사용 */\n value?: string[];\n /** 선택 값 변경 핸들러 (controlled일 때 필수) */\n onChange?: (values: string[]) => void;\n}\n\nexport interface UseCheckboxGroupResult {\n /** 현재 선택된 값들. CheckboxGroup의 value에 전달 */\n value: string[];\n /** 선택 변경 핸들러. CheckboxGroup의 onChange에 전달 */\n onChange: (values: string[]) => void;\n /** '전체 선택' 체크박스에 넘길 checked */\n selectAllChecked: boolean;\n /** '전체 선택' 체크박스에 넘길 indeterminate (일부만 선택된 경우) */\n selectAllIndeterminate: boolean;\n /** '전체 선택' 체크박스에 넘길 onChange */\n handleSelectAll: (e: React.ChangeEvent<HTMLInputElement>) => void;\n /** '전체 선택' Checkbox에 그대로 spread 가능한 props (checked, indeterminate, onChange) */\n selectAllProps: {\n checked: boolean;\n indeterminate: boolean;\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;\n };\n}\n\n/**\n * CheckboxGroup + '전체 선택' 체크박스(indeterminate 포함) 상태를 관리하는 훅.\n * options와 동기화된 value/onChange와, 전체 선택용 checked/indeterminate/onChange를 반환한다.\n * 외부에서는 이 훅만 사용하면 된다.\n *\n * @example\n * const options = ['react', 'vue', 'angular'] as const;\n * const { value, onChange, selectAllProps } = useCheckboxGroup({ options });\n *\n * <Checkbox label=\"전체 선택\" {...selectAllProps} />\n * <CheckboxGroup value={value} onChange={onChange} ...>\n * {options.map(v => <Checkbox key={v} value={v} label={v} />)}\n * </CheckboxGroup>\n */\nexport function useCheckboxGroup(\n config: UseCheckboxGroupOptions\n): UseCheckboxGroupResult {\n const {\n options,\n defaultValue = [],\n value: valueProp,\n onChange: onChangeProp,\n } = config;\n\n const [internalValue, setInternalValue] = React.useState<string[]>(\n defaultValue\n );\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const onChange = React.useCallback(\n (newValue: string[]) => {\n if (!isControlled) setInternalValue(newValue);\n onChangeProp?.(newValue);\n },\n [isControlled, onChangeProp]\n );\n\n const allSelected = value.length === options.length;\n const someSelected = value.length > 0;\n const selectAllChecked = allSelected;\n const selectAllIndeterminate = someSelected && !allSelected;\n\n const handleSelectAll = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.checked ? [...options] : []);\n },\n [options, onChange]\n );\n\n return {\n value,\n onChange,\n selectAllChecked,\n selectAllIndeterminate,\n handleSelectAll,\n selectAllProps: {\n checked: selectAllChecked,\n indeterminate: selectAllIndeterminate,\n onChange: handleSelectAll,\n },\n };\n}\n","import React from \"react\";\nimport { ChevronDownIcon, XMarkIcon } from \"@heroicons/react/24/outline\";\nimport { TextField } from \"../../TextField/TextField\";\nimport {\n SelectMenuOverlay,\n type SelectMenuItem,\n type SelectMenuProps,\n} from \"../SelectMenu/SelectMenu\";\nimport \"./select-header.css\";\nimport { RiArrowUpLine, RiArrowUpSLine } from \"@remixicon/react\";\n\nexport type SelectHeaderType = \"outlined\" | \"underlined\";\nexport type SelectHeaderSize = \"medium\" | \"small\";\n\nexport interface SelectHeaderProps {\n /** SelectHeader 타입 */\n type?: SelectHeaderType;\n /**\n * SelectHeader 사이즈\n * - \"medium\": Web~Tab 권장 사이즈\n * - \"small\": Mo 권장 사이즈\n * - 지정하지 않으면 breakpoint에 따라 자동 결정됨.\n */\n size?: SelectHeaderSize;\n /** Title 텍스트 */\n title?: string;\n /** 필수 필드 표시 여부 */\n required?: boolean;\n /** 선택된 값 표시 (items 없을 때) / 선택된 값 controlled (items 있을 때) */\n value?: string | string[] | null;\n /** 플레이스홀더 텍스트 */\n placeholder?: string;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** 읽기 전용 (값은 표시되지만 변경 불가) */\n readOnly?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** Help text (도움말 텍스트) */\n description?: React.ReactNode;\n /** Help text 아이콘 (true면 기본 아이콘, 노드면 커스텀, false면 아이콘 없음) */\n accentIcon?: boolean | React.ReactNode;\n /** 클릭 핸들러 */\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** 값 클리어 핸들러 */\n onClear?: (event: React.MouseEvent<HTMLElement>) => void;\n /** 왼쪽 prefix 아이콘 (TextField prefixIcon으로 전달) */\n prefixIcon?: React.ReactNode;\n /** 커스텀 아이콘 */\n icon?: React.ReactNode;\n /** SelectMenu 항목들 (있으면 클릭 시 메뉴 열림) */\n items?: SelectMenuItem[];\n /** 초기 선택 값 (uncontrolled, items 있을 때) */\n defaultValue?: string | string[];\n /** 값 변경 핸들러 (items 있을 때) */\n onChange?: (value: string | string[] | undefined) => void;\n /** 다중 선택 허용 여부 (items 있을 때) */\n multiple?: boolean;\n /** 클리어 버튼 표시 여부 (미지정 시 hasValue && !disabled && (onChange|onClear) 기준 자동) */\n showClear?: boolean;\n /** 래퍼(Wrapper)에 적용할 클래스 이름 */\n wrapperClassName?: string;\n /** 래퍼(Wrapper)에 적용할 인라인 스타일 */\n wrapperStyle?: React.CSSProperties;\n /** 너비 설정 (예: \"100%\", \"300px\"). 설정 시 max-width 제한이 해제됨 */\n width?: string | number;\n /** 추가 CSS 클래스명 */\n className?: string;\n /** 요소 ID */\n id?: string;\n /** SelectMenu에 전달: 항목 텍스트 스타일 오버라이드 */\n menuItemTextProps?: SelectMenuProps[\"itemTextProps\"];\n /** SelectMenu에 전달: 선택된 항목 suffix 아이콘 */\n menuSuffixIcon?: SelectMenuProps[\"suffixIcon\"];\n /** SelectMenu에 전달: className */\n menuClassName?: string;\n /** SelectMenu에 전달: style */\n menuStyle?: React.CSSProperties;\n /** SelectMenu에 전달: 최대 표시 행 수 */\n menuMaxRows?: number;\n}\n\n/** SelectHeader 컴포넌트는 선택된 값을 표시하고 드롭다운을 여는 헤더 컴포넌트다. items를 주면 클릭 시 메뉴가 열린다. */\nexport const SelectHeader = ({\n type = \"outlined\",\n title,\n required = false,\n value: valueProp,\n placeholder = \"선택하세요\",\n disabled = false,\n readOnly = false,\n error = false,\n description,\n accentIcon = true,\n onClick,\n onClear,\n prefixIcon,\n icon,\n className = \"\",\n id,\n items,\n defaultValue,\n onChange,\n multiple,\n showClear,\n wrapperClassName = \"\",\n wrapperStyle,\n width,\n size,\n menuItemTextProps,\n menuSuffixIcon,\n menuClassName,\n menuStyle,\n menuMaxRows,\n}: SelectHeaderProps) => {\n const [internalValue, setInternalValue] = React.useState<\n string | string[] | undefined\n >(defaultValue);\n\n const isSelectMode = items != null && items.length > 0;\n const isControlled = valueProp !== undefined;\n\n let currentValueForSelect: string | string[] | undefined = undefined;\n if (isSelectMode) {\n currentValueForSelect = isControlled\n ? valueProp === null\n ? undefined\n : valueProp\n : internalValue;\n }\n\n const handleSelectChange = (next: string | string[] | undefined) => {\n if (!isControlled) setInternalValue(next);\n onChange?.(next);\n };\n\n const displayValue: string | null = (() => {\n if (isSelectMode) {\n const v = currentValueForSelect;\n if (v == null || (Array.isArray(v) && v.length === 0)) return null;\n if (Array.isArray(v)) {\n return v\n .map((value) => items!.find((i) => i.value === value)?.label ?? value)\n .filter(Boolean)\n .join(\", \");\n }\n const found = items!.find((i) => i.value === v)?.label;\n return found != null ? String(found) : v;\n }\n if (valueProp == null) return null;\n if (Array.isArray(valueProp)) return valueProp.join(\", \");\n return typeof valueProp === \"string\" ? valueProp : null;\n })();\n\n const hasValue = Boolean(displayValue);\n const showClearButton =\n hasValue &&\n !disabled &&\n !readOnly &&\n (showClear !== undefined\n ? showClear\n : (isSelectMode ? Boolean(onChange) : Boolean(onClear)));\n\n const handleClear = (e: React.MouseEvent<HTMLElement>) => {\n e.stopPropagation();\n if (isSelectMode) {\n handleSelectChange(undefined);\n } else {\n onClear?.(e as React.MouseEvent<HTMLButtonElement>);\n }\n };\n\n const suffixContent = (\n <span className=\"select-header__actions\">\n {showClearButton && (\n <span\n role=\"button\"\n tabIndex={0}\n className=\"select-header__clear\"\n onClick={handleClear}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleClear(e as unknown as React.MouseEvent<HTMLElement>);\n }\n }}\n aria-label=\"값 지우기\"\n >\n <XMarkIcon className=\"select-header__clear-icon\" />\n </span>\n )}\n <span className=\"select-header__icon\">\n {icon || <RiArrowUpSLine className=\"select-header__chevron\" />}\n </span>\n </span>\n );\n\n const textFieldNode = (\n <TextField\n title={title}\n required={required}\n description={description}\n accentIcon={accentIcon}\n error={error}\n disabled={disabled}\n size={size}\n width={width}\n readOnly\n value={displayValue ?? \"\"}\n placeholder={placeholder}\n prefixIcon={prefixIcon}\n suffixIcon={suffixContent}\n className={[\n \"select-header-field\",\n type === \"underlined\" && \"select-header-field--underlined\",\n wrapperClassName,\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n style={wrapperStyle}\n id={id}\n onClick={onClick as React.MouseEventHandler<HTMLInputElement>}\n />\n );\n\n if (isSelectMode && !disabled && !readOnly) {\n return (\n <SelectMenuOverlay\n items={items!}\n value={currentValueForSelect}\n multiple={multiple}\n size={size}\n onChange={handleSelectChange}\n menuContainerStyle={{ width: \"100%\", marginTop: 8 }}\n itemTextProps={menuItemTextProps}\n suffixIcon={menuSuffixIcon}\n maxRows={menuMaxRows}\n className={menuClassName}\n style={menuStyle}\n >\n <div className=\"select-header-trigger\">{textFieldNode}</div>\n </SelectMenuOverlay>\n );\n }\n\n return textFieldNode;\n};\n\nSelectHeader.displayName = \"SelectHeader\";\n","import React, { useState, useId, forwardRef } from \"react\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport \"./text-field.css\";\nimport { Text } from \"../Typography/Typography\";\n\n// pc/mo는 디바이스 기반, medium/small은 스토리에서 쓰는 사이즈 네이밍\nexport type TextFieldSize = \"pc\" | \"mo\" | \"medium\" | \"small\";\ntype NormalizedTextFieldSize = \"pc\" | \"mo\";\ntype TextFieldState = \"default\" | \"error\";\nexport type TextFieldType = \"input\" | \"area\";\n\n/* ------------------------------------------------------------------ */\n/* 공통 Props */\n/* ------------------------------------------------------------------ */\ninterface TextFieldBaseProps {\n /** Title 텍스트 (있으면 표시) */\n title?: string;\n /** 필수 필드 표시 여부 */\n required?: boolean;\n /**\n * 크기\n * - \"pc\" / \"mo\": 디바이스 기반 네이밍\n * - \"medium\" / \"small\": 스토리/디자인 토큰 기반 네이밍 (pc ↔ medium, mo ↔ small)\n * 미지정 시 breakpoint 기준: tablet 미만 mo(small), 이상 pc(medium). 지정 시 오버라이드\n */\n size?: TextFieldSize;\n /** 에러 상태 */\n error?: boolean;\n /** Help text */\n description?: React.ReactNode;\n /** 컴포넌트 너비 (px 또는 CSS 문자열) */\n width?: number | string;\n /** 최대 문자 수 제한 */\n maxLength?: number;\n /**\n * 글자 수 카운트 표시 여부 (예: \"99/100\")\n * maxLength가 있을 때만 동작하며, 기본값은 true\n * @default true\n */\n showCount?: boolean;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** Help text 아이콘 (true면 기본 아이콘, 노드면 커스텀) */\n accentIcon?: boolean | React.ReactNode;\n\n // 공통 이벤트 핸들러 (Input/Textarea 호환을 위해 타입을 합침)\n onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onFocus?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onBlur?: (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onCopy?: React.ClipboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onCut?: React.ClipboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onPaste?: React.ClipboardEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n onSelect?: React.ReactEventHandler<HTMLInputElement | HTMLTextAreaElement>;\n}\n\n/* ------------------------------------------------------------------ */\n/* type=\"input\" 전용 Props */\n/* ------------------------------------------------------------------ */\ninterface TextFieldInputProps\n extends TextFieldBaseProps,\n Omit<\n React.InputHTMLAttributes<HTMLElement>,\n \"size\" | \"title\" | \"type\" | keyof TextFieldBaseProps\n > {\n /** 컴포넌트 타입: input (기본) */\n type?: \"input\";\n /** 왼쪽 아이콘 */\n prefixIcon?: React.ReactNode;\n /** 오른쪽 아이콘 */\n suffixIcon?: React.ReactNode;\n /** 오른쪽 단위 (타이머 등) */\n suffixUnit?: React.ReactNode;\n /** HTML input type (text, password, email 등) */\n inputType?: React.HTMLInputTypeAttribute;\n}\n\n/* ------------------------------------------------------------------ */\n/* type=\"area\" 전용 Props */\n/* ------------------------------------------------------------------ */\ninterface TextFieldAreaProps\n extends TextFieldBaseProps,\n Omit<\n React.TextareaHTMLAttributes<HTMLElement>,\n \"size\" | \"title\" | \"type\" | keyof TextFieldBaseProps\n > {\n /** 컴포넌트 타입: textarea */\n type: \"area\";\n /**\n * textarea 높이 (px 또는 CSS 문자열). 고정 높이로 적용되며 내용이 넘치면 스크롤 생성.\n * @default 120\n */\n height?: number | string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Discriminated Union */\n/* ------------------------------------------------------------------ */\nexport type TextFieldProps = TextFieldInputProps | TextFieldAreaProps;\n\n/* ------------------------------------------------------------------ */\n/* Type Guards */\n/* ------------------------------------------------------------------ */\nconst isAreaType = (\n props: TextFieldProps,\n): props is TextFieldAreaProps => props.type === \"area\";\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\n/** TextField 컴포넌트는 사용자로부터 텍스트 입력을 받는 폼 컴포넌트입니다. input과 textarea를 통합합니다. */\nexport const TextField = forwardRef<\n HTMLInputElement | HTMLTextAreaElement,\n TextFieldProps\n>((props, ref) => {\n const {\n type = \"input\",\n required = false,\n size,\n error = false,\n description,\n width,\n maxLength,\n showCount: showCountProp = true,\n title,\n accentIcon = true,\n className = \"\",\n style,\n id,\n value,\n defaultValue,\n readOnly,\n disabled,\n onChange,\n onFocus,\n onBlur,\n ...restProps\n } = props as TextFieldProps & { className?: string; style?: React.CSSProperties };\n\n const generatedId = useId();\n const fieldId = id || `textfield-${generatedId}`;\n const [focused, setFocused] = useState(false);\n\n // size 미지정 시: CSS media query로 해상도별 적용 (responsive). 지정 시: pc/mo\n const effectiveSize: NormalizedTextFieldSize | \"responsive\" =\n size === undefined\n ? \"responsive\"\n : size === \"medium\"\n ? \"pc\"\n : size === \"small\"\n ? \"mo\"\n : size;\n\n // maxLength 글자 수 표시용. value 없으면 uncontrolled → 내부에서만 사용\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue ?? \"\");\n const currentValue = isControlled ? value : internalValue;\n\n const inputState: TextFieldState = error ? \"error\" : \"default\";\n const count = maxLength\n ? `${String(currentValue).length}/${maxLength}`\n : undefined;\n const showCount = showCountProp && Boolean(count);\n const [countValue, countTotal] =\n typeof count === \"string\" && count.includes(\"/\")\n ? count.split(\"/\")\n : [count, undefined];\n const iconNode =\n typeof accentIcon === \"boolean\" ? (\n accentIcon ? (\n <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n ) : null\n ) : (\n accentIcon\n );\n const helpVariant = error ? \"error\" : \"inform\";\n\n const isArea = type === \"area\";\n\n /* ---------- 이벤트 핸들러 ---------- */\n const handleFocus = (\n e: React.FocusEvent<HTMLInputElement> | React.FocusEvent<HTMLTextAreaElement>,\n ) => {\n setFocused(true);\n (onFocus as (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void)?.(e);\n };\n\n const handleBlur = (\n e: React.FocusEvent<HTMLInputElement> | React.FocusEvent<HTMLTextAreaElement>,\n ) => {\n setFocused(false);\n (onBlur as (e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void)?.(e);\n };\n\n const handleChange = (\n e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>,\n ) => {\n let next = e.target.value;\n if (maxLength != null && next.length > maxLength) {\n next = next.slice(0, maxLength);\n e.target.value = next;\n }\n if (!isControlled) setInternalValue(next);\n (onChange as (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void)?.(e);\n };\n\n /* ---------- 클래스명 ---------- */\n const fieldClasses = [\n \"text-field__control\",\n `text-field__control--${effectiveSize}`,\n `text-field__control--${inputState}`,\n isArea && \"text-field__control--area\",\n focused && \"text-field__control--focused\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const shellClasses = [\n \"text-field-shell\",\n `text-field-shell--${inputState}`,\n `text-field-shell--${effectiveSize}`,\n readOnly && \"text-field-shell--readonly\",\n isArea && \"text-field-shell--area\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n /* ---------- textarea 스타일 ---------- */\n const getShellAreaStyle = (): React.CSSProperties | undefined => {\n if (!isArea) return undefined;\n const areaProps = props as TextFieldAreaProps;\n if (areaProps.height == null) return { height: \"120px\" };\n const h =\n typeof areaProps.height === \"number\"\n ? `${areaProps.height}px`\n : areaProps.height;\n return { height: h };\n };\n\n /* ---------- Input / Textarea 공통 제외 키 ---------- */\n const excludeKeys = new Set([\n \"type\", \"prefixIcon\", \"suffixIcon\", \"suffixUnit\",\n \"height\", \"width\", \"inputType\", \"showCount\",\n ]);\n const nativeProps = Object.fromEntries(\n Object.entries(restProps).filter(([k]) => !excludeKeys.has(k)),\n );\n\n /* ---------- Render ---------- */\n return (\n <div\n className={`text-field-wrapper text-field-wrapper--${effectiveSize} ${className}`.trim()}\n style={{\n ...style,\n ...(width != null && { width: typeof width === \"number\" ? `${width}px` : width }),\n }}\n >\n {title && (\n <label htmlFor={fieldId} className=\"flex items-center gap-1\">\n <Text variant=\"body-p3\">{title}</Text>\n {required && <span className=\"text-field__required\"> *</span>}\n </label>\n )}\n\n <div className={shellClasses} style={getShellAreaStyle()}>\n <div className={`text-field-container text-field-container--${effectiveSize}`}>\n {/* prefix icon — input only */}\n {!isArea && isInputType(props) && props.prefixIcon && (\n <span className=\"text-field__left-section\">{props.prefixIcon}</span>\n )}\n\n {isArea ? (\n <textarea\n {...(nativeProps as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n ref={ref as React.Ref<HTMLTextAreaElement>}\n id={fieldId}\n readOnly={readOnly}\n disabled={disabled}\n className={fieldClasses}\n style={undefined}\n value={currentValue}\n onChange={handleChange as React.ChangeEventHandler<HTMLTextAreaElement>}\n onFocus={handleFocus as React.FocusEventHandler<HTMLTextAreaElement>}\n onBlur={handleBlur as React.FocusEventHandler<HTMLTextAreaElement>}\n maxLength={maxLength}\n aria-invalid={error}\n aria-describedby={\n description || count ? `${fieldId}-description` : undefined\n }\n />\n ) : (\n <input\n {...(nativeProps as React.InputHTMLAttributes<HTMLInputElement>)}\n ref={ref as React.Ref<HTMLInputElement>}\n type={(props as TextFieldInputProps).inputType}\n id={fieldId}\n readOnly={readOnly}\n disabled={disabled}\n className={fieldClasses}\n value={currentValue}\n onChange={handleChange as React.ChangeEventHandler<HTMLInputElement>}\n onFocus={handleFocus as React.FocusEventHandler<HTMLInputElement>}\n onBlur={handleBlur as React.FocusEventHandler<HTMLInputElement>}\n maxLength={maxLength}\n aria-invalid={error}\n aria-describedby={\n description || count ? `${fieldId}-description` : undefined\n }\n />\n )}\n\n {/* suffix — input only */}\n {!isArea && isInputType(props) && (props.suffixIcon || props.suffixUnit) && (\n <div className=\"text-field__right-section\">\n {props.suffixIcon && <>{props.suffixIcon}</>}\n {props.suffixUnit && <>{props.suffixUnit}</>}\n </div>\n )}\n </div>\n </div>\n\n {/* Footer: help text + character count */}\n {(description || showCount) && (\n <div id={`${fieldId}-description`} className=\"text-field__footer\">\n <div\n className={`help-text-wrapper ${\n description && showCount\n ? \"help-text-wrapper--between\"\n : description\n ? \"help-text-wrapper--start\"\n : \"help-text-wrapper--end\"\n }`}\n >\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {iconNode && (\n <span className=\"help-text__icon\">{iconNode}</span>\n )}\n {typeof description === \"string\" ||\n typeof description === \"number\" ? (\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n ) : (\n <span className=\"help-text__content\">{description}</span>\n )}\n </span>\n )}\n {showCount && (\n <span\n className={`help-text__count help-text__count--${helpVariant}`}\n >\n {countValue && (\n <Text variant=\"body-p3\" className=\"help-text__count-number\">\n {countValue}\n </Text>\n )}\n {countTotal && (\n <Text variant=\"body-p3\" className=\"help-text__count-total\">\n /{countTotal}\n </Text>\n )}\n </span>\n )}\n </div>\n </div>\n )}\n </div>\n );\n});\n\nTextField.displayName = \"TextField\";\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\nfunction isInputType(\n props: TextFieldProps,\n): props is TextFieldInputProps {\n return !isAreaType(props);\n}\n","import * as React from \"react\";\nfunction ExclamationCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-8-5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5A.75.75 0 0 1 10 5Zm0 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ExclamationCircleIcon);\nexport default ForwardRef;","import React from \"react\";\nimport \"./select-menu.css\";\nimport { Text } from \"../../Typography/Typography\";\nimport { useBreakpoint } from \"../../../shared/hooks/useMediaQuery\";\nimport { RiCheckboxCircleFill } from \"@remixicon/react\";\n\nexport interface SelectMenuItem {\n value: string;\n label: React.ReactNode;\n disabled?: boolean;\n /** 항목 왼쪽 아이콘 */\n icon?: React.ReactNode;\n}\n\nexport interface SelectMenuProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n /** 메뉴 항목들 */\n items: SelectMenuItem[];\n /**\n * 메뉴 사이즈\n * - \"medium\": Web~Tab 권장 사이즈\n * - \"small\": Mo 권장 사이즈\n * - 지정하지 않으면 breakpoint에 따라 자동 결정됨.\n */\n size?: \"medium\" | \"small\";\n /** 선택된 값 (controlled) */\n value?: string | string[];\n /** 초기 선택 값 (uncontrolled) */\n defaultValue?: string | string[];\n /** 값 변경 핸들러 */\n onChange?: (value: string | string[] | undefined) => void;\n /** 다중 선택 허용 여부 */\n multiple?: boolean;\n /** 항목 텍스트 스타일 오버라이드 (옵션) */\n itemTextProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 선택된 항목 suffix 아이콘 (기본 체크 아이콘, 함수로 커스터마이즈 가능) */\n suffixIcon?: React.ReactNode | ((item: SelectMenuItem) => React.ReactNode);\n /** 메뉴에 표시할 최대 행 수. 초과 시 스크롤 */\n maxRows?: number;\n}\n\n/** SelectMenu는 옵션 리스트를 표시하고 값을 선택하는 메뉴 컴포넌트다. */\nexport const SelectMenu = React.forwardRef<HTMLDivElement, SelectMenuProps>((props, ref) => {\n const {\n items,\n size,\n value,\n defaultValue,\n onChange,\n multiple,\n itemTextProps,\n suffixIcon,\n maxRows,\n className = \"\",\n style,\n id,\n ...rest\n } = props;\n\n // value prop이 존재하면 (undefined 포함) controlled 로 간주\n const isControlled = Object.prototype.hasOwnProperty.call(props, \"value\");\n const [internalValue, setInternalValue] = React.useState<string | string[] | undefined>(\n defaultValue\n );\n const currentValue = isControlled ? value : internalValue;\n const isMultiple = !!multiple;\n\n const { isUnderTablet } = useBreakpoint();\n // size prop이 우선이며, 없으면 breakpoint 기준 자동 결정\n const resolvedSize: \"medium\" | \"small\" =\n size ?? (isUnderTablet ? \"small\" : \"medium\");\n\n const generatedId = React.useId();\n const menuId = id || `select-menu-${generatedId}`;\n\n const commitValue = (next: string) => {\n let newValue: string | string[] | undefined;\n\n if (isMultiple) {\n const prevArray = Array.isArray(currentValue)\n ? currentValue\n : currentValue\n ? [currentValue]\n : [];\n newValue = prevArray.includes(next)\n ? prevArray.filter((v) => v !== next)\n : [...prevArray, next];\n } else {\n newValue = currentValue === next ? undefined : next;\n }\n\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n };\n\n const baseClasses = [\"select-menu\", `select-menu--${resolvedSize}`, className]\n .filter(Boolean)\n .join(\" \");\n\n const resolvedItemTextProps = itemTextProps ?? {};\n const defaultVariant = resolvedSize === \"medium\" ? \"body-p2\" : \"body-p3\";\n\n const menuRef = React.useRef<HTMLDivElement | null>(null);\n const [computedMaxHeight, setComputedMaxHeight] = React.useState<string | undefined>(undefined);\n\n React.useLayoutEffect(() => {\n const el = menuRef.current;\n if (!el || maxRows == null) return;\n const firstItem = el.querySelector<HTMLElement>(\".select-menu__item\");\n if (!firstItem) return;\n const itemHeight = firstItem.offsetHeight;\n const menuStyle = getComputedStyle(el);\n const gap = parseFloat(menuStyle.gap) || 0;\n const paddingY = parseFloat(menuStyle.paddingTop) + parseFloat(menuStyle.paddingBottom);\n setComputedMaxHeight(`${itemHeight * maxRows + gap * (maxRows - 1) + paddingY}px`);\n }, [maxRows, resolvedSize, items.length]);\n\n const mergedRef = (node: HTMLDivElement | null) => {\n menuRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n };\n\n return (\n <div\n ref={mergedRef}\n id={menuId}\n className={baseClasses}\n role=\"listbox\"\n style={{ ...style, ...(maxRows != null && { maxHeight: computedMaxHeight }) }}\n {...rest}\n >\n {items.map((item, idx) => {\n const isSelected = Array.isArray(currentValue)\n ? currentValue.includes(item.value)\n : currentValue === item.value;\n const optionId = `${menuId}-option-${item.value}`;\n\n const defaultSuffix = <RiCheckboxCircleFill className=\"select-menu__suffix-icon\" />;\n const suffixNode =\n typeof suffixIcon === \"function\" ? suffixIcon(item) : suffixIcon ?? defaultSuffix;\n\n return (\n <button\n key={item.value}\n id={optionId}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n disabled={item.disabled}\n className=\"select-menu__item\"\n onClick={() => !item.disabled && commitValue(item.value)}\n >\n <span className=\"select-menu__item-content\">\n {item.icon && <span className=\"select-menu__prefix\">{item.icon}</span>}\n <Text\n variant={resolvedItemTextProps.variant ?? defaultVariant}\n as={resolvedItemTextProps.as ?? \"span\"}\n {...resolvedItemTextProps}\n className={[\"select-menu__item-text\", resolvedItemTextProps.className]\n .filter(Boolean)\n .join(\" \")}\n >\n {item.label}\n </Text>\n </span>\n {isSelected && <span className=\"select-menu__suffix\">{suffixNode}</span>}\n </button>\n );\n })}\n </div>\n );\n});\n\nSelectMenu.displayName = \"SelectMenu\";\n\nexport interface SelectMenuOverlayProps\n extends Omit<SelectMenuProps, \"onClose\"> {\n /** 메뉴를 열기 위한 트리거 요소 (버튼/텍스트/아이콘 등) */\n children: React.ReactNode;\n /** 열림 상태 (controlled) */\n open?: boolean;\n /** 초기 열림 상태 (uncontrolled) */\n defaultOpen?: boolean;\n /** 열림 상태 변경 핸들러 */\n onOpenChange?: (open: boolean) => void;\n /** 메뉴 컨테이너 스타일 (positioning 커스터마이즈용) */\n menuContainerStyle?: React.CSSProperties;\n}\n\n/** SelectMenuOverlay는 트리거(children)를 감싸고 SelectMenu를 토글하는 래퍼 컴포넌트다. */\nexport const SelectMenuOverlay = ({\n children,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n menuContainerStyle,\n ...menuProps\n}: SelectMenuOverlayProps) => {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n const wrapperRef = React.useRef<HTMLDivElement | null>(null);\n\n const setOpen = (next: boolean) => {\n if (!isControlled) {\n setInternalOpen(next);\n }\n onOpenChange?.(next);\n };\n\n // 메뉴 밖을 클릭하면 닫기\n React.useEffect(() => {\n if (!open) return;\n\n const handleClickOutside = (event: MouseEvent) => {\n if (!wrapperRef.current) return;\n if (!wrapperRef.current.contains(event.target as Node)) {\n setOpen(false);\n }\n };\n\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside);\n };\n }, [open, setOpen]);\n\n const handleToggle = () => {\n setOpen(!open);\n };\n\n let triggerNode: React.ReactNode = children;\n\n if (React.isValidElement<React.HTMLAttributes<HTMLElement>>(children)) {\n const originalOnClick = children.props.onClick;\n\n triggerNode = React.cloneElement<React.HTMLAttributes<HTMLElement>>(children, {\n ...children.props,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n originalOnClick?.(event);\n handleToggle();\n },\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": open,\n });\n } else {\n triggerNode = (\n <button\n type=\"button\"\n onClick={handleToggle}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n {children}\n </button>\n );\n }\n\n const handleChange = (value: string | string[] | undefined) => {\n menuProps.onChange?.(value);\n // 싱글 셀렉트: 항목 선택 시 메뉴 닫기\n if (!menuProps.multiple) {\n setOpen(false);\n }\n };\n\n return (\n <div\n ref={wrapperRef}\n className=\"select-menu-overlay\"\n >\n {triggerNode}\n {open && (\n <div\n style={{\n position: \"absolute\",\n top: \"100%\",\n left: 0,\n marginTop: 4,\n zIndex: 1000,\n ...menuContainerStyle,\n }}\n >\n <SelectMenu\n {...menuProps}\n onChange={handleChange}\n style={{\n ...menuProps.style,\n width: \"100%\",\n minWidth: 0,\n }}\n />\n </div>\n )}\n </div>\n );\n};\n\nSelectMenuOverlay.displayName = \"SelectMenuOverlay\";\n\n","import * as React from \"react\";\nfunction CheckCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(CheckCircleIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction ExclamationTriangleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003ZM12 8.25a.75.75 0 0 1 .75.75v3.75a.75.75 0 0 1-1.5 0V9a.75.75 0 0 1 .75-.75Zm0 8.25a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(ExclamationTriangleIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction InformationCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 0 1 .67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 1 1-.671-1.34l.041-.022ZM12 9a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(InformationCircleIcon);\nexport default ForwardRef;","import * as React from \"react\";\nfunction XCircleIcon({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", Object.assign({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"path\", {\n fillRule: \"evenodd\",\n d: \"M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25Zm-1.72 6.97a.75.75 0 1 0-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 1 0 1.06 1.06L12 13.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L13.06 12l1.72-1.72a.75.75 0 1 0-1.06-1.06L12 10.94l-1.72-1.72Z\",\n clipRule: \"evenodd\"\n }));\n}\nconst ForwardRef = /*#__PURE__*/ React.forwardRef(XCircleIcon);\nexport default ForwardRef;","import React from \"react\";\nimport {\n SelectHeader,\n type SelectHeaderProps,\n type SelectHeaderType,\n} from \"../SelectHeader\";\nimport type { SelectMenuItem, SelectMenuProps } from \"../SelectMenu/SelectMenu\";\nimport { CheckCircleIcon } from \"@heroicons/react/24/solid\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport { Text } from \"../../Typography/Typography\";\nimport \"../SelectHeader/select-header.css\";\nimport \"../SelectMenu/select-menu.css\";\nimport \"./select-box.css\";\n\nexport type SelectBoxSize = \"small\" | \"medium\";\n\n/** 파트별 className 오버라이드 */\nexport type SelectBoxClassNames = {\n root?: string;\n header?: string;\n menu?: string;\n};\n\n/** 파트별 style 오버라이드 */\nexport type SelectBoxStyles = {\n root?: React.CSSProperties;\n header?: React.CSSProperties;\n menu?: React.CSSProperties;\n};\n\n/** SelectBox 전용 props (label는 SelectHeader title에 매핑) */\ntype SelectBoxSpecificProps = {\n /** SelectBox 사이즈 */\n size?: SelectBoxSize;\n /** 비활성화 */\n disabled?: boolean;\n /** 읽기 전용 (값은 표시되지만 변경 불가) */\n readOnly?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** 성공 상태 */\n success?: boolean;\n /** 로딩 상태 */\n loading?: boolean;\n /** 라벨 텍스트 (SelectHeader title에 매핑) */\n label?: string;\n /** 하단 설명 텍스트 */\n description?: string;\n /**\n * 왼쪽 prefix 아이콘. 미지정 시 단일 선택인 경우 선택된 항목의 icon을 자동 감지.\n * false로 설정하면 자동 감지를 비활성화.\n */\n prefixIcon?: React.ReactNode | false;\n /** root에 적용할 className */\n className?: string;\n /** root에 적용할 인라인 스타일 */\n style?: React.CSSProperties;\n /**\n * 파트별 className 오버라이드\n * @example classNames={{ root: \"w-12\", header: \"border-red-500\", menu: \"bg-gray-50\" }}\n */\n classNames?: SelectBoxClassNames;\n /**\n * 파트별 인라인 스타일 오버라이드\n * @example styles={{ header: { borderColor: \"red\" }, menu: { maxHeight: 200 } }}\n */\n styles?: SelectBoxStyles;\n /** 너비 설정 (예: \"100%\", 300). 미지정 시 CSS 기본 360px */\n width?: string | number;\n};\n\n/** SelectHeader에서 SelectBox가 오버라이드하는 props 제외 */\ntype SelectHeaderPassThrough = Omit<\n SelectHeaderProps,\n | \"type\"\n | \"size\"\n | \"title\"\n | \"disabled\"\n | \"readOnly\"\n | \"error\"\n | \"description\"\n | \"accentIcon\"\n | \"icon\"\n | \"prefixIcon\"\n | \"wrapperClassName\"\n | \"menuClassName\"\n | \"menuStyle\"\n | \"style\"\n | \"className\"\n | \"width\"\n> & {\n /** SelectHeader 타입 (outlined | underlined) */\n headerType?: SelectHeaderType;\n};\n\n/** SelectMenu props (SelectHeader를 통해 SelectMenu로 전달) */\ntype SelectMenuPassThrough = {\n /** 메뉴 항목 텍스트 스타일 오버라이드 */\n itemTextProps?: SelectMenuProps[\"itemTextProps\"];\n /** 선택된 항목의 suffix 아이콘 (기본: 체크 아이콘). false면 숨김 */\n suffixIcon?: SelectMenuProps[\"suffixIcon\"];\n /** 메뉴에 표시할 최대 행 수. 초과 시 스크롤 */\n maxRows?: number;\n};\n\nexport type SelectBoxProps = SelectBoxSpecificProps &\n SelectHeaderPassThrough &\n SelectMenuPassThrough;\n\nconst LoadingSpinner = () => (\n <span className=\"select-box__spinner\" aria-hidden=\"true\">\n <svg\n className=\"select-box__spinner-svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n className=\"select-box__spinner-circle\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"32\"\n strokeDashoffset=\"32\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 40;40 40;0 40\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-40;-80\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n </span>\n);\n\n/** SelectBox는 SelectHeader와 SelectMenu를 하나로 통합한 컴포넌트로, 미리 정의된 목록에서 항목을 선택하도록 돕습니다. */\nexport const SelectBox = ({\n size = \"medium\",\n disabled = false,\n readOnly = false,\n error = false,\n success = false,\n loading = false,\n label,\n required = false,\n placeholder = \"선택하세요\",\n items,\n value,\n defaultValue,\n onChange,\n multiple,\n description,\n prefixIcon,\n className,\n style,\n classNames,\n styles,\n width,\n // SelectHeader pass-through\n headerType = \"outlined\",\n onClear,\n showClear,\n wrapperStyle,\n onClick,\n id,\n itemTextProps,\n suffixIcon,\n maxRows = 3,\n ...restHeaderProps\n}: SelectBoxProps) => {\n const isDisabled = disabled || loading;\n const isInteractive = !isDisabled && !readOnly;\n\n const showLabel = Boolean(label);\n\n const resolvedWidth =\n width !== undefined\n ? typeof width === \"number\"\n ? `${width}px`\n : width\n : undefined;\n\n const iconNode = loading ? <LoadingSpinner /> : undefined;\n\n const rootStyle: React.CSSProperties | undefined = (() => {\n const merged = { ...style, ...styles?.root };\n if (resolvedWidth != null) {\n merged.width = resolvedWidth;\n }\n return Object.keys(merged).length > 0 ? merged : undefined;\n })();\n\n const baseClasses = [\n \"select-box\",\n `select-box--${size}`,\n disabled && \"select-box--disabled\",\n readOnly && \"select-box--readonly\",\n error && \"select-box--error\",\n success && \"select-box--success\",\n className,\n classNames?.root,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // 선택된 아이템의 prefix 아이콘 자동 감지 (단일 선택, controlled 시)\n const resolvedPrefixIcon = (() => {\n if (prefixIcon === false) return undefined;\n if (prefixIcon !== undefined) return prefixIcon;\n if (!items || multiple) return undefined;\n const selectedValue = value ?? defaultValue;\n if (!selectedValue || Array.isArray(selectedValue)) return undefined;\n return items.find((i) => i.value === selectedValue)?.icon;\n })();\n\n // description용 아이콘 결정\n const descriptionIcon = success\n ? <CheckCircleIcon className=\"help-text__icon-svg\" />\n : error\n ? <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n : null;\n\n const helpVariant = error ? \"error\" : \"inform\";\n\n return (\n <div className={baseClasses} style={rootStyle}>\n <SelectHeader\n type={headerType}\n size={size}\n title={showLabel ? label : undefined}\n required={required}\n placeholder={placeholder}\n items={items}\n value={value}\n defaultValue={defaultValue}\n onChange={isInteractive ? onChange : undefined}\n multiple={multiple}\n disabled={isDisabled}\n readOnly={readOnly}\n error={error}\n prefixIcon={resolvedPrefixIcon}\n icon={iconNode}\n onClear={isInteractive ? onClear : undefined}\n showClear={isInteractive ? showClear : false}\n wrapperStyle={\n styles?.header || wrapperStyle\n ? { ...wrapperStyle, ...styles?.header }\n : undefined\n }\n wrapperClassName={[\"select-box__header-wrapper\", classNames?.header].filter(Boolean).join(\" \")}\n menuClassName={classNames?.menu}\n menuStyle={styles?.menu}\n onClick={onClick}\n id={id}\n {...restHeaderProps}\n menuItemTextProps={itemTextProps}\n menuSuffixIcon={suffixIcon}\n menuMaxRows={maxRows}\n width=\"100%\"\n />\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {descriptionIcon && (\n <span className=\"help-text__icon\">{descriptionIcon}</span>\n )}\n {typeof description === \"string\" || typeof description === \"number\" ? (\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n ) : (\n <span className=\"help-text__content\">{description}</span>\n )}\n </span>\n )}\n </div>\n );\n};\n\nSelectBox.displayName = \"SelectBox\";\n","import React from \"react\";\n\nimport \"./pagination.css\";\nimport { Text } from \"../Typography/Typography\";\nimport {\n RiArrowLeftSLine,\n RiArrowRightSLine,\n RiMoreLine,\n} from \"@remixicon/react\";\n\nexport type PaginationType = \"basic\" | \"compact\";\n\ntype PaginationItemType =\n | \"page\"\n | \"ellipsis\"\n | \"prev\"\n | \"next\"\n | \"first\"\n | \"last\";\n\ninterface PaginationItem {\n type: PaginationItemType;\n page?: number;\n key: string;\n disabled?: boolean;\n selected?: boolean;\n}\n\nexport interface PaginationProps {\n /** 총 페이지 수 (1 이상) */\n totalPages: number;\n /** 현재 페이지 (1부터 시작) */\n currentPage: number;\n /** 페이지 변경 핸들러 */\n onChange?: (page: number) => void;\n /** Pagination 타입 (기본형 / 축약형) */\n type?: PaginationType;\n /** 추가 CSS 클래스명 */\n className?: string;\n}\n\nconst range = (start: number, end: number): number[] => {\n const length = end - start + 1;\n return Array.from({ length }, (_, idx) => start + idx);\n};\n\nconst createPaginationItems = ({\n totalPages,\n currentPage,\n siblingCount,\n showEdgeButtons,\n showPrevNext,\n}: {\n totalPages: number;\n currentPage: number;\n siblingCount: number;\n showEdgeButtons: boolean;\n showPrevNext: boolean;\n}): PaginationItem[] => {\n if (totalPages <= 0) return [];\n\n const safeCurrent = Math.min(Math.max(currentPage, 1), totalPages);\n const items: PaginationItem[] = [];\n\n const add = (item: PaginationItem) => items.push(item);\n\n const isFirstPage = safeCurrent === 1;\n const isLastPage = safeCurrent === totalPages;\n\n if (showEdgeButtons) {\n add({\n type: \"first\",\n page: 1,\n key: \"first\",\n disabled: isFirstPage,\n });\n }\n\n if (showPrevNext) {\n add({\n type: \"prev\",\n page: Math.max(1, safeCurrent - 1),\n key: \"prev\",\n disabled: isFirstPage,\n });\n }\n\n // 페이지 번호들 + ... 계산 (MUI Pagination 로직과 유사)\n const totalPageNumbers = siblingCount * 2 + 5; // 1, last, current, 양옆, 그리고 두 개의 ellipsis 자리\n\n if (totalPages <= totalPageNumbers) {\n range(1, totalPages).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-${page}`,\n selected: page === safeCurrent,\n })\n );\n } else {\n const leftSiblingIndex = Math.max(safeCurrent - siblingCount, 2);\n const rightSiblingIndex = Math.min(\n safeCurrent + siblingCount,\n totalPages - 1\n );\n\n const shouldShowLeftEllipsis = leftSiblingIndex > 2;\n const shouldShowRightEllipsis = rightSiblingIndex < totalPages - 1;\n\n // 항상 첫 페이지\n add({\n type: \"page\",\n page: 1,\n key: \"page-1\",\n selected: safeCurrent === 1,\n });\n\n if (!shouldShowLeftEllipsis && shouldShowRightEllipsis) {\n // 왼쪽 ellipsis 없고 오른쪽만 필요\n const leftItemCount = 3 + 2 * siblingCount;\n const leftRange = range(2, leftItemCount);\n\n leftRange.forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n\n add({ type: \"ellipsis\", key: `ellipsis-right-${rightSiblingIndex}` });\n add({\n type: \"page\",\n page: totalPages,\n key: `page-${totalPages}`,\n selected: safeCurrent === totalPages,\n });\n } else if (shouldShowLeftEllipsis && !shouldShowRightEllipsis) {\n // 왼쪽만 필요하고 오른쪽 ellipsis 없음\n add({ type: \"ellipsis\", key: `ellipsis-left-${leftSiblingIndex}` });\n\n const rightItemCount = 3 + 2 * siblingCount;\n const rightRange = range(totalPages - rightItemCount + 1, totalPages - 1);\n\n rightRange.forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n\n add({\n type: \"page\",\n page: totalPages,\n key: `page-${totalPages}`,\n selected: safeCurrent === totalPages,\n });\n } else if (shouldShowLeftEllipsis && shouldShowRightEllipsis) {\n // 양쪽 모두 필요할 때: 1 ... [left~right] ... last\n add({ type: \"ellipsis\", key: `ellipsis-left-${leftSiblingIndex}` });\n\n range(leftSiblingIndex, rightSiblingIndex).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n\n add({ type: \"ellipsis\", key: `ellipsis-right-${rightSiblingIndex}` });\n add({\n type: \"page\",\n page: totalPages,\n key: `page-${totalPages}`,\n selected: safeCurrent === totalPages,\n });\n } else {\n // ellipsis 둘 다 필요 없을 때 (fallback)\n range(1, totalPages).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-dynamic-${page}-${safeCurrent}`,\n selected: page === safeCurrent,\n })\n );\n }\n }\n\n if (showPrevNext) {\n add({\n type: \"next\",\n page: Math.min(totalPages, safeCurrent + 1),\n key: \"next\",\n disabled: isLastPage,\n });\n }\n\n if (showEdgeButtons) {\n add({\n type: \"last\",\n page: totalPages,\n key: \"last\",\n disabled: isLastPage,\n });\n }\n\n return items;\n};\n\nconst createBasicPaginationItems = ({\n totalPages,\n currentPage,\n}: {\n totalPages: number;\n currentPage: number;\n}): PaginationItem[] => {\n if (totalPages <= 0) return [];\n\n const safeCurrent = Math.min(Math.max(currentPage, 1), totalPages);\n const items: PaginationItem[] = [];\n\n const add = (item: PaginationItem) => items.push(item);\n\n const isFirstPage = safeCurrent === 1;\n const isLastPage = safeCurrent === totalPages;\n\n // 기본형: first/last, ellipsis 없이 이전/다음 + 모든 페이지 번호\n add({\n type: \"prev\",\n page: Math.max(1, safeCurrent - 1),\n key: \"prev\",\n disabled: isFirstPage,\n });\n\n range(1, totalPages).forEach((page) =>\n add({\n type: \"page\",\n page,\n key: `page-${page}`,\n selected: page === safeCurrent,\n })\n );\n\n add({\n type: \"next\",\n page: Math.min(totalPages, safeCurrent + 1),\n key: \"next\",\n disabled: isLastPage,\n });\n\n return items;\n};\n\n/** Pagination 컴포넌트는 리스트/테이블 등에서 여러 페이지를 탐색할 때 사용하는 페이지네이션 컴포넌트다. */\nexport const Pagination = ({\n totalPages,\n currentPage,\n onChange,\n type = \"basic\",\n className = \"\",\n ...rest\n}: PaginationProps) => {\n // 디자인은 데스크탑 기준 단일 사이즈만 사용\n const size = \"web-tab\" as const;\n\n const variant: PaginationType = type ?? \"basic\";\n\n const items = React.useMemo(() => {\n if (variant === \"basic\") {\n return createBasicPaginationItems({\n totalPages,\n currentPage,\n });\n }\n\n // compact: ellipsis + first/last 버튼 포함\n return createPaginationItems({\n totalPages,\n currentPage,\n siblingCount: 1,\n showEdgeButtons: false,\n showPrevNext: true,\n });\n }, [totalPages, currentPage, variant]);\n\n const handleItemClick = React.useCallback(\n (item: PaginationItem) => {\n if (item.disabled) return;\n if (!item.page) return;\n onChange?.(item.page);\n },\n [onChange]\n );\n\n const handleEllipsisClick = React.useCallback(\n (key: string) => {\n if (key === \"ellipsis-left\") {\n // 왼쪽 ellipsis 클릭 → 첫 페이지로 이동\n onChange?.(1);\n } else if (key === \"ellipsis-right\") {\n // 오른쪽 ellipsis 클릭 → 마지막 페이지로 이동\n onChange?.(totalPages);\n }\n },\n [onChange, totalPages]\n );\n\n const rootClasses = [\"pagination\", `pagination--${size}`, className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <nav className={rootClasses} aria-label=\"페이지네이션\" {...rest}>\n <ul className=\"pagination__list\">\n {items.map((item) => {\n const isPage = item.type === \"page\";\n const isSelected = Boolean(item.selected);\n const isDisabled = Boolean(item.disabled);\n\n const itemClasses = [\n \"pagination__button\",\n `pagination__button--${item.type}`,\n isPage && \"pagination__button--page\",\n isSelected && \"pagination__button--selected\",\n isDisabled && \"pagination__button--disabled\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const labelText =\n item.type === \"page\"\n ? String(item.page)\n : item.type === \"prev\"\n ? \"이전 페이지\"\n : item.type === \"next\"\n ? \"다음 페이지\"\n : item.type === \"first\"\n ? \"첫 페이지\"\n : item.type === \"last\"\n ? \"마지막 페이지\"\n : \"\";\n\n const ariaLabel =\n item.type === \"page\" ? `${item.page}페이지` : labelText;\n\n if (item.type === \"ellipsis\") {\n return (\n <li\n key={item.key}\n className=\"pagination__item pagination__item--ellipsis\"\n >\n <button\n type=\"button\"\n className=\"pagination__button pagination__button--ellipsis\"\n onClick={() => handleEllipsisClick(item.key)}\n aria-label={\n item.key === \"ellipsis-left\"\n ? \"첫 페이지로 이동\"\n : \"마지막 페이지로 이동\"\n }\n >\n <RiMoreLine />\n </button>\n </li>\n );\n }\n\n return (\n <li key={item.key} className=\"pagination__item\">\n <button\n type=\"button\"\n className={itemClasses}\n onClick={() => handleItemClick(item)}\n disabled={isDisabled}\n aria-label={ariaLabel}\n aria-current={isPage && isSelected ? \"page\" : undefined}\n >\n {item.type === \"prev\" && (\n <RiArrowLeftSLine className=\"pagination__icon\" />\n )}\n {item.type === \"next\" && (\n <RiArrowRightSLine className=\"pagination__icon\" />\n )}\n {item.type === \"first\" && (\n <>\n <RiArrowLeftSLine className=\"pagination__icon pagination__icon--double\" />\n <RiArrowLeftSLine className=\"pagination__icon pagination__icon--double\" />\n </>\n )}\n {item.type === \"last\" && (\n <>\n <RiArrowRightSLine className=\"pagination__icon pagination__icon--double\" />\n <RiArrowRightSLine className=\"pagination__icon pagination__icon--double\" />\n </>\n )}\n {item.type === \"page\" && (\n <Text\n as=\"span\"\n variant={size === \"web-tab\" ? \"body-p2\" : \"body-p3\"}\n >\n {item.page}\n </Text>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </nav>\n );\n};\n\nPagination.displayName = \"Pagination\";\n","import React from \"react\";\nimport \"./radio-button.css\";\nimport { RiCircleLine, RiRadioButtonLine } from \"@remixicon/react\";\nimport { Text } from \"../Typography/Typography\";\n\nexport interface RadioButtonProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"type\" | \"size\" | \"onChange\"\n > {\n /** 라디오 라벨 */\n label?: React.ReactNode;\n /** label 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 라디오 설명 텍스트 */\n description?: React.ReactNode;\n /** 라디오 값 (RadioButton.Group에서 사용) */\n value?: string;\n /** 라디오 상태 변경 핸들러 */\n onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/** RadioButton은 단일 선택(라디오) 입력 컴포넌트다. */\nexport const RadioButton = React.forwardRef<HTMLInputElement, RadioButtonProps>(\n (\n {\n label,\n labelProps,\n description,\n value,\n checked: checkedProp,\n defaultChecked = false,\n onChange,\n disabled,\n className = \"\",\n id,\n name,\n onClick,\n ...props\n },\n ref\n ) => {\n // Controlled/Uncontrolled 패턴\n const [internalChecked, setInternalChecked] = React.useState(defaultChecked);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n if (!isControlled) {\n setInternalChecked(e.target.checked);\n }\n\n onChange?.(e);\n };\n\n const handleClick = (e: React.MouseEvent<HTMLInputElement>) => {\n if (checked && !disabled) {\n e.preventDefault();\n if (!isControlled) setInternalChecked(false);\n const syntheticEvent = {\n ...e,\n target: { ...e.target, checked: false },\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange?.(syntheticEvent);\n }\n onClick?.(e);\n };\n\n const generatedId = React.useId();\n const radioId = id || generatedId;\n const descriptionId = description ? `${radioId}-description` : undefined;\n\n const [isHovered, setIsHovered] = React.useState(false);\n\n const baseClasses = [\"radio-button\", disabled && \"radio-button--disabled\", className]\n .filter(Boolean)\n .join(\" \");\n\n const labelWrapperClasses = [\n \"radio-button__label-wrapper\",\n isHovered && !checked && !disabled && \"radio-button__label-wrapper--hovered\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n const resolvedLabelProps = labelProps ?? {};\n const labelClassName = [\"radio-button__label-text\", resolvedLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={baseClasses} data-checked={checked}>\n <div className=\"radio-button__wrapper\">\n <input\n ref={ref}\n type=\"radio\"\n id={radioId}\n name={name}\n checked={checked}\n onChange={handleChange}\n onClick={handleClick}\n disabled={disabled}\n value={value}\n aria-describedby={descriptionId || undefined}\n className=\"radio-button__input\"\n {...props}\n />\n <label\n htmlFor={radioId}\n className={labelWrapperClasses}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n >\n <span className=\"radio-button__icon-wrapper\" aria-hidden=\"true\">\n {checked ? (\n <RiRadioButtonLine className=\"radio-button__icon\" />\n ) : (\n <RiCircleLine className=\"radio-button__icon\" />\n )}\n </span>\n {label && (\n <Text\n variant={resolvedLabelProps.variant ?? \"body-p2\"}\n as={resolvedLabelProps.as ?? \"span\"}\n {...resolvedLabelProps}\n className={labelClassName}\n >\n {label}\n </Text>\n )}\n </label>\n </div>\n {description && (\n <div id={descriptionId} className=\"radio-button__description\">\n {description}\n </div>\n )}\n </div>\n );\n }\n);\n\nRadioButton.displayName = \"RadioButton\";\n\n// RadioButton.Group\nexport interface RadioButtonItem {\n /** 라디오 식별 값 */\n value: string;\n /** 라디오 라벨 */\n label?: React.ReactNode;\n /** 라디오 설명 텍스트 */\n description?: React.ReactNode;\n /** 개별 라디오 비활성화 */\n disabled?: boolean;\n}\n\nexport interface RadioButtonGroupProps {\n /** 그룹 라벨 */\n label?: React.ReactNode;\n /** 그룹 라벨 스타일 오버라이드 (옵션) */\n labelProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 그룹 설명 */\n description?: React.ReactNode;\n /** 그룹 설명 스타일 오버라이드 (옵션) */\n descriptionProps?: Omit<React.ComponentProps<typeof Text>, \"children\" | \"variant\"> & {\n variant?: React.ComponentProps<typeof Text>[\"variant\"];\n };\n /** 선택된 값 (controlled) */\n value?: string;\n /** 초기 선택 값 (uncontrolled) */\n defaultValue?: string;\n /** 값 변경 핸들러 (선택 해제 시 value는 undefined) */\n onChange?: (value: string | undefined) => void;\n /** 비활성화 상태 */\n disabled?: boolean;\n /** name (미지정 시 내부 생성) */\n name?: string;\n /** 라디오 데이터 배열 (items 사용 시 children 불필요) */\n items?: readonly RadioButtonItem[];\n /** 자식 RadioButton 컴포넌트들 (items 미사용 시) */\n children?: React.ReactNode;\n /** 추가 CSS 클래스명 */\n className?: string;\n}\n\n/** RadioButtonGroup은 여러 RadioButton을 그룹화하여 단일 선택을 관리한다. */\nexport const RadioButtonGroup = ({\n label,\n labelProps,\n description,\n descriptionProps,\n value: valueProp,\n defaultValue,\n onChange,\n disabled,\n name,\n items,\n children,\n className = \"\",\n}: RadioButtonGroupProps) => {\n const [internalValue, setInternalValue] = React.useState<string | undefined>(defaultValue);\n const isControlled = valueProp !== undefined;\n const value = isControlled ? valueProp : internalValue;\n\n const groupId = React.useId();\n const groupName = name || `radio-group-${groupId}`;\n const descriptionId = description ? `${groupId}-description` : undefined;\n const resolvedGroupLabelProps = labelProps ?? {};\n const resolvedGroupDescriptionProps = descriptionProps ?? {};\n\n const groupLabelClassName = [\"radio-button-group__label\", resolvedGroupLabelProps.className]\n .filter(Boolean)\n .join(\" \");\n const groupDescriptionClassName = [\n \"radio-button-group__description\",\n resolvedGroupDescriptionProps.className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const baseClasses = [\n \"radio-button-group\",\n disabled && \"radio-button-group--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const handleRadioChange = (radioValue: string) =>\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.checked) {\n if (!isControlled) setInternalValue(radioValue);\n onChange?.(radioValue);\n } else {\n if (!isControlled) setInternalValue(undefined);\n onChange?.(undefined);\n }\n };\n\n // items prop 우선: 데이터 기반 렌더링\n const renderedContent = items\n ? items.map((item) => (\n <RadioButton\n key={item.value}\n value={item.value}\n label={item.label}\n description={item.description}\n name={groupName}\n checked={value === item.value}\n onChange={handleRadioChange(item.value)}\n disabled={disabled || item.disabled}\n />\n ))\n : React.Children.map(children, (child) => {\n if (React.isValidElement<RadioButtonProps>(child) && child.type === RadioButton) {\n const radioValue = child.props.value;\n if (radioValue === undefined) {\n console.warn(\"RadioButtonGroup 내부의 RadioButton은 value prop이 필요합니다.\");\n return child;\n }\n\n const isChecked = value === radioValue;\n\n return React.cloneElement(child, {\n name: groupName,\n checked: isChecked,\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n handleRadioChange(radioValue)(e);\n child.props.onChange?.(e);\n },\n disabled: disabled || child.props.disabled,\n });\n }\n return child;\n });\n\n return (\n <div className={baseClasses} role=\"radiogroup\" aria-describedby={descriptionId || undefined}>\n {label && (\n <Text\n variant={resolvedGroupLabelProps.variant ?? \"subtitle-p2\"}\n as={resolvedGroupLabelProps.as ?? \"div\"}\n {...resolvedGroupLabelProps}\n className={groupLabelClassName}\n >\n {label}\n </Text>\n )}\n {description && (\n <Text\n id={descriptionId}\n variant={resolvedGroupDescriptionProps.variant ?? \"body-p3\"}\n as={resolvedGroupDescriptionProps.as ?? \"div\"}\n {...resolvedGroupDescriptionProps}\n className={groupDescriptionClassName}\n >\n {description}\n </Text>\n )}\n <div className=\"radio-button-group__content\">{renderedContent}</div>\n </div>\n );\n};\n\nRadioButtonGroup.displayName = \"RadioButtonGroup\";\n\n// RadioButton.Group을 RadioButton의 정적 프로퍼티로 추가\n(RadioButton as typeof RadioButton & { Group: typeof RadioButtonGroup }).Group = RadioButtonGroup;\n\n","import React from \"react\";\nimport \"./tag.css\";\nimport { Text } from \"../Typography/Typography\";\n\nexport type TagType = \"solid\" | \"outline\" | \"weak\";\nexport type TagSize = \"medium\" | \"small\";\nexport type TagState = \"enabled\" | \"error\" | \"progressing\" | \"warning\" | \"success\";\n\nexport interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** 태그 타입 (solid, outline, weak) */\n type?: TagType;\n /** 태그 크기 */\n size?: TagSize;\n /** 태그 상태 (type이 weak일 때만 사용 가능) */\n state?: TagState;\n /** 태그 라벨 */\n label: React.ReactNode;\n /** Prefix 아이콘 */\n prefixIcon?: React.ReactNode;\n /** Suffix 아이콘 */\n suffixIcon?: React.ReactNode;\n}\n\n/** Tag 컴포넌트는 콘텐츠의 속성, 상태, 카테고리를 시각적으로 표현하는 읽기 전용 라벨 컴포넌트다. */\nexport const Tag = React.forwardRef<HTMLSpanElement, TagProps>(({\n type = \"solid\",\n size = \"medium\",\n state = \"enabled\",\n label,\n prefixIcon,\n suffixIcon,\n className = \"\",\n ...props\n}, ref) => {\n // type이 weak가 아닐 때는 state를 무시하고 enabled로 처리\n const effectiveState = type === \"weak\" ? state : \"enabled\";\n\n // className은 마지막에 두고, tag.css는 타입/상태를 :where()로 넣어서 전달한 className이 우선 적용되도록 함\n const resolvedClassName = [\n \"tag\",\n `tag--${type}`,\n `tag--${size}`,\n `tag--${effectiveState}`,\n className,\n ]\n .filter(Boolean)\n .join(\" \")\n .trim();\n\n const textVariant = size === \"medium\" ? \"body-p2\" : \"body-p3\";\n\n return (\n <span ref={ref} {...props} className={resolvedClassName}>\n {prefixIcon && <span className=\"tag__prefix-icon\">{prefixIcon}</span>}\n <Text variant={textVariant}>{label}</Text>\n {suffixIcon && <span className=\"tag__suffix-icon\">{suffixIcon}</span>}\n </span>\n );\n});\n\nTag.displayName = \"Tag\";\n","import React, { useState, useRef, useEffect, useCallback, useLayoutEffect } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { Text } from \"../Typography/Typography\";\nimport \"./tooltip.css\";\n\nexport type TooltipPosition =\n | \"top\"\n | \"top-start\"\n | \"top-end\"\n | \"bottom\"\n | \"bottom-start\"\n | \"bottom-end\"\n | \"left\"\n | \"left-start\"\n | \"left-end\"\n | \"right\"\n | \"right-start\"\n | \"right-end\";\n\nexport type TooltipType = \"word\" | \"sentence\";\n\nexport interface TooltipProps {\n /** 툴팁에 표시할 내용 */\n label: React.ReactNode;\n /** 툴팁 타입 (word: 단어형, sentence: 장문형) */\n type?: TooltipType;\n /** Prefix 아이콘 (왼쪽) */\n prefixIcon?: React.ReactNode;\n /** Close 버튼 클릭 핸들러 (제공 시 닫기 버튼이 표시됨) */\n onClose?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n /** 툴팁이 표시될 방향 */\n direction?: TooltipPosition;\n /** 화살표 표시 여부 */\n withArrow?: boolean;\n /** 툴팁 열림 상태 (controlled) */\n opened?: boolean;\n /** 툴팁 초기 열림 상태 (uncontrolled) */\n defaultOpened?: boolean;\n /** 툴팁 비활성화 */\n disabled?: boolean;\n /** 툴팁 너비 */\n width?: number | string;\n /** 툴팁 오프셋 (px) */\n offset?: number;\n /** 포털 사용 여부 */\n withinPortal?: boolean;\n /** 툴팁 표시 지연 시간 (ms) */\n openDelay?: number;\n /** 툴팁 숨김 지연 시간 (ms) */\n closeDelay?: number;\n /** 툴팁이 표시될 대상 요소 */\n children: React.ReactElement;\n /** 추가 클래스명 */\n className?: string;\n}\n\n/** 뷰포트 기준 위치 계산 + flip(방향 반전) + shift(가장자리 보정) */\nfunction calcPosition(\n trigger: DOMRect,\n tooltip: { width: number; height: number },\n direction: TooltipPosition,\n offset: number,\n): { top: number; left: number; finalDirection: TooltipPosition } {\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n const parts = direction.split(\"-\");\n const side = parts[0] as \"top\" | \"bottom\" | \"left\" | \"right\";\n const alignment = parts[1] as \"start\" | \"end\" | undefined;\n\n // Flip: 공간 부족 시 반대쪽으로\n let finalSide = side;\n\n if (side === \"top\" && trigger.top < tooltip.height + offset) {\n if (vh - trigger.bottom >= tooltip.height + offset) finalSide = \"bottom\";\n } else if (side === \"bottom\" && vh - trigger.bottom < tooltip.height + offset) {\n if (trigger.top >= tooltip.height + offset) finalSide = \"top\";\n } else if (side === \"left\" && trigger.left < tooltip.width + offset) {\n if (vw - trigger.right >= tooltip.width + offset) finalSide = \"right\";\n } else if (side === \"right\" && vw - trigger.right < tooltip.width + offset) {\n if (trigger.left >= tooltip.width + offset) finalSide = \"left\";\n }\n\n let top = 0;\n let left = 0;\n\n // Main axis (주축 위치)\n switch (finalSide) {\n case \"top\":\n top = trigger.top - tooltip.height - offset;\n break;\n case \"bottom\":\n top = trigger.bottom + offset;\n break;\n case \"left\":\n left = trigger.left - tooltip.width - offset;\n break;\n case \"right\":\n left = trigger.right + offset;\n break;\n }\n\n // Cross axis (교차축 정렬)\n if (finalSide === \"top\" || finalSide === \"bottom\") {\n switch (alignment) {\n case \"start\":\n left = trigger.left;\n break;\n case \"end\":\n left = trigger.right - tooltip.width;\n break;\n default:\n left = trigger.left + (trigger.width - tooltip.width) / 2;\n break;\n }\n // Shift: 뷰포트 안에 유지\n left = Math.max(4, Math.min(left, vw - tooltip.width - 4));\n } else {\n switch (alignment) {\n case \"start\":\n top = trigger.top;\n break;\n case \"end\":\n top = trigger.bottom - tooltip.height;\n break;\n default:\n top = trigger.top + (trigger.height - tooltip.height) / 2;\n break;\n }\n top = Math.max(4, Math.min(top, vh - tooltip.height - 4));\n }\n\n const finalDirection = (\n alignment ? `${finalSide}-${alignment}` : finalSide\n ) as TooltipPosition;\n\n return { top, left, finalDirection };\n}\n\n/** Tooltip 컴포넌트는 사용자에게 추가 정보나 설명을 제공하는 작은 팝오버입니다. */\nexport const Tooltip = ({\n label,\n type = \"word\",\n prefixIcon,\n onClose,\n direction = \"top\",\n withArrow = true,\n opened: openedProp,\n defaultOpened = false,\n disabled = false,\n width,\n offset = 8,\n withinPortal = true,\n openDelay = 0,\n closeDelay = 0,\n children,\n className = \"\",\n}: TooltipProps) => {\n const [opened, setOpened] = useState(defaultOpened);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const openTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const closeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isControlled = openedProp !== undefined;\n const isOpened = isControlled ? openedProp : opened;\n\n // Portal 위치 상태\n const [portalPos, setPortalPos] = useState<{\n top: number;\n left: number;\n ready: boolean;\n dir: TooltipPosition;\n }>({ top: 0, left: 0, ready: false, dir: direction });\n\n // 타임아웃 정리\n useEffect(() => {\n return () => {\n if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);\n if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);\n };\n }, []);\n\n const handleMouseEnter = () => {\n if (!disabled && !isControlled) {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n if (openDelay > 0) {\n openTimeoutRef.current = setTimeout(() => {\n setOpened(true);\n }, openDelay);\n } else {\n setOpened(true);\n }\n }\n };\n\n const handleMouseLeave = () => {\n if (!disabled && !isControlled) {\n if (openTimeoutRef.current) {\n clearTimeout(openTimeoutRef.current);\n openTimeoutRef.current = null;\n }\n if (closeDelay > 0) {\n closeTimeoutRef.current = setTimeout(() => {\n setOpened(false);\n }, closeDelay);\n } else {\n setOpened(false);\n }\n }\n };\n\n const handleFocus = () => {\n if (!disabled && !isControlled) {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n if (openDelay > 0) {\n openTimeoutRef.current = setTimeout(() => {\n setOpened(true);\n }, openDelay);\n } else {\n setOpened(true);\n }\n }\n };\n\n const handleBlur = () => {\n if (!disabled && !isControlled) {\n if (openTimeoutRef.current) {\n clearTimeout(openTimeoutRef.current);\n openTimeoutRef.current = null;\n }\n if (closeDelay > 0) {\n closeTimeoutRef.current = setTimeout(() => {\n setOpened(false);\n }, closeDelay);\n } else {\n setOpened(false);\n }\n }\n };\n\n const handleCloseClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (onClose) {\n onClose(e);\n }\n if (!disabled && !isControlled) {\n setOpened(false);\n }\n };\n\n // Portal 위치 계산\n const updatePosition = useCallback(() => {\n if (!wrapperRef.current || !tooltipRef.current) return;\n\n const triggerRect = wrapperRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n const result = calcPosition(\n triggerRect,\n { width: tooltipRect.width, height: tooltipRect.height },\n direction,\n offset,\n );\n\n setPortalPos({\n top: result.top,\n left: result.left,\n ready: true,\n dir: result.finalDirection,\n });\n }, [direction, offset]);\n\n // Paint 전에 위치 계산 (깜빡임 방지)\n useLayoutEffect(() => {\n if (isOpened && withinPortal) {\n updatePosition();\n }\n }, [isOpened, withinPortal, updatePosition]);\n\n // Scroll/Resize 대응 (RAF 스로틀링)\n useEffect(() => {\n if (!isOpened || !withinPortal) return;\n\n let rafId = 0;\n const onUpdate = () => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(updatePosition);\n };\n\n // capture: true → 모든 조상의 스크롤 이벤트 감지\n window.addEventListener(\"scroll\", onUpdate, true);\n window.addEventListener(\"resize\", onUpdate);\n\n return () => {\n window.removeEventListener(\"scroll\", onUpdate, true);\n window.removeEventListener(\"resize\", onUpdate);\n cancelAnimationFrame(rafId);\n };\n }, [isOpened, withinPortal, updatePosition]);\n\n // 방향 결정: portal 모드면 계산된 방향, 아니면 prop 그대로\n const displayDirection = withinPortal ? portalPos.dir : direction;\n\n const tooltipContent = (\n <div\n ref={withinPortal ? tooltipRef : undefined}\n className={`tooltip tooltip--${type} tooltip--${displayDirection} ${withArrow ? \"tooltip--with-arrow\" : \"\"} ${className}`}\n style={\n withinPortal\n ? {\n position: \"fixed\" as const,\n top: portalPos.top,\n left: portalPos.left,\n bottom: \"auto\" as const,\n right: \"auto\" as const,\n transform: \"none\",\n margin: 0,\n visibility: portalPos.ready ? (\"visible\" as const) : (\"hidden\" as const),\n ...(width\n ? { width: typeof width === \"number\" ? `${width}px` : width }\n : {}),\n }\n : width\n ? { width: typeof width === \"number\" ? `${width}px` : width }\n : undefined\n }\n role=\"tooltip\"\n >\n <div className=\"tooltip__content\">\n {prefixIcon && (\n <div className=\"tooltip__prefix-icon\">\n {prefixIcon}\n </div>\n )}\n <div className=\"tooltip__label\">\n <Text variant=\"body-p3\">{label}</Text>\n </div>\n {onClose && (\n <button\n type=\"button\"\n className=\"tooltip__close-button\"\n onClick={handleCloseClick}\n aria-label=\"Close tooltip\"\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 4L4 12M4 4L12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </button>\n )}\n </div>\n {withArrow && (\n <div\n className={`tooltip__arrow tooltip__arrow--${displayDirection.split(\"-\")[0]}`}\n />\n )}\n </div>\n );\n\n // Portal 렌더링: body에 직접 렌더링하여 overflow: hidden 회피\n const renderedTooltip =\n isOpened && !disabled\n ? withinPortal\n ? ReactDOM.createPortal(tooltipContent, document.body)\n : tooltipContent\n : null;\n\n return (\n <div\n ref={wrapperRef}\n className=\"tooltip__wrapper\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n >\n {children}\n {renderedTooltip}\n </div>\n );\n};\n\nTooltip.displayName = \"Tooltip\";\n","import React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n XCircleIcon,\n ExclamationTriangleIcon,\n CheckCircleIcon,\n InformationCircleIcon,\n} from \"@heroicons/react/24/solid\";\nimport { useBreakpoint } from \"../../shared/hooks/useMediaQuery\";\nimport { Text } from \"../Typography/Typography\";\nimport \"./toast.css\";\n\nexport type ToastSize = \"medium\" | \"small\";\nexport type ToastState =\n | \"default\"\n | \"error\"\n | \"warning\"\n | \"success\"\n | \"information\";\nexport type ToastPosition = \"top\" | \"bottom\";\nexport type ToastHorizontalAlign = \"center\" | \"left\" | \"right\";\n\nexport interface ToastProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, \"style\"> {\n /** Toast 크기. 미지정 시 breakpoint 기준(tablet 미만: small, 이상: medium). 지정 시 해당 값으로 오버라이드 */\n size?: ToastSize;\n /** Toast 상태 (default, error, warning, success, information) */\n state?: ToastState;\n /** Toast 메시지 */\n label: React.ReactNode;\n /** State 아이콘 (state에 따라 자동으로 표시되지만, 커스텀 아이콘을 전달할 수 있음) */\n icon?: React.ReactNode;\n /** Toast 위치 (top: 상단, bottom: 하단) - 기본값: top */\n position?: ToastPosition;\n /** 수평 정렬 (center: 중앙, left: 왼쪽, right: 오른쪽) - 기본값: center */\n horizontalAlign?: ToastHorizontalAlign;\n /** 상단 여백 (px) - 기본값: medium일 때 60px, small일 때 20px */\n topOffset?: number;\n /** 하단 여백 (px) - 기본값: 20px */\n bottomOffset?: number;\n /** 좌우 여백 (px) - small 사이즈일 때만 적용, 기본값: 16px */\n horizontalPadding?: number;\n /** 추가 스타일 (position이 명시되면 fixed position 로직을 건너뜁니다) */\n style?: React.CSSProperties;\n}\n\n/** Toast 컴포넌트는 화면에 짧은 시간 동안 나타났다가 자동으로 사라지는 경량 알림 컴포넌트다. */\nexport const Toast = (props: ToastProps) => {\n const {\n size: sizeProp,\n state = \"default\",\n label,\n icon,\n position = \"top\",\n horizontalAlign = \"center\",\n topOffset,\n bottomOffset,\n horizontalPadding,\n className = \"\",\n style,\n ...rest\n } = props;\n\n const { isUnderTablet } = useBreakpoint();\n /** breakpoint 우선, size prop 있으면 오버라이드 (Dialog와 동일) */\n const size: ToastSize = sizeProp ?? (isUnderTablet ? \"small\" : \"medium\");\n\n const baseClasses = [\"toast\", `toast--${size}`, `toast--${state}`, className]\n .filter(Boolean)\n .join(\" \");\n\n // 기본 위치 값 계산 (Layout 스펙: desktop/tablet 60px, mobile 20px)\n const defaultTopOffset = size === \"medium\" ? 60 : 20;\n const defaultBottomOffset = size === \"medium\" ? 60 : 20;\n const defaultHorizontalPadding = 16;\n\n // style prop에 position이 명시되어 있으면 fixed position 로직을 건너뜀\n const hasCustomPosition = style?.position !== undefined;\n\n // 위치 스타일 계산\n const positionStyles: React.CSSProperties = hasCustomPosition\n ? {\n // style prop에 position이 있으면 그대로 사용 (문서/스토리북용)\n ...style,\n }\n : {\n // 실제 사용: fixed position\n position: \"fixed\",\n zIndex: 1000,\n ...style,\n };\n\n // 커스텀 position이 없을 때만 위치 스타일 적용\n if (!hasCustomPosition) {\n // 수직 위치\n if (position === \"top\") {\n positionStyles.top = `${topOffset ?? defaultTopOffset}px`;\n positionStyles.bottom = \"auto\";\n } else {\n positionStyles.bottom = `${bottomOffset ?? defaultBottomOffset}px`;\n positionStyles.top = \"auto\";\n }\n\n // 수평 정렬\n if (size === \"small\") {\n // Mobile: 좌우 패딩 적용\n const padding = horizontalPadding ?? defaultHorizontalPadding;\n positionStyles.left = `${padding}px`;\n positionStyles.right = `${padding}px`;\n positionStyles.transform = \"none\";\n positionStyles.width = `calc(100% - ${padding * 2}px)`;\n } else {\n // Desktop/Tablet: 중앙 정렬 또는 좌우 정렬\n if (horizontalAlign === \"center\") {\n positionStyles.left = \"50%\";\n positionStyles.right = \"auto\";\n positionStyles.transform = \"translateX(-50%)\";\n positionStyles.width = \"auto\";\n positionStyles.minWidth = \"540px\";\n positionStyles.maxWidth = \"760px\";\n } else if (horizontalAlign === \"left\") {\n positionStyles.left = \"16px\";\n positionStyles.right = \"auto\";\n positionStyles.transform = \"none\";\n positionStyles.width = \"auto\";\n positionStyles.minWidth = \"540px\";\n positionStyles.maxWidth = \"760px\";\n } else {\n positionStyles.right = \"16px\";\n positionStyles.left = \"auto\";\n positionStyles.transform = \"none\";\n positionStyles.width = \"auto\";\n positionStyles.minWidth = \"540px\";\n positionStyles.maxWidth = \"760px\";\n }\n }\n }\n\n // State에 따른 기본 아이콘 (icon prop이 제공되지 않은 경우)\n const defaultIcon =\n !icon && state !== \"default\" ? (\n <div className=\"toast__icon\">\n {state === \"error\" && (\n <XCircleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n {state === \"warning\" && (\n <ExclamationTriangleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n {state === \"success\" && (\n <CheckCircleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n {state === \"information\" && (\n <InformationCircleIcon style={{ width: \"100%\", height: \"100%\" }} />\n )}\n </div>\n ) : icon ? (\n <div className=\"toast__icon\">{icon}</div>\n ) : null;\n\n return (\n <div className={baseClasses} style={positionStyles} {...rest}>\n {defaultIcon}\n <Text variant={size === \"medium\" ? \"heading-h6\" : \"subtitle-p2\"}>\n {label}\n </Text>\n </div>\n );\n};\n\n// useToast hook 관련 타입 및 인터페이스\nexport interface ToastOptions {\n /** Toast 상태 */\n state?: ToastState;\n /** Toast 크기 */\n size?: ToastSize;\n /** 자동으로 사라지는 시간 (ms) - 기본값: 3000 */\n duration?: number;\n /** Toast 위치 */\n position?: ToastPosition;\n /** 수평 정렬 */\n horizontalAlign?: ToastHorizontalAlign;\n /** 상단 여백 */\n topOffset?: number;\n /** 하단 여백 */\n bottomOffset?: number;\n /** 좌우 여백 */\n horizontalPadding?: number;\n}\n\nconst TOAST_EXIT_MS = 250;\n\ninterface ToastItem {\n id: string;\n message: string;\n state: ToastState;\n /** 미지정 시 Toast 내부에서 breakpoint 기준 적용 */\n size?: ToastSize;\n duration: number;\n position: ToastPosition;\n horizontalAlign: ToastHorizontalAlign;\n topOffset?: number;\n bottomOffset?: number;\n horizontalPadding?: number;\n exiting?: boolean;\n}\n\ninterface ToastContextType {\n showToast: (message: string, options?: ToastOptions) => void;\n hideToast: (id: string) => void;\n}\n\nconst ToastContext = React.createContext<ToastContextType | undefined>(\n undefined\n);\n\n/**\n * ToastProvider\n *\n * 앱의 최상위(Root)에 선언하여 전역 Toast 기능을 제공합니다.\n * Portal을 사용하여 document.body에 Toast를 렌더링합니다.\n */\nexport const ToastProvider = ({ children }: { children: React.ReactNode }) => {\n const [toasts, setToasts] = React.useState<ToastItem[]>([]);\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n setMounted(true);\n }, []);\n\n const showToast = React.useCallback(\n (message: string, options: ToastOptions = {}) => {\n const id = `toast-${Date.now()}-${Math.random()}`;\n const {\n state = \"default\",\n size,\n duration = 3000,\n position = \"top\",\n horizontalAlign = \"center\",\n topOffset,\n bottomOffset,\n horizontalPadding,\n } = options;\n\n const newToast: ToastItem = {\n id,\n message,\n state,\n ...(size !== undefined && { size }),\n duration,\n position,\n horizontalAlign,\n topOffset,\n bottomOffset,\n horizontalPadding,\n };\n\n setToasts((prev) => [...prev, newToast]);\n\n if (duration > 0) {\n setTimeout(() => {\n setToasts((prev) =>\n prev.map((t) => (t.id === id ? { ...t, exiting: true } : t))\n );\n setTimeout(() => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, TOAST_EXIT_MS);\n }, duration);\n }\n },\n []\n );\n\n const hideToast = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ showToast, hideToast }}>\n {children}\n {mounted &&\n createPortal(\n <>\n {toasts.map((toast) => (\n <Toast\n key={toast.id}\n state={toast.state}\n size={toast.size}\n label={toast.message}\n position={toast.position}\n horizontalAlign={toast.horizontalAlign}\n topOffset={toast.topOffset}\n bottomOffset={toast.bottomOffset}\n horizontalPadding={toast.horizontalPadding}\n {...(toast.exiting && { className: \"toast--exiting\" })}\n />\n ))}\n </>,\n document.body\n )}\n </ToastContext.Provider>\n );\n};\n\n/**\n * useToast Hook\n *\n * ToastProvider 내부의 컴포넌트에서 호출하여 사용합니다.\n * { showToast } 함수를 반환합니다.\n *\n * @example\n * const { showToast } = useToast();\n * showToast(\"메시지\", { state: \"success\" });\n */\nexport function useToast() {\n const context = React.useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nToast.displayName = \"Toast\";\n","import React, { useState, useCallback, useRef, useEffect, useMemo } from \"react\";\nimport \"./datepicker.css\";\nimport { useBreakpoint } from \"../../shared/hooks/useMediaQuery\";\nimport { Calendar } from \"./Calendar\";\nimport type { CalendarProps } from \"./Calendar\";\nimport { DateInput, formatDate, parseDate } from \"./DateInput\";\nimport type { DateInputProps } from \"./DateInput\";\nimport { TimePicker } from \"./TimePicker\";\nimport { ActionButton } from \"@/stories/Button/ActionButton/ActionButton\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport { Text } from \"../Typography/Typography\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DatePickerType = \"single\" | \"range\";\n\n/**\n * DatePicker 내부 서브 컴포넌트 슬롯 이름.\n * classNames / styles 객체의 키로 사용됩니다.\n *\n * - `root` — 최상위 wrapper\n * - `input` — 상단 트리거 인풋 박스 (DateInput의 content 영역)\n * - `popover` — 팝오버 컨테이너\n * - `calendar` — Calendar 컴포넌트 (range 모드일 때 두 캘린더 모두 적용)\n * - `footer` — 푸터 영역 (취소/적용 버튼 영역)\n * - `footerInput` — 푸터 내부 인풋 박스 (range 모드에서만 사용)\n * - `timePicker` — TimePicker 컴포넌트 (showTimeSelect 사용 시)\n *\n * @example\n * <DatePicker\n * styles={{\n * input: { height: 40, borderRadius: 12 },\n * calendar: { background: \"#fafafa\" },\n * popover: { width: 400 },\n * }}\n * classNames={{\n * input: \"my-input\",\n * calendar: \"my-calendar\",\n * }}\n * />\n */\nexport type DatePickerSlot =\n | \"root\"\n | \"input\"\n | \"popover\"\n | \"calendar\"\n | \"footer\"\n | \"footerInput\"\n | \"timePicker\";\n\nexport interface DatePickerSingleProps {\n type?: \"single\";\n /** 선택된 날짜 */\n value?: Date | null;\n /**\n * 날짜 변경 핸들러 (적용/초기화 시 호출).\n * 초기화 시 `null`이 전달됩니다.\n * method syntax로 선언되어 `(d: Date) => ...` 형태의 기존 콜백과도 호환됩니다.\n */\n onChange?(date: Date | null): void;\n startDate?: never;\n endDate?: never;\n onRangeChange?: never;\n}\n\nexport interface DatePickerRangeProps {\n type: \"range\";\n value?: never;\n onChange?: never;\n /** 시작 날짜 */\n startDate?: Date | null;\n /** 종료 날짜 */\n endDate?: Date | null;\n /**\n * 기간 변경 핸들러 (적용/초기화 시 호출).\n * 초기화 시 `(null, null)`이 전달됩니다.\n * method syntax로 선언되어 `(s: Date, e: Date | null) => ...` 형태의 기존 콜백과도 호환됩니다.\n */\n onRangeChange?(start: Date | null, end: Date | null): void;\n}\n\n/** DatePicker가 내부적으로 관리하는 Calendar props (사용자가 오버라이드 불가) */\ntype ManagedCalendarProps =\n | \"year\" | \"month\"\n | \"selectedDate\" | \"startDate\" | \"endDate\" | \"hoverDate\"\n | \"rangeMode\" | \"minDate\" | \"maxDate\"\n | \"onClick\" | \"onHover\" | \"onPrev\" | \"onNext\"\n | \"showPrev\" | \"showNext\" | \"disablePrev\" | \"disableNext\"\n | \"locale\" | \"className\" | \"style\" | \"children\";\n\n/** DatePicker가 내부적으로 관리하는 DateInput props (사용자가 오버라이드 불가) */\ntype ManagedDateInputProps =\n | \"type\" | \"value\" | \"startDate\" | \"endDate\"\n | \"onClick\" | \"onReset\" | \"reset\"\n | \"disabled\" | \"error\" | \"description\"\n | \"locale\" | \"placeholder\" | \"dateFormat\" | \"className\" | \"style\";\n\ntype DatePickerBaseProps = {\n /** 비활성화 */\n disabled?: boolean;\n /** 읽기 전용 (값은 표시되지만 변경 불가) */\n readOnly?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** 도움말 텍스트 */\n description?: string;\n /** 선택 가능한 최소 날짜 */\n minDate?: Date;\n /** 선택 가능한 최대 날짜 */\n maxDate?: Date;\n /** 언어 설정 */\n locale?: string;\n /** 최상위 wrapper에 적용되는 CSS 클래스 (classNames.root의 단축 표현) */\n className?: string;\n /** 플레이스홀더 */\n placeholder?: string;\n /** 이전 버튼 표시 여부 (기본: true) */\n showPrev?: boolean;\n /** 다음 버튼 표시 여부 (기본: true) */\n showNext?: boolean;\n /** 이전 버튼 비활성화 여부 (기본: false) */\n disablePrev?: boolean;\n /** 다음 버튼 비활성화 여부 (기본: false) */\n disableNext?: boolean;\n /** 초기화 버튼 표시 여부 (기본: true, 날짜가 선택되어 있을 때 표시) */\n reset?: boolean;\n /**\n * 캘린더를 열었을 때 기본으로 표시할 월.\n * 지정하지 않으면 선택된 날짜 → 오늘 순으로 결정됩니다.\n * @example defaultMonth={new Date(2026, 5)} // 2026년 6월\n * @example defaultMonth=\"2026-06\"\n */\n defaultMonth?: Date | string;\n /** 시간 선택 패널 표시 여부 (기본: false, single 모드에서만 동작) */\n showTimeSelect?: boolean;\n /** 시간 간격 (분 단위, 기본: 30). showTimeSelect 활성화 시 사용 */\n timeIntervals?: number;\n /**\n * 날짜 표시 포맷.\n * 지원 토큰: yyyy, MM, M, dd, d, HH, mm\n * @default \"yyyy. M. d\" (showTimeSelect 시 \"yyyy. M. d HH:mm\")\n * @example \"yyyy.MM.dd HH:mm\" → \"2026.03.11 14:30\"\n * @example \"yyyy-MM-dd\" → \"2026-03-11\"\n */\n dateFormat?: string;\n /** 초기화 버튼 클릭 시 호출되는 콜백 (내부 초기화 동작 이후에 호출) */\n onReset?: () => void;\n /**\n * 적용 버튼 클릭 시 호출되는 콜백.\n * 값이 없을 땐 적용 버튼이 비활성화되어 호출되지 않습니다.\n * single 모드: (date: Date) => void\n * range 모드: (startDate: Date, endDate: Date) => void\n */\n onApply?: (date: Date, endDate?: Date) => void;\n /** 취소 버튼 클릭 시 호출되는 콜백 */\n onCancel?: () => void;\n\n /**\n * 각 서브 컴포넌트별 커스텀 CSS 클래스.\n * 기존 컴포넌트의 기본 className에 병합(추가)됩니다.\n *\n * @example\n * classNames={{\n * root: \"my-datepicker\",\n * input: \"my-input\",\n * popover: \"my-popover\",\n * calendar: \"my-calendar\",\n * footer: \"my-footer\",\n * footerInput: \"my-footer-input\",\n * }}\n */\n classNames?: Partial<Record<DatePickerSlot, string>>;\n\n /**\n * 각 서브 컴포넌트별 인라인 스타일.\n * 해당 컴포넌트의 최상위 요소에 style 속성으로 적용됩니다.\n *\n * @example\n * styles={{\n * input: { height: 40, borderRadius: 12 },\n * calendar: { background: \"#f5f5f5\" },\n * popover: { width: 400 },\n * }}\n */\n styles?: Partial<Record<DatePickerSlot, React.CSSProperties>>;\n\n /**\n * Calendar 컴포넌트에 전달할 추가 props.\n * DatePicker가 내부적으로 관리하는 props(year, month, selectedDate 등)는\n * 제외되며, 나머지를 오버라이드할 수 있습니다.\n * range 모드일 경우 두 캘린더 모두에 동일하게 적용됩니다.\n *\n * @example\n * calendarProps={{ disablePrev: true, disableNext: false }}\n */\n calendarProps?: Partial<Omit<CalendarProps, ManagedCalendarProps>>;\n\n /**\n * 트리거 DateInput 컴포넌트에 전달할 추가 props.\n * DatePicker가 내부적으로 관리하는 props(type, value, onClick 등)는\n * 제외되며, 나머지를 오버라이드할 수 있습니다.\n *\n * @example\n * dateInputProps={{\n * prefixIcon: false,\n * startPlaceholder: \"출발일\",\n * endPlaceholder: \"도착일\",\n * }}\n */\n dateInputProps?: Partial<Omit<DateInputProps, ManagedDateInputProps>>;\n};\n\nexport type DatePickerProps = DatePickerBaseProps &\n (DatePickerSingleProps | DatePickerRangeProps);\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nconst toDate = (d: Date | string | number): Date =>\n d instanceof Date ? d : new Date(d);\n\nconst startOf = (d: Date | string | number) => {\n const dt = toDate(d);\n return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());\n};\n\nconst I18N: Record<string, { today: string; cancel: string; apply: string }> = {\n \"ko-KR\": { today: \"오늘\", cancel: \"취소\", apply: \"적용\" },\n \"en-US\": { today: \"Today\", cancel: \"Cancel\", apply: \"Apply\" },\n \"ja-JP\": { today: \"今日\", cancel: \"キャンセル\", apply: \"適用\" },\n};\n\nconst getI18n = (locale: string) =>\n I18N[locale] ?? I18N[\"ko-KR\"];\n\n// ── DatePicker Component ──────────────────────────────────────────────────────\n\n/** DatePicker는 DateInput과 Calendar를 조합한 완성형 날짜 선택 컴포넌트입니다. */\nexport const DatePicker: React.FC<DatePickerProps> = (props) => {\n const {\n type = \"single\",\n disabled = false,\n readOnly = false,\n error = false,\n description,\n minDate,\n maxDate,\n locale = \"ko-KR\",\n className = \"\",\n placeholder,\n showPrev = true,\n showNext = true,\n disablePrev = false,\n disableNext = false,\n reset: resetProp = true,\n defaultMonth,\n showTimeSelect = false,\n timeIntervals = 30,\n dateFormat: dateFormatProp,\n onReset: onResetProp,\n onApply: onApplyProp,\n onCancel: onCancelProp,\n classNames,\n styles,\n calendarProps,\n dateInputProps,\n } = props;\n\n const i18n = getI18n(locale);\n const { isUnderTablet: isMobile } = useBreakpoint();\n const isRange = type === \"range\";\n const isTimeEnabled = showTimeSelect && !isRange;\n\n // showTimeSelect가 켜져있고 dateFormat이 지정되지 않으면 시간 포함 포맷\n const effectiveDateFormat = dateFormatProp ?? (isTimeEnabled ? \"yyyy. M. d HH:mm\" : undefined);\n const singleValue = !isRange\n ? (props as DatePickerSingleProps).value\n : undefined;\n const singleOnChange = !isRange\n ? (props as DatePickerSingleProps).onChange\n : undefined;\n const extStartDate = isRange\n ? (props as DatePickerRangeProps).startDate\n : undefined;\n const extEndDate = isRange\n ? (props as DatePickerRangeProps).endDate\n : undefined;\n const onRangeChange = isRange\n ? (props as DatePickerRangeProps).onRangeChange\n : undefined;\n\n const [isOpen, setIsOpen] = useState(false);\n const [rawCurrentMonth, setCurrentMonth] = useState<Date>(() => {\n if (defaultMonth) return defaultMonth instanceof Date ? defaultMonth : new Date(defaultMonth);\n if (singleValue) return singleValue;\n if (extStartDate) return extStartDate;\n const now = new Date();\n if (maxDate && now > toDate(maxDate)) return toDate(maxDate);\n if (minDate && now < toDate(minDate)) return toDate(minDate);\n return now;\n });\n\n // minDate/maxDate 범위를 벗어나면 자동 클램핑\n const currentMonth = useMemo(() => {\n if (maxDate && rawCurrentMonth > toDate(maxDate)) return toDate(maxDate);\n if (minDate && rawCurrentMonth < toDate(minDate)) return toDate(minDate);\n return rawCurrentMonth;\n }, [rawCurrentMonth, minDate, maxDate]);\n\n const [hoverDate, setHoverDate] = useState<Date | null>(null);\n const [internalStart, setInternalStart] = useState<Date | null>(\n extStartDate ?? null\n );\n const [internalEnd, setInternalEnd] = useState<Date | null>(\n extEndDate ?? null\n );\n const [internalSingle, setInternalSingle] = useState<Date | null>(\n singleValue ?? null\n );\n\n // 트리거 인풋에 표시할 확정된 값 (적용 버튼 클릭 시에만 갱신)\n const [committedSingle, setCommittedSingle] = useState<Date | null>(\n singleValue ?? null\n );\n const [committedStart, setCommittedStart] = useState<Date | null>(\n extStartDate ?? null\n );\n const [committedEnd, setCommittedEnd] = useState<Date | null>(\n extEndDate ?? null\n );\n\n // ── Single 캘린더 내부 날짜 입력 편집 상태 ──\n const [isEditingSingleField, setIsEditingSingleField] = useState(false);\n const [singleFieldText, setSingleFieldText] = useState(\"\");\n\n const handleSingleFieldFocus = useCallback(() => {\n setIsEditingSingleField(true);\n setSingleFieldText(formatDate(internalSingle, effectiveDateFormat, locale));\n }, [internalSingle, effectiveDateFormat, locale]);\n\n const handleSingleFieldBlur = useCallback(() => {\n const parsed = parseDate(singleFieldText, internalSingle);\n if (parsed && parsed !== internalSingle) {\n if (isTimeEnabled) {\n // 시간 포함 파싱이 안 됐으면(시간=0:00) 기존 시/분 유지\n const hasTime = parsed.getHours() !== 0 || parsed.getMinutes() !== 0;\n if (!hasTime && internalSingle) {\n parsed.setHours(internalSingle.getHours(), internalSingle.getMinutes(), 0, 0);\n }\n }\n setInternalSingle(parsed);\n setCurrentMonth(new Date(parsed.getFullYear(), parsed.getMonth(), 1));\n }\n setIsEditingSingleField(false);\n }, [singleFieldText, isTimeEnabled, internalSingle]);\n\n const handleSingleFieldKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleSingleFieldBlur();\n (e.target as HTMLInputElement).blur();\n }\n },\n [handleSingleFieldBlur],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node)\n ) {\n // 외부 클릭 시 취소와 동일하게 draft를 되돌림\n if (isRange) {\n setInternalStart(committedStart);\n setInternalEnd(committedEnd);\n } else {\n setInternalSingle(committedSingle);\n }\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isRange, committedSingle, committedStart, committedEnd]);\n\n // Sync external props\n useEffect(() => {\n if (!isRange && singleValue !== undefined) {\n requestAnimationFrame(() => {\n setInternalSingle(singleValue);\n setCommittedSingle(singleValue);\n });\n }\n }, [singleValue, isRange]);\n\n useEffect(() => {\n if (isRange) {\n requestAnimationFrame(() => {\n if (extStartDate !== undefined) {\n setInternalStart(extStartDate ?? null);\n setCommittedStart(extStartDate ?? null);\n }\n if (extEndDate !== undefined) {\n setInternalEnd(extEndDate ?? null);\n setCommittedEnd(extEndDate ?? null);\n }\n });\n }\n }, [extStartDate, extEndDate, isRange]);\n\n const year = currentMonth.getFullYear();\n const month = currentMonth.getMonth();\n\n const handlePrev = useCallback(\n () => setCurrentMonth(new Date(year, month - 1, 1)),\n [year, month]\n );\n const handleNext = useCallback(\n () => setCurrentMonth(new Date(year, month + 1, 1)),\n [year, month]\n );\n\n // minDate/maxDate 기준으로 이전/다음 달 버튼 자동 비활성화\n const autoDisablePrev = disablePrev || (minDate ? year === toDate(minDate).getFullYear() && month <= toDate(minDate).getMonth() : false);\n const autoDisableNext = disableNext || (maxDate ? year === toDate(maxDate).getFullYear() && month >= toDate(maxDate).getMonth() : false);\n\n const handleSingleDayClick = (date: Date) => {\n // outside month 날짜 클릭 시 해당 월로 자동 이동\n if (\n date.getMonth() !== currentMonth.getMonth() ||\n date.getFullYear() !== currentMonth.getFullYear()\n ) {\n setCurrentMonth(new Date(date.getFullYear(), date.getMonth(), 1));\n }\n if (isTimeEnabled && internalSingle) {\n // 시간 선택 모드: 기존 시/분을 유지하며 날짜만 변경\n const newDate = new Date(date);\n newDate.setHours(internalSingle.getHours(), internalSingle.getMinutes(), 0, 0);\n setInternalSingle(newDate);\n } else {\n setInternalSingle(date);\n }\n };\n\n const handleTimeChange = (date: Date) => {\n setInternalSingle(date);\n };\n\n const handleRangeDayClick = (date: Date) => {\n // 단일 캘린더 모드(모바일)에서만 outside 클릭 시 자동 이동\n // 데스크톱 이중 캘린더는 양쪽에 보이는 outside 가 많아서 이동하면 시점이 흔들림\n if (\n isMobile &&\n (date.getMonth() !== currentMonth.getMonth() ||\n date.getFullYear() !== currentMonth.getFullYear())\n ) {\n setCurrentMonth(new Date(date.getFullYear(), date.getMonth(), 1));\n }\n if (!internalStart || (internalStart && internalEnd)) {\n setInternalStart(date);\n setInternalEnd(null);\n } else {\n const s = startOf(internalStart);\n const e = startOf(date);\n if (e >= s) {\n setInternalEnd(date);\n } else {\n setInternalStart(date);\n setInternalEnd(internalStart);\n }\n }\n };\n\n const handleTodayClick = () => {\n const today = new Date();\n if (isRange) {\n setInternalStart(today);\n setInternalEnd(null);\n } else {\n setInternalSingle(today);\n }\n setCurrentMonth(new Date(today.getFullYear(), today.getMonth(), 1));\n };\n\n const handleCancel = () => {\n setIsOpen(false);\n if (isRange) {\n setInternalStart(committedStart);\n setInternalEnd(committedEnd);\n } else {\n setInternalSingle(committedSingle);\n }\n onCancelProp?.();\n };\n\n const handleApply = () => {\n setIsOpen(false);\n if (isRange && internalStart && internalEnd) {\n setCommittedStart(internalStart);\n setCommittedEnd(internalEnd);\n onRangeChange?.(internalStart, internalEnd);\n onApplyProp?.(internalStart, internalEnd);\n } else if (!isRange && internalSingle) {\n setCommittedSingle(internalSingle);\n singleOnChange?.(internalSingle);\n onApplyProp?.(internalSingle);\n }\n // 값이 없을 땐 isApplyDisabled로 이미 막혀있어 도달 불가\n };\n\n // ── 모바일 바텀시트 드래그 다운으로 닫기 ──\n const [dragY, setDragY] = useState(0);\n const dragStartRef = useRef<number | null>(null);\n\n const handleDragStart = (e: React.TouchEvent<HTMLDivElement>) => {\n dragStartRef.current = e.touches[0].clientY;\n };\n\n const handleDragMove = (e: React.TouchEvent<HTMLDivElement>) => {\n if (dragStartRef.current === null) return;\n const dy = e.touches[0].clientY - dragStartRef.current;\n if (dy > 0) setDragY(dy);\n };\n\n const handleDragEnd = () => {\n if (dragStartRef.current === null) return;\n if (dragY > 80) {\n handleCancel();\n }\n setDragY(0);\n dragStartRef.current = null;\n };\n\n // ── 모바일 바텀시트 열릴 때 오버레이/시트 전체 wheel/touchmove 차단 ──\n // 바텀시트 내부는 스크롤할 필요가 없으므로 전부 막음\n const overlayRef = useRef<HTMLDivElement>(null);\n const sheetRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!isOpen || !isMobile) return;\n\n const overlay = overlayRef.current;\n const sheet = sheetRef.current;\n\n const prevent = (e: Event) => e.preventDefault();\n\n overlay?.addEventListener(\"wheel\", prevent, { passive: false });\n overlay?.addEventListener(\"touchmove\", prevent, { passive: false });\n sheet?.addEventListener(\"wheel\", prevent, { passive: false });\n sheet?.addEventListener(\"touchmove\", prevent, { passive: false });\n\n return () => {\n overlay?.removeEventListener(\"wheel\", prevent);\n overlay?.removeEventListener(\"touchmove\", prevent);\n sheet?.removeEventListener(\"wheel\", prevent);\n sheet?.removeEventListener(\"touchmove\", prevent);\n };\n }, [isOpen, isMobile]);\n\n // ── ESC 키로 닫기 (취소 동작) ──\n useEffect(() => {\n if (!isOpen) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") handleCancel();\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n // ── 팝오버 방향 자동 결정 (뷰포트 하단 공간 부족 시 위로) ──\n const [openAbove, setOpenAbove] = useState(false);\n\n const calcOpenDirection = useCallback(() => {\n if (!containerRef.current) return false;\n const rect = containerRef.current.getBoundingClientRect();\n const popoverHeight = isRange ? 480 : 420;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n return spaceBelow < popoverHeight && spaceAbove > spaceBelow;\n }, [isRange]);\n\n const handleReset = () => {\n if (isRange) {\n setInternalStart(null);\n setInternalEnd(null);\n setCommittedStart(null);\n setCommittedEnd(null);\n // 소비자가 onRangeChange에서 reset 감지 가능하도록 null 전달\n onRangeChange?.(null, null);\n } else {\n setInternalSingle(null);\n setCommittedSingle(null);\n // 소비자가 onChange에서 reset 감지 가능하도록 null 전달\n singleOnChange?.(null);\n }\n onResetProp?.();\n };\n\n // 적용 버튼 활성화 조건: single은 날짜 선택, range는 시작+종료 모두 선택\n const isApplyDisabled = isRange\n ? !internalStart || !internalEnd\n : !internalSingle;\n\n const helpVariant = error ? \"error\" : \"inform\";\n\n return (\n <div\n className={`datepicker-root ${disabled ? \"datepicker-root--disabled\" : \"\"} ${readOnly ? \"datepicker-root--readonly\" : \"\"} ${className} ${classNames?.root ?? \"\"}`.trim()}\n style={styles?.root}\n ref={containerRef}\n >\n <div className=\"datepicker-wrapper\">\n <DateInput\n {...dateInputProps}\n disabled={disabled}\n error={error}\n type={isRange ? \"range\" : \"single\"}\n value={!isRange ? (singleValue ?? committedSingle) : undefined}\n startDate={isRange ? (extStartDate ?? committedStart) : undefined}\n endDate={isRange ? (extEndDate ?? committedEnd) : undefined}\n reset={\n resetProp &&\n !disabled &&\n !readOnly &&\n (isRange\n ? !!(committedStart || committedEnd)\n : !!(singleValue ?? committedSingle))\n }\n locale={locale}\n placeholder={placeholder}\n dateFormat={effectiveDateFormat}\n classNames={{\n ...dateInputProps?.classNames,\n ...(classNames?.input ? { content: [dateInputProps?.classNames?.content, classNames.input].filter(Boolean).join(\" \") || undefined } : {}),\n }}\n styles={{\n ...dateInputProps?.styles,\n ...(styles?.input ? { content: { ...dateInputProps?.styles?.content, ...styles.input } } : {}),\n }}\n onClick={() => {\n if (disabled || readOnly) return;\n if (!isOpen) setOpenAbove(calcOpenDirection());\n setIsOpen(!isOpen);\n }}\n onReset={handleReset}\n />\n\n {isMobile && (\n <div\n ref={overlayRef}\n className={`dp-overlay ${isOpen ? \"dp-overlay--open\" : \"\"}`.trim()}\n onClick={handleCancel}\n aria-hidden={!isOpen}\n />\n )}\n {(isOpen || isMobile) && (\n <div\n ref={sheetRef}\n className={`dp-popover ${isMobile ? \"dp-popover--mobile\" : \"\"} ${isMobile && isOpen ? \"dp-popover--open\" : \"\"} ${openAbove ? \"dp-popover--top\" : \"\"} ${isRange ? \"dp-popover--range\" : \"dp-popover--single\"} ${isTimeEnabled ? \"dp-popover--with-time\" : \"\"} ${classNames?.popover ?? \"\"}`.trim()}\n aria-hidden={isMobile && !isOpen}\n style={{\n ...styles?.popover,\n ...(isMobile && dragY > 0\n ? { transform: `translateY(${dragY}px)`, transition: \"none\" }\n : {}),\n }}\n >\n {isMobile && (\n <div\n className=\"dp-handle-area\"\n onTouchStart={handleDragStart}\n onTouchMove={handleDragMove}\n onTouchEnd={handleDragEnd}\n onTouchCancel={handleDragEnd}\n >\n <div className=\"dp-handle\" aria-hidden=\"true\" />\n </div>\n )}\n {isRange ? (\n <>\n <div className=\"dp-content\">\n <div className=\"dp-calendars-wrapper\">\n <Calendar\n {...calendarProps}\n fixedWeeks={isMobile}\n year={year}\n month={month}\n locale={locale}\n startDate={internalStart}\n endDate={internalEnd}\n hoverDate={hoverDate}\n rangeMode\n minDate={minDate}\n maxDate={maxDate}\n showPrev={showPrev}\n showNext={isMobile ? showNext : false}\n disablePrev={autoDisablePrev}\n disableNext={autoDisableNext}\n className={classNames?.calendar}\n style={styles?.calendar}\n onClick={handleRangeDayClick}\n onHover={setHoverDate}\n onPrev={handlePrev}\n onNext={handleNext}\n >\n {isMobile && (\n <div className=\"calendar-date-input-row\">\n <DateInput\n type=\"range\"\n startDate={internalStart}\n endDate={internalEnd}\n prefixIcon={false}\n reset={false}\n editable\n locale={locale}\n dateFormat={effectiveDateFormat}\n onStartChange={(date) => {\n if (date) {\n setInternalStart(date);\n setCurrentMonth(new Date(date.getFullYear(), date.getMonth(), 1));\n }\n }}\n onEndChange={(date) => {\n if (date) setInternalEnd(date);\n }}\n />\n </div>\n )}\n </Calendar>\n <Calendar\n {...calendarProps}\n fixedWeeks={isMobile}\n year={month === 11 ? year + 1 : year}\n month={month === 11 ? 0 : month + 1}\n locale={locale}\n startDate={internalStart}\n endDate={internalEnd}\n hoverDate={hoverDate}\n rangeMode\n minDate={minDate}\n maxDate={maxDate}\n showPrev={false}\n showNext={showNext}\n disablePrev={autoDisablePrev}\n disableNext={autoDisableNext}\n className={classNames?.calendar}\n style={styles?.calendar}\n onClick={handleRangeDayClick}\n onHover={setHoverDate}\n onPrev={handlePrev}\n onNext={handleNext}\n />\n </div>\n </div>\n\n {/* Range Footer: DateInput(editable) + 취소 + 적용 */}\n <div\n className={`dp-footer ${classNames?.footer ?? \"\"}`.trim()}\n style={styles?.footer}\n >\n <div className=\"dp-footer-input\">\n <DateInput\n type=\"range\"\n startDate={internalStart}\n endDate={internalEnd}\n prefixIcon={false}\n reset={false}\n editable\n locale={locale}\n dateFormat={effectiveDateFormat}\n classNames={classNames?.footerInput ? { content: classNames.footerInput } : undefined}\n styles={styles?.footerInput ? { content: styles.footerInput } : undefined}\n onStartChange={(date) => {\n if (date) {\n setInternalStart(date);\n setCurrentMonth(new Date(date.getFullYear(), date.getMonth(), 1));\n }\n }}\n onEndChange={(date) => {\n if (date) setInternalEnd(date);\n }}\n />\n </div>\n <ActionButton\n type=\"outline\"\n color=\"neutral\"\n size={isMobile ? \"medium\" : \"large\"}\n label={i18n.cancel}\n className=\"dp-footer__action\"\n onClick={handleCancel}\n />\n <ActionButton\n type=\"solid\"\n color=\"primary\"\n size={isMobile ? \"medium\" : \"large\"}\n label={i18n.apply}\n className=\"dp-footer__action\"\n onClick={handleApply}\n disabled={isApplyDisabled}\n />\n </div>\n </>\n ) : (\n <>\n <div\n className={`dp-content ${isTimeEnabled ? \"dp-content--with-time\" : \"\"}`.trim()}\n >\n <Calendar\n {...calendarProps}\n fixedWeeks={isMobile}\n year={year}\n month={month}\n locale={locale}\n selectedDate={internalSingle}\n minDate={minDate}\n maxDate={maxDate}\n showPrev={showPrev}\n showNext={showNext}\n disablePrev={autoDisablePrev}\n disableNext={autoDisableNext}\n className={classNames?.calendar}\n style={styles?.calendar}\n onClick={handleSingleDayClick}\n onPrev={handlePrev}\n onNext={handleNext}\n >\n {/* 날짜 입력 필드 + 오늘 버튼 (헤더와 그리드 사이) */}\n <div className=\"calendar-date-input-row\">\n <div className=\"calendar-date-field\">\n <input\n type=\"text\"\n className=\"calendar-date-field__input\"\n value={\n isEditingSingleField\n ? singleFieldText\n : formatDate(internalSingle, effectiveDateFormat, locale) || \"\"\n }\n placeholder={placeholder || \"날짜 선택\"}\n onFocus={handleSingleFieldFocus}\n onChange={(e) => setSingleFieldText(e.target.value)}\n onBlur={handleSingleFieldBlur}\n onKeyDown={handleSingleFieldKeyDown}\n />\n </div>\n <button\n type=\"button\"\n className=\"calendar-today-btn\"\n onClick={handleTodayClick}\n >\n {i18n.today}\n </button>\n </div>\n </Calendar>\n\n {isTimeEnabled && (\n <TimePicker\n selectedDate={internalSingle}\n onTimeChange={handleTimeChange}\n timeIntervals={timeIntervals}\n className={classNames?.timePicker}\n style={styles?.timePicker}\n />\n )}\n </div>\n\n {/* Single Footer: 취소 + 적용 */}\n <div\n className={`dp-footer dp-footer--single ${classNames?.footer ?? \"\"}`.trim()}\n style={styles?.footer}\n >\n <ActionButton\n type=\"outline\"\n color=\"neutral\"\n size={isMobile ? \"medium\" : \"large\"}\n label={i18n.cancel}\n className=\"dp-footer__action\"\n onClick={handleCancel}\n />\n <ActionButton\n type=\"solid\"\n color=\"primary\"\n size={isMobile ? \"medium\" : \"large\"}\n label={i18n.apply}\n className=\"dp-footer__action\"\n onClick={handleApply}\n disabled={isApplyDisabled}\n />\n </div>\n </>\n )}\n </div>\n )}\n </div>\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {error && (\n <span className=\"help-text__icon\">\n <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n </span>\n )}\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n </span>\n )}\n </div>\n );\n};\n\nDatePicker.displayName = \"DatePicker\";\n","import React, { useMemo, useCallback } from \"react\";\nimport \"./calendar.css\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface CalendarProps {\n /** 연도 */\n year?: number;\n /** 월 (0-11) */\n month?: number;\n /** 선택된 날짜 (single 모드) */\n selectedDate?: Date | null;\n /** 시작 날짜 (range 모드) */\n startDate?: Date | null;\n /** 종료 날짜 (range 모드) */\n endDate?: Date | null;\n /** 호버 중인 날짜 (range 모드) */\n hoverDate?: Date | null;\n /** 기간 선택 모드 여부 */\n rangeMode?: boolean;\n /** 선택 가능한 최소 날짜 */\n minDate?: Date;\n /** 선택 가능한 최대 날짜 */\n maxDate?: Date;\n /** 언어 설정 */\n locale?: string;\n /** 날짜 클릭 핸들러 */\n onClick?: (date: Date) => void;\n /** 날짜 호버 핸들러 */\n onHover?: (date: Date | null) => void;\n /** 이전 달 이동 핸들러 */\n onPrev?: () => void;\n /** 다음 달 이동 핸들러 */\n onNext?: () => void;\n /** 이전 버튼 표시 여부 */\n showPrev?: boolean;\n /** 다음 버튼 표시 여부 */\n showNext?: boolean;\n /** 이전 버튼 비활성화 여부 */\n disablePrev?: boolean;\n /** 다음 버튼 비활성화 여부 */\n disableNext?: boolean;\n /** 항상 6주(42칸) 고정 렌더 — 월 이동 시 높이 변화 방지 */\n fixedWeeks?: boolean;\n /** 추가 CSS 클래스 */\n className?: string;\n /** 인라인 스타일 (최상위 calendar 요소에 적용) */\n style?: React.CSSProperties;\n /** 헤더와 그리드 사이에 렌더링할 콘텐츠 */\n children?: React.ReactNode;\n}\n\n// ── Icons ─────────────────────────────────────────────────────────────────────\n\nconst ChevronLeft = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M15 18L9 12L15 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nconst ChevronRight = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M9 18L15 12L9 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// ── Utility helpers ───────────────────────────────────────────────────────────\n\nconst getWeekdays = (locale: string): string[] => {\n const base = new Date(2023, 0, 1); // Sunday\n return Array.from({ length: 7 }, (_, i) => {\n const d = new Date(base);\n d.setDate(base.getDate() + i);\n return d.toLocaleDateString(locale, { weekday: \"short\" }).replace(/요일$/, \"\");\n });\n};\n\nconst getDaysInMonth = (year: number, month: number) =>\n new Date(year, month + 1, 0).getDate();\n\nconst getFirstDayOfMonth = (year: number, month: number) =>\n new Date(year, month, 1).getDay();\n\nconst isSameDay = (a: Date | string | number, b: Date | string | number) => {\n const da = toDate(a);\n const db = toDate(b);\n return (\n da.getFullYear() === db.getFullYear() &&\n da.getMonth() === db.getMonth() &&\n da.getDate() === db.getDate()\n );\n};\n\nconst toDate = (d: Date | string | number): Date =>\n d instanceof Date ? d : new Date(d);\n\nconst startOf = (d: Date | string | number) => {\n const dt = toDate(d);\n return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());\n};\n\ninterface DayItem {\n date: Date;\n isCurrentMonth: boolean;\n}\n\nconst buildDayGrid = (year: number, month: number, fixedWeeks = false): DayItem[] => {\n const grid: DayItem[] = [];\n const daysInMonth = getDaysInMonth(year, month);\n const firstDay = getFirstDayOfMonth(year, month);\n\n for (let i = 0; i < firstDay; i++) {\n grid.push({ date: new Date(year, month, -(firstDay - 1 - i)), isCurrentMonth: false });\n }\n for (let i = 1; i <= daysInMonth; i++) {\n grid.push({ date: new Date(year, month, i), isCurrentMonth: true });\n }\n const target = fixedWeeks ? 42 : grid.length + ((7 - (grid.length % 7)) % 7);\n let nextDay = 1;\n while (grid.length < target) {\n grid.push({ date: new Date(year, month + 1, nextDay++), isCurrentMonth: false });\n }\n return grid;\n};\n\n// ── Calendar Component ────────────────────────────────────────────────────────\n\n/** Calendar는 단독으로 사용하거나 DatePicker의 일부분으로 사용되는 달력 그리드입니다. */\nexport const Calendar: React.FC<CalendarProps> = ({\n year: yearProp,\n month: monthProp,\n locale = \"ko-KR\",\n selectedDate,\n startDate,\n endDate,\n hoverDate,\n rangeMode = false,\n minDate,\n maxDate,\n onClick,\n onHover,\n onPrev,\n onNext,\n showPrev = true,\n showNext = true,\n disablePrev = false,\n disableNext = false,\n fixedWeeks = false,\n className = \"\",\n style,\n children,\n}) => {\n const now = new Date();\n const year = yearProp ?? now.getFullYear();\n const month = monthProp ?? now.getMonth();\n\n const today = useMemo(() => startOf(new Date()), []);\n const days = useMemo(() => buildDayGrid(year, month, fixedWeeks), [year, month, fixedWeeks]);\n const weekdays = useMemo(() => getWeekdays(locale), [locale]);\n const monthLabel = `${year}. ${month + 1}`;\n\n const isDisabled = useCallback(\n (date: Date) => {\n const d = startOf(date);\n if (minDate && d < startOf(minDate)) return true;\n if (maxDate && d > startOf(maxDate)) return true;\n return false;\n },\n [minDate, maxDate]\n );\n\n // Range 경계값을 렌더당 한 번만 계산 (매 셀마다 startOf 반복 방지)\n const rangeS = rangeMode && startDate ? startOf(startDate) : null;\n const rangeE = rangeMode && endDate ? startOf(endDate) : null;\n const rangeH = rangeMode && hoverDate ? startOf(hoverDate) : null;\n\n const getDayClass = (item: DayItem) => {\n const d = startOf(item.date);\n const classes = [\"calendar-day\"];\n\n if (!item.isCurrentMonth) classes.push(\"calendar-day--outside\");\n if (isDisabled(item.date)) classes.push(\"calendar-day--disabled\");\n if (isSameDay(d, today)) classes.push(\"calendar-day--today\");\n\n // ── Single 모드 ──\n if (!rangeMode) {\n if (selectedDate && isSameDay(d, selectedDate)) {\n classes.push(\"calendar-day--selected\");\n }\n return classes.join(\" \");\n }\n\n // ── Range 모드 ──\n if (!rangeS) return classes.join(\" \");\n const s = rangeS;\n const e = rangeE;\n const h = rangeH;\n\n // Case 1: 시작 + 종료 모두 선택됨\n if (e) {\n const isStart = isSameDay(d, s);\n const isEnd = isSameDay(d, e);\n if (isStart) classes.push(\"calendar-day--range-start\");\n if (isEnd) classes.push(\"calendar-day--range-end\");\n if (!isStart && !isEnd && d > s && d < e) {\n classes.push(\"calendar-day--in-range\");\n }\n return classes.join(\" \");\n }\n\n // Case 2: 시작만 선택 + hover 중 (선택 범위 예고)\n if (h) {\n if (isSameDay(d, s)) {\n // hover 방향에 따라 start 셀의 반쪽 배경 방향을 맞춤\n if (h > s) classes.push(\"calendar-day--range-start\");\n else if (h < s) classes.push(\"calendar-day--range-end\");\n else classes.push(\"calendar-day--selected\");\n } else if (h > s ? d > s && d <= h : d < s && d >= h) {\n classes.push(\"calendar-day--in-range\");\n }\n return classes.join(\" \");\n }\n\n // Case 3: 시작만 선택 + hover 없음 — 원만 표시\n if (isSameDay(d, s)) {\n classes.push(\"calendar-day--selected\");\n }\n return classes.join(\" \");\n };\n\n return (\n <div className={`calendar ${className}`} style={style}>\n <div className=\"calendar-header\">\n {showPrev ? (\n <button type=\"button\" className=\"calendar-nav-btn\" disabled={disablePrev} onClick={onPrev} aria-label=\"이전 달\">\n <ChevronLeft />\n </button>\n ) : (\n <div className=\"calendar-nav-placeholder\" />\n )}\n <span className=\"calendar-month-label\">{monthLabel}</span>\n {showNext ? (\n <button type=\"button\" className=\"calendar-nav-btn\" disabled={disableNext} onClick={onNext} aria-label=\"다음 달\">\n <ChevronRight />\n </button>\n ) : (\n <div className=\"calendar-nav-placeholder\" />\n )}\n </div>\n\n {children}\n\n <div className=\"calendar-grid\" role=\"grid\" aria-label={monthLabel}>\n {weekdays.map((wd) => (\n <div key={wd} className=\"calendar-weekday\" role=\"columnheader\">\n {wd}\n </div>\n ))}\n {days.map((item, idx) => {\n const dayDisabled = isDisabled(item.date);\n return (\n <button\n key={idx}\n type=\"button\"\n className={getDayClass(item)}\n disabled={dayDisabled}\n onClick={() => onClick?.(item.date)}\n onMouseEnter={() => onHover?.(item.date)}\n onMouseLeave={() => onHover?.(null)}\n aria-selected={\n !rangeMode && selectedDate ? isSameDay(item.date, selectedDate) : undefined\n }\n tabIndex={dayDisabled ? -1 : 0}\n >\n {item.date.getDate()}\n </button>\n );\n })}\n </div>\n </div>\n );\n};\n\nCalendar.displayName = \"Calendar\";\n","import React, { useState, useCallback } from \"react\";\nimport \"./date-input.css\";\nimport { RiCalendar2Line } from \"@remixicon/react\";\nimport { ExclamationCircleIcon } from \"@heroicons/react/20/solid\";\nimport { TextField } from \"../TextField/TextField\";\nimport { Text } from \"../Typography/Typography\";\n\n// ── Icons ────────────────────────────────────────────────────────────────────\n\nconst CloseCircleIcon = () => (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M10 18C14.4183 18 18 14.4183 18 10C18 5.58172 14.4183 2 10 2C5.58172 2 2 5.58172 2 10C2 14.4183 5.58172 18 10 18Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12.5 7.5L7.5 12.5M7.5 7.5L12.5 12.5\"\n stroke=\"white\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type DateInputType = \"single\" | \"range\";\n/**\n * DateInput 내부 서브 요소 슬롯 이름.\n * classNames / styles 객체의 키로 사용됩니다.\n *\n * - `root` — 최상위 wrapper (`date-input`)\n * - `content` — 입력 영역\n * - `icon` — prefix 캘린더 아이콘 (range 모드에서만 사용)\n * - `text` — 날짜 텍스트 표시 영역 (range 모드에서만 사용)\n * - `separator` — range 모드 구분자 (`-`)\n * - `reset` — 초기화 버튼 (range 모드에서만 사용)\n */\nexport type DateInputSlot =\n | \"root\"\n | \"content\"\n | \"icon\"\n | \"text\"\n | \"separator\"\n | \"reset\";\n\nexport interface DateInputProps {\n /** 입력 타입: 단일 날짜 또는 기간 */\n type?: DateInputType;\n /** 비활성화 */\n disabled?: boolean;\n /** 에러 상태 */\n error?: boolean;\n /** 선택된 날짜 (single 모드) */\n value?: Date | null;\n /** 시작 날짜 (range 모드) */\n startDate?: Date | null;\n /** 종료 날짜 (range 모드) */\n endDate?: Date | null;\n /** prefix 아이콘 표시 여부 */\n prefixIcon?: boolean;\n /** 초기화 버튼 표시 여부 (single / range 모두 지원) */\n reset?: boolean;\n /** 도움말 텍스트 */\n description?: string;\n /** 날짜 표시 포맷 (locale) */\n locale?: string;\n /** 단일 모드 플레이스홀더 */\n placeholder?: string;\n /** 시작일 플레이스홀더 (range 모드) */\n startPlaceholder?: string;\n /** 종료일 플레이스홀더 (range 모드) */\n endPlaceholder?: string;\n /** 날짜 표시 포맷 (기본: \"yyyy. M. d\"). 예: \"yyyy.MM.dd HH:mm\" */\n dateFormat?: string;\n /**\n * 텍스트 입력으로 날짜를 직접 편집할 수 있는지 여부.\n * true이면 날짜 텍스트가 `<input>`으로 렌더링되어 타이핑 입력이 가능합니다.\n */\n editable?: boolean;\n /** 날짜 값 변경 콜백 (single 모드, editable 시 사용) */\n onValueChange?: (date: Date | null) => void;\n /** 시작일 변경 콜백 (range 모드, editable 시 사용) */\n onStartChange?: (date: Date | null) => void;\n /** 종료일 변경 콜백 (range 모드, editable 시 사용) */\n onEndChange?: (date: Date | null) => void;\n /** 클릭 핸들러 */\n onClick?: () => void;\n /** 초기화 클릭 핸들러 */\n onReset?: () => void;\n /** 추가 CSS 클래스 (classNames.root의 단축 표현) */\n className?: string;\n /** 인라인 스타일 (styles.root의 단축 표현) */\n style?: React.CSSProperties;\n\n /**\n * 각 서브 요소별 커스텀 CSS 클래스.\n * 기존 요소의 기본 className에 병합(추가)됩니다.\n */\n classNames?: Partial<Record<DateInputSlot, string>>;\n\n /**\n * 각 서브 요소별 인라인 스타일.\n * 해당 요소에 style 속성으로 적용됩니다.\n */\n styles?: Partial<Record<DateInputSlot, React.CSSProperties>>;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\n/**\n * Date를 포맷 문자열에 따라 변환합니다.\n * 지원 토큰: yyyy, MM, M, dd, d, HH, mm\n * format이 없으면 locale 기반 기본 포맷을 사용합니다.\n */\nexport const formatDate = (\n d: Date | null | undefined,\n format?: string,\n locale?: string,\n): string => {\n if (!d) return \"\";\n\n // 기본 포맷: \"yyyy. M. d\"\n if (!format) {\n return `${d.getFullYear()}. ${d.getMonth() + 1}. ${d.getDate()}`;\n }\n\n const y = d.getFullYear();\n const M = d.getMonth() + 1;\n const day = d.getDate();\n const H = d.getHours();\n const min = d.getMinutes();\n\n return format\n .replace(\"yyyy\", String(y))\n .replace(\"MM\", pad2(M))\n .replace(\"M\", String(M))\n .replace(\"dd\", pad2(day))\n .replace(\"d\", String(day))\n .replace(\"HH\", pad2(H))\n .replace(\"mm\", pad2(min));\n};\n\n/**\n * 날짜 문자열을 Date 객체로 파싱합니다.\n *\n * 지원 포맷:\n * - 구분자 포맷: \"2026.3.11\", \"2026-03-11\", \"2026/03/11\", \"2026. 3. 11\"\n * - 8자리 숫자: \"20260311\"\n * - 시간 포함: \"2026.03.11 14:30\", \"2026-03-11 09:00\"\n *\n * 파싱 실패 시 `fallback`을 반환합니다 (기본: null).\n */\nexport const parseDate = (\n str: string,\n fallback: Date | null = null,\n): Date | null => {\n if (!str || !str.trim()) return fallback;\n const trimmed = str.trim();\n\n let y: number | undefined;\n let m: number | undefined;\n let d: number | undefined;\n let hours = 0;\n let minutes = 0;\n\n // 1) 시간 포함: \"2026.03.11 14:30\", \"2026-03-11 09:00\" 등\n const dtMatch = trimmed.match(\n /^(\\d{4})\\s*[.\\-/]\\s*(\\d{1,2})\\s*[.\\-/]\\s*(\\d{1,2})\\s+(\\d{1,2}):(\\d{2})$/,\n );\n if (dtMatch) {\n y = Number(dtMatch[1]);\n m = Number(dtMatch[2]) - 1;\n d = Number(dtMatch[3]);\n hours = Number(dtMatch[4]);\n minutes = Number(dtMatch[5]);\n }\n\n // 2) 구분자 포맷: \"2026.3.11\", \"2026-03-11\", \"2026/03/11\"\n if (y === undefined) {\n const cleaned = trimmed.replace(/\\s+/g, \"\");\n const dateMatch = cleaned.match(/^(\\d{4})[.\\-/](\\d{1,2})[.\\-/](\\d{1,2})$/);\n if (dateMatch) {\n y = Number(dateMatch[1]);\n m = Number(dateMatch[2]) - 1;\n d = Number(dateMatch[3]);\n }\n }\n\n // 3) 8자리 숫자: \"20260311\"\n if (y === undefined) {\n const cleaned = trimmed.replace(/\\s+/g, \"\");\n const numMatch = cleaned.match(/^(\\d{4})(\\d{2})(\\d{2})$/);\n if (numMatch) {\n y = Number(numMatch[1]);\n m = Number(numMatch[2]) - 1;\n d = Number(numMatch[3]);\n }\n }\n\n if (y === undefined || m === undefined || d === undefined) return fallback;\n\n // 시/분 유효 범위 체크\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return fallback;\n\n const date = new Date(y, m, d, hours, minutes, 0, 0);\n if (\n !isNaN(date.getTime()) &&\n date.getFullYear() === y &&\n date.getMonth() === m &&\n date.getDate() === d\n ) {\n return date;\n }\n return fallback;\n};\n\n// ── Component ────────────────────────────────────────────────────────────────\n\n/** DateInput은 날짜를 표시하고 입력받는 필드 컴포넌트로, single/range 타입을 지원합니다. */\nexport const DateInput: React.FC<DateInputProps> = ({\n type = \"single\",\n disabled = false,\n error = false,\n value,\n startDate,\n endDate,\n prefixIcon = true,\n reset = false,\n description,\n locale = \"ko-KR\",\n placeholder = \"날짜 선택\",\n startPlaceholder = \"시작일\",\n endPlaceholder = \"종료일\",\n dateFormat,\n editable = false,\n onValueChange,\n onStartChange,\n onEndChange,\n onClick,\n onReset,\n className = \"\",\n style,\n classNames,\n styles,\n}) => {\n const isRange = type === \"range\";\n\n // ── Editable state ──\n const [editingField, setEditingField] = useState<\"value\" | \"start\" | \"end\" | null>(null);\n const [editText, setEditText] = useState(\"\");\n\n const handleEditFocus = useCallback(\n (field: \"value\" | \"start\" | \"end\", currentText: string) => {\n setEditingField(field);\n setEditText(currentText);\n },\n [],\n );\n\n const handleEditBlur = useCallback(\n (field: \"value\" | \"start\" | \"end\") => {\n const fallback =\n field === \"value\" ? (value ?? null) :\n field === \"start\" ? (startDate ?? null) :\n (endDate ?? null);\n const parsed = parseDate(editText, fallback);\n if (field === \"value\") onValueChange?.(parsed);\n else if (field === \"start\") onStartChange?.(parsed);\n else if (field === \"end\") onEndChange?.(parsed);\n setEditingField(null);\n },\n [editText, value, startDate, endDate, onValueChange, onStartChange, onEndChange],\n );\n\n const handleEditKeyDown = useCallback(\n (field: \"value\" | \"start\" | \"end\", e: React.KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleEditBlur(field);\n (e.target as HTMLInputElement).blur();\n }\n },\n [handleEditBlur],\n );\n\n const handleClick = () => {\n if (!disabled) onClick?.();\n };\n\n const handleResetClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n if (!disabled) onReset?.();\n };\n\n const wrapperCls = [\n \"date-input\",\n !isRange && \"date-input--single\",\n isRange && \"date-input--range\",\n className,\n classNames?.root,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const mergedRootStyle = style || styles?.root\n ? { ...style, ...styles?.root }\n : undefined;\n\n // ── Single mode → TextField ──\n if (!isRange) {\n const dateStr = formatDate(value, dateFormat, locale);\n\n return (\n <div className={wrapperCls} style={mergedRootStyle} onClick={handleClick}>\n <TextField\n type=\"input\"\n readOnly={!editable}\n value={editable && editingField === \"value\" ? editText : (dateStr || \"\")}\n placeholder={placeholder}\n prefixIcon={prefixIcon ? <RiCalendar2Line /> : undefined}\n suffixIcon={reset ? (\n <button\n type=\"button\"\n className=\"date-input__reset\"\n onClick={handleResetClick}\n disabled={disabled}\n aria-label=\"날짜 초기화\"\n >\n <CloseCircleIcon />\n </button>\n ) : undefined}\n error={error}\n description={description}\n accentIcon={!!error}\n disabled={disabled}\n className={classNames?.content}\n style={styles?.content}\n onFocus={editable ? () => handleEditFocus(\"value\", dateStr) : undefined}\n onChange={editable ? (e) => setEditText(e.target.value) : undefined}\n onBlur={editable ? () => handleEditBlur(\"value\") : undefined}\n />\n </div>\n );\n }\n\n // ── Range mode → custom ──\n const startStr = formatDate(startDate, dateFormat, locale);\n const endStr = formatDate(endDate, dateFormat, locale);\n const showStartPlaceholder = !startStr;\n const showEndPlaceholder = !endStr;\n\n const contentCls = [\n \"date-input__content\",\n \"date-input__content--range\",\n disabled && \"date-input__content--disabled\",\n error && \"date-input__content--error\",\n classNames?.content,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const helpVariant = error ? \"error\" : \"inform\";\n\n return (\n <div className={wrapperCls} style={mergedRootStyle}>\n <div className={contentCls} style={styles?.content} onClick={handleClick}>\n {prefixIcon && (\n <span\n className={`date-input__icon ${classNames?.icon ?? \"\"}`}\n style={styles?.icon}\n >\n <RiCalendar2Line />\n </span>\n )}\n {editable ? (\n <input\n type=\"text\"\n className={`date-input__editable ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n value={editingField === \"start\" ? editText : startStr}\n placeholder={startPlaceholder}\n onFocus={() => handleEditFocus(\"start\", startStr)}\n onChange={(e) => setEditText(e.target.value)}\n onBlur={() => handleEditBlur(\"start\")}\n onKeyDown={(e) => handleEditKeyDown(\"start\", e)}\n />\n ) : (\n <span\n className={`date-input__text ${showStartPlaceholder ? \"date-input__text--placeholder\" : \"\"} ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n >\n {startStr || startPlaceholder}\n </span>\n )}\n <span\n className={`date-input__separator ${classNames?.separator ?? \"\"}`}\n style={styles?.separator}\n >\n -\n </span>\n {editable ? (\n <input\n type=\"text\"\n className={`date-input__editable ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n value={editingField === \"end\" ? editText : endStr}\n placeholder={endPlaceholder}\n onFocus={() => handleEditFocus(\"end\", endStr)}\n onChange={(e) => setEditText(e.target.value)}\n onBlur={() => handleEditBlur(\"end\")}\n onKeyDown={(e) => handleEditKeyDown(\"end\", e)}\n />\n ) : (\n <span\n className={`date-input__text ${showEndPlaceholder ? \"date-input__text--placeholder\" : \"\"} ${classNames?.text ?? \"\"}`}\n style={styles?.text}\n >\n {endStr || endPlaceholder}\n </span>\n )}\n {reset && (\n <button\n type=\"button\"\n className={`date-input__reset ${classNames?.reset ?? \"\"}`}\n style={styles?.reset}\n onClick={handleResetClick}\n aria-label=\"날짜 초기화\"\n disabled={disabled}\n >\n <CloseCircleIcon />\n </button>\n )}\n </div>\n {description && (\n <span className={`help-text help-text--${helpVariant}`}>\n {error && (\n <span className=\"help-text__icon\">\n <ExclamationCircleIcon className=\"help-text__icon-svg\" />\n </span>\n )}\n <Text variant=\"body-p3\" className=\"help-text__content\">\n {description}\n </Text>\n </span>\n )}\n </div>\n );\n};\n\nDateInput.displayName = \"DateInput\";\n","import React, { useMemo, useRef, useEffect, useCallback } from \"react\";\nimport \"./time-picker.css\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface TimePickerProps {\n /** 현재 선택된 시간이 포함된 Date */\n selectedDate?: Date | null;\n /** 시간 선택 시 콜백 (시/분이 설정된 새 Date 반환) */\n onTimeChange?: (date: Date) => void;\n /** 시간 간격 (분 단위, 기본: 30) */\n timeIntervals?: number;\n /** 추가 CSS 클래스 */\n className?: string;\n /** 인라인 스타일 */\n style?: React.CSSProperties;\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\ninterface TimeSlot {\n hour: number;\n minute: number;\n label: string;\n}\n\nconst pad = (n: number): string => String(n).padStart(2, \"0\");\n\nconst buildTimeSlots = (intervals: number): TimeSlot[] => {\n const slots: TimeSlot[] = [];\n const totalMinutesInDay = 24 * 60;\n\n for (let m = 0; m < totalMinutesInDay; m += intervals) {\n const hour = Math.floor(m / 60);\n const minute = m % 60;\n slots.push({\n hour,\n minute,\n label: `${pad(hour)}:${pad(minute)}`,\n });\n }\n return slots;\n};\n\nconst isSameTime = (\n date: Date | null | undefined,\n hour: number,\n minute: number,\n): boolean => {\n if (!date) return false;\n return date.getHours() === hour && date.getMinutes() === minute;\n};\n\n// ── TimePicker Component ──────────────────────────────────────────────────────\n\n/** TimePicker는 세로 스크롤 리스트로 시간을 선택하는 컴포넌트입니다. */\nexport const TimePicker: React.FC<TimePickerProps> = ({\n selectedDate,\n onTimeChange,\n timeIntervals = 30,\n className = \"\",\n style,\n}) => {\n const listRef = useRef<HTMLDivElement>(null);\n const selectedRef = useRef<HTMLButtonElement>(null);\n\n const slots = useMemo(() => buildTimeSlots(timeIntervals), [timeIntervals]);\n\n // 선택된 시간으로 자동 스크롤\n useEffect(() => {\n if (selectedRef.current && listRef.current) {\n const list = listRef.current;\n const item = selectedRef.current;\n const listRect = list.getBoundingClientRect();\n const itemRect = item.getBoundingClientRect();\n\n // 아이템이 뷰포트 밖에 있을 때만 스크롤\n if (itemRect.top < listRect.top || itemRect.bottom > listRect.bottom) {\n list.scrollTop =\n item.offsetTop -\n list.offsetTop -\n list.clientHeight / 2 +\n item.clientHeight / 2;\n }\n }\n }, [selectedDate]);\n\n const handleTimeClick = useCallback(\n (hour: number, minute: number) => {\n const base = selectedDate ? new Date(selectedDate) : new Date();\n base.setHours(hour, minute, 0, 0);\n onTimeChange?.(new Date(base));\n },\n [selectedDate, onTimeChange],\n );\n\n return (\n <div className={`time-picker ${className}`} style={style}>\n <div className=\"time-picker__header\">시간</div>\n <div className=\"time-picker__list\" ref={listRef}>\n {slots.map((slot) => {\n const isSelected = isSameTime(selectedDate, slot.hour, slot.minute);\n return (\n <button\n key={slot.label}\n ref={isSelected ? selectedRef : undefined}\n type=\"button\"\n className={`time-picker__item ${isSelected ? \"time-picker__item--selected\" : \"\"}`}\n onClick={() => handleTimeClick(slot.hour, slot.minute)}\n >\n {slot.label}\n </button>\n );\n })}\n </div>\n </div>\n );\n};\n\nTimePicker.displayName = \"TimePicker\";\n","/**\n * 로고 SVG 에셋 - 번들에 포함되어 패키지 사용 시 별도 복사 불필요\n */\nimport likelionEngPrimary from \"../assets/logo/likelion-eng-primary.svg\";\nimport likelionEngBlack from \"../assets/logo/likelion-eng-black.svg\";\nimport likelionEngWhite from \"../assets/logo/likelion-eng-white.svg\";\nimport likelionKrPrimary from \"../assets/logo/likelion-kr-primary.svg\";\nimport likelionKrBlack from \"../assets/logo/likelion-kr-black.svg\";\nimport likelionKrWhite from \"../assets/logo/likelion-kr-white.svg\";\nimport bootcampPrimary from \"../assets/logo/bootcamp-primary.svg\";\nimport bootcampBlack from \"../assets/logo/bootcamp-black.svg\";\nimport bootcampWhite from \"../assets/logo/bootcamp-white.svg\";\nimport symbolPrimary from \"../assets/logo/symbol-primary.svg\";\nimport symbolBlack from \"../assets/logo/symbol-black.svg\";\nimport symbolWhite from \"../assets/logo/symbol-white.svg\";\nimport faviconPrimary from \"../assets/logo/favicon-primary.svg\";\nimport faviconBlack from \"../assets/logo/favicon-black.svg\";\n\nexport type LogoColor = \"primary\" | \"black\" | \"white\";\n\n/**\n * Next.js SVG import → { src: string, ... } 객체 또는 plain string.\n * 두 환경 모두 호환되도록 src 프로퍼티를 추출한다.\n */\nconst toUrl = (imported: string | { src: string }): string =>\n typeof imported === \"string\" ? imported : imported.src;\n\nexport const LOGO_URLS: Record<\n string,\n Record<LogoColor, string>\n> = {\n \"likelion-eng\": {\n primary: toUrl(likelionEngPrimary),\n black: toUrl(likelionEngBlack),\n white: toUrl(likelionEngWhite),\n },\n \"likelion-kr\": {\n primary: toUrl(likelionKrPrimary),\n black: toUrl(likelionKrBlack),\n white: toUrl(likelionKrWhite),\n },\n bootcamp: {\n primary: toUrl(bootcampPrimary),\n black: toUrl(bootcampBlack),\n white: toUrl(bootcampWhite),\n },\n symbol: {\n primary: toUrl(symbolPrimary),\n black: toUrl(symbolBlack),\n white: toUrl(symbolWhite),\n },\n favicon: {\n primary: toUrl(faviconPrimary),\n black: toUrl(faviconBlack),\n white: toUrl(faviconPrimary),\n },\n};\n","import React from \"react\";\nimport \"./logo.css\";\nimport { LOGO_URLS } from \"./logo-assets\";\n\nexport type LogoType =\n | \"likelion-eng\"\n | \"likelion-kr\"\n | \"bootcamp\"\n | \"symbol\"\n | \"favicon\"\n | \"og-image\";\n\nexport type LogoColor = \"primary\" | \"black\" | \"white\";\n\nexport type LogoSize = \"large\" | \"medium\" | \"small\" | \"favicon\" | \"og-image\";\n\nexport interface LogoProps extends React.HTMLAttributes<HTMLDivElement> {\n /** 로고 타입 */\n type?: LogoType;\n /** 로고 색상 */\n color?: LogoColor;\n /** 로고 크기 */\n size?: LogoSize;\n /** 서비스 타입 (og-image용) */\n service?: \"likelion\" | \"bootcamp\";\n}\n\nconst getLogoSrc = (type: LogoType, color: LogoColor) => {\n if (type in LOGO_URLS) {\n return LOGO_URLS[type][color];\n }\n return \"\";\n};\n\nconst LionIcon = ({ className: iconClassName }: { className?: string }) => (\n <img\n src={LOGO_URLS.symbol.white}\n alt=\"Lion Icon\"\n className={iconClassName}\n />\n);\n\n/**\n * Logo 컴포넌트는 브랜드 아이덴티티를 표현하는 로고 컴포넌트다.\n * `size` 외에 `className` 또는 `style`로 너비/높이를 직접 지정할 수 있다.\n */\nexport const Logo = ({\n type = \"likelion-kr\",\n color = \"primary\",\n size = \"medium\",\n service = \"likelion\",\n className = \"\",\n style,\n ...props\n}: LogoProps) => {\n const logoClasses = [\n \"logo\",\n `logo--${type}`,\n `logo--${color}`,\n `logo--${size}`,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const hasCustomSize = !!(className || style);\n const rootProps = hasCustomSize\n ? { ...props, className, style }\n : { ...props, className: `${logoClasses} ${className}`.trim(), style };\n\n const imgStyle = hasCustomSize\n ? { width: \"100%\", height: \"100%\", display: \"block\" as const, objectFit: \"contain\" as const }\n : { width: \"100%\", height: \"100%\", display: \"block\" as const };\n const innerStyle = hasCustomSize\n ? { width: \"100%\", height: \"100%\", display: \"flex\" as const, alignItems: \"center\", justifyContent: \"center\" }\n : undefined;\n\n const renderLogo = (content: React.ReactNode) => {\n if (hasCustomSize) {\n return (\n <div {...rootProps}>\n <div className={logoClasses} style={innerStyle}>\n {content}\n </div>\n </div>\n );\n }\n return <div {...rootProps}>{content}</div>;\n };\n\n // 멋쟁이사자처럼_ENG\n if (type === \"likelion-eng\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"likelion-eng\", color)}\n alt=\"멋쟁이사자처럼_ENG\"\n style={imgStyle}\n />\n );\n }\n\n // 멋쟁이사자처럼_KR\n if (type === \"likelion-kr\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"likelion-kr\", color)}\n alt=\"멋쟁이사자처럼_KR\"\n style={imgStyle}\n />\n );\n }\n\n // 멋사 부트캠프\n if (type === \"bootcamp\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"bootcamp\", color)}\n alt=\"멋사 부트캠프\"\n style={imgStyle}\n />\n );\n }\n\n const getText = () => null;\n\n // 심볼\n if (type === \"symbol\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"symbol\", color)}\n alt=\"심볼\"\n style={imgStyle}\n />\n );\n }\n\n // 파비콘\n if (type === \"favicon\") {\n return renderLogo(\n <img\n src={getLogoSrc(\"favicon\", color)}\n alt=\"파비콘\"\n style={imgStyle}\n />\n );\n }\n\n // OG 이미지\n if (type === \"og-image\") {\n const ogText = service === \"likelion\" ? \"멋쟁이사자처럼\" : \"멋사 부트캠프\";\n const ogLogoSrc =\n service === \"likelion\"\n ? getLogoSrc(\"likelion-kr\", \"white\")\n : getLogoSrc(\"bootcamp\", \"white\");\n const ogContent = (\n <div className=\"logo__og-container\">\n <img\n src={ogLogoSrc}\n alt={ogText}\n style={{ width: \"auto\", height: \"37.8px\", display: \"block\" }}\n />\n </div>\n );\n return hasCustomSize ? (\n <div {...rootProps}>\n <div className={logoClasses} style={innerStyle}>\n {ogContent}\n </div>\n </div>\n ) : (\n <div {...rootProps}>{ogContent}</div>\n );\n }\n\n const text = getText();\n const fallbackContent = (\n <>\n <div className=\"logo__icon\">\n <LionIcon />\n </div>\n {text && <span className=\"logo__text\">{text}</span>}\n </>\n );\n return hasCustomSize ? (\n <div {...rootProps}>\n <div className={logoClasses} style={innerStyle}>\n {fallbackContent}\n </div>\n </div>\n ) : (\n <div {...rootProps}>{fallbackContent}</div>\n );\n};\n\nLogo.displayName = \"Logo\";\n","// Screen Foundation - 브레이크포인트 관련 유틸리티 export\nexport { useBreakpoint, useMediaQuery, BreakpointProvider } from \"../../shared/hooks/useMediaQuery\";\n\n// 브레이크포인트 상수 (기본 - Mobile/Tablet/Desktop)\nexport const BREAKPOINTS = {\n mobile: {\n min: 375,\n max: 743,\n },\n tablet: {\n min: 744,\n max: 1279,\n },\n desktop: {\n min: 1280,\n },\n} as const;\n\n// Tailwind Screens 설정 - 주요 브레이크포인트 (mo, tb, pc)\nexport const TAILWIND_SCREENS = {\n mo: \"375px\", // Mobile\n tb: \"744px\", // Tablet\n pc: \"1280px\", // Desktop\n} as const;\n\n// 미디어 쿼리 문자열\nexport const MEDIA_QUERIES = {\n mobile: \"(min-width: 375px) and (max-width: 743px)\",\n tablet: \"(min-width: 744px) and (max-width: 1279px)\",\n desktop: \"(min-width: 1280px)\",\n underTablet: \"(max-width: 743px)\",\n} as const;\n\n// 레이아웃 시스템 (Margin, Column, Gutter)\nexport const LAYOUT_SYSTEM = {\n mobile: {\n margin: 16, // 화면 가장자리 여백\n column: 4, // 컬럼 수\n gutter: 16, // 컬럼 사이 간격\n },\n tablet: {\n margin: 24,\n column: 8,\n gutter: 24,\n },\n desktop: {\n margin: 24,\n column: 12,\n gutter: 24,\n },\n} as const;\n","import React from \"react\";\nimport { DialogProvider } from \"./Dialog\";\nimport { ToastProvider } from \"./Toast\";\n\n/**\n * LIKELION Design System 통합 Provider\n * DialogProvider + ToastProvider를 하나로 감싸줍니다.\n */\nexport const LDSProvider = ({ children }: { children: React.ReactNode }) => {\n return (\n <DialogProvider>\n <ToastProvider>{children}</ToastProvider>\n </DialogProvider>\n );\n};\n"],"mappings":"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","names":["React","React","Text","React","_a","ref","_b","variant","decoration","as","children","className","props","__objRest","defaultTag","level","Tag","baseClasses","__spreadValues","jsx","jsxs","ensureTextAsSpan","node","React","Text","_a","children","rest","__objRest","__spreadProps","__spreadValues","ActionButton","ref","_b","size","color","type","htmlType","label","prefixIcon","suffixIcon","loading","className","disabled","props","isDisabled","isLoading","baseClasses","textVariant","React","jsx","IconButton","React","_a","ref","_b","size","color","type","icon","className","disabled","htmlType","propsStyle","styles","props","__objRest","isWeakType","colorClass","typeClass","baseClasses","shouldHide","__spreadProps","__spreadValues","React","useState","forwardRef","React","jsx","Badge","React","_a","ref","_b","type","variant","value","maxValue","className","props","__objRest","baseClasses","displayValue","__spreadProps","__spreadValues","Text","jsx","jsxs","Tab","forwardRef","_a","ref","_b","type","size","badge","label","mode","className","selected","disabled","onClick","props","__objRest","internalPressed","setInternalPressed","useState","isControlled","isPressed","handleClick","e","prev","state","baseClasses","__spreadProps","__spreadValues","Badge","TabGroup","valueProp","defaultValue","onChange","items","children","gap","style","internalValue","setInternalValue","React","value","groupStyle","handleTabClick","tabValue","originalOnClick","renderedTabs","item","isSelected","child","_c","React","React","CheckIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","CheckIcon_default","React","XMarkIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","XMarkIcon_default","jsx","jsxs","ChipComponent","React","_a","ref","_b","type","size","variant","value","onChange","checkedProp","defaultChecked","selectedValue","selectedValues","label","prefixIcon","suffixIcon","showCheck","showClose","onClose","className","disabled","onClick","props","__objRest","internalChecked","setInternalChecked","isControlled","checked","shouldRenderCheckIcon","displayLeftIcon","CheckIcon_default","hasPrefix","hasSuffix","paddingClass","baseClasses","handleClick","e","prev","handleClose","__spreadProps","__spreadValues","Text","ChipGroup","valueProp","defaultValue","multiple","items","children","rest","internalValue","setInternalValue","handleChange","chipValue","arr","next","v","renderedChips","item","child","_c","_d","Chip","React","createPortal","createContext","useContext","useSyncExternalStore","BreakpointContext","BreakpointProvider","useMediaQuery","query","callback","matchMedia","useBreakpoint","_a","_b","_c","_d","contextValue","isMobileQuery","isTabletQuery","isDesktopQuery","isUnderTabletQuery","Fragment","jsx","jsxs","DialogContext","React","DialogRoot","_a","_b","open","onClose","closeOnOverlayClick","closeOnEsc","withClose","variant","align","title","description","icon","actionItems","footerLayout","width","className","children","props","__objRest","isUnderTablet","useBreakpoint","mounted","setMounted","originalStyle","handleKeyDown","e","resolvedAlign","baseClasses","handleOverlayClick","contentNode","DialogHeader","DialogBody","DialogFooter","item","idx","DialogButton","dialogOverlay","__spreadProps","__spreadValues","XMarkIcon_default","createPortal","Text","layout","layoutClass","label","color","type","size","prefixIcon","suffixIcon","loading","disabled","onClick","closeOnClick","style","context","buttonWidth","defaultSize","defaultType","defaultColor","handleClick","ActionButton","Dialog","GlobalDialogContext","DialogProvider","dialogs","setDialogs","close","id","prev","d","closeAll","options","alert","resolve","confirm","_c","dialog","useDialog","React","jsx","jsxs","Toggle","React","_a","ref","_b","size","label","labelPosition","description","checkedProp","defaultChecked","onChange","disabled","className","id","props","__objRest","inputRef","combinedRef","node","internalChecked","setInternalChecked","isControlled","checked","handleChange","e","generatedId","toggleId","descriptionId","baseClasses","__spreadValues","Text","React","RiCheckboxBlankLine","RiCheckboxFill","RiCheckboxIndeterminateFill","jsx","jsxs","Checkbox","React","_a","ref","_b","label","labelProps","description","value","checkedProp","defaultChecked","onChange","disabled","indeterminate","className","id","props","__objRest","inputRef","combinedRef","node","internalChecked","setInternalChecked","isControlled","checked","handleChange","e","generatedId","checkboxId","descriptionId","baseClasses","resolvedLabelProps","labelClassName","__spreadValues","RiCheckboxIndeterminateFill","RiCheckboxFill","RiCheckboxBlankLine","Text","__spreadProps","CheckboxGroup","descriptionProps","multiple","valueProp","defaultValue","items","children","_c","_d","internalValue","setInternalValue","checkboxValue","newValue","v","groupId","resolvedGroupLabelProps","resolvedGroupDescriptionProps","groupLabelClassName","groupDescriptionClassName","renderedContent","item","child","isChecked","React","useCheckboxGroup","config","options","defaultValue","valueProp","onChangeProp","internalValue","setInternalValue","isControlled","value","onChange","newValue","allSelected","someSelected","selectAllChecked","selectAllIndeterminate","handleSelectAll","e","React","useState","useId","forwardRef","React","ExclamationCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","ExclamationCircleIcon_default","Fragment","jsx","jsxs","isAreaType","props","TextField","forwardRef","ref","_a","type","required","size","error","description","width","maxLength","showCountProp","title","accentIcon","className","style","id","value","defaultValue","readOnly","disabled","onChange","onFocus","onBlur","restProps","__objRest","generatedId","useId","fieldId","focused","setFocused","useState","effectiveSize","isControlled","internalValue","setInternalValue","currentValue","inputState","count","showCount","countValue","countTotal","iconNode","ExclamationCircleIcon_default","helpVariant","isArea","handleFocus","e","handleBlur","handleChange","next","fieldClasses","shellClasses","getShellAreaStyle","areaProps","excludeKeys","nativeProps","k","__spreadValues","Text","isInputType","__spreadProps","React","RiCheckboxCircleFill","jsx","jsxs","SelectMenu","React","props","ref","_a","items","size","value","defaultValue","onChange","multiple","itemTextProps","suffixIcon","maxRows","className","style","id","rest","__objRest","isControlled","internalValue","setInternalValue","currentValue","isMultiple","isUnderTablet","useBreakpoint","resolvedSize","generatedId","menuId","commitValue","next","newValue","prevArray","v","baseClasses","resolvedItemTextProps","defaultVariant","menuRef","computedMaxHeight","setComputedMaxHeight","el","firstItem","itemHeight","menuStyle","gap","paddingY","__spreadProps","__spreadValues","node","item","idx","_b","isSelected","optionId","defaultSuffix","RiCheckboxCircleFill","suffixNode","Text","SelectMenuOverlay","children","openProp","defaultOpen","onOpenChange","menuContainerStyle","menuProps","internalOpen","setInternalOpen","open","wrapperRef","setOpen","handleClickOutside","event","handleToggle","triggerNode","originalOnClick","handleChange","RiArrowUpSLine","jsx","jsxs","SelectHeader","type","title","required","valueProp","placeholder","disabled","readOnly","error","description","accentIcon","onClick","onClear","prefixIcon","icon","className","id","items","defaultValue","onChange","multiple","showClear","wrapperClassName","wrapperStyle","width","size","menuItemTextProps","menuSuffixIcon","menuClassName","menuStyle","menuMaxRows","internalValue","setInternalValue","React","isSelectMode","isControlled","currentValueForSelect","handleSelectChange","next","displayValue","_a","v","value","_b","i","found","showClearButton","handleClear","e","suffixContent","XMarkIcon_default","textFieldNode","TextField","SelectMenuOverlay","React","CheckCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","CheckCircleIcon_default","React","ExclamationTriangleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","ExclamationTriangleIcon_default","React","InformationCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","InformationCircleIcon_default","React","XCircleIcon","_a","svgRef","_b","title","titleId","props","__objRest","ForwardRef","XCircleIcon_default","jsx","jsxs","LoadingSpinner","SelectBox","_a","_b","size","disabled","readOnly","error","success","loading","label","required","placeholder","items","value","defaultValue","onChange","multiple","description","prefixIcon","className","style","classNames","styles","width","headerType","onClear","showClear","wrapperStyle","onClick","id","itemTextProps","suffixIcon","maxRows","restHeaderProps","__objRest","isDisabled","isInteractive","showLabel","resolvedWidth","iconNode","rootStyle","merged","__spreadValues","baseClasses","resolvedPrefixIcon","selectedValue","i","descriptionIcon","CheckCircleIcon_default","ExclamationCircleIcon_default","helpVariant","SelectHeader","__spreadProps","Text","React","RiArrowLeftSLine","RiArrowRightSLine","RiMoreLine","Fragment","jsx","jsxs","range","start","end","length","_","idx","createPaginationItems","totalPages","currentPage","siblingCount","showEdgeButtons","showPrevNext","safeCurrent","items","add","item","isFirstPage","isLastPage","totalPageNumbers","page","leftSiblingIndex","rightSiblingIndex","shouldShowLeftEllipsis","shouldShowRightEllipsis","leftItemCount","rightItemCount","createBasicPaginationItems","Pagination","_a","_b","onChange","type","className","rest","__objRest","size","variant","React","handleItemClick","handleEllipsisClick","key","rootClasses","__spreadProps","__spreadValues","isPage","isSelected","isDisabled","itemClasses","labelText","ariaLabel","RiMoreLine","RiArrowLeftSLine","RiArrowRightSLine","Text","React","RiCircleLine","RiRadioButtonLine","jsx","jsxs","RadioButton","React","_a","ref","_b","label","labelProps","description","value","checkedProp","defaultChecked","onChange","disabled","className","id","name","onClick","props","__objRest","internalChecked","setInternalChecked","isControlled","checked","handleChange","e","handleClick","syntheticEvent","__spreadProps","__spreadValues","generatedId","radioId","descriptionId","isHovered","setIsHovered","baseClasses","labelWrapperClasses","resolvedLabelProps","labelClassName","RiRadioButtonLine","RiCircleLine","Text","RadioButtonGroup","descriptionProps","valueProp","defaultValue","items","children","_c","_d","internalValue","setInternalValue","groupId","groupName","resolvedGroupLabelProps","resolvedGroupDescriptionProps","groupLabelClassName","groupDescriptionClassName","handleRadioChange","radioValue","renderedContent","item","child","isChecked","React","jsx","jsxs","Tag","React","_a","ref","_b","type","size","state","label","prefixIcon","suffixIcon","className","props","__objRest","effectiveState","resolvedClassName","textVariant","__spreadProps","__spreadValues","Text","useState","useRef","useEffect","useCallback","useLayoutEffect","ReactDOM","jsx","jsxs","calcPosition","trigger","tooltip","direction","offset","vw","vh","parts","side","alignment","finalSide","top","left","finalDirection","Tooltip","label","type","prefixIcon","onClose","withArrow","openedProp","defaultOpened","disabled","width","withinPortal","openDelay","closeDelay","children","className","opened","setOpened","useState","wrapperRef","useRef","tooltipRef","openTimeoutRef","closeTimeoutRef","isControlled","isOpened","portalPos","setPortalPos","useEffect","handleMouseEnter","handleMouseLeave","handleFocus","handleBlur","handleCloseClick","e","updatePosition","useCallback","triggerRect","tooltipRect","result","useLayoutEffect","rafId","onUpdate","displayDirection","tooltipContent","__spreadValues","Text","renderedTooltip","ReactDOM","React","createPortal","Fragment","jsx","jsxs","Toast","props","_a","sizeProp","state","label","icon","position","horizontalAlign","topOffset","bottomOffset","horizontalPadding","className","style","rest","__objRest","isUnderTablet","useBreakpoint","size","baseClasses","defaultTopOffset","defaultBottomOffset","defaultHorizontalPadding","hasCustomPosition","positionStyles","__spreadValues","padding","defaultIcon","XCircleIcon_default","ExclamationTriangleIcon_default","CheckCircleIcon_default","InformationCircleIcon_default","__spreadProps","Text","TOAST_EXIT_MS","ToastContext","React","ToastProvider","children","toasts","setToasts","mounted","setMounted","showToast","message","options","id","duration","newToast","prev","t","toast","hideToast","createPortal","useToast","context","useState","useCallback","useRef","useEffect","useMemo","useMemo","useCallback","jsx","jsxs","ChevronLeft","ChevronRight","getWeekdays","locale","base","_","i","d","getDaysInMonth","year","month","getFirstDayOfMonth","isSameDay","a","b","da","toDate","db","startOf","dt","buildDayGrid","fixedWeeks","grid","daysInMonth","firstDay","target","nextDay","Calendar","yearProp","monthProp","selectedDate","startDate","endDate","hoverDate","rangeMode","minDate","maxDate","onClick","onHover","onPrev","onNext","showPrev","showNext","disablePrev","disableNext","className","style","children","now","today","useMemo","days","weekdays","monthLabel","isDisabled","useCallback","date","rangeS","rangeE","rangeH","getDayClass","item","classes","s","e","h","isStart","isEnd","wd","idx","dayDisabled","useState","useCallback","RiCalendar2Line","jsx","jsxs","CloseCircleIcon","pad2","n","formatDate","d","format","locale","y","M","day","H","min","parseDate","str","fallback","trimmed","m","hours","minutes","dtMatch","dateMatch","numMatch","date","DateInput","type","disabled","error","value","startDate","endDate","prefixIcon","reset","description","placeholder","startPlaceholder","endPlaceholder","dateFormat","editable","onValueChange","onStartChange","onEndChange","onClick","onReset","className","style","classNames","styles","_a","_b","_c","_d","_e","_f","_g","isRange","editingField","setEditingField","useState","editText","setEditText","handleEditFocus","useCallback","field","currentText","handleEditBlur","parsed","handleEditKeyDown","e","handleClick","handleResetClick","wrapperCls","mergedRootStyle","__spreadValues","dateStr","TextField","RiCalendar2Line","startStr","endStr","showStartPlaceholder","showEndPlaceholder","contentCls","helpVariant","ExclamationCircleIcon_default","Text","useMemo","useRef","useEffect","useCallback","jsx","jsxs","pad","n","buildTimeSlots","intervals","slots","m","hour","minute","isSameTime","date","TimePicker","selectedDate","onTimeChange","timeIntervals","className","style","listRef","useRef","selectedRef","useMemo","useEffect","list","item","listRect","itemRect","handleTimeClick","useCallback","base","slot","isSelected","Fragment","jsx","jsxs","toDate","d","startOf","dt","I18N","getI18n","locale","_a","DatePicker","props","_b","_c","_d","_e","_f","type","disabled","readOnly","error","description","minDate","maxDate","className","placeholder","showPrev","showNext","disablePrev","disableNext","resetProp","defaultMonth","showTimeSelect","timeIntervals","dateFormatProp","onResetProp","onApplyProp","onCancelProp","classNames","styles","calendarProps","dateInputProps","i18n","isMobile","useBreakpoint","isRange","isTimeEnabled","effectiveDateFormat","singleValue","singleOnChange","extStartDate","extEndDate","onRangeChange","isOpen","setIsOpen","useState","rawCurrentMonth","setCurrentMonth","now","currentMonth","useMemo","hoverDate","setHoverDate","internalStart","setInternalStart","internalEnd","setInternalEnd","internalSingle","setInternalSingle","committedSingle","setCommittedSingle","committedStart","setCommittedStart","committedEnd","setCommittedEnd","isEditingSingleField","setIsEditingSingleField","singleFieldText","setSingleFieldText","handleSingleFieldFocus","useCallback","formatDate","handleSingleFieldBlur","parsed","parseDate","handleSingleFieldKeyDown","e","containerRef","useRef","useEffect","handleClickOutside","event","year","month","handlePrev","handleNext","autoDisablePrev","autoDisableNext","handleSingleDayClick","date","newDate","handleTimeChange","handleRangeDayClick","s","handleTodayClick","today","handleCancel","handleApply","dragY","setDragY","dragStartRef","handleDragStart","handleDragMove","dy","handleDragEnd","overlayRef","sheetRef","overlay","sheet","prevent","handleKeyDown","openAbove","setOpenAbove","calcOpenDirection","rect","popoverHeight","spaceBelow","spaceAbove","handleReset","isApplyDisabled","helpVariant","DateInput","__spreadProps","__spreadValues","Calendar","ActionButton","TimePicker","ExclamationCircleIcon_default","Text","toUrl","imported","LOGO_URLS","likelion_eng_primary_default","likelion_eng_black_default","likelion_eng_white_default","likelion_kr_primary_default","likelion_kr_black_default","likelion_kr_white_default","bootcamp_primary_default","bootcamp_black_default","bootcamp_white_default","symbol_primary_default","symbol_black_default","symbol_white_default","favicon_primary_default","favicon_black_default","Fragment","jsx","jsxs","getLogoSrc","type","color","LOGO_URLS","LionIcon","iconClassName","Logo","_a","_b","size","service","className","style","props","__objRest","logoClasses","hasCustomSize","rootProps","__spreadProps","__spreadValues","imgStyle","innerStyle","renderLogo","content","getText","ogText","ogLogoSrc","ogContent","text","fallbackContent","BREAKPOINTS","TAILWIND_SCREENS","MEDIA_QUERIES","LAYOUT_SYSTEM","jsx","LDSProvider","children","DialogProvider","ToastProvider"]}
|