refract-ui 0.0.0 → 1.0.2
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 +14 -3
- package/dist/RefractProvider-Bzz4G22S.cjs +25 -0
- package/dist/RefractProvider-Bzz4G22S.cjs.map +1 -0
- package/dist/RefractProvider-D__A8gQl.js +238 -0
- package/dist/RefractProvider-D__A8gQl.js.map +1 -0
- package/dist/assets/iphone-11.glb +0 -0
- package/dist/assets/macbook-pro.glb +0 -0
- package/dist/carousel.cjs +48 -1
- package/dist/carousel.cjs.map +1 -1
- package/dist/carousel.js +300 -0
- package/dist/carousel.js.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +10 -0
- package/dist/components/Breadcrumbs/index.d.ts +2 -0
- package/dist/components/Button/Button.d.ts +22 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Carousel/Carousel.d.ts +21 -0
- package/dist/components/Carousel/index.d.ts +1 -0
- package/dist/components/Divider/Divider.d.ts +12 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Heading/Heading.d.ts +9 -0
- package/dist/components/Heading/index.d.ts +2 -0
- package/dist/components/Icon/Icon.d.ts +30 -0
- package/dist/components/Icon/index.d.ts +2 -0
- package/dist/components/Image/Image.d.ts +27 -0
- package/dist/components/Image/index.d.ts +1 -0
- package/dist/components/Input/Input.d.ts +21 -0
- package/dist/components/Input/TextArea.d.ts +11 -0
- package/dist/components/Input/index.d.ts +2 -0
- package/dist/components/Link/Link.d.ts +10 -0
- package/dist/components/Link/index.d.ts +1 -0
- package/dist/components/LinkProvider/LinkProvider.d.ts +11 -0
- package/dist/components/LinkProvider/index.d.ts +1 -0
- package/dist/components/List/List.d.ts +11 -0
- package/dist/components/List/index.d.ts +1 -0
- package/dist/components/Loader/Loader.d.ts +6 -0
- package/dist/components/Loader/index.d.ts +2 -0
- package/dist/components/Model/Model.d.ts +40 -0
- package/dist/components/Model/deviceModels.d.ts +29 -0
- package/dist/components/Model/index.d.ts +2 -0
- package/dist/components/RefractProvider/RefractProvider.d.ts +20 -0
- package/dist/components/RefractProvider/index.d.ts +1 -0
- package/dist/components/ScrambleReveal/ScrambleReveal.d.ts +9 -0
- package/dist/components/ScrambleReveal/index.d.ts +1 -0
- package/dist/components/Section/Section.d.ts +8 -0
- package/dist/components/Section/index.d.ts +1 -0
- package/dist/components/SegmentedControl/SegmentedControl.d.ts +15 -0
- package/dist/components/SegmentedControl/index.d.ts +1 -0
- package/dist/components/Table/Table.d.ts +11 -0
- package/dist/components/Table/index.d.ts +1 -0
- package/dist/components/ThemeProvider/ThemeProvider.d.ts +21 -0
- package/dist/components/ThemeProvider/index.d.ts +5 -0
- package/dist/components/ThemeProvider/theme.d.ts +138 -0
- package/dist/components/ThemeProvider/useTheme.d.ts +2 -0
- package/dist/components/Transition/Transition.d.ts +19 -0
- package/dist/components/Transition/index.d.ts +1 -0
- package/dist/components/VisuallyHidden/VisuallyHidden.d.ts +10 -0
- package/dist/components/VisuallyHidden/index.d.ts +2 -0
- package/dist/components/Wordmark/Wordmark.d.ts +5 -0
- package/dist/components/Wordmark/index.d.ts +2 -0
- package/dist/entries/carousel.d.ts +1 -1
- package/dist/entries/model.d.ts +1 -1
- package/dist/hooks/useFormInput.d.ts +11 -0
- package/dist/hooks/useFps.d.ts +8 -0
- package/dist/hooks/useHasMounted.d.ts +1 -0
- package/dist/hooks/useInViewport.d.ts +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.js +914 -45
- package/dist/index.js.map +1 -1
- package/dist/model.cjs +4 -1
- package/dist/model.cjs.map +1 -1
- package/dist/model.js +267 -0
- package/dist/model.js.map +1 -1
- package/dist/style-CWBkJEps.cjs +2 -0
- package/dist/style-CWBkJEps.cjs.map +1 -0
- package/dist/style-uMN7vipQ.js +96 -0
- package/dist/style-uMN7vipQ.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/three-CWsiEOQZ.js +48 -0
- package/dist/three-CWsiEOQZ.js.map +1 -0
- package/dist/three-aeLbW1yA.cjs +2 -0
- package/dist/three-aeLbW1yA.cjs.map +1 -0
- package/dist/tokens.css +1 -0
- package/dist/utils/delay.d.ts +1 -0
- package/dist/utils/image.d.ts +31 -0
- package/dist/utils/three.d.ts +29 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -4,7 +4,16 @@ Themeable React component library — extracted from [parammehta.com](https://pa
|
|
|
4
4
|
Primitives, form controls, and a couple of Three.js pieces (device models, a
|
|
5
5
|
displacement carousel), with no Next.js or portfolio-specific coupling.
|
|
6
6
|
|
|
7
|
-
Storybook: https://storybook.parammehta.com
|
|
7
|
+
Storybook: https://storybook.parammehta.com — start on the Introduction and Theming pages
|
|
8
|
+
for an overview and the token reference.
|
|
9
|
+
|
|
10
|
+
## Components
|
|
11
|
+
|
|
12
|
+
Text, Heading, Section, List, Divider, Table, VisuallyHidden, Transition, Loader, Icon,
|
|
13
|
+
SegmentedControl, Input, TextArea, Button, Link, Breadcrumbs, ScrambleReveal, Image, Wordmark,
|
|
14
|
+
ThemeProvider, LinkProvider, RefractProvider — all from the default `refract-ui` entry.
|
|
15
|
+
`Model` and `Carousel` are separate entries (`refract-ui/model`, `refract-ui/carousel`) so
|
|
16
|
+
`three`/`three-stdlib` never land in a bundle that doesn't use them.
|
|
8
17
|
|
|
9
18
|
## Install
|
|
10
19
|
|
|
@@ -31,8 +40,10 @@ function App() {
|
|
|
31
40
|
}
|
|
32
41
|
```
|
|
33
42
|
|
|
34
|
-
Required
|
|
35
|
-
shared keyframes)
|
|
43
|
+
Required stylesheets: `refract-ui/styles.css` (component styles + a couple of
|
|
44
|
+
shared keyframes) and `refract-ui/tokens.css` (the CSS custom properties
|
|
45
|
+
components read from — see the Storybook Theming page for the full
|
|
46
|
+
reference). Optional: `refract-ui/reset.css` (a minimal CSS reset) and
|
|
36
47
|
`refract-ui/media.css` (the breakpoint contract as `@custom-media`, for
|
|
37
48
|
consumers running their own `postcss-preset-env`).
|
|
38
49
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";"use strict";const a=require("react/jsx-runtime"),n=require("react"),e=require("./style-CWBkJEps.cjs"),R=n.forwardRef((t,o)=>a.jsx("a",{...t,ref:o}));R.displayName="DefaultLink";const b=n.createContext(R),z=({component:t,children:o})=>a.jsx(b.Provider,{value:t,children:o}),B=()=>n.useContext(b);function k(){const[t,o]=n.useState(!1);return n.useEffect(()=>{o(!0)},[]),t}const M={rgbBlack:"0 0 0",rgbWhite:"255 255 255",bezierFastoutSlowin:"cubic-bezier(0.4, 0.0, 0.2, 1)",durationXS:"200ms",durationS:"300ms",durationM:"400ms",durationL:"600ms",durationXL:"800ms",systemFontStack:"system-ui, -apple-system, BlinkMacSystemFont, San Francisco, Roboto, Segoe UI, Ubuntu, Helvetica Neue, sans-serif",fontStack:"var(--brandFontStack, var(--systemFontStack))",monoFontStack:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace",devanagariFontStack:"Kohinoor Devanagari, Devanagari Sangam MN, Nirmala UI, Noto Sans Devanagari, sans-serif",fontWeightRegular:400,fontWeightMedium:500,fontWeightBold:700,fontSizeH0:e.pxToRem(140),fontSizeH1:e.pxToRem(100),fontSizeH2:e.pxToRem(58),fontSizeH3:e.pxToRem(38),fontSizeH4:e.pxToRem(28),fontSizeH5:e.pxToRem(24),fontSizeBodyXL:e.pxToRem(22),fontSizeBodyL:e.pxToRem(20),fontSizeBodyM:e.pxToRem(18),fontSizeBodyS:e.pxToRem(16),fontSizeBodyXS:e.pxToRem(14),lineHeightTitle:"1.1",lineHeightBody:"1.6",maxWidthS:"540px",maxWidthM:"720px",maxWidthL:"1096px",maxWidthXL:"1680px",spaceOuter:"64px",spaceXS:"4px",spaceS:"8px",spaceM:"16px",spaceL:"24px",spaceXL:"32px",space2XL:"48px",space3XL:"64px",space4XL:"96px",space5XL:"128px",zIndex0:0,zIndex1:4,zIndex2:8,zIndex3:16,zIndex4:32,zIndex5:64},C={fontSizeH0:e.pxToRem(120),fontSizeH1:e.pxToRem(80)},P={maxWidthS:"480px",maxWidthM:"640px",maxWidthL:"1000px",maxWidthXL:"1100px",spaceOuter:"48px",fontSizeH0:e.pxToRem(100),fontSizeH1:e.pxToRem(70),fontSizeH2:e.pxToRem(50),fontSizeH3:e.pxToRem(36),fontSizeH4:e.pxToRem(26),fontSizeH5:e.pxToRem(22)},j={fontSizeH0:e.pxToRem(80),fontSizeH1:e.pxToRem(60),fontSizeH2:e.pxToRem(48),fontSizeH3:e.pxToRem(32),fontSizeH4:e.pxToRem(24),fontSizeH5:e.pxToRem(20)},W={spaceOuter:"24px",fontSizeH0:e.pxToRem(56),fontSizeH1:e.pxToRem(40),fontSizeH2:e.pxToRem(34),fontSizeH3:e.pxToRem(28),fontSizeH4:e.pxToRem(22),fontSizeH5:e.pxToRem(18),fontSizeBodyL:e.pxToRem(17),fontSizeBodyM:e.pxToRem(16),fontSizeBodyS:e.pxToRem(14)},X={spaceOuter:"16px",fontSizeH0:e.pxToRem(42),fontSizeH1:e.pxToRem(38),fontSizeH2:e.pxToRem(28),fontSizeH3:e.pxToRem(24),fontSizeH4:e.pxToRem(20)},I={themeId:"dark",rgbBackground:"17 17 17",rgbBackgroundLight:"26 26 26",rgbPrimary:"251 146 60",rgbAccent:"251 146 60",rgbText:"255 255 255",rgbError:"255 55 102",colorTextName:"246 240 228",colorTextTitle:"rgb(var(--rgbText) / 1)",colorTextBody:"rgb(var(--rgbText) / 0.8)",colorTextLight:"rgb(var(--rgbText) / 0.6)"},N={themeId:"light",rgbBackground:"242 242 242",rgbBackgroundLight:"255 255 255",rgbPrimary:"168 85 8",rgbAccent:"255 138 45",rgbText:"0 0 0",rgbError:"255 0 60",colorTextName:"28 24 20",colorTextTitle:"rgb(var(--rgbText) / 1)",colorTextBody:"rgb(var(--rgbText) / 0.8)",colorTextLight:"rgb(var(--rgbText) / 0.6)"},l={base:M,desktop:C,laptop:P,tablet:j,mobile:W,mobileS:X},d={dark:I,light:N};function H(){return n.useContext(g)}const g=n.createContext({}),y=({themeId:t="dark",theme:o,children:r,className:f,as:T="div",themeColor:m=!0,...S})=>{const i={...d[t],...o},x=!H().themeId,h=k();return n.useEffect(()=>{if(!x||!h||(window.localStorage.setItem("theme",JSON.stringify(t)),document.body.dataset.theme=t,!m))return;let s=document.head.querySelector('meta[name="theme-color"]');s||(s=document.createElement("meta"),s.name="theme-color",document.head.appendChild(s)),s.content=`rgb(${i.rgbBackground})`},[t,x,h,m,i.rgbBackground]),a.jsxs(g.Provider,{value:i,children:[x&&r,!x&&a.jsx(T,{className:e.classes("theme-provider",f),"data-theme":t,...S,children:r})]})};function u(t){return t.replace(/\s\s+/g," ")}function c(t){return u(Object.keys(t).filter(o=>o!=="themeId").map(o=>`--${o}: ${t[o]};`).join(`
|
|
2
|
+
|
|
3
|
+
`))}function $(t){const o={};for(const r of Object.keys(t))r!=="themeId"&&(o[`--${r}`]=t[r]);return o}function v(){return u(Object.keys(e.media).map(t=>`
|
|
4
|
+
@media (max-width: ${e.media[t]}px) {
|
|
5
|
+
:root {
|
|
6
|
+
${c(l[t])}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
`).join(`
|
|
10
|
+
`))}const F=u(`
|
|
11
|
+
:root {
|
|
12
|
+
${c(l.base)}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
${v()}
|
|
16
|
+
|
|
17
|
+
[data-theme='dark'] {
|
|
18
|
+
${c(d.dark)}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[data-theme='light'] {
|
|
22
|
+
${c(d.light)}
|
|
23
|
+
}
|
|
24
|
+
`),p={dracoDecoderPath:"/draco/",modelBasePath:"/models/",portalContainer:()=>document.getElementById("portal-root")},L=n.createContext(p),D=()=>n.useContext(L),O=({linkComponent:t,themeId:o,theme:r,themeColor:f,dracoDecoderPath:T=p.dracoDecoderPath,modelBasePath:m=p.modelBasePath,portalContainer:S=p.portalContainer,children:i})=>a.jsx(L.Provider,{value:{dracoDecoderPath:T,modelBasePath:m,portalContainer:S},children:a.jsx(y,{themeId:o,theme:r,themeColor:f,children:t?a.jsx(z,{component:t,children:i}):i})});exports.LinkProvider=z;exports.RefractProvider=O;exports.ThemeContext=g;exports.ThemeProvider=y;exports.createMediaTokenProperties=v;exports.createThemeProperties=c;exports.createThemeStyleObject=$;exports.squish=u;exports.theme=d;exports.tokenStyles=F;exports.tokens=l;exports.useHasMounted=k;exports.useLinkComponent=B;exports.useRefractConfig=D;exports.useTheme=H;
|
|
25
|
+
//# sourceMappingURL=RefractProvider-Bzz4G22S.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefractProvider-Bzz4G22S.cjs","sources":["../src/components/LinkProvider/LinkProvider.tsx","../src/hooks/useHasMounted.ts","../src/components/ThemeProvider/theme.ts","../src/components/ThemeProvider/useTheme.ts","../src/components/ThemeProvider/ThemeProvider.tsx","../src/components/RefractProvider/RefractProvider.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext } from 'react';\nimport type {\n AnchorHTMLAttributes,\n ForwardRefExoticComponent,\n ReactNode,\n RefAttributes,\n} from 'react';\n\nexport type LinkComponentProps = AnchorHTMLAttributes<HTMLAnchorElement> & { href: string };\n\nexport type LinkComponent = ForwardRefExoticComponent<\n LinkComponentProps & RefAttributes<HTMLAnchorElement>\n>;\n\nconst DefaultLink = forwardRef<HTMLAnchorElement, LinkComponentProps>((props, ref) => (\n <a {...props} ref={ref} />\n));\n\nDefaultLink.displayName = 'DefaultLink';\n\nconst LinkComponentContext = createContext<LinkComponent>(DefaultLink);\n\nexport interface LinkProviderProps {\n component: LinkComponent;\n children?: ReactNode;\n}\n\n// Lets a host app (e.g. Next.js) supply its own routed link component —\n// Link and Button render it in place of a plain <a> for internal hrefs.\n// Defaults to <a> so the components work standalone with no provider.\nexport const LinkProvider = ({ component, children }: LinkProviderProps) => (\n <LinkComponentContext.Provider value={component}>{children}</LinkComponentContext.Provider>\n);\n\nexport const useLinkComponent = (): LinkComponent => useContext(LinkComponentContext);\n","import { useEffect, useState } from 'react';\n\nexport function useHasMounted(): boolean {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n // The entire point of this hook is to flip after mount for hydration-safe\n // client-only rendering; that's inherently a setState-in-effect.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setMounted(true);\n }, []);\n\n return mounted;\n}\n","import { pxToRem } from '../../utils/style';\n\n// Full list of tokens\nconst baseTokens = {\n rgbBlack: '0 0 0',\n rgbWhite: '255 255 255',\n bezierFastoutSlowin: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n durationXS: '200ms',\n durationS: '300ms',\n durationM: '400ms',\n durationL: '600ms',\n durationXL: '800ms',\n systemFontStack:\n 'system-ui, -apple-system, BlinkMacSystemFont, San Francisco, Roboto, Segoe UI, Ubuntu, Helvetica Neue, sans-serif',\n fontStack: `var(--brandFontStack, var(--systemFontStack))`,\n monoFontStack:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace',\n devanagariFontStack:\n 'Kohinoor Devanagari, Devanagari Sangam MN, Nirmala UI, Noto Sans Devanagari, sans-serif',\n fontWeightRegular: 400,\n fontWeightMedium: 500,\n fontWeightBold: 700,\n fontSizeH0: pxToRem(140),\n fontSizeH1: pxToRem(100),\n fontSizeH2: pxToRem(58),\n fontSizeH3: pxToRem(38),\n fontSizeH4: pxToRem(28),\n fontSizeH5: pxToRem(24),\n fontSizeBodyXL: pxToRem(22),\n fontSizeBodyL: pxToRem(20),\n fontSizeBodyM: pxToRem(18),\n fontSizeBodyS: pxToRem(16),\n fontSizeBodyXS: pxToRem(14),\n lineHeightTitle: '1.1',\n lineHeightBody: '1.6',\n maxWidthS: '540px',\n maxWidthM: '720px',\n maxWidthL: '1096px',\n maxWidthXL: '1680px',\n spaceOuter: '64px',\n spaceXS: '4px',\n spaceS: '8px',\n spaceM: '16px',\n spaceL: '24px',\n spaceXL: '32px',\n space2XL: '48px',\n space3XL: '64px',\n space4XL: '96px',\n space5XL: '128px',\n zIndex0: 0,\n zIndex1: 4,\n zIndex2: 8,\n zIndex3: 16,\n zIndex4: 32,\n zIndex5: 64,\n} as const;\n\n// Tokens that change based on viewport size\nconst tokensDesktop = {\n fontSizeH0: pxToRem(120),\n fontSizeH1: pxToRem(80),\n} as const;\n\nconst tokensLaptop = {\n maxWidthS: '480px',\n maxWidthM: '640px',\n maxWidthL: '1000px',\n maxWidthXL: '1100px',\n spaceOuter: '48px',\n fontSizeH0: pxToRem(100),\n fontSizeH1: pxToRem(70),\n fontSizeH2: pxToRem(50),\n fontSizeH3: pxToRem(36),\n fontSizeH4: pxToRem(26),\n fontSizeH5: pxToRem(22),\n} as const;\n\nconst tokensTablet = {\n fontSizeH0: pxToRem(80),\n fontSizeH1: pxToRem(60),\n fontSizeH2: pxToRem(48),\n fontSizeH3: pxToRem(32),\n fontSizeH4: pxToRem(24),\n fontSizeH5: pxToRem(20),\n} as const;\n\nconst tokensMobile = {\n spaceOuter: '24px',\n fontSizeH0: pxToRem(56),\n fontSizeH1: pxToRem(40),\n fontSizeH2: pxToRem(34),\n fontSizeH3: pxToRem(28),\n fontSizeH4: pxToRem(22),\n fontSizeH5: pxToRem(18),\n fontSizeBodyL: pxToRem(17),\n fontSizeBodyM: pxToRem(16),\n fontSizeBodyS: pxToRem(14),\n} as const;\n\nconst tokensMobileSmall = {\n spaceOuter: '16px',\n fontSizeH0: pxToRem(42),\n fontSizeH1: pxToRem(38),\n fontSizeH2: pxToRem(28),\n fontSizeH3: pxToRem(24),\n fontSizeH4: pxToRem(20),\n} as const;\n\n// Tokens that change based on theme\nconst dark = {\n themeId: 'dark' as const,\n rgbBackground: '17 17 17',\n rgbBackgroundLight: '26 26 26',\n rgbPrimary: '251 146 60',\n rgbAccent: '251 146 60',\n rgbText: '255 255 255',\n rgbError: '255 55 102',\n colorTextName: '246 240 228',\n colorTextTitle: 'rgb(var(--rgbText) / 1)',\n colorTextBody: 'rgb(var(--rgbText) / 0.8)',\n colorTextLight: 'rgb(var(--rgbText) / 0.6)',\n};\n\nconst light = {\n themeId: 'light' as const,\n rgbBackground: '242 242 242',\n rgbBackgroundLight: '255 255 255',\n rgbPrimary: '168 85 8',\n rgbAccent: '255 138 45',\n rgbText: '0 0 0',\n rgbError: '255 0 60',\n colorTextName: '28 24 20',\n colorTextTitle: 'rgb(var(--rgbText) / 1)',\n colorTextBody: 'rgb(var(--rgbText) / 0.8)',\n colorTextLight: 'rgb(var(--rgbText) / 0.6)',\n};\n\nexport const tokens = {\n base: baseTokens,\n desktop: tokensDesktop,\n laptop: tokensLaptop,\n tablet: tokensTablet,\n mobile: tokensMobile,\n mobileS: tokensMobileSmall,\n} as const;\n\nexport const theme = { dark, light } as const;\n\nexport type ThemeTokens = {\n themeId: 'dark' | 'light';\n rgbBackground: string;\n rgbBackgroundLight: string;\n rgbPrimary: string;\n rgbAccent: string;\n rgbText: string;\n rgbError: string;\n colorTextName: string;\n colorTextTitle: string;\n colorTextBody: string;\n colorTextLight: string;\n};\n","import { useContext } from 'react';\nimport { ThemeContext } from './ThemeProvider';\nimport type { ThemeTokens } from './theme';\n\nexport function useTheme(): ThemeTokens | Record<string, never> {\n const currentTheme = useContext(ThemeContext);\n return currentTheme;\n}\n","import { useHasMounted } from '../../hooks/useHasMounted';\nimport { createContext, useEffect, type ElementType, type ReactNode } from 'react';\nimport { classes, media } from '../../utils/style';\nimport { theme, tokens, type ThemeTokens } from './theme';\nimport { useTheme } from './useTheme';\n\nexport type ThemeId = 'dark' | 'light';\n\nexport const ThemeContext = createContext<ThemeTokens | Record<string, never>>({});\n\ninterface ThemeProviderProps {\n themeId?: ThemeId;\n theme?: Partial<ThemeTokens>;\n children?: ReactNode;\n className?: string;\n as?: ElementType;\n /** Keep the `<meta name=\"theme-color\">` tag in sync with the theme. Defaults to true. */\n themeColor?: boolean;\n [key: string]: unknown;\n}\n\nexport const ThemeProvider = ({\n themeId = 'dark',\n theme: themeOverrides,\n children,\n className,\n as: Component = 'div',\n themeColor = true,\n ...rest\n}: ThemeProviderProps) => {\n const currentTheme = { ...theme[themeId], ...themeOverrides };\n const parentTheme = useTheme();\n const isRootProvider = !parentTheme.themeId;\n const hasMounted = useHasMounted();\n\n useEffect(() => {\n if (!isRootProvider || !hasMounted) return;\n\n window.localStorage.setItem('theme', JSON.stringify(themeId));\n document.body.dataset.theme = themeId;\n\n if (!themeColor) return;\n\n let meta = document.head.querySelector<HTMLMetaElement>('meta[name=\"theme-color\"]');\n\n if (!meta) {\n meta = document.createElement('meta');\n meta.name = 'theme-color';\n document.head.appendChild(meta);\n }\n\n meta.content = `rgb(${currentTheme.rgbBackground})`;\n }, [themeId, isRootProvider, hasMounted, themeColor, currentTheme.rgbBackground]);\n\n return (\n <ThemeContext.Provider value={currentTheme}>\n {isRootProvider && children}\n {!isRootProvider && (\n <Component\n className={classes('theme-provider', className)}\n data-theme={themeId}\n {...rest}\n >\n {children}\n </Component>\n )}\n </ThemeContext.Provider>\n );\n};\n\nexport function squish(styles: string): string {\n return styles.replace(/\\s\\s+/g, ' ');\n}\n\nexport function createThemeProperties(themeObj: Record<string, string | number>): string {\n return squish(\n Object.keys(themeObj)\n .filter(key => key !== 'themeId')\n .map(key => `--${key}: ${themeObj[key]};`)\n .join('\\n\\n')\n );\n}\n\nexport function createThemeStyleObject(themeObj: Record<string, string | number>): Record<string, string | number> {\n const style: Record<string, string | number> = {};\n\n for (const key of Object.keys(themeObj)) {\n if (key !== 'themeId') {\n style[`--${key}`] = themeObj[key];\n }\n }\n\n return style;\n}\n\nexport function createMediaTokenProperties(): string {\n return squish(\n (Object.keys(media) as Array<keyof typeof media>)\n .map(key => {\n return `\n @media (max-width: ${media[key]}px) {\n :root {\n ${createThemeProperties(tokens[key] as unknown as Record<string, string | number>)}\n }\n }\n `;\n })\n .join('\\n')\n );\n}\n\nexport const tokenStyles = squish(`\n :root {\n ${createThemeProperties(tokens.base as unknown as Record<string, string | number>)}\n }\n\n ${createMediaTokenProperties()}\n\n [data-theme='dark'] {\n ${createThemeProperties(theme.dark)}\n }\n\n [data-theme='light'] {\n ${createThemeProperties(theme.light)}\n }\n`);\n","import { createContext, useContext, type ReactNode } from 'react';\nimport { LinkProvider, type LinkComponent } from '../LinkProvider';\nimport { ThemeProvider, type ThemeId } from '../ThemeProvider';\nimport type { ThemeTokens } from '../ThemeProvider';\n\nexport interface RefractConfig {\n /** Path the draco decoder assets are served from. Defaults to '/draco/'. */\n dracoDecoderPath?: string;\n /** Path device .glb models are served from. Defaults to '/models/'. */\n modelBasePath?: string;\n /** Container the Loader's screen-reader announcement portals into. Defaults to #portal-root. */\n portalContainer?: () => HTMLElement | null;\n}\n\nconst defaultConfig: Required<RefractConfig> = {\n dracoDecoderPath: '/draco/',\n modelBasePath: '/models/',\n portalContainer: () => document.getElementById('portal-root'),\n};\n\nconst RefractConfigContext = createContext<Required<RefractConfig>>(defaultConfig);\n\nexport const useRefractConfig = (): Required<RefractConfig> => useContext(RefractConfigContext);\n\nexport interface RefractProviderProps extends RefractConfig {\n linkComponent?: LinkComponent;\n themeId?: ThemeId;\n theme?: Partial<ThemeTokens>;\n themeColor?: boolean;\n children?: ReactNode;\n}\n\n// Convenience composition of ThemeProvider + LinkProvider + the asset-path\n// config the 3D components need. Each piece stays independently exported and\n// usable on its own — nothing here is required.\nexport const RefractProvider = ({\n linkComponent,\n themeId,\n theme,\n themeColor,\n dracoDecoderPath = defaultConfig.dracoDecoderPath,\n modelBasePath = defaultConfig.modelBasePath,\n portalContainer = defaultConfig.portalContainer,\n children,\n}: RefractProviderProps) => (\n <RefractConfigContext.Provider value={{ dracoDecoderPath, modelBasePath, portalContainer }}>\n <ThemeProvider themeId={themeId} theme={theme} themeColor={themeColor}>\n {linkComponent ? (\n <LinkProvider component={linkComponent}>{children}</LinkProvider>\n ) : (\n children\n )}\n </ThemeProvider>\n </RefractConfigContext.Provider>\n);\n"],"names":["DefaultLink","forwardRef","props","ref","LinkComponentContext","createContext","LinkProvider","component","children","jsx","useLinkComponent","useContext","useHasMounted","mounted","setMounted","useState","useEffect","baseTokens","pxToRem","tokensDesktop","tokensLaptop","tokensTablet","tokensMobile","tokensMobileSmall","dark","light","tokens","theme","useTheme","ThemeContext","ThemeProvider","themeId","themeOverrides","className","Component","themeColor","rest","currentTheme","isRootProvider","hasMounted","meta","jsxs","classes","squish","styles","createThemeProperties","themeObj","key","createThemeStyleObject","style","createMediaTokenProperties","media","tokenStyles","defaultConfig","RefractConfigContext","useRefractConfig","RefractProvider","linkComponent","dracoDecoderPath","modelBasePath","portalContainer"],"mappings":"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"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as r, jsxs as v } from "react/jsx-runtime";
|
|
3
|
+
import { useContext as p, createContext as g, forwardRef as B, useState as M, useEffect as z } from "react";
|
|
4
|
+
import { e, a as P, b } from "./style-uMN7vipQ.js";
|
|
5
|
+
const k = B((t, o) => /* @__PURE__ */ r("a", { ...t, ref: o }));
|
|
6
|
+
k.displayName = "DefaultLink";
|
|
7
|
+
const H = g(k), C = ({ component: t, children: o }) => /* @__PURE__ */ r(H.Provider, { value: t, children: o }), K = () => p(H);
|
|
8
|
+
function W() {
|
|
9
|
+
const [t, o] = M(!1);
|
|
10
|
+
return z(() => {
|
|
11
|
+
o(!0);
|
|
12
|
+
}, []), t;
|
|
13
|
+
}
|
|
14
|
+
const X = {
|
|
15
|
+
rgbBlack: "0 0 0",
|
|
16
|
+
rgbWhite: "255 255 255",
|
|
17
|
+
bezierFastoutSlowin: "cubic-bezier(0.4, 0.0, 0.2, 1)",
|
|
18
|
+
durationXS: "200ms",
|
|
19
|
+
durationS: "300ms",
|
|
20
|
+
durationM: "400ms",
|
|
21
|
+
durationL: "600ms",
|
|
22
|
+
durationXL: "800ms",
|
|
23
|
+
systemFontStack: "system-ui, -apple-system, BlinkMacSystemFont, San Francisco, Roboto, Segoe UI, Ubuntu, Helvetica Neue, sans-serif",
|
|
24
|
+
fontStack: "var(--brandFontStack, var(--systemFontStack))",
|
|
25
|
+
monoFontStack: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace",
|
|
26
|
+
devanagariFontStack: "Kohinoor Devanagari, Devanagari Sangam MN, Nirmala UI, Noto Sans Devanagari, sans-serif",
|
|
27
|
+
fontWeightRegular: 400,
|
|
28
|
+
fontWeightMedium: 500,
|
|
29
|
+
fontWeightBold: 700,
|
|
30
|
+
fontSizeH0: e(140),
|
|
31
|
+
fontSizeH1: e(100),
|
|
32
|
+
fontSizeH2: e(58),
|
|
33
|
+
fontSizeH3: e(38),
|
|
34
|
+
fontSizeH4: e(28),
|
|
35
|
+
fontSizeH5: e(24),
|
|
36
|
+
fontSizeBodyXL: e(22),
|
|
37
|
+
fontSizeBodyL: e(20),
|
|
38
|
+
fontSizeBodyM: e(18),
|
|
39
|
+
fontSizeBodyS: e(16),
|
|
40
|
+
fontSizeBodyXS: e(14),
|
|
41
|
+
lineHeightTitle: "1.1",
|
|
42
|
+
lineHeightBody: "1.6",
|
|
43
|
+
maxWidthS: "540px",
|
|
44
|
+
maxWidthM: "720px",
|
|
45
|
+
maxWidthL: "1096px",
|
|
46
|
+
maxWidthXL: "1680px",
|
|
47
|
+
spaceOuter: "64px",
|
|
48
|
+
spaceXS: "4px",
|
|
49
|
+
spaceS: "8px",
|
|
50
|
+
spaceM: "16px",
|
|
51
|
+
spaceL: "24px",
|
|
52
|
+
spaceXL: "32px",
|
|
53
|
+
space2XL: "48px",
|
|
54
|
+
space3XL: "64px",
|
|
55
|
+
space4XL: "96px",
|
|
56
|
+
space5XL: "128px",
|
|
57
|
+
zIndex0: 0,
|
|
58
|
+
zIndex1: 4,
|
|
59
|
+
zIndex2: 8,
|
|
60
|
+
zIndex3: 16,
|
|
61
|
+
zIndex4: 32,
|
|
62
|
+
zIndex5: 64
|
|
63
|
+
}, I = {
|
|
64
|
+
fontSizeH0: e(120),
|
|
65
|
+
fontSizeH1: e(80)
|
|
66
|
+
}, N = {
|
|
67
|
+
maxWidthS: "480px",
|
|
68
|
+
maxWidthM: "640px",
|
|
69
|
+
maxWidthL: "1000px",
|
|
70
|
+
maxWidthXL: "1100px",
|
|
71
|
+
spaceOuter: "48px",
|
|
72
|
+
fontSizeH0: e(100),
|
|
73
|
+
fontSizeH1: e(70),
|
|
74
|
+
fontSizeH2: e(50),
|
|
75
|
+
fontSizeH3: e(36),
|
|
76
|
+
fontSizeH4: e(26),
|
|
77
|
+
fontSizeH5: e(22)
|
|
78
|
+
}, R = {
|
|
79
|
+
fontSizeH0: e(80),
|
|
80
|
+
fontSizeH1: e(60),
|
|
81
|
+
fontSizeH2: e(48),
|
|
82
|
+
fontSizeH3: e(32),
|
|
83
|
+
fontSizeH4: e(24),
|
|
84
|
+
fontSizeH5: e(20)
|
|
85
|
+
}, $ = {
|
|
86
|
+
spaceOuter: "24px",
|
|
87
|
+
fontSizeH0: e(56),
|
|
88
|
+
fontSizeH1: e(40),
|
|
89
|
+
fontSizeH2: e(34),
|
|
90
|
+
fontSizeH3: e(28),
|
|
91
|
+
fontSizeH4: e(22),
|
|
92
|
+
fontSizeH5: e(18),
|
|
93
|
+
fontSizeBodyL: e(17),
|
|
94
|
+
fontSizeBodyM: e(16),
|
|
95
|
+
fontSizeBodyS: e(14)
|
|
96
|
+
}, F = {
|
|
97
|
+
spaceOuter: "16px",
|
|
98
|
+
fontSizeH0: e(42),
|
|
99
|
+
fontSizeH1: e(38),
|
|
100
|
+
fontSizeH2: e(28),
|
|
101
|
+
fontSizeH3: e(24),
|
|
102
|
+
fontSizeH4: e(20)
|
|
103
|
+
}, D = {
|
|
104
|
+
themeId: "dark",
|
|
105
|
+
rgbBackground: "17 17 17",
|
|
106
|
+
rgbBackgroundLight: "26 26 26",
|
|
107
|
+
rgbPrimary: "251 146 60",
|
|
108
|
+
rgbAccent: "251 146 60",
|
|
109
|
+
rgbText: "255 255 255",
|
|
110
|
+
rgbError: "255 55 102",
|
|
111
|
+
colorTextName: "246 240 228",
|
|
112
|
+
colorTextTitle: "rgb(var(--rgbText) / 1)",
|
|
113
|
+
colorTextBody: "rgb(var(--rgbText) / 0.8)",
|
|
114
|
+
colorTextLight: "rgb(var(--rgbText) / 0.6)"
|
|
115
|
+
}, O = {
|
|
116
|
+
themeId: "light",
|
|
117
|
+
rgbBackground: "242 242 242",
|
|
118
|
+
rgbBackgroundLight: "255 255 255",
|
|
119
|
+
rgbPrimary: "168 85 8",
|
|
120
|
+
rgbAccent: "255 138 45",
|
|
121
|
+
rgbText: "0 0 0",
|
|
122
|
+
rgbError: "255 0 60",
|
|
123
|
+
colorTextName: "28 24 20",
|
|
124
|
+
colorTextTitle: "rgb(var(--rgbText) / 1)",
|
|
125
|
+
colorTextBody: "rgb(var(--rgbText) / 0.8)",
|
|
126
|
+
colorTextLight: "rgb(var(--rgbText) / 0.6)"
|
|
127
|
+
}, T = {
|
|
128
|
+
base: X,
|
|
129
|
+
desktop: I,
|
|
130
|
+
laptop: N,
|
|
131
|
+
tablet: R,
|
|
132
|
+
mobile: $,
|
|
133
|
+
mobileS: F
|
|
134
|
+
}, l = { dark: D, light: O };
|
|
135
|
+
function j() {
|
|
136
|
+
return p(y);
|
|
137
|
+
}
|
|
138
|
+
const y = g({}), w = ({
|
|
139
|
+
themeId: t = "dark",
|
|
140
|
+
theme: o,
|
|
141
|
+
children: n,
|
|
142
|
+
className: f,
|
|
143
|
+
as: u = "div",
|
|
144
|
+
themeColor: s = !0,
|
|
145
|
+
...S
|
|
146
|
+
}) => {
|
|
147
|
+
const a = { ...l[t], ...o }, c = !j().themeId, h = W();
|
|
148
|
+
return z(() => {
|
|
149
|
+
if (!c || !h || (window.localStorage.setItem("theme", JSON.stringify(t)), document.body.dataset.theme = t, !s)) return;
|
|
150
|
+
let i = document.head.querySelector('meta[name="theme-color"]');
|
|
151
|
+
i || (i = document.createElement("meta"), i.name = "theme-color", document.head.appendChild(i)), i.content = `rgb(${a.rgbBackground})`;
|
|
152
|
+
}, [t, c, h, s, a.rgbBackground]), /* @__PURE__ */ v(y.Provider, { value: a, children: [
|
|
153
|
+
c && n,
|
|
154
|
+
!c && /* @__PURE__ */ r(
|
|
155
|
+
u,
|
|
156
|
+
{
|
|
157
|
+
className: P("theme-provider", f),
|
|
158
|
+
"data-theme": t,
|
|
159
|
+
...S,
|
|
160
|
+
children: n
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
] });
|
|
164
|
+
};
|
|
165
|
+
function x(t) {
|
|
166
|
+
return t.replace(/\s\s+/g, " ");
|
|
167
|
+
}
|
|
168
|
+
function d(t) {
|
|
169
|
+
return x(
|
|
170
|
+
Object.keys(t).filter((o) => o !== "themeId").map((o) => `--${o}: ${t[o]};`).join(`
|
|
171
|
+
|
|
172
|
+
`)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
function G(t) {
|
|
176
|
+
const o = {};
|
|
177
|
+
for (const n of Object.keys(t))
|
|
178
|
+
n !== "themeId" && (o[`--${n}`] = t[n]);
|
|
179
|
+
return o;
|
|
180
|
+
}
|
|
181
|
+
function E() {
|
|
182
|
+
return x(
|
|
183
|
+
Object.keys(b).map((t) => `
|
|
184
|
+
@media (max-width: ${b[t]}px) {
|
|
185
|
+
:root {
|
|
186
|
+
${d(T[t])}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
`).join(`
|
|
190
|
+
`)
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const Q = x(`
|
|
194
|
+
:root {
|
|
195
|
+
${d(T.base)}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
${E()}
|
|
199
|
+
|
|
200
|
+
[data-theme='dark'] {
|
|
201
|
+
${d(l.dark)}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
[data-theme='light'] {
|
|
205
|
+
${d(l.light)}
|
|
206
|
+
}
|
|
207
|
+
`), m = {
|
|
208
|
+
dracoDecoderPath: "/draco/",
|
|
209
|
+
modelBasePath: "/models/",
|
|
210
|
+
portalContainer: () => document.getElementById("portal-root")
|
|
211
|
+
}, L = g(m), V = () => p(L), Y = ({
|
|
212
|
+
linkComponent: t,
|
|
213
|
+
themeId: o,
|
|
214
|
+
theme: n,
|
|
215
|
+
themeColor: f,
|
|
216
|
+
dracoDecoderPath: u = m.dracoDecoderPath,
|
|
217
|
+
modelBasePath: s = m.modelBasePath,
|
|
218
|
+
portalContainer: S = m.portalContainer,
|
|
219
|
+
children: a
|
|
220
|
+
}) => /* @__PURE__ */ r(L.Provider, { value: { dracoDecoderPath: u, modelBasePath: s, portalContainer: S }, children: /* @__PURE__ */ r(w, { themeId: o, theme: n, themeColor: f, children: t ? /* @__PURE__ */ r(C, { component: t, children: a }) : a }) });
|
|
221
|
+
export {
|
|
222
|
+
C as L,
|
|
223
|
+
Y as R,
|
|
224
|
+
y as T,
|
|
225
|
+
W as a,
|
|
226
|
+
K as b,
|
|
227
|
+
j as c,
|
|
228
|
+
w as d,
|
|
229
|
+
E as e,
|
|
230
|
+
d as f,
|
|
231
|
+
G as g,
|
|
232
|
+
l as h,
|
|
233
|
+
Q as i,
|
|
234
|
+
x as s,
|
|
235
|
+
T as t,
|
|
236
|
+
V as u
|
|
237
|
+
};
|
|
238
|
+
//# sourceMappingURL=RefractProvider-D__A8gQl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefractProvider-D__A8gQl.js","sources":["../src/components/LinkProvider/LinkProvider.tsx","../src/hooks/useHasMounted.ts","../src/components/ThemeProvider/theme.ts","../src/components/ThemeProvider/useTheme.ts","../src/components/ThemeProvider/ThemeProvider.tsx","../src/components/RefractProvider/RefractProvider.tsx"],"sourcesContent":["import { createContext, forwardRef, useContext } from 'react';\nimport type {\n AnchorHTMLAttributes,\n ForwardRefExoticComponent,\n ReactNode,\n RefAttributes,\n} from 'react';\n\nexport type LinkComponentProps = AnchorHTMLAttributes<HTMLAnchorElement> & { href: string };\n\nexport type LinkComponent = ForwardRefExoticComponent<\n LinkComponentProps & RefAttributes<HTMLAnchorElement>\n>;\n\nconst DefaultLink = forwardRef<HTMLAnchorElement, LinkComponentProps>((props, ref) => (\n <a {...props} ref={ref} />\n));\n\nDefaultLink.displayName = 'DefaultLink';\n\nconst LinkComponentContext = createContext<LinkComponent>(DefaultLink);\n\nexport interface LinkProviderProps {\n component: LinkComponent;\n children?: ReactNode;\n}\n\n// Lets a host app (e.g. Next.js) supply its own routed link component —\n// Link and Button render it in place of a plain <a> for internal hrefs.\n// Defaults to <a> so the components work standalone with no provider.\nexport const LinkProvider = ({ component, children }: LinkProviderProps) => (\n <LinkComponentContext.Provider value={component}>{children}</LinkComponentContext.Provider>\n);\n\nexport const useLinkComponent = (): LinkComponent => useContext(LinkComponentContext);\n","import { useEffect, useState } from 'react';\n\nexport function useHasMounted(): boolean {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n // The entire point of this hook is to flip after mount for hydration-safe\n // client-only rendering; that's inherently a setState-in-effect.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setMounted(true);\n }, []);\n\n return mounted;\n}\n","import { pxToRem } from '../../utils/style';\n\n// Full list of tokens\nconst baseTokens = {\n rgbBlack: '0 0 0',\n rgbWhite: '255 255 255',\n bezierFastoutSlowin: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n durationXS: '200ms',\n durationS: '300ms',\n durationM: '400ms',\n durationL: '600ms',\n durationXL: '800ms',\n systemFontStack:\n 'system-ui, -apple-system, BlinkMacSystemFont, San Francisco, Roboto, Segoe UI, Ubuntu, Helvetica Neue, sans-serif',\n fontStack: `var(--brandFontStack, var(--systemFontStack))`,\n monoFontStack:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace',\n devanagariFontStack:\n 'Kohinoor Devanagari, Devanagari Sangam MN, Nirmala UI, Noto Sans Devanagari, sans-serif',\n fontWeightRegular: 400,\n fontWeightMedium: 500,\n fontWeightBold: 700,\n fontSizeH0: pxToRem(140),\n fontSizeH1: pxToRem(100),\n fontSizeH2: pxToRem(58),\n fontSizeH3: pxToRem(38),\n fontSizeH4: pxToRem(28),\n fontSizeH5: pxToRem(24),\n fontSizeBodyXL: pxToRem(22),\n fontSizeBodyL: pxToRem(20),\n fontSizeBodyM: pxToRem(18),\n fontSizeBodyS: pxToRem(16),\n fontSizeBodyXS: pxToRem(14),\n lineHeightTitle: '1.1',\n lineHeightBody: '1.6',\n maxWidthS: '540px',\n maxWidthM: '720px',\n maxWidthL: '1096px',\n maxWidthXL: '1680px',\n spaceOuter: '64px',\n spaceXS: '4px',\n spaceS: '8px',\n spaceM: '16px',\n spaceL: '24px',\n spaceXL: '32px',\n space2XL: '48px',\n space3XL: '64px',\n space4XL: '96px',\n space5XL: '128px',\n zIndex0: 0,\n zIndex1: 4,\n zIndex2: 8,\n zIndex3: 16,\n zIndex4: 32,\n zIndex5: 64,\n} as const;\n\n// Tokens that change based on viewport size\nconst tokensDesktop = {\n fontSizeH0: pxToRem(120),\n fontSizeH1: pxToRem(80),\n} as const;\n\nconst tokensLaptop = {\n maxWidthS: '480px',\n maxWidthM: '640px',\n maxWidthL: '1000px',\n maxWidthXL: '1100px',\n spaceOuter: '48px',\n fontSizeH0: pxToRem(100),\n fontSizeH1: pxToRem(70),\n fontSizeH2: pxToRem(50),\n fontSizeH3: pxToRem(36),\n fontSizeH4: pxToRem(26),\n fontSizeH5: pxToRem(22),\n} as const;\n\nconst tokensTablet = {\n fontSizeH0: pxToRem(80),\n fontSizeH1: pxToRem(60),\n fontSizeH2: pxToRem(48),\n fontSizeH3: pxToRem(32),\n fontSizeH4: pxToRem(24),\n fontSizeH5: pxToRem(20),\n} as const;\n\nconst tokensMobile = {\n spaceOuter: '24px',\n fontSizeH0: pxToRem(56),\n fontSizeH1: pxToRem(40),\n fontSizeH2: pxToRem(34),\n fontSizeH3: pxToRem(28),\n fontSizeH4: pxToRem(22),\n fontSizeH5: pxToRem(18),\n fontSizeBodyL: pxToRem(17),\n fontSizeBodyM: pxToRem(16),\n fontSizeBodyS: pxToRem(14),\n} as const;\n\nconst tokensMobileSmall = {\n spaceOuter: '16px',\n fontSizeH0: pxToRem(42),\n fontSizeH1: pxToRem(38),\n fontSizeH2: pxToRem(28),\n fontSizeH3: pxToRem(24),\n fontSizeH4: pxToRem(20),\n} as const;\n\n// Tokens that change based on theme\nconst dark = {\n themeId: 'dark' as const,\n rgbBackground: '17 17 17',\n rgbBackgroundLight: '26 26 26',\n rgbPrimary: '251 146 60',\n rgbAccent: '251 146 60',\n rgbText: '255 255 255',\n rgbError: '255 55 102',\n colorTextName: '246 240 228',\n colorTextTitle: 'rgb(var(--rgbText) / 1)',\n colorTextBody: 'rgb(var(--rgbText) / 0.8)',\n colorTextLight: 'rgb(var(--rgbText) / 0.6)',\n};\n\nconst light = {\n themeId: 'light' as const,\n rgbBackground: '242 242 242',\n rgbBackgroundLight: '255 255 255',\n rgbPrimary: '168 85 8',\n rgbAccent: '255 138 45',\n rgbText: '0 0 0',\n rgbError: '255 0 60',\n colorTextName: '28 24 20',\n colorTextTitle: 'rgb(var(--rgbText) / 1)',\n colorTextBody: 'rgb(var(--rgbText) / 0.8)',\n colorTextLight: 'rgb(var(--rgbText) / 0.6)',\n};\n\nexport const tokens = {\n base: baseTokens,\n desktop: tokensDesktop,\n laptop: tokensLaptop,\n tablet: tokensTablet,\n mobile: tokensMobile,\n mobileS: tokensMobileSmall,\n} as const;\n\nexport const theme = { dark, light } as const;\n\nexport type ThemeTokens = {\n themeId: 'dark' | 'light';\n rgbBackground: string;\n rgbBackgroundLight: string;\n rgbPrimary: string;\n rgbAccent: string;\n rgbText: string;\n rgbError: string;\n colorTextName: string;\n colorTextTitle: string;\n colorTextBody: string;\n colorTextLight: string;\n};\n","import { useContext } from 'react';\nimport { ThemeContext } from './ThemeProvider';\nimport type { ThemeTokens } from './theme';\n\nexport function useTheme(): ThemeTokens | Record<string, never> {\n const currentTheme = useContext(ThemeContext);\n return currentTheme;\n}\n","import { useHasMounted } from '../../hooks/useHasMounted';\nimport { createContext, useEffect, type ElementType, type ReactNode } from 'react';\nimport { classes, media } from '../../utils/style';\nimport { theme, tokens, type ThemeTokens } from './theme';\nimport { useTheme } from './useTheme';\n\nexport type ThemeId = 'dark' | 'light';\n\nexport const ThemeContext = createContext<ThemeTokens | Record<string, never>>({});\n\ninterface ThemeProviderProps {\n themeId?: ThemeId;\n theme?: Partial<ThemeTokens>;\n children?: ReactNode;\n className?: string;\n as?: ElementType;\n /** Keep the `<meta name=\"theme-color\">` tag in sync with the theme. Defaults to true. */\n themeColor?: boolean;\n [key: string]: unknown;\n}\n\nexport const ThemeProvider = ({\n themeId = 'dark',\n theme: themeOverrides,\n children,\n className,\n as: Component = 'div',\n themeColor = true,\n ...rest\n}: ThemeProviderProps) => {\n const currentTheme = { ...theme[themeId], ...themeOverrides };\n const parentTheme = useTheme();\n const isRootProvider = !parentTheme.themeId;\n const hasMounted = useHasMounted();\n\n useEffect(() => {\n if (!isRootProvider || !hasMounted) return;\n\n window.localStorage.setItem('theme', JSON.stringify(themeId));\n document.body.dataset.theme = themeId;\n\n if (!themeColor) return;\n\n let meta = document.head.querySelector<HTMLMetaElement>('meta[name=\"theme-color\"]');\n\n if (!meta) {\n meta = document.createElement('meta');\n meta.name = 'theme-color';\n document.head.appendChild(meta);\n }\n\n meta.content = `rgb(${currentTheme.rgbBackground})`;\n }, [themeId, isRootProvider, hasMounted, themeColor, currentTheme.rgbBackground]);\n\n return (\n <ThemeContext.Provider value={currentTheme}>\n {isRootProvider && children}\n {!isRootProvider && (\n <Component\n className={classes('theme-provider', className)}\n data-theme={themeId}\n {...rest}\n >\n {children}\n </Component>\n )}\n </ThemeContext.Provider>\n );\n};\n\nexport function squish(styles: string): string {\n return styles.replace(/\\s\\s+/g, ' ');\n}\n\nexport function createThemeProperties(themeObj: Record<string, string | number>): string {\n return squish(\n Object.keys(themeObj)\n .filter(key => key !== 'themeId')\n .map(key => `--${key}: ${themeObj[key]};`)\n .join('\\n\\n')\n );\n}\n\nexport function createThemeStyleObject(themeObj: Record<string, string | number>): Record<string, string | number> {\n const style: Record<string, string | number> = {};\n\n for (const key of Object.keys(themeObj)) {\n if (key !== 'themeId') {\n style[`--${key}`] = themeObj[key];\n }\n }\n\n return style;\n}\n\nexport function createMediaTokenProperties(): string {\n return squish(\n (Object.keys(media) as Array<keyof typeof media>)\n .map(key => {\n return `\n @media (max-width: ${media[key]}px) {\n :root {\n ${createThemeProperties(tokens[key] as unknown as Record<string, string | number>)}\n }\n }\n `;\n })\n .join('\\n')\n );\n}\n\nexport const tokenStyles = squish(`\n :root {\n ${createThemeProperties(tokens.base as unknown as Record<string, string | number>)}\n }\n\n ${createMediaTokenProperties()}\n\n [data-theme='dark'] {\n ${createThemeProperties(theme.dark)}\n }\n\n [data-theme='light'] {\n ${createThemeProperties(theme.light)}\n }\n`);\n","import { createContext, useContext, type ReactNode } from 'react';\nimport { LinkProvider, type LinkComponent } from '../LinkProvider';\nimport { ThemeProvider, type ThemeId } from '../ThemeProvider';\nimport type { ThemeTokens } from '../ThemeProvider';\n\nexport interface RefractConfig {\n /** Path the draco decoder assets are served from. Defaults to '/draco/'. */\n dracoDecoderPath?: string;\n /** Path device .glb models are served from. Defaults to '/models/'. */\n modelBasePath?: string;\n /** Container the Loader's screen-reader announcement portals into. Defaults to #portal-root. */\n portalContainer?: () => HTMLElement | null;\n}\n\nconst defaultConfig: Required<RefractConfig> = {\n dracoDecoderPath: '/draco/',\n modelBasePath: '/models/',\n portalContainer: () => document.getElementById('portal-root'),\n};\n\nconst RefractConfigContext = createContext<Required<RefractConfig>>(defaultConfig);\n\nexport const useRefractConfig = (): Required<RefractConfig> => useContext(RefractConfigContext);\n\nexport interface RefractProviderProps extends RefractConfig {\n linkComponent?: LinkComponent;\n themeId?: ThemeId;\n theme?: Partial<ThemeTokens>;\n themeColor?: boolean;\n children?: ReactNode;\n}\n\n// Convenience composition of ThemeProvider + LinkProvider + the asset-path\n// config the 3D components need. Each piece stays independently exported and\n// usable on its own — nothing here is required.\nexport const RefractProvider = ({\n linkComponent,\n themeId,\n theme,\n themeColor,\n dracoDecoderPath = defaultConfig.dracoDecoderPath,\n modelBasePath = defaultConfig.modelBasePath,\n portalContainer = defaultConfig.portalContainer,\n children,\n}: RefractProviderProps) => (\n <RefractConfigContext.Provider value={{ dracoDecoderPath, modelBasePath, portalContainer }}>\n <ThemeProvider themeId={themeId} theme={theme} themeColor={themeColor}>\n {linkComponent ? (\n <LinkProvider component={linkComponent}>{children}</LinkProvider>\n ) : (\n children\n )}\n </ThemeProvider>\n </RefractConfigContext.Provider>\n);\n"],"names":["DefaultLink","forwardRef","props","ref","LinkComponentContext","createContext","LinkProvider","component","children","jsx","useLinkComponent","useContext","useHasMounted","mounted","setMounted","useState","useEffect","baseTokens","pxToRem","tokensDesktop","tokensLaptop","tokensTablet","tokensMobile","tokensMobileSmall","dark","light","tokens","theme","useTheme","ThemeContext","ThemeProvider","themeId","themeOverrides","className","Component","themeColor","rest","currentTheme","isRootProvider","hasMounted","meta","jsxs","classes","squish","styles","createThemeProperties","themeObj","key","createThemeStyleObject","style","createMediaTokenProperties","media","tokenStyles","defaultConfig","RefractConfigContext","useRefractConfig","RefractProvider","linkComponent","dracoDecoderPath","modelBasePath","portalContainer"],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|
package/dist/carousel.cjs
CHANGED
|
@@ -1,2 +1,49 @@
|
|
|
1
|
-
"use client";"use strict";
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react/jsx-runtime"),t=require("react"),V=require("framer-motion"),N=require("./style-CWBkJEps.cjs"),m=require("three"),q=require("./three-aeLbW1yA.cjs");function oe(r){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const c in r)if(c!=="default"){const f=Object.getOwnPropertyDescriptor(r,c);Object.defineProperty(o,c,f.get?f:{enumerable:!0,get:()=>r[c]})}}return o.default=r,Object.freeze(o)}const E=oe(t),ce=r=>E.createElement("svg",{fill:"currentColor",width:18,height:42,viewBox:"0 0 18 42",...r},E.createElement("path",{d:"M18.03 1.375L16.47.125-.031 20.75l16.5 20.625 1.562-1.25L2.53 20.75z"})),se=r=>E.createElement("svg",{fill:"currentColor",width:18,height:42,viewBox:"0 0 18 42",...r},E.createElement("path",{d:"M-.03 1.375L1.53.125l16.5 20.625-16.5 20.625-1.562-1.25 15.5-19.375z"})),ie="_carousel_miavd_1",ue="_content_miavd_5",le="_imageWrapper_miavd_11",de="_canvasWrapper_miavd_23",me="_canvas_miavd_23",ve="_placeholder_miavd_36",fe="_button_miavd_51",pe="_nav_miavd_107",ge="_navButton_miavd_114",v={carousel:ie,content:ue,imageWrapper:le,canvasWrapper:de,canvas:me,placeholder:ve,button:fe,nav:pe,navButton:ge},xe=`varying vec2 vUv;
|
|
2
|
+
uniform sampler2D currentImage;
|
|
3
|
+
uniform sampler2D nextImage;
|
|
4
|
+
uniform float dispFactor;
|
|
5
|
+
uniform float direction;
|
|
6
|
+
uniform bool reduceMotion;
|
|
7
|
+
|
|
8
|
+
void main() {
|
|
9
|
+
if (reduceMotion) {
|
|
10
|
+
// Simple crossfade
|
|
11
|
+
vec4 _currentImage = texture2D(currentImage, vUv);
|
|
12
|
+
vec4 _nextImage = texture2D(nextImage, vUv);
|
|
13
|
+
vec4 finalTexture = mix(_currentImage, _nextImage, dispFactor);
|
|
14
|
+
gl_FragColor = finalTexture;
|
|
15
|
+
} else {
|
|
16
|
+
// Liquid distortion effect
|
|
17
|
+
vec2 uv = vUv;
|
|
18
|
+
vec4 _currentImage;
|
|
19
|
+
vec4 _nextImage;
|
|
20
|
+
float intensity = 0.6;
|
|
21
|
+
|
|
22
|
+
vec4 orig1 = texture2D(currentImage, uv);
|
|
23
|
+
vec4 orig2 = texture2D(nextImage, uv);
|
|
24
|
+
|
|
25
|
+
vec2 distortedPosition = vec2(
|
|
26
|
+
uv.x + direction * (dispFactor * (orig2.r * intensity)),
|
|
27
|
+
uv.y + direction * (dispFactor * (orig2 * intensity))
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
vec2 distortedPosition2 = vec2(
|
|
31
|
+
uv.x - direction * ((1.0 - dispFactor) * (orig1.r * intensity)),
|
|
32
|
+
uv.y - direction * ((1.0 - dispFactor) * (orig1 * intensity))
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
_currentImage = texture2D(currentImage, distortedPosition);
|
|
36
|
+
_nextImage = texture2D(nextImage, distortedPosition2);
|
|
37
|
+
|
|
38
|
+
vec4 finalTexture = mix(_currentImage, _nextImage, dispFactor);
|
|
39
|
+
gl_FragColor = finalTexture;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`,Ie=`varying vec2 vUv;
|
|
43
|
+
|
|
44
|
+
void main() {
|
|
45
|
+
vUv = uv;
|
|
46
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
47
|
+
}
|
|
48
|
+
`;function K(r,o,c,f){if(o!==null)return o;const h=c.length,S=(r-1+h)%h,P=(r+1)%h;return f>0?P:S}const _e=({width:r,height:o,images:c,placeholder:f,...h})=>{const[S,P]=t.useState(!1),[s,J]=t.useState(0),[y,H]=t.useState(!1),[Q,Y]=t.useState(!0),[l,Z]=t.useState(),[F,ee]=t.useState(),M=t.useRef(null),L=t.useRef(),T=t.useRef(),x=t.useRef(),I=t.useRef(),C=t.useRef(),i=t.useRef(),_=t.useRef(!1),R=t.useRef(),D=t.useRef(),W=t.useRef(),z=V.useReducedMotion(),B=N.useInViewport(M,!0),O=t.useRef(null),U=t.useRef(),te=`Slide ${s+1} of ${c.length}. ${c[s].alt}`;t.useEffect(()=>(S&&(document.body.style.cursor="grabbing"),()=>{document.body.style.cursor=""}),[S]),t.useEffect(()=>{const e=[r/-2,r/2,o/2,o/-2,1,1e3];return i.current=new m.WebGLRenderer({canvas:M.current,antialias:!1,alpha:!0,powerPreference:"high-performance",failIfMajorPerformanceCaveat:!0}),C.current=new m.OrthographicCamera(...e),I.current=new m.Scene,i.current.setPixelRatio(2),i.current.setClearColor(1118481,1),i.current.setSize(r,o),i.current.domElement.style.width="100%",i.current.domElement.style.height="auto",I.current.background=new m.Color(1118481),C.current.position.z=1,()=>{_.current=!1,q.cleanScene(I.current),q.cleanRenderer(i.current)}},[o,r]),t.useEffect(()=>{let e=!0;return B&&!y&&(async()=>{const a=i.current.capabilities.getMaxAnisotropy(),p=c.map(async g=>{const A=g.srcSet?await N.resolveSrcFromSrcSet({srcSet:g.srcSet}):g.src.src,w=await q.textureLoader.loadAsync(A);return await i.current.initTexture(w),w.colorSpace=m.SRGBColorSpace,w.minFilter=m.LinearFilter,w.magFilter=m.LinearFilter,w.anisotropy=a,w.generateMipmaps=!1,w}),b=await Promise.all(p);e&&(x.current=new m.ShaderMaterial({uniforms:{dispFactor:{value:0},direction:{value:1},currentImage:{value:b[0]},nextImage:{value:b[1]},reduceMotion:{value:z}},vertexShader:Ie,fragmentShader:xe,transparent:!1,opacity:1}),T.current=new m.PlaneGeometry(r,o,1),L.current=new m.Mesh(T.current,x.current),L.current.position.set(0,0,0),I.current.add(L.current),H(!0),Z(b),requestAnimationFrame(()=>{i.current.render(I.current,C.current)}))})(),()=>{e=!1}},[o,c,B,y,z,r]);const $=t.useCallback(({index:e,direction:n=1})=>{if(!l)return;J(e);const{uniforms:a}=x.current;a.nextImage.value=l[e],a.direction.value=n;const p=()=>{a.currentImage.value=l[e],a.dispFactor.value=0,_.current=!1};a.dispFactor.value!==1&&(_.current=!0,V.animate(a.dispFactor.value,1,{type:"spring",stiffness:100,damping:20,restSpeed:.001,restDelta:.001,onUpdate:b=>{a.dispFactor.value=b},onComplete:p}))},[l]),d=t.useCallback(({direction:e,index:n=null,...a})=>{if(!y)return;if(_.current){cancelAnimationFrame(W.current),W.current=requestAnimationFrame(()=>d({direction:e,index:n,...a}));return}const p=K(s,n??null,l,e);$({index:p,direction:e,...a})},[$,s,y,l]),ne=t.useCallback(e=>{if(e===s)return;const n=e>s?1:-1;d({direction:n,index:e})},[s,d]);t.useEffect(()=>{const e=()=>{const n=M.current.getBoundingClientRect();ee(n)};return window.addEventListener("resize",e),e(),()=>{window.removeEventListener("resize",e)}},[]),t.useEffect(()=>{let e;const n=()=>{e=requestAnimationFrame(n),_.current&&i.current.render(I.current,C.current)};return e=requestAnimationFrame(n),()=>{cancelAnimationFrame(e)}},[]),t.useEffect(()=>{if(f){const e=()=>{Y(!1)},n=O.current;return n==null||n.addEventListener("transitionend",e),()=>{n&&n.removeEventListener("transitionend",e)}}},[f]);const X=t.useCallback(e=>{if(_.current||!x.current||!l||!F)return;D.current=e;const n=Math.abs(e),a=F.width;R.current=e>0?-1:1;const p=1-(n-a)/a*-1,b=K(s,null,c,R.current),g=x.current.uniforms,A=Math.min(Math.max(p,0),1);g.currentImage.value=l[s],g.nextImage.value=l[b],g.direction.value=R.current,g.dispFactor.value=A,requestAnimationFrame(()=>{i.current.render(I.current,C.current)})},[F,s,c,l]),G=t.useCallback(()=>{if(!x.current)return;const e=x.current.uniforms,n=(1-e.dispFactor.value)*1e3,a=Math.abs(D.current),p=F.width*.2;D.current=0,!_.current&&(a===0||!a||(a>p?d({duration:n,direction:R.current}):(e.currentImage.value=e.nextImage.value,e.nextImage.value=e.currentImage.value,e.dispFactor.value=1-e.dispFactor.value,d({direction:R.current*-1,index:s}))))},[F,s,d]),j=t.useCallback(e=>{X(e.clientX-U.current)},[X]),k=t.useCallback(()=>{P(!1),G(),document.removeEventListener("pointerup",k),document.removeEventListener("pointermove",j)},[j,G]),re=t.useCallback(e=>{U.current=e.clientX,P(!0),document.addEventListener("pointermove",j),document.addEventListener("pointerup",k)},[j,k]),ae=e=>{switch(e.key){case"ArrowRight":d({direction:1});break;case"ArrowLeft":d({direction:-1});break}};return u.jsxs("div",{className:v.carousel,onKeyDown:ae,...h,children:[u.jsxs("div",{className:v.content,children:[u.jsxs("div",{className:v.imageWrapper,"data-dragging":S,onPointerDown:re,style:N.cssProps({aspectRatio:`${r} / ${o}`}),children:[u.jsx("div",{"aria-atomic":!0,className:v.canvasWrapper,"aria-live":"polite","aria-label":te,role:"img",children:u.jsx("canvas",{"aria-hidden":!0,className:v.canvas,ref:M})}),Q&&f&&u.jsx("img",{"aria-hidden":!0,className:v.placeholder,"data-loaded":y&&!!l,src:f.src,ref:O,alt:"",role:"presentation"})]}),u.jsx("button",{className:v.button,"data-prev":!0,"aria-label":"Previous slide",onClick:()=>d({direction:-1}),children:u.jsx(ce,{})}),u.jsx("button",{className:v.button,"data-next":!0,"aria-label":"Next slide",onClick:()=>d({direction:1}),children:u.jsx(se,{})})]}),u.jsx("div",{className:v.nav,children:c.map((e,n)=>u.jsx("button",{className:v.navButton,onClick:()=>ne(n),"aria-label":`Jump to slide ${n+1}`,"aria-pressed":n===s},e.alt))})]})};exports.Carousel=_e;
|
|
2
49
|
//# sourceMappingURL=carousel.cjs.map
|
package/dist/carousel.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"carousel.cjs","sources":["../src/components/Carousel/svg/arrow-left.svg","../src/components/Carousel/svg/arrow-right.svg","../src/components/Carousel/carousel.frag.glsl?raw","../src/components/Carousel/carousel.vert.glsl?raw","../src/components/Carousel/Carousel.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgArrowLeft = (props) => /* @__PURE__ */ React.createElement(\"svg\", { fill: \"currentColor\", width: 18, height: 42, viewBox: \"0 0 18 42\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M18.03 1.375L16.47.125-.031 20.75l16.5 20.625 1.562-1.25L2.53 20.75z\" }));\nexport default SvgArrowLeft;\n","import * as React from \"react\";\nconst SvgArrowRight = (props) => /* @__PURE__ */ React.createElement(\"svg\", { fill: \"currentColor\", width: 18, height: 42, viewBox: \"0 0 18 42\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { d: \"M-.03 1.375L1.53.125l16.5 20.625-16.5 20.625-1.562-1.25 15.5-19.375z\" }));\nexport default SvgArrowRight;\n","export default \"varying vec2 vUv;\\nuniform sampler2D currentImage;\\nuniform sampler2D nextImage;\\nuniform float dispFactor;\\nuniform float direction;\\nuniform bool reduceMotion;\\n\\nvoid main() {\\n if (reduceMotion) {\\n // Simple crossfade\\n vec4 _currentImage = texture2D(currentImage, vUv);\\n vec4 _nextImage = texture2D(nextImage, vUv);\\n vec4 finalTexture = mix(_currentImage, _nextImage, dispFactor);\\n gl_FragColor = finalTexture;\\n } else {\\n // Liquid distortion effect\\n vec2 uv = vUv;\\n vec4 _currentImage;\\n vec4 _nextImage;\\n float intensity = 0.6;\\n\\n vec4 orig1 = texture2D(currentImage, uv);\\n vec4 orig2 = texture2D(nextImage, uv);\\n\\n vec2 distortedPosition = vec2(\\n uv.x + direction * (dispFactor * (orig2.r * intensity)),\\n uv.y + direction * (dispFactor * (orig2 * intensity))\\n );\\n\\n vec2 distortedPosition2 = vec2(\\n uv.x - direction * ((1.0 - dispFactor) * (orig1.r * intensity)),\\n uv.y - direction * ((1.0 - dispFactor) * (orig1 * intensity))\\n );\\n\\n _currentImage = texture2D(currentImage, distortedPosition);\\n _nextImage = texture2D(nextImage, distortedPosition2);\\n\\n vec4 finalTexture = mix(_currentImage, _nextImage, dispFactor);\\n gl_FragColor = finalTexture;\\n }\\n}\\n\"","export default \"varying vec2 vUv;\\n\\nvoid main() {\\n vUv = uv;\\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\\n}\\n\"","import ArrowLeft from './svg/arrow-left.svg';\nimport ArrowRight from './svg/arrow-right.svg';\nimport { animate, useReducedMotion } from 'framer-motion';\nimport { useInViewport } from '../../hooks/useInViewport';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { HTMLAttributes, KeyboardEvent, PointerEvent } from 'react';\nimport {\n Color,\n LinearFilter,\n Mesh,\n OrthographicCamera,\n PlaneGeometry,\n Scene,\n ShaderMaterial,\n SRGBColorSpace,\n WebGLRenderer,\n} from 'three';\nimport type { Texture } from 'three';\nimport { resolveSrcFromSrcSet } from '../../utils/image';\nimport { cssProps } from '../../utils/style';\nimport { cleanRenderer, cleanScene, textureLoader } from '../../utils/three';\nimport styles from './Carousel.module.css';\nimport fragment from './carousel.frag.glsl?raw';\nimport vertex from './carousel.vert.glsl?raw';\n\ninterface CarouselImage {\n src?: { src: string };\n srcSet?: { src: string; width: number }[];\n alt: string;\n}\n\ninterface CarouselProps extends HTMLAttributes<HTMLDivElement> {\n width: number;\n height: number;\n images: CarouselImage[];\n placeholder?: { src: string };\n}\n\nfunction determineIndex(\n imageIndex: number,\n index: number | null,\n images: CarouselImage[] | Texture[],\n direction: number\n) {\n if (index !== null) return index;\n const length = images.length;\n const prevIndex = (imageIndex - 1 + length) % length;\n const nextIndex = (imageIndex + 1) % length;\n const finalIndex = direction > 0 ? nextIndex : prevIndex;\n return finalIndex;\n}\n\nexport const Carousel = ({ width, height, images, placeholder, ...rest }: CarouselProps) => {\n const [dragging, setDragging] = useState(false);\n const [imageIndex, setImageIndex] = useState(0);\n const [loaded, setLoaded] = useState(false);\n const [showPlaceholder, setShowPlaceholder] = useState(true);\n const [textures, setTextures] = useState<Texture[]>();\n const [canvasRect, setCanvasRect] = useState<DOMRect>();\n const canvas = useRef<HTMLCanvasElement>(null);\n const imagePlane = useRef<Mesh>();\n const geometry = useRef<PlaneGeometry>();\n const material = useRef<ShaderMaterial>();\n const scene = useRef<Scene>();\n const camera = useRef<OrthographicCamera>();\n const renderer = useRef<WebGLRenderer>();\n const animating = useRef(false);\n const swipeDirection = useRef<number>();\n const lastSwipePosition = useRef<number>();\n const scheduledAnimationFrame = useRef<number>();\n const reduceMotion = useReducedMotion();\n const inViewport = useInViewport(canvas, true);\n const placeholderRef = useRef<HTMLImageElement>(null);\n const initSwipeX = useRef<number>();\n\n const currentImageAlt = `Slide ${imageIndex + 1} of ${images.length}. ${\n images[imageIndex].alt\n }`;\n\n useEffect(() => {\n if (dragging) {\n document.body.style.cursor = 'grabbing';\n }\n\n return () => {\n document.body.style.cursor = '';\n };\n }, [dragging]);\n\n useEffect(() => {\n const cameraOptions = [width / -2, width / 2, height / 2, height / -2, 1, 1000] as const;\n renderer.current = new WebGLRenderer({\n canvas: canvas.current!,\n antialias: false,\n alpha: true,\n powerPreference: 'high-performance',\n failIfMajorPerformanceCaveat: true,\n });\n camera.current = new OrthographicCamera(...cameraOptions);\n scene.current = new Scene();\n renderer.current.setPixelRatio(2);\n renderer.current.setClearColor(0x111111, 1.0);\n renderer.current.setSize(width, height);\n renderer.current.domElement.style.width = '100%';\n renderer.current.domElement.style.height = 'auto';\n scene.current.background = new Color(0x111111);\n camera.current.position.z = 1;\n\n return () => {\n animating.current = false;\n cleanScene(scene.current!);\n cleanRenderer(renderer.current!);\n };\n }, [height, width]);\n\n useEffect(() => {\n let mounted = true;\n\n const loadImages = async () => {\n const anisotropy = renderer.current!.capabilities.getMaxAnisotropy();\n\n const texturePromises = images.map(async image => {\n const imageSrc = image.srcSet\n ? await resolveSrcFromSrcSet({ srcSet: image.srcSet })\n : image.src!.src;\n const imageTexture = await textureLoader.loadAsync(imageSrc);\n await renderer.current!.initTexture(imageTexture);\n imageTexture.colorSpace = SRGBColorSpace;\n imageTexture.minFilter = LinearFilter;\n imageTexture.magFilter = LinearFilter;\n imageTexture.anisotropy = anisotropy;\n imageTexture.generateMipmaps = false;\n return imageTexture;\n });\n\n const loadedTextures = await Promise.all(texturePromises);\n\n if (!mounted) return;\n\n material.current = new ShaderMaterial({\n uniforms: {\n dispFactor: { value: 0 },\n direction: { value: 1 },\n currentImage: { value: loadedTextures[0] },\n nextImage: { value: loadedTextures[1] },\n reduceMotion: { value: reduceMotion },\n },\n vertexShader: vertex,\n fragmentShader: fragment,\n transparent: false,\n opacity: 1,\n });\n\n geometry.current = new PlaneGeometry(width, height, 1);\n imagePlane.current = new Mesh(geometry.current, material.current);\n imagePlane.current.position.set(0, 0, 0);\n scene.current!.add(imagePlane.current);\n\n setLoaded(true);\n setTextures(loadedTextures);\n\n requestAnimationFrame(() => {\n renderer.current!.render(scene.current!, camera.current!);\n });\n };\n\n if (inViewport && !loaded) {\n loadImages();\n }\n\n return () => {\n mounted = false;\n };\n }, [height, images, inViewport, loaded, reduceMotion, width]);\n\n const goToIndex = useCallback(\n ({ index, direction = 1 }: { index: number; direction?: number }) => {\n if (!textures) return;\n setImageIndex(index);\n const { uniforms } = material.current!;\n uniforms.nextImage.value = textures[index];\n uniforms.direction.value = direction;\n\n const onComplete = () => {\n uniforms.currentImage.value = textures[index];\n uniforms.dispFactor.value = 0;\n animating.current = false;\n };\n\n if (uniforms.dispFactor.value !== 1) {\n animating.current = true;\n\n animate(uniforms.dispFactor.value, 1, {\n type: 'spring',\n stiffness: 100,\n damping: 20,\n restSpeed: 0.001,\n restDelta: 0.001,\n onUpdate: (value: number) => {\n uniforms.dispFactor.value = value;\n },\n onComplete,\n });\n }\n },\n [textures]\n );\n\n const navigate = useCallback(\n ({ direction, index = null, ...navRest }: { direction: number; index?: number | null; duration?: number }) => {\n if (!loaded) return;\n\n if (animating.current) {\n cancelAnimationFrame(scheduledAnimationFrame.current!);\n scheduledAnimationFrame.current = requestAnimationFrame(() =>\n // Self-recursive call: safe, runs async after `navigate` is fully assigned\n // eslint-disable-next-line react-hooks/immutability\n navigate({ direction, index, ...navRest })\n );\n return;\n }\n\n const finalIndex = determineIndex(imageIndex, index ?? null, textures!, direction);\n goToIndex({ index: finalIndex, direction, ...navRest });\n },\n [goToIndex, imageIndex, loaded, textures]\n );\n\n const onNavClick = useCallback(\n (index: number) => {\n if (index === imageIndex) return;\n const direction = index > imageIndex ? 1 : -1;\n navigate({ direction, index });\n },\n [imageIndex, navigate]\n );\n\n useEffect(() => {\n const handleResize = () => {\n const rect = canvas.current!.getBoundingClientRect();\n setCanvasRect(rect);\n };\n\n window.addEventListener('resize', handleResize);\n handleResize();\n\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, []);\n\n useEffect(() => {\n let animation: number;\n\n const animateLoop = () => {\n animation = requestAnimationFrame(animateLoop);\n if (animating.current) {\n renderer.current!.render(scene.current!, camera.current!);\n }\n };\n\n animation = requestAnimationFrame(animateLoop);\n\n return () => {\n cancelAnimationFrame(animation);\n };\n }, []);\n\n useEffect(() => {\n if (placeholder) {\n const purgePlaceholder = () => {\n setShowPlaceholder(false);\n };\n\n const placeholderElement = placeholderRef.current;\n placeholderElement?.addEventListener('transitionend', purgePlaceholder);\n\n return () => {\n if (placeholderElement) {\n placeholderElement.removeEventListener('transitionend', purgePlaceholder);\n }\n };\n }\n }, [placeholder]);\n\n const onSwipeMove = useCallback(\n (x: number) => {\n if (animating.current || !material.current || !textures || !canvasRect) return;\n lastSwipePosition.current = x;\n const absoluteX = Math.abs(x);\n const containerWidth = canvasRect.width;\n swipeDirection.current = x > 0 ? -1 : 1;\n const swipePercentage = 1 - ((absoluteX - containerWidth) / containerWidth) * -1;\n const nextIndex = determineIndex(imageIndex, null, images, swipeDirection.current);\n const uniforms = material.current.uniforms;\n const displacementClamp = Math.min(Math.max(swipePercentage, 0), 1);\n\n uniforms.currentImage.value = textures[imageIndex];\n uniforms.nextImage.value = textures[nextIndex];\n uniforms.direction.value = swipeDirection.current;\n\n uniforms.dispFactor.value = displacementClamp;\n\n requestAnimationFrame(() => {\n renderer.current!.render(scene.current!, camera.current!);\n });\n },\n [canvasRect, imageIndex, images, textures]\n );\n\n const onSwipeEnd = useCallback(() => {\n if (!material.current) return;\n const uniforms = material.current.uniforms;\n const duration = (1 - uniforms.dispFactor.value) * 1000;\n const position = Math.abs(lastSwipePosition.current!);\n const minSwipeDistance = canvasRect!.width * 0.2;\n lastSwipePosition.current = 0;\n\n if (animating.current) return;\n if (position === 0 || !position) return;\n\n if (position > minSwipeDistance) {\n navigate({\n duration,\n direction: swipeDirection.current!,\n });\n } else {\n uniforms.currentImage.value = uniforms.nextImage.value;\n uniforms.nextImage.value = uniforms.currentImage.value;\n uniforms.dispFactor.value = 1 - uniforms.dispFactor.value;\n\n navigate({\n direction: swipeDirection.current! * -1,\n index: imageIndex,\n });\n }\n }, [canvasRect, imageIndex, navigate]);\n\n const handlePointerMove = useCallback(\n (event: globalThis.PointerEvent) => {\n onSwipeMove(event.clientX - initSwipeX.current!);\n },\n [onSwipeMove]\n );\n\n const handlePointerUp = useCallback(() => {\n setDragging(false);\n onSwipeEnd();\n\n // Self-reference: safe, only runs when the listener actually fires (after assignment)\n // eslint-disable-next-line react-hooks/immutability\n document.removeEventListener('pointerup', handlePointerUp);\n document.removeEventListener('pointermove', handlePointerMove);\n }, [handlePointerMove, onSwipeEnd]);\n\n const handlePointerDown = useCallback(\n (event: PointerEvent) => {\n initSwipeX.current = event.clientX;\n setDragging(true);\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n },\n [handlePointerMove, handlePointerUp]\n );\n\n const handleKeyDown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowRight':\n navigate({ direction: 1 });\n break;\n case 'ArrowLeft':\n navigate({ direction: -1 });\n break;\n }\n };\n\n return (\n <div className={styles.carousel} onKeyDown={handleKeyDown} {...rest}>\n <div className={styles.content}>\n <div\n className={styles.imageWrapper}\n data-dragging={dragging}\n onPointerDown={handlePointerDown}\n style={cssProps({ aspectRatio: `${width} / ${height}` })}\n >\n <div\n aria-atomic\n className={styles.canvasWrapper}\n aria-live=\"polite\"\n aria-label={currentImageAlt}\n role=\"img\"\n >\n <canvas aria-hidden className={styles.canvas} ref={canvas} />\n </div>\n {showPlaceholder && placeholder && (\n <img\n aria-hidden\n className={styles.placeholder}\n data-loaded={loaded && !!textures}\n src={placeholder.src}\n ref={placeholderRef}\n alt=\"\"\n role=\"presentation\"\n />\n )}\n </div>\n <button\n className={styles.button}\n data-prev={true}\n aria-label=\"Previous slide\"\n onClick={() => navigate({ direction: -1 })}\n >\n <ArrowLeft />\n </button>\n <button\n className={styles.button}\n data-next={true}\n aria-label=\"Next slide\"\n onClick={() => navigate({ direction: 1 })}\n >\n <ArrowRight />\n </button>\n </div>\n <div className={styles.nav}>\n {images.map((image, index) => (\n <button\n className={styles.navButton}\n key={image.alt}\n onClick={() => onNavClick(index)}\n aria-label={`Jump to slide ${index + 1}`}\n aria-pressed={index === imageIndex}\n />\n ))}\n </div>\n </div>\n );\n};\n"],"names":["SvgArrowLeft","props","React","SvgArrowRight","fragment","vertex","determineIndex","imageIndex","index","images","direction","length","prevIndex","nextIndex","Carousel","width","height","placeholder","rest","dragging","setDragging","useState","setImageIndex","loaded","setLoaded","showPlaceholder","setShowPlaceholder","textures","setTextures","canvasRect","setCanvasRect","canvas","useRef","imagePlane","geometry","material","scene","camera","renderer","animating","swipeDirection","lastSwipePosition","scheduledAnimationFrame","reduceMotion","useReducedMotion","inViewport","useInViewport","placeholderRef","initSwipeX","currentImageAlt","useEffect","cameraOptions","WebGLRenderer","OrthographicCamera","Scene","Color","cleanScene","cleanRenderer","mounted","anisotropy","texturePromises","image","imageSrc","resolveSrcFromSrcSet","imageTexture","textureLoader","SRGBColorSpace","LinearFilter","loadedTextures","ShaderMaterial","PlaneGeometry","Mesh","goToIndex","useCallback","uniforms","onComplete","animate","value","navigate","navRest","finalIndex","onNavClick","handleResize","rect","animation","animateLoop","purgePlaceholder","placeholderElement","onSwipeMove","x","absoluteX","containerWidth","swipePercentage","displacementClamp","onSwipeEnd","duration","position","minSwipeDistance","handlePointerMove","event","handlePointerUp","handlePointerDown","handleKeyDown","jsxs","styles","cssProps","jsx","ArrowLeft","ArrowRight"],"mappings":"miBACMA,GAAgBC,GAA0BC,EAAM,cAAc,MAAO,CAAE,KAAM,eAAgB,MAAO,GAAI,OAAQ,GAAI,QAAS,YAAa,GAAGD,CAAK,EAAoBC,EAAM,cAAc,OAAQ,CAAE,EAAG,sEAAsE,CAAE,CAAC,ECAhRC,GAAiBF,GAA0BC,EAAM,cAAc,MAAO,CAAE,KAAM,eAAgB,MAAO,GAAI,OAAQ,GAAI,QAAS,YAAa,GAAGD,CAAK,EAAoBC,EAAM,cAAc,OAAQ,CAAE,EAAG,sEAAsE,CAAE,CAAC,gVCDvRE,GAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECAfC,GAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECsCf,SAASC,EACPC,EACAC,EACAC,EACAC,EACA,CACA,GAAIF,IAAU,KAAM,OAAOA,EAC3B,MAAMG,EAASF,EAAO,OAChBG,GAAaL,EAAa,EAAII,GAAUA,EACxCE,GAAaN,EAAa,GAAKI,EAErC,OADmBD,EAAY,EAAIG,EAAYD,CAEjD,CAEO,MAAME,GAAW,CAAC,CAAE,MAAAC,EAAO,OAAAC,EAAQ,OAAAP,EAAQ,YAAAQ,EAAa,GAAGC,KAA0B,CAC1F,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAAS,EAAK,EACxC,CAACd,EAAYe,CAAa,EAAID,EAAAA,SAAS,CAAC,EACxC,CAACE,EAAQC,CAAS,EAAIH,EAAAA,SAAS,EAAK,EACpC,CAACI,EAAiBC,CAAkB,EAAIL,EAAAA,SAAS,EAAI,EACrD,CAACM,EAAUC,CAAW,EAAIP,WAAA,EAC1B,CAACQ,EAAYC,EAAa,EAAIT,WAAA,EAC9BU,EAASC,EAAAA,OAA0B,IAAI,EACvCC,EAAaD,EAAAA,OAAA,EACbE,EAAWF,EAAAA,OAAA,EACXG,EAAWH,EAAAA,OAAA,EACXI,EAAQJ,EAAAA,OAAA,EACRK,EAASL,EAAAA,OAAA,EACTM,EAAWN,EAAAA,OAAA,EACXO,EAAYP,EAAAA,OAAO,EAAK,EACxBQ,EAAiBR,EAAAA,OAAA,EACjBS,EAAoBT,EAAAA,OAAA,EACpBU,EAA0BV,EAAAA,OAAA,EAC1BW,EAAeC,EAAAA,iBAAA,EACfC,EAAaC,EAAAA,cAAcf,EAAQ,EAAI,EACvCgB,EAAiBf,EAAAA,OAAyB,IAAI,EAC9CgB,EAAahB,EAAAA,OAAA,EAEbiB,GAAkB,SAAS1C,EAAa,CAAC,OAAOE,EAAO,MAAM,KACjEA,EAAOF,CAAU,EAAE,GACrB,GAEA2C,EAAAA,UAAU,KACJ/B,IACF,SAAS,KAAK,MAAM,OAAS,YAGxB,IAAM,CACX,SAAS,KAAK,MAAM,OAAS,EAC/B,GACC,CAACA,CAAQ,CAAC,EAEb+B,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAgB,CAACpC,EAAQ,GAAIA,EAAQ,EAAGC,EAAS,EAAGA,EAAS,GAAI,EAAG,GAAI,EAC9E,OAAAsB,EAAS,QAAU,IAAIc,gBAAc,CACnC,OAAQrB,EAAO,QACf,UAAW,GACX,MAAO,GACP,gBAAiB,mBACjB,6BAA8B,EAAA,CAC/B,EACDM,EAAO,QAAU,IAAIgB,EAAAA,mBAAmB,GAAGF,CAAa,EACxDf,EAAM,QAAU,IAAIkB,QACpBhB,EAAS,QAAQ,cAAc,CAAC,EAChCA,EAAS,QAAQ,cAAc,QAAU,CAAG,EAC5CA,EAAS,QAAQ,QAAQvB,EAAOC,CAAM,EACtCsB,EAAS,QAAQ,WAAW,MAAM,MAAQ,OAC1CA,EAAS,QAAQ,WAAW,MAAM,OAAS,OAC3CF,EAAM,QAAQ,WAAa,IAAImB,EAAAA,MAAM,OAAQ,EAC7ClB,EAAO,QAAQ,SAAS,EAAI,EAErB,IAAM,CACXE,EAAU,QAAU,GACpBiB,EAAAA,WAAWpB,EAAM,OAAQ,EACzBqB,EAAAA,cAAcnB,EAAS,OAAQ,CACjC,CACF,EAAG,CAACtB,EAAQD,CAAK,CAAC,EAElBmC,EAAAA,UAAU,IAAM,CACd,IAAIQ,EAAU,GAkDd,OAAIb,GAAc,CAACtB,IAhDA,SAAY,CAC7B,MAAMoC,EAAarB,EAAS,QAAS,aAAa,iBAAA,EAE5CsB,EAAkBnD,EAAO,IAAI,MAAMoD,GAAS,CAChD,MAAMC,EAAWD,EAAM,OACnB,MAAME,EAAAA,qBAAqB,CAAE,OAAQF,EAAM,MAAA,CAAQ,EACnDA,EAAM,IAAK,IACTG,EAAe,MAAMC,gBAAc,UAAUH,CAAQ,EAC3D,aAAMxB,EAAS,QAAS,YAAY0B,CAAY,EAChDA,EAAa,WAAaE,EAAAA,eAC1BF,EAAa,UAAYG,EAAAA,aACzBH,EAAa,UAAYG,EAAAA,aACzBH,EAAa,WAAaL,EAC1BK,EAAa,gBAAkB,GACxBA,CACT,CAAC,EAEKI,EAAiB,MAAM,QAAQ,IAAIR,CAAe,EAEnDF,IAELvB,EAAS,QAAU,IAAIkC,iBAAe,CACpC,SAAU,CACR,WAAY,CAAE,MAAO,CAAA,EACrB,UAAW,CAAE,MAAO,CAAA,EACpB,aAAc,CAAE,MAAOD,EAAe,CAAC,CAAA,EACvC,UAAW,CAAE,MAAOA,EAAe,CAAC,CAAA,EACpC,aAAc,CAAE,MAAOzB,CAAA,CAAa,EAEtC,aAActC,GACd,eAAgBD,GAChB,YAAa,GACb,QAAS,CAAA,CACV,EAED8B,EAAS,QAAU,IAAIoC,EAAAA,cAAcvD,EAAOC,EAAQ,CAAC,EACrDiB,EAAW,QAAU,IAAIsC,EAAAA,KAAKrC,EAAS,QAASC,EAAS,OAAO,EAChEF,EAAW,QAAQ,SAAS,IAAI,EAAG,EAAG,CAAC,EACvCG,EAAM,QAAS,IAAIH,EAAW,OAAO,EAErCT,EAAU,EAAI,EACdI,EAAYwC,CAAc,EAE1B,sBAAsB,IAAM,CAC1B9B,EAAS,QAAS,OAAOF,EAAM,QAAUC,EAAO,OAAQ,CAC1D,CAAC,EACH,GAGE,EAGK,IAAM,CACXqB,EAAU,EACZ,CACF,EAAG,CAAC1C,EAAQP,EAAQoC,EAAYtB,EAAQoB,EAAc5B,CAAK,CAAC,EAE5D,MAAMyD,EAAYC,EAAAA,YAChB,CAAC,CAAE,MAAAjE,EAAO,UAAAE,EAAY,KAA+C,CACnE,GAAI,CAACiB,EAAU,OACfL,EAAcd,CAAK,EACnB,KAAM,CAAE,SAAAkE,GAAavC,EAAS,QAC9BuC,EAAS,UAAU,MAAQ/C,EAASnB,CAAK,EACzCkE,EAAS,UAAU,MAAQhE,EAE3B,MAAMiE,EAAa,IAAM,CACvBD,EAAS,aAAa,MAAQ/C,EAASnB,CAAK,EAC5CkE,EAAS,WAAW,MAAQ,EAC5BnC,EAAU,QAAU,EACtB,EAEImC,EAAS,WAAW,QAAU,IAChCnC,EAAU,QAAU,GAEpBqC,EAAAA,QAAQF,EAAS,WAAW,MAAO,EAAG,CACpC,KAAM,SACN,UAAW,IACX,QAAS,GACT,UAAW,KACX,UAAW,KACX,SAAWG,GAAkB,CAC3BH,EAAS,WAAW,MAAQG,CAC9B,EACA,WAAAF,CAAA,CACD,EAEL,EACA,CAAChD,CAAQ,CAAA,EAGLmD,EAAWL,EAAAA,YACf,CAAC,CAAE,UAAA/D,EAAW,MAAAF,EAAQ,KAAM,GAAGuE,KAA+E,CAC5G,GAAI,CAACxD,EAAQ,OAEb,GAAIgB,EAAU,QAAS,CACrB,qBAAqBG,EAAwB,OAAQ,EACrDA,EAAwB,QAAU,sBAAsB,IAGtDoC,EAAS,CAAE,UAAApE,EAAW,MAAAF,EAAO,GAAGuE,EAAS,CAAA,EAE3C,MACF,CAEA,MAAMC,EAAa1E,EAAeC,EAAYC,GAAS,KAAMmB,EAAWjB,CAAS,EACjF8D,EAAU,CAAE,MAAOQ,EAAY,UAAAtE,EAAW,GAAGqE,EAAS,CACxD,EACA,CAACP,EAAWjE,EAAYgB,EAAQI,CAAQ,CAAA,EAGpCsD,GAAaR,EAAAA,YAChBjE,GAAkB,CACjB,GAAIA,IAAUD,EAAY,OAC1B,MAAMG,EAAYF,EAAQD,EAAa,EAAI,GAC3CuE,EAAS,CAAE,UAAApE,EAAW,MAAAF,EAAO,CAC/B,EACA,CAACD,EAAYuE,CAAQ,CAAA,EAGvB5B,EAAAA,UAAU,IAAM,CACd,MAAMgC,EAAe,IAAM,CACzB,MAAMC,EAAOpD,EAAO,QAAS,sBAAA,EAC7BD,GAAcqD,CAAI,CACpB,EAEA,cAAO,iBAAiB,SAAUD,CAAY,EAC9CA,EAAA,EAEO,IAAM,CACX,OAAO,oBAAoB,SAAUA,CAAY,CACnD,CACF,EAAG,CAAA,CAAE,EAELhC,EAAAA,UAAU,IAAM,CACd,IAAIkC,EAEJ,MAAMC,EAAc,IAAM,CACxBD,EAAY,sBAAsBC,CAAW,EACzC9C,EAAU,SACZD,EAAS,QAAS,OAAOF,EAAM,QAAUC,EAAO,OAAQ,CAE5D,EAEA,OAAA+C,EAAY,sBAAsBC,CAAW,EAEtC,IAAM,CACX,qBAAqBD,CAAS,CAChC,CACF,EAAG,CAAA,CAAE,EAELlC,EAAAA,UAAU,IAAM,CACd,GAAIjC,EAAa,CACf,MAAMqE,EAAmB,IAAM,CAC7B5D,EAAmB,EAAK,CAC1B,EAEM6D,EAAqBxC,EAAe,QAC1C,OAAAwC,GAAA,MAAAA,EAAoB,iBAAiB,gBAAiBD,GAE/C,IAAM,CACPC,GACFA,EAAmB,oBAAoB,gBAAiBD,CAAgB,CAE5E,CACF,CACF,EAAG,CAACrE,CAAW,CAAC,EAEhB,MAAMuE,EAAcf,EAAAA,YACjBgB,GAAc,CACb,GAAIlD,EAAU,SAAW,CAACJ,EAAS,SAAW,CAACR,GAAY,CAACE,EAAY,OACxEY,EAAkB,QAAUgD,EAC5B,MAAMC,EAAY,KAAK,IAAID,CAAC,EACtBE,EAAiB9D,EAAW,MAClCW,EAAe,QAAUiD,EAAI,EAAI,GAAK,EACtC,MAAMG,EAAkB,GAAMF,EAAYC,GAAkBA,EAAkB,GACxE9E,EAAYP,EAAeC,EAAY,KAAME,EAAQ+B,EAAe,OAAO,EAC3EkC,EAAWvC,EAAS,QAAQ,SAC5B0D,EAAoB,KAAK,IAAI,KAAK,IAAID,EAAiB,CAAC,EAAG,CAAC,EAElElB,EAAS,aAAa,MAAQ/C,EAASpB,CAAU,EACjDmE,EAAS,UAAU,MAAQ/C,EAASd,CAAS,EAC7C6D,EAAS,UAAU,MAAQlC,EAAe,QAE1CkC,EAAS,WAAW,MAAQmB,EAE5B,sBAAsB,IAAM,CAC1BvD,EAAS,QAAS,OAAOF,EAAM,QAAUC,EAAO,OAAQ,CAC1D,CAAC,CACH,EACA,CAACR,EAAYtB,EAAYE,EAAQkB,CAAQ,CAAA,EAGrCmE,EAAarB,EAAAA,YAAY,IAAM,CACnC,GAAI,CAACtC,EAAS,QAAS,OACvB,MAAMuC,EAAWvC,EAAS,QAAQ,SAC5B4D,GAAY,EAAIrB,EAAS,WAAW,OAAS,IAC7CsB,EAAW,KAAK,IAAIvD,EAAkB,OAAQ,EAC9CwD,EAAmBpE,EAAY,MAAQ,GAC7CY,EAAkB,QAAU,EAExB,CAAAF,EAAU,UACVyD,IAAa,GAAK,CAACA,IAEnBA,EAAWC,EACbnB,EAAS,CACP,SAAAiB,EACA,UAAWvD,EAAe,OAAA,CAC3B,GAEDkC,EAAS,aAAa,MAAQA,EAAS,UAAU,MACjDA,EAAS,UAAU,MAAQA,EAAS,aAAa,MACjDA,EAAS,WAAW,MAAQ,EAAIA,EAAS,WAAW,MAEpDI,EAAS,CACP,UAAWtC,EAAe,QAAW,GACrC,MAAOjC,CAAA,CACR,IAEL,EAAG,CAACsB,EAAYtB,EAAYuE,CAAQ,CAAC,EAE/BoB,EAAoBzB,EAAAA,YACvB0B,GAAmC,CAClCX,EAAYW,EAAM,QAAUnD,EAAW,OAAQ,CACjD,EACA,CAACwC,CAAW,CAAA,EAGRY,EAAkB3B,EAAAA,YAAY,IAAM,CACxCrD,EAAY,EAAK,EACjB0E,EAAA,EAIA,SAAS,oBAAoB,YAAaM,CAAe,EACzD,SAAS,oBAAoB,cAAeF,CAAiB,CAC/D,EAAG,CAACA,EAAmBJ,CAAU,CAAC,EAE5BO,GAAoB5B,EAAAA,YACvB0B,GAAwB,CACvBnD,EAAW,QAAUmD,EAAM,QAC3B/E,EAAY,EAAI,EAEhB,SAAS,iBAAiB,cAAe8E,CAAiB,EAC1D,SAAS,iBAAiB,YAAaE,CAAe,CACxD,EACA,CAACF,EAAmBE,CAAe,CAAA,EAG/BE,GAAiBH,GAAyB,CAC9C,OAAQA,EAAM,IAAA,CACZ,IAAK,aACHrB,EAAS,CAAE,UAAW,EAAG,EACzB,MACF,IAAK,YACHA,EAAS,CAAE,UAAW,GAAI,EAC1B,KAAA,CAEN,EAEA,OACEyB,OAAC,OAAI,UAAWC,EAAO,SAAU,UAAWF,GAAgB,GAAGpF,EAC7D,SAAA,CAAAqF,EAAAA,KAAC,MAAA,CAAI,UAAWC,EAAO,QACrB,SAAA,CAAAD,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAO,aAClB,gBAAerF,EACf,cAAekF,GACf,MAAOI,EAAAA,SAAS,CAAE,YAAa,GAAG1F,CAAK,MAAMC,CAAM,GAAI,EAEvD,SAAA,CAAA0F,EAAAA,IAAC,MAAA,CACC,cAAW,GACX,UAAWF,EAAO,cAClB,YAAU,SACV,aAAYvD,GACZ,KAAK,MAEL,SAAAyD,EAAAA,IAAC,UAAO,cAAW,GAAC,UAAWF,EAAO,OAAQ,IAAKzE,CAAA,CAAQ,CAAA,CAAA,EAE5DN,GAAmBR,GAClByF,EAAAA,IAAC,MAAA,CACC,cAAW,GACX,UAAWF,EAAO,YAClB,cAAajF,GAAU,CAAC,CAACI,EACzB,IAAKV,EAAY,IACjB,IAAK8B,EACL,IAAI,GACJ,KAAK,cAAA,CAAA,CACP,CAAA,CAAA,EAGJ2D,EAAAA,IAAC,SAAA,CACC,UAAWF,EAAO,OAClB,YAAW,GACX,aAAW,iBACX,QAAS,IAAM1B,EAAS,CAAE,UAAW,GAAI,EAEzC,eAAC6B,GAAA,CAAA,CAAU,CAAA,CAAA,EAEbD,EAAAA,IAAC,SAAA,CACC,UAAWF,EAAO,OAClB,YAAW,GACX,aAAW,aACX,QAAS,IAAM1B,EAAS,CAAE,UAAW,EAAG,EAExC,eAAC8B,GAAA,CAAA,CAAW,CAAA,CAAA,CACd,EACF,EACAF,EAAAA,IAAC,OAAI,UAAWF,EAAO,IACpB,SAAA/F,EAAO,IAAI,CAACoD,EAAOrD,IAClBkG,EAAAA,IAAC,SAAA,CACC,UAAWF,EAAO,UAElB,QAAS,IAAMvB,GAAWzE,CAAK,EAC/B,aAAY,iBAAiBA,EAAQ,CAAC,GACtC,eAAcA,IAAUD,CAAA,EAHnBsD,EAAM,GAAA,CAKd,CAAA,CACH,CAAA,EACF,CAEJ"}
|