@combinedk/ui 3.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/index.cjs +1 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +19 -0
  4. package/dist/index10.cjs +2 -0
  5. package/dist/index10.cjs.map +1 -0
  6. package/dist/index10.js +289 -0
  7. package/dist/index10.js.map +1 -0
  8. package/dist/index11.cjs +2 -0
  9. package/dist/index11.cjs.map +1 -0
  10. package/dist/index11.js +52 -0
  11. package/dist/index11.js.map +1 -0
  12. package/dist/index12.cjs +2 -0
  13. package/dist/index12.cjs.map +1 -0
  14. package/dist/index12.js +133 -0
  15. package/dist/index12.js.map +1 -0
  16. package/dist/index13.cjs +2 -0
  17. package/dist/index13.cjs.map +1 -0
  18. package/dist/index13.js +150 -0
  19. package/dist/index13.js.map +1 -0
  20. package/dist/index14.cjs +2 -0
  21. package/dist/index14.cjs.map +1 -0
  22. package/dist/index14.js +100 -0
  23. package/dist/index14.js.map +1 -0
  24. package/dist/index15.cjs +2 -0
  25. package/dist/index15.cjs.map +1 -0
  26. package/dist/index15.js +35 -0
  27. package/dist/index15.js.map +1 -0
  28. package/dist/index16.cjs +2 -0
  29. package/dist/index16.cjs.map +1 -0
  30. package/dist/index16.js +330 -0
  31. package/dist/index16.js.map +1 -0
  32. package/dist/index17.cjs +2 -0
  33. package/dist/index17.cjs.map +1 -0
  34. package/dist/index17.js +114 -0
  35. package/dist/index17.js.map +1 -0
  36. package/dist/index18.cjs +2 -0
  37. package/dist/index18.cjs.map +1 -0
  38. package/dist/index18.js +110 -0
  39. package/dist/index18.js.map +1 -0
  40. package/dist/index19.cjs +2 -0
  41. package/dist/index19.cjs.map +1 -0
  42. package/dist/index19.js +24 -0
  43. package/dist/index19.js.map +1 -0
  44. package/dist/index2.cjs +2 -0
  45. package/dist/index2.cjs.map +1 -0
  46. package/dist/index2.js +90 -0
  47. package/dist/index2.js.map +1 -0
  48. package/dist/index3.cjs +2 -0
  49. package/dist/index3.cjs.map +1 -0
  50. package/dist/index3.js +71 -0
  51. package/dist/index3.js.map +1 -0
  52. package/dist/index4.cjs +2 -0
  53. package/dist/index4.cjs.map +1 -0
  54. package/dist/index4.js +32 -0
  55. package/dist/index4.js.map +1 -0
  56. package/dist/index5.cjs +2 -0
  57. package/dist/index5.cjs.map +1 -0
  58. package/dist/index5.js +27 -0
  59. package/dist/index5.js.map +1 -0
  60. package/dist/index6.cjs +2 -0
  61. package/dist/index6.cjs.map +1 -0
  62. package/dist/index6.js +23 -0
  63. package/dist/index6.js.map +1 -0
  64. package/dist/index7.cjs +2 -0
  65. package/dist/index7.cjs.map +1 -0
  66. package/dist/index7.js +82 -0
  67. package/dist/index7.js.map +1 -0
  68. package/dist/index8.cjs +2 -0
  69. package/dist/index8.cjs.map +1 -0
  70. package/dist/index8.js +93 -0
  71. package/dist/index8.js.map +1 -0
  72. package/dist/index9.cjs +2 -0
  73. package/dist/index9.cjs.map +1 -0
  74. package/dist/index9.js +99 -0
  75. package/dist/index9.js.map +1 -0
  76. package/dist/src/components/Badge.d.ts +9 -0
  77. package/dist/src/components/Button.d.ts +11 -0
  78. package/dist/src/components/Card.d.ts +9 -0
  79. package/dist/src/components/Checkbox.d.ts +22 -0
  80. package/dist/src/components/ConfirmDialog.d.ts +13 -0
  81. package/dist/src/components/DropdownMenu.d.ts +24 -0
  82. package/dist/src/components/EmptyState.d.ts +9 -0
  83. package/dist/src/components/Field.d.ts +24 -0
  84. package/dist/src/components/Input.d.ts +9 -0
  85. package/dist/src/components/Modal.d.ts +12 -0
  86. package/dist/src/components/PageHeader.d.ts +11 -0
  87. package/dist/src/components/PreviewBadge.d.ts +8 -0
  88. package/dist/src/components/Select.d.ts +32 -0
  89. package/dist/src/components/Skeleton.d.ts +21 -0
  90. package/dist/src/components/StatusPill.d.ts +7 -0
  91. package/dist/src/components/Table.d.ts +26 -0
  92. package/dist/src/components/Tag.d.ts +5 -0
  93. package/dist/src/components/Toast.d.ts +13 -0
  94. package/dist/src/index.d.ts +21 -0
  95. package/package.json +43 -0
  96. package/src/tokens.css +151 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index12.js","names":[],"sources":["../src/components/Skeleton.tsx"],"sourcesContent":["import type { CSSProperties } from 'react'\n\ninterface SkeletonProps {\n width?: number | string\n height?: number | string\n radius?: number | string\n style?: CSSProperties\n}\n\nexport function Skeleton({ width = '100%', height = 12, radius = 4, style }: SkeletonProps) {\n return (\n <span style={{\n display: 'inline-block',\n width,\n height,\n borderRadius: radius,\n background: 'linear-gradient(90deg, var(--color-neutral-100) 0%, #f9f4f3 50%, var(--color-neutral-100) 100%)',\n backgroundSize: '200% 100%',\n animation: 'skelShimmer 1.4s ease-in-out infinite',\n flexShrink: 0,\n ...style,\n }} />\n )\n}\n\n// ── Pre-built skeleton shapes ──────────────────────────────────────────────\n\nexport function SkeletonTableRow({ cols = 4 }: { cols?: number }) {\n const widths = ['60%', '45%', '30%', '20%', '50%', '35%']\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '11px 14px', borderBottom: '1px solid var(--color-neutral-100)' }}>\n {Array.from({ length: cols }, (_, i) => (\n <div key={i} style={{ flex: i === 0 ? '1.5' : '1' }}>\n <Skeleton width={widths[i % widths.length]} height={10} />\n </div>\n ))}\n </div>\n )\n}\n\nexport function SkeletonTable({ rows = 5, cols = 4 }: { rows?: number; cols?: number }) {\n return (\n <div style={{ border: '1px solid var(--c-border)', borderRadius: 10, overflow: 'hidden' }}>\n {/* Header */}\n <div style={{ display: 'flex', gap: 16, padding: '10px 14px', background: 'var(--c-elevated)', borderBottom: '1px solid var(--c-border)' }}>\n {Array.from({ length: cols }, (_, i) => (\n <div key={i} style={{ flex: i === 0 ? '1.5' : '1' }}>\n <Skeleton width=\"50%\" height={8} />\n </div>\n ))}\n </div>\n {Array.from({ length: rows }, (_, i) => (\n <SkeletonTableRow key={i} cols={cols} />\n ))}\n </div>\n )\n}\n\nexport function SkeletonText({ lines = 3, lastWidth = '60%' }: { lines?: number; lastWidth?: string }) {\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {Array.from({ length: lines }, (_, i) => (\n <Skeleton key={i} width={i === lines - 1 ? lastWidth : '100%'} height={10} />\n ))}\n </div>\n )\n}\n\nexport function SkeletonCard() {\n return (\n <div style={{ background: 'var(--c-surface)', border: '1px solid var(--c-border)', borderRadius: 'var(--radius-lg)', padding: 20, display: 'flex', flexDirection: 'column', gap: 12 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>\n <Skeleton width={32} height={32} radius={8} />\n <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 6 }}>\n <Skeleton width=\"50%\" height={11} />\n <Skeleton width=\"30%\" height={9} />\n </div>\n <Skeleton width={54} height={20} radius={999} />\n </div>\n <SkeletonText lines={2} lastWidth=\"70%\" />\n </div>\n )\n}\n"],"mappings":";;AASA,SAAgB,EAAS,EAAE,WAAQ,QAAQ,YAAS,IAAI,YAAS,GAAG,YAAwB;AAC1F,QACE,kBAAC,QAAD,EAAM,OAAO;EACX,SAAiB;EACjB;EACA;EACA,cAAiB;EACjB,YAAiB;EACjB,gBAAiB;EACjB,WAAiB;EACjB,YAAiB;EACjB,GAAG;EACJ,EAAI,CAAA;;AAMT,SAAgB,EAAiB,EAAE,UAAO,KAAwB;CAChE,IAAM,IAAS;EAAC;EAAO;EAAO;EAAO;EAAO;EAAO;EAAM;AACzD,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,SAAS;GAAQ,YAAY;GAAU,KAAK;GAAI,SAAS;GAAa,cAAc;GAAsC;YACrI,MAAM,KAAK,EAAE,QAAQ,GAAM,GAAG,GAAG,MAChC,kBAAC,OAAD;GAAa,OAAO,EAAE,MAAM,MAAM,IAAI,QAAQ,KAAK;aACjD,kBAAC,GAAD;IAAU,OAAO,EAAO,IAAI,EAAO;IAAS,QAAQ;IAAM,CAAA;GACtD,EAFI,EAEJ,CACN;EACE,CAAA;;AAIV,SAAgB,EAAc,EAAE,UAAO,GAAG,UAAO,KAAuC;AACtF,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,QAAQ;GAA6B,cAAc;GAAI,UAAU;GAAU;YAAzF,CAEE,kBAAC,OAAD;GAAK,OAAO;IAAE,SAAS;IAAQ,KAAK;IAAI,SAAS;IAAa,YAAY;IAAqB,cAAc;IAA6B;aACvI,MAAM,KAAK,EAAE,QAAQ,GAAM,GAAG,GAAG,MAChC,kBAAC,OAAD;IAAa,OAAO,EAAE,MAAM,MAAM,IAAI,QAAQ,KAAK;cACjD,kBAAC,GAAD;KAAU,OAAM;KAAM,QAAQ;KAAK,CAAA;IAC/B,EAFI,EAEJ,CACN;GACE,CAAA,EACL,MAAM,KAAK,EAAE,QAAQ,GAAM,GAAG,GAAG,MAChC,kBAAC,GAAD,EAAgC,SAAQ,EAAjB,EAAiB,CACxC,CACE;;;AAIV,SAAgB,EAAa,EAAE,WAAQ,GAAG,eAAY,SAAiD;AACrG,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,SAAS;GAAQ,eAAe;GAAU,KAAK;GAAG;YAC7D,MAAM,KAAK,EAAE,QAAQ,GAAO,GAAG,GAAG,MACjC,kBAAC,GAAD;GAAkB,OAAO,MAAM,IAAQ,IAAI,IAAY;GAAQ,QAAQ;GAAM,EAA9D,EAA8D,CAC7E;EACE,CAAA;;AAIV,SAAgB,IAAe;AAC7B,QACE,kBAAC,OAAD;EAAK,OAAO;GAAE,YAAY;GAAoB,QAAQ;GAA6B,cAAc;GAAoB,SAAS;GAAI,SAAS;GAAQ,eAAe;GAAU,KAAK;GAAI;YAArL,CACE,kBAAC,OAAD;GAAK,OAAO;IAAE,SAAS;IAAQ,YAAY;IAAU,KAAK;IAAI;aAA9D;IACE,kBAAC,GAAD;KAAU,OAAO;KAAI,QAAQ;KAAI,QAAQ;KAAK,CAAA;IAC9C,kBAAC,OAAD;KAAK,OAAO;MAAE,MAAM;MAAG,SAAS;MAAQ,eAAe;MAAU,KAAK;MAAG;eAAzE,CACE,kBAAC,GAAD;MAAU,OAAM;MAAM,QAAQ;MAAM,CAAA,EACpC,kBAAC,GAAD;MAAU,OAAM;MAAM,QAAQ;MAAK,CAAA,CAC/B;;IACN,kBAAC,GAAD;KAAU,OAAO;KAAI,QAAQ;KAAI,QAAQ;KAAO,CAAA;IAC5C;MACN,kBAAC,GAAD;GAAc,OAAO;GAAG,WAAU;GAAQ,CAAA,CACtC"}
