css-drawer 0.1.2 → 0.1.4
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/README.md +57 -3
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +4 -0
- package/dist/react.d.cts.map +1 -1
- package/dist/react.d.mts +4 -0
- package/dist/react.d.mts.map +1 -1
- package/dist/react.mjs +2 -2
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A near drop-in replacement for [Vaul](https://vaul.emilkowal.ski) using native `
|
|
|
12
12
|
| Animation engine | JavaScript | Pure CSS |
|
|
13
13
|
| Nesting | Manual setup | Automatic (CSS `:has()`) |
|
|
14
14
|
| Accessibility | Built-in | Automatic (native `<dialog>` + `inert`) |
|
|
15
|
-
| API | Controlled state | Native refs |
|
|
15
|
+
| API | Controlled state | Native refs or controlled state |
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
@@ -104,7 +104,11 @@ Provides context for direction. Wrap your drawer content.
|
|
|
104
104
|
|
|
105
105
|
### Drawer.Content
|
|
106
106
|
|
|
107
|
-
The dialog element.
|
|
107
|
+
The dialog element. Supports both uncontrolled (refs) and controlled (state) modes.
|
|
108
|
+
|
|
109
|
+
> **Note:** `open`/`onOpenChange` props are on `Content`, not `Root`. This is intentional - `Content` wraps the native `<dialog>` element, so open/close control lives where the element lives. `Root` only provides configuration (direction).
|
|
110
|
+
|
|
111
|
+
#### Uncontrolled Mode (Refs)
|
|
108
112
|
|
|
109
113
|
```tsx
|
|
110
114
|
const ref = useRef<HTMLDialogElement>(null)
|
|
@@ -118,9 +122,29 @@ ref.current?.close()
|
|
|
118
122
|
<Drawer.Content ref={ref}>...</Drawer.Content>
|
|
119
123
|
```
|
|
120
124
|
|
|
125
|
+
#### Controlled Mode (State)
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
129
|
+
|
|
130
|
+
<Drawer.Content open={isOpen} onOpenChange={setIsOpen}>
|
|
131
|
+
...
|
|
132
|
+
</Drawer.Content>
|
|
133
|
+
|
|
134
|
+
// Open programmatically
|
|
135
|
+
<button onClick={() => setIsOpen(true)}>Open</button>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The `onOpenChange` callback fires when:
|
|
139
|
+
- User presses Escape
|
|
140
|
+
- User clicks the backdrop (if `closeOnOutsideClick` is true)
|
|
141
|
+
- You call `setIsOpen(false)`
|
|
142
|
+
|
|
121
143
|
| Prop | Type | Default | Description |
|
|
122
144
|
|------|------|---------|-------------|
|
|
123
|
-
| `ref` | `Ref<HTMLDialogElement>` | - | Ref to control the dialog |
|
|
145
|
+
| `ref` | `Ref<HTMLDialogElement>` | - | Ref to control the dialog (uncontrolled mode) |
|
|
146
|
+
| `open` | `boolean` | - | Controlled open state |
|
|
147
|
+
| `onOpenChange` | `(open: boolean) => void` | - | Called when open state changes |
|
|
124
148
|
| `closeOnOutsideClick` | `boolean` | `true` | Close when clicking outside the drawer |
|
|
125
149
|
| `className` | `string` | - | Additional CSS classes |
|
|
126
150
|
| `...props` | `DialogHTMLAttributes` | - | All native dialog props |
|
|
@@ -360,6 +384,8 @@ const isMobile = useMediaQuery('(max-width: 768px)')
|
|
|
360
384
|
|
|
361
385
|
Drawers automatically stack when opened. No configuration needed.
|
|
362
386
|
|
|
387
|
+
### With Refs
|
|
388
|
+
|
|
363
389
|
```tsx
|
|
364
390
|
const drawer1 = useRef<HTMLDialogElement>(null)
|
|
365
391
|
const drawer2 = useRef<HTMLDialogElement>(null)
|
|
@@ -372,6 +398,34 @@ drawer2.current?.showModal()
|
|
|
372
398
|
// drawer1 automatically scales down and dims
|
|
373
399
|
```
|
|
374
400
|
|
|
401
|
+
### With Controlled State
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
const [settingsOpen, setSettingsOpen] = useState(false)
|
|
405
|
+
const [confirmOpen, setConfirmOpen] = useState(false)
|
|
406
|
+
|
|
407
|
+
<>
|
|
408
|
+
<button onClick={() => setSettingsOpen(true)}>Settings</button>
|
|
409
|
+
|
|
410
|
+
<Drawer.Root>
|
|
411
|
+
<Drawer.Content open={settingsOpen} onOpenChange={setSettingsOpen}>
|
|
412
|
+
<button onClick={() => setConfirmOpen(true)}>Delete Account</button>
|
|
413
|
+
</Drawer.Content>
|
|
414
|
+
</Drawer.Root>
|
|
415
|
+
|
|
416
|
+
<Drawer.Root>
|
|
417
|
+
<Drawer.Content open={confirmOpen} onOpenChange={setConfirmOpen}>
|
|
418
|
+
<button onClick={() => {
|
|
419
|
+
setConfirmOpen(false)
|
|
420
|
+
setSettingsOpen(false)
|
|
421
|
+
}}>
|
|
422
|
+
Confirm
|
|
423
|
+
</button>
|
|
424
|
+
</Drawer.Content>
|
|
425
|
+
</Drawer.Root>
|
|
426
|
+
</>
|
|
427
|
+
```
|
|
428
|
+
|
|
375
429
|
Works up to 5 levels. CSS `:has()` selectors handle the visual stacking.
|
|
376
430
|
|
|
377
431
|
---
|
package/dist/react.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
require('./react.css');
|
|
2
|
-
let e=require(`react`),t=require(`react/jsx-runtime`);if(typeof window<`u`){let e=()=>{let e=Array.from(document.querySelectorAll(`dialog.drawer[open]`));e.forEach((t,n)=>{n===e.length-1?t.removeAttribute(`inert`):t.setAttribute(`inert`,``)})};new MutationObserver(t=>{for(let n of t)if(n.type===`attributes`&&n.attributeName===`open`&&n.target.classList.contains(`drawer`)){e();break}}).observe(document.body,{subtree:!0,attributes:!0,attributeFilter:[`open`]})}const n=(0,e.createContext)({direction:void 0});function r(){return(0,e.useContext)(n)}function i({children:e,direction:r}){return(0,t.jsx)(n.Provider,{value:{direction:r},children:e})}const a=(0,e.forwardRef)(({children:
|
|
2
|
+
let e=require(`react`),t=require(`react/jsx-runtime`);if(typeof window<`u`){let e=()=>{let e=Array.from(document.querySelectorAll(`dialog.drawer[open]`));e.forEach((t,n)=>{n===e.length-1?t.removeAttribute(`inert`):t.setAttribute(`inert`,``)})};new MutationObserver(t=>{for(let n of t)if(n.type===`attributes`&&n.attributeName===`open`&&n.target.classList.contains(`drawer`)){e();break}}).observe(document.body,{subtree:!0,attributes:!0,attributeFilter:[`open`]})}const n=(0,e.createContext)({direction:void 0});function r(){return(0,e.useContext)(n)}function i({children:e,direction:r}){return(0,t.jsx)(n.Provider,{value:{direction:r},children:e})}const a=(0,e.forwardRef)(({children:n,className:i,open:a,onOpenChange:o,closeOnOutsideClick:s=!0,...c},l)=>{let{direction:u}=r(),d=(0,e.useRef)(null),f=l||d;return(0,e.useEffect)(()=>{let e=f.current;e&&(a&&!e.open?(e.showModal(),o?.(!0)):a===!1&&e.open&&e.close())},[a]),(0,t.jsx)(`dialog`,{ref:f,className:`drawer ${i??``}`.trim(),"data-direction":u,onClose:e=>{c.onClose?.(e),o?.(!1)},onClick:e=>{c.onClick?.(e),s&&e.target===e.currentTarget&&e.currentTarget.close()},...c,children:n})});a.displayName=`Drawer.Content`;const o=(0,e.forwardRef)(({className:e,...n},r)=>(0,t.jsx)(`div`,{ref:r,className:`drawer-handle ${e??``}`.trim(),"aria-hidden":`true`,...n}));o.displayName=`Drawer.Handle`;const s=(0,e.forwardRef)((e,n)=>(0,t.jsx)(`h2`,{ref:n,...e}));s.displayName=`Drawer.Title`;const c=(0,e.forwardRef)((e,n)=>(0,t.jsx)(`p`,{ref:n,...e}));c.displayName=`Drawer.Description`;const l={Root:i,Content:a,Handle:o,Title:s,Description:c};exports.Drawer=l;
|
package/dist/react.d.cts
CHANGED
|
@@ -14,6 +14,10 @@ declare function Root({
|
|
|
14
14
|
direction
|
|
15
15
|
}: RootProps): react_jsx_runtime0.JSX.Element;
|
|
16
16
|
interface ContentProps extends Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> {
|
|
17
|
+
/** Controlled open state */
|
|
18
|
+
open?: boolean;
|
|
19
|
+
/** Called when open state changes */
|
|
20
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
21
|
/** Close when clicking outside the drawer (default: true) */
|
|
18
22
|
closeOnOutsideClick?: boolean;
|
|
19
23
|
}
|
package/dist/react.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.cts","names":[],"sources":["../src/react.tsx"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"react.d.cts","names":[],"sources":["../src/react.tsx"],"sourcesContent":[],"mappings":";;;;;KAgDK,SAAA;UAcK,SAAA;YACE;EAfP;EAcK,SAAA,CAAA,EAGI,SAHK;AAGI;iBAGd,IAAA,CAAO;EAAA,QAAA;EAAA;AAAA,CAAA,EAAuB,SAAvB,CAAA,EAAgC,kBAAA,CAAA,GAAA,CAAA,OAAhC;UASN,YAAA,SAAqB,IATL,CASU,wBATV,CAAA,QAAA,CAAA,EAAA,MAAA,CAAA,CAAA;EAAa;EAAS,IAAA,CAAA,EAAA,OAAA;EAAA;EAStC,YAAA,CAAA,EAAa,CAAA,IAAA,EAAA,OAAa,EAAA,GAAA,IAAA;EAqD1B;EAaA,mBAAW,CAAA,EAAA,OAAQ;AAAwB;AAgBrD,UA7BU,WAAA,SAAoB,wBAmC7B,CAAA,KAAA,CAAA,CAAA;UAtBS,UAAA,SAAmB;UAQnB,gBAAA,SAAyB;cAQtB"}
|
package/dist/react.d.mts
CHANGED
|
@@ -14,6 +14,10 @@ declare function Root({
|
|
|
14
14
|
direction
|
|
15
15
|
}: RootProps): react_jsx_runtime0.JSX.Element;
|
|
16
16
|
interface ContentProps extends Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> {
|
|
17
|
+
/** Controlled open state */
|
|
18
|
+
open?: boolean;
|
|
19
|
+
/** Called when open state changes */
|
|
20
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
21
|
/** Close when clicking outside the drawer (default: true) */
|
|
18
22
|
closeOnOutsideClick?: boolean;
|
|
19
23
|
}
|
package/dist/react.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.mts","names":[],"sources":["../src/react.tsx"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"react.d.mts","names":[],"sources":["../src/react.tsx"],"sourcesContent":[],"mappings":";;;;;KAgDK,SAAA;UAcK,SAAA;YACE;EAfP;EAcK,SAAA,CAAA,EAGI,SAHK;AAGI;iBAGd,IAAA,CAAO;EAAA,QAAA;EAAA;AAAA,CAAA,EAAuB,SAAvB,CAAA,EAAgC,kBAAA,CAAA,GAAA,CAAA,OAAhC;UASN,YAAA,SAAqB,IATL,CASU,wBATV,CAAA,QAAA,CAAA,EAAA,MAAA,CAAA,CAAA;EAAa;EAAS,IAAA,CAAA,EAAA,OAAA;EAAA;EAStC,YAAA,CAAA,EAAa,CAAA,IAAA,EAAA,OAAa,EAAA,GAAA,IAAA;EAqD1B;EAaA,mBAAW,CAAA,EAAA,OAAQ;AAAwB;AAgBrD,UA7BU,WAAA,SAAoB,wBAmC7B,CAAA,KAAA,CAAA,CAAA;UAtBS,UAAA,SAAmB;UAQnB,gBAAA,SAAyB;cAQtB"}
|
package/dist/react.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createContext as e,forwardRef as t,useContext as n}from"react";import{jsx as
|
|
2
|
-
if(typeof window<`u`){let e=()=>{let e=Array.from(document.querySelectorAll(`dialog.drawer[open]`));e.forEach((t,n)=>{n===e.length-1?t.removeAttribute(`inert`):t.setAttribute(`inert`,``)})};new MutationObserver(t=>{for(let n of t)if(n.type===`attributes`&&n.attributeName===`open`&&n.target.classList.contains(`drawer`)){e();break}}).observe(document.body,{subtree:!0,attributes:!0,attributeFilter:[`open`]})}const
|
|
1
|
+
import{createContext as e,forwardRef as t,useContext as n,useEffect as r,useRef as i}from"react";import{jsx as a}from"react/jsx-runtime";import './react.css';
|
|
2
|
+
if(typeof window<`u`){let e=()=>{let e=Array.from(document.querySelectorAll(`dialog.drawer[open]`));e.forEach((t,n)=>{n===e.length-1?t.removeAttribute(`inert`):t.setAttribute(`inert`,``)})};new MutationObserver(t=>{for(let n of t)if(n.type===`attributes`&&n.attributeName===`open`&&n.target.classList.contains(`drawer`)){e();break}}).observe(document.body,{subtree:!0,attributes:!0,attributeFilter:[`open`]})}const o=e({direction:void 0});function s(){return n(o)}function c({children:e,direction:t}){return a(o.Provider,{value:{direction:t},children:e})}const l=t(({children:e,className:t,open:n,onOpenChange:o,closeOnOutsideClick:c=!0,...l},u)=>{let{direction:d}=s(),f=i(null),p=u||f;return r(()=>{let e=p.current;e&&(n&&!e.open?(e.showModal(),o?.(!0)):n===!1&&e.open&&e.close())},[n]),a(`dialog`,{ref:p,className:`drawer ${t??``}`.trim(),"data-direction":d,onClose:e=>{l.onClose?.(e),o?.(!1)},onClick:e=>{l.onClick?.(e),c&&e.target===e.currentTarget&&e.currentTarget.close()},...l,children:e})});l.displayName=`Drawer.Content`;const u=t(({className:e,...t},n)=>a(`div`,{ref:n,className:`drawer-handle ${e??``}`.trim(),"aria-hidden":`true`,...t}));u.displayName=`Drawer.Handle`;const d=t((e,t)=>a(`h2`,{ref:t,...e}));d.displayName=`Drawer.Title`;const f=t((e,t)=>a(`p`,{ref:t,...e}));f.displayName=`Drawer.Description`;const p={Root:c,Content:l,Handle:u,Title:d,Description:f};export{p as Drawer};
|
|
3
3
|
//# sourceMappingURL=react.mjs.map
|
package/dist/react.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.mjs","names":[],"sources":["../src/react.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n forwardRef,\n type ReactNode,\n type ComponentPropsWithoutRef,\n} from 'react'\nimport './drawer.css'\n\n/* ===== Auto-enable accessibility for stacked drawers ===== */\nif (typeof window !== 'undefined') {\n const updateInertState = () => {\n const openDrawers = Array.from(\n document.querySelectorAll<HTMLDialogElement>('dialog.drawer[open]')\n )\n openDrawers.forEach((drawer, index) => {\n const isTopmost = index === openDrawers.length - 1\n if (isTopmost) {\n drawer.removeAttribute('inert')\n } else {\n drawer.setAttribute('inert', '')\n }\n })\n }\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'open' &&\n (mutation.target as HTMLElement).classList.contains('drawer')\n ) {\n updateInertState()\n break\n }\n }\n })\n\n observer.observe(document.body, {\n subtree: true,\n attributes: true,\n attributeFilter: ['open'],\n })\n}\n\n/* ===== Types ===== */\ntype Direction = 'bottom' | 'top' | 'left' | 'right'\n\ninterface DrawerContextValue {\n direction?: Direction\n}\n\n/* ===== Context ===== */\nconst DrawerContext = createContext<DrawerContextValue>({ direction: undefined })\n\nfunction useDrawerContext() {\n return useContext(DrawerContext)\n}\n\n/* ===== Root ===== */\ninterface RootProps {\n children: ReactNode\n /** Direction the drawer opens from */\n direction?: Direction\n}\n\nfunction Root({ children, direction }: RootProps) {\n return (\n <DrawerContext.Provider value={{ direction }}>\n {children}\n </DrawerContext.Provider>\n )\n}\n\n/* ===== Content ===== */\ninterface ContentProps extends Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> {\n /** Close when clicking outside the drawer (default: true) */\n closeOnOutsideClick?: boolean\n}\n\nconst Content = forwardRef<HTMLDialogElement, ContentProps>(\n ({ children, className, closeOnOutsideClick = true, ...props }, ref) => {\n const { direction } = useDrawerContext()\n\n return (\n <dialog\n ref={
|
|
1
|
+
{"version":3,"file":"react.mjs","names":[],"sources":["../src/react.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n forwardRef,\n useEffect,\n useRef,\n type ReactNode,\n type ComponentPropsWithoutRef,\n} from 'react'\nimport './drawer.css'\n\n/* ===== Auto-enable accessibility for stacked drawers ===== */\nif (typeof window !== 'undefined') {\n const updateInertState = () => {\n const openDrawers = Array.from(\n document.querySelectorAll<HTMLDialogElement>('dialog.drawer[open]')\n )\n openDrawers.forEach((drawer, index) => {\n const isTopmost = index === openDrawers.length - 1\n if (isTopmost) {\n drawer.removeAttribute('inert')\n } else {\n drawer.setAttribute('inert', '')\n }\n })\n }\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'open' &&\n (mutation.target as HTMLElement).classList.contains('drawer')\n ) {\n updateInertState()\n break\n }\n }\n })\n\n observer.observe(document.body, {\n subtree: true,\n attributes: true,\n attributeFilter: ['open'],\n })\n}\n\n/* ===== Types ===== */\ntype Direction = 'bottom' | 'top' | 'left' | 'right'\n\ninterface DrawerContextValue {\n direction?: Direction\n}\n\n/* ===== Context ===== */\nconst DrawerContext = createContext<DrawerContextValue>({ direction: undefined })\n\nfunction useDrawerContext() {\n return useContext(DrawerContext)\n}\n\n/* ===== Root ===== */\ninterface RootProps {\n children: ReactNode\n /** Direction the drawer opens from */\n direction?: Direction\n}\n\nfunction Root({ children, direction }: RootProps) {\n return (\n <DrawerContext.Provider value={{ direction }}>\n {children}\n </DrawerContext.Provider>\n )\n}\n\n/* ===== Content ===== */\ninterface ContentProps extends Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> {\n /** Controlled open state */\n open?: boolean\n /** Called when open state changes */\n onOpenChange?: (open: boolean) => void\n /** Close when clicking outside the drawer (default: true) */\n closeOnOutsideClick?: boolean\n}\n\nconst Content = forwardRef<HTMLDialogElement, ContentProps>(\n ({ children, className, open, onOpenChange, closeOnOutsideClick = true, ...props }, ref) => {\n const { direction } = useDrawerContext()\n const internalRef = useRef<HTMLDialogElement>(null)\n const dialogRef = (ref as React.RefObject<HTMLDialogElement>) || internalRef\n\n useEffect(() => {\n const dialog = dialogRef.current\n if (!dialog) return\n\n if (open && !dialog.open) {\n dialog.showModal()\n onOpenChange?.(true)\n } else if (open === false && dialog.open) {\n dialog.close()\n }\n }, [open])\n\n return (\n <dialog\n ref={dialogRef}\n className={`drawer ${className ?? ''}`.trim()}\n data-direction={direction}\n onClose={(e) => {\n props.onClose?.(e)\n onOpenChange?.(false)\n }}\n onClick={(e) => {\n props.onClick?.(e)\n // Backdrop click - only if clicking the dialog element itself\n if (closeOnOutsideClick && e.target === e.currentTarget) {\n e.currentTarget.close()\n }\n }}\n {...props}\n >\n {children}\n </dialog>\n )\n }\n)\nContent.displayName = 'Drawer.Content'\n\n/* ===== Handle ===== */\ninterface HandleProps extends ComponentPropsWithoutRef<'div'> {}\n\nconst Handle = forwardRef<HTMLDivElement, HandleProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={`drawer-handle ${className ?? ''}`.trim()}\n aria-hidden=\"true\"\n {...props}\n />\n))\nHandle.displayName = 'Drawer.Handle'\n\n/* ===== Title ===== */\ninterface TitleProps extends ComponentPropsWithoutRef<'h2'> {}\n\nconst Title = forwardRef<HTMLHeadingElement, TitleProps>((props, ref) => (\n <h2 ref={ref} {...props} />\n))\nTitle.displayName = 'Drawer.Title'\n\n/* ===== Description ===== */\ninterface DescriptionProps extends ComponentPropsWithoutRef<'p'> {}\n\nconst Description = forwardRef<HTMLParagraphElement, DescriptionProps>((props, ref) => (\n <p ref={ref} {...props} />\n))\nDescription.displayName = 'Drawer.Description'\n\n/* ===== Namespace Export ===== */\nexport const Drawer = {\n Root,\n Content,\n Handle,\n Title,\n Description,\n}\n\nexport type {\n RootProps as DrawerRootProps,\n ContentProps as DrawerContentProps,\n HandleProps as DrawerHandleProps,\n TitleProps as DrawerTitleProps,\n DescriptionProps as DrawerDescriptionProps,\n Direction as DrawerDirection,\n}\n"],"mappings":"yIAYA,GAAI,OAAO,OAAW,IAAa,CACjC,IAAM,MAAyB,CAC7B,IAAM,EAAc,MAAM,KACxB,SAAS,iBAAoC,sBAAsB,CACpE,CACD,EAAY,SAAS,EAAQ,IAAU,CACnB,IAAU,EAAY,OAAS,EAE/C,EAAO,gBAAgB,QAAQ,CAE/B,EAAO,aAAa,QAAS,GAAG,EAElC,EAGa,IAAI,iBAAkB,GAAc,CACnD,IAAK,IAAM,KAAY,EACrB,GACE,EAAS,OAAS,cAClB,EAAS,gBAAkB,QAC1B,EAAS,OAAuB,UAAU,SAAS,SAAS,CAC7D,CACA,GAAkB,CAClB,QAGJ,CAEO,QAAQ,SAAS,KAAM,CAC9B,QAAS,GACT,WAAY,GACZ,gBAAiB,CAAC,OAAO,CAC1B,CAAC,CAWJ,MAAM,EAAgB,EAAkC,CAAE,UAAW,IAAA,GAAW,CAAC,CAEjF,SAAS,GAAmB,CAC1B,OAAO,EAAW,EAAc,CAUlC,SAAS,EAAK,CAAE,WAAU,aAAwB,CAChD,OACE,EAAC,EAAc,SAAA,CAAS,MAAO,CAAE,YAAW,CACzC,YACsB,CAc7B,MAAM,EAAU,GACb,CAAE,WAAU,YAAW,OAAM,eAAc,sBAAsB,GAAM,GAAG,GAAS,IAAQ,CAC1F,GAAM,CAAE,aAAc,GAAkB,CAClC,EAAc,EAA0B,KAAK,CAC7C,EAAa,GAA8C,EAcjE,OAZA,MAAgB,CACd,IAAM,EAAS,EAAU,QACpB,IAED,GAAQ,CAAC,EAAO,MAClB,EAAO,WAAW,CAClB,IAAe,GAAK,EACX,IAAS,IAAS,EAAO,MAClC,EAAO,OAAO,GAEf,CAAC,EAAK,CAAC,CAGR,EAAC,SAAA,CACC,IAAK,EACL,UAAW,UAAU,GAAa,KAAK,MAAM,CAC7C,iBAAgB,EAChB,QAAU,GAAM,CACd,EAAM,UAAU,EAAE,CAClB,IAAe,GAAM,EAEvB,QAAU,GAAM,CACd,EAAM,UAAU,EAAE,CAEd,GAAuB,EAAE,SAAW,EAAE,eACxC,EAAE,cAAc,OAAO,EAG3B,GAAI,EAEH,YACM,EAGd,CACD,EAAQ,YAAc,iBAKtB,MAAM,EAAS,GAAyC,CAAE,YAAW,GAAG,GAAS,IAC/E,EAAC,MAAA,CACM,MACL,UAAW,iBAAiB,GAAa,KAAK,MAAM,CACpD,cAAY,OACZ,GAAI,GACJ,CACF,CACF,EAAO,YAAc,gBAKrB,MAAM,EAAQ,GAA4C,EAAO,IAC/D,EAAC,KAAA,CAAQ,MAAK,GAAI,GAAS,CAC3B,CACF,EAAM,YAAc,eAKpB,MAAM,EAAc,GAAoD,EAAO,IAC7E,EAAC,IAAA,CAAO,MAAK,GAAI,GAAS,CAC1B,CACF,EAAY,YAAc,qBAG1B,MAAa,EAAS,CACpB,OACA,UACA,SACA,QACA,cACD"}
|