@pollinations/ui 0.1.0-alpha.0 → 0.1.0-alpha.1
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 +28 -65
- package/dist/{Chip-SM52sUbZ.d.cts → Chip-CQCq34kS.d.cts} +1 -1
- package/dist/{Chip-C5impfYd.d.ts → Chip-Cj4xG7Te.d.ts} +1 -1
- package/dist/{compositions/app-user.cjs → app-user-menu/sdk.cjs} +148 -148
- package/dist/app-user-menu/sdk.cjs.map +1 -0
- package/dist/{compositions/app-user.js → app-user-menu/sdk.js} +127 -127
- package/dist/app-user-menu/sdk.js.map +1 -0
- package/dist/app.css +94 -3
- package/dist/auth/index.cjs +2 -2
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.js +2 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/{models → gen}/index.cjs +40 -71
- package/dist/gen/index.cjs.map +1 -0
- package/dist/gen/index.d.cts +35 -0
- package/dist/gen/index.d.ts +35 -0
- package/dist/{models → gen}/index.js +31 -66
- package/dist/gen/index.js.map +1 -0
- package/dist/index.cjs +1594 -1142
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +268 -178
- package/dist/index.d.ts +268 -178
- package/dist/index.js +1581 -1134
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme-jRPPBmld.d.cts +20 -0
- package/dist/theme-jRPPBmld.d.ts +20 -0
- package/dist/wallet/index.cjs +4 -4
- package/dist/wallet/index.cjs.map +1 -1
- package/dist/wallet/index.d.cts +2 -2
- package/dist/wallet/index.d.ts +2 -2
- package/dist/wallet/index.js +4 -4
- package/dist/wallet/index.js.map +1 -1
- package/package.json +9 -24
- package/dist/Button-BvLF_Km2.d.cts +0 -26
- package/dist/Button-DQAZzvyQ.d.ts +0 -26
- package/dist/auth/sdk.cjs +0 -221
- package/dist/auth/sdk.cjs.map +0 -1
- package/dist/auth/sdk.d.cts +0 -53
- package/dist/auth/sdk.d.ts +0 -53
- package/dist/auth/sdk.js +0 -188
- package/dist/auth/sdk.js.map +0 -1
- package/dist/compositions/app-user.cjs.map +0 -1
- package/dist/compositions/app-user.js.map +0 -1
- package/dist/modality/index.cjs +0 -86
- package/dist/modality/index.cjs.map +0 -1
- package/dist/modality/index.d.cts +0 -26
- package/dist/modality/index.d.ts +0 -26
- package/dist/modality/index.js +0 -59
- package/dist/modality/index.js.map +0 -1
- package/dist/models/index.cjs.map +0 -1
- package/dist/models/index.d.cts +0 -22
- package/dist/models/index.d.ts +0 -22
- package/dist/models/index.js.map +0 -1
- package/dist/theme-VMRlhqST.d.cts +0 -9
- package/dist/theme-VMRlhqST.d.ts +0 -9
- package/dist/wallet/sdk.cjs +0 -206
- package/dist/wallet/sdk.cjs.map +0 -1
- package/dist/wallet/sdk.d.cts +0 -33
- package/dist/wallet/sdk.d.ts +0 -33
- package/dist/wallet/sdk.js +0 -175
- package/dist/wallet/sdk.js.map +0 -1
- /package/dist/{compositions/app-user.d.cts → app-user-menu/sdk.d.cts} +0 -0
- /package/dist/{compositions/app-user.d.ts → app-user-menu/sdk.d.ts} +0 -0
package/dist/auth/index.js
CHANGED
|
@@ -60,7 +60,7 @@ var Dialog = ({
|
|
|
60
60
|
ArkDialog.Backdrop,
|
|
61
61
|
{
|
|
62
62
|
className: cn(
|
|
63
|
-
"polli:fixed polli:inset-0 polli:z-[100] polli:bg-
|
|
63
|
+
"polli:fixed polli:inset-0 polli:z-[100] polli:bg-ink-950/50",
|
|
64
64
|
backdropClassName
|
|
65
65
|
)
|
|
66
66
|
}
|
|
@@ -81,7 +81,7 @@ var Dialog = ({
|
|
|
81
81
|
"aria-label": ariaLabel,
|
|
82
82
|
"aria-labelledby": labelledBy,
|
|
83
83
|
className: cn(
|
|
84
|
-
"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-
|
|
84
|
+
"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-surface-opaque polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none",
|
|
85
85
|
sizeClasses[size],
|
|
86
86
|
contentClassName
|
|
87
87
|
),
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/primitives/Dialog.tsx","../../src/lib/cn.ts","../../src/modules/auth/AuthModal.tsx"],"sourcesContent":["import { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useRef } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst sizeClasses = {\n sm: \"polli:max-w-md\",\n md: \"polli:max-w-xl\",\n lg: \"polli:max-w-2xl\",\n} as const;\n\nexport type DialogProps = {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: ReactNode;\n triggerAsChild?: boolean;\n triggerClassName?: string;\n title?: ReactNode;\n titleClassName?: string;\n ariaLabel?: string;\n labelledBy?: string;\n theme?: ThemeName;\n size?: keyof typeof sizeClasses;\n showBackdrop?: boolean;\n backdropClassName?: string;\n positionerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n};\n\nexport const Dialog: FC<DialogProps> = ({\n open,\n onOpenChange,\n trigger,\n triggerAsChild = false,\n triggerClassName,\n title,\n titleClassName,\n ariaLabel,\n labelledBy,\n theme = \"blue\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n positionerClassName,\n contentClassName,\n children,\n}) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <ArkDialog.Root\n open={open}\n initialFocusEl={() => contentRef.current}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n {trigger && (\n <ArkDialog.Trigger\n asChild={triggerAsChild}\n className={triggerClassName}\n >\n {trigger}\n </ArkDialog.Trigger>\n )}\n <Portal>\n {showBackdrop && (\n <ArkDialog.Backdrop\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[100] polli:bg-gray-950/50\",\n backdropClassName,\n )}\n />\n )}\n <ArkDialog.Positioner\n data-theme={theme}\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4\",\n positionerClassName,\n )}\n >\n <ArkDialog.Content\n ref={contentRef}\n data-theme={theme}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={cn(\n \"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-white polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none\",\n sizeClasses[size],\n contentClassName,\n )}\n >\n {title && (\n <DialogTitle\n className={cn(\n \"polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong\",\n titleClassName,\n )}\n >\n {title}\n </DialogTitle>\n )}\n {children}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n </Portal>\n </ArkDialog.Root>\n );\n};\n\nexport const DialogTitle = ArkDialog.Title;\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { CSSProperties, ReactNode } from \"react\";\nimport logoUrl from \"../../assets/logo.svg\";\nimport { Dialog } from \"../../primitives/Dialog.tsx\";\n\nconst authLogoMaskUrl = `url('${logoUrl}')`;\n\nconst authLogoMask: CSSProperties = {\n WebkitMaskImage: authLogoMaskUrl,\n WebkitMaskPosition: \"center\",\n WebkitMaskRepeat: \"no-repeat\",\n WebkitMaskSize: \"contain\",\n maskImage: authLogoMaskUrl,\n maskPosition: \"center\",\n maskRepeat: \"no-repeat\",\n maskSize: \"contain\",\n};\n\nexport type AuthModalProps = {\n children: ReactNode;\n dialog?: {\n label?: string;\n labelledBy?: string;\n };\n tone?: \"default\" | \"error\";\n};\n\nexport function AuthModal({\n children,\n dialog,\n tone = \"default\",\n}: AuthModalProps) {\n const borderClass =\n tone === \"error\"\n ? \"polli:border-intent-danger-border\"\n : \"polli:border-theme-border\";\n return (\n <Dialog\n open\n theme=\"amber\"\n showBackdrop={false}\n ariaLabel={dialog?.label}\n labelledBy={dialog?.labelledBy}\n positionerClassName=\"polli:items-start polli:overflow-y-auto polli:bg-theme-bg-pale\"\n contentClassName={`polli:bg-surface-white polli:border-2 ${borderClass} polli:rounded-lg polli:shadow-lg polli:max-w-xl polli:w-full polli:my-auto`}\n >\n {children}\n </Dialog>\n );\n}\n\nexport type AuthModalHeaderProps = {\n children?: ReactNode;\n};\n\nexport function AuthModalHeader({ children }: AuthModalHeaderProps) {\n const logo = (\n <a\n href=\"https://pollinations.ai\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n tabIndex={-1}\n className=\"polli:block polli:shrink-0 polli:text-theme-text-strong polli:focus:outline-none\"\n aria-label=\"pollinations.ai\"\n >\n <span className=\"polli:sr-only\">pollinations.ai</span>\n <span\n aria-hidden=\"true\"\n className=\"polli:block polli:h-8 polli:w-8 polli:bg-current\"\n style={authLogoMask}\n />\n </a>\n );\n if (!children) {\n return (\n <div className=\"polli:flex polli:justify-start polli:px-6 polli:pt-6\">\n {logo}\n </div>\n );\n }\n return (\n <div className=\"polli:px-6 polli:pt-6 polli:pb-2\">\n <div className=\"polli:flex polli:items-center polli:justify-between polli:gap-3\">\n {logo}\n {children}\n </div>\n </div>\n );\n}\n\nexport function AuthModalLoading() {\n return (\n <AuthModal>\n <AuthModalHeader />\n <div className=\"polli:px-8 polli:pt-2 polli:pb-8 polli:text-center\">\n <p className=\"polli:text-theme-text-strong\">Loading...</p>\n </div>\n </AuthModal>\n );\n}\n\nexport function ErrorBanner({ children }: { children: ReactNode }) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:p-4\">\n <p className=\"polli:text-sm polli:text-intent-danger-text\">\n {children}\n </p>\n </div>\n );\n}\n\nexport type AuthInfoCardProps = {\n title?: string;\n children: ReactNode;\n};\n\nexport function AuthInfoCard({\n title = \"Authorize\",\n children,\n}: AuthInfoCardProps) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-theme-bg-pale polli:p-4\">\n <p className=\"polli:mb-2 polli:font-body polli:text-xs polli:font-semibold polli:tracking-wide polli:text-theme-text-soft\">\n {title}\n </p>\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/Dialog.tsx","../../src/lib/cn.ts","../../src/modules/auth/AuthModal.tsx"],"sourcesContent":["import { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useRef } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst sizeClasses = {\n sm: \"polli:max-w-md\",\n md: \"polli:max-w-xl\",\n lg: \"polli:max-w-2xl\",\n} as const;\n\nexport type DialogProps = {\n open: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: ReactNode;\n triggerAsChild?: boolean;\n triggerClassName?: string;\n title?: ReactNode;\n titleClassName?: string;\n ariaLabel?: string;\n labelledBy?: string;\n theme?: ThemeName;\n size?: keyof typeof sizeClasses;\n showBackdrop?: boolean;\n backdropClassName?: string;\n positionerClassName?: string;\n contentClassName?: string;\n children: ReactNode;\n};\n\nexport const Dialog: FC<DialogProps> = ({\n open,\n onOpenChange,\n trigger,\n triggerAsChild = false,\n triggerClassName,\n title,\n titleClassName,\n ariaLabel,\n labelledBy,\n theme = \"blue\",\n size = \"md\",\n showBackdrop = true,\n backdropClassName,\n positionerClassName,\n contentClassName,\n children,\n}) => {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <ArkDialog.Root\n open={open}\n initialFocusEl={() => contentRef.current}\n onOpenChange={(details) => onOpenChange?.(details.open)}\n >\n {trigger && (\n <ArkDialog.Trigger\n asChild={triggerAsChild}\n className={triggerClassName}\n >\n {trigger}\n </ArkDialog.Trigger>\n )}\n <Portal>\n {showBackdrop && (\n <ArkDialog.Backdrop\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[100] polli:bg-ink-950/50\",\n backdropClassName,\n )}\n />\n )}\n <ArkDialog.Positioner\n data-theme={theme}\n className={cn(\n \"polli:fixed polli:inset-0 polli:z-[110] polli:flex polli:h-dvh polli:items-start polli:justify-center polli:overflow-hidden polli:p-4\",\n positionerClassName,\n )}\n >\n <ArkDialog.Content\n ref={contentRef}\n data-theme={theme}\n aria-label={ariaLabel}\n aria-labelledby={labelledBy}\n className={cn(\n \"polli:my-auto polli:w-full polli:overflow-hidden polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-surface-opaque polli:shadow-lg polli:outline-none polli:focus:outline-none polli:focus-visible:outline-none\",\n sizeClasses[size],\n contentClassName,\n )}\n >\n {title && (\n <DialogTitle\n className={cn(\n \"polli:px-6 polli:pt-6 polli:font-subheading polli:text-xl polli:text-theme-text-strong\",\n titleClassName,\n )}\n >\n {title}\n </DialogTitle>\n )}\n {children}\n </ArkDialog.Content>\n </ArkDialog.Positioner>\n </Portal>\n </ArkDialog.Root>\n );\n};\n\nexport const DialogTitle = ArkDialog.Title;\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { CSSProperties, ReactNode } from \"react\";\nimport logoUrl from \"../../assets/logo.svg\";\nimport { Dialog } from \"../../primitives/Dialog.tsx\";\n\nconst authLogoMaskUrl = `url('${logoUrl}')`;\n\nconst authLogoMask: CSSProperties = {\n WebkitMaskImage: authLogoMaskUrl,\n WebkitMaskPosition: \"center\",\n WebkitMaskRepeat: \"no-repeat\",\n WebkitMaskSize: \"contain\",\n maskImage: authLogoMaskUrl,\n maskPosition: \"center\",\n maskRepeat: \"no-repeat\",\n maskSize: \"contain\",\n};\n\nexport type AuthModalProps = {\n children: ReactNode;\n dialog?: {\n label?: string;\n labelledBy?: string;\n };\n tone?: \"default\" | \"error\";\n};\n\nexport function AuthModal({\n children,\n dialog,\n tone = \"default\",\n}: AuthModalProps) {\n const borderClass =\n tone === \"error\"\n ? \"polli:border-intent-danger-border\"\n : \"polli:border-theme-border\";\n return (\n <Dialog\n open\n theme=\"amber\"\n showBackdrop={false}\n ariaLabel={dialog?.label}\n labelledBy={dialog?.labelledBy}\n positionerClassName=\"polli:items-start polli:overflow-y-auto polli:bg-theme-bg-pale\"\n contentClassName={`polli:bg-surface-white polli:border-2 ${borderClass} polli:rounded-lg polli:shadow-lg polli:max-w-xl polli:w-full polli:my-auto`}\n >\n {children}\n </Dialog>\n );\n}\n\nexport type AuthModalHeaderProps = {\n children?: ReactNode;\n};\n\nexport function AuthModalHeader({ children }: AuthModalHeaderProps) {\n const logo = (\n <a\n href=\"https://pollinations.ai\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n tabIndex={-1}\n className=\"polli:block polli:shrink-0 polli:text-theme-text-strong polli:focus:outline-none\"\n aria-label=\"pollinations.ai\"\n >\n <span className=\"polli:sr-only\">pollinations.ai</span>\n <span\n aria-hidden=\"true\"\n className=\"polli:block polli:h-8 polli:w-8 polli:bg-current\"\n style={authLogoMask}\n />\n </a>\n );\n if (!children) {\n return (\n <div className=\"polli:flex polli:justify-start polli:px-6 polli:pt-6\">\n {logo}\n </div>\n );\n }\n return (\n <div className=\"polli:px-6 polli:pt-6 polli:pb-2\">\n <div className=\"polli:flex polli:items-center polli:justify-between polli:gap-3\">\n {logo}\n {children}\n </div>\n </div>\n );\n}\n\nexport function AuthModalLoading() {\n return (\n <AuthModal>\n <AuthModalHeader />\n <div className=\"polli:px-8 polli:pt-2 polli:pb-8 polli:text-center\">\n <p className=\"polli:text-theme-text-strong\">Loading...</p>\n </div>\n </AuthModal>\n );\n}\n\nexport function ErrorBanner({ children }: { children: ReactNode }) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-intent-danger-border polli:bg-intent-danger-bg-light polli:p-4\">\n <p className=\"polli:text-sm polli:text-intent-danger-text\">\n {children}\n </p>\n </div>\n );\n}\n\nexport type AuthInfoCardProps = {\n title?: string;\n children: ReactNode;\n};\n\nexport function AuthInfoCard({\n title = \"Authorize\",\n children,\n}: AuthInfoCardProps) {\n return (\n <div className=\"polli:rounded-lg polli:border-2 polli:border-theme-border polli:bg-theme-bg-pale polli:p-4\">\n <p className=\"polli:mb-2 polli:font-body polli:text-xs polli:font-semibold polli:tracking-wide polli:text-theme-text-soft\">\n {title}\n </p>\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
@@ -17,12 +17,16 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/modules/
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
23
|
-
|
|
20
|
+
// src/modules/gen/index.ts
|
|
21
|
+
var gen_exports = {};
|
|
22
|
+
__export(gen_exports, {
|
|
23
|
+
CATEGORY_LABELS: () => CATEGORY_LABELS,
|
|
24
|
+
ModelSelector: () => ModelSelector,
|
|
25
|
+
categoryLabel: () => categoryLabel,
|
|
26
|
+
getModalityTheme: () => getModalityTheme,
|
|
27
|
+
modalityTheme: () => modalityTheme
|
|
24
28
|
});
|
|
25
|
-
module.exports = __toCommonJS(
|
|
29
|
+
module.exports = __toCommonJS(gen_exports);
|
|
26
30
|
|
|
27
31
|
// src/lib/cn.ts
|
|
28
32
|
var import_clsx = require("clsx");
|
|
@@ -127,10 +131,10 @@ var chipSizes = {
|
|
|
127
131
|
var intentClasses2 = {
|
|
128
132
|
news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
|
|
129
133
|
alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
|
|
130
|
-
neutral: "polli:
|
|
131
|
-
success: "polli:
|
|
132
|
-
warning: "polli:
|
|
133
|
-
danger: "polli:
|
|
134
|
+
neutral: "polli:bg-ink-100/80 polli:text-ink-900",
|
|
135
|
+
success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
|
|
136
|
+
warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
|
|
137
|
+
danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
|
|
134
138
|
};
|
|
135
139
|
var Chip = ({
|
|
136
140
|
theme,
|
|
@@ -348,86 +352,49 @@ var TabButton = ({
|
|
|
348
352
|
);
|
|
349
353
|
};
|
|
350
354
|
|
|
351
|
-
// src/modules/
|
|
352
|
-
var
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
hover,
|
|
360
|
-
text
|
|
361
|
-
},
|
|
362
|
-
image: {
|
|
363
|
-
theme: "pink",
|
|
364
|
-
filled,
|
|
365
|
-
hover,
|
|
366
|
-
text
|
|
367
|
-
},
|
|
368
|
-
video: {
|
|
369
|
-
theme: "teal",
|
|
370
|
-
filled,
|
|
371
|
-
hover,
|
|
372
|
-
text
|
|
373
|
-
},
|
|
374
|
-
audio: {
|
|
375
|
-
theme: "violet",
|
|
376
|
-
filled,
|
|
377
|
-
hover,
|
|
378
|
-
text
|
|
379
|
-
},
|
|
380
|
-
realtime: {
|
|
381
|
-
theme: "green",
|
|
382
|
-
filled,
|
|
383
|
-
hover,
|
|
384
|
-
text
|
|
385
|
-
},
|
|
386
|
-
embedding: {
|
|
387
|
-
theme: "amber",
|
|
388
|
-
filled,
|
|
389
|
-
hover,
|
|
390
|
-
text
|
|
391
|
-
}
|
|
355
|
+
// src/modules/gen/themes.ts
|
|
356
|
+
var MODALITY_THEMES = {
|
|
357
|
+
text: "blue",
|
|
358
|
+
image: "pink",
|
|
359
|
+
video: "teal",
|
|
360
|
+
audio: "amber",
|
|
361
|
+
realtime: "coral",
|
|
362
|
+
embedding: "violet"
|
|
392
363
|
};
|
|
364
|
+
function modalityTheme(category) {
|
|
365
|
+
return MODALITY_THEMES[category];
|
|
366
|
+
}
|
|
393
367
|
function normalize(category) {
|
|
394
368
|
const lower = category.toLowerCase();
|
|
395
369
|
if (lower === "images") return "image";
|
|
396
370
|
if (lower === "embeddings") return "embedding";
|
|
397
|
-
|
|
398
|
-
return lower;
|
|
399
|
-
}
|
|
400
|
-
return null;
|
|
371
|
+
return lower in MODALITY_THEMES ? lower : null;
|
|
401
372
|
}
|
|
402
|
-
function
|
|
373
|
+
function getModalityTheme(category) {
|
|
403
374
|
const key = normalize(category);
|
|
404
|
-
return key ?
|
|
375
|
+
return key ? MODALITY_THEMES[key] : null;
|
|
405
376
|
}
|
|
406
377
|
|
|
407
|
-
// src/modules/
|
|
378
|
+
// src/modules/gen/ModelSelector.tsx
|
|
408
379
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
409
380
|
var CATEGORY_LABELS = {
|
|
410
381
|
image: "Image",
|
|
411
382
|
video: "Video",
|
|
412
383
|
text: "Text",
|
|
413
|
-
audio: "Audio"
|
|
384
|
+
audio: "Audio",
|
|
385
|
+
embedding: "Embeddings",
|
|
386
|
+
realtime: "Realtime"
|
|
414
387
|
};
|
|
415
|
-
function
|
|
416
|
-
return
|
|
388
|
+
function categoryLabel(category) {
|
|
389
|
+
return CATEGORY_LABELS[category];
|
|
417
390
|
}
|
|
418
|
-
function
|
|
419
|
-
|
|
420
|
-
if (!colors) {
|
|
421
|
-
throw new Error(`Missing modality colors for ${category}`);
|
|
422
|
-
}
|
|
423
|
-
return colors.theme;
|
|
391
|
+
function displayModelName(model) {
|
|
392
|
+
return model.title;
|
|
424
393
|
}
|
|
425
394
|
function ModelSelector({
|
|
426
395
|
models,
|
|
427
396
|
category,
|
|
428
397
|
value,
|
|
429
|
-
allowedModelIds,
|
|
430
|
-
isLoggedIn = false,
|
|
431
398
|
isLoading = false,
|
|
432
399
|
onChange
|
|
433
400
|
}) {
|
|
@@ -463,7 +430,6 @@ function ModelSelector({
|
|
|
463
430
|
theme,
|
|
464
431
|
className: "polli:max-h-64 polli:pr-2",
|
|
465
432
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "polli:flex polli:flex-col polli:gap-1", children: filteredModels.map((model) => {
|
|
466
|
-
const isAllowed = !isLoggedIn || !allowedModelIds || allowedModelIds.has(model.id);
|
|
467
433
|
const isActive = value === model.id;
|
|
468
434
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
469
435
|
TabButton,
|
|
@@ -472,7 +438,6 @@ function ModelSelector({
|
|
|
472
438
|
theme: modalityTheme(model.category),
|
|
473
439
|
size: "sm",
|
|
474
440
|
variant: "ghost",
|
|
475
|
-
disabled: !isAllowed,
|
|
476
441
|
className: "polli:w-full polli:justify-between polli:text-left",
|
|
477
442
|
onClick: () => {
|
|
478
443
|
onChange(model.id);
|
|
@@ -503,6 +468,10 @@ function ModelSelector({
|
|
|
503
468
|
}
|
|
504
469
|
// Annotate the CommonJS export names for ESM import in node:
|
|
505
470
|
0 && (module.exports = {
|
|
506
|
-
|
|
471
|
+
CATEGORY_LABELS,
|
|
472
|
+
ModelSelector,
|
|
473
|
+
categoryLabel,
|
|
474
|
+
getModalityTheme,
|
|
475
|
+
modalityTheme
|
|
507
476
|
});
|
|
508
477
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/gen/index.ts","../../src/lib/cn.ts","../../src/primitives/Button.tsx","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Chip.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/ScrollArea.tsx","../../src/primitives/TabButton.tsx","../../src/modules/gen/themes.ts","../../src/modules/gen/ModelSelector.tsx"],"sourcesContent":["export {\n CATEGORY_LABELS,\n categoryLabel,\n ModelSelector,\n type ModelSelectorCategory,\n type ModelSelectorItem,\n type ModelSelectorProps,\n} from \"./ModelSelector.tsx\";\nexport {\n getModalityTheme,\n type Modality,\n modalityTheme,\n} from \"./themes.ts\";\n","import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Button only supports `danger`. Label/status color recipes live on Chip. */\ntype ButtonIntent = \"danger\";\n\nconst sizes = {\n sm: \"polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:px-6 polli:py-3\",\n} as const;\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-bg-hover polli:transition-colors\";\n\n// Single intent: danger. Soft recipe — light tile + deep text, slightly\n// deeper bg on hover. No filled CTAs anywhere.\nconst intentClasses: Record<ButtonIntent, string> = {\n danger:\n \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */\n theme?: ThemeName;\n /** Only `\"danger\"` for now. */\n intent?: ButtonIntent;\n size?: keyof typeof sizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n theme: _theme,\n intent,\n size,\n className,\n disabled,\n}: BaseButtonProps & { disabled?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border\",\n disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n sizes[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n theme,\n intent,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n\n return (\n <Component\n // Cascade override only applies when `intent` is unset.\n data-theme={intent ? undefined : theme}\n data-intent={intent}\n className={buttonClasses({\n theme,\n intent,\n size,\n className,\n disabled,\n })}\n disabled={disabled}\n {...buttonProps}\n >\n {children}\n </Component>\n );\n}\n","import type { FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype ChevronIconProps = {\n /** Rotate 180° when expanded/open. */\n expanded?: boolean;\n className?: string;\n};\n\n/**\n * Canonical chevron used for collapsibles, dropdown triggers, and select pills\n * across the app. One icon everywhere.\n */\nexport const ChevronIcon: FC<ChevronIconProps> = ({ expanded, className }) => (\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n className={cn(\n \"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out\",\n expanded && \"polli:rotate-180\",\n className,\n )}\n >\n <path\n d=\"M3 4.5 6 7.5l3-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n);\n","import type { ComponentPropsWithoutRef, FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Semantic chip labels for status and metadata badges. */\ntype ChipIntent =\n | \"news\"\n | \"alpha\"\n | \"neutral\"\n | \"success\"\n | \"warning\"\n | \"danger\";\n\nconst chipSizes = {\n sm: \"polli:px-2 polli:py-0.5 polli:text-xs\",\n md: \"polli:px-2.5 polli:py-0.5 polli:text-sm\",\n lg: \"polli:px-3 polli:py-1 polli:text-sm\",\n} as const;\n\nconst intentClasses: Record<ChipIntent, string> = {\n news: \"polli:bg-intent-news-bg-light polli:text-intent-news-text\",\n alpha: \"polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text\",\n neutral: \"polli:bg-ink-100/80 polli:text-ink-900\",\n success: \"polli:bg-intent-success-bg-light polli:text-intent-success-text\",\n warning: \"polli:bg-intent-warning-bg-light polli:text-intent-warning-text\",\n danger: \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text\",\n};\n\nexport type ChipProps = ComponentPropsWithoutRef<\"span\"> & {\n /** Override the cascade theme for this chip's subtree. */\n theme?: ThemeName;\n /** Semantic intent. Wins over `theme` when set. */\n intent?: ChipIntent;\n size?: keyof typeof chipSizes;\n};\n\n// Static, rectangular colored container. Round shapes are reserved for buttons.\n// Reads `bg-theme-bg-active` / `text-theme-text-strong` from the cascade unless\n// `intent` is set (semantic, theme-independent).\nexport const Chip: FC<ChipProps> = ({\n theme,\n intent,\n size = \"md\",\n className,\n children,\n ...rest\n}) => {\n const intentClass = intent\n ? intentClasses[intent]\n : \"polli:bg-theme-bg-active polli:text-theme-text-strong\";\n return (\n <span\n {...rest}\n data-theme={theme}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal\",\n chipSizes[size],\n intentClass,\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import { Popover } from \"@ark-ui/react/popover\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst DEFAULT_PANEL =\n \"polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg\";\n\nexport type DropdownProps = {\n theme: ThemeName;\n /** Trigger element; receives the current open state (e.g. to rotate a chevron). */\n trigger: (open: boolean) => ReactNode;\n /** Panel content. As a function, receives `close` to dismiss after a selection. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** Panel placement relative to the trigger. */\n align?: \"start\" | \"end\";\n /** Controlled open state. Omit to let the Dropdown manage its own. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Appended after the surface (widths, padding, max-height…). */\n className?: string;\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n theme,\n trigger,\n children,\n align = \"start\",\n open: openProp,\n onOpenChange,\n className,\n}) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(details) => setOpen(details.open)}\n positioning={{\n placement: align === \"end\" ? \"bottom-end\" : \"bottom-start\",\n }}\n >\n <Popover.Trigger asChild>{trigger(open)}</Popover.Trigger>\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n data-theme={theme}\n className={cn(\n \"polli:z-50 polli:overflow-hidden polli:focus:outline-none\",\n DEFAULT_PANEL,\n className,\n )}\n >\n {typeof children === \"function\"\n ? children(() => setOpen(false))\n : children}\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n );\n};\n","import {\n type ComponentPropsWithoutRef,\n forwardRef,\n type MutableRefObject,\n type PropsWithChildren,\n type Ref,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\ntype ScrollAxis = \"y\" | \"x\";\n\nconst axisClasses: Record<ScrollAxis, string> = {\n y: \"polli:overflow-y-auto polli:overflow-x-hidden\",\n x: \"polli:overflow-x-auto polli:overflow-y-hidden\",\n};\n\ntype ScrollAreaOwnProps = {\n /** Override the ambient cascade theme for this scroller's thumb. */\n theme?: ThemeName;\n /** Scroll direction. Default `y`. */\n axis?: ScrollAxis;\n className?: string;\n};\n\nexport type ScrollAreaProps = PropsWithChildren<\n ScrollAreaOwnProps &\n Omit<ComponentPropsWithoutRef<\"div\">, keyof ScrollAreaOwnProps>\n>;\n\nfunction assignRef<T>(ref: Ref<T> | undefined, value: T | null) {\n if (typeof ref === \"function\") ref(value);\n else if (ref) (ref as MutableRefObject<T | null>).current = value;\n}\n\n/**\n * Themed auto-hide scroll container. Thumb color follows the nearest\n * `[data-theme=\"...\"]` ancestor; pass `theme` to override locally.\n */\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(\n ({ theme, axis = \"y\", className, children, ...rest }, externalRef) => {\n const innerRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n assignRef(externalRef, node);\n },\n [externalRef],\n );\n\n useEffect(() => {\n const element = innerRef.current;\n if (!element) return;\n\n let hideTimer: number | null = null;\n\n const clearHideTimer = () => {\n if (hideTimer !== null) {\n window.clearTimeout(hideTimer);\n hideTimer = null;\n }\n };\n\n const show = () => {\n element.dataset.scrollbarActive = \"true\";\n clearHideTimer();\n };\n\n const hide = () => {\n element.dataset.scrollbarActive = \"false\";\n clearHideTimer();\n };\n\n const scheduleHide = () => {\n clearHideTimer();\n hideTimer = window.setTimeout(hide, 2000);\n };\n\n const handleInteraction = () => {\n show();\n scheduleHide();\n };\n\n hide();\n\n element.addEventListener(\"scroll\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"wheel\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"touchstart\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"pointerdown\", handleInteraction);\n element.addEventListener(\"keydown\", handleInteraction);\n element.addEventListener(\"focusin\", handleInteraction);\n element.addEventListener(\"focusout\", scheduleHide);\n\n return () => {\n clearHideTimer();\n element.removeEventListener(\"scroll\", handleInteraction);\n element.removeEventListener(\"wheel\", handleInteraction);\n element.removeEventListener(\"touchstart\", handleInteraction);\n element.removeEventListener(\"pointerdown\", handleInteraction);\n element.removeEventListener(\"keydown\", handleInteraction);\n element.removeEventListener(\"focusin\", handleInteraction);\n element.removeEventListener(\"focusout\", scheduleHide);\n };\n }, []);\n\n return (\n <div\n {...rest}\n ref={setRef}\n data-theme={theme}\n className={cn(\n \"polli-scrollbar-subtle polli:min-w-0 polli:max-w-full\",\n axisClasses[axis],\n className,\n )}\n >\n {children}\n </div>\n );\n },\n);\n\nScrollArea.displayName = \"ScrollArea\";\n","import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nexport type TabButtonProps = {\n active: boolean;\n onClick: () => void;\n children: ReactNode;\n /** Optional cascade override; defaults to inherited [data-theme]. */\n theme?: ThemeName;\n size?: \"md\" | \"sm\";\n variant?: \"default\" | \"ghost\";\n ariaLabel?: string;\n disabled?: boolean;\n className?: string;\n};\n\nconst sizeClasses = {\n md: \"polli:px-4 polli:py-1.5 polli:text-base\",\n sm: \"polli:px-3 polli:py-1.5 polli:text-sm\",\n} as const;\n\nconst variantClasses = {\n default: {\n base: \"polli:border\",\n active: \"polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border\",\n inactive:\n \"polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active\",\n },\n ghost: {\n base: \"polli:border polli:border-transparent\",\n active: \"polli:bg-theme-bg-active polli:text-theme-text-strong\",\n inactive:\n \"polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong\",\n },\n} as const;\n\nexport const TabButton: FC<TabButtonProps> = ({\n theme,\n active,\n onClick,\n children,\n size = \"md\",\n variant = \"default\",\n ariaLabel,\n disabled = false,\n className,\n}) => {\n const classes = variantClasses[variant];\n return (\n <button\n type=\"button\"\n data-theme={theme}\n onClick={onClick}\n aria-label={ariaLabel}\n aria-pressed={active}\n disabled={disabled}\n className={cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:font-medium polli:leading-normal polli:transition-all polli:duration-200\",\n classes.base,\n active ? classes.active : classes.inactive,\n disabled && \"polli:cursor-not-allowed polli:opacity-50\",\n sizeClasses[size],\n className,\n )}\n >\n {children}\n </button>\n );\n};\n","/** Pollinations model modality to package theme mapping. */\nimport type { ModelCategory } from \"@pollinations/sdk\";\nimport type { ThemeName } from \"../../theme.ts\";\n\n/** A model modality is just a model category. Single source of truth: the SDK. */\nexport type Modality = ModelCategory;\n\nexport const MODALITY_THEMES: Record<ModelCategory, ThemeName> = {\n text: \"blue\",\n image: \"pink\",\n video: \"teal\",\n audio: \"amber\",\n realtime: \"coral\",\n embedding: \"violet\",\n};\n\n/** Theme for a known model category. Total — every category has a theme. */\nexport function modalityTheme(category: ModelCategory): ThemeName {\n return MODALITY_THEMES[category];\n}\n\n/** Map a human-typed category string to the canonical `ModelCategory` key. */\nfunction normalize(category: string): ModelCategory | null {\n const lower = category.toLowerCase();\n if (lower === \"images\") return \"image\";\n if (lower === \"embeddings\") return \"embedding\";\n return lower in MODALITY_THEMES ? (lower as ModelCategory) : null;\n}\n\n/** Theme for an untrusted category string (e.g. user input); null if unknown. */\nexport function getModalityTheme(category: string): ThemeName | null {\n const key = normalize(category);\n return key ? MODALITY_THEMES[key] : null;\n}\n","import type { ModelCategory } from \"@pollinations/sdk\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { Button } from \"../../primitives/Button.tsx\";\nimport { ChevronIcon } from \"../../primitives/ChevronIcon.tsx\";\nimport { Chip } from \"../../primitives/Chip.tsx\";\nimport { Dropdown } from \"../../primitives/Dropdown.tsx\";\nimport { ScrollArea } from \"../../primitives/ScrollArea.tsx\";\nimport { TabButton } from \"../../primitives/TabButton.tsx\";\nimport { modalityTheme } from \"./themes.ts\";\n\nexport type ModelSelectorCategory = ModelCategory;\n\nexport type ModelSelectorItem = {\n id: string;\n name: string;\n title: string;\n description?: string;\n category: ModelSelectorCategory;\n paidOnly?: boolean;\n};\n\nexport type ModelSelectorProps = {\n models: readonly ModelSelectorItem[];\n category: ModelSelectorCategory;\n value: string;\n isLoading?: boolean;\n onChange: (modelId: string) => void;\n};\n\nexport const CATEGORY_LABELS: Record<ModelSelectorCategory, string> = {\n image: \"Image\",\n video: \"Video\",\n text: \"Text\",\n audio: \"Audio\",\n embedding: \"Embeddings\",\n realtime: \"Realtime\",\n};\n\n/** Human-readable label for a model category, e.g. \"embedding\" -> \"Embeddings\". */\nexport function categoryLabel(category: ModelSelectorCategory): string {\n return CATEGORY_LABELS[category];\n}\n\nfunction displayModelName(model: ModelSelectorItem): string {\n return model.title;\n}\n\nexport function ModelSelector({\n models,\n category,\n value,\n isLoading = false,\n onChange,\n}: ModelSelectorProps) {\n const filteredModels = models.filter(\n (model) => model.category === category,\n );\n const currentModel = models.find((model) => model.id === value);\n const theme = modalityTheme(category);\n const modelLabel = currentModel ? displayModelName(currentModel) : \"Select\";\n const accessibleLabel = currentModel\n ? `${CATEGORY_LABELS[category]} model: ${modelLabel}`\n : `Select ${CATEGORY_LABELS[category].toLowerCase()} model`;\n\n return (\n <Dropdown\n theme={theme}\n align=\"end\"\n className=\"polli:w-[min(24rem,calc(100vw-2rem))] polli:p-2\"\n trigger={(open) => (\n <Button\n type=\"button\"\n theme={theme}\n aria-label={accessibleLabel}\n className=\"polli:min-w-64 polli:max-w-full polli:self-start polli:justify-between polli:gap-2\"\n >\n <span className=\"polli:truncate\">{modelLabel}</span>\n <ChevronIcon expanded={open} />\n </Button>\n )}\n >\n {(close) =>\n isLoading ? (\n <p className=\"polli:m-0 polli:px-2 polli:py-2 polli:text-sm polli:text-theme-text-soft\">\n Loading models...\n </p>\n ) : (\n <ScrollArea\n theme={theme}\n className=\"polli:max-h-64 polli:pr-2\"\n >\n <div className=\"polli:flex polli:flex-col polli:gap-1\">\n {filteredModels.map((model) => {\n const isActive = value === model.id;\n return (\n <TabButton\n key={model.id}\n active={isActive}\n theme={modalityTheme(model.category)}\n size=\"sm\"\n variant=\"ghost\"\n className=\"polli:w-full polli:justify-between polli:text-left\"\n onClick={() => {\n onChange(model.id);\n close();\n }}\n >\n <span className=\"polli:truncate\">\n {displayModelName(model)}\n </span>\n {model.paidOnly && (\n <Chip\n size=\"sm\"\n className={cn(\n \"polli:shrink-0\",\n isActive &&\n \"polli:bg-surface-white\",\n )}\n >\n paid\n </Chip>\n )}\n </TabButton>\n );\n })}\n </div>\n </ScrollArea>\n )\n }\n </Dropdown>\n );\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","intentClasses","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ModelCategory } from '@pollinations/sdk';
|
|
3
|
+
import { T as ThemeName } from '../theme-jRPPBmld.cjs';
|
|
4
|
+
|
|
5
|
+
type ModelSelectorCategory = ModelCategory;
|
|
6
|
+
type ModelSelectorItem = {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
title: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
category: ModelSelectorCategory;
|
|
12
|
+
paidOnly?: boolean;
|
|
13
|
+
};
|
|
14
|
+
type ModelSelectorProps = {
|
|
15
|
+
models: readonly ModelSelectorItem[];
|
|
16
|
+
category: ModelSelectorCategory;
|
|
17
|
+
value: string;
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
onChange: (modelId: string) => void;
|
|
20
|
+
};
|
|
21
|
+
declare const CATEGORY_LABELS: Record<ModelSelectorCategory, string>;
|
|
22
|
+
/** Human-readable label for a model category, e.g. "embedding" -> "Embeddings". */
|
|
23
|
+
declare function categoryLabel(category: ModelSelectorCategory): string;
|
|
24
|
+
declare function ModelSelector({ models, category, value, isLoading, onChange, }: ModelSelectorProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
|
|
26
|
+
/** Pollinations model modality to package theme mapping. */
|
|
27
|
+
|
|
28
|
+
/** A model modality is just a model category. Single source of truth: the SDK. */
|
|
29
|
+
type Modality = ModelCategory;
|
|
30
|
+
/** Theme for a known model category. Total — every category has a theme. */
|
|
31
|
+
declare function modalityTheme(category: ModelCategory): ThemeName;
|
|
32
|
+
/** Theme for an untrusted category string (e.g. user input); null if unknown. */
|
|
33
|
+
declare function getModalityTheme(category: string): ThemeName | null;
|
|
34
|
+
|
|
35
|
+
export { CATEGORY_LABELS, type Modality, ModelSelector, type ModelSelectorCategory, type ModelSelectorItem, type ModelSelectorProps, categoryLabel, getModalityTheme, modalityTheme };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ModelCategory } from '@pollinations/sdk';
|
|
3
|
+
import { T as ThemeName } from '../theme-jRPPBmld.js';
|
|
4
|
+
|
|
5
|
+
type ModelSelectorCategory = ModelCategory;
|
|
6
|
+
type ModelSelectorItem = {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
title: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
category: ModelSelectorCategory;
|
|
12
|
+
paidOnly?: boolean;
|
|
13
|
+
};
|
|
14
|
+
type ModelSelectorProps = {
|
|
15
|
+
models: readonly ModelSelectorItem[];
|
|
16
|
+
category: ModelSelectorCategory;
|
|
17
|
+
value: string;
|
|
18
|
+
isLoading?: boolean;
|
|
19
|
+
onChange: (modelId: string) => void;
|
|
20
|
+
};
|
|
21
|
+
declare const CATEGORY_LABELS: Record<ModelSelectorCategory, string>;
|
|
22
|
+
/** Human-readable label for a model category, e.g. "embedding" -> "Embeddings". */
|
|
23
|
+
declare function categoryLabel(category: ModelSelectorCategory): string;
|
|
24
|
+
declare function ModelSelector({ models, category, value, isLoading, onChange, }: ModelSelectorProps): react_jsx_runtime.JSX.Element;
|
|
25
|
+
|
|
26
|
+
/** Pollinations model modality to package theme mapping. */
|
|
27
|
+
|
|
28
|
+
/** A model modality is just a model category. Single source of truth: the SDK. */
|
|
29
|
+
type Modality = ModelCategory;
|
|
30
|
+
/** Theme for a known model category. Total — every category has a theme. */
|
|
31
|
+
declare function modalityTheme(category: ModelCategory): ThemeName;
|
|
32
|
+
/** Theme for an untrusted category string (e.g. user input); null if unknown. */
|
|
33
|
+
declare function getModalityTheme(category: string): ThemeName | null;
|
|
34
|
+
|
|
35
|
+
export { CATEGORY_LABELS, type Modality, ModelSelector, type ModelSelectorCategory, type ModelSelectorItem, type ModelSelectorProps, categoryLabel, getModalityTheme, modalityTheme };
|
|
@@ -101,10 +101,10 @@ var chipSizes = {
|
|
|
101
101
|
var intentClasses2 = {
|
|
102
102
|
news: "polli:bg-intent-news-bg-light polli:text-intent-news-text",
|
|
103
103
|
alpha: "polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text",
|
|
104
|
-
neutral: "polli:
|
|
105
|
-
success: "polli:
|
|
106
|
-
warning: "polli:
|
|
107
|
-
danger: "polli:
|
|
104
|
+
neutral: "polli:bg-ink-100/80 polli:text-ink-900",
|
|
105
|
+
success: "polli:bg-intent-success-bg-light polli:text-intent-success-text",
|
|
106
|
+
warning: "polli:bg-intent-warning-bg-light polli:text-intent-warning-text",
|
|
107
|
+
danger: "polli:bg-intent-danger-bg-light polli:text-intent-danger-text"
|
|
108
108
|
};
|
|
109
109
|
var Chip = ({
|
|
110
110
|
theme,
|
|
@@ -327,86 +327,49 @@ var TabButton = ({
|
|
|
327
327
|
);
|
|
328
328
|
};
|
|
329
329
|
|
|
330
|
-
// src/modules/
|
|
331
|
-
var
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
hover,
|
|
339
|
-
text
|
|
340
|
-
},
|
|
341
|
-
image: {
|
|
342
|
-
theme: "pink",
|
|
343
|
-
filled,
|
|
344
|
-
hover,
|
|
345
|
-
text
|
|
346
|
-
},
|
|
347
|
-
video: {
|
|
348
|
-
theme: "teal",
|
|
349
|
-
filled,
|
|
350
|
-
hover,
|
|
351
|
-
text
|
|
352
|
-
},
|
|
353
|
-
audio: {
|
|
354
|
-
theme: "violet",
|
|
355
|
-
filled,
|
|
356
|
-
hover,
|
|
357
|
-
text
|
|
358
|
-
},
|
|
359
|
-
realtime: {
|
|
360
|
-
theme: "green",
|
|
361
|
-
filled,
|
|
362
|
-
hover,
|
|
363
|
-
text
|
|
364
|
-
},
|
|
365
|
-
embedding: {
|
|
366
|
-
theme: "amber",
|
|
367
|
-
filled,
|
|
368
|
-
hover,
|
|
369
|
-
text
|
|
370
|
-
}
|
|
330
|
+
// src/modules/gen/themes.ts
|
|
331
|
+
var MODALITY_THEMES = {
|
|
332
|
+
text: "blue",
|
|
333
|
+
image: "pink",
|
|
334
|
+
video: "teal",
|
|
335
|
+
audio: "amber",
|
|
336
|
+
realtime: "coral",
|
|
337
|
+
embedding: "violet"
|
|
371
338
|
};
|
|
339
|
+
function modalityTheme(category) {
|
|
340
|
+
return MODALITY_THEMES[category];
|
|
341
|
+
}
|
|
372
342
|
function normalize(category) {
|
|
373
343
|
const lower = category.toLowerCase();
|
|
374
344
|
if (lower === "images") return "image";
|
|
375
345
|
if (lower === "embeddings") return "embedding";
|
|
376
|
-
|
|
377
|
-
return lower;
|
|
378
|
-
}
|
|
379
|
-
return null;
|
|
346
|
+
return lower in MODALITY_THEMES ? lower : null;
|
|
380
347
|
}
|
|
381
|
-
function
|
|
348
|
+
function getModalityTheme(category) {
|
|
382
349
|
const key = normalize(category);
|
|
383
|
-
return key ?
|
|
350
|
+
return key ? MODALITY_THEMES[key] : null;
|
|
384
351
|
}
|
|
385
352
|
|
|
386
|
-
// src/modules/
|
|
353
|
+
// src/modules/gen/ModelSelector.tsx
|
|
387
354
|
import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
388
355
|
var CATEGORY_LABELS = {
|
|
389
356
|
image: "Image",
|
|
390
357
|
video: "Video",
|
|
391
358
|
text: "Text",
|
|
392
|
-
audio: "Audio"
|
|
359
|
+
audio: "Audio",
|
|
360
|
+
embedding: "Embeddings",
|
|
361
|
+
realtime: "Realtime"
|
|
393
362
|
};
|
|
394
|
-
function
|
|
395
|
-
return
|
|
363
|
+
function categoryLabel(category) {
|
|
364
|
+
return CATEGORY_LABELS[category];
|
|
396
365
|
}
|
|
397
|
-
function
|
|
398
|
-
|
|
399
|
-
if (!colors) {
|
|
400
|
-
throw new Error(`Missing modality colors for ${category}`);
|
|
401
|
-
}
|
|
402
|
-
return colors.theme;
|
|
366
|
+
function displayModelName(model) {
|
|
367
|
+
return model.title;
|
|
403
368
|
}
|
|
404
369
|
function ModelSelector({
|
|
405
370
|
models,
|
|
406
371
|
category,
|
|
407
372
|
value,
|
|
408
|
-
allowedModelIds,
|
|
409
|
-
isLoggedIn = false,
|
|
410
373
|
isLoading = false,
|
|
411
374
|
onChange
|
|
412
375
|
}) {
|
|
@@ -442,7 +405,6 @@ function ModelSelector({
|
|
|
442
405
|
theme,
|
|
443
406
|
className: "polli:max-h-64 polli:pr-2",
|
|
444
407
|
children: /* @__PURE__ */ jsx7("div", { className: "polli:flex polli:flex-col polli:gap-1", children: filteredModels.map((model) => {
|
|
445
|
-
const isAllowed = !isLoggedIn || !allowedModelIds || allowedModelIds.has(model.id);
|
|
446
408
|
const isActive = value === model.id;
|
|
447
409
|
return /* @__PURE__ */ jsxs2(
|
|
448
410
|
TabButton,
|
|
@@ -451,7 +413,6 @@ function ModelSelector({
|
|
|
451
413
|
theme: modalityTheme(model.category),
|
|
452
414
|
size: "sm",
|
|
453
415
|
variant: "ghost",
|
|
454
|
-
disabled: !isAllowed,
|
|
455
416
|
className: "polli:w-full polli:justify-between polli:text-left",
|
|
456
417
|
onClick: () => {
|
|
457
418
|
onChange(model.id);
|
|
@@ -481,6 +442,10 @@ function ModelSelector({
|
|
|
481
442
|
);
|
|
482
443
|
}
|
|
483
444
|
export {
|
|
484
|
-
|
|
445
|
+
CATEGORY_LABELS,
|
|
446
|
+
ModelSelector,
|
|
447
|
+
categoryLabel,
|
|
448
|
+
getModalityTheme,
|
|
449
|
+
modalityTheme
|
|
485
450
|
};
|
|
486
451
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/cn.ts","../../src/primitives/Button.tsx","../../src/primitives/ChevronIcon.tsx","../../src/primitives/Chip.tsx","../../src/primitives/Dropdown.tsx","../../src/primitives/ScrollArea.tsx","../../src/primitives/TabButton.tsx","../../src/modules/gen/themes.ts","../../src/modules/gen/ModelSelector.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"polli\" });\n\n/** Internal class merge for polli:-prefixed package primitive classes. */\nexport function cn(...inputs: (string | undefined | null | false)[]) {\n return twMerge(clsx(...inputs));\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Button only supports `danger`. Label/status color recipes live on Chip. */\ntype ButtonIntent = \"danger\";\n\nconst sizes = {\n sm: \"polli:px-2 polli:pt-0.5 polli:pb-1\",\n md: \"polli:px-4 polli:pt-1.5 polli:pb-2\",\n lg: \"polli:px-6 polli:py-3\",\n} as const;\n\n// Cascade-driven base — reads [data-theme] vars.\nconst themeClasses =\n \"polli:bg-theme-bg-active polli:text-theme-text-base \" +\n \"polli:hover:bg-theme-bg-hover polli:transition-colors\";\n\n// Single intent: danger. Soft recipe — light tile + deep text, slightly\n// deeper bg on hover. No filled CTAs anywhere.\nconst intentClasses: Record<ButtonIntent, string> = {\n danger:\n \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text \" +\n \"polli:hover:bg-intent-danger-bg-hover polli:transition-colors\",\n};\n\ntype BaseButtonProps = {\n /** Override the cascade theme for this button's subtree. Ignored when `intent` is set. */\n theme?: ThemeName;\n /** Only `\"danger\"` for now. */\n intent?: ButtonIntent;\n size?: keyof typeof sizes;\n className?: string;\n disabled?: boolean;\n};\n\nconst buttonClasses = ({\n theme: _theme,\n intent,\n size,\n className,\n disabled,\n}: BaseButtonProps & { disabled?: boolean }) => {\n const colorClasses = intent ? intentClasses[intent] : themeClasses;\n return cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:self-center polli:font-medium polli:leading-normal polli:box-border\",\n disabled\n ? \"polli:opacity-50 polli:cursor-not-allowed\"\n : \"polli:hover:filter polli:hover:brightness-105 polli:cursor-pointer\",\n colorClasses,\n sizes[size || \"md\"],\n className,\n );\n};\n\nexport type ButtonProps<T extends React.ElementType = \"button\"> =\n PropsWithChildren<BaseButtonProps> & {\n as?: T;\n } & Omit<React.ComponentPropsWithoutRef<T>, keyof BaseButtonProps | \"as\">;\n\nexport function Button<T extends React.ElementType = \"button\">({\n as,\n children,\n theme,\n intent,\n size,\n className,\n disabled,\n ...buttonProps\n}: ButtonProps<T>) {\n const Component: React.ElementType = as || \"button\";\n\n return (\n <Component\n // Cascade override only applies when `intent` is unset.\n data-theme={intent ? undefined : theme}\n data-intent={intent}\n className={buttonClasses({\n theme,\n intent,\n size,\n className,\n disabled,\n })}\n disabled={disabled}\n {...buttonProps}\n >\n {children}\n </Component>\n );\n}\n","import type { FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\n\ntype ChevronIconProps = {\n /** Rotate 180° when expanded/open. */\n expanded?: boolean;\n className?: string;\n};\n\n/**\n * Canonical chevron used for collapsibles, dropdown triggers, and select pills\n * across the app. One icon everywhere.\n */\nexport const ChevronIcon: FC<ChevronIconProps> = ({ expanded, className }) => (\n <svg\n aria-hidden=\"true\"\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n className={cn(\n \"polli:shrink-0 polli:transition-transform polli:duration-200 polli:ease-out\",\n expanded && \"polli:rotate-180\",\n className,\n )}\n >\n <path\n d=\"M3 4.5 6 7.5l3-3\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n />\n </svg>\n);\n","import type { ComponentPropsWithoutRef, FC } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\n/** Semantic chip labels for status and metadata badges. */\ntype ChipIntent =\n | \"news\"\n | \"alpha\"\n | \"neutral\"\n | \"success\"\n | \"warning\"\n | \"danger\";\n\nconst chipSizes = {\n sm: \"polli:px-2 polli:py-0.5 polli:text-xs\",\n md: \"polli:px-2.5 polli:py-0.5 polli:text-sm\",\n lg: \"polli:px-3 polli:py-1 polli:text-sm\",\n} as const;\n\nconst intentClasses: Record<ChipIntent, string> = {\n news: \"polli:bg-intent-news-bg-light polli:text-intent-news-text\",\n alpha: \"polli:bg-intent-alpha-bg-light polli:text-intent-alpha-text\",\n neutral: \"polli:bg-ink-100/80 polli:text-ink-900\",\n success: \"polli:bg-intent-success-bg-light polli:text-intent-success-text\",\n warning: \"polli:bg-intent-warning-bg-light polli:text-intent-warning-text\",\n danger: \"polli:bg-intent-danger-bg-light polli:text-intent-danger-text\",\n};\n\nexport type ChipProps = ComponentPropsWithoutRef<\"span\"> & {\n /** Override the cascade theme for this chip's subtree. */\n theme?: ThemeName;\n /** Semantic intent. Wins over `theme` when set. */\n intent?: ChipIntent;\n size?: keyof typeof chipSizes;\n};\n\n// Static, rectangular colored container. Round shapes are reserved for buttons.\n// Reads `bg-theme-bg-active` / `text-theme-text-strong` from the cascade unless\n// `intent` is set (semantic, theme-independent).\nexport const Chip: FC<ChipProps> = ({\n theme,\n intent,\n size = \"md\",\n className,\n children,\n ...rest\n}) => {\n const intentClass = intent\n ? intentClasses[intent]\n : \"polli:bg-theme-bg-active polli:text-theme-text-strong\";\n return (\n <span\n {...rest}\n data-theme={theme}\n className={cn(\n \"polli:inline-flex polli:shrink-0 polli:items-center polli:gap-1 polli:rounded-lg polli:font-medium polli:leading-normal\",\n chipSizes[size],\n intentClass,\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import { Popover } from \"@ark-ui/react/popover\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport type { FC, ReactNode } from \"react\";\nimport { useState } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nconst DEFAULT_PANEL =\n \"polli:rounded-lg polli:border polli:border-theme-border polli:bg-theme-bg-pale polli:shadow-lg\";\n\nexport type DropdownProps = {\n theme: ThemeName;\n /** Trigger element; receives the current open state (e.g. to rotate a chevron). */\n trigger: (open: boolean) => ReactNode;\n /** Panel content. As a function, receives `close` to dismiss after a selection. */\n children: ReactNode | ((close: () => void) => ReactNode);\n /** Panel placement relative to the trigger. */\n align?: \"start\" | \"end\";\n /** Controlled open state. Omit to let the Dropdown manage its own. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Appended after the surface (widths, padding, max-height…). */\n className?: string;\n};\n\nexport const Dropdown: FC<DropdownProps> = ({\n theme,\n trigger,\n children,\n align = \"start\",\n open: openProp,\n onOpenChange,\n className,\n}) => {\n const [internalOpen, setInternalOpen] = useState(false);\n const isControlled = openProp !== undefined;\n const open = isControlled ? openProp : internalOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n return (\n <Popover.Root\n open={open}\n onOpenChange={(details) => setOpen(details.open)}\n positioning={{\n placement: align === \"end\" ? \"bottom-end\" : \"bottom-start\",\n }}\n >\n <Popover.Trigger asChild>{trigger(open)}</Popover.Trigger>\n <Portal>\n <Popover.Positioner>\n <Popover.Content\n data-theme={theme}\n className={cn(\n \"polli:z-50 polli:overflow-hidden polli:focus:outline-none\",\n DEFAULT_PANEL,\n className,\n )}\n >\n {typeof children === \"function\"\n ? children(() => setOpen(false))\n : children}\n </Popover.Content>\n </Popover.Positioner>\n </Portal>\n </Popover.Root>\n );\n};\n","import {\n type ComponentPropsWithoutRef,\n forwardRef,\n type MutableRefObject,\n type PropsWithChildren,\n type Ref,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\ntype ScrollAxis = \"y\" | \"x\";\n\nconst axisClasses: Record<ScrollAxis, string> = {\n y: \"polli:overflow-y-auto polli:overflow-x-hidden\",\n x: \"polli:overflow-x-auto polli:overflow-y-hidden\",\n};\n\ntype ScrollAreaOwnProps = {\n /** Override the ambient cascade theme for this scroller's thumb. */\n theme?: ThemeName;\n /** Scroll direction. Default `y`. */\n axis?: ScrollAxis;\n className?: string;\n};\n\nexport type ScrollAreaProps = PropsWithChildren<\n ScrollAreaOwnProps &\n Omit<ComponentPropsWithoutRef<\"div\">, keyof ScrollAreaOwnProps>\n>;\n\nfunction assignRef<T>(ref: Ref<T> | undefined, value: T | null) {\n if (typeof ref === \"function\") ref(value);\n else if (ref) (ref as MutableRefObject<T | null>).current = value;\n}\n\n/**\n * Themed auto-hide scroll container. Thumb color follows the nearest\n * `[data-theme=\"...\"]` ancestor; pass `theme` to override locally.\n */\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(\n ({ theme, axis = \"y\", className, children, ...rest }, externalRef) => {\n const innerRef = useRef<HTMLDivElement | null>(null);\n\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n innerRef.current = node;\n assignRef(externalRef, node);\n },\n [externalRef],\n );\n\n useEffect(() => {\n const element = innerRef.current;\n if (!element) return;\n\n let hideTimer: number | null = null;\n\n const clearHideTimer = () => {\n if (hideTimer !== null) {\n window.clearTimeout(hideTimer);\n hideTimer = null;\n }\n };\n\n const show = () => {\n element.dataset.scrollbarActive = \"true\";\n clearHideTimer();\n };\n\n const hide = () => {\n element.dataset.scrollbarActive = \"false\";\n clearHideTimer();\n };\n\n const scheduleHide = () => {\n clearHideTimer();\n hideTimer = window.setTimeout(hide, 2000);\n };\n\n const handleInteraction = () => {\n show();\n scheduleHide();\n };\n\n hide();\n\n element.addEventListener(\"scroll\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"wheel\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"touchstart\", handleInteraction, {\n passive: true,\n });\n element.addEventListener(\"pointerdown\", handleInteraction);\n element.addEventListener(\"keydown\", handleInteraction);\n element.addEventListener(\"focusin\", handleInteraction);\n element.addEventListener(\"focusout\", scheduleHide);\n\n return () => {\n clearHideTimer();\n element.removeEventListener(\"scroll\", handleInteraction);\n element.removeEventListener(\"wheel\", handleInteraction);\n element.removeEventListener(\"touchstart\", handleInteraction);\n element.removeEventListener(\"pointerdown\", handleInteraction);\n element.removeEventListener(\"keydown\", handleInteraction);\n element.removeEventListener(\"focusin\", handleInteraction);\n element.removeEventListener(\"focusout\", scheduleHide);\n };\n }, []);\n\n return (\n <div\n {...rest}\n ref={setRef}\n data-theme={theme}\n className={cn(\n \"polli-scrollbar-subtle polli:min-w-0 polli:max-w-full\",\n axisClasses[axis],\n className,\n )}\n >\n {children}\n </div>\n );\n },\n);\n\nScrollArea.displayName = \"ScrollArea\";\n","import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../lib/cn.ts\";\nimport type { ThemeName } from \"../theme.ts\";\n\nexport type TabButtonProps = {\n active: boolean;\n onClick: () => void;\n children: ReactNode;\n /** Optional cascade override; defaults to inherited [data-theme]. */\n theme?: ThemeName;\n size?: \"md\" | \"sm\";\n variant?: \"default\" | \"ghost\";\n ariaLabel?: string;\n disabled?: boolean;\n className?: string;\n};\n\nconst sizeClasses = {\n md: \"polli:px-4 polli:py-1.5 polli:text-base\",\n sm: \"polli:px-3 polli:py-1.5 polli:text-sm\",\n} as const;\n\nconst variantClasses = {\n default: {\n base: \"polli:border\",\n active: \"polli:bg-theme-bg-active polli:text-theme-text-strong polli:border-theme-border\",\n inactive:\n \"polli:bg-theme-bg-subtle polli:text-theme-text-base polli:border-theme-border polli:hover:bg-theme-bg-active\",\n },\n ghost: {\n base: \"polli:border polli:border-transparent\",\n active: \"polli:bg-theme-bg-active polli:text-theme-text-strong\",\n inactive:\n \"polli:bg-transparent polli:text-theme-text-base polli:hover:bg-theme-bg-subtle polli:hover:text-theme-text-strong\",\n },\n} as const;\n\nexport const TabButton: FC<TabButtonProps> = ({\n theme,\n active,\n onClick,\n children,\n size = \"md\",\n variant = \"default\",\n ariaLabel,\n disabled = false,\n className,\n}) => {\n const classes = variantClasses[variant];\n return (\n <button\n type=\"button\"\n data-theme={theme}\n onClick={onClick}\n aria-label={ariaLabel}\n aria-pressed={active}\n disabled={disabled}\n className={cn(\n \"polli-control polli:inline-flex polli:items-center polli:justify-center polli:rounded-full polli:font-medium polli:leading-normal polli:transition-all polli:duration-200\",\n classes.base,\n active ? classes.active : classes.inactive,\n disabled && \"polli:cursor-not-allowed polli:opacity-50\",\n sizeClasses[size],\n className,\n )}\n >\n {children}\n </button>\n );\n};\n","/** Pollinations model modality to package theme mapping. */\nimport type { ModelCategory } from \"@pollinations/sdk\";\nimport type { ThemeName } from \"../../theme.ts\";\n\n/** A model modality is just a model category. Single source of truth: the SDK. */\nexport type Modality = ModelCategory;\n\nexport const MODALITY_THEMES: Record<ModelCategory, ThemeName> = {\n text: \"blue\",\n image: \"pink\",\n video: \"teal\",\n audio: \"amber\",\n realtime: \"coral\",\n embedding: \"violet\",\n};\n\n/** Theme for a known model category. Total — every category has a theme. */\nexport function modalityTheme(category: ModelCategory): ThemeName {\n return MODALITY_THEMES[category];\n}\n\n/** Map a human-typed category string to the canonical `ModelCategory` key. */\nfunction normalize(category: string): ModelCategory | null {\n const lower = category.toLowerCase();\n if (lower === \"images\") return \"image\";\n if (lower === \"embeddings\") return \"embedding\";\n return lower in MODALITY_THEMES ? (lower as ModelCategory) : null;\n}\n\n/** Theme for an untrusted category string (e.g. user input); null if unknown. */\nexport function getModalityTheme(category: string): ThemeName | null {\n const key = normalize(category);\n return key ? MODALITY_THEMES[key] : null;\n}\n","import type { ModelCategory } from \"@pollinations/sdk\";\nimport { cn } from \"../../lib/cn.ts\";\nimport { Button } from \"../../primitives/Button.tsx\";\nimport { ChevronIcon } from \"../../primitives/ChevronIcon.tsx\";\nimport { Chip } from \"../../primitives/Chip.tsx\";\nimport { Dropdown } from \"../../primitives/Dropdown.tsx\";\nimport { ScrollArea } from \"../../primitives/ScrollArea.tsx\";\nimport { TabButton } from \"../../primitives/TabButton.tsx\";\nimport { modalityTheme } from \"./themes.ts\";\n\nexport type ModelSelectorCategory = ModelCategory;\n\nexport type ModelSelectorItem = {\n id: string;\n name: string;\n title: string;\n description?: string;\n category: ModelSelectorCategory;\n paidOnly?: boolean;\n};\n\nexport type ModelSelectorProps = {\n models: readonly ModelSelectorItem[];\n category: ModelSelectorCategory;\n value: string;\n isLoading?: boolean;\n onChange: (modelId: string) => void;\n};\n\nexport const CATEGORY_LABELS: Record<ModelSelectorCategory, string> = {\n image: \"Image\",\n video: \"Video\",\n text: \"Text\",\n audio: \"Audio\",\n embedding: \"Embeddings\",\n realtime: \"Realtime\",\n};\n\n/** Human-readable label for a model category, e.g. \"embedding\" -> \"Embeddings\". */\nexport function categoryLabel(category: ModelSelectorCategory): string {\n return CATEGORY_LABELS[category];\n}\n\nfunction displayModelName(model: ModelSelectorItem): string {\n return model.title;\n}\n\nexport function ModelSelector({\n models,\n category,\n value,\n isLoading = false,\n onChange,\n}: ModelSelectorProps) {\n const filteredModels = models.filter(\n (model) => model.category === category,\n );\n const currentModel = models.find((model) => model.id === value);\n const theme = modalityTheme(category);\n const modelLabel = currentModel ? displayModelName(currentModel) : \"Select\";\n const accessibleLabel = currentModel\n ? `${CATEGORY_LABELS[category]} model: ${modelLabel}`\n : `Select ${CATEGORY_LABELS[category].toLowerCase()} model`;\n\n return (\n <Dropdown\n theme={theme}\n align=\"end\"\n className=\"polli:w-[min(24rem,calc(100vw-2rem))] polli:p-2\"\n trigger={(open) => (\n <Button\n type=\"button\"\n theme={theme}\n aria-label={accessibleLabel}\n className=\"polli:min-w-64 polli:max-w-full polli:self-start polli:justify-between polli:gap-2\"\n >\n <span className=\"polli:truncate\">{modelLabel}</span>\n <ChevronIcon expanded={open} />\n </Button>\n )}\n >\n {(close) =>\n isLoading ? (\n <p className=\"polli:m-0 polli:px-2 polli:py-2 polli:text-sm polli:text-theme-text-soft\">\n Loading models...\n </p>\n ) : (\n <ScrollArea\n theme={theme}\n className=\"polli:max-h-64 polli:pr-2\"\n >\n <div className=\"polli:flex polli:flex-col polli:gap-1\">\n {filteredModels.map((model) => {\n const isActive = value === model.id;\n return (\n <TabButton\n key={model.id}\n active={isActive}\n theme={modalityTheme(model.category)}\n size=\"sm\"\n variant=\"ghost\"\n className=\"polli:w-full polli:justify-between polli:text-left\"\n onClick={() => {\n onChange(model.id);\n close();\n }}\n >\n <span className=\"polli:truncate\">\n {displayModelName(model)}\n </span>\n {model.paidOnly && (\n <Chip\n size=\"sm\"\n className={cn(\n \"polli:shrink-0\",\n isActive &&\n \"polli:bg-surface-white\",\n )}\n >\n paid\n </Chip>\n )}\n </TabButton>\n );\n })}\n </div>\n </ScrollArea>\n )\n }\n </Dropdown>\n );\n}\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,2BAA2B;AAEpC,IAAM,UAAU,oBAAoB,EAAE,QAAQ,QAAQ,CAAC;AAGhD,SAAS,MAAM,QAA+C;AACjE,SAAO,QAAQ,KAAK,GAAG,MAAM,CAAC;AAClC;;;ACiEQ;AAlER,IAAM,QAAQ;AAAA,EACV,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR;AAGA,IAAM,eACF;AAKJ,IAAM,gBAA8C;AAAA,EAChD,QACI;AAER;AAYA,IAAM,gBAAgB,CAAC;AAAA,EACnB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,MAAgD;AAC5C,QAAM,eAAe,SAAS,cAAc,MAAM,IAAI;AACtD,SAAO;AAAA,IACH;AAAA,IACA,WACM,8CACA;AAAA,IACN;AAAA,IACA,MAAM,QAAQ,IAAI;AAAA,IAClB;AAAA,EACJ;AACJ;AAOO,SAAS,OAA+C;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACP,GAAmB;AACf,QAAM,YAA+B,MAAM;AAE3C,SACI;AAAA,IAAC;AAAA;AAAA,MAEG,cAAY,SAAS,SAAY;AAAA,MACjC,eAAa;AAAA,MACb,WAAW,cAAc;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,MACD;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACL;AAER;;;ACjEQ,gBAAAA,YAAA;AAZD,IAAM,cAAoC,CAAC,EAAE,UAAU,UAAU,MACpE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACG,eAAY;AAAA,IACZ,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,WAAW;AAAA,MACP;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,IACJ;AAAA,IAEA,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACG,GAAE;AAAA,QACF,MAAK;AAAA,QACL,QAAO;AAAA,QACP,eAAc;AAAA,QACd,gBAAe;AAAA,QACf,aAAY;AAAA;AAAA,IAChB;AAAA;AACJ;;;ACkBI,gBAAAC,YAAA;AAtCR,IAAM,YAAY;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACR;AAEA,IAAMC,iBAA4C;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACZ;AAaO,IAAM,OAAsB,CAAC;AAAA,EAChC;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,GAAG;AACP,MAAM;AACF,QAAM,cAAc,SACdA,eAAc,MAAM,IACpB;AACN,SACI,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACI,GAAG;AAAA,MACJ,cAAY;AAAA,MACZ,WAAW;AAAA,QACP;AAAA,QACA,UAAU,IAAI;AAAA,QACd;AAAA,QACA;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,EACL;AAER;;;AChEA,SAAS,eAAe;AACxB,SAAS,cAAc;AAEvB,SAAS,gBAAgB;AAyCjB,SAOI,OAAAE,MAPJ;AArCR,IAAM,gBACF;AAiBG,IAAM,WAA8B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,MAAM;AAAA,EACN;AAAA,EACA;AACJ,MAAM;AACF,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,eAAe,aAAa;AAClC,QAAM,OAAO,eAAe,WAAW;AAEvC,QAAM,UAAU,CAAC,SAAkB;AAC/B,QAAI,CAAC,aAAc,iBAAgB,IAAI;AACvC,mBAAe,IAAI;AAAA,EACvB;AAEA,SACI;AAAA,IAAC,QAAQ;AAAA,IAAR;AAAA,MACG;AAAA,MACA,cAAc,CAAC,YAAY,QAAQ,QAAQ,IAAI;AAAA,MAC/C,aAAa;AAAA,QACT,WAAW,UAAU,QAAQ,eAAe;AAAA,MAChD;AAAA,MAEA;AAAA,wBAAAA,KAAC,QAAQ,SAAR,EAAgB,SAAO,MAAE,kBAAQ,IAAI,GAAE;AAAA,QACxC,gBAAAA,KAAC,UACG,0BAAAA,KAAC,QAAQ,YAAR,EACG,0BAAAA;AAAA,UAAC,QAAQ;AAAA,UAAR;AAAA,YACG,cAAY;AAAA,YACZ,WAAW;AAAA,cACP;AAAA,cACA;AAAA,cACA;AAAA,YACJ;AAAA,YAEC,iBAAO,aAAa,aACf,SAAS,MAAM,QAAQ,KAAK,CAAC,IAC7B;AAAA;AAAA,QACV,GACJ,GACJ;AAAA;AAAA;AAAA,EACJ;AAER;;;ACtEA;AAAA,EAEI;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,OACG;AA2GK,gBAAAC,YAAA;AArGZ,IAAM,cAA0C;AAAA,EAC5C,GAAG;AAAA,EACH,GAAG;AACP;AAeA,SAAS,UAAa,KAAyB,OAAiB;AAC5D,MAAI,OAAO,QAAQ,WAAY,KAAI,KAAK;AAAA,WAC/B,IAAK,CAAC,IAAmC,UAAU;AAChE;AAMO,IAAM,aAAa;AAAA,EACtB,CAAC,EAAE,OAAO,OAAO,KAAK,WAAW,UAAU,GAAG,KAAK,GAAG,gBAAgB;AAClE,UAAM,WAAW,OAA8B,IAAI;AAEnD,UAAM,SAAS;AAAA,MACX,CAAC,SAAgC;AAC7B,iBAAS,UAAU;AACnB,kBAAU,aAAa,IAAI;AAAA,MAC/B;AAAA,MACA,CAAC,WAAW;AAAA,IAChB;AAEA,cAAU,MAAM;AACZ,YAAM,UAAU,SAAS;AACzB,UAAI,CAAC,QAAS;AAEd,UAAI,YAA2B;AAE/B,YAAM,iBAAiB,MAAM;AACzB,YAAI,cAAc,MAAM;AACpB,iBAAO,aAAa,SAAS;AAC7B,sBAAY;AAAA,QAChB;AAAA,MACJ;AAEA,YAAM,OAAO,MAAM;AACf,gBAAQ,QAAQ,kBAAkB;AAClC,uBAAe;AAAA,MACnB;AAEA,YAAM,OAAO,MAAM;AACf,gBAAQ,QAAQ,kBAAkB;AAClC,uBAAe;AAAA,MACnB;AAEA,YAAM,eAAe,MAAM;AACvB,uBAAe;AACf,oBAAY,OAAO,WAAW,MAAM,GAAI;AAAA,MAC5C;AAEA,YAAM,oBAAoB,MAAM;AAC5B,aAAK;AACL,qBAAa;AAAA,MACjB;AAEA,WAAK;AAEL,cAAQ,iBAAiB,UAAU,mBAAmB;AAAA,QAClD,SAAS;AAAA,MACb,CAAC;AACD,cAAQ,iBAAiB,SAAS,mBAAmB;AAAA,QACjD,SAAS;AAAA,MACb,CAAC;AACD,cAAQ,iBAAiB,cAAc,mBAAmB;AAAA,QACtD,SAAS;AAAA,MACb,CAAC;AACD,cAAQ,iBAAiB,eAAe,iBAAiB;AACzD,cAAQ,iBAAiB,WAAW,iBAAiB;AACrD,cAAQ,iBAAiB,WAAW,iBAAiB;AACrD,cAAQ,iBAAiB,YAAY,YAAY;AAEjD,aAAO,MAAM;AACT,uBAAe;AACf,gBAAQ,oBAAoB,UAAU,iBAAiB;AACvD,gBAAQ,oBAAoB,SAAS,iBAAiB;AACtD,gBAAQ,oBAAoB,cAAc,iBAAiB;AAC3D,gBAAQ,oBAAoB,eAAe,iBAAiB;AAC5D,gBAAQ,oBAAoB,WAAW,iBAAiB;AACxD,gBAAQ,oBAAoB,WAAW,iBAAiB;AACxD,gBAAQ,oBAAoB,YAAY,YAAY;AAAA,MACxD;AAAA,IACJ,GAAG,CAAC,CAAC;AAEL,WACI,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACI,GAAG;AAAA,QACJ,KAAK;AAAA,QACL,cAAY;AAAA,QACZ,WAAW;AAAA,UACP;AAAA,UACA,YAAY,IAAI;AAAA,UAChB;AAAA,QACJ;AAAA,QAEC;AAAA;AAAA,IACL;AAAA,EAER;AACJ;AAEA,WAAW,cAAc;;;AClFjB,gBAAAC,YAAA;AAjCR,IAAM,cAAc;AAAA,EAChB,IAAI;AAAA,EACJ,IAAI;AACR;AAEA,IAAM,iBAAiB;AAAA,EACnB,SAAS;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UACI;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACH,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,UACI;AAAA,EACR;AACJ;AAEO,IAAM,YAAgC,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA,WAAW;AAAA,EACX;AACJ,MAAM;AACF,QAAM,UAAU,eAAe,OAAO;AACtC,SACI,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACG,MAAK;AAAA,MACL,cAAY;AAAA,MACZ;AAAA,MACA,cAAY;AAAA,MACZ,gBAAc;AAAA,MACd;AAAA,MACA,WAAW;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,QACR,SAAS,QAAQ,SAAS,QAAQ;AAAA,QAClC,YAAY;AAAA,QACZ,YAAY,IAAI;AAAA,QAChB;AAAA,MACJ;AAAA,MAEC;AAAA;AAAA,EACL;AAER;;;AC9DO,IAAM,kBAAoD;AAAA,EAC7D,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AACf;AAGO,SAAS,cAAc,UAAoC;AAC9D,SAAO,gBAAgB,QAAQ;AACnC;AAGA,SAAS,UAAU,UAAwC;AACvD,QAAM,QAAQ,SAAS,YAAY;AACnC,MAAI,UAAU,SAAU,QAAO;AAC/B,MAAI,UAAU,aAAc,QAAO;AACnC,SAAO,SAAS,kBAAmB,QAA0B;AACjE;AAGO,SAAS,iBAAiB,UAAoC;AACjE,QAAM,MAAM,UAAU,QAAQ;AAC9B,SAAO,MAAM,gBAAgB,GAAG,IAAI;AACxC;;;ACqCgB,SAMI,OAAAC,MANJ,QAAAC,aAAA;AAzCT,IAAM,kBAAyD;AAAA,EAClE,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,UAAU;AACd;AAGO,SAAS,cAAc,UAAyC;AACnE,SAAO,gBAAgB,QAAQ;AACnC;AAEA,SAAS,iBAAiB,OAAkC;AACxD,SAAO,MAAM;AACjB;AAEO,SAAS,cAAc;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACJ,GAAuB;AACnB,QAAM,iBAAiB,OAAO;AAAA,IAC1B,CAAC,UAAU,MAAM,aAAa;AAAA,EAClC;AACA,QAAM,eAAe,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,KAAK;AAC9D,QAAM,QAAQ,cAAc,QAAQ;AACpC,QAAM,aAAa,eAAe,iBAAiB,YAAY,IAAI;AACnE,QAAM,kBAAkB,eAClB,GAAG,gBAAgB,QAAQ,CAAC,WAAW,UAAU,KACjD,UAAU,gBAAgB,QAAQ,EAAE,YAAY,CAAC;AAEvD,SACI,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACG;AAAA,MACA,OAAM;AAAA,MACN,WAAU;AAAA,MACV,SAAS,CAAC,SACN,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACG,MAAK;AAAA,UACL;AAAA,UACA,cAAY;AAAA,UACZ,WAAU;AAAA,UAEV;AAAA,4BAAAD,KAAC,UAAK,WAAU,kBAAkB,sBAAW;AAAA,YAC7C,gBAAAA,KAAC,eAAY,UAAU,MAAM;AAAA;AAAA;AAAA,MACjC;AAAA,MAGH,WAAC,UACE,YACI,gBAAAA,KAAC,OAAE,WAAU,4EAA2E,+BAExF,IAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACG;AAAA,UACA,WAAU;AAAA,UAEV,0BAAAA,KAAC,SAAI,WAAU,yCACV,yBAAe,IAAI,CAAC,UAAU;AAC3B,kBAAM,WAAW,UAAU,MAAM;AACjC,mBACI,gBAAAC;AAAA,cAAC;AAAA;AAAA,gBAEG,QAAQ;AAAA,gBACR,OAAO,cAAc,MAAM,QAAQ;AAAA,gBACnC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,WAAU;AAAA,gBACV,SAAS,MAAM;AACX,2BAAS,MAAM,EAAE;AACjB,wBAAM;AAAA,gBACV;AAAA,gBAEA;AAAA,kCAAAD,KAAC,UAAK,WAAU,kBACX,2BAAiB,KAAK,GAC3B;AAAA,kBACC,MAAM,YACH,gBAAAA;AAAA,oBAAC;AAAA;AAAA,sBACG,MAAK;AAAA,sBACL,WAAW;AAAA,wBACP;AAAA,wBACA,YACI;AAAA,sBACR;AAAA,sBACH;AAAA;AAAA,kBAED;AAAA;AAAA;AAAA,cAxBC,MAAM;AAAA,YA0Bf;AAAA,UAER,CAAC,GACL;AAAA;AAAA,MACJ;AAAA;AAAA,EAGZ;AAER;","names":["jsx","jsx","intentClasses","jsx","jsx","jsx","jsx","jsxs"]}
|