@@ -0,0 +1,2 @@
1
+ let e=require(`react`),t=require(`react/jsx-runtime`),n=require(`react-dom`);var r={success:{bg:`#e8f7ee`,border:`#b6e2ca`,fg:`#0d5a30`,dot:`#12B05F`},info:{bg:`#eaf1fb`,border:`#c3d6ee`,fg:`#1d3d6b`,dot:`#2563eb`},warning:{bg:`#fff4d6`,border:`#f2d58d`,fg:`#8c5f16`,dot:`#F5B547`},error:{bg:`#fbeaea`,border:`#f3c8c8`,fg:`#7a1f15`,dot:`#c0392b`}},i=6e3,a=(0,e.createContext)(null),o=0;function s({entry:n,onClose:a}){let o=r[n.kind];return(0,e.useEffect)(()=>{let e=setTimeout(a,i);return()=>clearTimeout(e)},[a]),(0,t.jsxs)(`div`,{style:{display:`flex`,gap:10,alignItems:`flex-start`,padding:`12px 14px`,background:o.bg,border:`1px solid ${o.border}`,borderRadius:10,boxShadow:`0 12px 32px rgba(47,56,67,0.14)`,minWidth:320,maxWidth:420,animation:`toastIn 320ms cubic-bezier(0,0,0,1)`},children:[(0,t.jsx)(`span`,{style:{width:8,height:8,borderRadius:`50%`,background:o.dot,marginTop:6,flexShrink:0}}),(0,t.jsxs)(`div`,{style:{flex:1},children:[(0,t.jsx)(`div`,{style:{fontFamily:`var(--font-sans)`,fontSize:12.5,fontWeight:700,color:o.fg},children:n.title}),n.body&&(0,t.jsx)(`div`,{style:{fontFamily:`var(--font-sans)`,fontSize:11.5,color:o.fg,opacity:.85,marginTop:2,lineHeight:1.5,whiteSpace:`pre-line`},children:n.body})]}),(0,t.jsx)(`button`,{onClick:a,style:{border:`none`,background:`transparent`,color:o.fg,opacity:.6,cursor:`pointer`,fontSize:16,padding:0,lineHeight:1,flexShrink:0},children:`×`})]})}function c({toasts:e,onClose:r}){return e.length===0?null:(0,n.createPortal)((0,t.jsx)(`div`,{style:{position:`fixed`,bottom:24,right:24,zIndex:1500,display:`flex`,flexDirection:`column`,gap:8},children:e.map(e=>(0,t.jsx)(s,{entry:e,onClose:()=>r(e.id)},e.id))}),document.body)}function l({children:n}){let[r,i]=(0,e.useState)([]),s=(0,e.useCallback)(e=>{i(t=>t.filter(t=>t.id!==e))},[]),l=(0,e.useCallback)((e,t,n)=>{let r=++o;i(i=>[...i,{id:r,kind:e,title:t,body:n}])},[]);return(0,t.jsxs)(a.Provider,{value:{success:(e,t)=>l(`success`,e,t),info:(e,t)=>l(`info`,e,t),warning:(e,t)=>l(`warning`,e,t),error:(e,t)=>l(`error`,e,t)},children:[n,(0,t.jsx)(c,{toasts:r,onClose:s})]})}function u(){let t=(0,e.useContext)(a);if(!t)throw Error(`useToast must be used inside ToastProvider`);return t}exports.ToastProvider=l,exports.useToast=u;
2
+ //# sourceMappingURL=index13.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index13.cjs","names":[],"sources":["../src/components/Toast.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useEffect, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport type ToastKind = 'success' | 'info' | 'warning' | 'error'\n\ninterface ToastEntry {\n id: number\n kind: ToastKind\n title: string\n body?: string\n}\n\ninterface ToastContextValue {\n success: (title: string, body?: string) => void\n info: (title: string, body?: string) => void\n warning: (title: string, body?: string) => void\n error: (title: string, body?: string) => void\n}\n\nconst STYLES: Record<ToastKind, { bg: string; border: string; fg: string; dot: string }> = {\n success: { bg: '#e8f7ee', border: '#b6e2ca', fg: '#0d5a30', dot: '#12B05F' },\n info: { bg: '#eaf1fb', border: '#c3d6ee', fg: '#1d3d6b', dot: '#2563eb' },\n warning: { bg: '#fff4d6', border: '#f2d58d', fg: '#8c5f16', dot: '#F5B547' },\n error: { bg: '#fbeaea', border: '#f3c8c8', fg: '#7a1f15', dot: '#c0392b' },\n}\n\nconst AUTO_DISMISS_MS = 6000\n\nconst ToastContext = createContext<ToastContextValue | null>(null)\n\nlet _nextId = 0\n\nfunction ToastItem({ entry, onClose }: { entry: ToastEntry; onClose: () => void }) {\n const s = STYLES[entry.kind]\n\n useEffect(() => {\n const timer = setTimeout(onClose, AUTO_DISMISS_MS)\n return () => clearTimeout(timer)\n }, [onClose])\n\n return (\n <div style={{\n display: 'flex',\n gap: 10,\n alignItems: 'flex-start',\n padding: '12px 14px',\n background: s.bg,\n border: `1px solid ${s.border}`,\n borderRadius: 10,\n boxShadow: '0 12px 32px rgba(47,56,67,0.14)',\n minWidth: 320,\n maxWidth: 420,\n animation: 'toastIn 320ms cubic-bezier(0,0,0,1)',\n }}>\n <span style={{ width: 8, height: 8, borderRadius: '50%', background: s.dot, marginTop: 6, flexShrink: 0 }} />\n <div style={{ flex: 1 }}>\n <div style={{ fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 700, color: s.fg }}>\n {entry.title}\n </div>\n {entry.body && (\n <div style={{ fontFamily: 'var(--font-sans)', fontSize: 11.5, color: s.fg, opacity: 0.85, marginTop: 2, lineHeight: 1.5, whiteSpace: 'pre-line' }}>\n {entry.body}\n </div>\n )}\n </div>\n <button\n onClick={onClose}\n style={{ border: 'none', background: 'transparent', color: s.fg, opacity: 0.6, cursor: 'pointer', fontSize: 16, padding: 0, lineHeight: 1, flexShrink: 0 }}\n >\n ×\n </button>\n </div>\n )\n}\n\nfunction ToastContainer({ toasts, onClose }: { toasts: ToastEntry[]; onClose: (id: number) => void }) {\n if (toasts.length === 0) return null\n return createPortal(\n <div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 1500, display: 'flex', flexDirection: 'column', gap: 8 }}>\n {toasts.map(t => (\n <ToastItem key={t.id} entry={t} onClose={() => onClose(t.id)} />\n ))}\n </div>,\n document.body\n )\n}\n\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<ToastEntry[]>([])\n\n const dismiss = useCallback((id: number) => {\n setToasts(prev => prev.filter(t => t.id !== id))\n }, [])\n\n const add = useCallback((kind: ToastKind, title: string, body?: string) => {\n const id = ++_nextId\n setToasts(prev => [...prev, { id, kind, title, body }])\n }, [])\n\n const ctx: ToastContextValue = {\n success: (title, body) => add('success', title, body),\n info: (title, body) => add('info', title, body),\n warning: (title, body) => add('warning', title, body),\n error: (title, body) => add('error', title, body),\n }\n\n return (\n <ToastContext.Provider value={ctx}>\n {children}\n <ToastContainer toasts={toasts} onClose={dismiss} />\n </ToastContext.Provider>\n )\n}\n\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext)\n if (!ctx) throw new Error('useToast must be used inside ToastProvider')\n return ctx\n}\n"],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import { createContext as e, useCallback as t, useContext as n, useEffect as r, useState as i } from "react";
2
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
3
+ import { createPortal as s } from "react-dom";
4
+ //#region src/components/Toast.tsx
5
+ var c = {
6
+ success: {
7
+ bg: "#e8f7ee",
8
+ border: "#b6e2ca",
9
+ fg: "#0d5a30",
10
+ dot: "#12B05F"
11
+ },
12
+ info: {
13
+ bg: "#eaf1fb",
14
+ border: "#c3d6ee",
15
+ fg: "#1d3d6b",
16
+ dot: "#2563eb"
17
+ },
18
+ warning: {
19
+ bg: "#fff4d6",
20
+ border: "#f2d58d",
21
+ fg: "#8c5f16",
22
+ dot: "#F5B547"
23
+ },
24
+ error: {
25
+ bg: "#fbeaea",
26
+ border: "#f3c8c8",
27
+ fg: "#7a1f15",
28
+ dot: "#c0392b"
29
+ }
30
+ }, l = 6e3, u = e(null), d = 0;
31
+ function f({ entry: e, onClose: t }) {
32
+ let n = c[e.kind];
33
+ return r(() => {
34
+ let e = setTimeout(t, l);
35
+ return () => clearTimeout(e);
36
+ }, [t]), /* @__PURE__ */ o("div", {
37
+ style: {
38
+ display: "flex",
39
+ gap: 10,
40
+ alignItems: "flex-start",
41
+ padding: "12px 14px",
42
+ background: n.bg,
43
+ border: `1px solid ${n.border}`,
44
+ borderRadius: 10,
45
+ boxShadow: "0 12px 32px rgba(47,56,67,0.14)",
46
+ minWidth: 320,
47
+ maxWidth: 420,
48
+ animation: "toastIn 320ms cubic-bezier(0,0,0,1)"
49
+ },
50
+ children: [
51
+ /* @__PURE__ */ a("span", { style: {
52
+ width: 8,
53
+ height: 8,
54
+ borderRadius: "50%",
55
+ background: n.dot,
56
+ marginTop: 6,
57
+ flexShrink: 0
58
+ } }),
59
+ /* @__PURE__ */ o("div", {
60
+ style: { flex: 1 },
61
+ children: [/* @__PURE__ */ a("div", {
62
+ style: {
63
+ fontFamily: "var(--font-sans)",
64
+ fontSize: 12.5,
65
+ fontWeight: 700,
66
+ color: n.fg
67
+ },
68
+ children: e.title
69
+ }), e.body && /* @__PURE__ */ a("div", {
70
+ style: {
71
+ fontFamily: "var(--font-sans)",
72
+ fontSize: 11.5,
73
+ color: n.fg,
74
+ opacity: .85,
75
+ marginTop: 2,
76
+ lineHeight: 1.5,
77
+ whiteSpace: "pre-line"
78
+ },
79
+ children: e.body
80
+ })]
81
+ }),
82
+ /* @__PURE__ */ a("button", {
83
+ onClick: t,
84
+ style: {
85
+ border: "none",
86
+ background: "transparent",
87
+ color: n.fg,
88
+ opacity: .6,
89
+ cursor: "pointer",
90
+ fontSize: 16,
91
+ padding: 0,
92
+ lineHeight: 1,
93
+ flexShrink: 0
94
+ },
95
+ children: "×"
96
+ })
97
+ ]
98
+ });
99
+ }
100
+ function p({ toasts: e, onClose: t }) {
101
+ return e.length === 0 ? null : s(/* @__PURE__ */ a("div", {
102
+ style: {
103
+ position: "fixed",
104
+ bottom: 24,
105
+ right: 24,
106
+ zIndex: 1500,
107
+ display: "flex",
108
+ flexDirection: "column",
109
+ gap: 8
110
+ },
111
+ children: e.map((e) => /* @__PURE__ */ a(f, {
112
+ entry: e,
113
+ onClose: () => t(e.id)
114
+ }, e.id))
115
+ }), document.body);
116
+ }
117
+ function m({ children: e }) {
118
+ let [n, r] = i([]), s = t((e) => {
119
+ r((t) => t.filter((t) => t.id !== e));
120
+ }, []), c = t((e, t, n) => {
121
+ let i = ++d;
122
+ r((r) => [...r, {
123
+ id: i,
124
+ kind: e,
125
+ title: t,
126
+ body: n
127
+ }]);
128
+ }, []);
129
+ return /* @__PURE__ */ o(u.Provider, {
130
+ value: {
131
+ success: (e, t) => c("success", e, t),
132
+ info: (e, t) => c("info", e, t),
133
+ warning: (e, t) => c("warning", e, t),
134
+ error: (e, t) => c("error", e, t)
135
+ },
136
+ children: [e, /* @__PURE__ */ a(p, {
137
+ toasts: n,
138
+ onClose: s
139
+ })]
140
+ });
141
+ }
142
+ function h() {
143
+ let e = n(u);
144
+ if (!e) throw Error("useToast must be used inside ToastProvider");
145
+ return e;
146
+ }
147
+ //#endregion
148
+ export { m as ToastProvider, h as useToast };
149
+
150
+ //# sourceMappingURL=index13.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index13.js","names":[],"sources":["../src/components/Toast.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useEffect, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport type ToastKind = 'success' | 'info' | 'warning' | 'error'\n\ninterface ToastEntry {\n id: number\n kind: ToastKind\n title: string\n body?: string\n}\n\ninterface ToastContextValue {\n success: (title: string, body?: string) => void\n info: (title: string, body?: string) => void\n warning: (title: string, body?: string) => void\n error: (title: string, body?: string) => void\n}\n\nconst STYLES: Record<ToastKind, { bg: string; border: string; fg: string; dot: string }> = {\n success: { bg: '#e8f7ee', border: '#b6e2ca', fg: '#0d5a30', dot: '#12B05F' },\n info: { bg: '#eaf1fb', border: '#c3d6ee', fg: '#1d3d6b', dot: '#2563eb' },\n warning: { bg: '#fff4d6', border: '#f2d58d', fg: '#8c5f16', dot: '#F5B547' },\n error: { bg: '#fbeaea', border: '#f3c8c8', fg: '#7a1f15', dot: '#c0392b' },\n}\n\nconst AUTO_DISMISS_MS = 6000\n\nconst ToastContext = createContext<ToastContextValue | null>(null)\n\nlet _nextId = 0\n\nfunction ToastItem({ entry, onClose }: { entry: ToastEntry; onClose: () => void }) {\n const s = STYLES[entry.kind]\n\n useEffect(() => {\n const timer = setTimeout(onClose, AUTO_DISMISS_MS)\n return () => clearTimeout(timer)\n }, [onClose])\n\n return (\n <div style={{\n display: 'flex',\n gap: 10,\n alignItems: 'flex-start',\n padding: '12px 14px',\n background: s.bg,\n border: `1px solid ${s.border}`,\n borderRadius: 10,\n boxShadow: '0 12px 32px rgba(47,56,67,0.14)',\n minWidth: 320,\n maxWidth: 420,\n animation: 'toastIn 320ms cubic-bezier(0,0,0,1)',\n }}>\n <span style={{ width: 8, height: 8, borderRadius: '50%', background: s.dot, marginTop: 6, flexShrink: 0 }} />\n <div style={{ flex: 1 }}>\n <div style={{ fontFamily: 'var(--font-sans)', fontSize: 12.5, fontWeight: 700, color: s.fg }}>\n {entry.title}\n </div>\n {entry.body && (\n <div style={{ fontFamily: 'var(--font-sans)', fontSize: 11.5, color: s.fg, opacity: 0.85, marginTop: 2, lineHeight: 1.5, whiteSpace: 'pre-line' }}>\n {entry.body}\n </div>\n )}\n </div>\n <button\n onClick={onClose}\n style={{ border: 'none', background: 'transparent', color: s.fg, opacity: 0.6, cursor: 'pointer', fontSize: 16, padding: 0, lineHeight: 1, flexShrink: 0 }}\n >\n ×\n </button>\n </div>\n )\n}\n\nfunction ToastContainer({ toasts, onClose }: { toasts: ToastEntry[]; onClose: (id: number) => void }) {\n if (toasts.length === 0) return null\n return createPortal(\n <div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 1500, display: 'flex', flexDirection: 'column', gap: 8 }}>\n {toasts.map(t => (\n <ToastItem key={t.id} entry={t} onClose={() => onClose(t.id)} />\n ))}\n </div>,\n document.body\n )\n}\n\nexport function ToastProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<ToastEntry[]>([])\n\n const dismiss = useCallback((id: number) => {\n setToasts(prev => prev.filter(t => t.id !== id))\n }, [])\n\n const add = useCallback((kind: ToastKind, title: string, body?: string) => {\n const id = ++_nextId\n setToasts(prev => [...prev, { id, kind, title, body }])\n }, [])\n\n const ctx: ToastContextValue = {\n success: (title, body) => add('success', title, body),\n info: (title, body) => add('info', title, body),\n warning: (title, body) => add('warning', title, body),\n error: (title, body) => add('error', title, body),\n }\n\n return (\n <ToastContext.Provider value={ctx}>\n {children}\n <ToastContainer toasts={toasts} onClose={dismiss} />\n </ToastContext.Provider>\n )\n}\n\nexport function useToast(): ToastContextValue {\n const ctx = useContext(ToastContext)\n if (!ctx) throw new Error('useToast must be used inside ToastProvider')\n return ctx\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ let e=require(`react`),t=require(`react/jsx-runtime`),n=require(`react-dom`);function r({trigger:r,items:i,align:a=`right`}){let[o,s]=(0,e.useState)(!1),[c,l]=(0,e.useState)({top:0,left:0}),u=(0,e.useRef)(null),d=(0,e.useRef)(null);return(0,e.useEffect)(()=>{if(!o)return;let e=e=>{e.key===`Escape`&&s(!1)},t=e=>{!d.current?.contains(e.target)&&!u.current?.contains(e.target)&&s(!1)};return document.addEventListener(`mousedown`,t),document.addEventListener(`keydown`,e),()=>{document.removeEventListener(`mousedown`,t),document.removeEventListener(`keydown`,e)}},[o]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(`div`,{ref:u,onClick:()=>{let e=u.current?.getBoundingClientRect();e&&(l({top:e.bottom+window.scrollY+4,left:a===`right`?e.right+window.scrollX:e.left+window.scrollX}),s(!0))},style:{display:`inline-flex`,cursor:`pointer`},children:r}),o&&(0,n.createPortal)((0,t.jsx)(`div`,{ref:d,style:{position:`absolute`,top:c.top,left:a===`right`?void 0:c.left,right:a===`right`?`calc(100vw - ${c.left}px)`:void 0,minWidth:160,background:`var(--c-surface)`,border:`1px solid var(--c-border)`,borderRadius:8,boxShadow:`0 4px 12px rgba(47,56,67,0.12)`,padding:4,zIndex:500},children:i.map((e,n)=>{if(`separator`in e&&e.separator)return(0,t.jsx)(`div`,{style:{height:1,background:`var(--c-border)`,margin:`4px 0`}},n);let r=e;return(0,t.jsxs)(`button`,{disabled:r.disabled,onClick:()=>{r.onClick?.(),s(!1)},style:{display:`flex`,alignItems:`center`,gap:8,width:`100%`,padding:`7px 10px`,borderRadius:4,border:`none`,background:`transparent`,color:r.variant===`destructive`?`var(--c-error)`:r.disabled?`var(--c-text-muted)`:`var(--c-text)`,fontFamily:`var(--font-sans)`,fontSize:13,fontWeight:500,textAlign:`left`,cursor:r.disabled?`default`:`pointer`,opacity:r.disabled?.5:1,transition:`background 100ms`},onMouseEnter:e=>{r.disabled||(e.currentTarget.style.background=`var(--c-elevated)`)},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`},children:[r.icon&&(0,t.jsx)(`span`,{style:{display:`inline-flex`,color:r.variant===`destructive`?`var(--c-error)`:`var(--c-text-subtle)`,flexShrink:0},children:r.icon}),r.label]},n)})}),document.body)]})}exports.DropdownMenu=r;
2
+ //# sourceMappingURL=index14.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index14.cjs","names":[],"sources":["../src/components/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport interface DropdownMenuItem {\n label: string\n icon?: ReactNode\n onClick?: () => void\n variant?: 'default' | 'destructive'\n disabled?: boolean\n separator?: never\n}\n\nexport interface DropdownMenuSeparator {\n separator: true\n label?: never\n onClick?: never\n variant?: never\n disabled?: never\n}\n\nexport type DropdownMenuEntry = DropdownMenuItem | DropdownMenuSeparator\n\ninterface DropdownMenuProps {\n trigger: ReactNode\n items: DropdownMenuEntry[]\n align?: 'left' | 'right'\n}\n\ninterface Pos { top: number; left: number }\n\nexport function DropdownMenu({ trigger, items, align = 'right' }: DropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const [pos, setPos] = useState<Pos>({ top: 0, left: 0 })\n const triggerRef = useRef<HTMLDivElement>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n\n const openMenu = () => {\n const rect = triggerRef.current?.getBoundingClientRect()\n if (!rect) return\n setPos({\n top: rect.bottom + window.scrollY + 4,\n left: align === 'right'\n ? rect.right + window.scrollX\n : rect.left + window.scrollX,\n })\n setOpen(true)\n }\n\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false) }\n const onClick = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node) && !triggerRef.current?.contains(e.target as Node)) {\n setOpen(false)\n }\n }\n document.addEventListener('mousedown', onClick)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onClick)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n return (\n <>\n <div ref={triggerRef} onClick={openMenu} style={{ display: 'inline-flex', cursor: 'pointer' }}>\n {trigger}\n </div>\n\n {open && createPortal(\n <div\n ref={menuRef}\n style={{\n position: 'absolute',\n top: pos.top,\n left: align === 'right' ? undefined : pos.left,\n right: align === 'right' ? `calc(100vw - ${pos.left}px)` : undefined,\n minWidth: 160,\n background: 'var(--c-surface)',\n border: '1px solid var(--c-border)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(47,56,67,0.12)',\n padding: 4,\n zIndex: 500,\n }}\n >\n {items.map((item, i) => {\n if ('separator' in item && item.separator) {\n return <div key={i} style={{ height: 1, background: 'var(--c-border)', margin: '4px 0' }} />\n }\n const mi = item as DropdownMenuItem\n return (\n <button\n key={i}\n disabled={mi.disabled}\n onClick={() => { mi.onClick?.(); setOpen(false) }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n width: '100%',\n padding: '7px 10px',\n borderRadius: 4,\n border: 'none',\n background: 'transparent',\n color: mi.variant === 'destructive' ? 'var(--c-error)' : mi.disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n fontWeight: 500,\n textAlign: 'left',\n cursor: mi.disabled ? 'default' : 'pointer',\n opacity: mi.disabled ? 0.5 : 1,\n transition: 'background 100ms',\n }}\n onMouseEnter={e => { if (!mi.disabled) e.currentTarget.style.background = 'var(--c-elevated)' }}\n onMouseLeave={e => { e.currentTarget.style.background = 'transparent' }}\n >\n {mi.icon && (\n <span style={{ display: 'inline-flex', color: mi.variant === 'destructive' ? 'var(--c-error)' : 'var(--c-text-subtle)', flexShrink: 0 }}>\n {mi.icon}\n </span>\n )}\n {mi.label}\n </button>\n )\n })}\n </div>,\n document.body\n )}\n </>\n )\n}\n"],"mappings":"6EA8BA,SAAgB,EAAa,CAAE,UAAS,QAAO,QAAQ,SAA8B,CACnF,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,GAAM,CACjC,CAAC,EAAK,IAAA,EAAA,EAAA,UAAwB,CAAE,IAAK,EAAG,KAAM,EAAG,CAAC,CAClD,GAAA,EAAA,EAAA,QAAoC,KAAK,CACzC,GAAA,EAAA,EAAA,QAAiC,KAAK,CA8B5C,OAhBA,EAAA,EAAA,eAAgB,CACd,GAAI,CAAC,EAAM,OACX,IAAM,EAAW,GAAqB,CAAM,EAAE,MAAQ,UAAU,EAAQ,GAAM,EACxE,EAAW,GAAkB,CAC7B,CAAC,EAAQ,SAAS,SAAS,EAAE,OAAe,EAAI,CAAC,EAAW,SAAS,SAAS,EAAE,OAAe,EACjG,EAAQ,GAAM,EAKlB,OAFA,SAAS,iBAAiB,YAAa,EAAQ,CAC/C,SAAS,iBAAiB,UAAW,EAAM,KAC9B,CACX,SAAS,oBAAoB,YAAa,EAAQ,CAClD,SAAS,oBAAoB,UAAW,EAAM,GAE/C,CAAC,EAAK,CAAC,EAGR,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAY,YA9BH,CACrB,IAAM,EAAO,EAAW,SAAS,uBAAuB,CACnD,IACL,EAAO,CACL,IAAM,EAAK,OAAS,OAAO,QAAU,EACrC,KAAM,IAAU,QACZ,EAAK,MAAS,OAAO,QACrB,EAAK,KAAS,OAAO,QAC1B,CAAC,CACF,EAAQ,GAAK,GAqB8B,MAAO,CAAE,QAAS,cAAe,OAAQ,UAAW,UAC1F,EACG,CAAA,CAEL,IAAA,EAAA,EAAA,eACC,EAAA,EAAA,KAAC,MAAD,CACE,IAAK,EACL,MAAO,CACL,SAAc,WACd,IAAc,EAAI,IAClB,KAAc,IAAU,QAAU,IAAA,GAAY,EAAI,KAClD,MAAc,IAAU,QAAU,gBAAgB,EAAI,KAAK,KAAO,IAAA,GAClE,SAAc,IACd,WAAc,mBACd,OAAc,4BACd,aAAc,EACd,UAAc,iCACd,QAAc,EACd,OAAc,IACf,UAEA,EAAM,KAAK,EAAM,IAAM,CACtB,GAAI,cAAe,GAAQ,EAAK,UAC9B,OAAO,EAAA,EAAA,KAAC,MAAD,CAAa,MAAO,CAAE,OAAQ,EAAG,WAAY,kBAAmB,OAAQ,QAAS,CAAI,CAA3E,EAA2E,CAE9F,IAAM,EAAK,EACX,OACE,EAAA,EAAA,MAAC,SAAD,CAEE,SAAU,EAAG,SACb,YAAe,CAAE,EAAG,WAAW,CAAE,EAAQ,GAAM,EAC/C,MAAO,CACL,QAAY,OACZ,WAAY,SACZ,IAAY,EACZ,MAAY,OACZ,QAAY,WACZ,aAAc,EACd,OAAY,OACZ,WAAY,cACZ,MAAY,EAAG,UAAY,cAAgB,iBAAmB,EAAG,SAAW,sBAAwB,gBACpG,WAAY,mBACZ,SAAY,GACZ,WAAY,IACZ,UAAY,OACZ,OAAY,EAAG,SAAW,UAAY,UACtC,QAAY,EAAG,SAAW,GAAM,EAChC,WAAY,mBACb,CACD,aAAc,GAAK,CAAO,EAAG,WAAU,EAAE,cAAc,MAAM,WAAa,sBAC1E,aAAc,GAAK,CAAE,EAAE,cAAc,MAAM,WAAa,wBAvB1D,CAyBG,EAAG,OACF,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,QAAS,cAAe,MAAO,EAAG,UAAY,cAAgB,iBAAmB,uBAAwB,WAAY,EAAG,UACpI,EAAG,KACC,CAAA,CAER,EAAG,MACG,EA9BF,EA8BE,EAEX,CACE,CAAA,CACN,SAAS,KACV,CACA,CAAA,CAAA"}
@@ -0,0 +1,100 @@
1
+ import { useEffect as e, useRef as t, useState as n } from "react";
2
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
3
+ import { createPortal as o } from "react-dom";
4
+ //#region src/components/DropdownMenu.tsx
5
+ function s({ trigger: s, items: c, align: l = "right" }) {
6
+ let [u, d] = n(!1), [f, p] = n({
7
+ top: 0,
8
+ left: 0
9
+ }), m = t(null), h = t(null);
10
+ return e(() => {
11
+ if (!u) return;
12
+ let e = (e) => {
13
+ e.key === "Escape" && d(!1);
14
+ }, t = (e) => {
15
+ !h.current?.contains(e.target) && !m.current?.contains(e.target) && d(!1);
16
+ };
17
+ return document.addEventListener("mousedown", t), document.addEventListener("keydown", e), () => {
18
+ document.removeEventListener("mousedown", t), document.removeEventListener("keydown", e);
19
+ };
20
+ }, [u]), /* @__PURE__ */ a(r, { children: [/* @__PURE__ */ i("div", {
21
+ ref: m,
22
+ onClick: () => {
23
+ let e = m.current?.getBoundingClientRect();
24
+ e && (p({
25
+ top: e.bottom + window.scrollY + 4,
26
+ left: l === "right" ? e.right + window.scrollX : e.left + window.scrollX
27
+ }), d(!0));
28
+ },
29
+ style: {
30
+ display: "inline-flex",
31
+ cursor: "pointer"
32
+ },
33
+ children: s
34
+ }), u && o(/* @__PURE__ */ i("div", {
35
+ ref: h,
36
+ style: {
37
+ position: "absolute",
38
+ top: f.top,
39
+ left: l === "right" ? void 0 : f.left,
40
+ right: l === "right" ? `calc(100vw - ${f.left}px)` : void 0,
41
+ minWidth: 160,
42
+ background: "var(--c-surface)",
43
+ border: "1px solid var(--c-border)",
44
+ borderRadius: 8,
45
+ boxShadow: "0 4px 12px rgba(47,56,67,0.12)",
46
+ padding: 4,
47
+ zIndex: 500
48
+ },
49
+ children: c.map((e, t) => {
50
+ if ("separator" in e && e.separator) return /* @__PURE__ */ i("div", { style: {
51
+ height: 1,
52
+ background: "var(--c-border)",
53
+ margin: "4px 0"
54
+ } }, t);
55
+ let n = e;
56
+ return /* @__PURE__ */ a("button", {
57
+ disabled: n.disabled,
58
+ onClick: () => {
59
+ n.onClick?.(), d(!1);
60
+ },
61
+ style: {
62
+ display: "flex",
63
+ alignItems: "center",
64
+ gap: 8,
65
+ width: "100%",
66
+ padding: "7px 10px",
67
+ borderRadius: 4,
68
+ border: "none",
69
+ background: "transparent",
70
+ color: n.variant === "destructive" ? "var(--c-error)" : n.disabled ? "var(--c-text-muted)" : "var(--c-text)",
71
+ fontFamily: "var(--font-sans)",
72
+ fontSize: 13,
73
+ fontWeight: 500,
74
+ textAlign: "left",
75
+ cursor: n.disabled ? "default" : "pointer",
76
+ opacity: n.disabled ? .5 : 1,
77
+ transition: "background 100ms"
78
+ },
79
+ onMouseEnter: (e) => {
80
+ n.disabled || (e.currentTarget.style.background = "var(--c-elevated)");
81
+ },
82
+ onMouseLeave: (e) => {
83
+ e.currentTarget.style.background = "transparent";
84
+ },
85
+ children: [n.icon && /* @__PURE__ */ i("span", {
86
+ style: {
87
+ display: "inline-flex",
88
+ color: n.variant === "destructive" ? "var(--c-error)" : "var(--c-text-subtle)",
89
+ flexShrink: 0
90
+ },
91
+ children: n.icon
92
+ }), n.label]
93
+ }, t);
94
+ })
95
+ }), document.body)] });
96
+ }
97
+ //#endregion
98
+ export { s as DropdownMenu };
99
+
100
+ //# sourceMappingURL=index14.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index14.js","names":[],"sources":["../src/components/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\nexport interface DropdownMenuItem {\n label: string\n icon?: ReactNode\n onClick?: () => void\n variant?: 'default' | 'destructive'\n disabled?: boolean\n separator?: never\n}\n\nexport interface DropdownMenuSeparator {\n separator: true\n label?: never\n onClick?: never\n variant?: never\n disabled?: never\n}\n\nexport type DropdownMenuEntry = DropdownMenuItem | DropdownMenuSeparator\n\ninterface DropdownMenuProps {\n trigger: ReactNode\n items: DropdownMenuEntry[]\n align?: 'left' | 'right'\n}\n\ninterface Pos { top: number; left: number }\n\nexport function DropdownMenu({ trigger, items, align = 'right' }: DropdownMenuProps) {\n const [open, setOpen] = useState(false)\n const [pos, setPos] = useState<Pos>({ top: 0, left: 0 })\n const triggerRef = useRef<HTMLDivElement>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n\n const openMenu = () => {\n const rect = triggerRef.current?.getBoundingClientRect()\n if (!rect) return\n setPos({\n top: rect.bottom + window.scrollY + 4,\n left: align === 'right'\n ? rect.right + window.scrollX\n : rect.left + window.scrollX,\n })\n setOpen(true)\n }\n\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false) }\n const onClick = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node) && !triggerRef.current?.contains(e.target as Node)) {\n setOpen(false)\n }\n }\n document.addEventListener('mousedown', onClick)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onClick)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n return (\n <>\n <div ref={triggerRef} onClick={openMenu} style={{ display: 'inline-flex', cursor: 'pointer' }}>\n {trigger}\n </div>\n\n {open && createPortal(\n <div\n ref={menuRef}\n style={{\n position: 'absolute',\n top: pos.top,\n left: align === 'right' ? undefined : pos.left,\n right: align === 'right' ? `calc(100vw - ${pos.left}px)` : undefined,\n minWidth: 160,\n background: 'var(--c-surface)',\n border: '1px solid var(--c-border)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(47,56,67,0.12)',\n padding: 4,\n zIndex: 500,\n }}\n >\n {items.map((item, i) => {\n if ('separator' in item && item.separator) {\n return <div key={i} style={{ height: 1, background: 'var(--c-border)', margin: '4px 0' }} />\n }\n const mi = item as DropdownMenuItem\n return (\n <button\n key={i}\n disabled={mi.disabled}\n onClick={() => { mi.onClick?.(); setOpen(false) }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n width: '100%',\n padding: '7px 10px',\n borderRadius: 4,\n border: 'none',\n background: 'transparent',\n color: mi.variant === 'destructive' ? 'var(--c-error)' : mi.disabled ? 'var(--c-text-muted)' : 'var(--c-text)',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n fontWeight: 500,\n textAlign: 'left',\n cursor: mi.disabled ? 'default' : 'pointer',\n opacity: mi.disabled ? 0.5 : 1,\n transition: 'background 100ms',\n }}\n onMouseEnter={e => { if (!mi.disabled) e.currentTarget.style.background = 'var(--c-elevated)' }}\n onMouseLeave={e => { e.currentTarget.style.background = 'transparent' }}\n >\n {mi.icon && (\n <span style={{ display: 'inline-flex', color: mi.variant === 'destructive' ? 'var(--c-error)' : 'var(--c-text-subtle)', flexShrink: 0 }}>\n {mi.icon}\n </span>\n )}\n {mi.label}\n </button>\n )\n })}\n </div>,\n document.body\n )}\n </>\n )\n}\n"],"mappings":";;;;AA8BA,SAAgB,EAAa,EAAE,YAAS,UAAO,WAAQ,WAA8B;CACnF,IAAM,CAAC,GAAM,KAAW,EAAS,GAAM,EACjC,CAAC,GAAK,KAAU,EAAc;EAAE,KAAK;EAAG,MAAM;EAAG,CAAC,EAClD,IAAa,EAAuB,KAAK,EACzC,IAAU,EAAuB,KAAK;AA8B5C,QAhBA,QAAgB;AACd,MAAI,CAAC,EAAM;EACX,IAAM,KAAW,MAAqB;AAAE,GAAI,EAAE,QAAQ,YAAU,EAAQ,GAAM;KACxE,KAAW,MAAkB;AACjC,GAAI,CAAC,EAAQ,SAAS,SAAS,EAAE,OAAe,IAAI,CAAC,EAAW,SAAS,SAAS,EAAE,OAAe,IACjG,EAAQ,GAAM;;AAKlB,SAFA,SAAS,iBAAiB,aAAa,EAAQ,EAC/C,SAAS,iBAAiB,WAAW,EAAM,QAC9B;AAEX,GADA,SAAS,oBAAoB,aAAa,EAAQ,EAClD,SAAS,oBAAoB,WAAW,EAAM;;IAE/C,CAAC,EAAK,CAAC,EAGR,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;EAAK,KAAK;EAAY,eA9BH;GACrB,IAAM,IAAO,EAAW,SAAS,uBAAuB;AACnD,SACL,EAAO;IACL,KAAM,EAAK,SAAS,OAAO,UAAU;IACrC,MAAM,MAAU,UACZ,EAAK,QAAS,OAAO,UACrB,EAAK,OAAS,OAAO;IAC1B,CAAC,EACF,EAAQ,GAAK;;EAqB8B,OAAO;GAAE,SAAS;GAAe,QAAQ;GAAW;YAC1F;EACG,CAAA,EAEL,KAAQ,EACP,kBAAC,OAAD;EACE,KAAK;EACL,OAAO;GACL,UAAc;GACd,KAAc,EAAI;GAClB,MAAc,MAAU,UAAU,KAAA,IAAY,EAAI;GAClD,OAAc,MAAU,UAAU,gBAAgB,EAAI,KAAK,OAAO,KAAA;GAClE,UAAc;GACd,YAAc;GACd,QAAc;GACd,cAAc;GACd,WAAc;GACd,SAAc;GACd,QAAc;GACf;YAEA,EAAM,KAAK,GAAM,MAAM;AACtB,OAAI,eAAe,KAAQ,EAAK,UAC9B,QAAO,kBAAC,OAAD,EAAa,OAAO;IAAE,QAAQ;IAAG,YAAY;IAAmB,QAAQ;IAAS,EAAI,EAA3E,EAA2E;GAE9F,IAAM,IAAK;AACX,UACE,kBAAC,UAAD;IAEE,UAAU,EAAG;IACb,eAAe;AAAkB,KAAhB,EAAG,WAAW,EAAE,EAAQ,GAAM;;IAC/C,OAAO;KACL,SAAY;KACZ,YAAY;KACZ,KAAY;KACZ,OAAY;KACZ,SAAY;KACZ,cAAc;KACd,QAAY;KACZ,YAAY;KACZ,OAAY,EAAG,YAAY,gBAAgB,mBAAmB,EAAG,WAAW,wBAAwB;KACpG,YAAY;KACZ,UAAY;KACZ,YAAY;KACZ,WAAY;KACZ,QAAY,EAAG,WAAW,YAAY;KACtC,SAAY,EAAG,WAAW,KAAM;KAChC,YAAY;KACb;IACD,eAAc,MAAK;AAAE,KAAK,EAAG,aAAU,EAAE,cAAc,MAAM,aAAa;;IAC1E,eAAc,MAAK;AAAE,OAAE,cAAc,MAAM,aAAa;;cAvB1D,CAyBG,EAAG,QACF,kBAAC,QAAD;KAAM,OAAO;MAAE,SAAS;MAAe,OAAO,EAAG,YAAY,gBAAgB,mBAAmB;MAAwB,YAAY;MAAG;eACpI,EAAG;KACC,CAAA,EAER,EAAG,MACG;MA9BF,EA8BE;IAEX;EACE,CAAA,EACN,SAAS,KACV,CACA,EAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./index2.cjs`),t=require(`./index9.cjs`);let n=require(`react/jsx-runtime`);function r({open:r,onClose:i,onConfirm:a,title:o,body:s,confirmLabel:c=`Confirm`,cancelLabel:l=`Cancel`,confirmVariant:u=`destructive`,loading:d}){return(0,n.jsx)(t.Modal,{open:r,onClose:i,title:o,width:420,actions:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.Button,{variant:`ghost`,onClick:i,disabled:d,children:l}),(0,n.jsx)(e.Button,{variant:u,onClick:a,disabled:d,children:d?`Working…`:c})]}),children:s&&(0,n.jsx)(`p`,{style:{margin:0,color:`var(--c-text)`,lineHeight:1.6},children:s})})}exports.ConfirmDialog=r;
2
+ //# sourceMappingURL=index15.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index15.cjs","names":[],"sources":["../src/components/ConfirmDialog.tsx"],"sourcesContent":["import { Modal } from './Modal'\nimport { Button } from './Button'\n\ninterface ConfirmDialogProps {\n open: boolean\n onClose: () => void\n onConfirm: () => void\n title: string\n body?: string\n confirmLabel?: string\n cancelLabel?: string\n confirmVariant?: 'destructive' | 'primary'\n loading?: boolean\n}\n\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n body,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n confirmVariant = 'destructive',\n loading,\n}: ConfirmDialogProps) {\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n width={420}\n actions={\n <>\n <Button variant=\"ghost\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button variant={confirmVariant} onClick={onConfirm} disabled={loading}>\n {loading ? 'Working…' : confirmLabel}\n </Button>\n </>\n }\n >\n {body && (\n <p style={{ margin: 0, color: 'var(--c-text)', lineHeight: 1.6 }}>\n {body}\n </p>\n )}\n </Modal>\n )\n}\n"],"mappings":"6FAeA,SAAgB,EAAc,CAC5B,OACA,UACA,YACA,QACA,OACA,eAAgB,UAChB,cAAgB,SAChB,iBAAiB,cACjB,WACqB,CACrB,OACE,EAAA,EAAA,KAAC,EAAA,MAAD,CACQ,OACG,UACF,QACP,MAAO,IACP,SACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,QAAQ,QAAQ,QAAS,EAAS,SAAU,WACjD,EACM,CAAA,EACT,EAAA,EAAA,KAAC,EAAA,OAAD,CAAQ,QAAS,EAAgB,QAAS,EAAW,SAAU,WAC5D,EAAU,WAAa,EACjB,CAAA,CACR,CAAA,CAAA,UAGJ,IACC,EAAA,EAAA,KAAC,IAAD,CAAG,MAAO,CAAE,OAAQ,EAAG,MAAO,gBAAiB,WAAY,IAAK,UAC7D,EACC,CAAA,CAEA,CAAA"}
@@ -0,0 +1,35 @@
1
+ import { Button as e } from "./index2.js";
2
+ import { Modal as t } from "./index9.js";
3
+ import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ //#region src/components/ConfirmDialog.tsx
5
+ function a({ open: a, onClose: o, onConfirm: s, title: c, body: l, confirmLabel: u = "Confirm", cancelLabel: d = "Cancel", confirmVariant: f = "destructive", loading: p }) {
6
+ return /* @__PURE__ */ r(t, {
7
+ open: a,
8
+ onClose: o,
9
+ title: c,
10
+ width: 420,
11
+ actions: /* @__PURE__ */ i(n, { children: [/* @__PURE__ */ r(e, {
12
+ variant: "ghost",
13
+ onClick: o,
14
+ disabled: p,
15
+ children: d
16
+ }), /* @__PURE__ */ r(e, {
17
+ variant: f,
18
+ onClick: s,
19
+ disabled: p,
20
+ children: p ? "Working…" : u
21
+ })] }),
22
+ children: l && /* @__PURE__ */ r("p", {
23
+ style: {
24
+ margin: 0,
25
+ color: "var(--c-text)",
26
+ lineHeight: 1.6
27
+ },
28
+ children: l
29
+ })
30
+ });
31
+ }
32
+ //#endregion
33
+ export { a as ConfirmDialog };
34
+
35
+ //# sourceMappingURL=index15.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index15.js","names":[],"sources":["../src/components/ConfirmDialog.tsx"],"sourcesContent":["import { Modal } from './Modal'\nimport { Button } from './Button'\n\ninterface ConfirmDialogProps {\n open: boolean\n onClose: () => void\n onConfirm: () => void\n title: string\n body?: string\n confirmLabel?: string\n cancelLabel?: string\n confirmVariant?: 'destructive' | 'primary'\n loading?: boolean\n}\n\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n body,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n confirmVariant = 'destructive',\n loading,\n}: ConfirmDialogProps) {\n return (\n <Modal\n open={open}\n onClose={onClose}\n title={title}\n width={420}\n actions={\n <>\n <Button variant=\"ghost\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button variant={confirmVariant} onClick={onConfirm} disabled={loading}>\n {loading ? 'Working…' : confirmLabel}\n </Button>\n </>\n }\n >\n {body && (\n <p style={{ margin: 0, color: 'var(--c-text)', lineHeight: 1.6 }}>\n {body}\n </p>\n )}\n </Modal>\n )\n}\n"],"mappings":";;;;AAeA,SAAgB,EAAc,EAC5B,SACA,YACA,cACA,UACA,SACA,kBAAgB,WAChB,iBAAgB,UAChB,oBAAiB,eACjB,cACqB;AACrB,QACE,kBAAC,GAAD;EACQ;EACG;EACF;EACP,OAAO;EACP,SACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;GAAQ,SAAQ;GAAQ,SAAS;GAAS,UAAU;aACjD;GACM,CAAA,EACT,kBAAC,GAAD;GAAQ,SAAS;GAAgB,SAAS;GAAW,UAAU;aAC5D,IAAU,aAAa;GACjB,CAAA,CACR,EAAA,CAAA;YAGJ,KACC,kBAAC,KAAD;GAAG,OAAO;IAAE,QAAQ;IAAG,OAAO;IAAiB,YAAY;IAAK;aAC7D;GACC,CAAA;EAEA,CAAA"}
@@ -0,0 +1,2 @@
1
+ let e=require(`react`),t=require(`react/jsx-runtime`),n=require(`react-dom`);function r({triggerContent:r,open:i,onOpen:a,triggerRef:o,children:s,minWidth:c=200}){let l=(0,e.useRef)(null),[u,d]=(0,e.useState)({top:0,left:0,width:0});return(0,e.useEffect)(()=>{if(!i)return;let e=e=>{!l.current?.contains(e.target)&&!o.current?.contains(e.target)&&a()},t=e=>{e.key===`Escape`&&a()};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[i]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(`div`,{ref:o,onClick:()=>{let e=o.current?.getBoundingClientRect();e&&(d({top:e.bottom+window.scrollY+4,left:e.left+window.scrollX,width:e.width}),a())},style:{cursor:`pointer`},children:r}),i&&(0,n.createPortal)((0,t.jsx)(`div`,{ref:l,style:{position:`absolute`,top:u.top,left:u.left,minWidth:Math.max(u.width,c),background:`var(--c-surface)`,border:`1px solid var(--c-border)`,borderRadius:8,boxShadow:`0 4px 12px rgba(47,56,67,0.10)`,padding:4,zIndex:1100,maxHeight:240,overflowY:`auto`},children:s}),document.body)]})}function i({label:e,selected:n,onClick:r,checkbox:i}){return(0,t.jsxs)(`div`,{onClick:r,style:{padding:`6px 10px`,borderRadius:4,cursor:`pointer`,fontFamily:`var(--font-sans)`,fontSize:13,color:`var(--c-text)`,display:`flex`,alignItems:`center`,gap:8,background:!i&&n?`#fff4d6`:`transparent`},onMouseEnter:e=>{e.currentTarget.style.background=!i&&n?`#fff4d6`:`var(--c-elevated)`},onMouseLeave:e=>{e.currentTarget.style.background=!i&&n?`#fff4d6`:`transparent`},children:[i?(0,t.jsx)(`span`,{style:{width:14,height:14,borderRadius:3,flexShrink:0,border:`1.5px solid ${n?`var(--c-text)`:`var(--c-border-strong)`}`,background:n?`var(--c-text)`:`var(--c-surface)`,color:`#fff`,fontSize:10,display:`inline-flex`,alignItems:`center`,justifyContent:`center`},children:n?`✓`:``}):(0,t.jsx)(`span`,{style:{width:14,color:`var(--c-amber)`,fontWeight:700},children:n?`✓`:``}),(0,t.jsx)(`span`,{children:e})]})}function a({value:n,onChange:a,options:o,placeholder:s=`Select…`,disabled:c}){let[l,u]=(0,e.useState)(!1),d=(0,e.useRef)(null),f=o.map(e=>typeof e==`string`?{value:e,label:e}:e),p=f.find(e=>e.value===n);return(0,t.jsx)(r,{triggerRef:d,open:l,onOpen:()=>!c&&u(e=>!e),triggerContent:(0,t.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:8,padding:`8px 12px`,background:`var(--c-surface)`,border:`1px solid ${l?`var(--c-text)`:`var(--c-border)`}`,borderRadius:6,fontSize:13,fontFamily:`var(--font-sans)`,color:p?`var(--c-text)`:`var(--c-text-muted)`,boxShadow:l?`0 0 0 3px rgba(47,56,67,0.08)`:`none`,opacity:c?.5:1},children:[(0,t.jsx)(`span`,{style:{flex:1},children:p?.label??s}),(0,t.jsx)(`span`,{style:{fontSize:10,color:`var(--c-text-subtle)`,transform:l?`rotate(180deg)`:`none`,transition:`transform 160ms`},children:`▾`})]}),children:f.map(e=>(0,t.jsx)(i,{label:e.label,selected:e.value===n,onClick:()=>{a(e.value),u(!1)}},e.value))})}function o({values:n,onChange:a,options:o,placeholder:s=`Select…`}){let[c,l]=(0,e.useState)(!1),u=(0,e.useRef)(null),d=o.map(e=>typeof e==`string`?{value:e,label:e}:e),f=e=>a(n.includes(e)?n.filter(t=>t!==e):[...n,e]);return(0,t.jsx)(r,{triggerRef:u,open:c,onOpen:()=>l(e=>!e),triggerContent:(0,t.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:6,flexWrap:`wrap`,padding:`6px 10px`,background:`var(--c-surface)`,border:`1px solid ${c?`var(--c-text)`:`var(--c-border)`}`,borderRadius:6,minHeight:36,cursor:`pointer`,boxShadow:c?`0 0 0 3px rgba(47,56,67,0.08)`:`none`},children:[n.length===0?(0,t.jsx)(`span`,{style:{fontFamily:`var(--font-sans)`,fontSize:13,color:`var(--c-text-muted)`},children:s}):n.map(e=>(0,t.jsxs)(`span`,{style:{display:`inline-flex`,alignItems:`center`,gap:4,padding:`2px 8px`,background:`var(--color-neutral-100)`,borderRadius:999,fontFamily:`var(--font-sans)`,fontSize:11.5,color:`var(--c-text)`},children:[d.find(t=>t.value===e)?.label??e,(0,t.jsx)(`span`,{onClick:t=>{t.stopPropagation(),f(e)},style:{cursor:`pointer`,color:`var(--c-text-subtle)`,lineHeight:1},children:`×`})]},e)),(0,t.jsx)(`span`,{style:{marginLeft:`auto`,fontSize:10,color:`var(--c-text-subtle)`,flexShrink:0},children:`▾`})]}),children:d.map(e=>(0,t.jsx)(i,{label:e.label,selected:n.includes(e.value),onClick:()=>f(e.value),checkbox:!0},e.value))})}function s(e,n){if(!n)return e;let r=e.toLowerCase().indexOf(n.toLowerCase());return r<0?e:(0,t.jsxs)(t.Fragment,{children:[e.slice(0,r),(0,t.jsx)(`b`,{style:{background:`#fff4d6`,color:`var(--c-text)`,fontWeight:700},children:e.slice(r,r+n.length)}),e.slice(r+n.length)]})}function c({value:r,onChange:i,options:a,placeholder:o=`Search…`}){let[c,l]=(0,e.useState)(r),[u,d]=(0,e.useState)(!1),f=(0,e.useRef)(null),p=(0,e.useRef)(null),m=(0,e.useRef)(null),[h,g]=(0,e.useState)({top:0,left:0,width:0}),_=a.map(e=>typeof e==`string`?{value:e,label:e}:e).filter(e=>e.label.toLowerCase().includes(c.toLowerCase())),v=()=>{let e=f.current?.getBoundingClientRect();e&&g({top:e.bottom+window.scrollY+4,left:e.left+window.scrollX,width:e.width}),d(!0)};return(0,e.useEffect)(()=>{if(!u)return;let e=e=>{!m.current?.contains(e.target)&&!f.current?.contains(e.target)&&d(!1)},t=e=>{e.key===`Escape`&&d(!1)};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[u]),(0,t.jsxs)(`div`,{ref:f,children:[(0,t.jsx)(`input`,{ref:p,value:c,onChange:e=>{l(e.target.value),v()},onFocus:v,placeholder:o,style:{width:`100%`,padding:`8px 12px`,border:`1px solid ${u?`var(--c-text)`:`var(--c-border)`}`,borderRadius:6,fontFamily:`var(--font-sans)`,fontSize:13,color:`var(--c-text)`,outline:`none`,boxSizing:`border-box`,boxShadow:u?`0 0 0 3px rgba(47,56,67,0.08)`:`none`,background:`var(--c-surface)`}}),u&&(0,n.createPortal)((0,t.jsx)(`div`,{ref:m,style:{position:`absolute`,top:h.top,left:h.left,width:h.width,background:`var(--c-surface)`,border:`1px solid var(--c-border)`,borderRadius:8,boxShadow:`0 4px 12px rgba(47,56,67,0.10)`,padding:4,zIndex:1100,maxHeight:200,overflowY:`auto`},children:_.length===0?(0,t.jsx)(`div`,{style:{padding:`8px 10px`,fontSize:12,color:`var(--c-text-subtle)`,fontFamily:`var(--font-sans)`},children:`No matches`}):_.map(e=>(0,t.jsx)(`div`,{onClick:()=>{i(e.value),l(e.label),d(!1)},style:{padding:`6px 10px`,borderRadius:4,cursor:`pointer`,fontFamily:`var(--font-mono)`,fontSize:12,color:`var(--c-text)`},onMouseEnter:e=>{e.currentTarget.style.background=`var(--c-elevated)`},onMouseLeave:e=>{e.currentTarget.style.background=`transparent`},children:s(e.label,c)},e.value))}),document.body)]})}exports.Combobox=c,exports.MultiSelect=o,exports.Select=a;
2
+ //# sourceMappingURL=index16.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index16.cjs","names":[],"sources":["../src/components/Select.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\n\n// ── Shared dropdown shell ──────────────────────────────────────────────────\n\ninterface DropdownShellProps {\n triggerContent: ReactNode\n open: boolean\n onOpen: () => void\n triggerRef: React.RefObject<HTMLDivElement | null>\n children: ReactNode\n minWidth?: number\n}\n\nfunction DropdownShell({ triggerContent, open, onOpen, triggerRef, children, minWidth = 200 }: DropdownShellProps) {\n const menuRef = useRef<HTMLDivElement>(null)\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 })\n\n const handleOpen = () => {\n const rect = triggerRef.current?.getBoundingClientRect()\n if (!rect) return\n setPos({ top: rect.bottom + window.scrollY + 4, left: rect.left + window.scrollX, width: rect.width })\n onOpen()\n }\n\n useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node) && !triggerRef.current?.contains(e.target as Node)) {\n onOpen() // caller's toggle closes\n }\n }\n const onEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') onOpen() }\n document.addEventListener('mousedown', handler)\n document.addEventListener('keydown', onEsc)\n return () => { document.removeEventListener('mousedown', handler); document.removeEventListener('keydown', onEsc) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open])\n\n return (\n <>\n <div ref={triggerRef} onClick={handleOpen} style={{ cursor: 'pointer' }}>\n {triggerContent}\n </div>\n {open && createPortal(\n <div ref={menuRef} style={{\n position: 'absolute',\n top: pos.top,\n left: pos.left,\n minWidth: Math.max(pos.width, minWidth),\n background: 'var(--c-surface)',\n border: '1px solid var(--c-border)',\n borderRadius: 8,\n boxShadow: '0 4px 12px rgba(47,56,67,0.10)',\n padding: 4,\n zIndex: 1100,\n maxHeight: 240,\n overflowY: 'auto',\n }}>\n {children}\n </div>,\n document.body\n )}\n </>\n )\n}\n\nfunction OptionItem({ label, selected, onClick, checkbox }: { label: string; selected: boolean; onClick: () => void; checkbox?: boolean }) {\n return (\n <div\n onClick={onClick}\n style={{\n padding: '6px 10px',\n borderRadius: 4,\n cursor: 'pointer',\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: 'var(--c-text)',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n background: !checkbox && selected ? '#fff4d6' : 'transparent',\n }}\n onMouseEnter={e => { e.currentTarget.style.background = !checkbox && selected ? '#fff4d6' : 'var(--c-elevated)' }}\n onMouseLeave={e => { e.currentTarget.style.background = !checkbox && selected ? '#fff4d6' : 'transparent' }}\n >\n {checkbox ? (\n <span style={{\n width: 14, height: 14, borderRadius: 3, flexShrink: 0,\n border: `1.5px solid ${selected ? 'var(--c-text)' : 'var(--c-border-strong)'}`,\n background: selected ? 'var(--c-text)' : 'var(--c-surface)',\n color: '#fff', fontSize: 10, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',\n }}>\n {selected ? '✓' : ''}\n </span>\n ) : (\n <span style={{ width: 14, color: 'var(--c-amber)', fontWeight: 700 }}>{selected ? '✓' : ''}</span>\n )}\n <span>{label}</span>\n </div>\n )\n}\n\n// ── Select ─────────────────────────────────────────────────────────────────\n\ninterface SelectProps {\n value: string\n onChange: (v: string) => void\n options: string[] | Array<{ value: string; label: string }>\n placeholder?: string\n disabled?: boolean\n}\n\nexport function Select({ value, onChange, options, placeholder = 'Select…', disabled }: SelectProps) {\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null!)\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n const selected = opts.find(o => o.value === value)\n\n return (\n <DropdownShell\n triggerRef={ref}\n open={open}\n onOpen={() => !disabled && setOpen(o => !o)}\n triggerContent={\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '8px 12px',\n background: 'var(--c-surface)',\n border: `1px solid ${open ? 'var(--c-text)' : 'var(--c-border)'}`,\n borderRadius: 6,\n fontSize: 13,\n fontFamily: 'var(--font-sans)',\n color: selected ? 'var(--c-text)' : 'var(--c-text-muted)',\n boxShadow: open ? '0 0 0 3px rgba(47,56,67,0.08)' : 'none',\n opacity: disabled ? 0.5 : 1,\n }}>\n <span style={{ flex: 1 }}>{selected?.label ?? placeholder}</span>\n <span style={{ fontSize: 10, color: 'var(--c-text-subtle)', transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 160ms' }}>▾</span>\n </div>\n }\n >\n {opts.map(o => (\n <OptionItem\n key={o.value}\n label={o.label}\n selected={o.value === value}\n onClick={() => { onChange(o.value); setOpen(false) }}\n />\n ))}\n </DropdownShell>\n )\n}\n\n// ── MultiSelect ────────────────────────────────────────────────────────────\n\ninterface MultiSelectProps {\n values: string[]\n onChange: (v: string[]) => void\n options: string[] | Array<{ value: string; label: string }>\n placeholder?: string\n}\n\nexport function MultiSelect({ values, onChange, options, placeholder = 'Select…' }: MultiSelectProps) {\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null!)\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n\n const toggle = (v: string) =>\n onChange(values.includes(v) ? values.filter(x => x !== v) : [...values, v])\n\n return (\n <DropdownShell\n triggerRef={ref}\n open={open}\n onOpen={() => setOpen(o => !o)}\n triggerContent={\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n flexWrap: 'wrap',\n padding: '6px 10px',\n background: 'var(--c-surface)',\n border: `1px solid ${open ? 'var(--c-text)' : 'var(--c-border)'}`,\n borderRadius: 6,\n minHeight: 36,\n cursor: 'pointer',\n boxShadow: open ? '0 0 0 3px rgba(47,56,67,0.08)' : 'none',\n }}>\n {values.length === 0\n ? <span style={{ fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--c-text-muted)' }}>{placeholder}</span>\n : values.map(v => {\n const label = opts.find(o => o.value === v)?.label ?? v\n return (\n <span key={v} style={{\n display: 'inline-flex', alignItems: 'center', gap: 4,\n padding: '2px 8px', background: 'var(--color-neutral-100)',\n borderRadius: 999, fontFamily: 'var(--font-sans)', fontSize: 11.5, color: 'var(--c-text)',\n }}>\n {label}\n <span onClick={e => { e.stopPropagation(); toggle(v) }} style={{ cursor: 'pointer', color: 'var(--c-text-subtle)', lineHeight: 1 }}>×</span>\n </span>\n )\n })}\n <span style={{ marginLeft: 'auto', fontSize: 10, color: 'var(--c-text-subtle)', flexShrink: 0 }}>▾</span>\n </div>\n }\n >\n {opts.map(o => (\n <OptionItem\n key={o.value}\n label={o.label}\n selected={values.includes(o.value)}\n onClick={() => toggle(o.value)}\n checkbox\n />\n ))}\n </DropdownShell>\n )\n}\n\n// ── Combobox ───────────────────────────────────────────────────────────────\n\ninterface ComboboxProps {\n value: string\n onChange: (v: string) => void\n options: string[] | Array<{ value: string; label: string }>\n placeholder?: string\n}\n\nfunction highlight(text: string, query: string): ReactNode {\n if (!query) return text\n const idx = text.toLowerCase().indexOf(query.toLowerCase())\n if (idx < 0) return text\n return (\n <>\n {text.slice(0, idx)}\n <b style={{ background: '#fff4d6', color: 'var(--c-text)', fontWeight: 700 }}>\n {text.slice(idx, idx + query.length)}\n </b>\n {text.slice(idx + query.length)}\n </>\n )\n}\n\nexport function Combobox({ value, onChange, options, placeholder = 'Search…' }: ComboboxProps) {\n const [q, setQ] = useState(value)\n const [open, setOpen] = useState(false)\n const ref = useRef<HTMLDivElement>(null!)\n const inputRef = useRef<HTMLInputElement>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 })\n\n const opts = options.map(o => typeof o === 'string' ? { value: o, label: o } : o)\n const results = opts.filter(o => o.label.toLowerCase().includes(q.toLowerCase()))\n\n const openDropdown = () => {\n const rect = ref.current?.getBoundingClientRect()\n if (rect) setPos({ top: rect.bottom + window.scrollY + 4, left: rect.left + window.scrollX, width: rect.width })\n setOpen(true)\n }\n\n useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node) && !ref.current?.contains(e.target as Node)) setOpen(false)\n }\n const onEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false) }\n document.addEventListener('mousedown', handler)\n document.addEventListener('keydown', onEsc)\n return () => { document.removeEventListener('mousedown', handler); document.removeEventListener('keydown', onEsc) }\n }, [open])\n\n return (\n <div ref={ref}>\n <input\n ref={inputRef}\n value={q}\n onChange={e => { setQ(e.target.value); openDropdown() }}\n onFocus={openDropdown}\n placeholder={placeholder}\n style={{\n width: '100%',\n padding: '8px 12px',\n border: `1px solid ${open ? 'var(--c-text)' : 'var(--c-border)'}`,\n borderRadius: 6,\n fontFamily: 'var(--font-sans)',\n fontSize: 13,\n color: 'var(--c-text)',\n outline: 'none',\n boxSizing: 'border-box',\n boxShadow: open ? '0 0 0 3px rgba(47,56,67,0.08)' : 'none',\n background: 'var(--c-surface)',\n }}\n />\n {open && createPortal(\n <div ref={menuRef} style={{\n position: 'absolute', top: pos.top, left: pos.left, width: pos.width,\n background: 'var(--c-surface)', border: '1px solid var(--c-border)',\n borderRadius: 8, boxShadow: '0 4px 12px rgba(47,56,67,0.10)',\n padding: 4, zIndex: 1100, maxHeight: 200, overflowY: 'auto',\n }}>\n {results.length === 0\n ? <div style={{ padding: '8px 10px', fontSize: 12, color: 'var(--c-text-subtle)', fontFamily: 'var(--font-sans)' }}>No matches</div>\n : results.map(r => (\n <div\n key={r.value}\n onClick={() => { onChange(r.value); setQ(r.label); setOpen(false) }}\n style={{ padding: '6px 10px', borderRadius: 4, cursor: 'pointer', fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--c-text)' }}\n onMouseEnter={e => { e.currentTarget.style.background = 'var(--c-elevated)' }}\n onMouseLeave={e => { e.currentTarget.style.background = 'transparent' }}\n >\n {highlight(r.label, q)}\n </div>\n ))}\n </div>,\n document.body\n )}\n </div>\n )\n}\n"],"mappings":"6EAcA,SAAS,EAAc,CAAE,iBAAgB,OAAM,SAAQ,aAAY,WAAU,WAAW,KAA2B,CACjH,IAAM,GAAA,EAAA,EAAA,QAAiC,KAAK,CACtC,CAAC,EAAK,IAAA,EAAA,EAAA,UAAmB,CAAE,IAAK,EAAG,KAAM,EAAG,MAAO,EAAG,CAAC,CAuB7D,OAdA,EAAA,EAAA,eAAgB,CACd,GAAI,CAAC,EAAM,OACX,IAAM,EAAW,GAAkB,CAC7B,CAAC,EAAQ,SAAS,SAAS,EAAE,OAAe,EAAI,CAAC,EAAW,SAAS,SAAS,EAAE,OAAe,EACjG,GAAQ,EAGN,EAAS,GAAqB,CAAM,EAAE,MAAQ,UAAU,GAAQ,EAGtE,OAFA,SAAS,iBAAiB,YAAa,EAAQ,CAC/C,SAAS,iBAAiB,UAAW,EAAM,KAC9B,CAAE,SAAS,oBAAoB,YAAa,EAAQ,CAAE,SAAS,oBAAoB,UAAW,EAAM,GAEhH,CAAC,EAAK,CAAC,EAGR,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAY,YAvBD,CACvB,IAAM,EAAO,EAAW,SAAS,uBAAuB,CACnD,IACL,EAAO,CAAE,IAAK,EAAK,OAAS,OAAO,QAAU,EAAG,KAAM,EAAK,KAAO,OAAO,QAAS,MAAO,EAAK,MAAO,CAAC,CACtG,GAAQ,GAmBqC,MAAO,CAAE,OAAQ,UAAW,UACpE,EACG,CAAA,CACL,IAAA,EAAA,EAAA,eACC,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAS,MAAO,CACxB,SAAc,WACd,IAAc,EAAI,IAClB,KAAc,EAAI,KAClB,SAAc,KAAK,IAAI,EAAI,MAAO,EAAS,CAC3C,WAAc,mBACd,OAAc,4BACd,aAAc,EACd,UAAc,iCACd,QAAc,EACd,OAAc,KACd,UAAc,IACd,UAAc,OACf,CACE,WACG,CAAA,CACN,SAAS,KACV,CACA,CAAA,CAAA,CAIP,SAAS,EAAW,CAAE,QAAO,WAAU,UAAS,YAA2F,CACzI,OACE,EAAA,EAAA,MAAC,MAAD,CACW,UACT,MAAO,CACL,QAAc,WACd,aAAc,EACd,OAAc,UACd,WAAc,mBACd,SAAc,GACd,MAAc,gBACd,QAAc,OACd,WAAc,SACd,IAAc,EACd,WAAc,CAAC,GAAY,EAAW,UAAY,cACnD,CACD,aAAc,GAAK,CAAE,EAAE,cAAc,MAAM,WAAa,CAAC,GAAY,EAAW,UAAY,qBAC5F,aAAc,GAAK,CAAE,EAAE,cAAc,MAAM,WAAa,CAAC,GAAY,EAAW,UAAY,wBAf9F,CAiBG,GACC,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CACX,MAAO,GAAI,OAAQ,GAAI,aAAc,EAAG,WAAY,EACpD,OAAQ,eAAe,EAAW,gBAAkB,2BACpD,WAAY,EAAW,gBAAkB,mBACzC,MAAO,OAAQ,SAAU,GAAI,QAAS,cAAe,WAAY,SAAU,eAAgB,SAC5F,UACE,EAAW,IAAM,GACb,CAAA,EAEP,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,MAAO,GAAI,MAAO,iBAAkB,WAAY,IAAK,UAAG,EAAW,IAAM,GAAU,CAAA,EAEpG,EAAA,EAAA,KAAC,OAAD,CAAA,SAAO,EAAa,CAAA,CAChB,GAcV,SAAgB,EAAO,CAAE,QAAO,WAAU,UAAS,cAAc,UAAW,YAAyB,CACnG,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,GAAM,CACjC,GAAA,EAAA,EAAA,QAA6B,KAAM,CACnC,EAAO,EAAQ,IAAI,GAAK,OAAO,GAAM,SAAW,CAAE,MAAO,EAAG,MAAO,EAAG,CAAG,EAAE,CAC3E,EAAW,EAAK,KAAK,GAAK,EAAE,QAAU,EAAM,CAElD,OACE,EAAA,EAAA,KAAC,EAAD,CACE,WAAY,EACN,OACN,WAAc,CAAC,GAAY,EAAQ,GAAK,CAAC,EAAE,CAC3C,gBACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CACV,QAAc,OACd,WAAc,SACd,IAAc,EACd,QAAc,WACd,WAAc,mBACd,OAAc,aAAa,EAAO,gBAAkB,oBACpD,aAAc,EACd,SAAc,GACd,WAAc,mBACd,MAAc,EAAW,gBAAkB,sBAC3C,UAAc,EAAO,gCAAkC,OACvD,QAAc,EAAW,GAAM,EAChC,UAbD,EAcE,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,KAAM,EAAG,UAAG,GAAU,OAAS,EAAmB,CAAA,EACjE,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,SAAU,GAAI,MAAO,uBAAwB,UAAW,EAAO,iBAAmB,OAAQ,WAAY,kBAAmB,UAAE,IAAQ,CAAA,CAC9I,YAGP,EAAK,IAAI,IACR,EAAA,EAAA,KAAC,EAAD,CAEE,MAAO,EAAE,MACT,SAAU,EAAE,QAAU,EACtB,YAAe,CAAE,EAAS,EAAE,MAAM,CAAE,EAAQ,GAAM,EAClD,CAJK,EAAE,MAIP,CACF,CACY,CAAA,CAapB,SAAgB,EAAY,CAAE,SAAQ,WAAU,UAAS,cAAc,WAA+B,CACpG,GAAM,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,GAAM,CACjC,GAAA,EAAA,EAAA,QAA6B,KAAM,CACnC,EAAO,EAAQ,IAAI,GAAK,OAAO,GAAM,SAAW,CAAE,MAAO,EAAG,MAAO,EAAG,CAAG,EAAE,CAE3E,EAAU,GACd,EAAS,EAAO,SAAS,EAAE,CAAG,EAAO,OAAO,GAAK,IAAM,EAAE,CAAG,CAAC,GAAG,EAAQ,EAAE,CAAC,CAE7E,OACE,EAAA,EAAA,KAAC,EAAD,CACE,WAAY,EACN,OACN,WAAc,EAAQ,GAAK,CAAC,EAAE,CAC9B,gBACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CACV,QAAc,OACd,WAAc,SACd,IAAc,EACd,SAAc,OACd,QAAc,WACd,WAAc,mBACd,OAAc,aAAa,EAAO,gBAAkB,oBACpD,aAAc,EACd,UAAc,GACd,OAAc,UACd,UAAc,EAAO,gCAAkC,OACxD,UAZD,CAaG,EAAO,SAAW,GACf,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,WAAY,mBAAoB,SAAU,GAAI,MAAO,sBAAuB,UAAG,EAAmB,CAAA,CACjH,EAAO,IAAI,IAGT,EAAA,EAAA,MAAC,OAAD,CAAc,MAAO,CACnB,QAAS,cAAe,WAAY,SAAU,IAAK,EACnD,QAAS,UAAW,WAAY,2BAChC,aAAc,IAAK,WAAY,mBAAoB,SAAU,KAAM,MAAO,gBAC3E,UAJD,CAFY,EAAK,KAAK,GAAK,EAAE,QAAU,EAAE,EAAE,OAAS,GAQlD,EAAA,EAAA,KAAC,OAAD,CAAM,QAAS,GAAK,CAAE,EAAE,iBAAiB,CAAE,EAAO,EAAE,EAAI,MAAO,CAAE,OAAQ,UAAW,MAAO,uBAAwB,WAAY,EAAG,UAAE,IAAQ,CAAA,CACvI,EAPI,EAOJ,CAET,EACJ,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,CAAE,WAAY,OAAQ,SAAU,GAAI,MAAO,uBAAwB,WAAY,EAAG,UAAE,IAAQ,CAAA,CACrG,YAGP,EAAK,IAAI,IACR,EAAA,EAAA,KAAC,EAAD,CAEE,MAAO,EAAE,MACT,SAAU,EAAO,SAAS,EAAE,MAAM,CAClC,YAAe,EAAO,EAAE,MAAM,CAC9B,SAAA,GACA,CALK,EAAE,MAKP,CACF,CACY,CAAA,CAapB,SAAS,EAAU,EAAc,EAA0B,CACzD,GAAI,CAAC,EAAO,OAAO,EACnB,IAAM,EAAM,EAAK,aAAa,CAAC,QAAQ,EAAM,aAAa,CAAC,CAE3D,OADI,EAAM,EAAU,GAElB,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,EAAK,MAAM,EAAG,EAAI,EACnB,EAAA,EAAA,KAAC,IAAD,CAAG,MAAO,CAAE,WAAY,UAAW,MAAO,gBAAiB,WAAY,IAAK,UACzE,EAAK,MAAM,EAAK,EAAM,EAAM,OAAO,CAClC,CAAA,CACH,EAAK,MAAM,EAAM,EAAM,OAAO,CAC9B,CAAA,CAAA,CAIP,SAAgB,EAAS,CAAE,QAAO,WAAU,UAAS,cAAc,WAA4B,CAC7F,GAAM,CAAC,EAAG,IAAA,EAAA,EAAA,UAAiB,EAAM,CAC3B,CAAC,EAAM,IAAA,EAAA,EAAA,UAAoB,GAAM,CACjC,GAAA,EAAA,EAAA,QAA6B,KAAM,CACnC,GAAA,EAAA,EAAA,QAAoC,KAAK,CACzC,GAAA,EAAA,EAAA,QAAiC,KAAK,CACtC,CAAC,EAAK,IAAA,EAAA,EAAA,UAAmB,CAAE,IAAK,EAAG,KAAM,EAAG,MAAO,EAAG,CAAC,CAGvD,EADO,EAAQ,IAAI,GAAK,OAAO,GAAM,SAAW,CAAE,MAAO,EAAG,MAAO,EAAG,CAAG,EAC/D,CAAK,OAAO,GAAK,EAAE,MAAM,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAE3E,MAAqB,CACzB,IAAM,EAAO,EAAI,SAAS,uBAAuB,CAC7C,GAAM,EAAO,CAAE,IAAK,EAAK,OAAS,OAAO,QAAU,EAAG,KAAM,EAAK,KAAO,OAAO,QAAS,MAAO,EAAK,MAAO,CAAC,CAChH,EAAQ,GAAK,EAcf,OAXA,EAAA,EAAA,eAAgB,CACd,GAAI,CAAC,EAAM,OACX,IAAM,EAAW,GAAkB,CAC7B,CAAC,EAAQ,SAAS,SAAS,EAAE,OAAe,EAAI,CAAC,EAAI,SAAS,SAAS,EAAE,OAAe,EAAE,EAAQ,GAAM,EAExG,EAAS,GAAqB,CAAM,EAAE,MAAQ,UAAU,EAAQ,GAAM,EAG5E,OAFA,SAAS,iBAAiB,YAAa,EAAQ,CAC/C,SAAS,iBAAiB,UAAW,EAAM,KAC9B,CAAE,SAAS,oBAAoB,YAAa,EAAQ,CAAE,SAAS,oBAAoB,UAAW,EAAM,GAChH,CAAC,EAAK,CAAC,EAGR,EAAA,EAAA,MAAC,MAAD,CAAU,eAAV,EACE,EAAA,EAAA,KAAC,QAAD,CACE,IAAK,EACL,MAAO,EACP,SAAU,GAAK,CAAE,EAAK,EAAE,OAAO,MAAM,CAAE,GAAc,EACrD,QAAS,EACI,cACb,MAAO,CACL,MAAc,OACd,QAAc,WACd,OAAc,aAAa,EAAO,gBAAkB,oBACpD,aAAc,EACd,WAAc,mBACd,SAAc,GACd,MAAc,gBACd,QAAc,OACd,UAAc,aACd,UAAc,EAAO,gCAAkC,OACvD,WAAc,mBACf,CACD,CAAA,CACD,IAAA,EAAA,EAAA,eACC,EAAA,EAAA,KAAC,MAAD,CAAK,IAAK,EAAS,MAAO,CACxB,SAAU,WAAY,IAAK,EAAI,IAAK,KAAM,EAAI,KAAM,MAAO,EAAI,MAC/D,WAAY,mBAAoB,OAAQ,4BACxC,aAAc,EAAG,UAAW,iCAC5B,QAAS,EAAG,OAAQ,KAAM,UAAW,IAAK,UAAW,OACtD,UACE,EAAQ,SAAW,GAChB,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,CAAE,QAAS,WAAY,SAAU,GAAI,MAAO,uBAAwB,WAAY,mBAAoB,UAAE,aAAgB,CAAA,CAClI,EAAQ,IAAI,IACZ,EAAA,EAAA,KAAC,MAAD,CAEE,YAAe,CAAE,EAAS,EAAE,MAAM,CAAE,EAAK,EAAE,MAAM,CAAE,EAAQ,GAAM,EACjE,MAAO,CAAE,QAAS,WAAY,aAAc,EAAG,OAAQ,UAAW,WAAY,mBAAoB,SAAU,GAAI,MAAO,gBAAiB,CACxI,aAAc,GAAK,CAAE,EAAE,cAAc,MAAM,WAAa,qBACxD,aAAc,GAAK,CAAE,EAAE,cAAc,MAAM,WAAa,wBAEvD,EAAU,EAAE,MAAO,EAAE,CAClB,CAPC,EAAE,MAOH,CACN,CACA,CAAA,CACN,SAAS,KACV,CACG"}