@zezosoft/react-player 0.0.10 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/VideoPlayer/components/controls/BottomControls.d.ts +4 -1
- package/dist/VideoPlayer/components/controls/MiddleControls.d.ts +7 -1
- package/dist/VideoPlayer/components/controls/VideoPlayerControls.d.ts +4 -1
- package/dist/VideoPlayer/components/time-line/TimeLine.d.ts +5 -0
- package/dist/VideoPlayer/components/time-line/components/HoverTimeWithPreview.d.ts +1 -0
- package/dist/VideoPlayer/components/time-line/components/TimeCodeItem.d.ts +3 -0
- package/dist/VideoPlayer/components/time-line/components/TimeCodes.d.ts +3 -0
- package/dist/VideoPlayer/hooks/index.d.ts +0 -1
- package/dist/VideoPlayer/hooks/useSubtitleStyling.d.ts +3 -0
- package/dist/VideoPlayer/hooks/useVideoSource.d.ts +1 -1
- package/dist/VideoPlayer/types/VideoPlayerTypes.d.ts +21 -1
- package/dist/VideoPlayer/utils/index.d.ts +0 -11
- package/dist/components/ui/LiveIndicator.d.ts +9 -0
- package/dist/components/ui/Settings.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +277 -229
- package/dist/store/types/StoreTypes.d.ts +2 -0
- package/package.json +6 -7
- package/dist/VideoPlayer/MediaControls/BottomControls.d.ts +0 -5
- package/dist/VideoPlayer/MediaControls/ControlsHeader.d.ts +0 -5
- package/dist/VideoPlayer/MediaControls/MiddleControls.d.ts +0 -3
- package/dist/VideoPlayer/MediaControls/VideoPlayerControls.d.ts +0 -4
- package/dist/VideoPlayer/_components/BottomControls.d.ts +0 -5
- package/dist/VideoPlayer/_components/ControlsHeader.d.ts +0 -5
- package/dist/VideoPlayer/_components/MiddleControls.d.ts +0 -3
- package/dist/VideoPlayer/_components/Overlay.d.ts +0 -4
- package/dist/VideoPlayer/_components/SubtitleOverlay.d.ts +0 -7
- package/dist/VideoPlayer/_components/TimeLine/TimeLine.d.ts +0 -20
- package/dist/VideoPlayer/_components/TimeLine/_components/hoverTimeWithPreview.d.ts +0 -16
- package/dist/VideoPlayer/_components/TimeLine/_components/thumb.d.ts +0 -9
- package/dist/VideoPlayer/_components/TimeLine/_components/timeCodeItem.d.ts +0 -21
- package/dist/VideoPlayer/_components/TimeLine/_components/timeCodes.d.ts +0 -15
- package/dist/VideoPlayer/_components/TimeLine/utils/getEndTimeByIndex.d.ts +0 -2
- package/dist/VideoPlayer/_components/TimeLine/utils/getHoverTimePosition.d.ts +0 -3
- package/dist/VideoPlayer/_components/TimeLine/utils/getPositionPercent.d.ts +0 -1
- package/dist/VideoPlayer/_components/TimeLine/utils/getTimeScale.d.ts +0 -1
- package/dist/VideoPlayer/_components/TimeLine/utils/isInRange.d.ts +0 -1
- package/dist/VideoPlayer/_components/TimeLine/utils/positionToMs.d.ts +0 -1
- package/dist/VideoPlayer/_components/TimeLine/utils/secondsToTime.d.ts +0 -6
- package/dist/VideoPlayer/_components/TimeLine/utils/timeToTimeString.d.ts +0 -1
- package/dist/VideoPlayer/_components/VideoPlayerControls.d.ts +0 -4
- package/dist/VideoPlayer/hooks/useNetworkSpeed.d.ts +0 -7
- /package/dist/components/ui/{tooltip.d.ts → Tooltip.d.ts} +0 -0
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 --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) 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 .visible {\n visibility: visible;\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 {\n top: calc(var(--spacing) * 1);\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 {\n left: calc(var(--spacing) * 1);\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-1 {\n margin-right: calc(var(--spacing) * -1);\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 .contents {\n display: contents;\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 .table {\n display: table;\n }\n .h-1 {\n height: calc(var(--spacing) * 1);\n }\n .h-1\\.5 {\n height: calc(var(--spacing) * 1.5);\n }\n .h-2 {\n height: calc(var(--spacing) * 2);\n }\n .h-2\\.5 {\n height: calc(var(--spacing) * 2.5);\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 .max-h-\\[min\\(80vh\\,480px\\)\\] {\n max-height: min(80vh, 480px);\n }\n .min-h-0 {\n min-height: calc(var(--spacing) * 0);\n }\n .w-1 {\n width: calc(var(--spacing) * 1);\n }\n .w-1\\.5 {\n width: calc(var(--spacing) * 1.5);\n }\n .w-2 {\n width: calc(var(--spacing) * 2);\n }\n .w-2\\.5 {\n width: calc(var(--spacing) * 2.5);\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-\\[min\\(90vw\\,320px\\)\\] {\n max-width: min(90vw, 320px);\n }\n .max-w-md {\n max-width: var(--container-md);\n }\n .flex-1 {\n flex: 1;\n }\n .flex-shrink {\n flex-shrink: 1;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .border-collapse {\n border-collapse: collapse;\n }\n .-translate-x-1 {\n --tw-translate-x: calc(var(--spacing) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\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 {\n --tw-translate-y: calc(var(--spacing) * -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-pulse {\n animation: var(--animate-pulse);\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 .resize {\n resize: both;\n }\n .flex-col {\n flex-direction: column;\n }\n .flex-wrap {\n flex-wrap: wrap;\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 {\n border-color: var(--color-gray-700);\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 {\n border-color: var(--color-white);\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-500 {\n background-color: var(--color-red-500);\n }\n .bg-red-500\\/15 {\n background-color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 15%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-red-500) 15%, transparent);\n }\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 {\n --tw-gradient-to: 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 .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-2 {\n padding-inline: calc(var(--spacing) * 2);\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-1\\.5 {\n padding-block: calc(var(--spacing) * 1.5);\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 .pr-1 {\n padding-right: calc(var(--spacing) * 1);\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 .underline {\n text-decoration-line: underline;\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 .ring-1 {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + 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 .ring-red-500 {\n --tw-ring-color: var(--color-red-500);\n }\n .ring-red-500\\/25 {\n --tw-ring-color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 25%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-ring-color: color-mix(in oklab, var(--color-red-500) 25%, transparent);\n }\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\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 .backdrop-filter {\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@keyframes live-dot-blink {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.6);\n }\n 50% {\n opacity: 0.35;\n transform: scale(0.85);\n box-shadow: 0 0 0 4px rgba(239, 68, 68, 0);\n }\n}\n.animate-live-blink {\n animation: live-dot-blink 1.2s ease-in-out infinite;\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-outline-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\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@keyframes pulse {\n 50% {\n opacity: 0.5;\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-outline-style: solid;\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) => ({
|
|
@@ -88,6 +88,8 @@ const createVideoQualitySlice = (set) => ({
|
|
|
88
88
|
setCurrentQuality: (currentQuality) => set({ currentQuality }),
|
|
89
89
|
streamType: "mp4",
|
|
90
90
|
setStreamType: (streamType) => set({ streamType }),
|
|
91
|
+
isLive: false,
|
|
92
|
+
setIsLive: (isLive) => set({ isLive }),
|
|
91
93
|
});
|
|
92
94
|
|
|
93
95
|
const createSubtitlesSlice = (set) => ({
|
|
@@ -420,7 +422,7 @@ function getTimeScale(currentTime, startTime, endTime, isTimePassed) {
|
|
|
420
422
|
return isTimePassed ? 1 : currentScalePercent;
|
|
421
423
|
}
|
|
422
424
|
|
|
423
|
-
const TimeCodeItem = memo(({ label = "", startTime, maxTime, endTime, currentTime, seekHoverTime, bufferTime, isTimePassed = false, isBufferPassed = false, isHoverPassed = false, onHover = () => undefined, withGap, trackColor, }) => {
|
|
425
|
+
const TimeCodeItem = memo(({ label = "", startTime, maxTime, endTime, currentTime, seekHoverTime, bufferTime, isTimePassed = false, isBufferPassed = false, isHoverPassed = false, onHover = () => undefined, withGap, trackColor, bufferColor, hoverColor, trackBackgroundColor, }) => {
|
|
424
426
|
const positionPercent = getPositionPercent(maxTime, startTime);
|
|
425
427
|
const timeDiff = endTime - startTime;
|
|
426
428
|
const widthPercent = (timeDiff / maxTime) * 100;
|
|
@@ -429,15 +431,26 @@ const TimeCodeItem = memo(({ label = "", startTime, maxTime, endTime, currentTim
|
|
|
429
431
|
const seekHoverTimeScale = getTimeScale(seekHoverTime, startTime, endTime, isHoverPassed);
|
|
430
432
|
const bufferTimeScale = getTimeScale(bufferTime, startTime, endTime, isBufferPassed);
|
|
431
433
|
const handleMouseMove = () => onHover(label);
|
|
434
|
+
const trackBg = trackBackgroundColor ?? "rgba(255, 255, 255, 0.2)";
|
|
435
|
+
const bufColor = bufferColor ?? "rgba(255, 255, 255, 0.3)";
|
|
436
|
+
const hovColor = hoverColor ?? "rgba(255, 255, 255, 0.5)";
|
|
437
|
+
const progColor = trackColor ?? "#ff0000";
|
|
432
438
|
return (React__default.createElement("div", { className: mainClassName, onMouseMove: handleMouseMove, style: {
|
|
433
439
|
width: `${widthPercent}%`,
|
|
434
440
|
left: `${positionPercent}%`,
|
|
441
|
+
"--seek-track-bg": trackBg,
|
|
435
442
|
} },
|
|
436
|
-
React__default.createElement("div", { className: "inner-seek-block buffered", "data-test-id": "test-buffered", style: {
|
|
437
|
-
|
|
443
|
+
React__default.createElement("div", { className: "inner-seek-block buffered", "data-test-id": "test-buffered", style: {
|
|
444
|
+
transform: `scaleX(${bufferTimeScale})`,
|
|
445
|
+
backgroundColor: bufColor,
|
|
446
|
+
} }),
|
|
447
|
+
React__default.createElement("div", { className: "inner-seek-block seek-hover", "data-test-id": "test-seek-hover", style: {
|
|
448
|
+
transform: `scaleX(${seekHoverTimeScale})`,
|
|
449
|
+
backgroundColor: hovColor,
|
|
450
|
+
} }),
|
|
438
451
|
React__default.createElement("div", { className: "inner-seek-block connect", style: {
|
|
439
452
|
transform: `scaleX(${currentTimeScale})`,
|
|
440
|
-
backgroundColor:
|
|
453
|
+
backgroundColor: progColor,
|
|
441
454
|
} })));
|
|
442
455
|
});
|
|
443
456
|
|
|
@@ -448,7 +461,7 @@ function positionToMs(max, position, trackWidth) {
|
|
|
448
461
|
|
|
449
462
|
const getEndTimeByIndex = (timeCodes, index, max) => (index + 1 < timeCodes.length ? timeCodes[index + 1].fromMs : max);
|
|
450
463
|
|
|
451
|
-
const TimeCodes = ({ max = 1000, currentTime = 0, bufferTime = 0, seekHoverPosition = 0, timeCodes, trackWidth, mobileSeeking, label, setLabel, trackColor, }) => {
|
|
464
|
+
const TimeCodes = ({ max = 1000, currentTime = 0, bufferTime = 0, seekHoverPosition = 0, timeCodes, trackWidth, mobileSeeking, label, setLabel, trackColor, bufferColor, hoverColor, trackBackgroundColor, }) => {
|
|
452
465
|
const hoverTimeValue = positionToMs(max, seekHoverPosition, trackWidth);
|
|
453
466
|
const handleLabelChange = useCallback((currentLabel) => {
|
|
454
467
|
if (label !== currentLabel) {
|
|
@@ -478,7 +491,7 @@ const TimeCodes = ({ max = 1000, currentTime = 0, bufferTime = 0, seekHoverPosit
|
|
|
478
491
|
const newBufferTime = isBufferPassed || !inRange ? 0 : bufferTime;
|
|
479
492
|
inRange = isInRange(hoverTimeValue, fromMs, endTime);
|
|
480
493
|
const newHoverTime = isHoverPassed || !inRange ? 0 : hoverTimeValue;
|
|
481
|
-
return (React__default.createElement(TimeCodeItem, { key: fromMs, label: description, maxTime: max, startTime: fromMs, endTime: endTime, isTimePassed: isTimePassed, isBufferPassed: isBufferPassed, isHoverPassed: isHoverPassed, currentTime: newCurrentTime, bufferTime: newBufferTime, seekHoverTime: newHoverTime, onHover: handleLabelChange, withGap: true, trackColor: trackColor }));
|
|
494
|
+
return (React__default.createElement(TimeCodeItem, { key: fromMs, label: description, maxTime: max, startTime: fromMs, endTime: endTime, isTimePassed: isTimePassed, isBufferPassed: isBufferPassed, isHoverPassed: isHoverPassed, currentTime: newCurrentTime, bufferTime: newBufferTime, seekHoverTime: newHoverTime, onHover: handleLabelChange, withGap: true, trackColor: trackColor, bufferColor: bufferColor, hoverColor: hoverColor, trackBackgroundColor: trackBackgroundColor }));
|
|
482
495
|
})));
|
|
483
496
|
};
|
|
484
497
|
|
|
@@ -522,7 +535,7 @@ function timeToTimeString(max, seekHoverTime, offset = 0, minutesPrefix = "", se
|
|
|
522
535
|
return `${times.hh}:${times.mm}:${times.ss}`;
|
|
523
536
|
}
|
|
524
537
|
|
|
525
|
-
const HoverTimeWithPreview = ({ max, hoverTimeValue, offset, trackWidth, seekHoverPosition, isThumbActive, limitTimeTooltipBySides, label, minutesPrefix, secondsPrefix, getPreviewScreenUrl, }) => {
|
|
538
|
+
const HoverTimeWithPreview = ({ max, hoverTimeValue, offset, trackWidth, seekHoverPosition, isThumbActive, limitTimeTooltipBySides, label, minutesPrefix, secondsPrefix, getPreviewScreenUrl, isLive = false, }) => {
|
|
526
539
|
const hoverTimeElement = useRef(null);
|
|
527
540
|
const hoverTimeClassName = isThumbActive ? "hover-time active" : "hover-time";
|
|
528
541
|
const hoverTimePosition = getHoverTimePosition(seekHoverPosition, hoverTimeElement?.current, trackWidth, limitTimeTooltipBySides);
|
|
@@ -531,8 +544,11 @@ const HoverTimeWithPreview = ({ max, hoverTimeValue, offset, trackWidth, seekHov
|
|
|
531
544
|
isThumbActive && getPreviewScreenUrl && (React__default.createElement("div", { className: "preview-screen", style: {
|
|
532
545
|
backgroundImage: `url(${getPreviewScreenUrl(hoverTimeValue)})`,
|
|
533
546
|
} })),
|
|
534
|
-
label && React__default.createElement("div", null, label),
|
|
535
|
-
|
|
547
|
+
label && !isLive && React__default.createElement("div", null, label),
|
|
548
|
+
isLive ? (React__default.createElement("span", { className: "inline-flex items-center gap-2 rounded-[5px] bg-red-500/15 px-2 py-1 text-xs font-semibold text-red-400 ring-1 ring-red-500/25 backdrop-blur-sm" },
|
|
549
|
+
React__default.createElement("span", { className: "relative flex h-1.5 w-1.5 shrink-0 items-center justify-center", "aria-hidden": true },
|
|
550
|
+
React__default.createElement("span", { className: "h-1.5 w-1.5 rounded-full bg-red-500 animate-live-blink" })),
|
|
551
|
+
"LIVE")) : (hoverTimeString)));
|
|
536
552
|
};
|
|
537
553
|
|
|
538
554
|
const Thumb = ({ max, currentTime, isThumbActive, trackColor, }) => {
|
|
@@ -549,10 +565,10 @@ const Thumb = ({ max, currentTime, isThumbActive, trackColor, }) => {
|
|
|
549
565
|
} })));
|
|
550
566
|
};
|
|
551
567
|
|
|
552
|
-
var css_248z$3 = ".ui-video-seek-slider {\n position: relative;\n touch-action: none;\n}\n.ui-video-seek-slider:focus {\n outline: none;\n}\n.ui-video-seek-slider .track {\n padding: 0;\n cursor: pointer;\n outline: none;\n}\n.ui-video-seek-slider .track:focus {\n border: 0;\n outline: none;\n}\n.ui-video-seek-slider .track .main {\n width: 100%;\n outline: none;\n height: 18px;\n top: 0;\n position: absolute;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n}\n.ui-video-seek-slider .track .main:before {\n content: \"\";\n position: absolute;\n width: 100%;\n height: 3px;\n background-color: rgba(255, 255, 255, 0.2);\n overflow: hidden;\n transition: height 0.1s;\n outline: none;\n}\n.ui-video-seek-slider .track .main .inner-seek-block {\n position: absolute;\n width: 100%;\n height: 3px;\n transition: height 0.1s, opacity 0.4s, transform 0.2s ease-out;\n transform-origin: 0 0;\n}\n.ui-video-seek-slider .track .main:focus {\n border: 0;\n outline: none;\n}\n.ui-video-seek-slider .track .main .buffered {\n background-color: rgba(255, 255, 255, 0.3);\n z-index: 2;\n transition: transform 0.2s ease-out;\n}\n.ui-video-seek-slider .track .main .seek-hover {\n background-color: rgba(255, 255, 255, 0.5);\n z-index: 1;\n}\n.ui-video-seek-slider .track .main .connect {\n background-color: #ff0000;\n z-index: 3;\n transform-origin: 0 0;\n}\n.ui-video-seek-slider .track .main.with-gap .inner-seek-block,\n.ui-video-seek-slider .track .main.with-gap:before {\n width: calc(100% - 2px);\n margin: 0 auto;\n}\n@media (hover) {\n .ui-video-seek-slider .track .main:hover:before {\n height: 8px;\n }\n .ui-video-seek-slider .track .main:hover .inner-seek-block {\n height: 8px;\n }\n}\n.ui-video-seek-slider .thumb {\n pointer-events: none;\n position: absolute;\n width: 12px;\n height: 12px;\n left: -6px;\n z-index: 4;\n top: 3px;\n}\n.ui-video-seek-slider .thumb .handler {\n border-radius: 100%;\n width: 100%;\n height: 100%;\n background-color: #ff0000;\n opacity: 0;\n transform: scale(0.4);\n transition: transform 0.2s, opacity 0.2s;\n}\n.ui-video-seek-slider .thumb.active .handler {\n opacity: 1;\n transform: scale(1);\n}\n.ui-video-seek-slider .hover-time {\n text-shadow: 1px 1px 1px #000;\n position: absolute;\n line-height: 18px;\n font-size: 16px;\n color: #ddd;\n bottom: 5px;\n left: 0;\n padding: 5px 10px;\n opacity: 0;\n pointer-events: none;\n text-align: center;\n}\n.ui-video-seek-slider .hover-time.active {\n opacity: 1;\n}\n.ui-video-seek-slider .hover-time .preview-screen {\n background-repeat: no-repeat;\n background-size: cover;\n background-position: center;\n width: 200px;\n height: 110px;\n border-radius: 5px;\n background-color: #000;\n margin: 0 auto 10px;\n}\n.ui-video-seek-slider:hover .track .main .seek-hover {\n opacity: 1;\n}\n\n";
|
|
568
|
+
var css_248z$3 = ".ui-video-seek-slider {\n position: relative;\n touch-action: none;\n}\n.ui-video-seek-slider:focus {\n outline: none;\n}\n.ui-video-seek-slider .track {\n padding: 0;\n cursor: pointer;\n outline: none;\n}\n.ui-video-seek-slider .track:focus {\n border: 0;\n outline: none;\n}\n.ui-video-seek-slider .track .main {\n width: 100%;\n outline: none;\n height: 18px;\n top: 0;\n position: absolute;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n}\n.ui-video-seek-slider .track .main:before {\n content: \"\";\n position: absolute;\n width: 100%;\n height: 3px;\n background-color: var(--seek-track-bg, rgba(255, 255, 255, 0.2));\n overflow: hidden;\n transition: height 0.1s;\n outline: none;\n}\n.ui-video-seek-slider .track .main .inner-seek-block {\n position: absolute;\n width: 100%;\n height: 3px;\n transition: height 0.1s, opacity 0.4s, transform 0.2s ease-out;\n transform-origin: 0 0;\n}\n.ui-video-seek-slider .track .main:focus {\n border: 0;\n outline: none;\n}\n.ui-video-seek-slider .track .main .buffered {\n background-color: rgba(255, 255, 255, 0.3);\n z-index: 2;\n transition: transform 0.2s ease-out;\n}\n.ui-video-seek-slider .track .main .seek-hover {\n background-color: rgba(255, 255, 255, 0.5);\n z-index: 1;\n}\n.ui-video-seek-slider .track .main .connect {\n background-color: #ff0000;\n z-index: 3;\n transform-origin: 0 0;\n}\n.ui-video-seek-slider .track .main.with-gap .inner-seek-block,\n.ui-video-seek-slider .track .main.with-gap:before {\n width: calc(100% - 2px);\n margin: 0 auto;\n}\n@media (hover) {\n .ui-video-seek-slider .track .main:hover:before {\n height: 8px;\n }\n .ui-video-seek-slider .track .main:hover .inner-seek-block {\n height: 8px;\n }\n}\n.ui-video-seek-slider .thumb {\n pointer-events: none;\n position: absolute;\n width: 12px;\n height: 12px;\n left: -6px;\n z-index: 4;\n top: 3px;\n}\n.ui-video-seek-slider .thumb .handler {\n border-radius: 100%;\n width: 100%;\n height: 100%;\n background-color: #ff0000;\n opacity: 0;\n transform: scale(0.4);\n transition: transform 0.2s, opacity 0.2s;\n}\n.ui-video-seek-slider .thumb.active .handler {\n opacity: 1;\n transform: scale(1);\n}\n.ui-video-seek-slider .hover-time {\n text-shadow: 1px 1px 1px #000;\n position: absolute;\n line-height: 18px;\n font-size: 16px;\n color: #ddd;\n bottom: 5px;\n left: 0;\n padding: 5px 10px;\n opacity: 0;\n pointer-events: none;\n text-align: center;\n}\n.ui-video-seek-slider .hover-time.active {\n opacity: 1;\n}\n.ui-video-seek-slider .hover-time .preview-screen {\n background-repeat: no-repeat;\n background-size: cover;\n background-position: center;\n width: 200px;\n height: 110px;\n border-radius: 5px;\n background-color: #000;\n margin: 0 auto 10px;\n}\n.ui-video-seek-slider:hover .track .main .seek-hover {\n opacity: 1;\n}\n\n";
|
|
553
569
|
styleInject(css_248z$3,{"insertAt":"top"});
|
|
554
570
|
|
|
555
|
-
const VideoSeekSlider = ({ max = 1000, currentTime = 0, bufferTime = 0, hideThumbTooltip = false, offset = 0, secondsPrefix = "", minutesPrefix = "", limitTimeTooltipBySides = true, timeCodes, onChange = () => undefined, getPreviewScreenUrl, trackColor, }) => {
|
|
571
|
+
const VideoSeekSlider = ({ max = 1000, currentTime = 0, bufferTime = 0, hideThumbTooltip = false, offset = 0, secondsPrefix = "", minutesPrefix = "", limitTimeTooltipBySides = true, timeCodes, onChange = () => undefined, getPreviewScreenUrl, trackColor, bufferColor, hoverColor, thumbColor, trackBackgroundColor, isLive = false, }) => {
|
|
556
572
|
const [seekHoverPosition, setSeekHoverPosition] = useState(0);
|
|
557
573
|
const [label, setLabel] = useState("");
|
|
558
574
|
const seeking = useRef(false);
|
|
@@ -636,32 +652,39 @@ const VideoSeekSlider = ({ max = 1000, currentTime = 0, bufferTime = 0, hideThum
|
|
|
636
652
|
}, [max, offset, trackWidth]);
|
|
637
653
|
return (React__default.createElement("div", { className: "ui-video-seek-slider" },
|
|
638
654
|
React__default.createElement("div", { className: isThumbActive ? "track active" : "track", ref: trackElement, onMouseMove: (event) => handleTrackHover(false, event), onMouseLeave: (event) => handleTrackHover(true, event), onMouseDown: (event) => setSeeking(true, event), onTouchStart: () => setMobileSeeking(true), "data-testid": "main-track" },
|
|
639
|
-
Boolean(timeCodes?.length) && (React__default.createElement(TimeCodes, { currentTime: currentTime, max: max, bufferTime: bufferTime, seekHoverPosition: seekHoverPosition, timeCodes: timeCodes, mobileSeeking: mobileSeeking.current, trackWidth: trackWidth, label: label, setLabel: setLabel, trackColor: trackColor })),
|
|
640
|
-
!timeCodes && (React__default.createElement(TimeCodeItem, { maxTime: max, startTime: 0, endTime: max, currentTime: currentTime, bufferTime: bufferTime, seekHoverTime: hoverTimeValue, trackColor: trackColor }))),
|
|
641
|
-
!hideThumbTooltip && (React__default.createElement(HoverTimeWithPreview, { max: max, hoverTimeValue: hoverTimeValue, isThumbActive: isThumbActive, label: label, limitTimeTooltipBySides: limitTimeTooltipBySides, offset: offset, seekHoverPosition: seekHoverPosition, trackWidth: trackWidth, getPreviewScreenUrl: getPreviewScreenUrl, minutesPrefix: minutesPrefix, secondsPrefix: secondsPrefix })),
|
|
642
|
-
React__default.createElement(Thumb, { max: max, currentTime: currentTime, isThumbActive: isThumbActive, trackColor: trackColor })));
|
|
655
|
+
Boolean(timeCodes?.length) && (React__default.createElement(TimeCodes, { currentTime: currentTime, max: max, bufferTime: bufferTime, seekHoverPosition: seekHoverPosition, timeCodes: timeCodes, mobileSeeking: mobileSeeking.current, trackWidth: trackWidth, label: label, setLabel: setLabel, trackColor: trackColor, bufferColor: bufferColor, hoverColor: hoverColor, trackBackgroundColor: trackBackgroundColor })),
|
|
656
|
+
!timeCodes && (React__default.createElement(TimeCodeItem, { maxTime: max, startTime: 0, endTime: max, currentTime: currentTime, bufferTime: bufferTime, seekHoverTime: hoverTimeValue, trackColor: trackColor, bufferColor: bufferColor, hoverColor: hoverColor, trackBackgroundColor: trackBackgroundColor }))),
|
|
657
|
+
!hideThumbTooltip && (React__default.createElement(HoverTimeWithPreview, { max: max, hoverTimeValue: hoverTimeValue, isThumbActive: isThumbActive, label: label, limitTimeTooltipBySides: limitTimeTooltipBySides, offset: offset, seekHoverPosition: seekHoverPosition, trackWidth: trackWidth, getPreviewScreenUrl: getPreviewScreenUrl, minutesPrefix: minutesPrefix, secondsPrefix: secondsPrefix, isLive: isLive })),
|
|
658
|
+
React__default.createElement(Thumb, { max: max, currentTime: currentTime, isThumbActive: isThumbActive, trackColor: thumbColor ?? trackColor })));
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Clean LIVE indicator with blinking dot animation for live streams.
|
|
663
|
+
*/
|
|
664
|
+
const LiveIndicator = ({ className = "" }) => {
|
|
665
|
+
return (React__default.createElement("div", { className: `flex items-center gap-2 ${className}`, "data-testid": "live-indicator" },
|
|
666
|
+
React__default.createElement("span", { className: "inline-flex items-center gap-2 rounded-[5px] bg-red-500/15 px-3 py-1.5 text-sm font-semibold text-red-400 ring-1 ring-red-500/25 backdrop-blur-sm", "aria-label": "Live stream" },
|
|
667
|
+
React__default.createElement("span", { className: "relative flex h-2.5 w-2.5 shrink-0 items-center justify-center", "aria-hidden": true },
|
|
668
|
+
React__default.createElement("span", { className: "h-2 w-2 rounded-full bg-red-500 animate-live-blink" })),
|
|
669
|
+
"LIVE")));
|
|
643
670
|
};
|
|
644
671
|
|
|
645
|
-
// Memoized time formatter to prevent unnecessary recalculations
|
|
646
672
|
const formatTimeMemo = (() => {
|
|
647
673
|
const cache = new Map();
|
|
648
674
|
return (seconds) => {
|
|
649
|
-
if (cache.has(seconds))
|
|
675
|
+
if (cache.has(seconds))
|
|
650
676
|
return cache.get(seconds);
|
|
651
|
-
}
|
|
652
677
|
const formatted = timeFormat(seconds);
|
|
653
678
|
cache.set(seconds, formatted);
|
|
654
|
-
// Limit cache size to prevent memory leaks
|
|
655
679
|
if (cache.size > 100) {
|
|
656
680
|
const firstKey = cache.keys().next().value;
|
|
657
|
-
if (firstKey !== undefined)
|
|
681
|
+
if (firstKey !== undefined)
|
|
658
682
|
cache.delete(firstKey);
|
|
659
|
-
}
|
|
660
683
|
}
|
|
661
684
|
return formatted;
|
|
662
685
|
};
|
|
663
686
|
})();
|
|
664
|
-
const BottomControls = memo(({ config }) => {
|
|
687
|
+
const BottomControls = memo(({ config, isLive = false }) => {
|
|
665
688
|
const { videoRef, currentTime, isFullscreen, bufferedProgress, isAdPlaying } = useVideoStore(useShallow((state) => ({
|
|
666
689
|
videoRef: state.videoRef,
|
|
667
690
|
currentTime: state.currentTime,
|
|
@@ -673,34 +696,33 @@ const BottomControls = memo(({ config }) => {
|
|
|
673
696
|
const currentTimeValue = currentTime || 0;
|
|
674
697
|
const bufferedValue = bufferedProgress || 0;
|
|
675
698
|
const handleSeek = useCallback((currentTimeInMs) => {
|
|
676
|
-
if (!videoRef)
|
|
699
|
+
if (!videoRef)
|
|
677
700
|
return;
|
|
678
|
-
}
|
|
679
701
|
videoRef.currentTime = currentTimeInMs / 1000;
|
|
680
702
|
}, [videoRef]);
|
|
681
703
|
const bufferTime = useMemo(() => {
|
|
682
|
-
if (!duration)
|
|
704
|
+
if (!duration)
|
|
683
705
|
return 0;
|
|
684
|
-
}
|
|
685
706
|
return secondsToMilliseconds(duration * (bufferedValue / 100));
|
|
686
707
|
}, [bufferedValue, duration]);
|
|
687
|
-
// Round to nearest second for time display to reduce re-renders
|
|
688
708
|
const roundedCurrentTime = useMemo(() => Math.floor(currentTimeValue), [currentTimeValue]);
|
|
689
709
|
const roundedDuration = useMemo(() => Math.floor(duration), [duration]);
|
|
690
710
|
const durationFormatted = useMemo(() => formatTimeMemo(roundedDuration), [roundedDuration]);
|
|
691
711
|
const currentTimeFormatted = useMemo(() => formatTimeMemo(roundedCurrentTime), [roundedCurrentTime]);
|
|
692
|
-
|
|
693
|
-
|
|
712
|
+
const seekSliderMax = useMemo(() => {
|
|
713
|
+
if (isLive && !Number.isFinite(duration))
|
|
714
|
+
return 1000;
|
|
715
|
+
return secondsToMilliseconds(duration);
|
|
716
|
+
}, [duration, isLive]);
|
|
694
717
|
const seekSliderCurrentTime = useMemo(() => secondsToMilliseconds(currentTimeValue), [currentTimeValue]);
|
|
695
|
-
if (isAdPlaying)
|
|
718
|
+
if (isAdPlaying)
|
|
696
719
|
return null;
|
|
697
|
-
}
|
|
698
720
|
return (React__default.createElement("div", { className: "px-10" },
|
|
699
|
-
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
|
-
React__default.createElement("div", { className: `pt-6 ${isFullscreen ? "pb-10" : "pb-16"} lg:pb-12 flex items-center gap-4 text-white` },
|
|
721
|
+
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, bufferColor: config?.seekBarConfig?.bufferColor, hoverColor: config?.seekBarConfig?.hoverColor, thumbColor: config?.seekBarConfig?.thumbColor, trackBackgroundColor: config?.seekBarConfig?.trackBackgroundColor, isLive: isLive }),
|
|
722
|
+
React__default.createElement("div", { className: `pt-6 ${isFullscreen ? "pb-10" : "pb-16"} lg:pb-12 flex items-center gap-4 text-white flex-wrap` }, isLive ? (React__default.createElement(LiveIndicator, null)) : (React__default.createElement(React__default.Fragment, null,
|
|
701
723
|
React__default.createElement("span", { className: "text-lg lg:text-2xl font-semibold text-white cursor-pointer hover:text-gray-200 transition-colors duration-200" }, currentTimeFormatted),
|
|
702
724
|
React__default.createElement("span", { className: "text-lg lg:text-3xl font-semibold text-gray-500 cursor-pointer hover:text-gray-200 transition-colors duration-200" }, "/"),
|
|
703
|
-
React__default.createElement("span", { className: "text-lg lg:text-2xl font-semibold text-gray-400 cursor-pointer hover:text-gray-200 transition-colors duration-200" }, durationFormatted))));
|
|
725
|
+
React__default.createElement("span", { className: "text-lg lg:text-2xl font-semibold text-gray-400 cursor-pointer hover:text-gray-200 transition-colors duration-200" }, durationFormatted))))));
|
|
704
726
|
});
|
|
705
727
|
BottomControls.displayName = "BottomControls";
|
|
706
728
|
|
|
@@ -724,7 +746,6 @@ const Popover = ({ button, children, closeOnButtonClick = false, className = "",
|
|
|
724
746
|
const [isOpen, setIsOpen] = useState(false);
|
|
725
747
|
const popoverRef = useRef(null);
|
|
726
748
|
const buttonRef = useRef(null);
|
|
727
|
-
// Close on outside click or Escape key
|
|
728
749
|
useEffect(() => {
|
|
729
750
|
const handleClickOutside = (event) => {
|
|
730
751
|
if (popoverRef.current &&
|
|
@@ -749,7 +770,6 @@ const Popover = ({ button, children, closeOnButtonClick = false, className = "",
|
|
|
749
770
|
const togglePopover = () => {
|
|
750
771
|
setIsOpen((prev) => (closeOnButtonClick ? !prev : true));
|
|
751
772
|
};
|
|
752
|
-
// Get alignment classes
|
|
753
773
|
const getAlignmentClasses = () => {
|
|
754
774
|
switch (align) {
|
|
755
775
|
case "center":
|
|
@@ -761,7 +781,6 @@ const Popover = ({ button, children, closeOnButtonClick = false, className = "",
|
|
|
761
781
|
return "left-0";
|
|
762
782
|
}
|
|
763
783
|
};
|
|
764
|
-
// Arrow is always centered regardless of popover alignment
|
|
765
784
|
const getArrowPositionClasses = () => {
|
|
766
785
|
return "left-1/2 -translate-x-1/2";
|
|
767
786
|
};
|
|
@@ -785,27 +804,24 @@ const Tooltip = ({ children, title, position = "top", className, }) => {
|
|
|
785
804
|
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
805
|
};
|
|
787
806
|
|
|
788
|
-
const
|
|
807
|
+
const speedOptions = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
808
|
+
const Settings = ({ iconClassName, qualityConfig, }) => {
|
|
809
|
+
const showQualityInSettings = qualityConfig?.showInSettings !== false;
|
|
789
810
|
const { qualityLevels, activeQuality, currentQuality, subtitles, activeSubtitle, setActiveSubtitle, videoRef, streamType, } = useVideoStore();
|
|
790
|
-
// Load playback speed from localStorage or default to 1
|
|
791
811
|
const getStoredPlaybackSpeed = () => {
|
|
792
812
|
try {
|
|
793
813
|
const stored = localStorage.getItem("react-player-playback-speed");
|
|
794
814
|
if (stored) {
|
|
795
815
|
const speed = parseFloat(stored);
|
|
796
|
-
if (speedOptions.includes(speed))
|
|
816
|
+
if (speedOptions.includes(speed))
|
|
797
817
|
return speed;
|
|
798
|
-
}
|
|
799
818
|
}
|
|
800
819
|
}
|
|
801
|
-
catch
|
|
802
|
-
// Ignore localStorage errors
|
|
803
|
-
}
|
|
820
|
+
catch { }
|
|
804
821
|
return 1;
|
|
805
822
|
};
|
|
806
823
|
const [speed, setSpeed] = React.useState(getStoredPlaybackSpeed());
|
|
807
824
|
const [activeMenu, setActiveMenu] = React.useState("main");
|
|
808
|
-
// Initialize playback speed from localStorage on mount
|
|
809
825
|
React.useEffect(() => {
|
|
810
826
|
if (videoRef) {
|
|
811
827
|
const storedSpeed = getStoredPlaybackSpeed();
|
|
@@ -815,16 +831,12 @@ const Settings = ({ iconClassName }) => {
|
|
|
815
831
|
}, [videoRef]);
|
|
816
832
|
const handleSpeedChange = (newSpeed) => {
|
|
817
833
|
setSpeed(newSpeed);
|
|
818
|
-
if (videoRef)
|
|
834
|
+
if (videoRef)
|
|
819
835
|
videoRef.playbackRate = newSpeed;
|
|
820
|
-
}
|
|
821
|
-
// Persist to localStorage
|
|
822
836
|
try {
|
|
823
837
|
localStorage.setItem("react-player-playback-speed", newSpeed.toString());
|
|
824
838
|
}
|
|
825
|
-
catch
|
|
826
|
-
// Ignore localStorage errors
|
|
827
|
-
}
|
|
839
|
+
catch { }
|
|
828
840
|
};
|
|
829
841
|
const isAdaptiveStream = streamType === "hls" || streamType === "dash";
|
|
830
842
|
const qualityOptions = React.useMemo(() => {
|
|
@@ -849,27 +861,23 @@ const Settings = ({ iconClassName }) => {
|
|
|
849
861
|
return b.originalIndex - a.originalIndex;
|
|
850
862
|
});
|
|
851
863
|
}, [qualityLevels, isAdaptiveStream, streamType]);
|
|
852
|
-
const speedOptions = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
|
|
853
864
|
const handleBack = () => setActiveMenu("main");
|
|
854
865
|
const formatBitrate = (bitrate) => {
|
|
855
866
|
if (!bitrate || bitrate <= 0)
|
|
856
867
|
return "";
|
|
857
|
-
if (bitrate >= 1000000)
|
|
868
|
+
if (bitrate >= 1000000)
|
|
858
869
|
return `${(bitrate / 1000000).toFixed(1)} Mbps`;
|
|
859
|
-
}
|
|
860
870
|
return `${Math.round(bitrate / 1000)} Kbps`;
|
|
861
871
|
};
|
|
862
|
-
// Get quality label: show explicit resolution to avoid duplicates
|
|
863
872
|
const getQualityName = (height, bitrate) => {
|
|
864
873
|
if (height && height > 0)
|
|
865
874
|
return `${height}p`;
|
|
866
875
|
const bitrateLabel = formatBitrate(bitrate);
|
|
867
876
|
return bitrateLabel || "Quality";
|
|
868
877
|
};
|
|
869
|
-
// Get quality label for display
|
|
870
878
|
const getQualityLabel = () => {
|
|
871
|
-
if (!isAdaptiveStream)
|
|
872
|
-
return "
|
|
879
|
+
if (!isAdaptiveStream || qualityOptions.length === 0)
|
|
880
|
+
return "Off";
|
|
873
881
|
if (currentQuality === "auto")
|
|
874
882
|
return "Auto";
|
|
875
883
|
const option = qualityOptions.find((q) => q.value === currentQuality);
|
|
@@ -878,15 +886,12 @@ const Settings = ({ iconClassName }) => {
|
|
|
878
886
|
const label = getQualityName(option.height, option.bitrate);
|
|
879
887
|
return label === "Quality" ? "Custom" : label;
|
|
880
888
|
};
|
|
881
|
-
|
|
889
|
+
const hasQualityOptions = isAdaptiveStream && qualityOptions.length > 0;
|
|
882
890
|
const getDataUsage = (height, bitrate) => {
|
|
883
|
-
// bitrate in bits/sec -> GB/hour
|
|
884
891
|
if (bitrate && bitrate > 0) {
|
|
885
892
|
const gbPerHour = (bitrate * 3600) / 8 / 1e9;
|
|
886
|
-
|
|
887
|
-
return `Uses about ${rounded} GB per hour`;
|
|
893
|
+
return `Uses about ${gbPerHour.toFixed(2)} GB per hour`;
|
|
888
894
|
}
|
|
889
|
-
// Fallback by resolution when bitrate missing
|
|
890
895
|
if (height >= 2160)
|
|
891
896
|
return "Uses about 7.00 GB per hour";
|
|
892
897
|
if (height >= 1440)
|
|
@@ -903,12 +908,12 @@ const Settings = ({ iconClassName }) => {
|
|
|
903
908
|
};
|
|
904
909
|
return (React.createElement(Tooltip, { title: "Settings" },
|
|
905
910
|
React.createElement(Popover, { button: React.createElement(Settings$1, { className: iconClassName }), align: "center" },
|
|
906
|
-
React.createElement("div", { className: "bg-[#3a4049] text-white rounded-[7px] w-80 overflow-hidden" },
|
|
911
|
+
React.createElement("div", { className: "bg-[#3a4049] text-white rounded-[7px] w-80 max-w-[min(90vw,320px)] overflow-hidden" },
|
|
907
912
|
activeMenu === "main" && (React.createElement("div", { className: "p-4" },
|
|
908
913
|
React.createElement("h3", { className: "text-white font-bold text-xl mb-4" }, "Settings"),
|
|
909
914
|
React.createElement("p", { className: "text-gray-300 text-sm mb-4" }, "Customize playback"),
|
|
910
915
|
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" },
|
|
916
|
+
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
917
|
React.createElement("div", { className: "flex items-center gap-3" },
|
|
913
918
|
React.createElement("div", { className: "p-2 bg-blue-500 rounded-md" },
|
|
914
919
|
React.createElement("svg", { className: "w-5 h-5 text-white", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
|
|
@@ -916,7 +921,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
916
921
|
React.createElement("div", { className: "text-left" },
|
|
917
922
|
React.createElement("div", { className: "text-white font-semibold" }, "Quality"),
|
|
918
923
|
React.createElement("div", { className: "text-gray-400 text-sm" }, getQualityLabel()))),
|
|
919
|
-
React.createElement(ChevronRight, { className: "w-5 h-5 text-gray-400" })),
|
|
924
|
+
React.createElement(ChevronRight, { className: "w-5 h-5 text-gray-400" }))),
|
|
920
925
|
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
926
|
React.createElement("div", { className: "flex items-center gap-3" },
|
|
922
927
|
React.createElement("div", { className: "p-2 bg-purple-500 rounded-md" },
|
|
@@ -937,35 +942,31 @@ const Settings = ({ iconClassName }) => {
|
|
|
937
942
|
speed,
|
|
938
943
|
"x"))),
|
|
939
944
|
React.createElement(ChevronRight, { className: "w-5 h-5 text-gray-400" }))))),
|
|
940
|
-
activeMenu === "quality" && (React.createElement("div", { className: "p-4" },
|
|
941
|
-
React.createElement("div", { className: "flex items-center gap-3 mb-4" },
|
|
942
|
-
React.createElement("button", { onClick: handleBack, className: "p-1 rounded-md transition-colors" },
|
|
945
|
+
activeMenu === "quality" && (React.createElement("div", { className: "p-4 flex flex-col max-h-[min(80vh,480px)]" },
|
|
946
|
+
React.createElement("div", { className: "flex items-center gap-3 mb-4 shrink-0" },
|
|
947
|
+
React.createElement("button", { onClick: handleBack, className: "p-1 rounded-md transition-colors hover:bg-white/10" },
|
|
943
948
|
React.createElement(ChevronRight, { className: "w-6 h-6 text-white rotate-180" })),
|
|
944
949
|
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"
|
|
950
|
+
React.createElement("div", { className: "space-y-3 overflow-y-auto min-h-0 flex-1 pr-1 -mr-1" }, hasQualityOptions ? (React.createElement(React.Fragment, null,
|
|
951
|
+
React.createElement("button", { onClick: () => QualityManager.setQuality(streamType, "auto"), className: `w-full text-left px-4 py-3 rounded-md transition-all ${activeQuality === "auto"
|
|
951
952
|
? "bg-white/10"
|
|
952
|
-
:
|
|
953
|
-
? "hover:bg-white/5"
|
|
954
|
-
: "opacity-50 cursor-not-allowed"}` },
|
|
953
|
+
: "hover:bg-white/5"}` },
|
|
955
954
|
React.createElement("div", { className: "flex items-start justify-between" },
|
|
956
955
|
React.createElement("div", null,
|
|
957
956
|
React.createElement("div", { className: "text-white font-semibold text-lg mb-1" }, "Auto"),
|
|
958
957
|
React.createElement("div", { className: "text-gray-400 text-sm" }, "Adjust to your connection")),
|
|
959
958
|
activeQuality === "auto" && (React.createElement(Check, { className: "w-6 h-6 text-white mt-1" })))),
|
|
960
|
-
|
|
959
|
+
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
960
|
? "bg-white/10"
|
|
962
961
|
: "hover:bg-white/5"}` },
|
|
963
962
|
React.createElement("div", { className: "flex items-start justify-between" },
|
|
964
963
|
React.createElement("div", null,
|
|
965
964
|
React.createElement("div", { className: "text-white font-semibold text-lg mb-1" }, getQualityName(level.height, level.bitrate)),
|
|
966
965
|
React.createElement("div", { className: "text-gray-400 text-sm" }, getDataUsage(level.height, level.bitrate))),
|
|
967
|
-
|
|
968
|
-
|
|
966
|
+
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" },
|
|
967
|
+
React.createElement("div", { className: "flex items-start justify-between" },
|
|
968
|
+
React.createElement("span", { className: "text-white font-semibold text-lg" }, "Off"),
|
|
969
|
+
React.createElement(Check, { className: "w-6 h-6 text-white mt-1" }))))))),
|
|
969
970
|
activeMenu === "subtitles" && (React.createElement("div", { className: "p-4" },
|
|
970
971
|
React.createElement("div", { className: "flex items-center gap-3 mb-4" },
|
|
971
972
|
React.createElement("button", { onClick: handleBack, className: "p-1 hover:bg-white/10 rounded-md transition-colors" },
|
|
@@ -974,7 +975,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
974
975
|
React.createElement("div", { className: "space-y-3" },
|
|
975
976
|
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
977
|
React.createElement("span", { className: "text-white font-semibold text-lg" }, "Off"),
|
|
977
|
-
!activeSubtitle && React.createElement(Check, { className: "w-6 h-6 text-white" })),
|
|
978
|
+
!activeSubtitle && (React.createElement(Check, { className: "w-6 h-6 text-white" }))),
|
|
978
979
|
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
980
|
? "bg-white/10"
|
|
980
981
|
: "hover:bg-white/5"}` },
|
|
@@ -987,7 +988,7 @@ const Settings = ({ iconClassName }) => {
|
|
|
987
988
|
React.createElement("h3", { className: "text-white font-bold text-xl" }, "Playback Speed")),
|
|
988
989
|
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
990
|
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" })))))))))));
|
|
991
|
+
speed === s && (React.createElement(Check, { className: "w-6 h-6 text-white" }))))))))))));
|
|
991
992
|
};
|
|
992
993
|
|
|
993
994
|
const ControlsHeader = ({ config }) => {
|
|
@@ -1083,7 +1084,7 @@ const ControlsHeader = ({ config }) => {
|
|
|
1083
1084
|
setIsPipActive(false);
|
|
1084
1085
|
}
|
|
1085
1086
|
}
|
|
1086
|
-
catch
|
|
1087
|
+
catch { }
|
|
1087
1088
|
};
|
|
1088
1089
|
React.useEffect(() => {
|
|
1089
1090
|
const handlePipChange = () => setIsPipActive(!!document.pictureInPictureElement);
|
|
@@ -1096,9 +1097,7 @@ const ControlsHeader = ({ config }) => {
|
|
|
1096
1097
|
}, []);
|
|
1097
1098
|
const handleClose = () => {
|
|
1098
1099
|
resetStore();
|
|
1099
|
-
|
|
1100
|
-
config.onClose();
|
|
1101
|
-
}
|
|
1100
|
+
config?.onClose?.();
|
|
1102
1101
|
};
|
|
1103
1102
|
const renderAdHeader = () => (React.createElement("div", { className: "flex items-center gap-4" },
|
|
1104
1103
|
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 +1112,7 @@ const ControlsHeader = ({ config }) => {
|
|
|
1113
1112
|
return (React.createElement("div", { className: "flex items-center justify-between p-10 bg-linear-to-b from-black" },
|
|
1114
1113
|
isAdPlaying ? renderAdHeader() : renderVideoHeader(),
|
|
1115
1114
|
React.createElement("div", { className: "flex items-center gap-7 text-white" },
|
|
1116
|
-
!isAdPlaying && React.createElement(Settings, { iconClassName: iconClassName }),
|
|
1115
|
+
!isAdPlaying && (React.createElement(Settings, { iconClassName: iconClassName, qualityConfig: config?.qualityConfig })),
|
|
1117
1116
|
React.createElement("div", { onClick: handleMute }, muted ? (React.createElement(Tooltip, { title: "Unmute" },
|
|
1118
1117
|
React.createElement(IoVolumeMuteOutline, { className: iconClassName }))) : (React.createElement(Tooltip, { title: "Mute" },
|
|
1119
1118
|
React.createElement(IoVolumeHighOutline, { className: iconClassName })))),
|
|
@@ -1150,10 +1149,16 @@ PauseIcon.displayName = "PauseIcon";
|
|
|
1150
1149
|
const PlayIcon = memo(() => (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", className: "icon-class", fill: "currentColor", viewBox: "0 0 67 67" },
|
|
1151
1150
|
React__default.createElement("path", { d: "M20.28 9.65c-2.205-1.268-4.026-.228-4.026 2.307v43.805c0 2.535 1.82 3.574 4.027 2.307l38.471-21.903a2.556 2.556 0 0 0 1.094-.935 2.514 2.514 0 0 0 0-2.743 2.556 2.556 0 0 0-1.093-.936L20.28 9.65z" }))));
|
|
1152
1151
|
PlayIcon.displayName = "PlayIcon";
|
|
1153
|
-
const ControlButtonComponent = ({ onClick, icon, className, }) => (React__default.createElement("button", { onClick: onClick, className: `flex justify-center items-center h-full cursor-pointer ${className}
|
|
1152
|
+
const ControlButtonComponent = ({ onClick, icon, className, style, }) => (React__default.createElement("button", { onClick: onClick, className: `flex justify-center items-center h-full cursor-pointer rounded-full transition-colors duration-200 ${className}`, style: style }, icon));
|
|
1154
1153
|
const ControlButton = memo(ControlButtonComponent);
|
|
1155
1154
|
ControlButton.displayName = "ControlButton";
|
|
1156
|
-
const MiddleControls = () => {
|
|
1155
|
+
const MiddleControls = ({ config }) => {
|
|
1156
|
+
const ppConfig = config?.playPauseButtonConfig;
|
|
1157
|
+
const playPauseStyle = React__default.useMemo(() => ({
|
|
1158
|
+
backgroundColor: ppConfig?.backgroundColor,
|
|
1159
|
+
borderRadius: ppConfig?.borderRadius ?? "50%",
|
|
1160
|
+
padding: ppConfig?.padding,
|
|
1161
|
+
}), [ppConfig?.backgroundColor, ppConfig?.borderRadius, ppConfig?.padding]);
|
|
1157
1162
|
const { videoRef, adVideoRef, isPlaying, setIsPlaying, isAdPlaying } = useVideoStore(useShallow((state) => ({
|
|
1158
1163
|
videoRef: state.videoRef,
|
|
1159
1164
|
adVideoRef: state.adVideoRef,
|
|
@@ -1263,25 +1268,24 @@ const MiddleControls = () => {
|
|
|
1263
1268
|
]);
|
|
1264
1269
|
if (isAdPlaying) {
|
|
1265
1270
|
return (React__default.createElement("div", { className: "flex justify-center items-center" },
|
|
1266
|
-
React__default.createElement(ControlButton, { onClick: handlePlayPause, className: "w-[10vw]", icon: isBuffering ? (React__default.createElement("div", { className: "relative" },
|
|
1267
|
-
React__default.createElement(Loader, { className: "w-
|
|
1271
|
+
React__default.createElement(ControlButton, { onClick: handlePlayPause, className: "w-[10vw]", style: playPauseStyle, icon: isBuffering ? (React__default.createElement("div", { className: "relative" },
|
|
1272
|
+
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
1273
|
}
|
|
1269
1274
|
return (React__default.createElement("div", { className: "flex justify-center items-center" },
|
|
1270
1275
|
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-
|
|
1276
|
+
React__default.createElement(ControlButton, { onClick: handlePlayPause, className: "w-[10vw]", style: playPauseStyle, 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
1277
|
React__default.createElement(ControlButton, { onClick: handleForward, className: "w-[15vw]", icon: React__default.createElement(ForwardIcon, null) })));
|
|
1273
1278
|
};
|
|
1274
1279
|
|
|
1275
|
-
const VideoPlayerControls = ({ config }) => {
|
|
1280
|
+
const VideoPlayerControls = ({ config, isLive = false, }) => {
|
|
1276
1281
|
return (React.createElement("div", { className: "px-20" },
|
|
1277
1282
|
React.createElement("div", { className: "absolute top-0 left-0 h-full w-full bg-[rgba(0,0,0,0.5)] flex flex-col justify-between" },
|
|
1278
1283
|
React.createElement(ControlsHeader, { config: config?.headerConfig?.config }),
|
|
1279
|
-
React.createElement(MiddleControls,
|
|
1280
|
-
React.createElement(BottomControls, { config: config?.bottomConfig?.config }))));
|
|
1284
|
+
React.createElement(MiddleControls, { config: config?.middleConfig?.config }),
|
|
1285
|
+
React.createElement(BottomControls, { config: config?.bottomConfig?.config, isLive: isLive }))));
|
|
1281
1286
|
};
|
|
1282
1287
|
|
|
1283
1288
|
const VideoActionButton = React__default.memo(({ text, onClick, icon, disabled = false, position = "left", }) => {
|
|
1284
|
-
// Increase icon size and apply consistent color to icon
|
|
1285
1289
|
const renderedIcon = icon
|
|
1286
1290
|
? React__default.cloneElement(icon, {
|
|
1287
1291
|
className: "h-5 w-5 text-gray-900",
|
|
@@ -1295,6 +1299,7 @@ const VideoActionButton = React__default.memo(({ text, onClick, icon, disabled =
|
|
|
1295
1299
|
VideoActionButton.displayName = "VideoActionButton";
|
|
1296
1300
|
|
|
1297
1301
|
const Overlay = React__default.memo(({ config }) => {
|
|
1302
|
+
const isLive = config?.isLive ?? false;
|
|
1298
1303
|
const controlsTimerRef = useRef(null);
|
|
1299
1304
|
const containerRef = useRef(null);
|
|
1300
1305
|
const { setControls, controls, showCountdown, countdownTime, setShowCountdown, setAutoPlayNext, setCurrentEpisodeIndex, episodeList, setCountdownTime, videoRef, currentEpisodeIndex, isAdPlaying, } = useVideoStore(useShallow((state) => ({
|
|
@@ -1393,12 +1398,88 @@ const Overlay = React__default.memo(({ config }) => {
|
|
|
1393
1398
|
episodeList.length > 0 &&
|
|
1394
1399
|
currentEpisodeIndex + 1 < episodeList.length, [showCountdown, episodeList.length, currentEpisodeIndex]);
|
|
1395
1400
|
return (React__default.createElement("div", { id: "videoPlayerControls", ref: containerRef, className: "absolute inset-0", onMouseMove: handleMouseEnter },
|
|
1396
|
-
controls && !isAdPlaying && React__default.createElement(VideoPlayerControls, { config: config }),
|
|
1401
|
+
controls && !isAdPlaying && (React__default.createElement(VideoPlayerControls, { config: config, isLive: isLive })),
|
|
1397
1402
|
shouldShowCountdown && (React__default.createElement(VideoActionButton, { text: "Next Episode", onClick: handleNextEpisodeManually, icon: React__default.createElement(ArrowRight, { className: "h-5 w-5 text-gray-900" }), disabled: currentEpisodeIndex + 1 >= episodeList.length, position: "right" }))));
|
|
1398
1403
|
});
|
|
1399
1404
|
Overlay.displayName = "Overlay";
|
|
1400
1405
|
|
|
1401
|
-
|
|
1406
|
+
/** Returns true if value is a Tailwind background class (e.g. bg-red, bg-black, bg-transparent) ya CSS "transparent" */
|
|
1407
|
+
const isTailwindBackground = (value) => typeof value === "string" &&
|
|
1408
|
+
(value.trim().startsWith("bg-") || value.trim().toLowerCase() === "transparent");
|
|
1409
|
+
const useSubtitleStyling = (config) => {
|
|
1410
|
+
const { videoRef } = useVideoStore();
|
|
1411
|
+
useEffect(() => {
|
|
1412
|
+
if (!videoRef)
|
|
1413
|
+
return;
|
|
1414
|
+
const applySubtitleStyles = () => {
|
|
1415
|
+
const style = document.createElement("style");
|
|
1416
|
+
style.id = "custom-subtitle-styles";
|
|
1417
|
+
const existingStyle = document.getElementById("custom-subtitle-styles");
|
|
1418
|
+
if (existingStyle) {
|
|
1419
|
+
existingStyle.remove();
|
|
1420
|
+
}
|
|
1421
|
+
const bgRaw = config?.backgroundColor;
|
|
1422
|
+
const useTailwindBg = isTailwindBackground(bgRaw);
|
|
1423
|
+
const cueBackground = useTailwindBg
|
|
1424
|
+
? "transparent"
|
|
1425
|
+
: bgRaw || "linear-gradient(135deg, #fbbf24, #f59e0b)";
|
|
1426
|
+
const styles = `
|
|
1427
|
+
.video-player video::cue {
|
|
1428
|
+
font-size: ${config?.fontSize || "1.75rem"} !important;
|
|
1429
|
+
background: ${cueBackground} !important;
|
|
1430
|
+
color: ${config?.textColor || "#000000"} !important;
|
|
1431
|
+
border-radius: ${config?.borderRadius || "12px"} !important;
|
|
1432
|
+
padding: ${config?.padding || "12px 20px"} !important;
|
|
1433
|
+
max-width: ${config?.maxWidth || "80%"} !important;
|
|
1434
|
+
${config?.position === "top"
|
|
1435
|
+
? "top: 10% !important; bottom: auto !important;"
|
|
1436
|
+
: ""}
|
|
1437
|
+
${config?.position === "center"
|
|
1438
|
+
? "top: 50% !important; bottom: auto !important; transform: translateX(-50%) translateY(-50%) !important;"
|
|
1439
|
+
: ""}
|
|
1440
|
+
${config?.position === "bottom" || !config?.position
|
|
1441
|
+
? "bottom: 15% !important; top: auto !important;"
|
|
1442
|
+
: ""}
|
|
1443
|
+
}
|
|
1444
|
+
`;
|
|
1445
|
+
style.textContent = styles;
|
|
1446
|
+
document.head.appendChild(style);
|
|
1447
|
+
};
|
|
1448
|
+
applySubtitleStyles();
|
|
1449
|
+
return () => {
|
|
1450
|
+
const existingStyle = document.getElementById("custom-subtitle-styles");
|
|
1451
|
+
if (existingStyle) {
|
|
1452
|
+
existingStyle.remove();
|
|
1453
|
+
}
|
|
1454
|
+
};
|
|
1455
|
+
}, [videoRef, config]);
|
|
1456
|
+
};
|
|
1457
|
+
|
|
1458
|
+
const getPositionStyles = (position) => {
|
|
1459
|
+
const pos = position || "bottom";
|
|
1460
|
+
switch (pos) {
|
|
1461
|
+
case "top":
|
|
1462
|
+
return {
|
|
1463
|
+
top: "10%",
|
|
1464
|
+
left: "50%",
|
|
1465
|
+
transform: "translateX(-50%)",
|
|
1466
|
+
};
|
|
1467
|
+
case "center":
|
|
1468
|
+
return {
|
|
1469
|
+
top: "50%",
|
|
1470
|
+
left: "50%",
|
|
1471
|
+
transform: "translate(-50%, -50%)",
|
|
1472
|
+
};
|
|
1473
|
+
case "bottom":
|
|
1474
|
+
default:
|
|
1475
|
+
return {
|
|
1476
|
+
bottom: "15%",
|
|
1477
|
+
left: "50%",
|
|
1478
|
+
transform: "translateX(-50%)",
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
const SubtitleOverlay = ({ styleConfig }) => {
|
|
1402
1483
|
const { videoRef, activeSubtitle } = useVideoStore(useShallow((state) => ({
|
|
1403
1484
|
videoRef: state.videoRef,
|
|
1404
1485
|
activeSubtitle: state.activeSubtitle,
|
|
@@ -1422,7 +1503,7 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1422
1503
|
const currentTime = videoRef.currentTime;
|
|
1423
1504
|
const textTracks = Array.from(videoRef.textTracks);
|
|
1424
1505
|
const activeTrack = textTracks.find((track) => track.mode === "showing" && track.label === activeSubtitle.label);
|
|
1425
|
-
if (activeTrack
|
|
1506
|
+
if (activeTrack?.cues) {
|
|
1426
1507
|
const activeCues = Array.from(activeTrack.cues).filter((cue) => currentTime >= cue.startTime && currentTime <= cue.endTime);
|
|
1427
1508
|
if (activeCues.length > 0) {
|
|
1428
1509
|
const cue = activeCues[0];
|
|
@@ -1432,15 +1513,14 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1432
1513
|
cueText = cue.text;
|
|
1433
1514
|
}
|
|
1434
1515
|
else if (typeof cue.getCueAsHTML === "function") {
|
|
1435
|
-
const
|
|
1436
|
-
cueText =
|
|
1437
|
-
htmlElement?.textContent || htmlElement?.innerText || "";
|
|
1516
|
+
const fragment = cue.getCueAsHTML();
|
|
1517
|
+
cueText = fragment?.textContent ?? "";
|
|
1438
1518
|
}
|
|
1439
1519
|
else {
|
|
1440
|
-
cueText = cue.toString()
|
|
1520
|
+
cueText = cue.toString() ?? "";
|
|
1441
1521
|
}
|
|
1442
1522
|
}
|
|
1443
|
-
catch
|
|
1523
|
+
catch {
|
|
1444
1524
|
cueText = "";
|
|
1445
1525
|
}
|
|
1446
1526
|
setCurrentSubtitle(cueText);
|
|
@@ -1451,6 +1531,10 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1451
1531
|
setIsVisible(false);
|
|
1452
1532
|
}
|
|
1453
1533
|
}
|
|
1534
|
+
else {
|
|
1535
|
+
setCurrentSubtitle("");
|
|
1536
|
+
setIsVisible(false);
|
|
1537
|
+
}
|
|
1454
1538
|
});
|
|
1455
1539
|
};
|
|
1456
1540
|
videoRef.addEventListener("timeupdate", handleTimeUpdate);
|
|
@@ -1468,96 +1552,79 @@ const SubtitleOverlay = React__default.memo(({ styleConfig }) => {
|
|
|
1468
1552
|
setIsVisible(false);
|
|
1469
1553
|
}
|
|
1470
1554
|
}, [activeSubtitle]);
|
|
1555
|
+
const bgValue = styleConfig?.backgroundColor ?? "rgba(0, 0, 0, 0.4)";
|
|
1556
|
+
const isTailwindBg = isTailwindBackground(bgValue);
|
|
1557
|
+
const bgClassName = isTailwindBg
|
|
1558
|
+
? (bgValue.trim().toLowerCase() === "transparent" ? "bg-transparent" : bgValue.trim())
|
|
1559
|
+
: undefined;
|
|
1560
|
+
const isTransparentBg = bgValue.trim().toLowerCase() === "transparent" ||
|
|
1561
|
+
bgClassName === "bg-transparent";
|
|
1562
|
+
const subtitleStyle = useMemo(() => {
|
|
1563
|
+
const base = {
|
|
1564
|
+
position: "absolute",
|
|
1565
|
+
...getPositionStyles(styleConfig?.position),
|
|
1566
|
+
fontSize: styleConfig?.fontSize ?? "1.2rem",
|
|
1567
|
+
fontWeight: "500",
|
|
1568
|
+
lineHeight: "1.2",
|
|
1569
|
+
textAlign: "center",
|
|
1570
|
+
color: styleConfig?.textColor ?? "#fff",
|
|
1571
|
+
padding: styleConfig?.padding ?? "8px 16px",
|
|
1572
|
+
borderRadius: styleConfig?.borderRadius ?? "5px",
|
|
1573
|
+
maxWidth: styleConfig?.maxWidth ?? "60%",
|
|
1574
|
+
minWidth: "fit-content",
|
|
1575
|
+
boxShadow: isTransparentBg ? "none" : "0 6px 20px rgba(0, 0, 0, 0.4)",
|
|
1576
|
+
backdropFilter: isTransparentBg ? "none" : "blur(6px)",
|
|
1577
|
+
border: isTransparentBg ? "none" : "1px solid rgba(255, 255, 255, 0.2)",
|
|
1578
|
+
transition: "all 0.2s ease-in-out",
|
|
1579
|
+
opacity: isVisible ? 1 : 0,
|
|
1580
|
+
zIndex: 10,
|
|
1581
|
+
pointerEvents: "none",
|
|
1582
|
+
};
|
|
1583
|
+
if (!isTailwindBg)
|
|
1584
|
+
base.background = bgValue;
|
|
1585
|
+
return base;
|
|
1586
|
+
}, [styleConfig, isVisible, bgValue, isTailwindBg, isTransparentBg]);
|
|
1471
1587
|
if (!isVisible || !currentSubtitle)
|
|
1472
1588
|
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
|
-
});
|
|
1589
|
+
return (React__default.createElement("div", { className: bgClassName, style: subtitleStyle }, currentSubtitle));
|
|
1590
|
+
};
|
|
1520
1591
|
SubtitleOverlay.displayName = "SubtitleOverlay";
|
|
1521
1592
|
|
|
1522
|
-
const
|
|
1593
|
+
const getHlsConfig = (isLive) => ({
|
|
1523
1594
|
enableWorker: true,
|
|
1524
|
-
lowLatencyMode:
|
|
1525
|
-
backBufferLength: 90,
|
|
1526
|
-
liveSyncDurationCount: 3,
|
|
1595
|
+
lowLatencyMode: isLive,
|
|
1596
|
+
backBufferLength: isLive ? 30 : 90,
|
|
1597
|
+
liveSyncDurationCount: isLive ? 1 : 3,
|
|
1598
|
+
liveMaxLatencyDurationCount: isLive ? 3 : 10,
|
|
1527
1599
|
maxBufferSize: 80 * 1000000,
|
|
1528
|
-
maxBufferLength: 30,
|
|
1600
|
+
maxBufferLength: isLive ? 10 : 30,
|
|
1529
1601
|
manifestLoadingMaxRetry: 4,
|
|
1530
1602
|
manifestLoadingRetryDelay: 1000,
|
|
1531
1603
|
levelLoadingMaxRetry: 4,
|
|
1532
1604
|
levelLoadingRetryDelay: 1000,
|
|
1533
1605
|
fragLoadingMaxRetry: 6,
|
|
1534
|
-
fragLoadingRetryDelay: 750,
|
|
1606
|
+
fragLoadingRetryDelay: isLive ? 500 : 750,
|
|
1535
1607
|
startLevel: -1,
|
|
1536
|
-
startPosition: -1,
|
|
1608
|
+
startPosition: isLive ? -1 : -1,
|
|
1537
1609
|
capLevelToPlayerSize: true,
|
|
1538
|
-
};
|
|
1539
|
-
const
|
|
1610
|
+
});
|
|
1611
|
+
const getDashSettings = (isLive) => ({
|
|
1540
1612
|
streaming: {
|
|
1541
1613
|
abr: {
|
|
1542
|
-
autoSwitchBitrate: {
|
|
1543
|
-
video: true,
|
|
1544
|
-
audio: true,
|
|
1545
|
-
},
|
|
1614
|
+
autoSwitchBitrate: { video: true, audio: true },
|
|
1546
1615
|
limitBitrateByPortal: true,
|
|
1547
1616
|
ABRStrategy: "abrThroughput",
|
|
1548
1617
|
bandwidthSafetyFactor: 0.9,
|
|
1549
1618
|
},
|
|
1550
1619
|
buffer: {
|
|
1551
1620
|
fastSwitchEnabled: true,
|
|
1552
|
-
bufferTimeAtTopQuality: 28,
|
|
1553
|
-
bufferTimeAtTopQualityLongForm: 55,
|
|
1621
|
+
bufferTimeAtTopQuality: isLive ? 12 : 28,
|
|
1622
|
+
bufferTimeAtTopQualityLongForm: isLive ? 20 : 55,
|
|
1554
1623
|
},
|
|
1555
|
-
lowLatencyEnabled:
|
|
1624
|
+
lowLatencyEnabled: isLive,
|
|
1556
1625
|
},
|
|
1557
|
-
debug: {
|
|
1558
|
-
|
|
1559
|
-
},
|
|
1560
|
-
};
|
|
1626
|
+
debug: { logLevel: dashjs.Debug.LOG_LEVEL_NONE },
|
|
1627
|
+
});
|
|
1561
1628
|
const MAX_HLS_NETWORK_RETRIES = 4;
|
|
1562
1629
|
const MAX_DASH_RESTARTS = 3;
|
|
1563
1630
|
const sanitizeUrl = (url) => {
|
|
@@ -1590,7 +1657,7 @@ const resolveStreamType = (explicitType, source) => {
|
|
|
1590
1657
|
return "mp4";
|
|
1591
1658
|
return "other";
|
|
1592
1659
|
};
|
|
1593
|
-
const useHlsEngine = ({ enabled, source, videoElement, setHlsInstance, setQualityLevels, setCurrentQuality, }) => {
|
|
1660
|
+
const useHlsEngine = ({ enabled, source, videoElement, setHlsInstance, setQualityLevels, setCurrentQuality, isLive = false, }) => {
|
|
1594
1661
|
const networkRetryRef = useRef(0);
|
|
1595
1662
|
const retryTimerRef = useRef(undefined);
|
|
1596
1663
|
useEffect(() => {
|
|
@@ -1641,7 +1708,7 @@ const useHlsEngine = ({ enabled, source, videoElement, setHlsInstance, setQualit
|
|
|
1641
1708
|
videoElement.load();
|
|
1642
1709
|
return;
|
|
1643
1710
|
}
|
|
1644
|
-
const hls = new Hls(
|
|
1711
|
+
const hls = new Hls(getHlsConfig(isLive));
|
|
1645
1712
|
setHlsInstance(hls);
|
|
1646
1713
|
const updateQualityLevels = () => {
|
|
1647
1714
|
const levels = hls.levels ?? [];
|
|
@@ -1748,9 +1815,10 @@ const useHlsEngine = ({ enabled, source, videoElement, setHlsInstance, setQualit
|
|
|
1748
1815
|
setHlsInstance,
|
|
1749
1816
|
setQualityLevels,
|
|
1750
1817
|
setCurrentQuality,
|
|
1818
|
+
isLive,
|
|
1751
1819
|
]);
|
|
1752
1820
|
};
|
|
1753
|
-
const useDashEngine = ({ enabled, source, videoElement, setDashInstance, setQualityLevels, setCurrentQuality, }) => {
|
|
1821
|
+
const useDashEngine = ({ enabled, source, videoElement, setDashInstance, setQualityLevels, setCurrentQuality, isLive = false, }) => {
|
|
1754
1822
|
const restartCountRef = useRef(0);
|
|
1755
1823
|
const restartTimerRef = useRef(undefined);
|
|
1756
1824
|
useEffect(() => {
|
|
@@ -1777,7 +1845,7 @@ const useDashEngine = ({ enabled, source, videoElement, setDashInstance, setQual
|
|
|
1777
1845
|
}
|
|
1778
1846
|
};
|
|
1779
1847
|
const applySettings = () => {
|
|
1780
|
-
player.updateSettings(
|
|
1848
|
+
player.updateSettings(getDashSettings(isLive));
|
|
1781
1849
|
};
|
|
1782
1850
|
const updateQualityLevels = () => {
|
|
1783
1851
|
try {
|
|
@@ -1892,9 +1960,10 @@ const useDashEngine = ({ enabled, source, videoElement, setDashInstance, setQual
|
|
|
1892
1960
|
setDashInstance,
|
|
1893
1961
|
setQualityLevels,
|
|
1894
1962
|
setCurrentQuality,
|
|
1963
|
+
isLive,
|
|
1895
1964
|
]);
|
|
1896
1965
|
};
|
|
1897
|
-
const useVideoSource = (trackSrc, type) => {
|
|
1966
|
+
const useVideoSource = (trackSrc, type, isLive) => {
|
|
1898
1967
|
const { videoRef, setQualityLevels, setHlsInstance, setDashInstance, setStreamType, setActiveQuality, setCurrentQuality, } = useVideoStore(useShallow((state) => ({
|
|
1899
1968
|
videoRef: state.videoRef,
|
|
1900
1969
|
setQualityLevels: state.setQualityLevels,
|
|
@@ -1947,6 +2016,7 @@ const useVideoSource = (trackSrc, type) => {
|
|
|
1947
2016
|
setHlsInstance,
|
|
1948
2017
|
setQualityLevels,
|
|
1949
2018
|
setCurrentQuality,
|
|
2019
|
+
isLive: isLive ?? false,
|
|
1950
2020
|
});
|
|
1951
2021
|
useDashEngine({
|
|
1952
2022
|
enabled: streamType === "dash",
|
|
@@ -1955,6 +2025,7 @@ const useVideoSource = (trackSrc, type) => {
|
|
|
1955
2025
|
setDashInstance,
|
|
1956
2026
|
setQualityLevels,
|
|
1957
2027
|
setCurrentQuality,
|
|
2028
|
+
isLive: isLive ?? false,
|
|
1958
2029
|
});
|
|
1959
2030
|
useEffect(() => {
|
|
1960
2031
|
if (!videoRef)
|
|
@@ -2036,51 +2107,6 @@ const useSubtitles = (subtitles) => {
|
|
|
2036
2107
|
}, [subtitles, setSubtitles]);
|
|
2037
2108
|
};
|
|
2038
2109
|
|
|
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
2110
|
const useVideoTracking = (tracking, episodeList, currentEpisodeIndex, onClose) => {
|
|
2085
2111
|
const { videoRef, setShowCountdown } = useVideoStore();
|
|
2086
2112
|
const isViewCounted = useRef(false);
|
|
@@ -3460,13 +3486,23 @@ var css_248z = "\n.loader {\n width: 64px;\n height: 64px;\n border-radius: 5
|
|
|
3460
3486
|
styleInject(css_248z,{"insertAt":"top"});
|
|
3461
3487
|
|
|
3462
3488
|
const VideoPlayer = React__default.memo(({ video, style, events, features }) => {
|
|
3463
|
-
const { src: trackSrc, title: trackTitle, poster: trackPoster, type, isTrailer, showControls = true, isMute = false, startFrom, } = video;
|
|
3464
|
-
const { className, width, height, subtitleStyle } = style || {};
|
|
3489
|
+
const { src: trackSrc, title: trackTitle, poster: trackPoster, type, isTrailer, showControls = true, isMute = false, startFrom, isLive: isLiveProp = false, } = video;
|
|
3490
|
+
const { className, width, height, subtitleStyle, qualityConfig, seekBarConfig: styleSeekBarConfig, playPauseButtonConfig, } = style || {};
|
|
3465
3491
|
const { onEnded, onError, onClose, onWatchHistoryUpdate } = events || {};
|
|
3466
3492
|
const { timeCodes, getPreviewScreenUrl, tracking, subtitles, episodeList, currentEpisodeIndex = 0, intro, nextEpisodeConfig, ads, } = features || {};
|
|
3467
|
-
const { setVideoWrapperRef } = useVideoStore(useShallow((state) => ({
|
|
3493
|
+
const { setVideoWrapperRef, setActiveQuality, setIsLive, } = useVideoStore(useShallow((state) => ({
|
|
3468
3494
|
setVideoWrapperRef: state.setVideoWrapperRef,
|
|
3495
|
+
setActiveQuality: state.setActiveQuality,
|
|
3496
|
+
setIsLive: state.setIsLive,
|
|
3469
3497
|
})));
|
|
3498
|
+
React__default.useEffect(() => {
|
|
3499
|
+
setIsLive(isLiveProp);
|
|
3500
|
+
}, [isLiveProp, setIsLive]);
|
|
3501
|
+
React__default.useEffect(() => {
|
|
3502
|
+
if (qualityConfig?.defaultQuality) {
|
|
3503
|
+
setActiveQuality(qualityConfig.defaultQuality);
|
|
3504
|
+
}
|
|
3505
|
+
}, [qualityConfig?.defaultQuality, setActiveQuality]);
|
|
3470
3506
|
const effectiveAds = React__default.useMemo(() => (isTrailer ? undefined : ads), [ads, isTrailer]);
|
|
3471
3507
|
const hasPreRoll = React__default.useMemo(() => Boolean(effectiveAds?.preRoll), [effectiveAds?.preRoll]);
|
|
3472
3508
|
const { registerVideoRef, videoRef, isAdPlaying, currentAd, initialAdFinished, shouldCoverMainVideo, shouldShowPlaceholder, } = usePrimaryVideoLifecycle({
|
|
@@ -3501,23 +3537,32 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3501
3537
|
onClose?.();
|
|
3502
3538
|
}, [getWatchHistoryData, onWatchHistoryUpdate, onClose]);
|
|
3503
3539
|
const overlayConfig = React__default.useMemo(() => ({
|
|
3540
|
+
isLive: isLiveProp,
|
|
3504
3541
|
headerConfig: {
|
|
3505
3542
|
config: {
|
|
3506
3543
|
isTrailer: isTrailer,
|
|
3507
3544
|
title: trackTitle,
|
|
3508
3545
|
onClose: handleClose,
|
|
3509
3546
|
videoRef: videoRef,
|
|
3547
|
+
qualityConfig,
|
|
3510
3548
|
},
|
|
3511
3549
|
},
|
|
3512
3550
|
bottomConfig: {
|
|
3513
3551
|
config: {
|
|
3514
3552
|
seekBarConfig: {
|
|
3515
3553
|
timeCodes: timeCodes,
|
|
3516
|
-
trackColor: "
|
|
3554
|
+
trackColor: styleSeekBarConfig?.trackColor ?? "#ff0000",
|
|
3555
|
+
bufferColor: styleSeekBarConfig?.bufferColor,
|
|
3556
|
+
hoverColor: styleSeekBarConfig?.hoverColor,
|
|
3557
|
+
thumbColor: styleSeekBarConfig?.thumbColor,
|
|
3558
|
+
trackBackgroundColor: styleSeekBarConfig?.trackBackgroundColor,
|
|
3517
3559
|
getPreviewScreenUrl,
|
|
3518
3560
|
},
|
|
3519
3561
|
},
|
|
3520
3562
|
},
|
|
3563
|
+
middleConfig: {
|
|
3564
|
+
config: { playPauseButtonConfig },
|
|
3565
|
+
},
|
|
3521
3566
|
}), [
|
|
3522
3567
|
isTrailer,
|
|
3523
3568
|
trackTitle,
|
|
@@ -3525,6 +3570,9 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3525
3570
|
videoRef,
|
|
3526
3571
|
timeCodes,
|
|
3527
3572
|
getPreviewScreenUrl,
|
|
3573
|
+
qualityConfig,
|
|
3574
|
+
styleSeekBarConfig,
|
|
3575
|
+
playPauseButtonConfig,
|
|
3528
3576
|
]);
|
|
3529
3577
|
const adOverlayConfig = React__default.useMemo(() => ({
|
|
3530
3578
|
config: {
|
|
@@ -3546,7 +3594,7 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3546
3594
|
},
|
|
3547
3595
|
},
|
|
3548
3596
|
}), [isTrailer, trackTitle, handleClose, timeCodes, getPreviewScreenUrl]);
|
|
3549
|
-
useVideoSource(trackSrc, type);
|
|
3597
|
+
useVideoSource(trackSrc, type, isLiveProp);
|
|
3550
3598
|
useSubtitles(subtitles);
|
|
3551
3599
|
useSubtitleStyling(subtitleStyle);
|
|
3552
3600
|
useVideoTracking(tracking, episodeList, currentEpisodeIndex, handleClose);
|
|
@@ -3586,7 +3634,7 @@ const VideoPlayer = React__default.memo(({ video, style, events, features }) =>
|
|
|
3586
3634
|
onError?.(e);
|
|
3587
3635
|
}, autoPlay: !hasPreRoll, muted: isMute, className: `w-full h-full relative ${className || ""} ${shouldCoverMainVideo ? "opacity-0" : "opacity-100"} transition-opacity duration-200 ease-out` }),
|
|
3588
3636
|
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-
|
|
3637
|
+
React__default.createElement(Loader, { className: "w-14 h-14 lg:w-18 lg:h-18 animate-spin text-white" }))),
|
|
3590
3638
|
showControls && initialAdFinished && (React__default.createElement(Overlay, { config: overlayConfig })),
|
|
3591
3639
|
React__default.createElement(SubtitleOverlay, { styleConfig: subtitleStyle }),
|
|
3592
3640
|
showSkipIntro && !isAdPlaying && initialAdFinished && (React__default.createElement(VideoActionButton, { text: "Skip Intro", onClick: handleSkipIntro, position: "left" })),
|