@zezosoft/react-player 0.0.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/VideoPlayer/hooks/index.d.ts +0 -1
- package/dist/VideoPlayer/hooks/useSubtitleStyling.d.ts +3 -0
- package/dist/VideoPlayer/types/VideoPlayerTypes.d.ts +5 -1
- package/dist/VideoPlayer/utils/index.d.ts +0 -11
- package/dist/components/ui/Settings.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +166 -170
- package/package.json +1 -1
|
@@ -8,4 +8,3 @@ export { useVideoEvents } from "./useVideoEvents";
|
|
|
8
8
|
export { useAdManager } from "./useAdManager";
|
|
9
9
|
export { usePrimaryVideoLifecycle } from "./usePrimaryVideoLifecycle";
|
|
10
10
|
export { useVideoError } from "./useVideoError";
|
|
11
|
-
export { useNetworkSpeed } from "./useNetworkSpeed";
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
/** Returns true if value is a Tailwind background class (e.g. bg-red, bg-black, bg-transparent) ya CSS "transparent" */
|
|
2
|
+
export declare const isTailwindBackground: (value: unknown) => value is string;
|
|
1
3
|
export interface SubtitleStyleConfig {
|
|
2
4
|
fontSize?: string;
|
|
5
|
+
/** CSS value (rgba, hex, gradient) ya Tailwind class: bg-red, bg-black, bg-transparent, bg-amber-500/80, etc. */
|
|
3
6
|
backgroundColor?: string;
|
|
4
7
|
textColor?: string;
|
|
5
8
|
position?: "top" | "center" | "bottom";
|
|
@@ -19,17 +19,21 @@ export interface VideoProps {
|
|
|
19
19
|
isMute?: boolean;
|
|
20
20
|
startFrom?: number;
|
|
21
21
|
}
|
|
22
|
+
export interface VideoQualityConfig {
|
|
23
|
+
defaultQuality?: "auto" | string;
|
|
24
|
+
showInSettings?: boolean;
|
|
25
|
+
}
|
|
22
26
|
export interface StyleProps {
|
|
23
27
|
className?: string;
|
|
24
28
|
width?: string;
|
|
25
29
|
height?: string;
|
|
26
30
|
subtitleStyle?: SubtitleStyleConfig;
|
|
31
|
+
qualityConfig?: VideoQualityConfig;
|
|
27
32
|
}
|
|
28
33
|
export interface EventProps {
|
|
29
34
|
onEnded?: (e: React.SyntheticEvent<HTMLVideoElement>) => void;
|
|
30
35
|
onError?: (e?: React.SyntheticEvent<HTMLVideoElement, Event>) => void;
|
|
31
36
|
onClose?: () => void;
|
|
32
|
-
/** Called when player closes with watch progress data for history tracking */
|
|
33
37
|
onWatchHistoryUpdate?: (data: WatchHistoryData) => void;
|
|
34
38
|
}
|
|
35
39
|
export interface FeatureProps {
|
|
@@ -4,23 +4,12 @@
|
|
|
4
4
|
* @returns
|
|
5
5
|
*/
|
|
6
6
|
export declare const timeFormat: (seconds: number) => string;
|
|
7
|
-
/**
|
|
8
|
-
* @description
|
|
9
|
-
* @param seconds
|
|
10
|
-
*/
|
|
11
|
-
export declare const timeFormatForContent: (seconds: number) => string;
|
|
12
7
|
/**
|
|
13
8
|
* @description
|
|
14
9
|
* @param seconds
|
|
15
10
|
* @returns
|
|
16
11
|
*/
|
|
17
12
|
export declare const secondsToMilliseconds: (seconds: number) => number;
|
|
18
|
-
/**
|
|
19
|
-
* @description
|
|
20
|
-
* @param milliseconds
|
|
21
|
-
* @returns
|
|
22
|
-
*/
|
|
23
|
-
export declare const millisecondsToSeconds: (milliseconds: number) => number;
|
|
24
13
|
/**
|
|
25
14
|
* @description
|
|
26
15
|
* @param url
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import type { VideoQualityConfig } from "../../VideoPlayer/types/VideoPlayerTypes";
|
|
2
3
|
interface SettingsProps {
|
|
3
4
|
iconClassName: string;
|
|
5
|
+
qualityConfig?: VideoQualityConfig;
|
|
4
6
|
}
|
|
5
7
|
declare const Settings: React.FC<SettingsProps>;
|
|
6
8
|
export default Settings;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { default as VideoPlayer } from "./VideoPlayer/VideoPlayer";
|
|
|
3
3
|
export { useVideoStore } from "./store/VideoState";
|
|
4
4
|
export type { VideoPlayerProps, Episode, SubtitleTrack, IntroConfig, NextEpisodeConfig, WatchHistoryData, } from "./VideoPlayer/types/VideoPlayerTypes";
|
|
5
5
|
export type { SubtitleStyleConfig } from "./VideoPlayer/hooks/useSubtitleStyling";
|
|
6
|
+
export type { VideoQualityConfig } from "./VideoPlayer/types/VideoPlayerTypes";
|
|
6
7
|
export type { VideoState, VideoRefsState, VideoPlaybackState, VideoTimingState, VideoControlsState, VideoQualityState, SubtitlesState, EpisodesState, IntroState, } from "./store/types/StoreTypes";
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ function styleInject(css, ref) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
var css_248z$4 = "/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\",\n \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace;\n --color-red-400: oklch(70.4% 0.191 22.216);\n --color-red-500: oklch(63.7% 0.237 25.331);\n --color-red-600: oklch(57.7% 0.245 27.325);\n --color-red-700: oklch(50.5% 0.213 27.518);\n --color-green-500: oklch(72.3% 0.219 149.579);\n --color-sky-300: oklch(82.8% 0.111 230.318);\n --color-blue-500: oklch(62.3% 0.214 259.815);\n --color-purple-500: oklch(62.7% 0.265 303.9);\n --color-gray-200: oklch(92.8% 0.006 264.531);\n --color-gray-300: oklch(87.2% 0.01 258.338);\n --color-gray-400: oklch(70.7% 0.022 261.325);\n --color-gray-500: oklch(55.1% 0.027 264.364);\n --color-gray-600: oklch(44.6% 0.03 256.802);\n --color-gray-700: oklch(37.3% 0.034 259.733);\n --color-gray-900: oklch(21% 0.034 264.665);\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --container-md: 28rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 1rem;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-2xl: 1.5rem;\n --text-2xl--line-height: calc(2 / 1.5);\n --text-3xl: 1.875rem;\n --text-3xl--line-height: calc(2.25 / 1.875);\n --font-weight-normal: 400;\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-wider: 0.05em;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --ease-out: cubic-bezier(0, 0, 0.2, 1);\n --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);\n --animate-spin: spin 1s linear infinite;\n --blur-sm: 8px;\n --blur-md: 12px;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\"button\"], [type=\"reset\"], [type=\"submit\"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\"until-found\"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .pointer-events-none {\n pointer-events: none;\n }\n .absolute {\n position: absolute;\n }\n .relative {\n position: relative;\n }\n .static {\n position: static;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .-top-2 {\n top: calc(var(--spacing) * -2);\n }\n .top-0 {\n top: calc(var(--spacing) * 0);\n }\n .top-1\\/2 {\n top: calc(1/2 * 100%);\n }\n .top-full {\n top: 100%;\n }\n .right-0 {\n right: calc(var(--spacing) * 0);\n }\n .right-32 {\n right: calc(var(--spacing) * 32);\n }\n .right-full {\n right: 100%;\n }\n .bottom-36 {\n bottom: calc(var(--spacing) * 36);\n }\n .bottom-full {\n bottom: 100%;\n }\n .left-0 {\n left: calc(var(--spacing) * 0);\n }\n .left-1\\/2 {\n left: calc(1/2 * 100%);\n }\n .left-32 {\n left: calc(var(--spacing) * 32);\n }\n .left-full {\n left: 100%;\n }\n .z-40 {\n z-index: 40;\n }\n .z-50 {\n z-index: 50;\n }\n .z-\\[-1\\] {\n z-index: -1;\n }\n .container {\n width: 100%;\n @media (width >= 40rem) {\n max-width: 40rem;\n }\n @media (width >= 48rem) {\n max-width: 48rem;\n }\n @media (width >= 64rem) {\n max-width: 64rem;\n }\n @media (width >= 80rem) {\n max-width: 80rem;\n }\n @media (width >= 96rem) {\n max-width: 96rem;\n }\n }\n .mx-2 {\n margin-inline: calc(var(--spacing) * 2);\n }\n .mx-auto {\n margin-inline: auto;\n }\n .mt-1 {\n margin-top: calc(var(--spacing) * 1);\n }\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n .mt-4 {\n margin-top: calc(var(--spacing) * 4);\n }\n .mr-2 {\n margin-right: calc(var(--spacing) * 2);\n }\n .mb-1 {\n margin-bottom: calc(var(--spacing) * 1);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n .ml-1 {\n margin-left: calc(var(--spacing) * 1);\n }\n .ml-2 {\n margin-left: calc(var(--spacing) * 2);\n }\n .flex {\n display: flex;\n }\n .hidden {\n display: none;\n }\n .inline {\n display: inline;\n }\n .inline-block {\n display: inline-block;\n }\n .inline-flex {\n display: inline-flex;\n }\n .h-1 {\n height: calc(var(--spacing) * 1);\n }\n .h-3 {\n height: calc(var(--spacing) * 3);\n }\n .h-4 {\n height: calc(var(--spacing) * 4);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-6 {\n height: calc(var(--spacing) * 6);\n }\n .h-10 {\n height: calc(var(--spacing) * 10);\n }\n .h-12 {\n height: calc(var(--spacing) * 12);\n }\n .h-24 {\n height: calc(var(--spacing) * 24);\n }\n .h-full {\n height: 100%;\n }\n .max-h-80 {\n max-height: calc(var(--spacing) * 80);\n }\n .w-3 {\n width: calc(var(--spacing) * 3);\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n .w-6 {\n width: calc(var(--spacing) * 6);\n }\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n .w-24 {\n width: calc(var(--spacing) * 24);\n }\n .w-80 {\n width: calc(var(--spacing) * 80);\n }\n .w-\\[2px\\] {\n width: 2px;\n }\n .w-\\[10vw\\] {\n width: 10vw;\n }\n .w-\\[15vw\\] {\n width: 15vw;\n }\n .w-fit {\n width: fit-content;\n }\n .w-full {\n width: 100%;\n }\n .max-w-md {\n max-width: var(--container-md);\n }\n .flex-1 {\n flex: 1;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .rotate-45 {\n rotate: 45deg;\n }\n .rotate-180 {\n rotate: 180deg;\n }\n .transform {\n transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);\n }\n .animate-spin {\n animation: var(--animate-spin);\n }\n .cursor-not-allowed {\n cursor: not-allowed;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .items-start {\n align-items: flex-start;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .justify-end {\n justify-content: flex-end;\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-3 {\n gap: calc(var(--spacing) * 3);\n }\n .gap-4 {\n gap: calc(var(--spacing) * 4);\n }\n .gap-7 {\n gap: calc(var(--spacing) * 7);\n }\n .space-y-0 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-3 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .overflow-hidden {\n overflow: hidden;\n }\n .overflow-y-auto {\n overflow-y: auto;\n }\n .rounded {\n border-radius: 0.25rem;\n }\n .rounded-\\[5px\\] {\n border-radius: 5px;\n }\n .rounded-\\[7px\\] {\n border-radius: 7px;\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .border-gray-600 {\n border-color: var(--color-gray-600);\n }\n .border-gray-700\\/60 {\n border-color: color-mix(in srgb, oklch(37.3% 0.034 259.733) 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-gray-700) 60%, transparent);\n }\n }\n .border-white\\/10 {\n border-color: color-mix(in srgb, #fff 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n .border-white\\/30 {\n border-color: color-mix(in srgb, #fff 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 30%, transparent);\n }\n }\n .border-white\\/40 {\n border-color: color-mix(in srgb, #fff 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 40%, transparent);\n }\n }\n .bg-\\[\\#3a4049\\] {\n background-color: #3a4049;\n }\n .bg-\\[\\#454545\\] {\n background-color: #454545;\n }\n .bg-\\[rgba\\(0\\,0\\,0\\,0\\.5\\)\\] {\n background-color: rgba(0,0,0,0.5);\n }\n .bg-black {\n background-color: var(--color-black);\n }\n .bg-black\\/60 {\n background-color: color-mix(in srgb, #000 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 60%, transparent);\n }\n }\n .bg-black\\/90 {\n background-color: color-mix(in srgb, #000 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 90%, transparent);\n }\n }\n .bg-blue-500 {\n background-color: var(--color-blue-500);\n }\n .bg-gray-500 {\n background-color: var(--color-gray-500);\n }\n .bg-gray-900 {\n background-color: var(--color-gray-900);\n }\n .bg-green-500 {\n background-color: var(--color-green-500);\n }\n .bg-purple-500 {\n background-color: var(--color-purple-500);\n }\n .bg-red-600 {\n background-color: var(--color-red-600);\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .bg-white\\/5 {\n background-color: color-mix(in srgb, #fff 5%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 5%, transparent);\n }\n }\n .bg-white\\/10 {\n background-color: color-mix(in srgb, #fff 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n .bg-white\\/20 {\n background-color: color-mix(in srgb, #fff 20%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 20%, transparent);\n }\n }\n .bg-white\\/80 {\n background-color: color-mix(in srgb, #fff 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 80%, transparent);\n }\n }\n .bg-linear-to-b {\n --tw-gradient-position: to bottom;\n @supports (background-image: linear-gradient(in lab, red, red)) {\n --tw-gradient-position: to bottom in oklab;\n }\n background-image: linear-gradient(var(--tw-gradient-stops));\n }\n .from-black {\n --tw-gradient-from: var(--color-black);\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .from-black\\/80 {\n --tw-gradient-from: color-mix(in srgb, #000 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-gradient-from: color-mix(in oklab, var(--color-black) 80%, transparent);\n }\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .via-transparent {\n --tw-gradient-via: transparent;\n --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-via-stops);\n }\n .to-black\\/90 {\n --tw-gradient-to: color-mix(in srgb, #000 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-gradient-to: color-mix(in oklab, var(--color-black) 90%, transparent);\n }\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .bg-cover {\n background-size: cover;\n }\n .bg-center {\n background-position: center;\n }\n .object-contain {\n object-fit: contain;\n }\n .p-0 {\n padding: calc(var(--spacing) * 0);\n }\n .p-1 {\n padding: calc(var(--spacing) * 1);\n }\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n .p-6 {\n padding: calc(var(--spacing) * 6);\n }\n .p-10 {\n padding: calc(var(--spacing) * 10);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .px-5 {\n padding-inline: calc(var(--spacing) * 5);\n }\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n .px-10 {\n padding-inline: calc(var(--spacing) * 10);\n }\n .px-20 {\n padding-inline: calc(var(--spacing) * 20);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .py-3 {\n padding-block: calc(var(--spacing) * 3);\n }\n .py-4 {\n padding-block: calc(var(--spacing) * 4);\n }\n .pt-6 {\n padding-top: calc(var(--spacing) * 6);\n }\n .pb-3 {\n padding-bottom: calc(var(--spacing) * 3);\n }\n .pb-4 {\n padding-bottom: calc(var(--spacing) * 4);\n }\n .pb-6 {\n padding-bottom: calc(var(--spacing) * 6);\n }\n .pb-10 {\n padding-bottom: calc(var(--spacing) * 10);\n }\n .pb-16 {\n padding-bottom: calc(var(--spacing) * 16);\n }\n .text-center {\n text-align: center;\n }\n .text-left {\n text-align: left;\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-normal {\n --tw-font-weight: var(--font-weight-normal);\n font-weight: var(--font-weight-normal);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .tracking-wider {\n --tw-tracking: var(--tracking-wider);\n letter-spacing: var(--tracking-wider);\n }\n .whitespace-nowrap {\n white-space: nowrap;\n }\n .text-gray-200 {\n color: var(--color-gray-200);\n }\n .text-gray-300 {\n color: var(--color-gray-300);\n }\n .text-gray-400 {\n color: var(--color-gray-400);\n }\n .text-gray-500 {\n color: var(--color-gray-500);\n }\n .text-gray-900 {\n color: var(--color-gray-900);\n }\n .text-red-400 {\n color: var(--color-red-400);\n }\n .text-red-500 {\n color: var(--color-red-500);\n }\n .text-red-600 {\n color: var(--color-red-600);\n }\n .text-sky-300 {\n color: var(--color-sky-300);\n }\n .text-white {\n color: var(--color-white);\n }\n .normal-case {\n text-transform: none;\n }\n .opacity-0 {\n opacity: 0%;\n }\n .opacity-50 {\n opacity: 50%;\n }\n .opacity-100 {\n opacity: 100%;\n }\n .shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-md {\n --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .backdrop-blur-md {\n --tw-backdrop-blur: blur(var(--blur-md));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-blur-sm {\n --tw-backdrop-blur: blur(var(--blur-sm));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-200 {\n --tw-duration: 200ms;\n transition-duration: 200ms;\n }\n .duration-300 {\n --tw-duration: 300ms;\n transition-duration: 300ms;\n }\n .ease-in-out {\n --tw-ease: var(--ease-in-out);\n transition-timing-function: var(--ease-in-out);\n }\n .ease-out {\n --tw-ease: var(--ease-out);\n transition-timing-function: var(--ease-out);\n }\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .hover\\:scale-105 {\n &:hover {\n @media (hover: hover) {\n --tw-scale-x: 105%;\n --tw-scale-y: 105%;\n --tw-scale-z: 105%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n }\n .hover\\:border-white\\/50 {\n &:hover {\n @media (hover: hover) {\n border-color: color-mix(in srgb, #fff 50%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 50%, transparent);\n }\n }\n }\n }\n .hover\\:bg-gray-300 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-gray-300);\n }\n }\n }\n .hover\\:bg-red-700 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-red-700);\n }\n }\n }\n .hover\\:bg-white\\/5 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 5%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 5%, transparent);\n }\n }\n }\n }\n .hover\\:bg-white\\/10 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n }\n }\n .hover\\:bg-white\\/30 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 30%, transparent);\n }\n }\n }\n }\n .hover\\:bg-white\\/90 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 90%, transparent);\n }\n }\n }\n }\n .hover\\:text-gray-200 {\n &:hover {\n @media (hover: hover) {\n color: var(--color-gray-200);\n }\n }\n }\n .hover\\:text-white {\n &:hover {\n @media (hover: hover) {\n color: var(--color-white);\n }\n }\n }\n .hover\\:shadow-lg {\n &:hover {\n @media (hover: hover) {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n }\n .focus\\:ring-2 {\n &:focus {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .focus\\:ring-gray-400 {\n &:focus {\n --tw-ring-color: var(--color-gray-400);\n }\n }\n .focus\\:ring-offset-1 {\n &:focus {\n --tw-ring-offset-width: 1px;\n --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n }\n }\n .focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n .active\\:scale-95 {\n &:active {\n --tw-scale-x: 95%;\n --tw-scale-y: 95%;\n --tw-scale-z: 95%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n .disabled\\:cursor-not-allowed {\n &:disabled {\n cursor: not-allowed;\n }\n }\n .disabled\\:bg-white\\/50 {\n &:disabled {\n background-color: color-mix(in srgb, #fff 50%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 50%, transparent);\n }\n }\n }\n .disabled\\:opacity-50 {\n &:disabled {\n opacity: 50%;\n }\n }\n .lg\\:h-32 {\n @media (width >= 64rem) {\n height: calc(var(--spacing) * 32);\n }\n }\n .lg\\:w-32 {\n @media (width >= 64rem) {\n width: calc(var(--spacing) * 32);\n }\n }\n .lg\\:pb-12 {\n @media (width >= 64rem) {\n padding-bottom: calc(var(--spacing) * 12);\n }\n }\n .lg\\:text-2xl {\n @media (width >= 64rem) {\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n }\n }\n .lg\\:text-3xl {\n @media (width >= 64rem) {\n font-size: var(--text-3xl);\n line-height: var(--tw-leading, var(--text-3xl--line-height));\n }\n }\n .lg\\:text-base {\n @media (width >= 64rem) {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n }\n}\n.noCursor {\n cursor: none !important;\n}\n.icon-class {\n height: calc(var(--spacing) * 14);\n width: calc(var(--spacing) * 14);\n cursor: pointer;\n color: var(--color-gray-400);\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n &:hover {\n @media (hover: hover) {\n color: var(--color-gray-200);\n }\n }\n @media (width >= 64rem) {\n height: calc(var(--spacing) * 18);\n }\n @media (width >= 64rem) {\n width: calc(var(--spacing) * 18);\n }\n}\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-rotate-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-z {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-space-y-reverse {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-gradient-position {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-from {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-via {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-to {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-stops {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-via-stops {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-from-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 0%;\n}\n@property --tw-gradient-via-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 50%;\n}\n@property --tw-gradient-to-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-tracking {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: \"<length>\";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: \"*\";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-backdrop-blur {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-duration {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ease {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-scale-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-space-y-reverse: 0;\n --tw-border-style: solid;\n --tw-gradient-position: initial;\n --tw-gradient-from: #0000;\n --tw-gradient-via: #0000;\n --tw-gradient-to: #0000;\n --tw-gradient-stops: initial;\n --tw-gradient-via-stops: initial;\n --tw-gradient-from-position: 0%;\n --tw-gradient-via-position: 50%;\n --tw-gradient-to-position: 100%;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n --tw-duration: initial;\n --tw-ease: initial;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n }\n }\n}\n";
|
|
39
|
+
var css_248z$4 = "/*! tailwindcss v4.1.17 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\",\n \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace;\n --color-red-400: oklch(70.4% 0.191 22.216);\n --color-red-500: oklch(63.7% 0.237 25.331);\n --color-red-600: oklch(57.7% 0.245 27.325);\n --color-red-700: oklch(50.5% 0.213 27.518);\n --color-green-500: oklch(72.3% 0.219 149.579);\n --color-sky-300: oklch(82.8% 0.111 230.318);\n --color-blue-500: oklch(62.3% 0.214 259.815);\n --color-purple-500: oklch(62.7% 0.265 303.9);\n --color-gray-200: oklch(92.8% 0.006 264.531);\n --color-gray-300: oklch(87.2% 0.01 258.338);\n --color-gray-400: oklch(70.7% 0.022 261.325);\n --color-gray-500: oklch(55.1% 0.027 264.364);\n --color-gray-600: oklch(44.6% 0.03 256.802);\n --color-gray-700: oklch(37.3% 0.034 259.733);\n --color-gray-900: oklch(21% 0.034 264.665);\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --container-md: 28rem;\n --text-xs: 0.75rem;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 1rem;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-2xl: 1.5rem;\n --text-2xl--line-height: calc(2 / 1.5);\n --text-3xl: 1.875rem;\n --text-3xl--line-height: calc(2.25 / 1.875);\n --font-weight-normal: 400;\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --tracking-wider: 0.05em;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --ease-out: cubic-bezier(0, 0, 0.2, 1);\n --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);\n --animate-spin: spin 1s linear infinite;\n --blur-sm: 8px;\n --blur-md: 12px;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\"button\"], [type=\"reset\"], [type=\"submit\"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\"until-found\"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .pointer-events-none {\n pointer-events: none;\n }\n .absolute {\n position: absolute;\n }\n .relative {\n position: relative;\n }\n .static {\n position: static;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .-top-2 {\n top: calc(var(--spacing) * -2);\n }\n .top-0 {\n top: calc(var(--spacing) * 0);\n }\n .top-1\\/2 {\n top: calc(1/2 * 100%);\n }\n .top-full {\n top: 100%;\n }\n .right-0 {\n right: calc(var(--spacing) * 0);\n }\n .right-32 {\n right: calc(var(--spacing) * 32);\n }\n .right-full {\n right: 100%;\n }\n .bottom-36 {\n bottom: calc(var(--spacing) * 36);\n }\n .bottom-full {\n bottom: 100%;\n }\n .left-0 {\n left: calc(var(--spacing) * 0);\n }\n .left-1\\/2 {\n left: calc(1/2 * 100%);\n }\n .left-32 {\n left: calc(var(--spacing) * 32);\n }\n .left-full {\n left: 100%;\n }\n .z-40 {\n z-index: 40;\n }\n .z-50 {\n z-index: 50;\n }\n .z-\\[-1\\] {\n z-index: -1;\n }\n .container {\n width: 100%;\n @media (width >= 40rem) {\n max-width: 40rem;\n }\n @media (width >= 48rem) {\n max-width: 48rem;\n }\n @media (width >= 64rem) {\n max-width: 64rem;\n }\n @media (width >= 80rem) {\n max-width: 80rem;\n }\n @media (width >= 96rem) {\n max-width: 96rem;\n }\n }\n .mx-2 {\n margin-inline: calc(var(--spacing) * 2);\n }\n .mx-auto {\n margin-inline: auto;\n }\n .mt-1 {\n margin-top: calc(var(--spacing) * 1);\n }\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n .mt-4 {\n margin-top: calc(var(--spacing) * 4);\n }\n .mr-2 {\n margin-right: calc(var(--spacing) * 2);\n }\n .mb-1 {\n margin-bottom: calc(var(--spacing) * 1);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n .ml-1 {\n margin-left: calc(var(--spacing) * 1);\n }\n .ml-2 {\n margin-left: calc(var(--spacing) * 2);\n }\n .flex {\n display: flex;\n }\n .hidden {\n display: none;\n }\n .inline {\n display: inline;\n }\n .inline-block {\n display: inline-block;\n }\n .inline-flex {\n display: inline-flex;\n }\n .h-1 {\n height: calc(var(--spacing) * 1);\n }\n .h-3 {\n height: calc(var(--spacing) * 3);\n }\n .h-4 {\n height: calc(var(--spacing) * 4);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-6 {\n height: calc(var(--spacing) * 6);\n }\n .h-10 {\n height: calc(var(--spacing) * 10);\n }\n .h-12 {\n height: calc(var(--spacing) * 12);\n }\n .h-14 {\n height: calc(var(--spacing) * 14);\n }\n .h-full {\n height: 100%;\n }\n .max-h-80 {\n max-height: calc(var(--spacing) * 80);\n }\n .w-3 {\n width: calc(var(--spacing) * 3);\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n .w-6 {\n width: calc(var(--spacing) * 6);\n }\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n .w-14 {\n width: calc(var(--spacing) * 14);\n }\n .w-80 {\n width: calc(var(--spacing) * 80);\n }\n .w-\\[2px\\] {\n width: 2px;\n }\n .w-\\[10vw\\] {\n width: 10vw;\n }\n .w-\\[15vw\\] {\n width: 15vw;\n }\n .w-fit {\n width: fit-content;\n }\n .w-full {\n width: 100%;\n }\n .max-w-md {\n max-width: var(--container-md);\n }\n .flex-1 {\n flex: 1;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .rotate-45 {\n rotate: 45deg;\n }\n .rotate-180 {\n rotate: 180deg;\n }\n .transform {\n transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);\n }\n .animate-spin {\n animation: var(--animate-spin);\n }\n .cursor-default {\n cursor: default;\n }\n .cursor-not-allowed {\n cursor: not-allowed;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .items-start {\n align-items: flex-start;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .justify-end {\n justify-content: flex-end;\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-3 {\n gap: calc(var(--spacing) * 3);\n }\n .gap-4 {\n gap: calc(var(--spacing) * 4);\n }\n .gap-7 {\n gap: calc(var(--spacing) * 7);\n }\n .space-y-0 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .space-y-3 {\n :where(& > :not(:last-child)) {\n --tw-space-y-reverse: 0;\n margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));\n margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));\n }\n }\n .overflow-hidden {\n overflow: hidden;\n }\n .overflow-y-auto {\n overflow-y: auto;\n }\n .rounded {\n border-radius: 0.25rem;\n }\n .rounded-\\[5px\\] {\n border-radius: 5px;\n }\n .rounded-\\[7px\\] {\n border-radius: 7px;\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .border-gray-600 {\n border-color: var(--color-gray-600);\n }\n .border-gray-700\\/60 {\n border-color: color-mix(in srgb, oklch(37.3% 0.034 259.733) 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-gray-700) 60%, transparent);\n }\n }\n .border-white\\/10 {\n border-color: color-mix(in srgb, #fff 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n .border-white\\/30 {\n border-color: color-mix(in srgb, #fff 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 30%, transparent);\n }\n }\n .border-white\\/40 {\n border-color: color-mix(in srgb, #fff 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 40%, transparent);\n }\n }\n .bg-\\[\\#3a4049\\] {\n background-color: #3a4049;\n }\n .bg-\\[\\#454545\\] {\n background-color: #454545;\n }\n .bg-\\[rgba\\(0\\,0\\,0\\,0\\.5\\)\\] {\n background-color: rgba(0,0,0,0.5);\n }\n .bg-black {\n background-color: var(--color-black);\n }\n .bg-black\\/60 {\n background-color: color-mix(in srgb, #000 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 60%, transparent);\n }\n }\n .bg-black\\/90 {\n background-color: color-mix(in srgb, #000 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 90%, transparent);\n }\n }\n .bg-blue-500 {\n background-color: var(--color-blue-500);\n }\n .bg-gray-500 {\n background-color: var(--color-gray-500);\n }\n .bg-gray-900 {\n background-color: var(--color-gray-900);\n }\n .bg-green-500 {\n background-color: var(--color-green-500);\n }\n .bg-purple-500 {\n background-color: var(--color-purple-500);\n }\n .bg-red-600 {\n background-color: var(--color-red-600);\n }\n .bg-transparent {\n background-color: transparent;\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .bg-white\\/10 {\n background-color: color-mix(in srgb, #fff 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n .bg-white\\/20 {\n background-color: color-mix(in srgb, #fff 20%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 20%, transparent);\n }\n }\n .bg-white\\/80 {\n background-color: color-mix(in srgb, #fff 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 80%, transparent);\n }\n }\n .bg-linear-to-b {\n --tw-gradient-position: to bottom;\n @supports (background-image: linear-gradient(in lab, red, red)) {\n --tw-gradient-position: to bottom in oklab;\n }\n background-image: linear-gradient(var(--tw-gradient-stops));\n }\n .from-black {\n --tw-gradient-from: var(--color-black);\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .from-black\\/80 {\n --tw-gradient-from: color-mix(in srgb, #000 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-gradient-from: color-mix(in oklab, var(--color-black) 80%, transparent);\n }\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .via-transparent {\n --tw-gradient-via: transparent;\n --tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-via-stops);\n }\n .to-black\\/90 {\n --tw-gradient-to: color-mix(in srgb, #000 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-gradient-to: color-mix(in oklab, var(--color-black) 90%, transparent);\n }\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .bg-cover {\n background-size: cover;\n }\n .bg-center {\n background-position: center;\n }\n .object-contain {\n object-fit: contain;\n }\n .p-0 {\n padding: calc(var(--spacing) * 0);\n }\n .p-1 {\n padding: calc(var(--spacing) * 1);\n }\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n .p-6 {\n padding: calc(var(--spacing) * 6);\n }\n .p-10 {\n padding: calc(var(--spacing) * 10);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .px-5 {\n padding-inline: calc(var(--spacing) * 5);\n }\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n .px-10 {\n padding-inline: calc(var(--spacing) * 10);\n }\n .px-20 {\n padding-inline: calc(var(--spacing) * 20);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .py-3 {\n padding-block: calc(var(--spacing) * 3);\n }\n .py-4 {\n padding-block: calc(var(--spacing) * 4);\n }\n .pt-6 {\n padding-top: calc(var(--spacing) * 6);\n }\n .pb-3 {\n padding-bottom: calc(var(--spacing) * 3);\n }\n .pb-4 {\n padding-bottom: calc(var(--spacing) * 4);\n }\n .pb-6 {\n padding-bottom: calc(var(--spacing) * 6);\n }\n .pb-10 {\n padding-bottom: calc(var(--spacing) * 10);\n }\n .pb-16 {\n padding-bottom: calc(var(--spacing) * 16);\n }\n .text-center {\n text-align: center;\n }\n .text-left {\n text-align: left;\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-normal {\n --tw-font-weight: var(--font-weight-normal);\n font-weight: var(--font-weight-normal);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .tracking-wider {\n --tw-tracking: var(--tracking-wider);\n letter-spacing: var(--tracking-wider);\n }\n .whitespace-nowrap {\n white-space: nowrap;\n }\n .text-gray-200 {\n color: var(--color-gray-200);\n }\n .text-gray-300 {\n color: var(--color-gray-300);\n }\n .text-gray-400 {\n color: var(--color-gray-400);\n }\n .text-gray-500 {\n color: var(--color-gray-500);\n }\n .text-gray-900 {\n color: var(--color-gray-900);\n }\n .text-red-400 {\n color: var(--color-red-400);\n }\n .text-red-500 {\n color: var(--color-red-500);\n }\n .text-red-600 {\n color: var(--color-red-600);\n }\n .text-sky-300 {\n color: var(--color-sky-300);\n }\n .text-white {\n color: var(--color-white);\n }\n .normal-case {\n text-transform: none;\n }\n .opacity-0 {\n opacity: 0%;\n }\n .opacity-50 {\n opacity: 50%;\n }\n .opacity-100 {\n opacity: 100%;\n }\n .shadow-2xl {\n --tw-shadow: 0 25px 50px -12px var(--tw-shadow-color, rgb(0 0 0 / 0.25));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-md {\n --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .backdrop-blur-md {\n --tw-backdrop-blur: blur(var(--blur-md));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-blur-sm {\n --tw-backdrop-blur: blur(var(--blur-sm));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-200 {\n --tw-duration: 200ms;\n transition-duration: 200ms;\n }\n .duration-300 {\n --tw-duration: 300ms;\n transition-duration: 300ms;\n }\n .ease-in-out {\n --tw-ease: var(--ease-in-out);\n transition-timing-function: var(--ease-in-out);\n }\n .ease-out {\n --tw-ease: var(--ease-out);\n transition-timing-function: var(--ease-out);\n }\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .hover\\:scale-105 {\n &:hover {\n @media (hover: hover) {\n --tw-scale-x: 105%;\n --tw-scale-y: 105%;\n --tw-scale-z: 105%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n }\n .hover\\:border-white\\/50 {\n &:hover {\n @media (hover: hover) {\n border-color: color-mix(in srgb, #fff 50%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-white) 50%, transparent);\n }\n }\n }\n }\n .hover\\:bg-gray-300 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-gray-300);\n }\n }\n }\n .hover\\:bg-red-700 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-red-700);\n }\n }\n }\n .hover\\:bg-white\\/5 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 5%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 5%, transparent);\n }\n }\n }\n }\n .hover\\:bg-white\\/10 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 10%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n }\n }\n .hover\\:bg-white\\/30 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 30%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 30%, transparent);\n }\n }\n }\n }\n .hover\\:bg-white\\/90 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 90%, transparent);\n }\n }\n }\n }\n .hover\\:text-gray-200 {\n &:hover {\n @media (hover: hover) {\n color: var(--color-gray-200);\n }\n }\n }\n .hover\\:text-white {\n &:hover {\n @media (hover: hover) {\n color: var(--color-white);\n }\n }\n }\n .hover\\:shadow-lg {\n &:hover {\n @media (hover: hover) {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n }\n .focus\\:ring-2 {\n &:focus {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .focus\\:ring-gray-400 {\n &:focus {\n --tw-ring-color: var(--color-gray-400);\n }\n }\n .focus\\:ring-offset-1 {\n &:focus {\n --tw-ring-offset-width: 1px;\n --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n }\n }\n .focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n .active\\:scale-95 {\n &:active {\n --tw-scale-x: 95%;\n --tw-scale-y: 95%;\n --tw-scale-z: 95%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n }\n .disabled\\:cursor-not-allowed {\n &:disabled {\n cursor: not-allowed;\n }\n }\n .disabled\\:bg-white\\/50 {\n &:disabled {\n background-color: color-mix(in srgb, #fff 50%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 50%, transparent);\n }\n }\n }\n .disabled\\:opacity-50 {\n &:disabled {\n opacity: 50%;\n }\n }\n .lg\\:h-18 {\n @media (width >= 64rem) {\n height: calc(var(--spacing) * 18);\n }\n }\n .lg\\:w-18 {\n @media (width >= 64rem) {\n width: calc(var(--spacing) * 18);\n }\n }\n .lg\\:pb-12 {\n @media (width >= 64rem) {\n padding-bottom: calc(var(--spacing) * 12);\n }\n }\n .lg\\:text-2xl {\n @media (width >= 64rem) {\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n }\n }\n .lg\\:text-3xl {\n @media (width >= 64rem) {\n font-size: var(--text-3xl);\n line-height: var(--tw-leading, var(--text-3xl--line-height));\n }\n }\n .lg\\:text-base {\n @media (width >= 64rem) {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n }\n}\n.noCursor {\n cursor: none !important;\n}\n.icon-class {\n height: calc(var(--spacing) * 14);\n width: calc(var(--spacing) * 14);\n cursor: pointer;\n color: var(--color-gray-400);\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n &:hover {\n @media (hover: hover) {\n color: var(--color-gray-200);\n }\n }\n @media (width >= 64rem) {\n height: calc(var(--spacing) * 18);\n }\n @media (width >= 64rem) {\n width: calc(var(--spacing) * 18);\n }\n}\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-rotate-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-z {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-space-y-reverse {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-gradient-position {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-from {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-via {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-to {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-stops {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-via-stops {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-from-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 0%;\n}\n@property --tw-gradient-via-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 50%;\n}\n@property --tw-gradient-to-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-tracking {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: \"<length>\";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: \"*\";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-backdrop-blur {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-duration {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ease {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-scale-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 1;\n}\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-space-y-reverse: 0;\n --tw-border-style: solid;\n --tw-gradient-position: initial;\n --tw-gradient-from: #0000;\n --tw-gradient-via: #0000;\n --tw-gradient-to: #0000;\n --tw-gradient-stops: initial;\n --tw-gradient-via-stops: initial;\n --tw-gradient-from-position: 0%;\n --tw-gradient-via-position: 50%;\n --tw-gradient-to-position: 100%;\n --tw-font-weight: initial;\n --tw-tracking: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n --tw-duration: initial;\n --tw-ease: initial;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n }\n }\n}\n";
|
|
40
40
|
styleInject(css_248z$4,{"insertAt":"top"});
|
|
41
41
|
|
|
42
42
|
const createVideoRefsSlice = (set) => ({
|
|
@@ -642,21 +642,17 @@ const VideoSeekSlider = ({ max = 1000, currentTime = 0, bufferTime = 0, hideThum
|
|
|
642
642
|
React__default.createElement(Thumb, { max: max, currentTime: currentTime, isThumbActive: isThumbActive, trackColor: trackColor })));
|
|
643
643
|
};
|
|
644
644
|
|
|
645
|
-
// Memoized time formatter to prevent unnecessary recalculations
|
|
646
645
|
const formatTimeMemo = (() => {
|
|
647
646
|
const cache = new Map();
|
|
648
647
|
return (seconds) => {
|
|
649
|
-
if (cache.has(seconds))
|
|
648
|
+
if (cache.has(seconds))
|
|
650
649
|
return cache.get(seconds);
|
|
651
|
-
}
|
|
652
650
|
const formatted = timeFormat(seconds);
|
|
653
651
|
cache.set(seconds, formatted);
|
|
654
|
-
// Limit cache size to prevent memory leaks
|
|
655
652
|
if (cache.size > 100) {
|
|
656
653
|
const firstKey = cache.keys().next().value;
|
|
657
|
-
if (firstKey !== undefined)
|
|
654
|
+
if (firstKey !== undefined)
|
|
658
655
|
cache.delete(firstKey);
|
|
659
|
-
}
|
|
660
656
|
}
|
|
661
657
|
return formatted;
|
|
662
658
|
};
|
|
@@ -673,28 +669,23 @@ const BottomControls = memo(({ config }) => {
|
|
|
673
669
|
const currentTimeValue = currentTime || 0;
|
|
674
670
|
const bufferedValue = bufferedProgress || 0;
|
|
675
671
|
const handleSeek = useCallback((currentTimeInMs) => {
|
|
676
|
-
if (!videoRef)
|
|
672
|
+
if (!videoRef)
|
|
677
673
|
return;
|
|
678
|
-
}
|
|
679
674
|
videoRef.currentTime = currentTimeInMs / 1000;
|
|
680
675
|
}, [videoRef]);
|
|
681
676
|
const bufferTime = useMemo(() => {
|
|
682
|
-
if (!duration)
|
|
677
|
+
if (!duration)
|
|
683
678
|
return 0;
|
|
684
|
-
}
|
|
685
679
|
return secondsToMilliseconds(duration * (bufferedValue / 100));
|
|
686
680
|
}, [bufferedValue, duration]);
|
|
687
|
-
// Round to nearest second for time display to reduce re-renders
|
|
688
681
|
const roundedCurrentTime = useMemo(() => Math.floor(currentTimeValue), [currentTimeValue]);
|
|
689
682
|
const roundedDuration = useMemo(() => Math.floor(duration), [duration]);
|
|
690
683
|
const durationFormatted = useMemo(() => formatTimeMemo(roundedDuration), [roundedDuration]);
|
|
691
684
|
const currentTimeFormatted = useMemo(() => formatTimeMemo(roundedCurrentTime), [roundedCurrentTime]);
|
|
692
|
-
// Memoize seek slider props to prevent unnecessary re-renders
|
|
693
685
|
const seekSliderMax = useMemo(() => secondsToMilliseconds(duration), [duration]);
|
|
694
686
|
const seekSliderCurrentTime = useMemo(() => secondsToMilliseconds(currentTimeValue), [currentTimeValue]);
|
|
695
|
-
if (isAdPlaying)
|
|
687
|
+
if (isAdPlaying)
|
|
696
688
|
return null;
|
|
697
|
-
}
|
|
698
689
|
return (React__default.createElement("div", { className: "px-10" },
|
|
699
690
|
React__default.createElement(VideoSeekSlider, { max: seekSliderMax, currentTime: seekSliderCurrentTime, bufferTime: bufferTime, onChange: handleSeek, secondsPrefix: "00:00:", minutesPrefix: "00:", getPreviewScreenUrl: config?.seekBarConfig?.getPreviewScreenUrl, timeCodes: config?.seekBarConfig?.timeCodes, trackColor: config?.seekBarConfig?.trackColor }),
|
|
700
691
|
React__default.createElement("div", { className: `pt-6 ${isFullscreen ? "pb-10" : "pb-16"} lg:pb-12 flex items-center gap-4 text-white` },
|
|
@@ -724,7 +715,6 @@ const Popover = ({ button, children, closeOnButtonClick = false, className = "",
|
|
|
724
715
|
const [isOpen, setIsOpen] = useState(false);
|
|
725
716
|
const popoverRef = useRef(null);
|
|
726
717
|
const buttonRef = useRef(null);
|
|
727
|
-
// Close on outside click or Escape key
|
|
728
718
|
useEffect(() => {
|
|
729
719
|
const handleClickOutside = (event) => {
|
|
730
720
|
if (popoverRef.current &&
|
|
@@ -749,7 +739,6 @@ const Popover = ({ button, children, closeOnButtonClick = false, className = "",
|
|
|
749
739
|
const togglePopover = () => {
|
|
750
740
|
setIsOpen((prev) => (closeOnButtonClick ? !prev : true));
|
|
751
741
|
};
|
|
752
|
-
// Get alignment classes
|
|
753
742
|
const getAlignmentClasses = () => {
|
|
754
743
|
switch (align) {
|
|
755
744
|
case "center":
|
|
@@ -761,7 +750,6 @@ const Popover = ({ button, children, closeOnButtonClick = false, className = "",
|
|
|
761
750
|
return "left-0";
|
|
762
751
|
}
|
|
763
752
|
};
|
|
764
|
-
// Arrow is always centered regardless of popover alignment
|
|
765
753
|
const getArrowPositionClasses = () => {
|
|
766
754
|
return "left-1/2 -translate-x-1/2";
|
|
767
755
|
};
|
|
@@ -785,27 +773,24 @@ const Tooltip = ({ children, title, position = "top", className, }) => {
|
|
|
785
773
|
visible && (React__default.createElement("div", { className: `absolute z-50 px-3 py-1 text-sm text-white bg-gray-900 rounded-md shadow-md transition-opacity duration-200 ease-in-out whitespace-nowrap ${positionStyles[position]}` }, title))));
|
|
786
774
|
};
|
|
787
775
|
|
|
788
|
-
const
|
|
776
|
+
const speedOptions = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
777
|
+
const Settings = ({ iconClassName, qualityConfig, }) => {
|
|
778
|
+
const showQualityInSettings = qualityConfig?.showInSettings !== false;
|
|
789
779
|
const { qualityLevels, activeQuality, currentQuality, subtitles, activeSubtitle, setActiveSubtitle, videoRef, streamType, } = useVideoStore();
|
|
790
|
-
// Load playback speed from localStorage or default to 1
|
|
791
780
|
const getStoredPlaybackSpeed = () => {
|
|
792
781
|
try {
|
|
793
782
|
const stored = localStorage.getItem("react-player-playback-speed");
|
|
794
783
|
if (stored) {
|
|
795
784
|
const speed = parseFloat(stored);
|
|
796
|
-
if (speedOptions.includes(speed))
|
|
785
|
+
if (speedOptions.includes(speed))
|
|
797
786
|
return speed;
|
|
798
|
-
}
|
|
799
787
|
}
|
|
800
788
|
}
|
|
801
|
-
catch
|
|
802
|
-
// Ignore localStorage errors
|
|
803
|
-
}
|
|
789
|
+
catch { }
|
|
804
790
|
return 1;
|
|
805
791
|
};
|
|
806
792
|
const [speed, setSpeed] = React.useState(getStoredPlaybackSpeed());
|
|
807
793
|
const [activeMenu, setActiveMenu] = React.useState("main");
|
|
808
|
-
// Initialize playback speed from localStorage on mount
|
|
809
794
|
React.useEffect(() => {
|
|
810
795
|
if (videoRef) {
|
|
811
796
|
const storedSpeed = getStoredPlaybackSpeed();
|
|
@@ -815,16 +800,12 @@ const Settings = ({ iconClassName }) => {
|
|
|
815
800
|
}, [videoRef]);
|
|
816
801
|
const handleSpeedChange = (newSpeed) => {
|
|
817
802
|
setSpeed(newSpeed);
|
|
818
|
-
if (videoRef)
|
|
803
|
+
if (videoRef)
|
|
819
804
|
videoRef.playbackRate = newSpeed;
|
|
820
|
-
}
|
|
821
|
-
// Persist to localStorage
|
|
822
805
|
try {
|
|
823
806
|
localStorage.setItem("react-player-playback-speed", newSpeed.toString());
|
|
824
807
|
}
|
|
825
|
-
catch
|
|
826
|
-
// Ignore localStorage errors
|
|
827
|
-
}
|
|
808
|
+
catch { }
|
|
828
809
|
};
|
|
829
810
|
const isAdaptiveStream = streamType === "hls" || streamType === "dash";
|
|
830
811
|
const qualityOptions = React.useMemo(() => {
|
|
@@ -849,27 +830,23 @@ const Settings = ({ iconClassName }) => {
|
|
|
849
830
|
return b.originalIndex - a.originalIndex;
|
|
850
831
|
});
|
|
851
832
|
}, [qualityLevels, isAdaptiveStream, streamType]);
|
|
852
|
-
const speedOptions = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
853
833
|
const handleBack = () => setActiveMenu("main");
|
|
854
834
|
const formatBitrate = (bitrate) => {
|
|
855
835
|
if (!bitrate || bitrate <= 0)
|
|
856
836
|
return "";
|
|
857
|
-
if (bitrate >= 1000000)
|
|
837
|
+
if (bitrate >= 1000000)
|
|
858
838
|
return `${(bitrate / 1000000).toFixed(1)} Mbps`;
|
|
859
|
-
}
|
|
860
839
|
return `${Math.round(bitrate / 1000)} Kbps`;
|
|
861
840
|
};
|
|
862
|
-
// Get quality label: show explicit resolution to avoid duplicates
|
|
863
841
|
const getQualityName = (height, bitrate) => {
|
|
864
842
|
if (height && height > 0)
|
|
865
843
|
return `${height}p`;
|
|
866
844
|
const bitrateLabel = formatBitrate(bitrate);
|
|
867
845
|
return bitrateLabel || "Quality";
|
|
868
846
|
};
|
|
869
|
-
// Get quality label for display
|
|
870
847
|
const getQualityLabel = () => {
|
|
871
|
-
if (!isAdaptiveStream)
|
|
872
|
-
return "
|
|
848
|
+
if (!isAdaptiveStream || qualityOptions.length === 0)
|
|
849
|
+
return "Off";
|
|
873
850
|
if (currentQuality === "auto")
|
|
874
851
|
return "Auto";
|
|
875
852
|
const option = qualityOptions.find((q) => q.value === currentQuality);
|
|
@@ -878,15 +855,12 @@ const Settings = ({ iconClassName }) => {
|
|
|
878
855
|
const label = getQualityName(option.height, option.bitrate);
|
|
879
856
|
return label === "Quality" ? "Custom" : label;
|
|
880
857
|
};
|
|
881
|
-
|
|
858
|
+
const hasQualityOptions = isAdaptiveStream && qualityOptions.length > 0;
|
|
882
859
|
const getDataUsage = (height, bitrate) => {
|
|
883
|
-
// bitrate in bits/sec -> GB/hour
|
|
884
860
|
if (bitrate && bitrate > 0) {
|
|
885
861
|
const gbPerHour = (bitrate * 3600) / 8 / 1e9;
|
|
886
|
-
|
|
887
|
-
return `Uses about ${rounded} GB per hour`;
|
|
862
|
+
return `Uses about ${gbPerHour.toFixed(2)} GB per hour`;
|
|
888
863
|
}
|
|
889
|
-
// Fallback by resolution when bitrate missing
|
|
890
864
|
if (height >= 2160)
|
|
891
865
|
return "Uses about 7.00 GB per hour";
|
|
892
866
|
if (height >= 1440)
|
|
@@ -908,7 +882,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
908
882
|
React.createElement("h3", { className: "text-white font-bold text-xl mb-4" }, "Settings"),
|
|
909
883
|
React.createElement("p", { className: "text-gray-300 text-sm mb-4" }, "Customize playback"),
|
|
910
884
|
React.createElement("div", { className: "space-y-0 border-t border-gray-600" },
|
|
911
|
-
React.createElement("button", { onClick: () => setActiveMenu("quality"), className: "w-full flex items-center justify-between py-4 border-b border-gray-600 rounded-[5px] transition-colors" },
|
|
885
|
+
showQualityInSettings && (React.createElement("button", { onClick: () => setActiveMenu("quality"), className: "w-full flex items-center justify-between py-4 border-b border-gray-600 rounded-[5px] transition-colors" },
|
|
912
886
|
React.createElement("div", { className: "flex items-center gap-3" },
|
|
913
887
|
React.createElement("div", { className: "p-2 bg-blue-500 rounded-md" },
|
|
914
888
|
React.createElement("svg", { className: "w-5 h-5 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
|
|
@@ -916,7 +890,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
916
890
|
React.createElement("div", { className: "text-left" },
|
|
917
891
|
React.createElement("div", { className: "text-white font-semibold" }, "Quality"),
|
|
918
892
|
React.createElement("div", { className: "text-gray-400 text-sm" }, getQualityLabel()))),
|
|
919
|
-
React.createElement(ChevronRight, { className: "w-5 h-5 text-gray-400" })),
|
|
893
|
+
React.createElement(ChevronRight, { className: "w-5 h-5 text-gray-400" }))),
|
|
920
894
|
React.createElement("button", { onClick: () => setActiveMenu("subtitles"), className: "w-full flex items-center justify-between py-4 border-b border-gray-600 rounded-[5px] transition-colors" },
|
|
921
895
|
React.createElement("div", { className: "flex items-center gap-3" },
|
|
922
896
|
React.createElement("div", { className: "p-2 bg-purple-500 rounded-md" },
|
|
@@ -942,30 +916,26 @@ const Settings = ({ iconClassName }) => {
|
|
|
942
916
|
React.createElement("button", { onClick: handleBack, className: "p-1 rounded-md transition-colors" },
|
|
943
917
|
React.createElement(ChevronRight, { className: "w-6 h-6 text-white rotate-180" })),
|
|
944
918
|
React.createElement("h3", { className: "text-white font-bold text-xl" }, "Video Quality")),
|
|
945
|
-
React.createElement("div", { className: "space-y-3" },
|
|
946
|
-
React.createElement("button", { onClick: () => {
|
|
947
|
-
if (isAdaptiveStream) {
|
|
948
|
-
QualityManager.setQuality(streamType, "auto");
|
|
949
|
-
}
|
|
950
|
-
}, disabled: !isAdaptiveStream, className: `w-full text-left px-4 py-3 rounded-md transition-all ${activeQuality === "auto"
|
|
919
|
+
React.createElement("div", { className: "space-y-3" }, hasQualityOptions ? (React.createElement(React.Fragment, null,
|
|
920
|
+
React.createElement("button", { onClick: () => QualityManager.setQuality(streamType, "auto"), className: `w-full text-left px-4 py-3 rounded-md transition-all ${activeQuality === "auto"
|
|
951
921
|
? "bg-white/10"
|
|
952
|
-
:
|
|
953
|
-
? "hover:bg-white/5"
|
|
954
|
-
: "opacity-50 cursor-not-allowed"}` },
|
|
922
|
+
: "hover:bg-white/5"}` },
|
|
955
923
|
React.createElement("div", { className: "flex items-start justify-between" },
|
|
956
924
|
React.createElement("div", null,
|
|
957
925
|
React.createElement("div", { className: "text-white font-semibold text-lg mb-1" }, "Auto"),
|
|
958
926
|
React.createElement("div", { className: "text-gray-400 text-sm" }, "Adjust to your connection")),
|
|
959
927
|
activeQuality === "auto" && (React.createElement(Check, { className: "w-6 h-6 text-white mt-1" })))),
|
|
960
|
-
|
|
928
|
+
qualityOptions.map((level) => (React.createElement("button", { key: level.value, onClick: () => QualityManager.setQuality(streamType, level.value), className: `w-full text-left px-4 py-3 rounded-md transition-all ${activeQuality === level.value
|
|
961
929
|
? "bg-white/10"
|
|
962
930
|
: "hover:bg-white/5"}` },
|
|
963
931
|
React.createElement("div", { className: "flex items-start justify-between" },
|
|
964
932
|
React.createElement("div", null,
|
|
965
933
|
React.createElement("div", { className: "text-white font-semibold text-lg mb-1" }, getQualityName(level.height, level.bitrate)),
|
|
966
934
|
React.createElement("div", { className: "text-gray-400 text-sm" }, getDataUsage(level.height, level.bitrate))),
|
|
967
|
-
|
|
968
|
-
|
|
935
|
+
activeQuality === level.value && (React.createElement(Check, { className: "w-6 h-6 text-white mt-1" })))))))) : (React.createElement("button", { className: "w-full text-left px-4 py-3 rounded-md bg-white/10 cursor-default" },
|
|
936
|
+
React.createElement("div", { className: "flex items-start justify-between" },
|
|
937
|
+
React.createElement("span", { className: "text-white font-semibold text-lg" }, "Off"),
|
|
938
|
+
React.createElement(Check, { className: "w-6 h-6 text-white mt-1" }))))))),
|
|
969
939
|
activeMenu === "subtitles" && (React.createElement("div", { className: "p-4" },
|
|
970
940
|
React.createElement("div", { className: "flex items-center gap-3 mb-4" },
|
|
971
941
|
React.createElement("button", { onClick: handleBack, className: "p-1 hover:bg-white/10 rounded-md transition-colors" },
|
|
@@ -974,7 +944,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
974
944
|
React.createElement("div", { className: "space-y-3" },
|
|
975
945
|
React.createElement("button", { onClick: () => setActiveSubtitle(null), className: `w-full text-left px-4 py-3 rounded-[5px] transition-all flex items-center justify-between ${!activeSubtitle ? "bg-[#454545]" : ""}` },
|
|
976
946
|
React.createElement("span", { className: "text-white font-semibold text-lg" }, "Off"),
|
|
977
|
-
!activeSubtitle && React.createElement(Check, { className: "w-6 h-6 text-white" })),
|
|
947
|
+
!activeSubtitle && (React.createElement(Check, { className: "w-6 h-6 text-white" }))),
|
|
978
948
|
subtitles?.map((subtitle, index) => (React.createElement("button", { key: index, onClick: () => setActiveSubtitle(subtitle), className: `w-full text-left px-4 py-3 rounded-md transition-all flex items-center justify-between ${activeSubtitle?.label === subtitle.label
|
|
979
949
|
? "bg-white/10"
|
|
980
950
|
: "hover:bg-white/5"}` },
|
|
@@ -987,7 +957,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
987
957
|
React.createElement("h3", { className: "text-white font-bold text-xl" }, "Playback Speed")),
|
|
988
958
|
React.createElement("div", { className: "space-y-3 max-h-80 overflow-y-auto" }, speedOptions.map((s) => (React.createElement("button", { key: s, onClick: () => handleSpeedChange(s), className: `w-full text-left px-4 py-3 rounded-[5px] transition-all flex items-center justify-between ${speed === s ? "bg-[#454545]" : ""}` },
|
|
989
959
|
React.createElement("span", { className: "text-white font-semibold text-lg" }, s === 1 ? "Normal" : `${s}x`),
|
|
990
|
-
speed === s && React.createElement(Check, { className: "w-6 h-6 text-white" })))))))))));
|
|
960
|
+
speed === s && (React.createElement(Check, { className: "w-6 h-6 text-white" }))))))))))));
|
|
991
961
|
};
|
|
992
962
|
|
|
993
963
|
const ControlsHeader = ({ config }) => {
|
|
@@ -1083,7 +1053,7 @@ const ControlsHeader = ({ config }) => {
|
|
|
1083
1053
|
setIsPipActive(false);
|
|
1084
1054
|
}
|
|
1085
1055
|
}
|
|
1086
|
-
catch
|
|
1056
|
+
catch { }
|
|
1087
1057
|
};
|
|
1088
1058
|
React.useEffect(() => {
|
|
1089
1059
|
const handlePipChange = () => setIsPipActive(!!document.pictureInPictureElement);
|
|
@@ -1096,9 +1066,7 @@ const ControlsHeader = ({ config }) => {
|
|
|
1096
1066
|
}, []);
|
|
1097
1067
|
const handleClose = () => {
|
|
1098
1068
|
resetStore();
|
|
1099
|
-
|
|
1100
|
-
config.onClose();
|
|
1101
|
-
}
|
|
1069
|
+
config?.onClose?.();
|
|
1102
1070
|
};
|
|
1103
1071
|
const renderAdHeader = () => (React.createElement("div", { className: "flex items-center gap-4" },
|
|
1104
1072
|
React.createElement("span", { className: "inline-flex items-center gap-1 rounded-full px-4 py-2 font-medium text-xs tracking-wider text-red-600 border border-gray-700/60" },
|
|
@@ -1113,7 +1081,7 @@ const ControlsHeader = ({ config }) => {
|
|
|
1113
1081
|
return (React.createElement("div", { className: "flex items-center justify-between p-10 bg-linear-to-b from-black" },
|
|
1114
1082
|
isAdPlaying ? renderAdHeader() : renderVideoHeader(),
|
|
1115
1083
|
React.createElement("div", { className: "flex items-center gap-7 text-white" },
|
|
1116
|
-
!isAdPlaying && React.createElement(Settings, { iconClassName: iconClassName }),
|
|
1084
|
+
!isAdPlaying && (React.createElement(Settings, { iconClassName: iconClassName, qualityConfig: config?.qualityConfig })),
|
|
1117
1085
|
React.createElement("div", { onClick: handleMute }, muted ? (React.createElement(Tooltip, { title: "Unmute" },
|
|
1118
1086
|
React.createElement(IoVolumeMuteOutline, { className: iconClassName }))) : (React.createElement(Tooltip, { title: "Mute" },
|
|
1119
1087
|
React.createElement(IoVolumeHighOutline, { className: iconClassName })))),
|
|
@@ -1264,11 +1232,11 @@ const MiddleControls = () => {
|
|
|
1264
1232
|
if (isAdPlaying) {
|
|
1265
1233
|
return (React__default.createElement("div", { className: "flex justify-center items-center" },
|
|
1266
1234
|
React__default.createElement(ControlButton, { onClick: handlePlayPause, className: "w-[10vw]", icon: isBuffering ? (React__default.createElement("div", { className: "relative" },
|
|
1267
|
-
React__default.createElement(Loader, { className: "w-
|
|
1235
|
+
React__default.createElement(Loader, { className: "w-14 h-14 lg:w-18 lg:h-18 animate-spin text-white" }))) : isPlaying ? (React__default.createElement(PauseIcon, null)) : (React__default.createElement(PlayIcon, null)) })));
|
|
1268
1236
|
}
|
|
1269
1237
|
return (React__default.createElement("div", { className: "flex justify-center items-center" },
|
|
1270
1238
|
React__default.createElement(ControlButton, { onClick: handleBackward, className: "w-[15vw]", icon: React__default.createElement(BackwardIcon, null) }),
|
|
1271
|
-
React__default.createElement(ControlButton, { onClick: handlePlayPause, className: "w-[10vw]", icon: isBuffering ? (React__default.createElement(Loader, { className: "w-
|
|
1239
|
+
React__default.createElement(ControlButton, { onClick: handlePlayPause, className: "w-[10vw]", icon: isBuffering ? (React__default.createElement(Loader, { className: "w-14 h-14 lg:w-18 lg:h-18 animate-spin text-white" })) : isPlaying ? (React__default.createElement(PauseIcon, null)) : (React__default.createElement(PlayIcon, null)) }),
|
|
1272
1240
|
React__default.createElement(ControlButton, { onClick: handleForward, className: "w-[15vw]", icon: React__default.createElement(ForwardIcon, null) })));
|
|
1273
1241
|
};
|
|
1274
1242
|
|
|
@@ -1281,7 +1249,6 @@ const VideoPlayerControls = ({ config }) => {
|
|
|
1281
1249
|
};
|
|
1282
1250
|
|
|
1283
1251
|
const VideoActionButton = React__default.memo(({ text, onClick, icon, disabled = false, position = "left", }) => {
|
|
1284
|
-
// Increase icon size and apply consistent color to icon
|
|
1285
1252
|
const renderedIcon = icon
|
|
1286
1253
|
? React__default.cloneElement(icon, {
|
|
1287
1254
|
className: "h-5 w-5 text-gray-900",
|
|
@@ -1398,7 +1365,83 @@ const Overlay = React__default.memo(({ config }) => {
|
|
|
1398
1365
|
});
|
|
1399
1366
|
Overlay.displayName = "Overlay";
|
|
1400
1367
|
|
|
1401
|
-
|
|
1368
|
+
/** Returns true if value is a Tailwind background class (e.g. bg-red, bg-black, bg-transparent) ya CSS "transparent" */
|
|
1369
|
+
const isTailwindBackground = (value) => typeof value === "string" &&
|
|
1370
|
+
(value.trim().startsWith("bg-") || value.trim().toLowerCase() === "transparent");
|
|
1371
|
+
const useSubtitleStyling = (config) => {
|
|
1372
|
+
const { videoRef } = useVideoStore();
|
|
1373
|
+
useEffect(() => {
|
|
1374
|
+
if (!videoRef)
|
|
1375
|
+
return;
|
|
1376
|
+
const applySubtitleStyles = () => {
|
|
1377
|
+
const style = document.createElement("style");
|
|
1378
|
+
style.id = "custom-subtitle-styles";
|
|
1379
|
+
const existingStyle = document.getElementById("custom-subtitle-styles");
|
|
1380
|
+
if (existingStyle) {
|
|
1381
|
+
existingStyle.remove();
|
|
1382
|
+
}
|
|
1383
|
+
const bgRaw = config?.backgroundColor;
|
|
1384
|
+
const useTailwindBg = isTailwindBackground(bgRaw);
|
|
1385
|
+
const cueBackground = useTailwindBg
|
|
1386
|
+
? "transparent"
|
|
1387
|
+
: bgRaw || "linear-gradient(135deg, #fbbf24, #f59e0b)";
|
|
1388
|
+
const styles = `
|
|
1389
|
+
.video-player video::cue {
|
|
1390
|
+
font-size: ${config?.fontSize || "1.75rem"} !important;
|
|
1391
|
+
background: ${cueBackground} !important;
|
|
1392
|
+
color: ${config?.textColor || "#000000"} !important;
|
|
1393
|
+
border-radius: ${config?.borderRadius || "12px"} !important;
|
|
1394
|
+
padding: ${config?.padding || "12px 20px"} !important;
|
|
1395
|
+
max-width: ${config?.maxWidth || "80%"} !important;
|
|
1396
|
+
${config?.position === "top"
|
|
1397
|
+
? "top: 10% !important; bottom: auto !important;"
|
|
1398
|
+
: ""}
|
|
1399
|
+
${config?.position === "center"
|
|
1400
|
+
? "top: 50% !important; bottom: auto !important; transform: translateX(-50%) translateY(-50%) !important;"
|
|
1401
|
+
: ""}
|
|
1402
|
+
${config?.position === "bottom" || !config?.position
|
|
1403
|
+
? "bottom: 15% !important; top: auto !important;"
|
|
1404
|
+
: ""}
|
|
1405
|
+
}
|
|
1406
|
+
`;
|
|
1407
|
+
style.textContent = styles;
|
|
1408
|
+
document.head.appendChild(style);
|
|
1409
|
+
};
|
|
1410
|
+
applySubtitleStyles();
|
|
1411
|
+
return () => {
|
|
1412
|
+
const existingStyle = document.getElementById("custom-subtitle-styles");
|
|
1413
|
+
if (existingStyle) {
|
|
1414
|
+
existingStyle.remove();
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
}, [videoRef, config]);
|
|
1418
|
+
};
|
|
1419
|
+
|
|
1420
|
+
const getPositionStyles = (position) => {
|
|
1421
|
+
const pos = position || "bottom";
|
|
1422
|
+
switch (pos) {
|
|
1423
|
+
case "top":
|
|
1424
|
+
return {
|
|
1425
|
+
top: "10%",
|
|
1426
|
+
left: "50%",
|
|
1427
|
+
transform: "translateX(-50%)",
|
|
1428
|
+
};
|
|
1429
|
+
case "center":
|
|
1430
|
+
return {
|
|
1431
|
+
top: "50%",
|
|
1432
|
+
left: "50%",
|
|
1433
|
+
transform: "translate(-50%, -50%)",
|
|
1434
|
+
};
|
|
1435
|
+
case "bottom":
|
|
1436
|
+
default:
|
|
1437
|
+
return {
|
|
1438
|
+
bottom: "15%",
|
|
1439
|
+
left: "50%",
|
|
1440
|
+
transform: "translateX(-50%)",
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
};
|
|
1444
|
+
const SubtitleOverlay = ({ styleConfig }) => {
|
|
1402
1445
|
const { videoRef, activeSubtitle } = useVideoStore(useShallow((state) => ({
|
|
1403
1446
|
videoRef: state.videoRef,
|
|
1404
1447
|
activeSubtitle: state.activeSubtitle,
|
|
@@ -1422,7 +1465,7 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1422
1465
|
const currentTime = videoRef.currentTime;
|
|
1423
1466
|
const textTracks = Array.from(videoRef.textTracks);
|
|
1424
1467
|
const activeTrack = textTracks.find((track) => track.mode === "showing" && track.label === activeSubtitle.label);
|
|
1425
|
-
if (activeTrack
|
|
1468
|
+
if (activeTrack?.cues) {
|
|
1426
1469
|
const activeCues = Array.from(activeTrack.cues).filter((cue) => currentTime >= cue.startTime && currentTime <= cue.endTime);
|
|
1427
1470
|
if (activeCues.length > 0) {
|
|
1428
1471
|
const cue = activeCues[0];
|
|
@@ -1432,15 +1475,14 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1432
1475
|
cueText = cue.text;
|
|
1433
1476
|
}
|
|
1434
1477
|
else if (typeof cue.getCueAsHTML === "function") {
|
|
1435
|
-
const
|
|
1436
|
-
cueText =
|
|
1437
|
-
htmlElement?.textContent || htmlElement?.innerText || "";
|
|
1478
|
+
const fragment = cue.getCueAsHTML();
|
|
1479
|
+
cueText = fragment?.textContent ?? "";
|
|
1438
1480
|
}
|
|
1439
1481
|
else {
|
|
1440
|
-
cueText = cue.toString()
|
|
1482
|
+
cueText = cue.toString() ?? "";
|
|
1441
1483
|
}
|
|
1442
1484
|
}
|
|
1443
|
-
catch
|
|
1485
|
+
catch {
|
|
1444
1486
|
cueText = "";
|
|
1445
1487
|
}
|
|
1446
1488
|
setCurrentSubtitle(cueText);
|
|
@@ -1451,6 +1493,10 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1451
1493
|
setIsVisible(false);
|
|
1452
1494
|
}
|
|
1453
1495
|
}
|
|
1496
|
+
else {
|
|
1497
|
+
setCurrentSubtitle("");
|
|
1498
|
+
setIsVisible(false);
|
|
1499
|
+
}
|
|
1454
1500
|
});
|
|
1455
1501
|
};
|
|
1456
1502
|
videoRef.addEventListener("timeupdate", handleTimeUpdate);
|
|
@@ -1468,55 +1514,42 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1468
1514
|
setIsVisible(false);
|
|
1469
1515
|
}
|
|
1470
1516
|
}, [activeSubtitle]);
|
|
1517
|
+
const bgValue = styleConfig?.backgroundColor ?? "rgba(0, 0, 0, 0.4)";
|
|
1518
|
+
const isTailwindBg = isTailwindBackground(bgValue);
|
|
1519
|
+
const bgClassName = isTailwindBg
|
|
1520
|
+
? (bgValue.trim().toLowerCase() === "transparent" ? "bg-transparent" : bgValue.trim())
|
|
1521
|
+
: undefined;
|
|
1522
|
+
const isTransparentBg = bgValue.trim().toLowerCase() === "transparent" ||
|
|
1523
|
+
bgClassName === "bg-transparent";
|
|
1524
|
+
const subtitleStyle = useMemo(() => {
|
|
1525
|
+
const base = {
|
|
1526
|
+
position: "absolute",
|
|
1527
|
+
...getPositionStyles(styleConfig?.position),
|
|
1528
|
+
fontSize: styleConfig?.fontSize ?? "1.2rem",
|
|
1529
|
+
fontWeight: "500",
|
|
1530
|
+
lineHeight: "1.2",
|
|
1531
|
+
textAlign: "center",
|
|
1532
|
+
color: styleConfig?.textColor ?? "#fff",
|
|
1533
|
+
padding: styleConfig?.padding ?? "8px 16px",
|
|
1534
|
+
borderRadius: styleConfig?.borderRadius ?? "5px",
|
|
1535
|
+
maxWidth: styleConfig?.maxWidth ?? "60%",
|
|
1536
|
+
minWidth: "fit-content",
|
|
1537
|
+
boxShadow: isTransparentBg ? "none" : "0 6px 20px rgba(0, 0, 0, 0.4)",
|
|
1538
|
+
backdropFilter: isTransparentBg ? "none" : "blur(6px)",
|
|
1539
|
+
border: isTransparentBg ? "none" : "1px solid rgba(255, 255, 255, 0.2)",
|
|
1540
|
+
transition: "all 0.2s ease-in-out",
|
|
1541
|
+
opacity: isVisible ? 1 : 0,
|
|
1542
|
+
zIndex: 10,
|
|
1543
|
+
pointerEvents: "none",
|
|
1544
|
+
};
|
|
1545
|
+
if (!isTailwindBg)
|
|
1546
|
+
base.background = bgValue;
|
|
1547
|
+
return base;
|
|
1548
|
+
}, [styleConfig, isVisible, bgValue, isTailwindBg, isTransparentBg]);
|
|
1471
1549
|
if (!isVisible || !currentSubtitle)
|
|
1472
1550
|
return null;
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
switch (position) {
|
|
1476
|
-
case "top":
|
|
1477
|
-
return {
|
|
1478
|
-
top: "10%",
|
|
1479
|
-
left: "50%",
|
|
1480
|
-
transform: "translateX(-50%)",
|
|
1481
|
-
};
|
|
1482
|
-
case "center":
|
|
1483
|
-
return {
|
|
1484
|
-
top: "50%",
|
|
1485
|
-
left: "50%",
|
|
1486
|
-
transform: "translate(-50%, -50%)",
|
|
1487
|
-
};
|
|
1488
|
-
case "bottom":
|
|
1489
|
-
default:
|
|
1490
|
-
return {
|
|
1491
|
-
bottom: "15%",
|
|
1492
|
-
left: "50%",
|
|
1493
|
-
transform: "translateX(-50%)",
|
|
1494
|
-
};
|
|
1495
|
-
}
|
|
1496
|
-
};
|
|
1497
|
-
const subtitleStyle = {
|
|
1498
|
-
position: "absolute",
|
|
1499
|
-
...getPositionStyles(),
|
|
1500
|
-
fontSize: styleConfig?.fontSize || "1.2rem",
|
|
1501
|
-
fontWeight: "500",
|
|
1502
|
-
lineHeight: "1.2",
|
|
1503
|
-
textAlign: "center",
|
|
1504
|
-
background: styleConfig?.backgroundColor || "rgba(0, 0, 0, 0.4)",
|
|
1505
|
-
color: styleConfig?.textColor || "#fff",
|
|
1506
|
-
padding: styleConfig?.padding || "8px 16px",
|
|
1507
|
-
borderRadius: styleConfig?.borderRadius || "5px",
|
|
1508
|
-
maxWidth: styleConfig?.maxWidth || "60%",
|
|
1509
|
-
minWidth: "fit-content",
|
|
1510
|
-
boxShadow: "0 6px 20px rgba(0, 0, 0, 0.4)",
|
|
1511
|
-
backdropFilter: "blur(6px)",
|
|
1512
|
-
border: "1px solid rgba(255, 255, 255, 0.2)",
|
|
1513
|
-
transition: "all 0.2s ease-in-out",
|
|
1514
|
-
opacity: isVisible ? 1 : 0,
|
|
1515
|
-
zIndex: 10,
|
|
1516
|
-
pointerEvents: "none",
|
|
1517
|
-
};
|
|
1518
|
-
return React__default.createElement("div", { style: subtitleStyle }, currentSubtitle);
|
|
1519
|
-
});
|
|
1551
|
+
return (React__default.createElement("div", { className: bgClassName, style: subtitleStyle }, currentSubtitle));
|
|
1552
|
+
};
|
|
1520
1553
|
SubtitleOverlay.displayName = "SubtitleOverlay";
|
|
1521
1554
|
|
|
1522
1555
|
const HLS_CONFIG = {
|
|
@@ -2036,51 +2069,6 @@ const useSubtitles = (subtitles) => {
|
|
|
2036
2069
|
}, [subtitles, setSubtitles]);
|
|
2037
2070
|
};
|
|
2038
2071
|
|
|
2039
|
-
const useSubtitleStyling = (config) => {
|
|
2040
|
-
const { videoRef } = useVideoStore();
|
|
2041
|
-
useEffect(() => {
|
|
2042
|
-
if (!videoRef)
|
|
2043
|
-
return;
|
|
2044
|
-
const applySubtitleStyles = () => {
|
|
2045
|
-
const style = document.createElement("style");
|
|
2046
|
-
style.id = "custom-subtitle-styles";
|
|
2047
|
-
const existingStyle = document.getElementById("custom-subtitle-styles");
|
|
2048
|
-
if (existingStyle) {
|
|
2049
|
-
existingStyle.remove();
|
|
2050
|
-
}
|
|
2051
|
-
const styles = `
|
|
2052
|
-
.video-player video::cue {
|
|
2053
|
-
font-size: ${config?.fontSize || "1.75rem"} !important;
|
|
2054
|
-
background: ${config?.backgroundColor ||
|
|
2055
|
-
"linear-gradient(135deg, #fbbf24, #f59e0b)"} !important;
|
|
2056
|
-
color: ${config?.textColor || "#000000"} !important;
|
|
2057
|
-
border-radius: ${config?.borderRadius || "12px"} !important;
|
|
2058
|
-
padding: ${config?.padding || "12px 20px"} !important;
|
|
2059
|
-
max-width: ${config?.maxWidth || "80%"} !important;
|
|
2060
|
-
${config?.position === "top"
|
|
2061
|
-
? "top: 10% !important; bottom: auto !important;"
|
|
2062
|
-
: ""}
|
|
2063
|
-
${config?.position === "center"
|
|
2064
|
-
? "top: 50% !important; bottom: auto !important; transform: translateX(-50%) translateY(-50%) !important;"
|
|
2065
|
-
: ""}
|
|
2066
|
-
${config?.position === "bottom" || !config?.position
|
|
2067
|
-
? "bottom: 15% !important; top: auto !important;"
|
|
2068
|
-
: ""}
|
|
2069
|
-
}
|
|
2070
|
-
`;
|
|
2071
|
-
style.textContent = styles;
|
|
2072
|
-
document.head.appendChild(style);
|
|
2073
|
-
};
|
|
2074
|
-
applySubtitleStyles();
|
|
2075
|
-
return () => {
|
|
2076
|
-
const existingStyle = document.getElementById("custom-subtitle-styles");
|
|
2077
|
-
if (existingStyle) {
|
|
2078
|
-
existingStyle.remove();
|
|
2079
|
-
}
|
|
2080
|
-
};
|
|
2081
|
-
}, [videoRef, config]);
|
|
2082
|
-
};
|
|
2083
|
-
|
|
2084
2072
|
const useVideoTracking = (tracking, episodeList, currentEpisodeIndex, onClose) => {
|
|
2085
2073
|
const { videoRef, setShowCountdown } = useVideoStore();
|
|
2086
2074
|
const isViewCounted = useRef(false);
|
|
@@ -3461,12 +3449,18 @@ styleInject(css_248z,{"insertAt":"top"});
|
|
|
3461
3449
|
|
|
3462
3450
|
const VideoPlayer = React__default.memo(({ video, style, events, features }) => {
|
|
3463
3451
|
const { src: trackSrc, title: trackTitle, poster: trackPoster, type, isTrailer, showControls = true, isMute = false, startFrom, } = video;
|
|
3464
|
-
const { className, width, height, subtitleStyle } = style || {};
|
|
3452
|
+
const { className, width, height, subtitleStyle, qualityConfig } = style || {};
|
|
3465
3453
|
const { onEnded, onError, onClose, onWatchHistoryUpdate } = events || {};
|
|
3466
3454
|
const { timeCodes, getPreviewScreenUrl, tracking, subtitles, episodeList, currentEpisodeIndex = 0, intro, nextEpisodeConfig, ads, } = features || {};
|
|
3467
|
-
const { setVideoWrapperRef } = useVideoStore(useShallow((state) => ({
|
|
3455
|
+
const { setVideoWrapperRef, setActiveQuality } = useVideoStore(useShallow((state) => ({
|
|
3468
3456
|
setVideoWrapperRef: state.setVideoWrapperRef,
|
|
3457
|
+
setActiveQuality: state.setActiveQuality,
|
|
3469
3458
|
})));
|
|
3459
|
+
React__default.useEffect(() => {
|
|
3460
|
+
if (qualityConfig?.defaultQuality) {
|
|
3461
|
+
setActiveQuality(qualityConfig.defaultQuality);
|
|
3462
|
+
}
|
|
3463
|
+
}, [qualityConfig?.defaultQuality, setActiveQuality]);
|
|
3470
3464
|
const effectiveAds = React__default.useMemo(() => (isTrailer ? undefined : ads), [ads, isTrailer]);
|
|
3471
3465
|
const hasPreRoll = React__default.useMemo(() => Boolean(effectiveAds?.preRoll), [effectiveAds?.preRoll]);
|
|
3472
3466
|
const { registerVideoRef, videoRef, isAdPlaying, currentAd, initialAdFinished, shouldCoverMainVideo, shouldShowPlaceholder, } = usePrimaryVideoLifecycle({
|
|
@@ -3507,6 +3501,7 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3507
3501
|
title: trackTitle,
|
|
3508
3502
|
onClose: handleClose,
|
|
3509
3503
|
videoRef: videoRef,
|
|
3504
|
+
qualityConfig,
|
|
3510
3505
|
},
|
|
3511
3506
|
},
|
|
3512
3507
|
bottomConfig: {
|
|
@@ -3525,6 +3520,7 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3525
3520
|
videoRef,
|
|
3526
3521
|
timeCodes,
|
|
3527
3522
|
getPreviewScreenUrl,
|
|
3523
|
+
qualityConfig,
|
|
3528
3524
|
]);
|
|
3529
3525
|
const adOverlayConfig = React__default.useMemo(() => ({
|
|
3530
3526
|
config: {
|
|
@@ -3586,7 +3582,7 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3586
3582
|
onError?.(e);
|
|
3587
3583
|
}, autoPlay: !hasPreRoll, muted: isMute, className: `w-full h-full relative ${className || ""} ${shouldCoverMainVideo ? "opacity-0" : "opacity-100"} transition-opacity duration-200 ease-out` }),
|
|
3588
3584
|
shouldShowPlaceholder && (React__default.createElement("div", { className: "absolute inset-0 z-40 flex flex-col items-center justify-center bg-black/90 backdrop-blur-sm" },
|
|
3589
|
-
React__default.createElement(Loader, { className: "w-
|
|
3585
|
+
React__default.createElement(Loader, { className: "w-14 h-14 lg:w-18 lg:h-18 animate-spin text-white" }))),
|
|
3590
3586
|
showControls && initialAdFinished && (React__default.createElement(Overlay, { config: overlayConfig })),
|
|
3591
3587
|
React__default.createElement(SubtitleOverlay, { styleConfig: subtitleStyle }),
|
|
3592
3588
|
showSkipIntro && !isAdPlaying && initialAdFinished && (React__default.createElement(VideoActionButton, { text: "Skip Intro", onClick: handleSkipIntro, position: "left" })),
|